ответвлено от xt-sys/exectos
Сравнить коммиты
1049
Коммитов
| Автор | SHA1 | Дата | |
|---|---|---|---|
|
|
03f6ecea50
|
||
|
|
b33b6b2131
|
||
|
|
61218ad742
|
||
|
|
f9008510f5
|
||
|
|
6448335db1
|
||
|
|
ca76ed314b
|
||
|
|
b6ab1b959b
|
||
|
|
ea967b8084
|
||
|
|
392bc007a3
|
||
|
|
6c2f50d538
|
||
|
|
317cf5ef24
|
||
|
|
ba6b22f160
|
||
|
|
d05990a812
|
||
|
|
1a28106bb8
|
||
|
|
537e7e37e2
|
||
|
|
577621e082
|
||
|
|
7e66630c1b
|
||
|
|
0a66c8a3a3
|
||
|
|
d9a556e077
|
||
|
|
3a05d2f2f6
|
||
|
|
8d639f7c97
|
||
|
|
a84b9b641d
|
||
|
|
a2b23b2ef4
|
||
|
|
c6020578ce
|
||
|
|
1ecc9bd298
|
||
|
|
9b701c89f4
|
||
|
|
328b785b18
|
||
|
|
e0c8b313ff
|
||
|
|
b510e88745
|
||
|
|
f456cfd21e
|
||
|
|
a066a835c6
|
||
|
|
4f79c12e53
|
||
|
|
06ec2bc189
|
||
|
|
0439d9526b
|
||
|
|
bbad4bf8f4
|
||
|
|
bc99258d52
|
||
|
|
5349bd115e
|
||
|
|
f99e919cb7
|
||
|
|
68e08d3065
|
||
|
|
e4ae43f676
|
||
|
|
f436efbd11
|
||
|
|
168a8655ac
|
||
|
|
6b840939d5
|
||
|
|
b256c260b9
|
||
|
|
06291d2525
|
||
|
|
2a140661fd
|
||
|
|
34620b182a
|
||
|
|
e1c422c992
|
||
|
|
5e91e362ae
|
||
|
|
f276489e92
|
||
|
|
8ad412ecb5
|
||
|
|
b77a57a0e3
|
||
|
|
c48cefd463
|
||
|
|
130e797dd9
|
||
|
|
30abb5be98
|
||
|
|
f51c7a5ce5
|
||
|
|
c7b257dfc4
|
||
|
|
e8fa736c7a
|
||
|
|
a12e21f15c
|
||
|
|
b83aaf7cd0
|
||
|
|
849d68b939
|
||
|
|
e8c4b5cbda
|
||
|
|
b98d94b4f3
|
||
|
|
17f23fff41
|
||
|
|
e164370cff
|
||
|
|
2b1ff4aa9f
|
||
|
|
4ddc0c91c0
|
||
|
|
d8eeff620e
|
||
|
|
7a6982d44a
|
||
|
|
9f618eeb14
|
||
|
|
3ba50e7d59
|
||
|
|
f9a471633f
|
||
|
|
5982403a79
|
||
|
|
55e1373fc5
|
||
|
|
a00f7219fc
|
||
|
|
7db52a816f
|
||
|
|
34acfe2b8b
|
||
|
|
ec356b8a6e
|
||
|
|
aae31c2b1d
|
||
|
|
7336710c23
|
||
|
|
195c749396
|
||
|
|
96502d5db6
|
||
|
|
279aba9742
|
||
|
|
9012f82681
|
||
|
|
f2922349de
|
||
|
|
e5cf62cbfb
|
||
|
|
10aaac59e4
|
||
|
|
e3081c0cf5
|
||
|
|
a0e707d35f
|
||
|
|
042bf8520c
|
||
|
|
30a6517109
|
||
|
|
cba4c6fffb
|
||
|
|
66f74be947
|
||
|
|
0ccf20f0c9
|
||
|
|
a2801bab2a
|
||
|
|
9fcd81a507
|
||
|
|
46fb492032
|
||
|
|
b2e3a6afe0
|
||
|
|
2389bcbed1
|
||
|
|
213713b6d2
|
||
|
|
c1bc4e4940
|
||
|
|
b76a240fd8
|
||
|
|
d164495d48
|
||
|
|
2b7fc5b41d
|
||
|
|
5cd52a4a12
|
||
|
|
c58305022f
|
||
|
|
d8f4f6bfd0
|
||
|
|
ef4f9ba74d
|
||
|
|
f9cbe78f84
|
||
|
|
91946ae88f
|
||
|
|
84d35e3c97
|
||
|
|
9ef8c569d5
|
||
|
|
7d9c338e2a
|
||
|
|
2868db63ca
|
||
|
|
9d5466594a
|
||
|
|
119480382b
|
||
|
|
3011df6f3c
|
||
|
|
6e4f9dd5b1
|
||
|
|
42d6426318
|
||
|
|
757acb732e
|
||
|
|
a54c4b48fb
|
||
|
|
314012cad9
|
||
|
|
b3ce1a8be8
|
||
|
|
d6f925ebfd
|
||
|
|
53a8b57a96
|
||
|
|
77c1138f7d
|
||
|
|
03f97d94ae
|
||
|
|
8c6e06c973
|
||
|
|
f2168e8c55
|
||
|
|
6184e9e73d
|
||
|
|
3d42ecf3d3
|
||
|
|
c309bd769d
|
||
|
|
79c9b2abef
|
||
|
|
d9a4217f8b
|
||
|
|
7b27b09748
|
||
|
|
195c4a34ad
|
||
|
|
e266b30e24
|
||
|
|
28daa1718c
|
||
|
|
b016ffd0d7
|
||
|
|
8479c95e82
|
||
|
|
f66e27cf83
|
||
|
|
cf846d5abe
|
||
|
|
08f26c6762
|
||
|
|
19a1b11236
|
||
|
|
d10b2cc2a1
|
||
|
|
5475d970c4
|
||
|
|
18d36b9f23
|
||
|
|
fe02bb9214
|
||
|
|
76b1807eee
|
||
|
|
e431bccd44
|
||
|
|
7526f90759
|
||
|
|
c45b81d345
|
||
|
|
95ec18a1de
|
||
|
|
9faf19b57e
|
||
|
|
bae43034a6
|
||
|
|
156ae3efab
|
||
|
|
854a8c8eef
|
||
|
|
1fca2400a4
|
||
|
|
ea1ad3c6b1
|
||
|
|
cea860b008
|
||
|
|
6560ca9b96
|
||
|
|
ffcb2dbeda
|
||
|
|
780bf92b40
|
||
|
|
cc288f5417
|
||
|
|
55eb3047e3
|
||
|
|
8597e37650
|
||
|
|
1c90218042
|
||
|
|
f6f37494cd
|
||
|
|
d1aa3cf481
|
||
|
|
208684c3b4
|
||
|
|
89681897d7
|
||
|
|
e035666f7a
|
||
|
|
df35bf8601
|
||
|
|
15523e7d71
|
||
|
|
f79c9023d8
|
||
|
|
97703c7932
|
||
|
|
2f5902119d
|
||
|
|
7a10135731
|
||
|
|
b0074637f8
|
||
|
|
1a062ca05f
|
||
|
|
c702152cca
|
||
|
|
81c799e590
|
||
|
|
cf0d7f0a40
|
||
|
|
b0d2868f82
|
||
|
|
32f0b747a1
|
||
|
|
c57aa98923
|
||
|
|
429e4ef6f1
|
||
|
|
39928f2ef4
|
||
|
|
51ec7e3bab
|
||
|
|
f3ae70573c
|
||
|
|
830f84ab26
|
||
|
|
5a9df7ca86
|
||
|
|
4bcdcda3a0
|
||
|
|
7a27912dac
|
||
|
|
cf4b91ac83
|
||
|
|
36c3d92399
|
||
|
|
6a2a35c008
|
||
|
|
a9202f5b57
|
||
|
|
4cbefe3a22
|
||
|
|
3841ceaf5b
|
||
|
|
e2eb784eef
|
||
|
|
6078a5ba29
|
||
|
|
663f5cd048
|
||
|
|
5999906bf0
|
||
|
|
1e0c1490fb
|
||
|
|
5b0eebdb43
|
||
|
|
9e64939de4
|
||
|
|
b911670121
|
||
|
|
d175a817a5
|
||
|
|
b285bc7312
|
||
|
|
c8cd198c4e
|
||
|
|
95d45f5a0a
|
||
|
|
766e4d9603
|
||
|
|
a601fd0afa
|
||
|
|
cc23e459e0
|
||
|
|
d36b678ba1
|
||
|
|
43265bcddb
|
||
|
|
47d4069d6f
|
||
|
|
904df63198
|
||
|
|
1df971a71e
|
||
|
|
2a413d5717
|
||
|
|
9c2357dfe6
|
||
|
|
f82562f450
|
||
|
|
a33b63842a
|
||
|
|
4256a312ae
|
||
|
|
678a0f4f48
|
||
|
|
7344c5ed4a
|
||
|
|
537fbc8af4
|
||
|
|
cf25af23d1
|
||
|
|
f680830b53
|
||
|
|
53a239958f
|
||
|
|
f13326ffaf
|
||
|
|
75e7760d04
|
||
|
|
02d0f3f538
|
||
|
|
e2a78389f2
|
||
|
|
81fdf1f77a
|
||
|
|
631f58bf72
|
||
|
|
1d2d66fc83
|
||
|
|
34aba8c7c7
|
||
|
|
5e764a0d17
|
||
|
|
65e86db731
|
||
|
|
615d253bb4
|
||
|
|
2fcbc7bee8
|
||
|
|
2c14da997d
|
||
|
|
a7c2182d4a
|
||
|
|
0aabc206a1
|
||
|
|
7d8b33390a
|
||
|
|
5a5604c35d
|
||
|
|
addf9addab
|
||
|
|
f562aa0874
|
||
|
|
19a9dfe7c6
|
||
|
|
46594f1fc3
|
||
|
|
a93ebbfb5b
|
||
|
|
53726b5743
|
||
|
|
71870cd178
|
||
|
|
6f3b5b5e51
|
||
|
|
6b689baa7a
|
||
|
|
9ac64605d3
|
||
|
|
102b357a75
|
||
|
|
6eb0b4d982
|
||
|
|
d8cb7c9242
|
||
|
|
9002ac8b5c
|
||
|
|
72a03f641d
|
||
|
|
fe2e78f3c7
|
||
|
|
6e4f0ba6e4
|
||
|
|
19092eda2e
|
||
|
|
b03cca65d8
|
||
|
|
fec5bf65f1
|
||
|
|
7836dbe147
|
||
|
|
297aba248b
|
||
|
|
d41c90f541
|
||
|
|
f2c70d582a
|
||
|
|
24c9ae321c
|
||
|
|
7a18a2602f
|
||
|
|
a39835493a
|
||
|
|
4e7113a079
|
||
|
|
8080e07281
|
||
|
|
fc0e1384c4
|
||
|
|
9603453334
|
||
|
|
29368a0dd8
|
||
|
|
8ee97ac0ae
|
||
|
|
6bbeb657ea
|
||
|
|
c824e15cdb
|
||
|
|
38b2e7a1ed
|
||
|
|
efff262fb5
|
||
|
|
8da6fefdc0
|
||
|
|
14cbd63b01
|
||
|
|
63d18aad1e
|
||
|
|
ed52d421ea
|
||
|
|
6df6a012d2
|
||
|
|
ac675b037e
|
||
|
|
ca4f3acc0e
|
||
|
|
5b7761fe7d
|
||
|
|
7a2a27b1b9
|
||
|
|
1cff58c106
|
||
|
|
9185ceade6
|
||
|
|
908bc87b06
|
||
|
|
6b852556a5
|
||
|
|
ae18468bad
|
||
|
|
42bbdc9b26
|
||
|
|
b1ecdc3439
|
||
|
|
fd7e18989d
|
||
|
|
757eac08c6
|
||
|
|
760e58f993
|
||
|
|
c8868ead47
|
||
|
|
58981e0087
|
||
|
|
06635ed014
|
||
|
|
5a92173586
|
||
|
|
897d9d4099
|
||
|
|
6b14f31107
|
||
|
|
976eee9ce3
|
||
|
|
689951cfde
|
||
|
|
4cb5b12e68
|
||
|
|
9761569e06
|
||
|
|
100b58312f
|
||
|
|
c5b0d15830
|
||
|
|
8107692d83
|
||
|
|
3262ad78c1
|
||
|
|
85fb08b3d4
|
||
|
|
0952dd80b2
|
||
|
|
a3178e94bd
|
||
|
|
f7554e0e24
|
||
|
|
27440aefc4
|
||
|
|
ba85c88544
|
||
|
|
b417f84492
|
||
|
|
48ef4bcdca
|
||
|
|
7a28cf1c0a
|
||
|
|
1050ddea8a
|
||
|
|
a7151dbc89
|
||
|
|
d532303b7f
|
||
|
|
7017985682
|
||
|
|
7aba8aa4ec
|
||
|
|
d1eed619a7
|
||
|
|
6cbda52d6b
|
||
|
|
f03515b0eb
|
||
|
|
03a9907bee
|
||
|
|
49fde5adbd
|
||
|
|
165e82f78b
|
||
|
|
3ad10b8b07
|
||
|
|
e2e2b05bc6
|
||
|
|
98733aa62b
|
||
|
|
58deafb1d8
|
||
|
|
88d1f6f2ae
|
||
|
|
6a983fe33c
|
||
|
|
8d58a7fcc1
|
||
|
|
13cf7b5fe7
|
||
|
|
6a46dad9c5
|
||
|
|
534aaba27e
|
||
|
|
119679c996
|
||
|
|
b1d013977f
|
||
|
|
4d12f7ac01
|
||
|
|
439ea891ca
|
||
|
|
8ab3ddb8eb
|
||
|
|
4afe678667
|
||
|
|
3b76146d53
|
||
|
|
341759a325
|
||
|
|
122bae21a2
|
||
|
|
5dc782ca24
|
||
|
|
f2baa765b4
|
||
|
|
2dd1fdf869
|
||
|
|
b1e849a251
|
||
|
|
58010c27f4
|
||
|
|
98f2f449f9
|
||
|
|
76ee56c762
|
||
|
|
ba41ad8f0b
|
||
|
|
a217391338
|
||
|
|
5824e9d366
|
||
|
|
57bd3d505e
|
||
|
|
d6c2dabcbb
|
||
|
|
1f733c120c
|
||
|
|
735ccd96a6
|
||
|
|
cd4e905054
|
||
|
|
715419abe7
|
||
|
|
d37f2e3827
|
||
|
|
cec5e8b16b
|
||
|
|
a08e07e515
|
||
|
|
d7f390b236
|
||
|
|
55cb12c978
|
||
|
|
7d8bfa8f0a
|
||
|
|
d00e96baa4
|
||
|
|
17f044cb3f
|
||
|
|
1fa6e90439
|
||
|
|
f15790e25b
|
||
|
|
53c5946c04
|
||
|
|
9ffb03217a
|
||
|
|
4f65773aa9
|
||
|
|
f1476912f3
|
||
|
|
adb591f8c7
|
||
|
|
4ef068dadc
|
||
|
|
a0d5ee17c2
|
||
|
|
9935d2d26b
|
||
|
|
9eff9874c5
|
||
|
|
09516835d0
|
||
|
|
2a24ce9a35
|
||
|
|
9ea79c92a6
|
||
|
|
c30df8e5b5
|
||
|
|
397d0a9f29
|
||
|
|
0fa23ccf40
|
||
|
|
87a91bfeb1
|
||
|
|
232b92fd7e
|
||
|
|
d88f9f0a15
|
||
|
|
154b2062ba
|
||
|
|
38d49eece4
|
||
|
|
d00577ac8d
|
||
|
|
620fc24cd2
|
||
|
|
494b615dc2
|
||
|
|
d834b7e0c8
|
||
|
|
987b8f45d7
|
||
|
|
52ecbdeaff
|
||
|
|
121f461491
|
||
|
|
f4b189adef
|
||
|
|
40c4860548
|
||
|
|
d2a7ae46ac
|
||
|
|
8a02a5aca3
|
||
|
|
96df5a80b8
|
||
|
|
489ef8a514
|
||
|
|
8c6c63465f
|
||
|
|
e9aaeab982
|
||
|
|
a608b26fde
|
||
|
|
3ce009db41
|
||
|
|
a0b0938099
|
||
|
|
32d3672a51
|
||
|
|
0c17337388
|
||
|
|
9c449bed43
|
||
|
|
a64aa83eb8
|
||
|
|
64b5de98c8
|
||
|
|
4e02664977
|
||
|
|
bad3aaf6e0
|
||
|
|
9b19bc94b3
|
||
|
|
9479f3d364
|
||
|
|
8d97ea4112
|
||
|
|
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
|
||
|
|
56a1a811b9
|
||
|
|
32bacdd228
|
||
|
|
2d4c82cd29
|
||
|
|
e5611d8081
|
||
|
|
e52977fb63
|
||
|
|
11f096d9f3
|
||
|
|
6e507be5e9
|
||
|
|
6a8a561484
|
||
|
|
c5f522be4c
|
||
|
|
ce8041754b
|
||
|
|
c4af89946b
|
||
|
|
95fecfc095
|
||
|
|
ec4e8c416c
|
||
|
|
64733914f2
|
||
|
|
4e7baf302c
|
||
|
|
2f9a6b5548
|
||
|
|
646e246ec6
|
||
|
|
ae941d2761
|
||
|
|
b40db0d1dd
|
||
|
|
cf4c17df22
|
||
|
|
f152e2bac7
|
||
|
|
f81e895fe1
|
||
|
|
370a635ee2
|
||
|
|
4696faf86d
|
||
|
|
332e57f305
|
||
|
|
4ee3daa8f8
|
||
|
|
ee82475aa3
|
||
|
|
ff0caf93da
|
||
|
|
20fd950ef4
|
||
|
|
6e10089280
|
||
|
|
9298aef87e
|
||
|
|
6c66028800
|
||
|
|
ed293c7e61
|
||
|
|
7791ca13e2
|
||
|
|
d0aeaf1109
|
||
|
|
c041457799
|
||
|
|
08a9a0273f
|
||
|
|
ae4b95380a
|
||
|
|
2b49b23d41
|
||
|
|
38f1af025c
|
||
|
|
d0577611ca
|
||
|
|
7b357ebc54
|
||
|
|
4c380bae1c
|
||
|
|
1b0468f742
|
||
|
|
e7425de523
|
||
|
|
b2c8fa3e62
|
||
|
|
9bbac6d3c1
|
||
|
|
dcae0cbb91
|
||
|
|
57fbbf820c
|
||
|
|
86fd2b4eea
|
||
|
|
7117d76842
|
||
|
|
98ad2087de
|
||
|
|
fabf3a3a5e
|
||
|
|
ba9e5b1b88
|
||
|
|
307ec1794c
|
||
|
|
f86b63f68d
|
||
|
|
2f25107d09
|
||
|
|
556e832056
|
||
|
|
f4561c1f4f
|
||
|
|
ee97388981
|
||
|
|
0a0fdffc46
|
||
|
|
e3898f28fc
|
||
|
|
52c4d2a346
|
||
|
|
404595801d
|
||
|
|
3e097c260d
|
||
|
|
e0844b38cd
|
||
|
|
f321ca908b
|
||
|
|
79ec28641a
|
||
|
|
4592955da1
|
||
|
|
a2fe39defd
|
||
|
|
7cdfa8f79d
|
||
|
|
0647b853a6
|
||
|
|
3a11d536d5
|
||
|
|
96043f3d70
|
||
|
|
5f44458e64
|
||
|
|
cc632c5ef9
|
||
|
|
631c260280
|
||
|
|
1357e92627
|
||
|
|
3395934330
|
||
|
|
744fffdd8a
|
||
|
|
0a3450f649
|
||
|
|
7d5eab1a8e
|
||
|
|
7674196cc1
|
||
|
|
c160e5ddf2
|
||
|
|
9518e7da8e
|
||
|
|
e507dd0390
|
||
|
|
510dccc5dc
|
||
|
|
17712883c5
|
||
|
|
5cb6474ade
|
||
|
|
4947f788d5
|
||
|
|
465a23633e
|
||
|
|
7c5d6326f8
|
||
|
|
3f5f57ef12
|
||
|
|
4e24b239a4
|
||
|
|
c8dc2a1407
|
||
|
|
27fec1bacb
|
||
|
|
d8e0e07805
|
||
|
|
8898a427df
|
||
|
|
7e039c47ae
|
||
|
|
c2a4ad026a
|
||
|
|
db81e43525
|
||
|
|
9cc776e06a
|
||
|
|
602da0960c
|
||
|
|
9577a39046
|
||
|
|
f9fe20ba68
|
||
|
|
227da47bfc
|
||
|
|
9f5daafad9
|
||
|
|
b2df65f5cc
|
||
|
|
d6999fad2f
|
||
|
|
e4981b52ed
|
||
|
|
3c25934495
|
||
|
|
e23a4c71a2
|
||
|
|
6ee7243e04
|
||
|
|
d45cc5ffe5
|
||
|
|
3c8b7cb1f2
|
||
|
|
2e415f6ec2
|
||
|
|
5ff9303bd1
|
||
|
|
84ac8f00e0
|
||
|
|
418ff68be4
|
||
|
|
2d1b6363e6
|
||
|
|
34cebf2810
|
||
|
|
0fa4a175e0
|
||
|
|
72a832f190
|
||
|
|
ba65264d1e
|
||
|
|
2ee33ab229
|
||
|
|
1eea654a36
|
||
|
|
c6643125e1
|
||
|
|
b68514b176
|
||
|
|
960e913222
|
||
|
|
e99e563aff
|
||
|
|
0b40a3fb10
|
||
|
|
a84ef21571
|
||
|
|
1ef2560ef6
|
||
|
|
d1b14fccdd
|
||
|
|
88b3a57962
|
||
|
|
9f6121e9b2
|
||
|
|
4a7ea6009d
|
||
|
|
c4a7df6f38
|
||
|
|
2468d80078
|
||
|
|
ebae8c655c
|
||
|
|
1a0bc7f65f
|
||
|
|
91a5db2ee4
|
||
|
|
b639bf3077
|
||
|
|
c409400cbf
|
||
|
|
d602038858
|
||
|
|
017b8603d5
|
||
|
|
a9dd1eaacd
|
||
|
|
f30d3df5b3
|
||
|
|
c3ece4f317
|
||
|
|
1e11acee72
|
||
|
|
57193eecc0
|
||
|
|
720d525b95
|
||
|
|
f77f2bbf92
|
||
|
|
0ed59f223c
|
||
|
|
de2973ac42
|
||
|
|
8491e5fed1
|
||
|
|
6a330e38f2
|
||
|
|
1dcd3fceed
|
||
|
|
5768d4bba6
|
||
|
|
f85fe31b38
|
||
|
|
22f81a106b
|
||
|
|
7e08dc286e
|
||
|
|
3ca6d04f6b
|
||
|
|
e57985da8d
|
||
|
|
8a23cc444f
|
||
|
|
2e0a87e596
|
||
|
|
e8771dfc5b
|
||
|
|
030575592c
|
||
|
|
88fba6d408
|
||
|
|
2375a653fe
|
||
|
|
bf291613a3
|
||
|
|
406c0a0cd2
|
||
|
|
c9f9f87973
|
||
|
|
383d5eeb06
|
||
|
|
dce2c50b9d
|
||
|
|
e888befee1
|
||
|
|
a33a45fc20
|
||
|
|
23e8be1097
|
||
|
|
800810169d
|
||
|
|
eeb5e8d455
|
||
|
|
d806c8e1f2
|
||
|
|
2ea306097d
|
||
|
|
3472b448c7
|
||
|
|
e62820187d
|
||
|
|
a6814aa2a3
|
||
|
|
560bd8b65e
|
||
|
|
a431816243
|
||
|
|
574582f977
|
||
|
|
23f022965a
|
||
|
|
aef81760d0
|
||
|
|
bb5deb10d5
|
||
|
|
69d4e0cd84
|
||
|
|
a9a264252a
|
||
|
|
a539191a33
|
||
|
|
3f2496644f
|
||
|
|
daf8b87832
|
||
|
|
a2b9af56dd
|
||
|
|
8de661494a
|
||
|
|
07f2e73a22
|
||
|
|
2472cbbff4
|
||
|
|
58c2092049
|
||
|
|
311d5e1f5c
|
||
|
|
39d8f82caf
|
||
|
|
d7552f1dce
|
||
|
|
9badf36ce0
|
||
|
|
aff069dd1a
|
||
|
|
f29f2bca74
|
||
|
|
544ec63d6e
|
||
|
|
ed75060482
|
||
|
|
1d376486cd
|
||
|
|
1ffddfd0e2
|
||
|
|
0d3fb550f2
|
||
|
|
ca6c913fa7
|
||
|
|
ca06f9ebb5
|
||
|
|
e6ebac7cda
|
||
|
|
4453b95f5c
|
||
|
|
61d5e36a4e
|
||
|
|
410b96b58a
|
||
|
|
66e136c7d6
|
||
|
|
d61b48740f
|
||
|
|
3607a6d930
|
||
|
|
c8787c3bd6
|
||
|
|
b83c3923da
|
||
|
|
a694be3795
|
||
|
|
9eae01cc98
|
||
|
|
58e3371fac
|
||
|
|
98c3b93c3d
|
||
|
|
15a81b03d9
|
||
|
|
7fce778ee4
|
||
|
|
b0aabf96b8
|
||
|
|
486e987b71
|
||
|
|
ecaf923e6d
|
||
|
|
953de7fb5f
|
||
|
|
55ef9bf686
|
||
|
|
6823982227
|
||
|
|
ff41b0d4f7
|
||
|
|
6130a34587
|
||
|
|
2ca708fe43
|
||
|
|
d2ce921676
|
||
|
|
a81bad32fe
|
||
|
|
da3e039a05
|
||
|
|
e778a95a01
|
||
|
|
24b6cc2250
|
||
|
|
fdf649fcec
|
||
|
|
61fcf8e0ec
|
||
|
|
d85ed34ce2
|
||
|
|
dcb0b8fb4b
|
||
|
|
6729d72322
|
||
|
|
b229854ae0
|
||
|
|
e0125dda54
|
||
|
|
7b8f4f15cc
|
||
|
|
2e7793dc2b
|
||
|
|
2c5b680426
|
||
|
|
626ece8046
|
||
|
|
088940424d
|
||
|
|
7abd0f3017
|
||
|
|
f8519ec09d
|
||
|
|
3bda67be0a
|
||
|
|
cb64235953
|
||
|
|
ceb36ae8ec
|
||
|
|
94076b7471
|
||
|
|
ebc2607446
|
||
|
|
801cf64f45
|
||
|
|
f52c50242a
|
||
|
|
3f10e1b59e
|
||
|
|
47219585d4
|
||
|
|
e46f2e6116
|
||
|
|
3804786e89
|
||
|
|
6bcf3e134f
|
||
|
|
cc0edeeb47
|
||
|
|
156cb7bcac
|
||
|
|
c2db94125d
|
||
|
|
330d3fa72e
|
||
|
|
6b70074ec6
|
||
|
|
712107ae10
|
||
|
|
906e09fd9f
|
||
|
|
91e8a86ee2
|
||
|
|
c7e96184e6
|
||
|
|
3c1eea33d9
|
||
|
|
bfe3d4b18a
|
||
|
|
bd7d4f5a0d
|
||
|
|
3097ff6250
|
||
|
|
2f16f4f613
|
||
|
|
f36b59c961
|
||
|
|
86bc2042e5
|
||
|
|
658cb2d3c8
|
||
|
|
829fc49aac
|
||
|
|
92e861ebae
|
||
|
|
4212453cf5
|
||
|
|
ef65bceccd
|
||
|
|
b061c87fc9
|
||
|
|
8a4caba26f
|
||
|
|
76e1fc6099
|
||
|
|
7b29897efb
|
||
|
|
7704e5d399
|
||
|
|
db5d6c42c9
|
||
|
|
54b7e46f1b
|
||
|
|
de709162e3
|
||
|
|
5d2d409d0f
|
||
|
|
f265810a5c
|
||
|
|
9124574bc5
|
||
|
|
7f922dd864
|
||
|
|
c289dab514
|
||
|
|
29ff9e114e
|
||
|
|
c1ab5fe98d
|
||
|
|
6176ca38a8
|
||
|
|
abb65b99fe
|
||
|
|
6b1ccc4ce5
|
||
|
|
f968eb21fd
|
||
|
|
7f8846f23d
|
||
|
|
ae243a9d07
|
||
|
|
a7c4f6c2aa
|
||
|
|
4a275b3dec
|
||
|
|
70d1295919
|
||
|
|
03ba3b5583
|
||
|
|
94a40501d4
|
||
|
|
b4588d5b4c
|
||
|
|
5221db2e63
|
||
|
|
143803aad9
|
||
|
|
edbc2cc045
|
||
|
|
609538b9be
|
||
|
|
4db5425238
|
||
|
|
03727a61d3
|
||
|
|
28903e0c10
|
||
|
|
500498508e
|
||
|
|
ac33b86c3d
|
||
|
|
4931f1b9a3
|
||
|
|
c17f6a95d4
|
||
|
|
34cc81c446
|
||
|
|
2103b2dafd
|
||
|
|
d2014a5e82
|
||
|
|
811b173387
|
||
|
|
740df726e9
|
||
|
|
5591e1b377
|
||
|
|
41bc673694
|
||
|
|
8a15d46198
|
||
|
|
1e2efce26a
|
||
|
|
74c1b03a6b
|
||
|
|
058649036f
|
||
|
|
f74a5521ba
|
||
|
|
9f1a4f0ced
|
||
|
|
2a8cc7397e
|
||
|
|
efef3cb80d
|
||
|
|
01d127f49e
|
||
|
|
60a9e4b534
|
||
|
|
086d9ed7e2
|
||
|
|
78424385fc
|
||
|
|
e311cad8f7
|
||
|
|
c576f7f8f2
|
||
|
|
615a1457bf
|
||
|
|
3d08be4fac
|
||
|
|
eeeb9d6ed7
|
||
|
|
c34b6ff6c1
|
||
|
|
38b0b2ac7d
|
||
|
|
3c3a756771
|
||
|
|
fb099a1988
|
||
|
|
b65ff2a767
|
||
|
|
8d6d27651c
|
||
|
|
f66e9aea9e
|
||
|
|
276eb77862
|
||
|
|
ac0b8ab36a
|
||
|
|
2c384d780f
|
@@ -7,6 +7,7 @@ jobs:
|
||||
strategy:
|
||||
matrix:
|
||||
arch: [amd64, i686]
|
||||
build: [debug, release]
|
||||
runs-on: oscw
|
||||
container:
|
||||
image: codingworkshop/oscw-runner:latest
|
||||
@@ -17,7 +18,7 @@ jobs:
|
||||
fetch-depth: 0
|
||||
- name: Build ExectOS
|
||||
run: |
|
||||
echo "charch ${{ matrix.arch }} && ./configure.sh && cd build-${{ matrix.arch }}-xtchain && xbuild -v && xbuild diskimg -v" > build.cmds
|
||||
echo "charch ${{ matrix.arch }} && chbuild ${{ matrix.build }} && ./configure.sh && cd build-${{ matrix.arch }}-${{ matrix.build }} && xbuild -v && xbuild diskimg -v" > build.cmds
|
||||
xtchain < build.cmds
|
||||
- name: Publish binaries
|
||||
if: ${{ github.ref == 'refs/heads/master' }}
|
||||
@@ -26,8 +27,8 @@ jobs:
|
||||
OSCW_ARTIFACTS_USERNAME: ${{ secrets.OSCW_ARTIFACTS_USERNAME }}
|
||||
OSCW_ARTIFACTS_USERKEY: ${{ secrets.OSCW_ARTIFACTS_USERKEY }}
|
||||
run: |
|
||||
tar -I 'gzip' -cpf ExectOS-$(date +'%Y%m%d')-${GITHUB_SHA:0:10}-${{ matrix.arch }}-bin.tar.gz -C build-${{ matrix.arch }}-xtchain/output/binaries .
|
||||
tar -I 'gzip' -cpf ExectOS-$(date +'%Y%m%d')-${GITHUB_SHA:0:10}-${{ matrix.arch }}-lib.tar.gz -C build-${{ matrix.arch }}-xtchain/output/library .
|
||||
tar -I 'gzip' -cpf ExectOS-$(date +'%Y%m%d')-${GITHUB_SHA:0:10}-${{ matrix.arch }}-sym.tar.gz -C build-${{ matrix.arch }}-xtchain/output/symbols .
|
||||
gzip -c build-${{ matrix.arch }}-xtchain/output/disk.img > ExectOS-$(date +'%Y%m%d')-${GITHUB_SHA:0:10}-${{ matrix.arch }}.img.gz
|
||||
artifact_publish "ExectOS-$(date +'%Y%m%d')-${GITHUB_SHA:0:10}-${{ matrix.arch }}*.gz" ExectOS
|
||||
tar -I 'gzip' -cpf ExectOS-$(date +'%Y%m%d')-${GITHUB_SHA:0:10}-${{ matrix.arch }}-${{ matrix.build }}-bin.tar.gz -C build-${{ matrix.arch }}-${{ matrix.build }}/output/binaries .
|
||||
tar -I 'gzip' -cpf ExectOS-$(date +'%Y%m%d')-${GITHUB_SHA:0:10}-${{ matrix.arch }}-${{ matrix.build }}-sdk.tar.gz -C build-${{ matrix.arch }}-${{ matrix.build }}/output/sdk .
|
||||
tar -I 'gzip' -cpf ExectOS-$(date +'%Y%m%d')-${GITHUB_SHA:0:10}-${{ matrix.arch }}-${{ matrix.build }}-sym.tar.gz -C build-${{ matrix.arch }}-${{ matrix.build }}/output/symbols .
|
||||
gzip -c build-${{ matrix.arch }}-${{ matrix.build }}/output/disk.img > ExectOS-$(date +'%Y%m%d')-${GITHUB_SHA:0:10}-${{ matrix.arch }}-${{ matrix.build }}.img.gz
|
||||
artifact_publish "ExectOS-$(date +'%Y%m%d')-${GITHUB_SHA:0:10}-${{ matrix.arch }}-${{ matrix.build }}*.gz" ExectOS
|
||||
|
||||
+7
-10
@@ -1,8 +1,5 @@
|
||||
# Detect XTChain toolchain
|
||||
# Minimum CMake version requirement
|
||||
cmake_minimum_required(VERSION 3.19.0)
|
||||
if(NOT CMAKE_VERSION MATCHES "XTC")
|
||||
message(FATAL_ERROR "XTChain not detected or corrupted!")
|
||||
endif()
|
||||
|
||||
# Lowercase target architecture
|
||||
string(TOLOWER ${ARCH} ARCH)
|
||||
@@ -44,7 +41,7 @@ set(CMAKE_TOOLCHAIN_FILE "sdk/cmake/toolchain.cmake")
|
||||
project(EXECTOS)
|
||||
|
||||
# Load all the CMake SDK
|
||||
include(sdk/cmake/baseaddress.cmake)
|
||||
include(sdk/cmake/baseaddress/${ARCH}.cmake)
|
||||
include(sdk/cmake/emulation.cmake)
|
||||
include(sdk/cmake/functions.cmake)
|
||||
include(sdk/cmake/version.cmake)
|
||||
@@ -58,18 +55,18 @@ add_definitions(-D__XTOS__)
|
||||
add_definitions(-DXTOS_SOURCE_DIR="${EXECTOS_SOURCE_DIR}")
|
||||
add_definitions(-DXTOS_BINARY_DIR="${EXECTOS_BINARY_DIR}")
|
||||
|
||||
# Set libraries target directory
|
||||
set(LIBRARY_OUTPUT_PATH ${EXECTOS_BINARY_DIR}/output/library CACHE PATH "Build directory" FORCE)
|
||||
# Add assembler flags
|
||||
add_compiler_asmflags(-D__XTOS_ASSEMBLER__)
|
||||
|
||||
# Compute __FILE__ definition
|
||||
file(RELATIVE_PATH _PATH_PREFIX ${EXECTOS_BINARY_DIR} ${EXECTOS_SOURCE_DIR})
|
||||
add_compiler_flags(-D__RELFILE__="&__FILE__[__FILE__[0] == '.' ? sizeof \\\"${_PATH_PREFIX}\\\" - 1 : sizeof XTOS_SOURCE_DIR]")
|
||||
|
||||
# Set the virtual disk image size (in MiB)
|
||||
set_disk_image_size(32)
|
||||
set_disk_image_size(48)
|
||||
|
||||
# Build all subprojects
|
||||
add_subdirectory(bootdata)
|
||||
add_subdirectory(boot)
|
||||
add_subdirectory(drivers)
|
||||
add_subdirectory(xtldr)
|
||||
add_subdirectory(sdk)
|
||||
add_subdirectory(xtoskrnl)
|
||||
|
||||
@@ -9,8 +9,7 @@ porting drivers, fixing bugs, writing tests, creating documentation, or helping
|
||||
love the help.
|
||||
|
||||
## Wish List
|
||||
If you are looking for a way to contribute, but you are not sure where to start, check our [IDEAS](IDEAS.md) and
|
||||
[KNOWN ISSUES](KNOWN_ISSUES.md) pages for suggestions. We try to keep them up to date. You can also check a list of
|
||||
If you are looking for a way to contribute, but you are not sure where to start, check our list of
|
||||
[open issues](https://git.codingworkshop.eu.org/xt-sys/exectos/issues). If you find interesting task and you are serious
|
||||
about tackling one, feel free to contact us. We will be able to provide a more detailed information and suggestions
|
||||
towards getting started.
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
## ExectOS Ideas
|
||||
This is a list of ideas that migh but not must be realized.
|
||||
|
||||
### SDK
|
||||
- [ ] Currently XT Development Kit (XTDK) is a garbage. It should be cleaned up the way, it contains all structures
|
||||
and definitions, as well as all routines that are exported and can be used by other components or software
|
||||
dynamically linked. All other routines should be available as well in some form, as some libraries can share
|
||||
code with others (eg. XTLDR calls routines exported by XTOSKRNL). This is partially done, as XTDK has been
|
||||
cleaned up, but still there are routines used by XTLDR.
|
||||
|
||||
### XTLDR
|
||||
- [ ] Rewrite memory mapping and paging support in bootloader to make it more flexible and architecture independent.
|
||||
This should support paging levels, thus allowing to make a use of PML5 on modern AMD64 processors and increasing
|
||||
the addressable virtual memory from 256TB to 128PB.
|
||||
- [ ] Find graphics card from all PCI devices and identify its framebuffer address when GOP is not supported by UEFI
|
||||
firmware and UGA has to be used instead.
|
||||
|
||||
### XTOSKRNL
|
||||
- [ ] Implement mechanism for detecting CPU features and checking hardware requirements. If CPU does not meet
|
||||
requirements, it should cause a kernel panic before any non-supported instruction is being used.
|
||||
- [ ] Design a mechanism of sharing common code between some architectures (i.e. both i686 and amd64 supports APIC,
|
||||
while it is not available on ARM).
|
||||
- [ ] Finish framebuffer and terminal implementation. Initialization code is already prepared as well as routines for
|
||||
clearing the screen and drawing single points. Terminal should be instantiable (should be able to create many
|
||||
terminals and switch between them) and work on top of FB. It should define ANSI colors and scrollback buffer.
|
||||
@@ -1,6 +0,0 @@
|
||||
## ExectOS Known Issues
|
||||
This is a list of well known bugs that exists in all master branch builds.
|
||||
|
||||
### XTLDR
|
||||
- [ ] EFI Runtime Services are not mapped properly into higher half. They are mapped itself, but all pointers inside
|
||||
that structure point to some physical address that is unavailable after paging is enabled.
|
||||
+25
-25
@@ -8,20 +8,20 @@
|
||||
<a href="https://git.codingworkshop.eu.org/xt-sys/exectos/actions">
|
||||
<img alt="Build Status" src="https://codingworkshop.eu.org/actions.php?project=xt-sys/exectos">
|
||||
</a>
|
||||
<a href="https://artifacts.codingworkshop.eu.org/ExectOS">
|
||||
<a href="https://artifacts.codingworkshop.eu.org/ExectOS/?C=M&O=D">
|
||||
<img alt="CI/CD Artifacts" src="https://img.shields.io/badge/Download-%F0%9F%A1%87-blueviolet">
|
||||
</a>
|
||||
<a href="https://git.codingworkshop.eu.org/xt-sys/exectos/src/branch/master/COPYING.md">
|
||||
<img alt="License" src="https://img.shields.io/badge/License-GPLv3-blue.svg">
|
||||
</a>
|
||||
<a href="https://codeium.com/">
|
||||
<img alt="Codeium" src="https://img.shields.io/badge/Powered%20By-Codeium-09B6A2?logo=Codeium">
|
||||
<a href="https://exectos.eu.org/ai-assisted">
|
||||
<img alt="AI Assisted" src="https://img.shields.io/badge/AI-Assisted-darkcyan">
|
||||
</a>
|
||||
<a href="https://github.com/sponsors/xt-sys/">
|
||||
<img alt="Sponsor" src="https://img.shields.io/badge/Sponsor-%E2%9D%A4-red?logo=GitHub">
|
||||
</a>
|
||||
<a href="https://discord.com/invite/zBzJ5qMGX7">
|
||||
<img alt="Discord" src="https://img.shields.io/discord/723186294540206100?label=Chat">
|
||||
<img alt="Discord" src="https://img.shields.io/badge/Chat-Join%20Discord-success">
|
||||
</a>
|
||||
</p>
|
||||
|
||||
@@ -53,31 +53,31 @@ implement any environment subsystem to support applications that are strictly wr
|
||||
* NT drivers compatibility layer
|
||||
|
||||
# Requirements
|
||||
ExectOS is in very early development stage, thus its requirements have been not specified yet. However according to its
|
||||
design, it requires a modern EFI enabled hardware. It is not possible currently to boot ExectOS on a legacy BIOS.
|
||||
ExectOS is currently in a very early stage of development, so its specific requirements are not fully defined yet.
|
||||
However, based on the current design, it requires modern EFI hardware. You cannot boot ExectOS on a legacy BIOS
|
||||
right now, but there are plans to add BIOS support in the future.
|
||||
|
||||
# Source structure
|
||||
| Directory | Description |
|
||||
|-------------|----------------------------------------------------------|
|
||||
| bootdata | default configuration and data needed to boot XTOS |
|
||||
| drivers | XT native drivers source code |
|
||||
| sdk/cmake | Host toolchain configuration and build-related functions |
|
||||
| sdk/xtdk | XT Software Development Kit headers |
|
||||
| services | integral subsystems services source code |
|
||||
| subsystems | environment subsystems source code |
|
||||
| xtoskrnl | XTOS kernel source code |
|
||||
| xtldr | XTOS boot loader source code |
|
||||
| Directory | Description |
|
||||
|------------------|--------------------------------------------------------------|
|
||||
| boot/bootdata | default configuration and data needed to boot XTOS |
|
||||
| boot/bootsect | boot sector code (MBR & VBR) initializing the boot process |
|
||||
| boot/xtldr | XTOS boot loader source code |
|
||||
| drivers | XT native drivers source code |
|
||||
| sdk/cmake | host toolchain configuration and build-related functions |
|
||||
| sdk/firmware | firmware enabling XTOS to boot on virtual machines |
|
||||
| sdk/xtdk | XT Software Development Kit headers |
|
||||
| services | integral subsystems services source code |
|
||||
| subsystems | environment subsystems source code |
|
||||
| xtoskrnl | XTOS kernel source code |
|
||||
|
||||
# Build
|
||||
XTOS can be built only by using [XTChain](https://git.codingworkshop.eu.org/xt-sys/xtchain), a special toolchain
|
||||
prepared for compiling XT software. Currently, there is only a Linux version available, so a Linux distribution or WSL
|
||||
is needed. If XTChain is already installed and available, then building ExectOS is quiet easy. First, open a terminal
|
||||
or WSL console and type the following command to launch XTChain build console:
|
||||
```
|
||||
xtchain
|
||||
```
|
||||
While the console is already running, navigate to the directory containing ExectOS source code and use the following
|
||||
commands to first set target build architecture and configure the sources:
|
||||
XTOS can only be built using [XTchain](https://git.codingworkshop.eu.org/xt-sys/xtchain), a dedicated toolchain designed
|
||||
specifically for compiling XT software. XTChain is currently available for both Linux and Windows. Detailed instructions
|
||||
on how to configure and run XTChain can be found [here](https://exectos.eu.org/contributing/setting-up-xtchain).
|
||||
|
||||
With the XTchain environment already running, navigate to the directory containing the ExectOS source code and use the
|
||||
following commands to set the target build architecture and configure the sources:
|
||||
```
|
||||
charch [i686|amd64]
|
||||
chbuild [DEBUG|RELEASE]
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
add_subdirectory(bootdata)
|
||||
add_subdirectory(bootsect)
|
||||
add_subdirectory(xtldr)
|
||||
@@ -40,6 +40,30 @@ SystemPath=multi(0)disk(0)rdisk(0)partition(1)/ExectOS
|
||||
KernelFile=xtoskrnl.exe
|
||||
Parameters=DEBUG=COM1,115200
|
||||
|
||||
[ExectOS_FBDEBUG]
|
||||
SystemName="ExectOS Operating System (FBDEBUG)"
|
||||
SystemType=XTOS
|
||||
BootModules=xtos_o
|
||||
SystemPath=multi(0)disk(0)rdisk(0)partition(1)/ExectOS
|
||||
KernelFile=xtoskrnl.exe
|
||||
Parameters=DEBUG=COM1,115200;SCREEN
|
||||
|
||||
[ExectOS_NOXPA]
|
||||
SystemName="ExectOS Operating System (NOXPA)"
|
||||
SystemType=XTOS
|
||||
BootModules=xtos_o
|
||||
SystemPath=multi(0)disk(0)rdisk(0)partition(1)/ExectOS
|
||||
KernelFile=xtoskrnl.exe
|
||||
Parameters=DEBUG=COM1,115200 NOXPA
|
||||
|
||||
[ExectOS_NOXPA_FBDEBUG]
|
||||
SystemName="ExectOS Operating System (NOXPA / FBDEBUG)"
|
||||
SystemType=XTOS
|
||||
BootModules=xtos_o
|
||||
SystemPath=multi(0)disk(0)rdisk(0)partition(1)/ExectOS
|
||||
KernelFile=xtoskrnl.exe
|
||||
Parameters=DEBUG=COM1,115200;SCREEN NOXPA
|
||||
|
||||
[Windows]
|
||||
SystemName="Microsoft Windows 2000"
|
||||
SystemType=NT50
|
||||
@@ -0,0 +1,8 @@
|
||||
# XT Boot Sector
|
||||
PROJECT(BOOTSECT)
|
||||
|
||||
add_definitions("-DARCH_ESP_SOURCE=\\\"${ARCH}/cpu.S\\\"")
|
||||
|
||||
# Compile boot sectors
|
||||
compile_bootsector(mbrboot ${BOOTSECT_SOURCE_DIR}/mbrboot.S 0x7C00 Start)
|
||||
compile_bootsector(espboot ${BOOTSECT_SOURCE_DIR}/espboot.S 0x7C00 Start)
|
||||
@@ -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"
|
||||
@@ -0,0 +1,529 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: boot/bootsect/espboot.S
|
||||
* DESCRIPTION: XT Boot Loader ESP boot code (FAT32)
|
||||
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
|
||||
*/
|
||||
|
||||
.text
|
||||
.code16
|
||||
|
||||
|
||||
.global Start
|
||||
Start:
|
||||
/* Jump to the real start to omit the BPB (BIOS Parameter Block) */
|
||||
jmp RealStart
|
||||
nop
|
||||
|
||||
/* BIOS Parameter Block */
|
||||
OsName:
|
||||
.ascii "XTOS "
|
||||
OsVersion:
|
||||
.ascii "1.0"
|
||||
BytesPerSector:
|
||||
.word 512
|
||||
SectorsPerCluster:
|
||||
.byte 2
|
||||
ReservedSectors:
|
||||
.word 8
|
||||
FatCopies:
|
||||
.byte 1
|
||||
RootDirEntries:
|
||||
.word 1024
|
||||
TotalSectors:
|
||||
.word 0
|
||||
MediaType:
|
||||
.byte 0xF8
|
||||
SectorsPerFat:
|
||||
.word 0
|
||||
SectorsPerTrack:
|
||||
.word 17
|
||||
NumberOfHeads:
|
||||
.word 0
|
||||
HiddenSectors:
|
||||
.long 0
|
||||
TotalBigSectors:
|
||||
.long 0x200000
|
||||
BigSectorsPerFat:
|
||||
.long 0x1FE0
|
||||
ExtendedFlags:
|
||||
.word 0
|
||||
FsVersion:
|
||||
.word 0
|
||||
RootDirStartCluster:
|
||||
.long 0
|
||||
FSInfoSector:
|
||||
.word 0
|
||||
BackupBootSector:
|
||||
.word 6
|
||||
Reserved:
|
||||
.fill 12, 1, 0
|
||||
DriveNumber:
|
||||
.byte 0x80
|
||||
CurrentHead:
|
||||
.byte 0
|
||||
Signature:
|
||||
.byte 0x29
|
||||
SerialNumber:
|
||||
.long 0
|
||||
VolumeLabel:
|
||||
.ascii "NO NAME "
|
||||
FileSystem:
|
||||
.ascii "FAT32 "
|
||||
|
||||
RealStart:
|
||||
/* Set segments and stack */
|
||||
cli
|
||||
cld
|
||||
xorw %ax, %ax
|
||||
movw %ax, %ds
|
||||
movw %ax, %es
|
||||
movw %ax, %ss
|
||||
movw $0x7C00, %bp
|
||||
leaw -16(%bp), %sp
|
||||
sti
|
||||
|
||||
/* Get drive number */
|
||||
cmpb $0xFF, DriveNumber - Start(%bp)
|
||||
jne GetDriveParameters
|
||||
movb %dl, DriveNumber - Start(%bp)
|
||||
|
||||
GetDriveParameters:
|
||||
/* Get drive parameters from the BIOS */
|
||||
movb DriveNumber - Start(%bp), %dl
|
||||
movb $0x08, %ah
|
||||
movb $0x00, %al
|
||||
int $0x13
|
||||
jnc GetDriveSize
|
||||
movw $0xFFFF, %cx
|
||||
movb %cl, %dh
|
||||
|
||||
GetDriveSize:
|
||||
/* Get drive size from the BIOS */
|
||||
movzbl %dh, %eax
|
||||
incw %ax
|
||||
movzbl %cl, %edx
|
||||
andb $0x3F, %dl
|
||||
mulw %dx
|
||||
xchgb %cl, %ch
|
||||
shrb $0x06, %ch
|
||||
incw %cx
|
||||
movzwl %cx, %ecx
|
||||
mull %ecx
|
||||
movl %eax, %edi
|
||||
|
||||
VerifyBiosParameterBlock:
|
||||
/* Verify the FAT32 BPB */
|
||||
cmpw $0x00, SectorsPerFat - Start(%bp)
|
||||
jne FsError
|
||||
cmpw $0x00, FsVersion - Start(%bp)
|
||||
ja FsError
|
||||
|
||||
ReadExtraCode:
|
||||
/* Read second VBR sector with extra boot code (3 sectors starting from sector 2) */
|
||||
movl HiddenSectors - Start(%bp), %eax
|
||||
addl $0x02, %eax
|
||||
movw $0x03, %cx
|
||||
xorw %bx, %bx
|
||||
movw %bx, %es
|
||||
movw $0x7E00, %bx
|
||||
call ReadSectors
|
||||
jmp StartExtraCode
|
||||
|
||||
ReadSectors:
|
||||
/* Check for extended BIOS functions and use it only if available */
|
||||
pushw %es
|
||||
pushal
|
||||
movb $0x41, %ah
|
||||
movw $0x55AA, %bx
|
||||
movb DriveNumber - Start(%bp), %dl
|
||||
int $0x13
|
||||
jc .ReadCHS
|
||||
cmpw $0xAA55, %bx
|
||||
jne .ReadCHS
|
||||
testb $0x01, %cl
|
||||
jz .ReadCHS
|
||||
|
||||
/* Verify drive size and determine whether to use CHS or LBA */
|
||||
cmpl %edi, %eax
|
||||
jnb .ReadLBA
|
||||
|
||||
.ReadCHS:
|
||||
/* Read sectors using CHS */
|
||||
popal
|
||||
|
||||
.CHSLoop:
|
||||
/* Read sector by sector using CHS */
|
||||
pushw %cx
|
||||
pushal
|
||||
xorl %edx, %edx
|
||||
movzwl SectorsPerTrack - Start(%bp), %ecx
|
||||
divl %ecx
|
||||
incb %dl
|
||||
movb %dl, %cl
|
||||
movl %eax, %edx
|
||||
shrl $0x10, %edx
|
||||
divw NumberOfHeads - Start(%bp)
|
||||
movb %dl, %dh
|
||||
movb DriveNumber - Start(%bp), %dl
|
||||
movb %al, %ch
|
||||
rorb $0x01, %ah
|
||||
rorb $0x01, %ah
|
||||
orb %ah, %cl
|
||||
movw $0x0201, %ax
|
||||
int $0x13
|
||||
popal
|
||||
popw %cx
|
||||
jc DiskError
|
||||
incl %eax
|
||||
movw %es, %dx
|
||||
addw $0x20, %dx
|
||||
movw %dx, %es
|
||||
loop .CHSLoop
|
||||
popw %es
|
||||
ret
|
||||
|
||||
.ReadLBA:
|
||||
/* Prepare DAP packet and read sectors using LBA */
|
||||
popal
|
||||
pushw %cx
|
||||
pushal
|
||||
pushw $0x00
|
||||
pushw $0x00
|
||||
pushl %eax
|
||||
pushw %es
|
||||
pushw %bx
|
||||
pushw %cx
|
||||
pushw $0x10
|
||||
movw %sp, %si
|
||||
movb DriveNumber - Start(%bp), %dl
|
||||
movb $0x42, %ah
|
||||
int $0x13
|
||||
jc DiskError
|
||||
addw $0x10, %sp
|
||||
popal
|
||||
popw %si
|
||||
pushw %bx
|
||||
movzwl %si, %ebx
|
||||
addl %ebx, %eax
|
||||
shll $0x05, %ebx
|
||||
movw %es, %dx
|
||||
addw %bx, %dx
|
||||
movw %dx, %es
|
||||
popw %bx
|
||||
subw %si, %cx
|
||||
jnz .ReadLBA
|
||||
popw %es
|
||||
ret
|
||||
|
||||
DiskError:
|
||||
/* Display disk error message and reboot */
|
||||
movw $.MsgDiskError, %si
|
||||
call Print
|
||||
jmp Reboot
|
||||
|
||||
FsError:
|
||||
/* Display FS error message and reboot */
|
||||
movw $.MsgFsError, %si
|
||||
call Print
|
||||
jmp Reboot
|
||||
|
||||
Print:
|
||||
/* Simple routine to print messages */
|
||||
lodsb
|
||||
orb %al, %al
|
||||
jz .DonePrint
|
||||
movb $0x0E, %ah
|
||||
movw $0x07, %bx
|
||||
int $0x10
|
||||
jmp Print
|
||||
.DonePrint:
|
||||
retw
|
||||
|
||||
Reboot:
|
||||
/* Display a message, wait for a key press and reboot */
|
||||
movw $.MsgAnyKey, %si
|
||||
call Print
|
||||
xorw %ax, %ax
|
||||
int $0x16
|
||||
int $0x19
|
||||
|
||||
.MsgAnyKey:
|
||||
.ascii "Press any key to restart...\r\n\0"
|
||||
|
||||
.MsgDiskError:
|
||||
.ascii "Disk error!\r\n\0"
|
||||
|
||||
.MsgFsError:
|
||||
.ascii "File system error!\r\n\0"
|
||||
|
||||
/* Fill the rest of the VBR with zeros and add VBR signature at the end */
|
||||
.fill (510 - (. - Start)), 1, 0
|
||||
.word 0xAA55
|
||||
|
||||
|
||||
StartExtraCode:
|
||||
/* Load XTLDR file from disk */
|
||||
call LoadStage2
|
||||
|
||||
/* Enable A20 gate */
|
||||
call EnableA20
|
||||
|
||||
/* Call architecture specific initialization code */
|
||||
call InitializeCpu
|
||||
|
||||
/* Jump to Stage2 */
|
||||
call RunStage2
|
||||
|
||||
Clear8042:
|
||||
/* Clear 8042 PS/2 buffer */
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
inb $0x64, %al
|
||||
cmpb $0xff, %al
|
||||
je .Clear8042_Done
|
||||
testb $0x02, %al
|
||||
jnz Clear8042
|
||||
.Clear8042_Done:
|
||||
ret
|
||||
|
||||
EnableA20:
|
||||
/* Enable A20 gate */
|
||||
pushaw
|
||||
call Clear8042
|
||||
movb $0xD1, %al
|
||||
outb %al, $0x64
|
||||
call Clear8042
|
||||
movb $0xDF, %al
|
||||
outb %al, $0x60
|
||||
call Clear8042
|
||||
movb $0xFF, %al
|
||||
outb %al, $0x64
|
||||
call Clear8042
|
||||
popaw
|
||||
ret
|
||||
|
||||
FindFatEntry:
|
||||
/* Find a file or directory in the FAT table */
|
||||
pushw %bx
|
||||
pushw %cx
|
||||
pushw %dx
|
||||
pushw %si
|
||||
pushw %di
|
||||
.FindFatCluster:
|
||||
/* Find FAT32 cluster holding the entry */
|
||||
cmp $0x0FFFFFF8, %eax
|
||||
jae .FindEntryFail
|
||||
pushl %eax
|
||||
movw $0x0200, %bx
|
||||
movw %bx, %es
|
||||
call ReadCluster
|
||||
popl %eax
|
||||
movb SectorsPerCluster - Start(%bp), %cl
|
||||
shlw $0x04, %cx
|
||||
xorw %di, %di
|
||||
.FindEntryLoop:
|
||||
/* Find the entry */
|
||||
movb %es:(%di), %al
|
||||
cmpb $0x00, %al
|
||||
je .FindEntryFail
|
||||
cmpb $0xE5, %al
|
||||
je .FindSkipEntry
|
||||
movb %es:0x0B(%di), %ah
|
||||
cmpb $0x0F, %ah
|
||||
je .FindSkipEntry
|
||||
pushw %di
|
||||
pushw %si
|
||||
pushw %cx
|
||||
movw $0x0B, %cx
|
||||
repe cmpsb
|
||||
popw %cx
|
||||
popw %si
|
||||
popw %di
|
||||
jnz .FindSkipEntry
|
||||
movw %es:0x1A(%di), %ax
|
||||
movw %es:0x14(%di), %dx
|
||||
shll $0x10, %edx
|
||||
orl %edx, %eax
|
||||
clc
|
||||
jmp .FindEntryDone
|
||||
.FindSkipEntry:
|
||||
/* Skip to the next entry */
|
||||
addw $0x20, %di
|
||||
decw %cx
|
||||
jnz .FindEntryLoop
|
||||
call GetFatEntry
|
||||
jmp .FindFatCluster
|
||||
.FindEntryFail:
|
||||
/* Error, file/directory not found */
|
||||
stc
|
||||
.FindEntryDone:
|
||||
/* Clean up the stack */
|
||||
popw %di
|
||||
popw %si
|
||||
popw %dx
|
||||
popw %cx
|
||||
popw %bx
|
||||
ret
|
||||
|
||||
GetFatEntry:
|
||||
/* Get FAT32 sector and offset from FAT table */
|
||||
shll $0x02, %eax
|
||||
movl %eax, %ecx
|
||||
xorl %edx, %edx
|
||||
movzwl BytesPerSector - Start(%bp), %ebx
|
||||
pushl %ebx
|
||||
divl %ebx
|
||||
movzwl ReservedSectors - Start(%bp), %ebx
|
||||
addl %ebx, %eax
|
||||
movl HiddenSectors - Start(%bp), %ebx
|
||||
addl %ebx, %eax
|
||||
popl %ebx
|
||||
decl %ebx
|
||||
andl %ebx, %ecx
|
||||
movzwl ExtendedFlags - Start(%bp), %ebx
|
||||
andw $0x0F, %bx
|
||||
jz LoadFatSector
|
||||
cmpb FatCopies - Start(%bp), %bl
|
||||
jae FsError
|
||||
pushl %eax
|
||||
movl BigSectorsPerFat - Start(%bp), %eax
|
||||
mull %ebx
|
||||
popl %edx
|
||||
addl %edx, %eax
|
||||
|
||||
LoadFatSector:
|
||||
/* Load FAT32 sector from disk */
|
||||
pushl %ecx
|
||||
movw $0x9000, %bx
|
||||
movw %bx, %es
|
||||
cmpl %esi, %eax
|
||||
je .LoadFatSectorDone
|
||||
movl %eax, %esi
|
||||
xorw %bx, %bx
|
||||
movw $0x01, %cx
|
||||
call ReadSectors
|
||||
.LoadFatSectorDone:
|
||||
/* Clean up the stack */
|
||||
popl %ecx
|
||||
movl %es:(%ecx), %eax
|
||||
andl $0x0FFFFFFF, %eax
|
||||
ret
|
||||
|
||||
LoadStage2:
|
||||
/* Load Stage2 executable, first find file in the path */
|
||||
movl $0xFFFFFFFF, %esi
|
||||
pushl %esi
|
||||
movl 0x7C2C, %eax
|
||||
movw $.EfiDirName, %si
|
||||
call FindFatEntry
|
||||
jc Stage2NotLoaded
|
||||
movw $.BootDirName, %si
|
||||
call FindFatEntry
|
||||
jc Stage2NotLoaded
|
||||
movw $.Stage2FileName, %si
|
||||
call FindFatEntry
|
||||
jc Stage2NotLoaded
|
||||
popl %esi
|
||||
/* Load XTLDR file from disk */
|
||||
cmpl $0x02, %eax
|
||||
jb FileNotFound
|
||||
cmpl $0x0FFFFFF8, %eax
|
||||
jae FileNotFound
|
||||
movw $(0xF800 / 16), %bx
|
||||
movw %bx, %es
|
||||
.LoadStage2Loop:
|
||||
/* Load file data from disk */
|
||||
pushl %eax
|
||||
xorw %bx, %bx
|
||||
pushw %es
|
||||
call ReadCluster
|
||||
popw %es
|
||||
xorw %bx, %bx
|
||||
movb SectorsPerCluster - Start(%bp), %bl
|
||||
shlw $0x05, %bx
|
||||
movw %es, %ax
|
||||
addw %bx, %ax
|
||||
movw %ax, %es
|
||||
popl %eax
|
||||
pushw %es
|
||||
call GetFatEntry
|
||||
popw %es
|
||||
cmpl $0x0FFFFFF8, %eax
|
||||
jb .LoadStage2Loop
|
||||
ret
|
||||
|
||||
ParseExecutableHeader:
|
||||
/* Parse Stage2 PE/COFF executable header */
|
||||
pushw %es
|
||||
movw $(0xF800 / 16), %ax
|
||||
movw %ax, %es
|
||||
movl %es:60, %eax
|
||||
addl $(4 + 20), %eax
|
||||
movl %es:16(%eax), %eax
|
||||
addl $0xF800, %eax
|
||||
popw %es
|
||||
ret
|
||||
|
||||
ReadCluster:
|
||||
/* Read FAT32 cluster from disk */
|
||||
decl %eax
|
||||
decl %eax
|
||||
xorl %edx, %edx
|
||||
movzbl SectorsPerCluster - Start(%bp), %ebx
|
||||
mull %ebx
|
||||
pushl %eax
|
||||
xorl %edx, %edx
|
||||
movzbl FatCopies - Start(%bp), %eax
|
||||
mull BigSectorsPerFat - Start(%bp)
|
||||
movzwl ReservedSectors - Start(%bp), %ebx
|
||||
addl %ebx, %eax
|
||||
addl HiddenSectors - Start(%bp), %eax
|
||||
popl %ebx
|
||||
addl %ebx, %eax
|
||||
xorw %bx, %bx
|
||||
movzbw SectorsPerCluster - Start(%bp), %cx
|
||||
call ReadSectors
|
||||
ret
|
||||
|
||||
/* Include architecture specific code */
|
||||
.include ARCH_ESP_SOURCE
|
||||
|
||||
CpuUnsupported:
|
||||
/* Display CPU unsupported message and reboot */
|
||||
popal
|
||||
movw $.MsgCpuUnsupported, %si
|
||||
call Print
|
||||
jmp Reboot
|
||||
|
||||
FileNotFound:
|
||||
/* Display XTLDR not found message and reboot */
|
||||
movw $.MsgXtLdrNotFound, %si
|
||||
call Print
|
||||
jmp Reboot
|
||||
|
||||
Stage2NotLoaded:
|
||||
/* Clean up the stack and display XTLDR not found message and reboot */
|
||||
popl %esi
|
||||
jmp FileNotFound
|
||||
|
||||
.BootDirName:
|
||||
/* Boot directory name */
|
||||
.ascii "BOOT "
|
||||
|
||||
.EfiDirName:
|
||||
/* EFI directory name */
|
||||
.ascii "EFI "
|
||||
|
||||
.MsgCpuUnsupported:
|
||||
.ascii "CPU not supported!\r\n\0"
|
||||
|
||||
.MsgXtLdrNotFound:
|
||||
.ascii "XTLDR Stage2 not found!\r\n\0"
|
||||
|
||||
/* Fill the rest of the extra VBR with zeros and add signature */
|
||||
.fill (2043 - (. - Start)), 1, 0
|
||||
.ascii "XTLDR"
|
||||
@@ -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"
|
||||
@@ -0,0 +1,154 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: boot/bootsect/amd64/mbrboot.S
|
||||
* DESCRIPTION: XT Boot Loader MBR boot code
|
||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||
* Aiken Harris <aiken@codingworkshop.eu.org>
|
||||
*/
|
||||
|
||||
.text
|
||||
.code16
|
||||
|
||||
|
||||
.global Start
|
||||
Start:
|
||||
/* Set segments and stack */
|
||||
cli
|
||||
cld
|
||||
xorw %ax, %ax
|
||||
movw %ax, %ds
|
||||
movw %ax, %es
|
||||
movw %ax, %ss
|
||||
movw $0x7C00, %bp
|
||||
leaw -16(%bp), %sp
|
||||
sti
|
||||
|
||||
/* Relocate MBR to 1FE0:7C00 */
|
||||
movw $0x1FE0, %ax
|
||||
movw %ax, %es
|
||||
movw %bp, %si
|
||||
movw %bp, %di
|
||||
movw $256, %cx
|
||||
rep movsw
|
||||
|
||||
/* Jump to the relocated MBR code */
|
||||
jmp $0x1FE0, $RealStart
|
||||
|
||||
RealStart:
|
||||
/* Set segments */
|
||||
movw %ax, %ds
|
||||
movw %ax, %es
|
||||
movw %ax, %ss
|
||||
|
||||
/* Print welcome message */
|
||||
leaw .MsgXtosBoot, %si
|
||||
call Print
|
||||
|
||||
/* Get BIOS boot drive and partition table offset */
|
||||
lea 0x1BE(%bp), %si
|
||||
movb %dl, .BootDrive
|
||||
xorw %cx, %cx
|
||||
|
||||
FindActivePartition:
|
||||
/* Look for active partition */
|
||||
movb (%si), %al
|
||||
cmpb $0x80, %al
|
||||
je PartitionFound
|
||||
addw $16, %si
|
||||
incw %cx
|
||||
cmpw $4, %cx
|
||||
jne FindActivePartition
|
||||
jmp PartitionNotFound
|
||||
|
||||
PartitionFound:
|
||||
/* Save LBA start */
|
||||
movl 8(%si), %eax
|
||||
movl %eax, .LbaStart
|
||||
|
||||
/* Prepare Disk Address Packet (DAP) */
|
||||
lea .Dap, %si
|
||||
movb $0x10, 0(%si)
|
||||
movb $0x00, 1(%si)
|
||||
movw $1, 2(%si)
|
||||
movw $0x7C00, 4(%si)
|
||||
movw $0x0000, 6(%si)
|
||||
movl .LbaStart, %eax
|
||||
movl %eax, 8(%si)
|
||||
|
||||
/* Read Volume Boot Record (VBR) */
|
||||
movb $0x42, %ah
|
||||
movb .BootDrive, %dl
|
||||
int $0x13
|
||||
jc VbrReadFail
|
||||
|
||||
/* Verify VBR signature */
|
||||
cmpw $0xAA55, (0x7C00 + 0x01FE)
|
||||
jne InvalidSignature
|
||||
|
||||
/* Jump to the VBR code */
|
||||
jmp $0x0000, $0x7C00
|
||||
|
||||
InvalidSignature:
|
||||
/* Invalid signature error */
|
||||
leaw .MsgInvalidSignature, %si
|
||||
call Print
|
||||
jmp HaltSystem
|
||||
|
||||
PartitionNotFound:
|
||||
/* Active partition not found error */
|
||||
leaw .MsgPartitionNotFound, %si
|
||||
call Print
|
||||
jmp HaltSystem
|
||||
|
||||
VbrReadFail:
|
||||
/* VBR read failed error */
|
||||
leaw .MsgVbrReadFail, %si
|
||||
call Print
|
||||
jmp HaltSystem
|
||||
|
||||
HaltSystem:
|
||||
/* Disable interrupts and stop the CPU */
|
||||
cli
|
||||
hlt
|
||||
jmp HaltSystem
|
||||
|
||||
Print:
|
||||
/* Simple routine to print messages */
|
||||
lodsb
|
||||
orb %al, %al
|
||||
jz DonePrint
|
||||
movb $0x0E, %ah
|
||||
movw $0x07, %bx
|
||||
int $0x10
|
||||
jmp Print
|
||||
DonePrint:
|
||||
retw
|
||||
|
||||
.BootDrive:
|
||||
/* Storage for the boot drive number */
|
||||
.byte 0
|
||||
|
||||
.Dap:
|
||||
/* Storage for the Disk Address Packet (DAP) */
|
||||
.fill 16, 1, 0
|
||||
|
||||
.LbaStart:
|
||||
/* Storage for the LBA start */
|
||||
.long 0
|
||||
|
||||
.MsgInvalidSignature:
|
||||
.asciz "Invalid partition signature!"
|
||||
|
||||
.MsgPartitionNotFound:
|
||||
.asciz "Bootable partition not found!"
|
||||
|
||||
.MsgVbrReadFail:
|
||||
.asciz "VBR read failed!"
|
||||
|
||||
.MsgXtosBoot:
|
||||
.asciz "Starting XTOS boot loader...\r\n"
|
||||
|
||||
/* Fill the rest of the MBR with zeros and add MBR signature at the end */
|
||||
.fill (510 - (. - Start)), 1, 0
|
||||
.word 0xAA55
|
||||
@@ -11,23 +11,24 @@ include_directories(
|
||||
|
||||
# Specify list of library source code files
|
||||
list(APPEND LIBXTLDR_SOURCE
|
||||
${XTLDR_SOURCE_DIR}/library/modproto.c)
|
||||
${XTLDR_SOURCE_DIR}/library/modproto.cc)
|
||||
|
||||
# Specify list of source code files
|
||||
list(APPEND XTLDR_SOURCE
|
||||
${XTLDR_SOURCE_DIR}/arch/${ARCH}/memory.c
|
||||
${XTLDR_SOURCE_DIR}/config.c
|
||||
${XTLDR_SOURCE_DIR}/console.c
|
||||
${XTLDR_SOURCE_DIR}/debug.c
|
||||
${XTLDR_SOURCE_DIR}/efiutils.c
|
||||
${XTLDR_SOURCE_DIR}/globals.c
|
||||
${XTLDR_SOURCE_DIR}/hardware.c
|
||||
${XTLDR_SOURCE_DIR}/memory.c
|
||||
${XTLDR_SOURCE_DIR}/protocol.c
|
||||
${XTLDR_SOURCE_DIR}/shell.c
|
||||
${XTLDR_SOURCE_DIR}/textui.c
|
||||
${XTLDR_SOURCE_DIR}/volume.c
|
||||
${XTLDR_SOURCE_DIR}/xtldr.c)
|
||||
${XTLDR_SOURCE_DIR}/arch/${ARCH}/memory.cc
|
||||
${XTLDR_SOURCE_DIR}/biosutil.cc
|
||||
${XTLDR_SOURCE_DIR}/bootutil.cc
|
||||
${XTLDR_SOURCE_DIR}/config.cc
|
||||
${XTLDR_SOURCE_DIR}/console.cc
|
||||
${XTLDR_SOURCE_DIR}/data.cc
|
||||
${XTLDR_SOURCE_DIR}/debug.cc
|
||||
${XTLDR_SOURCE_DIR}/efiutils.cc
|
||||
${XTLDR_SOURCE_DIR}/memory.cc
|
||||
${XTLDR_SOURCE_DIR}/protocol.cc
|
||||
${XTLDR_SOURCE_DIR}/shell.cc
|
||||
${XTLDR_SOURCE_DIR}/textui.cc
|
||||
${XTLDR_SOURCE_DIR}/volume.cc
|
||||
${XTLDR_SOURCE_DIR}/xtldr.cc)
|
||||
|
||||
# Link static XTLDR library
|
||||
add_library(libxtldr ${LIBXTLDR_SOURCE})
|
||||
@@ -38,6 +39,9 @@ add_executable(xtldr ${XTLDR_SOURCE})
|
||||
# Add linker libraries
|
||||
target_link_libraries(xtldr libxtos)
|
||||
|
||||
# Add linker options
|
||||
target_link_options(xtldr PRIVATE /ALIGN:512)
|
||||
|
||||
# Set proper binary name and install target
|
||||
if(ARCH STREQUAL "i686")
|
||||
set(BINARY_NAME "bootia32")
|
||||
@@ -0,0 +1,401 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: xtldr/arch/amd64/memory.cc
|
||||
* DESCRIPTION: XT Boot Loader AMD64 specific memory management
|
||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||
* Aiken Harris <harraiken91@gmail.com>
|
||||
*/
|
||||
|
||||
#include <xtldr.hh>
|
||||
|
||||
|
||||
/**
|
||||
* Maps boot loader related code and builds page map.
|
||||
*
|
||||
* @param PageMap
|
||||
* Supplies a pointer to the page mapping structure.
|
||||
*
|
||||
* @param SelfMapAddress
|
||||
* Supplies a virtual address of the page tables.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
Memory::BuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
|
||||
IN ULONG_PTR SelfMapAddress)
|
||||
{
|
||||
PLIST_ENTRY ModulesList, ModulesListEntry;
|
||||
PXTBL_MODULE_INFO ModuleInfo;
|
||||
EFI_PHYSICAL_ADDRESS Address;
|
||||
ULONGLONG LoaderSize;
|
||||
EFI_STATUS Status;
|
||||
PVOID LoaderBase;
|
||||
|
||||
/* Allocate pages for the Page Map */
|
||||
Status = AllocatePages(AllocateAnyPages, 1, &Address);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Memory allocation failure */
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Add new memory mapping for the page map itself */
|
||||
Status = MapVirtualMemory(PageMap, (ULONGLONG)NULLPTR, Address, 1, LoaderMemoryData);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Memory mapping failure */
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Assign and zero-fill memory used by page mappings */
|
||||
PageMap->PtePointer = (PVOID)(UINT_PTR)Address;
|
||||
RTL::Memory::ZeroMemory(PageMap->PtePointer, EFI_PAGE_SIZE);
|
||||
|
||||
/* Add page mapping itself to memory mapping */
|
||||
Status = Memory::SelfMapPml(PageMap, SelfMapAddress);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* PML mapping failed */
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Map the trampoline code area */
|
||||
Status = MapVirtualMemory(PageMap, MM_TRAMPOLINE_ADDRESS, MM_TRAMPOLINE_ADDRESS,
|
||||
1, LoaderFirmwareTemporary);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Mapping trampoline code failed */
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Get list of XTLDR modules */
|
||||
ModulesList = Protocol::GetModulesList();
|
||||
ModulesListEntry = ModulesList->Flink;
|
||||
while(ModulesListEntry != ModulesList)
|
||||
{
|
||||
/* Get module info */
|
||||
ModuleInfo = CONTAIN_RECORD(ModulesListEntry, XTBL_MODULE_INFO, Flink);
|
||||
|
||||
/* Map module code */
|
||||
Status = MapVirtualMemory(PageMap, (ULONGLONG)ModuleInfo->ModuleBase, (ULONGLONG)ModuleInfo->ModuleBase,
|
||||
EFI_SIZE_TO_PAGES(ModuleInfo->ModuleSize), LoaderFirmwareTemporary);
|
||||
|
||||
/* Check if mapping succeeded */
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Mapping module code failed */
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Get next module */
|
||||
ModulesListEntry = ModulesListEntry->Flink;
|
||||
}
|
||||
|
||||
/* Get boot loader image information */
|
||||
XtLoader::GetLoaderImageInformation(&LoaderBase, &LoaderSize);
|
||||
|
||||
/* Make sure boot loader image base and size are set */
|
||||
if(LoaderBase && LoaderSize)
|
||||
{
|
||||
/* Map boot loader code as well */
|
||||
Status = MapVirtualMemory(PageMap, (ULONGLONG)LoaderBase, (ULONGLONG)LoaderBase,
|
||||
EFI_SIZE_TO_PAGES(LoaderSize), LoaderFirmwareTemporary);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Mapping boot loader code failed */
|
||||
return Status;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Boot loader image information re not available */
|
||||
return STATUS_EFI_PROTOCOL_ERROR;
|
||||
}
|
||||
|
||||
/* Return success */
|
||||
return STATUS_EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterates through the memory map and physically maps all virtual addresses to page tables.
|
||||
*
|
||||
* @param PageMap
|
||||
* Supplies a pointer to the page mapping structure.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
Memory::CommitPageMap(IN PXTBL_PAGE_MAPPING PageMap)
|
||||
{
|
||||
PXTBL_MEMORY_MAPPING Mapping;
|
||||
PLIST_ENTRY ListEntry;
|
||||
EFI_STATUS Status;
|
||||
|
||||
/* Iterate through and map all the mappings*/
|
||||
Debug::Print(L"Mapping and dumping EFI memory:\n");
|
||||
ListEntry = PageMap->MemoryMap.Flink;
|
||||
while(ListEntry != &PageMap->MemoryMap)
|
||||
{
|
||||
/* Take mapping from the list */
|
||||
Mapping = CONTAIN_RECORD(ListEntry, XTBL_MEMORY_MAPPING, ListEntry);
|
||||
|
||||
/* Check if virtual address is set */
|
||||
if(Mapping->VirtualAddress)
|
||||
{
|
||||
/* Dump memory mapping */
|
||||
Debug::Print(L" Type=%02lu, PhysicalBase=%.16P, VirtualBase=%.16P, Pages=%llu\n", Mapping->MemoryType,
|
||||
Mapping->PhysicalAddress, Mapping->VirtualAddress, Mapping->NumberOfPages);
|
||||
|
||||
/* Map memory */
|
||||
Status = MapPage(PageMap, (UINT_PTR)Mapping->VirtualAddress,
|
||||
(UINT_PTR)Mapping->PhysicalAddress, Mapping->NumberOfPages);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Memory mapping failed */
|
||||
return Status;
|
||||
}
|
||||
}
|
||||
|
||||
/* Take next element */
|
||||
ListEntry = ListEntry->Flink;
|
||||
}
|
||||
|
||||
/* Return success */
|
||||
return STATUS_EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns next level of the Page Table.
|
||||
*
|
||||
* @param PageMap
|
||||
* Supplies a pointer to the page mapping structure.
|
||||
*
|
||||
* @param PageTable
|
||||
* Supplies a pointer to the current Page Table.
|
||||
*
|
||||
* @param Entry
|
||||
* Supplies an index of the current Page Table entry.
|
||||
*
|
||||
* @param NextPageTable
|
||||
* Supplies a pointer to the memory area where the next Page Table level is returned.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
Memory::GetNextPageTable(IN PXTBL_PAGE_MAPPING PageMap,
|
||||
IN PVOID PageTable,
|
||||
IN SIZE_T Entry,
|
||||
OUT PVOID *NextPageTable)
|
||||
{
|
||||
EFI_PHYSICAL_ADDRESS Address;
|
||||
ULONGLONG PmlPointer = 0;
|
||||
PHARDWARE_PTE PmlTable;
|
||||
EFI_STATUS Status;
|
||||
|
||||
PmlTable = (PHARDWARE_PTE)PageTable;
|
||||
|
||||
/* Check if this is a valid table */
|
||||
if(PmlTable[Entry].Valid)
|
||||
{
|
||||
/* Get PML pointer */
|
||||
PmlPointer = PmlTable[Entry].PageFrameNumber;
|
||||
PmlPointer <<= EFI_PAGE_SHIFT;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Allocate pages for new PML entry */
|
||||
Status = AllocatePages(AllocateAnyPages, 1, &Address);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Memory allocation failure */
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Add new memory mapping */
|
||||
Status = MapVirtualMemory(PageMap, (ULONGLONG)NULLPTR, Address, 1, LoaderMemoryData);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Memory mapping failure */
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Fill allocated memory with zeros */
|
||||
RTL::Memory::ZeroMemory((PVOID)(ULONGLONG)Address, EFI_PAGE_SIZE);
|
||||
|
||||
/* Set paging entry settings */
|
||||
PmlTable[Entry].PageFrameNumber = Address / EFI_PAGE_SIZE;
|
||||
PmlTable[Entry].Valid = 1;
|
||||
PmlTable[Entry].Writable = 1;
|
||||
PmlPointer = (ULONGLONG)Address;
|
||||
}
|
||||
|
||||
/* Set next Page Map Level (PML) */
|
||||
*NextPageTable = (PVOID)(ULONGLONG)PmlPointer;
|
||||
|
||||
/* Return success */
|
||||
return STATUS_EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Does the actual virtual memory mapping.
|
||||
*
|
||||
* @param PageMap
|
||||
* Supplies a pointer to the page mapping structure.
|
||||
*
|
||||
* @param VirtualAddress
|
||||
* Supplies a virtual address of the mapping.
|
||||
*
|
||||
* @param PhysicalAddress
|
||||
* Supplies a physical address of the mapping.
|
||||
*
|
||||
* @param NumberOfPages
|
||||
* Supplies a number of the pages of the mapping.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
Memory::MapPage(IN PXTBL_PAGE_MAPPING PageMap,
|
||||
IN ULONGLONG VirtualAddress,
|
||||
IN ULONGLONG PhysicalAddress,
|
||||
IN ULONGLONG NumberOfPages)
|
||||
{
|
||||
PVOID Pml1, Pml2, Pml3, Pml4, Pml5;
|
||||
SIZE_T Pml1Entry, Pml2Entry, Pml3Entry, Pml4Entry, Pml5Entry;
|
||||
PHARDWARE_PTE PmlTable;
|
||||
SIZE_T PageFrameNumber;
|
||||
EFI_STATUS Status;
|
||||
|
||||
/* Set the Page Frame Number (PFN) */
|
||||
PageFrameNumber = PhysicalAddress >> EFI_PAGE_SHIFT;
|
||||
|
||||
/* Do the recursive mapping */
|
||||
while(NumberOfPages > 0)
|
||||
{
|
||||
/* Calculate the indices in the various Page Tables from the virtual address */
|
||||
Pml5Entry = (VirtualAddress & ((ULONGLONG)0x1FF << MM_P5I_SHIFT)) >> MM_P5I_SHIFT;
|
||||
Pml4Entry = (VirtualAddress & ((ULONGLONG)0x1FF << MM_PXI_SHIFT)) >> MM_PXI_SHIFT;
|
||||
Pml3Entry = (VirtualAddress & ((ULONGLONG)0x1FF << MM_PPI_SHIFT)) >> MM_PPI_SHIFT;
|
||||
Pml2Entry = (VirtualAddress & ((ULONGLONG)0x1FF << MM_PDI_SHIFT)) >> MM_PDI_SHIFT;
|
||||
Pml1Entry = (VirtualAddress & ((ULONGLONG)0x1FF << MM_PTI_SHIFT)) >> MM_PTI_SHIFT;
|
||||
|
||||
/* Check page map level */
|
||||
if(PageMap->PageMapLevel == 5)
|
||||
{
|
||||
/* Five level Page Map */
|
||||
Pml5 = PageMap->PtePointer;
|
||||
|
||||
/* Get PML4 */
|
||||
Status = GetNextPageTable(PageMap, Pml5, Pml5Entry, &Pml4);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Memory mapping failure */
|
||||
return Status;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Four level Page Map */
|
||||
Pml4 = PageMap->PtePointer;
|
||||
}
|
||||
|
||||
/* Get PML3 */
|
||||
Status = GetNextPageTable(PageMap, Pml4, Pml4Entry, &Pml3);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Memory mapping failure */
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Get PML 2 */
|
||||
Status = GetNextPageTable(PageMap, Pml3, Pml3Entry, &Pml2);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Memory mapping failure */
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Get PML1 */
|
||||
Status = GetNextPageTable(PageMap, Pml2, Pml2Entry, &Pml1);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Memory mapping failure */
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Set paging entry settings */
|
||||
PmlTable = (PHARDWARE_PTE)Pml1;
|
||||
RTL::Memory::ZeroMemory(&PmlTable[Pml1Entry], sizeof(HARDWARE_PTE));
|
||||
PmlTable[Pml1Entry].PageFrameNumber = PageFrameNumber;
|
||||
PmlTable[Pml1Entry].Valid = 1;
|
||||
PmlTable[Pml1Entry].Writable = 1;
|
||||
|
||||
/* Take next virtual address and PFN */
|
||||
VirtualAddress += EFI_PAGE_SIZE;
|
||||
PageFrameNumber++;
|
||||
|
||||
/* Decrease number of pages left */
|
||||
NumberOfPages--;
|
||||
}
|
||||
|
||||
/* Return success */
|
||||
return STATUS_EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a recursive self mapping for all PML levels.
|
||||
*
|
||||
* @param PageMap
|
||||
* Supplies a pointer to the page mapping structure.
|
||||
*
|
||||
* @param SelfMapAddress
|
||||
* Supplies a virtual address of the page tables.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
Memory::SelfMapPml(IN PXTBL_PAGE_MAPPING PageMap,
|
||||
IN ULONG_PTR SelfMapAddress)
|
||||
{
|
||||
PHARDWARE_PTE PmlBase;
|
||||
ULONGLONG PmlIndex;
|
||||
|
||||
/* Initialize PML base pointer */
|
||||
PmlBase = (PHARDWARE_PTE)PageMap->PtePointer;
|
||||
|
||||
/* Check page map level */
|
||||
if(PageMap->PageMapLevel == 5)
|
||||
{
|
||||
/* Calculate PML index based on provided self map address for PML5 */
|
||||
PmlIndex = (SelfMapAddress >> MM_P5I_SHIFT) & 0x1FF;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Calculate PML index based on provided self map address for PML4 */
|
||||
PmlIndex = (SelfMapAddress >> MM_PXI_SHIFT) & 0x1FF;
|
||||
}
|
||||
|
||||
/* Add self-mapping */
|
||||
RTL::Memory::ZeroMemory(&PmlBase[PmlIndex], sizeof(HARDWARE_PTE));
|
||||
PmlBase[PmlIndex].PageFrameNumber = (UINT_PTR)PageMap->PtePointer / EFI_PAGE_SIZE;
|
||||
PmlBase[PmlIndex].Valid = 1;
|
||||
PmlBase[PmlIndex].Writable = 1;
|
||||
|
||||
/* Return success */
|
||||
return STATUS_EFI_SUCCESS;
|
||||
}
|
||||
@@ -0,0 +1,506 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: xtldr/arch/i686/memory.cc
|
||||
* DESCRIPTION: XT Boot Loader i686 specific memory management
|
||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||
* Aiken Harris <harraiken91@gmail.com>
|
||||
*/
|
||||
|
||||
#include <xtldr.hh>
|
||||
|
||||
|
||||
/**
|
||||
* Maps boot loader related code and builds page map.
|
||||
*
|
||||
* @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::BuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
|
||||
IN ULONG_PTR SelfMapAddress)
|
||||
{
|
||||
EFI_PHYSICAL_ADDRESS Address, DirectoryAddress;
|
||||
PLIST_ENTRY ModulesList, ModulesListEntry;
|
||||
PXTBL_MODULE_INFO ModuleInfo;
|
||||
ULONGLONG LoaderSize;
|
||||
EFI_STATUS Status;
|
||||
PVOID LoaderBase;
|
||||
ULONG Index;
|
||||
|
||||
/* Check the page map level to determine which paging structure to create */
|
||||
if(PageMap->PageMapLevel == 3)
|
||||
{
|
||||
/* Allocate a page for the 3-level page map structure (PAE enabled) */
|
||||
Status = AllocatePages(AllocateAnyPages, 1, &Address);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Memory allocation failed, cannot proceed with page map creation */
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Add new memory mapping for the page map itself */
|
||||
Status = MapVirtualMemory(PageMap, (ULONGLONG)NULLPTR, Address, 1, LoaderMemoryData);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Memory mapping failure */
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Assign the allocated page to the page map and zero it out */
|
||||
PageMap->PtePointer = (PVOID)(UINT_PTR)Address;
|
||||
RTL::Memory::ZeroMemory(PageMap->PtePointer, EFI_PAGE_SIZE);
|
||||
|
||||
/* Allocate 4 pages for the Page Directories (PDs) */
|
||||
Status = AllocatePages(AllocateAnyPages, 4, &DirectoryAddress);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Memory allocation failed, cannot proceed with page map creation */
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Add new memory mapping for the Page Directories (PDs) */
|
||||
Status = MapVirtualMemory(PageMap, (ULONGLONG)NULLPTR, DirectoryAddress, 4, LoaderMemoryData);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Memory mapping failure */
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Zero-fill the allocated memory for the Page Directories */
|
||||
RTL::Memory::ZeroMemory((PVOID)DirectoryAddress, EFI_PAGE_SIZE * 4);
|
||||
|
||||
/* Fill the PDPT with pointers to the Page Directories */
|
||||
for(Index = 0; Index < 4; Index++)
|
||||
{
|
||||
RTL::Memory::ZeroMemory(&((PHARDWARE_MODERN_PTE)PageMap->PtePointer)[Index], sizeof(HARDWARE_MODERN_PTE));
|
||||
((PHARDWARE_MODERN_PTE)PageMap->PtePointer)[Index].PageFrameNumber = DirectoryAddress / EFI_PAGE_SIZE;
|
||||
((PHARDWARE_MODERN_PTE)PageMap->PtePointer)[Index].Valid = 1;
|
||||
DirectoryAddress += EFI_PAGE_SIZE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Allocate a page for the 2-level page map structure (PAE disabled) */
|
||||
Status = AllocatePages(AllocateAnyPages, 1, &Address);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Memory allocation failed, cannot proceed with page map creation */
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Add new memory mapping for the page map itself */
|
||||
Status = MapVirtualMemory(PageMap, (ULONGLONG)NULLPTR, Address, 1, LoaderMemoryData);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Memory mapping failure */
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Assign the allocated page to the page map and zero it out */
|
||||
PageMap->PtePointer = (PVOID)(UINT_PTR)Address;
|
||||
RTL::Memory::ZeroMemory(PageMap->PtePointer, EFI_PAGE_SIZE);
|
||||
}
|
||||
|
||||
/* Add page mapping itself to memory mapping */
|
||||
Status = SelfMapPml(PageMap, SelfMapAddress);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* PML mapping failed */
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Map the trampoline code area */
|
||||
Status = MapVirtualMemory(PageMap, MM_TRAMPOLINE_ADDRESS, MM_TRAMPOLINE_ADDRESS, 1, LoaderFirmwareTemporary);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Mapping trampoline code failed */
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Get list of XTLDR modules */
|
||||
ModulesList = Protocol::GetModulesList();
|
||||
ModulesListEntry = ModulesList->Flink;
|
||||
while(ModulesListEntry != ModulesList)
|
||||
{
|
||||
/* Get module info */
|
||||
ModuleInfo = CONTAIN_RECORD(ModulesListEntry, XTBL_MODULE_INFO, Flink);
|
||||
|
||||
/* Map module code */
|
||||
Status = MapVirtualMemory(PageMap, (ULONGLONG)ModuleInfo->ModuleBase, (ULONGLONG)ModuleInfo->ModuleBase,
|
||||
EFI_SIZE_TO_PAGES(ModuleInfo->ModuleSize), LoaderFirmwareTemporary);
|
||||
|
||||
/* Check if mapping succeeded */
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Mapping module code failed */
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Get next module */
|
||||
ModulesListEntry = ModulesListEntry->Flink;
|
||||
}
|
||||
|
||||
/* Get boot loader image information */
|
||||
XtLoader::GetLoaderImageInformation(&LoaderBase, &LoaderSize);
|
||||
|
||||
/* Make sure boot loader image base and size are set */
|
||||
if(LoaderBase && LoaderSize)
|
||||
{
|
||||
/* Map boot loader code as well */
|
||||
Status = MapVirtualMemory(PageMap, (ULONGLONG)LoaderBase, (ULONGLONG)LoaderBase,
|
||||
EFI_SIZE_TO_PAGES(LoaderSize), LoaderFirmwareTemporary);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Mapping boot loader code failed */
|
||||
return Status;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Boot loader image information re not available */
|
||||
return STATUS_EFI_PROTOCOL_ERROR;
|
||||
}
|
||||
|
||||
/* Return success */
|
||||
return STATUS_EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterates through the memory map and physically maps all virtual addresses to page tables.
|
||||
*
|
||||
* @param PageMap
|
||||
* Supplies a pointer to the page mapping structure.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
Memory::CommitPageMap(IN PXTBL_PAGE_MAPPING PageMap)
|
||||
{
|
||||
PXTBL_MEMORY_MAPPING Mapping;
|
||||
PLIST_ENTRY ListEntry;
|
||||
EFI_STATUS Status;
|
||||
|
||||
/* Iterate through and map all the mappings*/
|
||||
Debug::Print(L"Mapping and dumping EFI memory:\n");
|
||||
ListEntry = PageMap->MemoryMap.Flink;
|
||||
while(ListEntry != &PageMap->MemoryMap)
|
||||
{
|
||||
/* Take mapping from the list */
|
||||
Mapping = CONTAIN_RECORD(ListEntry, XTBL_MEMORY_MAPPING, ListEntry);
|
||||
|
||||
/* Check if virtual address is set */
|
||||
if(Mapping->VirtualAddress)
|
||||
{
|
||||
/* Dump memory mapping */
|
||||
Debug::Print(L" Type=%02lu, PhysicalBase=0x%.8llX, VirtualBase=0x%.8llX, Pages=%llu\n",
|
||||
Mapping->MemoryType, Mapping->PhysicalAddress,
|
||||
Mapping->VirtualAddress, Mapping->NumberOfPages);
|
||||
|
||||
/* Map memory */
|
||||
Status = MapPage(PageMap, (UINT_PTR)Mapping->VirtualAddress,
|
||||
(UINT_PTR)Mapping->PhysicalAddress, Mapping->NumberOfPages);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Memory mapping failed */
|
||||
return Status;
|
||||
}
|
||||
}
|
||||
|
||||
/* Take next element */
|
||||
ListEntry = ListEntry->Flink;
|
||||
}
|
||||
|
||||
/* Return success */
|
||||
return STATUS_EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns next level of the Page Table.
|
||||
*
|
||||
* @param PageMap
|
||||
* Supplies a pointer to the page mapping structure.
|
||||
*
|
||||
* @param PageTable
|
||||
* Supplies a pointer to the current Page Table.
|
||||
*
|
||||
* @param Entry
|
||||
* Supplies an index of the current Page Table entry.
|
||||
*
|
||||
* @param NextPageTable
|
||||
* Supplies a pointer to the memory area where the next Page Table level is returned.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
Memory::GetNextPageTable(IN PXTBL_PAGE_MAPPING PageMap,
|
||||
IN PVOID PageTable,
|
||||
IN SIZE_T Entry,
|
||||
OUT PVOID *NextPageTable)
|
||||
{
|
||||
EFI_PHYSICAL_ADDRESS Address;
|
||||
ULONGLONG PmlPointer = 0;
|
||||
EFI_STATUS Status;
|
||||
PHARDWARE_LEGACY_PTE LegacyPmlTable;
|
||||
PHARDWARE_MODERN_PTE PmlTable;
|
||||
BOOLEAN ValidPte = FALSE;
|
||||
|
||||
/* Check page map level to determine PTE size */
|
||||
if(PageMap->PageMapLevel >= 3)
|
||||
{
|
||||
/* 64-bit PTE for PML3 (PAE enabled) */
|
||||
PmlTable = (PHARDWARE_MODERN_PTE)PageTable;
|
||||
if(PmlTable[Entry].Valid)
|
||||
{
|
||||
/* Get page frame number from page table entry */
|
||||
PmlPointer = PmlTable[Entry].PageFrameNumber;
|
||||
ValidPte = TRUE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* 32-bit PTE for PML2 (PAE disabled) */
|
||||
LegacyPmlTable = (PHARDWARE_LEGACY_PTE)PageTable;
|
||||
if(LegacyPmlTable[Entry].Valid)
|
||||
{
|
||||
/* Get page frame number from page table entry */
|
||||
PmlPointer = LegacyPmlTable[Entry].PageFrameNumber;
|
||||
ValidPte = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if page table entry is valid */
|
||||
if(ValidPte)
|
||||
{
|
||||
/* Calculate the base address of the next page table */
|
||||
PmlPointer <<= EFI_PAGE_SHIFT;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Allocate pages for new PML entry */
|
||||
Status = AllocatePages(AllocateAnyPages, 1, &Address);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Memory allocation failure */
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Add new memory mapping */
|
||||
Status = MapVirtualMemory(PageMap, (ULONGLONG)NULLPTR, Address, 1, LoaderMemoryData);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Memory mapping failure */
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Fill allocated memory with zeros */
|
||||
RTL::Memory::ZeroMemory((PVOID)(ULONGLONG)Address, EFI_PAGE_SIZE);
|
||||
|
||||
/* Set paging entry settings based on level */
|
||||
if(PageMap->PageMapLevel >= 3)
|
||||
{
|
||||
/* 64-bit PTE for PML3 (PAE enabled) */
|
||||
PmlTable = (PHARDWARE_MODERN_PTE)PageTable;
|
||||
PmlTable[Entry].PageFrameNumber = Address / EFI_PAGE_SIZE;
|
||||
PmlTable[Entry].Valid = 1;
|
||||
PmlTable[Entry].Writable = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* 32-bit PTE for PML2 (PAE disabled) */
|
||||
LegacyPmlTable = (PHARDWARE_LEGACY_PTE)PageTable;
|
||||
LegacyPmlTable[Entry].PageFrameNumber = (UINT32)(Address / EFI_PAGE_SIZE);
|
||||
LegacyPmlTable[Entry].Valid = 1;
|
||||
LegacyPmlTable[Entry].Writable = 1;
|
||||
}
|
||||
|
||||
/* Return the address of the new page table */
|
||||
PmlPointer = (ULONGLONG)Address;
|
||||
}
|
||||
|
||||
/* Set next Page Map Level (PML) */
|
||||
*NextPageTable = (PVOID)(ULONGLONG)PmlPointer;
|
||||
|
||||
/* Return success */
|
||||
return STATUS_EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Does the actual virtual memory mapping.
|
||||
*
|
||||
* @param PageMap
|
||||
* Supplies a pointer to the page mapping structure.
|
||||
*
|
||||
* @param VirtualAddress
|
||||
* Supplies a virtual address of the mapping.
|
||||
*
|
||||
* @param PhysicalAddress
|
||||
* Supplies a physical address of the mapping.
|
||||
*
|
||||
* @param NumberOfPages
|
||||
* Supplies a number of the pages of the mapping.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
Memory::MapPage(IN PXTBL_PAGE_MAPPING PageMap,
|
||||
IN ULONGLONG VirtualAddress,
|
||||
IN ULONGLONG PhysicalAddress,
|
||||
IN ULONGLONG NumberOfPages)
|
||||
{
|
||||
ULONGLONG PageFrameNumber;
|
||||
PVOID Pml1, Pml2, Pml3;
|
||||
SIZE_T Pml1Entry, Pml2Entry, Pml3Entry;
|
||||
PHARDWARE_LEGACY_PTE LegacyPmlTable;
|
||||
PHARDWARE_MODERN_PTE PmlTable;
|
||||
EFI_STATUS Status;
|
||||
|
||||
/* Set the Page Frame Number (PFN) */
|
||||
PageFrameNumber = PhysicalAddress >> EFI_PAGE_SHIFT;
|
||||
|
||||
/* Map all requested pages */
|
||||
while(NumberOfPages > 0)
|
||||
{
|
||||
/* Check the paging mode to use the correct page table structure */
|
||||
if(PageMap->PageMapLevel == 3)
|
||||
{
|
||||
/* Calculate the indices for PAE page tables */
|
||||
Pml3Entry = (VirtualAddress >> 30) & 0x3;
|
||||
Pml2Entry = (VirtualAddress >> 21) & 0x1FF;
|
||||
Pml1Entry = (VirtualAddress >> 12) & 0x1FF;
|
||||
|
||||
/* Get Page Directory Pointer Table (PML3) */
|
||||
Pml3 = PageMap->PtePointer;
|
||||
|
||||
/* Get Page Directory (PML2) */
|
||||
Status = GetNextPageTable(PageMap, Pml3, Pml3Entry, &Pml2);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Failed to get the Page Table, abort mapping */
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Get Page Table (PML1) */
|
||||
Status = GetNextPageTable(PageMap, Pml2, Pml2Entry, &Pml1);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Failed to get the Page Table, abort mapping */
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Set the 64-bit PTE entry */
|
||||
PmlTable = (PHARDWARE_MODERN_PTE)Pml1;
|
||||
RTL::Memory::ZeroMemory(&PmlTable[Pml1Entry], sizeof(HARDWARE_MODERN_PTE));
|
||||
PmlTable[Pml1Entry].PageFrameNumber = PageFrameNumber;
|
||||
PmlTable[Pml1Entry].Valid = 1;
|
||||
PmlTable[Pml1Entry].Writable = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Calculate the indices for non-PAE page tables */
|
||||
Pml2Entry = (VirtualAddress >> 22) & 0x3FF;
|
||||
Pml1Entry = (VirtualAddress >> 12) & 0x3FF;
|
||||
|
||||
/* Get Page Directory (PML2) */
|
||||
Pml2 = PageMap->PtePointer;
|
||||
|
||||
/* Get Page Table (PML1) */
|
||||
Status = GetNextPageTable(PageMap, Pml2, Pml2Entry, &Pml1);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Failed to get the Page Table, abort mapping */
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Set the 32-bit PTE entry */
|
||||
LegacyPmlTable = (PHARDWARE_LEGACY_PTE)Pml1;
|
||||
RTL::Memory::ZeroMemory(&LegacyPmlTable[Pml1Entry], sizeof(HARDWARE_LEGACY_PTE));
|
||||
LegacyPmlTable[Pml1Entry].PageFrameNumber = (UINT32)PageFrameNumber;
|
||||
LegacyPmlTable[Pml1Entry].Valid = 1;
|
||||
LegacyPmlTable[Pml1Entry].Writable = 1;
|
||||
}
|
||||
|
||||
/* Take next virtual address and PFN */
|
||||
VirtualAddress += EFI_PAGE_SIZE;
|
||||
PageFrameNumber++;
|
||||
|
||||
/* Decrease number of pages left */
|
||||
NumberOfPages--;
|
||||
}
|
||||
|
||||
/* Return success */
|
||||
return STATUS_EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a recursive self mapping for all PML levels.
|
||||
*
|
||||
* @param PageMap
|
||||
* Supplies a pointer to the page mapping structure.
|
||||
*
|
||||
* @param SelfMapAddress
|
||||
* Supplies a virtual address of the page tables.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
Memory::SelfMapPml(IN PXTBL_PAGE_MAPPING PageMap,
|
||||
IN ULONG_PTR SelfMapAddress)
|
||||
{
|
||||
PHARDWARE_LEGACY_PTE LegacyPml;
|
||||
PHARDWARE_MODERN_PTE Pml;
|
||||
ULONGLONG PmlIndex;
|
||||
ULONG Index;
|
||||
|
||||
/* Check page map level */
|
||||
if(PageMap->PageMapLevel == 3)
|
||||
{
|
||||
/* Calculate PML index based on provided self map address */
|
||||
PmlIndex = (SelfMapAddress >> MM_PDI_SHIFT) & 0x1FF;
|
||||
|
||||
/* Get Page Directory */
|
||||
Pml = (PHARDWARE_MODERN_PTE)(((PHARDWARE_MODERN_PTE)PageMap->PtePointer)[SelfMapAddress >> MM_PPI_SHIFT].PageFrameNumber * EFI_PAGE_SIZE);
|
||||
|
||||
/* Add self-mapping for PML3 (PAE enabled) */
|
||||
for(Index = 0; Index < 4; Index++)
|
||||
{
|
||||
RTL::Memory::ZeroMemory(&Pml[PmlIndex + Index], sizeof(HARDWARE_MODERN_PTE));
|
||||
Pml[PmlIndex + Index].PageFrameNumber = ((PHARDWARE_MODERN_PTE)PageMap->PtePointer)[Index].PageFrameNumber;
|
||||
Pml[PmlIndex + Index].Valid = 1;
|
||||
Pml[PmlIndex + Index].Writable = 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LegacyPml = (PHARDWARE_LEGACY_PTE)PageMap->PtePointer;
|
||||
|
||||
/* Calculate PML index based on provided self map address */
|
||||
PmlIndex = (SelfMapAddress >> MM_PDI_LEGACY_SHIFT);
|
||||
|
||||
/* Add self-mapping for PML2 (PAE disabled) */
|
||||
RTL::Memory::ZeroMemory(&LegacyPml[PmlIndex], sizeof(HARDWARE_LEGACY_PTE));
|
||||
LegacyPml[PmlIndex].PageFrameNumber = (UINT_PTR)PageMap->PtePointer / EFI_PAGE_SIZE;
|
||||
LegacyPml[PmlIndex].Valid = 1;
|
||||
LegacyPml[PmlIndex].Writable = 1;
|
||||
}
|
||||
|
||||
/* Return success */
|
||||
return STATUS_EFI_SUCCESS;
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: xtldr/bootutil.cc
|
||||
* DESCRIPTION: Helper functions used by the boot protocol during system startup
|
||||
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
|
||||
*/
|
||||
|
||||
#include <xtldr.hh>
|
||||
|
||||
|
||||
/**
|
||||
* Checks if a specific option exists in the list of provided boot parameters.
|
||||
*
|
||||
* @param Parameters
|
||||
* A pointer to the wide-character string containing the boot parameters, separated by spaces.
|
||||
*
|
||||
* @param Needle
|
||||
* A pointer to the wide-character string representing the kernel option to find.
|
||||
*
|
||||
* @return This routine returns TRUE if the option is found, otherwise FALSE.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
BOOLEAN
|
||||
BootUtils::GetBooleanParameter(IN PCWSTR Parameters,
|
||||
IN PCWSTR Needle)
|
||||
{
|
||||
PCWSTR CurrentPosition, TokenEnd, TokenStart;
|
||||
SIZE_T NeedleLength, TokenLength;
|
||||
|
||||
/* Validate input data and ensure the option is not an empty string */
|
||||
if(Parameters == NULLPTR || Needle == NULLPTR || *Needle == L'\0')
|
||||
{
|
||||
/* One of the parameters was invalid */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
CurrentPosition = Parameters;
|
||||
NeedleLength = RTL::WideString::WideStringLength(Needle, 0);
|
||||
|
||||
/* Iterate through the entire parameters string */
|
||||
while(*CurrentPosition != L'\0')
|
||||
{
|
||||
/* Skip any leading whitespace to find the start of the token */
|
||||
while(*CurrentPosition == L' ')
|
||||
{
|
||||
CurrentPosition++;
|
||||
}
|
||||
|
||||
/* Check if end of the string has been reached */
|
||||
if(*CurrentPosition == L'\0')
|
||||
{
|
||||
/* End of string reached, no more tokens */
|
||||
break;
|
||||
}
|
||||
|
||||
/* Identify the boundaries of the current token */
|
||||
TokenStart = CurrentPosition;
|
||||
TokenEnd = TokenStart;
|
||||
while(*TokenEnd != L'\0' && *TokenEnd != L' ')
|
||||
{
|
||||
TokenEnd++;
|
||||
}
|
||||
|
||||
/* Calculate the length of the token found */
|
||||
TokenLength = TokenEnd - TokenStart;
|
||||
|
||||
/* Compare the token length */
|
||||
if(TokenLength == NeedleLength)
|
||||
{
|
||||
/* Length matches, compare the strings */
|
||||
if(RTL::WideString::CompareWideStringInsensitive(TokenStart, Needle, NeedleLength) == 0)
|
||||
{
|
||||
/* A match was found */
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Move the position past the current token to continue the search */
|
||||
CurrentPosition = TokenEnd;
|
||||
}
|
||||
|
||||
/* No match was found */
|
||||
return FALSE;
|
||||
}
|
||||
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
@@ -1,12 +1,12 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: xtldr/console.c
|
||||
* FILE: xtldr/console.cc
|
||||
* DESCRIPTION: EFI console support
|
||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||
*/
|
||||
|
||||
#include <xtldr.h>
|
||||
#include <xtldr.hh>
|
||||
|
||||
|
||||
/**
|
||||
@@ -21,19 +21,19 @@
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
BlClearConsoleLine(IN ULONGLONG LineNo)
|
||||
Console::ClearLine(IN ULONGLONG LineNo)
|
||||
{
|
||||
UINT_PTR Index, ResX, ResY;
|
||||
|
||||
/* Query console mode */
|
||||
BlQueryConsoleMode(&ResX, &ResY);
|
||||
QueryMode(&ResX, &ResY);
|
||||
|
||||
/* Set cursor position and clear line */
|
||||
BlSetCursorPosition(0, LineNo);
|
||||
SetCursorPosition(0, LineNo);
|
||||
for(Index = 0; Index < ResX; Index++)
|
||||
{
|
||||
/* Clear line */
|
||||
BlConsoleWrite(L" ");
|
||||
Write(L" ");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,10 +46,10 @@ BlClearConsoleLine(IN ULONGLONG LineNo)
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
BlClearConsoleScreen()
|
||||
Console::ClearScreen()
|
||||
{
|
||||
/* Clear screen */
|
||||
EfiSystemTable->ConOut->ClearScreen(EfiSystemTable->ConOut);
|
||||
XtLoader::GetEfiSystemTable()->ConOut->ClearScreen(XtLoader::GetEfiSystemTable()->ConOut);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -61,9 +61,9 @@ BlClearConsoleScreen()
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
BlDisableConsoleCursor()
|
||||
Console::DisableCursor()
|
||||
{
|
||||
EfiSystemTable->ConOut->EnableCursor(EfiSystemTable->ConOut, FALSE);
|
||||
XtLoader::GetEfiSystemTable()->ConOut->EnableCursor(XtLoader::GetEfiSystemTable()->ConOut, FALSE);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -75,9 +75,39 @@ BlDisableConsoleCursor()
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
BlEnableConsoleCursor()
|
||||
Console::EnableCursor()
|
||||
{
|
||||
EfiSystemTable->ConOut->EnableCursor(EfiSystemTable->ConOut, TRUE);
|
||||
XtLoader::GetEfiSystemTable()->ConOut->EnableCursor(XtLoader::GetEfiSystemTable()->ConOut, TRUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* This routine initializes the EFI console.
|
||||
*
|
||||
* @return This routine returns status code.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
Console::InitializeConsole()
|
||||
{
|
||||
/* Clear console buffers */
|
||||
XtLoader::GetEfiSystemTable()->ConIn->Reset(XtLoader::GetEfiSystemTable()->ConIn, TRUE);
|
||||
XtLoader::GetEfiSystemTable()->ConOut->Reset(XtLoader::GetEfiSystemTable()->ConOut, TRUE);
|
||||
XtLoader::GetEfiSystemTable()->StdErr->Reset(XtLoader::GetEfiSystemTable()->StdErr, TRUE);
|
||||
|
||||
/* Make sure that current console mode is 80x25 characters, as some broken EFI implementations might
|
||||
* set different mode that do not fit on the screen, causing a text to be displayed offscreen */
|
||||
if(XtLoader::GetEfiSystemTable()->ConOut->Mode->Mode != 0)
|
||||
{
|
||||
/* Set console mode to 0, which is standard, 80x25 text mode */
|
||||
SetMode(0);
|
||||
}
|
||||
|
||||
/* Clear screen and enable cursor */
|
||||
SetAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_LIGHTGRAY);
|
||||
ClearScreen();
|
||||
EnableCursor();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -95,30 +125,30 @@ BlEnableConsoleCursor()
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
BlConsolePrint(IN PUSHORT Format,
|
||||
Console::Print(IN PCWSTR Format,
|
||||
IN ...)
|
||||
{
|
||||
RTL_PRINT_CONTEXT ConsolePrintContext, SerialPrintContext;
|
||||
VA_LIST Arguments;
|
||||
|
||||
/* Initialise the print contexts */
|
||||
ConsolePrintContext.WriteWideCharacter = BlpConsolePutChar;
|
||||
SerialPrintContext.WriteWideCharacter = BlpDebugPutChar;
|
||||
ConsolePrintContext.WriteWideCharacter = PutChar;
|
||||
SerialPrintContext.WriteWideCharacter = Debug::PutChar;
|
||||
|
||||
/* Initialise the va_list */
|
||||
VA_START(Arguments, Format);
|
||||
|
||||
/* Format and print the string to the stdout */
|
||||
RtlFormatWideString(&ConsolePrintContext, (PWCHAR)Format, Arguments);
|
||||
RTL::WideString::FormatWideString(&ConsolePrintContext, (PWCHAR)Format, Arguments);
|
||||
|
||||
/* Print to serial console only if not running under OVMF */
|
||||
if(RtlCompareWideString(EfiSystemTable->FirmwareVendor, L"EDK II", 6) != 0)
|
||||
if(RTL::WideString::CompareWideString(XtLoader::GetEfiSystemTable()->FirmwareVendor, L"EDK II", 6) != 0)
|
||||
{
|
||||
/* Check if debugging enabled and if EFI serial port is fully initialized */
|
||||
if(DEBUG && (BlpStatus.SerialPort.Flags & COMPORT_FLAG_INIT))
|
||||
if(DEBUG && Debug::SerialPortReady())
|
||||
{
|
||||
/* Format and print the string to the serial console */
|
||||
RtlFormatWideString(&SerialPrintContext, (PWCHAR)Format, Arguments);
|
||||
RTL::WideString::FormatWideString(&SerialPrintContext, (PWCHAR)Format, Arguments);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -127,50 +157,35 @@ BlConsolePrint(IN PUSHORT Format,
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays the string on the device at the current cursor location.
|
||||
* Writes a character to the default EFI console.
|
||||
*
|
||||
* @param String
|
||||
* The string to be displayed.
|
||||
* @param Character
|
||||
* The integer promotion of the character to be written.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
* @return This routine returns a status code.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
BlConsoleWrite(IN PUSHORT String)
|
||||
XTSTATUS
|
||||
Console::PutChar(IN WCHAR Character)
|
||||
{
|
||||
EfiSystemTable->ConOut->OutputString(EfiSystemTable->ConOut, String);
|
||||
}
|
||||
WCHAR Buffer[2];
|
||||
|
||||
/**
|
||||
* This routine initializes the EFI console.
|
||||
*
|
||||
* @return This routine returns status code.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
BlInitializeConsole()
|
||||
{
|
||||
/* Clear console buffers */
|
||||
EfiSystemTable->ConIn->Reset(EfiSystemTable->ConIn, TRUE);
|
||||
EfiSystemTable->ConOut->Reset(EfiSystemTable->ConOut, TRUE);
|
||||
EfiSystemTable->StdErr->Reset(EfiSystemTable->StdErr, TRUE);
|
||||
|
||||
/* Make sure that current console mode is 80x25 characters, as some broken EFI implementations might
|
||||
* set different mode that do not fit on the screen, causing a text to be displayed offscreen */
|
||||
if(EfiSystemTable->ConOut->Mode->Mode != 0)
|
||||
/* Check if character is a newline ('\n') */
|
||||
if(Character == L'\n')
|
||||
{
|
||||
/* Set console mode to 0, which is standard, 80x25 text mode */
|
||||
BlSetConsoleMode(0);
|
||||
/* Print carriage return ('\r') as well */
|
||||
PutChar(L'\r');
|
||||
}
|
||||
|
||||
/* Clear screen and enable cursor */
|
||||
BlSetConsoleAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_LIGHTGRAY);
|
||||
BlClearConsoleScreen();
|
||||
BlEnableConsoleCursor();
|
||||
/* Write character to the screen console */
|
||||
Buffer[0] = Character;
|
||||
Buffer[1] = 0;
|
||||
XtLoader::GetEfiSystemTable()->ConOut->OutputString(XtLoader::GetEfiSystemTable()->ConOut, Buffer);
|
||||
|
||||
/* Return success */
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -188,10 +203,11 @@ BlInitializeConsole()
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
BlQueryConsoleMode(OUT PUINT_PTR ResX,
|
||||
Console::QueryMode(OUT PUINT_PTR ResX,
|
||||
OUT PUINT_PTR ResY)
|
||||
{
|
||||
EfiSystemTable->ConOut->QueryMode(EfiSystemTable->ConOut, EfiSystemTable->ConOut->Mode->Mode, ResX, ResY);
|
||||
XtLoader::GetEfiSystemTable()->ConOut->QueryMode(XtLoader::GetEfiSystemTable()->ConOut,
|
||||
XtLoader::GetEfiSystemTable()->ConOut->Mode->Mode, ResX, ResY);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -205,10 +221,15 @@ BlQueryConsoleMode(OUT PUINT_PTR ResX,
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
BlReadKeyStroke(OUT PEFI_INPUT_KEY Key)
|
||||
EFI_STATUS
|
||||
Console::ReadKeyStroke(OUT PEFI_INPUT_KEY Key)
|
||||
{
|
||||
EfiSystemTable->ConIn->ReadKeyStroke(EfiSystemTable->ConIn, Key);
|
||||
/* Clear the key structure to prevent ghost keystrokes */
|
||||
Key->ScanCode = 0;
|
||||
Key->UnicodeChar = 0;
|
||||
|
||||
/* Read the keystroke from the EFI input console */
|
||||
return XtLoader::GetEfiSystemTable()->ConIn->ReadKeyStroke(XtLoader::GetEfiSystemTable()->ConIn, Key);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -220,9 +241,9 @@ BlReadKeyStroke(OUT PEFI_INPUT_KEY Key)
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
BlResetConsoleInputBuffer()
|
||||
Console::ResetInputBuffer()
|
||||
{
|
||||
EfiSystemTable->ConIn->Reset(EfiSystemTable->ConIn, FALSE);
|
||||
XtLoader::GetEfiSystemTable()->ConIn->Reset(XtLoader::GetEfiSystemTable()->ConIn, FALSE);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -237,26 +258,9 @@ BlResetConsoleInputBuffer()
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
BlSetConsoleAttributes(IN ULONGLONG Attributes)
|
||||
Console::SetAttributes(IN ULONGLONG Attributes)
|
||||
{
|
||||
EfiSystemTable->ConOut->SetAttribute(EfiSystemTable->ConOut, Attributes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the output console device to the requested mode.
|
||||
*
|
||||
* @param Mode
|
||||
* Supplies a text mode number to set.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlSetConsoleMode(IN ULONGLONG Mode)
|
||||
{
|
||||
return EfiSystemTable->ConOut->SetMode(EfiSystemTable->ConOut, Mode);
|
||||
XtLoader::GetEfiSystemTable()->ConOut->SetAttribute(XtLoader::GetEfiSystemTable()->ConOut, Attributes);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -274,40 +278,42 @@ BlSetConsoleMode(IN ULONGLONG Mode)
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
BlSetCursorPosition(IN ULONGLONG PosX,
|
||||
IN ULONGLONG PosY)
|
||||
Console::SetCursorPosition(IN ULONGLONG PosX,
|
||||
IN ULONGLONG PosY)
|
||||
{
|
||||
EfiSystemTable->ConOut->SetCursorPosition(EfiSystemTable->ConOut, PosX, PosY);
|
||||
XtLoader::GetEfiSystemTable()->ConOut->SetCursorPosition(XtLoader::GetEfiSystemTable()->ConOut, PosX, PosY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a character to the default EFI console.
|
||||
* Sets the output console device to the requested mode.
|
||||
*
|
||||
* @param Character
|
||||
* The integer promotion of the character to be written.
|
||||
* @param Mode
|
||||
* Supplies a text mode number to set.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
XTSTATUS
|
||||
BlpConsolePutChar(IN USHORT Character)
|
||||
EFI_STATUS
|
||||
Console::SetMode(IN ULONGLONG Mode)
|
||||
{
|
||||
USHORT Buffer[2];
|
||||
return XtLoader::GetEfiSystemTable()->ConOut->SetMode(XtLoader::GetEfiSystemTable()->ConOut, Mode);
|
||||
}
|
||||
|
||||
/* Check if character is a newline ('\n') */
|
||||
if(Character == L'\n')
|
||||
{
|
||||
/* Print carriage return ('\r') as well */
|
||||
BlpConsolePutChar(L'\r');
|
||||
}
|
||||
|
||||
/* Write character to the screen console */
|
||||
Buffer[0] = Character;
|
||||
Buffer[1] = 0;
|
||||
EfiSystemTable->ConOut->OutputString(EfiSystemTable->ConOut, Buffer);
|
||||
|
||||
/* Return success */
|
||||
return STATUS_SUCCESS;
|
||||
/**
|
||||
* Displays the string on the device at the current cursor location.
|
||||
*
|
||||
* @param String
|
||||
* The string to be displayed.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
Console::Write(IN PCWSTR String)
|
||||
{
|
||||
XtLoader::GetEfiSystemTable()->ConOut->OutputString(XtLoader::GetEfiSystemTable()->ConOut, (PWSTR)String);
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: xtldr/data.cc
|
||||
* DESCRIPTION: XT Boot Loader global and static data
|
||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||
* Aiken Harris <harraiken91@gmail.com>
|
||||
*/
|
||||
|
||||
#include <xtldr.hh>
|
||||
|
||||
|
||||
/* Legacy BIOS cursor X position */
|
||||
USHORT BiosUtils::CursorX = 0;
|
||||
|
||||
/* Legacy BIOS cursor Y position */
|
||||
USHORT BiosUtils::CursorY = 0;
|
||||
|
||||
/* Legacy BIOS screen height */
|
||||
CONST USHORT BiosUtils::VgaHeight = 25;
|
||||
|
||||
/* Legacy BIOS screen width */
|
||||
CONST USHORT BiosUtils::VgaWidth = 80;
|
||||
|
||||
/* XT Boot Loader menu list */
|
||||
PLIST_ENTRY Configuration::BootMenuList = NULLPTR;
|
||||
|
||||
/* XT Boot Loader configuration list */
|
||||
LIST_ENTRY Configuration::Config;
|
||||
|
||||
/* XT Boot Loader loaded configuration */
|
||||
LIST_ENTRY Configuration::ConfigSections;
|
||||
|
||||
/* List of user-editable boot options */
|
||||
PCWSTR Configuration::EditableConfigOptions[] = {
|
||||
L"BootModules", L"SystemType", L"SystemPath",
|
||||
L"KernelFile", L"InitrdFile", L"HalFile",
|
||||
L"Parameters", NULLPTR
|
||||
};
|
||||
|
||||
/* XT Boot Loader serial ports list */
|
||||
ULONG Debug::ComPortList[COMPORT_COUNT] = COMPORT_ADDRESS;
|
||||
|
||||
/* A list of enabled debug ports */
|
||||
ULONG Debug::EnabledDebugPorts;
|
||||
|
||||
/* XT Boot Loader serial port handle */
|
||||
CPPORT Debug::SerialPort;
|
||||
|
||||
/* XT Boot Loader registered boot protocol list */
|
||||
LIST_ENTRY Protocol::BootProtocols;
|
||||
|
||||
/* XT Boot Loader protocol */
|
||||
XTBL_LOADER_PROTOCOL Protocol::LoaderProtocol;
|
||||
|
||||
/* XT Boot Loader loaded modules list */
|
||||
LIST_ENTRY Protocol::LoadedModules;
|
||||
|
||||
/* XT Boot Loader shell exit flag */
|
||||
BOOLEAN Shell::ExitRequest;
|
||||
|
||||
/* XT Boot Loader shell history buffer */
|
||||
WCHAR Shell::History[XTBL_SH_HISTORY_ENTRIES][XTBL_SH_MAX_LINE_LENGTH];
|
||||
|
||||
/* XT Boot Loader shell history count */
|
||||
ULONG Shell::HistoryCount = 0;
|
||||
|
||||
/* XT Boot Loader shell history index */
|
||||
ULONG Shell::HistoryIndex = 0;
|
||||
|
||||
/* XT Boot Loader shell commands list */
|
||||
LIST_ENTRY Shell::ShellCommands;
|
||||
|
||||
/* List of available block devices */
|
||||
LIST_ENTRY Volume::EfiBlockDevices;
|
||||
|
||||
/* Pointer to the boot menu callback routine */
|
||||
PBL_XT_BOOT_MENU XtLoader::BootMenu = NULLPTR;
|
||||
|
||||
/* EFI Image Handle */
|
||||
EFI_HANDLE XtLoader::EfiImageHandle;
|
||||
|
||||
/* EFI System Table */
|
||||
PEFI_SYSTEM_TABLE XtLoader::EfiSystemTable;
|
||||
|
||||
/* XT Boot Loader status data */
|
||||
XTBL_STATUS XtLoader::LoaderStatus = {0};
|
||||
@@ -0,0 +1,402 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: xtldr/debug.cc
|
||||
* DESCRIPTION: XT Boot Loader debugging support
|
||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||
*/
|
||||
|
||||
#include <xtldr.hh>
|
||||
|
||||
|
||||
/**
|
||||
* Enables I/O space access to all serial controllers found on the PCI(E) root bridge.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
Debug::ActivateSerialIOController()
|
||||
{
|
||||
EFI_GUID PciGuid = EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_GUID;
|
||||
PEFI_PCI_ROOT_BRIDGE_IO_PROTOCOL PciDev;
|
||||
USHORT Bus, Device, Function, Command;
|
||||
UINT_PTR Index, PciHandleSize;
|
||||
PEFI_HANDLE PciHandle = NULLPTR;
|
||||
PCI_COMMON_HEADER PciHeader;
|
||||
EFI_STATUS Status;
|
||||
ULONGLONG Address;
|
||||
|
||||
/* Allocate memory for single EFI_HANDLE, what should be enough in most cases */
|
||||
PciHandleSize = sizeof(EFI_HANDLE);
|
||||
Status = Memory::AllocatePool(PciHandleSize, (PVOID*)&PciHandle);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Memory allocation failure */
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Get all instances of PciRootBridgeIo */
|
||||
Status = XtLoader::GetEfiSystemTable()->BootServices->LocateHandle(ByProtocol, &PciGuid, NULLPTR,
|
||||
&PciHandleSize, PciHandle);
|
||||
if(Status == STATUS_EFI_BUFFER_TOO_SMALL)
|
||||
{
|
||||
/* Reallocate more memory as requested by UEFI */
|
||||
Memory::FreePool(PciHandle);
|
||||
Status = Memory::AllocatePool(PciHandleSize, (PVOID*)&PciHandle);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Memory reallocation failure */
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Second attempt to get instances of PciRootBridgeIo */
|
||||
Status = XtLoader::GetEfiSystemTable()->BootServices->LocateHandle(ByProtocol, &PciGuid, NULLPTR,
|
||||
&PciHandleSize, PciHandle);
|
||||
}
|
||||
|
||||
/* Make sure successfully obtained PciRootBridgeIo instances */
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Failed to get PciRootBridgeIo instances */
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Enumerate all devices for each handle, which decides a segment and a bus number range */
|
||||
for(Index = 0; Index < (PciHandleSize / sizeof(EFI_HANDLE)); Index++)
|
||||
{
|
||||
/* Get inferface from the protocol */
|
||||
Status = XtLoader::GetEfiSystemTable()->BootServices->HandleProtocol(PciHandle[Index], &PciGuid, (PVOID*)&PciDev);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Failed to get interface */
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Enumerate whole PCI bridge */
|
||||
for(Bus = 0; Bus <= PCI_MAX_BRIDGE_NUMBER; Bus++)
|
||||
{
|
||||
/* Enumerate all devices for each bus */
|
||||
for(Device = 0; Device < PCI_MAX_DEVICES; Device++)
|
||||
{
|
||||
/* Enumerate all functions for each devices */
|
||||
for(Function = 0; Function < PCI_MAX_FUNCTION; Function++)
|
||||
{
|
||||
/* Read configuration space */
|
||||
Address = ((ULONGLONG)((((UINT_PTR) Bus) << 24) + (((UINT_PTR) Device) << 16) +
|
||||
(((UINT_PTR) Function) << 8) + ((UINT_PTR) 0)));
|
||||
PciDev->Pci.Read(PciDev, EfiPciIoWidthUint32, Address, sizeof (PciHeader) / sizeof (UINT), &PciHeader);
|
||||
|
||||
/* Check if device exists */
|
||||
if(PciHeader.VendorId == PCI_INVALID_VENDORID)
|
||||
{
|
||||
/* Skip non-existen device */
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Check if device is serial controller or multiport serial controller */
|
||||
if(PciHeader.BaseClass == 0x07 && (PciHeader.SubClass == 0x00 || PciHeader.SubClass == 0x02))
|
||||
{
|
||||
/* Enable I/O space access */
|
||||
Address |= 0x4;
|
||||
Command = PCI_ENABLE_IO_SPACE;
|
||||
Status = PciDev->Pci.Write(PciDev, EfiPciIoWidthUint16, Address, 1, &Command);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Return SUCCESS */
|
||||
return STATUS_EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* This routine initializes the XTLDR debug console.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
Debug::InitializeDebugConsole()
|
||||
{
|
||||
ULONG PortAddress, PortNumber, BaudRate;
|
||||
PWCHAR DebugConfiguration, DebugPort, LastPort;
|
||||
EFI_STATUS Status;
|
||||
|
||||
/* Set default serial port options */
|
||||
PortAddress = 0;
|
||||
PortNumber = 0;
|
||||
BaudRate = 0;
|
||||
|
||||
/* Get debug configuration */
|
||||
Configuration::GetValue(L"DEBUG", &DebugConfiguration);
|
||||
|
||||
/* Make sure any debug options are provided and debug console is not initialized yet */
|
||||
if(DebugConfiguration && EnabledDebugPorts == 0)
|
||||
{
|
||||
/* Find all debug ports */
|
||||
DebugPort = RTL::WideString::TokenizeWideString(DebugConfiguration, L";", &LastPort);
|
||||
|
||||
/* Iterate over all debug ports */
|
||||
while(DebugPort != NULLPTR)
|
||||
{
|
||||
/* Check what port is set for debugging */
|
||||
if(RTL::WideString::CompareWideStringInsensitive(DebugPort, L"COM", 3) == 0)
|
||||
{
|
||||
/* Read COM port number */
|
||||
DebugPort += 3;
|
||||
while(*DebugPort >= '0' && *DebugPort <= '9')
|
||||
{
|
||||
/* Get port number */
|
||||
PortNumber *= 10;
|
||||
PortNumber += *DebugPort - '0';
|
||||
DebugPort++;
|
||||
}
|
||||
|
||||
/* Check if custom COM port address supplied */
|
||||
if(PortNumber == 0 && RTL::WideString::CompareWideStringInsensitive(DebugPort, L":0x", 3) == 0)
|
||||
{
|
||||
/* COM port address provided */
|
||||
DebugPort += 3;
|
||||
while((*DebugPort >= '0' && *DebugPort <= '9') ||
|
||||
(*DebugPort >= 'A' && *DebugPort <= 'F') ||
|
||||
(*DebugPort >= 'a' && *DebugPort <= 'f'))
|
||||
{
|
||||
/* Get port address */
|
||||
PortAddress *= 16;
|
||||
if(*DebugPort >= '0' && *DebugPort <= '9')
|
||||
{
|
||||
PortAddress += *DebugPort - '0';
|
||||
}
|
||||
else if(*DebugPort >= 'A' && *DebugPort <= 'F')
|
||||
{
|
||||
PortAddress += *DebugPort - 'A' + 10;
|
||||
}
|
||||
else if(*DebugPort >= 'a' && *DebugPort <= 'f')
|
||||
{
|
||||
PortAddress += *DebugPort - 'a' + 10;
|
||||
}
|
||||
DebugPort++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Look for additional COM port parameters */
|
||||
if(*DebugPort == ',')
|
||||
{
|
||||
/* Baud rate provided */
|
||||
DebugPort++;
|
||||
while(*DebugPort >= '0' && *DebugPort <= '9')
|
||||
{
|
||||
/* Get baud rate */
|
||||
BaudRate *= 10;
|
||||
BaudRate += *DebugPort - '0';
|
||||
DebugPort++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Enable debug port */
|
||||
EnabledDebugPorts |= XTBL_DEBUGPORT_SERIAL;
|
||||
}
|
||||
else if(RTL::WideString::CompareWideStringInsensitive(DebugPort, L"SCREEN", 5) == 0)
|
||||
{
|
||||
/* Enable debug port */
|
||||
EnabledDebugPorts |= XTBL_DEBUGPORT_SCREEN;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Unsupported debug port specified */
|
||||
Console::Print(L"ERROR: Unsupported debug port ('%S') specified\n", DebugPort);
|
||||
EfiUtils::SleepExecution(3000);
|
||||
}
|
||||
|
||||
/* Take next debug port */
|
||||
DebugPort = RTL::WideString::TokenizeWideString(NULLPTR, L";", &LastPort);
|
||||
}
|
||||
|
||||
/* Check if serial debug port is enabled */
|
||||
if(EnabledDebugPorts & XTBL_DEBUGPORT_SERIAL)
|
||||
{
|
||||
/* Try to initialize COM port */
|
||||
Status = InitializeSerialPort(PortNumber, PortAddress, BaudRate);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Remove serial debug port, as COM port initialization failed and return */
|
||||
EnabledDebugPorts &= ~XTBL_DEBUGPORT_SERIAL;
|
||||
return Status;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Return success */
|
||||
return STATUS_EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* This routine initializes the serial debug console.
|
||||
*
|
||||
* @param PortNumber
|
||||
* Supplies a port number.
|
||||
*
|
||||
* @param PortAddress
|
||||
* Supplies an address of the COM port.
|
||||
*
|
||||
* @param BaudRate
|
||||
* Supplies an optional port baud rate.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
Debug::InitializeSerialPort(IN ULONG PortNumber,
|
||||
IN ULONG PortAddress,
|
||||
IN ULONG BaudRate)
|
||||
{
|
||||
EFI_STATUS EfiStatus;
|
||||
XTSTATUS Status;
|
||||
|
||||
/* Check if custom COM port address supplied */
|
||||
if(!PortAddress)
|
||||
{
|
||||
/* We support only a pre-defined number of ports */
|
||||
if(PortNumber > COMPORT_COUNT)
|
||||
{
|
||||
/* Fail if wrong/unsupported port used */
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
/* Check if serial port is set */
|
||||
if(PortNumber == 0)
|
||||
{
|
||||
/* Use COM1 by default */
|
||||
PortNumber = 1;
|
||||
}
|
||||
|
||||
/* Set custom port address based on the port number and print debug message */
|
||||
PortAddress = ComPortList[PortNumber - 1];
|
||||
Console::Print(L"Initializing serial console at port COM%d\n", PortNumber);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Custom port address supplied, print debug message */
|
||||
Console::Print(L"Initializing serial console at COM port address: 0x%lX\n", PortAddress);
|
||||
}
|
||||
|
||||
/* Initialize COM port */
|
||||
Status = HL::ComPort::InitializeComPort(&SerialPort, (PUCHAR)UlongToPtr(PortAddress), BaudRate);
|
||||
|
||||
/* Port not found under supplied address */
|
||||
if(Status == STATUS_NOT_FOUND && PortAddress)
|
||||
{
|
||||
/* This might be PCI(E) serial controller, try to activate I/O space access first */
|
||||
EfiStatus = ActivateSerialIOController();
|
||||
if(EfiStatus == STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Try to reinitialize COM port */
|
||||
Console::Print(L"Enabled I/O space access for all PCI(E) serial controllers found\n");
|
||||
Status = HL::ComPort::InitializeComPort(&SerialPort, (PUCHAR)UlongToPtr(PortAddress), BaudRate);
|
||||
}
|
||||
}
|
||||
|
||||
/* Check COM port initialization status code */
|
||||
if(Status != STATUS_SUCCESS)
|
||||
{
|
||||
/* Serial port initialization failed, mark as not ready */
|
||||
return STATUS_EFI_NOT_READY;
|
||||
}
|
||||
|
||||
/* Return success */
|
||||
return STATUS_EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* This routine formats the input string and prints it out to the debug ports.
|
||||
*
|
||||
* @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
|
||||
Debug::Print(IN PCWSTR Format,
|
||||
IN ...)
|
||||
{
|
||||
RTL_PRINT_CONTEXT ConsolePrintContext, SerialPrintContext;
|
||||
VA_LIST Arguments;
|
||||
|
||||
/* Check if debugging enabled and if EFI serial port is fully initialized */
|
||||
if(DEBUG)
|
||||
{
|
||||
/* Initialize the print contexts */
|
||||
ConsolePrintContext.WriteWideCharacter = Console::PutChar;
|
||||
SerialPrintContext.WriteWideCharacter = PutChar;
|
||||
|
||||
/* Initialise the va_list */
|
||||
VA_START(Arguments, Format);
|
||||
|
||||
/* Check if serial debug port is enabled */
|
||||
if((EnabledDebugPorts & XTBL_DEBUGPORT_SERIAL) && (SerialPort.Flags & COMPORT_FLAG_INIT))
|
||||
{
|
||||
/* Format and print the string to the serial console */
|
||||
RTL::WideString::FormatWideString(&SerialPrintContext, (PWCHAR)Format, Arguments);
|
||||
}
|
||||
|
||||
/* Check if screen debug port is enabled and Boot Services are still available */
|
||||
if((EnabledDebugPorts & XTBL_DEBUGPORT_SCREEN) && (XtLoader::GetBootServicesStatus() == TRUE))
|
||||
{
|
||||
/* Format and print the string to the screen */
|
||||
RTL::WideString::FormatWideString(&ConsolePrintContext, (PWCHAR)Format, Arguments);
|
||||
}
|
||||
|
||||
/* Clean up the va_list */
|
||||
VA_END(Arguments);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a character to the serial console.
|
||||
*
|
||||
* @param Character
|
||||
* The integer promotion of the character to be written.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
XTSTATUS
|
||||
Debug::PutChar(IN WCHAR Character)
|
||||
{
|
||||
WCHAR Buffer[2];
|
||||
|
||||
/* Write character to the serial console */
|
||||
Buffer[0] = Character;
|
||||
Buffer[1] = 0;
|
||||
return HL::ComPort::WriteComPort(&SerialPort, Buffer[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if the serial port has been successfully initialized and is ready for communication.
|
||||
*
|
||||
* @return This routine returns TRUE if the serial port is initialized and ready, FALSE otherwise.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
BOOLEAN
|
||||
Debug::SerialPortReady()
|
||||
{
|
||||
return (SerialPort.Flags & COMPORT_FLAG_INIT);
|
||||
}
|
||||
@@ -1,12 +1,12 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: xtldr/efiutils.c
|
||||
* FILE: xtldr/efiutils.cc
|
||||
* DESCRIPTION: EFI related routines for XT Boot Loader
|
||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||
*/
|
||||
|
||||
#include <xtldr.h>
|
||||
#include <xtldr.hh>
|
||||
|
||||
|
||||
/**
|
||||
@@ -18,29 +18,35 @@
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlEnterFirmwareSetup()
|
||||
EfiUtils::EnterFirmwareSetup()
|
||||
{
|
||||
EFI_GUID Guid = EFI_GLOBAL_VARIABLE_GUID;
|
||||
PULONGLONG SetupSupport;
|
||||
PULONGLONG SetupSupport = NULLPTR;
|
||||
ULONGLONG Indications;
|
||||
EFI_STATUS Status;
|
||||
|
||||
/* Check if booting into firmware interface is supported */
|
||||
Status = BlGetEfiVariable(&Guid, L"OsIndicationsSupported", (PVOID*)&SetupSupport);
|
||||
Status = GetEfiVariable(&Guid, L"OsIndicationsSupported", (PVOID*)&SetupSupport);
|
||||
if(Status != STATUS_EFI_SUCCESS || !(*SetupSupport & EFI_OS_INDICATIONS_BOOT_TO_FW_UI))
|
||||
{
|
||||
/* Reboot into firmware setup is not supported */
|
||||
BlDebugPrint(L"WARNING: Reboot into firmware setup interface not supported\n");
|
||||
Debug::Print(L"WARNING: Reboot into firmware setup interface not supported\n");
|
||||
if(SetupSupport)
|
||||
{
|
||||
Memory::FreePool((PVOID)SetupSupport);
|
||||
}
|
||||
return STATUS_EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
Memory::FreePool((PVOID)SetupSupport);
|
||||
|
||||
/* Get the value of OsIndications variable */
|
||||
Indications = 0;
|
||||
Status = BlGetEfiVariable(&Guid, L"OsIndications", (PVOID)&Indications);
|
||||
Status = GetEfiVariable(&Guid, L"OsIndications", (PVOID*)&Indications);
|
||||
|
||||
/* Enable FW setup on next boot */
|
||||
Indications |= EFI_OS_INDICATIONS_BOOT_TO_FW_UI;
|
||||
Status = BlSetEfiVariable(&Guid, L"OsIndications", (PVOID)&Indications, sizeof(Indications));
|
||||
Status = SetEfiVariable(&Guid, L"OsIndications", (PVOID)&Indications, sizeof(Indications));
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Failed to update OsIndications variable */
|
||||
@@ -48,7 +54,7 @@ BlEnterFirmwareSetup()
|
||||
}
|
||||
|
||||
/* Reboot into firmware setup */
|
||||
BlRebootSystem();
|
||||
RebootSystem();
|
||||
|
||||
/* Must not reach this point, just make the compiler happy */
|
||||
return STATUS_EFI_SUCCESS;
|
||||
@@ -63,33 +69,33 @@ BlEnterFirmwareSetup()
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlExitBootServices()
|
||||
EfiUtils::ExitBootServices()
|
||||
{
|
||||
PEFI_MEMORY_MAP MemoryMap;
|
||||
EFI_STATUS Status;
|
||||
ULONG Counter;
|
||||
|
||||
/* Boot Services might be partially shutdown, so mark them as unavailable */
|
||||
BlpStatus.BootServices = FALSE;
|
||||
XtLoader::DisableBootServices();
|
||||
|
||||
/* Allocate buffer for EFI memory map */
|
||||
Status = BlAllocateMemoryPool(sizeof(EFI_MEMORY_MAP), (PVOID*)&MemoryMap);
|
||||
Status = Memory::AllocatePool(sizeof(EFI_MEMORY_MAP), (PVOID*)&MemoryMap);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Memory allocation failure */
|
||||
BlDebugPrint(L"ERROR: Memory allocation failure (Status Code: 0x%zX)\n", Status);
|
||||
Debug::Print(L"ERROR: Memory allocation failure (Status Code: 0x%zX)\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Zero fill the buffer and initialize counter */
|
||||
RtlZeroMemory(MemoryMap, sizeof(EFI_MEMORY_MAP));
|
||||
RTL::Memory::ZeroMemory(MemoryMap, sizeof(EFI_MEMORY_MAP));
|
||||
Counter = 0xFF;
|
||||
|
||||
/* Attempt to exit boot services */
|
||||
while(Counter > 0)
|
||||
{
|
||||
/* Get memory map each time as it can change between two calls */
|
||||
Status = BlGetMemoryMap(MemoryMap);
|
||||
Status = Memory::GetMemoryMap(MemoryMap);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Failed to get new memory map */
|
||||
@@ -97,7 +103,8 @@ BlExitBootServices()
|
||||
}
|
||||
|
||||
/* Exit boot services */
|
||||
Status = EfiSystemTable->BootServices->ExitBootServices(EfiImageHandle, MemoryMap->MapKey);
|
||||
Status = XtLoader::GetEfiSystemTable()->BootServices->ExitBootServices(XtLoader::GetEfiImageHandle(),
|
||||
MemoryMap->MapKey);
|
||||
if(Status == STATUS_EFI_SUCCESS)
|
||||
{
|
||||
break;
|
||||
@@ -126,25 +133,26 @@ BlExitBootServices()
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlGetConfigurationTable(IN PEFI_GUID TableGuid,
|
||||
OUT PVOID *Table)
|
||||
EfiUtils::GetConfigurationTable(IN PEFI_GUID TableGuid,
|
||||
OUT PVOID *Table)
|
||||
{
|
||||
SIZE_T Index;
|
||||
|
||||
/* Iterate through all system configuration tables */
|
||||
for(Index = 0; Index < EfiSystemTable->NumberOfTableEntries; Index++)
|
||||
for(Index = 0; Index < XtLoader::GetEfiSystemTable()->NumberOfTableEntries; Index++)
|
||||
{
|
||||
/* Check if this table matches requested table */
|
||||
if(RtlCompareGuids((PGUID)&(EfiSystemTable->ConfigurationTable[Index].VendorGuid), (PGUID)TableGuid))
|
||||
if(RTL::Guid::CompareGuids((PGUID)&(XtLoader::GetEfiSystemTable()->ConfigurationTable[Index].VendorGuid),
|
||||
(PGUID)TableGuid))
|
||||
{
|
||||
/* Found requested table, return success */
|
||||
*Table = EfiSystemTable->ConfigurationTable[Index].VendorTable;
|
||||
*Table = XtLoader::GetEfiSystemTable()->ConfigurationTable[Index].VendorTable;
|
||||
return STATUS_EFI_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
/* Table not found */
|
||||
*Table = NULL;
|
||||
*Table = NULLPTR;
|
||||
return STATUS_EFI_NOT_FOUND;
|
||||
}
|
||||
|
||||
@@ -166,17 +174,17 @@ BlGetConfigurationTable(IN PEFI_GUID TableGuid,
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlGetEfiVariable(IN PEFI_GUID Vendor,
|
||||
IN PWCHAR VariableName,
|
||||
OUT PVOID *VariableValue)
|
||||
EfiUtils::GetEfiVariable(IN PEFI_GUID Vendor,
|
||||
IN PCWSTR VariableName,
|
||||
OUT PVOID *VariableValue)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
PVOID Buffer;
|
||||
UINT_PTR Size;
|
||||
UINT_PTR Size = 0;
|
||||
|
||||
/* Allocate a buffer for storing a variable's value */
|
||||
Size = EFI_MAXIMUM_VARIABLE_SIZE * sizeof(PWCHAR);
|
||||
Status = BlAllocateMemoryPool(Size, (PVOID*)&Buffer);
|
||||
Status = Memory::AllocatePool(Size, (PVOID*)&Buffer);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Memory allocation failure */
|
||||
@@ -184,7 +192,8 @@ BlGetEfiVariable(IN PEFI_GUID Vendor,
|
||||
}
|
||||
|
||||
/* Attempt to get variable value */
|
||||
Status = EfiSystemTable->RuntimeServices->GetVariable(VariableName, Vendor, NULL, &Size, Buffer);
|
||||
Status = XtLoader::GetEfiSystemTable()->RuntimeServices->GetVariable((PWCHAR)VariableName, Vendor, NULLPTR,
|
||||
&Size, Buffer);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Failed to get variable, probably not found such one */
|
||||
@@ -210,7 +219,7 @@ BlGetEfiVariable(IN PEFI_GUID Vendor,
|
||||
*/
|
||||
XTCDECL
|
||||
ULONGLONG
|
||||
BlGetRandomValue(IN OUT PULONGLONG RNGBuffer)
|
||||
EfiUtils::GetRandomValue(IN OUT PULONGLONG RNGBuffer)
|
||||
{
|
||||
/* Recalculate RNG buffer with XORSHIFT */
|
||||
*RNGBuffer ^= *RNGBuffer >> 12;
|
||||
@@ -230,21 +239,21 @@ BlGetRandomValue(IN OUT PULONGLONG RNGBuffer)
|
||||
*/
|
||||
XTCDECL
|
||||
INT_PTR
|
||||
BlGetSecureBootStatus()
|
||||
EfiUtils::GetSecureBootStatus()
|
||||
{
|
||||
EFI_GUID VarGuid = EFI_GLOBAL_VARIABLE_GUID;
|
||||
INT_PTR SecureBootStatus = 0;
|
||||
UCHAR VarValue = 0;
|
||||
INT_PTR VarValue = 0;
|
||||
UINT_PTR Size;
|
||||
|
||||
Size = sizeof(VarValue);
|
||||
if(EfiSystemTable->RuntimeServices->GetVariable(L"SecureBoot", &VarGuid,
|
||||
NULL, &Size, &VarValue) == STATUS_EFI_SUCCESS)
|
||||
Size = sizeof(INT_PTR);
|
||||
if(XtLoader::GetEfiSystemTable()->RuntimeServices->GetVariable((PWCHAR)L"SecureBoot", &VarGuid,
|
||||
NULLPTR, &Size, &VarValue) == STATUS_EFI_SUCCESS)
|
||||
{
|
||||
SecureBootStatus = (INT_PTR)VarValue;
|
||||
|
||||
if((EfiSystemTable->RuntimeServices->GetVariable(L"SetupMode", &VarGuid,
|
||||
NULL, &Size, &VarValue) == STATUS_EFI_SUCCESS) && VarValue != 0)
|
||||
SecureBootStatus = VarValue;
|
||||
Size = sizeof(INT_PTR);
|
||||
if((XtLoader::GetEfiSystemTable()->RuntimeServices->GetVariable((PWCHAR)L"SetupMode", &VarGuid,
|
||||
NULLPTR, &Size, &VarValue) == STATUS_EFI_SUCCESS) && VarValue != 0)
|
||||
{
|
||||
SecureBootStatus = -1;
|
||||
}
|
||||
@@ -266,7 +275,7 @@ BlGetSecureBootStatus()
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlInitializeEntropy(PULONGLONG RNGBuffer)
|
||||
EfiUtils::InitializeEntropy(PULONGLONG RNGBuffer)
|
||||
{
|
||||
EFI_GUID RngGuid = EFI_RNG_PROTOCOL_GUID;
|
||||
PEFI_RNG_PROTOCOL Rng;
|
||||
@@ -274,11 +283,11 @@ BlInitializeEntropy(PULONGLONG RNGBuffer)
|
||||
ULONGLONG Seed;
|
||||
|
||||
/* Initialize variables */
|
||||
Rng = NULL;
|
||||
Rng = NULLPTR;
|
||||
Seed = 0;
|
||||
|
||||
/* Locate RNG protocol */
|
||||
Status = EfiSystemTable->BootServices->LocateProtocol(&RngGuid, NULL, (PVOID *)&Rng);
|
||||
Status = XtLoader::GetEfiSystemTable()->BootServices->LocateProtocol(&RngGuid, NULLPTR, (PVOID *)&Rng);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Failed to locate RNG protocol, return status code */
|
||||
@@ -286,7 +295,7 @@ BlInitializeEntropy(PULONGLONG RNGBuffer)
|
||||
}
|
||||
|
||||
/* Get RNG value using the default algorithm */
|
||||
Status = Rng->GetRNG(Rng, NULL, 8, (PUCHAR)&Seed);
|
||||
Status = Rng->GetRNG(Rng, NULLPTR, 8, (PUCHAR)&Seed);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Failed to get RNG value, return status code */
|
||||
@@ -319,13 +328,14 @@ BlInitializeEntropy(PULONGLONG RNGBuffer)
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlLoadEfiImage(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath,
|
||||
IN PVOID ImageData,
|
||||
IN SIZE_T ImageSize,
|
||||
OUT PEFI_HANDLE ImageHandle)
|
||||
EfiUtils::LoadEfiImage(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath,
|
||||
IN PVOID ImageData,
|
||||
IN SIZE_T ImageSize,
|
||||
OUT PEFI_HANDLE ImageHandle)
|
||||
{
|
||||
/* Load EFI image */
|
||||
return EfiSystemTable->BootServices->LoadImage(FALSE, EfiImageHandle, DevicePath, ImageData, ImageSize, ImageHandle);
|
||||
return XtLoader::GetEfiSystemTable()->BootServices->LoadImage(FALSE, XtLoader::GetEfiImageHandle(), DevicePath,
|
||||
ImageData, ImageSize, ImageHandle);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -337,10 +347,10 @@ BlLoadEfiImage(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath,
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlRebootSystem()
|
||||
EfiUtils::RebootSystem()
|
||||
{
|
||||
/* Reboot machine */
|
||||
return EfiSystemTable->RuntimeServices->ResetSystem(EfiResetCold, STATUS_EFI_SUCCESS, 0, NULL);
|
||||
return XtLoader::GetEfiSystemTable()->RuntimeServices->ResetSystem(EfiResetCold, STATUS_EFI_SUCCESS, 0, NULLPTR);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -364,16 +374,17 @@ BlRebootSystem()
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlSetEfiVariable(IN PEFI_GUID Vendor,
|
||||
IN PWCHAR VariableName,
|
||||
IN PVOID VariableValue,
|
||||
IN UINT_PTR Size)
|
||||
EfiUtils::SetEfiVariable(IN PEFI_GUID Vendor,
|
||||
IN PCWSTR VariableName,
|
||||
IN PVOID VariableValue,
|
||||
IN UINT_PTR Size)
|
||||
{
|
||||
ULONG Attributes;
|
||||
|
||||
/* Set EFI variable */
|
||||
Attributes = EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS;
|
||||
return EfiSystemTable->RuntimeServices->SetVariable(VariableName, Vendor, Attributes, Size, VariableValue);
|
||||
return XtLoader::GetEfiSystemTable()->RuntimeServices->SetVariable((PWCHAR)VariableName, Vendor, Attributes,
|
||||
Size, VariableValue);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -385,10 +396,10 @@ BlSetEfiVariable(IN PEFI_GUID Vendor,
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlShutdownSystem()
|
||||
EfiUtils::ShutdownSystem()
|
||||
{
|
||||
/* Shutdown machine */
|
||||
return EfiSystemTable->RuntimeServices->ResetSystem(EfiResetShutdown, STATUS_EFI_SUCCESS, 0, NULL);
|
||||
return XtLoader::GetEfiSystemTable()->RuntimeServices->ResetSystem(EfiResetShutdown, STATUS_EFI_SUCCESS, 0, NULLPTR);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -403,9 +414,9 @@ BlShutdownSystem()
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
BlSleepExecution(IN ULONG_PTR Milliseconds)
|
||||
EfiUtils::SleepExecution(IN ULONG_PTR Milliseconds)
|
||||
{
|
||||
EfiSystemTable->BootServices->Stall(Milliseconds * 1000);
|
||||
XtLoader::GetEfiSystemTable()->BootServices->Stall(Milliseconds * 1000);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -420,9 +431,9 @@ BlSleepExecution(IN ULONG_PTR Milliseconds)
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlStartEfiImage(IN EFI_HANDLE ImageHandle)
|
||||
EfiUtils::StartEfiImage(IN EFI_HANDLE ImageHandle)
|
||||
{
|
||||
return EfiSystemTable->BootServices->StartImage(ImageHandle, NULL, NULL);
|
||||
return XtLoader::GetEfiSystemTable()->BootServices->StartImage(ImageHandle, NULLPTR, NULLPTR);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -443,9 +454,9 @@ BlStartEfiImage(IN EFI_HANDLE ImageHandle)
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlWaitForEfiEvent(IN UINT_PTR NumberOfEvents,
|
||||
IN PEFI_EVENT Event,
|
||||
OUT PUINT_PTR Index)
|
||||
EfiUtils::WaitForEfiEvent(IN UINT_PTR NumberOfEvents,
|
||||
IN PEFI_EVENT Event,
|
||||
OUT PUINT_PTR Index)
|
||||
{
|
||||
return EfiSystemTable->BootServices->WaitForEvent(NumberOfEvents, Event, Index);
|
||||
return XtLoader::GetEfiSystemTable()->BootServices->WaitForEvent(NumberOfEvents, Event, Index);
|
||||
}
|
||||
@@ -0,0 +1,142 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: xtldr/includes/libxtos.hh
|
||||
* DESCRIPTION: XT Loader to LIBXTOS interface
|
||||
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef __XTLDR_LIBXTOS_HH
|
||||
#define __XTLDR_LIBXTOS_HH
|
||||
|
||||
#include <xtblapi.h>
|
||||
|
||||
|
||||
/* Minimal forward references for AR classes used by XTLDR */
|
||||
namespace AR
|
||||
{
|
||||
class CpuFunctions
|
||||
{
|
||||
public:
|
||||
STATIC XTCDECL BOOLEAN CpuId(IN OUT PCPUID_REGISTERS Registers);
|
||||
STATIC XTCDECL ULONG_PTR ReadControlRegister(IN USHORT ControlRegister);
|
||||
STATIC XTCDECL ULONGLONG ReadModelSpecificRegister(IN ULONG Register);
|
||||
STATIC XTCDECL VOID WriteControlRegister(IN USHORT ControlRegister,
|
||||
IN UINT_PTR Value);
|
||||
};
|
||||
|
||||
class ProcessorSupport
|
||||
{
|
||||
public:
|
||||
STATIC XTAPI VOID GetTrampolineInformation(IN TRAMPOLINE_TYPE TrampolineType,
|
||||
OUT PVOID *TrampolineCode,
|
||||
OUT PULONG TrampolineSize);
|
||||
};
|
||||
}
|
||||
|
||||
/* Minimal forward references for HL classes used by XTLDR */
|
||||
namespace HL
|
||||
{
|
||||
class ComPort
|
||||
{
|
||||
public:
|
||||
STATIC XTCDECL XTSTATUS InitializeComPort(IN OUT PCPPORT Port,
|
||||
IN PUCHAR PortAddress,
|
||||
IN ULONG BaudRate);
|
||||
STATIC XTCDECL XTSTATUS WriteComPort(IN PCPPORT Port,
|
||||
IN UCHAR Byte);
|
||||
};
|
||||
|
||||
class IoPort
|
||||
{
|
||||
public:
|
||||
STATIC XTCDECL UCHAR ReadPort8(IN USHORT Port);
|
||||
STATIC XTCDECL USHORT ReadPort16(IN USHORT Port);
|
||||
STATIC XTCDECL ULONG ReadPort32(IN USHORT Port);
|
||||
STATIC XTCDECL VOID WritePort8(IN USHORT Port,
|
||||
IN UCHAR Value);
|
||||
STATIC XTCDECL VOID WritePort16(IN USHORT Port,
|
||||
IN USHORT Value);
|
||||
STATIC XTCDECL VOID WritePort32(IN USHORT Port,
|
||||
IN ULONG Value);
|
||||
};
|
||||
}
|
||||
|
||||
/* Minimal forward references for RTL classes used by XTLDR */
|
||||
namespace RTL
|
||||
{
|
||||
class Guid
|
||||
{
|
||||
public:
|
||||
STATIC XTAPI BOOLEAN CompareGuids(IN PGUID Guid1,
|
||||
IN PGUID Guid2);
|
||||
};
|
||||
|
||||
class LinkedList
|
||||
{
|
||||
public:
|
||||
STATIC XTCDECL VOID InitializeListHead(IN PLIST_ENTRY ListHead);
|
||||
STATIC XTCDECL VOID InsertHeadList(IN OUT PLIST_ENTRY ListHead,
|
||||
IN PLIST_ENTRY Entry);
|
||||
STATIC XTCDECL VOID InsertTailList(IN OUT PLIST_ENTRY ListHead,
|
||||
IN PLIST_ENTRY Entry);
|
||||
STATIC XTCDECL VOID RemoveEntryList(IN PLIST_ENTRY Entry);
|
||||
};
|
||||
|
||||
class Memory
|
||||
{
|
||||
public:
|
||||
STATIC XTAPI SIZE_T CompareMemory(IN PCVOID LeftBuffer,
|
||||
IN PCVOID RightBuffer,
|
||||
IN SIZE_T Length);
|
||||
STATIC XTAPI VOID CopyMemory(OUT PVOID Destination,
|
||||
IN PCVOID Source,
|
||||
IN SIZE_T Length);
|
||||
STATIC XTAPI VOID MoveMemory(OUT PVOID Destination,
|
||||
IN PCVOID Source,
|
||||
IN SIZE_T Length);
|
||||
STATIC XTAPI VOID SetMemory(OUT PVOID Destination,
|
||||
IN UCHAR Byte,
|
||||
IN SIZE_T Length);
|
||||
STATIC XTAPI VOID ZeroMemory(OUT PVOID Destination,
|
||||
IN SIZE_T Length);
|
||||
};
|
||||
|
||||
class String
|
||||
{
|
||||
public:
|
||||
STATIC XTAPI LONG CompareString(IN PCSTR String1,
|
||||
IN PCSTR String2,
|
||||
IN SIZE_T Length);
|
||||
STATIC XTAPI SIZE_T StringLength(IN PCSTR String,
|
||||
IN SIZE_T MaxLength);
|
||||
STATIC XTAPI SIZE_T StringToWideString(OUT PWCHAR Destination,
|
||||
IN PCSTR *Source,
|
||||
IN SIZE_T Length);
|
||||
STATIC XTAPI PCHAR TrimString(IN PCHAR String);
|
||||
};
|
||||
|
||||
class WideString
|
||||
{
|
||||
public:
|
||||
STATIC XTAPI LONG CompareWideString(IN PCWSTR String1,
|
||||
IN PCWSTR String2,
|
||||
IN SIZE_T Length);
|
||||
STATIC XTAPI LONG CompareWideStringInsensitive(IN PCWSTR String1,
|
||||
IN PCWSTR String2,
|
||||
IN SIZE_T Length);
|
||||
STATIC XTAPI PWCHAR ConcatenateWideString(OUT PWCHAR Destination,
|
||||
IN PWCHAR Source,
|
||||
IN SIZE_T Count);
|
||||
STATIC XTAPI XTSTATUS FormatWideString(IN PRTL_PRINT_CONTEXT Context,
|
||||
IN PCWSTR Format,
|
||||
IN VA_LIST ArgumentList);
|
||||
STATIC XTAPI PWCHAR TokenizeWideString(IN PWCHAR String,
|
||||
IN PCWSTR Delimiter,
|
||||
IN OUT PWCHAR *SavePtr);
|
||||
STATIC XTAPI SIZE_T WideStringLength(IN PCWSTR String,
|
||||
IN SIZE_T MaxLength);
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* __XTLDR_LIBXTOS_HH */
|
||||
@@ -0,0 +1,409 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: xtldr/includes/xtldr.hh
|
||||
* DESCRIPTION: Top level header for XTLDR
|
||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||
*/
|
||||
|
||||
#ifndef __XTLDR_XTLDR_HH
|
||||
#define __XTLDR_XTLDR_HH
|
||||
|
||||
#include <xtblapi.h>
|
||||
#include <xtver.h>
|
||||
|
||||
#include <libxtos.hh>
|
||||
|
||||
|
||||
class BiosUtils
|
||||
{
|
||||
private:
|
||||
STATIC USHORT CursorX;
|
||||
STATIC USHORT CursorY;
|
||||
STATIC CONST USHORT VgaHeight;
|
||||
STATIC CONST USHORT VgaWidth;
|
||||
|
||||
public:
|
||||
STATIC XTCDECL VOID ClearScreen();
|
||||
STATIC XTCDECL VOID Print(IN PCWSTR Format,
|
||||
IN ...);
|
||||
STATIC XTCDECL XTSTATUS PutChar(IN WCHAR Character);
|
||||
|
||||
private:
|
||||
STATIC XTCDECL VOID ScrollScreen();
|
||||
STATIC XTCDECL VOID UpdateCursor();
|
||||
};
|
||||
|
||||
class BootUtils
|
||||
{
|
||||
public:
|
||||
STATIC XTCDECL BOOLEAN GetBooleanParameter(IN PCWSTR Parameters,
|
||||
IN PCWSTR Needle);
|
||||
};
|
||||
|
||||
class Configuration
|
||||
{
|
||||
private:
|
||||
STATIC PLIST_ENTRY BootMenuList;
|
||||
STATIC LIST_ENTRY Config;
|
||||
STATIC LIST_ENTRY ConfigSections;
|
||||
STATIC PCWSTR EditableConfigOptions[];
|
||||
|
||||
public:
|
||||
STATIC XTCDECL BOOLEAN GetBooleanValue(IN PCWSTR ConfigName);
|
||||
STATIC XTCDECL EFI_STATUS GetBootOptionValue(IN PLIST_ENTRY Options,
|
||||
IN PCWSTR OptionName,
|
||||
OUT PWCHAR *OptionValue);
|
||||
STATIC XTCDECL VOID GetEditableOptions(OUT PCWSTR **OptionsArray,
|
||||
OUT PULONG OptionsCount);
|
||||
STATIC XTCDECL EFI_STATUS GetValue(IN PCWSTR ConfigName,
|
||||
OUT PWCHAR *ConfigValue);
|
||||
STATIC XTCDECL EFI_STATUS InitializeBootMenuList(IN ULONG MaxNameLength,
|
||||
OUT PXTBL_BOOTMENU_ITEM *MenuEntries,
|
||||
OUT PULONG EntriesCount,
|
||||
OUT PULONG DefaultId);
|
||||
STATIC XTCDECL VOID InitializeConfiguration();
|
||||
STATIC XTCDECL EFI_STATUS LoadConfiguration();
|
||||
STATIC XTCDECL EFI_STATUS ParseCommandLine();
|
||||
STATIC XTCDECL EFI_STATUS SetBootOptionValue(IN PLIST_ENTRY Options,
|
||||
IN PCWSTR OptionName,
|
||||
IN PCWSTR OptionValue);
|
||||
|
||||
private:
|
||||
STATIC XTCDECL EFI_STATUS ParseConfigFile(IN CONST PCHAR RawConfig,
|
||||
OUT PLIST_ENTRY Configuration);
|
||||
STATIC XTCDECL EFI_STATUS ReadConfigFile(IN PCWSTR ConfigDirectory,
|
||||
IN PCWSTR ConfigFile,
|
||||
OUT PCHAR *ConfigData);
|
||||
STATIC XTCDECL EFI_STATUS SetValue(IN PCWSTR ConfigName,
|
||||
IN PCWSTR ConfigValue);
|
||||
STATIC XTCDECL VOID UpdateConfiguration(IN PLIST_ENTRY NewConfig);
|
||||
};
|
||||
|
||||
class Console
|
||||
{
|
||||
public:
|
||||
STATIC XTCDECL VOID ClearLine(IN ULONGLONG LineNo);
|
||||
STATIC XTCDECL VOID ClearScreen();
|
||||
STATIC XTCDECL VOID DisableCursor();
|
||||
STATIC XTCDECL VOID EnableCursor();
|
||||
STATIC XTCDECL VOID InitializeConsole();
|
||||
STATIC XTCDECL VOID Print(IN PCWSTR Format,
|
||||
IN ...);
|
||||
STATIC XTCDECL XTSTATUS PutChar(IN WCHAR Character);
|
||||
STATIC XTCDECL VOID QueryMode(OUT PUINT_PTR ResX,
|
||||
OUT PUINT_PTR ResY);
|
||||
STATIC XTCDECL EFI_STATUS ReadKeyStroke(OUT PEFI_INPUT_KEY Key);
|
||||
STATIC XTCDECL VOID ResetInputBuffer();
|
||||
STATIC XTCDECL VOID SetAttributes(IN ULONGLONG Attributes);
|
||||
STATIC XTCDECL VOID SetCursorPosition(IN ULONGLONG PosX,
|
||||
IN ULONGLONG PosY);
|
||||
STATIC XTCDECL VOID Write(IN PCWSTR String);
|
||||
|
||||
private:
|
||||
STATIC XTCDECL EFI_STATUS SetMode(IN ULONGLONG Mode);
|
||||
};
|
||||
|
||||
class Debug
|
||||
{
|
||||
private:
|
||||
STATIC ULONG ComPortList[COMPORT_COUNT];
|
||||
STATIC ULONG EnabledDebugPorts;
|
||||
STATIC CPPORT SerialPort;
|
||||
|
||||
public:
|
||||
STATIC XTCDECL EFI_STATUS InitializeDebugConsole();
|
||||
STATIC XTCDECL VOID Print(IN PCWSTR Format,
|
||||
IN ...);
|
||||
STATIC XTCDECL XTSTATUS PutChar(IN WCHAR Character);
|
||||
STATIC XTCDECL BOOLEAN SerialPortReady();
|
||||
|
||||
private:
|
||||
STATIC XTCDECL EFI_STATUS ActivateSerialIOController();
|
||||
STATIC XTCDECL EFI_STATUS InitializeSerialPort(IN ULONG PortNumber,
|
||||
IN ULONG PortAddress,
|
||||
IN ULONG BaudRate);
|
||||
};
|
||||
|
||||
class EfiUtils
|
||||
{
|
||||
public:
|
||||
STATIC XTCDECL EFI_STATUS EnterFirmwareSetup();
|
||||
STATIC XTCDECL EFI_STATUS ExitBootServices();
|
||||
STATIC XTCDECL EFI_STATUS GetConfigurationTable(IN PEFI_GUID TableGuid,
|
||||
OUT PVOID *Table);
|
||||
STATIC XTCDECL EFI_STATUS GetEfiVariable(IN PEFI_GUID Vendor,
|
||||
IN PCWSTR VariableName,
|
||||
OUT PVOID *VariableValue);
|
||||
STATIC XTCDECL ULONGLONG GetRandomValue(IN OUT PULONGLONG RNGBuffer);
|
||||
STATIC XTCDECL INT_PTR GetSecureBootStatus();
|
||||
STATIC XTCDECL EFI_STATUS InitializeEntropy(PULONGLONG RNGBuffer);
|
||||
STATIC XTCDECL EFI_STATUS LoadEfiImage(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath,
|
||||
IN PVOID ImageData,
|
||||
IN SIZE_T ImageSize,
|
||||
OUT PEFI_HANDLE ImageHandle);
|
||||
STATIC XTCDECL EFI_STATUS RebootSystem();
|
||||
STATIC XTCDECL EFI_STATUS SetEfiVariable(IN PEFI_GUID Vendor,
|
||||
IN PCWSTR VariableName,
|
||||
IN PVOID VariableValue,
|
||||
IN UINT_PTR Size);
|
||||
STATIC XTCDECL EFI_STATUS ShutdownSystem();
|
||||
STATIC XTCDECL VOID SleepExecution(IN ULONG_PTR Milliseconds);
|
||||
STATIC XTCDECL EFI_STATUS StartEfiImage(IN EFI_HANDLE ImageHandle);
|
||||
STATIC XTCDECL EFI_STATUS WaitForEfiEvent(IN UINT_PTR NumberOfEvents,
|
||||
IN PEFI_EVENT Event,
|
||||
OUT PUINT_PTR Index);
|
||||
};
|
||||
|
||||
class Memory
|
||||
{
|
||||
public:
|
||||
STATIC XTCDECL EFI_STATUS AllocatePages(IN EFI_ALLOCATE_TYPE AllocationType,
|
||||
IN ULONGLONG NumberOfPages,
|
||||
OUT PEFI_PHYSICAL_ADDRESS Memory);
|
||||
STATIC XTCDECL EFI_STATUS AllocatePool(IN UINT_PTR Size,
|
||||
OUT PVOID *Memory);
|
||||
STATIC XTCDECL EFI_STATUS BuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
|
||||
IN ULONG_PTR SelfMapAddress);
|
||||
STATIC XTCDECL EFI_STATUS CommitPageMap(IN PXTBL_PAGE_MAPPING PageMap);
|
||||
STATIC XTCDECL EFI_STATUS FreePages(IN ULONGLONG NumberOfPages,
|
||||
IN EFI_PHYSICAL_ADDRESS Memory);
|
||||
STATIC XTCDECL EFI_STATUS FreePool(IN PVOID Memory);
|
||||
STATIC XTCDECL VOID GetMappingsCount(IN PXTBL_PAGE_MAPPING PageMap,
|
||||
OUT PULONG NumberOfMappings);
|
||||
STATIC XTCDECL EFI_STATUS GetMemoryMap(OUT PEFI_MEMORY_MAP MemoryMap);
|
||||
STATIC XTCDECL PVOID GetVirtualAddress(IN PXTBL_PAGE_MAPPING PageMap,
|
||||
IN PVOID PhysicalAddress);
|
||||
STATIC XTCDECL VOID InitializePageMap(OUT PXTBL_PAGE_MAPPING PageMap,
|
||||
IN SHORT PageMapLevel,
|
||||
IN PAGE_SIZE PageSize);
|
||||
STATIC XTCDECL EFI_STATUS MapEfiMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
|
||||
IN OUT PVOID *BaseAddress,
|
||||
IN BOOLEAN IdentityMapping,
|
||||
IN PBL_GET_MEMTYPE_ROUTINE GetMemoryTypeRoutine);
|
||||
STATIC XTCDECL EFI_STATUS MapPage(IN PXTBL_PAGE_MAPPING PageMap,
|
||||
IN ULONGLONG VirtualAddress,
|
||||
IN ULONGLONG PhysicalAddress,
|
||||
IN ULONGLONG NumberOfPages);
|
||||
STATIC XTCDECL EFI_STATUS MapVirtualMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
|
||||
IN ULONGLONG VirtualAddress,
|
||||
IN ULONGLONG PhysicalAddress,
|
||||
IN ULONGLONG NumberOfPages,
|
||||
IN LOADER_MEMORY_TYPE MemoryType);
|
||||
STATIC XTCDECL PVOID PhysicalAddressToVirtual(IN PVOID PhysicalAddress,
|
||||
IN PVOID PhysicalBase,
|
||||
IN PVOID VirtualBase);
|
||||
STATIC XTCDECL EFI_STATUS PhysicalListToVirtual(IN PXTBL_PAGE_MAPPING PageMap,
|
||||
IN OUT PLIST_ENTRY ListHead,
|
||||
IN PVOID PhysicalBase,
|
||||
IN PVOID VirtualBase);
|
||||
|
||||
private:
|
||||
STATIC XTCDECL LOADER_MEMORY_TYPE GetLoaderMemoryType(IN EFI_MEMORY_TYPE EfiMemoryType);
|
||||
STATIC XTCDECL EFI_STATUS GetNextPageTable(IN PXTBL_PAGE_MAPPING PageMap,
|
||||
IN PVOID PageTable,
|
||||
IN SIZE_T Entry,
|
||||
OUT PVOID *NextPageTable);
|
||||
STATIC XTCDECL EFI_STATUS SelfMapPml(IN PXTBL_PAGE_MAPPING PageMap,
|
||||
IN ULONG_PTR SelfMapAddress);
|
||||
};
|
||||
|
||||
class Protocol
|
||||
{
|
||||
private:
|
||||
STATIC LIST_ENTRY BootProtocols;
|
||||
STATIC XTBL_LOADER_PROTOCOL LoaderProtocol;
|
||||
STATIC LIST_ENTRY LoadedModules;
|
||||
|
||||
public:
|
||||
STATIC XTCDECL EFI_STATUS CloseProtocol(IN PEFI_HANDLE Handle,
|
||||
IN PEFI_GUID ProtocolGuid);
|
||||
STATIC XTCDECL EFI_STATUS FindBootProtocol(IN PCWSTR SystemType,
|
||||
OUT PEFI_GUID BootProtocolGuid);
|
||||
STATIC XTCDECL PLIST_ENTRY GetModulesList();
|
||||
STATIC XTCDECL EFI_STATUS InstallProtocol(IN PVOID Interface,
|
||||
IN PEFI_GUID Guid);
|
||||
STATIC XTCDECL VOID InitializeProtocol();
|
||||
STATIC XTCDECL EFI_STATUS InvokeBootProtocol(IN PWCHAR ShortName,
|
||||
IN PLIST_ENTRY OptionsList);
|
||||
STATIC XTCDECL EFI_STATUS LoadModule(IN PWCHAR ModuleName);
|
||||
STATIC XTCDECL EFI_STATUS LoadModules(IN PWCHAR ModulesList);
|
||||
STATIC XTCDECL EFI_STATUS LocateProtocolHandles(OUT PEFI_HANDLE *Handles,
|
||||
OUT PUINT_PTR Count,
|
||||
IN PEFI_GUID ProtocolGuid);
|
||||
STATIC XTCDECL EFI_STATUS OpenProtocol(OUT PEFI_HANDLE Handle,
|
||||
OUT PVOID *ProtocolHandler,
|
||||
IN PEFI_GUID ProtocolGuid);
|
||||
STATIC XTCDECL EFI_STATUS OpenProtocolHandle(IN EFI_HANDLE Handle,
|
||||
OUT PVOID *ProtocolHandler,
|
||||
IN PEFI_GUID ProtocolGuid);
|
||||
STATIC XTCDECL EFI_STATUS RegisterBootProtocol(IN PCWSTR SystemType,
|
||||
IN PEFI_GUID BootProtocolGuid);
|
||||
STATIC XTCDECL EFI_STATUS InstallXtLoaderProtocol();
|
||||
|
||||
private:
|
||||
STATIC XTCDECL EFI_STATUS GetModuleInformation(IN PWCHAR SectionData,
|
||||
IN ULONG SectionSize,
|
||||
OUT PXTBL_MODULE_INFO ModuleInfo);
|
||||
STATIC XTCDECL EFI_STATUS GetModuleInfoStrings(IN PWCHAR SectionData,
|
||||
IN ULONG SectionSize,
|
||||
OUT PWCHAR **ModInfo,
|
||||
OUT PULONG InfoCount);
|
||||
};
|
||||
|
||||
class Shell
|
||||
{
|
||||
private:
|
||||
STATIC BOOLEAN ExitRequest;
|
||||
STATIC WCHAR History[XTBL_SH_HISTORY_ENTRIES][XTBL_SH_MAX_LINE_LENGTH];
|
||||
STATIC ULONG HistoryCount;
|
||||
STATIC ULONG HistoryIndex;
|
||||
STATIC LIST_ENTRY ShellCommands;
|
||||
|
||||
public:
|
||||
STATIC XTCDECL VOID InitializeShell();
|
||||
STATIC XTCDECL EFI_STATUS RegisterCommand(IN PCWSTR Command,
|
||||
IN PCWSTR Description,
|
||||
IN PBL_SHELL_COMMAND Handler);
|
||||
STATIC XTCDECL VOID StartLoaderShell();
|
||||
|
||||
private:
|
||||
STATIC XTCDECL VOID CommandExit(IN ULONG Argc,
|
||||
IN PWCHAR *Argv);
|
||||
STATIC XTCDECL VOID CommandHelp(IN ULONG Argc,
|
||||
IN PWCHAR *Argv);
|
||||
STATIC XTCDECL VOID CommandInsmod(IN ULONG Argc,
|
||||
IN PWCHAR *Argv);
|
||||
STATIC XTCDECL VOID CommandLsmod(IN ULONG Argc,
|
||||
IN PWCHAR *Argv);
|
||||
STATIC XTCDECL VOID CommandPoweroff(IN ULONG Argc,
|
||||
IN PWCHAR *Argv);
|
||||
STATIC XTCDECL VOID CommandReboot(IN ULONG Argc,
|
||||
IN PWCHAR *Argv);
|
||||
STATIC XTCDECL VOID CommandVersion(IN ULONG Argc,
|
||||
IN PWCHAR *Argv);
|
||||
STATIC XTCDECL VOID ExecuteCommand(IN ULONG Argc,
|
||||
IN PWCHAR *Argv);
|
||||
STATIC XTCDECL EFI_STATUS ParseCommand(IN PWCHAR CommandLine,
|
||||
OUT PULONG Argc,
|
||||
OUT PWCHAR **Argv);
|
||||
STATIC XTCDECL VOID PrintPrompt();
|
||||
STATIC XTCDECL VOID PrintPromptLine(IN PWCHAR Buffer,
|
||||
IN ULONG BufferLength,
|
||||
IN ULONG CursorPosition,
|
||||
IN ULONG PreviousBufferLength);
|
||||
STATIC XTCDECL VOID ReadCommand(OUT PWCHAR Buffer,
|
||||
IN ULONG BufferSize);
|
||||
STATIC XTCDECL VOID RegisterBuiltinCommands();
|
||||
};
|
||||
|
||||
class TextUi
|
||||
{
|
||||
public:
|
||||
STATIC XTCDECL VOID DisplayBootMenu();
|
||||
STATIC XTCDECL VOID DisplayErrorDialog(IN PCWSTR Caption,
|
||||
IN PCWSTR Message);
|
||||
STATIC XTCDECL VOID DisplayInfoDialog(IN PCWSTR Caption,
|
||||
IN PCWSTR Message);
|
||||
STATIC XTCDECL VOID DisplayInputDialog(IN PCWSTR Caption,
|
||||
IN PCWSTR Message,
|
||||
IN OUT PWCHAR *InputFieldText);
|
||||
STATIC XTCDECL XTBL_DIALOG_HANDLE DisplayProgressDialog(IN PCWSTR Caption,
|
||||
IN PCWSTR Message,
|
||||
IN UCHAR Percentage);
|
||||
STATIC XTCDECL VOID UpdateProgressBar(IN PXTBL_DIALOG_HANDLE Handle,
|
||||
IN PCWSTR Message,
|
||||
IN UCHAR Percentage);
|
||||
|
||||
private:
|
||||
STATIC XTCDECL VOID DetermineDialogBoxSize(IN OUT PXTBL_DIALOG_HANDLE Handle,
|
||||
IN PCWSTR Message);
|
||||
STATIC XTCDECL VOID DisplayEditMenu(IN PXTBL_BOOTMENU_ITEM MenuEntry);
|
||||
STATIC XTCDECL VOID DrawBootMenu(OUT PXTBL_DIALOG_HANDLE Handle);
|
||||
STATIC XTCDECL VOID DrawBootMenuEntry(IN PXTBL_DIALOG_HANDLE Handle,
|
||||
IN PWCHAR MenuEntry,
|
||||
IN UINT Position,
|
||||
IN BOOLEAN Highlighted);
|
||||
STATIC XTCDECL VOID DrawDialogBox(IN OUT PXTBL_DIALOG_HANDLE Handle,
|
||||
IN PCWSTR Caption,
|
||||
IN PCWSTR Message);
|
||||
STATIC XTCDECL VOID DrawButton(IN PXTBL_DIALOG_HANDLE Handle);
|
||||
STATIC XTCDECL VOID DrawInputField(IN PXTBL_DIALOG_HANDLE Handle,
|
||||
IN PWCHAR InputFieldText);
|
||||
STATIC XTCDECL VOID DrawMessage(IN PXTBL_DIALOG_HANDLE Handle,
|
||||
IN PCWSTR Message);
|
||||
STATIC XTCDECL VOID DrawProgressBar(IN PXTBL_DIALOG_HANDLE Handle,
|
||||
IN UCHAR Percentage);
|
||||
STATIC XTCDECL VOID DrawEditMenu(OUT PXTBL_DIALOG_HANDLE Handle);
|
||||
STATIC XTCDECL EFI_STATUS DrawEditMenuEntry(IN PXTBL_DIALOG_HANDLE Handle,
|
||||
IN PCWSTR OptionName,
|
||||
IN PCWSTR OptionValue,
|
||||
IN UINT Position,
|
||||
IN BOOLEAN Highlighted);
|
||||
};
|
||||
|
||||
class Volume
|
||||
{
|
||||
private:
|
||||
STATIC LIST_ENTRY EfiBlockDevices;
|
||||
|
||||
public:
|
||||
STATIC XTCDECL EFI_STATUS CloseVolume(IN PEFI_HANDLE VolumeHandle);
|
||||
STATIC XTCDECL EFI_STATUS EnumerateBlockDevices();
|
||||
STATIC XTCDECL EFI_STATUS FindDevicePath(IN PEFI_DEVICE_PATH_PROTOCOL FsHandle,
|
||||
IN CONST PWCHAR FileSystemPath,
|
||||
OUT PEFI_DEVICE_PATH_PROTOCOL* DevicePath);
|
||||
STATIC XTCDECL EFI_STATUS GetEfiPath(IN PWCHAR SystemPath,
|
||||
OUT PWCHAR *EfiPath);
|
||||
STATIC XTCDECL EFI_STATUS GetDevicePath(IN PWCHAR SystemPath,
|
||||
OUT PEFI_DEVICE_PATH_PROTOCOL *DevicePath,
|
||||
OUT PWCHAR *ArcName,
|
||||
OUT PWCHAR *Path);
|
||||
STATIC XTCDECL EFI_STATUS OpenVolume(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath,
|
||||
OUT PEFI_HANDLE DiskHandle,
|
||||
OUT PEFI_FILE_HANDLE *FsHandle);
|
||||
STATIC XTCDECL EFI_STATUS ReadFile(IN PEFI_FILE_HANDLE DirHandle,
|
||||
IN PCWSTR FileName,
|
||||
OUT PVOID *FileData,
|
||||
OUT PSIZE_T FileSize);
|
||||
|
||||
|
||||
private:
|
||||
STATIC XTCDECL EFI_STATUS DiscoverEfiBlockDevices(OUT PLIST_ENTRY BlockDevices);
|
||||
STATIC XTCDECL EFI_STATUS DissectArcPath(IN PWCHAR SystemPath,
|
||||
OUT PWCHAR *ArcName,
|
||||
OUT PWCHAR *Path,
|
||||
OUT PUSHORT DriveType,
|
||||
OUT PULONG DriveNumber,
|
||||
OUT PULONG PartNumber);
|
||||
STATIC XTCDECL PEFI_DEVICE_PATH_PROTOCOL DuplicateDevicePath(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath);
|
||||
STATIC XTCDECL EFI_STATUS FindLastBlockDeviceNode(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath,
|
||||
OUT PEFI_DEVICE_PATH_PROTOCOL *LastNode);
|
||||
STATIC XTCDECL BOOLEAN FindParentBlockDevice(IN PLIST_ENTRY BlockDevices,
|
||||
IN PEFI_BLOCK_DEVICE_DATA ChildNode,
|
||||
OUT PEFI_BLOCK_DEVICE_DATA *ParentNode);
|
||||
};
|
||||
|
||||
class XtLoader
|
||||
{
|
||||
private:
|
||||
STATIC PBL_XT_BOOT_MENU BootMenu;
|
||||
STATIC EFI_HANDLE EfiImageHandle;
|
||||
STATIC PEFI_SYSTEM_TABLE EfiSystemTable;
|
||||
STATIC XTBL_STATUS LoaderStatus;
|
||||
|
||||
public:
|
||||
STATIC XTCDECL VOID DisableBootServices();
|
||||
STATIC XTCDECL BOOLEAN GetBootServicesStatus();
|
||||
STATIC XTCDECL EFI_HANDLE GetEfiImageHandle();
|
||||
STATIC XTCDECL PEFI_SYSTEM_TABLE GetEfiSystemTable();
|
||||
STATIC XTCDECL VOID GetLoaderImageInformation(PVOID *LoaderBase,
|
||||
PULONGLONG LoaderSize);
|
||||
STATIC XTCDECL INT_PTR GetSecureBootStatus();
|
||||
STATIC XTCDECL VOID InitializeBootLoader(IN EFI_HANDLE ImageHandle,
|
||||
IN PEFI_SYSTEM_TABLE SystemTable);
|
||||
STATIC XTCDECL VOID RegisterBootMenu(IN PVOID BootMenuRoutine);
|
||||
STATIC XTCDECL VOID ShowBootMenu();
|
||||
};
|
||||
|
||||
#endif /* __XTLDR_XTLDR_HH */
|
||||
@@ -1,12 +1,12 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: xtldr/library/modproto.c
|
||||
* FILE: xtldr/library/modproto.cc
|
||||
* DESCRIPTION: XT Boot Loader protocol support for XTLDR modules
|
||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||
*/
|
||||
|
||||
#include <xtldr.h>
|
||||
#include <xtldr.hh>
|
||||
|
||||
|
||||
/**
|
||||
@@ -25,6 +25,7 @@
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCLINK
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlGetXtLdrProtocol(IN PEFI_SYSTEM_TABLE SystemTable,
|
||||
@@ -32,13 +33,13 @@ BlGetXtLdrProtocol(IN PEFI_SYSTEM_TABLE SystemTable,
|
||||
OUT PXTBL_LOADER_PROTOCOL *ProtocolHandler)
|
||||
{
|
||||
EFI_GUID ProtocolGuid = XT_BOOT_LOADER_PROTOCOL_GUID;
|
||||
PEFI_HANDLE Handles = NULL;
|
||||
PEFI_HANDLE Handles = NULLPTR;
|
||||
EFI_STATUS Status;
|
||||
UINT_PTR Count;
|
||||
UINT Index;
|
||||
|
||||
/* Try to locate the handles */
|
||||
Status = SystemTable->BootServices->LocateHandleBuffer(ByProtocol, &ProtocolGuid, NULL, &Count, &Handles);
|
||||
Status = SystemTable->BootServices->LocateHandleBuffer(ByProtocol, &ProtocolGuid, NULLPTR, &Count, &Handles);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Unable to get handles */
|
||||
@@ -53,7 +54,7 @@ BlGetXtLdrProtocol(IN PEFI_SYSTEM_TABLE SystemTable,
|
||||
{
|
||||
/* Try to open protocol */
|
||||
Status = SystemTable->BootServices->OpenProtocol(Handles[Index], &ProtocolGuid,
|
||||
(PVOID*)ProtocolHandler, ImageHandle, NULL,
|
||||
(PVOID*)ProtocolHandler, ImageHandle, NULLPTR,
|
||||
EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL);
|
||||
|
||||
/* Check if successfully opened the loader protocol */
|
||||
@@ -69,7 +70,7 @@ BlGetXtLdrProtocol(IN PEFI_SYSTEM_TABLE SystemTable,
|
||||
SystemTable->BootServices->FreePool(Handles);
|
||||
|
||||
/* Make sure the loaded protocol has been found */
|
||||
if(*ProtocolHandler == NULL)
|
||||
if(*ProtocolHandler == NULLPTR)
|
||||
{
|
||||
/* Protocol not found */
|
||||
return STATUS_EFI_NOT_FOUND;
|
||||
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
@@ -8,8 +8,8 @@ include_directories(
|
||||
|
||||
# Specify list of source code files
|
||||
list(APPEND XTLDR_ACPI_SOURCE
|
||||
${XTLDR_ACPI_SOURCE_DIR}/acpi.c
|
||||
${XTLDR_ACPI_SOURCE_DIR}/globals.c)
|
||||
${XTLDR_ACPI_SOURCE_DIR}/acpi.cc
|
||||
${XTLDR_ACPI_SOURCE_DIR}/data.cc)
|
||||
|
||||
# Link module executable
|
||||
add_executable(acpi ${XTLDR_ACPI_SOURCE})
|
||||
@@ -0,0 +1,439 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: xtldr/modules/acpi/acpi.cc
|
||||
* DESCRIPTION: XTLDR ACPI Support Module
|
||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||
*/
|
||||
|
||||
#include <acpi.hh>
|
||||
|
||||
|
||||
/* ACPI module information */
|
||||
MODULE_AUTHOR(L"Rafal Kupiec <belliash@codingworkshop.eu.org>");
|
||||
MODULE_DESCRIPTION(L"ACPI support");
|
||||
MODULE_LICENSE(L"GPLv3");
|
||||
MODULE_VERSION(L"0.1");
|
||||
|
||||
|
||||
/**
|
||||
* Attempts to get XSDP. If it is not found or checksum mismatch, it will try to get RSDP instead.
|
||||
*
|
||||
* @param AcpiTable
|
||||
* Suplies a pointer to memory area where XSDP or RSRP address will be stored.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
Acpi::GetAcpiDescriptionPointer(OUT PVOID *AcpiTable)
|
||||
{
|
||||
PVOID Rsdp;
|
||||
|
||||
/* Try to get XSDP (ACPI 2.0) from system configuration tables */
|
||||
if(GetXsdpTable(&Rsdp) == STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* XSDP found, return success */
|
||||
*AcpiTable = Rsdp;
|
||||
return STATUS_EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/* Try to get RSDP (ACPI 1.0) from system configuration tables */
|
||||
if(GetRsdpTable(&Rsdp) == STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* RSDP found, return success */
|
||||
*AcpiTable = Rsdp;
|
||||
return STATUS_EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/* Neither XSDP nor RSDP found */
|
||||
return STATUS_EFI_NOT_FOUND;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds ACPI description table with given signature.
|
||||
*
|
||||
* @param Signature
|
||||
* Supplies the signature of the desired ACPI table.
|
||||
*
|
||||
* @param PreviousTable
|
||||
* Supplies a pointer to the table to start searching from.
|
||||
*
|
||||
* @param AcpiTable
|
||||
* Supplies a pointer to memory area where ACPI table address will be stored, or NULLPTR if not found.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
Acpi::GetAcpiTable(IN CONST UINT Signature,
|
||||
IN PVOID PreviousTable,
|
||||
OUT PVOID *AcpiTable)
|
||||
{
|
||||
PACPI_DESCRIPTION_HEADER TableHeader;
|
||||
SIZE_T RsdtIndex, TableIndex;
|
||||
EFI_STATUS Status;
|
||||
SIZE_T TableCount;
|
||||
PACPI_RSDP Rsdp;
|
||||
PACPI_RSDT Rsdt;
|
||||
BOOLEAN Xsdp;
|
||||
|
||||
/* Return NULLPTR by default if requested table not found */
|
||||
*AcpiTable = NULLPTR;
|
||||
|
||||
/* Get Root System Description Table Pointer */
|
||||
Status = GetAcpiDescriptionPointer((PVOID*)&Rsdp);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* ACPI tables not found, return error */
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Check if it is XSDP (ACPI 2.0) or RSDP (ACPI 1.0) */
|
||||
if(Rsdp->Revision >= 2 && Rsdp->XsdtAddress)
|
||||
{
|
||||
/* XSDP (ACPI 2.0) */
|
||||
Xsdp = TRUE;
|
||||
Rsdt = (PACPI_RSDT)(UINT_PTR)Rsdp->XsdtAddress;
|
||||
TableCount = (Rsdt->Header.Length - sizeof(ACPI_DESCRIPTION_HEADER)) / 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* RSDP (ACPI 1.0) */
|
||||
Xsdp = FALSE;
|
||||
Rsdt = (PACPI_RSDT)(UINT_PTR)Rsdp->RsdtAddress;
|
||||
TableCount = (Rsdt->Header.Length - sizeof(ACPI_DESCRIPTION_HEADER)) / 4;
|
||||
}
|
||||
|
||||
/* Iterate over all ACPI tables */
|
||||
for(TableIndex = 0; TableIndex < TableCount; TableIndex++)
|
||||
{
|
||||
/* Get table headers in reverse order */
|
||||
RsdtIndex = TableCount - TableIndex - 1;
|
||||
|
||||
/* Check if XSDP or RSDT is used */
|
||||
if(Xsdp)
|
||||
{
|
||||
/* Get table header from XSDT */
|
||||
TableHeader = (PACPI_DESCRIPTION_HEADER)(ULONG_PTR)((PULONGLONG)Rsdt->Tables)[RsdtIndex];
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Get table header from RSDT */
|
||||
TableHeader = (PACPI_DESCRIPTION_HEADER)(ULONG_PTR)((PULONG)Rsdt->Tables)[RsdtIndex];
|
||||
}
|
||||
|
||||
/* Check if previous table provided */
|
||||
if(PreviousTable != NULLPTR)
|
||||
{
|
||||
/* Check if this is a table previously found */
|
||||
if(TableHeader == (PVOID)PreviousTable)
|
||||
{
|
||||
/* Unset previous table */
|
||||
PreviousTable = NULLPTR;
|
||||
}
|
||||
|
||||
/* Skip to next ACPI table */
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Verify table signature */
|
||||
if((TableHeader->Signature == Signature))
|
||||
{
|
||||
/* Found requested ACPI table */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Make sure table was found */
|
||||
if(TableHeader->Signature != Signature)
|
||||
{
|
||||
/* ACPI table not found, return error */
|
||||
return STATUS_EFI_NOT_FOUND;
|
||||
}
|
||||
|
||||
/* Don't validate FADT on old, broken firmwares with ACPI 2.0 or older */
|
||||
if(TableHeader->Signature != ACPI_FADT_SIGNATURE || TableHeader->Revision > 2)
|
||||
{
|
||||
/* Validate table checksum */
|
||||
if(!ValidateAcpiTable(TableHeader, TableHeader->Length))
|
||||
{
|
||||
/* Checksum mismatch, return error */
|
||||
return STATUS_EFI_CRC_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
/* Found valid ACPI table, return success */
|
||||
*AcpiTable = TableHeader;
|
||||
return STATUS_EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Advanced Programmable Interrupt Controller (APIC) base address.
|
||||
*
|
||||
* @param ApicBase
|
||||
* Supplies a pointer to memory area where APIC base address will be stored.
|
||||
*
|
||||
* @return This routine returns an EFI status code.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
Acpi::GetApicBase(OUT PVOID *ApicBase)
|
||||
{
|
||||
CPUID_REGISTERS CpuRegisters;
|
||||
|
||||
/* Prepare CPUID registers to query for APIC support */
|
||||
XtLdrProtocol->Memory.ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
|
||||
CpuRegisters.Leaf = CPUID_GET_STANDARD1_FEATURES;
|
||||
|
||||
/* Query CPUID */
|
||||
XtLdrProtocol->Cpu.CpuId(&CpuRegisters);
|
||||
|
||||
/* Check if APIC present */
|
||||
if((CpuRegisters.Edx & CPUID_FEATURES_EDX_APIC) == 0)
|
||||
{
|
||||
/* APIC is not supported by the CPU */
|
||||
return STATUS_EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
/* Get APIC base address */
|
||||
*ApicBase = (PVOID)((UINT_PTR)XtLdrProtocol->Cpu.ReadModelSpecificRegister(0x1B) & 0xFFFFF000);
|
||||
|
||||
/* Return success */
|
||||
return STATUS_EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets RSDP (ACPI 1.0) from EFI system configuration
|
||||
*
|
||||
* @param AcpiTable
|
||||
* Suplies a pointer to memory area where RSDP address will be stored.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
Acpi::GetRsdpTable(OUT PVOID *AcpiTable)
|
||||
{
|
||||
EFI_GUID AcpiGuid = EFI_CONFIG_TABLE_ACPI_TABLE_GUID;
|
||||
EFI_STATUS Status;
|
||||
PVOID RsdpTable;
|
||||
|
||||
/* Get RSDP (ACPI 1.0) table from system configuration tables */
|
||||
Status = XtLdrProtocol->Utils.GetConfigurationTable(&AcpiGuid, &RsdpTable);
|
||||
if(Status != STATUS_EFI_SUCCESS || !ValidateAcpiTable(RsdpTable, 20))
|
||||
{
|
||||
/* RSDP not found or checksum mismatch */
|
||||
*AcpiTable = NULLPTR;
|
||||
return STATUS_EFI_NOT_FOUND;
|
||||
}
|
||||
|
||||
/* RSDP found, return success */
|
||||
*AcpiTable = RsdpTable;
|
||||
return STATUS_EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets SMBIOS from EFI system configuration
|
||||
*
|
||||
* @param SmBiosTable
|
||||
* Suplies a pointer to memory area where SMBIOS address will be stored.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
Acpi::GetSMBiosTable(OUT PVOID *SmBiosTable)
|
||||
{
|
||||
EFI_GUID SmBiosGuid = EFI_CONFIG_TABLE_SMBIOS_TABLE_GUID;
|
||||
PSMBIOS_TABLE_HEADER SmBios;
|
||||
EFI_STATUS Status;
|
||||
|
||||
/* Get SMBIOS table from system configuration tables */
|
||||
Status = XtLdrProtocol->Utils.GetConfigurationTable(&SmBiosGuid, (PVOID*)&SmBios);
|
||||
if(Status != STATUS_EFI_SUCCESS || !ValidateAcpiTable(SmBios, SmBios->Length))
|
||||
{
|
||||
/* SMBIOS not found or checksum mismatch */
|
||||
*SmBiosTable = NULLPTR;
|
||||
return STATUS_EFI_NOT_FOUND;
|
||||
}
|
||||
|
||||
/* SMBIOS found, return success */
|
||||
*SmBiosTable = SmBios;
|
||||
return STATUS_EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets SMBIOS3 from EFI system configuration
|
||||
*
|
||||
* @param SmBiosTable
|
||||
* Suplies a pointer to memory area where SMBIOS3 address will be stored.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
Acpi::GetSMBios3Table(OUT PVOID *SmBiosTable)
|
||||
{
|
||||
EFI_GUID SmBios3Guid = EFI_CONFIG_TABLE_SMBIOS3_TABLE_GUID;
|
||||
PSMBIOS3_TABLE_HEADER SmBios;
|
||||
EFI_STATUS Status;
|
||||
|
||||
/* Get SMBIOS3 table from system configuration tables */
|
||||
Status = XtLdrProtocol->Utils.GetConfigurationTable(&SmBios3Guid, (PVOID*)&SmBios);
|
||||
if(Status != STATUS_EFI_SUCCESS || !ValidateAcpiTable(SmBios, SmBios->Length))
|
||||
{
|
||||
/* SMBIOS3 not found or checksum mismatch */
|
||||
*SmBiosTable = NULLPTR;
|
||||
return STATUS_EFI_NOT_FOUND;
|
||||
}
|
||||
|
||||
/* SMBIOS3 found, return success */
|
||||
*SmBiosTable = SmBios;
|
||||
return STATUS_EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets XSDP (ACPI 2.0) from EFI system configuration
|
||||
*
|
||||
* @param AcpiTable
|
||||
* Suplies a pointer to memory area where XSDP address will be stored.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
Acpi::GetXsdpTable(OUT PVOID *AcpiTable)
|
||||
{
|
||||
EFI_GUID AcpiGuid = EFI_CONFIG_TABLE_ACPI20_TABLE_GUID;
|
||||
EFI_STATUS Status;
|
||||
PVOID XsdpTable;
|
||||
|
||||
/* Get XSDP (ACPI 2.0) from system configuration tables */
|
||||
Status = XtLdrProtocol->Utils.GetConfigurationTable(&AcpiGuid, &XsdpTable);
|
||||
if(Status != STATUS_EFI_SUCCESS || !ValidateAcpiTable(XsdpTable, 36))
|
||||
{
|
||||
/* XSDP not found or checksum mismatch */
|
||||
*AcpiTable = NULLPTR;
|
||||
return STATUS_EFI_NOT_FOUND;
|
||||
}
|
||||
|
||||
/* XSDP found, return success */
|
||||
*AcpiTable = XsdpTable;
|
||||
return STATUS_EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes ACPI module by opening XTLDR protocol and installing ACPI protocol.
|
||||
*
|
||||
* @param ImageHandle
|
||||
* Firmware-allocated handle that identifies the image.
|
||||
*
|
||||
* @param SystemTable
|
||||
* Provides the EFI system table.
|
||||
*
|
||||
* @return This routine returns status code.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
Acpi::InitializeModule(IN EFI_HANDLE ImageHandle,
|
||||
IN PEFI_SYSTEM_TABLE SystemTable)
|
||||
{
|
||||
EFI_GUID Guid = XT_ACPI_PROTOCOL_GUID;
|
||||
EFI_STATUS Status;
|
||||
|
||||
/* Open the XTLDR protocol */
|
||||
Status = BlGetXtLdrProtocol(SystemTable, ImageHandle, &XtLdrProtocol);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Failed to open the protocol, return error */
|
||||
return STATUS_EFI_PROTOCOL_ERROR;
|
||||
}
|
||||
|
||||
/* Set routines available via ACPI protocol */
|
||||
AcpiProtocol.GetAcpiDescriptionPointer = GetAcpiDescriptionPointer;
|
||||
AcpiProtocol.GetAcpiTable = GetAcpiTable;
|
||||
AcpiProtocol.GetApicBase = GetApicBase;
|
||||
AcpiProtocol.GetRsdpTable = GetRsdpTable;
|
||||
AcpiProtocol.GetSMBiosTable = GetSMBiosTable;
|
||||
AcpiProtocol.GetSMBios3Table = GetSMBios3Table;
|
||||
AcpiProtocol.GetXsdpTable = GetXsdpTable;
|
||||
|
||||
/* Install ACPI protocol */
|
||||
return XtLdrProtocol->Protocol.Install(&AcpiProtocol, &Guid);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates given ACPI table by calculating its checksum.
|
||||
*
|
||||
* @param Buffer
|
||||
* Supplies a pointer to the table to checksum.
|
||||
*
|
||||
* @param Size
|
||||
* Supplies the size of the table, in bytes.
|
||||
*
|
||||
* @return This routine returns TRUE if the table is valid, or FALSE otherwise.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
BOOLEAN
|
||||
Acpi::ValidateAcpiTable(IN PVOID Buffer,
|
||||
IN UINT_PTR Size)
|
||||
{
|
||||
PUCHAR Pointer;
|
||||
UCHAR Sum;
|
||||
|
||||
/* Initialize variables */
|
||||
Sum = 0;
|
||||
Pointer = (PUCHAR)Buffer;
|
||||
|
||||
/* Calculate checksum of given table */
|
||||
while(Size != 0)
|
||||
{
|
||||
Sum = (UCHAR)(Sum + *Pointer);
|
||||
Pointer += 1;
|
||||
Size -= 1;
|
||||
}
|
||||
|
||||
/* Return calculated checksum */
|
||||
return (Sum == 0) ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* This routine is the entry point of the XT EFI boot loader module.
|
||||
*
|
||||
* @param ImageHandle
|
||||
* Firmware-allocated handle that identifies the image.
|
||||
*
|
||||
* @param SystemTable
|
||||
* Provides the EFI system table.
|
||||
*
|
||||
* @return This routine returns status code.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
XtLdrModuleMain(IN EFI_HANDLE ImageHandle,
|
||||
IN PEFI_SYSTEM_TABLE SystemTable)
|
||||
{
|
||||
/* Initialize ACPI module */
|
||||
return Acpi::InitializeModule(ImageHandle, SystemTable);
|
||||
}
|
||||
@@ -1,16 +1,16 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: xtldr/modules/acpi/globals.c
|
||||
* DESCRIPTION: ACPI module global variables
|
||||
* FILE: xtldr/modules/acpi/data.cc
|
||||
* DESCRIPTION: ACPI module global and static data
|
||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||
*/
|
||||
|
||||
#include <xtblapi.h>
|
||||
#include <acpi.hh>
|
||||
|
||||
|
||||
/* ACPI Protocol */
|
||||
XTBL_ACPI_PROTOCOL AcpAcpiProtocol;
|
||||
XTBL_ACPI_PROTOCOL Acpi::AcpiProtocol;
|
||||
|
||||
/* XTLDR protocol handler */
|
||||
PXTBL_LOADER_PROTOCOL XtLdrProtocol;
|
||||
PXTBL_LOADER_PROTOCOL Acpi::XtLdrProtocol;
|
||||
@@ -0,0 +1,40 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: xtldr/modules/acpi/includes/acpi.hh
|
||||
* DESCRIPTION: XTLDR ACPI module header file
|
||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||
*/
|
||||
|
||||
#ifndef __XTLDR_ACPI_ACPI_HH
|
||||
#define __XTLDR_ACPI_ACPI_HH
|
||||
|
||||
#include <xtblapi.h>
|
||||
|
||||
|
||||
/* ACPI module for XTLDR */
|
||||
class Acpi
|
||||
{
|
||||
private:
|
||||
STATIC XTBL_ACPI_PROTOCOL AcpiProtocol;
|
||||
STATIC PXTBL_LOADER_PROTOCOL XtLdrProtocol;
|
||||
|
||||
public:
|
||||
STATIC XTCDECL EFI_STATUS GetAcpiDescriptionPointer(OUT PVOID *AcpiTable);
|
||||
STATIC XTCDECL EFI_STATUS GetAcpiTable(IN CONST UINT Signature,
|
||||
IN PVOID PreviousTable,
|
||||
OUT PVOID *AcpiTable);
|
||||
STATIC XTCDECL EFI_STATUS GetApicBase(OUT PVOID *ApicBase);
|
||||
STATIC XTCDECL EFI_STATUS GetRsdpTable(OUT PVOID *AcpiTable);
|
||||
STATIC XTCDECL EFI_STATUS GetSMBiosTable(OUT PVOID *SmBiosTable);
|
||||
STATIC XTCDECL EFI_STATUS GetSMBios3Table(OUT PVOID *SmBiosTable);
|
||||
STATIC XTCDECL EFI_STATUS GetXsdpTable(OUT PVOID *AcpiTable);
|
||||
STATIC XTCDECL EFI_STATUS InitializeModule(IN EFI_HANDLE ImageHandle,
|
||||
IN PEFI_SYSTEM_TABLE SystemTable);
|
||||
|
||||
private:
|
||||
STATIC XTCDECL BOOLEAN ValidateAcpiTable(IN PVOID Buffer,
|
||||
IN UINT_PTR Size);
|
||||
};
|
||||
|
||||
#endif /* __XTLDR_ACPI_ACPI_HH */
|
||||
@@ -8,8 +8,8 @@ include_directories(
|
||||
|
||||
# Specify list of source code files
|
||||
list(APPEND XTLDR_BEEP_SOURCE
|
||||
${XTLDR_BEEP_SOURCE_DIR}/beep.c
|
||||
${XTLDR_BEEP_SOURCE_DIR}/globals.c)
|
||||
${XTLDR_BEEP_SOURCE_DIR}/beep.cc
|
||||
${XTLDR_BEEP_SOURCE_DIR}/data.cc)
|
||||
|
||||
# Link module executable
|
||||
add_executable(beep ${XTLDR_BEEP_SOURCE})
|
||||
@@ -0,0 +1,311 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: xtldr/modules/beep/beep.cc
|
||||
* DESCRIPTION: XTLDR Beep Module
|
||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||
*/
|
||||
|
||||
#include <beep.hh>
|
||||
|
||||
|
||||
/* Beep module information */
|
||||
MODULE_AUTHOR(L"Rafal Kupiec <belliash@codingworkshop.eu.org>");
|
||||
MODULE_DESCRIPTION(L"Plays a GRUB compatible tune via PC speaker");
|
||||
MODULE_LICENSE(L"GPLv3");
|
||||
MODULE_VERSION(L"0.2");
|
||||
|
||||
/**
|
||||
* Executes the beep shell command to play a musical tune.
|
||||
*
|
||||
* @param Argc
|
||||
* Supplies the number of arguments passed to the command line.
|
||||
*
|
||||
* @param Argv
|
||||
* Supplies a pointer to an array of null-terminated argument strings.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
Beep::CommandBeep(IN ULONG Argc,
|
||||
IN PWCHAR *Argv)
|
||||
{
|
||||
WCHAR Tune[XTBL_SH_MAX_LINE_LENGTH];
|
||||
ULONG ArgumentIndex, TuneLength;
|
||||
PWCHAR Character;
|
||||
|
||||
/* Check the number of arguments */
|
||||
if(Argc < 2)
|
||||
{
|
||||
/* Invalid number of arguments, print usage message and return */
|
||||
XtLdrProtocol->Console.Print(L"Usage: beep <tempo> <pitch1> <duration1> [pitch2 duration2 ...]\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Rebuild the space-separated argument string */
|
||||
TuneLength = 0;
|
||||
for(ArgumentIndex = 1; ArgumentIndex < Argc; ArgumentIndex++)
|
||||
{
|
||||
/* Retrieve the pointer to the current argument string */
|
||||
Character = Argv[ArgumentIndex];
|
||||
while(*Character != L'\0')
|
||||
{
|
||||
/* Verify that the tune buffer has sufficient capacity */
|
||||
if(TuneLength >= XTBL_SH_MAX_LINE_LENGTH - 1)
|
||||
{
|
||||
/* Buffer capacity exceeded, print error message and return */
|
||||
XtLdrProtocol->Console.Print(L"ERROR: Tune is too long.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Copy the current character to the buffer and advance the source pointer */
|
||||
Tune[TuneLength++] = *Character++;
|
||||
}
|
||||
|
||||
/* Check if there are subsequent arguments */
|
||||
if(ArgumentIndex + 1 < Argc)
|
||||
{
|
||||
/* Verify that the tune buffer has sufficient capacity */
|
||||
if(TuneLength >= XTBL_SH_MAX_LINE_LENGTH - 1)
|
||||
{
|
||||
/* Buffer capacity exceeded, print error message and return */
|
||||
XtLdrProtocol->Console.Print(L"ERROR: Tune is too long.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Append a space character to the tune buffer */
|
||||
Tune[TuneLength++] = L' ';
|
||||
}
|
||||
}
|
||||
|
||||
/* Terminate the reconstructed string and dispatch it to the playback routine */
|
||||
Tune[TuneLength] = L'\0';
|
||||
PlayTune(Tune);
|
||||
}
|
||||
|
||||
/**
|
||||
* Disables the PC speaker.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
Beep::DisableToneBeep()
|
||||
{
|
||||
UCHAR Status;
|
||||
|
||||
/* Stop the PC speaker */
|
||||
Status = XtLdrProtocol->IoPort.Read8(0x61);
|
||||
XtLdrProtocol->IoPort.Write8(0x61, Status & 0xFC);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables the PC speaker and plays a sound.
|
||||
*
|
||||
* @param Pitch
|
||||
* Specifies a pitch (in Hz) of the sound.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
Beep::EnableToneBeep(IN UINT Pitch)
|
||||
{
|
||||
UINT Counter;
|
||||
UCHAR Status;
|
||||
|
||||
/* Pitch only in range of 20..20000 */
|
||||
if(Pitch < 20)
|
||||
{
|
||||
Pitch = 20;
|
||||
}
|
||||
else if(Pitch > 20000)
|
||||
{
|
||||
Pitch = 20000;
|
||||
}
|
||||
|
||||
/* Set the desired frequency of the PIT clock */
|
||||
Counter = 0x1234DD / Pitch;
|
||||
XtLdrProtocol->IoPort.Write8(0x43, 0xB6);
|
||||
XtLdrProtocol->IoPort.Write8(0x43, 0xB6);
|
||||
XtLdrProtocol->IoPort.Write8(0x42, (UCHAR) Counter & 0xFF);
|
||||
XtLdrProtocol->IoPort.Write8(0x42, (UCHAR) (Counter >> 8) & 0xFF);
|
||||
|
||||
/* Start the PC speaker */
|
||||
Status = XtLdrProtocol->IoPort.Read8(0x61);
|
||||
XtLdrProtocol->IoPort.Write8(0x61, Status | 0x03);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes BEEP module by opening XTLDR protocol and playing the tune.
|
||||
*
|
||||
* @param ImageHandle
|
||||
* Firmware-allocated handle that identifies the image.
|
||||
*
|
||||
* @param SystemTable
|
||||
* Provides the EFI system table.
|
||||
*
|
||||
* @return This routine returns status code.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
Beep::InitializeModule(IN EFI_HANDLE ImageHandle,
|
||||
IN PEFI_SYSTEM_TABLE SystemTable)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
PWCHAR Tune;
|
||||
|
||||
/* Open the XTLDR protocol */
|
||||
Status = BlGetXtLdrProtocol(SystemTable, ImageHandle, &XtLdrProtocol);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Failed to open the protocol, return error */
|
||||
return STATUS_EFI_PROTOCOL_ERROR;
|
||||
}
|
||||
|
||||
/* Register the `beep` command */
|
||||
XtLdrProtocol->Shell.RegisterCommand(L"beep", L"Plays a GRUB compatible tune", CommandBeep);
|
||||
|
||||
/* Play the tune set in the configuration */
|
||||
XtLdrProtocol->Config.GetValue(L"TUNE", &Tune);
|
||||
PlayTune(Tune);
|
||||
|
||||
/* Return success */
|
||||
return STATUS_EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* This routine plays a tune.
|
||||
*
|
||||
* @param Arguments
|
||||
* Optional list of parameters provided with the command.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
Beep::PlayTune(IN PWCHAR Arguments)
|
||||
{
|
||||
LONG Pitch, Duration, Tempo;
|
||||
PWCHAR Argument, LastArgument;
|
||||
|
||||
/* Reset pitch and duration */
|
||||
Duration = -1;
|
||||
Pitch = -1;
|
||||
Tempo = -1;
|
||||
|
||||
/* Tokenize provided list of arguments */
|
||||
Argument = XtLdrProtocol->WideString.Tokenize(Arguments, L" ", &LastArgument);
|
||||
|
||||
/* Iterate over all arguments */
|
||||
while(Argument != NULLPTR)
|
||||
{
|
||||
/* Check if tempo, pitch and duration are set */
|
||||
if(Tempo < 0)
|
||||
{
|
||||
/* Set the tempo */
|
||||
Tempo = WideStringToNumber(Argument);
|
||||
}
|
||||
else if(Pitch < 0)
|
||||
{
|
||||
/* Set the pitch */
|
||||
Pitch = WideStringToNumber(Argument);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Set the duration */
|
||||
Duration = WideStringToNumber(Argument);
|
||||
|
||||
/* Check pitch value */
|
||||
if(Pitch > 0)
|
||||
{
|
||||
/* Emit the beep tone */
|
||||
EnableToneBeep(Pitch);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Stop emitting beep tone */
|
||||
DisableToneBeep();
|
||||
}
|
||||
|
||||
/* Wait for duration time */
|
||||
XtLdrProtocol->Utils.SleepExecution(60000 * Duration / Tempo);
|
||||
|
||||
/* Reset pitch and duration */
|
||||
Pitch = -1;
|
||||
Duration = -1;
|
||||
}
|
||||
|
||||
/* Get next argument */
|
||||
Argument = XtLdrProtocol->WideString.Tokenize(NULLPTR, L" ", &LastArgument);
|
||||
}
|
||||
|
||||
/* Stop emitting beep tone */
|
||||
DisableToneBeep();
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a wide string into a number.
|
||||
*
|
||||
* @param String
|
||||
* Supplies an input wide string.
|
||||
*
|
||||
* @return This routine returns the number that was converted from the wide string.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
UINT
|
||||
Beep::WideStringToNumber(IN PWCHAR String)
|
||||
{
|
||||
ULONG Number = 0;
|
||||
|
||||
/* Iterate over all characters until '\0' found */
|
||||
do
|
||||
{
|
||||
/* Check if this is a digit */
|
||||
if(*String - '0' < 10)
|
||||
{
|
||||
/* Add another digit to the number */
|
||||
Number *= 10;
|
||||
Number += *String - '0';
|
||||
}
|
||||
}
|
||||
while(*++String != L'\0');
|
||||
|
||||
/* Return number */
|
||||
return Number;
|
||||
}
|
||||
|
||||
/**
|
||||
* This routine is the entry point of the XT EFI boot loader module.
|
||||
*
|
||||
* @param ImageHandle
|
||||
* Firmware-allocated handle that identifies the image.
|
||||
*
|
||||
* @param SystemTable
|
||||
* Provides the EFI system table.
|
||||
*
|
||||
* @return This routine returns status code.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
XtLdrModuleMain(IN EFI_HANDLE ImageHandle,
|
||||
IN PEFI_SYSTEM_TABLE SystemTable)
|
||||
{
|
||||
/* Initialize BEEP module */
|
||||
return Beep::InitializeModule(ImageHandle, SystemTable);
|
||||
}
|
||||
@@ -1,13 +1,13 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: xtldr/modules/beep/globals.c
|
||||
* DESCRIPTION: Beep module global variables
|
||||
* FILE: xtldr/modules/beep/data.cc
|
||||
* DESCRIPTION: BEEP module global and static data
|
||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||
*/
|
||||
|
||||
#include <xtblapi.h>
|
||||
#include <beep.hh>
|
||||
|
||||
|
||||
/* XTLDR protocol handler */
|
||||
PXTBL_LOADER_PROTOCOL XtLdrProtocol;
|
||||
PXTBL_LOADER_PROTOCOL Beep::XtLdrProtocol;
|
||||
@@ -0,0 +1,33 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: xtldr/modules/beep/includes/beep.hh
|
||||
* DESCRIPTION: XTLDR Beep Module header file
|
||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||
*/
|
||||
|
||||
#ifndef __XTLDR_BEEP_BEEP_HH
|
||||
#define __XTLDR_BEEP_BEEP_HH
|
||||
|
||||
#include <xtblapi.h>
|
||||
|
||||
|
||||
/* BEEP module for XTLDR */
|
||||
class Beep
|
||||
{
|
||||
private:
|
||||
STATIC PXTBL_LOADER_PROTOCOL XtLdrProtocol;
|
||||
|
||||
public:
|
||||
STATIC XTCDECL EFI_STATUS InitializeModule(IN EFI_HANDLE ImageHandle,
|
||||
IN PEFI_SYSTEM_TABLE SystemTable);
|
||||
|
||||
private:
|
||||
STATIC XTCDECL VOID CommandBeep(IN ULONG Argc, IN PWCHAR *Argv);
|
||||
STATIC XTCDECL VOID DisableToneBeep();
|
||||
STATIC XTCDECL VOID EnableToneBeep(IN UINT Pitch);
|
||||
STATIC XTCDECL VOID PlayTune(IN PWCHAR Arguments);
|
||||
STATIC XTCDECL UINT WideStringToNumber(IN PWCHAR String);
|
||||
};
|
||||
|
||||
#endif /* __XTLDR_BEEP_BEEP_HH */
|
||||
+2
-2
@@ -8,8 +8,8 @@ include_directories(
|
||||
|
||||
# Specify list of source code files
|
||||
list(APPEND XTLDR_CHAINLDR_SOURCE
|
||||
${XTLDR_CHAINLDR_SOURCE_DIR}/chainldr.c
|
||||
${XTLDR_CHAINLDR_SOURCE_DIR}/globals.c)
|
||||
${XTLDR_CHAINLDR_SOURCE_DIR}/chainldr.cc
|
||||
${XTLDR_CHAINLDR_SOURCE_DIR}/data.cc)
|
||||
|
||||
# Link module executable
|
||||
add_executable(chainldr ${XTLDR_CHAINLDR_SOURCE})
|
||||
+53
-30
@@ -1,12 +1,12 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: xtldr/modules/chainldr/chainldr.c
|
||||
* FILE: xtldr/modules/chainldr/chainldr.cc
|
||||
* DESCRIPTION: XTLDR Chain Loader
|
||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||
*/
|
||||
|
||||
#include <chainldr.h>
|
||||
#include <chainldr.hh>
|
||||
|
||||
|
||||
/* ChainLoader module information */
|
||||
@@ -15,6 +15,7 @@ MODULE_DESCRIPTION(L"XTLDR Chain Loader");
|
||||
MODULE_LICENSE(L"GPLv3");
|
||||
MODULE_VERSION(L"0.1");
|
||||
|
||||
|
||||
/**
|
||||
* Chainloads another boot loader.
|
||||
*
|
||||
@@ -27,7 +28,7 @@ MODULE_VERSION(L"0.1");
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
ChBootSystem(IN PXTBL_BOOT_PARAMETERS Parameters)
|
||||
ChainLoader::BootSystem(IN PXTBL_BOOT_PARAMETERS Parameters)
|
||||
{
|
||||
EFI_GUID LIPGuid = EFI_LOADED_IMAGE_PROTOCOL_GUID;
|
||||
EFI_MEMMAP_DEVICE_PATH MemoryDevicePath[2];
|
||||
@@ -39,7 +40,7 @@ ChBootSystem(IN PXTBL_BOOT_PARAMETERS Parameters)
|
||||
PVOID LoaderData;
|
||||
|
||||
/* Check if image file is provided */
|
||||
if(Parameters->KernelFile == NULL)
|
||||
if(Parameters->KernelFile == NULLPTR)
|
||||
{
|
||||
/* No image filename provided, return error code */
|
||||
XtLdrProtocol->Debug.Print(L"ERROR: No EFI image filename provided\n");
|
||||
@@ -47,7 +48,7 @@ ChBootSystem(IN PXTBL_BOOT_PARAMETERS Parameters)
|
||||
}
|
||||
|
||||
/* Open EFI volume */
|
||||
Status = XtLdrProtocol->Disk.OpenVolume(NULL, &DiskHandle, &FsHandle);
|
||||
Status = XtLdrProtocol->Disk.OpenVolume(Parameters->DevicePath, &DiskHandle, &FsHandle);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Failed to open a volume, return error code */
|
||||
@@ -66,14 +67,14 @@ ChBootSystem(IN PXTBL_BOOT_PARAMETERS Parameters)
|
||||
XtLdrProtocol->Debug.Print(L"ERROR: Unable to open system boot directory (Status Code: 0x%zX)\n", Status);
|
||||
|
||||
/* Close volume and return error code */
|
||||
XtLdrProtocol->Disk.CloseVolume(DiskHandle);
|
||||
XtLdrProtocol->Disk.CloseVolume(&DiskHandle);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Read EFI image file from disk and close both directory and EFI volume */
|
||||
Status = XtLdrProtocol->Disk.ReadFile(BootDir, Parameters->KernelFile, &LoaderData, &LoaderSize);
|
||||
BootDir->Close(BootDir);
|
||||
XtLdrProtocol->Disk.CloseVolume(DiskHandle);
|
||||
XtLdrProtocol->Disk.CloseVolume(&DiskHandle);
|
||||
|
||||
/* Setup device path for EFI image */
|
||||
MemoryDevicePath[0].Header.Length[0] = sizeof(EFI_MEMMAP_DEVICE_PATH);
|
||||
@@ -89,8 +90,8 @@ ChBootSystem(IN PXTBL_BOOT_PARAMETERS Parameters)
|
||||
MemoryDevicePath[1].Header.SubType = EFI_END_ENTIRE_DP;
|
||||
|
||||
/* Load EFI image */
|
||||
Status = XtLdrProtocol->Util.LoadEfiImage((PEFI_DEVICE_PATH_PROTOCOL)MemoryDevicePath,
|
||||
LoaderData, LoaderSize, &LoaderHandle);
|
||||
Status = XtLdrProtocol->Utils.LoadEfiImage((PEFI_DEVICE_PATH_PROTOCOL)MemoryDevicePath,
|
||||
LoaderData, LoaderSize, &LoaderHandle);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Failed to chainload EFI binary, return error code */
|
||||
@@ -112,7 +113,7 @@ ChBootSystem(IN PXTBL_BOOT_PARAMETERS Parameters)
|
||||
if(Parameters->Parameters)
|
||||
{
|
||||
/* Pass arguments to chainloaded image */
|
||||
LoadedImage->LoadOptionsSize = RtlWideStringLength(Parameters->Parameters, 0) * sizeof(WCHAR);
|
||||
LoadedImage->LoadOptionsSize = XtLdrProtocol->WideString.Length(Parameters->Parameters, 0) * sizeof(WCHAR);
|
||||
LoadedImage->LoadOptions = Parameters->Parameters;
|
||||
}
|
||||
|
||||
@@ -120,7 +121,46 @@ ChBootSystem(IN PXTBL_BOOT_PARAMETERS Parameters)
|
||||
LoadedImage->DeviceHandle = DiskHandle;
|
||||
|
||||
/* Chainload EFI image */
|
||||
return XtLdrProtocol->Util.StartEfiImage(LoaderHandle);
|
||||
return XtLdrProtocol->Utils.StartEfiImage(LoaderHandle);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes CHAINLDR module by opening XTLDR protocol and installing CHAINLOADER protocol.
|
||||
*
|
||||
* @param ImageHandle
|
||||
* Firmware-allocated handle that identifies the image.
|
||||
*
|
||||
* @param SystemTable
|
||||
* Provides the EFI system table.
|
||||
*
|
||||
* @return This routine returns status code.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
ChainLoader::InitializeModule(IN EFI_HANDLE ImageHandle,
|
||||
IN PEFI_SYSTEM_TABLE SystemTable)
|
||||
{
|
||||
EFI_GUID Guid = XT_CHAIN_BOOT_PROTOCOL_GUID;
|
||||
EFI_STATUS Status;
|
||||
|
||||
/* Open the XTLDR protocol */
|
||||
Status = BlGetXtLdrProtocol(SystemTable, ImageHandle, &XtLdrProtocol);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Failed to open the protocol, return error */
|
||||
return STATUS_EFI_PROTOCOL_ERROR;
|
||||
}
|
||||
|
||||
/* Set routines available via ChainLoader boot protocol */
|
||||
BootProtocol.BootSystem = BootSystem;
|
||||
|
||||
/* Register XTOS boot protocol */
|
||||
XtLdrProtocol->Boot.RegisterProtocol(L"CHAINLOADER", &Guid);
|
||||
|
||||
/* Install XTOS protocol */
|
||||
return XtLdrProtocol->Protocol.Install(&BootProtocol, &Guid);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -141,23 +181,6 @@ EFI_STATUS
|
||||
XtLdrModuleMain(IN EFI_HANDLE ImageHandle,
|
||||
IN PEFI_SYSTEM_TABLE SystemTable)
|
||||
{
|
||||
EFI_GUID Guid = XT_CHAIN_BOOT_PROTOCOL_GUID;
|
||||
EFI_STATUS Status;
|
||||
|
||||
/* Open the XTLDR protocol */
|
||||
Status = BlGetXtLdrProtocol(SystemTable, ImageHandle, &XtLdrProtocol);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Failed to open the protocol, return error */
|
||||
return STATUS_EFI_PROTOCOL_ERROR;
|
||||
}
|
||||
|
||||
/* Set routines available via ChainLoader boot protocol */
|
||||
ChpBootProtocol.BootSystem = ChBootSystem;
|
||||
|
||||
/* Register XTOS boot protocol */
|
||||
XtLdrProtocol->Boot.RegisterProtocol(L"CHAINLOADER", &Guid);
|
||||
|
||||
/* Install XTOS protocol */
|
||||
return XtLdrProtocol->Protocol.Install(&ChpBootProtocol, &Guid);
|
||||
/* Initialize CHAINLDR module */
|
||||
return ChainLoader::InitializeModule(ImageHandle, SystemTable);
|
||||
}
|
||||
@@ -1,16 +1,16 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: xtldr/modules/chainldr/globals.c
|
||||
* DESCRIPTION: XTLDR Chain Loader global variables
|
||||
* FILE: xtldr/modules/chainldr/data.cc
|
||||
* DESCRIPTION: CHAINLDR module global and static data
|
||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||
*/
|
||||
|
||||
#include <xtblapi.h>
|
||||
#include <chainldr.hh>
|
||||
|
||||
|
||||
/* ChainLoader Boot Protocol */
|
||||
XTBL_BOOT_PROTOCOL ChpBootProtocol;
|
||||
XTBL_BOOT_PROTOCOL ChainLoader::BootProtocol;
|
||||
|
||||
/* XTLDR protocol handler */
|
||||
PXTBL_LOADER_PROTOCOL XtLdrProtocol;
|
||||
PXTBL_LOADER_PROTOCOL ChainLoader::XtLdrProtocol;
|
||||
@@ -0,0 +1,28 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: xtldr/modules/chainldr/includes/chainldr.hh
|
||||
* DESCRIPTION: XTLDR Chain Loader header file
|
||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||
*/
|
||||
|
||||
#ifndef __XTLDR_CHAINLDR_CHAINLDR_HH
|
||||
#define __XTLDR_CHAINLDR_CHAINLDR_HH
|
||||
|
||||
#include <xtblapi.h>
|
||||
|
||||
|
||||
/* CHAINLDR module for XTLDR */
|
||||
class ChainLoader
|
||||
{
|
||||
private:
|
||||
STATIC XTBL_BOOT_PROTOCOL BootProtocol;
|
||||
STATIC PXTBL_LOADER_PROTOCOL XtLdrProtocol;
|
||||
|
||||
public:
|
||||
STATIC XTCDECL EFI_STATUS BootSystem(IN PXTBL_BOOT_PARAMETERS Parameters);
|
||||
STATIC XTCDECL EFI_STATUS InitializeModule(IN EFI_HANDLE ImageHandle,
|
||||
IN PEFI_SYSTEM_TABLE SystemTable);
|
||||
};
|
||||
|
||||
#endif /* __XTLDR_CHAINLDR_CHAINLDR_HH */
|
||||
@@ -8,8 +8,8 @@ include_directories(
|
||||
|
||||
# Specify list of source code files
|
||||
list(APPEND XTLDR_DUMMY_SOURCE
|
||||
${XTLDR_DUMMY_SOURCE_DIR}/dummy.c
|
||||
${XTLDR_DUMMY_SOURCE_DIR}/globals.c)
|
||||
${XTLDR_DUMMY_SOURCE_DIR}/dummy.cc
|
||||
${XTLDR_DUMMY_SOURCE_DIR}/data.cc)
|
||||
|
||||
# Link module executable
|
||||
add_executable(dummy ${XTLDR_DUMMY_SOURCE})
|
||||
@@ -1,16 +1,16 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: xtldr/modules/dummy/globals.c
|
||||
* DESCRIPTION: Dummy XTLDR module global variables
|
||||
* FILE: xtldr/modules/dummy/data.cc
|
||||
* DESCRIPTION: Dummy XTLDR module global and static data
|
||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||
*/
|
||||
|
||||
#include <dummy.h>
|
||||
#include <dummy.hh>
|
||||
|
||||
|
||||
/* XTLDR protocol handler */
|
||||
PXTBL_LOADER_PROTOCOL XtLdrProtocol;
|
||||
|
||||
/* Dummy Boot Protocol handler */
|
||||
XTBL_BOOT_PROTOCOL BlpDummyProtocol;
|
||||
XTBL_BOOT_PROTOCOL Dummy::DummyProtocol;
|
||||
|
||||
/* XTLDR protocol handler */
|
||||
PXTBL_LOADER_PROTOCOL Dummy::XtLdrProtocol;
|
||||
@@ -1,12 +1,12 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: xtldr/modules/dummy/dummy.c
|
||||
* FILE: xtldr/modules/dummy/dummy.cc
|
||||
* DESCRIPTION: XTLDR Dummy Module
|
||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||
*/
|
||||
|
||||
#include <dummy.h>
|
||||
#include <dummy.hh>
|
||||
|
||||
|
||||
/* Dummy module information */
|
||||
@@ -15,6 +15,7 @@ MODULE_DESCRIPTION(L"XTLDR Dummy Module");
|
||||
MODULE_LICENSE(L"GPLv3");
|
||||
MODULE_VERSION(L"0.1");
|
||||
|
||||
|
||||
/**
|
||||
* Stub boot routine.
|
||||
*
|
||||
@@ -27,11 +28,50 @@ MODULE_VERSION(L"0.1");
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
DmBootSystem(IN PXTBL_BOOT_PARAMETERS Parameters)
|
||||
Dummy::BootSystem(IN PXTBL_BOOT_PARAMETERS Parameters)
|
||||
{
|
||||
return STATUS_EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes DUMMY module by opening XTLDR protocol and installing DUMMY protocol.
|
||||
*
|
||||
* @param ImageHandle
|
||||
* Firmware-allocated handle that identifies the image.
|
||||
*
|
||||
* @param SystemTable
|
||||
* Provides the EFI system table.
|
||||
*
|
||||
* @return This routine returns status code.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
Dummy::InitializeModule(IN EFI_HANDLE ImageHandle,
|
||||
IN PEFI_SYSTEM_TABLE SystemTable)
|
||||
{
|
||||
EFI_GUID DummyGuid = XT_DUMMY_BOOT_PROTOCOL_GUID;
|
||||
EFI_STATUS Status;
|
||||
|
||||
/* Open the XTLDR protocol */
|
||||
Status = BlGetXtLdrProtocol(SystemTable, ImageHandle, &XtLdrProtocol);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Failed to open the protocol, return error */
|
||||
return STATUS_EFI_PROTOCOL_ERROR;
|
||||
}
|
||||
|
||||
/* Set boot protocol routines */
|
||||
DummyProtocol.BootSystem = BootSystem;
|
||||
|
||||
/* Register XTOS boot protocol */
|
||||
XtLdrProtocol->Boot.RegisterProtocol(L"DUMMYOS", &DummyGuid);
|
||||
|
||||
/* Register DUMMY protocol as XTOS boot protocol */
|
||||
return XtLdrProtocol->Protocol.Install(&DummyProtocol, &DummyGuid);
|
||||
}
|
||||
|
||||
/**
|
||||
* This routine is the entry point of the XT EFI boot loader module.
|
||||
*
|
||||
@@ -50,23 +90,6 @@ EFI_STATUS
|
||||
XtLdrModuleMain(IN EFI_HANDLE ImageHandle,
|
||||
IN PEFI_SYSTEM_TABLE SystemTable)
|
||||
{
|
||||
EFI_GUID DummyGuid = XT_DUMMY_BOOT_PROTOCOL_GUID;
|
||||
EFI_STATUS Status;
|
||||
|
||||
/* Open the XTLDR protocol */
|
||||
Status = BlGetXtLdrProtocol(SystemTable, ImageHandle, &XtLdrProtocol);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Failed to open the protocol, return error */
|
||||
return STATUS_EFI_PROTOCOL_ERROR;
|
||||
}
|
||||
|
||||
/* Set boot protocol routines */
|
||||
BlpDummyProtocol.BootSystem = DmBootSystem;
|
||||
|
||||
/* Register XTOS boot protocol */
|
||||
XtLdrProtocol->Boot.RegisterProtocol(L"DUMMYOS", &DummyGuid);
|
||||
|
||||
/* Register DUMMY protocol as XTOS boot protocol */
|
||||
return XtLdrProtocol->Protocol.Install(&BlpDummyProtocol, &DummyGuid);
|
||||
/* Initialize DUMMY module */
|
||||
return Dummy::InitializeModule(ImageHandle, SystemTable);
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: xtldr/modules/dummy/includes/dummy.hh
|
||||
* DESCRIPTION: XTLDR Dummy Module header file
|
||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||
*/
|
||||
|
||||
#ifndef __XTLDR_DUMMY_DUMMY_HH
|
||||
#define __XTLDR_DUMMY_DUMMY_HH
|
||||
|
||||
#include <xtblapi.h>
|
||||
|
||||
|
||||
/* DUMMY module for XTLDR */
|
||||
class Dummy
|
||||
{
|
||||
private:
|
||||
STATIC XTBL_BOOT_PROTOCOL DummyProtocol;
|
||||
STATIC PXTBL_LOADER_PROTOCOL XtLdrProtocol;
|
||||
|
||||
public:
|
||||
STATIC EFI_STATUS BootSystem(IN PXTBL_BOOT_PARAMETERS Parameters);
|
||||
STATIC EFI_STATUS InitializeModule(IN EFI_HANDLE ImageHandle,
|
||||
IN PEFI_SYSTEM_TABLE SystemTable);
|
||||
};
|
||||
|
||||
#endif/* __XTLDR_DUMMY_DUMMY_HH */
|
||||
+2
-2
@@ -8,8 +8,8 @@ include_directories(
|
||||
|
||||
# Specify list of source code files
|
||||
list(APPEND XTLDR_FRAMEBUF_SOURCE
|
||||
${XTLDR_FRAMEBUF_SOURCE_DIR}/framebuf.c
|
||||
${XTLDR_FRAMEBUF_SOURCE_DIR}/globals.c)
|
||||
${XTLDR_FRAMEBUF_SOURCE_DIR}/framebuf.cc
|
||||
${XTLDR_FRAMEBUF_SOURCE_DIR}/data.cc)
|
||||
|
||||
# Link bootloader executable
|
||||
add_executable(framebuf ${XTLDR_FRAMEBUF_SOURCE})
|
||||
@@ -0,0 +1,19 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: xtldr/modules/framebuf/data.cc
|
||||
* DESCRIPTION: EFI framebuffer module global and static data
|
||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||
*/
|
||||
|
||||
#include <framebuf.hh>
|
||||
|
||||
|
||||
/* Framebuffer display information */
|
||||
XTBL_FRAMEBUFFER_INFORMATION FrameBuffer::DisplayInfo;
|
||||
|
||||
/* Framebuffer protocol handler */
|
||||
XTBL_FRAMEBUFFER_PROTOCOL FrameBuffer::FbProtocol;
|
||||
|
||||
/* XTLDR protocol handler */
|
||||
PXTBL_LOADER_PROTOCOL FrameBuffer::XtLdrProtocol;
|
||||
+542
-515
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
@@ -0,0 +1,44 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: xtldr/modules/framebuf/includes/framebuf.hh
|
||||
* DESCRIPTION: EFI Framebuffer support module header file
|
||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||
*/
|
||||
|
||||
#ifndef __XTLDR_MODULES_FRAMEBUF_HH
|
||||
#define __XTLDR_MODULES_FRAMEBUF_HH
|
||||
|
||||
#include <xtblapi.h>
|
||||
|
||||
|
||||
class FrameBuffer
|
||||
{
|
||||
private:
|
||||
STATIC XTBL_FRAMEBUFFER_INFORMATION DisplayInfo;
|
||||
STATIC XTBL_FRAMEBUFFER_PROTOCOL FbProtocol;
|
||||
STATIC PXTBL_LOADER_PROTOCOL XtLdrProtocol;
|
||||
|
||||
public:
|
||||
STATIC XTCDECL EFI_STATUS GetDisplayDriver(OUT PEFI_GRAPHICS_PROTOCOL Protocol);
|
||||
STATIC XTCDECL EFI_STATUS GetDisplayInformation(OUT PEFI_PHYSICAL_ADDRESS FrameBufferBase,
|
||||
OUT PULONG_PTR FrameBufferSize,
|
||||
OUT PXTBL_FRAMEBUFFER_MODE_INFORMATION ModeInfo);
|
||||
STATIC XTCDECL EFI_STATUS GetPreferredScreenResolution(OUT PUINT PreferredWidth,
|
||||
OUT PUINT PreferredHeight);
|
||||
STATIC XTCDECL EFI_STATUS InitializeDisplay();
|
||||
STATIC XTCDECL EFI_STATUS InitializeModule(IN EFI_HANDLE ImageHandle,
|
||||
IN PEFI_SYSTEM_TABLE SystemTable);
|
||||
STATIC XTCDECL EFI_STATUS SetScreenResolution(IN UINT Width,
|
||||
IN UINT Height);
|
||||
|
||||
private:
|
||||
STATIC EFI_STATUS FindFramebufferAddress(OUT PEFI_PHYSICAL_ADDRESS Address);
|
||||
STATIC XTCDECL VOID GetColorMask(IN UINT EfiMask,
|
||||
OUT PUSHORT ColorSize,
|
||||
OUT PUSHORT ColorShift);
|
||||
STATIC XTCDECL EFI_STATUS GetModeInformation();
|
||||
STATIC XTCDECL VOID GetPixelInformation(IN PEFI_PIXEL_BITMASK PixelsBitMask);
|
||||
};
|
||||
|
||||
#endif /* __XTLDR_MODULES_FRAMEBUF_HH */
|
||||
+2
-2
@@ -8,8 +8,8 @@ include_directories(
|
||||
|
||||
# Specify list of source code files
|
||||
list(APPEND XTLDR_PECOFF_SOURCE
|
||||
${XTLDR_PECOFF_SOURCE_DIR}/globals.c
|
||||
${XTLDR_PECOFF_SOURCE_DIR}/pecoff.c)
|
||||
${XTLDR_PECOFF_SOURCE_DIR}/data.cc
|
||||
${XTLDR_PECOFF_SOURCE_DIR}/pecoff.cc)
|
||||
|
||||
# Link module executable
|
||||
add_executable(pecoff ${XTLDR_PECOFF_SOURCE})
|
||||
@@ -0,0 +1,16 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: xtldr/modules/pecoff/globals.cc
|
||||
* DESCRIPTION: Basic PE/COFF executable file format global and static data
|
||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||
*/
|
||||
|
||||
#include <pecoff.hh>
|
||||
|
||||
|
||||
/* XTOS PE/COFF Image Protocol */
|
||||
XTBL_EXECUTABLE_IMAGE_PROTOCOL PeCoff::PeProtocol;
|
||||
|
||||
/* EFI XT Loader Protocol */
|
||||
PXTBL_LOADER_PROTOCOL PeCoff::XtLdrProtocol;
|
||||
@@ -0,0 +1,53 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: xtldr/modules/pecoff/includes/pecoff.hh
|
||||
* DESCRIPTION: Basic PE/COFF executable file format support header
|
||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||
*/
|
||||
|
||||
#ifndef __XTLDR_PECOFF_HH
|
||||
#define __XTLDR_PECOFF_HH
|
||||
|
||||
#include <xtblapi.h>
|
||||
|
||||
|
||||
/* PE/COFF module for XTLDR */
|
||||
class PeCoff
|
||||
{
|
||||
private:
|
||||
STATIC XTBL_EXECUTABLE_IMAGE_PROTOCOL PeProtocol;
|
||||
STATIC PXTBL_LOADER_PROTOCOL XtLdrProtocol;
|
||||
|
||||
public:
|
||||
STATIC XTCDECL EFI_STATUS GetEntryPoint(IN PVOID ImagePointer,
|
||||
OUT PVOID *EntryPoint);
|
||||
STATIC XTCDECL EFI_STATUS GetFileSize(IN PVOID ImagePointer,
|
||||
OUT PULONGLONG FileSize);
|
||||
STATIC XTCDECL EFI_STATUS GetImageSize(IN PVOID ImagePointer,
|
||||
OUT PUINT ImageSize);
|
||||
STATIC XTCDECL EFI_STATUS GetMachineType(IN PVOID ImagePointer,
|
||||
OUT PUSHORT MachineType);
|
||||
STATIC XTCDECL EFI_STATUS GetSection(IN PVOID ImagePointer,
|
||||
IN PCHAR SectionName,
|
||||
OUT PULONG *RawData);
|
||||
STATIC XTCDECL EFI_STATUS GetSubSystem(IN PVOID ImagePointer,
|
||||
OUT PUSHORT SubSystem);
|
||||
STATIC XTCDECL EFI_STATUS GetVersion(IN PVOID ImagePointer,
|
||||
OUT PUSHORT Version);
|
||||
STATIC XTCDECL EFI_STATUS InitializeModule(IN EFI_HANDLE ImageHandle,
|
||||
IN PEFI_SYSTEM_TABLE SystemTable);
|
||||
STATIC XTCDECL EFI_STATUS LoadImage(IN PEFI_FILE_HANDLE FileHandle,
|
||||
IN LOADER_MEMORY_TYPE MemoryType,
|
||||
IN PVOID VirtualAddress,
|
||||
OUT PVOID *ImagePointer);
|
||||
STATIC XTCDECL EFI_STATUS RelocateImage(IN PVOID ImagePointer,
|
||||
IN EFI_VIRTUAL_ADDRESS Address);
|
||||
STATIC XTCDECL EFI_STATUS UnloadImage(IN PVOID ImagePointer);
|
||||
STATIC XTCDECL EFI_STATUS VerifyImage(IN PVOID ImagePointer);
|
||||
|
||||
private:
|
||||
STATIC XTCDECL EFI_STATUS RelocateLoadedImage(IN PPECOFF_IMAGE_CONTEXT Image);
|
||||
};
|
||||
|
||||
#endif /* __XTLDR_PECOFF_HH */
|
||||
@@ -1,12 +1,12 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: xtldr/modules/pecoff/pecoff.c
|
||||
* FILE: xtldr/modules/pecoff/pecoff.cc
|
||||
* DESCRIPTION: Basic PE/COFF executable file format support module
|
||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||
*/
|
||||
|
||||
#include <pecoff.h>
|
||||
#include <pecoff.hh>
|
||||
|
||||
|
||||
/* PE/COFF_O module information */
|
||||
@@ -15,6 +15,7 @@ MODULE_DESCRIPTION(L"Basic PE/COFF executable file format support");
|
||||
MODULE_LICENSE(L"GPLv3");
|
||||
MODULE_VERSION(L"0.1");
|
||||
|
||||
|
||||
/**
|
||||
* Returns the address of the entry point.
|
||||
*
|
||||
@@ -30,10 +31,13 @@ MODULE_VERSION(L"0.1");
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
PeGetEntryPoint(IN PVOID ImagePointer,
|
||||
OUT PVOID *EntryPoint)
|
||||
PeCoff::GetEntryPoint(IN PVOID ImagePointer,
|
||||
OUT PVOID *EntryPoint)
|
||||
{
|
||||
PPECOFF_IMAGE_CONTEXT Image = ImagePointer;
|
||||
PPECOFF_IMAGE_CONTEXT Image;
|
||||
|
||||
/* Get PE/COFF image pointer*/
|
||||
Image = (PPECOFF_IMAGE_CONTEXT)ImagePointer;
|
||||
|
||||
/* Validate input data */
|
||||
if(!Image || !Image->PeHeader)
|
||||
@@ -46,12 +50,12 @@ PeGetEntryPoint(IN PVOID ImagePointer,
|
||||
if(Image->PeHeader->OptionalHeader32.Magic == PECOFF_IMAGE_PE_OPTIONAL_HDR64_MAGIC)
|
||||
{
|
||||
/* Get entry point from 64-bit optional header */
|
||||
*EntryPoint = (PUINT8)Image->VirtualAddress + Image->PeHeader->OptionalHeader64.AddressOfEntryPoint;
|
||||
*EntryPoint = (PUCHAR)Image->VirtualAddress + Image->PeHeader->OptionalHeader64.AddressOfEntryPoint;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Get entry point from 32-bit optional header */
|
||||
*EntryPoint = (PUINT8)Image->VirtualAddress + Image->PeHeader->OptionalHeader32.AddressOfEntryPoint;
|
||||
*EntryPoint = (PUCHAR)Image->VirtualAddress + Image->PeHeader->OptionalHeader32.AddressOfEntryPoint;
|
||||
}
|
||||
|
||||
/* Return success */
|
||||
@@ -73,13 +77,13 @@ PeGetEntryPoint(IN PVOID ImagePointer,
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
PeGetFileSize(IN PVOID ImagePointer,
|
||||
OUT PULONGLONG FileSize)
|
||||
PeCoff::GetFileSize(IN PVOID ImagePointer,
|
||||
OUT PULONGLONG FileSize)
|
||||
{
|
||||
PPECOFF_IMAGE_CONTEXT Image;
|
||||
|
||||
/* Get PE/COFF image pointer*/
|
||||
Image = ImagePointer;
|
||||
Image = (PPECOFF_IMAGE_CONTEXT)ImagePointer;
|
||||
|
||||
/* Validate input data */
|
||||
if(!Image || !Image->ImageSize)
|
||||
@@ -108,13 +112,13 @@ PeGetFileSize(IN PVOID ImagePointer,
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
PeGetImageSize(IN PVOID ImagePointer,
|
||||
OUT PUINT ImageSize)
|
||||
PeCoff::GetImageSize(IN PVOID ImagePointer,
|
||||
OUT PUINT ImageSize)
|
||||
{
|
||||
PPECOFF_IMAGE_CONTEXT Image;
|
||||
|
||||
/* Get PE/COFF image pointer*/
|
||||
Image = ImagePointer;
|
||||
Image = (PPECOFF_IMAGE_CONTEXT)ImagePointer;
|
||||
|
||||
/* Validate input data */
|
||||
if(!Image || !Image->ImageSize)
|
||||
@@ -143,10 +147,13 @@ PeGetImageSize(IN PVOID ImagePointer,
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
PeGetMachineType(IN PVOID ImagePointer,
|
||||
OUT PUSHORT MachineType)
|
||||
PeCoff::GetMachineType(IN PVOID ImagePointer,
|
||||
OUT PUSHORT MachineType)
|
||||
{
|
||||
PPECOFF_IMAGE_CONTEXT Image = ImagePointer;
|
||||
PPECOFF_IMAGE_CONTEXT Image;
|
||||
|
||||
/* Get PE/COFF image pointer*/
|
||||
Image = (PPECOFF_IMAGE_CONTEXT)ImagePointer;
|
||||
|
||||
/* Validate input data */
|
||||
if(!Image || !Image->PeHeader)
|
||||
@@ -178,9 +185,9 @@ PeGetMachineType(IN PVOID ImagePointer,
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
PeGetSection(IN PVOID ImagePointer,
|
||||
IN PCHAR SectionName,
|
||||
OUT PULONG *RawData)
|
||||
PeCoff::GetSection(IN PVOID ImagePointer,
|
||||
IN PCHAR SectionName,
|
||||
OUT PULONG *RawData)
|
||||
{
|
||||
PPECOFF_IMAGE_SECTION_HEADER SectionHeader;
|
||||
PPECOFF_IMAGE_CONTEXT Image;
|
||||
@@ -188,7 +195,7 @@ PeGetSection(IN PVOID ImagePointer,
|
||||
USHORT SectionIndex;
|
||||
|
||||
/* Get PE/COFF image pointer*/
|
||||
Image = ImagePointer;
|
||||
Image = (PPECOFF_IMAGE_CONTEXT)ImagePointer;
|
||||
|
||||
/* Validate input data */
|
||||
if(!Image || !Image->PeHeader)
|
||||
@@ -212,16 +219,16 @@ PeGetSection(IN PVOID ImagePointer,
|
||||
}
|
||||
|
||||
/* Get section name length */
|
||||
SectionNameLength = RtlStringLength(SectionName, 0);
|
||||
SectionNameLength = XtLdrProtocol->String.Length(SectionName, 0);
|
||||
|
||||
/* Iterate through all image sections */
|
||||
for(SectionIndex = 0; SectionIndex < Image->PeHeader->FileHeader.NumberOfSections; SectionIndex++)
|
||||
{
|
||||
/* Check section name */
|
||||
if(RtlCompareString((PCHAR)SectionHeader[SectionIndex].Name, SectionName, SectionNameLength) == 0)
|
||||
if(XtLdrProtocol->String.Compare((PCHAR)SectionHeader[SectionIndex].Name, SectionName, SectionNameLength) == 0)
|
||||
{
|
||||
/* Store section address and return */
|
||||
*RawData = Image->Data + SectionHeader[SectionIndex].PointerToRawData;
|
||||
*RawData = (PULONG)((PUCHAR)Image->Data + SectionHeader[SectionIndex].PointerToRawData);
|
||||
return STATUS_EFI_SUCCESS;
|
||||
}
|
||||
}
|
||||
@@ -245,10 +252,13 @@ PeGetSection(IN PVOID ImagePointer,
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
PeGetSubSystem(IN PVOID ImagePointer,
|
||||
OUT PUSHORT SubSystem)
|
||||
PeCoff::GetSubSystem(IN PVOID ImagePointer,
|
||||
OUT PUSHORT SubSystem)
|
||||
{
|
||||
PPECOFF_IMAGE_CONTEXT Image = ImagePointer;
|
||||
PPECOFF_IMAGE_CONTEXT Image;
|
||||
|
||||
/* Get PE/COFF image pointer*/
|
||||
Image = (PPECOFF_IMAGE_CONTEXT)ImagePointer;
|
||||
|
||||
/* Validate input data */
|
||||
if(!Image || !Image->PeHeader)
|
||||
@@ -288,10 +298,13 @@ PeGetSubSystem(IN PVOID ImagePointer,
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
PeGetVersion(IN PVOID ImagePointer,
|
||||
OUT PUSHORT Version)
|
||||
PeCoff::GetVersion(IN PVOID ImagePointer,
|
||||
OUT PUSHORT Version)
|
||||
{
|
||||
PPECOFF_IMAGE_CONTEXT Image = ImagePointer;
|
||||
PPECOFF_IMAGE_CONTEXT Image;
|
||||
|
||||
/* Get PE/COFF image pointer*/
|
||||
Image = (PPECOFF_IMAGE_CONTEXT)ImagePointer;
|
||||
|
||||
/* Validate input data */
|
||||
if(!Image || !Image->PeHeader)
|
||||
@@ -316,6 +329,52 @@ PeGetVersion(IN PVOID ImagePointer,
|
||||
return STATUS_EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes PECOFF module by opening XTLDR protocol and installing PECOFF protocol.
|
||||
*
|
||||
* @param ImageHandle
|
||||
* Firmware-allocated handle that identifies the image.
|
||||
*
|
||||
* @param SystemTable
|
||||
* Provides the EFI system table.
|
||||
*
|
||||
* @return This routine returns status code.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
PeCoff::InitializeModule(IN EFI_HANDLE ImageHandle,
|
||||
IN PEFI_SYSTEM_TABLE SystemTable)
|
||||
{
|
||||
EFI_GUID Guid = XT_PECOFF_IMAGE_PROTOCOL_GUID;
|
||||
EFI_STATUS Status;
|
||||
|
||||
/* Open the XTLDR protocol */
|
||||
Status = BlGetXtLdrProtocol(SystemTable, ImageHandle, &XtLdrProtocol);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Failed to open loader protocol */
|
||||
return STATUS_EFI_PROTOCOL_ERROR;
|
||||
}
|
||||
|
||||
/* Set routines available via PE/COFF image protocol */
|
||||
PeProtocol.GetEntryPoint = GetEntryPoint;
|
||||
PeProtocol.GetFileSize = GetFileSize;
|
||||
PeProtocol.GetImageSize = GetImageSize;
|
||||
PeProtocol.GetMachineType = GetMachineType;
|
||||
PeProtocol.GetSection = GetSection;
|
||||
PeProtocol.GetSubSystem = GetSubSystem;
|
||||
PeProtocol.GetVersion = GetVersion;
|
||||
PeProtocol.LoadImage = LoadImage;
|
||||
PeProtocol.RelocateImage = RelocateImage;
|
||||
PeProtocol.UnloadImage = UnloadImage;
|
||||
PeProtocol.VerifyImage = VerifyImage;
|
||||
|
||||
/* Register PE/COFF protocol */
|
||||
return XtLdrProtocol->Protocol.Install(&PeProtocol, &Guid);
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads a PE/COFF image file.
|
||||
*
|
||||
@@ -337,10 +396,10 @@ PeGetVersion(IN PVOID ImagePointer,
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
PeLoadImage(IN PEFI_FILE_HANDLE FileHandle,
|
||||
IN LOADER_MEMORY_TYPE MemoryType,
|
||||
IN PVOID VirtualAddress,
|
||||
OUT PVOID *ImagePointer)
|
||||
PeCoff::LoadImage(IN PEFI_FILE_HANDLE FileHandle,
|
||||
IN LOADER_MEMORY_TYPE MemoryType,
|
||||
IN PVOID VirtualAddress,
|
||||
OUT PVOID *ImagePointer)
|
||||
{
|
||||
EFI_GUID FileInfoGuid = EFI_FILE_INFO_PROTOCOL_GUID;
|
||||
PPECOFF_IMAGE_SECTION_HEADER SectionHeader;
|
||||
@@ -400,7 +459,7 @@ PeLoadImage(IN PEFI_FILE_HANDLE FileHandle,
|
||||
}
|
||||
|
||||
/* Store file size and memory type, nullify data and free up memory */
|
||||
ImageData->Data = NULL;
|
||||
ImageData->Data = NULLPTR;
|
||||
ImageData->FileSize = FileInfo->FileSize;
|
||||
ImageData->MemoryType = MemoryType;
|
||||
XtLdrProtocol->Memory.FreePool(FileInfo);
|
||||
@@ -409,7 +468,7 @@ PeLoadImage(IN PEFI_FILE_HANDLE FileHandle,
|
||||
Pages = EFI_SIZE_TO_PAGES(ImageData->FileSize);
|
||||
|
||||
/* Allocate pages */
|
||||
Status = XtLdrProtocol->Memory.AllocatePages(Pages, &Address);
|
||||
Status = XtLdrProtocol->Memory.AllocatePages(AllocateAnyPages, Pages, &Address);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Pages allocation failure */
|
||||
@@ -433,10 +492,10 @@ PeLoadImage(IN PEFI_FILE_HANDLE FileHandle,
|
||||
|
||||
/* Extract DOS and PE headers */
|
||||
ImageData->DosHeader = (PPECOFF_IMAGE_DOS_HEADER)Data;
|
||||
ImageData->PeHeader = (PPECOFF_IMAGE_PE_HEADER)((PUINT8)Data + ImageData->DosHeader->PeHeaderOffset);
|
||||
ImageData->PeHeader = (PPECOFF_IMAGE_PE_HEADER)((PUCHAR)Data + ImageData->DosHeader->PeHeaderOffset);
|
||||
|
||||
/* Validate headers */
|
||||
Status = PeVerifyImage(ImageData);
|
||||
Status = PeCoff::VerifyImage(ImageData);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Header validation failed, probably broken or invalid PE/COFF image */
|
||||
@@ -472,7 +531,7 @@ PeLoadImage(IN PEFI_FILE_HANDLE FileHandle,
|
||||
ImageData->ImagePages = EFI_SIZE_TO_PAGES(ImageData->ImageSize);
|
||||
|
||||
/* Allocate image pages */
|
||||
Status = XtLdrProtocol->Memory.AllocatePages(ImageData->ImagePages, &Address);
|
||||
Status = XtLdrProtocol->Memory.AllocatePages(AllocateAnyPages, ImageData->ImagePages, &Address);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Pages reallocation failure */
|
||||
@@ -482,7 +541,7 @@ PeLoadImage(IN PEFI_FILE_HANDLE FileHandle,
|
||||
}
|
||||
|
||||
/* Store image data and virtual address */
|
||||
ImageData->Data = (PUINT8)(UINT_PTR)Address;
|
||||
ImageData->Data = (PUCHAR)(UINT_PTR)Address;
|
||||
ImageData->PhysicalAddress = (PVOID)(UINT_PTR)Address;
|
||||
if(VirtualAddress)
|
||||
{
|
||||
@@ -534,7 +593,7 @@ PeLoadImage(IN PEFI_FILE_HANDLE FileHandle,
|
||||
if(SectionSize > 0 && SectionHeader[Index].PointerToRawData != 0)
|
||||
{
|
||||
/* Copy section */
|
||||
XtLdrProtocol->Memory.CopyMemory((PUINT8)ImageData->Data + SectionHeader[Index].VirtualAddress,
|
||||
XtLdrProtocol->Memory.CopyMemory((PUCHAR)ImageData->Data + SectionHeader[Index].VirtualAddress,
|
||||
Data + SectionHeader[Index].PointerToRawData, SectionSize);
|
||||
}
|
||||
|
||||
@@ -542,7 +601,7 @@ PeLoadImage(IN PEFI_FILE_HANDLE FileHandle,
|
||||
if(SectionSize < SectionHeader[Index].Misc.VirtualSize)
|
||||
{
|
||||
/* Fill remaining space with zeroes */
|
||||
XtLdrProtocol->Memory.ZeroMemory((PUINT8)ImageData->Data + SectionHeader[Index].VirtualAddress + SectionSize,
|
||||
XtLdrProtocol->Memory.ZeroMemory((PUCHAR)ImageData->Data + SectionHeader[Index].VirtualAddress + SectionSize,
|
||||
SectionHeader[Index].Misc.VirtualSize - SectionSize);
|
||||
}
|
||||
}
|
||||
@@ -551,7 +610,7 @@ PeLoadImage(IN PEFI_FILE_HANDLE FileHandle,
|
||||
XtLdrProtocol->Memory.FreePages((EFI_PHYSICAL_ADDRESS)(UINT_PTR)Data, Pages);
|
||||
|
||||
/* Perform relocation fixups */
|
||||
Status = PepRelocateLoadedImage(ImageData);
|
||||
Status = PeCoff::RelocateLoadedImage(ImageData);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Failed to relocate image */
|
||||
@@ -581,14 +640,16 @@ PeLoadImage(IN PEFI_FILE_HANDLE FileHandle,
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
PeRelocateImage(IN PVOID ImagePointer,
|
||||
IN EFI_VIRTUAL_ADDRESS Address)
|
||||
PeCoff::RelocateImage(IN PVOID ImagePointer,
|
||||
IN EFI_VIRTUAL_ADDRESS Address)
|
||||
{
|
||||
PPECOFF_IMAGE_CONTEXT Image = ImagePointer;
|
||||
|
||||
UINT64 ImageBase, OldVirtualAddress;
|
||||
PPECOFF_IMAGE_CONTEXT Image;
|
||||
ULONGLONG ImageBase, OldVirtualAddress;
|
||||
EFI_STATUS Status;
|
||||
|
||||
/* Get PE/COFF image pointer*/
|
||||
Image = (PPECOFF_IMAGE_CONTEXT)ImagePointer;
|
||||
|
||||
/* Store original virtual address */
|
||||
OldVirtualAddress = (UINT_PTR)Image->VirtualAddress;
|
||||
|
||||
@@ -606,7 +667,7 @@ PeRelocateImage(IN PVOID ImagePointer,
|
||||
|
||||
/* Overwrite virtual address and relocate image once again */
|
||||
Image->VirtualAddress = (PVOID)(Address - OldVirtualAddress + ImageBase);
|
||||
Status = PepRelocateLoadedImage(Image);
|
||||
Status = PeCoff::RelocateLoadedImage(Image);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Relocation failed */
|
||||
@@ -620,6 +681,130 @@ PeRelocateImage(IN PVOID ImagePointer,
|
||||
return STATUS_EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Relocates a loaded PE/COFF image.
|
||||
*
|
||||
* @param Image
|
||||
* Supplies a pointer to the PE/COFF context structure representing the loaded image.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
PeCoff::RelocateLoadedImage(IN PPECOFF_IMAGE_CONTEXT Image)
|
||||
{
|
||||
PPECOFF_IMAGE_BASE_RELOCATION RelocationDir, RelocationEnd;
|
||||
PPECOFF_IMAGE_DATA_DIRECTORY DataDirectory;
|
||||
USHORT Offset, Type, Count;
|
||||
PUSHORT TypeOffset;
|
||||
ULONGLONG ImageBase;
|
||||
PUINT Address;
|
||||
PULONGLONG LongPtr;
|
||||
PUINT ShortPtr;
|
||||
|
||||
/* Make sure image is not stripped */
|
||||
if(Image->PeHeader->FileHeader.Characteristics & PECOFF_IMAGE_FILE_RELOCS_STRIPPED)
|
||||
{
|
||||
/* No relocation information found */
|
||||
XtLdrProtocol->Debug.Print(L"WARNING: PE/COFF image is stripped and contains no information about relocations\n");
|
||||
return STATUS_EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/* Check PE/COFF image type */
|
||||
if(Image->PeHeader->OptionalHeader32.Magic == PECOFF_IMAGE_PE_OPTIONAL_HDR64_MAGIC)
|
||||
{
|
||||
/* Set relocation data directory and image base address */
|
||||
DataDirectory = &Image->PeHeader->OptionalHeader64.DataDirectory[PECOFF_IMAGE_DIRECTORY_ENTRY_BASERELOC];
|
||||
ImageBase = Image->PeHeader->OptionalHeader64.ImageBase;
|
||||
|
||||
/* Check if loaded 64-bit PE32+ image should be relocated */
|
||||
if(Image->PeHeader->OptionalHeader64.NumberOfRvaAndSizes <= PECOFF_IMAGE_DIRECTORY_ENTRY_BASERELOC ||
|
||||
DataDirectory->VirtualAddress == 0 || DataDirectory->Size < sizeof(PECOFF_IMAGE_BASE_RELOCATION))
|
||||
{
|
||||
/* No need to relocate the image */
|
||||
return STATUS_EFI_SUCCESS;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Set relocation data directory and image base address */
|
||||
DataDirectory = &Image->PeHeader->OptionalHeader32.DataDirectory[PECOFF_IMAGE_DIRECTORY_ENTRY_BASERELOC];
|
||||
ImageBase = Image->PeHeader->OptionalHeader32.ImageBase;
|
||||
|
||||
/* Check if loaded 32-bit PE32 image should be relocated */
|
||||
if(Image->PeHeader->OptionalHeader32.NumberOfRvaAndSizes <= PECOFF_IMAGE_DIRECTORY_ENTRY_BASERELOC ||
|
||||
DataDirectory->VirtualAddress == 0 || DataDirectory->Size < sizeof(PECOFF_IMAGE_BASE_RELOCATION))
|
||||
{
|
||||
/* No need to relocate the image */
|
||||
return STATUS_EFI_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
/* Set relocation pointers */
|
||||
RelocationDir = (PPECOFF_IMAGE_BASE_RELOCATION)((ULONG_PTR)Image->Data + DataDirectory->VirtualAddress);
|
||||
RelocationEnd = (PPECOFF_IMAGE_BASE_RELOCATION)((ULONG_PTR)RelocationDir + DataDirectory->Size);
|
||||
|
||||
/* Do relocations */
|
||||
while(RelocationDir < RelocationEnd && RelocationDir->SizeOfBlock > 0)
|
||||
{
|
||||
/* Calculate number of relocations needed, address and type offset */
|
||||
Count = (RelocationDir->SizeOfBlock - sizeof(PECOFF_IMAGE_BASE_RELOCATION)) / sizeof(USHORT);
|
||||
Address = (PUINT)((PUCHAR)Image->Data + RelocationDir->VirtualAddress);
|
||||
TypeOffset = (PUSHORT)((PUCHAR)RelocationDir + sizeof(PECOFF_IMAGE_BASE_RELOCATION));
|
||||
|
||||
/* Do relocations */
|
||||
while(Count--)
|
||||
{
|
||||
/* Calculate offset and relocation type */
|
||||
Offset = *TypeOffset & 0xFFF;
|
||||
Type = *TypeOffset >> 12;
|
||||
|
||||
/* Check if end of the loaded address reached */
|
||||
if((PVOID)(PUSHORT)(Address + Offset) >= (PUCHAR)Image->Data + Image->ImageSize)
|
||||
{
|
||||
/* Do not relocate after the end of loaded image */
|
||||
break;
|
||||
}
|
||||
|
||||
/* Make sure we are not going to relocate into .reloc section */
|
||||
if((ULONG_PTR)(Address + Offset) < (ULONG_PTR)RelocationDir ||
|
||||
(ULONG_PTR)(Address + Offset) >= (ULONG_PTR)RelocationEnd)
|
||||
{
|
||||
/* Apply relocation fixup */
|
||||
switch (Type)
|
||||
{
|
||||
case PECOFF_IMAGE_REL_BASED_ABSOLUTE:
|
||||
/* No relocation required */
|
||||
break;
|
||||
case PECOFF_IMAGE_REL_BASED_DIR64:
|
||||
/* 64-bit relocation */
|
||||
LongPtr = (PULONGLONG)((PUCHAR)Address + Offset);
|
||||
*LongPtr = *LongPtr - ImageBase + (UINT_PTR)Image->VirtualAddress;
|
||||
break;
|
||||
case PECOFF_IMAGE_REL_BASED_HIGHLOW:
|
||||
/* 32-bit relocation of hight and low half of address */
|
||||
ShortPtr = (PUINT)((PUCHAR)Address + Offset);
|
||||
*ShortPtr = *ShortPtr - ImageBase + (UINT_PTR)Image->VirtualAddress;
|
||||
break;
|
||||
default:
|
||||
/* Unknown or unsupported relocation type */
|
||||
return STATUS_EFI_UNSUPPORTED;
|
||||
}
|
||||
}
|
||||
/* Increment the type offset */
|
||||
TypeOffset++;
|
||||
}
|
||||
|
||||
/* Next relocation */
|
||||
RelocationDir = (PPECOFF_IMAGE_BASE_RELOCATION)((PUCHAR)RelocationDir + RelocationDir->SizeOfBlock);
|
||||
}
|
||||
|
||||
/* Return SUCCESS */
|
||||
return STATUS_EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unloads a PE/COFF image file and frees allocated memory.
|
||||
*
|
||||
@@ -632,13 +817,13 @@ PeRelocateImage(IN PVOID ImagePointer,
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
PeUnloadImage(IN PVOID ImagePointer)
|
||||
PeCoff::UnloadImage(IN PVOID ImagePointer)
|
||||
{
|
||||
PPECOFF_IMAGE_CONTEXT Image;
|
||||
EFI_STATUS Status;
|
||||
|
||||
/* Get PE/COFF image pointer*/
|
||||
Image = ImagePointer;
|
||||
Image = (PPECOFF_IMAGE_CONTEXT)ImagePointer;
|
||||
|
||||
/* Validate input data */
|
||||
if(!Image || !Image->Data)
|
||||
@@ -667,9 +852,12 @@ PeUnloadImage(IN PVOID ImagePointer)
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
PeVerifyImage(IN PVOID ImagePointer)
|
||||
PeCoff::VerifyImage(IN PVOID ImagePointer)
|
||||
{
|
||||
PPECOFF_IMAGE_CONTEXT Image = ImagePointer;
|
||||
PPECOFF_IMAGE_CONTEXT Image;
|
||||
|
||||
/* Get PE/COFF image pointer*/
|
||||
Image = (PPECOFF_IMAGE_CONTEXT)ImagePointer;
|
||||
|
||||
/* Validate input data */
|
||||
if(!Image || !Image->PeHeader)
|
||||
@@ -712,130 +900,6 @@ PeVerifyImage(IN PVOID ImagePointer)
|
||||
return STATUS_EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Relocates a loaded PE/COFF image.
|
||||
*
|
||||
* @param Image
|
||||
* Supplies a pointer to the PE/COFF context structure representing the loaded image.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
PepRelocateLoadedImage(IN PPECOFF_IMAGE_CONTEXT Image)
|
||||
{
|
||||
PPECOFF_IMAGE_BASE_RELOCATION RelocationDir, RelocationEnd;
|
||||
PPECOFF_IMAGE_DATA_DIRECTORY DataDirectory;
|
||||
USHORT Offset, Type, Count;
|
||||
PUSHORT TypeOffset;
|
||||
UINT64 ImageBase;
|
||||
PUINT32 Address;
|
||||
PUINT64 LongPtr;
|
||||
PUINT ShortPtr;
|
||||
|
||||
/* Make sure image is not stripped */
|
||||
if(Image->PeHeader->FileHeader.Characteristics & PECOFF_IMAGE_FILE_RELOCS_STRIPPED)
|
||||
{
|
||||
/* No relocation information found */
|
||||
XtLdrProtocol->Debug.Print(L"WARNING: PE/COFF image is stripped and contains no information about relocations\n");
|
||||
return STATUS_EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/* Check PE/COFF image type */
|
||||
if(Image->PeHeader->OptionalHeader32.Magic == PECOFF_IMAGE_PE_OPTIONAL_HDR64_MAGIC)
|
||||
{
|
||||
/* Set relocation data directory and image base address */
|
||||
DataDirectory = &Image->PeHeader->OptionalHeader64.DataDirectory[PECOFF_IMAGE_DIRECTORY_ENTRY_BASERELOC];
|
||||
ImageBase = Image->PeHeader->OptionalHeader64.ImageBase;
|
||||
|
||||
/* Check if loaded 64-bit PE32+ image should be relocated */
|
||||
if(Image->PeHeader->OptionalHeader64.NumberOfRvaAndSizes <= PECOFF_IMAGE_DIRECTORY_ENTRY_BASERELOC ||
|
||||
DataDirectory->VirtualAddress == 0 || DataDirectory->Size < sizeof(PECOFF_IMAGE_BASE_RELOCATION))
|
||||
{
|
||||
/* No need to relocate the image */
|
||||
return STATUS_EFI_SUCCESS;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Check if loaded 32-bit PE32 image should be relocated */
|
||||
/* Set relocation data directory and image base address */
|
||||
DataDirectory = &Image->PeHeader->OptionalHeader32.DataDirectory[PECOFF_IMAGE_DIRECTORY_ENTRY_BASERELOC];
|
||||
ImageBase = Image->PeHeader->OptionalHeader32.ImageBase;
|
||||
|
||||
if(Image->PeHeader->OptionalHeader32.NumberOfRvaAndSizes <= PECOFF_IMAGE_DIRECTORY_ENTRY_BASERELOC ||
|
||||
DataDirectory->VirtualAddress == 0 || DataDirectory->Size < sizeof(PECOFF_IMAGE_BASE_RELOCATION))
|
||||
{
|
||||
/* No need to relocate the image */
|
||||
return STATUS_EFI_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
/* Set relocation pointers */
|
||||
RelocationDir = (PPECOFF_IMAGE_BASE_RELOCATION)((ULONG_PTR)Image->Data + DataDirectory->VirtualAddress);
|
||||
RelocationEnd = (PPECOFF_IMAGE_BASE_RELOCATION)((ULONG_PTR)RelocationDir + DataDirectory->Size);
|
||||
|
||||
/* Do relocations */
|
||||
while(RelocationDir < RelocationEnd && RelocationDir->SizeOfBlock > 0)
|
||||
{
|
||||
/* Calculate number of relocations needed, address and type offset */
|
||||
Count = (RelocationDir->SizeOfBlock - sizeof(PECOFF_IMAGE_BASE_RELOCATION)) / sizeof(USHORT);
|
||||
Address = (PUINT)((PUCHAR)Image->Data + RelocationDir->VirtualAddress);
|
||||
TypeOffset = (PUSHORT)((PUCHAR)RelocationDir + sizeof(PECOFF_IMAGE_BASE_RELOCATION));
|
||||
|
||||
/* Do relocations */
|
||||
while(Count--)
|
||||
{
|
||||
/* Calculate offset and relocation type */
|
||||
Offset = *TypeOffset & 0xFFF;
|
||||
Type = *TypeOffset >> 12;
|
||||
|
||||
/* Check if end of the loaded address reached */
|
||||
if((PVOID)(PUSHORT)(Address + Offset) >= Image->Data + Image->ImageSize)
|
||||
{
|
||||
/* Do not relocate after the end of loaded image */
|
||||
break;
|
||||
}
|
||||
|
||||
/* Make sure we are not going to relocate into .reloc section */
|
||||
if((ULONG_PTR)(Address + Offset) < (ULONG_PTR)RelocationDir ||
|
||||
(ULONG_PTR)(Address + Offset) >= (ULONG_PTR)RelocationEnd)
|
||||
{
|
||||
/* Apply relocation fixup */
|
||||
switch (Type)
|
||||
{
|
||||
case PECOFF_IMAGE_REL_BASED_ABSOLUTE:
|
||||
/* No relocation required */
|
||||
break;
|
||||
case PECOFF_IMAGE_REL_BASED_DIR64:
|
||||
/* 64-bit relocation */
|
||||
LongPtr = (PULONGLONG)((PUCHAR)Address + Offset);
|
||||
*LongPtr = *LongPtr - ImageBase + (UINT_PTR)Image->VirtualAddress;
|
||||
break;
|
||||
case PECOFF_IMAGE_REL_BASED_HIGHLOW:
|
||||
/* 32-bit relocation of hight and low half of address */
|
||||
ShortPtr = (PUINT32)((PUCHAR)Address + Offset);
|
||||
*ShortPtr = *ShortPtr - ImageBase + (UINT_PTR)Image->VirtualAddress;
|
||||
break;
|
||||
default:
|
||||
/* Unknown or unsupported relocation type */
|
||||
return STATUS_EFI_UNSUPPORTED;
|
||||
}
|
||||
}
|
||||
/* Increment the type offset */
|
||||
TypeOffset++;
|
||||
}
|
||||
|
||||
/* Next relocation */
|
||||
RelocationDir = (PPECOFF_IMAGE_BASE_RELOCATION)((PUCHAR)RelocationDir + RelocationDir->SizeOfBlock);
|
||||
}
|
||||
|
||||
/* Return SUCCESS */
|
||||
return STATUS_EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* This routine is the entry point of the XT EFI boot loader module.
|
||||
*
|
||||
@@ -854,30 +918,6 @@ EFI_STATUS
|
||||
XtLdrModuleMain(IN EFI_HANDLE ImageHandle,
|
||||
IN PEFI_SYSTEM_TABLE SystemTable)
|
||||
{
|
||||
EFI_GUID Guid = XT_PECOFF_IMAGE_PROTOCOL_GUID;
|
||||
EFI_STATUS Status;
|
||||
|
||||
/* Open the XTLDR protocol */
|
||||
Status = BlGetXtLdrProtocol(SystemTable, ImageHandle, &XtLdrProtocol);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Failed to open loader protocol */
|
||||
return STATUS_EFI_PROTOCOL_ERROR;
|
||||
}
|
||||
|
||||
/* Set routines available via PE/COFF image protocol */
|
||||
PeCoffProtocol.GetEntryPoint = PeGetEntryPoint;
|
||||
PeCoffProtocol.GetFileSize = PeGetFileSize;
|
||||
PeCoffProtocol.GetImageSize = PeGetImageSize;
|
||||
PeCoffProtocol.GetMachineType = PeGetMachineType;
|
||||
PeCoffProtocol.GetSection = PeGetSection;
|
||||
PeCoffProtocol.GetSubSystem = PeGetSubSystem;
|
||||
PeCoffProtocol.GetVersion = PeGetVersion;
|
||||
PeCoffProtocol.LoadImage = PeLoadImage;
|
||||
PeCoffProtocol.RelocateImage = PeRelocateImage;
|
||||
PeCoffProtocol.UnloadImage = PeUnloadImage;
|
||||
PeCoffProtocol.VerifyImage = PeVerifyImage;
|
||||
|
||||
/* Register PE/COFF protocol */
|
||||
return XtLdrProtocol->Protocol.Install(&PeCoffProtocol, &Guid);
|
||||
/* Initialize PECOFF module */
|
||||
return PeCoff::InitializeModule(ImageHandle, SystemTable);
|
||||
}
|
||||
+3
-2
@@ -8,8 +8,9 @@ include_directories(
|
||||
|
||||
# Specify list of source code files
|
||||
list(APPEND XTLDR_XTOS_O_SOURCE
|
||||
${XTLDR_XTOS_O_SOURCE_DIR}/${ARCH}/memory.c
|
||||
${XTLDR_XTOS_O_SOURCE_DIR}/xtos.c)
|
||||
${XTLDR_XTOS_O_SOURCE_DIR}/${ARCH}/memory.cc
|
||||
${XTLDR_XTOS_O_SOURCE_DIR}/data.cc
|
||||
${XTLDR_XTOS_O_SOURCE_DIR}/xtos.cc)
|
||||
|
||||
# Link bootloader executable
|
||||
add_executable(xtos_o ${XTLDR_XTOS_O_SOURCE})
|
||||
@@ -0,0 +1,336 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: xtldr/amd64/memory.cc
|
||||
* DESCRIPTION: EFI memory management for AMD64 target
|
||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||
* Aiken Harris <harraiken91@gmail.com>
|
||||
*/
|
||||
|
||||
#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.
|
||||
*
|
||||
* @param Parameters
|
||||
* A pointer to the wide character string containing the kernel boot parameters.
|
||||
*
|
||||
* @return This routine returns the appropriate page map level (5 if LA57 is enabled, 4 otherwise).
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
ULONG
|
||||
Xtos::DeterminePagingLevel(IN CONST PWCHAR Parameters)
|
||||
{
|
||||
CPUID_REGISTERS CpuRegisters;
|
||||
|
||||
/* Prepare CPUID registers to query for STD7 features */
|
||||
XtLdrProtocol->Memory.ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
|
||||
CpuRegisters.Leaf = CPUID_GET_VENDOR_STRING;
|
||||
|
||||
/* Query CPUID */
|
||||
XtLdrProtocol->Cpu.CpuId(&CpuRegisters);
|
||||
|
||||
/* Verify if the CPU supports the STD7 feature leaf (0x00000007) */
|
||||
if(CpuRegisters.Eax >= CPUID_GET_STANDARD7_FEATURES)
|
||||
{
|
||||
/* Prepare CPUID registers to query for LA57 support */
|
||||
XtLdrProtocol->Memory.ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
|
||||
CpuRegisters.Leaf = CPUID_GET_STANDARD7_FEATURES;
|
||||
|
||||
/* Query CPUID */
|
||||
XtLdrProtocol->Cpu.CpuId(&CpuRegisters);
|
||||
|
||||
/* Check if eXtended Physical Addressing (XPA) is enabled and if LA57 is supported by the CPU */
|
||||
if((CpuRegisters.Ecx & CPUID_FEATURES_ECX_LA57) &&
|
||||
!(XtLdrProtocol->BootUtils.GetBooleanParameter(Parameters, L"NOXPA")))
|
||||
{
|
||||
/* Enable LA57 (PML5) */
|
||||
return 5;
|
||||
}
|
||||
}
|
||||
|
||||
/* Disable LA57 and use PML4 by default */
|
||||
return 4;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the actual memory mapping page table and enables paging. This routine exits EFI boot services as well.
|
||||
*
|
||||
* @param PageMap
|
||||
* Supplies a pointer to the page mapping structure.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
Xtos::EnablePaging(IN PXTBL_PAGE_MAPPING PageMap)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_PHYSICAL_ADDRESS TrampolineAddress;
|
||||
PXT_TRAMPOLINE_ENTRY TrampolineEntry;
|
||||
ULONG TrampolineSize;
|
||||
PVOID TrampolineCode;
|
||||
|
||||
/* Check the configured page map level to set the LA57 state accordingly */
|
||||
if(PageMap->PageMapLevel == 5)
|
||||
{
|
||||
/* Get the trampoline code information */
|
||||
XtLdrProtocol->BootUtils.GetTrampolineInformation(TrampolineEnableXpa, &TrampolineCode, &TrampolineSize);
|
||||
if(TrampolineCode == NULLPTR || TrampolineSize == 0)
|
||||
{
|
||||
/* Failed to get trampoline information */
|
||||
XtLdrProtocol->Debug.Print(L"Failed to get trampoline information\n");
|
||||
return STATUS_EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
/* Set the address of the trampoline code below 1MB */
|
||||
TrampolineAddress = MM_TRAMPOLINE_ADDRESS;
|
||||
|
||||
/* Allocate pages for the trampoline */
|
||||
Status = XtLdrProtocol->Memory.AllocatePages(AllocateAddress, EFI_SIZE_TO_PAGES(TrampolineSize), &TrampolineAddress);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Failed to allocate memory for trampoline code */
|
||||
XtLdrProtocol->Debug.Print(L"Failed to allocate memory for trampoline code (Status code: %zX)\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Set the trampoline entry point and copy its code into the allocated buffer */
|
||||
TrampolineEntry = (PXT_TRAMPOLINE_ENTRY)(UINT_PTR)TrampolineAddress;
|
||||
XtLdrProtocol->Memory.CopyMemory((PVOID)TrampolineEntry, TrampolineCode, TrampolineSize);
|
||||
}
|
||||
|
||||
/* Exit EFI Boot Services */
|
||||
XtLdrProtocol->Debug.Print(L"Exiting EFI boot services\n");
|
||||
Status = XtLdrProtocol->Utils.ExitBootServices();
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Failed to exit boot services */
|
||||
XtLdrProtocol->Debug.Print(L"Failed to exit boot services (Status code: %zX)\n", Status);
|
||||
return STATUS_EFI_ABORTED;
|
||||
}
|
||||
|
||||
/* Check the configured page map level to set the LA57 state accordingly */
|
||||
if(PageMap->PageMapLevel == 5)
|
||||
{
|
||||
/* Enable Linear Address 57-bit (LA57) extension */
|
||||
XtLdrProtocol->Debug.Print(L"Enabling Linear Address 57-bit (LA57)\n");
|
||||
|
||||
/* Execute the trampoline to enable LA57 and write PML5 to CR3 */
|
||||
TrampolineEntry((UINT64)PageMap->PtePointer);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Disable Linear Address 57-bit (LA57) extension */
|
||||
XtLdrProtocol->Debug.Print(L"Disabling Linear Address 57-bit (LA57)\n");
|
||||
|
||||
/* Write PML4 to CR3 and enable paging */
|
||||
XtLdrProtocol->Cpu.WriteControlRegister(3, (UINT_PTR)PageMap->PtePointer);
|
||||
XtLdrProtocol->Cpu.WriteControlRegister(0, XtLdrProtocol->Cpu.ReadControlRegister(0) | CR0_PG);
|
||||
}
|
||||
|
||||
/* Return success */
|
||||
return STATUS_EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Maps the page table for hardware layer addess space.
|
||||
*
|
||||
* @param PageMap
|
||||
* Supplies a pointer to the page mapping structure.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
Xtos::MapHardwareMemoryPool(IN PXTBL_PAGE_MAPPING PageMap)
|
||||
{
|
||||
PHARDWARE_PTE P5eBase, PdeBase, PpeBase, PxeBase;
|
||||
EFI_PHYSICAL_ADDRESS Address;
|
||||
EFI_STATUS Status;
|
||||
ULONG Index;
|
||||
|
||||
if(PageMap->PageMapLevel == 5)
|
||||
{
|
||||
/* Get P5E (PML5) base address */
|
||||
P5eBase = (PHARDWARE_PTE)PageMap->PtePointer;
|
||||
|
||||
/* Check if P5E entry already exists */
|
||||
if(!P5eBase[(MM_HARDWARE_VA_START >> MM_P5I_SHIFT) & 0x1FF].Valid)
|
||||
{
|
||||
/* No valid P5E, allocate memory */
|
||||
Status = XtLdrProtocol->Memory.AllocatePages(AllocateAnyPages, 1, &Address);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Memory allocation failure, return error */
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Map hardware memory */
|
||||
XtLdrProtocol->Memory.MapVirtualMemory(PageMap, (ULONGLONG)NULLPTR, Address, 1, LoaderMemoryData);
|
||||
|
||||
/* Zero fill memory used by P5E */
|
||||
XtLdrProtocol->Memory.ZeroMemory((PVOID)Address, EFI_PAGE_SIZE);
|
||||
|
||||
/* Make P5E valid */
|
||||
P5eBase[(MM_HARDWARE_VA_START >> MM_P5I_SHIFT) & 0x1FF].Valid = 1;
|
||||
P5eBase[(MM_HARDWARE_VA_START >> MM_P5I_SHIFT) & 0x1FF].PageFrameNumber = Address / EFI_PAGE_SIZE;
|
||||
P5eBase[(MM_HARDWARE_VA_START >> MM_P5I_SHIFT) & 0x1FF].Writable = 1;
|
||||
|
||||
/* Set PXE base address */
|
||||
PxeBase = (PHARDWARE_PTE)(UINT_PTR)Address;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Set PXE base address based on existing P5E */
|
||||
PxeBase = (PHARDWARE_PTE)((P5eBase[(MM_HARDWARE_VA_START >> MM_P5I_SHIFT) & 0x1FF].PageFrameNumber) << EFI_PAGE_SHIFT);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Get PXE (PML4) base address */
|
||||
PxeBase = (PHARDWARE_PTE)PageMap->PtePointer;
|
||||
}
|
||||
|
||||
/* Check if PXE entry already exists */
|
||||
if(!PxeBase[(MM_HARDWARE_VA_START >> MM_PXI_SHIFT) & 0x1FF].Valid)
|
||||
{
|
||||
/* No valid PXE, allocate memory */
|
||||
Status = XtLdrProtocol->Memory.AllocatePages(AllocateAnyPages, 1, &Address);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Memory allocation failure, return error */
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Map hardware memory */
|
||||
XtLdrProtocol->Memory.MapVirtualMemory(PageMap, (ULONGLONG)NULLPTR, Address, 1, LoaderMemoryData);
|
||||
|
||||
/* Zero fill memory used by PXE */
|
||||
XtLdrProtocol->Memory.ZeroMemory((PVOID)Address, EFI_PAGE_SIZE);
|
||||
|
||||
/* Make PXE valid */
|
||||
PxeBase[(MM_HARDWARE_VA_START >> MM_PXI_SHIFT) & 0x1FF].Valid = 1;
|
||||
PxeBase[(MM_HARDWARE_VA_START >> MM_PXI_SHIFT) & 0x1FF].PageFrameNumber = Address / EFI_PAGE_SIZE;
|
||||
PxeBase[(MM_HARDWARE_VA_START >> MM_PXI_SHIFT) & 0x1FF].Writable = 1;
|
||||
|
||||
/* Set PPE base address */
|
||||
PpeBase = (PHARDWARE_PTE)(UINT_PTR)Address;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Set PPE base address based on existing PXE */
|
||||
PpeBase = (PHARDWARE_PTE)((PxeBase[(MM_HARDWARE_VA_START >> MM_PXI_SHIFT) & 0x1FF].PageFrameNumber) << EFI_PAGE_SHIFT);
|
||||
}
|
||||
|
||||
/* Check if PPE entry already exists */
|
||||
if(!PpeBase[(MM_HARDWARE_VA_START >> MM_PPI_SHIFT) & 0x1FF].Valid)
|
||||
{
|
||||
/* No valid PPE, allocate memory */
|
||||
Status = XtLdrProtocol->Memory.AllocatePages(AllocateAnyPages, 1, &Address);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Memory allocation failure, return error */
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Map hardware memory */
|
||||
XtLdrProtocol->Memory.MapVirtualMemory(PageMap, (ULONGLONG)NULLPTR, Address, 1, LoaderMemoryData);
|
||||
|
||||
/* Zero fill memory used by PPE */
|
||||
XtLdrProtocol->Memory.ZeroMemory((PVOID)Address, EFI_PAGE_SIZE);
|
||||
|
||||
/* Make PPE valid */
|
||||
PpeBase[(MM_HARDWARE_VA_START >> MM_PPI_SHIFT) & 0x1FF].Valid = 1;
|
||||
PpeBase[(MM_HARDWARE_VA_START >> MM_PPI_SHIFT) & 0x1FF].PageFrameNumber = Address / EFI_PAGE_SIZE;
|
||||
PpeBase[(MM_HARDWARE_VA_START >> MM_PPI_SHIFT) & 0x1FF].Writable = 1;
|
||||
|
||||
/* Set PDE base address */
|
||||
PdeBase = (PHARDWARE_PTE)Address;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Set PDE base address, based on existing PPE */
|
||||
PdeBase = (PHARDWARE_PTE)((PpeBase[(MM_HARDWARE_VA_START >> MM_PPI_SHIFT) & 0x1FF].PageFrameNumber) << EFI_PAGE_SHIFT);
|
||||
}
|
||||
|
||||
/* Loop through 2 PDE entries */
|
||||
for(Index = 0 ; Index < 2 ; Index++)
|
||||
{
|
||||
/* Check if PDE entry already exists */
|
||||
if(!PdeBase[((MM_HARDWARE_VA_START >> MM_PDI_SHIFT) & 0x1FF) + Index].Valid)
|
||||
{
|
||||
/* No valid PDE, allocate memory */
|
||||
Status = XtLdrProtocol->Memory.AllocatePages(AllocateAnyPages, 1, &Address);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Memory allocation failure, return error */
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Map hardware memory */
|
||||
XtLdrProtocol->Memory.MapVirtualMemory(PageMap, (ULONGLONG)NULLPTR, Address, 1, LoaderMemoryData);
|
||||
|
||||
/* Zero fill memory used by PDE */
|
||||
XtLdrProtocol->Memory.ZeroMemory((PVOID)Address, EFI_PAGE_SIZE);
|
||||
|
||||
/* Make PDE valid */
|
||||
PdeBase[((MM_HARDWARE_VA_START >> MM_PDI_SHIFT) & 0x1FF) + Index].Valid = 1;
|
||||
PdeBase[((MM_HARDWARE_VA_START >> MM_PDI_SHIFT) & 0x1FF) + Index].PageFrameNumber = Address / EFI_PAGE_SIZE;
|
||||
PdeBase[((MM_HARDWARE_VA_START >> MM_PDI_SHIFT) & 0x1FF) + Index].Writable = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Return success */
|
||||
return STATUS_EFI_SUCCESS;
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: xtldr/modules/xtos/data.cc
|
||||
* DESCRIPTION: XTOS module global and static data
|
||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||
*/
|
||||
|
||||
#include <xtos.hh>
|
||||
|
||||
|
||||
/* XTOS Boot Protocol */
|
||||
XTBL_BOOT_PROTOCOL Xtos::BootProtocol;
|
||||
|
||||
/* XTOS PE/COFF Image Protocol */
|
||||
PXTBL_EXECUTABLE_IMAGE_PROTOCOL Xtos::PeCoffProtocol;
|
||||
|
||||
/* EFI XT Loader Protocol */
|
||||
PXTBL_LOADER_PROTOCOL Xtos::XtLdrProtocol;
|
||||
@@ -0,0 +1,222 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: xtldr/i686/memory.cc
|
||||
* DESCRIPTION: EFI memory management for i686 target
|
||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||
*/
|
||||
|
||||
#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.
|
||||
*
|
||||
* @param Parameters
|
||||
* A pointer to the wide character string containing the kernel boot parameters.
|
||||
*
|
||||
* @return This routine returns the appropriate page map level (3 if PAE is enabled, 2 otherwise).
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
ULONG
|
||||
Xtos::DeterminePagingLevel(IN CONST PWCHAR Parameters)
|
||||
{
|
||||
CPUID_REGISTERS CpuRegisters;
|
||||
|
||||
/* Prepare CPUID registers to query for PAE support */
|
||||
XtLdrProtocol->Memory.ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
|
||||
CpuRegisters.Leaf = CPUID_GET_STANDARD1_FEATURES;
|
||||
|
||||
/* Query CPUID */
|
||||
XtLdrProtocol->Cpu.CpuId(&CpuRegisters);
|
||||
|
||||
/* Check if eXtended Physical Addressing (XPA) is enabled and if PAE is supported by the CPU */
|
||||
if((CpuRegisters.Edx & CPUID_FEATURES_EDX_PAE) &&
|
||||
!(XtLdrProtocol->BootUtils.GetBooleanParameter(Parameters, L"NOXPA")))
|
||||
{
|
||||
/* Enable PAE (PML3) */
|
||||
return 3;
|
||||
}
|
||||
|
||||
/* Disable PAE and use PML2 by default */
|
||||
return 2;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the actual memory mapping page table and enables paging. This routine exits EFI boot services as well.
|
||||
*
|
||||
* @param PageMap
|
||||
* Supplies a pointer to the page mapping structure.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
Xtos::EnablePaging(IN PXTBL_PAGE_MAPPING PageMap)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
|
||||
/* Exit EFI Boot Services */
|
||||
XtLdrProtocol->Debug.Print(L"Exiting EFI boot services\n");
|
||||
Status = XtLdrProtocol->Utils.ExitBootServices();
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Failed to exit boot services */
|
||||
XtLdrProtocol->Debug.Print(L"Failed to exit boot services (Status code: %zX)\n", Status);
|
||||
return STATUS_EFI_ABORTED;
|
||||
}
|
||||
|
||||
/* Disable paging */
|
||||
XtLdrProtocol->Cpu.WriteControlRegister(0, XtLdrProtocol->Cpu.ReadControlRegister(0) & ~CR0_PG);
|
||||
|
||||
/* Check the configured page map level to set the PAE state accordingly */
|
||||
if(PageMap->PageMapLevel == 3)
|
||||
{
|
||||
/* Enable Physical Address Extension (PAE) */
|
||||
XtLdrProtocol->Debug.Print(L"Enabling Physical Address Extension (PAE)\n");
|
||||
XtLdrProtocol->Cpu.WriteControlRegister(4, XtLdrProtocol->Cpu.ReadControlRegister(4) | CR4_PAE);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Disable Physical Address Extension (PAE) */
|
||||
XtLdrProtocol->Debug.Print(L"Disabling Physical Address Extension (PAE)\n");
|
||||
XtLdrProtocol->Cpu.WriteControlRegister(4, XtLdrProtocol->Cpu.ReadControlRegister(4) & ~CR4_PAE);
|
||||
}
|
||||
|
||||
/* Write page mappings to CR3 */
|
||||
XtLdrProtocol->Cpu.WriteControlRegister(3, (UINT_PTR)PageMap->PtePointer);
|
||||
|
||||
/* Enable paging */
|
||||
XtLdrProtocol->Cpu.WriteControlRegister(0, XtLdrProtocol->Cpu.ReadControlRegister(0) | CR0_PG);
|
||||
|
||||
/* Return success */
|
||||
return STATUS_EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Maps the page table for hardware layer addess space.
|
||||
*
|
||||
* @param PageMap
|
||||
* Supplies a pointer to the page mapping structure.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
Xtos::MapHardwareMemoryPool(IN PXTBL_PAGE_MAPPING PageMap)
|
||||
{
|
||||
EFI_PHYSICAL_ADDRESS Address;
|
||||
PHARDWARE_LEGACY_PTE LegacyPdeBase;
|
||||
PHARDWARE_MODERN_PTE PdeBase;
|
||||
EFI_STATUS Status;
|
||||
|
||||
/* Allocate memory */
|
||||
Status = XtLdrProtocol->Memory.AllocatePages(AllocateAnyPages, 1, &Address);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Memory allocation failure, return error */
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Zero fill allocated memory */
|
||||
XtLdrProtocol->Memory.ZeroMemory((PVOID)Address, EFI_PAGE_SIZE);
|
||||
|
||||
/* Map hardware memory */
|
||||
XtLdrProtocol->Memory.MapVirtualMemory(PageMap, (ULONGLONG)NULLPTR, Address, 1, LoaderMemoryData);
|
||||
|
||||
/* Check if PAE is enabled (3-level paging) */
|
||||
if(PageMap->PageMapLevel == 3)
|
||||
{
|
||||
/* Get PDE base address (PAE enabled) */
|
||||
PdeBase = (PHARDWARE_MODERN_PTE)(((PHARDWARE_MODERN_PTE)PageMap->PtePointer)[MM_HARDWARE_VA_START >> MM_PPI_SHIFT].PageFrameNumber << MM_PAGE_SHIFT);
|
||||
|
||||
/* Make PDE valid */
|
||||
XtLdrProtocol->Memory.ZeroMemory(&PdeBase[(MM_HARDWARE_VA_START >> MM_PDI_SHIFT) & 0x1FF], sizeof(HARDWARE_MODERN_PTE));
|
||||
PdeBase[(MM_HARDWARE_VA_START >> MM_PDI_SHIFT) & 0x1FF].PageFrameNumber = Address >> MM_PAGE_SHIFT;
|
||||
PdeBase[(MM_HARDWARE_VA_START >> MM_PDI_SHIFT) & 0x1FF].Valid = 1;
|
||||
PdeBase[(MM_HARDWARE_VA_START >> MM_PDI_SHIFT) & 0x1FF].Writable = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Get PDE base address (PAE disabled) */
|
||||
LegacyPdeBase = (PHARDWARE_LEGACY_PTE)PageMap->PtePointer;
|
||||
|
||||
/* Check for a conflicting PDE */
|
||||
if(LegacyPdeBase[MM_HARDWARE_VA_START >> MM_PDI_LEGACY_SHIFT].Valid)
|
||||
{
|
||||
/* PDE already exists and is valid, nothing to do */
|
||||
return STATUS_EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/* Make PDE valid */
|
||||
XtLdrProtocol->Memory.ZeroMemory(&LegacyPdeBase[MM_HARDWARE_VA_START >> MM_PDI_LEGACY_SHIFT], sizeof(HARDWARE_LEGACY_PTE));
|
||||
LegacyPdeBase[MM_HARDWARE_VA_START >> MM_PDI_LEGACY_SHIFT].Valid = 1;
|
||||
LegacyPdeBase[MM_HARDWARE_VA_START >> MM_PDI_LEGACY_SHIFT].PageFrameNumber = Address >> MM_PAGE_SHIFT;
|
||||
LegacyPdeBase[MM_HARDWARE_VA_START >> MM_PDI_LEGACY_SHIFT].Writable = 1;
|
||||
}
|
||||
|
||||
/* Return success */
|
||||
return STATUS_EFI_SUCCESS;
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: xtldr/modules/xtos/includes/xtos.hh
|
||||
* DESCRIPTION: XTOS boot protocol support header
|
||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||
*/
|
||||
|
||||
#ifndef __XTLDR_MODULES_XTOS_HH
|
||||
#define __XTLDR_MODULES_XTOS_HH
|
||||
|
||||
#include <xtblapi.h>
|
||||
|
||||
|
||||
/* XTOS kernel entry point */
|
||||
typedef VOID (XTAPI *PXT_ENTRY_POINT)(IN PKERNEL_INITIALIZATION_BLOCK BootParameters);
|
||||
|
||||
/* XTOS trampoline entry point */
|
||||
typedef VOID (*PXT_TRAMPOLINE_ENTRY)(UINT64 PageMap);
|
||||
|
||||
|
||||
/* XTOS module for XTLDR */
|
||||
class Xtos
|
||||
{
|
||||
private:
|
||||
STATIC XTBL_BOOT_PROTOCOL BootProtocol;
|
||||
STATIC PXTBL_EXECUTABLE_IMAGE_PROTOCOL PeCoffProtocol;
|
||||
STATIC PXTBL_LOADER_PROTOCOL XtLdrProtocol;
|
||||
|
||||
public:
|
||||
STATIC XTCDECL EFI_STATUS BootSystem(IN PXTBL_BOOT_PARAMETERS Parameters);
|
||||
STATIC XTCDECL EFI_STATUS InitializeModule(IN EFI_HANDLE ImageHandle,
|
||||
IN PEFI_SYSTEM_TABLE SystemTable);
|
||||
|
||||
private:
|
||||
STATIC XTCDECL EFI_STATUS AddVirtualMemoryMapping(IN PLIST_ENTRY MemoryMappings,
|
||||
IN PVOID VirtualAddress,
|
||||
IN PVOID PhysicalAddress,
|
||||
IN UINT NumberOfPages,
|
||||
IN LOADER_MEMORY_TYPE MemoryType);
|
||||
STATIC XTCDECL EFI_STATUS BuildPageMap(IN PXTBL_PAGE_MAPPING PageMap);
|
||||
STATIC XTCDECL LOADER_MEMORY_TYPE ConvertEfiMemoryType(IN EFI_MEMORY_TYPE EfiMemoryType);
|
||||
STATIC XTCDECL BOOLEAN DetermineMappingStrategy();
|
||||
STATIC XTCDECL ULONG DeterminePagingLevel(IN CONST PWCHAR Parameters);
|
||||
STATIC XTCDECL EFI_STATUS EnablePaging(IN PXTBL_PAGE_MAPPING PageMap);
|
||||
STATIC XTCDECL VOID GetDisplayInformation(OUT PSYSTEM_RESOURCE_FRAMEBUFFER FrameBufferResource,
|
||||
IN PEFI_PHYSICAL_ADDRESS FrameBufferBase,
|
||||
IN PULONG_PTR FrameBufferSize,
|
||||
IN PXTBL_FRAMEBUFFER_MODE_INFORMATION FrameBufferModeInfo);
|
||||
STATIC XTCDECL EFI_STATUS GetMemoryDescriptorList(IN PXTBL_PAGE_MAPPING PageMap,
|
||||
IN EFI_PHYSICAL_ADDRESS PhysicalBase,
|
||||
IN PVOID VirtualBase,
|
||||
OUT PLIST_ENTRY MemoryDescriptorList);
|
||||
STATIC XTCDECL EFI_STATUS GetSystemResourcesList(IN PXTBL_PAGE_MAPPING PageMap,
|
||||
IN EFI_PHYSICAL_ADDRESS PhysicalBase,
|
||||
IN PVOID VirtualBase,
|
||||
IN PVOID FrameBufferVirtualBase,
|
||||
OUT PLIST_ENTRY SystemResourcesList);
|
||||
STATIC XTCDECL EFI_STATUS GetVirtualAddress(IN PLIST_ENTRY MemoryMappings,
|
||||
IN PVOID PhysicalAddress,
|
||||
OUT PVOID *VirtualAddress);
|
||||
STATIC XTCDECL EFI_STATUS InitializeApicBase(IN PXTBL_PAGE_MAPPING PageMap);
|
||||
STATIC XTCDECL EFI_STATUS InitializeLoaderBlock(IN PXTBL_PAGE_MAPPING PageMap,
|
||||
IN PVOID *VirtualAddress,
|
||||
IN PXTBL_BOOT_PARAMETERS Parameters);
|
||||
STATIC XTCDECL EFI_STATUS InitializeVirtualMemory(IN OUT PLIST_ENTRY MemoryMappings,
|
||||
IN OUT PVOID *MemoryMapAddress);
|
||||
STATIC XTCDECL EFI_STATUS LoadModule(IN PEFI_FILE_HANDLE BootDir,
|
||||
IN PWCHAR FileName,
|
||||
IN PVOID VirtualAddress,
|
||||
IN LOADER_MEMORY_TYPE MemoryType,
|
||||
OUT PPECOFF_IMAGE_CONTEXT *ImageContext);
|
||||
STATIC XTCDECL EFI_STATUS MapHardwareMemoryPool(IN PXTBL_PAGE_MAPPING PageMap);
|
||||
STATIC XTCDECL EFI_STATUS MapVirtualMemory(IN PLIST_ENTRY MemoryMappings,
|
||||
IN UINT_PTR VirtualAddress,
|
||||
IN UINT_PTR PhysicalAddress,
|
||||
IN UINT NumberOfPages,
|
||||
IN OUT PVOID *PtePointer);
|
||||
STATIC XTCDECL EFI_STATUS RunBootSequence(IN PEFI_FILE_HANDLE BootDir,
|
||||
IN PXTBL_BOOT_PARAMETERS Parameters);
|
||||
};
|
||||
|
||||
#endif /* __XTLDR_MODULES_XTOS_HH */
|
||||
@@ -0,0 +1,787 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: xtldr/modules/xtos/xtos.cc
|
||||
* DESCRIPTION: XTOS boot protocol support
|
||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||
*/
|
||||
|
||||
#include <xtos.hh>
|
||||
|
||||
|
||||
/* XTOS module information */
|
||||
MODULE_AUTHOR(L"Rafal Kupiec <belliash@codingworkshop.eu.org>");
|
||||
MODULE_DESCRIPTION(L"XTOS boot protocol support");
|
||||
MODULE_DEPENDENCY(L"acpi framebuf pecoff");
|
||||
MODULE_LICENSE(L"GPLv3");
|
||||
MODULE_VERSION(L"0.1");
|
||||
|
||||
|
||||
/**
|
||||
* Starts the operating system according to the provided parameters using XTOS boot protocol.
|
||||
*
|
||||
* @param Parameters
|
||||
* Input parameters with detailed system configuration like boot device or kernel path.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
Xtos::BootSystem(IN PXTBL_BOOT_PARAMETERS Parameters)
|
||||
{
|
||||
EFI_GUID PeCoffProtocolGuid = XT_PECOFF_IMAGE_PROTOCOL_GUID;
|
||||
EFI_HANDLE DiskHandle, ProtocolHandle;
|
||||
PEFI_FILE_HANDLE FsHandle, BootDir;
|
||||
PWCHAR SystemPath;
|
||||
EFI_STATUS Status;
|
||||
|
||||
/* Print debug message */
|
||||
XtLdrProtocol->Debug.Print(L"XTOS boot protocol activated\n");
|
||||
|
||||
/* Open the XT PE/COFF protocol */
|
||||
Status = XtLdrProtocol->Protocol.Open(&ProtocolHandle, (PVOID *)&PeCoffProtocol, &PeCoffProtocolGuid);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Failed to open loader protocol */
|
||||
XtLdrProtocol->Debug.Print(L"ERROR: Unable to load PE/COFF image protocol\n");
|
||||
return STATUS_EFI_PROTOCOL_ERROR;
|
||||
}
|
||||
|
||||
/* Check device path */
|
||||
if(Parameters->DevicePath == NULLPTR)
|
||||
{
|
||||
/* No device path set */
|
||||
XtLdrProtocol->Debug.Print(L"ERROR: No device path provided, unable to boot system\n");
|
||||
return STATUS_EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
/* Check if system path is set */
|
||||
if(Parameters->SystemPath != NULLPTR)
|
||||
{
|
||||
/* Make sure system path begins with backslash, the only separator supported by EFI */
|
||||
if(Parameters->SystemPath[0] == '/')
|
||||
{
|
||||
/* Replace directory separator if needed */
|
||||
Parameters->SystemPath[0] = '\\';
|
||||
}
|
||||
|
||||
/* Validate system path */
|
||||
SystemPath = &Parameters->SystemPath[1];
|
||||
while(*SystemPath)
|
||||
{
|
||||
/* Make sure it does not point to any subdirectory and not contains special characters */
|
||||
if(((*SystemPath | 32) - 'a' >= 26) && ((*SystemPath - '0') >= 10))
|
||||
{
|
||||
/* Invalid path specified */
|
||||
XtLdrProtocol->Debug.Print(L"ERROR: System path does not point to the valid XTOS installation\n");
|
||||
return STATUS_EFI_INVALID_PARAMETER;
|
||||
}
|
||||
/* Check next character in the path */
|
||||
SystemPath++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Fallback to '/ExectOS' by default */
|
||||
XtLdrProtocol->Debug.Print(L"WARNING: No system path set, falling back to defaults\n");
|
||||
Parameters->SystemPath = (PWCHAR)L"\\ExectOS";
|
||||
}
|
||||
|
||||
/* Check if kernel file is set */
|
||||
if(Parameters->KernelFile == NULLPTR)
|
||||
{
|
||||
/* No kernel filename set, fallback to default */
|
||||
XtLdrProtocol->Debug.Print(L"WARNING: No kernel file specified, falling back to defaults\n");
|
||||
Parameters->KernelFile = (PWCHAR)L"xtoskrnl.exe";
|
||||
}
|
||||
|
||||
/* Check if provided any kernel boot arguments */
|
||||
if(Parameters->Parameters == NULLPTR)
|
||||
{
|
||||
/* No argument supplied */
|
||||
Parameters->Parameters = (PWCHAR)L"";
|
||||
}
|
||||
|
||||
/* Print a debug message */
|
||||
XtLdrProtocol->Debug.Print(L"[XTOS] ARC Path: %S\n"
|
||||
L"[XTOS] System Path: %S\n"
|
||||
L"[XTOS] Kernel File: %S\n"
|
||||
L"[XTOS] Boot Arguments: %S\n",
|
||||
Parameters->ArcName, Parameters->SystemPath,
|
||||
Parameters->KernelFile, Parameters->Parameters);
|
||||
|
||||
/* Open EFI volume */
|
||||
Status = XtLdrProtocol->Disk.OpenVolume(Parameters->DevicePath, &DiskHandle, &FsHandle);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Failed to open a volume */
|
||||
XtLdrProtocol->Debug.Print(L"ERROR: Unable to open boot volume\n");
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* System path has to point to the boot directory */
|
||||
XtLdrProtocol->WideString.Concatenate(Parameters->SystemPath, (PWCHAR)L"\\Boot", 0);
|
||||
|
||||
/* Open XTOS system boot directory */
|
||||
Status = FsHandle->Open(FsHandle, &BootDir, Parameters->SystemPath, EFI_FILE_MODE_READ, 0);
|
||||
FsHandle->Close(FsHandle);
|
||||
|
||||
/* Check if system path directory opened successfully */
|
||||
if(Status == STATUS_EFI_NOT_FOUND)
|
||||
{
|
||||
/* Directory not found, nothing to load */
|
||||
XtLdrProtocol->Debug.Print(L"ERROR: System boot directory not found\n");
|
||||
|
||||
/* Close volume */
|
||||
XtLdrProtocol->Disk.CloseVolume(&DiskHandle);
|
||||
return Status;
|
||||
}
|
||||
else if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Failed to open directory */
|
||||
XtLdrProtocol->Debug.Print(L"ERROR: Unable to open system boot directory\n");
|
||||
XtLdrProtocol->Disk.CloseVolume(&DiskHandle);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Start boot sequence */
|
||||
return RunBootSequence(BootDir, Parameters);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns information about frame buffer in XTOS compatible format.
|
||||
*
|
||||
* @param InformationBlock
|
||||
* A pointer to memory area containing XT structure where all the information will be stored.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
Xtos::GetDisplayInformation(OUT PSYSTEM_RESOURCE_FRAMEBUFFER FrameBufferResource,
|
||||
IN PEFI_PHYSICAL_ADDRESS FrameBufferBase,
|
||||
IN PULONG_PTR FrameBufferSize,
|
||||
IN PXTBL_FRAMEBUFFER_MODE_INFORMATION FrameBufferModeInfo)
|
||||
{
|
||||
/* Fill in frame buffer resource */
|
||||
FrameBufferResource->Header.PhysicalAddress = (PVOID)*FrameBufferBase;
|
||||
FrameBufferResource->Header.ResourceType = SystemResourceFrameBuffer;
|
||||
FrameBufferResource->Header.ResourceSize = sizeof(SYSTEM_RESOURCE_FRAMEBUFFER);
|
||||
FrameBufferResource->BufferSize = *FrameBufferSize;
|
||||
FrameBufferResource->Width = FrameBufferModeInfo->Width;
|
||||
FrameBufferResource->Height = FrameBufferModeInfo->Height;
|
||||
FrameBufferResource->Depth = FrameBufferModeInfo->Depth;
|
||||
FrameBufferResource->BitsPerPixel = FrameBufferModeInfo->BitsPerPixel;
|
||||
FrameBufferResource->PixelsPerScanLine = FrameBufferModeInfo->PixelsPerScanLine;
|
||||
FrameBufferResource->Pitch = FrameBufferModeInfo->Pitch;
|
||||
FrameBufferResource->Pixels.BlueShift = FrameBufferModeInfo->PixelInformation.BlueShift;
|
||||
FrameBufferResource->Pixels.BlueSize = FrameBufferModeInfo->PixelInformation.BlueSize;
|
||||
FrameBufferResource->Pixels.GreenShift = FrameBufferModeInfo->PixelInformation.GreenShift;
|
||||
FrameBufferResource->Pixels.GreenSize = FrameBufferModeInfo->PixelInformation.GreenSize;
|
||||
FrameBufferResource->Pixels.RedShift = FrameBufferModeInfo->PixelInformation.RedShift;
|
||||
FrameBufferResource->Pixels.RedSize = FrameBufferModeInfo->PixelInformation.RedSize;
|
||||
FrameBufferResource->Pixels.ReservedShift = FrameBufferModeInfo->PixelInformation.ReservedShift;
|
||||
FrameBufferResource->Pixels.ReservedSize = FrameBufferModeInfo->PixelInformation.ReservedSize;
|
||||
}
|
||||
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
Xtos::GetMemoryDescriptorList(IN PXTBL_PAGE_MAPPING PageMap,
|
||||
IN EFI_PHYSICAL_ADDRESS PhysicalBase,
|
||||
IN PVOID VirtualBase,
|
||||
OUT PLIST_ENTRY MemoryDescriptorList)
|
||||
{
|
||||
PLOADER_MEMORY_DESCRIPTOR Descriptor;
|
||||
PXTBL_MEMORY_MAPPING MemoryMapping;
|
||||
PLIST_ENTRY ListEntry;
|
||||
|
||||
/* Initialize the descriptor pointer to the start of the allocated physical buffer */
|
||||
Descriptor = (PLOADER_MEMORY_DESCRIPTOR)PhysicalBase;
|
||||
|
||||
/* Get the first entry from the internal boot loader memory map */
|
||||
ListEntry = PageMap->MemoryMap.Flink;
|
||||
|
||||
/* Iterate through the internal memory map and populate the loader descriptor list */
|
||||
while(ListEntry != &PageMap->MemoryMap)
|
||||
{
|
||||
/* Retrieve the internal memory mapping record from the current list entry */
|
||||
MemoryMapping = CONTAIN_RECORD(ListEntry, XTBL_MEMORY_MAPPING, ListEntry);
|
||||
|
||||
/* Transfer memory type and address information to the kernel descriptor */
|
||||
Descriptor->MemoryType = MemoryMapping->MemoryType;
|
||||
Descriptor->BasePage = (UINT_PTR)(MemoryMapping->PhysicalAddress / EFI_PAGE_SIZE);
|
||||
Descriptor->PageCount = (ULONG)MemoryMapping->NumberOfPages;
|
||||
|
||||
/* Link the entry */
|
||||
XtLdrProtocol->LinkedList.InsertTail(MemoryDescriptorList, &Descriptor->ListEntry);
|
||||
|
||||
/* Move to the next slot in the allocated buffer */
|
||||
Descriptor++;
|
||||
ListEntry = ListEntry->Flink;
|
||||
}
|
||||
|
||||
/* Convert all physical link pointers in the list to their corresponding virtual addresses */
|
||||
XtLdrProtocol->Memory.PhysicalListToVirtual(PageMap, MemoryDescriptorList, (PVOID)PhysicalBase, VirtualBase);
|
||||
|
||||
/* Return success */
|
||||
return STATUS_EFI_SUCCESS;
|
||||
}
|
||||
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
Xtos::GetSystemResourcesList(IN PXTBL_PAGE_MAPPING PageMap,
|
||||
IN EFI_PHYSICAL_ADDRESS PhysicalBase,
|
||||
IN PVOID VirtualBase,
|
||||
IN PVOID FrameBufferVirtualBase,
|
||||
OUT PLIST_ENTRY SystemResourcesList)
|
||||
{
|
||||
XTSTATUS Status;
|
||||
EFI_HANDLE ProtocolHandle;
|
||||
EFI_GUID AcpiGuid = XT_ACPI_PROTOCOL_GUID;
|
||||
EFI_GUID FrameBufGuid = XT_FRAMEBUFFER_PROTOCOL_GUID;
|
||||
PXTBL_ACPI_PROTOCOL AcpiProtocol;
|
||||
PXTBL_FRAMEBUFFER_PROTOCOL FrameBufProtocol;
|
||||
XTBL_FRAMEBUFFER_MODE_INFORMATION FbModeInfo;
|
||||
EFI_PHYSICAL_ADDRESS FbAddress;
|
||||
EFI_PHYSICAL_ADDRESS OriginalPhysicalBase;
|
||||
ULONG_PTR FbSize;
|
||||
PSYSTEM_RESOURCE_FRAMEBUFFER FrameBufferResource;
|
||||
PSYSTEM_RESOURCE_ACPI AcpiResource;
|
||||
|
||||
/* Save original physical base */
|
||||
OriginalPhysicalBase = PhysicalBase;
|
||||
|
||||
AcpiResource = (PSYSTEM_RESOURCE_ACPI)PhysicalBase;
|
||||
XtLdrProtocol->Memory.ZeroMemory(AcpiResource, sizeof(SYSTEM_RESOURCE_ACPI));
|
||||
|
||||
/* Load ACPI protocol */
|
||||
Status = XtLdrProtocol->Protocol.Open(&ProtocolHandle, (PVOID*)&AcpiProtocol, &AcpiGuid);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
return Status;
|
||||
}
|
||||
|
||||
AcpiResource->Header.ResourceType = SystemResourceAcpi;
|
||||
AcpiResource->Header.ResourceSize = sizeof(SYSTEM_RESOURCE_ACPI);
|
||||
|
||||
/* Get APIC and XSDP/RSDP addresses */
|
||||
AcpiProtocol->GetApicBase(&AcpiResource->ApicBase);
|
||||
AcpiProtocol->GetAcpiDescriptionPointer(&AcpiResource->Header.PhysicalAddress);
|
||||
|
||||
/* No need to map ACPI */
|
||||
AcpiResource->Header.VirtualAddress = 0;
|
||||
|
||||
XtLdrProtocol->LinkedList.InsertTail(SystemResourcesList, &AcpiResource->Header.ListEntry);
|
||||
|
||||
/* Close ACPI protocol */
|
||||
XtLdrProtocol->Protocol.Close(&ProtocolHandle, &AcpiGuid);
|
||||
|
||||
PhysicalBase = PhysicalBase + sizeof(SYSTEM_RESOURCE_ACPI);
|
||||
FrameBufferResource = (PSYSTEM_RESOURCE_FRAMEBUFFER)PhysicalBase;
|
||||
XtLdrProtocol->Memory.ZeroMemory(FrameBufferResource, sizeof(SYSTEM_RESOURCE_FRAMEBUFFER));
|
||||
|
||||
/* Load FrameBuffer protocol */
|
||||
Status = XtLdrProtocol->Protocol.Open(&ProtocolHandle, (PVOID*)&FrameBufProtocol, &FrameBufGuid);
|
||||
if(Status == STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Get FrameBuffer information */
|
||||
Status = FrameBufProtocol->GetDisplayInformation(&FbAddress, &FbSize, &FbModeInfo);
|
||||
if(Status == STATUS_EFI_SUCCESS)
|
||||
{
|
||||
|
||||
/* Store information about FrameBuffer device */
|
||||
GetDisplayInformation(FrameBufferResource, &FbAddress, &FbSize, &FbModeInfo);
|
||||
}
|
||||
}
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Assign the pre-mapped virtual address to the resource block */
|
||||
FrameBufferResource->Header.VirtualAddress = FrameBufferVirtualBase;
|
||||
XtLdrProtocol->Protocol.Close(&ProtocolHandle, &FrameBufGuid);
|
||||
|
||||
XtLdrProtocol->LinkedList.InsertTail(SystemResourcesList, &FrameBufferResource->Header.ListEntry);
|
||||
|
||||
/* Convert list pointers to virtual */
|
||||
XtLdrProtocol->Memory.PhysicalListToVirtual(PageMap, SystemResourcesList, (PVOID)OriginalPhysicalBase, VirtualBase);
|
||||
|
||||
/* Return success */
|
||||
return STATUS_EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if APIC is present in the system and finds its base address.
|
||||
*
|
||||
* @param MemoryMappings
|
||||
* Supplies a pointer to linked list containing all memory mappings.
|
||||
*
|
||||
* @return This routine returns an EFI status code.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
Xtos::InitializeApicBase(IN PXTBL_PAGE_MAPPING PageMap)
|
||||
{
|
||||
EFI_GUID AcpiGuid = XT_ACPI_PROTOCOL_GUID;
|
||||
PXTBL_ACPI_PROTOCOL AcpiProtocol;
|
||||
EFI_HANDLE ProtocolHandle;
|
||||
PVOID ApicBaseAddress;
|
||||
EFI_STATUS Status;
|
||||
|
||||
/* Open ACPI protocol */
|
||||
Status = XtLdrProtocol->Protocol.Open(&ProtocolHandle, (PVOID*)&AcpiProtocol, &AcpiGuid);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* ACPI protocol not found */
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Get APIC base address */
|
||||
Status = AcpiProtocol->GetApicBase(&ApicBaseAddress);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Failed to get APIC base address */
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Map APIC base address */
|
||||
XtLdrProtocol->Memory.MapVirtualMemory(PageMap, APIC_BASE, (ULONGLONG)ApicBaseAddress, 1, LoaderFirmwarePermanent);
|
||||
return STATUS_EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes and maps the kernel initialization block.
|
||||
*
|
||||
* @param MemoryMappings
|
||||
* Supplies a pointer to linked list containing all memory mappings.
|
||||
*
|
||||
* @param VirtualAddress
|
||||
* Supplies a pointer to the next valid, free and available virtual address.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
Xtos::InitializeLoaderBlock(IN PXTBL_PAGE_MAPPING PageMap,
|
||||
IN OUT PVOID *VirtualAddress,
|
||||
IN PXTBL_BOOT_PARAMETERS Parameters)
|
||||
{
|
||||
EFI_PHYSICAL_ADDRESS FbPhysicalAddress, PhysicalBlock, PhysicalDescriptor, PhysicalResources;
|
||||
PVOID FbVirtualAddress, VirtualBlock, VirtualResources, VirtualDescriptor;
|
||||
UINT BlockPages, DescriptorPages, FbPages, ParametersSize, ResourcesPages;
|
||||
XTBL_FRAMEBUFFER_MODE_INFORMATION FbModeInfo;
|
||||
PXTBL_FRAMEBUFFER_PROTOCOL FrameBufProtocol;
|
||||
PKERNEL_INITIALIZATION_BLOCK LoaderBlock;
|
||||
EFI_HANDLE ProtocolHandle;
|
||||
EFI_STATUS Status;
|
||||
ULONG_PTR FbSize;
|
||||
|
||||
EFI_GUID FrameBufGuid = XT_FRAMEBUFFER_PROTOCOL_GUID;
|
||||
|
||||
/* Initialize Framebuffer information */
|
||||
FbPhysicalAddress = 0;
|
||||
FbSize = 0;
|
||||
FbVirtualAddress = NULLPTR;
|
||||
FbPages = 0;
|
||||
|
||||
/* Calculate size of parameters */
|
||||
ParametersSize = (XtLdrProtocol->WideString.Length(Parameters->Parameters, 0) + 1) * sizeof(WCHAR);
|
||||
|
||||
/* Calculate number of pages needed for initialization block */
|
||||
BlockPages = EFI_SIZE_TO_PAGES(sizeof(KERNEL_INITIALIZATION_BLOCK) + ParametersSize);
|
||||
ResourcesPages = EFI_SIZE_TO_PAGES(sizeof(SYSTEM_RESOURCE_ACPI) + sizeof(SYSTEM_RESOURCE_FRAMEBUFFER));
|
||||
|
||||
/* Query Framebuffer size for allocation */
|
||||
if(XtLdrProtocol->Protocol.Open(&ProtocolHandle, (PVOID*)&FrameBufProtocol, &FrameBufGuid) == STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Get FrameBuffer information */
|
||||
FrameBufProtocol->GetDisplayInformation(&FbPhysicalAddress, &FbSize, &FbModeInfo);
|
||||
XtLdrProtocol->Protocol.Close(&ProtocolHandle, &FrameBufGuid);
|
||||
}
|
||||
FbPages = EFI_SIZE_TO_PAGES(FbSize);
|
||||
|
||||
/* Precommit page map to allocate memory */
|
||||
XtLdrProtocol->Memory.CommitPageMap(PageMap);
|
||||
|
||||
/* Calculate number of pages needed for memory descriptor list */
|
||||
DescriptorPages = EFI_SIZE_TO_PAGES(PageMap->MapSize * sizeof(LOADER_MEMORY_DESCRIPTOR) * 2);
|
||||
|
||||
/* Allocate memory for the kernel initialization block and boot parameters */
|
||||
Status = XtLdrProtocol->Memory.AllocatePages(AllocateAnyPages, BlockPages, &PhysicalBlock);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Memory allocation failure, return status code */
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Allocate memory for the system resources data structures */
|
||||
Status = XtLdrProtocol->Memory.AllocatePages(AllocateAnyPages, ResourcesPages, &PhysicalResources);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Memory allocation failure, return status code */
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Allocate memory for the memory descriptor list */
|
||||
Status = XtLdrProtocol->Memory.AllocatePages(AllocateAnyPages, DescriptorPages, &PhysicalDescriptor);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Memory allocation failure, return status code */
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Map the Kernel Initialization Block into virtual memory and advance the virtual address pointer */
|
||||
VirtualBlock = *VirtualAddress;
|
||||
XtLdrProtocol->Memory.MapVirtualMemory(PageMap, (ULONGLONG)VirtualBlock, PhysicalBlock, BlockPages, LoaderSystemBlock);
|
||||
*VirtualAddress = (PUINT8)*VirtualAddress + (BlockPages * EFI_PAGE_SIZE);
|
||||
|
||||
/* Map the system resources physical memory into virtual address space and update the allocation pointer */
|
||||
VirtualResources = *VirtualAddress;
|
||||
XtLdrProtocol->Memory.MapVirtualMemory(PageMap, (ULONGLONG)VirtualResources, PhysicalResources, ResourcesPages, LoaderFirmwarePermanent);
|
||||
*VirtualAddress = (PUINT8)*VirtualAddress + (ResourcesPages * EFI_PAGE_SIZE);
|
||||
|
||||
/* Check if a framebuffer was detected and requires memory mapping */
|
||||
if(FbPages > 0)
|
||||
{
|
||||
/* Map the framebuffer physical memory range into virtual address space */
|
||||
FbVirtualAddress = *VirtualAddress;
|
||||
XtLdrProtocol->Memory.MapVirtualMemory(PageMap, (ULONGLONG)FbVirtualAddress, FbPhysicalAddress, FbPages, LoaderFirmwarePermanent);
|
||||
*VirtualAddress = (PUINT8)*VirtualAddress + (FbPages * EFI_PAGE_SIZE);
|
||||
}
|
||||
|
||||
/* Map the allocated physical memory for memory descriptors into the virtual address space */
|
||||
VirtualDescriptor = *VirtualAddress;
|
||||
XtLdrProtocol->Memory.MapVirtualMemory(PageMap, (ULONGLONG)VirtualDescriptor, PhysicalDescriptor, DescriptorPages, LoaderMemoryData);
|
||||
*VirtualAddress = (PUINT8)*VirtualAddress + (DescriptorPages * EFI_PAGE_SIZE);
|
||||
|
||||
/* Set basic loader block properties */
|
||||
XtLdrProtocol->Memory.ZeroMemory((PVOID)PhysicalBlock, sizeof(KERNEL_INITIALIZATION_BLOCK) + ParametersSize);
|
||||
LoaderBlock = (PKERNEL_INITIALIZATION_BLOCK)PhysicalBlock;
|
||||
LoaderBlock->BlockSize = sizeof(KERNEL_INITIALIZATION_BLOCK);
|
||||
LoaderBlock->BlockVersion = INITIALIZATION_BLOCK_VERSION;
|
||||
LoaderBlock->ProtocolVersion = BOOT_PROTOCOL_VERSION;
|
||||
|
||||
/* Set LoaderInformation block properties */
|
||||
LoaderBlock->LoaderInformation.DbgPrint = (PVOID)XtLdrProtocol->Debug.Print;
|
||||
|
||||
/* Set FirmwareInformation block properties */
|
||||
LoaderBlock->FirmwareInformation.FirmwareType = SystemFirmwareEfi;
|
||||
// LoaderBlock->FirmwareInformation.EfiFirmware.EfiVersion = EfiSystemTable->Hdr.Revision;
|
||||
LoaderBlock->FirmwareInformation.EfiFirmware.EfiRuntimeServices = NULLPTR;
|
||||
|
||||
/* Copy parameters to kernel initialization block */
|
||||
LoaderBlock->KernelParameters = (PWCHAR)((UINT_PTR)VirtualBlock + sizeof(KERNEL_INITIALIZATION_BLOCK));
|
||||
XtLdrProtocol->Memory.CopyMemory((PVOID)((UINT_PTR)LoaderBlock + sizeof(KERNEL_INITIALIZATION_BLOCK)),
|
||||
Parameters->Parameters, ParametersSize);
|
||||
|
||||
/* Commit mappings */
|
||||
XtLdrProtocol->Memory.CommitPageMap(PageMap);
|
||||
|
||||
/* Initialize system resources list */
|
||||
XtLdrProtocol->LinkedList.InitializeHead(&LoaderBlock->SystemResourcesListHead);
|
||||
Status = GetSystemResourcesList(PageMap, PhysicalResources, VirtualResources, FbVirtualAddress, &LoaderBlock->SystemResourcesListHead);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Failed to initialize system resources list, return status code */
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Initialize memory descriptor list */
|
||||
XtLdrProtocol->LinkedList.InitializeHead(&LoaderBlock->MemoryDescriptorListHead);
|
||||
Status = GetMemoryDescriptorList(PageMap, PhysicalDescriptor, VirtualDescriptor, &LoaderBlock->MemoryDescriptorListHead);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Failed to initialize memory descriptor list, return status code */
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Set boot image size */
|
||||
LoaderBlock->BootImageSize = (PFN_NUMBER)(((ULONGLONG)*VirtualAddress - KSEG0_BASE) / EFI_PAGE_SIZE);
|
||||
|
||||
/* Return success */
|
||||
return STATUS_EFI_SUCCESS;
|
||||
}
|
||||
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
Xtos::InitializeModule(IN EFI_HANDLE ImageHandle,
|
||||
IN PEFI_SYSTEM_TABLE SystemTable)
|
||||
{
|
||||
EFI_GUID Guid = XT_XTOS_BOOT_PROTOCOL_GUID;
|
||||
EFI_STATUS Status;
|
||||
|
||||
/* Open the XTLDR protocol */
|
||||
Status = BlGetXtLdrProtocol(SystemTable, ImageHandle, &XtLdrProtocol);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Failed to open loader protocol */
|
||||
return STATUS_EFI_PROTOCOL_ERROR;
|
||||
}
|
||||
|
||||
/* Set routines available via XTOS boot protocol */
|
||||
BootProtocol.BootSystem = Xtos::BootSystem;
|
||||
|
||||
/* Register XTOS boot protocol */
|
||||
XtLdrProtocol->Boot.RegisterProtocol(L"XTOS", &Guid);
|
||||
|
||||
/* Install XTOS protocol */
|
||||
return XtLdrProtocol->Protocol.Install(&BootProtocol, &Guid);
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads XTOS PE/COFF module.
|
||||
*
|
||||
* @param SystemDir
|
||||
* An EFI handle to the opened system directory containing a module that will be loaded.
|
||||
*
|
||||
* @param FileName
|
||||
* An on disk filename of the module that will be loaded.
|
||||
*
|
||||
* @param VirtualAddress
|
||||
* Optional virtual address pointing to the memory area where PE/COFF file will be loaded.
|
||||
*
|
||||
* @param MemoryType
|
||||
* Supplies the type of memory to be assigned to the memory descriptor.
|
||||
*
|
||||
* @param ImageContext
|
||||
* Supplies pointer to the memory area where loaded PE/COFF image context will be stored.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
Xtos::LoadModule(IN PEFI_FILE_HANDLE SystemDir,
|
||||
IN PWCHAR FileName,
|
||||
IN PVOID VirtualAddress,
|
||||
IN LOADER_MEMORY_TYPE MemoryType,
|
||||
OUT PPECOFF_IMAGE_CONTEXT *ImageContext)
|
||||
{
|
||||
PEFI_FILE_HANDLE ModuleHandle;
|
||||
USHORT MachineType, SubSystem;
|
||||
EFI_STATUS Status;
|
||||
|
||||
/* Print debug message */
|
||||
XtLdrProtocol->Debug.Print(L"Loading %S ... \n", FileName);
|
||||
|
||||
/* Open module file */
|
||||
Status = SystemDir->Open(SystemDir, &ModuleHandle, FileName, EFI_FILE_MODE_READ, 0);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Unable to open the file */
|
||||
XtLdrProtocol->Debug.Print(L"ERROR: Failed to open '%S'\n", FileName);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Load the PE/COFF image file */
|
||||
Status = PeCoffProtocol->LoadImage(ModuleHandle, MemoryType, VirtualAddress, (PVOID*)ImageContext);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Unable to load the file */
|
||||
XtLdrProtocol->Debug.Print(L"ERROR: Failed to load '%S'\n", FileName);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Close image file */
|
||||
ModuleHandle->Close(ModuleHandle);
|
||||
|
||||
/* Check PE/COFF image machine type compatibility */
|
||||
PeCoffProtocol->GetMachineType(*ImageContext, &MachineType);
|
||||
if(MachineType != _ARCH_IMAGE_MACHINE_TYPE)
|
||||
{
|
||||
/* Machine type mismatch */
|
||||
XtLdrProtocol->Debug.Print(L"ERROR: Loaded incompatible PE/COFF image (machine type mismatch)\n");
|
||||
return STATUS_EFI_INCOMPATIBLE_VERSION;
|
||||
}
|
||||
|
||||
/* Check PE/COFF image subsystem */
|
||||
PeCoffProtocol->GetSubSystem(*ImageContext, &SubSystem);
|
||||
if(SubSystem != PECOFF_IMAGE_SUBSYSTEM_XT_NATIVE_KERNEL &&
|
||||
SubSystem != PECOFF_IMAGE_SUBSYSTEM_XT_NATIVE_APPLICATION &&
|
||||
SubSystem != PECOFF_IMAGE_SUBSYSTEM_XT_NATIVE_DRIVER)
|
||||
{
|
||||
XtLdrProtocol->Debug.Print(L"WARNING: Loaded PE/COFF image with non-XT subsystem set\n");
|
||||
}
|
||||
|
||||
/* Print debug message */
|
||||
XtLdrProtocol->Debug.Print(L"Loaded %S at PA: %P, VA: %P\n", FileName,
|
||||
(*ImageContext)->PhysicalAddress, (*ImageContext)->VirtualAddress);
|
||||
|
||||
/* Return success */
|
||||
return STATUS_EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* This routine initiates an XTOS boot sequence.
|
||||
*
|
||||
* @param BootDir
|
||||
* An EFI handle to the XTOS boot directory.
|
||||
*
|
||||
* @param Parameters
|
||||
* Input parameters with detailed system configuration like boot device or kernel path.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
Xtos::RunBootSequence(IN PEFI_FILE_HANDLE BootDir,
|
||||
IN PXTBL_BOOT_PARAMETERS Parameters)
|
||||
{
|
||||
EFI_GUID LoadedImageGuid = EFI_LOADED_IMAGE_PROTOCOL_GUID;
|
||||
EFI_GUID FrameBufGuid = XT_FRAMEBUFFER_PROTOCOL_GUID;
|
||||
PKERNEL_INITIALIZATION_BLOCK KernelParameters;
|
||||
PXTBL_FRAMEBUFFER_PROTOCOL FrameBufProtocol;
|
||||
PPECOFF_IMAGE_CONTEXT ImageContext = NULLPTR;
|
||||
PEFI_LOADED_IMAGE_PROTOCOL ImageProtocol;
|
||||
PVOID VirtualAddress;
|
||||
PXT_ENTRY_POINT KernelEntryPoint;
|
||||
EFI_HANDLE ProtocolHandle;
|
||||
EFI_STATUS Status;
|
||||
XTBL_PAGE_MAPPING PageMap;
|
||||
BOOLEAN IdentityMapping;
|
||||
|
||||
/* Initialize XTOS startup sequence */
|
||||
XtLdrProtocol->Debug.Print(L"Initializing XTOS startup sequence\n");
|
||||
|
||||
/* Load FrameBuffer protocol */
|
||||
Status = XtLdrProtocol->Protocol.Open(&ProtocolHandle, (PVOID*)&FrameBufProtocol, &FrameBufGuid);
|
||||
if(Status == STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Make sure FrameBuffer is initialized */
|
||||
FrameBufProtocol->Initialize();
|
||||
FrameBufProtocol->SetScreenResolution(0, 0);
|
||||
}
|
||||
|
||||
/* Close FrameBuffer protocol */
|
||||
XtLdrProtocol->Protocol.Close(&ProtocolHandle, &FrameBufGuid);
|
||||
|
||||
/* Determine whether to use a sequential or an identity mapping strategy */
|
||||
IdentityMapping = DetermineMappingStrategy();
|
||||
|
||||
/* Set base virtual memory area for the kernel mappings */
|
||||
VirtualAddress = (PVOID)(KSEG0_BASE);
|
||||
|
||||
/* Initialize virtual memory mappings */
|
||||
XtLdrProtocol->Memory.InitializePageMap(&PageMap, DeterminePagingLevel(Parameters->Parameters), Size4K);
|
||||
|
||||
/* Map all EFI memory regions */
|
||||
Status = XtLdrProtocol->Memory.MapEfiMemory(&PageMap, &VirtualAddress, IdentityMapping, NULLPTR);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Mapping failed */
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Check mapping strategy */
|
||||
if(IdentityMapping)
|
||||
{
|
||||
/* Adjust virtual address to skip the identity-mapped physical range */
|
||||
VirtualAddress = (PVOID)((ULONGLONG)VirtualAddress + 0x800000000);
|
||||
}
|
||||
|
||||
/* Load the kernel */
|
||||
Status = LoadModule(BootDir, Parameters->KernelFile, VirtualAddress, LoaderSystemCode, &ImageContext);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Failed to load the kernel */
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Add kernel image memory mapping */
|
||||
Status = XtLdrProtocol->Memory.MapVirtualMemory(&PageMap, (ULONGLONG)ImageContext->VirtualAddress,
|
||||
(ULONGLONG)ImageContext->PhysicalAddress, ImageContext->ImagePages,
|
||||
LoaderSystemCode);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Set next valid virtual address right after the kernel */
|
||||
VirtualAddress = (PUINT8)VirtualAddress + (ImageContext->ImagePages * EFI_PAGE_SIZE);
|
||||
|
||||
/* Find and map APIC base address */
|
||||
Status = InitializeApicBase(&PageMap);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Failed to setup kernel initialization block */
|
||||
XtLdrProtocol->Debug.Print(L"Failed to initialize APIC (Status Code: 0x%zX)\n", 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 */
|
||||
KernelParameters = (PKERNEL_INITIALIZATION_BLOCK)VirtualAddress;
|
||||
|
||||
/* Setup and map kernel initialization block */
|
||||
Status = InitializeLoaderBlock(&PageMap, &VirtualAddress, Parameters);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Failed to setup kernel initialization block */
|
||||
XtLdrProtocol->Debug.Print(L"Failed to setup kernel initialization block (Status Code: 0x%zX)\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Get kernel entry point */
|
||||
PeCoffProtocol->GetEntryPoint(ImageContext, (PVOID*)&KernelEntryPoint);
|
||||
|
||||
/* Close boot directory handle */
|
||||
BootDir->Close(BootDir);
|
||||
|
||||
/* Enable paging */
|
||||
XtLdrProtocol->Protocol.Open(&ProtocolHandle, (PVOID*)&ImageProtocol, &LoadedImageGuid);
|
||||
Status = EnablePaging(&PageMap);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Failed to enable paging */
|
||||
XtLdrProtocol->Debug.Print(L"Failed to enable paging (Status Code: 0x%zX)\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Call XTOS kernel */
|
||||
XtLdrProtocol->Debug.Print(L"Booting the XTOS kernel\n");
|
||||
KernelEntryPoint(KernelParameters);
|
||||
|
||||
/* Return success */
|
||||
return STATUS_EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* This routine is the entry point of the XT EFI boot loader module.
|
||||
*
|
||||
* @param ImageHandle
|
||||
* Firmware-allocated handle that identifies the image.
|
||||
*
|
||||
* @param SystemTable
|
||||
* Provides the EFI system table.
|
||||
*
|
||||
* @return This routine returns status code.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
XtLdrModuleMain(IN EFI_HANDLE ImageHandle,
|
||||
IN PEFI_SYSTEM_TABLE SystemTable)
|
||||
{
|
||||
/* Initialize XTOS module */
|
||||
return Xtos::InitializeModule(ImageHandle, SystemTable);
|
||||
}
|
||||
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
@@ -0,0 +1,959 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: xtldr/shell.cc
|
||||
* DESCRIPTION: XT Boot Loader shell
|
||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||
* Aiken Harris <harraiken91@gmail.com>
|
||||
*/
|
||||
|
||||
#include <xtldr.hh>
|
||||
|
||||
|
||||
/**
|
||||
* Implements the built-in `exit` command. Sets the exit flag to signal the main
|
||||
* shell loop to terminate and return control to the boot menu.
|
||||
*
|
||||
* @param Argc
|
||||
* Supplies the number of arguments provided by the user.
|
||||
*
|
||||
* @param Argv
|
||||
* Supplies a list of arguments provided by the user.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
Shell::CommandExit(IN ULONG Argc,
|
||||
IN PWCHAR *Argv)
|
||||
{
|
||||
/* Signal the main shell loop to stop and return to the boot menu */
|
||||
ExitRequest = TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements the built-in `help` command. Prints a list of available commands alongside their descriptions.
|
||||
*
|
||||
* @param Argc
|
||||
* Supplies the number of arguments provided by the user.
|
||||
*
|
||||
* @param Argv
|
||||
* Supplies a list of arguments provided by the user.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
Shell::CommandHelp(IN ULONG Argc,
|
||||
IN PWCHAR *Argv)
|
||||
{
|
||||
PXTBL_SHELL_COMMAND CommandEntry;
|
||||
PLIST_ENTRY ListEntry;
|
||||
|
||||
/* Print a header line */
|
||||
Console::Print(L"Available commands:\n\n");
|
||||
|
||||
/* Walk the registered commands list */
|
||||
ListEntry = ShellCommands.Flink;
|
||||
while(ListEntry != &ShellCommands)
|
||||
{
|
||||
/* Retrieve the current command entry */
|
||||
CommandEntry = CONTAIN_RECORD(ListEntry, XTBL_SHELL_COMMAND, Flink);
|
||||
|
||||
/* Print the command name in a highlighted color */
|
||||
Console::SetAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_WHITE);
|
||||
Console::Print(L" %-12S", CommandEntry->Command);
|
||||
|
||||
/* Print the description in the default color */
|
||||
Console::SetAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_LIGHTGRAY);
|
||||
Console::Print(L" %S\n", CommandEntry->Description);
|
||||
|
||||
/* Advance to the next entry */
|
||||
ListEntry = ListEntry->Flink;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements the built-in `insmod` command. Loads an XTLDR module by its name.
|
||||
*
|
||||
* @param Argc
|
||||
* Supplies the number of arguments provided by the user.
|
||||
*
|
||||
* @param Argv
|
||||
* Supplies a list of arguments provided by the user.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
Shell::CommandInsmod(IN ULONG Argc,
|
||||
IN PWCHAR *Argv)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
|
||||
/* Check if the module name was provided */
|
||||
if(Argc != 2)
|
||||
{
|
||||
/* Print usage message and return */
|
||||
Console::Print(L"Usage: insmod <module_name>\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Load the module */
|
||||
Status = Protocol::LoadModule(Argv[1]);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Failed to load module, print error message */
|
||||
Console::Print(L"ERROR: Failed to load module '%S' (Status: 0x%llx).\n", Argv[1], Status);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements the built-in `lsmod` command. Lists all loaded XTLDR modules.
|
||||
*
|
||||
* @param Argc
|
||||
* Supplies the number of arguments provided by the user.
|
||||
*
|
||||
* @param Argv
|
||||
* Supplies a list of arguments provided by the user.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
Shell::CommandLsmod(IN ULONG Argc,
|
||||
IN PWCHAR *Argv)
|
||||
{
|
||||
PXTBL_MODULE_INFO ModuleInfo;
|
||||
PLIST_ENTRY ModulesList;
|
||||
PLIST_ENTRY ListEntry;
|
||||
|
||||
/* Print header */
|
||||
Console::Print(L"Module Name Version Base Address Size\n");
|
||||
Console::Print(L"----------------------------------------------------------------------\n");
|
||||
|
||||
/* Get modules list */
|
||||
ModulesList = Protocol::GetModulesList();
|
||||
if(ModulesList == NULLPTR)
|
||||
{
|
||||
/* No modules loaded */
|
||||
return;
|
||||
}
|
||||
|
||||
/* Iterate over all loaded modules */
|
||||
ListEntry = ModulesList->Flink;
|
||||
while(ListEntry != ModulesList)
|
||||
{
|
||||
/* Retrieve the module information */
|
||||
ModuleInfo = CONTAIN_RECORD(ListEntry, XTBL_MODULE_INFO, Flink);
|
||||
|
||||
/* Print module information */
|
||||
Console::Print(L"%-16S %-16S 0x%016llx %llu\n",
|
||||
ModuleInfo->ModuleName, ModuleInfo->Version,
|
||||
(ULONGLONG)ModuleInfo->ModuleBase, ModuleInfo->ModuleSize);
|
||||
|
||||
/* Advance to the next entry */
|
||||
ListEntry = ListEntry->Flink;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements the built-in `poweroff` command. Shuts down the machine.
|
||||
*
|
||||
* @param Argc
|
||||
* Supplies the number of arguments provided by the user.
|
||||
*
|
||||
* @param Argv
|
||||
* Supplies a list of arguments provided by the user.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
Shell::CommandPoweroff(IN ULONG Argc,
|
||||
IN PWCHAR *Argv)
|
||||
{
|
||||
/* Attempt to power off the machine */
|
||||
Console::Print(L"Powering off...\n");
|
||||
EfiUtils::ShutdownSystem();
|
||||
|
||||
/* The poweroff call failed, print error message */
|
||||
Console::Print(L"ERROR: Failed to power off the machine\n");
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements the built-in `reboot` command. Performs a normal system restart via the EFI runtime services.
|
||||
* When the '/EFI' parameter is supplied, the routine instead schedules a reboot into the UEFI firmware setup interface.
|
||||
*
|
||||
* @param Argc
|
||||
* Supplies the number of arguments provided by the user.
|
||||
*
|
||||
* @param Argv
|
||||
* Supplies a list of arguments provided by the user.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
Shell::CommandReboot(IN ULONG Argc,
|
||||
IN PWCHAR *Argv)
|
||||
{
|
||||
/* Check if the /EFI flag was specified */
|
||||
if(Argc > 1 && RTL::WideString::CompareWideStringInsensitive(Argv[1], L"/EFI", 0) == 0)
|
||||
{
|
||||
/* Attempt to reboot into firmware setup */
|
||||
Console::Print(L"Rebooting into UEFI firmware setup...\n");
|
||||
EfiUtils::EnterFirmwareSetup();
|
||||
|
||||
/* The firmware does not support this feature, print error message */
|
||||
Console::Print(L"ERROR: Reboot into firmware setup interface not supported.\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Perform a standard system reboot */
|
||||
Console::Print(L"Rebooting...\n");
|
||||
EfiUtils::RebootSystem();
|
||||
|
||||
/* The reboot call failed, print error message */
|
||||
Console::Print(L"ERROR: Failed to reboot the machine\n");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements the built-in `ver` command. Prints the bootloader identification string.
|
||||
*
|
||||
* @param Argc
|
||||
* Supplies the number of arguments provided by the user.
|
||||
*
|
||||
* @param Argv
|
||||
* Supplies a list of arguments provided by the user.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
Shell::CommandVersion(IN ULONG Argc,
|
||||
IN PWCHAR *Argv)
|
||||
{
|
||||
/* Check if debugging enabled */
|
||||
if(DEBUG)
|
||||
{
|
||||
/* Print debug version of XTLDR version string */
|
||||
Console::Print(L"XTLDR Boot Loader v%d.%d (%s-%s)\n",
|
||||
XTLDR_VERSION_MAJOR, XTLDR_VERSION_MINOR, XTOS_VERSION_DATE, XTOS_VERSION_HASH);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Print standard XTLDR version string */
|
||||
Console::Print(L"XTLDR Boot Loader v%d.%d\n", XTLDR_VERSION_MAJOR, XTLDR_VERSION_MINOR);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Looks up the given command name in the registered shell commands list and invokes the corresponding handler.
|
||||
*
|
||||
* @param Argc
|
||||
* Supplies the number of arguments in the argument vector, including the command name itself.
|
||||
*
|
||||
* @param Argv
|
||||
* Supplies a pointer to the argument vector. First argument is the command name.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
Shell::ExecuteCommand(IN ULONG Argc,
|
||||
IN PWCHAR *Argv)
|
||||
{
|
||||
PXTBL_SHELL_COMMAND CommandEntry;
|
||||
PLIST_ENTRY ListEntry;
|
||||
|
||||
/* Walk through the list of registered shell commands */
|
||||
ListEntry = ShellCommands.Flink;
|
||||
while(ListEntry != &ShellCommands)
|
||||
{
|
||||
/* Retrieve the shell command entry from the list node */
|
||||
CommandEntry = CONTAIN_RECORD(ListEntry, XTBL_SHELL_COMMAND, Flink);
|
||||
|
||||
/* Perform a case-insensitive comparison against the command name */
|
||||
if(RTL::WideString::CompareWideStringInsensitive(CommandEntry->Command, Argv[0], 0) == 0)
|
||||
{
|
||||
/* Command matches, invoke its handler and return */
|
||||
CommandEntry->Handler(Argc, Argv);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Advance to the next registered command */
|
||||
ListEntry = ListEntry->Flink;
|
||||
}
|
||||
|
||||
/* No matching command was found, print error message */
|
||||
Console::Print(L"ERROR: '%S' is not recognized as a valid command.\n", Argv[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the bootloader shell.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
Shell::InitializeShell()
|
||||
{
|
||||
/* Initialize the shell commands list */
|
||||
RTL::LinkedList::InitializeListHead(&ShellCommands);
|
||||
|
||||
/* Register all built-in commands */
|
||||
RegisterBuiltinCommands();
|
||||
}
|
||||
|
||||
/**
|
||||
* Splits the supplied raw command line string into an argument count and an argument vector suitable
|
||||
* for command dispatch. The input string is tokenized by whitespace.
|
||||
*
|
||||
* @param CommandLine
|
||||
* Supplies a mutable wide-character string containing the raw command line.
|
||||
*
|
||||
* @param Argc
|
||||
* Receives the number of arguments found in the command line.
|
||||
*
|
||||
* @param Argv
|
||||
* Receives a pointer to an allocated array of wide-character string pointers, one for each argument.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
Shell::ParseCommand(IN PWCHAR CommandLine,
|
||||
OUT PULONG Argc,
|
||||
OUT PWCHAR **Argv)
|
||||
{
|
||||
PWCHAR *ArgumentVector, TempLine;
|
||||
ULONG ArgumentCount;
|
||||
EFI_STATUS Status;
|
||||
|
||||
/* Initialize argument count */
|
||||
ArgumentCount = 0;
|
||||
|
||||
/* Count the tokens to determine the size of the argument vector */
|
||||
TempLine = CommandLine;
|
||||
while(*TempLine != L'\0')
|
||||
{
|
||||
/* Skip leading spaces */
|
||||
while(*TempLine == L' ')
|
||||
{
|
||||
/* Move to the next character */
|
||||
TempLine++;
|
||||
}
|
||||
|
||||
/* Check if the end of the string was reached */
|
||||
if(*TempLine == L'\0')
|
||||
{
|
||||
/* End of the string, break the loop */
|
||||
break;
|
||||
}
|
||||
|
||||
/* One more argument found */
|
||||
ArgumentCount++;
|
||||
|
||||
/* Skip the characters of the token */
|
||||
while(*TempLine != L'\0' && *TempLine != L' ')
|
||||
{
|
||||
/* Move to the next character */
|
||||
TempLine++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if the command line was empty */
|
||||
if(ArgumentCount == 0)
|
||||
{
|
||||
/* Set argument count and vector to zero and NULL */
|
||||
*Argc = 0;
|
||||
*Argv = NULLPTR;
|
||||
|
||||
/* Return success */
|
||||
return STATUS_EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/* Allocate memory for the argument vector */
|
||||
Status = Memory::AllocatePool(ArgumentCount * sizeof(PWCHAR), (PVOID *)&ArgumentVector);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Memory allocation failure, return status code */
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Reset argument count and temp line */
|
||||
ArgumentCount = 0;
|
||||
TempLine = CommandLine;
|
||||
|
||||
/* Walk through the command line */
|
||||
while(*TempLine != L'\0')
|
||||
{
|
||||
/* Skip leading whitespace */
|
||||
while(*TempLine == L' ')
|
||||
{
|
||||
/* Move to the next character */
|
||||
TempLine++;
|
||||
}
|
||||
|
||||
/* Check if the end of the string was reached */
|
||||
if(*TempLine == L'\0')
|
||||
{
|
||||
/* End of string reached, break the loop */
|
||||
break;
|
||||
}
|
||||
|
||||
/* Record token */
|
||||
ArgumentVector[ArgumentCount] = TempLine;
|
||||
ArgumentCount++;
|
||||
|
||||
/* Advance past the token characters */
|
||||
while(*TempLine != L'\0' && *TempLine != L' ')
|
||||
{
|
||||
/* Move to the next character */
|
||||
TempLine++;
|
||||
}
|
||||
|
||||
/* Check if token was NULL-terminated */
|
||||
if(*TempLine != L'\0')
|
||||
{
|
||||
/* NULL-terminate the token and move to the next character */
|
||||
*TempLine = L'\0';
|
||||
TempLine++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Return results to the caller */
|
||||
*Argc = ArgumentCount;
|
||||
*Argv = ArgumentVector;
|
||||
return STATUS_EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints XTLDR shell prompt.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
Shell::PrintPrompt()
|
||||
{
|
||||
/* Set prompt color */
|
||||
Console::SetAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_YELLOW);
|
||||
|
||||
/* Print prompt at the start of the line */
|
||||
Console::Print(L"\rXTLDR> ");
|
||||
|
||||
/* Reset standard shell colors */
|
||||
Console::SetAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_LIGHTGRAY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints the whole prompt line, including the current command line and the cursor position.
|
||||
*
|
||||
* @param Buffer
|
||||
* Supplies a pointer to the buffer containing the command line.
|
||||
*
|
||||
* @param BufferLength
|
||||
* Supplies the buffer text length.
|
||||
*
|
||||
* @param CursorPosition
|
||||
* Supplies the current cursor position.
|
||||
*
|
||||
* @param PreviousBufferLength
|
||||
* Supplies the previous buffer text length to clear artifacts.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
Shell::PrintPromptLine(IN PWCHAR Buffer,
|
||||
IN ULONG BufferLength,
|
||||
IN ULONG CursorPosition,
|
||||
IN ULONG PreviousBufferLength)
|
||||
{
|
||||
INT32 TargetX, TargetY;
|
||||
WCHAR SavedChar;
|
||||
ULONG Index;
|
||||
|
||||
/* Print the prompt */
|
||||
PrintPrompt();
|
||||
|
||||
/* Temporarily truncate the string to capture cursor position */
|
||||
SavedChar = Buffer[CursorPosition];
|
||||
Buffer[CursorPosition] = L'\0';
|
||||
|
||||
/* Print up to the cursor position */
|
||||
Console::Print(L"%S", Buffer);
|
||||
|
||||
/* Capture target cursor coordinates from the EFI text mode structure */
|
||||
TargetX = XtLoader::GetEfiSystemTable()->ConOut->Mode->CursorColumn;
|
||||
TargetY = XtLoader::GetEfiSystemTable()->ConOut->Mode->CursorRow;
|
||||
|
||||
/* Restore the character and print the remainder of the buffer */
|
||||
Buffer[CursorPosition] = SavedChar;
|
||||
Console::Print(L"%S", Buffer + CursorPosition);
|
||||
|
||||
/* Check if the previous buffer was longer than the current one */
|
||||
if(PreviousBufferLength > BufferLength)
|
||||
{
|
||||
/* Clear artifacts from the previous longer line */
|
||||
for(Index = 0; Index < (PreviousBufferLength - BufferLength); Index++)
|
||||
{
|
||||
/* Print a white space */
|
||||
Console::Print(L" ");
|
||||
}
|
||||
}
|
||||
|
||||
/* Move the cursor back to the correct target position */
|
||||
Console::SetCursorPosition(TargetX, TargetY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a complete line of input from the shell console into the supplied buffer.
|
||||
*
|
||||
* @param Buffer
|
||||
* Supplies a pointer to a wide-character buffer that receives the entered command line.
|
||||
*
|
||||
* @param BufferSize
|
||||
* Supplies the capacity of the buffer, in wide characters.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
Shell::ReadCommand(OUT PWCHAR Buffer,
|
||||
IN ULONG BufferSize)
|
||||
{
|
||||
ULONG BufferLength, CursorPosition, OldBufferLength;
|
||||
UINT_PTR EventIndex;
|
||||
EFI_INPUT_KEY Key;
|
||||
|
||||
/* Start with an empty buffer */
|
||||
CursorPosition = 0;
|
||||
BufferLength = 0;
|
||||
Buffer[0] = L'\0';
|
||||
|
||||
/* Reset history index */
|
||||
HistoryIndex = HistoryCount;
|
||||
|
||||
/* Read characters until the user submits the command line */
|
||||
while(TRUE)
|
||||
{
|
||||
/* Wait until a key event is available */
|
||||
EfiUtils::WaitForEfiEvent(1, &(XtLoader::GetEfiSystemTable()->ConIn->WaitForKey), &EventIndex);
|
||||
|
||||
/* Read the keystroke from the input device */
|
||||
Console::ReadKeyStroke(&Key);
|
||||
|
||||
/* Capture the previous line length to wipe possible artifacts */
|
||||
OldBufferLength = BufferLength;
|
||||
|
||||
/* Check the keystroke */
|
||||
if(Key.UnicodeChar == 0x0D)
|
||||
{
|
||||
/* ENTER key pressed, terminate the buffer and move to a new line */
|
||||
Buffer[BufferLength] = L'\0';
|
||||
Console::Print(L"\n");
|
||||
|
||||
/* Check if the buffer is not empty */
|
||||
if(BufferLength > 0)
|
||||
{
|
||||
/* Check if the history is not full */
|
||||
if(HistoryCount < XTBL_SH_HISTORY_ENTRIES)
|
||||
{
|
||||
/* Store command in history and increment history count */
|
||||
RTL::Memory::CopyMemory(History[HistoryCount], Buffer, (BufferLength + 1) * sizeof(WCHAR));
|
||||
HistoryCount++;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Shift history entries to fit new command */
|
||||
RTL::Memory::MoveMemory(History[0],
|
||||
History[1],
|
||||
(XTBL_SH_HISTORY_ENTRIES - 1) * XTBL_SH_MAX_LINE_LENGTH * sizeof(WCHAR));
|
||||
RTL::Memory::CopyMemory(History[XTBL_SH_HISTORY_ENTRIES - 1],
|
||||
Buffer,
|
||||
(BufferLength + 1) * sizeof(WCHAR));
|
||||
}
|
||||
}
|
||||
|
||||
/* Return the command line to the caller */
|
||||
return;
|
||||
}
|
||||
else if(Key.ScanCode == 0x01)
|
||||
{
|
||||
/* UP key pressed, go back in history */
|
||||
if(HistoryIndex > 0)
|
||||
{
|
||||
/* Decrement history index */
|
||||
HistoryIndex--;
|
||||
|
||||
/* Copy history entry to buffer and update cursor position */
|
||||
BufferLength = RTL::WideString::WideStringLength(History[HistoryIndex], XTBL_SH_MAX_LINE_LENGTH - 1);
|
||||
RTL::Memory::CopyMemory(Buffer, History[HistoryIndex], (BufferLength + 1) * sizeof(WCHAR));
|
||||
CursorPosition = BufferLength;
|
||||
|
||||
/* Reprint the prompt line */
|
||||
PrintPromptLine(Buffer, BufferLength, CursorPosition, OldBufferLength);
|
||||
}
|
||||
|
||||
/* Continue to the next iteration */
|
||||
continue;
|
||||
}
|
||||
else if(Key.ScanCode == 0x02)
|
||||
{
|
||||
/* DOWN key pressed, go forward in history */
|
||||
if(HistoryIndex < HistoryCount)
|
||||
{
|
||||
/* Increment history index */
|
||||
HistoryIndex++;
|
||||
|
||||
/* Check if we are at the end of history */
|
||||
if(HistoryIndex == HistoryCount)
|
||||
{
|
||||
/* End of history, show empty prompt */
|
||||
Buffer[0] = L'\0';
|
||||
BufferLength = 0;
|
||||
CursorPosition = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Copy history entry to buffer and update cursor position */
|
||||
BufferLength = RTL::WideString::WideStringLength(History[HistoryIndex],
|
||||
XTBL_SH_MAX_LINE_LENGTH - 1);
|
||||
RTL::Memory::CopyMemory(Buffer, History[HistoryIndex], (BufferLength + 1) * sizeof(WCHAR));
|
||||
CursorPosition = BufferLength;
|
||||
}
|
||||
|
||||
/* Reprint the prompt line */
|
||||
PrintPromptLine(Buffer, BufferLength, CursorPosition, OldBufferLength);
|
||||
}
|
||||
|
||||
/* Continue to the next iteration */
|
||||
continue;
|
||||
}
|
||||
else if(Key.ScanCode == 0x03)
|
||||
{
|
||||
/* RIGHT key pressed, move cursor right */
|
||||
if(CursorPosition < BufferLength)
|
||||
{
|
||||
/* Increment cursor position */
|
||||
CursorPosition++;
|
||||
|
||||
/* Reprint the prompt line */
|
||||
PrintPromptLine(Buffer, BufferLength, CursorPosition, OldBufferLength);
|
||||
}
|
||||
|
||||
/* Continue to the next iteration */
|
||||
continue;
|
||||
}
|
||||
else if(Key.ScanCode == 0x04)
|
||||
{
|
||||
/* LEFT key pressed, move cursor left */
|
||||
if(CursorPosition > 0)
|
||||
{
|
||||
/* Decrement cursor position */
|
||||
CursorPosition--;
|
||||
|
||||
/* Reprint the prompt line */
|
||||
PrintPromptLine(Buffer, BufferLength, CursorPosition, OldBufferLength);
|
||||
}
|
||||
|
||||
/* Continue to the next iteration */
|
||||
continue;
|
||||
}
|
||||
else if(Key.ScanCode == 0x05)
|
||||
{
|
||||
/* HOME key pressed, move cursor to beginning */
|
||||
if (CursorPosition > 0)
|
||||
{
|
||||
/* Set cursor position to beginning of the line and reprint the prompt line */
|
||||
CursorPosition = 0;
|
||||
PrintPromptLine(Buffer, BufferLength, CursorPosition, OldBufferLength);
|
||||
}
|
||||
|
||||
/* Continue to the next iteration */
|
||||
continue;
|
||||
}
|
||||
else if(Key.ScanCode == 0x06)
|
||||
{
|
||||
/* END key pressed, move cursor to end */
|
||||
if (CursorPosition < BufferLength)
|
||||
{
|
||||
/* Set cursor position to end of the line and reprint the prompt line */
|
||||
CursorPosition = BufferLength;
|
||||
PrintPromptLine(Buffer, BufferLength, CursorPosition, OldBufferLength);
|
||||
}
|
||||
|
||||
/* Continue to the next iteration */
|
||||
continue;
|
||||
}
|
||||
else if(Key.ScanCode == 0x17)
|
||||
{
|
||||
/* ESC key pressed, discard the current input, move to a new line and reprint the prompt */
|
||||
Buffer[0] = L'\0';
|
||||
Console::Print(L"\n");
|
||||
PrintPrompt();
|
||||
|
||||
/* Reset cursor position, buffer length and history index */
|
||||
CursorPosition = 0;
|
||||
BufferLength = 0;
|
||||
HistoryIndex = HistoryCount;
|
||||
|
||||
/* Continue reading the command line */
|
||||
continue;
|
||||
}
|
||||
else if(Key.ScanCode == 0x08)
|
||||
{
|
||||
/* DELETE key pressed, remove character at cursor */
|
||||
if(CursorPosition < BufferLength)
|
||||
{
|
||||
/* Move memory to remove the character at cursor */
|
||||
RTL::Memory::MoveMemory(Buffer + CursorPosition,
|
||||
Buffer + CursorPosition + 1,
|
||||
(BufferLength - CursorPosition) * sizeof(WCHAR));
|
||||
|
||||
/* Decrement buffer length and reprint the prompt line */
|
||||
BufferLength--;
|
||||
PrintPromptLine(Buffer, BufferLength, CursorPosition, OldBufferLength);
|
||||
}
|
||||
|
||||
/* Continue to the next iteration */
|
||||
continue;
|
||||
}
|
||||
else if(Key.UnicodeChar == 0x08)
|
||||
{
|
||||
/* BACKSPACE key pressed, delete character before cursor */
|
||||
if(CursorPosition > 0)
|
||||
{
|
||||
/* Move memory to remove the character before cursor */
|
||||
RTL::Memory::MoveMemory(Buffer + CursorPosition - 1,
|
||||
Buffer + CursorPosition,
|
||||
(BufferLength - CursorPosition + 1) * sizeof(WCHAR));
|
||||
|
||||
/* Decrement cursor position and buffer length */
|
||||
CursorPosition--;
|
||||
BufferLength--;
|
||||
|
||||
/* Reprint the prompt line */
|
||||
PrintPromptLine(Buffer, BufferLength, CursorPosition, OldBufferLength);
|
||||
}
|
||||
|
||||
/* Continue reading the command line */
|
||||
continue;
|
||||
}
|
||||
else if(Key.UnicodeChar == 0)
|
||||
{
|
||||
/* Ignore non-printable characters */
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Make sure there is room in the buffer (reserve one slot for NULL terminator) */
|
||||
if(BufferLength < BufferSize - 1)
|
||||
{
|
||||
/* Insert character in the middle or end of the buffer */
|
||||
RTL::Memory::MoveMemory(Buffer + CursorPosition + 1,
|
||||
Buffer + CursorPosition,
|
||||
(BufferLength - CursorPosition + 1) * sizeof(WCHAR));
|
||||
Buffer[CursorPosition] = Key.UnicodeChar;
|
||||
|
||||
/* Increment cursor position and buffer length */
|
||||
CursorPosition++;
|
||||
BufferLength++;
|
||||
|
||||
/* Reprint the prompt line */
|
||||
PrintPromptLine(Buffer, BufferLength, CursorPosition, OldBufferLength);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a new command in the XTLDR shell.
|
||||
*
|
||||
* @param Command
|
||||
* Supplies the command keyword that the user types at the shell prompt.
|
||||
*
|
||||
* @param Description
|
||||
* Supplies a short help string displayed by the 'help' command.
|
||||
*
|
||||
* @param Handler
|
||||
* Supplies a pointer to the function that implements the command.
|
||||
*
|
||||
* @return This routine returns a status code indicating the success or failure of the operation.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
Shell::RegisterCommand(IN PCWSTR Command,
|
||||
IN PCWSTR Description,
|
||||
IN PBL_SHELL_COMMAND Handler)
|
||||
{
|
||||
PXTBL_SHELL_COMMAND CommandEntry;
|
||||
PLIST_ENTRY ListEntry;
|
||||
EFI_STATUS Status;
|
||||
|
||||
/* Verify that a command with this name has not already been registered */
|
||||
ListEntry = ShellCommands.Flink;
|
||||
while(ListEntry != &ShellCommands)
|
||||
{
|
||||
/* Retrieve the existing shell command entry */
|
||||
CommandEntry = CONTAIN_RECORD(ListEntry, XTBL_SHELL_COMMAND, Flink);
|
||||
|
||||
/* Compare command names case-insensitively */
|
||||
if(RTL::WideString::CompareWideStringInsensitive(CommandEntry->Command, Command, 0) == 0)
|
||||
{
|
||||
/* Duplicate command name, return error */
|
||||
return STATUS_EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
/* Check if the existing command string is lexicographically greater than the new command */
|
||||
if(RTL::WideString::CompareWideStringInsensitive(CommandEntry->Command, Command, 0) > 0)
|
||||
{
|
||||
/* Break the traversal loop */
|
||||
break;
|
||||
}
|
||||
|
||||
/* Advance to the next entry */
|
||||
ListEntry = ListEntry->Flink;
|
||||
}
|
||||
|
||||
/* Allocate memory for the new command entry */
|
||||
Status = Memory::AllocatePool(sizeof(XTBL_SHELL_COMMAND), (PVOID *)&CommandEntry);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Memory allocation failure, return error */
|
||||
return STATUS_EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
/* Populate the new command entry */
|
||||
CommandEntry->Command = (PWCHAR)Command;
|
||||
CommandEntry->Description = (PWCHAR)Description;
|
||||
CommandEntry->Handler = Handler;
|
||||
|
||||
/* Check if the traversal reached the end of the command list */
|
||||
if(ListEntry == &ShellCommands)
|
||||
{
|
||||
/* Append the new command entry to the tail of the list */
|
||||
RTL::LinkedList::InsertTailList(&ShellCommands, &CommandEntry->Flink);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Insert the new command entry before the current item */
|
||||
RTL::LinkedList::InsertHeadList(ListEntry->Blink, &CommandEntry->Flink);
|
||||
}
|
||||
|
||||
/* Return success */
|
||||
return STATUS_EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers all built-in shell commands that are provided by the XTLDR.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
Shell::RegisterBuiltinCommands()
|
||||
{
|
||||
/* Register all built-in shell commands */
|
||||
RegisterCommand(L"exit", L"Exits the shell and returns to the boot menu", CommandExit);
|
||||
RegisterCommand(L"help", L"Displays a list of all available shell commands", CommandHelp);
|
||||
RegisterCommand(L"insmod", L"Loads a specific XTLDR module", CommandInsmod);
|
||||
RegisterCommand(L"lsmod", L"Displays a list of loaded modules", CommandLsmod);
|
||||
RegisterCommand(L"poweroff", L"Shuts down the machine", CommandPoweroff);
|
||||
RegisterCommand(L"reboot", L"Reboots the machine (/EFI to enter firmware setup)", CommandReboot);
|
||||
RegisterCommand(L"ver", L"Displays the boot loader version information", CommandVersion);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the command list, registers the built-in commands and enters an interactive XTLDR shell loop.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
Shell::StartLoaderShell()
|
||||
{
|
||||
WCHAR CommandLine[XTBL_SH_MAX_LINE_LENGTH];
|
||||
PWCHAR *ArgumentVector;
|
||||
ULONG ArgumentCount;
|
||||
EFI_STATUS Status;
|
||||
|
||||
/* Initialize console */
|
||||
Console::InitializeConsole();
|
||||
|
||||
/* Clear the shell exit request flag */
|
||||
ExitRequest = FALSE;
|
||||
|
||||
/* Main XTLDR shell loop */
|
||||
while(!ExitRequest)
|
||||
{
|
||||
/* Display the shell prompt */
|
||||
PrintPrompt();
|
||||
|
||||
/* Read a command line */
|
||||
ReadCommand(CommandLine, XTBL_SH_MAX_LINE_LENGTH);
|
||||
|
||||
/* Parse the command line into a list of arguments */
|
||||
Status = ParseCommand(CommandLine, &ArgumentCount, &ArgumentVector);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Parsing failed, print error and continue */
|
||||
Console::Print(L"ERROR: Failed to parse command line (Status: 0x%llx).\n\n", Status);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Check if command line is empty */
|
||||
if(ArgumentCount == 0)
|
||||
{
|
||||
/* Skip empty command line */
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Check if command line starts with a comment symbol (#) */
|
||||
if(ArgumentVector[0][0] != L'#')
|
||||
{
|
||||
/* Dispatch the command */
|
||||
ExecuteCommand(ArgumentCount, ArgumentVector);
|
||||
}
|
||||
|
||||
/* Free the argument vector */
|
||||
Memory::FreePool(ArgumentVector);
|
||||
|
||||
/* Print a trailing blank line for visual separation */
|
||||
Console::Print(L"\n");
|
||||
}
|
||||
}
|
||||
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
@@ -1,12 +1,13 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: xtldr/volume.c
|
||||
* FILE: xtldr/volume.cc
|
||||
* DESCRIPTION: XTLDR volume support
|
||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||
* Aiken Harris <harraiken91@gmail.com>
|
||||
*/
|
||||
|
||||
#include <xtldr.h>
|
||||
#include <xtldr.hh>
|
||||
|
||||
|
||||
/**
|
||||
@@ -21,15 +22,16 @@
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlCloseVolume(IN PEFI_HANDLE VolumeHandle)
|
||||
Volume::CloseVolume(IN PEFI_HANDLE VolumeHandle)
|
||||
{
|
||||
EFI_GUID LIPGuid = EFI_LOADED_IMAGE_PROTOCOL_GUID;
|
||||
|
||||
/* Make sure a handle specified */
|
||||
if(VolumeHandle != NULL)
|
||||
if(VolumeHandle != NULLPTR)
|
||||
{
|
||||
/* Close a handle */
|
||||
return EfiSystemTable->BootServices->CloseProtocol(VolumeHandle, &LIPGuid, EfiImageHandle, NULL);
|
||||
return XtLoader::GetEfiSystemTable()->BootServices->CloseProtocol(VolumeHandle, &LIPGuid,
|
||||
XtLoader::GetEfiImageHandle(), NULLPTR);
|
||||
}
|
||||
|
||||
/* Return success */
|
||||
@@ -45,10 +47,14 @@ BlCloseVolume(IN PEFI_HANDLE VolumeHandle)
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlEnumerateBlockDevices()
|
||||
Volume::EnumerateBlockDevices()
|
||||
{
|
||||
PEFI_DEVICE_PATH_PROTOCOL LastNode = NULL;
|
||||
PEFI_BLOCK_DEVICE_DATA ParentNode = NULL;
|
||||
EFI_GUID LoadedImageProtocolGuid = EFI_LOADED_IMAGE_PROTOCOL_GUID;
|
||||
EFI_GUID BlockIoGuid = EFI_BLOCK_IO_PROTOCOL_GUID;
|
||||
EFI_HANDLE BootDeviceHandle = NULLPTR, DeviceHandle = NULLPTR;
|
||||
EFI_LOADED_IMAGE_PROTOCOL* LoadedImage;
|
||||
PEFI_DEVICE_PATH_PROTOCOL DevicePath = NULLPTR, LastNode = NULLPTR;
|
||||
PEFI_BLOCK_DEVICE_DATA ParentNode = NULLPTR;
|
||||
PEFI_BLOCK_DEVICE_DATA BlockDeviceData;
|
||||
PEFI_BLOCK_DEVICE BlockDevice;
|
||||
LIST_ENTRY BlockDevices;
|
||||
@@ -62,15 +68,28 @@ BlEnumerateBlockDevices()
|
||||
USHORT DriveType;
|
||||
ULONG CDCount = 0, FDCount = 0, HDCount = 0, RDCount = 0;
|
||||
|
||||
/* Initialize list entries */
|
||||
RtlInitializeListHead(&BlockDevices);
|
||||
RtlInitializeListHead(&EfiBlockDevices);
|
||||
|
||||
/* Discover EFI block devices and store them in linked list */
|
||||
Status = BlpDiscoverEfiBlockDevices(&BlockDevices);
|
||||
/* Get the device handle of the image that is running */
|
||||
Status = XtLoader::GetEfiSystemTable()->BootServices->HandleProtocol(XtLoader::GetEfiImageHandle(), &LoadedImageProtocolGuid,
|
||||
(VOID**)&LoadedImage);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
BlDebugPrint(L"ERROR: Failed to discover EFI block devices (Status Code: 0x%zX)\n", Status);
|
||||
/* Failed to get boot device handle */
|
||||
Debug::Print(L"ERROR: Failed to get boot device handle (Status Code: 0x%zX)\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Save the boot device handle */
|
||||
BootDeviceHandle = LoadedImage->DeviceHandle;
|
||||
|
||||
/* Initialize list entries */
|
||||
RTL::LinkedList::InitializeListHead(&BlockDevices);
|
||||
RTL::LinkedList::InitializeListHead(&EfiBlockDevices);
|
||||
|
||||
/* Discover EFI block devices and store them in linked list */
|
||||
Status = DiscoverEfiBlockDevices(&BlockDevices);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
Debug::Print(L"ERROR: Failed to discover EFI block devices (Status Code: 0x%zX)\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
@@ -78,21 +97,42 @@ BlEnumerateBlockDevices()
|
||||
ListEntry = BlockDevices.Flink;
|
||||
while(ListEntry != &BlockDevices)
|
||||
{
|
||||
/* Take block device from the list */
|
||||
/* Get data for the next discovered device. */
|
||||
BlockDeviceData = CONTAIN_RECORD(ListEntry, EFI_BLOCK_DEVICE_DATA, ListEntry);
|
||||
PartitionGuid = NULLPTR;
|
||||
|
||||
/* Find last node */
|
||||
Status = BlpFindLastBlockDeviceNode(BlockDeviceData->DevicePath, &LastNode);
|
||||
Status = FindLastBlockDeviceNode(BlockDeviceData->DevicePath, &LastNode);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
BlDebugPrint(L"WARNING: Block device last node not found\n");
|
||||
/* Skip this device if its last node cannot be found, as it is required for classification */
|
||||
Debug::Print(L"WARNING: Block device last node not found\n");
|
||||
ListEntry = ListEntry->Flink;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Set drive type to 'unknown' by default */
|
||||
/* Initialize drive type before attempting to classify the device */
|
||||
DriveType = XTBL_BOOT_DEVICE_UNKNOWN;
|
||||
|
||||
/* Locate the parent for this block device to ensure it is not an orphaned entry */
|
||||
if(!FindParentBlockDevice(&BlockDevices, BlockDeviceData, &ParentNode))
|
||||
{
|
||||
/* Orphaned device found. Log a warning and skip it as it cannot be properly classified */
|
||||
Debug::Print(L"WARNING: No parent device found, skipping orphaned media device path\n");
|
||||
ListEntry = ListEntry->Flink;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Verify that media information is available, as some devices may not report it */
|
||||
if(!BlockDeviceData->BlockIo->Media)
|
||||
{
|
||||
/* The device is unusable without media info, log a warning and skip it */
|
||||
Debug::Print(L"WARNING: Block device is missing media information\n");
|
||||
ListEntry = ListEntry->Flink;
|
||||
continue;
|
||||
}
|
||||
Media = BlockDeviceData->BlockIo->Media;
|
||||
|
||||
/* Check last node type */
|
||||
if(LastNode->Type == EFI_ACPI_DEVICE_PATH && LastNode->SubType == EFI_ACPI_DP)
|
||||
{
|
||||
@@ -101,87 +141,95 @@ BlEnumerateBlockDevices()
|
||||
if(AcpiDevice->HID == 0x60441D0 || AcpiDevice->HID == 0x70041D0 || AcpiDevice->HID == 0x70141D1)
|
||||
{
|
||||
/* Floppy drive found */
|
||||
Media = BlockDeviceData->BlockIo->Media;
|
||||
DriveType = XTBL_BOOT_DEVICE_FLOPPY;
|
||||
DriveNumber = FDCount++;
|
||||
PartitionNumber = 0;
|
||||
|
||||
/* Print debug message */
|
||||
BlDebugPrint(L"Found Floppy Disk (DiskNumber: %lu, MediaPresent: %u, RO: %u)\n",
|
||||
DriveNumber, Media->MediaPresent, Media->ReadOnly);
|
||||
Debug::Print(L"Found Floppy Disk (DiskNumber: %lu, MediaPresent: %u, RO: %u)\n",
|
||||
DriveNumber, Media->MediaPresent, Media->ReadOnly);
|
||||
}
|
||||
}
|
||||
else if(LastNode->Type == EFI_MEDIA_DEVICE_PATH)
|
||||
else if((LastNode->Type == EFI_MEDIA_DEVICE_PATH && LastNode->SubType == EFI_MEDIA_CDROM_DP) ||
|
||||
(LastNode->Type == EFI_MESSAGING_DEVICE_PATH &&
|
||||
(LastNode->SubType == EFI_MESSAGING_ATAPI_DP || LastNode->SubType == EFI_MESSAGING_SATA_DP) &&
|
||||
Media->MediaPresent && Media->RemovableMedia))
|
||||
{
|
||||
/* Media device path found */
|
||||
if(LastNode->SubType == EFI_MEDIA_CDROM_DP)
|
||||
{
|
||||
/* Optical drive found */
|
||||
Media = BlockDeviceData->BlockIo->Media;
|
||||
DriveType = XTBL_BOOT_DEVICE_CDROM;
|
||||
DriveNumber = CDCount++;
|
||||
PartitionNumber = 0;
|
||||
/* Optical drive found */
|
||||
DriveType = XTBL_BOOT_DEVICE_CDROM;
|
||||
DriveNumber = CDCount++;
|
||||
PartitionNumber = 0;
|
||||
|
||||
/* Print debug message */
|
||||
BlDebugPrint(L"Found CD-ROM drive (DriveNumber: %lu, MediaPresent: %u, RemovableMedia: %u, RO: %u)\n",
|
||||
DriveNumber, Media->MediaPresent, Media->RemovableMedia, Media->ReadOnly);
|
||||
}
|
||||
else if(LastNode->SubType == EFI_MEDIA_HARDDRIVE_DP)
|
||||
{
|
||||
/* Hard disk partition found */
|
||||
Media = BlockDeviceData->BlockIo->Media;
|
||||
HDPath = (PEFI_HARDDRIVE_DEVICE_PATH)LastNode;
|
||||
DriveType = XTBL_BOOT_DEVICE_HARDDISK;
|
||||
DriveNumber = (HDPath->PartitionNumber == 1) ? HDCount++ : HDCount - 1;
|
||||
PartitionNumber = HDPath->PartitionNumber;
|
||||
PartitionGuid = (PEFI_GUID)HDPath->Signature;
|
||||
/* Print debug message */
|
||||
Debug::Print(L"Found CD-ROM drive (DriveNumber: %lu, MediaPresent: %u, RemovableMedia: %u, RO: %u)\n",
|
||||
DriveNumber, Media->MediaPresent, Media->RemovableMedia, Media->ReadOnly);
|
||||
}
|
||||
else if(LastNode->Type == EFI_MEDIA_DEVICE_PATH && LastNode->SubType == EFI_MEDIA_HARDDRIVE_DP)
|
||||
{
|
||||
/* Hard disk partition found */
|
||||
HDPath = (PEFI_HARDDRIVE_DEVICE_PATH)LastNode;
|
||||
DriveType = XTBL_BOOT_DEVICE_HARDDISK;
|
||||
DriveNumber = (HDPath->PartitionNumber == 1) ? HDCount++ : HDCount - 1;
|
||||
PartitionNumber = HDPath->PartitionNumber;
|
||||
PartitionGuid = (PEFI_GUID)HDPath->Signature;
|
||||
|
||||
/* Print debug message */
|
||||
BlDebugPrint(L"Found Hard Disk partition (DiskNumber: %lu, PartNumber: %lu, "
|
||||
L"MBRType: %u, GUID: {%V}, PartSize: %uB)\n",
|
||||
DriveNumber, PartitionNumber, HDPath->MBRType,
|
||||
PartitionGuid, HDPath->PartitionSize * Media->BlockSize);
|
||||
}
|
||||
else if(LastNode->SubType == EFI_MEDIA_RAMDISK_DP)
|
||||
/* Check if this is the EFI System Partition (ESP) */
|
||||
if(BootDeviceHandle != NULLPTR)
|
||||
{
|
||||
/* RAM disk found */
|
||||
Media = BlockDeviceData->BlockIo->Media;
|
||||
DriveType = XTBL_BOOT_DEVICE_RAMDISK;
|
||||
DriveNumber = RDCount++;
|
||||
PartitionNumber = 0;
|
||||
|
||||
/* Print debug message */
|
||||
BlDebugPrint(L"Found RAM Disk (DiskNumber: %lu, MediaPresent: %u)\n",
|
||||
DriveNumber, Media->MediaPresent);
|
||||
/* Allocate memory for device path */
|
||||
DevicePath = DuplicateDevicePath(BlockDeviceData->DevicePath);
|
||||
if(DevicePath != NULLPTR)
|
||||
{
|
||||
/* Check if this is the boot device */
|
||||
Status = XtLoader::GetEfiSystemTable()->BootServices->LocateDevicePath(&BlockIoGuid, &DevicePath,
|
||||
&DeviceHandle);
|
||||
if(Status == STATUS_EFI_SUCCESS && DeviceHandle == BootDeviceHandle)
|
||||
{
|
||||
/* Mark partition as ESP */
|
||||
DriveType |= XTBL_BOOT_DEVICE_ESP;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!BlpFindParentBlockDevice(&BlockDevices, BlockDeviceData, ParentNode))
|
||||
{
|
||||
BlDebugPrint(L"WARNING: No parent device found, skipping orphaned media device path\n");
|
||||
continue;
|
||||
}
|
||||
/* Print debug message */
|
||||
Debug::Print(L"Found Hard Disk partition (DiskNumber: %lu, PartNumber: %lu, "
|
||||
L"MBRType: %u, GUID: {%V}, PartSize: %lluB) %S\n",
|
||||
DriveNumber, PartitionNumber, HDPath->MBRType,
|
||||
PartitionGuid, HDPath->PartitionSize * Media->BlockSize,
|
||||
(DriveType & XTBL_BOOT_DEVICE_ESP) ? L"(ESP)" : L"");
|
||||
}
|
||||
else if(LastNode->Type == EFI_MEDIA_DEVICE_PATH && LastNode->SubType == EFI_MEDIA_RAMDISK_DP)
|
||||
{
|
||||
/* RAM disk found */
|
||||
DriveType = XTBL_BOOT_DEVICE_RAMDISK;
|
||||
DriveNumber = RDCount++;
|
||||
PartitionNumber = 0;
|
||||
|
||||
/* Print debug message */
|
||||
Debug::Print(L"Found RAM Disk (DiskNumber: %lu, MediaPresent: %u)\n",
|
||||
DriveNumber, Media->MediaPresent);
|
||||
}
|
||||
|
||||
/* Make sure the device found has valid type set */
|
||||
if(DriveType != XTBL_BOOT_DEVICE_UNKNOWN)
|
||||
{
|
||||
/* Allocate memory for block device */
|
||||
Status = BlAllocateMemoryPool(sizeof(EFI_BLOCK_DEVICE), (PVOID *)&BlockDevice);
|
||||
Status = Memory::AllocatePool(sizeof(EFI_BLOCK_DEVICE), (PVOID *)&BlockDevice);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
BlDebugPrint(L"ERROR: Failed to allocate memory pool for block device (Status Code: 0x%zX)\n", Status);
|
||||
Debug::Print(L"ERROR: Failed to allocate memory pool for block device (Status Code: 0x%zX)\n", Status);
|
||||
return STATUS_EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
/* Initialize block device */
|
||||
BlockDevice->DevicePath = BlpDuplicateDevicePath(BlockDeviceData->DevicePath);
|
||||
BlockDevice->DevicePath = DuplicateDevicePath(BlockDeviceData->DevicePath);
|
||||
BlockDevice->DriveType = DriveType;
|
||||
BlockDevice->DriveNumber = DriveNumber;
|
||||
BlockDevice->PartitionNumber = PartitionNumber;
|
||||
BlockDevice->PartitionGuid = PartitionGuid;
|
||||
|
||||
/* Add block device to global list */
|
||||
RtlInsertTailList(&EfiBlockDevices, &BlockDevice->ListEntry);
|
||||
RTL::LinkedList::InsertTailList(&EfiBlockDevices, &BlockDevice->ListEntry);
|
||||
}
|
||||
|
||||
/* Get next entry from linked list */
|
||||
@@ -210,13 +258,13 @@ BlEnumerateBlockDevices()
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlFindVolumeDevicePath(IN PEFI_DEVICE_PATH_PROTOCOL FsHandle,
|
||||
Volume::FindDevicePath(IN PEFI_DEVICE_PATH_PROTOCOL FsHandle,
|
||||
IN CONST PWCHAR FileSystemPath,
|
||||
OUT PEFI_DEVICE_PATH_PROTOCOL* DevicePath)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
SIZE_T FsPathLength, DevicePathLength = 0;
|
||||
PEFI_FILEPATH_DEVICE_PATH FilePath = NULL;
|
||||
PEFI_FILEPATH_DEVICE_PATH FilePath = NULLPTR;
|
||||
PEFI_DEVICE_PATH_PROTOCOL EndDevicePath;
|
||||
PEFI_DEVICE_PATH_PROTOCOL DevicePathHandle;
|
||||
|
||||
@@ -245,10 +293,10 @@ BlFindVolumeDevicePath(IN PEFI_DEVICE_PATH_PROTOCOL FsHandle,
|
||||
}
|
||||
|
||||
/* Check real path length */
|
||||
FsPathLength = RtlWideStringLength(FileSystemPath, 0) * sizeof(WCHAR);
|
||||
FsPathLength = RTL::WideString::WideStringLength(FileSystemPath, 0) * sizeof(WCHAR);
|
||||
|
||||
/* Allocate memory pool for device path */
|
||||
Status = BlAllocateMemoryPool(FsPathLength + DevicePathLength + sizeof(EFI_DEVICE_PATH_PROTOCOL),
|
||||
Status = Memory::AllocatePool(FsPathLength + DevicePathLength + sizeof(EFI_DEVICE_PATH_PROTOCOL),
|
||||
(PVOID *)DevicePath);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
@@ -257,7 +305,7 @@ BlFindVolumeDevicePath(IN PEFI_DEVICE_PATH_PROTOCOL FsHandle,
|
||||
}
|
||||
|
||||
/* Set file path */
|
||||
RtlCopyMemory(*DevicePath, FsHandle, DevicePathLength);
|
||||
RTL::Memory::CopyMemory(*DevicePath, FsHandle, DevicePathLength);
|
||||
FilePath = (PEFI_FILEPATH_DEVICE_PATH)((PUCHAR)*DevicePath + DevicePathLength);
|
||||
FilePath->Header.Type = EFI_MEDIA_DEVICE_PATH;
|
||||
FilePath->Header.SubType = EFI_MEDIA_FILEPATH_DP;
|
||||
@@ -265,7 +313,7 @@ BlFindVolumeDevicePath(IN PEFI_DEVICE_PATH_PROTOCOL FsHandle,
|
||||
FilePath->Header.Length[1] = FilePath->Header.Length[0] >> 8;
|
||||
|
||||
/* Set device path end node */
|
||||
RtlCopyMemory(FilePath->PathName, FileSystemPath, FsPathLength + sizeof(WCHAR));
|
||||
RTL::Memory::CopyMemory(FilePath->PathName, FileSystemPath, FsPathLength + sizeof(WCHAR));
|
||||
EndDevicePath = (PEFI_DEVICE_PATH_PROTOCOL)&FilePath->PathName[(FsPathLength / sizeof(WCHAR)) + 1];
|
||||
EndDevicePath->Type = EFI_END_DEVICE_PATH;
|
||||
EndDevicePath->SubType = EFI_END_ENTIRE_DP;
|
||||
@@ -291,26 +339,26 @@ BlFindVolumeDevicePath(IN PEFI_DEVICE_PATH_PROTOCOL FsHandle,
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlGetEfiPath(IN PWCHAR SystemPath,
|
||||
OUT PWCHAR *EfiPath)
|
||||
Volume::GetEfiPath(IN PWCHAR SystemPath,
|
||||
OUT PWCHAR *EfiPath)
|
||||
{
|
||||
SIZE_T Index, PathLength;
|
||||
EFI_STATUS Status;
|
||||
|
||||
/* Get system path length */
|
||||
PathLength = RtlWideStringLength(SystemPath, 0);
|
||||
PathLength = RTL::WideString::WideStringLength(SystemPath, 0);
|
||||
|
||||
/* Allocate memory for storing EFI path */
|
||||
Status = BlAllocateMemoryPool(sizeof(WCHAR) * (PathLength + 1), (PVOID *)EfiPath);
|
||||
Status = Memory::AllocatePool(sizeof(WCHAR) * (PathLength + 1), (PVOID *)EfiPath);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Failed to allocate memory, print error message and return status code */
|
||||
BlDebugPrint(L"ERROR: Memory allocation failure (Status Code: 0x%zX)\n", Status);
|
||||
Debug::Print(L"ERROR: Memory allocation failure (Status Code: 0x%zX)\n", Status);
|
||||
return STATUS_EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
/* Make a copy of SystemPath string */
|
||||
RtlCopyMemory(*EfiPath, SystemPath, sizeof(WCHAR) * (PathLength + 1));
|
||||
RTL::Memory::CopyMemory(*EfiPath, SystemPath, sizeof(WCHAR) * (PathLength + 1));
|
||||
|
||||
/* Replace directory separator if needed to comply with EFI standard */
|
||||
for(Index = 0; Index < PathLength; Index++)
|
||||
@@ -344,7 +392,7 @@ BlGetEfiPath(IN PWCHAR SystemPath,
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlGetVolumeDevicePath(IN PWCHAR SystemPath,
|
||||
Volume::GetDevicePath(IN PWCHAR SystemPath,
|
||||
OUT PEFI_DEVICE_PATH_PROTOCOL *DevicePath,
|
||||
OUT PWCHAR *ArcName,
|
||||
OUT PWCHAR *Path)
|
||||
@@ -359,7 +407,7 @@ BlGetVolumeDevicePath(IN PWCHAR SystemPath,
|
||||
EFI_STATUS Status;
|
||||
|
||||
/* Make sure this is not set */
|
||||
*DevicePath = NULL;
|
||||
*DevicePath = NULLPTR;
|
||||
|
||||
/* Find volume path and its length */
|
||||
Volume = SystemPath;
|
||||
@@ -383,13 +431,13 @@ BlGetVolumeDevicePath(IN PWCHAR SystemPath,
|
||||
if(PathLength == GUID_STRING_LENGTH)
|
||||
{
|
||||
/* This is EFI GUID */
|
||||
BlDebugPrint(L"WARNING: EFI/GPT GUID in system path is not supported\n");
|
||||
Debug::Print(L"WARNING: EFI/GPT GUID in system path is not supported\n");
|
||||
return STATUS_EFI_UNSUPPORTED;
|
||||
}
|
||||
else if(PathLength == PARTUUID_STRING_LENGTH)
|
||||
{
|
||||
/* This is MBR UUID */
|
||||
BlDebugPrint(L"WARNING: MBR partition UUID in system path is not supported\n");
|
||||
Debug::Print(L"WARNING: MBR partition UUID in system path is not supported\n");
|
||||
return STATUS_EFI_UNSUPPORTED;
|
||||
}
|
||||
else
|
||||
@@ -401,14 +449,14 @@ BlGetVolumeDevicePath(IN PWCHAR SystemPath,
|
||||
else
|
||||
{
|
||||
/* Defaults to ARC path, dissect it */
|
||||
Status = BlpDissectVolumeArcPath(SystemPath, ArcName, Path, &DriveType, &DriveNumber, &PartNumber);
|
||||
Status = DissectArcPath(SystemPath, ArcName, Path, &DriveType, &DriveNumber, &PartNumber);
|
||||
}
|
||||
|
||||
/* Check if volume path parsed successfully */
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Failed to parse system path */
|
||||
BlDebugPrint(L"ERROR: Failed to parse system path: '%s' (Status Code: 0x%zX)\n", SystemPath, Status);
|
||||
Debug::Print(L"ERROR: Failed to parse system path: '%S' (Status Code: 0x%zX)\n", SystemPath, Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
@@ -418,22 +466,36 @@ BlGetVolumeDevicePath(IN PWCHAR SystemPath,
|
||||
{
|
||||
/* Check if this is the volume we are looking for */
|
||||
Device = CONTAIN_RECORD(ListEntry, EFI_BLOCK_DEVICE, ListEntry);
|
||||
if((Device->DriveType == DriveType && Device->DriveNumber == DriveNumber &&
|
||||
Device->PartitionNumber == PartNumber))
|
||||
if(DriveType == XTBL_BOOT_DEVICE_ESP)
|
||||
{
|
||||
/* Found volume */
|
||||
*DevicePath = Device->DevicePath;
|
||||
break;
|
||||
/* ESP requested, verify if flag is set for this device */
|
||||
if((Device->DriveType & XTBL_BOOT_DEVICE_ESP) != 0)
|
||||
{
|
||||
/* Found volume */
|
||||
*DevicePath = Device->DevicePath;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(((Device->DriveType & DriveType) == DriveType) &&
|
||||
(Device->DriveNumber == DriveNumber) &&
|
||||
(Device->PartitionNumber == PartNumber))
|
||||
{
|
||||
/* Found volume */
|
||||
*DevicePath = Device->DevicePath;
|
||||
break;
|
||||
}
|
||||
}
|
||||
ListEntry = ListEntry->Flink;
|
||||
}
|
||||
|
||||
/* Check if volume was found */
|
||||
if(*DevicePath == NULL)
|
||||
if(*DevicePath == NULLPTR)
|
||||
{
|
||||
/* Failed to find volume */
|
||||
BlDebugPrint(L"ERROR: Volume (DriveType: %u, DriveNumber: %lu, PartNumber: %lu) not found\n",
|
||||
DriveType, DriveNumber, PartNumber);
|
||||
/* Volume not found */
|
||||
Debug::Print(L"ERROR: Volume (DriveType: %u, DriveNumber: %lu, PartNumber: %lu) not found\n",
|
||||
DriveType, DriveNumber, PartNumber);
|
||||
return STATUS_EFI_NOT_FOUND;
|
||||
}
|
||||
|
||||
@@ -459,9 +521,9 @@ BlGetVolumeDevicePath(IN PWCHAR SystemPath,
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlOpenVolume(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath,
|
||||
OUT PEFI_HANDLE DiskHandle,
|
||||
OUT PEFI_FILE_HANDLE *FsHandle)
|
||||
Volume::OpenVolume(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath,
|
||||
OUT PEFI_HANDLE DiskHandle,
|
||||
OUT PEFI_FILE_HANDLE *FsHandle)
|
||||
{
|
||||
EFI_GUID SFSGuid = EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID;
|
||||
EFI_GUID LIPGuid = EFI_LOADED_IMAGE_PROTOCOL_GUID;
|
||||
@@ -470,10 +532,10 @@ BlOpenVolume(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath,
|
||||
EFI_STATUS Status;
|
||||
|
||||
/* Check if device path has been passed or not */
|
||||
if(DevicePath != NULL)
|
||||
if(DevicePath != NULLPTR)
|
||||
{
|
||||
/* Locate the device path */
|
||||
Status = EfiSystemTable->BootServices->LocateDevicePath(&SFSGuid, &DevicePath, DiskHandle);
|
||||
Status = XtLoader::GetEfiSystemTable()->BootServices->LocateDevicePath(&SFSGuid, &DevicePath, DiskHandle);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Failed to locate device path */
|
||||
@@ -483,8 +545,12 @@ BlOpenVolume(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath,
|
||||
else
|
||||
{
|
||||
/* Open the image protocol if no device path specified */
|
||||
Status = EfiSystemTable->BootServices->OpenProtocol(EfiImageHandle, &LIPGuid, (PVOID *)&ImageProtocol,
|
||||
EfiImageHandle, NULL, EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL);
|
||||
Status = XtLoader::GetEfiSystemTable()->BootServices->OpenProtocol(XtLoader::GetEfiImageHandle(),
|
||||
&LIPGuid,
|
||||
(PVOID *)&ImageProtocol,
|
||||
XtLoader::GetEfiImageHandle(),
|
||||
NULLPTR,
|
||||
EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Failed to open image protocol */
|
||||
@@ -496,14 +562,16 @@ BlOpenVolume(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath,
|
||||
}
|
||||
|
||||
/* Open the filesystem protocol */
|
||||
Status = EfiSystemTable->BootServices->OpenProtocol(*DiskHandle, &SFSGuid, (PVOID *)&FileSystemProtocol,
|
||||
EfiImageHandle, NULL, EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL);
|
||||
Status = XtLoader::GetEfiSystemTable()->BootServices->OpenProtocol(*DiskHandle, &SFSGuid,
|
||||
(PVOID *)&FileSystemProtocol,
|
||||
XtLoader::GetEfiImageHandle(), NULLPTR,
|
||||
EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL);
|
||||
|
||||
/* Check if filesystem protocol opened successfully */
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Failed to open the filesystem protocol, close volume */
|
||||
BlCloseVolume(*DiskHandle);
|
||||
CloseVolume(DiskHandle);
|
||||
return Status;
|
||||
}
|
||||
|
||||
@@ -512,7 +580,7 @@ BlOpenVolume(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath,
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Failed to open the filesystem, close volume */
|
||||
BlCloseVolume(*DiskHandle);
|
||||
CloseVolume(DiskHandle);
|
||||
return Status;
|
||||
}
|
||||
|
||||
@@ -541,10 +609,10 @@ BlOpenVolume(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath,
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlReadFile(IN PEFI_FILE_HANDLE DirHandle,
|
||||
IN CONST PWCHAR FileName,
|
||||
OUT PVOID *FileData,
|
||||
OUT PSIZE_T FileSize)
|
||||
Volume::ReadFile(IN PEFI_FILE_HANDLE DirHandle,
|
||||
IN PCWSTR FileName,
|
||||
OUT PVOID *FileData,
|
||||
OUT PSIZE_T FileSize)
|
||||
{
|
||||
EFI_GUID FileInfoGuid = EFI_FILE_INFO_PROTOCOL_GUID;
|
||||
EFI_PHYSICAL_ADDRESS Address;
|
||||
@@ -554,7 +622,7 @@ BlReadFile(IN PEFI_FILE_HANDLE DirHandle,
|
||||
UINT_PTR ReadSize;
|
||||
SIZE_T Pages;
|
||||
|
||||
Status = DirHandle->Open(DirHandle, &FileHandle, FileName, EFI_FILE_MODE_READ,
|
||||
Status = DirHandle->Open(DirHandle, &FileHandle, (PWCHAR)FileName, EFI_FILE_MODE_READ,
|
||||
EFI_FILE_READ_ONLY | EFI_FILE_HIDDEN | EFI_FILE_SYSTEM);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
@@ -566,7 +634,7 @@ BlReadFile(IN PEFI_FILE_HANDLE DirHandle,
|
||||
ReadSize = sizeof(EFI_FILE_INFO) + 32;
|
||||
|
||||
/* Allocate necessary amount of memory */
|
||||
Status = BlAllocateMemoryPool(ReadSize, (PVOID *)&FileInfo);
|
||||
Status = Memory::AllocatePool(ReadSize, (PVOID *)&FileInfo);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Memory allocation failure */
|
||||
@@ -579,8 +647,8 @@ BlReadFile(IN PEFI_FILE_HANDLE DirHandle,
|
||||
if(Status == STATUS_EFI_BUFFER_TOO_SMALL)
|
||||
{
|
||||
/* Buffer is too small, but EFI tells the required size, so reallocate */
|
||||
BlFreeMemoryPool(&FileInfo);
|
||||
Status = BlAllocateMemoryPool(ReadSize, (PVOID *)&FileInfo);
|
||||
Memory::FreePool(&FileInfo);
|
||||
Status = Memory::AllocatePool(ReadSize, (PVOID *)&FileInfo);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Memory allocation failure */
|
||||
@@ -597,7 +665,7 @@ BlReadFile(IN PEFI_FILE_HANDLE DirHandle,
|
||||
{
|
||||
/* Unable to get file information */
|
||||
FileHandle->Close(FileHandle);
|
||||
BlFreeMemoryPool(&FileInfo);
|
||||
Memory::FreePool(&FileInfo);
|
||||
return Status;
|
||||
}
|
||||
|
||||
@@ -606,19 +674,19 @@ BlReadFile(IN PEFI_FILE_HANDLE DirHandle,
|
||||
Pages = EFI_SIZE_TO_PAGES(FileInfo->FileSize);
|
||||
|
||||
/* Allocate pages */
|
||||
Status = BlAllocateMemoryPages(Pages, &Address);
|
||||
Status = Memory::AllocatePages(AllocateAnyPages, Pages, &Address);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Pages allocation failure */
|
||||
FileHandle->Close(FileHandle);
|
||||
BlFreeMemoryPool(&FileInfo);
|
||||
Memory::FreePool(&FileInfo);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Calculate number of bytes to read and zero memory */
|
||||
ReadSize = Pages * EFI_PAGE_SIZE;
|
||||
*FileData = (PCHAR)(UINT_PTR)Address;
|
||||
RtlZeroMemory(*FileData, ReadSize);
|
||||
RTL::Memory::ZeroMemory(*FileData, ReadSize);
|
||||
|
||||
/* Read data from the file */
|
||||
Status = FileHandle->Read(FileHandle, &ReadSize, *FileData);
|
||||
@@ -626,14 +694,14 @@ BlReadFile(IN PEFI_FILE_HANDLE DirHandle,
|
||||
{
|
||||
/* Failed to read data */
|
||||
FileHandle->Close(FileHandle);
|
||||
BlFreeMemoryPool(&FileInfo);
|
||||
BlFreeMemoryPages(Pages, (EFI_PHYSICAL_ADDRESS)(UINT_PTR)*FileData);
|
||||
Memory::FreePool(&FileInfo);
|
||||
Memory::FreePages(Pages, (EFI_PHYSICAL_ADDRESS)(UINT_PTR)*FileData);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Close handle and free memory */
|
||||
FileHandle->Close(FileHandle);
|
||||
BlFreeMemoryPool(FileInfo);
|
||||
Memory::FreePool(FileInfo);
|
||||
|
||||
/* Return success */
|
||||
return STATUS_EFI_SUCCESS;
|
||||
@@ -651,23 +719,23 @@ BlReadFile(IN PEFI_FILE_HANDLE DirHandle,
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlpDiscoverEfiBlockDevices(OUT PLIST_ENTRY BlockDevices)
|
||||
Volume::DiscoverEfiBlockDevices(OUT PLIST_ENTRY BlockDevices)
|
||||
{
|
||||
EFI_GUID DevicePathGuid = EFI_DEVICE_PATH_PROTOCOL_GUID;
|
||||
EFI_GUID IoGuid = EFI_BLOCK_IO_PROTOCOL_GUID;
|
||||
PEFI_DEVICE_PATH_PROTOCOL DevicePath;
|
||||
PEFI_BLOCK_DEVICE_DATA BlockDevice;
|
||||
UINT_PTR HandlesCount, Index;
|
||||
PEFI_HANDLE Handles = NULL;
|
||||
PEFI_HANDLE Handles = NULLPTR;
|
||||
PEFI_BLOCK_IO_PROTOCOL Io;
|
||||
EFI_STATUS Status;
|
||||
|
||||
/* Locate handles which support the disk I/O interface */
|
||||
Status = BlLocateProtocolHandles(&Handles, &HandlesCount, &IoGuid);
|
||||
Status = Protocol::LocateProtocolHandles(&Handles, &HandlesCount, &IoGuid);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Failed to locate handles */
|
||||
BlDebugPrint(L"ERROR: Failed to locate block devices handles (Status Code: 0x%zX)\n", Status);
|
||||
Debug::Print(L"ERROR: Failed to locate block devices handles (Status Code: 0x%zX)\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
@@ -675,15 +743,15 @@ BlpDiscoverEfiBlockDevices(OUT PLIST_ENTRY BlockDevices)
|
||||
for(Index = 0; Index < HandlesCount; Index++)
|
||||
{
|
||||
/* Print debug message */
|
||||
BlDebugPrint(L"Opening %lu block device from %lu discovered\n", Index + 1, HandlesCount);
|
||||
Debug::Print(L"Opening %lu block device from %lu discovered\n", Index + 1, HandlesCount);
|
||||
|
||||
/* Open I/O protocol for given handle */
|
||||
Io = NULL;
|
||||
Status = BlOpenProtocolHandle(Handles[Index], (PVOID *)&Io, &IoGuid);
|
||||
if(Status != STATUS_EFI_SUCCESS || Io == NULL)
|
||||
Io = NULLPTR;
|
||||
Status = Protocol::OpenProtocolHandle(Handles[Index], (PVOID *)&Io, &IoGuid);
|
||||
if(Status != STATUS_EFI_SUCCESS || Io == NULLPTR)
|
||||
{
|
||||
/* Failed to open I/O protocol, skip it */
|
||||
BlDebugPrint(L"WARNING: Failed to open EFI Block I/O protocol (Status Code: 0x%zX)\n", Status);
|
||||
Debug::Print(L"WARNING: Failed to open EFI Block I/O protocol (Status Code: 0x%zX)\n", Status);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -691,40 +759,44 @@ BlpDiscoverEfiBlockDevices(OUT PLIST_ENTRY BlockDevices)
|
||||
if(Io->Media && Io->Media->BlockSize == 1 && Io->Media->MediaId == 0x69505845U)
|
||||
{
|
||||
/* Skip stub as it is non-functional */
|
||||
BlDebugPrint(L"WARNING: Skipping iPXE stub block I/O protocol");
|
||||
Debug::Print(L"WARNING: Skipping iPXE stub block I/O protocol");
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Check if DevicePath protocol is supported by this handle */
|
||||
DevicePath = NULL;
|
||||
Status = EfiSystemTable->BootServices->HandleProtocol(Handles[Index], &DevicePathGuid, (PVOID *)&DevicePath);
|
||||
if(Status != STATUS_EFI_SUCCESS || DevicePath == NULL)
|
||||
DevicePath = NULLPTR;
|
||||
Status = XtLoader::GetEfiSystemTable()->BootServices->HandleProtocol(Handles[Index], &DevicePathGuid,
|
||||
(PVOID *)&DevicePath);
|
||||
if(Status != STATUS_EFI_SUCCESS || DevicePath == NULLPTR)
|
||||
{
|
||||
/* Device failed to handle DP protocol */
|
||||
BlDebugPrint(L"WARNING: Unable to open DevicePath protocol (Status Code: 0x%zX)\n", Status);
|
||||
EfiSystemTable->BootServices->CloseProtocol(Handles[Index], &IoGuid, EfiImageHandle, NULL);
|
||||
Debug::Print(L"WARNING: Unable to open DevicePath protocol (Status Code: 0x%zX)\n", Status);
|
||||
XtLoader::GetEfiSystemTable()->BootServices->CloseProtocol(Handles[Index], &IoGuid,
|
||||
XtLoader::GetEfiImageHandle(), NULLPTR);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Allocate memory for block device */
|
||||
Status = BlAllocateMemoryPool(sizeof(*BlockDevice), (PVOID *)&BlockDevice);
|
||||
Status = Memory::AllocatePool(sizeof(*BlockDevice), (PVOID *)&BlockDevice);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Memory allocation failure */
|
||||
BlDebugPrint(L"ERROR: Failed to allocate memory pool for block device (Status Code: 0x%zX)\n", Status);
|
||||
EfiSystemTable->BootServices->CloseProtocol(Handles[Index], &DevicePathGuid, EfiImageHandle, NULL);
|
||||
EfiSystemTable->BootServices->CloseProtocol(Handles[Index], &IoGuid, EfiImageHandle, NULL);
|
||||
Debug::Print(L"ERROR: Failed to allocate memory pool for block device (Status Code: 0x%zX)\n", Status);
|
||||
XtLoader::GetEfiSystemTable()->BootServices->CloseProtocol(Handles[Index], &DevicePathGuid,
|
||||
XtLoader::GetEfiImageHandle(), NULLPTR);
|
||||
XtLoader::GetEfiSystemTable()->BootServices->CloseProtocol(Handles[Index], &IoGuid,
|
||||
XtLoader::GetEfiImageHandle(), NULLPTR);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Store new block device into a linked list */
|
||||
BlockDevice->BlockIo = Io;
|
||||
BlockDevice->DevicePath = DevicePath;
|
||||
RtlInsertTailList(BlockDevices, &BlockDevice->ListEntry);
|
||||
RTL::LinkedList::InsertTailList(BlockDevices, &BlockDevice->ListEntry);
|
||||
}
|
||||
|
||||
/* Free handles buffer */
|
||||
BlFreeMemoryPool(Handles);
|
||||
Memory::FreePool(Handles);
|
||||
|
||||
/* Return success */
|
||||
return STATUS_EFI_SUCCESS;
|
||||
@@ -754,12 +826,12 @@ BlpDiscoverEfiBlockDevices(OUT PLIST_ENTRY BlockDevices)
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlpDissectVolumeArcPath(IN PWCHAR SystemPath,
|
||||
OUT PWCHAR *ArcName,
|
||||
OUT PWCHAR *Path,
|
||||
OUT PUSHORT DriveType,
|
||||
OUT PULONG DriveNumber,
|
||||
OUT PULONG PartNumber)
|
||||
Volume::DissectArcPath(IN PWCHAR SystemPath,
|
||||
OUT PWCHAR *ArcName,
|
||||
OUT PWCHAR *Path,
|
||||
OUT PUSHORT DriveType,
|
||||
OUT PULONG DriveNumber,
|
||||
OUT PULONG PartNumber)
|
||||
{
|
||||
PWCHAR ArcPath, LocalArcName;
|
||||
ULONG ArcLength = 0;
|
||||
@@ -770,20 +842,26 @@ BlpDissectVolumeArcPath(IN PWCHAR SystemPath,
|
||||
*PartNumber = 0;
|
||||
|
||||
/* Look for the ARC path */
|
||||
if(RtlCompareWideStringInsensitive(SystemPath, L"ramdisk(0)", 0) == 0)
|
||||
if(RTL::WideString::CompareWideStringInsensitive(SystemPath, L"ramdisk(0)", 10) == 0)
|
||||
{
|
||||
/* This is RAM disk */
|
||||
ArcLength = 10;
|
||||
*DriveType = XTBL_BOOT_DEVICE_RAMDISK;
|
||||
}
|
||||
else if(RtlCompareWideStringInsensitive(SystemPath, L"multi(0)disk(0)", 0) == 0)
|
||||
else if(RTL::WideString::CompareWideStringInsensitive(SystemPath, L"multi(0)esp(0)", 14) == 0)
|
||||
{
|
||||
/* This is ESP */
|
||||
ArcLength = 14;
|
||||
*DriveType = XTBL_BOOT_DEVICE_ESP;
|
||||
}
|
||||
else if(RTL::WideString::CompareWideStringInsensitive(SystemPath, L"multi(0)disk(0)", 15) == 0)
|
||||
{
|
||||
/* This is a multi-disk port */
|
||||
ArcLength = 15;
|
||||
ArcPath = SystemPath + ArcLength;
|
||||
|
||||
/* Check for disk type */
|
||||
if(RtlCompareWideStringInsensitive(ArcPath, L"cdrom(", 0) == 0)
|
||||
if(RTL::WideString::CompareWideStringInsensitive(ArcPath, L"cdrom(", 6) == 0)
|
||||
{
|
||||
/* This is an optical drive */
|
||||
ArcLength += 6;
|
||||
@@ -804,7 +882,7 @@ BlpDissectVolumeArcPath(IN PWCHAR SystemPath,
|
||||
*DriveType = XTBL_BOOT_DEVICE_CDROM;
|
||||
ArcLength++;
|
||||
}
|
||||
else if(RtlCompareWideStringInsensitive(ArcPath, L"fdisk(", 0) == 0)
|
||||
else if(RTL::WideString::CompareWideStringInsensitive(ArcPath, L"fdisk(", 6) == 0)
|
||||
{
|
||||
/* This is a floppy drive */
|
||||
ArcLength += 6;
|
||||
@@ -825,7 +903,7 @@ BlpDissectVolumeArcPath(IN PWCHAR SystemPath,
|
||||
*DriveType = XTBL_BOOT_DEVICE_FLOPPY;
|
||||
ArcLength++;
|
||||
}
|
||||
else if(RtlCompareWideStringInsensitive(ArcPath, L"rdisk(", 0) == 0)
|
||||
else if(RTL::WideString::CompareWideStringInsensitive(ArcPath, L"rdisk(", 6) == 0)
|
||||
{
|
||||
/* This is a hard disk */
|
||||
ArcLength += 6;
|
||||
@@ -848,7 +926,7 @@ BlpDissectVolumeArcPath(IN PWCHAR SystemPath,
|
||||
ArcPath = SystemPath + ArcLength;
|
||||
|
||||
/* Look for a partition */
|
||||
if(RtlCompareWideStringInsensitive(ArcPath, L"partition(", 0) == 0)
|
||||
if(RTL::WideString::CompareWideStringInsensitive(ArcPath, L"partition(", 10) == 0)
|
||||
{
|
||||
/* Partition information found */
|
||||
ArcLength += 10;
|
||||
@@ -888,8 +966,8 @@ BlpDissectVolumeArcPath(IN PWCHAR SystemPath,
|
||||
/* Store ARC name if possible */
|
||||
if(ArcName)
|
||||
{
|
||||
BlAllocateMemoryPool(ArcLength * sizeof(WCHAR), (PVOID *)&LocalArcName);
|
||||
RtlCopyMemory(LocalArcName, SystemPath, ArcLength * sizeof(WCHAR));
|
||||
Memory::AllocatePool(ArcLength * sizeof(WCHAR), (PVOID *)&LocalArcName);
|
||||
RTL::Memory::CopyMemory(LocalArcName, SystemPath, ArcLength * sizeof(WCHAR));
|
||||
LocalArcName[ArcLength] = '\0';
|
||||
*ArcName = LocalArcName;
|
||||
}
|
||||
@@ -910,44 +988,52 @@ BlpDissectVolumeArcPath(IN PWCHAR SystemPath,
|
||||
*/
|
||||
XTCDECL
|
||||
PEFI_DEVICE_PATH_PROTOCOL
|
||||
BlpDuplicateDevicePath(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath)
|
||||
Volume::DuplicateDevicePath(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath)
|
||||
{
|
||||
PEFI_DEVICE_PATH_PROTOCOL DevicePathNode;
|
||||
PEFI_DEVICE_PATH_PROTOCOL DevicePathClone;
|
||||
EFI_STATUS Status;
|
||||
UINT Length = 0;
|
||||
|
||||
/* Check if the input device path is NULL pointer */
|
||||
if(!DevicePath)
|
||||
{
|
||||
/* Nothing to duplicate */
|
||||
return NULLPTR;
|
||||
}
|
||||
|
||||
/* Start iterating from the beginning of the device path */
|
||||
DevicePathNode = DevicePath;
|
||||
|
||||
/* Get the device path length */
|
||||
while(TRUE)
|
||||
{
|
||||
Length += *(PUSHORT)DevicePath->Length;
|
||||
Length += *(PUSHORT)DevicePathNode->Length;
|
||||
if(DevicePathNode->Type == EFI_END_DEVICE_PATH)
|
||||
{
|
||||
break;
|
||||
}
|
||||
DevicePathNode = (PEFI_DEVICE_PATH_PROTOCOL)((PUCHAR)DevicePathNode + *(PUSHORT)DevicePath->Length);
|
||||
DevicePathNode = (PEFI_DEVICE_PATH_PROTOCOL)((PUCHAR)DevicePathNode + *(PUSHORT)DevicePathNode->Length);
|
||||
}
|
||||
|
||||
/* Check length */
|
||||
if(Length == 0)
|
||||
{
|
||||
/* Nothing to duplicate */
|
||||
return NULL;
|
||||
return NULLPTR;
|
||||
}
|
||||
|
||||
/* Allocate memory for the new device path */
|
||||
Status = BlAllocateMemoryPool(Length, (PVOID *)&DevicePathClone);
|
||||
Status = Memory::AllocatePool(Length, (PVOID *)&DevicePathClone);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Failed to allocate memory */
|
||||
BlDebugPrint(L"ERROR: Failed to allocate memory pool for device path duplicate (Status Code: 0x%zX)\n", Status);
|
||||
return NULL;
|
||||
Debug::Print(L"ERROR: Failed to allocate memory pool for device path duplicate (Status Code: 0x%zX)\n", Status);
|
||||
return NULLPTR;
|
||||
}
|
||||
|
||||
/* Copy the device path */
|
||||
RtlCopyMemory(DevicePathClone, DevicePath, Length);
|
||||
RTL::Memory::CopyMemory(DevicePathClone, DevicePath, Length);
|
||||
|
||||
/* Return the cloned object */
|
||||
return DevicePathClone;
|
||||
@@ -968,8 +1054,8 @@ BlpDuplicateDevicePath(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath)
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlpFindLastBlockDeviceNode(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath,
|
||||
OUT PEFI_DEVICE_PATH_PROTOCOL *LastNode)
|
||||
Volume::FindLastBlockDeviceNode(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath,
|
||||
OUT PEFI_DEVICE_PATH_PROTOCOL *LastNode)
|
||||
{
|
||||
PEFI_DEVICE_PATH_PROTOCOL EndNode, NextNode;
|
||||
|
||||
@@ -977,7 +1063,7 @@ BlpFindLastBlockDeviceNode(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath,
|
||||
if(DevicePath->Type == EFI_END_DEVICE_PATH)
|
||||
{
|
||||
/* End reached, nothing to do */
|
||||
LastNode = NULL;
|
||||
LastNode = NULLPTR;
|
||||
return STATUS_EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
@@ -1014,9 +1100,9 @@ BlpFindLastBlockDeviceNode(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath,
|
||||
*/
|
||||
XTCDECL
|
||||
BOOLEAN
|
||||
BlpFindParentBlockDevice(IN PLIST_ENTRY BlockDevices,
|
||||
IN PEFI_BLOCK_DEVICE_DATA ChildNode,
|
||||
OUT PEFI_BLOCK_DEVICE_DATA ParentNode)
|
||||
Volume::FindParentBlockDevice(IN PLIST_ENTRY BlockDevices,
|
||||
IN PEFI_BLOCK_DEVICE_DATA ChildNode,
|
||||
OUT PEFI_BLOCK_DEVICE_DATA *ParentNode)
|
||||
{
|
||||
PEFI_DEVICE_PATH_PROTOCOL ChildDevicePath, ParentDevicePath;
|
||||
PEFI_BLOCK_DEVICE_DATA BlockDeviceData;
|
||||
@@ -1029,6 +1115,14 @@ BlpFindParentBlockDevice(IN PLIST_ENTRY BlockDevices,
|
||||
/* Take block device from the list */
|
||||
BlockDeviceData = CONTAIN_RECORD(ListEntry, EFI_BLOCK_DEVICE_DATA, ListEntry);
|
||||
|
||||
/* A device cannot be its own parent */
|
||||
if (BlockDeviceData == ChildNode)
|
||||
{
|
||||
/* Move to the next device */
|
||||
ListEntry = ListEntry->Flink;
|
||||
continue;
|
||||
}
|
||||
|
||||
ChildDevicePath = ChildNode->DevicePath;
|
||||
ParentDevicePath = BlockDeviceData->DevicePath;
|
||||
|
||||
@@ -1039,7 +1133,7 @@ BlpFindParentBlockDevice(IN PLIST_ENTRY BlockDevices,
|
||||
if(ParentDevicePath->Type == EFI_END_DEVICE_PATH)
|
||||
{
|
||||
/* Parent device is a match */
|
||||
ParentNode = BlockDeviceData;
|
||||
*ParentNode = BlockDeviceData;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -1047,10 +1141,11 @@ BlpFindParentBlockDevice(IN PLIST_ENTRY BlockDevices,
|
||||
ChildLength = *(PUSHORT)ChildDevicePath->Length;
|
||||
ParentLength = *(PUSHORT)ParentDevicePath->Length;
|
||||
|
||||
/* Check if lengths match */
|
||||
if(ChildLength != ParentLength)
|
||||
/* Check if nodes match */
|
||||
if((ChildLength != ParentLength) ||
|
||||
(RTL::Memory::CompareMemory(ChildDevicePath, ParentDevicePath, ParentLength) != ParentLength))
|
||||
{
|
||||
/* Lengths do not match, this is not a valid parent */
|
||||
/* Nodes do not match, this is not a valid parent */
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,340 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: xtldr/xtldr.cc
|
||||
* DESCRIPTION: XTOS UEFI Boot Loader
|
||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||
*/
|
||||
|
||||
#include <xtldr.hh>
|
||||
|
||||
|
||||
/**
|
||||
* Disables access to EFI Boot Services.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
XtLoader::DisableBootServices()
|
||||
{
|
||||
LoaderStatus.BootServices = FALSE;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Queries the availability of EFI Boot Services.
|
||||
*
|
||||
* @return This routine returns TRUE if EFI Boot Services are available, FALSE otherwise.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
BOOLEAN
|
||||
XtLoader::GetBootServicesStatus()
|
||||
{
|
||||
return LoaderStatus.BootServices;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the EFI image handle.
|
||||
*
|
||||
* @return This routine returns a handle to the EFI-loaded image.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_HANDLE
|
||||
XtLoader::GetEfiImageHandle()
|
||||
{
|
||||
return XtLoader::EfiImageHandle;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the EFI system table pointer.
|
||||
*
|
||||
* @return This routine returns a pointer to the EFI system table.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
PEFI_SYSTEM_TABLE
|
||||
XtLoader::GetEfiSystemTable()
|
||||
{
|
||||
return XtLoader::EfiSystemTable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides base address and size of the XTLDR image.
|
||||
*
|
||||
* @param LoaderBase
|
||||
* Supplies a pointer to a variable that receives the base address of the XTLDR image.
|
||||
*
|
||||
* @param LoaderSize
|
||||
* Supplies a pointer to a variable that receives the size of the XTLDR image.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
XtLoader::GetLoaderImageInformation(PVOID *LoaderBase,
|
||||
PULONGLONG LoaderSize)
|
||||
{
|
||||
*LoaderBase = XtLoader::LoaderStatus.LoaderBase;
|
||||
*LoaderSize = XtLoader::LoaderStatus.LoaderSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the Secure Boot status.
|
||||
*
|
||||
* @return This routine returns SecureBoot status.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
INT_PTR
|
||||
XtLoader::GetSecureBootStatus()
|
||||
{
|
||||
return LoaderStatus.SecureBoot;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes EFI Boot Loader (XTLDR).
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
XtLoader::InitializeBootLoader(IN EFI_HANDLE ImageHandle,
|
||||
IN PEFI_SYSTEM_TABLE SystemTable)
|
||||
{
|
||||
EFI_GUID LipGuid = EFI_LOADED_IMAGE_PROTOCOL_GUID;
|
||||
PEFI_LOADED_IMAGE_PROTOCOL LoadedImage;
|
||||
EFI_HANDLE Handle;
|
||||
EFI_STATUS Status;
|
||||
|
||||
/* Set the system table and image handle */
|
||||
EfiImageHandle = ImageHandle;
|
||||
EfiSystemTable = SystemTable;
|
||||
|
||||
/* Set current XTLDR's EFI BootServices status */
|
||||
LoaderStatus.BootServices = TRUE;
|
||||
|
||||
/* Initialize console */
|
||||
Console::InitializeConsole();
|
||||
|
||||
/* Print XTLDR version */
|
||||
Console::Print(L"XTLDR boot loader v%s\n", XTOS_VERSION);
|
||||
|
||||
/* Initialize XTLDR protocol */
|
||||
Protocol::InitializeProtocol();
|
||||
|
||||
/* Initialize XTLDR configuration */
|
||||
Configuration::InitializeConfiguration();
|
||||
|
||||
/* Initialize shell */
|
||||
Shell::InitializeShell();
|
||||
|
||||
/* Store SecureBoot status */
|
||||
LoaderStatus.SecureBoot = EfiUtils::GetSecureBootStatus();
|
||||
|
||||
/* Attempt to open EFI LoadedImage protocol */
|
||||
Status = Protocol::OpenProtocol(&Handle, (PVOID *)&LoadedImage, &LipGuid);
|
||||
if(Status == STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Store boot loader image base and size */
|
||||
LoaderStatus.LoaderBase = LoadedImage->ImageBase;
|
||||
LoaderStatus.LoaderSize = LoadedImage->ImageSize;
|
||||
|
||||
/* Check if debug is enabled */
|
||||
if(DEBUG)
|
||||
{
|
||||
/* Protocol opened successfully, print useful debug information */
|
||||
Console::Print(L"\n---------- BOOTLOADER DEBUG ----------\n"
|
||||
L"Pointer Size : %d\n"
|
||||
L"Image Base Address : %P\n"
|
||||
L"Image Base Size : 0x%lX\n"
|
||||
L"Image Revision : 0x%lX\n"
|
||||
L"Secure Boot Status : %zd\n"
|
||||
L"--------------------------------------\n",
|
||||
sizeof(PVOID),
|
||||
LoadedImage->ImageBase,
|
||||
LoadedImage->ImageSize,
|
||||
LoadedImage->Revision,
|
||||
LoaderStatus.SecureBoot);
|
||||
EfiUtils::SleepExecution(3000);
|
||||
}
|
||||
|
||||
/* Close EFI LoadedImage protocol */
|
||||
Protocol::CloseProtocol(&Handle, &LipGuid);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a boot menu callback routine, that will be used to display alternative boot menu.
|
||||
*
|
||||
* @param BootMenuRoutine
|
||||
* Supplies a pointer to the boot menu callback routine.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
XtLoader::RegisterBootMenu(IN PVOID BootMenuRoutine)
|
||||
{
|
||||
/* Set boot menu routine */
|
||||
BootMenu = (PBL_XT_BOOT_MENU)BootMenuRoutine;
|
||||
}
|
||||
|
||||
/**
|
||||
* Invokes either a custom boot menu handler, if one has been registered, or displays the default boot menu.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
XtLoader::ShowBootMenu()
|
||||
{
|
||||
/* Check if custom boot menu registered */
|
||||
if(BootMenu != NULLPTR)
|
||||
{
|
||||
/* Display alternative boot menu */
|
||||
BootMenu();
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Display default boot menu */
|
||||
TextUi::DisplayBootMenu();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This routine is the entry point of the XT EFI boot loader.
|
||||
*
|
||||
* @param ImageHandle
|
||||
* Firmware-allocated handle that identifies the image.
|
||||
*
|
||||
* @param SystemTable
|
||||
* Provides the EFI system table.
|
||||
*
|
||||
* @return This routine returns status code.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlStartXtLoader(IN EFI_HANDLE ImageHandle,
|
||||
IN PEFI_SYSTEM_TABLE SystemTable)
|
||||
{
|
||||
PWCHAR Modules;
|
||||
EFI_STATUS Status;
|
||||
|
||||
/* Check if system is EFI-based and provided parameters are valid */
|
||||
if(ImageHandle == NULLPTR || SystemTable == NULLPTR)
|
||||
{
|
||||
/* Invalid parameters, print error message using BIOS calls and hang */
|
||||
BiosUtils::ClearScreen();
|
||||
BiosUtils::Print(L"XTLDR requires EFI-based system!");
|
||||
for(;;);
|
||||
}
|
||||
|
||||
/* Initialize XTLDR */
|
||||
XtLoader::InitializeBootLoader(ImageHandle, SystemTable);
|
||||
|
||||
/* Parse configuration options passed from UEFI shell */
|
||||
Status = Configuration::ParseCommandLine();
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Failed to parse command line options */
|
||||
TextUi::DisplayErrorDialog(L"XTLDR", L"Failed to parse command line parameters.");
|
||||
}
|
||||
|
||||
/* Attempt to early initialize debug console */
|
||||
if(DEBUG)
|
||||
{
|
||||
Status = Debug::InitializeDebugConsole();
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Initialization failed, notify user on stdout */
|
||||
TextUi::DisplayErrorDialog(L"XTLDR", L"Failed to initialize debug console.");
|
||||
}
|
||||
}
|
||||
|
||||
/* Load XTLDR configuration file */
|
||||
Status = Configuration::LoadConfiguration();
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Failed to load/parse config file */
|
||||
TextUi::DisplayErrorDialog(L"XTLDR", L"Failed to load and parse configuration file ");
|
||||
}
|
||||
|
||||
/* Reinitialize debug console if it was not initialized earlier */
|
||||
if(DEBUG)
|
||||
{
|
||||
Status = Debug::InitializeDebugConsole();
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Initialization failed, notify user on stdout */
|
||||
TextUi::DisplayErrorDialog(L"XTLDR", L"Failed to initialize debug console.");
|
||||
}
|
||||
}
|
||||
|
||||
/* Disable watchdog timer */
|
||||
Status = XtLoader::GetEfiSystemTable()->BootServices->SetWatchdogTimer(0, 0x10000, 0, NULLPTR);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Failed to disable the timer, print message */
|
||||
Debug::Print(L"WARNING: Failed to disable watchdog timer (Status Code: 0x%zX)\n", Status);
|
||||
}
|
||||
|
||||
/* Install loader protocol */
|
||||
Status = Protocol::InstallXtLoaderProtocol();
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Failed to register loader protocol */
|
||||
Debug::Print(L"ERROR: Failed to register XTLDR loader protocol (Status Code: 0x%zX)\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Load all necessary modules */
|
||||
Configuration::GetValue(L"MODULES", &Modules);
|
||||
Status = Protocol::LoadModules(Modules);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Failed to load modules */
|
||||
Debug::Print(L"ERROR: Failed to load XTLDR modules (Status Code: 0x%zX)\n", Status);
|
||||
TextUi::DisplayErrorDialog(L"XTLDR", L"Failed to load some XTLDR modules.");
|
||||
}
|
||||
|
||||
/* Discover and enumerate EFI block devices */
|
||||
Status = Volume::EnumerateBlockDevices();
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Failed to enumerate block devices */
|
||||
Debug::Print(L"ERROR: Failed to discover and enumerate block devices (Status Code: 0x%zX)\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Main boot loader loop */
|
||||
while(TRUE)
|
||||
{
|
||||
/* Show boot menu */
|
||||
XtLoader::ShowBootMenu();
|
||||
|
||||
/* Fallback to shell, if boot menu returned */
|
||||
Shell::StartLoaderShell();
|
||||
}
|
||||
|
||||
/* This point should be never reached, if this happen return error code */
|
||||
return STATUS_EFI_LOAD_ERROR;
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
# PROJECT: ExectOS
|
||||
# LICENSE: See the COPYING.md in the top level directory
|
||||
# FILE: configure.ps1
|
||||
# DESCRIPTION: Project configuration script for preparing the build environment
|
||||
# DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
|
||||
|
||||
# Check XTchain
|
||||
if (-not $env:XTCVER) {
|
||||
Write-Error "XTChain not detected or corrupted!"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Set target architecture defaulting to amd64
|
||||
$ARCH = if ($env:TARGET) { $env:TARGET } else { "amd64" }
|
||||
|
||||
# Set target build type defaulting to Debug
|
||||
$env:BUILD_TYPE = if ($env:BUILD_TYPE -in @("Debug", "Release")) { $env:BUILD_TYPE } else { "Debug" }
|
||||
|
||||
# Set variables
|
||||
$EXECTOS_SOURCE_DIR = $PSScriptRoot
|
||||
$EXECTOS_BINARY_DIR = Join-Path $EXECTOS_SOURCE_DIR "build-$ARCH-$($env:BUILD_TYPE.ToLower())"
|
||||
|
||||
# Create build directory
|
||||
if (-not (Test-Path $EXECTOS_BINARY_DIR)) {
|
||||
Write-Host "Creating build directory: $EXECTOS_BINARY_DIR"
|
||||
New-Item -ItemType Directory -Path $EXECTOS_BINARY_DIR -Force | Out-Null
|
||||
}
|
||||
|
||||
Set-Location $EXECTOS_BINARY_DIR
|
||||
|
||||
# Delete old cache
|
||||
Remove-Item "CMakeCache.txt", "host-tools/CMakeCache.txt" -ErrorAction SilentlyContinue
|
||||
|
||||
# Configure project using CMake
|
||||
& cmake -G Ninja "-DARCH:STRING=$ARCH" "-DBUILD_TYPE:STRING=$($env:BUILD_TYPE)" $EXECTOS_SOURCE_DIR
|
||||
|
||||
# Check if configuration succeeded
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
Write-Error "Configure script failed."
|
||||
exit 1
|
||||
}
|
||||
|
||||
$ARCH | Out-File -Encoding ASCII -NoNewline "build.arch"
|
||||
Write-Host "Configure completed. Run 'xbuild' to build ExectOS."
|
||||
+7
-2
@@ -1,4 +1,10 @@
|
||||
#!/bin/bash
|
||||
# PROJECT: ExectOS
|
||||
# LICENSE: See the COPYING.md in the top level directory
|
||||
# FILE: configure.sh
|
||||
# DESCRIPTION: Project configuration script for preparing the build environment
|
||||
# DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||
|
||||
|
||||
# Check XTCHain
|
||||
if [ "x${XTCVER}" = "x" ]; then
|
||||
@@ -16,13 +22,12 @@ fi
|
||||
|
||||
# Set variables
|
||||
EXECTOS_SOURCE_DIR=$(cd `dirname ${0}` && pwd)
|
||||
EXECTOS_BINARY_DIR=build-${ARCH}-xtchain
|
||||
EXECTOS_BINARY_DIR=build-${ARCH}-${BUILD_TYPE,,}
|
||||
|
||||
# Create directories if needed
|
||||
if [ "${EXECTOS_SOURCE_DIR}" = "${PWD}" ]; then
|
||||
echo Creating directories in ${EXECTOS_BINARY_DIR}
|
||||
mkdir -p "${EXECTOS_BINARY_DIR}"
|
||||
ln -sf ${EXECTOS_BINARY_DIR} build
|
||||
cd "${EXECTOS_BINARY_DIR}"
|
||||
fi
|
||||
|
||||
|
||||
@@ -7,8 +7,8 @@ include_directories(
|
||||
|
||||
# Specify list of source code files
|
||||
list(APPEND NTOSDRV_SOURCE
|
||||
${NTOSDRV_SOURCE_DIR}/ntosdrv.c
|
||||
${NTOSDRV_SOURCE_DIR}/rtl.c)
|
||||
${NTOSDRV_SOURCE_DIR}/ntosdrv.cc
|
||||
${NTOSDRV_SOURCE_DIR}/rtl.cc)
|
||||
|
||||
# Set module definition SPEC file
|
||||
set_specfile(ntosdrv.spec ntosdrv.sys)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: drivers/ntosdrv/ntosdrv.c
|
||||
* FILE: drivers/ntosdrv/ntosdrv.cc
|
||||
* DESCRIPTION: NTOS compatibility driver
|
||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||
*/
|
||||
@@ -16,6 +16,7 @@
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCLINK
|
||||
XTAPI
|
||||
XTSTATUS
|
||||
XtDriverEntry(VOID)
|
||||
@@ -1,7 +1,7 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: drivers/ntosdrv/rtl.c
|
||||
* FILE: drivers/ntosdrv/rtl.cc
|
||||
* DESCRIPTION: NTOS compatibility driver runtime library
|
||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||
*/
|
||||
@@ -25,6 +25,7 @@
|
||||
*
|
||||
* @since NT 3.5
|
||||
*/
|
||||
XTCLINK
|
||||
XTAPI
|
||||
VOID
|
||||
RtlFillMemory(OUT PVOID Destination,
|
||||
@@ -0,0 +1,3 @@
|
||||
add_subdirectory("xtadk")
|
||||
|
||||
set_sdk_target("xtdk/" "include")
|
||||
@@ -0,0 +1,3 @@
|
||||
# Set base addresses for all modules
|
||||
set(BASEADDRESS_XTLDR 0x000000000000F800)
|
||||
set(BASEADDRESS_XTOSKRNL 0x0000000140000000)
|
||||
@@ -1,3 +1,3 @@
|
||||
# Set base addresses for all modules
|
||||
set(BASEADDRESS_XTLDR 0x00010000)
|
||||
set(BASEADDRESS_XTLDR 0x0000F800)
|
||||
set(BASEADDRESS_XTOSKRNL 0x00400000)
|
||||
@@ -8,41 +8,79 @@ endif()
|
||||
# This target creates a disk image
|
||||
add_custom_target(diskimg
|
||||
DEPENDS install
|
||||
COMMAND sh -c "dd if=/dev/zero of=${EXECTOS_BINARY_DIR}/output/disk.img bs=512 count=${PROJECT_DISK_IMAGE_BLOCKS} 2>/dev/null 1>/dev/null"
|
||||
COMMAND parted ${EXECTOS_BINARY_DIR}/output/disk.img -s -a minimal mklabel gpt
|
||||
COMMAND parted ${EXECTOS_BINARY_DIR}/output/disk.img -s -a minimal mkpart EFI FAT32 2048s ${PROJECT_PART_IMAGE_BLOCKS}s
|
||||
COMMAND parted ${EXECTOS_BINARY_DIR}/output/disk.img -s -a minimal toggle 1 boot
|
||||
COMMAND sh -c "dd if=/dev/zero of=${EXECTOS_BINARY_DIR}/output/part.img bs=512 count=${PROJECT_PART_IMAGE_BLOCKS} 2>/dev/null 1>/dev/null"
|
||||
COMMAND mformat -i ${EXECTOS_BINARY_DIR}/output/part.img -h32 -t32 -n64 -L32
|
||||
COMMAND sh -c "mcopy -s -i ${EXECTOS_BINARY_DIR}/output/part.img ${EXECTOS_BINARY_DIR}/output/binaries/* ::"
|
||||
COMMAND sh -c "dd if=${EXECTOS_BINARY_DIR}/output/part.img of=${EXECTOS_BINARY_DIR}/output/disk.img bs=512 count=${PROJECT_PART_IMAGE_BLOCKS} seek=2048 conv=notrunc 2>/dev/null 1>/dev/null"
|
||||
COMMAND rm ${EXECTOS_BINARY_DIR}/output/part.img
|
||||
COMMAND diskimg -c ${EXECTOS_BINARY_DIR}/output/binaries -f 32 -o ${EXECTOS_BINARY_DIR}/output/disk.img -s ${PROJECT_DISK_IMAGE_SIZE}
|
||||
-m ${EXECTOS_BINARY_DIR}/boot/bootsect/mbrboot.bin -v ${EXECTOS_BINARY_DIR}/boot/bootsect/espboot.bin
|
||||
VERBATIM)
|
||||
|
||||
# This target starts up a BOCHS+OVMF virtual machine
|
||||
add_custom_target(bochsvm
|
||||
DEPENDS diskimg
|
||||
COMMAND bochs -f ../sdk/firmware/bochsrc_${ARCH}.cfg -q -unlock
|
||||
VERBATIM USES_TERMINAL)
|
||||
find_program(BOCHS_EMULATOR bochs)
|
||||
if(BOCHS_EMULATOR)
|
||||
# This target starts up a BOCHS+BIOS virtual machine
|
||||
add_custom_target(bochsvm
|
||||
DEPENDS diskimg
|
||||
COMMAND bochs -f ../sdk/firmware/bochsrc_${ARCH}.cfg -q -unlock
|
||||
VERBATIM USES_TERMINAL)
|
||||
endif()
|
||||
|
||||
# This target starts up a QEMU+OVMF virtual machine using KVM accelerator
|
||||
add_custom_target(testkvm
|
||||
DEPENDS diskimg
|
||||
COMMAND ${QEMU_COMMAND} -name "ExectOS-${ARCH}-KVM" -machine type=q35,kernel_irqchip=on,accel=kvm,mem-merge=off,vmport=off -enable-kvm -cpu host,-hypervisor,+topoext
|
||||
-smp 2,sockets=1,cores=1,threads=2 -m 4G -overcommit mem-lock=off -rtc clock=host,base=localtime,driftfix=none
|
||||
-drive file=${EXECTOS_SOURCE_DIR}/sdk/firmware/ovmf_code_${ARCH}.fd,if=pflash,format=raw,unit=0,readonly=on
|
||||
-drive file=${EXECTOS_SOURCE_DIR}/sdk/firmware/ovmf_vars_${ARCH}.fd,if=pflash,format=raw,unit=1
|
||||
-hda ${EXECTOS_BINARY_DIR}/output/disk.img
|
||||
-boot menu=on -d int -M smm=off -no-reboot -no-shutdown -serial stdio
|
||||
VERBATIM USES_TERMINAL)
|
||||
find_program(QEMU_EMULATOR ${QEMU_COMMAND})
|
||||
if(QEMU_EMULATOR)
|
||||
if(CMAKE_HOST_LINUX)
|
||||
# This target starts up a QEMU+OVMF virtual machine using KVM accelerator
|
||||
add_custom_target(testefikvm
|
||||
DEPENDS install
|
||||
COMMAND ${QEMU_COMMAND} -name "ExectOS-${ARCH}-EFI-KVM" -machine type=q35,kernel_irqchip=on,accel=kvm,mem-merge=off,vmport=off -enable-kvm -cpu host,-hypervisor,+topoext
|
||||
-smp 2,sockets=1,cores=1,threads=2 -m 4G -overcommit mem-lock=off -rtc clock=host,base=localtime,driftfix=none
|
||||
-bios ${EXECTOS_SOURCE_DIR}/sdk/firmware/ovmf_${ARCH}.fd
|
||||
-hda fat:rw:${EXECTOS_BINARY_DIR}/output/binaries
|
||||
-boot menu=on -d int -M smm=off -no-reboot -no-shutdown -serial stdio
|
||||
VERBATIM USES_TERMINAL)
|
||||
elseif(CMAKE_HOST_WIN32)
|
||||
# This target starts up a QEMU+OVMF virtual machine using WHPX accelerator
|
||||
add_custom_target(testefiwhpx
|
||||
DEPENDS install
|
||||
COMMAND ${QEMU_COMMAND} -name "ExectOS-${ARCH}-EFI-WHPX" -machine type=q35,kernel_irqchip=off,accel=whpx,mem-merge=off,vmport=off
|
||||
-m 4G -overcommit mem-lock=off -rtc clock=host,base=localtime,driftfix=none
|
||||
-bios ${EXECTOS_SOURCE_DIR}/sdk/firmware/ovmf_${ARCH}.fd
|
||||
-hda fat:rw:${EXECTOS_BINARY_DIR}/output/binaries
|
||||
-boot menu=on -d int -M smm=off -no-reboot -no-shutdown -serial stdio
|
||||
VERBATIM USES_TERMINAL)
|
||||
endif()
|
||||
|
||||
# This target starts up a QEMU+OVMF virtual machine using TCG accelerator
|
||||
add_custom_target(testtcg
|
||||
DEPENDS diskimg
|
||||
COMMAND ${QEMU_COMMAND} -name "ExectOS-${ARCH}-TCG" -machine type=q35,accel=tcg -cpu max,-hypervisor
|
||||
-smp 2,sockets=1,cores=1,threads=2 -m 4G -overcommit mem-lock=off -rtc clock=host,base=localtime,driftfix=none
|
||||
-drive file=${EXECTOS_SOURCE_DIR}/sdk/firmware/ovmf_code_${ARCH}.fd,if=pflash,format=raw,unit=0,readonly=on
|
||||
-drive file=${EXECTOS_SOURCE_DIR}/sdk/firmware/ovmf_vars_${ARCH}.fd,if=pflash,format=raw,unit=1
|
||||
-hda ${EXECTOS_BINARY_DIR}/output/disk.img
|
||||
-boot menu=on -d int -M smm=off -no-reboot -no-shutdown -serial stdio
|
||||
VERBATIM USES_TERMINAL)
|
||||
# This target starts up a QEMU+OVMF virtual machine using TCG accelerator
|
||||
add_custom_target(testefitcg
|
||||
DEPENDS install
|
||||
COMMAND ${QEMU_COMMAND} -name "ExectOS-${ARCH}-EFI-TCG" -machine type=q35,accel=tcg -cpu max,-hypervisor
|
||||
-smp 2,sockets=1,cores=1,threads=2 -m 4G -overcommit mem-lock=off -rtc clock=host,base=localtime,driftfix=none
|
||||
-bios ${EXECTOS_SOURCE_DIR}/sdk/firmware/ovmf_${ARCH}.fd
|
||||
-hda fat:rw:${EXECTOS_BINARY_DIR}/output/binaries
|
||||
-boot menu=on -d int -no-reboot -no-shutdown -serial stdio
|
||||
VERBATIM USES_TERMINAL)
|
||||
|
||||
if(CMAKE_HOST_LINUX)
|
||||
# This target starts up a QEMU+SEABIOS virtual machine using KVM accelerator
|
||||
add_custom_target(testkvm
|
||||
DEPENDS diskimg
|
||||
COMMAND ${QEMU_COMMAND} -name "ExectOS-${ARCH}-BIOS-KVM" -machine type=q35,kernel_irqchip=on,accel=kvm,mem-merge=off,vmport=off -enable-kvm -cpu host,-hypervisor,+topoext
|
||||
-smp 2,sockets=1,cores=1,threads=2 -m 4G -overcommit mem-lock=off -rtc clock=host,base=localtime,driftfix=none
|
||||
-hda ${EXECTOS_BINARY_DIR}/output/disk.img
|
||||
-boot menu=on -d int -no-reboot -no-shutdown -serial stdio
|
||||
VERBATIM USES_TERMINAL)
|
||||
elseif(CMAKE_HOST_WIN32)
|
||||
# This target starts up a QEMU+SEABIOS virtual machine using WHPX accelerator
|
||||
add_custom_target(testwhpx
|
||||
DEPENDS diskimg
|
||||
COMMAND ${QEMU_COMMAND} -name "ExectOS-${ARCH}-BIOS-WHPX" -machine type=q35,kernel_irqchip=off,accel=whpx,mem-merge=off,vmport=off
|
||||
-m 4G -overcommit mem-lock=off -rtc clock=host,base=localtime,driftfix=none
|
||||
-hda ${EXECTOS_BINARY_DIR}/output/disk.img
|
||||
-boot menu=on -d int -no-reboot -no-shutdown -serial stdio
|
||||
VERBATIM USES_TERMINAL)
|
||||
endif()
|
||||
|
||||
# This target starts up a QEMU+SEABIOS virtual machine using TCG accelerator
|
||||
add_custom_target(testtcg
|
||||
DEPENDS diskimg
|
||||
COMMAND ${QEMU_COMMAND} -name "ExectOS-${ARCH}-BIOS-TCG" -machine type=q35,accel=tcg -cpu max,-hypervisor
|
||||
-smp 2,sockets=1,cores=1,threads=2 -m 4G -overcommit mem-lock=off -rtc clock=host,base=localtime,driftfix=none
|
||||
-hda ${EXECTOS_BINARY_DIR}/output/disk.img
|
||||
-boot menu=on -d int -no-reboot -no-shutdown -serial stdio
|
||||
VERBATIM USES_TERMINAL)
|
||||
endif()
|
||||
|
||||
@@ -59,18 +59,128 @@ function(add_module_linker_flags MODULE FLAGS)
|
||||
set_module_property(${MODULE} LINK_FLAGS ${FLAGS})
|
||||
endfunction()
|
||||
|
||||
# This function sets a property for specified module
|
||||
function(set_module_property MODULE PROPERTY FLAGS)
|
||||
if(NOT ${ARGC} EQUAL 3)
|
||||
message(FATAL_ERROR "Invalid number of arguments passwd to add_module_property() function")
|
||||
# This function compiles XT Assembly Development Kit
|
||||
function(generate_xtadk TARGET_NAME SOURCE_FILES)
|
||||
# Define the absolute destination path for the generated header file
|
||||
set(HEADER_OUTPUT "${EXECTOS_BINARY_DIR}/sdk/includes/${TARGET_NAME}.h")
|
||||
get_filename_component(HEADER_OUTPUT_DIRECTORY "${HEADER_OUTPUT}" DIRECTORY)
|
||||
|
||||
# Tokenize global CXX flags into a list to ensure correct argument expansion
|
||||
separate_arguments(COMPILER_FLAGS NATIVE_COMMAND "${CMAKE_CXX_FLAGS}")
|
||||
|
||||
# Resolve and tokenize build-configuration specific flags
|
||||
string(TOUPPER "${CMAKE_BUILD_TYPE}" BUILD_TYPE)
|
||||
if(BUILD_TYPE)
|
||||
separate_arguments(BUILD_TYPE_SPECIFIC_FLAGS NATIVE_COMMAND "${CMAKE_CXX_FLAGS_${BUILD_TYPE}}")
|
||||
endif()
|
||||
get_target_property(VAL ${MODULE} ${PROPERTY})
|
||||
if(VAL)
|
||||
set(VAL "${VAL} ${FLAGS}")
|
||||
else()
|
||||
set(VAL "${FLAGS}")
|
||||
endif()
|
||||
set_property(TARGET ${MODULE} PROPERTY ${PROPERTY} ${VAL})
|
||||
|
||||
# Retrieve compiler definitions, include paths, and options
|
||||
get_directory_property(COMPILE_DEFINITIONS COMPILE_DEFINITIONS)
|
||||
get_directory_property(INCLUDE_DIRECTORIES INCLUDE_DIRECTORIES)
|
||||
get_directory_property(COMPILE_OPTIONS COMPILE_OPTIONS)
|
||||
|
||||
# Initialize the final compiler argument list
|
||||
set(COMPILER_ARGUMENTS "")
|
||||
list(APPEND COMPILER_ARGUMENTS ${COMPILER_FLAGS} ${BUILD_TYPE_SPECIFIC_FLAGS})
|
||||
|
||||
# Transform definitions into MSVC-style
|
||||
foreach(DEFINITION ${COMPILE_DEFINITIONS})
|
||||
list(APPEND COMPILER_ARGUMENTS "/D${DEFINITION}")
|
||||
endforeach()
|
||||
|
||||
# Transform include paths into MSVC-style
|
||||
foreach(INCLUDE_PATH ${INCLUDE_DIRECTORIES})
|
||||
list(APPEND COMPILER_ARGUMENTS "/I${INCLUDE_PATH}")
|
||||
endforeach()
|
||||
|
||||
# Append all supplemental compiler options
|
||||
list(APPEND COMPILER_ARGUMENTS ${COMPILE_OPTIONS})
|
||||
set(COLLECTED_ASSEMBLY_OUTPUTS "")
|
||||
|
||||
# Iterate through each source file to create individual assembly generation rules
|
||||
foreach(SOURCE_FILE_PATH ${SOURCE_FILES})
|
||||
# Extract the base filename
|
||||
get_filename_component(FILENAME_WITHOUT_EXTENSION "${SOURCE_FILE_PATH}" NAME_WE)
|
||||
|
||||
# Define the unique output path for the intermediate assembly file
|
||||
set(CURRENT_ASSEMBLY_OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${FILENAME_WITHOUT_EXTENSION}.S")
|
||||
list(APPEND COLLECTED_ASSEMBLY_OUTPUTS "${CURRENT_ASSEMBLY_OUTPUT}")
|
||||
get_filename_component(CURRENT_ASSEMBLY_DIRECTORY "${CURRENT_ASSEMBLY_OUTPUT}" DIRECTORY)
|
||||
|
||||
# Execute the compiler to generate assembly code
|
||||
add_custom_command(
|
||||
OUTPUT "${CURRENT_ASSEMBLY_OUTPUT}"
|
||||
COMMAND ${CMAKE_COMMAND} -E make_directory "${CURRENT_ASSEMBLY_DIRECTORY}"
|
||||
COMMAND ${CMAKE_CXX_COMPILER}
|
||||
${COMPILER_ARGUMENTS}
|
||||
/c /FAs /Fa${CURRENT_ASSEMBLY_OUTPUT}
|
||||
-- ${SOURCE_FILE_PATH}
|
||||
DEPENDS "${SOURCE_FILE_PATH}"
|
||||
COMMENT "Generating XTADK Assembly: ${FILENAME_WITHOUT_EXTENSION}"
|
||||
VERBATIM
|
||||
COMMAND_EXPAND_LISTS
|
||||
)
|
||||
endforeach()
|
||||
|
||||
# Aggregate all generated assembly units into a single consolidated XTADK header
|
||||
add_custom_command(
|
||||
OUTPUT "${HEADER_OUTPUT}"
|
||||
COMMAND ${CMAKE_COMMAND} -E make_directory "${HEADER_OUTPUT_DIRECTORY}"
|
||||
COMMAND xtadkgen ${COLLECTED_ASSEMBLY_OUTPUTS} -O "${HEADER_OUTPUT}"
|
||||
DEPENDS ${COLLECTED_ASSEMBLY_OUTPUTS}
|
||||
COMMENT "Generating XTADK header: ${TARGET_NAME}"
|
||||
VERBATIM
|
||||
)
|
||||
|
||||
# Establish the generation target and expose the header directory via an interface library
|
||||
add_custom_target(${TARGET_NAME}_gen DEPENDS "${HEADER_OUTPUT}")
|
||||
add_library(${TARGET_NAME} INTERFACE)
|
||||
add_dependencies(${TARGET_NAME} ${TARGET_NAME}_gen)
|
||||
target_include_directories(${TARGET_NAME} INTERFACE "${EXECTOS_BINARY_DIR}/sdk/includes")
|
||||
endfunction()
|
||||
|
||||
# This function compiles an assembly bootsector file into a flat binary
|
||||
function(compile_bootsector NAME SOURCE BASEADDR ENTRYPOINT)
|
||||
set(BINARY_NAME "${NAME}.bin")
|
||||
set(OBJECT_NAME "${NAME}.obj")
|
||||
|
||||
get_directory_property(DEFS COMPILE_DEFINITIONS)
|
||||
foreach(def ${DEFS})
|
||||
list(APPEND ASM_DEFS "-D${def}")
|
||||
endforeach()
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${BINARY_NAME}
|
||||
COMMAND ${CMAKE_ASM_COMPILER}
|
||||
/nologo
|
||||
--target=i386-none-elf
|
||||
${ASM_DEFS}
|
||||
-I${CMAKE_CURRENT_SOURCE_DIR}
|
||||
/Fo${CMAKE_CURRENT_BINARY_DIR}/${OBJECT_NAME}
|
||||
-c -- ${SOURCE}
|
||||
COMMAND ${CMAKE_ASM_LINKER}
|
||||
-m elf_i386
|
||||
--image-base=0
|
||||
--oformat binary
|
||||
-Ttext=${BASEADDR}
|
||||
--entry=_start${ENTRYPOINT}
|
||||
-o ${CMAKE_CURRENT_BINARY_DIR}/${BINARY_NAME}
|
||||
${CMAKE_CURRENT_BINARY_DIR}/${OBJECT_NAME}
|
||||
DEPENDS ${SOURCE}
|
||||
)
|
||||
|
||||
add_custom_target(${NAME} ALL
|
||||
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${BINARY_NAME}
|
||||
)
|
||||
endfunction()
|
||||
|
||||
# This function sets the the qemu disk image size (in MiB)
|
||||
function(set_disk_image_size SIZE)
|
||||
MATH(EXPR DISK_BLOCKS ${SIZE}*1024*1024/512)
|
||||
MATH(EXPR PART_BLOCKS ${DISK_BLOCKS}-2048)
|
||||
set(PROJECT_DISK_IMAGE_SIZE ${SIZE} CACHE INTERNAL "PROJECT_DISK_IMAGE_SIZE")
|
||||
set(PROJECT_DISK_IMAGE_BLOCKS ${DISK_BLOCKS} CACHE INTERNAL "PROJECT_DISK_IMAGE_BLOCKS")
|
||||
set(PROJECT_PART_IMAGE_BLOCKS ${PART_BLOCKS} CACHE INTERNAL "PROJECT_PART_IMAGE_BLOCKS")
|
||||
endfunction()
|
||||
|
||||
# This function installs specified directory recursively under destination directory
|
||||
@@ -85,9 +195,28 @@ endfunction()
|
||||
|
||||
# This function installs specified target results under destination directory
|
||||
function(set_install_target TARGET DESTINATION)
|
||||
set_target_properties(${TARGET} PROPERTIES ARCHIVE_OUTPUT_DIRECTORY "${EXECTOS_BINARY_DIR}/output/sdk/lib")
|
||||
install(TARGETS ${TARGET} DESTINATION ${EXECTOS_BINARY_DIR}/output/binaries/${DESTINATION})
|
||||
endfunction()
|
||||
|
||||
# This function sets a property for specified module
|
||||
function(set_module_property MODULE PROPERTY FLAGS)
|
||||
if(NOT ${ARGC} EQUAL 3)
|
||||
message(FATAL_ERROR "Invalid number of arguments passwd to add_module_property() function")
|
||||
endif()
|
||||
get_target_property(VAL ${MODULE} ${PROPERTY})
|
||||
if(VAL)
|
||||
set(VAL "${VAL} ${FLAGS}")
|
||||
else()
|
||||
set(VAL "${FLAGS}")
|
||||
endif()
|
||||
set_property(TARGET ${MODULE} PROPERTY ${PROPERTY} ${VAL})
|
||||
endfunction()
|
||||
|
||||
function(set_sdk_target FILENAME DESTINATION)
|
||||
install(DIRECTORY ${FILENAME} DESTINATION ${EXECTOS_BINARY_DIR}/output/sdk/${DESTINATION})
|
||||
endfunction()
|
||||
|
||||
# This function is responsible for compiling module SPEC file
|
||||
function(set_specfile SPECFILE EXPORTNAME)
|
||||
if(NOT ${ARGC} EQUAL 2)
|
||||
@@ -97,11 +226,3 @@ function(set_specfile SPECFILE EXPORTNAME)
|
||||
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${FILENAME}.def ${CMAKE_CURRENT_BINARY_DIR}/${FILENAME}.c
|
||||
COMMAND ${CMAKE_SPEC_COMPILER} -a=${ARCH} -n=${EXPORTNAME} -d=${CMAKE_CURRENT_BINARY_DIR}/${FILENAME}.def -s=${CMAKE_CURRENT_BINARY_DIR}/${FILENAME}.c ${CMAKE_CURRENT_SOURCE_DIR}/${SPECFILE})
|
||||
endfunction()
|
||||
|
||||
# This function sets the the qemu disk image size (in MiB)
|
||||
function(set_disk_image_size SIZE)
|
||||
MATH(EXPR DISK_BLOCKS ${SIZE}*1024*1024/512)
|
||||
MATH(EXPR PART_BLOCKS ${DISK_BLOCKS}-2048)
|
||||
set(PROJECT_DISK_IMAGE_BLOCKS ${DISK_BLOCKS} CACHE INTERNAL "PROJECT_DISK_IMAGE_BLOCKS")
|
||||
set(PROJECT_PART_IMAGE_BLOCKS ${PART_BLOCKS} CACHE INTERNAL "PROJECT_PART_IMAGE_BLOCKS")
|
||||
endfunction()
|
||||
|
||||
@@ -3,8 +3,10 @@ set(CMAKE_SYSTEM_NAME Windows)
|
||||
|
||||
# Set toolchain compilers
|
||||
set(CMAKE_ASM_COMPILER clang-cl)
|
||||
set(CMAKE_ASM_LINKER ld.lld)
|
||||
set(CMAKE_C_COMPILER clang-cl)
|
||||
set(CMAKE_CXX_COMPILER clang-cl)
|
||||
set(CMAKE_LINKER lld-link)
|
||||
set(CMAKE_MC_COMPILER wmc)
|
||||
set(CMAKE_RC_COMPILER wrc)
|
||||
set(CMAKE_SPEC_COMPILER xtcspecc)
|
||||
@@ -20,8 +22,9 @@ set(CMAKE_CXX_EXTENSIONS OFF)
|
||||
set(CMAKE_C_STANDARD 23)
|
||||
set(CMAKE_CXX_STANDARD 23)
|
||||
|
||||
# Disable standard C libraries
|
||||
# Disable standard C and C++ libraries
|
||||
set(CMAKE_C_STANDARD_LIBRARIES "" CACHE INTERNAL "")
|
||||
set(CMAKE_CXX_STANDARD_LIBRARIES "" CACHE INTERNAL "")
|
||||
|
||||
# Clean linker flags
|
||||
set(CMAKE_STATIC_LINKER_FLAGS "")
|
||||
|
||||
@@ -11,11 +11,10 @@ endif()
|
||||
|
||||
# Set build optimisation
|
||||
if(BUILD_TYPE STREQUAL "DEBUG")
|
||||
add_compiler_ccxxflags("/Zi")
|
||||
add_compiler_ccxxflags("-Ob0 -Od")
|
||||
add_linker_flags("/DEBUG /INCREMENTAL /OPT:NOREF /OPT:NOICF /PDBSOURCEPATH:build")
|
||||
add_compiler_ccxxflags("/GS- /Zi /Ob0 /Od")
|
||||
add_linker_flags("/DEBUG /INCREMENTAL:NO /OPT:REF /OPT:NOICF /PDBSOURCEPATH:build")
|
||||
else()
|
||||
add_compiler_ccxxflags("-Ob2 -Oy")
|
||||
add_compiler_ccxxflags("/GS- /Ob2 /Ot /Ox /Oy")
|
||||
add_linker_flags("/INCREMENTAL:NO /OPT:REF /OPT:ICF")
|
||||
endif()
|
||||
|
||||
@@ -48,8 +47,12 @@ add_compiler_ccxxflags("-nostdinc -Wno-char-subscripts -Wno-incompatible-library
|
||||
add_compiler_ccxxflags("-Wno-microsoft-enum-forward-reference -Wno-multichar -Wno-parentheses-equality -Wno-undefined-inline")
|
||||
add_compiler_ccxxflags("-Wno-gnu-folding-constant")
|
||||
|
||||
# Set debugging symbols output directory
|
||||
# Disable compiler builtins
|
||||
add_compiler_ccxxflags("-fno-builtin")
|
||||
|
||||
# Set symbols and libraries output directory
|
||||
set(CMAKE_PDB_OUTPUT_DIRECTORY "${EXECTOS_BINARY_DIR}/output/symbols")
|
||||
set(LIBRARY_OUTPUT_PATH "${EXECTOS_BINARY_DIR}/output/sdk/lib")
|
||||
|
||||
# Set linker flags
|
||||
add_linker_flags("${HOTPATCH_LINKER_FLAG} /LARGEADDRESSAWARE /IGNORE:4039 /IGNORE:4104 /MANIFEST:NO /NODEFAULTLIB /SAFESEH:NO")
|
||||
|
||||
@@ -13,6 +13,10 @@ The ovmf_vars files, store UEFI variables, which are used to store and retrieve
|
||||
boot options, device settings, and system preferences. The ovmf_vars file contains the persistent variables specific to
|
||||
a virtual machine, allowing it to maintain its configuration across multiple boot sessions.
|
||||
|
||||
## BOCHS ROM BIOS
|
||||
The rombios.bin file contains the ROM BIOS image for Bochs. This image is distributed under the GNU Lesser General Public
|
||||
License (LGPL).
|
||||
|
||||
## Video BIOS (LGPL'd VGABios)
|
||||
The vgabios.bin file contains the Video Bios for Bochs and QEMU. This VGA Bios is very specific to the emulated VGA card.
|
||||
It is NOT meant to drive a physical vga card. It also implements support for VBE version 2.0.
|
||||
|
||||
@@ -3,9 +3,9 @@ plugin_ctrl: usb_xhci=false, serial=true, e1000=false, extfpuirq=true, parallel=
|
||||
config_interface: textconfig
|
||||
display_library: x
|
||||
memory: host=64, guest=64
|
||||
romimage: file="../sdk/firmware/ovmf_pure_amd64.fd", address=0x00000000, options=none
|
||||
romimage: file="../sdk/firmware/rombios.bin", address=0x00000000, options=none
|
||||
vgaromimage: file="../sdk/firmware/vgabios.bin"
|
||||
boot: floppy
|
||||
boot: disk
|
||||
floppy_bootsig_check: disabled=0
|
||||
floppya: type=1_44
|
||||
# no floppyb
|
||||
@@ -27,11 +27,7 @@ optramimage3: file=none
|
||||
optramimage4: file=none
|
||||
pci: enabled=1, chipset=i440fx, slot1=cirrus, slot2=none, slot3=none, slot4=none, slot5=none
|
||||
vga: extension=cirrus, update_freq=5, realtime=1, ddc=builtin
|
||||
cpu: count=1:1:1, ips=400000000, quantum=16, model=bx_generic, reset_on_triple_fault=0, cpuid_limit_winnt=0, ignore_bad_msrs=1, mwait_is_nop=0
|
||||
cpuid: level=6, stepping=3, model=3, family=6, vendor_string="GenuineIntel", brand_string=" Intel(R) Pentium(R) 4 CPU "
|
||||
cpuid: mmx=true, apic=xapic, simd=sse4_2, sse4a=false, misaligned_sse=false, sep=true
|
||||
cpuid: movbe=false, adx=false, aes=false, sha=false, xsave=false, xsaveopt=false, x86_64=true
|
||||
cpuid: 1g_pages=false, pcid=false, fsgsbase=false, smep=false, smap=false, mwait=true
|
||||
cpu: count=1:1:1, ips=400000000, quantum=16, model=corei7_sandy_bridge_2600k, reset_on_triple_fault=0, cpuid_limit_winnt=0, ignore_bad_msrs=1, mwait_is_nop=0
|
||||
print_timestamps: enabled=0
|
||||
port_e9_hack: enabled=0
|
||||
private_colormap: enabled=0
|
||||
|
||||
@@ -3,9 +3,9 @@ plugin_ctrl: usb_xhci=false, serial=true, e1000=false, extfpuirq=true, parallel=
|
||||
config_interface: textconfig
|
||||
display_library: x
|
||||
memory: host=64, guest=64
|
||||
romimage: file="../sdk/firmware/ovmf_pure_i686.fd", address=0x00000000, options=none
|
||||
romimage: file="../sdk/firmware/rombios.bin", address=0x00000000, options=none
|
||||
vgaromimage: file="../sdk/firmware/vgabios.bin"
|
||||
boot: floppy
|
||||
boot: disk
|
||||
floppy_bootsig_check: disabled=0
|
||||
floppya: type=1_44
|
||||
# no floppyb
|
||||
@@ -27,11 +27,7 @@ optramimage3: file=none
|
||||
optramimage4: file=none
|
||||
pci: enabled=1, chipset=i440fx, slot1=cirrus, slot2=none, slot3=none, slot4=none, slot5=none
|
||||
vga: extension=cirrus, update_freq=5, realtime=1, ddc=builtin
|
||||
cpu: count=1:1:1, ips=400000000, quantum=16, model=bx_generic, reset_on_triple_fault=0, cpuid_limit_winnt=0, ignore_bad_msrs=1, mwait_is_nop=0
|
||||
cpuid: level=6, stepping=3, model=3, family=6, vendor_string="GenuineIntel", brand_string=" Intel(R) Pentium(R) 4 CPU "
|
||||
cpuid: mmx=true, apic=xapic, simd=sse4_2, sse4a=false, misaligned_sse=false, sep=true
|
||||
cpuid: movbe=false, adx=false, aes=false, sha=false, xsave=false, xsaveopt=false, x86_64=true
|
||||
cpuid: 1g_pages=false, pcid=false, fsgsbase=false, smep=false, smap=false, mwait=true
|
||||
cpu: count=1:1:1, ips=400000000, quantum=16, model=corei7_sandy_bridge_2600k, reset_on_triple_fault=0, cpuid_limit_winnt=0, ignore_bad_msrs=1, mwait_is_nop=0
|
||||
print_timestamps: enabled=0
|
||||
port_e9_hack: enabled=0
|
||||
private_colormap: enabled=0
|
||||
|
||||
Двоичный файл не отображается.
Двоичный файл не отображается.
Двоичные данные
Двоичный файл не отображается.
Двоичные данные
Двоичный файл не отображается.
Двоичные данные
Двоичный файл не отображается.
Двоичные данные
Двоичный файл не отображается.
Двоичные данные
Двоичный файл не отображается.
@@ -0,0 +1,14 @@
|
||||
# XT Assembly Development Kit
|
||||
PROJECT(XTADK)
|
||||
|
||||
# Specify include directories
|
||||
include_directories(
|
||||
${EXECTOS_SOURCE_DIR}/sdk/xtdk
|
||||
${XTADK_SOURCE_DIR}/includes)
|
||||
|
||||
# Specify list of XTADK source code files
|
||||
list(APPEND XTADK_SOURCE
|
||||
${XTADK_SOURCE_DIR}/${ARCH}/ke.cc)
|
||||
|
||||
# Generate assembly header from XTADK sources
|
||||
generate_xtadk(xtadk "${XTADK_SOURCE}")
|
||||
@@ -0,0 +1,92 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: sdk/xtadk/amd64/ke.cc
|
||||
* DESCRIPTION: ADK generator for AMD64 version of Kernel Library
|
||||
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
|
||||
*/
|
||||
|
||||
#include <xtkmapi.h>
|
||||
#include <adkdefs.h>
|
||||
|
||||
|
||||
/**
|
||||
* Generates a definitions file for the Kernel Library used by the XTOS kernel assembly code
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCLINK
|
||||
XTAPI
|
||||
VOID
|
||||
GenerateAssemblyDefinitions(VOID)
|
||||
{
|
||||
/* Generate KTRAP_FRAME offsets */
|
||||
ADK_OFFSET(KTRAP_FRAME, Xmm0);
|
||||
ADK_OFFSET(KTRAP_FRAME, Xmm1);
|
||||
ADK_OFFSET(KTRAP_FRAME, Xmm2);
|
||||
ADK_OFFSET(KTRAP_FRAME, Xmm3);
|
||||
ADK_OFFSET(KTRAP_FRAME, Xmm4);
|
||||
ADK_OFFSET(KTRAP_FRAME, Xmm5);
|
||||
ADK_OFFSET(KTRAP_FRAME, Xmm6);
|
||||
ADK_OFFSET(KTRAP_FRAME, Xmm7);
|
||||
ADK_OFFSET(KTRAP_FRAME, Xmm8);
|
||||
ADK_OFFSET(KTRAP_FRAME, Xmm9);
|
||||
ADK_OFFSET(KTRAP_FRAME, Xmm10);
|
||||
ADK_OFFSET(KTRAP_FRAME, Xmm11);
|
||||
ADK_OFFSET(KTRAP_FRAME, Xmm12);
|
||||
ADK_OFFSET(KTRAP_FRAME, Xmm13);
|
||||
ADK_OFFSET(KTRAP_FRAME, Xmm14);
|
||||
ADK_OFFSET(KTRAP_FRAME, Xmm15);
|
||||
ADK_OFFSET(KTRAP_FRAME, MxCsr);
|
||||
ADK_OFFSET(KTRAP_FRAME, PreviousMode);
|
||||
ADK_OFFSET(KTRAP_FRAME, Cr2);
|
||||
ADK_OFFSET(KTRAP_FRAME, Cr3);
|
||||
ADK_OFFSET(KTRAP_FRAME, Dr0);
|
||||
ADK_OFFSET(KTRAP_FRAME, Dr1);
|
||||
ADK_OFFSET(KTRAP_FRAME, Dr2);
|
||||
ADK_OFFSET(KTRAP_FRAME, Dr3);
|
||||
ADK_OFFSET(KTRAP_FRAME, Dr6);
|
||||
ADK_OFFSET(KTRAP_FRAME, Dr7);
|
||||
ADK_OFFSET(KTRAP_FRAME, SegDs);
|
||||
ADK_OFFSET(KTRAP_FRAME, SegEs);
|
||||
ADK_OFFSET(KTRAP_FRAME, SegFs);
|
||||
ADK_OFFSET(KTRAP_FRAME, SegGs);
|
||||
ADK_OFFSET(KTRAP_FRAME, Rax);
|
||||
ADK_OFFSET(KTRAP_FRAME, Rbx);
|
||||
ADK_OFFSET(KTRAP_FRAME, Rcx);
|
||||
ADK_OFFSET(KTRAP_FRAME, Rdx);
|
||||
ADK_OFFSET(KTRAP_FRAME, R8);
|
||||
ADK_OFFSET(KTRAP_FRAME, R9);
|
||||
ADK_OFFSET(KTRAP_FRAME, R10);
|
||||
ADK_OFFSET(KTRAP_FRAME, R11);
|
||||
ADK_OFFSET(KTRAP_FRAME, R12);
|
||||
ADK_OFFSET(KTRAP_FRAME, R13);
|
||||
ADK_OFFSET(KTRAP_FRAME, R14);
|
||||
ADK_OFFSET(KTRAP_FRAME, R15);
|
||||
ADK_OFFSET(KTRAP_FRAME, Rsi);
|
||||
ADK_OFFSET(KTRAP_FRAME, Rdi);
|
||||
ADK_OFFSET(KTRAP_FRAME, Rbp);
|
||||
ADK_OFFSET(KTRAP_FRAME, Vector);
|
||||
ADK_OFFSET(KTRAP_FRAME, ErrorCode);
|
||||
ADK_OFFSET(KTRAP_FRAME, ExceptionFrame);
|
||||
ADK_OFFSET(KTRAP_FRAME, Rip);
|
||||
ADK_OFFSET(KTRAP_FRAME, SegCs);
|
||||
ADK_OFFSET(KTRAP_FRAME, Flags);
|
||||
ADK_OFFSET(KTRAP_FRAME, Rsp);
|
||||
ADK_OFFSET(KTRAP_FRAME, SegSs);
|
||||
|
||||
/* Generate KTRAP_FRAME size and REGISTERS_SIZE */
|
||||
ADK_SIZE(KTRAP_FRAME);
|
||||
ADK_SIZE_FROM(REGISTERS_SIZE, KTRAP_FRAME, Rax);
|
||||
|
||||
/* Generate PROCESSOR_START_BLOCK offsets */
|
||||
ADK_OFFSET(PROCESSOR_START_BLOCK, Cr3);
|
||||
ADK_OFFSET(PROCESSOR_START_BLOCK, Cr4);
|
||||
ADK_OFFSET(PROCESSOR_START_BLOCK, EntryPoint);
|
||||
ADK_OFFSET(PROCESSOR_START_BLOCK, InitialStack);
|
||||
ADK_OFFSET(PROCESSOR_START_BLOCK, ProcessorStructures);
|
||||
ADK_OFFSET(PROCESSOR_START_BLOCK, Stack);
|
||||
ADK_OFFSET(PROCESSOR_START_BLOCK, Started);
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: sdk/xtadk/i686/ke.cc
|
||||
* DESCRIPTION: ADK generator for i686 version of Kernel Library
|
||||
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
|
||||
*/
|
||||
|
||||
#include <xtkmapi.h>
|
||||
#include <adkdefs.h>
|
||||
|
||||
|
||||
/**
|
||||
* Generates a definitions file for the Kernel Library used by the XTOS kernel assembly code
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCLINK
|
||||
XTAPI
|
||||
VOID
|
||||
GenerateAssemblyDefinitions(VOID)
|
||||
{
|
||||
/* Generate KTRAP_FRAME offsets */
|
||||
ADK_OFFSET(KTRAP_FRAME, PreviousMode);
|
||||
ADK_OFFSET(KTRAP_FRAME, Cr2);
|
||||
ADK_OFFSET(KTRAP_FRAME, Cr3);
|
||||
ADK_OFFSET(KTRAP_FRAME, Dr0);
|
||||
ADK_OFFSET(KTRAP_FRAME, Dr1);
|
||||
ADK_OFFSET(KTRAP_FRAME, Dr2);
|
||||
ADK_OFFSET(KTRAP_FRAME, Dr3);
|
||||
ADK_OFFSET(KTRAP_FRAME, Dr6);
|
||||
ADK_OFFSET(KTRAP_FRAME, Dr7);
|
||||
ADK_OFFSET(KTRAP_FRAME, SegDs);
|
||||
ADK_OFFSET(KTRAP_FRAME, SegEs);
|
||||
ADK_OFFSET(KTRAP_FRAME, SegFs);
|
||||
ADK_OFFSET(KTRAP_FRAME, SegGs);
|
||||
ADK_OFFSET(KTRAP_FRAME, Eax);
|
||||
ADK_OFFSET(KTRAP_FRAME, Ebx);
|
||||
ADK_OFFSET(KTRAP_FRAME, Ecx);
|
||||
ADK_OFFSET(KTRAP_FRAME, Edx);
|
||||
ADK_OFFSET(KTRAP_FRAME, Esi);
|
||||
ADK_OFFSET(KTRAP_FRAME, Edi);
|
||||
ADK_OFFSET(KTRAP_FRAME, Ebp);
|
||||
ADK_OFFSET(KTRAP_FRAME, Vector);
|
||||
ADK_OFFSET(KTRAP_FRAME, ErrorCode);
|
||||
ADK_OFFSET(KTRAP_FRAME, Eip);
|
||||
ADK_OFFSET(KTRAP_FRAME, SegCs);
|
||||
ADK_OFFSET(KTRAP_FRAME, Flags);
|
||||
ADK_OFFSET(KTRAP_FRAME, Esp);
|
||||
ADK_OFFSET(KTRAP_FRAME, SegSs);
|
||||
|
||||
/* Generate KTRAP_FRAME size and REGISTERS_SIZE */
|
||||
ADK_SIZE(KTRAP_FRAME);
|
||||
ADK_SIZE_FROM(REGISTERS_SIZE, KTRAP_FRAME, Eax);
|
||||
|
||||
/* Generate PROCESSOR_START_BLOCK offsets */
|
||||
ADK_OFFSET(PROCESSOR_START_BLOCK, Cr3);
|
||||
ADK_OFFSET(PROCESSOR_START_BLOCK, Cr4);
|
||||
ADK_OFFSET(PROCESSOR_START_BLOCK, EntryPoint);
|
||||
ADK_OFFSET(PROCESSOR_START_BLOCK, InitialStack);
|
||||
ADK_OFFSET(PROCESSOR_START_BLOCK, ProcessorStructures);
|
||||
ADK_OFFSET(PROCESSOR_START_BLOCK, Stack);
|
||||
ADK_OFFSET(PROCESSOR_START_BLOCK, Started);
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: sdk/xtadk/adkdefs.h
|
||||
* DESCRIPTION: Definitions for XTADK
|
||||
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef __XTADK_ADKDEFS_H
|
||||
#define __XTADK_ADKDEFS_H
|
||||
|
||||
|
||||
/* Macros for calculating structure size and offsets for assembler code */
|
||||
#define ADK_DEFINE(Symbol, Value) __asm__ volatile("\n\t# ==> " #Symbol " %c0" : : "i" ((SIZE_T)(Value)))
|
||||
#define ADK_OFFSET(Structure, Member) ADK_DEFINE(Structure ## _ ## Member, FIELD_OFFSET(Structure, Member))
|
||||
#define ADK_SIZE(Structure) ADK_DEFINE(Structure ## _SIZE, sizeof(Structure))
|
||||
#define ADK_SIZE_FROM(Name, Structure, Member) ADK_DEFINE(Structure ## _ ## Name, sizeof(Structure) - FIELD_OFFSET(Structure, Member))
|
||||
|
||||
#endif /* __XTADK_ADKDEFS_H */
|
||||
@@ -1,13 +0,0 @@
|
||||
## XT Building Kit (XTBK)
|
||||
The XTBK, or XT Building Kit is a kind of SDK (Software Development Kit) utilized internally by XTOS, the XT Operating
|
||||
System. It is designed to provide a collection of public functions that are available within the operating system but
|
||||
not necessarily exposed or accessible to software and driver developers.
|
||||
|
||||
Unlike XTDK, which focuses on providing headers for external developers to create kernel mode drivers and user mode
|
||||
applications, XTBK serves as an extension to XTDK and aids in the code-sharing process between different XTOS
|
||||
components. This enables the reuse of code across various components of the operating system, resulting in a more
|
||||
efficient and streamlined development process.
|
||||
|
||||
By incorporating XTBK, XTOS can optimize code reuse, particularly in low-level kernel code that can be shared with other
|
||||
components like the boot loader. This approach helps in reducing code duplication and improving overall code
|
||||
maintainability. Additionally, it allows for consistent implementation of functionality across different parts of the OS.
|
||||
@@ -1,44 +0,0 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: sdk/xtdk/amd64/arfuncs.h
|
||||
* DESCRIPTION: AMD64 architecture library routines
|
||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||
*/
|
||||
|
||||
#ifndef __XTDK_AMD64_ARFUNCS_H
|
||||
#define __XTDK_AMD64_ARFUNCS_H
|
||||
|
||||
#include <xtdefs.h>
|
||||
#include <xtstruct.h>
|
||||
#include <xttypes.h>
|
||||
#include <amd64/xtstruct.h>
|
||||
|
||||
|
||||
/* Routines used by XTLDR */
|
||||
XTCDECL
|
||||
VOID
|
||||
ArClearInterruptFlag(VOID);
|
||||
|
||||
XTCDECL
|
||||
BOOLEAN
|
||||
ArCpuId(IN OUT PCPUID_REGISTERS Registers);
|
||||
|
||||
XTCDECL
|
||||
VOID
|
||||
ArHalt(VOID);
|
||||
|
||||
XTCDECL
|
||||
ULONG_PTR
|
||||
ArReadControlRegister(IN USHORT ControlRegister);
|
||||
|
||||
XTCDECL
|
||||
ULONGLONG
|
||||
ArReadModelSpecificRegister(IN ULONG Register);
|
||||
|
||||
XTCDECL
|
||||
VOID
|
||||
ArWriteControlRegister(IN USHORT ControlRegister,
|
||||
IN UINT_PTR Value);
|
||||
|
||||
#endif /* __XTDK_AMD64_ARFUNCS_H */
|
||||
+333
-90
@@ -12,6 +12,7 @@
|
||||
#include <xtdefs.h>
|
||||
#include <xtstruct.h>
|
||||
#include <xttypes.h>
|
||||
#include ARCH_HEADER(xtstruct.h)
|
||||
|
||||
|
||||
/* Control Register 0 constants */
|
||||
@@ -39,13 +40,22 @@
|
||||
#define CR4_PCE 0x00000100
|
||||
#define CR4_FXSR 0x00000200
|
||||
#define CR4_XMMEXCPT 0x00000400
|
||||
#define CR4_UMIP 0x00000800
|
||||
#define CR4_LA57 0x00001000
|
||||
#define CR4_RESERVED1 0x00001800
|
||||
#define CR4_VMXE 0x00002000
|
||||
#define CR4_SMXE 0x00004000
|
||||
#define CR4_RESERVED2 0x00018000
|
||||
#define CR4_XSAVE 0x00020000
|
||||
#define CR4_RESERVED3 0xFFFC0000
|
||||
#define CR4_FSGSBASE 0x00010000
|
||||
#define CR4_PCIDE 0x00020000
|
||||
#define CR4_XSAVE 0x00040000
|
||||
#define CR4_KL 0x00080000
|
||||
#define CR4_SMEP 0x00100000
|
||||
#define CR4_SMAP 0x00200000
|
||||
#define CR4_PKE 0x00400000
|
||||
#define CR4_CET 0x00800000
|
||||
#define CR4_PKS 0x01000000
|
||||
#define CR4_UINTR 0x02000000
|
||||
#define CR4_LASS 0x08000000
|
||||
#define CR4_LAM_SUP 0x10000000
|
||||
|
||||
/* Descriptors size */
|
||||
#define GDT_ENTRIES 128
|
||||
@@ -84,6 +94,7 @@
|
||||
#define X86_MSR_FSBASE 0xC0000100
|
||||
#define X86_MSR_GSBASE 0xC0000101
|
||||
#define X86_MSR_KERNEL_GSBASE 0xC0000102
|
||||
#define X86_MSR_TSC_AUX 0xC0000103
|
||||
|
||||
/* Processor features in the EFER MSR */
|
||||
#define X86_MSR_EFER_SCE (1 << 0)
|
||||
@@ -91,113 +102,337 @@
|
||||
#define X86_MSR_EFER_LMA (1 << 10)
|
||||
#define X86_MSR_EFER_NXE (1 << 11)
|
||||
#define X86_MSR_EFER_SVME (1 << 12)
|
||||
#define X86_EFER_LMSLE (1 << 13)
|
||||
#define X86_EFER_FFXSR (1 << 14)
|
||||
#define X86_EFER_TCE (1 << 15)
|
||||
#define X86_EFER_AUTOIBRS (1 << 21)
|
||||
|
||||
/* X86 EFLAG bit masks definitions */
|
||||
#define X86_EFLAGS_CF_MASK 0x00000001
|
||||
#define X86_EFLAGS_PF_MASK 0x00000004
|
||||
#define X86_EFALGS_AF_MASK 0x00000010
|
||||
#define X86_EFLAGS_ZF_MASK 0x00000040
|
||||
#define X86_EFLAGS_SF_MASK 0x00000080
|
||||
#define X86_EFLAGS_TF_MASK 0x00000100
|
||||
#define X86_EFLAGS_IF_MASK 0x00000200
|
||||
#define X86_EFLAGS_DF_MASK 0x00000400
|
||||
#define X86_EFLAGS_OF_MASK 0x00000800
|
||||
#define X86_EFLAGS_IOPL_MASK 0x00003000
|
||||
#define X86_EFLAGS_NT_MASK 0x00004000
|
||||
#define X86_EFLAGS_RF_MASK 0x00010000
|
||||
#define X86_EFLAGS_VM_MASK 0x00020000
|
||||
#define X86_EFLAGS_AC_MASK 0x00040000
|
||||
#define X86_EFLAGS_VIF_MASK 0x00080000
|
||||
#define X86_EFLAGS_VIP_MASK 0x00100000
|
||||
#define X86_EFLAGS_ID_MASK 0x00200000
|
||||
#define X86_EFLAGS_NF_MASK 0x00000000 /* None */
|
||||
#define X86_EFLAGS_CF_MASK 0x00000001 /* Carry */
|
||||
#define X86_EFLAGS_PF_MASK 0x00000004 /* Parity */
|
||||
#define X86_EFALGS_AF_MASK 0x00000010 /* Aux Carry */
|
||||
#define X86_EFLAGS_ZF_MASK 0x00000040 /* Zero */
|
||||
#define X86_EFLAGS_SF_MASK 0x00000080 /* Sign */
|
||||
#define X86_EFLAGS_TF_MASK 0x00000100 /* Trap */
|
||||
#define X86_EFLAGS_IF_MASK 0x00000200 /* Interrupt */
|
||||
#define X86_EFLAGS_DF_MASK 0x00000400 /* Direction */
|
||||
#define X86_EFLAGS_OF_MASK 0x00000800 /* Overflow */
|
||||
#define X86_EFLAGS_IOPL_MASK 0x00003000 /* I/O Privilege */
|
||||
#define X86_EFLAGS_NT_MASK 0x00004000 /* Nested Task */
|
||||
#define X86_EFLAGS_SIGN_MASK 0x00008000 /* Sign */
|
||||
#define X86_EFLAGS_RF_MASK 0x00010000 /* Resume */
|
||||
#define X86_EFLAGS_V86_MASK 0x00020000 /* Virtual 8086 */
|
||||
#define X86_EFLAGS_AC_MASK 0x00040000 /* Alignment Check */
|
||||
#define X86_EFLAGS_VIF_MASK 0x00080000 /* Virtual Interrupt */
|
||||
#define X86_EFLAGS_VIP_MASK 0x00100000 /* Virtual Interrupt Pending */
|
||||
#define X86_EFLAGS_ID_MASK 0x00200000 /* Identification */
|
||||
|
||||
|
||||
/* C/C++ specific code */
|
||||
#ifndef __XTOS_ASSEMBLER__
|
||||
|
||||
/* CPU vendor enumeration list */
|
||||
typedef enum _CPU_VENDOR
|
||||
{
|
||||
CPU_VENDOR_AMD = 0x68747541,
|
||||
CPU_VENDOR_INTEL = 0x756e6547,
|
||||
CPU_VENDOR_INTEL = 0x756E6547,
|
||||
CPU_VENDOR_UNKNOWN = 0xFFFFFFFF
|
||||
} CPU_VENDOR, *PCPU_VENDOR;
|
||||
|
||||
/* CPUID features enumeration list */
|
||||
typedef enum _CPUID_FEATURES
|
||||
/* CPUID advanced power management features (0x80000007) enumeration list */
|
||||
typedef enum _CPUID_FEATURES_ADVANCED_POWER_MANAGEMENT
|
||||
{
|
||||
CPUID_FEATURES_ECX_SSE3 = 1 << 0,
|
||||
CPUID_FEATURES_ECX_PCLMUL = 1 << 1,
|
||||
CPUID_FEATURES_ECX_DTES64 = 1 << 2,
|
||||
CPUID_FEATURES_ECX_MONITOR = 1 << 3,
|
||||
CPUID_FEATURES_ECX_DS_CPL = 1 << 4,
|
||||
CPUID_FEATURES_ECX_VMX = 1 << 5,
|
||||
CPUID_FEATURES_ECX_SMX = 1 << 6,
|
||||
CPUID_FEATURES_ECX_EST = 1 << 7,
|
||||
CPUID_FEATURES_ECX_TM2 = 1 << 8,
|
||||
CPUID_FEATURES_ECX_SSSE3 = 1 << 9,
|
||||
CPUID_FEATURES_ECX_CID = 1 << 10,
|
||||
CPUID_FEATURES_ECX_SDBG = 1 << 11,
|
||||
CPUID_FEATURES_ECX_FMA = 1 << 12,
|
||||
CPUID_FEATURES_ECX_CX16 = 1 << 13,
|
||||
CPUID_FEATURES_ECX_XTPR = 1 << 14,
|
||||
CPUID_FEATURES_ECX_PDCM = 1 << 15,
|
||||
CPUID_FEATURES_ECX_PCID = 1 << 17,
|
||||
CPUID_FEATURES_ECX_DCA = 1 << 18,
|
||||
CPUID_FEATURES_ECX_SSE4_1 = 1 << 19,
|
||||
CPUID_FEATURES_ECX_SSE4_2 = 1 << 20,
|
||||
CPUID_FEATURES_ECX_X2APIC = 1 << 21,
|
||||
CPUID_FEATURES_ECX_MOVBE = 1 << 22,
|
||||
CPUID_FEATURES_ECX_POPCNT = 1 << 23,
|
||||
CPUID_FEATURES_ECX_TSC = 1 << 24,
|
||||
CPUID_FEATURES_ECX_AES = 1 << 25,
|
||||
CPUID_FEATURES_ECX_XSAVE = 1 << 26,
|
||||
CPUID_FEATURES_ECX_OSXSAVE = 1 << 27,
|
||||
CPUID_FEATURES_ECX_AVX = 1 << 28,
|
||||
CPUID_FEATURES_ECX_F16C = 1 << 29,
|
||||
CPUID_FEATURES_ECX_RDRAND = 1 << 30,
|
||||
CPUID_FEATURES_ECX_HYPERVISOR = 1 << 31,
|
||||
CPUID_FEATURES_EDX_FPU = 1 << 0,
|
||||
CPUID_FEATURES_EDX_VME = 1 << 1,
|
||||
CPUID_FEATURES_EDX_DE = 1 << 2,
|
||||
CPUID_FEATURES_EDX_PSE = 1 << 3,
|
||||
CPUID_FEATURES_EDX_TSC = 1 << 4,
|
||||
CPUID_FEATURES_EDX_MSR = 1 << 5,
|
||||
CPUID_FEATURES_EDX_PAE = 1 << 6,
|
||||
CPUID_FEATURES_EDX_MCE = 1 << 7,
|
||||
CPUID_FEATURES_EDX_CX8 = 1 << 8,
|
||||
CPUID_FEATURES_EDX_APIC = 1 << 9,
|
||||
CPUID_FEATURES_EDX_SEP = 1 << 11,
|
||||
CPUID_FEATURES_EDX_MTRR = 1 << 12,
|
||||
CPUID_FEATURES_EDX_PGE = 1 << 13,
|
||||
CPUID_FEATURES_EDX_MCA = 1 << 14,
|
||||
CPUID_FEATURES_EDX_CMOV = 1 << 15,
|
||||
CPUID_FEATURES_EDX_PAT = 1 << 16,
|
||||
CPUID_FEATURES_EDX_PSE36 = 1 << 17,
|
||||
CPUID_FEATURES_EDX_PSN = 1 << 18,
|
||||
CPUID_FEATURES_EDX_CLFLUSH = 1 << 19,
|
||||
CPUID_FEATURES_EDX_DS = 1 << 21,
|
||||
CPUID_FEATURES_EDX_ACPI = 1 << 22,
|
||||
CPUID_FEATURES_EDX_MMX = 1 << 23,
|
||||
CPUID_FEATURES_EDX_FXSR = 1 << 24,
|
||||
CPUID_FEATURES_EDX_SSE = 1 << 25,
|
||||
CPUID_FEATURES_EDX_SSE2 = 1 << 26,
|
||||
CPUID_FEATURES_EDX_SS = 1 << 27,
|
||||
CPUID_FEATURES_EDX_HTT = 1 << 28,
|
||||
CPUID_FEATURES_EDX_TM = 1 << 29,
|
||||
CPUID_FEATURES_EDX_IA64 = 1 << 30,
|
||||
CPUID_FEATURES_EDX_PBE = 1 << 31
|
||||
} CPUID_FEATURES, *PCPUID_FEATURES;
|
||||
CPUID_FEATURES_EDX_TS = 1 << 0, /* Temperature Sensor */
|
||||
CPUID_FEATURES_EDX_FIS = 1 << 1, /* Frequency ID Selection */
|
||||
CPUID_FEATURES_EDX_VIS = 1 << 2, /* Voltage ID Selection */
|
||||
CPUID_FEATURES_EDX_TTS = 1 << 3, /* ThermaTrip Support */
|
||||
CPUID_FEATURES_EDX_HTC = 1 << 4, /* Hardware Thermal Throttling */
|
||||
CPUID_FEATURES_EDX_STC = 1 << 5, /* Software Thermal Throttling */
|
||||
CPUID_FEATURES_EDX_TSCI = 1 << 8 /* TSC Invariant */
|
||||
} CPUID_FEATURES_ADVANCED_POWER_MANAGEMENT, *PCPUID_FEATURES_ADVANCED_POWER_MANAGEMENT;
|
||||
|
||||
/* CPUID extended features (0x80000001) enumeration list */
|
||||
typedef enum _CPUID_FEATURES_EXTENDED
|
||||
{
|
||||
CPUID_FEATURES_ECX_LAHF_SAHF = 1 << 0,
|
||||
CPUID_FEATURES_ECX_CMP_LEGACY = 1 << 1,
|
||||
CPUID_FEATURES_ECX_SVM = 1 << 2,
|
||||
CPUID_FEATURES_ECX_EXT_APIC_SPACE = 1 << 3,
|
||||
CPUID_FEATURES_ECX_ALT_MOV_CR8 = 1 << 4,
|
||||
CPUID_FEATURES_ECX_LZCNT = 1 << 5,
|
||||
CPUID_FEATURES_ECX_SSE4A = 1 << 6,
|
||||
CPUID_FEATURES_ECX_MISALIGNED_SSE = 1 << 7,
|
||||
CPUID_FEATURES_ECX_PREFETCHW = 1 << 8,
|
||||
CPUID_FEATURES_ECX_OSVW = 1 << 9,
|
||||
CPUID_FEATURES_ECX_IBS = 1 << 10,
|
||||
CPUID_FEATURES_ECX_XOP = 1 << 11,
|
||||
CPUID_FEATURES_ECX_SKINIT = 1 << 12,
|
||||
CPUID_FEATURES_ECX_WDT = 1 << 13,
|
||||
CPUID_FEATURES_ECX_LWP = 1 << 15,
|
||||
CPUID_FEATURES_ECX_FMA4 = 1 << 16,
|
||||
CPUID_FEATURES_ECX_TCE = 1 << 17,
|
||||
CPUID_FEATURES_ECX_NODEID = 1 << 19,
|
||||
CPUID_FEATURES_ECX_TBM = 1 << 21,
|
||||
CPUID_FEATURES_ECX_TOPOLOGY_EXTENSIONS = 1 << 22,
|
||||
CPUID_FEATURES_ECX_PERFCTR_EXT_CORE = 1 << 23,
|
||||
CPUID_FEATURES_ECX_PERFCTR_EXT_NB = 1 << 24,
|
||||
CPUID_FEATURES_ECX_DATA_BREAKPOINT_EXT = 1 << 26,
|
||||
CPUID_FEATURES_ECX_PERF_TSC = 1 << 27,
|
||||
CPUID_FEATURES_ECX_PERFCTR_EXT_L2I = 1 << 28,
|
||||
CPUID_FEATURES_ECX_MONITORX_MWAITX = 1 << 29,
|
||||
CPUID_FEATURES_ECX_CODEBP_ADDRMASK_EXT = 1 << 30,
|
||||
CPUID_FEATURES_EDX_SYSCALL_SYSRET = 1 << 11,
|
||||
CPUID_FEATURES_EDX_NX = 1 << 20,
|
||||
CPUID_FEATURES_EDX_AMD_MMX_EXT = 1 << 22,
|
||||
CPUID_FEATURES_EDX_FFXSR = 1 << 25,
|
||||
CPUID_FEATURES_EDX_1G_PAGES = 1 << 26,
|
||||
CPUID_FEATURES_EDX_RDTSCP = 1 << 27,
|
||||
CPUID_FEATURES_EDX_LONG_MODE = 1 << 29,
|
||||
CPUID_FEATURES_EDX_3DNOW_EXT = 1 << 30,
|
||||
CPUID_FEATURES_EDX_3DNOW = 1 << 31
|
||||
} CPUID_FEATURES_EXTENDED, *PCPUID_FEATURES_EXTENDED;
|
||||
|
||||
/* CPUID Thermal and Power Management features (0x00000006) enumeration list */
|
||||
typedef enum _CPUID_FEATURES_POWER_MANAGEMENT
|
||||
{
|
||||
CPUID_FEATURES_EAX_DTHERM = 1 << 0,
|
||||
CPUID_FEATURES_EAX_IDA = 1 << 1,
|
||||
CPUID_FEATURES_EAX_ARAT = 1 << 2,
|
||||
CPUID_FEATURES_EAX_PLN = 1 << 4,
|
||||
CPUID_FEATURES_EAX_PTS = 1 << 6,
|
||||
CPUID_FEATURES_EAX_HWP = 1 << 7,
|
||||
CPUID_FEATURES_EAX_HWP_NOTIFY = 1 << 8,
|
||||
CPUID_FEATURES_EAX_HWP_ACT_WINDOW = 1 << 9,
|
||||
CPUID_FEATURES_EAX_HWP_EPP = 1 << 10,
|
||||
CPUID_FEATURES_EAX_HWP_PKG_REQ = 1 << 11,
|
||||
CPUID_FEATURES_EAX_HWP_HIGHEST_PERF_CHANGE = 1 << 15,
|
||||
CPUID_FEATURES_EAX_HFI = 1 << 19
|
||||
} CPUID_FEATURES_LEAF6, *PCPUID_FEATURES_LEAF6;
|
||||
|
||||
/* CPUID STD1 features (0x00000001) enumeration list */
|
||||
typedef enum _CPUID_FEATURES_STANDARD1
|
||||
{
|
||||
CPUID_FEATURES_ECX_SSE3 = 1 << 0,
|
||||
CPUID_FEATURES_ECX_PCLMUL = 1 << 1,
|
||||
CPUID_FEATURES_ECX_DTES64 = 1 << 2,
|
||||
CPUID_FEATURES_ECX_MONITOR = 1 << 3,
|
||||
CPUID_FEATURES_ECX_DS_CPL = 1 << 4,
|
||||
CPUID_FEATURES_ECX_VMX = 1 << 5,
|
||||
CPUID_FEATURES_ECX_SMX = 1 << 6,
|
||||
CPUID_FEATURES_ECX_EST = 1 << 7,
|
||||
CPUID_FEATURES_ECX_TM2 = 1 << 8,
|
||||
CPUID_FEATURES_ECX_SSSE3 = 1 << 9,
|
||||
CPUID_FEATURES_ECX_CID = 1 << 10,
|
||||
CPUID_FEATURES_ECX_SDBG = 1 << 11,
|
||||
CPUID_FEATURES_ECX_FMA = 1 << 12,
|
||||
CPUID_FEATURES_ECX_CX16 = 1 << 13,
|
||||
CPUID_FEATURES_ECX_XTPR = 1 << 14,
|
||||
CPUID_FEATURES_ECX_PDCM = 1 << 15,
|
||||
CPUID_FEATURES_ECX_PCID = 1 << 17,
|
||||
CPUID_FEATURES_ECX_DCA = 1 << 18,
|
||||
CPUID_FEATURES_ECX_SSE4_1 = 1 << 19,
|
||||
CPUID_FEATURES_ECX_SSE4_2 = 1 << 20,
|
||||
CPUID_FEATURES_ECX_X2APIC = 1 << 21,
|
||||
CPUID_FEATURES_ECX_MOVBE = 1 << 22,
|
||||
CPUID_FEATURES_ECX_POPCNT = 1 << 23,
|
||||
CPUID_FEATURES_ECX_TSC_DEADLINE = 1 << 24,
|
||||
CPUID_FEATURES_ECX_AES = 1 << 25,
|
||||
CPUID_FEATURES_ECX_XSAVE = 1 << 26,
|
||||
CPUID_FEATURES_ECX_OSXSAVE = 1 << 27,
|
||||
CPUID_FEATURES_ECX_AVX = 1 << 28,
|
||||
CPUID_FEATURES_ECX_F16C = 1 << 29,
|
||||
CPUID_FEATURES_ECX_RDRAND = 1 << 30,
|
||||
CPUID_FEATURES_ECX_HYPERVISOR = 1 << 31,
|
||||
CPUID_FEATURES_EDX_FPU = 1 << 0,
|
||||
CPUID_FEATURES_EDX_VME = 1 << 1,
|
||||
CPUID_FEATURES_EDX_DE = 1 << 2,
|
||||
CPUID_FEATURES_EDX_PSE = 1 << 3,
|
||||
CPUID_FEATURES_EDX_TSC = 1 << 4,
|
||||
CPUID_FEATURES_EDX_MSR = 1 << 5,
|
||||
CPUID_FEATURES_EDX_PAE = 1 << 6,
|
||||
CPUID_FEATURES_EDX_MCE = 1 << 7,
|
||||
CPUID_FEATURES_EDX_CX8 = 1 << 8,
|
||||
CPUID_FEATURES_EDX_APIC = 1 << 9,
|
||||
CPUID_FEATURES_EDX_SEP = 1 << 11,
|
||||
CPUID_FEATURES_EDX_MTRR = 1 << 12,
|
||||
CPUID_FEATURES_EDX_PGE = 1 << 13,
|
||||
CPUID_FEATURES_EDX_MCA = 1 << 14,
|
||||
CPUID_FEATURES_EDX_CMOV = 1 << 15,
|
||||
CPUID_FEATURES_EDX_PAT = 1 << 16,
|
||||
CPUID_FEATURES_EDX_PSE36 = 1 << 17,
|
||||
CPUID_FEATURES_EDX_PSN = 1 << 18,
|
||||
CPUID_FEATURES_EDX_CLFLUSH = 1 << 19,
|
||||
CPUID_FEATURES_EDX_DS = 1 << 21,
|
||||
CPUID_FEATURES_EDX_ACPI = 1 << 22,
|
||||
CPUID_FEATURES_EDX_MMX = 1 << 23,
|
||||
CPUID_FEATURES_EDX_FXSR = 1 << 24,
|
||||
CPUID_FEATURES_EDX_SSE = 1 << 25,
|
||||
CPUID_FEATURES_EDX_SSE2 = 1 << 26,
|
||||
CPUID_FEATURES_EDX_SS = 1 << 27,
|
||||
CPUID_FEATURES_EDX_HTT = 1 << 28,
|
||||
CPUID_FEATURES_EDX_TM = 1 << 29,
|
||||
CPUID_FEATURES_EDX_IA64 = 1 << 30,
|
||||
CPUID_FEATURES_EDX_PBE = 1 << 31
|
||||
} CPUID_FEATURES_STANDARD1, *PCPUID_FEATURES_STANDARD1;
|
||||
|
||||
/* CPUID STD7 features (0x00000007, subleaf 0) enumeration list */
|
||||
typedef enum _CPUID_FEATURES_STANDARD7_LEAF0
|
||||
{
|
||||
CPUID_FEATURES_EBX_FSGSBASE = 1 << 0,
|
||||
CPUID_FEATURES_EBX_TSC_ADJUST = 1 << 1,
|
||||
CPUID_FEATURES_EBX_SGX = 1 << 2,
|
||||
CPUID_FEATURES_EBX_BMI1 = 1 << 3,
|
||||
CPUID_FEATURES_EBX_HLE = 1 << 4,
|
||||
CPUID_FEATURES_EBX_AVX2 = 1 << 5,
|
||||
CPUID_FEATURES_EBX_FDP_DEPRECATION = 1 << 6,
|
||||
CPUID_FEATURES_EBX_SMEP = 1 << 7,
|
||||
CPUID_FEATURES_EBX_BMI2 = 1 << 8,
|
||||
CPUID_FEATURES_EBX_ERMS = 1 << 9,
|
||||
CPUID_FEATURES_EBX_INVPCID = 1 << 10,
|
||||
CPUID_FEATURES_EBX_RTM = 1 << 11,
|
||||
CPUID_FEATURES_EBX_QOS_MONITORING = 1 << 12,
|
||||
CPUID_FEATURES_EBX_DEPRECATE_FCS_FDS = 1 << 13,
|
||||
CPUID_FEATURES_EBX_MPX = 1 << 14,
|
||||
CPUID_FEATURES_EBX_QOS_ENFORCEMENT = 1 << 15,
|
||||
CPUID_FEATURES_EBX_AVX512F = 1 << 16,
|
||||
CPUID_FEATURES_EBX_AVX512DQ = 1 << 17,
|
||||
CPUID_FEATURES_EBX_RDSEED = 1 << 18,
|
||||
CPUID_FEATURES_EBX_ADX = 1 << 19,
|
||||
CPUID_FEATURES_EBX_SMAP = 1 << 20,
|
||||
CPUID_FEATURES_EBX_AVX512IFMA52 = 1 << 21,
|
||||
CPUID_FEATURES_EBX_CLFLUSHOPT = 1 << 23,
|
||||
CPUID_FEATURES_EBX_CLWB = 1 << 24,
|
||||
CPUID_FEATURES_EBX_PROCESSOR_TRACE = 1 << 25,
|
||||
CPUID_FEATURES_EBX_AVX512PF = 1 << 26,
|
||||
CPUID_FEATURES_EBX_AVX512ER = 1 << 27,
|
||||
CPUID_FEATURES_EBX_AVX512CD = 1 << 28,
|
||||
CPUID_FEATURES_EBX_SHA = 1 << 29,
|
||||
CPUID_FEATURES_EBX_AVX512BW = 1 << 30,
|
||||
CPUID_FEATURES_EBX_AVX512VL = 1 << 31,
|
||||
CPUID_FEATURES_ECX_PREFETCHWT1 = 1 << 0,
|
||||
CPUID_FEATURES_ECX_AVX512_VBMI = 1 << 1,
|
||||
CPUID_FEATURES_ECX_UMIP = 1 << 2,
|
||||
CPUID_FEATURES_ECX_PKU = 1 << 3,
|
||||
CPUID_FEATURES_ECX_OSPKE = 1 << 4,
|
||||
CPUID_FEATURES_ECX_WAITPKG = 1 << 5,
|
||||
CPUID_FEATURES_ECX_AVX512_VBMI2 = 1 << 6,
|
||||
CPUID_FEATURES_ECX_CET_SS = 1 << 7,
|
||||
CPUID_FEATURES_ECX_GFNI = 1 << 8,
|
||||
CPUID_FEATURES_ECX_VAES = 1 << 9,
|
||||
CPUID_FEATURES_ECX_VPCLMULQDQ = 1 << 10,
|
||||
CPUID_FEATURES_ECX_AVX512_VNNI = 1 << 11,
|
||||
CPUID_FEATURES_ECX_AVX512_BITALG = 1 << 12,
|
||||
CPUID_FEATURES_ECX_TME = 1 << 13,
|
||||
CPUID_FEATURES_ECX_AVX512_VPOPCNTDQ = 1 << 14,
|
||||
CPUID_FEATURES_ECX_LA57 = 1 << 16,
|
||||
CPUID_FEATURES_ECX_RDPID = 1 << 22,
|
||||
CPUID_FEATURES_ECX_KEYLOCKER = 1 << 23,
|
||||
CPUID_FEATURES_ECX_BUS_LOCK_DETECT = 1 << 24,
|
||||
CPUID_FEATURES_ECX_CLDEMOTE = 1 << 25,
|
||||
CPUID_FEATURES_ECX_MOVDIRI = 1 << 27,
|
||||
CPUID_FEATURES_ECX_MOVDIR64B = 1 << 28,
|
||||
CPUID_FEATURES_ECX_ENQCMD = 1 << 29,
|
||||
CPUID_FEATURES_ECX_SGX_LAUNCH_CONFIG = 1 << 30,
|
||||
CPUID_FEATURES_ECX_PKS = 1 << 31,
|
||||
CPUID_FEATURES_EDX_SGX_KEYS = 1 << 1,
|
||||
CPUID_FEATURES_EDX_AVX512_4VNNIW = 1 << 2,
|
||||
CPUID_FEATURES_EDX_AVX512_4FMAPS = 1 << 3,
|
||||
CPUID_FEATURES_EDX_FAST_SHORT_REP_MOV = 1 << 4,
|
||||
CPUID_FEATURES_EDX_UINTR = 1 << 5,
|
||||
CPUID_FEATURES_EDX_AVX512_VPINTERSECT = 1 << 8,
|
||||
CPUID_FEATURES_EDX_SRBDS_CTRL = 1 << 9,
|
||||
CPUID_FEATURES_EDX_MD_CLEAR = 1 << 10,
|
||||
CPUID_FEATURES_EDX_RTM_ALWAYS_ABORT = 1 << 11,
|
||||
CPUID_FEATURES_EDX_RTM_FORCE_ABORT = 1 << 13,
|
||||
CPUID_FEATURES_EDX_SERIALIZE = 1 << 14,
|
||||
CPUID_FEATURES_EDX_HYBRID = 1 << 15,
|
||||
CPUID_FEATURES_EDX_TSXLDTRK = 1 << 16,
|
||||
CPUID_FEATURES_EDX_PCONFIG = 1 << 18,
|
||||
CPUID_FEATURES_EDX_ARCH_LBR = 1 << 19,
|
||||
CPUID_FEATURES_EDX_CET_IBT = 1 << 20,
|
||||
CPUID_FEATURES_EDX_AMX_BF16 = 1 << 22,
|
||||
CPUID_FEATURES_EDX_AVX512_FP16 = 1 << 23,
|
||||
CPUID_FEATURES_EDX_AMX_TILE = 1 << 24,
|
||||
CPUID_FEATURES_EDX_AMX_INT8 = 1 << 25,
|
||||
CPUID_FEATURES_EDX_SCA_IBRS_IBPB = 1 << 26,
|
||||
CPUID_FEATURES_EDX_SCA_STIBP = 1 << 27,
|
||||
CPUID_FEATURES_EDX_L1D_FLUSH = 1 << 28,
|
||||
CPUID_FEATURES_EDX_ARCH_CAPABILITIES_MSR = 1 << 29,
|
||||
CPUID_FEATURES_EDX_CORE_CAPABILITIES_MSR = 1 << 30,
|
||||
CPUID_FEATURES_EDX_SCA_SSBD = 1 << 31
|
||||
} CPUID_FEATURES_STANDARD7_LEAF0, *PCPUID_FEATURES_STANDARD7_LEAF0;
|
||||
|
||||
/* CPUID STD7 features (0x00000007, subleaf 1) enumeration list */
|
||||
typedef enum _CPUID_FEATURES_STANDARD7_LEAF1
|
||||
{
|
||||
CPUID_FEATURES_EAX_SHA512 = 1 << 0,
|
||||
CPUID_FEATURES_EAX_SM3 = 1 << 1,
|
||||
CPUID_FEATURES_EAX_SM4 = 1 << 2,
|
||||
CPUID_FEATURES_EAX_RAO_INT = 1 << 3,
|
||||
CPUID_FEATURES_EAX_AVX_VNNI = 1 << 4,
|
||||
CPUID_FEATURES_EAX_AVX512_BF16 = 1 << 5,
|
||||
CPUID_FEATURES_EAX_LASS = 1 << 6,
|
||||
CPUID_FEATURES_EAX_CMPCCXADD = 1 << 7,
|
||||
CPUID_FEATURES_EAX_ARCH_PERFMON = 1 << 8,
|
||||
CPUID_FEATURES_EAX_FAST_ZEROLEN_REP_MOVSB = 1 << 10,
|
||||
CPUID_FEATURES_EAX_FAST_ZEROLEN_REP_STOSB = 1 << 11,
|
||||
CPUID_FEATURES_EAX_FAST_ZEROLEN_REP_CMPSB = 1 << 12,
|
||||
CPUID_FEATURES_EAX_FRED = 1 << 17,
|
||||
CPUID_FEATURES_EAX_LKGS = 1 << 18,
|
||||
CPUID_FEATURES_EAX_WRMSRNS = 1 << 19,
|
||||
CPUID_FEATURES_EAX_NMI_SOURCE_REPORTING = 1 << 20,
|
||||
CPUID_FEATURES_EAX_AMX_FP16 = 1 << 21,
|
||||
CPUID_FEATURES_EAX_HRESET = 1 << 22,
|
||||
CPUID_FEATURES_EAX_AVX_IFMA = 1 << 23,
|
||||
CPUID_FEATURES_EAX_LAM = 1 << 26,
|
||||
CPUID_FEATURES_EAX_MSRLIST = 1 << 27,
|
||||
CPUID_FEATURES_EAX_INVD_DISABLE = 1 << 30,
|
||||
CPUID_FEATURES_EAX_MOVRS = 1 << 31,
|
||||
CPUID_FEATURES_EBX_PPIN = 1 << 0,
|
||||
CPUID_FEATURES_EBX_TSE = 1 << 1,
|
||||
CPUID_FEATURES_EBX_CPUIDMAXVAL_LIM_RMV = 1 << 3,
|
||||
CPUID_FEATURES_ECX_MSR_IMM = 1 << 5,
|
||||
CPUID_FEATURES_EDX_AVX_VNNI_INT8 = 1 << 4,
|
||||
CPUID_FEATURES_EDX_AVX_NE_CONVERT = 1 << 5,
|
||||
CPUID_FEATURES_EDX_AMX_COMPLEX = 1 << 8,
|
||||
CPUID_FEATURES_EDX_AVX_VNNI_INT16 = 1 << 10,
|
||||
CPUID_FEATURES_EDX_USER_TIMER = 1 << 13,
|
||||
CPUID_FEATURES_EDX_PREFETCHI = 1 << 14,
|
||||
CPUID_FEATURES_EDX_USER_MSR = 1 << 15,
|
||||
CPUID_FEATURES_EDX_UIRET_UIF = 1 << 17,
|
||||
CPUID_FEATURES_EDX_CET_SSS = 1 << 18,
|
||||
CPUID_FEATURES_EDX_AVX10 = 1 << 19,
|
||||
CPUID_FEATURES_EDX_APX = 1 << 21,
|
||||
CPUID_FEATURES_EDX_MWAIT_AND_LEAF5 = 1 << 23
|
||||
} CPUID_FEATURES_STANDARD7_LEAF1, *PCPUID_FEATURES_STANDARD7_LEAF1;
|
||||
|
||||
/* CPUID requests */
|
||||
typedef enum _CPUID_REQUESTS
|
||||
{
|
||||
CPUID_GET_VENDOR_STRING,
|
||||
CPUID_GET_CPU_FEATURES,
|
||||
CPUID_GET_TLB,
|
||||
CPUID_GET_SERIAL
|
||||
CPUID_GET_VENDOR_STRING = 0x00000000,
|
||||
CPUID_GET_STANDARD1_FEATURES = 0x00000001,
|
||||
CPUID_GET_TLB_CACHE = 0x00000002,
|
||||
CPUID_GET_SERIAL = 0x00000003,
|
||||
CPUID_GET_CACHE_TOPOLOGY = 0x00000004,
|
||||
CPUID_GET_MONITOR_MWAIT = 0x00000005,
|
||||
CPUID_GET_POWER_MANAGEMENT = 0x00000006,
|
||||
CPUID_GET_STANDARD7_FEATURES = 0x00000007,
|
||||
CPUID_GET_TSC_CRYSTAL_CLOCK = 0x00000015,
|
||||
CPUID_GET_EXTENDED_MAX = 0x80000000,
|
||||
CPUID_GET_EXTENDED_FEATURES = 0x80000001,
|
||||
CPUID_GET_ADVANCED_POWER_MANAGEMENT = 0x80000007
|
||||
} CPUID_REQUESTS, *PCPUID_REQUESTS;
|
||||
|
||||
/* Interrupt handler */
|
||||
typedef VOID (*PINTERRUPT_HANDLER)(PKTRAP_FRAME TrapFrame);
|
||||
|
||||
/* Processor identification information */
|
||||
typedef struct _CPU_IDENTIFICATION
|
||||
{
|
||||
ULONGLONG ExtendedFeatureBits;
|
||||
USHORT Family;
|
||||
ULONGLONG FeatureBits;
|
||||
USHORT Model;
|
||||
USHORT Stepping;
|
||||
CPU_VENDOR Vendor;
|
||||
@@ -227,4 +462,12 @@ typedef struct _CPUID_SIGNATURE
|
||||
ULONG Unused2:4;
|
||||
} CPU_SIGNATURE, *PCPU_SIGNATURE;
|
||||
|
||||
/* Trampoline types */
|
||||
typedef enum _TRAMPOLINE_TYPE
|
||||
{
|
||||
TrampolineApStartup,
|
||||
TrampolineEnableXpa
|
||||
} TRAMPOLINE_TYPE, *PTRAMPOLINE_TYPE;
|
||||
|
||||
#endif /* __XTOS_ASSEMBLER__ */
|
||||
#endif /* __XTDK_AMD64_ARTYPES_H */
|
||||
|
||||
@@ -15,32 +15,42 @@
|
||||
#include <amd64/xtstruct.h>
|
||||
|
||||
|
||||
/* HAL library routines forward references */
|
||||
/* C/C++ specific code */
|
||||
#ifndef __XTOS_ASSEMBLER__
|
||||
|
||||
/* Hardware layer routines forward references */
|
||||
XTCLINK
|
||||
XTCDECL
|
||||
UCHAR
|
||||
HlIoPortInByte(IN USHORT Port);
|
||||
|
||||
XTCDECL
|
||||
ULONG
|
||||
HlIoPortInLong(IN USHORT Port);
|
||||
HlReadPort8(IN USHORT Port);
|
||||
|
||||
XTCLINK
|
||||
XTCDECL
|
||||
USHORT
|
||||
HlIoPortInShort(IN USHORT Port);
|
||||
HlReadPort16(IN USHORT Port);
|
||||
|
||||
XTCLINK
|
||||
XTCDECL
|
||||
ULONG
|
||||
HlReadPort32(IN USHORT Port);
|
||||
|
||||
XTCLINK
|
||||
XTCDECL
|
||||
VOID
|
||||
HlIoPortOutByte(IN USHORT Port,
|
||||
IN UCHAR Data);
|
||||
HlWritePort8(IN USHORT Port,
|
||||
IN UCHAR Data);
|
||||
|
||||
XTCLINK
|
||||
XTCDECL
|
||||
VOID
|
||||
HlIoPortOutLong(IN USHORT Port,
|
||||
IN ULONG Value);
|
||||
HlWritePort16(IN USHORT Port,
|
||||
IN USHORT Value);
|
||||
|
||||
XTCLINK
|
||||
XTCDECL
|
||||
VOID
|
||||
HlIoPortOutShort(IN USHORT Port,
|
||||
IN USHORT Value);
|
||||
HlWritePort32(IN USHORT Port,
|
||||
IN ULONG Value);
|
||||
|
||||
#endif /* __XTOS_ASSEMBLER__ */
|
||||
#endif /* __XTDK_AMD64_HLFUNCS_H */
|
||||
|
||||
+420
-23
@@ -9,6 +9,7 @@
|
||||
#ifndef __XTDK_AMD64_HLTYPES_H
|
||||
#define __XTDK_AMD64_HLTYPES_H
|
||||
|
||||
#include <xtbase.h>
|
||||
#include <xtdefs.h>
|
||||
#include <xtstruct.h>
|
||||
#include <xttypes.h>
|
||||
@@ -38,41 +39,288 @@
|
||||
#define APIC_VECTOR_PERF 0xFE
|
||||
#define APIC_VECTOR_NMI 0xFF
|
||||
|
||||
/* APIC SIPI vector shift */
|
||||
#define APIC_VECTOR_SIPI_SHIFT 12
|
||||
|
||||
/* APIC destination formats */
|
||||
#define APIC_DF_FLAT 0xFFFFFFFF
|
||||
#define APIC_DF_CLUSTER 0x0FFFFFFF
|
||||
|
||||
/* APIC delivery modes */
|
||||
#define APIC_DM_FIXED 0
|
||||
#define APIC_DM_LOWPRIO 1
|
||||
#define APIC_DM_SMI 2
|
||||
#define APIC_DM_REMOTE 3
|
||||
#define APIC_DM_NMI 4
|
||||
#define APIC_DM_INIT 5
|
||||
#define APIC_DM_STARTUP 6
|
||||
#define APIC_DM_EXTINT 7
|
||||
|
||||
/* APIC trigger modes */
|
||||
#define APIC_TGM_EDGE 0
|
||||
#define APIC_TGM_LEVEL 1
|
||||
|
||||
/* APIC LDR (Logical Destination Register) shifts */
|
||||
#define APIC_X2APIC_LDR_SHIFT 16
|
||||
#define APIC_XAPIC_LDR_SHIFT 24
|
||||
|
||||
/* Maximum number of I/O APICs */
|
||||
#define APIC_MAX_IOAPICS 64
|
||||
|
||||
/* I/O APIC base address */
|
||||
#define IOAPIC_DEFAULT_BASE 0xFEC00000
|
||||
|
||||
/* I/O APIC definitions */
|
||||
#define IOAPIC_MAX_CONTROLLERS 128
|
||||
#define IOAPIC_MAX_OVERRIDES 16
|
||||
#define IOAPIC_RTE_MASKED 0x100FF
|
||||
#define IOAPIC_RTE_SIZE 2
|
||||
#define IOAPIC_VECTOR_FREE 0xFF
|
||||
#define IOAPIC_VECTOR_RESERVED 0xFE
|
||||
|
||||
/* IOAPIC offsets */
|
||||
#define IOAPIC_IOREGSEL 0x00
|
||||
#define IOAPIC_IOWIN 0x10
|
||||
|
||||
/* IOAPIC registers */
|
||||
#define IOAPIC_ID 0x00
|
||||
#define IOAPIC_VER 0x01
|
||||
#define IOAPIC_ARB 0x02
|
||||
#define IOAPIC_REDTBL 0x10
|
||||
|
||||
/* 8259/ISP PIC ports definitions */
|
||||
#define PIC1_CONTROL_PORT 0x20
|
||||
#define PIC1_DATA_PORT 0x21
|
||||
#define PIC1_ELCR_PORT 0x04D0
|
||||
#define PIC2_CONTROL_PORT 0xA0
|
||||
#define PIC2_DATA_PORT 0xA1
|
||||
#define PIC2_ELCR_PORT 0x04D1
|
||||
|
||||
/* PIC vector definitions */
|
||||
#define PIC1_VECTOR_SPURIOUS 0x37
|
||||
|
||||
/* Serial port I/O addresses */
|
||||
#define COMPORT_ADDRESSES {0x000, 0x3F8, 0x2F8, 0x3E8, 0x2E8, 0x5F8, 0x4F8, 0x5E8, 0x4E8}
|
||||
/* HPET General Capabilities definitions */
|
||||
#define HPET_CAPABILITY_64BIT 0x2000ULL
|
||||
#define HPET_CAPABILITY_LEGACY_REPLACEMENT 0x8000ULL
|
||||
|
||||
/* HPET General Configuration definitions */
|
||||
#define HPET_CONFIG_ENABLE 0x0001ULL
|
||||
#define HPET_CONFIG_LEGACY_REPLACEMENT 0x0002ULL
|
||||
|
||||
/* HPET Timer Configuration definitions */
|
||||
#define HPET_TIMER_CONFIG_LEVEL_TRIGGERED 0x0002ULL
|
||||
#define HPET_TIMER_CONFIG_ENABLED 0x0004ULL
|
||||
#define HPET_TIMER_CONFIG_PERIODIC 0x0008ULL
|
||||
#define HPET_TIMER_CONFIG_SUPPORTS_PERIODIC 0x0010ULL
|
||||
#define HPET_TIMER_CONFIG_SUPPORTS_64BIT 0x0020ULL
|
||||
#define HPET_TIMER_CONFIG_VALUE_ACCUMULATOR 0x0040ULL
|
||||
#define HPET_TIMER_CONFIG_FORCE_32BIT 0x0100ULL
|
||||
#define HPET_TIMER_CONFIG_FSB_ENABLED 0x4000ULL
|
||||
#define HPET_TIMER_CONFIG_SUPPORTS_FSB 0x8000ULL
|
||||
|
||||
/* PIT ports definitions */
|
||||
#define PIT_COMMAND_PORT 0x43
|
||||
#define PIT_DATA_PORT0 0x40
|
||||
#define PIT_DATA_PORT1 0x41
|
||||
#define PIT_DATA_PORT2 0x42
|
||||
|
||||
/* PIT related definitions */
|
||||
#define PIT_BASE_FREQUENCY 1193182
|
||||
|
||||
/* PIT Access Mode: Defines how the CPU reads or writes the counter value */
|
||||
#define PIT_CMD_ACCESS_LATCH 0x00
|
||||
#define PIT_CMD_ACCESS_LOWBYTE_ONLY 0x10
|
||||
#define PIT_CMD_ACCESS_HIGHBYTE_ONLY 0x20
|
||||
#define PIT_CMD_ACCESS_LOWBYTE_HIGHBYTE 0x30
|
||||
|
||||
/* PIT Channel Selection: Specifies the physical timer channel to configure */
|
||||
#define PIT_CMD_CHANNEL0 0x00
|
||||
#define PIT_CMD_CHANNEL1 0x40
|
||||
#define PIT_CMD_CHANNEL2 0x80
|
||||
|
||||
/* PIT Operating Mode: Defines the hardware behavior and the generated waveform */
|
||||
#define PIT_MODE0_INT_ON_TERMINAL_COUNT 0x00
|
||||
#define PIT_MODE1_ONESHOT 0x02
|
||||
#define PIT_MODE2_RATE_GENERATOR 0x04
|
||||
#define PIT_MODE3_SQUARE_WAVE_GEN 0x06
|
||||
#define PIT_MODE4_SOFTWARE_STROBE 0x08
|
||||
#define PIT_MODE5_HARDWARE_STROBE 0x0A
|
||||
|
||||
/* CMOS controller access ports */
|
||||
#define CMOS_SELECT_PORT 0x70
|
||||
#define CMOS_DATA_PORT 0x71
|
||||
|
||||
/* CMOD Select port definitions */
|
||||
#define CMOS_NMI_SELECT 0x80
|
||||
#define CMOS_REGISTER_SECOND 0x00
|
||||
#define CMOS_REGISTER_MINUTE 0x02
|
||||
#define CMOS_REGISTER_HOUR 0x04
|
||||
#define CMOS_REGISTER_WEEKDAY 0x06
|
||||
#define CMOS_REGISTER_DAY 0x07
|
||||
#define CMOS_REGISTER_MONTH 0x08
|
||||
#define CMOS_REGISTER_YEAR 0x09
|
||||
#define CMOS_REGISTER_A 0x0A
|
||||
#define CMOS_REGISTER_B 0x0B
|
||||
#define CMOS_REGISTER_C 0x0C
|
||||
|
||||
/* CMOS Register A definitions */
|
||||
#define CMOS_REGISTER_A_RATE_MASK 0x0F
|
||||
#define CMOS_REGISTER_A_UPDATE_IN_PROGRESS 0x80
|
||||
|
||||
/* CMOS Register B definitions */
|
||||
#define CMOS_REGISTER_B_24_HOUR 0x02
|
||||
#define CMOS_REGISTER_B_BINARY 0x04
|
||||
#define CMOS_REGISTER_B_PERIODIC 0x40
|
||||
#define CMOS_REGISTER_B_SET_CLOCK 0x80
|
||||
|
||||
/* CMOS Register C definitions */
|
||||
#define CMOS_REGISTER_C_PERIODIC 0x40
|
||||
#define CMOS_REGISTER_C_INTERRUPT 0x80
|
||||
|
||||
/* CMOS RTC 24-hour mode */
|
||||
#define CMOS_RTC_POST_MERIDIEM 0x80
|
||||
|
||||
/* Serial ports information */
|
||||
#define COMPORT_ADDRESS {0x3F8, 0x2F8, 0x3E8, 0x2E8, 0x5F8, 0x4F8, 0x5E8, 0x4E8}
|
||||
#define COMPORT_COUNT 8
|
||||
|
||||
/* Initial stall factor */
|
||||
#define INITIAL_STALL_FACTOR 100
|
||||
|
||||
|
||||
/* C/C++ specific code */
|
||||
#ifndef __XTOS_ASSEMBLER__
|
||||
|
||||
/* APIC destination mode enumeration list */
|
||||
typedef enum _APIC_DEST_MODE
|
||||
{
|
||||
APIC_DM_Physical,
|
||||
APIC_DM_Logical
|
||||
} APIC_DEST_MODE, *PAPIC_DEST_MODE;
|
||||
|
||||
/* APIC delivery mode enumeration list */
|
||||
typedef enum _APIC_DM
|
||||
{
|
||||
APIC_DM_FIXED,
|
||||
APIC_DM_LOWPRIO,
|
||||
APIC_DM_SMI,
|
||||
APIC_DM_REMOTE,
|
||||
APIC_DM_NMI,
|
||||
APIC_DM_INIT,
|
||||
APIC_DM_STARTUP,
|
||||
APIC_DM_EXTINT,
|
||||
} APIC_DM, *PAPIC_DM;
|
||||
|
||||
/* APIC destination short-hand enumeration list */
|
||||
typedef enum _APIC_DSH
|
||||
{
|
||||
APIC_DSH_Destination,
|
||||
APIC_DSH_Self,
|
||||
APIC_DSH_AllIncludingSelf,
|
||||
APIC_DSH_AllExclusingSelf
|
||||
} APIC_DSH, *PAPIC_DSH;
|
||||
|
||||
/* APIC mode list */
|
||||
typedef enum _APIC_MODE
|
||||
{
|
||||
APIC_MODE_COMPAT,
|
||||
APIC_MODE_X2APIC
|
||||
} APIC_MODE, *PAPIC_MODE;
|
||||
|
||||
/* APIC Register Address Map */
|
||||
typedef enum _APIC_REGISTER
|
||||
{
|
||||
APIC_ID = 0x02, /* APIC ID Register */
|
||||
APIC_VER = 0x03, /* APIC Version Register */
|
||||
APIC_TPR = 0x08, /* Task Priority Register */
|
||||
APIC_APR = 0x09, /* Arbitration Priority Register */
|
||||
APIC_PPR = 0x0A, /* Processor Priority Register (R) */
|
||||
APIC_EOI = 0x0B, /* EOI Register */
|
||||
APIC_RRR = 0x0C, /* Remote Read Register */
|
||||
APIC_LDR = 0x0D, /* Logical Destination Register */
|
||||
APIC_DFR = 0x0E, /* Destination Format Register (not available in extended mode) */
|
||||
APIC_SIVR = 0x0F, /* Spurious Interrupt Vector Register */
|
||||
APIC_ISR = 0x10, /* Interrupt Service Register*/
|
||||
APIC_TMR = 0x18, /* Trigger Mode Register */
|
||||
APIC_IRR = 0x20, /* Interrupt Request Register */
|
||||
APIC_ESR = 0x28, /* Error Status Register */
|
||||
APIC_ICR0 = 0x30, /* Interrupt Command Register */
|
||||
APIC_ICR1 = 0x31, /* Interrupt Command Register (not available in extended mode) */
|
||||
APIC_TMRLVTR = 0x32, /* Timer Local Vector Table */
|
||||
APIC_THRMLVTR = 0x33, /* Thermal Local Vector Table */
|
||||
APIC_PCLVTR = 0x34, /* Performance Counter Local Vector Table */
|
||||
APIC_LINT0 = 0x35, /* LINT0 Local Vector Table */
|
||||
APIC_LINT1 = 0x36, /* LINT1 Local Vector Table */
|
||||
APIC_ERRLVTR = 0x37, /* Error Local Vector Table */
|
||||
APIC_TICR = 0x38, /* Initial Count Register for Timer */
|
||||
APIC_TCCR = 0x39, /* Current Count Register for Timer */
|
||||
APIC_TDCR = 0x3E, /* Timer Divide Configuration Register */
|
||||
APIC_SIPI = 0x3F, /* Self-IPI Register */
|
||||
APIC_EAFR = 0x40, /* extended APIC Feature register */
|
||||
APIC_EACR = 0x41, /* Extended APIC Control Register */
|
||||
APIC_SEOI = 0x42, /* Specific End Of Interrupt Register */
|
||||
APIC_EXT0LVTR = 0x50, /* Extended Interrupt 0 Local Vector Table */
|
||||
APIC_EXT1LVTR = 0x51, /* Extended Interrupt 1 Local Vector Table */
|
||||
APIC_EXT2LVTR = 0x52, /* Extended Interrupt 2 Local Vector Table */
|
||||
APIC_EXT3LVTR = 0x53 /* Extended Interrupt 3 Local Vector Table */
|
||||
} APIC_REGISTER, *PAPIC_REGISTER;
|
||||
|
||||
/* APIC Timer Divide enumeration list */
|
||||
typedef enum _APIC_TIMER_DIVISOR
|
||||
{
|
||||
TIMER_DivideBy2 = 0,
|
||||
TIMER_DivideBy4 = 1,
|
||||
TIMER_DivideBy8 = 2,
|
||||
TIMER_DivideBy16 = 3,
|
||||
TIMER_DivideBy32 = 8,
|
||||
TIMER_DivideBy64 = 9,
|
||||
TIMER_DivideBy128 = 10,
|
||||
TIMER_DivideBy1 = 11,
|
||||
} APIC_TIMER_DIVISOR, *PAPIC_TIMER_DIVISOR;
|
||||
|
||||
/* I8259 PIC interrupt mode enumeration list */
|
||||
typedef enum _PIC_I8259_ICW1_INTERRUPT_MODE
|
||||
{
|
||||
EdgeTriggered,
|
||||
LevelTriggered
|
||||
} PIC_I8259_ICW1_INTERRUPT_MODE, *PPIC_I8259_ICW1_INTERRUPT_MODE;
|
||||
|
||||
/* I8259 PIC interval enumeration list */
|
||||
typedef enum _PIC_I8259_ICW1_INTERVAL
|
||||
{
|
||||
Interval8,
|
||||
Interval4
|
||||
} PIC_I8259_ICW1_INTERVAL, *PPIC_I8259_ICW1_INTERVAL;
|
||||
|
||||
/* I8259 PIC operating mode enumeration list */
|
||||
typedef enum _PIC_I8259_ICW1_OPERATING_MODE
|
||||
{
|
||||
Cascade,
|
||||
Single
|
||||
} PIC_I8259_ICW1_OPERATING_MODE, *PPIC_I8259_ICW1_OPERATING_MODE;
|
||||
|
||||
/* I8259 PIC buffered mode enumeration list */
|
||||
typedef enum _PIC_I8259_ICW4_BUFFERED_MODE
|
||||
{
|
||||
NonBuffered,
|
||||
NonBuffered2,
|
||||
BufferedSlave,
|
||||
BufferedMaster
|
||||
} PIC_I8259_ICW4_BUFFERED_MODE, *PPIC_I8259_ICW4_BUFFERED_MODE;
|
||||
|
||||
/* I8259 PIC End Of Interrupt (EOI) mode enumeration list */
|
||||
typedef enum _PIC_I8259_ICW4_EOI_MODE
|
||||
{
|
||||
NormalEoi,
|
||||
AutomaticEoi
|
||||
} PIC_I8259_ICW4_EOI_MODE, *PPIC_I8259_ICW4_EOI_MODE;
|
||||
|
||||
/* I8259 PIC system mode enumeration list */
|
||||
typedef enum _PIC_I8259_ICW4_SYSTEM_MODE
|
||||
{
|
||||
Mcs8085Mode,
|
||||
New8086Mode
|
||||
} PIC_I8259_ICW4_SYSTEM_MODE, *PPIC_I8259_ICW4_SYSTEM_MODE;
|
||||
|
||||
/* Supported hardware timer backends */
|
||||
typedef enum _TIMER_TYPE
|
||||
{
|
||||
TimerNone,
|
||||
TimerAcpiPm,
|
||||
TimerHpet,
|
||||
TimerLapic,
|
||||
TimerPit,
|
||||
TimerTsc
|
||||
} TIMER_TYPE, *PTIMER_TYPE;
|
||||
|
||||
/* APIC Base Register */
|
||||
typedef union _APIC_BASE_REGISTER
|
||||
{
|
||||
@@ -89,6 +337,31 @@ typedef union _APIC_BASE_REGISTER
|
||||
};
|
||||
} APIC_BASE_REGISTER, *PAPIC_BASE_REGISTER;
|
||||
|
||||
/* APIC Command Register */
|
||||
typedef union _APIC_COMMAND_REGISTER
|
||||
{
|
||||
ULONGLONG LongLong;
|
||||
struct
|
||||
{
|
||||
ULONG Long0;
|
||||
ULONG Long1;
|
||||
};
|
||||
struct
|
||||
{
|
||||
ULONGLONG Vector:8;
|
||||
ULONGLONG DeliveryMode:3;
|
||||
ULONGLONG DestinationMode:1;
|
||||
ULONGLONG DeliveryStatus:1;
|
||||
ULONGLONG ReservedMBZ:1;
|
||||
ULONGLONG Level:1;
|
||||
ULONGLONG TriggerMode:1;
|
||||
ULONGLONG RemoteReadStatus:2;
|
||||
ULONGLONG DestinationShortHand:2;
|
||||
ULONGLONG Reserved2MBZ:36;
|
||||
ULONGLONG Destination:8;
|
||||
};
|
||||
} APIC_COMMAND_REGISTER, *PAPIC_COMMAND_REGISTER;
|
||||
|
||||
/* APIC Local Vector Table (LVT) Register */
|
||||
typedef union _APIC_LVT_REGISTER
|
||||
{
|
||||
@@ -96,7 +369,7 @@ typedef union _APIC_LVT_REGISTER
|
||||
struct
|
||||
{
|
||||
ULONG Vector:8;
|
||||
ULONG MessageType:3;
|
||||
ULONG DeliveryMode:3;
|
||||
ULONG Reserved1:1;
|
||||
ULONG DeliveryStatus:1;
|
||||
ULONG Reserved2:1;
|
||||
@@ -121,14 +394,138 @@ typedef union _APIC_SPURIOUS_REGISTER
|
||||
};
|
||||
} APIC_SPURIOUS_REGISTER, *PAPIC_SPURIOUS_REGISTER;
|
||||
|
||||
/* Processor identity structure */
|
||||
typedef struct _HAL_PROCESSOR_IDENTITY
|
||||
/* I/O APIC Controller information */
|
||||
typedef struct _IOAPIC_DATA
|
||||
{
|
||||
UCHAR ProcessorId;
|
||||
UCHAR LApicId;
|
||||
BOOLEAN Bsp;
|
||||
BOOLEAN Started;
|
||||
PKPROCESSOR_BLOCK ProcessorBlock;
|
||||
} HAL_PROCESSOR_IDENTITY, *PHAL_PROCESSOR_IDENTITY;
|
||||
ULONG GsiBase;
|
||||
ULONG Identifier;
|
||||
ULONG LineCount;
|
||||
PHYSICAL_ADDRESS PhysicalAddress;
|
||||
ULONG_PTR VirtualAddress;
|
||||
} IOAPIC_DATA, *PIOAPIC_DATA;
|
||||
|
||||
/* I/O APIC Redirection Register */
|
||||
typedef union _IOAPIC_REDIRECTION_REGISTER
|
||||
{
|
||||
ULONGLONG LongLong;
|
||||
struct
|
||||
{
|
||||
UINT Base;
|
||||
UINT Extended;
|
||||
};
|
||||
struct
|
||||
{
|
||||
ULONGLONG Vector:8;
|
||||
ULONGLONG DeliveryMode:3;
|
||||
ULONGLONG DestinationMode:1;
|
||||
ULONGLONG DeliveryStatus:1;
|
||||
ULONGLONG PinPolarity:1;
|
||||
ULONGLONG RemoteIRR:1;
|
||||
ULONGLONG TriggerMode:1;
|
||||
ULONGLONG Mask:1;
|
||||
ULONGLONG Reserved:39;
|
||||
ULONGLONG Destination:8;
|
||||
};
|
||||
} IOAPIC_REDIRECTION_REGISTER, *PIOAPIC_REDIRECTION_REGISTER;
|
||||
|
||||
/* I8259 PIC register structure */
|
||||
typedef union _PIC_I8259_ICW1
|
||||
{
|
||||
struct
|
||||
{
|
||||
UCHAR NeedIcw4:1;
|
||||
UCHAR OperatingMode:1;
|
||||
UCHAR Interval:1;
|
||||
UCHAR InterruptMode:1;
|
||||
UCHAR Init:1;
|
||||
UCHAR InterruptVectorAddress:3;
|
||||
};
|
||||
UCHAR Bits;
|
||||
} PIC_I8259_ICW1, *PPIC_I8259_ICW1;
|
||||
|
||||
/* I8259 PIC register structure */
|
||||
typedef union _PIC_I8259_ICW2
|
||||
{
|
||||
struct
|
||||
{
|
||||
UCHAR Sbz:3;
|
||||
UCHAR InterruptVector:5;
|
||||
};
|
||||
UCHAR Bits;
|
||||
} PIC_I8259_ICW2, *PPIC_I8259_ICW2;
|
||||
|
||||
/* I8259 PIC register structure */
|
||||
typedef union _PIC_I8259_ICW3
|
||||
{
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
UCHAR SlaveIrq0:1;
|
||||
UCHAR SlaveIrq1:1;
|
||||
UCHAR SlaveIrq2:1;
|
||||
UCHAR SlaveIrq3:1;
|
||||
UCHAR SlaveIrq4:1;
|
||||
UCHAR SlaveIrq5:1;
|
||||
UCHAR SlaveIrq6:1;
|
||||
UCHAR SlaveIrq7:1;
|
||||
};
|
||||
struct
|
||||
{
|
||||
UCHAR SlaveId:3;
|
||||
UCHAR Reserved:5;
|
||||
};
|
||||
};
|
||||
UCHAR Bits;
|
||||
} PIC_I8259_ICW3, *PPIC_I8259_ICW3;
|
||||
|
||||
/* I8259 PIC register structure */
|
||||
typedef union _PIC_I8259_ICW4
|
||||
{
|
||||
struct
|
||||
{
|
||||
UCHAR SystemMode:1;
|
||||
UCHAR EoiMode:1;
|
||||
UCHAR BufferedMode:2;
|
||||
UCHAR SpecialFullyNestedMode:1;
|
||||
UCHAR Reserved:3;
|
||||
};
|
||||
UCHAR Bits;
|
||||
} PIC_I8259_ICW4, *PPIC_I8259_ICW4;
|
||||
|
||||
/* HPET Registers structure definition */
|
||||
typedef struct _HPET_REGISTERS
|
||||
{
|
||||
VOLATILE ULONGLONG GeneralCapabilities;
|
||||
VOLATILE ULONGLONG Reserved0;
|
||||
VOLATILE ULONGLONG GeneralConfiguration;
|
||||
VOLATILE ULONGLONG Reserved1;
|
||||
VOLATILE ULONGLONG GeneralInterruptStatus;
|
||||
VOLATILE ULONGLONG Reserved2;
|
||||
VOLATILE ULONGLONG Reserved3[2][12];
|
||||
VOLATILE ULONGLONG MainCounterValue;
|
||||
VOLATILE ULONGLONG Reserved4;
|
||||
struct
|
||||
{
|
||||
VOLATILE ULONGLONG Configuration;
|
||||
VOLATILE ULONGLONG Comparator;
|
||||
VOLATILE ULONGLONG FsbInterruptRoute;
|
||||
VOLATILE ULONGLONG Reserved;
|
||||
} Timers[];
|
||||
} HPET_REGISTERS, *PHPET_REGISTERS;
|
||||
|
||||
/* Hardware timer capabilities and CPU clock features */
|
||||
typedef struct _TIMER_CAPABILITIES
|
||||
{
|
||||
BOOLEAN Arat;
|
||||
BOOLEAN Art;
|
||||
BOOLEAN InvariantTsc;
|
||||
BOOLEAN RDTSCP;
|
||||
ULONG TimerFrequency;
|
||||
BOOLEAN TscDeadline;
|
||||
ULONG TscDenominator;
|
||||
ULONG TscNumerator;
|
||||
} TIMER_CAPABILITIES, *PTIMER_CAPABILITIES;
|
||||
|
||||
#endif /* __XTOS_ASSEMBLER__ */
|
||||
#endif /* __XTDK_AMD64_HLTYPES_H */
|
||||
|
||||
+213
-94
@@ -12,114 +12,160 @@
|
||||
#include <xtbase.h>
|
||||
#include <xtstruct.h>
|
||||
#include <xttypes.h>
|
||||
#include <extypes.h>
|
||||
#include <potypes.h>
|
||||
#include ARCH_HEADER(xtstruct.h)
|
||||
#include ARCH_HEADER(artypes.h)
|
||||
|
||||
|
||||
/* Selector masks */
|
||||
#define MODE_MASK 0x0001
|
||||
#define RPL_MASK 0x0003
|
||||
#define MODE_MASK 0x0001
|
||||
#define RPL_MASK 0x0003
|
||||
|
||||
/* GDT selector names */
|
||||
#define KGDT_NULL 0x0000
|
||||
#define KGDT_R0_CODE 0x0010
|
||||
#define KGDT_R0_DATA 0x0018
|
||||
#define KGDT_R3_CMCODE 0x0020
|
||||
#define KGDT_R3_DATA 0x0028
|
||||
#define KGDT_R3_CODE 0x0030
|
||||
#define KGDT_SYS_TSS 0x0040
|
||||
#define KGDT_R3_CMTEB 0x0050
|
||||
#define KGDT_R0_LDT 0x0060
|
||||
#define KGDT_ALIAS 0x0070
|
||||
#define KGDT_NULL 0x0000
|
||||
#define KGDT_R0_CMCODE 0x0008
|
||||
#define KGDT_R0_CODE 0x0010
|
||||
#define KGDT_R0_DATA 0x0018
|
||||
#define KGDT_R3_CMCODE 0x0020
|
||||
#define KGDT_R3_DATA 0x0028
|
||||
#define KGDT_R3_CODE 0x0030
|
||||
#define KGDT_SYS_TSS 0x0040
|
||||
#define KGDT_R3_CMTEB 0x0050
|
||||
#define KGDT_R0_LDT 0x0060
|
||||
#define KGDT_ALIAS 0x0070
|
||||
|
||||
/* GDT descriptor privilege levels */
|
||||
#define KGDT_DPL_SYSTEM 0
|
||||
#define KGDT_DPL_USER 3
|
||||
#define KGDT_DPL_SYSTEM 0
|
||||
#define KGDT_DPL_USER 3
|
||||
|
||||
/* GDT descriptor properties */
|
||||
#define KGDT_DESCRIPTOR_ACCESSED 0x01
|
||||
#define KGDT_DESCRIPTOR_READ_WRITE 0x02
|
||||
#define KGDT_DESCRIPTOR_EXECUTE_READ 0x02
|
||||
#define KGDT_DESCRIPTOR_EXPAND_DOWN 0x04
|
||||
#define KGDT_DESCRIPTOR_CONFORMING 0x04
|
||||
#define KGDT_DESCRIPTOR_CODE 0x08
|
||||
#define KGDT_DESCRIPTOR_ACCESSED 0x01
|
||||
#define KGDT_DESCRIPTOR_READ_WRITE 0x02
|
||||
#define KGDT_DESCRIPTOR_EXECUTE_READ 0x02
|
||||
#define KGDT_DESCRIPTOR_EXPAND_DOWN 0x04
|
||||
#define KGDT_DESCRIPTOR_CONFORMING 0x04
|
||||
#define KGDT_DESCRIPTOR_CODE 0x08
|
||||
|
||||
/* GDT descriptor type codes */
|
||||
#define KGDT_TYPE_NONE 0x0
|
||||
#define KGDT_TYPE_CODE (0x10 | KGDT_DESCRIPTOR_CODE | KGDT_DESCRIPTOR_EXECUTE_READ)
|
||||
#define KGDT_TYPE_DATA (0x10 | KGDT_DESCRIPTOR_READ_WRITE)
|
||||
#define KGDT_TYPE_NONE 0x00
|
||||
#define KGDT_TYPE_CODE (0x10 | KGDT_DESCRIPTOR_CODE | KGDT_DESCRIPTOR_EXECUTE_READ)
|
||||
#define KGDT_TYPE_DATA (0x10 | KGDT_DESCRIPTOR_READ_WRITE)
|
||||
|
||||
/* IDT access levels */
|
||||
#define KIDT_ACCESS_RING0 0x0
|
||||
#define KIDT_ACCESS_RING3 0x3
|
||||
#define KIDT_ACCESS_RING0 0x0
|
||||
#define KIDT_ACCESS_RING3 0x3
|
||||
|
||||
/* IDT Interrupt Stack Table entries */
|
||||
#define KIDT_IST_RESERVED 0
|
||||
#define KIDT_IST_PANIC 1
|
||||
#define KIDT_IST_MCA 2
|
||||
#define KIDT_IST_RESERVED 0
|
||||
#define KIDT_IST_PANIC 1
|
||||
#define KIDT_IST_MCA 2
|
||||
#define KIDT_IST_NMI 3
|
||||
|
||||
/* AMD64 Segment Types */
|
||||
#define AMD64_TASK_GATE 0x5
|
||||
#define AMD64_TSS 0x9
|
||||
#define AMD64_ACTIVE_TSS 0xB
|
||||
#define AMD64_CALL_GATE 0xC
|
||||
#define AMD64_INTERRUPT_GATE 0xE
|
||||
#define AMD64_TRAP_GATE 0xF
|
||||
#define AMD64_TASK_GATE 0x5
|
||||
#define AMD64_TSS 0x9
|
||||
#define AMD64_ACTIVE_TSS 0xB
|
||||
#define AMD64_CALL_GATE 0xC
|
||||
#define AMD64_INTERRUPT_GATE 0xE
|
||||
#define AMD64_TRAP_GATE 0xF
|
||||
|
||||
/* EFLAGS bits definitions */
|
||||
#define EFLAGS_NF_MASK 0x00000000L /* None */
|
||||
#define EFLAGS_CF_MASK 0x00000001L /* Carry */
|
||||
#define EFLAGS_PF_MASK 0x00000004L /* Parity */
|
||||
#define EFLAGS_AF_MASK 0x00000010L /* Aux Carry */
|
||||
#define EFLAGS_ZF_MASK 0x00000040L /* Zero */
|
||||
#define EFLAGS_SF_MASK 0x00000080L /* Sign */
|
||||
#define EFLAGS_TF 0x00000100L /* Trap */
|
||||
#define EFLAGS_INTERRUPT_MASK 0x00000200L /* Interrupt */
|
||||
#define EFLAGS_DF_MASK 0x00000400L /* Direction */
|
||||
#define EFLAGS_OF_MASK 0x00000800L /* Overflow */
|
||||
#define EFLAGS_IOPL_MASK 0x00003000L /* I/O Privilege */
|
||||
#define EFLAGS_NT 0x00004000L /* Nested Task */
|
||||
#define EFLAGS_SIGN_MASK 0x00008000L /* Sign */
|
||||
#define EFLAGS_RF 0x00010000L /* Resume */
|
||||
#define EFLAGS_V86_MASK 0x00020000L /* Virtual 8086 */
|
||||
#define EFLAGS_ALIGN_CHECK 0x00040000L /* Alignment Check */
|
||||
#define EFLAGS_VIF 0x00080000L /* Virtual Interrupt */
|
||||
#define EFLAGS_VIP 0x00100000L /* Virtual Interrupt Pending */
|
||||
#define EFLAGS_ID_MASK 0x00200000L /* Identification */
|
||||
/* Kernel CPU Standard Features */
|
||||
#define KCF_VME (1ULL << 0) /* Virtual 8086 Mode Enhancements */
|
||||
#define KCF_LARGE_PAGE (1ULL << 1) /* Page Size Extensions */
|
||||
#define KCF_RDTSC (1ULL << 2) /* Time Stamp Counter */
|
||||
#define KCF_PAE (1ULL << 3) /* Physical Address Extension */
|
||||
#define KCF_MCE (1ULL << 4) /* Machine Check Exception */
|
||||
#define KCF_CMPXCHG8B (1ULL << 5) /* CMPXCHG8B Instruction */
|
||||
#define KCF_APIC (1ULL << 6) /* APIC On-Chip */
|
||||
#define KCF_FAST_SYSCALL (1ULL << 7) /* SYSENTER/SYSEXIT Instructions */
|
||||
#define KCF_MTRR (1ULL << 8) /* Memory Type Range Registers */
|
||||
#define KCF_GLOBAL_PAGE (1ULL << 9) /* Page Global Enable */
|
||||
#define KCF_MCA (1ULL << 10) /* Machine Check Architecture */
|
||||
#define KCF_CMOV (1ULL << 11) /* Conditional Move Instructions */
|
||||
#define KCF_PAT (1ULL << 12) /* Page Attribute Table */
|
||||
#define KCF_PSE36 (1ULL << 13) /* 36-bit Page Size Extension */
|
||||
#define KCF_CLFLUSH (1ULL << 14) /* CLFLUSH Instruction */
|
||||
#define KCF_FXSR (1ULL << 15) /* FXSAVE/FXRSTOR Instructions */
|
||||
#define KCF_ACPI (1ULL << 16) /* Thermal Monitor and Software Controlled Clock */
|
||||
#define KCF_MMX (1ULL << 17) /* MMX Technology */
|
||||
#define KCF_SSE (1ULL << 18) /* Streaming SIMD Extensions */
|
||||
#define KCF_SSE2 (1ULL << 19) /* Streaming SIMD Extensions 2 */
|
||||
#define KCF_SMT (1ULL << 20) /* Hyper-Threading Technology */
|
||||
#define KCF_SSE3 (1ULL << 21) /* Streaming SIMD Extensions 3 */
|
||||
#define KCF_VMX (1ULL << 22) /* Intel Virtual Machine Extensions */
|
||||
#define KCF_SSSE3 (1ULL << 23) /* Supplemental SSE3 Instructions */
|
||||
#define KCF_SSE41 (1ULL << 24) /* SSE4.1 Instructions */
|
||||
#define KCF_SSE42 (1ULL << 25) /* SSE4.2 Instructions */
|
||||
#define KCF_X2APIC (1ULL << 26) /* x2APIC Support */
|
||||
#define KCF_POPCNT (1ULL << 27) /* POPCNT Instruction */
|
||||
#define KCF_TSC_DEADLINE (1ULL << 28) /* TSC Deadline Timer */
|
||||
#define KCF_AES (1ULL << 29) /* AES-NI Instruction Set */
|
||||
#define KCF_XSAVE (1ULL << 30) /* XSAVE/XRSTOR Instructions */
|
||||
#define KCF_AVX (1ULL << 31) /* Advanced Vector Extensions */
|
||||
#define KCF_RDRAND (1ULL << 32) /* RDRAND Instruction */
|
||||
#define KCF_FSGSBASE (1ULL << 33) /* RDFSBASE/WRFSBASE Instructions */
|
||||
#define KCF_AVX2 (1ULL << 34) /* AVX2 Instructions */
|
||||
#define KCF_SMEP (1ULL << 35) /* Supervisor Mode Execution Prevention */
|
||||
#define KCF_RDSEED (1ULL << 36) /* RDSEED Instruction */
|
||||
#define KCF_SMAP (1ULL << 37) /* Supervisor Mode Access Prevention */
|
||||
#define KCF_SHA (1ULL << 38) /* SHA Extensions */
|
||||
#define KCF_LA57 (1ULL << 39) /* 57-bit Linear Addresses */
|
||||
#define KCF_ARAT (1ULL << 40) /* Always Running APIC Timer */
|
||||
|
||||
/* EFLAGS sanitize masks */
|
||||
#define EFLAGS_KERNELMODE 0x00210FD5L
|
||||
#define EFLAGS_USERMODE 0x00010DD5L
|
||||
/* Kernel CPU Extended Features */
|
||||
#define KCF_SVM (1ULL << 0) /* AMD Secure Virtual Machine */
|
||||
#define KCF_SSE4A (1ULL << 1) /* SSE4A Instructions */
|
||||
#define KCF_FMA4 (1ULL << 2) /* FMA4 Instructions */
|
||||
#define KCF_TOPOEXT (1ULL << 3) /* AMD Topology Extensions */
|
||||
#define KCF_SYSCALL (1ULL << 4) /* SYSCALL/SYSRET Instructions */
|
||||
#define KCF_NX_BIT (1ULL << 5) /* No-Execute Page Protection */
|
||||
#define KCF_RDTSCP (1ULL << 6) /* RDTSCP Instruction */
|
||||
#define KCF_64BIT (1ULL << 7) /* Long Mode Support */
|
||||
#define KCF_3DNOW_EXT (1ULL << 8) /* 3DNow! Extensions */
|
||||
#define KCF_3DNOW (1ULL << 9) /* 3DNow! Instructions */
|
||||
#define KCF_INVARIANT_TSC (1ULL << 10) /* Invariant Time Stamp Counter */
|
||||
|
||||
/* Context control flags */
|
||||
#define CONTEXT_ARCHITECTURE 0x00100000
|
||||
#define CONTEXT_CONTROL (CONTEXT_ARCHITECTURE | 0x01)
|
||||
#define CONTEXT_INTEGER (CONTEXT_ARCHITECTURE | 0x02)
|
||||
#define CONTEXT_SEGMENTS (CONTEXT_ARCHITECTURE | 0x04)
|
||||
#define CONTEXT_FLOATING_POINT (CONTEXT_ARCHITECTURE | 0x08)
|
||||
#define CONTEXT_DEBUG_REGISTERS (CONTEXT_ARCHITECTURE | 0x10)
|
||||
#define CONTEXT_ARCHITECTURE 0x00100000
|
||||
#define CONTEXT_CONTROL (CONTEXT_ARCHITECTURE | 0x01)
|
||||
#define CONTEXT_INTEGER (CONTEXT_ARCHITECTURE | 0x02)
|
||||
#define CONTEXT_SEGMENTS (CONTEXT_ARCHITECTURE | 0x04)
|
||||
#define CONTEXT_FLOATING_POINT (CONTEXT_ARCHITECTURE | 0x08)
|
||||
#define CONTEXT_DEBUG_REGISTERS (CONTEXT_ARCHITECTURE | 0x10)
|
||||
#define CONTEXT_FULL (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_FLOATING_POINT)
|
||||
#define CONTEXT_ALL (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS | \
|
||||
CONTEXT_FLOATING_POINT | CONTEXT_DEBUG_REGISTERS)
|
||||
|
||||
/* Clock control flags */
|
||||
#define CLOCK_QUANTUM_DECREMENT 3
|
||||
|
||||
/* DPC definitions */
|
||||
#define DPC_ADJUST_THRESHOLD 20
|
||||
#define DPC_IDEAL_RATE 20
|
||||
#define DPC_MAXIMUM_QUEUE_DEPTH 4
|
||||
#define DPC_MINIMUM_RATE 3
|
||||
|
||||
/* Interrupt request levels definitions */
|
||||
#define PASSIVE_LEVEL 0
|
||||
#define LOW_LEVEL 0
|
||||
#define APC_LEVEL 1
|
||||
#define DISPATCH_LEVEL 2
|
||||
#define CMC_LEVEL 5
|
||||
#define DEVICE1_LEVEL 6
|
||||
#define DEVICE2_LEVEL 7
|
||||
#define DEVICE3_LEVEL 8
|
||||
#define DEVICE4_LEVEL 9
|
||||
#define DEVICE5_LEVEL 10
|
||||
#define DEVICE6_LEVEL 11
|
||||
#define DEVICE7_LEVEL 12
|
||||
#define SYNC_LEVEL 12
|
||||
#define CLOCK_LEVEL 13
|
||||
#define IPI_LEVEL 14
|
||||
#define DRS_LEVEL 14
|
||||
#define POWER_LEVEL 14
|
||||
#define PROFILE_LEVEL 15
|
||||
#define HIGH_LEVEL 15
|
||||
#define PASSIVE_LEVEL 0
|
||||
#define LOW_LEVEL 0
|
||||
#define APC_LEVEL 1
|
||||
#define DISPATCH_LEVEL 2
|
||||
#define CMC_LEVEL 5
|
||||
#define DEVICE1_LEVEL 6
|
||||
#define DEVICE2_LEVEL 7
|
||||
#define DEVICE3_LEVEL 8
|
||||
#define DEVICE4_LEVEL 9
|
||||
#define DEVICE5_LEVEL 10
|
||||
#define DEVICE6_LEVEL 11
|
||||
#define DEVICE7_LEVEL 12
|
||||
#define SYNC_LEVEL 12
|
||||
#define CLOCK_LEVEL 13
|
||||
#define IPI_LEVEL 14
|
||||
#define DRS_LEVEL 14
|
||||
#define POWER_LEVEL 14
|
||||
#define PROFILE_LEVEL 15
|
||||
#define HIGH_LEVEL 15
|
||||
|
||||
/* Size of the exception area */
|
||||
#define EXCEPTION_AREA_SIZE 64
|
||||
@@ -133,21 +179,26 @@
|
||||
/* Static Kernel-Mode address start */
|
||||
#define KSEG0_BASE 0xFFFFF80000000000
|
||||
|
||||
/* XTOS Kernel address base */
|
||||
#define KSEG0_KERNEL_BASE 0x0000000800000000
|
||||
|
||||
/* XTOS Kernel stack size */
|
||||
#define KERNEL_STACK_SIZE 0x8000
|
||||
#define KERNEL_STACKS 3
|
||||
|
||||
/* XTOS Kernel stack guard pages */
|
||||
#define KERNEL_STACK_GUARD_PAGES 1
|
||||
|
||||
/* Processor structures size */
|
||||
#define KPROCESSOR_STRUCTURES_SIZE ((KERNEL_STACKS * KERNEL_STACK_SIZE) + (GDT_ENTRIES * sizeof(KGDTENTRY)) + \
|
||||
sizeof(KTSS) + sizeof(KPROCESSOR_BLOCK) + MM_PAGE_SIZE)
|
||||
|
||||
/* Kernel frames */
|
||||
#define KEXCEPTION_FRAME_SIZE sizeof(KEXCEPTION_FRAME)
|
||||
#define KSWITCH_FRAME_SIZE sizeof(KSWITCH_FRAME)
|
||||
#define KTRAP_FRAME_ALIGN 0x10
|
||||
#define KTRAP_FRAME_SIZE sizeof(KTRAP_FRAME)
|
||||
|
||||
/* Initial stack reservation size */
|
||||
#define KTHREAD_STACK_OFFSET ((sizeof(KTHREAD_INIT_FRAME) + STACK_ALIGNMENT - 1) & ~(STACK_ALIGNMENT - 1))
|
||||
|
||||
/* Return address size pushed by 'call' instruction */
|
||||
#define KRETURN_ADDRESS_SIZE 0x8
|
||||
|
||||
@@ -159,6 +210,10 @@
|
||||
#define NPX_STATE_SCRUB 0x1
|
||||
#define NPX_STATE_SWITCH 0x2
|
||||
|
||||
|
||||
/* C/C++ specific code */
|
||||
#ifndef __XTOS_ASSEMBLER__
|
||||
|
||||
/* Floating point state storing structure */
|
||||
typedef struct _FLOATING_SAVE_AREA
|
||||
{
|
||||
@@ -190,7 +245,7 @@ typedef struct _CONTEXT
|
||||
USHORT SegFs;
|
||||
USHORT SegGs;
|
||||
USHORT SegSs;
|
||||
ULONG EFlags;
|
||||
ULONG Flags;
|
||||
ULONG64 Dr0;
|
||||
ULONG64 Dr1;
|
||||
ULONG64 Dr2;
|
||||
@@ -256,6 +311,24 @@ typedef struct _KDESCRIPTOR
|
||||
PVOID Base;
|
||||
} KDESCRIPTOR, *PKDESCRIPTOR;
|
||||
|
||||
/* Device Queue structure definition */
|
||||
typedef struct _KDEVICE_QUEUE
|
||||
{
|
||||
CSHORT Type;
|
||||
CSHORT Size;
|
||||
LIST_ENTRY DeviceListHead;
|
||||
KSPIN_LOCK Lock;
|
||||
union
|
||||
{
|
||||
BOOLEAN Busy;
|
||||
struct
|
||||
{
|
||||
LONGLONG Reserved:8;
|
||||
LONGLONG Hint:56;
|
||||
};
|
||||
};
|
||||
} KDEVICE_QUEUE, *PKDEVICE_QUEUE;
|
||||
|
||||
/* Global Descriptor Table (GDT) entry union definition */
|
||||
typedef struct _KGDTENTRY
|
||||
{
|
||||
@@ -293,11 +366,18 @@ typedef struct _KIDTENTRY
|
||||
{
|
||||
USHORT OffsetLow;
|
||||
USHORT Selector;
|
||||
USHORT IstIndex:3;
|
||||
USHORT Reserved0:5;
|
||||
USHORT Type:5;
|
||||
USHORT Dpl:2;
|
||||
USHORT Present:1;
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
USHORT IstIndex:3;
|
||||
USHORT Reserved0:5;
|
||||
USHORT Type:5;
|
||||
USHORT Dpl:2;
|
||||
USHORT Present:1;
|
||||
};
|
||||
USHORT Access;
|
||||
};
|
||||
USHORT OffsetMiddle;
|
||||
ULONG OffsetHigh;
|
||||
ULONG Reserved1;
|
||||
@@ -314,7 +394,7 @@ typedef struct _KTSS
|
||||
ULONG64 Reserved1;
|
||||
USHORT Reserved2;
|
||||
USHORT IoMapBase;
|
||||
} PACK KTSS, *PKTSS;
|
||||
} PACKED KTSS, *PKTSS;
|
||||
|
||||
/* Exception frame definition */
|
||||
typedef struct _KEXCEPTION_FRAME
|
||||
@@ -480,18 +560,30 @@ typedef struct _KSPECIAL_REGISTERS
|
||||
ULONG64 MsrSyscallMask;
|
||||
} KSPECIAL_REGISTERS, *PKSPECIAL_REGISTERS;
|
||||
|
||||
/* Processor start block structure definition */
|
||||
typedef struct _PROCESSOR_START_BLOCK
|
||||
{
|
||||
ULONG_PTR Cr3;
|
||||
ULONG_PTR Cr4;
|
||||
PVOID EntryPoint;
|
||||
PVOID InitialStack;
|
||||
PVOID ProcessorStructures;
|
||||
PVOID Stack;
|
||||
BOOLEAN Started;
|
||||
} PROCESSOR_START_BLOCK, *PPROCESSOR_START_BLOCK;
|
||||
|
||||
/* Processor state frame structure definition */
|
||||
typedef struct _KPROCESSOR_STATE
|
||||
{
|
||||
KSPECIAL_REGISTERS SpecialRegisters;
|
||||
CONTEXT ContextFrame;
|
||||
KSPECIAL_REGISTERS SpecialRegisters;
|
||||
} KPROCESSOR_STATE, *PKPROCESSOR_STATE;
|
||||
|
||||
/* Processor Control Block (PRCB) structure definition */
|
||||
typedef struct _KPROCESSOR_CONTROL_BLOCK
|
||||
{
|
||||
ULONG MxCsr;
|
||||
UCHAR Number;
|
||||
UCHAR CpuNumber;
|
||||
PKTHREAD CurrentThread;
|
||||
PKTHREAD IdleThread;
|
||||
PKTHREAD NextThread;
|
||||
@@ -499,14 +591,32 @@ typedef struct _KPROCESSOR_CONTROL_BLOCK
|
||||
ULONG_PTR SetMember;
|
||||
CPU_IDENTIFICATION CpuId;
|
||||
KPROCESSOR_STATE ProcessorState;
|
||||
KSPIN_LOCK PrcbLock;
|
||||
KSPIN_LOCK_QUEUE LockQueue[MaximumLock];
|
||||
LOOKASIDE_LIST LookasideList[16];
|
||||
LOOKASIDE_LIST NonPagedLookasideList[POOL_LOOKASIDE_LISTS];
|
||||
LOOKASIDE_LIST PagedLookasideList[POOL_LOOKASIDE_LISTS];
|
||||
VOLATILE ULONG IpiFrozen;
|
||||
VOLATILE LONG_PTR RequestSummary;
|
||||
KDPC_DATA DpcData[2];
|
||||
PVOID DpcStack;
|
||||
LONG MaximumDpcQueueDepth;
|
||||
ULONG DpcRequestRate;
|
||||
BOOLEAN DpcInterruptRequested;
|
||||
VOLATILE BOOLEAN DpcRoutineActive;
|
||||
ULONG DpcLastCount;
|
||||
VOLATILE ULONG_PTR TimerHand;
|
||||
VOLATILE ULONG_PTR TimerRequest;
|
||||
ULONG_PTR MultiThreadProcessorSet;
|
||||
SINGLE_LIST_ENTRY DeferredReadyListHead;
|
||||
ULONG InterruptCount;
|
||||
ULONG KernelTime;
|
||||
ULONG UserTime;
|
||||
ULONG DpcTime;
|
||||
ULONG InterruptTime;
|
||||
ULONG AdjustDpcThreshold;
|
||||
PROCESSOR_POWER_STATE PowerState;
|
||||
ULONG ProfilingCountdown;
|
||||
} KPROCESSOR_CONTROL_BLOCK, *PKPROCESSOR_CONTROL_BLOCK;
|
||||
|
||||
/* Processor Block structure definition */
|
||||
@@ -526,8 +636,16 @@ typedef struct _KPROCESSOR_BLOCK
|
||||
PKIDTENTRY IdtBase;
|
||||
KRUNLEVEL RunLevel;
|
||||
KPROCESSOR_CONTROL_BLOCK Prcb;
|
||||
ULONG Irr;
|
||||
ULONG IrrActive;
|
||||
ULONG Idr;
|
||||
ULONG ContextSwitches;
|
||||
KAFFINITY SetMember;
|
||||
ULONG StallScaleFactor;
|
||||
UCHAR CpuNumber;
|
||||
ULONG HardwareId;
|
||||
VOLATILE BOOLEAN Started;
|
||||
PINTERRUPT_HANDLER InterruptDispatchTable[256];
|
||||
} KPROCESSOR_BLOCK, *PKPROCESSOR_BLOCK;
|
||||
|
||||
/* Thread Environment Block (TEB) structure definition */
|
||||
@@ -536,4 +654,5 @@ typedef struct _THREAD_ENVIRONMENT_BLOCK
|
||||
THREAD_INFORMATION_BLOCK InformationBlock;
|
||||
} THREAD_ENVIRONMENT_BLOCK, *PTHREAD_ENVIRONMENT_BLOCK;
|
||||
|
||||
#endif /* __XTOS_ASSEMBLER__ */
|
||||
#endif /* __XTDK_AMD64_KETYPES_H */
|
||||
|
||||
+187
-10
@@ -14,30 +14,119 @@
|
||||
|
||||
|
||||
/* Pages related definitions */
|
||||
#define MM_PAGE_MASK 0xFFF
|
||||
#define MM_PAGE_MASK (MM_PAGE_SIZE - 1)
|
||||
#define MM_PAGE_SHIFT 12L
|
||||
#define MM_PAGE_SIZE 4096
|
||||
|
||||
#define MM_PTE_BASE 0xFFFFF68000000000UI64
|
||||
#define MM_PDE_BASE 0xFFFFF6FB40000000UI64
|
||||
#define MM_PPE_BASE 0xFFFFF6FB7DA00000UI64
|
||||
#define MM_PXE_BASE 0xFFFFF6FB7DBED000UI64
|
||||
/* Page directory and page base addresses for 4-level paging */
|
||||
#define MM_PTE_BASE 0xFFFFF68000000000ULL
|
||||
#define MM_PDE_BASE 0xFFFFF6FB40000000ULL
|
||||
#define MM_PPE_BASE 0xFFFFF6FB7DA00000ULL
|
||||
#define MM_PXE_BASE 0xFFFFF6FB7DBED000ULL
|
||||
|
||||
/* Page directory and page base addresses for 5-level paging */
|
||||
#define MM_PTE_LA57_BASE 0xFFED000000000000ULL
|
||||
#define MM_PDE_LA57_BASE 0xFFEDF68000000000ULL
|
||||
#define MM_PPE_LA57_BASE 0xFFEDF6FB40000000ULL
|
||||
#define MM_PXE_LA57_BASE 0xFFEDF6FB7DA00000ULL
|
||||
#define MM_P5E_LA57_BASE 0xFFEDF6FB7DBED000ULL
|
||||
|
||||
/* PTE shift values */
|
||||
#define MM_PTE_SHIFT 3
|
||||
#define MM_PTI_SHIFT 12
|
||||
#define MM_PDI_SHIFT 21
|
||||
#define MM_PPI_SHIFT 30
|
||||
#define MM_PXI_SHIFT 39
|
||||
#define MM_P5I_SHIFT 48
|
||||
|
||||
#define MM_PTE_SHIFT 3
|
||||
/* PTE state flags */
|
||||
#define MM_PTE_VALID 0x0000000000000001ULL
|
||||
#define MM_PTE_ACCESSED 0x0000000000000020ULL
|
||||
#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 */
|
||||
#define MM_MINIMUM_PHYSICAL_PAGES 2048
|
||||
|
||||
/* Number of system PTEs */
|
||||
#define MM_DEFAULT_NUMBER_SYSTEM_PTES 22000
|
||||
|
||||
/* Default number of secondary colors */
|
||||
#define MM_DEFAULT_SECONDARY_COLORS 64
|
||||
|
||||
/* Number of HAL allocation descriptors */
|
||||
#define MM_HARDWARE_ALLOCATION_DESCRIPTORS 64
|
||||
|
||||
/* Kernel HAL heap initial start address */
|
||||
#define MM_HARDWARE_HEAP_START_ADDRESS ((PVOID)(((ULONG_PTR)MM_HARDWARE_VA_START) + 1024 * 1024))
|
||||
|
||||
/* HAL memory pool virtual address start */
|
||||
#define MM_HARDWARE_VA_START 0xFFFFFFFFFFC00000ULL
|
||||
|
||||
/* Kernel shared data address */
|
||||
#define MM_KERNEL_SHARED_DATA_ADDRESS 0xFFFFFFFFFFDF0000ULL
|
||||
|
||||
/* Maximum physical address used by HAL allocations */
|
||||
#define MM_MAXIMUM_PHYSICAL_ADDRESS 0x00000000FFFFFFFFULL
|
||||
|
||||
/* Highest system address */
|
||||
#define MM_HIGHEST_SYSTEM_ADDRESS 0xFFFFFFFFFFFFFFFFULL
|
||||
|
||||
/* User probe address */
|
||||
#define MM_USER_PROBE_ADDRESS 0x00007FFFFFFF0000ULL
|
||||
#define MM_USER_PROBE_LA57_ADDRESS 0x00FFFFFFFFFF0000ULL
|
||||
|
||||
/* Trampoline code address */
|
||||
#define MM_TRAMPOLINE_ADDRESS 0x80000
|
||||
|
||||
/* 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)
|
||||
|
||||
|
||||
/* C/C++ specific code */
|
||||
#ifndef __XTOS_ASSEMBLER__
|
||||
|
||||
/* Page size enumeration list */
|
||||
typedef enum _PAGE_SIZE
|
||||
{
|
||||
@@ -67,6 +156,18 @@ typedef struct _HARDWARE_PTE
|
||||
ULONGLONG NoExecute:1;
|
||||
} HARDWARE_PTE, *PHARDWARE_PTE;
|
||||
|
||||
/* Page map information structure definition */
|
||||
typedef struct _MMPAGEMAP_INFO
|
||||
{
|
||||
BOOLEAN Xpa;
|
||||
ULONGLONG PteBase;
|
||||
ULONGLONG PdeBase;
|
||||
ULONGLONG PpeBase;
|
||||
ULONGLONG PxeBase;
|
||||
ULONGLONG P5eBase;
|
||||
ULONG VaBits;
|
||||
} MMPAGEMAP_INFO, *PMMPAGEMAP_INFO;
|
||||
|
||||
/* A Page Table Entry on AMD64 system */
|
||||
typedef struct _MMPTE_HARDWARE
|
||||
{
|
||||
@@ -212,6 +313,7 @@ typedef struct _MMPFN
|
||||
USHORT ReferenceCount;
|
||||
} e2;
|
||||
} u3;
|
||||
ULONG UsedPageTableEntries;
|
||||
union
|
||||
{
|
||||
MMPTE OriginalPte;
|
||||
@@ -222,15 +324,90 @@ typedef struct _MMPFN
|
||||
ULONG_PTR EntireFrame;
|
||||
struct
|
||||
{
|
||||
ULONG_PTR PteFrame:58;
|
||||
ULONG_PTR PteFrame:57;
|
||||
ULONG_PTR InPageError:1;
|
||||
ULONG_PTR VerifierAllocation:1;
|
||||
ULONG_PTR AweAllocation:1;
|
||||
ULONG_PTR LockCharged:1;
|
||||
ULONG_PTR KernelStack:1;
|
||||
ULONG_PTR Priority:3;
|
||||
ULONG_PTR MustBeCached:1;
|
||||
};
|
||||
} u4;
|
||||
} MMPFN, *PMMPFN;
|
||||
|
||||
/* Pool descriptor structure definition */
|
||||
typedef struct _POOL_DESCRIPTOR
|
||||
{
|
||||
LIST_ENTRY ListHeads[MM_POOL_LISTS_PER_PAGE];
|
||||
PVOID LockAddress;
|
||||
ULONG PoolIndex;
|
||||
LONG PendingFreeDepth;
|
||||
PVOID PendingFrees;
|
||||
MMPOOL_TYPE PoolType;
|
||||
ULONG RunningFrees;
|
||||
ULONG RunningAllocations;
|
||||
ULONG Threshold;
|
||||
ULONG TotalPages;
|
||||
ULONG TotalBigAllocations;
|
||||
SIZE_T TotalBytes;
|
||||
SIZE_T Reserved;
|
||||
} POOL_DESCRIPTOR, *PPOOL_DESCRIPTOR;
|
||||
|
||||
/* Working set list entry structure definition */
|
||||
typedef struct _MMWSLENTRY
|
||||
{
|
||||
ULONG_PTR Valid:1;
|
||||
ULONG_PTR LockedInWs:1;
|
||||
ULONG_PTR LockedInMemory:1;
|
||||
ULONG_PTR Protection:5;
|
||||
ULONG_PTR Hashed:1;
|
||||
ULONG_PTR Direct:1;
|
||||
ULONG_PTR Age:2;
|
||||
ULONG_PTR VirtualPageNumber:52;
|
||||
} MMWSLENTRY, *PMMWSLENTRY;
|
||||
|
||||
/* Working set free entry structure definition */
|
||||
typedef struct _MMWSLE_FREE_ENTRY
|
||||
{
|
||||
ULONG MustBeZero:1;
|
||||
ULONG PreviousFree:31;
|
||||
LONG NextFree;
|
||||
} MMWSLE_FREE_ENTRY, *PMMWSLE_FREE_ENTRY;
|
||||
|
||||
/* Working set list entry union definition */
|
||||
typedef union _MMWSLE
|
||||
{
|
||||
PVOID VirtualAddress;
|
||||
ULONG_PTR Long;
|
||||
MMWSLENTRY e1;
|
||||
MMWSLE_FREE_ENTRY Free;
|
||||
} MMWSLE, *PMMWSLE;
|
||||
|
||||
/* Working set list structure definition */
|
||||
typedef struct _MMWSL
|
||||
{
|
||||
ULONG FirstFree;
|
||||
ULONG FirstDynamic;
|
||||
ULONG LastEntry;
|
||||
ULONG NextSlot;
|
||||
PMMWSLE Wsle;
|
||||
ULONG LastInitializedWsle;
|
||||
ULONG NonDirectCount;
|
||||
PMMWSLE_HASH HashTable;
|
||||
ULONG HashTableSize;
|
||||
ULONG NumberOfCommittedPageTables;
|
||||
PVOID HashTableStart;
|
||||
PVOID HighestPermittedHashAddress;
|
||||
ULONG NumberOfImageWaiters;
|
||||
ULONG VadBitMapHint;
|
||||
PVOID HighestUserAddress;
|
||||
ULONG MaximumUserPageTablePages;
|
||||
ULONG MaximumUserPageDirectoryPages;
|
||||
PULONG CommittedPageTables;
|
||||
ULONG NumberOfCommittedPageDirectories;
|
||||
PULONG CommittedPageDirectories;
|
||||
ULONG NumberOfCommittedPageDirectoryParents;
|
||||
ULONGLONG CommittedPageDirectoryParents[1];
|
||||
} MMWSL, *PMMWSL;
|
||||
|
||||
#endif /* __XTOS_ASSEMBLER__ */
|
||||
#endif /* __XTDK_AMD64_MMTYPES_H */
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: sdk/xtdk/amd64/rtltypes.h
|
||||
* DESCRIPTION: Runtime library structures definitions for AMD64 architecture
|
||||
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef __XTDK_AMD64_RTLTYPES_H
|
||||
#define __XTDK_AMD64_RTLTYPES_H
|
||||
|
||||
#include <xtbase.h>
|
||||
#include <rtltypes.h>
|
||||
|
||||
|
||||
/* C/C++ specific code */
|
||||
#ifndef __XTOS_ASSEMBLER__
|
||||
|
||||
/* Header for a sequenced single linked list union definition */
|
||||
typedef union _SINGLE_LIST_HEADER
|
||||
{
|
||||
struct
|
||||
{
|
||||
ULONGLONG Alignment;
|
||||
ULONGLONG Region;
|
||||
};
|
||||
struct
|
||||
{
|
||||
ULONGLONG Depth:16;
|
||||
ULONGLONG Sequence:9;
|
||||
ULONGLONG NextEntry:39;
|
||||
ULONGLONG HeaderType:1;
|
||||
ULONGLONG Init:1;
|
||||
ULONGLONG Reserved:59;
|
||||
ULONGLONG Region:3;
|
||||
} Header8;
|
||||
struct
|
||||
{
|
||||
ULONGLONG Depth:16;
|
||||
ULONGLONG Sequence:48;
|
||||
ULONGLONG HeaderType:1;
|
||||
ULONGLONG Init:1;
|
||||
ULONGLONG Reserved:2;
|
||||
ULONGLONG NextEntry:60;
|
||||
} Header16;
|
||||
struct
|
||||
{
|
||||
ULONGLONG Depth:16;
|
||||
ULONGLONG Sequence:48;
|
||||
ULONGLONG HeaderType:1;
|
||||
ULONGLONG Reserved:3;
|
||||
ULONGLONG NextEntry:60;
|
||||
} Header64;
|
||||
} SINGLE_LIST_HEADER, *PSINGLE_LIST_HEADER;
|
||||
|
||||
#endif /* __XTOS_ASSEMBLER__ */
|
||||
#endif /* __XTDK_AMD64_RTLTYPES_H */
|
||||
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Ссылка в новой задаче
Block a user