Compare commits
1 Commits
memmgr
...
b74c31f17c
| Author | SHA1 | Date | |
|---|---|---|---|
|
b74c31f17c
|
@@ -53,9 +53,8 @@ implement any environment subsystem to support applications that are strictly wr
|
|||||||
* NT drivers compatibility layer
|
* NT drivers compatibility layer
|
||||||
|
|
||||||
# Requirements
|
# Requirements
|
||||||
ExectOS is currently in a very early stage of development, so its specific requirements are not fully defined yet.
|
ExectOS is in very early development stage, thus its requirements have been not specified yet. However according to its
|
||||||
However, based on the current design, it requires modern EFI hardware. You cannot boot ExectOS on a legacy BIOS
|
design, it requires a modern EFI enabled hardware. It is not possible currently to boot ExectOS on a legacy BIOS.
|
||||||
right now, but there are plans to add BIOS support in the future.
|
|
||||||
|
|
||||||
# Source structure
|
# Source structure
|
||||||
| Directory | Description |
|
| Directory | Description |
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
# XT Boot Sector
|
# XT Boot Sector
|
||||||
PROJECT(BOOTSECT)
|
PROJECT(BOOTSECT)
|
||||||
|
|
||||||
add_definitions("-DARCH_ESP_SOURCE=\\\"${ARCH}/cpu.S\\\"")
|
|
||||||
|
|
||||||
# Compile boot sectors
|
# Compile boot sectors
|
||||||
compile_bootsector(mbrboot ${BOOTSECT_SOURCE_DIR}/mbrboot.S 0x7C00 Start)
|
compile_bootsector(mbrboot ${BOOTSECT_SOURCE_DIR}/mbrboot.S 0x7C00 Start)
|
||||||
compile_bootsector(espboot ${BOOTSECT_SOURCE_DIR}/espboot.S 0x7C00 Start)
|
compile_bootsector(espboot ${BOOTSECT_SOURCE_DIR}/espboot.S 0x7C00 Start)
|
||||||
|
|||||||
@@ -1,144 +0,0 @@
|
|||||||
/**
|
|
||||||
* PROJECT: ExectOS
|
|
||||||
* COPYRIGHT: See COPYING.md in the top level directory
|
|
||||||
* FILE: boot/bootsect/amd64/cpu.S
|
|
||||||
* DESCRIPTION: Low-level support for CPU initialization
|
|
||||||
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
BuildPageMap:
|
|
||||||
/* Generate page map for first 1GB of memory */
|
|
||||||
pushaw
|
|
||||||
pushw %es
|
|
||||||
cld
|
|
||||||
movw $(0x1000 / 16), %ax
|
|
||||||
movw %ax, %es
|
|
||||||
xorw %di, %di
|
|
||||||
movl $(0x2000 | 0x07), %eax
|
|
||||||
stosl
|
|
||||||
xorl %eax, %eax
|
|
||||||
movw $1021, %cx
|
|
||||||
rep stosl
|
|
||||||
movw $(0x2000 / 16), %ax
|
|
||||||
movw %ax, %es
|
|
||||||
xorw %di, %di
|
|
||||||
movl $(0x3000 | 0x07), %eax
|
|
||||||
stosl
|
|
||||||
xorl %eax, %eax
|
|
||||||
movw $1021, %cx
|
|
||||||
rep stosl
|
|
||||||
movw $(0x3000 / 16), %ax
|
|
||||||
movw %ax, %es
|
|
||||||
xorw %di, %di
|
|
||||||
movw $512, %cx
|
|
||||||
movl $0x00000083, %eax
|
|
||||||
.BuildPageMapLoop:
|
|
||||||
/* Identity map 512 pages of 2MB */
|
|
||||||
movl %eax, %es:(%di)
|
|
||||||
addl $2097152, %eax
|
|
||||||
addw $0x08, %di
|
|
||||||
loop .BuildPageMapLoop
|
|
||||||
popw %es
|
|
||||||
popaw
|
|
||||||
ret
|
|
||||||
|
|
||||||
InitializeCpu:
|
|
||||||
/* Check if CPU supports CPUID, long mode and PAE */
|
|
||||||
pushal
|
|
||||||
pushfl
|
|
||||||
popl %eax
|
|
||||||
movl %eax, %ebx
|
|
||||||
xorl $0x00200000, %eax
|
|
||||||
pushl %eax
|
|
||||||
popfl
|
|
||||||
pushfl
|
|
||||||
popl %eax
|
|
||||||
cmpl %ebx, %eax
|
|
||||||
je CpuUnsupported
|
|
||||||
movl $0x01, %eax
|
|
||||||
cpuid
|
|
||||||
testl $0x40, %edx
|
|
||||||
jz CpuUnsupported
|
|
||||||
movl $0x80000000, %eax
|
|
||||||
cpuid
|
|
||||||
cmpl $0x80000000, %eax
|
|
||||||
jbe CpuUnsupported
|
|
||||||
movl $0x80000001, %eax
|
|
||||||
cpuid
|
|
||||||
testl $0x20000000, %edx
|
|
||||||
jz CpuUnsupported
|
|
||||||
popal
|
|
||||||
call LoadGdt
|
|
||||||
ret
|
|
||||||
|
|
||||||
LoadGdt:
|
|
||||||
/* Load Global Descriptor Table */
|
|
||||||
lgdt .GdtPointer
|
|
||||||
ret
|
|
||||||
|
|
||||||
RunStage2:
|
|
||||||
/* Switch to long mode and pass control to Stage 2 */
|
|
||||||
call BuildPageMap
|
|
||||||
call ParseExecutableHeader
|
|
||||||
xorl %edx, %edx
|
|
||||||
pushl %edx
|
|
||||||
pushl %eax
|
|
||||||
cli
|
|
||||||
xorw %ax, %ax
|
|
||||||
movw %ax, %ds
|
|
||||||
movw %ax, %es
|
|
||||||
movw %ax, %fs
|
|
||||||
movw %ax, %gs
|
|
||||||
movw %ax, %ss
|
|
||||||
movl %cr4, %eax
|
|
||||||
orl $0x00A0, %eax
|
|
||||||
movl %eax, %cr4
|
|
||||||
movl $0x00001000, %eax
|
|
||||||
movl %eax, %cr3
|
|
||||||
movl $0xC0000080, %ecx
|
|
||||||
rdmsr
|
|
||||||
orl $0x00000100, %eax
|
|
||||||
wrmsr
|
|
||||||
movl %cr0, %eax
|
|
||||||
orl $0x80000001, %eax
|
|
||||||
movl %eax, %cr0
|
|
||||||
ljmp $0x10, $.Stage2LongMode
|
|
||||||
.code64
|
|
||||||
.Stage2LongMode:
|
|
||||||
/* Set segments and stack, then jump to Stage 2 */
|
|
||||||
movw $0x18, %ax
|
|
||||||
movw %ax, %ds
|
|
||||||
movw %ax, %es
|
|
||||||
movw %ax, %ss
|
|
||||||
xorw %ax, %ax
|
|
||||||
movw %ax, %fs
|
|
||||||
movw %ax, %gs
|
|
||||||
popq %rax
|
|
||||||
xorq %rbx, %rbx
|
|
||||||
xorq %rcx, %rcx
|
|
||||||
xorq %rdx, %rdx
|
|
||||||
xorq %rsi, %rsi
|
|
||||||
xorq %rdi, %rdi
|
|
||||||
xorq %rbp, %rbp
|
|
||||||
jmp *%rax
|
|
||||||
|
|
||||||
.code16
|
|
||||||
.GdtDescriptor:
|
|
||||||
/* Global Descriptor Table */
|
|
||||||
.quad 0x0000000000000000
|
|
||||||
.quad 0x0000000000000000
|
|
||||||
.quad 0x00AF9A000000FFFF
|
|
||||||
.quad 0x00CF92000000FFFF
|
|
||||||
.quad 0x00009E000000FFFF
|
|
||||||
.quad 0x000092000000FFFF
|
|
||||||
.quad 0x00CF9B000000FFFF
|
|
||||||
|
|
||||||
.GdtPointer:
|
|
||||||
/* Pointer to Global Descriptor Table */
|
|
||||||
.word .GdtPointer - .GdtDescriptor - 1
|
|
||||||
.long .GdtDescriptor
|
|
||||||
|
|
||||||
.Stage2FileName:
|
|
||||||
/* Name of Stage 2 executable file */
|
|
||||||
.ascii "BOOTX64 EFI"
|
|
||||||
@@ -121,15 +121,15 @@ VerifyBiosParameterBlock:
|
|||||||
ja FsError
|
ja FsError
|
||||||
|
|
||||||
ReadExtraCode:
|
ReadExtraCode:
|
||||||
/* Read second VBR sector with extra boot code (3 sectors starting from sector 2) */
|
/* Read second VBR sector with extra boot code */
|
||||||
movl HiddenSectors - Start(%bp), %eax
|
movl HiddenSectors - Start(%bp), %eax
|
||||||
addl $0x02, %eax
|
addl $0x02, %eax
|
||||||
movw $0x03, %cx
|
movw $0x01, %cx
|
||||||
xorw %bx, %bx
|
xorw %bx, %bx
|
||||||
movw %bx, %es
|
movw %bx, %es
|
||||||
movw $0x7E00, %bx
|
movw $0x7E00, %bx
|
||||||
call ReadSectors
|
call ReadSectors
|
||||||
jmp StartExtraCode
|
jmp StartSectors
|
||||||
|
|
||||||
ReadSectors:
|
ReadSectors:
|
||||||
/* Check for extended BIOS functions and use it only if available */
|
/* Check for extended BIOS functions and use it only if available */
|
||||||
@@ -139,22 +139,18 @@ ReadSectors:
|
|||||||
movw $0x55AA, %bx
|
movw $0x55AA, %bx
|
||||||
movb DriveNumber - Start(%bp), %dl
|
movb DriveNumber - Start(%bp), %dl
|
||||||
int $0x13
|
int $0x13
|
||||||
jc .ReadCHS
|
jc ReadCHS
|
||||||
cmpw $0xAA55, %bx
|
cmpw $0xAA55, %bx
|
||||||
jne .ReadCHS
|
jne ReadCHS
|
||||||
testb $0x01, %cl
|
testb $0x01, %cl
|
||||||
jz .ReadCHS
|
jz ReadCHS
|
||||||
|
|
||||||
/* Verify drive size and determine whether to use CHS or LBA */
|
/* Verify drive size and determine whether to use CHS or LBA */
|
||||||
cmpl %edi, %eax
|
cmpl %edi, %eax
|
||||||
jnb .ReadLBA
|
jnb ReadLBA
|
||||||
|
|
||||||
.ReadCHS:
|
ReadCHS:
|
||||||
/* Read sectors using CHS */
|
/* Read sectors using CHS */
|
||||||
popal
|
|
||||||
|
|
||||||
.CHSLoop:
|
|
||||||
/* Read sector by sector using CHS */
|
|
||||||
pushw %cx
|
pushw %cx
|
||||||
pushal
|
pushal
|
||||||
xorl %edx, %edx
|
xorl %edx, %edx
|
||||||
@@ -180,11 +176,11 @@ ReadSectors:
|
|||||||
movw %es, %dx
|
movw %es, %dx
|
||||||
addw $0x20, %dx
|
addw $0x20, %dx
|
||||||
movw %dx, %es
|
movw %dx, %es
|
||||||
loop .CHSLoop
|
loop ReadCHS
|
||||||
popw %es
|
popw %es
|
||||||
ret
|
ret
|
||||||
|
|
||||||
.ReadLBA:
|
ReadLBA:
|
||||||
/* Prepare DAP packet and read sectors using LBA */
|
/* Prepare DAP packet and read sectors using LBA */
|
||||||
popal
|
popal
|
||||||
pushw %cx
|
pushw %cx
|
||||||
@@ -213,19 +209,19 @@ ReadSectors:
|
|||||||
movw %dx, %es
|
movw %dx, %es
|
||||||
popw %bx
|
popw %bx
|
||||||
subw %si, %cx
|
subw %si, %cx
|
||||||
jnz .ReadLBA
|
jnz ReadLBA
|
||||||
popw %es
|
popw %es
|
||||||
ret
|
ret
|
||||||
|
|
||||||
DiskError:
|
DiskError:
|
||||||
/* Display disk error message and reboot */
|
/* Display disk error message and reboot */
|
||||||
movw $.MsgDiskError, %si
|
movw $msgDiskError, %si
|
||||||
call Print
|
call Print
|
||||||
jmp Reboot
|
jmp Reboot
|
||||||
|
|
||||||
FsError:
|
FsError:
|
||||||
/* Display FS error message and reboot */
|
/* Display FS error message and reboot */
|
||||||
movw $.MsgFsError, %si
|
movw $msgFsError, %si
|
||||||
call Print
|
call Print
|
||||||
jmp Reboot
|
jmp Reboot
|
||||||
|
|
||||||
@@ -233,297 +229,48 @@ Print:
|
|||||||
/* Simple routine to print messages */
|
/* Simple routine to print messages */
|
||||||
lodsb
|
lodsb
|
||||||
orb %al, %al
|
orb %al, %al
|
||||||
jz .DonePrint
|
jz DonePrint
|
||||||
movb $0x0E, %ah
|
movb $0x0E, %ah
|
||||||
movw $0x07, %bx
|
movw $0x07, %bx
|
||||||
int $0x10
|
int $0x10
|
||||||
jmp Print
|
jmp Print
|
||||||
.DonePrint:
|
DonePrint:
|
||||||
retw
|
retw
|
||||||
|
|
||||||
Reboot:
|
Reboot:
|
||||||
/* Display a message, wait for a key press and reboot */
|
/* Display a message, wait for a key press and reboot */
|
||||||
movw $.MsgAnyKey, %si
|
movw $msgAnyKey, %si
|
||||||
call Print
|
call Print
|
||||||
xorw %ax, %ax
|
xorw %ax, %ax
|
||||||
int $0x16
|
int $0x16
|
||||||
int $0x19
|
int $0x19
|
||||||
|
|
||||||
.MsgAnyKey:
|
msgAnyKey:
|
||||||
.ascii "Press any key to restart...\r\n\0"
|
.ascii "Press any key to restart\r\n"
|
||||||
|
|
||||||
.MsgDiskError:
|
msgDiskError:
|
||||||
.ascii "Disk error!\r\n\0"
|
.ascii "Disk error\r\n"
|
||||||
|
|
||||||
.MsgFsError:
|
msgFsError:
|
||||||
.ascii "File system error!\r\n\0"
|
.ascii "File system error\r\n"
|
||||||
|
|
||||||
/* Fill the rest of the VBR with zeros and add VBR signature at the end */
|
/* Fill the rest of the VBR with zeros and add VBR signature at the end */
|
||||||
.fill (510 - (. - Start)), 1, 0
|
.fill (510 - (. - Start)), 1, 0
|
||||||
.word 0xAA55
|
.word 0xAA55
|
||||||
|
|
||||||
|
|
||||||
StartExtraCode:
|
StartSectors:
|
||||||
/* Load XTLDR file from disk */
|
/* Print message */
|
||||||
call LoadStage2
|
movw $msgUnavailable, %si
|
||||||
|
|
||||||
/* Enable A20 gate */
|
|
||||||
call EnableA20
|
|
||||||
|
|
||||||
/* Call architecture specific initialization code */
|
|
||||||
call InitializeCpu
|
|
||||||
|
|
||||||
/* Jump to Stage2 */
|
|
||||||
call RunStage2
|
|
||||||
|
|
||||||
Clear8042:
|
|
||||||
/* Clear 8042 PS/2 buffer */
|
|
||||||
nop
|
|
||||||
nop
|
|
||||||
nop
|
|
||||||
nop
|
|
||||||
inb $0x64, %al
|
|
||||||
cmpb $0xff, %al
|
|
||||||
je .Clear8042_Done
|
|
||||||
testb $0x02, %al
|
|
||||||
jnz Clear8042
|
|
||||||
.Clear8042_Done:
|
|
||||||
ret
|
|
||||||
|
|
||||||
EnableA20:
|
|
||||||
/* Enable A20 gate */
|
|
||||||
pushaw
|
|
||||||
call Clear8042
|
|
||||||
movb $0xD1, %al
|
|
||||||
outb %al, $0x64
|
|
||||||
call Clear8042
|
|
||||||
movb $0xDF, %al
|
|
||||||
outb %al, $0x60
|
|
||||||
call Clear8042
|
|
||||||
movb $0xFF, %al
|
|
||||||
outb %al, $0x64
|
|
||||||
call Clear8042
|
|
||||||
popaw
|
|
||||||
ret
|
|
||||||
|
|
||||||
FindFatEntry:
|
|
||||||
/* Find a file or directory in the FAT table */
|
|
||||||
pushw %bx
|
|
||||||
pushw %cx
|
|
||||||
pushw %dx
|
|
||||||
pushw %si
|
|
||||||
pushw %di
|
|
||||||
.FindFatCluster:
|
|
||||||
/* Find FAT32 cluster holding the entry */
|
|
||||||
cmp $0x0FFFFFF8, %eax
|
|
||||||
jae .FindEntryFail
|
|
||||||
pushl %eax
|
|
||||||
movw $0x0200, %bx
|
|
||||||
movw %bx, %es
|
|
||||||
call ReadCluster
|
|
||||||
popl %eax
|
|
||||||
movb SectorsPerCluster - Start(%bp), %cl
|
|
||||||
shlw $0x04, %cx
|
|
||||||
xorw %di, %di
|
|
||||||
.FindEntryLoop:
|
|
||||||
/* Find the entry */
|
|
||||||
movb %es:(%di), %al
|
|
||||||
cmpb $0x00, %al
|
|
||||||
je .FindEntryFail
|
|
||||||
cmpb $0xE5, %al
|
|
||||||
je .FindSkipEntry
|
|
||||||
movb %es:0x0B(%di), %ah
|
|
||||||
cmpb $0x0F, %ah
|
|
||||||
je .FindSkipEntry
|
|
||||||
pushw %di
|
|
||||||
pushw %si
|
|
||||||
pushw %cx
|
|
||||||
movw $0x0B, %cx
|
|
||||||
repe cmpsb
|
|
||||||
popw %cx
|
|
||||||
popw %si
|
|
||||||
popw %di
|
|
||||||
jnz .FindSkipEntry
|
|
||||||
movw %es:0x1A(%di), %ax
|
|
||||||
movw %es:0x14(%di), %dx
|
|
||||||
shll $0x10, %edx
|
|
||||||
orl %edx, %eax
|
|
||||||
clc
|
|
||||||
jmp .FindEntryDone
|
|
||||||
.FindSkipEntry:
|
|
||||||
/* Skip to the next entry */
|
|
||||||
addw $0x20, %di
|
|
||||||
decw %cx
|
|
||||||
jnz .FindEntryLoop
|
|
||||||
call GetFatEntry
|
|
||||||
jmp .FindFatCluster
|
|
||||||
.FindEntryFail:
|
|
||||||
/* Error, file/directory not found */
|
|
||||||
stc
|
|
||||||
.FindEntryDone:
|
|
||||||
/* Clean up the stack */
|
|
||||||
popw %di
|
|
||||||
popw %si
|
|
||||||
popw %dx
|
|
||||||
popw %cx
|
|
||||||
popw %bx
|
|
||||||
ret
|
|
||||||
|
|
||||||
GetFatEntry:
|
|
||||||
/* Get FAT32 sector and offset from FAT table */
|
|
||||||
shll $0x02, %eax
|
|
||||||
movl %eax, %ecx
|
|
||||||
xorl %edx, %edx
|
|
||||||
movzwl BytesPerSector - Start(%bp), %ebx
|
|
||||||
pushl %ebx
|
|
||||||
divl %ebx
|
|
||||||
movzwl ReservedSectors - Start(%bp), %ebx
|
|
||||||
addl %ebx, %eax
|
|
||||||
movl HiddenSectors - Start(%bp), %ebx
|
|
||||||
addl %ebx, %eax
|
|
||||||
popl %ebx
|
|
||||||
decl %ebx
|
|
||||||
andl %ebx, %ecx
|
|
||||||
movzwl ExtendedFlags - Start(%bp), %ebx
|
|
||||||
andw $0x0F, %bx
|
|
||||||
jz LoadFatSector
|
|
||||||
cmpb FatCopies - Start(%bp), %bl
|
|
||||||
jae FsError
|
|
||||||
pushl %eax
|
|
||||||
movl BigSectorsPerFat - Start(%bp), %eax
|
|
||||||
mull %ebx
|
|
||||||
popl %edx
|
|
||||||
addl %edx, %eax
|
|
||||||
|
|
||||||
LoadFatSector:
|
|
||||||
/* Load FAT32 sector from disk */
|
|
||||||
pushl %ecx
|
|
||||||
movw $0x9000, %bx
|
|
||||||
movw %bx, %es
|
|
||||||
cmpl %esi, %eax
|
|
||||||
je .LoadFatSectorDone
|
|
||||||
movl %eax, %esi
|
|
||||||
xorw %bx, %bx
|
|
||||||
movw $0x01, %cx
|
|
||||||
call ReadSectors
|
|
||||||
.LoadFatSectorDone:
|
|
||||||
/* Clean up the stack */
|
|
||||||
popl %ecx
|
|
||||||
movl %es:(%ecx), %eax
|
|
||||||
andl $0x0FFFFFFF, %eax
|
|
||||||
ret
|
|
||||||
|
|
||||||
LoadStage2:
|
|
||||||
/* Load Stage2 executable, first find file in the path */
|
|
||||||
movl $0xFFFFFFFF, %esi
|
|
||||||
pushl %esi
|
|
||||||
movl 0x7C2C, %eax
|
|
||||||
movw $.EfiDirName, %si
|
|
||||||
call FindFatEntry
|
|
||||||
jc Stage2NotLoaded
|
|
||||||
movw $.BootDirName, %si
|
|
||||||
call FindFatEntry
|
|
||||||
jc Stage2NotLoaded
|
|
||||||
movw $.Stage2FileName, %si
|
|
||||||
call FindFatEntry
|
|
||||||
jc Stage2NotLoaded
|
|
||||||
popl %esi
|
|
||||||
/* Load XTLDR file from disk */
|
|
||||||
cmpl $0x02, %eax
|
|
||||||
jb FileNotFound
|
|
||||||
cmpl $0x0FFFFFF8, %eax
|
|
||||||
jae FileNotFound
|
|
||||||
movw $(0xF800 / 16), %bx
|
|
||||||
movw %bx, %es
|
|
||||||
.LoadStage2Loop:
|
|
||||||
/* Load file data from disk */
|
|
||||||
pushl %eax
|
|
||||||
xorw %bx, %bx
|
|
||||||
pushw %es
|
|
||||||
call ReadCluster
|
|
||||||
popw %es
|
|
||||||
xorw %bx, %bx
|
|
||||||
movb SectorsPerCluster - Start(%bp), %bl
|
|
||||||
shlw $0x05, %bx
|
|
||||||
movw %es, %ax
|
|
||||||
addw %bx, %ax
|
|
||||||
movw %ax, %es
|
|
||||||
popl %eax
|
|
||||||
pushw %es
|
|
||||||
call GetFatEntry
|
|
||||||
popw %es
|
|
||||||
cmpl $0x0FFFFFF8, %eax
|
|
||||||
jb .LoadStage2Loop
|
|
||||||
ret
|
|
||||||
|
|
||||||
ParseExecutableHeader:
|
|
||||||
/* Parse Stage2 PE/COFF executable header */
|
|
||||||
pushw %es
|
|
||||||
movw $(0xF800 / 16), %ax
|
|
||||||
movw %ax, %es
|
|
||||||
movl %es:60, %eax
|
|
||||||
addl $(4 + 20), %eax
|
|
||||||
movl %es:16(%eax), %eax
|
|
||||||
addl $0xF800, %eax
|
|
||||||
popw %es
|
|
||||||
ret
|
|
||||||
|
|
||||||
ReadCluster:
|
|
||||||
/* Read FAT32 cluster from disk */
|
|
||||||
decl %eax
|
|
||||||
decl %eax
|
|
||||||
xorl %edx, %edx
|
|
||||||
movzbl SectorsPerCluster - Start(%bp), %ebx
|
|
||||||
mull %ebx
|
|
||||||
pushl %eax
|
|
||||||
xorl %edx, %edx
|
|
||||||
movzbl FatCopies - Start(%bp), %eax
|
|
||||||
mull BigSectorsPerFat - Start(%bp)
|
|
||||||
movzwl ReservedSectors - Start(%bp), %ebx
|
|
||||||
addl %ebx, %eax
|
|
||||||
addl HiddenSectors - Start(%bp), %eax
|
|
||||||
popl %ebx
|
|
||||||
addl %ebx, %eax
|
|
||||||
xorw %bx, %bx
|
|
||||||
movzbw SectorsPerCluster - Start(%bp), %cx
|
|
||||||
call ReadSectors
|
|
||||||
ret
|
|
||||||
|
|
||||||
/* Include architecture specific code */
|
|
||||||
.include ARCH_ESP_SOURCE
|
|
||||||
|
|
||||||
CpuUnsupported:
|
|
||||||
/* Display CPU unsupported message and reboot */
|
|
||||||
popal
|
|
||||||
movw $.MsgCpuUnsupported, %si
|
|
||||||
call Print
|
call Print
|
||||||
jmp Reboot
|
|
||||||
|
|
||||||
FileNotFound:
|
/* Wait for key press and reboot */
|
||||||
/* Display XTLDR not found message and reboot */
|
xorw %ax, %ax
|
||||||
movw $.MsgXtLdrNotFound, %si
|
int $0x16
|
||||||
call Print
|
int $0x19
|
||||||
jmp Reboot
|
|
||||||
|
|
||||||
Stage2NotLoaded:
|
msgUnavailable:
|
||||||
/* Clean up the stack and display XTLDR not found message and reboot */
|
.ascii "XTLDR requires EFI-based system!\r\nPress any key to restart\r\n"
|
||||||
popl %esi
|
|
||||||
jmp FileNotFound
|
|
||||||
|
|
||||||
.BootDirName:
|
/* Fill the rest of the extra VBR with zeros */
|
||||||
/* Boot directory name */
|
.fill (1024 - (. - Start)), 1, 0
|
||||||
.ascii "BOOT "
|
|
||||||
|
|
||||||
.EfiDirName:
|
|
||||||
/* EFI directory name */
|
|
||||||
.ascii "EFI "
|
|
||||||
|
|
||||||
.MsgCpuUnsupported:
|
|
||||||
.ascii "CPU not supported!\r\n\0"
|
|
||||||
|
|
||||||
.MsgXtLdrNotFound:
|
|
||||||
.ascii "XTLDR Stage2 not found!\r\n\0"
|
|
||||||
|
|
||||||
/* Fill the rest of the extra VBR with zeros and add signature */
|
|
||||||
.fill (2043 - (. - Start)), 1, 0
|
|
||||||
.ascii "XTLDR"
|
|
||||||
|
|||||||
@@ -1,124 +0,0 @@
|
|||||||
/**
|
|
||||||
* PROJECT: ExectOS
|
|
||||||
* COPYRIGHT: See COPYING.md in the top level directory
|
|
||||||
* FILE: boot/bootsect/i686/cpu.S
|
|
||||||
* DESCRIPTION: Low-level support for CPU initialization
|
|
||||||
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
BuildPageMap:
|
|
||||||
/* Generate page map for first 16MB of memory */
|
|
||||||
pushaw
|
|
||||||
pushw %es
|
|
||||||
cld
|
|
||||||
movw $(0x1000 >> 0x04), %ax
|
|
||||||
movw %ax, %es
|
|
||||||
xorw %di, %di
|
|
||||||
movl $(0x2000 | 0x03), %eax
|
|
||||||
stosl
|
|
||||||
movl $(0x3000 | 0x03), %eax
|
|
||||||
stosl
|
|
||||||
movl $(0x4000 | 0x03), %eax
|
|
||||||
stosl
|
|
||||||
movl $(0x5000 | 0x03), %eax
|
|
||||||
stosl
|
|
||||||
xorl %eax, %eax
|
|
||||||
movw $(1024 - 4), %cx
|
|
||||||
rep stosl
|
|
||||||
movl $0x00000003, %eax
|
|
||||||
movl $4, %edx
|
|
||||||
movw $(0x2000 >> 0x04), %bx
|
|
||||||
.BuildPageMapLoop:
|
|
||||||
/* Identity map 1024 pages of 4KB */
|
|
||||||
movw %bx, %es
|
|
||||||
xorw %di, %di
|
|
||||||
pushl %edx
|
|
||||||
movw $1024, %cx
|
|
||||||
.FillPageMapTable:
|
|
||||||
/* Fill the page table */
|
|
||||||
movl %eax, %es:(%di)
|
|
||||||
addl $4096, %eax
|
|
||||||
addw $0x04, %di
|
|
||||||
loop .FillPageMapTable
|
|
||||||
popl %edx
|
|
||||||
addw $(0x1000 >> 0x04), %bx
|
|
||||||
decl %edx
|
|
||||||
jnz .BuildPageMapLoop
|
|
||||||
popw %es
|
|
||||||
popaw
|
|
||||||
ret
|
|
||||||
|
|
||||||
InitializeCpu:
|
|
||||||
/* Check if CPU supports CPUID */
|
|
||||||
pushal
|
|
||||||
pushfl
|
|
||||||
popl %eax
|
|
||||||
movl %eax, %ebx
|
|
||||||
xorl $0x00200000, %eax
|
|
||||||
pushl %eax
|
|
||||||
popfl
|
|
||||||
pushfl
|
|
||||||
popl %eax
|
|
||||||
cmpl %ebx, %eax
|
|
||||||
je CpuUnsupported
|
|
||||||
popal
|
|
||||||
call LoadGdt
|
|
||||||
ret
|
|
||||||
|
|
||||||
LoadGdt:
|
|
||||||
/* Load Global Descriptor Table */
|
|
||||||
lgdt .GdtPointer
|
|
||||||
ret
|
|
||||||
|
|
||||||
RunStage2:
|
|
||||||
/* Switch to protected mode and pass control to Stage 2 */
|
|
||||||
call BuildPageMap
|
|
||||||
call ParseExecutableHeader
|
|
||||||
pushl %eax
|
|
||||||
cli
|
|
||||||
movl %cr0, %eax
|
|
||||||
orl $0x01, %eax
|
|
||||||
movl %eax, %cr0
|
|
||||||
ljmp $0x08, $.Stage2ProtectedMode
|
|
||||||
.code32
|
|
||||||
.Stage2ProtectedMode:
|
|
||||||
/* Set segments and stack, then jump to Stage 2 */
|
|
||||||
movw $0x10, %ax
|
|
||||||
movw %ax, %ds
|
|
||||||
movw %ax, %es
|
|
||||||
movw %ax, %ss
|
|
||||||
xorw %ax, %ax
|
|
||||||
movw %ax, %fs
|
|
||||||
movw %ax, %gs
|
|
||||||
popl %eax
|
|
||||||
xorl %ebx, %ebx
|
|
||||||
xorl %ecx, %ecx
|
|
||||||
xorl %edx, %edx
|
|
||||||
xorl %esi, %esi
|
|
||||||
xorl %edi, %edi
|
|
||||||
xorl %ebp, %ebp
|
|
||||||
movl $0x1000, %ebx
|
|
||||||
movl %ebx, %cr3
|
|
||||||
movl %cr0, %ebx
|
|
||||||
orl $0x80000000, %ebx
|
|
||||||
movl %ebx, %cr0
|
|
||||||
jmp *%eax
|
|
||||||
|
|
||||||
.code16
|
|
||||||
.GdtDescriptor:
|
|
||||||
/* Global Descriptor Table */
|
|
||||||
.quad 0x0000000000000000
|
|
||||||
.quad 0x00CF9A000000FFFF
|
|
||||||
.quad 0x00CF92000000FFFF
|
|
||||||
.quad 0x00009E000000FFFF
|
|
||||||
.quad 0x000092000000FFFF
|
|
||||||
|
|
||||||
.GdtPointer:
|
|
||||||
/* Pointer to Global Descriptor Table */
|
|
||||||
.word .GdtPointer - .GdtDescriptor - 1
|
|
||||||
.long .GdtDescriptor
|
|
||||||
|
|
||||||
.Stage2FileName:
|
|
||||||
/* Name of Stage 2 executable file */
|
|
||||||
.ascii "BOOTIA32EFI"
|
|
||||||
@@ -4,7 +4,6 @@
|
|||||||
* FILE: boot/bootsect/amd64/mbrboot.S
|
* FILE: boot/bootsect/amd64/mbrboot.S
|
||||||
* DESCRIPTION: XT Boot Loader MBR boot code
|
* DESCRIPTION: XT Boot Loader MBR boot code
|
||||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||||
* Aiken Harris <aiken@codingworkshop.eu.org>
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
.text
|
.text
|
||||||
@@ -42,7 +41,7 @@ RealStart:
|
|||||||
movw %ax, %ss
|
movw %ax, %ss
|
||||||
|
|
||||||
/* Print welcome message */
|
/* Print welcome message */
|
||||||
leaw .MsgXtosBoot, %si
|
leaw msgXtosBoot, %si
|
||||||
call Print
|
call Print
|
||||||
|
|
||||||
/* Get BIOS boot drive and partition table offset */
|
/* Get BIOS boot drive and partition table offset */
|
||||||
@@ -91,19 +90,19 @@ PartitionFound:
|
|||||||
|
|
||||||
InvalidSignature:
|
InvalidSignature:
|
||||||
/* Invalid signature error */
|
/* Invalid signature error */
|
||||||
leaw .MsgInvalidSignature, %si
|
leaw msgInvalidSignature, %si
|
||||||
call Print
|
call Print
|
||||||
jmp HaltSystem
|
jmp HaltSystem
|
||||||
|
|
||||||
PartitionNotFound:
|
PartitionNotFound:
|
||||||
/* Active partition not found error */
|
/* Active partition not found error */
|
||||||
leaw .MsgPartitionNotFound, %si
|
leaw msgPartitionNotFound, %si
|
||||||
call Print
|
call Print
|
||||||
jmp HaltSystem
|
jmp HaltSystem
|
||||||
|
|
||||||
VbrReadFail:
|
VbrReadFail:
|
||||||
/* VBR read failed error */
|
/* VBR read failed error */
|
||||||
leaw .MsgVbrReadFail, %si
|
leaw msgVbrReadFail, %si
|
||||||
call Print
|
call Print
|
||||||
jmp HaltSystem
|
jmp HaltSystem
|
||||||
|
|
||||||
@@ -137,16 +136,16 @@ DonePrint:
|
|||||||
/* Storage for the LBA start */
|
/* Storage for the LBA start */
|
||||||
.long 0
|
.long 0
|
||||||
|
|
||||||
.MsgInvalidSignature:
|
msgInvalidSignature:
|
||||||
.asciz "Invalid partition signature!"
|
.asciz "Invalid partition signature!"
|
||||||
|
|
||||||
.MsgPartitionNotFound:
|
msgPartitionNotFound:
|
||||||
.asciz "Bootable partition not found!"
|
.asciz "Bootable partition not found!"
|
||||||
|
|
||||||
.MsgVbrReadFail:
|
msgVbrReadFail:
|
||||||
.asciz "VBR read failed!"
|
.asciz "VBR read failed!"
|
||||||
|
|
||||||
.MsgXtosBoot:
|
msgXtosBoot:
|
||||||
.asciz "Starting XTOS boot loader...\r\n"
|
.asciz "Starting XTOS boot loader...\r\n"
|
||||||
|
|
||||||
/* Fill the rest of the MBR with zeros and add MBR signature at the end */
|
/* Fill the rest of the MBR with zeros and add MBR signature at the end */
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ list(APPEND LIBXTLDR_SOURCE
|
|||||||
# Specify list of source code files
|
# Specify list of source code files
|
||||||
list(APPEND XTLDR_SOURCE
|
list(APPEND XTLDR_SOURCE
|
||||||
${XTLDR_SOURCE_DIR}/arch/${ARCH}/memory.cc
|
${XTLDR_SOURCE_DIR}/arch/${ARCH}/memory.cc
|
||||||
${XTLDR_SOURCE_DIR}/biosutil.cc
|
|
||||||
${XTLDR_SOURCE_DIR}/bootutil.cc
|
${XTLDR_SOURCE_DIR}/bootutil.cc
|
||||||
${XTLDR_SOURCE_DIR}/config.cc
|
${XTLDR_SOURCE_DIR}/config.cc
|
||||||
${XTLDR_SOURCE_DIR}/console.cc
|
${XTLDR_SOURCE_DIR}/console.cc
|
||||||
@@ -39,9 +38,6 @@ add_executable(xtldr ${XTLDR_SOURCE})
|
|||||||
# Add linker libraries
|
# Add linker libraries
|
||||||
target_link_libraries(xtldr libxtos)
|
target_link_libraries(xtldr libxtos)
|
||||||
|
|
||||||
# Add linker options
|
|
||||||
target_link_options(xtldr PRIVATE /ALIGN:512)
|
|
||||||
|
|
||||||
# Set proper binary name and install target
|
# Set proper binary name and install target
|
||||||
if(ARCH STREQUAL "i686")
|
if(ARCH STREQUAL "i686")
|
||||||
set(BINARY_NAME "bootia32")
|
set(BINARY_NAME "bootia32")
|
||||||
@@ -53,6 +49,5 @@ set_install_target(xtldr efi/boot)
|
|||||||
|
|
||||||
# Set loader entrypoint and subsystem
|
# Set loader entrypoint and subsystem
|
||||||
set_entrypoint(xtldr "BlStartXtLoader")
|
set_entrypoint(xtldr "BlStartXtLoader")
|
||||||
set_imagebase(xtldr ${BASEADDRESS_XTLDR})
|
|
||||||
set_linker_map(xtldr TRUE)
|
set_linker_map(xtldr TRUE)
|
||||||
set_subsystem(xtldr efi_application)
|
set_subsystem(xtldr efi_application)
|
||||||
|
|||||||
@@ -44,14 +44,6 @@ Memory::BuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
|
|||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add new memory mapping for the page map itself */
|
|
||||||
Status = MapVirtualMemory(PageMap, (ULONGLONG)NULLPTR, Address, 1, LoaderMemoryData);
|
|
||||||
if(Status != STATUS_EFI_SUCCESS)
|
|
||||||
{
|
|
||||||
/* Memory mapping failure */
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Assign and zero-fill memory used by page mappings */
|
/* Assign and zero-fill memory used by page mappings */
|
||||||
PageMap->PtePointer = (PVOID)(UINT_PTR)Address;
|
PageMap->PtePointer = (PVOID)(UINT_PTR)Address;
|
||||||
RTL::Memory::ZeroMemory(PageMap->PtePointer, EFI_PAGE_SIZE);
|
RTL::Memory::ZeroMemory(PageMap->PtePointer, EFI_PAGE_SIZE);
|
||||||
@@ -65,7 +57,7 @@ Memory::BuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Map the trampoline code area */
|
/* Map the trampoline code area */
|
||||||
Status = MapVirtualMemory(PageMap, MM_TRAMPOLINE_ADDRESS,MM_TRAMPOLINE_ADDRESS,
|
Status = MapVirtualMemory(PageMap, (PVOID)MM_TRAMPOLINE_ADDRESS,(PVOID)MM_TRAMPOLINE_ADDRESS,
|
||||||
1, LoaderFirmwareTemporary);
|
1, LoaderFirmwareTemporary);
|
||||||
if(Status != STATUS_EFI_SUCCESS)
|
if(Status != STATUS_EFI_SUCCESS)
|
||||||
{
|
{
|
||||||
@@ -82,7 +74,7 @@ Memory::BuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
|
|||||||
ModuleInfo = CONTAIN_RECORD(ModulesListEntry, XTBL_MODULE_INFO, Flink);
|
ModuleInfo = CONTAIN_RECORD(ModulesListEntry, XTBL_MODULE_INFO, Flink);
|
||||||
|
|
||||||
/* Map module code */
|
/* Map module code */
|
||||||
Status = MapVirtualMemory(PageMap, (ULONGLONG)ModuleInfo->ModuleBase, (ULONGLONG)ModuleInfo->ModuleBase,
|
Status = MapVirtualMemory(PageMap, ModuleInfo->ModuleBase, ModuleInfo->ModuleBase,
|
||||||
EFI_SIZE_TO_PAGES(ModuleInfo->ModuleSize), LoaderFirmwareTemporary);
|
EFI_SIZE_TO_PAGES(ModuleInfo->ModuleSize), LoaderFirmwareTemporary);
|
||||||
|
|
||||||
/* Check if mapping succeeded */
|
/* Check if mapping succeeded */
|
||||||
@@ -103,7 +95,7 @@ Memory::BuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
|
|||||||
if(LoaderBase && LoaderSize)
|
if(LoaderBase && LoaderSize)
|
||||||
{
|
{
|
||||||
/* Map boot loader code as well */
|
/* Map boot loader code as well */
|
||||||
Status = MapVirtualMemory(PageMap, (ULONGLONG)LoaderBase, (ULONGLONG)LoaderBase,
|
Status = MapVirtualMemory(PageMap, LoaderBase, LoaderBase,
|
||||||
EFI_SIZE_TO_PAGES(LoaderSize), LoaderFirmwareTemporary);
|
EFI_SIZE_TO_PAGES(LoaderSize), LoaderFirmwareTemporary);
|
||||||
if(Status != STATUS_EFI_SUCCESS)
|
if(Status != STATUS_EFI_SUCCESS)
|
||||||
{
|
{
|
||||||
@@ -201,7 +193,7 @@ Memory::GetNextPageTable(IN PXTBL_PAGE_MAPPING PageMap,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Add new memory mapping */
|
/* Add new memory mapping */
|
||||||
Status = MapVirtualMemory(PageMap, (ULONGLONG)NULLPTR, Address, 1, LoaderMemoryData);
|
Status = MapVirtualMemory(PageMap, NULLPTR, (PVOID)(UINT_PTR)Address, 1, LoaderMemoryData);
|
||||||
if(Status != STATUS_EFI_SUCCESS)
|
if(Status != STATUS_EFI_SUCCESS)
|
||||||
{
|
{
|
||||||
/* Memory mapping failure */
|
/* Memory mapping failure */
|
||||||
@@ -247,9 +239,9 @@ Memory::GetNextPageTable(IN PXTBL_PAGE_MAPPING PageMap,
|
|||||||
XTCDECL
|
XTCDECL
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
Memory::MapPage(IN PXTBL_PAGE_MAPPING PageMap,
|
Memory::MapPage(IN PXTBL_PAGE_MAPPING PageMap,
|
||||||
IN ULONGLONG VirtualAddress,
|
IN ULONG_PTR VirtualAddress,
|
||||||
IN ULONGLONG PhysicalAddress,
|
IN ULONG_PTR PhysicalAddress,
|
||||||
IN ULONGLONG NumberOfPages)
|
IN ULONG NumberOfPages)
|
||||||
{
|
{
|
||||||
PVOID Pml1, Pml2, Pml3, Pml4, Pml5;
|
PVOID Pml1, Pml2, Pml3, Pml4, Pml5;
|
||||||
SIZE_T Pml1Entry, Pml2Entry, Pml3Entry, Pml4Entry, Pml5Entry;
|
SIZE_T Pml1Entry, Pml2Entry, Pml3Entry, Pml4Entry, Pml5Entry;
|
||||||
|
|||||||
@@ -93,7 +93,8 @@ Memory::BuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Map the trampoline code area */
|
/* Map the trampoline code area */
|
||||||
Status = MapVirtualMemory(PageMap, MM_TRAMPOLINE_ADDRESS, MM_TRAMPOLINE_ADDRESS, 1, LoaderFirmwareTemporary);
|
Status = MapVirtualMemory(PageMap, (PVOID)MM_TRAMPOLINE_ADDRESS,(PVOID)MM_TRAMPOLINE_ADDRESS,
|
||||||
|
1, LoaderFirmwareTemporary);
|
||||||
if(Status != STATUS_EFI_SUCCESS)
|
if(Status != STATUS_EFI_SUCCESS)
|
||||||
{
|
{
|
||||||
/* Mapping trampoline code failed */
|
/* Mapping trampoline code failed */
|
||||||
@@ -109,7 +110,7 @@ Memory::BuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
|
|||||||
ModuleInfo = CONTAIN_RECORD(ModulesListEntry, XTBL_MODULE_INFO, Flink);
|
ModuleInfo = CONTAIN_RECORD(ModulesListEntry, XTBL_MODULE_INFO, Flink);
|
||||||
|
|
||||||
/* Map module code */
|
/* Map module code */
|
||||||
Status = MapVirtualMemory(PageMap, (ULONGLONG)ModuleInfo->ModuleBase, (ULONGLONG)ModuleInfo->ModuleBase,
|
Status = MapVirtualMemory(PageMap, ModuleInfo->ModuleBase, ModuleInfo->ModuleBase,
|
||||||
EFI_SIZE_TO_PAGES(ModuleInfo->ModuleSize), LoaderFirmwareTemporary);
|
EFI_SIZE_TO_PAGES(ModuleInfo->ModuleSize), LoaderFirmwareTemporary);
|
||||||
|
|
||||||
/* Check if mapping succeeded */
|
/* Check if mapping succeeded */
|
||||||
@@ -130,7 +131,7 @@ Memory::BuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
|
|||||||
if(LoaderBase && LoaderSize)
|
if(LoaderBase && LoaderSize)
|
||||||
{
|
{
|
||||||
/* Map boot loader code as well */
|
/* Map boot loader code as well */
|
||||||
Status = MapVirtualMemory(PageMap, (ULONGLONG)LoaderBase, (ULONGLONG)LoaderBase,
|
Status = MapVirtualMemory(PageMap, LoaderBase, LoaderBase,
|
||||||
EFI_SIZE_TO_PAGES(LoaderSize), LoaderFirmwareTemporary);
|
EFI_SIZE_TO_PAGES(LoaderSize), LoaderFirmwareTemporary);
|
||||||
if(Status != STATUS_EFI_SUCCESS)
|
if(Status != STATUS_EFI_SUCCESS)
|
||||||
{
|
{
|
||||||
@@ -156,9 +157,8 @@ Memory::BuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
|
|||||||
if(Mapping->VirtualAddress)
|
if(Mapping->VirtualAddress)
|
||||||
{
|
{
|
||||||
/* Dump memory mapping */
|
/* Dump memory mapping */
|
||||||
Debug::Print(L" Type=%02lu, PhysicalBase=0x%.8llX, VirtualBase=0x%.8llX, Pages=%llu\n",
|
Debug::Print(L" Type=%02lu, PhysicalBase=%.8P, VirtualBase=%.8P, Pages=%llu\n", Mapping->MemoryType,
|
||||||
Mapping->MemoryType, Mapping->PhysicalAddress,
|
Mapping->PhysicalAddress, Mapping->VirtualAddress, Mapping->NumberOfPages);
|
||||||
Mapping->VirtualAddress, Mapping->NumberOfPages);
|
|
||||||
|
|
||||||
/* Map memory */
|
/* Map memory */
|
||||||
Status = MapPage(PageMap, (UINT_PTR)Mapping->VirtualAddress,
|
Status = MapPage(PageMap, (UINT_PTR)Mapping->VirtualAddress,
|
||||||
@@ -252,7 +252,7 @@ Memory::GetNextPageTable(IN PXTBL_PAGE_MAPPING PageMap,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Add new memory mapping */
|
/* Add new memory mapping */
|
||||||
Status = MapVirtualMemory(PageMap, (ULONGLONG)NULLPTR, Address, 1, LoaderMemoryData);
|
Status = MapVirtualMemory(PageMap, NULLPTR, (PVOID)(UINT_PTR)Address, 1, LoaderMemoryData);
|
||||||
if(Status != STATUS_EFI_SUCCESS)
|
if(Status != STATUS_EFI_SUCCESS)
|
||||||
{
|
{
|
||||||
/* Memory mapping failure */
|
/* Memory mapping failure */
|
||||||
@@ -313,11 +313,11 @@ Memory::GetNextPageTable(IN PXTBL_PAGE_MAPPING PageMap,
|
|||||||
XTCDECL
|
XTCDECL
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
Memory::MapPage(IN PXTBL_PAGE_MAPPING PageMap,
|
Memory::MapPage(IN PXTBL_PAGE_MAPPING PageMap,
|
||||||
IN ULONGLONG VirtualAddress,
|
IN ULONG_PTR VirtualAddress,
|
||||||
IN ULONGLONG PhysicalAddress,
|
IN ULONG_PTR PhysicalAddress,
|
||||||
IN ULONGLONG NumberOfPages)
|
IN ULONG NumberOfPages)
|
||||||
{
|
{
|
||||||
ULONGLONG PageFrameNumber;
|
SIZE_T PageFrameNumber;
|
||||||
PVOID Pml1, Pml2, Pml3;
|
PVOID Pml1, Pml2, Pml3;
|
||||||
SIZE_T Pml1Entry, Pml2Entry, Pml3Entry;
|
SIZE_T Pml1Entry, Pml2Entry, Pml3Entry;
|
||||||
PHARDWARE_LEGACY_PTE LegacyPmlTable;
|
PHARDWARE_LEGACY_PTE LegacyPmlTable;
|
||||||
|
|||||||
@@ -1,190 +0,0 @@
|
|||||||
/**
|
|
||||||
* PROJECT: ExectOS
|
|
||||||
* COPYRIGHT: See COPYING.md in the top level directory
|
|
||||||
* FILE: xtldr/biosutil.cc
|
|
||||||
* DESCRIPTION: Legacy BIOS support
|
|
||||||
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <xtldr.hh>
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Clears the entire screen and moves the cursor to the top-left corner.
|
|
||||||
*
|
|
||||||
* @return This routine does not return any value.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTCDECL
|
|
||||||
VOID
|
|
||||||
BiosUtils::ClearScreen()
|
|
||||||
{
|
|
||||||
VOLATILE PUSHORT VgaBuffer = (PUSHORT)0xB8000;
|
|
||||||
USHORT Blank;
|
|
||||||
UINT Index;
|
|
||||||
|
|
||||||
/* Set blank character */
|
|
||||||
Blank = (0x0F << 8) | L' ';
|
|
||||||
|
|
||||||
/* Fill the entire screen with blank characters */
|
|
||||||
for(Index = 0; Index < VgaWidth * VgaHeight; Index++)
|
|
||||||
{
|
|
||||||
VgaBuffer[Index] = Blank;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Reset cursor position to the top-left corner */
|
|
||||||
CursorX = 0;
|
|
||||||
CursorY = 0;
|
|
||||||
|
|
||||||
/* Update the hardware cursor position */
|
|
||||||
UpdateCursor();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Formats the input string and prints it out to the screen.
|
|
||||||
*
|
|
||||||
* @param Format
|
|
||||||
* The formatted string that is to be written to the output.
|
|
||||||
*
|
|
||||||
* @param ...
|
|
||||||
* Depending on the format string, this routine might expect a sequence of additional arguments.
|
|
||||||
*
|
|
||||||
* @return This routine does not return any value.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTCDECL
|
|
||||||
VOID
|
|
||||||
BiosUtils::Print(IN PCWSTR Format,
|
|
||||||
IN ...)
|
|
||||||
{
|
|
||||||
RTL_PRINT_CONTEXT PrintContext;
|
|
||||||
VA_LIST Arguments;
|
|
||||||
|
|
||||||
/* Initialise the print contexts */
|
|
||||||
PrintContext.WriteWideCharacter = PutChar;
|
|
||||||
|
|
||||||
/* Initialise the va_list */
|
|
||||||
VA_START(Arguments, Format);
|
|
||||||
|
|
||||||
/* Format and print the string to the stdout */
|
|
||||||
RTL::WideString::FormatWideString(&PrintContext, (PWCHAR)Format, Arguments);
|
|
||||||
|
|
||||||
/* Clean up the va_list */
|
|
||||||
VA_END(Arguments);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Writes a single wide character to the screen using legacy BIOS VGA text mode.
|
|
||||||
*
|
|
||||||
* @param Character
|
|
||||||
* The wide character to be printed.
|
|
||||||
*
|
|
||||||
* @return This routine returns a status code.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTCDECL
|
|
||||||
XTSTATUS
|
|
||||||
BiosUtils::PutChar(IN WCHAR Character)
|
|
||||||
{
|
|
||||||
VOLATILE PUSHORT VgaBuffer = (PUSHORT)0xB8000;
|
|
||||||
USHORT VgaCharacter;
|
|
||||||
|
|
||||||
/* Handle special characters */
|
|
||||||
if(Character == L'\n')
|
|
||||||
{
|
|
||||||
/* Move to the next line */
|
|
||||||
CursorX = 0;
|
|
||||||
CursorY++;
|
|
||||||
}
|
|
||||||
else if(Character == L'\r')
|
|
||||||
{
|
|
||||||
/* Move to the beginning of the current line */
|
|
||||||
CursorX = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Print character and move cursor to the right */
|
|
||||||
VgaCharacter = (0x0F << 8) | (Character & 0xFF);
|
|
||||||
VgaBuffer[CursorY * VgaWidth + CursorX] = VgaCharacter;
|
|
||||||
CursorX++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Handle moving to the next line if cursor is at the end of the line */
|
|
||||||
if(CursorX >= VgaWidth)
|
|
||||||
{
|
|
||||||
CursorX = 0;
|
|
||||||
CursorY++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Handle scrolling if cursor is at the end of the screen */
|
|
||||||
if(CursorY >= VgaHeight)
|
|
||||||
{
|
|
||||||
ScrollScreen();
|
|
||||||
CursorY = VgaHeight - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Update the hardware cursor position */
|
|
||||||
UpdateCursor();
|
|
||||||
|
|
||||||
/* Return success */
|
|
||||||
return STATUS_EFI_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Scrolls the entire screen content up by one line and clears the last line.
|
|
||||||
*
|
|
||||||
* @return This routine does not return any value.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTCDECL
|
|
||||||
VOID
|
|
||||||
BiosUtils::ScrollScreen()
|
|
||||||
{
|
|
||||||
VOLATILE PUSHORT VgaBuffer = (PUSHORT)0xB8000;
|
|
||||||
USHORT Blank;
|
|
||||||
UINT Index;
|
|
||||||
|
|
||||||
/* Set blank character */
|
|
||||||
Blank = (0x0F << 8) | L' ';
|
|
||||||
|
|
||||||
/* Move every line up by one */
|
|
||||||
for(Index = 0; Index < (VgaHeight - 1) * VgaWidth; Index++)
|
|
||||||
{
|
|
||||||
VgaBuffer[Index] = VgaBuffer[Index + VgaWidth];
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Clear the last line */
|
|
||||||
for(Index = (VgaHeight - 1) * VgaWidth; Index < VgaHeight * VgaWidth; Index++)
|
|
||||||
{
|
|
||||||
VgaBuffer[Index] = Blank;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Updates the hardware cursor position on the screen.
|
|
||||||
*
|
|
||||||
* @return This routine does not return any value.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTCDECL
|
|
||||||
VOID
|
|
||||||
BiosUtils::UpdateCursor()
|
|
||||||
{
|
|
||||||
USHORT Position;
|
|
||||||
|
|
||||||
/* Calculate cursor position */
|
|
||||||
Position = CursorY * VgaWidth + CursorX;
|
|
||||||
|
|
||||||
/* Send command to set the high byte of the cursor position */
|
|
||||||
HL::IoPort::WritePort8(0x3D4, 0x0E);
|
|
||||||
HL::IoPort::WritePort8(0x3D5, (UCHAR)((Position >> 8) & 0xFF));
|
|
||||||
|
|
||||||
/* Send command to set the low byte of the cursor position */
|
|
||||||
HL::IoPort::WritePort8(0x3D4, 0x0F);
|
|
||||||
HL::IoPort::WritePort8(0x3D5, (UCHAR)(Position & 0xFF));
|
|
||||||
}
|
|
||||||
@@ -10,18 +10,6 @@
|
|||||||
#include <xtldr.hh>
|
#include <xtldr.hh>
|
||||||
|
|
||||||
|
|
||||||
/* Legacy BIOS cursor X position */
|
|
||||||
USHORT BiosUtils::CursorX = 0;
|
|
||||||
|
|
||||||
/* Legacy BIOS cursor Y position */
|
|
||||||
USHORT BiosUtils::CursorY = 0;
|
|
||||||
|
|
||||||
/* Legacy BIOS screen height */
|
|
||||||
CONST USHORT BiosUtils::VgaHeight = 25;
|
|
||||||
|
|
||||||
/* Legacy BIOS screen width */
|
|
||||||
CONST USHORT BiosUtils::VgaWidth = 80;
|
|
||||||
|
|
||||||
/* XT Boot Loader menu list */
|
/* XT Boot Loader menu list */
|
||||||
PLIST_ENTRY Configuration::BootMenuList = NULLPTR;
|
PLIST_ENTRY Configuration::BootMenuList = NULLPTR;
|
||||||
|
|
||||||
|
|||||||
@@ -15,25 +15,6 @@
|
|||||||
#include <libxtos.hh>
|
#include <libxtos.hh>
|
||||||
|
|
||||||
|
|
||||||
class BiosUtils
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
STATIC USHORT CursorX;
|
|
||||||
STATIC USHORT CursorY;
|
|
||||||
STATIC CONST USHORT VgaHeight;
|
|
||||||
STATIC CONST USHORT VgaWidth;
|
|
||||||
|
|
||||||
public:
|
|
||||||
STATIC XTCDECL VOID ClearScreen();
|
|
||||||
STATIC XTCDECL VOID Print(IN PCWSTR Format,
|
|
||||||
IN ...);
|
|
||||||
STATIC XTCDECL XTSTATUS PutChar(IN WCHAR Character);
|
|
||||||
|
|
||||||
private:
|
|
||||||
STATIC XTCDECL VOID ScrollScreen();
|
|
||||||
STATIC XTCDECL VOID UpdateCursor();
|
|
||||||
};
|
|
||||||
|
|
||||||
class BootUtils
|
class BootUtils
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -177,16 +158,15 @@ class Memory
|
|||||||
IN SHORT PageMapLevel,
|
IN SHORT PageMapLevel,
|
||||||
IN PAGE_SIZE PageSize);
|
IN PAGE_SIZE PageSize);
|
||||||
STATIC XTCDECL EFI_STATUS MapEfiMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
|
STATIC XTCDECL EFI_STATUS MapEfiMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
|
||||||
IN OUT PVOID *BaseAddress,
|
IN OUT PVOID *MemoryMapAddress,
|
||||||
IN BOOLEAN IdentityMapping,
|
|
||||||
IN PBL_GET_MEMTYPE_ROUTINE GetMemoryTypeRoutine);
|
IN PBL_GET_MEMTYPE_ROUTINE GetMemoryTypeRoutine);
|
||||||
STATIC XTCDECL EFI_STATUS MapPage(IN PXTBL_PAGE_MAPPING PageMap,
|
STATIC XTCDECL EFI_STATUS MapPage(IN PXTBL_PAGE_MAPPING PageMap,
|
||||||
IN ULONGLONG VirtualAddress,
|
IN ULONG_PTR VirtualAddress,
|
||||||
IN ULONGLONG PhysicalAddress,
|
IN ULONG_PTR PhysicalAddress,
|
||||||
IN ULONGLONG NumberOfPages);
|
IN ULONG NumberOfPages);
|
||||||
STATIC XTCDECL EFI_STATUS MapVirtualMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
|
STATIC XTCDECL EFI_STATUS MapVirtualMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
|
||||||
IN ULONGLONG VirtualAddress,
|
IN PVOID VirtualAddress,
|
||||||
IN ULONGLONG PhysicalAddress,
|
IN PVOID PhysicalAddress,
|
||||||
IN ULONGLONG NumberOfPages,
|
IN ULONGLONG NumberOfPages,
|
||||||
IN LOADER_MEMORY_TYPE MemoryType);
|
IN LOADER_MEMORY_TYPE MemoryType);
|
||||||
STATIC XTCDECL PVOID PhysicalAddressToVirtual(IN PVOID PhysicalAddress,
|
STATIC XTCDECL PVOID PhysicalAddressToVirtual(IN PVOID PhysicalAddress,
|
||||||
|
|||||||
@@ -314,12 +314,9 @@ Memory::InitializePageMap(OUT PXTBL_PAGE_MAPPING PageMap,
|
|||||||
* @param PageMap
|
* @param PageMap
|
||||||
* Supplies a pointer to the page mapping structure.
|
* Supplies a pointer to the page mapping structure.
|
||||||
*
|
*
|
||||||
* @param BaseAddress
|
* @param MemoryMapAddress
|
||||||
* Supplies a virtual address, where EFI memory will be mapped.
|
* Supplies a virtual address, where EFI memory will be mapped.
|
||||||
*
|
*
|
||||||
* @param IdentityMapping
|
|
||||||
* Specifies whether EFI non-free memory should be mapped by identity or sequential mapping.
|
|
||||||
*
|
|
||||||
* @param GetMemoryTypeRoutine
|
* @param GetMemoryTypeRoutine
|
||||||
* Supplies a pointer to the routine which will be used to match EFI memory type to the OS memory type.
|
* Supplies a pointer to the routine which will be used to match EFI memory type to the OS memory type.
|
||||||
*
|
*
|
||||||
@@ -330,20 +327,19 @@ Memory::InitializePageMap(OUT PXTBL_PAGE_MAPPING PageMap,
|
|||||||
XTCDECL
|
XTCDECL
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
Memory::MapEfiMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
|
Memory::MapEfiMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
|
||||||
IN OUT PVOID *BaseAddress,
|
IN OUT PVOID *MemoryMapAddress,
|
||||||
IN BOOLEAN IdentityMapping,
|
|
||||||
IN PBL_GET_MEMTYPE_ROUTINE GetMemoryTypeRoutine)
|
IN PBL_GET_MEMTYPE_ROUTINE GetMemoryTypeRoutine)
|
||||||
{
|
{
|
||||||
ULONGLONG MaxAddress, VirtualAddress;
|
|
||||||
PEFI_MEMORY_DESCRIPTOR Descriptor;
|
PEFI_MEMORY_DESCRIPTOR Descriptor;
|
||||||
LOADER_MEMORY_TYPE MemoryType;
|
LOADER_MEMORY_TYPE MemoryType;
|
||||||
PEFI_MEMORY_MAP MemoryMap;
|
PEFI_MEMORY_MAP MemoryMap;
|
||||||
SIZE_T DescriptorCount;
|
SIZE_T DescriptorCount;
|
||||||
|
PUCHAR VirtualAddress;
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
SIZE_T Index;
|
SIZE_T Index;
|
||||||
|
|
||||||
/* Set virtual address as specified in argument */
|
/* Set virtual address as specified in argument */
|
||||||
VirtualAddress = (ULONGLONG)*BaseAddress;
|
VirtualAddress = (PUCHAR)*MemoryMapAddress;
|
||||||
|
|
||||||
/* Check if custom memory type routine is specified */
|
/* Check if custom memory type routine is specified */
|
||||||
if(GetMemoryTypeRoutine == NULLPTR)
|
if(GetMemoryTypeRoutine == NULLPTR)
|
||||||
@@ -371,37 +367,8 @@ Memory::MapEfiMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
|
|||||||
/* Iterate through all descriptors from the memory map */
|
/* Iterate through all descriptors from the memory map */
|
||||||
for(Index = 0; Index < DescriptorCount; Index++)
|
for(Index = 0; Index < DescriptorCount; Index++)
|
||||||
{
|
{
|
||||||
/* Check page map level */
|
/* Make sure descriptor does not start beyond lowest physical page */
|
||||||
if(PageMap->PageMapLevel == 2)
|
if(Descriptor->PhysicalStart <= MAXUINT_PTR)
|
||||||
{
|
|
||||||
/* Limit physical address to 4GB in legacy mode */
|
|
||||||
MaxAddress = 0xFFFFFFFF;
|
|
||||||
}
|
|
||||||
else if(PageMap->PageMapLevel == 3)
|
|
||||||
{
|
|
||||||
/* Limit physical address to 64GB in PAE mode */
|
|
||||||
MaxAddress = 0xFFFFFFFFFULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check page map level */
|
|
||||||
if(PageMap->PageMapLevel == 2 || PageMap->PageMapLevel == 3)
|
|
||||||
{
|
|
||||||
/* Check if physical address starts beyond limit */
|
|
||||||
if(Descriptor->PhysicalStart >= MaxAddress)
|
|
||||||
{
|
|
||||||
/* Go to the next descriptor */
|
|
||||||
Descriptor = (PEFI_MEMORY_DESCRIPTOR)((PUCHAR)Descriptor + MemoryMap->DescriptorSize);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check if memory descriptor exceeds the lowest physical page */
|
|
||||||
if(Descriptor->PhysicalStart + (Descriptor->NumberOfPages << EFI_PAGE_SHIFT) > MaxAddress)
|
|
||||||
{
|
|
||||||
/* Truncate memory descriptor to the lowest supported physical page */
|
|
||||||
Descriptor->NumberOfPages = (MaxAddress - Descriptor->PhysicalStart) >> EFI_PAGE_SHIFT;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
{
|
||||||
/* Skip EFI reserved memory */
|
/* Skip EFI reserved memory */
|
||||||
if(Descriptor->Type == EfiReservedMemoryType)
|
if(Descriptor->Type == EfiReservedMemoryType)
|
||||||
@@ -411,6 +378,25 @@ Memory::MapEfiMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Check if preparing page map level 2 (non-PAE i686) */
|
||||||
|
if(PageMap->PageMapLevel == 2)
|
||||||
|
{
|
||||||
|
/* Check if physical address starts beyond 4GB */
|
||||||
|
if(Descriptor->PhysicalStart > 0xFFFFFFFF)
|
||||||
|
{
|
||||||
|
/* Go to the next descriptor */
|
||||||
|
Descriptor = (PEFI_MEMORY_DESCRIPTOR)((PUCHAR)Descriptor + MemoryMap->DescriptorSize);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if memory descriptor exceeds the lowest physical page */
|
||||||
|
if(Descriptor->PhysicalStart + (Descriptor->NumberOfPages << EFI_PAGE_SHIFT) > MAXULONG)
|
||||||
|
{
|
||||||
|
/* Truncate memory descriptor to the 4GB */
|
||||||
|
Descriptor->NumberOfPages = (((ULONGLONG)MAXULONG + 1) - Descriptor->PhysicalStart) >> EFI_PAGE_SHIFT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Convert EFI memory type into XTLDR memory type */
|
/* Convert EFI memory type into XTLDR memory type */
|
||||||
MemoryType = GetMemoryTypeRoutine((EFI_MEMORY_TYPE)Descriptor->Type);
|
MemoryType = GetMemoryTypeRoutine((EFI_MEMORY_TYPE)Descriptor->Type);
|
||||||
|
|
||||||
@@ -418,32 +404,22 @@ Memory::MapEfiMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
|
|||||||
if(MemoryType == LoaderFirmwareTemporary)
|
if(MemoryType == LoaderFirmwareTemporary)
|
||||||
{
|
{
|
||||||
/* Map EFI firmware code */
|
/* Map EFI firmware code */
|
||||||
Status = MapVirtualMemory(PageMap, Descriptor->PhysicalStart,
|
Status = MapVirtualMemory(PageMap, (PVOID)Descriptor->PhysicalStart,
|
||||||
Descriptor->PhysicalStart, Descriptor->NumberOfPages, MemoryType);
|
(PVOID)Descriptor->PhysicalStart, Descriptor->NumberOfPages, MemoryType);
|
||||||
}
|
}
|
||||||
else if(MemoryType != LoaderFree)
|
else if(MemoryType != LoaderFree)
|
||||||
{
|
{
|
||||||
/* Check mapping strategy */
|
/* Add any non-free memory mapping */
|
||||||
if(IdentityMapping)
|
Status = MapVirtualMemory(PageMap, VirtualAddress, (PVOID)Descriptor->PhysicalStart,
|
||||||
{
|
|
||||||
/* Add any non-free memory using identity mapping */
|
|
||||||
Status = MapVirtualMemory(PageMap, Descriptor->PhysicalStart + KSEG0_BASE, Descriptor->PhysicalStart,
|
|
||||||
Descriptor->NumberOfPages, MemoryType);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Add any non-free memory using sequential mapping */
|
|
||||||
Status = MapVirtualMemory(PageMap, VirtualAddress, Descriptor->PhysicalStart,
|
|
||||||
Descriptor->NumberOfPages, MemoryType);
|
Descriptor->NumberOfPages, MemoryType);
|
||||||
|
|
||||||
/* Update virtual address */
|
/* Calculate next valid virtual address */
|
||||||
VirtualAddress = VirtualAddress + (Descriptor->NumberOfPages * MM_PAGE_SIZE);
|
VirtualAddress += Descriptor->NumberOfPages * EFI_PAGE_SIZE;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Map all other memory as loader free */
|
/* Map all other memory as loader free */
|
||||||
Status = MapVirtualMemory(PageMap, (ULONGLONG)NULLPTR, Descriptor->PhysicalStart,
|
Status = MapVirtualMemory(PageMap, NULLPTR, (PVOID)Descriptor->PhysicalStart,
|
||||||
Descriptor->NumberOfPages, LoaderFree);
|
Descriptor->NumberOfPages, LoaderFree);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -460,7 +436,7 @@ Memory::MapEfiMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Always map first page */
|
/* Always map first page */
|
||||||
Status = MapVirtualMemory(PageMap, (ULONGLONG)NULLPTR, 0, 1, LoaderFirmwarePermanent);
|
Status = MapVirtualMemory(PageMap, NULLPTR, (PVOID)0, 1, LoaderFirmwarePermanent);
|
||||||
if(Status != STATUS_EFI_SUCCESS)
|
if(Status != STATUS_EFI_SUCCESS)
|
||||||
{
|
{
|
||||||
/* Mapping failed */
|
/* Mapping failed */
|
||||||
@@ -468,7 +444,7 @@ Memory::MapEfiMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Map BIOS ROM and VRAM */
|
/* Map BIOS ROM and VRAM */
|
||||||
Status = MapVirtualMemory(PageMap, (ULONGLONG)NULLPTR, 0xA0000, 0x60, LoaderFirmwarePermanent);
|
Status = MapVirtualMemory(PageMap, NULLPTR, (PVOID)0xA0000, 0x60, LoaderFirmwarePermanent);
|
||||||
if(Status != STATUS_EFI_SUCCESS)
|
if(Status != STATUS_EFI_SUCCESS)
|
||||||
{
|
{
|
||||||
/* Mapping failed */
|
/* Mapping failed */
|
||||||
@@ -476,7 +452,7 @@ Memory::MapEfiMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Store next valid virtual address and return success */
|
/* Store next valid virtual address and return success */
|
||||||
*BaseAddress = (PVOID)VirtualAddress;
|
*MemoryMapAddress = VirtualAddress;
|
||||||
return STATUS_EFI_SUCCESS;
|
return STATUS_EFI_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -505,13 +481,13 @@ Memory::MapEfiMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
|
|||||||
XTCDECL
|
XTCDECL
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
Memory::MapVirtualMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
|
Memory::MapVirtualMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
|
||||||
IN ULONGLONG VirtualAddress,
|
IN PVOID VirtualAddress,
|
||||||
IN ULONGLONG PhysicalAddress,
|
IN PVOID PhysicalAddress,
|
||||||
IN ULONGLONG NumberOfPages,
|
IN ULONGLONG NumberOfPages,
|
||||||
IN LOADER_MEMORY_TYPE MemoryType)
|
IN LOADER_MEMORY_TYPE MemoryType)
|
||||||
{
|
{
|
||||||
PXTBL_MEMORY_MAPPING Mapping1, Mapping2, Mapping3;
|
PXTBL_MEMORY_MAPPING Mapping1, Mapping2, Mapping3;
|
||||||
ULONGLONG PhysicalAddressEnd, PhysicalAddress2End;
|
PVOID PhysicalAddressEnd, PhysicalAddress2End;
|
||||||
PLIST_ENTRY ListEntry, MappingListEntry;
|
PLIST_ENTRY ListEntry, MappingListEntry;
|
||||||
SIZE_T NumberOfMappedPages;
|
SIZE_T NumberOfMappedPages;
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
@@ -531,7 +507,7 @@ Memory::MapVirtualMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
|
|||||||
Mapping1->MemoryType = MemoryType;
|
Mapping1->MemoryType = MemoryType;
|
||||||
|
|
||||||
/* Calculate the end of the physical address */
|
/* Calculate the end of the physical address */
|
||||||
PhysicalAddressEnd = PhysicalAddress + (NumberOfPages * EFI_PAGE_SIZE) - 1;
|
PhysicalAddressEnd = (PVOID)((ULONG_PTR)PhysicalAddress + (NumberOfPages * EFI_PAGE_SIZE) - 1);
|
||||||
|
|
||||||
/* Iterate through all the mappings already set to insert new mapping at the correct place */
|
/* Iterate through all the mappings already set to insert new mapping at the correct place */
|
||||||
ListEntry = PageMap->MemoryMap.Flink;
|
ListEntry = PageMap->MemoryMap.Flink;
|
||||||
@@ -539,7 +515,7 @@ Memory::MapVirtualMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
|
|||||||
{
|
{
|
||||||
/* Take a mapping from the list and calculate its end of physical address */
|
/* Take a mapping from the list and calculate its end of physical address */
|
||||||
Mapping2 = CONTAIN_RECORD(ListEntry, XTBL_MEMORY_MAPPING, ListEntry);
|
Mapping2 = CONTAIN_RECORD(ListEntry, XTBL_MEMORY_MAPPING, ListEntry);
|
||||||
PhysicalAddress2End = Mapping2->PhysicalAddress + (Mapping2->NumberOfPages * EFI_PAGE_SIZE) - 1;
|
PhysicalAddress2End = (PVOID)((ULONG_PTR)Mapping2->PhysicalAddress + (Mapping2->NumberOfPages * EFI_PAGE_SIZE) - 1);
|
||||||
|
|
||||||
/* Check if new mapping is a subset of an existing mapping */
|
/* Check if new mapping is a subset of an existing mapping */
|
||||||
if(Mapping1->PhysicalAddress >= Mapping2->PhysicalAddress && PhysicalAddressEnd <= PhysicalAddress2End)
|
if(Mapping1->PhysicalAddress >= Mapping2->PhysicalAddress && PhysicalAddressEnd <= PhysicalAddress2End)
|
||||||
@@ -563,7 +539,7 @@ Memory::MapVirtualMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Calculate number of pages for this mapping */
|
/* Calculate number of pages for this mapping */
|
||||||
NumberOfMappedPages = (PhysicalAddress2End - PhysicalAddressEnd) / EFI_PAGE_SIZE;
|
NumberOfMappedPages = ((PUCHAR)PhysicalAddress2End - (PUCHAR)PhysicalAddressEnd) / EFI_PAGE_SIZE;
|
||||||
if(NumberOfMappedPages > 0)
|
if(NumberOfMappedPages > 0)
|
||||||
{
|
{
|
||||||
/* Pages associated to the mapping, allocate memory for it */
|
/* Pages associated to the mapping, allocate memory for it */
|
||||||
@@ -575,8 +551,8 @@ Memory::MapVirtualMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Set mapping fields and insert it on the top */
|
/* Set mapping fields and insert it on the top */
|
||||||
Mapping3->PhysicalAddress = PhysicalAddressEnd + 1;
|
Mapping3->PhysicalAddress = (PUCHAR)PhysicalAddressEnd + 1;
|
||||||
Mapping3->VirtualAddress = (ULONGLONG)NULLPTR;
|
Mapping3->VirtualAddress = NULLPTR;
|
||||||
Mapping3->NumberOfPages = NumberOfMappedPages;
|
Mapping3->NumberOfPages = NumberOfMappedPages;
|
||||||
Mapping3->MemoryType = Mapping2->MemoryType;
|
Mapping3->MemoryType = Mapping2->MemoryType;
|
||||||
RTL::LinkedList::InsertHeadList(&Mapping2->ListEntry, &Mapping3->ListEntry);
|
RTL::LinkedList::InsertHeadList(&Mapping2->ListEntry, &Mapping3->ListEntry);
|
||||||
@@ -585,7 +561,7 @@ Memory::MapVirtualMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
|
|||||||
/* Calculate number of pages and the end of the physical address */
|
/* Calculate number of pages and the end of the physical address */
|
||||||
Mapping2->NumberOfPages = ((PUCHAR)PhysicalAddressEnd + 1 -
|
Mapping2->NumberOfPages = ((PUCHAR)PhysicalAddressEnd + 1 -
|
||||||
(PUCHAR)Mapping2->PhysicalAddress) / EFI_PAGE_SIZE;
|
(PUCHAR)Mapping2->PhysicalAddress) / EFI_PAGE_SIZE;
|
||||||
PhysicalAddress2End = Mapping2->PhysicalAddress + (Mapping2->NumberOfPages * EFI_PAGE_SIZE) - 1;
|
PhysicalAddress2End = (PVOID)((ULONG_PTR)Mapping2->PhysicalAddress + (Mapping2->NumberOfPages * EFI_PAGE_SIZE) - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if they overlap */
|
/* Check if they overlap */
|
||||||
@@ -612,7 +588,7 @@ Memory::MapVirtualMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
|
|||||||
|
|
||||||
/* Set mapping fields and insert it on the top */
|
/* Set mapping fields and insert it on the top */
|
||||||
Mapping3->PhysicalAddress = Mapping1->PhysicalAddress;
|
Mapping3->PhysicalAddress = Mapping1->PhysicalAddress;
|
||||||
Mapping3->VirtualAddress = (ULONGLONG)NULLPTR;
|
Mapping3->VirtualAddress = NULLPTR;
|
||||||
Mapping3->NumberOfPages = NumberOfMappedPages;
|
Mapping3->NumberOfPages = NumberOfMappedPages;
|
||||||
Mapping3->MemoryType = Mapping2->MemoryType;
|
Mapping3->MemoryType = Mapping2->MemoryType;
|
||||||
RTL::LinkedList::InsertHeadList(&Mapping2->ListEntry, &Mapping3->ListEntry);
|
RTL::LinkedList::InsertHeadList(&Mapping2->ListEntry, &Mapping3->ListEntry);
|
||||||
@@ -621,7 +597,7 @@ Memory::MapVirtualMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
|
|||||||
/* Calculate number of pages and the end of the physical address */
|
/* Calculate number of pages and the end of the physical address */
|
||||||
Mapping2->NumberOfPages = ((PUCHAR)Mapping1->PhysicalAddress -
|
Mapping2->NumberOfPages = ((PUCHAR)Mapping1->PhysicalAddress -
|
||||||
(PUCHAR)Mapping2->PhysicalAddress) / EFI_PAGE_SIZE;
|
(PUCHAR)Mapping2->PhysicalAddress) / EFI_PAGE_SIZE;
|
||||||
PhysicalAddress2End = Mapping2->PhysicalAddress + (Mapping2->NumberOfPages * EFI_PAGE_SIZE) - 1;
|
PhysicalAddress2End = (PVOID)((ULONG_PTR)Mapping2->PhysicalAddress + (Mapping2->NumberOfPages * EFI_PAGE_SIZE) - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if mapping is really needed */
|
/* Check if mapping is really needed */
|
||||||
|
|||||||
@@ -729,11 +729,11 @@ PeCoff::RelocateLoadedImage(IN PPECOFF_IMAGE_CONTEXT Image)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
/* Check if loaded 32-bit PE32 image should be relocated */
|
||||||
/* Set relocation data directory and image base address */
|
/* Set relocation data directory and image base address */
|
||||||
DataDirectory = &Image->PeHeader->OptionalHeader32.DataDirectory[PECOFF_IMAGE_DIRECTORY_ENTRY_BASERELOC];
|
DataDirectory = &Image->PeHeader->OptionalHeader32.DataDirectory[PECOFF_IMAGE_DIRECTORY_ENTRY_BASERELOC];
|
||||||
ImageBase = Image->PeHeader->OptionalHeader32.ImageBase;
|
ImageBase = Image->PeHeader->OptionalHeader32.ImageBase;
|
||||||
|
|
||||||
/* Check if loaded 32-bit PE32 image should be relocated */
|
|
||||||
if(Image->PeHeader->OptionalHeader32.NumberOfRvaAndSizes <= PECOFF_IMAGE_DIRECTORY_ENTRY_BASERELOC ||
|
if(Image->PeHeader->OptionalHeader32.NumberOfRvaAndSizes <= PECOFF_IMAGE_DIRECTORY_ENTRY_BASERELOC ||
|
||||||
DataDirectory->VirtualAddress == 0 || DataDirectory->Size < sizeof(PECOFF_IMAGE_BASE_RELOCATION))
|
DataDirectory->VirtualAddress == 0 || DataDirectory->Size < sizeof(PECOFF_IMAGE_BASE_RELOCATION))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -10,21 +10,6 @@
|
|||||||
#include <xtos.hh>
|
#include <xtos.hh>
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determines the appropriate EFI memory mapping strategy for the AMD64 architecture.
|
|
||||||
*
|
|
||||||
* @return This routine returns TRUE, what results in an identity mapping.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTCDECL
|
|
||||||
BOOLEAN
|
|
||||||
Xtos::DetermineMappingStrategy()
|
|
||||||
{
|
|
||||||
/* Use an identity mapping strategy */
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determines the appropriate paging level (PML) for the AMD64 architecture.
|
* Determines the appropriate paging level (PML) for the AMD64 architecture.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -9,21 +9,6 @@
|
|||||||
#include <xtos.hh>
|
#include <xtos.hh>
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determines the appropriate EFI memory mapping strategy for the i686 architecture.
|
|
||||||
*
|
|
||||||
* @return This routine returns FALSE, what results in a sequential mapping.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTCDECL
|
|
||||||
BOOLEAN
|
|
||||||
Xtos::DetermineMappingStrategy()
|
|
||||||
{
|
|
||||||
/* Use a sequential mapping strategy */
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determines the appropriate paging level (PML) for the i686 architecture.
|
* Determines the appropriate paging level (PML) for the i686 architecture.
|
||||||
*
|
*
|
||||||
@@ -74,22 +59,9 @@ EFI_STATUS
|
|||||||
Xtos::EnablePaging(IN PXTBL_PAGE_MAPPING PageMap)
|
Xtos::EnablePaging(IN PXTBL_PAGE_MAPPING PageMap)
|
||||||
{
|
{
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
ULONG_PTR SelfMapAddress;
|
|
||||||
|
|
||||||
/* Initialize self map address */
|
|
||||||
if(PageMap->PageMapLevel == 3)
|
|
||||||
{
|
|
||||||
/* For PML3 (PAE) use PTE base address */
|
|
||||||
SelfMapAddress = MM_PTE_BASE;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* For PML2 (PAE disabled) use legacy PDE base address */
|
|
||||||
SelfMapAddress = MM_PDE_LEGACY_BASE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Build page map */
|
/* Build page map */
|
||||||
Status = XtLdrProtocol->Memory.BuildPageMap(PageMap, SelfMapAddress);
|
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 */
|
||||||
|
|||||||
@@ -39,7 +39,6 @@ class Xtos
|
|||||||
IN UINT NumberOfPages,
|
IN UINT NumberOfPages,
|
||||||
IN LOADER_MEMORY_TYPE MemoryType);
|
IN LOADER_MEMORY_TYPE MemoryType);
|
||||||
STATIC XTCDECL LOADER_MEMORY_TYPE ConvertEfiMemoryType(IN EFI_MEMORY_TYPE EfiMemoryType);
|
STATIC XTCDECL LOADER_MEMORY_TYPE ConvertEfiMemoryType(IN EFI_MEMORY_TYPE EfiMemoryType);
|
||||||
STATIC XTCDECL BOOLEAN DetermineMappingStrategy();
|
|
||||||
STATIC XTCDECL ULONG DeterminePagingLevel(IN CONST PWCHAR Parameters);
|
STATIC XTCDECL ULONG DeterminePagingLevel(IN CONST PWCHAR Parameters);
|
||||||
STATIC XTCDECL EFI_STATUS EnablePaging(IN PXTBL_PAGE_MAPPING PageMap);
|
STATIC XTCDECL EFI_STATUS EnablePaging(IN PXTBL_PAGE_MAPPING PageMap);
|
||||||
STATIC XTCDECL VOID GetDisplayInformation(OUT PSYSTEM_RESOURCE_FRAMEBUFFER FrameBufferResource,
|
STATIC XTCDECL VOID GetDisplayInformation(OUT PSYSTEM_RESOURCE_FRAMEBUFFER FrameBufferResource,
|
||||||
|
|||||||
@@ -194,63 +194,46 @@ Xtos::GetMemoryDescriptorList(IN PXTBL_PAGE_MAPPING PageMap,
|
|||||||
IN PVOID *VirtualAddress,
|
IN PVOID *VirtualAddress,
|
||||||
OUT PLIST_ENTRY MemoryDescriptorList)
|
OUT PLIST_ENTRY MemoryDescriptorList)
|
||||||
{
|
{
|
||||||
PLOADER_MEMORY_DESCRIPTOR Descriptor;
|
|
||||||
PXTBL_MEMORY_MAPPING MemoryMapping;
|
|
||||||
EFI_PHYSICAL_ADDRESS Address;
|
EFI_PHYSICAL_ADDRESS Address;
|
||||||
PLIST_ENTRY ListEntry;
|
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
ULONGLONG Pages;
|
ULONGLONG Pages;
|
||||||
|
|
||||||
/* Calculate the number of pages required to store the memory descriptor array */
|
|
||||||
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));
|
||||||
|
|
||||||
/* Allocate physical pages to hold the memory descriptor list */
|
|
||||||
Status = XtLdrProtocol->Memory.AllocatePages(AllocateAnyPages, Pages, &Address);
|
Status = XtLdrProtocol->Memory.AllocatePages(AllocateAnyPages, Pages, &Address);
|
||||||
if(Status != STATUS_EFI_SUCCESS)
|
if(Status != STATUS_EFI_SUCCESS)
|
||||||
{
|
{
|
||||||
/* Page allocation failed, return the status code */
|
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create a virtual memory mapping for the allocated descriptor buffer */
|
Status = XtLdrProtocol->Memory.MapVirtualMemory(PageMap, *VirtualAddress, (PVOID)Address, Pages, LoaderMemoryData);
|
||||||
Status = XtLdrProtocol->Memory.MapVirtualMemory(PageMap, (ULONGLONG)*VirtualAddress, Address, Pages, LoaderMemoryData);
|
|
||||||
if(Status != STATUS_EFI_SUCCESS)
|
if(Status != STATUS_EFI_SUCCESS)
|
||||||
{
|
{
|
||||||
/* Release the allocated pages as the virtual mapping failed and return status code */
|
|
||||||
XtLdrProtocol->Memory.FreePages(Address, Pages);
|
XtLdrProtocol->Memory.FreePages(Address, Pages);
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Initialize the descriptor pointer to the start of the allocated physical buffer */
|
PVOID PhysicalBase = (PVOID)Address;
|
||||||
Descriptor = (PLOADER_MEMORY_DESCRIPTOR)Address;
|
|
||||||
|
|
||||||
/* Get the first entry from the internal boot loader memory map */
|
PLIST_ENTRY ListEntry;
|
||||||
ListEntry = PageMap->MemoryMap.Flink;
|
ListEntry = PageMap->MemoryMap.Flink;
|
||||||
|
|
||||||
/* Iterate through the internal memory map and populate the loader descriptor list */
|
|
||||||
while(ListEntry != &PageMap->MemoryMap)
|
while(ListEntry != &PageMap->MemoryMap)
|
||||||
{
|
{
|
||||||
/* Retrieve the internal memory mapping record from the current list entry */
|
PXTBL_MEMORY_MAPPING MemoryMapping = CONTAIN_RECORD(ListEntry, XTBL_MEMORY_MAPPING, ListEntry);
|
||||||
MemoryMapping = CONTAIN_RECORD(ListEntry, XTBL_MEMORY_MAPPING, ListEntry);
|
PLOADER_MEMORY_DESCRIPTOR MemoryDescriptor = (PLOADER_MEMORY_DESCRIPTOR)Address;
|
||||||
|
|
||||||
/* Transfer memory type and address information to the kernel descriptor */
|
MemoryDescriptor->MemoryType = MemoryMapping->MemoryType;
|
||||||
Descriptor->MemoryType = MemoryMapping->MemoryType;
|
MemoryDescriptor->BasePage = (UINT_PTR)MemoryMapping->PhysicalAddress / EFI_PAGE_SIZE;
|
||||||
Descriptor->BasePage = (UINT_PTR)(MemoryMapping->PhysicalAddress / EFI_PAGE_SIZE);
|
MemoryDescriptor->PageCount = MemoryMapping->NumberOfPages;
|
||||||
Descriptor->PageCount = (ULONG)MemoryMapping->NumberOfPages;
|
|
||||||
|
|
||||||
/* Link the entry */
|
XtLdrProtocol->LinkedList.InsertTail(MemoryDescriptorList, &MemoryDescriptor->ListEntry);
|
||||||
XtLdrProtocol->LinkedList.InsertTail(MemoryDescriptorList, &Descriptor->ListEntry);
|
|
||||||
|
|
||||||
/* Move to the next slot in the allocated buffer */
|
Address = Address + sizeof(LOADER_MEMORY_DESCRIPTOR);
|
||||||
Descriptor++;
|
|
||||||
ListEntry = ListEntry->Flink;
|
ListEntry = ListEntry->Flink;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Convert all physical link pointers in the list to their corresponding virtual addresses */
|
XtLdrProtocol->Memory.PhysicalListToVirtual(PageMap, MemoryDescriptorList, PhysicalBase, *VirtualAddress);
|
||||||
XtLdrProtocol->Memory.PhysicalListToVirtual(PageMap, MemoryDescriptorList, (PVOID)Address, *VirtualAddress);
|
|
||||||
|
|
||||||
/* Advance the virtual address pointer to the next available free region and return success */
|
|
||||||
*VirtualAddress = (PUINT8)*VirtualAddress + (Pages * EFI_PAGE_SIZE);
|
|
||||||
return STATUS_EFI_SUCCESS;
|
return STATUS_EFI_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -283,7 +266,7 @@ Xtos::GetSystemResourcesList(IN PXTBL_PAGE_MAPPING PageMap,
|
|||||||
{
|
{
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
Status = XtLdrProtocol->Memory.MapVirtualMemory(PageMap, (ULONGLONG)*VirtualAddress, Address, Pages, LoaderFirmwarePermanent);
|
Status = XtLdrProtocol->Memory.MapVirtualMemory(PageMap, *VirtualAddress, (PVOID)Address, Pages, LoaderFirmwarePermanent);
|
||||||
if(Status != STATUS_EFI_SUCCESS)
|
if(Status != STATUS_EFI_SUCCESS)
|
||||||
{
|
{
|
||||||
XtLdrProtocol->Memory.FreePages(Address, Pages);
|
XtLdrProtocol->Memory.FreePages(Address, Pages);
|
||||||
@@ -353,8 +336,8 @@ Xtos::GetSystemResourcesList(IN PXTBL_PAGE_MAPPING PageMap,
|
|||||||
FrameBufferResource->Header.VirtualAddress = *VirtualAddress;
|
FrameBufferResource->Header.VirtualAddress = *VirtualAddress;
|
||||||
|
|
||||||
/* Map frame buffer memory */
|
/* Map frame buffer memory */
|
||||||
XtLdrProtocol->Memory.MapVirtualMemory(PageMap, (ULONGLONG)FrameBufferResource->Header.VirtualAddress,
|
XtLdrProtocol->Memory.MapVirtualMemory(PageMap, FrameBufferResource->Header.VirtualAddress,
|
||||||
(ULONGLONG)FrameBufferResource->Header.PhysicalAddress,
|
FrameBufferResource->Header.PhysicalAddress,
|
||||||
FrameBufferPages, LoaderFirmwarePermanent);
|
FrameBufferPages, LoaderFirmwarePermanent);
|
||||||
|
|
||||||
/* Close FrameBuffer protocol */
|
/* Close FrameBuffer protocol */
|
||||||
@@ -406,7 +389,7 @@ Xtos::InitializeApicBase(IN PXTBL_PAGE_MAPPING PageMap)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Map APIC base address */
|
/* Map APIC base address */
|
||||||
XtLdrProtocol->Memory.MapVirtualMemory(PageMap, APIC_BASE, (ULONGLONG)ApicBaseAddress, 1, LoaderFirmwarePermanent);
|
XtLdrProtocol->Memory.MapVirtualMemory(PageMap, (PVOID)APIC_BASE, ApicBaseAddress, 1, LoaderFirmwarePermanent);
|
||||||
return STATUS_EFI_SUCCESS;
|
return STATUS_EFI_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -473,7 +456,7 @@ Xtos::InitializeLoaderBlock(IN PXTBL_PAGE_MAPPING PageMap,
|
|||||||
ParametersSize);
|
ParametersSize);
|
||||||
|
|
||||||
/* Map kernel initialization block */
|
/* Map kernel initialization block */
|
||||||
XtLdrProtocol->Memory.MapVirtualMemory(PageMap, (ULONGLONG)*VirtualAddress, (ULONGLONG)LoaderBlock,
|
XtLdrProtocol->Memory.MapVirtualMemory(PageMap, *VirtualAddress, (PVOID)LoaderBlock,
|
||||||
BlockPages, LoaderSystemBlock);
|
BlockPages, LoaderSystemBlock);
|
||||||
|
|
||||||
/* Calculate next valid virtual address */
|
/* Calculate next valid virtual address */
|
||||||
@@ -486,9 +469,6 @@ Xtos::InitializeLoaderBlock(IN PXTBL_PAGE_MAPPING PageMap,
|
|||||||
XtLdrProtocol->LinkedList.InitializeHead(&LoaderBlock->MemoryDescriptorListHead);
|
XtLdrProtocol->LinkedList.InitializeHead(&LoaderBlock->MemoryDescriptorListHead);
|
||||||
GetMemoryDescriptorList(PageMap, VirtualAddress, &LoaderBlock->MemoryDescriptorListHead);
|
GetMemoryDescriptorList(PageMap, VirtualAddress, &LoaderBlock->MemoryDescriptorListHead);
|
||||||
|
|
||||||
/* Set boot image size */
|
|
||||||
LoaderBlock->BootImageSize = (PFN_NUMBER)(((ULONGLONG)*VirtualAddress - KSEG0_BASE) / EFI_PAGE_SIZE);
|
|
||||||
|
|
||||||
/* Return success */
|
/* Return success */
|
||||||
return STATUS_EFI_SUCCESS;
|
return STATUS_EFI_SUCCESS;
|
||||||
}
|
}
|
||||||
@@ -627,12 +607,11 @@ Xtos::RunBootSequence(IN PEFI_FILE_HANDLE BootDir,
|
|||||||
PXTBL_FRAMEBUFFER_PROTOCOL FrameBufProtocol;
|
PXTBL_FRAMEBUFFER_PROTOCOL FrameBufProtocol;
|
||||||
PPECOFF_IMAGE_CONTEXT ImageContext = NULLPTR;
|
PPECOFF_IMAGE_CONTEXT ImageContext = NULLPTR;
|
||||||
PEFI_LOADED_IMAGE_PROTOCOL ImageProtocol;
|
PEFI_LOADED_IMAGE_PROTOCOL ImageProtocol;
|
||||||
PVOID VirtualAddress;
|
PVOID VirtualAddress, VirtualMemoryArea;
|
||||||
PXT_ENTRY_POINT KernelEntryPoint;
|
PXT_ENTRY_POINT KernelEntryPoint;
|
||||||
EFI_HANDLE ProtocolHandle;
|
EFI_HANDLE ProtocolHandle;
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
XTBL_PAGE_MAPPING PageMap;
|
XTBL_PAGE_MAPPING PageMap;
|
||||||
BOOLEAN IdentityMapping;
|
|
||||||
|
|
||||||
/* Initialize XTOS startup sequence */
|
/* Initialize XTOS startup sequence */
|
||||||
XtLdrProtocol->Debug.Print(L"Initializing XTOS startup sequence\n");
|
XtLdrProtocol->Debug.Print(L"Initializing XTOS startup sequence\n");
|
||||||
@@ -649,30 +628,19 @@ Xtos::RunBootSequence(IN PEFI_FILE_HANDLE BootDir,
|
|||||||
/* Close FrameBuffer protocol */
|
/* Close FrameBuffer protocol */
|
||||||
XtLdrProtocol->Protocol.Close(&ProtocolHandle, &FrameBufGuid);
|
XtLdrProtocol->Protocol.Close(&ProtocolHandle, &FrameBufGuid);
|
||||||
|
|
||||||
/* Determine whether to use a sequential or an identity mapping strategy */
|
|
||||||
IdentityMapping = DetermineMappingStrategy();
|
|
||||||
|
|
||||||
/* Set base virtual memory area for the kernel mappings */
|
/* Set base virtual memory area for the kernel mappings */
|
||||||
VirtualAddress = (PVOID)(KSEG0_BASE);
|
VirtualMemoryArea = (PVOID)KSEG0_BASE;
|
||||||
|
VirtualAddress = (PVOID)(KSEG0_BASE + KSEG0_KERNEL_BASE);
|
||||||
|
|
||||||
/* Initialize virtual memory mappings */
|
/* Initialize virtual memory mappings */
|
||||||
XtLdrProtocol->Memory.InitializePageMap(&PageMap, DeterminePagingLevel(Parameters->Parameters), Size4K);
|
XtLdrProtocol->Memory.InitializePageMap(&PageMap, DeterminePagingLevel(Parameters->Parameters), Size4K);
|
||||||
|
|
||||||
/* Map all EFI memory regions */
|
Status = XtLdrProtocol->Memory.MapEfiMemory(&PageMap, &VirtualMemoryArea, NULLPTR);
|
||||||
Status = XtLdrProtocol->Memory.MapEfiMemory(&PageMap, &VirtualAddress, IdentityMapping, NULLPTR);
|
|
||||||
if(Status != STATUS_EFI_SUCCESS)
|
if(Status != STATUS_EFI_SUCCESS)
|
||||||
{
|
{
|
||||||
/* Mapping failed */
|
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check mapping strategy */
|
|
||||||
if(IdentityMapping)
|
|
||||||
{
|
|
||||||
/* Adjust virtual address to skip the identity-mapped physical range */
|
|
||||||
VirtualAddress = (PVOID)((ULONGLONG)VirtualAddress + 0x800000000);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Load the kernel */
|
/* Load the kernel */
|
||||||
Status = LoadModule(BootDir, Parameters->KernelFile, VirtualAddress, LoaderSystemCode, &ImageContext);
|
Status = LoadModule(BootDir, Parameters->KernelFile, VirtualAddress, LoaderSystemCode, &ImageContext);
|
||||||
if(Status != STATUS_EFI_SUCCESS)
|
if(Status != STATUS_EFI_SUCCESS)
|
||||||
@@ -682,8 +650,8 @@ Xtos::RunBootSequence(IN PEFI_FILE_HANDLE BootDir,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Add kernel image memory mapping */
|
/* Add kernel image memory mapping */
|
||||||
Status = XtLdrProtocol->Memory.MapVirtualMemory(&PageMap, (ULONGLONG)ImageContext->VirtualAddress,
|
Status = XtLdrProtocol->Memory.MapVirtualMemory(&PageMap, ImageContext->VirtualAddress,
|
||||||
(ULONGLONG)ImageContext->PhysicalAddress, ImageContext->ImagePages,
|
ImageContext->PhysicalAddress, ImageContext->ImagePages,
|
||||||
LoaderSystemCode);
|
LoaderSystemCode);
|
||||||
if(Status != STATUS_EFI_SUCCESS)
|
if(Status != STATUS_EFI_SUCCESS)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -236,15 +236,6 @@ BlStartXtLoader(IN EFI_HANDLE ImageHandle,
|
|||||||
PWCHAR Modules;
|
PWCHAR Modules;
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
|
|
||||||
/* Check if system is EFI-based and provided parameters are valid */
|
|
||||||
if(ImageHandle == NULLPTR || SystemTable == NULLPTR)
|
|
||||||
{
|
|
||||||
/* Invalid parameters, print error message using BIOS calls and hang */
|
|
||||||
BiosUtils::ClearScreen();
|
|
||||||
BiosUtils::Print(L"XTLDR requires EFI-based system!");
|
|
||||||
for(;;);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Initialize XTLDR and */
|
/* Initialize XTLDR and */
|
||||||
XtLoader::InitializeBootLoader(ImageHandle, SystemTable);
|
XtLoader::InitializeBootLoader(ImageHandle, SystemTable);
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,2 @@
|
|||||||
# Set base addresses for all modules
|
# Set base addresses for all modules
|
||||||
set(BASEADDRESS_XTLDR 0x000000000000F800)
|
|
||||||
set(BASEADDRESS_XTOSKRNL 0x0000000140000000)
|
set(BASEADDRESS_XTOSKRNL 0x0000000140000000)
|
||||||
|
|||||||
@@ -1,3 +1,2 @@
|
|||||||
# Set base addresses for all modules
|
# Set base addresses for all modules
|
||||||
set(BASEADDRESS_XTLDR 0x0000F800)
|
|
||||||
set(BASEADDRESS_XTOSKRNL 0x00400000)
|
set(BASEADDRESS_XTOSKRNL 0x00400000)
|
||||||
|
|||||||
@@ -64,17 +64,11 @@ function(compile_bootsector NAME SOURCE BASEADDR ENTRYPOINT)
|
|||||||
set(BINARY_NAME "${NAME}.bin")
|
set(BINARY_NAME "${NAME}.bin")
|
||||||
set(OBJECT_NAME "${NAME}.obj")
|
set(OBJECT_NAME "${NAME}.obj")
|
||||||
|
|
||||||
get_directory_property(DEFS COMPILE_DEFINITIONS)
|
|
||||||
foreach(def ${DEFS})
|
|
||||||
list(APPEND ASM_DEFS "-D${def}")
|
|
||||||
endforeach()
|
|
||||||
|
|
||||||
add_custom_command(
|
add_custom_command(
|
||||||
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${BINARY_NAME}
|
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${BINARY_NAME}
|
||||||
COMMAND ${CMAKE_ASM_COMPILER}
|
COMMAND ${CMAKE_ASM_COMPILER}
|
||||||
/nologo
|
/nologo
|
||||||
--target=i386-none-elf
|
--target=i386-none-elf
|
||||||
${ASM_DEFS}
|
|
||||||
-I${CMAKE_CURRENT_SOURCE_DIR}
|
-I${CMAKE_CURRENT_SOURCE_DIR}
|
||||||
/Fo${CMAKE_CURRENT_BINARY_DIR}/${OBJECT_NAME}
|
/Fo${CMAKE_CURRENT_BINARY_DIR}/${OBJECT_NAME}
|
||||||
-c -- ${SOURCE}
|
-c -- ${SOURCE}
|
||||||
|
|||||||
@@ -108,6 +108,9 @@
|
|||||||
/* Static Kernel-Mode address start */
|
/* Static Kernel-Mode address start */
|
||||||
#define KSEG0_BASE 0xFFFFF80000000000
|
#define KSEG0_BASE 0xFFFFF80000000000
|
||||||
|
|
||||||
|
/* XTOS Kernel address base */
|
||||||
|
#define KSEG0_KERNEL_BASE 0x0000000800000000
|
||||||
|
|
||||||
/* XTOS Kernel stack size */
|
/* XTOS Kernel stack size */
|
||||||
#define KERNEL_STACK_SIZE 0x8000
|
#define KERNEL_STACK_SIZE 0x8000
|
||||||
|
|
||||||
@@ -269,18 +272,11 @@ typedef struct _KIDTENTRY
|
|||||||
{
|
{
|
||||||
USHORT OffsetLow;
|
USHORT OffsetLow;
|
||||||
USHORT Selector;
|
USHORT Selector;
|
||||||
union
|
|
||||||
{
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
USHORT IstIndex:3;
|
USHORT IstIndex:3;
|
||||||
USHORT Reserved0:5;
|
USHORT Reserved0:5;
|
||||||
USHORT Type:5;
|
USHORT Type:5;
|
||||||
USHORT Dpl:2;
|
USHORT Dpl:2;
|
||||||
USHORT Present:1;
|
USHORT Present:1;
|
||||||
};
|
|
||||||
USHORT Access;
|
|
||||||
};
|
|
||||||
USHORT OffsetMiddle;
|
USHORT OffsetMiddle;
|
||||||
ULONG OffsetHigh;
|
ULONG OffsetHigh;
|
||||||
ULONG Reserved1;
|
ULONG Reserved1;
|
||||||
|
|||||||
@@ -25,11 +25,11 @@
|
|||||||
#define MM_PXE_BASE 0xFFFFF6FB7DBED000ULL
|
#define MM_PXE_BASE 0xFFFFF6FB7DBED000ULL
|
||||||
|
|
||||||
/* Page directory and page base addresses for 5-level paging */
|
/* Page directory and page base addresses for 5-level paging */
|
||||||
#define MM_PTE_LA57_BASE 0xFFED000000000000ULL
|
#define MM_PTE_LA57_BASE 0xFFFF000000000000ULL
|
||||||
#define MM_PDE_LA57_BASE 0xFFEDF68000000000ULL
|
#define MM_PDE_LA57_BASE 0xFFFF010000000000ULL
|
||||||
#define MM_PPE_LA57_BASE 0xFFEDF6FB40000000ULL
|
#define MM_PPE_LA57_BASE 0xFFFF010800000000ULL
|
||||||
#define MM_PXE_LA57_BASE 0xFFEDF6FB7DA00000ULL
|
#define MM_PXE_LA57_BASE 0xFFFF010840000000ULL
|
||||||
#define MM_P5E_LA57_BASE 0xFFEDF6FB7DBED000ULL
|
#define MM_P5E_LA57_BASE 0xFFFF010840200000ULL
|
||||||
|
|
||||||
/* PTE shift values */
|
/* PTE shift values */
|
||||||
#define MM_PTE_SHIFT 3
|
#define MM_PTE_SHIFT 3
|
||||||
@@ -39,56 +39,15 @@
|
|||||||
#define MM_PXI_SHIFT 39
|
#define MM_PXI_SHIFT 39
|
||||||
#define MM_P5I_SHIFT 48
|
#define MM_P5I_SHIFT 48
|
||||||
|
|
||||||
/* PTE state flags */
|
/* Number of PTEs per page */
|
||||||
#define MM_PTE_VALID 0x0000000000000001ULL
|
#define MM_PTE_PER_PAGE 512
|
||||||
#define MM_PTE_ACCESSED 0x0000000000000020ULL
|
#define MM_PDE_PER_PAGE 512
|
||||||
#define MM_PTE_DIRTY 0x0000000000000040ULL
|
#define MM_PPE_PER_PAGE 512
|
||||||
|
#define MM_PXE_PER_PAGE 512
|
||||||
/* PTE scope flags */
|
|
||||||
#define MM_PTE_LARGE_PAGE 0x0000000000000080ULL
|
|
||||||
#define MM_PTE_GLOBAL 0x0000000000000100ULL
|
|
||||||
|
|
||||||
/* PTE access flags */
|
|
||||||
#define MM_PTE_NOACCESS 0x0000000000000000ULL
|
|
||||||
#define MM_PTE_READONLY 0x0000000000000000ULL
|
|
||||||
#define MM_PTE_EXECUTE 0x0000000000000000ULL
|
|
||||||
#define MM_PTE_EXECUTE_READ 0x0000000000000000ULL
|
|
||||||
#define MM_PTE_READWRITE 0x8000000000000002ULL
|
|
||||||
#define MM_PTE_WRITECOPY 0x8000000000000200ULL
|
|
||||||
#define MM_PTE_EXECUTE_READWRITE 0x0000000000000002ULL
|
|
||||||
#define MM_PTE_EXECUTE_WRITECOPY 0x0000000000000200ULL
|
|
||||||
|
|
||||||
/* PTE protection flags */
|
|
||||||
#define MM_PTE_NOEXECUTE 0x8000000000000000ULL
|
|
||||||
#define MM_PTE_GUARDED 0x8000000000000018ULL
|
|
||||||
#define MM_PTE_PROTECT 0x8000000000000612ULL
|
|
||||||
|
|
||||||
/* PTE cache flags */
|
|
||||||
#define MM_PTE_CACHE_ENABLE 0x0000000000000000ULL
|
|
||||||
#define MM_PTE_CACHE_DISABLE 0x0000000000000010ULL
|
|
||||||
#define MM_PTE_CACHE_WRITECOMBINED 0x0000000000000010ULL
|
|
||||||
#define MM_PTE_CACHE_WRITETHROUGH 0x0000000000000008ULL
|
|
||||||
|
|
||||||
/* PTE software flags */
|
|
||||||
#define MM_PTE_COPY_ON_WRITE 0x0000000000000200ULL
|
|
||||||
#define MM_PTE_PROTOTYPE 0x0000000000000400ULL
|
|
||||||
#define MM_PTE_TRANSITION 0x0000000000000800ULL
|
|
||||||
|
|
||||||
/* PTE frame bits */
|
|
||||||
#define MM_PTE_FRAME_BITS 57
|
|
||||||
|
|
||||||
/* PTE protection bits */
|
|
||||||
#define MM_PTE_PROTECTION_BITS 5
|
|
||||||
|
|
||||||
/* Base address of the system page table */
|
|
||||||
#define MM_SYSTEM_PTE_BASE KSEG0_BASE
|
|
||||||
|
|
||||||
/* Minimum number of physical pages needed by the system */
|
/* Minimum number of physical pages needed by the system */
|
||||||
#define MM_MINIMUM_PHYSICAL_PAGES 2048
|
#define MM_MINIMUM_PHYSICAL_PAGES 2048
|
||||||
|
|
||||||
/* Number of system PTEs */
|
|
||||||
#define MM_DEFAULT_NUMBER_SYSTEM_PTES 22000
|
|
||||||
|
|
||||||
/* Default number of secondary colors */
|
/* Default number of secondary colors */
|
||||||
#define MM_DEFAULT_SECONDARY_COLORS 64
|
#define MM_DEFAULT_SECONDARY_COLORS 64
|
||||||
|
|
||||||
@@ -104,9 +63,6 @@
|
|||||||
/* Maximum physical address used by HAL allocations */
|
/* Maximum physical address used by HAL allocations */
|
||||||
#define MM_MAXIMUM_PHYSICAL_ADDRESS 0x00000000FFFFFFFFULL
|
#define MM_MAXIMUM_PHYSICAL_ADDRESS 0x00000000FFFFFFFFULL
|
||||||
|
|
||||||
/* Highest system address */
|
|
||||||
#define MM_HIGHEST_SYSTEM_ADDRESS 0xFFFFFFFFFFFFFFFFULL
|
|
||||||
|
|
||||||
/* Trampoline code address */
|
/* Trampoline code address */
|
||||||
#define MM_TRAMPOLINE_ADDRESS 0x80000
|
#define MM_TRAMPOLINE_ADDRESS 0x80000
|
||||||
|
|
||||||
@@ -296,7 +252,6 @@ typedef struct _MMPFN
|
|||||||
USHORT ReferenceCount;
|
USHORT ReferenceCount;
|
||||||
} e2;
|
} e2;
|
||||||
} u3;
|
} u3;
|
||||||
ULONG UsedPageTableEntries;
|
|
||||||
union
|
union
|
||||||
{
|
{
|
||||||
MMPTE OriginalPte;
|
MMPTE OriginalPte;
|
||||||
@@ -307,11 +262,12 @@ typedef struct _MMPFN
|
|||||||
ULONG_PTR EntireFrame;
|
ULONG_PTR EntireFrame;
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
ULONG_PTR PteFrame:57;
|
ULONG_PTR PteFrame:58;
|
||||||
ULONG_PTR InPageError:1;
|
ULONG_PTR InPageError:1;
|
||||||
ULONG_PTR VerifierAllocation:1;
|
ULONG_PTR VerifierAllocation:1;
|
||||||
ULONG_PTR AweAllocation:1;
|
ULONG_PTR AweAllocation:1;
|
||||||
ULONG_PTR Priority:3;
|
ULONG_PTR LockCharged:1;
|
||||||
|
ULONG_PTR KernelStack:1;
|
||||||
ULONG_PTR MustBeCached:1;
|
ULONG_PTR MustBeCached:1;
|
||||||
};
|
};
|
||||||
} u4;
|
} u4;
|
||||||
|
|||||||
@@ -100,9 +100,9 @@ typedef VOID (XTCDECL *PBL_LLIST_INITIALIZE_HEAD)(IN PLIST_ENTRY ListHead);
|
|||||||
typedef VOID (XTCDECL *PBL_LLIST_INSERT_HEAD)(IN OUT PLIST_ENTRY ListHead, IN PLIST_ENTRY Entry);
|
typedef VOID (XTCDECL *PBL_LLIST_INSERT_HEAD)(IN OUT PLIST_ENTRY ListHead, IN PLIST_ENTRY Entry);
|
||||||
typedef VOID (XTCDECL *PBL_LLIST_INSERT_TAIL)(IN OUT PLIST_ENTRY ListHead, IN PLIST_ENTRY Entry);
|
typedef VOID (XTCDECL *PBL_LLIST_INSERT_TAIL)(IN OUT PLIST_ENTRY ListHead, IN PLIST_ENTRY Entry);
|
||||||
typedef VOID (XTCDECL *PBL_LLIST_REMOVE_ENTRY)(IN PLIST_ENTRY Entry);
|
typedef VOID (XTCDECL *PBL_LLIST_REMOVE_ENTRY)(IN PLIST_ENTRY Entry);
|
||||||
typedef EFI_STATUS (XTCDECL *PBL_MAP_EFI_MEMORY)(IN OUT PXTBL_PAGE_MAPPING PageMap, IN OUT PVOID *BaseAddress, IN BOOLEAN IdentityMapping, IN PBL_GET_MEMTYPE_ROUTINE GetMemoryTypeRoutine);
|
typedef EFI_STATUS (XTCDECL *PBL_MAP_EFI_MEMORY)(IN OUT PXTBL_PAGE_MAPPING PageMap, IN OUT PVOID *MemoryMapAddress, IN PBL_GET_MEMTYPE_ROUTINE GetMemoryTypeRoutine);
|
||||||
typedef EFI_STATUS (XTCDECL *PBL_MAP_PAGE)(IN PXTBL_PAGE_MAPPING PageMap, IN ULONGLONG VirtualAddress, IN ULONGLONG PhysicalAddress, IN ULONGLONG NumberOfPages);
|
typedef EFI_STATUS (XTCDECL *PBL_MAP_PAGE)(IN PXTBL_PAGE_MAPPING PageMap, IN ULONG_PTR VirtualAddress, IN ULONG_PTR PhysicalAddress, IN ULONG NumberOfPages);
|
||||||
typedef EFI_STATUS (XTCDECL *PBL_MAP_VIRTUAL_MEMORY)(IN OUT PXTBL_PAGE_MAPPING PageMap, IN ULONGLONG VirtualAddress, IN ULONGLONG PhysicalAddress, IN ULONGLONG NumberOfPages, IN LOADER_MEMORY_TYPE MemoryType);
|
typedef EFI_STATUS (XTCDECL *PBL_MAP_VIRTUAL_MEMORY)(IN OUT PXTBL_PAGE_MAPPING PageMap, IN PVOID VirtualAddress, IN PVOID PhysicalAddress, IN ULONGLONG NumberOfPages, IN LOADER_MEMORY_TYPE MemoryType);
|
||||||
typedef VOID (XTAPI *PBL_MOVE_MEMORY)(IN OUT PVOID Destination, IN PCVOID Source, IN SIZE_T Length);
|
typedef VOID (XTAPI *PBL_MOVE_MEMORY)(IN OUT PVOID Destination, IN PCVOID Source, IN SIZE_T Length);
|
||||||
typedef EFI_STATUS (XTCDECL *PBL_OPEN_VOLUME)(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath, OUT PEFI_HANDLE DiskHandle, OUT PEFI_FILE_HANDLE *FsHandle);
|
typedef EFI_STATUS (XTCDECL *PBL_OPEN_VOLUME)(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath, OUT PEFI_HANDLE DiskHandle, OUT PEFI_FILE_HANDLE *FsHandle);
|
||||||
typedef EFI_STATUS (XTCDECL *PBL_OPEN_PROTOCOL)(OUT PEFI_HANDLE Handle, OUT PVOID *ProtocolHandler, IN PEFI_GUID ProtocolGuid);
|
typedef EFI_STATUS (XTCDECL *PBL_OPEN_PROTOCOL)(OUT PEFI_HANDLE Handle, OUT PVOID *ProtocolHandler, IN PEFI_GUID ProtocolGuid);
|
||||||
@@ -232,8 +232,8 @@ typedef struct _XTBL_KNOWN_BOOT_PROTOCOL
|
|||||||
typedef struct _XTBL_MEMORY_MAPPING
|
typedef struct _XTBL_MEMORY_MAPPING
|
||||||
{
|
{
|
||||||
LIST_ENTRY ListEntry;
|
LIST_ENTRY ListEntry;
|
||||||
ULONGLONG VirtualAddress;
|
PVOID VirtualAddress;
|
||||||
ULONGLONG PhysicalAddress;
|
PVOID PhysicalAddress;
|
||||||
ULONGLONG NumberOfPages;
|
ULONGLONG NumberOfPages;
|
||||||
LOADER_MEMORY_TYPE MemoryType;
|
LOADER_MEMORY_TYPE MemoryType;
|
||||||
} XTBL_MEMORY_MAPPING, *PXTBL_MEMORY_MAPPING;
|
} XTBL_MEMORY_MAPPING, *PXTBL_MEMORY_MAPPING;
|
||||||
|
|||||||
@@ -58,6 +58,12 @@
|
|||||||
#define KIDT_ACCESS_RING0 0x00
|
#define KIDT_ACCESS_RING0 0x00
|
||||||
#define KIDT_ACCESS_RING3 0x60
|
#define KIDT_ACCESS_RING3 0x60
|
||||||
|
|
||||||
|
/* IDT gate types */
|
||||||
|
#define KIDT_TASK 0x05
|
||||||
|
#define KIDT_CALL 0x0C
|
||||||
|
#define KIDT_INTERRUPT 0x0E
|
||||||
|
#define KIDT_TRAP 0x0F
|
||||||
|
|
||||||
/* TSS Offsets */
|
/* TSS Offsets */
|
||||||
#define KTSS_ESP0 0x04
|
#define KTSS_ESP0 0x04
|
||||||
#define KTSS_CR3 0x1C
|
#define KTSS_CR3 0x1C
|
||||||
@@ -128,6 +134,9 @@
|
|||||||
/* Static Kernel-Mode address start */
|
/* Static Kernel-Mode address start */
|
||||||
#define KSEG0_BASE 0x80000000
|
#define KSEG0_BASE 0x80000000
|
||||||
|
|
||||||
|
/* XTOS Kernel address base */
|
||||||
|
#define KSEG0_KERNEL_BASE 0x01800000
|
||||||
|
|
||||||
/* XTOS Kernel stack size */
|
/* XTOS Kernel stack size */
|
||||||
#define KERNEL_STACK_SIZE 0x4000
|
#define KERNEL_STACK_SIZE 0x4000
|
||||||
|
|
||||||
@@ -275,18 +284,7 @@ typedef struct _KIDTENTRY
|
|||||||
{
|
{
|
||||||
USHORT Offset;
|
USHORT Offset;
|
||||||
USHORT Selector;
|
USHORT Selector;
|
||||||
union
|
|
||||||
{
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
UCHAR Reserved;
|
|
||||||
UCHAR Type:4;
|
|
||||||
UCHAR Flag:1;
|
|
||||||
UCHAR Dpl:2;
|
|
||||||
UCHAR Present:1;
|
|
||||||
};
|
|
||||||
USHORT Access;
|
USHORT Access;
|
||||||
};
|
|
||||||
USHORT ExtendedOffset;
|
USHORT ExtendedOffset;
|
||||||
} KIDTENTRY, *PKIDTENTRY;
|
} KIDTENTRY, *PKIDTENTRY;
|
||||||
|
|
||||||
|
|||||||
@@ -35,58 +35,9 @@
|
|||||||
#define MM_PTE_LEGACY_SHIFT 2
|
#define MM_PTE_LEGACY_SHIFT 2
|
||||||
#define MM_PDI_LEGACY_SHIFT 22
|
#define MM_PDI_LEGACY_SHIFT 22
|
||||||
|
|
||||||
/* PTE state flags */
|
|
||||||
#define MM_PTE_VALID 0x00000001
|
|
||||||
#define MM_PTE_ACCESSED 0x00000020
|
|
||||||
#define MM_PTE_DIRTY 0x00000040
|
|
||||||
|
|
||||||
/* PTE scope flags */
|
|
||||||
#define MM_PTE_LARGE_PAGE 0x00000080
|
|
||||||
#define MM_PTE_GLOBAL 0x00000100
|
|
||||||
|
|
||||||
/* PTE access flags */
|
|
||||||
#define MM_PTE_NOACCESS 0x00000000
|
|
||||||
#define MM_PTE_READONLY 0x00000000
|
|
||||||
#define MM_PTE_EXECUTE 0x00000000
|
|
||||||
#define MM_PTE_EXECUTE_READ 0x00000000
|
|
||||||
#define MM_PTE_READWRITE 0x00000002
|
|
||||||
#define MM_PTE_WRITECOPY 0x00000200
|
|
||||||
#define MM_PTE_EXECUTE_READWRITE 0x00000002
|
|
||||||
#define MM_PTE_EXECUTE_WRITECOPY 0x00000200
|
|
||||||
|
|
||||||
/* PTE protection flags */
|
|
||||||
#define MM_PTE_NOEXECUTE 0x00000000
|
|
||||||
#define MM_PTE_GUARDED 0x00000018
|
|
||||||
#define MM_PTE_PROTECT 0x00000612
|
|
||||||
|
|
||||||
/* PTE cache flags */
|
|
||||||
#define MM_PTE_CACHE_ENABLE 0x00000000
|
|
||||||
#define MM_PTE_CACHE_DISABLE 0x00000010
|
|
||||||
#define MM_PTE_CACHE_WRITECOMBINED 0x00000010
|
|
||||||
#define MM_PTE_CACHE_WRITETHROUGH 0x00000008
|
|
||||||
|
|
||||||
/* PTE software flags */
|
|
||||||
#define MM_PTE_COPY_ON_WRITE 0x00000200
|
|
||||||
#define MM_PTE_PROTOTYPE 0x00000400
|
|
||||||
#define MM_PTE_TRANSITION 0x00000800
|
|
||||||
|
|
||||||
/* PTE frame bits */
|
|
||||||
#define MM_PTE_FRAME_BITS 25
|
|
||||||
|
|
||||||
/* PTE protection bits */
|
|
||||||
#define MM_PTE_PROTECTION_BITS 5
|
|
||||||
|
|
||||||
/* Base address of the system page table */
|
|
||||||
#define MM_SYSTEM_PTE_BASE NULLPTR
|
|
||||||
|
|
||||||
/* Minimum number of physical pages needed by the system */
|
/* Minimum number of physical pages needed by the system */
|
||||||
#define MM_MINIMUM_PHYSICAL_PAGES 1100
|
#define MM_MINIMUM_PHYSICAL_PAGES 1100
|
||||||
|
|
||||||
/* Number of system PTEs */
|
|
||||||
#define MM_MINIMUM_NUMBER_SYSTEM_PTES 7000
|
|
||||||
#define MM_DEFAULT_NUMBER_SYSTEM_PTES 11000
|
|
||||||
#define MM_MAXIMUM_NUMBER_SYSTEM_PTES 22000
|
|
||||||
|
|
||||||
/* Default number of secondary colors */
|
/* Default number of secondary colors */
|
||||||
#define MM_DEFAULT_SECONDARY_COLORS 64
|
#define MM_DEFAULT_SECONDARY_COLORS 64
|
||||||
|
|
||||||
@@ -102,9 +53,6 @@
|
|||||||
/* 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
|
||||||
|
|
||||||
/* Highest system address */
|
|
||||||
#define MM_HIGHEST_SYSTEM_ADDRESS 0xFFFFFFFF
|
|
||||||
|
|
||||||
/* Trampoline code address */
|
/* Trampoline code address */
|
||||||
#define MM_TRAMPOLINE_ADDRESS 0x80000
|
#define MM_TRAMPOLINE_ADDRESS 0x80000
|
||||||
|
|
||||||
@@ -158,6 +106,7 @@ typedef struct _HARDWARE_MODERN_PTE
|
|||||||
/* Generic Page Table entry union to abstract PML2 and PML3 formats */
|
/* Generic Page Table entry union to abstract PML2 and PML3 formats */
|
||||||
typedef union _HARDWARE_PTE
|
typedef union _HARDWARE_PTE
|
||||||
{
|
{
|
||||||
|
ULONGLONG Long;
|
||||||
HARDWARE_LEGACY_PTE Pml2;
|
HARDWARE_LEGACY_PTE Pml2;
|
||||||
HARDWARE_MODERN_PTE Pml3;
|
HARDWARE_MODERN_PTE Pml3;
|
||||||
} HARDWARE_PTE, *PHARDWARE_PTE;
|
} HARDWARE_PTE, *PHARDWARE_PTE;
|
||||||
@@ -252,12 +201,12 @@ typedef struct _MMPML2_PTE_TRANSITION
|
|||||||
typedef union _MMPML2_PTE
|
typedef union _MMPML2_PTE
|
||||||
{
|
{
|
||||||
ULONG Long;
|
ULONG Long;
|
||||||
HARDWARE_LEGACY_PTE Flush;
|
HARDWARE_PTE Flush;
|
||||||
MMPML2_PTE_HARDWARE Hardware;
|
MMPML2_PTE_HARDWARE Hard;
|
||||||
MMPML2_PTE_PROTOTYPE Prototype;
|
MMPML2_PTE_PROTOTYPE Proto;
|
||||||
MMPML2_PTE_SOFTWARE Software;
|
MMPML2_PTE_SOFTWARE Soft;
|
||||||
MMPML2_PTE_TRANSITION Transition;
|
MMPML2_PTE_TRANSITION Trans;
|
||||||
MMPML2_PTE_SUBSECTION Subsection;
|
MMPML2_PTE_SUBSECTION Subsect;
|
||||||
MMPML2_PTE_LIST List;
|
MMPML2_PTE_LIST List;
|
||||||
} MMPML2_PTE, *PMMPML2_PTE;
|
} MMPML2_PTE, *PMMPML2_PTE;
|
||||||
|
|
||||||
@@ -347,7 +296,7 @@ typedef struct _MMPML3_PTE_TRANSITION
|
|||||||
typedef union _MMPML3_PTE
|
typedef union _MMPML3_PTE
|
||||||
{
|
{
|
||||||
ULONGLONG Long;
|
ULONGLONG Long;
|
||||||
HARDWARE_MODERN_PTE Flush;
|
HARDWARE_PTE Flush;
|
||||||
MMPML3_PTE_HARDWARE Hardware;
|
MMPML3_PTE_HARDWARE Hardware;
|
||||||
MMPML3_PTE_PROTOTYPE Prototype;
|
MMPML3_PTE_PROTOTYPE Prototype;
|
||||||
MMPML3_PTE_SOFTWARE Software;
|
MMPML3_PTE_SOFTWARE Software;
|
||||||
@@ -359,6 +308,7 @@ typedef union _MMPML3_PTE
|
|||||||
/* Generic Page Table Entry union to abstract PML2 and PML3 formats */
|
/* Generic Page Table Entry union to abstract PML2 and PML3 formats */
|
||||||
typedef union _MMPTE
|
typedef union _MMPTE
|
||||||
{
|
{
|
||||||
|
ULONGLONG Long;
|
||||||
MMPML2_PTE Pml2;
|
MMPML2_PTE Pml2;
|
||||||
MMPML3_PTE Pml3;
|
MMPML3_PTE Pml3;
|
||||||
} MMPTE, *PMMPTE;
|
} MMPTE, *PMMPTE;
|
||||||
@@ -389,7 +339,6 @@ typedef struct _MMPFN
|
|||||||
USHORT ReferenceCount;
|
USHORT ReferenceCount;
|
||||||
} e2;
|
} e2;
|
||||||
} u3;
|
} u3;
|
||||||
ULONG UsedPageTableEntries;
|
|
||||||
union
|
union
|
||||||
{
|
{
|
||||||
MMPTE OriginalPte;
|
MMPTE OriginalPte;
|
||||||
@@ -400,11 +349,12 @@ typedef struct _MMPFN
|
|||||||
ULONG_PTR EntireFrame;
|
ULONG_PTR EntireFrame;
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
ULONG_PTR PteFrame:25;
|
ULONG_PTR PteFrame:26;
|
||||||
ULONG_PTR InPageError:1;
|
ULONG_PTR InPageError:1;
|
||||||
ULONG_PTR VerifierAllocation:1;
|
ULONG_PTR VerifierAllocation:1;
|
||||||
ULONG_PTR AweAllocation:1;
|
ULONG_PTR AweAllocation:1;
|
||||||
ULONG_PTR Priority:3;
|
ULONG_PTR LockCharged:1;
|
||||||
|
ULONG_PTR KernelStack:1;
|
||||||
ULONG_PTR MustBeCached:1;
|
ULONG_PTR MustBeCached:1;
|
||||||
};
|
};
|
||||||
} u4;
|
} u4;
|
||||||
|
|||||||
@@ -150,23 +150,21 @@ typedef enum _KTHREAD_STATE
|
|||||||
typedef enum _KSPIN_LOCK_QUEUE_LEVEL
|
typedef enum _KSPIN_LOCK_QUEUE_LEVEL
|
||||||
{
|
{
|
||||||
DispatcherLock,
|
DispatcherLock,
|
||||||
ExpansionLock,
|
UnusedSpareLock,
|
||||||
PfnLock,
|
PfnLock,
|
||||||
SystemSpaceLock,
|
SystemSpaceLock,
|
||||||
VacbLock,
|
VacbLock,
|
||||||
MasterLock,
|
MasterLock,
|
||||||
NonPagedAllocPoolLock,
|
NonPagedPoolLock,
|
||||||
IoCancelLock,
|
IoCancelLock,
|
||||||
WorkQueueLock,
|
WorkQueueLock,
|
||||||
IoVpbLock,
|
IoVpbLock,
|
||||||
IoDatabaseLock,
|
IoDatabaseLock,
|
||||||
IoCompletionLock,
|
IoCompletionLock,
|
||||||
FileSystemLock,
|
FsStructLock,
|
||||||
AfdWorkQueueLock,
|
AfdWorkQueueLock,
|
||||||
BcbLock,
|
BcbLock,
|
||||||
NonPagedPoolLock,
|
MmNonPagedPoolLock,
|
||||||
ReservedSystemLock,
|
|
||||||
TimerTableLock,
|
|
||||||
MaximumLock
|
MaximumLock
|
||||||
} KSPIN_LOCK_QUEUE_LEVEL, *PKSPIN_LOCK_QUEUE_LEVEL;
|
} KSPIN_LOCK_QUEUE_LEVEL, *PKSPIN_LOCK_QUEUE_LEVEL;
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
* FILE: sdk/xtdk/mmtypes.h
|
* FILE: sdk/xtdk/mmtypes.h
|
||||||
* DESCRIPTION: Memory management data structures
|
* DESCRIPTION: Memory management data structures
|
||||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||||
* Aiken Harris <harraiken91@gmail.com>
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __XTDK_MMTYPES_H
|
#ifndef __XTDK_MMTYPES_H
|
||||||
@@ -14,72 +13,6 @@
|
|||||||
#include ARCH_HEADER(xtstruct.h)
|
#include ARCH_HEADER(xtstruct.h)
|
||||||
|
|
||||||
|
|
||||||
/* Number of hyper space pages */
|
|
||||||
#define MM_HYPERSPACE_PAGE_COUNT 255
|
|
||||||
|
|
||||||
/* Number of free page list heads */
|
|
||||||
#define MM_MAX_FREE_PAGE_LIST_HEADS 4
|
|
||||||
|
|
||||||
/* Number of paging colors */
|
|
||||||
#define MM_PAGING_COLORS 64
|
|
||||||
|
|
||||||
/* PTE frame mask definition */
|
|
||||||
#define MM_PFN_PTE_FRAME (((ULONG_PTR)1 << MM_PTE_FRAME_BITS) - 1)
|
|
||||||
|
|
||||||
/* Memory manager pool type mask definition */
|
|
||||||
#define MM_POOL_TYPE_MASK 1
|
|
||||||
|
|
||||||
/* Number of reserved zeroed PTEs */
|
|
||||||
#define MM_RESERVED_ZERO_PTES 32
|
|
||||||
|
|
||||||
/* Memory manager page lists */
|
|
||||||
typedef enum _MMPAGELISTS
|
|
||||||
{
|
|
||||||
ZeroedPageList = 0,
|
|
||||||
FreePageList = 1,
|
|
||||||
StandbyPageList = 2,
|
|
||||||
ModifiedPageList = 3,
|
|
||||||
ModifiedReadOnlyPageList = 4,
|
|
||||||
BadPageList = 5,
|
|
||||||
ActiveAndValid = 6,
|
|
||||||
TransitionPage = 7
|
|
||||||
} MMPAGELISTS, *PMMPAGELISTS;
|
|
||||||
|
|
||||||
/* Page cache attributes */
|
|
||||||
typedef enum _MMPFN_CACHE_ATTRIBUTE
|
|
||||||
{
|
|
||||||
PfnNonCached,
|
|
||||||
PfnCached,
|
|
||||||
PfnWriteCombined,
|
|
||||||
PfnNotMapped
|
|
||||||
} MMPFN_CACHE_ATTRIBUTE, *PMMPFN_CACHE_ATTRIBUTE;
|
|
||||||
|
|
||||||
/* Memory Manager pool types */
|
|
||||||
typedef enum _MMPOOL_TYPE
|
|
||||||
{
|
|
||||||
NonPagedPool = 0,
|
|
||||||
PagedPool = 1,
|
|
||||||
NonPagedPoolMustSucceed = 2,
|
|
||||||
NonPagedPoolCacheAligned = 4,
|
|
||||||
PagedPoolCacheAligned = 5,
|
|
||||||
NonPagedPoolCacheAlignedMustS = 6,
|
|
||||||
MaxPoolType = 7,
|
|
||||||
NonPagedPoolSession = 32,
|
|
||||||
PagedPoolSession = 33,
|
|
||||||
NonPagedPoolMustSucceedSession = 34,
|
|
||||||
NonPagedPoolCacheAlignedSession = 36,
|
|
||||||
PagedPoolCacheAlignedSession = 37,
|
|
||||||
NonPagedPoolCacheAlignedMustSSession = 38
|
|
||||||
} MMPOOL_TYPE, *PMMPOOL_TYPE;
|
|
||||||
|
|
||||||
/* Page table pool types */
|
|
||||||
typedef enum _MMSYSTEM_PTE_POOL_TYPE
|
|
||||||
{
|
|
||||||
SystemPteSpace,
|
|
||||||
NonPagedPoolExpansion,
|
|
||||||
MaximumPtePoolTypes
|
|
||||||
} MMSYSTEM_PTE_POOL_TYPE, *PMMSYSTEM_PTE_POOL_TYPE;
|
|
||||||
|
|
||||||
/* Page map routines structure definition */
|
/* Page map routines structure definition */
|
||||||
typedef CONST STRUCT _CMMPAGEMAP_ROUTINES
|
typedef CONST STRUCT _CMMPAGEMAP_ROUTINES
|
||||||
{
|
{
|
||||||
@@ -97,57 +30,6 @@ typedef struct _MMCOLOR_TABLES
|
|||||||
ULONG_PTR Count;
|
ULONG_PTR Count;
|
||||||
} MMCOLOR_TABLES, *PMMCOLOR_TABLES;
|
} MMCOLOR_TABLES, *PMMCOLOR_TABLES;
|
||||||
|
|
||||||
/* Free pool entry structure definition */
|
|
||||||
typedef struct _MMFREE_POOL_ENTRY
|
|
||||||
{
|
|
||||||
LIST_ENTRY List;
|
|
||||||
PFN_COUNT Size;
|
|
||||||
} MMFREE_POOL_ENTRY, *PMMFREE_POOL_ENTRY;
|
|
||||||
|
|
||||||
/* Memory layout structure definition */
|
|
||||||
typedef struct _MMMEMORY_LAYOUT
|
|
||||||
{
|
|
||||||
PMMPFN PfnDatabase;
|
|
||||||
PFN_NUMBER PfnDatabaseSize;
|
|
||||||
PVOID SelfMapAddress;
|
|
||||||
PVOID HardwarePoolStart;
|
|
||||||
PVOID HardwarePoolEnd;
|
|
||||||
PVOID HyperSpaceStart;
|
|
||||||
PVOID HyperSpaceEnd;
|
|
||||||
PVOID LoaderMappingsStart;
|
|
||||||
PVOID LoaderMappingsEnd;
|
|
||||||
PFN_NUMBER LoaderMappingsSize;
|
|
||||||
PVOID NonCanonicalStart;
|
|
||||||
PVOID NonCanonicalEnd;
|
|
||||||
PVOID NonPagedPoolStart;
|
|
||||||
PVOID NonPagedPoolEnd;
|
|
||||||
PFN_NUMBER NonPagedPoolSize;
|
|
||||||
PVOID NonPagedExpansionPoolStart;
|
|
||||||
PVOID NonPagedExpansionPoolEnd;
|
|
||||||
PFN_NUMBER NonPagedExpansionPoolSize;
|
|
||||||
PVOID NonPagedSystemPoolStart;
|
|
||||||
PVOID NonPagedSystemPoolEnd;
|
|
||||||
PFN_NUMBER NonPagedSystemPoolSize;
|
|
||||||
PVOID PagedPoolStart;
|
|
||||||
PVOID PagedPoolEnd;
|
|
||||||
PFN_NUMBER PagedPoolSize;
|
|
||||||
PVOID ReservedSystemPoolStart;
|
|
||||||
PVOID ReservedSystemPoolEnd;
|
|
||||||
PVOID SessionSpaceStart;
|
|
||||||
PVOID SessionSpaceEnd;
|
|
||||||
PFN_NUMBER SessionSpaceSize;
|
|
||||||
PVOID SharedSystemPageStart;
|
|
||||||
PVOID SharedSystemPageEnd;
|
|
||||||
PVOID SystemCacheStart;
|
|
||||||
PVOID SystemCacheEnd;
|
|
||||||
PVOID SystemWorkingSetStart;
|
|
||||||
PVOID SystemWorkingSetEnd;
|
|
||||||
PVOID UserSpaceStart;
|
|
||||||
PVOID UserSpaceEnd;
|
|
||||||
PVOID PteSpaceStart;
|
|
||||||
PVOID PteSpaceEnd;
|
|
||||||
} MMMEMORY_LAYOUT, *PMMMEMORY_LAYOUT;
|
|
||||||
|
|
||||||
/* Page Frame Entry structure definition */
|
/* Page Frame Entry structure definition */
|
||||||
typedef struct _MMPFNENTRY
|
typedef struct _MMPFNENTRY
|
||||||
{
|
{
|
||||||
@@ -163,13 +45,4 @@ typedef struct _MMPFNENTRY
|
|||||||
USHORT ParityError:1;
|
USHORT ParityError:1;
|
||||||
} MMPFNENTRY, *PMMPFNENTRY;
|
} MMPFNENTRY, *PMMPFNENTRY;
|
||||||
|
|
||||||
/* Page Frame List structure definition */
|
|
||||||
typedef struct _MMPFNLIST
|
|
||||||
{
|
|
||||||
PFN_NUMBER Total;
|
|
||||||
MMPAGELISTS ListName;
|
|
||||||
PFN_NUMBER Flink;
|
|
||||||
PFN_NUMBER Blink;
|
|
||||||
} MMPFNLIST, *PMMPFNLIST;
|
|
||||||
|
|
||||||
#endif /* __XTDK_MMTYPES_H */
|
#endif /* __XTDK_MMTYPES_H */
|
||||||
|
|||||||
@@ -49,10 +49,6 @@
|
|||||||
#define PFL_DIGIT_PRECISION 0x00002000
|
#define PFL_DIGIT_PRECISION 0x00002000
|
||||||
#define PFL_THOUSANDS_GROUPING 0x00004000
|
#define PFL_THOUSANDS_GROUPING 0x00004000
|
||||||
|
|
||||||
/* Cryptographic related definitions */
|
|
||||||
#define SHA1_BLOCK_SIZE 64
|
|
||||||
#define SHA1_DIGEST_SIZE 20
|
|
||||||
|
|
||||||
/* Runtime Library routine callbacks */
|
/* Runtime Library routine callbacks */
|
||||||
typedef XTSTATUS (*PWRITE_CHARACTER)(IN CHAR Character);
|
typedef XTSTATUS (*PWRITE_CHARACTER)(IN CHAR Character);
|
||||||
typedef XTSTATUS (*PWRITE_WIDE_CHARACTER)(IN WCHAR Character);
|
typedef XTSTATUS (*PWRITE_WIDE_CHARACTER)(IN WCHAR Character);
|
||||||
@@ -99,12 +95,4 @@ typedef struct _RTL_PRINT_FORMAT_PROPERTIES
|
|||||||
LONG Flags;
|
LONG Flags;
|
||||||
} RTL_PRINT_FORMAT_PROPERTIES, *PRTL_PRINT_FORMAT_PROPERTIES;
|
} RTL_PRINT_FORMAT_PROPERTIES, *PRTL_PRINT_FORMAT_PROPERTIES;
|
||||||
|
|
||||||
/* Runtime Library SHA-1 context structure definition */
|
|
||||||
typedef struct _RTL_SHA1_CONTEXT
|
|
||||||
{
|
|
||||||
ULONG State[5];
|
|
||||||
ULONG Count[2];
|
|
||||||
UCHAR Buffer[SHA1_BLOCK_SIZE];
|
|
||||||
} RTL_SHA1_CONTEXT, *PRTL_SHA1_CONTEXT;
|
|
||||||
|
|
||||||
#endif /* __XTDK_RTLTYPES_H */
|
#endif /* __XTDK_RTLTYPES_H */
|
||||||
|
|||||||
@@ -29,9 +29,6 @@ typedef UCHAR KRUNLEVEL, *PKRUNLEVEL;
|
|||||||
/* Spin locks synchronization mechanism */
|
/* Spin locks synchronization mechanism */
|
||||||
typedef ULONG_PTR KSPIN_LOCK, *PKSPIN_LOCK;
|
typedef ULONG_PTR KSPIN_LOCK, *PKSPIN_LOCK;
|
||||||
|
|
||||||
/* Page Frame Number count */
|
|
||||||
typedef ULONG PFN_COUNT;
|
|
||||||
|
|
||||||
/* Page Frame Number */
|
/* Page Frame Number */
|
||||||
typedef ULONG_PTR PFN_NUMBER, *PPFN_NUMBER;
|
typedef ULONG_PTR PFN_NUMBER, *PPFN_NUMBER;
|
||||||
|
|
||||||
|
|||||||
@@ -12,9 +12,8 @@
|
|||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
/* C++ definitions */
|
/* C++ definitions */
|
||||||
#define NULLPTR nullptr
|
|
||||||
#define VIRTUAL virtual
|
|
||||||
#define XTCLINK extern "C"
|
#define XTCLINK extern "C"
|
||||||
|
#define NULLPTR nullptr
|
||||||
|
|
||||||
/* C++ boolean type */
|
/* C++ boolean type */
|
||||||
typedef bool BOOLEAN, *PBOOLEAN;
|
typedef bool BOOLEAN, *PBOOLEAN;
|
||||||
@@ -25,9 +24,8 @@
|
|||||||
typedef wchar_t wchar;
|
typedef wchar_t wchar;
|
||||||
#else
|
#else
|
||||||
/* C definitions */
|
/* C definitions */
|
||||||
#define NULLPTR ((void *)0)
|
|
||||||
#define VIRTUAL
|
|
||||||
#define XTCLINK
|
#define XTCLINK
|
||||||
|
#define NULLPTR ((void *)0)
|
||||||
|
|
||||||
/* C boolean type */
|
/* C boolean type */
|
||||||
typedef enum _BOOLEAN
|
typedef enum _BOOLEAN
|
||||||
|
|||||||
@@ -74,20 +74,12 @@
|
|||||||
/* Macro for calculating size of a field in the structure */
|
/* Macro for calculating size of a field in the structure */
|
||||||
#define FIELD_SIZE(Structure, Field) (sizeof(((Structure *)0)->Field))
|
#define FIELD_SIZE(Structure, Field) (sizeof(((Structure *)0)->Field))
|
||||||
|
|
||||||
/* Macros for calculating minimum and maximum of two values */
|
|
||||||
#define MIN(A, B) (((A) < (B)) ? (A) : (B))
|
|
||||||
#define MAX(A, B) (((A) > (B)) ? (A) : (B))
|
|
||||||
|
|
||||||
/* Macro that page-aligns a virtual address */
|
/* Macro that page-aligns a virtual address */
|
||||||
#define PAGE_ALIGN(VirtualAddress) ((PVOID)((ULONG_PTR)VirtualAddress & ~MM_PAGE_MASK))
|
#define PAGE_ALIGN(VirtualAddress) ((PVOID)((ULONG_PTR)VirtualAddress & ~MM_PAGE_MASK))
|
||||||
|
|
||||||
/* Macro that returns offset of the virtual address */
|
/* Macro that returns offset of the virtual address */
|
||||||
#define PAGE_OFFSET(VirtualAddress) ((ULONG)((ULONG_PTR)VirtualAddress & MM_PAGE_MASK))
|
#define PAGE_OFFSET(VirtualAddress) ((ULONG)((ULONG_PTR)VirtualAddress & MM_PAGE_MASK))
|
||||||
|
|
||||||
/* Macros for bitwise rotating */
|
|
||||||
#define ROTATE_LEFT(Value, Count) ((Value << Count) | (Value >> (32 - Count)))
|
|
||||||
#define ROTATE_RIGHT(Value, Count) ((Value >> Count) | (Value << (32 - Count)))
|
|
||||||
|
|
||||||
/* Macro for rounding down */
|
/* Macro for rounding down */
|
||||||
#define ROUND_DOWN(Value, Alignment) ((Value) & ~((Alignment) - 1))
|
#define ROUND_DOWN(Value, Alignment) ((Value) & ~((Alignment) - 1))
|
||||||
|
|
||||||
@@ -112,7 +104,7 @@
|
|||||||
|
|
||||||
/* Variadic ABI functions */
|
/* Variadic ABI functions */
|
||||||
typedef __builtin_va_list VA_LIST, *PVA_LIST;
|
typedef __builtin_va_list VA_LIST, *PVA_LIST;
|
||||||
#define VA_ARG(Marker, Type) ((sizeof(Type) < sizeof(UINT_PTR)) ? \
|
#define VA_ARG(Marker, Type) ((sizeof (Type) < sizeof(UINT_PTR)) ? \
|
||||||
(Type)(__builtin_va_arg(Marker, UINT_PTR)) : \
|
(Type)(__builtin_va_arg(Marker, UINT_PTR)) : \
|
||||||
(Type)(__builtin_va_arg(Marker, Type)))
|
(Type)(__builtin_va_arg(Marker, Type)))
|
||||||
#define VA_COPY(Dest, Start) __builtin_va_copy(Dest, Start)
|
#define VA_COPY(Dest, Start) __builtin_va_copy(Dest, Start)
|
||||||
|
|||||||
@@ -107,7 +107,6 @@ typedef struct _KERNEL_INITIALIZATION_BLOCK
|
|||||||
ULONG BlockVersion;
|
ULONG BlockVersion;
|
||||||
ULONG ProtocolVersion;
|
ULONG ProtocolVersion;
|
||||||
PWCHAR KernelParameters;
|
PWCHAR KernelParameters;
|
||||||
PFN_NUMBER BootImageSize;
|
|
||||||
LIST_ENTRY LoadOrderListHead;
|
LIST_ENTRY LoadOrderListHead;
|
||||||
LIST_ENTRY MemoryDescriptorListHead;
|
LIST_ENTRY MemoryDescriptorListHead;
|
||||||
LIST_ENTRY BootDriverListHead;
|
LIST_ENTRY BootDriverListHead;
|
||||||
|
|||||||
@@ -48,10 +48,6 @@ typedef enum _KTHREAD_STATE KTHREAD_STATE, *PKTHREAD_STATE;
|
|||||||
typedef enum _KTIMER_TYPE KTIMER_TYPE, *PKTIMER_TYPE;
|
typedef enum _KTIMER_TYPE KTIMER_TYPE, *PKTIMER_TYPE;
|
||||||
typedef enum _KUBSAN_DATA_TYPE KUBSAN_DATA_TYPE, *PKUBSAN_DATA_TYPE;
|
typedef enum _KUBSAN_DATA_TYPE KUBSAN_DATA_TYPE, *PKUBSAN_DATA_TYPE;
|
||||||
typedef enum _LOADER_MEMORY_TYPE LOADER_MEMORY_TYPE, *PLOADER_MEMORY_TYPE;
|
typedef enum _LOADER_MEMORY_TYPE LOADER_MEMORY_TYPE, *PLOADER_MEMORY_TYPE;
|
||||||
typedef enum _MMPAGELISTS MMPAGELISTS, *PMMPAGELISTS;
|
|
||||||
typedef enum _MMPFN_CACHE_ATTRIBUTE MMPFN_CACHE_ATTRIBUTE, *PMMPFN_CACHE_ATTRIBUTE;
|
|
||||||
typedef enum _MMPOOL_TYPE MMPOOL_TYPE, *PMMPOOL_TYPE;
|
|
||||||
typedef enum _MMSYSTEM_PTE_POOL_TYPE MMSYSTEM_PTE_POOL_TYPE, *PMMSYSTEM_PTE_POOL_TYPE;
|
|
||||||
typedef enum _MODE MODE, *PMODE;
|
typedef enum _MODE MODE, *PMODE;
|
||||||
typedef enum _RTL_VARIABLE_TYPE RTL_VARIABLE_TYPE, *PRTL_VARIABLE_TYPE;
|
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;
|
||||||
@@ -278,10 +274,7 @@ typedef struct _LOADER_INFORMATION_BLOCK LOADER_INFORMATION_BLOCK, *PLOADER_INFO
|
|||||||
typedef struct _LOADER_MEMORY_DESCRIPTOR LOADER_MEMORY_DESCRIPTOR, *PLOADER_MEMORY_DESCRIPTOR;
|
typedef struct _LOADER_MEMORY_DESCRIPTOR LOADER_MEMORY_DESCRIPTOR, *PLOADER_MEMORY_DESCRIPTOR;
|
||||||
typedef struct _M128 M128, *PM128;
|
typedef struct _M128 M128, *PM128;
|
||||||
typedef struct _MMCOLOR_TABLES MMCOLOR_TABLES, *PMMCOLOR_TABLES;
|
typedef struct _MMCOLOR_TABLES MMCOLOR_TABLES, *PMMCOLOR_TABLES;
|
||||||
typedef struct _MMFREE_POOL_ENTRY MMFREE_POOL_ENTRY, *PMMFREE_POOL_ENTRY;
|
|
||||||
typedef struct _MMMEMORY_LAYOUT MMMEMORY_LAYOUT, *PMMMEMORY_LAYOUT;
|
|
||||||
typedef struct _MMPFNENTRY MMPFNENTRY, *PMMPFNENTRY;
|
typedef struct _MMPFNENTRY MMPFNENTRY, *PMMPFNENTRY;
|
||||||
typedef struct _MMPFNLIST MMPFNLIST, *PMMPFNLIST;
|
|
||||||
typedef struct _PCAT_FIRMWARE_INFORMATION PCAT_FIRMWARE_INFORMATION, *PPCAT_FIRMWARE_INFORMATION;
|
typedef struct _PCAT_FIRMWARE_INFORMATION PCAT_FIRMWARE_INFORMATION, *PPCAT_FIRMWARE_INFORMATION;
|
||||||
typedef struct _PCI_BRIDGE_CONTROL_REGISTER PCI_BRIDGE_CONTROL_REGISTER, *PPCI_BRIDGE_CONTROL_REGISTER;
|
typedef struct _PCI_BRIDGE_CONTROL_REGISTER PCI_BRIDGE_CONTROL_REGISTER, *PPCI_BRIDGE_CONTROL_REGISTER;
|
||||||
typedef struct _PCI_COMMON_CONFIG PCI_COMMON_CONFIG, *PPCI_COMMON_CONFIG;
|
typedef struct _PCI_COMMON_CONFIG PCI_COMMON_CONFIG, *PPCI_COMMON_CONFIG;
|
||||||
|
|||||||
@@ -51,22 +51,14 @@ list(APPEND XTOSKRNL_SOURCE
|
|||||||
${XTOSKRNL_SOURCE_DIR}/ke/spinlock.cc
|
${XTOSKRNL_SOURCE_DIR}/ke/spinlock.cc
|
||||||
${XTOSKRNL_SOURCE_DIR}/ke/sysres.cc
|
${XTOSKRNL_SOURCE_DIR}/ke/sysres.cc
|
||||||
${XTOSKRNL_SOURCE_DIR}/ke/timer.cc
|
${XTOSKRNL_SOURCE_DIR}/ke/timer.cc
|
||||||
${XTOSKRNL_SOURCE_DIR}/mm/${ARCH}/alloc.cc
|
${XTOSKRNL_SOURCE_DIR}/mm/${ARCH}/init.cc
|
||||||
${XTOSKRNL_SOURCE_DIR}/mm/${ARCH}/mmgr.cc
|
|
||||||
${XTOSKRNL_SOURCE_DIR}/mm/${ARCH}/pagemap.cc
|
${XTOSKRNL_SOURCE_DIR}/mm/${ARCH}/pagemap.cc
|
||||||
${XTOSKRNL_SOURCE_DIR}/mm/${ARCH}/paging.cc
|
${XTOSKRNL_SOURCE_DIR}/mm/${ARCH}/paging.cc
|
||||||
${XTOSKRNL_SOURCE_DIR}/mm/${ARCH}/pfault.cc
|
|
||||||
${XTOSKRNL_SOURCE_DIR}/mm/${ARCH}/pfn.cc
|
|
||||||
${XTOSKRNL_SOURCE_DIR}/mm/${ARCH}/pte.cc
|
|
||||||
${XTOSKRNL_SOURCE_DIR}/mm/alloc.cc
|
|
||||||
${XTOSKRNL_SOURCE_DIR}/mm/colors.cc
|
|
||||||
${XTOSKRNL_SOURCE_DIR}/mm/data.cc
|
${XTOSKRNL_SOURCE_DIR}/mm/data.cc
|
||||||
${XTOSKRNL_SOURCE_DIR}/mm/hlpool.cc
|
${XTOSKRNL_SOURCE_DIR}/mm/hlpool.cc
|
||||||
|
${XTOSKRNL_SOURCE_DIR}/mm/init.cc
|
||||||
${XTOSKRNL_SOURCE_DIR}/mm/kpool.cc
|
${XTOSKRNL_SOURCE_DIR}/mm/kpool.cc
|
||||||
${XTOSKRNL_SOURCE_DIR}/mm/mmgr.cc
|
|
||||||
${XTOSKRNL_SOURCE_DIR}/mm/paging.cc
|
${XTOSKRNL_SOURCE_DIR}/mm/paging.cc
|
||||||
${XTOSKRNL_SOURCE_DIR}/mm/pfn.cc
|
|
||||||
${XTOSKRNL_SOURCE_DIR}/mm/pte.cc
|
|
||||||
${XTOSKRNL_SOURCE_DIR}/po/idle.cc
|
${XTOSKRNL_SOURCE_DIR}/po/idle.cc
|
||||||
${XTOSKRNL_SOURCE_DIR}/rtl/${ARCH}/dispatch.cc
|
${XTOSKRNL_SOURCE_DIR}/rtl/${ARCH}/dispatch.cc
|
||||||
${XTOSKRNL_SOURCE_DIR}/rtl/${ARCH}/exsup.cc
|
${XTOSKRNL_SOURCE_DIR}/rtl/${ARCH}/exsup.cc
|
||||||
@@ -79,8 +71,6 @@ list(APPEND XTOSKRNL_SOURCE
|
|||||||
${XTOSKRNL_SOURCE_DIR}/rtl/llist.cc
|
${XTOSKRNL_SOURCE_DIR}/rtl/llist.cc
|
||||||
${XTOSKRNL_SOURCE_DIR}/rtl/math.cc
|
${XTOSKRNL_SOURCE_DIR}/rtl/math.cc
|
||||||
${XTOSKRNL_SOURCE_DIR}/rtl/memory.cc
|
${XTOSKRNL_SOURCE_DIR}/rtl/memory.cc
|
||||||
${XTOSKRNL_SOURCE_DIR}/rtl/sha1.cc
|
|
||||||
${XTOSKRNL_SOURCE_DIR}/rtl/slist.cc
|
|
||||||
${XTOSKRNL_SOURCE_DIR}/rtl/string.cc
|
${XTOSKRNL_SOURCE_DIR}/rtl/string.cc
|
||||||
${XTOSKRNL_SOURCE_DIR}/rtl/widestr.cc)
|
${XTOSKRNL_SOURCE_DIR}/rtl/widestr.cc)
|
||||||
|
|
||||||
@@ -92,12 +82,11 @@ add_library(libxtos ${XTOSKRNL_SOURCE})
|
|||||||
|
|
||||||
# Link kernel executable
|
# Link kernel executable
|
||||||
add_executable(xtoskrnl
|
add_executable(xtoskrnl
|
||||||
|
${XTOSKRNL_SOURCE}
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/xtoskrnl.def)
|
${CMAKE_CURRENT_BINARY_DIR}/xtoskrnl.def)
|
||||||
|
|
||||||
# Add linker libraries
|
# Add linker libraries
|
||||||
target_link_libraries(xtoskrnl
|
target_link_libraries(xtoskrnl)
|
||||||
PRIVATE
|
|
||||||
libxtos)
|
|
||||||
|
|
||||||
# Set proper binary name and install target
|
# Set proper binary name and install target
|
||||||
set_target_properties(xtoskrnl PROPERTIES SUFFIX .exe)
|
set_target_properties(xtoskrnl PROPERTIES SUFFIX .exe)
|
||||||
|
|||||||
@@ -4,18 +4,6 @@ within the XTOS kernel space. It is responsible for various core services, such
|
|||||||
management, and process scheduling. The kernel contains the scheduler (sometimes referred to as the Dispatcher), the
|
management, and process scheduling. The kernel contains the scheduler (sometimes referred to as the Dispatcher), the
|
||||||
cache, object, and memory managers, the security manager, and other executive components described below.
|
cache, object, and memory managers, the security manager, and other executive components described below.
|
||||||
|
|
||||||
|
|
||||||
## Kernel Parameters
|
|
||||||
Kernel parameters are XTOS boot-time options used to ensure proper initialization and handling of hardware peripherals.
|
|
||||||
These parameters can be configured either temporarily by editing the boot entry in the bootloader’s selection menu, or
|
|
||||||
permanently by modifying the XTLDR configuration file.
|
|
||||||
|
|
||||||
The following is a consolidated list of available kernel parameters:
|
|
||||||
* **NOXPA**: Disables PAE or LA57 support, depending on the CPU architecture. This parameter is handled by the
|
|
||||||
bootloader, which configures paging and selects the appropriate Page Map Level (PML) before transferring control to
|
|
||||||
the kernel.
|
|
||||||
|
|
||||||
## Source Code
|
|
||||||
The source code of the kernel is organized into subsystem-specific directories. Each directory name also defines the
|
The source code of the kernel is organized into subsystem-specific directories. Each directory name also defines the
|
||||||
corresponding C++ namespace in which the subsystem's classes and routines reside. These subsystems include:
|
corresponding C++ namespace in which the subsystem's classes and routines reside. These subsystems include:
|
||||||
|
|
||||||
|
|||||||
@@ -249,34 +249,34 @@ AR::ProcSup::InitializeIdt(IN PKPROCESSOR_BLOCK ProcessorBlock)
|
|||||||
for(Vector = 0; Vector < IDT_ENTRIES; Vector++)
|
for(Vector = 0; Vector < IDT_ENTRIES; Vector++)
|
||||||
{
|
{
|
||||||
/* Set the IDT to handle unexpected interrupts */
|
/* Set the IDT to handle unexpected interrupts */
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, Vector, (PVOID)ArTrap0xFF, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_INTERRUPT_GATE);
|
SetIdtGate(ProcessorBlock->IdtBase, Vector, (PVOID)ArTrap0xFF, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Setup IDT handlers for known interrupts and traps */
|
/* Setup IDT handlers for known interrupts and traps */
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x00, (PVOID)ArTrap0x00, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x00, (PVOID)ArTrap0x00, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x01, (PVOID)ArTrap0x01, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x01, (PVOID)ArTrap0x01, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x02, (PVOID)ArTrap0x02, KGDT_R0_CODE, KIDT_IST_PANIC, KIDT_ACCESS_RING0, AMD64_INTERRUPT_GATE);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x02, (PVOID)ArTrap0x02, KGDT_R0_CODE, KIDT_IST_PANIC, KIDT_ACCESS_RING0);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x03, (PVOID)ArTrap0x03, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3, AMD64_TRAP_GATE);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x03, (PVOID)ArTrap0x03, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x04, (PVOID)ArTrap0x04, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3, AMD64_TRAP_GATE);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x04, (PVOID)ArTrap0x04, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x05, (PVOID)ArTrap0x05, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x05, (PVOID)ArTrap0x05, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x06, (PVOID)ArTrap0x06, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x06, (PVOID)ArTrap0x06, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x07, (PVOID)ArTrap0x07, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x07, (PVOID)ArTrap0x07, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x08, (PVOID)ArTrap0x08, KGDT_R0_CODE, KIDT_IST_PANIC, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x08, (PVOID)ArTrap0x08, KGDT_R0_CODE, KIDT_IST_PANIC, KIDT_ACCESS_RING0);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x09, (PVOID)ArTrap0x09, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x09, (PVOID)ArTrap0x09, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x0A, (PVOID)ArTrap0x0A, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x0A, (PVOID)ArTrap0x0A, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x0B, (PVOID)ArTrap0x0B, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x0B, (PVOID)ArTrap0x0B, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x0C, (PVOID)ArTrap0x0C, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x0C, (PVOID)ArTrap0x0C, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x0D, (PVOID)ArTrap0x0D, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x0D, (PVOID)ArTrap0x0D, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x0E, (PVOID)ArTrap0x0E, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x0E, (PVOID)ArTrap0x0E, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x10, (PVOID)ArTrap0x10, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x10, (PVOID)ArTrap0x10, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x11, (PVOID)ArTrap0x11, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x11, (PVOID)ArTrap0x11, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x12, (PVOID)ArTrap0x12, KGDT_R0_CODE, KIDT_IST_MCA, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x12, (PVOID)ArTrap0x12, KGDT_R0_CODE, KIDT_IST_MCA, KIDT_ACCESS_RING0);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x13, (PVOID)ArTrap0x13, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x13, (PVOID)ArTrap0x13, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x1F, (PVOID)ArTrap0x1F, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_INTERRUPT_GATE);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x1F, (PVOID)ArTrap0x1F, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x2C, (PVOID)ArTrap0x2C, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3, AMD64_TRAP_GATE);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x2C, (PVOID)ArTrap0x2C, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x2D, (PVOID)ArTrap0x2D, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3, AMD64_TRAP_GATE);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x2D, (PVOID)ArTrap0x2D, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x2F, (PVOID)ArTrap0x2F, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_INTERRUPT_GATE);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x2F, (PVOID)ArTrap0x2F, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0xE1, (PVOID)ArTrap0xE1, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_INTERRUPT_GATE);
|
SetIdtGate(ProcessorBlock->IdtBase, 0xE1, (PVOID)ArTrap0xE1, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -636,9 +636,6 @@ AR::ProcSup::SetGdtEntryBase(IN PKGDTENTRY Gdt,
|
|||||||
* @param Access
|
* @param Access
|
||||||
* Supplies the gate access rights.
|
* Supplies the gate access rights.
|
||||||
*
|
*
|
||||||
* @param Type
|
|
||||||
* Supplies the gate type.
|
|
||||||
*
|
|
||||||
* @return This routine does not return any value.
|
* @return This routine does not return any value.
|
||||||
*
|
*
|
||||||
* @since XT 1.0
|
* @since XT 1.0
|
||||||
@@ -650,22 +647,15 @@ AR::ProcSup::SetIdtGate(IN PKIDTENTRY Idt,
|
|||||||
IN PVOID Handler,
|
IN PVOID Handler,
|
||||||
IN USHORT Selector,
|
IN USHORT Selector,
|
||||||
IN USHORT Ist,
|
IN USHORT Ist,
|
||||||
IN USHORT Dpl,
|
IN USHORT Access)
|
||||||
IN USHORT Type)
|
|
||||||
{
|
{
|
||||||
/* Set the handler's address */
|
/* Setup the gate */
|
||||||
Idt[Vector].OffsetLow = ((ULONG_PTR)Handler & 0xFFFF);
|
Idt[Vector].OffsetLow = ((ULONG_PTR)Handler & 0xFFFF);
|
||||||
Idt[Vector].OffsetMiddle = (((ULONG_PTR)Handler >> 16) & 0xFFFF);
|
Idt[Vector].OffsetMiddle = (((ULONG_PTR)Handler >> 16) & 0xFFFF);
|
||||||
Idt[Vector].OffsetHigh = (ULONG_PTR)Handler >> 32;
|
Idt[Vector].OffsetHigh = (ULONG_PTR)Handler >> 32;
|
||||||
|
Idt[Vector].Dpl = Access;
|
||||||
/* Set the code segment selector */
|
|
||||||
Idt[Vector].Selector = Selector;
|
|
||||||
|
|
||||||
/* Initialize the gate's attributes and flags */
|
|
||||||
Idt[Vector].Access = 0;
|
|
||||||
Idt[Vector].Dpl = Dpl;
|
|
||||||
Idt[Vector].IstIndex = Ist;
|
Idt[Vector].IstIndex = Ist;
|
||||||
Idt[Vector].Present = 1;
|
Idt[Vector].Present = 1;
|
||||||
Idt[Vector].Reserved1 = 0;
|
Idt[Vector].Selector = Selector;
|
||||||
Idt[Vector].Type = Type;
|
Idt[Vector].Type = 0xE;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -242,34 +242,34 @@ AR::ProcSup::InitializeIdt(IN PKPROCESSOR_BLOCK ProcessorBlock)
|
|||||||
for(Vector = 0; Vector < IDT_ENTRIES; Vector++)
|
for(Vector = 0; Vector < IDT_ENTRIES; Vector++)
|
||||||
{
|
{
|
||||||
/* Set the IDT to handle unexpected interrupts */
|
/* Set the IDT to handle unexpected interrupts */
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, Vector, (PVOID)ArTrap0xFF, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_INTERRUPT_GATE);
|
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 */
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x00, (PVOID)ArTrap0x00, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x00, (PVOID)ArTrap0x00, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x01, (PVOID)ArTrap0x01, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x01, (PVOID)ArTrap0x01, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x02, (PVOID)ArTrap0x02, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_INTERRUPT_GATE);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x02, (PVOID)ArTrap0x02, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x03, (PVOID)ArTrap0x03, KGDT_R0_CODE, 0, KIDT_ACCESS_RING3, I686_TRAP_GATE);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x03, (PVOID)ArTrap0x03, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING3);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x04, (PVOID)ArTrap0x04, KGDT_R0_CODE, 0, KIDT_ACCESS_RING3, I686_TRAP_GATE);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x04, (PVOID)ArTrap0x04, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING3);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x05, (PVOID)ArTrap0x05, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x05, (PVOID)ArTrap0x05, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x06, (PVOID)ArTrap0x06, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x06, (PVOID)ArTrap0x06, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x07, (PVOID)ArTrap0x07, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x07, (PVOID)ArTrap0x07, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x08, (PVOID)ArTrap0x08, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x08, (PVOID)ArTrap0x08, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x09, (PVOID)ArTrap0x09, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x09, (PVOID)ArTrap0x09, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x0A, (PVOID)ArTrap0x0A, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x0A, (PVOID)ArTrap0x0A, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x0B, (PVOID)ArTrap0x0B, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x0B, (PVOID)ArTrap0x0B, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x0C, (PVOID)ArTrap0x0C, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x0C, (PVOID)ArTrap0x0C, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x0D, (PVOID)ArTrap0x0D, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x0D, (PVOID)ArTrap0x0D, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x0E, (PVOID)ArTrap0x0E, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x0E, (PVOID)ArTrap0x0E, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x10, (PVOID)ArTrap0x10, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x10, (PVOID)ArTrap0x10, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x11, (PVOID)ArTrap0x11, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x11, (PVOID)ArTrap0x11, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x12, (PVOID)ArTrap0x12, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x12, (PVOID)ArTrap0x12, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x13, (PVOID)ArTrap0x13, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x13, (PVOID)ArTrap0x13, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x2A, (PVOID)ArTrap0x2A, KGDT_R0_CODE, 0, KIDT_ACCESS_RING3, I686_TRAP_GATE);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x2A, (PVOID)ArTrap0x2A, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING3);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x2B, (PVOID)ArTrap0x2B, KGDT_R0_CODE, 0, KIDT_ACCESS_RING3, I686_TRAP_GATE);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x2B, (PVOID)ArTrap0x2B, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING3);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x2C, (PVOID)ArTrap0x2C, KGDT_R0_CODE, 0, KIDT_ACCESS_RING3, I686_TRAP_GATE);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x2C, (PVOID)ArTrap0x2C, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING3);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x2D, (PVOID)ArTrap0x2D, KGDT_R0_CODE, 0, KIDT_ACCESS_RING3, I686_TRAP_GATE);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x2D, (PVOID)ArTrap0x2D, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING3);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x2E, (PVOID)ArTrap0x2E, KGDT_R0_CODE, 0, KIDT_ACCESS_RING3, I686_TRAP_GATE);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x2E, (PVOID)ArTrap0x2E, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING3);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -656,9 +656,6 @@ AR::ProcSup::SetGdtEntryBase(IN PKGDTENTRY Gdt,
|
|||||||
* @param Access
|
* @param Access
|
||||||
* Supplies the gate access rights.
|
* Supplies the gate access rights.
|
||||||
*
|
*
|
||||||
* @param Type
|
|
||||||
* Supplies the gate type.
|
|
||||||
*
|
|
||||||
* @return This routine does not return any value.
|
* @return This routine does not return any value.
|
||||||
*
|
*
|
||||||
* @since XT 1.0
|
* @since XT 1.0
|
||||||
@@ -670,21 +667,13 @@ AR::ProcSup::SetIdtGate(IN PKIDTENTRY Idt,
|
|||||||
IN PVOID Handler,
|
IN PVOID Handler,
|
||||||
IN USHORT Selector,
|
IN USHORT Selector,
|
||||||
IN USHORT Ist,
|
IN USHORT Ist,
|
||||||
IN USHORT Dpl,
|
IN USHORT Access)
|
||||||
IN USHORT Type)
|
|
||||||
{
|
{
|
||||||
/* Set the handler's address */
|
/* Setup the gate */
|
||||||
Idt[Vector].Offset = (USHORT)((ULONG)Handler & 0xFFFF);
|
Idt[Vector].Offset = (USHORT)((ULONG)Handler & 0xFFFF);
|
||||||
Idt[Vector].ExtendedOffset = (USHORT)((ULONG)Handler >> 16);
|
Idt[Vector].ExtendedOffset = (USHORT)((ULONG)Handler >> 16);
|
||||||
|
Idt[Vector].Access = 0x8000 | (Access << 8);
|
||||||
/* Set the code segment selector */
|
|
||||||
Idt[Vector].Selector = Selector;
|
Idt[Vector].Selector = Selector;
|
||||||
|
|
||||||
/* Initialize the gate's attributes and flags */
|
|
||||||
Idt[Vector].Access = 0;
|
|
||||||
Idt[Vector].Dpl = Dpl;
|
|
||||||
Idt[Vector].Present = 1;
|
|
||||||
Idt[Vector].Type = Type;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -67,8 +67,7 @@ namespace AR
|
|||||||
IN PVOID Handler,
|
IN PVOID Handler,
|
||||||
IN USHORT Selector,
|
IN USHORT Selector,
|
||||||
IN USHORT Ist,
|
IN USHORT Ist,
|
||||||
IN USHORT Dpl,
|
IN USHORT Access);
|
||||||
IN USHORT Type);
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -72,8 +72,7 @@ namespace AR
|
|||||||
IN PVOID Handler,
|
IN PVOID Handler,
|
||||||
IN USHORT Selector,
|
IN USHORT Selector,
|
||||||
IN USHORT Ist,
|
IN USHORT Ist,
|
||||||
IN USHORT Dpl,
|
IN USHORT Access);
|
||||||
IN USHORT Type);
|
|
||||||
STATIC XTAPI VOID SetNonMaskableInterruptTssEntry(IN PKPROCESSOR_BLOCK ProcessorBlock,
|
STATIC XTAPI VOID SetNonMaskableInterruptTssEntry(IN PKPROCESSOR_BLOCK ProcessorBlock,
|
||||||
IN PVOID KernelFaultStack);
|
IN PVOID KernelFaultStack);
|
||||||
|
|
||||||
|
|||||||
@@ -22,48 +22,6 @@ namespace KE
|
|||||||
STATIC XTFASTCALL VOID LowerRunLevel(IN KRUNLEVEL RunLevel);
|
STATIC XTFASTCALL VOID LowerRunLevel(IN KRUNLEVEL RunLevel);
|
||||||
STATIC XTFASTCALL KRUNLEVEL RaiseRunLevel(IN KRUNLEVEL RunLevel);
|
STATIC XTFASTCALL KRUNLEVEL RaiseRunLevel(IN KRUNLEVEL RunLevel);
|
||||||
};
|
};
|
||||||
|
|
||||||
class LowerRunLevel
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
KRUNLEVEL PreviousRunLevel;
|
|
||||||
|
|
||||||
public:
|
|
||||||
LowerRunLevel(KRUNLEVEL RunLevel)
|
|
||||||
{
|
|
||||||
PreviousRunLevel = KE::RunLevel::GetCurrentRunLevel();
|
|
||||||
KE::RunLevel::LowerRunLevel(RunLevel);
|
|
||||||
}
|
|
||||||
|
|
||||||
~LowerRunLevel()
|
|
||||||
{
|
|
||||||
KE::RunLevel::RaiseRunLevel(PreviousRunLevel);
|
|
||||||
}
|
|
||||||
|
|
||||||
LowerRunLevel(const LowerRunLevel&) = delete;
|
|
||||||
LowerRunLevel& operator=(const LowerRunLevel&) = delete;
|
|
||||||
};
|
|
||||||
|
|
||||||
class RaiseRunLevel
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
KRUNLEVEL PreviousRunLevel;
|
|
||||||
|
|
||||||
public:
|
|
||||||
RaiseRunLevel(KRUNLEVEL RunLevel)
|
|
||||||
{
|
|
||||||
PreviousRunLevel = KE::RunLevel::GetCurrentRunLevel();
|
|
||||||
KE::RunLevel::RaiseRunLevel(RunLevel);
|
|
||||||
}
|
|
||||||
|
|
||||||
~RaiseRunLevel()
|
|
||||||
{
|
|
||||||
KE::RunLevel::LowerRunLevel(PreviousRunLevel);
|
|
||||||
}
|
|
||||||
|
|
||||||
RaiseRunLevel(const RaiseRunLevel&) = delete;
|
|
||||||
RaiseRunLevel& operator=(const RaiseRunLevel&) = delete;
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* __XTOSKRNL_KE_RUNLEVEL_HH */
|
#endif /* __XTOSKRNL_KE_RUNLEVEL_HH */
|
||||||
|
|||||||
@@ -17,73 +17,12 @@ namespace KE
|
|||||||
{
|
{
|
||||||
class SpinLock
|
class SpinLock
|
||||||
{
|
{
|
||||||
private:
|
|
||||||
STATIC KSPIN_LOCK DispatcherLockQueue;
|
|
||||||
STATIC KSPIN_LOCK ExpansionLockQueue;
|
|
||||||
STATIC KSPIN_LOCK FileSystemLockQueue;
|
|
||||||
STATIC KSPIN_LOCK IoCancelLockQueue;
|
|
||||||
STATIC KSPIN_LOCK IoCompletionLockQueue;
|
|
||||||
STATIC KSPIN_LOCK IoDatabaseLockQueue;
|
|
||||||
STATIC KSPIN_LOCK IoVpbLockQueue;
|
|
||||||
STATIC KSPIN_LOCK MasterLockQueue;
|
|
||||||
STATIC KSPIN_LOCK NonPagedAllocLockQueue;
|
|
||||||
STATIC KSPIN_LOCK NonPagedPoolLockQueue;
|
|
||||||
STATIC KSPIN_LOCK PfnLockQueue;
|
|
||||||
STATIC KSPIN_LOCK SystemSpaceLockQueue;
|
|
||||||
STATIC KSPIN_LOCK TimerTableLockQueue;
|
|
||||||
STATIC KSPIN_LOCK VacbLockQueue;
|
|
||||||
STATIC KSPIN_LOCK WorkLockQueue;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
STATIC XTFASTCALL VOID AcquireQueuedSpinLock(IN KSPIN_LOCK_QUEUE_LEVEL LockLevel);
|
STATIC XTFASTCALL VOID AcquireQueuedSpinLock(IN KSPIN_LOCK_QUEUE_LEVEL LockLevel);
|
||||||
STATIC XTFASTCALL VOID AcquireSpinLock(IN OUT PKSPIN_LOCK SpinLock);
|
STATIC XTFASTCALL VOID AcquireSpinLock(IN OUT PKSPIN_LOCK SpinLock);
|
||||||
STATIC XTAPI VOID InitializeAllLocks();
|
|
||||||
STATIC XTAPI VOID InitializeLockQueues();
|
|
||||||
STATIC XTAPI VOID InitializeSpinLock(IN PKSPIN_LOCK SpinLock);
|
STATIC XTAPI VOID InitializeSpinLock(IN PKSPIN_LOCK SpinLock);
|
||||||
STATIC XTFASTCALL VOID ReleaseQueuedSpinLock(IN KSPIN_LOCK_QUEUE_LEVEL LockLevel);
|
STATIC XTFASTCALL VOID ReleaseQueuedSpinLock(IN KSPIN_LOCK_QUEUE_LEVEL LockLevel);
|
||||||
STATIC XTFASTCALL VOID ReleaseSpinLock(IN OUT PKSPIN_LOCK SpinLock);
|
STATIC XTFASTCALL VOID ReleaseSpinLock(IN OUT PKSPIN_LOCK SpinLock);
|
||||||
STATIC XTFASTCALL BOOLEAN TestSpinLock(IN PKSPIN_LOCK SpinLock);
|
|
||||||
};
|
|
||||||
|
|
||||||
class QueuedSpinLockGuard
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
KSPIN_LOCK_QUEUE_LEVEL QueuedLockLevel;
|
|
||||||
|
|
||||||
public:
|
|
||||||
QueuedSpinLockGuard(IN OUT KSPIN_LOCK_QUEUE_LEVEL LockLevel)
|
|
||||||
{
|
|
||||||
QueuedLockLevel = LockLevel;
|
|
||||||
KE::SpinLock::AcquireQueuedSpinLock(QueuedLockLevel);
|
|
||||||
}
|
|
||||||
|
|
||||||
~QueuedSpinLockGuard()
|
|
||||||
{
|
|
||||||
KE::SpinLock::ReleaseQueuedSpinLock(QueuedLockLevel);
|
|
||||||
}
|
|
||||||
|
|
||||||
QueuedSpinLockGuard(const QueuedSpinLockGuard&) = delete;
|
|
||||||
QueuedSpinLockGuard& operator=(const QueuedSpinLockGuard&) = delete;
|
|
||||||
};
|
|
||||||
|
|
||||||
class SpinLockGuard
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
PKSPIN_LOCK SpinLock;
|
|
||||||
|
|
||||||
public:
|
|
||||||
SpinLockGuard(IN OUT PKSPIN_LOCK SpinLock)
|
|
||||||
{
|
|
||||||
KE::SpinLock::AcquireSpinLock(SpinLock);
|
|
||||||
}
|
|
||||||
|
|
||||||
~SpinLockGuard()
|
|
||||||
{
|
|
||||||
KE::SpinLock::ReleaseSpinLock(SpinLock);
|
|
||||||
}
|
|
||||||
|
|
||||||
SpinLockGuard(const SpinLockGuard&) = delete;
|
|
||||||
SpinLockGuard& operator=(const SpinLockGuard&) = delete;
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,15 +12,10 @@
|
|||||||
#include <xtos.hh>
|
#include <xtos.hh>
|
||||||
|
|
||||||
#include XTOS_ARCH_HEADER(mm, pagemap.hh)
|
#include XTOS_ARCH_HEADER(mm, pagemap.hh)
|
||||||
#include XTOS_ARCH_HEADER(mm, paging.hh)
|
|
||||||
#include XTOS_ARCH_HEADER(mm, pte.hh)
|
|
||||||
|
|
||||||
#include <mm/alloc.hh>
|
|
||||||
#include <mm/colors.hh>
|
|
||||||
#include <mm/hlpool.hh>
|
#include <mm/hlpool.hh>
|
||||||
|
#include <mm/init.hh>
|
||||||
#include <mm/kpool.hh>
|
#include <mm/kpool.hh>
|
||||||
#include <mm/mmgr.hh>
|
#include <mm/paging.hh>
|
||||||
#include <mm/pfault.hh>
|
|
||||||
#include <mm/pfn.hh>
|
|
||||||
|
|
||||||
#endif /* __XTOSKRNL_MM_HH */
|
#endif /* __XTOSKRNL_MM_HH */
|
||||||
|
|||||||
@@ -1,39 +0,0 @@
|
|||||||
/**
|
|
||||||
* PROJECT: ExectOS
|
|
||||||
* COPYRIGHT: See COPYING.md in the top level directory
|
|
||||||
* FILE: xtoskrnl/includes/mm/alloc.hh
|
|
||||||
* DESCRIPTION: Memory manager pool allocation
|
|
||||||
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __XTOSKRNL_MM_ALLOC_HH
|
|
||||||
#define __XTOSKRNL_MM_ALLOC_HH
|
|
||||||
|
|
||||||
#include <xtos.hh>
|
|
||||||
|
|
||||||
|
|
||||||
/* Memory Manager */
|
|
||||||
namespace MM
|
|
||||||
{
|
|
||||||
class Allocator
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
STATIC LIST_ENTRY NonPagedPoolFreeList[MM_MAX_FREE_PAGE_LIST_HEADS];
|
|
||||||
|
|
||||||
public:
|
|
||||||
STATIC XTAPI XTSTATUS AllocatePages(IN MMPOOL_TYPE PoolType,
|
|
||||||
IN SIZE_T Bytes,
|
|
||||||
OUT PVOID *Memory);
|
|
||||||
STATIC XTAPI VOID InitializeNonPagedPool(VOID);
|
|
||||||
STATIC XTAPI VOID InitializePagedPool(VOID);
|
|
||||||
|
|
||||||
private:
|
|
||||||
STATIC XTAPI XTSTATUS AllocateNonPagedPoolPages(IN PFN_COUNT Pages,
|
|
||||||
OUT PVOID *Memory);
|
|
||||||
STATIC XTAPI XTSTATUS AllocatePagedPoolPages(IN PFN_COUNT Pages,
|
|
||||||
OUT PVOID *Memory);
|
|
||||||
STATIC XTAPI VOID MapNonPagedPool(VOID);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* __XTOSKRNL_MM_ALLOC_HH */
|
|
||||||
@@ -1,13 +1,13 @@
|
|||||||
/**
|
/**
|
||||||
* PROJECT: ExectOS
|
* PROJECT: ExectOS
|
||||||
* COPYRIGHT: See COPYING.md in the top level directory
|
* COPYRIGHT: See COPYING.md in the top level directory
|
||||||
* FILE: xtoskrnl/includes/mm/amd64/pagemap.hh
|
* FILE: xtoskrnl/includes/mm/pagemap.hh
|
||||||
* DESCRIPTION: Low-level support for page map manipulation
|
* DESCRIPTION: Low-level support for page map manipulation
|
||||||
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
|
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __XTOSKRNL_MM_AMD64_PAGEMAP_HH
|
#ifndef __XTOSKRNL_MM_PAGEMAP_HH
|
||||||
#define __XTOSKRNL_MM_AMD64_PAGEMAP_HH
|
#define __XTOSKRNL_MM_PAGEMAP_HH
|
||||||
|
|
||||||
#include <xtos.hh>
|
#include <xtos.hh>
|
||||||
|
|
||||||
@@ -21,76 +21,33 @@ namespace MM
|
|||||||
MMPAGEMAP_INFO PageMapInfo;
|
MMPAGEMAP_INFO PageMapInfo;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
XTAPI PMMPTE AdvancePte(IN PMMPTE Pte,
|
XTAPI VOID ClearPte(PHARDWARE_PTE PtePointer);
|
||||||
IN LONG Count);
|
XTAPI PMMP5E GetP5eAddress(PVOID Address);
|
||||||
XTAPI VOID ClearPte(IN PMMPTE PtePointer);
|
XTAPI PMMPDE GetPdeAddress(PVOID Address);
|
||||||
XTAPI ULONG_PTR GetNextEntry(IN PMMPTE Pte);
|
XTAPI PMMPPE GetPpeAddress(PVOID Address);
|
||||||
XTAPI PMMPTE GetNextPte(IN PMMPTE Pte);
|
XTAPI PMMPTE GetPteAddress(PVOID Address);
|
||||||
XTAPI BOOLEAN GetOneEntry(IN PMMPTE Pte);
|
XTAPI PMMPXE GetPxeAddress(PVOID Address);
|
||||||
XTAPI PMMP5E GetP5eAddress(IN PVOID Address);
|
virtual XTAPI VOID InitializePageMapInfo(VOID) = 0;
|
||||||
XTAPI ULONG GetP5eOffset(IN PVOID Address);
|
XTAPI BOOLEAN PteValid(PHARDWARE_PTE PtePointer);
|
||||||
XTAPI PVOID GetP5eVirtualAddress(IN PMMP5E P5ePointer);
|
XTAPI VOID SetPte(PHARDWARE_PTE PtePointer,
|
||||||
XTAPI USHORT GetPageMapLevel();
|
PFN_NUMBER PageFrameNumber,
|
||||||
XTAPI PFN_NUMBER GetPageFrameNumber(IN PMMPTE Pte);
|
BOOLEAN Writable);
|
||||||
XTAPI PMMPDE GetPdeAddress(IN PVOID Address);
|
XTAPI VOID SetPteCaching(PHARDWARE_PTE PtePointer,
|
||||||
XTAPI ULONG GetPdeOffset(IN PVOID Address);
|
BOOLEAN CacheDisable,
|
||||||
VIRTUAL XTAPI PVOID GetPdeVirtualAddress(IN PMMPDE PdePointer) = 0;
|
BOOLEAN WriteThrough);
|
||||||
XTAPI PMMPPE GetPpeAddress(IN PVOID Address);
|
|
||||||
XTAPI ULONG GetPpeOffset(IN PVOID Address);
|
|
||||||
VIRTUAL XTAPI PVOID GetPpeVirtualAddress(IN PMMPPE PpePointer) = 0;
|
|
||||||
XTAPI ULONG_PTR GetPte(IN PMMPTE PtePointer);
|
|
||||||
XTAPI PMMPTE GetPteAddress(IN PVOID Address);
|
|
||||||
XTAPI LONG GetPteDistance(PMMPTE EndPte,
|
|
||||||
PMMPTE StartPte);
|
|
||||||
XTAPI ULONG GetPteOffset(IN PVOID Address);
|
|
||||||
XTAPI ULONG GetPteSize(VOID);
|
|
||||||
XTAPI ULONG GetPteSoftwareProtection(IN PMMPTE PtePointer);
|
|
||||||
XTAPI ULONG GetPteSoftwarePrototype(IN PMMPTE PtePointer);
|
|
||||||
XTAPI ULONG GetPteSoftwareTransition(IN PMMPTE PtePointer);
|
|
||||||
VIRTUAL XTAPI PVOID GetPteVirtualAddress(IN PMMPTE PtePointer) = 0;
|
|
||||||
XTAPI PMMPXE GetPxeAddress(IN PVOID Address);
|
|
||||||
XTAPI ULONG GetPxeOffset(IN PVOID Address);
|
|
||||||
VIRTUAL XTAPI PVOID GetPxeVirtualAddress(IN PMMPXE PxePointer) = 0;
|
|
||||||
XTAPI BOOLEAN GetXpaStatus();
|
|
||||||
VIRTUAL XTAPI VOID InitializePageMapInfo(VOID) = 0;
|
|
||||||
XTAPI BOOLEAN PteValid(IN PMMPTE PtePointer);
|
|
||||||
XTAPI VOID SetNextEntry(IN PMMPTE Pte,
|
|
||||||
IN ULONG_PTR Value);
|
|
||||||
XTAPI VOID SetOneEntry(IN PMMPTE Pte,
|
|
||||||
IN BOOLEAN Value);
|
|
||||||
XTAPI VOID SetPte(IN PMMPTE PtePointer,
|
|
||||||
IN PFN_NUMBER PageFrameNumber,
|
|
||||||
IN ULONG_PTR AttributesMask);
|
|
||||||
XTAPI VOID SetPte(IN PMMPTE PtePointer,
|
|
||||||
IN ULONG_PTR Attributes);
|
|
||||||
XTAPI VOID SetPteCaching(IN PMMPTE PtePointer,
|
|
||||||
IN BOOLEAN CacheDisable,
|
|
||||||
IN BOOLEAN WriteThrough);
|
|
||||||
XTAPI VOID TransitionPte(IN PMMPTE PointerPte,
|
|
||||||
IN ULONG_PTR Protection);
|
|
||||||
XTAPI VOID WritePte(IN PMMPTE Pte,
|
|
||||||
IN MMPTE Value);
|
|
||||||
} PAGEMAP, *PPAGEMAP;
|
} PAGEMAP, *PPAGEMAP;
|
||||||
|
|
||||||
class PageMapBasic final : public PageMap
|
class PageMapBasic final : public PageMap
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
XTAPI PVOID GetPdeVirtualAddress(IN PMMPDE PdePointer);
|
|
||||||
XTAPI PVOID GetPpeVirtualAddress(IN PMMPPE PpePointer);
|
|
||||||
XTAPI PVOID GetPteVirtualAddress(IN PMMPTE PtePointer);
|
|
||||||
XTAPI PVOID GetPxeVirtualAddress(IN PMMPXE PxePointer);
|
|
||||||
XTAPI VOID InitializePageMapInfo(VOID);
|
XTAPI VOID InitializePageMapInfo(VOID);
|
||||||
};
|
};
|
||||||
|
|
||||||
class PageMapXpa final : public PageMap
|
class PageMapXpa final : public PageMap
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
XTAPI PVOID GetPdeVirtualAddress(IN PMMPDE PdePointer);
|
|
||||||
XTAPI PVOID GetPpeVirtualAddress(IN PMMPPE PpePointer);
|
|
||||||
XTAPI PVOID GetPteVirtualAddress(IN PMMPTE PtePointer);
|
|
||||||
XTAPI PVOID GetPxeVirtualAddress(IN PMMPXE PxePointer);
|
|
||||||
XTAPI VOID InitializePageMapInfo(VOID);
|
XTAPI VOID InitializePageMapInfo(VOID);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* __XTOSKRNL_MM_AMD64_PAGEMAP_HH */
|
#endif /* __XTOSKRNL_MM_PAGEMAP_HH */
|
||||||
|
|||||||
@@ -1,79 +0,0 @@
|
|||||||
/**
|
|
||||||
* PROJECT: ExectOS
|
|
||||||
* COPYRIGHT: See COPYING.md in the top level directory
|
|
||||||
* FILE: xtoskrnl/includes/mm/amd64/paging.hh
|
|
||||||
* DESCRIPTION: Low level page management support for AMD64
|
|
||||||
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __XTOSKRNL_MM_AMD64_PAGING_HH
|
|
||||||
#define __XTOSKRNL_MM_AMD64_PAGING_HH
|
|
||||||
|
|
||||||
#include <xtos.hh>
|
|
||||||
|
|
||||||
|
|
||||||
/* Memory Manager */
|
|
||||||
namespace MM
|
|
||||||
{
|
|
||||||
class Paging
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
STATIC PPAGEMAP PmlRoutines;
|
|
||||||
|
|
||||||
public:
|
|
||||||
STATIC XTAPI PMMPTE AdvancePte(IN PMMPTE Pte,
|
|
||||||
IN LONG Count);
|
|
||||||
STATIC XTAPI VOID ClearPte(IN PMMPTE PtePointer);
|
|
||||||
STATIC XTAPI VOID FlushTlb(VOID);
|
|
||||||
STATIC XTAPI ULONG_PTR GetNextEntry(IN PMMPTE Pte);
|
|
||||||
STATIC XTAPI PMMPTE GetNextPte(IN PMMPTE Pte);
|
|
||||||
STATIC XTAPI BOOLEAN GetOneEntry(IN PMMPTE Pte);
|
|
||||||
STATIC XTAPI PMMP5E GetP5eAddress(IN PVOID Address);
|
|
||||||
STATIC XTAPI PVOID GetP5eVirtualAddress(IN PMMP5E P5ePointer);
|
|
||||||
STATIC XTAPI PFN_NUMBER GetPageFrameNumber(IN PMMPTE Pte);
|
|
||||||
STATIC XTAPI USHORT GetPageMapLevel();
|
|
||||||
STATIC XTAPI PMMPDE GetPdeAddress(IN PVOID Address);
|
|
||||||
STATIC XTAPI PVOID GetPdeVirtualAddress(IN PMMPDE PdePointer);
|
|
||||||
STATIC XTAPI PMMPPE GetPpeAddress(IN PVOID Address);
|
|
||||||
STATIC XTAPI PVOID GetPpeVirtualAddress(IN PMMPPE PpePointer);
|
|
||||||
STATIC XTAPI ULONG_PTR GetPte(IN PMMPTE PtePointer);
|
|
||||||
STATIC XTAPI PMMPTE GetPteAddress(IN PVOID Address);
|
|
||||||
STATIC XTAPI LONG GetPteDistance(PMMPTE EndPte,
|
|
||||||
PMMPTE StartPte);
|
|
||||||
STATIC XTAPI ULONG GetPteSize(VOID);
|
|
||||||
STATIC XTAPI ULONG GetPteSoftwareProtection(IN PMMPTE PtePointer);
|
|
||||||
STATIC XTAPI ULONG GetPteSoftwarePrototype(IN PMMPTE PtePointer);
|
|
||||||
STATIC XTAPI ULONG GetPteSoftwareTransition(IN PMMPTE PtePointer);
|
|
||||||
STATIC XTAPI PVOID GetPteVirtualAddress(IN PMMPTE PtePointer);
|
|
||||||
STATIC XTAPI PMMPXE GetPxeAddress(IN PVOID Address);
|
|
||||||
STATIC XTAPI PVOID GetPxeVirtualAddress(IN PMMPXE PxePointer);
|
|
||||||
STATIC XTAPI BOOLEAN GetXpaStatus(VOID);
|
|
||||||
STATIC XTAPI VOID InitializePageMapSupport(VOID);
|
|
||||||
STATIC XTAPI BOOLEAN PteValid(IN PMMPTE PtePointer);
|
|
||||||
STATIC XTAPI VOID SetNextEntry(IN PMMPTE Pte,
|
|
||||||
IN ULONG_PTR Value);
|
|
||||||
STATIC XTAPI VOID SetOneEntry(IN PMMPTE Pte,
|
|
||||||
IN BOOLEAN Value);
|
|
||||||
STATIC XTAPI VOID SetPte(IN PMMPTE PtePointer,
|
|
||||||
IN PFN_NUMBER PageFrameNumber,
|
|
||||||
IN ULONG_PTR AttributesMask);
|
|
||||||
STATIC XTAPI VOID SetPte(IN PMMPTE PtePointer,
|
|
||||||
IN ULONG_PTR Attributes);
|
|
||||||
STATIC XTAPI VOID SetPteCaching(IN PMMPTE PtePointer,
|
|
||||||
IN BOOLEAN CacheDisable,
|
|
||||||
IN BOOLEAN WriteThrough);
|
|
||||||
STATIC XTAPI VOID WritePte(IN PMMPTE Pte,
|
|
||||||
IN MMPTE Value);
|
|
||||||
STATIC XTAPI VOID TransitionPte(IN PMMPTE PointerPte,
|
|
||||||
IN ULONG_PTR Protection);
|
|
||||||
STATIC XTFASTCALL VOID ZeroPages(IN PVOID Address,
|
|
||||||
IN ULONG Size);
|
|
||||||
|
|
||||||
private:
|
|
||||||
STATIC XTAPI BOOLEAN GetExtendedPhysicalAddressingStatus(VOID);
|
|
||||||
STATIC XTAPI PPAGEMAP GetPageMapBasicRoutines(VOID);
|
|
||||||
STATIC XTAPI PPAGEMAP GetPageMapXpaRoutines(VOID);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* __XTOSKRNL_MM_AMD64_PAGING_HH */
|
|
||||||
@@ -1,69 +0,0 @@
|
|||||||
/**
|
|
||||||
* PROJECT: ExectOS
|
|
||||||
* COPYRIGHT: See COPYING.md in the top level directory
|
|
||||||
* FILE: xtoskrnl/includes/mm/amd64/pte.hh
|
|
||||||
* DESCRIPTION: Page Table Entry (PTE) for AMD64 support
|
|
||||||
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __XTOSKRNL_MM_AMD64_PTE_HH
|
|
||||||
#define __XTOSKRNL_MM_AMD64_PTE_HH
|
|
||||||
|
|
||||||
#include <xtos.hh>
|
|
||||||
|
|
||||||
|
|
||||||
/* Memory Manager */
|
|
||||||
namespace MM
|
|
||||||
{
|
|
||||||
class Pte
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
STATIC MMPTE FirstSystemFreePte[MaximumPtePoolTypes];
|
|
||||||
STATIC PMMPTE SystemPteBase;
|
|
||||||
STATIC PMMPTE SystemPtesEnd[MaximumPtePoolTypes];
|
|
||||||
STATIC PMMPTE SystemPtesStart[MaximumPtePoolTypes];
|
|
||||||
STATIC PFN_COUNT TotalSystemFreePtes[MaximumPtePoolTypes];
|
|
||||||
STATIC MMPTE ValidPte;
|
|
||||||
|
|
||||||
public:
|
|
||||||
STATIC XTAPI BOOLEAN AddressValid(IN PVOID VirtualAddress);
|
|
||||||
STATIC XTAPI PFN_COUNT GetPtesPerPage(VOID);
|
|
||||||
STATIC XTAPI PMMPTE GetSystemPteBaseAddress(VOID);
|
|
||||||
STATIC XTAPI PMMPTE GetValidPte(VOID);
|
|
||||||
STATIC XTAPI VOID InitializePageTable(VOID);
|
|
||||||
STATIC XTAPI VOID InitializeSystemPte(VOID);
|
|
||||||
STATIC XTAPI VOID InitializeSystemPteSpace(VOID);
|
|
||||||
STATIC XTAPI VOID MapP5E(IN PVOID StartAddress,
|
|
||||||
IN PVOID EndAddress,
|
|
||||||
IN PMMP5E TemplateP5e);
|
|
||||||
STATIC XTAPI VOID MapPDE(IN PVOID StartAddress,
|
|
||||||
IN PVOID EndAddress,
|
|
||||||
IN PMMPDE TemplatePde);
|
|
||||||
STATIC XTAPI VOID MapPPE(IN PVOID StartAddress,
|
|
||||||
IN PVOID EndAddress,
|
|
||||||
IN PMMPPE TemplatePpe);
|
|
||||||
STATIC XTAPI VOID MapPTE(IN PVOID StartAddress,
|
|
||||||
IN PVOID EndAddress,
|
|
||||||
IN PMMPTE TemplatePte);
|
|
||||||
STATIC XTAPI VOID MapPXE(IN PVOID StartAddress,
|
|
||||||
IN PVOID EndAddress,
|
|
||||||
IN PMMPXE TemplatePxe);
|
|
||||||
STATIC XTAPI VOID ReleaseSystemPtes(IN PMMPTE StartingPte,
|
|
||||||
IN PFN_COUNT NumberOfPtes,
|
|
||||||
IN MMSYSTEM_PTE_POOL_TYPE SystemPtePoolType);
|
|
||||||
STATIC XTAPI PMMPTE ReserveSystemPtes(IN PFN_COUNT NumberOfPtes,
|
|
||||||
IN MMSYSTEM_PTE_POOL_TYPE SystemPtePoolType);
|
|
||||||
|
|
||||||
private:
|
|
||||||
STATIC XTAPI BOOLEAN FindFreeCluster(IN PFN_COUNT NumberOfPtes,
|
|
||||||
IN MMSYSTEM_PTE_POOL_TYPE SystemPtePoolType,
|
|
||||||
OUT PMMPTE *FoundCluster,
|
|
||||||
OUT PMMPTE *PreviousClusterNode);
|
|
||||||
STATIC XTAPI ULONG GetClusterSize(IN PMMPTE Pte);
|
|
||||||
STATIC XTAPI VOID InitializeSystemPtePool(IN PMMPTE StartingPte,
|
|
||||||
IN PFN_COUNT NumberOfPtes,
|
|
||||||
IN MMSYSTEM_PTE_POOL_TYPE PoolType);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* __XTOSKRNL_MM_AMD64_PTE_HH */
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
/**
|
|
||||||
* PROJECT: ExectOS
|
|
||||||
* COPYRIGHT: See COPYING.md in the top level directory
|
|
||||||
* FILE: xtoskrnl/includes/mm/colors.hh
|
|
||||||
* DESCRIPTION: Memory manager page coloring subsystem
|
|
||||||
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __XTOSKRNL_MM_COLORS_HH
|
|
||||||
#define __XTOSKRNL_MM_COLORS_HH
|
|
||||||
|
|
||||||
#include <xtos.hh>
|
|
||||||
|
|
||||||
|
|
||||||
/* Memory Manager */
|
|
||||||
namespace MM
|
|
||||||
{
|
|
||||||
class Colors
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
STATIC PMMCOLOR_TABLES FreePages[FreePageList + 1];
|
|
||||||
STATIC MMPFNLIST ModifiedPages[MM_PAGING_COLORS];
|
|
||||||
STATIC ULONG PagingColors;
|
|
||||||
STATIC ULONG PagingColorsMask;
|
|
||||||
|
|
||||||
public:
|
|
||||||
STATIC XTAPI VOID ComputePageColoring(VOID);
|
|
||||||
STATIC XTAPI PMMCOLOR_TABLES GetFreePages(IN MMPAGELISTS PageList,
|
|
||||||
IN ULONG Color);
|
|
||||||
STATIC XTAPI PMMPFNLIST GetModifiedPages(IN ULONG Color);
|
|
||||||
STATIC XTAPI ULONG GetNextColor(VOID);
|
|
||||||
STATIC XTAPI ULONG GetPagingColors(VOID);
|
|
||||||
STATIC XTAPI ULONG GetPagingColorsMask(VOID);
|
|
||||||
STATIC XTAPI VOID InitializeColorTables(VOID);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* __XTOSKRNL_MM_COLORS_HH */
|
|
||||||
@@ -1,13 +1,13 @@
|
|||||||
/**
|
/**
|
||||||
* PROJECT: ExectOS
|
* PROJECT: ExectOS
|
||||||
* COPYRIGHT: See COPYING.md in the top level directory
|
* COPYRIGHT: See COPYING.md in the top level directory
|
||||||
* FILE: xtoskrnl/includes/mm/i686/pagemap.hh
|
* FILE: xtoskrnl/includes/mm/pagemap.hh
|
||||||
* DESCRIPTION: Low-level support for page map manipulation
|
* DESCRIPTION: Low-level support for page map manipulation
|
||||||
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
|
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __XTOSKRNL_MM_I686_PAGEMAP_HH
|
#ifndef __XTOSKRNL_MM_PAGEMAP_HH
|
||||||
#define __XTOSKRNL_MM_I686_PAGEMAP_HH
|
#define __XTOSKRNL_MM_PAGEMAP_HH
|
||||||
|
|
||||||
#include <xtos.hh>
|
#include <xtos.hh>
|
||||||
|
|
||||||
@@ -21,129 +21,45 @@ namespace MM
|
|||||||
MMPAGEMAP_INFO PageMapInfo;
|
MMPAGEMAP_INFO PageMapInfo;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
VIRTUAL XTAPI PMMPTE AdvancePte(IN PMMPTE Pte,
|
XTAPI VOID ClearPte(PHARDWARE_PTE PtePointer);
|
||||||
IN ULONG Count) = 0;
|
XTAPI PMMPDE GetPdeAddress(PVOID Address);
|
||||||
VIRTUAL XTAPI VOID ClearPte(IN PMMPTE PtePointer) = 0;
|
XTAPI PMMPPE GetPpeAddress(PVOID Address);
|
||||||
VIRTUAL XTAPI ULONG_PTR GetNextEntry(IN PMMPTE Pte) = 0;
|
XTAPI PMMPTE GetPteAddress(PVOID Address);
|
||||||
VIRTUAL XTAPI PMMPTE GetNextPte(IN PMMPTE Pte) = 0;
|
virtual XTAPI VOID InitializePageMapInfo(VOID) = 0;
|
||||||
VIRTUAL XTAPI BOOLEAN GetOneEntry(IN PMMPTE Pte) = 0;
|
virtual XTAPI BOOLEAN PteValid(PHARDWARE_PTE PtePointer) = 0;
|
||||||
VIRTUAL XTAPI PFN_NUMBER GetPageFrameNumber(IN PMMPTE Pte) = 0;
|
virtual XTAPI VOID SetPte(PHARDWARE_PTE PtePointer,
|
||||||
XTAPI USHORT GetPageMapLevel();
|
PFN_NUMBER PageFrameNumber,
|
||||||
XTAPI PMMPDE GetPdeAddress(IN PVOID Address);
|
BOOLEAN Writable) = 0;
|
||||||
XTAPI ULONG GetPdeOffset(IN PVOID Address);
|
virtual XTAPI VOID SetPteCaching(PHARDWARE_PTE PtePointer,
|
||||||
VIRTUAL XTAPI PVOID GetPdeVirtualAddress(IN PMMPDE PdePointer) = 0;
|
BOOLEAN CacheDisable,
|
||||||
XTAPI PMMPPE GetPpeAddress(IN PVOID Address);
|
BOOLEAN WriteThrough) = 0;
|
||||||
XTAPI ULONG GetPpeOffset(IN PVOID Address);
|
|
||||||
XTAPI PVOID GetPpeVirtualAddress(IN PMMPPE PpePointer);
|
|
||||||
VIRTUAL XTAPI ULONG_PTR GetPte(IN PMMPTE PtePointer) = 0;
|
|
||||||
XTAPI PMMPTE GetPteAddress(IN PVOID Address);
|
|
||||||
XTAPI ULONG GetPteOffset(IN PVOID Address);
|
|
||||||
VIRTUAL XTAPI LONG GetPteDistance(PMMPTE EndPte,
|
|
||||||
PMMPTE StartPte) = 0;
|
|
||||||
VIRTUAL XTAPI ULONG GetPteSize(VOID) = 0;
|
|
||||||
VIRTUAL XTAPI ULONG GetPteSoftwareProtection(IN PMMPTE PtePointer) = 0;
|
|
||||||
VIRTUAL XTAPI ULONG GetPteSoftwarePrototype(IN PMMPTE PtePointer) = 0;
|
|
||||||
VIRTUAL XTAPI ULONG GetPteSoftwareTransition(IN PMMPTE PtePointer) = 0;
|
|
||||||
VIRTUAL XTAPI PVOID GetPteVirtualAddress(IN PMMPTE PtePointer) = 0;
|
|
||||||
XTAPI BOOLEAN GetXpaStatus();
|
|
||||||
VIRTUAL XTAPI VOID InitializePageMapInfo(VOID) = 0;
|
|
||||||
VIRTUAL XTAPI BOOLEAN PteValid(IN PMMPTE PtePointer) = 0;
|
|
||||||
VIRTUAL XTAPI VOID SetNextEntry(IN PMMPTE Pte,
|
|
||||||
IN ULONG_PTR Value) = 0;
|
|
||||||
VIRTUAL XTAPI VOID SetOneEntry(IN PMMPTE Pte,
|
|
||||||
IN BOOLEAN Value) = 0;
|
|
||||||
VIRTUAL XTAPI VOID SetPte(IN PMMPTE PtePointer,
|
|
||||||
IN PFN_NUMBER PageFrameNumber,
|
|
||||||
IN ULONG_PTR AttributesMask) = 0;
|
|
||||||
VIRTUAL XTAPI VOID SetPte(IN PMMPTE PtePointer,
|
|
||||||
IN ULONG_PTR Attributes) = 0;
|
|
||||||
VIRTUAL XTAPI VOID SetPteCaching(IN PMMPTE PtePointer,
|
|
||||||
IN BOOLEAN CacheDisable,
|
|
||||||
IN BOOLEAN WriteThrough) = 0;
|
|
||||||
VIRTUAL XTAPI VOID TransitionPte(IN PMMPTE PointerPte,
|
|
||||||
IN ULONG_PTR Protection) = 0;
|
|
||||||
VIRTUAL XTAPI VOID WritePte(IN PMMPTE Pte,
|
|
||||||
IN MMPTE Value) = 0;
|
|
||||||
|
|
||||||
} PAGEMAP, *PPAGEMAP;
|
} PAGEMAP, *PPAGEMAP;
|
||||||
|
|
||||||
class PageMapBasic final : public PageMap
|
class PageMapBasic final : public PageMap
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
XTAPI PMMPTE AdvancePte(IN PMMPTE Pte,
|
|
||||||
IN ULONG Count);
|
|
||||||
XTAPI VOID ClearPte(IN PMMPTE PtePointer);
|
|
||||||
XTAPI ULONG_PTR GetNextEntry(IN PMMPTE Pte);
|
|
||||||
XTAPI PMMPTE GetNextPte(IN PMMPTE Pte);
|
|
||||||
XTAPI BOOLEAN GetOneEntry(IN PMMPTE Pte);
|
|
||||||
XTAPI PFN_NUMBER GetPageFrameNumber(IN PMMPTE Pte);
|
|
||||||
XTAPI PVOID GetPdeVirtualAddress(IN PMMPDE PdePointer);
|
|
||||||
XTAPI ULONG_PTR GetPte(IN PMMPTE PtePointer);
|
|
||||||
XTAPI LONG GetPteDistance(PMMPTE EndPte,
|
|
||||||
PMMPTE StartPte);
|
|
||||||
XTAPI ULONG GetPteSize(VOID);
|
|
||||||
XTAPI ULONG GetPteSoftwareProtection(IN PMMPTE PtePointer);
|
|
||||||
XTAPI ULONG GetPteSoftwarePrototype(IN PMMPTE PtePointer);
|
|
||||||
XTAPI ULONG GetPteSoftwareTransition(IN PMMPTE PtePointer);
|
|
||||||
XTAPI PVOID GetPteVirtualAddress(IN PMMPTE PtePointer);
|
|
||||||
XTAPI VOID InitializePageMapInfo(VOID);
|
XTAPI VOID InitializePageMapInfo(VOID);
|
||||||
XTAPI BOOLEAN PteValid(IN PMMPTE PtePointer);
|
XTAPI BOOLEAN PteValid(PHARDWARE_PTE PtePointer);
|
||||||
XTAPI VOID SetNextEntry(IN PMMPTE Pte,
|
XTAPI VOID SetPte(PHARDWARE_PTE PtePointer,
|
||||||
IN ULONG_PTR Value);
|
PFN_NUMBER PageFrameNumber,
|
||||||
XTAPI VOID SetOneEntry(IN PMMPTE Pte,
|
BOOLEAN Writable);
|
||||||
IN BOOLEAN Value);
|
XTAPI VOID SetPteCaching(PHARDWARE_PTE PtePointer,
|
||||||
XTAPI VOID SetPte(IN PMMPTE PtePointer,
|
BOOLEAN CacheDisable,
|
||||||
IN PFN_NUMBER PageFrameNumber,
|
BOOLEAN WriteThrough);
|
||||||
IN ULONG_PTR AttributesMask);
|
|
||||||
XTAPI VOID SetPte(IN PMMPTE PtePointer,
|
|
||||||
IN ULONG_PTR Attributes);
|
|
||||||
XTAPI VOID SetPteCaching(IN PMMPTE PtePointer,
|
|
||||||
IN BOOLEAN CacheDisable,
|
|
||||||
IN BOOLEAN WriteThrough);
|
|
||||||
XTAPI VOID TransitionPte(IN PMMPTE PointerPte,
|
|
||||||
IN ULONG_PTR Protection);
|
|
||||||
XTAPI VOID WritePte(IN PMMPTE Pte,
|
|
||||||
IN MMPTE Value);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class PageMapXpa final : public PageMap
|
class PageMapXpa final : public PageMap
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
XTAPI PMMPTE AdvancePte(IN PMMPTE Pte,
|
|
||||||
IN ULONG Count);
|
|
||||||
XTAPI VOID ClearPte(IN PMMPTE PtePointer);
|
|
||||||
XTAPI ULONG_PTR GetNextEntry(IN PMMPTE Pte);
|
|
||||||
XTAPI PMMPTE GetNextPte(IN PMMPTE Pte);
|
|
||||||
XTAPI BOOLEAN GetOneEntry(IN PMMPTE Pte);
|
|
||||||
XTAPI PFN_NUMBER GetPageFrameNumber(IN PMMPTE Pte);
|
|
||||||
XTAPI PVOID GetPdeVirtualAddress(IN PMMPDE PdePointer);
|
|
||||||
XTAPI ULONG_PTR GetPte(IN PMMPTE PtePointer);
|
|
||||||
XTAPI LONG GetPteDistance(PMMPTE EndPte,
|
|
||||||
PMMPTE StartPte);
|
|
||||||
XTAPI ULONG GetPteSize(VOID);
|
|
||||||
XTAPI ULONG GetPteSoftwareProtection(IN PMMPTE PtePointer);
|
|
||||||
XTAPI ULONG GetPteSoftwarePrototype(IN PMMPTE PtePointer);
|
|
||||||
XTAPI ULONG GetPteSoftwareTransition(IN PMMPTE PtePointer);
|
|
||||||
XTAPI PVOID GetPteVirtualAddress(IN PMMPTE PtePointer);
|
|
||||||
XTAPI VOID InitializePageMapInfo(VOID);
|
XTAPI VOID InitializePageMapInfo(VOID);
|
||||||
XTAPI BOOLEAN PteValid(IN PMMPTE PtePointer);
|
XTAPI BOOLEAN PteValid(PHARDWARE_PTE PtePointer);
|
||||||
XTAPI VOID SetNextEntry(IN PMMPTE Pte,
|
XTAPI VOID SetPte(PHARDWARE_PTE PtePointer,
|
||||||
IN ULONG_PTR Value);
|
PFN_NUMBER PageFrameNumber,
|
||||||
XTAPI VOID SetOneEntry(IN PMMPTE Pte,
|
BOOLEAN Writable);
|
||||||
IN BOOLEAN Value);
|
XTAPI VOID SetPteCaching(PHARDWARE_PTE PtePointer,
|
||||||
XTAPI VOID SetPte(IN PMMPTE PtePointer,
|
BOOLEAN CacheDisable,
|
||||||
IN PFN_NUMBER PageFrameNumber,
|
BOOLEAN WriteThrough);
|
||||||
IN ULONG_PTR AttributesMask);
|
|
||||||
XTAPI VOID SetPte(IN PMMPTE PtePointer,
|
|
||||||
IN ULONG_PTR Attributes);
|
|
||||||
XTAPI VOID SetPteCaching(IN PMMPTE PtePointer,
|
|
||||||
IN BOOLEAN CacheDisable,
|
|
||||||
IN BOOLEAN WriteThrough);
|
|
||||||
XTAPI VOID TransitionPte(IN PMMPTE PointerPte,
|
|
||||||
IN ULONG_PTR Protection);
|
|
||||||
XTAPI VOID WritePte(IN PMMPTE Pte,
|
|
||||||
IN MMPTE Value);
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* __XTOSKRNL_MM_I686_PAGEMAP_HH */
|
#endif /* __XTOSKRNL_MM_PAGEMAP_HH */
|
||||||
|
|||||||
@@ -1,75 +0,0 @@
|
|||||||
/**
|
|
||||||
* PROJECT: ExectOS
|
|
||||||
* COPYRIGHT: See COPYING.md in the top level directory
|
|
||||||
* FILE: xtoskrnl/includes/mm/i686/paging.hh
|
|
||||||
* DESCRIPTION: Low level page management support for i686
|
|
||||||
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __XTOSKRNL_MM_I686_PAGING_HH
|
|
||||||
#define __XTOSKRNL_MM_I686_PAGING_HH
|
|
||||||
|
|
||||||
#include <xtos.hh>
|
|
||||||
|
|
||||||
|
|
||||||
/* Memory Manager */
|
|
||||||
namespace MM
|
|
||||||
{
|
|
||||||
class Paging
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
STATIC PPAGEMAP PmlRoutines;
|
|
||||||
|
|
||||||
public:
|
|
||||||
STATIC XTAPI PMMPTE AdvancePte(IN PMMPTE Pte,
|
|
||||||
IN LONG Count);
|
|
||||||
STATIC XTAPI VOID ClearPte(IN PMMPTE PtePointer);
|
|
||||||
STATIC XTAPI VOID FlushTlb(VOID);
|
|
||||||
STATIC XTAPI ULONG_PTR GetNextEntry(IN PMMPTE Pte);
|
|
||||||
STATIC XTAPI PMMPTE GetNextPte(IN PMMPTE Pte);
|
|
||||||
STATIC XTAPI BOOLEAN GetOneEntry(IN PMMPTE Pte);
|
|
||||||
STATIC XTAPI PFN_NUMBER GetPageFrameNumber(IN PMMPTE Pte);
|
|
||||||
STATIC XTAPI USHORT GetPageMapLevel();
|
|
||||||
STATIC XTAPI PMMPDE GetPdeAddress(IN PVOID Address);
|
|
||||||
STATIC XTAPI PVOID GetPdeVirtualAddress(IN PMMPDE PdePointer);
|
|
||||||
STATIC XTAPI PMMPPE GetPpeAddress(IN PVOID Address);
|
|
||||||
STATIC XTAPI PVOID GetPpeVirtualAddress(IN PMMPPE PpePointer);
|
|
||||||
STATIC XTAPI ULONG_PTR GetPte(IN PMMPTE PtePointer);
|
|
||||||
STATIC XTAPI PMMPTE GetPteAddress(IN PVOID Address);
|
|
||||||
STATIC XTAPI LONG GetPteDistance(PMMPTE EndPte,
|
|
||||||
PMMPTE StartPte);
|
|
||||||
STATIC XTAPI ULONG GetPteSize(VOID);
|
|
||||||
STATIC XTAPI ULONG GetPteSoftwareProtection(IN PMMPTE PtePointer);
|
|
||||||
STATIC XTAPI ULONG GetPteSoftwarePrototype(IN PMMPTE PtePointer);
|
|
||||||
STATIC XTAPI ULONG GetPteSoftwareTransition(IN PMMPTE PtePointer);
|
|
||||||
STATIC XTAPI PVOID GetPteVirtualAddress(IN PMMPTE PtePointer);
|
|
||||||
STATIC XTAPI BOOLEAN GetXpaStatus(VOID);
|
|
||||||
STATIC XTAPI VOID InitializePageMapSupport(VOID);
|
|
||||||
STATIC XTAPI BOOLEAN PteValid(IN PMMPTE PtePointer);
|
|
||||||
STATIC XTAPI VOID SetNextEntry(IN PMMPTE Pte,
|
|
||||||
IN ULONG_PTR Value);
|
|
||||||
STATIC XTAPI VOID SetOneEntry(IN PMMPTE Pte,
|
|
||||||
IN BOOLEAN Value);
|
|
||||||
STATIC XTAPI VOID SetPte(IN PMMPTE PtePointer,
|
|
||||||
IN PFN_NUMBER PageFrameNumber,
|
|
||||||
IN ULONG_PTR AttributesMask);
|
|
||||||
STATIC XTAPI VOID SetPte(IN PMMPTE PtePointer,
|
|
||||||
IN ULONG_PTR Attributes);
|
|
||||||
STATIC XTAPI VOID SetPteCaching(IN PMMPTE PtePointer,
|
|
||||||
IN BOOLEAN CacheDisable,
|
|
||||||
IN BOOLEAN WriteThrough);
|
|
||||||
STATIC XTAPI VOID WritePte(IN PMMPTE Pte,
|
|
||||||
IN MMPTE Value);
|
|
||||||
STATIC XTAPI VOID TransitionPte(IN PMMPTE PointerPte,
|
|
||||||
IN ULONG_PTR Protection);
|
|
||||||
STATIC XTFASTCALL VOID ZeroPages(IN PVOID Address,
|
|
||||||
IN ULONG Size);
|
|
||||||
|
|
||||||
private:
|
|
||||||
STATIC XTAPI BOOLEAN GetExtendedPhysicalAddressingStatus(VOID);
|
|
||||||
STATIC XTAPI PPAGEMAP GetPageMapBasicRoutines(VOID);
|
|
||||||
STATIC XTAPI PPAGEMAP GetPageMapXpaRoutines(VOID);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* __XTOSKRNL_MM_I686_PAGING_HH */
|
|
||||||
@@ -1,63 +0,0 @@
|
|||||||
/**
|
|
||||||
* PROJECT: ExectOS
|
|
||||||
* COPYRIGHT: See COPYING.md in the top level directory
|
|
||||||
* FILE: xtoskrnl/includes/mm/i686/pte.hh
|
|
||||||
* DESCRIPTION: Page Table Entry (PTE) for i686 support
|
|
||||||
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __XTOSKRNL_MM_I686_PTE_HH
|
|
||||||
#define __XTOSKRNL_MM_I686_PTE_HH
|
|
||||||
|
|
||||||
#include <xtos.hh>
|
|
||||||
|
|
||||||
|
|
||||||
/* Memory Manager */
|
|
||||||
namespace MM
|
|
||||||
{
|
|
||||||
class Pte
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
STATIC MMPTE FirstSystemFreePte[MaximumPtePoolTypes];
|
|
||||||
STATIC PMMPTE SystemPteBase;
|
|
||||||
STATIC PMMPTE SystemPtesEnd[MaximumPtePoolTypes];
|
|
||||||
STATIC PMMPTE SystemPtesStart[MaximumPtePoolTypes];
|
|
||||||
STATIC PFN_COUNT TotalSystemFreePtes[MaximumPtePoolTypes];
|
|
||||||
STATIC MMPTE ValidPte;
|
|
||||||
|
|
||||||
public:
|
|
||||||
STATIC XTAPI BOOLEAN AddressValid(IN PVOID VirtualAddress);
|
|
||||||
STATIC XTAPI PFN_COUNT GetPtesPerPage(VOID);
|
|
||||||
STATIC XTAPI PMMPTE GetSystemPteBaseAddress(VOID);
|
|
||||||
STATIC XTAPI PMMPTE GetValidPte(VOID);
|
|
||||||
STATIC XTAPI VOID InitializePageTable(VOID);
|
|
||||||
STATIC XTAPI VOID InitializeSystemPte(VOID);
|
|
||||||
STATIC XTAPI VOID InitializeSystemPteSpace(VOID);
|
|
||||||
STATIC XTAPI VOID MapPDE(IN PVOID StartAddress,
|
|
||||||
IN PVOID EndAddress,
|
|
||||||
IN PMMPDE TemplatePde);
|
|
||||||
STATIC XTAPI VOID MapPPE(IN PVOID StartAddress,
|
|
||||||
IN PVOID EndAddress,
|
|
||||||
IN PMMPPE TemplatePpe);
|
|
||||||
STATIC XTAPI VOID MapPTE(IN PVOID StartAddress,
|
|
||||||
IN PVOID EndAddress,
|
|
||||||
IN PMMPTE TemplatePte);
|
|
||||||
STATIC XTAPI VOID ReleaseSystemPtes(IN PMMPTE StartingPte,
|
|
||||||
IN PFN_COUNT NumberOfPtes,
|
|
||||||
IN MMSYSTEM_PTE_POOL_TYPE SystemPtePoolType);
|
|
||||||
STATIC XTAPI PMMPTE ReserveSystemPtes(IN PFN_COUNT NumberOfPtes,
|
|
||||||
IN MMSYSTEM_PTE_POOL_TYPE SystemPtePoolType);
|
|
||||||
|
|
||||||
private:
|
|
||||||
STATIC XTAPI BOOLEAN FindFreeCluster(IN PFN_COUNT NumberOfPtes,
|
|
||||||
IN MMSYSTEM_PTE_POOL_TYPE SystemPtePoolType,
|
|
||||||
OUT PMMPTE *FoundCluster,
|
|
||||||
OUT PMMPTE *PreviousClusterNode);
|
|
||||||
STATIC XTAPI ULONG GetClusterSize(IN PMMPTE Pte);
|
|
||||||
STATIC XTAPI VOID InitializeSystemPtePool(IN PMMPTE StartingPte,
|
|
||||||
IN PFN_COUNT NumberOfPtes,
|
|
||||||
IN MMSYSTEM_PTE_POOL_TYPE PoolType);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* __XTOSKRNL_MM_I686_PTE_HH */
|
|
||||||
39
xtoskrnl/includes/mm/init.hh
Normal file
39
xtoskrnl/includes/mm/init.hh
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
/**
|
||||||
|
* PROJECT: ExectOS
|
||||||
|
* COPYRIGHT: See COPYING.md in the top level directory
|
||||||
|
* FILE: xtoskrnl/includes/mm/init.hh
|
||||||
|
* DESCRIPTION: Memory Manager initialization
|
||||||
|
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __XTOSKRNL_MM_INIT_HH
|
||||||
|
#define __XTOSKRNL_MM_INIT_HH
|
||||||
|
|
||||||
|
#include <xtos.hh>
|
||||||
|
|
||||||
|
|
||||||
|
/* Memory Manager */
|
||||||
|
namespace MM
|
||||||
|
{
|
||||||
|
class Init
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
STATIC PLOADER_MEMORY_DESCRIPTOR FreeDescriptor;
|
||||||
|
STATIC ULONG_PTR HighestPhysicalPage;
|
||||||
|
STATIC ULONG_PTR LowestPhysicalPage;
|
||||||
|
STATIC ULONG NumberOfPhysicalPages;
|
||||||
|
STATIC LOADER_MEMORY_DESCRIPTOR OldFreeDescriptor;
|
||||||
|
|
||||||
|
public:
|
||||||
|
STATIC XTAPI VOID InitializeMemoryManager(VOID);
|
||||||
|
STATIC XTAPI VOID InitializePageMapSupport(VOID);
|
||||||
|
STATIC XTAPI VOID ScanMemoryDescriptors(VOID);
|
||||||
|
|
||||||
|
private:
|
||||||
|
STATIC XTAPI VOID InitializeArchitecture(VOID);
|
||||||
|
STATIC XTAPI BOOLEAN VerifyMemoryTypeFree(LOADER_MEMORY_TYPE MemoryType);
|
||||||
|
STATIC XTAPI BOOLEAN VerifyMemoryTypeInvisible(LOADER_MEMORY_TYPE MemoryType);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* __XTOSKRNL_MM_INIT_HH */
|
||||||
@@ -21,12 +21,13 @@ namespace MM
|
|||||||
STATIC UCHAR ProcessorStructuresData[MAXIMUM_PROCESSORS][KPROCESSOR_STRUCTURES_SIZE];
|
STATIC UCHAR ProcessorStructuresData[MAXIMUM_PROCESSORS][KPROCESSOR_STRUCTURES_SIZE];
|
||||||
|
|
||||||
public:
|
public:
|
||||||
STATIC XTAPI XTSTATUS AllocateKernelStack(OUT PVOID *Stack,
|
STATIC XTAPI XTSTATUS AllocateKernelStack(IN PVOID *Stack,
|
||||||
IN ULONG StackSize);
|
IN BOOLEAN LargeStack,
|
||||||
|
IN UCHAR SystemNode);
|
||||||
STATIC XTAPI XTSTATUS AllocateProcessorStructures(IN ULONG CpuNumber,
|
STATIC XTAPI XTSTATUS AllocateProcessorStructures(IN ULONG CpuNumber,
|
||||||
OUT PVOID *StructuresData);
|
OUT PVOID *StructuresData);
|
||||||
STATIC XTAPI VOID FreeKernelStack(IN PVOID Stack,
|
STATIC XTAPI VOID FreeKernelStack(IN PVOID Stack,
|
||||||
IN ULONG StackSize);
|
IN BOOLEAN LargeStack);
|
||||||
STATIC XTAPI VOID FreeProcessorStructures(IN PVOID StructuresData);
|
STATIC XTAPI VOID FreeProcessorStructures(IN PVOID StructuresData);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,44 +0,0 @@
|
|||||||
/**
|
|
||||||
* PROJECT: ExectOS
|
|
||||||
* COPYRIGHT: See COPYING.md in the top level directory
|
|
||||||
* FILE: xtoskrnl/includes/mm/mmgr.hh
|
|
||||||
* DESCRIPTION: Memory Manager
|
|
||||||
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __XTOSKRNL_MM_MMGR_HH
|
|
||||||
#define __XTOSKRNL_MM_MMGR_HH
|
|
||||||
|
|
||||||
#include <xtos.hh>
|
|
||||||
|
|
||||||
|
|
||||||
/* Memory Manager */
|
|
||||||
namespace MM
|
|
||||||
{
|
|
||||||
class Manager
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
STATIC MMMEMORY_LAYOUT MemoryLayout;
|
|
||||||
STATIC PFN_NUMBER NumberOfSystemPtes;
|
|
||||||
|
|
||||||
public:
|
|
||||||
STATIC XTAPI ULONG_PTR GetInstalledMemorySize(VOID);
|
|
||||||
STATIC XTAPI PMMMEMORY_LAYOUT GetMemoryLayout(VOID);
|
|
||||||
STATIC XTAPI PFN_NUMBER GetNumberOfSystemPtes();
|
|
||||||
STATIC XTAPI VOID InitializeMemoryLayout(VOID);
|
|
||||||
STATIC XTAPI VOID InitializeMemoryManager(VOID);
|
|
||||||
STATIC XTAPI BOOLEAN VerifyMemoryTypeFree(IN LOADER_MEMORY_TYPE MemoryType);
|
|
||||||
STATIC XTAPI BOOLEAN VerifyMemoryTypeInvisible(IN LOADER_MEMORY_TYPE MemoryType);
|
|
||||||
|
|
||||||
private:
|
|
||||||
STATIC XTAPI VOID ComputeBootImageSize(OUT PPFN_NUMBER BootImageSize);
|
|
||||||
STATIC XTAPI VOID ComputeMaximumNonPagedPoolSize(OUT PPFN_NUMBER PoolSize);
|
|
||||||
STATIC XTAPI VOID ComputeNonPagedPoolSize(OUT PPFN_NUMBER PoolSize);
|
|
||||||
STATIC XTAPI VOID ComputePagedPoolSize(OUT PPFN_NUMBER PoolSize);
|
|
||||||
STATIC XTAPI VOID ComputeSessionSpaceSize(OUT PPFN_NUMBER SpaceSize);
|
|
||||||
STATIC XTAPI VOID ComputeSystemPteSize(OUT PPFN_NUMBER PteSize);
|
|
||||||
STATIC XTAPI VOID DumpMemoryLayout(VOID);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* __XTOSKRNL_MM_MMGR_HH */
|
|
||||||
47
xtoskrnl/includes/mm/paging.hh
Normal file
47
xtoskrnl/includes/mm/paging.hh
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
/**
|
||||||
|
* PROJECT: ExectOS
|
||||||
|
* COPYRIGHT: See COPYING.md in the top level directory
|
||||||
|
* FILE: xtoskrnl/includes/mm/paging.hh
|
||||||
|
* DESCRIPTION: Low level page management support
|
||||||
|
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __XTOSKRNL_MM_PAGING_HH
|
||||||
|
#define __XTOSKRNL_MM_PAGING_HH
|
||||||
|
|
||||||
|
#include <xtos.hh>
|
||||||
|
|
||||||
|
|
||||||
|
/* Memory Manager */
|
||||||
|
namespace MM
|
||||||
|
{
|
||||||
|
class Paging
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
STATIC PPAGEMAP PmlRoutines;
|
||||||
|
|
||||||
|
public:
|
||||||
|
STATIC XTAPI VOID ClearPte(PHARDWARE_PTE PtePointer);
|
||||||
|
STATIC XTAPI VOID FlushTlb(VOID);
|
||||||
|
STATIC XTAPI PMMPDE GetPdeAddress(PVOID Address);
|
||||||
|
STATIC XTAPI PMMPPE GetPpeAddress(PVOID Address);
|
||||||
|
STATIC XTAPI PMMPTE GetPteAddress(PVOID Address);
|
||||||
|
STATIC XTAPI VOID InitializePageMapSupport(VOID);
|
||||||
|
STATIC XTAPI BOOLEAN PteValid(PHARDWARE_PTE PtePointer);
|
||||||
|
STATIC XTAPI VOID SetPte(PHARDWARE_PTE PtePointer,
|
||||||
|
PFN_NUMBER PageFrameNumber,
|
||||||
|
BOOLEAN Writable);
|
||||||
|
STATIC XTAPI VOID SetPteCaching(PHARDWARE_PTE PtePointer,
|
||||||
|
BOOLEAN CacheDisable,
|
||||||
|
BOOLEAN WriteThrough);
|
||||||
|
STATIC XTFASTCALL VOID ZeroPages(IN PVOID Address,
|
||||||
|
IN ULONG Size);
|
||||||
|
|
||||||
|
private:
|
||||||
|
STATIC XTAPI BOOLEAN GetExtendedPhysicalAddressingStatus(VOID);
|
||||||
|
STATIC XTAPI PPAGEMAP GetPageMapBasicRoutines(VOID);
|
||||||
|
STATIC XTAPI PPAGEMAP GetPageMapXpaRoutines(VOID);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* __XTOSKRNL_MM_PAGING_HH */
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
/**
|
|
||||||
* PROJECT: ExectOS
|
|
||||||
* COPYRIGHT: See COPYING.md in the top level directory
|
|
||||||
* FILE: xtoskrnl/includes/mm/pfault.hh
|
|
||||||
* DESCRIPTION: Page fault support
|
|
||||||
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __XTOSKRNL_MM_PFAULT_HH
|
|
||||||
#define __XTOSKRNL_MM_PFAULT_HH
|
|
||||||
|
|
||||||
#include <xtos.hh>
|
|
||||||
|
|
||||||
|
|
||||||
/* Memory Manager */
|
|
||||||
namespace MM
|
|
||||||
{
|
|
||||||
class PageFault
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
STATIC XTFASTCALL XTSTATUS CheckPdeForPagedPool(IN PVOID VirtualAddress);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* __XTOSKRNL_MM_PFAULT_HH */
|
|
||||||
@@ -1,83 +0,0 @@
|
|||||||
/**
|
|
||||||
* PROJECT: ExectOS
|
|
||||||
* COPYRIGHT: See COPYING.md in the top level directory
|
|
||||||
* FILE: xtoskrnl/includes/mm/pfn.hh
|
|
||||||
* DESCRIPTION: Physical Frame Number (PFN) support
|
|
||||||
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __XTOSKRNL_MM_PFN_HH
|
|
||||||
#define __XTOSKRNL_MM_PFN_HH
|
|
||||||
|
|
||||||
#include <xtos.hh>
|
|
||||||
|
|
||||||
|
|
||||||
/* Memory Manager */
|
|
||||||
namespace MM
|
|
||||||
{
|
|
||||||
class Pfn
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
STATIC PFN_NUMBER AvailablePages;
|
|
||||||
STATIC MMPFNLIST BadPagesList;
|
|
||||||
STATIC PLOADER_MEMORY_DESCRIPTOR FreeDescriptor;
|
|
||||||
STATIC MMPFNLIST FreePagesList;
|
|
||||||
STATIC ULONG_PTR HighestPhysicalPage;
|
|
||||||
STATIC PVOID HighestUserAddress;
|
|
||||||
STATIC ULONG_PTR LowestPhysicalPage;
|
|
||||||
STATIC MMPFNLIST ModifiedPagesList;
|
|
||||||
STATIC MMPFNLIST ModifiedReadOnlyPagesList;
|
|
||||||
STATIC ULONGLONG NumberOfPhysicalPages;
|
|
||||||
STATIC LOADER_MEMORY_DESCRIPTOR OriginalFreeDescriptor;
|
|
||||||
STATIC PMMPFNLIST PageLocationList[];
|
|
||||||
STATIC MMPFNLIST RomPagesList;
|
|
||||||
STATIC MMPFNLIST StandbyPagesList;
|
|
||||||
STATIC MMPFNLIST ZeroedPagesList;
|
|
||||||
|
|
||||||
public:
|
|
||||||
STATIC XTAPI PFN_NUMBER AllocateBootstrapPages(IN PFN_NUMBER NumberOfPages);
|
|
||||||
STATIC XTAPI PFN_NUMBER AllocatePhysicalPage(IN ULONG Color);
|
|
||||||
STATIC XTAPI VOID ComputePfnDatabaseSize(OUT PPFN_NUMBER DatabaseSize);
|
|
||||||
STATIC XTAPI VOID DecrementReferenceCount(IN PMMPFN Pfn1,
|
|
||||||
IN PFN_NUMBER PageFrameIndex,
|
|
||||||
IN BOOLEAN BeginStandbyList = FALSE);
|
|
||||||
STATIC XTAPI VOID DecrementShareCount(IN PMMPFN Pfn1,
|
|
||||||
IN PFN_NUMBER PageFrameIndex,
|
|
||||||
IN BOOLEAN BeginStandbyList = FALSE);
|
|
||||||
STATIC XTAPI VOID FreePhysicalPage(IN PMMPTE PointerPte);
|
|
||||||
STATIC XTAPI PFN_NUMBER GetAvailablePages(VOID);
|
|
||||||
STATIC XTAPI ULONG_PTR GetHighestPhysicalPage(VOID);
|
|
||||||
STATIC XTAPI ULONGLONG GetNumberOfPhysicalPages(VOID);
|
|
||||||
STATIC XTAPI PMMPFN GetPfnEntry(IN PFN_NUMBER Pfn);
|
|
||||||
STATIC XTAPI VOID InitializePfnDatabase(VOID);
|
|
||||||
STATIC XTAPI VOID LinkPfn(IN PFN_NUMBER PageFrameIndex,
|
|
||||||
IN PMMPTE PointerPte,
|
|
||||||
IN BOOLEAN Modified);
|
|
||||||
STATIC XTAPI VOID LinkPfnWithParent(IN PFN_NUMBER PageFrameIndex,
|
|
||||||
IN PMMPTE PointerPte,
|
|
||||||
IN PFN_NUMBER ParentFrame);
|
|
||||||
STATIC XTAPI VOID ScanMemoryDescriptors(VOID);
|
|
||||||
|
|
||||||
private:
|
|
||||||
STATIC XTAPI VOID DecrementAvailablePages(VOID);
|
|
||||||
STATIC XTAPI VOID IncrementAvailablePages(VOID);
|
|
||||||
STATIC XTAPI VOID InitializePageDirectory(IN PMMPDE StartingPde,
|
|
||||||
IN PMMPDE EndingPde);
|
|
||||||
STATIC XTAPI VOID InitializePageTablePfns(VOID);
|
|
||||||
STATIC XTAPI VOID LinkFreePage(IN PFN_NUMBER PageFrameIndex);
|
|
||||||
STATIC XTAPI VOID LinkPage(IN PMMPFNLIST ListHead,
|
|
||||||
IN PFN_NUMBER PageFrameIndex);
|
|
||||||
STATIC XTAPI VOID LinkPfnForPageTable(IN PFN_NUMBER PageFrameIndex,
|
|
||||||
IN PMMPTE PointerPte);
|
|
||||||
STATIC XTFASTCALL VOID LinkStandbyPage(IN PFN_NUMBER PageFrameIndex);
|
|
||||||
STATIC XTAPI VOID ProcessMemoryDescriptor(IN PFN_NUMBER BasePage,
|
|
||||||
IN PFN_NUMBER PageCount,
|
|
||||||
IN LOADER_MEMORY_TYPE MemoryType);
|
|
||||||
STATIC XTAPI VOID ScanPageTable(IN PMMPTE PointerPte,
|
|
||||||
IN ULONG Level);
|
|
||||||
STATIC XTAPI PFN_NUMBER UnlinkFreePage(IN PFN_NUMBER PageFrameIndex,
|
|
||||||
IN ULONG Color);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* __XTOSKRNL_MM_PFN_HH */
|
|
||||||
@@ -19,8 +19,6 @@
|
|||||||
#include <rtl/llist.hh>
|
#include <rtl/llist.hh>
|
||||||
#include <rtl/math.hh>
|
#include <rtl/math.hh>
|
||||||
#include <rtl/memory.hh>
|
#include <rtl/memory.hh>
|
||||||
#include <rtl/sha1.hh>
|
|
||||||
#include <rtl/slist.hh>
|
|
||||||
#include <rtl/string.hh>
|
#include <rtl/string.hh>
|
||||||
#include <rtl/widestr.hh>
|
#include <rtl/widestr.hh>
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
* FILE: xtoskrnl/includes/rtl/llist.hh
|
* FILE: xtoskrnl/includes/rtl/llist.hh
|
||||||
* DESCRIPTION: Linked list manipulation routines
|
* DESCRIPTION: Linked list manipulation routines
|
||||||
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
|
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
|
||||||
* Rafal Kupiec <belliash@codingworkshop.eu.org>
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __XTOSKRNL_RTL_LLIST_HH
|
#ifndef __XTOSKRNL_RTL_LLIST_HH
|
||||||
@@ -19,7 +18,6 @@ namespace RTL
|
|||||||
class LinkedList
|
class LinkedList
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
STATIC XTCDECL PLIST_ENTRY GetFirstEntry(IN PLIST_ENTRY ListHead);
|
|
||||||
STATIC XTCDECL VOID InitializeListHead(IN PLIST_ENTRY ListHead);
|
STATIC XTCDECL VOID InitializeListHead(IN PLIST_ENTRY ListHead);
|
||||||
STATIC XTCDECL VOID InitializeListHead32(IN PLIST_ENTRY32 ListHead);
|
STATIC XTCDECL VOID InitializeListHead32(IN PLIST_ENTRY32 ListHead);
|
||||||
STATIC XTCDECL VOID InsertHeadList(IN OUT PLIST_ENTRY ListHead,
|
STATIC XTCDECL VOID InsertHeadList(IN OUT PLIST_ENTRY ListHead,
|
||||||
@@ -29,10 +27,6 @@ namespace RTL
|
|||||||
STATIC XTCDECL BOOLEAN ListEmpty(IN PLIST_ENTRY ListHead);
|
STATIC XTCDECL BOOLEAN ListEmpty(IN PLIST_ENTRY ListHead);
|
||||||
STATIC XTCDECL BOOLEAN ListLoop(IN PLIST_ENTRY ListHead);
|
STATIC XTCDECL BOOLEAN ListLoop(IN PLIST_ENTRY ListHead);
|
||||||
STATIC XTCDECL VOID RemoveEntryList(IN PLIST_ENTRY Entry);
|
STATIC XTCDECL VOID RemoveEntryList(IN PLIST_ENTRY Entry);
|
||||||
STATIC XTCDECL VOID SpliceHeadList(IN OUT PLIST_ENTRY ListHead,
|
|
||||||
IN OUT PLIST_ENTRY SpliceList);
|
|
||||||
STATIC XTCDECL VOID SpliceTailList(IN OUT PLIST_ENTRY ListHead,
|
|
||||||
IN OUT PLIST_ENTRY SpliceList);
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,37 +0,0 @@
|
|||||||
/**
|
|
||||||
* PROJECT: ExectOS
|
|
||||||
* COPYRIGHT: See COPYING.md in the top level directory
|
|
||||||
* FILE: xtoskrnl/includes/rtl/sha1.hh
|
|
||||||
* DESCRIPTION: SHA1 computation support
|
|
||||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __XTOSKRNL_RTL_SHA1_HH
|
|
||||||
#define __XTOSKRNL_RTL_SHA1_HH
|
|
||||||
|
|
||||||
#include <xtos.hh>
|
|
||||||
|
|
||||||
|
|
||||||
/* Runtime Library */
|
|
||||||
namespace RTL
|
|
||||||
{
|
|
||||||
class SHA1
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
STATIC XTAPI XTSTATUS ComputeDigest(IN PCUCHAR Buffer,
|
|
||||||
IN SIZE_T BufferSize,
|
|
||||||
OUT PUCHAR Digest);
|
|
||||||
|
|
||||||
private:
|
|
||||||
STATIC XTAPI VOID ComputeHash(IN OUT PRTL_SHA1_CONTEXT Context,
|
|
||||||
OUT PUCHAR Digest);
|
|
||||||
STATIC XTAPI VOID HashData(IN OUT PRTL_SHA1_CONTEXT Context,
|
|
||||||
IN PCUCHAR Data,
|
|
||||||
IN ULONG Length);
|
|
||||||
STATIC XTAPI XTSTATUS InitializeContext(OUT PRTL_SHA1_CONTEXT Context);
|
|
||||||
STATIC XTAPI VOID TransformData(IN OUT PULONG State,
|
|
||||||
IN PCUCHAR Buffer);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* __XTOSKRNL_RTL_SHA1_HH */
|
|
||||||
@@ -1,39 +0,0 @@
|
|||||||
/**
|
|
||||||
* PROJECT: ExectOS
|
|
||||||
* COPYRIGHT: See COPYING.md in the top level directory
|
|
||||||
* FILE: xtoskrnl/includes/rtl/slist.hh
|
|
||||||
* DESCRIPTION: Singly linked list manipulation routines
|
|
||||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __XTOSKRNL_RTL_SLIST_HH
|
|
||||||
#define __XTOSKRNL_RTL_SLIST_HH
|
|
||||||
|
|
||||||
#include <xtos.hh>
|
|
||||||
|
|
||||||
|
|
||||||
/* Runtime Library */
|
|
||||||
namespace RTL
|
|
||||||
{
|
|
||||||
class SinglyList
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
STATIC XTCDECL PSINGLE_LIST_ENTRY GetFirstEntry(IN PSINGLE_LIST_HEADER ListHead);
|
|
||||||
STATIC XTCDECL VOID InitializeListHead(IN PSINGLE_LIST_HEADER ListHead);
|
|
||||||
STATIC XTCDECL PSINGLE_LIST_ENTRY InsertHeadList(IN OUT PSINGLE_LIST_HEADER ListHead,
|
|
||||||
IN PSINGLE_LIST_ENTRY Entry);
|
|
||||||
STATIC XTCDECL PSINGLE_LIST_ENTRY InsertTailList(IN OUT PSINGLE_LIST_HEADER ListHead,
|
|
||||||
IN PSINGLE_LIST_ENTRY Entry);
|
|
||||||
STATIC XTCDECL BOOLEAN ListEmpty(IN PSINGLE_LIST_HEADER ListHead);
|
|
||||||
STATIC XTAPI USHORT QueryListDepth(IN PSINGLE_LIST_HEADER ListHead);
|
|
||||||
STATIC XTCDECL VOID RemoveEntryList(IN PSINGLE_LIST_HEADER ListHead,
|
|
||||||
IN PSINGLE_LIST_ENTRY Entry);
|
|
||||||
STATIC XTCDECL PSINGLE_LIST_ENTRY SpliceHeadList(IN OUT PSINGLE_LIST_HEADER ListHead,
|
|
||||||
IN OUT PSINGLE_LIST_HEADER SpliceList);
|
|
||||||
STATIC XTCDECL PSINGLE_LIST_ENTRY SpliceTailList(IN OUT PSINGLE_LIST_HEADER ListHead,
|
|
||||||
IN OUT PSINGLE_LIST_HEADER SpliceList);
|
|
||||||
STATIC XTCDECL PSINGLE_LIST_ENTRY TakeFirstEntry(IN PSINGLE_LIST_HEADER ListHead);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* __XTOSKRNL_RTL_SLIST_HH */
|
|
||||||
@@ -86,10 +86,6 @@ KE::KernelInit::StartKernel(VOID)
|
|||||||
/* Save processor state */
|
/* Save processor state */
|
||||||
Processor::SaveProcessorState(&Prcb->ProcessorState);
|
Processor::SaveProcessorState(&Prcb->ProcessorState);
|
||||||
|
|
||||||
/* Initialize spin locks */
|
|
||||||
SpinLock::InitializeAllLocks();
|
|
||||||
SpinLock::InitializeLockQueues();
|
|
||||||
|
|
||||||
/* Lower to APC runlevel */
|
/* Lower to APC runlevel */
|
||||||
RunLevel::LowerRunLevel(APC_LEVEL);
|
RunLevel::LowerRunLevel(APC_LEVEL);
|
||||||
|
|
||||||
@@ -112,9 +108,6 @@ KE::KernelInit::StartKernel(VOID)
|
|||||||
CurrentThread->WaitRunLevel = DISPATCH_LEVEL;
|
CurrentThread->WaitRunLevel = DISPATCH_LEVEL;
|
||||||
CurrentProcess->ActiveProcessors |= (ULONG_PTR)1 << Prcb->CpuNumber;
|
CurrentProcess->ActiveProcessors |= (ULONG_PTR)1 << Prcb->CpuNumber;
|
||||||
|
|
||||||
/* Initialize Memory Manager */
|
|
||||||
MM::Manager::InitializeMemoryManager();
|
|
||||||
|
|
||||||
/* Enter infinite loop */
|
/* Enter infinite loop */
|
||||||
DebugPrint(L"KernelInit::StartKernel() finished. Entering infinite loop.\n");
|
DebugPrint(L"KernelInit::StartKernel() finished. Entering infinite loop.\n");
|
||||||
Crash::HaltSystem();
|
Crash::HaltSystem();
|
||||||
|
|||||||
@@ -12,6 +12,12 @@
|
|||||||
/* Kernel initialization block passed by boot loader */
|
/* Kernel initialization block passed by boot loader */
|
||||||
PKERNEL_INITIALIZATION_BLOCK KE::BootInformation::InitializationBlock = {};
|
PKERNEL_INITIALIZATION_BLOCK KE::BootInformation::InitializationBlock = {};
|
||||||
|
|
||||||
|
/* Kernel boot resources list */
|
||||||
|
LIST_ENTRY KE::SystemResources::ResourcesListHead;
|
||||||
|
|
||||||
|
/* Kernel boot resources lock */
|
||||||
|
KSPIN_LOCK KE::SystemResources::ResourcesLock;
|
||||||
|
|
||||||
/* Kernel initial process */
|
/* Kernel initial process */
|
||||||
EPROCESS KE::KProcess::InitialProcess;
|
EPROCESS KE::KProcess::InitialProcess;
|
||||||
|
|
||||||
@@ -20,54 +26,3 @@ ETHREAD KE::KThread::InitialThread = {};
|
|||||||
|
|
||||||
/* Kernel UBSAN active frame flag */
|
/* Kernel UBSAN active frame flag */
|
||||||
BOOLEAN KE::KUbsan::ActiveFrame = FALSE;
|
BOOLEAN KE::KUbsan::ActiveFrame = FALSE;
|
||||||
|
|
||||||
/* Kernel dispatcher lock queue */
|
|
||||||
KSPIN_LOCK KE::SpinLock::DispatcherLockQueue;
|
|
||||||
|
|
||||||
/* Kernel expansion lock queue */
|
|
||||||
KSPIN_LOCK KE::SpinLock::ExpansionLockQueue;
|
|
||||||
|
|
||||||
/* Kernel file system structures lock queue */
|
|
||||||
KSPIN_LOCK KE::SpinLock::FileSystemLockQueue;
|
|
||||||
|
|
||||||
/* Kernel IO cancel lock queue */
|
|
||||||
KSPIN_LOCK KE::SpinLock::IoCancelLockQueue;
|
|
||||||
|
|
||||||
/* Kernel IO completion lock queue */
|
|
||||||
KSPIN_LOCK KE::SpinLock::IoCompletionLockQueue;
|
|
||||||
|
|
||||||
/* Kernel IO database lock queue */
|
|
||||||
KSPIN_LOCK KE::SpinLock::IoDatabaseLockQueue;
|
|
||||||
|
|
||||||
/* Kernel IO VPB lock queue */
|
|
||||||
KSPIN_LOCK KE::SpinLock::IoVpbLockQueue;
|
|
||||||
|
|
||||||
/* Kernel cache master lock queue */
|
|
||||||
KSPIN_LOCK KE::SpinLock::MasterLockQueue;
|
|
||||||
|
|
||||||
/* Kernel non-paged allocator lock queue */
|
|
||||||
KSPIN_LOCK KE::SpinLock::NonPagedAllocLockQueue;
|
|
||||||
|
|
||||||
/* Kernel non-paged pool lock queue */
|
|
||||||
KSPIN_LOCK KE::SpinLock::NonPagedPoolLockQueue;
|
|
||||||
|
|
||||||
/* Kernel PFN lock queue */
|
|
||||||
KSPIN_LOCK KE::SpinLock::PfnLockQueue;
|
|
||||||
|
|
||||||
/* Kernel system space lock queue */
|
|
||||||
KSPIN_LOCK KE::SpinLock::SystemSpaceLockQueue;
|
|
||||||
|
|
||||||
/* Kernel Timer table lock queue */
|
|
||||||
KSPIN_LOCK KE::SpinLock::TimerTableLockQueue;
|
|
||||||
|
|
||||||
/* Kernel VACB lock queue */
|
|
||||||
KSPIN_LOCK KE::SpinLock::VacbLockQueue;
|
|
||||||
|
|
||||||
/* Kernel work queue lock queue */
|
|
||||||
KSPIN_LOCK KE::SpinLock::WorkLockQueue;
|
|
||||||
|
|
||||||
/* Kernel boot resources list */
|
|
||||||
LIST_ENTRY KE::SystemResources::ResourcesListHead;
|
|
||||||
|
|
||||||
/* Kernel boot resources lock */
|
|
||||||
KSPIN_LOCK KE::SystemResources::ResourcesLock;
|
|
||||||
|
|||||||
@@ -86,10 +86,6 @@ KE::KernelInit::StartKernel(VOID)
|
|||||||
/* Save processor state */
|
/* Save processor state */
|
||||||
Processor::SaveProcessorState(&Prcb->ProcessorState);
|
Processor::SaveProcessorState(&Prcb->ProcessorState);
|
||||||
|
|
||||||
/* Initialize spin locks */
|
|
||||||
SpinLock::InitializeAllLocks();
|
|
||||||
SpinLock::InitializeLockQueues();
|
|
||||||
|
|
||||||
/* Lower to APC runlevel */
|
/* Lower to APC runlevel */
|
||||||
RunLevel::LowerRunLevel(APC_LEVEL);
|
RunLevel::LowerRunLevel(APC_LEVEL);
|
||||||
|
|
||||||
@@ -112,9 +108,6 @@ KE::KernelInit::StartKernel(VOID)
|
|||||||
CurrentThread->WaitRunLevel = DISPATCH_LEVEL;
|
CurrentThread->WaitRunLevel = DISPATCH_LEVEL;
|
||||||
CurrentProcess->ActiveProcessors |= (ULONG_PTR)1 << Prcb->CpuNumber;
|
CurrentProcess->ActiveProcessors |= (ULONG_PTR)1 << Prcb->CpuNumber;
|
||||||
|
|
||||||
/* Initialize Memory Manager */
|
|
||||||
MM::Manager::InitializeMemoryManager();
|
|
||||||
|
|
||||||
/* Enter infinite loop */
|
/* Enter infinite loop */
|
||||||
DebugPrint(L"KernelInit::StartKernel() finished. Entering infinite loop.\n");
|
DebugPrint(L"KernelInit::StartKernel() finished. Entering infinite loop.\n");
|
||||||
Crash::HaltSystem();
|
Crash::HaltSystem();
|
||||||
|
|||||||
@@ -152,7 +152,7 @@ KE::KThread::InitializeThread(IN PKPROCESS Process,
|
|||||||
if(!Stack)
|
if(!Stack)
|
||||||
{
|
{
|
||||||
/* Allocate new stack */
|
/* Allocate new stack */
|
||||||
Status = MM::KernelPool::AllocateKernelStack(&Stack, KERNEL_STACK_SIZE);
|
Status = MM::KernelPool::AllocateKernelStack(&Stack, FALSE, 0);
|
||||||
if(Status != STATUS_SUCCESS || !Stack)
|
if(Status != STATUS_SUCCESS || !Stack)
|
||||||
{
|
{
|
||||||
/* Stack allocation failed */
|
/* Stack allocation failed */
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
* FILE: xtoskrnl/ke/spinlock.cc
|
* FILE: xtoskrnl/ke/spinlock.cc
|
||||||
* DESCRIPTION: Spinlocks support
|
* DESCRIPTION: Spinlocks support
|
||||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||||
* Aiken Harris <harraiken91@gmail.com>
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <xtos.hh>
|
#include <xtos.hh>
|
||||||
@@ -57,78 +56,6 @@ KE::SpinLock::AcquireSpinLock(IN OUT PKSPIN_LOCK SpinLock)
|
|||||||
AR::CpuFunc::ReadWriteBarrier();
|
AR::CpuFunc::ReadWriteBarrier();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Initializes all kernel spinlocks.
|
|
||||||
*
|
|
||||||
* @return This routine does not return any value.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
VOID
|
|
||||||
KE::SpinLock::InitializeAllLocks()
|
|
||||||
{
|
|
||||||
/* Initialize all spin locks */
|
|
||||||
InitializeSpinLock(&DispatcherLockQueue);
|
|
||||||
InitializeSpinLock(&PfnLockQueue);
|
|
||||||
InitializeSpinLock(&SystemSpaceLockQueue);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initializes spinlock queues for current processor.
|
|
||||||
*
|
|
||||||
* @return This routine does not return any value.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
VOID
|
|
||||||
KE::SpinLock::InitializeLockQueues()
|
|
||||||
{
|
|
||||||
PKPROCESSOR_CONTROL_BLOCK ControlBlock;
|
|
||||||
|
|
||||||
/* Get current processor control block */
|
|
||||||
ControlBlock = KE::Processor::GetCurrentProcessorControlBlock();
|
|
||||||
|
|
||||||
/* Initialize PCB lock queues */
|
|
||||||
ControlBlock->LockQueue[DispatcherLock].Lock = &DispatcherLockQueue;
|
|
||||||
ControlBlock->LockQueue[DispatcherLock].Next = NULLPTR;
|
|
||||||
ControlBlock->LockQueue[ExpansionLock].Lock = &ExpansionLockQueue;
|
|
||||||
ControlBlock->LockQueue[ExpansionLock].Next = NULLPTR;
|
|
||||||
ControlBlock->LockQueue[PfnLock].Lock = &PfnLockQueue;
|
|
||||||
ControlBlock->LockQueue[PfnLock].Next = NULLPTR;
|
|
||||||
ControlBlock->LockQueue[SystemSpaceLock].Lock = &SystemSpaceLockQueue;
|
|
||||||
ControlBlock->LockQueue[SystemSpaceLock].Next = NULLPTR;
|
|
||||||
ControlBlock->LockQueue[VacbLock].Lock = &VacbLockQueue;
|
|
||||||
ControlBlock->LockQueue[VacbLock].Next = NULLPTR;
|
|
||||||
ControlBlock->LockQueue[MasterLock].Lock = &MasterLockQueue;
|
|
||||||
ControlBlock->LockQueue[MasterLock].Next = NULLPTR;
|
|
||||||
ControlBlock->LockQueue[NonPagedAllocPoolLock].Lock = &NonPagedAllocLockQueue;
|
|
||||||
ControlBlock->LockQueue[NonPagedAllocPoolLock].Next = NULLPTR;
|
|
||||||
ControlBlock->LockQueue[IoCancelLock].Lock = &IoCancelLockQueue;
|
|
||||||
ControlBlock->LockQueue[IoCancelLock].Next = NULLPTR;
|
|
||||||
ControlBlock->LockQueue[WorkQueueLock].Lock = &WorkLockQueue;
|
|
||||||
ControlBlock->LockQueue[WorkQueueLock].Next = NULLPTR;
|
|
||||||
ControlBlock->LockQueue[IoVpbLock].Lock = &IoVpbLockQueue;
|
|
||||||
ControlBlock->LockQueue[IoVpbLock].Next = NULLPTR;
|
|
||||||
ControlBlock->LockQueue[IoDatabaseLock].Lock = &IoDatabaseLockQueue;
|
|
||||||
ControlBlock->LockQueue[IoDatabaseLock].Next = NULLPTR;
|
|
||||||
ControlBlock->LockQueue[IoCompletionLock].Lock = &IoCompletionLockQueue;
|
|
||||||
ControlBlock->LockQueue[IoCompletionLock].Next = NULLPTR;
|
|
||||||
ControlBlock->LockQueue[FileSystemLock].Lock = &FileSystemLockQueue;
|
|
||||||
ControlBlock->LockQueue[FileSystemLock].Next = NULLPTR;
|
|
||||||
ControlBlock->LockQueue[AfdWorkQueueLock].Lock = NULLPTR;
|
|
||||||
ControlBlock->LockQueue[AfdWorkQueueLock].Next = NULLPTR;
|
|
||||||
ControlBlock->LockQueue[BcbLock].Lock = NULLPTR;
|
|
||||||
ControlBlock->LockQueue[BcbLock].Next = NULLPTR;
|
|
||||||
ControlBlock->LockQueue[NonPagedPoolLock].Lock = &NonPagedPoolLockQueue;
|
|
||||||
ControlBlock->LockQueue[NonPagedPoolLock].Next = NULLPTR;
|
|
||||||
ControlBlock->LockQueue[ReservedSystemLock].Lock = NULLPTR;
|
|
||||||
ControlBlock->LockQueue[ReservedSystemLock].Next = NULLPTR;
|
|
||||||
ControlBlock->LockQueue[TimerTableLock].Lock = &TimerTableLockQueue;
|
|
||||||
ControlBlock->LockQueue[TimerTableLock].Next = NULLPTR;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes a kernel spinlock object.
|
* Initializes a kernel spinlock object.
|
||||||
*
|
*
|
||||||
@@ -185,29 +112,3 @@ KE::SpinLock::ReleaseSpinLock(IN OUT PKSPIN_LOCK SpinLock)
|
|||||||
/* Add an explicit memory barrier */
|
/* Add an explicit memory barrier */
|
||||||
AR::CpuFunc::ReadWriteBarrier();
|
AR::CpuFunc::ReadWriteBarrier();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Tests a kernel spin lock.
|
|
||||||
*
|
|
||||||
* @param SpinLock
|
|
||||||
* Supplies a pointer to the kernel spin lock.
|
|
||||||
*
|
|
||||||
* @return This routine returns TRUE if the lock is free, FALSE otherwise.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTFASTCALL
|
|
||||||
BOOLEAN
|
|
||||||
TestSpinLock(IN PKSPIN_LOCK SpinLock)
|
|
||||||
{
|
|
||||||
/* Check if the lock is free */
|
|
||||||
if(*SpinLock)
|
|
||||||
{
|
|
||||||
/* Spinlock is busy, yield processor and return FALSE */
|
|
||||||
AR::CpuFunc::YieldProcessor();
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Spinlock is free, return TRUE */
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,313 +0,0 @@
|
|||||||
/**
|
|
||||||
* PROJECT: ExectOS
|
|
||||||
* COPYRIGHT: See COPYING.md in the top level directory
|
|
||||||
* FILE: xtoskrnl/mm/alloc.cc
|
|
||||||
* DESCRIPTION: Memory manager pool allocation
|
|
||||||
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <xtos.hh>
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Allocates pages from the non-paged pool.
|
|
||||||
*
|
|
||||||
* @param Pages
|
|
||||||
* Specifies the number of pages to allocate.
|
|
||||||
*
|
|
||||||
* @param Memory
|
|
||||||
* Supplies a pointer to the allocated pool.
|
|
||||||
*
|
|
||||||
* @return This routine returns a status code.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
XTSTATUS
|
|
||||||
MM::Allocator::AllocateNonPagedPoolPages(IN PFN_COUNT Pages,
|
|
||||||
OUT PVOID *Memory)
|
|
||||||
{
|
|
||||||
PLIST_ENTRY Entry, LastHead, ListHead;
|
|
||||||
PMMPTE PointerPte, ValidPte;
|
|
||||||
PMMFREE_POOL_ENTRY FreePage;
|
|
||||||
PFN_NUMBER PageFrameNumber;
|
|
||||||
PVOID BaseAddress;
|
|
||||||
ULONG Index;
|
|
||||||
PMMPFN Pfn;
|
|
||||||
|
|
||||||
/* Calculate the free list index based on the requested page count, capped at the maximum list head index */
|
|
||||||
Index = MIN(Pages, MM_MAX_FREE_PAGE_LIST_HEADS) - 1;
|
|
||||||
|
|
||||||
/* Set the starting list head and the boundary for the search loop */
|
|
||||||
ListHead = &NonPagedPoolFreeList[Index];
|
|
||||||
LastHead = &NonPagedPoolFreeList[MM_MAX_FREE_PAGE_LIST_HEADS];
|
|
||||||
|
|
||||||
/* Start a guarded code block */
|
|
||||||
{
|
|
||||||
/* Acquire the Non-Paged pool lock and raise runlevel to DISPATCH_LEVEL */
|
|
||||||
KE::RaiseRunLevel RunLevel(DISPATCH_LEVEL);
|
|
||||||
KE::QueuedSpinLockGuard NonPagedPoolSpinLock(NonPagedPoolLock);
|
|
||||||
|
|
||||||
/* Iterate through the free lists */
|
|
||||||
do
|
|
||||||
{
|
|
||||||
/* Iterate through the free entries in the current list */
|
|
||||||
Entry = ListHead->Flink;
|
|
||||||
while(Entry != ListHead)
|
|
||||||
{
|
|
||||||
/* Get the free pool entry structure from the list entry */
|
|
||||||
FreePage = CONTAIN_RECORD(Entry, MMFREE_POOL_ENTRY, List);
|
|
||||||
|
|
||||||
/* Check if this block is large enough to satisfy the request */
|
|
||||||
if(FreePage->Size >= Pages)
|
|
||||||
{
|
|
||||||
/* Adjust the size of the free block to account for the allocated pages */
|
|
||||||
FreePage->Size -= Pages;
|
|
||||||
|
|
||||||
/* Calculate the base address of the allocated block */
|
|
||||||
BaseAddress = (PVOID)((ULONG_PTR)FreePage + (FreePage->Size << MM_PAGE_SHIFT));
|
|
||||||
|
|
||||||
/* Remove the entry from the free list */
|
|
||||||
RTL::LinkedList::RemoveEntryList(&FreePage->List);
|
|
||||||
|
|
||||||
/* Check if there is remaining space in the entry */
|
|
||||||
if(FreePage->Size != 0)
|
|
||||||
{
|
|
||||||
/* Calculate the new list index for the remaining fragment */
|
|
||||||
Index = MIN(FreePage->Size, MM_MAX_FREE_PAGE_LIST_HEADS) - 1;
|
|
||||||
|
|
||||||
/* Insert the entry into the free list */
|
|
||||||
RTL::LinkedList::InsertTailList(&NonPagedPoolFreeList[Index], &FreePage->List);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get the Page Table Entry (PTE) for the allocated address */
|
|
||||||
PointerPte = MM::Paging::GetPteAddress(BaseAddress);
|
|
||||||
|
|
||||||
/* Get the Page Frame Number (PFN) database entry for the corresponding physical page */
|
|
||||||
Pfn = MM::Pfn::GetPfnEntry(MM::Paging::GetPageFrameNumber(PointerPte));
|
|
||||||
|
|
||||||
/* Denote allocation boundaries */
|
|
||||||
Pfn->u3.e1.ReadInProgress = 1;
|
|
||||||
|
|
||||||
/* Check if multiple pages were requested */
|
|
||||||
if(Pages != 1)
|
|
||||||
{
|
|
||||||
/* Advance to the PTE of the last page in the allocation */
|
|
||||||
PointerPte = MM::Paging::AdvancePte(PointerPte, Pages - 1);
|
|
||||||
|
|
||||||
/* Get the PFN entry for the last page */
|
|
||||||
Pfn = MM::Pfn::GetPfnEntry(MM::Paging::GetPageFrameNumber(PointerPte));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Denote allocation boundaries */
|
|
||||||
Pfn->u3.e1.WriteInProgress = 1;
|
|
||||||
|
|
||||||
/* Set the allocated memory address and return success */
|
|
||||||
*Memory = BaseAddress;
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Move to the next entry in the free list */
|
|
||||||
Entry = FreePage->List.Flink;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
while(++ListHead < LastHead);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* No suitable free block found; try to expand the pool by reserving system PTEs */
|
|
||||||
PointerPte = MM::Pte::ReserveSystemPtes(Pages, NonPagedPoolExpansion);
|
|
||||||
if(PointerPte == NULLPTR)
|
|
||||||
{
|
|
||||||
/* PTE reservation failed, return insufficient resources */
|
|
||||||
return STATUS_INSUFFICIENT_RESOURCES;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Acquire the Non-Paged pool lock and raise runlevel to DISPATCH_LEVEL */
|
|
||||||
KE::RaiseRunLevel RunLevel(DISPATCH_LEVEL);
|
|
||||||
KE::QueuedSpinLockGuard NonPagedPoolSpinLock(NonPagedPoolLock);
|
|
||||||
|
|
||||||
/* Acquire the PFN database lock */
|
|
||||||
KE::QueuedSpinLockGuard PfnSpinLock(PfnLock);
|
|
||||||
|
|
||||||
/* Check if there are enough available physical pages to back the allocation */
|
|
||||||
if(Pages >= MM::Pfn::GetAvailablePages())
|
|
||||||
{
|
|
||||||
/* Not enough physical pages, release the reserved system PTEs */
|
|
||||||
MM::Pte::ReleaseSystemPtes(PointerPte, Pages, NonPagedPoolExpansion);
|
|
||||||
|
|
||||||
/* Return failure due to insufficient resources */
|
|
||||||
return STATUS_INSUFFICIENT_RESOURCES;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get a template valid PTE and loop through the allocation to map physical pages */
|
|
||||||
ValidPte = MM::Pte::GetValidPte();
|
|
||||||
do
|
|
||||||
{
|
|
||||||
/* Allocate a physical page */
|
|
||||||
PageFrameNumber = MM::Pfn::AllocatePhysicalPage(MM::Colors::GetNextColor());
|
|
||||||
|
|
||||||
/* Initialize the PFN entry for the allocated physical page */
|
|
||||||
Pfn = MM::Pfn::GetPfnEntry(PageFrameNumber);
|
|
||||||
Pfn->PteAddress = PointerPte;
|
|
||||||
Pfn->u2.ShareCount = 1;
|
|
||||||
Pfn->u3.e1.PageLocation = ActiveAndValid;
|
|
||||||
Pfn->u3.e2.ReferenceCount = 1;
|
|
||||||
Pfn->u4.VerifierAllocation = 0;
|
|
||||||
|
|
||||||
/* Build a valid PTE pointing to the allocated page frame */
|
|
||||||
MM::Paging::SetPte(ValidPte, PageFrameNumber, 0);
|
|
||||||
|
|
||||||
/* Write the valid PTE into the system PTE range */
|
|
||||||
*(MM::Paging::GetNextPte(PointerPte)) = *ValidPte;
|
|
||||||
}
|
|
||||||
while(--Pages > 0);
|
|
||||||
|
|
||||||
/* Dnote allocation boundaries */
|
|
||||||
Pfn->u3.e1.WriteInProgress = 1;
|
|
||||||
|
|
||||||
/* Get the PFN entry for the first page of the allocation */
|
|
||||||
Pfn = MM::Pfn::GetPfnEntry(MM::Paging::GetPageFrameNumber(PointerPte));
|
|
||||||
|
|
||||||
/* Denote allocation boundaries */
|
|
||||||
Pfn->u3.e1.ReadInProgress = 1;
|
|
||||||
|
|
||||||
/* Convert the PTE address to the virtual address and store in the buffer */
|
|
||||||
*Memory = MM::Paging::GetPteVirtualAddress(PointerPte);
|
|
||||||
|
|
||||||
/* Return success */
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Allocates pages from the paged pool.
|
|
||||||
*
|
|
||||||
* @param Pages
|
|
||||||
* Specifies the number of pages to allocate.
|
|
||||||
*
|
|
||||||
* @param Memory
|
|
||||||
* Supplies a pointer to the allocated pool.
|
|
||||||
*
|
|
||||||
* @return This routine returns a status code.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
XTSTATUS
|
|
||||||
MM::Allocator::AllocatePagedPoolPages(IN PFN_COUNT Pages,
|
|
||||||
OUT PVOID *Memory)
|
|
||||||
{
|
|
||||||
UNIMPLEMENTED;
|
|
||||||
|
|
||||||
/* Return not implemented status code */
|
|
||||||
return STATUS_NOT_IMPLEMENTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Allocates pages from the specified pool type.
|
|
||||||
*
|
|
||||||
* @param PoolType
|
|
||||||
* Specifies the type of pool to allocate pages from.
|
|
||||||
*
|
|
||||||
* @param Bytes
|
|
||||||
* Specifies the number of bytes to allocate.
|
|
||||||
*
|
|
||||||
* @param Memory
|
|
||||||
* Supplies a pointer to the allocated pool.
|
|
||||||
*
|
|
||||||
* @return This routine returns a status code.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
XTSTATUS
|
|
||||||
MM::Allocator::AllocatePages(IN MMPOOL_TYPE PoolType,
|
|
||||||
IN SIZE_T Bytes,
|
|
||||||
OUT PVOID *Memory)
|
|
||||||
{
|
|
||||||
PFN_COUNT Pages;
|
|
||||||
|
|
||||||
/* Initialize the output parameter */
|
|
||||||
*Memory = NULLPTR;
|
|
||||||
|
|
||||||
/* Convert bytes to pages */
|
|
||||||
Pages = SIZE_TO_PAGES(Bytes);
|
|
||||||
|
|
||||||
/* Check if there are any pages to allocate */
|
|
||||||
if(!Pages)
|
|
||||||
{
|
|
||||||
/* Nothing to allocate, return NULLPTR */
|
|
||||||
return STATUS_INVALID_PARAMETER;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Switch on pool type */
|
|
||||||
switch(PoolType & MM_POOL_TYPE_MASK)
|
|
||||||
{
|
|
||||||
case NonPagedPool:
|
|
||||||
/* Allocate non-paged pool */
|
|
||||||
return AllocateNonPagedPoolPages(Pages, Memory);
|
|
||||||
case PagedPool:
|
|
||||||
/* Allocate paged pool */
|
|
||||||
return AllocatePagedPoolPages(Pages, Memory);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Invalid pool type specified, return error */
|
|
||||||
return STATUS_INVALID_PARAMETER;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initializes the non-paged pool for memory allocator.
|
|
||||||
*
|
|
||||||
* @return This routine does not return any value.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
VOID
|
|
||||||
MM::Allocator::InitializeNonPagedPool(VOID)
|
|
||||||
{
|
|
||||||
PMMMEMORY_LAYOUT MemoryLayout;
|
|
||||||
PMMFREE_POOL_ENTRY FreeEntry;
|
|
||||||
ULONG Index;
|
|
||||||
|
|
||||||
/* Retrieve memory layout */
|
|
||||||
MemoryLayout = MM::Manager::GetMemoryLayout();
|
|
||||||
|
|
||||||
/* Map PTEs for the non-paged pool */
|
|
||||||
MapNonPagedPool();
|
|
||||||
|
|
||||||
/* Iterate over the free page list heads */
|
|
||||||
for(Index = 0; Index < MM_MAX_FREE_PAGE_LIST_HEADS; Index++)
|
|
||||||
{
|
|
||||||
/* Initialize a free page list head */
|
|
||||||
RTL::LinkedList::InitializeListHead(&NonPagedPoolFreeList[Index]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Take the first free page from the pool */
|
|
||||||
FreeEntry = (PMMFREE_POOL_ENTRY)MemoryLayout->NonPagedPoolStart;
|
|
||||||
|
|
||||||
/* Take number of pages in the pool */
|
|
||||||
Index = (ULONG)(MemoryLayout->NonPagedPoolSize - 1);
|
|
||||||
if(Index >= MM_MAX_FREE_PAGE_LIST_HEADS)
|
|
||||||
{
|
|
||||||
/* Number of pages exceeds the number of free page list heads */
|
|
||||||
Index = MM_MAX_FREE_PAGE_LIST_HEADS - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Insert the first free page into the free page list and set its size */
|
|
||||||
RTL::LinkedList::InsertHeadList(&NonPagedPoolFreeList[Index], &FreeEntry->List);
|
|
||||||
FreeEntry->Size = MemoryLayout->NonPagedPoolSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initializes the non-paged pool for memory allocator.
|
|
||||||
*
|
|
||||||
* @return This routine does not return any value.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
VOID
|
|
||||||
MM::Allocator::InitializePagedPool(VOID)
|
|
||||||
{
|
|
||||||
UNIMPLEMENTED;
|
|
||||||
}
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
/**
|
|
||||||
* PROJECT: ExectOS
|
|
||||||
* COPYRIGHT: See COPYING.md in the top level directory
|
|
||||||
* FILE: xtoskrnl/mm/amd64/alloc.cc
|
|
||||||
* DESCRIPTION: Memory manager pool allocation
|
|
||||||
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <xtos.hh>
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Maps the PTE for the base of the non-paged pool.
|
|
||||||
*
|
|
||||||
* @return This routine does not return any value.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
VOID
|
|
||||||
MM::Allocator::MapNonPagedPool(VOID)
|
|
||||||
{
|
|
||||||
PMMMEMORY_LAYOUT MemoryLayout;
|
|
||||||
|
|
||||||
/* Retrieve memory layout */
|
|
||||||
MemoryLayout = MM::Manager::GetMemoryLayout();
|
|
||||||
|
|
||||||
/* Map PPE and PDE for whole non-paged pool */
|
|
||||||
MM::Pte::MapPPE(MemoryLayout->NonPagedPoolStart, MemoryLayout->NonPagedExpansionPoolEnd, MM::Pte::GetValidPte());
|
|
||||||
MM::Pte::MapPDE(MemoryLayout->NonPagedPoolStart, MemoryLayout->NonPagedExpansionPoolEnd, MM::Pte::GetValidPte());
|
|
||||||
|
|
||||||
/* Map PTE only for the base of the non-paged pool */
|
|
||||||
MM::Pte::MapPTE(MemoryLayout->NonPagedPoolStart, (PCHAR)MemoryLayout->NonPagedPoolEnd - 1, MM::Pte::GetValidPte());
|
|
||||||
}
|
|
||||||
25
xtoskrnl/mm/amd64/init.cc
Normal file
25
xtoskrnl/mm/amd64/init.cc
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
/**
|
||||||
|
* PROJECT: ExectOS
|
||||||
|
* COPYRIGHT: See COPYING.md in the top level directory
|
||||||
|
* FILE: xtoskrnl/mm/amd64/init.cc
|
||||||
|
* DESCRIPTION: Architecture specific Memory Manager initialization routines
|
||||||
|
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||||
|
* Aiken Harris <harraiken91@gmail.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <xtos.hh>
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Performs architecture specific initialization of the XTOS Memory Manager.
|
||||||
|
*
|
||||||
|
* @return This routine does not return any value.
|
||||||
|
*
|
||||||
|
* @since XT 1.0
|
||||||
|
*/
|
||||||
|
XTAPI
|
||||||
|
VOID
|
||||||
|
MM::Init::InitializeArchitecture(VOID)
|
||||||
|
{
|
||||||
|
UNIMPLEMENTED;
|
||||||
|
}
|
||||||
@@ -1,390 +0,0 @@
|
|||||||
/**
|
|
||||||
* PROJECT: ExectOS
|
|
||||||
* COPYRIGHT: See COPYING.md in the top level directory
|
|
||||||
* FILE: xtoskrnl/mm/amd64/mmgr.cc
|
|
||||||
* DESCRIPTION: Memory Manager
|
|
||||||
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <xtos.hh>
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Calculates the maximum possible size of the non-paged pool.
|
|
||||||
*
|
|
||||||
* @param PoolSize
|
|
||||||
* A pointer to a variable that will receive the number of pages available for the non-paged pool.
|
|
||||||
*
|
|
||||||
* @return This routine does not return any value.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
VOID
|
|
||||||
MM::Manager::ComputeMaximumNonPagedPoolSize(OUT PPFN_NUMBER PoolSize)
|
|
||||||
{
|
|
||||||
ULONG_PTR MaximumNonPagedPoolSize;
|
|
||||||
|
|
||||||
/* Start with the 1MiB and add 400KiB for each MiB above 16MiB */
|
|
||||||
MaximumNonPagedPoolSize = 1048576 + (((MM::Pfn::GetNumberOfPhysicalPages() - 4096) / 256) * 409600);
|
|
||||||
|
|
||||||
/* Check if non-paged pool does not exceed 128GiB */
|
|
||||||
if(MaximumNonPagedPoolSize > 137438953472)
|
|
||||||
{
|
|
||||||
/* Limit non-paged pool size to 128GiB */
|
|
||||||
MaximumNonPagedPoolSize = 137438953472;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Return non-paged pool size */
|
|
||||||
*PoolSize = SIZE_TO_PAGES(MaximumNonPagedPoolSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Calculates the size of the non-paged pool.
|
|
||||||
*
|
|
||||||
* @param PoolSize
|
|
||||||
* A pointer to a variable that will receive the number of pages available for the non-paged pool.
|
|
||||||
*
|
|
||||||
* @return This routine does not return any value.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
VOID
|
|
||||||
MM::Manager::ComputeNonPagedPoolSize(OUT PPFN_NUMBER PoolSize)
|
|
||||||
{
|
|
||||||
ULONG_PTR NonPagedPoolSize;
|
|
||||||
|
|
||||||
/* Start with 1MiB and add 32KiB for each MiB above 16MiB */
|
|
||||||
NonPagedPoolSize = 1048576 + (((MM::Pfn::GetNumberOfPhysicalPages() - 4096) / 256) * 32768);
|
|
||||||
|
|
||||||
/* Check if non-paged pool does not exceed 128GiB */
|
|
||||||
if(NonPagedPoolSize > 137438953472)
|
|
||||||
{
|
|
||||||
/* Limit non-paged pool size to 128GiB */
|
|
||||||
NonPagedPoolSize = 137438953472;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Return non-paged pool size in pages, aligned up to page size boundary */
|
|
||||||
*PoolSize = SIZE_TO_PAGES(ROUND_UP(NonPagedPoolSize, MM_PAGE_SIZE));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Calculates the size of the paged pool.
|
|
||||||
*
|
|
||||||
* @param PoolSize
|
|
||||||
* A pointer to a variable that will receive the number of pages available for the paged pool.
|
|
||||||
*
|
|
||||||
* @return This routine does not return any value.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
VOID
|
|
||||||
MM::Manager::ComputePagedPoolSize(OUT PPFN_NUMBER PoolSize)
|
|
||||||
{
|
|
||||||
ULONGLONG PagedPoolSize, PteCount;
|
|
||||||
ULONG PtesPerPage;
|
|
||||||
|
|
||||||
/* Start with 4x maximum non-paged pool size and at least 48MiB */
|
|
||||||
ComputeMaximumNonPagedPoolSize(&PagedPoolSize);
|
|
||||||
PagedPoolSize *= 4 * MM_PAGE_SIZE;
|
|
||||||
|
|
||||||
/* Ensure that paged pool size is at least 48MiB */
|
|
||||||
if(PagedPoolSize < 50331648)
|
|
||||||
{
|
|
||||||
/* Increase paged pool size to at least 48MiB */
|
|
||||||
PagedPoolSize = 50331648;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check if paged pool does not overlap non-paged pool */
|
|
||||||
if(PagedPoolSize > (ULONGLONG)MemoryLayout.NonPagedSystemPoolStart - (ULONGLONG)MemoryLayout.PagedPoolStart)
|
|
||||||
{
|
|
||||||
/* Limit paged pool size to maximum possible */
|
|
||||||
PagedPoolSize = (ULONGLONG)MemoryLayout.NonPagedSystemPoolStart - (ULONGLONG)MemoryLayout.PagedPoolStart;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check if paged pool does not exceed 128GiB */
|
|
||||||
if(PagedPoolSize > 137438953472)
|
|
||||||
{
|
|
||||||
/* Limit paged pool size to 128GiB */
|
|
||||||
PagedPoolSize = 137438953472;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get the number of PTEs per page and calculate size of paged pool */
|
|
||||||
PtesPerPage = MM::Pte::GetPtesPerPage();
|
|
||||||
PteCount = ((SIZE_TO_PAGES(PagedPoolSize) + (PtesPerPage - 1)) / PtesPerPage);
|
|
||||||
|
|
||||||
/* Return paged pool size */
|
|
||||||
*PoolSize = PteCount * PtesPerPage;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Calculates the size of the session space.
|
|
||||||
*
|
|
||||||
* @param SpaceSize
|
|
||||||
* A pointer to a variable that will receive the number of pages available by the session space.
|
|
||||||
*
|
|
||||||
* @return This routine does not return any value.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
VOID
|
|
||||||
MM::Manager::ComputeSessionSpaceSize(OUT PPFN_NUMBER SpaceSize)
|
|
||||||
{
|
|
||||||
PFN_NUMBER SessionSpaceSize;
|
|
||||||
|
|
||||||
/* Session Pool, Session View, Session Image, Session Working Set and System View takes 1120MiB */
|
|
||||||
SessionSpaceSize = 1174405120;
|
|
||||||
|
|
||||||
/* Return number of pages used by the session space */
|
|
||||||
*SpaceSize = SessionSpaceSize / MM_PAGE_SIZE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Calculates the size of the system PTEs.
|
|
||||||
*
|
|
||||||
* @param PteSize
|
|
||||||
* A pointer to a variable that will receive the number of system PTEs.
|
|
||||||
*
|
|
||||||
* @return This routine does not return any value.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
VOID
|
|
||||||
MM::Manager::ComputeSystemPteSize(OUT PPFN_NUMBER PteSize)
|
|
||||||
{
|
|
||||||
PFN_NUMBER SystemPteSize;
|
|
||||||
|
|
||||||
/* Check if system has less than 24MiB of physical memory */
|
|
||||||
if(MM::Pfn::GetNumberOfPhysicalPages() < 6144)
|
|
||||||
{
|
|
||||||
/* Set minimal system PTE size */
|
|
||||||
SystemPteSize = 7000;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Use standard system PTE size */
|
|
||||||
SystemPteSize = 11000;
|
|
||||||
|
|
||||||
/* Check if system has more than 32MiB of physical memory */
|
|
||||||
if(MM::Pfn::GetNumberOfPhysicalPages() > 8192)
|
|
||||||
{
|
|
||||||
/* Double system PTE size */
|
|
||||||
SystemPteSize *= 2;
|
|
||||||
|
|
||||||
/* Check if system has more than 256MiB of physical memory */
|
|
||||||
if(MM::Pfn::GetNumberOfPhysicalPages() > 65536)
|
|
||||||
{
|
|
||||||
/* Double system PTE size */
|
|
||||||
SystemPteSize *= 2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Return system PTE size */
|
|
||||||
*PteSize = SystemPteSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Dumps the kernel's memory layout.
|
|
||||||
*
|
|
||||||
* @return This routine does not return any value.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
VOID
|
|
||||||
MM::Manager::DumpMemoryLayout(VOID)
|
|
||||||
{
|
|
||||||
/* Dump memory layout */
|
|
||||||
DebugPrint(L"System with %zu MiB of installed memory:\n"
|
|
||||||
L"User Space: %.16P - %.16P\n"
|
|
||||||
L"Non-Canonical: %.16P - %.16P\n"
|
|
||||||
L"Reserved System Pool: %.16P - %.16P\n"
|
|
||||||
L"PTE Space: %.16P - %.16P\n"
|
|
||||||
L"Hyper Space: %.16P - %.16P\n"
|
|
||||||
L"Shared System Page: %.16P - %.16P\n"
|
|
||||||
L"System Working Set: %.16P - %.16P\n"
|
|
||||||
L"Loader Mappings: %.16P - %.16P\n"
|
|
||||||
L"Non-Paged System Pool: %.16P - %.16P\n"
|
|
||||||
L"Paged Pool: %.16P - %.16P\n"
|
|
||||||
L"Session Space: %.16P - %.16P\n"
|
|
||||||
L"System Cache: %.16P - %.16P\n"
|
|
||||||
L"PFN Database: %.16P - %.16P\n"
|
|
||||||
L"Non-Paged Pool: %.16P - %.16P\n"
|
|
||||||
L"Non-Paged Expansion Pool: %.16P - %.16P\n"
|
|
||||||
L"Hardware Pool: %.16P - %.16P\n",
|
|
||||||
GetInstalledMemorySize(),
|
|
||||||
MemoryLayout.UserSpaceStart,
|
|
||||||
MemoryLayout.UserSpaceEnd,
|
|
||||||
MemoryLayout.NonCanonicalStart,
|
|
||||||
MemoryLayout.NonCanonicalEnd,
|
|
||||||
MemoryLayout.ReservedSystemPoolStart,
|
|
||||||
MemoryLayout.ReservedSystemPoolEnd,
|
|
||||||
MemoryLayout.PteSpaceStart,
|
|
||||||
MemoryLayout.PteSpaceEnd,
|
|
||||||
MemoryLayout.HyperSpaceStart,
|
|
||||||
MemoryLayout.HyperSpaceEnd,
|
|
||||||
MemoryLayout.SharedSystemPageStart,
|
|
||||||
MemoryLayout.SharedSystemPageEnd,
|
|
||||||
MemoryLayout.SystemWorkingSetStart,
|
|
||||||
MemoryLayout.SystemWorkingSetEnd,
|
|
||||||
MemoryLayout.LoaderMappingsStart,
|
|
||||||
MemoryLayout.LoaderMappingsEnd,
|
|
||||||
MemoryLayout.NonPagedSystemPoolStart,
|
|
||||||
MemoryLayout.NonPagedSystemPoolEnd,
|
|
||||||
MemoryLayout.PagedPoolStart,
|
|
||||||
MemoryLayout.PagedPoolEnd,
|
|
||||||
MemoryLayout.SessionSpaceStart,
|
|
||||||
MemoryLayout.SessionSpaceEnd,
|
|
||||||
MemoryLayout.SystemCacheStart,
|
|
||||||
MemoryLayout.SystemCacheEnd,
|
|
||||||
MemoryLayout.PfnDatabase,
|
|
||||||
(PVOID)((ULONG_PTR)MemoryLayout.PfnDatabase + (ULONG_PTR)MemoryLayout.PfnDatabaseSize * MM_PAGE_SIZE),
|
|
||||||
MemoryLayout.NonPagedPoolStart,
|
|
||||||
MemoryLayout.NonPagedPoolEnd,
|
|
||||||
MemoryLayout.NonPagedExpansionPoolStart,
|
|
||||||
MemoryLayout.NonPagedExpansionPoolEnd,
|
|
||||||
MemoryLayout.HardwarePoolStart,
|
|
||||||
MemoryLayout.HardwarePoolEnd);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initializes the kernel's virtual memory layout.
|
|
||||||
*
|
|
||||||
* @return This routine does not return any value.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
VOID
|
|
||||||
MM::Manager::InitializeMemoryLayout(VOID)
|
|
||||||
{
|
|
||||||
PFN_NUMBER MaximumNonPagedPoolSize;
|
|
||||||
ULONG_PTR PfnDatabaseEnd;
|
|
||||||
|
|
||||||
/* Check if 5-level paging (LA57) is enabled */
|
|
||||||
if(MM::Paging::GetXpaStatus())
|
|
||||||
{
|
|
||||||
/* Set PML5 base address */
|
|
||||||
MemoryLayout.SelfMapAddress = (PVOID)MM_P5E_LA57_BASE;
|
|
||||||
|
|
||||||
/* Define memory layout for 5-level paging */
|
|
||||||
MemoryLayout.UserSpaceStart = (PVOID)0x0000000000010000;
|
|
||||||
MemoryLayout.UserSpaceEnd = (PVOID)0x00FFFFFFFFFEFFFF;
|
|
||||||
MemoryLayout.NonCanonicalStart = (PVOID)0x0080000000000000;
|
|
||||||
MemoryLayout.NonCanonicalEnd = (PVOID)0xFEFFFFFFFFFFFFFF;
|
|
||||||
MemoryLayout.ReservedSystemPoolStart = (PVOID)0xFF00000000000000;
|
|
||||||
MemoryLayout.ReservedSystemPoolEnd = (PVOID)0xFFECFFFFFFFFFFFF;
|
|
||||||
MemoryLayout.PteSpaceStart = (PVOID)0xFFED000000000000;
|
|
||||||
MemoryLayout.PteSpaceEnd = (PVOID)0xFFEDFFFFFFFFFFFF;
|
|
||||||
MemoryLayout.HyperSpaceStart = (PVOID)0xFFFFF70000000000;
|
|
||||||
MemoryLayout.HyperSpaceEnd = (PVOID)0xFFFFF77FFFFFFFFF;
|
|
||||||
MemoryLayout.SharedSystemPageStart = (PVOID)0xFFFFF78000000000;
|
|
||||||
MemoryLayout.SharedSystemPageEnd = (PVOID)0xFFFFF78000000FFF;
|
|
||||||
MemoryLayout.SystemWorkingSetStart = (PVOID)0xFFFFF78000001000;
|
|
||||||
MemoryLayout.SystemWorkingSetEnd = (PVOID)0xFFFFF7FFFFFFFFFF;
|
|
||||||
MemoryLayout.LoaderMappingsStart = (PVOID)0xFFFFF80000000000;
|
|
||||||
MemoryLayout.LoaderMappingsEnd = (PVOID)0xFFFFF87FFFFFFFFF;
|
|
||||||
MemoryLayout.NonPagedSystemPoolStart = (PVOID)0xFFFFF88000000000;
|
|
||||||
MemoryLayout.NonPagedSystemPoolEnd = (PVOID)0xFFFFF89FFFFFFFFF;
|
|
||||||
MemoryLayout.PagedPoolStart = (PVOID)0xFFFFF8A000000000;
|
|
||||||
MemoryLayout.PagedPoolEnd = (PVOID)0xFFFFF8BFFFFFFFFF;
|
|
||||||
MemoryLayout.SessionSpaceStart = (PVOID)0xFFFFF90000000000;
|
|
||||||
MemoryLayout.SessionSpaceEnd = (PVOID)0xFFFFF98000000000;
|
|
||||||
MemoryLayout.SystemCacheStart = (PVOID)0xFFFFF98000000000;
|
|
||||||
MemoryLayout.SystemCacheEnd = (PVOID)0xFFFFFA7FFFFFFFFF;
|
|
||||||
MemoryLayout.NonPagedPoolStart = (PVOID)0xFFFFFA8000000000;
|
|
||||||
MemoryLayout.NonPagedPoolEnd = (PVOID)0xFFFFFFFFFFBFFFFF;
|
|
||||||
MemoryLayout.HardwarePoolStart = (PVOID)0xFFFFFFFFFFC00000;
|
|
||||||
MemoryLayout.HardwarePoolEnd = (PVOID)0xFFFFFFFFFFFFFFFF;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Set PML4 base address */
|
|
||||||
MemoryLayout.SelfMapAddress = (PVOID)MM_PXE_BASE;
|
|
||||||
|
|
||||||
/* Define memory layout for 4-level paging */
|
|
||||||
MemoryLayout.UserSpaceStart = (PVOID)0x0000000000010000;
|
|
||||||
MemoryLayout.UserSpaceEnd = (PVOID)0x000007FFFFFEFFFF;
|
|
||||||
MemoryLayout.NonCanonicalStart = (PVOID)0x0000800000000000;
|
|
||||||
MemoryLayout.NonCanonicalEnd = (PVOID)0xFFFF7FFFFFFFFFFF;
|
|
||||||
MemoryLayout.ReservedSystemPoolStart = (PVOID)0xFFFF800000000000;
|
|
||||||
MemoryLayout.ReservedSystemPoolEnd = (PVOID)0xFFFFF67FFFFFFFFF;
|
|
||||||
MemoryLayout.PteSpaceStart = (PVOID)0xFFFFF68000000000;
|
|
||||||
MemoryLayout.PteSpaceEnd = (PVOID)0xFFFFF6FFFFFFFFFF;
|
|
||||||
MemoryLayout.HyperSpaceStart = (PVOID)0xFFFFF70000000000;
|
|
||||||
MemoryLayout.HyperSpaceEnd = (PVOID)0xFFFFF77FFFFFFFFF;
|
|
||||||
MemoryLayout.SharedSystemPageStart = (PVOID)0xFFFFF78000000000;
|
|
||||||
MemoryLayout.SharedSystemPageEnd = (PVOID)0xFFFFF78000000FFF;
|
|
||||||
MemoryLayout.SystemWorkingSetStart = (PVOID)0xFFFFF78000001000;
|
|
||||||
MemoryLayout.SystemWorkingSetEnd = (PVOID)0xFFFFF7FFFFFFFFFF;
|
|
||||||
MemoryLayout.LoaderMappingsStart = (PVOID)0xFFFFF80000000000;
|
|
||||||
MemoryLayout.LoaderMappingsEnd = (PVOID)0xFFFFF87FFFFFFFFF;
|
|
||||||
MemoryLayout.NonPagedSystemPoolStart = (PVOID)0xFFFFF88000000000;
|
|
||||||
MemoryLayout.NonPagedSystemPoolEnd = (PVOID)0xFFFFF89FFFFFFFFF;
|
|
||||||
MemoryLayout.PagedPoolStart = (PVOID)0xFFFFF8A000000000;
|
|
||||||
MemoryLayout.PagedPoolEnd = (PVOID)0xFFFFF8BFFFFFFFFF;
|
|
||||||
MemoryLayout.SessionSpaceStart = (PVOID)0xFFFFF90000000000;
|
|
||||||
MemoryLayout.SessionSpaceEnd = (PVOID)0xFFFFF98000000000;
|
|
||||||
MemoryLayout.SystemCacheStart = (PVOID)0xFFFFF98000000000;
|
|
||||||
MemoryLayout.SystemCacheEnd = (PVOID)0xFFFFFA7FFFFFFFFF;
|
|
||||||
MemoryLayout.NonPagedPoolStart = (PVOID)0xFFFFFA8000000000;
|
|
||||||
MemoryLayout.NonPagedPoolEnd = (PVOID)0xFFFFFFFFFFBFFFFF;
|
|
||||||
MemoryLayout.HardwarePoolStart = (PVOID)0xFFFFFFFFFFC00000;
|
|
||||||
MemoryLayout.HardwarePoolEnd = (PVOID)0xFFFFFFFFFFFFFFFF;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Compute allocation size for the PFN database */
|
|
||||||
MM::Pfn::ComputePfnDatabaseSize(&MemoryLayout.PfnDatabaseSize);
|
|
||||||
|
|
||||||
/* Compute boot image size */
|
|
||||||
ComputeBootImageSize(&MemoryLayout.LoaderMappingsSize);
|
|
||||||
|
|
||||||
/* Compute session space size */
|
|
||||||
ComputeSessionSpaceSize(&MemoryLayout.SessionSpaceSize);
|
|
||||||
|
|
||||||
/* Update loader mappings space end address */
|
|
||||||
MemoryLayout.LoaderMappingsEnd = (PVOID)((ULONGLONG)MemoryLayout.LoaderMappingsStart +
|
|
||||||
MemoryLayout.LoaderMappingsSize * MM_PAGE_SIZE);
|
|
||||||
|
|
||||||
/* Update session space start address */
|
|
||||||
MemoryLayout.SessionSpaceStart = (PVOID)((ULONGLONG)MemoryLayout.SessionSpaceEnd -
|
|
||||||
MemoryLayout.SessionSpaceSize * MM_PAGE_SIZE);
|
|
||||||
|
|
||||||
/* Compute system PTE size */
|
|
||||||
ComputeSystemPteSize(&NumberOfSystemPtes);
|
|
||||||
|
|
||||||
/* Compute non-paged pool size */
|
|
||||||
ComputeNonPagedPoolSize(&MemoryLayout.NonPagedPoolSize);
|
|
||||||
ComputeMaximumNonPagedPoolSize(&MaximumNonPagedPoolSize);
|
|
||||||
|
|
||||||
/* Compute paged pool size */
|
|
||||||
ComputePagedPoolSize(&MemoryLayout.PagedPoolSize);
|
|
||||||
|
|
||||||
/* Insert the PFN database at the beginning of the non-paged pool */
|
|
||||||
MemoryLayout.PfnDatabase = (PMMPFN)MemoryLayout.NonPagedPoolStart;
|
|
||||||
|
|
||||||
/* Compute the PFN database page-aligned end address */
|
|
||||||
PfnDatabaseEnd = (ULONGLONG)MemoryLayout.PfnDatabase + (MemoryLayout.PfnDatabaseSize * MM_PAGE_SIZE);
|
|
||||||
PfnDatabaseEnd = ROUND_UP(PfnDatabaseEnd, MM_PAGE_SIZE);
|
|
||||||
|
|
||||||
/* Shrink the non-paged pool to fit the PFN database */
|
|
||||||
MemoryLayout.NonPagedPoolStart = (PVOID)PfnDatabaseEnd;
|
|
||||||
|
|
||||||
/* Assign the rest of the non-paged pool to the expansion pool */
|
|
||||||
MemoryLayout.NonPagedExpansionPoolStart = (PVOID)((ULONGLONG)MemoryLayout.NonPagedPoolStart +
|
|
||||||
MemoryLayout.NonPagedPoolSize * MM_PAGE_SIZE);
|
|
||||||
MemoryLayout.NonPagedPoolEnd = MemoryLayout.NonPagedExpansionPoolStart;
|
|
||||||
MemoryLayout.NonPagedExpansionPoolEnd = (PVOID)((ULONGLONG)MemoryLayout.NonPagedPoolStart +
|
|
||||||
MaximumNonPagedPoolSize * MM_PAGE_SIZE);
|
|
||||||
MemoryLayout.NonPagedExpansionPoolSize = ((ULONGLONG)MemoryLayout.NonPagedExpansionPoolEnd -
|
|
||||||
(ULONGLONG)MemoryLayout.NonPagedExpansionPoolStart) / MM_PAGE_SIZE;
|
|
||||||
|
|
||||||
/* Update paged pool end address */
|
|
||||||
MemoryLayout.PagedPoolEnd = (PVOID)(((ULONGLONG)MemoryLayout.PagedPoolStart +
|
|
||||||
MemoryLayout.PagedPoolSize * MM_PAGE_SIZE) - 1);
|
|
||||||
}
|
|
||||||
@@ -9,28 +9,6 @@
|
|||||||
#include <xtos.hh>
|
#include <xtos.hh>
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Advances a PTE pointer by a given number of entries, considering the actual PTE size.
|
|
||||||
*
|
|
||||||
* @param Pte
|
|
||||||
* The PTE pointer to advance.
|
|
||||||
*
|
|
||||||
* @param Count
|
|
||||||
* The number of PTE entries to advance by.
|
|
||||||
*
|
|
||||||
* @return The advanced PTE pointer.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
PMMPTE
|
|
||||||
MM::PageMap::AdvancePte(IN PMMPTE Pte,
|
|
||||||
IN LONG Count)
|
|
||||||
{
|
|
||||||
/* Return advanced PTE pointer */
|
|
||||||
return (PMMPTE)((ULONG_PTR)Pte + (Count * sizeof(MMPTE)));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clears the contents of a page table entry (PTE).
|
* Clears the contents of a page table entry (PTE).
|
||||||
*
|
*
|
||||||
@@ -43,64 +21,13 @@ MM::PageMap::AdvancePte(IN PMMPTE Pte,
|
|||||||
*/
|
*/
|
||||||
XTAPI
|
XTAPI
|
||||||
VOID
|
VOID
|
||||||
MM::PageMap::ClearPte(IN PMMPTE PtePointer)
|
MM::PageMap::ClearPte(PHARDWARE_PTE PtePointer)
|
||||||
{
|
{
|
||||||
/* Clear PTE */
|
PtePointer->CacheDisable = 0;
|
||||||
PtePointer->Long = 0;
|
PtePointer->PageFrameNumber = 0;
|
||||||
}
|
PtePointer->Valid = 0;
|
||||||
|
PtePointer->Writable = 0;
|
||||||
/**
|
PtePointer->WriteThrough = 0;
|
||||||
* Gets the next entry in a PTE list.
|
|
||||||
*
|
|
||||||
* @param Pte
|
|
||||||
* The PTE pointer to get the next entry from.
|
|
||||||
*
|
|
||||||
* @return This routine returns the next entry in the PTE list.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
ULONG_PTR
|
|
||||||
MM::PageMap::GetNextEntry(IN PMMPTE Pte)
|
|
||||||
{
|
|
||||||
/* Return next entry in PTE list */
|
|
||||||
return Pte->List.NextEntry;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Advances a PTE pointer, considering the actual PTE size.
|
|
||||||
*
|
|
||||||
* @param Pte
|
|
||||||
* The PTE pointer to advance.
|
|
||||||
*
|
|
||||||
* @return The advanced PTE pointer.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
PMMPTE
|
|
||||||
MM::PageMap::GetNextPte(IN PMMPTE Pte)
|
|
||||||
{
|
|
||||||
/* Return advanced PTE pointer */
|
|
||||||
return AdvancePte(Pte, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if a PTE list contains only one entry.
|
|
||||||
*
|
|
||||||
* @param Pte
|
|
||||||
* The PTE pointer to check.
|
|
||||||
*
|
|
||||||
* @return This routine returns TRUE if the PTE list has only one entry, FALSE otherwise.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
BOOLEAN
|
|
||||||
MM::PageMap::GetOneEntry(IN PMMPTE Pte)
|
|
||||||
{
|
|
||||||
/* Return one entry status */
|
|
||||||
return Pte->List.OneEntry;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -115,7 +42,7 @@ MM::PageMap::GetOneEntry(IN PMMPTE Pte)
|
|||||||
*/
|
*/
|
||||||
XTAPI
|
XTAPI
|
||||||
PMMP5E
|
PMMP5E
|
||||||
MM::PageMap::GetP5eAddress(IN PVOID Address)
|
MM::PageMap::GetP5eAddress(PVOID Address)
|
||||||
{
|
{
|
||||||
ULONGLONG Offset;
|
ULONGLONG Offset;
|
||||||
|
|
||||||
@@ -124,72 +51,6 @@ MM::PageMap::GetP5eAddress(IN PVOID Address)
|
|||||||
return (PMMP5E)((PageMapInfo.P5eBase + Offset) * PageMapInfo.Xpa);
|
return (PMMP5E)((PageMapInfo.P5eBase + Offset) * PageMapInfo.Xpa);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the Offset of the P5E (Page Map Level 5 Entry), that maps given address.
|
|
||||||
*
|
|
||||||
* @param Address
|
|
||||||
* Specifies the virtual address for which to retrieve the corresponding P5E.
|
|
||||||
*
|
|
||||||
* @return This routine returns the Offset of the P5E, or NULLPTR if LA57 is not enabled.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
ULONG
|
|
||||||
MM::PageMap::GetP5eOffset(IN PVOID Address)
|
|
||||||
{
|
|
||||||
/* Return P5E Offset */
|
|
||||||
return (((((ULONGLONG)Address) >> MM_P5I_SHIFT) & 0x1FF) * PageMapInfo.Xpa);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the virtual address that is mapped by a given Page Map Level 5 Entry.
|
|
||||||
*
|
|
||||||
* @param P5ePointer
|
|
||||||
* Specifies the address of the P5E.
|
|
||||||
*
|
|
||||||
* @return This routine returns the virtual address mapped by the P5E, or NULLPTR if LA57 is not enabled.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
PVOID
|
|
||||||
MM::PageMap::GetP5eVirtualAddress(IN PMMP5E P5ePointer)
|
|
||||||
{
|
|
||||||
return (PVOID)((((LONGLONG)P5ePointer << 52) >> 7) * PageMapInfo.Xpa);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the page frame number from a corresponding PTE.
|
|
||||||
*
|
|
||||||
* @param Pte
|
|
||||||
* The PTE pointer to get the page frame number from.
|
|
||||||
*
|
|
||||||
* @return This routine returns the page frame number.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
PFN_NUMBER
|
|
||||||
MM::PageMap::GetPageFrameNumber(IN PMMPTE Pte)
|
|
||||||
{
|
|
||||||
return Pte->Hardware.PageFrameNumber;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets Page Map Level (PML) for current paging mode.
|
|
||||||
*
|
|
||||||
* @return This routine returns the page map level.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
USHORT
|
|
||||||
MM::PageMap::GetPageMapLevel()
|
|
||||||
{
|
|
||||||
return PageMapInfo.Xpa ? 5 : 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the address of the PDE (Page Directory Entry), that maps given address.
|
* Gets the address of the PDE (Page Directory Entry), that maps given address.
|
||||||
*
|
*
|
||||||
@@ -202,7 +63,7 @@ MM::PageMap::GetPageMapLevel()
|
|||||||
*/
|
*/
|
||||||
XTAPI
|
XTAPI
|
||||||
PMMPDE
|
PMMPDE
|
||||||
MM::PageMap::GetPdeAddress(IN PVOID Address)
|
MM::PageMap::GetPdeAddress(PVOID Address)
|
||||||
{
|
{
|
||||||
ULONGLONG Offset;
|
ULONGLONG Offset;
|
||||||
|
|
||||||
@@ -211,29 +72,11 @@ MM::PageMap::GetPdeAddress(IN PVOID Address)
|
|||||||
return (PMMPDE)(PageMapInfo.PdeBase + Offset);
|
return (PMMPDE)(PageMapInfo.PdeBase + Offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the Offset of the PDE (Page Directory Entry), that maps given address.
|
|
||||||
*
|
|
||||||
* @param Address
|
|
||||||
* Specifies the virtual address for which to retrieve the corresponding PDE.
|
|
||||||
*
|
|
||||||
* @return This routine returns the Offset of the PDE.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
ULONG
|
|
||||||
MM::PageMap::GetPdeOffset(IN PVOID Address)
|
|
||||||
{
|
|
||||||
/* Return PDE Offset */
|
|
||||||
return ((((ULONGLONG)Address) >> MM_PDI_SHIFT) & 0x1FF);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the address of the PPE (Page Directory Pointer Table Entry), that maps given address.
|
* Gets the address of the PPE (Page Directory Pointer Table Entry), that maps given address.
|
||||||
*
|
*
|
||||||
* @param Address
|
* @param Address
|
||||||
* Specifies the virtual address for which to retrieve the corresponding PPE.
|
* Specifies the virtual address for which to retrieve the corresponding PDE.
|
||||||
*
|
*
|
||||||
* @return This routine returns the address of the PPE.
|
* @return This routine returns the address of the PPE.
|
||||||
*
|
*
|
||||||
@@ -241,7 +84,7 @@ MM::PageMap::GetPdeOffset(IN PVOID Address)
|
|||||||
*/
|
*/
|
||||||
XTAPI
|
XTAPI
|
||||||
PMMPPE
|
PMMPPE
|
||||||
MM::PageMap::GetPpeAddress(IN PVOID Address)
|
MM::PageMap::GetPpeAddress(PVOID Address)
|
||||||
{
|
{
|
||||||
ULONGLONG Offset;
|
ULONGLONG Offset;
|
||||||
|
|
||||||
@@ -250,42 +93,6 @@ MM::PageMap::GetPpeAddress(IN PVOID Address)
|
|||||||
return (PMMPPE)(PageMapInfo.PpeBase + Offset);
|
return (PMMPPE)(PageMapInfo.PpeBase + Offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the Offset of the PPE (Page Directory Pointer Table Entry), that maps given address.
|
|
||||||
*
|
|
||||||
* @param Address
|
|
||||||
* Specifies the virtual address for which to retrieve the corresponding PPE.
|
|
||||||
*
|
|
||||||
* @return This routine returns the Offset of the PPE.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
ULONG
|
|
||||||
MM::PageMap::GetPpeOffset(IN PVOID Address)
|
|
||||||
{
|
|
||||||
/* Return PPE Offset */
|
|
||||||
return ((((ULONGLONG)Address) >> MM_PPI_SHIFT) & 0x1FF);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the entire contents of a Page Table Entry (PTE) as a single value.
|
|
||||||
*
|
|
||||||
* @param PtePointer
|
|
||||||
* Pointer to the Page Table Entry (PTE) to read.
|
|
||||||
*
|
|
||||||
* @return This routine returns the contents of the PTE as a single value.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
ULONG_PTR
|
|
||||||
MM::PageMap::GetPte(IN PMMPTE PtePointer)
|
|
||||||
{
|
|
||||||
/* Return PTE value */
|
|
||||||
return PtePointer->Long;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the address of the PTE (Page Table Entry), that maps given address.
|
* Gets the address of the PTE (Page Table Entry), that maps given address.
|
||||||
*
|
*
|
||||||
@@ -298,7 +105,7 @@ MM::PageMap::GetPte(IN PMMPTE PtePointer)
|
|||||||
*/
|
*/
|
||||||
XTAPI
|
XTAPI
|
||||||
PMMPTE
|
PMMPTE
|
||||||
MM::PageMap::GetPteAddress(IN PVOID Address)
|
MM::PageMap::GetPteAddress(PVOID Address)
|
||||||
{
|
{
|
||||||
ULONGLONG Offset;
|
ULONGLONG Offset;
|
||||||
|
|
||||||
@@ -307,115 +114,6 @@ MM::PageMap::GetPteAddress(IN PVOID Address)
|
|||||||
return (PMMPTE)(PageMapInfo.PteBase + Offset);
|
return (PMMPTE)(PageMapInfo.PteBase + Offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Calculates the distance between two PTE pointers.
|
|
||||||
*
|
|
||||||
* @param EndPte
|
|
||||||
* Pointer to the ending Page Table Entry.
|
|
||||||
*
|
|
||||||
* @param StartPte
|
|
||||||
* Pointer to the starting Page Table Entry.
|
|
||||||
*
|
|
||||||
* @return This routine returns a signed value representing the number of PTEs between EndPte and StartPte.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
LONG
|
|
||||||
MM::PageMap::GetPteDistance(PMMPTE EndPte,
|
|
||||||
PMMPTE StartPte)
|
|
||||||
{
|
|
||||||
/* Return distance between PTE pointers */
|
|
||||||
return ((ULONG_PTR)EndPte - (ULONG_PTR)StartPte) / sizeof(MMPTE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the Offset of the PTE (Page Table Entry), that maps given address.
|
|
||||||
*
|
|
||||||
* @param Address
|
|
||||||
* Specifies the virtual address for which to retrieve the corresponding PTE.
|
|
||||||
*
|
|
||||||
* @return This routine returns the Offset of the PTE.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
ULONG
|
|
||||||
MM::PageMap::GetPteOffset(IN PVOID Address)
|
|
||||||
{
|
|
||||||
/* Return PTE Offset */
|
|
||||||
return ((((ULONGLONG)Address) >> MM_PTI_SHIFT) & 0x1FF);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the size of a PTE.
|
|
||||||
*
|
|
||||||
* @return This routine returns the size of a PTE.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
ULONG
|
|
||||||
MM::PageMap::GetPteSize(VOID)
|
|
||||||
{
|
|
||||||
/* Return the size of MMPTE */
|
|
||||||
return sizeof(MMPTE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the software protection value of the corresponding Page Table Entry.
|
|
||||||
*
|
|
||||||
* @param PtePointer
|
|
||||||
* Specifies the address of the PTE.
|
|
||||||
*
|
|
||||||
* @return This routine returns the PTE software protection value.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
ULONG
|
|
||||||
MM::PageMap::GetPteSoftwareProtection(IN PMMPTE PtePointer)
|
|
||||||
{
|
|
||||||
/* Return PTE software protection value */
|
|
||||||
return (ULONG)PtePointer->Software.Protection;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the software prototype value of the corresponding Page Table Entry.
|
|
||||||
*
|
|
||||||
* @param PtePointer
|
|
||||||
* Specifies the address of the PTE.
|
|
||||||
*
|
|
||||||
* @return This routine returns the PTE software prototype value.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
ULONG
|
|
||||||
MM::PageMap::GetPteSoftwarePrototype(IN PMMPTE PtePointer)
|
|
||||||
{
|
|
||||||
/* Return PTE software prototype value */
|
|
||||||
return (ULONG)PtePointer->Software.Prototype;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the software transition value of the corresponding Page Table Entry.
|
|
||||||
*
|
|
||||||
* @param PtePointer
|
|
||||||
* Specifies the address of the PTE.
|
|
||||||
*
|
|
||||||
* @return This routine returns the PTE software transition value.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
ULONG
|
|
||||||
MM::PageMap::GetPteSoftwareTransition(IN PMMPTE PtePointer)
|
|
||||||
{
|
|
||||||
/* Return PTE software transition value */
|
|
||||||
return (ULONG)PtePointer->Software.Transition;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the address of the PXE (Extended Page Entry), that maps given address.
|
* Gets the address of the PXE (Extended Page Entry), that maps given address.
|
||||||
*
|
*
|
||||||
@@ -428,47 +126,14 @@ MM::PageMap::GetPteSoftwareTransition(IN PMMPTE PtePointer)
|
|||||||
*/
|
*/
|
||||||
XTAPI
|
XTAPI
|
||||||
PMMPXE
|
PMMPXE
|
||||||
MM::PageMap::GetPxeAddress(IN PVOID Address)
|
MM::PageMap::GetPxeAddress(PVOID Address)
|
||||||
{
|
{
|
||||||
ULONGLONG Offset;
|
ULONGLONG Offset;
|
||||||
|
|
||||||
/* Calculate offset and return PXE address */
|
|
||||||
Offset = ((((ULONGLONG)Address & (((ULONGLONG)1 << PageMapInfo.VaBits) - 1)) >> MM_PXI_SHIFT) << MM_PTE_SHIFT);
|
Offset = ((((ULONGLONG)Address & (((ULONGLONG)1 << PageMapInfo.VaBits) - 1)) >> MM_PXI_SHIFT) << MM_PTE_SHIFT);
|
||||||
return (PMMPXE)(PageMapInfo.PxeBase + Offset);
|
return (PMMPXE)(PageMapInfo.PxeBase + Offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the Offset of the PXE (Extended Page Entry), that maps given address.
|
|
||||||
*
|
|
||||||
* @param Address
|
|
||||||
* Specifies the virtual address for which to retrieve the corresponding PXE.
|
|
||||||
*
|
|
||||||
* @return This routine returns the Offset of the PXE.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
ULONG
|
|
||||||
MM::PageMap::GetPxeOffset(IN PVOID Address)
|
|
||||||
{
|
|
||||||
/* Return PXE Offset */
|
|
||||||
return ((((ULONGLONG)Address) >> MM_PXI_SHIFT) & 0x1FF);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the status of Extended Paging Address (XPA) mode.
|
|
||||||
*
|
|
||||||
* @return This routine returns TRUE if XPA is enabled, FALSE otherwise.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
BOOLEAN
|
|
||||||
MM::PageMap::GetXpaStatus()
|
|
||||||
{
|
|
||||||
return PageMapInfo.Xpa;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks whether the given PML2 page table entry (PTE) is valid.
|
* Checks whether the given PML2 page table entry (PTE) is valid.
|
||||||
*
|
*
|
||||||
@@ -481,58 +146,13 @@ MM::PageMap::GetXpaStatus()
|
|||||||
*/
|
*/
|
||||||
XTAPI
|
XTAPI
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
MM::PageMap::PteValid(IN PMMPTE PtePointer)
|
MM::PageMap::PteValid(PHARDWARE_PTE PtePointer)
|
||||||
{
|
{
|
||||||
/* Check if PTE is valid */
|
return (BOOLEAN)PtePointer->Valid;
|
||||||
return (BOOLEAN)PtePointer->Hardware.Valid;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the next entry in a PTE list.
|
* Sets a PML2 page table entry (PTE) with the specified physical page and access flags.
|
||||||
*
|
|
||||||
* @param Pte
|
|
||||||
* The PTE pointer to modify.
|
|
||||||
*
|
|
||||||
* @param Value
|
|
||||||
* The value to set as the next entry.
|
|
||||||
*
|
|
||||||
* @return This routine does not return any value.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
VOID
|
|
||||||
MM::PageMap::SetNextEntry(IN PMMPTE Pte,
|
|
||||||
IN ULONG_PTR Value)
|
|
||||||
{
|
|
||||||
/* Set next entry in PTE list */
|
|
||||||
Pte->List.NextEntry = Value;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the flag indicating whether a PTE list contains only one entry.
|
|
||||||
*
|
|
||||||
* @param Pte
|
|
||||||
* The PTE pointer to modify.
|
|
||||||
*
|
|
||||||
* @param Value
|
|
||||||
* The value to set. TRUE if the list has only one entry, FALSE otherwise.
|
|
||||||
*
|
|
||||||
* @return This routine does not return any value.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
VOID
|
|
||||||
MM::PageMap::SetOneEntry(IN PMMPTE Pte,
|
|
||||||
IN BOOLEAN Value)
|
|
||||||
{
|
|
||||||
/* Set one entry status */
|
|
||||||
Pte->List.OneEntry = Value;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets a Page Table Entry (PTE) with the specified physical page and access flags.
|
|
||||||
*
|
*
|
||||||
* @param PtePointer
|
* @param PtePointer
|
||||||
* Pointer to the page table entry (PTE) to set.
|
* Pointer to the page table entry (PTE) to set.
|
||||||
@@ -540,8 +160,8 @@ MM::PageMap::SetOneEntry(IN PMMPTE Pte,
|
|||||||
* @param PageFrameNumber
|
* @param PageFrameNumber
|
||||||
* Physical frame number to map.
|
* Physical frame number to map.
|
||||||
*
|
*
|
||||||
* @param AttributesMask
|
* @param Writable
|
||||||
* Specifies the attributes mask to apply to the PTE.
|
* Indicates whether the page should be writable.
|
||||||
*
|
*
|
||||||
* @return This routine does not return any value.
|
* @return This routine does not return any value.
|
||||||
*
|
*
|
||||||
@@ -549,35 +169,13 @@ MM::PageMap::SetOneEntry(IN PMMPTE Pte,
|
|||||||
*/
|
*/
|
||||||
XTAPI
|
XTAPI
|
||||||
VOID
|
VOID
|
||||||
MM::PageMap::SetPte(IN PMMPTE PtePointer,
|
MM::PageMap::SetPte(PHARDWARE_PTE PtePointer,
|
||||||
IN PFN_NUMBER PageFrameNumber,
|
PFN_NUMBER PageFrameNumber,
|
||||||
IN ULONG_PTR AttributesMask)
|
BOOLEAN Writable)
|
||||||
{
|
{
|
||||||
/* Set PTE */
|
PtePointer->PageFrameNumber = PageFrameNumber;
|
||||||
PtePointer->Hardware.PageFrameNumber = PageFrameNumber;
|
PtePointer->Valid = 1;
|
||||||
PtePointer->Hardware.Valid = 1;
|
PtePointer->Writable = Writable;
|
||||||
PtePointer->Long |= AttributesMask;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets a Page Table Entry (PTE) with the specified attributes.
|
|
||||||
*
|
|
||||||
* @param PtePointer
|
|
||||||
* Pointer to the page table entry (PTE) to set.
|
|
||||||
*
|
|
||||||
* @param Attributes
|
|
||||||
* Specifies the attributes to apply to the PTE.
|
|
||||||
*
|
|
||||||
* @return This routine does not return any value.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
VOID
|
|
||||||
MM::PageMap::SetPte(IN PMMPTE PtePointer,
|
|
||||||
IN ULONG_PTR Attributes)
|
|
||||||
{
|
|
||||||
PtePointer->Long = Attributes;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -598,138 +196,12 @@ MM::PageMap::SetPte(IN PMMPTE PtePointer,
|
|||||||
*/
|
*/
|
||||||
XTAPI
|
XTAPI
|
||||||
VOID
|
VOID
|
||||||
MM::PageMap::SetPteCaching(IN PMMPTE PtePointer,
|
MM::PageMap::SetPteCaching(PHARDWARE_PTE PtePointer,
|
||||||
IN BOOLEAN CacheDisable,
|
BOOLEAN CacheDisable,
|
||||||
IN BOOLEAN WriteThrough)
|
BOOLEAN WriteThrough)
|
||||||
{
|
{
|
||||||
/* Set caching attributes */
|
PtePointer->CacheDisable = CacheDisable;
|
||||||
PtePointer->Hardware.CacheDisable = CacheDisable;
|
PtePointer->WriteThrough = WriteThrough;
|
||||||
PtePointer->Hardware.WriteThrough = WriteThrough;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Transitions a Page Table Entry (PTE) to invalid state
|
|
||||||
*
|
|
||||||
* @param PointerPte
|
|
||||||
* Pointer to the page table entry (PTE) to transition.
|
|
||||||
*
|
|
||||||
* @param Protection
|
|
||||||
* Specifies the protection attribute to apply to the PTE.
|
|
||||||
*
|
|
||||||
* @return This routine does not return any value.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
VOID
|
|
||||||
MM::PageMap::TransitionPte(IN PMMPTE PointerPte,
|
|
||||||
IN ULONG_PTR Protection)
|
|
||||||
{
|
|
||||||
MMPTE TempPte;
|
|
||||||
|
|
||||||
/* Set transition PTE */
|
|
||||||
TempPte = *PointerPte;
|
|
||||||
TempPte.Software.Protection = Protection;
|
|
||||||
TempPte.Software.Prototype = 0;
|
|
||||||
TempPte.Software.Transition = 1;
|
|
||||||
TempPte.Software.Valid = 0;
|
|
||||||
|
|
||||||
/* Write PTE value */
|
|
||||||
*PointerPte = TempPte;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Writes a Page Table Entry (PTE) with the specified value.
|
|
||||||
*
|
|
||||||
* @param Pte
|
|
||||||
* Pointer to the page table entry (PTE) to write.
|
|
||||||
*
|
|
||||||
* @param Value
|
|
||||||
* The value to write to the PTE.
|
|
||||||
*
|
|
||||||
* @return This routine does not return any value.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
VOID
|
|
||||||
MM::PageMap::WritePte(IN PMMPTE Pte,
|
|
||||||
IN MMPTE Value)
|
|
||||||
{
|
|
||||||
/* Write PTE value */
|
|
||||||
Pte->Long = Value.Long;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the virtual address that is mapped by a given Page Directory Entry (PML4).
|
|
||||||
*
|
|
||||||
* @param PdePointer
|
|
||||||
* Specifies the address of the PDE.
|
|
||||||
*
|
|
||||||
* @return This routine returns the virtual address mapped by the PDE.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
PVOID
|
|
||||||
MM::PageMapBasic::GetPdeVirtualAddress(IN PMMPDE PdePointer)
|
|
||||||
{
|
|
||||||
/* Return PDE virtual address */
|
|
||||||
return (PVOID)(((LONGLONG)PdePointer << 34) >> 16);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the virtual address that is mapped by a given Page Directory Pointer Table Entry (PML4).
|
|
||||||
*
|
|
||||||
* @param PpePointer
|
|
||||||
* Specifies the address of the PPE.
|
|
||||||
*
|
|
||||||
* @return This routine returns the virtual address mapped by the PPE.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
PVOID
|
|
||||||
MM::PageMapBasic::GetPpeVirtualAddress(IN PMMPPE PpePointer)
|
|
||||||
{
|
|
||||||
/* Return PPE virtual address */
|
|
||||||
return (PVOID)(((LONGLONG)PpePointer << 43) >> 16);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the virtual address that is mapped by a given Page Table Entry (PML4).
|
|
||||||
*
|
|
||||||
* @param PtePointer
|
|
||||||
* Specifies the address of the PTE.
|
|
||||||
*
|
|
||||||
* @return This routine returns the virtual address mapped by the PTE.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
PVOID
|
|
||||||
MM::PageMapBasic::GetPteVirtualAddress(IN PMMPTE PtePointer)
|
|
||||||
{
|
|
||||||
/* Return PTE virtual address */
|
|
||||||
return (PVOID)(((LONGLONG)PtePointer << 25) >> 16);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the virtual address that is mapped by a given Extended Page Entry (PML4).
|
|
||||||
*
|
|
||||||
* @param PxePointer
|
|
||||||
* Specifies the address of the PXE.
|
|
||||||
*
|
|
||||||
* @return This routine returns the virtual address mapped by the PXE.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
PVOID
|
|
||||||
MM::PageMapBasic::GetPxeVirtualAddress(IN PMMPXE PxePointer)
|
|
||||||
{
|
|
||||||
/* Return PXE virtual address */
|
|
||||||
return (PVOID)(((LONGLONG)PxePointer << 52) >> 16);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -757,78 +229,6 @@ MM::PageMapBasic::InitializePageMapInfo(VOID)
|
|||||||
PageMapInfo.VaBits = 48;
|
PageMapInfo.VaBits = 48;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the virtual address that is mapped by a given Page Directory Entry (PML5).
|
|
||||||
*
|
|
||||||
* @param PdePointer
|
|
||||||
* Specifies the address of the PDE.
|
|
||||||
*
|
|
||||||
* @return This routine returns the virtual address mapped by the PDE.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
PVOID
|
|
||||||
MM::PageMapXpa::GetPdeVirtualAddress(IN PMMPDE PdePointer)
|
|
||||||
{
|
|
||||||
/* Return PDE virtual address */
|
|
||||||
return (PVOID)(((LONGLONG)PdePointer << 25) >> 7);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the virtual address that is mapped by a given Page Directory Pointer Table Entry (PML5).
|
|
||||||
*
|
|
||||||
* @param PpePointer
|
|
||||||
* Specifies the address of the PPE.
|
|
||||||
*
|
|
||||||
* @return This routine returns the virtual address mapped by the PPE.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
PVOID
|
|
||||||
MM::PageMapXpa::GetPpeVirtualAddress(IN PMMPPE PpePointer)
|
|
||||||
{
|
|
||||||
/* Return PPE virtual address */
|
|
||||||
return (PVOID)(((LONGLONG)PpePointer << 34) >> 7);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the virtual address that is mapped by a given Page Table Entry (PML5).
|
|
||||||
*
|
|
||||||
* @param PtePointer
|
|
||||||
* Specifies the address of the PTE.
|
|
||||||
*
|
|
||||||
* @return This routine returns the virtual address mapped by the PTE.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
PVOID
|
|
||||||
MM::PageMapXpa::GetPteVirtualAddress(IN PMMPTE PtePointer)
|
|
||||||
{
|
|
||||||
/* Return PTE virtual address */
|
|
||||||
return (PVOID)(((LONGLONG)PtePointer << 16) >> 7);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the virtual address that is mapped by a given Extended Page Entry (PML5).
|
|
||||||
*
|
|
||||||
* @param PxePointer
|
|
||||||
* Specifies the address of the PXE.
|
|
||||||
*
|
|
||||||
* @return This routine returns the virtual address mapped by the PXE.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
PVOID
|
|
||||||
MM::PageMapXpa::GetPxeVirtualAddress(IN PMMPXE PxePointer)
|
|
||||||
{
|
|
||||||
/* Return PXE virtual address */
|
|
||||||
return (PVOID)(((LONGLONG)PxePointer << 43) >> 7);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes page map information for XPA paging (PML5).
|
* Initializes page map information for XPA paging (PML5).
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -25,78 +25,6 @@ MM::Paging::GetExtendedPhysicalAddressingStatus(VOID)
|
|||||||
return ((AR::CpuFunc::ReadControlRegister(4) & CR4_LA57) != 0) ? TRUE : FALSE;
|
return ((AR::CpuFunc::ReadControlRegister(4) & CR4_LA57) != 0) ? TRUE : FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the address of the P5E (Page Map Level 5 Entry), that maps given address.
|
|
||||||
*
|
|
||||||
* @param Address
|
|
||||||
* Specifies the virtual address for which to retrieve the corresponding P5E.
|
|
||||||
*
|
|
||||||
* @return This routine returns the address of the P5E, or NULLPTR if LA57 is not enabled.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
PMMP5E
|
|
||||||
MM::Paging::GetP5eAddress(IN PVOID Address)
|
|
||||||
{
|
|
||||||
/* Return PDE address */
|
|
||||||
return PmlRoutines->GetP5eAddress(Address);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the virtual address that is mapped by a given Page Map Level 5 Entry.
|
|
||||||
*
|
|
||||||
* @param P5ePointer
|
|
||||||
* Specifies the address of the P5E.
|
|
||||||
*
|
|
||||||
* @return This routine returns the virtual address mapped by the P5E, or NULLPTR if LA57 is not enabled.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
PVOID
|
|
||||||
MM::Paging::GetP5eVirtualAddress(IN PMMP5E P5ePointer)
|
|
||||||
{
|
|
||||||
/* Return PTE virtual address */
|
|
||||||
return PmlRoutines->GetP5eVirtualAddress(P5ePointer);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the address of the PXE (Extended Page Entry), that maps given address.
|
|
||||||
*
|
|
||||||
* @param Address
|
|
||||||
* Specifies the virtual address for which to retrieve the corresponding PXE.
|
|
||||||
*
|
|
||||||
* @return This routine returns the address of the PXE.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
PMMPXE
|
|
||||||
MM::Paging::GetPxeAddress(IN PVOID Address)
|
|
||||||
{
|
|
||||||
/* Return PXE address */
|
|
||||||
return PmlRoutines->GetPxeAddress(Address);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the virtual address that is mapped by a given Extended Page Entry.
|
|
||||||
*
|
|
||||||
* @param PxePointer
|
|
||||||
* Specifies the address of the PXE.
|
|
||||||
*
|
|
||||||
* @return This routine returns the virtual address mapped by the PXE.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
PVOID
|
|
||||||
MM::Paging::GetPxeVirtualAddress(IN PMMPXE PxePointer)
|
|
||||||
{
|
|
||||||
/* Return PXE virtual address */
|
|
||||||
return PmlRoutines->GetPxeVirtualAddress(PxePointer);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fills a section of memory with zeroes like RtlZeroMemory(), but in more efficient way.
|
* Fills a section of memory with zeroes like RtlZeroMemory(), but in more efficient way.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -1,26 +0,0 @@
|
|||||||
/**
|
|
||||||
* PROJECT: ExectOS
|
|
||||||
* COPYRIGHT: See COPYING.md in the top level directory
|
|
||||||
* FILE: xtoskrnl/mm/amd64/pfault.cc
|
|
||||||
* DESCRIPTION: Page fault support for AMD64 architecture
|
|
||||||
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <xtos.hh>
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Evaluates the PDE for for paged pool and per-session mappings.
|
|
||||||
*
|
|
||||||
* @param VirtualAddress
|
|
||||||
* Specifies the virtual address to verify.
|
|
||||||
*
|
|
||||||
* @return This routine returns ACCESS_VIOLATION regardless PML4 or PML5 is used.
|
|
||||||
*/
|
|
||||||
XTFASTCALL
|
|
||||||
XTSTATUS
|
|
||||||
MM::PageFault::CheckPdeForPagedPool(IN PVOID VirtualAddress)
|
|
||||||
{
|
|
||||||
/* Return access violation */
|
|
||||||
return STATUS_ACCESS_VIOLATION;
|
|
||||||
}
|
|
||||||
@@ -1,342 +0,0 @@
|
|||||||
/**
|
|
||||||
* PROJECT: ExectOS
|
|
||||||
* COPYRIGHT: See COPYING.md in the top level directory
|
|
||||||
* FILE: xtoskrnl/mm/amd64/pfn.cc
|
|
||||||
* DESCRIPTION: Physical Frame Number for AMD64 support
|
|
||||||
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
|
|
||||||
* Rafal Kupiec <belliash@codingworkshop.eu.org>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <xtos.hh>
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Allocates and initializes page directory structures for a range of PDEs.
|
|
||||||
*
|
|
||||||
* @param StartingPde
|
|
||||||
* Supplies a pointer to the first PDE in the range to initialize.
|
|
||||||
*
|
|
||||||
* @param EndingPde
|
|
||||||
* Supplies a pointer to the last PDE in the range to initialize.
|
|
||||||
*
|
|
||||||
* @return This routine does not return any value.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
VOID
|
|
||||||
MM::Pfn::InitializePageDirectory(IN PMMPDE StartingPde,
|
|
||||||
IN PMMPDE EndingPde)
|
|
||||||
{
|
|
||||||
PMMPTE ParentPte, ValidPte;
|
|
||||||
BOOLEAN PteValidated;
|
|
||||||
|
|
||||||
/* Get a template PTE for mapping the PFN database pages */
|
|
||||||
ValidPte = MM::Pte::GetValidPte();
|
|
||||||
|
|
||||||
/* Initialize validation flag */
|
|
||||||
PteValidated = FALSE;
|
|
||||||
|
|
||||||
/* Iterate through the range of PDEs to ensure the paging hierarchy is fully mapped */
|
|
||||||
while(StartingPde <= EndingPde)
|
|
||||||
{
|
|
||||||
/* Check if there is a need to validate upper-level page table entries */
|
|
||||||
if(!PteValidated || ((ULONG_PTR)StartingPde & (MM_PAGE_SIZE - 1)) == 0)
|
|
||||||
{
|
|
||||||
/* For LA57, ensure PML5 entry exists */
|
|
||||||
if(MM::Paging::GetXpaStatus())
|
|
||||||
{
|
|
||||||
/* Get the P5E that maps the PXE page containing this hierarchy */
|
|
||||||
ParentPte = MM::Paging::GetPpeAddress(StartingPde);
|
|
||||||
|
|
||||||
/* Check if P5E entry is valid */
|
|
||||||
if(!MM::Paging::PteValid(ParentPte))
|
|
||||||
{
|
|
||||||
/* Allocate a new PML4 page and map P5E to it */
|
|
||||||
MM::Paging::SetPte(ValidPte, AllocateBootstrapPages(1), 0);
|
|
||||||
*ParentPte = *ValidPte;
|
|
||||||
|
|
||||||
/* Clear the newly created page */
|
|
||||||
RTL::Memory::ZeroMemory(MM::Paging::GetPteVirtualAddress(ParentPte), MM_PAGE_SIZE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get the PXE that maps the PPE page containing PDE */
|
|
||||||
ParentPte = MM::Paging::GetPdeAddress(StartingPde);
|
|
||||||
|
|
||||||
/* Check if PXE entry is valid */
|
|
||||||
if(!MM::Paging::PteValid(ParentPte))
|
|
||||||
{
|
|
||||||
/* Allocate a new PPE page and map PXE to it */
|
|
||||||
MM::Paging::SetPte(ValidPte, AllocateBootstrapPages(1), 0);
|
|
||||||
*ParentPte = *ValidPte;
|
|
||||||
|
|
||||||
/* Clear the newly created page */
|
|
||||||
RTL::Memory::ZeroMemory(MM::Paging::GetPteVirtualAddress(ParentPte), MM_PAGE_SIZE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get the PPE that maps the PDE page containing PTE */
|
|
||||||
ParentPte = MM::Paging::GetPteAddress(StartingPde);
|
|
||||||
|
|
||||||
/* Check if PPE entry is valid */
|
|
||||||
if(!MM::Paging::PteValid(ParentPte))
|
|
||||||
{
|
|
||||||
/* Allocate a new PDE page and map PPE to it */
|
|
||||||
MM::Paging::SetPte(ValidPte, AllocateBootstrapPages(1), 0);
|
|
||||||
*ParentPte = *ValidPte;
|
|
||||||
|
|
||||||
/* Clear the newly created page */
|
|
||||||
RTL::Memory::ZeroMemory(MM::Paging::GetPteVirtualAddress(ParentPte), MM_PAGE_SIZE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Upper levels for this PDE have been validated */
|
|
||||||
PteValidated = TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Ensure the PDE has a PTE page allocated */
|
|
||||||
if(!MM::Paging::PteValid(StartingPde))
|
|
||||||
{
|
|
||||||
/* Allocate a new PTE page and map PDE to it */
|
|
||||||
MM::Paging::SetPte(ValidPte, AllocateBootstrapPages(1), 0);
|
|
||||||
*StartingPde = *ValidPte;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Move to the next PDE */
|
|
||||||
StartingPde = MM::Paging::GetNextPte(StartingPde);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initializes the PFN database by mapping virtual memory and populating entries.
|
|
||||||
*
|
|
||||||
* @return This routine does not return any value.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
VOID
|
|
||||||
MM::Pfn::InitializePfnDatabase(VOID)
|
|
||||||
{
|
|
||||||
PKERNEL_INITIALIZATION_BLOCK InitializationBlock;
|
|
||||||
PLIST_ENTRY ListEntry;
|
|
||||||
PLOADER_MEMORY_DESCRIPTOR Descriptor;
|
|
||||||
PUCHAR PfnDatabaseEnd;
|
|
||||||
PMMMEMORY_LAYOUT MemoryLayout;
|
|
||||||
PMMPTE ValidPte;
|
|
||||||
|
|
||||||
/* Raise runlevel and acquire the PFN lock */
|
|
||||||
KE::RaiseRunLevel RunLevel(DISPATCH_LEVEL);
|
|
||||||
KE::QueuedSpinLockGuard SpinLock(SystemSpaceLock);
|
|
||||||
|
|
||||||
/* Get the kernel initialization block */
|
|
||||||
InitializationBlock = KE::BootInformation::GetInitializationBlock();
|
|
||||||
|
|
||||||
/* Get the memory layout */
|
|
||||||
MemoryLayout = MM::Manager::GetMemoryLayout();
|
|
||||||
|
|
||||||
/* Get the PFN database size and calculate the end of the PFN database virtual address space */
|
|
||||||
PfnDatabaseEnd = (PUCHAR)MemoryLayout->PfnDatabase + (MemoryLayout->PfnDatabaseSize * MM_PAGE_SIZE) - 1;
|
|
||||||
|
|
||||||
/* Get a template PTE for mapping the PFN database pages */
|
|
||||||
ValidPte = MM::Pte::GetValidPte();
|
|
||||||
|
|
||||||
/* Map the Page Directory and Page Directory Pointer tables for the PFN database */
|
|
||||||
MM::Pte::MapPPE(MemoryLayout->PfnDatabase, PfnDatabaseEnd, ValidPte);
|
|
||||||
MM::Pte::MapPDE(MemoryLayout->PfnDatabase, PfnDatabaseEnd, ValidPte);
|
|
||||||
MM::Pte::MapPTE(MemoryLayout->PfnDatabase, PfnDatabaseEnd, ValidPte);
|
|
||||||
|
|
||||||
/* Zero PFN database virtual space */
|
|
||||||
RTL::Memory::ZeroMemory(MemoryLayout->PfnDatabase, MemoryLayout->PfnDatabaseSize * MM_PAGE_SIZE);
|
|
||||||
|
|
||||||
/* Initialize the color tables */
|
|
||||||
MM::Colors::InitializeColorTables();
|
|
||||||
|
|
||||||
/* Iterate over memory descriptors to map the PFN database and initialize entries */
|
|
||||||
ListEntry = InitializationBlock->MemoryDescriptorListHead.Flink;
|
|
||||||
while(ListEntry != &InitializationBlock->MemoryDescriptorListHead)
|
|
||||||
{
|
|
||||||
/* Get the descriptor */
|
|
||||||
Descriptor = CONTAIN_RECORD(ListEntry, LOADER_MEMORY_DESCRIPTOR, ListEntry);
|
|
||||||
|
|
||||||
/* Skip invisible memory regions */
|
|
||||||
if(MM::Manager::VerifyMemoryTypeInvisible(Descriptor->MemoryType))
|
|
||||||
{
|
|
||||||
/* Move to the next descriptor and continue */
|
|
||||||
ListEntry = ListEntry->Flink;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check if this is the modified free descriptor */
|
|
||||||
if(Descriptor == FreeDescriptor)
|
|
||||||
{
|
|
||||||
/* Switch to the original descriptor */
|
|
||||||
Descriptor = &OriginalFreeDescriptor;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check if the free memory block that was split is being processed */
|
|
||||||
if(Descriptor == &OriginalFreeDescriptor)
|
|
||||||
{
|
|
||||||
/* Skip loop processing, free memory is initialized separately */
|
|
||||||
ListEntry = ListEntry->Flink;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Initialize PFNs for this memory range */
|
|
||||||
ProcessMemoryDescriptor(Descriptor->BasePage, Descriptor->PageCount, Descriptor->MemoryType);
|
|
||||||
|
|
||||||
/* Move to the next descriptor */
|
|
||||||
ListEntry = ListEntry->Flink;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Initialize PFNs for the free memory */
|
|
||||||
ProcessMemoryDescriptor(FreeDescriptor->BasePage, FreeDescriptor->PageCount, LoaderFree);
|
|
||||||
|
|
||||||
/* Initialize PFNs for the physical pages backing the PFN database */
|
|
||||||
ProcessMemoryDescriptor(OriginalFreeDescriptor.BasePage,
|
|
||||||
FreeDescriptor->BasePage - OriginalFreeDescriptor.BasePage,
|
|
||||||
LoaderMemoryData);
|
|
||||||
|
|
||||||
/* Restore original free descriptor */
|
|
||||||
*FreeDescriptor = OriginalFreeDescriptor;
|
|
||||||
|
|
||||||
/* Initialize PFNs backing page tables */
|
|
||||||
InitializePageTablePfns();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initializes PFN database entries for the system page tables.
|
|
||||||
*
|
|
||||||
* @return This routine does not return any value.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
VOID
|
|
||||||
MM::Pfn::InitializePageTablePfns(VOID)
|
|
||||||
{
|
|
||||||
PFN_NUMBER PageFrameIndex;
|
|
||||||
PMMPFN Pfn;
|
|
||||||
ULONG RootLevel;
|
|
||||||
PMMPTE RootPte;
|
|
||||||
|
|
||||||
/* Determine root structure based on paging mode */
|
|
||||||
if(MM::Paging::GetXpaStatus())
|
|
||||||
{
|
|
||||||
/* XPA enabled, 5-level paging (LA57) */
|
|
||||||
RootLevel = 5;
|
|
||||||
|
|
||||||
/* Retrieve the PFN of the PML5 table and its virtual base address */
|
|
||||||
PageFrameIndex = MM::Paging::GetPageFrameNumber(MM::Paging::GetPteAddress((PVOID)MM_P5E_LA57_BASE));
|
|
||||||
RootPte = (PMMPTE)MM::Paging::GetP5eAddress(NULLPTR);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* XPA disabled, 4-level paging */
|
|
||||||
RootLevel = 4;
|
|
||||||
|
|
||||||
/* Retrieve the PFN of the PML4 table and its virtual base address */
|
|
||||||
PageFrameIndex = MM::Paging::GetPageFrameNumber(MM::Paging::GetPteAddress((PVOID)MM_PXE_BASE));
|
|
||||||
RootPte = (PMMPTE)MM::Paging::GetPxeAddress(NULLPTR);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Initialize the PFN entry for the root page table itself */
|
|
||||||
Pfn = GetPfnEntry(PageFrameIndex);
|
|
||||||
if(Pfn)
|
|
||||||
{
|
|
||||||
/* Initialize the PFN entry */
|
|
||||||
Pfn->PteAddress = NULLPTR;
|
|
||||||
Pfn->u1.WsIndex = 0;
|
|
||||||
Pfn->u2.ShareCount = 1;
|
|
||||||
Pfn->u3.e1.CacheAttribute = PfnNonCached;
|
|
||||||
Pfn->u3.e2.ReferenceCount = 1;
|
|
||||||
Pfn->u4.PteFrame = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Start recursive scan from the top level */
|
|
||||||
if(RootPte)
|
|
||||||
{
|
|
||||||
/* Scan the root page table */
|
|
||||||
ScanPageTable(RootPte, RootLevel);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Recursively scans a page table to initialize PFN database entries for active pages.
|
|
||||||
*
|
|
||||||
* @param PointerPte
|
|
||||||
* Pointer to the base of the page table to scan.
|
|
||||||
*
|
|
||||||
* @param Level
|
|
||||||
* The paging level of the table being scanned.
|
|
||||||
*
|
|
||||||
* @return This routine does not return any value.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
VOID
|
|
||||||
MM::Pfn::ScanPageTable(IN PMMPTE PointerPte,
|
|
||||||
IN ULONG Level)
|
|
||||||
{
|
|
||||||
PVOID Address;
|
|
||||||
ULONG Index;
|
|
||||||
PMMPTE NextLevelPte;
|
|
||||||
ULONG PtesPerPage;
|
|
||||||
|
|
||||||
/* Get the number of PTEs per page */
|
|
||||||
PtesPerPage = MM::Pte::GetPtesPerPage();
|
|
||||||
|
|
||||||
/* Iterate through all entries in the current page table */
|
|
||||||
for(Index = 0; Index < PtesPerPage; Index++)
|
|
||||||
{
|
|
||||||
/* Check if the page table entry is present */
|
|
||||||
if(MM::Paging::PteValid(PointerPte))
|
|
||||||
{
|
|
||||||
/* Mark the PFN pointed to by this entry as active */
|
|
||||||
LinkPfnForPageTable(MM::Paging::GetPageFrameNumber(PointerPte), PointerPte);
|
|
||||||
|
|
||||||
/* Recurse to the next level, if this is not a leaf node (PTE) */
|
|
||||||
if(Level > 1)
|
|
||||||
{
|
|
||||||
/* Calculate the virtual address mapped by this entry to find the next table */
|
|
||||||
switch(Level)
|
|
||||||
{
|
|
||||||
case 5:
|
|
||||||
/* Calculate PXE */
|
|
||||||
Address = MM::Paging::GetP5eVirtualAddress((PMMP5E)PointerPte);
|
|
||||||
NextLevelPte = (PMMPTE)MM::Paging::GetPxeAddress(Address);
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
/* Calculate PPE */
|
|
||||||
Address = MM::Paging::GetPxeVirtualAddress((PMMPXE)PointerPte);
|
|
||||||
NextLevelPte = (PMMPTE)MM::Paging::GetPpeAddress(Address);
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
/* Calculate PDE */
|
|
||||||
Address = MM::Paging::GetPpeVirtualAddress((PMMPPE)PointerPte);
|
|
||||||
NextLevelPte = (PMMPTE)MM::Paging::GetPdeAddress(Address);
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
/* Calculate PTE */
|
|
||||||
Address = MM::Paging::GetPdeVirtualAddress((PMMPDE)PointerPte);
|
|
||||||
NextLevelPte = MM::Paging::GetPteAddress(Address);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
/* Nothing to calculate, return NULLPTR */
|
|
||||||
NextLevelPte = NULLPTR;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Recurse deeper if not at the bottom level (PTE) already */
|
|
||||||
if(NextLevelPte)
|
|
||||||
{
|
|
||||||
/* Recursively scan the next level page table */
|
|
||||||
ScanPageTable(NextLevelPte, Level - 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Move to the next entry in the current table */
|
|
||||||
PointerPte = MM::Paging::GetNextPte(PointerPte);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,295 +0,0 @@
|
|||||||
/**
|
|
||||||
* PROJECT: ExectOS
|
|
||||||
* COPYRIGHT: See COPYING.md in the top level directory
|
|
||||||
* FILE: xtoskrnl/mm/amd64/pte.cc
|
|
||||||
* DESCRIPTION: Page Table Entry (PTE) for AMD64 support
|
|
||||||
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <xtos.hh>
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if the virtual address is valid and mapped in the page tables.
|
|
||||||
*
|
|
||||||
* @param VirtualAddress
|
|
||||||
* The virtual address to check.
|
|
||||||
*
|
|
||||||
* @return This routine returns TRUE if the address is valid, or FALSE otherwise.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
BOOLEAN
|
|
||||||
MM::Pte::AddressValid(IN PVOID VirtualAddress)
|
|
||||||
{
|
|
||||||
/* Check XPA status */
|
|
||||||
if(MM::Paging::GetXpaStatus())
|
|
||||||
{
|
|
||||||
/* Check if the P5E is valid */
|
|
||||||
if(!MM::Paging::PteValid(MM::Paging::GetP5eAddress(VirtualAddress)))
|
|
||||||
{
|
|
||||||
/* Invalid P5E, return FALSE */
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check if PXE, PPE, PDE and PTE are valid */
|
|
||||||
if(!MM::Paging::PteValid(MM::Paging::GetPxeAddress(VirtualAddress)) ||
|
|
||||||
!MM::Paging::PteValid(MM::Paging::GetPpeAddress(VirtualAddress)) ||
|
|
||||||
!MM::Paging::PteValid(MM::Paging::GetPdeAddress(VirtualAddress)) ||
|
|
||||||
!MM::Paging::PteValid(MM::Paging::GetPteAddress(VirtualAddress)))
|
|
||||||
{
|
|
||||||
/* Invalid PXE, PPE, PDE or PTE, return FALSE */
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Address is valid, return TRUE */
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieves the base virtual address of the system PTEs.
|
|
||||||
*
|
|
||||||
* @return This routine returns a pointer to the first PTE in the system PTE space.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
PMMPTE
|
|
||||||
MM::Pte::GetSystemPteBaseAddress(VOID)
|
|
||||||
{
|
|
||||||
PMMMEMORY_LAYOUT MemoryLayout;
|
|
||||||
|
|
||||||
/* Retrieve the system's memory layout */
|
|
||||||
MemoryLayout = MM::Manager::GetMemoryLayout();
|
|
||||||
|
|
||||||
/* Determine the base address for system PTEs based on the paging mode */
|
|
||||||
if(MM::Paging::GetXpaStatus())
|
|
||||||
{
|
|
||||||
/* For 5-level paging, system PTEs start at the beginning of system space */
|
|
||||||
return MM::Paging::GetPteAddress((PVOID)MemoryLayout->NonPagedSystemPoolStart);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* For 4-level paging, system PTEs start at the legacy KSEG0_BASE */
|
|
||||||
return MM::Paging::GetPteAddress((PVOID)KSEG0_BASE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Performs the initial setup of the system's page table hierarchy.
|
|
||||||
*
|
|
||||||
* @return This routine does not return any value.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
VOID
|
|
||||||
MM::Pte::InitializePageTable(VOID)
|
|
||||||
{
|
|
||||||
PMMPTE EndSpacePte, PointerPte;
|
|
||||||
PMMMEMORY_LAYOUT MemoryLayout;
|
|
||||||
PVOID MappingRange;
|
|
||||||
MMPTE TemplatePte;
|
|
||||||
BOOLEAN Xpa;
|
|
||||||
|
|
||||||
/* Retrieve current paging mode and memory layout */
|
|
||||||
Xpa = MM::Paging::GetXpaStatus();
|
|
||||||
MemoryLayout = MM::Manager::GetMemoryLayout();
|
|
||||||
|
|
||||||
/* Enable the Global Paging (PGE) feature */
|
|
||||||
AR::CpuFunc::WriteControlRegister(4, AR::CpuFunc::ReadControlRegister(4) | CR4_PGE);
|
|
||||||
|
|
||||||
/* Check XPA status */
|
|
||||||
if(Xpa)
|
|
||||||
{
|
|
||||||
/* Get the PML5 user-space range if 5-level paging is active */
|
|
||||||
PointerPte = MM::Paging::GetP5eAddress(0);
|
|
||||||
EndSpacePte = MM::Paging::GetP5eAddress(MemoryLayout->UserSpaceEnd);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Otherwise, get the PML4 user-space range for 4-level paging */
|
|
||||||
PointerPte = MM::Paging::GetPxeAddress(0);
|
|
||||||
EndSpacePte = MM::Paging::GetPxeAddress(MemoryLayout->UserSpaceEnd);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Clear all top-level entries mapping the user address space */
|
|
||||||
while(PointerPte <= EndSpacePte)
|
|
||||||
{
|
|
||||||
MM::Paging::ClearPte(PointerPte);
|
|
||||||
PointerPte = MM::Paging::GetNextPte(PointerPte);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Flush the TLB to invalidate all non-global entries */
|
|
||||||
AR::CpuFunc::FlushTlb();
|
|
||||||
|
|
||||||
/* Create a template PTE for mapping kernel pages */
|
|
||||||
MM::Paging::ClearPte(&TemplatePte);
|
|
||||||
MM::Paging::SetPte(&TemplatePte, 0, MM_PTE_READWRITE | MM_PTE_CACHE_ENABLE);
|
|
||||||
|
|
||||||
/* Check XPA status */
|
|
||||||
if(Xpa)
|
|
||||||
{
|
|
||||||
/* Map the kernel's PML5 entries if 5-level paging is active */
|
|
||||||
MM::Pte::MapP5E(MemoryLayout->HyperSpaceStart, (PVOID)MM_HIGHEST_SYSTEM_ADDRESS, &TemplatePte);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Map the kernel's PML4 entries */
|
|
||||||
MM::Pte::MapPXE(MemoryLayout->HyperSpaceStart, (PVOID)MM_HIGHEST_SYSTEM_ADDRESS, &TemplatePte);
|
|
||||||
|
|
||||||
/* Calculate the end address of the hyperspace working set mapping */
|
|
||||||
MappingRange = (PVOID)((ULONG_PTR)MemoryLayout->HyperSpaceStart + MM_HYPERSPACE_PAGE_COUNT * MM_PAGE_SIZE);
|
|
||||||
|
|
||||||
/* Map the PDPT entries for paged pool and hyperspace */
|
|
||||||
MM::Pte::MapPPE(MemoryLayout->PagedPoolStart, MemoryLayout->PagedPoolEnd, &ValidPte);
|
|
||||||
MM::Pte::MapPPE(MemoryLayout->HyperSpaceStart, MemoryLayout->HyperSpaceEnd, &ValidPte);
|
|
||||||
|
|
||||||
/* Map the PDEs for the hyperspace working set */
|
|
||||||
MM::Pte::MapPDE(MemoryLayout->HyperSpaceStart, MappingRange, &ValidPte);
|
|
||||||
|
|
||||||
/* Set the hyperspace working set's PTE with the total PTE count */
|
|
||||||
MM::Paging::SetPte(MM::Paging::GetPteAddress((PVOID)MemoryLayout->HyperSpaceStart), MM_HYPERSPACE_PAGE_COUNT, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Maps a range of virtual addresses at the P5E (PML5) level.
|
|
||||||
*
|
|
||||||
* @param StartAddress
|
|
||||||
* The beginning of the virtual address range to map.
|
|
||||||
*
|
|
||||||
* @param EndAddress
|
|
||||||
* The end of the virtual address range to map.
|
|
||||||
*
|
|
||||||
* @param TemplateP5e
|
|
||||||
* A template P5E to use for creating new entries.
|
|
||||||
*
|
|
||||||
* @return This routine does not return any value.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
VOID
|
|
||||||
MM::Pte::MapP5E(IN PVOID StartAddress,
|
|
||||||
IN PVOID EndAddress,
|
|
||||||
IN PMMP5E TemplateP5e)
|
|
||||||
{
|
|
||||||
PMMP5E EndSpace, PointerP5e;
|
|
||||||
|
|
||||||
/* Get P5E addresses */
|
|
||||||
PointerP5e = MM::Paging::GetP5eAddress(StartAddress);
|
|
||||||
EndSpace = MM::Paging::GetP5eAddress(EndAddress);
|
|
||||||
|
|
||||||
/* Iterate over all P5Es */
|
|
||||||
while(PointerP5e <= EndSpace)
|
|
||||||
{
|
|
||||||
/* Check if P5E is already mapped */
|
|
||||||
if(!MM::Paging::PteValid(PointerP5e))
|
|
||||||
{
|
|
||||||
/* Map P5E */
|
|
||||||
MM::Paging::SetPte(TemplateP5e, MM::Pfn::AllocateBootstrapPages(1), 0);
|
|
||||||
*PointerP5e = *TemplateP5e;
|
|
||||||
|
|
||||||
/* Clear the page table */
|
|
||||||
RTL::Memory::ZeroMemory(MM::Paging::GetPteVirtualAddress(PointerP5e), MM_PAGE_SIZE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get next table entry */
|
|
||||||
PointerP5e = MM::Paging::GetNextPte(PointerP5e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Maps a range of virtual addresses at the PPE (Page Directory Pointer Entry) level.
|
|
||||||
*
|
|
||||||
* @param StartAddress
|
|
||||||
* The beginning of the virtual address range to map.
|
|
||||||
*
|
|
||||||
* @param EndAddress
|
|
||||||
* The end of the virtual address range to map.
|
|
||||||
*
|
|
||||||
* @param TemplatePpe
|
|
||||||
* A template PPE to use for creating new entries.
|
|
||||||
*
|
|
||||||
* @return This routine does not return any value.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
VOID
|
|
||||||
MM::Pte::MapPPE(IN PVOID StartAddress,
|
|
||||||
IN PVOID EndAddress,
|
|
||||||
IN PMMPPE TemplatePpe)
|
|
||||||
{
|
|
||||||
PMMPPE EndSpace, PointerPpe;
|
|
||||||
|
|
||||||
/* Get PPE addresses */
|
|
||||||
PointerPpe = MM::Paging::GetPpeAddress(StartAddress);
|
|
||||||
EndSpace = MM::Paging::GetPpeAddress(EndAddress);
|
|
||||||
|
|
||||||
/* Iterate over all PPEs */
|
|
||||||
while(PointerPpe <= EndSpace)
|
|
||||||
{
|
|
||||||
/* Check if PPE is already mapped */
|
|
||||||
if(!MM::Paging::PteValid(PointerPpe))
|
|
||||||
{
|
|
||||||
/* Map PPE */
|
|
||||||
MM::Paging::SetPte(TemplatePpe, MM::Pfn::AllocateBootstrapPages(1), 0);
|
|
||||||
*PointerPpe = *TemplatePpe;
|
|
||||||
|
|
||||||
/* Clear the page table */
|
|
||||||
RTL::Memory::ZeroMemory(MM::Paging::GetPteVirtualAddress(PointerPpe), MM_PAGE_SIZE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get next table entry */
|
|
||||||
PointerPpe = MM::Paging::GetNextPte(PointerPpe);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Maps a range of virtual addresses at the PXE (PML4) level.
|
|
||||||
*
|
|
||||||
* @param StartAddress
|
|
||||||
* The beginning of the virtual address range to map.
|
|
||||||
*
|
|
||||||
* @param EndAddress
|
|
||||||
* The end of the virtual address range to map.
|
|
||||||
*
|
|
||||||
* @param TemplatePxe
|
|
||||||
* A template PXE to use for creating new entries.
|
|
||||||
*
|
|
||||||
* @return This routine does not return any value.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
VOID
|
|
||||||
MM::Pte::MapPXE(IN PVOID StartAddress,
|
|
||||||
IN PVOID EndAddress,
|
|
||||||
IN PMMPXE TemplatePxe)
|
|
||||||
{
|
|
||||||
PMMPXE EndSpace, PointerPxe;
|
|
||||||
|
|
||||||
/* Get PXE addresses */
|
|
||||||
PointerPxe = MM::Paging::GetPxeAddress(StartAddress);
|
|
||||||
EndSpace = MM::Paging::GetPxeAddress(EndAddress);
|
|
||||||
|
|
||||||
/* Iterate over all PTEs */
|
|
||||||
while(PointerPxe <= EndSpace)
|
|
||||||
{
|
|
||||||
/* Check if PTE is already mapped */
|
|
||||||
if(!MM::Paging::PteValid(PointerPxe))
|
|
||||||
{
|
|
||||||
/* Map PTE */
|
|
||||||
MM::Paging::SetPte(TemplatePxe, MM::Pfn::AllocateBootstrapPages(1), 0);
|
|
||||||
*PointerPxe = *TemplatePxe;
|
|
||||||
|
|
||||||
/* Clear the page table */
|
|
||||||
RTL::Memory::ZeroMemory(MM::Paging::GetPteVirtualAddress(PointerPxe), MM_PAGE_SIZE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get next table entry */
|
|
||||||
PointerPxe = MM::Paging::GetNextPte(PointerPxe);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,178 +0,0 @@
|
|||||||
/**
|
|
||||||
* PROJECT: ExectOS
|
|
||||||
* COPYRIGHT: See COPYING.md in the top level directory
|
|
||||||
* FILE: xtoskrnl/mm/colors.cc
|
|
||||||
* DESCRIPTION: Memory manager page coloring subsystem
|
|
||||||
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <xtos.hh>
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Computes & initializes the system's page coloring.
|
|
||||||
*
|
|
||||||
* @return This routine does not return any value.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
VOID
|
|
||||||
MM::Colors::ComputePageColoring(VOID)
|
|
||||||
{
|
|
||||||
UNIMPLEMENTED;
|
|
||||||
|
|
||||||
/* Compute L2 paging colors and mask */
|
|
||||||
PagingColors = MM_PAGING_COLORS;
|
|
||||||
PagingColorsMask = PagingColors - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieves a pointer to the color table for a specific page list and color.
|
|
||||||
*
|
|
||||||
* @param PageList
|
|
||||||
* The page list type (e.g., FreePageList, ZeroedPageList).
|
|
||||||
*
|
|
||||||
* @param Color
|
|
||||||
* Supplies the specific color index.
|
|
||||||
*
|
|
||||||
* @return This routine returns a pointer to the corresponding MMCOLOR_TABLES structure.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
PMMCOLOR_TABLES
|
|
||||||
MM::Colors::GetFreePages(IN MMPAGELISTS PageList,
|
|
||||||
IN ULONG Color)
|
|
||||||
{
|
|
||||||
/* Return a pointer to the requested color table entry */
|
|
||||||
return &FreePages[PageList][Color];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieves a pointer to the modified pages list for a specific color.
|
|
||||||
*
|
|
||||||
* @param Color
|
|
||||||
* Supplies the specific color index.
|
|
||||||
*
|
|
||||||
* @return This routine returns a pointer to the corresponding MMPFNLIST structure.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
PMMPFNLIST
|
|
||||||
MM::Colors::GetModifiedPages(IN ULONG Color)
|
|
||||||
{
|
|
||||||
return &ModifiedPages[Color];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieves the next available color for page coloring.
|
|
||||||
*
|
|
||||||
* @return This routine returns the next color value, ensuring it stays within the valid color range.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
ULONG
|
|
||||||
MM::Colors::GetNextColor(VOID)
|
|
||||||
{
|
|
||||||
/* Increment the color counter and wrap it around using the mask */
|
|
||||||
return ((++PagingColors) & PagingColorsMask);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieves the total number of page colors configured in the system.
|
|
||||||
*
|
|
||||||
* @return This routine returns the number of page colors.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
ULONG
|
|
||||||
MM::Colors::GetPagingColors(VOID)
|
|
||||||
{
|
|
||||||
/* Return the total number of page colors */
|
|
||||||
return PagingColors;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieves the bitmask used for calculating a page's color.
|
|
||||||
*
|
|
||||||
* @return This routine returns the page color mask.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
ULONG
|
|
||||||
MM::Colors::GetPagingColorsMask(VOID)
|
|
||||||
{
|
|
||||||
/* Return the mask used for page coloring calculations */
|
|
||||||
return PagingColorsMask;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initializes the data structures for page coloring.
|
|
||||||
*
|
|
||||||
* @return This routine does not return any value.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
VOID
|
|
||||||
MM::Colors::InitializeColorTables(VOID)
|
|
||||||
{
|
|
||||||
PMMMEMORY_LAYOUT MemoryLayout;
|
|
||||||
PMMPTE PointerPte, LastPte;
|
|
||||||
ULONG Color;
|
|
||||||
PMMPTE ValidPte;
|
|
||||||
|
|
||||||
/* Get the memory layout */
|
|
||||||
MemoryLayout = MM::Manager::GetMemoryLayout();
|
|
||||||
|
|
||||||
/* Set the base address of the color tables to start right after the PFN database */
|
|
||||||
FreePages[0] = (PMMCOLOR_TABLES)&((PMMPFN)MemoryLayout->PfnDatabase)[MM::Pfn::GetHighestPhysicalPage() + 1];
|
|
||||||
|
|
||||||
/* Calculate the virtual address range for both color tables */
|
|
||||||
PointerPte = MM::Paging::GetPteAddress(&FreePages[0][0]);
|
|
||||||
LastPte = MM::Paging::GetPteAddress((PVOID)((ULONG_PTR)FreePages[0] +
|
|
||||||
(2 * PagingColors * sizeof(MMCOLOR_TABLES)) - 1));
|
|
||||||
|
|
||||||
/* Get a pointer to a PTE template */
|
|
||||||
ValidPte = MM::Pte::GetValidPte();
|
|
||||||
|
|
||||||
/* Ensure the entire virtual address range for the color tables is mapped */
|
|
||||||
while(PointerPte <= LastPte)
|
|
||||||
{
|
|
||||||
/* Check if a page in the range is not mapped */
|
|
||||||
if(!MM::Paging::PteValid(PointerPte))
|
|
||||||
{
|
|
||||||
/* Use the bootstrap allocator to get a physical page */
|
|
||||||
MM::Paging::SetPte(ValidPte, MM::Pfn::AllocateBootstrapPages(1), 0);
|
|
||||||
*PointerPte = *ValidPte;
|
|
||||||
|
|
||||||
/* Zero out the newly mapped page */
|
|
||||||
RTL::Memory::ZeroMemory(MM::Paging::GetPteVirtualAddress(PointerPte), MM_PAGE_SIZE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Move to the next PTE in the range */
|
|
||||||
PointerPte = MM::Paging::GetNextPte(PointerPte);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Set the pointer for the second list */
|
|
||||||
FreePages[1] = &FreePages[0][PagingColors];
|
|
||||||
|
|
||||||
/* Initialize all entries in both color tables */
|
|
||||||
for(Color = 0; Color < PagingColors; Color++)
|
|
||||||
{
|
|
||||||
/* Initialize the FreePageList entry for the current color */
|
|
||||||
FreePages[FreePageList][Color].Flink = MAXULONG_PTR;
|
|
||||||
FreePages[FreePageList][Color].Blink = (PVOID)MAXULONG_PTR;
|
|
||||||
FreePages[FreePageList][Color].Count = 0;
|
|
||||||
|
|
||||||
/* Initialize the ZeroedPageList entry for the current color */
|
|
||||||
FreePages[ZeroedPageList][Color].Flink = MAXULONG_PTR;
|
|
||||||
FreePages[ZeroedPageList][Color].Blink = (PVOID)MAXULONG_PTR;
|
|
||||||
FreePages[ZeroedPageList][Color].Count = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -9,21 +9,6 @@
|
|||||||
#include <xtos.hh>
|
#include <xtos.hh>
|
||||||
|
|
||||||
|
|
||||||
/* Array of non-paged pool free list heads */
|
|
||||||
LIST_ENTRY MM::Allocator::NonPagedPoolFreeList[MM_MAX_FREE_PAGE_LIST_HEADS];
|
|
||||||
|
|
||||||
/* Array of free page lists segregated by cache color */
|
|
||||||
PMMCOLOR_TABLES MM::Colors::FreePages[FreePageList + 1];
|
|
||||||
|
|
||||||
/* Array of modified pages segregated by cache color */
|
|
||||||
MMPFNLIST MM::Colors::ModifiedPages[MM_PAGING_COLORS] = {{0, ModifiedPageList, MAXULONG_PTR, MAXULONG_PTR}};
|
|
||||||
|
|
||||||
/* Number of supported page colors */
|
|
||||||
ULONG MM::Colors::PagingColors;
|
|
||||||
|
|
||||||
/* Bitmask used to calculate the cache color index */
|
|
||||||
ULONG MM::Colors::PagingColorsMask;
|
|
||||||
|
|
||||||
/* Allocation descriptors dedicated for hardware layer */
|
/* Allocation descriptors dedicated for hardware layer */
|
||||||
LOADER_MEMORY_DESCRIPTOR MM::HardwarePool::HardwareAllocationDescriptors[MM_HARDWARE_ALLOCATION_DESCRIPTORS];
|
LOADER_MEMORY_DESCRIPTOR MM::HardwarePool::HardwareAllocationDescriptors[MM_HARDWARE_ALLOCATION_DESCRIPTORS];
|
||||||
|
|
||||||
@@ -33,81 +18,23 @@ PVOID MM::HardwarePool::HardwareHeapStart = MM_HARDWARE_HEAP_START_ADDRESS;
|
|||||||
/* Number of used hardware allocation descriptors */
|
/* Number of used hardware allocation descriptors */
|
||||||
ULONG MM::HardwarePool::UsedHardwareAllocationDescriptors = 0;
|
ULONG MM::HardwarePool::UsedHardwareAllocationDescriptors = 0;
|
||||||
|
|
||||||
|
/* Biggest free memory descriptor */
|
||||||
|
PLOADER_MEMORY_DESCRIPTOR MM::Init::FreeDescriptor;
|
||||||
|
|
||||||
|
/* Highest physical page number */
|
||||||
|
ULONG_PTR MM::Init::HighestPhysicalPage;
|
||||||
|
|
||||||
|
/* Lowest physical page number */
|
||||||
|
ULONG_PTR MM::Init::LowestPhysicalPage = -1;
|
||||||
|
|
||||||
|
/* Number of physical pages */
|
||||||
|
ULONG MM::Init::NumberOfPhysicalPages;
|
||||||
|
|
||||||
|
/* Old biggest free memory descriptor */
|
||||||
|
LOADER_MEMORY_DESCRIPTOR MM::Init::OldFreeDescriptor;
|
||||||
|
|
||||||
/* Processor structures data (THIS IS A TEMPORARY HACK) */
|
/* Processor structures data (THIS IS A TEMPORARY HACK) */
|
||||||
UCHAR MM::KernelPool::ProcessorStructuresData[MAXIMUM_PROCESSORS][KPROCESSOR_STRUCTURES_SIZE] = {{0}};
|
UCHAR MM::KernelPool::ProcessorStructuresData[MAXIMUM_PROCESSORS][KPROCESSOR_STRUCTURES_SIZE] = {{0}};
|
||||||
|
|
||||||
/* Global structure describing the virtual memory layout of the system */
|
|
||||||
MMMEMORY_LAYOUT MM::Manager::MemoryLayout;
|
|
||||||
|
|
||||||
/* Total number of PTEs reserved for system space mapping */
|
|
||||||
PFN_NUMBER MM::Manager::NumberOfSystemPtes;
|
|
||||||
|
|
||||||
/* Instance of the page map routines for the current PML level */
|
/* Instance of the page map routines for the current PML level */
|
||||||
MM::PPAGEMAP MM::Paging::PmlRoutines;
|
MM::PPAGEMAP MM::Paging::PmlRoutines;
|
||||||
|
|
||||||
/* Total number of physical pages available for allocation */
|
|
||||||
PFN_NUMBER MM::Pfn::AvailablePages;
|
|
||||||
|
|
||||||
/* Head of the list containing physical pages marked as defective */
|
|
||||||
MMPFNLIST MM::Pfn::BadPagesList = {0, BadPageList, MAXULONG_PTR, MAXULONG_PTR};
|
|
||||||
|
|
||||||
/* Biggest free memory descriptor */
|
|
||||||
PLOADER_MEMORY_DESCRIPTOR MM::Pfn::FreeDescriptor;
|
|
||||||
|
|
||||||
/* List containing free physical pages */
|
|
||||||
MMPFNLIST MM::Pfn::FreePagesList = {0, FreePageList, MAXULONG_PTR, MAXULONG_PTR};
|
|
||||||
|
|
||||||
/* Highest physical page number */
|
|
||||||
ULONG_PTR MM::Pfn::HighestPhysicalPage;
|
|
||||||
|
|
||||||
/* Lowest physical page number */
|
|
||||||
ULONG_PTR MM::Pfn::LowestPhysicalPage = -1;
|
|
||||||
|
|
||||||
/* List containing modified pages */
|
|
||||||
MMPFNLIST MM::Pfn::ModifiedPagesList = {0, ModifiedPageList, MAXULONG_PTR, MAXULONG_PTR};
|
|
||||||
|
|
||||||
/* List containing modified pages mapped as read-only */
|
|
||||||
MMPFNLIST MM::Pfn::ModifiedReadOnlyPagesList = {0, ModifiedReadOnlyPageList, MAXULONG_PTR, MAXULONG_PTR};
|
|
||||||
|
|
||||||
/* Number of physical pages */
|
|
||||||
ULONGLONG MM::Pfn::NumberOfPhysicalPages;
|
|
||||||
|
|
||||||
/* Old biggest free memory descriptor */
|
|
||||||
LOADER_MEMORY_DESCRIPTOR MM::Pfn::OriginalFreeDescriptor;
|
|
||||||
|
|
||||||
/* Array of pointers to PFN lists */
|
|
||||||
PMMPFNLIST MM::Pfn::PageLocationList[] = {&ZeroedPagesList,
|
|
||||||
&FreePagesList,
|
|
||||||
&StandbyPagesList,
|
|
||||||
&ModifiedPagesList,
|
|
||||||
&ModifiedReadOnlyPagesList,
|
|
||||||
&BadPagesList,
|
|
||||||
NULLPTR,
|
|
||||||
NULLPTR};
|
|
||||||
|
|
||||||
/* List containing pages mapped as Read-Only (ROM) */
|
|
||||||
MMPFNLIST MM::Pfn::RomPagesList = {0, StandbyPageList, MAXULONG_PTR, MAXULONG_PTR};
|
|
||||||
|
|
||||||
/* List containing standby pages (clean, can be reclaimed or repurposed) */
|
|
||||||
MMPFNLIST MM::Pfn::StandbyPagesList = {0, StandbyPageList, MAXULONG_PTR, MAXULONG_PTR};
|
|
||||||
|
|
||||||
/* List containing free physical pages that have been zeroed out */
|
|
||||||
MMPFNLIST MM::Pfn::ZeroedPagesList = {0, ZeroedPageList, MAXULONG_PTR, MAXULONG_PTR};
|
|
||||||
|
|
||||||
/* Array of lists for available System PTEs, separated by pool type */
|
|
||||||
MMPTE MM::Pte::FirstSystemFreePte[MaximumPtePoolTypes];
|
|
||||||
|
|
||||||
/* Virtual base address of the System PTE space */
|
|
||||||
PMMPTE MM::Pte::SystemPteBase;
|
|
||||||
|
|
||||||
/* End addresses for the System PTE ranges */
|
|
||||||
PMMPTE MM::Pte::SystemPtesEnd[MaximumPtePoolTypes];
|
|
||||||
|
|
||||||
/* Start addresses for the System PTE ranges */
|
|
||||||
PMMPTE MM::Pte::SystemPtesStart[MaximumPtePoolTypes];
|
|
||||||
|
|
||||||
/* Total count of available System PTEs */
|
|
||||||
PFN_COUNT MM::Pte::TotalSystemFreePtes[MaximumPtePoolTypes];
|
|
||||||
|
|
||||||
/* Template PTE entry containing standard flags for a valid, present kernel page */
|
|
||||||
MMPTE MM::Pte::ValidPte;
|
|
||||||
|
|||||||
@@ -170,7 +170,7 @@ MM::HardwarePool::MapHardwareMemory(IN PHYSICAL_ADDRESS PhysicalAddress,
|
|||||||
{
|
{
|
||||||
PVOID BaseAddress, ReturnAddress;
|
PVOID BaseAddress, ReturnAddress;
|
||||||
PFN_NUMBER MappedPages;
|
PFN_NUMBER MappedPages;
|
||||||
PMMPTE PtePointer;
|
PHARDWARE_PTE PtePointer;
|
||||||
|
|
||||||
/* Initialize variables */
|
/* Initialize variables */
|
||||||
BaseAddress = HardwareHeapStart;
|
BaseAddress = HardwareHeapStart;
|
||||||
@@ -189,7 +189,7 @@ MM::HardwarePool::MapHardwareMemory(IN PHYSICAL_ADDRESS PhysicalAddress,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Get PTE pointer and advance to next page */
|
/* Get PTE pointer and advance to next page */
|
||||||
PtePointer = MM::Paging::GetPteAddress(ReturnAddress);
|
PtePointer = (PHARDWARE_PTE)MM::Paging::GetPteAddress(ReturnAddress);
|
||||||
ReturnAddress = (PVOID)((ULONG_PTR)ReturnAddress + MM_PAGE_SIZE);
|
ReturnAddress = (PVOID)((ULONG_PTR)ReturnAddress + MM_PAGE_SIZE);
|
||||||
|
|
||||||
/* Check if PTE is valid */
|
/* Check if PTE is valid */
|
||||||
@@ -219,10 +219,10 @@ MM::HardwarePool::MapHardwareMemory(IN PHYSICAL_ADDRESS PhysicalAddress,
|
|||||||
while(MappedPages--)
|
while(MappedPages--)
|
||||||
{
|
{
|
||||||
/* Get PTE pointer */
|
/* Get PTE pointer */
|
||||||
PtePointer = MM::Paging::GetPteAddress(BaseAddress);
|
PtePointer = (PHARDWARE_PTE)MM::Paging::GetPteAddress(BaseAddress);
|
||||||
|
|
||||||
/* Fill the PTE */
|
/* Fill the PTE */
|
||||||
MM::Paging::SetPte(PtePointer, (PFN_NUMBER)(PhysicalAddress.QuadPart >> MM_PAGE_SHIFT), MM_PTE_READWRITE);
|
MM::Paging::SetPte(PtePointer, (PFN_NUMBER)(PhysicalAddress.QuadPart >> MM_PAGE_SHIFT), TRUE);
|
||||||
|
|
||||||
/* Advance to the next address */
|
/* Advance to the next address */
|
||||||
PhysicalAddress.QuadPart += MM_PAGE_SIZE;
|
PhysicalAddress.QuadPart += MM_PAGE_SIZE;
|
||||||
@@ -259,18 +259,18 @@ VOID
|
|||||||
MM::HardwarePool::MarkHardwareMemoryWriteThrough(IN PVOID VirtualAddress,
|
MM::HardwarePool::MarkHardwareMemoryWriteThrough(IN PVOID VirtualAddress,
|
||||||
IN PFN_NUMBER PageCount)
|
IN PFN_NUMBER PageCount)
|
||||||
{
|
{
|
||||||
PMMPTE PtePointer;
|
PHARDWARE_PTE PtePointer;
|
||||||
PFN_NUMBER Page;
|
PFN_NUMBER Page;
|
||||||
|
|
||||||
/* Get PTE address from virtual address */
|
/* Get PTE address from virtual address */
|
||||||
PtePointer = MM::Paging::GetPteAddress(VirtualAddress);
|
PtePointer = (PHARDWARE_PTE)MM::Paging::GetPteAddress(VirtualAddress);
|
||||||
|
|
||||||
/* Iterate through mapped pages */
|
/* Iterate through mapped pages */
|
||||||
for(Page = 0; Page < PageCount; Page++)
|
for(Page = 0; Page < PageCount; Page++)
|
||||||
{
|
{
|
||||||
/* Mark pages as CD/WT */
|
/* Mark pages as CD/WT */
|
||||||
MM::Paging::SetPteCaching(PtePointer, TRUE, TRUE);
|
MM::Paging::SetPteCaching(PtePointer, TRUE, TRUE);
|
||||||
MM::Paging::GetNextEntry(PtePointer);
|
PtePointer++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -296,13 +296,13 @@ MM::HardwarePool::RemapHardwareMemory(IN PVOID VirtualAddress,
|
|||||||
IN PHYSICAL_ADDRESS PhysicalAddress,
|
IN PHYSICAL_ADDRESS PhysicalAddress,
|
||||||
IN BOOLEAN FlushTlb)
|
IN BOOLEAN FlushTlb)
|
||||||
{
|
{
|
||||||
PMMPTE PtePointer;
|
PHARDWARE_PTE PtePointer;
|
||||||
|
|
||||||
/* Get PTE address from virtual address */
|
/* Get PTE address from virtual address */
|
||||||
PtePointer = MM::Paging::GetPteAddress(VirtualAddress);
|
PtePointer = (PHARDWARE_PTE)MM::Paging::GetPteAddress(VirtualAddress);
|
||||||
|
|
||||||
/* Remap the PTE */
|
/* Remap the PTE */
|
||||||
MM::Paging::SetPte(PtePointer, (PFN_NUMBER)(PhysicalAddress.QuadPart >> MM_PAGE_SHIFT), MM_PTE_READWRITE);
|
MM::Paging::SetPte(PtePointer, (PFN_NUMBER)(PhysicalAddress.QuadPart >> MM_PAGE_SHIFT), TRUE);
|
||||||
|
|
||||||
/* Check if TLB needs to be flushed */
|
/* Check if TLB needs to be flushed */
|
||||||
if(FlushTlb)
|
if(FlushTlb)
|
||||||
@@ -334,7 +334,7 @@ MM::HardwarePool::UnmapHardwareMemory(IN PVOID VirtualAddress,
|
|||||||
IN PFN_NUMBER PageCount,
|
IN PFN_NUMBER PageCount,
|
||||||
IN BOOLEAN FlushTlb)
|
IN BOOLEAN FlushTlb)
|
||||||
{
|
{
|
||||||
PMMPTE PtePointer;
|
PHARDWARE_PTE PtePointer;
|
||||||
PFN_NUMBER Page;
|
PFN_NUMBER Page;
|
||||||
|
|
||||||
/* Check if address is valid hardware memory */
|
/* Check if address is valid hardware memory */
|
||||||
@@ -348,7 +348,7 @@ MM::HardwarePool::UnmapHardwareMemory(IN PVOID VirtualAddress,
|
|||||||
VirtualAddress = (PVOID)((ULONG_PTR)VirtualAddress & ~(MM_PAGE_SIZE - 1));
|
VirtualAddress = (PVOID)((ULONG_PTR)VirtualAddress & ~(MM_PAGE_SIZE - 1));
|
||||||
|
|
||||||
/* Get PTE address from virtual address */
|
/* Get PTE address from virtual address */
|
||||||
PtePointer = MM::Paging::GetPteAddress(VirtualAddress);
|
PtePointer = (PHARDWARE_PTE)MM::Paging::GetPteAddress(VirtualAddress);
|
||||||
|
|
||||||
/* Iterate through mapped pages */
|
/* Iterate through mapped pages */
|
||||||
for(Page = 0; Page < PageCount; Page++)
|
for(Page = 0; Page < PageCount; Page++)
|
||||||
|
|||||||
@@ -1,31 +0,0 @@
|
|||||||
/**
|
|
||||||
* PROJECT: ExectOS
|
|
||||||
* COPYRIGHT: See COPYING.md in the top level directory
|
|
||||||
* FILE: xtoskrnl/mm/i686/alloc.cc
|
|
||||||
* DESCRIPTION: Memory manager pool allocation
|
|
||||||
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <xtos.hh>
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Maps the PTE for the base of the non-paged pool.
|
|
||||||
*
|
|
||||||
* @return This routine does not return any value.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
VOID
|
|
||||||
MM::Allocator::MapNonPagedPool(VOID)
|
|
||||||
{
|
|
||||||
PMMMEMORY_LAYOUT MemoryLayout;
|
|
||||||
|
|
||||||
/* Retrieve memory layout */
|
|
||||||
MemoryLayout = MM::Manager::GetMemoryLayout();
|
|
||||||
|
|
||||||
/* Map PDE and PTE for the base of the non-paged pool */
|
|
||||||
MM::Pte::MapPDE(MemoryLayout->NonPagedPoolStart, (PCHAR)MemoryLayout->NonPagedPoolEnd - 1, MM::Pte::GetValidPte());
|
|
||||||
MM::Pte::MapPTE(MemoryLayout->NonPagedPoolStart, (PCHAR)MemoryLayout->NonPagedPoolEnd - 1, MM::Pte::GetValidPte());
|
|
||||||
}
|
|
||||||
25
xtoskrnl/mm/i686/init.cc
Normal file
25
xtoskrnl/mm/i686/init.cc
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
/**
|
||||||
|
* PROJECT: ExectOS
|
||||||
|
* COPYRIGHT: See COPYING.md in the top level directory
|
||||||
|
* FILE: xtoskrnl/mm/i686/init.cc
|
||||||
|
* DESCRIPTION: Architecture specific Memory Manager initialization routines
|
||||||
|
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||||
|
* Aiken Harris <harraiken91@gmail.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <xtos.hh>
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Performs architecture specific initialization of the XTOS Memory Manager.
|
||||||
|
*
|
||||||
|
* @return This routine does not return any value.
|
||||||
|
*
|
||||||
|
* @since XT 1.0
|
||||||
|
*/
|
||||||
|
XTAPI
|
||||||
|
VOID
|
||||||
|
MM::Init::InitializeArchitecture(VOID)
|
||||||
|
{
|
||||||
|
UNIMPLEMENTED;
|
||||||
|
}
|
||||||
@@ -1,445 +0,0 @@
|
|||||||
/**
|
|
||||||
* PROJECT: ExectOS
|
|
||||||
* COPYRIGHT: See COPYING.md in the top level directory
|
|
||||||
* FILE: xtoskrnl/mm/i686/mmgr.cc
|
|
||||||
* DESCRIPTION: Memory Manager
|
|
||||||
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <xtos.hh>
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Calculates the maximum possible size of the non-paged pool.
|
|
||||||
*
|
|
||||||
* @param PoolSize
|
|
||||||
* A pointer to a variable that will receive the number of pages available for the non-paged pool.
|
|
||||||
*
|
|
||||||
* @return This routine does not return any value.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
VOID
|
|
||||||
MM::Manager::ComputeMaximumNonPagedPoolSize(OUT PPFN_NUMBER PoolSize)
|
|
||||||
{
|
|
||||||
ULONG_PTR MaximumNonPagedPoolSize;
|
|
||||||
ULONGLONG PhysicalPages;
|
|
||||||
|
|
||||||
/* Get number of physical pages */
|
|
||||||
PhysicalPages = MM::Pfn::GetNumberOfPhysicalPages();
|
|
||||||
|
|
||||||
/* Start with 1MiB and reserve space for PFN database */
|
|
||||||
MaximumNonPagedPoolSize = 1048576;
|
|
||||||
|
|
||||||
/* Check if system has at least 512MiB of physical memory */
|
|
||||||
if(PhysicalPages >= 126976)
|
|
||||||
{
|
|
||||||
/* Add 200KiB for each MiB above 4MiB */
|
|
||||||
MaximumNonPagedPoolSize += ((PhysicalPages - 1024)/256) * 204800;
|
|
||||||
|
|
||||||
/* Check if non-paged pool has at least 128MiB */
|
|
||||||
if(MaximumNonPagedPoolSize < 134217728)
|
|
||||||
{
|
|
||||||
/* Expand non-paged pool size to 128MiB */
|
|
||||||
MaximumNonPagedPoolSize = 134217728;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Add 400KiB for each MiB above 4MiB */
|
|
||||||
MaximumNonPagedPoolSize += ((PhysicalPages - 1024)/256) * 409600;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check if non-paged pool does not exceed 256MiB */
|
|
||||||
if(MaximumNonPagedPoolSize > 268435456)
|
|
||||||
{
|
|
||||||
/* Limit non-paged pool size to 256MiB */
|
|
||||||
MaximumNonPagedPoolSize = 268435456;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Return maximum non-paged pool size in pages */
|
|
||||||
*PoolSize = SIZE_TO_PAGES(MaximumNonPagedPoolSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Calculates the size of the non-paged pool.
|
|
||||||
*
|
|
||||||
* @param PoolSize
|
|
||||||
* A pointer to a variable that will receive the number of pages available for the non-paged pool.
|
|
||||||
*
|
|
||||||
* @return This routine does not return any value.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
VOID
|
|
||||||
MM::Manager::ComputeNonPagedPoolSize(OUT PPFN_NUMBER PoolSize)
|
|
||||||
{
|
|
||||||
ULONG_PTR NonPagedPoolSize;
|
|
||||||
ULONGLONG PhysicalPages;
|
|
||||||
|
|
||||||
/* Get number of physical pages */
|
|
||||||
PhysicalPages = MM::Pfn::GetNumberOfPhysicalPages();
|
|
||||||
|
|
||||||
/* Verify if system has less than 256MiB of physical memory */
|
|
||||||
if(PhysicalPages <= 65536)
|
|
||||||
{
|
|
||||||
/* Reduce initial non-paged pool size to 2MiB to save memory */
|
|
||||||
NonPagedPoolSize = 2097152;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Start with 256KiB and add 32KiB for each MiB above 4MiB */
|
|
||||||
NonPagedPoolSize = 262144 + (((PhysicalPages - 1024) / 256) * 32768);
|
|
||||||
|
|
||||||
if(NonPagedPoolSize > 134217728)
|
|
||||||
{
|
|
||||||
/* Limit non-paged pool size to 128MiB */
|
|
||||||
NonPagedPoolSize = 134217728;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Return non-paged pool size in pages, aligned down to page size boundary */
|
|
||||||
*PoolSize = SIZE_TO_PAGES(ROUND_DOWN(NonPagedPoolSize, MM_PAGE_SIZE));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Calculates the size of the paged pool.
|
|
||||||
*
|
|
||||||
* @param PoolSize
|
|
||||||
* A pointer to a variable that will receive the number of pages available for the paged pool.
|
|
||||||
*
|
|
||||||
* @return This routine does not return any value.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
VOID
|
|
||||||
MM::Manager::ComputePagedPoolSize(OUT PPFN_NUMBER PoolSize)
|
|
||||||
{
|
|
||||||
ULONG_PTR PagedPoolSize, PteCount;
|
|
||||||
ULONG PtesPerPage;
|
|
||||||
|
|
||||||
/* Start with maximum non-paged pool size */
|
|
||||||
ComputeMaximumNonPagedPoolSize(&PagedPoolSize);
|
|
||||||
PagedPoolSize *= MM_PAGE_SIZE;
|
|
||||||
|
|
||||||
/* Check XPA status */
|
|
||||||
if(MM::Paging::GetXpaStatus())
|
|
||||||
{
|
|
||||||
/* Four times the non-paged pool size on PAE-enabled systems */
|
|
||||||
PagedPoolSize *= 4;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Double the non-paged pool size on PAE-disabled systems */
|
|
||||||
PagedPoolSize *= 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check if paged pool does not overlap non-paged pool */
|
|
||||||
if(PagedPoolSize > (ULONG_PTR)MemoryLayout.NonPagedSystemPoolStart - (ULONG_PTR)MemoryLayout.PagedPoolStart)
|
|
||||||
{
|
|
||||||
/* Limit paged pool size to maximum possible */
|
|
||||||
PagedPoolSize = (ULONG_PTR)MemoryLayout.NonPagedSystemPoolStart - (ULONG_PTR)MemoryLayout.PagedPoolStart;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Ensure that paged pool size is at least 32MiB */
|
|
||||||
if(PagedPoolSize < 33554432)
|
|
||||||
{
|
|
||||||
/* Increase paged pool size to at least 32MiB */
|
|
||||||
PagedPoolSize = 33554432;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get the number of PTEs per page and calculate size of paged pool */
|
|
||||||
PtesPerPage = MM::Pte::GetPtesPerPage();
|
|
||||||
PteCount = ((SIZE_TO_PAGES(PagedPoolSize) + (PtesPerPage - 1)) / PtesPerPage);
|
|
||||||
|
|
||||||
/* Return paged pool size */
|
|
||||||
*PoolSize = (PFN_NUMBER)(PteCount * PtesPerPage);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Calculates the size of the session space.
|
|
||||||
*
|
|
||||||
* @param SpaceSize
|
|
||||||
* A pointer to a variable that will receive the number of pages available by the session space.
|
|
||||||
*
|
|
||||||
* @return This routine does not return any value.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
VOID
|
|
||||||
MM::Manager::ComputeSessionSpaceSize(OUT PPFN_NUMBER SpaceSize)
|
|
||||||
{
|
|
||||||
PFN_NUMBER SessionSpaceSize;
|
|
||||||
|
|
||||||
/* Session Pool, Session View, Session Image, Session Working Set and System View takes 108MiB */
|
|
||||||
SessionSpaceSize = 113246208;
|
|
||||||
|
|
||||||
/* Return number of pages used by the session space */
|
|
||||||
*SpaceSize = SessionSpaceSize / MM_PAGE_SIZE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Calculates the size of the system PTEs.
|
|
||||||
*
|
|
||||||
* @param PteSize
|
|
||||||
* A pointer to a variable that will receive the number of system PTEs.
|
|
||||||
*
|
|
||||||
* @return This routine does not return any value.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
VOID
|
|
||||||
MM::Manager::ComputeSystemPteSize(OUT PPFN_NUMBER PteSize)
|
|
||||||
{
|
|
||||||
PFN_NUMBER SystemPteSize;
|
|
||||||
|
|
||||||
/* Check if system has less than 19MiB of physical memory */
|
|
||||||
if(MM::Pfn::GetNumberOfPhysicalPages() < 4864)
|
|
||||||
{
|
|
||||||
/* Set minimal system PTE size */
|
|
||||||
SystemPteSize = 7000;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Use standard system PTE size */
|
|
||||||
SystemPteSize = 11000;
|
|
||||||
|
|
||||||
/* Check if system has more than 32MiB of physical memory */
|
|
||||||
if(MM::Pfn::GetNumberOfPhysicalPages() > 8192)
|
|
||||||
{
|
|
||||||
/* Double system PTE size */
|
|
||||||
SystemPteSize *= 2;
|
|
||||||
|
|
||||||
/* Check if system has more than 256MiB of physical memory */
|
|
||||||
if(MM::Pfn::GetNumberOfPhysicalPages() > 65536)
|
|
||||||
{
|
|
||||||
/* Double system PTE size */
|
|
||||||
SystemPteSize *= 2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Return system PTE size */
|
|
||||||
*PteSize = SystemPteSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Dumps the kernel's memory layout.
|
|
||||||
*
|
|
||||||
* @return This routine does not return any value.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
VOID
|
|
||||||
MM::Manager::DumpMemoryLayout(VOID)
|
|
||||||
{
|
|
||||||
/* Dump memory layout */
|
|
||||||
DebugPrint(L"System with %zu MiB of installed memory:\n"
|
|
||||||
L"User Space: %.8P - %.8P\n"
|
|
||||||
L"Loader Mappings: %.8P - %.8P\n"
|
|
||||||
L"PFN Database: %.8P - %.8P\n"
|
|
||||||
L"Non-Paged Pool: %.8P - %.8P\n"
|
|
||||||
L"Session Space: %.8P - %.8P\n"
|
|
||||||
L"PTE Space: %.8P - %.8P\n"
|
|
||||||
L"Hyper Space: %.8P - %.8P\n"
|
|
||||||
L"System Working Set: %.8P - %.8P\n"
|
|
||||||
L"System Cache: %.8P - %.8P\n"
|
|
||||||
L"Paged Pool: %.8P - %.8P\n"
|
|
||||||
L"Non-Paged System Pool: %.8P - %.8P\n"
|
|
||||||
L"Non-Paged Expansion Pool: %.8P - %.8P\n"
|
|
||||||
L"Shared System Page: %.8P - %.8P\n"
|
|
||||||
L"Hardware Pool: %.8P - %.8P\n",
|
|
||||||
GetInstalledMemorySize(),
|
|
||||||
MemoryLayout.UserSpaceStart,
|
|
||||||
MemoryLayout.UserSpaceEnd,
|
|
||||||
MemoryLayout.LoaderMappingsStart,
|
|
||||||
MemoryLayout.LoaderMappingsEnd,
|
|
||||||
MemoryLayout.PfnDatabase,
|
|
||||||
(PVOID)((ULONG_PTR)MemoryLayout.PfnDatabase + (ULONG_PTR)MemoryLayout.PfnDatabaseSize * MM_PAGE_SIZE),
|
|
||||||
MemoryLayout.NonPagedPoolStart,
|
|
||||||
MemoryLayout.NonPagedPoolEnd,
|
|
||||||
MemoryLayout.SessionSpaceStart,
|
|
||||||
MemoryLayout.SessionSpaceEnd,
|
|
||||||
MemoryLayout.PteSpaceStart,
|
|
||||||
MemoryLayout.PteSpaceEnd,
|
|
||||||
MemoryLayout.HyperSpaceStart,
|
|
||||||
MemoryLayout.HyperSpaceEnd,
|
|
||||||
MemoryLayout.SystemWorkingSetStart,
|
|
||||||
MemoryLayout.SystemWorkingSetEnd,
|
|
||||||
MemoryLayout.SystemCacheStart,
|
|
||||||
MemoryLayout.SystemCacheEnd,
|
|
||||||
MemoryLayout.PagedPoolStart,
|
|
||||||
MemoryLayout.PagedPoolEnd,
|
|
||||||
MemoryLayout.NonPagedSystemPoolStart,
|
|
||||||
MemoryLayout.NonPagedSystemPoolEnd,
|
|
||||||
MemoryLayout.NonPagedExpansionPoolStart,
|
|
||||||
MemoryLayout.NonPagedExpansionPoolEnd,
|
|
||||||
MemoryLayout.SharedSystemPageStart,
|
|
||||||
MemoryLayout.SharedSystemPageEnd,
|
|
||||||
MemoryLayout.HardwarePoolStart,
|
|
||||||
MemoryLayout.HardwarePoolEnd);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initializes the kernel's virtual memory layout.
|
|
||||||
*
|
|
||||||
* @return This routine does not return any value.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
VOID
|
|
||||||
MM::Manager::InitializeMemoryLayout(VOID)
|
|
||||||
{
|
|
||||||
PFN_NUMBER MaximumNonPagedPoolSize;
|
|
||||||
ULONG_PTR PfnDatabaseEnd;
|
|
||||||
|
|
||||||
/* Check if 3-level paging (PAE) is enabled */
|
|
||||||
if(MM::Paging::GetXpaStatus())
|
|
||||||
{
|
|
||||||
/* Set PML3 base address */
|
|
||||||
MemoryLayout.SelfMapAddress = (PVOID)MM_PTE_BASE;
|
|
||||||
|
|
||||||
/* Define memory layout for 3-level paging */
|
|
||||||
MemoryLayout.NonCanonicalStart = (PVOID)0x00000000;
|
|
||||||
MemoryLayout.NonCanonicalEnd = (PVOID)0x00000000;
|
|
||||||
MemoryLayout.ReservedSystemPoolStart = (PVOID)0x00000000;
|
|
||||||
MemoryLayout.ReservedSystemPoolEnd = (PVOID)0x00000000;
|
|
||||||
MemoryLayout.UserSpaceStart = (PVOID)0x00010000;
|
|
||||||
MemoryLayout.UserSpaceEnd = (PVOID)0x7FFEFFFF;
|
|
||||||
MemoryLayout.LoaderMappingsStart = (PVOID)0x80000000;
|
|
||||||
MemoryLayout.LoaderMappingsEnd = (PVOID)0x90000000;
|
|
||||||
MemoryLayout.NonPagedPoolStart = (PVOID)0x90000000;
|
|
||||||
MemoryLayout.NonPagedPoolEnd = (PVOID)0xB0000000;
|
|
||||||
MemoryLayout.SessionSpaceStart = (PVOID)0xB0000000;
|
|
||||||
MemoryLayout.SessionSpaceEnd = (PVOID)0xC0000000;
|
|
||||||
MemoryLayout.PteSpaceStart = (PVOID)0xC0000000;
|
|
||||||
MemoryLayout.PteSpaceEnd = (PVOID)0xC07FFFFF;
|
|
||||||
MemoryLayout.HyperSpaceStart = (PVOID)0xC0800000;
|
|
||||||
MemoryLayout.HyperSpaceEnd = (PVOID)0xC0BFFFFF;
|
|
||||||
MemoryLayout.SystemWorkingSetStart = (PVOID)0xC0C00000;
|
|
||||||
MemoryLayout.SystemWorkingSetEnd = (PVOID)0xC0FFFFFF;
|
|
||||||
MemoryLayout.SystemCacheStart = (PVOID)0xC1000000;
|
|
||||||
MemoryLayout.SystemCacheEnd = (PVOID)0xE0FFFFFF;
|
|
||||||
MemoryLayout.PagedPoolStart = (PVOID)0xE1000000;
|
|
||||||
MemoryLayout.PagedPoolEnd = (PVOID)0xECC00000;
|
|
||||||
MemoryLayout.NonPagedSystemPoolStart = (PVOID)0xECC00000;
|
|
||||||
MemoryLayout.NonPagedSystemPoolEnd = (PVOID)0xF7BE0000;
|
|
||||||
MemoryLayout.NonPagedExpansionPoolStart = (PVOID)0xF7BE0000;
|
|
||||||
MemoryLayout.NonPagedExpansionPoolEnd = (PVOID)0xFFBFF000;
|
|
||||||
MemoryLayout.SharedSystemPageStart = (PVOID)0xFFBFF000;
|
|
||||||
MemoryLayout.SharedSystemPageEnd = (PVOID)0xFFC00000;
|
|
||||||
MemoryLayout.HardwarePoolStart = (PVOID)0xFFC00000;
|
|
||||||
MemoryLayout.HardwarePoolEnd = (PVOID)0xFFFFFFFF;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Set PML2 base address */
|
|
||||||
MemoryLayout.SelfMapAddress = (PVOID)MM_PTE_BASE;
|
|
||||||
|
|
||||||
/* Define memory layout for 2-level paging */
|
|
||||||
MemoryLayout.NonCanonicalStart = (PVOID)0x00000000;
|
|
||||||
MemoryLayout.NonCanonicalEnd = (PVOID)0x00000000;
|
|
||||||
MemoryLayout.ReservedSystemPoolStart = (PVOID)0x00000000;
|
|
||||||
MemoryLayout.ReservedSystemPoolEnd = (PVOID)0x00000000;
|
|
||||||
MemoryLayout.UserSpaceStart = (PVOID)0x00010000;
|
|
||||||
MemoryLayout.UserSpaceEnd = (PVOID)0x7FFEFFFF;
|
|
||||||
MemoryLayout.LoaderMappingsStart = (PVOID)0x80000000;
|
|
||||||
MemoryLayout.LoaderMappingsEnd = (PVOID)0x90000000;
|
|
||||||
MemoryLayout.NonPagedPoolStart = (PVOID)0x90000000;
|
|
||||||
MemoryLayout.NonPagedPoolEnd = (PVOID)0xB0000000;
|
|
||||||
MemoryLayout.SessionSpaceStart = (PVOID)0xB0000000;
|
|
||||||
MemoryLayout.SessionSpaceEnd = (PVOID)0xC0000000;
|
|
||||||
MemoryLayout.PteSpaceStart = (PVOID)0xC0000000;
|
|
||||||
MemoryLayout.PteSpaceEnd = (PVOID)0xC03FFFFF;
|
|
||||||
MemoryLayout.HyperSpaceStart = (PVOID)0xC0400000;
|
|
||||||
MemoryLayout.HyperSpaceEnd = (PVOID)0xC07FFFFF;
|
|
||||||
MemoryLayout.SystemWorkingSetStart = (PVOID)0xC0C00000;
|
|
||||||
MemoryLayout.SystemWorkingSetEnd = (PVOID)0xC0FFFFFF;
|
|
||||||
MemoryLayout.SystemCacheStart = (PVOID)0xC1000000;
|
|
||||||
MemoryLayout.SystemCacheEnd = (PVOID)0xE0FFFFFF;
|
|
||||||
MemoryLayout.PagedPoolStart = (PVOID)0xE1000000;
|
|
||||||
MemoryLayout.PagedPoolEnd = (PVOID)0xECC00000;
|
|
||||||
MemoryLayout.NonPagedSystemPoolStart = (PVOID)0xECC00000;
|
|
||||||
MemoryLayout.NonPagedSystemPoolEnd = (PVOID)0xF7BE0000;
|
|
||||||
MemoryLayout.NonPagedExpansionPoolStart = (PVOID)0xF7BE0000;
|
|
||||||
MemoryLayout.NonPagedExpansionPoolEnd = (PVOID)0xFFBFF000;
|
|
||||||
MemoryLayout.SharedSystemPageStart = (PVOID)0xFFBFF000;
|
|
||||||
MemoryLayout.SharedSystemPageEnd = (PVOID)0xFFC00000;
|
|
||||||
MemoryLayout.HardwarePoolStart = (PVOID)0xFFC00000;
|
|
||||||
MemoryLayout.HardwarePoolEnd = (PVOID)0xFFFFFFFF;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Compute allocation size for the PFN database */
|
|
||||||
MM::Pfn::ComputePfnDatabaseSize(&MemoryLayout.PfnDatabaseSize);
|
|
||||||
|
|
||||||
/* Compute boot image size */
|
|
||||||
ComputeBootImageSize(&MemoryLayout.LoaderMappingsSize);
|
|
||||||
|
|
||||||
/* Compute session space size */
|
|
||||||
ComputeSessionSpaceSize(&MemoryLayout.SessionSpaceSize);
|
|
||||||
|
|
||||||
/* Update loader mappings space end address */
|
|
||||||
MemoryLayout.LoaderMappingsEnd = (PVOID)((ULONG_PTR)MemoryLayout.LoaderMappingsStart +
|
|
||||||
MemoryLayout.LoaderMappingsSize * MM_PAGE_SIZE);
|
|
||||||
|
|
||||||
/* Update session space start address */
|
|
||||||
MemoryLayout.SessionSpaceStart = (PVOID)((ULONGLONG)MemoryLayout.SessionSpaceEnd -
|
|
||||||
MemoryLayout.SessionSpaceSize * MM_PAGE_SIZE);
|
|
||||||
|
|
||||||
/* Compute system PTE size */
|
|
||||||
ComputeSystemPteSize(&NumberOfSystemPtes);
|
|
||||||
|
|
||||||
/* Compute the initial and maximum non-paged pool sizes */
|
|
||||||
ComputeNonPagedPoolSize(&MemoryLayout.NonPagedPoolSize);
|
|
||||||
ComputeMaximumNonPagedPoolSize(&MaximumNonPagedPoolSize);
|
|
||||||
|
|
||||||
/* Compute paged pool size */
|
|
||||||
ComputePagedPoolSize(&MemoryLayout.PagedPoolSize);
|
|
||||||
|
|
||||||
/* Position the PFN database right after the loader mappings */
|
|
||||||
MemoryLayout.PfnDatabase = (PMMPFN)MemoryLayout.LoaderMappingsEnd;
|
|
||||||
|
|
||||||
/* Compute the PFN database end address */
|
|
||||||
PfnDatabaseEnd = (ULONG_PTR)MemoryLayout.PfnDatabase + (MemoryLayout.PfnDatabaseSize * MM_PAGE_SIZE);
|
|
||||||
|
|
||||||
/* Position the initial non-paged pool immediately after the PFN database */
|
|
||||||
MemoryLayout.NonPagedPoolStart = (PVOID)PfnDatabaseEnd;
|
|
||||||
|
|
||||||
/* Check if the calculated non-paged pool size fits in the KVA */
|
|
||||||
if((MemoryLayout.NonPagedPoolSize * MM_PAGE_SIZE) >
|
|
||||||
((ULONG_PTR)MemoryLayout.SessionSpaceStart - (ULONG_PTR)MemoryLayout.NonPagedPoolStart))
|
|
||||||
{
|
|
||||||
/* Set the final size for the non-paged pool */
|
|
||||||
MemoryLayout.NonPagedPoolSize = ((ULONG_PTR)MemoryLayout.NonPagedPoolEnd -
|
|
||||||
(ULONG_PTR)MemoryLayout.NonPagedPoolStart) / MM_PAGE_SIZE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Set the final non-paged pool end address */
|
|
||||||
MemoryLayout.NonPagedPoolEnd = (PVOID)((ULONG_PTR)MemoryLayout.NonPagedPoolStart +
|
|
||||||
MemoryLayout.NonPagedPoolSize * MM_PAGE_SIZE);
|
|
||||||
|
|
||||||
/* Check if non-paged expansion pool overflows */
|
|
||||||
if((ULONG_PTR)MemoryLayout.NonPagedExpansionPoolStart + MaximumNonPagedPoolSize *
|
|
||||||
MM_PAGE_SIZE >= (ULONG_PTR)MemoryLayout.NonPagedExpansionPoolStart)
|
|
||||||
{
|
|
||||||
/* Check if non-paged expansion pool fits */
|
|
||||||
if((ULONG_PTR)MemoryLayout.NonPagedExpansionPoolStart + MaximumNonPagedPoolSize *
|
|
||||||
MM_PAGE_SIZE <= (ULONG_PTR)MemoryLayout.NonPagedExpansionPoolEnd)
|
|
||||||
{
|
|
||||||
/* Set new non-paged expansion pool end address */
|
|
||||||
MemoryLayout.NonPagedExpansionPoolEnd = (PVOID)((ULONG_PTR)MemoryLayout.NonPagedExpansionPoolStart +
|
|
||||||
MaximumNonPagedPoolSize * MM_PAGE_SIZE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Compute non-paged expansion pool size */
|
|
||||||
MemoryLayout.NonPagedExpansionPoolSize = ((ULONG_PTR)MemoryLayout.NonPagedExpansionPoolEnd -
|
|
||||||
(ULONG_PTR)MemoryLayout.NonPagedExpansionPoolStart) / MM_PAGE_SIZE;
|
|
||||||
}
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,36 +0,0 @@
|
|||||||
/**
|
|
||||||
* PROJECT: ExectOS
|
|
||||||
* COPYRIGHT: See COPYING.md in the top level directory
|
|
||||||
* FILE: xtoskrnl/mm/i686/pfault.cc
|
|
||||||
* DESCRIPTION: Page fault support for i686 architecture
|
|
||||||
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <xtos.hh>
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Evaluates the PDE for for paged pool and per-session mappings.
|
|
||||||
*
|
|
||||||
* @param VirtualAddress
|
|
||||||
* Specifies the virtual address to verify.
|
|
||||||
*
|
|
||||||
* @return This routine returns ACCESS_VIOLATION on PML3 or status code on PML2.
|
|
||||||
*/
|
|
||||||
XTFASTCALL
|
|
||||||
XTSTATUS
|
|
||||||
MM::PageFault::CheckPdeForPagedPool(IN PVOID VirtualAddress)
|
|
||||||
{
|
|
||||||
/* Check if XPA is enabled */
|
|
||||||
if(MM::Paging::GetXpaStatus())
|
|
||||||
{
|
|
||||||
/* Access violation for PML3 */
|
|
||||||
return STATUS_ACCESS_VIOLATION;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Unimplemented path for PML2 */
|
|
||||||
UNIMPLEMENTED;
|
|
||||||
|
|
||||||
/* Temporarily, just return access violation */
|
|
||||||
return STATUS_ACCESS_VIOLATION;
|
|
||||||
}
|
|
||||||
@@ -1,264 +0,0 @@
|
|||||||
/**
|
|
||||||
* PROJECT: ExectOS
|
|
||||||
* COPYRIGHT: See COPYING.md in the top level directory
|
|
||||||
* FILE: xtoskrnl/mm/i686/pfn.cc
|
|
||||||
* DESCRIPTION: Physical Frame Number for i686 support
|
|
||||||
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
|
|
||||||
* Rafal Kupiec <belliash@codingworkshop.eu.org>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <xtos.hh>
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Allocates and initializes page directory structures for a range of PDEs.
|
|
||||||
*
|
|
||||||
* @param StartingPde
|
|
||||||
* Supplies a pointer to the first PDE in the range to initialize.
|
|
||||||
*
|
|
||||||
* @param EndingPde
|
|
||||||
* Supplies a pointer to the last PDE in the range to initialize.
|
|
||||||
*
|
|
||||||
* @return This routine does not return any value.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
VOID
|
|
||||||
MM::Pfn::InitializePageDirectory(IN PMMPDE StartingPde,
|
|
||||||
IN PMMPDE EndingPde)
|
|
||||||
{
|
|
||||||
/* Nothing to do */
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initializes the PFN database by mapping virtual memory and populating entries.
|
|
||||||
*
|
|
||||||
* @return This routine does not return any value.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
VOID
|
|
||||||
MM::Pfn::InitializePfnDatabase(VOID)
|
|
||||||
{
|
|
||||||
PLOADER_MEMORY_DESCRIPTOR Descriptor;
|
|
||||||
PKERNEL_INITIALIZATION_BLOCK InitializationBlock;
|
|
||||||
PLIST_ENTRY ListEntry;
|
|
||||||
PMMMEMORY_LAYOUT MemoryLayout;
|
|
||||||
PUCHAR PfnDatabaseEnd;
|
|
||||||
PMMPTE ValidPte;
|
|
||||||
|
|
||||||
/* Raise runlevel and acquire PFN lock */
|
|
||||||
KE::RaiseRunLevel RunLevel(DISPATCH_LEVEL);
|
|
||||||
KE::QueuedSpinLockGuard SpinLock(SystemSpaceLock);
|
|
||||||
|
|
||||||
/* Get the kernel initialization block */
|
|
||||||
InitializationBlock = KE::BootInformation::GetInitializationBlock();
|
|
||||||
|
|
||||||
/* Get memory layout */
|
|
||||||
MemoryLayout = MM::Manager::GetMemoryLayout();
|
|
||||||
|
|
||||||
/* Get the PFN database size and calculate the end of the PFN database virtual address space */
|
|
||||||
PfnDatabaseEnd = (PUCHAR)MemoryLayout->PfnDatabase + (MemoryLayout->PfnDatabaseSize * MM_PAGE_SIZE) - 1;
|
|
||||||
|
|
||||||
/* Get a template PTE for mapping the PFN database pages */
|
|
||||||
ValidPte = MM::Pte::GetValidPte();
|
|
||||||
|
|
||||||
/* Map the Page Directory and Page Directory Pointer tables for the PFN database */
|
|
||||||
MM::Pte::MapPDE(MemoryLayout->PfnDatabase, PfnDatabaseEnd, ValidPte);
|
|
||||||
MM::Pte::MapPTE(MemoryLayout->PfnDatabase, PfnDatabaseEnd, ValidPte);
|
|
||||||
|
|
||||||
/* Zero PFN database virtual space */
|
|
||||||
RTL::Memory::ZeroMemory(MemoryLayout->PfnDatabase, MemoryLayout->PfnDatabaseSize * MM_PAGE_SIZE);
|
|
||||||
|
|
||||||
/* Initialize the color tables */
|
|
||||||
MM::Colors::InitializeColorTables();
|
|
||||||
|
|
||||||
/* Iterate over memory descriptors to map the PFN database and initialize entries */
|
|
||||||
ListEntry = InitializationBlock->MemoryDescriptorListHead.Flink;
|
|
||||||
while(ListEntry != &InitializationBlock->MemoryDescriptorListHead)
|
|
||||||
{
|
|
||||||
/* Get the descriptor */
|
|
||||||
Descriptor = CONTAIN_RECORD(ListEntry, LOADER_MEMORY_DESCRIPTOR, ListEntry);
|
|
||||||
|
|
||||||
/* Skip invisible memory regions */
|
|
||||||
if(MM::Manager::VerifyMemoryTypeInvisible(Descriptor->MemoryType))
|
|
||||||
{
|
|
||||||
/* Move to the next descriptor and continue */
|
|
||||||
ListEntry = ListEntry->Flink;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check if this is the modified free descriptor */
|
|
||||||
if(Descriptor == FreeDescriptor)
|
|
||||||
{
|
|
||||||
/* Switch to the original descriptor */
|
|
||||||
Descriptor = &OriginalFreeDescriptor;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check if the free memory block that was split is being processed */
|
|
||||||
if(Descriptor == &OriginalFreeDescriptor)
|
|
||||||
{
|
|
||||||
/* Skip loop processing, free memory is initialized separately */
|
|
||||||
ListEntry = ListEntry->Flink;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Initialize PFNs for this memory range */
|
|
||||||
ProcessMemoryDescriptor(Descriptor->BasePage, Descriptor->PageCount, Descriptor->MemoryType);
|
|
||||||
|
|
||||||
/* Move to the next descriptor */
|
|
||||||
ListEntry = ListEntry->Flink;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Initialize PFNs for the free memory */
|
|
||||||
ProcessMemoryDescriptor(FreeDescriptor->BasePage, FreeDescriptor->PageCount, LoaderFree);
|
|
||||||
|
|
||||||
/* Initialize PFNs for the physical pages backing the PFN database */
|
|
||||||
ProcessMemoryDescriptor(OriginalFreeDescriptor.BasePage,
|
|
||||||
FreeDescriptor->BasePage - OriginalFreeDescriptor.BasePage,
|
|
||||||
LoaderMemoryData);
|
|
||||||
|
|
||||||
/* Restore original free descriptor */
|
|
||||||
*FreeDescriptor = OriginalFreeDescriptor;
|
|
||||||
|
|
||||||
/* Initialize PFNs backing page tables */
|
|
||||||
InitializePageTablePfns();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initializes PFN database entries for the system page tables.
|
|
||||||
*
|
|
||||||
* @return This routine does not return any value.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
VOID
|
|
||||||
MM::Pfn::InitializePageTablePfns(VOID)
|
|
||||||
{
|
|
||||||
PFN_NUMBER PageFrameIndex;
|
|
||||||
PMMPFN Pfn;
|
|
||||||
ULONG RootLevel;
|
|
||||||
PMMPTE RootPte;
|
|
||||||
|
|
||||||
/* Determine root structure based on paging mode */
|
|
||||||
if(MM::Paging::GetXpaStatus())
|
|
||||||
{
|
|
||||||
/* XPA enabled, 3-level paging (PAE) */
|
|
||||||
RootLevel = 3;
|
|
||||||
|
|
||||||
/* Retrieve the PFN of the PML3 table and its virtual base address */
|
|
||||||
PageFrameIndex = AR::CpuFunc::ReadControlRegister(3) >> MM_PAGE_SHIFT;
|
|
||||||
RootPte = (PMMPTE)MM::Paging::GetPpeAddress(NULLPTR);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* XPA disabled, 2-level paging */
|
|
||||||
RootLevel = 2;
|
|
||||||
|
|
||||||
/* Retrieve the PFN of the PML2 table and its virtual base address */
|
|
||||||
PageFrameIndex = AR::CpuFunc::ReadControlRegister(3) >> MM_PAGE_SHIFT;
|
|
||||||
RootPte = (PMMPTE)MM::Paging::GetPdeAddress(NULLPTR);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Initialize the PFN entry for the root page table itself */
|
|
||||||
Pfn = GetPfnEntry(PageFrameIndex);
|
|
||||||
if(Pfn)
|
|
||||||
{
|
|
||||||
/* Initialize the PFN entry */
|
|
||||||
Pfn->PteAddress = NULLPTR;
|
|
||||||
Pfn->u1.WsIndex = 0;
|
|
||||||
Pfn->u2.ShareCount = 1;
|
|
||||||
Pfn->u3.e1.CacheAttribute = PfnNonCached;
|
|
||||||
Pfn->u3.e1.PageLocation = ActiveAndValid;
|
|
||||||
Pfn->u3.e2.ReferenceCount = 1;
|
|
||||||
Pfn->u4.PteFrame = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Start recursive scan from the top level */
|
|
||||||
if(RootPte)
|
|
||||||
{
|
|
||||||
/* Scan the root page table */
|
|
||||||
ScanPageTable(RootPte, RootLevel);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Recursively scans a page table to initialize PFN database entries for active pages.
|
|
||||||
*
|
|
||||||
* @param PointerPte
|
|
||||||
* Pointer to the base of the page table to scan.
|
|
||||||
*
|
|
||||||
* @param Level
|
|
||||||
* The paging level of the table being scanned.
|
|
||||||
*
|
|
||||||
* @return This routine does not return any value.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
VOID
|
|
||||||
MM::Pfn::ScanPageTable(IN PMMPTE PointerPte,
|
|
||||||
IN ULONG Level)
|
|
||||||
{
|
|
||||||
PVOID Address;
|
|
||||||
ULONG Index;
|
|
||||||
PMMPTE NextLevelPte;
|
|
||||||
ULONG PtesPerPage;
|
|
||||||
|
|
||||||
/* Get the number of PTEs per page */
|
|
||||||
PtesPerPage = MM::Pte::GetPtesPerPage();
|
|
||||||
|
|
||||||
/* Check if PML3 is enabled and current level is PDPT */
|
|
||||||
if(Level == 3)
|
|
||||||
{
|
|
||||||
/* PAE PDPT has only 4 entries */
|
|
||||||
PtesPerPage = 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Iterate through all entries in the current page table */
|
|
||||||
for(Index = 0; Index < PtesPerPage; Index++)
|
|
||||||
{
|
|
||||||
/* Check if the page table entry is present */
|
|
||||||
if(MM::Paging::PteValid(PointerPte))
|
|
||||||
{
|
|
||||||
/* Mark the PFN pointed to by this entry as active */
|
|
||||||
LinkPfnForPageTable(MM::Paging::GetPageFrameNumber(PointerPte), PointerPte);
|
|
||||||
|
|
||||||
/* Recurse to the next level, if this is not a leaf node (PTE) */
|
|
||||||
if(Level > 1)
|
|
||||||
{
|
|
||||||
/* Calculate the virtual address mapped by this entry to find the next table */
|
|
||||||
switch(Level)
|
|
||||||
{
|
|
||||||
case 3:
|
|
||||||
/* Calculate PDE */
|
|
||||||
Address = MM::Paging::GetPpeVirtualAddress(PointerPte);
|
|
||||||
NextLevelPte = (PMMPTE)MM::Paging::GetPdeAddress(Address);
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
/* Calculate PTE */
|
|
||||||
Address = MM::Paging::GetPdeVirtualAddress(PointerPte);
|
|
||||||
NextLevelPte = (PMMPTE)MM::Paging::GetPteAddress(Address);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
/* Nothing to calculate, return NULLPTR */
|
|
||||||
NextLevelPte = NULLPTR;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Recurse deeper if not at the bottom level (PTE) already */
|
|
||||||
if(NextLevelPte)
|
|
||||||
{
|
|
||||||
/* Recursively scan the next level page table */
|
|
||||||
ScanPageTable(NextLevelPte, Level - 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Move to the next entry in the current table */
|
|
||||||
PointerPte = MM::Paging::GetNextPte(PointerPte);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,128 +0,0 @@
|
|||||||
/**
|
|
||||||
* PROJECT: ExectOS
|
|
||||||
* COPYRIGHT: See COPYING.md in the top level directory
|
|
||||||
* FILE: xtoskrnl/mm/i686/pte.cc
|
|
||||||
* DESCRIPTION: Page Table Entry (PTE) for i686 support
|
|
||||||
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <xtos.hh>
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if the virtual address is valid and mapped in the page tables.
|
|
||||||
*
|
|
||||||
* @param VirtualAddress
|
|
||||||
* The virtual address to check.
|
|
||||||
*
|
|
||||||
* @return This routine returns TRUE if the address is valid, or FALSE otherwise.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
BOOLEAN
|
|
||||||
MM::Pte::AddressValid(IN PVOID VirtualAddress)
|
|
||||||
{
|
|
||||||
/* Check if PDE and PTE are valid */
|
|
||||||
if(!MM::Paging::PteValid(MM::Paging::GetPdeAddress(VirtualAddress)) ||
|
|
||||||
!MM::Paging::PteValid(MM::Paging::GetPteAddress(VirtualAddress)))
|
|
||||||
{
|
|
||||||
/* Invalid PDE or PTE, return FALSE */
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Address is valid, return TRUE */
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieves the base virtual address of the system PTEs.
|
|
||||||
*
|
|
||||||
* @return This routine returns a pointer to the first PTE in the system PTE space.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
PMMPTE
|
|
||||||
MM::Pte::GetSystemPteBaseAddress(VOID)
|
|
||||||
{
|
|
||||||
return MM::Paging::GetPteAddress(NULLPTR);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Performs the initial setup of the system's page table hierarchy.
|
|
||||||
*
|
|
||||||
* @return This routine does not return any value.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
VOID
|
|
||||||
MM::Pte::InitializePageTable(VOID)
|
|
||||||
{
|
|
||||||
PMMPTE EndSpacePte, PointerPte;
|
|
||||||
PMMMEMORY_LAYOUT MemoryLayout;
|
|
||||||
CPUID_REGISTERS CpuRegisters;
|
|
||||||
MMPTE TemplatePte;
|
|
||||||
|
|
||||||
/* Retrieve current paging mode and memory layout */
|
|
||||||
MemoryLayout = MM::Manager::GetMemoryLayout();
|
|
||||||
|
|
||||||
/* Get CPU features */
|
|
||||||
CpuRegisters.Leaf = CPUID_GET_STANDARD1_FEATURES;
|
|
||||||
AR::CpuFunc::CpuId(&CpuRegisters);
|
|
||||||
|
|
||||||
/* Check if Paging Global Extensions (PGE) is supported */
|
|
||||||
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_PGE)
|
|
||||||
{
|
|
||||||
/* Enable the Global Paging (PGE) feature */
|
|
||||||
AR::CpuFunc::WriteControlRegister(4, AR::CpuFunc::ReadControlRegister(4) | CR4_PGE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get the PD user-space range for both legacy and PAE paging */
|
|
||||||
PointerPte = (PMMPTE)MM::Paging::GetPdeAddress(0);
|
|
||||||
EndSpacePte = (PMMPTE)MM::Paging::GetPdeAddress(MemoryLayout->UserSpaceEnd);
|
|
||||||
|
|
||||||
/* Clear all top-level entries mapping the user address space */
|
|
||||||
while(PointerPte <= EndSpacePte)
|
|
||||||
{
|
|
||||||
MM::Paging::ClearPte(PointerPte);
|
|
||||||
PointerPte = MM::Paging::GetNextPte(PointerPte);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Flush the TLB to invalidate all non-global entries */
|
|
||||||
AR::CpuFunc::FlushTlb();
|
|
||||||
|
|
||||||
/* Create a template PTE for mapping kernel pages */
|
|
||||||
MM::Paging::ClearPte(&TemplatePte);
|
|
||||||
MM::Paging::SetPte(&TemplatePte, 0, MM_PTE_READWRITE | MM_PTE_CACHE_ENABLE);
|
|
||||||
|
|
||||||
/* Map the kernel's PD entries */
|
|
||||||
MM::Pte::MapPDE(MemoryLayout->NonPagedSystemPoolStart, (PVOID)MM_HIGHEST_SYSTEM_ADDRESS, &TemplatePte);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Maps a range of virtual addresses at the PPE (Page Directory Pointer Entry) level.
|
|
||||||
*
|
|
||||||
* @param StartAddress
|
|
||||||
* The beginning of the virtual address range to map.
|
|
||||||
*
|
|
||||||
* @param EndAddress
|
|
||||||
* The end of the virtual address range to map.
|
|
||||||
*
|
|
||||||
* @param TemplatePpe
|
|
||||||
* A template PPE to use for creating new entries.
|
|
||||||
*
|
|
||||||
* @return This routine does not return any value.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
VOID
|
|
||||||
MM::Pte::MapPPE(IN PVOID StartAddress,
|
|
||||||
IN PVOID EndAddress,
|
|
||||||
IN PMMPPE TemplatePpe)
|
|
||||||
{
|
|
||||||
/* Just a stub on i686 platform */
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
150
xtoskrnl/mm/init.cc
Normal file
150
xtoskrnl/mm/init.cc
Normal file
@@ -0,0 +1,150 @@
|
|||||||
|
/**
|
||||||
|
* PROJECT: ExectOS
|
||||||
|
* COPYRIGHT: See COPYING.md in the top level directory
|
||||||
|
* FILE: xtoskrnl/mm/init.cc
|
||||||
|
* DESCRIPTION: Memory Manager initialization routines
|
||||||
|
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <xtos.hh>
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Performs an early initialization of the XTOS Memory Manager.
|
||||||
|
*
|
||||||
|
* @return This routine does not return any value.
|
||||||
|
*
|
||||||
|
* @since XT 1.0
|
||||||
|
*/
|
||||||
|
XTAPI
|
||||||
|
VOID
|
||||||
|
MM::Init::InitializeMemoryManager(VOID)
|
||||||
|
{
|
||||||
|
/* Scan memory descriptors provided by the boot loader */
|
||||||
|
ScanMemoryDescriptors();
|
||||||
|
|
||||||
|
/* Check if there are enough physical pages */
|
||||||
|
if(NumberOfPhysicalPages < MM_MINIMUM_PHYSICAL_PAGES)
|
||||||
|
{
|
||||||
|
/* Insufficient physical pages, kernel panic */
|
||||||
|
DebugPrint(L"Insufficient physical pages! Install additional memory\n");
|
||||||
|
KE::Crash::Panic(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Proceed with architecture specific initialization */
|
||||||
|
InitializeArchitecture();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Scans memory descriptors provided by the boot loader.
|
||||||
|
*
|
||||||
|
* @return This routine does not return any value.
|
||||||
|
*
|
||||||
|
* @since XT 1.0
|
||||||
|
*/
|
||||||
|
XTAPI
|
||||||
|
VOID
|
||||||
|
MM::Init::ScanMemoryDescriptors(VOID)
|
||||||
|
{
|
||||||
|
PLIST_ENTRY LoaderMemoryDescriptors, MemoryMappings;
|
||||||
|
PLOADER_MEMORY_DESCRIPTOR MemoryDescriptor;
|
||||||
|
PFN_NUMBER FreePages;
|
||||||
|
|
||||||
|
/* Initially, set number of free pages to 0 */
|
||||||
|
FreePages = 0;
|
||||||
|
|
||||||
|
/* Get a list of memory descriptors provided by the boot loader */
|
||||||
|
LoaderMemoryDescriptors = KE::BootInformation::GetMemoryDescriptors();
|
||||||
|
|
||||||
|
/* Iterate through memory mappings provided by the boot loader */
|
||||||
|
MemoryMappings = LoaderMemoryDescriptors->Flink;
|
||||||
|
while(MemoryMappings != LoaderMemoryDescriptors)
|
||||||
|
{
|
||||||
|
/* Get memory descriptor */
|
||||||
|
MemoryDescriptor = CONTAIN_RECORD(MemoryMappings, LOADER_MEMORY_DESCRIPTOR, ListEntry);
|
||||||
|
|
||||||
|
/* Check if memory type is invisible or cached */
|
||||||
|
if(VerifyMemoryTypeInvisible(MemoryDescriptor->MemoryType) ||
|
||||||
|
(MemoryDescriptor->MemoryType == LoaderHardwareCachedMemory))
|
||||||
|
{
|
||||||
|
/* Skip this mapping */
|
||||||
|
MemoryMappings = MemoryMappings->Flink;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Make sure that memory type is not bad */
|
||||||
|
if(MemoryDescriptor->MemoryType != LoaderBad)
|
||||||
|
{
|
||||||
|
/* Increment number of physical pages */
|
||||||
|
NumberOfPhysicalPages += MemoryDescriptor->PageCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Find lowest physical page */
|
||||||
|
if(MemoryDescriptor->BasePage < LowestPhysicalPage)
|
||||||
|
{
|
||||||
|
/* Update lowest physical page */
|
||||||
|
LowestPhysicalPage = MemoryDescriptor->BasePage;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Find highest physical page */
|
||||||
|
if(MemoryDescriptor->BasePage + MemoryDescriptor->PageCount > HighestPhysicalPage)
|
||||||
|
{
|
||||||
|
/* Update highest physical page */
|
||||||
|
HighestPhysicalPage = (MemoryDescriptor->BasePage + MemoryDescriptor->PageCount) - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if memory type should be considered as free */
|
||||||
|
if(VerifyMemoryTypeFree(MemoryDescriptor->MemoryType))
|
||||||
|
{
|
||||||
|
/* Check if this descriptor contains more free pages */
|
||||||
|
if(MemoryDescriptor->PageCount >= FreePages)
|
||||||
|
{
|
||||||
|
/* Update free descriptor */
|
||||||
|
FreePages = MemoryDescriptor->PageCount;
|
||||||
|
FreeDescriptor = MemoryDescriptor;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get next memory descriptor */
|
||||||
|
MemoryMappings = MemoryMappings->Flink;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Store original free descriptor */
|
||||||
|
RTL::Memory::CopyMemory(&OldFreeDescriptor, FreeDescriptor, sizeof(LOADER_MEMORY_DESCRIPTOR));
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Checks whether the specified memory type should be considered as free.
|
||||||
|
*
|
||||||
|
* @param MemoryType
|
||||||
|
* Specifies the memory type to verify.
|
||||||
|
*
|
||||||
|
* @return This routine returns TRUE if the specified memory type should be considered as free, or FALSE otherwise.
|
||||||
|
*
|
||||||
|
* @since XT 1.0
|
||||||
|
*/
|
||||||
|
XTAPI
|
||||||
|
BOOLEAN
|
||||||
|
MM::Init::VerifyMemoryTypeFree(LOADER_MEMORY_TYPE MemoryType)
|
||||||
|
{
|
||||||
|
return ((MemoryType == LoaderFree) || (MemoryType == LoaderFirmwareTemporary) ||
|
||||||
|
(MemoryType == LoaderLoadedProgram) || (MemoryType == LoaderOsloaderStack));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks whether the specified memory type should be considered as invisible for the memory manager.
|
||||||
|
*
|
||||||
|
* @param MemoryType
|
||||||
|
* Specifies the memory type to verify.
|
||||||
|
*
|
||||||
|
* @return This routine returns TRUE if the specified memory type should be considered as invisible, or FALSE otherwise.
|
||||||
|
*
|
||||||
|
* @since XT 1.0
|
||||||
|
*/
|
||||||
|
XTAPI
|
||||||
|
BOOLEAN
|
||||||
|
MM::Init::VerifyMemoryTypeInvisible(LOADER_MEMORY_TYPE MemoryType)
|
||||||
|
{
|
||||||
|
return ((MemoryType == LoaderFirmwarePermanent) ||
|
||||||
|
(MemoryType == LoaderSpecialMemory) ||
|
||||||
|
(MemoryType == LoaderBBTMemory));
|
||||||
|
}
|
||||||
@@ -4,7 +4,6 @@
|
|||||||
* FILE: xtoskrnl/mm/kpool.cc
|
* FILE: xtoskrnl/mm/kpool.cc
|
||||||
* DESCRIPTION: Kernel pool memory management
|
* DESCRIPTION: Kernel pool memory management
|
||||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||||
* Aiken Harris <harraiken91@gmail.com>
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <xtos.hh>
|
#include <xtos.hh>
|
||||||
@@ -28,68 +27,12 @@
|
|||||||
*/
|
*/
|
||||||
XTAPI
|
XTAPI
|
||||||
XTSTATUS
|
XTSTATUS
|
||||||
MM::KernelPool::AllocateKernelStack(OUT PVOID *Stack,
|
MM::KernelPool::AllocateKernelStack(IN PVOID *Stack,
|
||||||
IN ULONG StackSize)
|
IN BOOLEAN LargeStack,
|
||||||
|
IN UCHAR SystemNode)
|
||||||
{
|
{
|
||||||
PFN_COUNT StackPages;
|
UNIMPLEMENTED;
|
||||||
PMMPTE PointerPte, StackPte;
|
return STATUS_NOT_IMPLEMENTED;
|
||||||
MMPTE TempPte, InvalidPte;
|
|
||||||
PFN_NUMBER PageFrameIndex;
|
|
||||||
ULONG Index;
|
|
||||||
|
|
||||||
/* Initialize the output stack pointer to NULLPTR */
|
|
||||||
*Stack = NULLPTR;
|
|
||||||
|
|
||||||
/* Convert the requested stack size into a page count */
|
|
||||||
StackPages = SIZE_TO_PAGES(StackSize);
|
|
||||||
|
|
||||||
/* Reserve PTEs for the stack pages, plus a guard page */
|
|
||||||
StackPte = MM::Pte::ReserveSystemPtes(StackPages + 1, SystemPteSpace);
|
|
||||||
if(!StackPte)
|
|
||||||
{
|
|
||||||
/* Failed to reserve PTEs for the new kernel stack */
|
|
||||||
return STATUS_INSUFFICIENT_RESOURCES;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Set up a template for an invalid PTE */
|
|
||||||
MM::Paging::SetPte(&InvalidPte, 0, MM_PTE_GUARDED);
|
|
||||||
|
|
||||||
/* Set up a template for a valid, writable stack PTE */
|
|
||||||
MM::Paging::ClearPte(&TempPte);
|
|
||||||
MM::Paging::SetPte(&TempPte, 0, MM_PTE_READWRITE | MM_PTE_CACHE_ENABLE);
|
|
||||||
|
|
||||||
/* Acquire the PFN database lock and raise runlevel to DISPATCH_LEVEL */
|
|
||||||
KE::RaiseRunLevel RunLevel(DISPATCH_LEVEL);
|
|
||||||
KE::QueuedSpinLockGuard SpinLock(SystemSpaceLock);
|
|
||||||
|
|
||||||
/* Start iterating from the base of the reserved PTE block */
|
|
||||||
PointerPte = StackPte;
|
|
||||||
|
|
||||||
/* Loop through each page of the stack that needs to be allocated */
|
|
||||||
for(Index = 0; Index < StackPages; Index++)
|
|
||||||
{
|
|
||||||
/* Advance to the next PTE */
|
|
||||||
PointerPte = MM::Paging::GetNextPte(PointerPte);
|
|
||||||
|
|
||||||
/* Allocate a physical page and temporarily mark the PTE as invalid */
|
|
||||||
PageFrameIndex = MM::Pfn::AllocatePhysicalPage(MM::Colors::GetNextColor());
|
|
||||||
*PointerPte = InvalidPte;
|
|
||||||
|
|
||||||
/* Associate the physical page with its corresponding PTE in the PFN database */
|
|
||||||
MM::Pfn::LinkPfn(PageFrameIndex, PointerPte, TRUE);
|
|
||||||
|
|
||||||
/* Make the PTE valid, mapping the virtual address to the physical page */
|
|
||||||
MM::Paging::SetPte(&TempPte, PageFrameIndex, 0);
|
|
||||||
*PointerPte = TempPte;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Zero the newly allocated stack memory, skipping the guard page */
|
|
||||||
RTL::Memory::ZeroMemory(MM::Paging::GetPteVirtualAddress(MM::Paging::GetNextPte(StackPte)),
|
|
||||||
MM_PAGE_SIZE * StackPages);
|
|
||||||
|
|
||||||
/* Return a pointer to the top of the new stack */
|
|
||||||
*Stack = MM::Paging::GetPteVirtualAddress(MM::Paging::AdvancePte(StackPte, StackPages + 1));
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -153,40 +96,9 @@ MM::KernelPool::AllocateProcessorStructures(IN ULONG CpuNumber,
|
|||||||
XTAPI
|
XTAPI
|
||||||
VOID
|
VOID
|
||||||
MM::KernelPool::FreeKernelStack(IN PVOID Stack,
|
MM::KernelPool::FreeKernelStack(IN PVOID Stack,
|
||||||
IN ULONG StackSize)
|
IN BOOLEAN LargeStack)
|
||||||
{
|
{
|
||||||
PFN_COUNT StackPages;
|
UNIMPLEMENTED;
|
||||||
PMMPTE PointerPte;
|
|
||||||
ULONG Index;
|
|
||||||
|
|
||||||
/* Get the PTE for the top of the stack, including the guard page */
|
|
||||||
PointerPte = MM::Paging::AdvancePte(MM::Paging::GetPteAddress(Stack), -1);
|
|
||||||
|
|
||||||
/* Convert the stack size into a page count */
|
|
||||||
StackPages = SIZE_TO_PAGES(StackSize);
|
|
||||||
|
|
||||||
/* Start a guarded code block */
|
|
||||||
{
|
|
||||||
/* Acquire the PFN database lock */
|
|
||||||
KE::QueuedSpinLockGuard SpinLock(SystemSpaceLock);
|
|
||||||
|
|
||||||
/* Loop through each page of the stack that needs to be freed */
|
|
||||||
for(Index = 0; Index < StackPages; Index++)
|
|
||||||
{
|
|
||||||
/* Ensure the PTE is valid */
|
|
||||||
if(MM::Paging::PteValid(PointerPte))
|
|
||||||
{
|
|
||||||
/* Free the physical page */
|
|
||||||
MM::Pfn::FreePhysicalPage(PointerPte);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Advance to the next PTE */
|
|
||||||
PointerPte = MM::Paging::AdvancePte(PointerPte, -1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Release all system PTEs used by the stack, including the guard page */
|
|
||||||
MM::Pte::ReleaseSystemPtes(PointerPte, StackPages + 1, SystemPteSpace);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,177 +0,0 @@
|
|||||||
/**
|
|
||||||
* PROJECT: ExectOS
|
|
||||||
* COPYRIGHT: See COPYING.md in the top level directory
|
|
||||||
* FILE: xtoskrnl/mm/mmgr.cc
|
|
||||||
* DESCRIPTION: Memory Manager
|
|
||||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
|
||||||
* Aiken Harris <harraiken91@gmail.com>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <xtos.hh>
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Computes the size of the boot image.
|
|
||||||
*
|
|
||||||
* @param BootImageSize
|
|
||||||
* Supplies a pointer to a variable that will receive the size of the boot image in pages.
|
|
||||||
*
|
|
||||||
* @return This routine does not return any value.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
VOID
|
|
||||||
MM::Manager::ComputeBootImageSize(OUT PPFN_NUMBER BootImageSize)
|
|
||||||
{
|
|
||||||
PKERNEL_INITIALIZATION_BLOCK InitializationBlock;
|
|
||||||
PFN_NUMBER ImageSize;
|
|
||||||
ULONG_PTR Alignment;
|
|
||||||
|
|
||||||
/* Get the kernel initialization block */
|
|
||||||
InitializationBlock = KE::BootInformation::GetInitializationBlock();
|
|
||||||
|
|
||||||
/* Calculate the alignment based on the PTE size */
|
|
||||||
Alignment = ((MM_PAGE_SIZE / MM::Paging::GetPteSize()) * MM_PAGE_SIZE);
|
|
||||||
|
|
||||||
/* Calculate the size of the boot image */
|
|
||||||
ImageSize = InitializationBlock->BootImageSize * MM_PAGE_SIZE;
|
|
||||||
ImageSize = (ImageSize + Alignment - 1) & ~(Alignment - 1);
|
|
||||||
|
|
||||||
/* Return number of pages used by the boot image */
|
|
||||||
*BootImageSize = ImageSize / MM_PAGE_SIZE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieves the amount of total available memory in the system.
|
|
||||||
*
|
|
||||||
* @return This routine returns the amount of available memory in the system in megabytes.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
ULONG_PTR
|
|
||||||
MM::Manager::GetInstalledMemorySize(VOID)
|
|
||||||
{
|
|
||||||
/* Return the amount of installed memory */
|
|
||||||
return (MM::Pfn::GetNumberOfPhysicalPages() * MM_PAGE_SIZE) / 1048576;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieves a pointer to the system's virtual memory layout structure.
|
|
||||||
*
|
|
||||||
* @return This routine returns a pointer to the memory layout structure.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
PMMMEMORY_LAYOUT
|
|
||||||
MM::Manager::GetMemoryLayout(VOID)
|
|
||||||
{
|
|
||||||
/* Return a pointer to the global memory layout structure */
|
|
||||||
return &MemoryLayout;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieves the number of system PTEs.
|
|
||||||
*
|
|
||||||
* @return This routine returns the number of system PTEs.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
PFN_NUMBER
|
|
||||||
MM::Manager::GetNumberOfSystemPtes()
|
|
||||||
{
|
|
||||||
return NumberOfSystemPtes;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Performs an early initialization of the XTOS Memory Manager.
|
|
||||||
*
|
|
||||||
* @return This routine does not return any value.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
VOID
|
|
||||||
MM::Manager::InitializeMemoryManager(VOID)
|
|
||||||
{
|
|
||||||
/* Scan memory descriptors provided by the boot loader */
|
|
||||||
MM::Pfn::ScanMemoryDescriptors();
|
|
||||||
|
|
||||||
/* Check if there are enough physical pages */
|
|
||||||
if(MM::Pfn::GetNumberOfPhysicalPages() < MM_MINIMUM_PHYSICAL_PAGES)
|
|
||||||
{
|
|
||||||
/* Insufficient physical pages, kernel panic */
|
|
||||||
DebugPrint(L"Insufficient physical pages! Install additional memory\n");
|
|
||||||
KE::Crash::Panic(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Compute page colors to reduce CPU cache conflicts */
|
|
||||||
MM::Colors::ComputePageColoring();
|
|
||||||
|
|
||||||
/* Initialize and dump memory layout */
|
|
||||||
InitializeMemoryLayout();
|
|
||||||
DumpMemoryLayout();
|
|
||||||
|
|
||||||
/* Initialize PTE template */
|
|
||||||
MM::Pte::InitializeSystemPte();
|
|
||||||
|
|
||||||
/* Initialize page table */
|
|
||||||
MM::Pte::InitializePageTable();
|
|
||||||
|
|
||||||
/* Initialize system PTE space */
|
|
||||||
MM::Pte::InitializeSystemPteSpace();
|
|
||||||
|
|
||||||
/* Initialize non-paged pool */
|
|
||||||
MM::Allocator::InitializeNonPagedPool();
|
|
||||||
|
|
||||||
/* Initialize PFN database */
|
|
||||||
MM::Pfn::InitializePfnDatabase();
|
|
||||||
|
|
||||||
/* Initialize paged pool */
|
|
||||||
MM::Allocator::InitializePagedPool();
|
|
||||||
|
|
||||||
/* Flush TLB */
|
|
||||||
AR::CpuFunc::FlushTlb();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks whether the specified memory type should be considered as free.
|
|
||||||
*
|
|
||||||
* @param MemoryType
|
|
||||||
* Specifies the memory type to verify.
|
|
||||||
*
|
|
||||||
* @return This routine returns TRUE if the specified memory type should be considered as free, or FALSE otherwise.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
BOOLEAN
|
|
||||||
MM::Manager::VerifyMemoryTypeFree(LOADER_MEMORY_TYPE MemoryType)
|
|
||||||
{
|
|
||||||
return ((MemoryType == LoaderFirmwareTemporary) ||
|
|
||||||
(MemoryType == LoaderFree) ||
|
|
||||||
(MemoryType == LoaderLoadedProgram) ||
|
|
||||||
(MemoryType == LoaderOsloaderStack));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks whether the specified memory type should be considered as invisible for the memory manager.
|
|
||||||
*
|
|
||||||
* @param MemoryType
|
|
||||||
* Specifies the memory type to verify.
|
|
||||||
*
|
|
||||||
* @return This routine returns TRUE if the specified memory type should be considered as invisible, or FALSE otherwise.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
BOOLEAN
|
|
||||||
MM::Manager::VerifyMemoryTypeInvisible(LOADER_MEMORY_TYPE MemoryType)
|
|
||||||
{
|
|
||||||
return ((MemoryType == LoaderBBTMemory) ||
|
|
||||||
(MemoryType == LoaderFirmwarePermanent) ||
|
|
||||||
(MemoryType == LoaderSpecialMemory));
|
|
||||||
}
|
|
||||||
@@ -9,28 +9,6 @@
|
|||||||
#include <xtos.hh>
|
#include <xtos.hh>
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Advances a PTE pointer by a given number of entries, considering the actual PTE size.
|
|
||||||
*
|
|
||||||
* @param Pte
|
|
||||||
* The PTE pointer to advance.
|
|
||||||
*
|
|
||||||
* @param Count
|
|
||||||
* The number of PTE entries to advance by.
|
|
||||||
*
|
|
||||||
* @return The advanced PTE pointer.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
PMMPTE
|
|
||||||
MM::Paging::AdvancePte(IN PMMPTE Pte,
|
|
||||||
IN LONG Count)
|
|
||||||
{
|
|
||||||
/* Return advanced PTE pointer */
|
|
||||||
return PmlRoutines->AdvancePte(Pte, Count);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clears the contents of a page table entry (PTE).
|
* Clears the contents of a page table entry (PTE).
|
||||||
*
|
*
|
||||||
@@ -43,9 +21,8 @@ MM::Paging::AdvancePte(IN PMMPTE Pte,
|
|||||||
*/
|
*/
|
||||||
XTAPI
|
XTAPI
|
||||||
VOID
|
VOID
|
||||||
MM::Paging::ClearPte(IN PMMPTE PtePointer)
|
MM::Paging::ClearPte(PHARDWARE_PTE PtePointer)
|
||||||
{
|
{
|
||||||
/* Clear PTE */
|
|
||||||
PmlRoutines->ClearPte(PtePointer);
|
PmlRoutines->ClearPte(PtePointer);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -101,77 +78,6 @@ MM::Paging::FlushTlb(VOID)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the next entry in a PTE list.
|
|
||||||
*
|
|
||||||
* @param Pte
|
|
||||||
* The PTE pointer to get the next entry from.
|
|
||||||
*
|
|
||||||
* @return This routine returns the next entry in the PTE list.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
ULONG_PTR
|
|
||||||
MM::Paging::GetNextEntry(IN PMMPTE Pte)
|
|
||||||
{
|
|
||||||
/* Return next entry in PTE list */
|
|
||||||
return PmlRoutines->GetNextEntry(Pte);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Advances a PTE pointer, considering the actual PTE size.
|
|
||||||
*
|
|
||||||
* @param Pte
|
|
||||||
* The PTE pointer to advance.
|
|
||||||
*
|
|
||||||
* @return The advanced PTE pointer.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
PMMPTE
|
|
||||||
MM::Paging::GetNextPte(IN PMMPTE Pte)
|
|
||||||
{
|
|
||||||
/* Return advanced PTE pointer */
|
|
||||||
return PmlRoutines->GetNextPte(Pte);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if a PTE list contains only one entry.
|
|
||||||
*
|
|
||||||
* @param Pte
|
|
||||||
* The PTE pointer to check.
|
|
||||||
*
|
|
||||||
* @return This routine returns TRUE if the PTE list has only one entry, FALSE otherwise.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
BOOLEAN
|
|
||||||
MM::Paging::GetOneEntry(IN PMMPTE Pte)
|
|
||||||
{
|
|
||||||
/* Return one entry status */
|
|
||||||
return PmlRoutines->GetOneEntry(Pte);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the page frame number from a corresponding PTE.
|
|
||||||
*
|
|
||||||
* @param Pte
|
|
||||||
* The PTE pointer to get the page frame number from.
|
|
||||||
*
|
|
||||||
* @return This routine returns the page frame number.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
PFN_NUMBER
|
|
||||||
MM::Paging::GetPageFrameNumber(IN PMMPTE Pte)
|
|
||||||
{
|
|
||||||
return PmlRoutines->GetPageFrameNumber(Pte);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the page map routines for basic paging mode (non-XPA).
|
* Gets the page map routines for basic paging mode (non-XPA).
|
||||||
*
|
*
|
||||||
@@ -184,25 +90,9 @@ MM::PPAGEMAP
|
|||||||
MM::Paging::GetPageMapBasicRoutines(VOID)
|
MM::Paging::GetPageMapBasicRoutines(VOID)
|
||||||
{
|
{
|
||||||
static MM::PageMapBasic PageMapBasicRoutines;
|
static MM::PageMapBasic PageMapBasicRoutines;
|
||||||
|
|
||||||
/* Return non-XPA page map routines */
|
|
||||||
return &PageMapBasicRoutines;
|
return &PageMapBasicRoutines;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets Page Map Level (PML) for current paging mode.
|
|
||||||
*
|
|
||||||
* @return This routine returns the page map level.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
USHORT
|
|
||||||
MM::Paging::GetPageMapLevel()
|
|
||||||
{
|
|
||||||
return PmlRoutines->GetPageMapLevel();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the page map routines for eXtended Physical Addressing (XPA) mode.
|
* Gets the page map routines for eXtended Physical Addressing (XPA) mode.
|
||||||
*
|
*
|
||||||
@@ -215,8 +105,6 @@ MM::PPAGEMAP
|
|||||||
MM::Paging::GetPageMapXpaRoutines(VOID)
|
MM::Paging::GetPageMapXpaRoutines(VOID)
|
||||||
{
|
{
|
||||||
static MM::PageMapXpa PageMapXpaRoutines;
|
static MM::PageMapXpa PageMapXpaRoutines;
|
||||||
|
|
||||||
/* Return XPA page map routines */
|
|
||||||
return &PageMapXpaRoutines;
|
return &PageMapXpaRoutines;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -232,30 +120,11 @@ MM::Paging::GetPageMapXpaRoutines(VOID)
|
|||||||
*/
|
*/
|
||||||
XTAPI
|
XTAPI
|
||||||
PMMPDE
|
PMMPDE
|
||||||
MM::Paging::GetPdeAddress(IN PVOID Address)
|
MM::Paging::GetPdeAddress(PVOID Address)
|
||||||
{
|
{
|
||||||
/* Return PDE address */
|
|
||||||
return PmlRoutines->GetPdeAddress(Address);
|
return PmlRoutines->GetPdeAddress(Address);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the virtual address that is mapped by a given Page Directory Entry.
|
|
||||||
*
|
|
||||||
* @param PdePointer
|
|
||||||
* Specifies the address of the PDE.
|
|
||||||
*
|
|
||||||
* @return This routine returns the virtual address mapped by the PDE.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
PVOID
|
|
||||||
MM::Paging::GetPdeVirtualAddress(IN PMMPDE PdePointer)
|
|
||||||
{
|
|
||||||
/* Return PTE virtual address */
|
|
||||||
return PmlRoutines->GetPdeVirtualAddress(PdePointer);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the address of the PPE (Page Directory Pointer Table Entry), that maps given address.
|
* Gets the address of the PPE (Page Directory Pointer Table Entry), that maps given address.
|
||||||
*
|
*
|
||||||
@@ -268,48 +137,11 @@ MM::Paging::GetPdeVirtualAddress(IN PMMPDE PdePointer)
|
|||||||
*/
|
*/
|
||||||
XTAPI
|
XTAPI
|
||||||
PMMPPE
|
PMMPPE
|
||||||
MM::Paging::GetPpeAddress(IN PVOID Address)
|
MM::Paging::GetPpeAddress(PVOID Address)
|
||||||
{
|
{
|
||||||
/* Return PPE address */
|
|
||||||
return PmlRoutines->GetPpeAddress(Address);
|
return PmlRoutines->GetPpeAddress(Address);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the virtual address that is mapped by a given Page Directory Pointer Table Entry.
|
|
||||||
*
|
|
||||||
* @param PpePointer
|
|
||||||
* Specifies the address of the PPE.
|
|
||||||
*
|
|
||||||
* @return This routine returns the virtual address mapped by the PPE.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
PVOID
|
|
||||||
MM::Paging::GetPpeVirtualAddress(IN PMMPPE PpePointer)
|
|
||||||
{
|
|
||||||
/* Return PTE virtual address */
|
|
||||||
return PmlRoutines->GetPpeVirtualAddress(PpePointer);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the entire contents of a Page Table Entry (PTE) as a single value.
|
|
||||||
*
|
|
||||||
* @param PtePointer
|
|
||||||
* Pointer to the Page Table Entry (PTE) to read.
|
|
||||||
*
|
|
||||||
* @return This routine returns the contents of the PTE as a single value.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
ULONG_PTR
|
|
||||||
MM::Paging::GetPte(IN PMMPTE PtePointer)
|
|
||||||
{
|
|
||||||
/* Return PTE value */
|
|
||||||
return PmlRoutines->GetPte(PtePointer);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the address of the PTE (Page Table Entry), that maps given address.
|
* Gets the address of the PTE (Page Table Entry), that maps given address.
|
||||||
*
|
*
|
||||||
@@ -322,135 +154,11 @@ MM::Paging::GetPte(IN PMMPTE PtePointer)
|
|||||||
*/
|
*/
|
||||||
XTAPI
|
XTAPI
|
||||||
PMMPTE
|
PMMPTE
|
||||||
MM::Paging::GetPteAddress(IN PVOID Address)
|
MM::Paging::GetPteAddress(PVOID Address)
|
||||||
{
|
{
|
||||||
/* Return PTE address */
|
|
||||||
return PmlRoutines->GetPteAddress(Address);
|
return PmlRoutines->GetPteAddress(Address);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Calculates the distance between two PTE pointers.
|
|
||||||
*
|
|
||||||
* @param EndPte
|
|
||||||
* Pointer to the ending Page Table Entry.
|
|
||||||
*
|
|
||||||
* @param StartPte
|
|
||||||
* Pointer to the starting Page Table Entry.
|
|
||||||
*
|
|
||||||
* @return This routine returns a signed value representing the number of PTEs between EndPte and StartPte.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
LONG
|
|
||||||
MM::Paging::GetPteDistance(PMMPTE EndPte,
|
|
||||||
PMMPTE StartPte)
|
|
||||||
{
|
|
||||||
/* Return distance between PTE pointers */
|
|
||||||
return PmlRoutines->GetPteDistance(EndPte, StartPte);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the size of a PTE.
|
|
||||||
*
|
|
||||||
* @return This routine returns the size of a PTE.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
ULONG
|
|
||||||
MM::Paging::GetPteSize(VOID)
|
|
||||||
{
|
|
||||||
/* Return the size of MMPTE */
|
|
||||||
return PmlRoutines->GetPteSize();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the software protection value of the corresponding Page Table Entry.
|
|
||||||
*
|
|
||||||
* @param PtePointer
|
|
||||||
* Specifies the address of the PTE.
|
|
||||||
*
|
|
||||||
* @return This routine returns the PTE software protection value.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
ULONG
|
|
||||||
MM::Paging::GetPteSoftwareProtection(IN PMMPTE PtePointer)
|
|
||||||
{
|
|
||||||
/* Return PTE software protection value */
|
|
||||||
return PmlRoutines->GetPteSoftwareProtection(PtePointer);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the software prototype value of the corresponding Page Table Entry.
|
|
||||||
*
|
|
||||||
* @param PtePointer
|
|
||||||
* Specifies the address of the PTE.
|
|
||||||
*
|
|
||||||
* @return This routine returns the PTE software prototype value.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
ULONG
|
|
||||||
MM::Paging::GetPteSoftwarePrototype(IN PMMPTE PtePointer)
|
|
||||||
{
|
|
||||||
/* Return PTE software prototype value */
|
|
||||||
return PmlRoutines->GetPteSoftwarePrototype(PtePointer);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the software transition value of the corresponding Page Table Entry.
|
|
||||||
*
|
|
||||||
* @param PtePointer
|
|
||||||
* Specifies the address of the PTE.
|
|
||||||
*
|
|
||||||
* @return This routine returns the PTE software transition value.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
ULONG
|
|
||||||
MM::Paging::GetPteSoftwareTransition(IN PMMPTE PtePointer)
|
|
||||||
{
|
|
||||||
/* Return PTE software transition value */
|
|
||||||
return PmlRoutines->GetPteSoftwareTransition(PtePointer);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the virtual address that is mapped by a given Page Table Entry.
|
|
||||||
*
|
|
||||||
* @param PtePointer
|
|
||||||
* Specifies the address of the PTE.
|
|
||||||
*
|
|
||||||
* @return This routine returns the virtual address mapped by the PTE.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
PVOID
|
|
||||||
MM::Paging::GetPteVirtualAddress(IN PMMPTE PtePointer)
|
|
||||||
{
|
|
||||||
/* Return PTE virtual address */
|
|
||||||
return PmlRoutines->GetPteVirtualAddress(PtePointer);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets current status of eXtended Physical Addressing (XPA).
|
|
||||||
*
|
|
||||||
* @return This routine returns TRUE if PAE or LA57 (XPA) is enabled, or FALSE otherwise.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
BOOLEAN
|
|
||||||
MM::Paging::GetXpaStatus()
|
|
||||||
{
|
|
||||||
return PmlRoutines->GetXpaStatus();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Detects if eXtended Physical Addressing (XPA) is enabled and initializes page map support.
|
* Detects if eXtended Physical Addressing (XPA) is enabled and initializes page map support.
|
||||||
*
|
*
|
||||||
@@ -490,58 +198,13 @@ MM::Paging::InitializePageMapSupport(VOID)
|
|||||||
*/
|
*/
|
||||||
XTAPI
|
XTAPI
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
MM::Paging::PteValid(IN PMMPTE PtePointer)
|
MM::Paging::PteValid(PHARDWARE_PTE PtePointer)
|
||||||
{
|
{
|
||||||
/* Check if PTE is valid */
|
|
||||||
return PmlRoutines->PteValid(PtePointer);
|
return PmlRoutines->PteValid(PtePointer);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the next entry in a PTE list.
|
* Sets a PML2 page table entry (PTE) with the specified physical page and access flags.
|
||||||
*
|
|
||||||
* @param Pte
|
|
||||||
* The PTE pointer to modify.
|
|
||||||
*
|
|
||||||
* @param Value
|
|
||||||
* The value to set as the next entry.
|
|
||||||
*
|
|
||||||
* @return This routine does not return any value.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
VOID
|
|
||||||
MM::Paging::SetNextEntry(IN PMMPTE Pte,
|
|
||||||
IN ULONG_PTR Value)
|
|
||||||
{
|
|
||||||
/* Set next entry in PTE list */
|
|
||||||
PmlRoutines->SetNextEntry(Pte, Value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the flag indicating whether a PTE list contains only one entry.
|
|
||||||
*
|
|
||||||
* @param Pte
|
|
||||||
* The PTE pointer to modify.
|
|
||||||
*
|
|
||||||
* @param Value
|
|
||||||
* The value to set. TRUE if the list has only one entry, FALSE otherwise.
|
|
||||||
*
|
|
||||||
* @return This routine does not return any value.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
VOID
|
|
||||||
MM::Paging::SetOneEntry(IN PMMPTE Pte,
|
|
||||||
IN BOOLEAN Value)
|
|
||||||
{
|
|
||||||
/* Set one entry status */
|
|
||||||
PmlRoutines->SetOneEntry(Pte, Value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets a Page Table Entry (PTE) with the specified physical page and access flags.
|
|
||||||
*
|
*
|
||||||
* @param PtePointer
|
* @param PtePointer
|
||||||
* Pointer to the page table entry (PTE) to set.
|
* Pointer to the page table entry (PTE) to set.
|
||||||
@@ -549,8 +212,8 @@ MM::Paging::SetOneEntry(IN PMMPTE Pte,
|
|||||||
* @param PageFrameNumber
|
* @param PageFrameNumber
|
||||||
* Physical frame number to map.
|
* Physical frame number to map.
|
||||||
*
|
*
|
||||||
* @param AttributesMask
|
* @param Writable
|
||||||
* Specifies the attributes mask to apply to the PTE.
|
* Indicates whether the page should be writable.
|
||||||
*
|
*
|
||||||
* @return This routine does not return any value.
|
* @return This routine does not return any value.
|
||||||
*
|
*
|
||||||
@@ -558,33 +221,11 @@ MM::Paging::SetOneEntry(IN PMMPTE Pte,
|
|||||||
*/
|
*/
|
||||||
XTAPI
|
XTAPI
|
||||||
VOID
|
VOID
|
||||||
MM::Paging::SetPte(IN PMMPTE PtePointer,
|
MM::Paging::SetPte(PHARDWARE_PTE PtePointer,
|
||||||
IN PFN_NUMBER PageFrameNumber,
|
PFN_NUMBER PageFrameNumber,
|
||||||
IN ULONG_PTR AttributesMask)
|
BOOLEAN Writable)
|
||||||
{
|
{
|
||||||
/* Set PTE */
|
PmlRoutines->SetPte(PtePointer, PageFrameNumber, Writable);
|
||||||
PmlRoutines->SetPte(PtePointer, PageFrameNumber, AttributesMask);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets a Page Table Entry (PTE) with the specified attributes.
|
|
||||||
*
|
|
||||||
* @param PtePointer
|
|
||||||
* Pointer to the page table entry (PTE) to set.
|
|
||||||
*
|
|
||||||
* @param Attributes
|
|
||||||
* Specifies the attributes to apply to the PTE.
|
|
||||||
*
|
|
||||||
* @return This routine does not return any value.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
VOID
|
|
||||||
MM::Paging::SetPte(IN PMMPTE PtePointer,
|
|
||||||
IN ULONG_PTR Attributes)
|
|
||||||
{
|
|
||||||
PmlRoutines->SetPte(PtePointer, Attributes);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -605,54 +246,9 @@ MM::Paging::SetPte(IN PMMPTE PtePointer,
|
|||||||
*/
|
*/
|
||||||
XTAPI
|
XTAPI
|
||||||
VOID
|
VOID
|
||||||
MM::Paging::SetPteCaching(IN PMMPTE PtePointer,
|
MM::Paging::SetPteCaching(PHARDWARE_PTE PtePointer,
|
||||||
IN BOOLEAN CacheDisable,
|
BOOLEAN CacheDisable,
|
||||||
IN BOOLEAN WriteThrough)
|
BOOLEAN WriteThrough)
|
||||||
{
|
{
|
||||||
/* Set caching attributes */
|
|
||||||
PmlRoutines->SetPteCaching(PtePointer, CacheDisable, WriteThrough);
|
PmlRoutines->SetPteCaching(PtePointer, CacheDisable, WriteThrough);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Transitions a Page Table Entry (PTE) to invalid state
|
|
||||||
*
|
|
||||||
* @param PointerPte
|
|
||||||
* Pointer to the page table entry (PTE) to transition.
|
|
||||||
*
|
|
||||||
* @param Protection
|
|
||||||
* Specifies the protection attribute to apply to the PTE.
|
|
||||||
*
|
|
||||||
* @return This routine does not return any value.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
VOID
|
|
||||||
MM::Paging::TransitionPte(IN PMMPTE PointerPte,
|
|
||||||
IN ULONG_PTR Protection)
|
|
||||||
{
|
|
||||||
/* Transition PTE */
|
|
||||||
PmlRoutines->TransitionPte(PointerPte, Protection);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Writes a Page Table Entry (PTE) with the specified value.
|
|
||||||
*
|
|
||||||
* @param Pte
|
|
||||||
* Pointer to the page table entry (PTE) to write.
|
|
||||||
*
|
|
||||||
* @param Value
|
|
||||||
* The value to write to the PTE.
|
|
||||||
*
|
|
||||||
* @return This routine does not return any value.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
VOID
|
|
||||||
MM::Paging::WritePte(IN PMMPTE Pte,
|
|
||||||
IN MMPTE Value)
|
|
||||||
{
|
|
||||||
/* Assign PTE value */
|
|
||||||
PmlRoutines->WritePte(Pte, Value);
|
|
||||||
}
|
|
||||||
|
|||||||
1319
xtoskrnl/mm/pfn.cc
1319
xtoskrnl/mm/pfn.cc
File diff suppressed because it is too large
Load Diff
@@ -1,546 +0,0 @@
|
|||||||
/**
|
|
||||||
* PROJECT: ExectOS
|
|
||||||
* COPYRIGHT: See COPYING.md in the top level directory
|
|
||||||
* FILE: xtoskrnl/mm/pte.cc
|
|
||||||
* DESCRIPTION: Page Table Entry (PTE) support
|
|
||||||
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <xtos.hh>
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Finds a free cluster of system PTEs that can satisfy a given size.
|
|
||||||
*
|
|
||||||
* @param NumberOfPtes
|
|
||||||
* The number of contiguous PTEs required.
|
|
||||||
*
|
|
||||||
* @param SystemPtePoolType
|
|
||||||
* Specifies the system PTE pool to search within.
|
|
||||||
*
|
|
||||||
* @param FoundCluster
|
|
||||||
* On success, receives a pointer to the first PTE of the found cluster.
|
|
||||||
*
|
|
||||||
* @param PreviousClusterNode
|
|
||||||
* On success, receives a pointer to the list node that precedes the found cluster.
|
|
||||||
*
|
|
||||||
* @return This routine returns TRUE if a suitable cluster was found, FALSE otherwise.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
BOOLEAN
|
|
||||||
MM::Pte::FindFreeCluster(IN PFN_COUNT NumberOfPtes,
|
|
||||||
IN MMSYSTEM_PTE_POOL_TYPE SystemPtePoolType,
|
|
||||||
OUT PMMPTE *FoundCluster,
|
|
||||||
OUT PMMPTE *PreviousClusterNode)
|
|
||||||
{
|
|
||||||
PMMPTE CurrentCluster;
|
|
||||||
PMMPTE PreviousNode = &FirstSystemFreePte[SystemPtePoolType];
|
|
||||||
ULONG ClusterSize;
|
|
||||||
|
|
||||||
/* Find a free PTE cluster large enough for the request */
|
|
||||||
while(MM::Paging::GetNextEntry(PreviousNode) != MAXULONG)
|
|
||||||
{
|
|
||||||
/* Retrieve the cluster and its size */
|
|
||||||
CurrentCluster = MM::Paging::AdvancePte(SystemPteBase, MM::Paging::GetNextEntry(PreviousNode));
|
|
||||||
ClusterSize = GetClusterSize(CurrentCluster);
|
|
||||||
|
|
||||||
/* Check if this cluster is large enough */
|
|
||||||
if(NumberOfPtes <= ClusterSize)
|
|
||||||
{
|
|
||||||
/* Found a suitable cluster */
|
|
||||||
*FoundCluster = CurrentCluster;
|
|
||||||
*PreviousClusterNode = PreviousNode;
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* This cluster is too small, check the next one */
|
|
||||||
PreviousNode = CurrentCluster;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* No suitable cluster was found */
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Decodes and returns the size of a free PTE cluster.
|
|
||||||
*
|
|
||||||
* @param Pte
|
|
||||||
* Supplies a pointer to the first PTE of the free cluster to inspect.
|
|
||||||
*
|
|
||||||
* @return This routine returns the total number of contiguous PTEs in the free cluster.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
ULONG
|
|
||||||
MM::Pte::GetClusterSize(IN PMMPTE Pte)
|
|
||||||
{
|
|
||||||
/* A special flag in the first PTE indicates a free cluster of size one */
|
|
||||||
if(MM::Paging::GetOneEntry(Pte))
|
|
||||||
{
|
|
||||||
/* Flag is set, so the cluster size is 1 by definition */
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* For larger clusters, the size is encoded in the second PTE of the block */
|
|
||||||
Pte = MM::Paging::GetNextPte(Pte);
|
|
||||||
return MM::Paging::GetNextEntry(Pte);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Calculates the number of Page Table Entries (PTEs) that fit within a single page.
|
|
||||||
*
|
|
||||||
* @return This routine returns the number of PTEs per page.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
PFN_COUNT
|
|
||||||
MM::Pte::GetPtesPerPage(VOID)
|
|
||||||
{
|
|
||||||
/* Calculate and return the number of PTEs per page */
|
|
||||||
return MM_PAGE_SIZE / MM::Paging::GetPteSize();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a pointer to the valid PTE.
|
|
||||||
*
|
|
||||||
* @return This routine returns a pointer to the valid PTE.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
PMMPTE
|
|
||||||
MM::Pte::GetValidPte()
|
|
||||||
{
|
|
||||||
/* Return a pointer to the valid PTE */
|
|
||||||
return &ValidPte;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initializes the system's PTE.
|
|
||||||
*
|
|
||||||
* @return This routine does not return any value.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
VOID
|
|
||||||
MM::Pte::InitializeSystemPte(VOID)
|
|
||||||
{
|
|
||||||
/* Initialize the PTE template */
|
|
||||||
MM::Paging::SetPte(&ValidPte, MM_PTE_VALID | MM_PTE_EXECUTE_READWRITE | MM_PTE_DIRTY | MM_PTE_ACCESSED);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Formats a range of PTEs into a freelist-based pool for system allocations.
|
|
||||||
*
|
|
||||||
* @param StartingPte
|
|
||||||
* Supplies a pointer to the start of the PTE range to be formatted.
|
|
||||||
*
|
|
||||||
* @param NumberOfPtes
|
|
||||||
* Supplies the total number of PTEs in the contiguous range.
|
|
||||||
*
|
|
||||||
* @param PoolType
|
|
||||||
* The system PTE pool type that this range will be used for.
|
|
||||||
*
|
|
||||||
* @return This routine does not return any value.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
VOID
|
|
||||||
MM::Pte::InitializeSystemPtePool(IN PMMPTE StartingPte,
|
|
||||||
IN PFN_COUNT NumberOfPtes,
|
|
||||||
IN MMSYSTEM_PTE_POOL_TYPE PoolType)
|
|
||||||
{
|
|
||||||
/* Set the system PTE base address */
|
|
||||||
SystemPteBase = GetSystemPteBaseAddress();
|
|
||||||
|
|
||||||
/* Record the boundaries of this new PTE pool */
|
|
||||||
SystemPtesStart[PoolType] = StartingPte;
|
|
||||||
SystemPtesEnd[PoolType] = MM::Paging::AdvancePte(StartingPte, NumberOfPtes - 1);
|
|
||||||
|
|
||||||
/* Zero the memory for the new PTE pool before use */
|
|
||||||
RTL::Memory::ZeroMemory(StartingPte, NumberOfPtes * MM::Paging::GetPteSize());
|
|
||||||
|
|
||||||
/* Build the free list head to point to the start of the pool */
|
|
||||||
MM::Paging::SetNextEntry(StartingPte, MAXULONG);
|
|
||||||
MM::Paging::ClearPte(&FirstSystemFreePte[PoolType]);
|
|
||||||
MM::Paging::SetNextEntry(&FirstSystemFreePte[PoolType], MM::Paging::GetPteDistance(StartingPte, SystemPteBase));
|
|
||||||
|
|
||||||
/* Use the second PTE slot to store the total size of this pool */
|
|
||||||
StartingPte = MM::Paging::GetNextPte(StartingPte);
|
|
||||||
MM::Paging::ClearPte(StartingPte);
|
|
||||||
MM::Paging::SetNextEntry(StartingPte, NumberOfPtes);
|
|
||||||
|
|
||||||
/* Record the total number of free PTEs in this pool */
|
|
||||||
TotalSystemFreePtes[PoolType] = NumberOfPtes;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets up the entire system PTE address space.
|
|
||||||
*
|
|
||||||
* @return This routine does not return any value.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
VOID
|
|
||||||
MM::Pte::InitializeSystemPteSpace(VOID)
|
|
||||||
{
|
|
||||||
PMMPTE PointerPte;
|
|
||||||
PMMPTE FirstZeroingPte;
|
|
||||||
PMMMEMORY_LAYOUT MemoryLayout;
|
|
||||||
ULONGLONG NonPagedSystemPoolEnd;
|
|
||||||
|
|
||||||
/* Retrieve the system's memory layout */
|
|
||||||
MemoryLayout = MM::Manager::GetMemoryLayout();
|
|
||||||
|
|
||||||
NonPagedSystemPoolEnd = ((ULONGLONG)MemoryLayout->NonPagedSystemPoolStart +
|
|
||||||
MM::Manager::GetNumberOfSystemPtes() * MM_PAGE_SIZE);
|
|
||||||
|
|
||||||
/* Map the page table hierarchy for the entire system PTE space */
|
|
||||||
MM::Pte::MapPPE(MemoryLayout->NonPagedSystemPoolStart, (PVOID)NonPagedSystemPoolEnd, &ValidPte);
|
|
||||||
MM::Pte::MapPDE(MemoryLayout->NonPagedSystemPoolStart, (PVOID)NonPagedSystemPoolEnd, &ValidPte);
|
|
||||||
|
|
||||||
/* Format the main block of system PTEs into a free list pool */
|
|
||||||
PointerPte = MM::Paging::GetPteAddress(MemoryLayout->NonPagedSystemPoolStart);
|
|
||||||
|
|
||||||
InitializeSystemPtePool(PointerPte, MM::Manager::GetNumberOfSystemPtes(), SystemPteSpace);
|
|
||||||
|
|
||||||
/* Reserve and zero a dedicated block of system PTEs */
|
|
||||||
FirstZeroingPte = ReserveSystemPtes(MM_RESERVED_ZERO_PTES + 1, SystemPteSpace);
|
|
||||||
RTL::Memory::ZeroMemory(FirstZeroingPte, (MM_RESERVED_ZERO_PTES + 1) * MM::Paging::GetPteSize());
|
|
||||||
|
|
||||||
/* Use the first PTE of this block as a counter for available zeroing PTEs */
|
|
||||||
MM::Paging::SetPte(FirstZeroingPte, MM_RESERVED_ZERO_PTES, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Maps a range of virtual addresses at the PDE (Page Directory Entry) level.
|
|
||||||
*
|
|
||||||
* @param StartAddress
|
|
||||||
* The beginning of the virtual address range to map.
|
|
||||||
*
|
|
||||||
* @param EndAddress
|
|
||||||
* The end of the virtual address range to map.
|
|
||||||
*
|
|
||||||
* @param TemplatePde
|
|
||||||
* A template PDE to use for creating new entries.
|
|
||||||
*
|
|
||||||
* @return This routine does not return any value.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
VOID
|
|
||||||
MM::Pte::MapPDE(IN PVOID StartAddress,
|
|
||||||
IN PVOID EndAddress,
|
|
||||||
IN PMMPDE TemplatePde)
|
|
||||||
{
|
|
||||||
PMMPDE EndSpace, PointerPde;
|
|
||||||
|
|
||||||
/* Get PDE addresses */
|
|
||||||
PointerPde = MM::Paging::GetPdeAddress(StartAddress);
|
|
||||||
EndSpace = MM::Paging::GetPdeAddress(EndAddress);
|
|
||||||
|
|
||||||
/* Iterate over all PDEs */
|
|
||||||
while(PointerPde <= EndSpace)
|
|
||||||
{
|
|
||||||
/* Check if PDE is already mapped */
|
|
||||||
if(!MM::Paging::PteValid(PointerPde))
|
|
||||||
{
|
|
||||||
/* Map PDE */
|
|
||||||
MM::Paging::SetPte(TemplatePde, MM::Pfn::AllocateBootstrapPages(1), 0);
|
|
||||||
MM::Paging::WritePte(PointerPde, *TemplatePde);
|
|
||||||
|
|
||||||
/* Clear the page table */
|
|
||||||
RTL::Memory::ZeroMemory(MM::Paging::GetPteVirtualAddress(PointerPde), MM_PAGE_SIZE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get next table entry */
|
|
||||||
PointerPde = MM::Paging::GetNextPte(PointerPde);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Maps a range of virtual addresses at the PTE (Page Table Entry) level.
|
|
||||||
*
|
|
||||||
* @param StartAddress
|
|
||||||
* The beginning of the virtual address range to map.
|
|
||||||
*
|
|
||||||
* @param EndAddress
|
|
||||||
* The end of the virtual address range to map.
|
|
||||||
*
|
|
||||||
* @param TemplatePte
|
|
||||||
* A template PTE to use for creating new entries.
|
|
||||||
*
|
|
||||||
* @return This routine does not return any value.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
VOID
|
|
||||||
MM::Pte::MapPTE(IN PVOID StartAddress,
|
|
||||||
IN PVOID EndAddress,
|
|
||||||
IN PMMPTE TemplatePte)
|
|
||||||
{
|
|
||||||
PMMPTE EndSpace, PointerPte;
|
|
||||||
|
|
||||||
/* Get PTE addresses */
|
|
||||||
PointerPte = MM::Paging::GetPteAddress(StartAddress);
|
|
||||||
EndSpace = MM::Paging::GetPteAddress(EndAddress);
|
|
||||||
|
|
||||||
/* Iterate over all PTEs */
|
|
||||||
while(PointerPte <= EndSpace)
|
|
||||||
{
|
|
||||||
/* Check if PTE is already mapped */
|
|
||||||
if(!MM::Paging::PteValid(PointerPte))
|
|
||||||
{
|
|
||||||
/* Map PTE */
|
|
||||||
MM::Paging::SetPte(TemplatePte, MM::Pfn::AllocateBootstrapPages(1), 0);
|
|
||||||
MM::Paging::WritePte(PointerPte, *TemplatePte);
|
|
||||||
|
|
||||||
/* Clear the page table */
|
|
||||||
RTL::Memory::ZeroMemory(MM::Paging::GetPteVirtualAddress(PointerPte), MM_PAGE_SIZE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get next table entry */
|
|
||||||
PointerPte = MM::Paging::GetNextPte(PointerPte);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Releases a block of system PTEs into a specified pool.
|
|
||||||
*
|
|
||||||
* @param StartingPte
|
|
||||||
* A pointer to the first PTE to release.
|
|
||||||
*
|
|
||||||
* @param NumberOfPtes
|
|
||||||
* The number of contiguous PTEs to release.
|
|
||||||
*
|
|
||||||
* @param SystemPtePoolType
|
|
||||||
* Specifies the system PTE pool to release into.
|
|
||||||
*
|
|
||||||
* @return This routine does not return any value.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
VOID
|
|
||||||
MM::Pte::ReleaseSystemPtes(IN PMMPTE StartingPte,
|
|
||||||
IN PFN_COUNT NumberOfPtes,
|
|
||||||
IN MMSYSTEM_PTE_POOL_TYPE SystemPtePoolType)
|
|
||||||
{
|
|
||||||
PMMPTE NextPte, PreviousPte, ReleasedPte;
|
|
||||||
ULONG ClusterSize;
|
|
||||||
|
|
||||||
/* Clear the PTEs before releasing them */
|
|
||||||
RtlZeroMemory(StartingPte, NumberOfPtes * MM::Paging::GetPteSize());
|
|
||||||
|
|
||||||
/* Raise runlevel and acquire lock to protect the PTE pool */
|
|
||||||
KE::RaiseRunLevel RunLevel(DISPATCH_LEVEL);
|
|
||||||
KE::QueuedSpinLockGuard SpinLock(SystemSpaceLock);
|
|
||||||
|
|
||||||
/* Increment the total number of available PTEs in this pool */
|
|
||||||
TotalSystemFreePtes[SystemPtePoolType] += NumberOfPtes;
|
|
||||||
|
|
||||||
/* Start at the head of the free list for this pool */
|
|
||||||
PreviousPte = &FirstSystemFreePte[SystemPtePoolType];
|
|
||||||
ReleasedPte = NULLPTR;
|
|
||||||
|
|
||||||
/* Iterate through the free list to find adjacent blocks */
|
|
||||||
while(MM::Paging::GetNextEntry(PreviousPte) != MAXULONG)
|
|
||||||
{
|
|
||||||
/* Get the next free cluster to check its size */
|
|
||||||
NextPte = MM::Paging::AdvancePte(SystemPteBase, MM::Paging::GetNextEntry(PreviousPte));
|
|
||||||
ClusterSize = GetClusterSize(NextPte);
|
|
||||||
|
|
||||||
/* Check if the released block is adjacent to the current free block */
|
|
||||||
if((MM::Paging::AdvancePte(NextPte, ClusterSize) == StartingPte) ||
|
|
||||||
(MM::Paging::AdvancePte(StartingPte, NumberOfPtes) == NextPte))
|
|
||||||
{
|
|
||||||
/* Merge the blocks by adding their sizes */
|
|
||||||
NumberOfPtes += ClusterSize;
|
|
||||||
|
|
||||||
/* Check if the current free block is before the released block */
|
|
||||||
if(NextPte < StartingPte)
|
|
||||||
{
|
|
||||||
/* The new merged block starts at the current free block's address */
|
|
||||||
StartingPte = NextPte;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Unlink the current free block as it is being merged */
|
|
||||||
MM::Paging::SetNextEntry(PreviousPte, MM::Paging::GetNextEntry(NextPte));
|
|
||||||
|
|
||||||
/* Check if the block represents more than one PTE */
|
|
||||||
if(!MM::Paging::GetOneEntry(NextPte))
|
|
||||||
{
|
|
||||||
/* Clear block header and move to the size PTE */
|
|
||||||
MM::Paging::ClearPte(NextPte);
|
|
||||||
NextPte = MM::Paging::GetNextPte(NextPte);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Clear the merged block */
|
|
||||||
MM::Paging::ClearPte(NextPte);
|
|
||||||
|
|
||||||
/* Reset insertion point since block size/address changed due to merge */
|
|
||||||
ReleasedPte = NULLPTR;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Select the first free block large enough as insertion point */
|
|
||||||
if((ReleasedPte == NULLPTR) && (NumberOfPtes <= ClusterSize))
|
|
||||||
{
|
|
||||||
/* Mark this as the insertion point */
|
|
||||||
ReleasedPte = PreviousPte;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Advance to the next free block */
|
|
||||||
PreviousPte = NextPte;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check if there is only one PTE to release */
|
|
||||||
if(NumberOfPtes == 1)
|
|
||||||
{
|
|
||||||
/* Mark it as a single-PTE block */
|
|
||||||
MM::Paging::SetOneEntry(StartingPte, 1);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Otherwise, mark it as a multi-PTE block */
|
|
||||||
MM::Paging::SetOneEntry(StartingPte, 0);
|
|
||||||
|
|
||||||
/* The next PTE stores the size of the block */
|
|
||||||
NextPte = MM::Paging::GetNextPte(StartingPte);
|
|
||||||
MM::Paging::SetNextEntry(NextPte, NumberOfPtes);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check if no suitable insertion point was found */
|
|
||||||
if(ReleasedPte == NULLPTR)
|
|
||||||
{
|
|
||||||
/* Insert at the end of the list */
|
|
||||||
ReleasedPte = PreviousPte;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Link the new block into the free list */
|
|
||||||
MM::Paging::SetNextEntry(StartingPte, MM::Paging::GetNextEntry(ReleasedPte));
|
|
||||||
MM::Paging::SetNextEntry(ReleasedPte, MM::Paging::GetPteDistance(StartingPte, SystemPteBase));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reserves a contiguous block of system PTEs from a specified pool.
|
|
||||||
*
|
|
||||||
* @param NumberOfPtes
|
|
||||||
* The number of contiguous PTEs to reserve.
|
|
||||||
*
|
|
||||||
* @param SystemPtePoolType
|
|
||||||
* Specifies the system PTE pool from which to allocate.
|
|
||||||
*
|
|
||||||
* @return This routine returns a pointer to the beginning of the reserved block,
|
|
||||||
* or NULLPTR if not enough contiguous PTEs are available.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
PMMPTE
|
|
||||||
MM::Pte::ReserveSystemPtes(IN PFN_COUNT NumberOfPtes,
|
|
||||||
IN MMSYSTEM_PTE_POOL_TYPE SystemPtePoolType)
|
|
||||||
{
|
|
||||||
PMMPTE NextPte, PreviousPte, ReservedPte;
|
|
||||||
ULONG ClusterSize;
|
|
||||||
|
|
||||||
/* Raise runlevel and acquire lock to protect the PTE pool */
|
|
||||||
KE::RaiseRunLevel RunLevel(DISPATCH_LEVEL);
|
|
||||||
KE::QueuedSpinLockGuard SpinLock(SystemSpaceLock);
|
|
||||||
|
|
||||||
/* Find a free PTE cluster large enough for the request */
|
|
||||||
if(!FindFreeCluster(NumberOfPtes, SystemPtePoolType, &NextPte, &PreviousPte))
|
|
||||||
{
|
|
||||||
/* Out of system PTEs for this pool, return NULLPTR */
|
|
||||||
return NULLPTR;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* We have the cluster, now get its size for the allocation logic below */
|
|
||||||
ClusterSize = GetClusterSize(NextPte);
|
|
||||||
|
|
||||||
/* Unlink the found cluster from the free list for processing */
|
|
||||||
MM::Paging::SetNextEntry(PreviousPte, MM::Paging::GetNextEntry(NextPte));
|
|
||||||
|
|
||||||
/* Handle the allocation based on whether the cluster size is an exact match */
|
|
||||||
if(ClusterSize == NumberOfPtes)
|
|
||||||
{
|
|
||||||
/* Exact match, allocate the entire cluster */
|
|
||||||
ReservedPte = NextPte;
|
|
||||||
|
|
||||||
/* Handle metadata cleanup for a single-PTE cluster */
|
|
||||||
if(MM::Paging::GetOneEntry(NextPte))
|
|
||||||
{
|
|
||||||
/* Clear the PTE that held the list metadata */
|
|
||||||
MM::Paging::ClearPte(NextPte);
|
|
||||||
NextPte = MM::Paging::GetNextPte(NextPte);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Clear the PTE that held the cluster size */
|
|
||||||
MM::Paging::ClearPte(NextPte);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Cluster is larger than needed, so it will be split */
|
|
||||||
ClusterSize -= NumberOfPtes;
|
|
||||||
ReservedPte = MM::Paging::AdvancePte(NextPte, ClusterSize);
|
|
||||||
|
|
||||||
/* Update metadata for the new, smaller leftover cluster */
|
|
||||||
if(ClusterSize == 1)
|
|
||||||
{
|
|
||||||
/* The leftover fragment is a single PTE */
|
|
||||||
MM::Paging::SetOneEntry(NextPte, 1);
|
|
||||||
MM::Paging::ClearPte(ReservedPte);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* The leftover fragment is larger than one PTE */
|
|
||||||
NextPte = MM::Paging::GetNextPte(NextPte);
|
|
||||||
MM::Paging::SetNextEntry(NextPte, ClusterSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Find the correct sorted position to re-insert the leftover fragment */
|
|
||||||
PreviousPte = &FirstSystemFreePte[SystemPtePoolType];
|
|
||||||
while(MM::Paging::GetNextEntry(PreviousPte) != MAXULONG)
|
|
||||||
{
|
|
||||||
/* Get the next free cluster to check its size */
|
|
||||||
NextPte = MM::Paging::AdvancePte(SystemPteBase, MM::Paging::GetNextEntry(PreviousPte));
|
|
||||||
|
|
||||||
/* Check if the leftover fragment should be inserted here */
|
|
||||||
if(ClusterSize <= GetClusterSize(NextPte))
|
|
||||||
{
|
|
||||||
/* Found the correct sorted position */
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Advance to the next entry */
|
|
||||||
PreviousPte = NextPte;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get a pointer to the start of the leftover fragment */
|
|
||||||
NextPte = MM::Paging::AdvancePte(ReservedPte, -ClusterSize);
|
|
||||||
|
|
||||||
/* Insert the leftover fragment back into the free list at its sorted position */
|
|
||||||
MM::Paging::SetNextEntry(NextPte, MM::Paging::GetNextEntry(PreviousPte));
|
|
||||||
MM::Paging::SetNextEntry(PreviousPte, MM::Paging::GetPteDistance(NextPte, SystemPteBase));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Decrement the total number of available PTEs in this pool */
|
|
||||||
TotalSystemFreePtes[SystemPtePoolType] -= NumberOfPtes;
|
|
||||||
|
|
||||||
/* Flush the TLB to ensure address translation consistency */
|
|
||||||
AR::CpuFunc::FlushTlb();
|
|
||||||
|
|
||||||
/* Return a pointer to the start of the reserved PTE block */
|
|
||||||
return ReservedPte;
|
|
||||||
}
|
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
* PROJECT: ExectOS
|
* PROJECT: ExectOS
|
||||||
* COPYRIGHT: See COPYING.md in the top level directory
|
* COPYRIGHT: See COPYING.md in the top level directory
|
||||||
* FILE: xtoskrnl/rtl/llist.cc
|
* FILE: xtoskrnl/rtl/llist.cc
|
||||||
* DESCRIPTION: Doubly linked list manipulation routines
|
* DESCRIPTION: Linked list manipulation routines
|
||||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -10,35 +10,10 @@
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves the first entry from a doubly linked list without removing it from the list.
|
* This routine initializes a structure representing the head of a double-linked list.
|
||||||
*
|
*
|
||||||
* @param ListHead
|
* @param ListHead
|
||||||
* Supplies a pointer to a structure that serves as the list header.
|
* Pointer to a structure that serves as the list header.
|
||||||
*
|
|
||||||
* @return This routine returns a pointer to the first entry in the list, or NULLPTR if the list is empty.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTCDECL
|
|
||||||
PLIST_ENTRY
|
|
||||||
RTL::LinkedList::GetFirstEntry(IN PLIST_ENTRY ListHead)
|
|
||||||
{
|
|
||||||
/* Check if the list is empty */
|
|
||||||
if(ListEmpty(ListHead))
|
|
||||||
{
|
|
||||||
/* Empty list, return NULLPTR */
|
|
||||||
return NULLPTR;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Return first entry in the list */
|
|
||||||
return ListHead->Flink;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initializes a structure representing the head of a doubly linked list.
|
|
||||||
*
|
|
||||||
* @param ListHead
|
|
||||||
* Supplies a pointer to a structure that serves as the list header.
|
|
||||||
*
|
*
|
||||||
* @return This routine does not return any value.
|
* @return This routine does not return any value.
|
||||||
*
|
*
|
||||||
@@ -48,16 +23,15 @@ XTCDECL
|
|||||||
VOID
|
VOID
|
||||||
RTL::LinkedList::InitializeListHead(IN PLIST_ENTRY ListHead)
|
RTL::LinkedList::InitializeListHead(IN PLIST_ENTRY ListHead)
|
||||||
{
|
{
|
||||||
/* Initialize list head */
|
|
||||||
ListHead->Blink = ListHead;
|
ListHead->Blink = ListHead;
|
||||||
ListHead->Flink = ListHead;
|
ListHead->Flink = ListHead;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes a structure representing the head of a 32bit doubly linked list.
|
* This routine initializes a structure representing the head of a 32bit double-linked list.
|
||||||
*
|
*
|
||||||
* @param ListHead
|
* @param ListHead
|
||||||
* Supplies a pointer to a structure that serves as the list header.
|
* Pointer to a structure that serves as the list header.
|
||||||
*
|
*
|
||||||
* @return This routine does not return any value.
|
* @return This routine does not return any value.
|
||||||
*
|
*
|
||||||
@@ -67,19 +41,18 @@ XTCDECL
|
|||||||
VOID
|
VOID
|
||||||
RTL::LinkedList::InitializeListHead32(IN PLIST_ENTRY32 ListHead)
|
RTL::LinkedList::InitializeListHead32(IN PLIST_ENTRY32 ListHead)
|
||||||
{
|
{
|
||||||
/* Initialize list head */
|
|
||||||
ListHead->Blink = PtrToUlong(ListHead);
|
ListHead->Blink = PtrToUlong(ListHead);
|
||||||
ListHead->Flink = PtrToUlong(ListHead);
|
ListHead->Flink = PtrToUlong(ListHead);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Inserts an entry at the head of a doubly linked list.
|
* This routine inserts an entry at the head of a doubly linked list.
|
||||||
*
|
*
|
||||||
* @param ListHead
|
* @param ListHead
|
||||||
* Supplies a pointer to the head of the list.
|
* Pointer to the head of the list.
|
||||||
*
|
*
|
||||||
* @param Entry
|
* @param Entry
|
||||||
* Supplies a pointer to the entry that will be inserted in the list.
|
* Pointer to the entry that will be inserted in the list.
|
||||||
*
|
*
|
||||||
* @return This routine does not return any value.
|
* @return This routine does not return any value.
|
||||||
*
|
*
|
||||||
@@ -90,7 +63,6 @@ VOID
|
|||||||
RTL::LinkedList::InsertHeadList(IN OUT PLIST_ENTRY ListHead,
|
RTL::LinkedList::InsertHeadList(IN OUT PLIST_ENTRY ListHead,
|
||||||
IN PLIST_ENTRY Entry)
|
IN PLIST_ENTRY Entry)
|
||||||
{
|
{
|
||||||
/* Insert entry at the head of the list */
|
|
||||||
Entry->Flink = ListHead->Flink;
|
Entry->Flink = ListHead->Flink;
|
||||||
Entry->Blink = ListHead;
|
Entry->Blink = ListHead;
|
||||||
ListHead->Flink->Blink = Entry;
|
ListHead->Flink->Blink = Entry;
|
||||||
@@ -98,13 +70,13 @@ RTL::LinkedList::InsertHeadList(IN OUT PLIST_ENTRY ListHead,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Inserts an entry at the tail of a doubly linked list.
|
* This routine inserts an entry at the tail of a doubly linked list.
|
||||||
*
|
*
|
||||||
* @param ListHead
|
* @param ListHead
|
||||||
* Supplies a pointer to the head of the list.
|
* Pointer to the head of the list.
|
||||||
*
|
*
|
||||||
* @param Entry
|
* @param Entry
|
||||||
* Supplies a pointer to the entry that will be inserted in the list.
|
* Pointer to the entry that will be inserted in the list.
|
||||||
*
|
*
|
||||||
* @return This routine does not return any value.
|
* @return This routine does not return any value.
|
||||||
*
|
*
|
||||||
@@ -115,7 +87,6 @@ VOID
|
|||||||
RTL::LinkedList::InsertTailList(IN OUT PLIST_ENTRY ListHead,
|
RTL::LinkedList::InsertTailList(IN OUT PLIST_ENTRY ListHead,
|
||||||
IN PLIST_ENTRY Entry)
|
IN PLIST_ENTRY Entry)
|
||||||
{
|
{
|
||||||
/* Insert entry at the tail of the list */
|
|
||||||
Entry->Flink = ListHead;
|
Entry->Flink = ListHead;
|
||||||
Entry->Blink = ListHead->Blink;
|
Entry->Blink = ListHead->Blink;
|
||||||
ListHead->Blink->Flink = Entry;
|
ListHead->Blink->Flink = Entry;
|
||||||
@@ -126,9 +97,9 @@ RTL::LinkedList::InsertTailList(IN OUT PLIST_ENTRY ListHead,
|
|||||||
* Indicates whether a doubly linked list structure is empty, or not initialized at all.
|
* Indicates whether a doubly linked list structure is empty, or not initialized at all.
|
||||||
*
|
*
|
||||||
* @param ListHead
|
* @param ListHead
|
||||||
* Supplies a pointer to a structure that represents the head of the list.
|
* Pointer to a structure that represents the head of the list.
|
||||||
*
|
*
|
||||||
* @return This routine returns TRUE if there are currently no entries in the list or FALSE otherwise.
|
* @return TRUE if there are currently no entries in the list or FALSE otherwise.
|
||||||
*
|
*
|
||||||
* @since XT 1.0
|
* @since XT 1.0
|
||||||
*/
|
*/
|
||||||
@@ -136,15 +107,14 @@ XTCDECL
|
|||||||
BOOLEAN
|
BOOLEAN
|
||||||
RTL::LinkedList::ListEmpty(IN PLIST_ENTRY ListHead)
|
RTL::LinkedList::ListEmpty(IN PLIST_ENTRY ListHead)
|
||||||
{
|
{
|
||||||
/* Check if the list is empty */
|
|
||||||
return (((ListHead->Flink == NULLPTR) && (ListHead->Blink == NULLPTR)) || (ListHead->Flink == ListHead));
|
return (((ListHead->Flink == NULLPTR) && (ListHead->Blink == NULLPTR)) || (ListHead->Flink == ListHead));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Detects a loop in a doubly linked list.
|
* This routine detects a loop in a doubly linked list.
|
||||||
*
|
*
|
||||||
* @param ListHead
|
* @param ListHead
|
||||||
* Supplies a pointer to a structure that represents the head of the list.
|
* Pointer to a structure that represents the head of the list.
|
||||||
*
|
*
|
||||||
* @return TRUE if linked list contains a loop or FALSE otherwise.
|
* @return TRUE if linked list contains a loop or FALSE otherwise.
|
||||||
*
|
*
|
||||||
@@ -187,10 +157,10 @@ RTL::LinkedList::ListLoop(IN PLIST_ENTRY ListHead)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes an entry from a doubly linked list.
|
* This routine removes an entry from a doubly linked list.
|
||||||
*
|
*
|
||||||
* @param Entry
|
* @param Entry
|
||||||
* Supplies a pointer to the entry that will be removed from the list.
|
* Pointer to the entry that will be removed from the list.
|
||||||
*
|
*
|
||||||
* @return This routine does not return any value.
|
* @return This routine does not return any value.
|
||||||
*
|
*
|
||||||
@@ -200,91 +170,6 @@ XTCDECL
|
|||||||
VOID
|
VOID
|
||||||
RTL::LinkedList::RemoveEntryList(IN PLIST_ENTRY Entry)
|
RTL::LinkedList::RemoveEntryList(IN PLIST_ENTRY Entry)
|
||||||
{
|
{
|
||||||
/* Remove entry from the list */
|
|
||||||
Entry->Flink->Blink = Entry->Blink;
|
Entry->Flink->Blink = Entry->Blink;
|
||||||
Entry->Blink->Flink = Entry->Flink;
|
Entry->Blink->Flink = Entry->Flink;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Splices a doubly linked list at the head of another list. The source list is reinitialized to empty.
|
|
||||||
*
|
|
||||||
* @param ListHead
|
|
||||||
* Supplies a pointer to a structure that represents the head of the list.
|
|
||||||
*
|
|
||||||
* @param SpliceList
|
|
||||||
* Supplies a pointer to a structure that represents the head of the list that will be spliced.
|
|
||||||
*
|
|
||||||
* @return This routine does not return any value.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTCDECL
|
|
||||||
VOID
|
|
||||||
RTL::LinkedList::SpliceHeadList(IN OUT PLIST_ENTRY ListHead,
|
|
||||||
IN OUT PLIST_ENTRY SpliceList)
|
|
||||||
{
|
|
||||||
PLIST_ENTRY FirstEntry, LastEntry;
|
|
||||||
|
|
||||||
/* Check if the list to splice is empty */
|
|
||||||
if(SpliceList->Flink == SpliceList)
|
|
||||||
{
|
|
||||||
/* Nothing to splice, return */
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get first and last entries of the list to splice */
|
|
||||||
FirstEntry = SpliceList->Flink;
|
|
||||||
LastEntry = SpliceList->Blink;
|
|
||||||
|
|
||||||
/* Splice the list at the head of destination */
|
|
||||||
FirstEntry->Blink = ListHead;
|
|
||||||
LastEntry->Flink = ListHead->Flink;
|
|
||||||
ListHead->Flink->Blink = LastEntry;
|
|
||||||
ListHead->Flink = FirstEntry;
|
|
||||||
|
|
||||||
/* Reinitialize the source list to empty */
|
|
||||||
SpliceList->Blink = SpliceList;
|
|
||||||
SpliceList->Flink = SpliceList;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Splices a doubly linked list at the tail of another list. The source list is reinitialized to empty.
|
|
||||||
*
|
|
||||||
* @param ListHead
|
|
||||||
* Supplies a pointer to the head of the destination list.
|
|
||||||
*
|
|
||||||
* @param SpliceList
|
|
||||||
* Supplies a pointer to the head of the list that will be spliced.
|
|
||||||
*
|
|
||||||
* @return This routine does not return any value.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTCDECL
|
|
||||||
VOID
|
|
||||||
RTL::LinkedList::SpliceTailList(IN OUT PLIST_ENTRY ListHead,
|
|
||||||
IN OUT PLIST_ENTRY SpliceList)
|
|
||||||
{
|
|
||||||
PLIST_ENTRY FirstEntry, LastEntry;
|
|
||||||
|
|
||||||
/* Check if the list to splice is empty */
|
|
||||||
if(SpliceList->Flink == SpliceList)
|
|
||||||
{
|
|
||||||
/* Nothing to splice, return */
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get first and last entries of the list to splice */
|
|
||||||
FirstEntry = SpliceList->Flink;
|
|
||||||
LastEntry = SpliceList->Blink;
|
|
||||||
|
|
||||||
/* Splice the list at the tail of destination */
|
|
||||||
FirstEntry->Blink = ListHead->Blink;
|
|
||||||
LastEntry->Flink = ListHead;
|
|
||||||
ListHead->Blink->Flink = FirstEntry;
|
|
||||||
ListHead->Blink = LastEntry;
|
|
||||||
|
|
||||||
/* Reinitialize the source list to empty */
|
|
||||||
SpliceList->Blink = SpliceList;
|
|
||||||
SpliceList->Flink = SpliceList;
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,322 +0,0 @@
|
|||||||
/**
|
|
||||||
* PROJECT: ExectOS
|
|
||||||
* COPYRIGHT: See COPYING.md in the top level directory
|
|
||||||
* FILE: xtoskrnl/rtl/sha1.cc
|
|
||||||
* DESCRIPTION: SHA1 computation support
|
|
||||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <xtos.hh>
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Computes the SHA-1 hash of a buffer in a single step.
|
|
||||||
*
|
|
||||||
* @param Buffer
|
|
||||||
* Supplies a pointer to the buffer containing the data to be hashed.
|
|
||||||
*
|
|
||||||
* @param BufferSize
|
|
||||||
* Specifies the size of the buffer in bytes.
|
|
||||||
*
|
|
||||||
* @param Digest
|
|
||||||
* Supplies a pointer to the buffer that receives the 20-byte SHA-1 hash digest.
|
|
||||||
*
|
|
||||||
* @return This routine returns STATUS_SUCCESS if the hash was computed successfully,
|
|
||||||
* or STATUS_INVALID_PARAMETER if an invalid parameter was supplied.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
XTSTATUS
|
|
||||||
RTL::SHA1::ComputeDigest(IN PCUCHAR Buffer,
|
|
||||||
IN SIZE_T BufferSize,
|
|
||||||
OUT PUCHAR Digest)
|
|
||||||
{
|
|
||||||
RTL_SHA1_CONTEXT Context;
|
|
||||||
XTSTATUS Status;
|
|
||||||
|
|
||||||
/* Validate input parameters */
|
|
||||||
if(!Digest || (!Buffer && BufferSize > 0))
|
|
||||||
{
|
|
||||||
/* Invalid parameters, return error */
|
|
||||||
return STATUS_INVALID_PARAMETER;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Initialize SHA-1 context */
|
|
||||||
Status = InitializeContext(&Context);
|
|
||||||
if(Status != STATUS_SUCCESS)
|
|
||||||
{
|
|
||||||
/* Failed to initialize SHA-1 context, return error */
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Hash data and compute SHA-1 digest */
|
|
||||||
HashData(&Context, Buffer, BufferSize);
|
|
||||||
ComputeHash(&Context, Digest);
|
|
||||||
|
|
||||||
/* Return success */
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Finalizes the SHA-1 hash computation and provides the digest.
|
|
||||||
*
|
|
||||||
* @param Context
|
|
||||||
* Supplies a pointer to the SHA-1 context structure.
|
|
||||||
*
|
|
||||||
* @param Digest
|
|
||||||
* Supplies a pointer to a buffer that receives the 20-byte SHA-1 hash digest.
|
|
||||||
*
|
|
||||||
* @return This routine does not return any value.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
VOID
|
|
||||||
RTL::SHA1::ComputeHash(IN OUT PRTL_SHA1_CONTEXT Context,
|
|
||||||
OUT PUCHAR Digest)
|
|
||||||
{
|
|
||||||
ULONG Index, PaddingLength;
|
|
||||||
UCHAR Padding[64];
|
|
||||||
UCHAR Bits[8];
|
|
||||||
|
|
||||||
/* Zero padding and append 0x80 to it */
|
|
||||||
RTL::Memory::ZeroMemory(Padding, 64);
|
|
||||||
Padding[0] = 0x80;
|
|
||||||
|
|
||||||
/* Encode the total message length in bits as a Big Endian 64-bit integer */
|
|
||||||
*(PULONG)(Bits) = RTL::Endianness::SwapByte32(Context->Count[1]);
|
|
||||||
*(PULONG)(Bits + 4) = RTL::Endianness::SwapByte32(Context->Count[0]);
|
|
||||||
|
|
||||||
/* Calculate padding length needed to align the message to 56 bytes */
|
|
||||||
Index = (Context->Count[0] >> 3) & 0x3F;
|
|
||||||
PaddingLength = (Index < 56) ? (56 - Index) : (120 - Index);
|
|
||||||
|
|
||||||
/* Append the padding bytes to the message stream to satisfy the block boundary */
|
|
||||||
HashData(Context, Padding, PaddingLength);
|
|
||||||
|
|
||||||
/* Append bits before final transformation */
|
|
||||||
HashData(Context, Bits, 8);
|
|
||||||
|
|
||||||
/* Store hash to output in Big Endian format */
|
|
||||||
Digest[0] = (UCHAR)((Context->State[0] >> 24) & 0xFF);
|
|
||||||
Digest[1] = (UCHAR)((Context->State[0] >> 16) & 0xFF);
|
|
||||||
Digest[2] = (UCHAR)((Context->State[0] >> 8) & 0xFF);
|
|
||||||
Digest[3] = (UCHAR)(Context->State[0] & 0xFF);
|
|
||||||
Digest[4] = (UCHAR)((Context->State[1] >> 24) & 0xFF);
|
|
||||||
Digest[5] = (UCHAR)((Context->State[1] >> 16) & 0xFF);
|
|
||||||
Digest[6] = (UCHAR)((Context->State[1] >> 8) & 0xFF);
|
|
||||||
Digest[7] = (UCHAR)(Context->State[1] & 0xFF);
|
|
||||||
Digest[8] = (UCHAR)((Context->State[2] >> 24) & 0xFF);
|
|
||||||
Digest[9] = (UCHAR)((Context->State[2] >> 16) & 0xFF);
|
|
||||||
Digest[10] = (UCHAR)((Context->State[2] >> 8) & 0xFF);
|
|
||||||
Digest[11] = (UCHAR)(Context->State[2] & 0xFF);
|
|
||||||
Digest[12] = (UCHAR)((Context->State[3] >> 24) & 0xFF);
|
|
||||||
Digest[13] = (UCHAR)((Context->State[3] >> 16) & 0xFF);
|
|
||||||
Digest[14] = (UCHAR)((Context->State[3] >> 8) & 0xFF);
|
|
||||||
Digest[15] = (UCHAR)(Context->State[3] & 0xFF);
|
|
||||||
Digest[16] = (UCHAR)((Context->State[4] >> 24) & 0xFF);
|
|
||||||
Digest[17] = (UCHAR)((Context->State[4] >> 16) & 0xFF);
|
|
||||||
Digest[18] = (UCHAR)((Context->State[4] >> 8) & 0xFF);
|
|
||||||
Digest[19] = (UCHAR)(Context->State[4] & 0xFF);
|
|
||||||
|
|
||||||
/* Clear context memory for security */
|
|
||||||
RTL::Memory::ZeroMemory(Context, sizeof(RTL_SHA1_CONTEXT));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Updates the SHA-1 context with the provided data buffer.
|
|
||||||
*
|
|
||||||
* @param Context
|
|
||||||
* Supplies a pointer to the SHA-1 context structure.
|
|
||||||
*
|
|
||||||
* @param Data
|
|
||||||
* Supplies a pointer to the buffer containing the data to be hashed.
|
|
||||||
*
|
|
||||||
* @param Length
|
|
||||||
* Specifies the length of the data buffer in bytes.
|
|
||||||
*
|
|
||||||
* @return This routine does not return any value.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
VOID
|
|
||||||
RTL::SHA1::HashData(IN OUT PRTL_SHA1_CONTEXT Context,
|
|
||||||
IN PCUCHAR Data,
|
|
||||||
IN ULONG Length)
|
|
||||||
{
|
|
||||||
ULONG Index, Input, PartialLength;
|
|
||||||
|
|
||||||
/* Calculate byte offset within the 64-byte block buffer */
|
|
||||||
Index = (Context->Count[0] >> 3) & 0x3F;
|
|
||||||
|
|
||||||
/* Update the total bit count, handling overflow from low to high word */
|
|
||||||
if((Context->Count[0] += (Length << 3)) < (Length << 3))
|
|
||||||
{
|
|
||||||
/* Increment high 32-bit counter on low counter overflow */
|
|
||||||
Context->Count[1]++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Add the high-order bits of the length (bytes -> bits overflow) to the high counter */
|
|
||||||
Context->Count[1] += (Length >> 29);
|
|
||||||
|
|
||||||
/* Calculate the number of bytes required to fill the remaining buffer space */
|
|
||||||
PartialLength = 64 - Index;
|
|
||||||
|
|
||||||
/* Transform as many times as possible */
|
|
||||||
if(Length >= PartialLength)
|
|
||||||
{
|
|
||||||
/* Fill the buffer partially and transform */
|
|
||||||
RTL::Memory::CopyMemory(&Context->Buffer[Index], Data, PartialLength);
|
|
||||||
TransformData(Context->State, Context->Buffer);
|
|
||||||
|
|
||||||
/* Process remaining full 64-byte blocks directly from the input pointer */
|
|
||||||
for(Input = PartialLength; Input + 63 < Length; Input += 64)
|
|
||||||
{
|
|
||||||
/* Transform the full block without copying to the internal buffer */
|
|
||||||
TransformData(Context->State, &Data[Input]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Reset buffer index to indicate the buffer is now empty */
|
|
||||||
Index = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* No full block was formed, begin copying from the start of input */
|
|
||||||
Input = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Buffer remaining input */
|
|
||||||
RTL::Memory::CopyMemory(&Context->Buffer[Index], &Data[Input], Length - Input);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initializes a SHA-1 context structure with the standard initial hash values.
|
|
||||||
*
|
|
||||||
* @param Context
|
|
||||||
* Supplies a pointer to the SHA-1 context structure to initialize.
|
|
||||||
*
|
|
||||||
* @return This routine returns STATUS_SUCCESS if the context was initialized successfully,
|
|
||||||
* or STATUS_INVALID_PARAMETER if the pointer is NULLPTR.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
XTSTATUS
|
|
||||||
RTL::SHA1::InitializeContext(OUT PRTL_SHA1_CONTEXT Context)
|
|
||||||
{
|
|
||||||
/* Validate input parameter */
|
|
||||||
if(!Context)
|
|
||||||
{
|
|
||||||
/* Invalid parameter, return error */
|
|
||||||
return STATUS_INVALID_PARAMETER;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Initialize hash constants defined by FIPS 180-4 */
|
|
||||||
Context->State[0] = 0x67452301;
|
|
||||||
Context->State[1] = 0xEFCDAB89;
|
|
||||||
Context->State[2] = 0x98BADCFE;
|
|
||||||
Context->State[3] = 0x10325476;
|
|
||||||
Context->State[4] = 0xC3D2E1F0;
|
|
||||||
Context->Count[0] = 0;
|
|
||||||
Context->Count[1] = 0;
|
|
||||||
|
|
||||||
/* Clear buffer */
|
|
||||||
RTL::Memory::ZeroMemory(Context->Buffer, SHA1_BLOCK_SIZE);
|
|
||||||
|
|
||||||
/* Return success */
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Transforms a single 64-byte block using the SHA-1 compression function.
|
|
||||||
*
|
|
||||||
* @param State
|
|
||||||
* Supplies a pointer to the array containing the current hash state variables.
|
|
||||||
*
|
|
||||||
* @param Buffer
|
|
||||||
* Supplies a pointer to the 64-byte input buffer to be transformed.
|
|
||||||
*
|
|
||||||
* @return This routine does not return any value.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
VOID
|
|
||||||
RTL::SHA1::TransformData(IN OUT PULONG State,
|
|
||||||
IN PCUCHAR Buffer)
|
|
||||||
{
|
|
||||||
ULONG Constant, Function, Index, TempHash;
|
|
||||||
ULONG TempState[5];
|
|
||||||
ULONG Stack[80];
|
|
||||||
|
|
||||||
/* Initialize working variables with current state */
|
|
||||||
TempState[0] = State[0];
|
|
||||||
TempState[1] = State[1];
|
|
||||||
TempState[2] = State[2];
|
|
||||||
TempState[3] = State[3];
|
|
||||||
TempState[4] = State[4];
|
|
||||||
|
|
||||||
/* Initialize the first 16 words of the message schedule from the input buffer */
|
|
||||||
for(Index = 0; Index < 16; Index++)
|
|
||||||
{
|
|
||||||
/* Convert input words from Little Endian to Big Endian required by SHA-1 */
|
|
||||||
Stack[Index] = RTL::Endianness::SwapByte32(((const PULONG)Buffer)[Index]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Expand the message to 80 words using the SHA-1 algorithm */
|
|
||||||
for(Index = 16; Index < 80; Index++)
|
|
||||||
{
|
|
||||||
/* Compute the next word value based on XOR and left rotation */
|
|
||||||
Stack[Index] = ROTATE_LEFT((Stack[Index - 3] ^ Stack[Index - 8] ^ Stack[Index - 14] ^ Stack[Index - 16]), 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Execute the main compression loop for 80 rounds */
|
|
||||||
for(Index = 0; Index < 80; Index++)
|
|
||||||
{
|
|
||||||
/* Determine the logical function and constant based on the current round */
|
|
||||||
if(Index < 20)
|
|
||||||
{
|
|
||||||
/* Set the constant defined by FIPS 180-4 for rounds 0-19 and calculate the logical function */
|
|
||||||
Constant = 0x5A827999;
|
|
||||||
Function = (TempState[1] & TempState[2]) | ((~TempState[1]) & TempState[3]);
|
|
||||||
}
|
|
||||||
else if(Index < 40)
|
|
||||||
{
|
|
||||||
/* Set the constant defined by FIPS 180-4 for rounds 20-39 and calculate the logical function */
|
|
||||||
Constant = 0x6ED9EBA1;
|
|
||||||
Function = TempState[1] ^ TempState[2] ^ TempState[3];
|
|
||||||
}
|
|
||||||
else if(Index < 60)
|
|
||||||
{
|
|
||||||
/* Set the constant defined by FIPS 180-4 for rounds 40-59 and calculate the logical function */
|
|
||||||
Constant = 0x8F1BBCDC;
|
|
||||||
Function = (TempState[1] & TempState[2]) | (TempState[1] & TempState[3]) | (TempState[2] & TempState[3]);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Set the constant defined by FIPS 180-4 for rounds 60-79 and calculate the logical function */
|
|
||||||
Constant = 0xCA62C1D6;
|
|
||||||
Function = TempState[1] ^ TempState[2] ^ TempState[3];
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Calculate the temporary hash value for this round */
|
|
||||||
TempHash = ROTATE_LEFT(TempState[0], 5) + Function + TempState[4] + Constant + Stack[Index];
|
|
||||||
TempState[4] = TempState[3];
|
|
||||||
TempState[3] = TempState[2];
|
|
||||||
TempState[2] = ROTATE_LEFT(TempState[1], 30);
|
|
||||||
TempState[1] = TempState[0];
|
|
||||||
TempState[0] = TempHash;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Add the compressed chunk to the current hash value */
|
|
||||||
State[0] += TempState[0];
|
|
||||||
State[1] += TempState[1];
|
|
||||||
State[2] += TempState[2];
|
|
||||||
State[3] += TempState[3];
|
|
||||||
State[4] += TempState[4];
|
|
||||||
|
|
||||||
/* Clear sensitive data from stack */
|
|
||||||
RTL::Memory::ZeroMemory(Stack, sizeof(Stack));
|
|
||||||
}
|
|
||||||
@@ -1,390 +0,0 @@
|
|||||||
/**
|
|
||||||
* PROJECT: ExectOS
|
|
||||||
* COPYRIGHT: See COPYING.md in the top level directory
|
|
||||||
* FILE: xtoskrnl/rtl/slist.cc
|
|
||||||
* DESCRIPTION: Singly linked list manipulation routines
|
|
||||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <xtos.hh>
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieves the first entry from a singly linked list without removing it from the list.
|
|
||||||
*
|
|
||||||
* @param ListHead
|
|
||||||
* Supplies a pointer to a structure that serves as the list header.
|
|
||||||
*
|
|
||||||
* @return This routine returns a pointer to the first entry in the list, or NULLPTR if the list is empty.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTCDECL
|
|
||||||
PSINGLE_LIST_ENTRY
|
|
||||||
RTL::SinglyList::GetFirstEntry(IN PSINGLE_LIST_HEADER ListHead)
|
|
||||||
{
|
|
||||||
/* Check if the list is empty */
|
|
||||||
if(ListEmpty(ListHead))
|
|
||||||
{
|
|
||||||
/* Empty list, return NULLPTR */
|
|
||||||
return NULLPTR;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Return first entry in the list */
|
|
||||||
return ListHead->Next.Next;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initializes a structure representing the head of a singly linked list.
|
|
||||||
*
|
|
||||||
* @param ListHead
|
|
||||||
* Supplies a pointer to a structure that serves as the list header.
|
|
||||||
*
|
|
||||||
* @return This routine does not return any value.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTCDECL
|
|
||||||
VOID
|
|
||||||
RTL::SinglyList::InitializeListHead(IN PSINGLE_LIST_HEADER ListHead)
|
|
||||||
{
|
|
||||||
/* Initialize the singly linked list head */
|
|
||||||
ListHead->Alignment = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Inserts an entry at the head of a singly linked list.
|
|
||||||
*
|
|
||||||
* @param ListHead
|
|
||||||
* Supplies a pointer to the head of the list.
|
|
||||||
*
|
|
||||||
* @param Entry
|
|
||||||
* Supplies a pointer to the entry that will be inserted in the list.
|
|
||||||
*
|
|
||||||
* @return This routine returns a pointer to the original first entry in the list.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTCDECL
|
|
||||||
PSINGLE_LIST_ENTRY
|
|
||||||
RTL::SinglyList::InsertHeadList(IN OUT PSINGLE_LIST_HEADER ListHead,
|
|
||||||
IN PSINGLE_LIST_ENTRY Entry)
|
|
||||||
{
|
|
||||||
PSINGLE_LIST_ENTRY OriginalEntry;
|
|
||||||
|
|
||||||
/* Store the original first entry */
|
|
||||||
OriginalEntry = ListHead->Next.Next;
|
|
||||||
|
|
||||||
/* Insert entry at the head of the list and increment depth and sequence */
|
|
||||||
Entry->Next = ListHead->Next.Next;
|
|
||||||
ListHead->Next.Next = Entry;
|
|
||||||
ListHead->Depth++;
|
|
||||||
ListHead->Sequence++;
|
|
||||||
|
|
||||||
/* Return original first entry */
|
|
||||||
return OriginalEntry;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Inserts an entry at the tail of a singly linked list.
|
|
||||||
*
|
|
||||||
* @param ListHead
|
|
||||||
* Supplies a pointer to the head of the list.
|
|
||||||
*
|
|
||||||
* @param Entry
|
|
||||||
* Supplies a pointer to the entry that will be inserted in the list.
|
|
||||||
*
|
|
||||||
* @return This routine returns a pointer to the original last entry in the list.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTCDECL
|
|
||||||
PSINGLE_LIST_ENTRY
|
|
||||||
RTL::SinglyList::InsertTailList(IN OUT PSINGLE_LIST_HEADER ListHead,
|
|
||||||
IN PSINGLE_LIST_ENTRY Entry)
|
|
||||||
{
|
|
||||||
PSINGLE_LIST_ENTRY CurrentEntry, OriginalEntry;
|
|
||||||
|
|
||||||
/* Set Next pointer of the new entry to NULLPTR */
|
|
||||||
Entry->Next = NULLPTR;
|
|
||||||
|
|
||||||
/* Check if the list is empty */
|
|
||||||
if(ListEmpty(ListHead))
|
|
||||||
{
|
|
||||||
/* Store the original last entry */
|
|
||||||
OriginalEntry = ListHead->Next.Next;
|
|
||||||
|
|
||||||
/* Insert entry at the head */
|
|
||||||
ListHead->Next.Next = Entry;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Traverse the list to find the last entry */
|
|
||||||
CurrentEntry = ListHead->Next.Next;
|
|
||||||
while(CurrentEntry->Next != NULLPTR)
|
|
||||||
{
|
|
||||||
/* Move to the next entry */
|
|
||||||
CurrentEntry = CurrentEntry->Next;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Store the original last entry */
|
|
||||||
OriginalEntry = CurrentEntry;
|
|
||||||
|
|
||||||
/* Insert entry at the tail */
|
|
||||||
CurrentEntry->Next = Entry;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Increment list depth and sequence */
|
|
||||||
ListHead->Depth++;
|
|
||||||
ListHead->Sequence++;
|
|
||||||
|
|
||||||
/* Return original last entry */
|
|
||||||
return OriginalEntry;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Indicates whether a singly linked list structure is empty, or not initialized at all.
|
|
||||||
*
|
|
||||||
* @param ListHead
|
|
||||||
* Supplies a pointer to a structure that represents the head of the list.
|
|
||||||
*
|
|
||||||
* @return This routine returns TRUE if there are currently no entries in the list or FALSE otherwise.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTCDECL
|
|
||||||
BOOLEAN
|
|
||||||
RTL::SinglyList::ListEmpty(IN PSINGLE_LIST_HEADER ListHead)
|
|
||||||
{
|
|
||||||
/* Check if the list is empty */
|
|
||||||
return (ListHead == NULLPTR || ListHead->Next.Next == NULLPTR);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Queries the current depth (number of entries) of a singly linked list.
|
|
||||||
*
|
|
||||||
* @param ListHead
|
|
||||||
* Supplies a pointer to a structure that represents the head of the singly linked list.
|
|
||||||
*
|
|
||||||
* @return This routine returns the number of entries currently in the list, or zero if the list head is NULLPTR.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
USHORT
|
|
||||||
RTL::SinglyList::QueryListDepth(IN PSINGLE_LIST_HEADER ListHead)
|
|
||||||
{
|
|
||||||
/* Check if the list head is initialized and valid */
|
|
||||||
if(ListHead == NULLPTR)
|
|
||||||
{
|
|
||||||
/* Return zero */
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Return the list depth */
|
|
||||||
return ListHead->Depth;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Removes an entry from a singly linked list.
|
|
||||||
*
|
|
||||||
* @param ListHead
|
|
||||||
* Supplies a pointer to the head of the list.
|
|
||||||
*
|
|
||||||
* @param Entry
|
|
||||||
* Supplies a pointer to the entry that will be removed from the list.
|
|
||||||
*
|
|
||||||
* @return This routine does not return any value.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTCDECL
|
|
||||||
VOID
|
|
||||||
RTL::SinglyList::RemoveEntryList(IN PSINGLE_LIST_HEADER ListHead,
|
|
||||||
IN PSINGLE_LIST_ENTRY Entry)
|
|
||||||
{
|
|
||||||
PSINGLE_LIST_ENTRY PreviousEntry;
|
|
||||||
|
|
||||||
/* Check if the list is empty */
|
|
||||||
if(ListEmpty(ListHead))
|
|
||||||
{
|
|
||||||
/* List is empty, nothing to remove, return */
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check if the entry is the first one */
|
|
||||||
if(ListHead->Next.Next == Entry)
|
|
||||||
{
|
|
||||||
/* Remove the first entry and decrement depth */
|
|
||||||
ListHead->Next.Next = Entry->Next;
|
|
||||||
ListHead->Depth--;
|
|
||||||
|
|
||||||
/* Nothing else to do, return */
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Find the previous entry */
|
|
||||||
PreviousEntry = ListHead->Next.Next;
|
|
||||||
while(PreviousEntry->Next != Entry)
|
|
||||||
{
|
|
||||||
/* Move to the next entry */
|
|
||||||
PreviousEntry = PreviousEntry->Next;
|
|
||||||
|
|
||||||
/* Check if we reached the end of the list */
|
|
||||||
if(PreviousEntry == NULLPTR)
|
|
||||||
{
|
|
||||||
/* Entry not found, return */
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Remove the entry and decrement depth */
|
|
||||||
PreviousEntry->Next = Entry->Next;
|
|
||||||
ListHead->Depth--;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Splices a singly linked list at the head of another list. The source list is reinitialized to empty.
|
|
||||||
*
|
|
||||||
* @param ListHead
|
|
||||||
* Supplies a pointer to a structure that represents the head of the list.
|
|
||||||
*
|
|
||||||
* @param SpliceList
|
|
||||||
* Supplies a pointer to a structure that represents the head of the list that will be spliced.
|
|
||||||
*
|
|
||||||
* @return This routine returns a pointer to the original first entry in the list.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTCDECL
|
|
||||||
PSINGLE_LIST_ENTRY
|
|
||||||
RTL::SinglyList::SpliceHeadList(IN OUT PSINGLE_LIST_HEADER ListHead,
|
|
||||||
IN OUT PSINGLE_LIST_HEADER SpliceList)
|
|
||||||
{
|
|
||||||
PSINGLE_LIST_ENTRY LastEntry, OriginalEntry;
|
|
||||||
|
|
||||||
/* Store the original last entry */
|
|
||||||
OriginalEntry = ListHead->Next.Next;
|
|
||||||
|
|
||||||
/* Check if the list to splice is empty */
|
|
||||||
if(ListEmpty(SpliceList))
|
|
||||||
{
|
|
||||||
/* Nothing to splice, return original first entry */
|
|
||||||
return OriginalEntry;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Find the last entry of the list to splice */
|
|
||||||
LastEntry = SpliceList->Next.Next;
|
|
||||||
while(LastEntry->Next != NULLPTR)
|
|
||||||
{
|
|
||||||
/* Move to the next entry */
|
|
||||||
LastEntry = LastEntry->Next;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Splice the list at the head of destination */
|
|
||||||
LastEntry->Next = ListHead->Next.Next;
|
|
||||||
ListHead->Next.Next = SpliceList->Next.Next;
|
|
||||||
|
|
||||||
/* Update depth and sequence of the destination list */
|
|
||||||
ListHead->Depth += SpliceList->Depth;
|
|
||||||
ListHead->Sequence++;
|
|
||||||
|
|
||||||
/* Reinitialize the source list to empty */
|
|
||||||
SpliceList->Next.Next = NULLPTR;
|
|
||||||
SpliceList->Depth = 0;
|
|
||||||
|
|
||||||
/* Return the original last entry */
|
|
||||||
return OriginalEntry;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Splices a singly linked list at the tail of another list. The source list is reinitialized to empty.
|
|
||||||
*
|
|
||||||
* @param ListHead
|
|
||||||
* Supplies a pointer to the head of the destination list.
|
|
||||||
*
|
|
||||||
* @param SpliceList
|
|
||||||
* Supplies a pointer to the head of the list that will be spliced.
|
|
||||||
*
|
|
||||||
* @return This routine returns a pointer to the original last entry in the list.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTCDECL
|
|
||||||
PSINGLE_LIST_ENTRY
|
|
||||||
RTL::SinglyList::SpliceTailList(IN OUT PSINGLE_LIST_HEADER ListHead,
|
|
||||||
IN OUT PSINGLE_LIST_HEADER SpliceList)
|
|
||||||
{
|
|
||||||
PSINGLE_LIST_ENTRY LastEntry, OriginalEntry;
|
|
||||||
|
|
||||||
/* Check if the destination list is empty */
|
|
||||||
if(ListEmpty(ListHead))
|
|
||||||
{
|
|
||||||
/* Destination is empty, original last entry is NULLPTR */
|
|
||||||
OriginalEntry = NULLPTR;
|
|
||||||
|
|
||||||
/* Move the splice list to the destination head */
|
|
||||||
ListHead->Next.Next = SpliceList->Next.Next;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Find the last entry of the destination list */
|
|
||||||
LastEntry = ListHead->Next.Next;
|
|
||||||
while(LastEntry->Next != NULLPTR)
|
|
||||||
{
|
|
||||||
/* Move to the next entry */
|
|
||||||
LastEntry = LastEntry->Next;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Store the original last entry */
|
|
||||||
OriginalEntry = LastEntry;
|
|
||||||
|
|
||||||
/* Splice the list at the tail of destination */
|
|
||||||
LastEntry->Next = SpliceList->Next.Next;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Update depth and sequence of the destination list */
|
|
||||||
ListHead->Depth += SpliceList->Depth;
|
|
||||||
ListHead->Sequence++;
|
|
||||||
|
|
||||||
/* Reinitialize the source list to empty */
|
|
||||||
SpliceList->Next.Next = NULLPTR;
|
|
||||||
SpliceList->Depth = 0;
|
|
||||||
|
|
||||||
/* Return the original last entry */
|
|
||||||
return OriginalEntry;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieves the first entry from a singly linked list and removes it from the list.
|
|
||||||
*
|
|
||||||
* @param ListHead
|
|
||||||
* Pointer to a structure that serves as the list header.
|
|
||||||
*
|
|
||||||
* @return This routine returns a pointer to the first entry in the list, or NULLPTR if the list is empty.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTCDECL
|
|
||||||
PSINGLE_LIST_ENTRY
|
|
||||||
RTL::SinglyList::TakeFirstEntry(IN PSINGLE_LIST_HEADER ListHead)
|
|
||||||
{
|
|
||||||
PSINGLE_LIST_ENTRY Entry;
|
|
||||||
|
|
||||||
/* Check if the list is empty */
|
|
||||||
if(ListEmpty(ListHead))
|
|
||||||
{
|
|
||||||
/* List is empty, return NULLPTR */
|
|
||||||
return NULLPTR;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get the first entry */
|
|
||||||
Entry = ListHead->Next.Next;
|
|
||||||
|
|
||||||
/* Remove entry from the list */
|
|
||||||
ListHead->Next.Next = Entry->Next;
|
|
||||||
ListHead->Depth--;
|
|
||||||
|
|
||||||
/* Return the first entry */
|
|
||||||
return Entry;
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user