76 Commits

Author SHA1 Message Date
465a23633e Sync CMakeLists with current source tree 2025-09-08 22:39:07 +02:00
7c5d6326f8 Migrate EX subsystem to C++ 2025-09-08 22:35:59 +02:00
3f5f57ef12 Remove leftover test code 2025-09-08 15:44:12 +02:00
4e24b239a4 Fix cmake source path 2025-09-08 15:40:26 +02:00
c8dc2a1407 Migrate AR subsystem to C++ 2025-09-08 15:29:13 +02:00
27fec1bacb Add boot options with on-screen debugging 2025-09-05 21:30:01 +02:00
d8e0e07805 Correct format specifier for partition size to prevent stack corruption 2025-09-04 12:21:04 +02:00
8898a427df Rewrite and clarify kernel subsystem descriptions 2025-09-04 11:16:03 +02:00
7e039c47ae Simplify BlpDebugPutChar return path 2025-09-04 10:56:17 +02:00
c2a4ad026a Implement KD subsystem, add serial & framebuffer debug providers 2025-09-04 10:49:40 +02:00
db81e43525 Add missing forward references for RTL types 2025-09-04 10:28:32 +02:00
9cc776e06a Add generic kernel information support 2025-09-03 21:00:18 +02:00
602da0960c Unify string API parameter types to PCSTR/PCWSTR 2025-09-03 19:54:46 +02:00
9577a39046 Fix initialization block size calculation to account for variable-length kernel parameters 2025-09-03 18:10:42 +02:00
f9fe20ba68 Adjust forward references for HL_FRAMEBUFFER_DATA and HL_SCROLL_REGION_DATA 2025-09-03 16:44:52 +02:00
227da47bfc Add scroll region support and refactor framebuffer handling 2025-09-03 15:06:25 +02:00
9f5daafad9 Unify wide string types across console and debug functions 2025-09-03 10:41:24 +02:00
b2df65f5cc Fix KeDbgPrint prototype to use PCWSTR 2025-09-03 10:29:21 +02:00
d6999fad2f Extend RTL with substring search and character case functions 2025-09-02 21:51:10 +02:00
e4981b52ed Comment RtlTokenizeWideString for clarity 2025-09-02 20:18:33 +02:00
3c25934495 Add explanatory comments to string handling code 2025-09-02 19:31:13 +02:00
e23a4c71a2 Fix framebuffer address calculations by using Pitch and BytesPerPixel 2025-09-02 12:42:06 +02:00
6ee7243e04 Refactor APIC delivery mode handling and unify naming 2025-09-01 19:54:12 +02:00
d45cc5ffe5 Fix incorrect APIC delivery mode definitions 2025-09-01 19:32:29 +02:00
3c8b7cb1f2 Remove unused variable 2025-09-01 19:25:45 +02:00
2e415f6ec2 Remove broadcast INIT IPI 2025-09-01 19:23:02 +02:00
5ff9303bd1 Add debug screen clear at end of kernel initialization 2025-09-01 16:27:28 +02:00
84ac8f00e0 Fix APIC initialization and refine comments 2025-09-01 15:41:06 +02:00
418ff68be4 Add ESP boot support and improve block device enumeration 2025-09-01 14:02:38 +02:00
2d1b6363e6 Add CTRL-B shortcut to boot OS directly from edit menu 2025-09-01 12:43:33 +02:00
34cebf2810 Allow editing boot options using 'e' key 2025-09-01 11:47:36 +02:00
0fa4a175e0 Correct Backspace behavior in input dialog 2025-09-01 11:40:48 +02:00
72a832f190 Fix type mismatch in BlGetEditableOptions OptionsCount parameter 2025-08-30 20:35:01 +02:00
ba65264d1e Remove unnecessary console input buffer reset 2025-08-27 22:21:39 +02:00
2ee33ab229 Refactor BlGetConfigValue to return EFI_STATUS and output value via parameter 2025-08-27 19:44:52 +02:00
1eea654a36 Expose BlGetBootOptionValue, BlGetEditableOptions and BlSetBootOptionValue 2025-08-27 19:26:01 +02:00
c6643125e1 Implement boot entry editor 2025-08-27 19:15:38 +02:00
b68514b176 Limit boot menu entry names to available menu width 2025-08-25 19:03:57 +02:00
960e913222 Optimize boot menu drawing to eliminate screen flickering 2025-08-25 17:56:40 +02:00
e99e563aff Correct .modinfo section parsing 2025-08-25 12:07:49 +02:00
0b40a3fb10 Refactor MMU for multi-paging support and add 5-Level paging 2025-08-23 20:03:56 +02:00
a84ef21571 Adjust LA57 base addresses to prevent overflow 2025-08-21 01:42:36 +02:00
1ef2560ef6 Enable LA57 by invoking the trampoline code 2025-08-21 00:14:49 +02:00
d1b14fccdd Resolve build issues caused by the last commit 2025-08-20 21:08:43 +02:00
88b3a57962 Allow specifying an allocation type when allocating pages 2025-08-20 20:59:31 +02:00
9f6121e9b2 Map the physical page for trampoline code 2025-08-20 20:37:55 +02:00
4a7ea6009d Expose ArEnableExtendedPhysicalAddressing function in XTDK 2025-08-20 20:23:44 +02:00
c4a7df6f38 Extract trampoline code into a separate file 2025-08-20 20:20:35 +02:00
2468d80078 Add trampoline to enable 5-level paging 2025-08-20 00:20:10 +02:00
ebae8c655c Expand CR4, MSR, and EFER register definitions 2025-08-19 23:59:58 +02:00
1a0bc7f65f Update and correct CR4 bit definitions 2025-08-19 21:45:13 +02:00
91a5db2ee4 Implement PML5 support in XtpMapHardwareMemoryPool 2025-08-18 12:13:48 +02:00
b639bf3077 Implement PML5 self-mapping 2025-08-18 11:59:05 +02:00
c409400cbf Correct VA masking in AMD64 page mapping functions 2025-08-18 01:07:28 +02:00
d602038858 Temporarily disable LA57 paging 2025-08-18 00:10:32 +02:00
017b8603d5 Align parameters in PTE manipulation functions 2025-08-17 21:55:21 +02:00
a9dd1eaacd Implement MmpSetPteCaching function for AMD64 architecture 2025-08-17 21:51:43 +02:00
f30d3df5b3 Implement PTE manipulation functions for AMD64 architecture 2025-08-17 21:48:28 +02:00
c3ece4f317 Fix type usage in XtpMapHardwareMemoryPool 2025-08-17 00:51:26 +02:00
1e11acee72 Refactor hardware memory mapping to use page map routine callbacks 2025-08-17 00:47:56 +02:00
57193eecc0 Implement PML2/PML3 page table routines 2025-08-17 00:45:12 +02:00
720d525b95 Assign page map routines 2025-08-17 00:29:28 +02:00
f77f2bbf92 Introduce architecture-specific page map routines 2025-08-17 00:23:19 +02:00
0ed59f223c Relocate page mapping helpers and add PML5 support 2025-08-16 21:07:54 +02:00
de2973ac42 Implement page map info initialization 2025-08-16 20:28:05 +02:00
8491e5fed1 Remove PageMapLevel from the loader information block 2025-08-16 20:18:34 +02:00
6a330e38f2 Consolidate paging-related globals into MmpPageMapInfo 2025-08-16 20:14:18 +02:00
1dcd3fceed Define page map information structure for both supported architectures 2025-08-16 20:08:12 +02:00
5768d4bba6 Prepare for architecture-specific paging initialization 2025-08-16 19:58:00 +02:00
f85fe31b38 Adapt i686 memory mapping to new PML3 types 2025-08-16 00:36:20 +02:00
22f81a106b Update forward declarations for PML2/PML3 types 2025-08-16 00:33:18 +02:00
7e08dc286e Separate types for legacy (PML2) and PAE (PML3) paging 2025-08-16 00:29:20 +02:00
3ca6d04f6b Add definitions for 5-level paging and refactor constants 2025-08-16 00:22:21 +02:00
e57985da8d Rename MM_LA57_SHIFT to MM_P5I_SHIFT for consistency 2025-08-15 20:49:25 +02:00
8a23cc444f Merge branch 'master' into harraiken_mm 2025-08-15 11:30:48 +02:00
e8771dfc5b Use __asm__ to comply with disabled GNU extensions 2025-08-15 00:32:56 +02:00
117 changed files with 6049 additions and 1451 deletions

View File

@@ -40,6 +40,14 @@ SystemPath=multi(0)disk(0)rdisk(0)partition(1)/ExectOS
KernelFile=xtoskrnl.exe KernelFile=xtoskrnl.exe
Parameters=DEBUG=COM1,115200 Parameters=DEBUG=COM1,115200
[ExectOS_FBDEBUG]
SystemName="ExectOS Operating System (FBDEBUG)"
SystemType=XTOS
BootModules=xtos_o
SystemPath=multi(0)disk(0)rdisk(0)partition(1)/ExectOS
KernelFile=xtoskrnl.exe
Parameters=DEBUG=COM1,115200;SCREEN
[ExectOS_NOXPA] [ExectOS_NOXPA]
SystemName="ExectOS Operating System (NOXPA)" SystemName="ExectOS Operating System (NOXPA)"
SystemType=XTOS SystemType=XTOS
@@ -48,6 +56,14 @@ SystemPath=multi(0)disk(0)rdisk(0)partition(1)/ExectOS
KernelFile=xtoskrnl.exe KernelFile=xtoskrnl.exe
Parameters=DEBUG=COM1,115200 NOXPA Parameters=DEBUG=COM1,115200 NOXPA
[ExectOS_NOXPA_FBDEBUG]
SystemName="ExectOS Operating System (NOXPA / FBDEBUG)"
SystemType=XTOS
BootModules=xtos_o
SystemPath=multi(0)disk(0)rdisk(0)partition(1)/ExectOS
KernelFile=xtoskrnl.exe
Parameters=DEBUG=COM1,115200;SCREEN NOXPA
[Windows] [Windows]
SystemName="Microsoft Windows 2000" SystemName="Microsoft Windows 2000"
SystemType=NT50 SystemType=NT50

View File

@@ -20,8 +20,9 @@ set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_C_STANDARD 23) set(CMAKE_C_STANDARD 23)
set(CMAKE_CXX_STANDARD 23) set(CMAKE_CXX_STANDARD 23)
# Disable standard C libraries # Disable standard C and C++ libraries
set(CMAKE_C_STANDARD_LIBRARIES "" CACHE INTERNAL "") set(CMAKE_C_STANDARD_LIBRARIES "" CACHE INTERNAL "")
set(CMAKE_CXX_STANDARD_LIBRARIES "" CACHE INTERNAL "")
# Clean linker flags # Clean linker flags
set(CMAKE_STATIC_LINKER_FLAGS "") set(CMAKE_STATIC_LINKER_FLAGS "")

View File

@@ -1,13 +0,0 @@
## XT Building Kit (XTBK)
The XTBK, or XT Building Kit is a kind of SDK (Software Development Kit) utilized internally by XTOS, the XT Operating
System. It is designed to provide a collection of public functions that are available within the operating system but
not necessarily exposed or accessible to software and driver developers.
Unlike XTDK, which focuses on providing headers for external developers to create kernel mode drivers and user mode
applications, XTBK serves as an extension to XTDK and aids in the code-sharing process between different XTOS
components. This enables the reuse of code across various components of the operating system, resulting in a more
efficient and streamlined development process.
By incorporating XTBK, XTOS can optimize code reuse, particularly in low-level kernel code that can be shared with other
components like the boot loader. This approach helps in reducing code duplication and improving overall code
maintainability. Additionally, it allows for consistent implementation of functionality across different parts of the OS.

View File

@@ -16,26 +16,37 @@
/* Routines used by XTLDR */ /* Routines used by XTLDR */
XTCLINK
XTCDECL XTCDECL
VOID VOID
ArClearInterruptFlag(VOID); ArClearInterruptFlag(VOID);
XTCLINK
XTCDECL XTCDECL
BOOLEAN BOOLEAN
ArCpuId(IN OUT PCPUID_REGISTERS Registers); ArCpuId(IN OUT PCPUID_REGISTERS Registers);
XTCLINK
XTCDECL
VOID
ArEnableExtendedPhysicalAddressing(IN ULONG_PTR PageMap);
XTCLINK
XTCDECL XTCDECL
VOID VOID
ArHalt(VOID); ArHalt(VOID);
XTCLINK
XTCDECL XTCDECL
ULONG_PTR ULONG_PTR
ArReadControlRegister(IN USHORT ControlRegister); ArReadControlRegister(IN USHORT ControlRegister);
XTCLINK
XTCDECL XTCDECL
ULONGLONG ULONGLONG
ArReadModelSpecificRegister(IN ULONG Register); ArReadModelSpecificRegister(IN ULONG Register);
XTCLINK
XTCDECL XTCDECL
VOID VOID
ArWriteControlRegister(IN USHORT ControlRegister, ArWriteControlRegister(IN USHORT ControlRegister,

View File

@@ -39,13 +39,22 @@
#define CR4_PCE 0x00000100 #define CR4_PCE 0x00000100
#define CR4_FXSR 0x00000200 #define CR4_FXSR 0x00000200
#define CR4_XMMEXCPT 0x00000400 #define CR4_XMMEXCPT 0x00000400
#define CR4_UMIP 0x00000800
#define CR4_LA57 0x00001000 #define CR4_LA57 0x00001000
#define CR4_RESERVED1 0x00001800
#define CR4_VMXE 0x00002000 #define CR4_VMXE 0x00002000
#define CR4_SMXE 0x00004000 #define CR4_SMXE 0x00004000
#define CR4_RESERVED2 0x00018000 #define CR4_FSGSBASE 0x00010000
#define CR4_XSAVE 0x00020000 #define CR4_PCIDE 0x00020000
#define CR4_RESERVED3 0xFFFC0000 #define CR4_XSAVE 0x00040000
#define CR4_KL 0x00080000
#define CR4_SMEP 0x00100000
#define CR4_SMAP 0x00200000
#define CR4_PKE 0x00400000
#define CR4_CET 0x00800000
#define CR4_PKS 0x01000000
#define CR4_UINTR 0x02000000
#define CR4_LASS 0x08000000
#define CR4_LAM_SUP 0x10000000
/* Descriptors size */ /* Descriptors size */
#define GDT_ENTRIES 128 #define GDT_ENTRIES 128
@@ -84,6 +93,7 @@
#define X86_MSR_FSBASE 0xC0000100 #define X86_MSR_FSBASE 0xC0000100
#define X86_MSR_GSBASE 0xC0000101 #define X86_MSR_GSBASE 0xC0000101
#define X86_MSR_KERNEL_GSBASE 0xC0000102 #define X86_MSR_KERNEL_GSBASE 0xC0000102
#define X86_MSR_TSC_AUX 0xC0000103
/* Processor features in the EFER MSR */ /* Processor features in the EFER MSR */
#define X86_MSR_EFER_SCE (1 << 0) #define X86_MSR_EFER_SCE (1 << 0)
@@ -91,6 +101,10 @@
#define X86_MSR_EFER_LMA (1 << 10) #define X86_MSR_EFER_LMA (1 << 10)
#define X86_MSR_EFER_NXE (1 << 11) #define X86_MSR_EFER_NXE (1 << 11)
#define X86_MSR_EFER_SVME (1 << 12) #define X86_MSR_EFER_SVME (1 << 12)
#define X86_EFER_LMSLE (1 << 13)
#define X86_EFER_FFXSR (1 << 14)
#define X86_EFER_TCE (1 << 15)
#define X86_EFER_AUTOIBRS (1 << 21)
/* X86 EFLAG bit masks definitions */ /* X86 EFLAG bit masks definitions */
#define X86_EFLAGS_NF_MASK 0x00000000 /* None */ #define X86_EFLAGS_NF_MASK 0x00000000 /* None */

View File

@@ -16,28 +16,34 @@
/* HAL library routines forward references */ /* HAL library routines forward references */
XTCLINK
XTCDECL XTCDECL
UCHAR UCHAR
HlIoPortInByte(IN USHORT Port); HlIoPortInByte(IN USHORT Port);
XTCLINK
XTCDECL XTCDECL
ULONG ULONG
HlIoPortInLong(IN USHORT Port); HlIoPortInLong(IN USHORT Port);
XTCLINK
XTCDECL XTCDECL
USHORT USHORT
HlIoPortInShort(IN USHORT Port); HlIoPortInShort(IN USHORT Port);
XTCLINK
XTCDECL XTCDECL
VOID VOID
HlIoPortOutByte(IN USHORT Port, HlIoPortOutByte(IN USHORT Port,
IN UCHAR Data); IN UCHAR Data);
XTCLINK
XTCDECL XTCDECL
VOID VOID
HlIoPortOutLong(IN USHORT Port, HlIoPortOutLong(IN USHORT Port,
IN ULONG Value); IN ULONG Value);
XTCLINK
XTCDECL XTCDECL
VOID VOID
HlIoPortOutShort(IN USHORT Port, HlIoPortOutShort(IN USHORT Port,

View File

@@ -42,16 +42,6 @@
#define APIC_DF_FLAT 0xFFFFFFFF #define APIC_DF_FLAT 0xFFFFFFFF
#define APIC_DF_CLUSTER 0x0FFFFFFF #define APIC_DF_CLUSTER 0x0FFFFFFF
/* APIC delivery modes */
#define APIC_DM_FIXED 0x00000000
#define APIC_DM_LOWPRIO 0x00000100
#define APIC_DM_SMI 0x00000200
#define APIC_DM_REMOTE 0x00000300
#define APIC_DM_NMI 0x00000400
#define APIC_DM_INIT 0x00000500
#define APIC_DM_STARTUP 0x00000600
#define APIC_DM_EXTINT 0x00000700
/* APIC trigger modes */ /* APIC trigger modes */
#define APIC_TGM_EDGE 0 #define APIC_TGM_EDGE 0
#define APIC_TGM_LEVEL 1 #define APIC_TGM_LEVEL 1
@@ -79,6 +69,35 @@
/* Initial stall factor */ /* Initial stall factor */
#define INITIAL_STALL_FACTOR 100 #define INITIAL_STALL_FACTOR 100
/* APIC delivery mode enumeration list */
typedef enum _APIC_DM
{
APIC_DM_FIXED,
APIC_DM_LOWPRIO,
APIC_DM_SMI,
APIC_DM_REMOTE,
APIC_DM_NMI,
APIC_DM_INIT,
APIC_DM_STARTUP,
APIC_DM_EXTINT,
} APIC_DM, *PAPIC_DM;
/* APIC destination short-hand enumeration list */
typedef enum _APIC_DSH
{
APIC_DSH_Destination,
APIC_DSH_Self,
APIC_DSH_AllIncludingSelf,
APIC_DSH_AllExclusingSelf
} APIC_DSH, *PAPIC_DSH;
/* APIC mode list */
typedef enum _APIC_MODE
{
APIC_MODE_COMPAT,
APIC_MODE_X2APIC
} APIC_MODE, *PAPIC_MODE;
/* APIC Register Address Map */ /* APIC Register Address Map */
typedef enum _APIC_REGISTER typedef enum _APIC_REGISTER
{ {
@@ -116,35 +135,6 @@ typedef enum _APIC_REGISTER
APIC_EXT3LVTR = 0x53 /* Extended Interrupt 3 Local Vector Table */ APIC_EXT3LVTR = 0x53 /* Extended Interrupt 3 Local Vector Table */
} APIC_REGISTER, *PAPIC_REGISTER; } APIC_REGISTER, *PAPIC_REGISTER;
/* APIC mode list */
typedef enum _APIC_MODE
{
APIC_MODE_COMPAT,
APIC_MODE_X2APIC
} APIC_MODE, *PAPIC_MODE;
/* APIC destination short-hand enumeration list */
typedef enum _APIC_DSH
{
APIC_DSH_Destination,
APIC_DSH_Self,
APIC_DSH_AllIncludingSelf,
APIC_DSH_AllExclusingSelf
} APIC_DSH, *PAPIC_DSH;
/* APIC message type enumeration list */
typedef enum _APIC_MT
{
APIC_MT_Fixed,
APIC_MT_LowestPriority,
APIC_MT_SMI,
APIC_MT_RemoteRead,
APIC_MT_NMI,
APIC_MT_INIT,
APIC_MT_Startup,
APIC_MT_ExtInt,
} APIC_MT, *PAPIC_MT;
/* I8259 PIC interrupt mode enumeration list */ /* I8259 PIC interrupt mode enumeration list */
typedef enum _PIC_I8259_ICW1_INTERRUPT_MODE typedef enum _PIC_I8259_ICW1_INTERRUPT_MODE
{ {
@@ -217,7 +207,7 @@ typedef union _APIC_COMMAND_REGISTER
struct struct
{ {
ULONGLONG Vector:8; ULONGLONG Vector:8;
ULONGLONG MessageType:3; ULONGLONG DeliveryMode:3;
ULONGLONG DestinationMode:1; ULONGLONG DestinationMode:1;
ULONGLONG DeliveryStatus:1; ULONGLONG DeliveryStatus:1;
ULONGLONG ReservedMBZ:1; ULONGLONG ReservedMBZ:1;
@@ -237,7 +227,7 @@ typedef union _APIC_LVT_REGISTER
struct struct
{ {
ULONG Vector:8; ULONG Vector:8;
ULONG MessageType:3; ULONG DeliveryMode:3;
ULONG Reserved1:1; ULONG Reserved1:1;
ULONG DeliveryStatus:1; ULONG DeliveryStatus:1;
ULONG Reserved2:1; ULONG Reserved2:1;

View File

@@ -18,11 +18,18 @@
#define MM_PAGE_SHIFT 12L #define MM_PAGE_SHIFT 12L
#define MM_PAGE_SIZE 4096 #define MM_PAGE_SIZE 4096
/* Page directory and page base addresses */ /* Page directory and page base addresses for 4-level paging */
#define MM_PTE_BASE 0xFFFFF68000000000UI64 #define MM_PTE_BASE 0xFFFFF68000000000ULL
#define MM_PDE_BASE 0xFFFFF6FB40000000UI64 #define MM_PDE_BASE 0xFFFFF6FB40000000ULL
#define MM_PPE_BASE 0xFFFFF6FB7DA00000UI64 #define MM_PPE_BASE 0xFFFFF6FB7DA00000ULL
#define MM_PXE_BASE 0xFFFFF6FB7DBED000UI64 #define MM_PXE_BASE 0xFFFFF6FB7DBED000ULL
/* Page directory and page base addresses for 5-level paging */
#define MM_PTE_LA57_BASE 0xFFFF000000000000ULL
#define MM_PDE_LA57_BASE 0xFFFF010000000000ULL
#define MM_PPE_LA57_BASE 0xFFFF010800000000ULL
#define MM_PXE_LA57_BASE 0xFFFF010840000000ULL
#define MM_P5E_LA57_BASE 0xFFFF010840200000ULL
/* PTE shift values */ /* PTE shift values */
#define MM_PTE_SHIFT 3 #define MM_PTE_SHIFT 3
@@ -30,7 +37,7 @@
#define MM_PDI_SHIFT 21 #define MM_PDI_SHIFT 21
#define MM_PPI_SHIFT 30 #define MM_PPI_SHIFT 30
#define MM_PXI_SHIFT 39 #define MM_PXI_SHIFT 39
#define MM_LA57_SHIFT 48 #define MM_P5I_SHIFT 48
/* Number of PTEs per page */ /* Number of PTEs per page */
#define MM_PTE_PER_PAGE 512 #define MM_PTE_PER_PAGE 512
@@ -54,7 +61,10 @@
#define MM_HARDWARE_VA_START 0xFFFFFFFFFFC00000ULL #define MM_HARDWARE_VA_START 0xFFFFFFFFFFC00000ULL
/* Maximum physical address used by HAL allocations */ /* Maximum physical address used by HAL allocations */
#define MM_MAXIMUM_PHYSICAL_ADDRESS 0x00000000FFFFFFFF #define MM_MAXIMUM_PHYSICAL_ADDRESS 0x00000000FFFFFFFFULL
/* Trampoline code address */
#define MM_TRAMPOLINE_ADDRESS 0x80000
/* Page size enumeration list */ /* Page size enumeration list */
typedef enum _PAGE_SIZE typedef enum _PAGE_SIZE
@@ -85,6 +95,18 @@ typedef struct _HARDWARE_PTE
ULONGLONG NoExecute:1; ULONGLONG NoExecute:1;
} HARDWARE_PTE, *PHARDWARE_PTE; } HARDWARE_PTE, *PHARDWARE_PTE;
/* Page map information structure definition */
typedef struct _MMPAGEMAP_INFO
{
BOOLEAN Xpa;
ULONGLONG PteBase;
ULONGLONG PdeBase;
ULONGLONG PpeBase;
ULONGLONG PxeBase;
ULONGLONG P5eBase;
ULONG VaBits;
} MMPAGEMAP_INFO, *PMMPAGEMAP_INFO;
/* A Page Table Entry on AMD64 system */ /* A Page Table Entry on AMD64 system */
typedef struct _MMPTE_HARDWARE typedef struct _MMPTE_HARDWARE
{ {

View File

@@ -13,9 +13,9 @@
/* Architecture-specific enumeration lists forward references */ /* Architecture-specific enumeration lists forward references */
typedef enum _APIC_DM APIC_DM, *PAPIC_DM;
typedef enum _APIC_DSH APIC_DSH, *PAPIC_DSH; typedef enum _APIC_DSH APIC_DSH, *PAPIC_DSH;
typedef enum _APIC_MODE APIC_MODE, *PAPIC_MODE; typedef enum _APIC_MODE APIC_MODE, *PAPIC_MODE;
typedef enum _APIC_MT APIC_MT, *PAPIC_MT;
typedef enum _APIC_REGISTER APIC_REGISTER, *PAPIC_REGISTER; typedef enum _APIC_REGISTER APIC_REGISTER, *PAPIC_REGISTER;
typedef enum _CPU_VENDOR CPU_VENDOR, *PCPU_VENDOR; typedef enum _CPU_VENDOR CPU_VENDOR, *PCPU_VENDOR;
typedef enum _CPUID_FEATURES_EXTENDED CPUID_FEATURES_EXTENDED, *PCPUID_FEATURES_EXTENDED; typedef enum _CPUID_FEATURES_EXTENDED CPUID_FEATURES_EXTENDED, *PCPUID_FEATURES_EXTENDED;
@@ -51,6 +51,7 @@ typedef struct _KSWITCH_FRAME KSWITCH_FRAME, *PKSWITCH_FRAME;
typedef struct _KTHREAD_INIT_FRAME KTHREAD_INIT_FRAME, *PKTHREAD_INIT_FRAME; typedef struct _KTHREAD_INIT_FRAME KTHREAD_INIT_FRAME, *PKTHREAD_INIT_FRAME;
typedef struct _KTRAP_FRAME KTRAP_FRAME, *PKTRAP_FRAME; typedef struct _KTRAP_FRAME KTRAP_FRAME, *PKTRAP_FRAME;
typedef struct _KTSS KTSS, *PKTSS; typedef struct _KTSS KTSS, *PKTSS;
typedef struct _MMPAGEMAP_INFO MMPAGEMAP_INFO, *PMMPAGEMAP_INFO;
typedef struct _MMPFN MMPFN, *PMMPFN; typedef struct _MMPFN MMPFN, *PMMPFN;
typedef struct _MMPTE_HARDWARE MMPTE_HARDWARE, *PMMPTE_HARDWARE; typedef struct _MMPTE_HARDWARE MMPTE_HARDWARE, *PMMPTE_HARDWARE;
typedef struct _MMPTE_HARDWARE_LARGEPAGE MMPTE_HARDWARE_LARGEPAGE, *PMMPTE_HARDWARE_LARGEPAGE; typedef struct _MMPTE_HARDWARE_LARGEPAGE MMPTE_HARDWARE_LARGEPAGE, *PMMPTE_HARDWARE_LARGEPAGE;
@@ -66,6 +67,7 @@ typedef union _APIC_BASE_REGISTER APIC_BASE_REGISTER, *PAPIC_BASE_REGISTER;
typedef union _APIC_COMMAND_REGISTER APIC_COMMAND_REGISTER, *PAPIC_COMMAND_REGISTER; typedef union _APIC_COMMAND_REGISTER APIC_COMMAND_REGISTER, *PAPIC_COMMAND_REGISTER;
typedef union _APIC_LVT_REGISTER APIC_LVT_REGISTER, *PAPIC_LVT_REGISTER; typedef union _APIC_LVT_REGISTER APIC_LVT_REGISTER, *PAPIC_LVT_REGISTER;
typedef union _APIC_SPURIOUS_REGISTER APIC_SPURIOUS_REGISTER, *PAPIC_SPURIOUS_REGISTER; typedef union _APIC_SPURIOUS_REGISTER APIC_SPURIOUS_REGISTER, *PAPIC_SPURIOUS_REGISTER;
typedef union _MMPTE MMP5E, *PMMP5E;
typedef union _MMPTE MMPDE, *PMMPDE; typedef union _MMPTE MMPDE, *PMMPDE;
typedef union _MMPTE MMPPE, *PMMPPE; typedef union _MMPTE MMPPE, *PMMPPE;
typedef union _MMPTE MMPTE, *PMMPTE; typedef union _MMPTE MMPTE, *PMMPTE;

View File

@@ -14,6 +14,7 @@
/* XT BootLoader routines forward references */ /* XT BootLoader routines forward references */
XTCLINK
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
BlGetXtLdrProtocol(IN PEFI_SYSTEM_TABLE SystemTable, BlGetXtLdrProtocol(IN PEFI_SYSTEM_TABLE SystemTable,

View File

@@ -18,10 +18,11 @@
/* EFI XT boot devices */ /* EFI XT boot devices */
#define XTBL_BOOT_DEVICE_UNKNOWN 0x00 #define XTBL_BOOT_DEVICE_UNKNOWN 0x00
#define XTBL_BOOT_DEVICE_CDROM 0x01 #define XTBL_BOOT_DEVICE_ESP 0x01
#define XTBL_BOOT_DEVICE_FLOPPY 0x02 #define XTBL_BOOT_DEVICE_CDROM 0x02
#define XTBL_BOOT_DEVICE_HARDDISK 0x03 #define XTBL_BOOT_DEVICE_FLOPPY 0x04
#define XTBL_BOOT_DEVICE_RAMDISK 0x04 #define XTBL_BOOT_DEVICE_HARDDISK 0x08
#define XTBL_BOOT_DEVICE_RAMDISK 0x10
/* XTLDR Debug Port type definitions */ /* XTLDR Debug Port type definitions */
#define XTBL_DEBUGPORT_SCREEN 1 #define XTBL_DEBUGPORT_SCREEN 1
@@ -43,28 +44,31 @@
typedef LONG (*PBL_GET_MEMTYPE_ROUTINE)(IN EFI_MEMORY_TYPE EfiMemoryType); typedef LONG (*PBL_GET_MEMTYPE_ROUTINE)(IN EFI_MEMORY_TYPE EfiMemoryType);
/* Boot Loader protocol routine pointers */ /* Boot Loader protocol routine pointers */
typedef EFI_STATUS (*PBL_ALLOCATE_PAGES)(IN ULONGLONG Size, OUT PEFI_PHYSICAL_ADDRESS Memory); typedef EFI_STATUS (*PBL_ALLOCATE_PAGES)(IN EFI_ALLOCATE_TYPE AllocationType, IN ULONGLONG Size, OUT PEFI_PHYSICAL_ADDRESS Memory);
typedef EFI_STATUS (*PBL_ALLOCATE_POOL)(IN UINT_PTR Size, OUT PVOID *Memory); typedef EFI_STATUS (*PBL_ALLOCATE_POOL)(IN UINT_PTR Size, OUT PVOID *Memory);
typedef EFI_STATUS (*PBL_BOOTMENU_INITIALIZE_OS_LIST)(OUT PXTBL_BOOTMENU_ITEM *MenuEntries, OUT PULONG EntriesCount, OUT PULONG DefaultId); typedef EFI_STATUS (*PBL_BOOTMENU_INITIALIZE_OS_LIST)(IN ULONG MaxNameLength, OUT PXTBL_BOOTMENU_ITEM *MenuEntries, OUT PULONG EntriesCount, OUT PULONG DefaultId);
typedef BOOLEAN (*PBL_BOOTUTIL_GET_BOOLEAN_PARAMETER)(IN CONST PWCHAR Parameters, IN CONST PWCHAR Needle); typedef BOOLEAN (*PBL_BOOTUTIL_GET_BOOLEAN_PARAMETER)(IN CONST PWCHAR Parameters, IN CONST PWCHAR Needle);
typedef EFI_STATUS (*PBL_BUILD_PAGE_MAP)(IN PXTBL_PAGE_MAPPING PageMap, IN ULONG_PTR SelfMapAddress); typedef EFI_STATUS (*PBL_BUILD_PAGE_MAP)(IN PXTBL_PAGE_MAPPING PageMap, IN ULONG_PTR SelfMapAddress);
typedef EFI_STATUS (*PBL_CLOSE_VOLUME)(IN PEFI_HANDLE VolumeHandle); typedef EFI_STATUS (*PBL_CLOSE_VOLUME)(IN PEFI_HANDLE VolumeHandle);
typedef VOID (*PBL_CLEAR_CONSOLE_LINE)(IN ULONGLONG LineNo); typedef VOID (*PBL_CLEAR_CONSOLE_LINE)(IN ULONGLONG LineNo);
typedef EFI_STATUS (*PBL_CLOSE_XT_PROTOCOL)(IN PEFI_HANDLE Handle, IN PEFI_GUID ProtocolGuid); typedef EFI_STATUS (*PBL_CLOSE_XT_PROTOCOL)(IN PEFI_HANDLE Handle, IN PEFI_GUID ProtocolGuid);
typedef BOOLEAN (*PBL_CONFIG_GET_BOOLEAN_VALUE)(IN CONST PWCHAR ConfigName); typedef BOOLEAN (*PBL_CONFIG_GET_BOOLEAN_VALUE)(IN CONST PWCHAR ConfigName);
typedef PWCHAR (*PBL_CONFIG_GET_VALUE)(IN CONST PWCHAR ConfigName); typedef EFI_STATUS (*PBL_CONFIG_GET_BOOT_OPTION_VALUE)(IN PLIST_ENTRY Options, IN CONST PWCHAR OptionName, OUT PWCHAR *OptionValue);
typedef VOID (*PBL_CONFIG_GET_EDITABLE_OPTIONS)(OUT CONST PWCHAR **OptionsArray, OUT PULONG OptionsCount);
typedef EFI_STATUS (*PBL_CONFIG_GET_VALUE)(IN CONST PWCHAR ConfigName, OUT PWCHAR *ConfigValue);
typedef EFI_STATUS (*PBL_CONFIG_SET_BOOT_OPTION_VALUE)(IN PLIST_ENTRY Options, IN CONST PWCHAR OptionName, IN CONST PWCHAR OptionValue);
typedef VOID (*PBL_CONSOLE_CLEAR_SCREEN)(); typedef VOID (*PBL_CONSOLE_CLEAR_SCREEN)();
typedef VOID (*PBL_CONSOLE_DISABLE_CURSOR)(); typedef VOID (*PBL_CONSOLE_DISABLE_CURSOR)();
typedef VOID (*PBL_CONSOLE_ENABLE_CURSOR)(); typedef VOID (*PBL_CONSOLE_ENABLE_CURSOR)();
typedef VOID (*PBL_CONSOLE_PRINT)(IN PUSHORT Format, IN ...); typedef VOID (*PBL_CONSOLE_PRINT)(IN PCWSTR Format, IN ...);
typedef VOID (*PBL_CONSOLE_QUERY_MODE)(OUT PUINT_PTR ResX, OUT PUINT_PTR ResY); typedef VOID (*PBL_CONSOLE_QUERY_MODE)(OUT PUINT_PTR ResX, OUT PUINT_PTR ResY);
typedef VOID (*PBL_CONSOLE_READ_KEY_STROKE)(OUT PEFI_INPUT_KEY Key); typedef VOID (*PBL_CONSOLE_READ_KEY_STROKE)(OUT PEFI_INPUT_KEY Key);
typedef VOID (*PBL_CONSOLE_RESET_INPUT_BUFFER)(); typedef VOID (*PBL_CONSOLE_RESET_INPUT_BUFFER)();
typedef VOID (*PBL_CONSOLE_SET_ATTRIBUTES)(IN ULONGLONG Attributes); typedef VOID (*PBL_CONSOLE_SET_ATTRIBUTES)(IN ULONGLONG Attributes);
typedef VOID (*PBL_CONSOLE_SET_CURSOR_POSITION)(IN ULONGLONG PosX, IN ULONGLONG PosY); typedef VOID (*PBL_CONSOLE_SET_CURSOR_POSITION)(IN ULONGLONG PosX, IN ULONGLONG PosY);
typedef VOID (*PBL_CONSOLE_WRITE)(IN PUSHORT String); typedef VOID (*PBL_CONSOLE_WRITE)(IN PCWSTR String);
typedef VOID (XTAPI *PBL_COPY_MEMORY)(OUT PVOID Destination, IN PCVOID Source, IN SIZE_T Length); typedef VOID (XTAPI *PBL_COPY_MEMORY)(OUT PVOID Destination, IN PCVOID Source, IN SIZE_T Length);
typedef VOID (*PBL_DEBUG_PRINT)(IN PUSHORT Format, IN ...); typedef VOID (*PBL_DEBUG_PRINT)(IN PCWSTR Format, IN ...);
typedef EFI_STATUS (*PBL_ENTER_FIRMWARE_SETUP)(); typedef EFI_STATUS (*PBL_ENTER_FIRMWARE_SETUP)();
typedef EFI_STATUS (*PBL_EXIT_BOOT_SERVICES)(); typedef EFI_STATUS (*PBL_EXIT_BOOT_SERVICES)();
typedef EFI_STATUS (*PBL_FIND_BOOT_PROTOCOL)(IN PWCHAR SystemType, OUT PEFI_GUID BootProtocolGuid); typedef EFI_STATUS (*PBL_FIND_BOOT_PROTOCOL)(IN PWCHAR SystemType, OUT PEFI_GUID BootProtocolGuid);
@@ -153,6 +157,7 @@ typedef struct _XTBL_BOOT_PARAMETERS
typedef struct _XTBL_BOOTMENU_ITEM typedef struct _XTBL_BOOTMENU_ITEM
{ {
PWCHAR EntryName; PWCHAR EntryName;
PWCHAR FullName;
PWCHAR ShortName; PWCHAR ShortName;
PLIST_ENTRY Options; PLIST_ENTRY Options;
} XTBL_BOOTMENU_ITEM, *PXTBL_BOOTMENU_ITEM; } XTBL_BOOTMENU_ITEM, *PXTBL_BOOTMENU_ITEM;
@@ -361,7 +366,10 @@ typedef struct _XTBL_LOADER_PROTOCOL
struct struct
{ {
PBL_CONFIG_GET_BOOLEAN_VALUE GetBooleanValue; PBL_CONFIG_GET_BOOLEAN_VALUE GetBooleanValue;
PBL_CONFIG_GET_BOOT_OPTION_VALUE GetBootOptionValue;
PBL_CONFIG_GET_EDITABLE_OPTIONS GetEditableOptions;
PBL_CONFIG_GET_VALUE GetValue; PBL_CONFIG_GET_VALUE GetValue;
PBL_CONFIG_SET_BOOT_OPTION_VALUE SetBootOptionValue;
} Config; } Config;
struct struct
{ {

View File

@@ -14,26 +14,32 @@
/* Kernel Executive routines forward references */ /* Kernel Executive routines forward references */
XTCLINK
XTFASTCALL XTFASTCALL
BOOLEAN BOOLEAN
ExAcquireRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor); ExAcquireRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor);
XTCLINK
XTFASTCALL XTFASTCALL
VOID VOID
ExCompleteRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor); ExCompleteRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor);
XTCLINK
XTFASTCALL XTFASTCALL
VOID VOID
ExInitializeRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor); ExInitializeRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor);
XTCLINK
XTFASTCALL XTFASTCALL
VOID VOID
ExReInitializeRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor); ExReInitializeRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor);
XTCLINK
XTFASTCALL XTFASTCALL
VOID VOID
ExReleaseRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor); ExReleaseRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor);
XTCLINK
XTFASTCALL XTFASTCALL
VOID VOID
ExWaitForRundownProtectionRelease(IN PEX_RUNDOWN_REFERENCE Descriptor); ExWaitForRundownProtectionRelease(IN PEX_RUNDOWN_REFERENCE Descriptor);

View File

@@ -15,11 +15,13 @@
/* Routines used by XTLDR */ /* Routines used by XTLDR */
XTCLINK
XTCDECL XTCDECL
XTSTATUS XTSTATUS
HlComPortPutByte(IN PCPPORT Port, HlComPortPutByte(IN PCPPORT Port,
IN UCHAR Byte); IN UCHAR Byte);
XTCLINK
XTCDECL XTCDECL
XTSTATUS XTSTATUS
HlInitializeComPort(IN OUT PCPPORT Port, HlInitializeComPort(IN OUT PCPPORT Port,

View File

@@ -366,8 +366,8 @@ typedef struct _CPPORT
UCHAR Ring; UCHAR Ring;
} CPPORT, *PCPPORT; } CPPORT, *PCPPORT;
/* HAL framebuffer data structure */ /* Framebuffer data structure */
typedef struct _HAL_FRAMEBUFFER_DATA typedef struct _HL_FRAMEBUFFER_DATA
{ {
BOOLEAN Initialized; BOOLEAN Initialized;
PVOID Address; PVOID Address;
@@ -375,7 +375,7 @@ typedef struct _HAL_FRAMEBUFFER_DATA
UINT Width; UINT Width;
UINT Height; UINT Height;
UINT PixelsPerScanLine; UINT PixelsPerScanLine;
UINT BitsPerPixel; UINT BytesPerPixel;
UINT Pitch; UINT Pitch;
PVOID Font; PVOID Font;
struct struct
@@ -389,7 +389,22 @@ typedef struct _HAL_FRAMEBUFFER_DATA
USHORT ReservedShift; USHORT ReservedShift;
USHORT ReservedSize; USHORT ReservedSize;
} Pixels; } Pixels;
} HAL_FRAMEBUFFER_DATA, *PHAL_FRAMEBUFFER_DATA; } HL_FRAMEBUFFER_DATA, *PHL_FRAMEBUFFER_DATA;
/* Scroll region data structure */
typedef struct _HL_SCROLL_REGION_DATA
{
ULONG Left;
ULONG Top;
ULONG Right;
ULONG Bottom;
ULONG WidthInChars;
ULONG HeightInChars;
ULONG CursorX;
ULONG CursorY;
ULONG BackgroundColor;
ULONG TextColor;
} HL_SCROLL_REGION_DATA, *PHL_SCROLL_REGION_DATA;
/* Processor identity structure */ /* Processor identity structure */
typedef struct _PROCESSOR_IDENTITY typedef struct _PROCESSOR_IDENTITY

View File

@@ -16,26 +16,32 @@
/* Routines used by XTLDR */ /* Routines used by XTLDR */
XTCLINK
XTCDECL XTCDECL
VOID VOID
ArClearInterruptFlag(VOID); ArClearInterruptFlag(VOID);
XTCLINK
XTCDECL XTCDECL
BOOLEAN BOOLEAN
ArCpuId(IN OUT PCPUID_REGISTERS Registers); ArCpuId(IN OUT PCPUID_REGISTERS Registers);
XTCLINK
XTCDECL XTCDECL
VOID VOID
ArHalt(VOID); ArHalt(VOID);
XTCLINK
XTCDECL XTCDECL
ULONG_PTR ULONG_PTR
ArReadControlRegister(IN USHORT ControlRegister); ArReadControlRegister(IN USHORT ControlRegister);
XTCLINK
XTCDECL XTCDECL
ULONGLONG ULONGLONG
ArReadModelSpecificRegister(IN ULONG Register); ArReadModelSpecificRegister(IN ULONG Register);
XTCLINK
XTCDECL XTCDECL
VOID VOID
ArWriteControlRegister(IN USHORT ControlRegister, ArWriteControlRegister(IN USHORT ControlRegister,

View File

@@ -39,13 +39,22 @@
#define CR4_PCE 0x00000100 #define CR4_PCE 0x00000100
#define CR4_FXSR 0x00000200 #define CR4_FXSR 0x00000200
#define CR4_XMMEXCPT 0x00000400 #define CR4_XMMEXCPT 0x00000400
#define CR4_UMIP 0x00000800
#define CR4_LA57 0x00001000 #define CR4_LA57 0x00001000
#define CR4_RESERVED1 0x00001800
#define CR4_VMXE 0x00002000 #define CR4_VMXE 0x00002000
#define CR4_SMXE 0x00004000 #define CR4_SMXE 0x00004000
#define CR4_RESERVED2 0x00018000 #define CR4_FSGSBASE 0x00010000
#define CR4_XSAVE 0x00020000 #define CR4_PCIDE 0x00020000
#define CR4_RESERVED3 0xFFFC0000 #define CR4_XSAVE 0x00040000
#define CR4_KL 0x00080000
#define CR4_SMEP 0x00100000
#define CR4_SMAP 0x00200000
#define CR4_PKE 0x00400000
#define CR4_CET 0x00800000
#define CR4_PKS 0x01000000
#define CR4_UINTR 0x02000000
#define CR4_LASS 0x08000000
#define CR4_LAM_SUP 0x10000000
/* Descriptors size */ /* Descriptors size */
#define GDT_ENTRIES 128 #define GDT_ENTRIES 128

View File

@@ -16,28 +16,34 @@
/* HAL library routines forward references */ /* HAL library routines forward references */
XTCLINK
XTCDECL XTCDECL
UCHAR UCHAR
HlIoPortInByte(IN USHORT Port); HlIoPortInByte(IN USHORT Port);
XTCLINK
XTCDECL XTCDECL
ULONG ULONG
HlIoPortInLong(IN USHORT Port); HlIoPortInLong(IN USHORT Port);
XTCLINK
XTCDECL XTCDECL
USHORT USHORT
HlIoPortInShort(IN USHORT Port); HlIoPortInShort(IN USHORT Port);
XTCLINK
XTCDECL XTCDECL
VOID VOID
HlIoPortOutByte(IN USHORT Port, HlIoPortOutByte(IN USHORT Port,
IN UCHAR Data); IN UCHAR Data);
XTCLINK
XTCDECL XTCDECL
VOID VOID
HlIoPortOutLong(IN USHORT Port, HlIoPortOutLong(IN USHORT Port,
IN ULONG Value); IN ULONG Value);
XTCLINK
XTCDECL XTCDECL
VOID VOID
HlIoPortOutShort(IN USHORT Port, HlIoPortOutShort(IN USHORT Port,

View File

@@ -47,16 +47,6 @@
#define APIC_DF_FLAT 0xFFFFFFFF #define APIC_DF_FLAT 0xFFFFFFFF
#define APIC_DF_CLUSTER 0x0FFFFFFF #define APIC_DF_CLUSTER 0x0FFFFFFF
/* APIC delivery modes */
#define APIC_DM_FIXED 0x00000000
#define APIC_DM_LOWPRIO 0x00000100
#define APIC_DM_SMI 0x00000200
#define APIC_DM_REMOTE 0x00000300
#define APIC_DM_NMI 0x00000400
#define APIC_DM_INIT 0x00000500
#define APIC_DM_STARTUP 0x00000600
#define APIC_DM_EXTINT 0x00000700
/* APIC trigger modes */ /* APIC trigger modes */
#define APIC_TGM_EDGE 0 #define APIC_TGM_EDGE 0
#define APIC_TGM_LEVEL 1 #define APIC_TGM_LEVEL 1
@@ -86,6 +76,35 @@
/* Initial stall factor */ /* Initial stall factor */
#define INITIAL_STALL_FACTOR 100 #define INITIAL_STALL_FACTOR 100
/* APIC delivery mode enumeration list */
typedef enum _APIC_DM
{
APIC_DM_FIXED,
APIC_DM_LOWPRIO,
APIC_DM_SMI,
APIC_DM_REMOTE,
APIC_DM_NMI,
APIC_DM_INIT,
APIC_DM_STARTUP,
APIC_DM_EXTINT,
} APIC_DM, *PAPIC_DM;
/* APIC destination short-hand enumeration list */
typedef enum _APIC_DSH
{
APIC_DSH_Destination,
APIC_DSH_Self,
APIC_DSH_AllIncludingSelf,
APIC_DSH_AllExclusingSelf
} APIC_DSH, *PAPIC_DSH;
/* APIC mode list */
typedef enum _APIC_MODE
{
APIC_MODE_COMPAT,
APIC_MODE_X2APIC
} APIC_MODE, *PAPIC_MODE;
/* APIC Register Address Map */ /* APIC Register Address Map */
typedef enum _APIC_REGISTER typedef enum _APIC_REGISTER
{ {
@@ -123,35 +142,6 @@ typedef enum _APIC_REGISTER
APIC_EXT3LVTR = 0x53 /* Extended Interrupt 3 Local Vector Table */ APIC_EXT3LVTR = 0x53 /* Extended Interrupt 3 Local Vector Table */
} APIC_REGISTER, *PAPIC_REGISTER; } APIC_REGISTER, *PAPIC_REGISTER;
/* APIC mode list */
typedef enum _APIC_MODE
{
APIC_MODE_COMPAT,
APIC_MODE_X2APIC
} APIC_MODE, *PAPIC_MODE;
/* APIC destination short-hand enumeration list */
typedef enum _APIC_DSH
{
APIC_DSH_Destination,
APIC_DSH_Self,
APIC_DSH_AllIncludingSelf,
APIC_DSH_AllExclusingSelf
} APIC_DSH, *PAPIC_DSH;
/* APIC message type enumeration list */
typedef enum _APIC_MT
{
APIC_MT_Fixed,
APIC_MT_LowestPriority,
APIC_MT_SMI,
APIC_MT_RemoteRead,
APIC_MT_NMI,
APIC_MT_INIT,
APIC_MT_Startup,
APIC_MT_ExtInt,
} APIC_MT, *PAPIC_MT;
/* I8259 PIC interrupt mode enumeration list */ /* I8259 PIC interrupt mode enumeration list */
typedef enum _PIC_I8259_ICW1_INTERRUPT_MODE typedef enum _PIC_I8259_ICW1_INTERRUPT_MODE
{ {
@@ -224,7 +214,7 @@ typedef union _APIC_COMMAND_REGISTER
struct struct
{ {
ULONGLONG Vector:8; ULONGLONG Vector:8;
ULONGLONG MessageType:3; ULONGLONG DeliveryMode:3;
ULONGLONG DestinationMode:1; ULONGLONG DestinationMode:1;
ULONGLONG DeliveryStatus:1; ULONGLONG DeliveryStatus:1;
ULONGLONG ReservedMBZ:1; ULONGLONG ReservedMBZ:1;
@@ -244,7 +234,7 @@ typedef union _APIC_LVT_REGISTER
struct struct
{ {
ULONG Vector:8; ULONG Vector:8;
ULONG MessageType:3; ULONG DeliveryMode:3;
ULONG Reserved1:1; ULONG Reserved1:1;
ULONG DeliveryStatus:1; ULONG DeliveryStatus:1;
ULONG Reserved2:1; ULONG Reserved2:1;

View File

@@ -28,7 +28,11 @@
#define MM_PDI_SHIFT 21 #define MM_PDI_SHIFT 21
#define MM_PPI_SHIFT 30 #define MM_PPI_SHIFT 30
/* Page directory and page base legacy address */
#define MM_PDE_LEGACY_BASE 0xC0300000
/* PTE legacy shift values */ /* PTE legacy shift values */
#define MM_PTE_LEGACY_SHIFT 2
#define MM_PDI_LEGACY_SHIFT 22 #define MM_PDI_LEGACY_SHIFT 22
/* Minimum number of physical pages needed by the system */ /* Minimum number of physical pages needed by the system */
@@ -49,6 +53,8 @@
/* Maximum physical address used by HAL allocations */ /* Maximum physical address used by HAL allocations */
#define MM_MAXIMUM_PHYSICAL_ADDRESS 0xFFFFFFFF #define MM_MAXIMUM_PHYSICAL_ADDRESS 0xFFFFFFFF
/* Trampoline code address */
#define MM_TRAMPOLINE_ADDRESS 0x80000
/* Page size enumeration list */ /* Page size enumeration list */
typedef enum _PAGE_SIZE typedef enum _PAGE_SIZE
@@ -58,8 +64,26 @@ typedef enum _PAGE_SIZE
Size4M Size4M
} PAGE_SIZE, *PPAGE_SIZE; } PAGE_SIZE, *PPAGE_SIZE;
/* Page Table entry structure definition (with PAE support) */ /* Legacy Page Table entry structure definition (PML2) */
typedef struct _HARDWARE_PTE typedef struct _HARDWARE_LEGACY_PTE
{
ULONG Valid:1;
ULONG Writable:1;
ULONG Owner:1;
ULONG WriteThrough:1;
ULONG CacheDisable:1;
ULONG Accessed:1;
ULONG Dirty:1;
ULONG LargePage:1;
ULONG Global:1;
ULONG CopyOnWrite:1;
ULONG Prototype:1;
ULONG Reserved0:1;
ULONG PageFrameNumber:20;
} HARDWARE_LEGACY_PTE, *PHARDWARE_LEGACY_PTE;
/* Page Table entry structure definition (PML3) */
typedef struct _HARDWARE_MODERN_PTE
{ {
ULONGLONG Valid:1; ULONGLONG Valid:1;
ULONGLONG Writable:1; ULONGLONG Writable:1;
@@ -77,10 +101,117 @@ typedef struct _HARDWARE_PTE
ULONGLONG Reserved1:14; ULONGLONG Reserved1:14;
ULONGLONG SoftwareWsIndex:11; ULONGLONG SoftwareWsIndex:11;
ULONGLONG NoExecute:1; ULONGLONG NoExecute:1;
} HARDWARE_MODERN_PTE, *PHARDWARE_MODERN_PTE;
/* Generic Page Table entry union to abstract PML2 and PML3 formats */
typedef union _HARDWARE_PTE
{
ULONGLONG Long;
HARDWARE_LEGACY_PTE Pml2;
HARDWARE_MODERN_PTE Pml3;
} HARDWARE_PTE, *PHARDWARE_PTE; } HARDWARE_PTE, *PHARDWARE_PTE;
/* Page Table Entry on PAE enabled system */ /* Page map information structure definition */
typedef struct _MMPTE_HARDWARE typedef struct _MMPAGEMAP_INFO
{
BOOLEAN Xpa;
ULONG PteBase;
ULONG PdeBase;
ULONG PdiShift;
ULONG PteShift;
} MMPAGEMAP_INFO, *PMMPAGEMAP_INFO;
/* Legacy Page Table Entry hardware structure definition (PML2) */
typedef struct _MMPML2_PTE_HARDWARE
{
ULONG Valid:1;
ULONG Writable:1;
ULONG Owner:1;
ULONG WriteThrough:1;
ULONG CacheDisable:1;
ULONG Accessed:1;
ULONG Dirty:1;
ULONG LargePage:1;
ULONG Global:1;
ULONG CopyOnWrite:1;
ULONG Prototype:1;
ULONG Write:1;
ULONG PageFrameNumber:20;
} MMPML2_PTE_HARDWARE, *PMMPML2_PTE_HARDWARE;
/* Legacy Page Table Entry list structure definition (PML2) */
typedef struct _MMPML2_PTE_LIST
{
ULONG Valid:1;
ULONG OneEntry:1;
ULONG Reserved0:8;
ULONG Prototype:1;
ULONG Reserved1:1;
ULONG NextEntry:20;
} MMPML2_PTE_LIST, *PMMPML2_PTE_LIST;
/* Legacy Page Table Entry subsection structure definition (PML2) */
typedef struct _MMPML2_PTE_PROTOTYPE
{
ULONG Valid:1;
ULONG ProtoAddressLow:7;
ULONG ReadOnly:1;
ULONG WhichPool:1;
ULONG Prototype:1;
ULONG ProtoAddressHigh:21;
} MMPML2_PTE_PROTOTYPE, *PMMPML2_PTE_PROTOTYPE;
/* Legacy Page Table Entry software structure definition (PML2) */
typedef struct _MMPML2_PTE_SOFTWARE
{
ULONG Valid:1;
ULONG PageFileLow:4;
ULONG Protection:5;
ULONG Prototype:1;
ULONG Transition:1;
ULONG PageFileHigh:20;
} MMPML2_PTE_SOFTWARE, *PMMPML2_PTE_SOFTWARE;
/* Legacy Page Table Entry subsection structure definition (PML2) */
typedef struct _MMPML2_PTE_SUBSECTION
{
ULONG Valid:1;
ULONG SubsectionAddressLow:4;
ULONG Protection:5;
ULONG Prototype:1;
ULONG SubsectionAddressHigh:20;
ULONG WhichPool:1;
} MMPML2_PTE_SUBSECTION, *PMMPML2_PTE_SUBSECTION;
/* Legacy Page Table Entry transition structure definition (PML2) */
typedef struct _MMPML2_PTE_TRANSITION
{
ULONG Valid:1;
ULONG Write:1;
ULONG Owner:1;
ULONG WriteThrough:1;
ULONG CacheDisable:1;
ULONG Protection:5;
ULONG Prototype:1;
ULONG Transition:1;
ULONG PageFrameNumber:20;
} MMPML2_PTE_TRANSITION, *PMMPML2_PTE_TRANSITION;
/* Legacy Page Table Entry union definition (PML2) */
typedef union _MMPML2_PTE
{
ULONG Long;
HARDWARE_PTE Flush;
MMPML2_PTE_HARDWARE Hard;
MMPML2_PTE_PROTOTYPE Proto;
MMPML2_PTE_SOFTWARE Soft;
MMPML2_PTE_TRANSITION Trans;
MMPML2_PTE_SUBSECTION Subsect;
MMPML2_PTE_LIST List;
} MMPML2_PTE, *PMMPML2_PTE;
/* Page Table Entry hardware structure definition (PML3) */
typedef struct _MMPML3_PTE_HARDWARE
{ {
ULONGLONG Valid:1; ULONGLONG Valid:1;
ULONGLONG Writable:1; ULONGLONG Writable:1;
@@ -95,59 +226,59 @@ typedef struct _MMPTE_HARDWARE
ULONGLONG Prototype:1; ULONGLONG Prototype:1;
ULONGLONG Write:1; ULONGLONG Write:1;
ULONGLONG PageFrameNumber:26; ULONGLONG PageFrameNumber:26;
ULONGLONG Reserved1:25; ULONGLONG Reserved0:25;
ULONGLONG NoExecute:1; ULONGLONG NoExecute:1;
} MMPTE_HARDWARE, *PMMPTE_HARDWARE; } MMPML3_PTE_HARDWARE, *PMMPML3_PTE_HARDWARE;
/* Page Table Entry list structure definition (with PAE support) */ /* Page Table Entry list structure definition (PML3) */
typedef struct _MMPTE_LIST typedef struct _MMPML3_PTE_LIST
{ {
ULONGLONG Valid:1; ULONGLONG Valid:1;
ULONGLONG OneEntry:1; ULONGLONG OneEntry:1;
ULONGLONG Reserved1:8; ULONGLONG Reserved0:8;
ULONGLONG Prototype:1; ULONGLONG Prototype:1;
ULONGLONG Reserved2:21; ULONGLONG Reserved1:21;
ULONGLONG NextEntry:32; ULONGLONG NextEntry:32;
} MMPTE_LIST, *PMMPTE_LIST; } MMPML3_PTE_LIST, *PMMPML3_PTE_LIST;
/* Page Table Entry subsection structure definition (with PAE support) */ /* Page Table Entry subsection structure definition (PML3) */
typedef struct _MMPTE_PROTOTYPE typedef struct _MMPML3_PTE_PROTOTYPE
{ {
ULONGLONG Valid:1; ULONGLONG Valid:1;
ULONGLONG Reserved1:7; ULONGLONG Reserved0:7;
ULONGLONG ReadOnly:1; ULONGLONG ReadOnly:1;
ULONGLONG Reserved2:1; ULONGLONG Reserved1:1;
ULONGLONG Prototype:1; ULONGLONG Prototype:1;
ULONGLONG Protection:5; ULONGLONG Protection:5;
ULONGLONG Reserved3:16; ULONGLONG Reserved2:16;
ULONGLONG ProtoAddress:32; ULONGLONG ProtoAddress:32;
} MMPTE_PROTOTYPE, *PMMPTE_PROTOTYPE; } MMPML3_PTE_PROTOTYPE, *PMMPML3_PTE_PROTOTYPE;
/* Page Table Entry software structure definition (with PAE support) */ /* Page Table Entry software structure definition (PML3) */
typedef struct _MMPTE_SOFTWARE typedef struct _MMPML3_PTE_SOFTWARE
{ {
ULONGLONG Valid:1; ULONGLONG Valid:1;
ULONGLONG PageFileLow:4; ULONGLONG PageFileLow:4;
ULONGLONG Protection:5; ULONGLONG Protection:5;
ULONGLONG Prototype:1; ULONGLONG Prototype:1;
ULONGLONG Transition:1; ULONGLONG Transition:1;
ULONGLONG Reserved1:20; ULONGLONG Reserved0:20;
ULONGLONG PageFileHigh:32; ULONGLONG PageFileHigh:32;
} MMPTE_SOFTWARE, *PMMPTE_SOFTWARE; } MMPML3_PTE_SOFTWARE, *PMMPML3_PTE_SOFTWARE;
/* Page Table Entry subsection structure definition (with PAE support) */ /* Page Table Entry subsection structure definition (PML3) */
typedef struct _MMPTE_SUBSECTION typedef struct _MMPML3_PTE_SUBSECTION
{ {
ULONGLONG Valid:1; ULONGLONG Valid:1;
ULONGLONG Reserved1:4; ULONGLONG Reserved0:4;
ULONGLONG Protection:5; ULONGLONG Protection:5;
ULONGLONG Prototype:1; ULONGLONG Prototype:1;
ULONGLONG Reserved2:21; ULONGLONG Reserved1:21;
ULONGLONG SubsectionAddress:32; ULONGLONG SubsectionAddress:32;
} MMPTE_SUBSECTION, *PMMPTE_SUBSECTION; } MMPML3_PTE_SUBSECTION, *PMMPML3_PTE_SUBSECTION;
/* Page Table Entry transition structure definition (with PAE support) */ /* Page Table Entry transition structure definition (PML3) */
typedef struct _MMPTE_TRANSITION typedef struct _MMPML3_PTE_TRANSITION
{ {
ULONGLONG Valid:1; ULONGLONG Valid:1;
ULONGLONG Write:1; ULONGLONG Write:1;
@@ -159,38 +290,28 @@ typedef struct _MMPTE_TRANSITION
ULONGLONG Transition:1; ULONGLONG Transition:1;
ULONGLONG PageFrameNumber:26; ULONGLONG PageFrameNumber:26;
ULONGLONG Unused:26; ULONGLONG Unused:26;
} MMPTE_TRANSITION, *PMMPTE_TRANSITION; } MMPML3_PTE_TRANSITION, *PMMPML3_PTE_TRANSITION;
/* Page Table Entry structure definition (with PAE support) */ /* Page Table Entry union definition (PML3) */
typedef union _MMPTE typedef union _MMPML3_PTE
{ {
ULONGLONG Long; ULONGLONG Long;
HARDWARE_PTE Flush; HARDWARE_PTE Flush;
MMPTE_HARDWARE Hardware; MMPML3_PTE_HARDWARE Hardware;
MMPTE_PROTOTYPE Prototype; MMPML3_PTE_PROTOTYPE Prototype;
MMPTE_SOFTWARE Software; MMPML3_PTE_SOFTWARE Software;
MMPTE_TRANSITION Transition; MMPML3_PTE_TRANSITION Transition;
MMPTE_SUBSECTION Subsection; MMPML3_PTE_SUBSECTION Subsection;
MMPTE_LIST List; MMPML3_PTE_LIST List;
} MMPTE, *PMMPTE; } MMPML3_PTE, *PMMPML3_PTE;
/* Legacy Page Table entry structure definition (without PAE support) */ /* Generic Page Table Entry union to abstract PML2 and PML3 formats */
typedef struct _HARDWARE_LEGACY_PTE typedef union _MMPTE
{ {
ULONG Valid:1; ULONGLONG Long;
ULONG Writable:1; MMPML2_PTE Pml2;
ULONG Owner:1; MMPML3_PTE Pml3;
ULONG WriteThrough:1; } MMPTE, *PMMPTE;
ULONG CacheDisable:1;
ULONG Accessed:1;
ULONG Dirty:1;
ULONG LargePage:1;
ULONG Global:1;
ULONG CopyOnWrite:1;
ULONG Prototype:1;
ULONG Reserved0:1;
ULONG PageFrameNumber:20;
} HARDWARE_LEGACY_PTE, *PHARDWARE_LEGACY_PTE;
/* Page Frame Number structure definition */ /* Page Frame Number structure definition */
typedef struct _MMPFN typedef struct _MMPFN

View File

@@ -13,9 +13,9 @@
/* Architecture-specific enumeration lists forward references */ /* Architecture-specific enumeration lists forward references */
typedef enum _APIC_DM APIC_DM, *PAPIC_DM;
typedef enum _APIC_DSH APIC_DSH, *PAPIC_DSH; typedef enum _APIC_DSH APIC_DSH, *PAPIC_DSH;
typedef enum _APIC_MODE APIC_MODE, *PAPIC_MODE; typedef enum _APIC_MODE APIC_MODE, *PAPIC_MODE;
typedef enum _APIC_MT APIC_MT, *PAPIC_MT;
typedef enum _APIC_REGISTER APIC_REGISTER, *PAPIC_REGISTER; typedef enum _APIC_REGISTER APIC_REGISTER, *PAPIC_REGISTER;
typedef enum _CPU_VENDOR CPU_VENDOR, *PCPU_VENDOR; typedef enum _CPU_VENDOR CPU_VENDOR, *PCPU_VENDOR;
typedef enum _CPUID_FEATURES_EXTENDED CPUID_FEATURES_EXTENDED, *PCPUID_FEATURES_EXTENDED; typedef enum _CPUID_FEATURES_EXTENDED CPUID_FEATURES_EXTENDED, *PCPUID_FEATURES_EXTENDED;
@@ -40,7 +40,7 @@ typedef struct _FN_SAVE_FORMAT FN_SAVE_FORMAT, *PFN_SAVE_FORMAT;
typedef struct _FX_SAVE_AREA FX_SAVE_AREA, *PFX_SAVE_AREA; typedef struct _FX_SAVE_AREA FX_SAVE_AREA, *PFX_SAVE_AREA;
typedef struct _FX_SAVE_FORMAT FX_SAVE_FORMAT, *PFX_SAVE_FORMAT; typedef struct _FX_SAVE_FORMAT FX_SAVE_FORMAT, *PFX_SAVE_FORMAT;
typedef struct _HARDWARE_LEGACY_PTE HARDWARE_LEGACY_PTE, *PHARDWARE_LEGACY_PTE; typedef struct _HARDWARE_LEGACY_PTE HARDWARE_LEGACY_PTE, *PHARDWARE_LEGACY_PTE;
typedef struct _HARDWARE_PTE HARDWARE_PTE, *PHARDWARE_PTE; typedef struct _HARDWARE_MODERN_PTE HARDWARE_MODERN_PTE, *PHARDWARE_MODERN_PTE;
typedef struct _KDESCRIPTOR KDESCRIPTOR, *PKDESCRIPTOR; typedef struct _KDESCRIPTOR KDESCRIPTOR, *PKDESCRIPTOR;
typedef struct _KEXCEPTION_FRAME KEXCEPTION_FRAME, *PKEXCEPTION_FRAME; typedef struct _KEXCEPTION_FRAME KEXCEPTION_FRAME, *PKEXCEPTION_FRAME;
typedef struct _KGDTENTRY KGDTENTRY, *PKGDTENTRY; typedef struct _KGDTENTRY KGDTENTRY, *PKGDTENTRY;
@@ -55,13 +55,20 @@ typedef struct _KSWITCH_FRAME KSWITCH_FRAME, *PKSWITCH_FRAME;
typedef struct _KTHREAD_INIT_FRAME KTHREAD_INIT_FRAME, *PKTHREAD_INIT_FRAME; typedef struct _KTHREAD_INIT_FRAME KTHREAD_INIT_FRAME, *PKTHREAD_INIT_FRAME;
typedef struct _KTRAP_FRAME KTRAP_FRAME, *PKTRAP_FRAME; typedef struct _KTRAP_FRAME KTRAP_FRAME, *PKTRAP_FRAME;
typedef struct _KTSS KTSS, *PKTSS; typedef struct _KTSS KTSS, *PKTSS;
typedef struct _MMPAGEMAP_INFO MMPAGEMAP_INFO, *PMMPAGEMAP_INFO;
typedef struct _MMPFN MMPFN, *PMMPFN; typedef struct _MMPFN MMPFN, *PMMPFN;
typedef struct _MMPTE_HARDWARE MMPTE_HARDWARE, *PMMPTE_HARDWARE; typedef struct _MMPML2_PTE_HARDWARE MMPML2_PTE_HARDWARE, *PMMPML2_PTE_HARDWARE;
typedef struct _MMPTE_LIST MMPTE_LIST, *PMMPTE_LIST; typedef struct _MMPML2_PTE_LIST MMPML2_PTE_LIST, *PMMPML2_PTE_LIST;
typedef struct _MMPTE_PROTOTYPE MMPTE_PROTOTYPE, *PMMPTE_PROTOTYPE; typedef struct _MMPML2_PTE_PROTOTYPE MMPML2_PTE_PROTOTYPE, *PMMPML2_PTE_PROTOTYPE;
typedef struct _MMPTE_SOFTWARE MMPTE_SOFTWARE, *PMMPTE_SOFTWARE; typedef struct _MMPML2_PTE_SOFTWARE MMPML2_PTE_SOFTWARE, *PMMPML2_PTE_SOFTWARE;
typedef struct _MMPTE_SUBSECTION MMPTE_SUBSECTION, *PMMPTE_SUBSECTION; typedef struct _MMPML2_PTE_SUBSECTION MMPML2_PTE_SUBSECTION, *PMMPML2_PTE_SUBSECTION;
typedef struct _MMPTE_TRANSITION MMPTE_TRANSITION, *PMMPTE_TRANSITION; typedef struct _MMPML2_PTE_TRANSITION MMPML2_PTE_TRANSITION, *PMMPML2_PTE_TRANSITION;
typedef struct _MMPML3_PTE_HARDWARE MMPML3_PTE_HARDWARE, *PMMPML3_PTE_HARDWARE;
typedef struct _MMPML3_PTE_LIST MMPML3_PTE_LIST, *PMMPML3_PTE_LIST;
typedef struct _MMPML3_PTE_PROTOTYPE MMPML3_PTE_PROTOTYPE, *PMMPML3_PTE_PROTOTYPE;
typedef struct _MMPML3_PTE_SOFTWARE MMPML3_PTE_SOFTWARE, *PMMPML3_PTE_SOFTWARE;
typedef struct _MMPML3_PTE_SUBSECTION MMPML3_PTE_SUBSECTION, *PMMPML3_PTE_SUBSECTION;
typedef struct _MMPML3_PTE_TRANSITION MMPML3_PTE_TRANSITION, *PMMPML3_PTE_TRANSITION;
typedef struct _THREAD_ENVIRONMENT_BLOCK THREAD_ENVIRONMENT_BLOCK, *PTHREAD_ENVIRONMENT_BLOCK; typedef struct _THREAD_ENVIRONMENT_BLOCK THREAD_ENVIRONMENT_BLOCK, *PTHREAD_ENVIRONMENT_BLOCK;
/* Unions forward references */ /* Unions forward references */
@@ -69,12 +76,15 @@ typedef union _APIC_BASE_REGISTER APIC_BASE_REGISTER, *PAPIC_BASE_REGISTER;
typedef union _APIC_COMMAND_REGISTER APIC_COMMAND_REGISTER, *PAPIC_COMMAND_REGISTER; typedef union _APIC_COMMAND_REGISTER APIC_COMMAND_REGISTER, *PAPIC_COMMAND_REGISTER;
typedef union _APIC_LVT_REGISTER APIC_LVT_REGISTER, *PAPIC_LVT_REGISTER; typedef union _APIC_LVT_REGISTER APIC_LVT_REGISTER, *PAPIC_LVT_REGISTER;
typedef union _APIC_SPURIOUS_REGISTER APIC_SPURIOUS_REGISTER, *PAPIC_SPURIOUS_REGISTER; typedef union _APIC_SPURIOUS_REGISTER APIC_SPURIOUS_REGISTER, *PAPIC_SPURIOUS_REGISTER;
typedef union _HARDWARE_PTE HARDWARE_PTE, *PHARDWARE_PTE;
typedef union _MMPML2_PTE MMPML2_PTE, *PMMPML2_PTE;
typedef union _MMPML3_PTE MMPML3_PTE, *PMMPML3_PTE;
typedef union _MMPTE MMPDE, *PMMPDE; typedef union _MMPTE MMPDE, *PMMPDE;
typedef union _MMPTE MMPPE, *PMMPPE;
typedef union _MMPTE MMPTE, *PMMPTE; typedef union _MMPTE MMPTE, *PMMPTE;
typedef union _PIC_I8259_ICW1 PIC_I8259_ICW1, *PPIC_I8259_ICW1; 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_ICW2 PIC_I8259_ICW2, *PPIC_I8259_ICW2;
typedef union _PIC_I8259_ICW3 PIC_I8259_ICW3, *PPIC_I8259_ICW3; typedef union _PIC_I8259_ICW3 PIC_I8259_ICW3, *PPIC_I8259_ICW3;
typedef union _PIC_I8259_ICW4 PIC_I8259_ICW4, *PPIC_I8259_ICW4; typedef union _PIC_I8259_ICW4 PIC_I8259_ICW4, *PPIC_I8259_ICW4;
#endif /* __XTDK_I686_XTSTRUCT_H */ #endif /* __XTDK_I686_XTSTRUCT_H */

45
sdk/xtdk/kdtypes.h Normal file
View File

@@ -0,0 +1,45 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: sdk/xtdk/kdtypes.h
* DESCRIPTION: Kernel Debugger data structures
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
*/
#ifndef __XTDK_KDTYPES_H
#define __XTDK_KDTYPES_H
#include <xtbase.h>
#include <xtstruct.h>
#include <rtltypes.h>
/* Number of debug providers */
#define KDBG_PROVIDERS_COUNT 2
/* Debug providers bitmask definitions */
#define DEBUG_PROVIDER_COMPORT 0x00000001
#define DEBUG_PROVIDER_FRAMEBUFFER 0x00000002
/* Kernel routine callbacks */
typedef XTSTATUS (XTAPI *PKD_INIT_ROUTINE)();
typedef VOID (*PKD_PRINT_ROUTINE)(IN PCWSTR Format, IN ...);
/* Debug mode structure definition */
typedef struct _KD_DEBUG_MODE
{
BOOLEAN Enabled;
ULONG Mode;
ULONG ComPortAddress;
ULONG ComPortNumber;
ULONG ComPortBaudRate;
} KD_DEBUG_MODE, *PKD_DEBUG_MODE;
/* Kernel debugger dispatch table structure definition */
typedef struct _KD_DISPATCH_TABLE
{
LIST_ENTRY ListEntry;
RTL_PRINT_CONTEXT PrintContext;
} KD_DISPATCH_TABLE, *PKD_DISPATCH_TABLE;
#endif /* __XTDK_KDTYPES_H */

View File

@@ -16,36 +16,44 @@
/* Kernel services routines forward references */ /* Kernel services routines forward references */
XTCLINK
XTFASTCALL XTFASTCALL
VOID VOID
KeAcquireQueuedSpinLock(IN KSPIN_LOCK_QUEUE_LEVEL LockLevel); KeAcquireQueuedSpinLock(IN KSPIN_LOCK_QUEUE_LEVEL LockLevel);
XTCLINK
XTFASTCALL XTFASTCALL
VOID VOID
KeAcquireSpinLock(IN OUT PKSPIN_LOCK SpinLock); KeAcquireSpinLock(IN OUT PKSPIN_LOCK SpinLock);
XTCLINK
XTAPI XTAPI
XTSTATUS XTSTATUS
KeAcquireSystemResource(IN SYSTEM_RESOURCE_TYPE ResourceType, KeAcquireSystemResource(IN SYSTEM_RESOURCE_TYPE ResourceType,
OUT PSYSTEM_RESOURCE_HEADER *ResourceHeader); OUT PSYSTEM_RESOURCE_HEADER *ResourceHeader);
XTCLINK
XTAPI XTAPI
BOOLEAN BOOLEAN
KeCancelTimer(IN PKTIMER Timer); KeCancelTimer(IN PKTIMER Timer);
XTCLINK
XTFASTCALL XTFASTCALL
KRUNLEVEL KRUNLEVEL
KeGetCurrentRunLevel(VOID); KeGetCurrentRunLevel(VOID);
XTCLINK
XTAPI XTAPI
XTSTATUS XTSTATUS
KeGetSystemResource(IN SYSTEM_RESOURCE_TYPE ResourceType, KeGetSystemResource(IN SYSTEM_RESOURCE_TYPE ResourceType,
OUT PSYSTEM_RESOURCE_HEADER *ResourceHeader); OUT PSYSTEM_RESOURCE_HEADER *ResourceHeader);
XTCLINK
XTAPI XTAPI
BOOLEAN BOOLEAN
KeGetTimerState(IN PKTIMER Timer); KeGetTimerState(IN PKTIMER Timer);
XTCLINK
XTAPI XTAPI
VOID VOID
KeInitializeApc(IN PKAPC Apc, KeInitializeApc(IN PKAPC Apc,
@@ -57,45 +65,54 @@ KeInitializeApc(IN PKAPC Apc,
IN KPROCESSOR_MODE ApcMode, IN KPROCESSOR_MODE ApcMode,
IN PVOID Context); IN PVOID Context);
XTCLINK
XTAPI XTAPI
VOID VOID
KeInitializeDpc(IN PKDPC Dpc, KeInitializeDpc(IN PKDPC Dpc,
IN PKDEFERRED_ROUTINE DpcRoutine, IN PKDEFERRED_ROUTINE DpcRoutine,
IN PVOID DpcContext); IN PVOID DpcContext);
XTCLINK
XTAPI XTAPI
VOID VOID
KeInitializeSemaphore(IN PKSEMAPHORE Semaphore, KeInitializeSemaphore(IN PKSEMAPHORE Semaphore,
IN LONG Count, IN LONG Count,
IN LONG Limit); IN LONG Limit);
XTCLINK
XTAPI XTAPI
VOID VOID
KeInitializeSpinLock(IN PKSPIN_LOCK SpinLock); KeInitializeSpinLock(IN PKSPIN_LOCK SpinLock);
XTCLINK
XTAPI XTAPI
VOID VOID
KeInitializeThreadedDpc(IN PKDPC Dpc, KeInitializeThreadedDpc(IN PKDPC Dpc,
IN PKDEFERRED_ROUTINE DpcRoutine, IN PKDEFERRED_ROUTINE DpcRoutine,
IN PVOID DpcContext); IN PVOID DpcContext);
XTCLINK
XTAPI XTAPI
VOID VOID
KeInitializeTimer(OUT PKTIMER Timer, KeInitializeTimer(OUT PKTIMER Timer,
IN KTIMER_TYPE Type); IN KTIMER_TYPE Type);
XTCLINK
XTFASTCALL XTFASTCALL
VOID VOID
KeLowerRunLevel(IN KRUNLEVEL RunLevel); KeLowerRunLevel(IN KRUNLEVEL RunLevel);
XTCLINK
XTFASTCALL XTFASTCALL
KRUNLEVEL KRUNLEVEL
KeRaiseRunLevel(IN KRUNLEVEL RunLevel); KeRaiseRunLevel(IN KRUNLEVEL RunLevel);
XTCLINK
XTAPI XTAPI
LONG LONG
KeReadSemaphoreState(IN PKSEMAPHORE Semaphore); KeReadSemaphoreState(IN PKSEMAPHORE Semaphore);
XTCLINK
XTAPI XTAPI
LONG LONG
KeReleaseSemaphore(IN PKSEMAPHORE Semaphore, KeReleaseSemaphore(IN PKSEMAPHORE Semaphore,
@@ -103,23 +120,28 @@ KeReleaseSemaphore(IN PKSEMAPHORE Semaphore,
IN LONG Adjustment, IN LONG Adjustment,
IN BOOLEAN Wait); IN BOOLEAN Wait);
XTCLINK
XTFASTCALL XTFASTCALL
VOID VOID
KeReleaseQueuedSpinLock(IN KSPIN_LOCK_QUEUE_LEVEL LockLevel); KeReleaseQueuedSpinLock(IN KSPIN_LOCK_QUEUE_LEVEL LockLevel);
XTCLINK
XTFASTCALL XTFASTCALL
VOID VOID
KeReleaseSpinLock(IN OUT PKSPIN_LOCK SpinLock); KeReleaseSpinLock(IN OUT PKSPIN_LOCK SpinLock);
XTCLINK
XTAPI XTAPI
VOID VOID
KeReleaseSystemResource(IN PSYSTEM_RESOURCE_HEADER ResourceHeader); KeReleaseSystemResource(IN PSYSTEM_RESOURCE_HEADER ResourceHeader);
XTCLINK
XTAPI XTAPI
VOID VOID
KeSetTargetProcessorDpc(IN PKDPC Dpc, KeSetTargetProcessorDpc(IN PKDPC Dpc,
IN CCHAR Number); IN CCHAR Number);
XTCLINK
XTAPI XTAPI
VOID VOID
KeSetTimer(IN PKTIMER Timer, KeSetTimer(IN PKTIMER Timer,
@@ -127,10 +149,12 @@ KeSetTimer(IN PKTIMER Timer,
IN LONG Period, IN LONG Period,
IN PKDPC Dpc); IN PKDPC Dpc);
XTCLINK
XTAPI XTAPI
VOID VOID
KeSignalCallDpcDone(IN PVOID SystemArgument); KeSignalCallDpcDone(IN PVOID SystemArgument);
XTCLINK
XTAPI XTAPI
BOOLEAN BOOLEAN
KeSignalCallDpcSynchronize(IN PVOID SystemArgument); KeSignalCallDpcSynchronize(IN PVOID SystemArgument);

View File

@@ -10,8 +10,18 @@
#define __XTDK_MMTYPES_H #define __XTDK_MMTYPES_H
#include <xtbase.h> #include <xtbase.h>
#include ARCH_HEADER(xtstruct.h)
/* Page map routines structure definition */
typedef CONST STRUCT _CMMPAGEMAP_ROUTINES
{
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;
/* Color tables structure definition */ /* Color tables structure definition */
typedef struct _MMCOLOR_TABLES typedef struct _MMCOLOR_TABLES
{ {

View File

@@ -83,26 +83,26 @@ RtlCompareMemory(IN PCVOID LeftBuffer,
XTAPI XTAPI
SIZE_T SIZE_T
RtlCompareString(IN CONST PCHAR String1, RtlCompareString(IN PCSTR String1,
IN CONST PCHAR String2, IN PCSTR String2,
IN SIZE_T Length); IN SIZE_T Length);
XTAPI XTAPI
SIZE_T SIZE_T
RtlCompareStringInsensitive(IN CONST PCHAR String1, RtlCompareStringInsensitive(IN PCSTR String1,
IN CONST PCHAR String2, IN PCSTR String2,
IN SIZE_T Length); IN SIZE_T Length);
XTAPI XTAPI
SIZE_T SIZE_T
RtlCompareWideString(IN CONST PWCHAR String1, RtlCompareWideString(IN PCWSTR String1,
IN CONST PWCHAR String2, IN PCWSTR String2,
IN SIZE_T Length); IN SIZE_T Length);
XTAPI XTAPI
SIZE_T SIZE_T
RtlCompareWideStringInsensitive(IN CONST PWCHAR String1, RtlCompareWideStringInsensitive(IN PCWSTR String1,
IN CONST PWCHAR String2, IN PCWSTR String2,
IN SIZE_T Length); IN SIZE_T Length);
XTAPI XTAPI
@@ -134,13 +134,13 @@ RtlCopyMemory(OUT PVOID Destination,
XTAPI XTAPI
VOID VOID
RtlCopyString(IN PCHAR Destination, RtlCopyString(IN PCHAR Destination,
IN PCCHAR Source, IN PCSTR Source,
IN ULONG Length); IN ULONG Length);
XTAPI XTAPI
VOID VOID
RtlCopyWideString(IN PWCHAR Destination, RtlCopyWideString(IN PWCHAR Destination,
IN CONST PWCHAR Source, IN PCWSTR Source,
IN ULONG Length); IN ULONG Length);
XTAPI XTAPI
@@ -161,6 +161,26 @@ RtlFindSetBits(IN PRTL_BITMAP BitMap,
IN ULONG_PTR Length, IN ULONG_PTR Length,
IN ULONG_PTR Index); IN ULONG_PTR Index);
XTAPI
PCSTR
RtlFindString(IN PCSTR Source,
IN PCSTR Search);
XTAPI
PCSTR
RtlFindStringInsensitive(IN PCSTR Source,
IN PCSTR Search);
XTAPI
PCWSTR
RtlFindWideString(IN PCWSTR Source,
IN PCWSTR Search);
XTAPI
PCWSTR
RtlFindWideStringInsensitive(IN PCWSTR Source,
IN PCWSTR Search);
XTAPI XTAPI
XTSTATUS XTSTATUS
RtlFormatWideString(IN PRTL_PRINT_CONTEXT Context, RtlFormatWideString(IN PRTL_PRINT_CONTEXT Context,
@@ -229,13 +249,13 @@ RtlSetMemory(OUT PVOID Destination,
XTAPI XTAPI
SIZE_T SIZE_T
RtlStringLength(IN CONST PCHAR String, RtlStringLength(IN PCSTR String,
IN SIZE_T MaxLength); IN SIZE_T MaxLength);
XTAPI XTAPI
SIZE_T SIZE_T
RtlStringToWideString(OUT PWCHAR Destination, RtlStringToWideString(OUT PWCHAR Destination,
IN CONST PCHAR *Source, IN PCSTR *Source,
IN SIZE_T Length); IN SIZE_T Length);
XTAPI XTAPI
@@ -246,42 +266,58 @@ RtlTestBit(IN PRTL_BITMAP BitMap,
XTAPI XTAPI
PCHAR PCHAR
RtlTokenizeString(IN PCHAR String, RtlTokenizeString(IN PCHAR String,
IN CONST PCHAR Delimiter, IN PCSTR Delimiter,
IN OUT PCHAR *SavePtr); IN OUT PCHAR *SavePtr);
XTAPI XTAPI
PWCHAR PWCHAR
RtlTokenizeWideString(IN PWCHAR String, RtlTokenizeWideString(IN PWCHAR String,
IN CONST PWCHAR Delimiter, IN PCWSTR Delimiter,
IN OUT PWCHAR *SavePtr); IN OUT PWCHAR *SavePtr);
XTAPI XTAPI
PCHAR CHAR
RtlTrimLeftString(IN CONST PCHAR String); RtlToLowerCharacter(IN CHAR Character);
XTAPI XTAPI
PWCHAR WCHAR
RtlTrimLeftWideString(IN CONST PWCHAR String); RtlToLowerWideCharacter(IN WCHAR Character);
XTAPI
CHAR
RtlToUpperCharacter(IN CHAR Character);
XTAPI
WCHAR
RtlToUpperWideCharacter(IN WCHAR Character);
XTAPI XTAPI
PCHAR PCHAR
RtlTrimRightString(IN CONST PCHAR String); RtlTrimLeftString(IN PCHAR String);
XTAPI XTAPI
PWCHAR PWCHAR
RtlTrimRightWideString(IN CONST PWCHAR String); RtlTrimLeftWideString(IN PWCHAR String);
XTAPI XTAPI
PCHAR PCHAR
RtlTrimString(IN CONST PCHAR String); RtlTrimRightString(IN PCHAR String);
XTAPI XTAPI
PWCHAR PWCHAR
RtlTrimWideString(IN CONST PWCHAR String); RtlTrimRightWideString(IN PWCHAR String);
XTAPI
PCHAR
RtlTrimString(IN PCHAR String);
XTAPI
PWCHAR
RtlTrimWideString(IN PWCHAR String);
XTAPI XTAPI
SIZE_T SIZE_T
RtlWideStringLength(IN CONST PWCHAR String, RtlWideStringLength(IN PCWSTR String,
IN SIZE_T MaxLength); IN SIZE_T MaxLength);
XTAPI XTAPI

View File

@@ -7,6 +7,7 @@
*/ */
/* Base XT headers */ /* Base XT headers */
#include <xtcompat.h>
#include <xtdefs.h> #include <xtdefs.h>
#include <xtstatus.h> #include <xtstatus.h>
#include <xttarget.h> #include <xttarget.h>

21
sdk/xtdk/xtcompat.h Normal file
View File

@@ -0,0 +1,21 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: sdk/xtdk/xtcompat.h
* DESCRIPTION: C/C++ compatibility macros
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
*/
#ifndef __XTDK_XTCOMPAT_H
#define __XTDK_XTCOMPAT_H
#ifdef __cplusplus
#define XTCLINK extern "C"
typedef wchar_t wchar;
#else
#define XTCLINK
typedef unsigned short wchar;
#endif
#endif /* __XTDK_XTCOMPAT_H */

View File

@@ -20,7 +20,7 @@
/* XTOS platform debugging macros */ /* XTOS platform debugging macros */
#ifdef DBG #ifdef DBG
#define DEBUG 1 #define DEBUG 1
#define DebugPrint(Format, ...) if(KeDbgPrint) KeDbgPrint(Format, __VA_ARGS__); #define DebugPrint(Format, ...) if(KdPrint) KdPrint(Format, __VA_ARGS__);
#else #else
#define DEBUG 0 #define DEBUG 0
#define DebugPrint(Format, ...) ((VOID)NULL) #define DebugPrint(Format, ...) ((VOID)NULL)

View File

@@ -89,7 +89,6 @@ typedef struct _FIRMWARE_INFORMATION_BLOCK
typedef struct _LOADER_INFORMATION_BLOCK typedef struct _LOADER_INFORMATION_BLOCK
{ {
PVOID DbgPrint; PVOID DbgPrint;
ULONG PageMapLevel;
} LOADER_INFORMATION_BLOCK, *PLOADER_INFORMATION_BLOCK; } LOADER_INFORMATION_BLOCK, *PLOADER_INFORMATION_BLOCK;
/* Boot Loader memory mapping information */ /* Boot Loader memory mapping information */

View File

@@ -7,6 +7,7 @@
*/ */
/* Base XT headers */ /* Base XT headers */
#include <xtcompat.h>
#include <xtdefs.h> #include <xtdefs.h>
#include <xtstatus.h> #include <xtstatus.h>
#include <xttarget.h> #include <xttarget.h>
@@ -30,6 +31,7 @@
#include <extypes.h> #include <extypes.h>
#include <hltypes.h> #include <hltypes.h>
#include <iotypes.h> #include <iotypes.h>
#include <kdtypes.h>
#include <ketypes.h> #include <ketypes.h>
#include <ldrtypes.h> #include <ldrtypes.h>
#include <mmtypes.h> #include <mmtypes.h>

View File

@@ -59,6 +59,7 @@
#define STATUS_INVALID_PARAMETER ((XTSTATUS) 0xC000000DL) #define STATUS_INVALID_PARAMETER ((XTSTATUS) 0xC000000DL)
#define STATUS_END_OF_FILE ((XTSTATUS) 0xC0000011L) #define STATUS_END_OF_FILE ((XTSTATUS) 0xC0000011L)
#define STATUS_NO_MEMORY ((XTSTATUS) 0xC0000017L) #define STATUS_NO_MEMORY ((XTSTATUS) 0xC0000017L)
#define STATUS_PORT_DISCONNECTED ((XTSTATUS) 0xC0000037L)
#define STATUS_CRC_ERROR ((XTSTATUS) 0xC000003FL) #define STATUS_CRC_ERROR ((XTSTATUS) 0xC000003FL)
#define STATUS_INSUFFICIENT_RESOURCES ((XTSTATUS) 0xC000009AL) #define STATUS_INSUFFICIENT_RESOURCES ((XTSTATUS) 0xC000009AL)
#define STATUS_DEVICE_NOT_READY ((XTSTATUS) 0xC00000A3L) #define STATUS_DEVICE_NOT_READY ((XTSTATUS) 0xC00000A3L)

View File

@@ -50,6 +50,7 @@ typedef enum _KTIMER_TYPE KTIMER_TYPE, *PKTIMER_TYPE;
typedef enum _KUBSAN_DATA_TYPE KUBSAN_DATA_TYPE, *PKUBSAN_DATA_TYPE; typedef enum _KUBSAN_DATA_TYPE KUBSAN_DATA_TYPE, *PKUBSAN_DATA_TYPE;
typedef enum _LOADER_MEMORY_TYPE LOADER_MEMORY_TYPE, *PLOADER_MEMORY_TYPE; typedef enum _LOADER_MEMORY_TYPE LOADER_MEMORY_TYPE, *PLOADER_MEMORY_TYPE;
typedef enum _MODE MODE, *PMODE; typedef enum _MODE MODE, *PMODE;
typedef enum _RTL_VARIABLE_TYPE RTL_VARIABLE_TYPE, *PRTL_VARIABLE_TYPE;
typedef enum _SYSTEM_FIRMWARE_TYPE SYSTEM_FIRMWARE_TYPE, *PSYSTEM_FIRMWARE_TYPE; typedef enum _SYSTEM_FIRMWARE_TYPE SYSTEM_FIRMWARE_TYPE, *PSYSTEM_FIRMWARE_TYPE;
typedef enum _WAIT_TYPE WAIT_TYPE, *PWAIT_TYPE; typedef enum _WAIT_TYPE WAIT_TYPE, *PWAIT_TYPE;
@@ -69,6 +70,7 @@ typedef struct _ANSI_STRING ANSI_STRING, *PANSI_STRING;
typedef struct _ANSI_STRING32 ANSI_STRING32, *PANSI_STRING32; typedef struct _ANSI_STRING32 ANSI_STRING32, *PANSI_STRING32;
typedef struct _ANSI_STRING64 ANSI_STRING64, *PANSI_STRING64; typedef struct _ANSI_STRING64 ANSI_STRING64, *PANSI_STRING64;
typedef struct _CPPORT CPPORT, *PCPPORT; typedef struct _CPPORT CPPORT, *PCPPORT;
typedef const struct _CMMPAGEMAP_ROUTINES CMMPAGEMAP_ROUTINES, *PCMMPAGEMAP_ROUTINES;
typedef struct _CSTRING CSTRING, *PCSTRING; typedef struct _CSTRING CSTRING, *PCSTRING;
typedef struct _EFI_1394_DEVICE_PATH EFI_1394_DEVICE_PATH, *PEFI_1394_DEVICE_PATH; 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_ADDRESS_SPACE_DESCRIPTOR EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR, *PEFI_ACPI_ADDRESS_SPACE_DESCRIPTOR;
@@ -233,9 +235,12 @@ typedef struct _FIRMWARE_INFORMATION_BLOCK FIRMWARE_INFORMATION_BLOCK, *PFIRMWAR
typedef struct _FLOAT128 FLOAT128, *PFLOAT128; typedef struct _FLOAT128 FLOAT128, *PFLOAT128;
typedef struct _GENERIC_ADDRESS GENERIC_ADDRESS, *PGENERIC_ADDRESS; typedef struct _GENERIC_ADDRESS GENERIC_ADDRESS, *PGENERIC_ADDRESS;
typedef struct _GUID GUID, *PGUID; typedef struct _GUID GUID, *PGUID;
typedef struct _HAL_FRAMEBUFFER_DATA HAL_FRAMEBUFFER_DATA, *PHAL_FRAMEBUFFER_DATA; 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 _KAPC KAPC, *PKAPC; typedef struct _KAPC KAPC, *PKAPC;
typedef struct _KAPC_STATE KAPC_STATE, *PKAPC_STATE; 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 KDPC, *PKDPC;
typedef struct _KDPC_DATA KDPC_DATA, *PKDPC_DATA; typedef struct _KDPC_DATA KDPC_DATA, *PKDPC_DATA;
typedef struct _KERNEL_INITIALIZATION_BLOCK KERNEL_INITIALIZATION_BLOCK, *PKERNEL_INITIALIZATION_BLOCK; typedef struct _KERNEL_INITIALIZATION_BLOCK KERNEL_INITIALIZATION_BLOCK, *PKERNEL_INITIALIZATION_BLOCK;
@@ -300,6 +305,9 @@ typedef struct _PECOFF_IMAGE_SECTION_HEADER PECOFF_IMAGE_SECTION_HEADER, *PPECOF
typedef struct _PECOFF_IMAGE_VXD_HEADER PECOFF_IMAGE_VXD_HEADER, *PPECOFF_IMAGE_VXD_HEADER; typedef struct _PECOFF_IMAGE_VXD_HEADER PECOFF_IMAGE_VXD_HEADER, *PPECOFF_IMAGE_VXD_HEADER;
typedef struct _PROCESSOR_IDENTITY PROCESSOR_IDENTITY, *PPROCESSOR_IDENTITY; typedef struct _PROCESSOR_IDENTITY PROCESSOR_IDENTITY, *PPROCESSOR_IDENTITY;
typedef struct _PROCESSOR_POWER_STATE PROCESSOR_POWER_STATE, *PPROCESSOR_POWER_STATE; typedef struct _PROCESSOR_POWER_STATE PROCESSOR_POWER_STATE, *PPROCESSOR_POWER_STATE;
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 _SINGLE_LIST_ENTRY SINGLE_LIST_ENTRY, *PSINGLE_LIST_ENTRY; typedef struct _SINGLE_LIST_ENTRY SINGLE_LIST_ENTRY, *PSINGLE_LIST_ENTRY;
typedef struct _SMBIOS_TABLE_HEADER SMBIOS_TABLE_HEADER, *PSMBIOS_TABLE_HEADER; typedef struct _SMBIOS_TABLE_HEADER SMBIOS_TABLE_HEADER, *PSMBIOS_TABLE_HEADER;
typedef struct _SMBIOS3_TABLE_HEADER SMBIOS3_TABLE_HEADER, *PSMBIOS3_TABLE_HEADER; typedef struct _SMBIOS3_TABLE_HEADER SMBIOS3_TABLE_HEADER, *PSMBIOS3_TABLE_HEADER;

View File

@@ -10,6 +10,7 @@
#define __XTDK_XTTYPES_H #define __XTDK_XTTYPES_H
#include <xttarget.h> #include <xttarget.h>
#include <xtcompat.h>
/* Standard C types */ /* Standard C types */
@@ -128,7 +129,7 @@ typedef CHAR SZ, *PSZ;
typedef const CHAR CSZ, *PCSZ; typedef const CHAR CSZ, *PCSZ;
/* UNICODE character types */ /* UNICODE character types */
typedef USHORT WCHAR, *PWCHAR; typedef wchar WCHAR, *PWCHAR;
typedef WCHAR *PWCH, *LPWCH; typedef WCHAR *PWCH, *LPWCH;
typedef const WCHAR *PCWCH, *LPCWCH; typedef const WCHAR *PCWCH, *LPCWCH;
typedef WCHAR *PWSTR, *LPWSTR, *NWPSTR; typedef WCHAR *PWSTR, *LPWSTR, *NWPSTR;

View File

@@ -35,7 +35,7 @@ BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
EFI_STATUS Status; EFI_STATUS Status;
/* Allocate pages for the Page Map */ /* Allocate pages for the Page Map */
Status = BlAllocateMemoryPages(1, &Address); Status = BlAllocateMemoryPages(AllocateAnyPages, 1, &Address);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Memory allocation failure */ /* Memory allocation failure */
@@ -54,6 +54,15 @@ BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
return Status; return Status;
} }
/* Map the trampoline code area */
Status = BlMapVirtualMemory(PageMap, (PVOID)MM_TRAMPOLINE_ADDRESS,(PVOID)MM_TRAMPOLINE_ADDRESS,
1, LoaderFirmwareTemporary);
if(Status != STATUS_EFI_SUCCESS)
{
/* Mapping trampoline code failed */
return Status;
}
/* Get list of XTLDR modules */ /* Get list of XTLDR modules */
ModulesList = BlGetModulesList(); ModulesList = BlGetModulesList();
ModulesListEntry = ModulesList->Flink; ModulesListEntry = ModulesList->Flink;
@@ -167,7 +176,7 @@ BlMapPage(IN PXTBL_PAGE_MAPPING PageMap,
while(NumberOfPages > 0) while(NumberOfPages > 0)
{ {
/* Calculate the indices in the various Page Tables from the virtual address */ /* Calculate the indices in the various Page Tables from the virtual address */
Pml5Entry = (VirtualAddress & ((ULONGLONG)0x1FF << MM_LA57_SHIFT)) >> MM_LA57_SHIFT; Pml5Entry = (VirtualAddress & ((ULONGLONG)0x1FF << MM_P5I_SHIFT)) >> MM_P5I_SHIFT;
Pml4Entry = (VirtualAddress & ((ULONGLONG)0x1FF << MM_PXI_SHIFT)) >> MM_PXI_SHIFT; Pml4Entry = (VirtualAddress & ((ULONGLONG)0x1FF << MM_PXI_SHIFT)) >> MM_PXI_SHIFT;
Pml3Entry = (VirtualAddress & ((ULONGLONG)0x1FF << MM_PPI_SHIFT)) >> MM_PPI_SHIFT; Pml3Entry = (VirtualAddress & ((ULONGLONG)0x1FF << MM_PPI_SHIFT)) >> MM_PPI_SHIFT;
Pml2Entry = (VirtualAddress & ((ULONGLONG)0x1FF << MM_PDI_SHIFT)) >> MM_PDI_SHIFT; Pml2Entry = (VirtualAddress & ((ULONGLONG)0x1FF << MM_PDI_SHIFT)) >> MM_PDI_SHIFT;
@@ -279,7 +288,7 @@ BlpGetNextPageTable(IN PXTBL_PAGE_MAPPING PageMap,
else else
{ {
/* Allocate pages for new PML entry */ /* Allocate pages for new PML entry */
Status = BlAllocateMemoryPages(1, &Address); Status = BlAllocateMemoryPages(AllocateAnyPages, 1, &Address);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Memory allocation failure */ /* Memory allocation failure */
@@ -338,22 +347,21 @@ BlpSelfMapPml(IN PXTBL_PAGE_MAPPING PageMap,
/* Check page map level */ /* Check page map level */
if(PageMap->PageMapLevel == 5) if(PageMap->PageMapLevel == 5)
{ {
/* Self-mapping for PML5 is not supported */ /* Calculate PML index based on provided self map address for PML5 */
BlDebugPrint(L"PML5 self-mapping not supported yet!\n"); PmlIndex = (SelfMapAddress >> MM_P5I_SHIFT) & 0x1FF;
return STATUS_EFI_UNSUPPORTED;
} }
else else
{ {
/* Calculate PML index based on provided self map address */ /* Calculate PML index based on provided self map address for PML4 */
PmlIndex = (SelfMapAddress >> MM_PXI_SHIFT) & 0x1FF; PmlIndex = (SelfMapAddress >> MM_PXI_SHIFT) & 0x1FF;
/* Add self-mapping for PML4 */
RtlZeroMemory(&PmlBase[PmlIndex], sizeof(HARDWARE_PTE));
PmlBase[PmlIndex].PageFrameNumber = (UINT_PTR)PageMap->PtePointer / EFI_PAGE_SIZE;
PmlBase[PmlIndex].Valid = 1;
PmlBase[PmlIndex].Writable = 1;
} }
/* Add self-mapping */
RtlZeroMemory(&PmlBase[PmlIndex], sizeof(HARDWARE_PTE));
PmlBase[PmlIndex].PageFrameNumber = (UINT_PTR)PageMap->PtePointer / EFI_PAGE_SIZE;
PmlBase[PmlIndex].Valid = 1;
PmlBase[PmlIndex].Writable = 1;
/* Return success */ /* Return success */
return STATUS_EFI_SUCCESS; return STATUS_EFI_SUCCESS;
} }

View File

@@ -36,7 +36,7 @@ BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
if(PageMap->PageMapLevel == 3) if(PageMap->PageMapLevel == 3)
{ {
/* Allocate a page for the 3-level page map structure (PAE enabled) */ /* Allocate a page for the 3-level page map structure (PAE enabled) */
Status = BlAllocateMemoryPages(1, &Address); Status = BlAllocateMemoryPages(AllocateAnyPages, 1, &Address);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Memory allocation failed, cannot proceed with page map creation */ /* Memory allocation failed, cannot proceed with page map creation */
@@ -48,7 +48,7 @@ BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
RtlZeroMemory(PageMap->PtePointer, EFI_PAGE_SIZE); RtlZeroMemory(PageMap->PtePointer, EFI_PAGE_SIZE);
/* Allocate 4 pages for the Page Directories (PDs) */ /* Allocate 4 pages for the Page Directories (PDs) */
Status = BlAllocateMemoryPages(4, &DirectoryAddress); Status = BlAllocateMemoryPages(AllocateAnyPages, 4, &DirectoryAddress);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Memory allocation failed, cannot proceed with page map creation */ /* Memory allocation failed, cannot proceed with page map creation */
@@ -61,16 +61,16 @@ BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
/* Fill the PDPT with pointers to the Page Directories */ /* Fill the PDPT with pointers to the Page Directories */
for(Index = 0; Index < 4; Index++) for(Index = 0; Index < 4; Index++)
{ {
RtlZeroMemory(&((PHARDWARE_PTE)PageMap->PtePointer)[Index], sizeof(HARDWARE_PTE)); RtlZeroMemory(&((PHARDWARE_MODERN_PTE)PageMap->PtePointer)[Index], sizeof(HARDWARE_MODERN_PTE));
((PHARDWARE_PTE)PageMap->PtePointer)[Index].PageFrameNumber = DirectoryAddress / EFI_PAGE_SIZE; ((PHARDWARE_MODERN_PTE)PageMap->PtePointer)[Index].PageFrameNumber = DirectoryAddress / EFI_PAGE_SIZE;
((PHARDWARE_PTE)PageMap->PtePointer)[Index].Valid = 1; ((PHARDWARE_MODERN_PTE)PageMap->PtePointer)[Index].Valid = 1;
DirectoryAddress += EFI_PAGE_SIZE; DirectoryAddress += EFI_PAGE_SIZE;
} }
} }
else else
{ {
/* Allocate a page for the 2-level page map structure (PAE disabled) */ /* Allocate a page for the 2-level page map structure (PAE disabled) */
Status = BlAllocateMemoryPages(1, &Address); Status = BlAllocateMemoryPages(AllocateAnyPages, 1, &Address);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Memory allocation failed, cannot proceed with page map creation */ /* Memory allocation failed, cannot proceed with page map creation */
@@ -90,6 +90,15 @@ BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
return Status; return Status;
} }
/* Map the trampoline code area */
Status = BlMapVirtualMemory(PageMap, (PVOID)MM_TRAMPOLINE_ADDRESS,(PVOID)MM_TRAMPOLINE_ADDRESS,
1, LoaderFirmwareTemporary);
if(Status != STATUS_EFI_SUCCESS)
{
/* Mapping trampoline code failed */
return Status;
}
/* Get list of XTLDR modules */ /* Get list of XTLDR modules */
ModulesList = BlGetModulesList(); ModulesList = BlGetModulesList();
ModulesListEntry = ModulesList->Flink; ModulesListEntry = ModulesList->Flink;
@@ -193,8 +202,8 @@ BlMapPage(IN PXTBL_PAGE_MAPPING PageMap,
SIZE_T PageFrameNumber; SIZE_T PageFrameNumber;
PVOID Pml1, Pml2, Pml3; PVOID Pml1, Pml2, Pml3;
SIZE_T Pml1Entry, Pml2Entry, Pml3Entry; SIZE_T Pml1Entry, Pml2Entry, Pml3Entry;
PHARDWARE_PTE PmlTable;
PHARDWARE_LEGACY_PTE LegacyPmlTable; PHARDWARE_LEGACY_PTE LegacyPmlTable;
PHARDWARE_MODERN_PTE PmlTable;
EFI_STATUS Status; EFI_STATUS Status;
/* Set the Page Frame Number (PFN) */ /* Set the Page Frame Number (PFN) */
@@ -231,8 +240,8 @@ BlMapPage(IN PXTBL_PAGE_MAPPING PageMap,
} }
/* Set the 64-bit PTE entry */ /* Set the 64-bit PTE entry */
PmlTable = (PHARDWARE_PTE)Pml1; PmlTable = (PHARDWARE_MODERN_PTE)Pml1;
RtlZeroMemory(&PmlTable[Pml1Entry], sizeof(HARDWARE_PTE)); RtlZeroMemory(&PmlTable[Pml1Entry], sizeof(HARDWARE_MODERN_PTE));
PmlTable[Pml1Entry].PageFrameNumber = PageFrameNumber; PmlTable[Pml1Entry].PageFrameNumber = PageFrameNumber;
PmlTable[Pml1Entry].Valid = 1; PmlTable[Pml1Entry].Valid = 1;
PmlTable[Pml1Entry].Writable = 1; PmlTable[Pml1Entry].Writable = 1;
@@ -304,14 +313,14 @@ BlpGetNextPageTable(IN PXTBL_PAGE_MAPPING PageMap,
ULONGLONG PmlPointer = 0; ULONGLONG PmlPointer = 0;
EFI_STATUS Status; EFI_STATUS Status;
PHARDWARE_LEGACY_PTE LegacyPmlTable; PHARDWARE_LEGACY_PTE LegacyPmlTable;
PHARDWARE_PTE PmlTable; PHARDWARE_MODERN_PTE PmlTable;
BOOLEAN ValidPte = FALSE; BOOLEAN ValidPte = FALSE;
/* Check page map level to determine PTE size */ /* Check page map level to determine PTE size */
if(PageMap->PageMapLevel >= 3) if(PageMap->PageMapLevel >= 3)
{ {
/* 64-bit PTE for PML3 (PAE enabled) */ /* 64-bit PTE for PML3 (PAE enabled) */
PmlTable = (PHARDWARE_PTE)PageTable; PmlTable = (PHARDWARE_MODERN_PTE)PageTable;
if(PmlTable[Entry].Valid) if(PmlTable[Entry].Valid)
{ {
/* Get page frame number from page table entry */ /* Get page frame number from page table entry */
@@ -340,7 +349,7 @@ BlpGetNextPageTable(IN PXTBL_PAGE_MAPPING PageMap,
else else
{ {
/* Allocate pages for new PML entry */ /* Allocate pages for new PML entry */
Status = BlAllocateMemoryPages(1, &Address); Status = BlAllocateMemoryPages(AllocateAnyPages, 1, &Address);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Memory allocation failure */ /* Memory allocation failure */
@@ -362,7 +371,7 @@ BlpGetNextPageTable(IN PXTBL_PAGE_MAPPING PageMap,
if(PageMap->PageMapLevel >= 3) if(PageMap->PageMapLevel >= 3)
{ {
/* 64-bit PTE for PML3 (PAE enabled) */ /* 64-bit PTE for PML3 (PAE enabled) */
PmlTable = (PHARDWARE_PTE)PageTable; PmlTable = (PHARDWARE_MODERN_PTE)PageTable;
PmlTable[Entry].PageFrameNumber = Address / EFI_PAGE_SIZE; PmlTable[Entry].PageFrameNumber = Address / EFI_PAGE_SIZE;
PmlTable[Entry].Valid = 1; PmlTable[Entry].Valid = 1;
PmlTable[Entry].Writable = 1; PmlTable[Entry].Writable = 1;
@@ -406,7 +415,7 @@ BlpSelfMapPml(IN PXTBL_PAGE_MAPPING PageMap,
IN ULONG_PTR SelfMapAddress) IN ULONG_PTR SelfMapAddress)
{ {
PHARDWARE_LEGACY_PTE LegacyPml; PHARDWARE_LEGACY_PTE LegacyPml;
PHARDWARE_PTE Pml; PHARDWARE_MODERN_PTE Pml;
ULONGLONG PmlIndex; ULONGLONG PmlIndex;
ULONG Index; ULONG Index;
@@ -417,13 +426,13 @@ BlpSelfMapPml(IN PXTBL_PAGE_MAPPING PageMap,
PmlIndex = (SelfMapAddress >> MM_PDI_SHIFT) & 0x1FF; PmlIndex = (SelfMapAddress >> MM_PDI_SHIFT) & 0x1FF;
/* Get Page Directory */ /* Get Page Directory */
Pml = (PHARDWARE_PTE)(((PHARDWARE_PTE)PageMap->PtePointer)[SelfMapAddress >> MM_PPI_SHIFT].PageFrameNumber * EFI_PAGE_SIZE); Pml = (PHARDWARE_MODERN_PTE)(((PHARDWARE_MODERN_PTE)PageMap->PtePointer)[SelfMapAddress >> MM_PPI_SHIFT].PageFrameNumber * EFI_PAGE_SIZE);
/* Add self-mapping for PML3 (PAE enabled) */ /* Add self-mapping for PML3 (PAE enabled) */
for(Index = 0; Index < 4; Index++) for(Index = 0; Index < 4; Index++)
{ {
RtlZeroMemory(&Pml[PmlIndex + Index], sizeof(HARDWARE_PTE)); RtlZeroMemory(&Pml[PmlIndex + Index], sizeof(HARDWARE_MODERN_PTE));
Pml[PmlIndex + Index].PageFrameNumber = ((PHARDWARE_PTE)PageMap->PtePointer)[Index].PageFrameNumber; Pml[PmlIndex + Index].PageFrameNumber = ((PHARDWARE_MODERN_PTE)PageMap->PtePointer)[Index].PageFrameNumber;
Pml[PmlIndex + Index].Valid = 1; Pml[PmlIndex + Index].Valid = 1;
Pml[PmlIndex + Index].Writable = 1; Pml[PmlIndex + Index].Writable = 1;
} }

View File

@@ -4,11 +4,84 @@
* FILE: xtldr/config.c * FILE: xtldr/config.c
* DESCRIPTION: XT Boot Loader Configuration * DESCRIPTION: XT Boot Loader Configuration
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org> * DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
* Aiken Harris <harraiken91@gmail.com>
*/ */
#include <xtldr.h> #include <xtldr.h>
/**
* @brief Retrieves the value of a specific OS boot option from a list.
*
* @param Options
* A pointer to the head of a list of XTBL_CONFIG_ENTRY structures.
*
* @param OptionName
* A pointer to wide string that contains the name of the boot option to retrieve.
*
* @param OptionValue
* A pointer to a variable that receives a pointer to the retrieved boot option's value.
*
* @return This routine returns a status code.
*
* @since XT 1.0
*/
XTCDECL
EFI_STATUS
BlGetBootOptionValue(IN PLIST_ENTRY Options,
IN CONST PWCHAR OptionName,
OUT PWCHAR *OptionValue)
{
PXTBL_CONFIG_ENTRY ConfigEntry;
PLIST_ENTRY ConfigList;
ULONG KeyLength, ValueLength;
EFI_STATUS Status;
/* Assume the option will not be found */
*OptionValue = NULL;
/* Get the length of the option name we are looking for */
KeyLength = RtlWideStringLength(OptionName, 0);
/* Start iterating from the first entry in the options list */
ConfigList = Options->Flink;
while(ConfigList != Options)
{
/* Get the container record for the current config entry */
ConfigEntry = CONTAIN_RECORD(ConfigList, XTBL_CONFIG_ENTRY, Flink);
/* Compare the current entry's name with the requested option name */
if(RtlCompareWideStringInsensitive(ConfigEntry->Name, OptionName, KeyLength) == 0)
{
/* Found the option, now prepare to copy its value */
ValueLength = RtlWideStringLength(ConfigEntry->Value, 0);
/* Allocate memory for the output value string */
Status = BlAllocateMemoryPool((ValueLength + 1) * sizeof(WCHAR), (PVOID *)OptionValue);
if(Status != STATUS_EFI_SUCCESS)
{
/* Memory allocation failure, print debug message and return status code */
BlDebugPrint(L"ERROR: Memory allocation failure (Status Code: 0x%zX)\n", Status);
*OptionValue = NULL;
return Status;
}
/* Copy the value and NULL-terminate the new string */
RtlCopyMemory(*OptionValue, ConfigEntry->Value, ValueLength * sizeof(WCHAR));
(*OptionValue)[ValueLength] = L'\0';
/* Successfully retrieved the option value, return success */
return STATUS_EFI_SUCCESS;
}
/* Move to the next entry in the list */
ConfigList = ConfigList->Flink;
}
/* Option not found */
return STATUS_EFI_NOT_FOUND;
}
/** /**
* Returns a boolean value of the specified configuration key. * Returns a boolean value of the specified configuration key.
* *
@@ -26,7 +99,7 @@ BlGetConfigBooleanValue(IN CONST PWCHAR ConfigName)
PWCHAR Value; PWCHAR Value;
/* Get config value */ /* Get config value */
Value = BlGetConfigValue(ConfigName); BlGetConfigValue(ConfigName, &Value);
/* Check if option is enabled */ /* Check if option is enabled */
if(RtlCompareWideStringInsensitive(Value, L"ENABLED", 0) == 0 || if(RtlCompareWideStringInsensitive(Value, L"ENABLED", 0) == 0 ||
@@ -53,8 +126,9 @@ BlGetConfigBooleanValue(IN CONST PWCHAR ConfigName)
* @since XT 1.0 * @since XT 1.0
*/ */
XTCDECL XTCDECL
PWCHAR EFI_STATUS
BlGetConfigValue(IN CONST PWCHAR ConfigName) BlGetConfigValue(IN CONST PWCHAR ConfigName,
OUT PWCHAR *ConfigValue)
{ {
PXTBL_CONFIG_ENTRY ConfigEntry; PXTBL_CONFIG_ENTRY ConfigEntry;
PLIST_ENTRY ConfigListEntry; PLIST_ENTRY ConfigListEntry;
@@ -62,6 +136,9 @@ BlGetConfigValue(IN CONST PWCHAR ConfigName)
EFI_STATUS Status; EFI_STATUS Status;
PWCHAR Value; PWCHAR Value;
/* Assume the option will not be found */
*ConfigValue = NULL;
/* Get config entry name length */ /* Get config entry name length */
KeyLength = RtlWideStringLength(ConfigName, 0); KeyLength = RtlWideStringLength(ConfigName, 0);
@@ -84,13 +161,14 @@ BlGetConfigValue(IN CONST PWCHAR ConfigName)
{ {
/* Memory allocation failure, return NULL */ /* Memory allocation failure, return NULL */
BlDebugPrint(L"ERROR: Memory allocation failure (Status Code: 0x%zX)\n", Status); BlDebugPrint(L"ERROR: Memory allocation failure (Status Code: 0x%zX)\n", Status);
return NULL; return Status;
} }
/* Copy value and return it */ /* Copy value and return it */
RtlCopyMemory(Value, ConfigEntry->Value, ValueLength * sizeof(WCHAR)); RtlCopyMemory(Value, ConfigEntry->Value, ValueLength * sizeof(WCHAR));
Value[ValueLength] = L'\0'; Value[ValueLength] = L'\0';
return Value; *ConfigValue = Value;
return STATUS_EFI_SUCCESS;
} }
/* Move to the next config entry */ /* Move to the next config entry */
@@ -98,7 +176,157 @@ BlGetConfigValue(IN CONST PWCHAR ConfigName)
} }
/* Config entry not found, return NULL */ /* Config entry not found, return NULL */
return NULL; return STATUS_EFI_NOT_FOUND;
}
/**
* Retrieves the list of user-editable boot options.
*
* @param OptionsArray
* A pointer to a variable that will receive the pointer to the array of editable option names.
*
* @param OptionsCount
* A pointer to a variable that will be updated with the number of elements in the OptionsArray.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCDECL
VOID
BlGetEditableOptions(OUT CONST PWCHAR **OptionsArray,
OUT PULONG OptionsCount)
{
ULONG Count = 0;
/* Return a pointer to the global array of editable options */
*OptionsArray = BlpEditableConfigOptions;
/* Calculate the number of elements in the array */
while(BlpEditableConfigOptions[Count])
{
Count++;
}
/* Return the number of elements */
*OptionsCount = Count;
}
/**
* Sets the value of a specific OS boot option in a list, or adds it if it doesn't exist.
*
* @param Options
* A pointer to the head of a list of XTBL_CONFIG_ENTRY structures.
*
* @param OptionName
* A pointer to a wide string that contains the name of the boot option to set.
*
* @param OptionValue
* A pointer to a wide string that contains the new value for the boot option.
*
* @return This routine returns a status code.
*
* @since XT 1.0
*/
XTCDECL
EFI_STATUS
BlSetBootOptionValue(IN PLIST_ENTRY Options,
IN CONST PWCHAR OptionName,
IN CONST PWCHAR OptionValue)
{
PXTBL_CONFIG_ENTRY ConfigEntry;
PLIST_ENTRY ConfigList;
ULONG Length;
EFI_STATUS Status;
/* Get the length of the option name we are looking for */
Length = RtlWideStringLength(OptionName, 0);
/* Start iterating from the first entry in the options list */
ConfigList = Options->Flink;
while(ConfigList != Options)
{
/* Get the container record for the current config entry */
ConfigEntry = CONTAIN_RECORD(ConfigList, XTBL_CONFIG_ENTRY, Flink);
/* Compare the current entry's name with the requested option name */
if(RtlCompareWideStringInsensitive(ConfigEntry->Name, OptionName, Length) == 0)
{
/* Found the option, get its length */
Length = RtlWideStringLength(OptionValue, 0);
/* Reallocate memory for the new value */
Status = BlFreeMemoryPool(ConfigEntry->Value);
if(Status != STATUS_EFI_SUCCESS)
{
/* Failed to free memory, return status code */
return Status;
}
/* Allocate new memory for the updated value */
Status = BlAllocateMemoryPool((Length + 1) * sizeof(WCHAR), (PVOID *)&ConfigEntry->Value);
if(Status != STATUS_EFI_SUCCESS)
{
/* Memory allocation failure, print debug message and return status code */
BlDebugPrint(L"ERROR: Memory allocation failure (Status Code: 0x%zX)\\n", Status);
return Status;
}
/* Copy the value and NULL-terminate the new string */
RtlCopyMemory(ConfigEntry->Value, OptionValue, Length * sizeof(WCHAR));
ConfigEntry->Value[Length] = L'\0';
return STATUS_EFI_SUCCESS;
}
/* Move to the next entry in the list */
ConfigList = ConfigList->Flink;
}
/* Option not found, allocate memory for the new one */
Status = BlAllocateMemoryPool(sizeof(XTBL_CONFIG_ENTRY), (PVOID *)&ConfigEntry);
if(Status != STATUS_EFI_SUCCESS)
{
/* Memory allocation failure, print debug message and return status code */
BlDebugPrint(L"ERROR: Memory allocation failure (Status Code: 0x%zX)\\n", Status);
return Status;
}
/* Allocate memory for the option name */
Length = RtlWideStringLength(OptionName, 0);
Status = BlAllocateMemoryPool((Length + 1) * sizeof(WCHAR), (PVOID *)&ConfigEntry->Name);
if(Status != STATUS_EFI_SUCCESS)
{
/* Memory allocation failure, print debug message and return status code */
BlDebugPrint(L"ERROR: Memory allocation failure (Status Code: 0x%zX)\\n", Status);
BlFreeMemoryPool(ConfigEntry);
return Status;
}
/* Copy the option name and NULL-terminate the new string */
RtlCopyMemory(ConfigEntry->Name, OptionName, Length * sizeof(WCHAR));
ConfigEntry->Name[Length] = L'\0';
/* Allocate memory for the option value */
Length = RtlWideStringLength(OptionValue, 0);
Status = BlAllocateMemoryPool((Length + 1) * sizeof(WCHAR), (PVOID *)&ConfigEntry->Value);
if(Status != STATUS_EFI_SUCCESS)
{
/* Memory allocation failure, print debug message and return status code */
BlDebugPrint(L"ERROR: Memory allocation failure (Status Code: 0x%zX)\\n", Status);
BlFreeMemoryPool(ConfigEntry->Name);
BlFreeMemoryPool(ConfigEntry);
return Status;
}
/* Copy the value and NULL-terminate the new string */
RtlCopyMemory(ConfigEntry->Value, OptionValue, Length * sizeof(WCHAR));
ConfigEntry->Value[Length] = L'\0';
/* Insert the new config entry at the end of the options list */
RtlInsertTailList(Options, &ConfigEntry->Flink);
/* Return success */
return STATUS_EFI_SUCCESS;
} }
/** /**
@@ -110,7 +338,7 @@ BlGetConfigValue(IN CONST PWCHAR ConfigName)
* @param ConfigValue * @param ConfigValue
* Specifies the new configuration value. * Specifies the new configuration value.
* *
* @return This routine returns status code. * @return This routine returns a status code.
* *
* @since XT 1.0 * @since XT 1.0
*/ */
@@ -174,7 +402,7 @@ BlSetConfigValue(IN CONST PWCHAR ConfigName,
/** /**
* Loads and parses XTLDR configuration file. * Loads and parses XTLDR configuration file.
* *
* @return This routine returns status code. * @return This routine returns a status code.
* *
* @since XT 1.0 * @since XT 1.0
*/ */
@@ -453,7 +681,7 @@ BlpParseConfigFile(IN CONST PCHAR RawConfig,
/* Initialize new section and convert its name to wide string */ /* Initialize new section and convert its name to wide string */
RtlInitializeListHead(&Section->Options); RtlInitializeListHead(&Section->Options);
RtlStringToWideString(Section->SectionName, &SectionName, SectionLength); RtlStringToWideString(Section->SectionName, (PCSTR*)&SectionName, SectionLength);
/* Ensure string is NULL-terminated and add new section to the configuration list */ /* Ensure string is NULL-terminated and add new section to the configuration list */
Section->SectionName[SectionLength] = L'\0'; Section->SectionName[SectionLength] = L'\0';
@@ -542,8 +770,8 @@ BlpParseConfigFile(IN CONST PCHAR RawConfig,
} }
/* Convert key and value to wide strings */ /* Convert key and value to wide strings */
RtlStringToWideString(Option->Name, &Key, RtlStringLength(Key, 0) + 1); RtlStringToWideString(Option->Name, (PCSTR*)&Key, RtlStringLength(Key, 0) + 1);
RtlStringToWideString(Option->Value, &Value, RtlStringLength(Value, 0) + 1); RtlStringToWideString(Option->Value, (PCSTR*)&Value, RtlStringLength(Value, 0) + 1);
/* Ensure strings are NULL-terminated and add new option to the list */ /* Ensure strings are NULL-terminated and add new option to the list */
Option->Name[KeyLength] = L'\0'; Option->Name[KeyLength] = L'\0';
@@ -568,7 +796,7 @@ BlpParseConfigFile(IN CONST PCHAR RawConfig,
* @param ConfigData * @param ConfigData
* Provides a buffer to store the data read from the configuration file. * Provides a buffer to store the data read from the configuration file.
* *
* @return This routine returns status code. * @return This routine returns a status code.
* *
* @since XT 1.0 * @since XT 1.0
*/ */
@@ -629,6 +857,7 @@ VOID
BlpUpdateConfiguration(IN PLIST_ENTRY NewConfig) BlpUpdateConfiguration(IN PLIST_ENTRY NewConfig)
{ {
PXTBL_CONFIG_ENTRY ConfigEntry; PXTBL_CONFIG_ENTRY ConfigEntry;
PWCHAR ConfigValue;
PLIST_ENTRY ConfigListEntry, NextListEntry; PLIST_ENTRY ConfigListEntry, NextListEntry;
/* Iterate through new config entries */ /* Iterate through new config entries */
@@ -642,7 +871,8 @@ BlpUpdateConfiguration(IN PLIST_ENTRY NewConfig)
NextListEntry = ConfigListEntry->Flink; NextListEntry = ConfigListEntry->Flink;
/* Make sure config entry does not exist yet */ /* Make sure config entry does not exist yet */
if(BlGetConfigValue(ConfigEntry->Name) == NULL) BlGetConfigValue(ConfigEntry->Name, &ConfigValue);
if(ConfigValue == NULL)
{ {
/* Remove new config entry from input list and put it into global config list */ /* Remove new config entry from input list and put it into global config list */
RtlRemoveEntryList(&ConfigEntry->Flink); RtlRemoveEntryList(&ConfigEntry->Flink);

View File

@@ -95,7 +95,7 @@ BlEnableConsoleCursor()
*/ */
XTCDECL XTCDECL
VOID VOID
BlConsolePrint(IN PUSHORT Format, BlConsolePrint(IN PCWSTR Format,
IN ...) IN ...)
{ {
RTL_PRINT_CONTEXT ConsolePrintContext, SerialPrintContext; RTL_PRINT_CONTEXT ConsolePrintContext, SerialPrintContext;
@@ -138,9 +138,9 @@ BlConsolePrint(IN PUSHORT Format,
*/ */
XTCDECL XTCDECL
VOID VOID
BlConsoleWrite(IN PUSHORT String) BlConsoleWrite(IN PCWSTR String)
{ {
EfiSystemTable->ConOut->OutputString(EfiSystemTable->ConOut, String); EfiSystemTable->ConOut->OutputString(EfiSystemTable->ConOut, (PWSTR)String);
} }
/** /**
@@ -292,9 +292,9 @@ BlSetCursorPosition(IN ULONGLONG PosX,
*/ */
XTCDECL XTCDECL
XTSTATUS XTSTATUS
BlpConsolePutChar(IN USHORT Character) BlpConsolePutChar(IN WCHAR Character)
{ {
USHORT Buffer[2]; WCHAR Buffer[2];
/* Check if character is a newline ('\n') */ /* Check if character is a newline ('\n') */
if(Character == L'\n') if(Character == L'\n')

View File

@@ -24,7 +24,7 @@
*/ */
XTCDECL XTCDECL
VOID VOID
BlDebugPrint(IN PUSHORT Format, BlDebugPrint(IN PCWSTR Format,
IN ...) IN ...)
{ {
RTL_PRINT_CONTEXT ConsolePrintContext, SerialPrintContext; RTL_PRINT_CONTEXT ConsolePrintContext, SerialPrintContext;
@@ -71,17 +71,14 @@ BlDebugPrint(IN PUSHORT Format,
*/ */
XTCDECL XTCDECL
XTSTATUS XTSTATUS
BlpDebugPutChar(IN USHORT Character) BlpDebugPutChar(IN WCHAR Character)
{ {
USHORT Buffer[2]; WCHAR Buffer[2];
/* Write character to the serial console */ /* Write character to the serial console */
Buffer[0] = Character; Buffer[0] = Character;
Buffer[1] = 0; Buffer[1] = 0;
HlComPortPutByte(&BlpStatus.SerialPort, Buffer[0]); return HlComPortPutByte(&BlpStatus.SerialPort, Buffer[0]);
/* Return success */
return STATUS_EFI_SUCCESS;
} }
/** /**
@@ -105,7 +102,7 @@ BlpInitializeDebugConsole()
BaudRate = 0; BaudRate = 0;
/* Get debug configuration */ /* Get debug configuration */
DebugConfiguration = BlGetConfigValue(L"DEBUG"); BlGetConfigValue(L"DEBUG", &DebugConfiguration);
/* Make sure any debug options are provided and debug console is not initialized yet */ /* Make sure any debug options are provided and debug console is not initialized yet */
if(DebugConfiguration && BlpStatus.DebugPort == 0) if(DebugConfiguration && BlpStatus.DebugPort == 0)

View File

@@ -21,6 +21,13 @@ LIST_ENTRY BlpConfig;
/* XT Boot Loader loaded configuration */ /* XT Boot Loader loaded configuration */
LIST_ENTRY BlpConfigSections; LIST_ENTRY BlpConfigSections;
/* List of user-editable boot options */
PWCHAR BlpEditableConfigOptions[] = {
L"BootModules", L"SystemType", L"SystemPath",
L"KernelFile", L"InitrdFile", L"HalFile",
L"Parameters", NULL
};
/* XT Boot Loader protocol */ /* XT Boot Loader protocol */
XTBL_LOADER_PROTOCOL BlpLdrProtocol; XTBL_LOADER_PROTOCOL BlpLdrProtocol;
@@ -41,3 +48,4 @@ EFI_HANDLE EfiImageHandle;
/* EFI System Table */ /* EFI System Table */
PEFI_SYSTEM_TABLE EfiSystemTable; PEFI_SYSTEM_TABLE EfiSystemTable;

View File

@@ -24,6 +24,9 @@ EXTERN LIST_ENTRY BlpConfig;
/* XT Boot Loader loaded configuration */ /* XT Boot Loader loaded configuration */
EXTERN LIST_ENTRY BlpConfigSections; EXTERN LIST_ENTRY BlpConfigSections;
/* List of user-editable boot options */
EXTERN PWCHAR BlpEditableConfigOptions[];
/* XT Boot Loader protocol */ /* XT Boot Loader protocol */
EXTERN XTBL_LOADER_PROTOCOL BlpLdrProtocol; EXTERN XTBL_LOADER_PROTOCOL BlpLdrProtocol;

View File

@@ -18,7 +18,8 @@
/* XTLDR routines forward references */ /* XTLDR routines forward references */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
BlAllocateMemoryPages(IN ULONGLONG NumberOfPages, BlAllocateMemoryPages(IN EFI_ALLOCATE_TYPE AllocationType,
IN ULONGLONG NumberOfPages,
OUT PEFI_PHYSICAL_ADDRESS Memory); OUT PEFI_PHYSICAL_ADDRESS Memory);
XTCDECL XTCDECL
@@ -50,16 +51,16 @@ BlCloseVolume(IN PEFI_HANDLE VolumeHandle);
XTCDECL XTCDECL
VOID VOID
BlConsolePrint(IN PUSHORT Format, BlConsolePrint(IN PCWSTR Format,
IN ...); IN ...);
XTCDECL XTCDECL
VOID VOID
BlConsoleWrite(IN PUSHORT String); BlConsoleWrite(IN PCWSTR String);
XTCDECL XTCDECL
VOID VOID
BlDebugPrint(IN PUSHORT Format, BlDebugPrint(IN PCWSTR Format,
IN ...); IN ...);
XTCDECL XTCDECL
@@ -70,6 +71,10 @@ XTCDECL
VOID VOID
BlDisplayBootMenu(); BlDisplayBootMenu();
XTCDECL
VOID
BlDisplayEditMenu(IN PXTBL_BOOTMENU_ITEM MenuEntry);
XTCDECL XTCDECL
VOID VOID
BlDisplayErrorDialog(IN PWCHAR Caption, BlDisplayErrorDialog(IN PWCHAR Caption,
@@ -133,19 +138,31 @@ BOOLEAN
BlGetBooleanParameter(IN CONST PWCHAR Parameters, BlGetBooleanParameter(IN CONST PWCHAR Parameters,
IN CONST PWCHAR Needle); IN CONST PWCHAR Needle);
XTCDECL
EFI_STATUS
BlGetBootOptionValue(IN PLIST_ENTRY Options,
IN CONST PWCHAR OptionName,
OUT PWCHAR *OptionValue);
XTCDECL XTCDECL
BOOLEAN BOOLEAN
BlGetConfigBooleanValue(IN CONST PWCHAR ConfigName); BlGetConfigBooleanValue(IN CONST PWCHAR ConfigName);
XTCDECL XTCDECL
PWCHAR EFI_STATUS
BlGetConfigValue(IN CONST PWCHAR ConfigName); BlGetConfigValue(IN CONST PWCHAR ConfigName,
OUT PWCHAR *ConfigValue);
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
BlGetConfigurationTable(IN PEFI_GUID TableGuid, BlGetConfigurationTable(IN PEFI_GUID TableGuid,
OUT PVOID *Table); OUT PVOID *Table);
XTCDECL
VOID
BlGetEditableOptions(OUT CONST PWCHAR **OptionsArray,
OUT PULONG OptionsCount);
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
BlGetEfiPath(IN PWCHAR SystemPath, BlGetEfiPath(IN PWCHAR SystemPath,
@@ -196,7 +213,8 @@ BlInitializeBootLoader();
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
BlInitializeBootMenuList(OUT PXTBL_BOOTMENU_ITEM *MenuEntries, BlInitializeBootMenuList(IN ULONG MaxNameLength,
OUT PXTBL_BOOTMENU_ITEM *MenuEntries,
OUT PULONG EntriesCount, OUT PULONG EntriesCount,
OUT PULONG DefaultId); OUT PULONG DefaultId);
@@ -330,6 +348,12 @@ XTCDECL
VOID VOID
BlResetConsoleInputBuffer(); BlResetConsoleInputBuffer();
XTCDECL
EFI_STATUS
BlSetBootOptionValue(IN PLIST_ENTRY Options,
IN CONST PWCHAR OptionName,
IN CONST PWCHAR OptionValue);
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
BlSetConfigValue(IN CONST PWCHAR ConfigName, BlSetConfigValue(IN CONST PWCHAR ConfigName,
@@ -394,11 +418,11 @@ BlpActivateSerialIOController();
XTCDECL XTCDECL
XTSTATUS XTSTATUS
BlpConsolePutChar(IN USHORT Character); BlpConsolePutChar(IN WCHAR Character);
XTCDECL XTCDECL
XTSTATUS XTSTATUS
BlpDebugPutChar(IN USHORT Character); BlpDebugPutChar(IN WCHAR Character);
XTCDECL XTCDECL
VOID VOID
@@ -454,6 +478,18 @@ VOID
BlpDrawDialogProgressBar(IN PXTBL_DIALOG_HANDLE Handle, BlpDrawDialogProgressBar(IN PXTBL_DIALOG_HANDLE Handle,
IN UCHAR Percentage); IN UCHAR Percentage);
XTCDECL
VOID
BlpDrawEditMenu(OUT PXTBL_DIALOG_HANDLE Handle);
XTCDECL
EFI_STATUS
BlpDrawEditMenuEntry(IN PXTBL_DIALOG_HANDLE Handle,
IN PWCHAR OptionName,
IN PWCHAR OptionValue,
IN UINT Position,
IN BOOLEAN Highlighted);
XTCDECL XTCDECL
PEFI_DEVICE_PATH_PROTOCOL PEFI_DEVICE_PATH_PROTOCOL
BlpDuplicateDevicePath(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath); BlpDuplicateDevicePath(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath);

View File

@@ -24,10 +24,11 @@
*/ */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
BlAllocateMemoryPages(IN ULONGLONG NumberOfPages, BlAllocateMemoryPages(IN EFI_ALLOCATE_TYPE AllocationType,
IN ULONGLONG NumberOfPages,
OUT PEFI_PHYSICAL_ADDRESS Memory) OUT PEFI_PHYSICAL_ADDRESS Memory)
{ {
return EfiSystemTable->BootServices->AllocatePages(AllocateAnyPages, EfiLoaderData, NumberOfPages, Memory); return EfiSystemTable->BootServices->AllocatePages(AllocationType, EfiLoaderData, NumberOfPages, Memory);
} }
/** /**

View File

@@ -196,6 +196,7 @@ XtLdrModuleMain(IN EFI_HANDLE ImageHandle,
IN PEFI_SYSTEM_TABLE SystemTable) IN PEFI_SYSTEM_TABLE SystemTable)
{ {
EFI_STATUS Status; EFI_STATUS Status;
PWCHAR Tune;
/* Open the XTLDR protocol */ /* Open the XTLDR protocol */
Status = BlGetXtLdrProtocol(SystemTable, ImageHandle, &XtLdrProtocol); Status = BlGetXtLdrProtocol(SystemTable, ImageHandle, &XtLdrProtocol);
@@ -206,7 +207,8 @@ XtLdrModuleMain(IN EFI_HANDLE ImageHandle,
} }
/* Play the tune set in the configuration */ /* Play the tune set in the configuration */
BpPlayTune(XtLdrProtocol->Config.GetValue(L"TUNE")); XtLdrProtocol->Config.GetValue(L"TUNE", &Tune);
BpPlayTune(Tune);
/* Return success */ /* Return success */
return STATUS_EFI_SUCCESS; return STATUS_EFI_SUCCESS;

View File

@@ -409,7 +409,7 @@ PeLoadImage(IN PEFI_FILE_HANDLE FileHandle,
Pages = EFI_SIZE_TO_PAGES(ImageData->FileSize); Pages = EFI_SIZE_TO_PAGES(ImageData->FileSize);
/* Allocate pages */ /* Allocate pages */
Status = XtLdrProtocol->Memory.AllocatePages(Pages, &Address); Status = XtLdrProtocol->Memory.AllocatePages(AllocateAnyPages, Pages, &Address);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Pages allocation failure */ /* Pages allocation failure */
@@ -472,7 +472,7 @@ PeLoadImage(IN PEFI_FILE_HANDLE FileHandle,
ImageData->ImagePages = EFI_SIZE_TO_PAGES(ImageData->ImageSize); ImageData->ImagePages = EFI_SIZE_TO_PAGES(ImageData->ImageSize);
/* Allocate image pages */ /* Allocate image pages */
Status = XtLdrProtocol->Memory.AllocatePages(ImageData->ImagePages, &Address); Status = XtLdrProtocol->Memory.AllocatePages(AllocateAnyPages, ImageData->ImagePages, &Address);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Pages reallocation failure */ /* Pages reallocation failure */

View File

@@ -70,25 +70,54 @@ XTCDECL
EFI_STATUS EFI_STATUS
XtpMapHardwareMemoryPool(IN PXTBL_PAGE_MAPPING PageMap) XtpMapHardwareMemoryPool(IN PXTBL_PAGE_MAPPING PageMap)
{ {
PHARDWARE_PTE PdeBase, PpeBase, PxeBase; PHARDWARE_PTE P5eBase, PdeBase, PpeBase, PxeBase;
EFI_PHYSICAL_ADDRESS Address; EFI_PHYSICAL_ADDRESS Address;
EFI_STATUS Status; EFI_STATUS Status;
/* Check page map level */ if(PageMap->PageMapLevel == 5)
if(PageMap->PageMapLevel > 4)
{ {
/* PML5 (LA57) is not supported yet */ /* Get P5E (PML5) base address */
return STATUS_EFI_UNSUPPORTED; P5eBase = (PHARDWARE_PTE)PageMap->PtePointer;
}
/* Get PXE (PML4) base address */ /* Check if P5E entry already exists */
PxeBase = ((PHARDWARE_PTE)(PageMap->PtePointer)); if(!P5eBase[(MM_HARDWARE_VA_START >> MM_P5I_SHIFT) & 0x1FF].Valid)
{
/* No valid P5E, allocate memory */
Status = XtLdrProtocol->Memory.AllocatePages(AllocateAnyPages, 1, &Address);
if(Status != STATUS_EFI_SUCCESS)
{
/* Memory allocation failure, return error */
return Status;
}
/* Zero fill memory used by P5E */
RtlZeroMemory((PVOID)Address, EFI_PAGE_SIZE);
/* Make P5E valid */
P5eBase[(MM_HARDWARE_VA_START >> MM_P5I_SHIFT) & 0x1FF].Valid = 1;
P5eBase[(MM_HARDWARE_VA_START >> MM_P5I_SHIFT) & 0x1FF].PageFrameNumber = Address / EFI_PAGE_SIZE;
P5eBase[(MM_HARDWARE_VA_START >> MM_P5I_SHIFT) & 0x1FF].Writable = 1;
/* Set PXE base address */
PxeBase = (PHARDWARE_PTE)(UINT_PTR)Address;
}
else
{
/* Set PXE base address based on existing P5E */
PxeBase = (PHARDWARE_PTE)((P5eBase[(MM_HARDWARE_VA_START >> MM_P5I_SHIFT) & 0x1FF].PageFrameNumber) << EFI_PAGE_SHIFT);
}
}
else
{
/* Get PXE (PML4) base address */
PxeBase = (PHARDWARE_PTE)PageMap->PtePointer;
}
/* Check if PXE entry already exists */ /* Check if PXE entry already exists */
if(!PxeBase[(MM_HARDWARE_VA_START >> MM_PXI_SHIFT) & 0x1FF].Valid) if(!PxeBase[(MM_HARDWARE_VA_START >> MM_PXI_SHIFT) & 0x1FF].Valid)
{ {
/* No valid PXE, allocate memory */ /* No valid PXE, allocate memory */
Status = XtLdrProtocol->Memory.AllocatePages(1, &Address); Status = XtLdrProtocol->Memory.AllocatePages(AllocateAnyPages, 1, &Address);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Memory allocation failure, return error */ /* Memory allocation failure, return error */
@@ -116,7 +145,7 @@ XtpMapHardwareMemoryPool(IN PXTBL_PAGE_MAPPING PageMap)
if(!PpeBase[(MM_HARDWARE_VA_START >> MM_PPI_SHIFT) & 0x1FF].Valid) if(!PpeBase[(MM_HARDWARE_VA_START >> MM_PPI_SHIFT) & 0x1FF].Valid)
{ {
/* No valid PPE, allocate memory */ /* No valid PPE, allocate memory */
Status = XtLdrProtocol->Memory.AllocatePages(1, &Address); Status = XtLdrProtocol->Memory.AllocatePages(AllocateAnyPages, 1, &Address);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Memory allocation failure, return error */ /* Memory allocation failure, return error */
@@ -147,7 +176,7 @@ XtpMapHardwareMemoryPool(IN PXTBL_PAGE_MAPPING PageMap)
if(!PdeBase[((MM_HARDWARE_VA_START >> MM_PDI_SHIFT) & 0x1FF) + Index].Valid) if(!PdeBase[((MM_HARDWARE_VA_START >> MM_PDI_SHIFT) & 0x1FF) + Index].Valid)
{ {
/* No valid PDE, allocate memory */ /* No valid PDE, allocate memory */
Status = XtLdrProtocol->Memory.AllocatePages(1, &Address); Status = XtLdrProtocol->Memory.AllocatePages(AllocateAnyPages, 1, &Address);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Memory allocation failure, return error */ /* Memory allocation failure, return error */
@@ -183,9 +212,12 @@ EFI_STATUS
XtEnablePaging(IN PXTBL_PAGE_MAPPING PageMap) XtEnablePaging(IN PXTBL_PAGE_MAPPING PageMap)
{ {
EFI_STATUS Status; EFI_STATUS Status;
EFI_PHYSICAL_ADDRESS TrampolineAddress;
PXT_TRAMPOLINE_ENTRY TrampolineEntry;
ULONG_PTR TrampolineSize;
/* Build page map */ /* Build page map */
Status = XtLdrProtocol->Memory.BuildPageMap(PageMap, 0xFFFFF6FB7DBED000); Status = XtLdrProtocol->Memory.BuildPageMap(PageMap, (PageMap->PageMapLevel > 4) ? MM_P5E_LA57_BASE : MM_PXE_BASE);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Failed to build page map */ /* Failed to build page map */
@@ -202,6 +234,29 @@ XtEnablePaging(IN PXTBL_PAGE_MAPPING PageMap)
return Status; return Status;
} }
/* Check the configured page map level to set the LA57 state accordingly */
if(PageMap->PageMapLevel == 5)
{
/* Set the address of the trampoline code below 1MB */
TrampolineAddress = MM_TRAMPOLINE_ADDRESS;
/* Calculate the size of the trampoline code */
TrampolineSize = (ULONG_PTR)ArEnableExtendedPhysicalAddressingEnd - (ULONG_PTR)ArEnableExtendedPhysicalAddressing;
/* Allocate pages for the trampoline */
Status = XtLdrProtocol->Memory.AllocatePages(AllocateAddress, EFI_SIZE_TO_PAGES(TrampolineSize), &TrampolineAddress);
if(Status != STATUS_EFI_SUCCESS)
{
/* Failed to allocate memory for trampoline code */
XtLdrProtocol->Debug.Print(L"Failed to allocate memory for trampoline code (Status code: %zX)\n", Status);
return Status;
}
/* Set the trampoline entry point and copy its code into the allocated buffer */
TrampolineEntry = (PXT_TRAMPOLINE_ENTRY)(UINT_PTR)TrampolineAddress;
RtlCopyMemory(TrampolineEntry, ArEnableExtendedPhysicalAddressing, TrampolineSize);
}
/* Exit EFI Boot Services */ /* Exit EFI Boot Services */
XtLdrProtocol->Debug.Print(L"Exiting EFI boot services\n"); XtLdrProtocol->Debug.Print(L"Exiting EFI boot services\n");
Status = XtLdrProtocol->Util.ExitBootServices(); Status = XtLdrProtocol->Util.ExitBootServices();
@@ -217,19 +272,20 @@ XtEnablePaging(IN PXTBL_PAGE_MAPPING PageMap)
{ {
/* Enable Linear Address 57-bit (LA57) extension */ /* Enable Linear Address 57-bit (LA57) extension */
XtLdrProtocol->Debug.Print(L"Enabling Linear Address 57-bit (LA57)\n"); XtLdrProtocol->Debug.Print(L"Enabling Linear Address 57-bit (LA57)\n");
/* Execute the trampoline to enable LA57 and write PML5 to CR3 */
TrampolineEntry((UINT64)PageMap->PtePointer);
} }
else else
{ {
/* Disable Linear Address 57-bit (LA57) extension */ /* Disable Linear Address 57-bit (LA57) extension */
XtLdrProtocol->Debug.Print(L"Disabling Linear Address 57-bit (LA57)\n"); XtLdrProtocol->Debug.Print(L"Disabling Linear Address 57-bit (LA57)\n");
/* Write PML4 to CR3 and enable paging */
ArWriteControlRegister(3, (UINT_PTR)PageMap->PtePointer);
ArWriteControlRegister(0, ArReadControlRegister(0) | CR0_PG);
} }
/* Write PML4 to CR3 */
ArWriteControlRegister(3, (UINT_PTR)PageMap->PtePointer);
/* Enable paging */
ArWriteControlRegister(0, ArReadControlRegister(0) | CR0_PG);
/* Return success */ /* Return success */
return STATUS_EFI_SUCCESS; return STATUS_EFI_SUCCESS;
} }

View File

@@ -60,11 +60,11 @@ XtpMapHardwareMemoryPool(IN PXTBL_PAGE_MAPPING PageMap)
{ {
EFI_PHYSICAL_ADDRESS Address; EFI_PHYSICAL_ADDRESS Address;
PHARDWARE_LEGACY_PTE LegacyPdeBase; PHARDWARE_LEGACY_PTE LegacyPdeBase;
PHARDWARE_PTE PdeBase; PHARDWARE_MODERN_PTE PdeBase;
EFI_STATUS Status; EFI_STATUS Status;
/* Allocate memory */ /* Allocate memory */
Status = XtLdrProtocol->Memory.AllocatePages(1, &Address); Status = XtLdrProtocol->Memory.AllocatePages(AllocateAnyPages, 1, &Address);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Memory allocation failure, return error */ /* Memory allocation failure, return error */
@@ -78,10 +78,10 @@ XtpMapHardwareMemoryPool(IN PXTBL_PAGE_MAPPING PageMap)
if(PageMap->PageMapLevel == 3) if(PageMap->PageMapLevel == 3)
{ {
/* Get PDE base address (PAE enabled) */ /* Get PDE base address (PAE enabled) */
PdeBase = (PHARDWARE_PTE)(((PHARDWARE_PTE)PageMap->PtePointer)[MM_HARDWARE_VA_START >> MM_PPI_SHIFT].PageFrameNumber << MM_PAGE_SHIFT); PdeBase = (PHARDWARE_MODERN_PTE)(((PHARDWARE_MODERN_PTE)PageMap->PtePointer)[MM_HARDWARE_VA_START >> MM_PPI_SHIFT].PageFrameNumber << MM_PAGE_SHIFT);
/* Make PDE valid */ /* Make PDE valid */
RtlZeroMemory(&PdeBase[(MM_HARDWARE_VA_START >> MM_PDI_SHIFT) & 0x1FF], sizeof(HARDWARE_PTE)); RtlZeroMemory(&PdeBase[(MM_HARDWARE_VA_START >> MM_PDI_SHIFT) & 0x1FF], sizeof(HARDWARE_MODERN_PTE));
PdeBase[(MM_HARDWARE_VA_START >> MM_PDI_SHIFT) & 0x1FF].PageFrameNumber = Address >> MM_PAGE_SHIFT; PdeBase[(MM_HARDWARE_VA_START >> MM_PDI_SHIFT) & 0x1FF].PageFrameNumber = Address >> MM_PAGE_SHIFT;
PdeBase[(MM_HARDWARE_VA_START >> MM_PDI_SHIFT) & 0x1FF].Valid = 1; PdeBase[(MM_HARDWARE_VA_START >> MM_PDI_SHIFT) & 0x1FF].Valid = 1;
PdeBase[(MM_HARDWARE_VA_START >> MM_PDI_SHIFT) & 0x1FF].Writable = 1; PdeBase[(MM_HARDWARE_VA_START >> MM_PDI_SHIFT) & 0x1FF].Writable = 1;
@@ -126,7 +126,7 @@ XtEnablePaging(IN PXTBL_PAGE_MAPPING PageMap)
EFI_STATUS Status; EFI_STATUS Status;
/* Build page map */ /* Build page map */
Status = XtLdrProtocol->Memory.BuildPageMap(PageMap, 0xC0000000); Status = XtLdrProtocol->Memory.BuildPageMap(PageMap, MM_PTE_BASE);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Failed to build page map */ /* Failed to build page map */

View File

@@ -29,9 +29,15 @@ typedef struct _XT_FRAMEBUFFER_PROTOCOL
/* EFI XT Loader Protocol */ /* EFI XT Loader Protocol */
EXTERN PXTBL_LOADER_PROTOCOL XtLdrProtocol; EXTERN PXTBL_LOADER_PROTOCOL XtLdrProtocol;
/* XTOS trampoline end address to calculate trampoline size */
EXTERN PVOID ArEnableExtendedPhysicalAddressingEnd[];
/* XTOS kernel entry point */ /* XTOS kernel entry point */
typedef VOID (XTAPI *PXT_ENTRY_POINT)(IN PKERNEL_INITIALIZATION_BLOCK BootParameters); typedef VOID (XTAPI *PXT_ENTRY_POINT)(IN PKERNEL_INITIALIZATION_BLOCK BootParameters);
/* XTOS trampoline entry point */
typedef VOID (*PXT_TRAMPOLINE_ENTRY)(UINT64 PageMap);
/* XTOS boot protocol related routines forward references */ /* XTOS boot protocol related routines forward references */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS

View File

@@ -75,7 +75,7 @@ XtGetMemoryDescriptorList(IN PXTBL_PAGE_MAPPING PageMap,
Pages = (ULONGLONG)EFI_SIZE_TO_PAGES((PageMap->MapSize + 1) * sizeof(LOADER_MEMORY_DESCRIPTOR)); Pages = (ULONGLONG)EFI_SIZE_TO_PAGES((PageMap->MapSize + 1) * sizeof(LOADER_MEMORY_DESCRIPTOR));
Status = XtLdrProtocol->Memory.AllocatePages(Pages, &Address); Status = XtLdrProtocol->Memory.AllocatePages(AllocateAnyPages, Pages, &Address);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
return Status; return Status;
@@ -136,7 +136,7 @@ XtGetSystemResourcesList(IN PXTBL_PAGE_MAPPING PageMap,
Pages = (ULONGLONG)EFI_SIZE_TO_PAGES(sizeof(SYSTEM_RESOURCE_ACPI) + sizeof(SYSTEM_RESOURCE_FRAMEBUFFER)); Pages = (ULONGLONG)EFI_SIZE_TO_PAGES(sizeof(SYSTEM_RESOURCE_ACPI) + sizeof(SYSTEM_RESOURCE_FRAMEBUFFER));
Status = XtLdrProtocol->Memory.AllocatePages(Pages, &Address); Status = XtLdrProtocol->Memory.AllocatePages(AllocateAnyPages, Pages, &Address);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
return Status; return Status;
@@ -547,12 +547,16 @@ XtpInitializeLoaderBlock(IN PXTBL_PAGE_MAPPING PageMap,
// PVOID RuntimeServices; // PVOID RuntimeServices;
EFI_STATUS Status; EFI_STATUS Status;
UINT BlockPages; UINT BlockPages;
UINT ParametersSize;
/* Calculate size of parameters */
ParametersSize = (RtlWideStringLength(Parameters->Parameters, 0) + 1) * sizeof(WCHAR);
/* Calculate number of pages needed for initialization block */ /* Calculate number of pages needed for initialization block */
BlockPages = EFI_SIZE_TO_PAGES(sizeof(KERNEL_INITIALIZATION_BLOCK)); BlockPages = EFI_SIZE_TO_PAGES(sizeof(KERNEL_INITIALIZATION_BLOCK) + ParametersSize);
/* Allocate memory for kernel initialization block */ /* Allocate memory for kernel initialization block */
Status = XtLdrProtocol->Memory.AllocatePages(BlockPages, &Address); Status = XtLdrProtocol->Memory.AllocatePages(AllocateAnyPages, BlockPages, &Address);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Memory allocation failure */ /* Memory allocation failure */
@@ -561,7 +565,7 @@ XtpInitializeLoaderBlock(IN PXTBL_PAGE_MAPPING PageMap,
/* Initialize and zero-fill kernel initialization block */ /* Initialize and zero-fill kernel initialization block */
LoaderBlock = (PKERNEL_INITIALIZATION_BLOCK)(UINT_PTR)Address; LoaderBlock = (PKERNEL_INITIALIZATION_BLOCK)(UINT_PTR)Address;
RtlZeroMemory(LoaderBlock, sizeof(KERNEL_INITIALIZATION_BLOCK)); RtlZeroMemory(LoaderBlock, sizeof(KERNEL_INITIALIZATION_BLOCK) + ParametersSize);
/* Set basic loader block properties */ /* Set basic loader block properties */
LoaderBlock->BlockSize = sizeof(KERNEL_INITIALIZATION_BLOCK); LoaderBlock->BlockSize = sizeof(KERNEL_INITIALIZATION_BLOCK);
@@ -571,9 +575,6 @@ XtpInitializeLoaderBlock(IN PXTBL_PAGE_MAPPING PageMap,
/* Set LoaderInformation block properties */ /* Set LoaderInformation block properties */
LoaderBlock->LoaderInformation.DbgPrint = XtLdrProtocol->Debug.Print; LoaderBlock->LoaderInformation.DbgPrint = XtLdrProtocol->Debug.Print;
/* Store page map level */
LoaderBlock->LoaderInformation.PageMapLevel = PageMap->PageMapLevel;
/* Attempt to find virtual address of the EFI Runtime Services */ /* Attempt to find virtual address of the EFI Runtime Services */
// Status = XtLdrProtocol->GetVirtualAddress(MemoryMappings, &EfiSystemTable->RuntimeServices->Hdr, &RuntimeServices); // Status = XtLdrProtocol->GetVirtualAddress(MemoryMappings, &EfiSystemTable->RuntimeServices->Hdr, &RuntimeServices);
// if(Status == STATUS_EFI_SUCCESS) // if(Status == STATUS_EFI_SUCCESS)
@@ -590,8 +591,10 @@ XtpInitializeLoaderBlock(IN PXTBL_PAGE_MAPPING PageMap,
// } // }
/* Copy parameters to kernel initialization block */ /* Copy parameters to kernel initialization block */
RtlCopyMemory(LoaderBlock->KernelParameters, Parameters->Parameters, LoaderBlock->KernelParameters = (PWCHAR)((UINT_PTR)*VirtualAddress + sizeof(KERNEL_INITIALIZATION_BLOCK));
(RtlWideStringLength(Parameters->Parameters, 0) + 1) * sizeof(WCHAR)); RtlCopyMemory((PVOID)((UINT_PTR)LoaderBlock + sizeof(KERNEL_INITIALIZATION_BLOCK)),
Parameters->Parameters,
ParametersSize);
/* Map kernel initialization block */ /* Map kernel initialization block */
XtLdrProtocol->Memory.MapVirtualMemory(PageMap, *VirtualAddress, (PVOID)LoaderBlock, XtLdrProtocol->Memory.MapVirtualMemory(PageMap, *VirtualAddress, (PVOID)LoaderBlock,

View File

@@ -749,100 +749,96 @@ BlpGetModuleInfoStrings(IN PWCHAR SectionData,
EFI_STATUS Status; EFI_STATUS Status;
PWCHAR *Array; PWCHAR *Array;
PWCHAR String; PWCHAR String;
ULONG DataSize;
/* Check input parameters */ /* Check input parameters */
InfoStrings = SectionData; InfoStrings = SectionData;
if(!InfoStrings || !SectionSize) if(!InfoStrings || !SectionSize)
{ {
/* Invalid input parameters */ /* Invalid input parameters */
*ModInfo = NULL;
*InfoCount = 0;
return STATUS_EFI_INVALID_PARAMETER; return STATUS_EFI_INVALID_PARAMETER;
} }
/* Skip zero padding */ /* Calculate the size of the data based on the size of the section */
while(InfoStrings[0] == L'\0' && SectionSize > 1) DataSize = SectionSize / sizeof(WCHAR);
/* Skip zero padding at the beginning */
while(DataSize > 0 && *InfoStrings == L'\0')
{ {
/* Get next character and decrement section size */
InfoStrings++; InfoStrings++;
SectionSize--; DataSize--;
} }
/* Make sure there is at least one string available */ /* Make sure there is at least one string available */
if(SectionSize <= 1) if(DataSize < 1)
{ {
/* No strings found */ /* No strings found */
*ModInfo = NULL;
*InfoCount = 0;
return STATUS_EFI_END_OF_FILE; return STATUS_EFI_END_OF_FILE;
} }
/* Count number of strings */ /* Count number of strings */
Index = 0; Index = 0;
Count = 0; Count = 0;
while(Index < SectionSize) while(Index < DataSize)
{ {
/* Get to the next string */ /* Found start of a new string */
if(InfoStrings[Index] != L'\0') Count++;
{
/* Get next character */
Index++;
continue;
}
/* Skip zero padding */ /* Go to the end of the string */
while(InfoStrings[Index] == L'\0' && Index < SectionSize) while(Index < DataSize && InfoStrings[Index] != L'\0')
{
Index++;
}
/* Skip all null terminators */
while(Index < DataSize && InfoStrings[Index] == L'\0')
{ {
/* Get next character */
Index++; Index++;
} }
/* New string found, increment counter */
Count++;
} }
/* Make sure there is no missing string */ /* Allocate memory for the pointer array and the string data */
if(InfoStrings[Index - 1] != L'\0') Status = BlAllocateMemoryPool(sizeof(PWCHAR) * (Count + 1) + (DataSize + 1) * sizeof(WCHAR), (PVOID *)&Array);
{
/* One more string available */
Count++;
}
/* Allocate memory for array of strings */
Status = BlAllocateMemoryPool(SectionSize + 1 + sizeof(PWCHAR) * (Count + 1), (PVOID *)&Array);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Failed to allocate memory */ /* Failed to allocate memory */
return STATUS_EFI_OUT_OF_RESOURCES; return STATUS_EFI_OUT_OF_RESOURCES;
} }
/* Allocate memory and copy strings read from '.modinfo' section */ /* The string buffer is located right after the pointer array */
BlAllocateMemoryPool(SectionSize, (PVOID*)&String); String = (PWCHAR)(Array + Count + 1);
RtlCopyMemory(String, InfoStrings, SectionSize);
/* Make sure last string is NULL-terminated */ /* Copy the raw string data */
RtlCopyMemory(String, InfoStrings, DataSize * sizeof(WCHAR));
/* Ensure the entire buffer is null-terminated for safety */
String[DataSize] = L'\0';
/* Set the last element of the pointer array to NULL */
Array[Count] = NULL; Array[Count] = NULL;
Array[0] = String;
/* Parse strings into array */ /* Populate the array with pointers to the strings within the buffer */
Index = 0; Index = 0;
ArrayIndex = 1; ArrayIndex = 0;
while(Index < SectionSize && ArrayIndex < Count) while(Index < DataSize && ArrayIndex < Count)
{ {
/* Get to the next string */ /* Set pointer to the beginning of the string */
if(String[Index] != L'\0') Array[ArrayIndex++] = &String[Index];
{
/* Get next character */
Index++;
continue;
}
/* Skip zero padding */ /* Find the end of the current string */
while(InfoStrings[Index] == L'\0' && Index < SectionSize) while(Index < DataSize && String[Index] != L'\0')
{ {
/* Get next character */
Index++; Index++;
} }
/* Push string into array */ /* Skip all null terminators to find the beginning of the next string */
Array[ArrayIndex] = &String[Index]; while(Index < DataSize && String[Index] == L'\0')
ArrayIndex++; {
Index++;
}
} }
/* Return array of strings and its size */ /* Return array of strings and its size */
@@ -874,7 +870,10 @@ BlpInstallXtLoaderProtocol()
BlpLdrProtocol.Boot.RegisterProtocol = BlRegisterBootProtocol; BlpLdrProtocol.Boot.RegisterProtocol = BlRegisterBootProtocol;
BlpLdrProtocol.BootUtil.GetBooleanParameter = BlGetBooleanParameter; BlpLdrProtocol.BootUtil.GetBooleanParameter = BlGetBooleanParameter;
BlpLdrProtocol.Config.GetBooleanValue = BlGetConfigBooleanValue; BlpLdrProtocol.Config.GetBooleanValue = BlGetConfigBooleanValue;
BlpLdrProtocol.Config.GetBootOptionValue = BlGetBootOptionValue;
BlpLdrProtocol.Config.GetEditableOptions = BlGetEditableOptions;
BlpLdrProtocol.Config.GetValue = BlGetConfigValue; BlpLdrProtocol.Config.GetValue = BlGetConfigValue;
BlpLdrProtocol.Config.SetBootOptionValue = BlSetBootOptionValue;
BlpLdrProtocol.Console.ClearLine = BlClearConsoleLine; BlpLdrProtocol.Console.ClearLine = BlClearConsoleLine;
BlpLdrProtocol.Console.ClearScreen = BlClearConsoleScreen; BlpLdrProtocol.Console.ClearScreen = BlClearConsoleScreen;
BlpLdrProtocol.Console.DisableCursor = BlDisableConsoleCursor; BlpLdrProtocol.Console.DisableCursor = BlDisableConsoleCursor;

View File

@@ -24,7 +24,8 @@ BlDisplayBootMenu()
XTBL_DIALOG_HANDLE Handle; XTBL_DIALOG_HANDLE Handle;
PXTBL_BOOTMENU_ITEM MenuEntries = NULL; PXTBL_BOOTMENU_ITEM MenuEntries = NULL;
ULONG Index; ULONG Index;
ULONG HighligtedEntryId, NumberOfEntries, TopVisibleEntry, VisibleEntries; ULONG HighligtedEntryId, OldHighligtedEntryId, NumberOfEntries, TopVisibleEntry, VisibleEntries;
BOOLEAN RedrawBootMenu, RedrawEntries;
UINT_PTR EventIndex; UINT_PTR EventIndex;
EFI_EVENT Events[2]; EFI_EVENT Events[2];
EFI_INPUT_KEY Key; EFI_INPUT_KEY Key;
@@ -33,18 +34,18 @@ BlDisplayBootMenu()
LONG TimeOut; LONG TimeOut;
PWCHAR TimeOutString; PWCHAR TimeOutString;
/* Draw boot menu */
BlpDrawBootMenu(&Handle);
/* Initialize boot menu list */ /* Initialize boot menu list */
TopVisibleEntry = 0; TopVisibleEntry = 0;
Status = BlInitializeBootMenuList(&MenuEntries, &NumberOfEntries, &HighligtedEntryId); Status = BlInitializeBootMenuList(Handle.Width - 4, &MenuEntries, &NumberOfEntries, &HighligtedEntryId);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Failed to initialize boot menu list, exit into XTLDR shell */ /* Failed to initialize boot menu list, exit into XTLDR shell */
return; return;
} }
/* Draw boot menu */
BlpDrawBootMenu(&Handle);
/* Calculate how many entries can be visible in the menu box */ /* Calculate how many entries can be visible in the menu box */
VisibleEntries = Handle.Height - 2; VisibleEntries = Handle.Height - 2;
@@ -56,7 +57,7 @@ BlDisplayBootMenu()
} }
/* Get timeout from the configuration */ /* Get timeout from the configuration */
TimeOutString = BlGetConfigValue(L"TIMEOUT"); BlGetConfigValue(L"TIMEOUT", &TimeOutString);
TimeOut = -1; TimeOut = -1;
/* Check if timeout is specified */ /* Check if timeout is specified */
@@ -72,14 +73,23 @@ BlDisplayBootMenu()
} }
} }
/* Set redraw flags to not redraw the menu itself, but fill it with entries */
RedrawBootMenu = FALSE;
RedrawEntries = TRUE;
/* Infinite boot menu loop */ /* Infinite boot menu loop */
while(TRUE) while(TRUE)
{ {
/* Redraw boot menu */ /* Redraw boot menu frame if requested */
BlpDrawBootMenu(&Handle); if(RedrawBootMenu)
{
BlpDrawBootMenu(&Handle);
RedrawBootMenu = FALSE;
RedrawEntries = TRUE;
}
/* Sanity check to ensure we do not display more entries than possible */ /* Sanity check to ensure we do not display more entries than possible */
if (VisibleEntries > NumberOfEntries) if(VisibleEntries > NumberOfEntries)
{ {
VisibleEntries = NumberOfEntries; VisibleEntries = NumberOfEntries;
} }
@@ -87,12 +97,19 @@ BlDisplayBootMenu()
/* Check if there is anything to show in the boot menu */ /* Check if there is anything to show in the boot menu */
if(NumberOfEntries > 0) if(NumberOfEntries > 0)
{ {
/* Iterate through all menu entries */ /* Check if we need to redraw boot menu entries */
for(Index = 0; Index < VisibleEntries; Index++) if(RedrawEntries)
{ {
/* Draw menu entry */ /* Iterate through all menu entries */
BlpDrawBootMenuEntry(&Handle, MenuEntries[TopVisibleEntry + Index].EntryName, for(Index = 0; Index < VisibleEntries; Index++)
Index, (TopVisibleEntry + Index) == HighligtedEntryId); {
/* Draw menu entry */
BlpDrawBootMenuEntry(&Handle, MenuEntries[TopVisibleEntry + Index].EntryName,
Index, (TopVisibleEntry + Index) == HighligtedEntryId);
}
/* Clear redraw entries flag */
RedrawEntries = FALSE;
} }
} }
else else
@@ -126,6 +143,9 @@ BlDisplayBootMenu()
/* Flush keyboard buffer out of any keystrokes */ /* Flush keyboard buffer out of any keystrokes */
EfiSystemTable->ConIn->Reset(EfiSystemTable->ConIn, FALSE); EfiSystemTable->ConIn->Reset(EfiSystemTable->ConIn, FALSE);
/* Store old highlighted entry */
OldHighligtedEntryId = HighligtedEntryId;
/* Infinite boot menu event loop */ /* Infinite boot menu event loop */
while(TRUE) while(TRUE)
{ {
@@ -157,7 +177,7 @@ BlDisplayBootMenu()
BlSetConsoleAttributes(Handle.DialogColor | Handle.TextColor); BlSetConsoleAttributes(Handle.DialogColor | Handle.TextColor);
BlClearConsoleLine(Handle.PosY + Handle.Height + 4); BlClearConsoleLine(Handle.PosY + Handle.Height + 4);
BlSetCursorPosition(4, Handle.PosY + Handle.Height + 4); BlSetCursorPosition(4, Handle.PosY + Handle.Height + 4);
BlConsolePrint(L"Booting '%S' now...\n", MenuEntries[HighligtedEntryId].EntryName); BlConsolePrint(L"Booting '%S' now...\n", MenuEntries[HighligtedEntryId].FullName);
/* Boot the highlighted (chosen) OS */ /* Boot the highlighted (chosen) OS */
Status = BlInvokeBootProtocol(MenuEntries[HighligtedEntryId].ShortName, Status = BlInvokeBootProtocol(MenuEntries[HighligtedEntryId].ShortName,
@@ -166,8 +186,9 @@ BlDisplayBootMenu()
{ {
/* Failed to boot OS */ /* Failed to boot OS */
BlDebugPrint(L"ERROR: Failed to boot '%S' (Status Code: 0x%zX)\n", BlDebugPrint(L"ERROR: Failed to boot '%S' (Status Code: 0x%zX)\n",
MenuEntries[HighligtedEntryId].EntryName, Status); MenuEntries[HighligtedEntryId].FullName, Status);
BlDisplayErrorDialog(L"XTLDR", L"Failed to startup the selected Operating System."); BlDisplayErrorDialog(L"XTLDR", L"Failed to startup the selected Operating System.");
RedrawBootMenu = TRUE;
} }
/* Break from boot menu event loop to redraw whole boot menu */ /* Break from boot menu event loop to redraw whole boot menu */
@@ -176,14 +197,26 @@ BlDisplayBootMenu()
else if(Key.ScanCode == 0x01) else if(Key.ScanCode == 0x01)
{ {
/* UpArrow key pressed, go to previous entry if possible */ /* UpArrow key pressed, go to previous entry if possible */
if (HighligtedEntryId > 0) if(HighligtedEntryId > 0)
{ {
/* Highlight previous entry */
OldHighligtedEntryId = HighligtedEntryId;
HighligtedEntryId--; HighligtedEntryId--;
if (HighligtedEntryId < TopVisibleEntry)
/* Check if we need to scroll the view */
if(HighligtedEntryId < TopVisibleEntry)
{ {
/* Scroll the view */
TopVisibleEntry = HighligtedEntryId; TopVisibleEntry = HighligtedEntryId;
RedrawEntries = TRUE;
break;
} }
break;
/* Redraw new highlighted entry and the old one */
BlpDrawBootMenuEntry(&Handle, MenuEntries[OldHighligtedEntryId].EntryName,
OldHighligtedEntryId - TopVisibleEntry, FALSE);
BlpDrawBootMenuEntry(&Handle, MenuEntries[HighligtedEntryId].EntryName,
HighligtedEntryId - TopVisibleEntry, TRUE);
} }
} }
else if(Key.ScanCode == 0x02) else if(Key.ScanCode == 0x02)
@@ -191,12 +224,24 @@ BlDisplayBootMenu()
/* DownArrow key pressed, go to next entry if possible */ /* DownArrow key pressed, go to next entry if possible */
if(HighligtedEntryId < NumberOfEntries - 1) if(HighligtedEntryId < NumberOfEntries - 1)
{ {
/* Highlight next entry */
OldHighligtedEntryId = HighligtedEntryId;
HighligtedEntryId++; HighligtedEntryId++;
if (HighligtedEntryId >= TopVisibleEntry + VisibleEntries)
/* Check if we need to scroll the view */
if(HighligtedEntryId >= TopVisibleEntry + VisibleEntries)
{ {
/* Scroll the view */
TopVisibleEntry = HighligtedEntryId - VisibleEntries + 1; TopVisibleEntry = HighligtedEntryId - VisibleEntries + 1;
RedrawEntries = TRUE;
break;
} }
break;
/* Redraw new highlighted entry and the old one */
BlpDrawBootMenuEntry(&Handle, MenuEntries[OldHighligtedEntryId].EntryName,
OldHighligtedEntryId - TopVisibleEntry, FALSE);
BlpDrawBootMenuEntry(&Handle, MenuEntries[HighligtedEntryId].EntryName,
HighligtedEntryId - TopVisibleEntry, TRUE);
} }
} }
else if(Key.ScanCode == 0x09) else if(Key.ScanCode == 0x09)
@@ -207,6 +252,7 @@ BlDisplayBootMenu()
/* Highlight first entry */ /* Highlight first entry */
HighligtedEntryId = 0; HighligtedEntryId = 0;
TopVisibleEntry = 0; TopVisibleEntry = 0;
RedrawEntries = TRUE;
break; break;
} }
} }
@@ -218,6 +264,7 @@ BlDisplayBootMenu()
/* Highlight last entry */ /* Highlight last entry */
HighligtedEntryId = NumberOfEntries - 1; HighligtedEntryId = NumberOfEntries - 1;
TopVisibleEntry = (NumberOfEntries > VisibleEntries) ? (NumberOfEntries - VisibleEntries) : 0; TopVisibleEntry = (NumberOfEntries > VisibleEntries) ? (NumberOfEntries - VisibleEntries) : 0;
RedrawEntries = TRUE;
break; break;
} }
} }
@@ -241,6 +288,7 @@ BlDisplayBootMenu()
L"Visit https://exectos.eu.org/ for more information."); L"Visit https://exectos.eu.org/ for more information.");
/* Break from boot menu event loop to redraw whole boot menu */ /* Break from boot menu event loop to redraw whole boot menu */
RedrawBootMenu = TRUE;
break; break;
} }
else if(Key.ScanCode == 0x14) else if(Key.ScanCode == 0x14)
@@ -248,6 +296,7 @@ BlDisplayBootMenu()
/* F10 key pressed, reboot into UEFI setup interface */ /* F10 key pressed, reboot into UEFI setup interface */
BlEnterFirmwareSetup(); BlEnterFirmwareSetup();
BlDisplayErrorDialog(L"XTLDR", L"Reboot into firmware setup interface not supported!"); BlDisplayErrorDialog(L"XTLDR", L"Reboot into firmware setup interface not supported!");
RedrawBootMenu = TRUE;
/* Break from boot menu event loop to redraw whole boot menu */ /* Break from boot menu event loop to redraw whole boot menu */
break; break;
@@ -257,6 +306,7 @@ BlDisplayBootMenu()
/* F11 key pressed, reboot the machine */ /* F11 key pressed, reboot the machine */
BlRebootSystem(); BlRebootSystem();
BlDisplayErrorDialog(L"XTLDR", L"Failed to reboot the machine!"); BlDisplayErrorDialog(L"XTLDR", L"Failed to reboot the machine!");
RedrawBootMenu = TRUE;
/* Break from boot menu event loop to redraw whole boot menu */ /* Break from boot menu event loop to redraw whole boot menu */
break; break;
@@ -266,6 +316,7 @@ BlDisplayBootMenu()
/* F12 key pressed, shutdown the machine */ /* F12 key pressed, shutdown the machine */
BlShutdownSystem(); BlShutdownSystem();
BlDisplayErrorDialog(L"XTLDR", L"Failed to shutdown the machine!"); BlDisplayErrorDialog(L"XTLDR", L"Failed to shutdown the machine!");
RedrawBootMenu = TRUE;
/* Break from boot menu event loop to redraw whole boot menu */ /* Break from boot menu event loop to redraw whole boot menu */
break; break;
@@ -273,7 +324,8 @@ BlDisplayBootMenu()
else if(Key.UnicodeChar == 0x65) else if(Key.UnicodeChar == 0x65)
{ {
/* 'e' key pressed, edit the highlighted entry */ /* 'e' key pressed, edit the highlighted entry */
BlDisplayErrorDialog(L"XTLDR", L"Editing boot menu entries is not implemented yet!"); BlDisplayEditMenu(&MenuEntries[HighligtedEntryId]);
RedrawBootMenu = TRUE;
/* Break from boot menu event loop to redraw whole boot menu */ /* Break from boot menu event loop to redraw whole boot menu */
break; break;
@@ -302,7 +354,7 @@ BlDisplayBootMenu()
BlSetConsoleAttributes(Handle.DialogColor | Handle.TextColor); BlSetConsoleAttributes(Handle.DialogColor | Handle.TextColor);
BlClearConsoleLine(Handle.PosY + Handle.Height + 4); BlClearConsoleLine(Handle.PosY + Handle.Height + 4);
BlSetCursorPosition(4, Handle.PosY + Handle.Height + 4); BlSetCursorPosition(4, Handle.PosY + Handle.Height + 4);
BlConsolePrint(L"Booting '%S' now...\n", MenuEntries[HighligtedEntryId].EntryName); BlConsolePrint(L"Booting '%S' now...\n", MenuEntries[HighligtedEntryId].FullName);
/* Disable the timer just in case booting OS fails */ /* Disable the timer just in case booting OS fails */
TimeOut = -1; TimeOut = -1;
@@ -314,8 +366,9 @@ BlDisplayBootMenu()
{ {
/* Failed to boot OS */ /* Failed to boot OS */
BlDebugPrint(L"ERROR: Failed to boot '%S' (Status Code: 0x%zX)\n", BlDebugPrint(L"ERROR: Failed to boot '%S' (Status Code: 0x%zX)\n",
MenuEntries[HighligtedEntryId].EntryName, Status); MenuEntries[HighligtedEntryId].FullName, Status);
BlDisplayErrorDialog(L"XTLDR", L"Failed to startup the selected Operating System."); BlDisplayErrorDialog(L"XTLDR", L"Failed to startup the selected Operating System.");
RedrawBootMenu = TRUE;
} }
break; break;
} }
@@ -324,6 +377,254 @@ BlDisplayBootMenu()
} }
} }
/**
* Displays a simple TUI-based edit menu.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCDECL
VOID
BlDisplayEditMenu(IN PXTBL_BOOTMENU_ITEM MenuEntry)
{
ULONG HighligtedOptionId, Index, NumberOfOptions, OldHighligtedOptionId, TopVisibleEntry, VisibleEntries;
XTBL_DIALOG_HANDLE Handle;
BOOLEAN RedrawEditMenu, RedrawEntries;
EFI_INPUT_KEY Key;
UINT_PTR EventIndex;
PWCHAR NewValue, OptionName, OriginalValue, Value, ValueToEdit;
CONST PWCHAR *EditableOptions;
EFI_STATUS Status;
/* Draw edit menu */
BlpDrawEditMenu(&Handle);
/* Get the list of user editable options */
BlGetEditableOptions(&EditableOptions, &NumberOfOptions);
/* Calculate how many entries can be visible in the menu box */
VisibleEntries = Handle.Height - 2;
/* Assume the first option is highlighted by default */
HighligtedOptionId = 0;
OldHighligtedOptionId = 0;
TopVisibleEntry = 0;
/* Set redraw flags to not redraw the menu itself, but fill it with entries */
RedrawEditMenu = FALSE;
RedrawEntries = TRUE;
/* Infinite edit menu loop */
while(TRUE)
{
/* Redraw edit menu frame if requested */
if(RedrawEditMenu)
{
BlpDrawEditMenu(&Handle);
RedrawEditMenu = FALSE;
RedrawEntries = TRUE;
}
/* Sanity check to ensure we do not display more entries than possible */
if(VisibleEntries > NumberOfOptions)
{
VisibleEntries = NumberOfOptions;
}
/* Check if we need to redraw boot menu entries */
if(RedrawEntries)
{
/* Iterate through all menu entries */
for(Index = 0; Index < VisibleEntries; Index++)
{
/* Draw menu entry */
BlGetBootOptionValue(MenuEntry->Options, EditableOptions[TopVisibleEntry + Index], &Value);
BlpDrawEditMenuEntry(&Handle, EditableOptions[TopVisibleEntry + Index], Value, Index,
(TopVisibleEntry + Index) == HighligtedOptionId);
/* Free allocated value string if needed */
if(Value != NULL)
{
BlFreeMemoryPool(Value);
}
}
/* Clear redraw entries flag */
RedrawEntries = FALSE;
}
/* Wait for EFI event and read key stroke */
BlWaitForEfiEvent(1, &EfiSystemTable->ConIn->WaitForKey, &EventIndex);
BlReadKeyStroke(&Key);
/* Check key press scan code */
if(Key.UnicodeChar == 0x0D || Key.UnicodeChar == 0x65)
{
/* ENTER or 'e' key pressed, edit the highlighted option */
OptionName = EditableOptions[HighligtedOptionId];
BlGetBootOptionValue(MenuEntry->Options, OptionName, &OriginalValue);
/* If the original value is NULL, use an empty string for editing */
if(OriginalValue == NULL)
{
ValueToEdit = L"";
}
else
{
ValueToEdit = OriginalValue;
}
/* Display input dialog to edit the option value */
NewValue = ValueToEdit;
BlDisplayInputDialog(OptionName, L"Enter new value:", &NewValue);
/* Check if the value was changed */
if(NewValue != ValueToEdit)
{
/* Update the boot option with the new value and free the old value */
BlSetBootOptionValue(MenuEntry->Options, OptionName, NewValue);
BlFreeMemoryPool(NewValue);
}
/* Free the original value if it was allocated */
if(OriginalValue != NULL)
{
BlFreeMemoryPool(OriginalValue);
}
/* Mark the edit menu for redraw */
RedrawEditMenu = TRUE;
}
else if(Key.ScanCode == 0x01)
{
/* UpArrow key pressed, go to previous entry if possible */
if(HighligtedOptionId > 0)
{
/* Highlight previous entry */
OldHighligtedOptionId = HighligtedOptionId;
HighligtedOptionId--;
/* Check if we need to scroll the view */
if(HighligtedOptionId < TopVisibleEntry)
{
/* Scroll the view */
TopVisibleEntry = HighligtedOptionId;
RedrawEntries = TRUE;
continue;
}
/* Redraw old highlighted entry */
BlGetBootOptionValue(MenuEntry->Options, EditableOptions[OldHighligtedOptionId], &Value);
BlpDrawEditMenuEntry(&Handle, EditableOptions[OldHighligtedOptionId], Value, OldHighligtedOptionId - TopVisibleEntry, FALSE);
/* Free allocated value string if needed */
if(Value != NULL)
{
BlFreeMemoryPool(Value);
}
/* Redraw new highlighted entry */
BlGetBootOptionValue(MenuEntry->Options, EditableOptions[HighligtedOptionId], &Value);
BlpDrawEditMenuEntry(&Handle, EditableOptions[HighligtedOptionId], Value, HighligtedOptionId - TopVisibleEntry, TRUE);
/* Free allocated value string if needed */
if(Value != NULL)
{
BlFreeMemoryPool(Value);
}
}
}
else if(Key.ScanCode == 0x02)
{
/* DownArrow key pressed, go to next entry if possible */
if(HighligtedOptionId < NumberOfOptions - 1)
{
/* Highlight next entry */
OldHighligtedOptionId = HighligtedOptionId;
HighligtedOptionId++;
/* Check if we need to scroll the view */
if(HighligtedOptionId >= TopVisibleEntry + VisibleEntries)
{
/* Scroll the view */
TopVisibleEntry = HighligtedOptionId - VisibleEntries + 1;
RedrawEntries = TRUE;
continue;
}
/* Redraw old highlighted entry */
BlGetBootOptionValue(MenuEntry->Options, EditableOptions[OldHighligtedOptionId], &Value);
BlpDrawEditMenuEntry(&Handle, EditableOptions[OldHighligtedOptionId], Value, OldHighligtedOptionId - TopVisibleEntry, FALSE);
/* Free allocated value string if needed */
if(Value != NULL)
{
BlFreeMemoryPool(Value);
}
/* Redraw new highlighted entry */
BlGetBootOptionValue(MenuEntry->Options, EditableOptions[HighligtedOptionId], &Value);
BlpDrawEditMenuEntry(&Handle, EditableOptions[HighligtedOptionId], Value, HighligtedOptionId - TopVisibleEntry, TRUE);
/* Free allocated value string if needed */
if(Value != NULL)
{
BlFreeMemoryPool(Value);
}
}
}
else if(Key.ScanCode == 0x09)
{
/* PageUp key pressed, go to top entry */
if(HighligtedOptionId != 0)
{
/* Highlight first entry */
HighligtedOptionId = 0;
TopVisibleEntry = 0;
RedrawEntries = TRUE;
}
}
else if(Key.ScanCode == 0x0A)
{
/* PageDown key pressed, go to bottom entry */
if(HighligtedOptionId != NumberOfOptions - 1)
{
/* Highlight last entry */
HighligtedOptionId = NumberOfOptions - 1;
TopVisibleEntry = (NumberOfOptions > VisibleEntries) ? (NumberOfOptions - VisibleEntries) : 0;
RedrawEntries = TRUE;
}
}
else if(Key.UnicodeChar == 0x02)
{
/* CTRL-B key pressed, boot the OS */
BlSetConsoleAttributes(Handle.DialogColor | Handle.TextColor);
BlClearConsoleLine(Handle.PosY + Handle.Height + 4);
BlSetCursorPosition(4, Handle.PosY + Handle.Height + 4);
BlConsolePrint(L"Booting '%S' now...\n", MenuEntry->FullName);
/* Boot the OS */
Status = BlInvokeBootProtocol(MenuEntry->ShortName, MenuEntry->Options);
if(Status != STATUS_SUCCESS)
{
/* Failed to boot OS */
BlDebugPrint(L"ERROR: Failed to boot '%S' (Status Code: 0x%zX)\n", MenuEntry->FullName, Status);
BlDisplayErrorDialog(L"XTLDR", L"Failed to startup the selected Operating System.");
RedrawEditMenu = TRUE;
}
/* Return to the edit menu */
continue;
}
else if(Key.ScanCode == 0x17)
{
/* ESC key pressed, exit edit menu */
break;
}
}
}
/** /**
* Displays a red error dialog box with the specified caption and message. * Displays a red error dialog box with the specified caption and message.
* *
@@ -450,12 +751,11 @@ XTCDECL
VOID VOID
BlDisplayInputDialog(IN PWCHAR Caption, BlDisplayInputDialog(IN PWCHAR Caption,
IN PWCHAR Message, IN PWCHAR Message,
IN PWCHAR *InputFieldText) IN OUT PWCHAR *InputFieldText)
{ {
SIZE_T InputFieldLength, TextCursorPosition, TextIndex, TextPosition; SIZE_T InputFieldLength, TextCursorPosition, TextIndex, TextPosition;
XTBL_DIALOG_HANDLE Handle; XTBL_DIALOG_HANDLE Handle;
PWCHAR InputFieldBuffer; PWCHAR InputFieldBuffer;
SIZE_T BufferLength;
EFI_INPUT_KEY Key; EFI_INPUT_KEY Key;
EFI_STATUS Status; EFI_STATUS Status;
UINT_PTR Index; UINT_PTR Index;
@@ -480,9 +780,11 @@ BlDisplayInputDialog(IN PWCHAR Caption,
Key.ScanCode = 0; Key.ScanCode = 0;
Key.UnicodeChar = 0; Key.UnicodeChar = 0;
/* Get initial input text length and allocate a buffer */ /* Determine input field length */
BufferLength = RtlWideStringLength(*InputFieldText, 0); InputFieldLength = RtlWideStringLength(*InputFieldText, 0);
Status = BlAllocateMemoryPool(BufferLength * sizeof(WCHAR), (PVOID *)&InputFieldBuffer);
/* Allocate a buffer for storing the input field text */
Status = BlAllocateMemoryPool(2048 * sizeof(WCHAR), (PVOID *)&InputFieldBuffer);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Memory allocation failure, print error message and return */ /* Memory allocation failure, print error message and return */
@@ -492,15 +794,8 @@ BlDisplayInputDialog(IN PWCHAR Caption,
} }
/* Copy input text into edit buffer */ /* Copy input text into edit buffer */
RtlCopyMemory(InputFieldBuffer, *InputFieldText, BufferLength * sizeof(WCHAR)); RtlCopyMemory(InputFieldBuffer, *InputFieldText, InputFieldLength * sizeof(WCHAR));
InputFieldBuffer[BufferLength] = L'\0'; InputFieldBuffer[InputFieldLength] = L'\0';
/* Determine input field length */
InputFieldLength = BufferLength;
if(InputFieldLength > Handle.Width - 8)
{
InputFieldLength = Handle.Width - 8;
}
/* Start at first character */ /* Start at first character */
TextPosition = 0; TextPosition = 0;
@@ -512,7 +807,6 @@ BlDisplayInputDialog(IN PWCHAR Caption,
/* Wait for key press and read key stroke */ /* Wait for key press and read key stroke */
BlWaitForEfiEvent(1, &EfiSystemTable->ConIn->WaitForKey, &Index); BlWaitForEfiEvent(1, &EfiSystemTable->ConIn->WaitForKey, &Index);
BlReadKeyStroke(&Key); BlReadKeyStroke(&Key);
BlResetConsoleInputBuffer();
/* Check key press scan code */ /* Check key press scan code */
if(Key.ScanCode == 0x17) if(Key.ScanCode == 0x17)
@@ -563,12 +857,16 @@ BlDisplayInputDialog(IN PWCHAR Caption,
/* DELETE key pressed, delete character */ /* DELETE key pressed, delete character */
if(Handle.Attributes & XTBL_TUI_DIALOG_ACTIVE_INPUT) if(Handle.Attributes & XTBL_TUI_DIALOG_ACTIVE_INPUT)
{ {
/* Check if buffer is not empty */
if(InputFieldLength > 0 && TextPosition < InputFieldLength) if(InputFieldLength > 0 && TextPosition < InputFieldLength)
{ {
/* Delete character */
RtlMoveMemory(InputFieldBuffer + TextPosition, InputFieldBuffer + TextPosition + 1, RtlMoveMemory(InputFieldBuffer + TextPosition, InputFieldBuffer + TextPosition + 1,
(InputFieldLength - TextPosition) * sizeof(WCHAR)); (InputFieldLength - TextPosition) * sizeof(WCHAR));
/* Decrement length and null terminate string */
InputFieldLength--; InputFieldLength--;
InputFieldBuffer[InputFieldLength] = 0; InputFieldBuffer[InputFieldLength] = L'\0';
} }
} }
} }
@@ -577,13 +875,17 @@ BlDisplayInputDialog(IN PWCHAR Caption,
/* BACKSPACE key pressed, delete character */ /* BACKSPACE key pressed, delete character */
if(Handle.Attributes & XTBL_TUI_DIALOG_ACTIVE_INPUT) if(Handle.Attributes & XTBL_TUI_DIALOG_ACTIVE_INPUT)
{ {
/* Check if buffer is not empty */
if(InputFieldLength > 0 && TextPosition > 0 && TextPosition <= InputFieldLength) if(InputFieldLength > 0 && TextPosition > 0 && TextPosition <= InputFieldLength)
{ {
/* Move memory to overwrite the character to the left of the cursor */
RtlMoveMemory(InputFieldBuffer + TextPosition - 1, InputFieldBuffer + TextPosition,
(InputFieldLength - TextPosition + 1) * sizeof(WCHAR));
/* Decrement length, position and null terminate string */
TextPosition--; TextPosition--;
RtlMoveMemory(InputFieldBuffer + TextPosition, InputFieldBuffer + TextPosition + 1,
(InputFieldLength - TextPosition) * sizeof(WCHAR));
InputFieldLength--; InputFieldLength--;
InputFieldBuffer[InputFieldLength] = 0; InputFieldBuffer[InputFieldLength] = L'\0';
} }
} }
} }
@@ -598,15 +900,23 @@ BlDisplayInputDialog(IN PWCHAR Caption,
/* Other key pressed, add character to the buffer */ /* Other key pressed, add character to the buffer */
if(Handle.Attributes & XTBL_TUI_DIALOG_ACTIVE_INPUT && Key.UnicodeChar != 0) if(Handle.Attributes & XTBL_TUI_DIALOG_ACTIVE_INPUT && Key.UnicodeChar != 0)
{ {
RtlMoveMemory(InputFieldBuffer + TextPosition + 1, InputFieldBuffer + TextPosition, /* Check if buffer is full */
(InputFieldLength - TextPosition) * sizeof(WCHAR)); if(InputFieldLength < 2047)
InputFieldBuffer[TextPosition] = Key.UnicodeChar; {
TextPosition++; /* Insert character at current position */
InputFieldLength++; RtlMoveMemory(InputFieldBuffer + TextPosition + 1, InputFieldBuffer + TextPosition,
InputFieldBuffer[InputFieldLength] = 0; (InputFieldLength - TextPosition) * sizeof(WCHAR));
InputFieldBuffer[TextPosition] = Key.UnicodeChar;
/* Increment length, position and null terminate string */
TextPosition++;
InputFieldLength++;
InputFieldBuffer[InputFieldLength] = L'\0';
}
} }
} }
/* Calculate text index and cursor position */
if(TextPosition > (Handle.Width - 9)) if(TextPosition > (Handle.Width - 9))
{ {
TextIndex = TextPosition - (Handle.Width - 9); TextIndex = TextPosition - (Handle.Width - 9);
@@ -622,6 +932,7 @@ BlDisplayInputDialog(IN PWCHAR Caption,
BlpDrawDialogButton(&Handle); BlpDrawDialogButton(&Handle);
BlpDrawDialogInputField(&Handle, &InputFieldBuffer[TextIndex]); BlpDrawDialogInputField(&Handle, &InputFieldBuffer[TextIndex]);
/* Set cursor position if input field is active */
if(Handle.Attributes & XTBL_TUI_DIALOG_ACTIVE_INPUT) if(Handle.Attributes & XTBL_TUI_DIALOG_ACTIVE_INPUT)
{ {
BlSetCursorPosition(Handle.PosX + 4 + TextCursorPosition, Handle.PosY + Handle.Height - 4); BlSetCursorPosition(Handle.PosX + 4 + TextCursorPosition, Handle.PosY + Handle.Height - 4);
@@ -1340,3 +1651,164 @@ BlpDrawDialogProgressBar(IN PXTBL_DIALOG_HANDLE Handle,
BlDisableConsoleCursor(); BlDisableConsoleCursor();
BlConsoleWrite(ProgressBar); BlConsoleWrite(ProgressBar);
} }
/**
* Draws a text-based boot edition menu.
*
* @param Handle
* Supplies a pointer to the edition menu handle.
*
* @return This function does not return any value.
*
* @since XT 1.0
*/
XTCDECL
VOID
BlpDrawEditMenu(OUT PXTBL_DIALOG_HANDLE Handle)
{
/* Query console screen resolution */
BlQueryConsoleMode(&Handle->ResX, &Handle->ResY);
/* Set boot menu parameters */
Handle->Attributes = 0;
Handle->DialogColor = EFI_TEXT_BGCOLOR_BLACK;
Handle->TextColor = EFI_TEXT_FGCOLOR_LIGHTGRAY;
Handle->PosX = 3;
Handle->PosY = 3;
Handle->Width = Handle->ResX - 6;
Handle->Height = Handle->ResY - 10;
/* Clear screen and disable cursor */
BlSetConsoleAttributes(Handle->DialogColor | Handle->TextColor);
BlClearConsoleScreen();
BlDisableConsoleCursor();
/* Check if debugging enabled */
if(DEBUG)
{
/* Print debug version of XTLDR banner */
BlSetCursorPosition((Handle->ResX - 44) / 2, 1);
BlConsolePrint(L"XTLDR Boot Loader v%d.%d (%s-%s)\n",
XTLDR_VERSION_MAJOR, XTLDR_VERSION_MINOR, XTOS_VERSION_DATE, XTOS_VERSION_HASH);
}
else
{
/* Print standard XTLDR banner */
BlSetCursorPosition((Handle->ResX - 22) / 2, 1);
BlConsolePrint(L"XTLDR Boot Loader v%d.%d\n", XTLDR_VERSION_MAJOR, XTLDR_VERSION_MINOR);
}
/* Draw empty dialog box for boot menu */
BlpDrawDialogBox(Handle, L"Edit Options", NULL);
/* Print help message below the edit menu */
BlSetCursorPosition(0, Handle->PosY + Handle->Height);
BlSetConsoleAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_LIGHTGRAY);
BlConsolePrint(L" Use cursors to change the selection. Press ENTER key to edit the chosen\n"
L" option, ESC to return to the main boot menu or CTRL-B to boot.\n");
}
/**
* Draws edit menu entry at the specified position.
*
* @param Handle
* Supplies a pointer to the boot menu handle.
*
* @param OptionName
* Supplies a pointer to the buffer containing a part of the menu entry name (an option name).
*
* @param OptionValue
* Supplies a pointer to the buffer containing a part of the menu entry name (an option value).
*
* @param Position
* Specifies entry position on the list in the boot menu.
*
* @param Highlighted
* Specifies whether this entry should be highlighted or not.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCDECL
EFI_STATUS
BlpDrawEditMenuEntry(IN PXTBL_DIALOG_HANDLE Handle,
IN PWCHAR OptionName,
IN PWCHAR OptionValue,
IN UINT Position,
IN BOOLEAN Highlighted)
{
BOOLEAN Allocation;
PWCHAR DisplayValue, ShortValue;
UINT Index;
ULONG OptionNameLength, OptionValueLength, OptionWidth;
EFI_STATUS Status;
/* Assume no allocation was made */
Allocation = FALSE;
/* Set display value depending on input */
DisplayValue = (OptionValue != NULL) ? OptionValue : L"";
/* Determine lengths */
OptionNameLength = RtlWideStringLength(OptionName, 0);
OptionValueLength = RtlWideStringLength(DisplayValue, 0);
OptionWidth = Handle->Width - 4 - (OptionNameLength + 2);
/* Check if value needs to be truncated */
if(OptionValueLength > OptionWidth)
{
/* Allocate buffer for new, shortened value */
Status = BlAllocateMemoryPool((OptionWidth + 1) * sizeof(WCHAR), (PVOID *)&ShortValue);
if(Status != STATUS_EFI_SUCCESS)
{
/* Memory allocation failure, print debug message and return */
BlDebugPrint(L"ERROR: Memory allocation failure (Status Code: 0x%zX)\n", Status);
return Status;
}
/* Copy a desired value length into the allocated buffer and append "..." */
RtlCopyMemory(ShortValue, DisplayValue, (OptionWidth - 3) * sizeof(WCHAR));
RtlCopyMemory(ShortValue + OptionWidth - 3, L"...", 3 * sizeof(WCHAR));
ShortValue[OptionWidth] = L'\0';
/* Mark that allocation was made and set new display value */
Allocation = TRUE;
DisplayValue = ShortValue;
}
/* Move cursor to the right position */
BlSetCursorPosition(5, 4 + Position);
/* Check whether this entry should be highlighted */
if(Highlighted)
{
/* Highlight this entry */
BlSetConsoleAttributes(EFI_TEXT_BGCOLOR_LIGHTGRAY | EFI_TEXT_FGCOLOR_BLACK);
}
else
{
/* Set default colors */
BlSetConsoleAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_LIGHTGRAY);
}
/* Clear menu entry */
for(Index = 0; Index < Handle->Width - 4; Index++)
{
BlConsolePrint(L" ");
}
/* Print menu entry */
BlSetCursorPosition(5, 4 + Position);
BlConsolePrint(L"%S: %S", OptionName, DisplayValue);
/* Check if allocation was made */
if(Allocation)
{
/* Free allocated memory */
BlFreeMemoryPool(DisplayValue);
}
/* Return success */
return STATUS_EFI_SUCCESS;
}

View File

@@ -48,7 +48,11 @@ XTCDECL
EFI_STATUS EFI_STATUS
BlEnumerateBlockDevices() BlEnumerateBlockDevices()
{ {
PEFI_DEVICE_PATH_PROTOCOL LastNode = NULL; EFI_GUID LoadedImageProtocolGuid = EFI_LOADED_IMAGE_PROTOCOL_GUID;
EFI_GUID BlockIoGuid = EFI_BLOCK_IO_PROTOCOL_GUID;
EFI_HANDLE BootDeviceHandle = NULL, DeviceHandle = NULL;
EFI_LOADED_IMAGE_PROTOCOL* LoadedImage;
PEFI_DEVICE_PATH_PROTOCOL DevicePath = NULL, LastNode = NULL;
PEFI_BLOCK_DEVICE_DATA ParentNode = NULL; PEFI_BLOCK_DEVICE_DATA ParentNode = NULL;
PEFI_BLOCK_DEVICE_DATA BlockDeviceData; PEFI_BLOCK_DEVICE_DATA BlockDeviceData;
PEFI_BLOCK_DEVICE BlockDevice; PEFI_BLOCK_DEVICE BlockDevice;
@@ -63,6 +67,18 @@ BlEnumerateBlockDevices()
USHORT DriveType; USHORT DriveType;
ULONG CDCount = 0, FDCount = 0, HDCount = 0, RDCount = 0; ULONG CDCount = 0, FDCount = 0, HDCount = 0, RDCount = 0;
/* Get the device handle of the image that is running */
Status = EfiSystemTable->BootServices->HandleProtocol(EfiImageHandle, &LoadedImageProtocolGuid, (VOID**)&LoadedImage);
if(Status != STATUS_EFI_SUCCESS)
{
/* Failed to get boot device handle */
BlDebugPrint(L"ERROR: Failed to get boot device handle (Status Code: 0x%zX)\n", Status);
return Status;
}
/* Save the boot device handle */
BootDeviceHandle = LoadedImage->DeviceHandle;
/* Initialize list entries */ /* Initialize list entries */
RtlInitializeListHead(&BlockDevices); RtlInitializeListHead(&BlockDevices);
RtlInitializeListHead(&EfiBlockDevices); RtlInitializeListHead(&EfiBlockDevices);
@@ -81,6 +97,7 @@ BlEnumerateBlockDevices()
{ {
/* Get data for the next discovered device. */ /* Get data for the next discovered device. */
BlockDeviceData = CONTAIN_RECORD(ListEntry, EFI_BLOCK_DEVICE_DATA, ListEntry); BlockDeviceData = CONTAIN_RECORD(ListEntry, EFI_BLOCK_DEVICE_DATA, ListEntry);
PartitionGuid = NULL;
/* Find last node */ /* Find last node */
Status = BlpFindLastBlockDeviceNode(BlockDeviceData->DevicePath, &LastNode); Status = BlpFindLastBlockDeviceNode(BlockDeviceData->DevicePath, &LastNode);
@@ -154,11 +171,30 @@ BlEnumerateBlockDevices()
PartitionNumber = HDPath->PartitionNumber; PartitionNumber = HDPath->PartitionNumber;
PartitionGuid = (PEFI_GUID)HDPath->Signature; PartitionGuid = (PEFI_GUID)HDPath->Signature;
/* Check if this is the EFI System Partition (ESP) */
if(BootDeviceHandle != NULL)
{
/* Allocate memory for device path */
DevicePath = BlpDuplicateDevicePath(BlockDeviceData->DevicePath);
if(DevicePath != NULL)
{
/* Check if this is the boot device */
Status = EfiSystemTable->BootServices->LocateDevicePath(&BlockIoGuid, &DevicePath,
&DeviceHandle);
if(Status == STATUS_EFI_SUCCESS && DeviceHandle == BootDeviceHandle)
{
/* Mark partition as ESP */
DriveType |= XTBL_BOOT_DEVICE_ESP;
}
}
}
/* Print debug message */ /* Print debug message */
BlDebugPrint(L"Found Hard Disk partition (DiskNumber: %lu, PartNumber: %lu, " BlDebugPrint(L"Found Hard Disk partition (DiskNumber: %lu, PartNumber: %lu, "
L"MBRType: %u, GUID: {%V}, PartSize: %uB)\n", L"MBRType: %u, GUID: {%V}, PartSize: %lluB) %S\n",
DriveNumber, PartitionNumber, HDPath->MBRType, DriveNumber, PartitionNumber, HDPath->MBRType,
PartitionGuid, HDPath->PartitionSize * Media->BlockSize); PartitionGuid, HDPath->PartitionSize * Media->BlockSize,
(DriveType & XTBL_BOOT_DEVICE_ESP) ? L"(ESP)" : L"");
} }
else if(LastNode->Type == EFI_MEDIA_DEVICE_PATH && LastNode->SubType == EFI_MEDIA_RAMDISK_DP) else if(LastNode->Type == EFI_MEDIA_DEVICE_PATH && LastNode->SubType == EFI_MEDIA_RAMDISK_DP)
{ {
@@ -428,12 +464,26 @@ BlGetVolumeDevicePath(IN PWCHAR SystemPath,
{ {
/* Check if this is the volume we are looking for */ /* Check if this is the volume we are looking for */
Device = CONTAIN_RECORD(ListEntry, EFI_BLOCK_DEVICE, ListEntry); Device = CONTAIN_RECORD(ListEntry, EFI_BLOCK_DEVICE, ListEntry);
if((Device->DriveType == DriveType && Device->DriveNumber == DriveNumber && if(DriveType == XTBL_BOOT_DEVICE_ESP)
Device->PartitionNumber == PartNumber))
{ {
/* Found volume */ /* ESP requested, verify if flag is set for this device */
*DevicePath = Device->DevicePath; if((Device->DriveType & XTBL_BOOT_DEVICE_ESP) != 0)
break; {
/* Found volume */
*DevicePath = Device->DevicePath;
break;
}
}
else
{
if(((Device->DriveType & DriveType) == DriveType) &&
(Device->DriveNumber == DriveNumber) &&
(Device->PartitionNumber == PartNumber))
{
/* Found volume */
*DevicePath = Device->DevicePath;
break;
}
} }
ListEntry = ListEntry->Flink; ListEntry = ListEntry->Flink;
} }
@@ -441,9 +491,9 @@ BlGetVolumeDevicePath(IN PWCHAR SystemPath,
/* Check if volume was found */ /* Check if volume was found */
if(*DevicePath == NULL) if(*DevicePath == NULL)
{ {
/* Failed to find volume */ /* Volume not found */
BlDebugPrint(L"ERROR: Volume (DriveType: %u, DriveNumber: %lu, PartNumber: %lu) not found\n", BlDebugPrint(L"ERROR: Volume (DriveType: %u, DriveNumber: %lu, PartNumber: %lu) not found\n",
DriveType, DriveNumber, PartNumber); DriveType, DriveNumber, PartNumber);
return STATUS_EFI_NOT_FOUND; return STATUS_EFI_NOT_FOUND;
} }
@@ -616,7 +666,7 @@ BlReadFile(IN PEFI_FILE_HANDLE DirHandle,
Pages = EFI_SIZE_TO_PAGES(FileInfo->FileSize); Pages = EFI_SIZE_TO_PAGES(FileInfo->FileSize);
/* Allocate pages */ /* Allocate pages */
Status = BlAllocateMemoryPages(Pages, &Address); Status = BlAllocateMemoryPages(AllocateAnyPages, Pages, &Address);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Pages allocation failure */ /* Pages allocation failure */
@@ -786,6 +836,12 @@ BlpDissectVolumeArcPath(IN PWCHAR SystemPath,
ArcLength = 10; ArcLength = 10;
*DriveType = XTBL_BOOT_DEVICE_RAMDISK; *DriveType = XTBL_BOOT_DEVICE_RAMDISK;
} }
else if(RtlCompareWideStringInsensitive(SystemPath, L"multi(0)esp(0)", 0) == 0)
{
/* This is ESP */
ArcLength = 14;
*DriveType = XTBL_BOOT_DEVICE_ESP;
}
else if(RtlCompareWideStringInsensitive(SystemPath, L"multi(0)disk(0)", 0) == 0) else if(RtlCompareWideStringInsensitive(SystemPath, L"multi(0)disk(0)", 0) == 0)
{ {
/* This is a multi-disk port */ /* This is a multi-disk port */
@@ -1047,6 +1103,14 @@ BlpFindParentBlockDevice(IN PLIST_ENTRY BlockDevices,
/* Take block device from the list */ /* Take block device from the list */
BlockDeviceData = CONTAIN_RECORD(ListEntry, EFI_BLOCK_DEVICE_DATA, ListEntry); BlockDeviceData = CONTAIN_RECORD(ListEntry, EFI_BLOCK_DEVICE_DATA, ListEntry);
/* A device cannot be its own parent */
if (BlockDeviceData == ChildNode)
{
/* Move to the next device */
ListEntry = ListEntry->Flink;
continue;
}
ChildDevicePath = ChildNode->DevicePath; ChildDevicePath = ChildNode->DevicePath;
ParentDevicePath = BlockDeviceData->DevicePath; ParentDevicePath = BlockDeviceData->DevicePath;
@@ -1065,10 +1129,11 @@ BlpFindParentBlockDevice(IN PLIST_ENTRY BlockDevices,
ChildLength = *(PUSHORT)ChildDevicePath->Length; ChildLength = *(PUSHORT)ChildDevicePath->Length;
ParentLength = *(PUSHORT)ParentDevicePath->Length; ParentLength = *(PUSHORT)ParentDevicePath->Length;
/* Check if lengths match */ /* Check if nodes match */
if(ChildLength != ParentLength) if((ChildLength != ParentLength) ||
(RtlCompareMemory(ChildDevicePath, ParentDevicePath, ParentLength) != ParentLength))
{ {
/* Lengths do not match, this is not a valid parent */ /* Nodes do not match, this is not a valid parent */
break; break;
} }

View File

@@ -90,16 +90,17 @@ BlInitializeBootLoader()
*/ */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
BlInitializeBootMenuList(OUT PXTBL_BOOTMENU_ITEM *MenuEntries, BlInitializeBootMenuList(IN ULONG MaxNameLength,
OUT PXTBL_BOOTMENU_ITEM *MenuEntries,
OUT PULONG EntriesCount, OUT PULONG EntriesCount,
OUT PULONG DefaultId) OUT PULONG DefaultId)
{ {
EFI_GUID VendorGuid = XT_BOOT_LOADER_PROTOCOL_GUID; EFI_GUID VendorGuid = XT_BOOT_LOADER_PROTOCOL_GUID;
PWCHAR DefaultMenuEntry, LastBooted, MenuEntryName; PWCHAR DefaultMenuEntry, LastBooted, MenuEntryName, VisibleName;
PLIST_ENTRY MenuEntrySectionList, MenuEntryList; PLIST_ENTRY MenuEntrySectionList, MenuEntryList;
PXTBL_CONFIG_SECTION MenuEntrySection; PXTBL_CONFIG_SECTION MenuEntrySection;
PXTBL_CONFIG_ENTRY MenuEntryOption; PXTBL_CONFIG_ENTRY MenuEntryOption;
ULONG DefaultOS, NumberOfEntries; ULONG DefaultOS, NameLength,NumberOfEntries;
PXTBL_BOOTMENU_ITEM OsList; PXTBL_BOOTMENU_ITEM OsList;
EFI_STATUS Status; EFI_STATUS Status;
@@ -108,7 +109,7 @@ BlInitializeBootMenuList(OUT PXTBL_BOOTMENU_ITEM *MenuEntries,
NumberOfEntries = 0; NumberOfEntries = 0;
/* Get default menu entry from configuration */ /* Get default menu entry from configuration */
DefaultMenuEntry = BlGetConfigValue(L"DEFAULT"); BlGetConfigValue(L"DEFAULT", &DefaultMenuEntry);
/* Check if configuration allows to use last booted OS */ /* Check if configuration allows to use last booted OS */
if(BlGetConfigBooleanValue(L"KEEPLASTBOOT")) if(BlGetConfigBooleanValue(L"KEEPLASTBOOT"))
@@ -177,10 +178,36 @@ BlInitializeBootMenuList(OUT PXTBL_BOOTMENU_ITEM *MenuEntries,
} }
/* Add OS to the boot menu list */ /* Add OS to the boot menu list */
OsList[NumberOfEntries].EntryName = MenuEntryName; OsList[NumberOfEntries].FullName = MenuEntryName;
OsList[NumberOfEntries].ShortName = MenuEntrySection->SectionName; OsList[NumberOfEntries].ShortName = MenuEntrySection->SectionName;
OsList[NumberOfEntries].Options = &MenuEntrySection->Options; OsList[NumberOfEntries].Options = &MenuEntrySection->Options;
/* Check if the menu entry name fits the maximum length */
NameLength = RtlWideStringLength(MenuEntryName, 0);
if(NameLength > MaxNameLength)
{
/* Menu entry name is too long, allocate memory for shorter name visible in the boot menu */
Status = BlAllocateMemoryPool((MaxNameLength + 1) * sizeof(WCHAR), (PVOID*)&VisibleName);
if(Status != STATUS_EFI_SUCCESS)
{
/* Memory allocation failure */
return STATUS_EFI_OUT_OF_RESOURCES;
}
/* Copy shorter name and append "..." at the end */
RtlCopyMemory(VisibleName, MenuEntryName, (MaxNameLength - 3) * sizeof(WCHAR));
RtlCopyMemory(VisibleName + MaxNameLength - 3, L"...", 3 * sizeof(WCHAR));
VisibleName[MaxNameLength] = L'\0';
/* Set visible menu entry name */
OsList[NumberOfEntries].EntryName = VisibleName;
}
else
{
/* Menu entry name fits the maximum length, use it as is */
OsList[NumberOfEntries].EntryName = MenuEntryName;
}
/* Get next menu entry */ /* Get next menu entry */
MenuEntrySectionList = MenuEntrySectionList->Flink; MenuEntrySectionList = MenuEntrySectionList->Flink;
NumberOfEntries++; NumberOfEntries++;
@@ -364,6 +391,7 @@ EFI_STATUS
BlStartXtLoader(IN EFI_HANDLE ImageHandle, BlStartXtLoader(IN EFI_HANDLE ImageHandle,
IN PEFI_SYSTEM_TABLE SystemTable) IN PEFI_SYSTEM_TABLE SystemTable)
{ {
PWCHAR Modules;
EFI_STATUS Status; EFI_STATUS Status;
/* Set the system table and image handle */ /* Set the system table and image handle */
@@ -428,8 +456,9 @@ BlStartXtLoader(IN EFI_HANDLE ImageHandle,
return Status; return Status;
} }
/* Load boot loader modules */ /* Load all necessary modules */
Status = BlLoadModules(BlGetConfigValue(L"MODULES")); BlGetConfigValue(L"MODULES", &Modules);
Status = BlLoadModules(Modules);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Failed to load modules */ /* Failed to load modules */

View File

@@ -9,7 +9,8 @@ include_directories(
# Specify list of library source code files # Specify list of library source code files
list(APPEND LIBXTOS_SOURCE list(APPEND LIBXTOS_SOURCE
${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/cpufunc.c ${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/boot.S
${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/cpufunc.cc
${XTOSKRNL_SOURCE_DIR}/hl/cport.c ${XTOSKRNL_SOURCE_DIR}/hl/cport.c
${XTOSKRNL_SOURCE_DIR}/hl/${ARCH}/ioport.c ${XTOSKRNL_SOURCE_DIR}/hl/${ARCH}/ioport.c
${XTOSKRNL_SOURCE_DIR}/rtl/globals.c ${XTOSKRNL_SOURCE_DIR}/rtl/globals.c
@@ -23,11 +24,13 @@ list(APPEND LIBXTOS_SOURCE
# Specify list of kernel source code files # Specify list of kernel source code files
list(APPEND XTOSKRNL_SOURCE list(APPEND XTOSKRNL_SOURCE
${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/archsup.S ${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/archsup.S
${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/cpufunc.c ${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/boot.S
${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/globals.c ${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/cpufunc.cc
${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/procsup.c ${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/data.cc
${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/traps.c ${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/procsup.cc
${XTOSKRNL_SOURCE_DIR}/ex/rundown.c ${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/traps.cc
${XTOSKRNL_SOURCE_DIR}/ex/exports.cc
${XTOSKRNL_SOURCE_DIR}/ex/rundown.cc
${XTOSKRNL_SOURCE_DIR}/hl/acpi.c ${XTOSKRNL_SOURCE_DIR}/hl/acpi.c
${XTOSKRNL_SOURCE_DIR}/hl/cport.c ${XTOSKRNL_SOURCE_DIR}/hl/cport.c
${XTOSKRNL_SOURCE_DIR}/hl/fbdev.c ${XTOSKRNL_SOURCE_DIR}/hl/fbdev.c
@@ -37,10 +40,14 @@ list(APPEND XTOSKRNL_SOURCE
${XTOSKRNL_SOURCE_DIR}/hl/${ARCH}/pic.c ${XTOSKRNL_SOURCE_DIR}/hl/${ARCH}/pic.c
${XTOSKRNL_SOURCE_DIR}/hl/${ARCH}/ioport.c ${XTOSKRNL_SOURCE_DIR}/hl/${ARCH}/ioport.c
${XTOSKRNL_SOURCE_DIR}/hl/${ARCH}/runlevel.c ${XTOSKRNL_SOURCE_DIR}/hl/${ARCH}/runlevel.c
${XTOSKRNL_SOURCE_DIR}/kd/dbginit.c
${XTOSKRNL_SOURCE_DIR}/kd/dbgio.c
${XTOSKRNL_SOURCE_DIR}/kd/globals.c
${XTOSKRNL_SOURCE_DIR}/ke/apc.c ${XTOSKRNL_SOURCE_DIR}/ke/apc.c
${XTOSKRNL_SOURCE_DIR}/ke/dpc.c ${XTOSKRNL_SOURCE_DIR}/ke/dpc.c
${XTOSKRNL_SOURCE_DIR}/ke/event.c ${XTOSKRNL_SOURCE_DIR}/ke/event.c
${XTOSKRNL_SOURCE_DIR}/ke/globals.c ${XTOSKRNL_SOURCE_DIR}/ke/globals.c
${XTOSKRNL_SOURCE_DIR}/ke/info.c
${XTOSKRNL_SOURCE_DIR}/ke/kprocess.c ${XTOSKRNL_SOURCE_DIR}/ke/kprocess.c
${XTOSKRNL_SOURCE_DIR}/ke/krnlinit.c ${XTOSKRNL_SOURCE_DIR}/ke/krnlinit.c
${XTOSKRNL_SOURCE_DIR}/ke/kthread.c ${XTOSKRNL_SOURCE_DIR}/ke/kthread.c
@@ -60,8 +67,10 @@ list(APPEND XTOSKRNL_SOURCE
${XTOSKRNL_SOURCE_DIR}/mm/init.c ${XTOSKRNL_SOURCE_DIR}/mm/init.c
${XTOSKRNL_SOURCE_DIR}/mm/kpools.c ${XTOSKRNL_SOURCE_DIR}/mm/kpools.c
${XTOSKRNL_SOURCE_DIR}/mm/pages.c ${XTOSKRNL_SOURCE_DIR}/mm/pages.c
${XTOSKRNL_SOURCE_DIR}/mm/${ARCH}/globals.c
${XTOSKRNL_SOURCE_DIR}/mm/${ARCH}/init.c ${XTOSKRNL_SOURCE_DIR}/mm/${ARCH}/init.c
${XTOSKRNL_SOURCE_DIR}/mm/${ARCH}/pages.c ${XTOSKRNL_SOURCE_DIR}/mm/${ARCH}/pages.c
${XTOSKRNL_SOURCE_DIR}/mm/${ARCH}/pmap.c
${XTOSKRNL_SOURCE_DIR}/po/idle.c ${XTOSKRNL_SOURCE_DIR}/po/idle.c
${XTOSKRNL_SOURCE_DIR}/rtl/atomic.c ${XTOSKRNL_SOURCE_DIR}/rtl/atomic.c
${XTOSKRNL_SOURCE_DIR}/rtl/bitmap.c ${XTOSKRNL_SOURCE_DIR}/rtl/bitmap.c

View File

@@ -1,58 +1,68 @@
## XTOSKRNL ## XTOSKRNL
XTOSKRNL is an XT system kernel executable, providing the kernel and executive layers for XTOS kernel space. It is XTOSKRNL is the core kernel executable for ExectOS, providing the fundamental kernel and executive layers that operate
a fundamental part of ExectOS, responsible for various core services like hardware abstraction or memory management. within the XTOS kernel space. It is responsible for various core services, such as hardware abstraction, memory
This kernel, contains the scheduler (called sometimes as Dispatcher), cache, object and memory managers, security management, and process scheduling. The kernel contains the scheduler (sometimes referred to as the Dispatcher), the
manager and other kernel executives described below. cache, object, and memory managers, the security manager, and other executive components described below.
All routines in kernel are prefixed to indicate the kernel subsystem they belong and put inside separate directory. All routines in the kernel are prefixed to indicate the subsystem they belong to, and their source code is organized
This is a list of them: into corresponding directories. These subsystems include:
* Ar - Architecture library * Ar - Architecture-specific Library
* Ex - Kernel Executive * Ex - Kernel Executive
* Hl - Hardware Layer * Hl - Hardware Layer
* Ke - Core kernel library * Kd - Kernel Debugger
* Mm - Memory manager * Ke - Core Kernel Library
* Mm - Memory Manager
* Po - Plug&Play and Power Manager * Po - Plug&Play and Power Manager
* Rtl - Runtime library * Rtl - Runtime library
### AR: Architecture Library ### AR: Architecture Library
This module contains processor architecture specific functions. This includes enabling and disabling interrupts at This module contains functions specific to the processor architecture. These include routines for enabling and disabling
the processor, getting the address of a page fault, getting CPUID information, and performing very early processor interrupts, retrieving the faulting address on a page fault, querying CPUID information, and performing very early
initialization. This module does not contain any manufacturer or board-specific code, only CPU architecture specific processor initialization. This module contains only CPU architecture-specific code, with no manufacturer or
code. board-specific implementations.
### EX: Kernel Executive ### EX: Kernel Executive
The kernel executive supplies heap management, including support for allocating system memory from paged/non-paged The Kernel Executive provides services for allocating system memory from paged and non-paged pools. It also supplies
pools, as well as synchronization primitives like push locks and fast mutexes, interlocked memory access, and worker synchronization primitives such as pushlocks and fast mutexes, routines for interlocked memory access, and support for
threads. worker threads.
### HL: Hardware Layer ### HL: Hardware Layer
Hardware Layer, is a layer between the physical hardware of the computer and the rest of the operating system. It was The Hardware Layer is an abstraction layer between the physical hardware and the rest of the operating system. It is
designed to hide differences in hardware and therefore it provides a consistent platform on which the system and designed to abstract away hardware differences, providing a consistent platform on which the kernel and applications
applications may run. can run.
### KD: Kernel Debugger
The Kernel Debugger (KD) subsystem provides debugging support for the kernel. The KD is initialized early in the boot
process to facilitate debugging from the very beginning of the kernel's execution.
### KE: Kernel Library ### KE: Kernel Library
The kernel implements its core functionality that everything else in the system depends upon. This includes basic The Core Kernel Library implements the core functionality upon which the rest of the system depends. This includes
low-level operations such as routing hardware interrupts. fundamental low-level operations, such as routing hardware interrupts and managing dispatcher objects.
### MM: Memory Manager ### MM: Memory Manager
Memory Manager is one of core subsystems. It manages virtual memory, controls memory protection and the paging of memory The Memory Manager is one of the core subsystems. It manages virtual memory, controls memory protection, and
in and out of physical memory to secondary storage. It also implements a general-purpose allocator of physical memory. handles paging memory between physical RAM and secondary storage. It also implements a general-purpose allocator for
physical memory.
### PO: Plug&Play and Power Manager ### PO: Plug&Play and Power Manager
This subsystem deals with power events, such as power-off, stand-by, or hibernate. It also handles Plug&Play and This subsystem handles power management events, such as shutdown or standby. It also manages Plug and Play (PnP),
supports device detection and installation at boot time. It is responsible for starting and stopping devices on demand. supporting device detection and installation at boot time. Furthermore, it is responsible for starting and stopping
devices on demand.
### RTL: Runtime Library ### RTL: Runtime Library
This is a required static copy of C runtime objects. It includes many utility functions that can be used by native The Runtime Library provides a kernel-mode implementation of common C library functions. It includes many utility
applications. routines, for use by other kernel components.
## Functions Naming Convention ## Function Naming Convention
When naming a kernel functions, certain conventions are used. The function name is usually structured with All kernel functions adhere to a strict naming convention to enhance code readability and maintainability. The structure
&lt;Prefix&gt;&lt;Operation&gt;&lt;Object&gt;. The prefix denotes the module to which it belongs, thus module of a function name is generally composed of three parts: &lt;Prefix&gt;&lt;Operation&gt;&lt;Object&gt;
can be identified simply by the name of the function. Additionally, the prefix identifies the function visibility
as well. Thus all private functions, that should not be used from outside of the module has added "p" suffix to The prefix identifies the component to which the function belongs. Additionally, the prefix indicates the function's
the prefix. For example, KepInitializeStack() routine: visibility. Private functions, which should not be called from outside their own module, have a 'p' appended to their
* Kep - prefix meaning this is private routine belonging to Kernel library (Ke) module, prefix.
* Initialize - operation this function does with the object,
* Stack - the object is stack. For example, consider the **KepInitializeStack()** routine:
* **Kep** - The prefix indicates a private (p) routine belonging to the Core Kernel Library (Ke).
* **Initialize** - The operation performed by the function.
* **Stack** - The object on which the operation is performed.

View File

@@ -13,7 +13,7 @@
/** /**
* This macro creates a trap handler for the specified vector. * Creates a trap handler for the specified vector.
* *
* @param Vector * @param Vector
* Supplies a trap vector number. * Supplies a trap vector number.
@@ -22,9 +22,9 @@
* *
* @since XT 1.0 * @since XT 1.0
*/ */
.macro ArpCreateTrapHandler Vector .macro ArCreateTrapHandler Vector
.global ArpTrap\Vector .global ArTrap\Vector
ArpTrap\Vector: ArTrap\Vector:
/* Push fake error code for non-error vectors */ /* 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 .if \Vector != 8 && \Vector != 10 && \Vector != 11 && \Vector != 12 && \Vector != 13 && \Vector != 14 && \Vector != 17 && \Vector != 30
push $0 push $0
@@ -113,7 +113,7 @@ KernelMode$\Vector:
/* Push Frame Pointer, clear direction flag and pass to trap dispatcher */ /* Push Frame Pointer, clear direction flag and pass to trap dispatcher */
mov %rsp, %rcx mov %rsp, %rcx
cld cld
call ArpDispatchTrap call ArDispatchTrap
/* Test previous mode and swapgs if needed */ /* Test previous mode and swapgs if needed */
testb $1, TrapPreviousMode(%rbp) testb $1, TrapPreviousMode(%rbp)
@@ -176,6 +176,6 @@ KernelModeReturn$\Vector:
/* Populate common trap handlers */ /* Populate common trap handlers */
.irp i,0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F .irp i,0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F
.irp j,0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F .irp j,0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F
ArpCreateTrapHandler 0x\i\j ArCreateTrapHandler 0x\i\j
.endr .endr
.endr .endr

133
xtoskrnl/ar/amd64/boot.S Normal file
View File

@@ -0,0 +1,133 @@
/**
* 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 <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:

View File

@@ -1,15 +1,19 @@
/** /**
* PROJECT: ExectOS * PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory * COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/ar/amd64/cpufunc.c * FILE: xtoskrnl/ar/amd64/cpufunc.cc
* DESCRIPTION: Routines to provide access to special AMD64 CPU instructions * DESCRIPTION: Routines to provide access to special AMD64 CPU instructions
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org> * DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/ */
#include <xtos.h> #include <xtos.hh>
/** /* Architecture-specific Library */
namespace AR
{
/**
* Instructs the processor to clear the interrupt flag. * Instructs the processor to clear the interrupt flag.
* *
* @return This routine does not return any value. * @return This routine does not return any value.
@@ -18,7 +22,7 @@
*/ */
XTCDECL XTCDECL
VOID VOID
ArClearInterruptFlag(VOID) CpuFunc::ClearInterruptFlag(VOID)
{ {
__asm__ volatile("cli"); __asm__ volatile("cli");
} }
@@ -35,7 +39,7 @@ ArClearInterruptFlag(VOID)
*/ */
XTCDECL XTCDECL
BOOLEAN BOOLEAN
ArCpuId(IN OUT PCPUID_REGISTERS Registers) CpuFunc::CpuId(IN OUT PCPUID_REGISTERS Registers)
{ {
UINT32 MaxLeaf; UINT32 MaxLeaf;
@@ -76,10 +80,10 @@ ArCpuId(IN OUT PCPUID_REGISTERS Registers)
*/ */
XTCDECL XTCDECL
VOID VOID
ArFlushTlb(VOID) CpuFunc::FlushTlb(VOID)
{ {
/* Flush the TLB by resetting the CR3 */ /* Flush the TLB by resetting the CR3 */
ArWriteControlRegister(3, ArReadControlRegister(3)); WriteControlRegister(3, ReadControlRegister(3));
} }
/** /**
@@ -91,7 +95,7 @@ ArFlushTlb(VOID)
*/ */
XTCDECL XTCDECL
ULONG ULONG
ArGetCpuFlags(VOID) CpuFunc::GetCpuFlags(VOID)
{ {
ULONG_PTR Flags; ULONG_PTR Flags;
@@ -116,7 +120,7 @@ ArGetCpuFlags(VOID)
XTASSEMBLY XTASSEMBLY
XTCDECL XTCDECL
ULONG_PTR ULONG_PTR
ArGetStackPointer(VOID) CpuFunc::GetStackPointer(VOID)
{ {
/* Get current stack pointer */ /* Get current stack pointer */
__asm__ volatile("movq %%rsp, %%rax\n" __asm__ volatile("movq %%rsp, %%rax\n"
@@ -135,7 +139,7 @@ ArGetStackPointer(VOID)
*/ */
XTCDECL XTCDECL
VOID VOID
ArHalt(VOID) CpuFunc::Halt(VOID)
{ {
__asm__ volatile("hlt"); __asm__ volatile("hlt");
} }
@@ -149,12 +153,12 @@ ArHalt(VOID)
*/ */
XTCDECL XTCDECL
BOOLEAN BOOLEAN
ArInterruptsEnabled(VOID) CpuFunc::InterruptsEnabled(VOID)
{ {
ULONG_PTR Flags; ULONG_PTR Flags;
/* Get RFLAGS register */ /* Get RFLAGS register */
Flags = ArGetCpuFlags(); Flags = GetCpuFlags();
/* Check if interrupts are enabled and return result */ /* Check if interrupts are enabled and return result */
return (Flags & X86_EFLAGS_IF_MASK) ? TRUE : FALSE; return (Flags & X86_EFLAGS_IF_MASK) ? TRUE : FALSE;
@@ -172,7 +176,7 @@ ArInterruptsEnabled(VOID)
*/ */
XTCDECL XTCDECL
VOID VOID
ArInvalidateTlbEntry(IN PVOID Address) CpuFunc::InvalidateTlbEntry(IN PVOID Address)
{ {
__asm__ volatile("invlpg (%0)" __asm__ volatile("invlpg (%0)"
: :
@@ -192,7 +196,7 @@ ArInvalidateTlbEntry(IN PVOID Address)
*/ */
XTCDECL XTCDECL
VOID VOID
ArLoadGlobalDescriptorTable(IN PVOID Source) CpuFunc::LoadGlobalDescriptorTable(IN PVOID Source)
{ {
__asm__ volatile("lgdt %0" __asm__ volatile("lgdt %0"
: :
@@ -212,7 +216,7 @@ ArLoadGlobalDescriptorTable(IN PVOID Source)
*/ */
XTCDECL XTCDECL
VOID VOID
ArLoadInterruptDescriptorTable(IN PVOID Source) CpuFunc::LoadInterruptDescriptorTable(IN PVOID Source)
{ {
__asm__ volatile("lidt %0" __asm__ volatile("lidt %0"
: :
@@ -232,7 +236,7 @@ ArLoadInterruptDescriptorTable(IN PVOID Source)
*/ */
XTCDECL XTCDECL
VOID VOID
ArLoadLocalDescriptorTable(IN USHORT Source) CpuFunc::LoadLocalDescriptorTable(IN USHORT Source)
{ {
__asm__ volatile("lldtw %0" __asm__ volatile("lldtw %0"
: :
@@ -251,7 +255,7 @@ ArLoadLocalDescriptorTable(IN USHORT Source)
*/ */
XTCDECL XTCDECL
VOID VOID
ArLoadMxcsrRegister(IN ULONG Source) CpuFunc::LoadMxcsrRegister(IN ULONG Source)
{ {
__asm__ volatile("ldmxcsr %0" __asm__ volatile("ldmxcsr %0"
: :
@@ -273,8 +277,8 @@ ArLoadMxcsrRegister(IN ULONG Source)
*/ */
XTCDECL XTCDECL
VOID VOID
ArLoadSegment(IN USHORT Segment, CpuFunc::LoadSegment(IN USHORT Segment,
IN ULONG Source) IN ULONG Source)
{ {
switch(Segment) switch(Segment)
{ {
@@ -335,7 +339,7 @@ ArLoadSegment(IN USHORT Segment,
*/ */
XTCDECL XTCDECL
VOID VOID
ArLoadTaskRegister(USHORT Source) CpuFunc::LoadTaskRegister(USHORT Source)
{ {
__asm__ volatile("ltr %0" __asm__ volatile("ltr %0"
: :
@@ -351,7 +355,7 @@ ArLoadTaskRegister(USHORT Source)
*/ */
XTCDECL XTCDECL
VOID VOID
ArMemoryBarrier(VOID) CpuFunc::MemoryBarrier(VOID)
{ {
LONG Barrier; LONG Barrier;
__asm__ volatile("lock; orl $0, %0;" __asm__ volatile("lock; orl $0, %0;"
@@ -371,7 +375,7 @@ ArMemoryBarrier(VOID)
*/ */
XTCDECL XTCDECL
ULONG_PTR ULONG_PTR
ArReadControlRegister(IN USHORT ControlRegister) CpuFunc::ReadControlRegister(IN USHORT ControlRegister)
{ {
ULONG_PTR Value; ULONG_PTR Value;
@@ -435,7 +439,7 @@ ArReadControlRegister(IN USHORT ControlRegister)
*/ */
XTCDECL XTCDECL
ULONG_PTR ULONG_PTR
ArReadDebugRegister(IN USHORT DebugRegister) CpuFunc::ReadDebugRegister(IN USHORT DebugRegister)
{ {
ULONG_PTR Value; ULONG_PTR Value;
@@ -504,7 +508,7 @@ ArReadDebugRegister(IN USHORT DebugRegister)
*/ */
XTCDECL XTCDECL
ULONGLONG ULONGLONG
ArReadGSQuadWord(ULONG Offset) CpuFunc::ReadGSQuadWord(ULONG Offset)
{ {
ULONGLONG Value; ULONGLONG Value;
@@ -527,7 +531,7 @@ ArReadGSQuadWord(ULONG Offset)
*/ */
XTCDECL XTCDECL
ULONGLONG ULONGLONG
ArReadModelSpecificRegister(IN ULONG Register) CpuFunc::ReadModelSpecificRegister(IN ULONG Register)
{ {
ULONG Low, High; ULONG Low, High;
@@ -548,7 +552,7 @@ ArReadModelSpecificRegister(IN ULONG Register)
*/ */
XTCDECL XTCDECL
UINT UINT
ArReadMxCsrRegister(VOID) CpuFunc::ReadMxCsrRegister(VOID)
{ {
return __builtin_ia32_stmxcsr(); return __builtin_ia32_stmxcsr();
} }
@@ -562,7 +566,7 @@ ArReadMxCsrRegister(VOID)
*/ */
XTCDECL XTCDECL
ULONGLONG ULONGLONG
ArReadTimeStampCounter(VOID) CpuFunc::ReadTimeStampCounter(VOID)
{ {
ULONGLONG Low, High; ULONGLONG Low, High;
@@ -582,7 +586,7 @@ ArReadTimeStampCounter(VOID)
*/ */
XTCDECL XTCDECL
VOID VOID
ArReadWriteBarrier(VOID) CpuFunc::ReadWriteBarrier(VOID)
{ {
__asm__ volatile("" __asm__ volatile(""
: :
@@ -599,7 +603,7 @@ ArReadWriteBarrier(VOID)
*/ */
XTCDECL XTCDECL
VOID VOID
ArSetInterruptFlag(VOID) CpuFunc::SetInterruptFlag(VOID)
{ {
__asm__ volatile("sti"); __asm__ volatile("sti");
} }
@@ -616,7 +620,7 @@ ArSetInterruptFlag(VOID)
*/ */
XTCDECL XTCDECL
VOID VOID
ArStoreGlobalDescriptorTable(OUT PVOID Destination) CpuFunc::StoreGlobalDescriptorTable(OUT PVOID Destination)
{ {
__asm__ volatile("sgdt %0" __asm__ volatile("sgdt %0"
: "=m" (*(PSHORT)Destination) : "=m" (*(PSHORT)Destination)
@@ -636,7 +640,7 @@ ArStoreGlobalDescriptorTable(OUT PVOID Destination)
*/ */
XTCDECL XTCDECL
VOID VOID
ArStoreInterruptDescriptorTable(OUT PVOID Destination) CpuFunc::StoreInterruptDescriptorTable(OUT PVOID Destination)
{ {
__asm__ volatile("sidt %0" __asm__ volatile("sidt %0"
: "=m" (*(PSHORT)Destination) : "=m" (*(PSHORT)Destination)
@@ -656,7 +660,7 @@ ArStoreInterruptDescriptorTable(OUT PVOID Destination)
*/ */
XTCDECL XTCDECL
VOID VOID
ArStoreLocalDescriptorTable(OUT PVOID Destination) CpuFunc::StoreLocalDescriptorTable(OUT PVOID Destination)
{ {
__asm__ volatile("sldt %0" __asm__ volatile("sldt %0"
: "=m" (*(PSHORT)Destination) : "=m" (*(PSHORT)Destination)
@@ -679,8 +683,8 @@ ArStoreLocalDescriptorTable(OUT PVOID Destination)
*/ */
XTCDECL XTCDECL
VOID VOID
ArStoreSegment(IN USHORT Segment, CpuFunc::StoreSegment(IN USHORT Segment,
OUT PVOID Destination) OUT PVOID Destination)
{ {
switch(Segment) switch(Segment)
{ {
@@ -726,7 +730,7 @@ ArStoreSegment(IN USHORT Segment,
*/ */
XTCDECL XTCDECL
VOID VOID
ArStoreTaskRegister(OUT PVOID Destination) CpuFunc::StoreTaskRegister(OUT PVOID Destination)
{ {
__asm__ volatile("str %0" __asm__ volatile("str %0"
: "=m" (*(PULONG)Destination) : "=m" (*(PULONG)Destination)
@@ -749,8 +753,8 @@ ArStoreTaskRegister(OUT PVOID Destination)
*/ */
XTCDECL XTCDECL
VOID VOID
ArWriteControlRegister(IN USHORT ControlRegister, CpuFunc::WriteControlRegister(IN USHORT ControlRegister,
IN UINT_PTR Value) IN UINT_PTR Value)
{ {
/* Write a value into specified control register */ /* Write a value into specified control register */
switch(ControlRegister) switch(ControlRegister)
@@ -808,8 +812,8 @@ ArWriteControlRegister(IN USHORT ControlRegister,
*/ */
XTCDECL XTCDECL
VOID VOID
ArWriteDebugRegister(IN USHORT DebugRegister, CpuFunc::WriteDebugRegister(IN USHORT DebugRegister,
IN UINT_PTR Value) IN UINT_PTR Value)
{ {
/* Write a value into specified debug register */ /* Write a value into specified debug register */
switch(DebugRegister) switch(DebugRegister)
@@ -820,48 +824,56 @@ ArWriteDebugRegister(IN USHORT DebugRegister,
: :
: "r" (Value) : "r" (Value)
: "memory"); : "memory");
break;
case 1: case 1:
/* Write value to DR1 */ /* Write value to DR1 */
__asm__ volatile("mov %0, %%dr1" __asm__ volatile("mov %0, %%dr1"
: :
: "r" (Value) : "r" (Value)
: "memory"); : "memory");
break;
case 2: case 2:
/* Write value to DR2 */ /* Write value to DR2 */
__asm__ volatile("mov %0, %%dr2" __asm__ volatile("mov %0, %%dr2"
: :
: "r" (Value) : "r" (Value)
: "memory"); : "memory");
break;
case 3: case 3:
/* Write value to DR3 */ /* Write value to DR3 */
__asm__ volatile("mov %0, %%dr3" __asm__ volatile("mov %0, %%dr3"
: :
: "r" (Value) : "r" (Value)
: "memory"); : "memory");
break;
case 4: case 4:
/* Write value to DR4 */ /* Write value to DR4 */
__asm__ volatile("mov %0, %%dr4" __asm__ volatile("mov %0, %%dr4"
: :
: "r" (Value) : "r" (Value)
: "memory"); : "memory");
break;
case 5: case 5:
/* Write value to DR5 */ /* Write value to DR5 */
__asm__ volatile("mov %0, %%dr5" __asm__ volatile("mov %0, %%dr5"
: :
: "r" (Value) : "r" (Value)
: "memory"); : "memory");
break;
case 6: case 6:
/* Write value to DR6 */ /* Write value to DR6 */
__asm__ volatile("mov %0, %%dr6" __asm__ volatile("mov %0, %%dr6"
: :
: "r" (Value) : "r" (Value)
: "memory"); : "memory");
break;
case 7: case 7:
/* Write value to DR7 */ /* Write value to DR7 */
__asm__ volatile("mov %0, %%dr7" __asm__ volatile("mov %0, %%dr7"
: :
: "r" (Value) : "r" (Value)
: "memory"); : "memory");
break;
} }
} }
@@ -877,7 +889,7 @@ ArWriteDebugRegister(IN USHORT DebugRegister,
*/ */
XTCDECL XTCDECL
VOID VOID
ArWriteEflagsRegister(IN UINT_PTR Value) CpuFunc::WriteEflagsRegister(IN UINT_PTR Value)
{ {
__asm__ volatile("push %0\n" __asm__ volatile("push %0\n"
"popf" "popf"
@@ -900,8 +912,8 @@ ArWriteEflagsRegister(IN UINT_PTR Value)
*/ */
XTCDECL XTCDECL
VOID VOID
ArWriteModelSpecificRegister(IN ULONG Register, CpuFunc::WriteModelSpecificRegister(IN ULONG Register,
IN ULONGLONG Value) IN ULONGLONG Value)
{ {
ULONG Low = Value & 0xFFFFFFFF; ULONG Low = Value & 0xFFFFFFFF;
ULONG High = Value >> 32; ULONG High = Value >> 32;
@@ -922,10 +934,187 @@ ArWriteModelSpecificRegister(IN ULONG Register,
*/ */
XTCDECL XTCDECL
VOID VOID
ArYieldProcessor(VOID) CpuFunc::YieldProcessor(VOID)
{ {
__asm__ volatile("pause" __asm__ volatile("pause"
: :
: :
: "memory"); : "memory");
} }
} /* namespace */
/* NEEDED BY XTLDR */
XTCLINK
XTCDECL
VOID
ArClearInterruptFlag(VOID)
{
AR::CpuFunc::ClearInterruptFlag();
}
/* NEEDED BY XTLDR */
XTCLINK
XTCDECL
BOOLEAN
ArCpuId(IN OUT PCPUID_REGISTERS Registers)
{
return AR::CpuFunc::CpuId(Registers);
}
/* NEEDED BY XTLDR */
XTCLINK
XTCDECL
VOID
ArHalt(VOID)
{
AR::CpuFunc::Halt();
}
/* NEEDED BY XTLDR */
XTCLINK
XTCDECL
ULONG_PTR
ArReadControlRegister(IN USHORT ControlRegister)
{
return AR::CpuFunc::ReadControlRegister(ControlRegister);
}
/* NEEDED BY XTLDR */
XTCLINK
XTCDECL
ULONGLONG
ArReadModelSpecificRegister(IN ULONG Register)
{
return AR::CpuFunc::ReadModelSpecificRegister(Register);
}
/* NEEDED BY XTLDR */
XTCLINK
XTCDECL
VOID
ArWriteControlRegister(IN USHORT ControlRegister,
IN UINT_PTR Value)
{
AR::CpuFunc::WriteControlRegister(ControlRegister, Value);
}
/* TEMPORARY FOR COMPATIBILITY WITH C CODE */
XTCLINK
XTCDECL
VOID
ArYieldProcessor(VOID)
{
AR::CpuFunc::YieldProcessor();
}
/* TEMPORARY FOR COMPATIBILITY WITH C CODE */
XTCLINK
XTCDECL
VOID
ArReadWriteBarrier(VOID)
{
AR::CpuFunc::ReadWriteBarrier();
}
/* TEMPORARY FOR COMPATIBILITY WITH C CODE */
XTCLINK
XTCDECL
BOOLEAN
ArInterruptsEnabled(VOID)
{
return AR::CpuFunc::InterruptsEnabled();
}
/* TEMPORARY FOR COMPATIBILITY WITH C CODE */
XTCLINK
XTCDECL
VOID
ArSetInterruptFlag(VOID)
{
AR::CpuFunc::SetInterruptFlag();
}
/* TEMPORARY FOR COMPATIBILITY WITH C CODE */
XTCLINK
XTCDECL
ULONGLONG
ArReadGSQuadWord(ULONG Offset)
{
return AR::CpuFunc::ReadGSQuadWord(Offset);
}
/* TEMPORARY FOR COMPATIBILITY WITH C CODE */
XTCLINK
XTCDECL
ULONG_PTR
ArReadDebugRegister(IN USHORT DebugRegister)
{
return AR::CpuFunc::ReadDebugRegister(DebugRegister);
}
/* TEMPORARY FOR COMPATIBILITY WITH C CODE */
XTCLINK
XTCDECL
UINT
ArReadMxCsrRegister(VOID)
{
return AR::CpuFunc::ReadMxCsrRegister();
}
/* TEMPORARY FOR COMPATIBILITY WITH C CODE */
XTCLINK
XTCDECL
VOID
ArStoreGlobalDescriptorTable(IN PVOID Source)
{
AR::CpuFunc::StoreGlobalDescriptorTable(Source);
}
/* TEMPORARY FOR COMPATIBILITY WITH C CODE */
XTCLINK
XTCDECL
VOID
ArStoreInterruptDescriptorTable(IN PVOID Source)
{
AR::CpuFunc::StoreInterruptDescriptorTable(Source);
}
/* TEMPORARY FOR COMPATIBILITY WITH C CODE */
XTCLINK
XTCDECL
VOID
ArStoreLocalDescriptorTable(IN PVOID Source)
{
AR::CpuFunc::StoreLocalDescriptorTable(Source);
}
/* TEMPORARY FOR COMPATIBILITY WITH C CODE */
XTCLINK
XTCDECL
VOID
ArStoreTaskRegister(OUT PVOID Destination)
{
AR::CpuFunc::StoreTaskRegister(Destination);
}
/* TEMPORARY FOR COMPATIBILITY WITH C CODE */
XTCLINK
XTCDECL
VOID
ArFlushTlb(VOID)
{
AR::CpuFunc::FlushTlb();
}
/* TEMPORARY FOR COMPATIBILITY WITH C CODE */
XTCLINK
XTCDECL
VOID
ArWriteModelSpecificRegister(IN ULONG Register,
IN ULONGLONG Value)
{
AR::CpuFunc::WriteModelSpecificRegister(Register, Value);
}

34
xtoskrnl/ar/amd64/data.cc Normal file
View File

@@ -0,0 +1,34 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/ar/amd64/data.cc
* DESCRIPTION: AMD64 architecture-specific global and static data
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/
#include <xtos.hh>
/* Architecture-specific Library */
namespace AR
{
/* Initial kernel boot stack */
UCHAR ProcSup::BootStack[KERNEL_STACK_SIZE] = {};
/* Initial kernel fault stack */
UCHAR ProcSup::FaultStack[KERNEL_STACK_SIZE] = {};
/* Initial GDT */
KGDTENTRY ProcSup::InitialGdt[GDT_ENTRIES] = {};
/* Initial IDT */
KIDTENTRY ProcSup::InitialIdt[IDT_ENTRIES] = {};
/* Initial Processor Block */
KPROCESSOR_BLOCK ProcSup::InitialProcessorBlock;
/* Initial TSS */
KTSS ProcSup::InitialTss;
} /* namespace */

View File

@@ -1,28 +0,0 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/ar/amd64/globals.c
* DESCRIPTION: XT architecture library global variables
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/
#include <xtos.h>
/* Initial GDT */
KGDTENTRY ArInitialGdt[GDT_ENTRIES] = {0};
/* Initial IDT */
KIDTENTRY ArInitialIdt[IDT_ENTRIES] = {0};
/* Initial Processor Block */
KPROCESSOR_BLOCK ArInitialProcessorBlock;
/* Initial TSS */
KTSS ArInitialTss;
/* Initial kernel boot stack */
UCHAR ArKernelBootStack[KERNEL_STACK_SIZE] = {0};
/* Initial kernel fault stack */
UCHAR ArKernelFaultStack[KERNEL_STACK_SIZE] = {0};

View File

@@ -1,121 +1,28 @@
/** /**
* PROJECT: ExectOS * PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory * COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/ar/amd64/procsup.c * FILE: xtoskrnl/ar/amd64/procsup.cc
* DESCRIPTION: AMD64 processor functionality support * DESCRIPTION: AMD64 processor functionality support
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org> * DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/ */
#include <xtos.h> #include <xtos.hh>
/* Architecture-specific Library */
namespace AR
{
/** /**
* Initializes AMD64 processor specific structures. * Gets the base address of the kernel boot stack.
* *
* @return This routine does not return any value. * @return This routine returns a pointer to the kernel boot stack.
* *
* @since XT 1.0 * @since XT 1.0
*/ */
XTAPI PVOID ProcSup::GetBootStack(VOID)
VOID
ArInitializeProcessor(IN PVOID ProcessorStructures)
{ {
KDESCRIPTOR GdtDescriptor, IdtDescriptor; return (PVOID)BootStack;
PVOID KernelBootStack, KernelFaultStack;
PKPROCESSOR_BLOCK ProcessorBlock;
PKGDTENTRY Gdt;
PKIDTENTRY Idt;
PKTSS Tss;
/* Check if processor structures buffer provided */
if(ProcessorStructures)
{
/* Assign CPU structures from provided buffer */
ArpInitializeProcessorStructures(ProcessorStructures, &Gdt, &Tss, &ProcessorBlock,
&KernelBootStack, &KernelFaultStack);
/* Use global IDT */
Idt = ArInitialIdt;
}
else
{
/* Use initial structures */
Gdt = ArInitialGdt;
Idt = ArInitialIdt;
Tss = &ArInitialTss;
KernelBootStack = &ArKernelBootStack;
KernelFaultStack = &ArKernelFaultStack;
ProcessorBlock = &ArInitialProcessorBlock;
}
/* Initialize processor block */
ArpInitializeProcessorBlock(ProcessorBlock, Gdt, Idt, Tss, KernelFaultStack);
/* Initialize GDT, IDT and TSS */
ArpInitializeGdt(ProcessorBlock);
ArpInitializeIdt(ProcessorBlock);
ArpInitializeTss(ProcessorBlock, KernelBootStack, KernelFaultStack);
/* Set GDT and IDT descriptors */
GdtDescriptor.Base = Gdt;
GdtDescriptor.Limit = (GDT_ENTRIES * sizeof(KGDTENTRY)) - 1;
IdtDescriptor.Base = Idt;
IdtDescriptor.Limit = (IDT_ENTRIES * sizeof(KIDTENTRY)) - 1;
/* Load GDT, IDT and TSS */
ArLoadGlobalDescriptorTable(&GdtDescriptor.Limit);
ArLoadInterruptDescriptorTable(&IdtDescriptor.Limit);
ArLoadTaskRegister((UINT)KGDT_SYS_TSS);
/* Enter passive IRQ level */
HlSetRunLevel(PASSIVE_LEVEL);
/* Initialize segment registers */
ArpInitializeSegments();
/* Set GS base */
ArWriteModelSpecificRegister(X86_MSR_GSBASE, (ULONGLONG)ProcessorBlock);
ArWriteModelSpecificRegister(X86_MSR_KERNEL_GSBASE, (ULONGLONG)ProcessorBlock);
/* Initialize processor registers */
ArpInitializeProcessorRegisters();
/* Identify processor */
ArpIdentifyProcessor();
}
/**
* Updates an existing AMD64 GDT entry with new base address.
*
* @param Gdt
* Supplies a pointer to the GDT.
*
* @param Selector
* Specifies a segment selector of the GDT entry.
*
* @param Base
* Specifies a base address value of the descriptor.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTAPI
VOID
ArSetGdtEntryBase(IN PKGDTENTRY Gdt,
IN USHORT Selector,
IN ULONG_PTR Base)
{
PKGDTENTRY GdtEntry;
/* Get GDT entry */
GdtEntry = (PKGDTENTRY)((ULONG_PTR)Gdt + (Selector & ~RPL_MASK));
/* Set new GDT descriptor base */
GdtEntry->BaseLow = (Base & 0xFFFF);
GdtEntry->Bytes.BaseMiddle = ((Base >> 16) & 0xFF);
GdtEntry->Bytes.BaseHigh = ((Base >> 24) & 0xFF);
GdtEntry->BaseUpper = (Base >> 32);
} }
/** /**
@@ -128,7 +35,7 @@ ArSetGdtEntryBase(IN PKGDTENTRY Gdt,
*/ */
XTAPI XTAPI
VOID VOID
ArpIdentifyProcessor(VOID) ProcSup::IdentifyProcessor(VOID)
{ {
PKPROCESSOR_CONTROL_BLOCK Prcb; PKPROCESSOR_CONTROL_BLOCK Prcb;
CPUID_REGISTERS CpuRegisters; CPUID_REGISTERS CpuRegisters;
@@ -143,10 +50,10 @@ ArpIdentifyProcessor(VOID)
/* Get CPU vendor by issueing CPUID instruction */ /* Get CPU vendor by issueing CPUID instruction */
RtlZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS)); RtlZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
CpuRegisters.Leaf = CPUID_GET_VENDOR_STRING; CpuRegisters.Leaf = CPUID_GET_VENDOR_STRING;
ArCpuId(&CpuRegisters); CpuFunc::CpuId(&CpuRegisters);
/* Store CPU vendor in processor control block */ /* Store CPU vendor in processor control block */
Prcb->CpuId.Vendor = CpuRegisters.Ebx; Prcb->CpuId.Vendor = (CPU_VENDOR)CpuRegisters.Ebx;
*(PULONG)&Prcb->CpuId.VendorName[0] = CpuRegisters.Ebx; *(PULONG)&Prcb->CpuId.VendorName[0] = CpuRegisters.Ebx;
*(PULONG)&Prcb->CpuId.VendorName[4] = CpuRegisters.Edx; *(PULONG)&Prcb->CpuId.VendorName[4] = CpuRegisters.Edx;
*(PULONG)&Prcb->CpuId.VendorName[8] = CpuRegisters.Ecx; *(PULONG)&Prcb->CpuId.VendorName[8] = CpuRegisters.Ecx;
@@ -155,7 +62,7 @@ ArpIdentifyProcessor(VOID)
/* Get CPU standard features */ /* Get CPU standard features */
RtlZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS)); RtlZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
CpuRegisters.Leaf = CPUID_GET_STANDARD1_FEATURES; CpuRegisters.Leaf = CPUID_GET_STANDARD1_FEATURES;
ArCpuId(&CpuRegisters); CpuFunc::CpuId(&CpuRegisters);
/* Store CPU signature in processor control block */ /* Store CPU signature in processor control block */
CpuSignature = *(PCPUID_SIGNATURE)&CpuRegisters.Eax; CpuSignature = *(PCPUID_SIGNATURE)&CpuRegisters.Eax;
@@ -195,6 +102,81 @@ ArpIdentifyProcessor(VOID)
/* TODO: Store a list of CPU features in processor control block */ /* TODO: Store a list of CPU features in processor control block */
} }
/**
* Initializes AMD64 processor specific structures.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTAPI
VOID
ProcSup::InitializeProcessor(IN PVOID ProcessorStructures)
{
KDESCRIPTOR GdtDescriptor, IdtDescriptor;
PVOID KernelBootStack, KernelFaultStack;
PKPROCESSOR_BLOCK ProcessorBlock;
PKGDTENTRY Gdt;
PKIDTENTRY Idt;
PKTSS Tss;
/* Check if processor structures buffer provided */
if(ProcessorStructures)
{
/* Assign CPU structures from provided buffer */
InitializeProcessorStructures(ProcessorStructures, &Gdt, &Tss, &ProcessorBlock,
&KernelBootStack, &KernelFaultStack);
/* Use global IDT */
Idt = InitialIdt;
}
else
{
/* Use initial structures */
Gdt = InitialGdt;
Idt = InitialIdt;
Tss = &InitialTss;
KernelBootStack = &BootStack;
KernelFaultStack = &FaultStack;
ProcessorBlock = &InitialProcessorBlock;
}
/* Initialize processor block */
InitializeProcessorBlock(ProcessorBlock, Gdt, Idt, Tss, KernelFaultStack);
/* Initialize GDT, IDT and TSS */
InitializeGdt(ProcessorBlock);
InitializeIdt(ProcessorBlock);
InitializeTss(ProcessorBlock, KernelBootStack, KernelFaultStack);
/* Set GDT and IDT descriptors */
GdtDescriptor.Base = Gdt;
GdtDescriptor.Limit = (GDT_ENTRIES * sizeof(KGDTENTRY)) - 1;
IdtDescriptor.Base = Idt;
IdtDescriptor.Limit = (IDT_ENTRIES * sizeof(KIDTENTRY)) - 1;
/* Load GDT, IDT and TSS */
CpuFunc::LoadGlobalDescriptorTable(&GdtDescriptor.Limit);
CpuFunc::LoadInterruptDescriptorTable(&IdtDescriptor.Limit);
CpuFunc::LoadTaskRegister((UINT)KGDT_SYS_TSS);
/* Enter passive IRQ level */
HlSetRunLevel(PASSIVE_LEVEL);
/* Initialize segment registers */
InitializeSegments();
/* Set GS base */
CpuFunc::WriteModelSpecificRegister(X86_MSR_GSBASE, (ULONGLONG)ProcessorBlock);
CpuFunc::WriteModelSpecificRegister(X86_MSR_KERNEL_GSBASE, (ULONGLONG)ProcessorBlock);
/* Initialize processor registers */
InitializeProcessorRegisters();
/* Identify processor */
IdentifyProcessor();
}
/** /**
* Initializes the kernel's Global Descriptor Table (GDT). * Initializes the kernel's Global Descriptor Table (GDT).
* *
@@ -207,19 +189,21 @@ ArpIdentifyProcessor(VOID)
*/ */
XTAPI XTAPI
VOID VOID
ArpInitializeGdt(IN PKPROCESSOR_BLOCK ProcessorBlock) ProcSup::InitializeGdt(IN PKPROCESSOR_BLOCK ProcessorBlock)
{ {
/* Initialize GDT entries */ /* Initialize GDT entries */
ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_NULL, 0x0, 0x0, KGDT_TYPE_NONE, KGDT_DPL_SYSTEM, 1); SetGdtEntry(ProcessorBlock->GdtBase, KGDT_NULL, 0x0, 0x0, KGDT_TYPE_NONE, KGDT_DPL_SYSTEM, 1);
ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_R0_CODE, 0x0, 0x0, KGDT_TYPE_CODE, KGDT_DPL_SYSTEM, 1); SetGdtEntry(ProcessorBlock->GdtBase, KGDT_R0_CODE, 0x0, 0x0, KGDT_TYPE_CODE, KGDT_DPL_SYSTEM, 1);
ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_R0_DATA, 0x0, 0x0, KGDT_TYPE_DATA, KGDT_DPL_SYSTEM, 1); SetGdtEntry(ProcessorBlock->GdtBase, KGDT_R0_DATA, 0x0, 0x0, KGDT_TYPE_DATA, KGDT_DPL_SYSTEM, 1);
ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_R3_CMCODE, 0x0, 0xFFFFFFFF, KGDT_TYPE_CODE, KGDT_DPL_USER, 2); SetGdtEntry(ProcessorBlock->GdtBase, KGDT_R3_CMCODE, 0x0, 0xFFFFFFFF, KGDT_TYPE_CODE, KGDT_DPL_USER, 2);
ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_R3_DATA, 0x0, 0xFFFFFFFF, KGDT_TYPE_DATA, KGDT_DPL_USER, 2); SetGdtEntry(ProcessorBlock->GdtBase, KGDT_R3_DATA, 0x0, 0xFFFFFFFF, KGDT_TYPE_DATA, KGDT_DPL_USER, 2);
ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_R3_CODE, 0x0, 0x0, KGDT_TYPE_CODE, KGDT_DPL_USER, 1); SetGdtEntry(ProcessorBlock->GdtBase, KGDT_R3_CODE, 0x0, 0x0, KGDT_TYPE_CODE, KGDT_DPL_USER, 1);
ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_SYS_TSS, (ULONG_PTR)ProcessorBlock->TssBase, sizeof(KTSS) - 1, AMD64_TSS, KGDT_DPL_SYSTEM, 0); SetGdtEntry(ProcessorBlock->GdtBase, KGDT_SYS_TSS, (ULONG_PTR)ProcessorBlock->TssBase,
ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_R3_CMTEB, 0x0, 0x0FFF, KGDT_TYPE_DATA, KGDT_DPL_USER, 2); sizeof(KTSS) - 1, AMD64_TSS, KGDT_DPL_SYSTEM, 0);
ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_R0_LDT, 0x0, 0xFFFFFFFF, KGDT_TYPE_CODE, KGDT_DPL_SYSTEM, 0); SetGdtEntry(ProcessorBlock->GdtBase, KGDT_R3_CMTEB, 0x0, 0x0FFF, KGDT_TYPE_DATA, KGDT_DPL_USER, 2);
ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_ALIAS, (ULONG_PTR)ProcessorBlock->GdtBase, (GDT_ENTRIES * sizeof(KGDTENTRY)) - 1, KGDT_TYPE_DATA, KGDT_DPL_SYSTEM, 0); SetGdtEntry(ProcessorBlock->GdtBase, KGDT_R0_LDT, 0x0, 0xFFFFFFFF, KGDT_TYPE_CODE, KGDT_DPL_SYSTEM, 0);
SetGdtEntry(ProcessorBlock->GdtBase, KGDT_ALIAS, (ULONG_PTR)ProcessorBlock->GdtBase,
(GDT_ENTRIES * sizeof(KGDTENTRY)) - 1, KGDT_TYPE_DATA, KGDT_DPL_SYSTEM, 0);
} }
/** /**
@@ -234,7 +218,7 @@ ArpInitializeGdt(IN PKPROCESSOR_BLOCK ProcessorBlock)
*/ */
XTAPI XTAPI
VOID VOID
ArpInitializeIdt(IN PKPROCESSOR_BLOCK ProcessorBlock) ProcSup::InitializeIdt(IN PKPROCESSOR_BLOCK ProcessorBlock)
{ {
UINT Vector; UINT Vector;
@@ -242,34 +226,34 @@ ArpInitializeIdt(IN PKPROCESSOR_BLOCK ProcessorBlock)
for(Vector = 0; Vector < IDT_ENTRIES; Vector++) for(Vector = 0; Vector < IDT_ENTRIES; Vector++)
{ {
/* Set the IDT to handle unexpected interrupts */ /* Set the IDT to handle unexpected interrupts */
ArpSetIdtGate(ProcessorBlock->IdtBase, Vector, ArpHandleTrapFF, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0); SetIdtGate(ProcessorBlock->IdtBase, Vector, (PVOID)ArTrap0xFF, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
} }
/* Setup IDT handlers for known interrupts and traps */ /* Setup IDT handlers for known interrupts and traps */
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x00, ArpTrap0x00, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0); SetIdtGate(ProcessorBlock->IdtBase, 0x00, (PVOID)ArTrap0x00, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x01, ArpTrap0x01, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0); SetIdtGate(ProcessorBlock->IdtBase, 0x01, (PVOID)ArTrap0x01, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x02, ArpTrap0x02, KGDT_R0_CODE, KIDT_IST_PANIC, KIDT_ACCESS_RING0); SetIdtGate(ProcessorBlock->IdtBase, 0x02, (PVOID)ArTrap0x02, KGDT_R0_CODE, KIDT_IST_PANIC, KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x03, ArpTrap0x03, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3); SetIdtGate(ProcessorBlock->IdtBase, 0x03, (PVOID)ArTrap0x03, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x04, ArpTrap0x04, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3); SetIdtGate(ProcessorBlock->IdtBase, 0x04, (PVOID)ArTrap0x04, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x05, ArpTrap0x05, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0); SetIdtGate(ProcessorBlock->IdtBase, 0x05, (PVOID)ArTrap0x05, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x06, ArpTrap0x06, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0); SetIdtGate(ProcessorBlock->IdtBase, 0x06, (PVOID)ArTrap0x06, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x07, ArpTrap0x07, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0); SetIdtGate(ProcessorBlock->IdtBase, 0x07, (PVOID)ArTrap0x07, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x08, ArpTrap0x08, KGDT_R0_CODE, KIDT_IST_PANIC, KIDT_ACCESS_RING0); SetIdtGate(ProcessorBlock->IdtBase, 0x08, (PVOID)ArTrap0x08, KGDT_R0_CODE, KIDT_IST_PANIC, KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x09, ArpTrap0x09, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0); SetIdtGate(ProcessorBlock->IdtBase, 0x09, (PVOID)ArTrap0x09, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x0A, ArpTrap0x0A, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0); SetIdtGate(ProcessorBlock->IdtBase, 0x0A, (PVOID)ArTrap0x0A, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x0B, ArpTrap0x0B, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0); SetIdtGate(ProcessorBlock->IdtBase, 0x0B, (PVOID)ArTrap0x0B, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x0C, ArpTrap0x0C, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0); SetIdtGate(ProcessorBlock->IdtBase, 0x0C, (PVOID)ArTrap0x0C, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x0D, ArpTrap0x0D, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0); SetIdtGate(ProcessorBlock->IdtBase, 0x0D, (PVOID)ArTrap0x0D, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x0E, ArpTrap0x0E, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0); SetIdtGate(ProcessorBlock->IdtBase, 0x0E, (PVOID)ArTrap0x0E, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x10, ArpTrap0x10, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0); SetIdtGate(ProcessorBlock->IdtBase, 0x10, (PVOID)ArTrap0x10, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x11, ArpTrap0x11, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0); SetIdtGate(ProcessorBlock->IdtBase, 0x11, (PVOID)ArTrap0x11, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x12, ArpTrap0x12, KGDT_R0_CODE, KIDT_IST_MCA, KIDT_ACCESS_RING0); SetIdtGate(ProcessorBlock->IdtBase, 0x12, (PVOID)ArTrap0x12, KGDT_R0_CODE, KIDT_IST_MCA, KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x13, ArpTrap0x13, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0); SetIdtGate(ProcessorBlock->IdtBase, 0x13, (PVOID)ArTrap0x13, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x1F, ArpTrap0x1F, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0); SetIdtGate(ProcessorBlock->IdtBase, 0x1F, (PVOID)ArTrap0x1F, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x2C, ArpTrap0x2C, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3); SetIdtGate(ProcessorBlock->IdtBase, 0x2C, (PVOID)ArTrap0x2C, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x2D, ArpTrap0x2D, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3); SetIdtGate(ProcessorBlock->IdtBase, 0x2D, (PVOID)ArTrap0x2D, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x2F, ArpTrap0x2F, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0); SetIdtGate(ProcessorBlock->IdtBase, 0x2F, (PVOID)ArTrap0x2F, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0xE1, ArpTrap0xE1, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0); SetIdtGate(ProcessorBlock->IdtBase, 0xE1, (PVOID)ArTrap0xE1, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
} }
/** /**
@@ -293,18 +277,18 @@ ArpInitializeIdt(IN PKPROCESSOR_BLOCK ProcessorBlock)
*/ */
XTAPI XTAPI
VOID VOID
ArpInitializeProcessorBlock(OUT PKPROCESSOR_BLOCK ProcessorBlock, ProcSup::InitializeProcessorBlock(OUT PKPROCESSOR_BLOCK ProcessorBlock,
IN PKGDTENTRY Gdt, IN PKGDTENTRY Gdt,
IN PKIDTENTRY Idt, IN PKIDTENTRY Idt,
IN PKTSS Tss, IN PKTSS Tss,
IN PVOID DpcStack) IN PVOID DpcStack)
{ {
/* Set processor block and processor control block */ /* Set processor block and processor control block */
ProcessorBlock->Self = ProcessorBlock; ProcessorBlock->Self = ProcessorBlock;
ProcessorBlock->CurrentPrcb = &ProcessorBlock->Prcb; ProcessorBlock->CurrentPrcb = &ProcessorBlock->Prcb;
/* Set GDT, IDT and TSS descriptors */ /* Set GDT, IDT and TSS descriptors */
ProcessorBlock->GdtBase = (PVOID)Gdt; ProcessorBlock->GdtBase = (PKGDTENTRY)(PVOID)Gdt;
ProcessorBlock->IdtBase = Idt; ProcessorBlock->IdtBase = Idt;
ProcessorBlock->TssBase = Tss; ProcessorBlock->TssBase = Tss;
ProcessorBlock->Prcb.RspBase = Tss->Rsp0; ProcessorBlock->Prcb.RspBase = Tss->Rsp0;
@@ -325,7 +309,7 @@ ArpInitializeProcessorBlock(OUT PKPROCESSOR_BLOCK ProcessorBlock,
ProcessorBlock->Prcb.CurrentThread = &KeInitialThread.ThreadControlBlock; ProcessorBlock->Prcb.CurrentThread = &KeInitialThread.ThreadControlBlock;
ProcessorBlock->Prcb.CurrentThread->ApcState.Process = &KeInitialProcess.ProcessControlBlock; ProcessorBlock->Prcb.CurrentThread->ApcState.Process = &KeInitialProcess.ProcessControlBlock;
ProcessorBlock->Prcb.IdleThread = &KeInitialThread.ThreadControlBlock; ProcessorBlock->Prcb.IdleThread = &KeInitialThread.ThreadControlBlock;
ProcessorBlock->Prcb.NextThread = NULL; ProcessorBlock->Prcb.NextThread = nullptr;
/* Set initial MXCSR register value */ /* Set initial MXCSR register value */
ProcessorBlock->Prcb.MxCsr = INITIAL_MXCSR; ProcessorBlock->Prcb.MxCsr = INITIAL_MXCSR;
@@ -343,56 +327,50 @@ ArpInitializeProcessorBlock(OUT PKPROCESSOR_BLOCK ProcessorBlock,
*/ */
XTAPI XTAPI
VOID VOID
ArpInitializeProcessorRegisters(VOID) ProcSup::InitializeProcessorRegisters(VOID)
{ {
ULONGLONG PatAttributes; ULONGLONG PatAttributes;
/* Enable FXSAVE restore */ /* Enable FXSAVE restore */
ArWriteControlRegister(4, ArReadControlRegister(4) | CR4_FXSR); CpuFunc::WriteControlRegister(4, CpuFunc::ReadControlRegister(4) | CR4_FXSR);
/* Enable XMMI exceptions */ /* Enable XMMI exceptions */
ArWriteControlRegister(4, ArReadControlRegister(4) | CR4_XMMEXCPT); CpuFunc::WriteControlRegister(4, CpuFunc::ReadControlRegister(4) | CR4_XMMEXCPT);
/* Set debugger extension */ /* Set debugger extension */
ArWriteControlRegister(4, ArReadControlRegister(4) | CR4_DE); CpuFunc::WriteControlRegister(4, CpuFunc::ReadControlRegister(4) | CR4_DE);
/* Enable large pages */ /* Enable large pages */
ArWriteControlRegister(4, ArReadControlRegister(4) | CR4_PSE); CpuFunc::WriteControlRegister(4, CpuFunc::ReadControlRegister(4) | CR4_PSE);
/* Enable write-protection */ /* Enable write-protection */
ArWriteControlRegister(0, ArReadControlRegister(0) | CR0_WP); CpuFunc::WriteControlRegister(0, CpuFunc::ReadControlRegister(0) | CR0_WP);
/* Set alignment mask */ /* Set alignment mask */
ArWriteControlRegister(0, ArReadControlRegister(0) | CR0_AM); CpuFunc::WriteControlRegister(0, CpuFunc::ReadControlRegister(0) | CR0_AM);
/* Disable FPU monitoring */ /* Disable FPU monitoring */
ArWriteControlRegister(0, ArReadControlRegister(0) & ~CR0_MP); CpuFunc::WriteControlRegister(0, CpuFunc::ReadControlRegister(0) & ~CR0_MP);
/* Disable x87 FPU exceptions */ /* Disable x87 FPU exceptions */
ArWriteControlRegister(0, ArReadControlRegister(0) & ~CR0_NE); CpuFunc::WriteControlRegister(0, CpuFunc::ReadControlRegister(0) & ~CR0_NE);
/* Flush the TLB */ /* Flush the TLB */
ArFlushTlb(); CpuFunc::FlushTlb();
/* Initialize system calls MSR */ /* Initialize system call MSRs */
ArWriteModelSpecificRegister(X86_MSR_STAR, (((ULONG64)KGDT_R3_CMCODE | RPL_MASK) << 48) | ((ULONG64)KGDT_R0_CODE << 32)); Traps::InitializeSystemCallMsrs();
ArWriteModelSpecificRegister(X86_MSR_CSTAR, (ULONG64)&ArpHandleSystemCall32);
ArWriteModelSpecificRegister(X86_MSR_LSTAR, (ULONG64)&ArpHandleSystemCall64);
ArWriteModelSpecificRegister(X86_MSR_FMASK, X86_EFLAGS_IF_MASK | X86_EFLAGS_TF_MASK);
/* Enable system call extensions (SCE) in EFER MSR */
ArWriteModelSpecificRegister(X86_MSR_EFER, ArReadModelSpecificRegister(X86_MSR_EFER) | X86_MSR_EFER_SCE);
/* Enable No-Execute (NXE) in EFER MSR */ /* Enable No-Execute (NXE) in EFER MSR */
ArWriteModelSpecificRegister(X86_MSR_EFER, ArReadModelSpecificRegister(X86_MSR_EFER) | X86_MSR_EFER_NXE); CpuFunc::WriteModelSpecificRegister(X86_MSR_EFER, CpuFunc::ReadModelSpecificRegister(X86_MSR_EFER) | X86_MSR_EFER_NXE);
/* Initialize Page Attribute Table */ /* Initialize Page Attribute Table */
PatAttributes = (PAT_TYPE_WB << 0) | (PAT_TYPE_USWC << 8) | (PAT_TYPE_WEAK_UC << 16) | (PAT_TYPE_STRONG_UC << 24) | PatAttributes = (PAT_TYPE_WB << 0) | (PAT_TYPE_USWC << 8) | (PAT_TYPE_WEAK_UC << 16) | (PAT_TYPE_STRONG_UC << 24) |
(PAT_TYPE_WB << 32) | (PAT_TYPE_USWC << 40) | (PAT_TYPE_WEAK_UC << 48) | (PAT_TYPE_STRONG_UC << 56); (PAT_TYPE_WB << 32) | (PAT_TYPE_USWC << 40) | (PAT_TYPE_WEAK_UC << 48) | (PAT_TYPE_STRONG_UC << 56);
ArWriteModelSpecificRegister(X86_MSR_PAT, PatAttributes); CpuFunc::WriteModelSpecificRegister(X86_MSR_PAT, PatAttributes);
/* Initialize MXCSR register */ /* Initialize MXCSR register */
ArLoadMxcsrRegister(INITIAL_MXCSR); CpuFunc::LoadMxcsrRegister(INITIAL_MXCSR);
} }
/** /**
@@ -422,12 +400,12 @@ ArpInitializeProcessorRegisters(VOID)
*/ */
XTAPI XTAPI
VOID VOID
ArpInitializeProcessorStructures(IN PVOID ProcessorStructures, ProcSup::InitializeProcessorStructures(IN PVOID ProcessorStructures,
OUT PKGDTENTRY *Gdt, OUT PKGDTENTRY *Gdt,
OUT PKTSS *Tss, OUT PKTSS *Tss,
OUT PKPROCESSOR_BLOCK *ProcessorBlock, OUT PKPROCESSOR_BLOCK *ProcessorBlock,
OUT PVOID *KernelBootStack, OUT PVOID *KernelBootStack,
OUT PVOID *KernelFaultStack) OUT PVOID *KernelFaultStack)
{ {
UINT_PTR Address; UINT_PTR Address;
@@ -442,15 +420,15 @@ ArpInitializeProcessorStructures(IN PVOID ProcessorStructures,
*KernelFaultStack = (PVOID)Address; *KernelFaultStack = (PVOID)Address;
/* Assign a space for GDT and advance */ /* Assign a space for GDT and advance */
*Gdt = (PVOID)Address; *Gdt = (PKGDTENTRY)(PVOID)Address;
Address += sizeof(ArInitialGdt); Address += sizeof(InitialGdt);
/* Assign a space for Processor Block and advance */ /* Assign a space for Processor Block and advance */
*ProcessorBlock = (PVOID)Address; *ProcessorBlock = (PKPROCESSOR_BLOCK)(PVOID)Address;
Address += sizeof(ArInitialProcessorBlock); Address += sizeof(InitialProcessorBlock);
/* Assign a space for TSS */ /* Assign a space for TSS */
*Tss = (PVOID)Address; *Tss = (PKTSS)(PVOID)Address;
} }
/** /**
@@ -462,15 +440,15 @@ ArpInitializeProcessorStructures(IN PVOID ProcessorStructures,
*/ */
XTAPI XTAPI
VOID VOID
ArpInitializeSegments(VOID) ProcSup::InitializeSegments(VOID)
{ {
/* Initialize segments */ /* Initialize segments */
ArLoadSegment(SEGMENT_CS, KGDT_R0_CODE); CpuFunc::LoadSegment(SEGMENT_CS, KGDT_R0_CODE);
ArLoadSegment(SEGMENT_DS, KGDT_R3_DATA | RPL_MASK); CpuFunc::LoadSegment(SEGMENT_DS, KGDT_R3_DATA | RPL_MASK);
ArLoadSegment(SEGMENT_ES, KGDT_R3_DATA | RPL_MASK); CpuFunc::LoadSegment(SEGMENT_ES, KGDT_R3_DATA | RPL_MASK);
ArLoadSegment(SEGMENT_FS, KGDT_R3_CMTEB | RPL_MASK); CpuFunc::LoadSegment(SEGMENT_FS, KGDT_R3_CMTEB | RPL_MASK);
ArLoadSegment(SEGMENT_GS, KGDT_R3_DATA | RPL_MASK); CpuFunc::LoadSegment(SEGMENT_GS, KGDT_R3_DATA | RPL_MASK);
ArLoadSegment(SEGMENT_SS, KGDT_R0_DATA); CpuFunc::LoadSegment(SEGMENT_SS, KGDT_R0_DATA);
} }
/** /**
@@ -488,9 +466,9 @@ ArpInitializeSegments(VOID)
*/ */
XTAPI XTAPI
VOID VOID
ArpInitializeTss(IN PKPROCESSOR_BLOCK ProcessorBlock, ProcSup::InitializeTss(IN PKPROCESSOR_BLOCK ProcessorBlock,
IN PVOID KernelBootStack, IN PVOID KernelBootStack,
IN PVOID KernelFaultStack) IN PVOID KernelFaultStack)
{ {
/* Fill TSS with zeroes */ /* Fill TSS with zeroes */
RtlZeroMemory(ProcessorBlock->TssBase, sizeof(KTSS)); RtlZeroMemory(ProcessorBlock->TssBase, sizeof(KTSS));
@@ -532,13 +510,13 @@ ArpInitializeTss(IN PKPROCESSOR_BLOCK ProcessorBlock,
*/ */
XTAPI XTAPI
VOID VOID
ArpSetGdtEntry(IN PKGDTENTRY Gdt, ProcSup::SetGdtEntry(IN PKGDTENTRY Gdt,
IN USHORT Selector, IN USHORT Selector,
IN ULONG_PTR Base, IN ULONG_PTR Base,
IN ULONG Limit, IN ULONG Limit,
IN UCHAR Type, IN UCHAR Type,
IN UCHAR Dpl, IN UCHAR Dpl,
IN UCHAR SegmentMode) IN UCHAR SegmentMode)
{ {
PKGDTENTRY GdtEntry; PKGDTENTRY GdtEntry;
UCHAR Granularity; UCHAR Granularity;
@@ -580,6 +558,40 @@ ArpSetGdtEntry(IN PKGDTENTRY Gdt,
GdtEntry->MustBeZero = 0; GdtEntry->MustBeZero = 0;
} }
/**
* Updates an existing AMD64 GDT entry with new base address.
*
* @param Gdt
* Supplies a pointer to the GDT.
*
* @param Selector
* Specifies a segment selector of the GDT entry.
*
* @param Base
* Specifies a base address value of the descriptor.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTAPI
VOID
ProcSup::SetGdtEntryBase(IN PKGDTENTRY Gdt,
IN USHORT Selector,
IN ULONG_PTR Base)
{
PKGDTENTRY GdtEntry;
/* Get GDT entry */
GdtEntry = (PKGDTENTRY)((ULONG_PTR)Gdt + (Selector & ~RPL_MASK));
/* Set new GDT descriptor base */
GdtEntry->BaseLow = (Base & 0xFFFF);
GdtEntry->Bytes.BaseMiddle = ((Base >> 16) & 0xFF);
GdtEntry->Bytes.BaseHigh = ((Base >> 24) & 0xFF);
GdtEntry->BaseUpper = (Base >> 32);
}
/** /**
* Fills in a call, interrupt, task or trap gate entry. * Fills in a call, interrupt, task or trap gate entry.
* *
@@ -607,12 +619,12 @@ ArpSetGdtEntry(IN PKGDTENTRY Gdt,
*/ */
XTAPI XTAPI
VOID VOID
ArpSetIdtGate(IN PKIDTENTRY Idt, ProcSup::SetIdtGate(IN PKIDTENTRY Idt,
IN USHORT Vector, IN USHORT Vector,
IN PVOID Handler, IN PVOID Handler,
IN USHORT Selector, IN USHORT Selector,
IN USHORT Ist, IN USHORT Ist,
IN USHORT Access) IN USHORT Access)
{ {
/* Setup the gate */ /* Setup the gate */
Idt[Vector].OffsetLow = ((ULONG_PTR)Handler & 0xFFFF); Idt[Vector].OffsetLow = ((ULONG_PTR)Handler & 0xFFFF);
@@ -624,3 +636,24 @@ ArpSetIdtGate(IN PKIDTENTRY Idt,
Idt[Vector].Selector = Selector; Idt[Vector].Selector = Selector;
Idt[Vector].Type = 0xE; Idt[Vector].Type = 0xE;
} }
} /* namespace */
/* TEMPORARY FOR COMPATIBILITY WITH C CODE */
XTCLINK
XTAPI
PVOID
ArGetBootStack(VOID)
{
return AR::ProcSup::GetBootStack();
}
/* TEMPORARY FOR COMPATIBILITY WITH C CODE */
XTCLINK
XTAPI
VOID
ArInitializeProcessor(IN PVOID ProcessorStructures)
{
AR::ProcSup::InitializeProcessor(ProcessorStructures);
}

View File

@@ -1,14 +1,18 @@
/** /**
* PROJECT: ExectOS * PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory * COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/ar/amd64/traps.c * FILE: xtoskrnl/ar/amd64/traps.cc
* DESCRIPTION: AMD64 system traps * DESCRIPTION: AMD64 system traps
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org> * DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/ */
#include <xtos.h> #include <xtos.hh>
/* Architecture-specific Library */
namespace AR
{
/** /**
* Dispatches the trap provided by common trap handler. * Dispatches the trap provided by common trap handler.
* *
@@ -21,124 +25,138 @@
*/ */
XTCDECL XTCDECL
VOID VOID
ArpDispatchTrap(IN PKTRAP_FRAME TrapFrame) Traps::DispatchTrap(IN PKTRAP_FRAME TrapFrame)
{ {
/* Check vector and call appropriate handler */ /* Check vector and call appropriate handler */
switch(TrapFrame->Vector) switch(TrapFrame->Vector)
{ {
case 0x00: case 0x00:
/* Divide By Zero exception */ /* Divide By Zero exception */
ArpHandleTrap00(TrapFrame); HandleTrap00(TrapFrame);
break; break;
case 0x01: case 0x01:
/* Debug exception */ /* Debug exception */
ArpHandleTrap01(TrapFrame); HandleTrap01(TrapFrame);
break; break;
case 0x02: case 0x02:
/* Non-Maskable Interrupt (NMI) */ /* Non-Maskable Interrupt (NMI) */
ArpHandleTrap02(TrapFrame); HandleTrap02(TrapFrame);
break; break;
case 0x03: case 0x03:
/* INT3 instruction executed */ /* INT3 instruction executed */
ArpHandleTrap03(TrapFrame); HandleTrap03(TrapFrame);
break; break;
case 0x04: case 0x04:
/* Overflow exception */ /* Overflow exception */
ArpHandleTrap04(TrapFrame); HandleTrap04(TrapFrame);
break; break;
case 0x05: case 0x05:
/* Bound Range Exceeded exception */ /* Bound Range Exceeded exception */
ArpHandleTrap05(TrapFrame); HandleTrap05(TrapFrame);
break; break;
case 0x06: case 0x06:
/* Invalid Opcode exception */ /* Invalid Opcode exception */
ArpHandleTrap06(TrapFrame); HandleTrap06(TrapFrame);
break; break;
case 0x07: case 0x07:
/* Device Not Available exception */ /* Device Not Available exception */
ArpHandleTrap07(TrapFrame); HandleTrap07(TrapFrame);
break; break;
case 0x08: case 0x08:
/* Double Fault exception */ /* Double Fault exception */
ArpHandleTrap08(TrapFrame); HandleTrap08(TrapFrame);
break; break;
case 0x09: case 0x09:
/* Segment Overrun exception */ /* Segment Overrun exception */
ArpHandleTrap09(TrapFrame); HandleTrap09(TrapFrame);
break; break;
case 0x0A: case 0x0A:
/* Invalid TSS exception */ /* Invalid TSS exception */
ArpHandleTrap0A(TrapFrame); HandleTrap0A(TrapFrame);
break; break;
case 0x0B: case 0x0B:
/* Segment Not Present exception */ /* Segment Not Present exception */
ArpHandleTrap0B(TrapFrame); HandleTrap0B(TrapFrame);
break; break;
case 0x0C: case 0x0C:
/* Stack Segment Fault exception */ /* Stack Segment Fault exception */
ArpHandleTrap0C(TrapFrame); HandleTrap0C(TrapFrame);
break; break;
case 0x0D: case 0x0D:
/* General Protection Fault (GPF) exception*/ /* General Protection Fault (GPF) exception*/
ArpHandleTrap0D(TrapFrame); HandleTrap0D(TrapFrame);
break; break;
case 0x0E: case 0x0E:
/* Page Fault exception */ /* Page Fault exception */
ArpHandleTrap0E(TrapFrame); HandleTrap0E(TrapFrame);
break; break;
case 0x10: case 0x10:
/* X87 Floating-Point exception */ /* X87 Floating-Point exception */
ArpHandleTrap10(TrapFrame); HandleTrap10(TrapFrame);
break; break;
case 0x11: case 0x11:
/* Alignment Check exception */ /* Alignment Check exception */
ArpHandleTrap11(TrapFrame); HandleTrap11(TrapFrame);
break; break;
case 0x12: case 0x12:
/* Machine Check exception */ /* Machine Check exception */
ArpHandleTrap12(TrapFrame); HandleTrap12(TrapFrame);
break; break;
case 0x13: case 0x13:
/* SIMD Floating-Point exception */ /* SIMD Floating-Point exception */
ArpHandleTrap13(TrapFrame); HandleTrap13(TrapFrame);
break; break;
case 0x1F: case 0x1F:
/* Software Interrupt at APC level */ /* Software Interrupt at APC level */
ArpHandleTrap1F(TrapFrame); HandleTrap1F(TrapFrame);
break; break;
case 0x2C: case 0x2C:
/* Assertion raised */ /* Assertion raised */
ArpHandleTrap2C(TrapFrame); HandleTrap2C(TrapFrame);
break; break;
case 0x2D: case 0x2D:
/* Debug-Service-Request raised */ /* Debug-Service-Request raised */
ArpHandleTrap2D(TrapFrame); HandleTrap2D(TrapFrame);
break; break;
case 0x2F: case 0x2F:
/* Software Interrupt at DISPATCH level */ /* Software Interrupt at DISPATCH level */
ArpHandleTrap2F(TrapFrame); HandleTrap2F(TrapFrame);
break; break;
case 0xE1: case 0xE1:
/* InterProcessor Interrupt (IPI) */ /* InterProcessor Interrupt (IPI) */
ArpHandleTrapE1(TrapFrame); HandleTrapE1(TrapFrame);
break; break;
default: default:
/* Unknown/Unexpected trap */ /* Unknown/Unexpected trap */
ArpHandleTrapFF(TrapFrame); HandleTrapFF(TrapFrame);
break; break;
} }
} }
/**
* Handles a 32-bit system call.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCDECL XTCDECL
VOID VOID
ArpHandleSystemCall32(VOID) Traps::HandleSystemCall32(VOID)
{ {
DebugPrint(L"Handled 32-bit system call!\n"); DebugPrint(L"Handled 32-bit system call!\n");
} }
/**
* Handles a 64-bit system call.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCDECL XTCDECL
VOID VOID
ArpHandleSystemCall64(VOID) Traps::HandleSystemCall64(VOID)
{ {
DebugPrint(L"Handled 64-bit system call!\n"); DebugPrint(L"Handled 64-bit system call!\n");
} }
@@ -155,7 +173,7 @@ ArpHandleSystemCall64(VOID)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap00(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap00(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled Division-By-Zero Error (0x00)!\n"); DebugPrint(L"Handled Division-By-Zero Error (0x00)!\n");
for(;;); for(;;);
@@ -173,7 +191,7 @@ ArpHandleTrap00(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap01(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap01(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled Debug exception (0x01)!\n"); DebugPrint(L"Handled Debug exception (0x01)!\n");
for(;;); for(;;);
@@ -191,7 +209,7 @@ ArpHandleTrap01(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap02(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap02(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled Non-Maskable-Interrupt (0x02)!\n"); DebugPrint(L"Handled Non-Maskable-Interrupt (0x02)!\n");
for(;;); for(;;);
@@ -209,7 +227,7 @@ ArpHandleTrap02(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap03(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap03(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled INT3 (0x03)!\n"); DebugPrint(L"Handled INT3 (0x03)!\n");
for(;;); for(;;);
@@ -227,7 +245,7 @@ ArpHandleTrap03(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap04(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap04(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled Overflow exception (0x04)!\n"); DebugPrint(L"Handled Overflow exception (0x04)!\n");
for(;;); for(;;);
@@ -245,7 +263,7 @@ ArpHandleTrap04(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap05(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap05(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled Bound-Range-Exceeded exception (0x05)!\n"); DebugPrint(L"Handled Bound-Range-Exceeded exception (0x05)!\n");
for(;;); for(;;);
@@ -263,7 +281,7 @@ ArpHandleTrap05(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap06(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap06(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled Invalid Opcode exception (0x06)!\n"); DebugPrint(L"Handled Invalid Opcode exception (0x06)!\n");
for(;;); for(;;);
@@ -281,7 +299,7 @@ ArpHandleTrap06(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap07(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap07(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled Device Not Available exception (0x07)!\n"); DebugPrint(L"Handled Device Not Available exception (0x07)!\n");
for(;;); for(;;);
@@ -299,7 +317,7 @@ ArpHandleTrap07(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap08(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap08(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled Double-Fault exception (0x08)!\n"); DebugPrint(L"Handled Double-Fault exception (0x08)!\n");
for(;;); for(;;);
@@ -317,7 +335,7 @@ ArpHandleTrap08(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap09(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap09(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled Segment-Overrun exception (0x09)!\n"); DebugPrint(L"Handled Segment-Overrun exception (0x09)!\n");
for(;;); for(;;);
@@ -335,7 +353,7 @@ ArpHandleTrap09(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap0A(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap0A(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled Invalid-TSS exception (0x0A)!\n"); DebugPrint(L"Handled Invalid-TSS exception (0x0A)!\n");
for(;;); for(;;);
@@ -353,7 +371,7 @@ ArpHandleTrap0A(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap0B(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap0B(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled Segment-Not-Present exception (0x0B)!\n"); DebugPrint(L"Handled Segment-Not-Present exception (0x0B)!\n");
for(;;); for(;;);
@@ -371,7 +389,7 @@ ArpHandleTrap0B(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap0C(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap0C(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled Stack-Segment-Fault exception (0x0C)!\n"); DebugPrint(L"Handled Stack-Segment-Fault exception (0x0C)!\n");
for(;;); for(;;);
@@ -389,7 +407,7 @@ ArpHandleTrap0C(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap0D(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap0D(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled General-Protection-Fault (0x0D)!\n"); DebugPrint(L"Handled General-Protection-Fault (0x0D)!\n");
for(;;); for(;;);
@@ -407,7 +425,7 @@ ArpHandleTrap0D(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap0E(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap0E(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled Page-Fault exception (0x0E)!\n"); DebugPrint(L"Handled Page-Fault exception (0x0E)!\n");
for(;;); for(;;);
@@ -425,7 +443,7 @@ ArpHandleTrap0E(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap10(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap10(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled x87 Floating-Point exception (0x10)!\n"); DebugPrint(L"Handled x87 Floating-Point exception (0x10)!\n");
for(;;); for(;;);
@@ -443,7 +461,7 @@ ArpHandleTrap10(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap11(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap11(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled Alignment-Check exception (0x11)!\n"); DebugPrint(L"Handled Alignment-Check exception (0x11)!\n");
for(;;); for(;;);
@@ -461,7 +479,7 @@ ArpHandleTrap11(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap12(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap12(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled Machine-Check exception (0x12)!\n"); DebugPrint(L"Handled Machine-Check exception (0x12)!\n");
for(;;); for(;;);
@@ -479,7 +497,7 @@ ArpHandleTrap12(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap13(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap13(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled SIMD Floating-Point exception (0x13)!\n"); DebugPrint(L"Handled SIMD Floating-Point exception (0x13)!\n");
for(;;); for(;;);
@@ -497,7 +515,7 @@ ArpHandleTrap13(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap1F(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap1F(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Unhandled software interrupt at APC level (0x1F)!\n"); DebugPrint(L"Unhandled software interrupt at APC level (0x1F)!\n");
} }
@@ -514,7 +532,7 @@ ArpHandleTrap1F(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap2C(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap2C(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled Assertion (0x2C)!\n"); DebugPrint(L"Handled Assertion (0x2C)!\n");
for(;;); for(;;);
@@ -532,7 +550,7 @@ ArpHandleTrap2C(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap2D(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap2D(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled Debug-Service-Request (0x2D)!\n"); DebugPrint(L"Handled Debug-Service-Request (0x2D)!\n");
for(;;); for(;;);
@@ -550,7 +568,7 @@ ArpHandleTrap2D(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap2F(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap2F(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Unhandled software interrupt at DISPATCH level (0x2F)!\n"); DebugPrint(L"Unhandled software interrupt at DISPATCH level (0x2F)!\n");
} }
@@ -567,7 +585,7 @@ ArpHandleTrap2F(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrapE1(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrapE1(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Unhandled IPI interrupt (0xE1)!\n"); DebugPrint(L"Unhandled IPI interrupt (0xE1)!\n");
} }
@@ -584,8 +602,49 @@ ArpHandleTrapE1(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrapFF(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrapFF(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled Unexpected-Interrupt (0xFF)!\n"); DebugPrint(L"Handled Unexpected-Interrupt (0xFF)!\n");
for(;;); for(;;);
} }
/**
* Initializes system call MSRs.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCDECL
VOID
Traps::InitializeSystemCallMsrs(VOID)
{
/* Initialize system calls MSR */
CpuFunc::WriteModelSpecificRegister(X86_MSR_STAR, (((ULONG64)KGDT_R3_CMCODE | RPL_MASK) << 48) | ((ULONG64)KGDT_R0_CODE << 32));
CpuFunc::WriteModelSpecificRegister(X86_MSR_CSTAR, (ULONG64)&HandleSystemCall32);
CpuFunc::WriteModelSpecificRegister(X86_MSR_LSTAR, (ULONG64)&HandleSystemCall64);
CpuFunc::WriteModelSpecificRegister(X86_MSR_FMASK, X86_EFLAGS_IF_MASK | X86_EFLAGS_TF_MASK);
/* Enable system call extensions (SCE) in EFER MSR */
CpuFunc::WriteModelSpecificRegister(X86_MSR_EFER, CpuFunc::ReadModelSpecificRegister(X86_MSR_EFER) | X86_MSR_EFER_SCE);
}
} /* namespace */
/**
* C-linkage wrapper for dispatching the trap provided by common trap handler.
*
* @param TrapFrame
* Supplies a kernel trap frame pushed by common trap handler on the stack.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCLINK
XTCDECL
VOID
ArDispatchTrap(IN PKTRAP_FRAME TrapFrame)
{
AR::Traps::DispatchTrap(TrapFrame);
}

View File

@@ -22,9 +22,9 @@
* *
* @since XT 1.0 * @since XT 1.0
*/ */
.macro ArpCreateTrapHandler Vector .macro ArCreateTrapHandler Vector
.global _ArpTrap\Vector .global _ArTrap\Vector
_ArpTrap\Vector: _ArTrap\Vector:
/* Push fake error code for non-error vectors */ /* 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 .if \Vector != 8 && \Vector != 10 && \Vector != 11 && \Vector != 12 && \Vector != 13 && \Vector != 14 && \Vector != 17 && \Vector != 30
push $0 push $0
@@ -84,7 +84,7 @@ KernelMode$\Vector:
/* Push Frame Pointer, clear direction flag and pass to trap dispatcher */ /* Push Frame Pointer, clear direction flag and pass to trap dispatcher */
push %esp push %esp
cld cld
call _ArpDispatchTrap call _ArDispatchTrap
/* Clean up the stack */ /* Clean up the stack */
add $4, %esp add $4, %esp
@@ -121,6 +121,6 @@ KernelModeReturn$\Vector:
/* Populate common trap handlers */ /* Populate common trap handlers */
.irp i,0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F .irp i,0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F
.irp j,0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F .irp j,0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F
ArpCreateTrapHandler 0x\i\j ArCreateTrapHandler 0x\i\j
.endr .endr
.endr .endr

14
xtoskrnl/ar/i686/boot.S Normal file
View File

@@ -0,0 +1,14 @@
/**
* 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 <amd64/asmsup.h>
.altmacro
.text

View File

@@ -1,14 +1,18 @@
/** /**
* PROJECT: ExectOS * PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory * COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/ar/i686/cpufunc.c * FILE: xtoskrnl/ar/i686/cpufunc.cc
* DESCRIPTION: Routines to provide access to special i686 CPU instructions * DESCRIPTION: Routines to provide access to special i686 CPU instructions
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org> * DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/ */
#include <xtos.h> #include <xtos.hh>
/* Architecture-specific Library */
namespace AR
{
/** /**
* Instructs the processor to clear the interrupt flag. * Instructs the processor to clear the interrupt flag.
* *
@@ -18,7 +22,7 @@
*/ */
XTCDECL XTCDECL
VOID VOID
ArClearInterruptFlag(VOID) CpuFunc::ClearInterruptFlag(VOID)
{ {
__asm__ volatile("cli"); __asm__ volatile("cli");
} }
@@ -35,7 +39,7 @@ ArClearInterruptFlag(VOID)
*/ */
XTCDECL XTCDECL
BOOLEAN BOOLEAN
ArCpuId(IN OUT PCPUID_REGISTERS Registers) CpuFunc::CpuId(IN OUT PCPUID_REGISTERS Registers)
{ {
UINT32 MaxLeaf; UINT32 MaxLeaf;
@@ -76,7 +80,7 @@ ArCpuId(IN OUT PCPUID_REGISTERS Registers)
*/ */
XTCDECL XTCDECL
VOID VOID
ArFlushTlb(VOID) CpuFunc::FlushTlb(VOID)
{ {
/* Flush the TLB by resetting the CR3 */ /* Flush the TLB by resetting the CR3 */
ArWriteControlRegister(3, ArReadControlRegister(3)); ArWriteControlRegister(3, ArReadControlRegister(3));
@@ -91,7 +95,7 @@ ArFlushTlb(VOID)
*/ */
XTCDECL XTCDECL
ULONG ULONG
ArGetCpuFlags(VOID) CpuFunc::GetCpuFlags(VOID)
{ {
ULONG_PTR Flags; ULONG_PTR Flags;
@@ -116,7 +120,7 @@ ArGetCpuFlags(VOID)
XTASSEMBLY XTASSEMBLY
XTCDECL XTCDECL
ULONG_PTR ULONG_PTR
ArGetStackPointer(VOID) CpuFunc::GetStackPointer(VOID)
{ {
/* Get current stack pointer */ /* Get current stack pointer */
__asm__ volatile("mov %%esp, %%eax\n" __asm__ volatile("mov %%esp, %%eax\n"
@@ -135,7 +139,7 @@ ArGetStackPointer(VOID)
*/ */
XTCDECL XTCDECL
VOID VOID
ArHalt(VOID) CpuFunc::Halt(VOID)
{ {
__asm__ volatile("hlt"); __asm__ volatile("hlt");
} }
@@ -149,12 +153,12 @@ ArHalt(VOID)
*/ */
XTCDECL XTCDECL
BOOLEAN BOOLEAN
ArInterruptsEnabled(VOID) CpuFunc::InterruptsEnabled(VOID)
{ {
ULONG_PTR Flags; ULONG_PTR Flags;
/* Get RFLAGS register */ /* Get RFLAGS register */
Flags = ArGetCpuFlags(); Flags = GetCpuFlags();
/* Check if interrupts are enabled and return result */ /* Check if interrupts are enabled and return result */
return (Flags & X86_EFLAGS_IF_MASK) ? TRUE : FALSE; return (Flags & X86_EFLAGS_IF_MASK) ? TRUE : FALSE;
@@ -172,7 +176,7 @@ ArInterruptsEnabled(VOID)
*/ */
XTCDECL XTCDECL
VOID VOID
ArInvalidateTlbEntry(PVOID Address) CpuFunc::InvalidateTlbEntry(PVOID Address)
{ {
__asm__ volatile("invlpg (%0)" __asm__ volatile("invlpg (%0)"
: :
@@ -192,7 +196,7 @@ ArInvalidateTlbEntry(PVOID Address)
*/ */
XTCDECL XTCDECL
VOID VOID
ArLoadGlobalDescriptorTable(IN PVOID Source) CpuFunc::LoadGlobalDescriptorTable(IN PVOID Source)
{ {
__asm__ volatile("lgdt %0" __asm__ volatile("lgdt %0"
: :
@@ -212,7 +216,7 @@ ArLoadGlobalDescriptorTable(IN PVOID Source)
*/ */
XTCDECL XTCDECL
VOID VOID
ArLoadInterruptDescriptorTable(IN PVOID Source) CpuFunc::LoadInterruptDescriptorTable(IN PVOID Source)
{ {
__asm__ volatile("lidt %0" __asm__ volatile("lidt %0"
: :
@@ -232,7 +236,7 @@ ArLoadInterruptDescriptorTable(IN PVOID Source)
*/ */
XTCDECL XTCDECL
VOID VOID
ArLoadLocalDescriptorTable(IN USHORT Source) CpuFunc::LoadLocalDescriptorTable(IN USHORT Source)
{ {
__asm__ volatile("lldtw %0" __asm__ volatile("lldtw %0"
: :
@@ -254,8 +258,8 @@ ArLoadLocalDescriptorTable(IN USHORT Source)
*/ */
XTCDECL XTCDECL
VOID VOID
ArLoadSegment(IN USHORT Segment, CpuFunc::LoadSegment(IN USHORT Segment,
IN ULONG Source) IN ULONG Source)
{ {
switch(Segment) switch(Segment)
{ {
@@ -316,7 +320,7 @@ ArLoadSegment(IN USHORT Segment,
*/ */
XTCDECL XTCDECL
VOID VOID
ArLoadTaskRegister(USHORT Source) CpuFunc::LoadTaskRegister(USHORT Source)
{ {
__asm__ volatile("ltr %0" __asm__ volatile("ltr %0"
: :
@@ -332,7 +336,7 @@ ArLoadTaskRegister(USHORT Source)
*/ */
XTCDECL XTCDECL
VOID VOID
ArMemoryBarrier(VOID) CpuFunc::MemoryBarrier(VOID)
{ {
LONG Barrier; LONG Barrier;
__asm__ volatile("xchg %%eax, %0" __asm__ volatile("xchg %%eax, %0"
@@ -353,7 +357,7 @@ ArMemoryBarrier(VOID)
*/ */
XTCDECL XTCDECL
ULONG_PTR ULONG_PTR
ArReadControlRegister(IN USHORT ControlRegister) CpuFunc::ReadControlRegister(IN USHORT ControlRegister)
{ {
ULONG_PTR Value; ULONG_PTR Value;
@@ -410,7 +414,7 @@ ArReadControlRegister(IN USHORT ControlRegister)
*/ */
XTCDECL XTCDECL
ULONG_PTR ULONG_PTR
ArReadDebugRegister(IN USHORT DebugRegister) CpuFunc::ReadDebugRegister(IN USHORT DebugRegister)
{ {
ULONG_PTR Value; ULONG_PTR Value;
@@ -479,7 +483,7 @@ ArReadDebugRegister(IN USHORT DebugRegister)
*/ */
XTCDECL XTCDECL
ULONG ULONG
ArReadFSDualWord(ULONG Offset) CpuFunc::ReadFSDualWord(ULONG Offset)
{ {
ULONG Value; ULONG Value;
__asm__ volatile("movl %%fs:%a[Offset], %k[Value]" __asm__ volatile("movl %%fs:%a[Offset], %k[Value]"
@@ -500,7 +504,7 @@ ArReadFSDualWord(ULONG Offset)
*/ */
XTCDECL XTCDECL
ULONGLONG ULONGLONG
ArReadModelSpecificRegister(IN ULONG Register) CpuFunc::ReadModelSpecificRegister(IN ULONG Register)
{ {
ULONGLONG Value; ULONGLONG Value;
@@ -519,7 +523,7 @@ ArReadModelSpecificRegister(IN ULONG Register)
*/ */
XTCDECL XTCDECL
UINT UINT
ArReadMxCsrRegister(VOID) CpuFunc::ReadMxCsrRegister(VOID)
{ {
return __builtin_ia32_stmxcsr(); return __builtin_ia32_stmxcsr();
} }
@@ -533,7 +537,7 @@ ArReadMxCsrRegister(VOID)
*/ */
XTCDECL XTCDECL
ULONGLONG ULONGLONG
ArReadTimeStampCounter(VOID) CpuFunc::ReadTimeStampCounter(VOID)
{ {
ULONGLONG Value; ULONGLONG Value;
@@ -552,7 +556,7 @@ ArReadTimeStampCounter(VOID)
*/ */
XTCDECL XTCDECL
VOID VOID
ArReadWriteBarrier(VOID) CpuFunc::ReadWriteBarrier(VOID)
{ {
__asm__ volatile("" __asm__ volatile(""
: :
@@ -569,7 +573,7 @@ ArReadWriteBarrier(VOID)
*/ */
XTCDECL XTCDECL
VOID VOID
ArSetInterruptFlag(VOID) CpuFunc::SetInterruptFlag(VOID)
{ {
__asm__ volatile("sti"); __asm__ volatile("sti");
} }
@@ -586,7 +590,7 @@ ArSetInterruptFlag(VOID)
*/ */
XTCDECL XTCDECL
VOID VOID
ArStoreGlobalDescriptorTable(OUT PVOID Destination) CpuFunc::StoreGlobalDescriptorTable(OUT PVOID Destination)
{ {
__asm__ volatile("sgdt %0" __asm__ volatile("sgdt %0"
: "=m" (*(PSHORT)Destination) : "=m" (*(PSHORT)Destination)
@@ -606,7 +610,7 @@ ArStoreGlobalDescriptorTable(OUT PVOID Destination)
*/ */
XTCDECL XTCDECL
VOID VOID
ArStoreInterruptDescriptorTable(OUT PVOID Destination) CpuFunc::StoreInterruptDescriptorTable(OUT PVOID Destination)
{ {
__asm__ volatile("sidt %0" __asm__ volatile("sidt %0"
: "=m" (*(PSHORT)Destination) : "=m" (*(PSHORT)Destination)
@@ -626,7 +630,7 @@ ArStoreInterruptDescriptorTable(OUT PVOID Destination)
*/ */
XTCDECL XTCDECL
VOID VOID
ArStoreLocalDescriptorTable(OUT PVOID Destination) CpuFunc::StoreLocalDescriptorTable(OUT PVOID Destination)
{ {
__asm__ volatile("sldt %0" __asm__ volatile("sldt %0"
: "=m" (*(PSHORT)Destination) : "=m" (*(PSHORT)Destination)
@@ -649,8 +653,8 @@ ArStoreLocalDescriptorTable(OUT PVOID Destination)
*/ */
XTCDECL XTCDECL
VOID VOID
ArStoreSegment(IN USHORT Segment, CpuFunc::StoreSegment(IN USHORT Segment,
OUT PVOID Destination) OUT PVOID Destination)
{ {
switch(Segment) switch(Segment)
{ {
@@ -696,7 +700,7 @@ ArStoreSegment(IN USHORT Segment,
*/ */
XTCDECL XTCDECL
VOID VOID
ArStoreTaskRegister(OUT PVOID Destination) CpuFunc::StoreTaskRegister(OUT PVOID Destination)
{ {
__asm__ volatile("str %0" __asm__ volatile("str %0"
: "=m" (*(PULONG)Destination) : "=m" (*(PULONG)Destination)
@@ -719,8 +723,8 @@ ArStoreTaskRegister(OUT PVOID Destination)
*/ */
XTCDECL XTCDECL
VOID VOID
ArWriteControlRegister(IN USHORT ControlRegister, CpuFunc::WriteControlRegister(IN USHORT ControlRegister,
IN UINT_PTR Value) IN UINT_PTR Value)
{ {
/* Write a value into specified control register */ /* Write a value into specified control register */
switch(ControlRegister) switch(ControlRegister)
@@ -771,8 +775,8 @@ ArWriteControlRegister(IN USHORT ControlRegister,
*/ */
XTCDECL XTCDECL
VOID VOID
ArWriteDebugRegister(IN USHORT DebugRegister, CpuFunc::WriteDebugRegister(IN USHORT DebugRegister,
IN UINT_PTR Value) IN UINT_PTR Value)
{ {
/* Write a value into specified debug register */ /* Write a value into specified debug register */
switch(DebugRegister) switch(DebugRegister)
@@ -840,7 +844,7 @@ ArWriteDebugRegister(IN USHORT DebugRegister,
*/ */
XTCDECL XTCDECL
VOID VOID
ArWriteEflagsRegister(IN UINT_PTR Value) CpuFunc::WriteEflagsRegister(IN UINT_PTR Value)
{ {
__asm__ volatile("push %0\n" __asm__ volatile("push %0\n"
"popf" "popf"
@@ -863,8 +867,8 @@ ArWriteEflagsRegister(IN UINT_PTR Value)
*/ */
XTCDECL XTCDECL
VOID VOID
ArWriteModelSpecificRegister(IN ULONG Register, CpuFunc::WriteModelSpecificRegister(IN ULONG Register,
IN ULONGLONG Value) IN ULONGLONG Value)
{ {
__asm__ volatile("wrmsr" __asm__ volatile("wrmsr"
: :
@@ -881,10 +885,185 @@ ArWriteModelSpecificRegister(IN ULONG Register,
*/ */
XTCDECL XTCDECL
VOID VOID
ArYieldProcessor(VOID) CpuFunc::YieldProcessor(VOID)
{ {
__asm__ volatile("pause" __asm__ volatile("pause"
: :
: :
: "memory"); : "memory");
} }
} /* namespace */
/* NEEDED BY XTLDR */
XTCLINK
XTCDECL
VOID
ArClearInterruptFlag(VOID)
{
AR::CpuFunc::ClearInterruptFlag();
}
/* NEEDED BY XTLDR */
XTCLINK
XTCDECL
BOOLEAN
ArCpuId(IN OUT PCPUID_REGISTERS Registers)
{
return AR::CpuFunc::CpuId(Registers);
}
/* NEEDED BY XTLDR */
XTCLINK
XTCDECL
VOID
ArHalt(VOID)
{
AR::CpuFunc::Halt();
}
/* NEEDED BY XTLDR */
XTCLINK
XTCDECL
ULONG_PTR
ArReadControlRegister(IN USHORT ControlRegister)
{
return AR::CpuFunc::ReadControlRegister(ControlRegister);
}
/* NEEDED BY XTLDR */
XTCLINK
XTCDECL
ULONGLONG
ArReadModelSpecificRegister(IN ULONG Register)
{
return AR::CpuFunc::ReadModelSpecificRegister(Register);
}
/* NEEDED BY XTLDR */
XTCLINK
XTCDECL
VOID
ArWriteControlRegister(IN USHORT ControlRegister,
IN UINT_PTR Value)
{
AR::CpuFunc::WriteControlRegister(ControlRegister, Value);
}
/* TEMPORARY FOR COMPATIBILITY WITH C CODE */
XTCLINK
XTCDECL
VOID
ArYieldProcessor(VOID)
{
AR::CpuFunc::YieldProcessor();
}
/* TEMPORARY FOR COMPATIBILITY WITH C CODE */
XTCLINK
XTCDECL
VOID
ArReadWriteBarrier(VOID)
{
AR::CpuFunc::ReadWriteBarrier();
}
/* TEMPORARY FOR COMPATIBILITY WITH C CODE */
XTCLINK
XTCDECL
BOOLEAN
ArInterruptsEnabled(VOID)
{
return AR::CpuFunc::InterruptsEnabled();
}
/* TEMPORARY FOR COMPATIBILITY WITH C CODE */
XTCLINK
XTCDECL
VOID
ArSetInterruptFlag(VOID)
{
AR::CpuFunc::SetInterruptFlag();
}
/* TEMPORARY FOR COMPATIBILITY WITH C CODE */
XTCLINK
XTCDECL
ULONG
ArReadFSDualWord(ULONG Offset)
{
return AR::CpuFunc::ReadFSDualWord(Offset);
}
/* TEMPORARY FOR COMPATIBILITY WITH C CODE */
XTCLINK
XTCDECL
ULONG_PTR
ArReadDebugRegister(IN USHORT DebugRegister)
{
return AR::CpuFunc::ReadDebugRegister(DebugRegister);
}
/* TEMPORARY FOR COMPATIBILITY WITH C CODE */
XTCLINK
XTCDECL
UINT
ArReadMxCsrRegister(VOID)
{
return AR::CpuFunc::ReadMxCsrRegister();
}
/* TEMPORARY FOR COMPATIBILITY WITH C CODE */
XTCLINK
XTCDECL
VOID
ArStoreGlobalDescriptorTable(IN PVOID Source)
{
AR::CpuFunc::StoreGlobalDescriptorTable(Source);
}
/* TEMPORARY FOR COMPATIBILITY WITH C CODE */
XTCLINK
XTCDECL
VOID
ArStoreInterruptDescriptorTable(IN PVOID Source)
{
AR::CpuFunc::StoreInterruptDescriptorTable(Source);
}
/* TEMPORARY FOR COMPATIBILITY WITH C CODE */
XTCLINK
XTCDECL
VOID
ArStoreLocalDescriptorTable(IN PVOID Source)
{
AR::CpuFunc::StoreLocalDescriptorTable(Source);
}
/* TEMPORARY FOR COMPATIBILITY WITH C CODE */
XTCLINK
XTCDECL
VOID
ArStoreTaskRegister(OUT PVOID Destination)
{
AR::CpuFunc::StoreTaskRegister(Destination);
}
/* TEMPORARY FOR COMPATIBILITY WITH C CODE */
XTCLINK
XTCDECL
VOID
ArFlushTlb(VOID)
{
AR::CpuFunc::FlushTlb();
}
/* TEMPORARY FOR COMPATIBILITY WITH C CODE */
XTCLINK
XTCDECL
VOID
ArWriteModelSpecificRegister(IN ULONG Register,
IN ULONGLONG Value)
{
AR::CpuFunc::WriteModelSpecificRegister(Register, Value);
}

40
xtoskrnl/ar/i686/data.cc Normal file
View File

@@ -0,0 +1,40 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/ar/i686/data.cc
* DESCRIPTION: I686 architecture-specific global and static data
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/
#include <xtos.hh>
/* Architecture-specific Library */
namespace AR
{
/* Initial kernel boot stack */
UCHAR ProcSup::BootStack[KERNEL_STACK_SIZE] = {};
/* Double Fault gate */
UCHAR ProcSup::DoubleFaultTss[KTSS_IO_MAPS];
/* Initial kernel fault stack */
UCHAR ProcSup::FaultStack[KERNEL_STACK_SIZE] = {};
/* Initial GDT */
KGDTENTRY ProcSup::InitialGdt[GDT_ENTRIES] = {};
/* Initial IDT */
KIDTENTRY ProcSup::InitialIdt[IDT_ENTRIES] = {};
/* Initial Processor Block */
KPROCESSOR_BLOCK ProcSup::InitialProcessorBlock;
/* Initial TSS */
KTSS ProcSup::InitialTss;
/* NMI task gate */
UCHAR ProcSup::NonMaskableInterruptTss[KTSS_IO_MAPS];
} /* namespace */

View File

@@ -1,32 +0,0 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/ar/i686/globals.c
* DESCRIPTION: XT architecture library global variables
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/
#include <xtos.h>
/* Initial GDT */
KGDTENTRY ArInitialGdt[GDT_ENTRIES] = {0};
/* Initial IDT */
KIDTENTRY ArInitialIdt[IDT_ENTRIES] = {0};
/* Initial Processor Block */
KPROCESSOR_BLOCK ArInitialProcessorBlock;
/* Initial TSS */
KTSS ArInitialTss;
/* Double Fault and NMI task gates */
UCHAR ArpDoubleFaultTss[KTSS_IO_MAPS];
UCHAR ArpNonMaskableInterruptTss[KTSS_IO_MAPS];
/* Initial kernel boot stack */
UCHAR ArKernelBootStack[KERNEL_STACK_SIZE] = {0};
/* Initial kernel fault stack */
UCHAR ArKernelFaultStack[KERNEL_STACK_SIZE] = {0};

View File

@@ -1,116 +1,28 @@
/** /**
* PROJECT: ExectOS * PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory * COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/ar/i686/procsup.c * FILE: xtoskrnl/ar/i686/procsup.cc
* DESCRIPTION: I686 processor functionality support * DESCRIPTION: I686 processor functionality support
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org> * DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/ */
#include <xtos.h> #include <xtos.hh>
/* Architecture-specific Library */
namespace AR
{
/** /**
* Initializes i686 processor specific structures. * Gets the base address of the kernel boot stack.
* *
* @return This routine does not return any value. * @return This routine returns a pointer to the kernel boot stack.
* *
* @since XT 1.0 * @since XT 1.0
*/ */
XTAPI PVOID ProcSup::GetBootStack(VOID)
VOID
ArInitializeProcessor(IN PVOID ProcessorStructures)
{ {
KDESCRIPTOR GdtDescriptor, IdtDescriptor; return (PVOID)BootStack;
PVOID KernelBootStack, KernelFaultStack;
PKPROCESSOR_BLOCK ProcessorBlock;
PKGDTENTRY Gdt;
PKIDTENTRY Idt;
PKTSS Tss;
/* Check if processor structures buffer provided */
if(ProcessorStructures)
{
/* Assign CPU structures from provided buffer */
ArpInitializeProcessorStructures(ProcessorStructures, &Gdt, &Tss, &ProcessorBlock,
&KernelBootStack, &KernelFaultStack);
/* Use global IDT */
Idt = ArInitialIdt;
}
else
{
/* Use initial structures */
Gdt = ArInitialGdt;
Idt = ArInitialIdt;
Tss = &ArInitialTss;
KernelBootStack = &ArKernelBootStack;
KernelFaultStack = &ArKernelFaultStack;
ProcessorBlock = &ArInitialProcessorBlock;
}
/* Initialize processor block */
ArpInitializeProcessorBlock(ProcessorBlock, Gdt, Idt, Tss, KernelFaultStack);
/* Initialize GDT, IDT and TSS */
ArpInitializeGdt(ProcessorBlock);
ArpInitializeIdt(ProcessorBlock);
ArpInitializeTss(ProcessorBlock, KernelBootStack, KernelFaultStack);
/* Set GDT and IDT descriptors */
GdtDescriptor.Base = Gdt;
GdtDescriptor.Limit = (GDT_ENTRIES * sizeof(KGDTENTRY)) - 1;
IdtDescriptor.Base = Idt;
IdtDescriptor.Limit = (IDT_ENTRIES * sizeof(KIDTENTRY)) - 1;
/* Load GDT, IDT and TSS */
ArLoadGlobalDescriptorTable(&GdtDescriptor.Limit);
ArLoadInterruptDescriptorTable(&IdtDescriptor.Limit);
ArLoadTaskRegister((UINT)KGDT_SYS_TSS);
/* Enter passive IRQ level */
HlSetRunLevel(PASSIVE_LEVEL);
/* Initialize segment registers */
ArpInitializeSegments();
/* Initialize processor registers */
ArpInitializeProcessorRegisters();
/* Identify processor */
ArpIdentifyProcessor();
}
/**
* Updates an existing i686 GDT entry with new base address.
*
* @param Gdt
* Supplies a pointer to the GDT.
*
* @param Selector
* Specifies a segment selector of the GDT entry.
*
* @param Base
* Specifies a base address value of the descriptor.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTAPI
VOID
ArSetGdtEntryBase(IN PKGDTENTRY Gdt,
IN USHORT Selector,
IN ULONG_PTR Base)
{
PKGDTENTRY GdtEntry;
/* Get GDT entry */
GdtEntry = (PKGDTENTRY)((ULONG_PTR)Gdt + (Selector & ~RPL_MASK));
/* Set new GDT descriptor base */
GdtEntry->BaseLow = (Base & 0xFFFF);
GdtEntry->Bytes.BaseMiddle = ((Base >> 16) & 0xFF);
GdtEntry->Bytes.BaseHigh = ((Base >> 24) & 0xFF);
} }
/** /**
@@ -123,7 +35,7 @@ ArSetGdtEntryBase(IN PKGDTENTRY Gdt,
*/ */
XTAPI XTAPI
VOID VOID
ArpIdentifyProcessor(VOID) ProcSup::IdentifyProcessor(VOID)
{ {
PKPROCESSOR_CONTROL_BLOCK Prcb; PKPROCESSOR_CONTROL_BLOCK Prcb;
CPUID_REGISTERS CpuRegisters; CPUID_REGISTERS CpuRegisters;
@@ -141,7 +53,7 @@ ArpIdentifyProcessor(VOID)
ArCpuId(&CpuRegisters); ArCpuId(&CpuRegisters);
/* Store CPU vendor in processor control block */ /* Store CPU vendor in processor control block */
Prcb->CpuId.Vendor = CpuRegisters.Ebx; Prcb->CpuId.Vendor = (CPU_VENDOR)CpuRegisters.Ebx;
*(PULONG)&Prcb->CpuId.VendorName[0] = CpuRegisters.Ebx; *(PULONG)&Prcb->CpuId.VendorName[0] = CpuRegisters.Ebx;
*(PULONG)&Prcb->CpuId.VendorName[4] = CpuRegisters.Edx; *(PULONG)&Prcb->CpuId.VendorName[4] = CpuRegisters.Edx;
*(PULONG)&Prcb->CpuId.VendorName[8] = CpuRegisters.Ecx; *(PULONG)&Prcb->CpuId.VendorName[8] = CpuRegisters.Ecx;
@@ -190,6 +102,77 @@ ArpIdentifyProcessor(VOID)
/* TODO: Store a list of CPU features in processor control block */ /* TODO: Store a list of CPU features in processor control block */
} }
/**
* Initializes i686 processor specific structures.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTAPI
VOID
ProcSup::InitializeProcessor(IN PVOID ProcessorStructures)
{
KDESCRIPTOR GdtDescriptor, IdtDescriptor;
PVOID KernelBootStack, KernelFaultStack;
PKPROCESSOR_BLOCK ProcessorBlock;
PKGDTENTRY Gdt;
PKIDTENTRY Idt;
PKTSS Tss;
/* Check if processor structures buffer provided */
if(ProcessorStructures)
{
/* Assign CPU structures from provided buffer */
InitializeProcessorStructures(ProcessorStructures, &Gdt, &Tss, &ProcessorBlock,
&KernelBootStack, &KernelFaultStack);
/* Use global IDT */
Idt = InitialIdt;
}
else
{
/* Use initial structures */
Gdt = InitialGdt;
Idt = InitialIdt;
Tss = &InitialTss;
KernelBootStack = &BootStack;
KernelFaultStack = &FaultStack;
ProcessorBlock = &InitialProcessorBlock;
}
/* Initialize processor block */
InitializeProcessorBlock(ProcessorBlock, Gdt, Idt, Tss, KernelFaultStack);
/* Initialize GDT, IDT and TSS */
InitializeGdt(ProcessorBlock);
InitializeIdt(ProcessorBlock);
InitializeTss(ProcessorBlock, KernelBootStack, KernelFaultStack);
/* Set GDT and IDT descriptors */
GdtDescriptor.Base = Gdt;
GdtDescriptor.Limit = (GDT_ENTRIES * sizeof(KGDTENTRY)) - 1;
IdtDescriptor.Base = Idt;
IdtDescriptor.Limit = (IDT_ENTRIES * sizeof(KIDTENTRY)) - 1;
/* Load GDT, IDT and TSS */
CpuFunc::LoadGlobalDescriptorTable(&GdtDescriptor.Limit);
CpuFunc::LoadInterruptDescriptorTable(&IdtDescriptor.Limit);
CpuFunc::LoadTaskRegister((UINT)KGDT_SYS_TSS);
/* Enter passive IRQ level */
HlSetRunLevel(PASSIVE_LEVEL);
/* Initialize segment registers */
InitializeSegments();
/* Initialize processor registers */
InitializeProcessorRegisters();
/* Identify processor */
IdentifyProcessor();
}
/** /**
* Initializes the kernel's Global Descriptor Table (GDT). * Initializes the kernel's Global Descriptor Table (GDT).
* *
@@ -202,23 +185,23 @@ ArpIdentifyProcessor(VOID)
*/ */
XTAPI XTAPI
VOID VOID
ArpInitializeGdt(IN PKPROCESSOR_BLOCK ProcessorBlock) ProcSup::InitializeGdt(IN PKPROCESSOR_BLOCK ProcessorBlock)
{ {
/* Initialize GDT entries */ /* Initialize GDT entries */
ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_NULL, 0x0, 0x0, KGDT_TYPE_NONE, KGDT_DPL_SYSTEM, 0); SetGdtEntry(ProcessorBlock->GdtBase, KGDT_NULL, 0x0, 0x0, KGDT_TYPE_NONE, KGDT_DPL_SYSTEM, 0);
ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_R0_CODE, 0x0, 0xFFFFFFFF, KGDT_TYPE_CODE, KGDT_DPL_SYSTEM, 2); SetGdtEntry(ProcessorBlock->GdtBase, KGDT_R0_CODE, 0x0, 0xFFFFFFFF, KGDT_TYPE_CODE, KGDT_DPL_SYSTEM, 2);
ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_R0_DATA, 0x0, 0xFFFFFFFF, KGDT_TYPE_DATA, KGDT_DPL_SYSTEM, 2); SetGdtEntry(ProcessorBlock->GdtBase, KGDT_R0_DATA, 0x0, 0xFFFFFFFF, KGDT_TYPE_DATA, KGDT_DPL_SYSTEM, 2);
ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_R3_CODE, 0x0, 0xFFFFFFFF, KGDT_TYPE_CODE, KGDT_DPL_USER, 2); SetGdtEntry(ProcessorBlock->GdtBase, KGDT_R3_CODE, 0x0, 0xFFFFFFFF, KGDT_TYPE_CODE, KGDT_DPL_USER, 2);
ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_R3_DATA, 0x0, 0xFFFFFFFF, KGDT_TYPE_DATA, KGDT_DPL_USER, 2); SetGdtEntry(ProcessorBlock->GdtBase, KGDT_R3_DATA, 0x0, 0xFFFFFFFF, KGDT_TYPE_DATA, KGDT_DPL_USER, 2);
ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_SYS_TSS, (ULONG_PTR)ProcessorBlock->TssBase, sizeof(KTSS) - 1, I686_TSS, KGDT_DPL_SYSTEM, 0); SetGdtEntry(ProcessorBlock->GdtBase, KGDT_SYS_TSS, (ULONG_PTR)ProcessorBlock->TssBase, sizeof(KTSS) - 1, I686_TSS, KGDT_DPL_SYSTEM, 0);
ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_R0_PB, (ULONG_PTR)ProcessorBlock, sizeof(KPROCESSOR_BLOCK), KGDT_TYPE_DATA, KGDT_DPL_SYSTEM, 2); SetGdtEntry(ProcessorBlock->GdtBase, KGDT_R0_PB, (ULONG_PTR)ProcessorBlock, sizeof(KPROCESSOR_BLOCK), KGDT_TYPE_DATA, KGDT_DPL_SYSTEM, 2);
ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_R3_TEB, 0x0, 0xFFF, KGDT_TYPE_DATA | KGDT_DESCRIPTOR_ACCESSED, KGDT_DPL_USER, 2); SetGdtEntry(ProcessorBlock->GdtBase, KGDT_R3_TEB, 0x0, 0xFFF, KGDT_TYPE_DATA | KGDT_DESCRIPTOR_ACCESSED, KGDT_DPL_USER, 2);
ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_VDM_TILE, 0x0400, 0xFFFF, KGDT_TYPE_DATA, KGDT_DPL_USER, 0); SetGdtEntry(ProcessorBlock->GdtBase, KGDT_VDM_TILE, 0x0400, 0xFFFF, KGDT_TYPE_DATA, KGDT_DPL_USER, 0);
ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_R0_LDT, 0x0, 0x0, KGDT_TYPE_NONE, KGDT_DPL_SYSTEM, 0); SetGdtEntry(ProcessorBlock->GdtBase, KGDT_R0_LDT, 0x0, 0x0, KGDT_TYPE_NONE, KGDT_DPL_SYSTEM, 0);
ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_DF_TSS, 0x20000, 0xFFFF, I686_TSS, KGDT_DPL_SYSTEM, 0); SetGdtEntry(ProcessorBlock->GdtBase, KGDT_DF_TSS, 0x20000, 0xFFFF, I686_TSS, KGDT_DPL_SYSTEM, 0);
ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_NMI_TSS, 0x20000, 0xFFFF, KGDT_TYPE_CODE, KGDT_DPL_SYSTEM, 0); SetGdtEntry(ProcessorBlock->GdtBase, KGDT_NMI_TSS, 0x20000, 0xFFFF, KGDT_TYPE_CODE, KGDT_DPL_SYSTEM, 0);
ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_VDBS, 0xB8000, 0x3FFF, KGDT_TYPE_DATA, KGDT_DPL_SYSTEM, 0); SetGdtEntry(ProcessorBlock->GdtBase, KGDT_VDBS, 0xB8000, 0x3FFF, KGDT_TYPE_DATA, KGDT_DPL_SYSTEM, 0);
ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_ALIAS, (ULONG_PTR)ProcessorBlock->GdtBase, (GDT_ENTRIES * sizeof(KGDTENTRY)) - 1, KGDT_TYPE_DATA, KGDT_DPL_SYSTEM, 0); SetGdtEntry(ProcessorBlock->GdtBase, KGDT_ALIAS, (ULONG_PTR)ProcessorBlock->GdtBase, (GDT_ENTRIES * sizeof(KGDTENTRY)) - 1, KGDT_TYPE_DATA, KGDT_DPL_SYSTEM, 0);
} }
/** /**
@@ -233,7 +216,7 @@ ArpInitializeGdt(IN PKPROCESSOR_BLOCK ProcessorBlock)
*/ */
XTAPI XTAPI
VOID VOID
ArpInitializeIdt(IN PKPROCESSOR_BLOCK ProcessorBlock) ProcSup::InitializeIdt(IN PKPROCESSOR_BLOCK ProcessorBlock)
{ {
UINT Vector; UINT Vector;
@@ -241,34 +224,34 @@ ArpInitializeIdt(IN PKPROCESSOR_BLOCK ProcessorBlock)
for(Vector = 0; Vector < IDT_ENTRIES; Vector++) for(Vector = 0; Vector < IDT_ENTRIES; Vector++)
{ {
/* Set the IDT to handle unexpected interrupts */ /* Set the IDT to handle unexpected interrupts */
ArpSetIdtGate(ProcessorBlock->IdtBase, Vector, ArpHandleTrapFF, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); SetIdtGate(ProcessorBlock->IdtBase, Vector, (PVOID)ArTrap0xFF, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
} }
/* Setup IDT handlers for known interrupts and traps */ /* Setup IDT handlers for known interrupts and traps */
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x00, ArpTrap0x00, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); SetIdtGate(ProcessorBlock->IdtBase, 0x00, (PVOID)ArTrap0x00, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x01, ArpTrap0x01, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); SetIdtGate(ProcessorBlock->IdtBase, 0x01, (PVOID)ArTrap0x01, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x02, ArpTrap0x02, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); SetIdtGate(ProcessorBlock->IdtBase, 0x02, (PVOID)ArTrap0x02, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x03, ArpTrap0x03, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING3); SetIdtGate(ProcessorBlock->IdtBase, 0x03, (PVOID)ArTrap0x03, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING3);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x04, ArpTrap0x04, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING3); SetIdtGate(ProcessorBlock->IdtBase, 0x04, (PVOID)ArTrap0x04, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING3);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x05, ArpTrap0x05, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); SetIdtGate(ProcessorBlock->IdtBase, 0x05, (PVOID)ArTrap0x05, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x06, ArpTrap0x06, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); SetIdtGate(ProcessorBlock->IdtBase, 0x06, (PVOID)ArTrap0x06, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x07, ArpTrap0x07, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); SetIdtGate(ProcessorBlock->IdtBase, 0x07, (PVOID)ArTrap0x07, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x08, ArpTrap0x08, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); SetIdtGate(ProcessorBlock->IdtBase, 0x08, (PVOID)ArTrap0x08, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x09, ArpTrap0x09, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); SetIdtGate(ProcessorBlock->IdtBase, 0x09, (PVOID)ArTrap0x09, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x0A, ArpTrap0x0A, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); SetIdtGate(ProcessorBlock->IdtBase, 0x0A, (PVOID)ArTrap0x0A, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x0B, ArpTrap0x0B, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); SetIdtGate(ProcessorBlock->IdtBase, 0x0B, (PVOID)ArTrap0x0B, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x0C, ArpTrap0x0C, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); SetIdtGate(ProcessorBlock->IdtBase, 0x0C, (PVOID)ArTrap0x0C, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x0D, ArpTrap0x0D, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); SetIdtGate(ProcessorBlock->IdtBase, 0x0D, (PVOID)ArTrap0x0D, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x0E, ArpTrap0x0E, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); SetIdtGate(ProcessorBlock->IdtBase, 0x0E, (PVOID)ArTrap0x0E, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x10, ArpTrap0x10, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); SetIdtGate(ProcessorBlock->IdtBase, 0x10, (PVOID)ArTrap0x10, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x11, ArpTrap0x11, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); SetIdtGate(ProcessorBlock->IdtBase, 0x11, (PVOID)ArTrap0x11, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x12, ArpTrap0x12, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); SetIdtGate(ProcessorBlock->IdtBase, 0x12, (PVOID)ArTrap0x12, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x13, ArpTrap0x13, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); SetIdtGate(ProcessorBlock->IdtBase, 0x13, (PVOID)ArTrap0x13, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x2A, ArpTrap0x2A, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING3); SetIdtGate(ProcessorBlock->IdtBase, 0x2A, (PVOID)ArTrap0x2A, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING3);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x2B, ArpTrap0x2B, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING3); SetIdtGate(ProcessorBlock->IdtBase, 0x2B, (PVOID)ArTrap0x2B, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING3);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x2C, ArpTrap0x2C, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING3); SetIdtGate(ProcessorBlock->IdtBase, 0x2C, (PVOID)ArTrap0x2C, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING3);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x2D, ArpTrap0x2D, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING3); SetIdtGate(ProcessorBlock->IdtBase, 0x2D, (PVOID)ArTrap0x2D, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING3);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x2E, ArpTrap0x2E, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING3); SetIdtGate(ProcessorBlock->IdtBase, 0x2E, (PVOID)ArTrap0x2E, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING3);
} }
/** /**
@@ -292,18 +275,18 @@ ArpInitializeIdt(IN PKPROCESSOR_BLOCK ProcessorBlock)
*/ */
XTAPI XTAPI
VOID VOID
ArpInitializeProcessorBlock(OUT PKPROCESSOR_BLOCK ProcessorBlock, ProcSup::InitializeProcessorBlock(OUT PKPROCESSOR_BLOCK ProcessorBlock,
IN PKGDTENTRY Gdt, IN PKGDTENTRY Gdt,
IN PKIDTENTRY Idt, IN PKIDTENTRY Idt,
IN PKTSS Tss, IN PKTSS Tss,
IN PVOID DpcStack) IN PVOID DpcStack)
{ {
/* Set processor block and processor control block */ /* Set processor block and processor control block */
ProcessorBlock->Self = ProcessorBlock; ProcessorBlock->Self = ProcessorBlock;
ProcessorBlock->CurrentPrcb = &ProcessorBlock->Prcb; ProcessorBlock->CurrentPrcb = &ProcessorBlock->Prcb;
/* Set GDT, IDT and TSS descriptors */ /* Set GDT, IDT and TSS descriptors */
ProcessorBlock->GdtBase = Gdt; ProcessorBlock->GdtBase = (PKGDTENTRY)(PVOID)Gdt;
ProcessorBlock->IdtBase = Idt; ProcessorBlock->IdtBase = Idt;
ProcessorBlock->TssBase = Tss; ProcessorBlock->TssBase = Tss;
@@ -323,7 +306,7 @@ ArpInitializeProcessorBlock(OUT PKPROCESSOR_BLOCK ProcessorBlock,
ProcessorBlock->Prcb.CurrentThread = &KeInitialThread.ThreadControlBlock; ProcessorBlock->Prcb.CurrentThread = &KeInitialThread.ThreadControlBlock;
ProcessorBlock->Prcb.CurrentThread->ApcState.Process = &KeInitialProcess.ProcessControlBlock; ProcessorBlock->Prcb.CurrentThread->ApcState.Process = &KeInitialProcess.ProcessControlBlock;
ProcessorBlock->Prcb.IdleThread = &KeInitialThread.ThreadControlBlock; ProcessorBlock->Prcb.IdleThread = &KeInitialThread.ThreadControlBlock;
ProcessorBlock->Prcb.NextThread = NULL; ProcessorBlock->Prcb.NextThread = nullptr;
/* Set initial runlevel */ /* Set initial runlevel */
ProcessorBlock->RunLevel = PASSIVE_LEVEL; ProcessorBlock->RunLevel = PASSIVE_LEVEL;
@@ -338,13 +321,13 @@ ArpInitializeProcessorBlock(OUT PKPROCESSOR_BLOCK ProcessorBlock,
*/ */
XTAPI XTAPI
VOID VOID
ArpInitializeProcessorRegisters(VOID) ProcSup::InitializeProcessorRegisters(VOID)
{ {
/* Clear EFLAGS register */ /* Clear EFLAGS register */
ArWriteEflagsRegister(0); CpuFunc::WriteEflagsRegister(0);
/* Enable write-protection */ /* Enable write-protection */
ArWriteControlRegister(0, ArReadControlRegister(0) | CR0_WP); CpuFunc::WriteControlRegister(0, CpuFunc::ReadControlRegister(0) | CR0_WP);
} }
/** /**
@@ -374,12 +357,12 @@ ArpInitializeProcessorRegisters(VOID)
*/ */
XTAPI XTAPI
VOID VOID
ArpInitializeProcessorStructures(IN PVOID ProcessorStructures, ProcSup::InitializeProcessorStructures(IN PVOID ProcessorStructures,
OUT PKGDTENTRY *Gdt, OUT PKGDTENTRY *Gdt,
OUT PKTSS *Tss, OUT PKTSS *Tss,
OUT PKPROCESSOR_BLOCK *ProcessorBlock, OUT PKPROCESSOR_BLOCK *ProcessorBlock,
OUT PVOID *KernelBootStack, OUT PVOID *KernelBootStack,
OUT PVOID *KernelFaultStack) OUT PVOID *KernelFaultStack)
{ {
UINT_PTR Address; UINT_PTR Address;
@@ -394,15 +377,15 @@ ArpInitializeProcessorStructures(IN PVOID ProcessorStructures,
*KernelFaultStack = (PVOID)Address; *KernelFaultStack = (PVOID)Address;
/* Assign a space for GDT and advance */ /* Assign a space for GDT and advance */
*Gdt = (PVOID)Address; *Gdt = (PKGDTENTRY)(PVOID)Address;
Address += sizeof(ArInitialGdt); Address += sizeof(ArInitialGdt);
/* Assign a space for Processor Block and advance */ /* Assign a space for Processor Block and advance */
*ProcessorBlock = (PVOID)Address; *ProcessorBlock = (PKPROCESSOR_BLOCK)(PVOID)Address;
Address += sizeof(ArInitialProcessorBlock); Address += sizeof(ArInitialProcessorBlock);
/* Assign a space for TSS */ /* Assign a space for TSS */
*Tss = (PVOID)Address; *Tss = (PKTSS)(PVOID)Address;
} }
/** /**
@@ -414,13 +397,13 @@ ArpInitializeProcessorStructures(IN PVOID ProcessorStructures,
*/ */
XTAPI XTAPI
VOID VOID
ArpInitializeSegments(VOID) ProcSup::InitializeSegments(VOID)
{ {
/* Initialize segments */ /* Initialize segments */
ArLoadSegment(SEGMENT_CS, KGDT_R0_CODE); CpuFunc::LoadSegment(SEGMENT_CS, KGDT_R0_CODE);
ArLoadSegment(SEGMENT_DS, KGDT_R3_DATA | RPL_MASK); CpuFunc::LoadSegment(SEGMENT_DS, KGDT_R3_DATA | RPL_MASK);
ArLoadSegment(SEGMENT_ES, KGDT_R3_DATA | RPL_MASK); CpuFunc::LoadSegment(SEGMENT_ES, KGDT_R3_DATA | RPL_MASK);
ArLoadSegment(SEGMENT_FS, KGDT_R0_PB); CpuFunc::LoadSegment(SEGMENT_FS, KGDT_R0_PB);
} }
/** /**
@@ -435,9 +418,9 @@ ArpInitializeSegments(VOID)
*/ */
XTAPI XTAPI
VOID VOID
ArpInitializeTss(IN PKPROCESSOR_BLOCK ProcessorBlock, ProcSup::InitializeTss(IN PKPROCESSOR_BLOCK ProcessorBlock,
IN PVOID KernelBootStack, IN PVOID KernelBootStack,
IN PVOID KernelFaultStack) IN PVOID KernelFaultStack)
{ {
/* Clear I/O map */ /* Clear I/O map */
RtlSetMemory(ProcessorBlock->TssBase->IoMaps[0].IoMap, 0xFF, IOPM_FULL_SIZE); RtlSetMemory(ProcessorBlock->TssBase->IoMaps[0].IoMap, 0xFF, IOPM_FULL_SIZE);
@@ -468,8 +451,8 @@ ArpInitializeTss(IN PKPROCESSOR_BLOCK ProcessorBlock,
ProcessorBlock->TssBase->Ss0 = KGDT_R0_DATA; ProcessorBlock->TssBase->Ss0 = KGDT_R0_DATA;
/* Initialize task gates for DoubleFault and NMI traps */ /* Initialize task gates for DoubleFault and NMI traps */
ArpSetDoubleFaultTssEntry(ProcessorBlock, KernelFaultStack); SetDoubleFaultTssEntry(ProcessorBlock, KernelFaultStack);
ArpSetNonMaskableInterruptTssEntry(ProcessorBlock, KernelFaultStack); SetNonMaskableInterruptTssEntry(ProcessorBlock, KernelFaultStack);
} }
/** /**
@@ -484,8 +467,8 @@ ArpInitializeTss(IN PKPROCESSOR_BLOCK ProcessorBlock,
*/ */
XTAPI XTAPI
VOID VOID
ArpSetDoubleFaultTssEntry(IN PKPROCESSOR_BLOCK ProcessorBlock, ProcSup::SetDoubleFaultTssEntry(IN PKPROCESSOR_BLOCK ProcessorBlock,
IN PVOID KernelFaultStack) IN PVOID KernelFaultStack)
{ {
PKGDTENTRY TaskGateEntry, TssEntry; PKGDTENTRY TaskGateEntry, TssEntry;
PKTSS Tss; PKTSS Tss;
@@ -498,20 +481,20 @@ ArpSetDoubleFaultTssEntry(IN PKPROCESSOR_BLOCK ProcessorBlock,
((PKIDTENTRY)TaskGateEntry)->Selector = KGDT_DF_TSS; ((PKIDTENTRY)TaskGateEntry)->Selector = KGDT_DF_TSS;
/* Initialize DoubleFault TSS and set initial state */ /* Initialize DoubleFault TSS and set initial state */
Tss = (PKTSS)ArpDoubleFaultTss; Tss = (PKTSS)DoubleFaultTss;
Tss->IoMapBase = sizeof(KTSS); Tss->IoMapBase = sizeof(KTSS);
Tss->Flags = 0; Tss->Flags = 0;
Tss->LDT = KGDT_R0_LDT; Tss->LDT = KGDT_R0_LDT;
Tss->CR3 = ArReadControlRegister(3); Tss->CR3 = CpuFunc::ReadControlRegister(3);
Tss->Esp = (ULONG_PTR)KernelFaultStack; Tss->Esp = (ULONG_PTR)KernelFaultStack;
Tss->Esp0 = (ULONG_PTR)KernelFaultStack; Tss->Esp0 = (ULONG_PTR)KernelFaultStack;
Tss->Eip = PtrToUlong(ArpHandleTrap08); Tss->Eip = PtrToUlong(ArTrap0x08);
Tss->Cs = KGDT_R0_CODE; Tss->Cs = KGDT_R0_CODE;
Tss->Ds = KGDT_R3_DATA | RPL_MASK; Tss->Ds = KGDT_R3_DATA | RPL_MASK;
Tss->Es = KGDT_R3_DATA | RPL_MASK; Tss->Es = KGDT_R3_DATA | RPL_MASK;
Tss->Fs = KGDT_R0_PB; Tss->Fs = KGDT_R0_PB;
Tss->Ss0 = KGDT_R0_DATA; Tss->Ss0 = KGDT_R0_DATA;
ArStoreSegment(SEGMENT_SS, (PVOID)&Tss->Ss); CpuFunc::StoreSegment(SEGMENT_SS, (PVOID)&Tss->Ss);
/* Setup DoubleFault TSS entry in Global Descriptor Table */ /* Setup DoubleFault TSS entry in Global Descriptor Table */
TssEntry = (PKGDTENTRY)(&(ProcessorBlock->GdtBase[KGDT_DF_TSS / sizeof(KGDTENTRY)])); TssEntry = (PKGDTENTRY)(&(ProcessorBlock->GdtBase[KGDT_DF_TSS / sizeof(KGDTENTRY)]));
@@ -555,13 +538,13 @@ ArpSetDoubleFaultTssEntry(IN PKPROCESSOR_BLOCK ProcessorBlock,
*/ */
XTAPI XTAPI
VOID VOID
ArpSetGdtEntry(IN PKGDTENTRY Gdt, ProcSup::SetGdtEntry(IN PKGDTENTRY Gdt,
IN USHORT Selector, IN USHORT Selector,
IN ULONG_PTR Base, IN ULONG_PTR Base,
IN ULONG Limit, IN ULONG Limit,
IN UCHAR Type, IN UCHAR Type,
IN UCHAR Dpl, IN UCHAR Dpl,
IN UCHAR SegmentMode) IN UCHAR SegmentMode)
{ {
PKGDTENTRY GdtEntry; PKGDTENTRY GdtEntry;
UCHAR Granularity; UCHAR Granularity;
@@ -601,6 +584,39 @@ ArpSetGdtEntry(IN PKGDTENTRY Gdt,
GdtEntry->Bits.Type = (Type & 0x1F); GdtEntry->Bits.Type = (Type & 0x1F);
} }
/**
* Updates an existing i686 GDT entry with new base address.
*
* @param Gdt
* Supplies a pointer to the GDT.
*
* @param Selector
* Specifies a segment selector of the GDT entry.
*
* @param Base
* Specifies a base address value of the descriptor.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTAPI
VOID
ProcSup::SetGdtEntryBase(IN PKGDTENTRY Gdt,
IN USHORT Selector,
IN ULONG_PTR Base)
{
PKGDTENTRY GdtEntry;
/* Get GDT entry */
GdtEntry = (PKGDTENTRY)((ULONG_PTR)Gdt + (Selector & ~RPL_MASK));
/* Set new GDT descriptor base */
GdtEntry->BaseLow = (Base & 0xFFFF);
GdtEntry->Bytes.BaseMiddle = ((Base >> 16) & 0xFF);
GdtEntry->Bytes.BaseHigh = ((Base >> 24) & 0xFF);
}
/** /**
* Fills in a call, interrupt, task or trap gate entry. * Fills in a call, interrupt, task or trap gate entry.
* *
@@ -628,12 +644,12 @@ ArpSetGdtEntry(IN PKGDTENTRY Gdt,
*/ */
XTAPI XTAPI
VOID VOID
ArpSetIdtGate(IN PKIDTENTRY Idt, ProcSup::SetIdtGate(IN PKIDTENTRY Idt,
IN USHORT Vector, IN USHORT Vector,
IN PVOID Handler, IN PVOID Handler,
IN USHORT Selector, IN USHORT Selector,
IN USHORT Ist, IN USHORT Ist,
IN USHORT Access) IN USHORT Access)
{ {
/* Setup the gate */ /* Setup the gate */
Idt[Vector].Offset = (USHORT)((ULONG)Handler & 0xFFFF); Idt[Vector].Offset = (USHORT)((ULONG)Handler & 0xFFFF);
@@ -654,8 +670,8 @@ ArpSetIdtGate(IN PKIDTENTRY Idt,
*/ */
XTAPI XTAPI
VOID VOID
ArpSetNonMaskableInterruptTssEntry(IN PKPROCESSOR_BLOCK ProcessorBlock, ProcSup::SetNonMaskableInterruptTssEntry(IN PKPROCESSOR_BLOCK ProcessorBlock,
IN PVOID KernelFaultStack) IN PVOID KernelFaultStack)
{ {
PKGDTENTRY TaskGateEntry, TssEntry; PKGDTENTRY TaskGateEntry, TssEntry;
PKTSS Tss; PKTSS Tss;
@@ -668,19 +684,19 @@ ArpSetNonMaskableInterruptTssEntry(IN PKPROCESSOR_BLOCK ProcessorBlock,
((PKIDTENTRY)TaskGateEntry)->Selector = KGDT_NMI_TSS; ((PKIDTENTRY)TaskGateEntry)->Selector = KGDT_NMI_TSS;
/* Initialize NMI TSS and set initial state */ /* Initialize NMI TSS and set initial state */
Tss = (PKTSS)ArpNonMaskableInterruptTss; Tss = (PKTSS)NonMaskableInterruptTss;
Tss->IoMapBase = sizeof(KTSS); Tss->IoMapBase = sizeof(KTSS);
Tss->Flags = 0; Tss->Flags = 0;
Tss->LDT = KGDT_R0_LDT; Tss->LDT = KGDT_R0_LDT;
Tss->CR3 = ArReadControlRegister(3); Tss->CR3 = ArReadControlRegister(3);
Tss->Esp = (ULONG_PTR)KernelFaultStack; Tss->Esp = (ULONG_PTR)KernelFaultStack;
Tss->Esp0 = (ULONG_PTR)KernelFaultStack; Tss->Esp0 = (ULONG_PTR)KernelFaultStack;
Tss->Eip = PtrToUlong(ArpHandleTrap02); Tss->Eip = PtrToUlong(ArTrap0x02);
Tss->Cs = KGDT_R0_CODE; Tss->Cs = KGDT_R0_CODE;
Tss->Ds = KGDT_R3_DATA | RPL_MASK; Tss->Ds = KGDT_R3_DATA | RPL_MASK;
Tss->Es = KGDT_R3_DATA | RPL_MASK; Tss->Es = KGDT_R3_DATA | RPL_MASK;
Tss->Fs = KGDT_R0_PB; Tss->Fs = KGDT_R0_PB;
ArStoreSegment(SEGMENT_SS, (PVOID)&Tss->Ss); CpuFunc::StoreSegment(SEGMENT_SS, (PVOID)&Tss->Ss);
/* Setup NMI TSS entry in Global Descriptor Table */ /* Setup NMI TSS entry in Global Descriptor Table */
TssEntry = (PKGDTENTRY)(&(ProcessorBlock->GdtBase[KGDT_NMI_TSS / sizeof(KGDTENTRY)])); TssEntry = (PKGDTENTRY)(&(ProcessorBlock->GdtBase[KGDT_NMI_TSS / sizeof(KGDTENTRY)]));
@@ -693,3 +709,24 @@ ArpSetNonMaskableInterruptTssEntry(IN PKPROCESSOR_BLOCK ProcessorBlock,
TssEntry->Bits.Present = 1; TssEntry->Bits.Present = 1;
TssEntry->Bits.Type = I686_TSS; TssEntry->Bits.Type = I686_TSS;
} }
} /* namespace */
/* TEMPORARY FOR COMPATIBILITY WITH C CODE */
XTCLINK
XTAPI
PVOID
ArGetBootStack(VOID)
{
return AR::ProcSup::GetBootStack();
}
/* TEMPORARY FOR COMPATIBILITY WITH C CODE */
XTCLINK
XTAPI
VOID
ArInitializeProcessor(IN PVOID ProcessorStructures)
{
AR::ProcSup::InitializeProcessor(ProcessorStructures);
}

View File

@@ -1,14 +1,18 @@
/** /**
* PROJECT: ExectOS * PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory * COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/ar/i686/traps.c * FILE: xtoskrnl/ar/i686/traps.cc
* DESCRIPTION: I686 system traps * DESCRIPTION: I686 system traps
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org> * DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/ */
#include <xtos.h> #include <xtos.hh>
/* Architecture-specific Library */
namespace AR
{
/** /**
* Dispatches the trap provided by common trap handler. * Dispatches the trap provided by common trap handler.
* *
@@ -21,110 +25,110 @@
*/ */
XTCDECL XTCDECL
VOID VOID
ArpDispatchTrap(IN PKTRAP_FRAME TrapFrame) Traps::DispatchTrap(IN PKTRAP_FRAME TrapFrame)
{ {
/* Check vector and call appropriate handler */ /* Check vector and call appropriate handler */
switch(TrapFrame->Vector) switch(TrapFrame->Vector)
{ {
case 0x00: case 0x00:
/* Divide By Zero exception */ /* Divide By Zero exception */
ArpHandleTrap00(TrapFrame); HandleTrap00(TrapFrame);
break; break;
case 0x01: case 0x01:
/* Debug exception */ /* Debug exception */
ArpHandleTrap01(TrapFrame); HandleTrap01(TrapFrame);
break; break;
case 0x02: case 0x02:
/* Non-Maskable Interrupt (NMI) */ /* Non-Maskable Interrupt (NMI) */
ArpHandleTrap02(TrapFrame); HandleTrap02(TrapFrame);
break; break;
case 0x03: case 0x03:
/* INT3 instruction executed */ /* INT3 instruction executed */
ArpHandleTrap03(TrapFrame); HandleTrap03(TrapFrame);
break; break;
case 0x04: case 0x04:
/* Overflow exception */ /* Overflow exception */
ArpHandleTrap04(TrapFrame); HandleTrap04(TrapFrame);
break; break;
case 0x05: case 0x05:
/* Bound Range Exceeded exception */ /* Bound Range Exceeded exception */
ArpHandleTrap05(TrapFrame); HandleTrap05(TrapFrame);
break; break;
case 0x06: case 0x06:
/* Invalid Opcode exception */ /* Invalid Opcode exception */
ArpHandleTrap06(TrapFrame); HandleTrap06(TrapFrame);
break; break;
case 0x07: case 0x07:
/* Device Not Available exception */ /* Device Not Available exception */
ArpHandleTrap07(TrapFrame); HandleTrap07(TrapFrame);
break; break;
case 0x08: case 0x08:
/* Double Fault exception */ /* Double Fault exception */
ArpHandleTrap08(TrapFrame); HandleTrap08(TrapFrame);
break; break;
case 0x09: case 0x09:
/* Segment Overrun exception */ /* Segment Overrun exception */
ArpHandleTrap09(TrapFrame); HandleTrap09(TrapFrame);
break; break;
case 0x0A: case 0x0A:
/* Invalid TSS exception */ /* Invalid TSS exception */
ArpHandleTrap0A(TrapFrame); HandleTrap0A(TrapFrame);
break; break;
case 0x0B: case 0x0B:
/* Segment Not Present exception */ /* Segment Not Present exception */
ArpHandleTrap0B(TrapFrame); HandleTrap0B(TrapFrame);
break; break;
case 0x0C: case 0x0C:
/* Stack Segment Fault exception */ /* Stack Segment Fault exception */
ArpHandleTrap0C(TrapFrame); HandleTrap0C(TrapFrame);
break; break;
case 0x0D: case 0x0D:
/* General Protection Fault (GPF) exception*/ /* General Protection Fault (GPF) exception*/
ArpHandleTrap0D(TrapFrame); HandleTrap0D(TrapFrame);
break; break;
case 0x0E: case 0x0E:
/* Page Fault exception */ /* Page Fault exception */
ArpHandleTrap0E(TrapFrame); HandleTrap0E(TrapFrame);
break; break;
case 0x10: case 0x10:
/* X87 Floating-Point exception */ /* X87 Floating-Point exception */
ArpHandleTrap10(TrapFrame); HandleTrap10(TrapFrame);
break; break;
case 0x11: case 0x11:
/* Alignment Check exception */ /* Alignment Check exception */
ArpHandleTrap11(TrapFrame); HandleTrap11(TrapFrame);
break; break;
case 0x12: case 0x12:
/* Machine Check exception */ /* Machine Check exception */
ArpHandleTrap12(TrapFrame); HandleTrap12(TrapFrame);
break; break;
case 0x13: case 0x13:
/* SIMD Floating-Point exception */ /* SIMD Floating-Point exception */
ArpHandleTrap13(TrapFrame); HandleTrap13(TrapFrame);
break; break;
case 0x2A: case 0x2A:
/* Tick Count service request */ /* Tick Count service request */
ArpHandleTrap2A(TrapFrame); HandleTrap2A(TrapFrame);
break; break;
case 0x2B: case 0x2B:
/* User-mode callback return */ /* User-mode callback return */
ArpHandleTrap2B(TrapFrame); HandleTrap2B(TrapFrame);
break; break;
case 0x2C: case 0x2C:
/* Assertion raised */ /* Assertion raised */
ArpHandleTrap2C(TrapFrame); HandleTrap2C(TrapFrame);
break; break;
case 0x2D: case 0x2D:
/* Debug-Service-Request raised */ /* Debug-Service-Request raised */
ArpHandleTrap2D(TrapFrame); HandleTrap2D(TrapFrame);
break; break;
case 0x2E: case 0x2E:
/* System call service request */ /* System call service request */
ArpHandleTrap2E(TrapFrame); HandleTrap2E(TrapFrame);
break; break;
default: default:
/* Unknown/Unexpected trap */ /* Unknown/Unexpected trap */
ArpHandleTrapFF(TrapFrame); HandleTrapFF(TrapFrame);
break; break;
} }
} }
@@ -141,7 +145,7 @@ ArpDispatchTrap(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap00(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap00(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled Division-By-Zero Error (0x00)!\n"); DebugPrint(L"Handled Division-By-Zero Error (0x00)!\n");
for(;;); for(;;);
@@ -159,7 +163,7 @@ ArpHandleTrap00(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap01(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap01(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled Debug exception (0x01)!\n"); DebugPrint(L"Handled Debug exception (0x01)!\n");
for(;;); for(;;);
@@ -177,7 +181,7 @@ ArpHandleTrap01(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap02(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap02(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled Non-Maskable-Interrupt (0x02)!\n"); DebugPrint(L"Handled Non-Maskable-Interrupt (0x02)!\n");
for(;;); for(;;);
@@ -195,7 +199,7 @@ ArpHandleTrap02(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap03(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap03(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled INT3 (0x03)!\n"); DebugPrint(L"Handled INT3 (0x03)!\n");
for(;;); for(;;);
@@ -213,7 +217,7 @@ ArpHandleTrap03(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap04(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap04(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled Overflow exception (0x04)!\n"); DebugPrint(L"Handled Overflow exception (0x04)!\n");
for(;;); for(;;);
@@ -231,7 +235,7 @@ ArpHandleTrap04(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap05(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap05(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled Bound-Range-Exceeded exception (0x05)!\n"); DebugPrint(L"Handled Bound-Range-Exceeded exception (0x05)!\n");
for(;;); for(;;);
@@ -249,7 +253,7 @@ ArpHandleTrap05(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap06(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap06(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled Invalid Opcode exception (0x06)!\n"); DebugPrint(L"Handled Invalid Opcode exception (0x06)!\n");
for(;;); for(;;);
@@ -267,7 +271,7 @@ ArpHandleTrap06(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap07(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap07(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled Device Not Available exception (0x07)!\n"); DebugPrint(L"Handled Device Not Available exception (0x07)!\n");
for(;;); for(;;);
@@ -285,7 +289,7 @@ ArpHandleTrap07(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap08(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap08(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled Double-Fault exception (0x08)!\n"); DebugPrint(L"Handled Double-Fault exception (0x08)!\n");
for(;;); for(;;);
@@ -303,7 +307,7 @@ ArpHandleTrap08(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap09(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap09(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled Segment-Overrun exception (0x09)!\n"); DebugPrint(L"Handled Segment-Overrun exception (0x09)!\n");
for(;;); for(;;);
@@ -321,7 +325,7 @@ ArpHandleTrap09(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap0A(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap0A(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled Invalid-TSS exception (0x0A)!\n"); DebugPrint(L"Handled Invalid-TSS exception (0x0A)!\n");
for(;;); for(;;);
@@ -339,7 +343,7 @@ ArpHandleTrap0A(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap0B(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap0B(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled Segment-Not-Present exception (0x0B)!\n"); DebugPrint(L"Handled Segment-Not-Present exception (0x0B)!\n");
for(;;); for(;;);
@@ -357,7 +361,7 @@ ArpHandleTrap0B(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap0C(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap0C(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled Stack-Segment-Fault exception (0x0C)!\n"); DebugPrint(L"Handled Stack-Segment-Fault exception (0x0C)!\n");
for(;;); for(;;);
@@ -375,7 +379,7 @@ ArpHandleTrap0C(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap0D(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap0D(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled General-Protection-Fault (0x0D)!\n"); DebugPrint(L"Handled General-Protection-Fault (0x0D)!\n");
for(;;); for(;;);
@@ -393,7 +397,7 @@ ArpHandleTrap0D(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap0E(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap0E(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled Page-Fault exception (0x0E)!\n"); DebugPrint(L"Handled Page-Fault exception (0x0E)!\n");
for(;;); for(;;);
@@ -411,7 +415,7 @@ ArpHandleTrap0E(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap10(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap10(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled x87 Floating-Point exception (0x10)!\n"); DebugPrint(L"Handled x87 Floating-Point exception (0x10)!\n");
for(;;); for(;;);
@@ -429,7 +433,7 @@ ArpHandleTrap10(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap11(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap11(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled Alignment-Check exception (0x11)!\n"); DebugPrint(L"Handled Alignment-Check exception (0x11)!\n");
for(;;); for(;;);
@@ -447,7 +451,7 @@ ArpHandleTrap11(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap12(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap12(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled Machine-Check exception (0x12)!\n"); DebugPrint(L"Handled Machine-Check exception (0x12)!\n");
for(;;); for(;;);
@@ -465,7 +469,7 @@ ArpHandleTrap12(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap13(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap13(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled SIMD Floating-Point exception (0x13)!\n"); DebugPrint(L"Handled SIMD Floating-Point exception (0x13)!\n");
for(;;); for(;;);
@@ -483,7 +487,7 @@ ArpHandleTrap13(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap2A(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap2A(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Unhandled Tick Count service request (0x2A)!\n"); DebugPrint(L"Unhandled Tick Count service request (0x2A)!\n");
} }
@@ -500,7 +504,7 @@ ArpHandleTrap2A(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap2B(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap2B(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Unhandled Callback return service request (0x2B)!\n"); DebugPrint(L"Unhandled Callback return service request (0x2B)!\n");
} }
@@ -517,7 +521,7 @@ ArpHandleTrap2B(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap2C(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap2C(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled Assertion (0x2C)!\n"); DebugPrint(L"Handled Assertion (0x2C)!\n");
for(;;); for(;;);
@@ -535,7 +539,7 @@ ArpHandleTrap2C(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap2D(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap2D(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled Debug-Service-Request (0x2D)!\n"); DebugPrint(L"Handled Debug-Service-Request (0x2D)!\n");
for(;;); for(;;);
@@ -553,7 +557,7 @@ ArpHandleTrap2D(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap2E(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap2E(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Unhandled system call (0x2E)!\n"); DebugPrint(L"Unhandled system call (0x2E)!\n");
} }
@@ -570,8 +574,28 @@ ArpHandleTrap2E(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrapFF(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrapFF(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled Unexpected-Interrupt (0xFF)!\n"); DebugPrint(L"Handled Unexpected-Interrupt (0xFF)!\n");
for(;;); for(;;);
} }
} /* namespace */
/**
* C-linkage wrapper for dispatching the trap provided by common trap handler.
*
* @param TrapFrame
* Supplies a kernel trap frame pushed by common trap handler on the stack.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCLINK
XTCDECL
VOID
ArDispatchTrap(IN PKTRAP_FRAME TrapFrame)
{
AR::Traps::DispatchTrap(TrapFrame);
}

112
xtoskrnl/ex/exports.cc Normal file
View File

@@ -0,0 +1,112 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/ex/exports.cc
* DESCRIPTION: C-compatible API wrappers for exported kernel functions
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
*/
#include <xtos.hh>
/**
* Acquires the rundown protection for given descriptor.
*
* @param Descriptor
* Supplies a pointer to the rundown block descriptor.
*
* @return This routine returns TRUE if protection acquired successfully, or FALSE otherwise.
*
* @since NT 5.1
*/
XTFASTCALL
BOOLEAN
ExAcquireRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor)
{
return EX::Rundown::AcquireProtection(Descriptor);
}
/**
* Marks the rundown descriptor as completed.
*
* @param Descriptor
* Supplies a pointer to the descriptor to be completed.
*
* @return This routine does not return any value.
*
* @since NT 5.1
*/
XTFASTCALL
VOID
ExCompleteRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor)
{
EX::Rundown::CompleteProtection(Descriptor);
}
/**
* Initializes the rundown protection descriptor.
*
* @param Descriptor
* Supplies a pointer to the descriptor to be initialized.
*
* @return This routine does not return any value.
*
* @since NT 5.1
*/
XTFASTCALL
VOID
ExInitializeRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor)
{
EX::Rundown::InitializeProtection(Descriptor);
}
/**
* Reinitializes the rundown protection structure after it has been completed.
*
* @param Descriptor
* Supplies a pointer to the descriptor to be reinitialized.
*
* @return This routine does not return any value.
*
* @since NT 5.1
*/
XTFASTCALL
VOID
ExReInitializeRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor)
{
EX::Rundown::ReInitializeProtection(Descriptor);
}
/**
* Releases the rundown protection for given descriptor.
*
* @param Descriptor
* Supplies a pointer to the descriptor to be initialized.
*
* @return This routine does not return any value.
*
* @since NT 5.1
*/
XTFASTCALL
VOID
ExReleaseRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor)
{
EX::Rundown::ReleaseProtection(Descriptor);
}
/**
* Waits until rundown protection calls are completed.
*
* @param Descriptor
* Supplies a pointer to the rundown block descriptor.
*
* @return This routine does not return any value.
*
* @since NT 5.1
*/
XTFASTCALL
VOID
ExWaitForRundownProtectionRelease(IN PEX_RUNDOWN_REFERENCE Descriptor)
{
EX::Rundown::WaitForProtectionRelease(Descriptor);
}

View File

@@ -1,14 +1,17 @@
/** /**
* PROJECT: ExectOS * PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory * COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/ex/rundown.c * FILE: xtoskrnl/ex/rundown.cc
* DESCRIPTION: Rundown protection mechanism * DESCRIPTION: Rundown protection mechanism
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org> * DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/ */
#include <xtos.h> #include <xtos.hh>
namespace EX
{
/** /**
* Acquires the rundown protection for given descriptor. * Acquires the rundown protection for given descriptor.
* *
@@ -21,7 +24,7 @@
*/ */
XTFASTCALL XTFASTCALL
BOOLEAN BOOLEAN
ExAcquireRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor) Rundown::AcquireProtection(IN PEX_RUNDOWN_REFERENCE Descriptor)
{ {
ULONG_PTR CurrentValue, NewValue; ULONG_PTR CurrentValue, NewValue;
@@ -69,7 +72,7 @@ ExAcquireRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor)
*/ */
XTFASTCALL XTFASTCALL
VOID VOID
ExCompleteRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor) Rundown::CompleteProtection(IN PEX_RUNDOWN_REFERENCE Descriptor)
{ {
RtlAtomicExchangePointer(&Descriptor->Ptr, (PVOID)EX_RUNDOWN_ACTIVE); RtlAtomicExchangePointer(&Descriptor->Ptr, (PVOID)EX_RUNDOWN_ACTIVE);
} }
@@ -86,7 +89,7 @@ ExCompleteRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor)
*/ */
XTFASTCALL XTFASTCALL
VOID VOID
ExInitializeRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor) Rundown::InitializeProtection(IN PEX_RUNDOWN_REFERENCE Descriptor)
{ {
/* Reset descriptor counter */ /* Reset descriptor counter */
Descriptor->Count = 0; Descriptor->Count = 0;
@@ -104,7 +107,7 @@ ExInitializeRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor)
*/ */
XTFASTCALL XTFASTCALL
VOID VOID
ExReInitializeRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor) Rundown::ReInitializeProtection(IN PEX_RUNDOWN_REFERENCE Descriptor)
{ {
RtlAtomicExchangePointer(&Descriptor->Ptr, NULL); RtlAtomicExchangePointer(&Descriptor->Ptr, NULL);
} }
@@ -121,7 +124,7 @@ ExReInitializeRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor)
*/ */
XTFASTCALL XTFASTCALL
VOID VOID
ExReleaseRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor) Rundown::ReleaseProtection(IN PEX_RUNDOWN_REFERENCE Descriptor)
{ {
ULONG_PTR CurrentValue, NewValue; ULONG_PTR CurrentValue, NewValue;
PEX_RUNDOWN_WAIT_BLOCK WaitBlock; PEX_RUNDOWN_WAIT_BLOCK WaitBlock;
@@ -172,7 +175,9 @@ ExReleaseRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor)
*/ */
XTFASTCALL XTFASTCALL
VOID VOID
ExWaitForRundownProtectionRelease(IN PEX_RUNDOWN_REFERENCE Descriptor) Rundown::WaitForProtectionRelease(IN PEX_RUNDOWN_REFERENCE Descriptor)
{ {
UNIMPLEMENTED; UNIMPLEMENTED;
} }
} /* namespace */

View File

@@ -4,6 +4,7 @@
* FILE: xtoskrnl/hl/fbdev.c * FILE: xtoskrnl/hl/fbdev.c
* DESCRIPTION: FrameBuffer support * DESCRIPTION: FrameBuffer support
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org> * DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
* Aiken Harris <harraiken91@gmail.com>
*/ */
#include <xtos.h> #include <xtos.h>
@@ -24,9 +25,10 @@ XTAPI
VOID VOID
HlClearScreen(IN ULONG Color) HlClearScreen(IN ULONG Color)
{ {
SIZE_T Line, PositionX, PositionY; ULONG PositionX, PositionY;
ULONG BackgroundColor; ULONG BackgroundColor;
PULONG FrameBuf; PCHAR CurrentLine;
PULONG Pixel;
/* Make sure frame buffer is already initialized */ /* Make sure frame buffer is already initialized */
if(HlpFrameBufferData.Initialized == FALSE) if(HlpFrameBufferData.Initialized == FALSE)
@@ -35,34 +37,102 @@ HlClearScreen(IN ULONG Color)
return; return;
} }
/* Get pointer to frame buffer */ /* Convert background color and get pointer to frame buffer */
FrameBuf = HlpFrameBufferData.Address;
/* Convert background color */
BackgroundColor = HlpRGBColor(Color); BackgroundColor = HlpRGBColor(Color);
CurrentLine = HlpFrameBufferData.Address;
/* Fill the screen with a black box */ /* Fill the screen with the specified color */
for(PositionY = 0; PositionY < HlpFrameBufferData.Height; PositionY++) for(PositionY = 0; PositionY < HlpFrameBufferData.Height; PositionY++, CurrentLine += HlpFrameBufferData.Pitch)
{ {
Line = PositionY * HlpFrameBufferData.PixelsPerScanLine; /* Fill the current line with the specified color */
Pixel = (PULONG)CurrentLine;
for(PositionX = 0; PositionX < HlpFrameBufferData.Width; PositionX++) for(PositionX = 0; PositionX < HlpFrameBufferData.Width; PositionX++)
{ {
FrameBuf[Line + PositionX] = BackgroundColor; /* Set the color of the pixel */
Pixel[PositionX] = BackgroundColor;
} }
} }
} }
/** /**
* Draw a pixel on the screen at the given position and color. * Displays a single character at the current cursor position inside the scroll region.
* *
* @param PositionX * @param Character
* Supplies the X coordinate of the pixel. * Supplies the character to be displayed.
* *
* @param PositionY * @return This routine does not return any value.
* Supplies the Y coordinate of the pixel.
* *
* @param Color * @since XT 1.0
* Specifies the color of the pixel in (A)RGB format. */
XTCDECL
XTSTATUS
HlDisplayCharacter(IN WCHAR Character)
{
PSSFN_FONT_HEADER FbFont;
/* Make sure frame buffer is already initialized */
if(HlpFrameBufferData.Initialized == FALSE)
{
/* Unable to operate on non-initialized frame buffer */
return STATUS_DEVICE_NOT_READY;
}
/* Get font information */
FbFont = (PSSFN_FONT_HEADER)HlpFrameBufferData.Font;
/* Handle special characters */
switch(Character)
{
case L'\n':
/* Move cursor to the beginning of the next line */
HlpScrollRegionData.CursorX = HlpScrollRegionData.Left;
HlpScrollRegionData.CursorY += FbFont->Height;
break;
case L'\t':
/* Move cursor to the next tab stop */
HlpScrollRegionData.CursorX += (8 - (HlpScrollRegionData.CursorX - HlpScrollRegionData.Left) / FbFont->Width % 8) * FbFont->Width;
if (HlpScrollRegionData.CursorX >= HlpScrollRegionData.Right)
{
HlpScrollRegionData.CursorX = HlpScrollRegionData.Left;
HlpScrollRegionData.CursorY += FbFont->Height;
}
break;
default:
/* Draw the character */
HlpDrawCharacter(HlpScrollRegionData.CursorX, HlpScrollRegionData.CursorY, HlpScrollRegionData.TextColor, Character);
/* Advance cursor */
HlpScrollRegionData.CursorX += FbFont->Width;
/* Check if cursor reached end of line */
if(HlpScrollRegionData.CursorX >= HlpScrollRegionData.Right)
{
HlpScrollRegionData.CursorX = HlpScrollRegionData.Left;
HlpScrollRegionData.CursorY += FbFont->Height;
}
break;
}
/* Check if cursor reached end of scroll region */
if(HlpScrollRegionData.CursorY >= HlpScrollRegionData.Bottom)
{
/* Scroll one line up */
HlpScrollRegion();
HlpScrollRegionData.CursorY = HlpScrollRegionData.Bottom - FbFont->Height;
}
/* Return success */
return STATUS_SUCCESS;
}
/**
* Returns the current resolution of the frame buffer display.
*
* @param Width
* A pointer to memory area where the screen width will be stored.
*
* @param Height
* A pointer to memory area where the screen height will be stored.
* *
* @return This routine does not return any value. * @return This routine does not return any value.
* *
@@ -70,31 +140,10 @@ HlClearScreen(IN ULONG Color)
*/ */
XTAPI XTAPI
VOID VOID
HlDrawPixel(IN ULONG PositionX, HlGetFrameBufferResolution(OUT PULONG Width, OUT PULONG Height)
IN ULONG PositionY,
IN ULONG Color)
{ {
SIZE_T FrameBufferIndex; *Width = HlpFrameBufferData.Width;
*Height = HlpFrameBufferData.Height;
/* Make sure frame buffer is already initialized */
if(HlpFrameBufferData.Initialized == FALSE)
{
/* Unable to operate on non-initialized frame buffer */
return;
}
/* Make sure point is not offscreen */
if(PositionX >= HlpFrameBufferData.Width || PositionY >= HlpFrameBufferData.Height || Color > 0xFFFFFFFF)
{
/* Invalid pixel position or color given */
return;
}
/* Calculate the index of the pixel in the frame buffer memory using the provided x and y coordinates */
FrameBufferIndex = 4 * HlpFrameBufferData.PixelsPerScanLine * PositionY + 4 * PositionX;
/* Set the color of the pixel by writing to the corresponding memory location */
*((PULONG)(HlpFrameBufferData.Address + FrameBufferIndex)) = HlpRGBColor(Color);
} }
/** /**
@@ -153,7 +202,7 @@ HlInitializeFrameBuffer(VOID)
HlpFrameBufferData.Address = FrameBufferResource->Header.VirtualAddress; HlpFrameBufferData.Address = FrameBufferResource->Header.VirtualAddress;
HlpFrameBufferData.Width = FrameBufferResource->Width; HlpFrameBufferData.Width = FrameBufferResource->Width;
HlpFrameBufferData.Height = FrameBufferResource->Height; HlpFrameBufferData.Height = FrameBufferResource->Height;
HlpFrameBufferData.BitsPerPixel = FrameBufferResource->BitsPerPixel; HlpFrameBufferData.BytesPerPixel = FrameBufferResource->BitsPerPixel / 8;
HlpFrameBufferData.PixelsPerScanLine = FrameBufferResource->PixelsPerScanLine; HlpFrameBufferData.PixelsPerScanLine = FrameBufferResource->PixelsPerScanLine;
HlpFrameBufferData.Pitch = FrameBufferResource->Pitch; HlpFrameBufferData.Pitch = FrameBufferResource->Pitch;
HlpFrameBufferData.Pixels.BlueShift = FrameBufferResource->Pixels.BlueShift; HlpFrameBufferData.Pixels.BlueShift = FrameBufferResource->Pixels.BlueShift;
@@ -174,7 +223,81 @@ HlInitializeFrameBuffer(VOID)
} }
/** /**
* Puts a wide character on the framebuffer at the given position and color using the SSFN font. * Sets the scrollable region of the screen and calculates character dimensions.
*
* @param Left
* Supplies the left pixel coordinate of the scroll region.
*
* @param Top
* Supplies the top pixel coordinate of the scroll region.
*
* @param Right
* Supplies the right pixel coordinate of the scroll region.
*
* @param Bottom
* Supplies the bottom pixel coordinate of the scroll region.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTAPI
VOID
HlInitializeScrollRegion(IN ULONG Left,
IN ULONG Top,
IN ULONG Right,
IN ULONG Bottom,
IN ULONG FontColor)
{
PSSFN_FONT_HEADER FbFont;
PCHAR PixelAddress;
/* Make sure frame buffer is already initialized */
if(HlpFrameBufferData.Initialized == FALSE)
{
/* Unable to operate on non-initialized frame buffer */
return;
}
/* Store pixel coordinates of the scroll region */
HlpScrollRegionData.Left = Left;
HlpScrollRegionData.Top = Top;
HlpScrollRegionData.Right = Right;
HlpScrollRegionData.Bottom = Bottom;
/* Get font information */
FbFont = (PSSFN_FONT_HEADER)HlpFrameBufferData.Font;
/* Validate font information */
if(FbFont && FbFont->Width > 0 && FbFont->Height > 0)
{
/* Calculate character dimensions */
HlpScrollRegionData.WidthInChars = (Right - Left) / FbFont->Width;
HlpScrollRegionData.HeightInChars = (Bottom - Top) / FbFont->Height;
/* Ensure the bottom of the scroll region is an exact multiple of the font height */
HlpScrollRegionData.Bottom = HlpScrollRegionData.Top + (HlpScrollRegionData.HeightInChars * FbFont->Height);
}
else
{
/* Fallback to 0 if font info is not available or invalid */
HlpScrollRegionData.WidthInChars = 0;
HlpScrollRegionData.HeightInChars = 0;
}
/* Initialize cursor position and font color */
HlpScrollRegionData.CursorX = HlpScrollRegionData.Left;
HlpScrollRegionData.CursorY = HlpScrollRegionData.Top;
HlpScrollRegionData.TextColor = FontColor;
/* Get the background color by reading the pixel at the top-left corner of the scroll region */
PixelAddress = (PCHAR)HlpFrameBufferData.Address + (Top * HlpFrameBufferData.Pitch) +
(Left * HlpFrameBufferData.BytesPerPixel);
HlpScrollRegionData.BackgroundColor = *((PULONG)PixelAddress);
}
/**
* Draws a character on the framebuffer at the given position and color using the SSFN font.
* *
* @param PositionX * @param PositionX
* Supplies the X coordinate of the character. * Supplies the X coordinate of the character.
@@ -194,10 +317,10 @@ HlInitializeFrameBuffer(VOID)
*/ */
XTAPI XTAPI
VOID VOID
HlPutCharacter(IN ULONG PositionX, HlpDrawCharacter(IN ULONG PositionX,
IN ULONG PositionY, IN ULONG PositionY,
IN ULONG Color, IN ULONG Color,
IN WCHAR WideCharacter) IN WCHAR WideCharacter)
{ {
UINT CurrentFragment, Glyph, GlyphLimit, Index, Line, Mapping; UINT CurrentFragment, Glyph, GlyphLimit, Index, Line, Mapping;
PUCHAR Character, CharacterMapping, Fragment; PUCHAR Character, CharacterMapping, Fragment;
@@ -261,7 +384,8 @@ HlPutCharacter(IN ULONG PositionX,
} }
/* Find the glyph position on the frame buffer and set font color */ /* Find the glyph position on the frame buffer and set font color */
GlyphPixel = (UINT_PTR)HlpFrameBufferData.Address + PositionY * HlpFrameBufferData.Pitch + PositionX * 4; GlyphPixel = (UINT_PTR)HlpFrameBufferData.Address + PositionY * HlpFrameBufferData.Pitch +
PositionX * HlpFrameBufferData.BytesPerPixel;
FontColor = HlpRGBColor(Color); FontColor = HlpRGBColor(Color);
/* Check all kerning fragments */ /* Check all kerning fragments */
@@ -321,7 +445,7 @@ HlPutCharacter(IN ULONG PositionX,
} }
/* Advance pixel pointer */ /* Advance pixel pointer */
Pixel += 4; Pixel += HlpFrameBufferData.BytesPerPixel;
CurrentFragment <<= 1; CurrentFragment <<= 1;
} }
@@ -335,6 +459,52 @@ HlPutCharacter(IN ULONG PositionX,
} }
} }
/**
* Draw a pixel on the screen at the given position and color.
*
* @param PositionX
* Supplies the X coordinate of the pixel.
*
* @param PositionY
* Supplies the Y coordinate of the pixel.
*
* @param Color
* Specifies the color of the pixel in (A)RGB format.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTAPI
VOID
HlpDrawPixel(IN ULONG PositionX,
IN ULONG PositionY,
IN ULONG Color)
{
PCHAR PixelAddress;
/* Make sure frame buffer is already initialized */
if(HlpFrameBufferData.Initialized == FALSE)
{
/* Unable to operate on non-initialized frame buffer */
return;
}
/* Make sure point is not offscreen */
if(PositionX >= HlpFrameBufferData.Width || PositionY >= HlpFrameBufferData.Height || Color > 0xFFFFFFFF)
{
/* Invalid pixel position or color given */
return;
}
/* Calculate the address of the pixel in the frame buffer memory */
PixelAddress = (PCHAR)HlpFrameBufferData.Address + (PositionY * HlpFrameBufferData.Pitch) +
(PositionX * HlpFrameBufferData.BytesPerPixel);
/* Set the color of the pixel by writing to the corresponding memory location */
*((PULONG)PixelAddress) = HlpRGBColor(Color);
}
/** /**
* Converts color format from (A)RGB one expected by current FrameBuffer. * Converts color format from (A)RGB one expected by current FrameBuffer.
* *
@@ -361,3 +531,62 @@ HlpRGBColor(IN ULONG Color)
return (ULONG)((Blue << HlpFrameBufferData.Pixels.BlueShift) | (Green << HlpFrameBufferData.Pixels.GreenShift) | return (ULONG)((Blue << HlpFrameBufferData.Pixels.BlueShift) | (Green << HlpFrameBufferData.Pixels.GreenShift) |
(Red << HlpFrameBufferData.Pixels.RedShift) | (Reserved << HlpFrameBufferData.Pixels.ReservedShift)); (Red << HlpFrameBufferData.Pixels.RedShift) | (Reserved << HlpFrameBufferData.Pixels.ReservedShift));
} }
/**
* Scrolls the content of the scroll region up by one line.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTAPI
VOID
HlpScrollRegion(VOID)
{
PCHAR Destination, Source;
PSSFN_FONT_HEADER FbFont;
ULONG Line, PositionX;
ULONG LineBytes;
PULONG Pixel;
/* Make sure frame buffer is already initialized */
if(HlpFrameBufferData.Initialized == FALSE)
{
/* Unable to operate on non-initialized frame buffer */
return;
}
/* Get font information */
FbFont = (PSSFN_FONT_HEADER)HlpFrameBufferData.Font;
/* Calculate bytes per line in the scroll region */
LineBytes = (HlpScrollRegionData.Right - HlpScrollRegionData.Left) * HlpFrameBufferData.BytesPerPixel;
/* Scroll up each scan line in the scroll region */
for(Line = HlpScrollRegionData.Top; Line < HlpScrollRegionData.Bottom - FbFont->Height; Line++)
{
Destination = (PCHAR)HlpFrameBufferData.Address + Line * HlpFrameBufferData.Pitch +
HlpScrollRegionData.Left * HlpFrameBufferData.BytesPerPixel;
/* The source is one full text line (FbFont->Height) below the destination */
Source = (PCHAR)HlpFrameBufferData.Address + (Line + FbFont->Height) * HlpFrameBufferData.Pitch +
HlpScrollRegionData.Left * HlpFrameBufferData.BytesPerPixel;
/* Move each scan line in the scroll region up */
RtlMoveMemory(Destination, Source, LineBytes);
}
/* Clear the last text line */
for(Line = HlpScrollRegionData.Bottom - FbFont->Height; Line < HlpScrollRegionData.Bottom; Line++)
{
/* Get pointer to the start of the scan line to clear */
Pixel = (PULONG)((PCHAR)HlpFrameBufferData.Address + Line * HlpFrameBufferData.Pitch +
HlpScrollRegionData.Left * HlpFrameBufferData.BytesPerPixel);
/* Clear each pixel in the scan line with the background color */
for(PositionX = 0; PositionX < (HlpScrollRegionData.Right - HlpScrollRegionData.Left); PositionX++)
{
Pixel[PositionX] = HlpScrollRegionData.BackgroundColor;
}
}
}

View File

@@ -25,7 +25,10 @@ KAFFINITY HlpActiveProcessors;
APIC_MODE HlpApicMode; APIC_MODE HlpApicMode;
/* FrameBuffer information */ /* FrameBuffer information */
HAL_FRAMEBUFFER_DATA HlpFrameBufferData; HL_FRAMEBUFFER_DATA HlpFrameBufferData;
/* Scroll region information */
HL_SCROLL_REGION_DATA HlpScrollRegionData;
/* System information */ /* System information */
ACPI_SYSTEM_INFO HlpSystemInfo; ACPI_SYSTEM_INFO HlpSystemInfo;

View File

@@ -191,24 +191,23 @@ VOID
HlpInitializeApic(VOID) HlpInitializeApic(VOID)
{ {
APIC_SPURIOUS_REGISTER SpuriousRegister; APIC_SPURIOUS_REGISTER SpuriousRegister;
APIC_COMMAND_REGISTER CommandRegister;
APIC_BASE_REGISTER BaseRegister; APIC_BASE_REGISTER BaseRegister;
APIC_LVT_REGISTER LvtRegister; APIC_LVT_REGISTER LvtRegister;
ULONG CpuNumber; ULONG CpuNumber;
/* Check if this is an x2APIC compatible machine */ /* Determine APIC mode (xAPIC compatibility or x2APIC) */
if(HlpCheckX2ApicSupport()) if(HlpCheckX2ApicSupport())
{ {
/* Enable x2APIC */ /* Enable x2APIC mode */
HlpApicMode = APIC_MODE_X2APIC; HlpApicMode = APIC_MODE_X2APIC;
} }
else else
{ {
/* Use xAPIC compatibility mode */ /* Fall back to xAPIC compatibility mode */
HlpApicMode = APIC_MODE_COMPAT; HlpApicMode = APIC_MODE_COMPAT;
} }
/* Get processor number */ /* Get current processor number */
CpuNumber = KeGetCurrentProcessorNumber(); CpuNumber = KeGetCurrentProcessorNumber();
/* Enable the APIC */ /* Enable the APIC */
@@ -218,82 +217,73 @@ HlpInitializeApic(VOID)
BaseRegister.BootStrapProcessor = (CpuNumber == 0) ? 1 : 0; BaseRegister.BootStrapProcessor = (CpuNumber == 0) ? 1 : 0;
ArWriteModelSpecificRegister(APIC_LAPIC_MSR_BASE, BaseRegister.LongLong); ArWriteModelSpecificRegister(APIC_LAPIC_MSR_BASE, BaseRegister.LongLong);
/* Raise APIC task priority (TPR) to mask off all interrupts */ /* Mask all interrupts by raising Task Priority Register (TPR) */
HlWriteApicRegister(APIC_TPR, 0xFF); HlWriteApicRegister(APIC_TPR, 0xFF);
/* xAPIC compatibility mode specific initialization */ /* Perform initialization specific to xAPIC compatibility mode */
if(HlpApicMode == APIC_MODE_COMPAT) if(HlpApicMode == APIC_MODE_COMPAT)
{ {
/* Initialize Destination Format Register with flat model (not supported in x2APIC mode) */ /* Use Flat Model for destination format (not supported in x2APIC) */
HlWriteApicRegister(APIC_DFR, APIC_DF_FLAT); HlWriteApicRegister(APIC_DFR, APIC_DF_FLAT);
/* Set the logical APIC ID (read-only in x2APIC mode) */ /* Set the logical APIC ID for this processor (read-only in x2APIC) */
HlWriteApicRegister(APIC_LDR, (1UL << CpuNumber) << 24); HlWriteApicRegister(APIC_LDR, (1UL << CpuNumber) << 24);
} }
/* Set the spurious interrupt vector */ /* Configure the spurious interrupt vector */
SpuriousRegister.Long = HlReadApicRegister(APIC_SIVR); SpuriousRegister.Long = HlReadApicRegister(APIC_SIVR);
SpuriousRegister.Vector = APIC_VECTOR_SPURIOUS; SpuriousRegister.Vector = APIC_VECTOR_SPURIOUS;
SpuriousRegister.SoftwareEnable = 1; SpuriousRegister.SoftwareEnable = 1;
SpuriousRegister.CoreChecking = 0; SpuriousRegister.CoreChecking = 0;
HlWriteApicRegister(APIC_SIVR, SpuriousRegister.Long); HlWriteApicRegister(APIC_SIVR, SpuriousRegister.Long);
/* Mask LVTR_ERROR first, to prevent local APIC error */ /* Setup the LVT Error entry to deliver APIC errors on a dedicated vector */
HlWriteApicRegister(APIC_ERRLVTR, APIC_VECTOR_ERROR); HlWriteApicRegister(APIC_ERRLVTR, APIC_VECTOR_ERROR);
/* Mask TMRLVTR */ /* Program the APIC timer for periodic mode */
LvtRegister.Long = 0; LvtRegister.Long = 0;
LvtRegister.Mask = 1; LvtRegister.Mask = 1;
LvtRegister.MessageType = APIC_DM_FIXED; LvtRegister.DeliveryMode = APIC_DM_FIXED;
LvtRegister.TimerMode = 1; LvtRegister.TimerMode = 1;
LvtRegister.TriggerMode = APIC_TGM_EDGE; LvtRegister.TriggerMode = APIC_TGM_EDGE;
LvtRegister.Vector = APIC_VECTOR_PROFILE; LvtRegister.Vector = APIC_VECTOR_PROFILE;
HlWriteApicRegister(APIC_TMRLVTR, LvtRegister.Long); HlWriteApicRegister(APIC_TMRLVTR, LvtRegister.Long);
/* Mask PCLVTR */ /* Configure the performance counter overflow */
LvtRegister.Long = 0; LvtRegister.Long = 0;
LvtRegister.Mask = 0; LvtRegister.Mask = 0;
LvtRegister.MessageType = APIC_DM_FIXED; LvtRegister.DeliveryMode = APIC_DM_FIXED;
LvtRegister.TimerMode = 0; LvtRegister.TimerMode = 0;
LvtRegister.TriggerMode = APIC_TGM_EDGE; LvtRegister.TriggerMode = APIC_TGM_EDGE;
LvtRegister.Vector = APIC_VECTOR_PERF; LvtRegister.Vector = APIC_VECTOR_PERF;
HlWriteApicRegister(APIC_PCLVTR, LvtRegister.Long); HlWriteApicRegister(APIC_PCLVTR, LvtRegister.Long);
/* Mask LINT0 */ /* Configure the LINT0 pin */
LvtRegister.Long = 0; LvtRegister.Long = 0;
LvtRegister.Mask = 1; LvtRegister.Mask = 1;
LvtRegister.MessageType = APIC_DM_FIXED; LvtRegister.DeliveryMode = APIC_DM_FIXED;
LvtRegister.TimerMode = 0; LvtRegister.TimerMode = 0;
LvtRegister.TriggerMode = APIC_TGM_EDGE; LvtRegister.TriggerMode = APIC_TGM_EDGE;
LvtRegister.Vector = APIC_VECTOR_SPURIOUS; LvtRegister.Vector = APIC_VECTOR_SPURIOUS;
HlWriteApicRegister(APIC_LINT0, LvtRegister.Long); HlWriteApicRegister(APIC_LINT0, LvtRegister.Long);
/* Mask LINT1 */ /* Configure the LINT1 pin */
LvtRegister.Long = 0; LvtRegister.Long = 0;
LvtRegister.Mask = 0; LvtRegister.Mask = 0;
LvtRegister.MessageType = APIC_DM_NMI; LvtRegister.DeliveryMode = APIC_DM_NMI;
LvtRegister.TimerMode = 0; LvtRegister.TimerMode = 0;
LvtRegister.TriggerMode = APIC_TGM_EDGE; LvtRegister.TriggerMode = APIC_TGM_EDGE;
LvtRegister.Vector = APIC_VECTOR_NMI; LvtRegister.Vector = APIC_VECTOR_NMI;
HlWriteApicRegister(APIC_LINT1, LvtRegister.Long); HlWriteApicRegister(APIC_LINT1, LvtRegister.Long);
/* Mask ICR0 */ /* Register interrupt handlers */
CommandRegister.Long0 = 0;
CommandRegister.DestinationShortHand = APIC_DSH_Destination;
CommandRegister.MessageType = APIC_MT_INIT;
CommandRegister.DestinationMode = 1;
CommandRegister.TriggerMode = APIC_TGM_EDGE;
CommandRegister.Vector = APIC_VECTOR_ZERO;
HlWriteApicRegister(APIC_ICR0, CommandRegister.Long0);
/* Register interrupt handlers once the APIC initialization is done */
KeSetInterruptHandler(APIC_VECTOR_SPURIOUS, HlpHandleApicSpuriousService); KeSetInterruptHandler(APIC_VECTOR_SPURIOUS, HlpHandleApicSpuriousService);
KeSetInterruptHandler(PIC1_VECTOR_SPURIOUS, HlpHandlePicSpuriousService); KeSetInterruptHandler(PIC1_VECTOR_SPURIOUS, HlpHandlePicSpuriousService);
/* Clear errors after enabling vectors */ /* Clear any pre-existing errors */
HlWriteApicRegister(APIC_ESR, 0); HlWriteApicRegister(APIC_ESR, 0);
/* Lower APIC TPR to re-enable interrupts */ /* Re-enable all interrupts by lowering the Task Priority Register */
HlWriteApicRegister(APIC_TPR, 0x00); HlWriteApicRegister(APIC_TPR, 0x00);
} }

View File

@@ -25,6 +25,10 @@ XTCDECL
VOID VOID
ArFlushTlb(VOID); ArFlushTlb(VOID);
XTAPI
PVOID
ArGetBootStack(VOID);
XTCDECL XTCDECL
ULONG ULONG
ArGetCpuFlags(VOID); ArGetCpuFlags(VOID);
@@ -431,4 +435,8 @@ XTCDECL
VOID VOID
ArpTrap0xE1(VOID); ArpTrap0xE1(VOID);
XTCDECL
VOID
ArpTrap0xFF(VOID);
#endif /* __XTOSKRNL_AMD64_ARI_H */ #endif /* __XTOSKRNL_AMD64_ARI_H */

View File

@@ -10,6 +10,21 @@
#define __XTOSKRNL_AMD64_ASMSUP_H #define __XTOSKRNL_AMD64_ASMSUP_H
/* Control Register bit definitions */
#define CR0_PG 0x80000000
#define CR4_PGE 0x00000080
#define CR4_LA57 0x00001000
#define CR4_PCIDE 0x00020000
/* GDT selectors */
#define GDT_R0_CMCODE 0x08
#define GDT_R0_CODE 0x10
#define GDT_R0_DATA 0x18
/* MSR registers */
#define X86_MSR_EFER 0xC0000080
#define X86_MSR_EFER_LME (1 << 8)
/* KTRAP_FRAME structure offsets */ /* KTRAP_FRAME structure offsets */
#define TrapXmm0 0 #define TrapXmm0 0
#define TrapXmm1 16 #define TrapXmm1 16

View File

@@ -30,4 +30,10 @@ EXTERN UCHAR ArKernelBootStack[KERNEL_STACK_SIZE];
/* Kernel own fault stack */ /* Kernel own fault stack */
EXTERN UCHAR ArKernelFaultStack[KERNEL_STACK_SIZE]; EXTERN UCHAR ArKernelFaultStack[KERNEL_STACK_SIZE];
/* Page mapping routines for systems using 4-level paging (PML4) */
EXTERN CMMPAGEMAP_ROUTINES MmpPml4Routines;
/* Page mapping routines for systems using 5-level paging (PML5) */
EXTERN CMMPAGEMAP_ROUTINES MmpPml5Routines;
#endif /* __XTOSKRNL_AMD64_GLOBALS_H */ #endif /* __XTOSKRNL_AMD64_GLOBALS_H */

View File

@@ -55,6 +55,6 @@ KepStartKernel(VOID);
XTAPI XTAPI
VOID VOID
KepSwitchBootStack(IN ULONG_PTR Stack); KepSwitchBootStack();
#endif /* __XTOSKRNL_AMD64_KEI_H */ #endif /* __XTOSKRNL_AMD64_KEI_H */

View File

@@ -13,17 +13,33 @@
/* AMD64 Memory Manager routines forward references */ /* AMD64 Memory Manager routines forward references */
XTAPI
VOID
MmInitializePageMapSupport(VOID);
XTFASTCALL XTFASTCALL
VOID VOID
MmZeroPages(IN PVOID Address, MmZeroPages(IN PVOID Address,
IN ULONG Size); IN ULONG Size);
XTAPI XTAPI
PMMPTE VOID
MmpClearPte(PHARDWARE_PTE PtePointer);
XTAPI
BOOLEAN
MmpGetExtendedPhysicalAddressingStatus(VOID);
XTAPI
PMMP5E
MmpGetP5eAddress(PVOID Address);
XTAPI
PMMPDE
MmpGetPdeAddress(PVOID Address); MmpGetPdeAddress(PVOID Address);
XTAPI XTAPI
PMMPTE PMMPPE
MmpGetPpeAddress(PVOID Address); MmpGetPpeAddress(PVOID Address);
XTAPI XTAPI
@@ -31,7 +47,7 @@ PMMPTE
MmpGetPteAddress(PVOID Address); MmpGetPteAddress(PVOID Address);
XTAPI XTAPI
PMMPTE PMMPXE
MmpGetPxeAddress(PVOID Address); MmpGetPxeAddress(PVOID Address);
XTAPI XTAPI
@@ -40,6 +56,18 @@ MmpInitializeArchitecture(VOID);
XTAPI XTAPI
BOOLEAN BOOLEAN
MmpMemoryExtensionEnabled(VOID); MmpPteValid(PHARDWARE_PTE PtePointer);
XTAPI
VOID
MmpSetPte(PHARDWARE_PTE PtePointer,
PFN_NUMBER PageFrameNumber,
BOOLEAN Writable);
XTAPI
VOID
MmpSetPteCaching(PHARDWARE_PTE PtePointer,
BOOLEAN CacheDisable,
BOOLEAN WriteThrough);
#endif /* __XTOSKRNL_AMD64_MMI_H */ #endif /* __XTOSKRNL_AMD64_MMI_H */

18
xtoskrnl/includes/ar.hh Normal file
View File

@@ -0,0 +1,18 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/includes/ar.hh
* DESCRIPTION:
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
*/
#ifndef __XTOSKRNL_AR_HH
#define __XTOSKRNL_AR_HH
#include <xtos.hh>
#include XTOS_ARCH_HEADER(ar, cpufunc.hh)
#include XTOS_ARCH_HEADER(ar, procsup.hh)
#include XTOS_ARCH_HEADER(ar, traps.hh)
#endif /* __XTOSKRNL_AR_HH */

View File

@@ -0,0 +1,62 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/includes/ar/amd64/cpufunc.hh
* DESCRIPTION: Architecture-specific CPU control and utility functions for low-level system operations
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
*/
#ifndef __XTOSKRNL_AR_CPUFUNC_HH
#define __XTOSKRNL_AR_CPUFUNC_HH
#include <xtos.hh>
/* Architecture-specific Library */
namespace AR
{
class CpuFunc
{
public:
STATIC XTCDECL VOID ClearInterruptFlag(VOID);
STATIC XTCDECL BOOLEAN CpuId(IN OUT PCPUID_REGISTERS Registers);
STATIC XTCDECL VOID FlushTlb(VOID);
STATIC XTCDECL ULONG GetCpuFlags(VOID);
STATIC XTASSEMBLY XTCDECL ULONG_PTR GetStackPointer(VOID);
STATIC XTCDECL VOID Halt(VOID);
STATIC XTCDECL BOOLEAN InterruptsEnabled(VOID);
STATIC XTCDECL VOID InvalidateTlbEntry(IN PVOID Address);
STATIC XTCDECL VOID LoadGlobalDescriptorTable(IN PVOID Source);
STATIC XTCDECL VOID LoadInterruptDescriptorTable(IN PVOID Source);
STATIC XTCDECL VOID LoadLocalDescriptorTable(IN USHORT Source);
STATIC XTCDECL VOID LoadMxcsrRegister(IN ULONG Source);
STATIC XTCDECL VOID LoadSegment(IN USHORT Segment,
IN ULONG Source);
STATIC XTCDECL VOID LoadTaskRegister(USHORT Source);
STATIC XTCDECL VOID MemoryBarrier(VOID);
STATIC XTCDECL ULONG_PTR ReadControlRegister(IN USHORT ControlRegister);
STATIC XTCDECL ULONG_PTR ReadDebugRegister(IN USHORT DebugRegister);
STATIC XTCDECL ULONGLONG ReadGSQuadWord(ULONG Offset);
STATIC XTCDECL ULONGLONG ReadModelSpecificRegister(IN ULONG Register);
STATIC XTCDECL UINT ReadMxCsrRegister(VOID);
STATIC XTCDECL ULONGLONG ReadTimeStampCounter(VOID);
STATIC XTCDECL VOID ReadWriteBarrier(VOID);
STATIC XTCDECL VOID SetInterruptFlag(VOID);
STATIC XTCDECL VOID StoreGlobalDescriptorTable(OUT PVOID Destination);
STATIC XTCDECL VOID StoreInterruptDescriptorTable(OUT PVOID Destination);
STATIC XTCDECL VOID StoreLocalDescriptorTable(OUT PVOID Destination);
STATIC XTCDECL VOID StoreSegment(IN USHORT Segment,
OUT PVOID Destination);
STATIC XTCDECL VOID StoreTaskRegister(OUT PVOID Destination);
STATIC XTCDECL VOID WriteControlRegister(IN USHORT ControlRegister,
IN UINT_PTR Value);
STATIC XTCDECL VOID WriteDebugRegister(IN USHORT DebugRegister,
IN UINT_PTR Value);
STATIC XTCDECL VOID WriteEflagsRegister(IN UINT_PTR Value);
STATIC XTCDECL VOID WriteModelSpecificRegister(IN ULONG Register,
IN ULONGLONG Value);
STATIC XTCDECL VOID YieldProcessor(VOID);
};
}
#endif /* __XTOSKRNL_AR_CPUFUNC_HH */

View File

@@ -0,0 +1,71 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/includes/ar/amd64/procsup.hh
* DESCRIPTION: Architecture-specific routines for AMD64 processor initialization and system structure setup
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
*/
#ifndef __XTOSKRNL_AR_PROCSUP_HH
#define __XTOSKRNL_AR_PROCSUP_HH
#include <xtos.hh>
/* Architecture-specific Library */
namespace AR
{
class ProcSup
{
private:
STATIC UCHAR BootStack[KERNEL_STACK_SIZE];
STATIC UCHAR FaultStack[KERNEL_STACK_SIZE];
STATIC KGDTENTRY InitialGdt[GDT_ENTRIES];
STATIC KIDTENTRY InitialIdt[IDT_ENTRIES];
STATIC KPROCESSOR_BLOCK InitialProcessorBlock;
STATIC KTSS InitialTss;
public:
STATIC XTAPI PVOID GetBootStack(VOID);
STATIC XTAPI VOID InitializeProcessor(IN PVOID ProcessorStructures);
private:
STATIC XTAPI VOID IdentifyProcessor(VOID);
STATIC XTAPI VOID InitializeGdt(IN PKPROCESSOR_BLOCK ProcessorBlock);
STATIC XTAPI VOID InitializeIdt(IN PKPROCESSOR_BLOCK ProcessorBlock);
STATIC XTAPI VOID InitializeProcessorBlock(OUT PKPROCESSOR_BLOCK ProcessorBlock,
IN PKGDTENTRY Gdt,
IN PKIDTENTRY Idt,
IN PKTSS Tss,
IN PVOID DpcStack);
STATIC XTAPI VOID InitializeProcessorRegisters(VOID);
STATIC XTAPI VOID InitializeProcessorStructures(IN PVOID ProcessorStructures,
OUT PKGDTENTRY *Gdt,
OUT PKTSS *Tss,
OUT PKPROCESSOR_BLOCK *ProcessorBlock,
OUT PVOID *KernelBootStack,
OUT PVOID *KernelFaultStack);
STATIC XTAPI VOID InitializeSegments(VOID);
STATIC XTAPI VOID InitializeTss(IN PKPROCESSOR_BLOCK ProcessorBlock,
IN PVOID KernelBootStack,
IN PVOID KernelFaultStack);
STATIC XTAPI VOID SetGdtEntry(IN PKGDTENTRY Gdt,
IN USHORT Selector,
IN ULONG_PTR Base,
IN ULONG Limit,
IN UCHAR Type,
IN UCHAR Dpl,
IN UCHAR SegmentMode);
STATIC XTAPI VOID SetGdtEntryBase(IN PKGDTENTRY Gdt,
IN USHORT Selector,
IN ULONG_PTR Base);
STATIC XTAPI VOID SetIdtGate(IN PKIDTENTRY Idt,
IN USHORT Vector,
IN PVOID Handler,
IN USHORT Selector,
IN USHORT Ist,
IN USHORT Access);
};
}
#endif /* __XTOSKRNL_AR_PROCSUP_HH */

View File

@@ -0,0 +1,180 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/includes/ar/amd64/traps.hh
* DESCRIPTION: Trap handling routines and the dispatcher for processor exceptions
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
*/
#ifndef __XTOSKRNL_AR_TRAPS_HH
#define __XTOSKRNL_AR_TRAPS_HH
#include <xtos.hh>
/* Architecture-specific Library */
namespace AR
{
class Traps
{
public:
STATIC XTCDECL VOID DispatchTrap(IN PKTRAP_FRAME TrapFrame);
STATIC XTCDECL VOID InitializeSystemCallMsrs(VOID);
private:
STATIC XTCDECL VOID HandleSystemCall32(VOID);
STATIC XTCDECL VOID HandleSystemCall64(VOID);
STATIC XTCDECL VOID HandleTrap00(IN PKTRAP_FRAME TrapFrame);
STATIC XTCDECL VOID HandleTrap01(IN PKTRAP_FRAME TrapFrame);
STATIC XTCDECL VOID HandleTrap02(IN PKTRAP_FRAME TrapFrame);
STATIC XTCDECL VOID HandleTrap03(IN PKTRAP_FRAME TrapFrame);
STATIC XTCDECL VOID HandleTrap04(IN PKTRAP_FRAME TrapFrame);
STATIC XTCDECL VOID HandleTrap05(IN PKTRAP_FRAME TrapFrame);
STATIC XTCDECL VOID HandleTrap06(IN PKTRAP_FRAME TrapFrame);
STATIC XTCDECL VOID HandleTrap07(IN PKTRAP_FRAME TrapFrame);
STATIC XTCDECL VOID HandleTrap08(IN PKTRAP_FRAME TrapFrame);
STATIC XTCDECL VOID HandleTrap09(IN PKTRAP_FRAME TrapFrame);
STATIC XTCDECL VOID HandleTrap0A(IN PKTRAP_FRAME TrapFrame);
STATIC XTCDECL VOID HandleTrap0B(IN PKTRAP_FRAME TrapFrame);
STATIC XTCDECL VOID HandleTrap0C(IN PKTRAP_FRAME TrapFrame);
STATIC XTCDECL VOID HandleTrap0D(IN PKTRAP_FRAME TrapFrame);
STATIC XTCDECL VOID HandleTrap0E(IN PKTRAP_FRAME TrapFrame);
STATIC XTCDECL VOID HandleTrap10(IN PKTRAP_FRAME TrapFrame);
STATIC XTCDECL VOID HandleTrap11(IN PKTRAP_FRAME TrapFrame);
STATIC XTCDECL VOID HandleTrap12(IN PKTRAP_FRAME TrapFrame);
STATIC XTCDECL VOID HandleTrap13(IN PKTRAP_FRAME TrapFrame);
STATIC XTCDECL VOID HandleTrap1F(IN PKTRAP_FRAME TrapFrame);
STATIC XTCDECL VOID HandleTrap2C(IN PKTRAP_FRAME TrapFrame);
STATIC XTCDECL VOID HandleTrap2D(IN PKTRAP_FRAME TrapFrame);
STATIC XTCDECL VOID HandleTrap2F(IN PKTRAP_FRAME TrapFrame);
STATIC XTCDECL VOID HandleTrapE1(IN PKTRAP_FRAME TrapFrame);
STATIC XTCDECL VOID HandleTrapFF(IN PKTRAP_FRAME TrapFrame);
};
}
XTCLINK
XTCDECL
VOID
ArTrap0x00(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x01(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x02(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x03(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x04(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x05(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x06(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x07(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x08(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x09(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x0A(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x0B(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x0C(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x0D(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x0E(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x10(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x11(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x12(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x13(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x1F(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x2C(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x2D(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x2F(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0xE1(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0xFF(VOID);
#endif /* __XTOSKRNL_AR_TRAPS_HH */

View File

@@ -0,0 +1,61 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/includes/ar/i686/cpufunc.hh
* DESCRIPTION: Architecture-specific CPU control and utility functions for low-level system operations
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
*/
#ifndef __XTOSKRNL_AR_CPUFUNC_HH
#define __XTOSKRNL_AR_CPUFUNC_HH
#include <xtos.hh>
/* Architecture-specific Library */
namespace AR
{
class CpuFunc
{
public:
STATIC XTCDECL VOID ClearInterruptFlag(VOID);
STATIC XTCDECL BOOLEAN CpuId(IN OUT PCPUID_REGISTERS Registers);
STATIC XTCDECL VOID FlushTlb(VOID);
STATIC XTCDECL ULONG GetCpuFlags(VOID);
STATIC XTASSEMBLY XTCDECL ULONG_PTR GetStackPointer(VOID);
STATIC XTCDECL VOID Halt(VOID);
STATIC XTCDECL BOOLEAN InterruptsEnabled(VOID);
STATIC XTCDECL VOID InvalidateTlbEntry(IN PVOID Address);
STATIC XTCDECL VOID LoadGlobalDescriptorTable(IN PVOID Source);
STATIC XTCDECL VOID LoadInterruptDescriptorTable(IN PVOID Source);
STATIC XTCDECL VOID LoadLocalDescriptorTable(IN USHORT Source);
STATIC XTCDECL VOID LoadSegment(IN USHORT Segment,
IN ULONG Source);
STATIC XTCDECL VOID LoadTaskRegister(USHORT Source);
STATIC XTCDECL VOID MemoryBarrier(VOID);
STATIC XTCDECL ULONG_PTR ReadControlRegister(IN USHORT ControlRegister);
STATIC XTCDECL ULONG_PTR ReadDebugRegister(IN USHORT DebugRegister);
STATIC XTCDECL ULONG ReadFSDualWord(ULONG Offset);
STATIC XTCDECL ULONGLONG ReadModelSpecificRegister(IN ULONG Register);
STATIC XTCDECL UINT ReadMxCsrRegister(VOID);
STATIC XTCDECL ULONGLONG ReadTimeStampCounter(VOID);
STATIC XTCDECL VOID ReadWriteBarrier(VOID);
STATIC XTCDECL VOID SetInterruptFlag(VOID);
STATIC XTCDECL VOID StoreGlobalDescriptorTable(OUT PVOID Destination);
STATIC XTCDECL VOID StoreInterruptDescriptorTable(OUT PVOID Destination);
STATIC XTCDECL VOID StoreLocalDescriptorTable(OUT PVOID Destination);
STATIC XTCDECL VOID StoreSegment(IN USHORT Segment,
OUT PVOID Destination);
STATIC XTCDECL VOID StoreTaskRegister(OUT PVOID Destination);
STATIC XTCDECL VOID WriteControlRegister(IN USHORT ControlRegister,
IN UINT_PTR Value);
STATIC XTCDECL VOID WriteDebugRegister(IN USHORT DebugRegister,
IN UINT_PTR Value);
STATIC XTCDECL VOID WriteEflagsRegister(IN UINT_PTR Value);
STATIC XTCDECL VOID WriteModelSpecificRegister(IN ULONG Register,
IN ULONGLONG Value);
STATIC XTCDECL VOID YieldProcessor(VOID);
};
}
#endif /* __XTOSKRNL_AR_CPUFUNC_HH */

View File

@@ -0,0 +1,79 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/includes/ar/i686/procsup.hh
* DESCRIPTION: Architecture-specific routines for i686 processor initialization and system structure setup
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
*/
#ifndef __XTOSKRNL_AR_PROCSUP_HH
#define __XTOSKRNL_AR_PROCSUP_HH
#include <xtos.hh>
/* Architecture-specific Library */
namespace AR
{
class ProcSup
{
private:
STATIC UCHAR BootStack[KERNEL_STACK_SIZE];
STATIC UCHAR DoubleFaultTss[KTSS_IO_MAPS];
STATIC UCHAR FaultStack[KERNEL_STACK_SIZE];
STATIC KGDTENTRY InitialGdt[GDT_ENTRIES];
STATIC KIDTENTRY InitialIdt[IDT_ENTRIES];
STATIC KPROCESSOR_BLOCK InitialProcessorBlock;
STATIC KTSS InitialTss;
STATIC UCHAR NonMaskableInterruptTss[KTSS_IO_MAPS];
public:
STATIC XTAPI PVOID GetBootStack(VOID);
STATIC XTAPI VOID InitializeProcessor(IN PVOID ProcessorStructures);
private:
STATIC XTAPI VOID IdentifyProcessor(VOID);
STATIC XTAPI VOID InitializeGdt(IN PKPROCESSOR_BLOCK ProcessorBlock);
STATIC XTAPI VOID InitializeIdt(IN PKPROCESSOR_BLOCK ProcessorBlock);
STATIC XTAPI VOID InitializeProcessorBlock(OUT PKPROCESSOR_BLOCK ProcessorBlock,
IN PKGDTENTRY Gdt,
IN PKIDTENTRY Idt,
IN PKTSS Tss,
IN PVOID DpcStack);
STATIC XTAPI VOID InitializeProcessorRegisters(VOID);
STATIC XTAPI VOID InitializeProcessorStructures(IN PVOID ProcessorStructures,
OUT PKGDTENTRY *Gdt,
OUT PKTSS *Tss,
OUT PKPROCESSOR_BLOCK *ProcessorBlock,
OUT PVOID *KernelBootStack,
OUT PVOID *KernelFaultStack);
STATIC XTAPI VOID InitializeSegments(VOID);
STATIC XTAPI VOID InitializeTss(IN PKPROCESSOR_BLOCK ProcessorBlock,
IN PVOID KernelBootStack,
IN PVOID KernelFaultStack);
STATIC XTAPI VOID SetDoubleFaultTssEntry(IN PKPROCESSOR_BLOCK ProcessorBlock,
IN PVOID KernelFaultStack);
STATIC XTAPI VOID SetGdtEntry(IN PKGDTENTRY Gdt,
IN USHORT Selector,
IN ULONG_PTR Base,
IN ULONG Limit,
IN UCHAR Type,
IN UCHAR Dpl,
IN UCHAR SegmentMode);
STATIC XTAPI VOID SetGdtEntryBase(IN PKGDTENTRY Gdt,
IN USHORT Selector,
IN ULONG_PTR Base);
STATIC XTAPI VOID SetIdtGate(IN PKIDTENTRY Idt,
IN USHORT Vector,
IN PVOID Handler,
IN USHORT Selector,
IN USHORT Ist,
IN USHORT Access);
STATIC XTAPI VOID SetNonMaskableInterruptTssEntry(IN PKPROCESSOR_BLOCK ProcessorBlock,
IN PVOID KernelFaultStack);
};
}
#endif /* __XTOSKRNL_AR_PROCSUP_HH */

View File

@@ -0,0 +1,177 @@
/**@s
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/includes/ar/i686/traps.hh
* DESCRIPTION: Trap handling routines and the dispatcher for processor exceptions
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
*/
#ifndef __XTOSKRNL_AR_TRAPS_HH
#define __XTOSKRNL_AR_TRAPS_HH
#include <xtos.hh>
/* Architecture-specific Library */
namespace AR
{
class Traps
{
public:
STATIC XTCDECL VOID DispatchTrap(IN PKTRAP_FRAME TrapFrame);
private:
STATIC XTCDECL VOID HandleTrap00(IN PKTRAP_FRAME TrapFrame);
STATIC XTCDECL VOID HandleTrap01(IN PKTRAP_FRAME TrapFrame);
STATIC XTCDECL VOID HandleTrap02(IN PKTRAP_FRAME TrapFrame);
STATIC XTCDECL VOID HandleTrap03(IN PKTRAP_FRAME TrapFrame);
STATIC XTCDECL VOID HandleTrap04(IN PKTRAP_FRAME TrapFrame);
STATIC XTCDECL VOID HandleTrap05(IN PKTRAP_FRAME TrapFrame);
STATIC XTCDECL VOID HandleTrap06(IN PKTRAP_FRAME TrapFrame);
STATIC XTCDECL VOID HandleTrap07(IN PKTRAP_FRAME TrapFrame);
STATIC XTCDECL VOID HandleTrap08(IN PKTRAP_FRAME TrapFrame);
STATIC XTCDECL VOID HandleTrap09(IN PKTRAP_FRAME TrapFrame);
STATIC XTCDECL VOID HandleTrap0A(IN PKTRAP_FRAME TrapFrame);
STATIC XTCDECL VOID HandleTrap0B(IN PKTRAP_FRAME TrapFrame);
STATIC XTCDECL VOID HandleTrap0C(IN PKTRAP_FRAME TrapFrame);
STATIC XTCDECL VOID HandleTrap0D(IN PKTRAP_FRAME TrapFrame);
STATIC XTCDECL VOID HandleTrap0E(IN PKTRAP_FRAME TrapFrame);
STATIC XTCDECL VOID HandleTrap10(IN PKTRAP_FRAME TrapFrame);
STATIC XTCDECL VOID HandleTrap11(IN PKTRAP_FRAME TrapFrame);
STATIC XTCDECL VOID HandleTrap12(IN PKTRAP_FRAME TrapFrame);
STATIC XTCDECL VOID HandleTrap13(IN PKTRAP_FRAME TrapFrame);
STATIC XTCDECL VOID HandleTrap2A(IN PKTRAP_FRAME TrapFrame);
STATIC XTCDECL VOID HandleTrap2B(IN PKTRAP_FRAME TrapFrame);
STATIC XTCDECL VOID HandleTrap2C(IN PKTRAP_FRAME TrapFrame);
STATIC XTCDECL VOID HandleTrap2D(IN PKTRAP_FRAME TrapFrame);
STATIC XTCDECL VOID HandleTrap2E(IN PKTRAP_FRAME TrapFrame);
STATIC XTCDECL VOID HandleTrapFF(IN PKTRAP_FRAME TrapFrame);
};
}
XTCLINK
XTCDECL
VOID
ArTrap0x00(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x01(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x02(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x03(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x04(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x05(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x06(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x07(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x08(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x09(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x0A(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x0B(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x0C(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x0D(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x0E(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x10(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x11(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x12(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x13(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x2A(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x2B(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x2C(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x2D(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x2E(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0xFF(VOID);
#endif /* __XTOSKRNL_AR_TRAPS_HH */

16
xtoskrnl/includes/ex.hh Normal file
View File

@@ -0,0 +1,16 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/includes/ex.hh
* DESCRIPTION:
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
*/
#ifndef __XTOSKRNL_EX_HH
#define __XTOSKRNL_EX_HH
#include <xtos.hh>
#include <ex/rundown.hh>
#endif /* __XTOSKRNL_EX_HH */

View File

@@ -0,0 +1,30 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/includes/ex/rundown.hh
* DESCRIPTION: Rundown protection mechanism
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
*/
#ifndef __XTOSKRNL_EX_RUNDOWN_HH
#define __XTOSKRNL_EX_RUNDOWN_HH
#include <xtos.hh>
/* Architecture-specific Library */
namespace EX
{
class Rundown
{
public:
STATIC XTFASTCALL BOOLEAN AcquireProtection(IN PEX_RUNDOWN_REFERENCE Descriptor);
STATIC XTFASTCALL VOID CompleteProtection(IN PEX_RUNDOWN_REFERENCE Descriptor);
STATIC XTFASTCALL VOID InitializeProtection(IN PEX_RUNDOWN_REFERENCE Descriptor);
STATIC XTFASTCALL VOID ReInitializeProtection(IN PEX_RUNDOWN_REFERENCE Descriptor);
STATIC XTFASTCALL VOID ReleaseProtection(IN PEX_RUNDOWN_REFERENCE Descriptor);
STATIC XTFASTCALL VOID WaitForProtectionRelease(IN PEX_RUNDOWN_REFERENCE Descriptor);
};
}
#endif /* __XTOSKRNL_EX_RUNDOWN_HH */

View File

@@ -28,13 +28,32 @@ EXTERN KAFFINITY HlpActiveProcessors;
EXTERN APIC_MODE HlpApicMode; EXTERN APIC_MODE HlpApicMode;
/* FrameBuffer information */ /* FrameBuffer information */
EXTERN HAL_FRAMEBUFFER_DATA HlpFrameBufferData; EXTERN HL_FRAMEBUFFER_DATA HlpFrameBufferData;
/* Scroll region information */
EXTERN HL_SCROLL_REGION_DATA HlpScrollRegionData;
/* System information */ /* System information */
EXTERN ACPI_SYSTEM_INFO HlpSystemInfo; EXTERN ACPI_SYSTEM_INFO HlpSystemInfo;
/* Pointer to boot loader provided DbgPrint() routine */ /* Pointer to DbgPrint() routine */
EXTERN VOID (*KeDbgPrint)(IN PWCHAR Format, IN ...); EXTERN PKD_PRINT_ROUTINE KdPrint;
/* Kernel Debugger mode */
EXTERN KD_DEBUG_MODE KdpDebugMode;
/* Debugger I/O providers initialization routines */
EXTERN PKD_INIT_ROUTINE KdpIoProvidersInitRoutines[KDBG_PROVIDERS_COUNT];
/* List of active I/O providers */
EXTERN LIST_ENTRY KdpProviders;
/* Debugger's serial port handle */
EXTERN CPPORT KdpSerialPort;
/* Pre-defined serial port addresses */
EXTERN ULONG KdpSerialPortList[COMPORT_COUNT];
/* Kernel initialization block passed by boot loader */ /* Kernel initialization block passed by boot loader */
EXTERN PKERNEL_INITIALIZATION_BLOCK KeInitializationBlock; EXTERN PKERNEL_INITIALIZATION_BLOCK KeInitializationBlock;
@@ -75,9 +94,6 @@ EXTERN ULONG MmNumberOfPhysicalPages;
/* Old biggest free memory descriptor */ /* Old biggest free memory descriptor */
EXTERN LOADER_MEMORY_DESCRIPTOR MmOldFreeDescriptor; EXTERN LOADER_MEMORY_DESCRIPTOR MmOldFreeDescriptor;
/* Page Map Level */
EXTERN ULONG MmPageMapLevel;
/* Processor structures data (THIS IS A TEMPORARY HACK) */ /* Processor structures data (THIS IS A TEMPORARY HACK) */
EXTERN UCHAR MmProcessorStructuresData[MAXIMUM_PROCESSORS][KPROCESSOR_STRUCTURES_SIZE]; EXTERN UCHAR MmProcessorStructuresData[MAXIMUM_PROCESSORS][KPROCESSOR_STRUCTURES_SIZE];
@@ -87,8 +103,11 @@ EXTERN LOADER_MEMORY_DESCRIPTOR MmpHardwareAllocationDescriptors[MM_HARDWARE_ALL
/* Live address of kernel's hardware heap */ /* Live address of kernel's hardware heap */
EXTERN PVOID MmpHardwareHeapStart; EXTERN PVOID MmpHardwareHeapStart;
/* Architecture-specific memory extension */ /* Information about the current page map */
EXTERN BOOLEAN MmpMemoryExtension; EXTERN MMPAGEMAP_INFO MmpPageMapInfo;
/* Pointers to page map routines for the current paging mode */
EXTERN PCMMPAGEMAP_ROUTINES MmpPageMapRoutines;
/* Number of used hardware allocation descriptors */ /* Number of used hardware allocation descriptors */
EXTERN ULONG MmpUsedHardwareAllocationDescriptors; EXTERN ULONG MmpUsedHardwareAllocationDescriptors;

View File

@@ -34,11 +34,9 @@ UCHAR
HlComPortReadLsr(IN PCPPORT Port, HlComPortReadLsr(IN PCPPORT Port,
IN UCHAR Byte); IN UCHAR Byte);
XTAPI XTCDECL
VOID XTSTATUS
HlDrawPixel(IN ULONG PosX, HlDisplayCharacter(IN WCHAR Character);
IN ULONG PosY,
IN ULONG Color);
XTAPI XTAPI
XTSTATUS XTSTATUS
@@ -49,6 +47,10 @@ XTSTATUS
HlGetAcpiTable(IN ULONG Signature, HlGetAcpiTable(IN ULONG Signature,
OUT PACPI_DESCRIPTION_HEADER *AcpiTable); OUT PACPI_DESCRIPTION_HEADER *AcpiTable);
XTAPI
VOID
HlGetFrameBufferResolution(OUT PULONG Width, OUT PULONG Height);
XTFASTCALL XTFASTCALL
KRUNLEVEL KRUNLEVEL
HlGetRunLevel(VOID); HlGetRunLevel(VOID);
@@ -68,15 +70,16 @@ VOID
HlInitializeProcessor(VOID); HlInitializeProcessor(VOID);
XTAPI XTAPI
XTSTATUS VOID
HlInitializeSystem(VOID); HlInitializeScrollRegion(IN ULONG Left,
IN ULONG Top,
IN ULONG Right,
IN ULONG Bottom,
IN ULONG FontColor);
XTAPI XTAPI
VOID XTSTATUS
HlPutCharacter(IN ULONG PositionX, HlInitializeSystem(VOID);
IN ULONG PositionY,
IN ULONG Color,
IN WCHAR WideCharacter);
XTFASTCALL XTFASTCALL
VOID VOID
@@ -86,6 +89,19 @@ XTAPI
VOID VOID
HlpCacheAcpiTable(IN PACPI_DESCRIPTION_HEADER AcpiTable); HlpCacheAcpiTable(IN PACPI_DESCRIPTION_HEADER AcpiTable);
XTAPI
VOID
HlpDrawCharacter(IN ULONG PositionX,
IN ULONG PositionY,
IN ULONG Color,
IN WCHAR WideCharacter);
XTAPI
VOID
HlpDrawPixel(IN ULONG PosX,
IN ULONG PosY,
IN ULONG Color);
XTAPI XTAPI
XTSTATUS XTSTATUS
HlpInitializeAcpi(VOID); HlpInitializeAcpi(VOID);
@@ -124,6 +140,10 @@ XTAPI
ULONG ULONG
HlpRGBColor(IN ULONG Color); HlpRGBColor(IN ULONG Color);
XTAPI
VOID
HlpScrollRegion(VOID);
XTAPI XTAPI
BOOLEAN BOOLEAN
HlpValidateAcpiTable(IN PVOID Buffer, HlpValidateAcpiTable(IN PVOID Buffer,

View File

@@ -25,6 +25,10 @@ XTCDECL
VOID VOID
ArFlushTlb(VOID); ArFlushTlb(VOID);
XTAPI
PVOID
ArGetBootStack(VOID);
XTCDECL XTCDECL
ULONG ULONG
ArGetCpuFlags(VOID); ArGetCpuFlags(VOID);

View File

@@ -34,4 +34,10 @@ EXTERN UCHAR ArKernelBootStack[KERNEL_STACK_SIZE];
/* Kernel own fault stack */ /* Kernel own fault stack */
EXTERN UCHAR ArKernelFaultStack[KERNEL_STACK_SIZE]; EXTERN UCHAR ArKernelFaultStack[KERNEL_STACK_SIZE];
/* Page mapping routines for systems using 2-level paging (PML2) */
EXTERN CMMPAGEMAP_ROUTINES MmpPml2Routines;
/* Page mapping routines for systems using 3-level paging (PML3) */
EXTERN CMMPAGEMAP_ROUTINES MmpPml3Routines;
#endif /* __XTOSKRNL_I686_GLOBALS_H */ #endif /* __XTOSKRNL_I686_GLOBALS_H */

View File

@@ -55,6 +55,6 @@ KepStartKernel(VOID);
XTAPI XTAPI
VOID VOID
KepSwitchBootStack(IN ULONG_PTR Stack); KepSwitchBootStack();
#endif /* __XTOSKRNL_I686_KEI_H */ #endif /* __XTOSKRNL_I686_KEI_H */

View File

@@ -13,15 +13,31 @@
/* i686 Memory Manager routines forward references */ /* i686 Memory Manager routines forward references */
XTAPI
VOID
MmInitializePageMapSupport(VOID);
XTFASTCALL XTFASTCALL
VOID VOID
MmZeroPages(IN PVOID Address, MmZeroPages(IN PVOID Address,
IN ULONG Size); IN ULONG Size);
XTAPI XTAPI
PMMPTE VOID
MmpClearPte(PHARDWARE_PTE PtePointer);
XTAPI
BOOLEAN
MmpGetExtendedPhysicalAddressingStatus(VOID);
XTAPI
PMMPDE
MmpGetPdeAddress(PVOID Address); MmpGetPdeAddress(PVOID Address);
XTAPI
PMMPPE
MmpGetPpeAddress(PVOID Address);
XTAPI XTAPI
PMMPTE PMMPTE
MmpGetPteAddress(PVOID Address); MmpGetPteAddress(PVOID Address);
@@ -32,6 +48,34 @@ MmpInitializeArchitecture(VOID);
XTAPI XTAPI
BOOLEAN BOOLEAN
MmpMemoryExtensionEnabled(VOID); MmpPml2PteValid(PHARDWARE_PTE PtePointer);
XTAPI
VOID
MmpSetPml2Pte(PHARDWARE_PTE PtePointer,
PFN_NUMBER PageFrameNumber,
BOOLEAN Writable);
XTAPI
VOID
MmpSetPml2PteCaching(PHARDWARE_PTE PtePointer,
BOOLEAN CacheDisable,
BOOLEAN WriteThrough);
XTAPI
BOOLEAN
MmpPml3PteValid(PHARDWARE_PTE PtePointer);
XTAPI
VOID
MmpSetPml3Pte(PHARDWARE_PTE PtePointer,
PFN_NUMBER PageFrameNumber,
BOOLEAN Writable);
XTAPI
VOID
MmpSetPml3PteCaching(PHARDWARE_PTE PtePointer,
BOOLEAN CacheDisable,
BOOLEAN WriteThrough);
#endif /* __XTOSKRNL_I686_MMI_H */ #endif /* __XTOSKRNL_I686_MMI_H */

44
xtoskrnl/includes/kdi.h Normal file
View File

@@ -0,0 +1,44 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/includes/kdi.h
* DESCRIPTION: Kernel Debugger routines
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
*/
#ifndef __XTOSKRNL_KDI_H
#define __XTOSKRNL_KDI_H
#include <xtos.h>
/* Kernel Debugger routines forward references */
XTAPI
XTSTATUS
KdInitializeDebugIoProviders(VOID);
XTAPI
VOID
KdSetPrintRoutine(PVOID DebugPrintRoutine);
XTCDECL
VOID
KdpDebugPrint(PCWSTR Format, ...);
XTAPI
XTSTATUS
KdpDetectDebugPorts(VOID);
XTAPI
XTSTATUS
KdpInitializeFrameBufferProvider(VOID);
XTAPI
XTSTATUS
KdpInitializeSerialPortProvider(VOID);
XTCDECL
XTSTATUS
KdpSerialWriteCharacter(WCHAR Character);
#endif /* __XTOSKRNL_KDI_H */

View File

@@ -21,6 +21,15 @@ XTAPI
VOID VOID
KeClearTimer(IN PKTIMER Timer); KeClearTimer(IN PKTIMER Timer);
XTAPI
SYSTEM_FIRMWARE_TYPE
KeGetFirmwareType(VOID);
XTAPI
XTSTATUS
KeGetKernelParameter(IN PCWSTR ParameterName,
OUT PCWSTR *Parameter);
XTAPI XTAPI
VOID VOID
KeHaltSystem(VOID); KeHaltSystem(VOID);

View File

@@ -15,6 +15,7 @@
/* Kernel specific headers */ /* Kernel specific headers */
#include "globals.h" #include "globals.h"
#include "hli.h" #include "hli.h"
#include "kdi.h"
#include "kei.h" #include "kei.h"
#include "mmi.h" #include "mmi.h"
#include "poi.h" #include "poi.h"

30
xtoskrnl/includes/xtos.hh Normal file
View File

@@ -0,0 +1,30 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/includes/xtos.hh
* DESCRIPTION: Top level header for the XT kernel
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
*/
/* Preprocessor macro for including arch-specific headers */
#define XTOS_ARCH_HEADER(subsystem, header) STRINGIFY(subsystem/_ARCH/header)
/* Temporary includes for C code compatibility */
extern "C" {
/* XT Development Kit */
#include <xtkmapi.h>
/* XT OS version */
#include <xtver.h>
/* Kernel specific headers */
#include <xtos.h>
}
#include <ar.hh>
#include <ex.hh>

192
xtoskrnl/kd/dbginit.c Normal file
View File

@@ -0,0 +1,192 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/kd/dbginit.c
* DESCRIPTION: Kernel Debugger initialization
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
*/
#include <xtos.h>
/**
* Initializes the kernel's debugger I/O providers.
*
* @return This routine returns a status code.
*
* @since XT 1.0
*/
XTAPI
XTSTATUS
KdInitializeDebugIoProviders(VOID)
{
ULONG Index;
XTSTATUS ProviderStatus, Status;
/* Initialize debug providers list */
RtlInitializeListHead(&KdpProviders);
RtlZeroMemory(&KdpDebugMode, sizeof(KD_DEBUG_MODE));
KdpDetectDebugPorts();
/* Iterate over providers initialization routines */
for(Index = 0; Index < KDBG_PROVIDERS_COUNT; Index++)
{
/* Initialize provider */
ProviderStatus = KdpIoProvidersInitRoutines[Index]();
Status = (Status || ProviderStatus);
}
/* Initialize debug print routine */
KdSetPrintRoutine(KdpDebugPrint);
/* Return status code */
return Status;
}
/**
* Configures the kernel's debug print routine by setting a new output handler.
*
* @param DebugPrintRoutine
* Supplies a pointer to the new debug print routine.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTAPI
VOID
KdSetPrintRoutine(PVOID DebugPrintRoutine)
{
/* Set debug print routine */
KdPrint = DebugPrintRoutine;
}
/**
* Detects and enables the kernel's debug ports based on the 'DEBUG' parameter passed to the kernel.
*
* @return This routine returns a status code.
*
* @since XT 1.0
*/
XTAPI
XTSTATUS
KdpDetectDebugPorts(VOID)
{
PCWSTR DebugOption;
XTSTATUS Status;
/* Get debug parameter */
Status = KeGetKernelParameter(L"DEBUG", &DebugOption);
if(Status != STATUS_SUCCESS)
{
/* Debug parameter not found, disable debugging */
KdpDebugMode.Enabled = FALSE;
return Status;
}
/* Skip parameter name and check if it is set */
DebugOption += 5;
if(*DebugOption != L'=')
{
/* Debug parameter not set, disable debugging */
KdpDebugMode.Enabled = FALSE;
return STATUS_INVALID_PARAMETER;
}
/* Skip '=' symbol */
DebugOption++;
/* Iterate over all debug ports */
while(*DebugOption != L'\0' && *DebugOption != L' ')
{
/* Check what port is set for debugging */
if(RtlCompareWideStringInsensitive(DebugOption, L"COM", 3) == 0)
{
/* Enable serial port debugging mode */
KdpDebugMode.Mode |= DEBUG_PROVIDER_COMPORT;
/* Read COM port number */
DebugOption += 3;
while(*DebugOption >= '0' && *DebugOption <= '9')
{
/* Get port number */
KdpDebugMode.ComPortNumber *= 10;
KdpDebugMode.ComPortNumber += *DebugOption - '0';
DebugOption++;
}
/* Check if custom COM port address supplied */
if(KdpDebugMode.ComPortNumber == 0 && RtlCompareWideStringInsensitive(DebugOption, L":0x", 3) == 0)
{
/* COM port address provided */
DebugOption += 3;
while((*DebugOption >= '0' && *DebugOption <= '9') ||
(*DebugOption >= 'A' && *DebugOption <= 'F') ||
(*DebugOption >= 'a' && *DebugOption <= 'f'))
{
/* Get port address */
KdpDebugMode.ComPortAddress *= 16;
if(*DebugOption >= '0' && *DebugOption <= '9')
{
KdpDebugMode.ComPortAddress += *DebugOption - '0';
}
else if(*DebugOption >= 'A' && *DebugOption <= 'F')
{
KdpDebugMode.ComPortAddress += *DebugOption - 'A' + 10;
}
else if(*DebugOption >= 'a' && *DebugOption <= 'f')
{
KdpDebugMode.ComPortAddress += *DebugOption - 'a' + 10;
}
DebugOption++;
}
}
/* Look for additional COM port parameters */
if(*DebugOption == ',')
{
/* Baud rate provided */
DebugOption++;
while(*DebugOption >= '0' && *DebugOption <= '9')
{
/* Get baud rate */
KdpDebugMode.ComPortBaudRate *= 10;
KdpDebugMode.ComPortBaudRate += *DebugOption - '0';
DebugOption++;
}
}
}
else if(RtlCompareWideStringInsensitive(DebugOption, L"SCREEN", 6) == 0)
{
/* Enable framebuffer debugging mode */
KdpDebugMode.Mode |= DEBUG_PROVIDER_FRAMEBUFFER;
DebugOption += 6;
}
else if(*DebugOption == L';')
{
/* Skip separator */
DebugOption++;
}
else
{
/* Invalid debug option, skip it */
while(*DebugOption != L'\0' && *DebugOption != L' ' && *DebugOption != L';')
{
/* Advance debug option */
DebugOption++;
}
}
}
/* Ensure at least one debug port is enabled */
if(KdpDebugMode.Mode != 0)
{
/* Enable debugging */
KdpDebugMode.Enabled = TRUE;
}
/* Return success */
return STATUS_SUCCESS;
}

175
xtoskrnl/kd/dbgio.c Normal file
View File

@@ -0,0 +1,175 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/kd/dbgio.c
* DESCRIPTION: Kernel Debugger I/O routines
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
*/
#include <xtos.h>
/**
* Prints a formatted string using the configured debug output providers.
*
* @param Format
* Supplies the format string.
*
* @param ...
* Supplies the variable argument list.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCDECL
VOID
KdpDebugPrint(PCWSTR Format, ...)
{
VA_LIST Arguments;
PLIST_ENTRY DispatchTableEntry;
PKD_DISPATCH_TABLE DispatchTable;
/* Initialise the va_list */
VA_START(Arguments, Format);
DispatchTableEntry = KdpProviders.Flink;
while(DispatchTableEntry != &KdpProviders)
{
DispatchTable = CONTAIN_RECORD(DispatchTableEntry, KD_DISPATCH_TABLE, ListEntry);
RtlFormatWideString(&DispatchTable->PrintContext, (PWCHAR)Format, Arguments);
DispatchTableEntry = DispatchTableEntry->Flink;
}
/* Clean up the va_list */
VA_END(Arguments);
}
/**
* Initializes the framebuffer device provider for the kernel debugger.
*
* @return This routine returns a status code.
*
* @since XT 1.0
*/
XTAPI
XTSTATUS
KdpInitializeFrameBufferProvider(VOID)
{
STATIC KD_DISPATCH_TABLE DispatchTable;
ULONG Height, Width;
/* Check if framebuffer provider is enabled */
if(KdpDebugMode.Enabled && (KdpDebugMode.Mode & DEBUG_PROVIDER_FRAMEBUFFER) == 0)
{
/* Screen is not enabled, no need to initialize provider */
return STATUS_PORT_DISCONNECTED;
}
/* Ensure frame buffer is initialized and get FB resolution */
HlInitializeFrameBuffer();
HlGetFrameBufferResolution(&Width, &Height);
/* Print debug message */
DebugPrint(L"Initializing debug console at framebuffer device (%lu x %lu)\n", Width, Height);
/* Initialize scroll region to full screen and white font color */
HlInitializeScrollRegion(0, 0, Width - 1, Height - 1, 0xFFFFFFFF);
/* Initialize screen dispatch table */
DispatchTable.PrintContext.WriteWideCharacter = HlDisplayCharacter;
RtlInsertHeadList(&KdpProviders, &DispatchTable.ListEntry);
/* Return success */
return STATUS_SUCCESS;
}
/**
* Initializes the serial port device provider for the kernel debugger.
*
* @return This routine returns a status code.
*
* @since XT 1.0
*/
XTAPI
XTSTATUS
KdpInitializeSerialPortProvider(VOID)
{
STATIC KD_DISPATCH_TABLE DispatchTable;
XTSTATUS Status;
/* Check if serial port provider is enabled */
if(KdpDebugMode.Enabled && (KdpDebugMode.Mode & DEBUG_PROVIDER_COMPORT) == 0)
{
/* Serial port is not enabled, no need to initialize provider */
return STATUS_PORT_DISCONNECTED;
}
/* Check if custom COM port address supplied */
if(!KdpDebugMode.ComPortAddress)
{
/* We support only a pre-defined number of ports */
if(KdpDebugMode.ComPortNumber > COMPORT_COUNT)
{
/* Fail if wrong/unsupported port used */
return STATUS_INVALID_PARAMETER;
}
/* Check if serial port is set */
if(KdpDebugMode.ComPortNumber == 0)
{
/* Use COM1 by default */
KdpDebugMode.ComPortNumber = 1;
}
/* Set custom port address based on the port number and print debug message */
KdpDebugMode.ComPortAddress = KdpSerialPortList[KdpDebugMode.ComPortNumber - 1];
DebugPrint(L"Initializing debug console at serial port (COM%lu, BaudRate: %lu)\n",
KdpDebugMode.ComPortNumber, KdpDebugMode.ComPortBaudRate);
}
else
{
/* Custom port address supplied, print debug message */
DebugPrint(L"Initializing debug console at serial port (0x%lX, BaudRate: %lu)\n",
KdpDebugMode.ComPortAddress, KdpDebugMode.ComPortBaudRate);
}
/* Initialize COM port */
Status = HlInitializeComPort(&KdpSerialPort, UlongToPtr(KdpDebugMode.ComPortAddress), KdpDebugMode.ComPortBaudRate);
if(Status != STATUS_SUCCESS)
{
/* Serial port initialization failed */
return Status;
}
/* Initialize serial port dispatch table */
DispatchTable.PrintContext.WriteWideCharacter = KdpSerialWriteCharacter;
RtlInsertHeadList(&KdpProviders, &DispatchTable.ListEntry);
/* Return success */
return STATUS_SUCCESS;
}
/**
* Writes a character to the serial console.
*
* @param Character
* The integer promotion of the character to be written.
*
* @return This routine returns a status code.
*
* @since XT 1.0
*/
XTCDECL
XTSTATUS
KdpSerialWriteCharacter(WCHAR Character)
{
WCHAR Buffer[2];
/* Write character to the serial console */
Buffer[0] = Character;
Buffer[1] = 0;
return HlComPortPutByte(&KdpSerialPort, Buffer[0]);
}

31
xtoskrnl/kd/globals.c Normal file
View File

@@ -0,0 +1,31 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/kd/globals.c
* DESCRIPTION: Architecture independent global variables related to KD subsystem
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
*/
#include <xtos.h>
/* Pointer to DbgPrint() routine */
PKD_PRINT_ROUTINE KdPrint = NULL;
/* Kernel Debugger mode */
KD_DEBUG_MODE KdpDebugMode;
/* Debugger I/O providers initialization routines */
PKD_INIT_ROUTINE KdpIoProvidersInitRoutines[KDBG_PROVIDERS_COUNT] = {
KdpInitializeFrameBufferProvider,
KdpInitializeSerialPortProvider
};
/* List of active I/O providers */
LIST_ENTRY KdpProviders;
/* Debugger's serial port handle */
CPPORT KdpSerialPort;
/* Pre-defined serial port addresses */
ULONG KdpSerialPortList[COMPORT_COUNT] = COMPORT_ADDRESS;

View File

@@ -52,6 +52,9 @@ KepInitializeMachine(VOID)
/* Initialize processor */ /* Initialize processor */
HlInitializeProcessor(); HlInitializeProcessor();
/* Initialize page map support */
MmInitializePageMapSupport();
} }
/** /**
@@ -97,7 +100,7 @@ KepStartKernel(VOID)
CurrentProcess->Quantum = MAXCHAR; CurrentProcess->Quantum = MAXCHAR;
/* Initialize Idle thread */ /* Initialize Idle thread */
KeInitializeThread(CurrentProcess, CurrentThread, NULL, NULL, NULL, NULL, NULL, ArKernelBootStack, TRUE); KeInitializeThread(CurrentProcess, CurrentThread, NULL, NULL, NULL, NULL, NULL, ArGetBootStack(), TRUE);
CurrentThread->NextProcessor = Prcb->CpuNumber; CurrentThread->NextProcessor = Prcb->CpuNumber;
CurrentThread->Priority = THREAD_HIGH_PRIORITY; CurrentThread->Priority = THREAD_HIGH_PRIORITY;
CurrentThread->State = Running; CurrentThread->State = Running;
@@ -111,16 +114,19 @@ KepStartKernel(VOID)
} }
/** /**
* Switches to a new kernel boot stack. * Switches execution to a new boot stack and transfers control to the KepStartKernel() routine.
* *
* @return This routine does not return any value * @return This routine does not return any value.
* *
* @since XT 1.0 * @since XT 1.0
*/ */
XTAPI XTAPI
VOID VOID
KepSwitchBootStack(IN ULONG_PTR Stack) KepSwitchBootStack()
{ {
/* Calculate the stack pointer at the top of the buffer, ensuring it is properly aligned as required by the ABI */
ULONG_PTR Stack = ((ULONG_PTR)ArGetBootStack() + KERNEL_STACK_SIZE) & ~(STACK_ALIGNMENT - 1);
/* Discard old stack frame, switch stack and jump to KepStartKernel() */ /* Discard old stack frame, switch stack and jump to KepStartKernel() */
__asm__ volatile("mov %0, %%rdx\n" __asm__ volatile("mov %0, %%rdx\n"
"xor %%rbp, %%rbp\n" "xor %%rbp, %%rbp\n"
@@ -130,5 +136,6 @@ KepSwitchBootStack(IN ULONG_PTR Stack)
: :
: "m" (Stack), : "m" (Stack),
"i" (FLOATING_SAVE_AREA_SIZE | KEXCEPTION_FRAME_SIZE | KSWITCH_FRAME_SIZE | KRETURN_ADDRESS_SIZE), "i" (FLOATING_SAVE_AREA_SIZE | KEXCEPTION_FRAME_SIZE | KSWITCH_FRAME_SIZE | KRETURN_ADDRESS_SIZE),
"p" (KepStartKernel)); "p" (KepStartKernel)
: "rdx", "rbp", "rsp", "memory");
} }

Some files were not shown because too many files have changed in this diff Show More