Compare commits
1394 Commits
system76-s
...
edk2-stabl
Author | SHA1 | Date | |
---|---|---|---|
ef91b07388 | |||
0930e7ff64 | |||
bdf1df8a5f | |||
0996a7883c | |||
f7ee9e9253 | |||
31eaefd4df | |||
cd14150c15 | |||
62f2cf5784 | |||
6ffbb3581a | |||
7f34681c48 | |||
35f87da8a2 | |||
69637f91c7 | |||
0cf260fabc | |||
bd158441d6 | |||
5d7b5cd105 | |||
739a506b18 | |||
68e5ecc4d2 | |||
1262c02677 | |||
9da5ee116a | |||
0e43e02b9b | |||
67f3f8b661 | |||
388dfe02fb | |||
cb4267d4c2 | |||
799c07ca28 | |||
053cd5980c | |||
2385e1deca | |||
ee283e3395 | |||
82abb8f981 | |||
af0c597e98 | |||
37ef4bb1a7 | |||
a2b5ea38a6 | |||
869ccd4a3e | |||
533fff506e | |||
078400ee15 | |||
44ae214591 | |||
4f4d862c1c | |||
2e1e8c35f3 | |||
649a59bf83 | |||
cf4cbe194f | |||
42c0019f27 | |||
7766ebd5ad | |||
1d27e58e40 | |||
641866ac42 | |||
71cd84ac09 | |||
c615265b36 | |||
124f1dd1ee | |||
8cb9b29684 | |||
273261126e | |||
1534b6228b | |||
ecc267fec5 | |||
660d4faa29 | |||
5905e09c30 | |||
e64bd0704f | |||
bfc0fae459 | |||
bb41dc678c | |||
eec78fc14d | |||
6273e59a2e | |||
2ba6ecef39 | |||
0e51d7e445 | |||
2c7c64fc04 | |||
84a6db75b5 | |||
6e131aff00 | |||
4f92cfa44d | |||
cd9fb745d7 | |||
93ff7a4e8e | |||
827a71cc9e | |||
b69566afae | |||
92bdb2a9c6 | |||
4e1f316cec | |||
9e7621c05e | |||
472276f59b | |||
5c5354e8b9 | |||
43a113385e | |||
0d96664df3 | |||
1b6c3a94ec | |||
f6ec1dd34f | |||
e806bb29cf | |||
51b96e4b4c | |||
618e6a1f21 | |||
839f649abb | |||
3f90ac3ec0 | |||
3b468095cd | |||
c2432b31ed | |||
1ea21af13d | |||
e414a3e936 | |||
7a56650e2e | |||
44ac44a269 | |||
4593925505 | |||
79a951d199 | |||
14a746bb6a | |||
1f0fa9187b | |||
b1e97194a0 | |||
06201d580b | |||
8a09cdd7be | |||
5625c1fdf7 | |||
e35fce8ada | |||
037ccb09a2 | |||
2b9006762d | |||
f6c488b704 | |||
76ae542313 | |||
4bae4f02f3 | |||
ea56ebf67d | |||
c6be6dab9c | |||
2d6fc9d36f | |||
1c5c7bcd1d | |||
3a3501862f | |||
96a9acfc52 | |||
3b769c5110 | |||
6c5801be6e | |||
45962a05da | |||
5b4a97bbc3 | |||
339371ef78 | |||
38ee7bafa7 | |||
1487c13ce0 | |||
cefad282fb | |||
e843a21e23 | |||
c4cbd86493 | |||
f4a257a355 | |||
14d4b6be56 | |||
4edba29651 | |||
aa445ce02b | |||
e1b259da42 | |||
7ac1f28d4d | |||
517055d298 | |||
166a32d09a | |||
7a6172f88b | |||
ca272b9513 | |||
6e55868631 | |||
d3f3c94201 | |||
c8ce60eb29 | |||
70254306a8 | |||
101c55ac0d | |||
ef03e72651 | |||
130e929f98 | |||
a0b352e18b | |||
2912341cd9 | |||
f72fd9616e | |||
e68c2a22ca | |||
83facfd184 | |||
79f3404ad8 | |||
4f214830ce | |||
7dc277f9e4 | |||
a7ef2a03b9 | |||
c88736f860 | |||
014b9850f2 | |||
40c4cd5421 | |||
536a3e6726 | |||
da45a36087 | |||
ef23012e54 | |||
ebfe2d3eb5 | |||
edd74ad3ad | |||
e992cc3f48 | |||
a8a0831589 | |||
4ea3a6ded8 | |||
acabf1b033 | |||
fa4c4fb8cd | |||
ea830b96fd | |||
6e9233f968 | |||
a88731d545 | |||
805b8b8837 | |||
9783767fcf | |||
fabeffb09e | |||
1819817155 | |||
7e6776deaf | |||
4e38bb607a | |||
1d3d5e3256 | |||
a955c6f97f | |||
85b8eac59b | |||
362654246a | |||
5667dc43d8 | |||
c330af0246 | |||
a746ca5b47 | |||
60b195d257 | |||
31f5ebd6db | |||
84cddd7082 | |||
45388d046c | |||
b97dc4b92b | |||
3b32be7e71 | |||
bd0c1c8e22 | |||
7cb96c47a9 | |||
b78de543d8 | |||
a91b700e38 | |||
55ee36b0c4 | |||
e31dc4717c | |||
ad16388d69 | |||
48de23e548 | |||
8015f3f6d4 | |||
e9c5ff3d27 | |||
d8d1f6661d | |||
d4a3490a00 | |||
6f68283991 | |||
75d928ef29 | |||
0527053262 | |||
9a0f88b5fd | |||
0720bb7e4d | |||
b2b02a4843 | |||
6027747aae | |||
2da602fa1f | |||
561c363074 | |||
4779bc6c0b | |||
3ae63c2c55 | |||
764942a2dd | |||
84096dccd6 | |||
3efc2919d0 | |||
eff8f7a9b4 | |||
eda1ffacf1 | |||
7aa9d75211 | |||
92df3ca898 | |||
a9da96ac2a | |||
9ef62f5078 | |||
c6fa62aacc | |||
da29388b53 | |||
55ec21db57 | |||
3325965cb3 | |||
248d08c598 | |||
379e5098a4 | |||
7785b38ac9 | |||
0931171f54 | |||
58bba221b7 | |||
02c621f3f7 | |||
146af6a45b | |||
178dbd4442 | |||
b9b86dc4f6 | |||
15f5b04e43 | |||
88a7d4aa30 | |||
fd5c9bedbc | |||
c5bbf36c13 | |||
3f0d3dfa0e | |||
fb48f1e298 | |||
8b8b52ff0c | |||
13dcf62877 | |||
17ad8ce7b3 | |||
31ea1d2e07 | |||
f66c2b32cc | |||
a387f2ee2e | |||
1560fd4225 | |||
9a603fe191 | |||
a9e5186075 | |||
d61b2e28e6 | |||
53aabb978e | |||
e3fe63ddeb | |||
67e0e4caa5 | |||
df77614e54 | |||
e61088c858 | |||
b585238d33 | |||
020ec96304 | |||
21e1dc286e | |||
20b292d0cd | |||
4ad1bd63b2 | |||
4e51155487 | |||
c2d1cf1bce | |||
e590894536 | |||
0785c619a5 | |||
42fe8ca453 | |||
140674a460 | |||
e2747dbb5a | |||
d15d0d3d8a | |||
ab06012876 | |||
d21d270676 | |||
e690b81038 | |||
db83d69608 | |||
2bca741149 | |||
88e47d1959 | |||
d4945b1027 | |||
d77f9b1eff | |||
b6e360874f | |||
6899e6789a | |||
b23c5b9722 | |||
35ed29f207 | |||
13a506d4f5 | |||
3cbd54b92f | |||
6c33d7b2b1 | |||
647340b0ce | |||
dd0911859f | |||
c3f76ef89d | |||
bea1f51d6e | |||
c9f473df33 | |||
44f43f94ce | |||
6f7bc7196f | |||
867cb9f60c | |||
eb0b79586f | |||
b845de89d0 | |||
7a7752095c | |||
1c05df6998 | |||
d98d7e3005 | |||
c4edb49b4f | |||
b6b240f94f | |||
44bc78790e | |||
ba1184630a | |||
c09441c321 | |||
de0e11902b | |||
e3bc957706 | |||
0771671c4b | |||
ca61b84586 | |||
b6ce961a42 | |||
cd473d41dd | |||
a70860f449 | |||
f058cb69d1 | |||
da82d2e3a0 | |||
7e8c83f7d4 | |||
9307d7c7a4 | |||
28092a3938 | |||
d047439952 | |||
2e151d26ca | |||
92a4d30e04 | |||
334c13e106 | |||
72d4f133e9 | |||
b62a0c5603 | |||
fa97e37282 | |||
e8a74c9a07 | |||
6a2dc768f0 | |||
6578cacb46 | |||
eaa7115d60 | |||
b55d6622d4 | |||
fbc3e1267a | |||
5ab6a0e1c8 | |||
c06635ea3f | |||
3af6c521d9 | |||
3ce3274a5e | |||
6932f4bfe5 | |||
1159fc3230 | |||
0d49b82e4f | |||
e2bfd172e4 | |||
bb56ce816b | |||
982b0a5778 | |||
0dd0d42ab5 | |||
740b870dc8 | |||
7bb8dd9f98 | |||
319138d3f6 | |||
b7ae5efb79 | |||
5cc25cff5d | |||
6573ae8c85 | |||
089285b42c | |||
96201ae7bf | |||
caf8b3872a | |||
c487970ac8 | |||
90683caedf | |||
e6ae24e1d6 | |||
2255a2b107 | |||
5c3cdebf95 | |||
532f907b75 | |||
dcaa939365 | |||
a18a9bde36 | |||
be746104d1 | |||
01726b6d23 | |||
bff2811c6d | |||
224752eced | |||
b261a30c90 | |||
30d277ed7a | |||
ae1ef911a9 | |||
ef3e73c6a0 | |||
793c59da13 | |||
004f9776f4 | |||
1f304300ff | |||
d4633b36b9 | |||
856cf5abf7 | |||
10dc8c561c | |||
0db89a661f | |||
bd9da7b1da | |||
e157c8f9ed | |||
272a1db63a | |||
061cbbc111 | |||
2dfd81aaf5 | |||
42bec8c810 | |||
2e0cbfcbed | |||
a36a0f1d81 | |||
c5d970a01e | |||
746dda63b2 | |||
28978df0bd | |||
1485e8bbc8 | |||
4c7e107810 | |||
eb97f13839 | |||
d315bd2286 | |||
ee78edceca | |||
dd917bae85 | |||
f95e80d832 | |||
7061294be5 | |||
cee5b0441a | |||
8e4cb8fbce | |||
4b69fab6e2 | |||
265eabc905 | |||
97e2b622d1 | |||
375e9b190e | |||
71a4041541 | |||
c02bdb276b | |||
31e8a47b62 | |||
6af76adbbf | |||
126115a9fb | |||
6d95eff882 | |||
484e869dfd | |||
f94487284b | |||
59935c3813 | |||
cc5faa780d | |||
7c4ab1c2ef | |||
9fb629edd7 | |||
3cdfedc20e | |||
8d676f54ff | |||
f2d262e402 | |||
666923359e | |||
8501bb0c05 | |||
f69a2b9a42 | |||
73b604bb1e | |||
029677943f | |||
337fda061c | |||
872f953262 | |||
21f984cede | |||
e9d62effa3 | |||
388f9a9355 | |||
3ab9d60fcb | |||
3d39107f2d | |||
391610903b | |||
e7bd0dd26d | |||
47343af304 | |||
b9bdfc7285 | |||
6c8dd15c4a | |||
098af8b408 | |||
6c4efc0509 | |||
404250c8f7 | |||
1a110fcd4e | |||
e6a12a0fc8 | |||
4ecb1ba5ef | |||
c8b94334ca | |||
4e56034b5e | |||
0cbf1b772b | |||
397f1f4138 | |||
a2dd544f85 | |||
99e5cf5574 | |||
be7dc48727 | |||
1aa2cf0521 | |||
d3d560e0f0 | |||
fedd32d82f | |||
0a1b6d0be3 | |||
29d59baa39 | |||
124b3f9289 | |||
98ee0c68a2 | |||
28f4616fde | |||
e176bafc9d | |||
b6490426e3 | |||
d49fe0ca20 | |||
e691d80e37 | |||
61a85646eb | |||
435a05aff5 | |||
483449c9da | |||
b6104becb9 | |||
355b181f74 | |||
d11e235976 | |||
d448574e73 | |||
5e9a8a6dfb | |||
cabd0de9f6 | |||
662b42db76 | |||
4eea8f0136 | |||
544cb0132d | |||
b470520d75 | |||
1c48866e04 | |||
a4d2ddb947 | |||
91d95113d0 | |||
64e25d4b06 | |||
b465a81100 | |||
cc28ab7a1d | |||
36c50bd5d5 | |||
2cfec1d840 | |||
1b840718f7 | |||
5ec3033154 | |||
d150439b72 | |||
1b0db1ec87 | |||
fdce11226c | |||
f714fd67f2 | |||
fb2a1a36a2 | |||
12a0c11e81 | |||
8d9698ecf8 | |||
6133e72c00 | |||
a13967f2a3 | |||
8a7ca9923e | |||
990ab937c2 | |||
8c610e6075 | |||
8577d63cd8 | |||
76e8aac158 | |||
b96b44feab | |||
0af7f8e6a9 | |||
1366cd58cd | |||
dc0dae2d18 | |||
d00719485f | |||
09af9bd9be | |||
978b9d511f | |||
8d57088335 | |||
375683654d | |||
aa49066fe6 | |||
0166dad496 | |||
ffddac3e0f | |||
1946bee22a | |||
d4fae44d0d | |||
adad542ba1 | |||
c527aecd48 | |||
dc7e206ac6 | |||
4f808c62a3 | |||
5692db78a8 | |||
ed038688bf | |||
2363c69260 | |||
8ead7af22b | |||
cf299745ae | |||
0e0ae47da6 | |||
8cadcaa13d | |||
3cb6315933 | |||
0ec33398b4 | |||
a46e4738f5 | |||
4ae3b05a5a | |||
c26e291375 | |||
6ad819c1ab | |||
207414cba4 | |||
004ce0ab04 | |||
5550f4d33b | |||
2c1e9f1dc5 | |||
da29cc0e98 | |||
3b87d72874 | |||
eb520b93d2 | |||
31e97bdae2 | |||
a3212009d9 | |||
b70c4fdcde | |||
264eccb5df | |||
2bdc90429a | |||
24cf727265 | |||
e3c7db50ca | |||
8670a4ce67 | |||
e18bc21d6a | |||
5e0b708f74 | |||
e4dfb2ffa3 | |||
324931009e | |||
653fb710ce | |||
26442d11e6 | |||
f82b827c92 | |||
29d14d3a30 | |||
93edd1887e | |||
92e9c44f20 | |||
709b163940 | |||
73e3cb6c7e | |||
694bfd6ff5 | |||
30f0ec8d80 | |||
870ee2f6c8 | |||
6a9d0c1753 | |||
4a57aeaa7e | |||
6038e7a2c2 | |||
e556cebb2f | |||
a482f08d99 | |||
d30886d24c | |||
1c03498a25 | |||
69f8ef04a8 | |||
4c5e875ec1 | |||
39d76b2596 | |||
d3095addf3 | |||
cd09c38465 | |||
015be4075f | |||
a7d977040b | |||
d25fd8710d | |||
19c87b7d44 | |||
c4add64fd4 | |||
b9b7406c43 | |||
f77e3faa04 | |||
5d0a827122 | |||
9380177354 | |||
b65afdde74 | |||
5d1af380d3 | |||
9c1f455f5f | |||
cc942105ed | |||
ae511331e0 | |||
151c270899 | |||
cf0d09ca7b | |||
f1567720b1 | |||
61915c4144 | |||
244be783ae | |||
70c2f10fde | |||
5df413119e | |||
091ab12b34 | |||
69e95b9efe | |||
c63e13055a | |||
c640186ec8 | |||
2d8ca4f90e | |||
ebb3cc35f5 | |||
d8ab884fe9 | |||
52dbaaeace | |||
ffa51b3bde | |||
71dd80f14f | |||
2793a49565 | |||
2e14ee75c0 | |||
1d058c3e86 | |||
d8be01079b | |||
3a7a676114 | |||
9641a7f975 | |||
a8c77eba37 | |||
aec99d9bc3 | |||
dd5c7e3c52 | |||
3f3daf8930 | |||
fb97626fe0 | |||
4fc6912b96 | |||
e97c78c546 | |||
a6e9a9c025 | |||
00b51fcb1e | |||
86b3bee2f3 | |||
440121b542 | |||
ea9af51479 | |||
7faece6985 | |||
698d3d7726 | |||
b5701a4c7a | |||
4168137537 | |||
a09df5d2e1 | |||
ed0dce7d54 | |||
f56ed0e51d | |||
32b0a492d5 | |||
5648836987 | |||
8028b2907e | |||
5c06585528 | |||
28d7eea97e | |||
7bcb021a6d | |||
414d7d11e6 | |||
a62fb4229d | |||
1b461403ee | |||
067503a8c6 | |||
317d84abe3 | |||
f94345d9ea | |||
859e09523d | |||
cdfc7ed34f | |||
2ace920de1 | |||
06dc822d04 | |||
e8453aa373 | |||
0b143fa43e | |||
a7632e913c | |||
503248ccdf | |||
7513559926 | |||
46db105b7b | |||
0c5c45a133 | |||
5ffcbc4690 | |||
cbccf99592 | |||
020bb4b46d | |||
63d92674d2 | |||
547067dd86 | |||
c1a42bb0e2 | |||
6847329af2 | |||
53ea57fea4 | |||
6c02386403 | |||
17f65e4063 | |||
a13947b2fa | |||
78ab44cb96 | |||
aad9cba85f | |||
48a83481d2 | |||
ad40eb4e6c | |||
019f513a19 | |||
5ba203b54e | |||
4535fc312b | |||
d4e0b9607c | |||
5a6d764e1d | |||
82c65f14d4 | |||
a048af3c90 | |||
53b40c9c6d | |||
60835c96cd | |||
1371e15fff | |||
d181539b83 | |||
f034c05cc4 | |||
9b851fd6b2 | |||
7e6f150b69 | |||
7b453107f8 | |||
739adc8ba4 | |||
9b1ba18677 | |||
f2a8fae3f6 | |||
1bd632db77 | |||
354ef14cf5 | |||
0716b2390f | |||
f04e7547cd | |||
d05ff36c20 | |||
56aa9d19d8 | |||
647aa7110f | |||
5a677bbc45 | |||
1fde2b9d5b | |||
32ed3624fa | |||
fbc9cb4c8b | |||
57e7b66ab9 | |||
7f0b28415c | |||
20da7ca42a | |||
3b49d0a598 | |||
30937f2f98 | |||
7b7508ad78 | |||
e88a5b9833 | |||
0d7601e546 | |||
437eb3f7a8 | |||
e2db781f0c | |||
13e5492bfd | |||
8a2732186a | |||
0731236fc1 | |||
43c3df7846 | |||
88a363009a | |||
13ed9e5fc0 | |||
449a6e4934 | |||
0bbed0664f | |||
6995a1b79b | |||
cf845a749a | |||
0afa1d08f1 | |||
fefcf90c33 | |||
9f7e0d0ade | |||
3ef8bfc2b3 | |||
f4571f24d1 | |||
e4bb269a85 | |||
3caf1e2e22 | |||
5894fb1fa2 | |||
68d18bef41 | |||
4de7047976 | |||
c45f678a1e | |||
9711c9230b | |||
6587e08d3a | |||
0020157a98 | |||
fb040cced3 | |||
61bacc0fa1 | |||
5277540e37 | |||
3a4a6ead32 | |||
19c50eb61c | |||
8714978781 | |||
f8422f1e0b | |||
9b3ca509ab | |||
b098f5e9e9 | |||
1c0eb91503 | |||
a80e887819 | |||
c9db7bf10a | |||
39936d3393 | |||
7f7f511c5a | |||
24758e993a | |||
a5110b8955 | |||
43bec9ea3d | |||
5d8648345c | |||
5dc2699d10 | |||
313d2ec991 | |||
c76028a6ff | |||
5b035defa8 | |||
bade7f423b | |||
f2bd39fb60 | |||
095db69d4c | |||
c85ac5245c | |||
3196253710 | |||
01ea2ad59c | |||
3a68156778 | |||
e8db4f9c53 | |||
bb4e939253 | |||
feea651448 | |||
422e93e1de | |||
9f2d50f145 | |||
d9800046ea | |||
340f8f4565 | |||
26f5961f3e | |||
7f293b25d6 | |||
ca04956e1b | |||
667aa7ccbf | |||
0414377c02 | |||
e2c1104c50 | |||
f96dd8185d | |||
5764abda7c | |||
9275bb82ca | |||
bcab901b7c | |||
98f2808115 | |||
292e540854 | |||
056b0f1b20 | |||
3633d5309f | |||
e0eacd7daa | |||
94b7df5c4a | |||
f0f7140150 | |||
65904cdbb3 | |||
e17f459af2 | |||
be01087e07 | |||
e6042aec1b | |||
a3741780fe | |||
4698f544d2 | |||
14132666fa | |||
b88d95bb5b | |||
2d0c42fdf2 | |||
e3f8605a23 | |||
9565ab67c2 | |||
1a9369ef10 | |||
b4b9496b3c | |||
c9fa9762e8 | |||
de6859ec0c | |||
e4e27351e8 | |||
8665226464 | |||
c2db6a86a2 | |||
ef0460b852 | |||
bfe36cb4ef | |||
dcf51c05e8 | |||
aa1b377e71 | |||
2eea9c6fdf | |||
ee52b81c94 | |||
8834e10b30 | |||
e188ecc8b4 | |||
aa211bb6ef | |||
6bbd4de3bf | |||
34ceda3e93 | |||
92b9639503 | |||
6a0b48873b | |||
c3d92cff58 | |||
548c9669df | |||
bbb8a81858 | |||
e557442e3f | |||
9001b750df | |||
656419f922 | |||
137c2c6eff | |||
7f79b736b0 | |||
22f89fea1e | |||
9b484b33ba | |||
9a10c305a1 | |||
def0c5e181 | |||
aaaa7fd4d1 | |||
ce5855a8fa | |||
c6486c3fa9 | |||
1b647d65be | |||
b7ce4f93d5 | |||
7ed9c63d9e | |||
fdb056373c | |||
53936785b7 | |||
bdb54bfd83 | |||
eca948f6f3 | |||
e848b58d7c | |||
744ad444e5 | |||
3887820e5f | |||
1b0d659e6d | |||
ffde22468e | |||
92c19c68cb | |||
d7c9de51d2 | |||
012809cdca | |||
4b68cef04c | |||
479613bd06 | |||
60b12e69fb | |||
9bedaec05b | |||
1facb8fdef | |||
a44f558a84 | |||
6074f57e5b | |||
c25f146d8d | |||
8c30327deb | |||
91e4bcb313 | |||
50528537b2 | |||
ff2655d1a4 | |||
e43d0884ed | |||
7ff0459739 | |||
d0da48f112 | |||
b87f31f034 | |||
98625337e4 | |||
1f6fe5cb03 | |||
3e07c65641 | |||
91e2b4b6ec | |||
b630feee02 | |||
3d2f7953b2 | |||
9132a31b9c | |||
02539e9008 | |||
b3ee616e67 | |||
210b29fa99 | |||
a8ae714d4a | |||
17bd834eb5 | |||
dbd546a32d | |||
cb38ace647 | |||
3d9d66ad76 | |||
3d83274967 | |||
31830b0702 | |||
97e60818b6 | |||
f1d6c1eba1 | |||
8d6193902f | |||
12d99b8f23 | |||
23d982e205 | |||
79f802a50e | |||
386ca8abf7 | |||
5e6b870a53 | |||
e94d04a01b | |||
6ff53d2a13 | |||
d35773d5c0 | |||
21a23e6966 | |||
1da651cdb7 | |||
d9269d6913 | |||
e77966b341 | |||
c2e38a520e | |||
3bd5c994c8 | |||
82d0007750 | |||
5d29e2d020 | |||
9a6c4ac68e | |||
133891b712 | |||
75e92c1354 | |||
26824851b0 | |||
425df6923e | |||
77e42ca4df | |||
813c2b1525 | |||
f08715947a | |||
35f9d7c41b | |||
a0a49eb87c | |||
540fd45f75 | |||
d3c9e40abc | |||
0a81a98e90 | |||
9af8a299ce | |||
5b86bbf891 | |||
c7195b9ec3 | |||
e906346dcb | |||
a35de0aff3 | |||
256c4470f8 | |||
9c6f3545ae | |||
3c92912885 | |||
abc16e2531 | |||
d9a4084544 | |||
f45e3a4afa | |||
bceaf6952a | |||
48aa2edf5d | |||
f7f1b33282 | |||
bdafda8c45 | |||
df667535ed | |||
7da5f343bc | |||
3ed1c78466 | |||
627d1d6693 | |||
f43a14e3cf | |||
f56d52c7f5 | |||
c267eb889f | |||
0622a7b1b2 | |||
0a4aa20e8d | |||
88228db38e | |||
6511277827 | |||
01356d2963 | |||
c8edb70945 | |||
00217f1919 | |||
db77d8f7ee | |||
d45cf5ffdf | |||
422fe85cc3 | |||
e46e3040fc | |||
e18ac66d84 | |||
cae974bea2 | |||
0f01cec52f | |||
acfd555795 | |||
0060e0a694 | |||
654dc3ed85 | |||
a4a2258a1f | |||
20286e168b | |||
3900a63e3a | |||
03013d999c | |||
1a99203052 | |||
89f569ae8e | |||
00b8bf7eda | |||
322969adf1 | |||
239b50a863 | |||
3a9f932d80 | |||
7fe5022f28 | |||
763e0f0a72 | |||
6e9f7e5e3d | |||
45bc28172f | |||
8f22a331b9 | |||
2d233af64b | |||
58ae92a993 | |||
82808b4226 | |||
493f2c6931 | |||
cdc686223a | |||
102da0255b | |||
bd7c73ba77 | |||
a2433243fb | |||
8927e27777 | |||
b90beadfae | |||
4260c47867 | |||
9af1064995 | |||
b16fd231f6 | |||
fd708fe0e1 | |||
567bc4b4ae | |||
a4cfb842fc | |||
394e8e4bf5 | |||
3ee4f6cb36 | |||
e1d24410da | |||
14c7ed8b51 | |||
365fdb0f93 | |||
8c91934019 | |||
b7b3a5f99b | |||
5ebec96f28 | |||
4e3600b038 | |||
3b18b80aff | |||
9b52b06f96 | |||
dafce295e6 | |||
82e0b2f043 | |||
8cb890364b | |||
6aa48ab791 | |||
915f0831d8 | |||
cde194be8d | |||
6ff7c838d0 | |||
cfd73e0065 | |||
28dd887d68 | |||
037d86dd7a | |||
344f615df9 | |||
4ef72fe022 | |||
40e2e3ca33 | |||
321b078889 | |||
0ae52d4fd1 | |||
8035edbe12 | |||
bb78cfbec0 | |||
68d720fd92 | |||
7191dd3c59 | |||
b1d3895fb9 | |||
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 |
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,17 +2,20 @@
|
||||
# Azure Pipeline build file for a build using ubuntu and GCC5
|
||||
#
|
||||
# Copyright (c) Microsoft Corporation.
|
||||
# Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
|
||||
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
##
|
||||
trigger:
|
||||
- master
|
||||
- stable/*
|
||||
pr:
|
||||
- master
|
||||
- stable/*
|
||||
|
||||
jobs:
|
||||
- template: templates/pr-gate-build-job.yml
|
||||
parameters:
|
||||
tool_chain_tag: 'GCC5'
|
||||
vm_image: 'ubuntu-latest'
|
||||
arch_list: "IA32,X64,ARM,AARCH64"
|
||||
arch_list: "IA32,X64,ARM,AARCH64,RISCV64"
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
# NOTE: This example monitors pull requests against the edk2-ci branch. Most
|
||||
# environments would replace 'edk2-ci' with 'master'.
|
||||
#
|
||||
# Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
|
||||
# Copyright (c) 2019 - 2020, Intel Corporation. All rights reserved.<BR>
|
||||
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
#
|
||||
# https://github.com/tianocore
|
||||
@ -16,6 +16,7 @@ trigger: none
|
||||
|
||||
pr:
|
||||
- master
|
||||
- stable/*
|
||||
|
||||
pool:
|
||||
vmImage: 'ubuntu-latest'
|
||||
|
@ -6,9 +6,11 @@
|
||||
##
|
||||
trigger:
|
||||
- master
|
||||
- stable/*
|
||||
|
||||
pr:
|
||||
- master
|
||||
- stable/*
|
||||
|
||||
jobs:
|
||||
- template: templates/pr-gate-build-job.yml
|
||||
|
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())
|
||||
```
|
143
.azurepipelines/templates/platform-build-run-steps.yml
Normal file
143
.azurepipelines/templates/platform-build-run-steps.yml
Normal file
@ -0,0 +1,143 @@
|
||||
|
||||
## @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 }}"
|
||||
|
||||
# Use altername cmocka repo
|
||||
- bash: git config --global url.https://github.com/neverware-mirrors/cmocka.git.insteadOf https://git.cryptomilk.org/projects/cmocka.git
|
||||
|
||||
# Fetch the target branch so that pr_eval can diff them.
|
||||
# Seems like azure pipelines/github changed checkout process in nov 2020.
|
||||
- script: git fetch origin $(System.PullRequest.targetBranch)
|
||||
displayName: fetch target branch
|
||||
condition: eq(variables['Build.Reason'], 'PullRequest')
|
||||
|
||||
# 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()
|
@ -4,6 +4,7 @@
|
||||
# template file used to build supported packages.
|
||||
#
|
||||
# Copyright (c) Microsoft Corporation.
|
||||
# Copyright (c) 2020 - 2021, ARM Limited. All rights reserved.<BR>
|
||||
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
##
|
||||
|
||||
@ -30,20 +31,25 @@ jobs:
|
||||
Build.Pkgs: 'MdeModulePkg'
|
||||
Build.Targets: 'RELEASE,NO-TARGET'
|
||||
TARGET_NETWORK:
|
||||
Build.Pkgs: 'NetworkPkg'
|
||||
Build.Pkgs: 'NetworkPkg,RedfishPkg'
|
||||
Build.Targets: 'DEBUG,RELEASE,NO-TARGET'
|
||||
TARGET_OTHER:
|
||||
Build.Pkgs: 'PcAtChipsetPkg,ShellPkg'
|
||||
Build.Pkgs: 'PcAtChipsetPkg,ShellPkg,StandaloneMmPkg'
|
||||
Build.Targets: 'DEBUG,RELEASE,NO-TARGET'
|
||||
TARGET_FMP_FAT_TEST:
|
||||
Build.Pkgs: 'FmpDevicePkg,FatPkg,UnitTestFrameworkPkg'
|
||||
Build.Pkgs: 'FmpDevicePkg,FatPkg,UnitTestFrameworkPkg,DynamicTablesPkg'
|
||||
Build.Targets: 'DEBUG,RELEASE,NO-TARGET,NOOPT'
|
||||
TARGET_CRYPTO:
|
||||
Build.Pkgs: 'CryptoPkg'
|
||||
Build.Targets: 'DEBUG,RELEASE,NO-TARGET'
|
||||
Build.Targets: 'DEBUG,RELEASE,NO-TARGET,NOOPT'
|
||||
TARGET_SECURITY:
|
||||
Build.Pkgs: 'SecurityPkg'
|
||||
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:
|
||||
clean: all
|
||||
|
@ -20,7 +20,7 @@ steps:
|
||||
|
||||
- task: UsePythonVersion@0
|
||||
inputs:
|
||||
versionSpec: '3.7.x'
|
||||
versionSpec: '3.8.x'
|
||||
architecture: 'x64'
|
||||
|
||||
- script: pip install -r pip-requirements.txt --upgrade
|
||||
@ -31,6 +31,15 @@ steps:
|
||||
echo "##vso[task.setvariable variable=pkgs_to_build]${{ parameters.build_pkgs }}"
|
||||
echo "##vso[task.setvariable variable=pkg_count]${{ 1 }}"
|
||||
|
||||
# Use altername cmocka repo
|
||||
- bash: git config --global url.https://github.com/neverware-mirrors/cmocka.git.insteadOf https://git.cryptomilk.org/projects/cmocka.git
|
||||
|
||||
# Fetch the target branch so that pr_eval can diff them.
|
||||
# Seems like azure pipelines/github changed checkout process in nov 2020.
|
||||
- script: git fetch origin $(System.PullRequest.targetBranch)
|
||||
displayName: fetch target branch
|
||||
condition: eq(variables['Build.Reason'], 'PullRequest')
|
||||
|
||||
# trim the package list if this is a PR
|
||||
- task: CmdLine@1
|
||||
displayName: Check if ${{ parameters.build_pkgs }} need testing
|
||||
@ -39,11 +48,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}"
|
||||
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
|
||||
- template: spell-check-prereq-steps.yml
|
||||
|
||||
@ -62,6 +66,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}}
|
||||
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
|
||||
displayName: Build and Test ${{ parameters.build_pkgs }} ${{ parameters.build_archs}}
|
||||
inputs:
|
||||
|
13
.gitmodules
vendored
13
.gitmodules
vendored
@ -7,3 +7,16 @@
|
||||
[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
|
||||
[submodule "RedfishPkg/Library/JsonLib/jansson"]
|
||||
path = RedfishPkg/Library/JsonLib/jansson
|
||||
url = https://github.com/akheron/jansson
|
||||
|
17
.mailmap
17
.mailmap
@ -1,8 +1,7 @@
|
||||
#
|
||||
# This list is used by git-shortlog to fix a few botched name translations
|
||||
# in the git archive, either because the author's full name was messed up
|
||||
# and/or not always written the same way, making contributions from the
|
||||
# same person appearing not to be so or badly displayed.
|
||||
# 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:
|
||||
@ -23,6 +22,8 @@ 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>
|
||||
@ -37,6 +38,7 @@ 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 <gaoliming@byosoft.com.cn>
|
||||
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>
|
||||
@ -46,6 +48,7 @@ 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>
|
||||
Matt DeVillier <matt.devillier@gmail.com>
|
||||
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>
|
||||
@ -59,14 +62,20 @@ 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>
|
||||
Rebecca Cran <rebecca@bluestop.org>
|
||||
Rebecca Cran <rebecca@bsdio.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>
|
||||
Tom Lendacky <thomas.lendacky@amd.com>
|
||||
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>
|
||||
Wei6 Xu <wei6.xu@intel.com>
|
||||
Yonghong Zhu <yonghong.zhu@intel.com>
|
||||
Yonghong Zhu <yonghong.zhu@intel.com> <yzhu52@Edk2>
|
||||
Yu-Chen Lin <yuchenlin@synology.com>
|
||||
Zhichao Gao <zhichao.gao@intel.com>
|
||||
Zhiguang Liu <zhiguang.liu@intel.com>
|
||||
|
@ -16,7 +16,7 @@
|
||||
# * This file must be checked into the 'default' branch of a repo. Copies
|
||||
# of this file on other branches of a repo are ignored by Mergify.
|
||||
#
|
||||
# Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
|
||||
# Copyright (c) 2019 - 2020, Intel Corporation. All rights reserved.<BR>
|
||||
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
#
|
||||
# https://github.com/apps/mergify
|
||||
@ -28,7 +28,7 @@ pull_request_rules:
|
||||
|
||||
- name: Automatically merge a PR when all required checks pass and 'push' label is present
|
||||
conditions:
|
||||
- base=master
|
||||
- base~=(^master|^stable/)
|
||||
- label=push
|
||||
- author=@tianocore/edk-ii-maintainers
|
||||
- status-success=tianocore.PatchCheck
|
||||
@ -41,7 +41,7 @@ pull_request_rules:
|
||||
|
||||
- name: Automatically close a PR when all required checks pass and 'push' label is not present
|
||||
conditions:
|
||||
- base=master
|
||||
- base~=(^master|^stable/)
|
||||
- -label=push
|
||||
- -closed
|
||||
- status-success=tianocore.PatchCheck
|
||||
@ -55,7 +55,7 @@ pull_request_rules:
|
||||
|
||||
- name: Post a comment on a PR that can not be merged due to a merge conflict
|
||||
conditions:
|
||||
- base=master
|
||||
- base~=(^master|^stable/)
|
||||
- conflict
|
||||
actions:
|
||||
comment:
|
||||
@ -63,7 +63,7 @@ pull_request_rules:
|
||||
|
||||
- name: Automatically close a PR that fails the EDK II Maintainers membership check and 'push' label is present
|
||||
conditions:
|
||||
- base=master
|
||||
- base~=(^master|^stable/)
|
||||
- label=push
|
||||
- -author=@tianocore/edk-ii-maintainers
|
||||
actions:
|
||||
@ -72,7 +72,7 @@ pull_request_rules:
|
||||
|
||||
- name: Post a comment on a PR if PatchCheck fails
|
||||
conditions:
|
||||
- base=master
|
||||
- base~=(^master|^stable/)
|
||||
- status-failure=tianocore.PatchCheck
|
||||
actions:
|
||||
comment:
|
||||
@ -80,7 +80,7 @@ pull_request_rules:
|
||||
|
||||
- name: Post a comment on a PR if Ubuntu GCC5 fails
|
||||
conditions:
|
||||
- base=master
|
||||
- base~=(^master|^stable/)
|
||||
- status-failure=Ubuntu GCC5 PR
|
||||
- status-success=Ubuntu GCC5 PR (FAILED)
|
||||
actions:
|
||||
@ -89,7 +89,7 @@ pull_request_rules:
|
||||
|
||||
- name: Post a comment on a PR if Windows VS2019 fails
|
||||
conditions:
|
||||
- base=master
|
||||
- base~=(^master|^stable/)
|
||||
- status-failure=Windows VS2019 PR
|
||||
- status-success=Windows VS2019 PR (FAILED)
|
||||
actions:
|
||||
|
@ -1,6 +1,8 @@
|
||||
# @file
|
||||
#
|
||||
# Copyright (c) Microsoft Corporation.
|
||||
# Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
|
||||
# Copyright (c) 2020 - 2021, ARM Limited. All rights reserved.<BR>
|
||||
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
##
|
||||
import os
|
||||
@ -20,16 +22,24 @@ class Settings(CiBuildSettingsManager, UpdateSettingsManager, SetupSettingsManag
|
||||
self.ActualTargets = []
|
||||
self.ActualArchitectures = []
|
||||
self.ActualToolChainTag = ""
|
||||
self.UseBuiltInBaseTools = None
|
||||
self.ActualScopes = None
|
||||
|
||||
# ####################################################################################### #
|
||||
# Extra CmdLine configuration #
|
||||
# ####################################################################################### #
|
||||
|
||||
def AddCommandLineOptions(self, parserObj):
|
||||
pass
|
||||
group = parserObj.add_mutually_exclusive_group()
|
||||
group.add_argument("-force_piptools", "--fpt", dest="force_piptools", action="store_true", default=False, help="Force the system to use pip tools")
|
||||
group.add_argument("-no_piptools", "--npt", dest="no_piptools", action="store_true", default=False, help="Force the system to not use pip tools")
|
||||
|
||||
def RetrieveCommandLineOptions(self, args):
|
||||
pass
|
||||
super().RetrieveCommandLineOptions(args)
|
||||
if args.force_piptools:
|
||||
self.UseBuiltInBaseTools = True
|
||||
if args.no_piptools:
|
||||
self.UseBuiltInBaseTools = False
|
||||
|
||||
# ####################################################################################### #
|
||||
# Default Support for this Ci Build #
|
||||
@ -39,7 +49,10 @@ class Settings(CiBuildSettingsManager, UpdateSettingsManager, SetupSettingsManag
|
||||
''' return iterable of edk2 packages supported by this build.
|
||||
These should be edk2 workspace relative paths '''
|
||||
|
||||
return ("MdePkg",
|
||||
return ("ArmVirtPkg",
|
||||
"DynamicTablesPkg",
|
||||
"EmulatorPkg",
|
||||
"MdePkg",
|
||||
"MdeModulePkg",
|
||||
"NetworkPkg",
|
||||
"PcAtChipsetPkg",
|
||||
@ -47,17 +60,22 @@ class Settings(CiBuildSettingsManager, UpdateSettingsManager, SetupSettingsManag
|
||||
"UefiCpuPkg",
|
||||
"FmpDevicePkg",
|
||||
"ShellPkg",
|
||||
"StandaloneMmPkg",
|
||||
"FatPkg",
|
||||
"CryptoPkg",
|
||||
"UnitTestFrameworkPkg"
|
||||
"UnitTestFrameworkPkg",
|
||||
"OvmfPkg",
|
||||
"RedfishPkg"
|
||||
)
|
||||
|
||||
def GetArchitecturesSupported(self):
|
||||
''' return iterable of edk2 architectures supported by this build '''
|
||||
return ("IA32",
|
||||
return (
|
||||
"IA32",
|
||||
"X64",
|
||||
"ARM",
|
||||
"AARCH64")
|
||||
"AARCH64",
|
||||
"RISCV64")
|
||||
|
||||
def GetTargetsSupported(self):
|
||||
''' return iterable of edk2 target tags supported by this build '''
|
||||
@ -118,20 +136,38 @@ class Settings(CiBuildSettingsManager, UpdateSettingsManager, SetupSettingsManag
|
||||
|
||||
def GetActiveScopes(self):
|
||||
''' return tuple containing scopes that should be active for this process '''
|
||||
if self.ActualScopes is None:
|
||||
scopes = ("cibuild", "edk2-build", "host-based-test")
|
||||
|
||||
self.ActualToolChainTag = shell_environment.GetBuildVars().GetValue("TOOL_CHAIN_TAG", "")
|
||||
|
||||
if GetHostInfo().os.upper() == "WINDOWS":
|
||||
scopes += ('host-test-win',)
|
||||
is_linux = GetHostInfo().os.upper() == "LINUX"
|
||||
|
||||
if GetHostInfo().os.upper() == "LINUX" and self.ActualToolChainTag.upper().startswith("GCC"):
|
||||
if self.UseBuiltInBaseTools is None:
|
||||
is_linux = GetHostInfo().os.upper() == "LINUX"
|
||||
# try and import the pip module for basetools
|
||||
try:
|
||||
import edk2basetools
|
||||
self.UseBuiltInBaseTools = True
|
||||
except ImportError:
|
||||
self.UseBuiltInBaseTools = False
|
||||
pass
|
||||
|
||||
if self.UseBuiltInBaseTools == True:
|
||||
scopes += ('pipbuild-unix',) if is_linux else ('pipbuild-win',)
|
||||
logging.warning("Using Pip Tools based BaseTools")
|
||||
else:
|
||||
logging.warning("Falling back to using in-tree BaseTools")
|
||||
|
||||
if is_linux and self.ActualToolChainTag.upper().startswith("GCC"):
|
||||
if "AARCH64" in self.ActualArchitectures:
|
||||
scopes += ("gcc_aarch64_linux",)
|
||||
if "ARM" in self.ActualArchitectures:
|
||||
scopes += ("gcc_arm_linux",)
|
||||
|
||||
return scopes
|
||||
if "RISCV64" in self.ActualArchitectures:
|
||||
scopes += ("gcc_riscv64_unknown",)
|
||||
self.ActualScopes = scopes
|
||||
return self.ActualScopes
|
||||
|
||||
def GetRequiredSubmodules(self):
|
||||
''' return iterable containing RequiredSubmodule objects.
|
||||
@ -144,6 +180,14 @@ class Settings(CiBuildSettingsManager, UpdateSettingsManager, SetupSettingsManag
|
||||
"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))
|
||||
rs.append(RequiredSubmodule(
|
||||
"RedfishPkg/Library/JsonLib/jansson", False))
|
||||
return rs
|
||||
|
||||
def GetName(self):
|
||||
|
309
.pytool/Plugin/EccCheck/EccCheck.py
Normal file
309
.pytool/Plugin/EccCheck/EccCheck.py
Normal file
@ -0,0 +1,309 @@
|
||||
# @file EccCheck.py
|
||||
#
|
||||
# Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
|
||||
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
##
|
||||
|
||||
import os
|
||||
import shutil
|
||||
import re
|
||||
import csv
|
||||
import xml.dom.minidom
|
||||
from typing import List, Dict, Tuple
|
||||
import logging
|
||||
from io import StringIO
|
||||
from edk2toolext.environment import shell_environment
|
||||
from edk2toolext.environment.plugintypes.ci_build_plugin import ICiBuildPlugin
|
||||
from edk2toolext.environment.var_dict import VarDict
|
||||
from edk2toollib.utility_functions import RunCmd
|
||||
|
||||
|
||||
class EccCheck(ICiBuildPlugin):
|
||||
"""
|
||||
A CiBuildPlugin that finds the Ecc issues of newly added code in pull request.
|
||||
|
||||
Configuration options:
|
||||
"EccCheck": {
|
||||
"ExceptionList": [],
|
||||
"IgnoreFiles": []
|
||||
},
|
||||
"""
|
||||
|
||||
ReModifyFile = re.compile(r'[B-Q,S-Z]+[\d]*\t(.*)')
|
||||
FindModifyFile = re.compile(r'\+\+\+ b\/(.*)')
|
||||
LineScopePattern = (r'@@ -\d*\,*\d* \+\d*\,*\d* @@.*')
|
||||
LineNumRange = re.compile(r'@@ -\d*\,*\d* \+(\d*)\,*(\d*) @@.*')
|
||||
|
||||
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)
|
||||
"""
|
||||
return ("Check for efi coding style for " + packagename, packagename + ".EccCheck")
|
||||
|
||||
##
|
||||
# External function of plugin. This function is used to perform the task of the ci_build_plugin 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):
|
||||
edk2_path = Edk2pathObj.WorkspacePath
|
||||
python_path = os.path.join(edk2_path, "BaseTools", "Source", "Python")
|
||||
env = shell_environment.GetEnvironment()
|
||||
env.set_shell_var('PYTHONPATH', python_path)
|
||||
env.set_shell_var('WORKSPACE', edk2_path)
|
||||
self.ECC_PASS = True
|
||||
self.ApplyConfig(pkgconfig, edk2_path, packagename)
|
||||
modify_dir_list = self.GetModifyDir(packagename)
|
||||
patch = self.GetDiff(packagename)
|
||||
ecc_diff_range = self.GetDiffRange(patch, packagename, edk2_path)
|
||||
self.GenerateEccReport(modify_dir_list, ecc_diff_range, edk2_path)
|
||||
ecc_log = os.path.join(edk2_path, "Ecc.log")
|
||||
self.RevertCode()
|
||||
if self.ECC_PASS:
|
||||
tc.SetSuccess()
|
||||
self.RemoveFile(ecc_log)
|
||||
return 0
|
||||
else:
|
||||
with open(ecc_log, encoding='utf8') as output:
|
||||
ecc_output = output.readlines()
|
||||
for line in ecc_output:
|
||||
logging.error(line.strip())
|
||||
self.RemoveFile(ecc_log)
|
||||
tc.SetFailed("EccCheck failed for {0}".format(packagename), "Ecc detected issues")
|
||||
return 1
|
||||
|
||||
def RevertCode(self) -> None:
|
||||
submoudle_params = "submodule update --init"
|
||||
RunCmd("git", submoudle_params)
|
||||
reset_params = "reset HEAD --hard"
|
||||
RunCmd("git", reset_params)
|
||||
|
||||
def GetDiff(self, pkg: str) -> List[str]:
|
||||
return_buffer = StringIO()
|
||||
params = "diff --unified=0 origin/master HEAD"
|
||||
RunCmd("git", params, outstream=return_buffer)
|
||||
p = return_buffer.getvalue().strip()
|
||||
patch = p.split("\n")
|
||||
return_buffer.close()
|
||||
|
||||
return patch
|
||||
|
||||
def RemoveFile(self, file: str) -> None:
|
||||
if os.path.exists(file):
|
||||
os.remove(file)
|
||||
return
|
||||
|
||||
def GetModifyDir(self, pkg: str) -> List[str]:
|
||||
return_buffer = StringIO()
|
||||
params = "diff --name-status" + ' HEAD' + ' origin/master'
|
||||
RunCmd("git", params, outstream=return_buffer)
|
||||
p1 = return_buffer.getvalue().strip()
|
||||
dir_list = p1.split("\n")
|
||||
return_buffer.close()
|
||||
modify_dir_list = []
|
||||
for modify_dir in dir_list:
|
||||
file_path = self.ReModifyFile.findall(modify_dir)
|
||||
if file_path:
|
||||
file_dir = os.path.dirname(file_path[0])
|
||||
else:
|
||||
continue
|
||||
if pkg in file_dir and file_dir != pkg:
|
||||
modify_dir_list.append('%s' % file_dir)
|
||||
else:
|
||||
continue
|
||||
|
||||
modify_dir_list = list(set(modify_dir_list))
|
||||
return modify_dir_list
|
||||
|
||||
def GetDiffRange(self, patch_diff: List[str], pkg: str, workingdir: str) -> Dict[str, List[Tuple[int, int]]]:
|
||||
IsDelete = True
|
||||
StartCheck = False
|
||||
range_directory: Dict[str, List[Tuple[int, int]]] = {}
|
||||
for line in patch_diff:
|
||||
modify_file = self.FindModifyFile.findall(line)
|
||||
if modify_file and pkg in modify_file[0] and not StartCheck and os.path.isfile(modify_file[0]):
|
||||
modify_file_comment_dic = self.GetCommentRange(modify_file[0], workingdir)
|
||||
IsDelete = False
|
||||
StartCheck = True
|
||||
modify_file_dic = modify_file[0]
|
||||
modify_file_dic = modify_file_dic.replace("/", os.sep)
|
||||
range_directory[modify_file_dic] = []
|
||||
elif line.startswith('--- '):
|
||||
StartCheck = False
|
||||
elif re.match(self.LineScopePattern, line, re.I) and not IsDelete and StartCheck:
|
||||
start_line = self.LineNumRange.search(line).group(1)
|
||||
line_range = self.LineNumRange.search(line).group(2)
|
||||
if not line_range:
|
||||
line_range = '1'
|
||||
range_directory[modify_file_dic].append((int(start_line), int(start_line) + int(line_range) - 1))
|
||||
for i in modify_file_comment_dic:
|
||||
if int(i[0]) <= int(start_line) <= int(i[1]):
|
||||
range_directory[modify_file_dic].append(i)
|
||||
return range_directory
|
||||
|
||||
def GetCommentRange(self, modify_file: str, workingdir: str) -> List[Tuple[int, int]]:
|
||||
modify_file_path = os.path.join(workingdir, modify_file)
|
||||
with open(modify_file_path) as f:
|
||||
line_no = 1
|
||||
comment_range: List[Tuple[int, int]] = []
|
||||
Start = False
|
||||
for line in f:
|
||||
if line.startswith('/**'):
|
||||
start_no = line_no
|
||||
Start = True
|
||||
if line.startswith('**/') and Start:
|
||||
end_no = line_no
|
||||
Start = False
|
||||
comment_range.append((int(start_no), int(end_no)))
|
||||
line_no += 1
|
||||
|
||||
if comment_range and comment_range[0][0] == 1:
|
||||
del comment_range[0]
|
||||
return comment_range
|
||||
|
||||
def GenerateEccReport(self, modify_dir_list: List[str], ecc_diff_range: Dict[str, List[Tuple[int, int]]],
|
||||
edk2_path: str) -> None:
|
||||
ecc_need = False
|
||||
ecc_run = True
|
||||
config = os.path.join(edk2_path, "BaseTools", "Source", "Python", "Ecc", "config.ini")
|
||||
exception = os.path.join(edk2_path, "BaseTools", "Source", "Python", "Ecc", "exception.xml")
|
||||
report = os.path.join(edk2_path, "Ecc.csv")
|
||||
for modify_dir in modify_dir_list:
|
||||
target = os.path.join(edk2_path, modify_dir)
|
||||
logging.info('Run ECC tool for the commit in %s' % modify_dir)
|
||||
ecc_need = True
|
||||
ecc_params = "-c {0} -e {1} -t {2} -r {3}".format(config, exception, target, report)
|
||||
return_code = RunCmd("Ecc", ecc_params, workingdir=edk2_path)
|
||||
if return_code != 0:
|
||||
ecc_run = False
|
||||
break
|
||||
if not ecc_run:
|
||||
logging.error('Fail to run ECC tool')
|
||||
self.ParseEccReport(ecc_diff_range, edk2_path)
|
||||
|
||||
if not ecc_need:
|
||||
logging.info("Doesn't need run ECC check")
|
||||
|
||||
revert_params = "checkout -- {}".format(exception)
|
||||
RunCmd("git", revert_params)
|
||||
return
|
||||
|
||||
def ParseEccReport(self, ecc_diff_range: Dict[str, List[Tuple[int, int]]], edk2_path: str) -> None:
|
||||
ecc_log = os.path.join(edk2_path, "Ecc.log")
|
||||
ecc_csv = "Ecc.csv"
|
||||
file = os.listdir(edk2_path)
|
||||
row_lines = []
|
||||
ignore_error_code = self.GetIgnoreErrorCode()
|
||||
if ecc_csv in file:
|
||||
with open(ecc_csv) as csv_file:
|
||||
reader = csv.reader(csv_file)
|
||||
for row in reader:
|
||||
for modify_file in ecc_diff_range:
|
||||
if modify_file in row[3]:
|
||||
for i in ecc_diff_range[modify_file]:
|
||||
line_no = int(row[4])
|
||||
if i[0] <= line_no <= i[1] and row[1] not in ignore_error_code:
|
||||
row[0] = '\nEFI coding style error'
|
||||
row[1] = 'Error code: ' + row[1]
|
||||
row[3] = 'file: ' + row[3]
|
||||
row[4] = 'Line number: ' + row[4]
|
||||
row_line = '\n *'.join(row)
|
||||
row_lines.append(row_line)
|
||||
break
|
||||
break
|
||||
if row_lines:
|
||||
self.ECC_PASS = False
|
||||
|
||||
with open(ecc_log, 'a') as log:
|
||||
all_line = '\n'.join(row_lines)
|
||||
all_line = all_line + '\n'
|
||||
log.writelines(all_line)
|
||||
return
|
||||
|
||||
def ApplyConfig(self, pkgconfig: Dict[str, List[str]], edk2_path: str, pkg: str) -> None:
|
||||
if "IgnoreFiles" in pkgconfig:
|
||||
for a in pkgconfig["IgnoreFiles"]:
|
||||
a = os.path.join(edk2_path, pkg, a)
|
||||
a = a.replace(os.sep, "/")
|
||||
|
||||
logging.info("Ignoring Files {0}".format(a))
|
||||
if os.path.exists(a):
|
||||
if os.path.isfile(a):
|
||||
self.RemoveFile(a)
|
||||
elif os.path.isdir(a):
|
||||
shutil.rmtree(a)
|
||||
else:
|
||||
logging.error("EccCheck.IgnoreInf -> {0} not found in filesystem. Invalid ignore files".format(a))
|
||||
|
||||
if "ExceptionList" in pkgconfig:
|
||||
exception_list = pkgconfig["ExceptionList"]
|
||||
exception_xml = os.path.join(edk2_path, "BaseTools", "Source", "Python", "Ecc", "exception.xml")
|
||||
try:
|
||||
logging.info("Appending exceptions")
|
||||
self.AppendException(exception_list, exception_xml)
|
||||
except Exception as e:
|
||||
logging.error("Fail to apply exceptions")
|
||||
raise e
|
||||
return
|
||||
|
||||
def AppendException(self, exception_list: List[str], exception_xml: str) -> None:
|
||||
error_code_list = exception_list[::2]
|
||||
keyword_list = exception_list[1::2]
|
||||
dom_tree = xml.dom.minidom.parse(exception_xml)
|
||||
root_node = dom_tree.documentElement
|
||||
for error_code, keyword in zip(error_code_list, keyword_list):
|
||||
customer_node = dom_tree.createElement("Exception")
|
||||
keyword_node = dom_tree.createElement("KeyWord")
|
||||
keyword_node_text_value = dom_tree.createTextNode(keyword)
|
||||
keyword_node.appendChild(keyword_node_text_value)
|
||||
customer_node.appendChild(keyword_node)
|
||||
error_code_node = dom_tree.createElement("ErrorID")
|
||||
error_code_text_value = dom_tree.createTextNode(error_code)
|
||||
error_code_node.appendChild(error_code_text_value)
|
||||
customer_node.appendChild(error_code_node)
|
||||
root_node.appendChild(customer_node)
|
||||
with open(exception_xml, 'w') as f:
|
||||
dom_tree.writexml(f, indent='', addindent='', newl='\n', encoding='UTF-8')
|
||||
return
|
||||
|
||||
def GetIgnoreErrorCode(self) -> set:
|
||||
"""
|
||||
Below are kinds of error code that are accurate in ecc scanning of edk2 level.
|
||||
But EccCheck plugin is partial scanning so they are always false positive issues.
|
||||
The mapping relationship of error code and error message is listed BaseTools/Sourc/Python/Ecc/EccToolError.py
|
||||
"""
|
||||
ignore_error_code = {
|
||||
"10000",
|
||||
"10001",
|
||||
"10002",
|
||||
"10003",
|
||||
"10004",
|
||||
"10005",
|
||||
"10006",
|
||||
"10007",
|
||||
"10008",
|
||||
"10009",
|
||||
"10010",
|
||||
"10011",
|
||||
"10012",
|
||||
"10013",
|
||||
"10015",
|
||||
"10016",
|
||||
"10017",
|
||||
"10022",
|
||||
}
|
||||
return ignore_error_code
|
11
.pytool/Plugin/EccCheck/EccCheck_plug_in.yaml
Normal file
11
.pytool/Plugin/EccCheck/EccCheck_plug_in.yaml
Normal file
@ -0,0 +1,11 @@
|
||||
## @file
|
||||
# CiBuildPlugin used to check Ecc issues
|
||||
#
|
||||
# Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
|
||||
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
##
|
||||
{
|
||||
"scope": "cibuild",
|
||||
"name": "EccCheck Test",
|
||||
"module": "EccCheck"
|
||||
}
|
15
.pytool/Plugin/EccCheck/Readme.md
Normal file
15
.pytool/Plugin/EccCheck/Readme.md
Normal file
@ -0,0 +1,15 @@
|
||||
# EFI Coding style Check Plugin
|
||||
|
||||
This CiBuildPlugin finds the Ecc issues of newly added code in pull request.
|
||||
|
||||
## Configuration
|
||||
|
||||
The plugin can be configured to ignore certain files and issues.
|
||||
|
||||
"EccCheck": {
|
||||
"ExceptionList": [],
|
||||
"IgnoreFiles": []
|
||||
},
|
||||
"""
|
||||
|
||||
OPTIONAL List of file to ignore.
|
115
.pytool/Plugin/LicenseCheck/LicenseCheck.py
Normal file
115
.pytool/Plugin/LicenseCheck/LicenseCheck.py
Normal file
@ -0,0 +1,115 @@
|
||||
# @file LicenseCheck.py
|
||||
#
|
||||
# Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
|
||||
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
##
|
||||
|
||||
import os
|
||||
import logging
|
||||
import re
|
||||
from io import StringIO
|
||||
from typing import List, Tuple
|
||||
from edk2toolext.environment.plugintypes.ci_build_plugin import ICiBuildPlugin
|
||||
from edk2toolext.environment.var_dict import VarDict
|
||||
from edk2toollib.utility_functions import RunCmd
|
||||
|
||||
|
||||
class LicenseCheck(ICiBuildPlugin):
|
||||
|
||||
"""
|
||||
A CiBuildPlugin to check the license for new added files.
|
||||
|
||||
Configuration options:
|
||||
"LicenseCheck": {
|
||||
"IgnoreFiles": []
|
||||
},
|
||||
"""
|
||||
|
||||
license_format_preflix = 'SPDX-License-Identifier'
|
||||
|
||||
bsd2_patent = 'BSD-2-Clause-Patent'
|
||||
|
||||
Readdedfileformat = re.compile(r'\+\+\+ b\/(.*)')
|
||||
|
||||
file_extension_list = [".c", ".h", ".inf", ".dsc", ".dec", ".py", ".bat", ".sh", ".uni", ".yaml",
|
||||
".fdf", ".inc", "yml", ".asm", ".asm16", ".asl", ".vfr", ".s", ".S", ".aslc",
|
||||
".nasm", ".nasmb", ".idf", ".Vfr", ".H"]
|
||||
|
||||
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)
|
||||
"""
|
||||
return ("Check for license for " + packagename, packagename + ".LicenseCheck")
|
||||
|
||||
##
|
||||
# External function of plugin. This function is used to perform the task of the ci_build_plugin 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):
|
||||
return_buffer = StringIO()
|
||||
params = "diff --unified=0 origin/master HEAD"
|
||||
RunCmd("git", params, outstream=return_buffer)
|
||||
p = return_buffer.getvalue().strip()
|
||||
patch = p.split("\n")
|
||||
return_buffer.close()
|
||||
|
||||
ignore_files = []
|
||||
if "IgnoreFiles" in pkgconfig:
|
||||
ignore_files = pkgconfig["IgnoreFiles"]
|
||||
|
||||
self.ok = True
|
||||
self.startcheck = False
|
||||
self.license = True
|
||||
self.all_file_pass = True
|
||||
count = len(patch)
|
||||
line_index = 0
|
||||
for line in patch:
|
||||
if line.startswith('--- /dev/null'):
|
||||
nextline = patch[line_index + 1]
|
||||
added_file = self.Readdedfileformat.search(nextline).group(1)
|
||||
added_file_extension = os.path.splitext(added_file)[1]
|
||||
if added_file_extension in self.file_extension_list and packagename in added_file:
|
||||
if (self.IsIgnoreFile(added_file, ignore_files)):
|
||||
line_index = line_index + 1
|
||||
continue
|
||||
self.startcheck = True
|
||||
self.license = False
|
||||
if self.startcheck and self.license_format_preflix in line:
|
||||
if self.bsd2_patent in line:
|
||||
self.license = True
|
||||
if line_index + 1 == count or patch[line_index + 1].startswith('diff --') and self.startcheck:
|
||||
if not self.license:
|
||||
self.all_file_pass = False
|
||||
error_message = "Invalid license in: " + added_file + " Hint: Only BSD-2-Clause-Patent is accepted."
|
||||
logging.error(error_message)
|
||||
self.startcheck = False
|
||||
self.license = True
|
||||
line_index = line_index + 1
|
||||
|
||||
if self.all_file_pass:
|
||||
tc.SetSuccess()
|
||||
return 0
|
||||
else:
|
||||
tc.SetFailed("License Check {0} Failed. ".format(packagename), "LICENSE_CHECK_FAILED")
|
||||
return 1
|
||||
|
||||
def IsIgnoreFile(self, file: str, ignore_files: List[str]) -> bool:
|
||||
for f in ignore_files:
|
||||
if f in file:
|
||||
return True
|
||||
return False
|
11
.pytool/Plugin/LicenseCheck/LicenseCheck_plug_in.yaml
Normal file
11
.pytool/Plugin/LicenseCheck/LicenseCheck_plug_in.yaml
Normal file
@ -0,0 +1,11 @@
|
||||
## @file
|
||||
# CiBuildPlugin used to check license issues for new added files
|
||||
#
|
||||
# Copyright (c) 2020, Intel Corporation. All rights reserved.
|
||||
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
##
|
||||
{
|
||||
"scope": "cibuild",
|
||||
"name": "License Check Test",
|
||||
"module": "LicenseCheck"
|
||||
}
|
17
.pytool/Plugin/LicenseCheck/Readme.md
Normal file
17
.pytool/Plugin/LicenseCheck/Readme.md
Normal file
@ -0,0 +1,17 @@
|
||||
# License Check Plugin
|
||||
|
||||
This CiBuildPlugin scans all new added files in a package to make sure code
|
||||
is contributed under BSD-2-Clause-Patent.
|
||||
|
||||
## Configuration
|
||||
|
||||
The plugin can be configured to ignore certain files.
|
||||
|
||||
``` yaml
|
||||
"LicenseCheck": {
|
||||
"IgnoreFiles": []
|
||||
}
|
||||
```
|
||||
### IgnoreFiles
|
||||
|
||||
OPTIONAL List of file to ignore.
|
@ -22,6 +22,8 @@
|
||||
],
|
||||
"minWordLength": 5,
|
||||
"allowCompoundWords": false,
|
||||
"maxNumberOfProblems": 200,
|
||||
"maxDuplicateProblems": 200,
|
||||
"ignoreWords": [
|
||||
"muchange"
|
||||
],
|
||||
@ -161,5 +163,21 @@
|
||||
"bootability",
|
||||
"Sdhci",
|
||||
"inmodule",
|
||||
"RISCV",
|
||||
"edksetup",
|
||||
"iscsi",
|
||||
"nvdata",
|
||||
"pytools",
|
||||
"NTDDI",
|
||||
"Wnonportable",
|
||||
"CLANGPDB",
|
||||
"nologo",
|
||||
"lldmap",
|
||||
"ASMLINK",
|
||||
"NODEFAULTLIB",
|
||||
"vcruntimed",
|
||||
"ucrtd",
|
||||
"msvcrtd",
|
||||
"XIPFLAGS"
|
||||
]
|
||||
}
|
||||
|
@ -6,11 +6,11 @@
|
||||
| :---- | :----- | :---- | :--- |
|
||||
| ArmPkg |
|
||||
| ArmPlatformPkg |
|
||||
| ArmVirtPkg |
|
||||
| ArmVirtPkg | SEE PACKAGE README | SEE PACKAGE README |
|
||||
| CryptoPkg | :heavy_check_mark: | :heavy_check_mark: | Spell checking in audit mode
|
||||
| DynamicTablesPkg |
|
||||
| DynamicTablesPkg | | :heavy_check_mark: |
|
||||
| EmbeddedPkg |
|
||||
| EmulatorPkg |
|
||||
| EmulatorPkg | SEE PACKAGE README | SEE PACKAGE README | Spell checking in audit mode
|
||||
| FatPkg | :heavy_check_mark: | :heavy_check_mark: |
|
||||
| FmpDevicePkg | :heavy_check_mark: | :heavy_check_mark: |
|
||||
| IntelFsp2Pkg |
|
||||
@ -18,15 +18,16 @@
|
||||
| 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
|
||||
| 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: |
|
||||
| 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
|
||||
| SignedCapsulePkg |
|
||||
| SourceLevelDebugPkg |
|
||||
| StandaloneMmPkg |
|
||||
| StandaloneMmPkg | :heavy_check_mark: | :heavy_check_mark: |
|
||||
| UefiCpuPkg | :heavy_check_mark: | :heavy_check_mark: | Spell checking in audit mode, 2 binary modules not being built by DSC
|
||||
| UefiPayloadPkg |
|
||||
| UnitTestFrameworkPkg | :heavy_check_mark: | :heavy_check_mark: |
|
||||
|
||||
For more detailed status look at the test results of the latest CI run on the
|
||||
repo readme.
|
||||
@ -77,7 +78,7 @@ per package configuration which comes from this file.
|
||||
## Running CI locally
|
||||
|
||||
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
|
||||
[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
|
||||
* Windows SDK (for rc)
|
||||
* Windows WDK (for capsules)
|
||||
* Ubuntu 16.04
|
||||
* Ubuntu 18.04 or Fedora
|
||||
* GCC5
|
||||
* Easy to add more but this is the current state
|
||||
2. Python 3.7.x or newer on path
|
||||
@ -137,11 +138,31 @@ location makes more sense for the community.
|
||||
|
||||
### Module Inclusion Test - DscCompleteCheck
|
||||
|
||||
This test scans all available modules (via INF files) and compares them to the
|
||||
package-level DSC file for the package each module is contained within. The test
|
||||
considers it an error if any module does not appear in the `Components` section
|
||||
of at least one package-level DSC (indicating that it would not be built if the
|
||||
package were built).
|
||||
This scans all INF files from a package and confirms they are
|
||||
listed in the package level DSC file. The test considers it an error if any INF
|
||||
does not appear in the `Components` section of the package-level DSC (indicating
|
||||
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
|
||||
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
|
||||
|
||||
@ -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
|
||||
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
|
||||
|
||||
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 |
|
||||
| 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 |
|
||||
| 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
|
||||
|
||||
@ -216,8 +279,6 @@ few standard scopes.
|
||||
* Visual Studio AARCH64 and ARM support
|
||||
* BaseTools C tools CI/PR and binary release process
|
||||
* BaseTools Python tools CI/PR process
|
||||
* Host based unit testing
|
||||
* Extensible private/closed source platform reporting
|
||||
* Platform builds, validation
|
||||
* UEFI SCTs
|
||||
* Other automation
|
||||
|
@ -84,6 +84,13 @@
|
||||
# hardware coherency (i.e., no virtualization or cache coherent DMA)
|
||||
gArmTokenSpaceGuid.PcdNormalMemoryNonshareableOverride|FALSE|BOOLEAN|0x00000043
|
||||
|
||||
[PcdsFeatureFlag.AARCH64]
|
||||
## Used to select method for requesting services from S-EL1.<BR><BR>
|
||||
# TRUE - Selects FF-A calls for communication between S-EL0 and SPMC.<BR>
|
||||
# FALSE - Selects SVC calls for communication between S-EL0 and SPMC.<BR>
|
||||
# @Prompt Enable FF-A support.
|
||||
gArmTokenSpaceGuid.PcdFfaEnable|FALSE|BOOLEAN|0x0000005B
|
||||
|
||||
[PcdsFixedAtBuild.common]
|
||||
gArmTokenSpaceGuid.PcdTrustzoneSupport|FALSE|BOOLEAN|0x00000006
|
||||
|
||||
@ -115,6 +122,20 @@
|
||||
# The Primary Core is ClusterId[0] & CoreId[0]
|
||||
gArmTokenSpaceGuid.PcdArmPrimaryCore|0|UINT32|0x00000037
|
||||
|
||||
#
|
||||
# SMBIOS PCDs
|
||||
#
|
||||
gArmTokenSpaceGuid.PcdSystemProductName|L""|VOID*|0x30000053
|
||||
gArmTokenSpaceGuid.PcdSystemVersion|L""|VOID*|0x30000054
|
||||
gArmTokenSpaceGuid.PcdBaseBoardManufacturer|L""|VOID*|0x30000055
|
||||
gArmTokenSpaceGuid.PcdBaseBoardProductName|L""|VOID*|0x30000056
|
||||
gArmTokenSpaceGuid.PcdBaseBoardVersion|L""|VOID*|0x30000057
|
||||
gArmTokenSpaceGuid.PcdProcessorManufacturer|L""|VOID*|0x30000071
|
||||
gArmTokenSpaceGuid.PcdProcessorVersion|L""|VOID*|0x30000072
|
||||
gArmTokenSpaceGuid.PcdProcessorSerialNumber|L""|VOID*|0x30000073
|
||||
gArmTokenSpaceGuid.PcdProcessorAssetTag|L""|VOID*|0x30000074
|
||||
gArmTokenSpaceGuid.PcdProcessorPartNumber|L""|VOID*|0x30000075
|
||||
|
||||
#
|
||||
# ARM L2x0 PCDs
|
||||
#
|
||||
@ -215,6 +236,9 @@
|
||||
gArmTokenSpaceGuid.PcdMmBufferBase|0|UINT64|0x00000045
|
||||
gArmTokenSpaceGuid.PcdMmBufferSize|0|UINT64|0x00000046
|
||||
|
||||
gArmTokenSpaceGuid.PcdSystemBiosRelease|0xFFFF|UINT16|0x30000058
|
||||
gArmTokenSpaceGuid.PcdEmbeddedControllerFirmwareRelease|0xFFFF|UINT16|0x30000059
|
||||
|
||||
[PcdsFixedAtBuild.common, PcdsDynamic.common]
|
||||
#
|
||||
# ARM Architectural Timer
|
||||
|
@ -4,6 +4,7 @@
|
||||
# Copyright (c) 2009 - 2010, Apple Inc. 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) Microsoft Corporation.<BR>
|
||||
#
|
||||
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
#
|
||||
@ -28,6 +29,9 @@
|
||||
RELEASE_*_*_CC_FLAGS = -DMDEPKG_NDEBUG
|
||||
*_*_*_CC_FLAGS = -DDISABLE_NEW_DEPRECATED_INTERFACES
|
||||
|
||||
[PcdsFixedAtBuild]
|
||||
gEfiMdePkgTokenSpaceGuid.PcdDefaultTerminalType|4
|
||||
|
||||
[LibraryClasses.common]
|
||||
BaseLib|MdePkg/Library/BaseLib/BaseLib.inf
|
||||
BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
|
||||
@ -80,6 +84,8 @@
|
||||
|
||||
ArmMtlLib|ArmPkg/Library/ArmMtlNullLib/ArmMtlNullLib.inf
|
||||
|
||||
OemMiscLib|ArmPkg/Universal/Smbios/OemMiscLibNull/OemMiscLibNull.inf
|
||||
|
||||
[LibraryClasses.common.PEIM]
|
||||
HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf
|
||||
PeimEntryPoint|MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf
|
||||
@ -133,12 +139,19 @@
|
||||
ArmPkg/Library/ArmGicArchLib/ArmGicArchLib.inf
|
||||
ArmPkg/Library/ArmGicArchSecLib/ArmGicArchSecLib.inf
|
||||
ArmPkg/Library/ArmLib/ArmBaseLib.inf
|
||||
ArmPkg/Library/ArmMtlNullLib/ArmMtlNullLib.inf
|
||||
ArmPkg/Library/ArmSoftFloatLib/ArmSoftFloatLib.inf
|
||||
ArmPkg/Library/ArmSmcPsciResetSystemLib/ArmSmcPsciResetSystemLib.inf
|
||||
ArmPkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointerLib.inf
|
||||
ArmPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
|
||||
|
||||
ArmPkg/Drivers/ArmCrashDumpDxe/ArmCrashDumpDxe.inf
|
||||
ArmPkg/Drivers/ArmScmiDxe/ArmScmiDxe.inf
|
||||
|
||||
ArmPkg/Universal/Smbios/ProcessorSubClassDxe/ProcessorSubClassDxe.inf
|
||||
ArmPkg/Universal/Smbios/SmbiosMiscDxe/SmbiosMiscDxe.inf
|
||||
|
||||
[Components.AARCH64]
|
||||
ArmPkg/Drivers/MmCommunicationDxe/MmCommunication.inf
|
||||
ArmPkg/Library/ArmMmuLib/ArmMmuPeiLib.inf
|
||||
ArmPkg/Library/StandaloneMmMmuLib/ArmMmuStandaloneMmLib.inf
|
||||
|
@ -25,10 +25,13 @@
|
||||
+ ARM_GICR_SGI_RESERVED_FRAME_SIZE)
|
||||
|
||||
#define ISENABLER_ADDRESS(base,offset) ((base) + \
|
||||
ARM_GICR_CTLR_FRAME_SIZE + ARM_GICR_ISENABLER + (4 * offset))
|
||||
ARM_GICR_CTLR_FRAME_SIZE + ARM_GICR_ISENABLER + 4 * (offset))
|
||||
|
||||
#define ICENABLER_ADDRESS(base,offset) ((base) + \
|
||||
ARM_GICR_CTLR_FRAME_SIZE + ARM_GICR_ICENABLER + (4 * offset))
|
||||
ARM_GICR_CTLR_FRAME_SIZE + ARM_GICR_ICENABLER + 4 * (offset))
|
||||
|
||||
#define IPRIORITY_ADDRESS(base,offset) ((base) + \
|
||||
ARM_GICR_CTLR_FRAME_SIZE + ARM_GIC_ICDIPR + 4 * (offset))
|
||||
|
||||
/**
|
||||
*
|
||||
@ -199,6 +202,50 @@ ArmGicEndOfInterrupt (
|
||||
}
|
||||
}
|
||||
|
||||
VOID
|
||||
EFIAPI
|
||||
ArmGicSetInterruptPriority (
|
||||
IN UINTN GicDistributorBase,
|
||||
IN UINTN GicRedistributorBase,
|
||||
IN UINTN Source,
|
||||
IN UINTN Priority
|
||||
)
|
||||
{
|
||||
UINT32 RegOffset;
|
||||
UINTN RegShift;
|
||||
ARM_GIC_ARCH_REVISION Revision;
|
||||
UINTN GicCpuRedistributorBase;
|
||||
|
||||
// Calculate register offset and bit position
|
||||
RegOffset = Source / 4;
|
||||
RegShift = (Source % 4) * 8;
|
||||
|
||||
Revision = ArmGicGetSupportedArchRevision ();
|
||||
if ((Revision == ARM_GIC_ARCH_REVISION_2) ||
|
||||
FeaturePcdGet (PcdArmGicV3WithV2Legacy) ||
|
||||
SourceIsSpi (Source)) {
|
||||
MmioAndThenOr32 (
|
||||
GicDistributorBase + ARM_GIC_ICDIPR + (4 * RegOffset),
|
||||
~(0xff << RegShift),
|
||||
Priority << RegShift
|
||||
);
|
||||
} else {
|
||||
GicCpuRedistributorBase = GicGetCpuRedistributorBase (
|
||||
GicRedistributorBase,
|
||||
Revision
|
||||
);
|
||||
if (GicCpuRedistributorBase == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
MmioAndThenOr32 (
|
||||
IPRIORITY_ADDRESS (GicCpuRedistributorBase, RegOffset),
|
||||
~(0xff << RegShift),
|
||||
Priority << RegShift
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
VOID
|
||||
EFIAPI
|
||||
ArmGicEnableInterrupt (
|
||||
|
@ -374,8 +374,6 @@ GicV3DxeInitialize (
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
UINTN Index;
|
||||
UINT32 RegOffset;
|
||||
UINTN RegShift;
|
||||
UINT64 CpuTarget;
|
||||
UINT64 MpId;
|
||||
|
||||
@ -397,12 +395,11 @@ GicV3DxeInitialize (
|
||||
GicV3DisableInterruptSource (&gHardwareInterruptV3Protocol, Index);
|
||||
|
||||
// Set Priority
|
||||
RegOffset = Index / 4;
|
||||
RegShift = (Index % 4) * 8;
|
||||
MmioAndThenOr32 (
|
||||
mGicDistributorBase + ARM_GIC_ICDIPR + (4 * RegOffset),
|
||||
~(0xff << RegShift),
|
||||
ARM_GIC_DEFAULT_PRIORITY << RegShift
|
||||
ArmGicSetInterruptPriority (
|
||||
mGicDistributorBase,
|
||||
mGicRedistributorsBase,
|
||||
Index,
|
||||
ARM_GIC_DEFAULT_PRIORITY
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
/** @file
|
||||
|
||||
Copyright (c) 2017-2018, Arm Limited. All rights reserved.
|
||||
Copyright (c) 2017-2021, Arm Limited. All rights reserved.
|
||||
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
@ -161,8 +161,9 @@ ScmiProtocolDiscoveryCommon (
|
||||
)
|
||||
{
|
||||
SCMI_COMMAND Command;
|
||||
UINT32 PayloadLength = 0;
|
||||
UINT32 PayloadLength;
|
||||
|
||||
PayloadLength = 0;
|
||||
Command.ProtocolId = ProtocolId;
|
||||
Command.MessageId = MessageId;
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
/** @file
|
||||
|
||||
Copyright (c) 2017-2018, Arm Limited. All rights reserved.
|
||||
Copyright (c) 2017-2021, Arm Limited. All rights reserved.
|
||||
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
@ -189,12 +189,14 @@ ClockDescribeRates (
|
||||
CLOCK_DESCRIBE_RATES *DescribeRates;
|
||||
CLOCK_RATE_DWORD *Rate;
|
||||
|
||||
UINT32 RequiredArraySize = 0;
|
||||
UINT32 RateIndex = 0;
|
||||
UINT32 RequiredArraySize;
|
||||
UINT32 RateIndex;
|
||||
UINT32 RateNo;
|
||||
UINT32 RateOffset;
|
||||
|
||||
*TotalRates = 0;
|
||||
RequiredArraySize = 0;
|
||||
RateIndex = 0;
|
||||
|
||||
Status = ScmiCommandGetPayload (&MessageParams);
|
||||
if (EFI_ERROR (Status)) {
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
Copyright (c) 2009, Hewlett-Packard Company. All rights reserved.<BR>
|
||||
Portions copyright (c) 2010, Apple Inc. All rights reserved.<BR>
|
||||
Portions copyright (c) 2011-2013, ARM Ltd. All rights reserved.<BR>
|
||||
Portions copyright (c) 2011-2021, Arm Limited. All rights reserved.<BR>
|
||||
Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
|
||||
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
@ -13,7 +13,68 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
#include <Library/MemoryAllocationLib.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
|
||||
UINT64
|
||||
@ -37,7 +98,7 @@ GetFirstPageAttribute (
|
||||
{
|
||||
return FirstEntry & TT_ATTR_INDX_MASK;
|
||||
} 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 ((EntryType == TT_TYPE_BLOCK_ENTRY) ||
|
||||
((TableLevel == 3) && (EntryType == TT_TYPE_BLOCK_ENTRY_LEVEL3))) {
|
||||
if ((*PrevEntryAttribute == TT_ATTR_INDX_INVALID) || (EntryAttribute != *PrevEntryAttribute)) {
|
||||
if (*PrevEntryAttribute != TT_ATTR_INDX_INVALID) {
|
||||
if ((*PrevEntryAttribute == INVALID_ENTRY) || (EntryAttribute != *PrevEntryAttribute)) {
|
||||
if (*PrevEntryAttribute != INVALID_ENTRY) {
|
||||
// Update GCD with the last region
|
||||
SetGcdMemorySpaceAttributes (MemorySpaceMap, NumberOfDescriptors,
|
||||
*StartGcdRegion,
|
||||
@ -103,7 +164,7 @@ GetNextEntryAttribute (
|
||||
(BaseAddress + (Index * TT_ADDRESS_AT_LEVEL(TableLevel))),
|
||||
PrevEntryAttribute, StartGcdRegion);
|
||||
} else {
|
||||
if (*PrevEntryAttribute != TT_ATTR_INDX_INVALID) {
|
||||
if (*PrevEntryAttribute != INVALID_ENTRY) {
|
||||
// Update GCD with the last region
|
||||
SetGcdMemorySpaceAttributes (MemorySpaceMap, NumberOfDescriptors,
|
||||
*StartGcdRegion,
|
||||
@ -112,7 +173,7 @@ GetNextEntryAttribute (
|
||||
|
||||
// Start of the new region
|
||||
*StartGcdRegion = BaseAddress + (Index * TT_ADDRESS_AT_LEVEL(TableLevel));
|
||||
*PrevEntryAttribute = TT_ATTR_INDX_INVALID;
|
||||
*PrevEntryAttribute = INVALID_ENTRY;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -128,7 +189,7 @@ SyncCacheConfig (
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
UINT32 PageAttribute = 0;
|
||||
UINT32 PageAttribute;
|
||||
UINT64 *FirstLevelTableAddress;
|
||||
UINTN TableLevel;
|
||||
UINTN TableCount;
|
||||
@ -177,7 +238,7 @@ SyncCacheConfig (
|
||||
&PageAttribute, &BaseAddressGcdRegion);
|
||||
|
||||
// Update GCD with the last region if valid
|
||||
if (PageAttribute != TT_ATTR_INDX_INVALID) {
|
||||
if (PageAttribute != INVALID_ENTRY) {
|
||||
SetGcdMemorySpaceAttributes (MemorySpaceMap, NumberOfDescriptors,
|
||||
BaseAddressGcdRegion,
|
||||
EndAddressGcdRegion - BaseAddressGcdRegion,
|
||||
@ -221,12 +282,12 @@ EfiAttributeToArmAttribute (
|
||||
ArmAttributes |= TT_AF;
|
||||
|
||||
// Determine protection attributes
|
||||
if (EfiAttributes & EFI_MEMORY_RO) {
|
||||
if ((EfiAttributes & EFI_MEMORY_RO) != 0) {
|
||||
ArmAttributes |= TT_AP_RO_RO;
|
||||
}
|
||||
|
||||
// Process eXecute Never attribute
|
||||
if (EfiAttributes & EFI_MEMORY_XP) {
|
||||
if ((EfiAttributes & EFI_MEMORY_XP) != 0) {
|
||||
ArmAttributes |= TT_PXN_MASK;
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
Copyright (c) 2009, Hewlett-Packard Company. All rights reserved.<BR>
|
||||
Portions copyright (c) 2010, Apple Inc. All rights reserved.<BR>
|
||||
Portions copyright (c) 2013, ARM Ltd. All rights reserved.<BR>
|
||||
Portions copyright (c) 2013-2021, Arm Limited. All rights reserved.<BR>
|
||||
Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
|
||||
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
@ -155,8 +155,8 @@ SyncCacheConfigPage (
|
||||
EFI_STATUS Status;
|
||||
UINT32 i;
|
||||
volatile ARM_PAGE_TABLE_ENTRY *SecondLevelTable;
|
||||
UINT32 NextPageAttributes = 0;
|
||||
UINT32 PageAttributes = 0;
|
||||
UINT32 NextPageAttributes;
|
||||
UINT32 PageAttributes;
|
||||
UINT32 BaseAddress;
|
||||
UINT64 GcdAttributes;
|
||||
|
||||
@ -226,8 +226,8 @@ SyncCacheConfig (
|
||||
UINT32 i;
|
||||
EFI_PHYSICAL_ADDRESS NextRegionBase;
|
||||
UINT64 NextRegionLength;
|
||||
UINT32 NextSectionAttributes = 0;
|
||||
UINT32 SectionAttributes = 0;
|
||||
UINT32 NextSectionAttributes;
|
||||
UINT32 SectionAttributes;
|
||||
UINT64 GcdAttributes;
|
||||
volatile ARM_FIRST_LEVEL_DESCRIPTOR *FirstLevelTable;
|
||||
UINTN NumberOfDescriptors;
|
||||
@ -366,14 +366,14 @@ EfiAttributeToArmAttribute (
|
||||
}
|
||||
|
||||
// Determine protection attributes
|
||||
if (EfiAttributes & EFI_MEMORY_RO) {
|
||||
if ((EfiAttributes & EFI_MEMORY_RO) != 0) {
|
||||
ArmAttributes |= TT_DESCRIPTOR_SECTION_AP_RO_RO;
|
||||
} else {
|
||||
ArmAttributes |= TT_DESCRIPTOR_SECTION_AP_RW_RW;
|
||||
}
|
||||
|
||||
// Determine eXecute Never attribute
|
||||
if (EfiAttributes & EFI_MEMORY_XP) {
|
||||
if ((EfiAttributes & EFI_MEMORY_XP) != 0) {
|
||||
ArmAttributes |= TT_DESCRIPTOR_SECTION_XN_MASK;
|
||||
}
|
||||
|
||||
|
@ -134,13 +134,6 @@ GetMemoryRegion (
|
||||
OUT UINTN *RegionAttributes
|
||||
);
|
||||
|
||||
VOID
|
||||
GetRootTranslationTableInfo (
|
||||
IN UINTN T0SZ,
|
||||
OUT UINTN *TableLevel,
|
||||
OUT UINTN *TableEntryCount
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
SetGcdMemorySpaceAttributes (
|
||||
IN EFI_GCD_MEMORY_SPACE_DESCRIPTOR *MemorySpaceMap,
|
||||
|
@ -1,7 +1,7 @@
|
||||
/** @file
|
||||
|
||||
Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
|
||||
Portions Copyright (c) 2011 - 2014, ARM Ltd. All rights reserved.<BR>
|
||||
Portions Copyright (c) 2011 - 2021, Arm Limited. All rights reserved.<BR>
|
||||
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
@ -14,7 +14,8 @@
|
||||
EFI_STATUS
|
||||
InitializeExceptions (
|
||||
IN EFI_CPU_ARCH_PROTOCOL *Cpu
|
||||
) {
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_VECTOR_HANDOFF_INFO *VectorInfoList;
|
||||
EFI_VECTOR_HANDOFF_INFO *VectorInfo;
|
||||
@ -92,7 +93,8 @@ EFI_STATUS
|
||||
RegisterInterruptHandler(
|
||||
IN EFI_EXCEPTION_TYPE InterruptType,
|
||||
IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler
|
||||
) {
|
||||
)
|
||||
{
|
||||
// pass down to CpuExceptionHandlerLib
|
||||
return (EFI_STATUS)RegisterCpuInterruptHandler(InterruptType, InterruptHandler);
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
/** @file
|
||||
|
||||
Copyright (c) 2016-2018, ARM Limited. All rights reserved.
|
||||
Copyright (c) 2016-2021, Arm Limited. All rights reserved.<BR>
|
||||
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
@ -16,7 +16,7 @@
|
||||
#include <Library/UefiBootServicesTableLib.h>
|
||||
#include <Library/UefiRuntimeServicesTableLib.h>
|
||||
|
||||
#include <Protocol/MmCommunication.h>
|
||||
#include <Protocol/MmCommunication2.h>
|
||||
|
||||
#include <IndustryStandard/ArmStdSmc.h>
|
||||
|
||||
@ -39,38 +39,33 @@ STATIC EFI_HANDLE mMmCommunicateHandle;
|
||||
/**
|
||||
Communicates with a registered handler.
|
||||
|
||||
This function provides an interface to send and receive messages to the
|
||||
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().
|
||||
This function provides a service to send and receive messages from a registered UEFI service.
|
||||
|
||||
@param[in] This The EFI_MM_COMMUNICATION_PROTOCOL
|
||||
instance.
|
||||
@param[in, out] CommBuffer A pointer to the buffer to convey
|
||||
into MMRAM.
|
||||
@param[in, out] CommSize The size of the data buffer being
|
||||
passed in. This is optional.
|
||||
@param[in] This The EFI_MM_COMMUNICATION_PROTOCOL instance.
|
||||
@param[in] CommBufferPhysical Physical address of the MM communication buffer
|
||||
@param[in] CommBufferVirtual Virtual address of the MM communication buffer
|
||||
@param[in] CommSize The size of the data buffer being passed in. On exit, the size of data
|
||||
being returned. Zero if the handler does not wish to reply with any data.
|
||||
This parameter is optional and may be NULL.
|
||||
|
||||
@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
|
||||
@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.
|
||||
|
||||
**/
|
||||
STATIC
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
MmCommunicationCommunicate (
|
||||
IN CONST EFI_MM_COMMUNICATION_PROTOCOL *This,
|
||||
IN OUT VOID *CommBuffer,
|
||||
MmCommunication2Communicate (
|
||||
IN CONST EFI_MM_COMMUNICATION2_PROTOCOL *This,
|
||||
IN OUT VOID *CommBufferPhysical,
|
||||
IN OUT VOID *CommBufferVirtual,
|
||||
IN OUT UINTN *CommSize OPTIONAL
|
||||
)
|
||||
{
|
||||
@ -87,11 +82,11 @@ MmCommunicationCommunicate (
|
||||
//
|
||||
// Check parameters
|
||||
//
|
||||
if (CommBuffer == NULL) {
|
||||
if (CommBufferVirtual == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
CommunicateHeader = CommBuffer;
|
||||
CommunicateHeader = CommBufferVirtual;
|
||||
// CommBuffer is a mandatory parameter. Hence, Rely on
|
||||
// MessageLength + Header to ascertain the
|
||||
// total size of the communication payload rather than
|
||||
@ -101,7 +96,7 @@ MmCommunicationCommunicate (
|
||||
sizeof (CommunicateHeader->MessageLength);
|
||||
|
||||
// If the length of the CommBuffer is 0 then return the expected length.
|
||||
if (CommSize) {
|
||||
if (CommSize != 0) {
|
||||
// This case can be used by the consumer of this driver to find out the
|
||||
// max size that can be used for allocating CommBuffer.
|
||||
if ((*CommSize == 0) ||
|
||||
@ -136,7 +131,7 @@ MmCommunicationCommunicate (
|
||||
CommunicateSmcArgs.Arg1 = 0;
|
||||
|
||||
// Copy Communication Payload
|
||||
CopyMem ((VOID *)mNsCommBuffMemRegion.VirtualBase, CommBuffer, BufferSize);
|
||||
CopyMem ((VOID *)mNsCommBuffMemRegion.VirtualBase, CommBufferVirtual, BufferSize);
|
||||
|
||||
// comm_buffer_address (64-bit physical address)
|
||||
CommunicateSmcArgs.Arg2 = (UINTN)mNsCommBuffMemRegion.PhysicalBase;
|
||||
@ -149,7 +144,7 @@ MmCommunicationCommunicate (
|
||||
|
||||
switch (CommunicateSmcArgs.Arg0) {
|
||||
case ARM_SMC_MM_RET_SUCCESS:
|
||||
ZeroMem (CommBuffer, BufferSize);
|
||||
ZeroMem (CommBufferVirtual, BufferSize);
|
||||
// On successful return, the size of data being returned is inferred from
|
||||
// MessageLength + Header.
|
||||
CommunicateHeader = (EFI_MM_COMMUNICATE_HEADER *)mNsCommBuffMemRegion.VirtualBase;
|
||||
@ -158,7 +153,7 @@ MmCommunicationCommunicate (
|
||||
sizeof (CommunicateHeader->MessageLength);
|
||||
|
||||
CopyMem (
|
||||
CommBuffer,
|
||||
CommBufferVirtual,
|
||||
(VOID *)mNsCommBuffMemRegion.VirtualBase,
|
||||
BufferSize
|
||||
);
|
||||
@ -191,8 +186,8 @@ MmCommunicationCommunicate (
|
||||
//
|
||||
// MM Communication Protocol instance
|
||||
//
|
||||
EFI_MM_COMMUNICATION_PROTOCOL mMmCommunication = {
|
||||
MmCommunicationCommunicate
|
||||
STATIC EFI_MM_COMMUNICATION2_PROTOCOL mMmCommunication2 = {
|
||||
MmCommunication2Communicate
|
||||
};
|
||||
|
||||
/**
|
||||
@ -293,7 +288,7 @@ MmGuidedEventNotify (
|
||||
Header.Data[0] = 0;
|
||||
|
||||
Size = sizeof (Header);
|
||||
MmCommunicationCommunicate (&mMmCommunication, &Header, &Size);
|
||||
MmCommunication2Communicate (&mMmCommunication2, &Header, &Header, &Size);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -312,7 +307,7 @@ MmGuidedEventNotify (
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
MmCommunicationInitialize (
|
||||
MmCommunication2Initialize (
|
||||
IN EFI_HANDLE ImageHandle,
|
||||
IN EFI_SYSTEM_TABLE *SystemTable
|
||||
)
|
||||
@ -363,9 +358,9 @@ MmCommunicationInitialize (
|
||||
// Install the communication protocol
|
||||
Status = gBS->InstallProtocolInterface (
|
||||
&mMmCommunicateHandle,
|
||||
&gEfiMmCommunicationProtocolGuid,
|
||||
&gEfiMmCommunication2ProtocolGuid,
|
||||
EFI_NATIVE_INTERFACE,
|
||||
&mMmCommunication
|
||||
&mMmCommunication2
|
||||
);
|
||||
if (EFI_ERROR(Status)) {
|
||||
DEBUG ((DEBUG_ERROR, "MmCommunicationInitialize: "
|
||||
@ -390,12 +385,20 @@ MmCommunicationInitialize (
|
||||
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 (
|
||||
mMmCommunicateHandle,
|
||||
&gEfiMmCommunicationProtocolGuid,
|
||||
&mMmCommunication
|
||||
&gEfiMmCommunication2ProtocolGuid,
|
||||
&mMmCommunication2
|
||||
);
|
||||
|
||||
CleanAddedMemorySpace:
|
||||
|
@ -2,7 +2,7 @@
|
||||
#
|
||||
# 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
|
||||
#
|
||||
@ -14,7 +14,7 @@
|
||||
FILE_GUID = 09EE81D3-F15E-43F4-85B4-CB9873DA5D6B
|
||||
MODULE_TYPE = DXE_RUNTIME_DRIVER
|
||||
VERSION_STRING = 1.0
|
||||
ENTRY_POINT = MmCommunicationInitialize
|
||||
ENTRY_POINT = MmCommunication2Initialize
|
||||
|
||||
#
|
||||
# The following is for reference only and not required by
|
||||
@ -40,7 +40,7 @@
|
||||
UefiDriverEntryPoint
|
||||
|
||||
[Protocols]
|
||||
gEfiMmCommunicationProtocolGuid ## PRODUCES
|
||||
gEfiMmCommunication2ProtocolGuid ## PRODUCES
|
||||
|
||||
[Guids]
|
||||
gEfiEndOfDxeEventGroupGuid
|
||||
|
@ -1,7 +1,7 @@
|
||||
/** @file
|
||||
Timer Architecture Protocol driver of the ARM flavor
|
||||
|
||||
Copyright (c) 2011-2013 ARM Ltd. All rights reserved.<BR>
|
||||
Copyright (c) 2011-2021, Arm Limited. All rights reserved.<BR>
|
||||
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
@ -307,7 +307,7 @@ TimerInterruptHandler (
|
||||
// Check if the timer interrupt is active
|
||||
if ((ArmGenericTimerGetTimerCtrlReg () ) & ARM_ARCH_TIMER_ISTATUS) {
|
||||
|
||||
if (mTimerNotifyFunction) {
|
||||
if (mTimerNotifyFunction != 0) {
|
||||
mTimerNotifyFunction (mTimerPeriod * mElapsedPeriod);
|
||||
}
|
||||
|
||||
@ -359,7 +359,7 @@ TimerInitialize (
|
||||
IN EFI_SYSTEM_TABLE *SystemTable
|
||||
)
|
||||
{
|
||||
EFI_HANDLE Handle = NULL;
|
||||
EFI_HANDLE Handle;
|
||||
EFI_STATUS Status;
|
||||
UINTN TimerCtrlReg;
|
||||
UINT32 TimerHypIntrNum;
|
||||
@ -408,6 +408,7 @@ TimerInitialize (
|
||||
Status = TimerDriverSetTimerPeriod (&gTimer, FixedPcdGet32(PcdTimerPeriod)); // TIMER_DEFAULT_PERIOD
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
Handle = NULL;
|
||||
// Install the Timer Architectural Protocol onto a new handle
|
||||
Status = gBS->InstallMultipleProtocolInterfaces(
|
||||
&Handle,
|
||||
|
@ -2,7 +2,7 @@
|
||||
Support a Semi Host file system over a debuggers JTAG
|
||||
|
||||
Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
|
||||
Portions copyright (c) 2011 - 2014, ARM Ltd. All rights reserved.<BR>
|
||||
Portions copyright (c) 2011 - 2021, Arm Limited. All rights reserved.<BR>
|
||||
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
@ -90,8 +90,9 @@ AllocateFCB (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
SEMIHOST_FCB *Fcb = AllocateZeroPool (sizeof (SEMIHOST_FCB));
|
||||
SEMIHOST_FCB *Fcb;
|
||||
|
||||
Fcb = AllocateZeroPool (sizeof (SEMIHOST_FCB));
|
||||
if (Fcb != NULL) {
|
||||
CopyMem (&Fcb->File, &gSemihostFsFile, sizeof (gSemihostFsFile));
|
||||
Fcb->Signature = SEMIHOST_FCB_SIGNATURE;
|
||||
@ -122,7 +123,7 @@ VolumeOpen (
|
||||
OUT EFI_FILE **Root
|
||||
)
|
||||
{
|
||||
SEMIHOST_FCB *RootFcb = NULL;
|
||||
SEMIHOST_FCB *RootFcb;
|
||||
|
||||
if (Root == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
@ -196,8 +197,8 @@ FileOpen (
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if ((OpenMode & EFI_FILE_MODE_CREATE) &&
|
||||
(Attributes & EFI_FILE_DIRECTORY) ) {
|
||||
if (((OpenMode & EFI_FILE_MODE_CREATE) != 0) &&
|
||||
((Attributes & EFI_FILE_DIRECTORY) != 0)) {
|
||||
return EFI_WRITE_PROTECTED;
|
||||
}
|
||||
|
||||
@ -234,7 +235,7 @@ FileOpen (
|
||||
Return = SemihostFileOpen (AsciiFileName, SemihostMode, &SemihostHandle);
|
||||
|
||||
if (RETURN_ERROR (Return)) {
|
||||
if (OpenMode & EFI_FILE_MODE_CREATE) {
|
||||
if ((OpenMode & EFI_FILE_MODE_CREATE) != 0) {
|
||||
//
|
||||
// In the create if does not exist case, if the opening in update
|
||||
// mode failed, create it and open it in update mode. The update
|
||||
@ -277,7 +278,8 @@ FileOpen (
|
||||
|
||||
FileFcb->Info.FileSize = Length;
|
||||
FileFcb->Info.PhysicalSize = Length;
|
||||
FileFcb->Info.Attribute = (OpenMode & EFI_FILE_MODE_CREATE) ? Attributes : 0;
|
||||
FileFcb->Info.Attribute = ((OpenMode & EFI_FILE_MODE_CREATE) != 0) ?
|
||||
Attributes : 0;
|
||||
|
||||
InsertTailList (&gFileList, &FileFcb->Link);
|
||||
|
||||
@ -758,12 +760,13 @@ GetFileInfo (
|
||||
OUT VOID *Buffer
|
||||
)
|
||||
{
|
||||
EFI_FILE_INFO *Info = NULL;
|
||||
UINTN NameSize = 0;
|
||||
EFI_FILE_INFO *Info;
|
||||
UINTN NameSize;
|
||||
UINTN ResultSize;
|
||||
UINTN Index;
|
||||
|
||||
if (Fcb->IsRoot == TRUE) {
|
||||
if (Fcb->IsRoot) {
|
||||
NameSize = 0;
|
||||
ResultSize = SIZE_OF_EFI_FILE_INFO + sizeof(CHAR16);
|
||||
} else {
|
||||
NameSize = AsciiStrLen (Fcb->FileName) + 1;
|
||||
@ -783,7 +786,7 @@ GetFileInfo (
|
||||
// Fill in the structure
|
||||
Info->Size = ResultSize;
|
||||
|
||||
if (Fcb->IsRoot == TRUE) {
|
||||
if (Fcb->IsRoot) {
|
||||
Info->FileName[0] = L'\0';
|
||||
} else {
|
||||
for (Index = 0; Index < NameSize; Index++) {
|
||||
|
@ -112,6 +112,10 @@
|
||||
#define ARM_VECTOR_LOW_A32_FIQ 0x700
|
||||
#define ARM_VECTOR_LOW_A32_SERR 0x780
|
||||
|
||||
// The ID_AA64MMFR2_EL1 register was added in ARMv8.2. Since we
|
||||
// build for ARMv8.0, we need to define the register here.
|
||||
#define ID_AA64MMFR2_EL1 S3_0_C0_C7_2
|
||||
|
||||
#define VECTOR_BASE(tbl) \
|
||||
.section .text.##tbl##,"ax"; \
|
||||
.align 11; \
|
||||
@ -219,11 +223,6 @@ ArmReadCurrentEL (
|
||||
VOID
|
||||
);
|
||||
|
||||
UINT64
|
||||
PageAttributeToGcdAttribute (
|
||||
IN UINT64 PageAttributes
|
||||
);
|
||||
|
||||
UINTN
|
||||
ArmWriteCptr (
|
||||
IN UINT64 Cptr
|
||||
|
44
ArmPkg/Include/IndustryStandard/ArmFfaSvc.h
Normal file
44
ArmPkg/Include/IndustryStandard/ArmFfaSvc.h
Normal file
@ -0,0 +1,44 @@
|
||||
/** @file
|
||||
Header file for FF-A ABI's that will be used for
|
||||
communication between S-EL0 and the Secure Partition
|
||||
Manager(SPM)
|
||||
|
||||
Copyright (c) 2020, ARM Limited. All rights reserved.
|
||||
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
@par Revision Reference:
|
||||
- FF-A Version 1.0
|
||||
|
||||
|
||||
**/
|
||||
|
||||
#ifndef ARM_FFA_SVC_H_
|
||||
#define ARM_FFA_SVC_H_
|
||||
|
||||
#define ARM_SVC_ID_FFA_VERSION_AARCH32 0x84000063
|
||||
#define ARM_SVC_ID_FFA_MSG_SEND_DIRECT_REQ_AARCH64 0xC400006F
|
||||
#define ARM_SVC_ID_FFA_MSG_SEND_DIRECT_RESP_AARCH64 0xC4000070
|
||||
|
||||
#define SPM_MAJOR_VERSION_FFA 1
|
||||
#define SPM_MINOR_VERSION_FFA 0
|
||||
|
||||
#define ARM_FFA_SPM_RET_SUCCESS 0
|
||||
#define ARM_FFA_SPM_RET_NOT_SUPPORTED -1
|
||||
#define ARM_FFA_SPM_RET_INVALID_PARAMETERS -2
|
||||
#define ARM_FFA_SPM_RET_NO_MEMORY -3
|
||||
#define ARM_FFA_SPM_RET_BUSY -4
|
||||
#define ARM_FFA_SPM_RET_INTERRUPTED -5
|
||||
#define ARM_FFA_SPM_RET_DENIED -6
|
||||
#define ARM_FFA_SPM_RET_RETRY -7
|
||||
#define ARM_FFA_SPM_RET_ABORTED -8
|
||||
|
||||
// For now, the destination id to be used in the FF-A calls
|
||||
// is being hard-coded. Subsequently, support will be added
|
||||
// to get the endpoint id's dynamically
|
||||
// This is the endpoint id used by the optee os's implementation
|
||||
// of the spmc.
|
||||
// https://github.com/OP-TEE/optee_os/blob/master/core/arch/arm/kernel/stmm_sp.c#L66
|
||||
#define ARM_FFA_DESTINATION_ENDPOINT_ID 3
|
||||
|
||||
#endif // ARM_FFA_SVC_H_
|
@ -41,4 +41,7 @@
|
||||
#define ARM_SVC_SPM_RET_DENIED -3
|
||||
#define ARM_SVC_SPM_RET_NO_MEMORY -5
|
||||
|
||||
#define SPM_MAJOR_VERSION 0
|
||||
#define SPM_MINOR_VERSION 1
|
||||
|
||||
#endif
|
||||
|
@ -1,9 +1,13 @@
|
||||
/** @file
|
||||
*
|
||||
* Copyright (c) 2020, NUVIA Inc. All rights reserved.<BR>
|
||||
* Copyright (c) 2012-2017, ARM Limited. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
*
|
||||
* @par Revision Reference:
|
||||
* - SMC Calling Convention version 1.2
|
||||
* (https://developer.arm.com/documentation/den0028/c/?lang=en)
|
||||
**/
|
||||
|
||||
#ifndef __ARM_STD_SMC_H__
|
||||
@ -52,6 +56,18 @@
|
||||
#define ARM_SMC_MM_RET_DENIED -3
|
||||
#define ARM_SMC_MM_RET_NO_MEMORY -4
|
||||
|
||||
// ARM Architecture Calls
|
||||
#define SMCCC_VERSION 0x80000000
|
||||
#define SMCCC_ARCH_FEATURES 0x80000001
|
||||
#define SMCCC_ARCH_SOC_ID 0x80000002
|
||||
#define SMCCC_ARCH_WORKAROUND_1 0x80008000
|
||||
#define SMCCC_ARCH_WORKAROUND_2 0x80007FFF
|
||||
|
||||
#define SMC_ARCH_CALL_SUCCESS 0
|
||||
#define SMC_ARCH_CALL_NOT_SUPPORTED -1
|
||||
#define SMC_ARCH_CALL_NOT_REQUIRED -2
|
||||
#define SMC_ARCH_CALL_INVALID_PARAMETER -3
|
||||
|
||||
/*
|
||||
* Power State Coordination Interface (PSCI) calls cover a subset of the
|
||||
* Standard Service Call range.
|
||||
|
@ -208,6 +208,15 @@ ArmGicSetPriorityMask (
|
||||
IN INTN PriorityMask
|
||||
);
|
||||
|
||||
VOID
|
||||
EFIAPI
|
||||
ArmGicSetInterruptPriority (
|
||||
IN UINTN GicDistributorBase,
|
||||
IN UINTN GicRedistributorBase,
|
||||
IN UINTN Source,
|
||||
IN UINTN Priority
|
||||
);
|
||||
|
||||
VOID
|
||||
EFIAPI
|
||||
ArmGicEnableInterrupt (
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
|
||||
Copyright (c) 2011 - 2016, ARM Ltd. All rights reserved.<BR>
|
||||
Copyright (c) 2020, NUVIA Inc. All rights reserved.<BR>
|
||||
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
@ -108,6 +109,10 @@ typedef enum {
|
||||
#define GET_MPID(ClusterId, CoreId) (((ClusterId) << 8) | (CoreId))
|
||||
#define PRIMARY_CORE_ID (PcdGet32(PcdArmPrimaryCore) & ARM_CORE_MASK)
|
||||
|
||||
// The ARM Architecture Reference Manual for ARMv8-A defines up
|
||||
// to 7 levels of cache, L1 through L7.
|
||||
#define MAX_ARM_CACHE_LEVEL 7
|
||||
|
||||
UINTN
|
||||
EFIAPI
|
||||
ArmDataCacheLineLength (
|
||||
@ -132,18 +137,6 @@ ArmIsArchTimerImplemented (
|
||||
VOID
|
||||
);
|
||||
|
||||
UINTN
|
||||
EFIAPI
|
||||
ArmReadIdPfr0 (
|
||||
VOID
|
||||
);
|
||||
|
||||
UINTN
|
||||
EFIAPI
|
||||
ArmReadIdPfr1 (
|
||||
VOID
|
||||
);
|
||||
|
||||
UINTN
|
||||
EFIAPI
|
||||
ArmCacheInfo (
|
||||
@ -211,24 +204,6 @@ ArmCleanInvalidateDataCacheEntryByMVA (
|
||||
IN UINTN Address
|
||||
);
|
||||
|
||||
VOID
|
||||
EFIAPI
|
||||
ArmInvalidateDataCacheEntryBySetWay (
|
||||
IN UINTN SetWayFormat
|
||||
);
|
||||
|
||||
VOID
|
||||
EFIAPI
|
||||
ArmCleanDataCacheEntryBySetWay (
|
||||
IN UINTN SetWayFormat
|
||||
);
|
||||
|
||||
VOID
|
||||
EFIAPI
|
||||
ArmCleanInvalidateDataCacheEntryBySetWay (
|
||||
IN UINTN SetWayFormat
|
||||
);
|
||||
|
||||
VOID
|
||||
EFIAPI
|
||||
ArmEnableDataCache (
|
||||
@ -733,4 +708,49 @@ ArmGetPhysicalAddressBits (
|
||||
VOID
|
||||
);
|
||||
|
||||
|
||||
///
|
||||
/// ID Register Helper functions
|
||||
///
|
||||
|
||||
/**
|
||||
Check whether the CPU supports the GIC system register interface (any version)
|
||||
|
||||
@return Whether GIC System Register Interface is supported
|
||||
|
||||
**/
|
||||
BOOLEAN
|
||||
EFIAPI
|
||||
ArmHasGicSystemRegisters (
|
||||
VOID
|
||||
);
|
||||
|
||||
/** Checks if CCIDX is implemented.
|
||||
|
||||
@retval TRUE CCIDX is implemented.
|
||||
@retval FALSE CCIDX is not implemented.
|
||||
**/
|
||||
BOOLEAN
|
||||
EFIAPI
|
||||
ArmHasCcidx (
|
||||
VOID
|
||||
);
|
||||
|
||||
#ifdef MDE_CPU_ARM
|
||||
///
|
||||
/// AArch32-only ID Register Helper functions
|
||||
///
|
||||
/**
|
||||
Check whether the CPU supports the Security extensions
|
||||
|
||||
@return Whether the Security extensions are implemented
|
||||
|
||||
**/
|
||||
BOOLEAN
|
||||
EFIAPI
|
||||
ArmHasSecurityExtensions (
|
||||
VOID
|
||||
);
|
||||
#endif // MDE_CPU_ARM
|
||||
|
||||
#endif // __ARM_LIB__
|
||||
|
@ -27,10 +27,16 @@ typedef struct {
|
||||
/**
|
||||
Trigger an SVC call
|
||||
|
||||
SVC calls can take up to 7 arguments and return up to 4 return values.
|
||||
Therefore, the 4 first fields in the ARM_SVC_ARGS structure are used
|
||||
SVC calls can take up to 8 arguments and return up to 8 return values.
|
||||
Therefore, the 8 first fields in the ARM_SVC_ARGS structure are used
|
||||
for both input and output values.
|
||||
|
||||
@param[in, out] Args Arguments to be passed as part of the SVC call
|
||||
The return values of the SVC call are also placed
|
||||
in the same structure
|
||||
|
||||
@retval None
|
||||
|
||||
**/
|
||||
VOID
|
||||
ArmCallSvc (
|
||||
|
165
ArmPkg/Include/Library/OemMiscLib.h
Normal file
165
ArmPkg/Include/Library/OemMiscLib.h
Normal file
@ -0,0 +1,165 @@
|
||||
/** @file
|
||||
*
|
||||
* Copyright (c) 2021, NUVIA Inc. All rights reserved.
|
||||
* Copyright (c) 2015, Hisilicon Limited. All rights reserved.
|
||||
* Copyright (c) 2015, Linaro Limited. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
*
|
||||
**/
|
||||
|
||||
|
||||
#ifndef OEM_MISC_LIB_H_
|
||||
#define OEM_MISC_LIB_H_
|
||||
|
||||
#include <Uefi.h>
|
||||
#include <IndustryStandard/SmBios.h>
|
||||
|
||||
typedef enum
|
||||
{
|
||||
CpuCacheL1 = 1,
|
||||
CpuCacheL2,
|
||||
CpuCacheL3,
|
||||
CpuCacheL4,
|
||||
CpuCacheL5,
|
||||
CpuCacheL6,
|
||||
CpuCacheL7,
|
||||
CpuCacheLevelMax
|
||||
} OEM_MISC_CPU_CACHE_LEVEL;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
UINT8 Voltage; ///< Processor voltage
|
||||
UINT16 CurrentSpeed; ///< Current clock speed in MHz
|
||||
UINT16 MaxSpeed; ///< Maximum clock speed in MHz
|
||||
UINT16 ExternalClock; ///< External clock speed in MHz
|
||||
UINT16 CoreCount; ///< Number of cores available
|
||||
UINT16 CoresEnabled; ///< Number of cores enabled
|
||||
UINT16 ThreadCount; ///< Number of threads per processor
|
||||
} OEM_MISC_PROCESSOR_DATA;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
ProductNameType01,
|
||||
SerialNumType01,
|
||||
UuidType01,
|
||||
SystemManufacturerType01,
|
||||
SkuNumberType01,
|
||||
FamilyType01,
|
||||
AssertTagType02,
|
||||
SerialNumberType02,
|
||||
BoardManufacturerType02,
|
||||
SkuNumberType02,
|
||||
ChassisLocationType02,
|
||||
AssetTagType03,
|
||||
SerialNumberType03,
|
||||
VersionType03,
|
||||
ChassisTypeType03,
|
||||
ManufacturerType03,
|
||||
SkuNumberType03,
|
||||
SmbiosHiiStringFieldMax
|
||||
} OEM_MISC_SMBIOS_HII_STRING_FIELD;
|
||||
|
||||
/*
|
||||
* The following are functions that the each platform needs to
|
||||
* implement in its OemMiscLib library.
|
||||
*/
|
||||
|
||||
/** Gets the CPU frequency of the specified processor.
|
||||
|
||||
@param ProcessorIndex Index of the processor to get the frequency for.
|
||||
|
||||
@return CPU frequency in Hz
|
||||
**/
|
||||
UINTN
|
||||
EFIAPI
|
||||
OemGetCpuFreq (
|
||||
IN UINT8 ProcessorIndex
|
||||
);
|
||||
|
||||
/** Gets information about the specified processor and stores it in
|
||||
the structures provided.
|
||||
|
||||
@param ProcessorIndex Index of the processor to get the information for.
|
||||
@param ProcessorStatus Processor status.
|
||||
@param ProcessorCharacteristics Processor characteritics.
|
||||
@param MiscProcessorData Miscellaneous processor information.
|
||||
|
||||
@return TRUE on success, FALSE on failure.
|
||||
**/
|
||||
BOOLEAN
|
||||
EFIAPI
|
||||
OemGetProcessorInformation (
|
||||
IN UINTN ProcessorIndex,
|
||||
IN OUT PROCESSOR_STATUS_DATA *ProcessorStatus,
|
||||
IN OUT PROCESSOR_CHARACTERISTIC_FLAGS *ProcessorCharacteristics,
|
||||
IN OUT OEM_MISC_PROCESSOR_DATA *MiscProcessorData
|
||||
);
|
||||
|
||||
/** Gets information about the cache at the specified cache level.
|
||||
|
||||
@param ProcessorIndex The processor to get information for.
|
||||
@param CacheLevel The cache level to get information for.
|
||||
@param DataCache Whether the cache is a data cache.
|
||||
@param UnifiedCache Whether the cache is a unified cache.
|
||||
@param SmbiosCacheTable The SMBIOS Type7 cache information structure.
|
||||
|
||||
@return TRUE on success, FALSE on failure.
|
||||
**/
|
||||
BOOLEAN
|
||||
EFIAPI
|
||||
OemGetCacheInformation (
|
||||
IN UINT8 ProcessorIndex,
|
||||
IN UINT8 CacheLevel,
|
||||
IN BOOLEAN DataCache,
|
||||
IN BOOLEAN UnifiedCache,
|
||||
IN OUT SMBIOS_TABLE_TYPE7 *SmbiosCacheTable
|
||||
);
|
||||
|
||||
/** Gets the maximum number of processors supported by the platform.
|
||||
|
||||
@return The maximum number of processors.
|
||||
**/
|
||||
UINT8
|
||||
EFIAPI
|
||||
OemGetMaxProcessors (
|
||||
VOID
|
||||
);
|
||||
|
||||
/** Gets the type of chassis for the system.
|
||||
|
||||
@retval The type of the chassis.
|
||||
**/
|
||||
MISC_CHASSIS_TYPE
|
||||
EFIAPI
|
||||
OemGetChassisType (
|
||||
VOID
|
||||
);
|
||||
|
||||
/** Returns whether the specified processor is present or not.
|
||||
|
||||
@param ProcessIndex The processor index to check.
|
||||
|
||||
@return TRUE is the processor is present, FALSE otherwise.
|
||||
**/
|
||||
BOOLEAN
|
||||
EFIAPI
|
||||
OemIsProcessorPresent (
|
||||
IN UINTN ProcessorIndex
|
||||
);
|
||||
|
||||
/** Updates the HII string for the specified field.
|
||||
|
||||
@param HiiHandle The HII handle.
|
||||
@param TokenToUpdate The string to update.
|
||||
@param Field The field to get information about.
|
||||
**/
|
||||
VOID
|
||||
EFIAPI
|
||||
OemUpdateSmbiosInfo (
|
||||
IN EFI_HII_HANDLE HiiHandle,
|
||||
IN EFI_STRING_ID TokenToUpdate,
|
||||
IN OEM_MISC_SMBIOS_HII_STRING_FIELD Field
|
||||
);
|
||||
|
||||
#endif // OEM_MISC_LIB_H_
|
@ -56,7 +56,7 @@ TimerConstructor (
|
||||
// If the security extension is not implemented, set Timer Frequency
|
||||
// here.
|
||||
//
|
||||
if ((ArmReadIdPfr1 () & ARM_PFR1_SEC) == 0x0) {
|
||||
if (ArmHasSecurityExtensions ()) {
|
||||
ArmGenericTimerSetTimerFreq (PcdGet32 (PcdArmArchTimerFreqInHz));
|
||||
}
|
||||
#endif
|
||||
|
@ -1,7 +1,7 @@
|
||||
/** @file
|
||||
|
||||
Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
|
||||
Copyright (c) 2011 - 2014, ARM Limited. All rights reserved.
|
||||
Copyright (c) 2011 - 2021, ARM Limited. All rights reserved.
|
||||
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
@ -20,11 +20,14 @@ CacheRangeOperation (
|
||||
IN UINTN LineLength
|
||||
)
|
||||
{
|
||||
UINTN ArmCacheLineAlignmentMask = LineLength - 1;
|
||||
|
||||
UINTN ArmCacheLineAlignmentMask;
|
||||
// Align address (rounding down)
|
||||
UINTN AlignedAddress = (UINTN)Start - ((UINTN)Start & ArmCacheLineAlignmentMask);
|
||||
UINTN EndAddress = (UINTN)Start + Length;
|
||||
UINTN AlignedAddress;
|
||||
UINTN EndAddress;
|
||||
|
||||
ArmCacheLineAlignmentMask = LineLength - 1;
|
||||
AlignedAddress = (UINTN)Start - ((UINTN)Start & ArmCacheLineAlignmentMask);
|
||||
EndAddress = (UINTN)Start + Length;
|
||||
|
||||
// Perform the line operation on an address in each cache line
|
||||
while (AlignedAddress < EndAddress) {
|
||||
|
@ -2,6 +2,7 @@
|
||||
Default exception handler
|
||||
|
||||
Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>
|
||||
Copyright (c) 2021, Arm Limited. All rights reserved.<BR>
|
||||
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
@ -157,7 +158,7 @@ DisassembleArmInstruction (
|
||||
IN BOOLEAN Extended
|
||||
)
|
||||
{
|
||||
UINT32 OpCode = **OpCodePtr;
|
||||
UINT32 OpCode;
|
||||
CHAR8 *Type, *Root;
|
||||
BOOLEAN I, P, U, B, W, L, S, H;
|
||||
UINT32 Rn, Rd, Rm;
|
||||
@ -165,6 +166,8 @@ DisassembleArmInstruction (
|
||||
UINT32 Index;
|
||||
UINT32 shift_imm, shift;
|
||||
|
||||
OpCode = **OpCodePtr;
|
||||
|
||||
I = (OpCode & BIT25) == BIT25;
|
||||
P = (OpCode & BIT24) == BIT24;
|
||||
U = (OpCode & BIT23) == BIT23;
|
||||
@ -240,7 +243,7 @@ DisassembleArmInstruction (
|
||||
if (shift_imm == 0) {
|
||||
shift_imm = 32;
|
||||
}
|
||||
} else if (shift == 0x12) {
|
||||
} else if (shift == 0x2) {
|
||||
Type = "ASR";
|
||||
} else if (shift_imm == 0) {
|
||||
AsciiSPrint (&Buf[Index], Size - Index, "[%a, #%a%a, %a, RRX]%a", gReg[Rn], SIGN (U), gReg[Rm], WRITE (W));
|
||||
@ -270,7 +273,7 @@ DisassembleArmInstruction (
|
||||
if (shift_imm == 0) {
|
||||
shift_imm = 32;
|
||||
}
|
||||
} else if (shift == 0x12) {
|
||||
} else if (shift == 0x2) {
|
||||
Type = "ASR";
|
||||
} else if (shift_imm == 0) {
|
||||
AsciiSPrint (&Buf[Index], Size - Index, "[%a], #%a%a, %a, RRX", gReg[Rn], SIGN (U), gReg[Rm]);
|
||||
@ -367,7 +370,11 @@ DisassembleArmInstruction (
|
||||
AsciiSPrint (Buf, Size, "CPS #0x%x", (OpCode & 0x2f));
|
||||
} else {
|
||||
imode = (OpCode >> 18) & 0x3;
|
||||
Index = AsciiSPrint (Buf, Size, "CPS%a %a%a%a", (imode == 3) ? "ID":"IE", (OpCode & BIT8) ? "A":"", (OpCode & BIT7) ? "I":"", (OpCode & BIT6) ? "F":"");
|
||||
Index = AsciiSPrint (Buf, Size, "CPS%a %a%a%a",
|
||||
(imode == 3) ? "ID":"IE",
|
||||
((OpCode & BIT8) != 0) ? "A":"",
|
||||
((OpCode & BIT7) != 0) ? "I":"",
|
||||
((OpCode & BIT6) != 0) ? "F":"");
|
||||
if ((OpCode & BIT17) != 0) {
|
||||
AsciiSPrint (&Buf[Index], Size - Index, ", #0x%x", OpCode & 0x1f);
|
||||
}
|
||||
|
@ -19,7 +19,8 @@ EFI_EXCEPTION_CALLBACK gDebuggerExceptionHandlers[MAX_AARCH64_EXCEPTION + 1] =
|
||||
PHYSICAL_ADDRESS gExceptionVectorAlignmentMask = ARM_VECTOR_TABLE_ALIGNMENT;
|
||||
UINTN gDebuggerNoHandlerValue = 0; // todo: define for AArch64
|
||||
|
||||
#define EL0_STACK_PAGES 2
|
||||
#define EL0_STACK_SIZE EFI_PAGES_TO_SIZE(2)
|
||||
STATIC UINTN mNewStackBase[EL0_STACK_SIZE / sizeof (UINTN)];
|
||||
|
||||
VOID
|
||||
RegisterEl0Stack (
|
||||
@ -31,14 +32,11 @@ RETURN_STATUS ArchVectorConfig(
|
||||
)
|
||||
{
|
||||
UINTN HcrReg;
|
||||
UINT8 *Stack;
|
||||
|
||||
Stack = AllocatePages (EL0_STACK_PAGES);
|
||||
if (Stack == NULL) {
|
||||
return RETURN_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
RegisterEl0Stack ((UINT8 *)Stack + EFI_PAGES_TO_SIZE (EL0_STACK_PAGES));
|
||||
// Round down sp by 16 bytes alignment
|
||||
RegisterEl0Stack (
|
||||
(VOID *)(((UINTN)mNewStackBase + EL0_STACK_SIZE) & ~0xFUL)
|
||||
);
|
||||
|
||||
if (ArmReadCurrentEL() == AARCH64_EL2) {
|
||||
HcrReg = ArmReadHcr();
|
||||
|
@ -2,7 +2,7 @@
|
||||
* Main file supporting the SEC Phase for Versatile Express
|
||||
*
|
||||
* Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
|
||||
* Copyright (c) 2011-2014, ARM Limited. All rights reserved.
|
||||
* Copyright (c) 2011-2021, Arm Limited. All rights reserved.<BR>
|
||||
* Copyright (c) 2016 HP Development Company, L.P.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
@ -253,7 +253,8 @@ RETURN_STATUS
|
||||
RegisterCpuInterruptHandler(
|
||||
IN EFI_EXCEPTION_TYPE ExceptionType,
|
||||
IN EFI_CPU_INTERRUPT_HANDLER ExceptionHandler
|
||||
) {
|
||||
)
|
||||
{
|
||||
if (ExceptionType > gMaxExceptionNumber) {
|
||||
return RETURN_UNSUPPORTED;
|
||||
}
|
||||
|
@ -1,60 +0,0 @@
|
||||
/** @file
|
||||
*
|
||||
* Copyright (c) 2014, ARM Limited. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
*
|
||||
**/
|
||||
|
||||
#include <Library/ArmLib.h>
|
||||
#include <Library/ArmGicLib.h>
|
||||
|
||||
STATIC ARM_GIC_ARCH_REVISION mGicArchRevision;
|
||||
|
||||
RETURN_STATUS
|
||||
EFIAPI
|
||||
ArmGicArchLibInitialize (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
UINT32 IccSre;
|
||||
|
||||
// Ideally we would like to use the GICC IIDR Architecture version here, but
|
||||
// this does not seem to be very reliable as the implementation could easily
|
||||
// get it wrong. It is more reliable to check if the GICv3 System Register
|
||||
// feature is implemented on the CPU. This is also convenient as our GICv3
|
||||
// driver requires SRE. If only Memory mapped access is available we try to
|
||||
// drive the GIC as a v2.
|
||||
if (ArmReadIdPfr1 () & ARM_PFR1_GIC) {
|
||||
// Make sure System Register access is enabled (SRE). This depends on the
|
||||
// higher privilege level giving us permission, otherwise we will either
|
||||
// cause an exception here, or the write doesn't stick in which case we need
|
||||
// to fall back to the GICv2 MMIO interface.
|
||||
// Note: We do not need to set ICC_SRE_EL2.Enable because the OS is started
|
||||
// at the same exception level.
|
||||
// It is the OS responsibility to set this bit.
|
||||
IccSre = ArmGicV3GetControlSystemRegisterEnable ();
|
||||
if (!(IccSre & ICC_SRE_EL2_SRE)) {
|
||||
ArmGicV3SetControlSystemRegisterEnable (IccSre| ICC_SRE_EL2_SRE);
|
||||
IccSre = ArmGicV3GetControlSystemRegisterEnable ();
|
||||
}
|
||||
if (IccSre & ICC_SRE_EL2_SRE) {
|
||||
mGicArchRevision = ARM_GIC_ARCH_REVISION_3;
|
||||
goto Done;
|
||||
}
|
||||
}
|
||||
|
||||
mGicArchRevision = ARM_GIC_ARCH_REVISION_2;
|
||||
|
||||
Done:
|
||||
return RETURN_SUCCESS;
|
||||
}
|
||||
|
||||
ARM_GIC_ARCH_REVISION
|
||||
EFIAPI
|
||||
ArmGicGetSupportedArchRevision (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
return mGicArchRevision;
|
||||
}
|
@ -25,7 +25,7 @@ ArmGicArchLibInitialize (
|
||||
// feature is implemented on the CPU. This is also convenient as our GICv3
|
||||
// driver requires SRE. If only Memory mapped access is available we try to
|
||||
// drive the GIC as a v2.
|
||||
if (ArmReadIdPfr0 () & AARCH64_PFR0_GIC) {
|
||||
if (ArmHasGicSystemRegisters ()) {
|
||||
// Make sure System Register access is enabled (SRE). This depends on the
|
||||
// higher privilege level giving us permission, otherwise we will either
|
||||
// cause an exception here, or the write doesn't stick in which case we need
|
@ -14,11 +14,8 @@
|
||||
LIBRARY_CLASS = ArmGicArchLib|DXE_DRIVER UEFI_DRIVER UEFI_APPLICATION
|
||||
CONSTRUCTOR = ArmGicArchLibInitialize
|
||||
|
||||
[Sources.ARM]
|
||||
Arm/ArmGicArchLib.c
|
||||
|
||||
[Sources.AARCH64]
|
||||
AArch64/ArmGicArchLib.c
|
||||
[Sources]
|
||||
ArmGicArchLib.c
|
||||
|
||||
[Packages]
|
||||
MdePkg/MdePkg.dec
|
||||
|
@ -1,45 +0,0 @@
|
||||
/** @file
|
||||
*
|
||||
* Copyright (c) 2014, ARM Limited. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
*
|
||||
**/
|
||||
|
||||
#include <Library/ArmLib.h>
|
||||
#include <Library/ArmGicLib.h>
|
||||
|
||||
ARM_GIC_ARCH_REVISION
|
||||
EFIAPI
|
||||
ArmGicGetSupportedArchRevision (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
UINT32 IccSre;
|
||||
|
||||
// Ideally we would like to use the GICC IIDR Architecture version here, but
|
||||
// this does not seem to be very reliable as the implementation could easily
|
||||
// get it wrong. It is more reliable to check if the GICv3 System Register
|
||||
// feature is implemented on the CPU. This is also convenient as our GICv3
|
||||
// driver requires SRE. If only Memory mapped access is available we try to
|
||||
// drive the GIC as a v2.
|
||||
if (ArmReadIdPfr1 () & ARM_PFR1_GIC) {
|
||||
// Make sure System Register access is enabled (SRE). This depends on the
|
||||
// higher privilege level giving us permission, otherwise we will either
|
||||
// cause an exception here, or the write doesn't stick in which case we need
|
||||
// to fall back to the GICv2 MMIO interface.
|
||||
// Note: We do not need to set ICC_SRE_EL2.Enable because the OS is started
|
||||
// at the same exception level.
|
||||
// It is the OS responsibility to set this bit.
|
||||
IccSre = ArmGicV3GetControlSystemRegisterEnable ();
|
||||
if (!(IccSre & ICC_SRE_EL2_SRE)) {
|
||||
ArmGicV3SetControlSystemRegisterEnable (IccSre| ICC_SRE_EL2_SRE);
|
||||
IccSre = ArmGicV3GetControlSystemRegisterEnable ();
|
||||
}
|
||||
if (IccSre & ICC_SRE_EL2_SRE) {
|
||||
return ARM_GIC_ARCH_REVISION_3;
|
||||
}
|
||||
}
|
||||
|
||||
return ARM_GIC_ARCH_REVISION_2;
|
||||
}
|
@ -23,7 +23,7 @@ ArmGicGetSupportedArchRevision (
|
||||
// feature is implemented on the CPU. This is also convenient as our GICv3
|
||||
// driver requires SRE. If only Memory mapped access is available we try to
|
||||
// drive the GIC as a v2.
|
||||
if (ArmReadIdPfr0 () & AARCH64_PFR0_GIC) {
|
||||
if (ArmHasGicSystemRegisters ()) {
|
||||
// Make sure System Register access is enabled (SRE). This depends on the
|
||||
// higher privilege level giving us permission, otherwise we will either
|
||||
// cause an exception here, or the write doesn't stick in which case we need
|
@ -13,11 +13,8 @@
|
||||
VERSION_STRING = 1.0
|
||||
LIBRARY_CLASS = ArmGicArchLib|SEC
|
||||
|
||||
[Sources.ARM]
|
||||
Arm/ArmGicArchLib.c
|
||||
|
||||
[Sources.AARCH64]
|
||||
AArch64/ArmGicArchLib.c
|
||||
[Sources]
|
||||
ArmGicArchLib.c
|
||||
|
||||
[Packages]
|
||||
MdePkg/MdePkg.dec
|
||||
|
@ -2,16 +2,19 @@
|
||||
|
||||
Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
|
||||
Portions copyright (c) 2011 - 2014, ARM Ltd. All rights reserved.<BR>
|
||||
Copyright (c) 2021, NUVIA Inc. All rights reserved.<BR>
|
||||
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
**/
|
||||
|
||||
#include <Uefi.h>
|
||||
#include <Chipset/AArch64.h>
|
||||
#include <Base.h>
|
||||
|
||||
#include <Library/ArmLib.h>
|
||||
#include <Library/BaseLib.h>
|
||||
#include <Library/IoLib.h>
|
||||
#include <Library/DebugLib.h>
|
||||
|
||||
#include <Chipset/AArch64.h>
|
||||
|
||||
#include "AArch64Lib.h"
|
||||
#include "ArmLibPrivate.h"
|
||||
|
||||
@ -40,6 +43,8 @@ ArmInvalidateDataCache (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
ASSERT (!ArmMmuEnabled ());
|
||||
|
||||
ArmDataSynchronizationBarrier ();
|
||||
AArch64DataCacheOperation (ArmInvalidateDataCacheEntryBySetWay);
|
||||
}
|
||||
@ -50,6 +55,8 @@ ArmCleanInvalidateDataCache (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
ASSERT (!ArmMmuEnabled ());
|
||||
|
||||
ArmDataSynchronizationBarrier ();
|
||||
AArch64DataCacheOperation (ArmCleanInvalidateDataCacheEntryBySetWay);
|
||||
}
|
||||
@ -60,6 +67,40 @@ ArmCleanDataCache (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
ASSERT (!ArmMmuEnabled ());
|
||||
|
||||
ArmDataSynchronizationBarrier ();
|
||||
AArch64DataCacheOperation (ArmCleanDataCacheEntryBySetWay);
|
||||
}
|
||||
|
||||
/**
|
||||
Check whether the CPU supports the GIC system register interface (any version)
|
||||
|
||||
@return Whether GIC System Register Interface is supported
|
||||
|
||||
**/
|
||||
BOOLEAN
|
||||
EFIAPI
|
||||
ArmHasGicSystemRegisters (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
return ((ArmReadIdAA64Pfr0 () & AARCH64_PFR0_GIC) != 0);
|
||||
}
|
||||
|
||||
/** Checks if CCIDX is implemented.
|
||||
|
||||
@retval TRUE CCIDX is implemented.
|
||||
@retval FALSE CCIDX is not implemented.
|
||||
**/
|
||||
BOOLEAN
|
||||
EFIAPI
|
||||
ArmHasCcidx (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
UINTN Mmfr2;
|
||||
|
||||
Mmfr2 = ArmReadIdAA64Mmfr2 ();
|
||||
return (((Mmfr2 >> 20) & 0xF) == 1) ? TRUE : FALSE;
|
||||
}
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
|
||||
Portions Copyright (c) 2011 - 2013, ARM Ltd. All rights reserved.<BR>
|
||||
Copyright (c) 2020, NUVIA Inc. All rights reserved.<BR>
|
||||
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
@ -17,5 +18,39 @@ AArch64AllDataCachesOperation (
|
||||
IN AARCH64_CACHE_OPERATION DataCacheOperation
|
||||
);
|
||||
|
||||
VOID
|
||||
EFIAPI
|
||||
ArmInvalidateDataCacheEntryBySetWay (
|
||||
IN UINTN SetWayFormat
|
||||
);
|
||||
|
||||
VOID
|
||||
EFIAPI
|
||||
ArmCleanDataCacheEntryBySetWay (
|
||||
IN UINTN SetWayFormat
|
||||
);
|
||||
|
||||
VOID
|
||||
EFIAPI
|
||||
ArmCleanInvalidateDataCacheEntryBySetWay (
|
||||
IN UINTN SetWayFormat
|
||||
);
|
||||
|
||||
UINTN
|
||||
EFIAPI
|
||||
ArmReadIdAA64Pfr0 (
|
||||
VOID
|
||||
);
|
||||
|
||||
/** Reads the ID_AA64MMFR2_EL1 register.
|
||||
|
||||
@return The contents of the ID_AA64MMFR2_EL1 register.
|
||||
**/
|
||||
UINTN
|
||||
EFIAPI
|
||||
ArmReadIdAA64Mmfr2 (
|
||||
VOID
|
||||
);
|
||||
|
||||
#endif // __AARCH64_LIB_H__
|
||||
|
||||
|
@ -3,6 +3,7 @@
|
||||
# Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>
|
||||
# Copyright (c) 2011 - 2017, ARM Limited. All rights reserved.
|
||||
# Copyright (c) 2016, Linaro Limited. All rights reserved.
|
||||
# Copyright (c) 2020, NUVIA Inc. All rights reserved.
|
||||
#
|
||||
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
#
|
||||
@ -395,7 +396,7 @@ ASM_FUNC(ArmReadVBar)
|
||||
ASM_FUNC(ArmEnableVFP)
|
||||
// Check whether floating-point is implemented in the processor.
|
||||
mov x1, x30 // Save LR
|
||||
bl ArmReadIdPfr0 // Read EL1 Processor Feature Register (PFR0)
|
||||
bl ArmReadIdAA64Pfr0 // Read EL1 Processor Feature Register (PFR0)
|
||||
mov x30, x1 // Restore LR
|
||||
ubfx x0, x0, #16, #4 // Extract the FP bits 16:19
|
||||
cmp x0, #0xF // Check if FP bits are '1111b',
|
||||
@ -424,6 +425,9 @@ ASM_FUNC(ArmCallWFI)
|
||||
wfi
|
||||
ret
|
||||
|
||||
ASM_FUNC(ArmReadIdAA64Mmfr2)
|
||||
mrs x0, ID_AA64MMFR2_EL1 // read EL1 MMFR2
|
||||
ret
|
||||
|
||||
ASM_FUNC(ArmReadMpidr)
|
||||
mrs x0, mpidr_el1 // read EL1 MPIDR
|
||||
@ -448,19 +452,11 @@ ASM_FUNC(ArmIsArchTimerImplemented)
|
||||
ret
|
||||
|
||||
|
||||
ASM_FUNC(ArmReadIdPfr0)
|
||||
ASM_FUNC(ArmReadIdAA64Pfr0)
|
||||
mrs x0, id_aa64pfr0_el1 // Read ID_AA64PFR0 Register
|
||||
ret
|
||||
|
||||
|
||||
// Q: id_aa64pfr1_el1 not defined yet. What does this function want to access?
|
||||
// A: used to setup arch timer. Check if we have security extensions, permissions to set stuff.
|
||||
// See: ArmPkg/Library/ArmArchTimerLib/AArch64/ArmArchTimerLib.c
|
||||
// Not defined yet, but stick in here for now, should read all zeros.
|
||||
ASM_FUNC(ArmReadIdPfr1)
|
||||
mrs x0, id_aa64pfr1_el1 // Read ID_PFR1 Register
|
||||
ret
|
||||
|
||||
// VOID ArmWriteHcr(UINTN Hcr)
|
||||
ASM_FUNC(ArmWriteHcr)
|
||||
msr hcr_el2, x0 // Write the passed HCR value
|
||||
|
@ -13,6 +13,8 @@
|
||||
.set DAIF_RD_FIQ_BIT, (1 << 6)
|
||||
.set DAIF_RD_IRQ_BIT, (1 << 7)
|
||||
|
||||
.set SCTLR_ELx_M_BIT_POS, (0)
|
||||
|
||||
ASM_FUNC(ArmReadMidr)
|
||||
mrs x0, midr_el1 // Read from Main ID Register (MIDR)
|
||||
ret
|
||||
@ -120,13 +122,18 @@ ASM_FUNC(ArmSetMAIR)
|
||||
ASM_FUNC(ArmUpdateTranslationTableEntry)
|
||||
dsb nshst
|
||||
lsr x1, x1, #12
|
||||
EL1_OR_EL2_OR_EL3(x0)
|
||||
EL1_OR_EL2_OR_EL3(x2)
|
||||
1: tlbi vaae1, x1 // TLB Invalidate VA , EL1
|
||||
mrs x2, sctlr_el1
|
||||
b 4f
|
||||
2: tlbi vae2, x1 // TLB Invalidate VA , EL2
|
||||
mrs x2, sctlr_el2
|
||||
b 4f
|
||||
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
|
||||
ret
|
||||
|
||||
|
@ -84,7 +84,7 @@ ASM_FUNC(ArmDisableAllExceptions)
|
||||
ret
|
||||
|
||||
|
||||
// UINT32
|
||||
// UINTN
|
||||
// ReadCCSIDR (
|
||||
// IN UINT32 CSSELR
|
||||
// )
|
||||
|
@ -60,7 +60,11 @@ ASM_FUNC(ArmDisableInterrupts)
|
||||
isb
|
||||
bx LR
|
||||
|
||||
// UINT32
|
||||
ASM_FUNC(ArmReadIdMmfr4)
|
||||
mrc p15,0,r0,c0,c2,6 @ Read ID_MMFR4 Register
|
||||
bx lr
|
||||
|
||||
// UINTN
|
||||
// ReadCCSIDR (
|
||||
// IN UINT32 CSSELR
|
||||
// )
|
||||
@ -70,6 +74,16 @@ ASM_FUNC(ReadCCSIDR)
|
||||
mrc p15,1,r0,c0,c0,0 @ Read current CP15 Cache Size ID Register (CCSIDR)
|
||||
bx lr
|
||||
|
||||
// UINT32
|
||||
// ReadCCSIDR2 (
|
||||
// IN UINT32 CSSELR
|
||||
// )
|
||||
ASM_FUNC(ReadCCSIDR2)
|
||||
mcr p15,2,r0,c0,c0,0 @ Write Cache Size Selection Register (CSSELR)
|
||||
isb
|
||||
mrc p15,1,r0,c0,c0,2 @ Read current CP15 Cache Size ID Register (CCSIDR2)
|
||||
bx lr
|
||||
|
||||
// UINT32
|
||||
// ReadCLIDR (
|
||||
// IN UINT32 CSSELR
|
||||
|
@ -64,7 +64,11 @@
|
||||
isb
|
||||
bx LR
|
||||
|
||||
// UINT32
|
||||
RVCT_ASM_EXPORT ArmReadIdMmfr4
|
||||
mrc p15,0,r0,c0,c2,6 ; Read ID_MMFR4 Register
|
||||
bx LR
|
||||
|
||||
// UINTN
|
||||
// ReadCCSIDR (
|
||||
// IN UINT32 CSSELR
|
||||
// )
|
||||
@ -74,6 +78,16 @@
|
||||
mrc p15,1,r0,c0,c0,0 ; Read current CP15 Cache Size ID Register (CCSIDR)
|
||||
bx lr
|
||||
|
||||
// UINT32
|
||||
// ReadCCSIDR2 (
|
||||
// IN UINT32 CSSELR
|
||||
// )
|
||||
RVCT_ASM_EXPORT ReadCCSIDR2
|
||||
mcr p15,2,r0,c0,c0,0 ; Write Cache Size Selection Register (CSSELR)
|
||||
isb
|
||||
mrc p15,1,r0,c0,c0,2 ; Read current CP15 Cache Size ID Register (CCSIDR2)
|
||||
bx lr
|
||||
|
||||
// UINT32
|
||||
// ReadCLIDR (
|
||||
// IN UINT32 CSSELR
|
||||
|
@ -2,15 +2,19 @@
|
||||
|
||||
Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
|
||||
Copyright (c) 2011 - 2014, ARM Limited. All rights reserved.
|
||||
Copyright (c) 2021, NUVIA Inc. All rights reserved.<BR>
|
||||
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
**/
|
||||
#include <Uefi.h>
|
||||
#include <Chipset/ArmV7.h>
|
||||
|
||||
#include <Base.h>
|
||||
|
||||
#include <Library/ArmLib.h>
|
||||
#include <Library/BaseLib.h>
|
||||
#include <Library/IoLib.h>
|
||||
#include <Library/DebugLib.h>
|
||||
|
||||
#include <Chipset/ArmV7.h>
|
||||
|
||||
#include "ArmV7Lib.h"
|
||||
#include "ArmLibPrivate.h"
|
||||
|
||||
@ -39,6 +43,8 @@ ArmInvalidateDataCache (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
ASSERT (!ArmMmuEnabled ());
|
||||
|
||||
ArmDataSynchronizationBarrier ();
|
||||
ArmV7DataCacheOperation (ArmInvalidateDataCacheEntryBySetWay);
|
||||
}
|
||||
@ -49,6 +55,8 @@ ArmCleanInvalidateDataCache (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
ASSERT (!ArmMmuEnabled ());
|
||||
|
||||
ArmDataSynchronizationBarrier ();
|
||||
ArmV7DataCacheOperation (ArmCleanInvalidateDataCacheEntryBySetWay);
|
||||
}
|
||||
@ -59,6 +67,55 @@ ArmCleanDataCache (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
ASSERT (!ArmMmuEnabled ());
|
||||
|
||||
ArmDataSynchronizationBarrier ();
|
||||
ArmV7DataCacheOperation (ArmCleanDataCacheEntryBySetWay);
|
||||
}
|
||||
|
||||
/**
|
||||
Check whether the CPU supports the GIC system register interface (any version)
|
||||
|
||||
@return Whether GIC System Register Interface is supported
|
||||
|
||||
**/
|
||||
BOOLEAN
|
||||
EFIAPI
|
||||
ArmHasGicSystemRegisters (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
return ((ArmReadIdPfr1 () & ARM_PFR1_GIC) != 0);
|
||||
}
|
||||
|
||||
/**
|
||||
Check whether the CPU supports the Security extensions
|
||||
|
||||
@return Whether the Security extensions are implemented
|
||||
|
||||
**/
|
||||
BOOLEAN
|
||||
EFIAPI
|
||||
ArmHasSecurityExtensions (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
return ((ArmReadIdPfr1 () & ARM_PFR1_SEC) != 0);
|
||||
}
|
||||
|
||||
/** Checks if CCIDX is implemented.
|
||||
|
||||
@retval TRUE CCIDX is implemented.
|
||||
@retval FALSE CCIDX is not implemented.
|
||||
**/
|
||||
BOOLEAN
|
||||
EFIAPI
|
||||
ArmHasCcidx (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
UINTN Mmfr4;
|
||||
|
||||
Mmfr4 = ArmReadIdMmfr4 ();
|
||||
return (((Mmfr4 >> 24) & 0xF) == 1) ? TRUE : FALSE;
|
||||
}
|
||||
|
@ -30,5 +30,39 @@ ArmV7AllDataCachesOperation (
|
||||
IN ARM_V7_CACHE_OPERATION DataCacheOperation
|
||||
);
|
||||
|
||||
VOID
|
||||
EFIAPI
|
||||
ArmInvalidateDataCacheEntryBySetWay (
|
||||
IN UINTN SetWayFormat
|
||||
);
|
||||
|
||||
VOID
|
||||
EFIAPI
|
||||
ArmCleanDataCacheEntryBySetWay (
|
||||
IN UINTN SetWayFormat
|
||||
);
|
||||
|
||||
VOID
|
||||
EFIAPI
|
||||
ArmCleanInvalidateDataCacheEntryBySetWay (
|
||||
IN UINTN SetWayFormat
|
||||
);
|
||||
|
||||
/** Reads the ID_MMFR4 register.
|
||||
|
||||
@return The contents of the ID_MMFR4 register.
|
||||
**/
|
||||
UINT32
|
||||
EFIAPI
|
||||
ArmReadIdMmfr4 (
|
||||
VOID
|
||||
);
|
||||
|
||||
UINTN
|
||||
EFIAPI
|
||||
ArmReadIdPfr1 (
|
||||
VOID
|
||||
);
|
||||
|
||||
#endif // __ARM_V7_LIB_H__
|
||||
|
||||
|
@ -44,12 +44,12 @@
|
||||
AArch64/AArch64Support.S
|
||||
AArch64/AArch64ArchTimerSupport.S
|
||||
|
||||
[LibraryClasses]
|
||||
DebugLib
|
||||
|
||||
[Packages]
|
||||
ArmPkg/ArmPkg.dec
|
||||
MdePkg/MdePkg.dec
|
||||
|
||||
[Protocols]
|
||||
gEfiCpuArchProtocolGuid
|
||||
|
||||
[FeaturePcd.ARM]
|
||||
gArmTokenSpaceGuid.PcdNormalMemoryNonshareableOverride
|
||||
|
@ -1,7 +1,7 @@
|
||||
/** @file
|
||||
|
||||
Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
|
||||
Copyright (c) 2011 - 2014, ARM Ltd. All rights reserved.<BR>
|
||||
Copyright (c) 2011 - 2021, ARM Ltd. All rights reserved.<BR>
|
||||
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
@ -10,8 +10,6 @@
|
||||
#include <Base.h>
|
||||
|
||||
#include <Library/ArmLib.h>
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Library/PcdLib.h>
|
||||
|
||||
#include "ArmLibPrivate.h"
|
||||
|
||||
@ -21,9 +19,7 @@ ArmSetAuxCrBit (
|
||||
IN UINT32 Bits
|
||||
)
|
||||
{
|
||||
UINT32 val = ArmReadAuxCr();
|
||||
val |= Bits;
|
||||
ArmWriteAuxCr(val);
|
||||
ArmWriteAuxCr(ArmReadAuxCr() | Bits);
|
||||
}
|
||||
|
||||
VOID
|
||||
@ -32,9 +28,7 @@ ArmUnsetAuxCrBit (
|
||||
IN UINT32 Bits
|
||||
)
|
||||
{
|
||||
UINT32 val = ArmReadAuxCr();
|
||||
val &= ~Bits;
|
||||
ArmWriteAuxCr(val);
|
||||
ArmWriteAuxCr(ArmReadAuxCr() & ~Bits);
|
||||
}
|
||||
|
||||
//
|
||||
@ -47,10 +41,7 @@ ArmSetCpuActlrBit (
|
||||
IN UINTN Bits
|
||||
)
|
||||
{
|
||||
UINTN Value;
|
||||
Value = ArmReadCpuActlr ();
|
||||
Value |= Bits;
|
||||
ArmWriteCpuActlr (Value);
|
||||
ArmWriteCpuActlr (ArmReadCpuActlr () | Bits);
|
||||
}
|
||||
|
||||
VOID
|
||||
@ -59,10 +50,7 @@ ArmUnsetCpuActlrBit (
|
||||
IN UINTN Bits
|
||||
)
|
||||
{
|
||||
UINTN Value;
|
||||
Value = ArmReadCpuActlr ();
|
||||
Value &= ~Bits;
|
||||
ArmWriteCpuActlr (Value);
|
||||
ArmWriteCpuActlr (ArmReadCpuActlr () & ~Bits);
|
||||
}
|
||||
|
||||
UINTN
|
||||
|
@ -1,5 +1,7 @@
|
||||
/** @file
|
||||
ArmLibPrivate.h
|
||||
|
||||
Copyright (c) 2020, NUVIA Inc. All rights reserved.<BR>
|
||||
Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
|
||||
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
@ -50,6 +52,101 @@
|
||||
#define CACHE_ARCHITECTURE_UNIFIED (0UL)
|
||||
#define CACHE_ARCHITECTURE_SEPARATE (1UL)
|
||||
|
||||
|
||||
/// Defines the structure of the CSSELR (Cache Size Selection) register
|
||||
typedef union {
|
||||
struct {
|
||||
UINT32 InD :1; ///< Instruction not Data bit
|
||||
UINT32 Level :3; ///< Cache level (zero based)
|
||||
UINT32 TnD :1; ///< Allocation not Data bit
|
||||
UINT32 Reserved :27; ///< Reserved, RES0
|
||||
} Bits; ///< Bitfield definition of the register
|
||||
UINT32 Data; ///< The entire 32-bit value
|
||||
} CSSELR_DATA;
|
||||
|
||||
/// The cache type values for the InD field of the CSSELR register
|
||||
typedef enum
|
||||
{
|
||||
/// Select the data or unified cache
|
||||
CsselrCacheTypeDataOrUnified = 0,
|
||||
/// Select the instruction cache
|
||||
CsselrCacheTypeInstruction,
|
||||
CsselrCacheTypeMax
|
||||
} CSSELR_CACHE_TYPE;
|
||||
|
||||
/// Defines the structure of the CCSIDR (Current Cache Size ID) register
|
||||
typedef union {
|
||||
struct {
|
||||
UINT64 LineSize :3; ///< Line size (Log2(Num bytes in cache) - 4)
|
||||
UINT64 Associativity :10; ///< Associativity - 1
|
||||
UINT64 NumSets :15; ///< Number of sets in the cache -1
|
||||
UINT64 Unknown :4; ///< Reserved, UNKNOWN
|
||||
UINT64 Reserved :32; ///< Reserved, RES0
|
||||
} BitsNonCcidx; ///< Bitfield definition of the register when FEAT_CCIDX is not supported.
|
||||
struct {
|
||||
UINT64 LineSize :3; ///< Line size (Log2(Num bytes in cache) - 4)
|
||||
UINT64 Associativity :21; ///< Associativity - 1
|
||||
UINT64 Reserved1 :8; ///< Reserved, RES0
|
||||
UINT64 NumSets :24; ///< Number of sets in the cache -1
|
||||
UINT64 Reserved2 :8; ///< Reserved, RES0
|
||||
} BitsCcidxAA64; ///< Bitfield definition of the register when FEAT_IDX is supported.
|
||||
struct {
|
||||
UINT64 LineSize : 3;
|
||||
UINT64 Associativity : 21;
|
||||
UINT64 Reserved : 8;
|
||||
UINT64 Unallocated : 32;
|
||||
} BitsCcidxAA32;
|
||||
UINT64 Data; ///< The entire 64-bit value
|
||||
} CCSIDR_DATA;
|
||||
|
||||
/// Defines the structure of the AARCH32 CCSIDR2 register.
|
||||
typedef union {
|
||||
struct {
|
||||
UINT32 NumSets :24; ///< Number of sets in the cache - 1
|
||||
UINT32 Reserved :8; ///< Reserved, RES0
|
||||
} Bits; ///< Bitfield definition of the register
|
||||
UINT32 Data; ///< The entire 32-bit value
|
||||
} CCSIDR2_DATA;
|
||||
|
||||
/** Defines the structure of the CLIDR (Cache Level ID) register.
|
||||
*
|
||||
* The lower 32 bits are the same for both AARCH32 and AARCH64
|
||||
* so we can use the same structure for both.
|
||||
**/
|
||||
typedef union {
|
||||
struct {
|
||||
UINT32 Ctype1 : 3; ///< Level 1 cache type
|
||||
UINT32 Ctype2 : 3; ///< Level 2 cache type
|
||||
UINT32 Ctype3 : 3; ///< Level 3 cache type
|
||||
UINT32 Ctype4 : 3; ///< Level 4 cache type
|
||||
UINT32 Ctype5 : 3; ///< Level 5 cache type
|
||||
UINT32 Ctype6 : 3; ///< Level 6 cache type
|
||||
UINT32 Ctype7 : 3; ///< Level 7 cache type
|
||||
UINT32 LoUIS : 3; ///< Level of Unification Inner Shareable
|
||||
UINT32 LoC : 3; ///< Level of Coherency
|
||||
UINT32 LoUU : 3; ///< Level of Unification Uniprocessor
|
||||
UINT32 Icb : 3; ///< Inner Cache Boundary
|
||||
} Bits; ///< Bitfield definition of the register
|
||||
UINT32 Data; ///< The entire 32-bit value
|
||||
} CLIDR_DATA;
|
||||
|
||||
/// The cache types reported in the CLIDR register.
|
||||
typedef enum {
|
||||
/// No cache is present
|
||||
ClidrCacheTypeNone = 0,
|
||||
/// There is only an instruction cache
|
||||
ClidrCacheTypeInstructionOnly,
|
||||
/// There is only a data cache
|
||||
ClidrCacheTypeDataOnly,
|
||||
/// There are separate data and instruction caches
|
||||
ClidrCacheTypeSeparate,
|
||||
/// There is a unified cache
|
||||
ClidrCacheTypeUnified,
|
||||
ClidrCacheTypeMax
|
||||
} CLIDR_CACHE_TYPE;
|
||||
|
||||
#define CLIDR_GET_CACHE_TYPE(x, level) ((x >> (3 * (level))) & 0b111)
|
||||
|
||||
VOID
|
||||
CPSRMaskInsert (
|
||||
IN UINT32 Mask,
|
||||
@ -61,11 +158,29 @@ CPSRRead (
|
||||
VOID
|
||||
);
|
||||
|
||||
UINT32
|
||||
/** Reads the CCSIDR register for the specified cache.
|
||||
|
||||
@param CSSELR The CSSELR cache selection register value.
|
||||
|
||||
@return The contents of the CCSIDR_EL1 register for the specified cache, when in AARCH64 mode.
|
||||
Returns the contents of the CCSIDR register in AARCH32 mode.
|
||||
**/
|
||||
UINTN
|
||||
ReadCCSIDR (
|
||||
IN UINT32 CSSELR
|
||||
);
|
||||
|
||||
/** Reads the CCSIDR2 for the specified cache.
|
||||
|
||||
@param CSSELR The CSSELR cache selection register value
|
||||
|
||||
@return The contents of the CCSIDR2 register for the specified cache.
|
||||
**/
|
||||
UINT32
|
||||
ReadCCSIDR2 (
|
||||
IN UINT32 CSSELR
|
||||
);
|
||||
|
||||
UINT32
|
||||
ReadCLIDR (
|
||||
VOID
|
||||
|
@ -1,7 +1,7 @@
|
||||
/** @file
|
||||
* 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) 2017, Intel Corporation. All rights reserved.<BR>
|
||||
*
|
||||
@ -19,9 +19,6 @@
|
||||
#include <Library/BaseLib.h>
|
||||
#include <Library/DebugLib.h>
|
||||
|
||||
// We use this index definition to define an invalid block entry
|
||||
#define TT_ATTR_INDX_INVALID ((UINT32)~0)
|
||||
|
||||
STATIC
|
||||
UINT64
|
||||
ArmMemoryAttributeToPageAttribute (
|
||||
@ -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 BITS_PER_LEVEL 9
|
||||
#define MAX_VA_BITS 48
|
||||
|
||||
VOID
|
||||
GetRootTranslationTableInfo (
|
||||
IN UINTN T0SZ,
|
||||
OUT UINTN *TableLevel,
|
||||
OUT UINTN *TableEntryCount
|
||||
STATIC
|
||||
UINTN
|
||||
GetRootTableEntryCount (
|
||||
IN UINTN T0SZ
|
||||
)
|
||||
{
|
||||
// Get the level of the root table
|
||||
if (TableLevel) {
|
||||
*TableLevel = (T0SZ - MIN_T0SZ) / BITS_PER_LEVEL;
|
||||
return TT_ENTRY_COUNT >> (T0SZ - MIN_T0SZ) % BITS_PER_LEVEL;
|
||||
}
|
||||
|
||||
if (TableEntryCount) {
|
||||
*TableEntryCount = 1UL << (BITS_PER_LEVEL - (T0SZ - MIN_T0SZ) % BITS_PER_LEVEL);
|
||||
}
|
||||
STATIC
|
||||
UINTN
|
||||
GetRootTableLevel (
|
||||
IN UINTN T0SZ
|
||||
)
|
||||
{
|
||||
return (T0SZ - MIN_T0SZ) / BITS_PER_LEVEL;
|
||||
}
|
||||
|
||||
STATIC
|
||||
VOID
|
||||
ReplaceLiveEntry (
|
||||
ReplaceTableEntry (
|
||||
IN UINT64 *Entry,
|
||||
IN UINT64 Value,
|
||||
IN UINT64 RegionStart
|
||||
IN UINT64 RegionStart,
|
||||
IN BOOLEAN IsLiveBlockMapping
|
||||
)
|
||||
{
|
||||
if (!ArmMmuEnabled ()) {
|
||||
if (!ArmMmuEnabled () || !IsLiveBlockMapping) {
|
||||
*Entry = Value;
|
||||
ArmUpdateTranslationTableEntry (Entry, (VOID *)(UINTN)RegionStart);
|
||||
} else {
|
||||
ArmReplaceLiveTranslationEntry (Entry, Value, RegionStart);
|
||||
}
|
||||
@ -136,258 +95,214 @@ ReplaceLiveEntry (
|
||||
|
||||
STATIC
|
||||
VOID
|
||||
LookupAddresstoRootTable (
|
||||
IN UINT64 MaxAddress,
|
||||
OUT UINTN *T0SZ,
|
||||
OUT UINTN *TableEntryCount
|
||||
FreePageTablesRecursive (
|
||||
IN UINT64 *TranslationTable,
|
||||
IN UINTN Level
|
||||
)
|
||||
{
|
||||
UINTN TopBit;
|
||||
UINTN Index;
|
||||
|
||||
// Check the parameters are not NULL
|
||||
ASSERT ((T0SZ != NULL) && (TableEntryCount != NULL));
|
||||
ASSERT (Level <= 3);
|
||||
|
||||
// Look for the highest bit set in MaxAddress
|
||||
for (TopBit = 63; TopBit != 0; TopBit--) {
|
||||
if ((1ULL << TopBit) & MaxAddress) {
|
||||
// MaxAddress top bit is found
|
||||
TopBit = TopBit + 1;
|
||||
break;
|
||||
if (Level < 3) {
|
||||
for (Index = 0; Index < TT_ENTRY_COUNT; Index++) {
|
||||
if ((TranslationTable[Index] & TT_TYPE_MASK) == TT_TYPE_TABLE_ENTRY) {
|
||||
FreePageTablesRecursive ((VOID *)(UINTN)(TranslationTable[Index] &
|
||||
TT_ADDRESS_MASK_BLOCK_ENTRY),
|
||||
Level + 1);
|
||||
}
|
||||
}
|
||||
ASSERT (TopBit != 0);
|
||||
|
||||
// Calculate T0SZ from the top bit of the MaxAddress
|
||||
*T0SZ = 64 - TopBit;
|
||||
|
||||
// Get the Table info from T0SZ
|
||||
GetRootTranslationTableInfo (*T0SZ, NULL, TableEntryCount);
|
||||
}
|
||||
FreePages (TranslationTable, 1);
|
||||
}
|
||||
|
||||
STATIC
|
||||
UINT64*
|
||||
GetBlockEntryListFromAddress (
|
||||
IN UINT64 *RootTable,
|
||||
IN UINT64 RegionStart,
|
||||
OUT UINTN *TableLevel,
|
||||
IN OUT UINT64 *BlockEntrySize,
|
||||
OUT UINT64 **LastBlockEntry
|
||||
BOOLEAN
|
||||
IsBlockEntry (
|
||||
IN UINT64 Entry,
|
||||
IN UINTN Level
|
||||
)
|
||||
{
|
||||
UINTN RootTableLevel;
|
||||
UINTN RootTableEntryCount;
|
||||
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;
|
||||
if (Level == 3) {
|
||||
return (Entry & TT_TYPE_MASK) == TT_TYPE_BLOCK_ENTRY_LEVEL3;
|
||||
}
|
||||
return (Entry & TT_TYPE_MASK) == TT_TYPE_BLOCK_ENTRY;
|
||||
}
|
||||
|
||||
// Ensure the Region is aligned on 4KB boundary
|
||||
if ((RegionStart & (SIZE_4KB - 1)) != 0) {
|
||||
ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER);
|
||||
return NULL;
|
||||
STATIC
|
||||
BOOLEAN
|
||||
IsTableEntry (
|
||||
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
|
||||
if ((*BlockEntrySize & (SIZE_4KB - 1)) != 0 || *BlockEntrySize == 0) {
|
||||
ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER);
|
||||
return NULL;
|
||||
}
|
||||
STATIC
|
||||
EFI_STATUS
|
||||
UpdateRegionMappingRecursive (
|
||||
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;
|
||||
// Get the Table info from T0SZ
|
||||
GetRootTranslationTableInfo (T0SZ, &RootTableLevel, &RootTableEntryCount);
|
||||
ASSERT (((RegionStart | RegionEnd) & EFI_PAGE_MASK) == 0);
|
||||
|
||||
// If the start address is 0x0 then we use the size of the region to identify the alignment
|
||||
if (RegionStart == 0) {
|
||||
// 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);
|
||||
}
|
||||
BlockShift = (Level + 1) * BITS_PER_LEVEL + MIN_T0SZ;
|
||||
BlockMask = MAX_UINT64 >> BlockShift;
|
||||
|
||||
// Identify the Page Level the RegionStart must belong to. Note that PageLevel
|
||||
// should be at least 1 since block translations are not supported at level 0
|
||||
PageLevel = MAX (3 - ((BaseAddressAlignment - 12) / 9), 1);
|
||||
DEBUG ((DEBUG_VERBOSE, "%a(%d): %llx - %llx set %lx clr %lx\n", __FUNCTION__,
|
||||
Level, RegionStart, RegionEnd, AttributeSetMask, AttributeClearMask));
|
||||
|
||||
// If the required size is smaller than the current block size then we need to go to the page below.
|
||||
// The PageLevel was calculated on the Base Address alignment but did not take in account the alignment
|
||||
// of the allocation size
|
||||
while (*BlockEntrySize < TT_BLOCK_ENTRY_SIZE_AT_LEVEL (PageLevel)) {
|
||||
// It does not fit so we need to go a page level above
|
||||
PageLevel++;
|
||||
}
|
||||
for (; RegionStart < RegionEnd; RegionStart = BlockEnd) {
|
||||
BlockEnd = MIN (RegionEnd, (RegionStart | BlockMask) + 1);
|
||||
Entry = &PageTable[(RegionStart >> (64 - BlockShift)) & (TT_ENTRY_COUNT - 1)];
|
||||
|
||||
//
|
||||
// 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;
|
||||
for (IndexLevel = RootTableLevel; IndexLevel <= PageLevel; IndexLevel++) {
|
||||
BlockEntry = (UINT64*)TT_GET_ENTRY_FOR_ADDRESS (TranslationTable, IndexLevel, RegionStart);
|
||||
|
||||
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
|
||||
if (!IsTableEntry (*Entry, Level)) {
|
||||
//
|
||||
// No table entry exists yet, so we need to allocate a page table
|
||||
// for the next level.
|
||||
//
|
||||
TranslationTable = AllocatePages (1);
|
||||
if (TranslationTable == NULL) {
|
||||
return NULL;
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
// Populate the newly created lower level table
|
||||
SubTableBlockEntry = TranslationTable;
|
||||
for (Index = 0; Index < TT_ENTRY_COUNT; Index++) {
|
||||
*SubTableBlockEntry = Attributes | (BlockEntryAddress + (Index << TT_ADDRESS_OFFSET_AT_LEVEL(IndexLevel + 1)));
|
||||
SubTableBlockEntry++;
|
||||
if (!ArmMmuEnabled ()) {
|
||||
//
|
||||
// Make sure we are not inadvertently hitting in the caches
|
||||
// when populating the page tables.
|
||||
//
|
||||
InvalidateDataCacheRange (TranslationTable, EFI_PAGE_SIZE);
|
||||
}
|
||||
|
||||
// Fill the BlockEntry with the new TranslationTable
|
||||
ReplaceLiveEntry (BlockEntry,
|
||||
(UINTN)TranslationTable | TableAttributes | TT_TYPE_TABLE_ENTRY,
|
||||
RegionStart);
|
||||
ZeroMem (TranslationTable, EFI_PAGE_SIZE);
|
||||
|
||||
if (IsBlockEntry (*Entry, Level)) {
|
||||
//
|
||||
// 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 {
|
||||
if (IndexLevel != PageLevel) {
|
||||
TranslationTable = (VOID *)(UINTN)(*Entry & TT_ADDRESS_MASK_BLOCK_ENTRY);
|
||||
}
|
||||
|
||||
//
|
||||
// Case when we have an Invalid Entry and we are at a page level above of the one targetted.
|
||||
// Recurse to the next level
|
||||
//
|
||||
|
||||
// Create a new translation table
|
||||
TranslationTable = AllocatePages (1);
|
||||
if (TranslationTable == NULL) {
|
||||
return NULL;
|
||||
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;
|
||||
}
|
||||
|
||||
ZeroMem (TranslationTable, TT_ENTRY_COUNT * sizeof(UINT64));
|
||||
if (!IsTableEntry (*Entry, Level)) {
|
||||
EntryValue = (UINTN)TranslationTable | TT_TYPE_TABLE_ENTRY;
|
||||
ReplaceTableEntry (Entry, EntryValue, RegionStart,
|
||||
IsBlockEntry (*Entry, Level));
|
||||
}
|
||||
} else {
|
||||
EntryValue = (*Entry & AttributeClearMask) | AttributeSetMask;
|
||||
EntryValue |= RegionStart;
|
||||
EntryValue |= (Level == 3) ? TT_TYPE_BLOCK_ENTRY_LEVEL3
|
||||
: TT_TYPE_BLOCK_ENTRY;
|
||||
|
||||
// Fill the new BlockEntry with the TranslationTable
|
||||
*BlockEntry = ((UINTN)TranslationTable & TT_ADDRESS_MASK_DESCRIPTION_TABLE) | TT_TYPE_TABLE_ENTRY;
|
||||
if (IsTableEntry (*Entry, Level)) {
|
||||
//
|
||||
// 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);
|
||||
TranslationTable = (VOID *)(UINTN)(*Entry & TT_ADDRESS_MASK_BLOCK_ENTRY);
|
||||
ReplaceTableEntry (Entry, EntryValue, RegionStart, TRUE);
|
||||
FreePageTablesRecursive (TranslationTable, Level + 1);
|
||||
} else {
|
||||
ReplaceTableEntry (Entry, EntryValue, RegionStart, FALSE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 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;
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
STATIC
|
||||
EFI_STATUS
|
||||
UpdateRegionMapping (
|
||||
IN UINT64 *RootTable,
|
||||
IN UINT64 RegionStart,
|
||||
IN UINT64 RegionLength,
|
||||
IN UINT64 Attributes,
|
||||
IN UINT64 BlockEntryMask
|
||||
IN UINT64 AttributeSetMask,
|
||||
IN UINT64 AttributeClearMask
|
||||
)
|
||||
{
|
||||
UINT32 Type;
|
||||
UINT64 *BlockEntry;
|
||||
UINT64 *LastBlockEntry;
|
||||
UINT64 BlockEntrySize;
|
||||
UINTN TableLevel;
|
||||
UINTN T0SZ;
|
||||
|
||||
// Ensure the Length is aligned on 4KB boundary
|
||||
if ((RegionLength == 0) || ((RegionLength & (SIZE_4KB - 1)) != 0)) {
|
||||
ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER);
|
||||
if (((RegionStart | RegionLength) & EFI_PAGE_MASK) != 0) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
do {
|
||||
// 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;
|
||||
}
|
||||
T0SZ = ArmGetTCR () & TCR_T0SZ_MASK;
|
||||
|
||||
if (TableLevel != 3) {
|
||||
Type = TT_TYPE_BLOCK_ENTRY;
|
||||
} else {
|
||||
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;
|
||||
return UpdateRegionMappingRecursive (RegionStart, RegionStart + RegionLength,
|
||||
AttributeSetMask, AttributeClearMask, ArmGetTTBR0BaseAddress (),
|
||||
GetRootTableLevel (T0SZ));
|
||||
}
|
||||
|
||||
STATIC
|
||||
@ -398,7 +313,6 @@ FillTranslationTable (
|
||||
)
|
||||
{
|
||||
return UpdateRegionMapping (
|
||||
RootTable,
|
||||
MemoryRegion->VirtualBase,
|
||||
MemoryRegion->Length,
|
||||
ArmMemoryAttributeToPageAttribute (MemoryRegion->Attributes) | TT_AF,
|
||||
@ -455,8 +369,6 @@ ArmSetMemoryAttributes (
|
||||
IN UINT64 Attributes
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
UINT64 *TranslationTable;
|
||||
UINT64 PageAttributes;
|
||||
UINT64 PageAttributeMask;
|
||||
|
||||
@ -473,19 +385,8 @@ ArmSetMemoryAttributes (
|
||||
TT_PXN_MASK | TT_XN_MASK);
|
||||
}
|
||||
|
||||
TranslationTable = ArmGetTTBR0BaseAddress ();
|
||||
|
||||
Status = UpdateRegionMapping (
|
||||
TranslationTable,
|
||||
BaseAddress,
|
||||
Length,
|
||||
PageAttributes,
|
||||
return UpdateRegionMapping (BaseAddress, Length, PageAttributes,
|
||||
PageAttributeMask);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
STATIC
|
||||
@ -497,17 +398,7 @@ SetMemoryRegionAttribute (
|
||||
IN UINT64 BlockEntryMask
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
UINT64 *RootTable;
|
||||
|
||||
RootTable = ArmGetTTBR0BaseAddress ();
|
||||
|
||||
Status = UpdateRegionMapping (RootTable, BaseAddress, Length, Attributes, BlockEntryMask);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
return UpdateRegionMapping (BaseAddress, Length, Attributes, BlockEntryMask);
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
@ -584,7 +475,7 @@ ArmConfigureMmu (
|
||||
)
|
||||
{
|
||||
VOID* TranslationTable;
|
||||
UINT32 TranslationTableAttribute;
|
||||
UINTN MaxAddressBits;
|
||||
UINT64 MaxAddress;
|
||||
UINTN T0SZ;
|
||||
UINTN RootTableEntryCount;
|
||||
@ -603,11 +494,11 @@ ArmConfigureMmu (
|
||||
// into account the architectural limitations that result from UEFI's
|
||||
// use of 4 KB pages.
|
||||
//
|
||||
MaxAddress = MIN (LShiftU64 (1ULL, ArmGetPhysicalAddressBits ()) - 1,
|
||||
MAX_ALLOC_ADDRESS);
|
||||
MaxAddressBits = MIN (ArmGetPhysicalAddressBits (), MAX_VA_BITS);
|
||||
MaxAddress = LShiftU64 (1ULL, MaxAddressBits) - 1;
|
||||
|
||||
// Lookup the Table Level to get the information
|
||||
LookupAddresstoRootTable (MaxAddress, &T0SZ, &RootTableEntryCount);
|
||||
T0SZ = 64 - MaxAddressBits;
|
||||
RootTableEntryCount = GetRootTableEntryCount (T0SZ);
|
||||
|
||||
//
|
||||
// Set TCR that allows us to retrieve T0SZ in the subsequent functions
|
||||
@ -632,7 +523,9 @@ ArmConfigureMmu (
|
||||
} else if (MaxAddress < SIZE_256TB) {
|
||||
TCR |= TCR_PS_256TB;
|
||||
} 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
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
@ -654,7 +547,9 @@ ArmConfigureMmu (
|
||||
} else if (MaxAddress < SIZE_256TB) {
|
||||
TCR |= TCR_IPS_256TB;
|
||||
} 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
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
@ -684,9 +579,12 @@ ArmConfigureMmu (
|
||||
if (TranslationTable == NULL) {
|
||||
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
|
||||
// after the translation tables are populated.
|
||||
//
|
||||
// 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 after the translation tables are
|
||||
// populated.
|
||||
//
|
||||
ArmSetTTBR0 (TranslationTable);
|
||||
|
||||
if (TranslationTableBase != NULL) {
|
||||
@ -697,43 +595,34 @@ ArmConfigureMmu (
|
||||
*TranslationTableSize = 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) {
|
||||
|
||||
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);
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto FREE_TRANSLATION_TABLE;
|
||||
goto FreeTranslationTable;
|
||||
}
|
||||
MemoryTable++;
|
||||
}
|
||||
|
||||
ASSERT (TranslationTableAttribute == ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK ||
|
||||
TranslationTableAttribute == ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_WRITE_BACK);
|
||||
|
||||
ArmSetMAIR (MAIR_ATTR(TT_ATTR_INDX_DEVICE_MEMORY, MAIR_ATTR_DEVICE_MEMORY) | // mapped to EFI_MEMORY_UC
|
||||
MAIR_ATTR(TT_ATTR_INDX_MEMORY_NON_CACHEABLE, MAIR_ATTR_NORMAL_MEMORY_NON_CACHEABLE) | // mapped to EFI_MEMORY_WC
|
||||
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
|
||||
//
|
||||
// EFI_MEMORY_UC ==> MAIR_ATTR_DEVICE_MEMORY
|
||||
// EFI_MEMORY_WC ==> MAIR_ATTR_NORMAL_MEMORY_NON_CACHEABLE
|
||||
// EFI_MEMORY_WT ==> MAIR_ATTR_NORMAL_MEMORY_WRITE_THROUGH
|
||||
// EFI_MEMORY_WB ==> MAIR_ATTR_NORMAL_MEMORY_WRITE_BACK
|
||||
//
|
||||
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 ();
|
||||
ArmEnableStackAlignmentCheck ();
|
||||
@ -743,7 +632,7 @@ ArmConfigureMmu (
|
||||
ArmEnableMmu ();
|
||||
return EFI_SUCCESS;
|
||||
|
||||
FREE_TRANSLATION_TABLE:
|
||||
FreeTranslationTable:
|
||||
FreePages (TranslationTable, 1);
|
||||
return Status;
|
||||
}
|
||||
@ -760,7 +649,7 @@ ArmMmuBaseLibConstructor (
|
||||
// The ArmReplaceLiveTranslationEntry () helper function may be invoked
|
||||
// with the MMU off so we have to ensure that it gets cleaned to the PoC
|
||||
//
|
||||
WriteBackDataCacheRange (ArmReplaceLiveTranslationEntry,
|
||||
WriteBackDataCacheRange ((VOID *)(UINTN)ArmReplaceLiveTranslationEntry,
|
||||
ArmReplaceLiveTranslationEntrySize);
|
||||
|
||||
return RETURN_SUCCESS;
|
||||
|
@ -1,10 +1,10 @@
|
||||
#/* @file
|
||||
#
|
||||
# Copyright (c) 2016, Linaro Limited. All rights reserved.
|
||||
#
|
||||
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
#
|
||||
#*/
|
||||
/** @file
|
||||
|
||||
Copyright (c) 2016, Linaro Limited. All rights reserved.
|
||||
Copyright (c) 2021, Arm Limited. All rights reserved.<BR>
|
||||
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
*/
|
||||
|
||||
#include <Base.h>
|
||||
|
||||
@ -47,7 +47,7 @@ ArmMmuPeiLibConstructor (
|
||||
// The ArmReplaceLiveTranslationEntry () helper function may be invoked
|
||||
// with the MMU off so we have to ensure that it gets cleaned to the PoC
|
||||
//
|
||||
WriteBackDataCacheRange (ArmReplaceLiveTranslationEntry,
|
||||
WriteBackDataCacheRange ((VOID *)(UINTN)ArmReplaceLiveTranslationEntry,
|
||||
ArmReplaceLiveTranslationEntrySize);
|
||||
}
|
||||
|
||||
|
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_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
|
||||
EFIAPI
|
||||
ArmReadIdMmfr0 (
|
||||
@ -52,24 +43,6 @@ ArmHasMpExtensions (
|
||||
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
|
||||
BOOLEAN
|
||||
PreferNonshareableMemory (
|
||||
@ -165,14 +138,22 @@ PopulateLevel2PageTable (
|
||||
// Case where a virtual memory map descriptor overlapped a section entry
|
||||
|
||||
// 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)TranslationTable + TRANSLATION_TABLE_PAGE_ALIGNMENT_MASK) & ~TRANSLATION_TABLE_PAGE_ALIGNMENT_MASK;
|
||||
TranslationTable = (UINTN)AllocateAlignedPages (
|
||||
EFI_SIZE_TO_PAGES (TRANSLATION_TABLE_PAGE_SIZE),
|
||||
TRANSLATION_TABLE_PAGE_ALIGNMENT);
|
||||
|
||||
// Translate the Section Descriptor into Page Descriptor
|
||||
SectionDescriptor = TT_DESCRIPTOR_PAGE_TYPE_PAGE | ConvertSectionAttributesToPageAttributes (*SectionEntry, FALSE);
|
||||
|
||||
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
|
||||
PageEntry = (UINT32*)TranslationTable;
|
||||
for (Index = 0; Index < TRANSLATION_TABLE_PAGE_COUNT; Index++) {
|
||||
@ -189,9 +170,15 @@ PopulateLevel2PageTable (
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
TranslationTable = (UINTN)AllocatePages(EFI_SIZE_TO_PAGES(TRANSLATION_TABLE_PAGE_SIZE + TRANSLATION_TABLE_PAGE_ALIGNMENT));
|
||||
TranslationTable = ((UINTN)TranslationTable + TRANSLATION_TABLE_PAGE_ALIGNMENT_MASK) & ~TRANSLATION_TABLE_PAGE_ALIGNMENT_MASK;
|
||||
|
||||
TranslationTable = (UINTN)AllocateAlignedPages (
|
||||
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);
|
||||
|
||||
*SectionEntry = (TranslationTable & TT_DESCRIPTOR_SECTION_PAGETABLE_ADDRESS_MASK) |
|
||||
@ -210,6 +197,13 @@ PopulateLevel2PageTable (
|
||||
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
|
||||
@ -231,7 +225,7 @@ FillTranslationTable (
|
||||
return;
|
||||
}
|
||||
|
||||
PhysicalBase = MemoryRegion->PhysicalBase;
|
||||
PhysicalBase = (UINT32)MemoryRegion->PhysicalBase;
|
||||
RemainLength = MIN(MemoryRegion->Length, SIZE_4GB - PhysicalBase);
|
||||
|
||||
switch (MemoryRegion->Attributes) {
|
||||
@ -284,19 +278,36 @@ FillTranslationTable (
|
||||
RemainLength >= TT_DESCRIPTOR_SECTION_SIZE) {
|
||||
// Case: Physical address aligned on the Section Size (1MB) && the length
|
||||
// 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;
|
||||
RemainLength -= TT_DESCRIPTOR_SECTION_SIZE;
|
||||
} else {
|
||||
PageMapLength = MIN (RemainLength, TT_DESCRIPTOR_SECTION_SIZE -
|
||||
PageMapLength = MIN ((UINT32)RemainLength, TT_DESCRIPTOR_SECTION_SIZE -
|
||||
(PhysicalBase % TT_DESCRIPTOR_SECTION_SIZE));
|
||||
|
||||
// Case: Physical address aligned on the Section Size (1MB) && the length
|
||||
// does not fill a section
|
||||
// Case: Physical address NOT aligned on the Section Size (1MB)
|
||||
PopulateLevel2PageTable (SectionEntry++, PhysicalBase, PageMapLength,
|
||||
PopulateLevel2PageTable (SectionEntry, PhysicalBase, PageMapLength,
|
||||
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 (RemainLength < TT_DESCRIPTOR_SECTION_SIZE) {
|
||||
break;
|
||||
@ -317,15 +328,14 @@ ArmConfigureMmu (
|
||||
)
|
||||
{
|
||||
VOID *TranslationTable;
|
||||
ARM_MEMORY_REGION_ATTRIBUTES TranslationTableAttribute;
|
||||
UINT32 TTBRAttributes;
|
||||
|
||||
// Allocate pages for translation table.
|
||||
TranslationTable = AllocatePages (EFI_SIZE_TO_PAGES (TRANSLATION_TABLE_SECTION_SIZE + TRANSLATION_TABLE_SECTION_ALIGNMENT));
|
||||
TranslationTable = AllocateAlignedPages (
|
||||
EFI_SIZE_TO_PAGES (TRANSLATION_TABLE_SECTION_SIZE),
|
||||
TRANSLATION_TABLE_SECTION_ALIGNMENT);
|
||||
if (TranslationTable == NULL) {
|
||||
return RETURN_OUT_OF_RESOURCES;
|
||||
}
|
||||
TranslationTable = (VOID*)(((UINTN)TranslationTable + TRANSLATION_TABLE_SECTION_ALIGNMENT_MASK) & ~TRANSLATION_TABLE_SECTION_ALIGNMENT_MASK);
|
||||
|
||||
if (TranslationTableBase != NULL) {
|
||||
*TranslationTableBase = TranslationTable;
|
||||
@ -335,30 +345,20 @@ ArmConfigureMmu (
|
||||
*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);
|
||||
|
||||
// By default, mark the translation table as belonging to a uncached region
|
||||
TranslationTableAttribute = ARM_MEMORY_REGION_ATTRIBUTE_UNCACHED_UNBUFFERED;
|
||||
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);
|
||||
MemoryTable++;
|
||||
}
|
||||
|
||||
// Translate the Memory Attributes into Translation Table Register Attributes
|
||||
if ((TranslationTableAttribute == ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK) ||
|
||||
(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;
|
||||
}
|
||||
|
||||
TTBRAttributes = ArmHasMpExtensions () ? TTBR_MP_WRITE_BACK_ALLOC
|
||||
: TTBR_WRITE_BACK_ALLOC;
|
||||
if (TTBRAttributes & TTBR_SHAREABLE) {
|
||||
if (PreferNonshareableMemory ()) {
|
||||
TTBRAttributes ^= TTBR_SHAREABLE;
|
||||
@ -376,19 +376,7 @@ ArmConfigureMmu (
|
||||
}
|
||||
}
|
||||
|
||||
ArmCleanInvalidateDataCache ();
|
||||
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)));
|
||||
ArmSetTTBR0 ((VOID *)((UINTN)TranslationTable | TTBRAttributes));
|
||||
|
||||
//
|
||||
// The TTBCR register value is undefined at reset in the Non-Secure world.
|
||||
@ -423,419 +411,3 @@ ArmConfigureMmu (
|
||||
ArmEnableMmu();
|
||||
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;
|
||||
}
|
||||
|
437
ArmPkg/Library/ArmMmuLib/Arm/ArmMmuLibUpdate.c
Normal file
437
ArmPkg/Library/ArmMmuLib/Arm/ArmMmuLibUpdate.c
Normal file
@ -0,0 +1,437 @@
|
||||
/** @file
|
||||
* File managing the MMU for ARMv7 architecture
|
||||
*
|
||||
* Copyright (c) 2011-2021, Arm Limited. All rights reserved.<BR>
|
||||
*
|
||||
* 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) != 0) {
|
||||
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) != 0) {
|
||||
// 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) != 0) {
|
||||
// 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) != 0) {
|
||||
// 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) != 0) {
|
||||
// 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) != 0) {
|
||||
// catch unsupported memory type attributes
|
||||
ASSERT (FALSE);
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
if ((Attributes & EFI_MEMORY_RO) != 0) {
|
||||
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 = (UINT32)(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;
|
||||
UINT32 EntryMask;
|
||||
UINT32 EntryValue;
|
||||
UINT32 FirstLevelIdx;
|
||||
UINT32 NumSections;
|
||||
UINT32 i;
|
||||
UINT32 CurrentDescriptor;
|
||||
UINT32 Descriptor;
|
||||
VOID *Mva;
|
||||
volatile ARM_FIRST_LEVEL_DESCRIPTOR *FirstLevelTable;
|
||||
|
||||
Status = EFI_SUCCESS;
|
||||
|
||||
// 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) != 0) {
|
||||
// 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) != 0) {
|
||||
// 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) != 0) {
|
||||
// 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) != 0) {
|
||||
// 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) != 0) {
|
||||
// catch unsupported memory type attributes
|
||||
ASSERT (FALSE);
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
if ((Attributes & EFI_MEMORY_RO) != 0) {
|
||||
EntryValue |= TT_DESCRIPTOR_SECTION_AP_RO_RO;
|
||||
} else {
|
||||
EntryValue |= TT_DESCRIPTOR_SECTION_AP_RW_RW;
|
||||
}
|
||||
|
||||
if ((Attributes & EFI_MEMORY_XP) != 0) {
|
||||
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 = (UINT32)(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
|
||||
VERSION_STRING = 1.0
|
||||
LIBRARY_CLASS = ArmMmuLib
|
||||
|
||||
[Defines.AARCH64]
|
||||
CONSTRUCTOR = ArmMmuBaseLibConstructor
|
||||
|
||||
[Sources.AARCH64]
|
||||
@ -21,7 +23,9 @@
|
||||
AArch64/ArmMmuLibReplaceEntry.S
|
||||
|
||||
[Sources.ARM]
|
||||
Arm/ArmMmuLibConvert.c
|
||||
Arm/ArmMmuLibCore.c
|
||||
Arm/ArmMmuLibUpdate.c
|
||||
Arm/ArmMmuLibV7Support.S |GCC
|
||||
Arm/ArmMmuLibV7Support.asm |RVCT
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright (c) 2012 - 2017, ARM Limited. All rights reserved.
|
||||
// Copyright (c) 2012 - 2020, ARM Limited. All rights reserved.
|
||||
//
|
||||
// SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
//
|
||||
@ -25,14 +25,19 @@ ASM_PFX(ArmCallSvc):
|
||||
ldp x0, x1, [x0, #0]
|
||||
|
||||
svc #0
|
||||
// Prevent speculative execution beyond svc instruction
|
||||
dsb nsh
|
||||
isb
|
||||
|
||||
// Pop the ARM_SVC_ARGS structure address from the stack into x9
|
||||
ldr x9, [sp, #16]
|
||||
|
||||
// Store the SVC returned values into the ARM_SVC_ARGS structure.
|
||||
// A SVC call can return up to 4 values - we do not need to store back x4-x7.
|
||||
// A SVC call can return up to 8 values
|
||||
stp x0, x1, [x9, #0]
|
||||
stp x2, x3, [x9, #16]
|
||||
stp x4, x5, [x9, #32]
|
||||
stp x6, x7, [x9, #48]
|
||||
|
||||
mov x0, x9
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright (c) 2016 - 2017, ARM Limited. All rights reserved.
|
||||
// Copyright (c) 2016 - 2020, ARM Limited. All rights reserved.
|
||||
//
|
||||
// SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
//
|
||||
@ -18,6 +18,9 @@ ASM_PFX(ArmCallSvc):
|
||||
ldm r0, {r0-r7}
|
||||
|
||||
svc #0
|
||||
// Prevent speculative execution beyond svc instruction
|
||||
dsb nsh
|
||||
isb
|
||||
|
||||
// Load the ARM_SVC_ARGS structure address from the stack into r8
|
||||
ldr r8, [sp]
|
||||
|
@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright (c) 2016 - 2017, ARM Limited. All rights reserved.
|
||||
// Copyright (c) 2016 - 2020, ARM Limited. All rights reserved.
|
||||
//
|
||||
// SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
//
|
||||
@ -16,6 +16,9 @@
|
||||
ldm r0, {r0-r7}
|
||||
|
||||
svc #0
|
||||
// Prevent speculative execution beyond svc instruction
|
||||
dsb nsh
|
||||
isb
|
||||
|
||||
// Load the ARM_SVC_ARGS structure address from the stack into r8
|
||||
ldr r8, [sp]
|
||||
|
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/llsr.asm | MSFT
|
||||
|
||||
[Sources.AARCH64]
|
||||
AArch64/Atomics.S | GCC
|
||||
|
||||
[Packages]
|
||||
MdePkg/MdePkg.dec
|
||||
ArmPkg/ArmPkg.dec
|
||||
|
@ -1,6 +1,7 @@
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright (c) 2019, Pete Batard. All rights reserved.
|
||||
// Copyright (c) 2021, Arm Limited. All rights reserved.<BR>
|
||||
//
|
||||
// SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
//
|
||||
@ -17,10 +18,13 @@ int memcmp(void *, void *, size_t);
|
||||
#pragma function(memcmp)
|
||||
int memcmp(const void *s1, const void *s2, size_t n)
|
||||
{
|
||||
unsigned char const *t1 = s1;
|
||||
unsigned char const *t2 = s2;
|
||||
unsigned char const *t1;
|
||||
unsigned char const *t2;
|
||||
|
||||
while (n--) {
|
||||
t1 = s1;
|
||||
t2 = s2;
|
||||
|
||||
while (n-- != 0) {
|
||||
if (*t1 != *t2)
|
||||
return (int)*t1 - (int)*t2;
|
||||
t1++;
|
||||
|
@ -1,6 +1,7 @@
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright (c) 2016, Linaro Ltd. All rights reserved.<BR>
|
||||
// Copyright (c) 2021, Arm Limited. All rights reserved.<BR>
|
||||
//
|
||||
// SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
//
|
||||
@ -10,12 +11,16 @@ typedef __SIZE_TYPE__ size_t;
|
||||
|
||||
static void __memcpy(void *dest, const void *src, size_t n)
|
||||
{
|
||||
unsigned char *d = dest;
|
||||
unsigned char const *s = src;
|
||||
unsigned char *d;
|
||||
unsigned char const *s;
|
||||
|
||||
while (n--)
|
||||
d = dest;
|
||||
s = src;
|
||||
|
||||
while (n-- != 0) {
|
||||
*d++ = *s++;
|
||||
}
|
||||
}
|
||||
|
||||
void *memcpy(void *dest, const void *src, size_t n)
|
||||
{
|
||||
|
@ -1,6 +1,7 @@
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright (c) 2017, Pete Batard. All rights reserved.<BR>
|
||||
// Copyright (c) 2021, Arm Limited. All rights reserved.<BR>
|
||||
//
|
||||
// SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
//
|
||||
@ -17,11 +18,15 @@ void* memcpy(void *, const void *, size_t);
|
||||
#pragma function(memcpy)
|
||||
void* memcpy(void *dest, const void *src, size_t n)
|
||||
{
|
||||
unsigned char *d = dest;
|
||||
unsigned char const *s = src;
|
||||
unsigned char *d;
|
||||
unsigned char const *s;
|
||||
|
||||
while (n--)
|
||||
d = dest;
|
||||
s = src;
|
||||
|
||||
while (n-- != 0) {
|
||||
*d++ = *s++;
|
||||
}
|
||||
|
||||
return dest;
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright (c) 2019, Pete Batard. All rights reserved.
|
||||
// Copyright (c) 2021, Arm Limited. All rights reserved.<BR>
|
||||
//
|
||||
// SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
//
|
||||
@ -17,18 +18,23 @@ void* memmove(void *, const void *, size_t);
|
||||
#pragma function(memmove)
|
||||
void* memmove(void *dest, const void *src, size_t n)
|
||||
{
|
||||
unsigned char *d = dest;
|
||||
unsigned char const *s = src;
|
||||
unsigned char *d;
|
||||
unsigned char const *s;
|
||||
|
||||
d = dest;
|
||||
s = src;
|
||||
|
||||
if (d < s) {
|
||||
while (n--)
|
||||
while (n-- != 0) {
|
||||
*d++ = *s++;
|
||||
}
|
||||
} else {
|
||||
d += n;
|
||||
s += n;
|
||||
while (n--)
|
||||
while (n-- != 0) {
|
||||
*--d = *--s;
|
||||
}
|
||||
}
|
||||
|
||||
return dest;
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright (c) 2016, Linaro Ltd. All rights reserved.<BR>
|
||||
// Copyright (c) 2021, Arm Limited. All rights reserved.<BR>
|
||||
//
|
||||
// SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
//
|
||||
@ -11,10 +12,13 @@ typedef __SIZE_TYPE__ size_t;
|
||||
static __attribute__((__used__))
|
||||
void *__memset(void *s, int c, size_t n)
|
||||
{
|
||||
unsigned char *d = s;
|
||||
unsigned char *d;
|
||||
|
||||
while (n--)
|
||||
d = s;
|
||||
|
||||
while (n-- != 0) {
|
||||
*d++ = c;
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright (c) 2017, Pete Batard. All rights reserved.<BR>
|
||||
// Copyright (c) 2021, Arm Limited. All rights reserved.<BR>
|
||||
//
|
||||
// SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
//
|
||||
@ -17,10 +18,13 @@ void* memset(void *, int, size_t);
|
||||
#pragma function(memset)
|
||||
void *memset(void *s, int c, size_t n)
|
||||
{
|
||||
unsigned char *d = s;
|
||||
unsigned char *d;
|
||||
|
||||
while (n--)
|
||||
d = s;
|
||||
|
||||
while (n-- != 0) {
|
||||
*d++ = (unsigned char)c;
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
Default exception handler
|
||||
|
||||
Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>
|
||||
Copyright (c) 2012, ARM Ltd. All rights reserved.<BR>
|
||||
Copyright (c) 2012 - 2021, Arm Ltd. All rights reserved.<BR>
|
||||
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
@ -34,6 +34,20 @@ typedef struct {
|
||||
CHAR8 Char;
|
||||
} CPSR_CHAR;
|
||||
|
||||
STATIC CONST CPSR_CHAR mCpsrChar[] = {
|
||||
{ 31, 'n' },
|
||||
{ 30, 'z' },
|
||||
{ 29, 'c' },
|
||||
{ 28, 'v' },
|
||||
|
||||
{ 9, 'e' },
|
||||
{ 8, 'a' },
|
||||
{ 7, 'i' },
|
||||
{ 6, 'f' },
|
||||
{ 5, 't' },
|
||||
{ 0, '?' }
|
||||
};
|
||||
|
||||
CHAR8 *
|
||||
GetImageName (
|
||||
IN UINTN FaultAddress,
|
||||
@ -45,7 +59,7 @@ GetImageName (
|
||||
Convert the Current Program Status Register (CPSR) to a string. The string is
|
||||
a defacto standard in the ARM world.
|
||||
|
||||
It is possible to add extra bits by adding them to CpsrChar array.
|
||||
It is possible to add extra bits by adding them to mCpsrChar array.
|
||||
|
||||
@param Cpsr ARM CPSR register value
|
||||
@param ReturnStr CPSR_STRING_SIZE byte string that contains string
|
||||
@ -61,25 +75,12 @@ CpsrString (
|
||||
UINTN Index;
|
||||
CHAR8* Str;
|
||||
CHAR8* ModeStr;
|
||||
CPSR_CHAR CpsrChar[] = {
|
||||
{ 31, 'n' },
|
||||
{ 30, 'z' },
|
||||
{ 29, 'c' },
|
||||
{ 28, 'v' },
|
||||
|
||||
{ 9, 'e' },
|
||||
{ 8, 'a' },
|
||||
{ 7, 'i' },
|
||||
{ 6, 'f' },
|
||||
{ 5, 't' },
|
||||
{ 0, '?' }
|
||||
};
|
||||
|
||||
Str = ReturnStr;
|
||||
|
||||
for (Index = 0; CpsrChar[Index].BIT != 0; Index++, Str++) {
|
||||
*Str = CpsrChar[Index].Char;
|
||||
if ((Cpsr & (1 << CpsrChar[Index].BIT)) != 0) {
|
||||
for (Index = 0; mCpsrChar[Index].BIT != 0; Index++, Str++) {
|
||||
*Str = mCpsrChar[Index].Char;
|
||||
if ((Cpsr & (1 << mCpsrChar[Index].BIT)) != 0) {
|
||||
// Concert to upper case if bit is set
|
||||
*Str &= ~0x20;
|
||||
}
|
||||
@ -186,7 +187,9 @@ DefaultExceptionHandler (
|
||||
UINT32 DfsrStatus;
|
||||
UINT32 IfsrStatus;
|
||||
BOOLEAN DfsrWrite;
|
||||
UINT32 PcAdjust = 0;
|
||||
UINT32 PcAdjust;
|
||||
|
||||
PcAdjust = 0;
|
||||
|
||||
CharCount = AsciiSPrint (Buffer,sizeof (Buffer),"\n%a Exception PC at 0x%08x CPSR 0x%08x ",
|
||||
gExceptionTypeString[ExceptionType], SystemContext.SystemContextArm->PC, SystemContext.SystemContextArm->CPSR);
|
||||
|
@ -3,6 +3,7 @@
|
||||
secure monitor calls.
|
||||
|
||||
Copyright (c) 2018, Linaro Ltd. All rights reserved.<BR>
|
||||
Copyright (c) 2021, Arm Limited. All rights reserved.<BR>
|
||||
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
@ -227,7 +228,7 @@ OpteeOpenSession (
|
||||
|
||||
MessageArg->NumParams = 2;
|
||||
|
||||
if (OpteeCallWithArg ((UINTN)MessageArg)) {
|
||||
if (OpteeCallWithArg ((UINTN)MessageArg) != 0) {
|
||||
MessageArg->Return = OPTEE_ERROR_COMMUNICATION;
|
||||
MessageArg->ReturnOrigin = OPTEE_ORIGIN_COMMUNICATION;
|
||||
}
|
||||
@ -431,7 +432,7 @@ OpteeInvokeFunction (
|
||||
|
||||
MessageArg->NumParams = OPTEE_MAX_CALL_PARAMS;
|
||||
|
||||
if (OpteeCallWithArg ((UINTN)MessageArg)) {
|
||||
if (OpteeCallWithArg ((UINTN)MessageArg) != 0) {
|
||||
MessageArg->Return = OPTEE_ERROR_COMMUNICATION;
|
||||
MessageArg->ReturnOrigin = OPTEE_ORIGIN_COMMUNICATION;
|
||||
}
|
||||
@ -440,7 +441,7 @@ OpteeInvokeFunction (
|
||||
InvokeFunctionArg->Params,
|
||||
OPTEE_MAX_CALL_PARAMS,
|
||||
MessageArg->Params
|
||||
)) {
|
||||
) != 0) {
|
||||
MessageArg->Return = OPTEE_ERROR_COMMUNICATION;
|
||||
MessageArg->ReturnOrigin = OPTEE_ORIGIN_COMMUNICATION;
|
||||
}
|
||||
|
@ -23,10 +23,12 @@
|
||||
#include <Protocol/EsrtManagement.h>
|
||||
#include <Protocol/GraphicsOutput.h>
|
||||
#include <Protocol/LoadedImage.h>
|
||||
#include <Protocol/NonDiscoverableDevice.h>
|
||||
#include <Protocol/PciIo.h>
|
||||
#include <Protocol/PciRootBridgeIo.h>
|
||||
#include <Protocol/PlatformBootManager.h>
|
||||
#include <Guid/EventGroup.h>
|
||||
#include <Guid/NonDiscoverableDevice.h>
|
||||
#include <Guid/TtyTerm.h>
|
||||
#include <Guid/SerialPortLibVendor.h>
|
||||
|
||||
@ -254,6 +256,37 @@ IsPciDisplay (
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
This FILTER_FUNCTION checks if a handle corresponds to a non-discoverable
|
||||
USB host controller.
|
||||
**/
|
||||
STATIC
|
||||
BOOLEAN
|
||||
EFIAPI
|
||||
IsUsbHost (
|
||||
IN EFI_HANDLE Handle,
|
||||
IN CONST CHAR16 *ReportText
|
||||
)
|
||||
{
|
||||
NON_DISCOVERABLE_DEVICE *Device;
|
||||
EFI_STATUS Status;
|
||||
|
||||
Status = gBS->HandleProtocol (Handle,
|
||||
&gEdkiiNonDiscoverableDeviceProtocolGuid,
|
||||
(VOID **)&Device);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (CompareGuid (Device->Type, &gEdkiiNonDiscoverableUhciDeviceGuid) ||
|
||||
CompareGuid (Device->Type, &gEdkiiNonDiscoverableEhciDeviceGuid) ||
|
||||
CompareGuid (Device->Type, &gEdkiiNonDiscoverableXhciDeviceGuid)) {
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
This CALLBACK_FUNCTION attempts to connect a handle non-recursively, asking
|
||||
the matching driver to produce all first-level child handles.
|
||||
@ -324,7 +357,8 @@ VOID
|
||||
PlatformRegisterFvBootOption (
|
||||
CONST EFI_GUID *FileGuid,
|
||||
CHAR16 *Description,
|
||||
UINT32 Attributes
|
||||
UINT32 Attributes,
|
||||
EFI_INPUT_KEY *Key
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
@ -376,6 +410,9 @@ PlatformRegisterFvBootOption (
|
||||
if (OptionIndex == -1) {
|
||||
Status = EfiBootManagerAddLoadOptionVariable (&NewOption, MAX_UINTN);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
Status = EfiBootManagerAddKeyOptionVariable (NULL,
|
||||
(UINT16)NewOption.OptionNumber, 0, Key, NULL);
|
||||
ASSERT (Status == EFI_SUCCESS || Status == EFI_ALREADY_STARTED);
|
||||
}
|
||||
EfiBootManagerFreeLoadOption (&NewOption);
|
||||
EfiBootManagerFreeLoadOptions (BootOptions, BootOptionCount);
|
||||
@ -574,6 +611,15 @@ PlatformBootManagerBeforeConsole (
|
||||
//
|
||||
FilterAndProcess (&gEfiGraphicsOutputProtocolGuid, NULL, AddOutput);
|
||||
|
||||
//
|
||||
// The core BDS code connects short-form USB device paths by explicitly
|
||||
// looking for handles with PCI I/O installed, and checking the PCI class
|
||||
// code whether it matches the one for a USB host controller. This means
|
||||
// non-discoverable USB host controllers need to have the non-discoverable
|
||||
// PCI driver attached first.
|
||||
//
|
||||
FilterAndProcess (&gEdkiiNonDiscoverableDeviceProtocolGuid, IsUsbHost, Connect);
|
||||
|
||||
//
|
||||
// Add the hardcoded short-form USB keyboard device path to ConIn.
|
||||
//
|
||||
@ -583,7 +629,13 @@ PlatformBootManagerBeforeConsole (
|
||||
//
|
||||
// Add the hardcoded serial console device path to ConIn, ConOut, ErrOut.
|
||||
//
|
||||
ASSERT (FixedPcdGet8 (PcdDefaultTerminalType) == 4);
|
||||
STATIC_ASSERT (FixedPcdGet8 (PcdDefaultTerminalType) == 4,
|
||||
"PcdDefaultTerminalType must be TTYTERM");
|
||||
STATIC_ASSERT (FixedPcdGet8 (PcdUartDefaultParity) != 0,
|
||||
"PcdUartDefaultParity must be set to an actual value, not 'default'");
|
||||
STATIC_ASSERT (FixedPcdGet8 (PcdUartDefaultStopBits) != 0,
|
||||
"PcdUartDefaultStopBits must be set to an actual value, not 'default'");
|
||||
|
||||
CopyGuid (&mSerialConsole.TermType.Guid, &gEfiTtyTermGuid);
|
||||
|
||||
EfiBootManagerUpdateConsoleVariable (ConIn,
|
||||
@ -673,6 +725,7 @@ PlatformBootManagerAfterConsole (
|
||||
UINTN FirmwareVerLength;
|
||||
UINTN PosX;
|
||||
UINTN PosY;
|
||||
EFI_INPUT_KEY Key;
|
||||
|
||||
FirmwareVerLength = StrLen (PcdGetPtr (PcdFirmwareVersionString));
|
||||
|
||||
@ -700,11 +753,6 @@ PlatformBootManagerAfterConsole (
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Connect the rest of the devices.
|
||||
//
|
||||
EfiBootManagerConnectAll ();
|
||||
|
||||
//
|
||||
// On ARM, there is currently no reason to use the phased capsule
|
||||
// update approach where some capsules are dispatched before EndOfDxe
|
||||
@ -714,17 +762,12 @@ PlatformBootManagerAfterConsole (
|
||||
//
|
||||
HandleCapsules ();
|
||||
|
||||
//
|
||||
// Enumerate all possible boot options.
|
||||
//
|
||||
EfiBootManagerRefreshAllBootOption ();
|
||||
|
||||
//
|
||||
// Register UEFI Shell
|
||||
//
|
||||
PlatformRegisterFvBootOption (
|
||||
&gUefiShellFileGuid, L"UEFI Shell", LOAD_OPTION_ACTIVE
|
||||
);
|
||||
Key.ScanCode = SCAN_NULL;
|
||||
Key.UnicodeChar = L's';
|
||||
PlatformRegisterFvBootOption (&gUefiShellFileGuid, L"UEFI Shell", 0, &Key);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -775,5 +818,53 @@ PlatformBootManagerUnableToBoot (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_BOOT_MANAGER_LOAD_OPTION BootManagerMenu;
|
||||
EFI_BOOT_MANAGER_LOAD_OPTION *BootOptions;
|
||||
UINTN OldBootOptionCount;
|
||||
UINTN NewBootOptionCount;
|
||||
|
||||
//
|
||||
// Record the total number of boot configured boot options
|
||||
//
|
||||
BootOptions = EfiBootManagerGetLoadOptions (&OldBootOptionCount,
|
||||
LoadOptionTypeBoot);
|
||||
EfiBootManagerFreeLoadOptions (BootOptions, OldBootOptionCount);
|
||||
|
||||
//
|
||||
// Connect all devices, and regenerate all boot options
|
||||
//
|
||||
EfiBootManagerConnectAll ();
|
||||
EfiBootManagerRefreshAllBootOption ();
|
||||
|
||||
//
|
||||
// Record the updated number of boot configured boot options
|
||||
//
|
||||
BootOptions = EfiBootManagerGetLoadOptions (&NewBootOptionCount,
|
||||
LoadOptionTypeBoot);
|
||||
EfiBootManagerFreeLoadOptions (BootOptions, NewBootOptionCount);
|
||||
|
||||
//
|
||||
// If the number of configured boot options has changed, reboot
|
||||
// the system so the new boot options will be taken into account
|
||||
// while executing the ordinary BDS bootflow sequence.
|
||||
// *Unless* persistent varstore is being emulated, since we would
|
||||
// then end up in an endless reboot loop.
|
||||
//
|
||||
if (!PcdGetBool (PcdEmuVariableNvModeEnable)) {
|
||||
if (NewBootOptionCount != OldBootOptionCount) {
|
||||
DEBUG ((DEBUG_WARN, "%a: rebooting after refreshing all boot options\n",
|
||||
__FUNCTION__));
|
||||
gRT->ResetSystem (EfiResetCold, EFI_SUCCESS, 0, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
Status = EfiBootManagerGetBootManagerMenu (&BootManagerMenu);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
EfiBootManagerBoot (&BootManagerMenu);
|
||||
}
|
||||
}
|
||||
|
@ -55,6 +55,7 @@
|
||||
gEfiMdePkgTokenSpaceGuid.PcdUgaConsumeSupport
|
||||
|
||||
[FixedPcd]
|
||||
gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvModeEnable
|
||||
gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVersionString
|
||||
gEfiMdePkgTokenSpaceGuid.PcdUartDefaultBaudRate
|
||||
gEfiMdePkgTokenSpaceGuid.PcdUartDefaultDataBits
|
||||
@ -66,6 +67,9 @@
|
||||
gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut
|
||||
|
||||
[Guids]
|
||||
gEdkiiNonDiscoverableEhciDeviceGuid
|
||||
gEdkiiNonDiscoverableUhciDeviceGuid
|
||||
gEdkiiNonDiscoverableXhciDeviceGuid
|
||||
gEfiFileInfoGuid
|
||||
gEfiFileSystemInfoGuid
|
||||
gEfiFileSystemVolumeLabelInfoIdGuid
|
||||
@ -74,6 +78,7 @@
|
||||
gUefiShellFileGuid
|
||||
|
||||
[Protocols]
|
||||
gEdkiiNonDiscoverableDeviceProtocolGuid
|
||||
gEfiDevicePathProtocolGuid
|
||||
gEfiGraphicsOutputProtocolGuid
|
||||
gEfiLoadedImageProtocolGuid
|
||||
|
@ -2,6 +2,7 @@
|
||||
Serial I/O Port library functions with no library constructor/destructor
|
||||
|
||||
Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
|
||||
Copyright (c) 2021, Arm Limited. All rights reserved.<BR>
|
||||
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
@ -55,10 +56,13 @@ SerialPortWrite (
|
||||
)
|
||||
{
|
||||
UINT8 PrintBuffer[PRINT_BUFFER_SIZE];
|
||||
UINTN SourceIndex = 0;
|
||||
UINTN DestinationIndex = 0;
|
||||
UINTN SourceIndex;
|
||||
UINTN DestinationIndex;
|
||||
UINT8 CurrentCharacter;
|
||||
|
||||
SourceIndex = 0;
|
||||
DestinationIndex = 0;
|
||||
|
||||
while (SourceIndex < NumberOfBytes)
|
||||
{
|
||||
CurrentCharacter = Buffer[SourceIndex++];
|
||||
|
@ -1,7 +1,7 @@
|
||||
/** @file
|
||||
|
||||
Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
|
||||
Copyright (c) 2013 - 2014, ARM Ltd. All rights reserved.<BR>
|
||||
Copyright (c) 2013 - 2021, Arm Limited. All rights reserved.<BR>
|
||||
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
@ -135,9 +135,7 @@ SemihostFileClose (
|
||||
IN UINTN FileHandle
|
||||
)
|
||||
{
|
||||
INT32 Result = Semihost_SYS_CLOSE(&FileHandle);
|
||||
|
||||
if (Result == -1) {
|
||||
if (Semihost_SYS_CLOSE (&FileHandle) == -1) {
|
||||
return RETURN_INVALID_PARAMETER;
|
||||
} else {
|
||||
return RETURN_SUCCESS;
|
||||
|
@ -1,21 +1,149 @@
|
||||
/** @file
|
||||
* File managing the MMU for ARMv8 architecture in S-EL0
|
||||
*
|
||||
* Copyright (c) 2017 - 2018, ARM Limited. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
*
|
||||
File managing the MMU for ARMv8 architecture in S-EL0
|
||||
|
||||
Copyright (c) 2017 - 2021, Arm Limited. All rights reserved.<BR>
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
@par Reference(s):
|
||||
- [1] SPM based on the MM interface.
|
||||
(https://trustedfirmware-a.readthedocs.io/en/latest/components/
|
||||
secure-partition-manager-mm.html)
|
||||
- [2] Arm Firmware Framework for Armv8-A, DEN0077A, version 1.0
|
||||
(https://developer.arm.com/documentation/den0077/a)
|
||||
**/
|
||||
|
||||
#include <Uefi.h>
|
||||
#include <IndustryStandard/ArmMmSvc.h>
|
||||
#include <IndustryStandard/ArmFfaSvc.h>
|
||||
|
||||
#include <Library/ArmLib.h>
|
||||
#include <Library/ArmMmuLib.h>
|
||||
#include <Library/ArmSvcLib.h>
|
||||
#include <Library/BaseLib.h>
|
||||
#include <Library/BaseMemoryLib.h>
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Library/PcdLib.h>
|
||||
|
||||
/** Send memory permission request to target.
|
||||
|
||||
@param [in, out] SvcArgs Pointer to SVC arguments to send. On
|
||||
return it contains the response parameters.
|
||||
@param [out] RetVal Pointer to return the response value.
|
||||
|
||||
@retval EFI_SUCCESS Request successfull.
|
||||
@retval EFI_INVALID_PARAMETER A parameter is invalid.
|
||||
@retval EFI_NOT_READY Callee is busy or not in a state to handle
|
||||
this request.
|
||||
@retval EFI_UNSUPPORTED This function is not implemented by the
|
||||
callee.
|
||||
@retval EFI_ABORTED Message target ran into an unexpected error
|
||||
and has aborted.
|
||||
@retval EFI_ACCESS_DENIED Access denied.
|
||||
@retval EFI_OUT_OF_RESOURCES Out of memory to perform operation.
|
||||
**/
|
||||
STATIC
|
||||
EFI_STATUS
|
||||
SendMemoryPermissionRequest (
|
||||
IN OUT ARM_SVC_ARGS *SvcArgs,
|
||||
OUT INT32 *RetVal
|
||||
)
|
||||
{
|
||||
if ((SvcArgs == NULL) || (RetVal == NULL)) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
ArmCallSvc (SvcArgs);
|
||||
if (FeaturePcdGet (PcdFfaEnable)) {
|
||||
// Get/Set memory attributes is an atomic call, with
|
||||
// StandaloneMm at S-EL0 being the caller and the SPM
|
||||
// core being the callee. Thus there won't be a
|
||||
// FFA_INTERRUPT or FFA_SUCCESS response to the Direct
|
||||
// Request sent above. This will have to be considered
|
||||
// for other Direct Request calls which are not atomic
|
||||
// We therefore check only for Direct Response by the
|
||||
// callee.
|
||||
if (SvcArgs->Arg0 == ARM_SVC_ID_FFA_MSG_SEND_DIRECT_RESP_AARCH64) {
|
||||
// A Direct Response means FF-A success
|
||||
// Now check the payload for errors
|
||||
// The callee sends back the return value
|
||||
// in Arg3
|
||||
*RetVal = SvcArgs->Arg3;
|
||||
} else {
|
||||
// If Arg0 is not a Direct Response, that means we
|
||||
// have an FF-A error. We need to check Arg2 for the
|
||||
// FF-A error code.
|
||||
// See [2], Table 10.8: FFA_ERROR encoding.
|
||||
*RetVal = SvcArgs->Arg2;
|
||||
switch (*RetVal) {
|
||||
case ARM_FFA_SPM_RET_INVALID_PARAMETERS:
|
||||
return EFI_INVALID_PARAMETER;
|
||||
|
||||
case ARM_FFA_SPM_RET_DENIED:
|
||||
return EFI_ACCESS_DENIED;
|
||||
|
||||
case ARM_FFA_SPM_RET_NOT_SUPPORTED:
|
||||
return EFI_UNSUPPORTED;
|
||||
|
||||
case ARM_FFA_SPM_RET_BUSY:
|
||||
return EFI_NOT_READY;
|
||||
|
||||
case ARM_FFA_SPM_RET_ABORTED:
|
||||
return EFI_ABORTED;
|
||||
|
||||
default:
|
||||
// Undefined error code received.
|
||||
ASSERT (0);
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
*RetVal = SvcArgs->Arg0;
|
||||
}
|
||||
|
||||
// Check error response from Callee.
|
||||
if (*RetVal & BIT31) {
|
||||
// Bit 31 set means there is an error retured
|
||||
// See [1], Section 13.5.5.1 MM_SP_MEMORY_ATTRIBUTES_GET_AARCH64 and
|
||||
// Section 13.5.5.2 MM_SP_MEMORY_ATTRIBUTES_SET_AARCH64.
|
||||
switch (*RetVal) {
|
||||
case ARM_SVC_SPM_RET_NOT_SUPPORTED:
|
||||
return EFI_UNSUPPORTED;
|
||||
|
||||
case ARM_SVC_SPM_RET_INVALID_PARAMS:
|
||||
return EFI_INVALID_PARAMETER;
|
||||
|
||||
case ARM_SVC_SPM_RET_DENIED:
|
||||
return EFI_ACCESS_DENIED;
|
||||
|
||||
case ARM_SVC_SPM_RET_NO_MEMORY:
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
|
||||
default:
|
||||
// Undefined error code received.
|
||||
ASSERT (0);
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/** Request the permission attributes of a memory region from S-EL0.
|
||||
|
||||
@param [in] BaseAddress Base address for the memory region.
|
||||
@param [out] MemoryAttributes Pointer to return the memory attributes.
|
||||
|
||||
@retval EFI_SUCCESS Request successfull.
|
||||
@retval EFI_INVALID_PARAMETER A parameter is invalid.
|
||||
@retval EFI_NOT_READY Callee is busy or not in a state to handle
|
||||
this request.
|
||||
@retval EFI_UNSUPPORTED This function is not implemented by the
|
||||
callee.
|
||||
@retval EFI_ABORTED Message target ran into an unexpected error
|
||||
and has aborted.
|
||||
@retval EFI_ACCESS_DENIED Access denied.
|
||||
@retval EFI_OUT_OF_RESOURCES Out of memory to perform operation.
|
||||
**/
|
||||
STATIC
|
||||
EFI_STATUS
|
||||
GetMemoryPermissions (
|
||||
@ -23,70 +151,89 @@ GetMemoryPermissions (
|
||||
OUT UINT32 *MemoryAttributes
|
||||
)
|
||||
{
|
||||
ARM_SVC_ARGS GetMemoryPermissionsSvcArgs = {0};
|
||||
EFI_STATUS Status;
|
||||
INT32 Ret;
|
||||
ARM_SVC_ARGS SvcArgs;
|
||||
|
||||
GetMemoryPermissionsSvcArgs.Arg0 = ARM_SVC_ID_SP_GET_MEM_ATTRIBUTES_AARCH64;
|
||||
GetMemoryPermissionsSvcArgs.Arg1 = BaseAddress;
|
||||
GetMemoryPermissionsSvcArgs.Arg2 = 0;
|
||||
GetMemoryPermissionsSvcArgs.Arg3 = 0;
|
||||
|
||||
ArmCallSvc (&GetMemoryPermissionsSvcArgs);
|
||||
if (GetMemoryPermissionsSvcArgs.Arg0 == ARM_SVC_SPM_RET_INVALID_PARAMS) {
|
||||
*MemoryAttributes = 0;
|
||||
if (MemoryAttributes == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
*MemoryAttributes = GetMemoryPermissionsSvcArgs.Arg0;
|
||||
return EFI_SUCCESS;
|
||||
// Prepare the message parameters.
|
||||
// See [1], Section 13.5.5.1 MM_SP_MEMORY_ATTRIBUTES_GET_AARCH64.
|
||||
ZeroMem (&SvcArgs, sizeof (ARM_SVC_ARGS));
|
||||
if (FeaturePcdGet (PcdFfaEnable)) {
|
||||
// See [2], Section 10.2 FFA_MSG_SEND_DIRECT_REQ.
|
||||
SvcArgs.Arg0 = ARM_SVC_ID_FFA_MSG_SEND_DIRECT_REQ_AARCH64;
|
||||
SvcArgs.Arg1 = ARM_FFA_DESTINATION_ENDPOINT_ID;
|
||||
SvcArgs.Arg2 = 0;
|
||||
SvcArgs.Arg3 = ARM_SVC_ID_SP_GET_MEM_ATTRIBUTES_AARCH64;
|
||||
SvcArgs.Arg4 = BaseAddress;
|
||||
} else {
|
||||
SvcArgs.Arg0 = ARM_SVC_ID_SP_GET_MEM_ATTRIBUTES_AARCH64;
|
||||
SvcArgs.Arg1 = BaseAddress;
|
||||
SvcArgs.Arg2 = 0;
|
||||
SvcArgs.Arg3 = 0;
|
||||
}
|
||||
|
||||
Status = SendMemoryPermissionRequest (&SvcArgs, &Ret);
|
||||
if (EFI_ERROR (Status)) {
|
||||
*MemoryAttributes = 0;
|
||||
return Status;
|
||||
}
|
||||
|
||||
*MemoryAttributes = Ret;
|
||||
return Status;
|
||||
}
|
||||
|
||||
/** Set the permission attributes of a memory region from S-EL0.
|
||||
|
||||
@param [in] BaseAddress Base address for the memory region.
|
||||
@param [in] Length Length of the memory region.
|
||||
@param [in] Permissions Memory access controls attributes.
|
||||
|
||||
@retval EFI_SUCCESS Request successfull.
|
||||
@retval EFI_INVALID_PARAMETER A parameter is invalid.
|
||||
@retval EFI_NOT_READY Callee is busy or not in a state to handle
|
||||
this request.
|
||||
@retval EFI_UNSUPPORTED This function is not implemented by the
|
||||
callee.
|
||||
@retval EFI_ABORTED Message target ran into an unexpected error
|
||||
and has aborted.
|
||||
@retval EFI_ACCESS_DENIED Access denied.
|
||||
@retval EFI_OUT_OF_RESOURCES Out of memory to perform operation.
|
||||
**/
|
||||
STATIC
|
||||
EFI_STATUS
|
||||
RequestMemoryPermissionChange (
|
||||
IN EFI_PHYSICAL_ADDRESS BaseAddress,
|
||||
IN UINT64 Length,
|
||||
IN UINTN Permissions
|
||||
IN UINT32 Permissions
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
ARM_SVC_ARGS ChangeMemoryPermissionsSvcArgs = {0};
|
||||
INT32 Ret;
|
||||
ARM_SVC_ARGS SvcArgs;
|
||||
|
||||
ChangeMemoryPermissionsSvcArgs.Arg0 = ARM_SVC_ID_SP_SET_MEM_ATTRIBUTES_AARCH64;
|
||||
ChangeMemoryPermissionsSvcArgs.Arg1 = BaseAddress;
|
||||
ChangeMemoryPermissionsSvcArgs.Arg2 = EFI_SIZE_TO_PAGES(Length);
|
||||
ChangeMemoryPermissionsSvcArgs.Arg3 = Permissions;
|
||||
|
||||
ArmCallSvc (&ChangeMemoryPermissionsSvcArgs);
|
||||
|
||||
Status = ChangeMemoryPermissionsSvcArgs.Arg0;
|
||||
|
||||
switch (Status) {
|
||||
case ARM_SVC_SPM_RET_SUCCESS:
|
||||
Status = EFI_SUCCESS;
|
||||
break;
|
||||
|
||||
case ARM_SVC_SPM_RET_NOT_SUPPORTED:
|
||||
Status = EFI_UNSUPPORTED;
|
||||
break;
|
||||
|
||||
case ARM_SVC_SPM_RET_INVALID_PARAMS:
|
||||
Status = EFI_INVALID_PARAMETER;
|
||||
break;
|
||||
|
||||
case ARM_SVC_SPM_RET_DENIED:
|
||||
Status = EFI_ACCESS_DENIED;
|
||||
break;
|
||||
|
||||
case ARM_SVC_SPM_RET_NO_MEMORY:
|
||||
Status = EFI_BAD_BUFFER_SIZE;
|
||||
break;
|
||||
|
||||
default:
|
||||
Status = EFI_ACCESS_DENIED;
|
||||
ASSERT (0);
|
||||
// Prepare the message parameters.
|
||||
// See [1], Section 13.5.5.2 MM_SP_MEMORY_ATTRIBUTES_SET_AARCH64.
|
||||
ZeroMem (&SvcArgs, sizeof (ARM_SVC_ARGS));
|
||||
if (FeaturePcdGet (PcdFfaEnable)) {
|
||||
// See [2], Section 10.2 FFA_MSG_SEND_DIRECT_REQ.
|
||||
SvcArgs.Arg0 = ARM_SVC_ID_FFA_MSG_SEND_DIRECT_REQ_AARCH64;
|
||||
SvcArgs.Arg1 = ARM_FFA_DESTINATION_ENDPOINT_ID;
|
||||
SvcArgs.Arg2 = 0;
|
||||
SvcArgs.Arg3 = ARM_SVC_ID_SP_SET_MEM_ATTRIBUTES_AARCH64;
|
||||
SvcArgs.Arg4 = BaseAddress;
|
||||
SvcArgs.Arg5 = EFI_SIZE_TO_PAGES (Length);
|
||||
SvcArgs.Arg6 = Permissions;
|
||||
} else {
|
||||
SvcArgs.Arg0 = ARM_SVC_ID_SP_SET_MEM_ATTRIBUTES_AARCH64;
|
||||
SvcArgs.Arg1 = BaseAddress;
|
||||
SvcArgs.Arg2 = EFI_SIZE_TO_PAGES (Length);
|
||||
SvcArgs.Arg3 = Permissions;
|
||||
}
|
||||
|
||||
return Status;
|
||||
return SendMemoryPermissionRequest (&SvcArgs, &Ret);
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
@ -100,7 +247,7 @@ ArmSetMemoryRegionNoExec (
|
||||
UINT32 CodePermission;
|
||||
|
||||
Status = GetMemoryPermissions (BaseAddress, &MemoryAttributes);
|
||||
if (Status != EFI_INVALID_PARAMETER) {
|
||||
if (!EFI_ERROR (Status)) {
|
||||
CodePermission = SET_MEM_ATTR_CODE_PERM_XN << SET_MEM_ATTR_CODE_PERM_SHIFT;
|
||||
return RequestMemoryPermissionChange (
|
||||
BaseAddress,
|
||||
@ -108,7 +255,7 @@ ArmSetMemoryRegionNoExec (
|
||||
MemoryAttributes | CodePermission
|
||||
);
|
||||
}
|
||||
return EFI_INVALID_PARAMETER;
|
||||
return Status;
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
@ -122,7 +269,7 @@ ArmClearMemoryRegionNoExec (
|
||||
UINT32 CodePermission;
|
||||
|
||||
Status = GetMemoryPermissions (BaseAddress, &MemoryAttributes);
|
||||
if (Status != EFI_INVALID_PARAMETER) {
|
||||
if (!EFI_ERROR (Status)) {
|
||||
CodePermission = SET_MEM_ATTR_CODE_PERM_XN << SET_MEM_ATTR_CODE_PERM_SHIFT;
|
||||
return RequestMemoryPermissionChange (
|
||||
BaseAddress,
|
||||
@ -130,7 +277,7 @@ ArmClearMemoryRegionNoExec (
|
||||
MemoryAttributes & ~CodePermission
|
||||
);
|
||||
}
|
||||
return EFI_INVALID_PARAMETER;
|
||||
return Status;
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
@ -144,7 +291,7 @@ ArmSetMemoryRegionReadOnly (
|
||||
UINT32 DataPermission;
|
||||
|
||||
Status = GetMemoryPermissions (BaseAddress, &MemoryAttributes);
|
||||
if (Status != EFI_INVALID_PARAMETER) {
|
||||
if (!EFI_ERROR (Status)) {
|
||||
DataPermission = SET_MEM_ATTR_DATA_PERM_RO << SET_MEM_ATTR_DATA_PERM_SHIFT;
|
||||
return RequestMemoryPermissionChange (
|
||||
BaseAddress,
|
||||
@ -152,7 +299,7 @@ ArmSetMemoryRegionReadOnly (
|
||||
MemoryAttributes | DataPermission
|
||||
);
|
||||
}
|
||||
return EFI_INVALID_PARAMETER;
|
||||
return Status;
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
@ -166,7 +313,7 @@ ArmClearMemoryRegionReadOnly (
|
||||
UINT32 PermissionRequest;
|
||||
|
||||
Status = GetMemoryPermissions (BaseAddress, &MemoryAttributes);
|
||||
if (Status != EFI_INVALID_PARAMETER) {
|
||||
if (!EFI_ERROR (Status)) {
|
||||
PermissionRequest = SET_MEM_ATTR_MAKE_PERM_REQUEST (SET_MEM_ATTR_DATA_PERM_RW,
|
||||
MemoryAttributes);
|
||||
return RequestMemoryPermissionChange (
|
||||
@ -175,5 +322,5 @@ ArmClearMemoryRegionReadOnly (
|
||||
PermissionRequest
|
||||
);
|
||||
}
|
||||
return EFI_INVALID_PARAMETER;
|
||||
return Status;
|
||||
}
|
||||
|
@ -23,6 +23,9 @@
|
||||
ArmPkg/ArmPkg.dec
|
||||
MdePkg/MdePkg.dec
|
||||
|
||||
[FeaturePcd.AARCH64]
|
||||
gArmTokenSpaceGuid.PcdFfaEnable
|
||||
|
||||
[LibraryClasses]
|
||||
ArmLib
|
||||
CacheMaintenanceLib
|
||||
|
141
ArmPkg/Universal/Smbios/OemMiscLibNull/OemMiscLib.c
Normal file
141
ArmPkg/Universal/Smbios/OemMiscLibNull/OemMiscLib.c
Normal file
@ -0,0 +1,141 @@
|
||||
/** @file
|
||||
* OemMiscLib.c
|
||||
*
|
||||
* Copyright (c) 2021, NUVIA Inc. All rights reserved.
|
||||
* Copyright (c) 2018, Hisilicon Limited. All rights reserved.
|
||||
* Copyright (c) 2018, Linaro Limited. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
*
|
||||
**/
|
||||
|
||||
#include <Uefi.h>
|
||||
#include <Library/BaseMemoryLib.h>
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Library/HiiLib.h>
|
||||
#include <Library/OemMiscLib.h>
|
||||
|
||||
|
||||
/** Gets the CPU frequency of the specified processor.
|
||||
|
||||
@param ProcessorIndex Index of the processor to get the frequency for.
|
||||
|
||||
@return CPU frequency in Hz
|
||||
**/
|
||||
UINTN
|
||||
EFIAPI
|
||||
OemGetCpuFreq (
|
||||
IN UINT8 ProcessorIndex
|
||||
)
|
||||
{
|
||||
ASSERT (FALSE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Gets information about the specified processor and stores it in
|
||||
the structures provided.
|
||||
|
||||
@param ProcessorIndex Index of the processor to get the information for.
|
||||
@param ProcessorStatus Processor status.
|
||||
@param ProcessorCharacteristics Processor characteritics.
|
||||
@param MiscProcessorData Miscellaneous processor information.
|
||||
|
||||
@return TRUE on success, FALSE on failure.
|
||||
**/
|
||||
BOOLEAN
|
||||
EFIAPI
|
||||
OemGetProcessorInformation (
|
||||
IN UINTN ProcessorIndex,
|
||||
IN OUT PROCESSOR_STATUS_DATA *ProcessorStatus,
|
||||
IN OUT PROCESSOR_CHARACTERISTIC_FLAGS *ProcessorCharacteristics,
|
||||
IN OUT OEM_MISC_PROCESSOR_DATA *MiscProcessorData
|
||||
)
|
||||
{
|
||||
ASSERT (FALSE);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/** Gets information about the cache at the specified cache level.
|
||||
|
||||
@param ProcessorIndex The processor to get information for.
|
||||
@param CacheLevel The cache level to get information for.
|
||||
@param DataCache Whether the cache is a data cache.
|
||||
@param UnifiedCache Whether the cache is a unified cache.
|
||||
@param SmbiosCacheTable The SMBIOS Type7 cache information structure.
|
||||
|
||||
@return TRUE on success, FALSE on failure.
|
||||
**/
|
||||
BOOLEAN
|
||||
EFIAPI
|
||||
OemGetCacheInformation (
|
||||
IN UINT8 ProcessorIndex,
|
||||
IN UINT8 CacheLevel,
|
||||
IN BOOLEAN DataCache,
|
||||
IN BOOLEAN UnifiedCache,
|
||||
IN OUT SMBIOS_TABLE_TYPE7 *SmbiosCacheTable
|
||||
)
|
||||
{
|
||||
ASSERT (FALSE);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/** Gets the maximum number of processors supported by the platform.
|
||||
|
||||
@return The maximum number of processors.
|
||||
**/
|
||||
UINT8
|
||||
EFIAPI
|
||||
OemGetMaxProcessors (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
ASSERT (FALSE);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** Gets the type of chassis for the system.
|
||||
|
||||
@retval The type of the chassis.
|
||||
**/
|
||||
MISC_CHASSIS_TYPE
|
||||
EFIAPI
|
||||
OemGetChassisType (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
ASSERT (FALSE);
|
||||
return MiscChassisTypeUnknown;
|
||||
}
|
||||
|
||||
/** Returns whether the specified processor is present or not.
|
||||
|
||||
@param ProcessIndex The processor index to check.
|
||||
|
||||
@return TRUE is the processor is present, FALSE otherwise.
|
||||
**/
|
||||
BOOLEAN
|
||||
EFIAPI
|
||||
OemIsProcessorPresent (
|
||||
IN UINTN ProcessorIndex
|
||||
)
|
||||
{
|
||||
ASSERT (FALSE);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/** Updates the HII string for the specified field.
|
||||
|
||||
@param HiiHandle The HII handle.
|
||||
@param TokenToUpdate The string to update.
|
||||
@param Field The field to get information about.
|
||||
**/
|
||||
VOID
|
||||
EFIAPI
|
||||
OemUpdateSmbiosInfo (
|
||||
IN EFI_HII_HANDLE HiiHandle,
|
||||
IN EFI_STRING_ID TokenToUpdate,
|
||||
IN OEM_MISC_SMBIOS_HII_STRING_FIELD Field
|
||||
)
|
||||
{
|
||||
ASSERT (FALSE);
|
||||
}
|
31
ArmPkg/Universal/Smbios/OemMiscLibNull/OemMiscLibNull.inf
Normal file
31
ArmPkg/Universal/Smbios/OemMiscLibNull/OemMiscLibNull.inf
Normal file
@ -0,0 +1,31 @@
|
||||
#/** @file
|
||||
# OemMiscLib.inf
|
||||
#
|
||||
# Copyright (c) 2021, NUVIA Inc. All rights reserved.
|
||||
# Copyright (c) 2018, Hisilicon Limited. All rights reserved.
|
||||
# Copyright (c) 2018, Linaro Limited. All rights reserved.
|
||||
#
|
||||
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
#
|
||||
#**/
|
||||
|
||||
[Defines]
|
||||
INF_VERSION = 1.29
|
||||
BASE_NAME = OemMiscLibNull
|
||||
FILE_GUID = e80b8e6b-fffb-4c39-b433-41de67c9d7b8
|
||||
MODULE_TYPE = BASE
|
||||
VERSION_STRING = 1.0
|
||||
LIBRARY_CLASS = OemMiscLib
|
||||
|
||||
[Sources.common]
|
||||
OemMiscLib.c
|
||||
|
||||
[Packages]
|
||||
ArmPkg/ArmPkg.dec
|
||||
EmbeddedPkg/EmbeddedPkg.dec
|
||||
MdeModulePkg/MdeModulePkg.dec
|
||||
MdePkg/MdePkg.dec
|
||||
|
||||
[LibraryClasses]
|
||||
BaseMemoryLib
|
||||
DebugLib
|
752
ArmPkg/Universal/Smbios/ProcessorSubClassDxe/ProcessorSubClass.c
Normal file
752
ArmPkg/Universal/Smbios/ProcessorSubClassDxe/ProcessorSubClass.c
Normal file
@ -0,0 +1,752 @@
|
||||
/** @file
|
||||
ProcessorSubClass.c
|
||||
|
||||
Copyright (c) 2021, NUVIA Inc. All rights reserved.<BR>
|
||||
Copyright (c) 2015, Hisilicon Limited. All rights reserved.
|
||||
Copyright (c) 2015, Linaro Limited. All rights reserved.
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
**/
|
||||
|
||||
#include <Uefi.h>
|
||||
#include <Protocol/Smbios.h>
|
||||
#include <IndustryStandard/ArmStdSmc.h>
|
||||
#include <IndustryStandard/SmBios.h>
|
||||
#include <Library/ArmLib.h>
|
||||
#include <Library/ArmSmcLib.h>
|
||||
#include <Library/ArmLib/ArmLibPrivate.h>
|
||||
#include <Library/BaseLib.h>
|
||||
#include <Library/BaseMemoryLib.h>
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Library/HiiLib.h>
|
||||
#include <Library/IoLib.h>
|
||||
#include <Library/MemoryAllocationLib.h>
|
||||
#include <Library/OemMiscLib.h>
|
||||
#include <Library/PcdLib.h>
|
||||
#include <Library/PrintLib.h>
|
||||
#include <Library/UefiBootServicesTableLib.h>
|
||||
#include <Library/UefiLib.h>
|
||||
|
||||
#include "SmbiosProcessor.h"
|
||||
|
||||
extern UINT8 ProcessorSubClassStrings[];
|
||||
|
||||
#define CACHE_SOCKETED_SHIFT 3
|
||||
#define CACHE_LOCATION_SHIFT 5
|
||||
#define CACHE_ENABLED_SHIFT 7
|
||||
#define CACHE_OPERATION_MODE_SHIFT 8
|
||||
|
||||
typedef enum {
|
||||
CacheModeWriteThrough = 0, ///< Cache is write-through
|
||||
CacheModeWriteBack, ///< Cache is write-back
|
||||
CacheModeVariesWithAddress, ///< Cache mode varies by address
|
||||
CacheModeUnknown, ///< Cache mode is unknown
|
||||
CacheModeMax
|
||||
} CACHE_OPERATION_MODE;
|
||||
|
||||
typedef enum {
|
||||
CacheLocationInternal = 0, ///< Cache is internal to the processor
|
||||
CacheLocationExternal, ///< Cache is external to the processor
|
||||
CacheLocationReserved, ///< Reserved
|
||||
CacheLocationUnknown, ///< Cache location is unknown
|
||||
CacheLocationMax
|
||||
} CACHE_LOCATION;
|
||||
|
||||
EFI_HII_HANDLE mHiiHandle;
|
||||
|
||||
EFI_SMBIOS_PROTOCOL *mSmbios;
|
||||
|
||||
SMBIOS_TABLE_TYPE4 mSmbiosProcessorTableTemplate = {
|
||||
{ // Hdr
|
||||
EFI_SMBIOS_TYPE_PROCESSOR_INFORMATION, // Type
|
||||
sizeof (SMBIOS_TABLE_TYPE4), // Length
|
||||
0 // Handle
|
||||
},
|
||||
1, // Socket
|
||||
CentralProcessor, // ProcessorType
|
||||
ProcessorFamilyIndicatorFamily2, // ProcessorFamily
|
||||
2, // ProcessorManufacture
|
||||
{ // ProcessorId
|
||||
{ // Signature
|
||||
0
|
||||
},
|
||||
{ // FeatureFlags
|
||||
0
|
||||
}
|
||||
},
|
||||
3, // ProcessorVersion
|
||||
{ // Voltage
|
||||
0
|
||||
},
|
||||
0, // ExternalClock
|
||||
0, // MaxSpeed
|
||||
0, // CurrentSpeed
|
||||
0, // Status
|
||||
ProcessorUpgradeUnknown, // ProcessorUpgrade
|
||||
0xFFFF, // L1CacheHandle
|
||||
0xFFFF, // L2CacheHandle
|
||||
0xFFFF, // L3CacheHandle
|
||||
4, // SerialNumber
|
||||
5, // AssetTag
|
||||
6, // PartNumber
|
||||
0, // CoreCount
|
||||
0, //EnabledCoreCount
|
||||
0, // ThreadCount
|
||||
0, // ProcessorCharacteristics
|
||||
ProcessorFamilyARM, // ProcessorFamily2
|
||||
0, // CoreCount2
|
||||
0, // EnabledCoreCount2
|
||||
0 // ThreadCount2
|
||||
};
|
||||
|
||||
/** Sets the HII variable `StringId` is `Pcd` isn't empty.
|
||||
|
||||
@param Pcd The FixedAtBuild PCD that contains the string to fetch.
|
||||
@param StringId The string identifier to set.
|
||||
**/
|
||||
#define SET_HII_STRING_IF_PCD_NOT_EMPTY(Pcd, StringId) \
|
||||
do { \
|
||||
CHAR16 *Str; \
|
||||
Str = (CHAR16*)PcdGetPtr (Pcd); \
|
||||
if (StrLen (Str) > 0) { \
|
||||
HiiSetString (mHiiHandle, StringId, Str, NULL); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/** Fetches the specified processor's frequency in Hz.
|
||||
|
||||
@param ProcessorNumber The processor number
|
||||
|
||||
@return The clock frequency in MHz
|
||||
|
||||
**/
|
||||
UINT16
|
||||
GetCpuFrequency (
|
||||
IN UINT8 ProcessorNumber
|
||||
)
|
||||
{
|
||||
return (UINT16)(OemGetCpuFreq (ProcessorNumber) / 1000 / 1000);
|
||||
}
|
||||
|
||||
/** Gets a description of the specified cache.
|
||||
|
||||
@param[in] CacheLevel Zero-based cache level (e.g. L1 cache is 0).
|
||||
@param[in] DataCache Cache is a data cache.
|
||||
@param[in] UnifiedCache Cache is a unified cache.
|
||||
@param[out] CacheSocketStr The description of the specified cache
|
||||
|
||||
@return The number of Unicode characters in CacheSocketStr not including the
|
||||
terminating NUL.
|
||||
**/
|
||||
UINTN
|
||||
GetCacheSocketStr (
|
||||
IN UINT8 CacheLevel,
|
||||
IN BOOLEAN DataCache,
|
||||
IN BOOLEAN UnifiedCache,
|
||||
OUT CHAR16 *CacheSocketStr
|
||||
)
|
||||
{
|
||||
UINTN CacheSocketStrLen;
|
||||
|
||||
if (CacheLevel == CpuCacheL1 && !DataCache && !UnifiedCache) {
|
||||
CacheSocketStrLen = UnicodeSPrint (
|
||||
CacheSocketStr,
|
||||
SMBIOS_STRING_MAX_LENGTH - 1,
|
||||
L"L%x Instruction Cache",
|
||||
CacheLevel);
|
||||
} else if (CacheLevel == CpuCacheL1 && DataCache) {
|
||||
CacheSocketStrLen = UnicodeSPrint (CacheSocketStr,
|
||||
SMBIOS_STRING_MAX_LENGTH - 1,
|
||||
L"L%x Data Cache",
|
||||
CacheLevel);
|
||||
} else {
|
||||
CacheSocketStrLen = UnicodeSPrint (CacheSocketStr,
|
||||
SMBIOS_STRING_MAX_LENGTH - 1,
|
||||
L"L%x Cache",
|
||||
CacheLevel);
|
||||
}
|
||||
|
||||
return CacheSocketStrLen;
|
||||
}
|
||||
|
||||
/** Fills in the Type 7 record with the cache architecture information
|
||||
read from the CPU registers.
|
||||
|
||||
@param[in] CacheLevel Cache level (e.g. L1, L2).
|
||||
@param[in] DataCache Cache is a data cache.
|
||||
@param[in] UnifiedCache Cache is a unified cache.
|
||||
@param[out] Type7Record The Type 7 record to fill in.
|
||||
|
||||
**/
|
||||
VOID
|
||||
ConfigureCacheArchitectureInformation (
|
||||
IN UINT8 CacheLevel,
|
||||
IN BOOLEAN DataCache,
|
||||
IN BOOLEAN UnifiedCache,
|
||||
OUT SMBIOS_TABLE_TYPE7 *Type7Record
|
||||
)
|
||||
{
|
||||
UINT8 Associativity;
|
||||
UINT32 CacheSize32;
|
||||
UINT16 CacheSize16;
|
||||
UINT64 CacheSize64;
|
||||
|
||||
if (!DataCache && !UnifiedCache) {
|
||||
Type7Record->SystemCacheType = CacheTypeInstruction;
|
||||
} else if (DataCache) {
|
||||
Type7Record->SystemCacheType = CacheTypeData;
|
||||
} else if (UnifiedCache) {
|
||||
Type7Record->SystemCacheType = CacheTypeUnified;
|
||||
} else {
|
||||
ASSERT(FALSE);
|
||||
}
|
||||
|
||||
CacheSize64 = SmbiosProcessorGetCacheSize (CacheLevel,
|
||||
DataCache,
|
||||
UnifiedCache
|
||||
);
|
||||
|
||||
Associativity = SmbiosProcessorGetCacheAssociativity (CacheLevel,
|
||||
DataCache,
|
||||
UnifiedCache
|
||||
);
|
||||
|
||||
CacheSize64 /= 1024; // Minimum granularity is 1K
|
||||
|
||||
// Encode the cache size into the format SMBIOS wants
|
||||
if (CacheSize64 < MAX_INT16) {
|
||||
CacheSize16 = CacheSize64;
|
||||
CacheSize32 = CacheSize16;
|
||||
} else if ((CacheSize64 / 64) < MAX_INT16) {
|
||||
CacheSize16 = (1 << 15) | (CacheSize64 / 64);
|
||||
CacheSize32 = CacheSize16;
|
||||
} else {
|
||||
if ((CacheSize64 / 1024) <= 2047) {
|
||||
CacheSize32 = CacheSize64;
|
||||
} else {
|
||||
CacheSize32 = (1 << 31) | (CacheSize64 / 64);
|
||||
}
|
||||
|
||||
CacheSize16 = -1;
|
||||
}
|
||||
|
||||
Type7Record->MaximumCacheSize = CacheSize16;
|
||||
Type7Record->InstalledSize = CacheSize16;
|
||||
Type7Record->MaximumCacheSize2 = CacheSize32;
|
||||
Type7Record->InstalledSize2 = CacheSize32;
|
||||
|
||||
switch (Associativity) {
|
||||
case 2:
|
||||
Type7Record->Associativity = CacheAssociativity2Way;
|
||||
break;
|
||||
case 4:
|
||||
Type7Record->Associativity = CacheAssociativity4Way;
|
||||
break;
|
||||
case 8:
|
||||
Type7Record->Associativity = CacheAssociativity8Way;
|
||||
break;
|
||||
case 12:
|
||||
Type7Record->Associativity = CacheAssociativity12Way;
|
||||
break;
|
||||
case 16:
|
||||
Type7Record->Associativity = CacheAssociativity16Way;
|
||||
break;
|
||||
case 20:
|
||||
Type7Record->Associativity = CacheAssociativity20Way;
|
||||
break;
|
||||
case 24:
|
||||
Type7Record->Associativity = CacheAssociativity24Way;
|
||||
break;
|
||||
case 32:
|
||||
Type7Record->Associativity = CacheAssociativity32Way;
|
||||
break;
|
||||
case 48:
|
||||
Type7Record->Associativity = CacheAssociativity48Way;
|
||||
break;
|
||||
case 64:
|
||||
Type7Record->Associativity = CacheAssociativity64Way;
|
||||
break;
|
||||
default:
|
||||
Type7Record->Associativity = CacheAssociativityOther;
|
||||
break;
|
||||
}
|
||||
|
||||
Type7Record->CacheConfiguration = (CacheModeUnknown << CACHE_OPERATION_MODE_SHIFT) |
|
||||
(1 << CACHE_ENABLED_SHIFT) |
|
||||
(CacheLocationUnknown << CACHE_LOCATION_SHIFT) |
|
||||
(0 << CACHE_SOCKETED_SHIFT) |
|
||||
(CacheLevel - 1);
|
||||
}
|
||||
|
||||
|
||||
/** Allocates and initializes an SMBIOS_TABLE_TYPE7 structure.
|
||||
|
||||
@param[in] CacheLevel The cache level (L1-L7).
|
||||
@param[in] DataCache Cache is a data cache.
|
||||
@param[in] UnifiedCache Cache is a unified cache.
|
||||
|
||||
@return A pointer to the Type 7 structure. Returns NULL on failure.
|
||||
**/
|
||||
SMBIOS_TABLE_TYPE7 *
|
||||
AllocateAndInitCacheInformation (
|
||||
IN UINT8 CacheLevel,
|
||||
IN BOOLEAN DataCache,
|
||||
IN BOOLEAN UnifiedCache
|
||||
)
|
||||
{
|
||||
SMBIOS_TABLE_TYPE7 *Type7Record;
|
||||
EFI_STRING CacheSocketStr;
|
||||
UINTN CacheSocketStrLen;
|
||||
UINTN StringBufferSize;
|
||||
CHAR8 *OptionalStrStart;
|
||||
UINTN TableSize;
|
||||
|
||||
// Allocate and fetch the cache description
|
||||
StringBufferSize = sizeof (CHAR16) * SMBIOS_STRING_MAX_LENGTH;
|
||||
CacheSocketStr = AllocateZeroPool (StringBufferSize);
|
||||
if (CacheSocketStr == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
CacheSocketStrLen = GetCacheSocketStr (CacheLevel,
|
||||
DataCache,
|
||||
UnifiedCache,
|
||||
CacheSocketStr);
|
||||
|
||||
TableSize = sizeof (SMBIOS_TABLE_TYPE7) + CacheSocketStrLen + 1 + 1;
|
||||
Type7Record = AllocateZeroPool (TableSize);
|
||||
if (Type7Record == NULL) {
|
||||
FreePool(CacheSocketStr);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Type7Record->Hdr.Type = EFI_SMBIOS_TYPE_CACHE_INFORMATION;
|
||||
Type7Record->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE7);
|
||||
Type7Record->Hdr.Handle = SMBIOS_HANDLE_PI_RESERVED;
|
||||
|
||||
Type7Record->SocketDesignation = 1;
|
||||
|
||||
Type7Record->SupportedSRAMType.Unknown = 1;
|
||||
Type7Record->CurrentSRAMType.Unknown = 1;
|
||||
Type7Record->CacheSpeed = 0;
|
||||
Type7Record->ErrorCorrectionType = CacheErrorUnknown;
|
||||
|
||||
OptionalStrStart = (CHAR8 *)(Type7Record + 1);
|
||||
UnicodeStrToAsciiStrS (CacheSocketStr, OptionalStrStart, CacheSocketStrLen + 1);
|
||||
FreePool (CacheSocketStr);
|
||||
|
||||
return Type7Record;
|
||||
}
|
||||
|
||||
/**
|
||||
Add Type 7 SMBIOS Record for Cache Information.
|
||||
|
||||
@param[in] ProcessorIndex Processor number of specified processor.
|
||||
@param[out] L1CacheHandle Pointer to the handle of the L1 Cache SMBIOS record.
|
||||
@param[out] L2CacheHandle Pointer to the handle of the L2 Cache SMBIOS record.
|
||||
@param[out] L3CacheHandle Pointer to the handle of the L3 Cache SMBIOS record.
|
||||
|
||||
**/
|
||||
VOID
|
||||
AddSmbiosCacheTypeTable (
|
||||
IN UINTN ProcessorIndex,
|
||||
OUT EFI_SMBIOS_HANDLE *L1CacheHandle,
|
||||
OUT EFI_SMBIOS_HANDLE *L2CacheHandle,
|
||||
OUT EFI_SMBIOS_HANDLE *L3CacheHandle
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
SMBIOS_TABLE_TYPE7 *Type7Record;
|
||||
EFI_SMBIOS_HANDLE SmbiosHandle;
|
||||
UINT8 CacheLevel;
|
||||
UINT8 MaxCacheLevel;
|
||||
BOOLEAN DataCacheType;
|
||||
BOOLEAN SeparateCaches;
|
||||
|
||||
Status = EFI_SUCCESS;
|
||||
|
||||
MaxCacheLevel = 0;
|
||||
|
||||
// See if there's an L1 cache present.
|
||||
MaxCacheLevel = SmbiosProcessorGetMaxCacheLevel ();
|
||||
|
||||
if (MaxCacheLevel < 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (CacheLevel = 1; CacheLevel <= MaxCacheLevel; CacheLevel++) {
|
||||
Type7Record = NULL;
|
||||
|
||||
SeparateCaches = SmbiosProcessorHasSeparateCaches (CacheLevel);
|
||||
|
||||
// At each level of cache, we can have a single type (unified, instruction or data),
|
||||
// or two types - separate data and instruction caches. If we have separate
|
||||
// instruction and data caches, then on the first iteration (CacheSubLevel = 0)
|
||||
// process the instruction cache.
|
||||
for (DataCacheType = 0; DataCacheType <= 1; DataCacheType++) {
|
||||
// If there's no separate data/instruction cache, skip the second iteration
|
||||
if (DataCacheType == 1 && !SeparateCaches) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Type7Record = AllocateAndInitCacheInformation (CacheLevel,
|
||||
DataCacheType,
|
||||
!SeparateCaches
|
||||
);
|
||||
if (Type7Record == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
ConfigureCacheArchitectureInformation(CacheLevel,
|
||||
DataCacheType,
|
||||
!SeparateCaches,
|
||||
Type7Record
|
||||
);
|
||||
|
||||
// Allow the platform to fill in other information such as speed, SRAM type etc.
|
||||
if (!OemGetCacheInformation (ProcessorIndex, CacheLevel,
|
||||
DataCacheType, !SeparateCaches, Type7Record)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
|
||||
// Finally, install the table
|
||||
Status = mSmbios->Add (mSmbios, NULL, &SmbiosHandle,
|
||||
(EFI_SMBIOS_TABLE_HEADER *)Type7Record);
|
||||
if (EFI_ERROR (Status)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Config L1/L2/L3 Cache Handle
|
||||
switch (CacheLevel) {
|
||||
case CpuCacheL1:
|
||||
*L1CacheHandle = SmbiosHandle;
|
||||
break;
|
||||
case CpuCacheL2:
|
||||
*L2CacheHandle = SmbiosHandle;
|
||||
break;
|
||||
case CpuCacheL3:
|
||||
*L3CacheHandle = SmbiosHandle;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Allocates a Type 4 Processor Information structure and sets the
|
||||
strings following the data fields.
|
||||
|
||||
@param[out] Type4Record The Type 4 structure to allocate and initialize
|
||||
@param[in] ProcessorIndex The index of the processor
|
||||
@param[in] Populated Whether the specified processor is
|
||||
populated.
|
||||
|
||||
@retval EFI_SUCCESS The Type 4 structure was successfully
|
||||
allocated and the strings initialized.
|
||||
@retval EFI_OUT_OF_RESOURCES Could not allocate memory needed.
|
||||
**/
|
||||
EFI_STATUS
|
||||
AllocateType4AndSetProcessorInformationStrings (
|
||||
SMBIOS_TABLE_TYPE4 **Type4Record,
|
||||
UINT8 ProcessorIndex,
|
||||
BOOLEAN Populated
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_STRING_ID ProcessorManu;
|
||||
EFI_STRING_ID ProcessorVersion;
|
||||
EFI_STRING_ID SerialNumber;
|
||||
EFI_STRING_ID AssetTag;
|
||||
EFI_STRING_ID PartNumber;
|
||||
EFI_STRING ProcessorStr;
|
||||
EFI_STRING ProcessorManuStr;
|
||||
EFI_STRING ProcessorVersionStr;
|
||||
EFI_STRING SerialNumberStr;
|
||||
EFI_STRING AssetTagStr;
|
||||
EFI_STRING PartNumberStr;
|
||||
CHAR8 *OptionalStrStart;
|
||||
CHAR8 *StrStart;
|
||||
UINTN ProcessorStrLen;
|
||||
UINTN ProcessorManuStrLen;
|
||||
UINTN ProcessorVersionStrLen;
|
||||
UINTN SerialNumberStrLen;
|
||||
UINTN AssetTagStrLen;
|
||||
UINTN PartNumberStrLen;
|
||||
UINTN TotalSize;
|
||||
UINTN StringBufferSize;
|
||||
|
||||
Status = EFI_SUCCESS;
|
||||
|
||||
ProcessorManuStr = NULL;
|
||||
ProcessorVersionStr = NULL;
|
||||
SerialNumberStr = NULL;
|
||||
AssetTagStr = NULL;
|
||||
PartNumberStr = NULL;
|
||||
|
||||
ProcessorManu = STRING_TOKEN (STR_PROCESSOR_MANUFACTURE);
|
||||
ProcessorVersion = STRING_TOKEN (STR_PROCESSOR_VERSION);
|
||||
SerialNumber = STRING_TOKEN (STR_PROCESSOR_SERIAL_NUMBER);
|
||||
AssetTag = STRING_TOKEN (STR_PROCESSOR_ASSET_TAG);
|
||||
PartNumber = STRING_TOKEN (STR_PROCESSOR_PART_NUMBER);
|
||||
|
||||
SET_HII_STRING_IF_PCD_NOT_EMPTY (PcdProcessorManufacturer, ProcessorManu);
|
||||
SET_HII_STRING_IF_PCD_NOT_EMPTY (PcdProcessorVersion, ProcessorVersion);
|
||||
SET_HII_STRING_IF_PCD_NOT_EMPTY (PcdProcessorSerialNumber, SerialNumber);
|
||||
SET_HII_STRING_IF_PCD_NOT_EMPTY (PcdProcessorAssetTag, AssetTag);
|
||||
SET_HII_STRING_IF_PCD_NOT_EMPTY (PcdProcessorPartNumber, PartNumber);
|
||||
|
||||
// Processor Designation
|
||||
StringBufferSize = sizeof (CHAR16) * SMBIOS_STRING_MAX_LENGTH;
|
||||
ProcessorStr = AllocateZeroPool (StringBufferSize);
|
||||
if (ProcessorStr == NULL) {
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
ProcessorStrLen = UnicodeSPrint (ProcessorStr, StringBufferSize,
|
||||
L"CPU%02d", ProcessorIndex + 1);
|
||||
|
||||
// Processor Manufacture
|
||||
ProcessorManuStr = HiiGetPackageString (&gEfiCallerIdGuid, ProcessorManu, NULL);
|
||||
ProcessorManuStrLen = StrLen (ProcessorManuStr);
|
||||
|
||||
// Processor Version
|
||||
ProcessorVersionStr = HiiGetPackageString (&gEfiCallerIdGuid, ProcessorVersion, NULL);
|
||||
ProcessorVersionStrLen = StrLen (ProcessorVersionStr);
|
||||
|
||||
// Serial Number
|
||||
SerialNumberStr = HiiGetPackageString (&gEfiCallerIdGuid, SerialNumber, NULL);
|
||||
SerialNumberStrLen = StrLen (SerialNumberStr);
|
||||
|
||||
// Asset Tag
|
||||
AssetTagStr = HiiGetPackageString (&gEfiCallerIdGuid, AssetTag, NULL);
|
||||
AssetTagStrLen = StrLen (AssetTagStr);
|
||||
|
||||
// Part Number
|
||||
PartNumberStr = HiiGetPackageString (&gEfiCallerIdGuid, PartNumber, NULL);
|
||||
PartNumberStrLen = StrLen (PartNumberStr);
|
||||
|
||||
TotalSize = sizeof (SMBIOS_TABLE_TYPE4) +
|
||||
ProcessorStrLen + 1 +
|
||||
ProcessorManuStrLen + 1 +
|
||||
ProcessorVersionStrLen + 1 +
|
||||
SerialNumberStrLen + 1 +
|
||||
AssetTagStrLen + 1 +
|
||||
PartNumberStrLen + 1 + 1;
|
||||
|
||||
*Type4Record = AllocateZeroPool (TotalSize);
|
||||
if (*Type4Record == NULL) {
|
||||
Status = EFI_OUT_OF_RESOURCES;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
CopyMem (*Type4Record, &mSmbiosProcessorTableTemplate, sizeof (SMBIOS_TABLE_TYPE4));
|
||||
|
||||
OptionalStrStart = (CHAR8 *)(*Type4Record + 1);
|
||||
UnicodeStrToAsciiStrS (
|
||||
ProcessorStr,
|
||||
OptionalStrStart,
|
||||
ProcessorStrLen + 1
|
||||
);
|
||||
|
||||
StrStart = OptionalStrStart + ProcessorStrLen + 1;
|
||||
UnicodeStrToAsciiStrS (
|
||||
ProcessorManuStr,
|
||||
StrStart,
|
||||
ProcessorManuStrLen + 1
|
||||
);
|
||||
|
||||
StrStart += ProcessorManuStrLen + 1;
|
||||
UnicodeStrToAsciiStrS (
|
||||
ProcessorVersionStr,
|
||||
StrStart,
|
||||
ProcessorVersionStrLen + 1
|
||||
);
|
||||
|
||||
StrStart += ProcessorVersionStrLen + 1;
|
||||
UnicodeStrToAsciiStrS (
|
||||
SerialNumberStr,
|
||||
StrStart,
|
||||
SerialNumberStrLen + 1
|
||||
);
|
||||
|
||||
StrStart += SerialNumberStrLen + 1;
|
||||
UnicodeStrToAsciiStrS (
|
||||
AssetTagStr,
|
||||
StrStart,
|
||||
AssetTagStrLen + 1
|
||||
);
|
||||
|
||||
StrStart += AssetTagStrLen + 1;
|
||||
UnicodeStrToAsciiStrS (
|
||||
PartNumberStr,
|
||||
StrStart,
|
||||
PartNumberStrLen + 1
|
||||
);
|
||||
|
||||
Exit:
|
||||
FreePool (ProcessorStr);
|
||||
FreePool (ProcessorManuStr);
|
||||
FreePool (ProcessorVersionStr);
|
||||
FreePool (SerialNumberStr);
|
||||
FreePool (AssetTagStr);
|
||||
FreePool (PartNumberStr);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
Add Type 4 SMBIOS Record for Processor Information.
|
||||
|
||||
@param[in] ProcessorIndex Processor index of specified processor.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
AddSmbiosProcessorTypeTable (
|
||||
IN UINTN ProcessorIndex
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
SMBIOS_TABLE_TYPE4 *Type4Record;
|
||||
EFI_SMBIOS_HANDLE SmbiosHandle;
|
||||
EFI_SMBIOS_HANDLE L1CacheHandle;
|
||||
EFI_SMBIOS_HANDLE L2CacheHandle;
|
||||
EFI_SMBIOS_HANDLE L3CacheHandle;
|
||||
UINT8 *LegacyVoltage;
|
||||
PROCESSOR_STATUS_DATA ProcessorStatus;
|
||||
UINT64 *ProcessorId;
|
||||
PROCESSOR_CHARACTERISTIC_FLAGS ProcessorCharacteristics;
|
||||
OEM_MISC_PROCESSOR_DATA MiscProcessorData;
|
||||
BOOLEAN ProcessorPopulated;
|
||||
|
||||
Type4Record = NULL;
|
||||
|
||||
MiscProcessorData.Voltage = 0;
|
||||
MiscProcessorData.CurrentSpeed = 0;
|
||||
MiscProcessorData.CoreCount = 0;
|
||||
MiscProcessorData.CoresEnabled = 0;
|
||||
MiscProcessorData.ThreadCount = 0;
|
||||
MiscProcessorData.MaxSpeed = 0;
|
||||
L1CacheHandle = 0xFFFF;
|
||||
L2CacheHandle = 0xFFFF;
|
||||
L3CacheHandle = 0xFFFF;
|
||||
|
||||
ProcessorPopulated = OemIsProcessorPresent (ProcessorIndex);
|
||||
|
||||
Status = AllocateType4AndSetProcessorInformationStrings (
|
||||
&Type4Record,
|
||||
ProcessorIndex,
|
||||
ProcessorPopulated
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
OemGetProcessorInformation (ProcessorIndex,
|
||||
&ProcessorStatus,
|
||||
(PROCESSOR_CHARACTERISTIC_FLAGS*)
|
||||
&Type4Record->ProcessorCharacteristics,
|
||||
&MiscProcessorData);
|
||||
|
||||
if (ProcessorPopulated) {
|
||||
AddSmbiosCacheTypeTable (ProcessorIndex, &L1CacheHandle,
|
||||
&L2CacheHandle, &L3CacheHandle);
|
||||
}
|
||||
|
||||
LegacyVoltage = (UINT8*)&Type4Record->Voltage;
|
||||
|
||||
*LegacyVoltage = MiscProcessorData.Voltage;
|
||||
Type4Record->CurrentSpeed = MiscProcessorData.CurrentSpeed;
|
||||
Type4Record->MaxSpeed = MiscProcessorData.MaxSpeed;
|
||||
Type4Record->Status = ProcessorStatus.Data;
|
||||
Type4Record->L1CacheHandle = L1CacheHandle;
|
||||
Type4Record->L2CacheHandle = L2CacheHandle;
|
||||
Type4Record->L3CacheHandle = L3CacheHandle;
|
||||
Type4Record->CoreCount = MiscProcessorData.CoreCount;
|
||||
Type4Record->CoreCount2 = MiscProcessorData.CoreCount;
|
||||
Type4Record->EnabledCoreCount = MiscProcessorData.CoresEnabled;
|
||||
Type4Record->EnabledCoreCount2 = MiscProcessorData.CoresEnabled;
|
||||
Type4Record->ThreadCount = MiscProcessorData.ThreadCount;
|
||||
Type4Record->ThreadCount2 = MiscProcessorData.ThreadCount;
|
||||
|
||||
Type4Record->CurrentSpeed = GetCpuFrequency (ProcessorIndex);
|
||||
Type4Record->ExternalClock =
|
||||
(UINT16)(SmbiosGetExternalClockFrequency () / 1000 / 1000);
|
||||
|
||||
ProcessorId = (UINT64*)&Type4Record->ProcessorId;
|
||||
*ProcessorId = SmbiosGetProcessorId ();
|
||||
|
||||
ProcessorCharacteristics = SmbiosGetProcessorCharacteristics ();
|
||||
Type4Record->ProcessorCharacteristics |= *((UINT64*)&ProcessorCharacteristics);
|
||||
|
||||
Type4Record->ProcessorFamily = SmbiosGetProcessorFamily ();
|
||||
Type4Record->ProcessorFamily2 = SmbiosGetProcessorFamily2 ();
|
||||
|
||||
SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
|
||||
Status = mSmbios->Add (mSmbios, NULL, &SmbiosHandle,
|
||||
(EFI_SMBIOS_TABLE_HEADER *)Type4Record);
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((DEBUG_ERROR, "[%a]:[%dL] Smbios Type04 Table Log Failed! %r \n",
|
||||
__FUNCTION__, __LINE__, Status));
|
||||
}
|
||||
FreePool (Type4Record);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
Standard EFI driver point.
|
||||
|
||||
@param ImageHandle Handle for the image of this driver
|
||||
@param SystemTable Pointer to the EFI System Table
|
||||
|
||||
@retval EFI_SUCCESS The data was successfully stored.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
ProcessorSubClassEntryPoint(
|
||||
IN EFI_HANDLE ImageHandle,
|
||||
IN EFI_SYSTEM_TABLE *SystemTable
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
UINT32 ProcessorIndex;
|
||||
|
||||
//
|
||||
// Locate dependent protocols
|
||||
//
|
||||
Status = gBS->LocateProtocol (&gEfiSmbiosProtocolGuid, NULL, (VOID**)&mSmbios);
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((DEBUG_ERROR, "Could not locate SMBIOS protocol. %r\n", Status));
|
||||
return Status;
|
||||
}
|
||||
|
||||
//
|
||||
// Add our default strings to the HII database. They will be modified later.
|
||||
//
|
||||
mHiiHandle = HiiAddPackages (&gEfiCallerIdGuid,
|
||||
NULL,
|
||||
ProcessorSubClassStrings,
|
||||
NULL,
|
||||
NULL
|
||||
);
|
||||
if (mHiiHandle == NULL) {
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
//
|
||||
// Add SMBIOS tables for populated sockets.
|
||||
//
|
||||
for (ProcessorIndex = 0; ProcessorIndex < OemGetMaxProcessors (); ProcessorIndex++) {
|
||||
Status = AddSmbiosProcessorTypeTable (ProcessorIndex);
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((DEBUG_ERROR, "Add Processor Type Table Failed! %r.\n", Status));
|
||||
return Status;
|
||||
}
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
@ -0,0 +1,66 @@
|
||||
#/** @file
|
||||
# ProcessorSubClassDxe.inf
|
||||
#
|
||||
# Copyright (c) 2021, NUVIA Inc. All rights reserved.
|
||||
# Copyright (c) 2015, Hisilicon Limited. All rights reserved.
|
||||
# Copyright (c) 2015, Linaro Limited. All rights reserved.
|
||||
#
|
||||
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
#
|
||||
#**/
|
||||
|
||||
|
||||
[Defines]
|
||||
INF_VERSION = 1.29
|
||||
BASE_NAME = ProcessorSubClass
|
||||
FILE_GUID = f3fe0e33-ea38-4069-9fb5-be23407207c7
|
||||
MODULE_TYPE = DXE_DRIVER
|
||||
VERSION_STRING = 1.0
|
||||
ENTRY_POINT = ProcessorSubClassEntryPoint
|
||||
|
||||
[Sources]
|
||||
SmbiosProcessorArmCommon.c
|
||||
ProcessorSubClass.c
|
||||
ProcessorSubClassStrings.uni
|
||||
SmbiosProcessor.h
|
||||
|
||||
[Sources.AARCH64]
|
||||
SmbiosProcessorAArch64.c
|
||||
|
||||
[Sources.ARM]
|
||||
SmbiosProcessorArm.c
|
||||
|
||||
[Packages]
|
||||
ArmPkg/ArmPkg.dec
|
||||
MdeModulePkg/MdeModulePkg.dec
|
||||
MdePkg/MdePkg.dec
|
||||
|
||||
[LibraryClasses]
|
||||
ArmLib
|
||||
ArmSmcLib
|
||||
BaseLib
|
||||
BaseMemoryLib
|
||||
DebugLib
|
||||
HiiLib
|
||||
IoLib
|
||||
MemoryAllocationLib
|
||||
OemMiscLib
|
||||
PcdLib
|
||||
PrintLib
|
||||
UefiDriverEntryPoint
|
||||
|
||||
[Protocols]
|
||||
gEfiSmbiosProtocolGuid # PROTOCOL ALWAYS_CONSUMED
|
||||
|
||||
[Pcd]
|
||||
gArmTokenSpaceGuid.PcdProcessorManufacturer
|
||||
gArmTokenSpaceGuid.PcdProcessorVersion
|
||||
gArmTokenSpaceGuid.PcdProcessorSerialNumber
|
||||
gArmTokenSpaceGuid.PcdProcessorAssetTag
|
||||
gArmTokenSpaceGuid.PcdProcessorPartNumber
|
||||
|
||||
[Guids]
|
||||
|
||||
|
||||
[Depex]
|
||||
gEfiSmbiosProtocolGuid
|
@ -0,0 +1,24 @@
|
||||
/** @file
|
||||
SMBIOS Type 4 strings
|
||||
|
||||
Copyright (c) 2021, NUVIA Inc. All rights reserved.
|
||||
Copyright (c) 2015, Hisilicon Limited. All rights reserved.
|
||||
Copyright (c) 2015, Linaro Limited. All rights reserved.
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
**/
|
||||
|
||||
/=#
|
||||
|
||||
#langdef en-US "English"
|
||||
|
||||
//
|
||||
// Processor Information
|
||||
//
|
||||
#string STR_PROCESSOR_SOCKET_DESIGNATION #language en-US "Not Specified"
|
||||
#string STR_PROCESSOR_MANUFACTURE #language en-US "Not Specified"
|
||||
#string STR_PROCESSOR_VERSION #language en-US "Not Specified"
|
||||
#string STR_PROCESSOR_SERIAL_NUMBER #language en-US "Not Specified"
|
||||
#string STR_PROCESSOR_ASSET_TAG #language en-US "Not Specified"
|
||||
#string STR_PROCESSOR_PART_NUMBER #language en-US "Not Specified"
|
||||
#string STR_PROCESSOR_UNKNOWN #language en-US "Unknown"
|
102
ArmPkg/Universal/Smbios/ProcessorSubClassDxe/SmbiosProcessor.h
Normal file
102
ArmPkg/Universal/Smbios/ProcessorSubClassDxe/SmbiosProcessor.h
Normal file
@ -0,0 +1,102 @@
|
||||
/** @file
|
||||
SMBIOS Processor Related Functions.
|
||||
|
||||
Copyright (c) 2021, NUVIA Inc. All rights reserved.<BR>
|
||||
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
**/
|
||||
|
||||
#ifndef SMBIOS_PROCESSOR_H_
|
||||
#define SMBIOS_PROCESSOR_H_
|
||||
|
||||
#include <Uefi.h>
|
||||
#include <IndustryStandard/SmBios.h>
|
||||
|
||||
/** Returns the maximum cache level implemented by the current CPU.
|
||||
|
||||
@return The maximum cache level implemented.
|
||||
**/
|
||||
UINT8
|
||||
SmbiosProcessorGetMaxCacheLevel (
|
||||
VOID
|
||||
);
|
||||
|
||||
/** Returns whether or not the specified cache level has separate I/D caches.
|
||||
|
||||
@param CacheLevel The cache level (L1, L2 etc.).
|
||||
|
||||
@return TRUE if the cache level has separate I/D caches, FALSE otherwise.
|
||||
**/
|
||||
BOOLEAN
|
||||
SmbiosProcessorHasSeparateCaches (
|
||||
UINT8 CacheLevel
|
||||
);
|
||||
|
||||
/** Gets the size of the specified cache.
|
||||
|
||||
@param CacheLevel The cache level (L1, L2 etc.).
|
||||
@param DataCache Whether the cache is a dedicated data cache.
|
||||
@param UnifiedCache Whether the cache is a unified cache.
|
||||
|
||||
@return The cache size.
|
||||
**/
|
||||
UINT64
|
||||
SmbiosProcessorGetCacheSize (
|
||||
IN UINT8 CacheLevel,
|
||||
IN BOOLEAN DataCache,
|
||||
IN BOOLEAN UnifiedCache
|
||||
);
|
||||
|
||||
/** Gets the associativity of the specified cache.
|
||||
|
||||
@param CacheLevel The cache level (L1, L2 etc.).
|
||||
@param DataCache Whether the cache is a dedicated data cache.
|
||||
@param UnifiedCache Whether the cache is a unified cache.
|
||||
|
||||
@return The cache associativity.
|
||||
**/
|
||||
UINT32
|
||||
SmbiosProcessorGetCacheAssociativity (
|
||||
IN UINT8 CacheLevel,
|
||||
IN BOOLEAN DataCache,
|
||||
IN BOOLEAN UnifiedCache
|
||||
);
|
||||
|
||||
/** Returns a value for the Processor ID field that conforms to SMBIOS
|
||||
requirements.
|
||||
|
||||
@return Processor ID.
|
||||
**/
|
||||
UINT64
|
||||
SmbiosGetProcessorId (VOID);
|
||||
|
||||
/** Returns the external clock frequency.
|
||||
|
||||
@return The external CPU clock frequency.
|
||||
**/
|
||||
UINTN
|
||||
SmbiosGetExternalClockFrequency (VOID);
|
||||
|
||||
/** Returns the SMBIOS ProcessorFamily field value.
|
||||
|
||||
@return The value for the ProcessorFamily field.
|
||||
**/
|
||||
UINT8
|
||||
SmbiosGetProcessorFamily (VOID);
|
||||
|
||||
/** Returns the ProcessorFamily2 field value.
|
||||
|
||||
@return The value for the ProcessorFamily2 field.
|
||||
**/
|
||||
UINT16
|
||||
SmbiosGetProcessorFamily2 (VOID);
|
||||
|
||||
/** Returns the SMBIOS Processor Characteristics.
|
||||
|
||||
@return Processor Characteristics bitfield.
|
||||
**/
|
||||
PROCESSOR_CHARACTERISTIC_FLAGS
|
||||
SmbiosGetProcessorCharacteristics (VOID);
|
||||
|
||||
#endif // SMBIOS_PROCESSOR_H_
|
@ -0,0 +1,93 @@
|
||||
/** @file
|
||||
Functions for AARCH64 processor information
|
||||
|
||||
Copyright (c) 2021, NUVIA Inc. All rights reserved.<BR>
|
||||
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
**/
|
||||
|
||||
#include <Uefi.h>
|
||||
#include <Library/ArmLib.h>
|
||||
#include <Library/ArmLib/ArmLibPrivate.h>
|
||||
|
||||
#include "SmbiosProcessor.h"
|
||||
|
||||
/** Gets the size of the specified cache.
|
||||
|
||||
@param CacheLevel The cache level (L1, L2 etc.).
|
||||
@param DataCache Whether the cache is a dedicated data cache.
|
||||
@param UnifiedCache Whether the cache is a unified cache.
|
||||
|
||||
@return The cache size.
|
||||
**/
|
||||
UINT64
|
||||
SmbiosProcessorGetCacheSize (
|
||||
IN UINT8 CacheLevel,
|
||||
IN BOOLEAN DataCache,
|
||||
IN BOOLEAN UnifiedCache
|
||||
)
|
||||
{
|
||||
CCSIDR_DATA Ccsidr;
|
||||
CSSELR_DATA Csselr;
|
||||
BOOLEAN CcidxSupported;
|
||||
UINT64 CacheSize;
|
||||
|
||||
Csselr.Data = 0;
|
||||
Csselr.Bits.Level = CacheLevel - 1;
|
||||
Csselr.Bits.InD = (!DataCache && !UnifiedCache);
|
||||
|
||||
Ccsidr.Data = ReadCCSIDR (Csselr.Data);
|
||||
|
||||
CcidxSupported = ArmHasCcidx ();
|
||||
|
||||
if (CcidxSupported) {
|
||||
CacheSize = (1 << (Ccsidr.BitsCcidxAA64.LineSize + 4)) *
|
||||
(Ccsidr.BitsCcidxAA64.Associativity + 1) *
|
||||
(Ccsidr.BitsCcidxAA64.NumSets + 1);
|
||||
} else {
|
||||
CacheSize = (1 << (Ccsidr.BitsNonCcidx.LineSize + 4)) *
|
||||
(Ccsidr.BitsNonCcidx.Associativity + 1) *
|
||||
(Ccsidr.BitsNonCcidx.NumSets + 1);
|
||||
}
|
||||
|
||||
return CacheSize;
|
||||
}
|
||||
|
||||
/** Gets the associativity of the specified cache.
|
||||
|
||||
@param CacheLevel The cache level (L1, L2 etc.).
|
||||
@param DataCache Whether the cache is a dedicated data cache.
|
||||
@param UnifiedCache Whether the cache is a unified cache.
|
||||
|
||||
@return The cache associativity.
|
||||
**/
|
||||
UINT32
|
||||
SmbiosProcessorGetCacheAssociativity (
|
||||
IN UINT8 CacheLevel,
|
||||
IN BOOLEAN DataCache,
|
||||
IN BOOLEAN UnifiedCache
|
||||
)
|
||||
{
|
||||
CCSIDR_DATA Ccsidr;
|
||||
CSSELR_DATA Csselr;
|
||||
BOOLEAN CcidxSupported;
|
||||
UINT32 Associativity;
|
||||
|
||||
Csselr.Data = 0;
|
||||
Csselr.Bits.Level = CacheLevel - 1;
|
||||
Csselr.Bits.InD = (!DataCache && !UnifiedCache);
|
||||
|
||||
Ccsidr.Data = ReadCCSIDR (Csselr.Data);
|
||||
|
||||
CcidxSupported = ArmHasCcidx ();
|
||||
|
||||
if (CcidxSupported) {
|
||||
Associativity = Ccsidr.BitsCcidxAA64.Associativity + 1;
|
||||
} else {
|
||||
Associativity = Ccsidr.BitsNonCcidx.Associativity + 1;
|
||||
}
|
||||
|
||||
return Associativity;
|
||||
}
|
||||
|
@ -0,0 +1,97 @@
|
||||
/** @file
|
||||
Functions for ARM processor information
|
||||
|
||||
Copyright (c) 2021, NUVIA Inc. All rights reserved.<BR>
|
||||
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
**/
|
||||
|
||||
#include <Uefi.h>
|
||||
#include <Library/ArmLib.h>
|
||||
#include <Library/ArmLib/ArmLibPrivate.h>
|
||||
|
||||
#include "SmbiosProcessor.h"
|
||||
|
||||
/** Gets the size of the specified cache.
|
||||
|
||||
@param CacheLevel The cache level (L1, L2 etc.).
|
||||
@param DataCache Whether the cache is a dedicated data cache.
|
||||
@param UnifiedCache Whether the cache is a unified cache.
|
||||
|
||||
@return The cache size.
|
||||
**/
|
||||
UINT64
|
||||
SmbiosProcessorGetCacheSize (
|
||||
IN UINT8 CacheLevel,
|
||||
IN BOOLEAN DataCache,
|
||||
IN BOOLEAN UnifiedCache
|
||||
)
|
||||
{
|
||||
CCSIDR_DATA Ccsidr;
|
||||
CCSIDR2_DATA Ccsidr2;
|
||||
CSSELR_DATA Csselr;
|
||||
BOOLEAN CcidxSupported;
|
||||
UINT64 CacheSize;
|
||||
|
||||
// Read the CCSIDR register to get the cache architecture
|
||||
Csselr.Data = 0;
|
||||
Csselr.Bits.Level = CacheLevel - 1;
|
||||
Csselr.Bits.InD = (!DataCache && !UnifiedCache);
|
||||
|
||||
Ccsidr.Data = ReadCCSIDR (Csselr.Data);
|
||||
|
||||
CcidxSupported = ArmHasCcidx ();
|
||||
|
||||
if (CcidxSupported) {
|
||||
Ccsidr2.Data = ReadCCSIDR2 (Csselr.Data);
|
||||
CacheSize = (1 << (Ccsidr.BitsCcidxAA32.LineSize + 4)) *
|
||||
(Ccsidr.BitsCcidxAA32.Associativity + 1) *
|
||||
(Ccsidr2.Bits.NumSets + 1);
|
||||
} else {
|
||||
CacheSize = (1 << (Ccsidr.BitsNonCcidx.LineSize + 4)) *
|
||||
(Ccsidr.BitsNonCcidx.Associativity + 1) *
|
||||
(Ccsidr.BitsNonCcidx.NumSets + 1);
|
||||
}
|
||||
|
||||
return CacheSize;
|
||||
}
|
||||
|
||||
/** Gets the associativity of the specified cache.
|
||||
|
||||
@param CacheLevel The cache level (L1, L2 etc.).
|
||||
@param DataCache Whether the cache is a dedicated data cache.
|
||||
@param UnifiedCache Whether the cache is a unified cache.
|
||||
|
||||
@return The cache associativity.
|
||||
**/
|
||||
UINT32
|
||||
SmbiosProcessorGetCacheAssociativity (
|
||||
IN UINT8 CacheLevel,
|
||||
IN BOOLEAN DataCache,
|
||||
IN BOOLEAN UnifiedCache
|
||||
)
|
||||
{
|
||||
CCSIDR_DATA Ccsidr;
|
||||
CSSELR_DATA Csselr;
|
||||
BOOLEAN CcidxSupported;
|
||||
UINT32 Associativity;
|
||||
|
||||
// Read the CCSIDR register to get the cache architecture
|
||||
Csselr.Data = 0;
|
||||
Csselr.Bits.Level = CacheLevel - 1;
|
||||
Csselr.Bits.InD = (!DataCache && !UnifiedCache);
|
||||
|
||||
Ccsidr.Data = ReadCCSIDR (Csselr.Data);
|
||||
|
||||
CcidxSupported = ArmHasCcidx ();
|
||||
|
||||
if (CcidxSupported) {
|
||||
Associativity = Ccsidr.BitsCcidxAA32.Associativity + 1;
|
||||
} else {
|
||||
Associativity = Ccsidr.BitsNonCcidx.Associativity + 1;
|
||||
}
|
||||
|
||||
return Associativity;
|
||||
}
|
||||
|
@ -0,0 +1,249 @@
|
||||
/** @file
|
||||
Functions for processor information common to ARM and AARCH64.
|
||||
|
||||
Copyright (c) 2021, NUVIA Inc. All rights reserved.<BR>
|
||||
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
**/
|
||||
|
||||
#include <Uefi.h>
|
||||
#include <IndustryStandard/ArmStdSmc.h>
|
||||
#include <IndustryStandard/SmBios.h>
|
||||
#include <Library/ArmLib.h>
|
||||
#include <Library/ArmLib/ArmLibPrivate.h>
|
||||
#include <Library/ArmSmcLib.h>
|
||||
#include <Library/BaseMemoryLib.h>
|
||||
|
||||
#include "SmbiosProcessor.h"
|
||||
|
||||
/** Returns the maximum cache level implemented by the current CPU.
|
||||
|
||||
@return The maximum cache level implemented.
|
||||
**/
|
||||
UINT8
|
||||
SmbiosProcessorGetMaxCacheLevel (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
CLIDR_DATA Clidr;
|
||||
UINT8 CacheLevel;
|
||||
UINT8 MaxCacheLevel;
|
||||
|
||||
MaxCacheLevel = 0;
|
||||
|
||||
// Read the CLIDR register to find out what caches are present.
|
||||
Clidr.Data = ReadCLIDR ();
|
||||
|
||||
// Get the cache type for the L1 cache. If it's 0, there are no caches.
|
||||
if (CLIDR_GET_CACHE_TYPE (Clidr.Data, 1) == ClidrCacheTypeNone) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (CacheLevel = 1; CacheLevel <= MAX_ARM_CACHE_LEVEL; CacheLevel++) {
|
||||
if (CLIDR_GET_CACHE_TYPE (Clidr.Data, CacheLevel) == ClidrCacheTypeNone) {
|
||||
MaxCacheLevel = CacheLevel;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return MaxCacheLevel;
|
||||
}
|
||||
|
||||
/** Returns whether or not the specified cache level has separate I/D caches.
|
||||
|
||||
@param CacheLevel The cache level (L1, L2 etc.).
|
||||
|
||||
@return TRUE if the cache level has separate I/D caches, FALSE otherwise.
|
||||
**/
|
||||
BOOLEAN
|
||||
SmbiosProcessorHasSeparateCaches (
|
||||
UINT8 CacheLevel
|
||||
)
|
||||
{
|
||||
CLIDR_CACHE_TYPE CacheType;
|
||||
CLIDR_DATA Clidr;
|
||||
BOOLEAN SeparateCaches;
|
||||
|
||||
SeparateCaches = FALSE;
|
||||
|
||||
Clidr.Data = ReadCLIDR ();
|
||||
|
||||
CacheType = CLIDR_GET_CACHE_TYPE (Clidr.Data, CacheLevel - 1);
|
||||
|
||||
if (CacheType == ClidrCacheTypeSeparate) {
|
||||
SeparateCaches = TRUE;
|
||||
}
|
||||
|
||||
return SeparateCaches;
|
||||
}
|
||||
|
||||
/** Checks if ther ARM64 SoC ID SMC call is supported
|
||||
|
||||
@return Whether the ARM64 SoC ID call is supported.
|
||||
**/
|
||||
BOOLEAN
|
||||
HasSmcArm64SocId (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
ARM_SMC_ARGS Args;
|
||||
INT32 SmcCallStatus;
|
||||
BOOLEAN Arm64SocIdSupported;
|
||||
|
||||
Arm64SocIdSupported = FALSE;
|
||||
|
||||
Args.Arg0 = SMCCC_VERSION;
|
||||
ArmCallSmc (&Args);
|
||||
SmcCallStatus = (INT32)Args.Arg0;
|
||||
|
||||
if (SmcCallStatus < 0 || (SmcCallStatus >> 16) >= 1) {
|
||||
Args.Arg0 = SMCCC_ARCH_FEATURES;
|
||||
Args.Arg1 = SMCCC_ARCH_SOC_ID;
|
||||
ArmCallSmc (&Args);
|
||||
|
||||
if (Args.Arg0 >= 0) {
|
||||
Arm64SocIdSupported = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return Arm64SocIdSupported;
|
||||
}
|
||||
|
||||
/** Fetches the JEP106 code and SoC Revision.
|
||||
|
||||
@param Jep106Code JEP 106 code.
|
||||
@param SocRevision SoC revision.
|
||||
|
||||
@retval EFI_SUCCESS Succeeded.
|
||||
@retval EFI_UNSUPPORTED Failed.
|
||||
**/
|
||||
EFI_STATUS
|
||||
SmbiosGetSmcArm64SocId (
|
||||
OUT INT32 *Jep106Code,
|
||||
OUT INT32 *SocRevision
|
||||
)
|
||||
{
|
||||
ARM_SMC_ARGS Args;
|
||||
INT32 SmcCallStatus;
|
||||
EFI_STATUS Status;
|
||||
|
||||
Status = EFI_SUCCESS;
|
||||
|
||||
Args.Arg0 = SMCCC_ARCH_SOC_ID;
|
||||
Args.Arg1 = 0;
|
||||
ArmCallSmc (&Args);
|
||||
SmcCallStatus = (INT32)Args.Arg0;
|
||||
|
||||
if (SmcCallStatus >= 0) {
|
||||
*Jep106Code = (INT32)Args.Arg0;
|
||||
} else {
|
||||
Status = EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
Args.Arg0 = SMCCC_ARCH_SOC_ID;
|
||||
Args.Arg1 = 1;
|
||||
ArmCallSmc (&Args);
|
||||
SmcCallStatus = (INT32)Args.Arg0;
|
||||
|
||||
if (SmcCallStatus >= 0) {
|
||||
*SocRevision = (INT32)Args.Arg0;
|
||||
} else {
|
||||
Status = EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/** Returns a value for the Processor ID field that conforms to SMBIOS
|
||||
requirements.
|
||||
|
||||
@return Processor ID.
|
||||
**/
|
||||
UINT64
|
||||
SmbiosGetProcessorId (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
INT32 Jep106Code;
|
||||
INT32 SocRevision;
|
||||
UINT64 ProcessorId;
|
||||
|
||||
if (HasSmcArm64SocId ()) {
|
||||
SmbiosGetSmcArm64SocId (&Jep106Code, &SocRevision);
|
||||
ProcessorId = ((UINT64)Jep106Code << 32) | SocRevision;
|
||||
} else {
|
||||
ProcessorId = ArmReadMidr ();
|
||||
}
|
||||
|
||||
return ProcessorId;
|
||||
}
|
||||
|
||||
/** Returns the external clock frequency.
|
||||
|
||||
@return The external clock frequency.
|
||||
**/
|
||||
UINTN
|
||||
SmbiosGetExternalClockFrequency (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
return ArmReadCntFrq ();
|
||||
}
|
||||
|
||||
/** Returns the SMBIOS ProcessorFamily field value.
|
||||
|
||||
@return The value for the ProcessorFamily field.
|
||||
**/
|
||||
UINT8
|
||||
SmbiosGetProcessorFamily (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
return ProcessorFamilyIndicatorFamily2;
|
||||
}
|
||||
|
||||
/** Returns the ProcessorFamily2 field value.
|
||||
|
||||
@return The value for the ProcessorFamily2 field.
|
||||
**/
|
||||
UINT16
|
||||
SmbiosGetProcessorFamily2 (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
UINTN MainIdRegister;
|
||||
UINT16 ProcessorFamily2;
|
||||
|
||||
MainIdRegister = ArmReadMidr ();
|
||||
|
||||
if (((MainIdRegister >> 16) & 0xF) < 8) {
|
||||
ProcessorFamily2 = ProcessorFamilyARM;
|
||||
} else {
|
||||
if (sizeof (VOID*) == 4) {
|
||||
ProcessorFamily2 = ProcessorFamilyARMv7;
|
||||
} else {
|
||||
ProcessorFamily2 = ProcessorFamilyARMv8;
|
||||
}
|
||||
}
|
||||
|
||||
return ProcessorFamily2;
|
||||
}
|
||||
|
||||
/** Returns the SMBIOS Processor Characteristics.
|
||||
|
||||
@return Processor Characteristics bitfield.
|
||||
**/
|
||||
PROCESSOR_CHARACTERISTIC_FLAGS
|
||||
SmbiosGetProcessorCharacteristics (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
PROCESSOR_CHARACTERISTIC_FLAGS Characteristics;
|
||||
|
||||
ZeroMem (&Characteristics, sizeof (Characteristics));
|
||||
|
||||
Characteristics.ProcessorArm64SocId = HasSmcArm64SocId ();
|
||||
|
||||
return Characteristics;
|
||||
}
|
134
ArmPkg/Universal/Smbios/SmbiosMiscDxe/SmbiosMisc.h
Normal file
134
ArmPkg/Universal/Smbios/SmbiosMiscDxe/SmbiosMisc.h
Normal file
@ -0,0 +1,134 @@
|
||||
/** @file
|
||||
Header file for the SmbiosMisc Driver.
|
||||
|
||||
Based on files under Nt32Pkg/MiscSubClassPlatformDxe/
|
||||
|
||||
Copyright (c) 2021, NUVIA Inc. All rights reserved.<BR>
|
||||
Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
|
||||
Copyright (c) 2015, Hisilicon Limited. All rights reserved.<BR>
|
||||
Copyright (c) 2015, Linaro Limited. All rights reserved.<BR>
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
**/
|
||||
|
||||
#ifndef SMBIOS_MISC_H_
|
||||
#define SMBIOS_MISC_H_
|
||||
|
||||
#include <Protocol/Smbios.h>
|
||||
#include <IndustryStandard/SmBios.h>
|
||||
|
||||
//
|
||||
// Data table entry update function.
|
||||
//
|
||||
typedef EFI_STATUS (EFIAPI SMBIOS_MISC_DATA_FUNCTION) (
|
||||
IN VOID *RecordData,
|
||||
IN EFI_SMBIOS_PROTOCOL *Smbios
|
||||
);
|
||||
|
||||
|
||||
//
|
||||
// Data table entry definition.
|
||||
//
|
||||
typedef struct {
|
||||
//
|
||||
// intermediate input data for SMBIOS record
|
||||
//
|
||||
VOID *RecordData;
|
||||
SMBIOS_MISC_DATA_FUNCTION *Function;
|
||||
} SMBIOS_MISC_DATA_TABLE;
|
||||
|
||||
|
||||
//
|
||||
// SMBIOS table extern definitions
|
||||
//
|
||||
#define SMBIOS_MISC_TABLE_EXTERNS(NAME1, NAME2, NAME3) \
|
||||
extern NAME1 NAME2 ## Data; \
|
||||
extern SMBIOS_MISC_DATA_FUNCTION NAME3 ## Function;
|
||||
|
||||
|
||||
//
|
||||
// SMBIOS data table entries
|
||||
//
|
||||
// This is used to define a pair of table structure pointer and functions
|
||||
// in order to iterate through the list of tables, populate them and add
|
||||
// them into the system.
|
||||
#define SMBIOS_MISC_TABLE_ENTRY_DATA_AND_FUNCTION(NAME1, NAME2) \
|
||||
{ \
|
||||
& NAME1 ## Data, \
|
||||
NAME2 ## Function \
|
||||
}
|
||||
|
||||
//
|
||||
// Global definition macros.
|
||||
//
|
||||
#define SMBIOS_MISC_TABLE_DATA(NAME1, NAME2) \
|
||||
NAME1 NAME2 ## Data
|
||||
|
||||
#define SMBIOS_MISC_TABLE_FUNCTION(NAME2) \
|
||||
EFI_STATUS EFIAPI NAME2 ## Function( \
|
||||
IN VOID *RecordData, \
|
||||
IN EFI_SMBIOS_PROTOCOL *Smbios \
|
||||
)
|
||||
|
||||
//
|
||||
// Data Table Array Entries
|
||||
//
|
||||
extern EFI_HII_HANDLE mSmbiosMiscHiiHandle;
|
||||
|
||||
typedef struct _SMBIOS_TYPE13_BIOS_LANGUAGE_INFORMATION_STRING{
|
||||
UINT8 *LanguageSignature;
|
||||
EFI_STRING_ID InstallableLanguageLongString;
|
||||
EFI_STRING_ID InstallableLanguageAbbreviateString;
|
||||
} SMBIOS_TYPE13_BIOS_LANGUAGE_INFORMATION_STRING;
|
||||
|
||||
|
||||
/**
|
||||
Adds an SMBIOS record.
|
||||
|
||||
@param Buffer The data for the SMBIOS record.
|
||||
The format of the record is determined by
|
||||
EFI_SMBIOS_TABLE_HEADER.Type. The size of the
|
||||
formatted area is defined by EFI_SMBIOS_TABLE_HEADER.Length
|
||||
and either followed by a double-null (0x0000) or a set
|
||||
of null terminated strings and a null.
|
||||
@param SmbiosHandle A unique handle will be assigned to the SMBIOS record
|
||||
if not NULL.
|
||||
|
||||
@retval EFI_SUCCESS Record was added.
|
||||
@retval EFI_OUT_OF_RESOURCES Record was not added due to lack of system resources.
|
||||
@retval EFI_ALREADY_STARTED The SmbiosHandle passed in was already in use.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
SmbiosMiscAddRecord (
|
||||
IN UINT8 *Buffer,
|
||||
IN OUT EFI_SMBIOS_HANDLE *SmbiosHandle OPTIONAL
|
||||
);
|
||||
|
||||
/**
|
||||
Get Link Type Handle.
|
||||
|
||||
@param [in] SmbiosType Get this Type from SMBIOS table
|
||||
@param [out] HandleArray Pointer to handle array which will be freed by caller
|
||||
@param [out] HandleCount Pointer to handle count
|
||||
|
||||
**/
|
||||
VOID
|
||||
SmbiosMiscGetLinkTypeHandle(
|
||||
IN UINT8 SmbiosType,
|
||||
OUT UINT16 **HandleArray,
|
||||
OUT UINTN *HandleCount
|
||||
);
|
||||
|
||||
//
|
||||
// Data Table Array
|
||||
//
|
||||
extern SMBIOS_MISC_DATA_TABLE mSmbiosMiscDataTable[];
|
||||
|
||||
//
|
||||
// Data Table Array Entries
|
||||
//
|
||||
extern UINTN mSmbiosMiscDataTableEntries;
|
||||
extern UINT8 mSmbiosMiscDxeStrings[];
|
||||
|
||||
#endif // SMBIOS_MISC_H_
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user