forked from xt-sys/exectos
Compare commits
261 Commits
powershell
...
memmgr
| Author | SHA1 | Date | |
|---|---|---|---|
|
4e02664977
|
|||
|
bad3aaf6e0
|
|||
|
9b19bc94b3
|
|||
|
9479f3d364
|
|||
|
8d97ea4112
|
|||
|
40d54743e0
|
|||
|
576a2b7f1b
|
|||
|
3c2ad358ef
|
|||
|
e734ddda65
|
|||
|
a79f26250a
|
|||
|
441e4f510b
|
|||
|
33665839ad
|
|||
|
1e01c52c0c
|
|||
|
970902f3f9
|
|||
|
adff181f5a
|
|||
|
92986e1386
|
|||
|
9a34a5f735
|
|||
|
398db4bde1
|
|||
|
719564ba74
|
|||
|
b95613787a
|
|||
|
4292d89185
|
|||
|
214051e873
|
|||
|
3c52b88802
|
|||
|
944d5b5c0a
|
|||
|
597628a644
|
|||
|
b97babb2bf
|
|||
|
caacd9e275
|
|||
|
916d124c9b
|
|||
|
d85e313c15
|
|||
|
b83eaaa820
|
|||
|
233440c8be
|
|||
|
140af4278e
|
|||
|
c67372d747
|
|||
|
e2eff2b836
|
|||
|
930c9d3193
|
|||
|
f862871a1f
|
|||
|
afb20a1796
|
|||
|
876923e107
|
|||
|
3d7fe25471
|
|||
|
184ce5735e
|
|||
|
76d99dc9db
|
|||
|
d401ac4540
|
|||
|
22f9525e92
|
|||
|
80092a299e
|
|||
|
42525e5993
|
|||
|
0fed593147
|
|||
|
6cdb66cbb3
|
|||
|
d263f17831
|
|||
|
6175413db2
|
|||
|
428928c7e1
|
|||
|
7d2b41a044
|
|||
|
5fe0740c2e
|
|||
|
35eac9d34c
|
|||
|
5a78512561
|
|||
|
b7a92ccce4
|
|||
|
8d2dfa6f62
|
|||
|
5a9b7c0258
|
|||
|
5368fe2e8d
|
|||
|
3e1f57f67c
|
|||
|
44f27fad28
|
|||
|
ae8ac1eacb
|
|||
|
a72bfd3902
|
|||
|
7bdd0dfe2c
|
|||
|
5778a761b5
|
|||
|
d7d125dd50
|
|||
|
511dd15c0c
|
|||
|
278def3081
|
|||
|
0658e98436
|
|||
|
bfdb7bc476
|
|||
|
44fa2ca13a
|
|||
|
7a44901064
|
|||
|
7144242613
|
|||
|
7e62919c6b
|
|||
|
a136f21f4b
|
|||
|
2bbc21b667
|
|||
|
70d758ec5b
|
|||
|
d1553ff84a
|
|||
|
94a8917c5c
|
|||
|
f7b7b61ea4
|
|||
|
2af94a1c3b
|
|||
|
4b5188260f
|
|||
|
47ec89a85e
|
|||
|
edb40dd62b
|
|||
|
e2da6220f2
|
|||
|
53f7945771
|
|||
|
9a5ef6fc00
|
|||
|
fa64507350
|
|||
|
80ea0b49d0
|
|||
|
2e0e085acb
|
|||
|
0ce2741e18
|
|||
|
a46f30045a
|
|||
|
0763a9522b
|
|||
|
b51f21f55c
|
|||
|
0590ad3bcd
|
|||
|
9b8417565b
|
|||
|
bc391d6e1e
|
|||
|
7b6e284d39
|
|||
|
fae72f5326
|
|||
|
eb0957dbd4
|
|||
|
3d7f512377
|
|||
|
7f0341bb83
|
|||
|
ba4ac6cec8
|
|||
|
b16dbb19f8
|
|||
|
19f5307be6
|
|||
|
825de8b471
|
|||
|
6a7bc64ac7
|
|||
|
726fd84241
|
|||
|
54e75c9345
|
|||
|
5e3fb7a5a3
|
|||
|
58669d3074
|
|||
|
72f34c8286
|
|||
|
a7820ff568
|
|||
|
7f6114f8e5
|
|||
|
fd29cf55ef
|
|||
|
446ce920ec
|
|||
|
a4b9f495e5
|
|||
|
2c8eb6d692
|
|||
|
31b0e4f441
|
|||
|
b5f220a2ae
|
|||
|
0b1b76e9df
|
|||
|
d3edfef53b
|
|||
|
46c24e653e
|
|||
|
c3607ea943
|
|||
|
7da6bcc75e
|
|||
|
0f38d39705
|
|||
|
587b85d0a4
|
|||
|
0766eb4566
|
|||
|
11f7c25713
|
|||
|
15edd98242
|
|||
|
34c33a3b53
|
|||
|
032cab7f2f
|
|||
|
5500192575
|
|||
|
ec94e2341c
|
|||
|
9ed851ed1f
|
|||
|
b91c79e090
|
|||
|
bee91d0c71
|
|||
|
36e53bfc8c
|
|||
|
9027632c4f
|
|||
|
bd1a3605d2
|
|||
|
4b50278ac9
|
|||
|
154ca7be35
|
|||
|
3a087766cc
|
|||
|
410286d012
|
|||
|
e66baa0da0
|
|||
|
46576398a2
|
|||
|
cb6efc648f
|
|||
|
0a43a93f41
|
|||
|
9f359c10ed
|
|||
|
455349f2d7
|
|||
|
5e5b4a8392
|
|||
|
329143b4f6
|
|||
|
cc76ea40ee
|
|||
|
0159262ee0
|
|||
|
f653b9f79c
|
|||
|
7bcd78fdf3
|
|||
|
c080f74714
|
|||
|
5ff0cad094
|
|||
|
00702bfb23
|
|||
|
dbda6bbb29
|
|||
|
aced62e790
|
|||
|
53116b86a3
|
|||
|
d8fc223140
|
|||
|
f4c49e2f25
|
|||
|
4c7c914a1c
|
|||
|
4a00179af2
|
|||
|
0d2d41dcda
|
|||
|
c1514557f6
|
|||
|
49e97fb8b4
|
|||
|
28f49dd545
|
|||
|
7cb3d1764b
|
|||
|
200e9132b1
|
|||
|
d891088b1a
|
|||
|
04599161da
|
|||
|
0880a0f344
|
|||
|
4593a89a9b
|
|||
|
874d303f83
|
|||
|
b7c004528a
|
|||
|
5012c8dc37
|
|||
|
1e3917882c
|
|||
|
b3b874d3ce
|
|||
|
288b2f8b24
|
|||
|
c7cc536685
|
|||
|
b8e81e2223
|
|||
|
0fd2b8b729
|
|||
|
560cd43b34
|
|||
|
f0a06db7d2
|
|||
|
7575526f07
|
|||
|
643fd0d1e8
|
|||
|
6aa148784b
|
|||
|
e237a944cc
|
|||
|
755a167f2c
|
|||
|
24dccf4bed
|
|||
|
7b93c39348
|
|||
|
570301bb35
|
|||
|
b183d52806
|
|||
|
687c58d923
|
|||
|
049c9c6bbd
|
|||
|
f1a76bc01a
|
|||
|
cb4d113e31
|
|||
|
728241f998
|
|||
|
00d428d8de
|
|||
|
020b7c7676
|
|||
|
2265a4a522
|
|||
|
dc23f91110
|
|||
|
7f0ca6a948
|
|||
|
36c273ea13
|
|||
|
5cf3dfa844
|
|||
|
070c508e42
|
|||
|
5224dc315f
|
|||
|
b7bbf9ffa8
|
|||
|
eae48320f3
|
|||
|
17b5649362
|
|||
|
783a9eea3a
|
|||
|
237f6a2974
|
|||
|
ee9514fd5c
|
|||
|
63c27a149a
|
|||
|
7694df7744
|
|||
|
c710ec4688
|
|||
|
8054bb915a
|
|||
|
86aa22e5f8
|
|||
|
4a7494ad3f
|
|||
|
d4287198b0
|
|||
|
4265ae92d0
|
|||
|
931586eebd
|
|||
|
c099882866
|
|||
|
0097cb88d7
|
|||
|
20b0bfdfad
|
|||
|
35523a230a
|
|||
|
7b11a8feb1
|
|||
|
0cf178a648
|
|||
|
66f27e4b9a
|
|||
|
10b8ab347a
|
|||
|
071c840ca8
|
|||
|
dda8f88830
|
|||
|
cb2da54956
|
|||
|
fd13091476
|
|||
|
c28c3f8344
|
|||
|
dfb0284427
|
|||
|
1150b9ecdb
|
|||
|
f6dac12057
|
|||
|
ffa480d69a
|
|||
|
0120ba167f
|
|||
|
4e9dc15501
|
|||
|
164ff0c135
|
|||
|
f538d035e2
|
|||
|
72b92f853e
|
|||
|
00b04f5405
|
|||
|
52afd31e77
|
|||
|
7f06abf236
|
|||
|
4f4df52d3d
|
|||
|
764fec4d75
|
|||
|
ca8a539c0e
|
|||
|
c206b443ed
|
|||
|
b19b27a621
|
|||
|
56b81f5d73
|
|||
|
1e99a3f4a9
|
|||
|
0a71bc3995
|
|||
|
13a9d4c522
|
|||
|
9bf867af95
|
|||
|
a7be533521
|
|||
|
fdbe157c18
|
@@ -53,8 +53,9 @@ implement any environment subsystem to support applications that are strictly wr
|
||||
* NT drivers compatibility layer
|
||||
|
||||
# Requirements
|
||||
ExectOS is in very early development stage, thus its requirements have been not specified yet. However according to its
|
||||
design, it requires a modern EFI enabled hardware. It is not possible currently to boot ExectOS on a legacy BIOS.
|
||||
ExectOS is currently in a very early stage of development, so its specific requirements are not fully defined yet.
|
||||
However, based on the current design, it requires modern EFI hardware. You cannot boot ExectOS on a legacy BIOS
|
||||
right now, but there are plans to add BIOS support in the future.
|
||||
|
||||
# Source structure
|
||||
| Directory | Description |
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
# XT Boot Sector
|
||||
PROJECT(BOOTSECT)
|
||||
|
||||
add_definitions("-DARCH_ESP_SOURCE=\\\"${ARCH}/cpu.S\\\"")
|
||||
|
||||
# Compile boot sectors
|
||||
compile_bootsector(mbrboot ${BOOTSECT_SOURCE_DIR}/mbrboot.S 0x7C00 Start)
|
||||
compile_bootsector(espboot ${BOOTSECT_SOURCE_DIR}/espboot.S 0x7C00 Start)
|
||||
|
||||
144
boot/bootsect/amd64/cpu.S
Normal file
144
boot/bootsect/amd64/cpu.S
Normal file
@@ -0,0 +1,144 @@
|
||||
/**
|
||||
* 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
|
||||
|
||||
ReadExtraCode:
|
||||
/* Read second VBR sector with extra boot code */
|
||||
/* Read second VBR sector with extra boot code (3 sectors starting from sector 2) */
|
||||
movl HiddenSectors - Start(%bp), %eax
|
||||
addl $0x02, %eax
|
||||
movw $0x01, %cx
|
||||
movw $0x03, %cx
|
||||
xorw %bx, %bx
|
||||
movw %bx, %es
|
||||
movw $0x7E00, %bx
|
||||
call ReadSectors
|
||||
jmp StartSectors
|
||||
jmp StartExtraCode
|
||||
|
||||
ReadSectors:
|
||||
/* Check for extended BIOS functions and use it only if available */
|
||||
@@ -139,18 +139,22 @@ ReadSectors:
|
||||
movw $0x55AA, %bx
|
||||
movb DriveNumber - Start(%bp), %dl
|
||||
int $0x13
|
||||
jc ReadCHS
|
||||
jc .ReadCHS
|
||||
cmpw $0xAA55, %bx
|
||||
jne ReadCHS
|
||||
jne .ReadCHS
|
||||
testb $0x01, %cl
|
||||
jz ReadCHS
|
||||
jz .ReadCHS
|
||||
|
||||
/* Verify drive size and determine whether to use CHS or LBA */
|
||||
cmpl %edi, %eax
|
||||
jnb ReadLBA
|
||||
jnb .ReadLBA
|
||||
|
||||
ReadCHS:
|
||||
.ReadCHS:
|
||||
/* Read sectors using CHS */
|
||||
popal
|
||||
|
||||
.CHSLoop:
|
||||
/* Read sector by sector using CHS */
|
||||
pushw %cx
|
||||
pushal
|
||||
xorl %edx, %edx
|
||||
@@ -176,11 +180,11 @@ ReadCHS:
|
||||
movw %es, %dx
|
||||
addw $0x20, %dx
|
||||
movw %dx, %es
|
||||
loop ReadCHS
|
||||
loop .CHSLoop
|
||||
popw %es
|
||||
ret
|
||||
|
||||
ReadLBA:
|
||||
.ReadLBA:
|
||||
/* Prepare DAP packet and read sectors using LBA */
|
||||
popal
|
||||
pushw %cx
|
||||
@@ -209,19 +213,19 @@ ReadLBA:
|
||||
movw %dx, %es
|
||||
popw %bx
|
||||
subw %si, %cx
|
||||
jnz ReadLBA
|
||||
jnz .ReadLBA
|
||||
popw %es
|
||||
ret
|
||||
|
||||
DiskError:
|
||||
/* Display disk error message and reboot */
|
||||
movw $msgDiskError, %si
|
||||
movw $.MsgDiskError, %si
|
||||
call Print
|
||||
jmp Reboot
|
||||
|
||||
FsError:
|
||||
/* Display FS error message and reboot */
|
||||
movw $msgFsError, %si
|
||||
movw $.MsgFsError, %si
|
||||
call Print
|
||||
jmp Reboot
|
||||
|
||||
@@ -229,48 +233,297 @@ Print:
|
||||
/* Simple routine to print messages */
|
||||
lodsb
|
||||
orb %al, %al
|
||||
jz DonePrint
|
||||
jz .DonePrint
|
||||
movb $0x0E, %ah
|
||||
movw $0x07, %bx
|
||||
int $0x10
|
||||
jmp Print
|
||||
DonePrint:
|
||||
.DonePrint:
|
||||
retw
|
||||
|
||||
Reboot:
|
||||
/* Display a message, wait for a key press and reboot */
|
||||
movw $msgAnyKey, %si
|
||||
movw $.MsgAnyKey, %si
|
||||
call Print
|
||||
xorw %ax, %ax
|
||||
int $0x16
|
||||
int $0x19
|
||||
|
||||
msgAnyKey:
|
||||
.ascii "Press any key to restart\r\n"
|
||||
.MsgAnyKey:
|
||||
.ascii "Press any key to restart...\r\n\0"
|
||||
|
||||
msgDiskError:
|
||||
.ascii "Disk error\r\n"
|
||||
.MsgDiskError:
|
||||
.ascii "Disk error!\r\n\0"
|
||||
|
||||
msgFsError:
|
||||
.ascii "File system error\r\n"
|
||||
.MsgFsError:
|
||||
.ascii "File system error!\r\n\0"
|
||||
|
||||
/* Fill the rest of the VBR with zeros and add VBR signature at the end */
|
||||
.fill (510 - (. - Start)), 1, 0
|
||||
.word 0xAA55
|
||||
|
||||
|
||||
StartSectors:
|
||||
/* Print message */
|
||||
movw $msgUnavailable, %si
|
||||
StartExtraCode:
|
||||
/* Load XTLDR file from disk */
|
||||
call LoadStage2
|
||||
|
||||
/* 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
|
||||
jmp Reboot
|
||||
|
||||
/* Wait for key press and reboot */
|
||||
xorw %ax, %ax
|
||||
int $0x16
|
||||
int $0x19
|
||||
FileNotFound:
|
||||
/* Display XTLDR not found message and reboot */
|
||||
movw $.MsgXtLdrNotFound, %si
|
||||
call Print
|
||||
jmp Reboot
|
||||
|
||||
msgUnavailable:
|
||||
.ascii "XTLDR requires EFI-based system!\r\nPress any key to restart\r\n"
|
||||
Stage2NotLoaded:
|
||||
/* Clean up the stack and display XTLDR not found message and reboot */
|
||||
popl %esi
|
||||
jmp FileNotFound
|
||||
|
||||
/* Fill the rest of the extra VBR with zeros */
|
||||
.fill (1024 - (. - Start)), 1, 0
|
||||
.BootDirName:
|
||||
/* Boot directory name */
|
||||
.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"
|
||||
|
||||
124
boot/bootsect/i686/cpu.S
Normal file
124
boot/bootsect/i686/cpu.S
Normal file
@@ -0,0 +1,124 @@
|
||||
/**
|
||||
* 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,6 +4,7 @@
|
||||
* FILE: boot/bootsect/amd64/mbrboot.S
|
||||
* DESCRIPTION: XT Boot Loader MBR boot code
|
||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||
* Aiken Harris <aiken@codingworkshop.eu.org>
|
||||
*/
|
||||
|
||||
.text
|
||||
@@ -41,7 +42,7 @@ RealStart:
|
||||
movw %ax, %ss
|
||||
|
||||
/* Print welcome message */
|
||||
leaw msgXtosBoot, %si
|
||||
leaw .MsgXtosBoot, %si
|
||||
call Print
|
||||
|
||||
/* Get BIOS boot drive and partition table offset */
|
||||
@@ -90,19 +91,19 @@ PartitionFound:
|
||||
|
||||
InvalidSignature:
|
||||
/* Invalid signature error */
|
||||
leaw msgInvalidSignature, %si
|
||||
leaw .MsgInvalidSignature, %si
|
||||
call Print
|
||||
jmp HaltSystem
|
||||
|
||||
PartitionNotFound:
|
||||
/* Active partition not found error */
|
||||
leaw msgPartitionNotFound, %si
|
||||
leaw .MsgPartitionNotFound, %si
|
||||
call Print
|
||||
jmp HaltSystem
|
||||
|
||||
VbrReadFail:
|
||||
/* VBR read failed error */
|
||||
leaw msgVbrReadFail, %si
|
||||
leaw .MsgVbrReadFail, %si
|
||||
call Print
|
||||
jmp HaltSystem
|
||||
|
||||
@@ -136,16 +137,16 @@ DonePrint:
|
||||
/* Storage for the LBA start */
|
||||
.long 0
|
||||
|
||||
msgInvalidSignature:
|
||||
.MsgInvalidSignature:
|
||||
.asciz "Invalid partition signature!"
|
||||
|
||||
msgPartitionNotFound:
|
||||
.MsgPartitionNotFound:
|
||||
.asciz "Bootable partition not found!"
|
||||
|
||||
msgVbrReadFail:
|
||||
.MsgVbrReadFail:
|
||||
.asciz "VBR read failed!"
|
||||
|
||||
msgXtosBoot:
|
||||
.MsgXtosBoot:
|
||||
.asciz "Starting XTOS boot loader...\r\n"
|
||||
|
||||
/* Fill the rest of the MBR with zeros and add MBR signature at the end */
|
||||
|
||||
@@ -16,6 +16,7 @@ list(APPEND LIBXTLDR_SOURCE
|
||||
# Specify list of source code files
|
||||
list(APPEND XTLDR_SOURCE
|
||||
${XTLDR_SOURCE_DIR}/arch/${ARCH}/memory.cc
|
||||
${XTLDR_SOURCE_DIR}/biosutil.cc
|
||||
${XTLDR_SOURCE_DIR}/bootutil.cc
|
||||
${XTLDR_SOURCE_DIR}/config.cc
|
||||
${XTLDR_SOURCE_DIR}/console.cc
|
||||
@@ -38,6 +39,9 @@ add_executable(xtldr ${XTLDR_SOURCE})
|
||||
# Add linker libraries
|
||||
target_link_libraries(xtldr libxtos)
|
||||
|
||||
# Add linker options
|
||||
target_link_options(xtldr PRIVATE /ALIGN:512)
|
||||
|
||||
# Set proper binary name and install target
|
||||
if(ARCH STREQUAL "i686")
|
||||
set(BINARY_NAME "bootia32")
|
||||
@@ -49,5 +53,6 @@ set_install_target(xtldr efi/boot)
|
||||
|
||||
# Set loader entrypoint and subsystem
|
||||
set_entrypoint(xtldr "BlStartXtLoader")
|
||||
set_imagebase(xtldr ${BASEADDRESS_XTLDR})
|
||||
set_linker_map(xtldr TRUE)
|
||||
set_subsystem(xtldr efi_application)
|
||||
|
||||
@@ -28,13 +28,12 @@ EFI_STATUS
|
||||
Memory::BuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
|
||||
IN ULONG_PTR SelfMapAddress)
|
||||
{
|
||||
PLIST_ENTRY ListEntry, ModulesList, ModulesListEntry;
|
||||
PXTBL_MEMORY_MAPPING Mapping;
|
||||
PLIST_ENTRY ModulesList, ModulesListEntry;
|
||||
PXTBL_MODULE_INFO ModuleInfo;
|
||||
EFI_PHYSICAL_ADDRESS Address;
|
||||
PVOID LoaderBase;
|
||||
ULONGLONG LoaderSize;
|
||||
EFI_STATUS Status;
|
||||
PVOID LoaderBase;
|
||||
|
||||
/* Allocate pages for the Page Map */
|
||||
Status = AllocatePages(AllocateAnyPages, 1, &Address);
|
||||
@@ -44,6 +43,14 @@ Memory::BuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
|
||||
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 */
|
||||
PageMap->PtePointer = (PVOID)(UINT_PTR)Address;
|
||||
RTL::Memory::ZeroMemory(PageMap->PtePointer, EFI_PAGE_SIZE);
|
||||
@@ -57,7 +64,7 @@ Memory::BuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
|
||||
}
|
||||
|
||||
/* Map the trampoline code area */
|
||||
Status = MapVirtualMemory(PageMap, (PVOID)MM_TRAMPOLINE_ADDRESS,(PVOID)MM_TRAMPOLINE_ADDRESS,
|
||||
Status = MapVirtualMemory(PageMap, MM_TRAMPOLINE_ADDRESS, MM_TRAMPOLINE_ADDRESS,
|
||||
1, LoaderFirmwareTemporary);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
@@ -74,7 +81,7 @@ Memory::BuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
|
||||
ModuleInfo = CONTAIN_RECORD(ModulesListEntry, XTBL_MODULE_INFO, Flink);
|
||||
|
||||
/* Map module code */
|
||||
Status = MapVirtualMemory(PageMap, ModuleInfo->ModuleBase, ModuleInfo->ModuleBase,
|
||||
Status = MapVirtualMemory(PageMap, (ULONGLONG)ModuleInfo->ModuleBase, (ULONGLONG)ModuleInfo->ModuleBase,
|
||||
EFI_SIZE_TO_PAGES(ModuleInfo->ModuleSize), LoaderFirmwareTemporary);
|
||||
|
||||
/* Check if mapping succeeded */
|
||||
@@ -95,7 +102,7 @@ Memory::BuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
|
||||
if(LoaderBase && LoaderSize)
|
||||
{
|
||||
/* Map boot loader code as well */
|
||||
Status = MapVirtualMemory(PageMap, LoaderBase, LoaderBase,
|
||||
Status = MapVirtualMemory(PageMap, (ULONGLONG)LoaderBase, (ULONGLONG)LoaderBase,
|
||||
EFI_SIZE_TO_PAGES(LoaderSize), LoaderFirmwareTemporary);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
@@ -109,6 +116,28 @@ Memory::BuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
|
||||
return STATUS_EFI_PROTOCOL_ERROR;
|
||||
}
|
||||
|
||||
/* Return success */
|
||||
return STATUS_EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterates through the memory map and physically maps all virtual addresses to page tables.
|
||||
*
|
||||
* @param PageMap
|
||||
* Supplies a pointer to the page mapping structure.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
Memory::CommitPageMap(IN PXTBL_PAGE_MAPPING PageMap)
|
||||
{
|
||||
PXTBL_MEMORY_MAPPING Mapping;
|
||||
PLIST_ENTRY ListEntry;
|
||||
EFI_STATUS Status;
|
||||
|
||||
/* Iterate through and map all the mappings*/
|
||||
Debug::Print(L"Mapping and dumping EFI memory:\n");
|
||||
ListEntry = PageMap->MemoryMap.Flink;
|
||||
@@ -193,7 +222,7 @@ Memory::GetNextPageTable(IN PXTBL_PAGE_MAPPING PageMap,
|
||||
}
|
||||
|
||||
/* Add new memory mapping */
|
||||
Status = MapVirtualMemory(PageMap, NULLPTR, (PVOID)(UINT_PTR)Address, 1, LoaderMemoryData);
|
||||
Status = MapVirtualMemory(PageMap, (ULONGLONG)NULLPTR, Address, 1, LoaderMemoryData);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Memory mapping failure */
|
||||
@@ -239,9 +268,9 @@ Memory::GetNextPageTable(IN PXTBL_PAGE_MAPPING PageMap,
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
Memory::MapPage(IN PXTBL_PAGE_MAPPING PageMap,
|
||||
IN ULONG_PTR VirtualAddress,
|
||||
IN ULONG_PTR PhysicalAddress,
|
||||
IN ULONG NumberOfPages)
|
||||
IN ULONGLONG VirtualAddress,
|
||||
IN ULONGLONG PhysicalAddress,
|
||||
IN ULONGLONG NumberOfPages)
|
||||
{
|
||||
PVOID Pml1, Pml2, Pml3, Pml4, Pml5;
|
||||
SIZE_T Pml1Entry, Pml2Entry, Pml3Entry, Pml4Entry, Pml5Entry;
|
||||
|
||||
@@ -25,13 +25,12 @@ EFI_STATUS
|
||||
Memory::BuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
|
||||
IN ULONG_PTR SelfMapAddress)
|
||||
{
|
||||
PLIST_ENTRY ListEntry, ModulesList, ModulesListEntry;
|
||||
EFI_PHYSICAL_ADDRESS Address, DirectoryAddress;
|
||||
PLIST_ENTRY ModulesList, ModulesListEntry;
|
||||
PXTBL_MODULE_INFO ModuleInfo;
|
||||
PXTBL_MEMORY_MAPPING Mapping;
|
||||
PVOID LoaderBase;
|
||||
ULONGLONG LoaderSize;
|
||||
EFI_STATUS Status;
|
||||
PVOID LoaderBase;
|
||||
ULONG Index;
|
||||
|
||||
/* Check the page map level to determine which paging structure to create */
|
||||
@@ -45,6 +44,14 @@ Memory::BuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
|
||||
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 the allocated page to the page map and zero it out */
|
||||
PageMap->PtePointer = (PVOID)(UINT_PTR)Address;
|
||||
RTL::Memory::ZeroMemory(PageMap->PtePointer, EFI_PAGE_SIZE);
|
||||
@@ -57,6 +64,14 @@ Memory::BuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Add new memory mapping for the Page Directories (PDs) */
|
||||
Status = MapVirtualMemory(PageMap, (ULONGLONG)NULLPTR, DirectoryAddress, 4, LoaderMemoryData);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Memory mapping failure */
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Zero-fill the allocated memory for the Page Directories */
|
||||
RTL::Memory::ZeroMemory((PVOID)DirectoryAddress, EFI_PAGE_SIZE * 4);
|
||||
|
||||
@@ -79,6 +94,14 @@ Memory::BuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
|
||||
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 the allocated page to the page map and zero it out */
|
||||
PageMap->PtePointer = (PVOID)(UINT_PTR)Address;
|
||||
RTL::Memory::ZeroMemory(PageMap->PtePointer, EFI_PAGE_SIZE);
|
||||
@@ -93,8 +116,7 @@ Memory::BuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
|
||||
}
|
||||
|
||||
/* Map the trampoline code area */
|
||||
Status = MapVirtualMemory(PageMap, (PVOID)MM_TRAMPOLINE_ADDRESS,(PVOID)MM_TRAMPOLINE_ADDRESS,
|
||||
1, LoaderFirmwareTemporary);
|
||||
Status = MapVirtualMemory(PageMap, MM_TRAMPOLINE_ADDRESS, MM_TRAMPOLINE_ADDRESS, 1, LoaderFirmwareTemporary);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Mapping trampoline code failed */
|
||||
@@ -110,7 +132,7 @@ Memory::BuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
|
||||
ModuleInfo = CONTAIN_RECORD(ModulesListEntry, XTBL_MODULE_INFO, Flink);
|
||||
|
||||
/* Map module code */
|
||||
Status = MapVirtualMemory(PageMap, ModuleInfo->ModuleBase, ModuleInfo->ModuleBase,
|
||||
Status = MapVirtualMemory(PageMap, (ULONGLONG)ModuleInfo->ModuleBase, (ULONGLONG)ModuleInfo->ModuleBase,
|
||||
EFI_SIZE_TO_PAGES(ModuleInfo->ModuleSize), LoaderFirmwareTemporary);
|
||||
|
||||
/* Check if mapping succeeded */
|
||||
@@ -131,7 +153,7 @@ Memory::BuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
|
||||
if(LoaderBase && LoaderSize)
|
||||
{
|
||||
/* Map boot loader code as well */
|
||||
Status = MapVirtualMemory(PageMap, LoaderBase, LoaderBase,
|
||||
Status = MapVirtualMemory(PageMap, (ULONGLONG)LoaderBase, (ULONGLONG)LoaderBase,
|
||||
EFI_SIZE_TO_PAGES(LoaderSize), LoaderFirmwareTemporary);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
@@ -145,6 +167,28 @@ Memory::BuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
|
||||
return STATUS_EFI_PROTOCOL_ERROR;
|
||||
}
|
||||
|
||||
/* Return success */
|
||||
return STATUS_EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterates through the memory map and physically maps all virtual addresses to page tables.
|
||||
*
|
||||
* @param PageMap
|
||||
* Supplies a pointer to the page mapping structure.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
Memory::CommitPageMap(IN PXTBL_PAGE_MAPPING PageMap)
|
||||
{
|
||||
PXTBL_MEMORY_MAPPING Mapping;
|
||||
PLIST_ENTRY ListEntry;
|
||||
EFI_STATUS Status;
|
||||
|
||||
/* Iterate through and map all the mappings*/
|
||||
Debug::Print(L"Mapping and dumping EFI memory:\n");
|
||||
ListEntry = PageMap->MemoryMap.Flink;
|
||||
@@ -157,8 +201,9 @@ Memory::BuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
|
||||
if(Mapping->VirtualAddress)
|
||||
{
|
||||
/* Dump memory mapping */
|
||||
Debug::Print(L" Type=%02lu, PhysicalBase=%.8P, VirtualBase=%.8P, Pages=%llu\n", Mapping->MemoryType,
|
||||
Mapping->PhysicalAddress, Mapping->VirtualAddress, Mapping->NumberOfPages);
|
||||
Debug::Print(L" Type=%02lu, PhysicalBase=0x%.8llX, VirtualBase=0x%.8llX, Pages=%llu\n",
|
||||
Mapping->MemoryType, Mapping->PhysicalAddress,
|
||||
Mapping->VirtualAddress, Mapping->NumberOfPages);
|
||||
|
||||
/* Map memory */
|
||||
Status = MapPage(PageMap, (UINT_PTR)Mapping->VirtualAddress,
|
||||
@@ -252,7 +297,7 @@ Memory::GetNextPageTable(IN PXTBL_PAGE_MAPPING PageMap,
|
||||
}
|
||||
|
||||
/* Add new memory mapping */
|
||||
Status = MapVirtualMemory(PageMap, NULLPTR, (PVOID)(UINT_PTR)Address, 1, LoaderMemoryData);
|
||||
Status = MapVirtualMemory(PageMap, (ULONGLONG)NULLPTR, Address, 1, LoaderMemoryData);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Memory mapping failure */
|
||||
@@ -313,11 +358,11 @@ Memory::GetNextPageTable(IN PXTBL_PAGE_MAPPING PageMap,
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
Memory::MapPage(IN PXTBL_PAGE_MAPPING PageMap,
|
||||
IN ULONG_PTR VirtualAddress,
|
||||
IN ULONG_PTR PhysicalAddress,
|
||||
IN ULONG NumberOfPages)
|
||||
IN ULONGLONG VirtualAddress,
|
||||
IN ULONGLONG PhysicalAddress,
|
||||
IN ULONGLONG NumberOfPages)
|
||||
{
|
||||
SIZE_T PageFrameNumber;
|
||||
ULONGLONG PageFrameNumber;
|
||||
PVOID Pml1, Pml2, Pml3;
|
||||
SIZE_T Pml1Entry, Pml2Entry, Pml3Entry;
|
||||
PHARDWARE_LEGACY_PTE LegacyPmlTable;
|
||||
|
||||
190
boot/xtldr/biosutil.cc
Normal file
190
boot/xtldr/biosutil.cc
Normal file
@@ -0,0 +1,190 @@
|
||||
/**
|
||||
* 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,6 +10,18 @@
|
||||
#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 */
|
||||
PLIST_ENTRY Configuration::BootMenuList = NULLPTR;
|
||||
|
||||
|
||||
@@ -15,6 +15,25 @@
|
||||
#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
|
||||
{
|
||||
public:
|
||||
@@ -146,6 +165,7 @@ class Memory
|
||||
OUT PVOID *Memory);
|
||||
STATIC XTCDECL EFI_STATUS BuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
|
||||
IN ULONG_PTR SelfMapAddress);
|
||||
STATIC XTCDECL EFI_STATUS CommitPageMap(IN PXTBL_PAGE_MAPPING PageMap);
|
||||
STATIC XTCDECL EFI_STATUS FreePages(IN ULONGLONG NumberOfPages,
|
||||
IN EFI_PHYSICAL_ADDRESS Memory);
|
||||
STATIC XTCDECL EFI_STATUS FreePool(IN PVOID Memory);
|
||||
@@ -158,15 +178,16 @@ class Memory
|
||||
IN SHORT PageMapLevel,
|
||||
IN PAGE_SIZE PageSize);
|
||||
STATIC XTCDECL EFI_STATUS MapEfiMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
|
||||
IN OUT PVOID *MemoryMapAddress,
|
||||
IN OUT PVOID *BaseAddress,
|
||||
IN BOOLEAN IdentityMapping,
|
||||
IN PBL_GET_MEMTYPE_ROUTINE GetMemoryTypeRoutine);
|
||||
STATIC XTCDECL EFI_STATUS MapPage(IN PXTBL_PAGE_MAPPING PageMap,
|
||||
IN ULONG_PTR VirtualAddress,
|
||||
IN ULONG_PTR PhysicalAddress,
|
||||
IN ULONG NumberOfPages);
|
||||
IN ULONGLONG VirtualAddress,
|
||||
IN ULONGLONG PhysicalAddress,
|
||||
IN ULONGLONG NumberOfPages);
|
||||
STATIC XTCDECL EFI_STATUS MapVirtualMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
|
||||
IN PVOID VirtualAddress,
|
||||
IN PVOID PhysicalAddress,
|
||||
IN ULONGLONG VirtualAddress,
|
||||
IN ULONGLONG PhysicalAddress,
|
||||
IN ULONGLONG NumberOfPages,
|
||||
IN LOADER_MEMORY_TYPE MemoryType);
|
||||
STATIC XTCDECL PVOID PhysicalAddressToVirtual(IN PVOID PhysicalAddress,
|
||||
|
||||
@@ -314,9 +314,12 @@ Memory::InitializePageMap(OUT PXTBL_PAGE_MAPPING PageMap,
|
||||
* @param PageMap
|
||||
* Supplies a pointer to the page mapping structure.
|
||||
*
|
||||
* @param MemoryMapAddress
|
||||
* @param BaseAddress
|
||||
* 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
|
||||
* Supplies a pointer to the routine which will be used to match EFI memory type to the OS memory type.
|
||||
*
|
||||
@@ -327,19 +330,20 @@ Memory::InitializePageMap(OUT PXTBL_PAGE_MAPPING PageMap,
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
Memory::MapEfiMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
|
||||
IN OUT PVOID *MemoryMapAddress,
|
||||
IN OUT PVOID *BaseAddress,
|
||||
IN BOOLEAN IdentityMapping,
|
||||
IN PBL_GET_MEMTYPE_ROUTINE GetMemoryTypeRoutine)
|
||||
{
|
||||
ULONGLONG MaxAddress, VirtualAddress;
|
||||
PEFI_MEMORY_DESCRIPTOR Descriptor;
|
||||
LOADER_MEMORY_TYPE MemoryType;
|
||||
PEFI_MEMORY_MAP MemoryMap;
|
||||
SIZE_T DescriptorCount;
|
||||
PUCHAR VirtualAddress;
|
||||
EFI_STATUS Status;
|
||||
SIZE_T Index;
|
||||
|
||||
/* Set virtual address as specified in argument */
|
||||
VirtualAddress = (PUCHAR)*MemoryMapAddress;
|
||||
VirtualAddress = (ULONGLONG)*BaseAddress;
|
||||
|
||||
/* Check if custom memory type routine is specified */
|
||||
if(GetMemoryTypeRoutine == NULLPTR)
|
||||
@@ -367,8 +371,37 @@ Memory::MapEfiMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
|
||||
/* Iterate through all descriptors from the memory map */
|
||||
for(Index = 0; Index < DescriptorCount; Index++)
|
||||
{
|
||||
/* Make sure descriptor does not start beyond lowest physical page */
|
||||
if(Descriptor->PhysicalStart <= MAXUINT_PTR)
|
||||
/* Check page map level */
|
||||
if(PageMap->PageMapLevel == 2)
|
||||
{
|
||||
/* 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 */
|
||||
if(Descriptor->Type == EfiReservedMemoryType)
|
||||
@@ -378,25 +411,6 @@ Memory::MapEfiMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
|
||||
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 */
|
||||
MemoryType = GetMemoryTypeRoutine((EFI_MEMORY_TYPE)Descriptor->Type);
|
||||
|
||||
@@ -404,22 +418,32 @@ Memory::MapEfiMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
|
||||
if(MemoryType == LoaderFirmwareTemporary)
|
||||
{
|
||||
/* Map EFI firmware code */
|
||||
Status = MapVirtualMemory(PageMap, (PVOID)Descriptor->PhysicalStart,
|
||||
(PVOID)Descriptor->PhysicalStart, Descriptor->NumberOfPages, MemoryType);
|
||||
Status = MapVirtualMemory(PageMap, Descriptor->PhysicalStart,
|
||||
Descriptor->PhysicalStart, Descriptor->NumberOfPages, MemoryType);
|
||||
}
|
||||
else if(MemoryType != LoaderFree)
|
||||
{
|
||||
/* Add any non-free memory mapping */
|
||||
Status = MapVirtualMemory(PageMap, VirtualAddress, (PVOID)Descriptor->PhysicalStart,
|
||||
Descriptor->NumberOfPages, MemoryType);
|
||||
/* Check mapping strategy */
|
||||
if(IdentityMapping)
|
||||
{
|
||||
/* 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);
|
||||
|
||||
/* Calculate next valid virtual address */
|
||||
VirtualAddress += Descriptor->NumberOfPages * EFI_PAGE_SIZE;
|
||||
/* Update virtual address */
|
||||
VirtualAddress = VirtualAddress + (Descriptor->NumberOfPages * MM_PAGE_SIZE);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Map all other memory as loader free */
|
||||
Status = MapVirtualMemory(PageMap, NULLPTR, (PVOID)Descriptor->PhysicalStart,
|
||||
Status = MapVirtualMemory(PageMap, (ULONGLONG)NULLPTR, Descriptor->PhysicalStart,
|
||||
Descriptor->NumberOfPages, LoaderFree);
|
||||
}
|
||||
|
||||
@@ -436,7 +460,7 @@ Memory::MapEfiMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
|
||||
}
|
||||
|
||||
/* Always map first page */
|
||||
Status = MapVirtualMemory(PageMap, NULLPTR, (PVOID)0, 1, LoaderFirmwarePermanent);
|
||||
Status = MapVirtualMemory(PageMap, (ULONGLONG)NULLPTR, 0, 1, LoaderFirmwarePermanent);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Mapping failed */
|
||||
@@ -444,7 +468,7 @@ Memory::MapEfiMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
|
||||
}
|
||||
|
||||
/* Map BIOS ROM and VRAM */
|
||||
Status = MapVirtualMemory(PageMap, NULLPTR, (PVOID)0xA0000, 0x60, LoaderFirmwarePermanent);
|
||||
Status = MapVirtualMemory(PageMap, (ULONGLONG)NULLPTR, 0xA0000, 0x60, LoaderFirmwarePermanent);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Mapping failed */
|
||||
@@ -452,7 +476,7 @@ Memory::MapEfiMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
|
||||
}
|
||||
|
||||
/* Store next valid virtual address and return success */
|
||||
*MemoryMapAddress = VirtualAddress;
|
||||
*BaseAddress = (PVOID)VirtualAddress;
|
||||
return STATUS_EFI_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -481,13 +505,13 @@ Memory::MapEfiMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
Memory::MapVirtualMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
|
||||
IN PVOID VirtualAddress,
|
||||
IN PVOID PhysicalAddress,
|
||||
IN ULONGLONG VirtualAddress,
|
||||
IN ULONGLONG PhysicalAddress,
|
||||
IN ULONGLONG NumberOfPages,
|
||||
IN LOADER_MEMORY_TYPE MemoryType)
|
||||
{
|
||||
PXTBL_MEMORY_MAPPING Mapping1, Mapping2, Mapping3;
|
||||
PVOID PhysicalAddressEnd, PhysicalAddress2End;
|
||||
ULONGLONG PhysicalAddressEnd, PhysicalAddress2End;
|
||||
PLIST_ENTRY ListEntry, MappingListEntry;
|
||||
SIZE_T NumberOfMappedPages;
|
||||
EFI_STATUS Status;
|
||||
@@ -507,7 +531,7 @@ Memory::MapVirtualMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
|
||||
Mapping1->MemoryType = MemoryType;
|
||||
|
||||
/* Calculate the end of the physical address */
|
||||
PhysicalAddressEnd = (PVOID)((ULONG_PTR)PhysicalAddress + (NumberOfPages * EFI_PAGE_SIZE) - 1);
|
||||
PhysicalAddressEnd = PhysicalAddress + (NumberOfPages * EFI_PAGE_SIZE) - 1;
|
||||
|
||||
/* Iterate through all the mappings already set to insert new mapping at the correct place */
|
||||
ListEntry = PageMap->MemoryMap.Flink;
|
||||
@@ -515,7 +539,7 @@ Memory::MapVirtualMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
|
||||
{
|
||||
/* Take a mapping from the list and calculate its end of physical address */
|
||||
Mapping2 = CONTAIN_RECORD(ListEntry, XTBL_MEMORY_MAPPING, ListEntry);
|
||||
PhysicalAddress2End = (PVOID)((ULONG_PTR)Mapping2->PhysicalAddress + (Mapping2->NumberOfPages * EFI_PAGE_SIZE) - 1);
|
||||
PhysicalAddress2End = Mapping2->PhysicalAddress + (Mapping2->NumberOfPages * EFI_PAGE_SIZE) - 1;
|
||||
|
||||
/* Check if new mapping is a subset of an existing mapping */
|
||||
if(Mapping1->PhysicalAddress >= Mapping2->PhysicalAddress && PhysicalAddressEnd <= PhysicalAddress2End)
|
||||
@@ -523,7 +547,8 @@ Memory::MapVirtualMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
|
||||
/* Make sure it's memory type is the same */
|
||||
if(Mapping1->MemoryType == Mapping2->MemoryType)
|
||||
{
|
||||
/* It is already mapped */
|
||||
/* Free the unused mapping structure and return success */
|
||||
FreePool(Mapping1);
|
||||
return STATUS_EFI_SUCCESS;
|
||||
}
|
||||
}
|
||||
@@ -539,7 +564,7 @@ Memory::MapVirtualMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
|
||||
}
|
||||
|
||||
/* Calculate number of pages for this mapping */
|
||||
NumberOfMappedPages = ((PUCHAR)PhysicalAddress2End - (PUCHAR)PhysicalAddressEnd) / EFI_PAGE_SIZE;
|
||||
NumberOfMappedPages = (PhysicalAddress2End - PhysicalAddressEnd) / EFI_PAGE_SIZE;
|
||||
if(NumberOfMappedPages > 0)
|
||||
{
|
||||
/* Pages associated to the mapping, allocate memory for it */
|
||||
@@ -550,18 +575,21 @@ Memory::MapVirtualMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Set mapping fields and insert it on the top */
|
||||
Mapping3->PhysicalAddress = (PUCHAR)PhysicalAddressEnd + 1;
|
||||
Mapping3->VirtualAddress = NULLPTR;
|
||||
/* Set mapping fields */
|
||||
Mapping3->PhysicalAddress = PhysicalAddressEnd + 1;
|
||||
Mapping3->VirtualAddress = (ULONGLONG)NULLPTR;
|
||||
Mapping3->NumberOfPages = NumberOfMappedPages;
|
||||
Mapping3->MemoryType = Mapping2->MemoryType;
|
||||
|
||||
/* Insert new mapping in front of the list and increase page map size */
|
||||
RTL::LinkedList::InsertHeadList(&Mapping2->ListEntry, &Mapping3->ListEntry);
|
||||
PageMap->MapSize++;
|
||||
}
|
||||
|
||||
/* Calculate number of pages and the end of the physical address */
|
||||
Mapping2->NumberOfPages = ((PUCHAR)PhysicalAddressEnd + 1 -
|
||||
(PUCHAR)Mapping2->PhysicalAddress) / EFI_PAGE_SIZE;
|
||||
PhysicalAddress2End = (PVOID)((ULONG_PTR)Mapping2->PhysicalAddress + (Mapping2->NumberOfPages * EFI_PAGE_SIZE) - 1);
|
||||
PhysicalAddress2End = Mapping2->PhysicalAddress + (Mapping2->NumberOfPages * EFI_PAGE_SIZE) - 1;
|
||||
}
|
||||
|
||||
/* Check if they overlap */
|
||||
@@ -586,18 +614,21 @@ Memory::MapVirtualMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Set mapping fields and insert it on the top */
|
||||
/* Set mapping fields */
|
||||
Mapping3->PhysicalAddress = Mapping1->PhysicalAddress;
|
||||
Mapping3->VirtualAddress = NULLPTR;
|
||||
Mapping3->VirtualAddress = (ULONGLONG)NULLPTR;
|
||||
Mapping3->NumberOfPages = NumberOfMappedPages;
|
||||
Mapping3->MemoryType = Mapping2->MemoryType;
|
||||
|
||||
/* Insert new mapping in front of the list and increase page map size */
|
||||
RTL::LinkedList::InsertHeadList(&Mapping2->ListEntry, &Mapping3->ListEntry);
|
||||
PageMap->MapSize++;
|
||||
}
|
||||
|
||||
/* Calculate number of pages and the end of the physical address */
|
||||
Mapping2->NumberOfPages = ((PUCHAR)Mapping1->PhysicalAddress -
|
||||
(PUCHAR)Mapping2->PhysicalAddress) / EFI_PAGE_SIZE;
|
||||
PhysicalAddress2End = (PVOID)((ULONG_PTR)Mapping2->PhysicalAddress + (Mapping2->NumberOfPages * EFI_PAGE_SIZE) - 1);
|
||||
PhysicalAddress2End = Mapping2->PhysicalAddress + (Mapping2->NumberOfPages * EFI_PAGE_SIZE) - 1;
|
||||
}
|
||||
|
||||
/* Check if mapping is really needed */
|
||||
@@ -619,15 +650,19 @@ Memory::MapVirtualMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
|
||||
Status = FreePool(Mapping2);
|
||||
ListEntry = MappingListEntry;
|
||||
|
||||
/* Go to the next mapping */
|
||||
/* Decrease page map size and go to the next mapping */
|
||||
PageMap->MapSize--;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Determine physical address order */
|
||||
if(Mapping2->PhysicalAddress > Mapping1->PhysicalAddress)
|
||||
{
|
||||
/* Insert new mapping in front */
|
||||
/* Insert new mapping in front of the list and increase page map size */
|
||||
RTL::LinkedList::InsertHeadList(Mapping2->ListEntry.Blink, &Mapping1->ListEntry);
|
||||
PageMap->MapSize++;
|
||||
|
||||
/* Return success */
|
||||
return STATUS_EFI_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -635,7 +670,7 @@ Memory::MapVirtualMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
|
||||
ListEntry = ListEntry->Flink;
|
||||
}
|
||||
|
||||
/* Insert new mapping to the list and increase page map size */
|
||||
/* Insert new mapping to the tail of the list and increase page map size */
|
||||
RTL::LinkedList::InsertTailList(&PageMap->MemoryMap, &Mapping1->ListEntry);
|
||||
PageMap->MapSize++;
|
||||
|
||||
|
||||
@@ -729,11 +729,11 @@ PeCoff::RelocateLoadedImage(IN PPECOFF_IMAGE_CONTEXT Image)
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Check if loaded 32-bit PE32 image should be relocated */
|
||||
/* Set relocation data directory and image base address */
|
||||
DataDirectory = &Image->PeHeader->OptionalHeader32.DataDirectory[PECOFF_IMAGE_DIRECTORY_ENTRY_BASERELOC];
|
||||
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 ||
|
||||
DataDirectory->VirtualAddress == 0 || DataDirectory->Size < sizeof(PECOFF_IMAGE_BASE_RELOCATION))
|
||||
{
|
||||
|
||||
@@ -10,6 +10,49 @@
|
||||
#include <xtos.hh>
|
||||
|
||||
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
Xtos::BuildPageMap(IN PXTBL_PAGE_MAPPING PageMap)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
|
||||
/* Build page map */
|
||||
Status = XtLdrProtocol->Memory.BuildPageMap(PageMap, (PageMap->PageMapLevel > 4) ? MM_P5E_LA57_BASE : MM_PXE_BASE);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Failed to build page map */
|
||||
XtLdrProtocol->Debug.Print(L"Failed to build page map (Status code: %zX)\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Map memory for hardware layer */
|
||||
Status = MapHardwareMemoryPool(PageMap);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Failed to map memory for hardware layer */
|
||||
XtLdrProtocol->Debug.Print(L"Failed to map memory for hardware leyer (Status code: %zX)\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Return success */
|
||||
return STATUS_EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
@@ -76,24 +119,6 @@ Xtos::EnablePaging(IN PXTBL_PAGE_MAPPING PageMap)
|
||||
ULONG_PTR TrampolineSize;
|
||||
PVOID TrampolineCode;
|
||||
|
||||
/* Build page map */
|
||||
Status = XtLdrProtocol->Memory.BuildPageMap(PageMap, (PageMap->PageMapLevel > 4) ? MM_P5E_LA57_BASE : MM_PXE_BASE);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Failed to build page map */
|
||||
XtLdrProtocol->Debug.Print(L"Failed to build page map (Status code: %zX)\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Map memory for hardware layer */
|
||||
Status = MapHardwareMemoryPool(PageMap);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Failed to map memory for hardware layer */
|
||||
XtLdrProtocol->Debug.Print(L"Failed to map memory for hardware leyer (Status code: %zX)\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Check the configured page map level to set the LA57 state accordingly */
|
||||
if(PageMap->PageMapLevel == 5)
|
||||
{
|
||||
@@ -173,6 +198,7 @@ Xtos::MapHardwareMemoryPool(IN PXTBL_PAGE_MAPPING PageMap)
|
||||
PHARDWARE_PTE P5eBase, PdeBase, PpeBase, PxeBase;
|
||||
EFI_PHYSICAL_ADDRESS Address;
|
||||
EFI_STATUS Status;
|
||||
ULONG Index;
|
||||
|
||||
if(PageMap->PageMapLevel == 5)
|
||||
{
|
||||
@@ -190,6 +216,9 @@ Xtos::MapHardwareMemoryPool(IN PXTBL_PAGE_MAPPING PageMap)
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Map hardware memory */
|
||||
XtLdrProtocol->Memory.MapVirtualMemory(PageMap, (ULONGLONG)NULLPTR, Address, 1, LoaderMemoryData);
|
||||
|
||||
/* Zero fill memory used by P5E */
|
||||
XtLdrProtocol->Memory.ZeroMemory((PVOID)Address, EFI_PAGE_SIZE);
|
||||
|
||||
@@ -224,6 +253,9 @@ Xtos::MapHardwareMemoryPool(IN PXTBL_PAGE_MAPPING PageMap)
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Map hardware memory */
|
||||
XtLdrProtocol->Memory.MapVirtualMemory(PageMap, (ULONGLONG)NULLPTR, Address, 1, LoaderMemoryData);
|
||||
|
||||
/* Zero fill memory used by PXE */
|
||||
XtLdrProtocol->Memory.ZeroMemory((PVOID)Address, EFI_PAGE_SIZE);
|
||||
|
||||
@@ -252,6 +284,9 @@ Xtos::MapHardwareMemoryPool(IN PXTBL_PAGE_MAPPING PageMap)
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Map hardware memory */
|
||||
XtLdrProtocol->Memory.MapVirtualMemory(PageMap, (ULONGLONG)NULLPTR, Address, 1, LoaderMemoryData);
|
||||
|
||||
/* Zero fill memory used by PPE */
|
||||
XtLdrProtocol->Memory.ZeroMemory((PVOID)Address, EFI_PAGE_SIZE);
|
||||
|
||||
@@ -270,7 +305,7 @@ Xtos::MapHardwareMemoryPool(IN PXTBL_PAGE_MAPPING PageMap)
|
||||
}
|
||||
|
||||
/* Loop through 2 PDE entries */
|
||||
for(UINT Index = 0 ; Index < 2 ; Index++)
|
||||
for(Index = 0 ; Index < 2 ; Index++)
|
||||
{
|
||||
/* Check if PDE entry already exists */
|
||||
if(!PdeBase[((MM_HARDWARE_VA_START >> MM_PDI_SHIFT) & 0x1FF) + Index].Valid)
|
||||
@@ -283,6 +318,9 @@ Xtos::MapHardwareMemoryPool(IN PXTBL_PAGE_MAPPING PageMap)
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Map hardware memory */
|
||||
XtLdrProtocol->Memory.MapVirtualMemory(PageMap, (ULONGLONG)NULLPTR, Address, 1, LoaderMemoryData);
|
||||
|
||||
/* Zero fill memory used by PDE */
|
||||
XtLdrProtocol->Memory.ZeroMemory((PVOID)Address, EFI_PAGE_SIZE);
|
||||
|
||||
|
||||
@@ -9,6 +9,62 @@
|
||||
#include <xtos.hh>
|
||||
|
||||
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
Xtos::BuildPageMap(IN PXTBL_PAGE_MAPPING PageMap)
|
||||
{
|
||||
ULONG_PTR SelfMapAddress;
|
||||
EFI_STATUS Status;
|
||||
|
||||
/* 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 */
|
||||
Status = XtLdrProtocol->Memory.BuildPageMap(PageMap, SelfMapAddress);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Failed to build page map */
|
||||
XtLdrProtocol->Debug.Print(L"Failed to build page map (Status code: %zX)\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Map memory for hardware layer */
|
||||
Status = MapHardwareMemoryPool(PageMap);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Failed to map memory for hardware layer */
|
||||
XtLdrProtocol->Debug.Print(L"Failed to map memory for hardware layer (Status code: %zX)\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Return success */
|
||||
return STATUS_EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
@@ -60,24 +116,6 @@ Xtos::EnablePaging(IN PXTBL_PAGE_MAPPING PageMap)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
|
||||
/* Build page map */
|
||||
Status = XtLdrProtocol->Memory.BuildPageMap(PageMap, MM_PTE_BASE);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Failed to build page map */
|
||||
XtLdrProtocol->Debug.Print(L"Failed to build page map (Status code: %zX)\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Map memory for hardware layer */
|
||||
Status = MapHardwareMemoryPool(PageMap);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Failed to map memory for hardware layer */
|
||||
XtLdrProtocol->Debug.Print(L"Failed to map memory for hardware layer (Status code: %zX)\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Exit EFI Boot Services */
|
||||
XtLdrProtocol->Debug.Print(L"Exiting EFI boot services\n");
|
||||
Status = XtLdrProtocol->Utils.ExitBootServices();
|
||||
@@ -145,6 +183,9 @@ Xtos::MapHardwareMemoryPool(IN PXTBL_PAGE_MAPPING PageMap)
|
||||
/* Zero fill allocated memory */
|
||||
XtLdrProtocol->Memory.ZeroMemory((PVOID)Address, EFI_PAGE_SIZE);
|
||||
|
||||
/* Map hardware memory */
|
||||
XtLdrProtocol->Memory.MapVirtualMemory(PageMap, (ULONGLONG)NULLPTR, Address, 1, LoaderMemoryData);
|
||||
|
||||
/* Check if PAE is enabled (3-level paging) */
|
||||
if(PageMap->PageMapLevel == 3)
|
||||
{
|
||||
|
||||
@@ -38,7 +38,9 @@ class Xtos
|
||||
IN PVOID PhysicalAddress,
|
||||
IN UINT NumberOfPages,
|
||||
IN LOADER_MEMORY_TYPE MemoryType);
|
||||
STATIC XTCDECL EFI_STATUS BuildPageMap(IN PXTBL_PAGE_MAPPING PageMap);
|
||||
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 EFI_STATUS EnablePaging(IN PXTBL_PAGE_MAPPING PageMap);
|
||||
STATIC XTCDECL VOID GetDisplayInformation(OUT PSYSTEM_RESOURCE_FRAMEBUFFER FrameBufferResource,
|
||||
@@ -46,10 +48,13 @@ class Xtos
|
||||
IN PULONG_PTR FrameBufferSize,
|
||||
IN PXTBL_FRAMEBUFFER_MODE_INFORMATION FrameBufferModeInfo);
|
||||
STATIC XTCDECL EFI_STATUS GetMemoryDescriptorList(IN PXTBL_PAGE_MAPPING PageMap,
|
||||
IN PVOID *VirtualAddress,
|
||||
IN EFI_PHYSICAL_ADDRESS PhysicalBase,
|
||||
IN PVOID VirtualBase,
|
||||
OUT PLIST_ENTRY MemoryDescriptorList);
|
||||
STATIC XTCDECL EFI_STATUS GetSystemResourcesList(IN PXTBL_PAGE_MAPPING PageMap,
|
||||
IN PVOID *VirtualAddress,
|
||||
IN EFI_PHYSICAL_ADDRESS PhysicalBase,
|
||||
IN PVOID VirtualBase,
|
||||
IN PVOID FrameBufferVirtualBase,
|
||||
OUT PLIST_ENTRY SystemResourcesList);
|
||||
STATIC XTCDECL EFI_STATUS GetVirtualAddress(IN PLIST_ENTRY MemoryMappings,
|
||||
IN PVOID PhysicalAddress,
|
||||
|
||||
@@ -191,56 +191,52 @@ Xtos::GetDisplayInformation(OUT PSYSTEM_RESOURCE_FRAMEBUFFER FrameBufferResource
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
Xtos::GetMemoryDescriptorList(IN PXTBL_PAGE_MAPPING PageMap,
|
||||
IN PVOID *VirtualAddress,
|
||||
IN EFI_PHYSICAL_ADDRESS PhysicalBase,
|
||||
IN PVOID VirtualBase,
|
||||
OUT PLIST_ENTRY MemoryDescriptorList)
|
||||
{
|
||||
EFI_PHYSICAL_ADDRESS Address;
|
||||
EFI_STATUS Status;
|
||||
ULONGLONG Pages;
|
||||
|
||||
Pages = (ULONGLONG)EFI_SIZE_TO_PAGES((PageMap->MapSize + 1) * sizeof(LOADER_MEMORY_DESCRIPTOR));
|
||||
|
||||
Status = XtLdrProtocol->Memory.AllocatePages(AllocateAnyPages, Pages, &Address);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
return Status;
|
||||
}
|
||||
|
||||
Status = XtLdrProtocol->Memory.MapVirtualMemory(PageMap, *VirtualAddress, (PVOID)Address, Pages, LoaderMemoryData);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
XtLdrProtocol->Memory.FreePages(Address, Pages);
|
||||
return Status;
|
||||
}
|
||||
|
||||
PVOID PhysicalBase = (PVOID)Address;
|
||||
|
||||
PLOADER_MEMORY_DESCRIPTOR Descriptor;
|
||||
PXTBL_MEMORY_MAPPING MemoryMapping;
|
||||
PLIST_ENTRY ListEntry;
|
||||
|
||||
/* Initialize the descriptor pointer to the start of the allocated physical buffer */
|
||||
Descriptor = (PLOADER_MEMORY_DESCRIPTOR)PhysicalBase;
|
||||
|
||||
/* Get the first entry from the internal boot loader memory map */
|
||||
ListEntry = PageMap->MemoryMap.Flink;
|
||||
|
||||
/* Iterate through the internal memory map and populate the loader descriptor list */
|
||||
while(ListEntry != &PageMap->MemoryMap)
|
||||
{
|
||||
PXTBL_MEMORY_MAPPING MemoryMapping = CONTAIN_RECORD(ListEntry, XTBL_MEMORY_MAPPING, ListEntry);
|
||||
PLOADER_MEMORY_DESCRIPTOR MemoryDescriptor = (PLOADER_MEMORY_DESCRIPTOR)Address;
|
||||
/* Retrieve the internal memory mapping record from the current list entry */
|
||||
MemoryMapping = CONTAIN_RECORD(ListEntry, XTBL_MEMORY_MAPPING, ListEntry);
|
||||
|
||||
MemoryDescriptor->MemoryType = MemoryMapping->MemoryType;
|
||||
MemoryDescriptor->BasePage = (UINT_PTR)MemoryMapping->PhysicalAddress / EFI_PAGE_SIZE;
|
||||
MemoryDescriptor->PageCount = MemoryMapping->NumberOfPages;
|
||||
/* Transfer memory type and address information to the kernel descriptor */
|
||||
Descriptor->MemoryType = MemoryMapping->MemoryType;
|
||||
Descriptor->BasePage = (UINT_PTR)(MemoryMapping->PhysicalAddress / EFI_PAGE_SIZE);
|
||||
Descriptor->PageCount = (ULONG)MemoryMapping->NumberOfPages;
|
||||
|
||||
XtLdrProtocol->LinkedList.InsertTail(MemoryDescriptorList, &MemoryDescriptor->ListEntry);
|
||||
/* Link the entry */
|
||||
XtLdrProtocol->LinkedList.InsertTail(MemoryDescriptorList, &Descriptor->ListEntry);
|
||||
|
||||
Address = Address + sizeof(LOADER_MEMORY_DESCRIPTOR);
|
||||
/* Move to the next slot in the allocated buffer */
|
||||
Descriptor++;
|
||||
ListEntry = ListEntry->Flink;
|
||||
}
|
||||
|
||||
XtLdrProtocol->Memory.PhysicalListToVirtual(PageMap, MemoryDescriptorList, PhysicalBase, *VirtualAddress);
|
||||
/* Convert all physical link pointers in the list to their corresponding virtual addresses */
|
||||
XtLdrProtocol->Memory.PhysicalListToVirtual(PageMap, MemoryDescriptorList, (PVOID)PhysicalBase, VirtualBase);
|
||||
|
||||
/* Return success */
|
||||
return STATUS_EFI_SUCCESS;
|
||||
}
|
||||
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
Xtos::GetSystemResourcesList(IN PXTBL_PAGE_MAPPING PageMap,
|
||||
IN PVOID *VirtualAddress,
|
||||
IN EFI_PHYSICAL_ADDRESS PhysicalBase,
|
||||
IN PVOID VirtualBase,
|
||||
IN PVOID FrameBufferVirtualBase,
|
||||
OUT PLIST_ENTRY SystemResourcesList)
|
||||
{
|
||||
XTSTATUS Status;
|
||||
@@ -251,39 +247,18 @@ Xtos::GetSystemResourcesList(IN PXTBL_PAGE_MAPPING PageMap,
|
||||
PXTBL_FRAMEBUFFER_PROTOCOL FrameBufProtocol;
|
||||
XTBL_FRAMEBUFFER_MODE_INFORMATION FbModeInfo;
|
||||
EFI_PHYSICAL_ADDRESS FbAddress;
|
||||
EFI_PHYSICAL_ADDRESS OriginalPhysicalBase;
|
||||
ULONG_PTR FbSize;
|
||||
UINT FrameBufferPages;
|
||||
PSYSTEM_RESOURCE_FRAMEBUFFER FrameBufferResource;
|
||||
PSYSTEM_RESOURCE_ACPI AcpiResource;
|
||||
ULONGLONG Pages;
|
||||
EFI_PHYSICAL_ADDRESS Address;
|
||||
PVOID PhysicalBase, VirtualBase;
|
||||
|
||||
Pages = (ULONGLONG)EFI_SIZE_TO_PAGES(sizeof(SYSTEM_RESOURCE_ACPI) + sizeof(SYSTEM_RESOURCE_FRAMEBUFFER));
|
||||
|
||||
Status = XtLdrProtocol->Memory.AllocatePages(AllocateAnyPages, Pages, &Address);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
return Status;
|
||||
}
|
||||
Status = XtLdrProtocol->Memory.MapVirtualMemory(PageMap, *VirtualAddress, (PVOID)Address, Pages, LoaderFirmwarePermanent);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
XtLdrProtocol->Memory.FreePages(Address, Pages);
|
||||
return Status;
|
||||
}
|
||||
|
||||
PhysicalBase = (PVOID)Address;
|
||||
VirtualBase = *VirtualAddress;
|
||||
|
||||
/* Calculate next valid virtual address */
|
||||
*VirtualAddress = (PUINT8)*VirtualAddress + (Pages * EFI_PAGE_SIZE);
|
||||
|
||||
AcpiResource = (PSYSTEM_RESOURCE_ACPI)Address;
|
||||
/* Save original physical base */
|
||||
OriginalPhysicalBase = PhysicalBase;
|
||||
|
||||
AcpiResource = (PSYSTEM_RESOURCE_ACPI)PhysicalBase;
|
||||
XtLdrProtocol->Memory.ZeroMemory(AcpiResource, sizeof(SYSTEM_RESOURCE_ACPI));
|
||||
|
||||
/* Load FrameBuffer protocol */
|
||||
/* Load ACPI protocol */
|
||||
Status = XtLdrProtocol->Protocol.Open(&ProtocolHandle, (PVOID*)&AcpiProtocol, &AcpiGuid);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
@@ -302,13 +277,11 @@ Xtos::GetSystemResourcesList(IN PXTBL_PAGE_MAPPING PageMap,
|
||||
|
||||
XtLdrProtocol->LinkedList.InsertTail(SystemResourcesList, &AcpiResource->Header.ListEntry);
|
||||
|
||||
/* Close FrameBuffer protocol */
|
||||
XtLdrProtocol->Protocol.Close(&ProtocolHandle, &FrameBufGuid);
|
||||
|
||||
Address = Address + sizeof(SYSTEM_RESOURCE_ACPI);
|
||||
|
||||
FrameBufferResource = (PSYSTEM_RESOURCE_FRAMEBUFFER)Address;
|
||||
/* Close ACPI protocol */
|
||||
XtLdrProtocol->Protocol.Close(&ProtocolHandle, &AcpiGuid);
|
||||
|
||||
PhysicalBase = PhysicalBase + sizeof(SYSTEM_RESOURCE_ACPI);
|
||||
FrameBufferResource = (PSYSTEM_RESOURCE_FRAMEBUFFER)PhysicalBase;
|
||||
XtLdrProtocol->Memory.ZeroMemory(FrameBufferResource, sizeof(SYSTEM_RESOURCE_FRAMEBUFFER));
|
||||
|
||||
/* Load FrameBuffer protocol */
|
||||
@@ -329,26 +302,16 @@ Xtos::GetSystemResourcesList(IN PXTBL_PAGE_MAPPING PageMap,
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Calculate pages needed to map framebuffer */
|
||||
FrameBufferPages = EFI_SIZE_TO_PAGES(FbSize);
|
||||
|
||||
/* Rewrite framebuffer address by using virtual address */
|
||||
FrameBufferResource->Header.VirtualAddress = *VirtualAddress;
|
||||
|
||||
/* Map frame buffer memory */
|
||||
XtLdrProtocol->Memory.MapVirtualMemory(PageMap, FrameBufferResource->Header.VirtualAddress,
|
||||
FrameBufferResource->Header.PhysicalAddress,
|
||||
FrameBufferPages, LoaderFirmwarePermanent);
|
||||
|
||||
/* Close FrameBuffer protocol */
|
||||
/* Assign the pre-mapped virtual address to the resource block */
|
||||
FrameBufferResource->Header.VirtualAddress = FrameBufferVirtualBase;
|
||||
XtLdrProtocol->Protocol.Close(&ProtocolHandle, &FrameBufGuid);
|
||||
|
||||
*VirtualAddress = (PUINT8)*VirtualAddress + (FrameBufferPages * EFI_PAGE_SIZE);
|
||||
|
||||
XtLdrProtocol->LinkedList.InsertTail(SystemResourcesList, &FrameBufferResource->Header.ListEntry);
|
||||
|
||||
XtLdrProtocol->Memory.PhysicalListToVirtual(PageMap, SystemResourcesList, PhysicalBase, VirtualBase);
|
||||
/* Convert list pointers to virtual */
|
||||
XtLdrProtocol->Memory.PhysicalListToVirtual(PageMap, SystemResourcesList, (PVOID)OriginalPhysicalBase, VirtualBase);
|
||||
|
||||
/* Return success */
|
||||
return STATUS_EFI_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -389,7 +352,7 @@ Xtos::InitializeApicBase(IN PXTBL_PAGE_MAPPING PageMap)
|
||||
}
|
||||
|
||||
/* Map APIC base address */
|
||||
XtLdrProtocol->Memory.MapVirtualMemory(PageMap, (PVOID)APIC_BASE, ApicBaseAddress, 1, LoaderFirmwarePermanent);
|
||||
XtLdrProtocol->Memory.MapVirtualMemory(PageMap, APIC_BASE, (ULONGLONG)ApicBaseAddress, 1, LoaderFirmwarePermanent);
|
||||
return STATUS_EFI_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -409,34 +372,100 @@ Xtos::InitializeApicBase(IN PXTBL_PAGE_MAPPING PageMap)
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
Xtos::InitializeLoaderBlock(IN PXTBL_PAGE_MAPPING PageMap,
|
||||
IN PVOID *VirtualAddress,
|
||||
IN OUT PVOID *VirtualAddress,
|
||||
IN PXTBL_BOOT_PARAMETERS Parameters)
|
||||
{
|
||||
EFI_PHYSICAL_ADDRESS FbPhysicalAddress, PhysicalBlock, PhysicalDescriptor, PhysicalResources;
|
||||
PVOID FbVirtualAddress, VirtualBlock, VirtualResources, VirtualDescriptor;
|
||||
UINT BlockPages, DescriptorPages, FbPages, ParametersSize, ResourcesPages;
|
||||
XTBL_FRAMEBUFFER_MODE_INFORMATION FbModeInfo;
|
||||
PXTBL_FRAMEBUFFER_PROTOCOL FrameBufProtocol;
|
||||
PKERNEL_INITIALIZATION_BLOCK LoaderBlock;
|
||||
EFI_PHYSICAL_ADDRESS Address;
|
||||
EFI_HANDLE ProtocolHandle;
|
||||
EFI_STATUS Status;
|
||||
UINT BlockPages;
|
||||
UINT ParametersSize;
|
||||
ULONG_PTR FbSize;
|
||||
|
||||
EFI_GUID FrameBufGuid = XT_FRAMEBUFFER_PROTOCOL_GUID;
|
||||
|
||||
/* Initialize Framebuffer information */
|
||||
FbPhysicalAddress = 0;
|
||||
FbSize = 0;
|
||||
FbVirtualAddress = NULLPTR;
|
||||
FbPages = 0;
|
||||
|
||||
/* Calculate size of parameters */
|
||||
ParametersSize = (XtLdrProtocol->WideString.Length(Parameters->Parameters, 0) + 1) * sizeof(WCHAR);
|
||||
|
||||
/* Calculate number of pages needed for initialization block */
|
||||
BlockPages = EFI_SIZE_TO_PAGES(sizeof(KERNEL_INITIALIZATION_BLOCK) + ParametersSize);
|
||||
ResourcesPages = EFI_SIZE_TO_PAGES(sizeof(SYSTEM_RESOURCE_ACPI) + sizeof(SYSTEM_RESOURCE_FRAMEBUFFER));
|
||||
|
||||
/* Allocate memory for kernel initialization block */
|
||||
Status = XtLdrProtocol->Memory.AllocatePages(AllocateAnyPages, BlockPages, &Address);
|
||||
/* Query Framebuffer size for allocation */
|
||||
if(XtLdrProtocol->Protocol.Open(&ProtocolHandle, (PVOID*)&FrameBufProtocol, &FrameBufGuid) == STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Get FrameBuffer information */
|
||||
FrameBufProtocol->GetDisplayInformation(&FbPhysicalAddress, &FbSize, &FbModeInfo);
|
||||
XtLdrProtocol->Protocol.Close(&ProtocolHandle, &FrameBufGuid);
|
||||
}
|
||||
FbPages = EFI_SIZE_TO_PAGES(FbSize);
|
||||
|
||||
/* Precommit page map to allocate memory */
|
||||
XtLdrProtocol->Memory.CommitPageMap(PageMap);
|
||||
|
||||
/* Calculate number of pages needed for memory descriptor list */
|
||||
DescriptorPages = EFI_SIZE_TO_PAGES(PageMap->MapSize * sizeof(LOADER_MEMORY_DESCRIPTOR) * 2);
|
||||
|
||||
/* Allocate memory for the kernel initialization block and boot parameters */
|
||||
Status = XtLdrProtocol->Memory.AllocatePages(AllocateAnyPages, BlockPages, &PhysicalBlock);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Memory allocation failure */
|
||||
/* Memory allocation failure, return status code */
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Initialize and zero-fill kernel initialization block */
|
||||
LoaderBlock = (PKERNEL_INITIALIZATION_BLOCK)(UINT_PTR)Address;
|
||||
XtLdrProtocol->Memory.ZeroMemory(LoaderBlock, sizeof(KERNEL_INITIALIZATION_BLOCK) + ParametersSize);
|
||||
/* Allocate memory for the system resources data structures */
|
||||
Status = XtLdrProtocol->Memory.AllocatePages(AllocateAnyPages, ResourcesPages, &PhysicalResources);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Memory allocation failure, return status code */
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Allocate memory for the memory descriptor list */
|
||||
Status = XtLdrProtocol->Memory.AllocatePages(AllocateAnyPages, DescriptorPages, &PhysicalDescriptor);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Memory allocation failure, return status code */
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Map the Kernel Initialization Block into virtual memory and advance the virtual address pointer */
|
||||
VirtualBlock = *VirtualAddress;
|
||||
XtLdrProtocol->Memory.MapVirtualMemory(PageMap, (ULONGLONG)VirtualBlock, PhysicalBlock, BlockPages, LoaderSystemBlock);
|
||||
*VirtualAddress = (PUINT8)*VirtualAddress + (BlockPages * EFI_PAGE_SIZE);
|
||||
|
||||
/* Map the system resources physical memory into virtual address space and update the allocation pointer */
|
||||
VirtualResources = *VirtualAddress;
|
||||
XtLdrProtocol->Memory.MapVirtualMemory(PageMap, (ULONGLONG)VirtualResources, PhysicalResources, ResourcesPages, LoaderFirmwarePermanent);
|
||||
*VirtualAddress = (PUINT8)*VirtualAddress + (ResourcesPages * EFI_PAGE_SIZE);
|
||||
|
||||
/* Check if a framebuffer was detected and requires memory mapping */
|
||||
if(FbPages > 0)
|
||||
{
|
||||
/* Map the framebuffer physical memory range into virtual address space */
|
||||
FbVirtualAddress = *VirtualAddress;
|
||||
XtLdrProtocol->Memory.MapVirtualMemory(PageMap, (ULONGLONG)FbVirtualAddress, FbPhysicalAddress, FbPages, LoaderFirmwarePermanent);
|
||||
*VirtualAddress = (PUINT8)*VirtualAddress + (FbPages * EFI_PAGE_SIZE);
|
||||
}
|
||||
|
||||
/* Map the allocated physical memory for memory descriptors into the virtual address space */
|
||||
VirtualDescriptor = *VirtualAddress;
|
||||
XtLdrProtocol->Memory.MapVirtualMemory(PageMap, (ULONGLONG)VirtualDescriptor, PhysicalDescriptor, DescriptorPages, LoaderMemoryData);
|
||||
*VirtualAddress = (PUINT8)*VirtualAddress + (DescriptorPages * EFI_PAGE_SIZE);
|
||||
|
||||
/* Set basic loader block properties */
|
||||
XtLdrProtocol->Memory.ZeroMemory((PVOID)PhysicalBlock, sizeof(KERNEL_INITIALIZATION_BLOCK) + ParametersSize);
|
||||
LoaderBlock = (PKERNEL_INITIALIZATION_BLOCK)PhysicalBlock;
|
||||
LoaderBlock->BlockSize = sizeof(KERNEL_INITIALIZATION_BLOCK);
|
||||
LoaderBlock->BlockVersion = INITIALIZATION_BLOCK_VERSION;
|
||||
LoaderBlock->ProtocolVersion = BOOT_PROTOCOL_VERSION;
|
||||
@@ -450,24 +479,33 @@ Xtos::InitializeLoaderBlock(IN PXTBL_PAGE_MAPPING PageMap,
|
||||
LoaderBlock->FirmwareInformation.EfiFirmware.EfiRuntimeServices = NULLPTR;
|
||||
|
||||
/* Copy parameters to kernel initialization block */
|
||||
LoaderBlock->KernelParameters = (PWCHAR)((UINT_PTR)*VirtualAddress + sizeof(KERNEL_INITIALIZATION_BLOCK));
|
||||
LoaderBlock->KernelParameters = (PWCHAR)((UINT_PTR)VirtualBlock + sizeof(KERNEL_INITIALIZATION_BLOCK));
|
||||
XtLdrProtocol->Memory.CopyMemory((PVOID)((UINT_PTR)LoaderBlock + sizeof(KERNEL_INITIALIZATION_BLOCK)),
|
||||
Parameters->Parameters,
|
||||
ParametersSize);
|
||||
Parameters->Parameters, ParametersSize);
|
||||
|
||||
/* Map kernel initialization block */
|
||||
XtLdrProtocol->Memory.MapVirtualMemory(PageMap, *VirtualAddress, (PVOID)LoaderBlock,
|
||||
BlockPages, LoaderSystemBlock);
|
||||
|
||||
/* Calculate next valid virtual address */
|
||||
*VirtualAddress = (PUINT8)*VirtualAddress + (BlockPages * EFI_PAGE_SIZE);
|
||||
/* Commit mappings */
|
||||
XtLdrProtocol->Memory.CommitPageMap(PageMap);
|
||||
|
||||
/* Initialize system resources list */
|
||||
XtLdrProtocol->LinkedList.InitializeHead(&LoaderBlock->SystemResourcesListHead);
|
||||
GetSystemResourcesList(PageMap, VirtualAddress, &LoaderBlock->SystemResourcesListHead);
|
||||
Status = GetSystemResourcesList(PageMap, PhysicalResources, VirtualResources, FbVirtualAddress, &LoaderBlock->SystemResourcesListHead);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Failed to initialize system resources list, return status code */
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Initialize memory descriptor list */
|
||||
XtLdrProtocol->LinkedList.InitializeHead(&LoaderBlock->MemoryDescriptorListHead);
|
||||
GetMemoryDescriptorList(PageMap, VirtualAddress, &LoaderBlock->MemoryDescriptorListHead);
|
||||
Status = GetMemoryDescriptorList(PageMap, PhysicalDescriptor, VirtualDescriptor, &LoaderBlock->MemoryDescriptorListHead);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Failed to initialize memory descriptor list, return status code */
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Set boot image size */
|
||||
LoaderBlock->BootImageSize = (PFN_NUMBER)(((ULONGLONG)*VirtualAddress - KSEG0_BASE) / EFI_PAGE_SIZE);
|
||||
|
||||
/* Return success */
|
||||
return STATUS_EFI_SUCCESS;
|
||||
@@ -607,11 +645,12 @@ Xtos::RunBootSequence(IN PEFI_FILE_HANDLE BootDir,
|
||||
PXTBL_FRAMEBUFFER_PROTOCOL FrameBufProtocol;
|
||||
PPECOFF_IMAGE_CONTEXT ImageContext = NULLPTR;
|
||||
PEFI_LOADED_IMAGE_PROTOCOL ImageProtocol;
|
||||
PVOID VirtualAddress, VirtualMemoryArea;
|
||||
PVOID VirtualAddress;
|
||||
PXT_ENTRY_POINT KernelEntryPoint;
|
||||
EFI_HANDLE ProtocolHandle;
|
||||
EFI_STATUS Status;
|
||||
XTBL_PAGE_MAPPING PageMap;
|
||||
BOOLEAN IdentityMapping;
|
||||
|
||||
/* Initialize XTOS startup sequence */
|
||||
XtLdrProtocol->Debug.Print(L"Initializing XTOS startup sequence\n");
|
||||
@@ -628,19 +667,30 @@ Xtos::RunBootSequence(IN PEFI_FILE_HANDLE BootDir,
|
||||
/* Close FrameBuffer protocol */
|
||||
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 */
|
||||
VirtualMemoryArea = (PVOID)KSEG0_BASE;
|
||||
VirtualAddress = (PVOID)(KSEG0_BASE + KSEG0_KERNEL_BASE);
|
||||
VirtualAddress = (PVOID)(KSEG0_BASE);
|
||||
|
||||
/* Initialize virtual memory mappings */
|
||||
XtLdrProtocol->Memory.InitializePageMap(&PageMap, DeterminePagingLevel(Parameters->Parameters), Size4K);
|
||||
|
||||
Status = XtLdrProtocol->Memory.MapEfiMemory(&PageMap, &VirtualMemoryArea, NULLPTR);
|
||||
/* Map all EFI memory regions */
|
||||
Status = XtLdrProtocol->Memory.MapEfiMemory(&PageMap, &VirtualAddress, IdentityMapping, NULLPTR);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Mapping failed */
|
||||
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 */
|
||||
Status = LoadModule(BootDir, Parameters->KernelFile, VirtualAddress, LoaderSystemCode, &ImageContext);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
@@ -650,8 +700,8 @@ Xtos::RunBootSequence(IN PEFI_FILE_HANDLE BootDir,
|
||||
}
|
||||
|
||||
/* Add kernel image memory mapping */
|
||||
Status = XtLdrProtocol->Memory.MapVirtualMemory(&PageMap, ImageContext->VirtualAddress,
|
||||
ImageContext->PhysicalAddress, ImageContext->ImagePages,
|
||||
Status = XtLdrProtocol->Memory.MapVirtualMemory(&PageMap, (ULONGLONG)ImageContext->VirtualAddress,
|
||||
(ULONGLONG)ImageContext->PhysicalAddress, ImageContext->ImagePages,
|
||||
LoaderSystemCode);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
@@ -670,6 +720,14 @@ Xtos::RunBootSequence(IN PEFI_FILE_HANDLE BootDir,
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Build page map */
|
||||
Status = BuildPageMap(&PageMap);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
XtLdrProtocol->Debug.Print(L"Failed to build page map (Status code: %zX)\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Store virtual address of kernel initialization block for future kernel call */
|
||||
KernelParameters = (PKERNEL_INITIALIZATION_BLOCK)VirtualAddress;
|
||||
|
||||
|
||||
@@ -1054,6 +1054,7 @@ Protocol::InstallXtLoaderProtocol()
|
||||
LoaderProtocol.Memory.AllocatePages = Memory::AllocatePages;
|
||||
LoaderProtocol.Memory.AllocatePool = Memory::AllocatePool;
|
||||
LoaderProtocol.Memory.BuildPageMap = Memory::BuildPageMap;
|
||||
LoaderProtocol.Memory.CommitPageMap = Memory::CommitPageMap;
|
||||
LoaderProtocol.Memory.CompareMemory = RTL::Memory::CompareMemory;
|
||||
LoaderProtocol.Memory.CopyMemory = RTL::Memory::CopyMemory;
|
||||
LoaderProtocol.Memory.FreePages = Memory::FreePages;
|
||||
|
||||
@@ -236,6 +236,15 @@ BlStartXtLoader(IN EFI_HANDLE ImageHandle,
|
||||
PWCHAR Modules;
|
||||
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 */
|
||||
XtLoader::InitializeBootLoader(ImageHandle, SystemTable);
|
||||
|
||||
|
||||
@@ -4,48 +4,41 @@
|
||||
# DESCRIPTION: Project configuration script for preparing the build environment
|
||||
# DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
|
||||
|
||||
|
||||
# Check XTchain
|
||||
if (-not $env:XTCVER) {
|
||||
Write-Host "XTChain not detected or corrupted!"
|
||||
Write-Error "XTChain not detected or corrupted!"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Set target architecture
|
||||
if ($env:TARGET) {
|
||||
$ARCH = $env:TARGET
|
||||
} else {
|
||||
$ARCH = "amd64"
|
||||
}
|
||||
# Set target architecture defaulting to amd64
|
||||
$ARCH = if ($env:TARGET) { $env:TARGET } else { "amd64" }
|
||||
|
||||
# Set target build type
|
||||
if (-not $env:BUILD_TYPE) {
|
||||
$env:BUILD_TYPE = "DEBUG"
|
||||
}
|
||||
# Set target build type defaulting to Debug
|
||||
$env:BUILD_TYPE = if ($env:BUILD_TYPE -in @("Debug", "Release")) { $env:BUILD_TYPE } else { "Debug" }
|
||||
|
||||
# Set variables
|
||||
$EXECTOS_SOURCE_DIR = (Get-Location).Path
|
||||
$EXECTOS_BINARY_DIR = "build-$($ARCH)-$($env:BUILD_TYPE.ToLower())"
|
||||
$EXECTOS_SOURCE_DIR = $PSScriptRoot
|
||||
$EXECTOS_BINARY_DIR = Join-Path $EXECTOS_SOURCE_DIR "build-$ARCH-$($env:BUILD_TYPE.ToLower())"
|
||||
|
||||
# Create directories if needed
|
||||
if ($EXECTOS_SOURCE_DIR -eq (Get-Location).Path) {
|
||||
Write-Host "Creating directories in $EXECTOS_BINARY_DIR"
|
||||
# Create build directory
|
||||
if (-not (Test-Path $EXECTOS_BINARY_DIR)) {
|
||||
Write-Host "Creating build directory: $EXECTOS_BINARY_DIR"
|
||||
New-Item -ItemType Directory -Path $EXECTOS_BINARY_DIR -Force | Out-Null
|
||||
Set-Location -Path $EXECTOS_BINARY_DIR
|
||||
}
|
||||
|
||||
Set-Location $EXECTOS_BINARY_DIR
|
||||
|
||||
# Delete old cache
|
||||
Remove-Item -Path "CMakeCache.txt" -ErrorAction SilentlyContinue
|
||||
Remove-Item -Path "host-tools/CMakeCache.txt" -ErrorAction SilentlyContinue
|
||||
Remove-Item "CMakeCache.txt", "host-tools/CMakeCache.txt" -ErrorAction SilentlyContinue
|
||||
|
||||
# Configure project using CMake
|
||||
& cmake -G Ninja -DARCH:STRING=$($ARCH) -DBUILD_TYPE:STRING=$($env:BUILD_TYPE) $EXECTOS_SOURCE_DIR
|
||||
& cmake -G Ninja "-DARCH:STRING=$ARCH" "-DBUILD_TYPE:STRING=$($env:BUILD_TYPE)" $EXECTOS_SOURCE_DIR
|
||||
|
||||
# Check if configuration succeeded
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
Write-Host "Configure script failed."
|
||||
Write-Error "Configure script failed."
|
||||
exit 1
|
||||
} else {
|
||||
"$($ARCH)" | Out-File -Encoding ASCII -NoNewline build.arch
|
||||
Write-Host "Configure script completed. Enter '$EXECTOS_BINARY_DIR' directory and execute 'xbuild' to build ExectOS."
|
||||
}
|
||||
|
||||
$ARCH | Out-File -Encoding ASCII -NoNewline "build.arch"
|
||||
Write-Host "Configure completed. Run 'xbuild' to build ExectOS."
|
||||
@@ -1,2 +1,3 @@
|
||||
# Set base addresses for all modules
|
||||
set(BASEADDRESS_XTLDR 0x000000000000F800)
|
||||
set(BASEADDRESS_XTOSKRNL 0x0000000140000000)
|
||||
|
||||
@@ -1,2 +1,3 @@
|
||||
# Set base addresses for all modules
|
||||
set(BASEADDRESS_XTLDR 0x0000F800)
|
||||
set(BASEADDRESS_XTOSKRNL 0x00400000)
|
||||
|
||||
@@ -64,11 +64,17 @@ function(compile_bootsector NAME SOURCE BASEADDR ENTRYPOINT)
|
||||
set(BINARY_NAME "${NAME}.bin")
|
||||
set(OBJECT_NAME "${NAME}.obj")
|
||||
|
||||
get_directory_property(DEFS COMPILE_DEFINITIONS)
|
||||
foreach(def ${DEFS})
|
||||
list(APPEND ASM_DEFS "-D${def}")
|
||||
endforeach()
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${BINARY_NAME}
|
||||
COMMAND ${CMAKE_ASM_COMPILER}
|
||||
/nologo
|
||||
--target=i386-none-elf
|
||||
${ASM_DEFS}
|
||||
-I${CMAKE_CURRENT_SOURCE_DIR}
|
||||
/Fo${CMAKE_CURRENT_BINARY_DIR}/${OBJECT_NAME}
|
||||
-c -- ${SOURCE}
|
||||
|
||||
@@ -108,9 +108,6 @@
|
||||
/* Static Kernel-Mode address start */
|
||||
#define KSEG0_BASE 0xFFFFF80000000000
|
||||
|
||||
/* XTOS Kernel address base */
|
||||
#define KSEG0_KERNEL_BASE 0x0000000800000000
|
||||
|
||||
/* XTOS Kernel stack size */
|
||||
#define KERNEL_STACK_SIZE 0x8000
|
||||
|
||||
@@ -272,11 +269,18 @@ typedef struct _KIDTENTRY
|
||||
{
|
||||
USHORT OffsetLow;
|
||||
USHORT Selector;
|
||||
USHORT IstIndex:3;
|
||||
USHORT Reserved0:5;
|
||||
USHORT Type:5;
|
||||
USHORT Dpl:2;
|
||||
USHORT Present:1;
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
USHORT IstIndex:3;
|
||||
USHORT Reserved0:5;
|
||||
USHORT Type:5;
|
||||
USHORT Dpl:2;
|
||||
USHORT Present:1;
|
||||
};
|
||||
USHORT Access;
|
||||
};
|
||||
USHORT OffsetMiddle;
|
||||
ULONG OffsetHigh;
|
||||
ULONG Reserved1;
|
||||
|
||||
@@ -25,11 +25,11 @@
|
||||
#define MM_PXE_BASE 0xFFFFF6FB7DBED000ULL
|
||||
|
||||
/* Page directory and page base addresses for 5-level paging */
|
||||
#define MM_PTE_LA57_BASE 0xFFFF000000000000ULL
|
||||
#define MM_PDE_LA57_BASE 0xFFFF010000000000ULL
|
||||
#define MM_PPE_LA57_BASE 0xFFFF010800000000ULL
|
||||
#define MM_PXE_LA57_BASE 0xFFFF010840000000ULL
|
||||
#define MM_P5E_LA57_BASE 0xFFFF010840200000ULL
|
||||
#define MM_PTE_LA57_BASE 0xFFED000000000000ULL
|
||||
#define MM_PDE_LA57_BASE 0xFFEDF68000000000ULL
|
||||
#define MM_PPE_LA57_BASE 0xFFEDF6FB40000000ULL
|
||||
#define MM_PXE_LA57_BASE 0xFFEDF6FB7DA00000ULL
|
||||
#define MM_P5E_LA57_BASE 0xFFEDF6FB7DBED000ULL
|
||||
|
||||
/* PTE shift values */
|
||||
#define MM_PTE_SHIFT 3
|
||||
@@ -39,15 +39,56 @@
|
||||
#define MM_PXI_SHIFT 39
|
||||
#define MM_P5I_SHIFT 48
|
||||
|
||||
/* Number of PTEs per page */
|
||||
#define MM_PTE_PER_PAGE 512
|
||||
#define MM_PDE_PER_PAGE 512
|
||||
#define MM_PPE_PER_PAGE 512
|
||||
#define MM_PXE_PER_PAGE 512
|
||||
/* PTE state flags */
|
||||
#define MM_PTE_VALID 0x0000000000000001ULL
|
||||
#define MM_PTE_ACCESSED 0x0000000000000020ULL
|
||||
#define MM_PTE_DIRTY 0x0000000000000040ULL
|
||||
|
||||
/* 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 */
|
||||
#define MM_MINIMUM_PHYSICAL_PAGES 2048
|
||||
|
||||
/* Number of system PTEs */
|
||||
#define MM_DEFAULT_NUMBER_SYSTEM_PTES 22000
|
||||
|
||||
/* Default number of secondary colors */
|
||||
#define MM_DEFAULT_SECONDARY_COLORS 64
|
||||
|
||||
@@ -63,9 +104,21 @@
|
||||
/* Maximum physical address used by HAL allocations */
|
||||
#define MM_MAXIMUM_PHYSICAL_ADDRESS 0x00000000FFFFFFFFULL
|
||||
|
||||
/* Highest system address */
|
||||
#define MM_HIGHEST_SYSTEM_ADDRESS 0xFFFFFFFFFFFFFFFFULL
|
||||
|
||||
/* Trampoline code address */
|
||||
#define MM_TRAMPOLINE_ADDRESS 0x80000
|
||||
|
||||
/* Pool block size */
|
||||
#define MM_POOL_BLOCK_SIZE 16
|
||||
|
||||
/* Number of pool lists per page */
|
||||
#define MM_POOL_LISTS_PER_PAGE (MM_PAGE_SIZE / MM_POOL_BLOCK_SIZE)
|
||||
|
||||
/* Number of pool tracking tables */
|
||||
#define MM_POOL_TRACKING_TABLES 64
|
||||
|
||||
/* Page size enumeration list */
|
||||
typedef enum _PAGE_SIZE
|
||||
{
|
||||
@@ -252,6 +305,7 @@ typedef struct _MMPFN
|
||||
USHORT ReferenceCount;
|
||||
} e2;
|
||||
} u3;
|
||||
ULONG UsedPageTableEntries;
|
||||
union
|
||||
{
|
||||
MMPTE OriginalPte;
|
||||
@@ -262,15 +316,32 @@ typedef struct _MMPFN
|
||||
ULONG_PTR EntireFrame;
|
||||
struct
|
||||
{
|
||||
ULONG_PTR PteFrame:58;
|
||||
ULONG_PTR PteFrame:57;
|
||||
ULONG_PTR InPageError:1;
|
||||
ULONG_PTR VerifierAllocation:1;
|
||||
ULONG_PTR AweAllocation:1;
|
||||
ULONG_PTR LockCharged:1;
|
||||
ULONG_PTR KernelStack:1;
|
||||
ULONG_PTR Priority:3;
|
||||
ULONG_PTR MustBeCached:1;
|
||||
};
|
||||
} u4;
|
||||
} MMPFN, *PMMPFN;
|
||||
|
||||
/* Pool descriptor structure definition */
|
||||
typedef struct _POOL_DESCRIPTOR
|
||||
{
|
||||
LIST_ENTRY ListHeads[MM_POOL_LISTS_PER_PAGE];
|
||||
PVOID LockAddress;
|
||||
ULONG PoolIndex;
|
||||
LONG PendingFreeDepth;
|
||||
PVOID PendingFrees;
|
||||
MMPOOL_TYPE PoolType;
|
||||
ULONG RunningFrees;
|
||||
ULONG RunningAllocations;
|
||||
ULONG Threshold;
|
||||
ULONG TotalPages;
|
||||
ULONG TotalBigAllocations;
|
||||
SIZE_T TotalBytes;
|
||||
SIZE_T Reserved;
|
||||
} POOL_DESCRIPTOR, *PPOOL_DESCRIPTOR;
|
||||
|
||||
#endif /* __XTDK_AMD64_MMTYPES_H */
|
||||
|
||||
@@ -61,6 +61,7 @@ typedef struct _MMPTE_PROTOTYPE MMPTE_PROTOTYPE, *PMMPTE_PROTOTYPE;
|
||||
typedef struct _MMPTE_SOFTWARE MMPTE_SOFTWARE, *PMMPTE_SOFTWARE;
|
||||
typedef struct _MMPTE_SUBSECTION MMPTE_SUBSECTION, *PMMPTE_SUBSECTION;
|
||||
typedef struct _MMPTE_TRANSITION MMPTE_TRANSITION, *PMMPTE_TRANSITION;
|
||||
typedef struct _POOL_DESCRIPTOR POOL_DESCRIPTOR, *PPOOL_DESCRIPTOR;
|
||||
typedef struct _THREAD_ENVIRONMENT_BLOCK THREAD_ENVIRONMENT_BLOCK, *PTHREAD_ENVIRONMENT_BLOCK;
|
||||
|
||||
/* Unions forward references */
|
||||
|
||||
@@ -51,6 +51,7 @@ typedef EFI_STATUS (XTCDECL *PBL_BOOTMENU_INITIALIZE_OS_LIST)(IN ULONG MaxNameLe
|
||||
typedef BOOLEAN (XTCDECL *PBL_BOOTUTILS_GET_BOOLEAN_PARAMETER)(IN PCWSTR Parameters, IN PCWSTR Needle);
|
||||
typedef VOID (XTAPI *PBL_BOOTUTILS_GET_TRAMPOLINE_INFORMATION)(IN TRAMPOLINE_TYPE TrampolineType, OUT PVOID *TrampolineCode, OUT PULONG_PTR TrampolineSize);
|
||||
typedef EFI_STATUS (XTCDECL *PBL_BUILD_PAGE_MAP)(IN PXTBL_PAGE_MAPPING PageMap, IN ULONG_PTR SelfMapAddress);
|
||||
typedef EFI_STATUS (XTCDECL *PBL_COMMIT_PAGE_MAP)(IN PXTBL_PAGE_MAPPING PageMap);
|
||||
typedef EFI_STATUS (XTCDECL *PBL_CLOSE_VOLUME)(IN PEFI_HANDLE VolumeHandle);
|
||||
typedef VOID (XTCDECL *PBL_CLEAR_CONSOLE_LINE)(IN ULONGLONG LineNo);
|
||||
typedef BOOLEAN (XTCDECL *PBL_CPU_CPUID)(IN OUT PCPUID_REGISTERS Registers);
|
||||
@@ -100,9 +101,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_TAIL)(IN OUT PLIST_ENTRY ListHead, 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 *MemoryMapAddress, IN PBL_GET_MEMTYPE_ROUTINE GetMemoryTypeRoutine);
|
||||
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 PVOID VirtualAddress, IN PVOID PhysicalAddress, IN ULONGLONG NumberOfPages, IN LOADER_MEMORY_TYPE MemoryType);
|
||||
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_PAGE)(IN PXTBL_PAGE_MAPPING PageMap, IN ULONGLONG VirtualAddress, IN ULONGLONG PhysicalAddress, IN ULONGLONG 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 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_PROTOCOL)(OUT PEFI_HANDLE Handle, OUT PVOID *ProtocolHandler, IN PEFI_GUID ProtocolGuid);
|
||||
@@ -232,8 +233,8 @@ typedef struct _XTBL_KNOWN_BOOT_PROTOCOL
|
||||
typedef struct _XTBL_MEMORY_MAPPING
|
||||
{
|
||||
LIST_ENTRY ListEntry;
|
||||
PVOID VirtualAddress;
|
||||
PVOID PhysicalAddress;
|
||||
ULONGLONG VirtualAddress;
|
||||
ULONGLONG PhysicalAddress;
|
||||
ULONGLONG NumberOfPages;
|
||||
LOADER_MEMORY_TYPE MemoryType;
|
||||
} XTBL_MEMORY_MAPPING, *PXTBL_MEMORY_MAPPING;
|
||||
@@ -449,6 +450,7 @@ typedef struct _XTBL_LOADER_PROTOCOL
|
||||
PBL_ALLOCATE_PAGES AllocatePages;
|
||||
PBL_ALLOCATE_POOL AllocatePool;
|
||||
PBL_BUILD_PAGE_MAP BuildPageMap;
|
||||
PBL_COMMIT_PAGE_MAP CommitPageMap;
|
||||
PBL_COMPARE_MEMORY CompareMemory;
|
||||
PBL_COPY_MEMORY CopyMemory;
|
||||
PBL_FREE_PAGES FreePages;
|
||||
|
||||
@@ -58,12 +58,6 @@
|
||||
#define KIDT_ACCESS_RING0 0x00
|
||||
#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 */
|
||||
#define KTSS_ESP0 0x04
|
||||
#define KTSS_CR3 0x1C
|
||||
@@ -134,9 +128,6 @@
|
||||
/* Static Kernel-Mode address start */
|
||||
#define KSEG0_BASE 0x80000000
|
||||
|
||||
/* XTOS Kernel address base */
|
||||
#define KSEG0_KERNEL_BASE 0x01800000
|
||||
|
||||
/* XTOS Kernel stack size */
|
||||
#define KERNEL_STACK_SIZE 0x4000
|
||||
|
||||
@@ -284,7 +275,18 @@ typedef struct _KIDTENTRY
|
||||
{
|
||||
USHORT Offset;
|
||||
USHORT Selector;
|
||||
USHORT Access;
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
UCHAR Reserved;
|
||||
UCHAR Type:4;
|
||||
UCHAR Flag:1;
|
||||
UCHAR Dpl:2;
|
||||
UCHAR Present:1;
|
||||
};
|
||||
USHORT Access;
|
||||
};
|
||||
USHORT ExtendedOffset;
|
||||
} KIDTENTRY, *PKIDTENTRY;
|
||||
|
||||
|
||||
@@ -35,9 +35,58 @@
|
||||
#define MM_PTE_LEGACY_SHIFT 2
|
||||
#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 */
|
||||
#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 */
|
||||
#define MM_DEFAULT_SECONDARY_COLORS 64
|
||||
|
||||
@@ -53,9 +102,21 @@
|
||||
/* Maximum physical address used by HAL allocations */
|
||||
#define MM_MAXIMUM_PHYSICAL_ADDRESS 0xFFFFFFFF
|
||||
|
||||
/* Highest system address */
|
||||
#define MM_HIGHEST_SYSTEM_ADDRESS 0xFFFFFFFF
|
||||
|
||||
/* Trampoline code address */
|
||||
#define MM_TRAMPOLINE_ADDRESS 0x80000
|
||||
|
||||
/* Pool block size */
|
||||
#define MM_POOL_BLOCK_SIZE 8
|
||||
|
||||
/* Number of pool lists per page */
|
||||
#define MM_POOL_LISTS_PER_PAGE (MM_PAGE_SIZE / MM_POOL_BLOCK_SIZE)
|
||||
|
||||
/* Number of pool tracking tables */
|
||||
#define MM_POOL_TRACKING_TABLES 32
|
||||
|
||||
/* Page size enumeration list */
|
||||
typedef enum _PAGE_SIZE
|
||||
{
|
||||
@@ -106,7 +167,6 @@ typedef struct _HARDWARE_MODERN_PTE
|
||||
/* Generic Page Table entry union to abstract PML2 and PML3 formats */
|
||||
typedef union _HARDWARE_PTE
|
||||
{
|
||||
ULONGLONG Long;
|
||||
HARDWARE_LEGACY_PTE Pml2;
|
||||
HARDWARE_MODERN_PTE Pml3;
|
||||
} HARDWARE_PTE, *PHARDWARE_PTE;
|
||||
@@ -201,12 +261,12 @@ typedef struct _MMPML2_PTE_TRANSITION
|
||||
typedef union _MMPML2_PTE
|
||||
{
|
||||
ULONG Long;
|
||||
HARDWARE_PTE Flush;
|
||||
MMPML2_PTE_HARDWARE Hard;
|
||||
MMPML2_PTE_PROTOTYPE Proto;
|
||||
MMPML2_PTE_SOFTWARE Soft;
|
||||
MMPML2_PTE_TRANSITION Trans;
|
||||
MMPML2_PTE_SUBSECTION Subsect;
|
||||
HARDWARE_LEGACY_PTE Flush;
|
||||
MMPML2_PTE_HARDWARE Hardware;
|
||||
MMPML2_PTE_PROTOTYPE Prototype;
|
||||
MMPML2_PTE_SOFTWARE Software;
|
||||
MMPML2_PTE_TRANSITION Transition;
|
||||
MMPML2_PTE_SUBSECTION Subsection;
|
||||
MMPML2_PTE_LIST List;
|
||||
} MMPML2_PTE, *PMMPML2_PTE;
|
||||
|
||||
@@ -296,7 +356,7 @@ typedef struct _MMPML3_PTE_TRANSITION
|
||||
typedef union _MMPML3_PTE
|
||||
{
|
||||
ULONGLONG Long;
|
||||
HARDWARE_PTE Flush;
|
||||
HARDWARE_MODERN_PTE Flush;
|
||||
MMPML3_PTE_HARDWARE Hardware;
|
||||
MMPML3_PTE_PROTOTYPE Prototype;
|
||||
MMPML3_PTE_SOFTWARE Software;
|
||||
@@ -308,7 +368,6 @@ typedef union _MMPML3_PTE
|
||||
/* Generic Page Table Entry union to abstract PML2 and PML3 formats */
|
||||
typedef union _MMPTE
|
||||
{
|
||||
ULONGLONG Long;
|
||||
MMPML2_PTE Pml2;
|
||||
MMPML3_PTE Pml3;
|
||||
} MMPTE, *PMMPTE;
|
||||
@@ -339,6 +398,7 @@ typedef struct _MMPFN
|
||||
USHORT ReferenceCount;
|
||||
} e2;
|
||||
} u3;
|
||||
ULONG UsedPageTableEntries;
|
||||
union
|
||||
{
|
||||
MMPTE OriginalPte;
|
||||
@@ -349,15 +409,32 @@ typedef struct _MMPFN
|
||||
ULONG_PTR EntireFrame;
|
||||
struct
|
||||
{
|
||||
ULONG_PTR PteFrame:26;
|
||||
ULONG_PTR PteFrame:25;
|
||||
ULONG_PTR InPageError:1;
|
||||
ULONG_PTR VerifierAllocation:1;
|
||||
ULONG_PTR AweAllocation:1;
|
||||
ULONG_PTR LockCharged:1;
|
||||
ULONG_PTR KernelStack:1;
|
||||
ULONG_PTR Priority:3;
|
||||
ULONG_PTR MustBeCached:1;
|
||||
};
|
||||
} u4;
|
||||
} MMPFN, *PMMPFN;
|
||||
|
||||
/* Pool descriptor structure definition */
|
||||
typedef struct _POOL_DESCRIPTOR
|
||||
{
|
||||
LIST_ENTRY ListHeads[MM_POOL_LISTS_PER_PAGE];
|
||||
PVOID LockAddress;
|
||||
ULONG PoolIndex;
|
||||
LONG PendingFreeDepth;
|
||||
PVOID PendingFrees;
|
||||
MMPOOL_TYPE PoolType;
|
||||
ULONG RunningFrees;
|
||||
ULONG RunningAllocations;
|
||||
ULONG Threshold;
|
||||
ULONG TotalPages;
|
||||
ULONG TotalBigAllocations;
|
||||
SIZE_T TotalBytes;
|
||||
SIZE_T Reserved;
|
||||
} POOL_DESCRIPTOR, *PPOOL_DESCRIPTOR;
|
||||
|
||||
#endif /* __XTDK_I686_MMTYPES_H */
|
||||
|
||||
@@ -70,6 +70,7 @@ typedef struct _MMPML3_PTE_PROTOTYPE MMPML3_PTE_PROTOTYPE, *PMMPML3_PTE_PROTOTYP
|
||||
typedef struct _MMPML3_PTE_SOFTWARE MMPML3_PTE_SOFTWARE, *PMMPML3_PTE_SOFTWARE;
|
||||
typedef struct _MMPML3_PTE_SUBSECTION MMPML3_PTE_SUBSECTION, *PMMPML3_PTE_SUBSECTION;
|
||||
typedef struct _MMPML3_PTE_TRANSITION MMPML3_PTE_TRANSITION, *PMMPML3_PTE_TRANSITION;
|
||||
typedef struct _POOL_DESCRIPTOR POOL_DESCRIPTOR, *PPOOL_DESCRIPTOR;
|
||||
typedef struct _THREAD_ENVIRONMENT_BLOCK THREAD_ENVIRONMENT_BLOCK, *PTHREAD_ENVIRONMENT_BLOCK;
|
||||
|
||||
/* Unions forward references */
|
||||
|
||||
@@ -150,21 +150,23 @@ typedef enum _KTHREAD_STATE
|
||||
typedef enum _KSPIN_LOCK_QUEUE_LEVEL
|
||||
{
|
||||
DispatcherLock,
|
||||
UnusedSpareLock,
|
||||
ExpansionLock,
|
||||
PfnLock,
|
||||
SystemSpaceLock,
|
||||
VacbLock,
|
||||
MasterLock,
|
||||
NonPagedPoolLock,
|
||||
NonPagedAllocPoolLock,
|
||||
IoCancelLock,
|
||||
WorkQueueLock,
|
||||
IoVpbLock,
|
||||
IoDatabaseLock,
|
||||
IoCompletionLock,
|
||||
FsStructLock,
|
||||
FileSystemLock,
|
||||
AfdWorkQueueLock,
|
||||
BcbLock,
|
||||
MmNonPagedPoolLock,
|
||||
NonPagedPoolLock,
|
||||
ReservedSystemLock,
|
||||
TimerTableLock,
|
||||
MaximumLock
|
||||
} KSPIN_LOCK_QUEUE_LEVEL, *PKSPIN_LOCK_QUEUE_LEVEL;
|
||||
|
||||
|
||||
40
sdk/xtdk/mmfuncs.h
Normal file
40
sdk/xtdk/mmfuncs.h
Normal file
@@ -0,0 +1,40 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: sdk/xtdk/mmfuncs.h
|
||||
* DESCRIPTION: XTOS memory manager routine definitions
|
||||
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef __XTDK_MMFUNCS_H
|
||||
#define __XTDK_MMFUNCS_H
|
||||
|
||||
#include <xtdefs.h>
|
||||
#include <xtstruct.h>
|
||||
#include <xttypes.h>
|
||||
|
||||
|
||||
/* Memory manager routines forward references */
|
||||
XTAPI
|
||||
XTSTATUS
|
||||
MmAllocatePool(IN MMPOOL_TYPE PoolType,
|
||||
IN SIZE_T Bytes,
|
||||
OUT PVOID *Memory);
|
||||
|
||||
XTAPI
|
||||
XTSTATUS
|
||||
MmAllocatePoolWithTag(IN MMPOOL_TYPE PoolType,
|
||||
IN SIZE_T Bytes,
|
||||
OUT PVOID *Memory,
|
||||
IN ULONG Tag);
|
||||
|
||||
XTAPI
|
||||
XTSTATUS
|
||||
MmFreePool(IN PVOID VirtualAddress);
|
||||
|
||||
XTAPI
|
||||
XTSTATUS
|
||||
MmFreePoolWithTag(IN PVOID VirtualAddress,
|
||||
IN ULONG Tag);
|
||||
|
||||
#endif /* __XTDK_MMFUNCS_H */
|
||||
@@ -4,6 +4,7 @@
|
||||
* FILE: sdk/xtdk/mmtypes.h
|
||||
* DESCRIPTION: Memory management data structures
|
||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||
* Aiken Harris <harraiken91@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef __XTDK_MMTYPES_H
|
||||
@@ -13,6 +14,95 @@
|
||||
#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
|
||||
|
||||
/* Bad pool caller reasons */
|
||||
#define MM_POOL_INVALID_ALLOC_RUNLEVEL 8
|
||||
#define MM_POOL_INVALID_FREE_RUNLEVEL 9
|
||||
|
||||
/* Pool flags */
|
||||
#define MM_POOL_BIG_ALLOCATIONS_ENTRY_FREE 0x1
|
||||
#define MM_POOL_PROTECTED 0x80000000
|
||||
#define MM_POOL_RAISE_EXCEPTION 0x10
|
||||
|
||||
/* Number of reserved zeroed PTEs */
|
||||
#define MM_RESERVED_ZERO_PTES 32
|
||||
|
||||
/* Memory Manager Protection Bits */
|
||||
#define MM_ZERO_ACCESS 0
|
||||
#define MM_READONLY 1
|
||||
#define MM_EXECUTE 2
|
||||
#define MM_EXECUTE_READ 3
|
||||
#define MM_READWRITE 4
|
||||
#define MM_WRITECOPY 5
|
||||
#define MM_EXECUTE_READWRITE 6
|
||||
#define MM_EXECUTE_WRITECOPY 7
|
||||
#define MM_PROTECT_ACCESS 7
|
||||
|
||||
/* Protection field shift */
|
||||
#define MM_PROTECT_FIELD_SHIFT 5
|
||||
|
||||
/* 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,
|
||||
NonPagedPoolCacheAlignedMustSucceed = 6,
|
||||
MaxPoolType = 7,
|
||||
NonPagedPoolSession = 32,
|
||||
PagedPoolSession = 33,
|
||||
NonPagedPoolMustSucceedSession = 34,
|
||||
NonPagedPoolCacheAlignedSession = 36,
|
||||
PagedPoolCacheAlignedSession = 37,
|
||||
NonPagedPoolCacheAlignedMustSucceedSession = 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 */
|
||||
typedef CONST STRUCT _CMMPAGEMAP_ROUTINES
|
||||
{
|
||||
@@ -30,6 +120,58 @@ typedef struct _MMCOLOR_TABLES
|
||||
ULONG_PTR Count;
|
||||
} MMCOLOR_TABLES, *PMMCOLOR_TABLES;
|
||||
|
||||
/* Free pool entry structure definition */
|
||||
typedef struct _MMFREE_POOL_ENTRY
|
||||
{
|
||||
LIST_ENTRY List;
|
||||
PFN_COUNT Size;
|
||||
PMMFREE_POOL_ENTRY Owner;
|
||||
} 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 */
|
||||
typedef struct _MMPFNENTRY
|
||||
{
|
||||
@@ -45,4 +187,75 @@ typedef struct _MMPFNENTRY
|
||||
USHORT ParityError:1;
|
||||
} MMPFNENTRY, *PMMPFNENTRY;
|
||||
|
||||
/* Page Frame List structure definition */
|
||||
typedef struct _MMPFNLIST
|
||||
{
|
||||
PFN_NUMBER Total;
|
||||
MMPAGELISTS ListName;
|
||||
PFN_NUMBER Flink;
|
||||
PFN_NUMBER Blink;
|
||||
} MMPFNLIST, *PMMPFNLIST;
|
||||
|
||||
/* Physical memory run structure definition */
|
||||
typedef struct _PHYSICAL_MEMORY_RUN
|
||||
{
|
||||
PFN_NUMBER BasePage;
|
||||
PFN_NUMBER PageCount;
|
||||
} PHYSICAL_MEMORY_RUN, *PPHYSICAL_MEMORY_RUN;
|
||||
|
||||
/* Physical memory descriptor structure definition */
|
||||
typedef struct _PHYSICAL_MEMORY_DESCRIPTOR
|
||||
{
|
||||
ULONG NumberOfRuns;
|
||||
PFN_NUMBER NumberOfPages;
|
||||
PHYSICAL_MEMORY_RUN Run[1];
|
||||
} PHYSICAL_MEMORY_DESCRIPTOR, *PPHYSICAL_MEMORY_DESCRIPTOR;
|
||||
|
||||
/* Pool header structure definition */
|
||||
typedef struct _POOL_HEADER
|
||||
{
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
USHORT PreviousSize:9;
|
||||
USHORT PoolIndex:7;
|
||||
USHORT BlockSize:9;
|
||||
USHORT PoolType:7;
|
||||
};
|
||||
ULONG Long;
|
||||
};
|
||||
union
|
||||
{
|
||||
ULONG PoolTag;
|
||||
PEPROCESS ProcessBilled;
|
||||
struct
|
||||
{
|
||||
USHORT AllocatorBackTraceIndex;
|
||||
USHORT PoolTagHash;
|
||||
};
|
||||
};
|
||||
} POOL_HEADER, *PPOOL_HEADER;
|
||||
|
||||
/* Pool descriptor structure definition */
|
||||
typedef struct _POOL_TRACKING_BIG_ALLOCATIONS
|
||||
{
|
||||
ULONG NumberOfPages;
|
||||
PVOID QuotaObject;
|
||||
ULONG Tag;
|
||||
PVOID VirtualAddress;
|
||||
} POOL_TRACKING_BIG_ALLOCATIONS, *PPOOL_TRACKING_BIG_ALLOCATIONS;
|
||||
|
||||
/* Pool tracking table structure definition */
|
||||
typedef struct _POOL_TRACKING_TABLE
|
||||
{
|
||||
LONG NonPagedAllocations;
|
||||
SIZE_T NonPagedBytes;
|
||||
LONG NonPagedFrees;
|
||||
LONG PagedAllocations;
|
||||
SIZE_T PagedBytes;
|
||||
LONG PagedFrees;
|
||||
ULONG Tag;
|
||||
} POOL_TRACKING_TABLE, *PPOOL_TRACKING_TABLE;
|
||||
|
||||
#endif /* __XTDK_MMTYPES_H */
|
||||
|
||||
@@ -49,6 +49,10 @@
|
||||
#define PFL_DIGIT_PRECISION 0x00002000
|
||||
#define PFL_THOUSANDS_GROUPING 0x00004000
|
||||
|
||||
/* Cryptographic related definitions */
|
||||
#define SHA1_BLOCK_SIZE 64
|
||||
#define SHA1_DIGEST_SIZE 20
|
||||
|
||||
/* Runtime Library routine callbacks */
|
||||
typedef XTSTATUS (*PWRITE_CHARACTER)(IN CHAR Character);
|
||||
typedef XTSTATUS (*PWRITE_WIDE_CHARACTER)(IN WCHAR Character);
|
||||
@@ -95,4 +99,12 @@ typedef struct _RTL_PRINT_FORMAT_PROPERTIES
|
||||
LONG Flags;
|
||||
} 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 */
|
||||
|
||||
@@ -29,6 +29,9 @@ typedef UCHAR KRUNLEVEL, *PKRUNLEVEL;
|
||||
/* Spin locks synchronization mechanism */
|
||||
typedef ULONG_PTR KSPIN_LOCK, *PKSPIN_LOCK;
|
||||
|
||||
/* Page Frame Number count */
|
||||
typedef ULONG PFN_COUNT;
|
||||
|
||||
/* Page Frame Number */
|
||||
typedef ULONG_PTR PFN_NUMBER, *PPFN_NUMBER;
|
||||
|
||||
|
||||
@@ -12,8 +12,9 @@
|
||||
|
||||
#ifdef __cplusplus
|
||||
/* C++ definitions */
|
||||
#define XTCLINK extern "C"
|
||||
#define NULLPTR nullptr
|
||||
#define VIRTUAL virtual
|
||||
#define XTCLINK extern "C"
|
||||
|
||||
/* C++ boolean type */
|
||||
typedef bool BOOLEAN, *PBOOLEAN;
|
||||
@@ -24,8 +25,9 @@
|
||||
typedef wchar_t wchar;
|
||||
#else
|
||||
/* C definitions */
|
||||
#define XTCLINK
|
||||
#define NULLPTR ((void *)0)
|
||||
#define VIRTUAL
|
||||
#define XTCLINK
|
||||
|
||||
/* C boolean type */
|
||||
typedef enum _BOOLEAN
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
#define DebugPrint(Format, ...) DbgPrint(Format, __VA_ARGS__);
|
||||
#else
|
||||
#define DEBUG 0
|
||||
#define DebugPrint(Format, ...) ((VOID)NULL)
|
||||
#define DebugPrint(Format, ...) ((VOID)NULLPTR)
|
||||
#endif
|
||||
|
||||
#endif /* __XTDK_XTDEBUG_H */
|
||||
|
||||
@@ -74,12 +74,20 @@
|
||||
/* Macro for calculating size of a field in the structure */
|
||||
#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 */
|
||||
#define PAGE_ALIGN(VirtualAddress) ((PVOID)((ULONG_PTR)VirtualAddress & ~MM_PAGE_MASK))
|
||||
|
||||
/* Macro that returns offset of the virtual address */
|
||||
#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 */
|
||||
#define ROUND_DOWN(Value, Alignment) ((Value) & ~((Alignment) - 1))
|
||||
|
||||
@@ -104,7 +112,7 @@
|
||||
|
||||
/* Variadic ABI functions */
|
||||
typedef __builtin_va_list VA_LIST, *PVA_LIST;
|
||||
#define VA_ARG(Marker, Type) ((sizeof (Type) < sizeof(UINT_PTR)) ? \
|
||||
#define VA_ARG(Marker, Type) ((sizeof(Type) < sizeof(UINT_PTR)) ? \
|
||||
(Type)(__builtin_va_arg(Marker, UINT_PTR)) : \
|
||||
(Type)(__builtin_va_arg(Marker, Type)))
|
||||
#define VA_COPY(Dest, Start) __builtin_va_copy(Dest, Start)
|
||||
|
||||
@@ -107,6 +107,7 @@ typedef struct _KERNEL_INITIALIZATION_BLOCK
|
||||
ULONG BlockVersion;
|
||||
ULONG ProtocolVersion;
|
||||
PWCHAR KernelParameters;
|
||||
PFN_NUMBER BootImageSize;
|
||||
LIST_ENTRY LoadOrderListHead;
|
||||
LIST_ENTRY MemoryDescriptorListHead;
|
||||
LIST_ENTRY BootDriverListHead;
|
||||
|
||||
@@ -50,6 +50,7 @@
|
||||
#include <hlfuncs.h>
|
||||
#include <kdfuncs.h>
|
||||
#include <kefuncs.h>
|
||||
#include <mmfuncs.h>
|
||||
#include <rtlfuncs.h>
|
||||
|
||||
/* Architecture specific XT routines */
|
||||
|
||||
@@ -48,6 +48,10 @@ typedef enum _KTHREAD_STATE KTHREAD_STATE, *PKTHREAD_STATE;
|
||||
typedef enum _KTIMER_TYPE KTIMER_TYPE, *PKTIMER_TYPE;
|
||||
typedef enum _KUBSAN_DATA_TYPE KUBSAN_DATA_TYPE, *PKUBSAN_DATA_TYPE;
|
||||
typedef enum _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 _RTL_VARIABLE_TYPE RTL_VARIABLE_TYPE, *PRTL_VARIABLE_TYPE;
|
||||
typedef enum _SYSTEM_FIRMWARE_TYPE SYSTEM_FIRMWARE_TYPE, *PSYSTEM_FIRMWARE_TYPE;
|
||||
@@ -274,7 +278,10 @@ typedef struct _LOADER_INFORMATION_BLOCK LOADER_INFORMATION_BLOCK, *PLOADER_INFO
|
||||
typedef struct _LOADER_MEMORY_DESCRIPTOR LOADER_MEMORY_DESCRIPTOR, *PLOADER_MEMORY_DESCRIPTOR;
|
||||
typedef struct _M128 M128, *PM128;
|
||||
typedef struct _MMCOLOR_TABLES MMCOLOR_TABLES, *PMMCOLOR_TABLES;
|
||||
typedef struct _MMFREE_POOL_ENTRY MMFREE_POOL_ENTRY, *PMMFREE_POOL_ENTRY;
|
||||
typedef struct _MMMEMORY_LAYOUT MMMEMORY_LAYOUT, *PMMMEMORY_LAYOUT;
|
||||
typedef struct _MMPFNENTRY MMPFNENTRY, *PMMPFNENTRY;
|
||||
typedef struct _MMPFNLIST MMPFNLIST, *PMMPFNLIST;
|
||||
typedef struct _PCAT_FIRMWARE_INFORMATION PCAT_FIRMWARE_INFORMATION, *PPCAT_FIRMWARE_INFORMATION;
|
||||
typedef struct _PCI_BRIDGE_CONTROL_REGISTER PCI_BRIDGE_CONTROL_REGISTER, *PPCI_BRIDGE_CONTROL_REGISTER;
|
||||
typedef struct _PCI_COMMON_CONFIG PCI_COMMON_CONFIG, *PPCI_COMMON_CONFIG;
|
||||
@@ -303,6 +310,11 @@ typedef struct _PECOFF_IMAGE_ROM_HEADER PECOFF_IMAGE_ROM_HEADER, *PPECOFF_IMAGE_
|
||||
typedef struct _PECOFF_IMAGE_ROM_OPTIONAL_HEADER PECOFF_IMAGE_ROM_OPTIONAL_HEADER, *PPECOFF_IMAGE_ROM_OPTIONAL_HEADER;
|
||||
typedef struct _PECOFF_IMAGE_SECTION_HEADER PECOFF_IMAGE_SECTION_HEADER, *PPECOFF_IMAGE_SECTION_HEADER;
|
||||
typedef struct _PECOFF_IMAGE_VXD_HEADER PECOFF_IMAGE_VXD_HEADER, *PPECOFF_IMAGE_VXD_HEADER;
|
||||
typedef struct _PHYSICAL_MEMORY_DESCRIPTOR PHYSICAL_MEMORY_DESCRIPTOR, *PPHYSICAL_MEMORY_DESCRIPTOR;
|
||||
typedef struct _PHYSICAL_MEMORY_RUN PHYSICAL_MEMORY_RUN, *PPHYSICAL_MEMORY_RUN;
|
||||
typedef struct _POOL_HEADER POOL_HEADER, *PPOOL_HEADER;
|
||||
typedef struct _POOL_TRACKING_BIG_ALLOCATIONS POOL_TRACKING_BIG_ALLOCATIONS, *PPOOL_TRACKING_BIG_ALLOCATIONS;
|
||||
typedef struct _POOL_TRACKING_TABLE POOL_TRACKING_TABLE, *PPOOL_TRACKING_TABLE;
|
||||
typedef struct _PROCESSOR_IDENTITY PROCESSOR_IDENTITY, *PPROCESSOR_IDENTITY;
|
||||
typedef struct _PROCESSOR_POWER_STATE PROCESSOR_POWER_STATE, *PPROCESSOR_POWER_STATE;
|
||||
typedef struct _RTL_BITMAP RTL_BITMAP, *PRTL_BITMAP;
|
||||
|
||||
@@ -51,14 +51,24 @@ list(APPEND XTOSKRNL_SOURCE
|
||||
${XTOSKRNL_SOURCE_DIR}/ke/spinlock.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/ke/sysres.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/ke/timer.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}/paging.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/mm/${ARCH}/pfault.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/mm/${ARCH}/pfn.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/mm/${ARCH}/pool.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/exports.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/mm/hlpool.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/mm/init.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/mm/kpool.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/mm/mmgr.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/mm/paging.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/mm/pfn.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/mm/pool.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/mm/pte.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/po/idle.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/rtl/${ARCH}/dispatch.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/rtl/${ARCH}/exsup.cc
|
||||
@@ -71,6 +81,8 @@ list(APPEND XTOSKRNL_SOURCE
|
||||
${XTOSKRNL_SOURCE_DIR}/rtl/llist.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/rtl/math.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/widestr.cc)
|
||||
|
||||
@@ -82,11 +94,12 @@ add_library(libxtos ${XTOSKRNL_SOURCE})
|
||||
|
||||
# Link kernel executable
|
||||
add_executable(xtoskrnl
|
||||
${XTOSKRNL_SOURCE}
|
||||
${CMAKE_CURRENT_BINARY_DIR}/xtoskrnl.def)
|
||||
|
||||
# Add linker libraries
|
||||
target_link_libraries(xtoskrnl)
|
||||
target_link_libraries(xtoskrnl
|
||||
PRIVATE
|
||||
libxtos)
|
||||
|
||||
# Set proper binary name and install target
|
||||
set_target_properties(xtoskrnl PROPERTIES SUFFIX .exe)
|
||||
|
||||
@@ -4,6 +4,18 @@ 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
|
||||
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
|
||||
corresponding C++ namespace in which the subsystem's classes and routines reside. These subsystems include:
|
||||
|
||||
@@ -68,8 +80,8 @@ routine:
|
||||
For all C++ code inside the kernel the naming model has evolved. Consider the **KE::KThread::InitializeThread()**
|
||||
routine:
|
||||
* **KE** - The namespace replaces the prefix and indicates the subsystem. Namespaces are written in uppercase and no
|
||||
longer use the trailing p for private routines, because classes use C++ visibility to control access.
|
||||
longer use the trailing p for private routines, because classes use C++ visibility to control access.
|
||||
* **KThread** - Within each namespace, related functionality is grouped into classes, which encapsulate variables and
|
||||
methods.
|
||||
methods.
|
||||
* **InitializeThread** - Method names follow the `<Operation><Object>` pattern.
|
||||
|
||||
@@ -104,12 +104,20 @@ ArTrap\Vector:
|
||||
/* Test previous mode and swap GS if needed */
|
||||
movl $0, TrapPreviousMode(%rbp)
|
||||
mov %cs, %ax
|
||||
and $1, %al
|
||||
and $3, %al
|
||||
mov %al, TrapPreviousMode(%rbp)
|
||||
jz KernelMode$\Vector
|
||||
swapgs
|
||||
jmp UserMode$\Vector
|
||||
|
||||
KernelMode$\Vector:
|
||||
/* Save kernel stack pointer (SS:RSP) */
|
||||
movl %ss, %eax
|
||||
mov %eax, TrapSegSs(%rbp)
|
||||
lea TRAP_FRAME_SIZE(%rbp), %rax
|
||||
mov %rax, TrapRsp(%rbp)
|
||||
|
||||
UserMode$\Vector:
|
||||
/* Push Frame Pointer, clear direction flag and pass to trap dispatcher */
|
||||
mov %rsp, %rcx
|
||||
cld
|
||||
|
||||
@@ -249,34 +249,34 @@ AR::ProcSup::InitializeIdt(IN PKPROCESSOR_BLOCK ProcessorBlock)
|
||||
for(Vector = 0; Vector < IDT_ENTRIES; Vector++)
|
||||
{
|
||||
/* Set the IDT to handle unexpected interrupts */
|
||||
SetIdtGate(ProcessorBlock->IdtBase, Vector, (PVOID)ArTrap0xFF, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, Vector, (PVOID)ArTrap0xFF, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_INTERRUPT_GATE);
|
||||
}
|
||||
|
||||
/* Setup IDT handlers for known interrupts and traps */
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x00, (PVOID)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);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x00, (PVOID)ArTrap0x00, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x01, (PVOID)ArTrap0x01, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x02, (PVOID)ArTrap0x02, KGDT_R0_CODE, KIDT_IST_PANIC, KIDT_ACCESS_RING0, AMD64_INTERRUPT_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x03, (PVOID)ArTrap0x03, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3, AMD64_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x04, (PVOID)ArTrap0x04, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3, AMD64_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x05, (PVOID)ArTrap0x05, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x06, (PVOID)ArTrap0x06, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x07, (PVOID)ArTrap0x07, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x08, (PVOID)ArTrap0x08, KGDT_R0_CODE, KIDT_IST_PANIC, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x09, (PVOID)ArTrap0x09, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x0A, (PVOID)ArTrap0x0A, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x0B, (PVOID)ArTrap0x0B, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x0C, (PVOID)ArTrap0x0C, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x0D, (PVOID)ArTrap0x0D, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x0E, (PVOID)ArTrap0x0E, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x10, (PVOID)ArTrap0x10, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x11, (PVOID)ArTrap0x11, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x12, (PVOID)ArTrap0x12, KGDT_R0_CODE, KIDT_IST_MCA, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x13, (PVOID)ArTrap0x13, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x1F, (PVOID)ArTrap0x1F, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_INTERRUPT_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x2C, (PVOID)ArTrap0x2C, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3, AMD64_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x2D, (PVOID)ArTrap0x2D, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3, AMD64_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x2F, (PVOID)ArTrap0x2F, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_INTERRUPT_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0xE1, (PVOID)ArTrap0xE1, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_INTERRUPT_GATE);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -636,6 +636,9 @@ AR::ProcSup::SetGdtEntryBase(IN PKGDTENTRY Gdt,
|
||||
* @param Access
|
||||
* Supplies the gate access rights.
|
||||
*
|
||||
* @param Type
|
||||
* Supplies the gate type.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
@@ -647,15 +650,22 @@ AR::ProcSup::SetIdtGate(IN PKIDTENTRY Idt,
|
||||
IN PVOID Handler,
|
||||
IN USHORT Selector,
|
||||
IN USHORT Ist,
|
||||
IN USHORT Access)
|
||||
IN USHORT Dpl,
|
||||
IN USHORT Type)
|
||||
{
|
||||
/* Setup the gate */
|
||||
/* Set the handler's address */
|
||||
Idt[Vector].OffsetLow = ((ULONG_PTR)Handler & 0xFFFF);
|
||||
Idt[Vector].OffsetMiddle = (((ULONG_PTR)Handler >> 16) & 0xFFFF);
|
||||
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].Present = 1;
|
||||
Idt[Vector].Selector = Selector;
|
||||
Idt[Vector].Type = 0xE;
|
||||
Idt[Vector].Reserved1 = 0;
|
||||
Idt[Vector].Type = Type;
|
||||
}
|
||||
|
||||
@@ -75,12 +75,20 @@ _ArTrap\Vector:
|
||||
/* Test previous mode and swap GS if needed */
|
||||
movl $0, TrapPreviousMode(%ebp)
|
||||
mov %cs, %ax
|
||||
and $1, %al
|
||||
and $3, %al
|
||||
mov %al, TrapPreviousMode(%ebp)
|
||||
jz KernelMode$\Vector
|
||||
swapgs
|
||||
jmp UserMode$\Vector
|
||||
|
||||
KernelMode$\Vector:
|
||||
/* Save kernel stack pointer (SS:ESP) as CPU did not push them */
|
||||
movl %ss, %eax
|
||||
mov %eax, TrapSegSs(%ebp)
|
||||
lea TrapEsp(%ebp), %eax
|
||||
mov %eax, TrapEsp(%ebp)
|
||||
|
||||
UserMode$\Vector:
|
||||
/* Push Frame Pointer, clear direction flag and pass to trap dispatcher */
|
||||
push %esp
|
||||
cld
|
||||
@@ -100,6 +108,7 @@ KernelModeReturn$\Vector:
|
||||
mov TrapSegDs(%ebp), %ds
|
||||
mov TrapSegEs(%ebp), %es
|
||||
mov TrapSegFs(%ebp), %fs
|
||||
mov TrapSegGs(%ebp), %gs
|
||||
|
||||
/* Free stack space */
|
||||
add $(TRAP_FRAME_SIZE - TRAP_REGISTERS_SIZE), %esp
|
||||
|
||||
@@ -242,34 +242,34 @@ AR::ProcSup::InitializeIdt(IN PKPROCESSOR_BLOCK ProcessorBlock)
|
||||
for(Vector = 0; Vector < IDT_ENTRIES; Vector++)
|
||||
{
|
||||
/* Set the IDT to handle unexpected interrupts */
|
||||
SetIdtGate(ProcessorBlock->IdtBase, Vector, (PVOID)ArTrap0xFF, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, Vector, (PVOID)ArTrap0xFF, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_INTERRUPT_GATE);
|
||||
}
|
||||
|
||||
/* Setup IDT handlers for known interrupts and traps */
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x00, (PVOID)ArTrap0x00, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
|
||||
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_INTERRUPT | KIDT_ACCESS_RING0);
|
||||
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_INTERRUPT | KIDT_ACCESS_RING3);
|
||||
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_INTERRUPT | KIDT_ACCESS_RING0);
|
||||
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_INTERRUPT | KIDT_ACCESS_RING0);
|
||||
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_INTERRUPT | KIDT_ACCESS_RING0);
|
||||
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_INTERRUPT | KIDT_ACCESS_RING0);
|
||||
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_INTERRUPT | KIDT_ACCESS_RING0);
|
||||
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_INTERRUPT | KIDT_ACCESS_RING0);
|
||||
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_INTERRUPT | KIDT_ACCESS_RING0);
|
||||
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_INTERRUPT | KIDT_ACCESS_RING3);
|
||||
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_INTERRUPT | KIDT_ACCESS_RING3);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x2E, (PVOID)ArTrap0x2E, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING3);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x00, (PVOID)ArTrap0x00, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x01, (PVOID)ArTrap0x01, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x02, (PVOID)ArTrap0x02, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_INTERRUPT_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x03, (PVOID)ArTrap0x03, KGDT_R0_CODE, 0, KIDT_ACCESS_RING3, I686_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x04, (PVOID)ArTrap0x04, KGDT_R0_CODE, 0, KIDT_ACCESS_RING3, I686_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x05, (PVOID)ArTrap0x05, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x06, (PVOID)ArTrap0x06, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x07, (PVOID)ArTrap0x07, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x08, (PVOID)ArTrap0x08, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x09, (PVOID)ArTrap0x09, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x0A, (PVOID)ArTrap0x0A, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x0B, (PVOID)ArTrap0x0B, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x0C, (PVOID)ArTrap0x0C, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x0D, (PVOID)ArTrap0x0D, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x0E, (PVOID)ArTrap0x0E, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x10, (PVOID)ArTrap0x10, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x11, (PVOID)ArTrap0x11, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x12, (PVOID)ArTrap0x12, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x13, (PVOID)ArTrap0x13, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x2A, (PVOID)ArTrap0x2A, KGDT_R0_CODE, 0, KIDT_ACCESS_RING3, I686_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x2B, (PVOID)ArTrap0x2B, KGDT_R0_CODE, 0, KIDT_ACCESS_RING3, I686_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x2C, (PVOID)ArTrap0x2C, KGDT_R0_CODE, 0, KIDT_ACCESS_RING3, I686_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x2D, (PVOID)ArTrap0x2D, KGDT_R0_CODE, 0, KIDT_ACCESS_RING3, I686_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x2E, (PVOID)ArTrap0x2E, KGDT_R0_CODE, 0, KIDT_ACCESS_RING3, I686_TRAP_GATE);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -656,6 +656,9 @@ AR::ProcSup::SetGdtEntryBase(IN PKGDTENTRY Gdt,
|
||||
* @param Access
|
||||
* Supplies the gate access rights.
|
||||
*
|
||||
* @param Type
|
||||
* Supplies the gate type.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
@@ -667,13 +670,21 @@ AR::ProcSup::SetIdtGate(IN PKIDTENTRY Idt,
|
||||
IN PVOID Handler,
|
||||
IN USHORT Selector,
|
||||
IN USHORT Ist,
|
||||
IN USHORT Access)
|
||||
IN USHORT Dpl,
|
||||
IN USHORT Type)
|
||||
{
|
||||
/* Setup the gate */
|
||||
/* Set the handler's address */
|
||||
Idt[Vector].Offset = (USHORT)((ULONG)Handler & 0xFFFF);
|
||||
Idt[Vector].ExtendedOffset = (USHORT)((ULONG)Handler >> 16);
|
||||
Idt[Vector].Access = 0x8000 | (Access << 8);
|
||||
|
||||
/* 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].Present = 1;
|
||||
Idt[Vector].Type = Type;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -9,6 +9,41 @@
|
||||
#include <xtos.hh>
|
||||
|
||||
|
||||
/**
|
||||
* Checks whether the APIC is supported by the processor.
|
||||
*
|
||||
* @return This routine returns TRUE if APIC is supported, or FALSE otherwise.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
BOOLEAN
|
||||
HL::Pic::CheckApicSupport(VOID)
|
||||
{
|
||||
CPUID_REGISTERS CpuRegisters;
|
||||
|
||||
/* Prepare CPUID registers */
|
||||
CpuRegisters.Leaf = CPUID_GET_STANDARD1_FEATURES;
|
||||
CpuRegisters.SubLeaf = 0;
|
||||
CpuRegisters.Eax = 0;
|
||||
CpuRegisters.Ebx = 0;
|
||||
CpuRegisters.Ecx = 0;
|
||||
CpuRegisters.Edx = 0;
|
||||
|
||||
/* Get CPUID */
|
||||
AR::CpuFunc::CpuId(&CpuRegisters);
|
||||
|
||||
/* Check APIC status from the CPUID results */
|
||||
if(!(CpuRegisters.Edx & CPUID_FEATURES_EDX_APIC))
|
||||
{
|
||||
/* APIC is not supported */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* APIC is supported */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the x2APIC extension is supported by the processor.
|
||||
*
|
||||
@@ -124,6 +159,14 @@ HL::Pic::InitializeApic(VOID)
|
||||
APIC_LVT_REGISTER LvtRegister;
|
||||
ULONG CpuNumber;
|
||||
|
||||
/* Check APIC support */
|
||||
if(!CheckApicSupport())
|
||||
{
|
||||
/* APIC is not supported, raise kernel panic */
|
||||
DebugPrint(L"FATAL ERROR: Local APIC not present.\n");
|
||||
KE::Crash::Panic(0x5D, CPUID_GET_STANDARD1_FEATURES, 0x0, 0x0, CPUID_FEATURES_EDX_APIC);
|
||||
}
|
||||
|
||||
/* Determine APIC mode (xAPIC compatibility or x2APIC) */
|
||||
if(CheckX2ApicSupport())
|
||||
{
|
||||
|
||||
@@ -56,6 +56,8 @@
|
||||
#define TrapSegEs 330
|
||||
#define TrapSegFs 332
|
||||
#define TrapSegGs 334
|
||||
#define TrapRsp 496
|
||||
#define TrapSegSs 504
|
||||
|
||||
/* KTRAP_FRAME length related definitions */
|
||||
#define TRAP_FRAME_SIZE 512
|
||||
|
||||
@@ -31,6 +31,13 @@ namespace AR
|
||||
OUT PVOID *TrampolineCode,
|
||||
OUT PULONG_PTR TrampolineSize);
|
||||
STATIC XTAPI VOID InitializeProcessor(IN PVOID ProcessorStructures);
|
||||
STATIC XTAPI VOID SetIdtGate(IN PKIDTENTRY Idt,
|
||||
IN USHORT Vector,
|
||||
IN PVOID Handler,
|
||||
IN USHORT Selector,
|
||||
IN USHORT Ist,
|
||||
IN USHORT Dpl,
|
||||
IN USHORT Type);
|
||||
|
||||
private:
|
||||
STATIC XTAPI VOID IdentifyProcessor(VOID);
|
||||
@@ -62,12 +69,6 @@ namespace AR
|
||||
STATIC XTAPI VOID SetGdtEntryBase(IN PKGDTENTRY Gdt,
|
||||
IN USHORT Selector,
|
||||
IN ULONG_PTR Base);
|
||||
STATIC XTAPI VOID SetIdtGate(IN PKIDTENTRY Idt,
|
||||
IN USHORT Vector,
|
||||
IN PVOID Handler,
|
||||
IN USHORT Selector,
|
||||
IN USHORT Ist,
|
||||
IN USHORT Access);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -24,9 +24,11 @@
|
||||
#define TrapSegEs 38
|
||||
#define TrapSegFs 40
|
||||
#define TrapSegGs 42
|
||||
#define TrapEsp 92
|
||||
#define TrapSegSs 96
|
||||
|
||||
/* KTRAP_FRAME length related definitions */
|
||||
#define TRAP_FRAME_SIZE 100
|
||||
#define TRAP_REGISTERS_SIZE 56
|
||||
|
||||
#endif /* __XTOSKRNL_AMD64_ASMSUP_H */
|
||||
#endif /* __XTOSKRNL_I686_ASMSUP_H */
|
||||
|
||||
@@ -34,6 +34,13 @@ namespace AR
|
||||
OUT PVOID *TrampolineCode,
|
||||
OUT PULONG_PTR TrampolineSize);
|
||||
STATIC XTAPI VOID InitializeProcessor(IN PVOID ProcessorStructures);
|
||||
STATIC XTAPI VOID SetIdtGate(IN PKIDTENTRY Idt,
|
||||
IN USHORT Vector,
|
||||
IN PVOID Handler,
|
||||
IN USHORT Selector,
|
||||
IN USHORT Ist,
|
||||
IN USHORT Dpl,
|
||||
IN USHORT Type);
|
||||
|
||||
private:
|
||||
STATIC XTAPI VOID IdentifyProcessor(VOID);
|
||||
@@ -67,12 +74,6 @@ namespace AR
|
||||
STATIC XTAPI VOID SetGdtEntryBase(IN PKGDTENTRY Gdt,
|
||||
IN USHORT Selector,
|
||||
IN ULONG_PTR Base);
|
||||
STATIC XTAPI VOID SetIdtGate(IN PKIDTENTRY Idt,
|
||||
IN USHORT Vector,
|
||||
IN PVOID Handler,
|
||||
IN USHORT Selector,
|
||||
IN USHORT Ist,
|
||||
IN USHORT Access);
|
||||
STATIC XTAPI VOID SetNonMaskableInterruptTssEntry(IN PKPROCESSOR_BLOCK ProcessorBlock,
|
||||
IN PVOID KernelFaultStack);
|
||||
|
||||
|
||||
@@ -32,6 +32,7 @@ namespace HL
|
||||
IN ULONGLONG Value);
|
||||
|
||||
private:
|
||||
STATIC XTAPI BOOLEAN CheckApicSupport(VOID);
|
||||
STATIC XTAPI BOOLEAN CheckX2ApicSupport(VOID);
|
||||
STATIC XTCDECL VOID HandleApicSpuriousService(VOID);
|
||||
STATIC XTCDECL VOID HandlePicSpuriousService(VOID);
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include <ke/crash.hh>
|
||||
#include <ke/dpc.hh>
|
||||
#include <ke/event.hh>
|
||||
#include <ke/guard.hh>
|
||||
#include <ke/irq.hh>
|
||||
#include <ke/kprocess.hh>
|
||||
#include <ke/krnlinit.hh>
|
||||
|
||||
@@ -20,11 +20,11 @@ namespace KE
|
||||
public:
|
||||
STATIC XTAPI VOID HaltSystem(VOID);
|
||||
STATIC XTAPI VOID Panic(IN ULONG Code);
|
||||
STATIC XTAPI VOID PanicEx(IN ULONG Code,
|
||||
IN ULONG_PTR Parameter1,
|
||||
IN ULONG_PTR Parameter2,
|
||||
IN ULONG_PTR Parameter3,
|
||||
IN ULONG_PTR Parameter4);
|
||||
STATIC XTAPI VOID Panic(IN ULONG Code,
|
||||
IN ULONG_PTR Parameter1,
|
||||
IN ULONG_PTR Parameter2,
|
||||
IN ULONG_PTR Parameter3,
|
||||
IN ULONG_PTR Parameter4);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
61
xtoskrnl/includes/ke/guard.hh
Normal file
61
xtoskrnl/includes/ke/guard.hh
Normal file
@@ -0,0 +1,61 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: xtoskrnl/includes/ke/guard.hh
|
||||
* DESCRIPTION: Kernel synchronization guard
|
||||
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef __XTOSKRNL_KE_GUARD_HH
|
||||
#define __XTOSKRNL_KE_GUARD_HH
|
||||
|
||||
#include <xtos.hh>
|
||||
#include <ke/spinlock.hh>
|
||||
|
||||
/* Kernel Library */
|
||||
namespace KE
|
||||
{
|
||||
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 Lock;
|
||||
|
||||
public:
|
||||
SpinLockGuard(IN OUT PKSPIN_LOCK SpinLock)
|
||||
{
|
||||
Lock = SpinLock;
|
||||
KE::SpinLock::AcquireSpinLock(Lock);
|
||||
}
|
||||
|
||||
~SpinLockGuard()
|
||||
{
|
||||
KE::SpinLock::ReleaseSpinLock(Lock);
|
||||
}
|
||||
|
||||
SpinLockGuard(const SpinLockGuard&) = delete;
|
||||
SpinLockGuard& operator=(const SpinLockGuard&) = delete;
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* __XTOSKRNL_KE_GUARD_HH */
|
||||
@@ -22,6 +22,48 @@ namespace KE
|
||||
STATIC XTFASTCALL VOID LowerRunLevel(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 */
|
||||
|
||||
@@ -17,12 +17,32 @@ namespace KE
|
||||
{
|
||||
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:
|
||||
STATIC XTFASTCALL VOID AcquireQueuedSpinLock(IN KSPIN_LOCK_QUEUE_LEVEL LockLevel);
|
||||
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 XTFASTCALL VOID ReleaseQueuedSpinLock(IN KSPIN_LOCK_QUEUE_LEVEL LockLevel);
|
||||
STATIC XTFASTCALL VOID ReleaseSpinLock(IN OUT PKSPIN_LOCK SpinLock);
|
||||
STATIC XTFASTCALL BOOLEAN TestSpinLock(IN PKSPIN_LOCK SpinLock);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -12,10 +12,17 @@
|
||||
#include <xtos.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/guard.hh>
|
||||
#include <mm/hlpool.hh>
|
||||
#include <mm/init.hh>
|
||||
#include <mm/kpool.hh>
|
||||
#include <mm/paging.hh>
|
||||
#include <mm/mmgr.hh>
|
||||
#include <mm/pfault.hh>
|
||||
#include <mm/pfn.hh>
|
||||
#include <mm/pool.hh>
|
||||
|
||||
#endif /* __XTOSKRNL_MM_HH */
|
||||
|
||||
90
xtoskrnl/includes/mm/alloc.hh
Normal file
90
xtoskrnl/includes/mm/alloc.hh
Normal file
@@ -0,0 +1,90 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: xtoskrnl/includes/mm/alloc.hh
|
||||
* DESCRIPTION: Memory Manager pool allocator
|
||||
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef __XTOSKRNL_MM_ALLOC_HH
|
||||
#define __XTOSKRNL_MM_ALLOC_HH
|
||||
|
||||
#include <xtos.hh>
|
||||
#include <mm/pool.hh>
|
||||
|
||||
|
||||
/* Memory Manager */
|
||||
namespace MM
|
||||
{
|
||||
class Allocator final : private Pool
|
||||
{
|
||||
private:
|
||||
STATIC PPOOL_TRACKING_TABLE AllocationsTrackingExpansionTable;
|
||||
STATIC SIZE_T AllocationsTrackingExpansionTableSize;
|
||||
STATIC PPOOL_TRACKING_TABLE AllocationsTrackingTable;
|
||||
STATIC KSPIN_LOCK AllocationsTrackingTableLock;
|
||||
STATIC SIZE_T AllocationsTrackingTableMask;
|
||||
STATIC SIZE_T AllocationsTrackingTableSize;
|
||||
STATIC ULONG BigAllocationsInUse;
|
||||
STATIC PPOOL_TRACKING_BIG_ALLOCATIONS BigAllocationsTrackingTable;
|
||||
STATIC SIZE_T BigAllocationsTrackingTableHash;
|
||||
STATIC KSPIN_LOCK BigAllocationsTrackingTableLock;
|
||||
STATIC SIZE_T BigAllocationsTrackingTableSize;
|
||||
STATIC PPOOL_TRACKING_TABLE TagTables[MM_POOL_TRACKING_TABLES];
|
||||
|
||||
public:
|
||||
STATIC XTAPI XTSTATUS AllocatePages(IN MMPOOL_TYPE PoolType,
|
||||
IN SIZE_T Bytes,
|
||||
OUT PVOID *Memory);
|
||||
STATIC XTAPI XTSTATUS AllocatePool(IN MMPOOL_TYPE PoolType,
|
||||
IN SIZE_T Bytes,
|
||||
OUT PVOID *Memory);
|
||||
STATIC XTAPI XTSTATUS AllocatePool(IN MMPOOL_TYPE PoolType,
|
||||
IN SIZE_T Bytes,
|
||||
OUT PVOID *Memory,
|
||||
IN ULONG Tag);
|
||||
STATIC XTAPI XTSTATUS FreePages(IN PVOID VirtualAddress);
|
||||
STATIC XTAPI XTSTATUS FreePages(IN PVOID VirtualAddress,
|
||||
OUT PPFN_NUMBER PagesFreed);
|
||||
STATIC XTAPI XTSTATUS FreePool(IN PVOID VirtualAddress);
|
||||
STATIC XTAPI XTSTATUS FreePool(IN PVOID VirtualAddress,
|
||||
IN ULONG Tag);
|
||||
STATIC XTAPI VOID InitializeAllocationsTracking(VOID);
|
||||
STATIC XTAPI VOID InitializeBigAllocationsTracking(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 XTINLINE ULONG ComputeHash(IN PVOID VirtualAddress);
|
||||
STATIC XTINLINE ULONG ComputeHash(IN ULONG Tag,
|
||||
IN ULONG TableMask);
|
||||
STATIC XTAPI BOOLEAN ExpandBigAllocationsTable(VOID);
|
||||
STATIC XTAPI XTSTATUS FreeNonPagedPoolPages(IN PVOID VirtualAddress,
|
||||
OUT PPFN_NUMBER PagesFreed);
|
||||
STATIC XTAPI XTSTATUS FreePagedPoolPages(IN PVOID VirtualAddress,
|
||||
OUT PPFN_NUMBER PagesFreed);
|
||||
STATIC XTAPI VOID RegisterAllocationTag(IN ULONG Tag,
|
||||
IN SIZE_T Bytes,
|
||||
IN MMPOOL_TYPE PoolType);
|
||||
STATIC XTAPI VOID RegisterAllocationTagExpansion(IN ULONG Tag,
|
||||
IN SIZE_T Bytes,
|
||||
IN MMPOOL_TYPE PoolType);
|
||||
STATIC XTAPI BOOLEAN RegisterBigAllocationTag(IN PVOID VirtualAddress,
|
||||
IN ULONG Tag,
|
||||
IN ULONG Pages,
|
||||
IN MMPOOL_TYPE PoolType);
|
||||
STATIC XTAPI VOID UnregisterAllocationTag(IN ULONG Tag,
|
||||
IN SIZE_T Bytes,
|
||||
IN MMPOOL_TYPE PoolType);
|
||||
STATIC XTAPI VOID UnregisterAllocationTagExpansion(IN ULONG Tag,
|
||||
IN SIZE_T Bytes,
|
||||
IN MMPOOL_TYPE PoolType);
|
||||
STATIC XTAPI ULONG UnregisterBigAllocationTag(IN PVOID VirtualAddress,
|
||||
OUT PULONG_PTR Pages,
|
||||
IN MMPOOL_TYPE PoolType);
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* __XTOSKRNL_MM_ALLOC_HH */
|
||||
@@ -1,13 +1,13 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: xtoskrnl/includes/mm/pagemap.hh
|
||||
* FILE: xtoskrnl/includes/mm/amd64/pagemap.hh
|
||||
* DESCRIPTION: Low-level support for page map manipulation
|
||||
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef __XTOSKRNL_MM_PAGEMAP_HH
|
||||
#define __XTOSKRNL_MM_PAGEMAP_HH
|
||||
#ifndef __XTOSKRNL_MM_AMD64_PAGEMAP_HH
|
||||
#define __XTOSKRNL_MM_AMD64_PAGEMAP_HH
|
||||
|
||||
#include <xtos.hh>
|
||||
|
||||
@@ -21,33 +21,77 @@ namespace MM
|
||||
MMPAGEMAP_INFO PageMapInfo;
|
||||
|
||||
public:
|
||||
XTAPI VOID ClearPte(PHARDWARE_PTE PtePointer);
|
||||
XTAPI PMMP5E GetP5eAddress(PVOID Address);
|
||||
XTAPI PMMPDE GetPdeAddress(PVOID Address);
|
||||
XTAPI PMMPPE GetPpeAddress(PVOID Address);
|
||||
XTAPI PMMPTE GetPteAddress(PVOID Address);
|
||||
XTAPI PMMPXE GetPxeAddress(PVOID Address);
|
||||
virtual XTAPI VOID InitializePageMapInfo(VOID) = 0;
|
||||
XTAPI BOOLEAN PteValid(PHARDWARE_PTE PtePointer);
|
||||
XTAPI VOID SetPte(PHARDWARE_PTE PtePointer,
|
||||
PFN_NUMBER PageFrameNumber,
|
||||
BOOLEAN Writable);
|
||||
XTAPI VOID SetPteCaching(PHARDWARE_PTE PtePointer,
|
||||
BOOLEAN CacheDisable,
|
||||
BOOLEAN WriteThrough);
|
||||
XTAPI PMMPTE AdvancePte(IN PMMPTE Pte,
|
||||
IN LONG Count);
|
||||
XTAPI BOOLEAN CanonicalAddress(IN PVOID VirtualAddress);
|
||||
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 PMMP5E GetP5eAddress(IN PVOID Address);
|
||||
XTAPI ULONG GetP5eOffset(IN PVOID Address);
|
||||
XTAPI PVOID GetP5eVirtualAddress(IN PMMP5E P5ePointer);
|
||||
XTAPI USHORT GetPageMapLevel();
|
||||
XTAPI PFN_NUMBER GetPageFrameNumber(IN PMMPTE Pte);
|
||||
XTAPI PMMPDE GetPdeAddress(IN PVOID Address);
|
||||
XTAPI ULONG GetPdeOffset(IN PVOID Address);
|
||||
VIRTUAL XTAPI PVOID GetPdeVirtualAddress(IN PMMPDE PdePointer) = 0;
|
||||
XTAPI PMMPPE GetPpeAddress(IN PVOID Address);
|
||||
XTAPI ULONG GetPpeOffset(IN PVOID Address);
|
||||
VIRTUAL XTAPI PVOID GetPpeVirtualAddress(IN PMMPPE PpePointer) = 0;
|
||||
XTAPI ULONGLONG 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 ULONGLONG AttributesMask);
|
||||
XTAPI VOID SetPte(IN PMMPTE PtePointer,
|
||||
IN ULONGLONG 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;
|
||||
|
||||
class PageMapBasic final : public PageMap
|
||||
{
|
||||
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);
|
||||
};
|
||||
|
||||
class PageMapXpa final : public PageMap
|
||||
{
|
||||
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);
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* __XTOSKRNL_MM_PAGEMAP_HH */
|
||||
#endif /* __XTOSKRNL_MM_AMD64_PAGEMAP_HH */
|
||||
|
||||
81
xtoskrnl/includes/mm/amd64/paging.hh
Normal file
81
xtoskrnl/includes/mm/amd64/paging.hh
Normal file
@@ -0,0 +1,81 @@
|
||||
/**
|
||||
* 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 BOOLEAN CanonicalAddress(IN PVOID VirtualAddress);
|
||||
STATIC XTAPI VOID ClearPte(IN PMMPTE PtePointer);
|
||||
STATIC XTAPI VOID FlushEntireTlb(VOID);
|
||||
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 ULONGLONG 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 ULONGLONG AttributesMask);
|
||||
STATIC XTAPI VOID SetPte(IN PMMPTE PtePointer,
|
||||
IN ULONGLONG 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 */
|
||||
69
xtoskrnl/includes/mm/amd64/pte.hh
Normal file
69
xtoskrnl/includes/mm/amd64/pte.hh
Normal file
@@ -0,0 +1,69 @@
|
||||
/**
|
||||
* 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 InitializeSystemPtePool(IN PMMPTE StartingPte,
|
||||
IN PFN_COUNT NumberOfPtes,
|
||||
IN MMSYSTEM_PTE_POOL_TYPE PoolType);
|
||||
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);
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* __XTOSKRNL_MM_AMD64_PTE_HH */
|
||||
38
xtoskrnl/includes/mm/colors.hh
Normal file
38
xtoskrnl/includes/mm/colors.hh
Normal file
@@ -0,0 +1,38 @@
|
||||
/**
|
||||
* 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 */
|
||||
88
xtoskrnl/includes/mm/guard.hh
Normal file
88
xtoskrnl/includes/mm/guard.hh
Normal file
@@ -0,0 +1,88 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: xtoskrnl/includes/mm/guard.hh
|
||||
* DESCRIPTION: Memory Manager synchronization guard
|
||||
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef __XTOSKRNL_MM_GUARD_HH
|
||||
#define __XTOSKRNL_MM_GUARD_HH
|
||||
|
||||
#include <xtos.hh>
|
||||
#include <ke/runlevel.hh>
|
||||
#include <ke/spinlock.hh>
|
||||
|
||||
|
||||
/* Memory Manager */
|
||||
namespace MM
|
||||
{
|
||||
class PoolLockGuard
|
||||
{
|
||||
private:
|
||||
BOOLEAN Locked;
|
||||
MMPOOL_TYPE LockPoolType;
|
||||
KRUNLEVEL PreviousRunLevel;
|
||||
|
||||
public:
|
||||
PoolLockGuard(IN MMPOOL_TYPE PoolType)
|
||||
{
|
||||
LockPoolType = PoolType;
|
||||
|
||||
/* Determine the appropriate synchronization mechanism based on the requested pool type */
|
||||
if(LockPoolType == NonPagedPool)
|
||||
{
|
||||
/* Elevate the runlevel to DISPATCH_LEVEL */
|
||||
PreviousRunLevel = KE::RunLevel::RaiseRunLevel(DISPATCH_LEVEL);
|
||||
|
||||
/* Acquire the global queued spinlock protecting the non-paged pool */
|
||||
KE::SpinLock::AcquireQueuedSpinLock(NonPagedPoolLock);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Paged pool requires a mutex, currently unimplemented */
|
||||
UNIMPLEMENTED;
|
||||
}
|
||||
|
||||
/* Mark the guard as actively holding the lock */
|
||||
Locked = TRUE;
|
||||
}
|
||||
|
||||
~PoolLockGuard(VOID)
|
||||
{
|
||||
/* Automatically release the held lock upon going out of scope */
|
||||
Release();
|
||||
}
|
||||
|
||||
PoolLockGuard(const PoolLockGuard&) = delete;
|
||||
PoolLockGuard& operator=(const PoolLockGuard&) = delete;
|
||||
|
||||
VOID Release(VOID)
|
||||
{
|
||||
/* Check if the guard is currently holding a lock */
|
||||
if(!Locked)
|
||||
{
|
||||
/* Return, to prevent a double-free */
|
||||
return;
|
||||
}
|
||||
|
||||
/* Determine the appropriate synchronization mechanism based on the requested pool type */
|
||||
if(LockPoolType == NonPagedPool)
|
||||
{
|
||||
/* Release the non-paged pool spinlock and subsequently restore the original runlevel */
|
||||
KE::SpinLock::ReleaseQueuedSpinLock(NonPagedPoolLock);
|
||||
KE::RunLevel::LowerRunLevel(PreviousRunLevel);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Paged pool requires a mutex, currently unimplemented */
|
||||
UNIMPLEMENTED;
|
||||
}
|
||||
|
||||
/* Update the internal state, indicating that the lock is no longer held */
|
||||
Locked = FALSE;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* __XTOSKRNL_MM_GUARD_HH */
|
||||
@@ -1,13 +1,13 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: xtoskrnl/includes/mm/pagemap.hh
|
||||
* FILE: xtoskrnl/includes/mm/i686/pagemap.hh
|
||||
* DESCRIPTION: Low-level support for page map manipulation
|
||||
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef __XTOSKRNL_MM_PAGEMAP_HH
|
||||
#define __XTOSKRNL_MM_PAGEMAP_HH
|
||||
#ifndef __XTOSKRNL_MM_I686_PAGEMAP_HH
|
||||
#define __XTOSKRNL_MM_I686_PAGEMAP_HH
|
||||
|
||||
#include <xtos.hh>
|
||||
|
||||
@@ -21,45 +21,130 @@ namespace MM
|
||||
MMPAGEMAP_INFO PageMapInfo;
|
||||
|
||||
public:
|
||||
XTAPI VOID ClearPte(PHARDWARE_PTE PtePointer);
|
||||
XTAPI PMMPDE GetPdeAddress(PVOID Address);
|
||||
XTAPI PMMPPE GetPpeAddress(PVOID Address);
|
||||
XTAPI PMMPTE GetPteAddress(PVOID Address);
|
||||
virtual XTAPI VOID InitializePageMapInfo(VOID) = 0;
|
||||
virtual XTAPI BOOLEAN PteValid(PHARDWARE_PTE PtePointer) = 0;
|
||||
virtual XTAPI VOID SetPte(PHARDWARE_PTE PtePointer,
|
||||
PFN_NUMBER PageFrameNumber,
|
||||
BOOLEAN Writable) = 0;
|
||||
virtual XTAPI VOID SetPteCaching(PHARDWARE_PTE PtePointer,
|
||||
BOOLEAN CacheDisable,
|
||||
BOOLEAN WriteThrough) = 0;
|
||||
VIRTUAL XTAPI PMMPTE AdvancePte(IN PMMPTE Pte,
|
||||
IN ULONG Count) = 0;
|
||||
XTAPI BOOLEAN CanonicalAddress(IN PVOID VirtualAddress);
|
||||
VIRTUAL XTAPI VOID ClearPte(IN PMMPTE PtePointer) = 0;
|
||||
VIRTUAL XTAPI ULONG_PTR GetNextEntry(IN PMMPTE Pte) = 0;
|
||||
VIRTUAL XTAPI PMMPTE GetNextPte(IN PMMPTE Pte) = 0;
|
||||
VIRTUAL XTAPI BOOLEAN GetOneEntry(IN PMMPTE Pte) = 0;
|
||||
VIRTUAL XTAPI PFN_NUMBER GetPageFrameNumber(IN PMMPTE Pte) = 0;
|
||||
XTAPI USHORT GetPageMapLevel();
|
||||
XTAPI PMMPDE GetPdeAddress(IN PVOID Address);
|
||||
XTAPI ULONG GetPdeOffset(IN PVOID Address);
|
||||
VIRTUAL XTAPI PVOID GetPdeVirtualAddress(IN PMMPDE PdePointer) = 0;
|
||||
XTAPI PMMPPE GetPpeAddress(IN PVOID Address);
|
||||
XTAPI ULONG GetPpeOffset(IN PVOID Address);
|
||||
XTAPI PVOID GetPpeVirtualAddress(IN PMMPPE PpePointer);
|
||||
VIRTUAL XTAPI ULONGLONG 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 ULONGLONG AttributesMask) = 0;
|
||||
VIRTUAL XTAPI VOID SetPte(IN PMMPTE PtePointer,
|
||||
IN ULONGLONG 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;
|
||||
|
||||
class PageMapBasic final : public PageMap
|
||||
{
|
||||
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 ULONGLONG 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 BOOLEAN PteValid(PHARDWARE_PTE PtePointer);
|
||||
XTAPI VOID SetPte(PHARDWARE_PTE PtePointer,
|
||||
PFN_NUMBER PageFrameNumber,
|
||||
BOOLEAN Writable);
|
||||
XTAPI VOID SetPteCaching(PHARDWARE_PTE PtePointer,
|
||||
BOOLEAN CacheDisable,
|
||||
BOOLEAN WriteThrough);
|
||||
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 ULONGLONG AttributesMask);
|
||||
XTAPI VOID SetPte(IN PMMPTE PtePointer,
|
||||
IN ULONGLONG 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
|
||||
{
|
||||
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 ULONGLONG 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 BOOLEAN PteValid(PHARDWARE_PTE PtePointer);
|
||||
XTAPI VOID SetPte(PHARDWARE_PTE PtePointer,
|
||||
PFN_NUMBER PageFrameNumber,
|
||||
BOOLEAN Writable);
|
||||
XTAPI VOID SetPteCaching(PHARDWARE_PTE PtePointer,
|
||||
BOOLEAN CacheDisable,
|
||||
BOOLEAN WriteThrough);
|
||||
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 ULONGLONG AttributesMask);
|
||||
XTAPI VOID SetPte(IN PMMPTE PtePointer,
|
||||
IN ULONGLONG 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_PAGEMAP_HH */
|
||||
#endif /* __XTOSKRNL_MM_I686_PAGEMAP_HH */
|
||||
|
||||
77
xtoskrnl/includes/mm/i686/paging.hh
Normal file
77
xtoskrnl/includes/mm/i686/paging.hh
Normal file
@@ -0,0 +1,77 @@
|
||||
/**
|
||||
* 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 BOOLEAN CanonicalAddress(IN PVOID VirtualAddress);
|
||||
STATIC XTAPI VOID ClearPte(IN PMMPTE PtePointer);
|
||||
STATIC XTAPI VOID FlushEntireTlb(VOID);
|
||||
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 ULONGLONG 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 ULONGLONG AttributesMask);
|
||||
STATIC XTAPI VOID SetPte(IN PMMPTE PtePointer,
|
||||
IN ULONGLONG 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 */
|
||||
63
xtoskrnl/includes/mm/i686/pte.hh
Normal file
63
xtoskrnl/includes/mm/i686/pte.hh
Normal file
@@ -0,0 +1,63 @@
|
||||
/**
|
||||
* 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 InitializeSystemPtePool(IN PMMPTE StartingPte,
|
||||
IN PFN_COUNT NumberOfPtes,
|
||||
IN MMSYSTEM_PTE_POOL_TYPE PoolType);
|
||||
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);
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* __XTOSKRNL_MM_I686_PTE_HH */
|
||||
@@ -1,39 +0,0 @@
|
||||
/**
|
||||
* 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 */
|
||||
@@ -17,17 +17,13 @@ namespace MM
|
||||
{
|
||||
class KernelPool
|
||||
{
|
||||
private:
|
||||
STATIC UCHAR ProcessorStructuresData[MAXIMUM_PROCESSORS][KPROCESSOR_STRUCTURES_SIZE];
|
||||
|
||||
public:
|
||||
STATIC XTAPI XTSTATUS AllocateKernelStack(IN PVOID *Stack,
|
||||
IN BOOLEAN LargeStack,
|
||||
IN UCHAR SystemNode);
|
||||
STATIC XTAPI XTSTATUS AllocateKernelStack(OUT PVOID *Stack,
|
||||
IN ULONG StackSize);
|
||||
STATIC XTAPI XTSTATUS AllocateProcessorStructures(IN ULONG CpuNumber,
|
||||
OUT PVOID *StructuresData);
|
||||
OUT PVOID *StructuresData);
|
||||
STATIC XTAPI VOID FreeKernelStack(IN PVOID Stack,
|
||||
IN BOOLEAN LargeStack);
|
||||
IN ULONG StackSize);
|
||||
STATIC XTAPI VOID FreeProcessorStructures(IN PVOID StructuresData);
|
||||
};
|
||||
}
|
||||
|
||||
46
xtoskrnl/includes/mm/mmgr.hh
Normal file
46
xtoskrnl/includes/mm/mmgr.hh
Normal file
@@ -0,0 +1,46 @@
|
||||
/**
|
||||
* 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;
|
||||
STATIC PPHYSICAL_MEMORY_DESCRIPTOR PhysicalMemoryBlock;
|
||||
|
||||
public:
|
||||
STATIC XTAPI ULONG_PTR GetInstalledMemorySize(VOID);
|
||||
STATIC XTAPI PMMMEMORY_LAYOUT GetMemoryLayout(VOID);
|
||||
STATIC XTAPI PFN_NUMBER GetNumberOfSystemPtes(VOID);
|
||||
STATIC XTAPI PPHYSICAL_MEMORY_DESCRIPTOR GetPhysicalMemoryBlock(VOID);
|
||||
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 */
|
||||
@@ -1,47 +0,0 @@
|
||||
/**
|
||||
* 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 */
|
||||
25
xtoskrnl/includes/mm/pfault.hh
Normal file
25
xtoskrnl/includes/mm/pfault.hh
Normal file
@@ -0,0 +1,25 @@
|
||||
/**
|
||||
* 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 */
|
||||
85
xtoskrnl/includes/mm/pfn.hh
Normal file
85
xtoskrnl/includes/mm/pfn.hh
Normal file
@@ -0,0 +1,85 @@
|
||||
/**
|
||||
* 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 RTL_BITMAP PfnBitMap;
|
||||
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 InitializePfnBitmap(VOID);
|
||||
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 */
|
||||
68
xtoskrnl/includes/mm/pool.hh
Normal file
68
xtoskrnl/includes/mm/pool.hh
Normal file
@@ -0,0 +1,68 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: xtoskrnl/includes/mm/pool.hh
|
||||
* DESCRIPTION: Memory Manager pool manager
|
||||
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef __XTOSKRNL_MM_POOL_HH
|
||||
#define __XTOSKRNL_MM_POOL_HH
|
||||
|
||||
#include <xtos.hh>
|
||||
|
||||
|
||||
/* Memory Manager */
|
||||
namespace MM
|
||||
{
|
||||
class Pool
|
||||
{
|
||||
protected:
|
||||
STATIC POOL_DESCRIPTOR NonPagedPoolDescriptor;
|
||||
STATIC PFN_NUMBER NonPagedPoolFrameEnd;
|
||||
STATIC PFN_NUMBER NonPagedPoolFrameStart;
|
||||
STATIC LIST_ENTRY NonPagedPoolFreeList[MM_MAX_FREE_PAGE_LIST_HEADS];
|
||||
STATIC ULONG PoolSecureCookie;
|
||||
STATIC PPOOL_DESCRIPTOR PoolVector[2];
|
||||
|
||||
public:
|
||||
STATIC XTAPI MMPOOL_TYPE DeterminePoolType(IN PVOID VirtualAddress);
|
||||
STATIC XTAPI VOID InitializeNonPagedPool(VOID);
|
||||
STATIC XTAPI VOID InitializePagedPool(VOID);
|
||||
STATIC XTAPI VOID InitializePoolSecurity(VOID);
|
||||
|
||||
protected:
|
||||
STATIC XTAPI PLIST_ENTRY DecodePoolLink(IN PLIST_ENTRY PoolLink);
|
||||
STATIC XTAPI PLIST_ENTRY EncodePoolLink(IN PLIST_ENTRY PoolLink);
|
||||
STATIC XTAPI PPOOL_HEADER GetPoolBlock(IN PPOOL_HEADER Header, IN SSIZE_T Index);
|
||||
STATIC XTAPI PPOOL_HEADER GetPoolEntry(IN PVOID Payload);
|
||||
STATIC XTAPI PLIST_ENTRY GetPoolFreeBlock(IN PPOOL_HEADER Header);
|
||||
STATIC XTAPI PPOOL_HEADER GetPoolNextBlock(IN PPOOL_HEADER Header);
|
||||
STATIC XTAPI PPOOL_HEADER GetPoolPreviousBlock(IN PPOOL_HEADER Header);
|
||||
STATIC XTAPI VOID InsertPoolHeadList(IN PLIST_ENTRY ListHead,
|
||||
IN PLIST_ENTRY Entry);
|
||||
STATIC XTAPI VOID InsertPoolTailList(IN PLIST_ENTRY ListHead,
|
||||
IN PLIST_ENTRY Entry);
|
||||
STATIC XTAPI BOOLEAN PoolListEmpty(IN PLIST_ENTRY ListHead);
|
||||
STATIC XTAPI VOID RemovePoolEntryList(IN PLIST_ENTRY Entry);
|
||||
STATIC XTAPI PLIST_ENTRY RemovePoolHeadList(IN PLIST_ENTRY ListHead);
|
||||
STATIC XTAPI PLIST_ENTRY RemovePoolTailList(IN PLIST_ENTRY ListHead);
|
||||
STATIC XTAPI VOID VerifyPoolBlocks(IN PVOID Block);
|
||||
STATIC XTAPI VOID VerifyPoolHeader(IN PPOOL_HEADER Entry);
|
||||
STATIC XTAPI VOID VerifyPoolLinks(IN PLIST_ENTRY ListHead);
|
||||
STATIC XTAPI VOID VerifyRunLevel(IN MMPOOL_TYPE PoolType,
|
||||
IN SIZE_T Bytes,
|
||||
IN PVOID Entry);
|
||||
|
||||
private:
|
||||
STATIC XTAPI VOID InitializePoolDescriptor(IN PPOOL_DESCRIPTOR Descriptor,
|
||||
IN MMPOOL_TYPE PoolType,
|
||||
IN ULONG Index,
|
||||
IN ULONG Threshold,
|
||||
IN PVOID LockAddress);
|
||||
STATIC XTAPI VOID InitializePoolListHead(IN PLIST_ENTRY ListHead);
|
||||
STATIC XTAPI VOID MapNonPagedPool(VOID);
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* __XTOSKRNL_MM_POOL_HH */
|
||||
@@ -19,6 +19,8 @@
|
||||
#include <rtl/llist.hh>
|
||||
#include <rtl/math.hh>
|
||||
#include <rtl/memory.hh>
|
||||
#include <rtl/sha1.hh>
|
||||
#include <rtl/slist.hh>
|
||||
#include <rtl/string.hh>
|
||||
#include <rtl/widestr.hh>
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
* FILE: xtoskrnl/includes/rtl/llist.hh
|
||||
* DESCRIPTION: Linked list manipulation routines
|
||||
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
|
||||
* Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||
*/
|
||||
|
||||
#ifndef __XTOSKRNL_RTL_LLIST_HH
|
||||
@@ -18,6 +19,7 @@ namespace RTL
|
||||
class LinkedList
|
||||
{
|
||||
public:
|
||||
STATIC XTCDECL PLIST_ENTRY GetFirstEntry(IN PLIST_ENTRY ListHead);
|
||||
STATIC XTCDECL VOID InitializeListHead(IN PLIST_ENTRY ListHead);
|
||||
STATIC XTCDECL VOID InitializeListHead32(IN PLIST_ENTRY32 ListHead);
|
||||
STATIC XTCDECL VOID InsertHeadList(IN OUT PLIST_ENTRY ListHead,
|
||||
@@ -27,6 +29,10 @@ namespace RTL
|
||||
STATIC XTCDECL BOOLEAN ListEmpty(IN PLIST_ENTRY ListHead);
|
||||
STATIC XTCDECL BOOLEAN ListLoop(IN PLIST_ENTRY ListHead);
|
||||
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);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
37
xtoskrnl/includes/rtl/sha1.hh
Normal file
37
xtoskrnl/includes/rtl/sha1.hh
Normal file
@@ -0,0 +1,37 @@
|
||||
/**
|
||||
* 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 */
|
||||
39
xtoskrnl/includes/rtl/slist.hh
Normal file
39
xtoskrnl/includes/rtl/slist.hh
Normal file
@@ -0,0 +1,39 @@
|
||||
/**
|
||||
* 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 */
|
||||
@@ -33,7 +33,11 @@ KE::Irq::SetInterruptHandler(IN ULONG Vector,
|
||||
ProcessorBlock = KE::Processor::GetCurrentProcessorBlock();
|
||||
|
||||
/* Update interrupt handler */
|
||||
ProcessorBlock->IdtBase[(UCHAR) Vector].OffsetLow = ((ULONG_PTR)Handler & 0xFFFF);
|
||||
ProcessorBlock->IdtBase[(UCHAR) Vector].OffsetMiddle = (((ULONG_PTR)Handler >> 16) & 0xFFFF);
|
||||
ProcessorBlock->IdtBase[(UCHAR) Vector].OffsetHigh = (ULONG_PTR)Handler >> 32;
|
||||
AR::ProcSup::SetIdtGate(ProcessorBlock->IdtBase,
|
||||
Vector,
|
||||
Handler,
|
||||
KGDT_R0_CODE,
|
||||
0,
|
||||
KIDT_ACCESS_RING0,
|
||||
AMD64_INTERRUPT_GATE);
|
||||
}
|
||||
|
||||
@@ -86,6 +86,10 @@ KE::KernelInit::StartKernel(VOID)
|
||||
/* Save processor state */
|
||||
Processor::SaveProcessorState(&Prcb->ProcessorState);
|
||||
|
||||
/* Initialize spin locks */
|
||||
SpinLock::InitializeAllLocks();
|
||||
SpinLock::InitializeLockQueues();
|
||||
|
||||
/* Lower to APC runlevel */
|
||||
RunLevel::LowerRunLevel(APC_LEVEL);
|
||||
|
||||
@@ -108,6 +112,9 @@ KE::KernelInit::StartKernel(VOID)
|
||||
CurrentThread->WaitRunLevel = DISPATCH_LEVEL;
|
||||
CurrentProcess->ActiveProcessors |= (ULONG_PTR)1 << Prcb->CpuNumber;
|
||||
|
||||
/* Initialize Memory Manager */
|
||||
MM::Manager::InitializeMemoryManager();
|
||||
|
||||
/* Enter infinite loop */
|
||||
DebugPrint(L"KernelInit::StartKernel() finished. Entering infinite loop.\n");
|
||||
Crash::HaltSystem();
|
||||
|
||||
@@ -43,7 +43,7 @@ XTAPI
|
||||
VOID
|
||||
KE::Crash::Panic(IN ULONG Code)
|
||||
{
|
||||
PanicEx(Code, 0, 0, 0, 0);
|
||||
Panic(Code, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -70,12 +70,13 @@ KE::Crash::Panic(IN ULONG Code)
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
KE::Crash::PanicEx(IN ULONG Code,
|
||||
IN ULONG_PTR Parameter1,
|
||||
IN ULONG_PTR Parameter2,
|
||||
IN ULONG_PTR Parameter3,
|
||||
IN ULONG_PTR Parameter4)
|
||||
KE::Crash::Panic(IN ULONG Code,
|
||||
IN ULONG_PTR Parameter1,
|
||||
IN ULONG_PTR Parameter2,
|
||||
IN ULONG_PTR Parameter3,
|
||||
IN ULONG_PTR Parameter4)
|
||||
{
|
||||
KD::DebugIo::KdPrint(L"Fatal System Error: 0x%08lx\nKernel Panic!\n\n", Code);
|
||||
KD::DebugIo::KdPrint(L"Fatal System Error: 0x%08lx (0x%zx 0x%zx 0x%zx 0x%zx)\nKernel Panic!\n\n",
|
||||
Code, Parameter1, Parameter2, Parameter3, Parameter4);
|
||||
HaltSystem();
|
||||
}
|
||||
|
||||
@@ -12,12 +12,6 @@
|
||||
/* Kernel initialization block passed by boot loader */
|
||||
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 */
|
||||
EPROCESS KE::KProcess::InitialProcess;
|
||||
|
||||
@@ -26,3 +20,54 @@ ETHREAD KE::KThread::InitialThread = {};
|
||||
|
||||
/* Kernel UBSAN active frame flag */
|
||||
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;
|
||||
|
||||
@@ -33,6 +33,11 @@ KE::Irq::SetInterruptHandler(IN ULONG Vector,
|
||||
ProcessorBlock = KE::Processor::GetCurrentProcessorBlock();
|
||||
|
||||
/* Update interrupt handler */
|
||||
ProcessorBlock->IdtBase[(UCHAR) Vector].Offset = (USHORT)((ULONG)Handler & 0xFFFF);
|
||||
ProcessorBlock->IdtBase[(UCHAR) Vector].ExtendedOffset = (USHORT)((ULONG)Handler >> 16);
|
||||
AR::ProcSup::SetIdtGate(ProcessorBlock->IdtBase,
|
||||
Vector,
|
||||
Handler,
|
||||
KGDT_R0_CODE,
|
||||
0,
|
||||
KIDT_ACCESS_RING0,
|
||||
I686_INTERRUPT_GATE);
|
||||
}
|
||||
|
||||
@@ -86,6 +86,10 @@ KE::KernelInit::StartKernel(VOID)
|
||||
/* Save processor state */
|
||||
Processor::SaveProcessorState(&Prcb->ProcessorState);
|
||||
|
||||
/* Initialize spin locks */
|
||||
SpinLock::InitializeAllLocks();
|
||||
SpinLock::InitializeLockQueues();
|
||||
|
||||
/* Lower to APC runlevel */
|
||||
RunLevel::LowerRunLevel(APC_LEVEL);
|
||||
|
||||
@@ -108,6 +112,9 @@ KE::KernelInit::StartKernel(VOID)
|
||||
CurrentThread->WaitRunLevel = DISPATCH_LEVEL;
|
||||
CurrentProcess->ActiveProcessors |= (ULONG_PTR)1 << Prcb->CpuNumber;
|
||||
|
||||
/* Initialize Memory Manager */
|
||||
MM::Manager::InitializeMemoryManager();
|
||||
|
||||
/* Enter infinite loop */
|
||||
DebugPrint(L"KernelInit::StartKernel() finished. Entering infinite loop.\n");
|
||||
Crash::HaltSystem();
|
||||
|
||||
@@ -152,7 +152,7 @@ KE::KThread::InitializeThread(IN PKPROCESS Process,
|
||||
if(!Stack)
|
||||
{
|
||||
/* Allocate new stack */
|
||||
Status = MM::KernelPool::AllocateKernelStack(&Stack, FALSE, 0);
|
||||
Status = MM::KernelPool::AllocateKernelStack(&Stack, KERNEL_STACK_SIZE);
|
||||
if(Status != STATUS_SUCCESS || !Stack)
|
||||
{
|
||||
/* Stack allocation failed */
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
* FILE: xtoskrnl/ke/spinlock.cc
|
||||
* DESCRIPTION: Spinlocks support
|
||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||
* Aiken Harris <harraiken91@gmail.com>
|
||||
*/
|
||||
|
||||
#include <xtos.hh>
|
||||
@@ -56,6 +57,78 @@ KE::SpinLock::AcquireSpinLock(IN OUT PKSPIN_LOCK SpinLock)
|
||||
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.
|
||||
*
|
||||
@@ -112,3 +185,29 @@ KE::SpinLock::ReleaseSpinLock(IN OUT PKSPIN_LOCK SpinLock)
|
||||
/* Add an explicit memory barrier */
|
||||
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;
|
||||
}
|
||||
|
||||
2170
xtoskrnl/mm/alloc.cc
Normal file
2170
xtoskrnl/mm/alloc.cc
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,25 +0,0 @@
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
390
xtoskrnl/mm/amd64/mmgr.cc
Normal file
390
xtoskrnl/mm/amd64/mmgr.cc
Normal file
@@ -0,0 +1,390 @@
|
||||
/**
|
||||
* 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,6 +9,51 @@
|
||||
#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)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the given address is canonical.
|
||||
*
|
||||
* @param VirtualAddress
|
||||
* Specifies the virtual address to check.
|
||||
*
|
||||
* @return This routine returns TRUE if the address is canonical, FALSE otherwise.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
BOOLEAN
|
||||
MM::PageMap::CanonicalAddress(IN PVOID VirtualAddress)
|
||||
{
|
||||
ULONG Shift;
|
||||
|
||||
/* Calculate the number of unused upper bits based on the paging mode */
|
||||
Shift = 64 - PageMapInfo.VaBits;
|
||||
|
||||
/* Sign-extend via arithmetic shifts to verify the canonical form */
|
||||
return ((((LONGLONG)VirtualAddress << Shift) >> Shift) == (LONGLONG)VirtualAddress);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the contents of a page table entry (PTE).
|
||||
*
|
||||
@@ -21,13 +66,64 @@
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
MM::PageMap::ClearPte(PHARDWARE_PTE PtePointer)
|
||||
MM::PageMap::ClearPte(IN PMMPTE PtePointer)
|
||||
{
|
||||
PtePointer->CacheDisable = 0;
|
||||
PtePointer->PageFrameNumber = 0;
|
||||
PtePointer->Valid = 0;
|
||||
PtePointer->Writable = 0;
|
||||
PtePointer->WriteThrough = 0;
|
||||
/* Clear PTE */
|
||||
PtePointer->Long = 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;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -42,7 +138,7 @@ MM::PageMap::ClearPte(PHARDWARE_PTE PtePointer)
|
||||
*/
|
||||
XTAPI
|
||||
PMMP5E
|
||||
MM::PageMap::GetP5eAddress(PVOID Address)
|
||||
MM::PageMap::GetP5eAddress(IN PVOID Address)
|
||||
{
|
||||
ULONGLONG Offset;
|
||||
|
||||
@@ -51,6 +147,72 @@ MM::PageMap::GetP5eAddress(PVOID Address)
|
||||
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.
|
||||
*
|
||||
@@ -63,7 +225,7 @@ MM::PageMap::GetP5eAddress(PVOID Address)
|
||||
*/
|
||||
XTAPI
|
||||
PMMPDE
|
||||
MM::PageMap::GetPdeAddress(PVOID Address)
|
||||
MM::PageMap::GetPdeAddress(IN PVOID Address)
|
||||
{
|
||||
ULONGLONG Offset;
|
||||
|
||||
@@ -73,18 +235,36 @@ MM::PageMap::GetPdeAddress(PVOID Address)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the address of the PPE (Page Directory Pointer Table Entry), that maps given address.
|
||||
* 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.
|
||||
*
|
||||
* @param Address
|
||||
* Specifies the virtual address for which to retrieve the corresponding PPE.
|
||||
*
|
||||
* @return This routine returns the address of the PPE.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
PMMPPE
|
||||
MM::PageMap::GetPpeAddress(PVOID Address)
|
||||
MM::PageMap::GetPpeAddress(IN PVOID Address)
|
||||
{
|
||||
ULONGLONG Offset;
|
||||
|
||||
@@ -93,6 +273,42 @@ MM::PageMap::GetPpeAddress(PVOID Address)
|
||||
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
|
||||
ULONGLONG
|
||||
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.
|
||||
*
|
||||
@@ -105,7 +321,7 @@ MM::PageMap::GetPpeAddress(PVOID Address)
|
||||
*/
|
||||
XTAPI
|
||||
PMMPTE
|
||||
MM::PageMap::GetPteAddress(PVOID Address)
|
||||
MM::PageMap::GetPteAddress(IN PVOID Address)
|
||||
{
|
||||
ULONGLONG Offset;
|
||||
|
||||
@@ -114,6 +330,115 @@ MM::PageMap::GetPteAddress(PVOID Address)
|
||||
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.
|
||||
*
|
||||
@@ -126,14 +451,47 @@ MM::PageMap::GetPteAddress(PVOID Address)
|
||||
*/
|
||||
XTAPI
|
||||
PMMPXE
|
||||
MM::PageMap::GetPxeAddress(PVOID Address)
|
||||
MM::PageMap::GetPxeAddress(IN PVOID Address)
|
||||
{
|
||||
ULONGLONG Offset;
|
||||
|
||||
/* Calculate offset and return PXE address */
|
||||
Offset = ((((ULONGLONG)Address & (((ULONGLONG)1 << PageMapInfo.VaBits) - 1)) >> MM_PXI_SHIFT) << MM_PTE_SHIFT);
|
||||
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.
|
||||
*
|
||||
@@ -146,22 +504,20 @@ MM::PageMap::GetPxeAddress(PVOID Address)
|
||||
*/
|
||||
XTAPI
|
||||
BOOLEAN
|
||||
MM::PageMap::PteValid(PHARDWARE_PTE PtePointer)
|
||||
MM::PageMap::PteValid(IN PMMPTE PtePointer)
|
||||
{
|
||||
return (BOOLEAN)PtePointer->Valid;
|
||||
/* Check if PTE is valid */
|
||||
return (BOOLEAN)PtePointer->Hardware.Valid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a PML2 page table entry (PTE) with the specified physical page and access flags.
|
||||
* Sets the next entry in a PTE list.
|
||||
*
|
||||
* @param PtePointer
|
||||
* Pointer to the page table entry (PTE) to set.
|
||||
* @param Pte
|
||||
* The PTE pointer to modify.
|
||||
*
|
||||
* @param PageFrameNumber
|
||||
* Physical frame number to map.
|
||||
*
|
||||
* @param Writable
|
||||
* Indicates whether the page should be writable.
|
||||
* @param Value
|
||||
* The value to set as the next entry.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
@@ -169,13 +525,82 @@ MM::PageMap::PteValid(PHARDWARE_PTE PtePointer)
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
MM::PageMap::SetPte(PHARDWARE_PTE PtePointer,
|
||||
PFN_NUMBER PageFrameNumber,
|
||||
BOOLEAN Writable)
|
||||
MM::PageMap::SetNextEntry(IN PMMPTE Pte,
|
||||
IN ULONG_PTR Value)
|
||||
{
|
||||
PtePointer->PageFrameNumber = PageFrameNumber;
|
||||
PtePointer->Valid = 1;
|
||||
PtePointer->Writable = Writable;
|
||||
/* 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
|
||||
* Pointer to the page table entry (PTE) to set.
|
||||
*
|
||||
* @param PageFrameNumber
|
||||
* Physical frame number to map.
|
||||
*
|
||||
* @param AttributesMask
|
||||
* Specifies the attributes mask 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 PFN_NUMBER PageFrameNumber,
|
||||
IN ULONGLONG AttributesMask)
|
||||
{
|
||||
/* Set PTE */
|
||||
PtePointer->Hardware.PageFrameNumber = PageFrameNumber;
|
||||
PtePointer->Hardware.Valid = 1;
|
||||
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 ULONGLONG Attributes)
|
||||
{
|
||||
PtePointer->Long = Attributes;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -196,12 +621,138 @@ MM::PageMap::SetPte(PHARDWARE_PTE PtePointer,
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
MM::PageMap::SetPteCaching(PHARDWARE_PTE PtePointer,
|
||||
BOOLEAN CacheDisable,
|
||||
BOOLEAN WriteThrough)
|
||||
MM::PageMap::SetPteCaching(IN PMMPTE PtePointer,
|
||||
IN BOOLEAN CacheDisable,
|
||||
IN BOOLEAN WriteThrough)
|
||||
{
|
||||
PtePointer->CacheDisable = CacheDisable;
|
||||
PtePointer->WriteThrough = WriteThrough;
|
||||
/* Set caching attributes */
|
||||
PtePointer->Hardware.CacheDisable = CacheDisable;
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -229,6 +780,78 @@ MM::PageMapBasic::InitializePageMapInfo(VOID)
|
||||
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).
|
||||
*
|
||||
|
||||
@@ -25,6 +25,78 @@ MM::Paging::GetExtendedPhysicalAddressingStatus(VOID)
|
||||
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.
|
||||
*
|
||||
|
||||
26
xtoskrnl/mm/amd64/pfault.cc
Normal file
26
xtoskrnl/mm/amd64/pfault.cc
Normal file
@@ -0,0 +1,26 @@
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
345
xtoskrnl/mm/amd64/pfn.cc
Normal file
345
xtoskrnl/mm/amd64/pfn.cc
Normal file
@@ -0,0 +1,345 @@
|
||||
/**
|
||||
* 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;
|
||||
|
||||
/* Clear the newly created page */
|
||||
RTL::Memory::ZeroMemory(MM::Paging::GetPteVirtualAddress(StartingPde), MM_PAGE_SIZE);
|
||||
}
|
||||
|
||||
/* 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);
|
||||
}
|
||||
}
|
||||
34
xtoskrnl/mm/amd64/pool.cc
Normal file
34
xtoskrnl/mm/amd64/pool.cc
Normal file
@@ -0,0 +1,34 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: xtoskrnl/mm/amd64/pool.cc
|
||||
* DESCRIPTION: AMD64 Memory Manager pool manager
|
||||
* 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::Pool::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());
|
||||
}
|
||||
295
xtoskrnl/mm/amd64/pte.cc
Normal file
295
xtoskrnl/mm/amd64/pte.cc
Normal file
@@ -0,0 +1,295 @@
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
178
xtoskrnl/mm/colors.cc
Normal file
178
xtoskrnl/mm/colors.cc
Normal file
@@ -0,0 +1,178 @@
|
||||
/**
|
||||
* 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,6 +9,54 @@
|
||||
#include <xtos.hh>
|
||||
|
||||
|
||||
/* Expansion table used to track pool memory allocations */
|
||||
PPOOL_TRACKING_TABLE MM::Allocator::AllocationsTrackingExpansionTable;
|
||||
|
||||
/* Total number of entries in the expansion allocations tracking table */
|
||||
SIZE_T MM::Allocator::AllocationsTrackingExpansionTableSize;
|
||||
|
||||
/* Global table used to track pool memory allocations */
|
||||
PPOOL_TRACKING_TABLE MM::Allocator::AllocationsTrackingTable;
|
||||
|
||||
/* Spinlock protecting the allocations table */
|
||||
KSPIN_LOCK MM::Allocator::AllocationsTrackingTableLock;
|
||||
|
||||
/* Bitmask used during the hashing process */
|
||||
SIZE_T MM::Allocator::AllocationsTrackingTableMask;
|
||||
|
||||
/* Total number of entries in the global allocations tracking table */
|
||||
SIZE_T MM::Allocator::AllocationsTrackingTableSize;
|
||||
|
||||
/* Active number of big allocations to trigger table expansion */
|
||||
ULONG MM::Allocator::BigAllocationsInUse;
|
||||
|
||||
/* Pointer to the hash table for tracking page-aligned memory */
|
||||
PPOOL_TRACKING_BIG_ALLOCATIONS MM::Allocator::BigAllocationsTrackingTable;
|
||||
|
||||
/* Bitmask used for fast modulo arithmetic during hash bucket lookups */
|
||||
SIZE_T MM::Allocator::BigAllocationsTrackingTableHash;
|
||||
|
||||
/* Spinlock protecting the big allocations table */
|
||||
KSPIN_LOCK MM::Allocator::BigAllocationsTrackingTableLock;
|
||||
|
||||
/* Maximum capacity of the tracking hash table */
|
||||
SIZE_T MM::Allocator::BigAllocationsTrackingTableSize;
|
||||
|
||||
/* Array of CPU-local tracking tables */
|
||||
PPOOL_TRACKING_TABLE MM::Allocator::TagTables[MM_POOL_TRACKING_TABLES];
|
||||
|
||||
/* 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 */
|
||||
LOADER_MEMORY_DESCRIPTOR MM::HardwarePool::HardwareAllocationDescriptors[MM_HARDWARE_ALLOCATION_DESCRIPTORS];
|
||||
|
||||
@@ -18,23 +66,102 @@ PVOID MM::HardwarePool::HardwareHeapStart = MM_HARDWARE_HEAP_START_ADDRESS;
|
||||
/* Number of used hardware allocation descriptors */
|
||||
ULONG MM::HardwarePool::UsedHardwareAllocationDescriptors = 0;
|
||||
|
||||
/* Biggest free memory descriptor */
|
||||
PLOADER_MEMORY_DESCRIPTOR MM::Init::FreeDescriptor;
|
||||
/* Global structure describing the virtual memory layout of the system */
|
||||
MMMEMORY_LAYOUT MM::Manager::MemoryLayout;
|
||||
|
||||
/* Highest physical page number */
|
||||
ULONG_PTR MM::Init::HighestPhysicalPage;
|
||||
/* Total number of PTEs reserved for system space mapping */
|
||||
PFN_NUMBER MM::Manager::NumberOfSystemPtes;
|
||||
|
||||
/* 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) */
|
||||
UCHAR MM::KernelPool::ProcessorStructuresData[MAXIMUM_PROCESSORS][KPROCESSOR_STRUCTURES_SIZE] = {{0}};
|
||||
/* Physical memory block descriptor */
|
||||
PPHYSICAL_MEMORY_DESCRIPTOR MM::Manager::PhysicalMemoryBlock;
|
||||
|
||||
/* Instance of the page map routines for the current PML level */
|
||||
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;
|
||||
|
||||
/* 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};
|
||||
|
||||
/* Bitmap used to track physical pages */
|
||||
RTL_BITMAP MM::Pfn::PfnBitMap;
|
||||
|
||||
/* 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};
|
||||
|
||||
/* Non-paged pool descriptor */
|
||||
POOL_DESCRIPTOR MM::Pool::NonPagedPoolDescriptor;
|
||||
|
||||
/* PFN marking the initial non-paged pool end boundary */
|
||||
PFN_NUMBER MM::Pool::NonPagedPoolFrameEnd;
|
||||
|
||||
/* PFN marking the initial non-paged pool start boundary */
|
||||
PFN_NUMBER MM::Pool::NonPagedPoolFrameStart;
|
||||
|
||||
/* Array of non-paged pool free list heads */
|
||||
LIST_ENTRY MM::Pool::NonPagedPoolFreeList[MM_MAX_FREE_PAGE_LIST_HEADS];
|
||||
|
||||
/* Random cookie used to obfuscate pool links */
|
||||
ULONG MM::Pool::PoolSecureCookie;
|
||||
|
||||
/* Array of pool descriptors */
|
||||
PPOOL_DESCRIPTOR MM::Pool::PoolVector[2];
|
||||
|
||||
/* 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;
|
||||
|
||||
102
xtoskrnl/mm/exports.cc
Normal file
102
xtoskrnl/mm/exports.cc
Normal file
@@ -0,0 +1,102 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: xtoskrnl/mm/exports.cc
|
||||
* DESCRIPTION: C-compatible API wrappers for exported kernel functions
|
||||
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
|
||||
*/
|
||||
|
||||
#include <xtos.hh>
|
||||
|
||||
|
||||
/**
|
||||
* Allocates a block of memory from the specified pool type.
|
||||
*
|
||||
* @param PoolType
|
||||
* Specifies the type of pool to allocate from.
|
||||
*
|
||||
* @param Bytes
|
||||
* Specifies the number of bytes to allocate.
|
||||
*
|
||||
* @param Memory
|
||||
* Supplies a pointer to the allocated memory.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
XTSTATUS
|
||||
MmAllocatePool(IN MMPOOL_TYPE PoolType,
|
||||
IN SIZE_T Bytes,
|
||||
OUT PVOID *Memory)
|
||||
{
|
||||
return MM::Allocator::AllocatePool(PoolType, Bytes, Memory);
|
||||
}
|
||||
|
||||
/**
|
||||
* Allocates a block of memory from the specified pool type.
|
||||
*
|
||||
* @param PoolType
|
||||
* Specifies the type of pool to allocate from.
|
||||
*
|
||||
* @param Bytes
|
||||
* Specifies the number of bytes to allocate.
|
||||
*
|
||||
* @param Memory
|
||||
* Supplies a pointer to the allocated memory.
|
||||
*
|
||||
* @param Tag
|
||||
* Specifies the allocation identifying tag.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
XTSTATUS
|
||||
MmAllocatePoolWithTag(IN MMPOOL_TYPE PoolType,
|
||||
IN SIZE_T Bytes,
|
||||
OUT PVOID *Memory,
|
||||
IN ULONG Tag)
|
||||
{
|
||||
return MM::Allocator::AllocatePool(PoolType, Bytes, Memory, Tag);
|
||||
}
|
||||
|
||||
/**
|
||||
* Frees a previously allocated memory pool.
|
||||
*
|
||||
* @param VirtualAddress
|
||||
* Supplies the base virtual address of the pool allocation to free.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
XTSTATUS
|
||||
MmFreePool(IN PVOID VirtualAddress)
|
||||
{
|
||||
return MM::Allocator::FreePool(VirtualAddress);
|
||||
}
|
||||
|
||||
/**
|
||||
* Frees a previously allocated memory pool.
|
||||
*
|
||||
* @param VirtualAddress
|
||||
* Supplies the base virtual address of the pool allocation to free.
|
||||
*
|
||||
* @param Tag
|
||||
* Specifies the allocation identifying tag.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
XTSTATUS
|
||||
MmFreePoolWithTag(IN PVOID VirtualAddress,
|
||||
IN ULONG Tag)
|
||||
{
|
||||
return MM::Allocator::FreePool(VirtualAddress, Tag);
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user