Compare commits
775 Commits
edk2-stabl
...
intel-fsp-
Author | SHA1 | Date | |
---|---|---|---|
|
8674aecb6a | ||
|
563bd1f035 | ||
|
2415686bbc | ||
|
ca407c7246 | ||
|
4403bbd7c0 | ||
|
568eee7cf3 | ||
|
1c877c7160 | ||
|
09fe015af9 | ||
|
1a2ad3ba9e | ||
|
8f39da712f | ||
|
b1357a40fc | ||
|
74f90d38c4 | ||
|
fc72a6ceaa | ||
|
08c77cce0e | ||
|
3f89db8690 | ||
|
bc5012b8fb | ||
|
5a4b24b89a | ||
|
67c25bcc3a | ||
|
ea38791043 | ||
|
ff95c0fcba | ||
|
5af8fccd26 | ||
|
d3733188a2 | ||
|
7b6327ff03 | ||
|
8db87f9835 | ||
|
356b96b3a2 | ||
|
2c06e76bba | ||
|
9099dcbd61 | ||
|
15ac284815 | ||
|
4ac2457673 | ||
|
93ddc0d133 | ||
|
f8683a4ba0 | ||
|
84ce1f1bdc | ||
|
b99917ce3e | ||
|
c812d3209c | ||
|
b6174e2d09 | ||
|
89db28b9c9 | ||
|
80e28dcec8 | ||
|
394d589652 | ||
|
b8af2c9eda | ||
|
f4c15d3807 | ||
|
c22a32e1ab | ||
|
9b2a082e5b | ||
|
0a6fc3d067 | ||
|
aaa90aacaf | ||
|
0f30087b9a | ||
|
ba86bb2c4d | ||
|
6c4966423b | ||
|
ff306cfd6c | ||
|
a93bf06b1d | ||
|
154e243a99 | ||
|
2552fd58f5 | ||
|
f8edb7e998 | ||
|
5c7526f501 | ||
|
8adad18a94 | ||
|
ebe377f9eb | ||
|
7e9cef643d | ||
|
bcf181a33b | ||
|
8b680e4af1 | ||
|
f2cdb268ef | ||
|
ceacd9e992 | ||
|
242ab73d7f | ||
|
88899a372c | ||
|
be4e0cfbad | ||
|
fa37a846d0 | ||
|
789ea79e94 | ||
|
3e3acb3a27 | ||
|
9ad2b981bd | ||
|
c857042471 | ||
|
9378310dd8 | ||
|
b304d2807b | ||
|
ec94e97a6e | ||
|
c8543b8d83 | ||
|
f4f9c4cb63 | ||
|
f355b98606 | ||
|
3a3713e62c | ||
|
8293e6766a | ||
|
86c4f437d8 | ||
|
00acc6cbf9 | ||
|
fd8c6bed8a | ||
|
4e74764245 | ||
|
8c43227c64 | ||
|
3fd8800954 | ||
|
54a3d5ec48 | ||
|
089e9c19a8 | ||
|
38e72aa877 | ||
|
7601b251fd | ||
|
d3abb40d77 | ||
|
1510d6a391 | ||
|
e6956d0052 | ||
|
722da9078e | ||
|
ea56fa3d47 | ||
|
faef5a367c | ||
|
f793bfcae9 | ||
|
8af507c1f1 | ||
|
befd18fca6 | ||
|
469eb46169 | ||
|
55d6e39f72 | ||
|
8dd962a657 | ||
|
c635a56384 | ||
|
505812ae1d | ||
|
81cada9892 | ||
|
ecdbdba636 | ||
|
da8c0b8f4d | ||
|
f9941d31dd | ||
|
093cceaf79 | ||
|
a53e5b4174 | ||
|
f47074425d | ||
|
be7fcaa1c9 | ||
|
ad8f2d6b07 | ||
|
feec20b28d | ||
|
f159102a13 | ||
|
245bdd2cb9 | ||
|
de15e7c265 | ||
|
2a8fc911b9 | ||
|
704ff0ff2a | ||
|
f2bd980059 | ||
|
43bad5b5ba | ||
|
9ad9dc9d4f | ||
|
e54310451f | ||
|
91dee771fc | ||
|
70d5086c32 | ||
|
2a7a1223d0 | ||
|
13406bdeb5 | ||
|
f07fb43b2d | ||
|
052aa07da4 | ||
|
b2034179e8 | ||
|
f60d5ca97f | ||
|
178938b2b9 | ||
|
ad1db975c0 | ||
|
cdc3fa5418 | ||
|
270fece684 | ||
|
b8b890ca0a | ||
|
2377733248 | ||
|
b3c1bc1cfa | ||
|
98800cce65 | ||
|
611c7f1101 | ||
|
64ab457d1f | ||
|
3a402f9611 | ||
|
a91443885d | ||
|
52f012129a | ||
|
61ac4fc70d | ||
|
d5d60a4331 | ||
|
099dfbb29d | ||
|
0358c0bfc1 | ||
|
6cdf647b5f | ||
|
951a03536c | ||
|
0c7f189e60 | ||
|
4fcfd089aa | ||
|
0f1946b662 | ||
|
c5c5c980db | ||
|
63d425002a | ||
|
d5339c04d7 | ||
|
3a3a3af4a2 | ||
|
93f6df5f3b | ||
|
d70cdcf0b5 | ||
|
b6d542e927 | ||
|
92958abf7a | ||
|
002f38a44a | ||
|
b36fbd3645 | ||
|
c6a60cf4b9 | ||
|
1e823422fb | ||
|
bfd42b2075 | ||
|
1854eee1b4 | ||
|
c14f034a1a | ||
|
1755932f89 | ||
|
b447a20bdf | ||
|
40b9ca6beb | ||
|
6e3c834ae4 | ||
|
cda6f9455c | ||
|
3571e1360e | ||
|
9c463f6f59 | ||
|
d189a3f9b6 | ||
|
dc528558c9 | ||
|
309809455a | ||
|
e33d3e7f56 | ||
|
3b5a58c5f0 | ||
|
0f127f3187 | ||
|
05db94018b | ||
|
1a258c7703 | ||
|
7a7bedce25 | ||
|
be7295b364 | ||
|
ddfb0ab1bb | ||
|
1c76101134 | ||
|
df4f154da9 | ||
|
ca08f3d453 | ||
|
c884b23ac4 | ||
|
a7947b6366 | ||
|
06033f5aba | ||
|
58802e02c4 | ||
|
8c654bb3ec | ||
|
bd6aa93296 | ||
|
776ec4ea3c | ||
|
60f6a2774e | ||
|
6fedaa1c04 | ||
|
1cae0d4215 | ||
|
d84f090fd7 | ||
|
3fdc47c65b | ||
|
21276ce093 | ||
|
998d4c98b7 | ||
|
48b6c60cc6 | ||
|
a5d8a39963 | ||
|
e4004e8e50 | ||
|
9432cabfb9 | ||
|
d4bc5378e0 | ||
|
7cfc48fe4f | ||
|
d6f99b2ac4 | ||
|
3ab0dadd66 | ||
|
8acb61dfb3 | ||
|
9bb1f080c4 | ||
|
91a33d4113 | ||
|
edf88807f7 | ||
|
e1fbff3ded | ||
|
aab6a9c9ae | ||
|
c5824c27be | ||
|
d2c46681fa | ||
|
af4ee6953c | ||
|
48f0e94921 | ||
|
ee026ea78b | ||
|
ef5dcba975 | ||
|
0bb7f64702 | ||
|
9b2b0942f1 | ||
|
0467236267 | ||
|
e428889115 | ||
|
4efcc11c94 | ||
|
e576dfadd6 | ||
|
9025a014f9 | ||
|
0a44fd3165 | ||
|
8436d4de71 | ||
|
9817d442cd | ||
|
683df865a7 | ||
|
f73c9adfc6 | ||
|
991c5d89ba | ||
|
db0f8c2f84 | ||
|
49188b2aa4 | ||
|
f45e254f2e | ||
|
4deef2d865 | ||
|
e210fc130e | ||
|
98936dc4f4 | ||
|
335644f90f | ||
|
3f55418d53 | ||
|
4fb393aaa8 | ||
|
65c73df44c | ||
|
dd7523b5b1 | ||
|
9e7a063b07 | ||
|
4d9ca66204 | ||
|
8c944c9383 | ||
|
f34c7645bd | ||
|
7d8a04e9d2 | ||
|
c4c15b8702 | ||
|
6510e19794 | ||
|
b654edec03 | ||
|
5269c26e07 | ||
|
447e5d3902 | ||
|
6672b3cff2 | ||
|
45098e8a9a | ||
|
c08eaaaf37 | ||
|
9c2d8281af | ||
|
7efce2e59c | ||
|
e497432c2c | ||
|
a9f9d5cf56 | ||
|
419b30d642 | ||
|
ed08c57113 | ||
|
478c07d483 | ||
|
6c1fb56802 | ||
|
9c20342eed | ||
|
3000c2963d | ||
|
d4e2909bfc | ||
|
d671d1fa48 | ||
|
5650f307b3 | ||
|
4d23a7ec84 | ||
|
4817953949 | ||
|
8b2ac43bd8 | ||
|
effddeea39 | ||
|
7c10e8abb6 | ||
|
d39271f114 | ||
|
90e52483bf | ||
|
aa9aff2d4e | ||
|
878478116a | ||
|
96bb6704e0 | ||
|
869f234140 | ||
|
3e025c7742 | ||
|
f291a581ac | ||
|
43a0e08d02 | ||
|
6e9bd495b3 | ||
|
d21c2cd082 | ||
|
5042ee43d9 | ||
|
4ac82ea1e1 | ||
|
381f8ef6a1 | ||
|
5bc09cf05a | ||
|
090e267b5b | ||
|
695d90b9b1 | ||
|
a1c35ff312 | ||
|
32bcdfa512 | ||
|
5f7c91f0d7 | ||
|
f7079d1bc1 | ||
|
5fc899535e | ||
|
d390920ed4 | ||
|
f52b30e73d | ||
|
92a1ac4080 | ||
|
e24529a5c3 | ||
|
045e4b84c1 | ||
|
2f524a745e | ||
|
0dee1d1358 | ||
|
0c8ea9fe1a | ||
|
1b6b4a83e1 | ||
|
01ce872739 | ||
|
a2c3bf1f2f | ||
|
799d88c1ba | ||
|
912718d8c7 | ||
|
d42fdd6f83 | ||
|
89465fe9e0 | ||
|
b0ed7ebdeb | ||
|
cd99d07d53 | ||
|
d6961bb47a | ||
|
7d325f93e1 | ||
|
64a228f5f8 | ||
|
5a8bc527b3 | ||
|
484b1534ed | ||
|
5e75c4d1fe | ||
|
6b7855209a | ||
|
c72ca46668 | ||
|
4249278aa6 | ||
|
d93fe5b579 | ||
|
748fea6279 | ||
|
191fa79bce | ||
|
a3e25cc8a1 | ||
|
40d572f70d | ||
|
8068188431 | ||
|
1f3b1eb308 | ||
|
a17add32c2 | ||
|
a2ab46adbc | ||
|
806d1be6a7 | ||
|
b58ec859c7 | ||
|
f9ec8e51d2 | ||
|
3391e20ffa | ||
|
02d7797d1a | ||
|
825c3e2c1b | ||
|
eaaaece4ad | ||
|
faca87fa03 | ||
|
492679a55d | ||
|
d6607d8b30 | ||
|
ced77332ca | ||
|
f98608ab3f | ||
|
859b55443a | ||
|
de7c6081cb | ||
|
7c47d89003 | ||
|
1dc875a7d5 | ||
|
0758a8e979 | ||
|
efc52d67e1 | ||
|
364e0b4cda | ||
|
e569fbd205 | ||
|
ddd2be6b00 | ||
|
28de1a5550 | ||
|
57f9b7f89e | ||
|
6ae2d31ca2 | ||
|
7288ff4095 | ||
|
9b08c655ff | ||
|
3b9cd71454 | ||
|
9bfaa3da1e | ||
|
63fd7f3898 | ||
|
7d48d20a3d | ||
|
6d38761085 | ||
|
9767a597d7 | ||
|
643623147a | ||
|
6c9a3d4233 | ||
|
ed1c70cf1a | ||
|
6c6fef0247 | ||
|
3be909099c | ||
|
e63d54db95 | ||
|
a5c2ce7cd1 | ||
|
11ceb258f3 | ||
|
1158fc8e2c | ||
|
8f3ed1bc4d | ||
|
55942db1d3 | ||
|
bc498ac4ca | ||
|
51a6fb4118 | ||
|
63c89da242 | ||
|
17cb8ddba3 | ||
|
763840c9ab | ||
|
f668e78871 | ||
|
590f5f09b7 | ||
|
17efae27ac | ||
|
49df3fcee1 | ||
|
43df61878d | ||
|
c69f6406b9 | ||
|
90e11edd16 | ||
|
a1ddad9593 | ||
|
61d3b2d427 | ||
|
fc0a025ec3 | ||
|
6be54f15a0 | ||
|
8923699291 | ||
|
07952a962a | ||
|
ecb30848fd | ||
|
d55cfdc51f | ||
|
d8dd54f071 | ||
|
ec41733cfd | ||
|
1e404c405a | ||
|
2632178bc6 | ||
|
15bee1937f | ||
|
0980779a9d | ||
|
e521b3c54e | ||
|
82f6f44fc4 | ||
|
d9cd82e8bc | ||
|
c241c96f85 | ||
|
ddd34a8183 | ||
|
f5cb376703 | ||
|
39c503f155 | ||
|
82662a3b5f | ||
|
fdb3f06b82 | ||
|
6b3d196a7c | ||
|
4c0f6e349d | ||
|
2be4828af1 | ||
|
edfe16a6d9 | ||
|
1d3215fd24 | ||
|
b85048261a | ||
|
70228e101e | ||
|
c70bdf9d4a | ||
|
0997352ddb | ||
|
c230c002ac | ||
|
b1c1147059 | ||
|
cb30c8f251 | ||
|
5cd8be6079 | ||
|
a83dbf008c | ||
|
adc6898366 | ||
|
929d1a24d1 | ||
|
9e56970090 | ||
|
c13742b180 | ||
|
fbb9607223 | ||
|
578bcdc260 | ||
|
6d8f4bafad | ||
|
0b9026a823 | ||
|
c73fce3d12 | ||
|
3cf658ee7e | ||
|
e36d5ac7d1 | ||
|
f1d78c489a | ||
|
764e8ba138 | ||
|
c32be82e99 | ||
|
f9713abe95 | ||
|
1e947f9bf5 | ||
|
466b877f43 | ||
|
5b45b44e6f | ||
|
c788c2b1ad | ||
|
534fcb84de | ||
|
0f1ddb21ff | ||
|
707e6be745 | ||
|
3e63a91b17 | ||
|
7a38ad07d0 | ||
|
a67efa3b22 | ||
|
58bccfa57c | ||
|
422bf2725b | ||
|
02b7b861b1 | ||
|
ec97412b7c | ||
|
82af1cbf0d | ||
|
c44e0a896c | ||
|
818283de3f | ||
|
e465aae055 | ||
|
27fb01a0b0 | ||
|
b3407223c5 | ||
|
f76d50166b | ||
|
69c135462d | ||
|
67ead55b35 | ||
|
348a34d984 | ||
|
d148a178c1 | ||
|
ccb4c38a50 | ||
|
214bc6e206 | ||
|
ea26838a52 | ||
|
84a534b406 | ||
|
c4a53853c1 | ||
|
ce7b77a71b | ||
|
eb9db72ca8 | ||
|
a4826c8664 | ||
|
54d33a5314 | ||
|
f69248d093 | ||
|
5bd326c5f3 | ||
|
7f9e354a01 | ||
|
ddb7050c68 | ||
|
66360134f8 | ||
|
418aded964 | ||
|
ef62da4ff7 | ||
|
f60f4cfeb4 | ||
|
2a0755a947 | ||
|
a57268fe9e | ||
|
6b81166fff | ||
|
1825c24fd8 | ||
|
a302263ebb | ||
|
c38f0816e7 | ||
|
582b6cdd08 | ||
|
f16bd39441 | ||
|
6a5033ca3e | ||
|
ba562ca040 | ||
|
dd40a1f85c | ||
|
f9fd0c2108 | ||
|
ce4cca7c06 | ||
|
fc70522ffe | ||
|
aad15888d6 | ||
|
493dde944d | ||
|
38c92f7030 | ||
|
9854561c08 | ||
|
a2e7559576 | ||
|
f6fc95c943 | ||
|
48cf40b8c9 | ||
|
f221466ea7 | ||
|
e79bf8d707 | ||
|
5add2c5577 | ||
|
ff82167537 | ||
|
f7c4d22465 | ||
|
dad13c8067 | ||
|
81c6f1762e | ||
|
4cefb5e903 | ||
|
bb3594e842 | ||
|
f6c8bbbe92 | ||
|
68ddad3f60 | ||
|
5feb1fbd44 | ||
|
6deb4baa1f | ||
|
efb5659334 | ||
|
7de8045a09 | ||
|
6c585b52e5 | ||
|
ba3b642d5b | ||
|
c36b7b5114 | ||
|
cd72b6cfd1 | ||
|
d80c3d6e19 | ||
|
81a46615f5 | ||
|
0d622d9c3d | ||
|
f97117bae7 | ||
|
c194ccca26 | ||
|
8f628f7820 | ||
|
8d774c745c | ||
|
788421d5a7 | ||
|
43516263a8 | ||
|
fae43d06dd | ||
|
a8ecf980c0 | ||
|
c1d8b697cf | ||
|
b219e2cd4c | ||
|
0dbaba4239 | ||
|
13a623cf9c | ||
|
d22867471f | ||
|
957ca63190 | ||
|
5099057fb8 | ||
|
4be497df49 | ||
|
93b8ed68dd | ||
|
b854b07540 | ||
|
cc530cd10c | ||
|
1d031e750b | ||
|
29f7ad8b7c | ||
|
8c39253dff | ||
|
02d7b79771 | ||
|
7636747f44 | ||
|
7feed95031 | ||
|
db62b65c63 | ||
|
3d6b7fd303 | ||
|
26cfe2c659 | ||
|
de949fdbcf | ||
|
e60536756e | ||
|
513edcec28 | ||
|
7aa8af4576 | ||
|
4b026f0d5a | ||
|
b34ed98694 | ||
|
c10f7f77b0 | ||
|
7dcf32c1ee | ||
|
e5b911d411 | ||
|
184ee9b1de | ||
|
e50c2bb383 | ||
|
3e61b953b7 | ||
|
f74abe4a2c | ||
|
0eb522987f | ||
|
0f7fb5c5e5 | ||
|
b238ce28f8 | ||
|
0a5d2b505c | ||
|
61364ab927 | ||
|
bd33a385ee | ||
|
cd70de1cc0 | ||
|
cc1d13c922 | ||
|
3b0e04305b | ||
|
668621362f | ||
|
322ac05f8b | ||
|
1333d8c8d3 | ||
|
01712e6508 | ||
|
c6a6193d12 | ||
|
3b4ad37ebe | ||
|
d14feb6cb7 | ||
|
45b0be3840 | ||
|
77b738b36f | ||
|
b5808fe960 | ||
|
7285f275ff | ||
|
1549651da6 | ||
|
c37cce7a84 | ||
|
38ed2ff3dd | ||
|
a4960cf1b6 | ||
|
8778ee616a | ||
|
21821933ae | ||
|
7990438f14 | ||
|
f469c70281 | ||
|
a9e3458ba7 | ||
|
75839f977d | ||
|
50f911d25d | ||
|
9108fc17b0 | ||
|
300aae1180 | ||
|
84b223c18c | ||
|
adec2bd598 | ||
|
73974f809c | ||
|
e0ed7a9b15 | ||
|
04ff9d663b | ||
|
bca6fcd78f | ||
|
d74d56fcfa | ||
|
422da35375 | ||
|
b47fe2655d | ||
|
3feea54eae | ||
|
2c061de063 | ||
|
eafd990f26 | ||
|
8b0932c19f | ||
|
6aa31db5eb | ||
|
6d57592740 | ||
|
fb02f5b2cd | ||
|
c602e97446 | ||
|
12a4ef58a8 | ||
|
f891b052c5 | ||
|
47650a5cab | ||
|
61a9fa589a | ||
|
eccb856f01 | ||
|
1e0f973b65 | ||
|
83357313dd | ||
|
b75d1de536 | ||
|
4ef78a39f0 | ||
|
c8b8157e12 | ||
|
9a1f14ad72 | ||
|
a23fdff6fb | ||
|
5cd3d4bc43 | ||
|
18fcb37598 | ||
|
2ed845b3c3 | ||
|
d9c919744b | ||
|
48997fe4d3 | ||
|
430743a1e8 | ||
|
c67617f3c6 | ||
|
a22f4c34df | ||
|
4e2ac8062c | ||
|
c40c6351fa | ||
|
a523556244 | ||
|
302eb57b18 | ||
|
63653ff8c8 | ||
|
710ff7490a | ||
|
f6f66e0c30 | ||
|
94057f7402 | ||
|
a6a835bdb1 | ||
|
e3756ba90a | ||
|
4cca792399 | ||
|
a56af23f06 | ||
|
b112ec225f | ||
|
4465cd124f | ||
|
072b9c2839 | ||
|
27f44ea1fb | ||
|
9d1c9d0379 | ||
|
2d9950a2bf | ||
|
eaea26b781 | ||
|
6eacb857c1 | ||
|
7d3d87e4d7 | ||
|
dd01704111 | ||
|
c7c964b109 | ||
|
c0328cf380 | ||
|
8120390aab | ||
|
8f38b08b50 | ||
|
8ffa47fb3a | ||
|
1f0d809629 | ||
|
859046e000 | ||
|
df851da3ce | ||
|
e18792566c | ||
|
f55477fe2d | ||
|
cf3ad972a2 | ||
|
2649a735b2 | ||
|
972d887264 | ||
|
c9d7262843 | ||
|
396e791059 | ||
|
08a475df10 | ||
|
70911f1f4a | ||
|
4bb34b6df1 | ||
|
cc617b6e14 | ||
|
0ef6fbbd11 | ||
|
d96c7befc0 | ||
|
c751368c37 | ||
|
76b51586f4 | ||
|
0e660ee7a1 | ||
|
088573c973 | ||
|
ad12178c3d | ||
|
80f7c1b464 | ||
|
a292d6c8ef | ||
|
21429c1566 | ||
|
266efa6b29 | ||
|
43f2c9f8eb | ||
|
8ef8175a33 | ||
|
76fc038746 | ||
|
9b2e99e50a | ||
|
a85cdb9f2b | ||
|
44c9a93948 | ||
|
f235838f58 | ||
|
5556529b94 | ||
|
1bbbd6a79d | ||
|
59bbab3a9a | ||
|
082208a849 | ||
|
e2a8eaec0f | ||
|
52b6a7c889 | ||
|
0d141df465 | ||
|
31d60b9ba4 | ||
|
d42046e1da | ||
|
caa6584f36 | ||
|
83e78feb80 | ||
|
0ce7f25fe3 | ||
|
ba5410320b | ||
|
4a1aeca3bd | ||
|
6cfb6da951 | ||
|
d0d38ce20e | ||
|
f9c2c71ed6 | ||
|
0286fe8176 | ||
|
40801ac995 | ||
|
166830d8f7 | ||
|
f273905161 | ||
|
4fa25853cd | ||
|
df73a69faf | ||
|
f68cb23c14 | ||
|
49accdedf9 | ||
|
b948a49615 | ||
|
33a3293651 | ||
|
fd30b00707 | ||
|
88bd066166 | ||
|
e1ed55738e | ||
|
253909974a | ||
|
d786a17232 | ||
|
999463c865 | ||
|
a5abd9cc2c | ||
|
123b720eeb | ||
|
a457823f27 | ||
|
caa917491a | ||
|
ec8c74e8bc | ||
|
796b380ca7 | ||
|
665afccc52 | ||
|
95bb203861 | ||
|
c7a0aca0ed | ||
|
01b6090b75 | ||
|
c5d6a57da0 | ||
|
69ebe82806 | ||
|
78fb6b0e02 | ||
|
bfb141cf19 | ||
|
2fe25a74d6 | ||
|
d3add11e87 | ||
|
d39d1260c6 | ||
|
97eedf5dfb | ||
|
7e55cf6b48 | ||
|
a80032dc44 | ||
|
fc8b8deac2 | ||
|
3bfbc91507 | ||
|
91f6c533f8 | ||
|
0c3e8e9947 | ||
|
cb277815d5 | ||
|
e6edbe315f | ||
|
13c5e34a1b | ||
|
804666c86e | ||
|
49054b6bb6 | ||
|
62a75650e4 | ||
|
9caaa79dd7 | ||
|
490a62beb7 | ||
|
e8b9296c67 | ||
|
0f9395d7c5 | ||
|
94d4efb54e | ||
|
2926498f01 | ||
|
965dbf97ab | ||
|
d5cf0fba20 | ||
|
c9416efeef | ||
|
6cc63aee53 | ||
|
c8ff8e05af | ||
|
9c33f16f8c | ||
|
0a58c9a391 | ||
|
0844a16a07 | ||
|
46f6752834 | ||
|
4f47eaf945 | ||
|
4d613feee5 | ||
|
b49a6c8f80 | ||
|
fe6142f04c |
50
.azurepipelines/ReadMe.md
Normal file
50
.azurepipelines/ReadMe.md
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
# Azure DevOps Pipelines
|
||||||
|
|
||||||
|
These yml files are used to provide CI builds using the Azure DevOps Pipeline Service.
|
||||||
|
Most of the CI leverages edk2-pytools to support cross platform building and execution.
|
||||||
|
|
||||||
|
## Core CI
|
||||||
|
|
||||||
|
Focused on building and testing all packages in Edk2 without an actual target platform.
|
||||||
|
|
||||||
|
See `.pytools/ReadMe.py` for more details
|
||||||
|
|
||||||
|
## Platform CI
|
||||||
|
|
||||||
|
Focused on building a single target platform and confirming functionality on that platform.
|
||||||
|
|
||||||
|
## Conventions
|
||||||
|
|
||||||
|
* Files extension should be *.yml. *.yaml is also supported but in Edk2 we use those for our package configuration.
|
||||||
|
* Platform CI files should be in the `<PlatformPkg>/.azurepipelines` folder.
|
||||||
|
* Core CI files are in the root folder.
|
||||||
|
* Shared templates are in the `templates` folder.
|
||||||
|
* Top level CI files should be named `<host os>-<tool_chain_tag>.yml`
|
||||||
|
|
||||||
|
## Links
|
||||||
|
|
||||||
|
* Basic Azure Landing Site - https://docs.microsoft.com/en-us/azure/devops/pipelines/?view=azure-devops
|
||||||
|
* Pipeline jobs - https://docs.microsoft.com/en-us/azure/devops/pipelines/process/phases?view=azure-devops&tabs=yaml
|
||||||
|
* Pipeline yml scheme - https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=azure-devops&tabs=schema%2Cparameter-schema
|
||||||
|
* Pipeline expression - https://docs.microsoft.com/en-us/azure/devops/pipelines/process/expressions?view=azure-devops
|
||||||
|
* PyTools - https://github.com/tianocore/edk2-pytool-extensions and https://github.com/tianocore/edk2-pytool-library
|
||||||
|
|
||||||
|
## Lessons Learned
|
||||||
|
|
||||||
|
### Templates and parameters
|
||||||
|
|
||||||
|
They are great but evil. If they are used as part of determining the steps of a build they must resolve before the build starts. They can not use variables set in a yml or determined as part of a matrix. If they are used in a step then they can be bound late.
|
||||||
|
|
||||||
|
### File matching patterns
|
||||||
|
|
||||||
|
On Linux this can hang if there are too many files in the search list.
|
||||||
|
|
||||||
|
### Templates and file splitting
|
||||||
|
|
||||||
|
Suggestion is to do one big yaml file that does what you want for one of your targets. Then do the second one and find the deltas. From that you can start to figure out the right split of files, steps, jobs.
|
||||||
|
|
||||||
|
### Conditional steps
|
||||||
|
|
||||||
|
If you want the step to show up in the log but not run, use a step conditional. This is great when a platform doesn't currently support a feature but you want the builders to know that the features exists and maybe someday it will.
|
||||||
|
|
||||||
|
If you want the step to not show up use a template step conditional wrapper. Beware this will be evaluated early (at build start). This can hide things not needed on a given OS for example.
|
@@ -2,6 +2,7 @@
|
|||||||
# Azure Pipeline build file for a build using ubuntu and GCC5
|
# Azure Pipeline build file for a build using ubuntu and GCC5
|
||||||
#
|
#
|
||||||
# Copyright (c) Microsoft Corporation.
|
# Copyright (c) Microsoft Corporation.
|
||||||
|
# Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
|
||||||
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
##
|
##
|
||||||
trigger:
|
trigger:
|
||||||
@@ -14,5 +15,5 @@ jobs:
|
|||||||
parameters:
|
parameters:
|
||||||
tool_chain_tag: 'GCC5'
|
tool_chain_tag: 'GCC5'
|
||||||
vm_image: 'ubuntu-latest'
|
vm_image: 'ubuntu-latest'
|
||||||
arch_list: "IA32,X64,ARM,AARCH64"
|
arch_list: "IA32,X64,ARM,AARCH64,RISCV64"
|
||||||
|
|
||||||
|
59
.azurepipelines/templates/ReadMe.md
Normal file
59
.azurepipelines/templates/ReadMe.md
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
# CI Templates
|
||||||
|
|
||||||
|
This folder contains azure pipeline yml templates for "Core" and "Platform" Continuous Integration and PR validation.
|
||||||
|
|
||||||
|
## Common CI templates
|
||||||
|
|
||||||
|
### basetools-build-steps.yml
|
||||||
|
|
||||||
|
This template compiles the Edk2 basetools from source. The steps in this template are
|
||||||
|
conditional and will only run if variable `pkg_count` is greater than 0.
|
||||||
|
|
||||||
|
It also has two conditional steps only used when the toolchain contains GCC. These two steps
|
||||||
|
use `apt` to update the system packages and add those necessary for Edk2 builds.
|
||||||
|
|
||||||
|
## Core CI templates
|
||||||
|
|
||||||
|
### pr-gate-build-job.yml
|
||||||
|
|
||||||
|
This templates contains the jobs and most importantly the matrix of which packages and
|
||||||
|
targets to run for Core CI.
|
||||||
|
|
||||||
|
### pr-gate-steps.yml
|
||||||
|
|
||||||
|
This template is the main Core CI template. It controls all the steps run and is responsible for most functionality of the Core CI process. This template sets
|
||||||
|
the `pkg_count` variable using the `stuart_pr_eval` tool when the
|
||||||
|
build type is "pull request"
|
||||||
|
|
||||||
|
### spell-check-prereq-steps.yml
|
||||||
|
|
||||||
|
This template installs the node based tools used by the spell checker plugin. The steps
|
||||||
|
in this template are conditional and will only run if variable `pkg_count` is greater than 0.
|
||||||
|
|
||||||
|
## Platform CI templates
|
||||||
|
|
||||||
|
### platform-build-run-steps.yml
|
||||||
|
|
||||||
|
This template makes heavy use of pytools to build and run a platform in the Edk2 repo
|
||||||
|
|
||||||
|
Also uses basetools-build-steps.yml to compile basetools
|
||||||
|
|
||||||
|
#### Special Notes
|
||||||
|
|
||||||
|
* For a build type of pull request it will conditionally build if the patches change files that impact the platform.
|
||||||
|
* uses `stuart_pr_eval` to determine impact
|
||||||
|
* For manual builds or CI builds it will always build the platform
|
||||||
|
* It compiles basetools from source
|
||||||
|
* Will use `stuart_build --FlashOnly` to attempt to run the built image if the `Run` parameter is set.
|
||||||
|
* See the parameters block for expected configuration options
|
||||||
|
* Parameter `extra_install_step` allows the caller to insert extra steps. This is useful if additional dependencies, tools, or other things need to be installed. Here is an example of installing qemu on Windows.
|
||||||
|
|
||||||
|
``` yaml
|
||||||
|
steps:
|
||||||
|
- template: ../../.azurepipelines/templates/build-run-steps.yml
|
||||||
|
parameters:
|
||||||
|
extra_install_step:
|
||||||
|
- powershell: choco install qemu; Write-Host "##vso[task.prependpath]c:\Program Files\qemu"
|
||||||
|
displayName: Install QEMU and Set QEMU on path # friendly name displayed in the UI
|
||||||
|
condition: and(gt(variables.pkg_count, 0), succeeded())
|
||||||
|
```
|
134
.azurepipelines/templates/platform-build-run-steps.yml
Normal file
134
.azurepipelines/templates/platform-build-run-steps.yml
Normal file
@@ -0,0 +1,134 @@
|
|||||||
|
|
||||||
|
## @file
|
||||||
|
# File steps.yml
|
||||||
|
#
|
||||||
|
# template file containing the steps to build
|
||||||
|
#
|
||||||
|
# Copyright (c) Microsoft Corporation.
|
||||||
|
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
|
##
|
||||||
|
|
||||||
|
parameters:
|
||||||
|
- name: tool_chain_tag
|
||||||
|
type: string
|
||||||
|
default: ''
|
||||||
|
- name: build_pkg
|
||||||
|
type: string
|
||||||
|
default: ''
|
||||||
|
- name: build_target
|
||||||
|
type: string
|
||||||
|
default: ''
|
||||||
|
- name: build_arch
|
||||||
|
type: string
|
||||||
|
default: ''
|
||||||
|
- name: build_file
|
||||||
|
type: string
|
||||||
|
default: ''
|
||||||
|
- name: build_flags
|
||||||
|
type: string
|
||||||
|
default: ''
|
||||||
|
- name: run_flags
|
||||||
|
type: string
|
||||||
|
default: ''
|
||||||
|
|
||||||
|
- name: extra_install_step
|
||||||
|
type: stepList
|
||||||
|
default: []
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- checkout: self
|
||||||
|
clean: true
|
||||||
|
fetchDepth: 1
|
||||||
|
|
||||||
|
- task: UsePythonVersion@0
|
||||||
|
inputs:
|
||||||
|
versionSpec: "3.8.x"
|
||||||
|
architecture: "x64"
|
||||||
|
|
||||||
|
- script: pip install -r pip-requirements.txt --upgrade
|
||||||
|
displayName: 'Install/Upgrade pip modules'
|
||||||
|
|
||||||
|
# Set default
|
||||||
|
- bash: echo "##vso[task.setvariable variable=pkg_count]${{ 1 }}"
|
||||||
|
|
||||||
|
# trim the package list if this is a PR
|
||||||
|
- task: CmdLine@1
|
||||||
|
displayName: Check if ${{ parameters.build_pkg }} need testing
|
||||||
|
inputs:
|
||||||
|
filename: stuart_pr_eval
|
||||||
|
arguments: -c ${{ parameters.build_file }} -t ${{ parameters.build_target}} -a ${{ parameters.build_arch}} --pr-target origin/$(System.PullRequest.targetBranch) --output-count-format-string "##vso[task.setvariable variable=pkg_count;isOutpout=true]{pkgcount}"
|
||||||
|
condition: eq(variables['Build.Reason'], 'PullRequest')
|
||||||
|
|
||||||
|
# Setup repo
|
||||||
|
- task: CmdLine@1
|
||||||
|
displayName: Setup
|
||||||
|
inputs:
|
||||||
|
filename: stuart_setup
|
||||||
|
arguments: -c ${{ parameters.build_file }} TOOL_CHAIN_TAG=${{ parameters.tool_chain_tag}} -t ${{ parameters.build_target}} -a ${{ parameters.build_arch}} ${{ parameters.build_flags}}
|
||||||
|
condition: and(gt(variables.pkg_count, 0), succeeded())
|
||||||
|
|
||||||
|
# Stuart Update
|
||||||
|
- task: CmdLine@1
|
||||||
|
displayName: Update
|
||||||
|
inputs:
|
||||||
|
filename: stuart_update
|
||||||
|
arguments: -c ${{ parameters.build_file }} TOOL_CHAIN_TAG=${{ parameters.tool_chain_tag}} -t ${{ parameters.build_target}} -a ${{ parameters.build_arch}} ${{ parameters.build_flags}}
|
||||||
|
condition: and(gt(variables.pkg_count, 0), succeeded())
|
||||||
|
|
||||||
|
# build basetools
|
||||||
|
# do this after setup and update so that code base dependencies
|
||||||
|
# are all resolved.
|
||||||
|
- template: basetools-build-steps.yml
|
||||||
|
parameters:
|
||||||
|
tool_chain_tag: ${{ parameters.tool_chain_tag }}
|
||||||
|
|
||||||
|
# Potential Extra steps
|
||||||
|
- ${{ parameters.extra_install_step }}
|
||||||
|
|
||||||
|
# Build
|
||||||
|
- task: CmdLine@1
|
||||||
|
displayName: Build
|
||||||
|
inputs:
|
||||||
|
filename: stuart_build
|
||||||
|
arguments: -c ${{ parameters.build_file }} TOOL_CHAIN_TAG=${{ parameters.tool_chain_tag}} TARGET=${{ parameters.build_target}} -a ${{ parameters.build_arch}} ${{ parameters.build_flags}}
|
||||||
|
condition: and(gt(variables.pkg_count, 0), succeeded())
|
||||||
|
|
||||||
|
# Run
|
||||||
|
- task: CmdLine@1
|
||||||
|
displayName: Run to shell
|
||||||
|
inputs:
|
||||||
|
filename: stuart_build
|
||||||
|
arguments: -c ${{ parameters.build_file }} TOOL_CHAIN_TAG=${{ parameters.tool_chain_tag}} TARGET=${{ parameters.build_target}} -a ${{ parameters.build_arch}} ${{ parameters.build_flags}} ${{ parameters.run_flags }} --FlashOnly
|
||||||
|
condition: and(and(gt(variables.pkg_count, 0), succeeded()), eq(variables['Run'], true))
|
||||||
|
timeoutInMinutes: 1
|
||||||
|
|
||||||
|
# Copy the build logs to the artifact staging directory
|
||||||
|
- task: CopyFiles@2
|
||||||
|
displayName: "Copy build logs"
|
||||||
|
inputs:
|
||||||
|
targetFolder: "$(Build.ArtifactStagingDirectory)"
|
||||||
|
SourceFolder: "Build"
|
||||||
|
contents: |
|
||||||
|
BUILDLOG_*.txt
|
||||||
|
BUILDLOG_*.md
|
||||||
|
CI_*.txt
|
||||||
|
CI_*.md
|
||||||
|
CISETUP.txt
|
||||||
|
SETUPLOG.txt
|
||||||
|
UPDATE_LOG.txt
|
||||||
|
PREVALLOG.txt
|
||||||
|
TestSuites.xml
|
||||||
|
**/BUILD_TOOLS_REPORT.html
|
||||||
|
**/OVERRIDELOG.TXT
|
||||||
|
BASETOOLS_BUILD*.*
|
||||||
|
flattenFolders: true
|
||||||
|
condition: succeededOrFailed()
|
||||||
|
|
||||||
|
# Publish build artifacts to Azure Artifacts/TFS or a file share
|
||||||
|
- task: PublishBuildArtifacts@1
|
||||||
|
continueOnError: true
|
||||||
|
displayName: "Publish build logs"
|
||||||
|
inputs:
|
||||||
|
pathtoPublish: "$(Build.ArtifactStagingDirectory)"
|
||||||
|
artifactName: "Build Logs $(System.JobName)"
|
||||||
|
condition: succeededOrFailed()
|
@@ -22,10 +22,10 @@ jobs:
|
|||||||
matrix:
|
matrix:
|
||||||
TARGET_MDE_CPU:
|
TARGET_MDE_CPU:
|
||||||
Build.Pkgs: 'MdePkg,UefiCpuPkg'
|
Build.Pkgs: 'MdePkg,UefiCpuPkg'
|
||||||
Build.Targets: 'DEBUG,RELEASE,NO-TARGET'
|
Build.Targets: 'DEBUG,RELEASE,NO-TARGET,NOOPT'
|
||||||
TARGET_MDEMODULE_DEBUG:
|
TARGET_MDEMODULE_DEBUG:
|
||||||
Build.Pkgs: 'MdeModulePkg'
|
Build.Pkgs: 'MdeModulePkg'
|
||||||
Build.Targets: 'DEBUG'
|
Build.Targets: 'DEBUG,NOOPT'
|
||||||
TARGET_MDEMODULE_RELEASE:
|
TARGET_MDEMODULE_RELEASE:
|
||||||
Build.Pkgs: 'MdeModulePkg'
|
Build.Pkgs: 'MdeModulePkg'
|
||||||
Build.Targets: 'RELEASE,NO-TARGET'
|
Build.Targets: 'RELEASE,NO-TARGET'
|
||||||
@@ -35,15 +35,20 @@ jobs:
|
|||||||
TARGET_OTHER:
|
TARGET_OTHER:
|
||||||
Build.Pkgs: 'PcAtChipsetPkg,ShellPkg'
|
Build.Pkgs: 'PcAtChipsetPkg,ShellPkg'
|
||||||
Build.Targets: 'DEBUG,RELEASE,NO-TARGET'
|
Build.Targets: 'DEBUG,RELEASE,NO-TARGET'
|
||||||
TARGET_FMP:
|
TARGET_FMP_FAT_TEST:
|
||||||
Build.Pkgs: 'FmpDevicePkg,FatPkg'
|
Build.Pkgs: 'FmpDevicePkg,FatPkg,UnitTestFrameworkPkg'
|
||||||
Build.Targets: 'DEBUG,RELEASE,NO-TARGET'
|
Build.Targets: 'DEBUG,RELEASE,NO-TARGET,NOOPT'
|
||||||
TARGET_CRYPTO:
|
TARGET_CRYPTO:
|
||||||
Build.Pkgs: 'CryptoPkg'
|
Build.Pkgs: 'CryptoPkg'
|
||||||
Build.Targets: 'DEBUG,RELEASE,NO-TARGET'
|
Build.Targets: 'DEBUG,RELEASE,NO-TARGET'
|
||||||
TARGET_SECURITY:
|
TARGET_SECURITY:
|
||||||
Build.Pkgs: 'SecurityPkg'
|
Build.Pkgs: 'SecurityPkg'
|
||||||
Build.Targets: 'DEBUG,RELEASE,NO-TARGET'
|
Build.Targets: 'DEBUG,RELEASE,NO-TARGET'
|
||||||
|
TARGET_PLATFORMS:
|
||||||
|
# For Platforms only check code. Leave it to Platform CI
|
||||||
|
# to build them.
|
||||||
|
Build.Pkgs: 'ArmVirtPkg,EmulatorPkg,OvmfPkg'
|
||||||
|
Build.Targets: 'NO-TARGET'
|
||||||
|
|
||||||
workspace:
|
workspace:
|
||||||
clean: all
|
clean: all
|
||||||
|
@@ -20,7 +20,7 @@ steps:
|
|||||||
|
|
||||||
- task: UsePythonVersion@0
|
- task: UsePythonVersion@0
|
||||||
inputs:
|
inputs:
|
||||||
versionSpec: '3.7.x'
|
versionSpec: '3.8.x'
|
||||||
architecture: 'x64'
|
architecture: 'x64'
|
||||||
|
|
||||||
- script: pip install -r pip-requirements.txt --upgrade
|
- script: pip install -r pip-requirements.txt --upgrade
|
||||||
@@ -39,11 +39,6 @@ steps:
|
|||||||
arguments: -c .pytool/CISettings.py -p ${{ parameters.build_pkgs }} --pr-target origin/$(System.PullRequest.targetBranch) --output-csv-format-string "##vso[task.setvariable variable=pkgs_to_build;isOutpout=true]{pkgcsv}" --output-count-format-string "##vso[task.setvariable variable=pkg_count;isOutpout=true]{pkgcount}"
|
arguments: -c .pytool/CISettings.py -p ${{ parameters.build_pkgs }} --pr-target origin/$(System.PullRequest.targetBranch) --output-csv-format-string "##vso[task.setvariable variable=pkgs_to_build;isOutpout=true]{pkgcsv}" --output-count-format-string "##vso[task.setvariable variable=pkg_count;isOutpout=true]{pkgcount}"
|
||||||
condition: eq(variables['Build.Reason'], 'PullRequest')
|
condition: eq(variables['Build.Reason'], 'PullRequest')
|
||||||
|
|
||||||
# build basetools
|
|
||||||
- template: basetools-build-steps.yml
|
|
||||||
parameters:
|
|
||||||
tool_chain_tag: ${{ parameters.tool_chain_tag }}
|
|
||||||
|
|
||||||
# install spell check prereqs
|
# install spell check prereqs
|
||||||
- template: spell-check-prereq-steps.yml
|
- template: spell-check-prereq-steps.yml
|
||||||
|
|
||||||
@@ -62,6 +57,13 @@ steps:
|
|||||||
arguments: -c .pytool/CISettings.py -p $(pkgs_to_build) -t ${{ parameters.build_targets}} -a ${{ parameters.build_archs}} TOOL_CHAIN_TAG=${{ parameters.tool_chain_tag}}
|
arguments: -c .pytool/CISettings.py -p $(pkgs_to_build) -t ${{ parameters.build_targets}} -a ${{ parameters.build_archs}} TOOL_CHAIN_TAG=${{ parameters.tool_chain_tag}}
|
||||||
condition: and(gt(variables.pkg_count, 0), succeeded())
|
condition: and(gt(variables.pkg_count, 0), succeeded())
|
||||||
|
|
||||||
|
# build basetools
|
||||||
|
# do this after setup and update so that code base dependencies
|
||||||
|
# are all resolved.
|
||||||
|
- template: basetools-build-steps.yml
|
||||||
|
parameters:
|
||||||
|
tool_chain_tag: ${{ parameters.tool_chain_tag }}
|
||||||
|
|
||||||
- task: CmdLine@1
|
- task: CmdLine@1
|
||||||
displayName: Build and Test ${{ parameters.build_pkgs }} ${{ parameters.build_archs}}
|
displayName: Build and Test ${{ parameters.build_pkgs }} ${{ parameters.build_archs}}
|
||||||
inputs:
|
inputs:
|
||||||
|
13
.gitmodules
vendored
13
.gitmodules
vendored
@@ -4,3 +4,16 @@
|
|||||||
[submodule "SoftFloat"]
|
[submodule "SoftFloat"]
|
||||||
path = ArmPkg/Library/ArmSoftFloatLib/berkeley-softfloat-3
|
path = ArmPkg/Library/ArmSoftFloatLib/berkeley-softfloat-3
|
||||||
url = https://github.com/ucb-bar/berkeley-softfloat-3.git
|
url = https://github.com/ucb-bar/berkeley-softfloat-3.git
|
||||||
|
[submodule "UnitTestFrameworkPkg/Library/CmockaLib/cmocka"]
|
||||||
|
path = UnitTestFrameworkPkg/Library/CmockaLib/cmocka
|
||||||
|
url = https://git.cryptomilk.org/projects/cmocka.git
|
||||||
|
[submodule "MdeModulePkg/Universal/RegularExpressionDxe/oniguruma"]
|
||||||
|
path = MdeModulePkg/Universal/RegularExpressionDxe/oniguruma
|
||||||
|
url = https://github.com/kkos/oniguruma
|
||||||
|
[submodule "MdeModulePkg/Library/BrotliCustomDecompressLib/brotli"]
|
||||||
|
path = MdeModulePkg/Library/BrotliCustomDecompressLib/brotli
|
||||||
|
url = https://github.com/google/brotli
|
||||||
|
[submodule "BaseTools/Source/C/BrotliCompress/brotli"]
|
||||||
|
path = BaseTools/Source/C/BrotliCompress/brotli
|
||||||
|
url = https://github.com/google/brotli
|
||||||
|
ignore = untracked
|
||||||
|
73
.mailmap
Normal file
73
.mailmap
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
#
|
||||||
|
# This list is used by git-shortlog to update a few name translations
|
||||||
|
# in the git archive to adjust for job changes or incorrect/inconsistent
|
||||||
|
# name usage.
|
||||||
|
#
|
||||||
|
# Please keep this file sorted alphabetically, and email in lowercase.
|
||||||
|
# The format used is:
|
||||||
|
#
|
||||||
|
# Firstname Lastname <email@domain.tld>
|
||||||
|
#
|
||||||
|
|
||||||
|
Aaron Li <aaron.li@intel.com> <songpeng.li@intel.com>
|
||||||
|
Antoine Cœur <coeur@gmx.fr>
|
||||||
|
Antoine Cœur <coeur@gmx.fr> <Coeur@gmx.fr>
|
||||||
|
Ard Biesheuvel <ard.biesheuvel@linaro.org> <abiesheuvel@Edk2>
|
||||||
|
Ashley DeSimone <ashley.e.desimone@intel.com> <ashdesimone@6f19259b-4bc3-4df7-8a09-765794883524>
|
||||||
|
Baraneedharan Anbazhagan <anbazhagan@hp.com>
|
||||||
|
Chasel Chiu <chasel.chiu@intel.com>
|
||||||
|
Christopher J Zurcher <christopher.j.zurcher@intel.com>
|
||||||
|
Eric Dong <eric.dong@intel.com>
|
||||||
|
Eric Dong <eric.dong@intel.com> Eric Dong <eirc.dong@intel.com>
|
||||||
|
Eric Dong <eric.dong@intel.com> <ydong10@6f19259b-4bc3-4df7-8a09-765794883524>
|
||||||
|
Eric Dong <eric.dong@intel.com> <ydong10@Edk2>
|
||||||
|
Erik Bjorge <erik.c.bjorge@intel.com> <geekboy15a@6f19259b-4bc3-4df7-8a09-765794883524>
|
||||||
|
Eugene Cohen <eugene@nuviainc.com>
|
||||||
|
Eugene Cohen <eugene@nuviainc.com> <eugene@hp.com>
|
||||||
|
Hao A Wu <hao.a.wu@intel.com>
|
||||||
|
Hao A Wu <hao.a.wu@intel.com> <hwu1225@Edk2>
|
||||||
|
Hot Tian <hot.tian@intel.com>
|
||||||
|
Hot Tian <hot.tian@intel.com> <hhtian@6f19259b-4bc3-4df7-8a09-765794883524>
|
||||||
|
Jiewen Yao <jiewen.yao@intel.com>
|
||||||
|
Jiewen Yao <jiewen.yao@intel.com> <Jiewen.yao@intel.com>
|
||||||
|
Jiewen Yao <jiewen.yao@intel.com> <Jiewen.Yao@intel.com>
|
||||||
|
Jiewen Yao <jiewen.yao@intel.com> <jyao1>
|
||||||
|
Jiewen Yao <jiewen.yao@intel.com> <jyao1@6f19259b-4bc3-4df7-8a09-765794883524>
|
||||||
|
Jiewen Yao <jiewen.yao@intel.com> <jyao1@Edk2>
|
||||||
|
Jim Dailey <Jim.Dailey@Dell.com>
|
||||||
|
Jim Dailey <Jim.Dailey@Dell.com> <Jim_Dailey@Dell.com>
|
||||||
|
Laszlo Ersek <lersek@redhat.com> <lersek@6f19259b-4bc3-4df7-8a09-765794883524>
|
||||||
|
Laszlo Ersek <lersek@redhat.com> <lersek@Edk2>
|
||||||
|
Liming Gao <liming.gao@intel.com> <Gao, Liming liming.gao@intel.com>
|
||||||
|
Liming Gao <liming.gao@intel.com> <lgao4@6f19259b-4bc3-4df7-8a09-765794883524>
|
||||||
|
Liming Gao <liming.gao@intel.com> <lgao4@Edk2>
|
||||||
|
Liming Gao <liming.gao@intel.com> <liming.gao@intel.com>
|
||||||
|
Maciej Rabeda <maciej.rabeda@intel.com>
|
||||||
|
Marc-André Lureau <marcandre.lureau@redhat.com> <marcandre.lureau@redhat.com>
|
||||||
|
Marvin Häuser <Marvin.Haeuser@outlook.com>
|
||||||
|
Marvin Häuser <Marvin.Haeuser@outlook.com> edk2-devel <edk2-devel-bounces@lists.01.org>
|
||||||
|
Marvin Häuser <mhaeuser@outlook.de>
|
||||||
|
Maurice Ma <maurice.ma@intel.com>
|
||||||
|
Michael Kubacki <michael.a.kubacki@intel.com>
|
||||||
|
Michael Kubacki <michael.a.kubacki@intel.com> </o=Intel/ou=External (FYDIBOHF25SPDLT)/cn=Recipients/cn=3c8b0226e75f4ab08d20c151cb7a8a72>
|
||||||
|
Ming Tan <ming.tan@intel.com>
|
||||||
|
Nikolai Saoukh <nms@otdel-1.org>
|
||||||
|
Philippe Mathieu-Daudé <philmd@redhat.com>
|
||||||
|
Ray Ni <ray.ni@intel.com>
|
||||||
|
Ray Ni <ray.ni@intel.com> <C:/Program Files (x86)/Git/O=Intel/OU=Pacifica02/cn=Recipients/cn=rni2>
|
||||||
|
Ray Ni <ray.ni@intel.com> <niruiyu@6f19259b-4bc3-4df7-8a09-765794883524>
|
||||||
|
Ray Ni <ray.ni@intel.com> <niruiyu@Edk2>
|
||||||
|
Ray Ni <ray.ni@intel.com> <ruiyu.ni@intel.com>
|
||||||
|
Ray Ni <ray.ni@intel.com> <Ruiyu.ni@Intel.com>
|
||||||
|
Ray Ni <ray.ni@intel.com> <ruyu.ni@intel.com>
|
||||||
|
Samer El-Haj-Mahmoud <samer@elhajmahmoud.com> <elhaj@hpe.com>
|
||||||
|
Samer El-Haj-Mahmoud <samer@elhajmahmoud.com> <Samer El-Haj-Mahmoud elhaj@hp.com>
|
||||||
|
Shenglei Zhang <shenglei.zhang@intel.com>
|
||||||
|
Star Zeng <star.zeng@intel.com>
|
||||||
|
Star Zeng <star.zeng@intel.com> <lzeng14@6f19259b-4bc3-4df7-8a09-765794883524>
|
||||||
|
Star Zeng <star.zeng@intel.com> <lzeng14@Edk2>
|
||||||
|
Vitaly Cheptsov <vit9696@protonmail.com> Vitaly Cheptsov via Groups.Io <vit9696=protonmail.com@groups.io>
|
||||||
|
Vladimir Olovyannikov <vladimir.olovyannikov@broadcom.com> Vladimir Olovyannikov via edk2-devel <edk2-devel@lists.01.org>
|
||||||
|
Yonghong Zhu <yonghong.zhu@intel.com>
|
||||||
|
Yonghong Zhu <yonghong.zhu@intel.com> <yzhu52@Edk2>
|
||||||
|
Yu-Chen Lin <yuchenlin@synology.com>
|
@@ -1,6 +1,7 @@
|
|||||||
# @file
|
# @file
|
||||||
#
|
#
|
||||||
# Copyright (c) Microsoft Corporation.
|
# Copyright (c) Microsoft Corporation.
|
||||||
|
# Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
|
||||||
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
##
|
##
|
||||||
import os
|
import os
|
||||||
@@ -39,7 +40,9 @@ class Settings(CiBuildSettingsManager, UpdateSettingsManager, SetupSettingsManag
|
|||||||
''' return iterable of edk2 packages supported by this build.
|
''' return iterable of edk2 packages supported by this build.
|
||||||
These should be edk2 workspace relative paths '''
|
These should be edk2 workspace relative paths '''
|
||||||
|
|
||||||
return ("MdePkg",
|
return ("ArmVirtPkg",
|
||||||
|
"EmulatorPkg",
|
||||||
|
"MdePkg",
|
||||||
"MdeModulePkg",
|
"MdeModulePkg",
|
||||||
"NetworkPkg",
|
"NetworkPkg",
|
||||||
"PcAtChipsetPkg",
|
"PcAtChipsetPkg",
|
||||||
@@ -48,15 +51,19 @@ class Settings(CiBuildSettingsManager, UpdateSettingsManager, SetupSettingsManag
|
|||||||
"FmpDevicePkg",
|
"FmpDevicePkg",
|
||||||
"ShellPkg",
|
"ShellPkg",
|
||||||
"FatPkg",
|
"FatPkg",
|
||||||
"CryptoPkg"
|
"CryptoPkg",
|
||||||
|
"UnitTestFrameworkPkg",
|
||||||
|
"OvmfPkg"
|
||||||
)
|
)
|
||||||
|
|
||||||
def GetArchitecturesSupported(self):
|
def GetArchitecturesSupported(self):
|
||||||
''' return iterable of edk2 architectures supported by this build '''
|
''' return iterable of edk2 architectures supported by this build '''
|
||||||
return ("IA32",
|
return (
|
||||||
|
"IA32",
|
||||||
"X64",
|
"X64",
|
||||||
"ARM",
|
"ARM",
|
||||||
"AARCH64")
|
"AARCH64",
|
||||||
|
"RISCV64")
|
||||||
|
|
||||||
def GetTargetsSupported(self):
|
def GetTargetsSupported(self):
|
||||||
''' return iterable of edk2 target tags supported by this build '''
|
''' return iterable of edk2 target tags supported by this build '''
|
||||||
@@ -117,7 +124,7 @@ class Settings(CiBuildSettingsManager, UpdateSettingsManager, SetupSettingsManag
|
|||||||
|
|
||||||
def GetActiveScopes(self):
|
def GetActiveScopes(self):
|
||||||
''' return tuple containing scopes that should be active for this process '''
|
''' return tuple containing scopes that should be active for this process '''
|
||||||
scopes = ("cibuild","edk2-build")
|
scopes = ("cibuild", "edk2-build", "host-based-test")
|
||||||
|
|
||||||
self.ActualToolChainTag = shell_environment.GetBuildVars().GetValue("TOOL_CHAIN_TAG", "")
|
self.ActualToolChainTag = shell_environment.GetBuildVars().GetValue("TOOL_CHAIN_TAG", "")
|
||||||
|
|
||||||
@@ -126,6 +133,8 @@ class Settings(CiBuildSettingsManager, UpdateSettingsManager, SetupSettingsManag
|
|||||||
scopes += ("gcc_aarch64_linux",)
|
scopes += ("gcc_aarch64_linux",)
|
||||||
if "ARM" in self.ActualArchitectures:
|
if "ARM" in self.ActualArchitectures:
|
||||||
scopes += ("gcc_arm_linux",)
|
scopes += ("gcc_arm_linux",)
|
||||||
|
if "RISCV64" in self.ActualArchitectures:
|
||||||
|
scopes += ("gcc_riscv64_unknown",)
|
||||||
|
|
||||||
return scopes
|
return scopes
|
||||||
|
|
||||||
@@ -133,18 +142,27 @@ class Settings(CiBuildSettingsManager, UpdateSettingsManager, SetupSettingsManag
|
|||||||
''' return iterable containing RequiredSubmodule objects.
|
''' return iterable containing RequiredSubmodule objects.
|
||||||
If no RequiredSubmodules return an empty iterable
|
If no RequiredSubmodules return an empty iterable
|
||||||
'''
|
'''
|
||||||
rs=[]
|
rs = []
|
||||||
rs.append(RequiredSubmodule(
|
rs.append(RequiredSubmodule(
|
||||||
"ArmPkg/Library/ArmSoftFloatLib/berkeley-softfloat-3", False))
|
"ArmPkg/Library/ArmSoftFloatLib/berkeley-softfloat-3", False))
|
||||||
rs.append(RequiredSubmodule(
|
rs.append(RequiredSubmodule(
|
||||||
"CryptoPkg/Library/OpensslLib/openssl", False))
|
"CryptoPkg/Library/OpensslLib/openssl", False))
|
||||||
|
rs.append(RequiredSubmodule(
|
||||||
|
"UnitTestFrameworkPkg/Library/CmockaLib/cmocka", False))
|
||||||
|
rs.append(RequiredSubmodule(
|
||||||
|
"MdeModulePkg/Universal/RegularExpressionDxe/oniguruma", False))
|
||||||
|
rs.append(RequiredSubmodule(
|
||||||
|
"MdeModulePkg/Library/BrotliCustomDecompressLib/brotli", False))
|
||||||
|
rs.append(RequiredSubmodule(
|
||||||
|
"BaseTools/Source/C/BrotliCompress/brotli", False))
|
||||||
return rs
|
return rs
|
||||||
|
|
||||||
def GetName(self):
|
def GetName(self):
|
||||||
return "Edk2"
|
return "Edk2"
|
||||||
|
|
||||||
def GetDependencies(self):
|
def GetDependencies(self):
|
||||||
return []
|
return [
|
||||||
|
]
|
||||||
|
|
||||||
def GetPackagesPath(self):
|
def GetPackagesPath(self):
|
||||||
return ()
|
return ()
|
||||||
@@ -155,10 +173,11 @@ class Settings(CiBuildSettingsManager, UpdateSettingsManager, SetupSettingsManag
|
|||||||
|
|
||||||
def FilterPackagesToTest(self, changedFilesList: list, potentialPackagesList: list) -> list:
|
def FilterPackagesToTest(self, changedFilesList: list, potentialPackagesList: list) -> list:
|
||||||
''' Filter potential packages to test based on changed files. '''
|
''' Filter potential packages to test based on changed files. '''
|
||||||
build_these_packages=[]
|
build_these_packages = []
|
||||||
possible_packages=potentialPackagesList.copy()
|
possible_packages = potentialPackagesList.copy()
|
||||||
for f in changedFilesList:
|
for f in changedFilesList:
|
||||||
nodes=f.split("/") # split each part of path for comparison later
|
# split each part of path for comparison later
|
||||||
|
nodes = f.split("/")
|
||||||
|
|
||||||
# python file change in .pytool folder causes building all
|
# python file change in .pytool folder causes building all
|
||||||
if f.endswith(".py") and ".pytool" in nodes:
|
if f.endswith(".py") and ".pytool" in nodes:
|
||||||
|
@@ -100,7 +100,7 @@ class CharEncodingCheck(ICiBuildPlugin):
|
|||||||
overall_status += 1
|
overall_status += 1
|
||||||
|
|
||||||
tc.LogStdOut("Tested Encoding on {0} files".format(files_tested))
|
tc.LogStdOut("Tested Encoding on {0} files".format(files_tested))
|
||||||
if overall_status is not 0:
|
if overall_status != 0:
|
||||||
tc.SetFailed("CharEncoding {0} Failed. Errors {1}".format(packagename, overall_status), "CHAR_ENCODING_CHECK_FAILED")
|
tc.SetFailed("CharEncoding {0} Failed. Errors {1}".format(packagename, overall_status), "CHAR_ENCODING_CHECK_FAILED")
|
||||||
else:
|
else:
|
||||||
tc.SetSuccess()
|
tc.SetSuccess()
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
# @file HostUnitTestCompiler_plugin.py
|
# @file CompilerPlugin.py
|
||||||
##
|
##
|
||||||
# Copyright (c) Microsoft Corporation.
|
# Copyright (c) Microsoft Corporation.
|
||||||
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
@@ -42,7 +42,7 @@ class CompilerPlugin(ICiBuildPlugin):
|
|||||||
return ["DEBUG", "RELEASE"]
|
return ["DEBUG", "RELEASE"]
|
||||||
|
|
||||||
##
|
##
|
||||||
# External function of plugin. This function is used to perform the task of the MuBuild Plugin
|
# External function of plugin. This function is used to perform the task of the ICiBuildPlugin Plugin
|
||||||
#
|
#
|
||||||
# - package is the edk2 path to package. This means workspace/packagepath relative.
|
# - package is the edk2 path to package. This means workspace/packagepath relative.
|
||||||
# - edk2path object configured with workspace and packages path
|
# - edk2path object configured with workspace and packages path
|
||||||
|
@@ -113,7 +113,7 @@ class DependencyCheck(ICiBuildPlugin):
|
|||||||
overall_status += 1
|
overall_status += 1
|
||||||
|
|
||||||
# If XML object exists, add results
|
# If XML object exists, add results
|
||||||
if overall_status is not 0:
|
if overall_status != 0:
|
||||||
tc.SetFailed("Failed with {0} errors".format(overall_status), "DEPENDENCYCHECK_FAILED")
|
tc.SetFailed("Failed with {0} errors".format(overall_status), "DEPENDENCYCHECK_FAILED")
|
||||||
else:
|
else:
|
||||||
tc.SetSuccess()
|
tc.SetSuccess()
|
||||||
|
@@ -54,21 +54,25 @@ class DscCompleteCheck(ICiBuildPlugin):
|
|||||||
# Parse the config for required DscPath element
|
# Parse the config for required DscPath element
|
||||||
if "DscPath" not in pkgconfig:
|
if "DscPath" not in pkgconfig:
|
||||||
tc.SetSkipped()
|
tc.SetSkipped()
|
||||||
tc.LogStdError("DscPath not found in config file. Nothing to check.")
|
tc.LogStdError(
|
||||||
|
"DscPath not found in config file. Nothing to check.")
|
||||||
return -1
|
return -1
|
||||||
|
|
||||||
abs_pkg_path = Edk2pathObj.GetAbsolutePathOnThisSytemFromEdk2RelativePath(packagename)
|
abs_pkg_path = Edk2pathObj.GetAbsolutePathOnThisSytemFromEdk2RelativePath(
|
||||||
|
packagename)
|
||||||
abs_dsc_path = os.path.join(abs_pkg_path, pkgconfig["DscPath"].strip())
|
abs_dsc_path = os.path.join(abs_pkg_path, pkgconfig["DscPath"].strip())
|
||||||
wsr_dsc_path = Edk2pathObj.GetEdk2RelativePathFromAbsolutePath(abs_dsc_path)
|
wsr_dsc_path = Edk2pathObj.GetEdk2RelativePathFromAbsolutePath(
|
||||||
|
abs_dsc_path)
|
||||||
|
|
||||||
if abs_dsc_path is None or wsr_dsc_path is "" or not os.path.isfile(abs_dsc_path):
|
if abs_dsc_path is None or wsr_dsc_path == "" or not os.path.isfile(abs_dsc_path):
|
||||||
tc.SetSkipped()
|
tc.SetSkipped()
|
||||||
tc.LogStdError("Package Dsc not found")
|
tc.LogStdError("Package Dsc not found")
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
# Get INF Files
|
# Get INF Files
|
||||||
INFFiles = self.WalkDirectoryForExtension([".inf"], abs_pkg_path)
|
INFFiles = self.WalkDirectoryForExtension([".inf"], abs_pkg_path)
|
||||||
INFFiles = [Edk2pathObj.GetEdk2RelativePathFromAbsolutePath(x) for x in INFFiles] # make edk2relative path so can compare with DSC
|
INFFiles = [Edk2pathObj.GetEdk2RelativePathFromAbsolutePath(
|
||||||
|
x) for x in INFFiles] # make edk2relative path so can compare with DSC
|
||||||
|
|
||||||
# remove ignores
|
# remove ignores
|
||||||
|
|
||||||
@@ -79,8 +83,10 @@ class DscCompleteCheck(ICiBuildPlugin):
|
|||||||
tc.LogStdOut("Ignoring INF {0}".format(a))
|
tc.LogStdOut("Ignoring INF {0}".format(a))
|
||||||
INFFiles.remove(a)
|
INFFiles.remove(a)
|
||||||
except:
|
except:
|
||||||
tc.LogStdError("DscCompleteCheck.IgnoreInf -> {0} not found in filesystem. Invalid ignore file".format(a))
|
tc.LogStdError(
|
||||||
logging.info("DscCompleteCheck.IgnoreInf -> {0} not found in filesystem. Invalid ignore file".format(a))
|
"DscCompleteCheck.IgnoreInf -> {0} not found in filesystem. Invalid ignore file".format(a))
|
||||||
|
logging.info(
|
||||||
|
"DscCompleteCheck.IgnoreInf -> {0} not found in filesystem. Invalid ignore file".format(a))
|
||||||
|
|
||||||
# DSC Parser
|
# DSC Parser
|
||||||
dp = DscParser()
|
dp = DscParser()
|
||||||
@@ -99,11 +105,19 @@ class DscCompleteCheck(ICiBuildPlugin):
|
|||||||
infp.SetPackagePaths(Edk2pathObj.PackagePathList)
|
infp.SetPackagePaths(Edk2pathObj.PackagePathList)
|
||||||
infp.ParseFile(INF)
|
infp.ParseFile(INF)
|
||||||
if("MODULE_TYPE" not in infp.Dict):
|
if("MODULE_TYPE" not in infp.Dict):
|
||||||
tc.LogStdOut("Ignoring INF. Missing key for MODULE_TYPE {0}".format(INF))
|
tc.LogStdOut(
|
||||||
|
"Ignoring INF. Missing key for MODULE_TYPE {0}".format(INF))
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if(infp.Dict["MODULE_TYPE"] == "HOST_APPLICATION"):
|
if(infp.Dict["MODULE_TYPE"] == "HOST_APPLICATION"):
|
||||||
tc.LogStdOut("Ignoring INF. Module type is HOST_APPLICATION {0}".format(INF))
|
tc.LogStdOut(
|
||||||
|
"Ignoring INF. Module type is HOST_APPLICATION {0}".format(INF))
|
||||||
|
continue
|
||||||
|
|
||||||
|
if len(infp.SupportedPhases) == 1 and \
|
||||||
|
"HOST_APPLICATION" in infp.SupportedPhases:
|
||||||
|
tc.LogStdOut(
|
||||||
|
"Ignoring Library INF due to only supporting type HOST_APPLICATION {0}".format(INF))
|
||||||
continue
|
continue
|
||||||
|
|
||||||
logging.critical(INF + " not in " + wsr_dsc_path)
|
logging.critical(INF + " not in " + wsr_dsc_path)
|
||||||
@@ -111,8 +125,9 @@ class DscCompleteCheck(ICiBuildPlugin):
|
|||||||
overall_status = overall_status + 1
|
overall_status = overall_status + 1
|
||||||
|
|
||||||
# If XML object exists, add result
|
# If XML object exists, add result
|
||||||
if overall_status is not 0:
|
if overall_status != 0:
|
||||||
tc.SetFailed("DscCompleteCheck {0} Failed. Errors {1}".format(wsr_dsc_path, overall_status), "CHECK_FAILED")
|
tc.SetFailed("DscCompleteCheck {0} Failed. Errors {1}".format(
|
||||||
|
wsr_dsc_path, overall_status), "CHECK_FAILED")
|
||||||
else:
|
else:
|
||||||
tc.SetSuccess()
|
tc.SetSuccess()
|
||||||
return overall_status
|
return overall_status
|
||||||
|
@@ -7,6 +7,11 @@ that it would not be built if the package were built). This is critical because
|
|||||||
much of the CI infrastructure assumes that all modules will be listed in the DSC
|
much of the CI infrastructure assumes that all modules will be listed in the DSC
|
||||||
and compiled.
|
and compiled.
|
||||||
|
|
||||||
|
This test will ignore INFs in the following cases:
|
||||||
|
|
||||||
|
1. When MODULE_TYPE = HOST_APPLICATION
|
||||||
|
2. When a Library instance **only** supports the HOST_APPLICATION environment
|
||||||
|
|
||||||
## Configuration
|
## Configuration
|
||||||
|
|
||||||
The plugin has a few configuration options to support the UEFI codebase.
|
The plugin has a few configuration options to support the UEFI codebase.
|
||||||
@@ -14,7 +19,7 @@ The plugin has a few configuration options to support the UEFI codebase.
|
|||||||
``` yaml
|
``` yaml
|
||||||
"DscCompleteCheck": {
|
"DscCompleteCheck": {
|
||||||
"DscPath": "", # Path to dsc from root of package
|
"DscPath": "", # Path to dsc from root of package
|
||||||
"IgnoreInf": [] # Ignore INF if found in filesystem by not dsc
|
"IgnoreInf": [] # Ignore INF if found in filesystem but not dsc
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@@ -221,7 +221,7 @@ class GuidCheck(ICiBuildPlugin):
|
|||||||
|
|
||||||
# add result to test case
|
# add result to test case
|
||||||
overall_status = len(Errors)
|
overall_status = len(Errors)
|
||||||
if overall_status is not 0:
|
if overall_status != 0:
|
||||||
tc.SetFailed("GuidCheck {0} Failed. Errors {1}".format(
|
tc.SetFailed("GuidCheck {0} Failed. Errors {1}".format(
|
||||||
packagename, overall_status), "CHECK_FAILED")
|
packagename, overall_status), "CHECK_FAILED")
|
||||||
else:
|
else:
|
||||||
|
@@ -0,0 +1,149 @@
|
|||||||
|
# @file HostUnitTestCompilerPlugin.py
|
||||||
|
##
|
||||||
|
# Copyright (c) Microsoft Corporation.
|
||||||
|
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
|
##
|
||||||
|
|
||||||
|
import logging
|
||||||
|
import os
|
||||||
|
import re
|
||||||
|
from edk2toollib.uefi.edk2.parsers.dsc_parser import DscParser
|
||||||
|
from edk2toolext.environment.plugintypes.ci_build_plugin import ICiBuildPlugin
|
||||||
|
from edk2toolext.environment.uefi_build import UefiBuilder
|
||||||
|
from edk2toolext import edk2_logging
|
||||||
|
from edk2toolext.environment.var_dict import VarDict
|
||||||
|
from edk2toollib.utility_functions import GetHostInfo
|
||||||
|
|
||||||
|
|
||||||
|
class HostUnitTestCompilerPlugin(ICiBuildPlugin):
|
||||||
|
"""
|
||||||
|
A CiBuildPlugin that compiles the dsc for host based unit test apps.
|
||||||
|
An IUefiBuildPlugin may be attached to this plugin that will run the
|
||||||
|
unit tests and collect the results after successful compilation.
|
||||||
|
|
||||||
|
Configuration options:
|
||||||
|
"HostUnitTestCompilerPlugin": {
|
||||||
|
"DscPath": "<path to dsc from root of pkg>"
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
|
||||||
|
def GetTestName(self, packagename: str, environment: VarDict) -> tuple:
|
||||||
|
""" Provide the testcase name and classname for use in reporting
|
||||||
|
testclassname: a descriptive string for the testcase can include whitespace
|
||||||
|
classname: should be patterned <packagename>.<plugin>.<optionally any unique condition>
|
||||||
|
|
||||||
|
Args:
|
||||||
|
packagename: string containing name of package to build
|
||||||
|
environment: The VarDict for the test to run in
|
||||||
|
Returns:
|
||||||
|
a tuple containing the testcase name and the classname
|
||||||
|
(testcasename, classname)
|
||||||
|
"""
|
||||||
|
num,types = self.__GetHostUnitTestArch(environment)
|
||||||
|
types = types.replace(" ", "_")
|
||||||
|
|
||||||
|
return ("Compile and Run Host-Based UnitTests for " + packagename + " on arch " + types,
|
||||||
|
packagename + ".HostUnitTestCompiler." + types)
|
||||||
|
|
||||||
|
def RunsOnTargetList(self):
|
||||||
|
return ["NOOPT"]
|
||||||
|
|
||||||
|
#
|
||||||
|
# Find the intersection of application types that can run on this host
|
||||||
|
# and the TARGET_ARCH being build in this request.
|
||||||
|
#
|
||||||
|
# return tuple with (number of UEFI arch types, space separated string)
|
||||||
|
def __GetHostUnitTestArch(self, environment):
|
||||||
|
requested = environment.GetValue("TARGET_ARCH").split(' ')
|
||||||
|
host = []
|
||||||
|
if GetHostInfo().arch == 'x86':
|
||||||
|
#assume 64bit can handle 64 and 32
|
||||||
|
#assume 32bit can only handle 32
|
||||||
|
## change once IA32 issues resolved host.append("IA32")
|
||||||
|
if GetHostInfo().bit == '64':
|
||||||
|
host.append("X64")
|
||||||
|
elif GetHostInfo().arch == 'ARM':
|
||||||
|
if GetHostInfo().bit == '64':
|
||||||
|
host.append("AARCH64")
|
||||||
|
elif GetHostInfo().bit == '32':
|
||||||
|
host.append("ARM")
|
||||||
|
|
||||||
|
willrun = set(requested) & set(host)
|
||||||
|
return (len(willrun), " ".join(willrun))
|
||||||
|
|
||||||
|
|
||||||
|
##
|
||||||
|
# External function of plugin. This function is used to perform the task of the ICiBuildPlugin Plugin
|
||||||
|
#
|
||||||
|
# - package is the edk2 path to package. This means workspace/packagepath relative.
|
||||||
|
# - edk2path object configured with workspace and packages path
|
||||||
|
# - PkgConfig Object (dict) for the pkg
|
||||||
|
# - EnvConfig Object
|
||||||
|
# - Plugin Manager Instance
|
||||||
|
# - Plugin Helper Obj Instance
|
||||||
|
# - Junit Logger
|
||||||
|
# - output_stream the StringIO output stream from this plugin via logging
|
||||||
|
def RunBuildPlugin(self, packagename, Edk2pathObj, pkgconfig, environment, PLM, PLMHelper, tc, output_stream=None):
|
||||||
|
self._env = environment
|
||||||
|
environment.SetValue("CI_BUILD_TYPE", "host_unit_test", "Set in HostUnitTestCompilerPlugin")
|
||||||
|
|
||||||
|
# Parse the config for required DscPath element
|
||||||
|
if "DscPath" not in pkgconfig:
|
||||||
|
tc.SetSkipped()
|
||||||
|
tc.LogStdError("DscPath not found in config file. Nothing to compile for HostBasedUnitTests.")
|
||||||
|
return -1
|
||||||
|
|
||||||
|
AP = Edk2pathObj.GetAbsolutePathOnThisSytemFromEdk2RelativePath(packagename)
|
||||||
|
|
||||||
|
APDSC = os.path.join(AP, pkgconfig["DscPath"].strip())
|
||||||
|
AP_Path = Edk2pathObj.GetEdk2RelativePathFromAbsolutePath(APDSC)
|
||||||
|
if AP is None or AP_Path is None or not os.path.isfile(APDSC):
|
||||||
|
tc.SetSkipped()
|
||||||
|
tc.LogStdError("Package HostBasedUnitTest Dsc not found.")
|
||||||
|
return -1
|
||||||
|
|
||||||
|
logging.info("Building {0}".format(AP_Path))
|
||||||
|
self._env.SetValue("ACTIVE_PLATFORM", AP_Path, "Set in Compiler Plugin")
|
||||||
|
num, RUNNABLE_ARCHITECTURES = self.__GetHostUnitTestArch(environment)
|
||||||
|
if(num == 0):
|
||||||
|
tc.SetSkipped()
|
||||||
|
tc.LogStdError("No host architecture compatibility")
|
||||||
|
return -1
|
||||||
|
|
||||||
|
if not environment.SetValue("TARGET_ARCH",
|
||||||
|
RUNNABLE_ARCHITECTURES,
|
||||||
|
"Update Target Arch based on Host Support"):
|
||||||
|
#use AllowOverride function since this is a controlled attempt to change
|
||||||
|
environment.AllowOverride("TARGET_ARCH")
|
||||||
|
if not environment.SetValue("TARGET_ARCH",
|
||||||
|
RUNNABLE_ARCHITECTURES,
|
||||||
|
"Update Target Arch based on Host Support"):
|
||||||
|
raise RuntimeError("Can't Change TARGET_ARCH as required")
|
||||||
|
|
||||||
|
# Parse DSC to check for SUPPORTED_ARCHITECTURES
|
||||||
|
dp = DscParser()
|
||||||
|
dp.SetBaseAbsPath(Edk2pathObj.WorkspacePath)
|
||||||
|
dp.SetPackagePaths(Edk2pathObj.PackagePathList)
|
||||||
|
dp.ParseFile(AP_Path)
|
||||||
|
if "SUPPORTED_ARCHITECTURES" in dp.LocalVars:
|
||||||
|
SUPPORTED_ARCHITECTURES = dp.LocalVars["SUPPORTED_ARCHITECTURES"].split('|')
|
||||||
|
TARGET_ARCHITECTURES = environment.GetValue("TARGET_ARCH").split(' ')
|
||||||
|
|
||||||
|
# Skip if there is no intersection between SUPPORTED_ARCHITECTURES and TARGET_ARCHITECTURES
|
||||||
|
if len(set(SUPPORTED_ARCHITECTURES) & set(TARGET_ARCHITECTURES)) == 0:
|
||||||
|
tc.SetSkipped()
|
||||||
|
tc.LogStdError("No supported architecutres to build for host unit tests")
|
||||||
|
return -1
|
||||||
|
|
||||||
|
uefiBuilder = UefiBuilder()
|
||||||
|
# do all the steps
|
||||||
|
# WorkSpace, PackagesPath, PInHelper, PInManager
|
||||||
|
ret = uefiBuilder.Go(Edk2pathObj.WorkspacePath, os.pathsep.join(Edk2pathObj.PackagePathList), PLMHelper, PLM)
|
||||||
|
if ret != 0: # failure:
|
||||||
|
tc.SetFailed("Compile failed for {0}".format(packagename), "Compile_FAILED")
|
||||||
|
tc.LogStdError("{0} Compile failed with error code {1} ".format(AP_Path, ret))
|
||||||
|
return 1
|
||||||
|
|
||||||
|
else:
|
||||||
|
tc.SetSuccess()
|
||||||
|
return 0
|
@@ -0,0 +1,12 @@
|
|||||||
|
##
|
||||||
|
# CiBuildPlugin used to build anything that identifies
|
||||||
|
# as a unit test.
|
||||||
|
#
|
||||||
|
# Copyright (c) Microsoft Corporation.
|
||||||
|
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
|
##
|
||||||
|
{
|
||||||
|
"scope": "host-based-test",
|
||||||
|
"name": "Host Unit Test Compiler Plugin",
|
||||||
|
"module": "HostUnitTestCompilerPlugin"
|
||||||
|
}
|
24
.pytool/Plugin/HostUnitTestCompilerPlugin/Readme.md
Normal file
24
.pytool/Plugin/HostUnitTestCompilerPlugin/Readme.md
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
# Host UnitTest Compiler Plugin
|
||||||
|
|
||||||
|
A CiBuildPlugin that compiles the dsc for host based unit test apps.
|
||||||
|
An IUefiBuildPlugin may be attached to this plugin that will run the unit tests and collect the results after successful compilation.
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
The package relative path of the DSC file to build.
|
||||||
|
|
||||||
|
``` yaml
|
||||||
|
"HostUnitTestCompilerPlugin": {
|
||||||
|
"DscPath": "<path to dsc from root of pkg>"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### DscPath
|
||||||
|
|
||||||
|
Package relative path to the DSC file to build.
|
||||||
|
|
||||||
|
## Copyright
|
||||||
|
|
||||||
|
Copyright (c) Microsoft Corporation.
|
||||||
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
|
|
@@ -0,0 +1,140 @@
|
|||||||
|
# @file HostUnitTestDscCompleteCheck.py
|
||||||
|
#
|
||||||
|
# This is a copy of DscCompleteCheck with different filtering logic.
|
||||||
|
# It should be discussed if this should be one plugin
|
||||||
|
#
|
||||||
|
# Copyright (c) Microsoft Corporation.
|
||||||
|
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
|
##
|
||||||
|
import logging
|
||||||
|
import os
|
||||||
|
from edk2toolext.environment.plugintypes.ci_build_plugin import ICiBuildPlugin
|
||||||
|
from edk2toollib.uefi.edk2.parsers.dsc_parser import DscParser
|
||||||
|
from edk2toollib.uefi.edk2.parsers.inf_parser import InfParser
|
||||||
|
from edk2toolext.environment.var_dict import VarDict
|
||||||
|
|
||||||
|
|
||||||
|
class HostUnitTestDscCompleteCheck(ICiBuildPlugin):
|
||||||
|
"""
|
||||||
|
A CiBuildPlugin that scans the package Host Unit Test dsc file and confirms all Host application modules (inf files) are
|
||||||
|
listed in the components sections.
|
||||||
|
|
||||||
|
Configuration options:
|
||||||
|
"HostUnitTestDscCompleteCheck": {
|
||||||
|
"DscPath": "", # Path to Host based unit test DSC file
|
||||||
|
"IgnoreInf": [] # Ignore INF if found in filesystem but not dsc
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
|
||||||
|
def GetTestName(self, packagename: str, environment: VarDict) -> tuple:
|
||||||
|
""" Provide the testcase name and classname for use in reporting
|
||||||
|
|
||||||
|
Args:
|
||||||
|
packagename: string containing name of package to build
|
||||||
|
environment: The VarDict for the test to run in
|
||||||
|
Returns:
|
||||||
|
a tuple containing the testcase name and the classname
|
||||||
|
(testcasename, classname)
|
||||||
|
testclassname: a descriptive string for the testcase can include whitespace
|
||||||
|
classname: should be patterned <packagename>.<plugin>.<optionally any unique condition>
|
||||||
|
"""
|
||||||
|
return ("Check the " + packagename + " Host Unit Test DSC for a being complete", packagename + ".HostUnitTestDscCompleteCheck")
|
||||||
|
|
||||||
|
##
|
||||||
|
# External function of plugin. This function is used to perform the task of the MuBuild Plugin
|
||||||
|
#
|
||||||
|
# - package is the edk2 path to package. This means workspace/packagepath relative.
|
||||||
|
# - edk2path object configured with workspace and packages path
|
||||||
|
# - PkgConfig Object (dict) for the pkg
|
||||||
|
# - VarDict containing the shell environment Build Vars
|
||||||
|
# - Plugin Manager Instance
|
||||||
|
# - Plugin Helper Obj Instance
|
||||||
|
# - Junit Logger
|
||||||
|
# - output_stream the StringIO output stream from this plugin via logging
|
||||||
|
def RunBuildPlugin(self, packagename, Edk2pathObj, pkgconfig, environment, PLM, PLMHelper, tc, output_stream=None):
|
||||||
|
overall_status = 0
|
||||||
|
|
||||||
|
# Parse the config for required DscPath element
|
||||||
|
if "DscPath" not in pkgconfig:
|
||||||
|
tc.SetSkipped()
|
||||||
|
tc.LogStdError(
|
||||||
|
"DscPath not found in config file. Nothing to check.")
|
||||||
|
return -1
|
||||||
|
|
||||||
|
abs_pkg_path = Edk2pathObj.GetAbsolutePathOnThisSytemFromEdk2RelativePath(
|
||||||
|
packagename)
|
||||||
|
abs_dsc_path = os.path.join(abs_pkg_path, pkgconfig["DscPath"].strip())
|
||||||
|
wsr_dsc_path = Edk2pathObj.GetEdk2RelativePathFromAbsolutePath(
|
||||||
|
abs_dsc_path)
|
||||||
|
|
||||||
|
if abs_dsc_path is None or wsr_dsc_path == "" or not os.path.isfile(abs_dsc_path):
|
||||||
|
tc.SetSkipped()
|
||||||
|
tc.LogStdError("Package Host Unit Test Dsc not found")
|
||||||
|
return 0
|
||||||
|
|
||||||
|
# Get INF Files
|
||||||
|
INFFiles = self.WalkDirectoryForExtension([".inf"], abs_pkg_path)
|
||||||
|
INFFiles = [Edk2pathObj.GetEdk2RelativePathFromAbsolutePath(
|
||||||
|
x) for x in INFFiles] # make edk2relative path so can compare with DSC
|
||||||
|
|
||||||
|
# remove ignores
|
||||||
|
|
||||||
|
if "IgnoreInf" in pkgconfig:
|
||||||
|
for a in pkgconfig["IgnoreInf"]:
|
||||||
|
a = a.replace(os.sep, "/")
|
||||||
|
try:
|
||||||
|
tc.LogStdOut("Ignoring INF {0}".format(a))
|
||||||
|
INFFiles.remove(a)
|
||||||
|
except:
|
||||||
|
tc.LogStdError(
|
||||||
|
"HostUnitTestDscCompleteCheck.IgnoreInf -> {0} not found in filesystem. Invalid ignore file".format(a))
|
||||||
|
logging.info(
|
||||||
|
"HostUnitTestDscCompleteCheck.IgnoreInf -> {0} not found in filesystem. Invalid ignore file".format(a))
|
||||||
|
|
||||||
|
# DSC Parser
|
||||||
|
dp = DscParser()
|
||||||
|
dp.SetBaseAbsPath(Edk2pathObj.WorkspacePath)
|
||||||
|
dp.SetPackagePaths(Edk2pathObj.PackagePathList)
|
||||||
|
dp.SetInputVars(environment.GetAllBuildKeyValues())
|
||||||
|
dp.ParseFile(wsr_dsc_path)
|
||||||
|
|
||||||
|
# Check if INF in component section
|
||||||
|
for INF in INFFiles:
|
||||||
|
if not any(INF.strip() in x for x in dp.ThreeMods) and \
|
||||||
|
not any(INF.strip() in x for x in dp.SixMods) and \
|
||||||
|
not any(INF.strip() in x for x in dp.OtherMods):
|
||||||
|
|
||||||
|
infp = InfParser().SetBaseAbsPath(Edk2pathObj.WorkspacePath)
|
||||||
|
infp.SetPackagePaths(Edk2pathObj.PackagePathList)
|
||||||
|
infp.ParseFile(INF)
|
||||||
|
if("MODULE_TYPE" not in infp.Dict):
|
||||||
|
tc.LogStdOut(
|
||||||
|
"Ignoring INF. Missing key for MODULE_TYPE {0}".format(INF))
|
||||||
|
continue
|
||||||
|
|
||||||
|
if(infp.Dict["MODULE_TYPE"] == "HOST_APPLICATION"):
|
||||||
|
# should compile test a library that is declared type HOST_APPLICATION
|
||||||
|
pass
|
||||||
|
|
||||||
|
elif len(infp.SupportedPhases) > 0 and \
|
||||||
|
"HOST_APPLICATION" in infp.SupportedPhases:
|
||||||
|
# should compile test a library that supports HOST_APPLICATION but
|
||||||
|
# require it to be an explicit opt-in
|
||||||
|
pass
|
||||||
|
|
||||||
|
else:
|
||||||
|
tc.LogStdOut(
|
||||||
|
"Ignoring INF. MODULE_TYPE or suppored phases not HOST_APPLICATION {0}".format(INF))
|
||||||
|
continue
|
||||||
|
|
||||||
|
logging.critical(INF + " not in " + wsr_dsc_path)
|
||||||
|
tc.LogStdError("{0} not in {1}".format(INF, wsr_dsc_path))
|
||||||
|
overall_status = overall_status + 1
|
||||||
|
|
||||||
|
# If XML object exists, add result
|
||||||
|
if overall_status != 0:
|
||||||
|
tc.SetFailed("HostUnitTestDscCompleteCheck {0} Failed. Errors {1}".format(
|
||||||
|
wsr_dsc_path, overall_status), "CHECK_FAILED")
|
||||||
|
else:
|
||||||
|
tc.SetSuccess()
|
||||||
|
return overall_status
|
@@ -0,0 +1,12 @@
|
|||||||
|
##
|
||||||
|
# CiBuildPlugin used to confirm all INFs are listed in
|
||||||
|
# the components section of package dsc
|
||||||
|
#
|
||||||
|
# Copyright (c) Microsoft Corporation.
|
||||||
|
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
|
##
|
||||||
|
{
|
||||||
|
"scope": "host-based-test",
|
||||||
|
"name": "Host Unit Test Dsc Complete Check Test",
|
||||||
|
"module": "HostUnitTestDscCompleteCheck"
|
||||||
|
}
|
32
.pytool/Plugin/HostUnitTestDscCompleteCheck/Readme.md
Normal file
32
.pytool/Plugin/HostUnitTestDscCompleteCheck/Readme.md
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
# Host Unit Test Dsc Complete Check Plugin
|
||||||
|
|
||||||
|
This CiBuildPlugin scans all INF files from a package for those related to host
|
||||||
|
based unit tests confirms they are listed in the unit test DSC file for the package.
|
||||||
|
The test considers it an error if any INF meeting the requirements does not appear
|
||||||
|
in the `Components` section of the unit test DSC. This is critical because
|
||||||
|
much of the CI infrastructure assumes that modules will be listed in the DSC
|
||||||
|
and compiled.
|
||||||
|
|
||||||
|
This test will only require INFs in the following cases:
|
||||||
|
|
||||||
|
1. When MODULE_TYPE = HOST_APPLICATION
|
||||||
|
2. When a Library instance supports the HOST_APPLICATION environment
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
The plugin has a few configuration options to support the UEFI codebase.
|
||||||
|
|
||||||
|
``` yaml
|
||||||
|
"HostUnitTestDscCompleteCheck": {
|
||||||
|
"DscPath": "", # Path to Host based unit test DSC file
|
||||||
|
"IgnoreInf": [] # Ignore INF if found in filesystem but not dsc
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### DscPath
|
||||||
|
|
||||||
|
Path to DSC to consider platform dsc
|
||||||
|
|
||||||
|
### IgnoreInf
|
||||||
|
|
||||||
|
Ignore error if Inf file is not listed in DSC file
|
@@ -67,7 +67,7 @@ class LibraryClassCheck(ICiBuildPlugin):
|
|||||||
abs_dec_path = self.__GetPkgDec(abs_pkg_path)
|
abs_dec_path = self.__GetPkgDec(abs_pkg_path)
|
||||||
wsr_dec_path = Edk2pathObj.GetEdk2RelativePathFromAbsolutePath(abs_dec_path)
|
wsr_dec_path = Edk2pathObj.GetEdk2RelativePathFromAbsolutePath(abs_dec_path)
|
||||||
|
|
||||||
if abs_dec_path is None or wsr_dec_path is "" or not os.path.isfile(abs_dec_path):
|
if abs_dec_path is None or wsr_dec_path == "" or not os.path.isfile(abs_dec_path):
|
||||||
tc.SetSkipped()
|
tc.SetSkipped()
|
||||||
tc.LogStdError("No DEC file {0} in package {1}".format(abs_dec_path, abs_pkg_path))
|
tc.LogStdError("No DEC file {0} in package {1}".format(abs_dec_path, abs_pkg_path))
|
||||||
return -1
|
return -1
|
||||||
@@ -146,7 +146,7 @@ class LibraryClassCheck(ICiBuildPlugin):
|
|||||||
|
|
||||||
|
|
||||||
# If XML object exists, add result
|
# If XML object exists, add result
|
||||||
if overall_status is not 0:
|
if overall_status != 0:
|
||||||
tc.SetFailed("LibraryClassCheck {0} Failed. Errors {1}".format(wsr_dec_path, overall_status), "CHECK_FAILED")
|
tc.SetFailed("LibraryClassCheck {0} Failed. Errors {1}".format(wsr_dec_path, overall_status), "CHECK_FAILED")
|
||||||
else:
|
else:
|
||||||
tc.SetSuccess()
|
tc.SetSuccess()
|
||||||
|
@@ -22,6 +22,8 @@
|
|||||||
],
|
],
|
||||||
"minWordLength": 5,
|
"minWordLength": 5,
|
||||||
"allowCompoundWords": false,
|
"allowCompoundWords": false,
|
||||||
|
"maxNumberOfProblems": 200,
|
||||||
|
"maxDuplicateProblems": 200,
|
||||||
"ignoreWords": [
|
"ignoreWords": [
|
||||||
"muchange"
|
"muchange"
|
||||||
],
|
],
|
||||||
@@ -161,5 +163,20 @@
|
|||||||
"bootability",
|
"bootability",
|
||||||
"Sdhci",
|
"Sdhci",
|
||||||
"inmodule",
|
"inmodule",
|
||||||
|
"RISCV",
|
||||||
|
"edksetup",
|
||||||
|
"iscsi",
|
||||||
|
"nvdata",
|
||||||
|
"pytools",
|
||||||
|
"NTDDI",
|
||||||
|
"Wnonportable",
|
||||||
|
"CLANGPDB",
|
||||||
|
"nologo",
|
||||||
|
"lldmap",
|
||||||
|
"ASMLINK",
|
||||||
|
"NODEFAULTLIB",
|
||||||
|
"vcruntimed",
|
||||||
|
"ucrtd",
|
||||||
|
"msvcrtd",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@@ -2,31 +2,32 @@
|
|||||||
|
|
||||||
## Basic Status
|
## Basic Status
|
||||||
|
|
||||||
| Package | Windows VS2019 (IA32/X64)| Ubuntu GCC (IA32/X64/ARM/AARCH64) | Known Issues |
|
| Package | Windows VS2019 (IA32/X64)| Ubuntu GCC (IA32/X64/ARM/AARCH64) | Known Issues |
|
||||||
| :---- | :----- | :---- | :--- |
|
| :---- | :----- | :---- | :--- |
|
||||||
| ArmPkg |
|
| ArmPkg |
|
||||||
| ArmPlatformPkg |
|
| ArmPlatformPkg |
|
||||||
| ArmVirtPkg |
|
| ArmVirtPkg | SEE PACKAGE README | SEE PACKAGE README |
|
||||||
| CryptoPkg | :heavy_check_mark: | :heavy_check_mark: | Spell checking in audit mode
|
| CryptoPkg | :heavy_check_mark: | :heavy_check_mark: | Spell checking in audit mode
|
||||||
| DynamicTablesPkg |
|
| DynamicTablesPkg |
|
||||||
| EmbeddedPkg |
|
| EmbeddedPkg |
|
||||||
| EmulatorPkg |
|
| EmulatorPkg | SEE PACKAGE README | SEE PACKAGE README | Spell checking in audit mode
|
||||||
| FatPkg | :heavy_check_mark: | :heavy_check_mark: |
|
| FatPkg | :heavy_check_mark: | :heavy_check_mark: |
|
||||||
| FmpDevicePkg | :heavy_check_mark: | :heavy_check_mark: |
|
| FmpDevicePkg | :heavy_check_mark: | :heavy_check_mark: |
|
||||||
| IntelFsp2Pkg |
|
| IntelFsp2Pkg |
|
||||||
| IntelFsp2WrapperPkg |
|
| IntelFsp2WrapperPkg |
|
||||||
| MdeModulePkg | :heavy_check_mark: | :heavy_check_mark: | DxeIpl dependency on ArmPkg, Depends on StandaloneMmPkg, Spell checking in audit mode
|
| MdeModulePkg | :heavy_check_mark: | :heavy_check_mark: | DxeIpl dependency on ArmPkg, Depends on StandaloneMmPkg, Spell checking in audit mode
|
||||||
| MdePkg | :heavy_check_mark: | :heavy_check_mark: | Spell checking in audit mode
|
| MdePkg | :heavy_check_mark: | :heavy_check_mark: | Spell checking in audit mode
|
||||||
| NetworkPkg | :heavy_check_mark: | :heavy_check_mark: | Spell checking in audit mode
|
| NetworkPkg | :heavy_check_mark: | :heavy_check_mark: | Spell checking in audit mode
|
||||||
| OvmfPkg |
|
| OvmfPkg | SEE PACKAGE README | SEE PACKAGE README | Spell checking in audit mode
|
||||||
| PcAtChipsetPkg | :heavy_check_mark: | :heavy_check_mark: |
|
| PcAtChipsetPkg | :heavy_check_mark: | :heavy_check_mark: |
|
||||||
| SecurityPkg | :heavy_check_mark: | :heavy_check_mark: | Spell checking in audit mode
|
| SecurityPkg | :heavy_check_mark: | :heavy_check_mark: | Spell checking in audit mode
|
||||||
| ShellPkg | :heavy_check_mark: | :heavy_check_mark: | Spell checking in audit mode, 3 modules are not being built by DSC
|
| ShellPkg | :heavy_check_mark: | :heavy_check_mark: | Spell checking in audit mode, 3 modules are not being built by DSC
|
||||||
| SignedCapsulePkg |
|
| SignedCapsulePkg |
|
||||||
| SourceLevelDebugPkg |
|
| SourceLevelDebugPkg |
|
||||||
| StandaloneMmPkg |
|
| StandaloneMmPkg |
|
||||||
| UefiCpuPkg | :heavy_check_mark: | :heavy_check_mark: | Spell checking in audit mode, 2 binary modules not being built by DSC
|
| UefiCpuPkg | :heavy_check_mark: | :heavy_check_mark: | Spell checking in audit mode, 2 binary modules not being built by DSC
|
||||||
| UefiPayloadPkg |
|
| UefiPayloadPkg |
|
||||||
|
| UnitTestFrameworkPkg | :heavy_check_mark: | :heavy_check_mark: |
|
||||||
|
|
||||||
For more detailed status look at the test results of the latest CI run on the
|
For more detailed status look at the test results of the latest CI run on the
|
||||||
repo readme.
|
repo readme.
|
||||||
@@ -77,7 +78,7 @@ per package configuration which comes from this file.
|
|||||||
## Running CI locally
|
## Running CI locally
|
||||||
|
|
||||||
The EDKII Tools environment (and by extension the ci) is designed to support
|
The EDKII Tools environment (and by extension the ci) is designed to support
|
||||||
easily and consistantly running locally and in a cloud ci environment. To do
|
easily and consistently running locally and in a cloud ci environment. To do
|
||||||
that a few steps should be followed. Details of EDKII Tools can be found in the
|
that a few steps should be followed. Details of EDKII Tools can be found in the
|
||||||
[docs folder here](https://github.com/tianocore/edk2-pytool-extensions/tree/master/docs)
|
[docs folder here](https://github.com/tianocore/edk2-pytool-extensions/tree/master/docs)
|
||||||
|
|
||||||
@@ -88,7 +89,7 @@ that a few steps should be followed. Details of EDKII Tools can be found in the
|
|||||||
* VS 2017 or VS 2019
|
* VS 2017 or VS 2019
|
||||||
* Windows SDK (for rc)
|
* Windows SDK (for rc)
|
||||||
* Windows WDK (for capsules)
|
* Windows WDK (for capsules)
|
||||||
* Ubuntu 16.04
|
* Ubuntu 18.04 or Fedora
|
||||||
* GCC5
|
* GCC5
|
||||||
* Easy to add more but this is the current state
|
* Easy to add more but this is the current state
|
||||||
2. Python 3.7.x or newer on path
|
2. Python 3.7.x or newer on path
|
||||||
@@ -137,11 +138,31 @@ location makes more sense for the community.
|
|||||||
|
|
||||||
### Module Inclusion Test - DscCompleteCheck
|
### Module Inclusion Test - DscCompleteCheck
|
||||||
|
|
||||||
This test scans all available modules (via INF files) and compares them to the
|
This scans all INF files from a package and confirms they are
|
||||||
package-level DSC file for the package each module is contained within. The test
|
listed in the package level DSC file. The test considers it an error if any INF
|
||||||
considers it an error if any module does not appear in the `Components` section
|
does not appear in the `Components` section of the package-level DSC (indicating
|
||||||
of at least one package-level DSC (indicating that it would not be built if the
|
that it would not be built if the package were built). This is critical because
|
||||||
package were built).
|
much of the CI infrastructure assumes that all modules will be listed in the DSC
|
||||||
|
and compiled.
|
||||||
|
|
||||||
|
This test will ignore INFs in the following cases:
|
||||||
|
|
||||||
|
1. When `MODULE_TYPE` = `HOST_APPLICATION`
|
||||||
|
2. When a Library instance **only** supports the `HOST_APPLICATION` environment
|
||||||
|
|
||||||
|
### Host Module Inclusion Test - HostUnitTestDscCompleteCheck
|
||||||
|
|
||||||
|
This test scans all INF files from a package for those related to host
|
||||||
|
based unit tests and confirms they are listed in the unit test DSC file for the package.
|
||||||
|
The test considers it an error if any INF meeting the requirements does not appear
|
||||||
|
in the `Components` section of the unit test DSC. This is critical because
|
||||||
|
much of the CI infrastructure assumes that modules will be listed in the DSC
|
||||||
|
and compiled.
|
||||||
|
|
||||||
|
This test will only require INFs in the following cases:
|
||||||
|
|
||||||
|
1. When `MODULE_TYPE` = `HOST_APPLICATION`
|
||||||
|
2. When a Library instance explicitly supports the `HOST_APPLICATION` environment
|
||||||
|
|
||||||
### Code Compilation Test - CompilerPlugin
|
### Code Compilation Test - CompilerPlugin
|
||||||
|
|
||||||
@@ -150,6 +171,46 @@ all package-level DSCs were built, the Code Compilation Test simply runs through
|
|||||||
and builds every package-level DSC on every toolchain and for every architecture
|
and builds every package-level DSC on every toolchain and for every architecture
|
||||||
that is supported. Any module that fails to build is considered an error.
|
that is supported. Any module that fails to build is considered an error.
|
||||||
|
|
||||||
|
### Host Unit Test Compilation and Run Test - HostUnitTestCompilerPlugin
|
||||||
|
|
||||||
|
A test that compiles the dsc for host based unit test apps.
|
||||||
|
On Windows this will also enable a build plugin to execute that will run the unit tests and verify the results.
|
||||||
|
|
||||||
|
These tools will be invoked on any CI
|
||||||
|
pass that includes the NOOPT target. In order for these tools to do their job,
|
||||||
|
the package and tests must be configured in a particular way...
|
||||||
|
|
||||||
|
#### Including Host-Based Tests in the Package YAML
|
||||||
|
|
||||||
|
For example, looking at the `MdeModulePkg.ci.yaml` config file, there are two
|
||||||
|
config options that control HostBased test behavior:
|
||||||
|
|
||||||
|
```json
|
||||||
|
## options defined .pytool/Plugin/HostUnitTestCompilerPlugin
|
||||||
|
"HostUnitTestCompilerPlugin": {
|
||||||
|
"DscPath": "Test/MdeModulePkgHostTest.dsc"
|
||||||
|
},
|
||||||
|
```
|
||||||
|
|
||||||
|
This option tell the test builder to run. The test builder needs to know which
|
||||||
|
modules in this package are host-based tests, so that DSC path is provided.
|
||||||
|
|
||||||
|
#### Configuring the HostBased DSC
|
||||||
|
|
||||||
|
The HostBased DSC for `MdeModulePkg` is located at
|
||||||
|
`MdeModulePkg/Test/MdeModulePkgHostTest.dsc`.
|
||||||
|
|
||||||
|
To add automated host-based unit test building to a new package, create a
|
||||||
|
similar DSC. The new DSC should make sure to have the `NOOPT` BUILD_TARGET
|
||||||
|
and should include the line:
|
||||||
|
|
||||||
|
```
|
||||||
|
!include UnitTestFrameworkPkg/UnitTestFrameworkPkgHost.dsc.inc
|
||||||
|
```
|
||||||
|
|
||||||
|
All of the modules that are included in the `Components` section of this
|
||||||
|
DSC should be of type HOST_APPLICATION.
|
||||||
|
|
||||||
### GUID Uniqueness Test - GuidCheck
|
### GUID Uniqueness Test - GuidCheck
|
||||||
|
|
||||||
This test works on the collection of all packages rather than an individual
|
This test works on the collection of all packages rather than an individual
|
||||||
@@ -207,6 +268,8 @@ few standard scopes.
|
|||||||
| global-nix | edk2_invocable++ | Running on Linux based OS |
|
| global-nix | edk2_invocable++ | Running on Linux based OS |
|
||||||
| edk2-build | | This indicates that an invocable is building EDK2 based UEFI code |
|
| edk2-build | | This indicates that an invocable is building EDK2 based UEFI code |
|
||||||
| cibuild | set in .pytool/CISettings.py | Suggested target for edk2 continuous integration builds. Tools used for CiBuilds can use this scope. Example: asl compiler |
|
| cibuild | set in .pytool/CISettings.py | Suggested target for edk2 continuous integration builds. Tools used for CiBuilds can use this scope. Example: asl compiler |
|
||||||
|
| host-based-test | set in .pytool/CISettings.py | Turns on the host based tests and plugin |
|
||||||
|
| host-test-win | set in .pytool/CISettings.py | Enables the host based test runner for Windows |
|
||||||
|
|
||||||
## Future investments
|
## Future investments
|
||||||
|
|
||||||
@@ -216,8 +279,6 @@ few standard scopes.
|
|||||||
* Visual Studio AARCH64 and ARM support
|
* Visual Studio AARCH64 and ARM support
|
||||||
* BaseTools C tools CI/PR and binary release process
|
* BaseTools C tools CI/PR and binary release process
|
||||||
* BaseTools Python tools CI/PR process
|
* BaseTools Python tools CI/PR process
|
||||||
* Host based unit testing
|
|
||||||
* Extensible private/closed source platform reporting
|
* Extensible private/closed source platform reporting
|
||||||
* Platform builds, validation
|
|
||||||
* UEFI SCTs
|
* UEFI SCTs
|
||||||
* Other automation
|
* Other automation
|
||||||
|
@@ -78,10 +78,6 @@
|
|||||||
# Define if the GICv3 controller should use the GICv2 legacy
|
# Define if the GICv3 controller should use the GICv2 legacy
|
||||||
gArmTokenSpaceGuid.PcdArmGicV3WithV2Legacy|FALSE|BOOLEAN|0x00000042
|
gArmTokenSpaceGuid.PcdArmGicV3WithV2Legacy|FALSE|BOOLEAN|0x00000042
|
||||||
|
|
||||||
# Whether to implement warm reboot for capsule update using a jump back to the
|
|
||||||
# PEI entry point with caches and interrupts disabled.
|
|
||||||
gArmTokenSpaceGuid.PcdArmReenterPeiForCapsuleWarmReboot|FALSE|BOOLEAN|0x0000001F
|
|
||||||
|
|
||||||
[PcdsFeatureFlag.ARM]
|
[PcdsFeatureFlag.ARM]
|
||||||
# Whether to map normal memory as non-shareable. FALSE is the safe choice, but
|
# Whether to map normal memory as non-shareable. FALSE is the safe choice, but
|
||||||
# TRUE may be appropriate to fix performance problems if you don't care about
|
# TRUE may be appropriate to fix performance problems if you don't care about
|
||||||
|
@@ -4,6 +4,7 @@
|
|||||||
# Copyright (c) 2009 - 2010, Apple Inc. All rights reserved.<BR>
|
# Copyright (c) 2009 - 2010, Apple Inc. All rights reserved.<BR>
|
||||||
# Copyright (c) 2011 - 2018, ARM Ltd. All rights reserved.<BR>
|
# Copyright (c) 2011 - 2018, ARM Ltd. All rights reserved.<BR>
|
||||||
# Copyright (c) 2016, Linaro Ltd. All rights reserved.<BR>
|
# Copyright (c) 2016, Linaro Ltd. All rights reserved.<BR>
|
||||||
|
# Copyright (c) Microsoft Corporation.<BR>
|
||||||
#
|
#
|
||||||
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
#
|
#
|
||||||
@@ -133,11 +134,15 @@
|
|||||||
ArmPkg/Library/ArmGicArchLib/ArmGicArchLib.inf
|
ArmPkg/Library/ArmGicArchLib/ArmGicArchLib.inf
|
||||||
ArmPkg/Library/ArmGicArchSecLib/ArmGicArchSecLib.inf
|
ArmPkg/Library/ArmGicArchSecLib/ArmGicArchSecLib.inf
|
||||||
ArmPkg/Library/ArmLib/ArmBaseLib.inf
|
ArmPkg/Library/ArmLib/ArmBaseLib.inf
|
||||||
|
ArmPkg/Library/ArmMtlNullLib/ArmMtlNullLib.inf
|
||||||
ArmPkg/Library/ArmSoftFloatLib/ArmSoftFloatLib.inf
|
ArmPkg/Library/ArmSoftFloatLib/ArmSoftFloatLib.inf
|
||||||
|
ArmPkg/Library/ArmSmcPsciResetSystemLib/ArmSmcPsciResetSystemLib.inf
|
||||||
ArmPkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointerLib.inf
|
ArmPkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointerLib.inf
|
||||||
ArmPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
|
ArmPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
|
||||||
|
|
||||||
|
ArmPkg/Drivers/ArmCrashDumpDxe/ArmCrashDumpDxe.inf
|
||||||
ArmPkg/Drivers/ArmScmiDxe/ArmScmiDxe.inf
|
ArmPkg/Drivers/ArmScmiDxe/ArmScmiDxe.inf
|
||||||
|
ArmPkg/Drivers/MmCommunicationDxe/MmCommunication.inf
|
||||||
|
|
||||||
[Components.AARCH64]
|
[Components.AARCH64]
|
||||||
ArmPkg/Library/ArmMmuLib/ArmMmuPeiLib.inf
|
ArmPkg/Library/ArmMmuLib/ArmMmuPeiLib.inf
|
||||||
|
@@ -13,7 +13,68 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
|
|||||||
#include <Library/MemoryAllocationLib.h>
|
#include <Library/MemoryAllocationLib.h>
|
||||||
#include "CpuDxe.h"
|
#include "CpuDxe.h"
|
||||||
|
|
||||||
#define TT_ATTR_INDX_INVALID ((UINT32)~0)
|
#define INVALID_ENTRY ((UINT32)~0)
|
||||||
|
|
||||||
|
#define MIN_T0SZ 16
|
||||||
|
#define BITS_PER_LEVEL 9
|
||||||
|
|
||||||
|
STATIC
|
||||||
|
VOID
|
||||||
|
GetRootTranslationTableInfo (
|
||||||
|
IN UINTN T0SZ,
|
||||||
|
OUT UINTN *RootTableLevel,
|
||||||
|
OUT UINTN *RootTableEntryCount
|
||||||
|
)
|
||||||
|
{
|
||||||
|
*RootTableLevel = (T0SZ - MIN_T0SZ) / BITS_PER_LEVEL;
|
||||||
|
*RootTableEntryCount = TT_ENTRY_COUNT >> (T0SZ - MIN_T0SZ) % BITS_PER_LEVEL;
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC
|
||||||
|
UINT64
|
||||||
|
PageAttributeToGcdAttribute (
|
||||||
|
IN UINT64 PageAttributes
|
||||||
|
)
|
||||||
|
{
|
||||||
|
UINT64 GcdAttributes;
|
||||||
|
|
||||||
|
switch (PageAttributes & TT_ATTR_INDX_MASK) {
|
||||||
|
case TT_ATTR_INDX_DEVICE_MEMORY:
|
||||||
|
GcdAttributes = EFI_MEMORY_UC;
|
||||||
|
break;
|
||||||
|
case TT_ATTR_INDX_MEMORY_NON_CACHEABLE:
|
||||||
|
GcdAttributes = EFI_MEMORY_WC;
|
||||||
|
break;
|
||||||
|
case TT_ATTR_INDX_MEMORY_WRITE_THROUGH:
|
||||||
|
GcdAttributes = EFI_MEMORY_WT;
|
||||||
|
break;
|
||||||
|
case TT_ATTR_INDX_MEMORY_WRITE_BACK:
|
||||||
|
GcdAttributes = EFI_MEMORY_WB;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
DEBUG ((DEBUG_ERROR,
|
||||||
|
"PageAttributeToGcdAttribute: PageAttributes:0x%lX not supported.\n",
|
||||||
|
PageAttributes));
|
||||||
|
ASSERT (0);
|
||||||
|
// The Global Coherency Domain (GCD) value is defined as a bit set.
|
||||||
|
// Returning 0 means no attribute has been set.
|
||||||
|
GcdAttributes = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Determine protection attributes
|
||||||
|
if (((PageAttributes & TT_AP_MASK) == TT_AP_NO_RO) ||
|
||||||
|
((PageAttributes & TT_AP_MASK) == TT_AP_RO_RO)) {
|
||||||
|
// Read only cases map to write-protect
|
||||||
|
GcdAttributes |= EFI_MEMORY_RO;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Process eXecute Never attribute
|
||||||
|
if ((PageAttributes & (TT_PXN_MASK | TT_UXN_MASK)) != 0) {
|
||||||
|
GcdAttributes |= EFI_MEMORY_XP;
|
||||||
|
}
|
||||||
|
|
||||||
|
return GcdAttributes;
|
||||||
|
}
|
||||||
|
|
||||||
STATIC
|
STATIC
|
||||||
UINT64
|
UINT64
|
||||||
@@ -37,7 +98,7 @@ GetFirstPageAttribute (
|
|||||||
{
|
{
|
||||||
return FirstEntry & TT_ATTR_INDX_MASK;
|
return FirstEntry & TT_ATTR_INDX_MASK;
|
||||||
} else {
|
} else {
|
||||||
return TT_ATTR_INDX_INVALID;
|
return INVALID_ENTRY;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -78,8 +139,8 @@ GetNextEntryAttribute (
|
|||||||
// If Entry is a Table Descriptor type entry then go through the sub-level table
|
// If Entry is a Table Descriptor type entry then go through the sub-level table
|
||||||
if ((EntryType == TT_TYPE_BLOCK_ENTRY) ||
|
if ((EntryType == TT_TYPE_BLOCK_ENTRY) ||
|
||||||
((TableLevel == 3) && (EntryType == TT_TYPE_BLOCK_ENTRY_LEVEL3))) {
|
((TableLevel == 3) && (EntryType == TT_TYPE_BLOCK_ENTRY_LEVEL3))) {
|
||||||
if ((*PrevEntryAttribute == TT_ATTR_INDX_INVALID) || (EntryAttribute != *PrevEntryAttribute)) {
|
if ((*PrevEntryAttribute == INVALID_ENTRY) || (EntryAttribute != *PrevEntryAttribute)) {
|
||||||
if (*PrevEntryAttribute != TT_ATTR_INDX_INVALID) {
|
if (*PrevEntryAttribute != INVALID_ENTRY) {
|
||||||
// Update GCD with the last region
|
// Update GCD with the last region
|
||||||
SetGcdMemorySpaceAttributes (MemorySpaceMap, NumberOfDescriptors,
|
SetGcdMemorySpaceAttributes (MemorySpaceMap, NumberOfDescriptors,
|
||||||
*StartGcdRegion,
|
*StartGcdRegion,
|
||||||
@@ -103,7 +164,7 @@ GetNextEntryAttribute (
|
|||||||
(BaseAddress + (Index * TT_ADDRESS_AT_LEVEL(TableLevel))),
|
(BaseAddress + (Index * TT_ADDRESS_AT_LEVEL(TableLevel))),
|
||||||
PrevEntryAttribute, StartGcdRegion);
|
PrevEntryAttribute, StartGcdRegion);
|
||||||
} else {
|
} else {
|
||||||
if (*PrevEntryAttribute != TT_ATTR_INDX_INVALID) {
|
if (*PrevEntryAttribute != INVALID_ENTRY) {
|
||||||
// Update GCD with the last region
|
// Update GCD with the last region
|
||||||
SetGcdMemorySpaceAttributes (MemorySpaceMap, NumberOfDescriptors,
|
SetGcdMemorySpaceAttributes (MemorySpaceMap, NumberOfDescriptors,
|
||||||
*StartGcdRegion,
|
*StartGcdRegion,
|
||||||
@@ -112,7 +173,7 @@ GetNextEntryAttribute (
|
|||||||
|
|
||||||
// Start of the new region
|
// Start of the new region
|
||||||
*StartGcdRegion = BaseAddress + (Index * TT_ADDRESS_AT_LEVEL(TableLevel));
|
*StartGcdRegion = BaseAddress + (Index * TT_ADDRESS_AT_LEVEL(TableLevel));
|
||||||
*PrevEntryAttribute = TT_ATTR_INDX_INVALID;
|
*PrevEntryAttribute = INVALID_ENTRY;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -177,7 +238,7 @@ SyncCacheConfig (
|
|||||||
&PageAttribute, &BaseAddressGcdRegion);
|
&PageAttribute, &BaseAddressGcdRegion);
|
||||||
|
|
||||||
// Update GCD with the last region if valid
|
// Update GCD with the last region if valid
|
||||||
if (PageAttribute != TT_ATTR_INDX_INVALID) {
|
if (PageAttribute != INVALID_ENTRY) {
|
||||||
SetGcdMemorySpaceAttributes (MemorySpaceMap, NumberOfDescriptors,
|
SetGcdMemorySpaceAttributes (MemorySpaceMap, NumberOfDescriptors,
|
||||||
BaseAddressGcdRegion,
|
BaseAddressGcdRegion,
|
||||||
EndAddressGcdRegion - BaseAddressGcdRegion,
|
EndAddressGcdRegion - BaseAddressGcdRegion,
|
||||||
|
@@ -134,13 +134,6 @@ GetMemoryRegion (
|
|||||||
OUT UINTN *RegionAttributes
|
OUT UINTN *RegionAttributes
|
||||||
);
|
);
|
||||||
|
|
||||||
VOID
|
|
||||||
GetRootTranslationTableInfo (
|
|
||||||
IN UINTN T0SZ,
|
|
||||||
OUT UINTN *TableLevel,
|
|
||||||
OUT UINTN *TableEntryCount
|
|
||||||
);
|
|
||||||
|
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
SetGcdMemorySpaceAttributes (
|
SetGcdMemorySpaceAttributes (
|
||||||
IN EFI_GCD_MEMORY_SPACE_DESCRIPTOR *MemorySpaceMap,
|
IN EFI_GCD_MEMORY_SPACE_DESCRIPTOR *MemorySpaceMap,
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
/** @file
|
/** @file
|
||||||
|
|
||||||
Copyright (c) 2016-2018, ARM Limited. All rights reserved.
|
Copyright (c) 2016-2019, ARM Limited. All rights reserved.
|
||||||
|
|
||||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
|
|
||||||
@@ -16,7 +16,7 @@
|
|||||||
#include <Library/UefiBootServicesTableLib.h>
|
#include <Library/UefiBootServicesTableLib.h>
|
||||||
#include <Library/UefiRuntimeServicesTableLib.h>
|
#include <Library/UefiRuntimeServicesTableLib.h>
|
||||||
|
|
||||||
#include <Protocol/MmCommunication.h>
|
#include <Protocol/MmCommunication2.h>
|
||||||
|
|
||||||
#include <IndustryStandard/ArmStdSmc.h>
|
#include <IndustryStandard/ArmStdSmc.h>
|
||||||
|
|
||||||
@@ -39,39 +39,34 @@ STATIC EFI_HANDLE mMmCommunicateHandle;
|
|||||||
/**
|
/**
|
||||||
Communicates with a registered handler.
|
Communicates with a registered handler.
|
||||||
|
|
||||||
This function provides an interface to send and receive messages to the
|
This function provides a service to send and receive messages from a registered UEFI service.
|
||||||
Standalone MM environment on behalf of UEFI services. This function is part
|
|
||||||
of the MM Communication Protocol that may be called in physical mode prior to
|
|
||||||
SetVirtualAddressMap() and in virtual mode after SetVirtualAddressMap().
|
|
||||||
|
|
||||||
@param[in] This The EFI_MM_COMMUNICATION_PROTOCOL
|
@param[in] This The EFI_MM_COMMUNICATION_PROTOCOL instance.
|
||||||
instance.
|
@param[in] CommBufferPhysical Physical address of the MM communication buffer
|
||||||
@param[in, out] CommBuffer A pointer to the buffer to convey
|
@param[in] CommBufferVirtual Virtual address of the MM communication buffer
|
||||||
into MMRAM.
|
@param[in] CommSize The size of the data buffer being passed in. On exit, the size of data
|
||||||
@param[in, out] CommSize The size of the data buffer being
|
being returned. Zero if the handler does not wish to reply with any data.
|
||||||
passed in. This is optional.
|
This parameter is optional and may be NULL.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS The message was successfully posted.
|
||||||
|
@retval EFI_INVALID_PARAMETER CommBufferPhysical was NULL or CommBufferVirtual was NULL.
|
||||||
|
@retval EFI_BAD_BUFFER_SIZE The buffer is too large for the MM implementation.
|
||||||
|
If this error is returned, the MessageLength field
|
||||||
|
in the CommBuffer header or the integer pointed by
|
||||||
|
CommSize, are updated to reflect the maximum payload
|
||||||
|
size the implementation can accommodate.
|
||||||
|
@retval EFI_ACCESS_DENIED The CommunicateBuffer parameter or CommSize parameter,
|
||||||
|
if not omitted, are in address range that cannot be
|
||||||
|
accessed by the MM environment.
|
||||||
|
|
||||||
@retval EFI_SUCCESS The message was successfully posted.
|
|
||||||
@retval EFI_INVALID_PARAMETER The CommBuffer was NULL.
|
|
||||||
@retval EFI_BAD_BUFFER_SIZE The buffer size is incorrect for the MM
|
|
||||||
implementation. If this error is
|
|
||||||
returned, the MessageLength field in
|
|
||||||
the CommBuffer header or the integer
|
|
||||||
pointed by CommSize are updated to reflect
|
|
||||||
the maximum payload size the
|
|
||||||
implementation can accommodate.
|
|
||||||
@retval EFI_ACCESS_DENIED The CommunicateBuffer parameter
|
|
||||||
or CommSize parameter, if not omitted,
|
|
||||||
are in address range that cannot be
|
|
||||||
accessed by the MM environment
|
|
||||||
**/
|
**/
|
||||||
STATIC
|
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
EFIAPI
|
EFIAPI
|
||||||
MmCommunicationCommunicate (
|
MmCommunication2Communicate (
|
||||||
IN CONST EFI_MM_COMMUNICATION_PROTOCOL *This,
|
IN CONST EFI_MM_COMMUNICATION2_PROTOCOL *This,
|
||||||
IN OUT VOID *CommBuffer,
|
IN OUT VOID *CommBufferPhysical,
|
||||||
IN OUT UINTN *CommSize OPTIONAL
|
IN OUT VOID *CommBufferVirtual,
|
||||||
|
IN OUT UINTN *CommSize OPTIONAL
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
EFI_MM_COMMUNICATE_HEADER *CommunicateHeader;
|
EFI_MM_COMMUNICATE_HEADER *CommunicateHeader;
|
||||||
@@ -87,11 +82,11 @@ MmCommunicationCommunicate (
|
|||||||
//
|
//
|
||||||
// Check parameters
|
// Check parameters
|
||||||
//
|
//
|
||||||
if (CommBuffer == NULL) {
|
if (CommBufferVirtual == NULL) {
|
||||||
return EFI_INVALID_PARAMETER;
|
return EFI_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
|
|
||||||
CommunicateHeader = CommBuffer;
|
CommunicateHeader = CommBufferVirtual;
|
||||||
// CommBuffer is a mandatory parameter. Hence, Rely on
|
// CommBuffer is a mandatory parameter. Hence, Rely on
|
||||||
// MessageLength + Header to ascertain the
|
// MessageLength + Header to ascertain the
|
||||||
// total size of the communication payload rather than
|
// total size of the communication payload rather than
|
||||||
@@ -136,7 +131,7 @@ MmCommunicationCommunicate (
|
|||||||
CommunicateSmcArgs.Arg1 = 0;
|
CommunicateSmcArgs.Arg1 = 0;
|
||||||
|
|
||||||
// Copy Communication Payload
|
// Copy Communication Payload
|
||||||
CopyMem ((VOID *)mNsCommBuffMemRegion.VirtualBase, CommBuffer, BufferSize);
|
CopyMem ((VOID *)mNsCommBuffMemRegion.VirtualBase, CommBufferVirtual, BufferSize);
|
||||||
|
|
||||||
// comm_buffer_address (64-bit physical address)
|
// comm_buffer_address (64-bit physical address)
|
||||||
CommunicateSmcArgs.Arg2 = (UINTN)mNsCommBuffMemRegion.PhysicalBase;
|
CommunicateSmcArgs.Arg2 = (UINTN)mNsCommBuffMemRegion.PhysicalBase;
|
||||||
@@ -149,7 +144,7 @@ MmCommunicationCommunicate (
|
|||||||
|
|
||||||
switch (CommunicateSmcArgs.Arg0) {
|
switch (CommunicateSmcArgs.Arg0) {
|
||||||
case ARM_SMC_MM_RET_SUCCESS:
|
case ARM_SMC_MM_RET_SUCCESS:
|
||||||
ZeroMem (CommBuffer, BufferSize);
|
ZeroMem (CommBufferVirtual, BufferSize);
|
||||||
// On successful return, the size of data being returned is inferred from
|
// On successful return, the size of data being returned is inferred from
|
||||||
// MessageLength + Header.
|
// MessageLength + Header.
|
||||||
CommunicateHeader = (EFI_MM_COMMUNICATE_HEADER *)mNsCommBuffMemRegion.VirtualBase;
|
CommunicateHeader = (EFI_MM_COMMUNICATE_HEADER *)mNsCommBuffMemRegion.VirtualBase;
|
||||||
@@ -158,7 +153,7 @@ MmCommunicationCommunicate (
|
|||||||
sizeof (CommunicateHeader->MessageLength);
|
sizeof (CommunicateHeader->MessageLength);
|
||||||
|
|
||||||
CopyMem (
|
CopyMem (
|
||||||
CommBuffer,
|
CommBufferVirtual,
|
||||||
(VOID *)mNsCommBuffMemRegion.VirtualBase,
|
(VOID *)mNsCommBuffMemRegion.VirtualBase,
|
||||||
BufferSize
|
BufferSize
|
||||||
);
|
);
|
||||||
@@ -191,8 +186,8 @@ MmCommunicationCommunicate (
|
|||||||
//
|
//
|
||||||
// MM Communication Protocol instance
|
// MM Communication Protocol instance
|
||||||
//
|
//
|
||||||
EFI_MM_COMMUNICATION_PROTOCOL mMmCommunication = {
|
STATIC EFI_MM_COMMUNICATION2_PROTOCOL mMmCommunication2 = {
|
||||||
MmCommunicationCommunicate
|
MmCommunication2Communicate
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -259,6 +254,43 @@ GetMmCompatibility ()
|
|||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
STATIC EFI_GUID* CONST mGuidedEventGuid[] = {
|
||||||
|
&gEfiEndOfDxeEventGroupGuid,
|
||||||
|
&gEfiEventExitBootServicesGuid,
|
||||||
|
&gEfiEventReadyToBootGuid,
|
||||||
|
};
|
||||||
|
|
||||||
|
STATIC EFI_EVENT mGuidedEvent[ARRAY_SIZE (mGuidedEventGuid)];
|
||||||
|
|
||||||
|
/**
|
||||||
|
Event notification that is fired when GUIDed Event Group is signaled.
|
||||||
|
|
||||||
|
@param Event The Event that is being processed, not used.
|
||||||
|
@param Context Event Context, not used.
|
||||||
|
|
||||||
|
**/
|
||||||
|
STATIC
|
||||||
|
VOID
|
||||||
|
EFIAPI
|
||||||
|
MmGuidedEventNotify (
|
||||||
|
IN EFI_EVENT Event,
|
||||||
|
IN VOID *Context
|
||||||
|
)
|
||||||
|
{
|
||||||
|
EFI_MM_COMMUNICATE_HEADER Header;
|
||||||
|
UINTN Size;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Use Guid to initialize EFI_SMM_COMMUNICATE_HEADER structure
|
||||||
|
//
|
||||||
|
CopyGuid (&Header.HeaderGuid, Context);
|
||||||
|
Header.MessageLength = 1;
|
||||||
|
Header.Data[0] = 0;
|
||||||
|
|
||||||
|
Size = sizeof (Header);
|
||||||
|
MmCommunication2Communicate (&mMmCommunication2, &Header, &Header, &Size);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
The Entry Point for MM Communication
|
The Entry Point for MM Communication
|
||||||
|
|
||||||
@@ -275,12 +307,13 @@ GetMmCompatibility ()
|
|||||||
**/
|
**/
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
EFIAPI
|
EFIAPI
|
||||||
MmCommunicationInitialize (
|
MmCommunication2Initialize (
|
||||||
IN EFI_HANDLE ImageHandle,
|
IN EFI_HANDLE ImageHandle,
|
||||||
IN EFI_SYSTEM_TABLE *SystemTable
|
IN EFI_SYSTEM_TABLE *SystemTable
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
|
UINTN Index;
|
||||||
|
|
||||||
// Check if we can make the MM call
|
// Check if we can make the MM call
|
||||||
Status = GetMmCompatibility ();
|
Status = GetMmCompatibility ();
|
||||||
@@ -325,9 +358,9 @@ MmCommunicationInitialize (
|
|||||||
// Install the communication protocol
|
// Install the communication protocol
|
||||||
Status = gBS->InstallProtocolInterface (
|
Status = gBS->InstallProtocolInterface (
|
||||||
&mMmCommunicateHandle,
|
&mMmCommunicateHandle,
|
||||||
&gEfiMmCommunicationProtocolGuid,
|
&gEfiMmCommunication2ProtocolGuid,
|
||||||
EFI_NATIVE_INTERFACE,
|
EFI_NATIVE_INTERFACE,
|
||||||
&mMmCommunication
|
&mMmCommunication2
|
||||||
);
|
);
|
||||||
if (EFI_ERROR(Status)) {
|
if (EFI_ERROR(Status)) {
|
||||||
DEBUG ((DEBUG_ERROR, "MmCommunicationInitialize: "
|
DEBUG ((DEBUG_ERROR, "MmCommunicationInitialize: "
|
||||||
@@ -345,14 +378,27 @@ MmCommunicationInitialize (
|
|||||||
NULL,
|
NULL,
|
||||||
&mSetVirtualAddressMapEvent
|
&mSetVirtualAddressMapEvent
|
||||||
);
|
);
|
||||||
if (Status == EFI_SUCCESS) {
|
ASSERT_EFI_ERROR (Status);
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
for (Index = 0; Index < ARRAY_SIZE (mGuidedEventGuid); Index++) {
|
||||||
|
Status = gBS->CreateEventEx (EVT_NOTIFY_SIGNAL, TPL_CALLBACK,
|
||||||
|
MmGuidedEventNotify, mGuidedEventGuid[Index],
|
||||||
|
mGuidedEventGuid[Index], &mGuidedEvent[Index]);
|
||||||
|
ASSERT_EFI_ERROR (Status);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
while (Index-- > 0) {
|
||||||
|
gBS->CloseEvent (mGuidedEvent[Index]);
|
||||||
|
}
|
||||||
|
goto UninstallProtocol;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
|
||||||
|
UninstallProtocol:
|
||||||
gBS->UninstallProtocolInterface (
|
gBS->UninstallProtocolInterface (
|
||||||
mMmCommunicateHandle,
|
mMmCommunicateHandle,
|
||||||
&gEfiMmCommunicationProtocolGuid,
|
&gEfiMmCommunication2ProtocolGuid,
|
||||||
&mMmCommunication
|
&mMmCommunication2
|
||||||
);
|
);
|
||||||
|
|
||||||
CleanAddedMemorySpace:
|
CleanAddedMemorySpace:
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
#
|
#
|
||||||
# DXE MM Communicate driver
|
# DXE MM Communicate driver
|
||||||
#
|
#
|
||||||
# Copyright (c) 2016 - 2018, ARM Limited. All rights reserved.
|
# Copyright (c) 2016 - 2019, ARM Limited. All rights reserved.
|
||||||
#
|
#
|
||||||
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
#
|
#
|
||||||
@@ -14,7 +14,7 @@
|
|||||||
FILE_GUID = 09EE81D3-F15E-43F4-85B4-CB9873DA5D6B
|
FILE_GUID = 09EE81D3-F15E-43F4-85B4-CB9873DA5D6B
|
||||||
MODULE_TYPE = DXE_RUNTIME_DRIVER
|
MODULE_TYPE = DXE_RUNTIME_DRIVER
|
||||||
VERSION_STRING = 1.0
|
VERSION_STRING = 1.0
|
||||||
ENTRY_POINT = MmCommunicationInitialize
|
ENTRY_POINT = MmCommunication2Initialize
|
||||||
|
|
||||||
#
|
#
|
||||||
# The following is for reference only and not required by
|
# The following is for reference only and not required by
|
||||||
@@ -40,7 +40,12 @@
|
|||||||
UefiDriverEntryPoint
|
UefiDriverEntryPoint
|
||||||
|
|
||||||
[Protocols]
|
[Protocols]
|
||||||
gEfiMmCommunicationProtocolGuid ## PRODUCES
|
gEfiMmCommunication2ProtocolGuid ## PRODUCES
|
||||||
|
|
||||||
|
[Guids]
|
||||||
|
gEfiEndOfDxeEventGroupGuid
|
||||||
|
gEfiEventExitBootServicesGuid
|
||||||
|
gEfiEventReadyToBootGuid
|
||||||
|
|
||||||
[Pcd.common]
|
[Pcd.common]
|
||||||
gArmTokenSpaceGuid.PcdMmBufferBase
|
gArmTokenSpaceGuid.PcdMmBufferBase
|
||||||
|
@@ -219,11 +219,6 @@ ArmReadCurrentEL (
|
|||||||
VOID
|
VOID
|
||||||
);
|
);
|
||||||
|
|
||||||
UINT64
|
|
||||||
PageAttributeToGcdAttribute (
|
|
||||||
IN UINT64 PageAttributes
|
|
||||||
);
|
|
||||||
|
|
||||||
UINTN
|
UINTN
|
||||||
ArmWriteCptr (
|
ArmWriteCptr (
|
||||||
IN UINT64 Cptr
|
IN UINT64 Cptr
|
||||||
|
@@ -211,24 +211,6 @@ ArmCleanInvalidateDataCacheEntryByMVA (
|
|||||||
IN UINTN Address
|
IN UINTN Address
|
||||||
);
|
);
|
||||||
|
|
||||||
VOID
|
|
||||||
EFIAPI
|
|
||||||
ArmInvalidateDataCacheEntryBySetWay (
|
|
||||||
IN UINTN SetWayFormat
|
|
||||||
);
|
|
||||||
|
|
||||||
VOID
|
|
||||||
EFIAPI
|
|
||||||
ArmCleanDataCacheEntryBySetWay (
|
|
||||||
IN UINTN SetWayFormat
|
|
||||||
);
|
|
||||||
|
|
||||||
VOID
|
|
||||||
EFIAPI
|
|
||||||
ArmCleanInvalidateDataCacheEntryBySetWay (
|
|
||||||
IN UINTN SetWayFormat
|
|
||||||
);
|
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
EFIAPI
|
EFIAPI
|
||||||
ArmEnableDataCache (
|
ArmEnableDataCache (
|
||||||
|
@@ -7,11 +7,13 @@
|
|||||||
|
|
||||||
**/
|
**/
|
||||||
|
|
||||||
#include <Uefi.h>
|
#include <Base.h>
|
||||||
#include <Chipset/AArch64.h>
|
|
||||||
#include <Library/ArmLib.h>
|
#include <Library/ArmLib.h>
|
||||||
#include <Library/BaseLib.h>
|
#include <Library/DebugLib.h>
|
||||||
#include <Library/IoLib.h>
|
|
||||||
|
#include <Chipset/AArch64.h>
|
||||||
|
|
||||||
#include "AArch64Lib.h"
|
#include "AArch64Lib.h"
|
||||||
#include "ArmLibPrivate.h"
|
#include "ArmLibPrivate.h"
|
||||||
|
|
||||||
@@ -40,6 +42,8 @@ ArmInvalidateDataCache (
|
|||||||
VOID
|
VOID
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
ASSERT (!ArmMmuEnabled ());
|
||||||
|
|
||||||
ArmDataSynchronizationBarrier ();
|
ArmDataSynchronizationBarrier ();
|
||||||
AArch64DataCacheOperation (ArmInvalidateDataCacheEntryBySetWay);
|
AArch64DataCacheOperation (ArmInvalidateDataCacheEntryBySetWay);
|
||||||
}
|
}
|
||||||
@@ -50,6 +54,8 @@ ArmCleanInvalidateDataCache (
|
|||||||
VOID
|
VOID
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
ASSERT (!ArmMmuEnabled ());
|
||||||
|
|
||||||
ArmDataSynchronizationBarrier ();
|
ArmDataSynchronizationBarrier ();
|
||||||
AArch64DataCacheOperation (ArmCleanInvalidateDataCacheEntryBySetWay);
|
AArch64DataCacheOperation (ArmCleanInvalidateDataCacheEntryBySetWay);
|
||||||
}
|
}
|
||||||
@@ -60,6 +66,8 @@ ArmCleanDataCache (
|
|||||||
VOID
|
VOID
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
ASSERT (!ArmMmuEnabled ());
|
||||||
|
|
||||||
ArmDataSynchronizationBarrier ();
|
ArmDataSynchronizationBarrier ();
|
||||||
AArch64DataCacheOperation (ArmCleanDataCacheEntryBySetWay);
|
AArch64DataCacheOperation (ArmCleanDataCacheEntryBySetWay);
|
||||||
}
|
}
|
||||||
|
@@ -17,5 +17,23 @@ AArch64AllDataCachesOperation (
|
|||||||
IN AARCH64_CACHE_OPERATION DataCacheOperation
|
IN AARCH64_CACHE_OPERATION DataCacheOperation
|
||||||
);
|
);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
EFIAPI
|
||||||
|
ArmInvalidateDataCacheEntryBySetWay (
|
||||||
|
IN UINTN SetWayFormat
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
EFIAPI
|
||||||
|
ArmCleanDataCacheEntryBySetWay (
|
||||||
|
IN UINTN SetWayFormat
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
EFIAPI
|
||||||
|
ArmCleanInvalidateDataCacheEntryBySetWay (
|
||||||
|
IN UINTN SetWayFormat
|
||||||
|
);
|
||||||
|
|
||||||
#endif // __AARCH64_LIB_H__
|
#endif // __AARCH64_LIB_H__
|
||||||
|
|
||||||
|
@@ -13,6 +13,8 @@
|
|||||||
.set DAIF_RD_FIQ_BIT, (1 << 6)
|
.set DAIF_RD_FIQ_BIT, (1 << 6)
|
||||||
.set DAIF_RD_IRQ_BIT, (1 << 7)
|
.set DAIF_RD_IRQ_BIT, (1 << 7)
|
||||||
|
|
||||||
|
.set SCTLR_ELx_M_BIT_POS, (0)
|
||||||
|
|
||||||
ASM_FUNC(ArmReadMidr)
|
ASM_FUNC(ArmReadMidr)
|
||||||
mrs x0, midr_el1 // Read from Main ID Register (MIDR)
|
mrs x0, midr_el1 // Read from Main ID Register (MIDR)
|
||||||
ret
|
ret
|
||||||
@@ -120,13 +122,18 @@ ASM_FUNC(ArmSetMAIR)
|
|||||||
ASM_FUNC(ArmUpdateTranslationTableEntry)
|
ASM_FUNC(ArmUpdateTranslationTableEntry)
|
||||||
dsb nshst
|
dsb nshst
|
||||||
lsr x1, x1, #12
|
lsr x1, x1, #12
|
||||||
EL1_OR_EL2_OR_EL3(x0)
|
EL1_OR_EL2_OR_EL3(x2)
|
||||||
1: tlbi vaae1, x1 // TLB Invalidate VA , EL1
|
1: tlbi vaae1, x1 // TLB Invalidate VA , EL1
|
||||||
|
mrs x2, sctlr_el1
|
||||||
b 4f
|
b 4f
|
||||||
2: tlbi vae2, x1 // TLB Invalidate VA , EL2
|
2: tlbi vae2, x1 // TLB Invalidate VA , EL2
|
||||||
|
mrs x2, sctlr_el2
|
||||||
b 4f
|
b 4f
|
||||||
3: tlbi vae3, x1 // TLB Invalidate VA , EL3
|
3: tlbi vae3, x1 // TLB Invalidate VA , EL3
|
||||||
4: dsb nsh
|
mrs x2, sctlr_el3
|
||||||
|
4: tbnz x2, SCTLR_ELx_M_BIT_POS, 5f
|
||||||
|
dc ivac, x0 // invalidate in Dcache if MMU is still off
|
||||||
|
5: dsb nsh
|
||||||
isb
|
isb
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
@@ -6,11 +6,14 @@
|
|||||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
|
|
||||||
**/
|
**/
|
||||||
#include <Uefi.h>
|
|
||||||
#include <Chipset/ArmV7.h>
|
#include <Base.h>
|
||||||
|
|
||||||
#include <Library/ArmLib.h>
|
#include <Library/ArmLib.h>
|
||||||
#include <Library/BaseLib.h>
|
#include <Library/DebugLib.h>
|
||||||
#include <Library/IoLib.h>
|
|
||||||
|
#include <Chipset/ArmV7.h>
|
||||||
|
|
||||||
#include "ArmV7Lib.h"
|
#include "ArmV7Lib.h"
|
||||||
#include "ArmLibPrivate.h"
|
#include "ArmLibPrivate.h"
|
||||||
|
|
||||||
@@ -39,6 +42,8 @@ ArmInvalidateDataCache (
|
|||||||
VOID
|
VOID
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
ASSERT (!ArmMmuEnabled ());
|
||||||
|
|
||||||
ArmDataSynchronizationBarrier ();
|
ArmDataSynchronizationBarrier ();
|
||||||
ArmV7DataCacheOperation (ArmInvalidateDataCacheEntryBySetWay);
|
ArmV7DataCacheOperation (ArmInvalidateDataCacheEntryBySetWay);
|
||||||
}
|
}
|
||||||
@@ -49,6 +54,8 @@ ArmCleanInvalidateDataCache (
|
|||||||
VOID
|
VOID
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
ASSERT (!ArmMmuEnabled ());
|
||||||
|
|
||||||
ArmDataSynchronizationBarrier ();
|
ArmDataSynchronizationBarrier ();
|
||||||
ArmV7DataCacheOperation (ArmCleanInvalidateDataCacheEntryBySetWay);
|
ArmV7DataCacheOperation (ArmCleanInvalidateDataCacheEntryBySetWay);
|
||||||
}
|
}
|
||||||
@@ -59,6 +66,8 @@ ArmCleanDataCache (
|
|||||||
VOID
|
VOID
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
ASSERT (!ArmMmuEnabled ());
|
||||||
|
|
||||||
ArmDataSynchronizationBarrier ();
|
ArmDataSynchronizationBarrier ();
|
||||||
ArmV7DataCacheOperation (ArmCleanDataCacheEntryBySetWay);
|
ArmV7DataCacheOperation (ArmCleanDataCacheEntryBySetWay);
|
||||||
}
|
}
|
||||||
|
@@ -30,5 +30,23 @@ ArmV7AllDataCachesOperation (
|
|||||||
IN ARM_V7_CACHE_OPERATION DataCacheOperation
|
IN ARM_V7_CACHE_OPERATION DataCacheOperation
|
||||||
);
|
);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
EFIAPI
|
||||||
|
ArmInvalidateDataCacheEntryBySetWay (
|
||||||
|
IN UINTN SetWayFormat
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
EFIAPI
|
||||||
|
ArmCleanDataCacheEntryBySetWay (
|
||||||
|
IN UINTN SetWayFormat
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
EFIAPI
|
||||||
|
ArmCleanInvalidateDataCacheEntryBySetWay (
|
||||||
|
IN UINTN SetWayFormat
|
||||||
|
);
|
||||||
|
|
||||||
#endif // __ARM_V7_LIB_H__
|
#endif // __ARM_V7_LIB_H__
|
||||||
|
|
||||||
|
@@ -44,12 +44,12 @@
|
|||||||
AArch64/AArch64Support.S
|
AArch64/AArch64Support.S
|
||||||
AArch64/AArch64ArchTimerSupport.S
|
AArch64/AArch64ArchTimerSupport.S
|
||||||
|
|
||||||
|
[LibraryClasses]
|
||||||
|
DebugLib
|
||||||
|
|
||||||
[Packages]
|
[Packages]
|
||||||
ArmPkg/ArmPkg.dec
|
ArmPkg/ArmPkg.dec
|
||||||
MdePkg/MdePkg.dec
|
MdePkg/MdePkg.dec
|
||||||
|
|
||||||
[Protocols]
|
|
||||||
gEfiCpuArchProtocolGuid
|
|
||||||
|
|
||||||
[FeaturePcd.ARM]
|
[FeaturePcd.ARM]
|
||||||
gArmTokenSpaceGuid.PcdNormalMemoryNonshareableOverride
|
gArmTokenSpaceGuid.PcdNormalMemoryNonshareableOverride
|
||||||
|
@@ -10,8 +10,6 @@
|
|||||||
#include <Base.h>
|
#include <Base.h>
|
||||||
|
|
||||||
#include <Library/ArmLib.h>
|
#include <Library/ArmLib.h>
|
||||||
#include <Library/DebugLib.h>
|
|
||||||
#include <Library/PcdLib.h>
|
|
||||||
|
|
||||||
#include "ArmLibPrivate.h"
|
#include "ArmLibPrivate.h"
|
||||||
|
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
/** @file
|
/** @file
|
||||||
* File managing the MMU for ARMv8 architecture
|
* File managing the MMU for ARMv8 architecture
|
||||||
*
|
*
|
||||||
* Copyright (c) 2011-2014, ARM Limited. All rights reserved.
|
* Copyright (c) 2011-2020, ARM Limited. All rights reserved.
|
||||||
* Copyright (c) 2016, Linaro Limited. All rights reserved.
|
* Copyright (c) 2016, Linaro Limited. All rights reserved.
|
||||||
* Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
|
* Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
|
||||||
*
|
*
|
||||||
@@ -19,9 +19,6 @@
|
|||||||
#include <Library/BaseLib.h>
|
#include <Library/BaseLib.h>
|
||||||
#include <Library/DebugLib.h>
|
#include <Library/DebugLib.h>
|
||||||
|
|
||||||
// We use this index definition to define an invalid block entry
|
|
||||||
#define TT_ATTR_INDX_INVALID ((UINT32)~0)
|
|
||||||
|
|
||||||
STATIC
|
STATIC
|
||||||
UINT64
|
UINT64
|
||||||
ArmMemoryAttributeToPageAttribute (
|
ArmMemoryAttributeToPageAttribute (
|
||||||
@@ -47,7 +44,7 @@ ArmMemoryAttributeToPageAttribute (
|
|||||||
return TT_ATTR_INDX_MEMORY_NON_CACHEABLE;
|
return TT_ATTR_INDX_MEMORY_NON_CACHEABLE;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
ASSERT(0);
|
ASSERT (0);
|
||||||
case ARM_MEMORY_REGION_ATTRIBUTE_DEVICE:
|
case ARM_MEMORY_REGION_ATTRIBUTE_DEVICE:
|
||||||
case ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_DEVICE:
|
case ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_DEVICE:
|
||||||
if (ArmReadCurrentEL () == AARCH64_EL2)
|
if (ArmReadCurrentEL () == AARCH64_EL2)
|
||||||
@@ -57,78 +54,40 @@ ArmMemoryAttributeToPageAttribute (
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
UINT64
|
|
||||||
PageAttributeToGcdAttribute (
|
|
||||||
IN UINT64 PageAttributes
|
|
||||||
)
|
|
||||||
{
|
|
||||||
UINT64 GcdAttributes;
|
|
||||||
|
|
||||||
switch (PageAttributes & TT_ATTR_INDX_MASK) {
|
|
||||||
case TT_ATTR_INDX_DEVICE_MEMORY:
|
|
||||||
GcdAttributes = EFI_MEMORY_UC;
|
|
||||||
break;
|
|
||||||
case TT_ATTR_INDX_MEMORY_NON_CACHEABLE:
|
|
||||||
GcdAttributes = EFI_MEMORY_WC;
|
|
||||||
break;
|
|
||||||
case TT_ATTR_INDX_MEMORY_WRITE_THROUGH:
|
|
||||||
GcdAttributes = EFI_MEMORY_WT;
|
|
||||||
break;
|
|
||||||
case TT_ATTR_INDX_MEMORY_WRITE_BACK:
|
|
||||||
GcdAttributes = EFI_MEMORY_WB;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
DEBUG ((EFI_D_ERROR, "PageAttributeToGcdAttribute: PageAttributes:0x%lX not supported.\n", PageAttributes));
|
|
||||||
ASSERT (0);
|
|
||||||
// The Global Coherency Domain (GCD) value is defined as a bit set.
|
|
||||||
// Returning 0 means no attribute has been set.
|
|
||||||
GcdAttributes = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Determine protection attributes
|
|
||||||
if (((PageAttributes & TT_AP_MASK) == TT_AP_NO_RO) || ((PageAttributes & TT_AP_MASK) == TT_AP_RO_RO)) {
|
|
||||||
// Read only cases map to write-protect
|
|
||||||
GcdAttributes |= EFI_MEMORY_RO;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Process eXecute Never attribute
|
|
||||||
if ((PageAttributes & (TT_PXN_MASK | TT_UXN_MASK)) != 0 ) {
|
|
||||||
GcdAttributes |= EFI_MEMORY_XP;
|
|
||||||
}
|
|
||||||
|
|
||||||
return GcdAttributes;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define MIN_T0SZ 16
|
#define MIN_T0SZ 16
|
||||||
#define BITS_PER_LEVEL 9
|
#define BITS_PER_LEVEL 9
|
||||||
|
#define MAX_VA_BITS 48
|
||||||
|
|
||||||
VOID
|
STATIC
|
||||||
GetRootTranslationTableInfo (
|
UINTN
|
||||||
IN UINTN T0SZ,
|
GetRootTableEntryCount (
|
||||||
OUT UINTN *TableLevel,
|
IN UINTN T0SZ
|
||||||
OUT UINTN *TableEntryCount
|
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
// Get the level of the root table
|
return TT_ENTRY_COUNT >> (T0SZ - MIN_T0SZ) % BITS_PER_LEVEL;
|
||||||
if (TableLevel) {
|
}
|
||||||
*TableLevel = (T0SZ - MIN_T0SZ) / BITS_PER_LEVEL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (TableEntryCount) {
|
STATIC
|
||||||
*TableEntryCount = 1UL << (BITS_PER_LEVEL - (T0SZ - MIN_T0SZ) % BITS_PER_LEVEL);
|
UINTN
|
||||||
}
|
GetRootTableLevel (
|
||||||
|
IN UINTN T0SZ
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return (T0SZ - MIN_T0SZ) / BITS_PER_LEVEL;
|
||||||
}
|
}
|
||||||
|
|
||||||
STATIC
|
STATIC
|
||||||
VOID
|
VOID
|
||||||
ReplaceLiveEntry (
|
ReplaceTableEntry (
|
||||||
IN UINT64 *Entry,
|
IN UINT64 *Entry,
|
||||||
IN UINT64 Value,
|
IN UINT64 Value,
|
||||||
IN UINT64 RegionStart
|
IN UINT64 RegionStart,
|
||||||
|
IN BOOLEAN IsLiveBlockMapping
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
if (!ArmMmuEnabled ()) {
|
if (!ArmMmuEnabled () || !IsLiveBlockMapping) {
|
||||||
*Entry = Value;
|
*Entry = Value;
|
||||||
|
ArmUpdateTranslationTableEntry (Entry, (VOID *)(UINTN)RegionStart);
|
||||||
} else {
|
} else {
|
||||||
ArmReplaceLiveTranslationEntry (Entry, Value, RegionStart);
|
ArmReplaceLiveTranslationEntry (Entry, Value, RegionStart);
|
||||||
}
|
}
|
||||||
@@ -136,258 +95,214 @@ ReplaceLiveEntry (
|
|||||||
|
|
||||||
STATIC
|
STATIC
|
||||||
VOID
|
VOID
|
||||||
LookupAddresstoRootTable (
|
FreePageTablesRecursive (
|
||||||
IN UINT64 MaxAddress,
|
IN UINT64 *TranslationTable,
|
||||||
OUT UINTN *T0SZ,
|
IN UINTN Level
|
||||||
OUT UINTN *TableEntryCount
|
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
UINTN TopBit;
|
UINTN Index;
|
||||||
|
|
||||||
// Check the parameters are not NULL
|
ASSERT (Level <= 3);
|
||||||
ASSERT ((T0SZ != NULL) && (TableEntryCount != NULL));
|
|
||||||
|
|
||||||
// Look for the highest bit set in MaxAddress
|
if (Level < 3) {
|
||||||
for (TopBit = 63; TopBit != 0; TopBit--) {
|
for (Index = 0; Index < TT_ENTRY_COUNT; Index++) {
|
||||||
if ((1ULL << TopBit) & MaxAddress) {
|
if ((TranslationTable[Index] & TT_TYPE_MASK) == TT_TYPE_TABLE_ENTRY) {
|
||||||
// MaxAddress top bit is found
|
FreePageTablesRecursive ((VOID *)(UINTN)(TranslationTable[Index] &
|
||||||
TopBit = TopBit + 1;
|
TT_ADDRESS_MASK_BLOCK_ENTRY),
|
||||||
break;
|
Level + 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ASSERT (TopBit != 0);
|
FreePages (TranslationTable, 1);
|
||||||
|
|
||||||
// Calculate T0SZ from the top bit of the MaxAddress
|
|
||||||
*T0SZ = 64 - TopBit;
|
|
||||||
|
|
||||||
// Get the Table info from T0SZ
|
|
||||||
GetRootTranslationTableInfo (*T0SZ, NULL, TableEntryCount);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
STATIC
|
STATIC
|
||||||
UINT64*
|
BOOLEAN
|
||||||
GetBlockEntryListFromAddress (
|
IsBlockEntry (
|
||||||
IN UINT64 *RootTable,
|
IN UINT64 Entry,
|
||||||
IN UINT64 RegionStart,
|
IN UINTN Level
|
||||||
OUT UINTN *TableLevel,
|
|
||||||
IN OUT UINT64 *BlockEntrySize,
|
|
||||||
OUT UINT64 **LastBlockEntry
|
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
UINTN RootTableLevel;
|
if (Level == 3) {
|
||||||
UINTN RootTableEntryCount;
|
return (Entry & TT_TYPE_MASK) == TT_TYPE_BLOCK_ENTRY_LEVEL3;
|
||||||
UINT64 *TranslationTable;
|
|
||||||
UINT64 *BlockEntry;
|
|
||||||
UINT64 *SubTableBlockEntry;
|
|
||||||
UINT64 BlockEntryAddress;
|
|
||||||
UINTN BaseAddressAlignment;
|
|
||||||
UINTN PageLevel;
|
|
||||||
UINTN Index;
|
|
||||||
UINTN IndexLevel;
|
|
||||||
UINTN T0SZ;
|
|
||||||
UINT64 Attributes;
|
|
||||||
UINT64 TableAttributes;
|
|
||||||
|
|
||||||
// Initialize variable
|
|
||||||
BlockEntry = NULL;
|
|
||||||
|
|
||||||
// Ensure the parameters are valid
|
|
||||||
if (!(TableLevel && BlockEntrySize && LastBlockEntry)) {
|
|
||||||
ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER);
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
return (Entry & TT_TYPE_MASK) == TT_TYPE_BLOCK_ENTRY;
|
||||||
|
}
|
||||||
|
|
||||||
// Ensure the Region is aligned on 4KB boundary
|
STATIC
|
||||||
if ((RegionStart & (SIZE_4KB - 1)) != 0) {
|
BOOLEAN
|
||||||
ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER);
|
IsTableEntry (
|
||||||
return NULL;
|
IN UINT64 Entry,
|
||||||
|
IN UINTN Level
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (Level == 3) {
|
||||||
|
//
|
||||||
|
// TT_TYPE_TABLE_ENTRY aliases TT_TYPE_BLOCK_ENTRY_LEVEL3
|
||||||
|
// so we need to take the level into account as well.
|
||||||
|
//
|
||||||
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
return (Entry & TT_TYPE_MASK) == TT_TYPE_TABLE_ENTRY;
|
||||||
|
}
|
||||||
|
|
||||||
// Ensure the required size is aligned on 4KB boundary and not 0
|
STATIC
|
||||||
if ((*BlockEntrySize & (SIZE_4KB - 1)) != 0 || *BlockEntrySize == 0) {
|
EFI_STATUS
|
||||||
ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER);
|
UpdateRegionMappingRecursive (
|
||||||
return NULL;
|
IN UINT64 RegionStart,
|
||||||
}
|
IN UINT64 RegionEnd,
|
||||||
|
IN UINT64 AttributeSetMask,
|
||||||
|
IN UINT64 AttributeClearMask,
|
||||||
|
IN UINT64 *PageTable,
|
||||||
|
IN UINTN Level
|
||||||
|
)
|
||||||
|
{
|
||||||
|
UINTN BlockShift;
|
||||||
|
UINT64 BlockMask;
|
||||||
|
UINT64 BlockEnd;
|
||||||
|
UINT64 *Entry;
|
||||||
|
UINT64 EntryValue;
|
||||||
|
VOID *TranslationTable;
|
||||||
|
EFI_STATUS Status;
|
||||||
|
|
||||||
T0SZ = ArmGetTCR () & TCR_T0SZ_MASK;
|
ASSERT (((RegionStart | RegionEnd) & EFI_PAGE_MASK) == 0);
|
||||||
// Get the Table info from T0SZ
|
|
||||||
GetRootTranslationTableInfo (T0SZ, &RootTableLevel, &RootTableEntryCount);
|
|
||||||
|
|
||||||
// If the start address is 0x0 then we use the size of the region to identify the alignment
|
BlockShift = (Level + 1) * BITS_PER_LEVEL + MIN_T0SZ;
|
||||||
if (RegionStart == 0) {
|
BlockMask = MAX_UINT64 >> BlockShift;
|
||||||
// Identify the highest possible alignment for the Region Size
|
|
||||||
BaseAddressAlignment = LowBitSet64 (*BlockEntrySize);
|
|
||||||
} else {
|
|
||||||
// Identify the highest possible alignment for the Base Address
|
|
||||||
BaseAddressAlignment = LowBitSet64 (RegionStart);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Identify the Page Level the RegionStart must belong to. Note that PageLevel
|
DEBUG ((DEBUG_VERBOSE, "%a(%d): %llx - %llx set %lx clr %lx\n", __FUNCTION__,
|
||||||
// should be at least 1 since block translations are not supported at level 0
|
Level, RegionStart, RegionEnd, AttributeSetMask, AttributeClearMask));
|
||||||
PageLevel = MAX (3 - ((BaseAddressAlignment - 12) / 9), 1);
|
|
||||||
|
|
||||||
// If the required size is smaller than the current block size then we need to go to the page below.
|
for (; RegionStart < RegionEnd; RegionStart = BlockEnd) {
|
||||||
// The PageLevel was calculated on the Base Address alignment but did not take in account the alignment
|
BlockEnd = MIN (RegionEnd, (RegionStart | BlockMask) + 1);
|
||||||
// of the allocation size
|
Entry = &PageTable[(RegionStart >> (64 - BlockShift)) & (TT_ENTRY_COUNT - 1)];
|
||||||
while (*BlockEntrySize < TT_BLOCK_ENTRY_SIZE_AT_LEVEL (PageLevel)) {
|
|
||||||
// It does not fit so we need to go a page level above
|
|
||||||
PageLevel++;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Get the Table Descriptor for the corresponding PageLevel. We need to decompose RegionStart to get appropriate entries
|
// If RegionStart or BlockEnd is not aligned to the block size at this
|
||||||
//
|
// level, we will have to create a table mapping in order to map less
|
||||||
|
// than a block, and recurse to create the block or page entries at
|
||||||
|
// the next level. No block mappings are allowed at all at level 0,
|
||||||
|
// so in that case, we have to recurse unconditionally.
|
||||||
|
// If we are changing a table entry and the AttributeClearMask is non-zero,
|
||||||
|
// we cannot replace it with a block entry without potentially losing
|
||||||
|
// attribute information, so keep the table entry in that case.
|
||||||
|
//
|
||||||
|
if (Level == 0 || ((RegionStart | BlockEnd) & BlockMask) != 0 ||
|
||||||
|
(IsTableEntry (*Entry, Level) && AttributeClearMask != 0)) {
|
||||||
|
ASSERT (Level < 3);
|
||||||
|
|
||||||
TranslationTable = RootTable;
|
if (!IsTableEntry (*Entry, Level)) {
|
||||||
for (IndexLevel = RootTableLevel; IndexLevel <= PageLevel; IndexLevel++) {
|
//
|
||||||
BlockEntry = (UINT64*)TT_GET_ENTRY_FOR_ADDRESS (TranslationTable, IndexLevel, RegionStart);
|
// No table entry exists yet, so we need to allocate a page table
|
||||||
|
// for the next level.
|
||||||
if ((IndexLevel != 3) && ((*BlockEntry & TT_TYPE_MASK) == TT_TYPE_TABLE_ENTRY)) {
|
//
|
||||||
// Go to the next table
|
|
||||||
TranslationTable = (UINT64*)(*BlockEntry & TT_ADDRESS_MASK_DESCRIPTION_TABLE);
|
|
||||||
|
|
||||||
// If we are at the last level then update the last level to next level
|
|
||||||
if (IndexLevel == PageLevel) {
|
|
||||||
// Enter the next level
|
|
||||||
PageLevel++;
|
|
||||||
}
|
|
||||||
} else if ((*BlockEntry & TT_TYPE_MASK) == TT_TYPE_BLOCK_ENTRY) {
|
|
||||||
// If we are not at the last level then we need to split this BlockEntry
|
|
||||||
if (IndexLevel != PageLevel) {
|
|
||||||
// Retrieve the attributes from the block entry
|
|
||||||
Attributes = *BlockEntry & TT_ATTRIBUTES_MASK;
|
|
||||||
|
|
||||||
// Convert the block entry attributes into Table descriptor attributes
|
|
||||||
TableAttributes = TT_TABLE_AP_NO_PERMISSION;
|
|
||||||
if (Attributes & TT_NS) {
|
|
||||||
TableAttributes = TT_TABLE_NS;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the address corresponding at this entry
|
|
||||||
BlockEntryAddress = RegionStart;
|
|
||||||
BlockEntryAddress = BlockEntryAddress >> TT_ADDRESS_OFFSET_AT_LEVEL(IndexLevel);
|
|
||||||
// Shift back to right to set zero before the effective address
|
|
||||||
BlockEntryAddress = BlockEntryAddress << TT_ADDRESS_OFFSET_AT_LEVEL(IndexLevel);
|
|
||||||
|
|
||||||
// Set the correct entry type for the next page level
|
|
||||||
if ((IndexLevel + 1) == 3) {
|
|
||||||
Attributes |= TT_TYPE_BLOCK_ENTRY_LEVEL3;
|
|
||||||
} else {
|
|
||||||
Attributes |= TT_TYPE_BLOCK_ENTRY;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create a new translation table
|
|
||||||
TranslationTable = AllocatePages (1);
|
TranslationTable = AllocatePages (1);
|
||||||
if (TranslationTable == NULL) {
|
if (TranslationTable == NULL) {
|
||||||
return NULL;
|
return EFI_OUT_OF_RESOURCES;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Populate the newly created lower level table
|
if (!ArmMmuEnabled ()) {
|
||||||
SubTableBlockEntry = TranslationTable;
|
//
|
||||||
for (Index = 0; Index < TT_ENTRY_COUNT; Index++) {
|
// Make sure we are not inadvertently hitting in the caches
|
||||||
*SubTableBlockEntry = Attributes | (BlockEntryAddress + (Index << TT_ADDRESS_OFFSET_AT_LEVEL(IndexLevel + 1)));
|
// when populating the page tables.
|
||||||
SubTableBlockEntry++;
|
//
|
||||||
|
InvalidateDataCacheRange (TranslationTable, EFI_PAGE_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fill the BlockEntry with the new TranslationTable
|
ZeroMem (TranslationTable, EFI_PAGE_SIZE);
|
||||||
ReplaceLiveEntry (BlockEntry,
|
|
||||||
(UINTN)TranslationTable | TableAttributes | TT_TYPE_TABLE_ENTRY,
|
if (IsBlockEntry (*Entry, Level)) {
|
||||||
RegionStart);
|
//
|
||||||
|
// We are splitting an existing block entry, so we have to populate
|
||||||
|
// the new table with the attributes of the block entry it replaces.
|
||||||
|
//
|
||||||
|
Status = UpdateRegionMappingRecursive (RegionStart & ~BlockMask,
|
||||||
|
(RegionStart | BlockMask) + 1, *Entry & TT_ATTRIBUTES_MASK,
|
||||||
|
0, TranslationTable, Level + 1);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
//
|
||||||
|
// The range we passed to UpdateRegionMappingRecursive () is block
|
||||||
|
// aligned, so it is guaranteed that no further pages were allocated
|
||||||
|
// by it, and so we only have to free the page we allocated here.
|
||||||
|
//
|
||||||
|
FreePages (TranslationTable, 1);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
TranslationTable = (VOID *)(UINTN)(*Entry & TT_ADDRESS_MASK_BLOCK_ENTRY);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Recurse to the next level
|
||||||
|
//
|
||||||
|
Status = UpdateRegionMappingRecursive (RegionStart, BlockEnd,
|
||||||
|
AttributeSetMask, AttributeClearMask, TranslationTable,
|
||||||
|
Level + 1);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
if (!IsTableEntry (*Entry, Level)) {
|
||||||
|
//
|
||||||
|
// We are creating a new table entry, so on failure, we can free all
|
||||||
|
// allocations we made recursively, given that the whole subhierarchy
|
||||||
|
// has not been wired into the live page tables yet. (This is not
|
||||||
|
// possible for existing table entries, since we cannot revert the
|
||||||
|
// modifications we made to the subhierarchy it represents.)
|
||||||
|
//
|
||||||
|
FreePageTablesRecursive (TranslationTable, Level + 1);
|
||||||
|
}
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!IsTableEntry (*Entry, Level)) {
|
||||||
|
EntryValue = (UINTN)TranslationTable | TT_TYPE_TABLE_ENTRY;
|
||||||
|
ReplaceTableEntry (Entry, EntryValue, RegionStart,
|
||||||
|
IsBlockEntry (*Entry, Level));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (IndexLevel != PageLevel) {
|
EntryValue = (*Entry & AttributeClearMask) | AttributeSetMask;
|
||||||
|
EntryValue |= RegionStart;
|
||||||
|
EntryValue |= (Level == 3) ? TT_TYPE_BLOCK_ENTRY_LEVEL3
|
||||||
|
: TT_TYPE_BLOCK_ENTRY;
|
||||||
|
|
||||||
|
if (IsTableEntry (*Entry, Level)) {
|
||||||
//
|
//
|
||||||
// Case when we have an Invalid Entry and we are at a page level above of the one targetted.
|
// We are replacing a table entry with a block entry. This is only
|
||||||
|
// possible if we are keeping none of the original attributes.
|
||||||
|
// We can free the table entry's page table, and all the ones below
|
||||||
|
// it, since we are dropping the only possible reference to it.
|
||||||
//
|
//
|
||||||
|
ASSERT (AttributeClearMask == 0);
|
||||||
// Create a new translation table
|
TranslationTable = (VOID *)(UINTN)(*Entry & TT_ADDRESS_MASK_BLOCK_ENTRY);
|
||||||
TranslationTable = AllocatePages (1);
|
ReplaceTableEntry (Entry, EntryValue, RegionStart, TRUE);
|
||||||
if (TranslationTable == NULL) {
|
FreePageTablesRecursive (TranslationTable, Level + 1);
|
||||||
return NULL;
|
} else {
|
||||||
}
|
ReplaceTableEntry (Entry, EntryValue, RegionStart, FALSE);
|
||||||
|
|
||||||
ZeroMem (TranslationTable, TT_ENTRY_COUNT * sizeof(UINT64));
|
|
||||||
|
|
||||||
// Fill the new BlockEntry with the TranslationTable
|
|
||||||
*BlockEntry = ((UINTN)TranslationTable & TT_ADDRESS_MASK_DESCRIPTION_TABLE) | TT_TYPE_TABLE_ENTRY;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return EFI_SUCCESS;
|
||||||
// Expose the found PageLevel to the caller
|
|
||||||
*TableLevel = PageLevel;
|
|
||||||
|
|
||||||
// Now, we have the Table Level we can get the Block Size associated to this table
|
|
||||||
*BlockEntrySize = TT_BLOCK_ENTRY_SIZE_AT_LEVEL (PageLevel);
|
|
||||||
|
|
||||||
// The last block of the root table depends on the number of entry in this table,
|
|
||||||
// otherwise it is always the (TT_ENTRY_COUNT - 1)th entry in the table.
|
|
||||||
*LastBlockEntry = TT_LAST_BLOCK_ADDRESS(TranslationTable,
|
|
||||||
(PageLevel == RootTableLevel) ? RootTableEntryCount : TT_ENTRY_COUNT);
|
|
||||||
|
|
||||||
return BlockEntry;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
STATIC
|
STATIC
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
UpdateRegionMapping (
|
UpdateRegionMapping (
|
||||||
IN UINT64 *RootTable,
|
|
||||||
IN UINT64 RegionStart,
|
IN UINT64 RegionStart,
|
||||||
IN UINT64 RegionLength,
|
IN UINT64 RegionLength,
|
||||||
IN UINT64 Attributes,
|
IN UINT64 AttributeSetMask,
|
||||||
IN UINT64 BlockEntryMask
|
IN UINT64 AttributeClearMask
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
UINT32 Type;
|
UINTN T0SZ;
|
||||||
UINT64 *BlockEntry;
|
|
||||||
UINT64 *LastBlockEntry;
|
|
||||||
UINT64 BlockEntrySize;
|
|
||||||
UINTN TableLevel;
|
|
||||||
|
|
||||||
// Ensure the Length is aligned on 4KB boundary
|
if (((RegionStart | RegionLength) & EFI_PAGE_MASK)) {
|
||||||
if ((RegionLength == 0) || ((RegionLength & (SIZE_4KB - 1)) != 0)) {
|
|
||||||
ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER);
|
|
||||||
return EFI_INVALID_PARAMETER;
|
return EFI_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
|
|
||||||
do {
|
T0SZ = ArmGetTCR () & TCR_T0SZ_MASK;
|
||||||
// Get the first Block Entry that matches the Virtual Address and also the information on the Table Descriptor
|
|
||||||
// such as the size of the Block Entry and the address of the last BlockEntry of the Table Descriptor
|
|
||||||
BlockEntrySize = RegionLength;
|
|
||||||
BlockEntry = GetBlockEntryListFromAddress (RootTable, RegionStart, &TableLevel, &BlockEntrySize, &LastBlockEntry);
|
|
||||||
if (BlockEntry == NULL) {
|
|
||||||
// GetBlockEntryListFromAddress() return NULL when it fails to allocate new pages from the Translation Tables
|
|
||||||
return EFI_OUT_OF_RESOURCES;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (TableLevel != 3) {
|
return UpdateRegionMappingRecursive (RegionStart, RegionStart + RegionLength,
|
||||||
Type = TT_TYPE_BLOCK_ENTRY;
|
AttributeSetMask, AttributeClearMask, ArmGetTTBR0BaseAddress (),
|
||||||
} else {
|
GetRootTableLevel (T0SZ));
|
||||||
Type = TT_TYPE_BLOCK_ENTRY_LEVEL3;
|
|
||||||
}
|
|
||||||
|
|
||||||
do {
|
|
||||||
// Fill the Block Entry with attribute and output block address
|
|
||||||
*BlockEntry &= BlockEntryMask;
|
|
||||||
*BlockEntry |= (RegionStart & TT_ADDRESS_MASK_BLOCK_ENTRY) | Attributes | Type;
|
|
||||||
|
|
||||||
ArmUpdateTranslationTableEntry (BlockEntry, (VOID *)RegionStart);
|
|
||||||
|
|
||||||
// Go to the next BlockEntry
|
|
||||||
RegionStart += BlockEntrySize;
|
|
||||||
RegionLength -= BlockEntrySize;
|
|
||||||
BlockEntry++;
|
|
||||||
|
|
||||||
// Break the inner loop when next block is a table
|
|
||||||
// Rerun GetBlockEntryListFromAddress to avoid page table memory leak
|
|
||||||
if (TableLevel != 3 && BlockEntry <= LastBlockEntry &&
|
|
||||||
(*BlockEntry & TT_TYPE_MASK) == TT_TYPE_TABLE_ENTRY) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} while ((RegionLength >= BlockEntrySize) && (BlockEntry <= LastBlockEntry));
|
|
||||||
} while (RegionLength != 0);
|
|
||||||
|
|
||||||
return EFI_SUCCESS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
STATIC
|
STATIC
|
||||||
@@ -398,7 +313,6 @@ FillTranslationTable (
|
|||||||
)
|
)
|
||||||
{
|
{
|
||||||
return UpdateRegionMapping (
|
return UpdateRegionMapping (
|
||||||
RootTable,
|
|
||||||
MemoryRegion->VirtualBase,
|
MemoryRegion->VirtualBase,
|
||||||
MemoryRegion->Length,
|
MemoryRegion->Length,
|
||||||
ArmMemoryAttributeToPageAttribute (MemoryRegion->Attributes) | TT_AF,
|
ArmMemoryAttributeToPageAttribute (MemoryRegion->Attributes) | TT_AF,
|
||||||
@@ -455,8 +369,6 @@ ArmSetMemoryAttributes (
|
|||||||
IN UINT64 Attributes
|
IN UINT64 Attributes
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
EFI_STATUS Status;
|
|
||||||
UINT64 *TranslationTable;
|
|
||||||
UINT64 PageAttributes;
|
UINT64 PageAttributes;
|
||||||
UINT64 PageAttributeMask;
|
UINT64 PageAttributeMask;
|
||||||
|
|
||||||
@@ -473,19 +385,8 @@ ArmSetMemoryAttributes (
|
|||||||
TT_PXN_MASK | TT_XN_MASK);
|
TT_PXN_MASK | TT_XN_MASK);
|
||||||
}
|
}
|
||||||
|
|
||||||
TranslationTable = ArmGetTTBR0BaseAddress ();
|
return UpdateRegionMapping (BaseAddress, Length, PageAttributes,
|
||||||
|
PageAttributeMask);
|
||||||
Status = UpdateRegionMapping (
|
|
||||||
TranslationTable,
|
|
||||||
BaseAddress,
|
|
||||||
Length,
|
|
||||||
PageAttributes,
|
|
||||||
PageAttributeMask);
|
|
||||||
if (EFI_ERROR (Status)) {
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
return EFI_SUCCESS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
STATIC
|
STATIC
|
||||||
@@ -497,17 +398,7 @@ SetMemoryRegionAttribute (
|
|||||||
IN UINT64 BlockEntryMask
|
IN UINT64 BlockEntryMask
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
EFI_STATUS Status;
|
return UpdateRegionMapping (BaseAddress, Length, Attributes, BlockEntryMask);
|
||||||
UINT64 *RootTable;
|
|
||||||
|
|
||||||
RootTable = ArmGetTTBR0BaseAddress ();
|
|
||||||
|
|
||||||
Status = UpdateRegionMapping (RootTable, BaseAddress, Length, Attributes, BlockEntryMask);
|
|
||||||
if (EFI_ERROR (Status)) {
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
return EFI_SUCCESS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
@@ -584,14 +475,14 @@ ArmConfigureMmu (
|
|||||||
)
|
)
|
||||||
{
|
{
|
||||||
VOID* TranslationTable;
|
VOID* TranslationTable;
|
||||||
UINT32 TranslationTableAttribute;
|
UINTN MaxAddressBits;
|
||||||
UINT64 MaxAddress;
|
UINT64 MaxAddress;
|
||||||
UINTN T0SZ;
|
UINTN T0SZ;
|
||||||
UINTN RootTableEntryCount;
|
UINTN RootTableEntryCount;
|
||||||
UINT64 TCR;
|
UINT64 TCR;
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
|
|
||||||
if(MemoryTable == NULL) {
|
if (MemoryTable == NULL) {
|
||||||
ASSERT (MemoryTable != NULL);
|
ASSERT (MemoryTable != NULL);
|
||||||
return EFI_INVALID_PARAMETER;
|
return EFI_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
@@ -603,11 +494,11 @@ ArmConfigureMmu (
|
|||||||
// into account the architectural limitations that result from UEFI's
|
// into account the architectural limitations that result from UEFI's
|
||||||
// use of 4 KB pages.
|
// use of 4 KB pages.
|
||||||
//
|
//
|
||||||
MaxAddress = MIN (LShiftU64 (1ULL, ArmGetPhysicalAddressBits ()) - 1,
|
MaxAddressBits = MIN (ArmGetPhysicalAddressBits (), MAX_VA_BITS);
|
||||||
MAX_ALLOC_ADDRESS);
|
MaxAddress = LShiftU64 (1ULL, MaxAddressBits) - 1;
|
||||||
|
|
||||||
// Lookup the Table Level to get the information
|
T0SZ = 64 - MaxAddressBits;
|
||||||
LookupAddresstoRootTable (MaxAddress, &T0SZ, &RootTableEntryCount);
|
RootTableEntryCount = GetRootTableEntryCount (T0SZ);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Set TCR that allows us to retrieve T0SZ in the subsequent functions
|
// Set TCR that allows us to retrieve T0SZ in the subsequent functions
|
||||||
@@ -632,7 +523,9 @@ ArmConfigureMmu (
|
|||||||
} else if (MaxAddress < SIZE_256TB) {
|
} else if (MaxAddress < SIZE_256TB) {
|
||||||
TCR |= TCR_PS_256TB;
|
TCR |= TCR_PS_256TB;
|
||||||
} else {
|
} else {
|
||||||
DEBUG ((EFI_D_ERROR, "ArmConfigureMmu: The MaxAddress 0x%lX is not supported by this MMU configuration.\n", MaxAddress));
|
DEBUG ((DEBUG_ERROR,
|
||||||
|
"ArmConfigureMmu: The MaxAddress 0x%lX is not supported by this MMU configuration.\n",
|
||||||
|
MaxAddress));
|
||||||
ASSERT (0); // Bigger than 48-bit memory space are not supported
|
ASSERT (0); // Bigger than 48-bit memory space are not supported
|
||||||
return EFI_UNSUPPORTED;
|
return EFI_UNSUPPORTED;
|
||||||
}
|
}
|
||||||
@@ -654,7 +547,9 @@ ArmConfigureMmu (
|
|||||||
} else if (MaxAddress < SIZE_256TB) {
|
} else if (MaxAddress < SIZE_256TB) {
|
||||||
TCR |= TCR_IPS_256TB;
|
TCR |= TCR_IPS_256TB;
|
||||||
} else {
|
} else {
|
||||||
DEBUG ((EFI_D_ERROR, "ArmConfigureMmu: The MaxAddress 0x%lX is not supported by this MMU configuration.\n", MaxAddress));
|
DEBUG ((DEBUG_ERROR,
|
||||||
|
"ArmConfigureMmu: The MaxAddress 0x%lX is not supported by this MMU configuration.\n",
|
||||||
|
MaxAddress));
|
||||||
ASSERT (0); // Bigger than 48-bit memory space are not supported
|
ASSERT (0); // Bigger than 48-bit memory space are not supported
|
||||||
return EFI_UNSUPPORTED;
|
return EFI_UNSUPPORTED;
|
||||||
}
|
}
|
||||||
@@ -684,9 +579,12 @@ ArmConfigureMmu (
|
|||||||
if (TranslationTable == NULL) {
|
if (TranslationTable == NULL) {
|
||||||
return EFI_OUT_OF_RESOURCES;
|
return EFI_OUT_OF_RESOURCES;
|
||||||
}
|
}
|
||||||
// We set TTBR0 just after allocating the table to retrieve its location from the subsequent
|
//
|
||||||
// functions without needing to pass this value across the functions. The MMU is only enabled
|
// We set TTBR0 just after allocating the table to retrieve its location from
|
||||||
// after the translation tables are populated.
|
// the subsequent functions without needing to pass this value across the
|
||||||
|
// functions. The MMU is only enabled after the translation tables are
|
||||||
|
// populated.
|
||||||
|
//
|
||||||
ArmSetTTBR0 (TranslationTable);
|
ArmSetTTBR0 (TranslationTable);
|
||||||
|
|
||||||
if (TranslationTableBase != NULL) {
|
if (TranslationTableBase != NULL) {
|
||||||
@@ -694,46 +592,37 @@ ArmConfigureMmu (
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (TranslationTableSize != NULL) {
|
if (TranslationTableSize != NULL) {
|
||||||
*TranslationTableSize = RootTableEntryCount * sizeof(UINT64);
|
*TranslationTableSize = RootTableEntryCount * sizeof (UINT64);
|
||||||
}
|
}
|
||||||
|
|
||||||
ZeroMem (TranslationTable, RootTableEntryCount * sizeof(UINT64));
|
//
|
||||||
|
// Make sure we are not inadvertently hitting in the caches
|
||||||
|
// when populating the page tables.
|
||||||
|
//
|
||||||
|
InvalidateDataCacheRange (TranslationTable,
|
||||||
|
RootTableEntryCount * sizeof (UINT64));
|
||||||
|
ZeroMem (TranslationTable, RootTableEntryCount * sizeof (UINT64));
|
||||||
|
|
||||||
// Disable MMU and caches. ArmDisableMmu() also invalidates the TLBs
|
|
||||||
ArmDisableMmu ();
|
|
||||||
ArmDisableDataCache ();
|
|
||||||
ArmDisableInstructionCache ();
|
|
||||||
|
|
||||||
// Make sure nothing sneaked into the cache
|
|
||||||
ArmCleanInvalidateDataCache ();
|
|
||||||
ArmInvalidateInstructionCache ();
|
|
||||||
|
|
||||||
TranslationTableAttribute = TT_ATTR_INDX_INVALID;
|
|
||||||
while (MemoryTable->Length != 0) {
|
while (MemoryTable->Length != 0) {
|
||||||
|
|
||||||
DEBUG_CODE_BEGIN ();
|
|
||||||
// Find the memory attribute for the Translation Table
|
|
||||||
if ((UINTN)TranslationTable >= MemoryTable->PhysicalBase &&
|
|
||||||
(UINTN)TranslationTable + EFI_PAGE_SIZE <= MemoryTable->PhysicalBase +
|
|
||||||
MemoryTable->Length) {
|
|
||||||
TranslationTableAttribute = MemoryTable->Attributes;
|
|
||||||
}
|
|
||||||
DEBUG_CODE_END ();
|
|
||||||
|
|
||||||
Status = FillTranslationTable (TranslationTable, MemoryTable);
|
Status = FillTranslationTable (TranslationTable, MemoryTable);
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
goto FREE_TRANSLATION_TABLE;
|
goto FreeTranslationTable;
|
||||||
}
|
}
|
||||||
MemoryTable++;
|
MemoryTable++;
|
||||||
}
|
}
|
||||||
|
|
||||||
ASSERT (TranslationTableAttribute == ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK ||
|
//
|
||||||
TranslationTableAttribute == ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_WRITE_BACK);
|
// EFI_MEMORY_UC ==> MAIR_ATTR_DEVICE_MEMORY
|
||||||
|
// EFI_MEMORY_WC ==> MAIR_ATTR_NORMAL_MEMORY_NON_CACHEABLE
|
||||||
ArmSetMAIR (MAIR_ATTR(TT_ATTR_INDX_DEVICE_MEMORY, MAIR_ATTR_DEVICE_MEMORY) | // mapped to EFI_MEMORY_UC
|
// EFI_MEMORY_WT ==> MAIR_ATTR_NORMAL_MEMORY_WRITE_THROUGH
|
||||||
MAIR_ATTR(TT_ATTR_INDX_MEMORY_NON_CACHEABLE, MAIR_ATTR_NORMAL_MEMORY_NON_CACHEABLE) | // mapped to EFI_MEMORY_WC
|
// EFI_MEMORY_WB ==> MAIR_ATTR_NORMAL_MEMORY_WRITE_BACK
|
||||||
MAIR_ATTR(TT_ATTR_INDX_MEMORY_WRITE_THROUGH, MAIR_ATTR_NORMAL_MEMORY_WRITE_THROUGH) | // mapped to EFI_MEMORY_WT
|
//
|
||||||
MAIR_ATTR(TT_ATTR_INDX_MEMORY_WRITE_BACK, MAIR_ATTR_NORMAL_MEMORY_WRITE_BACK)); // mapped to EFI_MEMORY_WB
|
ArmSetMAIR (
|
||||||
|
MAIR_ATTR (TT_ATTR_INDX_DEVICE_MEMORY, MAIR_ATTR_DEVICE_MEMORY) |
|
||||||
|
MAIR_ATTR (TT_ATTR_INDX_MEMORY_NON_CACHEABLE, MAIR_ATTR_NORMAL_MEMORY_NON_CACHEABLE) |
|
||||||
|
MAIR_ATTR (TT_ATTR_INDX_MEMORY_WRITE_THROUGH, MAIR_ATTR_NORMAL_MEMORY_WRITE_THROUGH) |
|
||||||
|
MAIR_ATTR (TT_ATTR_INDX_MEMORY_WRITE_BACK, MAIR_ATTR_NORMAL_MEMORY_WRITE_BACK)
|
||||||
|
);
|
||||||
|
|
||||||
ArmDisableAlignmentCheck ();
|
ArmDisableAlignmentCheck ();
|
||||||
ArmEnableStackAlignmentCheck ();
|
ArmEnableStackAlignmentCheck ();
|
||||||
@@ -743,7 +632,7 @@ ArmConfigureMmu (
|
|||||||
ArmEnableMmu ();
|
ArmEnableMmu ();
|
||||||
return EFI_SUCCESS;
|
return EFI_SUCCESS;
|
||||||
|
|
||||||
FREE_TRANSLATION_TABLE:
|
FreeTranslationTable:
|
||||||
FreePages (TranslationTable, 1);
|
FreePages (TranslationTable, 1);
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
32
ArmPkg/Library/ArmMmuLib/Arm/ArmMmuLibConvert.c
Normal file
32
ArmPkg/Library/ArmMmuLib/Arm/ArmMmuLibConvert.c
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
/** @file
|
||||||
|
* File managing the MMU for ARMv7 architecture
|
||||||
|
*
|
||||||
|
* Copyright (c) 2011-2016, ARM Limited. All rights reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
|
*
|
||||||
|
**/
|
||||||
|
|
||||||
|
#include <Uefi.h>
|
||||||
|
|
||||||
|
#include <Library/ArmLib.h>
|
||||||
|
|
||||||
|
#include <Chipset/ArmV7.h>
|
||||||
|
|
||||||
|
UINT32
|
||||||
|
ConvertSectionAttributesToPageAttributes (
|
||||||
|
IN UINT32 SectionAttributes,
|
||||||
|
IN BOOLEAN IsLargePage
|
||||||
|
)
|
||||||
|
{
|
||||||
|
UINT32 PageAttributes;
|
||||||
|
|
||||||
|
PageAttributes = 0;
|
||||||
|
PageAttributes |= TT_DESCRIPTOR_CONVERT_TO_PAGE_CACHE_POLICY (SectionAttributes, IsLargePage);
|
||||||
|
PageAttributes |= TT_DESCRIPTOR_CONVERT_TO_PAGE_AP (SectionAttributes);
|
||||||
|
PageAttributes |= TT_DESCRIPTOR_CONVERT_TO_PAGE_XN (SectionAttributes, IsLargePage);
|
||||||
|
PageAttributes |= TT_DESCRIPTOR_CONVERT_TO_PAGE_NG (SectionAttributes);
|
||||||
|
PageAttributes |= TT_DESCRIPTOR_CONVERT_TO_PAGE_S (SectionAttributes);
|
||||||
|
|
||||||
|
return PageAttributes;
|
||||||
|
}
|
@@ -31,15 +31,6 @@
|
|||||||
#define ID_MMFR0_SHR_IMP_HW_COHERENT 1
|
#define ID_MMFR0_SHR_IMP_HW_COHERENT 1
|
||||||
#define ID_MMFR0_SHR_IGNORED 0xf
|
#define ID_MMFR0_SHR_IGNORED 0xf
|
||||||
|
|
||||||
#define __EFI_MEMORY_RWX 0 // no restrictions
|
|
||||||
|
|
||||||
#define CACHE_ATTRIBUTE_MASK (EFI_MEMORY_UC | \
|
|
||||||
EFI_MEMORY_WC | \
|
|
||||||
EFI_MEMORY_WT | \
|
|
||||||
EFI_MEMORY_WB | \
|
|
||||||
EFI_MEMORY_UCE | \
|
|
||||||
EFI_MEMORY_WP)
|
|
||||||
|
|
||||||
UINTN
|
UINTN
|
||||||
EFIAPI
|
EFIAPI
|
||||||
ArmReadIdMmfr0 (
|
ArmReadIdMmfr0 (
|
||||||
@@ -52,24 +43,6 @@ ArmHasMpExtensions (
|
|||||||
VOID
|
VOID
|
||||||
);
|
);
|
||||||
|
|
||||||
UINT32
|
|
||||||
ConvertSectionAttributesToPageAttributes (
|
|
||||||
IN UINT32 SectionAttributes,
|
|
||||||
IN BOOLEAN IsLargePage
|
|
||||||
)
|
|
||||||
{
|
|
||||||
UINT32 PageAttributes;
|
|
||||||
|
|
||||||
PageAttributes = 0;
|
|
||||||
PageAttributes |= TT_DESCRIPTOR_CONVERT_TO_PAGE_CACHE_POLICY (SectionAttributes, IsLargePage);
|
|
||||||
PageAttributes |= TT_DESCRIPTOR_CONVERT_TO_PAGE_AP (SectionAttributes);
|
|
||||||
PageAttributes |= TT_DESCRIPTOR_CONVERT_TO_PAGE_XN (SectionAttributes, IsLargePage);
|
|
||||||
PageAttributes |= TT_DESCRIPTOR_CONVERT_TO_PAGE_NG (SectionAttributes);
|
|
||||||
PageAttributes |= TT_DESCRIPTOR_CONVERT_TO_PAGE_S (SectionAttributes);
|
|
||||||
|
|
||||||
return PageAttributes;
|
|
||||||
}
|
|
||||||
|
|
||||||
STATIC
|
STATIC
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
PreferNonshareableMemory (
|
PreferNonshareableMemory (
|
||||||
@@ -165,14 +138,22 @@ PopulateLevel2PageTable (
|
|||||||
// Case where a virtual memory map descriptor overlapped a section entry
|
// Case where a virtual memory map descriptor overlapped a section entry
|
||||||
|
|
||||||
// Allocate a Level2 Page Table for this Section
|
// Allocate a Level2 Page Table for this Section
|
||||||
TranslationTable = (UINTN)AllocatePages(EFI_SIZE_TO_PAGES(TRANSLATION_TABLE_PAGE_SIZE + TRANSLATION_TABLE_PAGE_ALIGNMENT));
|
TranslationTable = (UINTN)AllocateAlignedPages (
|
||||||
TranslationTable = ((UINTN)TranslationTable + TRANSLATION_TABLE_PAGE_ALIGNMENT_MASK) & ~TRANSLATION_TABLE_PAGE_ALIGNMENT_MASK;
|
EFI_SIZE_TO_PAGES (TRANSLATION_TABLE_PAGE_SIZE),
|
||||||
|
TRANSLATION_TABLE_PAGE_ALIGNMENT);
|
||||||
|
|
||||||
// Translate the Section Descriptor into Page Descriptor
|
// Translate the Section Descriptor into Page Descriptor
|
||||||
SectionDescriptor = TT_DESCRIPTOR_PAGE_TYPE_PAGE | ConvertSectionAttributesToPageAttributes (*SectionEntry, FALSE);
|
SectionDescriptor = TT_DESCRIPTOR_PAGE_TYPE_PAGE | ConvertSectionAttributesToPageAttributes (*SectionEntry, FALSE);
|
||||||
|
|
||||||
BaseSectionAddress = TT_DESCRIPTOR_SECTION_BASE_ADDRESS(*SectionEntry);
|
BaseSectionAddress = TT_DESCRIPTOR_SECTION_BASE_ADDRESS(*SectionEntry);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Make sure we are not inadvertently hitting in the caches
|
||||||
|
// when populating the page tables
|
||||||
|
//
|
||||||
|
InvalidateDataCacheRange ((VOID *)TranslationTable,
|
||||||
|
TRANSLATION_TABLE_PAGE_SIZE);
|
||||||
|
|
||||||
// Populate the new Level2 Page Table for the section
|
// Populate the new Level2 Page Table for the section
|
||||||
PageEntry = (UINT32*)TranslationTable;
|
PageEntry = (UINT32*)TranslationTable;
|
||||||
for (Index = 0; Index < TRANSLATION_TABLE_PAGE_COUNT; Index++) {
|
for (Index = 0; Index < TRANSLATION_TABLE_PAGE_COUNT; Index++) {
|
||||||
@@ -189,9 +170,15 @@ PopulateLevel2PageTable (
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
TranslationTable = (UINTN)AllocatePages(EFI_SIZE_TO_PAGES(TRANSLATION_TABLE_PAGE_SIZE + TRANSLATION_TABLE_PAGE_ALIGNMENT));
|
TranslationTable = (UINTN)AllocateAlignedPages (
|
||||||
TranslationTable = ((UINTN)TranslationTable + TRANSLATION_TABLE_PAGE_ALIGNMENT_MASK) & ~TRANSLATION_TABLE_PAGE_ALIGNMENT_MASK;
|
EFI_SIZE_TO_PAGES (TRANSLATION_TABLE_PAGE_SIZE),
|
||||||
|
TRANSLATION_TABLE_PAGE_ALIGNMENT);
|
||||||
|
//
|
||||||
|
// Make sure we are not inadvertently hitting in the caches
|
||||||
|
// when populating the page tables
|
||||||
|
//
|
||||||
|
InvalidateDataCacheRange ((VOID *)TranslationTable,
|
||||||
|
TRANSLATION_TABLE_PAGE_SIZE);
|
||||||
ZeroMem ((VOID *)TranslationTable, TRANSLATION_TABLE_PAGE_SIZE);
|
ZeroMem ((VOID *)TranslationTable, TRANSLATION_TABLE_PAGE_SIZE);
|
||||||
|
|
||||||
*SectionEntry = (TranslationTable & TT_DESCRIPTOR_SECTION_PAGETABLE_ADDRESS_MASK) |
|
*SectionEntry = (TranslationTable & TT_DESCRIPTOR_SECTION_PAGETABLE_ADDRESS_MASK) |
|
||||||
@@ -210,6 +197,13 @@ PopulateLevel2PageTable (
|
|||||||
PhysicalBase += TT_DESCRIPTOR_PAGE_SIZE;
|
PhysicalBase += TT_DESCRIPTOR_PAGE_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Invalidate again to ensure that any line fetches that may have occurred
|
||||||
|
// [speculatively] since the previous invalidate are evicted again.
|
||||||
|
//
|
||||||
|
ArmDataMemoryBarrier ();
|
||||||
|
InvalidateDataCacheRange ((UINT32 *)TranslationTable + FirstPageOffset,
|
||||||
|
RemainLength / TT_DESCRIPTOR_PAGE_SIZE * sizeof (*PageEntry));
|
||||||
}
|
}
|
||||||
|
|
||||||
STATIC
|
STATIC
|
||||||
@@ -284,7 +278,16 @@ FillTranslationTable (
|
|||||||
RemainLength >= TT_DESCRIPTOR_SECTION_SIZE) {
|
RemainLength >= TT_DESCRIPTOR_SECTION_SIZE) {
|
||||||
// Case: Physical address aligned on the Section Size (1MB) && the length
|
// Case: Physical address aligned on the Section Size (1MB) && the length
|
||||||
// is greater than the Section Size
|
// is greater than the Section Size
|
||||||
*SectionEntry++ = TT_DESCRIPTOR_SECTION_BASE_ADDRESS(PhysicalBase) | Attributes;
|
*SectionEntry = TT_DESCRIPTOR_SECTION_BASE_ADDRESS(PhysicalBase) | Attributes;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Issue a DMB to ensure that the page table entry update made it to
|
||||||
|
// memory before we issue the invalidate, otherwise, a subsequent
|
||||||
|
// speculative fetch could observe the old value.
|
||||||
|
//
|
||||||
|
ArmDataMemoryBarrier ();
|
||||||
|
ArmInvalidateDataCacheEntryByMVA ((UINTN)SectionEntry++);
|
||||||
|
|
||||||
PhysicalBase += TT_DESCRIPTOR_SECTION_SIZE;
|
PhysicalBase += TT_DESCRIPTOR_SECTION_SIZE;
|
||||||
RemainLength -= TT_DESCRIPTOR_SECTION_SIZE;
|
RemainLength -= TT_DESCRIPTOR_SECTION_SIZE;
|
||||||
} else {
|
} else {
|
||||||
@@ -294,9 +297,17 @@ FillTranslationTable (
|
|||||||
// Case: Physical address aligned on the Section Size (1MB) && the length
|
// Case: Physical address aligned on the Section Size (1MB) && the length
|
||||||
// does not fill a section
|
// does not fill a section
|
||||||
// Case: Physical address NOT aligned on the Section Size (1MB)
|
// Case: Physical address NOT aligned on the Section Size (1MB)
|
||||||
PopulateLevel2PageTable (SectionEntry++, PhysicalBase, PageMapLength,
|
PopulateLevel2PageTable (SectionEntry, PhysicalBase, PageMapLength,
|
||||||
MemoryRegion->Attributes);
|
MemoryRegion->Attributes);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Issue a DMB to ensure that the page table entry update made it to
|
||||||
|
// memory before we issue the invalidate, otherwise, a subsequent
|
||||||
|
// speculative fetch could observe the old value.
|
||||||
|
//
|
||||||
|
ArmDataMemoryBarrier ();
|
||||||
|
ArmInvalidateDataCacheEntryByMVA ((UINTN)SectionEntry++);
|
||||||
|
|
||||||
// If it is the last entry
|
// If it is the last entry
|
||||||
if (RemainLength < TT_DESCRIPTOR_SECTION_SIZE) {
|
if (RemainLength < TT_DESCRIPTOR_SECTION_SIZE) {
|
||||||
break;
|
break;
|
||||||
@@ -316,16 +327,15 @@ ArmConfigureMmu (
|
|||||||
OUT UINTN *TranslationTableSize OPTIONAL
|
OUT UINTN *TranslationTableSize OPTIONAL
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
VOID* TranslationTable;
|
VOID *TranslationTable;
|
||||||
ARM_MEMORY_REGION_ATTRIBUTES TranslationTableAttribute;
|
|
||||||
UINT32 TTBRAttributes;
|
UINT32 TTBRAttributes;
|
||||||
|
|
||||||
// Allocate pages for translation table.
|
TranslationTable = AllocateAlignedPages (
|
||||||
TranslationTable = AllocatePages (EFI_SIZE_TO_PAGES (TRANSLATION_TABLE_SECTION_SIZE + TRANSLATION_TABLE_SECTION_ALIGNMENT));
|
EFI_SIZE_TO_PAGES (TRANSLATION_TABLE_SECTION_SIZE),
|
||||||
|
TRANSLATION_TABLE_SECTION_ALIGNMENT);
|
||||||
if (TranslationTable == NULL) {
|
if (TranslationTable == NULL) {
|
||||||
return RETURN_OUT_OF_RESOURCES;
|
return RETURN_OUT_OF_RESOURCES;
|
||||||
}
|
}
|
||||||
TranslationTable = (VOID*)(((UINTN)TranslationTable + TRANSLATION_TABLE_SECTION_ALIGNMENT_MASK) & ~TRANSLATION_TABLE_SECTION_ALIGNMENT_MASK);
|
|
||||||
|
|
||||||
if (TranslationTableBase != NULL) {
|
if (TranslationTableBase != NULL) {
|
||||||
*TranslationTableBase = TranslationTable;
|
*TranslationTableBase = TranslationTable;
|
||||||
@@ -335,30 +345,20 @@ ArmConfigureMmu (
|
|||||||
*TranslationTableSize = TRANSLATION_TABLE_SECTION_SIZE;
|
*TranslationTableSize = TRANSLATION_TABLE_SECTION_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Make sure we are not inadvertently hitting in the caches
|
||||||
|
// when populating the page tables
|
||||||
|
//
|
||||||
|
InvalidateDataCacheRange (TranslationTable, TRANSLATION_TABLE_SECTION_SIZE);
|
||||||
ZeroMem (TranslationTable, TRANSLATION_TABLE_SECTION_SIZE);
|
ZeroMem (TranslationTable, TRANSLATION_TABLE_SECTION_SIZE);
|
||||||
|
|
||||||
// By default, mark the translation table as belonging to a uncached region
|
|
||||||
TranslationTableAttribute = ARM_MEMORY_REGION_ATTRIBUTE_UNCACHED_UNBUFFERED;
|
|
||||||
while (MemoryTable->Length != 0) {
|
while (MemoryTable->Length != 0) {
|
||||||
// Find the memory attribute for the Translation Table
|
|
||||||
if (((UINTN)TranslationTable >= MemoryTable->PhysicalBase) && ((UINTN)TranslationTable <= MemoryTable->PhysicalBase - 1 + MemoryTable->Length)) {
|
|
||||||
TranslationTableAttribute = MemoryTable->Attributes;
|
|
||||||
}
|
|
||||||
|
|
||||||
FillTranslationTable (TranslationTable, MemoryTable);
|
FillTranslationTable (TranslationTable, MemoryTable);
|
||||||
MemoryTable++;
|
MemoryTable++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Translate the Memory Attributes into Translation Table Register Attributes
|
TTBRAttributes = ArmHasMpExtensions () ? TTBR_MP_WRITE_BACK_ALLOC
|
||||||
if ((TranslationTableAttribute == ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK) ||
|
: TTBR_WRITE_BACK_ALLOC;
|
||||||
(TranslationTableAttribute == ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_WRITE_BACK)) {
|
|
||||||
TTBRAttributes = ArmHasMpExtensions () ? TTBR_MP_WRITE_BACK_ALLOC : TTBR_WRITE_BACK_ALLOC;
|
|
||||||
} else {
|
|
||||||
// Page tables must reside in memory mapped as write-back cacheable
|
|
||||||
ASSERT (0);
|
|
||||||
return RETURN_UNSUPPORTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (TTBRAttributes & TTBR_SHAREABLE) {
|
if (TTBRAttributes & TTBR_SHAREABLE) {
|
||||||
if (PreferNonshareableMemory ()) {
|
if (PreferNonshareableMemory ()) {
|
||||||
TTBRAttributes ^= TTBR_SHAREABLE;
|
TTBRAttributes ^= TTBR_SHAREABLE;
|
||||||
@@ -376,19 +376,7 @@ ArmConfigureMmu (
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ArmCleanInvalidateDataCache ();
|
ArmSetTTBR0 ((VOID *)((UINTN)TranslationTable | TTBRAttributes));
|
||||||
ArmInvalidateInstructionCache ();
|
|
||||||
|
|
||||||
ArmDisableDataCache ();
|
|
||||||
ArmDisableInstructionCache();
|
|
||||||
// TLBs are also invalidated when calling ArmDisableMmu()
|
|
||||||
ArmDisableMmu ();
|
|
||||||
|
|
||||||
// Make sure nothing sneaked into the cache
|
|
||||||
ArmCleanInvalidateDataCache ();
|
|
||||||
ArmInvalidateInstructionCache ();
|
|
||||||
|
|
||||||
ArmSetTTBR0 ((VOID *)(UINTN)(((UINTN)TranslationTable & ~TRANSLATION_TABLE_SECTION_ALIGNMENT_MASK) | (TTBRAttributes & 0x7F)));
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// The TTBCR register value is undefined at reset in the Non-Secure world.
|
// The TTBCR register value is undefined at reset in the Non-Secure world.
|
||||||
@@ -423,419 +411,3 @@ ArmConfigureMmu (
|
|||||||
ArmEnableMmu();
|
ArmEnableMmu();
|
||||||
return RETURN_SUCCESS;
|
return RETURN_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
STATIC
|
|
||||||
EFI_STATUS
|
|
||||||
ConvertSectionToPages (
|
|
||||||
IN EFI_PHYSICAL_ADDRESS BaseAddress
|
|
||||||
)
|
|
||||||
{
|
|
||||||
UINT32 FirstLevelIdx;
|
|
||||||
UINT32 SectionDescriptor;
|
|
||||||
UINT32 PageTableDescriptor;
|
|
||||||
UINT32 PageDescriptor;
|
|
||||||
UINT32 Index;
|
|
||||||
|
|
||||||
volatile ARM_FIRST_LEVEL_DESCRIPTOR *FirstLevelTable;
|
|
||||||
volatile ARM_PAGE_TABLE_ENTRY *PageTable;
|
|
||||||
|
|
||||||
DEBUG ((EFI_D_PAGE, "Converting section at 0x%x to pages\n", (UINTN)BaseAddress));
|
|
||||||
|
|
||||||
// Obtain page table base
|
|
||||||
FirstLevelTable = (ARM_FIRST_LEVEL_DESCRIPTOR *)ArmGetTTBR0BaseAddress ();
|
|
||||||
|
|
||||||
// Calculate index into first level translation table for start of modification
|
|
||||||
FirstLevelIdx = TT_DESCRIPTOR_SECTION_BASE_ADDRESS(BaseAddress) >> TT_DESCRIPTOR_SECTION_BASE_SHIFT;
|
|
||||||
ASSERT (FirstLevelIdx < TRANSLATION_TABLE_SECTION_COUNT);
|
|
||||||
|
|
||||||
// Get section attributes and convert to page attributes
|
|
||||||
SectionDescriptor = FirstLevelTable[FirstLevelIdx];
|
|
||||||
PageDescriptor = TT_DESCRIPTOR_PAGE_TYPE_PAGE | ConvertSectionAttributesToPageAttributes (SectionDescriptor, FALSE);
|
|
||||||
|
|
||||||
// Allocate a page table for the 4KB entries (we use up a full page even though we only need 1KB)
|
|
||||||
PageTable = (volatile ARM_PAGE_TABLE_ENTRY *)AllocatePages (1);
|
|
||||||
if (PageTable == NULL) {
|
|
||||||
return EFI_OUT_OF_RESOURCES;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Write the page table entries out
|
|
||||||
for (Index = 0; Index < TRANSLATION_TABLE_PAGE_COUNT; Index++) {
|
|
||||||
PageTable[Index] = TT_DESCRIPTOR_PAGE_BASE_ADDRESS(BaseAddress + (Index << 12)) | PageDescriptor;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Formulate page table entry, Domain=0, NS=0
|
|
||||||
PageTableDescriptor = (((UINTN)PageTable) & TT_DESCRIPTOR_SECTION_PAGETABLE_ADDRESS_MASK) | TT_DESCRIPTOR_SECTION_TYPE_PAGE_TABLE;
|
|
||||||
|
|
||||||
// Write the page table entry out, replacing section entry
|
|
||||||
FirstLevelTable[FirstLevelIdx] = PageTableDescriptor;
|
|
||||||
|
|
||||||
return EFI_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
STATIC
|
|
||||||
EFI_STATUS
|
|
||||||
UpdatePageEntries (
|
|
||||||
IN EFI_PHYSICAL_ADDRESS BaseAddress,
|
|
||||||
IN UINT64 Length,
|
|
||||||
IN UINT64 Attributes,
|
|
||||||
OUT BOOLEAN *FlushTlbs OPTIONAL
|
|
||||||
)
|
|
||||||
{
|
|
||||||
EFI_STATUS Status;
|
|
||||||
UINT32 EntryValue;
|
|
||||||
UINT32 EntryMask;
|
|
||||||
UINT32 FirstLevelIdx;
|
|
||||||
UINT32 Offset;
|
|
||||||
UINT32 NumPageEntries;
|
|
||||||
UINT32 Descriptor;
|
|
||||||
UINT32 p;
|
|
||||||
UINT32 PageTableIndex;
|
|
||||||
UINT32 PageTableEntry;
|
|
||||||
UINT32 CurrentPageTableEntry;
|
|
||||||
VOID *Mva;
|
|
||||||
|
|
||||||
volatile ARM_FIRST_LEVEL_DESCRIPTOR *FirstLevelTable;
|
|
||||||
volatile ARM_PAGE_TABLE_ENTRY *PageTable;
|
|
||||||
|
|
||||||
Status = EFI_SUCCESS;
|
|
||||||
|
|
||||||
// EntryMask: bitmask of values to change (1 = change this value, 0 = leave alone)
|
|
||||||
// EntryValue: values at bit positions specified by EntryMask
|
|
||||||
EntryMask = TT_DESCRIPTOR_PAGE_TYPE_MASK | TT_DESCRIPTOR_PAGE_AP_MASK;
|
|
||||||
if (Attributes & EFI_MEMORY_XP) {
|
|
||||||
EntryValue = TT_DESCRIPTOR_PAGE_TYPE_PAGE_XN;
|
|
||||||
} else {
|
|
||||||
EntryValue = TT_DESCRIPTOR_PAGE_TYPE_PAGE;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Although the PI spec is unclear on this, the GCD guarantees that only
|
|
||||||
// one Attribute bit is set at a time, so the order of the conditionals below
|
|
||||||
// is irrelevant. If no memory attribute is specified, we preserve whatever
|
|
||||||
// memory type is set in the page tables, and update the permission attributes
|
|
||||||
// only.
|
|
||||||
if (Attributes & EFI_MEMORY_UC) {
|
|
||||||
// modify cacheability attributes
|
|
||||||
EntryMask |= TT_DESCRIPTOR_PAGE_CACHE_POLICY_MASK;
|
|
||||||
// map to strongly ordered
|
|
||||||
EntryValue |= TT_DESCRIPTOR_PAGE_CACHE_POLICY_STRONGLY_ORDERED; // TEX[2:0] = 0, C=0, B=0
|
|
||||||
} else if (Attributes & EFI_MEMORY_WC) {
|
|
||||||
// modify cacheability attributes
|
|
||||||
EntryMask |= TT_DESCRIPTOR_PAGE_CACHE_POLICY_MASK;
|
|
||||||
// map to normal non-cachable
|
|
||||||
EntryValue |= TT_DESCRIPTOR_PAGE_CACHE_POLICY_NON_CACHEABLE; // TEX [2:0]= 001 = 0x2, B=0, C=0
|
|
||||||
} else if (Attributes & EFI_MEMORY_WT) {
|
|
||||||
// modify cacheability attributes
|
|
||||||
EntryMask |= TT_DESCRIPTOR_PAGE_CACHE_POLICY_MASK;
|
|
||||||
// write through with no-allocate
|
|
||||||
EntryValue |= TT_DESCRIPTOR_PAGE_CACHE_POLICY_WRITE_THROUGH_NO_ALLOC; // TEX [2:0] = 0, C=1, B=0
|
|
||||||
} else if (Attributes & EFI_MEMORY_WB) {
|
|
||||||
// modify cacheability attributes
|
|
||||||
EntryMask |= TT_DESCRIPTOR_PAGE_CACHE_POLICY_MASK;
|
|
||||||
// write back (with allocate)
|
|
||||||
EntryValue |= TT_DESCRIPTOR_PAGE_CACHE_POLICY_WRITE_BACK_ALLOC; // TEX [2:0] = 001, C=1, B=1
|
|
||||||
} else if (Attributes & CACHE_ATTRIBUTE_MASK) {
|
|
||||||
// catch unsupported memory type attributes
|
|
||||||
ASSERT (FALSE);
|
|
||||||
return EFI_UNSUPPORTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Attributes & EFI_MEMORY_RO) {
|
|
||||||
EntryValue |= TT_DESCRIPTOR_PAGE_AP_RO_RO;
|
|
||||||
} else {
|
|
||||||
EntryValue |= TT_DESCRIPTOR_PAGE_AP_RW_RW;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Obtain page table base
|
|
||||||
FirstLevelTable = (ARM_FIRST_LEVEL_DESCRIPTOR *)ArmGetTTBR0BaseAddress ();
|
|
||||||
|
|
||||||
// Calculate number of 4KB page table entries to change
|
|
||||||
NumPageEntries = Length / TT_DESCRIPTOR_PAGE_SIZE;
|
|
||||||
|
|
||||||
// Iterate for the number of 4KB pages to change
|
|
||||||
Offset = 0;
|
|
||||||
for(p = 0; p < NumPageEntries; p++) {
|
|
||||||
// Calculate index into first level translation table for page table value
|
|
||||||
|
|
||||||
FirstLevelIdx = TT_DESCRIPTOR_SECTION_BASE_ADDRESS(BaseAddress + Offset) >> TT_DESCRIPTOR_SECTION_BASE_SHIFT;
|
|
||||||
ASSERT (FirstLevelIdx < TRANSLATION_TABLE_SECTION_COUNT);
|
|
||||||
|
|
||||||
// Read the descriptor from the first level page table
|
|
||||||
Descriptor = FirstLevelTable[FirstLevelIdx];
|
|
||||||
|
|
||||||
// Does this descriptor need to be converted from section entry to 4K pages?
|
|
||||||
if (!TT_DESCRIPTOR_SECTION_TYPE_IS_PAGE_TABLE(Descriptor)) {
|
|
||||||
Status = ConvertSectionToPages (FirstLevelIdx << TT_DESCRIPTOR_SECTION_BASE_SHIFT);
|
|
||||||
if (EFI_ERROR(Status)) {
|
|
||||||
// Exit for loop
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Re-read descriptor
|
|
||||||
Descriptor = FirstLevelTable[FirstLevelIdx];
|
|
||||||
if (FlushTlbs != NULL) {
|
|
||||||
*FlushTlbs = TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Obtain page table base address
|
|
||||||
PageTable = (ARM_PAGE_TABLE_ENTRY *)TT_DESCRIPTOR_PAGE_BASE_ADDRESS(Descriptor);
|
|
||||||
|
|
||||||
// Calculate index into the page table
|
|
||||||
PageTableIndex = ((BaseAddress + Offset) & TT_DESCRIPTOR_PAGE_INDEX_MASK) >> TT_DESCRIPTOR_PAGE_BASE_SHIFT;
|
|
||||||
ASSERT (PageTableIndex < TRANSLATION_TABLE_PAGE_COUNT);
|
|
||||||
|
|
||||||
// Get the entry
|
|
||||||
CurrentPageTableEntry = PageTable[PageTableIndex];
|
|
||||||
|
|
||||||
// Mask off appropriate fields
|
|
||||||
PageTableEntry = CurrentPageTableEntry & ~EntryMask;
|
|
||||||
|
|
||||||
// Mask in new attributes and/or permissions
|
|
||||||
PageTableEntry |= EntryValue;
|
|
||||||
|
|
||||||
if (CurrentPageTableEntry != PageTableEntry) {
|
|
||||||
Mva = (VOID *)(UINTN)((((UINTN)FirstLevelIdx) << TT_DESCRIPTOR_SECTION_BASE_SHIFT) + (PageTableIndex << TT_DESCRIPTOR_PAGE_BASE_SHIFT));
|
|
||||||
|
|
||||||
// Only need to update if we are changing the entry
|
|
||||||
PageTable[PageTableIndex] = PageTableEntry;
|
|
||||||
ArmUpdateTranslationTableEntry ((VOID *)&PageTable[PageTableIndex], Mva);
|
|
||||||
}
|
|
||||||
|
|
||||||
Status = EFI_SUCCESS;
|
|
||||||
Offset += TT_DESCRIPTOR_PAGE_SIZE;
|
|
||||||
|
|
||||||
} // End first level translation table loop
|
|
||||||
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
STATIC
|
|
||||||
EFI_STATUS
|
|
||||||
UpdateSectionEntries (
|
|
||||||
IN EFI_PHYSICAL_ADDRESS BaseAddress,
|
|
||||||
IN UINT64 Length,
|
|
||||||
IN UINT64 Attributes
|
|
||||||
)
|
|
||||||
{
|
|
||||||
EFI_STATUS Status = EFI_SUCCESS;
|
|
||||||
UINT32 EntryMask;
|
|
||||||
UINT32 EntryValue;
|
|
||||||
UINT32 FirstLevelIdx;
|
|
||||||
UINT32 NumSections;
|
|
||||||
UINT32 i;
|
|
||||||
UINT32 CurrentDescriptor;
|
|
||||||
UINT32 Descriptor;
|
|
||||||
VOID *Mva;
|
|
||||||
volatile ARM_FIRST_LEVEL_DESCRIPTOR *FirstLevelTable;
|
|
||||||
|
|
||||||
// EntryMask: bitmask of values to change (1 = change this value, 0 = leave alone)
|
|
||||||
// EntryValue: values at bit positions specified by EntryMask
|
|
||||||
|
|
||||||
// Make sure we handle a section range that is unmapped
|
|
||||||
EntryMask = TT_DESCRIPTOR_SECTION_TYPE_MASK | TT_DESCRIPTOR_SECTION_XN_MASK |
|
|
||||||
TT_DESCRIPTOR_SECTION_AP_MASK;
|
|
||||||
EntryValue = TT_DESCRIPTOR_SECTION_TYPE_SECTION;
|
|
||||||
|
|
||||||
// Although the PI spec is unclear on this, the GCD guarantees that only
|
|
||||||
// one Attribute bit is set at a time, so the order of the conditionals below
|
|
||||||
// is irrelevant. If no memory attribute is specified, we preserve whatever
|
|
||||||
// memory type is set in the page tables, and update the permission attributes
|
|
||||||
// only.
|
|
||||||
if (Attributes & EFI_MEMORY_UC) {
|
|
||||||
// modify cacheability attributes
|
|
||||||
EntryMask |= TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK;
|
|
||||||
// map to strongly ordered
|
|
||||||
EntryValue |= TT_DESCRIPTOR_SECTION_CACHE_POLICY_STRONGLY_ORDERED; // TEX[2:0] = 0, C=0, B=0
|
|
||||||
} else if (Attributes & EFI_MEMORY_WC) {
|
|
||||||
// modify cacheability attributes
|
|
||||||
EntryMask |= TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK;
|
|
||||||
// map to normal non-cachable
|
|
||||||
EntryValue |= TT_DESCRIPTOR_SECTION_CACHE_POLICY_NON_CACHEABLE; // TEX [2:0]= 001 = 0x2, B=0, C=0
|
|
||||||
} else if (Attributes & EFI_MEMORY_WT) {
|
|
||||||
// modify cacheability attributes
|
|
||||||
EntryMask |= TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK;
|
|
||||||
// write through with no-allocate
|
|
||||||
EntryValue |= TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_THROUGH_NO_ALLOC; // TEX [2:0] = 0, C=1, B=0
|
|
||||||
} else if (Attributes & EFI_MEMORY_WB) {
|
|
||||||
// modify cacheability attributes
|
|
||||||
EntryMask |= TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK;
|
|
||||||
// write back (with allocate)
|
|
||||||
EntryValue |= TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_BACK_ALLOC; // TEX [2:0] = 001, C=1, B=1
|
|
||||||
} else if (Attributes & CACHE_ATTRIBUTE_MASK) {
|
|
||||||
// catch unsupported memory type attributes
|
|
||||||
ASSERT (FALSE);
|
|
||||||
return EFI_UNSUPPORTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Attributes & EFI_MEMORY_RO) {
|
|
||||||
EntryValue |= TT_DESCRIPTOR_SECTION_AP_RO_RO;
|
|
||||||
} else {
|
|
||||||
EntryValue |= TT_DESCRIPTOR_SECTION_AP_RW_RW;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Attributes & EFI_MEMORY_XP) {
|
|
||||||
EntryValue |= TT_DESCRIPTOR_SECTION_XN_MASK;
|
|
||||||
}
|
|
||||||
|
|
||||||
// obtain page table base
|
|
||||||
FirstLevelTable = (ARM_FIRST_LEVEL_DESCRIPTOR *)ArmGetTTBR0BaseAddress ();
|
|
||||||
|
|
||||||
// calculate index into first level translation table for start of modification
|
|
||||||
FirstLevelIdx = TT_DESCRIPTOR_SECTION_BASE_ADDRESS(BaseAddress) >> TT_DESCRIPTOR_SECTION_BASE_SHIFT;
|
|
||||||
ASSERT (FirstLevelIdx < TRANSLATION_TABLE_SECTION_COUNT);
|
|
||||||
|
|
||||||
// calculate number of 1MB first level entries this applies to
|
|
||||||
NumSections = Length / TT_DESCRIPTOR_SECTION_SIZE;
|
|
||||||
|
|
||||||
// iterate through each descriptor
|
|
||||||
for(i=0; i<NumSections; i++) {
|
|
||||||
CurrentDescriptor = FirstLevelTable[FirstLevelIdx + i];
|
|
||||||
|
|
||||||
// has this descriptor already been converted to pages?
|
|
||||||
if (TT_DESCRIPTOR_SECTION_TYPE_IS_PAGE_TABLE(CurrentDescriptor)) {
|
|
||||||
// forward this 1MB range to page table function instead
|
|
||||||
Status = UpdatePageEntries (
|
|
||||||
(FirstLevelIdx + i) << TT_DESCRIPTOR_SECTION_BASE_SHIFT,
|
|
||||||
TT_DESCRIPTOR_SECTION_SIZE,
|
|
||||||
Attributes,
|
|
||||||
NULL);
|
|
||||||
} else {
|
|
||||||
// still a section entry
|
|
||||||
|
|
||||||
if (CurrentDescriptor != 0) {
|
|
||||||
// mask off appropriate fields
|
|
||||||
Descriptor = CurrentDescriptor & ~EntryMask;
|
|
||||||
} else {
|
|
||||||
Descriptor = ((UINTN)FirstLevelIdx + i) << TT_DESCRIPTOR_SECTION_BASE_SHIFT;
|
|
||||||
}
|
|
||||||
|
|
||||||
// mask in new attributes and/or permissions
|
|
||||||
Descriptor |= EntryValue;
|
|
||||||
|
|
||||||
if (CurrentDescriptor != Descriptor) {
|
|
||||||
Mva = (VOID *)(UINTN)(((UINTN)FirstLevelIdx + i) << TT_DESCRIPTOR_SECTION_BASE_SHIFT);
|
|
||||||
|
|
||||||
// Only need to update if we are changing the descriptor
|
|
||||||
FirstLevelTable[FirstLevelIdx + i] = Descriptor;
|
|
||||||
ArmUpdateTranslationTableEntry ((VOID *)&FirstLevelTable[FirstLevelIdx + i], Mva);
|
|
||||||
}
|
|
||||||
|
|
||||||
Status = EFI_SUCCESS;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
EFI_STATUS
|
|
||||||
ArmSetMemoryAttributes (
|
|
||||||
IN EFI_PHYSICAL_ADDRESS BaseAddress,
|
|
||||||
IN UINT64 Length,
|
|
||||||
IN UINT64 Attributes
|
|
||||||
)
|
|
||||||
{
|
|
||||||
EFI_STATUS Status;
|
|
||||||
UINT64 ChunkLength;
|
|
||||||
BOOLEAN FlushTlbs;
|
|
||||||
|
|
||||||
if (BaseAddress > (UINT64)MAX_ADDRESS) {
|
|
||||||
return EFI_UNSUPPORTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
Length = MIN (Length, (UINT64)MAX_ADDRESS - BaseAddress + 1);
|
|
||||||
if (Length == 0) {
|
|
||||||
return EFI_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
FlushTlbs = FALSE;
|
|
||||||
while (Length > 0) {
|
|
||||||
if ((BaseAddress % TT_DESCRIPTOR_SECTION_SIZE == 0) &&
|
|
||||||
Length >= TT_DESCRIPTOR_SECTION_SIZE) {
|
|
||||||
|
|
||||||
ChunkLength = Length - Length % TT_DESCRIPTOR_SECTION_SIZE;
|
|
||||||
|
|
||||||
DEBUG ((DEBUG_PAGE,
|
|
||||||
"SetMemoryAttributes(): MMU section 0x%lx length 0x%lx to %lx\n",
|
|
||||||
BaseAddress, ChunkLength, Attributes));
|
|
||||||
|
|
||||||
Status = UpdateSectionEntries (BaseAddress, ChunkLength, Attributes);
|
|
||||||
|
|
||||||
FlushTlbs = TRUE;
|
|
||||||
} else {
|
|
||||||
|
|
||||||
//
|
|
||||||
// Process page by page until the next section boundary, but only if
|
|
||||||
// we have more than a section's worth of area to deal with after that.
|
|
||||||
//
|
|
||||||
ChunkLength = TT_DESCRIPTOR_SECTION_SIZE -
|
|
||||||
(BaseAddress % TT_DESCRIPTOR_SECTION_SIZE);
|
|
||||||
if (ChunkLength + TT_DESCRIPTOR_SECTION_SIZE > Length) {
|
|
||||||
ChunkLength = Length;
|
|
||||||
}
|
|
||||||
|
|
||||||
DEBUG ((DEBUG_PAGE,
|
|
||||||
"SetMemoryAttributes(): MMU page 0x%lx length 0x%lx to %lx\n",
|
|
||||||
BaseAddress, ChunkLength, Attributes));
|
|
||||||
|
|
||||||
Status = UpdatePageEntries (BaseAddress, ChunkLength, Attributes,
|
|
||||||
&FlushTlbs);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (EFI_ERROR (Status)) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
BaseAddress += ChunkLength;
|
|
||||||
Length -= ChunkLength;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (FlushTlbs) {
|
|
||||||
ArmInvalidateTlb ();
|
|
||||||
}
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
EFI_STATUS
|
|
||||||
ArmSetMemoryRegionNoExec (
|
|
||||||
IN EFI_PHYSICAL_ADDRESS BaseAddress,
|
|
||||||
IN UINT64 Length
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return ArmSetMemoryAttributes (BaseAddress, Length, EFI_MEMORY_XP);
|
|
||||||
}
|
|
||||||
|
|
||||||
EFI_STATUS
|
|
||||||
ArmClearMemoryRegionNoExec (
|
|
||||||
IN EFI_PHYSICAL_ADDRESS BaseAddress,
|
|
||||||
IN UINT64 Length
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return ArmSetMemoryAttributes (BaseAddress, Length, __EFI_MEMORY_RWX);
|
|
||||||
}
|
|
||||||
|
|
||||||
EFI_STATUS
|
|
||||||
ArmSetMemoryRegionReadOnly (
|
|
||||||
IN EFI_PHYSICAL_ADDRESS BaseAddress,
|
|
||||||
IN UINT64 Length
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return ArmSetMemoryAttributes (BaseAddress, Length, EFI_MEMORY_RO);
|
|
||||||
}
|
|
||||||
|
|
||||||
EFI_STATUS
|
|
||||||
ArmClearMemoryRegionReadOnly (
|
|
||||||
IN EFI_PHYSICAL_ADDRESS BaseAddress,
|
|
||||||
IN UINT64 Length
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return ArmSetMemoryAttributes (BaseAddress, Length, __EFI_MEMORY_RWX);
|
|
||||||
}
|
|
||||||
|
|
||||||
RETURN_STATUS
|
|
||||||
EFIAPI
|
|
||||||
ArmMmuBaseLibConstructor (
|
|
||||||
VOID
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return RETURN_SUCCESS;
|
|
||||||
}
|
|
||||||
|
435
ArmPkg/Library/ArmMmuLib/Arm/ArmMmuLibUpdate.c
Normal file
435
ArmPkg/Library/ArmMmuLib/Arm/ArmMmuLibUpdate.c
Normal file
@@ -0,0 +1,435 @@
|
|||||||
|
/** @file
|
||||||
|
* File managing the MMU for ARMv7 architecture
|
||||||
|
*
|
||||||
|
* Copyright (c) 2011-2016, ARM Limited. All rights reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
|
*
|
||||||
|
**/
|
||||||
|
|
||||||
|
#include <Uefi.h>
|
||||||
|
|
||||||
|
#include <Library/ArmLib.h>
|
||||||
|
#include <Library/BaseLib.h>
|
||||||
|
#include <Library/BaseMemoryLib.h>
|
||||||
|
#include <Library/DebugLib.h>
|
||||||
|
#include <Library/CacheMaintenanceLib.h>
|
||||||
|
#include <Library/MemoryAllocationLib.h>
|
||||||
|
|
||||||
|
#include <Chipset/ArmV7.h>
|
||||||
|
|
||||||
|
#define __EFI_MEMORY_RWX 0 // no restrictions
|
||||||
|
|
||||||
|
#define CACHE_ATTRIBUTE_MASK (EFI_MEMORY_UC | \
|
||||||
|
EFI_MEMORY_WC | \
|
||||||
|
EFI_MEMORY_WT | \
|
||||||
|
EFI_MEMORY_WB | \
|
||||||
|
EFI_MEMORY_UCE | \
|
||||||
|
EFI_MEMORY_WP)
|
||||||
|
|
||||||
|
STATIC
|
||||||
|
EFI_STATUS
|
||||||
|
ConvertSectionToPages (
|
||||||
|
IN EFI_PHYSICAL_ADDRESS BaseAddress
|
||||||
|
)
|
||||||
|
{
|
||||||
|
UINT32 FirstLevelIdx;
|
||||||
|
UINT32 SectionDescriptor;
|
||||||
|
UINT32 PageTableDescriptor;
|
||||||
|
UINT32 PageDescriptor;
|
||||||
|
UINT32 Index;
|
||||||
|
|
||||||
|
volatile ARM_FIRST_LEVEL_DESCRIPTOR *FirstLevelTable;
|
||||||
|
volatile ARM_PAGE_TABLE_ENTRY *PageTable;
|
||||||
|
|
||||||
|
DEBUG ((DEBUG_PAGE, "Converting section at 0x%x to pages\n", (UINTN)BaseAddress));
|
||||||
|
|
||||||
|
// Obtain page table base
|
||||||
|
FirstLevelTable = (ARM_FIRST_LEVEL_DESCRIPTOR *)ArmGetTTBR0BaseAddress ();
|
||||||
|
|
||||||
|
// Calculate index into first level translation table for start of modification
|
||||||
|
FirstLevelIdx = TT_DESCRIPTOR_SECTION_BASE_ADDRESS(BaseAddress) >> TT_DESCRIPTOR_SECTION_BASE_SHIFT;
|
||||||
|
ASSERT (FirstLevelIdx < TRANSLATION_TABLE_SECTION_COUNT);
|
||||||
|
|
||||||
|
// Get section attributes and convert to page attributes
|
||||||
|
SectionDescriptor = FirstLevelTable[FirstLevelIdx];
|
||||||
|
PageDescriptor = TT_DESCRIPTOR_PAGE_TYPE_PAGE | ConvertSectionAttributesToPageAttributes (SectionDescriptor, FALSE);
|
||||||
|
|
||||||
|
// Allocate a page table for the 4KB entries (we use up a full page even though we only need 1KB)
|
||||||
|
PageTable = (volatile ARM_PAGE_TABLE_ENTRY *)AllocatePages (1);
|
||||||
|
if (PageTable == NULL) {
|
||||||
|
return EFI_OUT_OF_RESOURCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write the page table entries out
|
||||||
|
for (Index = 0; Index < TRANSLATION_TABLE_PAGE_COUNT; Index++) {
|
||||||
|
PageTable[Index] = TT_DESCRIPTOR_PAGE_BASE_ADDRESS(BaseAddress + (Index << 12)) | PageDescriptor;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Formulate page table entry, Domain=0, NS=0
|
||||||
|
PageTableDescriptor = (((UINTN)PageTable) & TT_DESCRIPTOR_SECTION_PAGETABLE_ADDRESS_MASK) | TT_DESCRIPTOR_SECTION_TYPE_PAGE_TABLE;
|
||||||
|
|
||||||
|
// Write the page table entry out, replacing section entry
|
||||||
|
FirstLevelTable[FirstLevelIdx] = PageTableDescriptor;
|
||||||
|
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC
|
||||||
|
EFI_STATUS
|
||||||
|
UpdatePageEntries (
|
||||||
|
IN EFI_PHYSICAL_ADDRESS BaseAddress,
|
||||||
|
IN UINT64 Length,
|
||||||
|
IN UINT64 Attributes,
|
||||||
|
OUT BOOLEAN *FlushTlbs OPTIONAL
|
||||||
|
)
|
||||||
|
{
|
||||||
|
EFI_STATUS Status;
|
||||||
|
UINT32 EntryValue;
|
||||||
|
UINT32 EntryMask;
|
||||||
|
UINT32 FirstLevelIdx;
|
||||||
|
UINT32 Offset;
|
||||||
|
UINT32 NumPageEntries;
|
||||||
|
UINT32 Descriptor;
|
||||||
|
UINT32 p;
|
||||||
|
UINT32 PageTableIndex;
|
||||||
|
UINT32 PageTableEntry;
|
||||||
|
UINT32 CurrentPageTableEntry;
|
||||||
|
VOID *Mva;
|
||||||
|
|
||||||
|
volatile ARM_FIRST_LEVEL_DESCRIPTOR *FirstLevelTable;
|
||||||
|
volatile ARM_PAGE_TABLE_ENTRY *PageTable;
|
||||||
|
|
||||||
|
Status = EFI_SUCCESS;
|
||||||
|
|
||||||
|
// EntryMask: bitmask of values to change (1 = change this value, 0 = leave alone)
|
||||||
|
// EntryValue: values at bit positions specified by EntryMask
|
||||||
|
EntryMask = TT_DESCRIPTOR_PAGE_TYPE_MASK | TT_DESCRIPTOR_PAGE_AP_MASK;
|
||||||
|
if (Attributes & EFI_MEMORY_XP) {
|
||||||
|
EntryValue = TT_DESCRIPTOR_PAGE_TYPE_PAGE_XN;
|
||||||
|
} else {
|
||||||
|
EntryValue = TT_DESCRIPTOR_PAGE_TYPE_PAGE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Although the PI spec is unclear on this, the GCD guarantees that only
|
||||||
|
// one Attribute bit is set at a time, so the order of the conditionals below
|
||||||
|
// is irrelevant. If no memory attribute is specified, we preserve whatever
|
||||||
|
// memory type is set in the page tables, and update the permission attributes
|
||||||
|
// only.
|
||||||
|
if (Attributes & EFI_MEMORY_UC) {
|
||||||
|
// modify cacheability attributes
|
||||||
|
EntryMask |= TT_DESCRIPTOR_PAGE_CACHE_POLICY_MASK;
|
||||||
|
// map to strongly ordered
|
||||||
|
EntryValue |= TT_DESCRIPTOR_PAGE_CACHE_POLICY_STRONGLY_ORDERED; // TEX[2:0] = 0, C=0, B=0
|
||||||
|
} else if (Attributes & EFI_MEMORY_WC) {
|
||||||
|
// modify cacheability attributes
|
||||||
|
EntryMask |= TT_DESCRIPTOR_PAGE_CACHE_POLICY_MASK;
|
||||||
|
// map to normal non-cachable
|
||||||
|
EntryValue |= TT_DESCRIPTOR_PAGE_CACHE_POLICY_NON_CACHEABLE; // TEX [2:0]= 001 = 0x2, B=0, C=0
|
||||||
|
} else if (Attributes & EFI_MEMORY_WT) {
|
||||||
|
// modify cacheability attributes
|
||||||
|
EntryMask |= TT_DESCRIPTOR_PAGE_CACHE_POLICY_MASK;
|
||||||
|
// write through with no-allocate
|
||||||
|
EntryValue |= TT_DESCRIPTOR_PAGE_CACHE_POLICY_WRITE_THROUGH_NO_ALLOC; // TEX [2:0] = 0, C=1, B=0
|
||||||
|
} else if (Attributes & EFI_MEMORY_WB) {
|
||||||
|
// modify cacheability attributes
|
||||||
|
EntryMask |= TT_DESCRIPTOR_PAGE_CACHE_POLICY_MASK;
|
||||||
|
// write back (with allocate)
|
||||||
|
EntryValue |= TT_DESCRIPTOR_PAGE_CACHE_POLICY_WRITE_BACK_ALLOC; // TEX [2:0] = 001, C=1, B=1
|
||||||
|
} else if (Attributes & CACHE_ATTRIBUTE_MASK) {
|
||||||
|
// catch unsupported memory type attributes
|
||||||
|
ASSERT (FALSE);
|
||||||
|
return EFI_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Attributes & EFI_MEMORY_RO) {
|
||||||
|
EntryValue |= TT_DESCRIPTOR_PAGE_AP_RO_RO;
|
||||||
|
} else {
|
||||||
|
EntryValue |= TT_DESCRIPTOR_PAGE_AP_RW_RW;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Obtain page table base
|
||||||
|
FirstLevelTable = (ARM_FIRST_LEVEL_DESCRIPTOR *)ArmGetTTBR0BaseAddress ();
|
||||||
|
|
||||||
|
// Calculate number of 4KB page table entries to change
|
||||||
|
NumPageEntries = Length / TT_DESCRIPTOR_PAGE_SIZE;
|
||||||
|
|
||||||
|
// Iterate for the number of 4KB pages to change
|
||||||
|
Offset = 0;
|
||||||
|
for(p = 0; p < NumPageEntries; p++) {
|
||||||
|
// Calculate index into first level translation table for page table value
|
||||||
|
|
||||||
|
FirstLevelIdx = TT_DESCRIPTOR_SECTION_BASE_ADDRESS(BaseAddress + Offset) >> TT_DESCRIPTOR_SECTION_BASE_SHIFT;
|
||||||
|
ASSERT (FirstLevelIdx < TRANSLATION_TABLE_SECTION_COUNT);
|
||||||
|
|
||||||
|
// Read the descriptor from the first level page table
|
||||||
|
Descriptor = FirstLevelTable[FirstLevelIdx];
|
||||||
|
|
||||||
|
// Does this descriptor need to be converted from section entry to 4K pages?
|
||||||
|
if (!TT_DESCRIPTOR_SECTION_TYPE_IS_PAGE_TABLE(Descriptor)) {
|
||||||
|
Status = ConvertSectionToPages (FirstLevelIdx << TT_DESCRIPTOR_SECTION_BASE_SHIFT);
|
||||||
|
if (EFI_ERROR(Status)) {
|
||||||
|
// Exit for loop
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Re-read descriptor
|
||||||
|
Descriptor = FirstLevelTable[FirstLevelIdx];
|
||||||
|
if (FlushTlbs != NULL) {
|
||||||
|
*FlushTlbs = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Obtain page table base address
|
||||||
|
PageTable = (ARM_PAGE_TABLE_ENTRY *)TT_DESCRIPTOR_PAGE_BASE_ADDRESS(Descriptor);
|
||||||
|
|
||||||
|
// Calculate index into the page table
|
||||||
|
PageTableIndex = ((BaseAddress + Offset) & TT_DESCRIPTOR_PAGE_INDEX_MASK) >> TT_DESCRIPTOR_PAGE_BASE_SHIFT;
|
||||||
|
ASSERT (PageTableIndex < TRANSLATION_TABLE_PAGE_COUNT);
|
||||||
|
|
||||||
|
// Get the entry
|
||||||
|
CurrentPageTableEntry = PageTable[PageTableIndex];
|
||||||
|
|
||||||
|
// Mask off appropriate fields
|
||||||
|
PageTableEntry = CurrentPageTableEntry & ~EntryMask;
|
||||||
|
|
||||||
|
// Mask in new attributes and/or permissions
|
||||||
|
PageTableEntry |= EntryValue;
|
||||||
|
|
||||||
|
if (CurrentPageTableEntry != PageTableEntry) {
|
||||||
|
Mva = (VOID *)(UINTN)((((UINTN)FirstLevelIdx) << TT_DESCRIPTOR_SECTION_BASE_SHIFT) + (PageTableIndex << TT_DESCRIPTOR_PAGE_BASE_SHIFT));
|
||||||
|
|
||||||
|
// Only need to update if we are changing the entry
|
||||||
|
PageTable[PageTableIndex] = PageTableEntry;
|
||||||
|
ArmUpdateTranslationTableEntry ((VOID *)&PageTable[PageTableIndex], Mva);
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = EFI_SUCCESS;
|
||||||
|
Offset += TT_DESCRIPTOR_PAGE_SIZE;
|
||||||
|
|
||||||
|
} // End first level translation table loop
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC
|
||||||
|
EFI_STATUS
|
||||||
|
UpdateSectionEntries (
|
||||||
|
IN EFI_PHYSICAL_ADDRESS BaseAddress,
|
||||||
|
IN UINT64 Length,
|
||||||
|
IN UINT64 Attributes
|
||||||
|
)
|
||||||
|
{
|
||||||
|
EFI_STATUS Status = EFI_SUCCESS;
|
||||||
|
UINT32 EntryMask;
|
||||||
|
UINT32 EntryValue;
|
||||||
|
UINT32 FirstLevelIdx;
|
||||||
|
UINT32 NumSections;
|
||||||
|
UINT32 i;
|
||||||
|
UINT32 CurrentDescriptor;
|
||||||
|
UINT32 Descriptor;
|
||||||
|
VOID *Mva;
|
||||||
|
volatile ARM_FIRST_LEVEL_DESCRIPTOR *FirstLevelTable;
|
||||||
|
|
||||||
|
// EntryMask: bitmask of values to change (1 = change this value, 0 = leave alone)
|
||||||
|
// EntryValue: values at bit positions specified by EntryMask
|
||||||
|
|
||||||
|
// Make sure we handle a section range that is unmapped
|
||||||
|
EntryMask = TT_DESCRIPTOR_SECTION_TYPE_MASK | TT_DESCRIPTOR_SECTION_XN_MASK |
|
||||||
|
TT_DESCRIPTOR_SECTION_AP_MASK;
|
||||||
|
EntryValue = TT_DESCRIPTOR_SECTION_TYPE_SECTION;
|
||||||
|
|
||||||
|
// Although the PI spec is unclear on this, the GCD guarantees that only
|
||||||
|
// one Attribute bit is set at a time, so the order of the conditionals below
|
||||||
|
// is irrelevant. If no memory attribute is specified, we preserve whatever
|
||||||
|
// memory type is set in the page tables, and update the permission attributes
|
||||||
|
// only.
|
||||||
|
if (Attributes & EFI_MEMORY_UC) {
|
||||||
|
// modify cacheability attributes
|
||||||
|
EntryMask |= TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK;
|
||||||
|
// map to strongly ordered
|
||||||
|
EntryValue |= TT_DESCRIPTOR_SECTION_CACHE_POLICY_STRONGLY_ORDERED; // TEX[2:0] = 0, C=0, B=0
|
||||||
|
} else if (Attributes & EFI_MEMORY_WC) {
|
||||||
|
// modify cacheability attributes
|
||||||
|
EntryMask |= TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK;
|
||||||
|
// map to normal non-cachable
|
||||||
|
EntryValue |= TT_DESCRIPTOR_SECTION_CACHE_POLICY_NON_CACHEABLE; // TEX [2:0]= 001 = 0x2, B=0, C=0
|
||||||
|
} else if (Attributes & EFI_MEMORY_WT) {
|
||||||
|
// modify cacheability attributes
|
||||||
|
EntryMask |= TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK;
|
||||||
|
// write through with no-allocate
|
||||||
|
EntryValue |= TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_THROUGH_NO_ALLOC; // TEX [2:0] = 0, C=1, B=0
|
||||||
|
} else if (Attributes & EFI_MEMORY_WB) {
|
||||||
|
// modify cacheability attributes
|
||||||
|
EntryMask |= TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK;
|
||||||
|
// write back (with allocate)
|
||||||
|
EntryValue |= TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_BACK_ALLOC; // TEX [2:0] = 001, C=1, B=1
|
||||||
|
} else if (Attributes & CACHE_ATTRIBUTE_MASK) {
|
||||||
|
// catch unsupported memory type attributes
|
||||||
|
ASSERT (FALSE);
|
||||||
|
return EFI_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Attributes & EFI_MEMORY_RO) {
|
||||||
|
EntryValue |= TT_DESCRIPTOR_SECTION_AP_RO_RO;
|
||||||
|
} else {
|
||||||
|
EntryValue |= TT_DESCRIPTOR_SECTION_AP_RW_RW;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Attributes & EFI_MEMORY_XP) {
|
||||||
|
EntryValue |= TT_DESCRIPTOR_SECTION_XN_MASK;
|
||||||
|
}
|
||||||
|
|
||||||
|
// obtain page table base
|
||||||
|
FirstLevelTable = (ARM_FIRST_LEVEL_DESCRIPTOR *)ArmGetTTBR0BaseAddress ();
|
||||||
|
|
||||||
|
// calculate index into first level translation table for start of modification
|
||||||
|
FirstLevelIdx = TT_DESCRIPTOR_SECTION_BASE_ADDRESS(BaseAddress) >> TT_DESCRIPTOR_SECTION_BASE_SHIFT;
|
||||||
|
ASSERT (FirstLevelIdx < TRANSLATION_TABLE_SECTION_COUNT);
|
||||||
|
|
||||||
|
// calculate number of 1MB first level entries this applies to
|
||||||
|
NumSections = Length / TT_DESCRIPTOR_SECTION_SIZE;
|
||||||
|
|
||||||
|
// iterate through each descriptor
|
||||||
|
for(i=0; i<NumSections; i++) {
|
||||||
|
CurrentDescriptor = FirstLevelTable[FirstLevelIdx + i];
|
||||||
|
|
||||||
|
// has this descriptor already been converted to pages?
|
||||||
|
if (TT_DESCRIPTOR_SECTION_TYPE_IS_PAGE_TABLE(CurrentDescriptor)) {
|
||||||
|
// forward this 1MB range to page table function instead
|
||||||
|
Status = UpdatePageEntries (
|
||||||
|
(FirstLevelIdx + i) << TT_DESCRIPTOR_SECTION_BASE_SHIFT,
|
||||||
|
TT_DESCRIPTOR_SECTION_SIZE,
|
||||||
|
Attributes,
|
||||||
|
NULL);
|
||||||
|
} else {
|
||||||
|
// still a section entry
|
||||||
|
|
||||||
|
if (CurrentDescriptor != 0) {
|
||||||
|
// mask off appropriate fields
|
||||||
|
Descriptor = CurrentDescriptor & ~EntryMask;
|
||||||
|
} else {
|
||||||
|
Descriptor = ((UINTN)FirstLevelIdx + i) << TT_DESCRIPTOR_SECTION_BASE_SHIFT;
|
||||||
|
}
|
||||||
|
|
||||||
|
// mask in new attributes and/or permissions
|
||||||
|
Descriptor |= EntryValue;
|
||||||
|
|
||||||
|
if (CurrentDescriptor != Descriptor) {
|
||||||
|
Mva = (VOID *)(UINTN)(((UINTN)FirstLevelIdx + i) << TT_DESCRIPTOR_SECTION_BASE_SHIFT);
|
||||||
|
|
||||||
|
// Only need to update if we are changing the descriptor
|
||||||
|
FirstLevelTable[FirstLevelIdx + i] = Descriptor;
|
||||||
|
ArmUpdateTranslationTableEntry ((VOID *)&FirstLevelTable[FirstLevelIdx + i], Mva);
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
ArmSetMemoryAttributes (
|
||||||
|
IN EFI_PHYSICAL_ADDRESS BaseAddress,
|
||||||
|
IN UINT64 Length,
|
||||||
|
IN UINT64 Attributes
|
||||||
|
)
|
||||||
|
{
|
||||||
|
EFI_STATUS Status;
|
||||||
|
UINT64 ChunkLength;
|
||||||
|
BOOLEAN FlushTlbs;
|
||||||
|
|
||||||
|
if (BaseAddress > (UINT64)MAX_ADDRESS) {
|
||||||
|
return EFI_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
Length = MIN (Length, (UINT64)MAX_ADDRESS - BaseAddress + 1);
|
||||||
|
if (Length == 0) {
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
FlushTlbs = FALSE;
|
||||||
|
while (Length > 0) {
|
||||||
|
if ((BaseAddress % TT_DESCRIPTOR_SECTION_SIZE == 0) &&
|
||||||
|
Length >= TT_DESCRIPTOR_SECTION_SIZE) {
|
||||||
|
|
||||||
|
ChunkLength = Length - Length % TT_DESCRIPTOR_SECTION_SIZE;
|
||||||
|
|
||||||
|
DEBUG ((DEBUG_PAGE,
|
||||||
|
"SetMemoryAttributes(): MMU section 0x%lx length 0x%lx to %lx\n",
|
||||||
|
BaseAddress, ChunkLength, Attributes));
|
||||||
|
|
||||||
|
Status = UpdateSectionEntries (BaseAddress, ChunkLength, Attributes);
|
||||||
|
|
||||||
|
FlushTlbs = TRUE;
|
||||||
|
} else {
|
||||||
|
|
||||||
|
//
|
||||||
|
// Process page by page until the next section boundary, but only if
|
||||||
|
// we have more than a section's worth of area to deal with after that.
|
||||||
|
//
|
||||||
|
ChunkLength = TT_DESCRIPTOR_SECTION_SIZE -
|
||||||
|
(BaseAddress % TT_DESCRIPTOR_SECTION_SIZE);
|
||||||
|
if (ChunkLength + TT_DESCRIPTOR_SECTION_SIZE > Length) {
|
||||||
|
ChunkLength = Length;
|
||||||
|
}
|
||||||
|
|
||||||
|
DEBUG ((DEBUG_PAGE,
|
||||||
|
"SetMemoryAttributes(): MMU page 0x%lx length 0x%lx to %lx\n",
|
||||||
|
BaseAddress, ChunkLength, Attributes));
|
||||||
|
|
||||||
|
Status = UpdatePageEntries (BaseAddress, ChunkLength, Attributes,
|
||||||
|
&FlushTlbs);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
BaseAddress += ChunkLength;
|
||||||
|
Length -= ChunkLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (FlushTlbs) {
|
||||||
|
ArmInvalidateTlb ();
|
||||||
|
}
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
ArmSetMemoryRegionNoExec (
|
||||||
|
IN EFI_PHYSICAL_ADDRESS BaseAddress,
|
||||||
|
IN UINT64 Length
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return ArmSetMemoryAttributes (BaseAddress, Length, EFI_MEMORY_XP);
|
||||||
|
}
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
ArmClearMemoryRegionNoExec (
|
||||||
|
IN EFI_PHYSICAL_ADDRESS BaseAddress,
|
||||||
|
IN UINT64 Length
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return ArmSetMemoryAttributes (BaseAddress, Length, __EFI_MEMORY_RWX);
|
||||||
|
}
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
ArmSetMemoryRegionReadOnly (
|
||||||
|
IN EFI_PHYSICAL_ADDRESS BaseAddress,
|
||||||
|
IN UINT64 Length
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return ArmSetMemoryAttributes (BaseAddress, Length, EFI_MEMORY_RO);
|
||||||
|
}
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
ArmClearMemoryRegionReadOnly (
|
||||||
|
IN EFI_PHYSICAL_ADDRESS BaseAddress,
|
||||||
|
IN UINT64 Length
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return ArmSetMemoryAttributes (BaseAddress, Length, __EFI_MEMORY_RWX);
|
||||||
|
}
|
@@ -14,6 +14,8 @@
|
|||||||
MODULE_TYPE = BASE
|
MODULE_TYPE = BASE
|
||||||
VERSION_STRING = 1.0
|
VERSION_STRING = 1.0
|
||||||
LIBRARY_CLASS = ArmMmuLib
|
LIBRARY_CLASS = ArmMmuLib
|
||||||
|
|
||||||
|
[Defines.AARCH64]
|
||||||
CONSTRUCTOR = ArmMmuBaseLibConstructor
|
CONSTRUCTOR = ArmMmuBaseLibConstructor
|
||||||
|
|
||||||
[Sources.AARCH64]
|
[Sources.AARCH64]
|
||||||
@@ -21,7 +23,9 @@
|
|||||||
AArch64/ArmMmuLibReplaceEntry.S
|
AArch64/ArmMmuLibReplaceEntry.S
|
||||||
|
|
||||||
[Sources.ARM]
|
[Sources.ARM]
|
||||||
|
Arm/ArmMmuLibConvert.c
|
||||||
Arm/ArmMmuLibCore.c
|
Arm/ArmMmuLibCore.c
|
||||||
|
Arm/ArmMmuLibUpdate.c
|
||||||
Arm/ArmMmuLibV7Support.S |GCC
|
Arm/ArmMmuLibV7Support.S |GCC
|
||||||
Arm/ArmMmuLibV7Support.asm |RVCT
|
Arm/ArmMmuLibV7Support.asm |RVCT
|
||||||
|
|
||||||
|
@@ -1,16 +1,16 @@
|
|||||||
//
|
//
|
||||||
// Copyright (c) 2016, Linaro Limited. All rights reserved.
|
// Copyright (c) 2016, Linaro Limited. All rights reserved.
|
||||||
//
|
//
|
||||||
// SPDX-License-Identifier: BSD-2-Clause-Patent
|
// SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
|
|
||||||
#include <Base.h>
|
#include <Base.h>
|
||||||
#include <Library/ArmSmcLib.h>
|
#include <Library/ArmSmcLib.h>
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
ArmCallSmc (
|
ArmCallSmc (
|
||||||
IN OUT ARM_SMC_ARGS *Args
|
IN OUT ARM_SMC_ARGS *Args
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@@ -1,24 +0,0 @@
|
|||||||
/** @file
|
|
||||||
ResetSystemLib implementation using PSCI calls
|
|
||||||
|
|
||||||
Copyright (c) 2018, Linaro Ltd. All rights reserved.<BR>
|
|
||||||
|
|
||||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
|
||||||
|
|
||||||
**/
|
|
||||||
|
|
||||||
#include <AsmMacroIoLibV8.h>
|
|
||||||
|
|
||||||
ASM_FUNC(DisableMmuAndReenterPei)
|
|
||||||
stp x29, x30, [sp, #-16]!
|
|
||||||
mov x29, sp
|
|
||||||
|
|
||||||
bl ArmDisableMmu
|
|
||||||
|
|
||||||
// no memory accesses after MMU and caches have been disabled
|
|
||||||
|
|
||||||
MOV64 (x0, FixedPcdGet64 (PcdFvBaseAddress))
|
|
||||||
blr x0
|
|
||||||
|
|
||||||
// never returns
|
|
||||||
nop
|
|
@@ -1,29 +0,0 @@
|
|||||||
;/** @file
|
|
||||||
; ResetSystemLib implementation using PSCI calls
|
|
||||||
;
|
|
||||||
; Copyright (c) 2018, Linaro Ltd. All rights reserved.<BR>
|
|
||||||
;
|
|
||||||
; SPDX-License-Identifier: BSD-2-Clause-Patent
|
|
||||||
;
|
|
||||||
;**/
|
|
||||||
|
|
||||||
AREA Reset, CODE, READONLY
|
|
||||||
|
|
||||||
EXPORT DisableMmuAndReenterPei
|
|
||||||
IMPORT ArmDisableMmu
|
|
||||||
|
|
||||||
DisableMmuAndReenterPei
|
|
||||||
stp x29, x30, [sp, #-16]!
|
|
||||||
mov x29, sp
|
|
||||||
|
|
||||||
bl ArmDisableMmu
|
|
||||||
|
|
||||||
; no memory accesses after MMU and caches have been disabled
|
|
||||||
|
|
||||||
movl x0, FixedPcdGet64 (PcdFvBaseAddress)
|
|
||||||
blr x0
|
|
||||||
|
|
||||||
; never returns
|
|
||||||
nop
|
|
||||||
|
|
||||||
END
|
|
@@ -1,23 +0,0 @@
|
|||||||
/** @file
|
|
||||||
ResetSystemLib implementation using PSCI calls
|
|
||||||
|
|
||||||
Copyright (c) 2018, Linaro Ltd. All rights reserved.<BR>
|
|
||||||
|
|
||||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
|
||||||
|
|
||||||
**/
|
|
||||||
|
|
||||||
#include <AsmMacroIoLib.h>
|
|
||||||
|
|
||||||
ASM_FUNC(DisableMmuAndReenterPei)
|
|
||||||
push {lr}
|
|
||||||
|
|
||||||
bl ArmDisableMmu
|
|
||||||
|
|
||||||
// no memory accesses after MMU and caches have been disabled
|
|
||||||
|
|
||||||
MOV32 (r0, FixedPcdGet64 (PcdFvBaseAddress))
|
|
||||||
blx r0
|
|
||||||
|
|
||||||
// never returns
|
|
||||||
nop
|
|
@@ -1,28 +0,0 @@
|
|||||||
;/** @file
|
|
||||||
; ResetSystemLib implementation using PSCI calls
|
|
||||||
;
|
|
||||||
; Copyright (c) 2018, Linaro Ltd. All rights reserved.<BR>
|
|
||||||
;
|
|
||||||
; SPDX-License-Identifier: BSD-2-Clause-Patent
|
|
||||||
;
|
|
||||||
;**/
|
|
||||||
|
|
||||||
INCLUDE AsmMacroExport.inc
|
|
||||||
PRESERVE8
|
|
||||||
|
|
||||||
IMPORT ArmDisableMmu
|
|
||||||
|
|
||||||
RVCT_ASM_EXPORT DisableMmuAndReenterPei
|
|
||||||
push {lr}
|
|
||||||
|
|
||||||
bl ArmDisableMmu
|
|
||||||
|
|
||||||
; no memory accesses after MMU and caches have been disabled
|
|
||||||
|
|
||||||
mov32 r0, FixedPcdGet64 (PcdFvBaseAddress)
|
|
||||||
blx r0
|
|
||||||
|
|
||||||
; never returns
|
|
||||||
nop
|
|
||||||
|
|
||||||
END
|
|
@@ -10,13 +10,10 @@
|
|||||||
|
|
||||||
#include <PiDxe.h>
|
#include <PiDxe.h>
|
||||||
|
|
||||||
#include <Library/ArmMmuLib.h>
|
|
||||||
#include <Library/ArmSmcLib.h>
|
#include <Library/ArmSmcLib.h>
|
||||||
#include <Library/BaseLib.h>
|
#include <Library/BaseLib.h>
|
||||||
#include <Library/DebugLib.h>
|
#include <Library/DebugLib.h>
|
||||||
#include <Library/ResetSystemLib.h>
|
#include <Library/ResetSystemLib.h>
|
||||||
#include <Library/UefiBootServicesTableLib.h>
|
|
||||||
#include <Library/UefiRuntimeLib.h>
|
|
||||||
|
|
||||||
#include <IndustryStandard/ArmStdSmc.h>
|
#include <IndustryStandard/ArmStdSmc.h>
|
||||||
|
|
||||||
@@ -76,79 +73,6 @@ ResetShutdown (
|
|||||||
ArmCallSmc (&ArmSmcArgs);
|
ArmCallSmc (&ArmSmcArgs);
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID DisableMmuAndReenterPei (VOID);
|
|
||||||
|
|
||||||
/**
|
|
||||||
This function causes the system to enter S3 and then wake up immediately.
|
|
||||||
|
|
||||||
If this function returns, it means that the system does not support S3 feature.
|
|
||||||
**/
|
|
||||||
VOID
|
|
||||||
EFIAPI
|
|
||||||
EnterS3WithImmediateWake (
|
|
||||||
VOID
|
|
||||||
)
|
|
||||||
{
|
|
||||||
EFI_PHYSICAL_ADDRESS Alloc;
|
|
||||||
EFI_MEMORY_DESCRIPTOR *MemMap;
|
|
||||||
UINTN MemMapSize;
|
|
||||||
UINTN MapKey, DescriptorSize;
|
|
||||||
UINT32 DescriptorVersion;
|
|
||||||
EFI_STATUS Status;
|
|
||||||
|
|
||||||
if (FeaturePcdGet (PcdArmReenterPeiForCapsuleWarmReboot) &&
|
|
||||||
!EfiAtRuntime ()) {
|
|
||||||
//
|
|
||||||
// At boot time, we are the only core running, so we can implement the
|
|
||||||
// immediate wake (which is used by capsule update) by disabling the MMU
|
|
||||||
// and interrupts, and jumping to the PEI entry point.
|
|
||||||
//
|
|
||||||
|
|
||||||
//
|
|
||||||
// Obtain the size of the memory map
|
|
||||||
//
|
|
||||||
MemMapSize = 0;
|
|
||||||
MemMap = NULL;
|
|
||||||
Status = gBS->GetMemoryMap (&MemMapSize, MemMap, &MapKey, &DescriptorSize,
|
|
||||||
&DescriptorVersion);
|
|
||||||
ASSERT (Status == EFI_BUFFER_TOO_SMALL);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Add some slack to the allocation to cater for changes in the memory
|
|
||||||
// map if ExitBootServices () fails the first time around.
|
|
||||||
//
|
|
||||||
MemMapSize += SIZE_4KB;
|
|
||||||
Status = gBS->AllocatePages (AllocateAnyPages, EfiBootServicesData,
|
|
||||||
EFI_SIZE_TO_PAGES (MemMapSize), &Alloc);
|
|
||||||
ASSERT_EFI_ERROR (Status);
|
|
||||||
|
|
||||||
MemMap = (EFI_MEMORY_DESCRIPTOR *)(UINTN)Alloc;
|
|
||||||
|
|
||||||
Status = gBS->GetMemoryMap (&MemMapSize, MemMap, &MapKey, &DescriptorSize,
|
|
||||||
&DescriptorVersion);
|
|
||||||
ASSERT_EFI_ERROR (Status);
|
|
||||||
|
|
||||||
Status = gBS->ExitBootServices (gImageHandle, MapKey);
|
|
||||||
if (EFI_ERROR (Status)) {
|
|
||||||
//
|
|
||||||
// ExitBootServices () may fail the first time around if an event fired
|
|
||||||
// right after the call to GetMemoryMap() which allocated or freed memory.
|
|
||||||
// Since that first call to ExitBootServices () will disarm the timer,
|
|
||||||
// this is guaranteed not to happen again, so one additional attempt
|
|
||||||
// should suffice.
|
|
||||||
//
|
|
||||||
Status = gBS->GetMemoryMap (&MemMapSize, MemMap, &MapKey, &DescriptorSize,
|
|
||||||
&DescriptorVersion);
|
|
||||||
ASSERT_EFI_ERROR (Status);
|
|
||||||
|
|
||||||
Status = gBS->ExitBootServices (gImageHandle, MapKey);
|
|
||||||
ASSERT_EFI_ERROR (Status);
|
|
||||||
}
|
|
||||||
|
|
||||||
DisableMmuAndReenterPei ();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
This function causes a systemwide reset. The exact type of the reset is
|
This function causes a systemwide reset. The exact type of the reset is
|
||||||
defined by the EFI_GUID that follows the Null-terminated Unicode string passed
|
defined by the EFI_GUID that follows the Null-terminated Unicode string passed
|
||||||
|
@@ -15,14 +15,6 @@
|
|||||||
VERSION_STRING = 1.0
|
VERSION_STRING = 1.0
|
||||||
LIBRARY_CLASS = ResetSystemLib
|
LIBRARY_CLASS = ResetSystemLib
|
||||||
|
|
||||||
[Sources.AARCH64]
|
|
||||||
AArch64/Reset.S | GCC
|
|
||||||
AArch64/Reset.asm | MSFT
|
|
||||||
|
|
||||||
[Sources.ARM]
|
|
||||||
Arm/Reset.S | GCC
|
|
||||||
Arm/Reset.asm | RVCT
|
|
||||||
|
|
||||||
[Sources]
|
[Sources]
|
||||||
ArmSmcPsciResetSystemLib.c
|
ArmSmcPsciResetSystemLib.c
|
||||||
|
|
||||||
@@ -32,15 +24,6 @@
|
|||||||
MdePkg/MdePkg.dec
|
MdePkg/MdePkg.dec
|
||||||
|
|
||||||
[LibraryClasses]
|
[LibraryClasses]
|
||||||
ArmMmuLib
|
|
||||||
ArmSmcLib
|
ArmSmcLib
|
||||||
BaseLib
|
BaseLib
|
||||||
DebugLib
|
DebugLib
|
||||||
UefiBootServicesTableLib
|
|
||||||
UefiRuntimeLib
|
|
||||||
|
|
||||||
[FeaturePcd]
|
|
||||||
gArmTokenSpaceGuid.PcdArmReenterPeiForCapsuleWarmReboot
|
|
||||||
|
|
||||||
[FixedPcd]
|
|
||||||
gArmTokenSpaceGuid.PcdFvBaseAddress
|
|
||||||
|
@@ -1,283 +1,283 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2015 - 2019, Linaro Limited
|
* Copyright (c) 2015 - 2019, Linaro Limited
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: BSD-2-Clause-Patent
|
* SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "platform.h"
|
#include "platform.h"
|
||||||
#include <softfloat.h>
|
#include <softfloat.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* On ARM32 EABI defines both a soft-float ABI and a hard-float ABI,
|
* On ARM32 EABI defines both a soft-float ABI and a hard-float ABI,
|
||||||
* hard-float is basically a super set of soft-float. Hard-float requires
|
* hard-float is basically a super set of soft-float. Hard-float requires
|
||||||
* all the support routines provided for soft-float, but the compiler may
|
* all the support routines provided for soft-float, but the compiler may
|
||||||
* choose to optimize to not use some of them.
|
* choose to optimize to not use some of them.
|
||||||
*
|
*
|
||||||
* The AEABI functions uses soft-float calling convention even if the
|
* The AEABI functions uses soft-float calling convention even if the
|
||||||
* functions are compiled for hard-float. So where float and double would
|
* functions are compiled for hard-float. So where float and double would
|
||||||
* have been expected we use aeabi_float_t and aeabi_double_t respectively
|
* have been expected we use aeabi_float_t and aeabi_double_t respectively
|
||||||
* instead.
|
* instead.
|
||||||
*/
|
*/
|
||||||
typedef uint32_t aeabi_float_t;
|
typedef uint32_t aeabi_float_t;
|
||||||
typedef uint64_t aeabi_double_t;
|
typedef uint64_t aeabi_double_t;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Helpers to convert between float32 and aeabi_float_t, and float64 and
|
* Helpers to convert between float32 and aeabi_float_t, and float64 and
|
||||||
* aeabi_double_t used by the AEABI functions below.
|
* aeabi_double_t used by the AEABI functions below.
|
||||||
*/
|
*/
|
||||||
static aeabi_float_t f32_to_f(float32_t val)
|
static aeabi_float_t f32_to_f(float32_t val)
|
||||||
{
|
{
|
||||||
return val.v;
|
return val.v;
|
||||||
}
|
}
|
||||||
|
|
||||||
static float32_t f32_from_f(aeabi_float_t val)
|
static float32_t f32_from_f(aeabi_float_t val)
|
||||||
{
|
{
|
||||||
float32_t res;
|
float32_t res;
|
||||||
|
|
||||||
res.v = val;
|
res.v = val;
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static aeabi_double_t f64_to_d(float64_t val)
|
static aeabi_double_t f64_to_d(float64_t val)
|
||||||
{
|
{
|
||||||
return val.v;
|
return val.v;
|
||||||
}
|
}
|
||||||
|
|
||||||
static float64_t f64_from_d(aeabi_double_t val)
|
static float64_t f64_from_d(aeabi_double_t val)
|
||||||
{
|
{
|
||||||
float64_t res;
|
float64_t res;
|
||||||
|
|
||||||
res.v = val;
|
res.v = val;
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* From ARM Run-time ABI for ARM Architecture
|
* From ARM Run-time ABI for ARM Architecture
|
||||||
* ARM IHI 0043D, current through ABI release 2.09
|
* ARM IHI 0043D, current through ABI release 2.09
|
||||||
*
|
*
|
||||||
* 4.1.2 The floating-point helper functions
|
* 4.1.2 The floating-point helper functions
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Table 2, Standard aeabi_double_t precision floating-point arithmetic helper
|
* Table 2, Standard aeabi_double_t precision floating-point arithmetic helper
|
||||||
* functions
|
* functions
|
||||||
*/
|
*/
|
||||||
|
|
||||||
aeabi_double_t __aeabi_dadd(aeabi_double_t a, aeabi_double_t b)
|
aeabi_double_t __aeabi_dadd(aeabi_double_t a, aeabi_double_t b)
|
||||||
{
|
{
|
||||||
return f64_to_d(f64_add(f64_from_d(a), f64_from_d(b)));
|
return f64_to_d(f64_add(f64_from_d(a), f64_from_d(b)));
|
||||||
}
|
}
|
||||||
|
|
||||||
aeabi_double_t __aeabi_ddiv(aeabi_double_t a, aeabi_double_t b)
|
aeabi_double_t __aeabi_ddiv(aeabi_double_t a, aeabi_double_t b)
|
||||||
{
|
{
|
||||||
return f64_to_d(f64_div(f64_from_d(a), f64_from_d(b)));
|
return f64_to_d(f64_div(f64_from_d(a), f64_from_d(b)));
|
||||||
}
|
}
|
||||||
|
|
||||||
aeabi_double_t __aeabi_dmul(aeabi_double_t a, aeabi_double_t b)
|
aeabi_double_t __aeabi_dmul(aeabi_double_t a, aeabi_double_t b)
|
||||||
{
|
{
|
||||||
return f64_to_d(f64_mul(f64_from_d(a), f64_from_d(b)));
|
return f64_to_d(f64_mul(f64_from_d(a), f64_from_d(b)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
aeabi_double_t __aeabi_drsub(aeabi_double_t a, aeabi_double_t b)
|
aeabi_double_t __aeabi_drsub(aeabi_double_t a, aeabi_double_t b)
|
||||||
{
|
{
|
||||||
return f64_to_d(f64_sub(f64_from_d(b), f64_from_d(a)));
|
return f64_to_d(f64_sub(f64_from_d(b), f64_from_d(a)));
|
||||||
}
|
}
|
||||||
|
|
||||||
aeabi_double_t __aeabi_dsub(aeabi_double_t a, aeabi_double_t b)
|
aeabi_double_t __aeabi_dsub(aeabi_double_t a, aeabi_double_t b)
|
||||||
{
|
{
|
||||||
return f64_to_d(f64_sub(f64_from_d(a), f64_from_d(b)));
|
return f64_to_d(f64_sub(f64_from_d(a), f64_from_d(b)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Table 3, double precision floating-point comparison helper functions
|
* Table 3, double precision floating-point comparison helper functions
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int __aeabi_dcmpeq(aeabi_double_t a, aeabi_double_t b)
|
int __aeabi_dcmpeq(aeabi_double_t a, aeabi_double_t b)
|
||||||
{
|
{
|
||||||
return f64_eq(f64_from_d(a), f64_from_d(b));
|
return f64_eq(f64_from_d(a), f64_from_d(b));
|
||||||
}
|
}
|
||||||
|
|
||||||
int __aeabi_dcmplt(aeabi_double_t a, aeabi_double_t b)
|
int __aeabi_dcmplt(aeabi_double_t a, aeabi_double_t b)
|
||||||
{
|
{
|
||||||
return f64_lt(f64_from_d(a), f64_from_d(b));
|
return f64_lt(f64_from_d(a), f64_from_d(b));
|
||||||
}
|
}
|
||||||
|
|
||||||
int __aeabi_dcmple(aeabi_double_t a, aeabi_double_t b)
|
int __aeabi_dcmple(aeabi_double_t a, aeabi_double_t b)
|
||||||
{
|
{
|
||||||
return f64_le(f64_from_d(a), f64_from_d(b));
|
return f64_le(f64_from_d(a), f64_from_d(b));
|
||||||
}
|
}
|
||||||
|
|
||||||
int __aeabi_dcmpge(aeabi_double_t a, aeabi_double_t b)
|
int __aeabi_dcmpge(aeabi_double_t a, aeabi_double_t b)
|
||||||
{
|
{
|
||||||
return f64_le(f64_from_d(b), f64_from_d(a));
|
return f64_le(f64_from_d(b), f64_from_d(a));
|
||||||
}
|
}
|
||||||
|
|
||||||
int __aeabi_dcmpgt(aeabi_double_t a, aeabi_double_t b)
|
int __aeabi_dcmpgt(aeabi_double_t a, aeabi_double_t b)
|
||||||
{
|
{
|
||||||
return f64_lt(f64_from_d(b), f64_from_d(a));
|
return f64_lt(f64_from_d(b), f64_from_d(a));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Table 4, Standard single precision floating-point arithmetic helper
|
* Table 4, Standard single precision floating-point arithmetic helper
|
||||||
* functions
|
* functions
|
||||||
*/
|
*/
|
||||||
|
|
||||||
aeabi_float_t __aeabi_fadd(aeabi_float_t a, aeabi_float_t b)
|
aeabi_float_t __aeabi_fadd(aeabi_float_t a, aeabi_float_t b)
|
||||||
{
|
{
|
||||||
return f32_to_f(f32_add(f32_from_f(a), f32_from_f(b)));
|
return f32_to_f(f32_add(f32_from_f(a), f32_from_f(b)));
|
||||||
}
|
}
|
||||||
|
|
||||||
aeabi_float_t __aeabi_fdiv(aeabi_float_t a, aeabi_float_t b)
|
aeabi_float_t __aeabi_fdiv(aeabi_float_t a, aeabi_float_t b)
|
||||||
{
|
{
|
||||||
return f32_to_f(f32_div(f32_from_f(a), f32_from_f(b)));
|
return f32_to_f(f32_div(f32_from_f(a), f32_from_f(b)));
|
||||||
}
|
}
|
||||||
|
|
||||||
aeabi_float_t __aeabi_fmul(aeabi_float_t a, aeabi_float_t b)
|
aeabi_float_t __aeabi_fmul(aeabi_float_t a, aeabi_float_t b)
|
||||||
{
|
{
|
||||||
return f32_to_f(f32_mul(f32_from_f(a), f32_from_f(b)));
|
return f32_to_f(f32_mul(f32_from_f(a), f32_from_f(b)));
|
||||||
}
|
}
|
||||||
|
|
||||||
aeabi_float_t __aeabi_frsub(aeabi_float_t a, aeabi_float_t b)
|
aeabi_float_t __aeabi_frsub(aeabi_float_t a, aeabi_float_t b)
|
||||||
{
|
{
|
||||||
return f32_to_f(f32_sub(f32_from_f(b), f32_from_f(a)));
|
return f32_to_f(f32_sub(f32_from_f(b), f32_from_f(a)));
|
||||||
}
|
}
|
||||||
|
|
||||||
aeabi_float_t __aeabi_fsub(aeabi_float_t a, aeabi_float_t b)
|
aeabi_float_t __aeabi_fsub(aeabi_float_t a, aeabi_float_t b)
|
||||||
{
|
{
|
||||||
return f32_to_f(f32_sub(f32_from_f(a), f32_from_f(b)));
|
return f32_to_f(f32_sub(f32_from_f(a), f32_from_f(b)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Table 5, Standard single precision floating-point comparison helper
|
* Table 5, Standard single precision floating-point comparison helper
|
||||||
* functions
|
* functions
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int __aeabi_fcmpeq(aeabi_float_t a, aeabi_float_t b)
|
int __aeabi_fcmpeq(aeabi_float_t a, aeabi_float_t b)
|
||||||
{
|
{
|
||||||
return f32_eq(f32_from_f(a), f32_from_f(b));
|
return f32_eq(f32_from_f(a), f32_from_f(b));
|
||||||
}
|
}
|
||||||
|
|
||||||
int __aeabi_fcmplt(aeabi_float_t a, aeabi_float_t b)
|
int __aeabi_fcmplt(aeabi_float_t a, aeabi_float_t b)
|
||||||
{
|
{
|
||||||
return f32_lt(f32_from_f(a), f32_from_f(b));
|
return f32_lt(f32_from_f(a), f32_from_f(b));
|
||||||
}
|
}
|
||||||
|
|
||||||
int __aeabi_fcmple(aeabi_float_t a, aeabi_float_t b)
|
int __aeabi_fcmple(aeabi_float_t a, aeabi_float_t b)
|
||||||
{
|
{
|
||||||
return f32_le(f32_from_f(a), f32_from_f(b));
|
return f32_le(f32_from_f(a), f32_from_f(b));
|
||||||
}
|
}
|
||||||
|
|
||||||
int __aeabi_fcmpge(aeabi_float_t a, aeabi_float_t b)
|
int __aeabi_fcmpge(aeabi_float_t a, aeabi_float_t b)
|
||||||
{
|
{
|
||||||
return f32_le(f32_from_f(b), f32_from_f(a));
|
return f32_le(f32_from_f(b), f32_from_f(a));
|
||||||
}
|
}
|
||||||
|
|
||||||
int __aeabi_fcmpgt(aeabi_float_t a, aeabi_float_t b)
|
int __aeabi_fcmpgt(aeabi_float_t a, aeabi_float_t b)
|
||||||
{
|
{
|
||||||
return f32_lt(f32_from_f(b), f32_from_f(a));
|
return f32_lt(f32_from_f(b), f32_from_f(a));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Table 6, Standard floating-point to integer conversions
|
* Table 6, Standard floating-point to integer conversions
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int __aeabi_d2iz(aeabi_double_t a)
|
int __aeabi_d2iz(aeabi_double_t a)
|
||||||
{
|
{
|
||||||
return f64_to_i32_r_minMag(f64_from_d(a), false);
|
return f64_to_i32_r_minMag(f64_from_d(a), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned __aeabi_d2uiz(aeabi_double_t a)
|
unsigned __aeabi_d2uiz(aeabi_double_t a)
|
||||||
{
|
{
|
||||||
return f64_to_ui32_r_minMag(f64_from_d(a), false);
|
return f64_to_ui32_r_minMag(f64_from_d(a), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
long long __aeabi_d2lz(aeabi_double_t a)
|
long long __aeabi_d2lz(aeabi_double_t a)
|
||||||
{
|
{
|
||||||
return f64_to_i64_r_minMag(f64_from_d(a), false);
|
return f64_to_i64_r_minMag(f64_from_d(a), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned long long __aeabi_d2ulz(aeabi_double_t a)
|
unsigned long long __aeabi_d2ulz(aeabi_double_t a)
|
||||||
{
|
{
|
||||||
return f64_to_ui64_r_minMag(f64_from_d(a), false);
|
return f64_to_ui64_r_minMag(f64_from_d(a), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
int __aeabi_f2iz(aeabi_float_t a)
|
int __aeabi_f2iz(aeabi_float_t a)
|
||||||
{
|
{
|
||||||
return f32_to_i32_r_minMag(f32_from_f(a), false);
|
return f32_to_i32_r_minMag(f32_from_f(a), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned __aeabi_f2uiz(aeabi_float_t a)
|
unsigned __aeabi_f2uiz(aeabi_float_t a)
|
||||||
{
|
{
|
||||||
return f32_to_ui32_r_minMag(f32_from_f(a), false);
|
return f32_to_ui32_r_minMag(f32_from_f(a), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
long long __aeabi_f2lz(aeabi_float_t a)
|
long long __aeabi_f2lz(aeabi_float_t a)
|
||||||
{
|
{
|
||||||
return f32_to_i64_r_minMag(f32_from_f(a), false);
|
return f32_to_i64_r_minMag(f32_from_f(a), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned long long __aeabi_f2ulz(aeabi_float_t a)
|
unsigned long long __aeabi_f2ulz(aeabi_float_t a)
|
||||||
{
|
{
|
||||||
return f32_to_ui64_r_minMag(f32_from_f(a), false);
|
return f32_to_ui64_r_minMag(f32_from_f(a), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Table 7, Standard conversions between floating types
|
* Table 7, Standard conversions between floating types
|
||||||
*/
|
*/
|
||||||
|
|
||||||
aeabi_float_t __aeabi_d2f(aeabi_double_t a)
|
aeabi_float_t __aeabi_d2f(aeabi_double_t a)
|
||||||
{
|
{
|
||||||
return f32_to_f(f64_to_f32(f64_from_d(a)));
|
return f32_to_f(f64_to_f32(f64_from_d(a)));
|
||||||
}
|
}
|
||||||
|
|
||||||
aeabi_double_t __aeabi_f2d(aeabi_float_t a)
|
aeabi_double_t __aeabi_f2d(aeabi_float_t a)
|
||||||
{
|
{
|
||||||
return f64_to_d(f32_to_f64(f32_from_f(a)));
|
return f64_to_d(f32_to_f64(f32_from_f(a)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Table 8, Standard integer to floating-point conversions
|
* Table 8, Standard integer to floating-point conversions
|
||||||
*/
|
*/
|
||||||
|
|
||||||
aeabi_double_t __aeabi_i2d(int a)
|
aeabi_double_t __aeabi_i2d(int a)
|
||||||
{
|
{
|
||||||
return f64_to_d(i32_to_f64(a));
|
return f64_to_d(i32_to_f64(a));
|
||||||
}
|
}
|
||||||
|
|
||||||
aeabi_double_t __aeabi_ui2d(unsigned a)
|
aeabi_double_t __aeabi_ui2d(unsigned a)
|
||||||
{
|
{
|
||||||
return f64_to_d(ui32_to_f64(a));
|
return f64_to_d(ui32_to_f64(a));
|
||||||
}
|
}
|
||||||
|
|
||||||
aeabi_double_t __aeabi_l2d(long long a)
|
aeabi_double_t __aeabi_l2d(long long a)
|
||||||
{
|
{
|
||||||
return f64_to_d(i64_to_f64(a));
|
return f64_to_d(i64_to_f64(a));
|
||||||
}
|
}
|
||||||
|
|
||||||
aeabi_double_t __aeabi_ul2d(unsigned long long a)
|
aeabi_double_t __aeabi_ul2d(unsigned long long a)
|
||||||
{
|
{
|
||||||
return f64_to_d(ui64_to_f64(a));
|
return f64_to_d(ui64_to_f64(a));
|
||||||
}
|
}
|
||||||
|
|
||||||
aeabi_float_t __aeabi_i2f(int a)
|
aeabi_float_t __aeabi_i2f(int a)
|
||||||
{
|
{
|
||||||
return f32_to_f(i32_to_f32(a));
|
return f32_to_f(i32_to_f32(a));
|
||||||
}
|
}
|
||||||
|
|
||||||
aeabi_float_t __aeabi_ui2f(unsigned a)
|
aeabi_float_t __aeabi_ui2f(unsigned a)
|
||||||
{
|
{
|
||||||
return f32_to_f(ui32_to_f32(a));
|
return f32_to_f(ui32_to_f32(a));
|
||||||
}
|
}
|
||||||
|
|
||||||
aeabi_float_t __aeabi_l2f(long long a)
|
aeabi_float_t __aeabi_l2f(long long a)
|
||||||
{
|
{
|
||||||
return f32_to_f(i64_to_f32(a));
|
return f32_to_f(i64_to_f32(a));
|
||||||
}
|
}
|
||||||
|
|
||||||
aeabi_float_t __aeabi_ul2f(unsigned long long a)
|
aeabi_float_t __aeabi_ul2f(unsigned long long a)
|
||||||
{
|
{
|
||||||
return f32_to_f(ui64_to_f32(a));
|
return f32_to_f(ui64_to_f32(a));
|
||||||
}
|
}
|
||||||
|
142
ArmPkg/Library/CompilerIntrinsicsLib/AArch64/Atomics.S
Normal file
142
ArmPkg/Library/CompilerIntrinsicsLib/AArch64/Atomics.S
Normal file
@@ -0,0 +1,142 @@
|
|||||||
|
#------------------------------------------------------------------------------
|
||||||
|
#
|
||||||
|
# Copyright (c) 2020, Arm, Limited. All rights reserved.<BR>
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
|
#
|
||||||
|
#------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Provide the GCC intrinsics that are required when using GCC 9 or
|
||||||
|
* later with the -moutline-atomics options (which became the default
|
||||||
|
* in GCC 10)
|
||||||
|
*/
|
||||||
|
.arch armv8-a
|
||||||
|
|
||||||
|
.macro reg_alias, pfx, sz
|
||||||
|
r0_\sz .req \pfx\()0
|
||||||
|
r1_\sz .req \pfx\()1
|
||||||
|
tmp0_\sz .req \pfx\()16
|
||||||
|
tmp1_\sz .req \pfx\()17
|
||||||
|
.endm
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Define register aliases of the right type for each size
|
||||||
|
* (xN for 8 bytes, wN for everything smaller)
|
||||||
|
*/
|
||||||
|
reg_alias w, 1
|
||||||
|
reg_alias w, 2
|
||||||
|
reg_alias w, 4
|
||||||
|
reg_alias x, 8
|
||||||
|
|
||||||
|
.macro fn_start, name:req
|
||||||
|
.section .text.\name
|
||||||
|
.globl \name
|
||||||
|
.type \name, %function
|
||||||
|
\name\():
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.macro fn_end, name:req
|
||||||
|
.size \name, . - \name
|
||||||
|
.endm
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Emit an atomic helper for \model with operands of size \sz, using
|
||||||
|
* the operation specified by \insn (which is the LSE name), and which
|
||||||
|
* can be implemented using the generic load-locked/store-conditional
|
||||||
|
* (LL/SC) sequence below, using the arithmetic operation given by
|
||||||
|
* \opc.
|
||||||
|
*/
|
||||||
|
.macro emit_ld_sz, sz:req, insn:req, opc:req, model:req, s, a, l
|
||||||
|
fn_start __aarch64_\insn\()\sz\()\model
|
||||||
|
mov tmp0_\sz, r0_\sz
|
||||||
|
0: ld\a\()xr\s r0_\sz, [x1]
|
||||||
|
.ifnc \insn, swp
|
||||||
|
\opc tmp1_\sz, r0_\sz, tmp0_\sz
|
||||||
|
st\l\()xr\s w15, tmp1_\sz, [x1]
|
||||||
|
.else
|
||||||
|
st\l\()xr\s w15, tmp0_\sz, [x1]
|
||||||
|
.endif
|
||||||
|
cbnz w15, 0b
|
||||||
|
ret
|
||||||
|
fn_end __aarch64_\insn\()\sz\()\model
|
||||||
|
.endm
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Emit atomic helpers for \model for operand sizes in the
|
||||||
|
* set {1, 2, 4, 8}, for the instruction pattern given by
|
||||||
|
* \insn. (This is the LSE name, but this implementation uses
|
||||||
|
* the generic LL/SC sequence using \opc as the arithmetic
|
||||||
|
* operation on the target.)
|
||||||
|
*/
|
||||||
|
.macro emit_ld, insn:req, opc:req, model:req, a, l
|
||||||
|
emit_ld_sz 1, \insn, \opc, \model, b, \a, \l
|
||||||
|
emit_ld_sz 2, \insn, \opc, \model, h, \a, \l
|
||||||
|
emit_ld_sz 4, \insn, \opc, \model, , \a, \l
|
||||||
|
emit_ld_sz 8, \insn, \opc, \model, , \a, \l
|
||||||
|
.endm
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Emit the compare and swap helper for \model and size \sz
|
||||||
|
* using LL/SC instructions.
|
||||||
|
*/
|
||||||
|
.macro emit_cas_sz, sz:req, model:req, uxt:req, s, a, l
|
||||||
|
fn_start __aarch64_cas\sz\()\model
|
||||||
|
\uxt tmp0_\sz, r0_\sz
|
||||||
|
0: ld\a\()xr\s r0_\sz, [x2]
|
||||||
|
cmp r0_\sz, tmp0_\sz
|
||||||
|
bne 1f
|
||||||
|
st\l\()xr\s w15, r1_\sz, [x2]
|
||||||
|
cbnz w15, 0b
|
||||||
|
1: ret
|
||||||
|
fn_end __aarch64_cas\sz\()\model
|
||||||
|
.endm
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Emit compare-and-swap helpers for \model for operand sizes in the
|
||||||
|
* set {1, 2, 4, 8, 16}.
|
||||||
|
*/
|
||||||
|
.macro emit_cas, model:req, a, l
|
||||||
|
emit_cas_sz 1, \model, uxtb, b, \a, \l
|
||||||
|
emit_cas_sz 2, \model, uxth, h, \a, \l
|
||||||
|
emit_cas_sz 4, \model, mov , , \a, \l
|
||||||
|
emit_cas_sz 8, \model, mov , , \a, \l
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We cannot use the parameterized sequence for 16 byte CAS, so we
|
||||||
|
* need to define it explicitly.
|
||||||
|
*/
|
||||||
|
fn_start __aarch64_cas16\model
|
||||||
|
mov x16, x0
|
||||||
|
mov x17, x1
|
||||||
|
0: ld\a\()xp x0, x1, [x4]
|
||||||
|
cmp x0, x16
|
||||||
|
ccmp x1, x17, #0, eq
|
||||||
|
bne 1f
|
||||||
|
st\l\()xp w15, x16, x17, [x4]
|
||||||
|
cbnz w15, 0b
|
||||||
|
1: ret
|
||||||
|
fn_end __aarch64_cas16\model
|
||||||
|
.endm
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Emit the set of GCC outline atomic helper functions for
|
||||||
|
* the memory ordering model given by \model:
|
||||||
|
* - relax unordered loads and stores
|
||||||
|
* - acq load-acquire, unordered store
|
||||||
|
* - rel unordered load, store-release
|
||||||
|
* - acq_rel load-acquire, store-release
|
||||||
|
*/
|
||||||
|
.macro emit_model, model:req, a, l
|
||||||
|
emit_ld ldadd, add, \model, \a, \l
|
||||||
|
emit_ld ldclr, bic, \model, \a, \l
|
||||||
|
emit_ld ldeor, eor, \model, \a, \l
|
||||||
|
emit_ld ldset, orr, \model, \a, \l
|
||||||
|
emit_ld swp, mov, \model, \a, \l
|
||||||
|
emit_cas \model, \a, \l
|
||||||
|
.endm
|
||||||
|
|
||||||
|
emit_model _relax
|
||||||
|
emit_model _acq, a
|
||||||
|
emit_model _rel,, l
|
||||||
|
emit_model _acq_rel, a, l
|
@@ -79,6 +79,9 @@
|
|||||||
Arm/ldivmod.asm | MSFT
|
Arm/ldivmod.asm | MSFT
|
||||||
Arm/llsr.asm | MSFT
|
Arm/llsr.asm | MSFT
|
||||||
|
|
||||||
|
[Sources.AARCH64]
|
||||||
|
AArch64/Atomics.S | GCC
|
||||||
|
|
||||||
[Packages]
|
[Packages]
|
||||||
MdePkg/MdePkg.dec
|
MdePkg/MdePkg.dec
|
||||||
ArmPkg/ArmPkg.dec
|
ArmPkg/ArmPkg.dec
|
||||||
|
@@ -1,55 +1,55 @@
|
|||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
// Copyright (c) 2016, Linaro Ltd. All rights reserved.<BR>
|
// Copyright (c) 2016, Linaro Ltd. All rights reserved.<BR>
|
||||||
//
|
//
|
||||||
// SPDX-License-Identifier: BSD-2-Clause-Patent
|
// SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
//
|
//
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
typedef __SIZE_TYPE__ size_t;
|
typedef __SIZE_TYPE__ size_t;
|
||||||
|
|
||||||
static __attribute__((__used__))
|
static __attribute__((__used__))
|
||||||
void *__memset(void *s, int c, size_t n)
|
void *__memset(void *s, int c, size_t n)
|
||||||
{
|
{
|
||||||
unsigned char *d = s;
|
unsigned char *d = s;
|
||||||
|
|
||||||
while (n--)
|
while (n--)
|
||||||
*d++ = c;
|
*d++ = c;
|
||||||
|
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Other modules (such as CryptoPkg/IntrinsicLib) may provide another
|
// Other modules (such as CryptoPkg/IntrinsicLib) may provide another
|
||||||
// implementation of memset(), which may conflict with this one if this
|
// implementation of memset(), which may conflict with this one if this
|
||||||
// object was pulled into the link due to the definitions below. So make
|
// object was pulled into the link due to the definitions below. So make
|
||||||
// our memset() 'weak' to let the other implementation take precedence.
|
// our memset() 'weak' to let the other implementation take precedence.
|
||||||
//
|
//
|
||||||
__attribute__((__weak__, __alias__("__memset")))
|
__attribute__((__weak__, __alias__("__memset")))
|
||||||
void *memset(void *dest, int c, size_t n);
|
void *memset(void *dest, int c, size_t n);
|
||||||
|
|
||||||
#ifdef __arm__
|
#ifdef __arm__
|
||||||
|
|
||||||
void __aeabi_memset(void *dest, size_t n, int c)
|
void __aeabi_memset(void *dest, size_t n, int c)
|
||||||
{
|
{
|
||||||
__memset(dest, c, n);
|
__memset(dest, c, n);
|
||||||
}
|
}
|
||||||
|
|
||||||
__attribute__((__alias__("__aeabi_memset")))
|
__attribute__((__alias__("__aeabi_memset")))
|
||||||
void __aeabi_memset4(void *dest, size_t n, int c);
|
void __aeabi_memset4(void *dest, size_t n, int c);
|
||||||
|
|
||||||
__attribute__((__alias__("__aeabi_memset")))
|
__attribute__((__alias__("__aeabi_memset")))
|
||||||
void __aeabi_memset8(void *dest, size_t n, int c);
|
void __aeabi_memset8(void *dest, size_t n, int c);
|
||||||
|
|
||||||
void __aeabi_memclr(void *dest, size_t n)
|
void __aeabi_memclr(void *dest, size_t n)
|
||||||
{
|
{
|
||||||
__memset(dest, 0, n);
|
__memset(dest, 0, n);
|
||||||
}
|
}
|
||||||
|
|
||||||
__attribute__((__alias__("__aeabi_memclr")))
|
__attribute__((__alias__("__aeabi_memclr")))
|
||||||
void __aeabi_memclr4(void *dest, size_t n);
|
void __aeabi_memclr4(void *dest, size_t n);
|
||||||
|
|
||||||
__attribute__((__alias__("__aeabi_memclr")))
|
__attribute__((__alias__("__aeabi_memclr")))
|
||||||
void __aeabi_memclr8(void *dest, size_t n);
|
void __aeabi_memclr8(void *dest, size_t n);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@@ -1,21 +1,21 @@
|
|||||||
//
|
//
|
||||||
// Copyright (c) 2016, Linaro Ltd. All rights reserved.<BR>
|
// Copyright (c) 2016, Linaro Ltd. All rights reserved.<BR>
|
||||||
//
|
//
|
||||||
// SPDX-License-Identifier: BSD-2-Clause-Patent
|
// SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
//
|
//
|
||||||
|
|
||||||
//
|
//
|
||||||
// GCC in LTO mode interoperates poorly with non-standard libraries that
|
// GCC in LTO mode interoperates poorly with non-standard libraries that
|
||||||
// provide implementations of compiler intrinsics such as memcpy/memset
|
// provide implementations of compiler intrinsics such as memcpy/memset
|
||||||
// or the stack protector entry points.
|
// or the stack protector entry points.
|
||||||
//
|
//
|
||||||
// By referencing these functions from a non-LTO object that can be passed
|
// By referencing these functions from a non-LTO object that can be passed
|
||||||
// to the linker via the -plugin-opt=-pass-through=-lxxx options, the
|
// to the linker via the -plugin-opt=-pass-through=-lxxx options, the
|
||||||
// intrinsics are included in the link in a way that allows them to be
|
// intrinsics are included in the link in a way that allows them to be
|
||||||
// pruned again if no other references to them exist.
|
// pruned again if no other references to them exist.
|
||||||
//
|
//
|
||||||
|
|
||||||
.long memcpy - .
|
.long memcpy - .
|
||||||
.long memset - .
|
.long memset - .
|
||||||
.long __stack_chk_fail - .
|
.long __stack_chk_fail - .
|
||||||
.long __stack_chk_guard - .
|
.long __stack_chk_guard - .
|
||||||
|
@@ -1,55 +1,55 @@
|
|||||||
//
|
//
|
||||||
// Copyright (c) 2016, Linaro Ltd. All rights reserved.<BR>
|
// Copyright (c) 2016, Linaro Ltd. All rights reserved.<BR>
|
||||||
//
|
//
|
||||||
// SPDX-License-Identifier: BSD-2-Clause-Patent
|
// SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
//
|
//
|
||||||
|
|
||||||
//
|
//
|
||||||
// GCC in LTO mode interoperates poorly with non-standard libraries that
|
// GCC in LTO mode interoperates poorly with non-standard libraries that
|
||||||
// provide implementations of compiler intrinsics such as memcpy/memset
|
// provide implementations of compiler intrinsics such as memcpy/memset
|
||||||
// or the stack protector entry points.
|
// or the stack protector entry points.
|
||||||
//
|
//
|
||||||
// By referencing these functions from a non-LTO object that can be passed
|
// By referencing these functions from a non-LTO object that can be passed
|
||||||
// to the linker via the -plugin-opt=-pass-through=-lxxx options, the
|
// to the linker via the -plugin-opt=-pass-through=-lxxx options, the
|
||||||
// intrinsics are included in the link in a way that allows them to be
|
// intrinsics are included in the link in a way that allows them to be
|
||||||
// pruned again if no other references to them exist.
|
// pruned again if no other references to them exist.
|
||||||
//
|
//
|
||||||
|
|
||||||
.long memcpy - .
|
.long memcpy - .
|
||||||
.long memset - .
|
.long memset - .
|
||||||
.long __stack_chk_fail - .
|
.long __stack_chk_fail - .
|
||||||
.long __stack_chk_guard - .
|
.long __stack_chk_guard - .
|
||||||
.long __ashrdi3 - .
|
.long __ashrdi3 - .
|
||||||
.long __ashldi3 - .
|
.long __ashldi3 - .
|
||||||
.long __aeabi_idiv - .
|
.long __aeabi_idiv - .
|
||||||
.long __aeabi_idivmod - .
|
.long __aeabi_idivmod - .
|
||||||
.long __aeabi_uidiv - .
|
.long __aeabi_uidiv - .
|
||||||
.long __aeabi_uidivmod - .
|
.long __aeabi_uidivmod - .
|
||||||
.long __divdi3 - .
|
.long __divdi3 - .
|
||||||
.long __divsi3 - .
|
.long __divsi3 - .
|
||||||
.long __lshrdi3 - .
|
.long __lshrdi3 - .
|
||||||
.long __aeabi_memcpy - .
|
.long __aeabi_memcpy - .
|
||||||
.long __aeabi_memset - .
|
.long __aeabi_memset - .
|
||||||
.long memmove - .
|
.long memmove - .
|
||||||
.long __modsi3 - .
|
.long __modsi3 - .
|
||||||
.long __moddi3 - .
|
.long __moddi3 - .
|
||||||
.long __muldi3 - .
|
.long __muldi3 - .
|
||||||
.long __aeabi_lmul - .
|
.long __aeabi_lmul - .
|
||||||
.long __ARM_ll_mullu - .
|
.long __ARM_ll_mullu - .
|
||||||
.long __udivsi3 - .
|
.long __udivsi3 - .
|
||||||
.long __umodsi3 - .
|
.long __umodsi3 - .
|
||||||
.long __udivdi3 - .
|
.long __udivdi3 - .
|
||||||
.long __umoddi3 - .
|
.long __umoddi3 - .
|
||||||
.long __udivmoddi4 - .
|
.long __udivmoddi4 - .
|
||||||
.long __clzsi2 - .
|
.long __clzsi2 - .
|
||||||
.long __ctzsi2 - .
|
.long __ctzsi2 - .
|
||||||
.long __ucmpdi2 - .
|
.long __ucmpdi2 - .
|
||||||
.long __switch8 - .
|
.long __switch8 - .
|
||||||
.long __switchu8 - .
|
.long __switchu8 - .
|
||||||
.long __switch16 - .
|
.long __switch16 - .
|
||||||
.long __switch32 - .
|
.long __switch32 - .
|
||||||
.long __aeabi_ulcmp - .
|
.long __aeabi_ulcmp - .
|
||||||
.long __aeabi_uldivmod - .
|
.long __aeabi_uldivmod - .
|
||||||
.long __aeabi_ldivmod - .
|
.long __aeabi_ldivmod - .
|
||||||
.long __aeabi_llsr - .
|
.long __aeabi_llsr - .
|
||||||
.long __aeabi_llsl - .
|
.long __aeabi_llsl - .
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
Implementation for PlatformBootManagerLib library class interfaces.
|
Implementation for PlatformBootManagerLib library class interfaces.
|
||||||
|
|
||||||
Copyright (C) 2015-2016, Red Hat, Inc.
|
Copyright (C) 2015-2016, Red Hat, Inc.
|
||||||
Copyright (c) 2014, ARM Ltd. All rights reserved.<BR>
|
Copyright (c) 2014 - 2019, ARM Ltd. All rights reserved.<BR>
|
||||||
Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>
|
Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||||
Copyright (c) 2016, Linaro Ltd. All rights reserved.<BR>
|
Copyright (c) 2016, Linaro Ltd. All rights reserved.<BR>
|
||||||
|
|
||||||
@@ -549,6 +549,11 @@ PlatformBootManagerBeforeConsole (
|
|||||||
//
|
//
|
||||||
EfiEventGroupSignal (&gEfiEndOfDxeEventGroupGuid);
|
EfiEventGroupSignal (&gEfiEndOfDxeEventGroupGuid);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Dispatch deferred images after EndOfDxe event.
|
||||||
|
//
|
||||||
|
EfiBootManagerDispatchDeferredImages ();
|
||||||
|
|
||||||
//
|
//
|
||||||
// Locate the PCI root bridges and make the PCI bus driver connect each,
|
// Locate the PCI root bridges and make the PCI bus driver connect each,
|
||||||
// non-recursively. This will produce a number of child handles with PciIo on
|
// non-recursively. This will produce a number of child handles with PciIo on
|
||||||
|
@@ -94,10 +94,6 @@
|
|||||||
gArmPlatformTokenSpaceGuid.PcdArmMaliDpBase|0x0|UINT64|0x00000050
|
gArmPlatformTokenSpaceGuid.PcdArmMaliDpBase|0x0|UINT64|0x00000050
|
||||||
gArmPlatformTokenSpaceGuid.PcdArmMaliDpMemoryRegionLength|0x0|UINT32|0x00000051
|
gArmPlatformTokenSpaceGuid.PcdArmMaliDpMemoryRegionLength|0x0|UINT32|0x00000051
|
||||||
|
|
||||||
## PL180 MCI
|
|
||||||
gArmPlatformTokenSpaceGuid.PcdPL180SysMciRegAddress|0x00000000|UINT32|0x00000028
|
|
||||||
gArmPlatformTokenSpaceGuid.PcdPL180MciBaseAddress|0x00000000|UINT32|0x00000029
|
|
||||||
|
|
||||||
# Graphics Output Pixel format
|
# Graphics Output Pixel format
|
||||||
# 0 : PixelRedGreenBlueReserved8BitPerColor
|
# 0 : PixelRedGreenBlueReserved8BitPerColor
|
||||||
# 1 : PixelBlueGreenRedReserved8BitPerColor
|
# 1 : PixelBlueGreenRedReserved8BitPerColor
|
||||||
|
@@ -4,6 +4,7 @@
|
|||||||
# Copyright (c) 2009 - 2010, Apple Inc. All rights reserved.<BR>
|
# Copyright (c) 2009 - 2010, Apple Inc. All rights reserved.<BR>
|
||||||
# Copyright (c) 2011 - 2018, ARM Ltd. All rights reserved.<BR>
|
# Copyright (c) 2011 - 2018, ARM Ltd. All rights reserved.<BR>
|
||||||
# Copyright (c) 2016 - 2017, Linaro Ltd. All rights reserved.<BR>
|
# Copyright (c) 2016 - 2017, Linaro Ltd. All rights reserved.<BR>
|
||||||
|
# Copyright (c) Microsoft Corporation.<BR>
|
||||||
#
|
#
|
||||||
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
#
|
#
|
||||||
@@ -90,11 +91,11 @@
|
|||||||
ArmPlatformPkg/Drivers/LcdGraphicsOutputDxe/LcdGraphicsOutputDxe.inf
|
ArmPlatformPkg/Drivers/LcdGraphicsOutputDxe/LcdGraphicsOutputDxe.inf
|
||||||
ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.inf
|
ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.inf
|
||||||
ArmPlatformPkg/Drivers/PL061GpioDxe/PL061GpioDxe.inf
|
ArmPlatformPkg/Drivers/PL061GpioDxe/PL061GpioDxe.inf
|
||||||
ArmPlatformPkg/Drivers/PL180MciDxe/PL180MciDxe.inf
|
|
||||||
ArmPlatformPkg/Drivers/SP805WatchdogDxe/SP805WatchdogDxe.inf
|
ArmPlatformPkg/Drivers/SP805WatchdogDxe/SP805WatchdogDxe.inf
|
||||||
|
|
||||||
ArmPlatformPkg/Library/ArmPlatformLibNull/ArmPlatformLibNull.inf
|
ArmPlatformPkg/Library/ArmPlatformLibNull/ArmPlatformLibNull.inf
|
||||||
ArmPlatformPkg/Library/ArmPlatformStackLib/ArmPlatformStackLib.inf
|
ArmPlatformPkg/Library/ArmPlatformStackLib/ArmPlatformStackLib.inf
|
||||||
|
ArmPlatformPkg/Library/HdLcd/HdLcd.inf
|
||||||
ArmPlatformPkg/Library/LcdHwNullLib/LcdHwNullLib.inf
|
ArmPlatformPkg/Library/LcdHwNullLib/LcdHwNullLib.inf
|
||||||
ArmPlatformPkg/Library/LcdPlatformNullLib/LcdPlatformNullLib.inf
|
ArmPlatformPkg/Library/LcdPlatformNullLib/LcdPlatformNullLib.inf
|
||||||
ArmPlatformPkg/Library/NorFlashPlatformNullLib/NorFlashPlatformNullLib.inf
|
ArmPlatformPkg/Library/NorFlashPlatformNullLib/NorFlashPlatformNullLib.inf
|
||||||
@@ -102,6 +103,7 @@
|
|||||||
ArmPlatformPkg/Library/PL011UartClockLib/PL011UartClockLib.inf
|
ArmPlatformPkg/Library/PL011UartClockLib/PL011UartClockLib.inf
|
||||||
ArmPlatformPkg/Library/PL011UartLib/PL011UartLib.inf
|
ArmPlatformPkg/Library/PL011UartLib/PL011UartLib.inf
|
||||||
ArmPlatformPkg/Library/PL031RealTimeClockLib/PL031RealTimeClockLib.inf
|
ArmPlatformPkg/Library/PL031RealTimeClockLib/PL031RealTimeClockLib.inf
|
||||||
|
ArmPlatformPkg/Library/PL111Lcd/PL111Lcd.inf
|
||||||
ArmPlatformPkg/Library/PrePiHobListPointerLib/PrePiHobListPointerLib.inf
|
ArmPlatformPkg/Library/PrePiHobListPointerLib/PrePiHobListPointerLib.inf
|
||||||
|
|
||||||
ArmPlatformPkg/MemoryInitPei/MemoryInitPeiLib.inf
|
ArmPlatformPkg/MemoryInitPei/MemoryInitPeiLib.inf
|
||||||
|
@@ -38,6 +38,7 @@
|
|||||||
UefiLib
|
UefiLib
|
||||||
|
|
||||||
[Protocols]
|
[Protocols]
|
||||||
|
gEfiCpuArchProtocolGuid
|
||||||
gEfiDevicePathProtocolGuid
|
gEfiDevicePathProtocolGuid
|
||||||
gEfiGraphicsOutputProtocolGuid
|
gEfiGraphicsOutputProtocolGuid
|
||||||
|
|
||||||
|
@@ -1,563 +0,0 @@
|
|||||||
/** @file
|
|
||||||
This file implement the MMC Host Protocol for the ARM PrimeCell PL180.
|
|
||||||
|
|
||||||
Copyright (c) 2011-2012, ARM Limited. All rights reserved.
|
|
||||||
|
|
||||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
|
||||||
|
|
||||||
**/
|
|
||||||
|
|
||||||
#include "PL180Mci.h"
|
|
||||||
|
|
||||||
#include <Library/DevicePathLib.h>
|
|
||||||
#include <Library/BaseMemoryLib.h>
|
|
||||||
|
|
||||||
EFI_MMC_HOST_PROTOCOL *gpMmcHost;
|
|
||||||
|
|
||||||
// Untested ...
|
|
||||||
//#define USE_STREAM
|
|
||||||
|
|
||||||
#define MMCI0_BLOCKLEN 512
|
|
||||||
#define MMCI0_POW2_BLOCKLEN 9
|
|
||||||
#define MMCI0_TIMEOUT 1000
|
|
||||||
|
|
||||||
#define SYS_MCI_CARDIN BIT0
|
|
||||||
#define SYS_MCI_WPROT BIT1
|
|
||||||
|
|
||||||
BOOLEAN
|
|
||||||
MciIsPowerOn (
|
|
||||||
VOID
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return ((MmioRead32 (MCI_POWER_CONTROL_REG) & MCI_POWER_ON) == MCI_POWER_ON);
|
|
||||||
}
|
|
||||||
|
|
||||||
EFI_STATUS
|
|
||||||
MciInitialize (
|
|
||||||
VOID
|
|
||||||
)
|
|
||||||
{
|
|
||||||
MCI_TRACE ("MciInitialize()");
|
|
||||||
return EFI_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOLEAN
|
|
||||||
MciIsCardPresent (
|
|
||||||
IN EFI_MMC_HOST_PROTOCOL *This
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return (MmioRead32 (FixedPcdGet32 (PcdPL180SysMciRegAddress)) & SYS_MCI_CARDIN);
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOLEAN
|
|
||||||
MciIsReadOnly (
|
|
||||||
IN EFI_MMC_HOST_PROTOCOL *This
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return (MmioRead32 (FixedPcdGet32 (PcdPL180SysMciRegAddress)) & SYS_MCI_WPROT);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Convert block size to 2^n
|
|
||||||
STATIC
|
|
||||||
UINT32
|
|
||||||
GetPow2BlockLen (
|
|
||||||
IN UINT32 BlockLen
|
|
||||||
)
|
|
||||||
{
|
|
||||||
UINTN Loop;
|
|
||||||
UINTN Pow2BlockLen;
|
|
||||||
|
|
||||||
Loop = 0x8000;
|
|
||||||
Pow2BlockLen = 15;
|
|
||||||
do {
|
|
||||||
Loop = (Loop >> 1) & 0xFFFF;
|
|
||||||
Pow2BlockLen--;
|
|
||||||
} while (Pow2BlockLen && (!(Loop & BlockLen)));
|
|
||||||
|
|
||||||
return Pow2BlockLen;
|
|
||||||
}
|
|
||||||
|
|
||||||
VOID
|
|
||||||
MciPrepareDataPath (
|
|
||||||
IN UINTN TransferDirection
|
|
||||||
)
|
|
||||||
{
|
|
||||||
// Set Data Length & Data Timer
|
|
||||||
MmioWrite32 (MCI_DATA_TIMER_REG, 0xFFFFFFF);
|
|
||||||
MmioWrite32 (MCI_DATA_LENGTH_REG, MMCI0_BLOCKLEN);
|
|
||||||
|
|
||||||
#ifndef USE_STREAM
|
|
||||||
//Note: we are using a hardcoded BlockLen (==512). If we decide to use a variable size, we could
|
|
||||||
// compute the pow2 of BlockLen with the above function GetPow2BlockLen ()
|
|
||||||
MmioWrite32 (MCI_DATA_CTL_REG, MCI_DATACTL_ENABLE | MCI_DATACTL_DMA_ENABLE | TransferDirection | (MMCI0_POW2_BLOCKLEN << 4));
|
|
||||||
#else
|
|
||||||
MmioWrite32 (MCI_DATA_CTL_REG, MCI_DATACTL_ENABLE | MCI_DATACTL_DMA_ENABLE | TransferDirection | MCI_DATACTL_STREAM_TRANS);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
EFI_STATUS
|
|
||||||
MciSendCommand (
|
|
||||||
IN EFI_MMC_HOST_PROTOCOL *This,
|
|
||||||
IN MMC_CMD MmcCmd,
|
|
||||||
IN UINT32 Argument
|
|
||||||
)
|
|
||||||
{
|
|
||||||
UINT32 Status;
|
|
||||||
UINT32 Cmd;
|
|
||||||
UINTN RetVal;
|
|
||||||
UINTN CmdCtrlReg;
|
|
||||||
UINT32 DoneMask;
|
|
||||||
|
|
||||||
RetVal = EFI_SUCCESS;
|
|
||||||
|
|
||||||
if ((MmcCmd == MMC_CMD17) || (MmcCmd == MMC_CMD11)) {
|
|
||||||
MciPrepareDataPath (MCI_DATACTL_CARD_TO_CONT);
|
|
||||||
} else if ((MmcCmd == MMC_CMD24) || (MmcCmd == MMC_CMD20)) {
|
|
||||||
MciPrepareDataPath (MCI_DATACTL_CONT_TO_CARD);
|
|
||||||
} else if (MmcCmd == MMC_CMD6) {
|
|
||||||
MmioWrite32 (MCI_DATA_TIMER_REG, 0xFFFFFFF);
|
|
||||||
MmioWrite32 (MCI_DATA_LENGTH_REG, 64);
|
|
||||||
#ifndef USE_STREAM
|
|
||||||
MmioWrite32 (MCI_DATA_CTL_REG, MCI_DATACTL_ENABLE | MCI_DATACTL_CARD_TO_CONT | GetPow2BlockLen (64));
|
|
||||||
#else
|
|
||||||
MmioWrite32 (MCI_DATA_CTL_REG, MCI_DATACTL_ENABLE | MCI_DATACTL_CARD_TO_CONT | MCI_DATACTL_STREAM_TRANS);
|
|
||||||
#endif
|
|
||||||
} else if (MmcCmd == MMC_ACMD51) {
|
|
||||||
MmioWrite32 (MCI_DATA_TIMER_REG, 0xFFFFFFF);
|
|
||||||
/* SCR register is 8 bytes long. */
|
|
||||||
MmioWrite32 (MCI_DATA_LENGTH_REG, 8);
|
|
||||||
#ifndef USE_STREAM
|
|
||||||
MmioWrite32 (MCI_DATA_CTL_REG, MCI_DATACTL_ENABLE | MCI_DATACTL_CARD_TO_CONT | GetPow2BlockLen (8));
|
|
||||||
#else
|
|
||||||
MmioWrite32 (MCI_DATA_CTL_REG, MCI_DATACTL_ENABLE | MCI_DATACTL_CARD_TO_CONT | MCI_DATACTL_STREAM_TRANS);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create Command for PL180
|
|
||||||
Cmd = (MMC_GET_INDX (MmcCmd) & INDX_MASK) | MCI_CPSM_ENABLE;
|
|
||||||
if (MmcCmd & MMC_CMD_WAIT_RESPONSE) {
|
|
||||||
Cmd |= MCI_CPSM_WAIT_RESPONSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (MmcCmd & MMC_CMD_LONG_RESPONSE) {
|
|
||||||
Cmd |= MCI_CPSM_LONG_RESPONSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Clear Status register static flags
|
|
||||||
MmioWrite32 (MCI_CLEAR_STATUS_REG, MCI_CLR_ALL_STATUS);
|
|
||||||
|
|
||||||
// Write to command argument register
|
|
||||||
MmioWrite32 (MCI_ARGUMENT_REG, Argument);
|
|
||||||
|
|
||||||
// Write to command register
|
|
||||||
MmioWrite32 (MCI_COMMAND_REG, Cmd);
|
|
||||||
|
|
||||||
DoneMask = (Cmd & MCI_CPSM_WAIT_RESPONSE)
|
|
||||||
? (MCI_STATUS_CMD_RESPEND | MCI_STATUS_CMD_ERROR)
|
|
||||||
: (MCI_STATUS_CMD_SENT | MCI_STATUS_CMD_ERROR);
|
|
||||||
do {
|
|
||||||
Status = MmioRead32 (MCI_STATUS_REG);
|
|
||||||
} while (! (Status & DoneMask));
|
|
||||||
|
|
||||||
if ((Status & MCI_STATUS_CMD_ERROR)) {
|
|
||||||
// Clear Status register error flags
|
|
||||||
MmioWrite32 (MCI_CLEAR_STATUS_REG, MCI_STATUS_CMD_ERROR);
|
|
||||||
|
|
||||||
if ((Status & MCI_STATUS_CMD_START_BIT_ERROR)) {
|
|
||||||
DEBUG ((EFI_D_ERROR, "MciSendCommand(CmdIndex:%d) Start bit Error! Response:0x%X Status:0x%x\n", (Cmd & 0x3F), MmioRead32 (MCI_RESPONSE0_REG), Status));
|
|
||||||
RetVal = EFI_NO_RESPONSE;
|
|
||||||
} else if ((Status & MCI_STATUS_CMD_CMDTIMEOUT)) {
|
|
||||||
//DEBUG ((EFI_D_ERROR, "MciSendCommand(CmdIndex:%d) TIMEOUT! Response:0x%X Status:0x%x\n", (Cmd & 0x3F), MmioRead32 (MCI_RESPONSE0_REG), Status));
|
|
||||||
RetVal = EFI_TIMEOUT;
|
|
||||||
} else if ((!(MmcCmd & MMC_CMD_NO_CRC_RESPONSE)) && (Status & MCI_STATUS_CMD_CMDCRCFAIL)) {
|
|
||||||
// The CMD1 and response type R3 do not contain CRC. We should ignore the CRC failed Status.
|
|
||||||
RetVal = EFI_CRC_ERROR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Disable Command Path
|
|
||||||
CmdCtrlReg = MmioRead32 (MCI_COMMAND_REG);
|
|
||||||
MmioWrite32 (MCI_COMMAND_REG, (CmdCtrlReg & ~MCI_CPSM_ENABLE));
|
|
||||||
return RetVal;
|
|
||||||
}
|
|
||||||
|
|
||||||
EFI_STATUS
|
|
||||||
MciReceiveResponse (
|
|
||||||
IN EFI_MMC_HOST_PROTOCOL *This,
|
|
||||||
IN MMC_RESPONSE_TYPE Type,
|
|
||||||
IN UINT32* Buffer
|
|
||||||
)
|
|
||||||
{
|
|
||||||
if (Buffer == NULL) {
|
|
||||||
return EFI_INVALID_PARAMETER;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( (Type == MMC_RESPONSE_TYPE_R1)
|
|
||||||
|| (Type == MMC_RESPONSE_TYPE_R1b)
|
|
||||||
|| (Type == MMC_RESPONSE_TYPE_R3)
|
|
||||||
|| (Type == MMC_RESPONSE_TYPE_R6)
|
|
||||||
|| (Type == MMC_RESPONSE_TYPE_R7))
|
|
||||||
{
|
|
||||||
Buffer[0] = MmioRead32 (MCI_RESPONSE3_REG);
|
|
||||||
} else if (Type == MMC_RESPONSE_TYPE_R2) {
|
|
||||||
Buffer[0] = MmioRead32 (MCI_RESPONSE0_REG);
|
|
||||||
Buffer[1] = MmioRead32 (MCI_RESPONSE1_REG);
|
|
||||||
Buffer[2] = MmioRead32 (MCI_RESPONSE2_REG);
|
|
||||||
Buffer[3] = MmioRead32 (MCI_RESPONSE3_REG);
|
|
||||||
}
|
|
||||||
|
|
||||||
return EFI_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
EFI_STATUS
|
|
||||||
MciReadBlockData (
|
|
||||||
IN EFI_MMC_HOST_PROTOCOL *This,
|
|
||||||
IN EFI_LBA Lba,
|
|
||||||
IN UINTN Length,
|
|
||||||
IN UINT32* Buffer
|
|
||||||
)
|
|
||||||
{
|
|
||||||
UINTN Loop;
|
|
||||||
UINTN Finish;
|
|
||||||
UINTN Status;
|
|
||||||
EFI_STATUS RetVal;
|
|
||||||
UINTN DataCtrlReg;
|
|
||||||
EFI_TPL Tpl;
|
|
||||||
|
|
||||||
RetVal = EFI_SUCCESS;
|
|
||||||
|
|
||||||
// Read data from the RX FIFO
|
|
||||||
Loop = 0;
|
|
||||||
if (Length < MMCI0_BLOCKLEN) {
|
|
||||||
Finish = Length / 4;
|
|
||||||
} else {
|
|
||||||
Finish = MMCI0_BLOCKLEN / 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Raise the TPL at the highest level to disable Interrupts.
|
|
||||||
Tpl = gBS->RaiseTPL (TPL_HIGH_LEVEL);
|
|
||||||
|
|
||||||
do {
|
|
||||||
// Read the Status flags
|
|
||||||
Status = MmioRead32 (MCI_STATUS_REG);
|
|
||||||
|
|
||||||
// Do eight reads if possible else a single read
|
|
||||||
if (Status & MCI_STATUS_CMD_RXFIFOHALFFULL) {
|
|
||||||
Buffer[Loop] = MmioRead32(MCI_FIFO_REG);
|
|
||||||
Loop++;
|
|
||||||
Buffer[Loop] = MmioRead32(MCI_FIFO_REG);
|
|
||||||
Loop++;
|
|
||||||
Buffer[Loop] = MmioRead32(MCI_FIFO_REG);
|
|
||||||
Loop++;
|
|
||||||
Buffer[Loop] = MmioRead32(MCI_FIFO_REG);
|
|
||||||
Loop++;
|
|
||||||
Buffer[Loop] = MmioRead32(MCI_FIFO_REG);
|
|
||||||
Loop++;
|
|
||||||
Buffer[Loop] = MmioRead32(MCI_FIFO_REG);
|
|
||||||
Loop++;
|
|
||||||
Buffer[Loop] = MmioRead32(MCI_FIFO_REG);
|
|
||||||
Loop++;
|
|
||||||
Buffer[Loop] = MmioRead32(MCI_FIFO_REG);
|
|
||||||
Loop++;
|
|
||||||
} else if (Status & MCI_STATUS_CMD_RXDATAAVAILBL) {
|
|
||||||
Buffer[Loop] = MmioRead32(MCI_FIFO_REG);
|
|
||||||
Loop++;
|
|
||||||
} else {
|
|
||||||
//Check for error conditions and timeouts
|
|
||||||
if (Status & MCI_STATUS_CMD_DATATIMEOUT) {
|
|
||||||
DEBUG ((EFI_D_ERROR, "MciReadBlockData(): TIMEOUT! Response:0x%X Status:0x%x\n", MmioRead32 (MCI_RESPONSE0_REG), Status));
|
|
||||||
RetVal = EFI_TIMEOUT;
|
|
||||||
break;
|
|
||||||
} else if (Status & MCI_STATUS_CMD_DATACRCFAIL) {
|
|
||||||
DEBUG ((EFI_D_ERROR, "MciReadBlockData(): CRC Error! Response:0x%X Status:0x%x\n", MmioRead32 (MCI_RESPONSE0_REG), Status));
|
|
||||||
RetVal = EFI_CRC_ERROR;
|
|
||||||
break;
|
|
||||||
} else if (Status & MCI_STATUS_CMD_START_BIT_ERROR) {
|
|
||||||
DEBUG ((EFI_D_ERROR, "MciReadBlockData(): Start-bit Error! Response:0x%X Status:0x%x\n", MmioRead32 (MCI_RESPONSE0_REG), Status));
|
|
||||||
RetVal = EFI_NO_RESPONSE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//clear RX over run flag
|
|
||||||
if(Status & MCI_STATUS_CMD_RXOVERRUN) {
|
|
||||||
MmioWrite32(MCI_CLEAR_STATUS_REG, MCI_STATUS_CMD_RXOVERRUN);
|
|
||||||
}
|
|
||||||
} while ((Loop < Finish));
|
|
||||||
|
|
||||||
// Restore Tpl
|
|
||||||
gBS->RestoreTPL (Tpl);
|
|
||||||
|
|
||||||
// Clear Status flags
|
|
||||||
MmioWrite32 (MCI_CLEAR_STATUS_REG, MCI_CLR_ALL_STATUS);
|
|
||||||
|
|
||||||
//Disable Data path
|
|
||||||
DataCtrlReg = MmioRead32 (MCI_DATA_CTL_REG);
|
|
||||||
MmioWrite32 (MCI_DATA_CTL_REG, (DataCtrlReg & MCI_DATACTL_DISABLE_MASK));
|
|
||||||
|
|
||||||
return RetVal;
|
|
||||||
}
|
|
||||||
|
|
||||||
EFI_STATUS
|
|
||||||
MciWriteBlockData (
|
|
||||||
IN EFI_MMC_HOST_PROTOCOL *This,
|
|
||||||
IN EFI_LBA Lba,
|
|
||||||
IN UINTN Length,
|
|
||||||
IN UINT32* Buffer
|
|
||||||
)
|
|
||||||
{
|
|
||||||
UINTN Loop;
|
|
||||||
UINTN Finish;
|
|
||||||
UINTN Timer;
|
|
||||||
UINTN Status;
|
|
||||||
EFI_STATUS RetVal;
|
|
||||||
UINTN DataCtrlReg;
|
|
||||||
EFI_TPL Tpl;
|
|
||||||
|
|
||||||
RetVal = EFI_SUCCESS;
|
|
||||||
|
|
||||||
// Write the data to the TX FIFO
|
|
||||||
Loop = 0;
|
|
||||||
Finish = MMCI0_BLOCKLEN / 4;
|
|
||||||
Timer = MMCI0_TIMEOUT * 100;
|
|
||||||
|
|
||||||
// Raise the TPL at the highest level to disable Interrupts.
|
|
||||||
Tpl = gBS->RaiseTPL (TPL_HIGH_LEVEL);
|
|
||||||
|
|
||||||
do {
|
|
||||||
// Read the Status flags
|
|
||||||
Status = MmioRead32 (MCI_STATUS_REG);
|
|
||||||
|
|
||||||
// Do eight writes if possible else a single write
|
|
||||||
if (Status & MCI_STATUS_CMD_TXFIFOHALFEMPTY) {
|
|
||||||
MmioWrite32(MCI_FIFO_REG, Buffer[Loop]);
|
|
||||||
Loop++;
|
|
||||||
MmioWrite32(MCI_FIFO_REG, Buffer[Loop]);
|
|
||||||
Loop++;
|
|
||||||
MmioWrite32(MCI_FIFO_REG, Buffer[Loop]);
|
|
||||||
Loop++;
|
|
||||||
MmioWrite32(MCI_FIFO_REG, Buffer[Loop]);
|
|
||||||
Loop++;
|
|
||||||
MmioWrite32(MCI_FIFO_REG, Buffer[Loop]);
|
|
||||||
Loop++;
|
|
||||||
MmioWrite32(MCI_FIFO_REG, Buffer[Loop]);
|
|
||||||
Loop++;
|
|
||||||
MmioWrite32(MCI_FIFO_REG, Buffer[Loop]);
|
|
||||||
Loop++;
|
|
||||||
MmioWrite32(MCI_FIFO_REG, Buffer[Loop]);
|
|
||||||
Loop++;
|
|
||||||
} else if (!(Status & MCI_STATUS_CMD_TXFIFOFULL)) {
|
|
||||||
MmioWrite32(MCI_FIFO_REG, Buffer[Loop]);
|
|
||||||
Loop++;
|
|
||||||
} else {
|
|
||||||
// Check for error conditions and timeouts
|
|
||||||
if (Status & MCI_STATUS_CMD_DATATIMEOUT) {
|
|
||||||
DEBUG ((EFI_D_ERROR, "MciWriteBlockData(): TIMEOUT! Response:0x%X Status:0x%x\n", MmioRead32 (MCI_RESPONSE0_REG), Status));
|
|
||||||
RetVal = EFI_TIMEOUT;
|
|
||||||
goto Exit;
|
|
||||||
} else if (Status & MCI_STATUS_CMD_DATACRCFAIL) {
|
|
||||||
DEBUG ((EFI_D_ERROR, "MciWriteBlockData(): CRC Error! Response:0x%X Status:0x%x\n", MmioRead32 (MCI_RESPONSE0_REG), Status));
|
|
||||||
RetVal = EFI_CRC_ERROR;
|
|
||||||
goto Exit;
|
|
||||||
} else if (Status & MCI_STATUS_CMD_TX_UNDERRUN) {
|
|
||||||
DEBUG ((EFI_D_ERROR, "MciWriteBlockData(): TX buffer Underrun! Response:0x%X Status:0x%x, Number of bytes written 0x%x\n",MmioRead32(MCI_RESPONSE0_REG),Status, Loop));
|
|
||||||
RetVal = EFI_BUFFER_TOO_SMALL;
|
|
||||||
ASSERT(0);
|
|
||||||
goto Exit;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} while (Loop < Finish);
|
|
||||||
|
|
||||||
// Restore Tpl
|
|
||||||
gBS->RestoreTPL (Tpl);
|
|
||||||
|
|
||||||
// Wait for FIFO to drain
|
|
||||||
Timer = MMCI0_TIMEOUT * 60;
|
|
||||||
Status = MmioRead32 (MCI_STATUS_REG);
|
|
||||||
#ifndef USE_STREAM
|
|
||||||
// Single block
|
|
||||||
while (((Status & MCI_STATUS_TXDONE) != MCI_STATUS_TXDONE) && Timer) {
|
|
||||||
#else
|
|
||||||
// Stream
|
|
||||||
while (((Status & MCI_STATUS_CMD_DATAEND) != MCI_STATUS_CMD_DATAEND) && Timer) {
|
|
||||||
#endif
|
|
||||||
NanoSecondDelay(10);
|
|
||||||
Status = MmioRead32 (MCI_STATUS_REG);
|
|
||||||
Timer--;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Clear Status flags
|
|
||||||
MmioWrite32 (MCI_CLEAR_STATUS_REG, MCI_CLR_ALL_STATUS);
|
|
||||||
|
|
||||||
if (Timer == 0) {
|
|
||||||
DEBUG ((EFI_D_ERROR, "MciWriteBlockData(): Data End timeout Number of words written 0x%x\n", Loop));
|
|
||||||
RetVal = EFI_TIMEOUT;
|
|
||||||
}
|
|
||||||
|
|
||||||
Exit:
|
|
||||||
// Disable Data path
|
|
||||||
DataCtrlReg = MmioRead32 (MCI_DATA_CTL_REG);
|
|
||||||
MmioWrite32 (MCI_DATA_CTL_REG, (DataCtrlReg & MCI_DATACTL_DISABLE_MASK));
|
|
||||||
return RetVal;
|
|
||||||
}
|
|
||||||
|
|
||||||
EFI_STATUS
|
|
||||||
MciNotifyState (
|
|
||||||
IN EFI_MMC_HOST_PROTOCOL *This,
|
|
||||||
IN MMC_STATE State
|
|
||||||
)
|
|
||||||
{
|
|
||||||
UINT32 Data32;
|
|
||||||
|
|
||||||
switch (State) {
|
|
||||||
case MmcInvalidState:
|
|
||||||
ASSERT (0);
|
|
||||||
break;
|
|
||||||
case MmcHwInitializationState:
|
|
||||||
// If device already turn on then restart it
|
|
||||||
Data32 = MmioRead32 (MCI_POWER_CONTROL_REG);
|
|
||||||
if ((Data32 & 0x2) == MCI_POWER_UP) {
|
|
||||||
MCI_TRACE ("MciNotifyState(MmcHwInitializationState): TurnOff MCI");
|
|
||||||
|
|
||||||
// Turn off
|
|
||||||
MmioWrite32 (MCI_CLOCK_CONTROL_REG, 0);
|
|
||||||
MmioWrite32 (MCI_POWER_CONTROL_REG, 0);
|
|
||||||
MicroSecondDelay (100);
|
|
||||||
}
|
|
||||||
|
|
||||||
MCI_TRACE ("MciNotifyState(MmcHwInitializationState): TurnOn MCI");
|
|
||||||
// Setup clock
|
|
||||||
// - 0x1D = 29 => should be the clock divider to be less than 400kHz at MCLK = 24Mhz
|
|
||||||
MmioWrite32 (MCI_CLOCK_CONTROL_REG, 0x1D | MCI_CLOCK_ENABLE | MCI_CLOCK_POWERSAVE);
|
|
||||||
|
|
||||||
// Set the voltage
|
|
||||||
MmioWrite32 (MCI_POWER_CONTROL_REG, MCI_POWER_OPENDRAIN | (15<<2));
|
|
||||||
MmioWrite32 (MCI_POWER_CONTROL_REG, MCI_POWER_ROD | MCI_POWER_OPENDRAIN | (15<<2) | MCI_POWER_UP);
|
|
||||||
MicroSecondDelay (10);
|
|
||||||
MmioWrite32 (MCI_POWER_CONTROL_REG, MCI_POWER_ROD | MCI_POWER_OPENDRAIN | (15<<2) | MCI_POWER_ON);
|
|
||||||
MicroSecondDelay (100);
|
|
||||||
|
|
||||||
// Set Data Length & Data Timer
|
|
||||||
MmioWrite32 (MCI_DATA_TIMER_REG, 0xFFFFF);
|
|
||||||
MmioWrite32 (MCI_DATA_LENGTH_REG, 8);
|
|
||||||
|
|
||||||
ASSERT ((MmioRead32 (MCI_POWER_CONTROL_REG) & 0x3) == MCI_POWER_ON);
|
|
||||||
break;
|
|
||||||
case MmcIdleState:
|
|
||||||
MCI_TRACE ("MciNotifyState(MmcIdleState)");
|
|
||||||
break;
|
|
||||||
case MmcReadyState:
|
|
||||||
MCI_TRACE ("MciNotifyState(MmcReadyState)");
|
|
||||||
break;
|
|
||||||
case MmcIdentificationState:
|
|
||||||
MCI_TRACE ("MciNotifyState (MmcIdentificationState)");
|
|
||||||
break;
|
|
||||||
case MmcStandByState:{
|
|
||||||
volatile UINT32 PwrCtrlReg;
|
|
||||||
MCI_TRACE ("MciNotifyState (MmcStandByState)");
|
|
||||||
|
|
||||||
// Enable MCICMD push-pull drive
|
|
||||||
PwrCtrlReg = MmioRead32 (MCI_POWER_CONTROL_REG);
|
|
||||||
//Disable Open Drain output
|
|
||||||
PwrCtrlReg &= ~ (MCI_POWER_OPENDRAIN);
|
|
||||||
MmioWrite32 (MCI_POWER_CONTROL_REG, PwrCtrlReg);
|
|
||||||
|
|
||||||
// Set MMCI0 clock to 4MHz (24MHz may be possible with cache enabled)
|
|
||||||
//
|
|
||||||
// Note: Increasing clock speed causes TX FIFO under-run errors.
|
|
||||||
// So careful when optimising this driver for higher performance.
|
|
||||||
//
|
|
||||||
MmioWrite32(MCI_CLOCK_CONTROL_REG,0x02 | MCI_CLOCK_ENABLE | MCI_CLOCK_POWERSAVE);
|
|
||||||
// Set MMCI0 clock to 24MHz (by bypassing the divider)
|
|
||||||
//MmioWrite32(MCI_CLOCK_CONTROL_REG,MCI_CLOCK_BYPASS | MCI_CLOCK_ENABLE);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case MmcTransferState:
|
|
||||||
//MCI_TRACE ("MciNotifyState(MmcTransferState)");
|
|
||||||
break;
|
|
||||||
case MmcSendingDataState:
|
|
||||||
MCI_TRACE ("MciNotifyState(MmcSendingDataState)");
|
|
||||||
break;
|
|
||||||
case MmcReceiveDataState:
|
|
||||||
MCI_TRACE ("MciNotifyState(MmcReceiveDataState)");
|
|
||||||
break;
|
|
||||||
case MmcProgrammingState:
|
|
||||||
MCI_TRACE ("MciNotifyState(MmcProgrammingState)");
|
|
||||||
break;
|
|
||||||
case MmcDisconnectState:
|
|
||||||
MCI_TRACE ("MciNotifyState(MmcDisconnectState)");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
ASSERT (0);
|
|
||||||
}
|
|
||||||
return EFI_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
EFI_GUID mPL180MciDevicePathGuid = EFI_CALLER_ID_GUID;
|
|
||||||
|
|
||||||
EFI_STATUS
|
|
||||||
MciBuildDevicePath (
|
|
||||||
IN EFI_MMC_HOST_PROTOCOL *This,
|
|
||||||
IN EFI_DEVICE_PATH_PROTOCOL **DevicePath
|
|
||||||
)
|
|
||||||
{
|
|
||||||
EFI_DEVICE_PATH_PROTOCOL *NewDevicePathNode;
|
|
||||||
|
|
||||||
NewDevicePathNode = CreateDeviceNode (HARDWARE_DEVICE_PATH, HW_VENDOR_DP, sizeof (VENDOR_DEVICE_PATH));
|
|
||||||
CopyGuid (& ((VENDOR_DEVICE_PATH*)NewDevicePathNode)->Guid, &mPL180MciDevicePathGuid);
|
|
||||||
|
|
||||||
*DevicePath = NewDevicePathNode;
|
|
||||||
return EFI_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
EFI_MMC_HOST_PROTOCOL gMciHost = {
|
|
||||||
MMC_HOST_PROTOCOL_REVISION,
|
|
||||||
MciIsCardPresent,
|
|
||||||
MciIsReadOnly,
|
|
||||||
MciBuildDevicePath,
|
|
||||||
MciNotifyState,
|
|
||||||
MciSendCommand,
|
|
||||||
MciReceiveResponse,
|
|
||||||
MciReadBlockData,
|
|
||||||
MciWriteBlockData
|
|
||||||
};
|
|
||||||
|
|
||||||
EFI_STATUS
|
|
||||||
PL180MciDxeInitialize (
|
|
||||||
IN EFI_HANDLE ImageHandle,
|
|
||||||
IN EFI_SYSTEM_TABLE *SystemTable
|
|
||||||
)
|
|
||||||
{
|
|
||||||
EFI_STATUS Status;
|
|
||||||
EFI_HANDLE Handle;
|
|
||||||
|
|
||||||
DEBUG ((EFI_D_WARN, "Probing ID registers at 0x%lx for a PL180\n",
|
|
||||||
MCI_PERIPH_ID_REG0));
|
|
||||||
|
|
||||||
// Check if this is a PL180
|
|
||||||
if (MmioRead8 (MCI_PERIPH_ID_REG0) != MCI_PERIPH_ID0 ||
|
|
||||||
MmioRead8 (MCI_PERIPH_ID_REG1) != MCI_PERIPH_ID1 ||
|
|
||||||
MmioRead8 (MCI_PERIPH_ID_REG2) != MCI_PERIPH_ID2 ||
|
|
||||||
MmioRead8 (MCI_PCELL_ID_REG0) != MCI_PCELL_ID0 ||
|
|
||||||
MmioRead8 (MCI_PCELL_ID_REG1) != MCI_PCELL_ID1 ||
|
|
||||||
MmioRead8 (MCI_PCELL_ID_REG2) != MCI_PCELL_ID2 ||
|
|
||||||
MmioRead8 (MCI_PCELL_ID_REG3) != MCI_PCELL_ID3) {
|
|
||||||
|
|
||||||
DEBUG ((EFI_D_WARN, "Probing ID registers at 0x%lx for a PL180"
|
|
||||||
" failed\n", MCI_PERIPH_ID_REG0));
|
|
||||||
return EFI_NOT_FOUND;
|
|
||||||
}
|
|
||||||
|
|
||||||
Handle = NULL;
|
|
||||||
|
|
||||||
MCI_TRACE ("PL180MciDxeInitialize()");
|
|
||||||
|
|
||||||
//Publish Component Name, BlockIO protocol interfaces
|
|
||||||
Status = gBS->InstallMultipleProtocolInterfaces (
|
|
||||||
&Handle,
|
|
||||||
&gEfiMmcHostProtocolGuid, &gMciHost,
|
|
||||||
NULL
|
|
||||||
);
|
|
||||||
ASSERT_EFI_ERROR (Status);
|
|
||||||
|
|
||||||
return EFI_SUCCESS;
|
|
||||||
}
|
|
@@ -1,162 +0,0 @@
|
|||||||
/** @file
|
|
||||||
Header for the MMC Host Protocol implementation for the ARM PrimeCell PL180.
|
|
||||||
|
|
||||||
Copyright (c) 2011-2012, ARM Limited. All rights reserved.
|
|
||||||
|
|
||||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
|
||||||
|
|
||||||
**/
|
|
||||||
|
|
||||||
#ifndef __PL180_MCI_H
|
|
||||||
#define __PL180_MCI_H
|
|
||||||
|
|
||||||
#include <Uefi.h>
|
|
||||||
|
|
||||||
#include <Protocol/MmcHost.h>
|
|
||||||
|
|
||||||
#include <Library/UefiLib.h>
|
|
||||||
#include <Library/DebugLib.h>
|
|
||||||
#include <Library/UefiBootServicesTableLib.h>
|
|
||||||
#include <Library/IoLib.h>
|
|
||||||
#include <Library/TimerLib.h>
|
|
||||||
#include <Library/PcdLib.h>
|
|
||||||
|
|
||||||
#define PL180_MCI_DXE_VERSION 0x10
|
|
||||||
|
|
||||||
#define MCI_SYSCTL FixedPcdGet32 (PcdPL180MciBaseAddress)
|
|
||||||
|
|
||||||
#define MCI_POWER_CONTROL_REG (MCI_SYSCTL + 0x000)
|
|
||||||
#define MCI_CLOCK_CONTROL_REG (MCI_SYSCTL + 0x004)
|
|
||||||
#define MCI_ARGUMENT_REG (MCI_SYSCTL + 0x008)
|
|
||||||
#define MCI_COMMAND_REG (MCI_SYSCTL + 0x00C)
|
|
||||||
#define MCI_RESPCMD_REG (MCI_SYSCTL + 0x010)
|
|
||||||
#define MCI_RESPONSE3_REG (MCI_SYSCTL + 0x014)
|
|
||||||
#define MCI_RESPONSE2_REG (MCI_SYSCTL + 0x018)
|
|
||||||
#define MCI_RESPONSE1_REG (MCI_SYSCTL + 0x01C)
|
|
||||||
#define MCI_RESPONSE0_REG (MCI_SYSCTL + 0x020)
|
|
||||||
#define MCI_DATA_TIMER_REG (MCI_SYSCTL + 0x024)
|
|
||||||
#define MCI_DATA_LENGTH_REG (MCI_SYSCTL + 0x028)
|
|
||||||
#define MCI_DATA_CTL_REG (MCI_SYSCTL + 0x02C)
|
|
||||||
#define MCI_DATA_COUNTER (MCI_SYSCTL + 0x030)
|
|
||||||
#define MCI_STATUS_REG (MCI_SYSCTL + 0x034)
|
|
||||||
#define MCI_CLEAR_STATUS_REG (MCI_SYSCTL + 0x038)
|
|
||||||
#define MCI_INT0_MASK_REG (MCI_SYSCTL + 0x03C)
|
|
||||||
#define MCI_INT1_MASK_REG (MCI_SYSCTL + 0x040)
|
|
||||||
#define MCI_SELECT_REG (MCI_SYSCTL + 0x044)
|
|
||||||
#define MCI_FIFOCOUNT_REG (MCI_SYSCTL + 0x048)
|
|
||||||
#define MCI_FIFO_REG (MCI_SYSCTL + 0x080)
|
|
||||||
#define MCI_PERIPH_ID_REG0 (MCI_SYSCTL + 0xFE0)
|
|
||||||
#define MCI_PERIPH_ID_REG1 (MCI_SYSCTL + 0xFE4)
|
|
||||||
#define MCI_PERIPH_ID_REG2 (MCI_SYSCTL + 0xFE8)
|
|
||||||
#define MCI_PERIPH_ID_REG3 (MCI_SYSCTL + 0xFEC)
|
|
||||||
#define MCI_PCELL_ID_REG0 (MCI_SYSCTL + 0xFF0)
|
|
||||||
#define MCI_PCELL_ID_REG1 (MCI_SYSCTL + 0xFF4)
|
|
||||||
#define MCI_PCELL_ID_REG2 (MCI_SYSCTL + 0xFF8)
|
|
||||||
#define MCI_PCELL_ID_REG3 (MCI_SYSCTL + 0xFFC)
|
|
||||||
|
|
||||||
#define MCI_PERIPH_ID0 0x80
|
|
||||||
#define MCI_PERIPH_ID1 0x11
|
|
||||||
#define MCI_PERIPH_ID2 0x04
|
|
||||||
#define MCI_PERIPH_ID3 0x00
|
|
||||||
#define MCI_PCELL_ID0 0x0D
|
|
||||||
#define MCI_PCELL_ID1 0xF0
|
|
||||||
#define MCI_PCELL_ID2 0x05
|
|
||||||
#define MCI_PCELL_ID3 0xB1
|
|
||||||
|
|
||||||
#define MCI_POWER_OFF 0
|
|
||||||
#define MCI_POWER_UP BIT1
|
|
||||||
#define MCI_POWER_ON (BIT1 | BIT0)
|
|
||||||
#define MCI_POWER_OPENDRAIN BIT6
|
|
||||||
#define MCI_POWER_ROD BIT7
|
|
||||||
|
|
||||||
#define MCI_CLOCK_ENABLE BIT8
|
|
||||||
#define MCI_CLOCK_POWERSAVE BIT9
|
|
||||||
#define MCI_CLOCK_BYPASS BIT10
|
|
||||||
#define MCI_CLOCK_WIDEBUS BIT11
|
|
||||||
|
|
||||||
#define MCI_STATUS_CMD_CMDCRCFAIL BIT0
|
|
||||||
#define MCI_STATUS_CMD_DATACRCFAIL BIT1
|
|
||||||
#define MCI_STATUS_CMD_CMDTIMEOUT BIT2
|
|
||||||
#define MCI_STATUS_CMD_DATATIMEOUT BIT3
|
|
||||||
#define MCI_STATUS_CMD_TX_UNDERRUN BIT4
|
|
||||||
#define MCI_STATUS_CMD_RXOVERRUN BIT5
|
|
||||||
#define MCI_STATUS_CMD_RESPEND BIT6
|
|
||||||
#define MCI_STATUS_CMD_SENT BIT7
|
|
||||||
#define MCI_STATUS_CMD_DATAEND BIT8
|
|
||||||
#define MCI_STATUS_CMD_START_BIT_ERROR BIT9
|
|
||||||
#define MCI_STATUS_CMD_DATABLOCKEND BIT10
|
|
||||||
#define MCI_STATUS_CMD_ACTIVE BIT11
|
|
||||||
#define MCI_STATUS_CMD_TXACTIVE BIT12
|
|
||||||
#define MCI_STATUS_CMD_RXACTIVE BIT13
|
|
||||||
#define MCI_STATUS_CMD_TXFIFOHALFEMPTY BIT14
|
|
||||||
#define MCI_STATUS_CMD_RXFIFOHALFFULL BIT15
|
|
||||||
#define MCI_STATUS_CMD_TXFIFOFULL BIT16
|
|
||||||
#define MCI_STATUS_CMD_RXFIFOFULL BIT17
|
|
||||||
#define MCI_STATUS_CMD_TXFIFOEMPTY BIT18
|
|
||||||
#define MCI_STATUS_CMD_RXFIFOEMPTY BIT19
|
|
||||||
#define MCI_STATUS_CMD_TXDATAAVAILBL BIT20
|
|
||||||
#define MCI_STATUS_CMD_RXDATAAVAILBL BIT21
|
|
||||||
|
|
||||||
#define MCI_STATUS_TXDONE (MCI_STATUS_CMD_DATAEND | MCI_STATUS_CMD_DATABLOCKEND)
|
|
||||||
#define MCI_STATUS_RXDONE (MCI_STATUS_CMD_DATAEND | MCI_STATUS_CMD_DATABLOCKEND)
|
|
||||||
#define MCI_STATUS_READ_ERROR ( MCI_STATUS_CMD_DATACRCFAIL \
|
|
||||||
| MCI_STATUS_CMD_DATATIMEOUT \
|
|
||||||
| MCI_STATUS_CMD_RXOVERRUN \
|
|
||||||
| MCI_STATUS_CMD_START_BIT_ERROR )
|
|
||||||
#define MCI_STATUS_WRITE_ERROR ( MCI_STATUS_CMD_DATACRCFAIL \
|
|
||||||
| MCI_STATUS_CMD_DATATIMEOUT \
|
|
||||||
| MCI_STATUS_CMD_TX_UNDERRUN )
|
|
||||||
#define MCI_STATUS_CMD_ERROR ( MCI_STATUS_CMD_CMDCRCFAIL \
|
|
||||||
| MCI_STATUS_CMD_CMDTIMEOUT \
|
|
||||||
| MCI_STATUS_CMD_START_BIT_ERROR )
|
|
||||||
|
|
||||||
#define MCI_CLR_CMD_STATUS ( MCI_STATUS_CMD_RESPEND \
|
|
||||||
| MCI_STATUS_CMD_SENT \
|
|
||||||
| MCI_STATUS_CMD_ERROR )
|
|
||||||
|
|
||||||
#define MCI_CLR_READ_STATUS ( MCI_STATUS_RXDONE \
|
|
||||||
| MCI_STATUS_READ_ERROR )
|
|
||||||
|
|
||||||
#define MCI_CLR_WRITE_STATUS ( MCI_STATUS_TXDONE \
|
|
||||||
| MCI_STATUS_WRITE_ERROR )
|
|
||||||
|
|
||||||
#define MCI_CLR_ALL_STATUS (BIT11 - 1)
|
|
||||||
|
|
||||||
#define MCI_DATACTL_DISABLE_MASK 0xFE
|
|
||||||
#define MCI_DATACTL_ENABLE BIT0
|
|
||||||
#define MCI_DATACTL_CONT_TO_CARD 0
|
|
||||||
#define MCI_DATACTL_CARD_TO_CONT BIT1
|
|
||||||
#define MCI_DATACTL_BLOCK_TRANS 0
|
|
||||||
#define MCI_DATACTL_STREAM_TRANS BIT2
|
|
||||||
#define MCI_DATACTL_DMA_DISABLED 0
|
|
||||||
#define MCI_DATACTL_DMA_ENABLE BIT3
|
|
||||||
|
|
||||||
#define INDX_MASK 0x3F
|
|
||||||
|
|
||||||
#define MCI_CPSM_WAIT_RESPONSE BIT6
|
|
||||||
#define MCI_CPSM_LONG_RESPONSE BIT7
|
|
||||||
#define MCI_CPSM_LONG_INTERRUPT BIT8
|
|
||||||
#define MCI_CPSM_LONG_PENDING BIT9
|
|
||||||
#define MCI_CPSM_ENABLE BIT10
|
|
||||||
|
|
||||||
#define MCI_TRACE(txt) DEBUG ((EFI_D_BLKIO, "ARM_MCI: " txt "\n"))
|
|
||||||
|
|
||||||
EFI_STATUS
|
|
||||||
EFIAPI
|
|
||||||
MciGetDriverName (
|
|
||||||
IN EFI_COMPONENT_NAME_PROTOCOL *This,
|
|
||||||
IN CHAR8 *Language,
|
|
||||||
OUT CHAR16 **DriverName
|
|
||||||
);
|
|
||||||
|
|
||||||
EFI_STATUS
|
|
||||||
EFIAPI
|
|
||||||
MciGetControllerName (
|
|
||||||
IN EFI_COMPONENT_NAME_PROTOCOL *This,
|
|
||||||
IN EFI_HANDLE ControllerHandle,
|
|
||||||
IN EFI_HANDLE ChildHandle OPTIONAL,
|
|
||||||
IN CHAR8 *Language,
|
|
||||||
OUT CHAR16 **ControllerName
|
|
||||||
);
|
|
||||||
|
|
||||||
#endif
|
|
@@ -1,46 +0,0 @@
|
|||||||
#/** @file
|
|
||||||
# INF file for the MMC Host Protocol implementation for the ARM PrimeCell PL180.
|
|
||||||
#
|
|
||||||
# Copyright (c) 2011, ARM Limited. All rights reserved.
|
|
||||||
#
|
|
||||||
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
|
||||||
#
|
|
||||||
#**/
|
|
||||||
|
|
||||||
[Defines]
|
|
||||||
INF_VERSION = 0x00010005
|
|
||||||
BASE_NAME = PL180MciDxe
|
|
||||||
FILE_GUID = 09831032-6fa3-4484-af4f-0a000a8d3a82
|
|
||||||
MODULE_TYPE = DXE_DRIVER
|
|
||||||
VERSION_STRING = 1.0
|
|
||||||
|
|
||||||
ENTRY_POINT = PL180MciDxeInitialize
|
|
||||||
|
|
||||||
[Sources.common]
|
|
||||||
PL180Mci.c
|
|
||||||
|
|
||||||
[Packages]
|
|
||||||
ArmPlatformPkg/ArmPlatformPkg.dec
|
|
||||||
EmbeddedPkg/EmbeddedPkg.dec
|
|
||||||
MdePkg/MdePkg.dec
|
|
||||||
|
|
||||||
[LibraryClasses]
|
|
||||||
BaseLib
|
|
||||||
UefiLib
|
|
||||||
UefiDriverEntryPoint
|
|
||||||
BaseMemoryLib
|
|
||||||
ArmLib
|
|
||||||
IoLib
|
|
||||||
TimerLib
|
|
||||||
|
|
||||||
[Protocols]
|
|
||||||
gEfiCpuArchProtocolGuid
|
|
||||||
gEfiDevicePathProtocolGuid
|
|
||||||
gEfiMmcHostProtocolGuid
|
|
||||||
|
|
||||||
[Pcd]
|
|
||||||
gArmPlatformTokenSpaceGuid.PcdPL180SysMciRegAddress
|
|
||||||
gArmPlatformTokenSpaceGuid.PcdPL180MciBaseAddress
|
|
||||||
|
|
||||||
[Depex]
|
|
||||||
gEfiCpuArchProtocolGuid
|
|
@@ -8,6 +8,7 @@
|
|||||||
**/
|
**/
|
||||||
|
|
||||||
#include <Library/BaseLib.h>
|
#include <Library/BaseLib.h>
|
||||||
|
#include <Library/CacheMaintenanceLib.h>
|
||||||
#include <Library/DebugAgentLib.h>
|
#include <Library/DebugAgentLib.h>
|
||||||
#include <Library/ArmLib.h>
|
#include <Library/ArmLib.h>
|
||||||
|
|
||||||
@@ -59,13 +60,14 @@ CEntryPoint (
|
|||||||
{
|
{
|
||||||
// Data Cache enabled on Primary core when MMU is enabled.
|
// Data Cache enabled on Primary core when MMU is enabled.
|
||||||
ArmDisableDataCache ();
|
ArmDisableDataCache ();
|
||||||
// Invalidate Data cache
|
|
||||||
ArmInvalidateDataCache ();
|
|
||||||
// Invalidate instruction cache
|
// Invalidate instruction cache
|
||||||
ArmInvalidateInstructionCache ();
|
ArmInvalidateInstructionCache ();
|
||||||
// Enable Instruction Caches on all cores.
|
// Enable Instruction Caches on all cores.
|
||||||
ArmEnableInstructionCache ();
|
ArmEnableInstructionCache ();
|
||||||
|
|
||||||
|
InvalidateDataCacheRange ((VOID *)(UINTN)PcdGet64 (PcdCPUCoresStackBase),
|
||||||
|
PcdGet32 (PcdCPUCorePrimaryStackSize));
|
||||||
|
|
||||||
//
|
//
|
||||||
// Note: Doesn't have to Enable CPU interface in non-secure world,
|
// Note: Doesn't have to Enable CPU interface in non-secure world,
|
||||||
// as Non-secure interface is already enabled in Secure world.
|
// as Non-secure interface is already enabled in Secure world.
|
||||||
@@ -77,6 +79,11 @@ CEntryPoint (
|
|||||||
ASSERT (((UINTN)PeiVectorTable & ARM_VECTOR_TABLE_ALIGNMENT) == 0);
|
ASSERT (((UINTN)PeiVectorTable & ARM_VECTOR_TABLE_ALIGNMENT) == 0);
|
||||||
ArmWriteVBar ((UINTN)PeiVectorTable);
|
ArmWriteVBar ((UINTN)PeiVectorTable);
|
||||||
|
|
||||||
|
// Enable Floating Point
|
||||||
|
if (FixedPcdGet32 (PcdVFPEnabled)) {
|
||||||
|
ArmEnableVFP ();
|
||||||
|
}
|
||||||
|
|
||||||
//Note: The MMU will be enabled by MemoryPeim. Only the primary core will have the MMU on.
|
//Note: The MMU will be enabled by MemoryPeim. Only the primary core will have the MMU on.
|
||||||
|
|
||||||
// If not primary Jump to Secondary Main
|
// If not primary Jump to Secondary Main
|
||||||
|
@@ -44,6 +44,7 @@
|
|||||||
[LibraryClasses]
|
[LibraryClasses]
|
||||||
ArmLib
|
ArmLib
|
||||||
ArmPlatformLib
|
ArmPlatformLib
|
||||||
|
CacheMaintenanceLib
|
||||||
BaseLib
|
BaseLib
|
||||||
DebugLib
|
DebugLib
|
||||||
DebugAgentLib
|
DebugAgentLib
|
||||||
@@ -62,6 +63,7 @@
|
|||||||
[FixedPcd]
|
[FixedPcd]
|
||||||
gArmTokenSpaceGuid.PcdFvBaseAddress
|
gArmTokenSpaceGuid.PcdFvBaseAddress
|
||||||
gArmTokenSpaceGuid.PcdFvSize
|
gArmTokenSpaceGuid.PcdFvSize
|
||||||
|
gArmTokenSpaceGuid.PcdVFPEnabled
|
||||||
|
|
||||||
gArmPlatformTokenSpaceGuid.PcdCPUCoresStackBase
|
gArmPlatformTokenSpaceGuid.PcdCPUCoresStackBase
|
||||||
gArmPlatformTokenSpaceGuid.PcdCPUCorePrimaryStackSize
|
gArmPlatformTokenSpaceGuid.PcdCPUCorePrimaryStackSize
|
||||||
|
@@ -44,6 +44,7 @@
|
|||||||
[LibraryClasses]
|
[LibraryClasses]
|
||||||
ArmLib
|
ArmLib
|
||||||
ArmPlatformLib
|
ArmPlatformLib
|
||||||
|
CacheMaintenanceLib
|
||||||
BaseLib
|
BaseLib
|
||||||
DebugLib
|
DebugLib
|
||||||
DebugAgentLib
|
DebugAgentLib
|
||||||
@@ -60,6 +61,7 @@
|
|||||||
[FixedPcd]
|
[FixedPcd]
|
||||||
gArmTokenSpaceGuid.PcdFvBaseAddress
|
gArmTokenSpaceGuid.PcdFvBaseAddress
|
||||||
gArmTokenSpaceGuid.PcdFvSize
|
gArmTokenSpaceGuid.PcdFvSize
|
||||||
|
gArmTokenSpaceGuid.PcdVFPEnabled
|
||||||
|
|
||||||
gArmPlatformTokenSpaceGuid.PcdCPUCoresStackBase
|
gArmPlatformTokenSpaceGuid.PcdCPUCoresStackBase
|
||||||
gArmPlatformTokenSpaceGuid.PcdCPUCorePrimaryStackSize
|
gArmPlatformTokenSpaceGuid.PcdCPUCorePrimaryStackSize
|
||||||
|
@@ -37,6 +37,7 @@
|
|||||||
|
|
||||||
[LibraryClasses]
|
[LibraryClasses]
|
||||||
BaseLib
|
BaseLib
|
||||||
|
CacheMaintenanceLib
|
||||||
DebugLib
|
DebugLib
|
||||||
DebugAgentLib
|
DebugAgentLib
|
||||||
ArmLib
|
ArmLib
|
||||||
|
@@ -37,6 +37,7 @@
|
|||||||
|
|
||||||
[LibraryClasses]
|
[LibraryClasses]
|
||||||
BaseLib
|
BaseLib
|
||||||
|
CacheMaintenanceLib
|
||||||
DebugLib
|
DebugLib
|
||||||
DebugAgentLib
|
DebugAgentLib
|
||||||
ArmLib
|
ArmLib
|
||||||
|
@@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
#include <PiPei.h>
|
#include <PiPei.h>
|
||||||
|
|
||||||
|
#include <Library/CacheMaintenanceLib.h>
|
||||||
#include <Library/DebugAgentLib.h>
|
#include <Library/DebugAgentLib.h>
|
||||||
#include <Library/PrePiLib.h>
|
#include <Library/PrePiLib.h>
|
||||||
#include <Library/PrintLib.h>
|
#include <Library/PrintLib.h>
|
||||||
@@ -22,7 +23,7 @@
|
|||||||
#include "PrePi.h"
|
#include "PrePi.h"
|
||||||
|
|
||||||
#define IS_XIP() (((UINT64)FixedPcdGet64 (PcdFdBaseAddress) > mSystemMemoryEnd) || \
|
#define IS_XIP() (((UINT64)FixedPcdGet64 (PcdFdBaseAddress) > mSystemMemoryEnd) || \
|
||||||
((FixedPcdGet64 (PcdFdBaseAddress) + FixedPcdGet32 (PcdFdSize)) < FixedPcdGet64 (PcdSystemMemoryBase)))
|
((FixedPcdGet64 (PcdFdBaseAddress) + FixedPcdGet32 (PcdFdSize)) <= FixedPcdGet64 (PcdSystemMemoryBase)))
|
||||||
|
|
||||||
UINT64 mSystemMemoryEnd = FixedPcdGet64(PcdSystemMemoryBase) +
|
UINT64 mSystemMemoryEnd = FixedPcdGet64(PcdSystemMemoryBase) +
|
||||||
FixedPcdGet64(PcdSystemMemorySize) - 1;
|
FixedPcdGet64(PcdSystemMemorySize) - 1;
|
||||||
@@ -178,8 +179,6 @@ CEntryPoint (
|
|||||||
|
|
||||||
// Data Cache enabled on Primary core when MMU is enabled.
|
// Data Cache enabled on Primary core when MMU is enabled.
|
||||||
ArmDisableDataCache ();
|
ArmDisableDataCache ();
|
||||||
// Invalidate Data cache
|
|
||||||
ArmInvalidateDataCache ();
|
|
||||||
// Invalidate instruction cache
|
// Invalidate instruction cache
|
||||||
ArmInvalidateInstructionCache ();
|
ArmInvalidateInstructionCache ();
|
||||||
// Enable Instruction Caches on all cores.
|
// Enable Instruction Caches on all cores.
|
||||||
@@ -200,6 +199,10 @@ CEntryPoint (
|
|||||||
|
|
||||||
// If not primary Jump to Secondary Main
|
// If not primary Jump to Secondary Main
|
||||||
if (ArmPlatformIsPrimaryCore (MpId)) {
|
if (ArmPlatformIsPrimaryCore (MpId)) {
|
||||||
|
|
||||||
|
InvalidateDataCacheRange ((VOID *)UefiMemoryBase,
|
||||||
|
FixedPcdGet32 (PcdSystemMemoryUefiRegionSize));
|
||||||
|
|
||||||
// Goto primary Main.
|
// Goto primary Main.
|
||||||
PrimaryMain (UefiMemoryBase, StacksBase, StartTimeStamp);
|
PrimaryMain (UefiMemoryBase, StacksBase, StartTimeStamp);
|
||||||
} else {
|
} else {
|
||||||
@@ -209,4 +212,3 @@ CEntryPoint (
|
|||||||
// DXE Core should always load and never return
|
// DXE Core should always load and never return
|
||||||
ASSERT (FALSE);
|
ASSERT (FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -81,7 +81,7 @@ class EfiSectionTE:
|
|||||||
filename = self.base_te + debug_rva + 0xc
|
filename = self.base_te + debug_rva + 0xc
|
||||||
else:
|
else:
|
||||||
filename = self.base_te + debug_rva + 0x10
|
filename = self.base_te + debug_rva + 0x10
|
||||||
filename = struct.unpack("200s", self.ec.getMemoryService().read(filename, 200, 32))[0]
|
filename = struct.unpack("400s", self.ec.getMemoryService().read(filename, 400, 32))[0]
|
||||||
return filename[0:string.find(filename,'\0')]
|
return filename[0:string.find(filename,'\0')]
|
||||||
|
|
||||||
def get_debug_elfbase(self):
|
def get_debug_elfbase(self):
|
||||||
@@ -119,7 +119,7 @@ class EfiSectionPE32:
|
|||||||
filename = self.base_pe32 + debug_rva + 0xc
|
filename = self.base_pe32 + debug_rva + 0xc
|
||||||
else:
|
else:
|
||||||
filename = self.base_pe32 + debug_rva + 0x10
|
filename = self.base_pe32 + debug_rva + 0x10
|
||||||
filename = struct.unpack("200s", self.ec.getMemoryService().read(str(filename), 200, 32))[0]
|
filename = struct.unpack("400s", self.ec.getMemoryService().read(str(filename), 400, 32))[0]
|
||||||
return filename[0:string.find(filename,'\0')]
|
return filename[0:string.find(filename,'\0')]
|
||||||
|
|
||||||
def get_debug_elfbase(self):
|
def get_debug_elfbase(self):
|
||||||
@@ -154,7 +154,7 @@ class EfiSectionPE64:
|
|||||||
filename = self.base_pe64 + debug_rva + 0xc
|
filename = self.base_pe64 + debug_rva + 0xc
|
||||||
else:
|
else:
|
||||||
filename = self.base_pe64 + debug_rva + 0x10
|
filename = self.base_pe64 + debug_rva + 0x10
|
||||||
filename = struct.unpack("200s", self.ec.getMemoryService().read(str(filename), 200, 32))[0]
|
filename = struct.unpack("400s", self.ec.getMemoryService().read(str(filename), 400, 32))[0]
|
||||||
return filename[0:string.find(filename,'\0')]
|
return filename[0:string.find(filename,'\0')]
|
||||||
|
|
||||||
def get_debug_elfbase(self):
|
def get_debug_elfbase(self):
|
||||||
|
@@ -1,328 +1,328 @@
|
|||||||
#!/usr/bin/python
|
#!/usr/bin/python
|
||||||
|
|
||||||
#
|
#
|
||||||
# Copyright (c) 2014, ARM Limited. All rights reserved.
|
# Copyright (c) 2014, ARM Limited. All rights reserved.
|
||||||
#
|
#
|
||||||
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
#
|
#
|
||||||
|
|
||||||
import getopt
|
import getopt
|
||||||
import operator
|
import operator
|
||||||
import os
|
import os
|
||||||
import pickle
|
import pickle
|
||||||
import sys
|
import sys
|
||||||
from sys import argv
|
from sys import argv
|
||||||
from cStringIO import StringIO
|
from cStringIO import StringIO
|
||||||
|
|
||||||
modules = {}
|
modules = {}
|
||||||
functions = {}
|
functions = {}
|
||||||
functions_addr = {}
|
functions_addr = {}
|
||||||
|
|
||||||
def usage():
|
def usage():
|
||||||
print "-t,--trace: Location of the Trace file"
|
print "-t,--trace: Location of the Trace file"
|
||||||
print "-s,--symbols: Location of the symbols and modules"
|
print "-s,--symbols: Location of the symbols and modules"
|
||||||
|
|
||||||
def get_address_from_string(address):
|
def get_address_from_string(address):
|
||||||
return int(address.strip("S:").strip("N:").strip("EL2:").strip("EL1:"), 16)
|
return int(address.strip("S:").strip("N:").strip("EL2:").strip("EL1:"), 16)
|
||||||
|
|
||||||
def get_module_from_addr(modules, addr):
|
def get_module_from_addr(modules, addr):
|
||||||
for key,value in modules.items():
|
for key,value in modules.items():
|
||||||
if (value['start'] <= addr) and (addr <= value['end']):
|
if (value['start'] <= addr) and (addr <= value['end']):
|
||||||
return key
|
return key
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def add_cycles_to_function(functions, func_name, addr, cycles):
|
def add_cycles_to_function(functions, func_name, addr, cycles):
|
||||||
if func_name != "<Unknown>":
|
if func_name != "<Unknown>":
|
||||||
# Check if we are still in the previous function
|
# Check if we are still in the previous function
|
||||||
if add_cycles_to_function.prev_func_name == func_name:
|
if add_cycles_to_function.prev_func_name == func_name:
|
||||||
add_cycles_to_function.prev_entry['cycles'] += cycles
|
add_cycles_to_function.prev_entry['cycles'] += cycles
|
||||||
return (add_cycles_to_function.prev_func_name, add_cycles_to_function.prev_module_name)
|
return (add_cycles_to_function.prev_func_name, add_cycles_to_function.prev_module_name)
|
||||||
|
|
||||||
if func_name in functions.keys():
|
if func_name in functions.keys():
|
||||||
for module_name, module_value in functions[func_name].iteritems():
|
for module_name, module_value in functions[func_name].iteritems():
|
||||||
if (module_value['start'] <= addr) and (addr < module_value['end']):
|
if (module_value['start'] <= addr) and (addr < module_value['end']):
|
||||||
module_value['cycles'] += cycles
|
module_value['cycles'] += cycles
|
||||||
|
|
||||||
add_cycles_to_function.prev_func_name = func_name
|
add_cycles_to_function.prev_func_name = func_name
|
||||||
add_cycles_to_function.prev_module_name = module_name
|
add_cycles_to_function.prev_module_name = module_name
|
||||||
add_cycles_to_function.prev_entry = module_value
|
add_cycles_to_function.prev_entry = module_value
|
||||||
return (func_name, module_name)
|
return (func_name, module_name)
|
||||||
elif (module_value['end'] == 0):
|
elif (module_value['end'] == 0):
|
||||||
module_value['cycles'] += cycles
|
module_value['cycles'] += cycles
|
||||||
|
|
||||||
add_cycles_to_function.prev_func_name = func_name
|
add_cycles_to_function.prev_func_name = func_name
|
||||||
add_cycles_to_function.prev_module_name = module_name
|
add_cycles_to_function.prev_module_name = module_name
|
||||||
add_cycles_to_function.prev_entry = module_value
|
add_cycles_to_function.prev_entry = module_value
|
||||||
return (func_name, module_name)
|
return (func_name, module_name)
|
||||||
|
|
||||||
# Workaround to fix the 'info func' limitation that does not expose the 'static' function
|
# Workaround to fix the 'info func' limitation that does not expose the 'static' function
|
||||||
module_name = get_module_from_addr(modules, addr)
|
module_name = get_module_from_addr(modules, addr)
|
||||||
functions[func_name] = {}
|
functions[func_name] = {}
|
||||||
functions[func_name][module_name] = {}
|
functions[func_name][module_name] = {}
|
||||||
functions[func_name][module_name]['start'] = 0
|
functions[func_name][module_name]['start'] = 0
|
||||||
functions[func_name][module_name]['end'] = 0
|
functions[func_name][module_name]['end'] = 0
|
||||||
functions[func_name][module_name]['cycles'] = cycles
|
functions[func_name][module_name]['cycles'] = cycles
|
||||||
functions[func_name][module_name]['count'] = 0
|
functions[func_name][module_name]['count'] = 0
|
||||||
|
|
||||||
add_cycles_to_function.prev_func_name = func_name
|
add_cycles_to_function.prev_func_name = func_name
|
||||||
add_cycles_to_function.prev_module_name = module_name
|
add_cycles_to_function.prev_module_name = module_name
|
||||||
add_cycles_to_function.prev_entry = functions[func_name][module_name]
|
add_cycles_to_function.prev_entry = functions[func_name][module_name]
|
||||||
return (func_name, module_name)
|
return (func_name, module_name)
|
||||||
else:
|
else:
|
||||||
# Check if we are still in the previous function
|
# Check if we are still in the previous function
|
||||||
if (add_cycles_to_function.prev_entry is not None) and (add_cycles_to_function.prev_entry['start'] <= addr) and (addr < add_cycles_to_function.prev_entry['end']):
|
if (add_cycles_to_function.prev_entry is not None) and (add_cycles_to_function.prev_entry['start'] <= addr) and (addr < add_cycles_to_function.prev_entry['end']):
|
||||||
add_cycles_to_function.prev_entry['cycles'] += cycles
|
add_cycles_to_function.prev_entry['cycles'] += cycles
|
||||||
return (add_cycles_to_function.prev_func_name, add_cycles_to_function.prev_module_name)
|
return (add_cycles_to_function.prev_func_name, add_cycles_to_function.prev_module_name)
|
||||||
|
|
||||||
# Generate the key for the given address
|
# Generate the key for the given address
|
||||||
key = addr & ~0x0FFF
|
key = addr & ~0x0FFF
|
||||||
|
|
||||||
if key not in functions_addr.keys():
|
if key not in functions_addr.keys():
|
||||||
if 'Unknown' not in functions.keys():
|
if 'Unknown' not in functions.keys():
|
||||||
functions['Unknown'] = {}
|
functions['Unknown'] = {}
|
||||||
if 'Unknown' not in functions['Unknown'].keys():
|
if 'Unknown' not in functions['Unknown'].keys():
|
||||||
functions['Unknown']['Unknown'] = {}
|
functions['Unknown']['Unknown'] = {}
|
||||||
functions['Unknown']['Unknown']['cycles'] = 0
|
functions['Unknown']['Unknown']['cycles'] = 0
|
||||||
functions['Unknown']['Unknown']['count'] = 0
|
functions['Unknown']['Unknown']['count'] = 0
|
||||||
functions['Unknown']['Unknown']['cycles'] += cycles
|
functions['Unknown']['Unknown']['cycles'] += cycles
|
||||||
|
|
||||||
add_cycles_to_function.prev_func_name = None
|
add_cycles_to_function.prev_func_name = None
|
||||||
return None
|
return None
|
||||||
|
|
||||||
for func_key, module in functions_addr[key].iteritems():
|
for func_key, module in functions_addr[key].iteritems():
|
||||||
for module_key, module_value in module.iteritems():
|
for module_key, module_value in module.iteritems():
|
||||||
if (module_value['start'] <= addr) and (addr < module_value['end']):
|
if (module_value['start'] <= addr) and (addr < module_value['end']):
|
||||||
module_value['cycles'] += cycles
|
module_value['cycles'] += cycles
|
||||||
|
|
||||||
# In case o <Unknown> we prefer to fallback on the direct search
|
# In case o <Unknown> we prefer to fallback on the direct search
|
||||||
add_cycles_to_function.prev_func_name = func_key
|
add_cycles_to_function.prev_func_name = func_key
|
||||||
add_cycles_to_function.prev_module_name = module_key
|
add_cycles_to_function.prev_module_name = module_key
|
||||||
add_cycles_to_function.prev_entry = module_value
|
add_cycles_to_function.prev_entry = module_value
|
||||||
return (func_key, module_key)
|
return (func_key, module_key)
|
||||||
|
|
||||||
print "Warning: Function %s @ 0x%x not found" % (func_name, addr)
|
print "Warning: Function %s @ 0x%x not found" % (func_name, addr)
|
||||||
|
|
||||||
add_cycles_to_function.prev_func_name = None
|
add_cycles_to_function.prev_func_name = None
|
||||||
return None
|
return None
|
||||||
|
|
||||||
# Static variables for the previous function
|
# Static variables for the previous function
|
||||||
add_cycles_to_function.prev_func_name = None
|
add_cycles_to_function.prev_func_name = None
|
||||||
add_cycles_to_function.prev_entry = None
|
add_cycles_to_function.prev_entry = None
|
||||||
|
|
||||||
def trace_read():
|
def trace_read():
|
||||||
global trace_process
|
global trace_process
|
||||||
line = trace.readline()
|
line = trace.readline()
|
||||||
trace_process += len(line)
|
trace_process += len(line)
|
||||||
return line
|
return line
|
||||||
|
|
||||||
#
|
#
|
||||||
# Parse arguments
|
# Parse arguments
|
||||||
#
|
#
|
||||||
trace_name = None
|
trace_name = None
|
||||||
symbols_file = None
|
symbols_file = None
|
||||||
|
|
||||||
opts,args = getopt.getopt(sys.argv[1:], "ht:vs:v", ["help","trace=","symbols="])
|
opts,args = getopt.getopt(sys.argv[1:], "ht:vs:v", ["help","trace=","symbols="])
|
||||||
if (opts is None) or (not opts):
|
if (opts is None) or (not opts):
|
||||||
usage()
|
usage()
|
||||||
sys.exit()
|
sys.exit()
|
||||||
|
|
||||||
for o,a in opts:
|
for o,a in opts:
|
||||||
if o in ("-h","--help"):
|
if o in ("-h","--help"):
|
||||||
usage()
|
usage()
|
||||||
sys.exit()
|
sys.exit()
|
||||||
elif o in ("-t","--trace"):
|
elif o in ("-t","--trace"):
|
||||||
trace_name = a
|
trace_name = a
|
||||||
elif o in ("-s","--symbols"):
|
elif o in ("-s","--symbols"):
|
||||||
symbols_file = a
|
symbols_file = a
|
||||||
else:
|
else:
|
||||||
assert False, "Unhandled option (%s)" % o
|
assert False, "Unhandled option (%s)" % o
|
||||||
|
|
||||||
#
|
#
|
||||||
# We try first to see if we run the script from DS-5
|
# We try first to see if we run the script from DS-5
|
||||||
#
|
#
|
||||||
try:
|
try:
|
||||||
from arm_ds.debugger_v1 import Debugger
|
from arm_ds.debugger_v1 import Debugger
|
||||||
from arm_ds.debugger_v1 import DebugException
|
from arm_ds.debugger_v1 import DebugException
|
||||||
|
|
||||||
# Debugger object for accessing the debugger
|
# Debugger object for accessing the debugger
|
||||||
debugger = Debugger()
|
debugger = Debugger()
|
||||||
|
|
||||||
# Initialisation commands
|
# Initialisation commands
|
||||||
ec = debugger.getExecutionContext(0)
|
ec = debugger.getExecutionContext(0)
|
||||||
ec.getExecutionService().stop()
|
ec.getExecutionService().stop()
|
||||||
ec.getExecutionService().waitForStop()
|
ec.getExecutionService().waitForStop()
|
||||||
# in case the execution context reference is out of date
|
# in case the execution context reference is out of date
|
||||||
ec = debugger.getExecutionContext(0)
|
ec = debugger.getExecutionContext(0)
|
||||||
|
|
||||||
#
|
#
|
||||||
# Get the module name and their memory range
|
# Get the module name and their memory range
|
||||||
#
|
#
|
||||||
info_file = ec.executeDSCommand("info file")
|
info_file = ec.executeDSCommand("info file")
|
||||||
info_file_str = StringIO(info_file)
|
info_file_str = StringIO(info_file)
|
||||||
|
|
||||||
line = info_file_str.readline().strip('\n')
|
line = info_file_str.readline().strip('\n')
|
||||||
while line != '':
|
while line != '':
|
||||||
if ("Symbols from" in line):
|
if ("Symbols from" in line):
|
||||||
# Get the module name from the line 'Symbols from "/home/...."'
|
# Get the module name from the line 'Symbols from "/home/...."'
|
||||||
module_name = line.split("\"")[1].split("/")[-1]
|
module_name = line.split("\"")[1].split("/")[-1]
|
||||||
modules[module_name] = {}
|
modules[module_name] = {}
|
||||||
|
|
||||||
# Look for the text section
|
# Look for the text section
|
||||||
line = info_file_str.readline().strip('\n')
|
line = info_file_str.readline().strip('\n')
|
||||||
while (line != '') and ("Symbols from" not in line):
|
while (line != '') and ("Symbols from" not in line):
|
||||||
if ("ER_RO" in line):
|
if ("ER_RO" in line):
|
||||||
modules[module_name]['start'] = get_address_from_string(line.split()[0])
|
modules[module_name]['start'] = get_address_from_string(line.split()[0])
|
||||||
modules[module_name]['end'] = get_address_from_string(line.split()[2])
|
modules[module_name]['end'] = get_address_from_string(line.split()[2])
|
||||||
line = info_file_str.readline().strip('\n')
|
line = info_file_str.readline().strip('\n')
|
||||||
break;
|
break;
|
||||||
if (".text" in line):
|
if (".text" in line):
|
||||||
modules[module_name]['start'] = get_address_from_string(line.split()[0])
|
modules[module_name]['start'] = get_address_from_string(line.split()[0])
|
||||||
modules[module_name]['end'] = get_address_from_string(line.split()[2])
|
modules[module_name]['end'] = get_address_from_string(line.split()[2])
|
||||||
line = info_file_str.readline().strip('\n')
|
line = info_file_str.readline().strip('\n')
|
||||||
break;
|
break;
|
||||||
line = info_file_str.readline().strip('\n')
|
line = info_file_str.readline().strip('\n')
|
||||||
line = info_file_str.readline().strip('\n')
|
line = info_file_str.readline().strip('\n')
|
||||||
|
|
||||||
#
|
#
|
||||||
# Get the function name and their memory range
|
# Get the function name and their memory range
|
||||||
#
|
#
|
||||||
info_func = ec.executeDSCommand("info func")
|
info_func = ec.executeDSCommand("info func")
|
||||||
info_func_str = StringIO(info_func)
|
info_func_str = StringIO(info_func)
|
||||||
|
|
||||||
# Skip the first line 'Low-level symbols ...'
|
# Skip the first line 'Low-level symbols ...'
|
||||||
line = info_func_str.readline().strip('\n')
|
line = info_func_str.readline().strip('\n')
|
||||||
func_prev = None
|
func_prev = None
|
||||||
while line != '':
|
while line != '':
|
||||||
# We ignore all the functions after 'Functions in'
|
# We ignore all the functions after 'Functions in'
|
||||||
if ("Functions in " in line):
|
if ("Functions in " in line):
|
||||||
line = info_func_str.readline().strip('\n')
|
line = info_func_str.readline().strip('\n')
|
||||||
while line != '':
|
while line != '':
|
||||||
line = info_func_str.readline().strip('\n')
|
line = info_func_str.readline().strip('\n')
|
||||||
line = info_func_str.readline().strip('\n')
|
line = info_func_str.readline().strip('\n')
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if ("Low-level symbols" in line):
|
if ("Low-level symbols" in line):
|
||||||
# We need to fixup the last function of the module
|
# We need to fixup the last function of the module
|
||||||
if func_prev is not None:
|
if func_prev is not None:
|
||||||
func_prev['end'] = modules[module_name]['end']
|
func_prev['end'] = modules[module_name]['end']
|
||||||
func_prev = None
|
func_prev = None
|
||||||
|
|
||||||
line = info_func_str.readline().strip('\n')
|
line = info_func_str.readline().strip('\n')
|
||||||
continue
|
continue
|
||||||
|
|
||||||
func_name = line.split()[1]
|
func_name = line.split()[1]
|
||||||
func_start = get_address_from_string(line.split()[0])
|
func_start = get_address_from_string(line.split()[0])
|
||||||
module_name = get_module_from_addr(modules, func_start)
|
module_name = get_module_from_addr(modules, func_start)
|
||||||
|
|
||||||
if func_name not in functions.keys():
|
if func_name not in functions.keys():
|
||||||
functions[func_name] = {}
|
functions[func_name] = {}
|
||||||
functions[func_name][module_name] = {}
|
functions[func_name][module_name] = {}
|
||||||
functions[func_name][module_name]['start'] = func_start
|
functions[func_name][module_name]['start'] = func_start
|
||||||
functions[func_name][module_name]['cycles'] = 0
|
functions[func_name][module_name]['cycles'] = 0
|
||||||
functions[func_name][module_name]['count'] = 0
|
functions[func_name][module_name]['count'] = 0
|
||||||
|
|
||||||
# Set the end address of the previous function
|
# Set the end address of the previous function
|
||||||
if func_prev is not None:
|
if func_prev is not None:
|
||||||
func_prev['end'] = func_start
|
func_prev['end'] = func_start
|
||||||
func_prev = functions[func_name][module_name]
|
func_prev = functions[func_name][module_name]
|
||||||
|
|
||||||
line = info_func_str.readline().strip('\n')
|
line = info_func_str.readline().strip('\n')
|
||||||
|
|
||||||
# Fixup the last function
|
# Fixup the last function
|
||||||
func_prev['end'] = modules[module_name]['end']
|
func_prev['end'] = modules[module_name]['end']
|
||||||
|
|
||||||
if symbols_file is not None:
|
if symbols_file is not None:
|
||||||
pickle.dump((modules, functions), open(symbols_file, "w"))
|
pickle.dump((modules, functions), open(symbols_file, "w"))
|
||||||
except:
|
except:
|
||||||
if symbols_file is None:
|
if symbols_file is None:
|
||||||
print "Error: Symbols file is required when run out of ARM DS-5"
|
print "Error: Symbols file is required when run out of ARM DS-5"
|
||||||
sys.exit()
|
sys.exit()
|
||||||
|
|
||||||
(modules, functions) = pickle.load(open(symbols_file, "r"))
|
(modules, functions) = pickle.load(open(symbols_file, "r"))
|
||||||
|
|
||||||
#
|
#
|
||||||
# Build optimized table for the <Unknown> functions
|
# Build optimized table for the <Unknown> functions
|
||||||
#
|
#
|
||||||
functions_addr = {}
|
functions_addr = {}
|
||||||
for func_key, module in functions.iteritems():
|
for func_key, module in functions.iteritems():
|
||||||
for module_key, module_value in module.iteritems():
|
for module_key, module_value in module.iteritems():
|
||||||
key = module_value['start'] & ~0x0FFF
|
key = module_value['start'] & ~0x0FFF
|
||||||
if key not in functions_addr.keys():
|
if key not in functions_addr.keys():
|
||||||
functions_addr[key] = {}
|
functions_addr[key] = {}
|
||||||
if func_key not in functions_addr[key].keys():
|
if func_key not in functions_addr[key].keys():
|
||||||
functions_addr[key][func_key] = {}
|
functions_addr[key][func_key] = {}
|
||||||
functions_addr[key][func_key][module_key] = module_value
|
functions_addr[key][func_key][module_key] = module_value
|
||||||
|
|
||||||
#
|
#
|
||||||
# Process the trace file
|
# Process the trace file
|
||||||
#
|
#
|
||||||
if trace_name is None:
|
if trace_name is None:
|
||||||
sys.exit()
|
sys.exit()
|
||||||
|
|
||||||
trace = open(trace_name, "r")
|
trace = open(trace_name, "r")
|
||||||
trace_size = os.path.getsize(trace_name)
|
trace_size = os.path.getsize(trace_name)
|
||||||
trace_process = 0
|
trace_process = 0
|
||||||
|
|
||||||
# Get the column names from the first line
|
# Get the column names from the first line
|
||||||
columns = trace_read().split()
|
columns = trace_read().split()
|
||||||
column_addr = columns.index('Address')
|
column_addr = columns.index('Address')
|
||||||
column_cycles = columns.index('Cycles')
|
column_cycles = columns.index('Cycles')
|
||||||
column_function = columns.index('Function')
|
column_function = columns.index('Function')
|
||||||
|
|
||||||
line = trace_read()
|
line = trace_read()
|
||||||
i = 0
|
i = 0
|
||||||
prev_callee = None
|
prev_callee = None
|
||||||
while line:
|
while line:
|
||||||
try:
|
try:
|
||||||
func_name = line.split('\t')[column_function].strip()
|
func_name = line.split('\t')[column_function].strip()
|
||||||
address = get_address_from_string(line.split('\t')[column_addr])
|
address = get_address_from_string(line.split('\t')[column_addr])
|
||||||
cycles = int(line.split('\t')[column_cycles])
|
cycles = int(line.split('\t')[column_cycles])
|
||||||
callee = add_cycles_to_function(functions, func_name, address, cycles)
|
callee = add_cycles_to_function(functions, func_name, address, cycles)
|
||||||
if (prev_callee != None) and (prev_callee != callee):
|
if (prev_callee != None) and (prev_callee != callee):
|
||||||
functions[prev_callee[0]][prev_callee[1]]['count'] += 1
|
functions[prev_callee[0]][prev_callee[1]]['count'] += 1
|
||||||
prev_callee = callee
|
prev_callee = callee
|
||||||
except ValueError:
|
except ValueError:
|
||||||
pass
|
pass
|
||||||
line = trace_read()
|
line = trace_read()
|
||||||
if ((i % 1000000) == 0) and (i != 0):
|
if ((i % 1000000) == 0) and (i != 0):
|
||||||
percent = (trace_process * 100.00) / trace_size
|
percent = (trace_process * 100.00) / trace_size
|
||||||
print "Processing file ... (%.2f %%)" % (percent)
|
print "Processing file ... (%.2f %%)" % (percent)
|
||||||
i = i + 1
|
i = i + 1
|
||||||
|
|
||||||
# Fixup the last callee
|
# Fixup the last callee
|
||||||
functions[prev_callee[0]][prev_callee[1]]['count'] += 1
|
functions[prev_callee[0]][prev_callee[1]]['count'] += 1
|
||||||
|
|
||||||
#
|
#
|
||||||
# Process results
|
# Process results
|
||||||
#
|
#
|
||||||
functions_cycles = {}
|
functions_cycles = {}
|
||||||
all_functions_cycles = {}
|
all_functions_cycles = {}
|
||||||
total_cycles = 0
|
total_cycles = 0
|
||||||
|
|
||||||
for func_key, module in functions.iteritems():
|
for func_key, module in functions.iteritems():
|
||||||
for module_key, module_value in module.iteritems():
|
for module_key, module_value in module.iteritems():
|
||||||
key = "%s/%s" % (module_key, func_key)
|
key = "%s/%s" % (module_key, func_key)
|
||||||
functions_cycles[key] = (module_value['cycles'], module_value['count'])
|
functions_cycles[key] = (module_value['cycles'], module_value['count'])
|
||||||
total_cycles += module_value['cycles']
|
total_cycles += module_value['cycles']
|
||||||
|
|
||||||
if func_key not in all_functions_cycles.keys():
|
if func_key not in all_functions_cycles.keys():
|
||||||
all_functions_cycles[func_key] = (module_value['cycles'], module_value['count'])
|
all_functions_cycles[func_key] = (module_value['cycles'], module_value['count'])
|
||||||
else:
|
else:
|
||||||
all_functions_cycles[func_key] = tuple(map(sum, zip(all_functions_cycles[func_key], (module_value['cycles'], module_value['count']))))
|
all_functions_cycles[func_key] = tuple(map(sum, zip(all_functions_cycles[func_key], (module_value['cycles'], module_value['count']))))
|
||||||
|
|
||||||
sorted_functions_cycles = sorted(functions_cycles.iteritems(), key=operator.itemgetter(1), reverse = True)
|
sorted_functions_cycles = sorted(functions_cycles.iteritems(), key=operator.itemgetter(1), reverse = True)
|
||||||
sorted_all_functions_cycles = sorted(all_functions_cycles.items(), key=operator.itemgetter(1), reverse = True)
|
sorted_all_functions_cycles = sorted(all_functions_cycles.items(), key=operator.itemgetter(1), reverse = True)
|
||||||
|
|
||||||
print
|
print
|
||||||
print "----"
|
print "----"
|
||||||
for (key,value) in sorted_functions_cycles[:20]:
|
for (key,value) in sorted_functions_cycles[:20]:
|
||||||
if value[0] != 0:
|
if value[0] != 0:
|
||||||
print "%s (cycles: %d - %d%%, count: %d)" % (key, value[0], (value[0] * 100) / total_cycles, value[1])
|
print "%s (cycles: %d - %d%%, count: %d)" % (key, value[0], (value[0] * 100) / total_cycles, value[1])
|
||||||
else:
|
else:
|
||||||
break;
|
break;
|
||||||
print "----"
|
print "----"
|
||||||
for (key,value) in sorted_all_functions_cycles[:20]:
|
for (key,value) in sorted_all_functions_cycles[:20]:
|
||||||
if value[0] != 0:
|
if value[0] != 0:
|
||||||
print "%s (cycles: %d - %d%%, count: %d)" % (key, value[0], (value[0] * 100) / total_cycles, value[1])
|
print "%s (cycles: %d - %d%%, count: %d)" % (key, value[0], (value[0] * 100) / total_cycles, value[1])
|
||||||
else:
|
else:
|
||||||
break;
|
break;
|
||||||
|
@@ -165,13 +165,11 @@
|
|||||||
# Secure Boot dependencies
|
# Secure Boot dependencies
|
||||||
#
|
#
|
||||||
!if $(SECURE_BOOT_ENABLE) == TRUE
|
!if $(SECURE_BOOT_ENABLE) == TRUE
|
||||||
TpmMeasurementLib|SecurityPkg/Library/DxeTpmMeasurementLib/DxeTpmMeasurementLib.inf
|
|
||||||
AuthVariableLib|SecurityPkg/Library/AuthVariableLib/AuthVariableLib.inf
|
AuthVariableLib|SecurityPkg/Library/AuthVariableLib/AuthVariableLib.inf
|
||||||
|
|
||||||
# re-use the UserPhysicalPresent() dummy implementation from the ovmf tree
|
# re-use the UserPhysicalPresent() dummy implementation from the ovmf tree
|
||||||
PlatformSecureLib|OvmfPkg/Library/PlatformSecureLib/PlatformSecureLib.inf
|
PlatformSecureLib|OvmfPkg/Library/PlatformSecureLib/PlatformSecureLib.inf
|
||||||
!else
|
!else
|
||||||
TpmMeasurementLib|MdeModulePkg/Library/TpmMeasurementLibNull/TpmMeasurementLibNull.inf
|
|
||||||
AuthVariableLib|MdeModulePkg/Library/AuthVariableLibNull/AuthVariableLibNull.inf
|
AuthVariableLib|MdeModulePkg/Library/AuthVariableLibNull/AuthVariableLibNull.inf
|
||||||
!endif
|
!endif
|
||||||
VarCheckLib|MdeModulePkg/Library/VarCheckLib/VarCheckLib.inf
|
VarCheckLib|MdeModulePkg/Library/VarCheckLib/VarCheckLib.inf
|
||||||
@@ -379,6 +377,10 @@
|
|||||||
<PcdsFixedAtBuild>
|
<PcdsFixedAtBuild>
|
||||||
gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
|
gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
|
||||||
}
|
}
|
||||||
|
OvmfPkg/LinuxInitrdDynamicShellCommand/LinuxInitrdDynamicShellCommand.inf {
|
||||||
|
<PcdsFixedAtBuild>
|
||||||
|
gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
|
||||||
|
}
|
||||||
ShellPkg/Application/Shell/Shell.inf {
|
ShellPkg/Application/Shell/Shell.inf {
|
||||||
<LibraryClasses>
|
<LibraryClasses>
|
||||||
ShellCommandLib|ShellPkg/Library/UefiShellCommandLib/UefiShellCommandLib.inf
|
ShellCommandLib|ShellPkg/Library/UefiShellCommandLib/UefiShellCommandLib.inf
|
||||||
|
103
ArmVirtPkg/ArmVirtPkg.ci.yaml
Normal file
103
ArmVirtPkg/ArmVirtPkg.ci.yaml
Normal file
@@ -0,0 +1,103 @@
|
|||||||
|
## @file
|
||||||
|
# Core CI configuration for ArmVirtPkg
|
||||||
|
#
|
||||||
|
# ArmVirtPkg is part of Platform Ci for builds so this is only
|
||||||
|
# used for code analysis.
|
||||||
|
#
|
||||||
|
# Copyright (c) Microsoft Corporation
|
||||||
|
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
|
##
|
||||||
|
{
|
||||||
|
## options defined .pytool/Plugin/CompilerPlugin
|
||||||
|
"CompilerPlugin": {
|
||||||
|
"DscPath": "" # Don't support this test
|
||||||
|
},
|
||||||
|
|
||||||
|
## options defined .pytool/Plugin/HostUnitTestCompilerPlugin
|
||||||
|
"HostUnitTestCompilerPlugin": {
|
||||||
|
"DscPath": "" # Don't support this test
|
||||||
|
},
|
||||||
|
|
||||||
|
## options defined .pytool/Plugin/CharEncodingCheck
|
||||||
|
"CharEncodingCheck": {
|
||||||
|
"IgnoreFiles": []
|
||||||
|
},
|
||||||
|
|
||||||
|
## options defined .pytool/Plugin/DependencyCheck
|
||||||
|
"DependencyCheck": {
|
||||||
|
"AcceptableDependencies": [
|
||||||
|
"MdePkg/MdePkg.dec",
|
||||||
|
"MdeModulePkg/MdeModulePkg.dec",
|
||||||
|
"ArmVirtPkg/ArmVirtPkg.dec",
|
||||||
|
"NetworkPkg/NetworkPkg.dec",
|
||||||
|
"ArmPkg/ArmPkg.dec",
|
||||||
|
"OvmfPkg/OvmfPkg.dec",
|
||||||
|
"EmbeddedPkg/EmbeddedPkg.dec",
|
||||||
|
"ArmPlatformPkg/ArmPlatformPkg.dec",
|
||||||
|
"SecurityPkg/SecurityPkg.dec",
|
||||||
|
"ShellPkg/ShellPkg.dec" #Is this ok?
|
||||||
|
],
|
||||||
|
# For host based unit tests
|
||||||
|
"AcceptableDependencies-HOST_APPLICATION":[
|
||||||
|
"UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec"
|
||||||
|
],
|
||||||
|
# For UEFI shell based apps
|
||||||
|
"AcceptableDependencies-UEFI_APPLICATION":[
|
||||||
|
|
||||||
|
],
|
||||||
|
"IgnoreInf": []
|
||||||
|
},
|
||||||
|
|
||||||
|
## options defined .pytool/Plugin/DscCompleteCheck
|
||||||
|
"DscCompleteCheck": {
|
||||||
|
"IgnoreInf": [""],
|
||||||
|
"DscPath": "" # Don't support this test
|
||||||
|
},
|
||||||
|
|
||||||
|
## options defined .pytool/Plugin/HostUnitTestDscCompleteCheck
|
||||||
|
"HostUnitTestDscCompleteCheck": {
|
||||||
|
"IgnoreInf": [""],
|
||||||
|
"DscPath": "" # Don't support this test
|
||||||
|
},
|
||||||
|
|
||||||
|
## options defined .pytool/Plugin/GuidCheck
|
||||||
|
"GuidCheck": {
|
||||||
|
"IgnoreGuidName": [],
|
||||||
|
"IgnoreGuidValue": [],
|
||||||
|
"IgnoreFoldersAndFiles": [],
|
||||||
|
"IgnoreDuplicates": [],
|
||||||
|
},
|
||||||
|
|
||||||
|
## options defined .pytool/Plugin/LibraryClassCheck
|
||||||
|
"LibraryClassCheck": {
|
||||||
|
"IgnoreHeaderFile": []
|
||||||
|
},
|
||||||
|
|
||||||
|
## options defined .pytool/Plugin/SpellCheck
|
||||||
|
"SpellCheck": {
|
||||||
|
"AuditOnly": False, # Fails right now with over 270 errors
|
||||||
|
"IgnoreFiles": [], # use gitignore syntax to ignore errors in matching files
|
||||||
|
"ExtendWords": [
|
||||||
|
"setjump",
|
||||||
|
"plong",
|
||||||
|
"lparam",
|
||||||
|
"lpdword",
|
||||||
|
"lpthread",
|
||||||
|
"lresult",
|
||||||
|
"bootable",
|
||||||
|
"bsymbolic",
|
||||||
|
"endiannness",
|
||||||
|
"fvmain",
|
||||||
|
"multiboot",
|
||||||
|
"qemu's",
|
||||||
|
"ramdisk",
|
||||||
|
"ramfb",
|
||||||
|
"unbootable",
|
||||||
|
"virt's",
|
||||||
|
"werror",
|
||||||
|
"xenio"
|
||||||
|
], # words to extend to the dictionary for this package
|
||||||
|
"IgnoreStandardPaths": [], # Standard Plugin defined paths that should be ignore
|
||||||
|
"AdditionalIncludePaths": [] # Additional paths to spell check (wildcards supported)
|
||||||
|
}
|
||||||
|
}
|
@@ -36,6 +36,12 @@
|
|||||||
[Protocols]
|
[Protocols]
|
||||||
gFdtClientProtocolGuid = { 0xE11FACA0, 0x4710, 0x4C8E, { 0xA7, 0xA2, 0x01, 0xBA, 0xA2, 0x59, 0x1B, 0x4C } }
|
gFdtClientProtocolGuid = { 0xE11FACA0, 0x4710, 0x4C8E, { 0xA7, 0xA2, 0x01, 0xBA, 0xA2, 0x59, 0x1B, 0x4C } }
|
||||||
|
|
||||||
|
[PcdsFeatureFlag]
|
||||||
|
#
|
||||||
|
# Feature Flag PCD that defines whether TPM2 support is enabled
|
||||||
|
#
|
||||||
|
gArmVirtTokenSpaceGuid.PcdTpm2SupportEnabled|FALSE|BOOLEAN|0x00000004
|
||||||
|
|
||||||
[PcdsFixedAtBuild, PcdsPatchableInModule]
|
[PcdsFixedAtBuild, PcdsPatchableInModule]
|
||||||
#
|
#
|
||||||
# This is the physical address where the device tree is expected to be stored
|
# This is the physical address where the device tree is expected to be stored
|
||||||
|
@@ -29,6 +29,8 @@
|
|||||||
#
|
#
|
||||||
DEFINE TTY_TERMINAL = FALSE
|
DEFINE TTY_TERMINAL = FALSE
|
||||||
DEFINE SECURE_BOOT_ENABLE = FALSE
|
DEFINE SECURE_BOOT_ENABLE = FALSE
|
||||||
|
DEFINE TPM2_ENABLE = FALSE
|
||||||
|
DEFINE TPM2_CONFIG_ENABLE = FALSE
|
||||||
|
|
||||||
#
|
#
|
||||||
# Network definition
|
# Network definition
|
||||||
@@ -56,6 +58,8 @@
|
|||||||
VirtioMmioDeviceLib|OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDeviceLib.inf
|
VirtioMmioDeviceLib|OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDeviceLib.inf
|
||||||
QemuFwCfgLib|ArmVirtPkg/Library/QemuFwCfgLib/QemuFwCfgLib.inf
|
QemuFwCfgLib|ArmVirtPkg/Library/QemuFwCfgLib/QemuFwCfgLib.inf
|
||||||
QemuFwCfgS3Lib|OvmfPkg/Library/QemuFwCfgS3Lib/BaseQemuFwCfgS3LibNull.inf
|
QemuFwCfgS3Lib|OvmfPkg/Library/QemuFwCfgS3Lib/BaseQemuFwCfgS3LibNull.inf
|
||||||
|
QemuFwCfgSimpleParserLib|OvmfPkg/Library/QemuFwCfgSimpleParserLib/QemuFwCfgSimpleParserLib.inf
|
||||||
|
QemuLoadImageLib|OvmfPkg/Library/GenericQemuLoadImageLib/GenericQemuLoadImageLib.inf
|
||||||
|
|
||||||
ArmPlatformLib|ArmPlatformPkg/Library/ArmPlatformLibNull/ArmPlatformLibNull.inf
|
ArmPlatformLib|ArmPlatformPkg/Library/ArmPlatformLibNull/ArmPlatformLibNull.inf
|
||||||
|
|
||||||
@@ -74,12 +78,30 @@
|
|||||||
PciSegmentLib|MdePkg/Library/BasePciSegmentLibPci/BasePciSegmentLibPci.inf
|
PciSegmentLib|MdePkg/Library/BasePciSegmentLibPci/BasePciSegmentLibPci.inf
|
||||||
PciHostBridgeLib|ArmVirtPkg/Library/FdtPciHostBridgeLib/FdtPciHostBridgeLib.inf
|
PciHostBridgeLib|ArmVirtPkg/Library/FdtPciHostBridgeLib/FdtPciHostBridgeLib.inf
|
||||||
|
|
||||||
|
!if $(TPM2_ENABLE) == TRUE
|
||||||
|
Tpm2CommandLib|SecurityPkg/Library/Tpm2CommandLib/Tpm2CommandLib.inf
|
||||||
|
Tcg2PhysicalPresenceLib|OvmfPkg/Library/Tcg2PhysicalPresenceLibQemu/DxeTcg2PhysicalPresenceLib.inf
|
||||||
|
TpmMeasurementLib|SecurityPkg/Library/DxeTpmMeasurementLib/DxeTpmMeasurementLib.inf
|
||||||
|
!else
|
||||||
|
TpmMeasurementLib|MdeModulePkg/Library/TpmMeasurementLibNull/TpmMeasurementLibNull.inf
|
||||||
|
!endif
|
||||||
|
|
||||||
[LibraryClasses.common.PEIM]
|
[LibraryClasses.common.PEIM]
|
||||||
ArmVirtMemInfoLib|ArmVirtPkg/Library/QemuVirtMemInfoLib/QemuVirtMemInfoPeiLib.inf
|
ArmVirtMemInfoLib|ArmVirtPkg/Library/QemuVirtMemInfoLib/QemuVirtMemInfoPeiLib.inf
|
||||||
|
|
||||||
|
!if $(TPM2_ENABLE) == TRUE
|
||||||
|
BaseCryptLib|CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf
|
||||||
|
ResetSystemLib|MdeModulePkg/Library/PeiResetSystemLib/PeiResetSystemLib.inf
|
||||||
|
Tpm2DeviceLib|SecurityPkg/Library/Tpm2DeviceLibDTpm/Tpm2DeviceLibDTpm.inf
|
||||||
|
!endif
|
||||||
|
|
||||||
[LibraryClasses.common.DXE_DRIVER]
|
[LibraryClasses.common.DXE_DRIVER]
|
||||||
ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf
|
ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf
|
||||||
|
|
||||||
|
!if $(TPM2_ENABLE) == TRUE
|
||||||
|
Tpm2DeviceLib|SecurityPkg/Library/Tpm2DeviceLibTcg2/Tpm2DeviceLibTcg2.inf
|
||||||
|
!endif
|
||||||
|
|
||||||
[LibraryClasses.common.UEFI_DRIVER]
|
[LibraryClasses.common.UEFI_DRIVER]
|
||||||
UefiScsiLib|MdePkg/Library/UefiScsiLib/UefiScsiLib.inf
|
UefiScsiLib|MdePkg/Library/UefiScsiLib/UefiScsiLib.inf
|
||||||
|
|
||||||
@@ -100,6 +122,8 @@
|
|||||||
|
|
||||||
gEfiMdeModulePkgTokenSpaceGuid.PcdTurnOffUsbLegacySupport|TRUE
|
gEfiMdeModulePkgTokenSpaceGuid.PcdTurnOffUsbLegacySupport|TRUE
|
||||||
|
|
||||||
|
gArmVirtTokenSpaceGuid.PcdTpm2SupportEnabled|$(TPM2_ENABLE)
|
||||||
|
|
||||||
[PcdsFixedAtBuild.common]
|
[PcdsFixedAtBuild.common]
|
||||||
!if $(ARCH) == AARCH64
|
!if $(ARCH) == AARCH64
|
||||||
gArmTokenSpaceGuid.PcdVFPEnabled|1
|
gArmTokenSpaceGuid.PcdVFPEnabled|1
|
||||||
@@ -186,10 +210,6 @@
|
|||||||
# point only, for entry point versions >= 3.0.
|
# point only, for entry point versions >= 3.0.
|
||||||
gEfiMdeModulePkgTokenSpaceGuid.PcdSmbiosEntryPointProvideMethod|0x2
|
gEfiMdeModulePkgTokenSpaceGuid.PcdSmbiosEntryPointProvideMethod|0x2
|
||||||
|
|
||||||
# ACPI predates the AARCH64 architecture by 5 versions, so
|
|
||||||
# we only target OSes that support ACPI v5.0 or later
|
|
||||||
gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiExposedTableVersions|0x20
|
|
||||||
|
|
||||||
[PcdsDynamicDefault.common]
|
[PcdsDynamicDefault.common]
|
||||||
gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut|3
|
gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut|3
|
||||||
|
|
||||||
@@ -237,9 +257,29 @@
|
|||||||
gEfiMdeModulePkgTokenSpaceGuid.PcdSmbiosDocRev|0x0
|
gEfiMdeModulePkgTokenSpaceGuid.PcdSmbiosDocRev|0x0
|
||||||
gUefiOvmfPkgTokenSpaceGuid.PcdQemuSmbiosValidated|FALSE
|
gUefiOvmfPkgTokenSpaceGuid.PcdQemuSmbiosValidated|FALSE
|
||||||
|
|
||||||
|
#
|
||||||
|
# IPv4 and IPv6 PXE Boot support.
|
||||||
|
#
|
||||||
|
gEfiNetworkPkgTokenSpaceGuid.PcdIPv4PXESupport|0x01
|
||||||
|
gEfiNetworkPkgTokenSpaceGuid.PcdIPv6PXESupport|0x01
|
||||||
|
|
||||||
|
#
|
||||||
|
# TPM2 support
|
||||||
|
#
|
||||||
|
gEfiSecurityPkgTokenSpaceGuid.PcdTpmBaseAddress|0x0
|
||||||
|
!if $(TPM2_ENABLE) == TRUE
|
||||||
|
gEfiSecurityPkgTokenSpaceGuid.PcdTpmInstanceGuid|{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
|
||||||
|
gEfiSecurityPkgTokenSpaceGuid.PcdTpm2HashMask|0
|
||||||
|
!endif
|
||||||
|
|
||||||
[PcdsDynamicHii]
|
[PcdsDynamicHii]
|
||||||
gArmVirtTokenSpaceGuid.PcdForceNoAcpi|L"ForceNoAcpi"|gArmVirtVariableGuid|0x0|FALSE|NV,BS
|
gArmVirtTokenSpaceGuid.PcdForceNoAcpi|L"ForceNoAcpi"|gArmVirtVariableGuid|0x0|FALSE|NV,BS
|
||||||
|
|
||||||
|
!if $(TPM2_CONFIG_ENABLE) == TRUE
|
||||||
|
gEfiSecurityPkgTokenSpaceGuid.PcdTcgPhysicalPresenceInterfaceVer|L"TCG2_VERSION"|gTcg2ConfigFormSetGuid|0x0|"1.3"|NV,BS
|
||||||
|
gEfiSecurityPkgTokenSpaceGuid.PcdTpm2AcpiTableRev|L"TCG2_VERSION"|gTcg2ConfigFormSetGuid|0x8|3|NV,BS
|
||||||
|
!endif
|
||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
#
|
#
|
||||||
# Components Section - list of all EDK II Modules needed by this Platform
|
# Components Section - list of all EDK II Modules needed by this Platform
|
||||||
@@ -261,6 +301,23 @@
|
|||||||
|
|
||||||
MdeModulePkg/Universal/Variable/Pei/VariablePei.inf
|
MdeModulePkg/Universal/Variable/Pei/VariablePei.inf
|
||||||
|
|
||||||
|
!if $(TPM2_ENABLE) == TRUE
|
||||||
|
MdeModulePkg/Universal/ResetSystemPei/ResetSystemPei.inf {
|
||||||
|
<LibraryClasses>
|
||||||
|
ResetSystemLib|ArmVirtPkg/Library/ArmVirtPsciResetSystemPeiLib/ArmVirtPsciResetSystemPeiLib.inf
|
||||||
|
}
|
||||||
|
OvmfPkg/Tcg/Tcg2Config/Tcg2ConfigPei.inf
|
||||||
|
SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.inf {
|
||||||
|
<LibraryClasses>
|
||||||
|
HashLib|SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterPei.inf
|
||||||
|
NULL|SecurityPkg/Library/HashInstanceLibSha1/HashInstanceLibSha1.inf
|
||||||
|
NULL|SecurityPkg/Library/HashInstanceLibSha256/HashInstanceLibSha256.inf
|
||||||
|
NULL|SecurityPkg/Library/HashInstanceLibSha384/HashInstanceLibSha384.inf
|
||||||
|
NULL|SecurityPkg/Library/HashInstanceLibSha512/HashInstanceLibSha512.inf
|
||||||
|
NULL|SecurityPkg/Library/HashInstanceLibSm3/HashInstanceLibSm3.inf
|
||||||
|
}
|
||||||
|
!endif
|
||||||
|
|
||||||
MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf {
|
MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf {
|
||||||
<LibraryClasses>
|
<LibraryClasses>
|
||||||
NULL|MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf
|
NULL|MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf
|
||||||
@@ -295,6 +352,9 @@
|
|||||||
MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf {
|
MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf {
|
||||||
<LibraryClasses>
|
<LibraryClasses>
|
||||||
NULL|SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.inf
|
NULL|SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.inf
|
||||||
|
!if $(TPM2_ENABLE) == TRUE
|
||||||
|
NULL|SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLib.inf
|
||||||
|
!endif
|
||||||
}
|
}
|
||||||
SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf
|
SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf
|
||||||
OvmfPkg/EnrollDefaultKeys/EnrollDefaultKeys.inf
|
OvmfPkg/EnrollDefaultKeys/EnrollDefaultKeys.inf
|
||||||
@@ -371,11 +431,18 @@
|
|||||||
NULL|MdeModulePkg/Library/BootManagerUiLib/BootManagerUiLib.inf
|
NULL|MdeModulePkg/Library/BootManagerUiLib/BootManagerUiLib.inf
|
||||||
NULL|MdeModulePkg/Library/BootMaintenanceManagerUiLib/BootMaintenanceManagerUiLib.inf
|
NULL|MdeModulePkg/Library/BootMaintenanceManagerUiLib/BootMaintenanceManagerUiLib.inf
|
||||||
}
|
}
|
||||||
|
OvmfPkg/QemuKernelLoaderFsDxe/QemuKernelLoaderFsDxe.inf
|
||||||
|
|
||||||
#
|
#
|
||||||
# Networking stack
|
# Networking stack
|
||||||
#
|
#
|
||||||
!include NetworkPkg/NetworkComponents.dsc.inc
|
!include NetworkPkg/NetworkComponents.dsc.inc
|
||||||
|
|
||||||
|
NetworkPkg/UefiPxeBcDxe/UefiPxeBcDxe.inf {
|
||||||
|
<LibraryClasses>
|
||||||
|
NULL|OvmfPkg/Library/PxeBcPcdProducerLib/PxeBcPcdProducerLib.inf
|
||||||
|
}
|
||||||
|
|
||||||
!if $(NETWORK_TLS_ENABLE) == TRUE
|
!if $(NETWORK_TLS_ENABLE) == TRUE
|
||||||
NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.inf {
|
NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.inf {
|
||||||
<LibraryClasses>
|
<LibraryClasses>
|
||||||
@@ -389,6 +456,11 @@
|
|||||||
MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBusDxe.inf
|
MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBusDxe.inf
|
||||||
MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDiskDxe.inf
|
MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDiskDxe.inf
|
||||||
|
|
||||||
|
#
|
||||||
|
# NVME Driver
|
||||||
|
#
|
||||||
|
MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressDxe.inf
|
||||||
|
|
||||||
#
|
#
|
||||||
# SMBIOS Support
|
# SMBIOS Support
|
||||||
#
|
#
|
||||||
@@ -430,6 +502,26 @@
|
|||||||
MdeModulePkg/Bus/Usb/UsbKbDxe/UsbKbDxe.inf
|
MdeModulePkg/Bus/Usb/UsbKbDxe/UsbKbDxe.inf
|
||||||
MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassStorageDxe.inf
|
MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassStorageDxe.inf
|
||||||
|
|
||||||
|
#
|
||||||
|
# TPM2 support
|
||||||
|
#
|
||||||
|
!if $(TPM2_ENABLE) == TRUE
|
||||||
|
SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.inf {
|
||||||
|
<LibraryClasses>
|
||||||
|
HashLib|SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterDxe.inf
|
||||||
|
Tpm2DeviceLib|SecurityPkg/Library/Tpm2DeviceLibRouter/Tpm2DeviceLibRouterDxe.inf
|
||||||
|
NULL|SecurityPkg/Library/Tpm2DeviceLibDTpm/Tpm2InstanceLibDTpm.inf
|
||||||
|
NULL|SecurityPkg/Library/HashInstanceLibSha1/HashInstanceLibSha1.inf
|
||||||
|
NULL|SecurityPkg/Library/HashInstanceLibSha256/HashInstanceLibSha256.inf
|
||||||
|
NULL|SecurityPkg/Library/HashInstanceLibSha384/HashInstanceLibSha384.inf
|
||||||
|
NULL|SecurityPkg/Library/HashInstanceLibSha512/HashInstanceLibSha512.inf
|
||||||
|
NULL|SecurityPkg/Library/HashInstanceLibSm3/HashInstanceLibSm3.inf
|
||||||
|
}
|
||||||
|
!if $(TPM2_CONFIG_ENABLE) == TRUE
|
||||||
|
SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigDxe.inf
|
||||||
|
!endif
|
||||||
|
!endif
|
||||||
|
|
||||||
#
|
#
|
||||||
# ACPI Support
|
# ACPI Support
|
||||||
#
|
#
|
||||||
|
@@ -113,6 +113,12 @@ READ_LOCK_STATUS = TRUE
|
|||||||
INF MdeModulePkg/Universal/Variable/Pei/VariablePei.inf
|
INF MdeModulePkg/Universal/Variable/Pei/VariablePei.inf
|
||||||
INF MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf
|
INF MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf
|
||||||
|
|
||||||
|
!if $(TPM2_ENABLE) == TRUE
|
||||||
|
INF MdeModulePkg/Universal/ResetSystemPei/ResetSystemPei.inf
|
||||||
|
INF OvmfPkg/Tcg/Tcg2Config/Tcg2ConfigPei.inf
|
||||||
|
INF SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.inf
|
||||||
|
!endif
|
||||||
|
|
||||||
FILE FV_IMAGE = 9E21FD93-9C72-4c15-8C4B-E77F1DB2D792 {
|
FILE FV_IMAGE = 9E21FD93-9C72-4c15-8C4B-E77F1DB2D792 {
|
||||||
SECTION GUIDED EE4E5898-3914-4259-9D6E-DC7BD79403CF PROCESSING_REQUIRED = TRUE {
|
SECTION GUIDED EE4E5898-3914-4259-9D6E-DC7BD79403CF PROCESSING_REQUIRED = TRUE {
|
||||||
SECTION FV_IMAGE = FVMAIN
|
SECTION FV_IMAGE = FVMAIN
|
||||||
|
@@ -103,6 +103,7 @@ READ_LOCK_STATUS = TRUE
|
|||||||
#
|
#
|
||||||
INF ShellPkg/Application/Shell/Shell.inf
|
INF ShellPkg/Application/Shell/Shell.inf
|
||||||
INF ShellPkg/DynamicCommand/TftpDynamicCommand/TftpDynamicCommand.inf
|
INF ShellPkg/DynamicCommand/TftpDynamicCommand/TftpDynamicCommand.inf
|
||||||
|
INF OvmfPkg/LinuxInitrdDynamicShellCommand/LinuxInitrdDynamicShellCommand.inf
|
||||||
|
|
||||||
#
|
#
|
||||||
# Bds
|
# Bds
|
||||||
@@ -113,6 +114,7 @@ READ_LOCK_STATUS = TRUE
|
|||||||
INF MdeModulePkg/Universal/DriverHealthManagerDxe/DriverHealthManagerDxe.inf
|
INF MdeModulePkg/Universal/DriverHealthManagerDxe/DriverHealthManagerDxe.inf
|
||||||
INF MdeModulePkg/Universal/BdsDxe/BdsDxe.inf
|
INF MdeModulePkg/Universal/BdsDxe/BdsDxe.inf
|
||||||
INF MdeModulePkg/Application/UiApp/UiApp.inf
|
INF MdeModulePkg/Application/UiApp/UiApp.inf
|
||||||
|
INF OvmfPkg/QemuKernelLoaderFsDxe/QemuKernelLoaderFsDxe.inf
|
||||||
|
|
||||||
#
|
#
|
||||||
# Networking stack
|
# Networking stack
|
||||||
@@ -126,6 +128,11 @@ READ_LOCK_STATUS = TRUE
|
|||||||
INF MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBusDxe.inf
|
INF MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBusDxe.inf
|
||||||
INF MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDiskDxe.inf
|
INF MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDiskDxe.inf
|
||||||
|
|
||||||
|
#
|
||||||
|
# NVME Driver
|
||||||
|
#
|
||||||
|
INF MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressDxe.inf
|
||||||
|
|
||||||
#
|
#
|
||||||
# SMBIOS Support
|
# SMBIOS Support
|
||||||
#
|
#
|
||||||
@@ -173,6 +180,16 @@ READ_LOCK_STATUS = TRUE
|
|||||||
INF MdeModulePkg/Bus/Usb/UsbKbDxe/UsbKbDxe.inf
|
INF MdeModulePkg/Bus/Usb/UsbKbDxe/UsbKbDxe.inf
|
||||||
INF MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassStorageDxe.inf
|
INF MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassStorageDxe.inf
|
||||||
|
|
||||||
|
#
|
||||||
|
# TPM2 support
|
||||||
|
#
|
||||||
|
!if $(TPM2_ENABLE) == TRUE
|
||||||
|
INF SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.inf
|
||||||
|
!if $(TPM2_CONFIG_ENABLE) == TRUE
|
||||||
|
INF SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigDxe.inf
|
||||||
|
!endif
|
||||||
|
!endif
|
||||||
|
|
||||||
#
|
#
|
||||||
# TianoCore logo (splash screen)
|
# TianoCore logo (splash screen)
|
||||||
#
|
#
|
||||||
|
@@ -56,6 +56,8 @@
|
|||||||
VirtioMmioDeviceLib|OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDeviceLib.inf
|
VirtioMmioDeviceLib|OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDeviceLib.inf
|
||||||
QemuFwCfgLib|ArmVirtPkg/Library/QemuFwCfgLib/QemuFwCfgLib.inf
|
QemuFwCfgLib|ArmVirtPkg/Library/QemuFwCfgLib/QemuFwCfgLib.inf
|
||||||
QemuFwCfgS3Lib|OvmfPkg/Library/QemuFwCfgS3Lib/BaseQemuFwCfgS3LibNull.inf
|
QemuFwCfgS3Lib|OvmfPkg/Library/QemuFwCfgS3Lib/BaseQemuFwCfgS3LibNull.inf
|
||||||
|
QemuFwCfgSimpleParserLib|OvmfPkg/Library/QemuFwCfgSimpleParserLib/QemuFwCfgSimpleParserLib.inf
|
||||||
|
QemuLoadImageLib|OvmfPkg/Library/GenericQemuLoadImageLib/GenericQemuLoadImageLib.inf
|
||||||
|
|
||||||
ArmVirtMemInfoLib|ArmVirtPkg/Library/QemuVirtMemInfoLib/QemuVirtMemInfoLib.inf
|
ArmVirtMemInfoLib|ArmVirtPkg/Library/QemuVirtMemInfoLib/QemuVirtMemInfoLib.inf
|
||||||
|
|
||||||
@@ -73,6 +75,7 @@
|
|||||||
PciPcdProducerLib|ArmVirtPkg/Library/FdtPciPcdProducerLib/FdtPciPcdProducerLib.inf
|
PciPcdProducerLib|ArmVirtPkg/Library/FdtPciPcdProducerLib/FdtPciPcdProducerLib.inf
|
||||||
PciSegmentLib|MdePkg/Library/BasePciSegmentLibPci/BasePciSegmentLibPci.inf
|
PciSegmentLib|MdePkg/Library/BasePciSegmentLibPci/BasePciSegmentLibPci.inf
|
||||||
PciHostBridgeLib|ArmVirtPkg/Library/FdtPciHostBridgeLib/FdtPciHostBridgeLib.inf
|
PciHostBridgeLib|ArmVirtPkg/Library/FdtPciHostBridgeLib/FdtPciHostBridgeLib.inf
|
||||||
|
TpmMeasurementLib|MdeModulePkg/Library/TpmMeasurementLibNull/TpmMeasurementLibNull.inf
|
||||||
|
|
||||||
[LibraryClasses.common.DXE_DRIVER]
|
[LibraryClasses.common.DXE_DRIVER]
|
||||||
ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf
|
ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf
|
||||||
@@ -172,6 +175,12 @@
|
|||||||
gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask|3
|
gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask|3
|
||||||
|
|
||||||
[PcdsPatchableInModule.common]
|
[PcdsPatchableInModule.common]
|
||||||
|
# we need to provide a resolution for this PCD that supports PcdSet64()
|
||||||
|
# being called from ArmVirtPkg/Library/PlatformPeiLib/PlatformPeiLib.c,
|
||||||
|
# even though that call will be compiled out on this platform as it does
|
||||||
|
# not (and cannot) support the TPM2 driver stack
|
||||||
|
gEfiSecurityPkgTokenSpaceGuid.PcdTpmBaseAddress|0x0
|
||||||
|
|
||||||
#
|
#
|
||||||
# This will be overridden in the code
|
# This will be overridden in the code
|
||||||
#
|
#
|
||||||
@@ -231,6 +240,12 @@
|
|||||||
gEfiMdeModulePkgTokenSpaceGuid.PcdSmbiosDocRev|0x0
|
gEfiMdeModulePkgTokenSpaceGuid.PcdSmbiosDocRev|0x0
|
||||||
gUefiOvmfPkgTokenSpaceGuid.PcdQemuSmbiosValidated|FALSE
|
gUefiOvmfPkgTokenSpaceGuid.PcdQemuSmbiosValidated|FALSE
|
||||||
|
|
||||||
|
#
|
||||||
|
# IPv4 and IPv6 PXE Boot support.
|
||||||
|
#
|
||||||
|
gEfiNetworkPkgTokenSpaceGuid.PcdIPv4PXESupport|0x01
|
||||||
|
gEfiNetworkPkgTokenSpaceGuid.PcdIPv6PXESupport|0x01
|
||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
#
|
#
|
||||||
# Components Section - list of all EDK II Modules needed by this Platform
|
# Components Section - list of all EDK II Modules needed by this Platform
|
||||||
@@ -355,11 +370,18 @@
|
|||||||
NULL|MdeModulePkg/Library/BootManagerUiLib/BootManagerUiLib.inf
|
NULL|MdeModulePkg/Library/BootManagerUiLib/BootManagerUiLib.inf
|
||||||
NULL|MdeModulePkg/Library/BootMaintenanceManagerUiLib/BootMaintenanceManagerUiLib.inf
|
NULL|MdeModulePkg/Library/BootMaintenanceManagerUiLib/BootMaintenanceManagerUiLib.inf
|
||||||
}
|
}
|
||||||
|
OvmfPkg/QemuKernelLoaderFsDxe/QemuKernelLoaderFsDxe.inf
|
||||||
|
|
||||||
#
|
#
|
||||||
# Networking stack
|
# Networking stack
|
||||||
#
|
#
|
||||||
!include NetworkPkg/NetworkComponents.dsc.inc
|
!include NetworkPkg/NetworkComponents.dsc.inc
|
||||||
|
|
||||||
|
NetworkPkg/UefiPxeBcDxe/UefiPxeBcDxe.inf {
|
||||||
|
<LibraryClasses>
|
||||||
|
NULL|OvmfPkg/Library/PxeBcPcdProducerLib/PxeBcPcdProducerLib.inf
|
||||||
|
}
|
||||||
|
|
||||||
!if $(NETWORK_TLS_ENABLE) == TRUE
|
!if $(NETWORK_TLS_ENABLE) == TRUE
|
||||||
NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.inf {
|
NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.inf {
|
||||||
<LibraryClasses>
|
<LibraryClasses>
|
||||||
@@ -373,6 +395,11 @@
|
|||||||
MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBusDxe.inf
|
MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBusDxe.inf
|
||||||
MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDiskDxe.inf
|
MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDiskDxe.inf
|
||||||
|
|
||||||
|
#
|
||||||
|
# NVME Driver
|
||||||
|
#
|
||||||
|
MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressDxe.inf
|
||||||
|
|
||||||
#
|
#
|
||||||
# SMBIOS Support
|
# SMBIOS Support
|
||||||
#
|
#
|
||||||
|
@@ -47,6 +47,7 @@
|
|||||||
BootLogoLib|MdeModulePkg/Library/BootLogoLib/BootLogoLib.inf
|
BootLogoLib|MdeModulePkg/Library/BootLogoLib/BootLogoLib.inf
|
||||||
PlatformBootManagerLib|ArmPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
|
PlatformBootManagerLib|ArmPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
|
||||||
CustomizedDisplayLib|MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLib.inf
|
CustomizedDisplayLib|MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLib.inf
|
||||||
|
TpmMeasurementLib|MdeModulePkg/Library/TpmMeasurementLibNull/TpmMeasurementLibNull.inf
|
||||||
|
|
||||||
[LibraryClasses.common.UEFI_DRIVER]
|
[LibraryClasses.common.UEFI_DRIVER]
|
||||||
UefiScsiLib|MdePkg/Library/UefiScsiLib/UefiScsiLib.inf
|
UefiScsiLib|MdePkg/Library/UefiScsiLib/UefiScsiLib.inf
|
||||||
@@ -95,6 +96,12 @@
|
|||||||
gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvModeEnable|TRUE
|
gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvModeEnable|TRUE
|
||||||
|
|
||||||
[PcdsPatchableInModule.common]
|
[PcdsPatchableInModule.common]
|
||||||
|
# we need to provide a resolution for this PCD that supports PcdSet64()
|
||||||
|
# being called from ArmVirtPkg/Library/PlatformPeiLib/PlatformPeiLib.c,
|
||||||
|
# even though that call will be compiled out on this platform as it does
|
||||||
|
# not (and cannot) support the TPM2 driver stack
|
||||||
|
gEfiSecurityPkgTokenSpaceGuid.PcdTpmBaseAddress|0x0
|
||||||
|
|
||||||
#
|
#
|
||||||
# This will be overridden in the code
|
# This will be overridden in the code
|
||||||
#
|
#
|
||||||
|
@@ -182,6 +182,7 @@ READ_LOCK_STATUS = TRUE
|
|||||||
#
|
#
|
||||||
INF ShellPkg/Application/Shell/Shell.inf
|
INF ShellPkg/Application/Shell/Shell.inf
|
||||||
INF ShellPkg/DynamicCommand/TftpDynamicCommand/TftpDynamicCommand.inf
|
INF ShellPkg/DynamicCommand/TftpDynamicCommand/TftpDynamicCommand.inf
|
||||||
|
INF OvmfPkg/LinuxInitrdDynamicShellCommand/LinuxInitrdDynamicShellCommand.inf
|
||||||
|
|
||||||
#
|
#
|
||||||
# Bds
|
# Bds
|
||||||
|
@@ -1,22 +1,22 @@
|
|||||||
/** @file
|
/** @file
|
||||||
|
|
||||||
Copyright (c) 2018, Linaro Limited. All rights reserved.
|
Copyright (c) 2018, Linaro Limited. All rights reserved.
|
||||||
|
|
||||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
|
|
||||||
**/
|
**/
|
||||||
|
|
||||||
#ifndef __PLATFORM_HIDDEN_H
|
#ifndef __PLATFORM_HIDDEN_H
|
||||||
#define __PLATFORM_HIDDEN_H
|
#define __PLATFORM_HIDDEN_H
|
||||||
|
|
||||||
//
|
//
|
||||||
// Setting the GCC -fvisibility=hidden command line option is not quite the same
|
// Setting the GCC -fvisibility=hidden command line option is not quite the same
|
||||||
// as setting the pragma below: the former only affects definitions, whereas the
|
// as setting the pragma below: the former only affects definitions, whereas the
|
||||||
// pragma affects extern declarations as well. So if we want to ensure that no
|
// pragma affects extern declarations as well. So if we want to ensure that no
|
||||||
// GOT indirected symbol references are emitted, we need to use the pragma, or
|
// GOT indirected symbol references are emitted, we need to use the pragma, or
|
||||||
// GOT based cross object references could be emitted, e.g., in libraries, and
|
// GOT based cross object references could be emitted, e.g., in libraries, and
|
||||||
// these cannot be relaxed to ordinary symbol references at link time.
|
// these cannot be relaxed to ordinary symbol references at link time.
|
||||||
//
|
//
|
||||||
#pragma GCC visibility push (hidden)
|
#pragma GCC visibility push (hidden)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@@ -110,7 +110,12 @@ ArmVirtGicArchLibConstructor (
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 2:
|
case 2:
|
||||||
ASSERT (RegSize == 32);
|
//
|
||||||
|
// When the GICv2 is emulated with virtualization=on, it adds a virtual
|
||||||
|
// set of control registers. This means the register property can be
|
||||||
|
// either 32 or 64 bytes in size.
|
||||||
|
//
|
||||||
|
ASSERT ((RegSize == 32) || (RegSize == 64));
|
||||||
|
|
||||||
DistBase = SwapBytes64 (Reg[0]);
|
DistBase = SwapBytes64 (Reg[0]);
|
||||||
CpuBase = SwapBytes64 (Reg[2]);
|
CpuBase = SwapBytes64 (Reg[2]);
|
||||||
|
@@ -145,20 +145,6 @@ ResetShutdown (
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
This function causes the system to enter S3 and then wake up immediately.
|
|
||||||
|
|
||||||
If this function returns, it means that the system does not support S3 feature.
|
|
||||||
**/
|
|
||||||
VOID
|
|
||||||
EFIAPI
|
|
||||||
EnterS3WithImmediateWake (
|
|
||||||
VOID
|
|
||||||
)
|
|
||||||
{
|
|
||||||
// not implemented
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
This function causes a systemwide reset. The exact type of the reset is
|
This function causes a systemwide reset. The exact type of the reset is
|
||||||
defined by the EFI_GUID that follows the Null-terminated Unicode string passed
|
defined by the EFI_GUID that follows the Null-terminated Unicode string passed
|
||||||
|
@@ -0,0 +1,232 @@
|
|||||||
|
/** @file
|
||||||
|
Reset System lib using PSCI hypervisor or secure monitor calls
|
||||||
|
|
||||||
|
Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
|
||||||
|
Copyright (c) 2013, ARM Ltd. All rights reserved.<BR>
|
||||||
|
Copyright (c) 2014-2020, Linaro Ltd. All rights reserved.<BR>
|
||||||
|
Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
|
||||||
|
|
||||||
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
|
|
||||||
|
**/
|
||||||
|
|
||||||
|
#include <PiPei.h>
|
||||||
|
|
||||||
|
#include <libfdt.h>
|
||||||
|
#include <Library/ArmHvcLib.h>
|
||||||
|
#include <Library/ArmSmcLib.h>
|
||||||
|
#include <Library/BaseLib.h>
|
||||||
|
#include <Library/DebugLib.h>
|
||||||
|
#include <Library/HobLib.h>
|
||||||
|
#include <Library/ResetSystemLib.h>
|
||||||
|
|
||||||
|
#include <IndustryStandard/ArmStdSmc.h>
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
PsciMethodUnknown,
|
||||||
|
PsciMethodSmc,
|
||||||
|
PsciMethodHvc,
|
||||||
|
} PSCI_METHOD;
|
||||||
|
|
||||||
|
STATIC
|
||||||
|
PSCI_METHOD
|
||||||
|
DiscoverPsciMethod (
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
{
|
||||||
|
VOID *DeviceTreeBase;
|
||||||
|
INT32 Node, Prev;
|
||||||
|
INT32 Len;
|
||||||
|
CONST CHAR8 *Compatible;
|
||||||
|
CONST CHAR8 *CompatibleItem;
|
||||||
|
CONST VOID *Prop;
|
||||||
|
|
||||||
|
DeviceTreeBase = (VOID*)(UINTN)PcdGet64 (PcdDeviceTreeInitialBaseAddress);
|
||||||
|
ASSERT (fdt_check_header (DeviceTreeBase) == 0);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Enumerate all FDT nodes looking for the PSCI node and capture the method
|
||||||
|
//
|
||||||
|
for (Prev = 0;; Prev = Node) {
|
||||||
|
Node = fdt_next_node (DeviceTreeBase, Prev, NULL);
|
||||||
|
if (Node < 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
Compatible = fdt_getprop (DeviceTreeBase, Node, "compatible", &Len);
|
||||||
|
if (Compatible == NULL) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Iterate over the NULL-separated items in the compatible string
|
||||||
|
//
|
||||||
|
for (CompatibleItem = Compatible; CompatibleItem < Compatible + Len;
|
||||||
|
CompatibleItem += 1 + AsciiStrLen (CompatibleItem)) {
|
||||||
|
|
||||||
|
if (AsciiStrCmp (CompatibleItem, "arm,psci-0.2") != 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
Prop = fdt_getprop (DeviceTreeBase, Node, "method", NULL);
|
||||||
|
if (!Prop) {
|
||||||
|
DEBUG ((DEBUG_ERROR, "%a: Missing PSCI method property\n",
|
||||||
|
__FUNCTION__));
|
||||||
|
return PsciMethodUnknown;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (AsciiStrnCmp (Prop, "hvc", 3) == 0) {
|
||||||
|
return PsciMethodHvc;
|
||||||
|
} else if (AsciiStrnCmp (Prop, "smc", 3) == 0) {
|
||||||
|
return PsciMethodSmc;
|
||||||
|
} else {
|
||||||
|
DEBUG ((DEBUG_ERROR, "%a: Unknown PSCI method \"%a\"\n", __FUNCTION__,
|
||||||
|
Prop));
|
||||||
|
return PsciMethodUnknown;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return PsciMethodUnknown;
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC
|
||||||
|
VOID
|
||||||
|
PerformPsciAction (
|
||||||
|
IN UINTN Arg0
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ARM_SMC_ARGS ArmSmcArgs;
|
||||||
|
ARM_HVC_ARGS ArmHvcArgs;
|
||||||
|
|
||||||
|
ArmSmcArgs.Arg0 = Arg0;
|
||||||
|
ArmHvcArgs.Arg0 = Arg0;
|
||||||
|
|
||||||
|
switch (DiscoverPsciMethod ()) {
|
||||||
|
case PsciMethodHvc:
|
||||||
|
ArmCallHvc (&ArmHvcArgs);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PsciMethodSmc:
|
||||||
|
ArmCallSmc (&ArmSmcArgs);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
DEBUG ((DEBUG_ERROR, "%a: no PSCI method defined\n", __FUNCTION__));
|
||||||
|
ASSERT (FALSE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
This function causes a system-wide reset (cold reset), in which
|
||||||
|
all circuitry within the system returns to its initial state. This type of reset
|
||||||
|
is asynchronous to system operation and operates without regard to
|
||||||
|
cycle boundaries.
|
||||||
|
|
||||||
|
If this function returns, it means that the system does not support cold reset.
|
||||||
|
**/
|
||||||
|
VOID
|
||||||
|
EFIAPI
|
||||||
|
ResetCold (
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
{
|
||||||
|
// Send a PSCI 0.2 SYSTEM_RESET command
|
||||||
|
PerformPsciAction (ARM_SMC_ID_PSCI_SYSTEM_RESET);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
This function causes a system-wide initialization (warm reset), in which all processors
|
||||||
|
are set to their initial state. Pending cycles are not corrupted.
|
||||||
|
|
||||||
|
If this function returns, it means that the system does not support warm reset.
|
||||||
|
**/
|
||||||
|
VOID
|
||||||
|
EFIAPI
|
||||||
|
ResetWarm (
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
{
|
||||||
|
// Map a warm reset into a cold reset
|
||||||
|
ResetCold ();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
This function causes the system to enter a power state equivalent
|
||||||
|
to the ACPI G2/S5 or G3 states.
|
||||||
|
|
||||||
|
If this function returns, it means that the system does not support shutdown reset.
|
||||||
|
**/
|
||||||
|
VOID
|
||||||
|
EFIAPI
|
||||||
|
ResetShutdown (
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
{
|
||||||
|
// Send a PSCI 0.2 SYSTEM_OFF command
|
||||||
|
PerformPsciAction (ARM_SMC_ID_PSCI_SYSTEM_OFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
This function causes a systemwide reset. The exact type of the reset is
|
||||||
|
defined by the EFI_GUID that follows the Null-terminated Unicode string passed
|
||||||
|
into ResetData. If the platform does not recognize the EFI_GUID in ResetData
|
||||||
|
the platform must pick a supported reset type to perform.The platform may
|
||||||
|
optionally log the parameters from any non-normal reset that occurs.
|
||||||
|
|
||||||
|
@param[in] DataSize The size, in bytes, of ResetData.
|
||||||
|
@param[in] ResetData The data buffer starts with a Null-terminated string,
|
||||||
|
followed by the EFI_GUID.
|
||||||
|
**/
|
||||||
|
VOID
|
||||||
|
EFIAPI
|
||||||
|
ResetPlatformSpecific (
|
||||||
|
IN UINTN DataSize,
|
||||||
|
IN VOID *ResetData
|
||||||
|
)
|
||||||
|
{
|
||||||
|
// Map the platform specific reset as reboot
|
||||||
|
ResetCold ();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
The ResetSystem function resets the entire platform.
|
||||||
|
|
||||||
|
@param[in] ResetType The type of reset to perform.
|
||||||
|
@param[in] ResetStatus The status code for the reset.
|
||||||
|
@param[in] DataSize The size, in bytes, of ResetData.
|
||||||
|
@param[in] ResetData For a ResetType of EfiResetCold, EfiResetWarm, or EfiResetShutdown
|
||||||
|
the data buffer starts with a Null-terminated string, optionally
|
||||||
|
followed by additional binary data. The string is a description
|
||||||
|
that the caller may use to further indicate the reason for the
|
||||||
|
system reset.
|
||||||
|
**/
|
||||||
|
VOID
|
||||||
|
EFIAPI
|
||||||
|
ResetSystem (
|
||||||
|
IN EFI_RESET_TYPE ResetType,
|
||||||
|
IN EFI_STATUS ResetStatus,
|
||||||
|
IN UINTN DataSize,
|
||||||
|
IN VOID *ResetData OPTIONAL
|
||||||
|
)
|
||||||
|
{
|
||||||
|
switch (ResetType) {
|
||||||
|
case EfiResetWarm:
|
||||||
|
ResetWarm ();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EfiResetCold:
|
||||||
|
ResetCold ();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EfiResetShutdown:
|
||||||
|
ResetShutdown ();
|
||||||
|
return;
|
||||||
|
|
||||||
|
case EfiResetPlatformSpecific:
|
||||||
|
ResetPlatformSpecific (DataSize, ResetData);
|
||||||
|
return;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,39 @@
|
|||||||
|
#/** @file
|
||||||
|
# Reset System lib using PSCI hypervisor or secure monitor calls
|
||||||
|
#
|
||||||
|
# Copyright (c) 2008, Apple Inc. All rights reserved.<BR>
|
||||||
|
# Copyright (c) 2014-2020, Linaro Ltd. All rights reserved.<BR>
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#**/
|
||||||
|
|
||||||
|
[Defines]
|
||||||
|
INF_VERSION = 1.27
|
||||||
|
BASE_NAME = ArmVirtPsciResetSystemPeiLib
|
||||||
|
FILE_GUID = 551cfb98-c185-41a3-86bf-8cdb7e2a530c
|
||||||
|
MODULE_TYPE = BASE
|
||||||
|
VERSION_STRING = 1.0
|
||||||
|
LIBRARY_CLASS = ResetSystemLib|PEIM
|
||||||
|
|
||||||
|
[Sources]
|
||||||
|
ArmVirtPsciResetSystemPeiLib.c
|
||||||
|
|
||||||
|
[Packages]
|
||||||
|
ArmPkg/ArmPkg.dec
|
||||||
|
ArmVirtPkg/ArmVirtPkg.dec
|
||||||
|
EmbeddedPkg/EmbeddedPkg.dec
|
||||||
|
MdeModulePkg/MdeModulePkg.dec
|
||||||
|
MdePkg/MdePkg.dec
|
||||||
|
|
||||||
|
[LibraryClasses]
|
||||||
|
ArmSmcLib
|
||||||
|
ArmHvcLib
|
||||||
|
BaseLib
|
||||||
|
DebugLib
|
||||||
|
FdtLib
|
||||||
|
HobLib
|
||||||
|
|
||||||
|
[Pcd]
|
||||||
|
gArmVirtTokenSpaceGuid.PcdDeviceTreeInitialBaseAddress
|
@@ -25,6 +25,7 @@
|
|||||||
#include <Protocol/PciRootBridgeIo.h>
|
#include <Protocol/PciRootBridgeIo.h>
|
||||||
#include <Protocol/VirtioDevice.h>
|
#include <Protocol/VirtioDevice.h>
|
||||||
#include <Guid/EventGroup.h>
|
#include <Guid/EventGroup.h>
|
||||||
|
#include <Guid/GlobalVariable.h>
|
||||||
#include <Guid/RootBridgesConnectedEventGroup.h>
|
#include <Guid/RootBridgesConnectedEventGroup.h>
|
||||||
#include <Guid/SerialPortLibVendor.h>
|
#include <Guid/SerialPortLibVendor.h>
|
||||||
|
|
||||||
@@ -686,7 +687,9 @@ PlatformBootManagerBeforeConsole (
|
|||||||
VOID
|
VOID
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
UINT16 FrontPageTimeout;
|
||||||
RETURN_STATUS PcdStatus;
|
RETURN_STATUS PcdStatus;
|
||||||
|
EFI_STATUS Status;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Signal EndOfDxe PI Event
|
// Signal EndOfDxe PI Event
|
||||||
@@ -744,9 +747,29 @@ PlatformBootManagerBeforeConsole (
|
|||||||
//
|
//
|
||||||
// Set the front page timeout from the QEMU configuration.
|
// Set the front page timeout from the QEMU configuration.
|
||||||
//
|
//
|
||||||
PcdStatus = PcdSet16S (PcdPlatformBootTimeOut,
|
FrontPageTimeout = GetFrontPageTimeoutFromQemu ();
|
||||||
GetFrontPageTimeoutFromQemu ());
|
PcdStatus = PcdSet16S (PcdPlatformBootTimeOut, FrontPageTimeout);
|
||||||
ASSERT_RETURN_ERROR (PcdStatus);
|
ASSERT_RETURN_ERROR (PcdStatus);
|
||||||
|
//
|
||||||
|
// Reflect the PCD in the standard Timeout variable.
|
||||||
|
//
|
||||||
|
Status = gRT->SetVariable (
|
||||||
|
EFI_TIME_OUT_VARIABLE_NAME,
|
||||||
|
&gEfiGlobalVariableGuid,
|
||||||
|
(EFI_VARIABLE_NON_VOLATILE |
|
||||||
|
EFI_VARIABLE_BOOTSERVICE_ACCESS |
|
||||||
|
EFI_VARIABLE_RUNTIME_ACCESS),
|
||||||
|
sizeof FrontPageTimeout,
|
||||||
|
&FrontPageTimeout
|
||||||
|
);
|
||||||
|
DEBUG ((
|
||||||
|
EFI_ERROR (Status) ? DEBUG_ERROR : DEBUG_VERBOSE,
|
||||||
|
"%a: SetVariable(%s, %u): %r\n",
|
||||||
|
__FUNCTION__,
|
||||||
|
EFI_TIME_OUT_VARIABLE_NAME,
|
||||||
|
FrontPageTimeout,
|
||||||
|
Status
|
||||||
|
));
|
||||||
|
|
||||||
//
|
//
|
||||||
// Register platform-specific boot options and keyboard shortcuts.
|
// Register platform-specific boot options and keyboard shortcuts.
|
||||||
|
@@ -44,9 +44,8 @@
|
|||||||
MemoryAllocationLib
|
MemoryAllocationLib
|
||||||
PcdLib
|
PcdLib
|
||||||
PlatformBmPrintScLib
|
PlatformBmPrintScLib
|
||||||
PrintLib
|
|
||||||
QemuBootOrderLib
|
QemuBootOrderLib
|
||||||
QemuFwCfgLib
|
QemuLoadImageLib
|
||||||
ReportStatusCodeLib
|
ReportStatusCodeLib
|
||||||
UefiBootManagerLib
|
UefiBootManagerLib
|
||||||
UefiBootServicesTableLib
|
UefiBootServicesTableLib
|
||||||
@@ -64,18 +63,13 @@
|
|||||||
gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut
|
gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut
|
||||||
|
|
||||||
[Guids]
|
[Guids]
|
||||||
gEfiFileInfoGuid
|
|
||||||
gEfiFileSystemInfoGuid
|
|
||||||
gEfiFileSystemVolumeLabelInfoIdGuid
|
|
||||||
gEfiEndOfDxeEventGroupGuid
|
gEfiEndOfDxeEventGroupGuid
|
||||||
|
gEfiGlobalVariableGuid
|
||||||
gRootBridgesConnectedEventGroupGuid
|
gRootBridgesConnectedEventGroupGuid
|
||||||
gUefiShellFileGuid
|
gUefiShellFileGuid
|
||||||
|
|
||||||
[Protocols]
|
[Protocols]
|
||||||
gEfiDevicePathProtocolGuid
|
|
||||||
gEfiFirmwareVolume2ProtocolGuid
|
gEfiFirmwareVolume2ProtocolGuid
|
||||||
gEfiGraphicsOutputProtocolGuid
|
gEfiGraphicsOutputProtocolGuid
|
||||||
gEfiLoadedImageProtocolGuid
|
|
||||||
gEfiPciRootBridgeIoProtocolGuid
|
gEfiPciRootBridgeIoProtocolGuid
|
||||||
gEfiSimpleFileSystemProtocolGuid
|
|
||||||
gVirtioDeviceProtocolGuid
|
gVirtioDeviceProtocolGuid
|
||||||
|
File diff suppressed because it is too large
Load Diff
@@ -1,7 +1,7 @@
|
|||||||
/** @file
|
/** @file
|
||||||
*
|
*
|
||||||
* Copyright (c) 2011-2014, ARM Limited. All rights reserved.
|
* Copyright (c) 2011-2014, ARM Limited. All rights reserved.
|
||||||
* Copyright (c) 2014, Linaro Limited. All rights reserved.
|
* Copyright (c) 2014-2020, Linaro Limited. All rights reserved.
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: BSD-2-Clause-Patent
|
* SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
*
|
*
|
||||||
@@ -13,11 +13,24 @@
|
|||||||
#include <Library/DebugLib.h>
|
#include <Library/DebugLib.h>
|
||||||
#include <Library/HobLib.h>
|
#include <Library/HobLib.h>
|
||||||
#include <Library/PcdLib.h>
|
#include <Library/PcdLib.h>
|
||||||
|
#include <Library/PeiServicesLib.h>
|
||||||
#include <libfdt.h>
|
#include <libfdt.h>
|
||||||
|
|
||||||
#include <Guid/EarlyPL011BaseAddress.h>
|
#include <Guid/EarlyPL011BaseAddress.h>
|
||||||
#include <Guid/FdtHob.h>
|
#include <Guid/FdtHob.h>
|
||||||
|
|
||||||
|
STATIC CONST EFI_PEI_PPI_DESCRIPTOR mTpm2DiscoveredPpi = {
|
||||||
|
EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
|
||||||
|
&gOvmfTpmDiscoveredPpiGuid,
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
STATIC CONST EFI_PEI_PPI_DESCRIPTOR mTpm2InitializationDonePpi = {
|
||||||
|
EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
|
||||||
|
&gPeiTpmInitializationDonePpiGuid,
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
EFIAPI
|
EFIAPI
|
||||||
PlatformPeim (
|
PlatformPeim (
|
||||||
@@ -31,14 +44,18 @@ PlatformPeim (
|
|||||||
UINT64 *FdtHobData;
|
UINT64 *FdtHobData;
|
||||||
UINT64 *UartHobData;
|
UINT64 *UartHobData;
|
||||||
INT32 Node, Prev;
|
INT32 Node, Prev;
|
||||||
|
INT32 Parent, Depth;
|
||||||
CONST CHAR8 *Compatible;
|
CONST CHAR8 *Compatible;
|
||||||
CONST CHAR8 *CompItem;
|
CONST CHAR8 *CompItem;
|
||||||
CONST CHAR8 *NodeStatus;
|
CONST CHAR8 *NodeStatus;
|
||||||
INT32 Len;
|
INT32 Len;
|
||||||
|
INT32 RangesLen;
|
||||||
INT32 StatusLen;
|
INT32 StatusLen;
|
||||||
CONST UINT64 *RegProp;
|
CONST UINT64 *RegProp;
|
||||||
|
CONST UINT32 *RangesProp;
|
||||||
UINT64 UartBase;
|
UINT64 UartBase;
|
||||||
|
UINT64 TpmBase;
|
||||||
|
EFI_STATUS Status;
|
||||||
|
|
||||||
Base = (VOID*)(UINTN)PcdGet64 (PcdDeviceTreeInitialBaseAddress);
|
Base = (VOID*)(UINTN)PcdGet64 (PcdDeviceTreeInitialBaseAddress);
|
||||||
ASSERT (Base != NULL);
|
ASSERT (Base != NULL);
|
||||||
@@ -58,18 +75,23 @@ PlatformPeim (
|
|||||||
ASSERT (UartHobData != NULL);
|
ASSERT (UartHobData != NULL);
|
||||||
*UartHobData = 0;
|
*UartHobData = 0;
|
||||||
|
|
||||||
|
TpmBase = 0;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Look for a UART node
|
// Set Parent to suppress incorrect compiler/analyzer warnings.
|
||||||
//
|
//
|
||||||
for (Prev = 0;; Prev = Node) {
|
Parent = 0;
|
||||||
Node = fdt_next_node (Base, Prev, NULL);
|
|
||||||
|
for (Prev = Depth = 0;; Prev = Node) {
|
||||||
|
Node = fdt_next_node (Base, Prev, &Depth);
|
||||||
if (Node < 0) {
|
if (Node < 0) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
if (Depth == 1) {
|
||||||
// Check for UART node
|
Parent = Node;
|
||||||
//
|
}
|
||||||
|
|
||||||
Compatible = fdt_getprop (Base, Node, "compatible", &Len);
|
Compatible = fdt_getprop (Base, Node, "compatible", &Len);
|
||||||
|
|
||||||
//
|
//
|
||||||
@@ -93,10 +115,74 @@ PlatformPeim (
|
|||||||
|
|
||||||
*UartHobData = UartBase;
|
*UartHobData = UartBase;
|
||||||
break;
|
break;
|
||||||
|
} else if (FeaturePcdGet (PcdTpm2SupportEnabled) &&
|
||||||
|
AsciiStrCmp (CompItem, "tcg,tpm-tis-mmio") == 0) {
|
||||||
|
|
||||||
|
RegProp = fdt_getprop (Base, Node, "reg", &Len);
|
||||||
|
ASSERT (Len == 8 || Len == 16);
|
||||||
|
if (Len == 8) {
|
||||||
|
TpmBase = fdt32_to_cpu (RegProp[0]);
|
||||||
|
} else if (Len == 16) {
|
||||||
|
TpmBase = fdt64_to_cpu (ReadUnaligned64 ((UINT64 *)RegProp));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Depth > 1) {
|
||||||
|
//
|
||||||
|
// QEMU/mach-virt may put the TPM on the platform bus, in which case
|
||||||
|
// we have to take its 'ranges' property into account to translate the
|
||||||
|
// MMIO address. This consists of a <child base, parent base, size>
|
||||||
|
// tuple, where the child base and the size use the same number of
|
||||||
|
// cells as the 'reg' property above, and the parent base uses 2 cells
|
||||||
|
//
|
||||||
|
RangesProp = fdt_getprop (Base, Parent, "ranges", &RangesLen);
|
||||||
|
ASSERT (RangesProp != NULL);
|
||||||
|
|
||||||
|
//
|
||||||
|
// a plain 'ranges' attribute without a value implies a 1:1 mapping
|
||||||
|
//
|
||||||
|
if (RangesLen != 0) {
|
||||||
|
//
|
||||||
|
// assume a single translated range with 2 cells for the parent base
|
||||||
|
//
|
||||||
|
if (RangesLen != Len + 2 * sizeof (UINT32)) {
|
||||||
|
DEBUG ((DEBUG_WARN,
|
||||||
|
"%a: 'ranges' property has unexpected size %d\n",
|
||||||
|
__FUNCTION__, RangesLen));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Len == 8) {
|
||||||
|
TpmBase -= fdt32_to_cpu (RangesProp[0]);
|
||||||
|
} else {
|
||||||
|
TpmBase -= fdt64_to_cpu (ReadUnaligned64 ((UINT64 *)RangesProp));
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// advance RangesProp to the parent bus address
|
||||||
|
//
|
||||||
|
RangesProp = (UINT32 *)((UINT8 *)RangesProp + Len / 2);
|
||||||
|
TpmBase += fdt64_to_cpu (ReadUnaligned64 ((UINT64 *)RangesProp));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (FeaturePcdGet (PcdTpm2SupportEnabled)) {
|
||||||
|
if (TpmBase != 0) {
|
||||||
|
DEBUG ((DEBUG_INFO, "%a: TPM @ 0x%lx\n", __FUNCTION__, TpmBase));
|
||||||
|
|
||||||
|
Status = (EFI_STATUS)PcdSet64S (PcdTpmBaseAddress, TpmBase);
|
||||||
|
ASSERT_EFI_ERROR (Status);
|
||||||
|
|
||||||
|
Status = PeiServicesInstallPpi (&mTpm2DiscoveredPpi);
|
||||||
|
} else {
|
||||||
|
Status = PeiServicesInstallPpi (&mTpm2InitializationDonePpi);
|
||||||
|
}
|
||||||
|
ASSERT_EFI_ERROR (Status);
|
||||||
|
}
|
||||||
|
|
||||||
BuildFvHob (PcdGet64 (PcdFvBaseAddress), PcdGet32 (PcdFvSize));
|
BuildFvHob (PcdGet64 (PcdFvBaseAddress), PcdGet32 (PcdFvSize));
|
||||||
|
|
||||||
return EFI_SUCCESS;
|
return EFI_SUCCESS;
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
#/** @file
|
#/** @file
|
||||||
#
|
#
|
||||||
# Copyright (c) 2011-2015, ARM Limited. All rights reserved.
|
# Copyright (c) 2011-2015, ARM Limited. All rights reserved.
|
||||||
# Copyright (c) 2014, Linaro Limited. All rights reserved.
|
# Copyright (c) 2014-2020, Linaro Limited. All rights reserved.
|
||||||
#
|
#
|
||||||
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
#
|
#
|
||||||
@@ -11,7 +11,7 @@
|
|||||||
INF_VERSION = 0x00010005
|
INF_VERSION = 0x00010005
|
||||||
BASE_NAME = PlatformPeiLib
|
BASE_NAME = PlatformPeiLib
|
||||||
FILE_GUID = 59C11815-F8DA-4F49-B4FB-EC1E41ED1F06
|
FILE_GUID = 59C11815-F8DA-4F49-B4FB-EC1E41ED1F06
|
||||||
MODULE_TYPE = SEC
|
MODULE_TYPE = BASE
|
||||||
VERSION_STRING = 1.0
|
VERSION_STRING = 1.0
|
||||||
LIBRARY_CLASS = PlatformPeiLib
|
LIBRARY_CLASS = PlatformPeiLib
|
||||||
|
|
||||||
@@ -21,14 +21,21 @@
|
|||||||
[Packages]
|
[Packages]
|
||||||
ArmPkg/ArmPkg.dec
|
ArmPkg/ArmPkg.dec
|
||||||
ArmVirtPkg/ArmVirtPkg.dec
|
ArmVirtPkg/ArmVirtPkg.dec
|
||||||
MdePkg/MdePkg.dec
|
|
||||||
MdeModulePkg/MdeModulePkg.dec
|
|
||||||
EmbeddedPkg/EmbeddedPkg.dec
|
EmbeddedPkg/EmbeddedPkg.dec
|
||||||
|
MdeModulePkg/MdeModulePkg.dec
|
||||||
|
MdePkg/MdePkg.dec
|
||||||
|
OvmfPkg/OvmfPkg.dec
|
||||||
|
SecurityPkg/SecurityPkg.dec
|
||||||
|
|
||||||
|
[FeaturePcd]
|
||||||
|
gArmVirtTokenSpaceGuid.PcdTpm2SupportEnabled
|
||||||
|
|
||||||
[LibraryClasses]
|
[LibraryClasses]
|
||||||
DebugLib
|
DebugLib
|
||||||
HobLib
|
HobLib
|
||||||
FdtLib
|
FdtLib
|
||||||
|
PcdLib
|
||||||
|
PeiServicesLib
|
||||||
|
|
||||||
[FixedPcd]
|
[FixedPcd]
|
||||||
gArmTokenSpaceGuid.PcdFvSize
|
gArmTokenSpaceGuid.PcdFvSize
|
||||||
@@ -37,6 +44,11 @@
|
|||||||
[Pcd]
|
[Pcd]
|
||||||
gArmTokenSpaceGuid.PcdFvBaseAddress
|
gArmTokenSpaceGuid.PcdFvBaseAddress
|
||||||
gArmVirtTokenSpaceGuid.PcdDeviceTreeInitialBaseAddress
|
gArmVirtTokenSpaceGuid.PcdDeviceTreeInitialBaseAddress
|
||||||
|
gEfiSecurityPkgTokenSpaceGuid.PcdTpmBaseAddress ## SOMETIMES_PRODUCES
|
||||||
|
|
||||||
|
[Ppis]
|
||||||
|
gOvmfTpmDiscoveredPpiGuid ## SOMETIMES_PRODUCES
|
||||||
|
gPeiTpmInitializationDonePpiGuid ## SOMETIMES_PRODUCES
|
||||||
|
|
||||||
[Guids]
|
[Guids]
|
||||||
gEarlyPL011BaseAddressGuid
|
gEarlyPL011BaseAddressGuid
|
||||||
|
@@ -15,7 +15,7 @@
|
|||||||
FILE_GUID = B271F41F-B841-48A9-BA8D-545B4BC2E2BF
|
FILE_GUID = B271F41F-B841-48A9-BA8D-545B4BC2E2BF
|
||||||
MODULE_TYPE = BASE
|
MODULE_TYPE = BASE
|
||||||
VERSION_STRING = 1.0
|
VERSION_STRING = 1.0
|
||||||
LIBRARY_CLASS = QemuFwCfgLib|DXE_DRIVER
|
LIBRARY_CLASS = QemuFwCfgLib|DXE_DRIVER UEFI_DRIVER
|
||||||
|
|
||||||
CONSTRUCTOR = QemuFwCfgInitialize
|
CONSTRUCTOR = QemuFwCfgInitialize
|
||||||
|
|
||||||
|
89
ArmVirtPkg/PlatformCI/.azurepipelines/Ubuntu-GCC5.yml
Normal file
89
ArmVirtPkg/PlatformCI/.azurepipelines/Ubuntu-GCC5.yml
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
## @file
|
||||||
|
# Azure Pipeline build file for building a platform.
|
||||||
|
#
|
||||||
|
# Platform: ArmVirtQemu
|
||||||
|
# OS: Ubuntu
|
||||||
|
# Toolchain: GCC5
|
||||||
|
#
|
||||||
|
# Copyright (c) Microsoft Corporation.
|
||||||
|
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
|
##
|
||||||
|
trigger:
|
||||||
|
- master
|
||||||
|
pr:
|
||||||
|
- master
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
- job: Platform_CI
|
||||||
|
variables:
|
||||||
|
package: 'ArmVirtPkg'
|
||||||
|
vm_image: 'ubuntu-latest'
|
||||||
|
should_run: true
|
||||||
|
run_flags: "MAKE_STARTUP_NSH=TRUE QEMU_HEADLESS=TRUE"
|
||||||
|
|
||||||
|
#Use matrix to speed up the build process
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
QEMU_AARCH64_DEBUG:
|
||||||
|
Build.File: "$(package)/PlatformCI/PlatformBuild.py"
|
||||||
|
Build.Arch: "AARCH64"
|
||||||
|
Build.Flags: ""
|
||||||
|
Build.Target: "DEBUG"
|
||||||
|
Run.Flags: $(run_flags)
|
||||||
|
Run: $(should_run)
|
||||||
|
QEMU_AARCH64_RELEASE:
|
||||||
|
Build.File: "$(package)/PlatformCI/PlatformBuild.py"
|
||||||
|
Build.Arch: "AARCH64"
|
||||||
|
Build.Flags: ""
|
||||||
|
Build.Target: "RELEASE"
|
||||||
|
Run.Flags: $(run_flags)
|
||||||
|
Run: $(should_run)
|
||||||
|
QEMU_AARCH64_NOOPT:
|
||||||
|
Build.File: "$(package)/PlatformCI/PlatformBuild.py"
|
||||||
|
Build.Arch: "AARCH64"
|
||||||
|
Build.Flags: ""
|
||||||
|
Build.Target: "NOOPT"
|
||||||
|
Run.Flags: $(run_flags)
|
||||||
|
Run: $(should_run)
|
||||||
|
QEMU_ARM_DEBUG:
|
||||||
|
Build.File: "$(package)/PlatformCI/PlatformBuild.py"
|
||||||
|
Build.Arch: "ARM"
|
||||||
|
Build.Flags: ""
|
||||||
|
Build.Target: "DEBUG"
|
||||||
|
Run.Flags: $(run_flags)
|
||||||
|
Run: $(should_run)
|
||||||
|
QEMU_ARM_RELEASE:
|
||||||
|
Build.File: "$(package)/PlatformCI/PlatformBuild.py"
|
||||||
|
Build.Arch: "ARM"
|
||||||
|
Build.Flags: ""
|
||||||
|
Build.Target: "RELEASE"
|
||||||
|
Run.Flags: $(run_flags)
|
||||||
|
Run: $(should_run)
|
||||||
|
QEMU_ARM_NOOPT:
|
||||||
|
Build.File: "$(package)/PlatformCI/PlatformBuild.py"
|
||||||
|
Build.Arch: "ARM"
|
||||||
|
Build.Flags: ""
|
||||||
|
Build.Target: "NOOPT"
|
||||||
|
Run.Flags: $(run_flags)
|
||||||
|
Run: $(should_run)
|
||||||
|
|
||||||
|
workspace:
|
||||||
|
clean: all
|
||||||
|
|
||||||
|
pool:
|
||||||
|
vmImage: $(vm_image)
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- template: ../../../.azurepipelines/templates/platform-build-run-steps.yml
|
||||||
|
parameters:
|
||||||
|
tool_chain_tag: GCC5
|
||||||
|
build_pkg: $(package)
|
||||||
|
build_target: $(Build.Target)
|
||||||
|
build_arch: $(Build.Arch)
|
||||||
|
build_file: $(Build.File)
|
||||||
|
build_flags: $(Build.Flags)
|
||||||
|
run_flags: $(Run.Flags)
|
||||||
|
extra_install_step:
|
||||||
|
- bash: sudo apt-get install qemu
|
||||||
|
displayName: Install qemu
|
||||||
|
condition: and(gt(variables.pkg_count, 0), succeeded())
|
276
ArmVirtPkg/PlatformCI/PlatformBuild.py
Normal file
276
ArmVirtPkg/PlatformCI/PlatformBuild.py
Normal file
@@ -0,0 +1,276 @@
|
|||||||
|
# @file
|
||||||
|
# Script to Build ArmVirtPkg UEFI firmware
|
||||||
|
#
|
||||||
|
# Copyright (c) Microsoft Corporation.
|
||||||
|
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
|
##
|
||||||
|
import os
|
||||||
|
import logging
|
||||||
|
import io
|
||||||
|
|
||||||
|
from edk2toolext.environment import shell_environment
|
||||||
|
from edk2toolext.environment.uefi_build import UefiBuilder
|
||||||
|
from edk2toolext.invocables.edk2_platform_build import BuildSettingsManager
|
||||||
|
from edk2toolext.invocables.edk2_setup import SetupSettingsManager, RequiredSubmodule
|
||||||
|
from edk2toolext.invocables.edk2_update import UpdateSettingsManager
|
||||||
|
from edk2toolext.invocables.edk2_pr_eval import PrEvalSettingsManager
|
||||||
|
from edk2toollib.utility_functions import RunCmd
|
||||||
|
from edk2toollib.utility_functions import GetHostInfo
|
||||||
|
|
||||||
|
# ####################################################################################### #
|
||||||
|
# Common Configuration #
|
||||||
|
# ####################################################################################### #
|
||||||
|
|
||||||
|
|
||||||
|
class CommonPlatform():
|
||||||
|
''' Common settings for this platform. Define static data here and use
|
||||||
|
for the different parts of stuart
|
||||||
|
'''
|
||||||
|
PackagesSupported = ("ArmVirtPkg",)
|
||||||
|
ArchSupported = ("AARCH64", "ARM")
|
||||||
|
TargetsSupported = ("DEBUG", "RELEASE", "NOOPT")
|
||||||
|
Scopes = ('armvirt', 'edk2-build')
|
||||||
|
WorkspaceRoot = os.path.realpath(os.path.join(
|
||||||
|
os.path.dirname(os.path.abspath(__file__)), "..", ".."))
|
||||||
|
|
||||||
|
# ####################################################################################### #
|
||||||
|
# Configuration for Update & Setup #
|
||||||
|
# ####################################################################################### #
|
||||||
|
|
||||||
|
|
||||||
|
class SettingsManager(UpdateSettingsManager, SetupSettingsManager, PrEvalSettingsManager):
|
||||||
|
|
||||||
|
def GetPackagesSupported(self):
|
||||||
|
''' return iterable of edk2 packages supported by this build.
|
||||||
|
These should be edk2 workspace relative paths '''
|
||||||
|
return CommonPlatform.PackagesSupported
|
||||||
|
|
||||||
|
def GetArchitecturesSupported(self):
|
||||||
|
''' return iterable of edk2 architectures supported by this build '''
|
||||||
|
return CommonPlatform.ArchSupported
|
||||||
|
|
||||||
|
def GetTargetsSupported(self):
|
||||||
|
''' return iterable of edk2 target tags supported by this build '''
|
||||||
|
return CommonPlatform.TargetsSupported
|
||||||
|
|
||||||
|
def GetRequiredSubmodules(self):
|
||||||
|
''' return iterable containing RequiredSubmodule objects.
|
||||||
|
If no RequiredSubmodules return an empty iterable
|
||||||
|
'''
|
||||||
|
rs = []
|
||||||
|
|
||||||
|
# intentionally declare this one with recursive false to avoid overhead
|
||||||
|
rs.append(RequiredSubmodule(
|
||||||
|
"CryptoPkg/Library/OpensslLib/openssl", False))
|
||||||
|
|
||||||
|
# To avoid maintenance of this file for every new submodule
|
||||||
|
# lets just parse the .gitmodules and add each if not already in list.
|
||||||
|
# The GetRequiredSubmodules is designed to allow a build to optimize
|
||||||
|
# the desired submodules but it isn't necessary for this repository.
|
||||||
|
result = io.StringIO()
|
||||||
|
ret = RunCmd("git", "config --file .gitmodules --get-regexp path", workingdir=self.GetWorkspaceRoot(), outstream=result)
|
||||||
|
# Cmd output is expected to look like:
|
||||||
|
# submodule.CryptoPkg/Library/OpensslLib/openssl.path CryptoPkg/Library/OpensslLib/openssl
|
||||||
|
# submodule.SoftFloat.path ArmPkg/Library/ArmSoftFloatLib/berkeley-softfloat-3
|
||||||
|
if ret == 0:
|
||||||
|
for line in result.getvalue().splitlines():
|
||||||
|
_, _, path = line.partition(" ")
|
||||||
|
if path is not None:
|
||||||
|
if path not in [x.path for x in rs]:
|
||||||
|
rs.append(RequiredSubmodule(path, True)) # add it with recursive since we don't know
|
||||||
|
return rs
|
||||||
|
|
||||||
|
def SetArchitectures(self, list_of_requested_architectures):
|
||||||
|
''' Confirm the requests architecture list is valid and configure SettingsManager
|
||||||
|
to run only the requested architectures.
|
||||||
|
|
||||||
|
Raise Exception if a list_of_requested_architectures is not supported
|
||||||
|
'''
|
||||||
|
unsupported = set(list_of_requested_architectures) - \
|
||||||
|
set(self.GetArchitecturesSupported())
|
||||||
|
if(len(unsupported) > 0):
|
||||||
|
errorString = (
|
||||||
|
"Unsupported Architecture Requested: " + " ".join(unsupported))
|
||||||
|
logging.critical(errorString)
|
||||||
|
raise Exception(errorString)
|
||||||
|
self.ActualArchitectures = list_of_requested_architectures
|
||||||
|
|
||||||
|
def GetWorkspaceRoot(self):
|
||||||
|
''' get WorkspacePath '''
|
||||||
|
return CommonPlatform.WorkspaceRoot
|
||||||
|
|
||||||
|
def GetActiveScopes(self):
|
||||||
|
''' return tuple containing scopes that should be active for this process '''
|
||||||
|
|
||||||
|
scopes = CommonPlatform.Scopes
|
||||||
|
ActualToolChainTag = shell_environment.GetBuildVars().GetValue("TOOL_CHAIN_TAG", "")
|
||||||
|
|
||||||
|
if GetHostInfo().os.upper() == "LINUX" and ActualToolChainTag.upper().startswith("GCC"):
|
||||||
|
if "AARCH64" in self.ActualArchitectures:
|
||||||
|
scopes += ("gcc_aarch64_linux",)
|
||||||
|
if "ARM" in self.ActualArchitectures:
|
||||||
|
scopes += ("gcc_arm_linux",)
|
||||||
|
return scopes
|
||||||
|
|
||||||
|
def FilterPackagesToTest(self, changedFilesList: list, potentialPackagesList: list) -> list:
|
||||||
|
''' Filter other cases that this package should be built
|
||||||
|
based on changed files. This should cover things that can't
|
||||||
|
be detected as dependencies. '''
|
||||||
|
build_these_packages = []
|
||||||
|
possible_packages = potentialPackagesList.copy()
|
||||||
|
for f in changedFilesList:
|
||||||
|
# BaseTools files that might change the build
|
||||||
|
if "BaseTools" in f:
|
||||||
|
if os.path.splitext(f) not in [".txt", ".md"]:
|
||||||
|
build_these_packages = possible_packages
|
||||||
|
break
|
||||||
|
|
||||||
|
# if the azure pipeline platform template file changed
|
||||||
|
if "platform-build-run-steps.yml" in f:
|
||||||
|
build_these_packages = possible_packages
|
||||||
|
break
|
||||||
|
|
||||||
|
|
||||||
|
return build_these_packages
|
||||||
|
|
||||||
|
def GetPlatformDscAndConfig(self) -> tuple:
|
||||||
|
''' If a platform desires to provide its DSC then Policy 4 will evaluate if
|
||||||
|
any of the changes will be built in the dsc.
|
||||||
|
|
||||||
|
The tuple should be (<workspace relative path to dsc file>, <input dictionary of dsc key value pairs>)
|
||||||
|
'''
|
||||||
|
return (os.path.join("ArmVirtPkg", "ArmVirtQemu.dsc"), {})
|
||||||
|
|
||||||
|
|
||||||
|
# ####################################################################################### #
|
||||||
|
# Actual Configuration for Platform Build #
|
||||||
|
# ####################################################################################### #
|
||||||
|
|
||||||
|
|
||||||
|
class PlatformBuilder(UefiBuilder, BuildSettingsManager):
|
||||||
|
def __init__(self):
|
||||||
|
UefiBuilder.__init__(self)
|
||||||
|
|
||||||
|
def AddCommandLineOptions(self, parserObj):
|
||||||
|
''' Add command line options to the argparser '''
|
||||||
|
parserObj.add_argument('-a', "--arch", dest="build_arch", type=str, default="AARCH64",
|
||||||
|
help="Optional - Architecture to build. Default = AARCH64")
|
||||||
|
|
||||||
|
def RetrieveCommandLineOptions(self, args):
|
||||||
|
''' Retrieve command line options from the argparser '''
|
||||||
|
|
||||||
|
shell_environment.GetBuildVars().SetValue(
|
||||||
|
"TARGET_ARCH", args.build_arch.upper(), "From CmdLine")
|
||||||
|
|
||||||
|
shell_environment.GetBuildVars().SetValue(
|
||||||
|
"ACTIVE_PLATFORM", "ArmVirtPkg/ArmVirtQemu.dsc", "From CmdLine")
|
||||||
|
|
||||||
|
def GetWorkspaceRoot(self):
|
||||||
|
''' get WorkspacePath '''
|
||||||
|
return CommonPlatform.WorkspaceRoot
|
||||||
|
|
||||||
|
def GetPackagesPath(self):
|
||||||
|
''' Return a list of workspace relative paths that should be mapped as edk2 PackagesPath '''
|
||||||
|
return ()
|
||||||
|
|
||||||
|
def GetActiveScopes(self):
|
||||||
|
''' return tuple containing scopes that should be active for this process '''
|
||||||
|
scopes = CommonPlatform.Scopes
|
||||||
|
ActualToolChainTag = shell_environment.GetBuildVars().GetValue("TOOL_CHAIN_TAG", "")
|
||||||
|
Arch = shell_environment.GetBuildVars().GetValue("TARGET_ARCH", "")
|
||||||
|
|
||||||
|
if GetHostInfo().os.upper() == "LINUX" and ActualToolChainTag.upper().startswith("GCC"):
|
||||||
|
if "AARCH64" == Arch:
|
||||||
|
scopes += ("gcc_aarch64_linux",)
|
||||||
|
elif "ARM" == Arch:
|
||||||
|
scopes += ("gcc_arm_linux",)
|
||||||
|
return scopes
|
||||||
|
|
||||||
|
def GetName(self):
|
||||||
|
''' Get the name of the repo, platform, or product being build '''
|
||||||
|
''' Used for naming the log file, among others '''
|
||||||
|
# check the startup nsh flag and if set then rename the log file.
|
||||||
|
# this helps in CI so we don't overwrite the build log since running
|
||||||
|
# uses the stuart_build command.
|
||||||
|
if(shell_environment.GetBuildVars().GetValue("MAKE_STARTUP_NSH", "FALSE") == "TRUE"):
|
||||||
|
return "ArmVirtPkg_With_Run"
|
||||||
|
return "ArmVirtPkg"
|
||||||
|
|
||||||
|
def GetLoggingLevel(self, loggerType):
|
||||||
|
''' Get the logging level for a given type
|
||||||
|
base == lowest logging level supported
|
||||||
|
con == Screen logging
|
||||||
|
txt == plain text file logging
|
||||||
|
md == markdown file logging
|
||||||
|
'''
|
||||||
|
return logging.DEBUG
|
||||||
|
|
||||||
|
def SetPlatformEnv(self):
|
||||||
|
logging.debug("PlatformBuilder SetPlatformEnv")
|
||||||
|
self.env.SetValue("PRODUCT_NAME", "ArmVirtQemu", "Platform Hardcoded")
|
||||||
|
self.env.SetValue("MAKE_STARTUP_NSH", "FALSE", "Default to false")
|
||||||
|
self.env.SetValue("QEMU_HEADLESS", "FALSE", "Default to false")
|
||||||
|
return 0
|
||||||
|
|
||||||
|
def PlatformPreBuild(self):
|
||||||
|
return 0
|
||||||
|
|
||||||
|
def PlatformPostBuild(self):
|
||||||
|
return 0
|
||||||
|
|
||||||
|
def FlashRomImage(self):
|
||||||
|
VirtualDrive = os.path.join(self.env.GetValue(
|
||||||
|
"BUILD_OUTPUT_BASE"), "VirtualDrive")
|
||||||
|
os.makedirs(VirtualDrive, exist_ok=True)
|
||||||
|
OutputPath_FV = os.path.join(
|
||||||
|
self.env.GetValue("BUILD_OUTPUT_BASE"), "FV")
|
||||||
|
Built_FV = os.path.join(OutputPath_FV, "QEMU_EFI.fd")
|
||||||
|
|
||||||
|
# pad fd to 64mb
|
||||||
|
with open(Built_FV, "ab") as fvfile:
|
||||||
|
fvfile.seek(0, os.SEEK_END)
|
||||||
|
additional = b'\0' * ((64 * 1024 * 1024)-fvfile.tell())
|
||||||
|
fvfile.write(additional)
|
||||||
|
|
||||||
|
# QEMU must be on that path
|
||||||
|
|
||||||
|
# Unique Command and Args parameters per ARCH
|
||||||
|
if (self.env.GetValue("TARGET_ARCH").upper() == "AARCH64"):
|
||||||
|
cmd = "qemu-system-aarch64"
|
||||||
|
args = "-M virt"
|
||||||
|
args += " -cpu cortex-a57" # emulate cpu
|
||||||
|
elif(self.env.GetValue("TARGET_ARCH").upper() == "ARM"):
|
||||||
|
cmd = "qemu-system-arm"
|
||||||
|
args = "-M virt"
|
||||||
|
args += " -cpu cortex-a15" # emulate cpu
|
||||||
|
else:
|
||||||
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
# Common Args
|
||||||
|
args += " -pflash " + Built_FV # path to fw
|
||||||
|
args += " -m 1024" # 1gb memory
|
||||||
|
# turn off network
|
||||||
|
args += " -net none"
|
||||||
|
# Serial messages out
|
||||||
|
args += " -serial stdio"
|
||||||
|
# Mount disk with startup.nsh
|
||||||
|
args += f" -drive file=fat:rw:{VirtualDrive},format=raw,media=disk"
|
||||||
|
|
||||||
|
# Conditional Args
|
||||||
|
if (self.env.GetValue("QEMU_HEADLESS").upper() == "TRUE"):
|
||||||
|
args += " -display none" # no graphics
|
||||||
|
|
||||||
|
if (self.env.GetValue("MAKE_STARTUP_NSH").upper() == "TRUE"):
|
||||||
|
f = open(os.path.join(VirtualDrive, "startup.nsh"), "w")
|
||||||
|
f.write("BOOT SUCCESS !!! \n")
|
||||||
|
# add commands here
|
||||||
|
f.write("reset -s\n")
|
||||||
|
f.close()
|
||||||
|
|
||||||
|
ret = RunCmd(cmd, args)
|
||||||
|
|
||||||
|
if ret == 0xc0000005:
|
||||||
|
# for some reason getting a c0000005 on successful return
|
||||||
|
return 0
|
||||||
|
|
||||||
|
return ret
|
125
ArmVirtPkg/PlatformCI/ReadMe.md
Normal file
125
ArmVirtPkg/PlatformCI/ReadMe.md
Normal file
@@ -0,0 +1,125 @@
|
|||||||
|
# ArmVirtPkg - Platform CI
|
||||||
|
|
||||||
|
This Readme.md describes the Azure DevOps based Platform CI for ArmVirtPkg and how
|
||||||
|
to use the same Pytools based build infrastructure locally.
|
||||||
|
|
||||||
|
## Supported Configuration Details
|
||||||
|
|
||||||
|
This solution for building and running ArmVirtPkg has only been validated with Ubuntu
|
||||||
|
18.04 and the GCC5 toolchain. Two different firmware builds are supported and are
|
||||||
|
described below.
|
||||||
|
|
||||||
|
| Configuration name | Architecture | DSC File |Additional Flags |
|
||||||
|
| :---------- | :----- | :----- | :---- |
|
||||||
|
| AARCH64 | AARCH64 | ArmVirtQemu.dsc | None |
|
||||||
|
| ARM | ARM | ArmVirtQemu.dsc | None |
|
||||||
|
|
||||||
|
## EDK2 Developer environment
|
||||||
|
|
||||||
|
- [Python 3.8.x - Download & Install](https://www.python.org/downloads/)
|
||||||
|
- [GIT - Download & Install](https://git-scm.com/download/)
|
||||||
|
- [QEMU - Download, Install, and add to your path](https://www.qemu.org/download/)
|
||||||
|
- [Edk2 Source](https://github.com/tianocore/edk2)
|
||||||
|
- Additional packages found necessary for Ubuntu 18.04
|
||||||
|
- apt-get install gcc g++ make uuid-dev
|
||||||
|
|
||||||
|
Note: edksetup, Submodule initialization and manual installation of NASM, iASL, or
|
||||||
|
the required cross-compiler toolchains are **not** required, this is handled by the
|
||||||
|
Pytools build system.
|
||||||
|
|
||||||
|
## Building with Pytools for ArmVirtPkg
|
||||||
|
|
||||||
|
1. [Optional] Create a Python Virtual Environment - generally once per workspace
|
||||||
|
|
||||||
|
``` bash
|
||||||
|
python -m venv <name of virtual environment>
|
||||||
|
```
|
||||||
|
|
||||||
|
2. [Optional] Activate Virtual Environment - each time new shell opened
|
||||||
|
- Windows
|
||||||
|
|
||||||
|
``` bash
|
||||||
|
<name of virtual environment>/Scripts/activate.bat
|
||||||
|
```
|
||||||
|
|
||||||
|
- Linux
|
||||||
|
|
||||||
|
```bash
|
||||||
|
source <name of virtual environment>/bin/activate
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Install Pytools - generally once per virtual env or whenever pip-requirements.txt changes
|
||||||
|
|
||||||
|
``` bash
|
||||||
|
pip install --upgrade -r pip-requirements.txt
|
||||||
|
```
|
||||||
|
|
||||||
|
4. Initialize & Update Submodules - only when submodules updated
|
||||||
|
|
||||||
|
``` bash
|
||||||
|
stuart_setup -c ArmVirtPkg/PlatformCI/PlatformBuild.py TOOL_CHAIN_TAG=<TOOL_CHAIN_TAG> -a <TARGET_ARCH>
|
||||||
|
```
|
||||||
|
|
||||||
|
5. Initialize & Update Dependencies - only as needed when ext_deps change
|
||||||
|
|
||||||
|
``` bash
|
||||||
|
stuart_update -c ArmVirtPkg/PlatformCI/PlatformBuild.py TOOL_CHAIN_TAG=<TOOL_CHAIN_TAG> -a <TARGET_ARCH>
|
||||||
|
```
|
||||||
|
|
||||||
|
6. Compile the basetools if necessary - only when basetools C source files change
|
||||||
|
|
||||||
|
``` bash
|
||||||
|
python BaseTools/Edk2ToolsBuild.py -t <ToolChainTag>
|
||||||
|
```
|
||||||
|
|
||||||
|
7. Compile Firmware
|
||||||
|
|
||||||
|
``` bash
|
||||||
|
stuart_build -c ArmVirtPkg/PlatformCI/PlatformBuild.py TOOL_CHAIN_TAG=<TOOL_CHAIN_TAG> -a <TARGET_ARCH>
|
||||||
|
```
|
||||||
|
|
||||||
|
- use `stuart_build -c ArmVirtPkg/PlatformCI/PlatformBuild.py -h` option to see additional
|
||||||
|
options like `--clean`
|
||||||
|
|
||||||
|
8. Running Emulator
|
||||||
|
- You can add `--FlashRom` to the end of your build command and the emulator will run after the
|
||||||
|
build is complete.
|
||||||
|
- or use the `--FlashOnly` feature to just run the emulator.
|
||||||
|
|
||||||
|
``` bash
|
||||||
|
stuart_build -c ArmVirtPkg/PlatformCI/PlatformBuild.py TOOL_CHAIN_TAG=<TOOL_CHAIN_TAG> -a <TARGET_ARCH> --FlashOnly
|
||||||
|
```
|
||||||
|
|
||||||
|
### Notes
|
||||||
|
|
||||||
|
1. Including the expected build architecture and toolchain to the _stuart_update_ command is critical.
|
||||||
|
This is because there are extra scopes and tools that will be resolved during the update step that
|
||||||
|
need to match your build step.
|
||||||
|
2. Configuring *ACTIVE_PLATFORM* and *TARGET_ARCH* in Conf/target.txt is **not** required. This
|
||||||
|
environment is set by PlatformBuild.py based upon the `[-a <TARGET_ARCH>]` parameter.
|
||||||
|
3. QEMU must be on your path. On Windows this is a manual process and not part of the QEMU installer.
|
||||||
|
|
||||||
|
**NOTE:** Logging the execution output will be in the normal stuart log as well as to your console.
|
||||||
|
|
||||||
|
### Custom Build Options
|
||||||
|
|
||||||
|
**MAKE_STARTUP_NSH=TRUE** will output a *startup.nsh* file to the location mapped as fs0. This is
|
||||||
|
used in CI in combination with the `--FlashOnly` feature to run QEMU to the UEFI shell and then execute
|
||||||
|
the contents of *startup.nsh*.
|
||||||
|
|
||||||
|
**QEMU_HEADLESS=TRUE** Since CI servers run headless QEMU must be told to run with no display otherwise
|
||||||
|
an error occurs. Locally you don't need to set this.
|
||||||
|
|
||||||
|
### Passing Build Defines
|
||||||
|
|
||||||
|
To pass build defines through _stuart_build_, prepend `BLD_*_`to the define name and pass it on the
|
||||||
|
command-line. _stuart_build_ currently requires values to be assigned, so add an`=1` suffix for bare defines.
|
||||||
|
For example, to enable the TPM2 support, instead of the traditional "-D TPM2_ENABLE=TRUE", the stuart_build
|
||||||
|
command-line would be:
|
||||||
|
|
||||||
|
`stuart_build -c ArmVirtPkg/PlatformCI/PlatformBuild.py BLD_*_TPM2_ENABLE=TRUE`
|
||||||
|
|
||||||
|
## References
|
||||||
|
|
||||||
|
- [Installing and using Pytools](https://github.com/tianocore/edk2-pytool-extensions/blob/master/docs/using.md#installing)
|
||||||
|
- More on [python virtual environments](https://docs.python.org/3/library/venv.html)
|
21
ArmVirtPkg/PlatformCI/iasl_ext_dep.yaml
Normal file
21
ArmVirtPkg/PlatformCI/iasl_ext_dep.yaml
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
## @file
|
||||||
|
# Download iasl executable tool from a nuget.org package
|
||||||
|
# - package contains different binaries based on host
|
||||||
|
# Add the folder with the tool to the path
|
||||||
|
#
|
||||||
|
# This is only downloaded for scope armvirt thus
|
||||||
|
# should have no impact on the asl compiler used by any
|
||||||
|
# other platform build
|
||||||
|
#
|
||||||
|
# Copyright (c) Microsoft Corporation.
|
||||||
|
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
|
##
|
||||||
|
{
|
||||||
|
"id": "iasl-armvirt-1",
|
||||||
|
"scope": "armvirt",
|
||||||
|
"type": "nuget",
|
||||||
|
"name": "iasl",
|
||||||
|
"source": "https://api.nuget.org/v3/index.json",
|
||||||
|
"version": "20190215.0.0",
|
||||||
|
"flags": ["set_path", "host_specific"],
|
||||||
|
}
|
22
BaseTools/Bin/gcc_riscv64_unknown_ext_dep.yaml
Normal file
22
BaseTools/Bin/gcc_riscv64_unknown_ext_dep.yaml
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
## @file
|
||||||
|
# Download GCC RISCV64 compiler from RISC-V Organization release site
|
||||||
|
# Set shell variable GCC5_RISCV64_INSTALL to this folder
|
||||||
|
#
|
||||||
|
# This is only downloaded when a build activates scope gcc_riscv64_unknown
|
||||||
|
#
|
||||||
|
# Copyright (c) Microsoft Corporation.
|
||||||
|
# Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
|
||||||
|
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
|
##
|
||||||
|
{
|
||||||
|
"scope": "gcc_riscv64_unknown",
|
||||||
|
"type": "web",
|
||||||
|
"name": "gcc_riscv64_unknown",
|
||||||
|
"source": "https://raw.githubusercontent.com/riscv/riscv-uefi-edk2-docs/master/gcc-riscv-edk2-ci-toolchain/gcc-riscv-9.2.0-2020.04-x86_64_riscv64-unknown-gnu.tar.xz",
|
||||||
|
"version": "9.2.0",
|
||||||
|
"compression_type": "tar",
|
||||||
|
"sha256": "28373643b69f0ce008273c3dc63f172aa1121952f1b9ae94d7485ac94af7f344",
|
||||||
|
"internal_path": "/gcc-riscv-9.2.0-2020.04-x86_64_riscv64-unknown-gnu",
|
||||||
|
"flags": ["set_shell_var", ],
|
||||||
|
"var_name": "GCC5_RISCV64_INSTALL"
|
||||||
|
}
|
14
BaseTools/BinWrappers/PosixLike/AmlToHex
Executable file
14
BaseTools/BinWrappers/PosixLike/AmlToHex
Executable file
@@ -0,0 +1,14 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
#python `dirname $0`/RunToolFromSource.py `basename $0` $*
|
||||||
|
|
||||||
|
# If a ${PYTHON_COMMAND} command is available, use it in preference to python
|
||||||
|
if command -v ${PYTHON_COMMAND} >/dev/null 2>&1; then
|
||||||
|
python_exe=${PYTHON_COMMAND}
|
||||||
|
fi
|
||||||
|
|
||||||
|
full_cmd=${BASH_SOURCE:-$0} # see http://mywiki.wooledge.org/BashFAQ/028 for a discussion of why $0 is not a good choice here
|
||||||
|
dir=$(dirname "$full_cmd")
|
||||||
|
exe=$(basename "$full_cmd")
|
||||||
|
|
||||||
|
export PYTHONPATH="$dir/../../Source/Python${PYTHONPATH:+:"$PYTHONPATH"}"
|
||||||
|
exec "${python_exe:-python}" "$dir/../../Source/Python/$exe/$exe.py" "$@"
|
3
BaseTools/BinWrappers/WindowsLike/AmlToHex.bat
Normal file
3
BaseTools/BinWrappers/WindowsLike/AmlToHex.bat
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
@setlocal
|
||||||
|
@set ToolName=%~n0%
|
||||||
|
@%PYTHON_COMMAND% %BASE_TOOLS_PATH%\Source\Python\%ToolName%\%ToolName%.py %*
|
@@ -1,6 +1,7 @@
|
|||||||
#
|
#
|
||||||
# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
|
# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||||
# Portions copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>
|
# Portions copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>
|
||||||
|
# Copyright (c) 2020, ARM Ltd. All rights reserved.<BR>
|
||||||
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
#
|
#
|
||||||
|
|
||||||
@@ -81,6 +82,8 @@
|
|||||||
# will be generated only when this macro is used in command line.
|
# will be generated only when this macro is used in command line.
|
||||||
# This is intended to get over the long command line limitation.
|
# This is intended to get over the long command line limitation.
|
||||||
# )
|
# )
|
||||||
|
# $(DEPS_FLAGS) This is a tool flag to have c compiler generate dependent header file list for a source file.
|
||||||
|
# To enable incremental build, this flag must apply to $(CC), $(VFRPP), $(PP), $(ASLCC) and $(ASLPP).
|
||||||
#
|
#
|
||||||
# $(CP) copy command
|
# $(CP) copy command
|
||||||
# $(MV) move command
|
# $(MV) move command
|
||||||
@@ -123,14 +126,14 @@
|
|||||||
$(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.obj
|
$(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.obj
|
||||||
|
|
||||||
<Command.MSFT, Command.INTEL>
|
<Command.MSFT, Command.INTEL>
|
||||||
"$(CC)" /Fo${dst} $(CC_FLAGS) $(INC) ${src}
|
"$(CC)" /Fo${dst} $(DEPS_FLAGS) $(CC_FLAGS) $(INC) ${src}
|
||||||
|
|
||||||
<Command.GCC, Command.RVCT>
|
<Command.GCC, Command.RVCT>
|
||||||
# For RVCTCYGWIN CC_FLAGS must be first to work around pathing issues
|
# For RVCTCYGWIN CC_FLAGS must be first to work around pathing issues
|
||||||
"$(CC)" $(CC_FLAGS) -c -o ${dst} $(INC) ${src}
|
"$(CC)" $(DEPS_FLAGS) $(CC_FLAGS) -c -o ${dst} $(INC) ${src}
|
||||||
|
|
||||||
<Command.XCODE>
|
<Command.XCODE>
|
||||||
"$(CC)" $(CC_FLAGS) -o ${dst} $(INC) ${src}
|
"$(CC)" $(DEPS_FLAGS) $(CC_FLAGS) -o ${dst} $(INC) ${src}
|
||||||
|
|
||||||
[C-Code-File.BASE.AARCH64,C-Code-File.SEC.AARCH64,C-Code-File.PEI_CORE.AARCH64,C-Code-File.PEIM.AARCH64,C-Code-File.BASE.ARM,C-Code-File.SEC.ARM,C-Code-File.PEI_CORE.ARM,C-Code-File.PEIM.ARM]
|
[C-Code-File.BASE.AARCH64,C-Code-File.SEC.AARCH64,C-Code-File.PEI_CORE.AARCH64,C-Code-File.PEIM.AARCH64,C-Code-File.BASE.ARM,C-Code-File.SEC.ARM,C-Code-File.PEI_CORE.ARM,C-Code-File.PEIM.ARM]
|
||||||
<InputFile>
|
<InputFile>
|
||||||
@@ -167,15 +170,17 @@
|
|||||||
$(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.obj
|
$(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.obj
|
||||||
|
|
||||||
<Command.MSFT, Command.INTEL>
|
<Command.MSFT, Command.INTEL>
|
||||||
"$(PP)" $(PP_FLAGS) $(INC) ${src} > ${d_path}(+)${s_base}.i
|
Trim --asm-file -o ${d_path}(+)${s_base}.i -i $(INC_LIST) ${src}
|
||||||
Trim --source-code --convert-hex --trim-long -o ${d_path}(+)${s_base}.iii ${d_path}(+)${s_base}.i
|
"$(PP)" $(DEPS_FLAGS) $(PP_FLAGS) $(INC) ${src} > ${d_path}(+)${s_base}.ii
|
||||||
"$(ASM)" /Fo${dst} $(ASM_FLAGS) /I${s_path} $(INC) ${d_path}(+)${s_base}.iii
|
Trim --source-code --convert-hex --trim-long -o ${d_path}(+)${s_base}.iiii ${d_path}(+)${s_base}.ii
|
||||||
|
"$(ASM)" /Fo${dst} $(ASM_FLAGS) /I${s_path} $(INC) ${d_path}(+)${s_base}.iiii
|
||||||
|
|
||||||
<Command.GCC, Command.RVCT>
|
<Command.GCC, Command.RVCT>
|
||||||
"$(PP)" $(PP_FLAGS) $(INC) ${src} > ${d_path}(+)${s_base}.i
|
Trim --asm-file -o ${d_path}(+)${s_base}.i -i $(INC_LIST) ${src}
|
||||||
Trim --trim-long --source-code -o ${d_path}(+)${s_base}.iii ${d_path}(+)${s_base}.i
|
"$(PP)" $(DEPS_FLAGS) $(PP_FLAGS) $(INC) ${src} > ${d_path}(+)${s_base}.ii
|
||||||
|
Trim --trim-long --source-code -o ${d_path}(+)${s_base}.iiii ${d_path}(+)${s_base}.ii
|
||||||
# For RVCTCYGWIN ASM_FLAGS must be first to work around pathing issues
|
# For RVCTCYGWIN ASM_FLAGS must be first to work around pathing issues
|
||||||
"$(ASM)" $(ASM_FLAGS) -o ${dst} $(INC) ${d_path}(+)${s_base}.iii
|
"$(ASM)" $(ASM_FLAGS) -o ${dst} $(INC) ${d_path}(+)${s_base}.iiii
|
||||||
|
|
||||||
[Assembly-Code-File.COMMON.ARM,Assembly-Code-File.COMMON.AARCH64]
|
[Assembly-Code-File.COMMON.ARM,Assembly-Code-File.COMMON.AARCH64]
|
||||||
# Remove --convert-hex for ARM as it breaks MSFT assemblers
|
# Remove --convert-hex for ARM as it breaks MSFT assemblers
|
||||||
@@ -192,20 +197,23 @@
|
|||||||
$(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.obj
|
$(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.obj
|
||||||
|
|
||||||
<Command.INTEL>
|
<Command.INTEL>
|
||||||
"$(PP)" $(PP_FLAGS) $(INC) ${src} > ${d_path}(+)${s_base}.i
|
Trim --asm-file -o ${d_path}(+)${s_base}.i -i $(INC_LIST) ${src}
|
||||||
Trim --source-code --convert-hex --trim-long -o ${d_path}(+)${s_base}.iii ${d_path}(+)${s_base}.i
|
"$(PP)" $(DEPS_FLAGS) $(PP_FLAGS) $(INC) ${src} > ${d_path}(+)${s_base}.ii
|
||||||
"$(ASM)" /Fo${dst} $(ASM_FLAGS) /I${s_path} $(INC) ${d_path}(+)${s_base}.iii
|
Trim --source-code --convert-hex --trim-long -o ${d_path}(+)${s_base}.iiii ${d_path}(+)${s_base}.ii
|
||||||
|
"$(ASM)" /Fo${dst} $(ASM_FLAGS) /I${s_path} $(INC) ${d_path}(+)${s_base}.iiii
|
||||||
|
|
||||||
<Command.MSFT>
|
<Command.MSFT>
|
||||||
"$(PP)" $(PP_FLAGS) $(INC) ${src} > ${d_path}(+)${s_base}.i
|
Trim --asm-file -o ${d_path}(+)${s_base}.i -i $(INC_LIST) ${src}
|
||||||
Trim --source-code --trim-long -o ${d_path}(+)${s_base}.iii ${d_path}(+)${s_base}.i
|
"$(PP)" $(DEPS_FLAGS) $(PP_FLAGS) $(INC) ${src} > ${d_path}(+)${s_base}.ii
|
||||||
"$(ASM)" /Fo${dst} $(ASM_FLAGS) /I${s_path} $(INC) ${d_path}(+)${s_base}.iii
|
Trim --source-code --trim-long -o ${d_path}(+)${s_base}.iiii ${d_path}(+)${s_base}.ii
|
||||||
|
"$(ASM)" /Fo${dst} $(ASM_FLAGS) /I${s_path} $(INC) ${d_path}(+)${s_base}.iiii
|
||||||
|
|
||||||
<Command.GCC, Command.RVCT>
|
<Command.GCC, Command.RVCT>
|
||||||
"$(PP)" $(PP_FLAGS) $(INC) ${src} > ${d_path}(+)${s_base}.i
|
Trim --asm-file -o ${d_path}(+)${s_base}.i -i $(INC_LIST) ${src}
|
||||||
Trim --trim-long --source-code -o ${d_path}(+)${s_base}.iii ${d_path}(+)${s_base}.i
|
"$(PP)" $(DEPS_FLAGS) $(PP_FLAGS) $(INC) ${src} > ${d_path}(+)${s_base}.ii
|
||||||
|
Trim --trim-long --source-code -o ${d_path}(+)${s_base}.iiii ${d_path}(+)${s_base}.ii
|
||||||
# For RVCTCYGWIN ASM_FLAGS must be first to work around pathing issues
|
# For RVCTCYGWIN ASM_FLAGS must be first to work around pathing issues
|
||||||
"$(ASM)" $(ASM_FLAGS) -o ${dst} $(INC) ${d_path}(+)${s_base}.iii
|
"$(ASM)" $(ASM_FLAGS) -o ${dst} $(INC) ${d_path}(+)${s_base}.iiii
|
||||||
|
|
||||||
[Nasm-Assembly-Code-File.COMMON.COMMON]
|
[Nasm-Assembly-Code-File.COMMON.COMMON]
|
||||||
<InputFile>
|
<InputFile>
|
||||||
@@ -218,8 +226,9 @@
|
|||||||
$(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.obj
|
$(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.obj
|
||||||
|
|
||||||
<Command>
|
<Command>
|
||||||
"$(PP)" $(PP_FLAGS) $(INC) ${src} > ${d_path}(+)${s_base}.i
|
Trim --asm-file -o ${d_path}(+)${s_base}.i -i $(INC_LIST) ${src}
|
||||||
Trim --trim-long --source-code -o ${d_path}(+)${s_base}.iii ${d_path}(+)${s_base}.i
|
"$(PP)" $(DEPS_FLAGS) $(PP_FLAGS) $(INC) ${src} > ${d_path}(+)${s_base}.ii
|
||||||
|
Trim --trim-long --source-code -o ${d_path}(+)${s_base}.iii ${d_path}(+)${s_base}.ii
|
||||||
"$(NASM)" -I${s_path}(+) $(NASM_INC) $(NASM_FLAGS) -o $dst ${d_path}(+)${s_base}.iii
|
"$(NASM)" -I${s_path}(+) $(NASM_INC) $(NASM_FLAGS) -o $dst ${d_path}(+)${s_base}.iii
|
||||||
|
|
||||||
[Device-Tree-Source-File]
|
[Device-Tree-Source-File]
|
||||||
@@ -249,7 +258,7 @@
|
|||||||
$(DEBUG_DIR)(+)${s_dir}(+)${s_base}.c
|
$(DEBUG_DIR)(+)${s_dir}(+)${s_base}.c
|
||||||
|
|
||||||
<Command>
|
<Command>
|
||||||
"$(VFRPP)" $(VFRPP_FLAGS) $(INC) ${src} > $(OUTPUT_DIR)(+)${s_base}.i
|
"$(VFRPP)" $(DEPS_FLAGS) $(VFRPP_FLAGS) $(INC) ${src} > $(OUTPUT_DIR)(+)${s_base}.i
|
||||||
"$(VFR)" $(VFR_FLAGS) --string-db $(OUTPUT_DIR)(+)$(MODULE_NAME)StrDefs.hpk --output-directory ${d_path} $(OUTPUT_DIR)(+)${s_base}.i
|
"$(VFR)" $(VFR_FLAGS) --string-db $(OUTPUT_DIR)(+)$(MODULE_NAME)StrDefs.hpk --output-directory ${d_path} $(OUTPUT_DIR)(+)${s_base}.i
|
||||||
|
|
||||||
[Object-File]
|
[Object-File]
|
||||||
@@ -400,7 +409,7 @@
|
|||||||
$(MAKE_FILE)
|
$(MAKE_FILE)
|
||||||
|
|
||||||
<Command>
|
<Command>
|
||||||
"$(PP)" $(APP_FLAGS) $(INC) ${src} > $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.i
|
"$(PP)" $(DEPS_FLAGS) $(APP_FLAGS) $(INC) ${src} > $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.i
|
||||||
Trim --source-code -o $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.iii $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.i
|
Trim --source-code -o $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.iii $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.i
|
||||||
GenDepex -t $(MODULE_TYPE) -o ${dst} $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.iii
|
GenDepex -t $(MODULE_TYPE) -o ${dst} $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.iii
|
||||||
|
|
||||||
@@ -415,16 +424,18 @@
|
|||||||
$(MAKE_FILE)
|
$(MAKE_FILE)
|
||||||
|
|
||||||
<Command.MSFT, Command.INTEL>
|
<Command.MSFT, Command.INTEL>
|
||||||
Trim --asl-file -o $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.i -i $(INC_LIST) ${src}
|
Trim --asl-file --asl-deps -o $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.i -i $(INC_LIST) ${src}
|
||||||
"$(ASLPP)" $(ASLPP_FLAGS) $(INC) /I${s_path} $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.i > $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.iii
|
"$(ASLPP)" $(DEPS_FLAGS) $(ASLPP_FLAGS) $(INC) /I${s_path} $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.i > $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.iii
|
||||||
Trim --source-code -l -o $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.iiii $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.iii
|
Trim --source-code -l -o $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.iiii $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.iii
|
||||||
"$(ASL)" $(ASL_FLAGS) $(ASL_OUTFLAGS)${dst} $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.iiii
|
"$(ASL)" $(ASL_FLAGS) $(ASL_OUTFLAGS)${dst} $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.iiii
|
||||||
|
-AmlToHex $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.aml
|
||||||
|
|
||||||
<Command.GCC>
|
<Command.GCC>
|
||||||
Trim --asl-file -o $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.i -i $(INC_LIST) ${src}
|
Trim --asl-file --asl-deps -o $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.i -i $(INC_LIST) ${src}
|
||||||
"$(ASLPP)" $(ASLPP_FLAGS) $(INC) -I${s_path} $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.i > $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.iii
|
"$(ASLPP)" $(DEPS_FLAGS) $(ASLPP_FLAGS) $(INC) -I${s_path} $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.i > $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.iii
|
||||||
Trim --source-code -l -o $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.iiii $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.iii
|
Trim --source-code -l -o $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.iiii $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.iii
|
||||||
"$(ASL)" $(ASL_FLAGS) $(ASL_OUTFLAGS)${dst} $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.iiii
|
"$(ASL)" $(ASL_FLAGS) $(ASL_OUTFLAGS)${dst} $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.iiii
|
||||||
|
-AmlToHex $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.aml
|
||||||
|
|
||||||
[C-Code-File.AcpiTable]
|
[C-Code-File.AcpiTable]
|
||||||
<InputFile>
|
<InputFile>
|
||||||
@@ -437,12 +448,12 @@
|
|||||||
$(MAKE_FILE)
|
$(MAKE_FILE)
|
||||||
|
|
||||||
<Command.MSFT, Command.INTEL>
|
<Command.MSFT, Command.INTEL>
|
||||||
"$(ASLCC)" /Fo$(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.obj $(ASLCC_FLAGS) $(INC) ${src}
|
"$(ASLCC)" $(DEPS_FLAGS) /Fo$(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.obj $(ASLCC_FLAGS) $(DEPS_FLAGS) $(INC) ${src}
|
||||||
"$(ASLDLINK)" /OUT:$(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.dll $(ASLDLINK_FLAGS) $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.obj
|
"$(ASLDLINK)" /OUT:$(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.dll $(ASLDLINK_FLAGS) $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.obj
|
||||||
"$(GENFW)" -o ${dst} -c $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.dll $(GENFW_FLAGS)
|
"$(GENFW)" -o ${dst} -c $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.dll $(GENFW_FLAGS)
|
||||||
|
|
||||||
<Command.GCC>
|
<Command.GCC>
|
||||||
"$(ASLCC)" -c -o $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.obj $(CC_FLAGS) $(ASLCC_FLAGS) $(INC) ${src}
|
"$(ASLCC)" $(DEPS_FLAGS) -c -o $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.obj $(CC_FLAGS) $(ASLCC_FLAGS) $(DEPS_FLAGS) $(INC) ${src}
|
||||||
"$(ASLDLINK)" -o $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.dll $(ASLDLINK_FLAGS) $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.obj
|
"$(ASLDLINK)" -o $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.dll $(ASLDLINK_FLAGS) $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.obj
|
||||||
"$(GENFW)" -o ${dst} -c $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.dll $(GENFW_FLAGS)
|
"$(GENFW)" -o ${dst} -c $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.dll $(GENFW_FLAGS)
|
||||||
|
|
||||||
@@ -457,22 +468,22 @@
|
|||||||
$(MAKE_FILE)
|
$(MAKE_FILE)
|
||||||
|
|
||||||
<Command.MSFT, Command.INTEL>
|
<Command.MSFT, Command.INTEL>
|
||||||
"$(ASLCC)" /Fo$(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.obj $(ASLCC_FLAGS) $(INC) ${src}
|
"$(ASLCC)" $(DEPS_FLAGS) /Fo$(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.obj $(ASLCC_FLAGS) $(DEPS_FLAGS) $(INC) ${src}
|
||||||
"$(ASLDLINK)" /OUT:$(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.dll $(ASLDLINK_FLAGS) $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.obj
|
"$(ASLDLINK)" /OUT:$(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.dll $(ASLDLINK_FLAGS) $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.obj
|
||||||
"$(GENFW)" -o ${dst} -c $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.dll $(GENFW_FLAGS)
|
"$(GENFW)" -o ${dst} -c $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.dll $(GENFW_FLAGS)
|
||||||
|
|
||||||
<Command.GCC>
|
<Command.GCC>
|
||||||
"$(ASLCC)" -c -o $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.obj $(CC_FLAGS) $(ASLCC_FLAGS) $(INC) ${src}
|
"$(ASLCC)" $(DEPS_FLAGS) -c -o $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.obj $(CC_FLAGS) $(ASLCC_FLAGS) $(DEPS_FLAGS) $(INC) ${src}
|
||||||
"$(ASLDLINK)" -o $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.dll $(ASLDLINK_FLAGS) $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.obj $(CC_FLAGS) $(ASLCC_FLAGS)
|
"$(ASLDLINK)" -o $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.dll $(ASLDLINK_FLAGS) $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.obj $(CC_FLAGS) $(ASLCC_FLAGS)
|
||||||
"$(GENFW)" -o ${dst} -c $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.dll $(GENFW_FLAGS)
|
"$(GENFW)" -o ${dst} -c $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.dll $(GENFW_FLAGS)
|
||||||
|
|
||||||
<Command.CLANGPDB>
|
<Command.CLANGPDB>
|
||||||
"$(ASLCC)" -c -o $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.obj $(CC_FLAGS) $(ASLCC_FLAGS) $(INC) ${src}
|
"$(ASLCC)" $(DEPS_FLAGS) -c -o $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.obj $(CC_FLAGS) $(ASLCC_FLAGS) $(DEPS_FLAGS) $(INC) ${src}
|
||||||
"$(ASLDLINK)" /OUT:$(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.dll $(ASLDLINK_FLAGS) $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.obj
|
"$(ASLDLINK)" /OUT:$(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.dll $(ASLDLINK_FLAGS) $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.obj
|
||||||
"$(GENFW)" -o ${dst} -c $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.dll $(GENFW_FLAGS)
|
"$(GENFW)" -o ${dst} -c $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.dll $(GENFW_FLAGS)
|
||||||
|
|
||||||
<Command.XCODE>
|
<Command.XCODE>
|
||||||
"$(ASLCC)" -o $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.obj $(ASLCC_FLAGS) $(INC) ${src}
|
"$(ASLCC)" $(DEPS_FLAGS) -o $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.obj $(ASLCC_FLAGS) $(DEPS_FLAGS) $(INC) ${src}
|
||||||
"$(ASLDLINK)" -o $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.dll $(ASLDLINK_FLAGS) $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.obj
|
"$(ASLDLINK)" -o $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.dll $(ASLDLINK_FLAGS) $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.obj
|
||||||
"$(MTOC)" -subsystem $(MODULE_TYPE) $(MTOC_FLAGS) $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.dll $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.pecoff
|
"$(MTOC)" -subsystem $(MODULE_TYPE) $(MTOC_FLAGS) $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.dll $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.pecoff
|
||||||
"$(GENFW)" -o ${dst} -c $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.pecoff $(GENFW_FLAGS)
|
"$(GENFW)" -o ${dst} -c $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.pecoff $(GENFW_FLAGS)
|
||||||
@@ -489,21 +500,24 @@
|
|||||||
$(OUTPUT_DIR)(+)${s_base}.com
|
$(OUTPUT_DIR)(+)${s_base}.com
|
||||||
|
|
||||||
<Command.MSFT, Command.INTEL>
|
<Command.MSFT, Command.INTEL>
|
||||||
"$(PP)" $(PP_FLAGS) $(INC) ${src} > ${d_path}(+)${s_base}.i
|
Trim --asm-file -o ${d_path}(+)${s_base}.i -i $(INC_LIST) ${src}
|
||||||
Trim --source-code --convert-hex --trim-long -o ${d_path}(+)${s_base}.iii ${d_path}(+)${s_base}.i
|
"$(PP)" $(DEPS_FLAGS) $(PP_FLAGS) $(INC) ${src} > ${d_path}(+)${s_base}.ii
|
||||||
|
Trim --source-code --convert-hex --trim-long -o ${d_path}(+)${s_base}.iii ${d_path}(+)${s_base}.ii
|
||||||
cd $(OUTPUT_DIR)(+)${s_dir}
|
cd $(OUTPUT_DIR)(+)${s_dir}
|
||||||
"$(ASM16)" /nologo /c /omf $(INC) /Fo$(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.obj ${d_path}(+)${s_base}.iii
|
"$(ASM16)" /nologo /c /omf $(INC) /Fo$(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.obj ${d_path}(+)${s_base}.iii
|
||||||
"$(ASMLINK)" $(ASMLINK_FLAGS) $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.obj,${dst},,,,
|
"$(ASMLINK)" $(ASMLINK_FLAGS) $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.obj,${dst},,,,
|
||||||
|
|
||||||
<Command.GCC>
|
<Command.GCC>
|
||||||
"$(PP)" $(PP_FLAGS) $(INC) ${src} > ${d_path}(+)${s_base}.i
|
Trim --asm-file -o {d_path}(+)${s_base}.i -i $(INC_LIST) ${src}
|
||||||
Trim --source-code -o ${d_path}(+)${s_base}.iii ${d_path}(+)${s_base}.i
|
"$(PP)" $(DEPS_FLAGS) $(PP_FLAGS) $(INC) ${src} > ${d_path}(+)${s_base}.ii
|
||||||
|
Trim --source-code -o ${d_path}(+)${s_base}.iii ${d_path}(+)${s_base}.ii
|
||||||
"$(ASM)" -o $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.obj $(ASM_FLAGS) $(INC) ${d_path}(+)${s_base}.iii
|
"$(ASM)" -o $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.obj $(ASM_FLAGS) $(INC) ${d_path}(+)${s_base}.iii
|
||||||
"$(DLINK)" -o ${dst} $(DLINK_FLAGS) --start-group $(DLINK_SPATH) $(LIBS) $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.obj --end-group
|
"$(DLINK)" -o ${dst} $(DLINK_FLAGS) --start-group $(DLINK_SPATH) $(LIBS) $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.obj --end-group
|
||||||
|
|
||||||
<Command.XCODE>
|
<Command.XCODE>
|
||||||
"$(PP)" $(PP_FLAGS) $(INC) ${src} > ${d_path}(+)${s_base}.i
|
Trim --asm-file -o ${d_path}(+)${s_base}.i -i $(INC_LIST) ${src}
|
||||||
Trim --source-code -o ${d_path}(+)${s_base}.iii ${d_path}(+)${s_base}.i
|
"$(PP)" $(DEPS_FLAGS) $(PP_FLAGS) $(INC) ${src} > ${d_path}(+)${s_base}.ii
|
||||||
|
Trim --source-code -o ${d_path}(+)${s_base}.iii ${d_path}(+)${s_base}.ii
|
||||||
"$(ASM)" -o $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.obj $(ASM_FLAGS) $(INC) ${d_path}(+)${s_base}.iii
|
"$(ASM)" -o $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.obj $(ASM_FLAGS) $(INC) ${d_path}(+)${s_base}.iii
|
||||||
"$(SLINK)" $(SLINK_FLAGS) $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.slib $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.obj
|
"$(SLINK)" $(SLINK_FLAGS) $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.slib $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.obj
|
||||||
otool -t $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.slib | hex2bin.py ${dst}
|
otool -t $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.slib | hex2bin.py ${dst}
|
||||||
@@ -520,9 +534,10 @@
|
|||||||
$(OUTPUT_DIR)(+)${s_base}.bin
|
$(OUTPUT_DIR)(+)${s_base}.bin
|
||||||
|
|
||||||
<Command>
|
<Command>
|
||||||
"$(PP)" $(PP_FLAGS) $(INC) ${src} > ${d_path}(+)${s_base}.i
|
Trim --asm-file -o ${d_path}(+)${s_base}.i -i $(INC_LIST) ${src}
|
||||||
Trim --source-code --convert-hex -o ${d_path}(+)${s_base}.iii ${d_path}(+)${s_base}.i
|
"$(PP)" $(DEPS_FLAGS) $(PP_FLAGS) $(INC) ${src} > ${d_path}(+)${s_base}.ii
|
||||||
"$(NASM)" -I${s_path}(+) -l ${d_path}(+)${s_base}.lst $(NASMB_FLAGS) -o $dst ${d_path}(+)${s_base}.iii
|
Trim --source-code --convert-hex -o ${d_path}(+)${s_base}.iii ${d_path}(+)${s_base}.ii
|
||||||
|
"$(NASM)" -I${s_path}(+) -l ${d_path}(+)${s_base}.lst $(NASMB_FLAGS) $(NASM_INC) -o $dst ${d_path}(+)${s_base}.iii
|
||||||
# copy the output file with .com postfix that be same to the output file of .asm16
|
# copy the output file with .com postfix that be same to the output file of .asm16
|
||||||
$(CP) ${dst} $(OUTPUT_DIR)(+)${s_base}.com
|
$(CP) ${dst} $(OUTPUT_DIR)(+)${s_base}.com
|
||||||
|
|
||||||
@@ -623,7 +638,7 @@
|
|||||||
$(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.hpk
|
$(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.hpk
|
||||||
|
|
||||||
<Command>
|
<Command>
|
||||||
"$(VFRPP)" $(VFRPP_FLAGS) $(INC) ${src} > $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.i
|
"$(VFRPP)" $(DEPS_FLAGS) $(VFRPP_FLAGS) $(INC) ${src} > $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.i
|
||||||
"$(VFR)" $(VFR_FLAGS) --create-ifr-package --string-db $(OUTPUT_DIR)(+)$(MODULE_NAME)StrDefs.hpk --output-directory $(OUTPUT_DIR)(+)${s_dir} $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.i
|
"$(VFR)" $(VFR_FLAGS) --create-ifr-package --string-db $(OUTPUT_DIR)(+)$(MODULE_NAME)StrDefs.hpk --output-directory $(OUTPUT_DIR)(+)${s_dir} $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.i
|
||||||
|
|
||||||
[Hii-Binary-Package.UEFI_HII]
|
[Hii-Binary-Package.UEFI_HII]
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user