forked from xt-sys/exectos
Compare commits
268 Commits
powershell
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
3ce009db41
|
|||
|
a0b0938099
|
|||
|
32d3672a51
|
|||
|
0c17337388
|
|||
|
9c449bed43
|
|||
|
a64aa83eb8
|
|||
|
64b5de98c8
|
|||
|
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
|
* NT drivers compatibility layer
|
||||||
|
|
||||||
# Requirements
|
# Requirements
|
||||||
ExectOS is in very early development stage, thus its requirements have been not specified yet. However according to its
|
ExectOS is currently in a very early stage of development, so its specific requirements are not fully defined yet.
|
||||||
design, it requires a modern EFI enabled hardware. It is not possible currently to boot ExectOS on a legacy BIOS.
|
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
|
# Source structure
|
||||||
| Directory | Description |
|
| Directory | Description |
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
# XT Boot Sector
|
# XT Boot Sector
|
||||||
PROJECT(BOOTSECT)
|
PROJECT(BOOTSECT)
|
||||||
|
|
||||||
|
add_definitions("-DARCH_ESP_SOURCE=\\\"${ARCH}/cpu.S\\\"")
|
||||||
|
|
||||||
# Compile boot sectors
|
# Compile boot sectors
|
||||||
compile_bootsector(mbrboot ${BOOTSECT_SOURCE_DIR}/mbrboot.S 0x7C00 Start)
|
compile_bootsector(mbrboot ${BOOTSECT_SOURCE_DIR}/mbrboot.S 0x7C00 Start)
|
||||||
compile_bootsector(espboot ${BOOTSECT_SOURCE_DIR}/espboot.S 0x7C00 Start)
|
compile_bootsector(espboot ${BOOTSECT_SOURCE_DIR}/espboot.S 0x7C00 Start)
|
||||||
|
|||||||
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
|
ja FsError
|
||||||
|
|
||||||
ReadExtraCode:
|
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
|
movl HiddenSectors - Start(%bp), %eax
|
||||||
addl $0x02, %eax
|
addl $0x02, %eax
|
||||||
movw $0x01, %cx
|
movw $0x03, %cx
|
||||||
xorw %bx, %bx
|
xorw %bx, %bx
|
||||||
movw %bx, %es
|
movw %bx, %es
|
||||||
movw $0x7E00, %bx
|
movw $0x7E00, %bx
|
||||||
call ReadSectors
|
call ReadSectors
|
||||||
jmp StartSectors
|
jmp StartExtraCode
|
||||||
|
|
||||||
ReadSectors:
|
ReadSectors:
|
||||||
/* Check for extended BIOS functions and use it only if available */
|
/* Check for extended BIOS functions and use it only if available */
|
||||||
@@ -139,18 +139,22 @@ ReadSectors:
|
|||||||
movw $0x55AA, %bx
|
movw $0x55AA, %bx
|
||||||
movb DriveNumber - Start(%bp), %dl
|
movb DriveNumber - Start(%bp), %dl
|
||||||
int $0x13
|
int $0x13
|
||||||
jc ReadCHS
|
jc .ReadCHS
|
||||||
cmpw $0xAA55, %bx
|
cmpw $0xAA55, %bx
|
||||||
jne ReadCHS
|
jne .ReadCHS
|
||||||
testb $0x01, %cl
|
testb $0x01, %cl
|
||||||
jz ReadCHS
|
jz .ReadCHS
|
||||||
|
|
||||||
/* Verify drive size and determine whether to use CHS or LBA */
|
/* Verify drive size and determine whether to use CHS or LBA */
|
||||||
cmpl %edi, %eax
|
cmpl %edi, %eax
|
||||||
jnb ReadLBA
|
jnb .ReadLBA
|
||||||
|
|
||||||
ReadCHS:
|
.ReadCHS:
|
||||||
/* Read sectors using CHS */
|
/* Read sectors using CHS */
|
||||||
|
popal
|
||||||
|
|
||||||
|
.CHSLoop:
|
||||||
|
/* Read sector by sector using CHS */
|
||||||
pushw %cx
|
pushw %cx
|
||||||
pushal
|
pushal
|
||||||
xorl %edx, %edx
|
xorl %edx, %edx
|
||||||
@@ -176,11 +180,11 @@ ReadCHS:
|
|||||||
movw %es, %dx
|
movw %es, %dx
|
||||||
addw $0x20, %dx
|
addw $0x20, %dx
|
||||||
movw %dx, %es
|
movw %dx, %es
|
||||||
loop ReadCHS
|
loop .CHSLoop
|
||||||
popw %es
|
popw %es
|
||||||
ret
|
ret
|
||||||
|
|
||||||
ReadLBA:
|
.ReadLBA:
|
||||||
/* Prepare DAP packet and read sectors using LBA */
|
/* Prepare DAP packet and read sectors using LBA */
|
||||||
popal
|
popal
|
||||||
pushw %cx
|
pushw %cx
|
||||||
@@ -209,19 +213,19 @@ ReadLBA:
|
|||||||
movw %dx, %es
|
movw %dx, %es
|
||||||
popw %bx
|
popw %bx
|
||||||
subw %si, %cx
|
subw %si, %cx
|
||||||
jnz ReadLBA
|
jnz .ReadLBA
|
||||||
popw %es
|
popw %es
|
||||||
ret
|
ret
|
||||||
|
|
||||||
DiskError:
|
DiskError:
|
||||||
/* Display disk error message and reboot */
|
/* Display disk error message and reboot */
|
||||||
movw $msgDiskError, %si
|
movw $.MsgDiskError, %si
|
||||||
call Print
|
call Print
|
||||||
jmp Reboot
|
jmp Reboot
|
||||||
|
|
||||||
FsError:
|
FsError:
|
||||||
/* Display FS error message and reboot */
|
/* Display FS error message and reboot */
|
||||||
movw $msgFsError, %si
|
movw $.MsgFsError, %si
|
||||||
call Print
|
call Print
|
||||||
jmp Reboot
|
jmp Reboot
|
||||||
|
|
||||||
@@ -229,48 +233,297 @@ Print:
|
|||||||
/* Simple routine to print messages */
|
/* Simple routine to print messages */
|
||||||
lodsb
|
lodsb
|
||||||
orb %al, %al
|
orb %al, %al
|
||||||
jz DonePrint
|
jz .DonePrint
|
||||||
movb $0x0E, %ah
|
movb $0x0E, %ah
|
||||||
movw $0x07, %bx
|
movw $0x07, %bx
|
||||||
int $0x10
|
int $0x10
|
||||||
jmp Print
|
jmp Print
|
||||||
DonePrint:
|
.DonePrint:
|
||||||
retw
|
retw
|
||||||
|
|
||||||
Reboot:
|
Reboot:
|
||||||
/* Display a message, wait for a key press and reboot */
|
/* Display a message, wait for a key press and reboot */
|
||||||
movw $msgAnyKey, %si
|
movw $.MsgAnyKey, %si
|
||||||
call Print
|
call Print
|
||||||
xorw %ax, %ax
|
xorw %ax, %ax
|
||||||
int $0x16
|
int $0x16
|
||||||
int $0x19
|
int $0x19
|
||||||
|
|
||||||
msgAnyKey:
|
.MsgAnyKey:
|
||||||
.ascii "Press any key to restart\r\n"
|
.ascii "Press any key to restart...\r\n\0"
|
||||||
|
|
||||||
msgDiskError:
|
.MsgDiskError:
|
||||||
.ascii "Disk error\r\n"
|
.ascii "Disk error!\r\n\0"
|
||||||
|
|
||||||
msgFsError:
|
.MsgFsError:
|
||||||
.ascii "File system error\r\n"
|
.ascii "File system error!\r\n\0"
|
||||||
|
|
||||||
/* Fill the rest of the VBR with zeros and add VBR signature at the end */
|
/* Fill the rest of the VBR with zeros and add VBR signature at the end */
|
||||||
.fill (510 - (. - Start)), 1, 0
|
.fill (510 - (. - Start)), 1, 0
|
||||||
.word 0xAA55
|
.word 0xAA55
|
||||||
|
|
||||||
|
|
||||||
StartSectors:
|
StartExtraCode:
|
||||||
/* Print message */
|
/* Load XTLDR file from disk */
|
||||||
movw $msgUnavailable, %si
|
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
|
call Print
|
||||||
|
jmp Reboot
|
||||||
|
|
||||||
/* Wait for key press and reboot */
|
FileNotFound:
|
||||||
xorw %ax, %ax
|
/* Display XTLDR not found message and reboot */
|
||||||
int $0x16
|
movw $.MsgXtLdrNotFound, %si
|
||||||
int $0x19
|
call Print
|
||||||
|
jmp Reboot
|
||||||
|
|
||||||
msgUnavailable:
|
Stage2NotLoaded:
|
||||||
.ascii "XTLDR requires EFI-based system!\r\nPress any key to restart\r\n"
|
/* 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 */
|
.BootDirName:
|
||||||
.fill (1024 - (. - Start)), 1, 0
|
/* 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
|
* FILE: boot/bootsect/amd64/mbrboot.S
|
||||||
* DESCRIPTION: XT Boot Loader MBR boot code
|
* DESCRIPTION: XT Boot Loader MBR boot code
|
||||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||||
|
* Aiken Harris <aiken@codingworkshop.eu.org>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
.text
|
.text
|
||||||
@@ -41,7 +42,7 @@ RealStart:
|
|||||||
movw %ax, %ss
|
movw %ax, %ss
|
||||||
|
|
||||||
/* Print welcome message */
|
/* Print welcome message */
|
||||||
leaw msgXtosBoot, %si
|
leaw .MsgXtosBoot, %si
|
||||||
call Print
|
call Print
|
||||||
|
|
||||||
/* Get BIOS boot drive and partition table offset */
|
/* Get BIOS boot drive and partition table offset */
|
||||||
@@ -90,19 +91,19 @@ PartitionFound:
|
|||||||
|
|
||||||
InvalidSignature:
|
InvalidSignature:
|
||||||
/* Invalid signature error */
|
/* Invalid signature error */
|
||||||
leaw msgInvalidSignature, %si
|
leaw .MsgInvalidSignature, %si
|
||||||
call Print
|
call Print
|
||||||
jmp HaltSystem
|
jmp HaltSystem
|
||||||
|
|
||||||
PartitionNotFound:
|
PartitionNotFound:
|
||||||
/* Active partition not found error */
|
/* Active partition not found error */
|
||||||
leaw msgPartitionNotFound, %si
|
leaw .MsgPartitionNotFound, %si
|
||||||
call Print
|
call Print
|
||||||
jmp HaltSystem
|
jmp HaltSystem
|
||||||
|
|
||||||
VbrReadFail:
|
VbrReadFail:
|
||||||
/* VBR read failed error */
|
/* VBR read failed error */
|
||||||
leaw msgVbrReadFail, %si
|
leaw .MsgVbrReadFail, %si
|
||||||
call Print
|
call Print
|
||||||
jmp HaltSystem
|
jmp HaltSystem
|
||||||
|
|
||||||
@@ -136,16 +137,16 @@ DonePrint:
|
|||||||
/* Storage for the LBA start */
|
/* Storage for the LBA start */
|
||||||
.long 0
|
.long 0
|
||||||
|
|
||||||
msgInvalidSignature:
|
.MsgInvalidSignature:
|
||||||
.asciz "Invalid partition signature!"
|
.asciz "Invalid partition signature!"
|
||||||
|
|
||||||
msgPartitionNotFound:
|
.MsgPartitionNotFound:
|
||||||
.asciz "Bootable partition not found!"
|
.asciz "Bootable partition not found!"
|
||||||
|
|
||||||
msgVbrReadFail:
|
.MsgVbrReadFail:
|
||||||
.asciz "VBR read failed!"
|
.asciz "VBR read failed!"
|
||||||
|
|
||||||
msgXtosBoot:
|
.MsgXtosBoot:
|
||||||
.asciz "Starting XTOS boot loader...\r\n"
|
.asciz "Starting XTOS boot loader...\r\n"
|
||||||
|
|
||||||
/* Fill the rest of the MBR with zeros and add MBR signature at the end */
|
/* Fill the rest of the MBR with zeros and add MBR signature at the end */
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ list(APPEND LIBXTLDR_SOURCE
|
|||||||
# Specify list of source code files
|
# Specify list of source code files
|
||||||
list(APPEND XTLDR_SOURCE
|
list(APPEND XTLDR_SOURCE
|
||||||
${XTLDR_SOURCE_DIR}/arch/${ARCH}/memory.cc
|
${XTLDR_SOURCE_DIR}/arch/${ARCH}/memory.cc
|
||||||
|
${XTLDR_SOURCE_DIR}/biosutil.cc
|
||||||
${XTLDR_SOURCE_DIR}/bootutil.cc
|
${XTLDR_SOURCE_DIR}/bootutil.cc
|
||||||
${XTLDR_SOURCE_DIR}/config.cc
|
${XTLDR_SOURCE_DIR}/config.cc
|
||||||
${XTLDR_SOURCE_DIR}/console.cc
|
${XTLDR_SOURCE_DIR}/console.cc
|
||||||
@@ -38,6 +39,9 @@ add_executable(xtldr ${XTLDR_SOURCE})
|
|||||||
# Add linker libraries
|
# Add linker libraries
|
||||||
target_link_libraries(xtldr libxtos)
|
target_link_libraries(xtldr libxtos)
|
||||||
|
|
||||||
|
# Add linker options
|
||||||
|
target_link_options(xtldr PRIVATE /ALIGN:512)
|
||||||
|
|
||||||
# Set proper binary name and install target
|
# Set proper binary name and install target
|
||||||
if(ARCH STREQUAL "i686")
|
if(ARCH STREQUAL "i686")
|
||||||
set(BINARY_NAME "bootia32")
|
set(BINARY_NAME "bootia32")
|
||||||
@@ -49,5 +53,6 @@ set_install_target(xtldr efi/boot)
|
|||||||
|
|
||||||
# Set loader entrypoint and subsystem
|
# Set loader entrypoint and subsystem
|
||||||
set_entrypoint(xtldr "BlStartXtLoader")
|
set_entrypoint(xtldr "BlStartXtLoader")
|
||||||
|
set_imagebase(xtldr ${BASEADDRESS_XTLDR})
|
||||||
set_linker_map(xtldr TRUE)
|
set_linker_map(xtldr TRUE)
|
||||||
set_subsystem(xtldr efi_application)
|
set_subsystem(xtldr efi_application)
|
||||||
|
|||||||
@@ -28,13 +28,12 @@ EFI_STATUS
|
|||||||
Memory::BuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
|
Memory::BuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
|
||||||
IN ULONG_PTR SelfMapAddress)
|
IN ULONG_PTR SelfMapAddress)
|
||||||
{
|
{
|
||||||
PLIST_ENTRY ListEntry, ModulesList, ModulesListEntry;
|
PLIST_ENTRY ModulesList, ModulesListEntry;
|
||||||
PXTBL_MEMORY_MAPPING Mapping;
|
|
||||||
PXTBL_MODULE_INFO ModuleInfo;
|
PXTBL_MODULE_INFO ModuleInfo;
|
||||||
EFI_PHYSICAL_ADDRESS Address;
|
EFI_PHYSICAL_ADDRESS Address;
|
||||||
PVOID LoaderBase;
|
|
||||||
ULONGLONG LoaderSize;
|
ULONGLONG LoaderSize;
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
|
PVOID LoaderBase;
|
||||||
|
|
||||||
/* Allocate pages for the Page Map */
|
/* Allocate pages for the Page Map */
|
||||||
Status = AllocatePages(AllocateAnyPages, 1, &Address);
|
Status = AllocatePages(AllocateAnyPages, 1, &Address);
|
||||||
@@ -44,6 +43,14 @@ Memory::BuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
|
|||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Add new memory mapping for the page map itself */
|
||||||
|
Status = MapVirtualMemory(PageMap, (ULONGLONG)NULLPTR, Address, 1, LoaderMemoryData);
|
||||||
|
if(Status != STATUS_EFI_SUCCESS)
|
||||||
|
{
|
||||||
|
/* Memory mapping failure */
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
/* Assign and zero-fill memory used by page mappings */
|
/* Assign and zero-fill memory used by page mappings */
|
||||||
PageMap->PtePointer = (PVOID)(UINT_PTR)Address;
|
PageMap->PtePointer = (PVOID)(UINT_PTR)Address;
|
||||||
RTL::Memory::ZeroMemory(PageMap->PtePointer, EFI_PAGE_SIZE);
|
RTL::Memory::ZeroMemory(PageMap->PtePointer, EFI_PAGE_SIZE);
|
||||||
@@ -57,7 +64,7 @@ Memory::BuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Map the trampoline code area */
|
/* 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);
|
1, LoaderFirmwareTemporary);
|
||||||
if(Status != STATUS_EFI_SUCCESS)
|
if(Status != STATUS_EFI_SUCCESS)
|
||||||
{
|
{
|
||||||
@@ -74,7 +81,7 @@ Memory::BuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
|
|||||||
ModuleInfo = CONTAIN_RECORD(ModulesListEntry, XTBL_MODULE_INFO, Flink);
|
ModuleInfo = CONTAIN_RECORD(ModulesListEntry, XTBL_MODULE_INFO, Flink);
|
||||||
|
|
||||||
/* Map module code */
|
/* Map module code */
|
||||||
Status = MapVirtualMemory(PageMap, ModuleInfo->ModuleBase, ModuleInfo->ModuleBase,
|
Status = MapVirtualMemory(PageMap, (ULONGLONG)ModuleInfo->ModuleBase, (ULONGLONG)ModuleInfo->ModuleBase,
|
||||||
EFI_SIZE_TO_PAGES(ModuleInfo->ModuleSize), LoaderFirmwareTemporary);
|
EFI_SIZE_TO_PAGES(ModuleInfo->ModuleSize), LoaderFirmwareTemporary);
|
||||||
|
|
||||||
/* Check if mapping succeeded */
|
/* Check if mapping succeeded */
|
||||||
@@ -95,7 +102,7 @@ Memory::BuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
|
|||||||
if(LoaderBase && LoaderSize)
|
if(LoaderBase && LoaderSize)
|
||||||
{
|
{
|
||||||
/* Map boot loader code as well */
|
/* Map boot loader code as well */
|
||||||
Status = MapVirtualMemory(PageMap, LoaderBase, LoaderBase,
|
Status = MapVirtualMemory(PageMap, (ULONGLONG)LoaderBase, (ULONGLONG)LoaderBase,
|
||||||
EFI_SIZE_TO_PAGES(LoaderSize), LoaderFirmwareTemporary);
|
EFI_SIZE_TO_PAGES(LoaderSize), LoaderFirmwareTemporary);
|
||||||
if(Status != STATUS_EFI_SUCCESS)
|
if(Status != STATUS_EFI_SUCCESS)
|
||||||
{
|
{
|
||||||
@@ -109,6 +116,28 @@ Memory::BuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
|
|||||||
return STATUS_EFI_PROTOCOL_ERROR;
|
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*/
|
/* Iterate through and map all the mappings*/
|
||||||
Debug::Print(L"Mapping and dumping EFI memory:\n");
|
Debug::Print(L"Mapping and dumping EFI memory:\n");
|
||||||
ListEntry = PageMap->MemoryMap.Flink;
|
ListEntry = PageMap->MemoryMap.Flink;
|
||||||
@@ -193,7 +222,7 @@ Memory::GetNextPageTable(IN PXTBL_PAGE_MAPPING PageMap,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Add new memory mapping */
|
/* 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)
|
if(Status != STATUS_EFI_SUCCESS)
|
||||||
{
|
{
|
||||||
/* Memory mapping failure */
|
/* Memory mapping failure */
|
||||||
@@ -239,9 +268,9 @@ Memory::GetNextPageTable(IN PXTBL_PAGE_MAPPING PageMap,
|
|||||||
XTCDECL
|
XTCDECL
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
Memory::MapPage(IN PXTBL_PAGE_MAPPING PageMap,
|
Memory::MapPage(IN PXTBL_PAGE_MAPPING PageMap,
|
||||||
IN ULONG_PTR VirtualAddress,
|
IN ULONGLONG VirtualAddress,
|
||||||
IN ULONG_PTR PhysicalAddress,
|
IN ULONGLONG PhysicalAddress,
|
||||||
IN ULONG NumberOfPages)
|
IN ULONGLONG NumberOfPages)
|
||||||
{
|
{
|
||||||
PVOID Pml1, Pml2, Pml3, Pml4, Pml5;
|
PVOID Pml1, Pml2, Pml3, Pml4, Pml5;
|
||||||
SIZE_T Pml1Entry, Pml2Entry, Pml3Entry, Pml4Entry, Pml5Entry;
|
SIZE_T Pml1Entry, Pml2Entry, Pml3Entry, Pml4Entry, Pml5Entry;
|
||||||
|
|||||||
@@ -25,13 +25,12 @@ EFI_STATUS
|
|||||||
Memory::BuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
|
Memory::BuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
|
||||||
IN ULONG_PTR SelfMapAddress)
|
IN ULONG_PTR SelfMapAddress)
|
||||||
{
|
{
|
||||||
PLIST_ENTRY ListEntry, ModulesList, ModulesListEntry;
|
|
||||||
EFI_PHYSICAL_ADDRESS Address, DirectoryAddress;
|
EFI_PHYSICAL_ADDRESS Address, DirectoryAddress;
|
||||||
|
PLIST_ENTRY ModulesList, ModulesListEntry;
|
||||||
PXTBL_MODULE_INFO ModuleInfo;
|
PXTBL_MODULE_INFO ModuleInfo;
|
||||||
PXTBL_MEMORY_MAPPING Mapping;
|
|
||||||
PVOID LoaderBase;
|
|
||||||
ULONGLONG LoaderSize;
|
ULONGLONG LoaderSize;
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
|
PVOID LoaderBase;
|
||||||
ULONG Index;
|
ULONG Index;
|
||||||
|
|
||||||
/* Check the page map level to determine which paging structure to create */
|
/* 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;
|
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 */
|
/* Assign the allocated page to the page map and zero it out */
|
||||||
PageMap->PtePointer = (PVOID)(UINT_PTR)Address;
|
PageMap->PtePointer = (PVOID)(UINT_PTR)Address;
|
||||||
RTL::Memory::ZeroMemory(PageMap->PtePointer, EFI_PAGE_SIZE);
|
RTL::Memory::ZeroMemory(PageMap->PtePointer, EFI_PAGE_SIZE);
|
||||||
@@ -57,6 +64,14 @@ Memory::BuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
|
|||||||
return Status;
|
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 */
|
/* Zero-fill the allocated memory for the Page Directories */
|
||||||
RTL::Memory::ZeroMemory((PVOID)DirectoryAddress, EFI_PAGE_SIZE * 4);
|
RTL::Memory::ZeroMemory((PVOID)DirectoryAddress, EFI_PAGE_SIZE * 4);
|
||||||
|
|
||||||
@@ -79,6 +94,14 @@ Memory::BuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
|
|||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Add new memory mapping for the page map itself */
|
||||||
|
Status = MapVirtualMemory(PageMap, (ULONGLONG)NULLPTR, Address, 1, LoaderMemoryData);
|
||||||
|
if(Status != STATUS_EFI_SUCCESS)
|
||||||
|
{
|
||||||
|
/* Memory mapping failure */
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
/* Assign the allocated page to the page map and zero it out */
|
/* Assign the allocated page to the page map and zero it out */
|
||||||
PageMap->PtePointer = (PVOID)(UINT_PTR)Address;
|
PageMap->PtePointer = (PVOID)(UINT_PTR)Address;
|
||||||
RTL::Memory::ZeroMemory(PageMap->PtePointer, EFI_PAGE_SIZE);
|
RTL::Memory::ZeroMemory(PageMap->PtePointer, EFI_PAGE_SIZE);
|
||||||
@@ -93,8 +116,7 @@ Memory::BuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Map the trampoline code area */
|
/* 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);
|
||||||
1, LoaderFirmwareTemporary);
|
|
||||||
if(Status != STATUS_EFI_SUCCESS)
|
if(Status != STATUS_EFI_SUCCESS)
|
||||||
{
|
{
|
||||||
/* Mapping trampoline code failed */
|
/* Mapping trampoline code failed */
|
||||||
@@ -110,7 +132,7 @@ Memory::BuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
|
|||||||
ModuleInfo = CONTAIN_RECORD(ModulesListEntry, XTBL_MODULE_INFO, Flink);
|
ModuleInfo = CONTAIN_RECORD(ModulesListEntry, XTBL_MODULE_INFO, Flink);
|
||||||
|
|
||||||
/* Map module code */
|
/* Map module code */
|
||||||
Status = MapVirtualMemory(PageMap, ModuleInfo->ModuleBase, ModuleInfo->ModuleBase,
|
Status = MapVirtualMemory(PageMap, (ULONGLONG)ModuleInfo->ModuleBase, (ULONGLONG)ModuleInfo->ModuleBase,
|
||||||
EFI_SIZE_TO_PAGES(ModuleInfo->ModuleSize), LoaderFirmwareTemporary);
|
EFI_SIZE_TO_PAGES(ModuleInfo->ModuleSize), LoaderFirmwareTemporary);
|
||||||
|
|
||||||
/* Check if mapping succeeded */
|
/* Check if mapping succeeded */
|
||||||
@@ -131,7 +153,7 @@ Memory::BuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
|
|||||||
if(LoaderBase && LoaderSize)
|
if(LoaderBase && LoaderSize)
|
||||||
{
|
{
|
||||||
/* Map boot loader code as well */
|
/* Map boot loader code as well */
|
||||||
Status = MapVirtualMemory(PageMap, LoaderBase, LoaderBase,
|
Status = MapVirtualMemory(PageMap, (ULONGLONG)LoaderBase, (ULONGLONG)LoaderBase,
|
||||||
EFI_SIZE_TO_PAGES(LoaderSize), LoaderFirmwareTemporary);
|
EFI_SIZE_TO_PAGES(LoaderSize), LoaderFirmwareTemporary);
|
||||||
if(Status != STATUS_EFI_SUCCESS)
|
if(Status != STATUS_EFI_SUCCESS)
|
||||||
{
|
{
|
||||||
@@ -145,6 +167,28 @@ Memory::BuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
|
|||||||
return STATUS_EFI_PROTOCOL_ERROR;
|
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*/
|
/* Iterate through and map all the mappings*/
|
||||||
Debug::Print(L"Mapping and dumping EFI memory:\n");
|
Debug::Print(L"Mapping and dumping EFI memory:\n");
|
||||||
ListEntry = PageMap->MemoryMap.Flink;
|
ListEntry = PageMap->MemoryMap.Flink;
|
||||||
@@ -157,8 +201,9 @@ Memory::BuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
|
|||||||
if(Mapping->VirtualAddress)
|
if(Mapping->VirtualAddress)
|
||||||
{
|
{
|
||||||
/* Dump memory mapping */
|
/* Dump memory mapping */
|
||||||
Debug::Print(L" Type=%02lu, PhysicalBase=%.8P, VirtualBase=%.8P, Pages=%llu\n", Mapping->MemoryType,
|
Debug::Print(L" Type=%02lu, PhysicalBase=0x%.8llX, VirtualBase=0x%.8llX, Pages=%llu\n",
|
||||||
Mapping->PhysicalAddress, Mapping->VirtualAddress, Mapping->NumberOfPages);
|
Mapping->MemoryType, Mapping->PhysicalAddress,
|
||||||
|
Mapping->VirtualAddress, Mapping->NumberOfPages);
|
||||||
|
|
||||||
/* Map memory */
|
/* Map memory */
|
||||||
Status = MapPage(PageMap, (UINT_PTR)Mapping->VirtualAddress,
|
Status = MapPage(PageMap, (UINT_PTR)Mapping->VirtualAddress,
|
||||||
@@ -252,7 +297,7 @@ Memory::GetNextPageTable(IN PXTBL_PAGE_MAPPING PageMap,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Add new memory mapping */
|
/* 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)
|
if(Status != STATUS_EFI_SUCCESS)
|
||||||
{
|
{
|
||||||
/* Memory mapping failure */
|
/* Memory mapping failure */
|
||||||
@@ -313,11 +358,11 @@ Memory::GetNextPageTable(IN PXTBL_PAGE_MAPPING PageMap,
|
|||||||
XTCDECL
|
XTCDECL
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
Memory::MapPage(IN PXTBL_PAGE_MAPPING PageMap,
|
Memory::MapPage(IN PXTBL_PAGE_MAPPING PageMap,
|
||||||
IN ULONG_PTR VirtualAddress,
|
IN ULONGLONG VirtualAddress,
|
||||||
IN ULONG_PTR PhysicalAddress,
|
IN ULONGLONG PhysicalAddress,
|
||||||
IN ULONG NumberOfPages)
|
IN ULONGLONG NumberOfPages)
|
||||||
{
|
{
|
||||||
SIZE_T PageFrameNumber;
|
ULONGLONG PageFrameNumber;
|
||||||
PVOID Pml1, Pml2, Pml3;
|
PVOID Pml1, Pml2, Pml3;
|
||||||
SIZE_T Pml1Entry, Pml2Entry, Pml3Entry;
|
SIZE_T Pml1Entry, Pml2Entry, Pml3Entry;
|
||||||
PHARDWARE_LEGACY_PTE LegacyPmlTable;
|
PHARDWARE_LEGACY_PTE LegacyPmlTable;
|
||||||
|
|||||||
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>
|
#include <xtldr.hh>
|
||||||
|
|
||||||
|
|
||||||
|
/* Legacy BIOS cursor X position */
|
||||||
|
USHORT BiosUtils::CursorX = 0;
|
||||||
|
|
||||||
|
/* Legacy BIOS cursor Y position */
|
||||||
|
USHORT BiosUtils::CursorY = 0;
|
||||||
|
|
||||||
|
/* Legacy BIOS screen height */
|
||||||
|
CONST USHORT BiosUtils::VgaHeight = 25;
|
||||||
|
|
||||||
|
/* Legacy BIOS screen width */
|
||||||
|
CONST USHORT BiosUtils::VgaWidth = 80;
|
||||||
|
|
||||||
/* XT Boot Loader menu list */
|
/* XT Boot Loader menu list */
|
||||||
PLIST_ENTRY Configuration::BootMenuList = NULLPTR;
|
PLIST_ENTRY Configuration::BootMenuList = NULLPTR;
|
||||||
|
|
||||||
|
|||||||
@@ -15,6 +15,25 @@
|
|||||||
#include <libxtos.hh>
|
#include <libxtos.hh>
|
||||||
|
|
||||||
|
|
||||||
|
class BiosUtils
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
STATIC USHORT CursorX;
|
||||||
|
STATIC USHORT CursorY;
|
||||||
|
STATIC CONST USHORT VgaHeight;
|
||||||
|
STATIC CONST USHORT VgaWidth;
|
||||||
|
|
||||||
|
public:
|
||||||
|
STATIC XTCDECL VOID ClearScreen();
|
||||||
|
STATIC XTCDECL VOID Print(IN PCWSTR Format,
|
||||||
|
IN ...);
|
||||||
|
STATIC XTCDECL XTSTATUS PutChar(IN WCHAR Character);
|
||||||
|
|
||||||
|
private:
|
||||||
|
STATIC XTCDECL VOID ScrollScreen();
|
||||||
|
STATIC XTCDECL VOID UpdateCursor();
|
||||||
|
};
|
||||||
|
|
||||||
class BootUtils
|
class BootUtils
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -146,6 +165,7 @@ class Memory
|
|||||||
OUT PVOID *Memory);
|
OUT PVOID *Memory);
|
||||||
STATIC XTCDECL EFI_STATUS BuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
|
STATIC XTCDECL EFI_STATUS BuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
|
||||||
IN ULONG_PTR SelfMapAddress);
|
IN ULONG_PTR SelfMapAddress);
|
||||||
|
STATIC XTCDECL EFI_STATUS CommitPageMap(IN PXTBL_PAGE_MAPPING PageMap);
|
||||||
STATIC XTCDECL EFI_STATUS FreePages(IN ULONGLONG NumberOfPages,
|
STATIC XTCDECL EFI_STATUS FreePages(IN ULONGLONG NumberOfPages,
|
||||||
IN EFI_PHYSICAL_ADDRESS Memory);
|
IN EFI_PHYSICAL_ADDRESS Memory);
|
||||||
STATIC XTCDECL EFI_STATUS FreePool(IN PVOID Memory);
|
STATIC XTCDECL EFI_STATUS FreePool(IN PVOID Memory);
|
||||||
@@ -158,15 +178,16 @@ class Memory
|
|||||||
IN SHORT PageMapLevel,
|
IN SHORT PageMapLevel,
|
||||||
IN PAGE_SIZE PageSize);
|
IN PAGE_SIZE PageSize);
|
||||||
STATIC XTCDECL EFI_STATUS MapEfiMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
|
STATIC XTCDECL EFI_STATUS MapEfiMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
|
||||||
IN OUT PVOID *MemoryMapAddress,
|
IN OUT PVOID *BaseAddress,
|
||||||
|
IN BOOLEAN IdentityMapping,
|
||||||
IN PBL_GET_MEMTYPE_ROUTINE GetMemoryTypeRoutine);
|
IN PBL_GET_MEMTYPE_ROUTINE GetMemoryTypeRoutine);
|
||||||
STATIC XTCDECL EFI_STATUS MapPage(IN PXTBL_PAGE_MAPPING PageMap,
|
STATIC XTCDECL EFI_STATUS MapPage(IN PXTBL_PAGE_MAPPING PageMap,
|
||||||
IN ULONG_PTR VirtualAddress,
|
IN ULONGLONG VirtualAddress,
|
||||||
IN ULONG_PTR PhysicalAddress,
|
IN ULONGLONG PhysicalAddress,
|
||||||
IN ULONG NumberOfPages);
|
IN ULONGLONG NumberOfPages);
|
||||||
STATIC XTCDECL EFI_STATUS MapVirtualMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
|
STATIC XTCDECL EFI_STATUS MapVirtualMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
|
||||||
IN PVOID VirtualAddress,
|
IN ULONGLONG VirtualAddress,
|
||||||
IN PVOID PhysicalAddress,
|
IN ULONGLONG PhysicalAddress,
|
||||||
IN ULONGLONG NumberOfPages,
|
IN ULONGLONG NumberOfPages,
|
||||||
IN LOADER_MEMORY_TYPE MemoryType);
|
IN LOADER_MEMORY_TYPE MemoryType);
|
||||||
STATIC XTCDECL PVOID PhysicalAddressToVirtual(IN PVOID PhysicalAddress,
|
STATIC XTCDECL PVOID PhysicalAddressToVirtual(IN PVOID PhysicalAddress,
|
||||||
|
|||||||
@@ -314,9 +314,12 @@ Memory::InitializePageMap(OUT PXTBL_PAGE_MAPPING PageMap,
|
|||||||
* @param PageMap
|
* @param PageMap
|
||||||
* Supplies a pointer to the page mapping structure.
|
* Supplies a pointer to the page mapping structure.
|
||||||
*
|
*
|
||||||
* @param MemoryMapAddress
|
* @param BaseAddress
|
||||||
* Supplies a virtual address, where EFI memory will be mapped.
|
* Supplies a virtual address, where EFI memory will be mapped.
|
||||||
*
|
*
|
||||||
|
* @param IdentityMapping
|
||||||
|
* Specifies whether EFI non-free memory should be mapped by identity or sequential mapping.
|
||||||
|
*
|
||||||
* @param GetMemoryTypeRoutine
|
* @param GetMemoryTypeRoutine
|
||||||
* Supplies a pointer to the routine which will be used to match EFI memory type to the OS memory type.
|
* Supplies a pointer to the routine which will be used to match EFI memory type to the OS memory type.
|
||||||
*
|
*
|
||||||
@@ -327,19 +330,20 @@ Memory::InitializePageMap(OUT PXTBL_PAGE_MAPPING PageMap,
|
|||||||
XTCDECL
|
XTCDECL
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
Memory::MapEfiMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
|
Memory::MapEfiMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
|
||||||
IN OUT PVOID *MemoryMapAddress,
|
IN OUT PVOID *BaseAddress,
|
||||||
|
IN BOOLEAN IdentityMapping,
|
||||||
IN PBL_GET_MEMTYPE_ROUTINE GetMemoryTypeRoutine)
|
IN PBL_GET_MEMTYPE_ROUTINE GetMemoryTypeRoutine)
|
||||||
{
|
{
|
||||||
|
ULONGLONG MaxAddress, VirtualAddress;
|
||||||
PEFI_MEMORY_DESCRIPTOR Descriptor;
|
PEFI_MEMORY_DESCRIPTOR Descriptor;
|
||||||
LOADER_MEMORY_TYPE MemoryType;
|
LOADER_MEMORY_TYPE MemoryType;
|
||||||
PEFI_MEMORY_MAP MemoryMap;
|
PEFI_MEMORY_MAP MemoryMap;
|
||||||
SIZE_T DescriptorCount;
|
SIZE_T DescriptorCount;
|
||||||
PUCHAR VirtualAddress;
|
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
SIZE_T Index;
|
SIZE_T Index;
|
||||||
|
|
||||||
/* Set virtual address as specified in argument */
|
/* Set virtual address as specified in argument */
|
||||||
VirtualAddress = (PUCHAR)*MemoryMapAddress;
|
VirtualAddress = (ULONGLONG)*BaseAddress;
|
||||||
|
|
||||||
/* Check if custom memory type routine is specified */
|
/* Check if custom memory type routine is specified */
|
||||||
if(GetMemoryTypeRoutine == NULLPTR)
|
if(GetMemoryTypeRoutine == NULLPTR)
|
||||||
@@ -367,8 +371,37 @@ Memory::MapEfiMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
|
|||||||
/* Iterate through all descriptors from the memory map */
|
/* Iterate through all descriptors from the memory map */
|
||||||
for(Index = 0; Index < DescriptorCount; Index++)
|
for(Index = 0; Index < DescriptorCount; Index++)
|
||||||
{
|
{
|
||||||
/* Make sure descriptor does not start beyond lowest physical page */
|
/* Check page map level */
|
||||||
if(Descriptor->PhysicalStart <= MAXUINT_PTR)
|
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 */
|
/* Skip EFI reserved memory */
|
||||||
if(Descriptor->Type == EfiReservedMemoryType)
|
if(Descriptor->Type == EfiReservedMemoryType)
|
||||||
@@ -378,25 +411,6 @@ Memory::MapEfiMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if preparing page map level 2 (non-PAE i686) */
|
|
||||||
if(PageMap->PageMapLevel == 2)
|
|
||||||
{
|
|
||||||
/* Check if physical address starts beyond 4GB */
|
|
||||||
if(Descriptor->PhysicalStart > 0xFFFFFFFF)
|
|
||||||
{
|
|
||||||
/* Go to the next descriptor */
|
|
||||||
Descriptor = (PEFI_MEMORY_DESCRIPTOR)((PUCHAR)Descriptor + MemoryMap->DescriptorSize);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check if memory descriptor exceeds the lowest physical page */
|
|
||||||
if(Descriptor->PhysicalStart + (Descriptor->NumberOfPages << EFI_PAGE_SHIFT) > MAXULONG)
|
|
||||||
{
|
|
||||||
/* Truncate memory descriptor to the 4GB */
|
|
||||||
Descriptor->NumberOfPages = (((ULONGLONG)MAXULONG + 1) - Descriptor->PhysicalStart) >> EFI_PAGE_SHIFT;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Convert EFI memory type into XTLDR memory type */
|
/* Convert EFI memory type into XTLDR memory type */
|
||||||
MemoryType = GetMemoryTypeRoutine((EFI_MEMORY_TYPE)Descriptor->Type);
|
MemoryType = GetMemoryTypeRoutine((EFI_MEMORY_TYPE)Descriptor->Type);
|
||||||
|
|
||||||
@@ -404,22 +418,32 @@ Memory::MapEfiMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
|
|||||||
if(MemoryType == LoaderFirmwareTemporary)
|
if(MemoryType == LoaderFirmwareTemporary)
|
||||||
{
|
{
|
||||||
/* Map EFI firmware code */
|
/* Map EFI firmware code */
|
||||||
Status = MapVirtualMemory(PageMap, (PVOID)Descriptor->PhysicalStart,
|
Status = MapVirtualMemory(PageMap, Descriptor->PhysicalStart,
|
||||||
(PVOID)Descriptor->PhysicalStart, Descriptor->NumberOfPages, MemoryType);
|
Descriptor->PhysicalStart, Descriptor->NumberOfPages, MemoryType);
|
||||||
}
|
}
|
||||||
else if(MemoryType != LoaderFree)
|
else if(MemoryType != LoaderFree)
|
||||||
{
|
{
|
||||||
/* Add any non-free memory mapping */
|
/* Check mapping strategy */
|
||||||
Status = MapVirtualMemory(PageMap, VirtualAddress, (PVOID)Descriptor->PhysicalStart,
|
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);
|
Descriptor->NumberOfPages, MemoryType);
|
||||||
|
|
||||||
/* Calculate next valid virtual address */
|
/* Update virtual address */
|
||||||
VirtualAddress += Descriptor->NumberOfPages * EFI_PAGE_SIZE;
|
VirtualAddress = VirtualAddress + (Descriptor->NumberOfPages * MM_PAGE_SIZE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Map all other memory as loader free */
|
/* Map all other memory as loader free */
|
||||||
Status = MapVirtualMemory(PageMap, NULLPTR, (PVOID)Descriptor->PhysicalStart,
|
Status = MapVirtualMemory(PageMap, (ULONGLONG)NULLPTR, Descriptor->PhysicalStart,
|
||||||
Descriptor->NumberOfPages, LoaderFree);
|
Descriptor->NumberOfPages, LoaderFree);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -436,7 +460,7 @@ Memory::MapEfiMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Always map first page */
|
/* 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)
|
if(Status != STATUS_EFI_SUCCESS)
|
||||||
{
|
{
|
||||||
/* Mapping failed */
|
/* Mapping failed */
|
||||||
@@ -444,7 +468,7 @@ Memory::MapEfiMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Map BIOS ROM and VRAM */
|
/* 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)
|
if(Status != STATUS_EFI_SUCCESS)
|
||||||
{
|
{
|
||||||
/* Mapping failed */
|
/* Mapping failed */
|
||||||
@@ -452,7 +476,7 @@ Memory::MapEfiMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Store next valid virtual address and return success */
|
/* Store next valid virtual address and return success */
|
||||||
*MemoryMapAddress = VirtualAddress;
|
*BaseAddress = (PVOID)VirtualAddress;
|
||||||
return STATUS_EFI_SUCCESS;
|
return STATUS_EFI_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -481,13 +505,13 @@ Memory::MapEfiMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
|
|||||||
XTCDECL
|
XTCDECL
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
Memory::MapVirtualMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
|
Memory::MapVirtualMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
|
||||||
IN PVOID VirtualAddress,
|
IN ULONGLONG VirtualAddress,
|
||||||
IN PVOID PhysicalAddress,
|
IN ULONGLONG PhysicalAddress,
|
||||||
IN ULONGLONG NumberOfPages,
|
IN ULONGLONG NumberOfPages,
|
||||||
IN LOADER_MEMORY_TYPE MemoryType)
|
IN LOADER_MEMORY_TYPE MemoryType)
|
||||||
{
|
{
|
||||||
PXTBL_MEMORY_MAPPING Mapping1, Mapping2, Mapping3;
|
PXTBL_MEMORY_MAPPING Mapping1, Mapping2, Mapping3;
|
||||||
PVOID PhysicalAddressEnd, PhysicalAddress2End;
|
ULONGLONG PhysicalAddressEnd, PhysicalAddress2End;
|
||||||
PLIST_ENTRY ListEntry, MappingListEntry;
|
PLIST_ENTRY ListEntry, MappingListEntry;
|
||||||
SIZE_T NumberOfMappedPages;
|
SIZE_T NumberOfMappedPages;
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
@@ -507,7 +531,7 @@ Memory::MapVirtualMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
|
|||||||
Mapping1->MemoryType = MemoryType;
|
Mapping1->MemoryType = MemoryType;
|
||||||
|
|
||||||
/* Calculate the end of the physical address */
|
/* Calculate the end of the physical address */
|
||||||
PhysicalAddressEnd = (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 */
|
/* Iterate through all the mappings already set to insert new mapping at the correct place */
|
||||||
ListEntry = PageMap->MemoryMap.Flink;
|
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 */
|
/* Take a mapping from the list and calculate its end of physical address */
|
||||||
Mapping2 = CONTAIN_RECORD(ListEntry, XTBL_MEMORY_MAPPING, ListEntry);
|
Mapping2 = CONTAIN_RECORD(ListEntry, XTBL_MEMORY_MAPPING, ListEntry);
|
||||||
PhysicalAddress2End = (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 */
|
/* Check if new mapping is a subset of an existing mapping */
|
||||||
if(Mapping1->PhysicalAddress >= Mapping2->PhysicalAddress && PhysicalAddressEnd <= PhysicalAddress2End)
|
if(Mapping1->PhysicalAddress >= Mapping2->PhysicalAddress && PhysicalAddressEnd <= PhysicalAddress2End)
|
||||||
@@ -523,7 +547,8 @@ Memory::MapVirtualMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
|
|||||||
/* Make sure it's memory type is the same */
|
/* Make sure it's memory type is the same */
|
||||||
if(Mapping1->MemoryType == Mapping2->MemoryType)
|
if(Mapping1->MemoryType == Mapping2->MemoryType)
|
||||||
{
|
{
|
||||||
/* It is already mapped */
|
/* Free the unused mapping structure and return success */
|
||||||
|
FreePool(Mapping1);
|
||||||
return STATUS_EFI_SUCCESS;
|
return STATUS_EFI_SUCCESS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -539,7 +564,7 @@ Memory::MapVirtualMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Calculate number of pages for this mapping */
|
/* Calculate number of pages for this mapping */
|
||||||
NumberOfMappedPages = ((PUCHAR)PhysicalAddress2End - (PUCHAR)PhysicalAddressEnd) / EFI_PAGE_SIZE;
|
NumberOfMappedPages = (PhysicalAddress2End - PhysicalAddressEnd) / EFI_PAGE_SIZE;
|
||||||
if(NumberOfMappedPages > 0)
|
if(NumberOfMappedPages > 0)
|
||||||
{
|
{
|
||||||
/* Pages associated to the mapping, allocate memory for it */
|
/* Pages associated to the mapping, allocate memory for it */
|
||||||
@@ -550,18 +575,21 @@ Memory::MapVirtualMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
|
|||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set mapping fields and insert it on the top */
|
/* Set mapping fields */
|
||||||
Mapping3->PhysicalAddress = (PUCHAR)PhysicalAddressEnd + 1;
|
Mapping3->PhysicalAddress = PhysicalAddressEnd + 1;
|
||||||
Mapping3->VirtualAddress = NULLPTR;
|
Mapping3->VirtualAddress = (ULONGLONG)NULLPTR;
|
||||||
Mapping3->NumberOfPages = NumberOfMappedPages;
|
Mapping3->NumberOfPages = NumberOfMappedPages;
|
||||||
Mapping3->MemoryType = Mapping2->MemoryType;
|
Mapping3->MemoryType = Mapping2->MemoryType;
|
||||||
|
|
||||||
|
/* Insert new mapping in front of the list and increase page map size */
|
||||||
RTL::LinkedList::InsertHeadList(&Mapping2->ListEntry, &Mapping3->ListEntry);
|
RTL::LinkedList::InsertHeadList(&Mapping2->ListEntry, &Mapping3->ListEntry);
|
||||||
|
PageMap->MapSize++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Calculate number of pages and the end of the physical address */
|
/* Calculate number of pages and the end of the physical address */
|
||||||
Mapping2->NumberOfPages = ((PUCHAR)PhysicalAddressEnd + 1 -
|
Mapping2->NumberOfPages = ((PUCHAR)PhysicalAddressEnd + 1 -
|
||||||
(PUCHAR)Mapping2->PhysicalAddress) / EFI_PAGE_SIZE;
|
(PUCHAR)Mapping2->PhysicalAddress) / EFI_PAGE_SIZE;
|
||||||
PhysicalAddress2End = (PVOID)((ULONG_PTR)Mapping2->PhysicalAddress + (Mapping2->NumberOfPages * EFI_PAGE_SIZE) - 1);
|
PhysicalAddress2End = Mapping2->PhysicalAddress + (Mapping2->NumberOfPages * EFI_PAGE_SIZE) - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if they overlap */
|
/* Check if they overlap */
|
||||||
@@ -586,18 +614,21 @@ Memory::MapVirtualMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
|
|||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set mapping fields and insert it on the top */
|
/* Set mapping fields */
|
||||||
Mapping3->PhysicalAddress = Mapping1->PhysicalAddress;
|
Mapping3->PhysicalAddress = Mapping1->PhysicalAddress;
|
||||||
Mapping3->VirtualAddress = NULLPTR;
|
Mapping3->VirtualAddress = (ULONGLONG)NULLPTR;
|
||||||
Mapping3->NumberOfPages = NumberOfMappedPages;
|
Mapping3->NumberOfPages = NumberOfMappedPages;
|
||||||
Mapping3->MemoryType = Mapping2->MemoryType;
|
Mapping3->MemoryType = Mapping2->MemoryType;
|
||||||
|
|
||||||
|
/* Insert new mapping in front of the list and increase page map size */
|
||||||
RTL::LinkedList::InsertHeadList(&Mapping2->ListEntry, &Mapping3->ListEntry);
|
RTL::LinkedList::InsertHeadList(&Mapping2->ListEntry, &Mapping3->ListEntry);
|
||||||
|
PageMap->MapSize++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Calculate number of pages and the end of the physical address */
|
/* Calculate number of pages and the end of the physical address */
|
||||||
Mapping2->NumberOfPages = ((PUCHAR)Mapping1->PhysicalAddress -
|
Mapping2->NumberOfPages = ((PUCHAR)Mapping1->PhysicalAddress -
|
||||||
(PUCHAR)Mapping2->PhysicalAddress) / EFI_PAGE_SIZE;
|
(PUCHAR)Mapping2->PhysicalAddress) / EFI_PAGE_SIZE;
|
||||||
PhysicalAddress2End = (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 */
|
/* Check if mapping is really needed */
|
||||||
@@ -619,15 +650,19 @@ Memory::MapVirtualMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
|
|||||||
Status = FreePool(Mapping2);
|
Status = FreePool(Mapping2);
|
||||||
ListEntry = MappingListEntry;
|
ListEntry = MappingListEntry;
|
||||||
|
|
||||||
/* Go to the next mapping */
|
/* Decrease page map size and go to the next mapping */
|
||||||
|
PageMap->MapSize--;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Determine physical address order */
|
/* Determine physical address order */
|
||||||
if(Mapping2->PhysicalAddress > Mapping1->PhysicalAddress)
|
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);
|
RTL::LinkedList::InsertHeadList(Mapping2->ListEntry.Blink, &Mapping1->ListEntry);
|
||||||
|
PageMap->MapSize++;
|
||||||
|
|
||||||
|
/* Return success */
|
||||||
return STATUS_EFI_SUCCESS;
|
return STATUS_EFI_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -635,7 +670,7 @@ Memory::MapVirtualMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
|
|||||||
ListEntry = ListEntry->Flink;
|
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);
|
RTL::LinkedList::InsertTailList(&PageMap->MemoryMap, &Mapping1->ListEntry);
|
||||||
PageMap->MapSize++;
|
PageMap->MapSize++;
|
||||||
|
|
||||||
|
|||||||
@@ -729,11 +729,11 @@ PeCoff::RelocateLoadedImage(IN PPECOFF_IMAGE_CONTEXT Image)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Check if loaded 32-bit PE32 image should be relocated */
|
|
||||||
/* Set relocation data directory and image base address */
|
/* Set relocation data directory and image base address */
|
||||||
DataDirectory = &Image->PeHeader->OptionalHeader32.DataDirectory[PECOFF_IMAGE_DIRECTORY_ENTRY_BASERELOC];
|
DataDirectory = &Image->PeHeader->OptionalHeader32.DataDirectory[PECOFF_IMAGE_DIRECTORY_ENTRY_BASERELOC];
|
||||||
ImageBase = Image->PeHeader->OptionalHeader32.ImageBase;
|
ImageBase = Image->PeHeader->OptionalHeader32.ImageBase;
|
||||||
|
|
||||||
|
/* Check if loaded 32-bit PE32 image should be relocated */
|
||||||
if(Image->PeHeader->OptionalHeader32.NumberOfRvaAndSizes <= PECOFF_IMAGE_DIRECTORY_ENTRY_BASERELOC ||
|
if(Image->PeHeader->OptionalHeader32.NumberOfRvaAndSizes <= PECOFF_IMAGE_DIRECTORY_ENTRY_BASERELOC ||
|
||||||
DataDirectory->VirtualAddress == 0 || DataDirectory->Size < sizeof(PECOFF_IMAGE_BASE_RELOCATION))
|
DataDirectory->VirtualAddress == 0 || DataDirectory->Size < sizeof(PECOFF_IMAGE_BASE_RELOCATION))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -10,6 +10,49 @@
|
|||||||
#include <xtos.hh>
|
#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.
|
* Determines the appropriate paging level (PML) for the AMD64 architecture.
|
||||||
*
|
*
|
||||||
@@ -76,24 +119,6 @@ Xtos::EnablePaging(IN PXTBL_PAGE_MAPPING PageMap)
|
|||||||
ULONG_PTR TrampolineSize;
|
ULONG_PTR TrampolineSize;
|
||||||
PVOID TrampolineCode;
|
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 */
|
/* Check the configured page map level to set the LA57 state accordingly */
|
||||||
if(PageMap->PageMapLevel == 5)
|
if(PageMap->PageMapLevel == 5)
|
||||||
{
|
{
|
||||||
@@ -173,6 +198,7 @@ Xtos::MapHardwareMemoryPool(IN PXTBL_PAGE_MAPPING PageMap)
|
|||||||
PHARDWARE_PTE P5eBase, PdeBase, PpeBase, PxeBase;
|
PHARDWARE_PTE P5eBase, PdeBase, PpeBase, PxeBase;
|
||||||
EFI_PHYSICAL_ADDRESS Address;
|
EFI_PHYSICAL_ADDRESS Address;
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
|
ULONG Index;
|
||||||
|
|
||||||
if(PageMap->PageMapLevel == 5)
|
if(PageMap->PageMapLevel == 5)
|
||||||
{
|
{
|
||||||
@@ -190,6 +216,9 @@ Xtos::MapHardwareMemoryPool(IN PXTBL_PAGE_MAPPING PageMap)
|
|||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Map hardware memory */
|
||||||
|
XtLdrProtocol->Memory.MapVirtualMemory(PageMap, (ULONGLONG)NULLPTR, Address, 1, LoaderMemoryData);
|
||||||
|
|
||||||
/* Zero fill memory used by P5E */
|
/* Zero fill memory used by P5E */
|
||||||
XtLdrProtocol->Memory.ZeroMemory((PVOID)Address, EFI_PAGE_SIZE);
|
XtLdrProtocol->Memory.ZeroMemory((PVOID)Address, EFI_PAGE_SIZE);
|
||||||
|
|
||||||
@@ -224,6 +253,9 @@ Xtos::MapHardwareMemoryPool(IN PXTBL_PAGE_MAPPING PageMap)
|
|||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Map hardware memory */
|
||||||
|
XtLdrProtocol->Memory.MapVirtualMemory(PageMap, (ULONGLONG)NULLPTR, Address, 1, LoaderMemoryData);
|
||||||
|
|
||||||
/* Zero fill memory used by PXE */
|
/* Zero fill memory used by PXE */
|
||||||
XtLdrProtocol->Memory.ZeroMemory((PVOID)Address, EFI_PAGE_SIZE);
|
XtLdrProtocol->Memory.ZeroMemory((PVOID)Address, EFI_PAGE_SIZE);
|
||||||
|
|
||||||
@@ -252,6 +284,9 @@ Xtos::MapHardwareMemoryPool(IN PXTBL_PAGE_MAPPING PageMap)
|
|||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Map hardware memory */
|
||||||
|
XtLdrProtocol->Memory.MapVirtualMemory(PageMap, (ULONGLONG)NULLPTR, Address, 1, LoaderMemoryData);
|
||||||
|
|
||||||
/* Zero fill memory used by PPE */
|
/* Zero fill memory used by PPE */
|
||||||
XtLdrProtocol->Memory.ZeroMemory((PVOID)Address, EFI_PAGE_SIZE);
|
XtLdrProtocol->Memory.ZeroMemory((PVOID)Address, EFI_PAGE_SIZE);
|
||||||
|
|
||||||
@@ -270,7 +305,7 @@ Xtos::MapHardwareMemoryPool(IN PXTBL_PAGE_MAPPING PageMap)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Loop through 2 PDE entries */
|
/* Loop through 2 PDE entries */
|
||||||
for(UINT Index = 0 ; Index < 2 ; Index++)
|
for(Index = 0 ; Index < 2 ; Index++)
|
||||||
{
|
{
|
||||||
/* Check if PDE entry already exists */
|
/* Check if PDE entry already exists */
|
||||||
if(!PdeBase[((MM_HARDWARE_VA_START >> MM_PDI_SHIFT) & 0x1FF) + Index].Valid)
|
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;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Map hardware memory */
|
||||||
|
XtLdrProtocol->Memory.MapVirtualMemory(PageMap, (ULONGLONG)NULLPTR, Address, 1, LoaderMemoryData);
|
||||||
|
|
||||||
/* Zero fill memory used by PDE */
|
/* Zero fill memory used by PDE */
|
||||||
XtLdrProtocol->Memory.ZeroMemory((PVOID)Address, EFI_PAGE_SIZE);
|
XtLdrProtocol->Memory.ZeroMemory((PVOID)Address, EFI_PAGE_SIZE);
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,62 @@
|
|||||||
#include <xtos.hh>
|
#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.
|
* Determines the appropriate paging level (PML) for the i686 architecture.
|
||||||
*
|
*
|
||||||
@@ -60,24 +116,6 @@ Xtos::EnablePaging(IN PXTBL_PAGE_MAPPING PageMap)
|
|||||||
{
|
{
|
||||||
EFI_STATUS Status;
|
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 */
|
/* Exit EFI Boot Services */
|
||||||
XtLdrProtocol->Debug.Print(L"Exiting EFI boot services\n");
|
XtLdrProtocol->Debug.Print(L"Exiting EFI boot services\n");
|
||||||
Status = XtLdrProtocol->Utils.ExitBootServices();
|
Status = XtLdrProtocol->Utils.ExitBootServices();
|
||||||
@@ -145,6 +183,9 @@ Xtos::MapHardwareMemoryPool(IN PXTBL_PAGE_MAPPING PageMap)
|
|||||||
/* Zero fill allocated memory */
|
/* Zero fill allocated memory */
|
||||||
XtLdrProtocol->Memory.ZeroMemory((PVOID)Address, EFI_PAGE_SIZE);
|
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) */
|
/* Check if PAE is enabled (3-level paging) */
|
||||||
if(PageMap->PageMapLevel == 3)
|
if(PageMap->PageMapLevel == 3)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -38,7 +38,9 @@ class Xtos
|
|||||||
IN PVOID PhysicalAddress,
|
IN PVOID PhysicalAddress,
|
||||||
IN UINT NumberOfPages,
|
IN UINT NumberOfPages,
|
||||||
IN LOADER_MEMORY_TYPE MemoryType);
|
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 LOADER_MEMORY_TYPE ConvertEfiMemoryType(IN EFI_MEMORY_TYPE EfiMemoryType);
|
||||||
|
STATIC XTCDECL BOOLEAN DetermineMappingStrategy();
|
||||||
STATIC XTCDECL ULONG DeterminePagingLevel(IN CONST PWCHAR Parameters);
|
STATIC XTCDECL ULONG DeterminePagingLevel(IN CONST PWCHAR Parameters);
|
||||||
STATIC XTCDECL EFI_STATUS EnablePaging(IN PXTBL_PAGE_MAPPING PageMap);
|
STATIC XTCDECL EFI_STATUS EnablePaging(IN PXTBL_PAGE_MAPPING PageMap);
|
||||||
STATIC XTCDECL VOID GetDisplayInformation(OUT PSYSTEM_RESOURCE_FRAMEBUFFER FrameBufferResource,
|
STATIC XTCDECL VOID GetDisplayInformation(OUT PSYSTEM_RESOURCE_FRAMEBUFFER FrameBufferResource,
|
||||||
@@ -46,10 +48,13 @@ class Xtos
|
|||||||
IN PULONG_PTR FrameBufferSize,
|
IN PULONG_PTR FrameBufferSize,
|
||||||
IN PXTBL_FRAMEBUFFER_MODE_INFORMATION FrameBufferModeInfo);
|
IN PXTBL_FRAMEBUFFER_MODE_INFORMATION FrameBufferModeInfo);
|
||||||
STATIC XTCDECL EFI_STATUS GetMemoryDescriptorList(IN PXTBL_PAGE_MAPPING PageMap,
|
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);
|
OUT PLIST_ENTRY MemoryDescriptorList);
|
||||||
STATIC XTCDECL EFI_STATUS GetSystemResourcesList(IN PXTBL_PAGE_MAPPING PageMap,
|
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);
|
OUT PLIST_ENTRY SystemResourcesList);
|
||||||
STATIC XTCDECL EFI_STATUS GetVirtualAddress(IN PLIST_ENTRY MemoryMappings,
|
STATIC XTCDECL EFI_STATUS GetVirtualAddress(IN PLIST_ENTRY MemoryMappings,
|
||||||
IN PVOID PhysicalAddress,
|
IN PVOID PhysicalAddress,
|
||||||
|
|||||||
@@ -191,56 +191,52 @@ Xtos::GetDisplayInformation(OUT PSYSTEM_RESOURCE_FRAMEBUFFER FrameBufferResource
|
|||||||
XTCDECL
|
XTCDECL
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
Xtos::GetMemoryDescriptorList(IN PXTBL_PAGE_MAPPING PageMap,
|
Xtos::GetMemoryDescriptorList(IN PXTBL_PAGE_MAPPING PageMap,
|
||||||
IN PVOID *VirtualAddress,
|
IN EFI_PHYSICAL_ADDRESS PhysicalBase,
|
||||||
|
IN PVOID VirtualBase,
|
||||||
OUT PLIST_ENTRY MemoryDescriptorList)
|
OUT PLIST_ENTRY MemoryDescriptorList)
|
||||||
{
|
{
|
||||||
EFI_PHYSICAL_ADDRESS Address;
|
PLOADER_MEMORY_DESCRIPTOR Descriptor;
|
||||||
EFI_STATUS Status;
|
PXTBL_MEMORY_MAPPING MemoryMapping;
|
||||||
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;
|
|
||||||
|
|
||||||
PLIST_ENTRY ListEntry;
|
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;
|
ListEntry = PageMap->MemoryMap.Flink;
|
||||||
|
|
||||||
|
/* Iterate through the internal memory map and populate the loader descriptor list */
|
||||||
while(ListEntry != &PageMap->MemoryMap)
|
while(ListEntry != &PageMap->MemoryMap)
|
||||||
{
|
{
|
||||||
PXTBL_MEMORY_MAPPING MemoryMapping = CONTAIN_RECORD(ListEntry, XTBL_MEMORY_MAPPING, ListEntry);
|
/* Retrieve the internal memory mapping record from the current list entry */
|
||||||
PLOADER_MEMORY_DESCRIPTOR MemoryDescriptor = (PLOADER_MEMORY_DESCRIPTOR)Address;
|
MemoryMapping = CONTAIN_RECORD(ListEntry, XTBL_MEMORY_MAPPING, ListEntry);
|
||||||
|
|
||||||
MemoryDescriptor->MemoryType = MemoryMapping->MemoryType;
|
/* Transfer memory type and address information to the kernel descriptor */
|
||||||
MemoryDescriptor->BasePage = (UINT_PTR)MemoryMapping->PhysicalAddress / EFI_PAGE_SIZE;
|
Descriptor->MemoryType = MemoryMapping->MemoryType;
|
||||||
MemoryDescriptor->PageCount = MemoryMapping->NumberOfPages;
|
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;
|
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;
|
return STATUS_EFI_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
XTCDECL
|
XTCDECL
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
Xtos::GetSystemResourcesList(IN PXTBL_PAGE_MAPPING PageMap,
|
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)
|
OUT PLIST_ENTRY SystemResourcesList)
|
||||||
{
|
{
|
||||||
XTSTATUS Status;
|
XTSTATUS Status;
|
||||||
@@ -251,39 +247,18 @@ Xtos::GetSystemResourcesList(IN PXTBL_PAGE_MAPPING PageMap,
|
|||||||
PXTBL_FRAMEBUFFER_PROTOCOL FrameBufProtocol;
|
PXTBL_FRAMEBUFFER_PROTOCOL FrameBufProtocol;
|
||||||
XTBL_FRAMEBUFFER_MODE_INFORMATION FbModeInfo;
|
XTBL_FRAMEBUFFER_MODE_INFORMATION FbModeInfo;
|
||||||
EFI_PHYSICAL_ADDRESS FbAddress;
|
EFI_PHYSICAL_ADDRESS FbAddress;
|
||||||
|
EFI_PHYSICAL_ADDRESS OriginalPhysicalBase;
|
||||||
ULONG_PTR FbSize;
|
ULONG_PTR FbSize;
|
||||||
UINT FrameBufferPages;
|
|
||||||
PSYSTEM_RESOURCE_FRAMEBUFFER FrameBufferResource;
|
PSYSTEM_RESOURCE_FRAMEBUFFER FrameBufferResource;
|
||||||
PSYSTEM_RESOURCE_ACPI AcpiResource;
|
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));
|
/* Save original physical base */
|
||||||
|
OriginalPhysicalBase = PhysicalBase;
|
||||||
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;
|
|
||||||
|
|
||||||
|
AcpiResource = (PSYSTEM_RESOURCE_ACPI)PhysicalBase;
|
||||||
XtLdrProtocol->Memory.ZeroMemory(AcpiResource, sizeof(SYSTEM_RESOURCE_ACPI));
|
XtLdrProtocol->Memory.ZeroMemory(AcpiResource, sizeof(SYSTEM_RESOURCE_ACPI));
|
||||||
|
|
||||||
/* Load FrameBuffer protocol */
|
/* Load ACPI protocol */
|
||||||
Status = XtLdrProtocol->Protocol.Open(&ProtocolHandle, (PVOID*)&AcpiProtocol, &AcpiGuid);
|
Status = XtLdrProtocol->Protocol.Open(&ProtocolHandle, (PVOID*)&AcpiProtocol, &AcpiGuid);
|
||||||
if(Status != STATUS_EFI_SUCCESS)
|
if(Status != STATUS_EFI_SUCCESS)
|
||||||
{
|
{
|
||||||
@@ -302,13 +277,11 @@ Xtos::GetSystemResourcesList(IN PXTBL_PAGE_MAPPING PageMap,
|
|||||||
|
|
||||||
XtLdrProtocol->LinkedList.InsertTail(SystemResourcesList, &AcpiResource->Header.ListEntry);
|
XtLdrProtocol->LinkedList.InsertTail(SystemResourcesList, &AcpiResource->Header.ListEntry);
|
||||||
|
|
||||||
/* Close FrameBuffer protocol */
|
/* Close ACPI protocol */
|
||||||
XtLdrProtocol->Protocol.Close(&ProtocolHandle, &FrameBufGuid);
|
XtLdrProtocol->Protocol.Close(&ProtocolHandle, &AcpiGuid);
|
||||||
|
|
||||||
Address = Address + sizeof(SYSTEM_RESOURCE_ACPI);
|
|
||||||
|
|
||||||
FrameBufferResource = (PSYSTEM_RESOURCE_FRAMEBUFFER)Address;
|
|
||||||
|
|
||||||
|
PhysicalBase = PhysicalBase + sizeof(SYSTEM_RESOURCE_ACPI);
|
||||||
|
FrameBufferResource = (PSYSTEM_RESOURCE_FRAMEBUFFER)PhysicalBase;
|
||||||
XtLdrProtocol->Memory.ZeroMemory(FrameBufferResource, sizeof(SYSTEM_RESOURCE_FRAMEBUFFER));
|
XtLdrProtocol->Memory.ZeroMemory(FrameBufferResource, sizeof(SYSTEM_RESOURCE_FRAMEBUFFER));
|
||||||
|
|
||||||
/* Load FrameBuffer protocol */
|
/* Load FrameBuffer protocol */
|
||||||
@@ -329,26 +302,16 @@ Xtos::GetSystemResourcesList(IN PXTBL_PAGE_MAPPING PageMap,
|
|||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Calculate pages needed to map framebuffer */
|
/* Assign the pre-mapped virtual address to the resource block */
|
||||||
FrameBufferPages = EFI_SIZE_TO_PAGES(FbSize);
|
FrameBufferResource->Header.VirtualAddress = FrameBufferVirtualBase;
|
||||||
|
|
||||||
/* 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 */
|
|
||||||
XtLdrProtocol->Protocol.Close(&ProtocolHandle, &FrameBufGuid);
|
XtLdrProtocol->Protocol.Close(&ProtocolHandle, &FrameBufGuid);
|
||||||
|
|
||||||
*VirtualAddress = (PUINT8)*VirtualAddress + (FrameBufferPages * EFI_PAGE_SIZE);
|
|
||||||
|
|
||||||
XtLdrProtocol->LinkedList.InsertTail(SystemResourcesList, &FrameBufferResource->Header.ListEntry);
|
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;
|
return STATUS_EFI_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -389,7 +352,7 @@ Xtos::InitializeApicBase(IN PXTBL_PAGE_MAPPING PageMap)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Map APIC base address */
|
/* 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;
|
return STATUS_EFI_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -409,34 +372,100 @@ Xtos::InitializeApicBase(IN PXTBL_PAGE_MAPPING PageMap)
|
|||||||
XTCDECL
|
XTCDECL
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
Xtos::InitializeLoaderBlock(IN PXTBL_PAGE_MAPPING PageMap,
|
Xtos::InitializeLoaderBlock(IN PXTBL_PAGE_MAPPING PageMap,
|
||||||
IN PVOID *VirtualAddress,
|
IN OUT PVOID *VirtualAddress,
|
||||||
IN PXTBL_BOOT_PARAMETERS Parameters)
|
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;
|
PKERNEL_INITIALIZATION_BLOCK LoaderBlock;
|
||||||
EFI_PHYSICAL_ADDRESS Address;
|
EFI_HANDLE ProtocolHandle;
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
UINT BlockPages;
|
ULONG_PTR FbSize;
|
||||||
UINT ParametersSize;
|
|
||||||
|
EFI_GUID FrameBufGuid = XT_FRAMEBUFFER_PROTOCOL_GUID;
|
||||||
|
|
||||||
|
/* Initialize Framebuffer information */
|
||||||
|
FbPhysicalAddress = 0;
|
||||||
|
FbSize = 0;
|
||||||
|
FbVirtualAddress = NULLPTR;
|
||||||
|
FbPages = 0;
|
||||||
|
|
||||||
/* Calculate size of parameters */
|
/* Calculate size of parameters */
|
||||||
ParametersSize = (XtLdrProtocol->WideString.Length(Parameters->Parameters, 0) + 1) * sizeof(WCHAR);
|
ParametersSize = (XtLdrProtocol->WideString.Length(Parameters->Parameters, 0) + 1) * sizeof(WCHAR);
|
||||||
|
|
||||||
/* Calculate number of pages needed for initialization block */
|
/* Calculate number of pages needed for initialization block */
|
||||||
BlockPages = EFI_SIZE_TO_PAGES(sizeof(KERNEL_INITIALIZATION_BLOCK) + ParametersSize);
|
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 */
|
/* Query Framebuffer size for allocation */
|
||||||
Status = XtLdrProtocol->Memory.AllocatePages(AllocateAnyPages, BlockPages, &Address);
|
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)
|
if(Status != STATUS_EFI_SUCCESS)
|
||||||
{
|
{
|
||||||
/* Memory allocation failure */
|
/* Memory allocation failure, return status code */
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Initialize and zero-fill kernel initialization block */
|
/* Allocate memory for the system resources data structures */
|
||||||
LoaderBlock = (PKERNEL_INITIALIZATION_BLOCK)(UINT_PTR)Address;
|
Status = XtLdrProtocol->Memory.AllocatePages(AllocateAnyPages, ResourcesPages, &PhysicalResources);
|
||||||
XtLdrProtocol->Memory.ZeroMemory(LoaderBlock, sizeof(KERNEL_INITIALIZATION_BLOCK) + ParametersSize);
|
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 */
|
/* 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->BlockSize = sizeof(KERNEL_INITIALIZATION_BLOCK);
|
||||||
LoaderBlock->BlockVersion = INITIALIZATION_BLOCK_VERSION;
|
LoaderBlock->BlockVersion = INITIALIZATION_BLOCK_VERSION;
|
||||||
LoaderBlock->ProtocolVersion = BOOT_PROTOCOL_VERSION;
|
LoaderBlock->ProtocolVersion = BOOT_PROTOCOL_VERSION;
|
||||||
@@ -450,24 +479,33 @@ Xtos::InitializeLoaderBlock(IN PXTBL_PAGE_MAPPING PageMap,
|
|||||||
LoaderBlock->FirmwareInformation.EfiFirmware.EfiRuntimeServices = NULLPTR;
|
LoaderBlock->FirmwareInformation.EfiFirmware.EfiRuntimeServices = NULLPTR;
|
||||||
|
|
||||||
/* Copy parameters to kernel initialization block */
|
/* 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)),
|
XtLdrProtocol->Memory.CopyMemory((PVOID)((UINT_PTR)LoaderBlock + sizeof(KERNEL_INITIALIZATION_BLOCK)),
|
||||||
Parameters->Parameters,
|
Parameters->Parameters, ParametersSize);
|
||||||
ParametersSize);
|
|
||||||
|
|
||||||
/* Map kernel initialization block */
|
/* Commit mappings */
|
||||||
XtLdrProtocol->Memory.MapVirtualMemory(PageMap, *VirtualAddress, (PVOID)LoaderBlock,
|
XtLdrProtocol->Memory.CommitPageMap(PageMap);
|
||||||
BlockPages, LoaderSystemBlock);
|
|
||||||
|
|
||||||
/* Calculate next valid virtual address */
|
|
||||||
*VirtualAddress = (PUINT8)*VirtualAddress + (BlockPages * EFI_PAGE_SIZE);
|
|
||||||
|
|
||||||
|
/* Initialize system resources list */
|
||||||
XtLdrProtocol->LinkedList.InitializeHead(&LoaderBlock->SystemResourcesListHead);
|
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 */
|
/* Initialize memory descriptor list */
|
||||||
XtLdrProtocol->LinkedList.InitializeHead(&LoaderBlock->MemoryDescriptorListHead);
|
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 success */
|
||||||
return STATUS_EFI_SUCCESS;
|
return STATUS_EFI_SUCCESS;
|
||||||
@@ -607,11 +645,12 @@ Xtos::RunBootSequence(IN PEFI_FILE_HANDLE BootDir,
|
|||||||
PXTBL_FRAMEBUFFER_PROTOCOL FrameBufProtocol;
|
PXTBL_FRAMEBUFFER_PROTOCOL FrameBufProtocol;
|
||||||
PPECOFF_IMAGE_CONTEXT ImageContext = NULLPTR;
|
PPECOFF_IMAGE_CONTEXT ImageContext = NULLPTR;
|
||||||
PEFI_LOADED_IMAGE_PROTOCOL ImageProtocol;
|
PEFI_LOADED_IMAGE_PROTOCOL ImageProtocol;
|
||||||
PVOID VirtualAddress, VirtualMemoryArea;
|
PVOID VirtualAddress;
|
||||||
PXT_ENTRY_POINT KernelEntryPoint;
|
PXT_ENTRY_POINT KernelEntryPoint;
|
||||||
EFI_HANDLE ProtocolHandle;
|
EFI_HANDLE ProtocolHandle;
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
XTBL_PAGE_MAPPING PageMap;
|
XTBL_PAGE_MAPPING PageMap;
|
||||||
|
BOOLEAN IdentityMapping;
|
||||||
|
|
||||||
/* Initialize XTOS startup sequence */
|
/* Initialize XTOS startup sequence */
|
||||||
XtLdrProtocol->Debug.Print(L"Initializing XTOS startup sequence\n");
|
XtLdrProtocol->Debug.Print(L"Initializing XTOS startup sequence\n");
|
||||||
@@ -628,19 +667,30 @@ Xtos::RunBootSequence(IN PEFI_FILE_HANDLE BootDir,
|
|||||||
/* Close FrameBuffer protocol */
|
/* Close FrameBuffer protocol */
|
||||||
XtLdrProtocol->Protocol.Close(&ProtocolHandle, &FrameBufGuid);
|
XtLdrProtocol->Protocol.Close(&ProtocolHandle, &FrameBufGuid);
|
||||||
|
|
||||||
|
/* Determine whether to use a sequential or an identity mapping strategy */
|
||||||
|
IdentityMapping = DetermineMappingStrategy();
|
||||||
|
|
||||||
/* Set base virtual memory area for the kernel mappings */
|
/* Set base virtual memory area for the kernel mappings */
|
||||||
VirtualMemoryArea = (PVOID)KSEG0_BASE;
|
VirtualAddress = (PVOID)(KSEG0_BASE);
|
||||||
VirtualAddress = (PVOID)(KSEG0_BASE + KSEG0_KERNEL_BASE);
|
|
||||||
|
|
||||||
/* Initialize virtual memory mappings */
|
/* Initialize virtual memory mappings */
|
||||||
XtLdrProtocol->Memory.InitializePageMap(&PageMap, DeterminePagingLevel(Parameters->Parameters), Size4K);
|
XtLdrProtocol->Memory.InitializePageMap(&PageMap, DeterminePagingLevel(Parameters->Parameters), Size4K);
|
||||||
|
|
||||||
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)
|
if(Status != STATUS_EFI_SUCCESS)
|
||||||
{
|
{
|
||||||
|
/* Mapping failed */
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Check mapping strategy */
|
||||||
|
if(IdentityMapping)
|
||||||
|
{
|
||||||
|
/* Adjust virtual address to skip the identity-mapped physical range */
|
||||||
|
VirtualAddress = (PVOID)((ULONGLONG)VirtualAddress + 0x800000000);
|
||||||
|
}
|
||||||
|
|
||||||
/* Load the kernel */
|
/* Load the kernel */
|
||||||
Status = LoadModule(BootDir, Parameters->KernelFile, VirtualAddress, LoaderSystemCode, &ImageContext);
|
Status = LoadModule(BootDir, Parameters->KernelFile, VirtualAddress, LoaderSystemCode, &ImageContext);
|
||||||
if(Status != STATUS_EFI_SUCCESS)
|
if(Status != STATUS_EFI_SUCCESS)
|
||||||
@@ -650,8 +700,8 @@ Xtos::RunBootSequence(IN PEFI_FILE_HANDLE BootDir,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Add kernel image memory mapping */
|
/* Add kernel image memory mapping */
|
||||||
Status = XtLdrProtocol->Memory.MapVirtualMemory(&PageMap, ImageContext->VirtualAddress,
|
Status = XtLdrProtocol->Memory.MapVirtualMemory(&PageMap, (ULONGLONG)ImageContext->VirtualAddress,
|
||||||
ImageContext->PhysicalAddress, ImageContext->ImagePages,
|
(ULONGLONG)ImageContext->PhysicalAddress, ImageContext->ImagePages,
|
||||||
LoaderSystemCode);
|
LoaderSystemCode);
|
||||||
if(Status != STATUS_EFI_SUCCESS)
|
if(Status != STATUS_EFI_SUCCESS)
|
||||||
{
|
{
|
||||||
@@ -670,6 +720,14 @@ Xtos::RunBootSequence(IN PEFI_FILE_HANDLE BootDir,
|
|||||||
return Status;
|
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 */
|
/* Store virtual address of kernel initialization block for future kernel call */
|
||||||
KernelParameters = (PKERNEL_INITIALIZATION_BLOCK)VirtualAddress;
|
KernelParameters = (PKERNEL_INITIALIZATION_BLOCK)VirtualAddress;
|
||||||
|
|
||||||
|
|||||||
@@ -1054,6 +1054,7 @@ Protocol::InstallXtLoaderProtocol()
|
|||||||
LoaderProtocol.Memory.AllocatePages = Memory::AllocatePages;
|
LoaderProtocol.Memory.AllocatePages = Memory::AllocatePages;
|
||||||
LoaderProtocol.Memory.AllocatePool = Memory::AllocatePool;
|
LoaderProtocol.Memory.AllocatePool = Memory::AllocatePool;
|
||||||
LoaderProtocol.Memory.BuildPageMap = Memory::BuildPageMap;
|
LoaderProtocol.Memory.BuildPageMap = Memory::BuildPageMap;
|
||||||
|
LoaderProtocol.Memory.CommitPageMap = Memory::CommitPageMap;
|
||||||
LoaderProtocol.Memory.CompareMemory = RTL::Memory::CompareMemory;
|
LoaderProtocol.Memory.CompareMemory = RTL::Memory::CompareMemory;
|
||||||
LoaderProtocol.Memory.CopyMemory = RTL::Memory::CopyMemory;
|
LoaderProtocol.Memory.CopyMemory = RTL::Memory::CopyMemory;
|
||||||
LoaderProtocol.Memory.FreePages = Memory::FreePages;
|
LoaderProtocol.Memory.FreePages = Memory::FreePages;
|
||||||
|
|||||||
@@ -236,6 +236,15 @@ BlStartXtLoader(IN EFI_HANDLE ImageHandle,
|
|||||||
PWCHAR Modules;
|
PWCHAR Modules;
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
|
|
||||||
|
/* Check if system is EFI-based and provided parameters are valid */
|
||||||
|
if(ImageHandle == NULLPTR || SystemTable == NULLPTR)
|
||||||
|
{
|
||||||
|
/* Invalid parameters, print error message using BIOS calls and hang */
|
||||||
|
BiosUtils::ClearScreen();
|
||||||
|
BiosUtils::Print(L"XTLDR requires EFI-based system!");
|
||||||
|
for(;;);
|
||||||
|
}
|
||||||
|
|
||||||
/* Initialize XTLDR and */
|
/* Initialize XTLDR and */
|
||||||
XtLoader::InitializeBootLoader(ImageHandle, SystemTable);
|
XtLoader::InitializeBootLoader(ImageHandle, SystemTable);
|
||||||
|
|
||||||
|
|||||||
@@ -1,2 +1,3 @@
|
|||||||
# Set base addresses for all modules
|
# Set base addresses for all modules
|
||||||
|
set(BASEADDRESS_XTLDR 0x000000000000F800)
|
||||||
set(BASEADDRESS_XTOSKRNL 0x0000000140000000)
|
set(BASEADDRESS_XTOSKRNL 0x0000000140000000)
|
||||||
|
|||||||
@@ -1,2 +1,3 @@
|
|||||||
# Set base addresses for all modules
|
# Set base addresses for all modules
|
||||||
|
set(BASEADDRESS_XTLDR 0x0000F800)
|
||||||
set(BASEADDRESS_XTOSKRNL 0x00400000)
|
set(BASEADDRESS_XTOSKRNL 0x00400000)
|
||||||
|
|||||||
@@ -64,11 +64,17 @@ function(compile_bootsector NAME SOURCE BASEADDR ENTRYPOINT)
|
|||||||
set(BINARY_NAME "${NAME}.bin")
|
set(BINARY_NAME "${NAME}.bin")
|
||||||
set(OBJECT_NAME "${NAME}.obj")
|
set(OBJECT_NAME "${NAME}.obj")
|
||||||
|
|
||||||
|
get_directory_property(DEFS COMPILE_DEFINITIONS)
|
||||||
|
foreach(def ${DEFS})
|
||||||
|
list(APPEND ASM_DEFS "-D${def}")
|
||||||
|
endforeach()
|
||||||
|
|
||||||
add_custom_command(
|
add_custom_command(
|
||||||
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${BINARY_NAME}
|
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${BINARY_NAME}
|
||||||
COMMAND ${CMAKE_ASM_COMPILER}
|
COMMAND ${CMAKE_ASM_COMPILER}
|
||||||
/nologo
|
/nologo
|
||||||
--target=i386-none-elf
|
--target=i386-none-elf
|
||||||
|
${ASM_DEFS}
|
||||||
-I${CMAKE_CURRENT_SOURCE_DIR}
|
-I${CMAKE_CURRENT_SOURCE_DIR}
|
||||||
/Fo${CMAKE_CURRENT_BINARY_DIR}/${OBJECT_NAME}
|
/Fo${CMAKE_CURRENT_BINARY_DIR}/${OBJECT_NAME}
|
||||||
-c -- ${SOURCE}
|
-c -- ${SOURCE}
|
||||||
|
|||||||
@@ -108,9 +108,6 @@
|
|||||||
/* Static Kernel-Mode address start */
|
/* Static Kernel-Mode address start */
|
||||||
#define KSEG0_BASE 0xFFFFF80000000000
|
#define KSEG0_BASE 0xFFFFF80000000000
|
||||||
|
|
||||||
/* XTOS Kernel address base */
|
|
||||||
#define KSEG0_KERNEL_BASE 0x0000000800000000
|
|
||||||
|
|
||||||
/* XTOS Kernel stack size */
|
/* XTOS Kernel stack size */
|
||||||
#define KERNEL_STACK_SIZE 0x8000
|
#define KERNEL_STACK_SIZE 0x8000
|
||||||
|
|
||||||
@@ -272,11 +269,18 @@ typedef struct _KIDTENTRY
|
|||||||
{
|
{
|
||||||
USHORT OffsetLow;
|
USHORT OffsetLow;
|
||||||
USHORT Selector;
|
USHORT Selector;
|
||||||
|
union
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
USHORT IstIndex:3;
|
USHORT IstIndex:3;
|
||||||
USHORT Reserved0:5;
|
USHORT Reserved0:5;
|
||||||
USHORT Type:5;
|
USHORT Type:5;
|
||||||
USHORT Dpl:2;
|
USHORT Dpl:2;
|
||||||
USHORT Present:1;
|
USHORT Present:1;
|
||||||
|
};
|
||||||
|
USHORT Access;
|
||||||
|
};
|
||||||
USHORT OffsetMiddle;
|
USHORT OffsetMiddle;
|
||||||
ULONG OffsetHigh;
|
ULONG OffsetHigh;
|
||||||
ULONG Reserved1;
|
ULONG Reserved1;
|
||||||
|
|||||||
@@ -25,11 +25,11 @@
|
|||||||
#define MM_PXE_BASE 0xFFFFF6FB7DBED000ULL
|
#define MM_PXE_BASE 0xFFFFF6FB7DBED000ULL
|
||||||
|
|
||||||
/* Page directory and page base addresses for 5-level paging */
|
/* Page directory and page base addresses for 5-level paging */
|
||||||
#define MM_PTE_LA57_BASE 0xFFFF000000000000ULL
|
#define MM_PTE_LA57_BASE 0xFFED000000000000ULL
|
||||||
#define MM_PDE_LA57_BASE 0xFFFF010000000000ULL
|
#define MM_PDE_LA57_BASE 0xFFEDF68000000000ULL
|
||||||
#define MM_PPE_LA57_BASE 0xFFFF010800000000ULL
|
#define MM_PPE_LA57_BASE 0xFFEDF6FB40000000ULL
|
||||||
#define MM_PXE_LA57_BASE 0xFFFF010840000000ULL
|
#define MM_PXE_LA57_BASE 0xFFEDF6FB7DA00000ULL
|
||||||
#define MM_P5E_LA57_BASE 0xFFFF010840200000ULL
|
#define MM_P5E_LA57_BASE 0xFFEDF6FB7DBED000ULL
|
||||||
|
|
||||||
/* PTE shift values */
|
/* PTE shift values */
|
||||||
#define MM_PTE_SHIFT 3
|
#define MM_PTE_SHIFT 3
|
||||||
@@ -39,15 +39,56 @@
|
|||||||
#define MM_PXI_SHIFT 39
|
#define MM_PXI_SHIFT 39
|
||||||
#define MM_P5I_SHIFT 48
|
#define MM_P5I_SHIFT 48
|
||||||
|
|
||||||
/* Number of PTEs per page */
|
/* PTE state flags */
|
||||||
#define MM_PTE_PER_PAGE 512
|
#define MM_PTE_VALID 0x0000000000000001ULL
|
||||||
#define MM_PDE_PER_PAGE 512
|
#define MM_PTE_ACCESSED 0x0000000000000020ULL
|
||||||
#define MM_PPE_PER_PAGE 512
|
#define MM_PTE_DIRTY 0x0000000000000040ULL
|
||||||
#define MM_PXE_PER_PAGE 512
|
|
||||||
|
/* PTE scope flags */
|
||||||
|
#define MM_PTE_LARGE_PAGE 0x0000000000000080ULL
|
||||||
|
#define MM_PTE_GLOBAL 0x0000000000000100ULL
|
||||||
|
|
||||||
|
/* PTE access flags */
|
||||||
|
#define MM_PTE_NOACCESS 0x0000000000000000ULL
|
||||||
|
#define MM_PTE_READONLY 0x0000000000000000ULL
|
||||||
|
#define MM_PTE_EXECUTE 0x0000000000000000ULL
|
||||||
|
#define MM_PTE_EXECUTE_READ 0x0000000000000000ULL
|
||||||
|
#define MM_PTE_READWRITE 0x8000000000000002ULL
|
||||||
|
#define MM_PTE_WRITECOPY 0x8000000000000200ULL
|
||||||
|
#define MM_PTE_EXECUTE_READWRITE 0x0000000000000002ULL
|
||||||
|
#define MM_PTE_EXECUTE_WRITECOPY 0x0000000000000200ULL
|
||||||
|
|
||||||
|
/* PTE protection flags */
|
||||||
|
#define MM_PTE_NOEXECUTE 0x8000000000000000ULL
|
||||||
|
#define MM_PTE_GUARDED 0x8000000000000018ULL
|
||||||
|
#define MM_PTE_PROTECT 0x8000000000000612ULL
|
||||||
|
|
||||||
|
/* PTE cache flags */
|
||||||
|
#define MM_PTE_CACHE_ENABLE 0x0000000000000000ULL
|
||||||
|
#define MM_PTE_CACHE_DISABLE 0x0000000000000010ULL
|
||||||
|
#define MM_PTE_CACHE_WRITECOMBINED 0x0000000000000010ULL
|
||||||
|
#define MM_PTE_CACHE_WRITETHROUGH 0x0000000000000008ULL
|
||||||
|
|
||||||
|
/* PTE software flags */
|
||||||
|
#define MM_PTE_COPY_ON_WRITE 0x0000000000000200ULL
|
||||||
|
#define MM_PTE_PROTOTYPE 0x0000000000000400ULL
|
||||||
|
#define MM_PTE_TRANSITION 0x0000000000000800ULL
|
||||||
|
|
||||||
|
/* PTE frame bits */
|
||||||
|
#define MM_PTE_FRAME_BITS 57
|
||||||
|
|
||||||
|
/* PTE protection bits */
|
||||||
|
#define MM_PTE_PROTECTION_BITS 5
|
||||||
|
|
||||||
|
/* Base address of the system page table */
|
||||||
|
#define MM_SYSTEM_PTE_BASE KSEG0_BASE
|
||||||
|
|
||||||
/* Minimum number of physical pages needed by the system */
|
/* Minimum number of physical pages needed by the system */
|
||||||
#define MM_MINIMUM_PHYSICAL_PAGES 2048
|
#define MM_MINIMUM_PHYSICAL_PAGES 2048
|
||||||
|
|
||||||
|
/* Number of system PTEs */
|
||||||
|
#define MM_DEFAULT_NUMBER_SYSTEM_PTES 22000
|
||||||
|
|
||||||
/* Default number of secondary colors */
|
/* Default number of secondary colors */
|
||||||
#define MM_DEFAULT_SECONDARY_COLORS 64
|
#define MM_DEFAULT_SECONDARY_COLORS 64
|
||||||
|
|
||||||
@@ -63,9 +104,21 @@
|
|||||||
/* Maximum physical address used by HAL allocations */
|
/* Maximum physical address used by HAL allocations */
|
||||||
#define MM_MAXIMUM_PHYSICAL_ADDRESS 0x00000000FFFFFFFFULL
|
#define MM_MAXIMUM_PHYSICAL_ADDRESS 0x00000000FFFFFFFFULL
|
||||||
|
|
||||||
|
/* Highest system address */
|
||||||
|
#define MM_HIGHEST_SYSTEM_ADDRESS 0xFFFFFFFFFFFFFFFFULL
|
||||||
|
|
||||||
/* Trampoline code address */
|
/* Trampoline code address */
|
||||||
#define MM_TRAMPOLINE_ADDRESS 0x80000
|
#define MM_TRAMPOLINE_ADDRESS 0x80000
|
||||||
|
|
||||||
|
/* 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 */
|
/* Page size enumeration list */
|
||||||
typedef enum _PAGE_SIZE
|
typedef enum _PAGE_SIZE
|
||||||
{
|
{
|
||||||
@@ -252,6 +305,7 @@ typedef struct _MMPFN
|
|||||||
USHORT ReferenceCount;
|
USHORT ReferenceCount;
|
||||||
} e2;
|
} e2;
|
||||||
} u3;
|
} u3;
|
||||||
|
ULONG UsedPageTableEntries;
|
||||||
union
|
union
|
||||||
{
|
{
|
||||||
MMPTE OriginalPte;
|
MMPTE OriginalPte;
|
||||||
@@ -262,15 +316,32 @@ typedef struct _MMPFN
|
|||||||
ULONG_PTR EntireFrame;
|
ULONG_PTR EntireFrame;
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
ULONG_PTR PteFrame:58;
|
ULONG_PTR PteFrame:57;
|
||||||
ULONG_PTR InPageError:1;
|
ULONG_PTR InPageError:1;
|
||||||
ULONG_PTR VerifierAllocation:1;
|
ULONG_PTR VerifierAllocation:1;
|
||||||
ULONG_PTR AweAllocation:1;
|
ULONG_PTR AweAllocation:1;
|
||||||
ULONG_PTR LockCharged:1;
|
ULONG_PTR Priority:3;
|
||||||
ULONG_PTR KernelStack:1;
|
|
||||||
ULONG_PTR MustBeCached:1;
|
ULONG_PTR MustBeCached:1;
|
||||||
};
|
};
|
||||||
} u4;
|
} u4;
|
||||||
} MMPFN, *PMMPFN;
|
} 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 */
|
#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_SOFTWARE MMPTE_SOFTWARE, *PMMPTE_SOFTWARE;
|
||||||
typedef struct _MMPTE_SUBSECTION MMPTE_SUBSECTION, *PMMPTE_SUBSECTION;
|
typedef struct _MMPTE_SUBSECTION MMPTE_SUBSECTION, *PMMPTE_SUBSECTION;
|
||||||
typedef struct _MMPTE_TRANSITION MMPTE_TRANSITION, *PMMPTE_TRANSITION;
|
typedef struct _MMPTE_TRANSITION MMPTE_TRANSITION, *PMMPTE_TRANSITION;
|
||||||
|
typedef struct _POOL_DESCRIPTOR POOL_DESCRIPTOR, *PPOOL_DESCRIPTOR;
|
||||||
typedef struct _THREAD_ENVIRONMENT_BLOCK THREAD_ENVIRONMENT_BLOCK, *PTHREAD_ENVIRONMENT_BLOCK;
|
typedef struct _THREAD_ENVIRONMENT_BLOCK THREAD_ENVIRONMENT_BLOCK, *PTHREAD_ENVIRONMENT_BLOCK;
|
||||||
|
|
||||||
/* Unions forward references */
|
/* 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 BOOLEAN (XTCDECL *PBL_BOOTUTILS_GET_BOOLEAN_PARAMETER)(IN PCWSTR Parameters, IN PCWSTR Needle);
|
||||||
typedef VOID (XTAPI *PBL_BOOTUTILS_GET_TRAMPOLINE_INFORMATION)(IN TRAMPOLINE_TYPE TrampolineType, OUT PVOID *TrampolineCode, OUT PULONG_PTR TrampolineSize);
|
typedef VOID (XTAPI *PBL_BOOTUTILS_GET_TRAMPOLINE_INFORMATION)(IN TRAMPOLINE_TYPE TrampolineType, OUT PVOID *TrampolineCode, OUT PULONG_PTR TrampolineSize);
|
||||||
typedef EFI_STATUS (XTCDECL *PBL_BUILD_PAGE_MAP)(IN PXTBL_PAGE_MAPPING PageMap, IN ULONG_PTR SelfMapAddress);
|
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 EFI_STATUS (XTCDECL *PBL_CLOSE_VOLUME)(IN PEFI_HANDLE VolumeHandle);
|
||||||
typedef VOID (XTCDECL *PBL_CLEAR_CONSOLE_LINE)(IN ULONGLONG LineNo);
|
typedef VOID (XTCDECL *PBL_CLEAR_CONSOLE_LINE)(IN ULONGLONG LineNo);
|
||||||
typedef BOOLEAN (XTCDECL *PBL_CPU_CPUID)(IN OUT PCPUID_REGISTERS Registers);
|
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_HEAD)(IN OUT PLIST_ENTRY ListHead, IN PLIST_ENTRY Entry);
|
||||||
typedef VOID (XTCDECL *PBL_LLIST_INSERT_TAIL)(IN OUT PLIST_ENTRY ListHead, IN PLIST_ENTRY Entry);
|
typedef VOID (XTCDECL *PBL_LLIST_INSERT_TAIL)(IN OUT PLIST_ENTRY ListHead, IN PLIST_ENTRY Entry);
|
||||||
typedef VOID (XTCDECL *PBL_LLIST_REMOVE_ENTRY)(IN PLIST_ENTRY Entry);
|
typedef VOID (XTCDECL *PBL_LLIST_REMOVE_ENTRY)(IN PLIST_ENTRY Entry);
|
||||||
typedef EFI_STATUS (XTCDECL *PBL_MAP_EFI_MEMORY)(IN OUT PXTBL_PAGE_MAPPING PageMap, IN OUT PVOID *MemoryMapAddress, IN PBL_GET_MEMTYPE_ROUTINE GetMemoryTypeRoutine);
|
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 ULONG_PTR VirtualAddress, IN ULONG_PTR PhysicalAddress, IN ULONG NumberOfPages);
|
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 PVOID VirtualAddress, IN PVOID PhysicalAddress, IN ULONGLONG NumberOfPages, IN LOADER_MEMORY_TYPE MemoryType);
|
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 VOID (XTAPI *PBL_MOVE_MEMORY)(IN OUT PVOID Destination, IN PCVOID Source, IN SIZE_T Length);
|
||||||
typedef EFI_STATUS (XTCDECL *PBL_OPEN_VOLUME)(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath, OUT PEFI_HANDLE DiskHandle, OUT PEFI_FILE_HANDLE *FsHandle);
|
typedef EFI_STATUS (XTCDECL *PBL_OPEN_VOLUME)(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath, OUT PEFI_HANDLE DiskHandle, OUT PEFI_FILE_HANDLE *FsHandle);
|
||||||
typedef EFI_STATUS (XTCDECL *PBL_OPEN_PROTOCOL)(OUT PEFI_HANDLE Handle, OUT PVOID *ProtocolHandler, IN PEFI_GUID ProtocolGuid);
|
typedef EFI_STATUS (XTCDECL *PBL_OPEN_PROTOCOL)(OUT PEFI_HANDLE Handle, OUT PVOID *ProtocolHandler, IN PEFI_GUID ProtocolGuid);
|
||||||
@@ -232,8 +233,8 @@ typedef struct _XTBL_KNOWN_BOOT_PROTOCOL
|
|||||||
typedef struct _XTBL_MEMORY_MAPPING
|
typedef struct _XTBL_MEMORY_MAPPING
|
||||||
{
|
{
|
||||||
LIST_ENTRY ListEntry;
|
LIST_ENTRY ListEntry;
|
||||||
PVOID VirtualAddress;
|
ULONGLONG VirtualAddress;
|
||||||
PVOID PhysicalAddress;
|
ULONGLONG PhysicalAddress;
|
||||||
ULONGLONG NumberOfPages;
|
ULONGLONG NumberOfPages;
|
||||||
LOADER_MEMORY_TYPE MemoryType;
|
LOADER_MEMORY_TYPE MemoryType;
|
||||||
} XTBL_MEMORY_MAPPING, *PXTBL_MEMORY_MAPPING;
|
} XTBL_MEMORY_MAPPING, *PXTBL_MEMORY_MAPPING;
|
||||||
@@ -449,6 +450,7 @@ typedef struct _XTBL_LOADER_PROTOCOL
|
|||||||
PBL_ALLOCATE_PAGES AllocatePages;
|
PBL_ALLOCATE_PAGES AllocatePages;
|
||||||
PBL_ALLOCATE_POOL AllocatePool;
|
PBL_ALLOCATE_POOL AllocatePool;
|
||||||
PBL_BUILD_PAGE_MAP BuildPageMap;
|
PBL_BUILD_PAGE_MAP BuildPageMap;
|
||||||
|
PBL_COMMIT_PAGE_MAP CommitPageMap;
|
||||||
PBL_COMPARE_MEMORY CompareMemory;
|
PBL_COMPARE_MEMORY CompareMemory;
|
||||||
PBL_COPY_MEMORY CopyMemory;
|
PBL_COPY_MEMORY CopyMemory;
|
||||||
PBL_FREE_PAGES FreePages;
|
PBL_FREE_PAGES FreePages;
|
||||||
|
|||||||
@@ -58,12 +58,6 @@
|
|||||||
#define KIDT_ACCESS_RING0 0x00
|
#define KIDT_ACCESS_RING0 0x00
|
||||||
#define KIDT_ACCESS_RING3 0x60
|
#define KIDT_ACCESS_RING3 0x60
|
||||||
|
|
||||||
/* IDT gate types */
|
|
||||||
#define KIDT_TASK 0x05
|
|
||||||
#define KIDT_CALL 0x0C
|
|
||||||
#define KIDT_INTERRUPT 0x0E
|
|
||||||
#define KIDT_TRAP 0x0F
|
|
||||||
|
|
||||||
/* TSS Offsets */
|
/* TSS Offsets */
|
||||||
#define KTSS_ESP0 0x04
|
#define KTSS_ESP0 0x04
|
||||||
#define KTSS_CR3 0x1C
|
#define KTSS_CR3 0x1C
|
||||||
@@ -134,9 +128,6 @@
|
|||||||
/* Static Kernel-Mode address start */
|
/* Static Kernel-Mode address start */
|
||||||
#define KSEG0_BASE 0x80000000
|
#define KSEG0_BASE 0x80000000
|
||||||
|
|
||||||
/* XTOS Kernel address base */
|
|
||||||
#define KSEG0_KERNEL_BASE 0x01800000
|
|
||||||
|
|
||||||
/* XTOS Kernel stack size */
|
/* XTOS Kernel stack size */
|
||||||
#define KERNEL_STACK_SIZE 0x4000
|
#define KERNEL_STACK_SIZE 0x4000
|
||||||
|
|
||||||
@@ -284,7 +275,18 @@ typedef struct _KIDTENTRY
|
|||||||
{
|
{
|
||||||
USHORT Offset;
|
USHORT Offset;
|
||||||
USHORT Selector;
|
USHORT Selector;
|
||||||
|
union
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
UCHAR Reserved;
|
||||||
|
UCHAR Type:4;
|
||||||
|
UCHAR Flag:1;
|
||||||
|
UCHAR Dpl:2;
|
||||||
|
UCHAR Present:1;
|
||||||
|
};
|
||||||
USHORT Access;
|
USHORT Access;
|
||||||
|
};
|
||||||
USHORT ExtendedOffset;
|
USHORT ExtendedOffset;
|
||||||
} KIDTENTRY, *PKIDTENTRY;
|
} KIDTENTRY, *PKIDTENTRY;
|
||||||
|
|
||||||
|
|||||||
@@ -35,9 +35,58 @@
|
|||||||
#define MM_PTE_LEGACY_SHIFT 2
|
#define MM_PTE_LEGACY_SHIFT 2
|
||||||
#define MM_PDI_LEGACY_SHIFT 22
|
#define MM_PDI_LEGACY_SHIFT 22
|
||||||
|
|
||||||
|
/* PTE state flags */
|
||||||
|
#define MM_PTE_VALID 0x00000001
|
||||||
|
#define MM_PTE_ACCESSED 0x00000020
|
||||||
|
#define MM_PTE_DIRTY 0x00000040
|
||||||
|
|
||||||
|
/* PTE scope flags */
|
||||||
|
#define MM_PTE_LARGE_PAGE 0x00000080
|
||||||
|
#define MM_PTE_GLOBAL 0x00000100
|
||||||
|
|
||||||
|
/* PTE access flags */
|
||||||
|
#define MM_PTE_NOACCESS 0x00000000
|
||||||
|
#define MM_PTE_READONLY 0x00000000
|
||||||
|
#define MM_PTE_EXECUTE 0x00000000
|
||||||
|
#define MM_PTE_EXECUTE_READ 0x00000000
|
||||||
|
#define MM_PTE_READWRITE 0x00000002
|
||||||
|
#define MM_PTE_WRITECOPY 0x00000200
|
||||||
|
#define MM_PTE_EXECUTE_READWRITE 0x00000002
|
||||||
|
#define MM_PTE_EXECUTE_WRITECOPY 0x00000200
|
||||||
|
|
||||||
|
/* PTE protection flags */
|
||||||
|
#define MM_PTE_NOEXECUTE 0x00000000
|
||||||
|
#define MM_PTE_GUARDED 0x00000018
|
||||||
|
#define MM_PTE_PROTECT 0x00000612
|
||||||
|
|
||||||
|
/* PTE cache flags */
|
||||||
|
#define MM_PTE_CACHE_ENABLE 0x00000000
|
||||||
|
#define MM_PTE_CACHE_DISABLE 0x00000010
|
||||||
|
#define MM_PTE_CACHE_WRITECOMBINED 0x00000010
|
||||||
|
#define MM_PTE_CACHE_WRITETHROUGH 0x00000008
|
||||||
|
|
||||||
|
/* PTE software flags */
|
||||||
|
#define MM_PTE_COPY_ON_WRITE 0x00000200
|
||||||
|
#define MM_PTE_PROTOTYPE 0x00000400
|
||||||
|
#define MM_PTE_TRANSITION 0x00000800
|
||||||
|
|
||||||
|
/* PTE frame bits */
|
||||||
|
#define MM_PTE_FRAME_BITS 25
|
||||||
|
|
||||||
|
/* PTE protection bits */
|
||||||
|
#define MM_PTE_PROTECTION_BITS 5
|
||||||
|
|
||||||
|
/* Base address of the system page table */
|
||||||
|
#define MM_SYSTEM_PTE_BASE NULLPTR
|
||||||
|
|
||||||
/* Minimum number of physical pages needed by the system */
|
/* Minimum number of physical pages needed by the system */
|
||||||
#define MM_MINIMUM_PHYSICAL_PAGES 1100
|
#define MM_MINIMUM_PHYSICAL_PAGES 1100
|
||||||
|
|
||||||
|
/* Number of system PTEs */
|
||||||
|
#define MM_MINIMUM_NUMBER_SYSTEM_PTES 7000
|
||||||
|
#define MM_DEFAULT_NUMBER_SYSTEM_PTES 11000
|
||||||
|
#define MM_MAXIMUM_NUMBER_SYSTEM_PTES 22000
|
||||||
|
|
||||||
/* Default number of secondary colors */
|
/* Default number of secondary colors */
|
||||||
#define MM_DEFAULT_SECONDARY_COLORS 64
|
#define MM_DEFAULT_SECONDARY_COLORS 64
|
||||||
|
|
||||||
@@ -53,9 +102,21 @@
|
|||||||
/* Maximum physical address used by HAL allocations */
|
/* Maximum physical address used by HAL allocations */
|
||||||
#define MM_MAXIMUM_PHYSICAL_ADDRESS 0xFFFFFFFF
|
#define MM_MAXIMUM_PHYSICAL_ADDRESS 0xFFFFFFFF
|
||||||
|
|
||||||
|
/* Highest system address */
|
||||||
|
#define MM_HIGHEST_SYSTEM_ADDRESS 0xFFFFFFFF
|
||||||
|
|
||||||
/* Trampoline code address */
|
/* Trampoline code address */
|
||||||
#define MM_TRAMPOLINE_ADDRESS 0x80000
|
#define MM_TRAMPOLINE_ADDRESS 0x80000
|
||||||
|
|
||||||
|
/* 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 */
|
/* Page size enumeration list */
|
||||||
typedef enum _PAGE_SIZE
|
typedef enum _PAGE_SIZE
|
||||||
{
|
{
|
||||||
@@ -106,7 +167,6 @@ typedef struct _HARDWARE_MODERN_PTE
|
|||||||
/* Generic Page Table entry union to abstract PML2 and PML3 formats */
|
/* Generic Page Table entry union to abstract PML2 and PML3 formats */
|
||||||
typedef union _HARDWARE_PTE
|
typedef union _HARDWARE_PTE
|
||||||
{
|
{
|
||||||
ULONGLONG Long;
|
|
||||||
HARDWARE_LEGACY_PTE Pml2;
|
HARDWARE_LEGACY_PTE Pml2;
|
||||||
HARDWARE_MODERN_PTE Pml3;
|
HARDWARE_MODERN_PTE Pml3;
|
||||||
} HARDWARE_PTE, *PHARDWARE_PTE;
|
} HARDWARE_PTE, *PHARDWARE_PTE;
|
||||||
@@ -201,12 +261,12 @@ typedef struct _MMPML2_PTE_TRANSITION
|
|||||||
typedef union _MMPML2_PTE
|
typedef union _MMPML2_PTE
|
||||||
{
|
{
|
||||||
ULONG Long;
|
ULONG Long;
|
||||||
HARDWARE_PTE Flush;
|
HARDWARE_LEGACY_PTE Flush;
|
||||||
MMPML2_PTE_HARDWARE Hard;
|
MMPML2_PTE_HARDWARE Hardware;
|
||||||
MMPML2_PTE_PROTOTYPE Proto;
|
MMPML2_PTE_PROTOTYPE Prototype;
|
||||||
MMPML2_PTE_SOFTWARE Soft;
|
MMPML2_PTE_SOFTWARE Software;
|
||||||
MMPML2_PTE_TRANSITION Trans;
|
MMPML2_PTE_TRANSITION Transition;
|
||||||
MMPML2_PTE_SUBSECTION Subsect;
|
MMPML2_PTE_SUBSECTION Subsection;
|
||||||
MMPML2_PTE_LIST List;
|
MMPML2_PTE_LIST List;
|
||||||
} MMPML2_PTE, *PMMPML2_PTE;
|
} MMPML2_PTE, *PMMPML2_PTE;
|
||||||
|
|
||||||
@@ -296,7 +356,7 @@ typedef struct _MMPML3_PTE_TRANSITION
|
|||||||
typedef union _MMPML3_PTE
|
typedef union _MMPML3_PTE
|
||||||
{
|
{
|
||||||
ULONGLONG Long;
|
ULONGLONG Long;
|
||||||
HARDWARE_PTE Flush;
|
HARDWARE_MODERN_PTE Flush;
|
||||||
MMPML3_PTE_HARDWARE Hardware;
|
MMPML3_PTE_HARDWARE Hardware;
|
||||||
MMPML3_PTE_PROTOTYPE Prototype;
|
MMPML3_PTE_PROTOTYPE Prototype;
|
||||||
MMPML3_PTE_SOFTWARE Software;
|
MMPML3_PTE_SOFTWARE Software;
|
||||||
@@ -308,7 +368,6 @@ typedef union _MMPML3_PTE
|
|||||||
/* Generic Page Table Entry union to abstract PML2 and PML3 formats */
|
/* Generic Page Table Entry union to abstract PML2 and PML3 formats */
|
||||||
typedef union _MMPTE
|
typedef union _MMPTE
|
||||||
{
|
{
|
||||||
ULONGLONG Long;
|
|
||||||
MMPML2_PTE Pml2;
|
MMPML2_PTE Pml2;
|
||||||
MMPML3_PTE Pml3;
|
MMPML3_PTE Pml3;
|
||||||
} MMPTE, *PMMPTE;
|
} MMPTE, *PMMPTE;
|
||||||
@@ -339,6 +398,7 @@ typedef struct _MMPFN
|
|||||||
USHORT ReferenceCount;
|
USHORT ReferenceCount;
|
||||||
} e2;
|
} e2;
|
||||||
} u3;
|
} u3;
|
||||||
|
ULONG UsedPageTableEntries;
|
||||||
union
|
union
|
||||||
{
|
{
|
||||||
MMPTE OriginalPte;
|
MMPTE OriginalPte;
|
||||||
@@ -349,15 +409,32 @@ typedef struct _MMPFN
|
|||||||
ULONG_PTR EntireFrame;
|
ULONG_PTR EntireFrame;
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
ULONG_PTR PteFrame:26;
|
ULONG_PTR PteFrame:25;
|
||||||
ULONG_PTR InPageError:1;
|
ULONG_PTR InPageError:1;
|
||||||
ULONG_PTR VerifierAllocation:1;
|
ULONG_PTR VerifierAllocation:1;
|
||||||
ULONG_PTR AweAllocation:1;
|
ULONG_PTR AweAllocation:1;
|
||||||
ULONG_PTR LockCharged:1;
|
ULONG_PTR Priority:3;
|
||||||
ULONG_PTR KernelStack:1;
|
|
||||||
ULONG_PTR MustBeCached:1;
|
ULONG_PTR MustBeCached:1;
|
||||||
};
|
};
|
||||||
} u4;
|
} u4;
|
||||||
} MMPFN, *PMMPFN;
|
} 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 */
|
#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_SOFTWARE MMPML3_PTE_SOFTWARE, *PMMPML3_PTE_SOFTWARE;
|
||||||
typedef struct _MMPML3_PTE_SUBSECTION MMPML3_PTE_SUBSECTION, *PMMPML3_PTE_SUBSECTION;
|
typedef struct _MMPML3_PTE_SUBSECTION MMPML3_PTE_SUBSECTION, *PMMPML3_PTE_SUBSECTION;
|
||||||
typedef struct _MMPML3_PTE_TRANSITION MMPML3_PTE_TRANSITION, *PMMPML3_PTE_TRANSITION;
|
typedef struct _MMPML3_PTE_TRANSITION MMPML3_PTE_TRANSITION, *PMMPML3_PTE_TRANSITION;
|
||||||
|
typedef struct _POOL_DESCRIPTOR POOL_DESCRIPTOR, *PPOOL_DESCRIPTOR;
|
||||||
typedef struct _THREAD_ENVIRONMENT_BLOCK THREAD_ENVIRONMENT_BLOCK, *PTHREAD_ENVIRONMENT_BLOCK;
|
typedef struct _THREAD_ENVIRONMENT_BLOCK THREAD_ENVIRONMENT_BLOCK, *PTHREAD_ENVIRONMENT_BLOCK;
|
||||||
|
|
||||||
/* Unions forward references */
|
/* Unions forward references */
|
||||||
|
|||||||
@@ -150,21 +150,23 @@ typedef enum _KTHREAD_STATE
|
|||||||
typedef enum _KSPIN_LOCK_QUEUE_LEVEL
|
typedef enum _KSPIN_LOCK_QUEUE_LEVEL
|
||||||
{
|
{
|
||||||
DispatcherLock,
|
DispatcherLock,
|
||||||
UnusedSpareLock,
|
ExpansionLock,
|
||||||
PfnLock,
|
PfnLock,
|
||||||
SystemSpaceLock,
|
SystemSpaceLock,
|
||||||
VacbLock,
|
VacbLock,
|
||||||
MasterLock,
|
MasterLock,
|
||||||
NonPagedPoolLock,
|
NonPagedAllocPoolLock,
|
||||||
IoCancelLock,
|
IoCancelLock,
|
||||||
WorkQueueLock,
|
WorkQueueLock,
|
||||||
IoVpbLock,
|
IoVpbLock,
|
||||||
IoDatabaseLock,
|
IoDatabaseLock,
|
||||||
IoCompletionLock,
|
IoCompletionLock,
|
||||||
FsStructLock,
|
FileSystemLock,
|
||||||
AfdWorkQueueLock,
|
AfdWorkQueueLock,
|
||||||
BcbLock,
|
BcbLock,
|
||||||
MmNonPagedPoolLock,
|
NonPagedPoolLock,
|
||||||
|
ReservedSystemLock,
|
||||||
|
TimerTableLock,
|
||||||
MaximumLock
|
MaximumLock
|
||||||
} KSPIN_LOCK_QUEUE_LEVEL, *PKSPIN_LOCK_QUEUE_LEVEL;
|
} 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
|
* FILE: sdk/xtdk/mmtypes.h
|
||||||
* DESCRIPTION: Memory management data structures
|
* DESCRIPTION: Memory management data structures
|
||||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||||
|
* Aiken Harris <harraiken91@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __XTDK_MMTYPES_H
|
#ifndef __XTDK_MMTYPES_H
|
||||||
@@ -13,6 +14,95 @@
|
|||||||
#include ARCH_HEADER(xtstruct.h)
|
#include ARCH_HEADER(xtstruct.h)
|
||||||
|
|
||||||
|
|
||||||
|
/* Number of hyper space pages */
|
||||||
|
#define MM_HYPERSPACE_PAGE_COUNT 255
|
||||||
|
|
||||||
|
/* Number of free page list heads */
|
||||||
|
#define MM_MAX_FREE_PAGE_LIST_HEADS 4
|
||||||
|
|
||||||
|
/* Number of paging colors */
|
||||||
|
#define MM_PAGING_COLORS 64
|
||||||
|
|
||||||
|
/* PTE frame mask definition */
|
||||||
|
#define MM_PFN_PTE_FRAME (((ULONG_PTR)1 << MM_PTE_FRAME_BITS) - 1)
|
||||||
|
|
||||||
|
/* Memory manager pool type mask definition */
|
||||||
|
#define MM_POOL_TYPE_MASK 1
|
||||||
|
|
||||||
|
/* 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 */
|
/* Page map routines structure definition */
|
||||||
typedef CONST STRUCT _CMMPAGEMAP_ROUTINES
|
typedef CONST STRUCT _CMMPAGEMAP_ROUTINES
|
||||||
{
|
{
|
||||||
@@ -30,6 +120,58 @@ typedef struct _MMCOLOR_TABLES
|
|||||||
ULONG_PTR Count;
|
ULONG_PTR Count;
|
||||||
} MMCOLOR_TABLES, *PMMCOLOR_TABLES;
|
} MMCOLOR_TABLES, *PMMCOLOR_TABLES;
|
||||||
|
|
||||||
|
/* Free pool entry structure definition */
|
||||||
|
typedef struct _MMFREE_POOL_ENTRY
|
||||||
|
{
|
||||||
|
LIST_ENTRY List;
|
||||||
|
PFN_COUNT Size;
|
||||||
|
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 */
|
/* Page Frame Entry structure definition */
|
||||||
typedef struct _MMPFNENTRY
|
typedef struct _MMPFNENTRY
|
||||||
{
|
{
|
||||||
@@ -45,4 +187,75 @@ typedef struct _MMPFNENTRY
|
|||||||
USHORT ParityError:1;
|
USHORT ParityError:1;
|
||||||
} MMPFNENTRY, *PMMPFNENTRY;
|
} MMPFNENTRY, *PMMPFNENTRY;
|
||||||
|
|
||||||
|
/* Page Frame List structure definition */
|
||||||
|
typedef struct _MMPFNLIST
|
||||||
|
{
|
||||||
|
PFN_NUMBER Total;
|
||||||
|
MMPAGELISTS ListName;
|
||||||
|
PFN_NUMBER Flink;
|
||||||
|
PFN_NUMBER Blink;
|
||||||
|
} MMPFNLIST, *PMMPFNLIST;
|
||||||
|
|
||||||
|
/* 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 */
|
#endif /* __XTDK_MMTYPES_H */
|
||||||
|
|||||||
@@ -49,6 +49,10 @@
|
|||||||
#define PFL_DIGIT_PRECISION 0x00002000
|
#define PFL_DIGIT_PRECISION 0x00002000
|
||||||
#define PFL_THOUSANDS_GROUPING 0x00004000
|
#define PFL_THOUSANDS_GROUPING 0x00004000
|
||||||
|
|
||||||
|
/* Cryptographic related definitions */
|
||||||
|
#define SHA1_BLOCK_SIZE 64
|
||||||
|
#define SHA1_DIGEST_SIZE 20
|
||||||
|
|
||||||
/* Runtime Library routine callbacks */
|
/* Runtime Library routine callbacks */
|
||||||
typedef XTSTATUS (*PWRITE_CHARACTER)(IN CHAR Character);
|
typedef XTSTATUS (*PWRITE_CHARACTER)(IN CHAR Character);
|
||||||
typedef XTSTATUS (*PWRITE_WIDE_CHARACTER)(IN WCHAR Character);
|
typedef XTSTATUS (*PWRITE_WIDE_CHARACTER)(IN WCHAR Character);
|
||||||
@@ -95,4 +99,12 @@ typedef struct _RTL_PRINT_FORMAT_PROPERTIES
|
|||||||
LONG Flags;
|
LONG Flags;
|
||||||
} RTL_PRINT_FORMAT_PROPERTIES, *PRTL_PRINT_FORMAT_PROPERTIES;
|
} RTL_PRINT_FORMAT_PROPERTIES, *PRTL_PRINT_FORMAT_PROPERTIES;
|
||||||
|
|
||||||
|
/* Runtime Library SHA-1 context structure definition */
|
||||||
|
typedef struct _RTL_SHA1_CONTEXT
|
||||||
|
{
|
||||||
|
ULONG State[5];
|
||||||
|
ULONG Count[2];
|
||||||
|
UCHAR Buffer[SHA1_BLOCK_SIZE];
|
||||||
|
} RTL_SHA1_CONTEXT, *PRTL_SHA1_CONTEXT;
|
||||||
|
|
||||||
#endif /* __XTDK_RTLTYPES_H */
|
#endif /* __XTDK_RTLTYPES_H */
|
||||||
|
|||||||
@@ -29,6 +29,9 @@ typedef UCHAR KRUNLEVEL, *PKRUNLEVEL;
|
|||||||
/* Spin locks synchronization mechanism */
|
/* Spin locks synchronization mechanism */
|
||||||
typedef ULONG_PTR KSPIN_LOCK, *PKSPIN_LOCK;
|
typedef ULONG_PTR KSPIN_LOCK, *PKSPIN_LOCK;
|
||||||
|
|
||||||
|
/* Page Frame Number count */
|
||||||
|
typedef ULONG PFN_COUNT;
|
||||||
|
|
||||||
/* Page Frame Number */
|
/* Page Frame Number */
|
||||||
typedef ULONG_PTR PFN_NUMBER, *PPFN_NUMBER;
|
typedef ULONG_PTR PFN_NUMBER, *PPFN_NUMBER;
|
||||||
|
|
||||||
|
|||||||
@@ -12,8 +12,9 @@
|
|||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
/* C++ definitions */
|
/* C++ definitions */
|
||||||
#define XTCLINK extern "C"
|
|
||||||
#define NULLPTR nullptr
|
#define NULLPTR nullptr
|
||||||
|
#define VIRTUAL virtual
|
||||||
|
#define XTCLINK extern "C"
|
||||||
|
|
||||||
/* C++ boolean type */
|
/* C++ boolean type */
|
||||||
typedef bool BOOLEAN, *PBOOLEAN;
|
typedef bool BOOLEAN, *PBOOLEAN;
|
||||||
@@ -24,8 +25,9 @@
|
|||||||
typedef wchar_t wchar;
|
typedef wchar_t wchar;
|
||||||
#else
|
#else
|
||||||
/* C definitions */
|
/* C definitions */
|
||||||
#define XTCLINK
|
|
||||||
#define NULLPTR ((void *)0)
|
#define NULLPTR ((void *)0)
|
||||||
|
#define VIRTUAL
|
||||||
|
#define XTCLINK
|
||||||
|
|
||||||
/* C boolean type */
|
/* C boolean type */
|
||||||
typedef enum _BOOLEAN
|
typedef enum _BOOLEAN
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
#define DebugPrint(Format, ...) DbgPrint(Format, __VA_ARGS__);
|
#define DebugPrint(Format, ...) DbgPrint(Format, __VA_ARGS__);
|
||||||
#else
|
#else
|
||||||
#define DEBUG 0
|
#define DEBUG 0
|
||||||
#define DebugPrint(Format, ...) ((VOID)NULL)
|
#define DebugPrint(Format, ...) ((VOID)NULLPTR)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* __XTDK_XTDEBUG_H */
|
#endif /* __XTDK_XTDEBUG_H */
|
||||||
|
|||||||
@@ -74,12 +74,20 @@
|
|||||||
/* Macro for calculating size of a field in the structure */
|
/* Macro for calculating size of a field in the structure */
|
||||||
#define FIELD_SIZE(Structure, Field) (sizeof(((Structure *)0)->Field))
|
#define FIELD_SIZE(Structure, Field) (sizeof(((Structure *)0)->Field))
|
||||||
|
|
||||||
|
/* Macros for calculating minimum and maximum of two values */
|
||||||
|
#define MIN(A, B) (((A) < (B)) ? (A) : (B))
|
||||||
|
#define MAX(A, B) (((A) > (B)) ? (A) : (B))
|
||||||
|
|
||||||
/* Macro that page-aligns a virtual address */
|
/* Macro that page-aligns a virtual address */
|
||||||
#define PAGE_ALIGN(VirtualAddress) ((PVOID)((ULONG_PTR)VirtualAddress & ~MM_PAGE_MASK))
|
#define PAGE_ALIGN(VirtualAddress) ((PVOID)((ULONG_PTR)VirtualAddress & ~MM_PAGE_MASK))
|
||||||
|
|
||||||
/* Macro that returns offset of the virtual address */
|
/* Macro that returns offset of the virtual address */
|
||||||
#define PAGE_OFFSET(VirtualAddress) ((ULONG)((ULONG_PTR)VirtualAddress & MM_PAGE_MASK))
|
#define PAGE_OFFSET(VirtualAddress) ((ULONG)((ULONG_PTR)VirtualAddress & MM_PAGE_MASK))
|
||||||
|
|
||||||
|
/* Macros for bitwise rotating */
|
||||||
|
#define ROTATE_LEFT(Value, Count) ((Value << Count) | (Value >> (32 - Count)))
|
||||||
|
#define ROTATE_RIGHT(Value, Count) ((Value >> Count) | (Value << (32 - Count)))
|
||||||
|
|
||||||
/* Macro for rounding down */
|
/* Macro for rounding down */
|
||||||
#define ROUND_DOWN(Value, Alignment) ((Value) & ~((Alignment) - 1))
|
#define ROUND_DOWN(Value, Alignment) ((Value) & ~((Alignment) - 1))
|
||||||
|
|
||||||
@@ -104,7 +112,7 @@
|
|||||||
|
|
||||||
/* Variadic ABI functions */
|
/* Variadic ABI functions */
|
||||||
typedef __builtin_va_list VA_LIST, *PVA_LIST;
|
typedef __builtin_va_list VA_LIST, *PVA_LIST;
|
||||||
#define VA_ARG(Marker, Type) ((sizeof (Type) < sizeof(UINT_PTR)) ? \
|
#define VA_ARG(Marker, Type) ((sizeof(Type) < sizeof(UINT_PTR)) ? \
|
||||||
(Type)(__builtin_va_arg(Marker, UINT_PTR)) : \
|
(Type)(__builtin_va_arg(Marker, UINT_PTR)) : \
|
||||||
(Type)(__builtin_va_arg(Marker, Type)))
|
(Type)(__builtin_va_arg(Marker, Type)))
|
||||||
#define VA_COPY(Dest, Start) __builtin_va_copy(Dest, Start)
|
#define VA_COPY(Dest, Start) __builtin_va_copy(Dest, Start)
|
||||||
|
|||||||
@@ -107,6 +107,7 @@ typedef struct _KERNEL_INITIALIZATION_BLOCK
|
|||||||
ULONG BlockVersion;
|
ULONG BlockVersion;
|
||||||
ULONG ProtocolVersion;
|
ULONG ProtocolVersion;
|
||||||
PWCHAR KernelParameters;
|
PWCHAR KernelParameters;
|
||||||
|
PFN_NUMBER BootImageSize;
|
||||||
LIST_ENTRY LoadOrderListHead;
|
LIST_ENTRY LoadOrderListHead;
|
||||||
LIST_ENTRY MemoryDescriptorListHead;
|
LIST_ENTRY MemoryDescriptorListHead;
|
||||||
LIST_ENTRY BootDriverListHead;
|
LIST_ENTRY BootDriverListHead;
|
||||||
|
|||||||
@@ -50,6 +50,7 @@
|
|||||||
#include <hlfuncs.h>
|
#include <hlfuncs.h>
|
||||||
#include <kdfuncs.h>
|
#include <kdfuncs.h>
|
||||||
#include <kefuncs.h>
|
#include <kefuncs.h>
|
||||||
|
#include <mmfuncs.h>
|
||||||
#include <rtlfuncs.h>
|
#include <rtlfuncs.h>
|
||||||
|
|
||||||
/* Architecture specific XT routines */
|
/* 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 _KTIMER_TYPE KTIMER_TYPE, *PKTIMER_TYPE;
|
||||||
typedef enum _KUBSAN_DATA_TYPE KUBSAN_DATA_TYPE, *PKUBSAN_DATA_TYPE;
|
typedef enum _KUBSAN_DATA_TYPE KUBSAN_DATA_TYPE, *PKUBSAN_DATA_TYPE;
|
||||||
typedef enum _LOADER_MEMORY_TYPE LOADER_MEMORY_TYPE, *PLOADER_MEMORY_TYPE;
|
typedef enum _LOADER_MEMORY_TYPE LOADER_MEMORY_TYPE, *PLOADER_MEMORY_TYPE;
|
||||||
|
typedef enum _MMPAGELISTS MMPAGELISTS, *PMMPAGELISTS;
|
||||||
|
typedef enum _MMPFN_CACHE_ATTRIBUTE MMPFN_CACHE_ATTRIBUTE, *PMMPFN_CACHE_ATTRIBUTE;
|
||||||
|
typedef enum _MMPOOL_TYPE MMPOOL_TYPE, *PMMPOOL_TYPE;
|
||||||
|
typedef enum _MMSYSTEM_PTE_POOL_TYPE MMSYSTEM_PTE_POOL_TYPE, *PMMSYSTEM_PTE_POOL_TYPE;
|
||||||
typedef enum _MODE MODE, *PMODE;
|
typedef enum _MODE MODE, *PMODE;
|
||||||
typedef enum _RTL_VARIABLE_TYPE RTL_VARIABLE_TYPE, *PRTL_VARIABLE_TYPE;
|
typedef enum _RTL_VARIABLE_TYPE RTL_VARIABLE_TYPE, *PRTL_VARIABLE_TYPE;
|
||||||
typedef enum _SYSTEM_FIRMWARE_TYPE SYSTEM_FIRMWARE_TYPE, *PSYSTEM_FIRMWARE_TYPE;
|
typedef enum _SYSTEM_FIRMWARE_TYPE SYSTEM_FIRMWARE_TYPE, *PSYSTEM_FIRMWARE_TYPE;
|
||||||
@@ -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 _LOADER_MEMORY_DESCRIPTOR LOADER_MEMORY_DESCRIPTOR, *PLOADER_MEMORY_DESCRIPTOR;
|
||||||
typedef struct _M128 M128, *PM128;
|
typedef struct _M128 M128, *PM128;
|
||||||
typedef struct _MMCOLOR_TABLES MMCOLOR_TABLES, *PMMCOLOR_TABLES;
|
typedef struct _MMCOLOR_TABLES MMCOLOR_TABLES, *PMMCOLOR_TABLES;
|
||||||
|
typedef struct _MMFREE_POOL_ENTRY MMFREE_POOL_ENTRY, *PMMFREE_POOL_ENTRY;
|
||||||
|
typedef struct _MMMEMORY_LAYOUT MMMEMORY_LAYOUT, *PMMMEMORY_LAYOUT;
|
||||||
typedef struct _MMPFNENTRY MMPFNENTRY, *PMMPFNENTRY;
|
typedef struct _MMPFNENTRY MMPFNENTRY, *PMMPFNENTRY;
|
||||||
|
typedef struct _MMPFNLIST MMPFNLIST, *PMMPFNLIST;
|
||||||
typedef struct _PCAT_FIRMWARE_INFORMATION PCAT_FIRMWARE_INFORMATION, *PPCAT_FIRMWARE_INFORMATION;
|
typedef struct _PCAT_FIRMWARE_INFORMATION PCAT_FIRMWARE_INFORMATION, *PPCAT_FIRMWARE_INFORMATION;
|
||||||
typedef struct _PCI_BRIDGE_CONTROL_REGISTER PCI_BRIDGE_CONTROL_REGISTER, *PPCI_BRIDGE_CONTROL_REGISTER;
|
typedef struct _PCI_BRIDGE_CONTROL_REGISTER PCI_BRIDGE_CONTROL_REGISTER, *PPCI_BRIDGE_CONTROL_REGISTER;
|
||||||
typedef struct _PCI_COMMON_CONFIG PCI_COMMON_CONFIG, *PPCI_COMMON_CONFIG;
|
typedef struct _PCI_COMMON_CONFIG PCI_COMMON_CONFIG, *PPCI_COMMON_CONFIG;
|
||||||
@@ -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_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_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 _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_IDENTITY PROCESSOR_IDENTITY, *PPROCESSOR_IDENTITY;
|
||||||
typedef struct _PROCESSOR_POWER_STATE PROCESSOR_POWER_STATE, *PPROCESSOR_POWER_STATE;
|
typedef struct _PROCESSOR_POWER_STATE PROCESSOR_POWER_STATE, *PPROCESSOR_POWER_STATE;
|
||||||
typedef struct _RTL_BITMAP RTL_BITMAP, *PRTL_BITMAP;
|
typedef struct _RTL_BITMAP RTL_BITMAP, *PRTL_BITMAP;
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ list(APPEND XTOSKRNL_SOURCE
|
|||||||
${XTOSKRNL_SOURCE_DIR}/hl/${ARCH}/cpu.cc
|
${XTOSKRNL_SOURCE_DIR}/hl/${ARCH}/cpu.cc
|
||||||
${XTOSKRNL_SOURCE_DIR}/hl/${ARCH}/pic.cc
|
${XTOSKRNL_SOURCE_DIR}/hl/${ARCH}/pic.cc
|
||||||
${XTOSKRNL_SOURCE_DIR}/hl/${ARCH}/ioport.cc
|
${XTOSKRNL_SOURCE_DIR}/hl/${ARCH}/ioport.cc
|
||||||
|
${XTOSKRNL_SOURCE_DIR}/hl/${ARCH}/irq.cc
|
||||||
${XTOSKRNL_SOURCE_DIR}/hl/${ARCH}/runlevel.cc
|
${XTOSKRNL_SOURCE_DIR}/hl/${ARCH}/runlevel.cc
|
||||||
${XTOSKRNL_SOURCE_DIR}/hl/acpi.cc
|
${XTOSKRNL_SOURCE_DIR}/hl/acpi.cc
|
||||||
${XTOSKRNL_SOURCE_DIR}/hl/cport.cc
|
${XTOSKRNL_SOURCE_DIR}/hl/cport.cc
|
||||||
@@ -31,7 +32,6 @@ list(APPEND XTOSKRNL_SOURCE
|
|||||||
${XTOSKRNL_SOURCE_DIR}/kd/data.cc
|
${XTOSKRNL_SOURCE_DIR}/kd/data.cc
|
||||||
${XTOSKRNL_SOURCE_DIR}/kd/dbgio.cc
|
${XTOSKRNL_SOURCE_DIR}/kd/dbgio.cc
|
||||||
${XTOSKRNL_SOURCE_DIR}/kd/exports.cc
|
${XTOSKRNL_SOURCE_DIR}/kd/exports.cc
|
||||||
${XTOSKRNL_SOURCE_DIR}/ke/${ARCH}/irq.cc
|
|
||||||
${XTOSKRNL_SOURCE_DIR}/ke/${ARCH}/krnlinit.cc
|
${XTOSKRNL_SOURCE_DIR}/ke/${ARCH}/krnlinit.cc
|
||||||
${XTOSKRNL_SOURCE_DIR}/ke/${ARCH}/kthread.cc
|
${XTOSKRNL_SOURCE_DIR}/ke/${ARCH}/kthread.cc
|
||||||
${XTOSKRNL_SOURCE_DIR}/ke/${ARCH}/proc.cc
|
${XTOSKRNL_SOURCE_DIR}/ke/${ARCH}/proc.cc
|
||||||
@@ -51,14 +51,24 @@ list(APPEND XTOSKRNL_SOURCE
|
|||||||
${XTOSKRNL_SOURCE_DIR}/ke/spinlock.cc
|
${XTOSKRNL_SOURCE_DIR}/ke/spinlock.cc
|
||||||
${XTOSKRNL_SOURCE_DIR}/ke/sysres.cc
|
${XTOSKRNL_SOURCE_DIR}/ke/sysres.cc
|
||||||
${XTOSKRNL_SOURCE_DIR}/ke/timer.cc
|
${XTOSKRNL_SOURCE_DIR}/ke/timer.cc
|
||||||
${XTOSKRNL_SOURCE_DIR}/mm/${ARCH}/init.cc
|
${XTOSKRNL_SOURCE_DIR}/mm/${ARCH}/mmgr.cc
|
||||||
${XTOSKRNL_SOURCE_DIR}/mm/${ARCH}/pagemap.cc
|
${XTOSKRNL_SOURCE_DIR}/mm/${ARCH}/pagemap.cc
|
||||||
${XTOSKRNL_SOURCE_DIR}/mm/${ARCH}/paging.cc
|
${XTOSKRNL_SOURCE_DIR}/mm/${ARCH}/paging.cc
|
||||||
|
${XTOSKRNL_SOURCE_DIR}/mm/${ARCH}/pfault.cc
|
||||||
|
${XTOSKRNL_SOURCE_DIR}/mm/${ARCH}/pfn.cc
|
||||||
|
${XTOSKRNL_SOURCE_DIR}/mm/${ARCH}/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/data.cc
|
||||||
|
${XTOSKRNL_SOURCE_DIR}/mm/exports.cc
|
||||||
${XTOSKRNL_SOURCE_DIR}/mm/hlpool.cc
|
${XTOSKRNL_SOURCE_DIR}/mm/hlpool.cc
|
||||||
${XTOSKRNL_SOURCE_DIR}/mm/init.cc
|
|
||||||
${XTOSKRNL_SOURCE_DIR}/mm/kpool.cc
|
${XTOSKRNL_SOURCE_DIR}/mm/kpool.cc
|
||||||
|
${XTOSKRNL_SOURCE_DIR}/mm/mmgr.cc
|
||||||
${XTOSKRNL_SOURCE_DIR}/mm/paging.cc
|
${XTOSKRNL_SOURCE_DIR}/mm/paging.cc
|
||||||
|
${XTOSKRNL_SOURCE_DIR}/mm/pfn.cc
|
||||||
|
${XTOSKRNL_SOURCE_DIR}/mm/pool.cc
|
||||||
|
${XTOSKRNL_SOURCE_DIR}/mm/pte.cc
|
||||||
${XTOSKRNL_SOURCE_DIR}/po/idle.cc
|
${XTOSKRNL_SOURCE_DIR}/po/idle.cc
|
||||||
${XTOSKRNL_SOURCE_DIR}/rtl/${ARCH}/dispatch.cc
|
${XTOSKRNL_SOURCE_DIR}/rtl/${ARCH}/dispatch.cc
|
||||||
${XTOSKRNL_SOURCE_DIR}/rtl/${ARCH}/exsup.cc
|
${XTOSKRNL_SOURCE_DIR}/rtl/${ARCH}/exsup.cc
|
||||||
@@ -71,6 +81,8 @@ list(APPEND XTOSKRNL_SOURCE
|
|||||||
${XTOSKRNL_SOURCE_DIR}/rtl/llist.cc
|
${XTOSKRNL_SOURCE_DIR}/rtl/llist.cc
|
||||||
${XTOSKRNL_SOURCE_DIR}/rtl/math.cc
|
${XTOSKRNL_SOURCE_DIR}/rtl/math.cc
|
||||||
${XTOSKRNL_SOURCE_DIR}/rtl/memory.cc
|
${XTOSKRNL_SOURCE_DIR}/rtl/memory.cc
|
||||||
|
${XTOSKRNL_SOURCE_DIR}/rtl/sha1.cc
|
||||||
|
${XTOSKRNL_SOURCE_DIR}/rtl/slist.cc
|
||||||
${XTOSKRNL_SOURCE_DIR}/rtl/string.cc
|
${XTOSKRNL_SOURCE_DIR}/rtl/string.cc
|
||||||
${XTOSKRNL_SOURCE_DIR}/rtl/widestr.cc)
|
${XTOSKRNL_SOURCE_DIR}/rtl/widestr.cc)
|
||||||
|
|
||||||
@@ -82,11 +94,12 @@ add_library(libxtos ${XTOSKRNL_SOURCE})
|
|||||||
|
|
||||||
# Link kernel executable
|
# Link kernel executable
|
||||||
add_executable(xtoskrnl
|
add_executable(xtoskrnl
|
||||||
${XTOSKRNL_SOURCE}
|
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/xtoskrnl.def)
|
${CMAKE_CURRENT_BINARY_DIR}/xtoskrnl.def)
|
||||||
|
|
||||||
# Add linker libraries
|
# Add linker libraries
|
||||||
target_link_libraries(xtoskrnl)
|
target_link_libraries(xtoskrnl
|
||||||
|
PRIVATE
|
||||||
|
libxtos)
|
||||||
|
|
||||||
# Set proper binary name and install target
|
# Set proper binary name and install target
|
||||||
set_target_properties(xtoskrnl PROPERTIES SUFFIX .exe)
|
set_target_properties(xtoskrnl PROPERTIES SUFFIX .exe)
|
||||||
|
|||||||
@@ -4,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
|
management, and process scheduling. The kernel contains the scheduler (sometimes referred to as the Dispatcher), the
|
||||||
cache, object, and memory managers, the security manager, and other executive components described below.
|
cache, object, and memory managers, the security manager, and other executive components described below.
|
||||||
|
|
||||||
|
|
||||||
|
## Kernel Parameters
|
||||||
|
Kernel parameters are XTOS boot-time options used to ensure proper initialization and handling of hardware peripherals.
|
||||||
|
These parameters can be configured either temporarily by editing the boot entry in the bootloader’s selection menu, or
|
||||||
|
permanently by modifying the XTLDR configuration file.
|
||||||
|
|
||||||
|
The following is a consolidated list of available kernel parameters:
|
||||||
|
* **NOXPA**: Disables PAE or LA57 support, depending on the CPU architecture. This parameter is handled by the
|
||||||
|
bootloader, which configures paging and selects the appropriate Page Map Level (PML) before transferring control to
|
||||||
|
the kernel.
|
||||||
|
|
||||||
|
## Source Code
|
||||||
The source code of the kernel is organized into subsystem-specific directories. Each directory name also defines the
|
The source code of the kernel is organized into subsystem-specific directories. Each directory name also defines the
|
||||||
corresponding C++ namespace in which the subsystem's classes and routines reside. These subsystems include:
|
corresponding C++ namespace in which the subsystem's classes and routines reside. These subsystems include:
|
||||||
|
|
||||||
|
|||||||
@@ -13,22 +13,31 @@
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a trap handler for the specified vector.
|
* Creates a trap or interrupt handler for the specified vector.
|
||||||
*
|
*
|
||||||
* @param Vector
|
* @param Vector
|
||||||
* Supplies a trap vector number.
|
* Supplies a trap/interrupt vector number.
|
||||||
|
*
|
||||||
|
* @param Type
|
||||||
|
* Specifies whether the handler is designed to handle an interrupt or a trap.
|
||||||
*
|
*
|
||||||
* @return This macro does not return any value.
|
* @return This macro does not return any value.
|
||||||
*
|
*
|
||||||
* @since XT 1.0
|
* @since XT 1.0
|
||||||
*/
|
*/
|
||||||
.macro ArCreateTrapHandler Vector
|
.macro ArCreateTrapHandler Vector Type
|
||||||
.global ArTrap\Vector
|
.global Ar\Type\Vector
|
||||||
ArTrap\Vector:
|
Ar\Type\Vector:
|
||||||
/* Push fake error code for non-error vectors */
|
/* Check handler type */
|
||||||
|
.ifc \Type,Trap
|
||||||
|
/* Push fake error code for non-error vector traps */
|
||||||
.if \Vector != 8 && \Vector != 10 && \Vector != 11 && \Vector != 12 && \Vector != 13 && \Vector != 14 && \Vector != 17 && \Vector != 30
|
.if \Vector != 8 && \Vector != 10 && \Vector != 11 && \Vector != 12 && \Vector != 13 && \Vector != 14 && \Vector != 17 && \Vector != 30
|
||||||
push $0
|
push $0
|
||||||
.endif
|
.endif
|
||||||
|
.else
|
||||||
|
/* Push fake error code for interrupts */
|
||||||
|
push $0
|
||||||
|
.endif
|
||||||
|
|
||||||
/* Push vector number */
|
/* Push vector number */
|
||||||
push $\Vector
|
push $\Vector
|
||||||
@@ -104,24 +113,39 @@ ArTrap\Vector:
|
|||||||
/* Test previous mode and swap GS if needed */
|
/* Test previous mode and swap GS if needed */
|
||||||
movl $0, TrapPreviousMode(%rbp)
|
movl $0, TrapPreviousMode(%rbp)
|
||||||
mov %cs, %ax
|
mov %cs, %ax
|
||||||
and $1, %al
|
and $3, %al
|
||||||
mov %al, TrapPreviousMode(%rbp)
|
mov %al, TrapPreviousMode(%rbp)
|
||||||
jz KernelMode$\Vector
|
jz KernelMode\Type\Vector
|
||||||
swapgs
|
swapgs
|
||||||
|
jmp UserMode\Type\Vector
|
||||||
|
|
||||||
KernelMode$\Vector:
|
KernelMode\Type\Vector:
|
||||||
/* Push Frame Pointer, clear direction flag and pass to trap dispatcher */
|
/* Save kernel stack pointer (SS:RSP) */
|
||||||
|
movl %ss, %eax
|
||||||
|
mov %eax, TrapSegSs(%rbp)
|
||||||
|
lea TRAP_FRAME_SIZE(%rbp), %rax
|
||||||
|
mov %rax, TrapRsp(%rbp)
|
||||||
|
|
||||||
|
UserMode\Type\Vector:
|
||||||
|
/* Push Frame Pointer and clear direction flag */
|
||||||
mov %rsp, %rcx
|
mov %rsp, %rcx
|
||||||
cld
|
cld
|
||||||
|
|
||||||
|
.ifc \Type,Trap
|
||||||
|
/* Pass to the trap dispatcher */
|
||||||
call ArDispatchTrap
|
call ArDispatchTrap
|
||||||
|
.else
|
||||||
|
/* Pass to the interrupt dispatcher */
|
||||||
|
call ArDispatchTrap
|
||||||
|
.endif
|
||||||
|
|
||||||
/* Test previous mode and swapgs if needed */
|
/* Test previous mode and swapgs if needed */
|
||||||
testb $1, TrapPreviousMode(%rbp)
|
testb $1, TrapPreviousMode(%rbp)
|
||||||
jz KernelModeReturn$\Vector
|
jz KernelModeReturn\Type\Vector
|
||||||
cli
|
cli
|
||||||
swapgs
|
swapgs
|
||||||
|
|
||||||
KernelModeReturn$\Vector:
|
KernelModeReturn\Type\Vector:
|
||||||
/* Restore XMM registers */
|
/* Restore XMM registers */
|
||||||
movdqa TrapXmm0(%rbp), %xmm0
|
movdqa TrapXmm0(%rbp), %xmm0
|
||||||
movdqa TrapXmm1(%rbp), %xmm1
|
movdqa TrapXmm1(%rbp), %xmm1
|
||||||
@@ -173,9 +197,28 @@ KernelModeReturn$\Vector:
|
|||||||
iretq
|
iretq
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
/* Populate common trap handlers */
|
/* Populate common interrupt and trap handlers */
|
||||||
.irp i,0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F
|
.irp i,0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F
|
||||||
.irp j,0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F
|
.irp j,0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F
|
||||||
ArCreateTrapHandler 0x\i\j
|
ArCreateTrapHandler 0x\i\j Interrupt
|
||||||
|
ArCreateTrapHandler 0x\i\j Trap
|
||||||
|
.endr
|
||||||
|
.endr
|
||||||
|
|
||||||
|
/* Define array of pointers to the interrupt handlers */
|
||||||
|
.global ArInterruptEntry
|
||||||
|
ArInterruptEntry:
|
||||||
|
.irp i,0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F
|
||||||
|
.irp j,0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F
|
||||||
|
.quad ArInterrupt0x\i\j
|
||||||
|
.endr
|
||||||
|
.endr
|
||||||
|
|
||||||
|
/* Define array of pointers to the trap handlers */
|
||||||
|
.global ArTrapEntry
|
||||||
|
ArTrapEntry:
|
||||||
|
.irp i,0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F
|
||||||
|
.irp j,0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F
|
||||||
|
.quad ArTrap0x\i\j
|
||||||
.endr
|
.endr
|
||||||
.endr
|
.endr
|
||||||
|
|||||||
@@ -249,34 +249,35 @@ AR::ProcSup::InitializeIdt(IN PKPROCESSOR_BLOCK ProcessorBlock)
|
|||||||
for(Vector = 0; Vector < IDT_ENTRIES; Vector++)
|
for(Vector = 0; Vector < IDT_ENTRIES; Vector++)
|
||||||
{
|
{
|
||||||
/* Set the IDT to handle unexpected interrupts */
|
/* Set the IDT to handle unexpected interrupts */
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, Vector, (PVOID)ArTrap0xFF, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
|
SetIdtGate(ProcessorBlock->IdtBase, Vector, (PVOID)ArInterruptEntry[Vector], KGDT_R0_CODE,
|
||||||
|
KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_INTERRUPT_GATE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Setup IDT handlers for known interrupts and traps */
|
/* 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, 0x00, (PVOID)ArTrapEntry[0x00], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x01, (PVOID)ArTrap0x01, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x01, (PVOID)ArTrapEntry[0x01], 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);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x02, (PVOID)ArTrapEntry[0x02], 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);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x03, (PVOID)ArTrapEntry[0x03], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3, AMD64_TRAP_GATE);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x04, (PVOID)ArTrap0x04, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x04, (PVOID)ArTrapEntry[0x04], 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);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x05, (PVOID)ArTrapEntry[0x05], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x06, (PVOID)ArTrap0x06, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x06, (PVOID)ArTrapEntry[0x06], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x07, (PVOID)ArTrap0x07, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x07, (PVOID)ArTrapEntry[0x07], 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);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x08, (PVOID)ArTrapEntry[0x08], 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);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x09, (PVOID)ArTrapEntry[0x09], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x0A, (PVOID)ArTrap0x0A, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x0A, (PVOID)ArTrapEntry[0x0A], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x0B, (PVOID)ArTrap0x0B, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x0B, (PVOID)ArTrapEntry[0x0B], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x0C, (PVOID)ArTrap0x0C, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x0C, (PVOID)ArTrapEntry[0x0C], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x0D, (PVOID)ArTrap0x0D, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x0D, (PVOID)ArTrapEntry[0x0D], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x0E, (PVOID)ArTrap0x0E, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x0E, (PVOID)ArTrapEntry[0x0E], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x10, (PVOID)ArTrap0x10, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x10, (PVOID)ArTrapEntry[0x10], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x11, (PVOID)ArTrap0x11, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x11, (PVOID)ArTrapEntry[0x11], 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);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x12, (PVOID)ArTrapEntry[0x12], 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);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x13, (PVOID)ArTrapEntry[0x13], 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);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x1F, (PVOID)ArTrapEntry[0x1F], 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);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x2C, (PVOID)ArTrapEntry[0x2C], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3, AMD64_TRAP_GATE);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x2D, (PVOID)ArTrap0x2D, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x2D, (PVOID)ArTrapEntry[0x2D], 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);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x2F, (PVOID)ArTrapEntry[0x2F], 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);
|
SetIdtGate(ProcessorBlock->IdtBase, 0xE1, (PVOID)ArTrapEntry[0xE1], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_INTERRUPT_GATE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -636,6 +637,9 @@ AR::ProcSup::SetGdtEntryBase(IN PKGDTENTRY Gdt,
|
|||||||
* @param Access
|
* @param Access
|
||||||
* Supplies the gate access rights.
|
* Supplies the gate access rights.
|
||||||
*
|
*
|
||||||
|
* @param Type
|
||||||
|
* Supplies the gate type.
|
||||||
|
*
|
||||||
* @return This routine does not return any value.
|
* @return This routine does not return any value.
|
||||||
*
|
*
|
||||||
* @since XT 1.0
|
* @since XT 1.0
|
||||||
@@ -647,15 +651,22 @@ AR::ProcSup::SetIdtGate(IN PKIDTENTRY Idt,
|
|||||||
IN PVOID Handler,
|
IN PVOID Handler,
|
||||||
IN USHORT Selector,
|
IN USHORT Selector,
|
||||||
IN USHORT Ist,
|
IN USHORT Ist,
|
||||||
IN USHORT Access)
|
IN USHORT Dpl,
|
||||||
|
IN USHORT Type)
|
||||||
{
|
{
|
||||||
/* Setup the gate */
|
/* Set the handler's address */
|
||||||
Idt[Vector].OffsetLow = ((ULONG_PTR)Handler & 0xFFFF);
|
Idt[Vector].OffsetLow = ((ULONG_PTR)Handler & 0xFFFF);
|
||||||
Idt[Vector].OffsetMiddle = (((ULONG_PTR)Handler >> 16) & 0xFFFF);
|
Idt[Vector].OffsetMiddle = (((ULONG_PTR)Handler >> 16) & 0xFFFF);
|
||||||
Idt[Vector].OffsetHigh = (ULONG_PTR)Handler >> 32;
|
Idt[Vector].OffsetHigh = (ULONG_PTR)Handler >> 32;
|
||||||
Idt[Vector].Dpl = Access;
|
|
||||||
|
/* Set the code segment selector */
|
||||||
|
Idt[Vector].Selector = Selector;
|
||||||
|
|
||||||
|
/* Initialize the gate's attributes and flags */
|
||||||
|
Idt[Vector].Access = 0;
|
||||||
|
Idt[Vector].Dpl = Dpl;
|
||||||
Idt[Vector].IstIndex = Ist;
|
Idt[Vector].IstIndex = Ist;
|
||||||
Idt[Vector].Present = 1;
|
Idt[Vector].Present = 1;
|
||||||
Idt[Vector].Selector = Selector;
|
Idt[Vector].Reserved1 = 0;
|
||||||
Idt[Vector].Type = 0xE;
|
Idt[Vector].Type = Type;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,22 +13,31 @@
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This macro creates a trap handler for the specified vector.
|
* Creates a trap or interrupt handler for the specified vector.
|
||||||
*
|
*
|
||||||
* @param Vector
|
* @param Vector
|
||||||
* Supplies a trap vector number.
|
* Supplies a trap/interrupt vector number.
|
||||||
|
*
|
||||||
|
* @param Type
|
||||||
|
* Specifies whether the handler is designed to handle an interrupt or a trap.
|
||||||
*
|
*
|
||||||
* @return This macro does not return any value.
|
* @return This macro does not return any value.
|
||||||
*
|
*
|
||||||
* @since XT 1.0
|
* @since XT 1.0
|
||||||
*/
|
*/
|
||||||
.macro ArCreateTrapHandler Vector
|
.macro ArCreateTrapHandler Vector Type
|
||||||
.global _ArTrap\Vector
|
.global _Ar\Type\Vector
|
||||||
_ArTrap\Vector:
|
_Ar\Type\Vector:
|
||||||
/* Push fake error code for non-error vectors */
|
/* Check handler type */
|
||||||
|
.ifc \Type,Trap
|
||||||
|
/* Push fake error code for non-error vector traps */
|
||||||
.if \Vector != 8 && \Vector != 10 && \Vector != 11 && \Vector != 12 && \Vector != 13 && \Vector != 14 && \Vector != 17 && \Vector != 30
|
.if \Vector != 8 && \Vector != 10 && \Vector != 11 && \Vector != 12 && \Vector != 13 && \Vector != 14 && \Vector != 17 && \Vector != 30
|
||||||
push $0
|
push $0
|
||||||
.endif
|
.endif
|
||||||
|
.else
|
||||||
|
/* Push fake error code for interrupts */
|
||||||
|
push $0
|
||||||
|
.endif
|
||||||
|
|
||||||
/* Push vector number */
|
/* Push vector number */
|
||||||
push $\Vector
|
push $\Vector
|
||||||
@@ -75,31 +84,47 @@ _ArTrap\Vector:
|
|||||||
/* Test previous mode and swap GS if needed */
|
/* Test previous mode and swap GS if needed */
|
||||||
movl $0, TrapPreviousMode(%ebp)
|
movl $0, TrapPreviousMode(%ebp)
|
||||||
mov %cs, %ax
|
mov %cs, %ax
|
||||||
and $1, %al
|
and $3, %al
|
||||||
mov %al, TrapPreviousMode(%ebp)
|
mov %al, TrapPreviousMode(%ebp)
|
||||||
jz KernelMode$\Vector
|
jz KernelMode\Type\Vector
|
||||||
swapgs
|
swapgs
|
||||||
|
jmp UserMode\Type\Vector
|
||||||
|
|
||||||
KernelMode$\Vector:
|
KernelMode\Type\Vector:
|
||||||
/* Push Frame Pointer, clear direction flag and pass to trap dispatcher */
|
/* Save kernel stack pointer (SS:ESP) */
|
||||||
|
movl %ss, %eax
|
||||||
|
mov %eax, TrapSegSs(%ebp)
|
||||||
|
lea TrapEsp(%ebp), %eax
|
||||||
|
mov %eax, TrapEsp(%ebp)
|
||||||
|
|
||||||
|
UserMode\Type\Vector:
|
||||||
|
/* Push Frame Pointer and clear direction flag */
|
||||||
push %esp
|
push %esp
|
||||||
cld
|
cld
|
||||||
|
|
||||||
|
.ifc \Type,Trap
|
||||||
|
/* Pass to the trap dispatcher */
|
||||||
call _ArDispatchTrap
|
call _ArDispatchTrap
|
||||||
|
.else
|
||||||
|
/* Pass to the interrupt dispatcher */
|
||||||
|
call _ArDispatchTrap
|
||||||
|
.endif
|
||||||
|
|
||||||
/* Clean up the stack */
|
/* Clean up the stack */
|
||||||
add $4, %esp
|
add $4, %esp
|
||||||
|
|
||||||
/* Test previous mode and swapgs if needed */
|
/* Test previous mode and swapgs if needed */
|
||||||
testb $1, TrapPreviousMode(%ebp)
|
testb $1, TrapPreviousMode(%ebp)
|
||||||
jz KernelModeReturn$\Vector
|
jz KernelModeReturn\Type\Vector
|
||||||
cli
|
cli
|
||||||
swapgs
|
swapgs
|
||||||
|
|
||||||
KernelModeReturn$\Vector:
|
KernelModeReturn\Type\Vector:
|
||||||
/* Restore segment selectors */
|
/* Restore segment selectors */
|
||||||
mov TrapSegDs(%ebp), %ds
|
mov TrapSegDs(%ebp), %ds
|
||||||
mov TrapSegEs(%ebp), %es
|
mov TrapSegEs(%ebp), %es
|
||||||
mov TrapSegFs(%ebp), %fs
|
mov TrapSegFs(%ebp), %fs
|
||||||
|
mov TrapSegGs(%ebp), %gs
|
||||||
|
|
||||||
/* Free stack space */
|
/* Free stack space */
|
||||||
add $(TRAP_FRAME_SIZE - TRAP_REGISTERS_SIZE), %esp
|
add $(TRAP_FRAME_SIZE - TRAP_REGISTERS_SIZE), %esp
|
||||||
@@ -118,9 +143,28 @@ KernelModeReturn$\Vector:
|
|||||||
iretl
|
iretl
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
/* Populate common trap handlers */
|
/* Populate common interrupt and trap handlers */
|
||||||
.irp i,0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F
|
.irp i,0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F
|
||||||
.irp j,0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F
|
.irp j,0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F
|
||||||
ArCreateTrapHandler 0x\i\j
|
ArCreateTrapHandler 0x\i\j Interrupt
|
||||||
|
ArCreateTrapHandler 0x\i\j Trap
|
||||||
|
.endr
|
||||||
|
.endr
|
||||||
|
|
||||||
|
/* Define array of pointers to the interrupt handlers */
|
||||||
|
.global _ArInterruptEntry
|
||||||
|
_ArInterruptEntry:
|
||||||
|
.irp i,0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F
|
||||||
|
.irp j,0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F
|
||||||
|
.long _ArInterrupt0x\i\j
|
||||||
|
.endr
|
||||||
|
.endr
|
||||||
|
|
||||||
|
/* Define array of pointers to the trap handlers */
|
||||||
|
.global _ArTrapEntry
|
||||||
|
_ArTrapEntry:
|
||||||
|
.irp i,0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F
|
||||||
|
.irp j,0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F
|
||||||
|
.long _ArTrap0x\i\j
|
||||||
.endr
|
.endr
|
||||||
.endr
|
.endr
|
||||||
|
|||||||
@@ -242,34 +242,35 @@ AR::ProcSup::InitializeIdt(IN PKPROCESSOR_BLOCK ProcessorBlock)
|
|||||||
for(Vector = 0; Vector < IDT_ENTRIES; Vector++)
|
for(Vector = 0; Vector < IDT_ENTRIES; Vector++)
|
||||||
{
|
{
|
||||||
/* Set the IDT to handle unexpected interrupts */
|
/* Set the IDT to handle unexpected interrupts */
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, Vector, (PVOID)ArTrap0xFF, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
|
SetIdtGate(ProcessorBlock->IdtBase, Vector, (PVOID)ArInterruptEntry[Vector],
|
||||||
|
KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_INTERRUPT_GATE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Setup IDT handlers for known interrupts and traps */
|
/* 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, 0x00, (PVOID)ArTrapEntry[0x00], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x01, (PVOID)ArTrap0x01, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x01, (PVOID)ArTrapEntry[0x01], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x02, (PVOID)ArTrap0x02, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x02, (PVOID)ArTrapEntry[0x02], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_INTERRUPT_GATE);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x03, (PVOID)ArTrap0x03, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING3);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x03, (PVOID)ArTrapEntry[0x03], KGDT_R0_CODE, 0, KIDT_ACCESS_RING3, I686_TRAP_GATE);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x04, (PVOID)ArTrap0x04, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING3);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x04, (PVOID)ArTrapEntry[0x04], KGDT_R0_CODE, 0, KIDT_ACCESS_RING3, I686_TRAP_GATE);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x05, (PVOID)ArTrap0x05, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x05, (PVOID)ArTrapEntry[0x05], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x06, (PVOID)ArTrap0x06, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x06, (PVOID)ArTrapEntry[0x06], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x07, (PVOID)ArTrap0x07, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x07, (PVOID)ArTrapEntry[0x07], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x08, (PVOID)ArTrap0x08, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x08, (PVOID)ArTrapEntry[0x08], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x09, (PVOID)ArTrap0x09, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x09, (PVOID)ArTrapEntry[0x09], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x0A, (PVOID)ArTrap0x0A, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x0A, (PVOID)ArTrapEntry[0x0A], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x0B, (PVOID)ArTrap0x0B, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x0B, (PVOID)ArTrapEntry[0x0B], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x0C, (PVOID)ArTrap0x0C, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x0C, (PVOID)ArTrapEntry[0x0C], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x0D, (PVOID)ArTrap0x0D, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x0D, (PVOID)ArTrapEntry[0x0D], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x0E, (PVOID)ArTrap0x0E, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x0E, (PVOID)ArTrapEntry[0x0E], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x10, (PVOID)ArTrap0x10, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x10, (PVOID)ArTrapEntry[0x10], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x11, (PVOID)ArTrap0x11, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x11, (PVOID)ArTrapEntry[0x11], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x12, (PVOID)ArTrap0x12, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x12, (PVOID)ArTrapEntry[0x12], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x13, (PVOID)ArTrap0x13, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x13, (PVOID)ArTrapEntry[0x13], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x2A, (PVOID)ArTrap0x2A, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING3);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x2A, (PVOID)ArTrapEntry[0x2A], KGDT_R0_CODE, 0, KIDT_ACCESS_RING3, I686_TRAP_GATE);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x2B, (PVOID)ArTrap0x2B, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING3);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x2B, (PVOID)ArTrapEntry[0x2B], KGDT_R0_CODE, 0, KIDT_ACCESS_RING3, I686_TRAP_GATE);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x2C, (PVOID)ArTrap0x2C, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING3);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x2C, (PVOID)ArTrapEntry[0x2C], KGDT_R0_CODE, 0, KIDT_ACCESS_RING3, I686_TRAP_GATE);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x2D, (PVOID)ArTrap0x2D, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING3);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x2D, (PVOID)ArTrapEntry[0x2D], KGDT_R0_CODE, 0, KIDT_ACCESS_RING3, I686_TRAP_GATE);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x2E, (PVOID)ArTrap0x2E, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING3);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x2E, (PVOID)ArTrapEntry[0x2E], KGDT_R0_CODE, 0, KIDT_ACCESS_RING3, I686_TRAP_GATE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -506,7 +507,7 @@ AR::ProcSup::SetDoubleFaultTssEntry(IN PKPROCESSOR_BLOCK ProcessorBlock,
|
|||||||
Tss->CR3 = CpuFunc::ReadControlRegister(3);
|
Tss->CR3 = CpuFunc::ReadControlRegister(3);
|
||||||
Tss->Esp = (ULONG_PTR)KernelFaultStack;
|
Tss->Esp = (ULONG_PTR)KernelFaultStack;
|
||||||
Tss->Esp0 = (ULONG_PTR)KernelFaultStack;
|
Tss->Esp0 = (ULONG_PTR)KernelFaultStack;
|
||||||
Tss->Eip = PtrToUlong(ArTrap0x08);
|
Tss->Eip = PtrToUlong(ArTrapEntry[0x08]);
|
||||||
Tss->Cs = KGDT_R0_CODE;
|
Tss->Cs = KGDT_R0_CODE;
|
||||||
Tss->Ds = KGDT_R3_DATA | RPL_MASK;
|
Tss->Ds = KGDT_R3_DATA | RPL_MASK;
|
||||||
Tss->Es = KGDT_R3_DATA | RPL_MASK;
|
Tss->Es = KGDT_R3_DATA | RPL_MASK;
|
||||||
@@ -656,6 +657,9 @@ AR::ProcSup::SetGdtEntryBase(IN PKGDTENTRY Gdt,
|
|||||||
* @param Access
|
* @param Access
|
||||||
* Supplies the gate access rights.
|
* Supplies the gate access rights.
|
||||||
*
|
*
|
||||||
|
* @param Type
|
||||||
|
* Supplies the gate type.
|
||||||
|
*
|
||||||
* @return This routine does not return any value.
|
* @return This routine does not return any value.
|
||||||
*
|
*
|
||||||
* @since XT 1.0
|
* @since XT 1.0
|
||||||
@@ -667,13 +671,21 @@ AR::ProcSup::SetIdtGate(IN PKIDTENTRY Idt,
|
|||||||
IN PVOID Handler,
|
IN PVOID Handler,
|
||||||
IN USHORT Selector,
|
IN USHORT Selector,
|
||||||
IN USHORT Ist,
|
IN USHORT Ist,
|
||||||
IN USHORT Access)
|
IN USHORT Dpl,
|
||||||
|
IN USHORT Type)
|
||||||
{
|
{
|
||||||
/* Setup the gate */
|
/* Set the handler's address */
|
||||||
Idt[Vector].Offset = (USHORT)((ULONG)Handler & 0xFFFF);
|
Idt[Vector].Offset = (USHORT)((ULONG)Handler & 0xFFFF);
|
||||||
Idt[Vector].ExtendedOffset = (USHORT)((ULONG)Handler >> 16);
|
Idt[Vector].ExtendedOffset = (USHORT)((ULONG)Handler >> 16);
|
||||||
Idt[Vector].Access = 0x8000 | (Access << 8);
|
|
||||||
|
/* Set the code segment selector */
|
||||||
Idt[Vector].Selector = Selector;
|
Idt[Vector].Selector = Selector;
|
||||||
|
|
||||||
|
/* Initialize the gate's attributes and flags */
|
||||||
|
Idt[Vector].Access = 0;
|
||||||
|
Idt[Vector].Dpl = Dpl;
|
||||||
|
Idt[Vector].Present = 1;
|
||||||
|
Idt[Vector].Type = Type;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -709,7 +721,7 @@ AR::ProcSup::SetNonMaskableInterruptTssEntry(IN PKPROCESSOR_BLOCK ProcessorBlock
|
|||||||
Tss->CR3 = CpuFunc::ReadControlRegister(3);
|
Tss->CR3 = CpuFunc::ReadControlRegister(3);
|
||||||
Tss->Esp = (ULONG_PTR)KernelFaultStack;
|
Tss->Esp = (ULONG_PTR)KernelFaultStack;
|
||||||
Tss->Esp0 = (ULONG_PTR)KernelFaultStack;
|
Tss->Esp0 = (ULONG_PTR)KernelFaultStack;
|
||||||
Tss->Eip = PtrToUlong(ArTrap0x02);
|
Tss->Eip = PtrToUlong(ArTrapEntry[0x02]);
|
||||||
Tss->Cs = KGDT_R0_CODE;
|
Tss->Cs = KGDT_R0_CODE;
|
||||||
Tss->Ds = KGDT_R3_DATA | RPL_MASK;
|
Tss->Ds = KGDT_R3_DATA | RPL_MASK;
|
||||||
Tss->Es = KGDT_R3_DATA | RPL_MASK;
|
Tss->Es = KGDT_R3_DATA | RPL_MASK;
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
/**
|
/**
|
||||||
* PROJECT: ExectOS
|
* PROJECT: ExectOS
|
||||||
* COPYRIGHT: See COPYING.md in the top level directory
|
* COPYRIGHT: See COPYING.md in the top level directory
|
||||||
* FILE: xtoskrnl/ke/i686/irq.cc
|
* FILE: xtoskrnl/hl/amd64/irq.cc
|
||||||
* DESCRIPTION: Kernel interrupts support for i686 architecture
|
* DESCRIPTION: Interrupts support for amd64 architecture
|
||||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||||
|
* Aiken Harris <harraiken91@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <xtos.hh>
|
#include <xtos.hh>
|
||||||
@@ -24,7 +25,7 @@
|
|||||||
*/
|
*/
|
||||||
XTAPI
|
XTAPI
|
||||||
VOID
|
VOID
|
||||||
KE::Irq::SetInterruptHandler(IN ULONG Vector,
|
HL::Irq::SetInterruptHandler(IN ULONG Vector,
|
||||||
IN PVOID Handler)
|
IN PVOID Handler)
|
||||||
{
|
{
|
||||||
PKPROCESSOR_BLOCK ProcessorBlock;
|
PKPROCESSOR_BLOCK ProcessorBlock;
|
||||||
@@ -33,6 +34,11 @@ KE::Irq::SetInterruptHandler(IN ULONG Vector,
|
|||||||
ProcessorBlock = KE::Processor::GetCurrentProcessorBlock();
|
ProcessorBlock = KE::Processor::GetCurrentProcessorBlock();
|
||||||
|
|
||||||
/* Update interrupt handler */
|
/* Update interrupt handler */
|
||||||
ProcessorBlock->IdtBase[(UCHAR) Vector].Offset = (USHORT)((ULONG)Handler & 0xFFFF);
|
AR::ProcSup::SetIdtGate(ProcessorBlock->IdtBase,
|
||||||
ProcessorBlock->IdtBase[(UCHAR) Vector].ExtendedOffset = (USHORT)((ULONG)Handler >> 16);
|
Vector,
|
||||||
|
Handler,
|
||||||
|
KGDT_R0_CODE,
|
||||||
|
0,
|
||||||
|
KIDT_ACCESS_RING0,
|
||||||
|
AMD64_INTERRUPT_GATE);
|
||||||
}
|
}
|
||||||
@@ -1,9 +1,10 @@
|
|||||||
/**
|
/**
|
||||||
* PROJECT: ExectOS
|
* PROJECT: ExectOS
|
||||||
* COPYRIGHT: See COPYING.md in the top level directory
|
* COPYRIGHT: See COPYING.md in the top level directory
|
||||||
* FILE: xtoskrnl/ke/amd64/irq.cc
|
* FILE: xtoskrnl/hl/i686/irq.cc
|
||||||
* DESCRIPTION: Kernel interrupts support for amd64 architecture
|
* DESCRIPTION: Interrupts support for i686 architecture
|
||||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||||
|
* Aiken Harris <harraiken91@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <xtos.hh>
|
#include <xtos.hh>
|
||||||
@@ -24,7 +25,7 @@
|
|||||||
*/
|
*/
|
||||||
XTAPI
|
XTAPI
|
||||||
VOID
|
VOID
|
||||||
KE::Irq::SetInterruptHandler(IN ULONG Vector,
|
HL::Irq::SetInterruptHandler(IN ULONG Vector,
|
||||||
IN PVOID Handler)
|
IN PVOID Handler)
|
||||||
{
|
{
|
||||||
PKPROCESSOR_BLOCK ProcessorBlock;
|
PKPROCESSOR_BLOCK ProcessorBlock;
|
||||||
@@ -33,7 +34,11 @@ KE::Irq::SetInterruptHandler(IN ULONG Vector,
|
|||||||
ProcessorBlock = KE::Processor::GetCurrentProcessorBlock();
|
ProcessorBlock = KE::Processor::GetCurrentProcessorBlock();
|
||||||
|
|
||||||
/* Update interrupt handler */
|
/* Update interrupt handler */
|
||||||
ProcessorBlock->IdtBase[(UCHAR) Vector].OffsetLow = ((ULONG_PTR)Handler & 0xFFFF);
|
AR::ProcSup::SetIdtGate(ProcessorBlock->IdtBase,
|
||||||
ProcessorBlock->IdtBase[(UCHAR) Vector].OffsetMiddle = (((ULONG_PTR)Handler >> 16) & 0xFFFF);
|
Vector,
|
||||||
ProcessorBlock->IdtBase[(UCHAR) Vector].OffsetHigh = (ULONG_PTR)Handler >> 32;
|
Handler,
|
||||||
|
KGDT_R0_CODE,
|
||||||
|
0,
|
||||||
|
KIDT_ACCESS_RING0,
|
||||||
|
I686_INTERRUPT_GATE);
|
||||||
}
|
}
|
||||||
@@ -9,6 +9,41 @@
|
|||||||
#include <xtos.hh>
|
#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.
|
* Checks whether the x2APIC extension is supported by the processor.
|
||||||
*
|
*
|
||||||
@@ -124,6 +159,14 @@ HL::Pic::InitializeApic(VOID)
|
|||||||
APIC_LVT_REGISTER LvtRegister;
|
APIC_LVT_REGISTER LvtRegister;
|
||||||
ULONG CpuNumber;
|
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) */
|
/* Determine APIC mode (xAPIC compatibility or x2APIC) */
|
||||||
if(CheckX2ApicSupport())
|
if(CheckX2ApicSupport())
|
||||||
{
|
{
|
||||||
@@ -206,8 +249,8 @@ HL::Pic::InitializeApic(VOID)
|
|||||||
WriteApicRegister(APIC_LINT1, LvtRegister.Long);
|
WriteApicRegister(APIC_LINT1, LvtRegister.Long);
|
||||||
|
|
||||||
/* Register interrupt handlers */
|
/* Register interrupt handlers */
|
||||||
KE::Irq::SetInterruptHandler(APIC_VECTOR_SPURIOUS, (PVOID)HandleApicSpuriousService);
|
HL::Irq::SetInterruptHandler(APIC_VECTOR_SPURIOUS, (PVOID)HandleApicSpuriousService);
|
||||||
KE::Irq::SetInterruptHandler(PIC1_VECTOR_SPURIOUS, (PVOID)HandlePicSpuriousService);
|
HL::Irq::SetInterruptHandler(PIC1_VECTOR_SPURIOUS, (PVOID)HandlePicSpuriousService);
|
||||||
|
|
||||||
/* Clear any pre-existing errors */
|
/* Clear any pre-existing errors */
|
||||||
WriteApicRegister(APIC_ESR, 0);
|
WriteApicRegister(APIC_ESR, 0);
|
||||||
|
|||||||
@@ -56,6 +56,8 @@
|
|||||||
#define TrapSegEs 330
|
#define TrapSegEs 330
|
||||||
#define TrapSegFs 332
|
#define TrapSegFs 332
|
||||||
#define TrapSegGs 334
|
#define TrapSegGs 334
|
||||||
|
#define TrapRsp 496
|
||||||
|
#define TrapSegSs 504
|
||||||
|
|
||||||
/* KTRAP_FRAME length related definitions */
|
/* KTRAP_FRAME length related definitions */
|
||||||
#define TRAP_FRAME_SIZE 512
|
#define TRAP_FRAME_SIZE 512
|
||||||
|
|||||||
@@ -15,9 +15,14 @@
|
|||||||
/* TrampolineEnableXpa end address to calculate trampoline size */
|
/* TrampolineEnableXpa end address to calculate trampoline size */
|
||||||
XTCLINK PVOID ArEnableExtendedPhysicalAddressingEnd[];
|
XTCLINK PVOID ArEnableExtendedPhysicalAddressingEnd[];
|
||||||
|
|
||||||
|
/* External array of pointers to the interrupt handlers */
|
||||||
|
XTCLINK ULONG_PTR ArInterruptEntry[256];
|
||||||
|
|
||||||
/* TrampolineApStartup end address to calculate trampoline size */
|
/* TrampolineApStartup end address to calculate trampoline size */
|
||||||
XTCLINK PVOID ArStartApplicationProcessorEnd[];
|
XTCLINK PVOID ArStartApplicationProcessorEnd[];
|
||||||
|
|
||||||
|
/* External array of pointers to the trap handlers */
|
||||||
|
XTCLINK ULONG_PTR ArTrapEntry[256];
|
||||||
|
|
||||||
/* Forward reference for assembler code */
|
/* Forward reference for assembler code */
|
||||||
XTCLINK
|
XTCLINK
|
||||||
@@ -30,129 +35,4 @@ XTCDECL
|
|||||||
VOID
|
VOID
|
||||||
ArStartApplicationProcessor(VOID);
|
ArStartApplicationProcessor(VOID);
|
||||||
|
|
||||||
XTCLINK
|
|
||||||
XTCDECL
|
|
||||||
VOID
|
|
||||||
ArTrap0x00(VOID);
|
|
||||||
|
|
||||||
XTCLINK
|
|
||||||
XTCDECL
|
|
||||||
VOID
|
|
||||||
ArTrap0x01(VOID);
|
|
||||||
|
|
||||||
XTCLINK
|
|
||||||
XTCDECL
|
|
||||||
VOID
|
|
||||||
ArTrap0x02(VOID);
|
|
||||||
|
|
||||||
XTCLINK
|
|
||||||
XTCDECL
|
|
||||||
VOID
|
|
||||||
ArTrap0x03(VOID);
|
|
||||||
|
|
||||||
XTCLINK
|
|
||||||
XTCDECL
|
|
||||||
VOID
|
|
||||||
ArTrap0x04(VOID);
|
|
||||||
|
|
||||||
XTCLINK
|
|
||||||
XTCDECL
|
|
||||||
VOID
|
|
||||||
ArTrap0x05(VOID);
|
|
||||||
|
|
||||||
XTCLINK
|
|
||||||
XTCDECL
|
|
||||||
VOID
|
|
||||||
ArTrap0x06(VOID);
|
|
||||||
|
|
||||||
XTCLINK
|
|
||||||
XTCDECL
|
|
||||||
VOID
|
|
||||||
ArTrap0x07(VOID);
|
|
||||||
|
|
||||||
XTCLINK
|
|
||||||
XTCDECL
|
|
||||||
VOID
|
|
||||||
ArTrap0x08(VOID);
|
|
||||||
|
|
||||||
XTCLINK
|
|
||||||
XTCDECL
|
|
||||||
VOID
|
|
||||||
ArTrap0x09(VOID);
|
|
||||||
|
|
||||||
XTCLINK
|
|
||||||
XTCDECL
|
|
||||||
VOID
|
|
||||||
ArTrap0x0A(VOID);
|
|
||||||
|
|
||||||
XTCLINK
|
|
||||||
XTCDECL
|
|
||||||
VOID
|
|
||||||
ArTrap0x0B(VOID);
|
|
||||||
|
|
||||||
XTCLINK
|
|
||||||
XTCDECL
|
|
||||||
VOID
|
|
||||||
ArTrap0x0C(VOID);
|
|
||||||
|
|
||||||
XTCLINK
|
|
||||||
XTCDECL
|
|
||||||
VOID
|
|
||||||
ArTrap0x0D(VOID);
|
|
||||||
|
|
||||||
XTCLINK
|
|
||||||
XTCDECL
|
|
||||||
VOID
|
|
||||||
ArTrap0x0E(VOID);
|
|
||||||
|
|
||||||
XTCLINK
|
|
||||||
XTCDECL
|
|
||||||
VOID
|
|
||||||
ArTrap0x10(VOID);
|
|
||||||
|
|
||||||
XTCLINK
|
|
||||||
XTCDECL
|
|
||||||
VOID
|
|
||||||
ArTrap0x11(VOID);
|
|
||||||
|
|
||||||
XTCLINK
|
|
||||||
XTCDECL
|
|
||||||
VOID
|
|
||||||
ArTrap0x12(VOID);
|
|
||||||
|
|
||||||
XTCLINK
|
|
||||||
XTCDECL
|
|
||||||
VOID
|
|
||||||
ArTrap0x13(VOID);
|
|
||||||
|
|
||||||
XTCLINK
|
|
||||||
XTCDECL
|
|
||||||
VOID
|
|
||||||
ArTrap0x1F(VOID);
|
|
||||||
|
|
||||||
XTCLINK
|
|
||||||
XTCDECL
|
|
||||||
VOID
|
|
||||||
ArTrap0x2C(VOID);
|
|
||||||
|
|
||||||
XTCLINK
|
|
||||||
XTCDECL
|
|
||||||
VOID
|
|
||||||
ArTrap0x2D(VOID);
|
|
||||||
|
|
||||||
XTCLINK
|
|
||||||
XTCDECL
|
|
||||||
VOID
|
|
||||||
ArTrap0x2F(VOID);
|
|
||||||
|
|
||||||
XTCLINK
|
|
||||||
XTCDECL
|
|
||||||
VOID
|
|
||||||
ArTrap0xE1(VOID);
|
|
||||||
|
|
||||||
XTCLINK
|
|
||||||
XTCDECL
|
|
||||||
VOID
|
|
||||||
ArTrap0xFF(VOID);
|
|
||||||
|
|
||||||
#endif /* __XTOSKRNL_AR_ASSEMBLY_HH */
|
#endif /* __XTOSKRNL_AR_ASSEMBLY_HH */
|
||||||
|
|||||||
@@ -31,6 +31,13 @@ namespace AR
|
|||||||
OUT PVOID *TrampolineCode,
|
OUT PVOID *TrampolineCode,
|
||||||
OUT PULONG_PTR TrampolineSize);
|
OUT PULONG_PTR TrampolineSize);
|
||||||
STATIC XTAPI VOID InitializeProcessor(IN PVOID ProcessorStructures);
|
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:
|
private:
|
||||||
STATIC XTAPI VOID IdentifyProcessor(VOID);
|
STATIC XTAPI VOID IdentifyProcessor(VOID);
|
||||||
@@ -62,12 +69,6 @@ namespace AR
|
|||||||
STATIC XTAPI VOID SetGdtEntryBase(IN PKGDTENTRY Gdt,
|
STATIC XTAPI VOID SetGdtEntryBase(IN PKGDTENTRY Gdt,
|
||||||
IN USHORT Selector,
|
IN USHORT Selector,
|
||||||
IN ULONG_PTR Base);
|
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 TrapSegEs 38
|
||||||
#define TrapSegFs 40
|
#define TrapSegFs 40
|
||||||
#define TrapSegGs 42
|
#define TrapSegGs 42
|
||||||
|
#define TrapEsp 92
|
||||||
|
#define TrapSegSs 96
|
||||||
|
|
||||||
/* KTRAP_FRAME length related definitions */
|
/* KTRAP_FRAME length related definitions */
|
||||||
#define TRAP_FRAME_SIZE 100
|
#define TRAP_FRAME_SIZE 100
|
||||||
#define TRAP_REGISTERS_SIZE 56
|
#define TRAP_REGISTERS_SIZE 56
|
||||||
|
|
||||||
#endif /* __XTOSKRNL_AMD64_ASMSUP_H */
|
#endif /* __XTOSKRNL_I686_ASMSUP_H */
|
||||||
|
|||||||
@@ -12,9 +12,14 @@
|
|||||||
#include <xtos.hh>
|
#include <xtos.hh>
|
||||||
|
|
||||||
|
|
||||||
|
/* External array of pointers to the interrupt handlers */
|
||||||
|
XTCLINK ULONG_PTR ArInterruptEntry[256];
|
||||||
|
|
||||||
/* TrampolineApStartup end address to calculate trampoline size */
|
/* TrampolineApStartup end address to calculate trampoline size */
|
||||||
XTCLINK PVOID ArStartApplicationProcessorEnd[];
|
XTCLINK PVOID ArStartApplicationProcessorEnd[];
|
||||||
|
|
||||||
|
/* External array of pointers to the trap handlers */
|
||||||
|
XTCLINK ULONG_PTR ArTrapEntry[256];
|
||||||
|
|
||||||
/* Forward reference for assembler code */
|
/* Forward reference for assembler code */
|
||||||
XTCLINK
|
XTCLINK
|
||||||
@@ -22,130 +27,4 @@ XTCDECL
|
|||||||
VOID
|
VOID
|
||||||
ArStartApplicationProcessor(VOID);
|
ArStartApplicationProcessor(VOID);
|
||||||
|
|
||||||
XTCLINK
|
|
||||||
XTCDECL
|
|
||||||
VOID
|
|
||||||
ArTrap0x00(VOID);
|
|
||||||
|
|
||||||
XTCLINK
|
|
||||||
XTCDECL
|
|
||||||
VOID
|
|
||||||
ArTrap0x01(VOID);
|
|
||||||
|
|
||||||
XTCLINK
|
|
||||||
XTCDECL
|
|
||||||
VOID
|
|
||||||
ArTrap0x02(VOID);
|
|
||||||
|
|
||||||
XTCLINK
|
|
||||||
XTCDECL
|
|
||||||
VOID
|
|
||||||
ArTrap0x03(VOID);
|
|
||||||
|
|
||||||
XTCLINK
|
|
||||||
XTCDECL
|
|
||||||
VOID
|
|
||||||
ArTrap0x04(VOID);
|
|
||||||
|
|
||||||
XTCLINK
|
|
||||||
XTCDECL
|
|
||||||
VOID
|
|
||||||
ArTrap0x05(VOID);
|
|
||||||
|
|
||||||
XTCLINK
|
|
||||||
XTCDECL
|
|
||||||
VOID
|
|
||||||
ArTrap0x06(VOID);
|
|
||||||
|
|
||||||
XTCLINK
|
|
||||||
XTCDECL
|
|
||||||
VOID
|
|
||||||
ArTrap0x07(VOID);
|
|
||||||
|
|
||||||
XTCLINK
|
|
||||||
XTCDECL
|
|
||||||
VOID
|
|
||||||
ArTrap0x08(VOID);
|
|
||||||
|
|
||||||
XTCLINK
|
|
||||||
XTCDECL
|
|
||||||
VOID
|
|
||||||
ArTrap0x09(VOID);
|
|
||||||
|
|
||||||
XTCLINK
|
|
||||||
XTCDECL
|
|
||||||
VOID
|
|
||||||
ArTrap0x0A(VOID);
|
|
||||||
|
|
||||||
XTCLINK
|
|
||||||
XTCDECL
|
|
||||||
VOID
|
|
||||||
ArTrap0x0B(VOID);
|
|
||||||
|
|
||||||
XTCLINK
|
|
||||||
XTCDECL
|
|
||||||
VOID
|
|
||||||
ArTrap0x0C(VOID);
|
|
||||||
|
|
||||||
XTCLINK
|
|
||||||
XTCDECL
|
|
||||||
VOID
|
|
||||||
ArTrap0x0D(VOID);
|
|
||||||
|
|
||||||
XTCLINK
|
|
||||||
XTCDECL
|
|
||||||
VOID
|
|
||||||
ArTrap0x0E(VOID);
|
|
||||||
|
|
||||||
XTCLINK
|
|
||||||
XTCDECL
|
|
||||||
VOID
|
|
||||||
ArTrap0x10(VOID);
|
|
||||||
|
|
||||||
XTCLINK
|
|
||||||
XTCDECL
|
|
||||||
VOID
|
|
||||||
ArTrap0x11(VOID);
|
|
||||||
|
|
||||||
XTCLINK
|
|
||||||
XTCDECL
|
|
||||||
VOID
|
|
||||||
ArTrap0x12(VOID);
|
|
||||||
|
|
||||||
XTCLINK
|
|
||||||
XTCDECL
|
|
||||||
VOID
|
|
||||||
ArTrap0x13(VOID);
|
|
||||||
|
|
||||||
XTCLINK
|
|
||||||
XTCDECL
|
|
||||||
VOID
|
|
||||||
ArTrap0x2A(VOID);
|
|
||||||
|
|
||||||
XTCLINK
|
|
||||||
XTCDECL
|
|
||||||
VOID
|
|
||||||
ArTrap0x2B(VOID);
|
|
||||||
|
|
||||||
XTCLINK
|
|
||||||
XTCDECL
|
|
||||||
VOID
|
|
||||||
ArTrap0x2C(VOID);
|
|
||||||
|
|
||||||
XTCLINK
|
|
||||||
XTCDECL
|
|
||||||
VOID
|
|
||||||
ArTrap0x2D(VOID);
|
|
||||||
|
|
||||||
XTCLINK
|
|
||||||
XTCDECL
|
|
||||||
VOID
|
|
||||||
ArTrap0x2E(VOID);
|
|
||||||
|
|
||||||
XTCLINK
|
|
||||||
XTCDECL
|
|
||||||
VOID
|
|
||||||
ArTrap0xFF(VOID);
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* __XTOSKRNL_AR_ASSEMBLY_HH */
|
#endif /* __XTOSKRNL_AR_ASSEMBLY_HH */
|
||||||
|
|||||||
@@ -34,6 +34,13 @@ namespace AR
|
|||||||
OUT PVOID *TrampolineCode,
|
OUT PVOID *TrampolineCode,
|
||||||
OUT PULONG_PTR TrampolineSize);
|
OUT PULONG_PTR TrampolineSize);
|
||||||
STATIC XTAPI VOID InitializeProcessor(IN PVOID ProcessorStructures);
|
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:
|
private:
|
||||||
STATIC XTAPI VOID IdentifyProcessor(VOID);
|
STATIC XTAPI VOID IdentifyProcessor(VOID);
|
||||||
@@ -67,12 +74,6 @@ namespace AR
|
|||||||
STATIC XTAPI VOID SetGdtEntryBase(IN PKGDTENTRY Gdt,
|
STATIC XTAPI VOID SetGdtEntryBase(IN PKGDTENTRY Gdt,
|
||||||
IN USHORT Selector,
|
IN USHORT Selector,
|
||||||
IN ULONG_PTR Base);
|
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,
|
STATIC XTAPI VOID SetNonMaskableInterruptTssEntry(IN PKPROCESSOR_BLOCK ProcessorBlock,
|
||||||
IN PVOID KernelFaultStack);
|
IN PVOID KernelFaultStack);
|
||||||
|
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
#include <hl/init.hh>
|
#include <hl/init.hh>
|
||||||
#include <hl/ioport.hh>
|
#include <hl/ioport.hh>
|
||||||
#include <hl/ioreg.hh>
|
#include <hl/ioreg.hh>
|
||||||
|
#include <hl/irq.hh>
|
||||||
#include <hl/pic.hh>
|
#include <hl/pic.hh>
|
||||||
#include <hl/runlevel.hh>
|
#include <hl/runlevel.hh>
|
||||||
|
|
||||||
|
|||||||
@@ -1,19 +1,19 @@
|
|||||||
/**
|
/**
|
||||||
* PROJECT: ExectOS
|
* PROJECT: ExectOS
|
||||||
* COPYRIGHT: See COPYING.md in the top level directory
|
* COPYRIGHT: See COPYING.md in the top level directory
|
||||||
* FILE: xtoskrnl/includes/ke/irq.hh
|
* FILE: xtoskrnl/includes/hl/irq.hh
|
||||||
* DESCRIPTION: Kernel interrupts support
|
* DESCRIPTION: Interrupts support
|
||||||
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
|
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __XTOSKRNL_KE_IRQ_HH
|
#ifndef __XTOSKRNL_HL_IRQ_HH
|
||||||
#define __XTOSKRNL_KE_IRQ_HH
|
#define __XTOSKRNL_HL_IRQ_HH
|
||||||
|
|
||||||
#include <xtos.hh>
|
#include <xtos.hh>
|
||||||
|
|
||||||
|
|
||||||
/* Kernel Library */
|
/* Hardware Layer */
|
||||||
namespace KE
|
namespace HL
|
||||||
{
|
{
|
||||||
class Irq
|
class Irq
|
||||||
{
|
{
|
||||||
@@ -23,4 +23,4 @@ namespace KE
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* __XTOSKRNL_KE_IRQ_HH */
|
#endif /* __XTOSKRNL_HL_IRQ_HH */
|
||||||
@@ -32,6 +32,7 @@ namespace HL
|
|||||||
IN ULONGLONG Value);
|
IN ULONGLONG Value);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
STATIC XTAPI BOOLEAN CheckApicSupport(VOID);
|
||||||
STATIC XTAPI BOOLEAN CheckX2ApicSupport(VOID);
|
STATIC XTAPI BOOLEAN CheckX2ApicSupport(VOID);
|
||||||
STATIC XTCDECL VOID HandleApicSpuriousService(VOID);
|
STATIC XTCDECL VOID HandleApicSpuriousService(VOID);
|
||||||
STATIC XTCDECL VOID HandlePicSpuriousService(VOID);
|
STATIC XTCDECL VOID HandlePicSpuriousService(VOID);
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
#include <ke/crash.hh>
|
#include <ke/crash.hh>
|
||||||
#include <ke/dpc.hh>
|
#include <ke/dpc.hh>
|
||||||
#include <ke/event.hh>
|
#include <ke/event.hh>
|
||||||
#include <ke/irq.hh>
|
#include <ke/guard.hh>
|
||||||
#include <ke/kprocess.hh>
|
#include <ke/kprocess.hh>
|
||||||
#include <ke/krnlinit.hh>
|
#include <ke/krnlinit.hh>
|
||||||
#include <ke/kthread.hh>
|
#include <ke/kthread.hh>
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ namespace KE
|
|||||||
public:
|
public:
|
||||||
STATIC XTAPI VOID HaltSystem(VOID);
|
STATIC XTAPI VOID HaltSystem(VOID);
|
||||||
STATIC XTAPI VOID Panic(IN ULONG Code);
|
STATIC XTAPI VOID Panic(IN ULONG Code);
|
||||||
STATIC XTAPI VOID PanicEx(IN ULONG Code,
|
STATIC XTAPI VOID Panic(IN ULONG Code,
|
||||||
IN ULONG_PTR Parameter1,
|
IN ULONG_PTR Parameter1,
|
||||||
IN ULONG_PTR Parameter2,
|
IN ULONG_PTR Parameter2,
|
||||||
IN ULONG_PTR Parameter3,
|
IN ULONG_PTR Parameter3,
|
||||||
|
|||||||
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 */
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
/**
|
|
||||||
* PROJECT: ExectOS
|
|
||||||
* COPYRIGHT: See COPYING.md in the top level directory
|
|
||||||
* FILE: xtoskrnl/includes/ke/info.hh
|
|
||||||
* DESCRIPTION: Generic kernel information support
|
|
||||||
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __XTOSKRNL_KE_INFO_HH
|
|
||||||
#define __XTOSKRNL_KE_INFO_HH
|
|
||||||
|
|
||||||
#include <xtos.hh>
|
|
||||||
|
|
||||||
|
|
||||||
/* Kernel Library */
|
|
||||||
namespace KE
|
|
||||||
{
|
|
||||||
class Info
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
STATIC XTAPI SYSTEM_FIRMWARE_TYPE GetFirmwareType(VOID);
|
|
||||||
STATIC XTAPI XTSTATUS GetKernelParameter(IN PCWSTR ParameterName,
|
|
||||||
OUT PCWSTR *Parameter);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* __XTOSKRNL_KE_INFO_HH */
|
|
||||||
@@ -22,6 +22,48 @@ namespace KE
|
|||||||
STATIC XTFASTCALL VOID LowerRunLevel(IN KRUNLEVEL RunLevel);
|
STATIC XTFASTCALL VOID LowerRunLevel(IN KRUNLEVEL RunLevel);
|
||||||
STATIC XTFASTCALL KRUNLEVEL RaiseRunLevel(IN KRUNLEVEL RunLevel);
|
STATIC XTFASTCALL KRUNLEVEL RaiseRunLevel(IN KRUNLEVEL RunLevel);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class LowerRunLevel
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
KRUNLEVEL PreviousRunLevel;
|
||||||
|
|
||||||
|
public:
|
||||||
|
LowerRunLevel(KRUNLEVEL RunLevel)
|
||||||
|
{
|
||||||
|
PreviousRunLevel = KE::RunLevel::GetCurrentRunLevel();
|
||||||
|
KE::RunLevel::LowerRunLevel(RunLevel);
|
||||||
|
}
|
||||||
|
|
||||||
|
~LowerRunLevel()
|
||||||
|
{
|
||||||
|
KE::RunLevel::RaiseRunLevel(PreviousRunLevel);
|
||||||
|
}
|
||||||
|
|
||||||
|
LowerRunLevel(const LowerRunLevel&) = delete;
|
||||||
|
LowerRunLevel& operator=(const LowerRunLevel&) = delete;
|
||||||
|
};
|
||||||
|
|
||||||
|
class RaiseRunLevel
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
KRUNLEVEL PreviousRunLevel;
|
||||||
|
|
||||||
|
public:
|
||||||
|
RaiseRunLevel(KRUNLEVEL RunLevel)
|
||||||
|
{
|
||||||
|
PreviousRunLevel = KE::RunLevel::GetCurrentRunLevel();
|
||||||
|
KE::RunLevel::RaiseRunLevel(RunLevel);
|
||||||
|
}
|
||||||
|
|
||||||
|
~RaiseRunLevel()
|
||||||
|
{
|
||||||
|
KE::RunLevel::LowerRunLevel(PreviousRunLevel);
|
||||||
|
}
|
||||||
|
|
||||||
|
RaiseRunLevel(const RaiseRunLevel&) = delete;
|
||||||
|
RaiseRunLevel& operator=(const RaiseRunLevel&) = delete;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* __XTOSKRNL_KE_RUNLEVEL_HH */
|
#endif /* __XTOSKRNL_KE_RUNLEVEL_HH */
|
||||||
|
|||||||
@@ -17,12 +17,32 @@ namespace KE
|
|||||||
{
|
{
|
||||||
class SpinLock
|
class SpinLock
|
||||||
{
|
{
|
||||||
|
private:
|
||||||
|
STATIC KSPIN_LOCK DispatcherLockQueue;
|
||||||
|
STATIC KSPIN_LOCK ExpansionLockQueue;
|
||||||
|
STATIC KSPIN_LOCK FileSystemLockQueue;
|
||||||
|
STATIC KSPIN_LOCK IoCancelLockQueue;
|
||||||
|
STATIC KSPIN_LOCK IoCompletionLockQueue;
|
||||||
|
STATIC KSPIN_LOCK IoDatabaseLockQueue;
|
||||||
|
STATIC KSPIN_LOCK IoVpbLockQueue;
|
||||||
|
STATIC KSPIN_LOCK MasterLockQueue;
|
||||||
|
STATIC KSPIN_LOCK NonPagedAllocLockQueue;
|
||||||
|
STATIC KSPIN_LOCK NonPagedPoolLockQueue;
|
||||||
|
STATIC KSPIN_LOCK PfnLockQueue;
|
||||||
|
STATIC KSPIN_LOCK SystemSpaceLockQueue;
|
||||||
|
STATIC KSPIN_LOCK TimerTableLockQueue;
|
||||||
|
STATIC KSPIN_LOCK VacbLockQueue;
|
||||||
|
STATIC KSPIN_LOCK WorkLockQueue;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
STATIC XTFASTCALL VOID AcquireQueuedSpinLock(IN KSPIN_LOCK_QUEUE_LEVEL LockLevel);
|
STATIC XTFASTCALL VOID AcquireQueuedSpinLock(IN KSPIN_LOCK_QUEUE_LEVEL LockLevel);
|
||||||
STATIC XTFASTCALL VOID AcquireSpinLock(IN OUT PKSPIN_LOCK SpinLock);
|
STATIC XTFASTCALL VOID AcquireSpinLock(IN OUT PKSPIN_LOCK SpinLock);
|
||||||
|
STATIC XTAPI VOID InitializeAllLocks();
|
||||||
|
STATIC XTAPI VOID InitializeLockQueues();
|
||||||
STATIC XTAPI VOID InitializeSpinLock(IN PKSPIN_LOCK SpinLock);
|
STATIC XTAPI VOID InitializeSpinLock(IN PKSPIN_LOCK SpinLock);
|
||||||
STATIC XTFASTCALL VOID ReleaseQueuedSpinLock(IN KSPIN_LOCK_QUEUE_LEVEL LockLevel);
|
STATIC XTFASTCALL VOID ReleaseQueuedSpinLock(IN KSPIN_LOCK_QUEUE_LEVEL LockLevel);
|
||||||
STATIC XTFASTCALL VOID ReleaseSpinLock(IN OUT PKSPIN_LOCK SpinLock);
|
STATIC XTFASTCALL VOID ReleaseSpinLock(IN OUT PKSPIN_LOCK SpinLock);
|
||||||
|
STATIC XTFASTCALL BOOLEAN TestSpinLock(IN PKSPIN_LOCK SpinLock);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,10 +12,17 @@
|
|||||||
#include <xtos.hh>
|
#include <xtos.hh>
|
||||||
|
|
||||||
#include XTOS_ARCH_HEADER(mm, pagemap.hh)
|
#include XTOS_ARCH_HEADER(mm, pagemap.hh)
|
||||||
|
#include XTOS_ARCH_HEADER(mm, paging.hh)
|
||||||
|
#include XTOS_ARCH_HEADER(mm, pte.hh)
|
||||||
|
|
||||||
|
#include <mm/alloc.hh>
|
||||||
|
#include <mm/colors.hh>
|
||||||
|
#include <mm/guard.hh>
|
||||||
#include <mm/hlpool.hh>
|
#include <mm/hlpool.hh>
|
||||||
#include <mm/init.hh>
|
|
||||||
#include <mm/kpool.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 */
|
#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
|
* PROJECT: ExectOS
|
||||||
* COPYRIGHT: See COPYING.md in the top level directory
|
* 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
|
* DESCRIPTION: Low-level support for page map manipulation
|
||||||
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
|
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __XTOSKRNL_MM_PAGEMAP_HH
|
#ifndef __XTOSKRNL_MM_AMD64_PAGEMAP_HH
|
||||||
#define __XTOSKRNL_MM_PAGEMAP_HH
|
#define __XTOSKRNL_MM_AMD64_PAGEMAP_HH
|
||||||
|
|
||||||
#include <xtos.hh>
|
#include <xtos.hh>
|
||||||
|
|
||||||
@@ -21,33 +21,77 @@ namespace MM
|
|||||||
MMPAGEMAP_INFO PageMapInfo;
|
MMPAGEMAP_INFO PageMapInfo;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
XTAPI VOID ClearPte(PHARDWARE_PTE PtePointer);
|
XTAPI PMMPTE AdvancePte(IN PMMPTE Pte,
|
||||||
XTAPI PMMP5E GetP5eAddress(PVOID Address);
|
IN LONG Count);
|
||||||
XTAPI PMMPDE GetPdeAddress(PVOID Address);
|
XTAPI BOOLEAN CanonicalAddress(IN PVOID VirtualAddress);
|
||||||
XTAPI PMMPPE GetPpeAddress(PVOID Address);
|
XTAPI VOID ClearPte(IN PMMPTE PtePointer);
|
||||||
XTAPI PMMPTE GetPteAddress(PVOID Address);
|
XTAPI ULONG_PTR GetNextEntry(IN PMMPTE Pte);
|
||||||
XTAPI PMMPXE GetPxeAddress(PVOID Address);
|
XTAPI PMMPTE GetNextPte(IN PMMPTE Pte);
|
||||||
virtual XTAPI VOID InitializePageMapInfo(VOID) = 0;
|
XTAPI BOOLEAN GetOneEntry(IN PMMPTE Pte);
|
||||||
XTAPI BOOLEAN PteValid(PHARDWARE_PTE PtePointer);
|
XTAPI PMMP5E GetP5eAddress(IN PVOID Address);
|
||||||
XTAPI VOID SetPte(PHARDWARE_PTE PtePointer,
|
XTAPI ULONG GetP5eOffset(IN PVOID Address);
|
||||||
PFN_NUMBER PageFrameNumber,
|
XTAPI PVOID GetP5eVirtualAddress(IN PMMP5E P5ePointer);
|
||||||
BOOLEAN Writable);
|
XTAPI USHORT GetPageMapLevel();
|
||||||
XTAPI VOID SetPteCaching(PHARDWARE_PTE PtePointer,
|
XTAPI PFN_NUMBER GetPageFrameNumber(IN PMMPTE Pte);
|
||||||
BOOLEAN CacheDisable,
|
XTAPI PMMPDE GetPdeAddress(IN PVOID Address);
|
||||||
BOOLEAN WriteThrough);
|
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;
|
} PAGEMAP, *PPAGEMAP;
|
||||||
|
|
||||||
class PageMapBasic final : public PageMap
|
class PageMapBasic final : public PageMap
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
XTAPI PVOID GetPdeVirtualAddress(IN PMMPDE PdePointer);
|
||||||
|
XTAPI PVOID GetPpeVirtualAddress(IN PMMPPE PpePointer);
|
||||||
|
XTAPI PVOID GetPteVirtualAddress(IN PMMPTE PtePointer);
|
||||||
|
XTAPI PVOID GetPxeVirtualAddress(IN PMMPXE PxePointer);
|
||||||
XTAPI VOID InitializePageMapInfo(VOID);
|
XTAPI VOID InitializePageMapInfo(VOID);
|
||||||
};
|
};
|
||||||
|
|
||||||
class PageMapXpa final : public PageMap
|
class PageMapXpa final : public PageMap
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
XTAPI PVOID GetPdeVirtualAddress(IN PMMPDE PdePointer);
|
||||||
|
XTAPI PVOID GetPpeVirtualAddress(IN PMMPPE PpePointer);
|
||||||
|
XTAPI PVOID GetPteVirtualAddress(IN PMMPTE PtePointer);
|
||||||
|
XTAPI PVOID GetPxeVirtualAddress(IN PMMPXE PxePointer);
|
||||||
XTAPI VOID InitializePageMapInfo(VOID);
|
XTAPI VOID InitializePageMapInfo(VOID);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* __XTOSKRNL_MM_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
|
* PROJECT: ExectOS
|
||||||
* COPYRIGHT: See COPYING.md in the top level directory
|
* 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
|
* DESCRIPTION: Low-level support for page map manipulation
|
||||||
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
|
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __XTOSKRNL_MM_PAGEMAP_HH
|
#ifndef __XTOSKRNL_MM_I686_PAGEMAP_HH
|
||||||
#define __XTOSKRNL_MM_PAGEMAP_HH
|
#define __XTOSKRNL_MM_I686_PAGEMAP_HH
|
||||||
|
|
||||||
#include <xtos.hh>
|
#include <xtos.hh>
|
||||||
|
|
||||||
@@ -21,45 +21,130 @@ namespace MM
|
|||||||
MMPAGEMAP_INFO PageMapInfo;
|
MMPAGEMAP_INFO PageMapInfo;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
XTAPI VOID ClearPte(PHARDWARE_PTE PtePointer);
|
VIRTUAL XTAPI PMMPTE AdvancePte(IN PMMPTE Pte,
|
||||||
XTAPI PMMPDE GetPdeAddress(PVOID Address);
|
IN ULONG Count) = 0;
|
||||||
XTAPI PMMPPE GetPpeAddress(PVOID Address);
|
XTAPI BOOLEAN CanonicalAddress(IN PVOID VirtualAddress);
|
||||||
XTAPI PMMPTE GetPteAddress(PVOID Address);
|
VIRTUAL XTAPI VOID ClearPte(IN PMMPTE PtePointer) = 0;
|
||||||
virtual XTAPI VOID InitializePageMapInfo(VOID) = 0;
|
VIRTUAL XTAPI ULONG_PTR GetNextEntry(IN PMMPTE Pte) = 0;
|
||||||
virtual XTAPI BOOLEAN PteValid(PHARDWARE_PTE PtePointer) = 0;
|
VIRTUAL XTAPI PMMPTE GetNextPte(IN PMMPTE Pte) = 0;
|
||||||
virtual XTAPI VOID SetPte(PHARDWARE_PTE PtePointer,
|
VIRTUAL XTAPI BOOLEAN GetOneEntry(IN PMMPTE Pte) = 0;
|
||||||
PFN_NUMBER PageFrameNumber,
|
VIRTUAL XTAPI PFN_NUMBER GetPageFrameNumber(IN PMMPTE Pte) = 0;
|
||||||
BOOLEAN Writable) = 0;
|
XTAPI USHORT GetPageMapLevel();
|
||||||
virtual XTAPI VOID SetPteCaching(PHARDWARE_PTE PtePointer,
|
XTAPI PMMPDE GetPdeAddress(IN PVOID Address);
|
||||||
BOOLEAN CacheDisable,
|
XTAPI ULONG GetPdeOffset(IN PVOID Address);
|
||||||
BOOLEAN WriteThrough) = 0;
|
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;
|
} PAGEMAP, *PPAGEMAP;
|
||||||
|
|
||||||
class PageMapBasic final : public PageMap
|
class PageMapBasic final : public PageMap
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
XTAPI PMMPTE AdvancePte(IN PMMPTE Pte,
|
||||||
|
IN ULONG Count);
|
||||||
|
XTAPI VOID ClearPte(IN PMMPTE PtePointer);
|
||||||
|
XTAPI ULONG_PTR GetNextEntry(IN PMMPTE Pte);
|
||||||
|
XTAPI PMMPTE GetNextPte(IN PMMPTE Pte);
|
||||||
|
XTAPI BOOLEAN GetOneEntry(IN PMMPTE Pte);
|
||||||
|
XTAPI PFN_NUMBER GetPageFrameNumber(IN PMMPTE Pte);
|
||||||
|
XTAPI PVOID GetPdeVirtualAddress(IN PMMPDE PdePointer);
|
||||||
|
XTAPI 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 VOID InitializePageMapInfo(VOID);
|
||||||
XTAPI BOOLEAN PteValid(PHARDWARE_PTE PtePointer);
|
XTAPI BOOLEAN PteValid(IN PMMPTE PtePointer);
|
||||||
XTAPI VOID SetPte(PHARDWARE_PTE PtePointer,
|
XTAPI VOID SetNextEntry(IN PMMPTE Pte,
|
||||||
PFN_NUMBER PageFrameNumber,
|
IN ULONG_PTR Value);
|
||||||
BOOLEAN Writable);
|
XTAPI VOID SetOneEntry(IN PMMPTE Pte,
|
||||||
XTAPI VOID SetPteCaching(PHARDWARE_PTE PtePointer,
|
IN BOOLEAN Value);
|
||||||
BOOLEAN CacheDisable,
|
XTAPI VOID SetPte(IN PMMPTE PtePointer,
|
||||||
BOOLEAN WriteThrough);
|
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
|
class PageMapXpa final : public PageMap
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
XTAPI PMMPTE AdvancePte(IN PMMPTE Pte,
|
||||||
|
IN ULONG Count);
|
||||||
|
XTAPI VOID ClearPte(IN PMMPTE PtePointer);
|
||||||
|
XTAPI ULONG_PTR GetNextEntry(IN PMMPTE Pte);
|
||||||
|
XTAPI PMMPTE GetNextPte(IN PMMPTE Pte);
|
||||||
|
XTAPI BOOLEAN GetOneEntry(IN PMMPTE Pte);
|
||||||
|
XTAPI PFN_NUMBER GetPageFrameNumber(IN PMMPTE Pte);
|
||||||
|
XTAPI PVOID GetPdeVirtualAddress(IN PMMPDE PdePointer);
|
||||||
|
XTAPI 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 VOID InitializePageMapInfo(VOID);
|
||||||
XTAPI BOOLEAN PteValid(PHARDWARE_PTE PtePointer);
|
XTAPI BOOLEAN PteValid(IN PMMPTE PtePointer);
|
||||||
XTAPI VOID SetPte(PHARDWARE_PTE PtePointer,
|
XTAPI VOID SetNextEntry(IN PMMPTE Pte,
|
||||||
PFN_NUMBER PageFrameNumber,
|
IN ULONG_PTR Value);
|
||||||
BOOLEAN Writable);
|
XTAPI VOID SetOneEntry(IN PMMPTE Pte,
|
||||||
XTAPI VOID SetPteCaching(PHARDWARE_PTE PtePointer,
|
IN BOOLEAN Value);
|
||||||
BOOLEAN CacheDisable,
|
XTAPI VOID SetPte(IN PMMPTE PtePointer,
|
||||||
BOOLEAN WriteThrough);
|
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
|
class KernelPool
|
||||||
{
|
{
|
||||||
private:
|
|
||||||
STATIC UCHAR ProcessorStructuresData[MAXIMUM_PROCESSORS][KPROCESSOR_STRUCTURES_SIZE];
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
STATIC XTAPI XTSTATUS AllocateKernelStack(IN PVOID *Stack,
|
STATIC XTAPI XTSTATUS AllocateKernelStack(OUT PVOID *Stack,
|
||||||
IN BOOLEAN LargeStack,
|
IN ULONG StackSize);
|
||||||
IN UCHAR SystemNode);
|
|
||||||
STATIC XTAPI XTSTATUS AllocateProcessorStructures(IN ULONG CpuNumber,
|
STATIC XTAPI XTSTATUS AllocateProcessorStructures(IN ULONG CpuNumber,
|
||||||
OUT PVOID *StructuresData);
|
OUT PVOID *StructuresData);
|
||||||
STATIC XTAPI VOID FreeKernelStack(IN PVOID Stack,
|
STATIC XTAPI VOID FreeKernelStack(IN PVOID Stack,
|
||||||
IN BOOLEAN LargeStack);
|
IN ULONG StackSize);
|
||||||
STATIC XTAPI VOID FreeProcessorStructures(IN PVOID StructuresData);
|
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/llist.hh>
|
||||||
#include <rtl/math.hh>
|
#include <rtl/math.hh>
|
||||||
#include <rtl/memory.hh>
|
#include <rtl/memory.hh>
|
||||||
|
#include <rtl/sha1.hh>
|
||||||
|
#include <rtl/slist.hh>
|
||||||
#include <rtl/string.hh>
|
#include <rtl/string.hh>
|
||||||
#include <rtl/widestr.hh>
|
#include <rtl/widestr.hh>
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
* FILE: xtoskrnl/includes/rtl/llist.hh
|
* FILE: xtoskrnl/includes/rtl/llist.hh
|
||||||
* DESCRIPTION: Linked list manipulation routines
|
* DESCRIPTION: Linked list manipulation routines
|
||||||
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
|
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
|
||||||
|
* Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __XTOSKRNL_RTL_LLIST_HH
|
#ifndef __XTOSKRNL_RTL_LLIST_HH
|
||||||
@@ -18,6 +19,7 @@ namespace RTL
|
|||||||
class LinkedList
|
class LinkedList
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
STATIC XTCDECL PLIST_ENTRY GetFirstEntry(IN PLIST_ENTRY ListHead);
|
||||||
STATIC XTCDECL VOID InitializeListHead(IN PLIST_ENTRY ListHead);
|
STATIC XTCDECL VOID InitializeListHead(IN PLIST_ENTRY ListHead);
|
||||||
STATIC XTCDECL VOID InitializeListHead32(IN PLIST_ENTRY32 ListHead);
|
STATIC XTCDECL VOID InitializeListHead32(IN PLIST_ENTRY32 ListHead);
|
||||||
STATIC XTCDECL VOID InsertHeadList(IN OUT PLIST_ENTRY ListHead,
|
STATIC XTCDECL VOID InsertHeadList(IN OUT PLIST_ENTRY ListHead,
|
||||||
@@ -27,6 +29,10 @@ namespace RTL
|
|||||||
STATIC XTCDECL BOOLEAN ListEmpty(IN PLIST_ENTRY ListHead);
|
STATIC XTCDECL BOOLEAN ListEmpty(IN PLIST_ENTRY ListHead);
|
||||||
STATIC XTCDECL BOOLEAN ListLoop(IN PLIST_ENTRY ListHead);
|
STATIC XTCDECL BOOLEAN ListLoop(IN PLIST_ENTRY ListHead);
|
||||||
STATIC XTCDECL VOID RemoveEntryList(IN PLIST_ENTRY Entry);
|
STATIC XTCDECL VOID RemoveEntryList(IN PLIST_ENTRY Entry);
|
||||||
|
STATIC XTCDECL VOID SpliceHeadList(IN OUT PLIST_ENTRY ListHead,
|
||||||
|
IN OUT PLIST_ENTRY SpliceList);
|
||||||
|
STATIC XTCDECL VOID SpliceTailList(IN OUT PLIST_ENTRY ListHead,
|
||||||
|
IN OUT PLIST_ENTRY SpliceList);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
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 */
|
||||||
@@ -86,6 +86,10 @@ KE::KernelInit::StartKernel(VOID)
|
|||||||
/* Save processor state */
|
/* Save processor state */
|
||||||
Processor::SaveProcessorState(&Prcb->ProcessorState);
|
Processor::SaveProcessorState(&Prcb->ProcessorState);
|
||||||
|
|
||||||
|
/* Initialize spin locks */
|
||||||
|
SpinLock::InitializeAllLocks();
|
||||||
|
SpinLock::InitializeLockQueues();
|
||||||
|
|
||||||
/* Lower to APC runlevel */
|
/* Lower to APC runlevel */
|
||||||
RunLevel::LowerRunLevel(APC_LEVEL);
|
RunLevel::LowerRunLevel(APC_LEVEL);
|
||||||
|
|
||||||
@@ -108,6 +112,9 @@ KE::KernelInit::StartKernel(VOID)
|
|||||||
CurrentThread->WaitRunLevel = DISPATCH_LEVEL;
|
CurrentThread->WaitRunLevel = DISPATCH_LEVEL;
|
||||||
CurrentProcess->ActiveProcessors |= (ULONG_PTR)1 << Prcb->CpuNumber;
|
CurrentProcess->ActiveProcessors |= (ULONG_PTR)1 << Prcb->CpuNumber;
|
||||||
|
|
||||||
|
/* Initialize Memory Manager */
|
||||||
|
MM::Manager::InitializeMemoryManager();
|
||||||
|
|
||||||
/* Enter infinite loop */
|
/* Enter infinite loop */
|
||||||
DebugPrint(L"KernelInit::StartKernel() finished. Entering infinite loop.\n");
|
DebugPrint(L"KernelInit::StartKernel() finished. Entering infinite loop.\n");
|
||||||
Crash::HaltSystem();
|
Crash::HaltSystem();
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ XTAPI
|
|||||||
VOID
|
VOID
|
||||||
KE::Crash::Panic(IN ULONG Code)
|
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
|
XTAPI
|
||||||
VOID
|
VOID
|
||||||
KE::Crash::PanicEx(IN ULONG Code,
|
KE::Crash::Panic(IN ULONG Code,
|
||||||
IN ULONG_PTR Parameter1,
|
IN ULONG_PTR Parameter1,
|
||||||
IN ULONG_PTR Parameter2,
|
IN ULONG_PTR Parameter2,
|
||||||
IN ULONG_PTR Parameter3,
|
IN ULONG_PTR Parameter3,
|
||||||
IN ULONG_PTR Parameter4)
|
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();
|
HaltSystem();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,12 +12,6 @@
|
|||||||
/* Kernel initialization block passed by boot loader */
|
/* Kernel initialization block passed by boot loader */
|
||||||
PKERNEL_INITIALIZATION_BLOCK KE::BootInformation::InitializationBlock = {};
|
PKERNEL_INITIALIZATION_BLOCK KE::BootInformation::InitializationBlock = {};
|
||||||
|
|
||||||
/* Kernel boot resources list */
|
|
||||||
LIST_ENTRY KE::SystemResources::ResourcesListHead;
|
|
||||||
|
|
||||||
/* Kernel boot resources lock */
|
|
||||||
KSPIN_LOCK KE::SystemResources::ResourcesLock;
|
|
||||||
|
|
||||||
/* Kernel initial process */
|
/* Kernel initial process */
|
||||||
EPROCESS KE::KProcess::InitialProcess;
|
EPROCESS KE::KProcess::InitialProcess;
|
||||||
|
|
||||||
@@ -26,3 +20,54 @@ ETHREAD KE::KThread::InitialThread = {};
|
|||||||
|
|
||||||
/* Kernel UBSAN active frame flag */
|
/* Kernel UBSAN active frame flag */
|
||||||
BOOLEAN KE::KUbsan::ActiveFrame = FALSE;
|
BOOLEAN KE::KUbsan::ActiveFrame = FALSE;
|
||||||
|
|
||||||
|
/* Kernel dispatcher lock queue */
|
||||||
|
KSPIN_LOCK KE::SpinLock::DispatcherLockQueue;
|
||||||
|
|
||||||
|
/* Kernel expansion lock queue */
|
||||||
|
KSPIN_LOCK KE::SpinLock::ExpansionLockQueue;
|
||||||
|
|
||||||
|
/* Kernel file system structures lock queue */
|
||||||
|
KSPIN_LOCK KE::SpinLock::FileSystemLockQueue;
|
||||||
|
|
||||||
|
/* Kernel IO cancel lock queue */
|
||||||
|
KSPIN_LOCK KE::SpinLock::IoCancelLockQueue;
|
||||||
|
|
||||||
|
/* Kernel IO completion lock queue */
|
||||||
|
KSPIN_LOCK KE::SpinLock::IoCompletionLockQueue;
|
||||||
|
|
||||||
|
/* Kernel IO database lock queue */
|
||||||
|
KSPIN_LOCK KE::SpinLock::IoDatabaseLockQueue;
|
||||||
|
|
||||||
|
/* Kernel IO VPB lock queue */
|
||||||
|
KSPIN_LOCK KE::SpinLock::IoVpbLockQueue;
|
||||||
|
|
||||||
|
/* Kernel cache master lock queue */
|
||||||
|
KSPIN_LOCK KE::SpinLock::MasterLockQueue;
|
||||||
|
|
||||||
|
/* Kernel non-paged allocator lock queue */
|
||||||
|
KSPIN_LOCK KE::SpinLock::NonPagedAllocLockQueue;
|
||||||
|
|
||||||
|
/* Kernel non-paged pool lock queue */
|
||||||
|
KSPIN_LOCK KE::SpinLock::NonPagedPoolLockQueue;
|
||||||
|
|
||||||
|
/* Kernel PFN lock queue */
|
||||||
|
KSPIN_LOCK KE::SpinLock::PfnLockQueue;
|
||||||
|
|
||||||
|
/* Kernel system space lock queue */
|
||||||
|
KSPIN_LOCK KE::SpinLock::SystemSpaceLockQueue;
|
||||||
|
|
||||||
|
/* Kernel Timer table lock queue */
|
||||||
|
KSPIN_LOCK KE::SpinLock::TimerTableLockQueue;
|
||||||
|
|
||||||
|
/* Kernel VACB lock queue */
|
||||||
|
KSPIN_LOCK KE::SpinLock::VacbLockQueue;
|
||||||
|
|
||||||
|
/* Kernel work queue lock queue */
|
||||||
|
KSPIN_LOCK KE::SpinLock::WorkLockQueue;
|
||||||
|
|
||||||
|
/* Kernel boot resources list */
|
||||||
|
LIST_ENTRY KE::SystemResources::ResourcesListHead;
|
||||||
|
|
||||||
|
/* Kernel boot resources lock */
|
||||||
|
KSPIN_LOCK KE::SystemResources::ResourcesLock;
|
||||||
|
|||||||
@@ -86,6 +86,10 @@ KE::KernelInit::StartKernel(VOID)
|
|||||||
/* Save processor state */
|
/* Save processor state */
|
||||||
Processor::SaveProcessorState(&Prcb->ProcessorState);
|
Processor::SaveProcessorState(&Prcb->ProcessorState);
|
||||||
|
|
||||||
|
/* Initialize spin locks */
|
||||||
|
SpinLock::InitializeAllLocks();
|
||||||
|
SpinLock::InitializeLockQueues();
|
||||||
|
|
||||||
/* Lower to APC runlevel */
|
/* Lower to APC runlevel */
|
||||||
RunLevel::LowerRunLevel(APC_LEVEL);
|
RunLevel::LowerRunLevel(APC_LEVEL);
|
||||||
|
|
||||||
@@ -108,6 +112,9 @@ KE::KernelInit::StartKernel(VOID)
|
|||||||
CurrentThread->WaitRunLevel = DISPATCH_LEVEL;
|
CurrentThread->WaitRunLevel = DISPATCH_LEVEL;
|
||||||
CurrentProcess->ActiveProcessors |= (ULONG_PTR)1 << Prcb->CpuNumber;
|
CurrentProcess->ActiveProcessors |= (ULONG_PTR)1 << Prcb->CpuNumber;
|
||||||
|
|
||||||
|
/* Initialize Memory Manager */
|
||||||
|
MM::Manager::InitializeMemoryManager();
|
||||||
|
|
||||||
/* Enter infinite loop */
|
/* Enter infinite loop */
|
||||||
DebugPrint(L"KernelInit::StartKernel() finished. Entering infinite loop.\n");
|
DebugPrint(L"KernelInit::StartKernel() finished. Entering infinite loop.\n");
|
||||||
Crash::HaltSystem();
|
Crash::HaltSystem();
|
||||||
|
|||||||
@@ -152,7 +152,7 @@ KE::KThread::InitializeThread(IN PKPROCESS Process,
|
|||||||
if(!Stack)
|
if(!Stack)
|
||||||
{
|
{
|
||||||
/* Allocate new stack */
|
/* Allocate new stack */
|
||||||
Status = MM::KernelPool::AllocateKernelStack(&Stack, FALSE, 0);
|
Status = MM::KernelPool::AllocateKernelStack(&Stack, KERNEL_STACK_SIZE);
|
||||||
if(Status != STATUS_SUCCESS || !Stack)
|
if(Status != STATUS_SUCCESS || !Stack)
|
||||||
{
|
{
|
||||||
/* Stack allocation failed */
|
/* Stack allocation failed */
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
* FILE: xtoskrnl/ke/spinlock.cc
|
* FILE: xtoskrnl/ke/spinlock.cc
|
||||||
* DESCRIPTION: Spinlocks support
|
* DESCRIPTION: Spinlocks support
|
||||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||||
|
* Aiken Harris <harraiken91@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <xtos.hh>
|
#include <xtos.hh>
|
||||||
@@ -56,6 +57,78 @@ KE::SpinLock::AcquireSpinLock(IN OUT PKSPIN_LOCK SpinLock)
|
|||||||
AR::CpuFunc::ReadWriteBarrier();
|
AR::CpuFunc::ReadWriteBarrier();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes all kernel spinlocks.
|
||||||
|
*
|
||||||
|
* @return This routine does not return any value.
|
||||||
|
*
|
||||||
|
* @since XT 1.0
|
||||||
|
*/
|
||||||
|
XTAPI
|
||||||
|
VOID
|
||||||
|
KE::SpinLock::InitializeAllLocks()
|
||||||
|
{
|
||||||
|
/* Initialize all spin locks */
|
||||||
|
InitializeSpinLock(&DispatcherLockQueue);
|
||||||
|
InitializeSpinLock(&PfnLockQueue);
|
||||||
|
InitializeSpinLock(&SystemSpaceLockQueue);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes spinlock queues for current processor.
|
||||||
|
*
|
||||||
|
* @return This routine does not return any value.
|
||||||
|
*
|
||||||
|
* @since XT 1.0
|
||||||
|
*/
|
||||||
|
XTAPI
|
||||||
|
VOID
|
||||||
|
KE::SpinLock::InitializeLockQueues()
|
||||||
|
{
|
||||||
|
PKPROCESSOR_CONTROL_BLOCK ControlBlock;
|
||||||
|
|
||||||
|
/* Get current processor control block */
|
||||||
|
ControlBlock = KE::Processor::GetCurrentProcessorControlBlock();
|
||||||
|
|
||||||
|
/* Initialize PCB lock queues */
|
||||||
|
ControlBlock->LockQueue[DispatcherLock].Lock = &DispatcherLockQueue;
|
||||||
|
ControlBlock->LockQueue[DispatcherLock].Next = NULLPTR;
|
||||||
|
ControlBlock->LockQueue[ExpansionLock].Lock = &ExpansionLockQueue;
|
||||||
|
ControlBlock->LockQueue[ExpansionLock].Next = NULLPTR;
|
||||||
|
ControlBlock->LockQueue[PfnLock].Lock = &PfnLockQueue;
|
||||||
|
ControlBlock->LockQueue[PfnLock].Next = NULLPTR;
|
||||||
|
ControlBlock->LockQueue[SystemSpaceLock].Lock = &SystemSpaceLockQueue;
|
||||||
|
ControlBlock->LockQueue[SystemSpaceLock].Next = NULLPTR;
|
||||||
|
ControlBlock->LockQueue[VacbLock].Lock = &VacbLockQueue;
|
||||||
|
ControlBlock->LockQueue[VacbLock].Next = NULLPTR;
|
||||||
|
ControlBlock->LockQueue[MasterLock].Lock = &MasterLockQueue;
|
||||||
|
ControlBlock->LockQueue[MasterLock].Next = NULLPTR;
|
||||||
|
ControlBlock->LockQueue[NonPagedAllocPoolLock].Lock = &NonPagedAllocLockQueue;
|
||||||
|
ControlBlock->LockQueue[NonPagedAllocPoolLock].Next = NULLPTR;
|
||||||
|
ControlBlock->LockQueue[IoCancelLock].Lock = &IoCancelLockQueue;
|
||||||
|
ControlBlock->LockQueue[IoCancelLock].Next = NULLPTR;
|
||||||
|
ControlBlock->LockQueue[WorkQueueLock].Lock = &WorkLockQueue;
|
||||||
|
ControlBlock->LockQueue[WorkQueueLock].Next = NULLPTR;
|
||||||
|
ControlBlock->LockQueue[IoVpbLock].Lock = &IoVpbLockQueue;
|
||||||
|
ControlBlock->LockQueue[IoVpbLock].Next = NULLPTR;
|
||||||
|
ControlBlock->LockQueue[IoDatabaseLock].Lock = &IoDatabaseLockQueue;
|
||||||
|
ControlBlock->LockQueue[IoDatabaseLock].Next = NULLPTR;
|
||||||
|
ControlBlock->LockQueue[IoCompletionLock].Lock = &IoCompletionLockQueue;
|
||||||
|
ControlBlock->LockQueue[IoCompletionLock].Next = NULLPTR;
|
||||||
|
ControlBlock->LockQueue[FileSystemLock].Lock = &FileSystemLockQueue;
|
||||||
|
ControlBlock->LockQueue[FileSystemLock].Next = NULLPTR;
|
||||||
|
ControlBlock->LockQueue[AfdWorkQueueLock].Lock = NULLPTR;
|
||||||
|
ControlBlock->LockQueue[AfdWorkQueueLock].Next = NULLPTR;
|
||||||
|
ControlBlock->LockQueue[BcbLock].Lock = NULLPTR;
|
||||||
|
ControlBlock->LockQueue[BcbLock].Next = NULLPTR;
|
||||||
|
ControlBlock->LockQueue[NonPagedPoolLock].Lock = &NonPagedPoolLockQueue;
|
||||||
|
ControlBlock->LockQueue[NonPagedPoolLock].Next = NULLPTR;
|
||||||
|
ControlBlock->LockQueue[ReservedSystemLock].Lock = NULLPTR;
|
||||||
|
ControlBlock->LockQueue[ReservedSystemLock].Next = NULLPTR;
|
||||||
|
ControlBlock->LockQueue[TimerTableLock].Lock = &TimerTableLockQueue;
|
||||||
|
ControlBlock->LockQueue[TimerTableLock].Next = NULLPTR;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes a kernel spinlock object.
|
* Initializes a kernel spinlock object.
|
||||||
*
|
*
|
||||||
@@ -112,3 +185,29 @@ KE::SpinLock::ReleaseSpinLock(IN OUT PKSPIN_LOCK SpinLock)
|
|||||||
/* Add an explicit memory barrier */
|
/* Add an explicit memory barrier */
|
||||||
AR::CpuFunc::ReadWriteBarrier();
|
AR::CpuFunc::ReadWriteBarrier();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests a kernel spin lock.
|
||||||
|
*
|
||||||
|
* @param SpinLock
|
||||||
|
* Supplies a pointer to the kernel spin lock.
|
||||||
|
*
|
||||||
|
* @return This routine returns TRUE if the lock is free, FALSE otherwise.
|
||||||
|
*
|
||||||
|
* @since XT 1.0
|
||||||
|
*/
|
||||||
|
XTFASTCALL
|
||||||
|
BOOLEAN
|
||||||
|
TestSpinLock(IN PKSPIN_LOCK SpinLock)
|
||||||
|
{
|
||||||
|
/* Check if the lock is free */
|
||||||
|
if(*SpinLock)
|
||||||
|
{
|
||||||
|
/* Spinlock is busy, yield processor and return FALSE */
|
||||||
|
AR::CpuFunc::YieldProcessor();
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Spinlock is free, return TRUE */
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|||||||
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>
|
#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).
|
* Clears the contents of a page table entry (PTE).
|
||||||
*
|
*
|
||||||
@@ -21,13 +66,64 @@
|
|||||||
*/
|
*/
|
||||||
XTAPI
|
XTAPI
|
||||||
VOID
|
VOID
|
||||||
MM::PageMap::ClearPte(PHARDWARE_PTE PtePointer)
|
MM::PageMap::ClearPte(IN PMMPTE PtePointer)
|
||||||
{
|
{
|
||||||
PtePointer->CacheDisable = 0;
|
/* Clear PTE */
|
||||||
PtePointer->PageFrameNumber = 0;
|
PtePointer->Long = 0;
|
||||||
PtePointer->Valid = 0;
|
}
|
||||||
PtePointer->Writable = 0;
|
|
||||||
PtePointer->WriteThrough = 0;
|
/**
|
||||||
|
* Gets the next entry in a PTE list.
|
||||||
|
*
|
||||||
|
* @param Pte
|
||||||
|
* The PTE pointer to get the next entry from.
|
||||||
|
*
|
||||||
|
* @return This routine returns the next entry in the PTE list.
|
||||||
|
*
|
||||||
|
* @since XT 1.0
|
||||||
|
*/
|
||||||
|
XTAPI
|
||||||
|
ULONG_PTR
|
||||||
|
MM::PageMap::GetNextEntry(IN PMMPTE Pte)
|
||||||
|
{
|
||||||
|
/* Return next entry in PTE list */
|
||||||
|
return Pte->List.NextEntry;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Advances a PTE pointer, considering the actual PTE size.
|
||||||
|
*
|
||||||
|
* @param Pte
|
||||||
|
* The PTE pointer to advance.
|
||||||
|
*
|
||||||
|
* @return The advanced PTE pointer.
|
||||||
|
*
|
||||||
|
* @since XT 1.0
|
||||||
|
*/
|
||||||
|
XTAPI
|
||||||
|
PMMPTE
|
||||||
|
MM::PageMap::GetNextPte(IN PMMPTE Pte)
|
||||||
|
{
|
||||||
|
/* Return advanced PTE pointer */
|
||||||
|
return AdvancePte(Pte, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if a PTE list contains only one entry.
|
||||||
|
*
|
||||||
|
* @param Pte
|
||||||
|
* The PTE pointer to check.
|
||||||
|
*
|
||||||
|
* @return This routine returns TRUE if the PTE list has only one entry, FALSE otherwise.
|
||||||
|
*
|
||||||
|
* @since XT 1.0
|
||||||
|
*/
|
||||||
|
XTAPI
|
||||||
|
BOOLEAN
|
||||||
|
MM::PageMap::GetOneEntry(IN PMMPTE Pte)
|
||||||
|
{
|
||||||
|
/* Return one entry status */
|
||||||
|
return Pte->List.OneEntry;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -42,7 +138,7 @@ MM::PageMap::ClearPte(PHARDWARE_PTE PtePointer)
|
|||||||
*/
|
*/
|
||||||
XTAPI
|
XTAPI
|
||||||
PMMP5E
|
PMMP5E
|
||||||
MM::PageMap::GetP5eAddress(PVOID Address)
|
MM::PageMap::GetP5eAddress(IN PVOID Address)
|
||||||
{
|
{
|
||||||
ULONGLONG Offset;
|
ULONGLONG Offset;
|
||||||
|
|
||||||
@@ -51,6 +147,72 @@ MM::PageMap::GetP5eAddress(PVOID Address)
|
|||||||
return (PMMP5E)((PageMapInfo.P5eBase + Offset) * PageMapInfo.Xpa);
|
return (PMMP5E)((PageMapInfo.P5eBase + Offset) * PageMapInfo.Xpa);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the Offset of the P5E (Page Map Level 5 Entry), that maps given address.
|
||||||
|
*
|
||||||
|
* @param Address
|
||||||
|
* Specifies the virtual address for which to retrieve the corresponding P5E.
|
||||||
|
*
|
||||||
|
* @return This routine returns the Offset of the P5E, or NULLPTR if LA57 is not enabled.
|
||||||
|
*
|
||||||
|
* @since XT 1.0
|
||||||
|
*/
|
||||||
|
XTAPI
|
||||||
|
ULONG
|
||||||
|
MM::PageMap::GetP5eOffset(IN PVOID Address)
|
||||||
|
{
|
||||||
|
/* Return P5E Offset */
|
||||||
|
return (((((ULONGLONG)Address) >> MM_P5I_SHIFT) & 0x1FF) * PageMapInfo.Xpa);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the virtual address that is mapped by a given Page Map Level 5 Entry.
|
||||||
|
*
|
||||||
|
* @param P5ePointer
|
||||||
|
* Specifies the address of the P5E.
|
||||||
|
*
|
||||||
|
* @return This routine returns the virtual address mapped by the P5E, or NULLPTR if LA57 is not enabled.
|
||||||
|
*
|
||||||
|
* @since XT 1.0
|
||||||
|
*/
|
||||||
|
XTAPI
|
||||||
|
PVOID
|
||||||
|
MM::PageMap::GetP5eVirtualAddress(IN PMMP5E P5ePointer)
|
||||||
|
{
|
||||||
|
return (PVOID)((((LONGLONG)P5ePointer << 52) >> 7) * PageMapInfo.Xpa);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the page frame number from a corresponding PTE.
|
||||||
|
*
|
||||||
|
* @param Pte
|
||||||
|
* The PTE pointer to get the page frame number from.
|
||||||
|
*
|
||||||
|
* @return This routine returns the page frame number.
|
||||||
|
*
|
||||||
|
* @since XT 1.0
|
||||||
|
*/
|
||||||
|
XTAPI
|
||||||
|
PFN_NUMBER
|
||||||
|
MM::PageMap::GetPageFrameNumber(IN PMMPTE Pte)
|
||||||
|
{
|
||||||
|
return Pte->Hardware.PageFrameNumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets Page Map Level (PML) for current paging mode.
|
||||||
|
*
|
||||||
|
* @return This routine returns the page map level.
|
||||||
|
*
|
||||||
|
* @since XT 1.0
|
||||||
|
*/
|
||||||
|
XTAPI
|
||||||
|
USHORT
|
||||||
|
MM::PageMap::GetPageMapLevel()
|
||||||
|
{
|
||||||
|
return PageMapInfo.Xpa ? 5 : 4;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the address of the PDE (Page Directory Entry), that maps given address.
|
* Gets the address of the PDE (Page Directory Entry), that maps given address.
|
||||||
*
|
*
|
||||||
@@ -63,7 +225,7 @@ MM::PageMap::GetP5eAddress(PVOID Address)
|
|||||||
*/
|
*/
|
||||||
XTAPI
|
XTAPI
|
||||||
PMMPDE
|
PMMPDE
|
||||||
MM::PageMap::GetPdeAddress(PVOID Address)
|
MM::PageMap::GetPdeAddress(IN PVOID Address)
|
||||||
{
|
{
|
||||||
ULONGLONG Offset;
|
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
|
* @param Address
|
||||||
* Specifies the virtual address for which to retrieve the corresponding PDE.
|
* 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.
|
* @return This routine returns the address of the PPE.
|
||||||
*
|
*
|
||||||
* @since XT 1.0
|
* @since XT 1.0
|
||||||
*/
|
*/
|
||||||
XTAPI
|
XTAPI
|
||||||
PMMPPE
|
PMMPPE
|
||||||
MM::PageMap::GetPpeAddress(PVOID Address)
|
MM::PageMap::GetPpeAddress(IN PVOID Address)
|
||||||
{
|
{
|
||||||
ULONGLONG Offset;
|
ULONGLONG Offset;
|
||||||
|
|
||||||
@@ -93,6 +273,42 @@ MM::PageMap::GetPpeAddress(PVOID Address)
|
|||||||
return (PMMPPE)(PageMapInfo.PpeBase + Offset);
|
return (PMMPPE)(PageMapInfo.PpeBase + Offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the Offset of the PPE (Page Directory Pointer Table Entry), that maps given address.
|
||||||
|
*
|
||||||
|
* @param Address
|
||||||
|
* Specifies the virtual address for which to retrieve the corresponding PPE.
|
||||||
|
*
|
||||||
|
* @return This routine returns the Offset of the PPE.
|
||||||
|
*
|
||||||
|
* @since XT 1.0
|
||||||
|
*/
|
||||||
|
XTAPI
|
||||||
|
ULONG
|
||||||
|
MM::PageMap::GetPpeOffset(IN PVOID Address)
|
||||||
|
{
|
||||||
|
/* Return PPE Offset */
|
||||||
|
return ((((ULONGLONG)Address) >> MM_PPI_SHIFT) & 0x1FF);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the entire contents of a Page Table Entry (PTE) as a single value.
|
||||||
|
*
|
||||||
|
* @param PtePointer
|
||||||
|
* Pointer to the Page Table Entry (PTE) to read.
|
||||||
|
*
|
||||||
|
* @return This routine returns the contents of the PTE as a single value.
|
||||||
|
*
|
||||||
|
* @since XT 1.0
|
||||||
|
*/
|
||||||
|
XTAPI
|
||||||
|
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.
|
* Gets the address of the PTE (Page Table Entry), that maps given address.
|
||||||
*
|
*
|
||||||
@@ -105,7 +321,7 @@ MM::PageMap::GetPpeAddress(PVOID Address)
|
|||||||
*/
|
*/
|
||||||
XTAPI
|
XTAPI
|
||||||
PMMPTE
|
PMMPTE
|
||||||
MM::PageMap::GetPteAddress(PVOID Address)
|
MM::PageMap::GetPteAddress(IN PVOID Address)
|
||||||
{
|
{
|
||||||
ULONGLONG Offset;
|
ULONGLONG Offset;
|
||||||
|
|
||||||
@@ -114,6 +330,115 @@ MM::PageMap::GetPteAddress(PVOID Address)
|
|||||||
return (PMMPTE)(PageMapInfo.PteBase + Offset);
|
return (PMMPTE)(PageMapInfo.PteBase + Offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculates the distance between two PTE pointers.
|
||||||
|
*
|
||||||
|
* @param EndPte
|
||||||
|
* Pointer to the ending Page Table Entry.
|
||||||
|
*
|
||||||
|
* @param StartPte
|
||||||
|
* Pointer to the starting Page Table Entry.
|
||||||
|
*
|
||||||
|
* @return This routine returns a signed value representing the number of PTEs between EndPte and StartPte.
|
||||||
|
*
|
||||||
|
* @since XT 1.0
|
||||||
|
*/
|
||||||
|
XTAPI
|
||||||
|
LONG
|
||||||
|
MM::PageMap::GetPteDistance(PMMPTE EndPte,
|
||||||
|
PMMPTE StartPte)
|
||||||
|
{
|
||||||
|
/* Return distance between PTE pointers */
|
||||||
|
return ((ULONG_PTR)EndPte - (ULONG_PTR)StartPte) / sizeof(MMPTE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the Offset of the PTE (Page Table Entry), that maps given address.
|
||||||
|
*
|
||||||
|
* @param Address
|
||||||
|
* Specifies the virtual address for which to retrieve the corresponding PTE.
|
||||||
|
*
|
||||||
|
* @return This routine returns the Offset of the PTE.
|
||||||
|
*
|
||||||
|
* @since XT 1.0
|
||||||
|
*/
|
||||||
|
XTAPI
|
||||||
|
ULONG
|
||||||
|
MM::PageMap::GetPteOffset(IN PVOID Address)
|
||||||
|
{
|
||||||
|
/* Return PTE Offset */
|
||||||
|
return ((((ULONGLONG)Address) >> MM_PTI_SHIFT) & 0x1FF);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the size of a PTE.
|
||||||
|
*
|
||||||
|
* @return This routine returns the size of a PTE.
|
||||||
|
*
|
||||||
|
* @since XT 1.0
|
||||||
|
*/
|
||||||
|
XTAPI
|
||||||
|
ULONG
|
||||||
|
MM::PageMap::GetPteSize(VOID)
|
||||||
|
{
|
||||||
|
/* Return the size of MMPTE */
|
||||||
|
return sizeof(MMPTE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the software protection value of the corresponding Page Table Entry.
|
||||||
|
*
|
||||||
|
* @param PtePointer
|
||||||
|
* Specifies the address of the PTE.
|
||||||
|
*
|
||||||
|
* @return This routine returns the PTE software protection value.
|
||||||
|
*
|
||||||
|
* @since XT 1.0
|
||||||
|
*/
|
||||||
|
XTAPI
|
||||||
|
ULONG
|
||||||
|
MM::PageMap::GetPteSoftwareProtection(IN PMMPTE PtePointer)
|
||||||
|
{
|
||||||
|
/* Return PTE software protection value */
|
||||||
|
return (ULONG)PtePointer->Software.Protection;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the software prototype value of the corresponding Page Table Entry.
|
||||||
|
*
|
||||||
|
* @param PtePointer
|
||||||
|
* Specifies the address of the PTE.
|
||||||
|
*
|
||||||
|
* @return This routine returns the PTE software prototype value.
|
||||||
|
*
|
||||||
|
* @since XT 1.0
|
||||||
|
*/
|
||||||
|
XTAPI
|
||||||
|
ULONG
|
||||||
|
MM::PageMap::GetPteSoftwarePrototype(IN PMMPTE PtePointer)
|
||||||
|
{
|
||||||
|
/* Return PTE software prototype value */
|
||||||
|
return (ULONG)PtePointer->Software.Prototype;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the software transition value of the corresponding Page Table Entry.
|
||||||
|
*
|
||||||
|
* @param PtePointer
|
||||||
|
* Specifies the address of the PTE.
|
||||||
|
*
|
||||||
|
* @return This routine returns the PTE software transition value.
|
||||||
|
*
|
||||||
|
* @since XT 1.0
|
||||||
|
*/
|
||||||
|
XTAPI
|
||||||
|
ULONG
|
||||||
|
MM::PageMap::GetPteSoftwareTransition(IN PMMPTE PtePointer)
|
||||||
|
{
|
||||||
|
/* Return PTE software transition value */
|
||||||
|
return (ULONG)PtePointer->Software.Transition;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the address of the PXE (Extended Page Entry), that maps given address.
|
* Gets the address of the PXE (Extended Page Entry), that maps given address.
|
||||||
*
|
*
|
||||||
@@ -126,14 +451,47 @@ MM::PageMap::GetPteAddress(PVOID Address)
|
|||||||
*/
|
*/
|
||||||
XTAPI
|
XTAPI
|
||||||
PMMPXE
|
PMMPXE
|
||||||
MM::PageMap::GetPxeAddress(PVOID Address)
|
MM::PageMap::GetPxeAddress(IN PVOID Address)
|
||||||
{
|
{
|
||||||
ULONGLONG Offset;
|
ULONGLONG Offset;
|
||||||
|
|
||||||
|
/* Calculate offset and return PXE address */
|
||||||
Offset = ((((ULONGLONG)Address & (((ULONGLONG)1 << PageMapInfo.VaBits) - 1)) >> MM_PXI_SHIFT) << MM_PTE_SHIFT);
|
Offset = ((((ULONGLONG)Address & (((ULONGLONG)1 << PageMapInfo.VaBits) - 1)) >> MM_PXI_SHIFT) << MM_PTE_SHIFT);
|
||||||
return (PMMPXE)(PageMapInfo.PxeBase + Offset);
|
return (PMMPXE)(PageMapInfo.PxeBase + Offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the Offset of the PXE (Extended Page Entry), that maps given address.
|
||||||
|
*
|
||||||
|
* @param Address
|
||||||
|
* Specifies the virtual address for which to retrieve the corresponding PXE.
|
||||||
|
*
|
||||||
|
* @return This routine returns the Offset of the PXE.
|
||||||
|
*
|
||||||
|
* @since XT 1.0
|
||||||
|
*/
|
||||||
|
XTAPI
|
||||||
|
ULONG
|
||||||
|
MM::PageMap::GetPxeOffset(IN PVOID Address)
|
||||||
|
{
|
||||||
|
/* Return PXE Offset */
|
||||||
|
return ((((ULONGLONG)Address) >> MM_PXI_SHIFT) & 0x1FF);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the status of Extended Paging Address (XPA) mode.
|
||||||
|
*
|
||||||
|
* @return This routine returns TRUE if XPA is enabled, FALSE otherwise.
|
||||||
|
*
|
||||||
|
* @since XT 1.0
|
||||||
|
*/
|
||||||
|
XTAPI
|
||||||
|
BOOLEAN
|
||||||
|
MM::PageMap::GetXpaStatus()
|
||||||
|
{
|
||||||
|
return PageMapInfo.Xpa;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks whether the given PML2 page table entry (PTE) is valid.
|
* Checks whether the given PML2 page table entry (PTE) is valid.
|
||||||
*
|
*
|
||||||
@@ -146,22 +504,20 @@ MM::PageMap::GetPxeAddress(PVOID Address)
|
|||||||
*/
|
*/
|
||||||
XTAPI
|
XTAPI
|
||||||
BOOLEAN
|
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
|
* @param Pte
|
||||||
* Pointer to the page table entry (PTE) to set.
|
* The PTE pointer to modify.
|
||||||
*
|
*
|
||||||
* @param PageFrameNumber
|
* @param Value
|
||||||
* Physical frame number to map.
|
* The value to set as the next entry.
|
||||||
*
|
|
||||||
* @param Writable
|
|
||||||
* Indicates whether the page should be writable.
|
|
||||||
*
|
*
|
||||||
* @return This routine does not return any value.
|
* @return This routine does not return any value.
|
||||||
*
|
*
|
||||||
@@ -169,13 +525,82 @@ MM::PageMap::PteValid(PHARDWARE_PTE PtePointer)
|
|||||||
*/
|
*/
|
||||||
XTAPI
|
XTAPI
|
||||||
VOID
|
VOID
|
||||||
MM::PageMap::SetPte(PHARDWARE_PTE PtePointer,
|
MM::PageMap::SetNextEntry(IN PMMPTE Pte,
|
||||||
PFN_NUMBER PageFrameNumber,
|
IN ULONG_PTR Value)
|
||||||
BOOLEAN Writable)
|
|
||||||
{
|
{
|
||||||
PtePointer->PageFrameNumber = PageFrameNumber;
|
/* Set next entry in PTE list */
|
||||||
PtePointer->Valid = 1;
|
Pte->List.NextEntry = Value;
|
||||||
PtePointer->Writable = Writable;
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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
|
XTAPI
|
||||||
VOID
|
VOID
|
||||||
MM::PageMap::SetPteCaching(PHARDWARE_PTE PtePointer,
|
MM::PageMap::SetPteCaching(IN PMMPTE PtePointer,
|
||||||
BOOLEAN CacheDisable,
|
IN BOOLEAN CacheDisable,
|
||||||
BOOLEAN WriteThrough)
|
IN BOOLEAN WriteThrough)
|
||||||
{
|
{
|
||||||
PtePointer->CacheDisable = CacheDisable;
|
/* Set caching attributes */
|
||||||
PtePointer->WriteThrough = WriteThrough;
|
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;
|
PageMapInfo.VaBits = 48;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the virtual address that is mapped by a given Page Directory Entry (PML5).
|
||||||
|
*
|
||||||
|
* @param PdePointer
|
||||||
|
* Specifies the address of the PDE.
|
||||||
|
*
|
||||||
|
* @return This routine returns the virtual address mapped by the PDE.
|
||||||
|
*
|
||||||
|
* @since XT 1.0
|
||||||
|
*/
|
||||||
|
XTAPI
|
||||||
|
PVOID
|
||||||
|
MM::PageMapXpa::GetPdeVirtualAddress(IN PMMPDE PdePointer)
|
||||||
|
{
|
||||||
|
/* Return PDE virtual address */
|
||||||
|
return (PVOID)(((LONGLONG)PdePointer << 25) >> 7);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the virtual address that is mapped by a given Page Directory Pointer Table Entry (PML5).
|
||||||
|
*
|
||||||
|
* @param PpePointer
|
||||||
|
* Specifies the address of the PPE.
|
||||||
|
*
|
||||||
|
* @return This routine returns the virtual address mapped by the PPE.
|
||||||
|
*
|
||||||
|
* @since XT 1.0
|
||||||
|
*/
|
||||||
|
XTAPI
|
||||||
|
PVOID
|
||||||
|
MM::PageMapXpa::GetPpeVirtualAddress(IN PMMPPE PpePointer)
|
||||||
|
{
|
||||||
|
/* Return PPE virtual address */
|
||||||
|
return (PVOID)(((LONGLONG)PpePointer << 34) >> 7);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the virtual address that is mapped by a given Page Table Entry (PML5).
|
||||||
|
*
|
||||||
|
* @param PtePointer
|
||||||
|
* Specifies the address of the PTE.
|
||||||
|
*
|
||||||
|
* @return This routine returns the virtual address mapped by the PTE.
|
||||||
|
*
|
||||||
|
* @since XT 1.0
|
||||||
|
*/
|
||||||
|
XTAPI
|
||||||
|
PVOID
|
||||||
|
MM::PageMapXpa::GetPteVirtualAddress(IN PMMPTE PtePointer)
|
||||||
|
{
|
||||||
|
/* Return PTE virtual address */
|
||||||
|
return (PVOID)(((LONGLONG)PtePointer << 16) >> 7);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the virtual address that is mapped by a given Extended Page Entry (PML5).
|
||||||
|
*
|
||||||
|
* @param PxePointer
|
||||||
|
* Specifies the address of the PXE.
|
||||||
|
*
|
||||||
|
* @return This routine returns the virtual address mapped by the PXE.
|
||||||
|
*
|
||||||
|
* @since XT 1.0
|
||||||
|
*/
|
||||||
|
XTAPI
|
||||||
|
PVOID
|
||||||
|
MM::PageMapXpa::GetPxeVirtualAddress(IN PMMPXE PxePointer)
|
||||||
|
{
|
||||||
|
/* Return PXE virtual address */
|
||||||
|
return (PVOID)(((LONGLONG)PxePointer << 43) >> 7);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes page map information for XPA paging (PML5).
|
* Initializes page map information for XPA paging (PML5).
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -25,6 +25,78 @@ MM::Paging::GetExtendedPhysicalAddressingStatus(VOID)
|
|||||||
return ((AR::CpuFunc::ReadControlRegister(4) & CR4_LA57) != 0) ? TRUE : FALSE;
|
return ((AR::CpuFunc::ReadControlRegister(4) & CR4_LA57) != 0) ? TRUE : FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the address of the P5E (Page Map Level 5 Entry), that maps given address.
|
||||||
|
*
|
||||||
|
* @param Address
|
||||||
|
* Specifies the virtual address for which to retrieve the corresponding P5E.
|
||||||
|
*
|
||||||
|
* @return This routine returns the address of the P5E, or NULLPTR if LA57 is not enabled.
|
||||||
|
*
|
||||||
|
* @since XT 1.0
|
||||||
|
*/
|
||||||
|
XTAPI
|
||||||
|
PMMP5E
|
||||||
|
MM::Paging::GetP5eAddress(IN PVOID Address)
|
||||||
|
{
|
||||||
|
/* Return PDE address */
|
||||||
|
return PmlRoutines->GetP5eAddress(Address);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the virtual address that is mapped by a given Page Map Level 5 Entry.
|
||||||
|
*
|
||||||
|
* @param P5ePointer
|
||||||
|
* Specifies the address of the P5E.
|
||||||
|
*
|
||||||
|
* @return This routine returns the virtual address mapped by the P5E, or NULLPTR if LA57 is not enabled.
|
||||||
|
*
|
||||||
|
* @since XT 1.0
|
||||||
|
*/
|
||||||
|
XTAPI
|
||||||
|
PVOID
|
||||||
|
MM::Paging::GetP5eVirtualAddress(IN PMMP5E P5ePointer)
|
||||||
|
{
|
||||||
|
/* Return PTE virtual address */
|
||||||
|
return PmlRoutines->GetP5eVirtualAddress(P5ePointer);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the address of the PXE (Extended Page Entry), that maps given address.
|
||||||
|
*
|
||||||
|
* @param Address
|
||||||
|
* Specifies the virtual address for which to retrieve the corresponding PXE.
|
||||||
|
*
|
||||||
|
* @return This routine returns the address of the PXE.
|
||||||
|
*
|
||||||
|
* @since XT 1.0
|
||||||
|
*/
|
||||||
|
XTAPI
|
||||||
|
PMMPXE
|
||||||
|
MM::Paging::GetPxeAddress(IN PVOID Address)
|
||||||
|
{
|
||||||
|
/* Return PXE address */
|
||||||
|
return PmlRoutines->GetPxeAddress(Address);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the virtual address that is mapped by a given Extended Page Entry.
|
||||||
|
*
|
||||||
|
* @param PxePointer
|
||||||
|
* Specifies the address of the PXE.
|
||||||
|
*
|
||||||
|
* @return This routine returns the virtual address mapped by the PXE.
|
||||||
|
*
|
||||||
|
* @since XT 1.0
|
||||||
|
*/
|
||||||
|
XTAPI
|
||||||
|
PVOID
|
||||||
|
MM::Paging::GetPxeVirtualAddress(IN PMMPXE PxePointer)
|
||||||
|
{
|
||||||
|
/* Return PXE virtual address */
|
||||||
|
return PmlRoutines->GetPxeVirtualAddress(PxePointer);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fills a section of memory with zeroes like RtlZeroMemory(), but in more efficient way.
|
* Fills a section of memory with zeroes like RtlZeroMemory(), but in more efficient way.
|
||||||
*
|
*
|
||||||
|
|||||||
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());
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user