mirror of
https://github.com/PCSX2/pcsx2.git
synced 2026-01-31 01:15:24 +01:00
Compare commits
2003 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d1daf21a3f | ||
|
|
98c83c8509 | ||
|
|
b25731f621 | ||
|
|
563f5ec713 | ||
|
|
ad25ae43d5 | ||
|
|
b058e72fdd | ||
|
|
38ee8ccfe3 | ||
|
|
53161f76a6 | ||
|
|
742a929966 | ||
|
|
63b3646e73 | ||
|
|
794c73a613 | ||
|
|
59fc2a4c15 | ||
|
|
6a144f86cf | ||
|
|
f218e11d78 | ||
|
|
f6bcd8a2c2 | ||
|
|
bf0cd5a6cd | ||
|
|
fc1504f2e5 | ||
|
|
7b4d545dca | ||
|
|
89f27d0b2d | ||
|
|
3728f42185 | ||
|
|
2d6c4c6aee | ||
|
|
83b8ec6a99 | ||
|
|
5e87f6d806 | ||
|
|
f2da932777 | ||
|
|
4b3e6d7a58 | ||
|
|
c50d671bdb | ||
|
|
5290cbea94 | ||
|
|
f6b55a4e19 | ||
|
|
4e0d2207a3 | ||
|
|
f089d5714f | ||
|
|
be26c04dd1 | ||
|
|
cbcfe37e28 | ||
|
|
ef0fde8615 | ||
|
|
cc728642ed | ||
|
|
d9360a66af | ||
|
|
4040f7afca | ||
|
|
758c347258 | ||
|
|
cf76a605d2 | ||
|
|
1cfcfc465e | ||
|
|
fc611dee57 | ||
|
|
de8b23db4e | ||
|
|
b036dcece6 | ||
|
|
94c83245db | ||
|
|
c14146926a | ||
|
|
29dffd06b3 | ||
|
|
9646d18624 | ||
|
|
170d9a27ff | ||
|
|
4d43374b31 | ||
|
|
085332da27 | ||
|
|
4dae3ee33b | ||
|
|
dd729ec649 | ||
|
|
9ef582bd6f | ||
|
|
a4fec6323c | ||
|
|
4e9d56441a | ||
|
|
af71ae9dd9 | ||
|
|
305563e44f | ||
|
|
f042fd2e88 | ||
|
|
5a13932dd9 | ||
|
|
06c9967971 | ||
|
|
6e8d667c6a | ||
|
|
0529ce2bc4 | ||
|
|
639552ae8f | ||
|
|
0d1cc8581a | ||
|
|
ed54b55a63 | ||
|
|
12d8a1f92e | ||
|
|
ed76e54904 | ||
|
|
c2bb936586 | ||
|
|
42b334efcd | ||
|
|
56367f257a | ||
|
|
55db243362 | ||
|
|
395f4e904c | ||
|
|
3c5a39a99a | ||
|
|
572c3be647 | ||
|
|
06e7d6c3df | ||
|
|
bcde888257 | ||
|
|
1767213321 | ||
|
|
b36b4e4ad1 | ||
|
|
8857eb4e78 | ||
|
|
fce3414c65 | ||
|
|
f0f23a2c61 | ||
|
|
a77f78f08f | ||
|
|
9269792a8c | ||
|
|
e87d507c0c | ||
|
|
5fc07180dd | ||
|
|
a35990ee4c | ||
|
|
7d71954674 | ||
|
|
1cee55bf45 | ||
|
|
c11ca2ff64 | ||
|
|
f88756cb53 | ||
|
|
54d284cdac | ||
|
|
011d6bebfa | ||
|
|
447dc54710 | ||
|
|
e2ff6327eb | ||
|
|
a293b6fc77 | ||
|
|
e56ffc689d | ||
|
|
4cca6a72d8 | ||
|
|
6e79b29678 | ||
|
|
a432ffc0ce | ||
|
|
205cb2c29d | ||
|
|
1594b46f68 | ||
|
|
e1e7791dff | ||
|
|
d3accbc085 | ||
|
|
69cc5a559e | ||
|
|
9f8f2f6730 | ||
|
|
498eb9330b | ||
|
|
6047322f0c | ||
|
|
2ce6a031a4 | ||
|
|
323bab7d4a | ||
|
|
73f45b8772 | ||
|
|
a9407f055c | ||
|
|
2eb1134828 | ||
|
|
7e35571b94 | ||
|
|
19f7e3631a | ||
|
|
094f2da774 | ||
|
|
1b9d22a491 | ||
|
|
df1e19dd47 | ||
|
|
8c4fa838fe | ||
|
|
2f6df2f9af | ||
|
|
446b0c2dfa | ||
|
|
0eb963d491 | ||
|
|
156484ac80 | ||
|
|
6511d4c21c | ||
|
|
e2a8c70f3d | ||
|
|
53386e4d42 | ||
|
|
d82d25cc10 | ||
|
|
d79b4b2352 | ||
|
|
a206187802 | ||
|
|
e48e810005 | ||
|
|
fbac3ebad1 | ||
|
|
c88a042c8b | ||
|
|
a78d76d143 | ||
|
|
33ea0af06f | ||
|
|
55a15f5a21 | ||
|
|
3dd5a32cc0 | ||
|
|
0df86c6aaf | ||
|
|
383ff6c234 | ||
|
|
2cf920a1d4 | ||
|
|
dc8bb7cc2f | ||
|
|
cfe51035fb | ||
|
|
a2afbd3080 | ||
|
|
dcb17243f8 | ||
|
|
6e706b3a8c | ||
|
|
f5e3d79cc7 | ||
|
|
1febfa4f4e | ||
|
|
9601d0fc45 | ||
|
|
9f8f0262c7 | ||
|
|
e718a4f843 | ||
|
|
2257103ee6 | ||
|
|
9e58aafa4a | ||
|
|
a13096bdfe | ||
|
|
53c3958b2b | ||
|
|
bbc0bcae1e | ||
|
|
2b52bf4539 | ||
|
|
40f315a259 | ||
|
|
f191915b53 | ||
|
|
cb0e79972d | ||
|
|
2a980d9fc0 | ||
|
|
6daeb56550 | ||
|
|
65ae3e1d8d | ||
|
|
403b93daf6 | ||
|
|
ff0380b456 | ||
|
|
e7bb6c8767 | ||
|
|
f9c7b4e441 | ||
|
|
0540b8e1ad | ||
|
|
fcde6f686e | ||
|
|
444dce4aeb | ||
|
|
1a0b8fb37f | ||
|
|
4fcc8abf55 | ||
|
|
131b92e9fe | ||
|
|
5391b529b6 | ||
|
|
92aea38230 | ||
|
|
590ca98463 | ||
|
|
16936aa452 | ||
|
|
dedb1e0c80 | ||
|
|
63163737c2 | ||
|
|
9f99e88c92 | ||
|
|
b6f748ad8f | ||
|
|
1f3f70a642 | ||
|
|
edfb59a87d | ||
|
|
999b01c814 | ||
|
|
e7f52cbf98 | ||
|
|
311d1c805d | ||
|
|
2908c97432 | ||
|
|
122423e535 | ||
|
|
639865f3e2 | ||
|
|
42e214eb17 | ||
|
|
73c29d44c3 | ||
|
|
ab6148f0b4 | ||
|
|
bf0243c253 | ||
|
|
b53c9daf50 | ||
|
|
7fa482e5c6 | ||
|
|
391bd119b8 | ||
|
|
cdd9b1fa3b | ||
|
|
99487d0e2b | ||
|
|
5ff98258df | ||
|
|
41bc4832f3 | ||
|
|
69dbb2e17c | ||
|
|
3dbaf96a9a | ||
|
|
15d8b891d6 | ||
|
|
efc09a7b47 | ||
|
|
6e84e5ce9c | ||
|
|
7d5d2b86cf | ||
|
|
e887600c7e | ||
|
|
8216faae6e | ||
|
|
8c1b9e1557 | ||
|
|
57595c70b0 | ||
|
|
cf568d2782 | ||
|
|
ba07e46cf8 | ||
|
|
f19ba1b0db | ||
|
|
51887f1cbc | ||
|
|
539e285f86 | ||
|
|
75d57640eb | ||
|
|
56316ffcca | ||
|
|
580dbd0905 | ||
|
|
42a394628e | ||
|
|
0233845994 | ||
|
|
f42647426b | ||
|
|
b54521de51 | ||
|
|
d7e09167fa | ||
|
|
26d20e458c | ||
|
|
3099d55b40 | ||
|
|
72218929b9 | ||
|
|
f99106ccb1 | ||
|
|
dd6f9c5ad3 | ||
|
|
7d2209860e | ||
|
|
c82a927556 | ||
|
|
59e9d80b18 | ||
|
|
732d30c919 | ||
|
|
8586490162 | ||
|
|
f8a3cf2d3d | ||
|
|
826ca5ece5 | ||
|
|
73a3542ab2 | ||
|
|
dfbe243b4c | ||
|
|
f7d76ebf1d | ||
|
|
34c36c09ff | ||
|
|
765dab5d8d | ||
|
|
063d02a9cb | ||
|
|
6e5e9ab7bc | ||
|
|
c8c7ac45d1 | ||
|
|
14181ec70d | ||
|
|
b20e5a1e01 | ||
|
|
64d222a1e4 | ||
|
|
e4554fe9ca | ||
|
|
8ec736789c | ||
|
|
9a323a9a8d | ||
|
|
298e626b6e | ||
|
|
af7308e395 | ||
|
|
7c80fcacba | ||
|
|
beb23efa88 | ||
|
|
1b65f5f164 | ||
|
|
bb336f1bc7 | ||
|
|
36d386b451 | ||
|
|
9199f48a3c | ||
|
|
5c88c585a0 | ||
|
|
771b1490d2 | ||
|
|
4bbdbf6332 | ||
|
|
7dc10fbe46 | ||
|
|
90ca83bd96 | ||
|
|
4ee92fc637 | ||
|
|
1d39488061 | ||
|
|
d87cd32ff4 | ||
|
|
2a50ae905d | ||
|
|
f536584d7a | ||
|
|
fa3bd58b7f | ||
|
|
1f5d2c49fc | ||
|
|
3e585c3438 | ||
|
|
c23e792f68 | ||
|
|
02d3c93c2c | ||
|
|
a07ef0f5ee | ||
|
|
e415251f30 | ||
|
|
ddbc143178 | ||
|
|
d54715a9c3 | ||
|
|
eb9507707d | ||
|
|
3377de1fe3 | ||
|
|
b5807e0788 | ||
|
|
c86e82039a | ||
|
|
999b2267c0 | ||
|
|
fbf9585b5a | ||
|
|
470365644f | ||
|
|
7b3847cc5c | ||
|
|
2b0e1a1dec | ||
|
|
316e140329 | ||
|
|
02c4c3b03d | ||
|
|
e5405e191b | ||
|
|
839ea61d55 | ||
|
|
02f27f8cbc | ||
|
|
35b5138593 | ||
|
|
809c5ed051 | ||
|
|
412451f9d6 | ||
|
|
35802f2089 | ||
|
|
8f6f0f8401 | ||
|
|
44d95badc4 | ||
|
|
d622faba17 | ||
|
|
b5945d3d5c | ||
|
|
52cd6fb1dd | ||
|
|
04681babf1 | ||
|
|
e63c068720 | ||
|
|
fb5b465a4e | ||
|
|
59ea3c7949 | ||
|
|
6f5306dbdc | ||
|
|
b5388fdf2f | ||
|
|
d2904c1fd5 | ||
|
|
7718feedd5 | ||
|
|
56add277f9 | ||
|
|
86f772ad38 | ||
|
|
24c99551c7 | ||
|
|
9441d2a33a | ||
|
|
3922091a58 | ||
|
|
1107ce8fd8 | ||
|
|
3d10cd1adf | ||
|
|
02ac3943f2 | ||
|
|
44b672b6f5 | ||
|
|
0239d8350d | ||
|
|
bada5fe941 | ||
|
|
6db871958e | ||
|
|
0b557fe265 | ||
|
|
ce08627396 | ||
|
|
200ec5dcfb | ||
|
|
8a6f55a63e | ||
|
|
e327f5e6f0 | ||
|
|
5849726913 | ||
|
|
e063613a7f | ||
|
|
48d2cb4975 | ||
|
|
59412b1673 | ||
|
|
d1a235272e | ||
|
|
7db9627ff6 | ||
|
|
83550cd153 | ||
|
|
77471bd9d6 | ||
|
|
0e94211ff1 | ||
|
|
f6e7bba354 | ||
|
|
b2255e5b27 | ||
|
|
7b493ff4c8 | ||
|
|
aeef163349 | ||
|
|
26f2352059 | ||
|
|
67e38d8de2 | ||
|
|
2c3a4cbabf | ||
|
|
fed3ea597c | ||
|
|
547b2fc9e8 | ||
|
|
cf07f4aef1 | ||
|
|
3dc4aea053 | ||
|
|
afa29facc6 | ||
|
|
8c0120bdbb | ||
|
|
a3e72c5b43 | ||
|
|
33efc86788 | ||
|
|
ec6be34c31 | ||
|
|
fd49a1e80a | ||
|
|
d1d6855d58 | ||
|
|
504b9e7051 | ||
|
|
9cb64fd087 | ||
|
|
fe9ccf55c1 | ||
|
|
4840da2c1b | ||
|
|
543fb282fe | ||
|
|
9b7ae498d2 | ||
|
|
5668bcf19b | ||
|
|
66c25b3cb6 | ||
|
|
e234fb32d9 | ||
|
|
f70c67ad7f | ||
|
|
cf3cfdb2bc | ||
|
|
394f1f2049 | ||
|
|
a9819542d4 | ||
|
|
d0e3b8c4ee | ||
|
|
e3681cf993 | ||
|
|
26c717a1bf | ||
|
|
6efdbf2950 | ||
|
|
b45b082c06 | ||
|
|
da21a649c0 | ||
|
|
347736f2b4 | ||
|
|
a6649b2d6b | ||
|
|
33a78c1919 | ||
|
|
3b4b669038 | ||
|
|
26b666abcd | ||
|
|
32e2a8ba2c | ||
|
|
fdc399b44c | ||
|
|
ec43661664 | ||
|
|
a05a655037 | ||
|
|
ca3833e71b | ||
|
|
3910b047d4 | ||
|
|
15c1381c1e | ||
|
|
c0e65d9a36 | ||
|
|
38ff490b60 | ||
|
|
f8fa41d4bf | ||
|
|
b74c65cc7c | ||
|
|
624e5ae633 | ||
|
|
71935e7099 | ||
|
|
bb9a551318 | ||
|
|
457ec7f6f5 | ||
|
|
433b88c0bf | ||
|
|
9f8911536a | ||
|
|
eeb09c54d8 | ||
|
|
52a3777aae | ||
|
|
ea1f451d35 | ||
|
|
28795e549b | ||
|
|
0a667bf18a | ||
|
|
2d8a4e13e6 | ||
|
|
f1702b5693 | ||
|
|
b89d0837a6 | ||
|
|
cba6a6ec51 | ||
|
|
d74623faf9 | ||
|
|
db4bf08475 | ||
|
|
f9c2327bf5 | ||
|
|
beab9870cf | ||
|
|
dbfb93a50f | ||
|
|
6b66cd7f29 | ||
|
|
08089e0654 | ||
|
|
b2ef973f16 | ||
|
|
d862f8cd53 | ||
|
|
9c61e9eda3 | ||
|
|
dc000e08ab | ||
|
|
5469d59de9 | ||
|
|
37f640ece2 | ||
|
|
906898c785 | ||
|
|
30f6c5f8f1 | ||
|
|
1a2059c0f1 | ||
|
|
4fb0050411 | ||
|
|
5708fb1668 | ||
|
|
870604d64c | ||
|
|
9f4bf4267d | ||
|
|
5c15d57f5f | ||
|
|
6e1f76185e | ||
|
|
7fe5ba480c | ||
|
|
2333ff7b2d | ||
|
|
5063961748 | ||
|
|
815c0a394d | ||
|
|
6d3f42a441 | ||
|
|
4b76594d8d | ||
|
|
f5144f33da | ||
|
|
03f7e9e15a | ||
|
|
a8baa4b67c | ||
|
|
f40bebed3b | ||
|
|
5a036e572b | ||
|
|
cd31f5fceb | ||
|
|
f812174270 | ||
|
|
aeaeb8ba94 | ||
|
|
2adeb401ff | ||
|
|
52325cb7dd | ||
|
|
6265bbf99a | ||
|
|
8c0c9a5e29 | ||
|
|
8638c73a4e | ||
|
|
d2d4038357 | ||
|
|
f8fdbaf566 | ||
|
|
0b2536dd3e | ||
|
|
b2b7d8d64e | ||
|
|
67c34794e8 | ||
|
|
30f0cdde6f | ||
|
|
71637cc282 | ||
|
|
56402db7ee | ||
|
|
3e76d380a1 | ||
|
|
4873165dbc | ||
|
|
277706505e | ||
|
|
9f09aa725b | ||
|
|
06fee385e1 | ||
|
|
dc4ef1163f | ||
|
|
2928837b76 | ||
|
|
a5124b118b | ||
|
|
e7db878188 | ||
|
|
0b164a7989 | ||
|
|
a4088685a0 | ||
|
|
fc06963c56 | ||
|
|
9680e7460c | ||
|
|
271e53a6bf | ||
|
|
3888483fb4 | ||
|
|
d67e72912c | ||
|
|
b843989719 | ||
|
|
7717450044 | ||
|
|
98947c10bb | ||
|
|
6aa7266084 | ||
|
|
bd5656bf89 | ||
|
|
1e4795e653 | ||
|
|
c8e0090870 | ||
|
|
2dd9d8338b | ||
|
|
8d3c82de19 | ||
|
|
3bff10e17d | ||
|
|
6562a5191a | ||
|
|
5ef159876a | ||
|
|
1bb86d8984 | ||
|
|
edd735ce80 | ||
|
|
4fd06b5ea8 | ||
|
|
f6d997ca87 | ||
|
|
5963efcec8 | ||
|
|
f8fbfee49d | ||
|
|
4d7ee63d77 | ||
|
|
21b97f68fa | ||
|
|
95c91b4dc6 | ||
|
|
ca1b35a351 | ||
|
|
84177d38d4 | ||
|
|
e21589da86 | ||
|
|
0768971f35 | ||
|
|
6c42a7f6e4 | ||
|
|
a65f3bd116 | ||
|
|
822e508d13 | ||
|
|
1611aeedce | ||
|
|
7c243756bc | ||
|
|
43b53df0a0 | ||
|
|
66c6c2400a | ||
|
|
30096a5ae4 | ||
|
|
c70afc24bd | ||
|
|
ce53b7adb1 | ||
|
|
25fa70fe9e | ||
|
|
724957fbec | ||
|
|
9084ef35b4 | ||
|
|
e58b1054ea | ||
|
|
24de0866f7 | ||
|
|
0cec99361b | ||
|
|
8ba745030a | ||
|
|
4ddf897719 | ||
|
|
9be7eb67d8 | ||
|
|
56bba522ac | ||
|
|
b6c1b3fb96 | ||
|
|
82de13d95a | ||
|
|
92dd6fb575 | ||
|
|
ced58a047d | ||
|
|
2d98b877a2 | ||
|
|
a26b91291c | ||
|
|
46a649afc1 | ||
|
|
3ce242886b | ||
|
|
3b5538a09c | ||
|
|
796519f6a7 | ||
|
|
2365a9caab | ||
|
|
425b5d0478 | ||
|
|
628560850a | ||
|
|
69f058e532 | ||
|
|
c66b660c10 | ||
|
|
4fdb3322cc | ||
|
|
73122400e3 | ||
|
|
d1cdfafe22 | ||
|
|
91e8a2cf0e | ||
|
|
b5721a92e9 | ||
|
|
cefe4b773c | ||
|
|
332346449f | ||
|
|
2c199e7c42 | ||
|
|
2a32864856 | ||
|
|
9481bbd2ef | ||
|
|
08aad5461e | ||
|
|
0bab9474ae | ||
|
|
1f802eca46 | ||
|
|
a02df6c980 | ||
|
|
e0194b2b95 | ||
|
|
74f4886ea6 | ||
|
|
d9119921de | ||
|
|
4a12ec6fc0 | ||
|
|
0c855cdd6d | ||
|
|
89d44a5f60 | ||
|
|
aa47018197 | ||
|
|
d5cd2446e4 | ||
|
|
eb386fb0fb | ||
|
|
cb24b84bff | ||
|
|
d65522a9b4 | ||
|
|
fa91d0b705 | ||
|
|
ae43cfaaf2 | ||
|
|
8bbcb05303 | ||
|
|
f2713462cc | ||
|
|
ac9d406862 | ||
|
|
74738022da | ||
|
|
aae8d5d639 | ||
|
|
372ee9b6b6 | ||
|
|
943e21f507 | ||
|
|
b6308bab4f | ||
|
|
6a4df2a641 | ||
|
|
a92eb4d10a | ||
|
|
c03e52c06f | ||
|
|
66e663757a | ||
|
|
d279f61d0b | ||
|
|
b59d4791cf | ||
|
|
680a3802d7 | ||
|
|
c3ee97103f | ||
|
|
489fbe628a | ||
|
|
9ba42ec950 | ||
|
|
b54facdbd8 | ||
|
|
5c790b8540 | ||
|
|
ef32b49e50 | ||
|
|
8fb09d07ed | ||
|
|
710d3360ac | ||
|
|
ded036b93e | ||
|
|
364e6a1341 | ||
|
|
2aec91d8c0 | ||
|
|
4f0c880e3e | ||
|
|
13d623f350 | ||
|
|
9aecf79d7f | ||
|
|
2e8076d909 | ||
|
|
655939147a | ||
|
|
bf899022d7 | ||
|
|
ed5aa4a67d | ||
|
|
22bf3549b6 | ||
|
|
f260a8be66 | ||
|
|
068ab8ab36 | ||
|
|
6fde585504 | ||
|
|
c45cc6928d | ||
|
|
110b7df4d5 | ||
|
|
73eea20fcc | ||
|
|
4f20a68b33 | ||
|
|
dafef46a1b | ||
|
|
e283831841 | ||
|
|
d13c7b6b3e | ||
|
|
e7d1477a7e | ||
|
|
2810f6afc1 | ||
|
|
821811cf0c | ||
|
|
fea666bd1e | ||
|
|
193254de94 | ||
|
|
b919719aeb | ||
|
|
ea051c6d5f | ||
|
|
893b3c629d | ||
|
|
c07c942659 | ||
|
|
b1d6d84e6f | ||
|
|
1afb248e4d | ||
|
|
cad85d76a5 | ||
|
|
29ad851a9c | ||
|
|
cb9eaeeff9 | ||
|
|
7c9493cbc2 | ||
|
|
d21c01f8d1 | ||
|
|
f4f06c9777 | ||
|
|
437b6f3f0e | ||
|
|
a163c90f2b | ||
|
|
9d9d22fcba | ||
|
|
df5e175b86 | ||
|
|
0f8bbfd64c | ||
|
|
8c270288de | ||
|
|
7bd7cdd867 | ||
|
|
f618713551 | ||
|
|
de329e49a8 | ||
|
|
2aa6f771a9 | ||
|
|
7787fcff8e | ||
|
|
6e576d208e | ||
|
|
00751dc5d3 | ||
|
|
e456fb8f88 | ||
|
|
9dd579a6d5 | ||
|
|
fbd36a4347 | ||
|
|
7f8bfb22de | ||
|
|
943b513a52 | ||
|
|
221eaf1a81 | ||
|
|
41f1ec445f | ||
|
|
a289723f66 | ||
|
|
a3f6efecb8 | ||
|
|
2587cf3b95 | ||
|
|
d535331b4b | ||
|
|
6d85399ec5 | ||
|
|
7a113474f0 | ||
|
|
0bb7cc0a1a | ||
|
|
322ff3fcb9 | ||
|
|
d329cabf07 | ||
|
|
38c48e8b6a | ||
|
|
cd0b349496 | ||
|
|
7f1932e282 | ||
|
|
17f2fb4471 | ||
|
|
022a9cc6df | ||
|
|
c88db3221c | ||
|
|
bd3e1299a3 | ||
|
|
3a97688804 | ||
|
|
3f027b2698 | ||
|
|
916754ea6d | ||
|
|
335633a5e0 | ||
|
|
925bfc2a99 | ||
|
|
d19c767ad1 | ||
|
|
d2347d9972 | ||
|
|
f8dcff9fc4 | ||
|
|
e5716922a3 | ||
|
|
65e956a01c | ||
|
|
a93829557b | ||
|
|
c21d475bbd | ||
|
|
935dd046da | ||
|
|
1b2d9f0c5d | ||
|
|
4baea67e75 | ||
|
|
1e8332f36a | ||
|
|
096696bed7 | ||
|
|
756cd1ee47 | ||
|
|
64534542a9 | ||
|
|
b22e31c302 | ||
|
|
008beb4896 | ||
|
|
576bcc6979 | ||
|
|
4ec345a239 | ||
|
|
972bfbcccc | ||
|
|
f59fbaf0eb | ||
|
|
631ed8c0fd | ||
|
|
41e8a2a7d1 | ||
|
|
599626b709 | ||
|
|
0ae17ddb1a | ||
|
|
7353c26a4f | ||
|
|
b8769e954e | ||
|
|
81cd2d9be9 | ||
|
|
90707c453d | ||
|
|
ec0e9f078c | ||
|
|
98b537575f | ||
|
|
233195b020 | ||
|
|
7d71e28bfc | ||
|
|
13e09953af | ||
|
|
a85ca4108c | ||
|
|
8620febeb3 | ||
|
|
af4c047c41 | ||
|
|
bec9b34f54 | ||
|
|
9989daec94 | ||
|
|
c86dd7397d | ||
|
|
eefc81ed8c | ||
|
|
91c717376f | ||
|
|
344c918b65 | ||
|
|
deeda519b0 | ||
|
|
2db12b9d84 | ||
|
|
378588c67d | ||
|
|
119b6bdfd5 | ||
|
|
8751a2d330 | ||
|
|
4543ddbcc2 | ||
|
|
77a7b18b29 | ||
|
|
749aef1a64 | ||
|
|
8091b6bc1b | ||
|
|
4efa845580 | ||
|
|
8c9ae90753 | ||
|
|
d1117aafac | ||
|
|
a565182b2b | ||
|
|
650b0ae646 | ||
|
|
b677619f32 | ||
|
|
2fa8f09a21 | ||
|
|
73c9279907 | ||
|
|
7d8912f170 | ||
|
|
2601ba53d4 | ||
|
|
81baaaa98a | ||
|
|
c2638131b4 | ||
|
|
586486b81c | ||
|
|
af75ac00e2 | ||
|
|
67b66c1780 | ||
|
|
b3dce680b0 | ||
|
|
d01a59650f | ||
|
|
5ae987d48e | ||
|
|
6a6ecbf826 | ||
|
|
4bdf180145 | ||
|
|
6ebb8c2e91 | ||
|
|
5eae7a6328 | ||
|
|
7d81c979fe | ||
|
|
c06ac00677 | ||
|
|
85c754b456 | ||
|
|
35d3547b62 | ||
|
|
8661f42fce | ||
|
|
a28098c4f8 | ||
|
|
d45f34ee8b | ||
|
|
d552f8dc43 | ||
|
|
b45360b49e | ||
|
|
fffdf8d671 | ||
|
|
2634134481 | ||
|
|
c0ac71611b | ||
|
|
63ecdfefe3 | ||
|
|
6345e8e467 | ||
|
|
e96545ca29 | ||
|
|
dc08858e0f | ||
|
|
f5787f9ba0 | ||
|
|
a271fe11e9 | ||
|
|
a20a3866d0 | ||
|
|
28d25fdf33 | ||
|
|
f13ad4fcb3 | ||
|
|
a524410b0a | ||
|
|
8e23d8d557 | ||
|
|
59531f005e | ||
|
|
4c8cba53ef | ||
|
|
34cd53249d | ||
|
|
14ce344a3f | ||
|
|
cc5142000b | ||
|
|
1ad6532f1a | ||
|
|
f136a1a970 | ||
|
|
a959ec7571 | ||
|
|
e1a6304e32 | ||
|
|
be05c95026 | ||
|
|
3983e542b2 | ||
|
|
3d76652b5f | ||
|
|
6532dbced4 | ||
|
|
fe27ebefc8 | ||
|
|
6e84613a14 | ||
|
|
568ebc6199 | ||
|
|
cf1d67d927 | ||
|
|
8181cc8528 | ||
|
|
b344ee094f | ||
|
|
b042aeacf5 | ||
|
|
fea58d2271 | ||
|
|
ca5da27170 | ||
|
|
11eab828c4 | ||
|
|
8ca3f9a9c2 | ||
|
|
deb044357b | ||
|
|
00c07d2dff | ||
|
|
185ed3ce0b | ||
|
|
3b043250b6 | ||
|
|
3359b3c7ab | ||
|
|
6b1e483d28 | ||
|
|
d3faa05479 | ||
|
|
73f17be890 | ||
|
|
9292ceedb1 | ||
|
|
d1470a9935 | ||
|
|
38fa137cfd | ||
|
|
a7288d8ad8 | ||
|
|
0692517f13 | ||
|
|
4f44e3fc46 | ||
|
|
14398da51f | ||
|
|
6e8897d62b | ||
|
|
69da1e4559 | ||
|
|
abde47fa18 | ||
|
|
f46b406cbd | ||
|
|
48313b42a2 | ||
|
|
1e06b57f25 | ||
|
|
8a6c896dde | ||
|
|
b3c7b07813 | ||
|
|
65072ddbe5 | ||
|
|
d42fb851a2 | ||
|
|
ea0791a3bf | ||
|
|
8d4df7f74b | ||
|
|
4b07eae80e | ||
|
|
77162ff637 | ||
|
|
e10f414724 | ||
|
|
53c3f253e6 | ||
|
|
b0f20c9973 | ||
|
|
5c3ae656a0 | ||
|
|
a98efdfedd | ||
|
|
3b8eb6731c | ||
|
|
89bc4707ab | ||
|
|
e5a8b01980 | ||
|
|
7194542029 | ||
|
|
06beadba74 | ||
|
|
b10249af7d | ||
|
|
1f04214461 | ||
|
|
39d611e870 | ||
|
|
b913d39a50 | ||
|
|
eb60e9aa9b | ||
|
|
53bb0c508f | ||
|
|
1c50d3e4b3 | ||
|
|
de724d9570 | ||
|
|
e8293b2e06 | ||
|
|
904345ff82 | ||
|
|
d16592817b | ||
|
|
14f1a78608 | ||
|
|
68c2a68087 | ||
|
|
ae83f729db | ||
|
|
c53f4d0d63 | ||
|
|
cbb3134740 | ||
|
|
9b97c157f2 | ||
|
|
11cf244e97 | ||
|
|
6673bd9212 | ||
|
|
02dfc5d20d | ||
|
|
565ff86ab4 | ||
|
|
5a77790859 | ||
|
|
66101f8628 | ||
|
|
2f70b153f2 | ||
|
|
31fe9979dd | ||
|
|
4fc6e9240c | ||
|
|
0eae59ee66 | ||
|
|
8e6cd47f25 | ||
|
|
ecdbe17fba | ||
|
|
0e9dcf74b2 | ||
|
|
5297c2a995 | ||
|
|
edf5e2c14e | ||
|
|
9180adb850 | ||
|
|
1b080f1777 | ||
|
|
0a2584172a | ||
|
|
1993203d26 | ||
|
|
3c18cdcb1f | ||
|
|
e767fb8d35 | ||
|
|
3255422836 | ||
|
|
67fa06b933 | ||
|
|
398e468c9e | ||
|
|
f7ee35e578 | ||
|
|
800b458d3d | ||
|
|
3f31a4d25b | ||
|
|
0592abd31b | ||
|
|
55d546b892 | ||
|
|
f28e42c4fe | ||
|
|
7cdc849ffa | ||
|
|
eed04b3ff3 | ||
|
|
e2044eba66 | ||
|
|
06e6d12e2f | ||
|
|
48fd68ca87 | ||
|
|
7ad59a7af1 | ||
|
|
bae2c9c1d8 | ||
|
|
3d171686b5 | ||
|
|
f86b3a32cd | ||
|
|
59d6113ee4 | ||
|
|
f270f34865 | ||
|
|
b2514d49d2 | ||
|
|
2951068e0c | ||
|
|
a4dcaa7c14 | ||
|
|
b90de6d89f | ||
|
|
532a7addd4 | ||
|
|
5389178644 | ||
|
|
6cbdc8c8b7 | ||
|
|
6e6a70b8ed | ||
|
|
1a0a0423e7 | ||
|
|
b28779b0f6 | ||
|
|
63fd349e3c | ||
|
|
481c92c1c8 | ||
|
|
d733730950 | ||
|
|
93a9e5dd83 | ||
|
|
db9672509c | ||
|
|
ffe69d313b | ||
|
|
502a44e9f5 | ||
|
|
5e913b0e9e | ||
|
|
864651ce8d | ||
|
|
850deed6c1 | ||
|
|
63424b765d | ||
|
|
a635e84d82 | ||
|
|
6991f819f3 | ||
|
|
a22c634cd4 | ||
|
|
80aaa962ec | ||
|
|
876ea3db52 | ||
|
|
1bfc0f3138 | ||
|
|
5fa9427323 | ||
|
|
29cea58471 | ||
|
|
4779bc830a | ||
|
|
dd8a645986 | ||
|
|
9aa2c52b20 | ||
|
|
0914b2a474 | ||
|
|
d387a1f4dc | ||
|
|
3488aa54be | ||
|
|
de541aeba9 | ||
|
|
5fb00bd6c7 | ||
|
|
fdabc82342 | ||
|
|
e5f90f176c | ||
|
|
6438547edc | ||
|
|
0f0ab25fe8 | ||
|
|
fc7a20dd0f | ||
|
|
f8c7237bba | ||
|
|
00af7d6835 | ||
|
|
86fb8e5809 | ||
|
|
29964c3f26 | ||
|
|
ec787d090d | ||
|
|
f9707e6809 | ||
|
|
5665e5e222 | ||
|
|
336e5c77fe | ||
|
|
d8b107f59c | ||
|
|
19197fabe8 | ||
|
|
3801825793 | ||
|
|
25e15a16b1 | ||
|
|
5ac9419703 | ||
|
|
821e15f1ee | ||
|
|
0efe03e726 | ||
|
|
577d6e735c | ||
|
|
7668123aaa | ||
|
|
0b87d580c3 | ||
|
|
170a03cac6 | ||
|
|
70d8acb812 | ||
|
|
2670d5a9aa | ||
|
|
44081671ac | ||
|
|
462b304bea | ||
|
|
059f58803c | ||
|
|
e170e9281d | ||
|
|
5987e03463 | ||
|
|
ddbdfd47be | ||
|
|
1b83e17d60 | ||
|
|
bc7ed4e7d0 | ||
|
|
283c7fa88c | ||
|
|
d01ee3163d | ||
|
|
90457e32b6 | ||
|
|
4cb6c94693 | ||
|
|
93c78a27b3 | ||
|
|
50452848e7 | ||
|
|
4f70fd9583 | ||
|
|
e6c8354ec8 | ||
|
|
a1e77002c3 | ||
|
|
099cd52381 | ||
|
|
0d1675fbaa | ||
|
|
f021da5627 | ||
|
|
906480b8e2 | ||
|
|
38b83af714 | ||
|
|
05dab12b7c | ||
|
|
c0628a64a6 | ||
|
|
5ecaa9459d | ||
|
|
24b2277206 | ||
|
|
8e60d2c72e | ||
|
|
cfe2f9e6b4 | ||
|
|
0a11b5898a | ||
|
|
be49de6fa0 | ||
|
|
1ad52e918b | ||
|
|
53388336d2 | ||
|
|
4e1496e736 | ||
|
|
216c964d13 | ||
|
|
6bb828eb8f | ||
|
|
511845a1c4 | ||
|
|
89f10e1605 | ||
|
|
76b4e93604 | ||
|
|
cec089a271 | ||
|
|
b4bd36c4b2 | ||
|
|
338eb42b04 | ||
|
|
8e42fce0aa | ||
|
|
a7900b342e | ||
|
|
506bbe1c08 | ||
|
|
d32d8cc0ec | ||
|
|
0cb9655523 | ||
|
|
3067bef82d | ||
|
|
486764be03 | ||
|
|
5e336138d0 | ||
|
|
4a5180bc0a | ||
|
|
dd28e33612 | ||
|
|
b66c0411df | ||
|
|
c59b114a1d | ||
|
|
352faeddb2 | ||
|
|
140d44d826 | ||
|
|
db220001f6 | ||
|
|
5ac9b5576a | ||
|
|
b23873e0ed | ||
|
|
284ec35699 | ||
|
|
cb0e629dd3 | ||
|
|
1aaadd6228 | ||
|
|
e20a357340 | ||
|
|
fef2952d47 | ||
|
|
f4b2e0dd7a | ||
|
|
d3aace98ac | ||
|
|
3a7f82eb66 | ||
|
|
3e24b678c4 | ||
|
|
2ab6ca06ed | ||
|
|
9ac5041b43 | ||
|
|
9262422d01 | ||
|
|
9f04becc7a | ||
|
|
8485af6cac | ||
|
|
48f7e6c63f | ||
|
|
e1fb84d6a3 | ||
|
|
5db9a738c5 | ||
|
|
145e75624d | ||
|
|
d09b49e17c | ||
|
|
fdc3ca1227 | ||
|
|
51d47a1455 | ||
|
|
9504671919 | ||
|
|
e5248db844 | ||
|
|
551d013b63 | ||
|
|
d65950cda2 | ||
|
|
15c38a0a4e | ||
|
|
74ed14496b | ||
|
|
1fa6fb0a8c | ||
|
|
3dc6ae115f | ||
|
|
fa36b9b5cb | ||
|
|
47fff9304b | ||
|
|
29c0d93864 | ||
|
|
38ff521851 | ||
|
|
34de1bffc6 | ||
|
|
8dc1592278 | ||
|
|
5b86205349 | ||
|
|
0d4fbd540e | ||
|
|
b9edabc236 | ||
|
|
180d9ae9c9 | ||
|
|
80cc2f0cb7 | ||
|
|
1927896442 | ||
|
|
bf9c1176b6 | ||
|
|
166156519a | ||
|
|
d89daa1b25 | ||
|
|
efc17f265c | ||
|
|
8427e6fd3e | ||
|
|
f1ac712eba | ||
|
|
0d4394a749 | ||
|
|
9dac598113 | ||
|
|
6db573d255 | ||
|
|
9b21f31b0d | ||
|
|
2fedecb809 | ||
|
|
b24a8c70e3 | ||
|
|
d6684efd26 | ||
|
|
644241959a | ||
|
|
273c1b1922 | ||
|
|
45682c382f | ||
|
|
4e6b86f8f4 | ||
|
|
a6b4ca69db | ||
|
|
6b32e00097 | ||
|
|
19d310475b | ||
|
|
a8b9df3952 | ||
|
|
bb75c78c1a | ||
|
|
57ea137982 | ||
|
|
9721ed0fb3 | ||
|
|
224863fbd5 | ||
|
|
1d459d8fab | ||
|
|
33e0ac729e | ||
|
|
268ecf42c3 | ||
|
|
708281f00b | ||
|
|
56b68a50e9 | ||
|
|
e4048dc2dd | ||
|
|
5949c772d1 | ||
|
|
63998b64cc | ||
|
|
fbb3ea142a | ||
|
|
435f760b5d | ||
|
|
f47129bd72 | ||
|
|
aa42acfe22 | ||
|
|
ddfe6ac5c1 | ||
|
|
624dff1b96 | ||
|
|
8d498b564d | ||
|
|
26561261bc | ||
|
|
44728be719 | ||
|
|
678bb1218b | ||
|
|
c496e80eac | ||
|
|
269db188d0 | ||
|
|
f5afbfd4f5 | ||
|
|
ccd86a242c | ||
|
|
42a5cb7ad2 | ||
|
|
6977323d88 | ||
|
|
7b1d03d45a | ||
|
|
8a4f1ef51a | ||
|
|
9b50bb2e81 | ||
|
|
4f27d779a1 | ||
|
|
73c6353351 | ||
|
|
f571b66a43 | ||
|
|
901664ba44 | ||
|
|
02012b5491 | ||
|
|
4f57e40c91 | ||
|
|
832e536a9e | ||
|
|
c2316ca5bc | ||
|
|
3535edcfa1 | ||
|
|
a4932ed0f1 | ||
|
|
515d9040a1 | ||
|
|
fe3a743814 | ||
|
|
8e08cd772b | ||
|
|
206f80c5f4 | ||
|
|
c6ce380042 | ||
|
|
939d98d660 | ||
|
|
c9a3420f85 | ||
|
|
9a1a399bac | ||
|
|
c8aac1dca9 | ||
|
|
14c17916f5 | ||
|
|
7b0576d7cc | ||
|
|
ecb118d5af | ||
|
|
efbf187b35 | ||
|
|
2ea3feba90 | ||
|
|
f265257efb | ||
|
|
13cc0caed7 | ||
|
|
2068240e1a | ||
|
|
7f5901f022 | ||
|
|
a022de6225 | ||
|
|
f5570b7f40 | ||
|
|
7e1c48694a | ||
|
|
a546f61ea8 | ||
|
|
7ecac10eee | ||
|
|
ee2e10e86b | ||
|
|
7752f44a90 | ||
|
|
e01fc3eb47 | ||
|
|
910c8190e0 | ||
|
|
a62ccc0d69 | ||
|
|
4f47041108 | ||
|
|
16cfde0538 | ||
|
|
6a15d46461 | ||
|
|
4331ae1925 | ||
|
|
4d85d916b7 | ||
|
|
4f4b14dd4d | ||
|
|
444e650711 | ||
|
|
c65ccaa153 | ||
|
|
6b54db9b75 | ||
|
|
3bab470db6 | ||
|
|
adf01cb56a | ||
|
|
bbe3af7f61 | ||
|
|
3e7d32c807 | ||
|
|
76e25cb738 | ||
|
|
8f0dc34847 | ||
|
|
fc6ec2cc02 | ||
|
|
34b7b07ff8 | ||
|
|
6c33b73cdd | ||
|
|
1e86ba4120 | ||
|
|
89c79aa6c3 | ||
|
|
4ed748fa30 | ||
|
|
5569e94f41 | ||
|
|
892eec79ed | ||
|
|
b248b4a8af | ||
|
|
39fe467b64 | ||
|
|
1c301ec889 | ||
|
|
de5690ddcb | ||
|
|
f376c8f7ae | ||
|
|
2e199d47a8 | ||
|
|
96269db93e | ||
|
|
d35db63d73 | ||
|
|
9d003486c2 | ||
|
|
0c4b85980c | ||
|
|
5961db6b9b | ||
|
|
d0039c2920 | ||
|
|
5bdec2f532 | ||
|
|
fd758bb307 | ||
|
|
a11d09ebdf | ||
|
|
d294064da6 | ||
|
|
fd4a5acc40 | ||
|
|
05a7a61257 | ||
|
|
90a4a11d49 | ||
|
|
d9f914eb7c | ||
|
|
134242973b | ||
|
|
92900d8dc8 | ||
|
|
7a970e1d00 | ||
|
|
e8e0f355fc | ||
|
|
3202fd88d2 | ||
|
|
1c66c904ab | ||
|
|
784e090081 | ||
|
|
2d08d3dc94 | ||
|
|
237b9754c6 | ||
|
|
74bbccdf59 | ||
|
|
062d625901 | ||
|
|
3f30c2bda2 | ||
|
|
0702692746 | ||
|
|
11a218b1aa | ||
|
|
f4acff1321 | ||
|
|
a8ee746c39 | ||
|
|
ddd5fc7bf3 | ||
|
|
22dfe05287 | ||
|
|
fa78e1295a | ||
|
|
4a634ca154 | ||
|
|
bd1f5d0888 | ||
|
|
2f028c5f40 | ||
|
|
56c8843406 | ||
|
|
37c4c596b5 | ||
|
|
7b0bde4f1f | ||
|
|
5c5c7d64a8 | ||
|
|
565189d08c | ||
|
|
682580e318 | ||
|
|
74e3d6470a | ||
|
|
b4e6a715fc | ||
|
|
85f0d44997 | ||
|
|
294855700d | ||
|
|
099ddfedc7 | ||
|
|
d9e2bcef6d | ||
|
|
7a628f1a12 | ||
|
|
75bc680934 | ||
|
|
0c98b5ff76 | ||
|
|
11918e5846 | ||
|
|
2c33bf8c6f | ||
|
|
e833a67bb7 | ||
|
|
6dc5087cbd | ||
|
|
eabda670ac | ||
|
|
845e7930d7 | ||
|
|
d20bfa240d | ||
|
|
ba27a46ac6 | ||
|
|
866e5bd929 | ||
|
|
1beb5517a7 | ||
|
|
a12ad1f627 | ||
|
|
c18be9dde7 | ||
|
|
4eba400170 | ||
|
|
dc376ab161 | ||
|
|
5ff49a78eb | ||
|
|
6df50992c4 | ||
|
|
5d2bcfaa38 | ||
|
|
990d7ad0f7 | ||
|
|
510283cd4d | ||
|
|
dcc183179a | ||
|
|
30bc9b04c5 | ||
|
|
8aaeb1c7ce | ||
|
|
1984c68516 | ||
|
|
c81c89d6d9 | ||
|
|
9ce2405f3f | ||
|
|
21fba45a3c | ||
|
|
a0bbdcefb3 | ||
|
|
753da789a0 | ||
|
|
cd5ce6e162 | ||
|
|
5a25cc171d | ||
|
|
32dc68f103 | ||
|
|
69a500d657 | ||
|
|
ed9f34de5f | ||
|
|
d6f1291c0b | ||
|
|
01079f5162 | ||
|
|
9b0dc287c1 | ||
|
|
bb92566781 | ||
|
|
17b1c664a8 | ||
|
|
2eaba084c7 | ||
|
|
ff75ab73cc | ||
|
|
3c54593456 | ||
|
|
39dfb2e606 | ||
|
|
4e7ade8612 | ||
|
|
664013e7ad | ||
|
|
9d51c64d92 | ||
|
|
ee82c7834d | ||
|
|
b389c6e103 | ||
|
|
b3a2d3c1e4 | ||
|
|
5d33af13ca | ||
|
|
6b2a851dec | ||
|
|
3b3072801c | ||
|
|
9ed33d4337 | ||
|
|
728b3eb5db | ||
|
|
f73398ea84 | ||
|
|
2b646c2153 | ||
|
|
f83692c0df | ||
|
|
b8236b1b1c | ||
|
|
1a3d77b2c0 | ||
|
|
816ee9e545 | ||
|
|
06766ddb98 | ||
|
|
7151848406 | ||
|
|
45b5347092 | ||
|
|
5b6986c230 | ||
|
|
de195d9b20 | ||
|
|
b47552c08f | ||
|
|
48dabd3ca2 | ||
|
|
91ac0368e3 | ||
|
|
dfe4bc199f | ||
|
|
1630404621 | ||
|
|
02c66491e8 | ||
|
|
d4b1d9abe5 | ||
|
|
6ab77be8fc | ||
|
|
6cf518e7df | ||
|
|
8f1745bf44 | ||
|
|
38f1ae34ad | ||
|
|
ad415945a6 | ||
|
|
a44fe29b8d | ||
|
|
c1d96fc876 | ||
|
|
65db50df5d | ||
|
|
f009d6f9e7 | ||
|
|
ed8bd18dfb | ||
|
|
af648334d1 | ||
|
|
8f4ce02d05 | ||
|
|
9b7e87c043 | ||
|
|
cae8e6ae79 | ||
|
|
1a2272ad43 | ||
|
|
fede91a98b | ||
|
|
7e8c6fcc9d | ||
|
|
0ca3167595 | ||
|
|
c74cc9bc12 | ||
|
|
061fff6f17 | ||
|
|
2aaabdd2ea | ||
|
|
2f06ed2af8 | ||
|
|
52252de3a6 | ||
|
|
ff725980c3 | ||
|
|
d6d420b1f7 | ||
|
|
977e8a4c54 | ||
|
|
b8188a7954 | ||
|
|
8ac57db117 | ||
|
|
5cc66e4d36 | ||
|
|
d9d2022096 | ||
|
|
1ea38b1981 | ||
|
|
d63a36216f | ||
|
|
9ac935ed94 | ||
|
|
02bb2b7477 | ||
|
|
9cfce59547 | ||
|
|
99f0d5c685 | ||
|
|
f84cb1c9cc | ||
|
|
ae4733c59d | ||
|
|
2629c92a00 | ||
|
|
4ccb922d1a | ||
|
|
8113e9a168 | ||
|
|
a632f3c5cb | ||
|
|
e64e2f2c4e | ||
|
|
f6d49eb5b9 | ||
|
|
ee4f498a13 | ||
|
|
3bdb1f8550 | ||
|
|
971f060029 | ||
|
|
2684fd6b62 | ||
|
|
6085c5bf01 | ||
|
|
550f0d9936 | ||
|
|
9c00554118 | ||
|
|
ec7e8989a6 | ||
|
|
3ca4272230 | ||
|
|
ae14afd5f7 | ||
|
|
3d40b23496 | ||
|
|
88c0c41a70 | ||
|
|
176917caf4 | ||
|
|
e2e8fdafb1 | ||
|
|
aad8b09d81 | ||
|
|
90e3d9e460 | ||
|
|
baf9e4a9af | ||
|
|
1b453d0436 | ||
|
|
49b1a496b1 | ||
|
|
50afd83bc6 | ||
|
|
85934dcbe2 | ||
|
|
095ff20e2b | ||
|
|
3a91ed2571 | ||
|
|
20c534fc46 | ||
|
|
0c0bd8be98 | ||
|
|
ead6f9f4cd | ||
|
|
2328d9e107 | ||
|
|
87aa8333a8 | ||
|
|
f1de985304 | ||
|
|
5d3cbf8d1a | ||
|
|
c24ed8d47b | ||
|
|
cbf4a83b3f | ||
|
|
a6887715c7 | ||
|
|
e2169bc1da | ||
|
|
89f3b46a9e | ||
|
|
d64e838b6d | ||
|
|
263e495561 | ||
|
|
127433628d | ||
|
|
29e8da0944 | ||
|
|
a2992c86e6 | ||
|
|
1cc796b1a7 | ||
|
|
679cc7af38 | ||
|
|
c4b3239e33 | ||
|
|
4139da82b9 | ||
|
|
bdc7dc2cd8 | ||
|
|
244a4da28a | ||
|
|
e7e0dbd29a | ||
|
|
1f6b2e629b | ||
|
|
793ba944d6 | ||
|
|
438480517b | ||
|
|
e3b4d13c47 | ||
|
|
3caebb31ae | ||
|
|
8b9eee4961 | ||
|
|
280f5adb22 | ||
|
|
16cfcad0bf | ||
|
|
51431d22ba | ||
|
|
ef3bc9202b | ||
|
|
cdae169922 | ||
|
|
c45a7a2ef6 | ||
|
|
ddf16b71c2 | ||
|
|
d29f843525 | ||
|
|
8ce8ac4404 | ||
|
|
b55e59e665 | ||
|
|
598a3b5d7b | ||
|
|
8c16e3231e | ||
|
|
eca5eced63 | ||
|
|
e87d8da1fb | ||
|
|
f5fba1cbd1 | ||
|
|
06b4c3faab | ||
|
|
6d0b9b3747 | ||
|
|
92f2cef4d1 | ||
|
|
5fdfbd470b | ||
|
|
75b5f70196 | ||
|
|
b68be77865 | ||
|
|
105aab0345 | ||
|
|
9c3270a2de | ||
|
|
5c33e9666a | ||
|
|
aeb9403b67 | ||
|
|
50735567c9 | ||
|
|
0e83c992c3 | ||
|
|
dac7106df8 | ||
|
|
11b467e455 | ||
|
|
7cc2437ef7 | ||
|
|
8d4ffc0713 | ||
|
|
5ec5fb17ca | ||
|
|
234d643dd3 | ||
|
|
7288a1fcb2 | ||
|
|
b8b23cd359 | ||
|
|
c05eaa9382 | ||
|
|
6d14bda7b0 | ||
|
|
e2fd951ff3 | ||
|
|
bf598d5fe9 | ||
|
|
32f420dbe5 | ||
|
|
6d0e35ddcb | ||
|
|
f9f4557841 | ||
|
|
d441cdba71 | ||
|
|
9f24fb618f | ||
|
|
9d43641765 | ||
|
|
93f9ae8a31 | ||
|
|
c2ca0852d9 | ||
|
|
8bedfc257f | ||
|
|
b709810079 | ||
|
|
d4721d50f7 | ||
|
|
14b54e554e | ||
|
|
7555091d56 | ||
|
|
dbc176fe25 | ||
|
|
0a45385d48 | ||
|
|
f33ee27f56 | ||
|
|
5444b575f3 | ||
|
|
6361cd8268 | ||
|
|
0055fcf489 | ||
|
|
b7899d0c8c | ||
|
|
c1e5e45431 | ||
|
|
44d0966892 | ||
|
|
be0932f538 | ||
|
|
6cfa740f90 | ||
|
|
1bd8ec786b | ||
|
|
9a276d7289 | ||
|
|
ac63d41daf | ||
|
|
bd0a8a642b | ||
|
|
3e9b38044f | ||
|
|
d8ca9b5f39 | ||
|
|
e9f8e5eebd | ||
|
|
bf2613ee49 | ||
|
|
3b691da8d1 | ||
|
|
4955a4ef98 | ||
|
|
ca55d86187 | ||
|
|
5974856924 | ||
|
|
bdb7c65ab0 | ||
|
|
45ba8690a9 | ||
|
|
7054190832 | ||
|
|
dbd997b551 | ||
|
|
369bda13f8 | ||
|
|
c9216e5625 | ||
|
|
93af9656d0 | ||
|
|
bcade5bb9d | ||
|
|
59ab303c5c | ||
|
|
4ab9d1a493 | ||
|
|
f1576eeb32 | ||
|
|
1f851887d9 | ||
|
|
2a2564cf45 | ||
|
|
b5a78763f8 | ||
|
|
728e1ffdd0 | ||
|
|
14c9cfb310 | ||
|
|
b511a54445 | ||
|
|
f446e5ad3d | ||
|
|
c263c12448 | ||
|
|
ed9b6f0d3f | ||
|
|
d3152bee9c | ||
|
|
a504b429bd | ||
|
|
7b6db5ad7a | ||
|
|
398f675412 | ||
|
|
d18bf338b6 | ||
|
|
3091d28615 | ||
|
|
ab2365b475 | ||
|
|
7d356a2d20 | ||
|
|
e5a4f27e79 | ||
|
|
9cbcda0f7b | ||
|
|
93b2cd6002 | ||
|
|
411ed1e0c7 | ||
|
|
e5c4fe003b | ||
|
|
d6293ab081 | ||
|
|
38a5431ceb | ||
|
|
7f2a9f6806 | ||
|
|
6ab69e5c1c | ||
|
|
cd902a12b3 | ||
|
|
72809e8724 | ||
|
|
610cad00bf | ||
|
|
4f5bbebcd8 | ||
|
|
33f88039d7 | ||
|
|
2cf6b5052d | ||
|
|
8cb680f34e | ||
|
|
f089ef3fbe | ||
|
|
e1d2d4b863 | ||
|
|
d0b34dc04c | ||
|
|
6a8cffe615 | ||
|
|
d08101a5f4 | ||
|
|
7b6a26367a | ||
|
|
08ecf3f582 | ||
|
|
8d38e97c0b | ||
|
|
4c167cf528 | ||
|
|
7d27b675d0 | ||
|
|
0ef7e82548 | ||
|
|
8db0b52821 | ||
|
|
364199916f | ||
|
|
42066ecaba | ||
|
|
986b5a2afe | ||
|
|
921689aa04 | ||
|
|
283dcaffe2 | ||
|
|
074ffacf9d | ||
|
|
f1d3177b69 | ||
|
|
fa50e9dd20 | ||
|
|
d4de43a062 | ||
|
|
af795985fc | ||
|
|
610b19d646 | ||
|
|
95c8915d78 | ||
|
|
6bdfec743c | ||
|
|
e270c46703 | ||
|
|
0c0a866481 | ||
|
|
28ca0aed48 | ||
|
|
ca9ab100e5 | ||
|
|
73732bfb29 | ||
|
|
048e7f4c1b | ||
|
|
d041df8254 | ||
|
|
8e8b9a3cff | ||
|
|
b7b65d7361 | ||
|
|
6263c8a0cd | ||
|
|
3c92054a6e | ||
|
|
cf2b6a895f | ||
|
|
5bdb34521d | ||
|
|
e1e83c11cc | ||
|
|
0f5b17de0f | ||
|
|
568d9a3e30 | ||
|
|
1518b793dc | ||
|
|
6182b46033 | ||
|
|
4194553450 | ||
|
|
5f5a696717 | ||
|
|
35d516e140 | ||
|
|
fb5e5cc13f | ||
|
|
aa475a8d2e | ||
|
|
fa5c023d33 | ||
|
|
22d8e6f79f | ||
|
|
126ae4a0f0 | ||
|
|
68f18245a7 | ||
|
|
e2e25b7134 | ||
|
|
32088647c3 | ||
|
|
baf8df9597 | ||
|
|
34aa266260 | ||
|
|
8c887c2eee | ||
|
|
a95250cabb | ||
|
|
96bc6807ae | ||
|
|
81a139b875 | ||
|
|
1a3c20f0f7 | ||
|
|
4f735d0201 | ||
|
|
ec0543335e | ||
|
|
0872d024f9 | ||
|
|
0ce21c91ef | ||
|
|
220c7c271b | ||
|
|
bf389b94d6 | ||
|
|
6187f36c33 | ||
|
|
73df4e4abf | ||
|
|
1a8a5a5e8e | ||
|
|
c4ab6280c6 | ||
|
|
a27b6a113a | ||
|
|
a60ded5c94 | ||
|
|
5ff67d4b2d | ||
|
|
874e3d976f | ||
|
|
90e1284d83 | ||
|
|
75518b71ea | ||
|
|
b355efd73a | ||
|
|
8e920d727f | ||
|
|
5976be55f4 | ||
|
|
4c3df1a963 | ||
|
|
5b44f495ee | ||
|
|
3951e15446 | ||
|
|
b9da7c6f27 | ||
|
|
c5ae4a6957 | ||
|
|
e40c2f97f0 | ||
|
|
1dbc11bdd5 | ||
|
|
299edae7c0 | ||
|
|
86309bd837 | ||
|
|
0312e9026d | ||
|
|
a7bafb60e9 | ||
|
|
602769b9d0 | ||
|
|
e76546f8e4 | ||
|
|
a9ef1680ce | ||
|
|
670ddef944 | ||
|
|
be6b8dce25 | ||
|
|
75fd20f5df | ||
|
|
f0509a6631 | ||
|
|
702319c4ca | ||
|
|
d5bd187930 | ||
|
|
753036f0c8 | ||
|
|
cfc763b488 | ||
|
|
7edfeab0b7 | ||
|
|
226b0540c5 | ||
|
|
0c36647506 | ||
|
|
1348c8880e | ||
|
|
9334285edd | ||
|
|
2330d3a056 | ||
|
|
bce54a64ff | ||
|
|
bd43400ad8 | ||
|
|
b16c75324e | ||
|
|
0ddef1169d | ||
|
|
4da09bd841 | ||
|
|
6811cd617b | ||
|
|
4e762c75b0 | ||
|
|
f471c30036 | ||
|
|
aaed932a67 | ||
|
|
5f168b1a1e | ||
|
|
5d6f0d7e47 | ||
|
|
cf176f1b99 | ||
|
|
d97e867c07 | ||
|
|
3d0654dd48 | ||
|
|
e688840703 | ||
|
|
8bf272e806 | ||
|
|
0744bc4004 | ||
|
|
918f8cbe16 | ||
|
|
b6dafff524 | ||
|
|
34686dc167 | ||
|
|
c0c75bf18e | ||
|
|
66cfb403c6 | ||
|
|
0375f9c0ae | ||
|
|
11ac758d78 | ||
|
|
9e705b2f53 | ||
|
|
b475108ff3 | ||
|
|
ab34dff152 | ||
|
|
6a3f093cfa | ||
|
|
04ef9af703 | ||
|
|
b773ab3fb4 | ||
|
|
32085dc009 | ||
|
|
18fdfc26aa | ||
|
|
f50d2fa48e | ||
|
|
e82859c979 | ||
|
|
99bb35f109 | ||
|
|
8637f8ee9b | ||
|
|
1e11d40828 | ||
|
|
5546b102eb | ||
|
|
7d9c8c9172 | ||
|
|
8dd51b7207 | ||
|
|
746c5b603f | ||
|
|
d0de8d22fe | ||
|
|
231b8e9481 | ||
|
|
f9f36700bb | ||
|
|
ba9fced3db | ||
|
|
c192ecf6b7 | ||
|
|
6ee029e14b | ||
|
|
935f880fa7 | ||
|
|
47d046c5fe | ||
|
|
4305e17cbe | ||
|
|
c5c4cdd0b4 | ||
|
|
252562db90 | ||
|
|
a898682f3e | ||
|
|
7829094668 | ||
|
|
042c23a545 | ||
|
|
af2b9e3a4c | ||
|
|
b3b7c55b9a | ||
|
|
1859ede325 | ||
|
|
2c32c374fb | ||
|
|
65d22406a3 | ||
|
|
92689a60ae | ||
|
|
1a598ccf0d | ||
|
|
e50feb74fd | ||
|
|
af067a8c84 | ||
|
|
61a196bc3d | ||
|
|
6a431daffc | ||
|
|
1aad3e6cc8 | ||
|
|
c8d42e32ed | ||
|
|
514cc6edb8 | ||
|
|
208d3ffa7b | ||
|
|
25dd92f8c0 | ||
|
|
3f81b7e56d | ||
|
|
99b7333991 | ||
|
|
a2ae4ba441 | ||
|
|
4e1b2792c9 | ||
|
|
55695bb5bc | ||
|
|
6e064da536 | ||
|
|
69ff12645c | ||
|
|
efb93d22d9 | ||
|
|
cdb0068dcc | ||
|
|
b0a0d714c4 | ||
|
|
7e36ee243c | ||
|
|
21bc56a8ba | ||
|
|
e920c0fe3e | ||
|
|
31992fb398 | ||
|
|
dc65599fae | ||
|
|
eb9dc7b70d | ||
|
|
06bf2502a6 | ||
|
|
242655bac9 | ||
|
|
8335b3ee77 | ||
|
|
a0c8ad9511 | ||
|
|
d775a9364b | ||
|
|
1695124472 | ||
|
|
70145eb150 | ||
|
|
dacd7d94d9 | ||
|
|
85bd8555c0 | ||
|
|
6920b4e366 | ||
|
|
bda3835cb1 | ||
|
|
83e5aa6137 | ||
|
|
4719e52c6e | ||
|
|
e313eadcd2 | ||
|
|
be952e40ba | ||
|
|
4d4b24f8b0 | ||
|
|
9533fa25c3 | ||
|
|
013c9072b9 | ||
|
|
bf8dc05fac | ||
|
|
f4b38662fa | ||
|
|
ea41cce5ef | ||
|
|
013c292ffb | ||
|
|
cb18f11133 | ||
|
|
ea25f49c65 | ||
|
|
5d15d5958e | ||
|
|
efed92b15c | ||
|
|
7d39d02e98 | ||
|
|
e006442e4f | ||
|
|
212848e931 | ||
|
|
732de53d1b | ||
|
|
08c00eed1e | ||
|
|
2a1c3d1f33 | ||
|
|
5f57084ed9 | ||
|
|
9368e29d62 | ||
|
|
ae8751e9ca | ||
|
|
a11b8c4750 | ||
|
|
1e7e23df96 | ||
|
|
8395e00835 | ||
|
|
66bc1bdc77 | ||
|
|
b8984661d9 | ||
|
|
ea98a1c9f9 | ||
|
|
9173b40e2e | ||
|
|
59e5b1918f | ||
|
|
ab4b7b8ee6 | ||
|
|
7f0f153ebd | ||
|
|
f3d51a242d | ||
|
|
88ce192610 | ||
|
|
bd489647e9 | ||
|
|
c36666b4d4 | ||
|
|
97727cae2c | ||
|
|
f412b6818e | ||
|
|
e8aea86e75 | ||
|
|
fac171fa95 | ||
|
|
fa1b6493da | ||
|
|
e58766745c | ||
|
|
d8a9c5b479 | ||
|
|
9a4d8ba934 | ||
|
|
ab816543c8 | ||
|
|
37ccd81985 | ||
|
|
42dad4ade8 | ||
|
|
b2ac035862 | ||
|
|
f42d7eec74 | ||
|
|
e4ef41f86a | ||
|
|
103dd3954a | ||
|
|
2f9577a28e | ||
|
|
33ec4d9430 | ||
|
|
209f09ca7a | ||
|
|
2e6af75f1d | ||
|
|
f68122a380 | ||
|
|
d51bdccf7f | ||
|
|
7d8377b133 | ||
|
|
80d3a8a757 | ||
|
|
2e6c5cde29 | ||
|
|
0f2768dca4 | ||
|
|
d5be095482 | ||
|
|
b315625a94 | ||
|
|
6b51462fa0 | ||
|
|
373e698545 | ||
|
|
3b309c6d4e | ||
|
|
8e93e9f516 | ||
|
|
ac8582eca7 | ||
|
|
e6f72fdde7 | ||
|
|
9166218d07 | ||
|
|
c0b1bde94b | ||
|
|
756a679262 | ||
|
|
13b19b35c0 | ||
|
|
cadb70d1e4 | ||
|
|
4cb4844e8d | ||
|
|
556c7ca080 | ||
|
|
962db4bfc4 | ||
|
|
da651cabe4 | ||
|
|
e03076c6ff | ||
|
|
122968e63a | ||
|
|
6beac26727 | ||
|
|
3073281d13 | ||
|
|
0e0e23eefb | ||
|
|
bcec38bd97 | ||
|
|
bd706f99b2 | ||
|
|
501af632f7 | ||
|
|
a143122804 | ||
|
|
92aa426bba | ||
|
|
96a1ce2fb2 | ||
|
|
c203a09435 | ||
|
|
c4084b4162 | ||
|
|
2a7c948a57 | ||
|
|
46912595ea | ||
|
|
120ee6c673 | ||
|
|
112238fbd7 | ||
|
|
38e288ef6a | ||
|
|
35322cf49b | ||
|
|
8d44e1af0e | ||
|
|
16af078b3b | ||
|
|
3e968b4390 | ||
|
|
0029dac32d | ||
|
|
a083343c6e | ||
|
|
c277ee1d34 | ||
|
|
ebe8592a8d | ||
|
|
6c3e357d9e | ||
|
|
64455620e8 | ||
|
|
fc799778de | ||
|
|
e04e0e38d1 | ||
|
|
8d6569be95 | ||
|
|
8b086a3898 | ||
|
|
a4b8c33cf3 | ||
|
|
1d37ba47f4 | ||
|
|
8d480c28ce | ||
|
|
6e38f40f96 | ||
|
|
017c37f212 | ||
|
|
6eee4cb38a | ||
|
|
1f6a14261c | ||
|
|
14e8d840ff | ||
|
|
125b9ea1e1 | ||
|
|
e6b1e1948e | ||
|
|
ba1072f470 | ||
|
|
1fb29de082 | ||
|
|
f79e5ab559 | ||
|
|
c3a9fd469e | ||
|
|
c8abc909fa | ||
|
|
401a9f4c62 | ||
|
|
f1edb0c960 | ||
|
|
d73335e4d3 | ||
|
|
7a554be7a7 | ||
|
|
31b6ff6046 | ||
|
|
38ab0630e6 | ||
|
|
b5fa9deb30 | ||
|
|
4e8bae1703 | ||
|
|
464ce1c3cd | ||
|
|
bb55c320c1 | ||
|
|
af585bffa9 | ||
|
|
bde4868b67 | ||
|
|
3835fc5ad1 | ||
|
|
7b815b5f07 | ||
|
|
754c6126b1 | ||
|
|
2dc2a32e45 | ||
|
|
7a579303b9 | ||
|
|
03401e377b | ||
|
|
ff4ec6d843 | ||
|
|
0dc3dcd9ed | ||
|
|
ed3237f808 | ||
|
|
9321c3c334 | ||
|
|
adc7d41183 | ||
|
|
4ca69d8818 | ||
|
|
cca52e271b | ||
|
|
a2e15bbc87 | ||
|
|
9d6ad0303c | ||
|
|
bbaa23c22d | ||
|
|
bacb860cc1 | ||
|
|
7a4191e16d | ||
|
|
0fa620e3ba | ||
|
|
96642d8bc3 | ||
|
|
8a26c3783a | ||
|
|
d2742a177c | ||
|
|
6d4713e069 | ||
|
|
342170b077 | ||
|
|
df02d784d6 | ||
|
|
340874996e | ||
|
|
3bd89154d3 | ||
|
|
1e198fbb83 | ||
|
|
01855fc66a | ||
|
|
7ac045b5e2 | ||
|
|
03f1617ff5 | ||
|
|
c75b20e37d | ||
|
|
08f72596d4 | ||
|
|
dcd1f90ae7 | ||
|
|
c10603d161 | ||
|
|
7ea335e59b | ||
|
|
d20cb91d90 | ||
|
|
e38d754e86 | ||
|
|
afacc47f33 | ||
|
|
5803cc441e | ||
|
|
d60c66deee | ||
|
|
d7797a50f5 | ||
|
|
87bbebed36 | ||
|
|
3aa33bf0b1 | ||
|
|
e37afd6976 | ||
|
|
791f2a63ac | ||
|
|
1917f2b98a | ||
|
|
78b74f1115 | ||
|
|
8ea24d9ff9 | ||
|
|
f36d5fdbdf | ||
|
|
d421fc6e6f | ||
|
|
90c4c9e96b | ||
|
|
0a79892923 | ||
|
|
d88f638fbc | ||
|
|
d29121a871 | ||
|
|
5b8e983478 | ||
|
|
24d47cb10b | ||
|
|
ae7b84a85f | ||
|
|
161240045f | ||
|
|
fe85fc9d25 | ||
|
|
b8a2cd1b06 | ||
|
|
eee51828cb | ||
|
|
1eddd9017b | ||
|
|
9c0582a103 | ||
|
|
6cd8b34abb | ||
|
|
47075bec49 | ||
|
|
8eb6cbd400 | ||
|
|
8f394b5c3f | ||
|
|
2245315b60 | ||
|
|
0d40661b33 | ||
|
|
e015b91ed1 | ||
|
|
de577709d9 | ||
|
|
52c6d79975 | ||
|
|
512064f1b5 | ||
|
|
a396b50610 | ||
|
|
67299fcd9f | ||
|
|
f7476dfb63 | ||
|
|
87f7672dbf | ||
|
|
648a958290 | ||
|
|
ed90e2fcf9 | ||
|
|
b74be70ffc | ||
|
|
2351431d71 | ||
|
|
7435f76609 | ||
|
|
d2c1a4a7fb | ||
|
|
e37fbfddc3 | ||
|
|
8ab884a89e | ||
|
|
42f438146c | ||
|
|
08b1b350db | ||
|
|
cbcd9b5004 | ||
|
|
162a0bbe46 | ||
|
|
69d50e583e | ||
|
|
40a8384087 | ||
|
|
6053b2b5c9 | ||
|
|
7e17497c1e | ||
|
|
b573be918e | ||
|
|
2fada14a65 | ||
|
|
cf64a2bc8e | ||
|
|
39fd3479b7 | ||
|
|
536133289f | ||
|
|
3f280649a9 | ||
|
|
6c80aa8c98 | ||
|
|
65c39f600f | ||
|
|
3b5a9f6c6a | ||
|
|
665db4bdad | ||
|
|
b34e7fa303 | ||
|
|
abc0458d4f | ||
|
|
1e35398a84 | ||
|
|
be3253bf87 | ||
|
|
241a762d04 | ||
|
|
b944687191 | ||
|
|
736c66ee31 | ||
|
|
d96f31d01b | ||
|
|
e30c096d87 | ||
|
|
be71b98c55 | ||
|
|
6bec3162f6 | ||
|
|
c863876dee | ||
|
|
f5d0542f06 | ||
|
|
b1650eb503 | ||
|
|
82b090e234 | ||
|
|
7f1e416d31 | ||
|
|
4312bf711c | ||
|
|
f8061448d1 | ||
|
|
e934bec4b7 | ||
|
|
4e5d7ba8ef | ||
|
|
59fd815c3d | ||
|
|
b901c6af71 | ||
|
|
b2fb6c7804 | ||
|
|
84c5f8f738 | ||
|
|
39c7f11b98 | ||
|
|
86a2d73931 | ||
|
|
8eb50c3517 | ||
|
|
d9defb19f9 | ||
|
|
874804bcfd | ||
|
|
b0f9662811 | ||
|
|
24850823a2 | ||
|
|
951604475b | ||
|
|
74f3bb2aa9 | ||
|
|
4442b798c9 | ||
|
|
f10a8de2c1 | ||
|
|
329b29269b | ||
|
|
5b3ffe6bab | ||
|
|
fb14500b41 | ||
|
|
ad29594d08 | ||
|
|
37e2142cca | ||
|
|
1e5f1de12c | ||
|
|
0f93dbcd5e | ||
|
|
e415d85dbe | ||
|
|
4c8bf53e69 | ||
|
|
83fcd4bd1f | ||
|
|
bfd960ad1b | ||
|
|
6b81808ecc | ||
|
|
c615a6f6e2 | ||
|
|
40b522b42f | ||
|
|
f2655b763f | ||
|
|
fd145e65aa | ||
|
|
6596b7f27e | ||
|
|
9d767838d6 | ||
|
|
f55219bb1b | ||
|
|
805b647c73 | ||
|
|
fd0351ca8f | ||
|
|
ed5a7802f3 | ||
|
|
44f8317b7e | ||
|
|
0200933ddd | ||
|
|
f712b2b63a | ||
|
|
71923e7cba | ||
|
|
532d14611c | ||
|
|
3a91a07d51 | ||
|
|
6a8287ea9f | ||
|
|
dc051541bd | ||
|
|
3265c2a614 | ||
|
|
f798401e93 |
3
.github/FUNDING.yml
vendored
Normal file
3
.github/FUNDING.yml
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
# These are supported funding model platforms
|
||||
|
||||
github: [PCSX2]
|
||||
78
.github/ISSUE_TEMPLATE/app_bug_report.yaml
vendored
Normal file
78
.github/ISSUE_TEMPLATE/app_bug_report.yaml
vendored
Normal file
@@ -0,0 +1,78 @@
|
||||
# Docs - https://docs.github.com/en/communities/using-templates-to-encourage-useful-issues-and-pull-requests/syntax-for-githubs-form-schema
|
||||
name: Application Bug Report
|
||||
description: Found a problem with the application itself (ie. bad file path handling, UX issue)? Help us improve it.
|
||||
title: "[BUG]: "
|
||||
labels: [Bug]
|
||||
# assignees:
|
||||
# - octocat
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
## Important: Read First
|
||||
|
||||
Please do not make support requests on GitHub. Our issue tracker is for tracking bugs and feature requests only
|
||||
If you need help configuring the emulator please make a request on our forums or contact us on discord
|
||||
|
||||
If you are unsure, start with [discord](https://discord.com/invite/TCz3t9k) or the [forums](https://forums.pcsx2.net/index.php)
|
||||
|
||||
Please make an effort to make sure your issue isn't already reported
|
||||
|
||||
### Please Avoid Issues Pertaining to the Following:
|
||||
- We are **not** accepting bug reports for **PSX mode** at this time
|
||||
- If you are interested in helping contribute to PSX mode please do so on the forums. Otherwise our recommendation is that you use a [proper PSX emulator](https://emulation.gametechwiki.com/index.php/PlayStation_emulators)
|
||||
- We do **not** accept issues relating to **upscaling** at this time
|
||||
- We are aware of the various problems with upscaling. The issue spans many games and having hundreds of issues for the same fundamental issues isn't particularly helpful. There are several workarounds for graphical problems that come as a result of upscaling
|
||||
- Please try your game at native resolution before creating an issue
|
||||
- If your bug is the result of upscaling please use the forums or discord for assistance with various upscaling workarounds. Additionally, the unofficial PCSX2 [Wiki](https://wiki.pcsx2.net/Main_Page) often lists various fixes for upscaling issues
|
||||
- type: textarea
|
||||
id: desc
|
||||
attributes:
|
||||
label: Describe the Bug
|
||||
description: "A clear and concise description of what the bug is"
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: repro
|
||||
attributes:
|
||||
label: Reproduction Steps
|
||||
description: "Steps to reproduce the behavior"
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: expect
|
||||
attributes:
|
||||
label: Expected Behavior
|
||||
description: "A clear and concise description of what you expected to happen"
|
||||
validations:
|
||||
required: false
|
||||
- type: input
|
||||
id: rev
|
||||
attributes:
|
||||
label: PCSX2 Revision
|
||||
description: "Please ensure you are on the latest version before making an issue"
|
||||
placeholder: "Example: v1.7.1337"
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
id: os
|
||||
attributes:
|
||||
label: Operating System
|
||||
options:
|
||||
- Windows 11
|
||||
- Windows 10 (64bit)
|
||||
- Windows 8.1 (64bit)
|
||||
- Linux (64bit) - Specify Distro Below
|
||||
- macOS (Monteray)
|
||||
- macOS (BigSur)
|
||||
- macOS (Catalina)
|
||||
- macOS (Mojave)
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: os-distro
|
||||
attributes:
|
||||
label: If Linux - Specify Distro
|
||||
placeholder: "Example: Arch"
|
||||
validations:
|
||||
required: false
|
||||
@@ -1,6 +1,6 @@
|
||||
# Docs - https://docs.github.com/en/communities/using-templates-to-encourage-useful-issues-and-pull-requests/syntax-for-githubs-form-schema
|
||||
name: Bug Report
|
||||
description: Found a problem? Help us improve.
|
||||
name: Emulation Bug Report
|
||||
description: Problem in a game (ie. graphical artifacts, crashes)? Help us improve it.
|
||||
title: "[BUG]: "
|
||||
labels: [Bug]
|
||||
# assignees:
|
||||
@@ -54,9 +54,6 @@ body:
|
||||
Please make sure your system meets our requirements for OS version, CPU and GPU
|
||||
- [System Requirements](https://github.com/PCSX2/pcsx2#system-requirements)
|
||||
|
||||
We **do not** accept bug reports for **unsupported operating systems**.
|
||||
- [For macOS Support](https://forums.pcsx2.net/Thread-Native-Mac-Testing-Build)
|
||||
|
||||
Performance issues as a result of not meeting our hardware requirements are not valid
|
||||
|
||||
Please read our known issues pages for AMD and Intel drivers.
|
||||
@@ -69,7 +66,7 @@ body:
|
||||
attributes:
|
||||
label: PCSX2 Revision
|
||||
description: "We only accept bug reports for the latest dev version. Please try upgrading before making an issue."
|
||||
placeholder: "Example: dev-525"
|
||||
placeholder: "Example: v1.7.1337"
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
@@ -77,11 +74,9 @@ body:
|
||||
attributes:
|
||||
label: Operating System
|
||||
options:
|
||||
- Windows 10 (32bit)
|
||||
- Windows 11
|
||||
- Windows 10 (64bit)
|
||||
- Windows 8.1 (32bit)
|
||||
- Windows 8.1 (64bit)
|
||||
- Linux (32bit) - Specify Distro Below
|
||||
- Linux (64bit) - Specify Distro Below
|
||||
- macOS (Monteray)
|
||||
- macOS (BigSur)
|
||||
23
.github/labeler.yml
vendored
23
.github/labeler.yml
vendored
@@ -27,11 +27,19 @@
|
||||
'GUI/WX':
|
||||
- 'pcsx2/gui/*'
|
||||
- 'pcsx2/gui/**/*'
|
||||
- 'pcsx2/SPU2/wx/*'
|
||||
- 'pcsx2/SPU2/wx/**/*'
|
||||
- 'pcsx2/PAD/Linux/wx_dialog/*'
|
||||
- 'pcsx2/PAD/Linux/wx_dialog/**/*'
|
||||
- 'pcsx2/GS/Window/GSwxDialog.h'
|
||||
'GUI/Qt':
|
||||
- 'pcsx2-qt/*'
|
||||
- 'pcsx2-qt/**/*'
|
||||
- '3rdparty/Qt/*'
|
||||
- '3rdparty/Qt/**/*'
|
||||
'GameDB':
|
||||
- '**/GameIndex.*'
|
||||
'Installer | Package':
|
||||
- 'nsis/*'
|
||||
- 'nsis/**/*'
|
||||
- 'build.sh'
|
||||
|
||||
# Tools / Features
|
||||
@@ -65,15 +73,24 @@
|
||||
'GS':
|
||||
- 'pcsx2/GS/*'
|
||||
- 'pcsx2/GS/**/*'
|
||||
'GS: Direct3D':
|
||||
'GS: Direct3D 11':
|
||||
- 'pcsx2/GS/Renderers/DX11/*'
|
||||
- 'pcsx2/GS/Renderers/DX11/**/*'
|
||||
'GS: Direct3D 12':
|
||||
- 'pcsx2/GS/Renderers/DX12/*'
|
||||
- 'pcsx2/GS/Renderers/DX12/**/*'
|
||||
'GS: Hardware':
|
||||
- 'pcsx2/GS/Renderers/HW/*'
|
||||
- 'pcsx2/GS/Renderers/HW/**/*'
|
||||
'GS: OpenGL':
|
||||
- 'pcsx2/GS/Renderers/OpenGL/*'
|
||||
- 'pcsx2/GS/Renderers/OpenGL/**/*'
|
||||
'GS: Vulkan':
|
||||
- 'pcsx2/GS/Renderers/Vulkan/*'
|
||||
- 'pcsx2/GS/Renderers/Vulkan/**/*'
|
||||
'GS: Metal':
|
||||
- 'pcsx2/GS/Renderers/Metal/*'
|
||||
- 'pcsx2/GS/Renderers/Metal/**/*'
|
||||
'GS: Texture Cache':
|
||||
- 'pcsx2/GS/Renderers/*TextureCache*.*'
|
||||
- 'pcsx2/GS/Renderers/**/*TextureCache*.*'
|
||||
|
||||
14
.github/workflows/architecture/README.md
vendored
Normal file
14
.github/workflows/architecture/README.md
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
# CI Documentation
|
||||
|
||||
## Releases
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
PCSX2 Repo->>Actions: PR is merged or commit is pushed to master
|
||||
Actions->>PCSX2 Repo: Increment latest tag and push, create a draft release
|
||||
Actions->>Actions: Kicked off pipeline on the tag push, build relevant configs
|
||||
Actions->>PCSX2 Repo: Rename and upload artifacts to draft release, publish the release
|
||||
Actions->>Discord: Announce release via a WebHook
|
||||
PCSX2 Repo->>Web API: POST webhook to API informing it that a new release has occurred
|
||||
Web API->>Web API: Update cache with new release
|
||||
```
|
||||
BIN
.github/workflows/architecture/release-process.png
vendored
BIN
.github/workflows/architecture/release-process.png
vendored
Binary file not shown.
|
Before Width: | Height: | Size: 82 KiB |
@@ -1,47 +0,0 @@
|
||||
@startuml
|
||||
participant User as user
|
||||
participant Github as github
|
||||
participant "Create Release WF" as create
|
||||
participant "Build WFs" as build
|
||||
participant "Finalize Release WF" as finalize
|
||||
participant Discord as discord
|
||||
|
||||
==Nightly Release==
|
||||
|
||||
user -> github : New Commit on master (from PR, or directly)
|
||||
...waiting for commit push event to fire...
|
||||
github -> create : Push a new git tag, patch incrementing latest Version
|
||||
alt from-pr? case
|
||||
create -> create : Use links to the PR as a description
|
||||
else was a commit
|
||||
create -> create : Use Commit Message as Description
|
||||
end
|
||||
create -> create : Generate release notes
|
||||
create -> github : Create new draft release, associated with tag and with the notes
|
||||
note right
|
||||
Draft releases are not public facing, only those with write access can see them!
|
||||
end note
|
||||
...waiting for push tag event to fire...
|
||||
loop for all build workflows
|
||||
github -> build : Build the tag commit
|
||||
build -> build : .exe will use the git tag for it's title and such
|
||||
build -> build : Upload the generated artifact to the associated release
|
||||
alt all-artifacts-uploaded? case
|
||||
build -> github : Publish the release
|
||||
user -> github : Can now download the artifacts on the published release
|
||||
end
|
||||
note right
|
||||
This is the only area where an eventual consistency issue is apparent
|
||||
It is because GitHub does not fire events for when draft releases are edited
|
||||
This is glossed over in the initial impl and can be improved and be made eventually consistent as well
|
||||
end note
|
||||
|
||||
|
||||
...waiting for release publish event to fire...
|
||||
github -> finalize : Announce the Release
|
||||
finalize -> github : Gather all asset links, and format message embed.
|
||||
finalize -> discord : Announce new build via a WebHook
|
||||
|
||||
...waiting for announcement...
|
||||
user -> discord : Can download artifacts from links via the discord
|
||||
@enduml
|
||||
29
.github/workflows/cron_update_controller_db.yml
vendored
Normal file
29
.github/workflows/cron_update_controller_db.yml
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
name: 🏭 Update Controller Database
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: "0 16 * * 1" # every monday @ 12pm EST - https://crontab.guru/#0_16_*_*_1
|
||||
|
||||
jobs:
|
||||
update-controller-db:
|
||||
if: github.repository == 'PCSX2/pcsx2'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Get Latest DB and Prepare DB File
|
||||
run: |
|
||||
cd .github/workflows/scripts/controller-db/
|
||||
wget -O game_controller_db.txt https://raw.githubusercontent.com/gabomdq/SDL_GameControllerDB/master/gamecontrollerdb.txt
|
||||
python ./update-db.py
|
||||
mv ./game_controller_db.txt ${{github.workspace}}/bin/resources/game_controller_db.txt
|
||||
|
||||
- name: Create Pull Request
|
||||
uses: peter-evans/create-pull-request@v4
|
||||
with:
|
||||
title: "PAD: Update to latest controller database"
|
||||
commit-message: "PAD: Update to latest controller database."
|
||||
committer: "PCSX2 Bot <PCSX2Bot@users.noreply.github.com>"
|
||||
author: "PCSX2 Bot <PCSX2Bot@users.noreply.github.com>"
|
||||
body: "Weekly automatic update of SDL Controller DB"
|
||||
reviewers: lightningterror
|
||||
27
.github/workflows/lint-gamedb.yml
vendored
27
.github/workflows/lint-gamedb.yml
vendored
@@ -1,27 +0,0 @@
|
||||
name: 📝 Validate GameDB
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
paths:
|
||||
- '**/GameIndex.yaml'
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
paths:
|
||||
- '**/GameIndex.yaml'
|
||||
|
||||
jobs:
|
||||
lint:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout Repository
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Validate GameDB
|
||||
env:
|
||||
SCRIPT_DIR: .github/workflows/scripts/validation/lint-gamedb
|
||||
run: |
|
||||
pip install -r "${SCRIPT_DIR}/requirements.txt"
|
||||
python "${SCRIPT_DIR}/lint-gamedb.py"
|
||||
34
.github/workflows/lint_gamedb.yml
vendored
Normal file
34
.github/workflows/lint_gamedb.yml
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
name: 📝 Validate GameDB
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
paths:
|
||||
- '**/GameIndex.yaml'
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
paths:
|
||||
- '**/GameIndex.yaml'
|
||||
|
||||
jobs:
|
||||
lint:
|
||||
name: Lint and Validate GameDB
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout Repository
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Validate Contents
|
||||
env:
|
||||
GAMEDB_PATH: ./bin/resources/GameIndex.yaml
|
||||
SCRIPT_DIR: .github/workflows/scripts/lint/gamedb
|
||||
run: |
|
||||
pip install -r "${SCRIPT_DIR}/requirements.txt"
|
||||
python "${SCRIPT_DIR}/lint.py"
|
||||
|
||||
- name: Check Formatting
|
||||
run: |
|
||||
npm install -g prettier
|
||||
prettier --check ./bin/resources/GameIndex.yaml
|
||||
207
.github/workflows/linux-workflow.yml
vendored
207
.github/workflows/linux-workflow.yml
vendored
@@ -1,207 +0,0 @@
|
||||
name: 🐧 Linux Builds
|
||||
|
||||
# Controls when the action will run. Triggers the workflow on push or pull request
|
||||
# events but only for the master branch
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
tags:
|
||||
- v*
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
paths-ignore:
|
||||
- "**/*.md"
|
||||
- "**/*.bat"
|
||||
- "**/*.cmd"
|
||||
- "**/*.props"
|
||||
- "**/*.sln"
|
||||
- ".clang-format"
|
||||
- ".codacy.yaml"
|
||||
- ".github/*"
|
||||
- ".github/workflows/lint-gamedb.yml"
|
||||
- ".github/workflows/macos-workflow.yml"
|
||||
- ".github/workflows/pr-triage.yml"
|
||||
- ".github/workflows/scripts/windows/**"
|
||||
- ".github/workflows/scripts/validation/**"
|
||||
- ".github/workflows/windows-workflow.yml"
|
||||
- ".gitignore"
|
||||
- "bin/PCSX2_keys.ini.default"
|
||||
- "build.sh"
|
||||
- "buildbot.xml"
|
||||
- "pcsx2/CDVD/Windows/**"
|
||||
- "pcsx2/DEV9/Win32/**"
|
||||
- "pcsx2/PAD/Windows/**"
|
||||
- "pcsx2/SPU2/Windows/**"
|
||||
- "pcsx2/USB/Win32/**"
|
||||
- "pcsx2/windows/**"
|
||||
|
||||
jobs:
|
||||
build:
|
||||
strategy:
|
||||
# Prevent one build from failing everything (although maybe those should be included as experimental builds instead)
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- os: ubuntu-18.04
|
||||
platform: x86
|
||||
compiler: gcc
|
||||
cmakeflags: -DLTO_PCSX2_CORE=ON
|
||||
appimage: true
|
||||
experimental: false
|
||||
- os: ubuntu-18.04
|
||||
platform: x64
|
||||
compiler: gcc
|
||||
cmakeflags: -DLTO_PCSX2_CORE=ON
|
||||
appimage: true
|
||||
experimental: false
|
||||
- os: ubuntu-18.04
|
||||
platform: x86
|
||||
compiler: clang
|
||||
# Need to disable PCH until cmake 3.17
|
||||
# (PCH conflicts with ccache, fixed by https://gitlab.kitware.com/cmake/cmake/-/merge_requests/4400)
|
||||
cmakeflags: -DCMAKE_DISABLE_PRECOMPILE_HEADERS=ON
|
||||
detail: " nopch"
|
||||
appimage: false
|
||||
experimental: false
|
||||
- os: ubuntu-18.04
|
||||
platform: x86
|
||||
compiler: gcc
|
||||
cmakeflags: -DCMAKE_DISABLE_PRECOMPILE_HEADERS=ON
|
||||
detail: " nopch"
|
||||
appimage: false
|
||||
experimental: false
|
||||
- os: ubuntu-18.04
|
||||
platform: x86
|
||||
compiler: gcc
|
||||
cmakeflags: -DCMAKE_DISABLE_PRECOMPILE_HEADERS=ON -DARCH_FLAG=-march=haswell
|
||||
detail: " avx2 nopch"
|
||||
appimage: false
|
||||
experimental: false
|
||||
|
||||
name: ${{ matrix.platform }} | ${{ matrix.compiler }}${{ matrix.detail }}
|
||||
runs-on: ${{ matrix.os }}
|
||||
continue-on-error: ${{ matrix.experimental }}
|
||||
# Set some sort of timeout in the event of run-away builds. We are limited on concurrent jobs so, get rid of them.
|
||||
timeout-minutes: 30
|
||||
|
||||
env:
|
||||
CCACHE_BASEDIR: ${{ github.workspace }}
|
||||
CCACHE_DIR: ${{ github.workspace }}/.ccache
|
||||
CCACHE_COMPRESS: true
|
||||
CCACHE_COMPRESSLEVEL: 9
|
||||
CCACHE_MAXSIZE: 100M
|
||||
|
||||
steps:
|
||||
# NOTE - useful for debugging
|
||||
# - name: Dump GitHub context
|
||||
# env:
|
||||
# GITHUB_CONTEXT: ${{ toJson(github) }}
|
||||
# run: |
|
||||
# echo "$GITHUB_CONTEXT"
|
||||
# echo ${{ github.event.pull_request.title }}
|
||||
|
||||
- name: Checkout Repository
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Checkout Submodules
|
||||
if: steps.cache-submodules.outputs.cache-hit != 'true'
|
||||
run: git submodule update --init --recursive -j $(getconf _NPROCESSORS_ONLN)
|
||||
|
||||
# -- SETUP CCACHE - https://cristianadam.eu/20200113/speeding-up-c-plus-plus-github-actions-using-ccache/
|
||||
- name: Prepare ccache timestamp
|
||||
id: ccache_cache_timestamp
|
||||
shell: cmake -P {0}
|
||||
run: |
|
||||
string(TIMESTAMP current_date "%Y-%m-%d-%H;%M;%S" UTC)
|
||||
message("::set-output name=timestamp::${current_date}")
|
||||
|
||||
- name: ccache cache files
|
||||
uses: actions/cache@v2.1.6
|
||||
with:
|
||||
path: .ccache
|
||||
key: ${{ matrix.os }} ${{ matrix.platform }} ${{ matrix.compiler }}${{ matrix.detail }} ccache ${{ steps.ccache_cache_timestamp.outputs.timestamp }}
|
||||
restore-keys: ${{ matrix.os }} ${{ matrix.platform }} ${{ matrix.compiler }}${{ matrix.detail }} ccache
|
||||
|
||||
- name: Prepare Artifact Metadata
|
||||
id: artifact-metadata
|
||||
shell: bash
|
||||
run: |
|
||||
ARCH=$([ "${{ matrix.platform }}" == x86 ] && echo "32bit" || echo "64bit")
|
||||
ARTIFACT_NAME=""
|
||||
if [ ${{ github.event_name }} == "pull_request" ]; then
|
||||
PR_SHA=$(git rev-parse --short "${{ github.event.pull_request.head.sha }}")
|
||||
ARTIFACT_NAME="PCSX2-${ARCH}"
|
||||
if [ ! -z "${{ github.event.pull_request.number }}" ]; then
|
||||
PR_NUM=${{ github.event.pull_request.number }}
|
||||
ARTIFACT_NAME="${ARTIFACT_NAME}-pr[${PR_NUM}]"
|
||||
fi
|
||||
ARTIFACT_NAME="${ARTIFACT_NAME}-sha[${PR_SHA}]"
|
||||
if [ ! -z "${{ github.event.pull_request.title }}" ]; then
|
||||
PR_TITLE=$(echo "${{ github.event.pull_request.title }}" | tr -cd '[a-zA-Z0-9[:space:]]_-')
|
||||
ARTIFACT_NAME="${ARTIFACT_NAME}-title["${PR_TITLE}""
|
||||
fi
|
||||
else
|
||||
SHA=$(git rev-parse --short "$GITHUB_SHA")
|
||||
ARTIFACT_NAME="PCSX2-${ARCH}-sha[${SHA}"
|
||||
fi
|
||||
TRIMMED_ARTIFACT_NAME=$(printf "%.199s]" "$ARTIFACT_NAME")
|
||||
echo "name=$TRIMMED_ARTIFACT_NAME"
|
||||
echo "##[set-output name=name;]${TRIMMED_ARTIFACT_NAME}"
|
||||
echo "##[set-output name=arch;]${ARCH}"
|
||||
|
||||
- name: Install Packages
|
||||
env:
|
||||
PLATFORM: ${{ matrix.platform }}
|
||||
COMPILER: ${{ matrix.compiler }}
|
||||
run: .github/workflows/scripts/linux/install-packages.sh
|
||||
|
||||
- name: Generate CMake
|
||||
env:
|
||||
PLATFORM: ${{ matrix.platform }}
|
||||
COMPILER: ${{ matrix.compiler }}
|
||||
ADDITIONAL_CMAKE_ARGS: ${{ matrix.cmakeflags }}
|
||||
run: .github/workflows/scripts/linux/generate-cmake.sh
|
||||
|
||||
- name: Build PCSX2
|
||||
working-directory: build
|
||||
run: ../.github/workflows/scripts/linux/compile.sh
|
||||
|
||||
- name: Run Tests
|
||||
working-directory: ./build
|
||||
run: ninja unittests
|
||||
|
||||
- name: Package AppImage
|
||||
if: matrix.appimage == true
|
||||
env:
|
||||
PLATFORM: ${{ matrix.platform }}
|
||||
COMPILER: ${{ matrix.compiler }}
|
||||
name: ${{ steps.artifact-metadata.outputs.name }}
|
||||
run: .github/workflows/scripts/linux/appimage.sh
|
||||
|
||||
- name: Upload artifact
|
||||
if: matrix.appimage == true
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: ${{ steps.artifact-metadata.outputs.name }}
|
||||
path: ci-artifacts
|
||||
|
||||
# ---- Release / Tagging related steps ----
|
||||
- name: Prepare Build Artifacts
|
||||
if: github.repository == 'PCSX2/pcsx2' && startsWith(github.ref, 'refs/tags/') && matrix.appimage == true
|
||||
run: |
|
||||
mv ./ci-artifacts/*.AppImage ./ci-artifacts/linux-AppImage-${{ steps.artifact-metadata.outputs.arch }}.AppImage
|
||||
ls ./ci-artifacts/
|
||||
|
||||
- name: Upload Assets and Potential Publish Release
|
||||
if: github.repository == 'PCSX2/pcsx2' && startsWith(github.ref, 'refs/tags/') && matrix.appimage == true
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.BOT_PAT }}
|
||||
ASSET_DIR: ${{ github.WORKSPACE }}/ci-artifacts
|
||||
ASSET_EXTENSION: AppImage
|
||||
TAG_TO_SEARCH_FOR: ${{ github.REF }}
|
||||
run: |
|
||||
cd ./.github/workflows/scripts/releases/upload-release-artifacts
|
||||
npm ci
|
||||
node index.js
|
||||
74
.github/workflows/linux_build_matrix.yml
vendored
Normal file
74
.github/workflows/linux_build_matrix.yml
vendored
Normal file
@@ -0,0 +1,74 @@
|
||||
name: 🐧 Linux Builds
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- '*'
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
|
||||
jobs:
|
||||
build_gcc_lto:
|
||||
name: "GCC"
|
||||
uses: ./.github/workflows/linux_build_wx.yml
|
||||
with:
|
||||
jobName: "with LTO"
|
||||
compiler: gcc
|
||||
cmakeflags: "-DLTO_PCSX2_CORE=ON"
|
||||
buildAppImage: true
|
||||
secrets: inherit
|
||||
|
||||
# (PCH conflicts with ccache, fixed by https://gitlab.kitware.com/cmake/cmake/-/merge_requests/4400)
|
||||
build_gcc_nopch:
|
||||
name: "GCC"
|
||||
uses: ./.github/workflows/linux_build_wx.yml
|
||||
with:
|
||||
jobName: "No PCH"
|
||||
compiler: gcc
|
||||
cmakeflags: "-DCMAKE_DISABLE_PRECOMPILE_HEADERS=ON"
|
||||
detail: " nopch"
|
||||
secrets: inherit
|
||||
|
||||
build_gcc_nopch_avx2:
|
||||
name: "GCC"
|
||||
uses: ./.github/workflows/linux_build_wx.yml
|
||||
with:
|
||||
jobName: "AVX2 and No PCH"
|
||||
compiler: gcc
|
||||
cmakeflags: "-DCMAKE_DISABLE_PRECOMPILE_HEADERS=ON -DARCH_FLAG=-march=haswell"
|
||||
detail: " avx2 nopch"
|
||||
secrets: inherit
|
||||
|
||||
build_clang_nopch:
|
||||
name: "Clang"
|
||||
uses: ./.github/workflows/linux_build_wx.yml
|
||||
with:
|
||||
jobName: "No PCH"
|
||||
compiler: clang
|
||||
cmakeflags: ""
|
||||
detail: " nopch"
|
||||
secrets: inherit
|
||||
|
||||
build_linux_qt_sse4:
|
||||
name: "AppImage"
|
||||
uses: ./.github/workflows/linux_build_qt.yml
|
||||
with:
|
||||
jobName: "Qt SSE4"
|
||||
compiler: clang
|
||||
cmakeflags: ""
|
||||
simd: "SSE4"
|
||||
buildAppImage: true
|
||||
secrets: inherit
|
||||
|
||||
build_linux_qt_avx2:
|
||||
name: "AppImage"
|
||||
uses: ./.github/workflows/linux_build_qt.yml
|
||||
with:
|
||||
jobName: "Qt AVX2"
|
||||
detail: ""
|
||||
compiler: clang
|
||||
cmakeflags: "-DARCH_FLAG=-march=haswell"
|
||||
simd: "AVX2"
|
||||
buildAppImage: true
|
||||
secrets: inherit
|
||||
129
.github/workflows/linux_build_qt.yml
vendored
Normal file
129
.github/workflows/linux_build_qt.yml
vendored
Normal file
@@ -0,0 +1,129 @@
|
||||
name: Linux Build Steps
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
jobName:
|
||||
required: true
|
||||
type: string
|
||||
os:
|
||||
required: false
|
||||
type: string
|
||||
default: ubuntu-20.04
|
||||
platform:
|
||||
required: false
|
||||
type: string
|
||||
default: x64
|
||||
compiler:
|
||||
required: true
|
||||
type: string
|
||||
cmakeflags:
|
||||
required: true
|
||||
type: string
|
||||
buildAppImage:
|
||||
required: false
|
||||
type: boolean
|
||||
default: false
|
||||
detail:
|
||||
required: false
|
||||
type: string
|
||||
default: ""
|
||||
simd:
|
||||
required: false
|
||||
type: string
|
||||
default: ""
|
||||
|
||||
jobs:
|
||||
build_linux:
|
||||
name: ${{ inputs.jobName }}
|
||||
runs-on: ${{ inputs.os }}
|
||||
# Set some sort of timeout in the event of run-away builds. We are limited on concurrent jobs so, get rid of them.
|
||||
timeout-minutes: 60
|
||||
env:
|
||||
CCACHE_BASEDIR: ${{ github.workspace }}
|
||||
CCACHE_DIR: ${{ github.workspace }}/.ccache
|
||||
CCACHE_COMPRESS: true
|
||||
CCACHE_COMPRESSLEVEL: 9
|
||||
CCACHE_MAXSIZE: 100M
|
||||
|
||||
steps:
|
||||
- name: Checkout Repository
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: Prepare Artifact Metadata
|
||||
id: artifact-metadata
|
||||
shell: bash
|
||||
env:
|
||||
OS: linux
|
||||
GUI_FRAMEWORK: QT
|
||||
ARCH: ${{ inputs.platform }}
|
||||
SIMD: ${{ inputs.simd }}
|
||||
EVENT_NAME: ${{ github.event_name }}
|
||||
PR_TITLE: ${{ github.event.pull_request.title }}
|
||||
PR_NUM: ${{ github.event.pull_request.number }}
|
||||
PR_SHA: ${{ github.event.pull_request.head.sha }}
|
||||
run: ./.github/workflows/scripts/common/name-artifacts.sh
|
||||
|
||||
# -- SETUP CCACHE - https://cristianadam.eu/20200113/speeding-up-c-plus-plus-github-actions-using-ccache/
|
||||
- name: Prepare ccache timestamp
|
||||
id: ccache_cache_timestamp
|
||||
shell: cmake -P {0}
|
||||
run: |
|
||||
string(TIMESTAMP current_date "%Y-%m-%d-%H;%M;%S" UTC)
|
||||
message("::set-output name=timestamp::${current_date}")
|
||||
|
||||
- name: ccache cache files
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: .ccache
|
||||
key: ${{ inputs.os }} ${{ inputs.platform }} ${{ inputs.compiler }} ${{ inputs.simd }} ${{ inputs.detail }} ccache ${{ steps.ccache_cache_timestamp.outputs.timestamp }}
|
||||
restore-keys: ${{ inputs.os }} ${{ inputs.platform }} ${{ inputs.compiler }} ${{ inputs.simd }} ${{ inputs.detail }} ccache
|
||||
|
||||
- name: Install Packages
|
||||
env:
|
||||
COMPILER: ${{ inputs.compiler }}
|
||||
run: .github/workflows/scripts/linux/install-packages-qt.sh
|
||||
|
||||
- name: Cache Dependencies
|
||||
id: cache-deps
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: ~/deps
|
||||
key: ${{ inputs.os }} ${{ inputs.platform }} ${{ inputs.gui }} deps ${{ hashFiles('.github/workflows/scripts/linux/build-dependencies-qt.sh') }}
|
||||
|
||||
- name: Build Dependencies
|
||||
if: steps.cache-deps.outputs.cache-hit != 'true'
|
||||
run: .github/workflows/scripts/linux/build-dependencies-qt.sh
|
||||
|
||||
- name: Generate CMake
|
||||
env:
|
||||
COMPILER: ${{ inputs.compiler }}
|
||||
ADDITIONAL_CMAKE_ARGS: ${{ inputs.cmakeflags }}
|
||||
run: .github/workflows/scripts/linux/generate-cmake-qt.sh
|
||||
|
||||
- name: Build PCSX2
|
||||
working-directory: build
|
||||
run: ../.github/workflows/scripts/linux/compile.sh
|
||||
|
||||
- name: Run Tests
|
||||
working-directory: ./build
|
||||
run: ninja unittests
|
||||
|
||||
- name: Package AppImage
|
||||
if: inputs.buildAppImage == true
|
||||
env:
|
||||
NAME: ${{ steps.artifact-metadata.outputs.artifact-name }}
|
||||
run: |
|
||||
ninja -C build install
|
||||
.github/workflows/scripts/linux/appimage-qt.sh "$(realpath .)" "$HOME/deps" "$NAME"
|
||||
mkdir -p "$GITHUB_WORKSPACE"/ci-artifacts/
|
||||
mv "${NAME}.AppImage" "$GITHUB_WORKSPACE"/ci-artifacts/
|
||||
|
||||
- name: Upload artifact
|
||||
if: inputs.buildAppImage == true
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: ${{ steps.artifact-metadata.outputs.artifact-name }}
|
||||
path: ci-artifacts
|
||||
146
.github/workflows/linux_build_wx.yml
vendored
Normal file
146
.github/workflows/linux_build_wx.yml
vendored
Normal file
@@ -0,0 +1,146 @@
|
||||
name: Linux Build Steps
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
jobName:
|
||||
required: true
|
||||
type: string
|
||||
os:
|
||||
required: false
|
||||
type: string
|
||||
default: ubuntu-18.04
|
||||
platform:
|
||||
required: false
|
||||
type: string
|
||||
default: x64
|
||||
compiler:
|
||||
required: true
|
||||
type: string
|
||||
cmakeflags:
|
||||
required: true
|
||||
type: string
|
||||
buildAppImage:
|
||||
required: false
|
||||
type: boolean
|
||||
default: false
|
||||
detail:
|
||||
required: false
|
||||
type: string
|
||||
default: ""
|
||||
|
||||
jobs:
|
||||
build_linux:
|
||||
name: ${{ inputs.jobName }}
|
||||
runs-on: ${{ inputs.os }}
|
||||
# Set some sort of timeout in the event of run-away builds. We are limited on concurrent jobs so, get rid of them.
|
||||
timeout-minutes: 60
|
||||
env:
|
||||
CCACHE_BASEDIR: ${{ github.workspace }}
|
||||
CCACHE_DIR: ${{ github.workspace }}/.ccache
|
||||
CCACHE_COMPRESS: true
|
||||
CCACHE_COMPRESSLEVEL: 9
|
||||
CCACHE_MAXSIZE: 100M
|
||||
SDL: SDL2-2.0.22
|
||||
PATCHELF_VERSION: 0.12
|
||||
|
||||
steps:
|
||||
- name: Checkout Repository
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: Prepare Artifact Metadata
|
||||
id: artifact-metadata
|
||||
shell: bash
|
||||
env:
|
||||
OS: linux
|
||||
GUI_FRAMEWORK: wxWidgets
|
||||
ARCH: ${{ inputs.platform }}
|
||||
SIMD: ''
|
||||
EVENT_NAME: ${{ github.event_name }}
|
||||
PR_TITLE: ${{ github.event.pull_request.title }}
|
||||
PR_NUM: ${{ github.event.pull_request.number }}
|
||||
PR_SHA: ${{ github.event.pull_request.head.sha }}
|
||||
run: ./.github/workflows/scripts/common/name-artifacts.sh
|
||||
|
||||
# -- SETUP CCACHE - https://cristianadam.eu/20200113/speeding-up-c-plus-plus-github-actions-using-ccache/
|
||||
- name: Prepare ccache timestamp
|
||||
id: ccache_cache_timestamp
|
||||
shell: cmake -P {0}
|
||||
run: |
|
||||
string(TIMESTAMP current_date "%Y-%m-%d-%H;%M;%S" UTC)
|
||||
message("::set-output name=timestamp::${current_date}")
|
||||
|
||||
- name: ccache cache files
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: .ccache
|
||||
key: ${{ inputs.os }} ${{ inputs.platform }} ${{ inputs.compiler }}${{ inputs.detail }} ccache ${{ steps.ccache_cache_timestamp.outputs.timestamp }}
|
||||
restore-keys: ${{ inputs.os }} ${{ inputs.platform }} ${{ inputs.compiler }}${{ inputs.detail }} ccache
|
||||
|
||||
- name: Install Packages
|
||||
env:
|
||||
PLATFORM: ${{ inputs.platform }}
|
||||
COMPILER: ${{ inputs.compiler }}
|
||||
run: .github/workflows/scripts/linux/install-packages.sh
|
||||
|
||||
- name: Cache Dependencies
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: |
|
||||
3rdparty/${{ env.SDL }}
|
||||
3rdparty/patchelf-${{ env.PATCHELF_VERSION }}
|
||||
key: ${{ inputs.os }} ${{ inputs.platform }} ${{ env.SDL }} patchelf-${{ env.PATCHELF_VERSION }}
|
||||
|
||||
- name: Build Dependencies
|
||||
run: |
|
||||
if [[ ! -e 3rdparty/patchelf-${{ env.PATCHELF_VERSION }} ]]; then
|
||||
curl -sSfL https://github.com/NixOS/patchelf/releases/download/${{ env.PATCHELF_VERSION }}/patchelf-${{ env.PATCHELF_VERSION }}.tar.bz2 | tar -xjC 3rdparty
|
||||
mv 3rdparty/patchelf-${{ env.PATCHELF_VERSION }}* 3rdparty/patchelf-${{ env.PATCHELF_VERSION }}
|
||||
cd 3rdparty/patchelf-${{ env.PATCHELF_VERSION }}
|
||||
./configure
|
||||
make && cd ../../
|
||||
fi
|
||||
sudo make -C 3rdparty/patchelf-${{ env.PATCHELF_VERSION }} install
|
||||
if [[ ! -e 3rdparty/${{ env.SDL }} ]]; then
|
||||
curl -sL https://libsdl.org/release/${{ env.SDL }}.tar.gz | tar -xzC 3rdparty
|
||||
cd 3rdparty/${{ env.SDL }}
|
||||
if [ "${{ inputs.platform }}" == "x86" ]; then
|
||||
./configure --build=i686-pc-linux-gnu CC=${{ inputs.compiler }} CFLAGS=-m32 CXXFLAGS=-m32 LDFLAGS=-m32 --prefix=/usr --libdir=/usr/lib/i386-linux-gnu
|
||||
else
|
||||
./configure --prefix=/usr --libdir=/usr/lib/x86_64-linux-gnu
|
||||
fi
|
||||
make -j $(getconf _NPROCESSORS_ONLN) && cd ../../
|
||||
fi
|
||||
sudo make -C 3rdparty/${{ env.SDL }} install
|
||||
|
||||
- name: Generate CMake
|
||||
env:
|
||||
PLATFORM: ${{ inputs.platform }}
|
||||
COMPILER: ${{ inputs.compiler }}
|
||||
ADDITIONAL_CMAKE_ARGS: ${{ inputs.cmakeflags }}
|
||||
run: .github/workflows/scripts/linux/generate-cmake.sh
|
||||
|
||||
- name: Build PCSX2
|
||||
working-directory: build
|
||||
run: ../.github/workflows/scripts/linux/compile.sh
|
||||
|
||||
- name: Run Tests
|
||||
working-directory: ./build
|
||||
run: ninja unittests
|
||||
|
||||
- name: Package AppImage
|
||||
if: inputs.buildAppImage == true
|
||||
env:
|
||||
PLATFORM: ${{ inputs.platform }}
|
||||
COMPILER: ${{ inputs.compiler }}
|
||||
name: ${{ steps.artifact-metadata.outputs.artifact-name }}
|
||||
run: .github/workflows/scripts/linux/appimage.sh
|
||||
|
||||
- name: Upload artifact
|
||||
if: inputs.buildAppImage == true
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: ${{ steps.artifact-metadata.outputs.artifact-name }}
|
||||
path: ci-artifacts
|
||||
118
.github/workflows/macos-workflow.yml
vendored
118
.github/workflows/macos-workflow.yml
vendored
@@ -1,118 +0,0 @@
|
||||
name: 🍎 MacOS Builds
|
||||
|
||||
# Controls when the action will run. Triggers the workflow on push or pull request
|
||||
# events but only for the master branch
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
paths-ignore:
|
||||
- '**/*.md'
|
||||
- '**/*.bat'
|
||||
- '**/*.cmd'
|
||||
- '**/*.props'
|
||||
- '**/*.sln'
|
||||
- '.clang-format'
|
||||
- '.codacy.yaml'
|
||||
- '.github/*'
|
||||
- '.github/workflows/lint-gamedb.yml'
|
||||
- '.github/workflows/linux-workflow.yml'
|
||||
- '.github/workflows/pr-triage.yml'
|
||||
- '.github/workflows/scripts/windows/**'
|
||||
- '.github/workflows/scripts/validation/**'
|
||||
- '.github/workflows/windows-workflow.yml'
|
||||
- '.gitignore'
|
||||
- 'bin/PCSX2_keys.ini.default'
|
||||
- 'build.sh'
|
||||
- 'buildbot.xml'
|
||||
- 'pcsx2/CDVD/Windows/**'
|
||||
- 'pcsx2/DEV9/Win32/**'
|
||||
- 'pcsx2/PAD/Windows/**'
|
||||
- 'pcsx2/SPU2/Windows/**'
|
||||
- 'pcsx2/USB/Win32/**'
|
||||
- 'pcsx2/windows/**'
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
paths-ignore:
|
||||
- '**/*.md'
|
||||
- '**/*.bat'
|
||||
- '**/*.cmd'
|
||||
- '**/*.props'
|
||||
- '**/*.sln'
|
||||
- '.clang-format'
|
||||
- '.codacy.yaml'
|
||||
- '.github/*'
|
||||
- '.github/workflows/lint-gamedb.yml'
|
||||
- '.github/workflows/linux-workflow.yml'
|
||||
- '.github/workflows/pr-triage.yml'
|
||||
- '.github/workflows/scripts/windows/**'
|
||||
- '.github/workflows/scripts/validation/**'
|
||||
- '.github/workflows/windows-workflow.yml'
|
||||
- '.gitignore'
|
||||
- 'bin/PCSX2_keys.ini.default'
|
||||
- 'build.sh'
|
||||
- 'buildbot.xml'
|
||||
- 'pcsx2/CDVD/Windows/**'
|
||||
- 'pcsx2/DEV9/Win32/**'
|
||||
- 'pcsx2/PAD/Windows/**'
|
||||
- 'pcsx2/SPU2/Windows/**'
|
||||
- 'pcsx2/USB/Win32/**'
|
||||
- 'pcsx2/windows/**'
|
||||
|
||||
jobs:
|
||||
build:
|
||||
strategy:
|
||||
# Prevent one build from failing everything (although maybe those should be included as experimental builds instead)
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [macos-11.0]
|
||||
platform: [x64]
|
||||
experimental: [false]
|
||||
|
||||
name: ${{ matrix.platform }}
|
||||
runs-on: ${{ matrix.os }}
|
||||
continue-on-error: ${{ matrix.experimental }}
|
||||
# Set some sort of timeout in the event of run-away builds. We are limited on concurrent jobs so, get rid of them.
|
||||
timeout-minutes: 30
|
||||
|
||||
steps:
|
||||
# NOTE - useful for debugging
|
||||
# - name: Dump GitHub context
|
||||
# env:
|
||||
# GITHUB_CONTEXT: ${{ toJson(github) }}
|
||||
# run: |
|
||||
# echo "$GITHUB_CONTEXT"
|
||||
# echo ${{ github.event.pull_request.title }}
|
||||
|
||||
- name: Checkout Repository
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Checkout Submodules
|
||||
run: git submodule update --init --recursive -j $(getconf _NPROCESSORS_ONLN)
|
||||
|
||||
- name: Install Packages
|
||||
env:
|
||||
PLATFORM: ${{ matrix.platform }}
|
||||
HOMEBREW_NO_INSTALL_CLEANUP: 1
|
||||
HOMEBREW_NO_ANALYTICS: 1
|
||||
run: |
|
||||
# To save time, only brew update if running the install without it fails
|
||||
function do-install() {
|
||||
brew install sound-touch portaudio wxmac gtk+3 sdl2 libsamplerate
|
||||
}
|
||||
if ! do-install; then
|
||||
brew update
|
||||
do-install
|
||||
fi
|
||||
|
||||
- name: Generate CMake Files
|
||||
run: cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_BUILD_PO=FALSE -DLTO_PCSX2_CORE=ON -B build .
|
||||
|
||||
- name: Build PCSX2
|
||||
working-directory: build
|
||||
run: make -j$(getconf _NPROCESSORS_ONLN) # macOS doesn't use make install
|
||||
|
||||
- name: Run Tests
|
||||
working-directory: build
|
||||
run: make -j$(getconf _NPROCESSORS_ONLN) unittests
|
||||
112
.github/workflows/macos_build.yml
vendored
Normal file
112
.github/workflows/macos_build.yml
vendored
Normal file
@@ -0,0 +1,112 @@
|
||||
name: MacOS Build Steps
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
jobName:
|
||||
required: true
|
||||
type: string
|
||||
os:
|
||||
required: false
|
||||
type: string
|
||||
default: macos-11.0
|
||||
platform:
|
||||
required: false
|
||||
type: string
|
||||
default: x64
|
||||
gui:
|
||||
required: true
|
||||
type: string
|
||||
|
||||
jobs:
|
||||
build_macos:
|
||||
name: ${{ inputs.jobName }}
|
||||
runs-on: ${{ inputs.os }}
|
||||
# Set some sort of timeout in the event of run-away builds. We are limited on concurrent jobs so, get rid of them.
|
||||
timeout-minutes: 90
|
||||
env:
|
||||
POWERSHELL_TELEMETRY_OPTOUT: 1
|
||||
BUILDCACHE_COMPRESS_FORMAT: ZSTD
|
||||
BUILDCACHE_COMPRESS_LEVEL: 9
|
||||
BUILDCACHE_MAX_CACHE_SIZE: 536870912 # 512MB
|
||||
BUILDCACHE_DIRECT_MODE: true
|
||||
BUILDCACHE_LOG_FILE: ${{ github.workspace }}\buildcache.log
|
||||
|
||||
steps:
|
||||
- name: Checkout Repository
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: Prepare Artifact Metadata
|
||||
id: artifact-metadata
|
||||
shell: bash
|
||||
env:
|
||||
OS: macos
|
||||
GUI_FRAMEWORK: ${{ inputs.gui }}
|
||||
ARCH: ${{ inputs.platform }}
|
||||
SIMD: ''
|
||||
EVENT_NAME: ${{ github.event_name }}
|
||||
PR_TITLE: ${{ github.event.pull_request.title }}
|
||||
PR_NUM: ${{ github.event.pull_request.number }}
|
||||
PR_SHA: ${{ github.event.pull_request.head.sha }}
|
||||
run: ./.github/workflows/scripts/common/name-artifacts.sh
|
||||
|
||||
- name: Install Packages
|
||||
env:
|
||||
PLATFORM: ${{ inputs.platform }}
|
||||
HOMEBREW_NO_INSTALL_CLEANUP: 1
|
||||
HOMEBREW_NO_ANALYTICS: 1
|
||||
run: |
|
||||
brew unlink libjpeg libpng # Conflicts with our self-built dependencies
|
||||
# Unlike other packages, brew's MoltenVK build uses MoltenVK's minimum macOS version of 10.13 so we can use it
|
||||
if ! brew install molten-vk; then
|
||||
brew update
|
||||
brew install molten-vk
|
||||
fi
|
||||
|
||||
- name: Cache Dependencies
|
||||
id: cache-deps
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: ~/deps
|
||||
key: ${{ inputs.os }} ${{ inputs.platform }} ${{ inputs.gui }} deps ${{ hashFiles('.github/workflows/scripts/macos/build-dependencies.sh') }}
|
||||
|
||||
- name: Build Dependencies
|
||||
if: steps.cache-deps.outputs.cache-hit != 'true'
|
||||
env:
|
||||
GUI: ${{ inputs.gui }}
|
||||
run: .github/workflows/scripts/macos/build-dependencies.sh
|
||||
|
||||
- name: Generate CMake Files
|
||||
run: |
|
||||
QT_BUILD=$([ "${{ inputs.gui }}" == "Qt" ] && echo "ON" || echo "OFF")
|
||||
cmake -DCMAKE_PREFIX_PATH="$HOME/deps" -DCMAKE_BUILD_TYPE=Release -DQT_BUILD="$QT_BUILD" -DUSE_OPENGL=OFF -DDISABLE_ADVANCE_SIMD=ON -DLTO_PCSX2_CORE=ON -DUSE_SYSTEM_LIBS=OFF -DUSE_SYSTEM_SDL2=ON -B build .
|
||||
|
||||
- name: Build PCSX2
|
||||
working-directory: build
|
||||
run: make -j$(getconf _NPROCESSORS_ONLN) # macOS doesn't use make install
|
||||
|
||||
- name: Run Tests
|
||||
working-directory: build
|
||||
run: make -j$(getconf _NPROCESSORS_ONLN) unittests
|
||||
|
||||
- name: Prepare Build Artifacts
|
||||
run: |
|
||||
cp /usr/local/lib/libMoltenVK.dylib build/pcsx2*/PCSX2.app/Contents/Frameworks/
|
||||
TAG="$(git tag --points-at HEAD)"
|
||||
if [ -z "$TAG" ]; then
|
||||
APPNAME="${{ steps.artifact-metadata.outputs.artifact-name }}"
|
||||
else
|
||||
APPNAME="PCSX2-$TAG"
|
||||
fi
|
||||
mv build/pcsx2*/PCSX2.app "$APPNAME.app"
|
||||
tar cvzf "${{ steps.artifact-metadata.outputs.artifact-name }}.tar.gz" "$APPNAME.app"
|
||||
mkdir ci-artifacts
|
||||
cp "${{ steps.artifact-metadata.outputs.artifact-name }}.tar.gz" ci-artifacts/macOS-${{ inputs.gui }}.tar.gz
|
||||
|
||||
- name: Upload Artifact
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: ${{ steps.artifact-metadata.outputs.artifact-name }}
|
||||
path: "*.tar.gz"
|
||||
25
.github/workflows/macos_build_matrix.yml
vendored
Normal file
25
.github/workflows/macos_build_matrix.yml
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
name: 🍎 MacOS Builds
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- '*'
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
|
||||
jobs:
|
||||
build_macos_wx:
|
||||
name: "Defaults"
|
||||
uses: ./.github/workflows/macos_build.yml
|
||||
with:
|
||||
jobName: "wxWidgets"
|
||||
gui: "wxWidgets"
|
||||
secrets: inherit
|
||||
build_macos_qt:
|
||||
name: "Defaults"
|
||||
uses: ./.github/workflows/macos_build.yml
|
||||
with:
|
||||
jobName: "Qt"
|
||||
gui: "Qt"
|
||||
secrets: inherit
|
||||
@@ -9,9 +9,9 @@ jobs:
|
||||
if: github.repository == 'PCSX2/pcsx2'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- uses: actions/setup-node@v2
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 16
|
||||
|
||||
@@ -25,23 +25,34 @@ jobs:
|
||||
cut-release:
|
||||
if: github.repository == 'PCSX2/pcsx2'
|
||||
runs-on: ubuntu-latest
|
||||
name: "Create Tag and Release"
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
# Docs - https://github.com/mathieudutour/github-tag-action
|
||||
# Workflows cannot trigger other workflows implicitly
|
||||
# - https://github.community/t/github-actions-workflow-not-triggering-with-tag-push/17053/7
|
||||
- name: Bump Version and Push Tag
|
||||
id: tag_version
|
||||
uses: mathieudutour/github-tag-action@v5.6
|
||||
uses: mathieudutour/github-tag-action@v6.0
|
||||
with:
|
||||
# Workflows cannot trigger other workflows implicitly
|
||||
# - https://github.community/t/github-actions-workflow-not-triggering-with-tag-push/17053/7
|
||||
github_token: ${{ secrets.BOT_PAT }}
|
||||
tag_prefix: v
|
||||
default_bump: patch
|
||||
|
||||
# Generate the Release Notes
|
||||
# TODO - we could do this and remove the node.js script, but auto-generated notes only work
|
||||
# with PRs -- not commits (determine how much we care).
|
||||
# - name: Create Draft Release
|
||||
# env:
|
||||
# GITHUB_TOKEN: ${{ secrets.BOT_PAT }}
|
||||
# run: |
|
||||
# echo "Creating release with tag - ${{ steps.tag_version.outputs.new_tag }}"
|
||||
# gh release create ${{ steps.tag_version.outputs.new_tag }} --draft --generate-notes -title ${{ steps.tag_version.outputs.new_tag }}
|
||||
|
||||
- name: Generate Release Notes
|
||||
env:
|
||||
OWNER: PCSX2
|
||||
REPO: pcsx2
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
COMMIT_SHA: ${{ github.SHA }}
|
||||
run: |
|
||||
@@ -49,9 +60,7 @@ jobs:
|
||||
npm ci
|
||||
node index.js
|
||||
mv ./release-notes.md ${GITHUB_WORKSPACE}/release-notes.md
|
||||
ls
|
||||
|
||||
# Docs - https://github.com/softprops/action-gh-release
|
||||
- name: Create a GitHub Release
|
||||
uses: softprops/action-gh-release@v1
|
||||
if: steps.tag_version.outputs.new_tag
|
||||
162
.github/workflows/release_pipeline.yml
vendored
Normal file
162
.github/workflows/release_pipeline.yml
vendored
Normal file
@@ -0,0 +1,162 @@
|
||||
name: 🏭 Release Pipeline
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- v*
|
||||
|
||||
jobs:
|
||||
# Build Everything
|
||||
# Linux
|
||||
build_gcc_lto:
|
||||
if: github.repository == 'PCSX2/pcsx2'
|
||||
name: "Linux - AppImage"
|
||||
uses: ./.github/workflows/linux_build_wx.yml
|
||||
with:
|
||||
jobName: "wxWidgets"
|
||||
compiler: gcc
|
||||
cmakeflags: "-DLTO_PCSX2_CORE=ON"
|
||||
buildAppImage: true
|
||||
secrets: inherit
|
||||
|
||||
build_linux_qt_sse4:
|
||||
if: github.repository == 'PCSX2/pcsx2'
|
||||
name: "Linux - AppImage SSE4"
|
||||
uses: ./.github/workflows/linux_build_qt.yml
|
||||
with:
|
||||
jobName: "Qt"
|
||||
compiler: clang
|
||||
cmakeflags: ""
|
||||
simd: "SSE4"
|
||||
buildAppImage: true
|
||||
secrets: inherit
|
||||
|
||||
build_linux_qt_avx2:
|
||||
if: github.repository == 'PCSX2/pcsx2'
|
||||
name: "Linux - AppImage AVX2"
|
||||
uses: ./.github/workflows/linux_build_qt.yml
|
||||
with:
|
||||
jobName: "Qt"
|
||||
detail: ""
|
||||
compiler: clang
|
||||
cmakeflags: "-DARCH_FLAG=-march=haswell"
|
||||
simd: "AVX2"
|
||||
buildAppImage: true
|
||||
secrets: inherit
|
||||
|
||||
# Windows
|
||||
build_wx_sse4:
|
||||
if: github.repository == 'PCSX2/pcsx2'
|
||||
name: "Windows - SSE4"
|
||||
uses: ./.github/workflows/windows_build_wx.yml
|
||||
with:
|
||||
jobName: wxWidgets
|
||||
configuration: Release
|
||||
simd: "SSE4"
|
||||
secrets: inherit
|
||||
|
||||
build_wx_avx2:
|
||||
if: github.repository == 'PCSX2/pcsx2'
|
||||
name: "Windows - AVX2"
|
||||
uses: ./.github/workflows/windows_build_wx.yml
|
||||
with:
|
||||
jobName: wxWidgets
|
||||
configuration: Release AVX2
|
||||
secrets: inherit
|
||||
|
||||
build_qt_sse4:
|
||||
if: github.repository == 'PCSX2/pcsx2'
|
||||
name: "Windows - SSE4"
|
||||
uses: ./.github/workflows/windows_build_qt.yml
|
||||
with:
|
||||
jobName: Qt
|
||||
configuration: Release
|
||||
simd: "SSE4"
|
||||
secrets: inherit
|
||||
|
||||
build_qt_avx2:
|
||||
if: github.repository == 'PCSX2/pcsx2'
|
||||
name: "Windows - AVX2"
|
||||
uses: ./.github/workflows/windows_build_qt.yml
|
||||
with:
|
||||
jobName: Qt
|
||||
configuration: Release AVX2
|
||||
secrets: inherit
|
||||
|
||||
# MacOS
|
||||
build_macos_wx:
|
||||
if: github.repository == 'PCSX2/pcsx2'
|
||||
name: "MacOS"
|
||||
uses: ./.github/workflows/macos_build.yml
|
||||
with:
|
||||
jobName: "wxWidgets"
|
||||
gui: "wxWidgets"
|
||||
secrets: inherit
|
||||
|
||||
build_macos_qt:
|
||||
if: github.repository == 'PCSX2/pcsx2'
|
||||
name: "MacOS"
|
||||
uses: ./.github/workflows/macos_build.yml
|
||||
with:
|
||||
jobName: "Qt"
|
||||
gui: "Qt"
|
||||
secrets: inherit
|
||||
|
||||
# Upload the Artifacts
|
||||
upload_artifacts:
|
||||
if: github.repository == 'PCSX2/pcsx2'
|
||||
needs:
|
||||
- build_gcc_lto
|
||||
- build_linux_qt_sse4
|
||||
- build_linux_qt_avx2
|
||||
- build_wx_sse4
|
||||
- build_wx_avx2
|
||||
- build_qt_sse4
|
||||
- build_qt_avx2
|
||||
- build_macos_wx
|
||||
- build_macos_qt
|
||||
name: "Upload Artifacts"
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Prepare Artifact Folder
|
||||
run: mkdir ./ci-artifacts/
|
||||
|
||||
- uses: actions/download-artifact@v3
|
||||
name: Download all Artifacts
|
||||
with:
|
||||
path: ./ci-artifacts/
|
||||
|
||||
- name: Display structure of downloaded files
|
||||
run: ls ./ci-artifacts/
|
||||
|
||||
# Prepare artifacts, they are all zips from github!
|
||||
- name: Prepare Artifacts
|
||||
working-directory: ./ci-artifacts/
|
||||
run: for d in *windows*/; do 7z a "${d}asset.7z" ./$d/*; done
|
||||
|
||||
# Artifact Naming:
|
||||
# MacOS: PCSX2-<tag>-macOS-[additional hyphen seperated tags]
|
||||
# Windows|Linux: PCSX2-<tag>-<windows|linux>-<32bit|64bit>--[additional hyphen seperated tags]
|
||||
- name: Name and Upload the Release Assets
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
TAG: ${{ github.REF }}
|
||||
SCAN_DIR: ${{ github.WORKSPACE }}/ci-artifacts
|
||||
OUT_DIR: ${{ github.WORKSPACE }}/ci-artifacts/out
|
||||
run: |
|
||||
gh release list --repo PCSX2/pcsx2
|
||||
mkdir -p ${{ github.WORKSPACE }}/ci-artifacts/out
|
||||
python ./.github/workflows/scripts/releases/rename-release-assets.py
|
||||
ls ${{ github.WORKSPACE }}/ci-artifacts/out
|
||||
TAG_VAL=$(echo ${{ github.REF }} | awk -F'refs/tags/' '{print $2}')
|
||||
gh release upload "${TAG_VAL}" ${{ github.WORKSPACE }}/ci-artifacts/out/* --repo PCSX2/pcsx2 --clobber
|
||||
|
||||
- name: Publish Release
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.BOT_PAT }}
|
||||
run: |
|
||||
TAG_VAL=$(echo ${{ github.REF }} | awk -F'refs/tags/' '{print $2}')
|
||||
gh release edit ${TAG_VAL} --draft=false --repo PCSX2/pcsx2
|
||||
|
||||
57
.github/workflows/scripts/common/name-artifacts.sh
vendored
Executable file
57
.github/workflows/scripts/common/name-artifacts.sh
vendored
Executable file
@@ -0,0 +1,57 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Artifact Naming Scheme:
|
||||
# PCSX2-<OS>-<GUI>-[ARCH]-[SIMD]-[pr\[PR_NUM\]]-[title|sha\[SHA|PR_TITLE\]
|
||||
# -- limited to 200 chars
|
||||
# Outputs:
|
||||
# - artifact-name
|
||||
|
||||
# Inputs as env-vars
|
||||
# OS
|
||||
# BUILD_SYSTEM
|
||||
# GUI_FRAMEWORK
|
||||
# ARCH
|
||||
# SIMD
|
||||
# EVENT_NAME
|
||||
# PR_TITLE
|
||||
# PR_NUM
|
||||
# PR_SHA
|
||||
|
||||
NAME=""
|
||||
|
||||
if [ "${OS}" == "macos" ]; then
|
||||
NAME="PCSX2-${OS}-${GUI_FRAMEWORK}"
|
||||
elif [[ "${OS}" == "windows" || ("$OS" == "linux" && "$GUI_FRAMEWORK" == "QT") ]]; then
|
||||
NAME="PCSX2-${OS}-${GUI_FRAMEWORK}-${ARCH}-${SIMD}"
|
||||
else
|
||||
NAME="PCSX2-${OS}-${GUI_FRAMEWORK}-${ARCH}"
|
||||
fi
|
||||
|
||||
# Add cmake if used to differentate it from msbuild builds
|
||||
# Else the two artifacts will have the same name and the files will be merged
|
||||
if [[ ! -z "${BUILD_SYSTEM}" ]]; then
|
||||
if [ "${BUILD_SYSTEM}" == "cmake" ]; then
|
||||
NAME="${NAME}-${BUILD_SYSTEM}"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Add PR / Commit Metadata
|
||||
if [ "$EVENT_NAME" == "pull_request" ]; then
|
||||
PR_SHA=$(git rev-parse --short "${PR_SHA}")
|
||||
if [ ! -z "${PR_NUM}" ]; then
|
||||
NAME="${NAME}-pr[${PR_NUM}]"
|
||||
fi
|
||||
NAME="${NAME}-sha[${PR_SHA}]"
|
||||
if [ ! -z "${PR_TITLE}" ]; then
|
||||
PR_TITLE=$(echo "${PR_TITLE}" | tr -cd '[a-zA-Z0-9[:space:]]_-')
|
||||
NAME="${NAME}-title[${PR_TITLE}"
|
||||
fi
|
||||
else
|
||||
SHA=$(git rev-parse --short "$GITHUB_SHA")
|
||||
NAME="${NAME}-sha[${SHA}"
|
||||
fi
|
||||
|
||||
# Trim the Name
|
||||
NAME=$(printf "%.199s]" "$NAME")
|
||||
echo "${NAME}"
|
||||
echo "##[set-output name=artifact-name;]${NAME}"
|
||||
1
.github/workflows/scripts/controller-db/.gitignore
vendored
Normal file
1
.github/workflows/scripts/controller-db/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
*.txt
|
||||
39
.github/workflows/scripts/controller-db/update-db.py
vendored
Normal file
39
.github/workflows/scripts/controller-db/update-db.py
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
import os
|
||||
|
||||
relevant_categories = [
|
||||
"# Windows",
|
||||
"# Mac OS X",
|
||||
"# Linux"
|
||||
]
|
||||
|
||||
header_lines = []
|
||||
new_db_contents = []
|
||||
|
||||
def is_relevant_category(line):
|
||||
for category in relevant_categories:
|
||||
if category in line:
|
||||
return True
|
||||
return False
|
||||
|
||||
with open("./game_controller_db.txt") as file:
|
||||
lines = file.readlines()
|
||||
finished_header = False
|
||||
processing_section = False
|
||||
for line in lines:
|
||||
if finished_header is False:
|
||||
header_lines.append(line)
|
||||
if line == "\n":
|
||||
finished_header = True
|
||||
if processing_section and line == "\n":
|
||||
processing_section = False
|
||||
new_db_contents.append("\n")
|
||||
if is_relevant_category(line) and processing_section is False:
|
||||
processing_section = True
|
||||
new_db_contents.append(line)
|
||||
elif processing_section:
|
||||
new_db_contents.append(line)
|
||||
|
||||
os.remove("./game_controller_db.txt")
|
||||
with open("./game_controller_db.txt", "w") as f:
|
||||
f.writelines(header_lines)
|
||||
f.writelines(new_db_contents)
|
||||
@@ -1,7 +1,8 @@
|
||||
import os
|
||||
import yaml
|
||||
|
||||
# Assumes this is ran from the root of the repository
|
||||
file_path = "./bin/GameIndex.yaml"
|
||||
file_path = os.environ['GAMEDB_PATH']
|
||||
|
||||
# These settings have to be manually kept in sync with the emulator code unfortunately.
|
||||
# up to date validation should ALWAYS be provided via the application!
|
||||
@@ -12,6 +13,7 @@ allowed_game_options = [
|
||||
"roundModes",
|
||||
"clampModes",
|
||||
"gameFixes",
|
||||
"gsHWFixes",
|
||||
"speedHacks",
|
||||
"memcardFilters",
|
||||
"patches",
|
||||
@@ -19,24 +21,59 @@ allowed_game_options = [
|
||||
allowed_round_modes = ["eeRoundMode", "vuRoundMode"]
|
||||
allowed_clamp_modes = ["eeClampMode", "vuClampMode"]
|
||||
allowed_game_fixes = [
|
||||
"VuAddSubHack",
|
||||
"FpuCompareHack",
|
||||
"FpuMulHack",
|
||||
"FpuNegDivHack",
|
||||
"XGKickHack",
|
||||
"EETimingHack",
|
||||
"GoemonTlbHack",
|
||||
"SoftwareRendererFMVHack",
|
||||
"SkipMPEGHack",
|
||||
"OPHFlagHack",
|
||||
"EETimingHack",
|
||||
"DMABusyHack",
|
||||
"GIFFIFOHack",
|
||||
"VIFFIFOHack",
|
||||
"VIF1StallHack",
|
||||
"GIFFIFOHack",
|
||||
"GoemonTlbHack",
|
||||
"VUKickstartHack",
|
||||
"VuAddSubHack",
|
||||
"IbitHack",
|
||||
"VUSyncHack",
|
||||
"VUOverflowHack",
|
||||
"XGKickHack",
|
||||
"BlitInternalFPSHack",
|
||||
]
|
||||
allowed_speed_hacks = ["mvuFlagSpeedHack", "InstantVU1SpeedHack"]
|
||||
allowed_gs_hw_fixes = [
|
||||
"autoFlush",
|
||||
"conservativeFramebuffer",
|
||||
"cpuFramebufferConversion",
|
||||
"disableDepthSupport",
|
||||
"wrapGSMem",
|
||||
"preloadFrameData",
|
||||
"disablePartialInvalidation",
|
||||
"textureInsideRT",
|
||||
"alignSprite",
|
||||
"mergeSprite",
|
||||
"wildArmsHack",
|
||||
"pointListPalette",
|
||||
"mipmap",
|
||||
"trilinearFiltering",
|
||||
"skipDrawStart",
|
||||
"skipDrawEnd",
|
||||
"halfBottomOverride",
|
||||
"halfPixelOffset",
|
||||
"roundSprite",
|
||||
"texturePreloading",
|
||||
"deinterlace",
|
||||
"cpuSpriteRenderBW",
|
||||
]
|
||||
gs_hw_fix_ranges = {
|
||||
"mipmap": (0, 2),
|
||||
"trilinearFiltering": (0, 2),
|
||||
"skipDrawStart": (0, 100000),
|
||||
"skipDrawEnd": (0, 100000),
|
||||
"halfPixelOffset": (0, 3),
|
||||
"roundSprite": (0, 2),
|
||||
"deinterlace": (0, 7),
|
||||
"cpuSpriteRenderBW": (1, 10),
|
||||
}
|
||||
allowed_speed_hacks = ["mvuFlagSpeedHack", "InstantVU1SpeedHack", "MTVUSpeedHack"]
|
||||
# Patches are allowed to have a 'default' key or a crc-32 key, followed by
|
||||
allowed_patch_options = ["author", "content"]
|
||||
|
||||
@@ -94,6 +131,29 @@ def validate_game_fixes(serial, key, value):
|
||||
validate_valid_options(serial, key, gamefix, allowed_game_fixes)
|
||||
|
||||
|
||||
def validate_gs_hw_fix_value(serial, key, value):
|
||||
low, high = 0, 1
|
||||
if key in gs_hw_fix_ranges:
|
||||
low, high = gs_hw_fix_ranges[key]
|
||||
validate_int_option(serial, key, value, low, high)
|
||||
|
||||
|
||||
def validate_gs_hw_fixes(serial, key, value):
|
||||
if not isinstance(value, dict):
|
||||
issue_list.append("[{}]: 'gsHWFixes' must be a valid object".format(serial))
|
||||
return
|
||||
for fix, fix_value in value.items():
|
||||
validate_valid_options(serial, key, fix, allowed_gs_hw_fixes)
|
||||
validate_gs_hw_fix_value(serial, fix, fix_value)
|
||||
|
||||
# skipdraw range must have end >= start
|
||||
skip_draw_start = value["skipDrawStart"] if "skipDrawStart" in value else 0
|
||||
skip_draw_end = value["skipDrawEnd"] if "skipDrawEnd" in value else 0
|
||||
if isinstance(skip_draw_start, int) and isinstance(skip_draw_end, int) and skip_draw_end < skip_draw_start:
|
||||
issue_list.append("[{}]: skipDrawStart({}) must be greater or equal to skipDrawEnd({})".format(
|
||||
serial, skip_draw_start, skip_draw_end))
|
||||
|
||||
|
||||
def validate_speed_hacks(serial, key, value):
|
||||
if not isinstance(value, dict):
|
||||
issue_list.append("[{}]: 'speedHacks' must be a valid object".format(serial))
|
||||
@@ -145,6 +205,7 @@ option_validation_handlers = {
|
||||
)
|
||||
),
|
||||
"gameFixes": (lambda serial, key, value: validate_game_fixes(serial, key, value)),
|
||||
"gsHWFixes": (lambda serial, key, value: validate_gs_hw_fixes(serial, key, value)),
|
||||
"speedHacks": (lambda serial, key, value: validate_speed_hacks(serial, key, value)),
|
||||
"memcardFilters": (
|
||||
lambda serial, key, value: validate_list_of_strings(serial, key, value)
|
||||
@@ -152,11 +213,21 @@ option_validation_handlers = {
|
||||
"patches": (lambda serial, key, value: validate_patches(serial, key, value)),
|
||||
}
|
||||
|
||||
class UniqueKeyLoader(yaml.FullLoader):
|
||||
def construct_mapping(self, node, deep=False):
|
||||
mapping = set()
|
||||
for key_node, _ in node.value:
|
||||
key = self.construct_object(key_node, deep=deep)
|
||||
if key in mapping:
|
||||
raise ValueError(f"Duplicate {key!r} key found in YAML.")
|
||||
mapping.add(key)
|
||||
return super().construct_mapping(node, deep)
|
||||
|
||||
print("Opening {}...".format(file_path))
|
||||
with open(file_path) as f:
|
||||
with open(file_path, encoding="utf-8") as f:
|
||||
try:
|
||||
print("Attempting to parse GameDB file...")
|
||||
gamedb = yaml.load(f, Loader=yaml.FullLoader)
|
||||
gamedb = yaml.load(f, Loader=UniqueKeyLoader)
|
||||
except Exception as err:
|
||||
print(err)
|
||||
print(
|
||||
14
.github/workflows/scripts/linux/AppRun
vendored
14
.github/workflows/scripts/linux/AppRun
vendored
@@ -1,15 +1,3 @@
|
||||
#!/bin/bash
|
||||
|
||||
export LD_LIBRARY_PATH="$APPDIR/usr/lib:$LD_LIBRARY_PATH"
|
||||
BINARY_NAME=$(basename "$ARGV0")
|
||||
if [[ ! -e "$PWD/$BINARY_NAME.config" ]]; then
|
||||
mkdir "$PWD/$BINARY_NAME.config"
|
||||
fi
|
||||
export XDG_CONFIG_HOME="$PWD/$BINARY_NAME.config"
|
||||
|
||||
ln -sf $APPDIR/usr/bin/app /tmp/PCSX2
|
||||
mkdir -p $HOME/.local/share/icons/hicolor/scalable/apps && cp $APPDIR/PCSX2.png $HOME/.local/share/icons/hicolor/scalable/apps
|
||||
|
||||
$APPDIR/AppRun-patched
|
||||
|
||||
unlink /tmp/PCSX2
|
||||
$APPDIR/AppRun-patched "$@"
|
||||
|
||||
4
.github/workflows/scripts/linux/AppRun-qt
vendored
Executable file
4
.github/workflows/scripts/linux/AppRun-qt
vendored
Executable file
@@ -0,0 +1,4 @@
|
||||
#!/bin/sh
|
||||
|
||||
cd "$(dirname "$0")"
|
||||
exec ./usr/bin/pcsx2-qt "$@"
|
||||
16
.github/workflows/scripts/linux/app-variables.sh
vendored
Normal file
16
.github/workflows/scripts/linux/app-variables.sh
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
#!/bin/bash
|
||||
|
||||
export LD_LIBRARY_PATH="$APPDIR/usr/lib:$LD_LIBRARY_PATH"
|
||||
|
||||
# use system wayland if available otherwise use the appimage provided wayland
|
||||
if [[ $(ldconfig -p | grep libwayland-client | wc -l) -lt 1 ]]; then
|
||||
export LD_LIBRARY_PATH="$APPDIR/usr/lib/wayland:$LD_LIBRARY_PATH"
|
||||
fi
|
||||
|
||||
export BINARY_NAME=$(basename "$ARGV0")
|
||||
if [[ ! -e "$PWD/$BINARY_NAME.config" ]]; then
|
||||
mkdir "$PWD/$BINARY_NAME.config"
|
||||
fi
|
||||
export XDG_CONFIG_HOME="$PWD/$BINARY_NAME.config"
|
||||
|
||||
mkdir -p "$HOME"/.local/share/icons/hicolor/scalable/apps && cp "$APPDIR"/PCSX2.png "$HOME"/.local/share/icons/hicolor/scalable/apps
|
||||
253
.github/workflows/scripts/linux/appimage-qt.sh
vendored
Executable file
253
.github/workflows/scripts/linux/appimage-qt.sh
vendored
Executable file
@@ -0,0 +1,253 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# This is free and unencumbered software released into the public domain.
|
||||
#
|
||||
# Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||
# distribute this software, either in source code form or as a compiled
|
||||
# binary, for any purpose, commercial or non-commercial, and by any
|
||||
# means.
|
||||
#
|
||||
# In jurisdictions that recognize copyright laws, the author or authors
|
||||
# of this software dedicate any and all copyright interest in the
|
||||
# software to the public domain. We make this dedication for the benefit
|
||||
# of the public at large and to the detriment of our heirs and
|
||||
# successors. We intend this dedication to be an overt act of
|
||||
# relinquishment in perpetuity of all present and future rights to this
|
||||
# software under copyright law.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
# IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
# OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
# For more information, please refer to <http://unlicense.org/>
|
||||
|
||||
if [ "$#" -ne 3 ]; then
|
||||
echo "Syntax: $0 <path to PCSX2 directory> <deps prefix> <output name>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
PCSX2DIR=$1
|
||||
DEPSDIR=$2
|
||||
NAME=$3
|
||||
|
||||
BINDIR="$PCSX2DIR/bin"
|
||||
|
||||
BINARY=pcsx2-qt
|
||||
APPDIRNAME=PCSX2.AppDir
|
||||
STRIP=llvm-strip-12
|
||||
|
||||
declare -a SYSLIBS=(
|
||||
"libaio.so.1"
|
||||
"libz.so.1"
|
||||
"libuuid.so.1"
|
||||
"libapparmor.so.1"
|
||||
"libblkid.so.1"
|
||||
"libbsd.so.0"
|
||||
"libdbus-1.so.3"
|
||||
"libgcrypt.so.20"
|
||||
"liblzma.so.5"
|
||||
"libmount.so.1"
|
||||
"libnsl.so.1"
|
||||
"libpcre.so.3"
|
||||
"libselinux.so.1"
|
||||
"libsystemd.so.0"
|
||||
"libudev.so.1"
|
||||
"libwrap.so.0"
|
||||
"libharfbuzz.so.0"
|
||||
"libFLAC.so.8"
|
||||
"libSoundTouch.so.1"
|
||||
"libXau.so.6"
|
||||
"libXcomposite.so.1"
|
||||
"libXcursor.so.1"
|
||||
"libXdamage.so.1"
|
||||
"libXdmcp.so.6"
|
||||
"libXext.so.6"
|
||||
"libXfixes.so.3"
|
||||
"libXi.so.6"
|
||||
"libXinerama.so.1"
|
||||
"libXrandr.so.2"
|
||||
"libXrender.so.1"
|
||||
"libXxf86vm.so.1"
|
||||
"libasyncns.so.0"
|
||||
"libcrypto.so.1.1"
|
||||
"libjpeg.so.8"
|
||||
"liblz4.so.1"
|
||||
"libogg.so.0"
|
||||
"libpcap.so.0.8"
|
||||
"libpng16.so.16"
|
||||
"libpulse.so.0"
|
||||
"libsamplerate.so.0"
|
||||
"libsndfile.so.1"
|
||||
"libvorbis.so.0"
|
||||
"libvorbisenc.so.2"
|
||||
"libxcb.so.1"
|
||||
"libxcb-render.so.0"
|
||||
"libxcb-shm.so.0"
|
||||
"libxkbcommon.so.0"
|
||||
"libxkbcommon-x11.so.0"
|
||||
"pulseaudio/libpulsecommon-13.99.so"
|
||||
"libfreetype.so.6"
|
||||
"libpcre2-16.so.0"
|
||||
"libexpat.so.1"
|
||||
"libffi.so.7"
|
||||
"libgraphite2.so.3"
|
||||
"libresolv.so.2"
|
||||
"libgpg-error.so.0"
|
||||
"libpcre2-16.so.0"
|
||||
"libpng16.so.16"
|
||||
"libxcb-icccm.so.4"
|
||||
"libxcb-image.so.0"
|
||||
"libxcb-keysyms.so.1"
|
||||
"libxcb-randr.so.0"
|
||||
"libxcb-render.so.0"
|
||||
"libxcb-render-util.so.0"
|
||||
"libxcb-shape.so.0"
|
||||
"libxcb-sync.so.1"
|
||||
"libxcb-util.so.1"
|
||||
"libxcb-xfixes.so.0"
|
||||
"libxcb-xkb.so.1"
|
||||
"libevdev.so.2"
|
||||
"libgudev-1.0.so.0"
|
||||
"libinput.so.10"
|
||||
"libjpeg.so.8"
|
||||
"libmtdev.so.1"
|
||||
"libpng16.so.16"
|
||||
"libudev.so.1"
|
||||
"libuuid.so.1"
|
||||
)
|
||||
|
||||
declare -a DEPLIBS=(
|
||||
"libSDL2-2.0.so.0"
|
||||
)
|
||||
|
||||
declare -a QTLIBS=(
|
||||
"libQt6Core.so.6"
|
||||
"libQt6Gui.so.6"
|
||||
"libQt6Network.so.6"
|
||||
"libQt6OpenGL.so.6"
|
||||
"libQt6Svg.so.6"
|
||||
"libQt6WaylandClient.so.6"
|
||||
"libQt6WaylandCompositor.so.6"
|
||||
"libQt6WaylandEglClientHwIntegration.so.6"
|
||||
"libQt6WaylandEglCompositorHwIntegration.so.6"
|
||||
"libQt6Widgets.so.6"
|
||||
"libQt6XcbQpa.so.6"
|
||||
)
|
||||
|
||||
declare -a QTPLUGINS=(
|
||||
"plugins/iconengines"
|
||||
"plugins/imageformats"
|
||||
"plugins/platforms"
|
||||
#"plugins/platformthemes" # Enable this if we want to ship GTK+ themes at any point.
|
||||
"plugins/wayland-decoration-client"
|
||||
"plugins/wayland-graphics-integration-client"
|
||||
"plugins/wayland-graphics-integration-server"
|
||||
"plugins/wayland-shell-integration"
|
||||
"plugins/xcbglintegrations"
|
||||
)
|
||||
|
||||
set -e
|
||||
|
||||
if [ ! -f appimagetool-x86_64.AppImage ]; then
|
||||
wget https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-x86_64.AppImage
|
||||
chmod +x appimagetool-x86_64.AppImage
|
||||
fi
|
||||
|
||||
OUTDIR=$(realpath "./$APPDIRNAME")
|
||||
SCRIPTDIR=$(dirname "${BASH_SOURCE[0]}")
|
||||
rm -fr "$OUTDIR"
|
||||
mkdir "$OUTDIR"
|
||||
|
||||
mkdir -p "$OUTDIR/usr/bin" "$OUTDIR/usr/lib" "$OUTDIR/usr/lib/pulseaudio"
|
||||
|
||||
echo "Copying binary and resources..."
|
||||
cp -a "$BINDIR/$BINARY" "$BINDIR/resources" "$BINDIR/shaders" "$OUTDIR/usr/bin"
|
||||
|
||||
# Don't need old wx locales.
|
||||
rm -fr "$OUTDIR/usr/bin/resources/locale"
|
||||
|
||||
# Patch RPATH so the binary goes hunting for shared libraries in the AppDir instead of system.
|
||||
echo "Patching RPATH in ${BINARY}..."
|
||||
patchelf --set-rpath '$ORIGIN/../lib' "$OUTDIR/usr/bin/$BINARY"
|
||||
|
||||
# Currently we leave the main binary unstripped, uncomment if this is not desired.
|
||||
#$STRIP "$OUTDIR/usr/bin/$BINARY"
|
||||
|
||||
# Libraries we pull in from the system.
|
||||
echo "Copying system libraries..."
|
||||
for lib in "${SYSLIBS[@]}"; do
|
||||
blib=$(basename "$lib")
|
||||
if [ -f "/lib/x86_64-linux-gnu/$lib" ]; then
|
||||
cp "/lib/x86_64-linux-gnu/$lib" "$OUTDIR/usr/lib/$blib"
|
||||
elif [ -f "$CHROOT/usr/lib/x86_64-linux-gnu/$lib" ]; then
|
||||
cp "$CHROOT/usr/lib/x86_64-linux-gnu/$lib" "$OUTDIR/usr/lib/$blib"
|
||||
elif [ -f "$CHROOT/lib/$lib" ]; then
|
||||
cp "$CHROOT/lib/$lib" "$OUTDIR/usr/lib/$blib"
|
||||
elif [ -f "$CHROOT/usr/lib/$lib" ]; then
|
||||
cp "$CHROOT/usr/lib/$lib" "$OUTDIR/usr/lib/$blib"
|
||||
else
|
||||
echo "*** Failed to find '$blib'"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
$STRIP "$OUTDIR/usr/lib/$blib"
|
||||
done
|
||||
|
||||
# Dependencies we built, at this point it's just SDL.
|
||||
echo "Copying dependency libraries..."
|
||||
for lib in "${DEPLIBS[@]}"; do
|
||||
blib=$(basename "$lib")
|
||||
if [ -f "$DEPSDIR/lib/$lib" ]; then
|
||||
cp "$DEPSDIR/lib/$lib" "$OUTDIR/usr/lib/$blib"
|
||||
else
|
||||
echo "*** Failed to find '$blib'"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
$STRIP "$OUTDIR/usr/lib/$blib"
|
||||
done
|
||||
|
||||
echo "Copying Qt libraries..."
|
||||
for lib in "${QTLIBS[@]}"; do
|
||||
cp -aL "$DEPSDIR/lib/$lib" "$OUTDIR/usr/lib"
|
||||
$STRIP "$OUTDIR/usr/lib/$lib"
|
||||
done
|
||||
|
||||
echo "Copying Qt plugins..."
|
||||
mkdir -p "$OUTDIR/usr/lib/plugins"
|
||||
for plugin in "${QTPLUGINS[@]}"; do
|
||||
mkdir -p "$OUTDIR/usr/lib/$plugin"
|
||||
cp -aL "$DEPSDIR/$plugin"/*.so "$OUTDIR/usr/lib/$plugin/"
|
||||
done
|
||||
|
||||
for so in $(find "$OUTDIR/usr/lib/plugins" -iname '*.so'); do
|
||||
# This is ../../ because it's usually plugins/group/name.so
|
||||
echo "Patching RPATH in ${so}..."
|
||||
patchelf --set-rpath '$ORIGIN/../..' "$so"
|
||||
$STRIP "$so"
|
||||
done
|
||||
|
||||
for so in $(find "$OUTDIR/usr/lib" -maxdepth 1); do
|
||||
if [ -f "$so" ]; then
|
||||
echo "Patching RPATH in ${so}"
|
||||
patchelf --set-rpath '$ORIGIN' "$so"
|
||||
fi
|
||||
done
|
||||
|
||||
echo "Creating qt.conf..."
|
||||
cat > "$OUTDIR/usr/bin/qt.conf" << EOF
|
||||
[Paths]
|
||||
Plugins = ../lib/plugins
|
||||
EOF
|
||||
|
||||
echo "Copy desktop/icon..."
|
||||
cp "$PCSX2DIR/pcsx2/gui/Resources/AppIcon64.png" "$OUTDIR/PCSX2.png"
|
||||
cp "$SCRIPTDIR/pcsx2-qt.desktop" "$OUTDIR/PCSX2.desktop"
|
||||
cp "$SCRIPTDIR/AppRun-qt" "$OUTDIR/AppRun"
|
||||
|
||||
echo "Generate AppImage"
|
||||
./appimagetool-x86_64.AppImage -v "$OUTDIR" "$NAME.AppImage"
|
||||
34
.github/workflows/scripts/linux/appimage.sh
vendored
34
.github/workflows/scripts/linux/appimage.sh
vendored
@@ -12,8 +12,6 @@ else
|
||||
ARCH="x86_64"
|
||||
LIBARCH="x86_64-linux-gnu"
|
||||
fi
|
||||
BUILDPATH="$GITHUB_WORKSPACE"/build
|
||||
BUILDBIN="$BUILDPATH"/pcsx2
|
||||
cd /tmp
|
||||
curl -sSfLO "https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-$ARCH.AppImage"
|
||||
chmod a+x linuxdeploy*.AppImage
|
||||
@@ -23,10 +21,7 @@ chmod a+x /tmp/squashfs-root/usr/bin/linuxdeploy-plugin-gtk.sh
|
||||
mv /tmp/squashfs-root/usr/bin/patchelf /tmp/squashfs-root/usr/bin/patchelf.orig
|
||||
sudo cp /usr/local/bin/patchelf /tmp/squashfs-root/usr/bin/patchelf
|
||||
cd "$GITHUB_WORKSPACE"
|
||||
mkdir -p squashfs-root/usr/bin
|
||||
ls -al "$BUILDBIN"
|
||||
cp -P "$BUILDBIN"/PCSX2 "$GITHUB_WORKSPACE"/squashfs-root/usr/bin/
|
||||
patchelf --set-rpath /tmp/PCSX2 "$GITHUB_WORKSPACE"/squashfs-root/usr/bin/PCSX2
|
||||
ninja -C build install
|
||||
cp ./pcsx2/gui/Resources/AppIcon64.png ./squashfs-root/PCSX2.png
|
||||
cp ./linux_various/PCSX2.desktop.in ./squashfs-root/PCSX2.desktop
|
||||
sed -i -e 's|Categories=@PCSX2_MENU_CATEGORIES@|Categories=Game;Emulator;|g' ./squashfs-root/PCSX2.desktop
|
||||
@@ -37,21 +32,32 @@ mkdir -p squashfs-root/usr/share/icons && cp ./squashfs-root/PCSX2.png ./squashf
|
||||
mkdir -p squashfs-root/usr/share/icons/hicolor/scalable/apps && cp ./squashfs-root/PCSX2.png ./squashfs-root/usr/share/icons/hicolor/scalable/apps
|
||||
mkdir -p squashfs-root/usr/share/pixmaps && cp ./squashfs-root/PCSX2.png ./squashfs-root/usr/share/pixmaps
|
||||
mkdir -p squashfs-root/usr/lib/
|
||||
mkdir -p squashfs-root/usr/optional/libstdc++
|
||||
mkdir -p squashfs-root/usr/optional/libgcc_s
|
||||
cp ./.github/workflows/scripts/linux/AppRun "$GITHUB_WORKSPACE"/squashfs-root/AppRun
|
||||
curl -sSfL "https://github.com/AppImage/AppImageKit/releases/download/continuous/AppRun-$APPARCH" -o "$GITHUB_WORKSPACE"/squashfs-root/AppRun-patched
|
||||
curl -sSfL "https://github.com/PCSX2/appimage-checkrt-branch/releases/download/AppImage-checkrt/AppRun_patched" -o "$GITHUB_WORKSPACE"/squashfs-root/AppRun-patched
|
||||
curl -sSfL "https://github.com/PCSX2/appimage-checkrt-branch/releases/download/AppImage-checkrt/exec.so" -o "$GITHUB_WORKSPACE"/squashfs-root/usr/optional/exec.so
|
||||
chmod a+x ./squashfs-root/AppRun
|
||||
chmod a+x ./squashfs-root/runtime
|
||||
chmod a+x ./squashfs-root/AppRun-patched
|
||||
chmod a+x ./squashfs-root/usr/optional/exec.so
|
||||
echo "$name" > "$GITHUB_WORKSPACE"/squashfs-root/version.txt
|
||||
mkdir -p "$GITHUB_WORKSPACE"/squashfs-root/usr/bin/app
|
||||
cp -r "$GITHUB_WORKSPACE"/bin/Langs "$GITHUB_WORKSPACE"/squashfs-root/usr/bin/
|
||||
cp "$GITHUB_WORKSPACE"/bin/docs/{Configuration_Guide.pdf,PCSX2_FAQ.pdf} "$GITHUB_WORKSPACE"/squashfs-root/usr/bin/app
|
||||
cp "$GITHUB_WORKSPACE"/bin/cheats_ws.zip "$GITHUB_WORKSPACE"/squashfs-root/usr/bin/app
|
||||
cp ./bin/GameIndex.yaml "$GITHUB_WORKSPACE"/squashfs-root/usr/bin/app/GameIndex.yaml
|
||||
mkdir -p "$GITHUB_WORKSPACE"/squashfs-root/apprun-hooks
|
||||
cp /usr/lib/$LIBARCH/libthai.so.0 "$GITHUB_WORKSPACE"/squashfs-root/usr/lib/
|
||||
cp --dereference /usr/lib/"$LIBARCH"/libstdc++.so.6 "$GITHUB_WORKSPACE"/squashfs-root/usr/optional/libstdc++/libstdc++.so.6
|
||||
cp --dereference /lib/"$LIBARCH"/libgcc_s.so.1 "$GITHUB_WORKSPACE"/squashfs-root/usr/optional/libgcc_s/libgcc_s.so.1
|
||||
chmod +x .github/workflows/scripts/linux/app-variables.sh
|
||||
cp .github/workflows/scripts/linux/app-variables.sh "$GITHUB_WORKSPACE"/squashfs-root/apprun-hooks
|
||||
export UPD_INFO="gh-releases-zsync|PCSX2|pcsx2|latest|$name.AppImage.zsync"
|
||||
export OUTPUT="$name.AppImage"
|
||||
/tmp/squashfs-root/AppRun --appdir="$GITHUB_WORKSPACE"/squashfs-root/ --plugin gtk -d "$GITHUB_WORKSPACE"/squashfs-root/PCSX2.desktop -i "$GITHUB_WORKSPACE"/squashfs-root/PCSX2.png --output appimage
|
||||
/tmp/squashfs-root/AppRun --appdir="$GITHUB_WORKSPACE"/squashfs-root/ --plugin gtk -d "$GITHUB_WORKSPACE"/squashfs-root/PCSX2.desktop -i "$GITHUB_WORKSPACE"/squashfs-root/PCSX2.png
|
||||
# see LD_LIBRARY_PATH in app-variables.sh - the intent is to use system wayland if available but fall back to app-image provided
|
||||
# a little bit hacky but should ensure maximum compatibility
|
||||
mkdir -p squashfs-root/usr/lib/wayland
|
||||
mv squashfs-root/usr/lib/libwayland-* squashfs-root/usr/lib/wayland
|
||||
rm squashfs-root/usr/lib/libgmodule-2.0.so.0
|
||||
curl -sSfL "https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-$ARCH.AppImage" -o ./appimagetool-"$ARCH".AppImage
|
||||
chmod a+x appimagetool*.AppImage
|
||||
./appimagetool-"$ARCH".AppImage "$GITHUB_WORKSPACE"/squashfs-root "$name.AppImage"
|
||||
mkdir -p "$GITHUB_WORKSPACE"/ci-artifacts/
|
||||
ls -al .
|
||||
mv "$name.AppImage" "$GITHUB_WORKSPACE"/ci-artifacts # && mv "$name.AppImage.zsync" "$GITHUB_WORKSPACE"/ci-artifacts
|
||||
|
||||
125
.github/workflows/scripts/linux/build-dependencies-qt.sh
vendored
Executable file
125
.github/workflows/scripts/linux/build-dependencies-qt.sh
vendored
Executable file
@@ -0,0 +1,125 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
|
||||
INSTALLDIR="$HOME/deps"
|
||||
NPROCS="$(getconf _NPROCESSORS_ONLN)"
|
||||
SDL=SDL2-2.0.22
|
||||
QT=6.3.1
|
||||
|
||||
mkdir -p deps-build
|
||||
cd deps-build
|
||||
|
||||
cat > SHASUMS <<EOF
|
||||
fe7cbf3127882e3fc7259a75a0cb585620272c51745d3852ab9dd87960697f2e $SDL.tar.gz
|
||||
0a64421d9c2469c2c48490a032ab91d547017c9cc171f3f8070bc31888f24e03 qtbase-everywhere-src-$QT.tar.xz
|
||||
7b19f418e6f7b8e23344082dd04440aacf5da23c5a73980ba22ae4eba4f87df7 qtsvg-everywhere-src-$QT.tar.xz
|
||||
c412750f2aa3beb93fce5f30517c607f55daaeb7d0407af206a8adf917e126c1 qttools-everywhere-src-$QT.tar.xz
|
||||
d7bdd55e2908ded901dcc262157100af2a490bf04d31e32995f6d91d78dfdb97 qttranslations-everywhere-src-$QT.tar.xz
|
||||
6f14fea2d172a5b4170be3efcb0e58535f6605b61bcd823f6d5c9d165bb8c0f0 qtwayland-everywhere-src-$QT.tar.xz
|
||||
EOF
|
||||
|
||||
curl -L \
|
||||
-O "https://libsdl.org/release/$SDL.tar.gz" \
|
||||
-O "https://download.qt.io/official_releases/qt/${QT%.*}/$QT/submodules/qtbase-everywhere-src-$QT.tar.xz" \
|
||||
-O "https://download.qt.io/official_releases/qt/${QT%.*}/$QT/submodules/qtsvg-everywhere-src-$QT.tar.xz" \
|
||||
-O "https://download.qt.io/official_releases/qt/${QT%.*}/$QT/submodules/qttools-everywhere-src-$QT.tar.xz" \
|
||||
-O "https://download.qt.io/official_releases/qt/${QT%.*}/$QT/submodules/qttranslations-everywhere-src-$QT.tar.xz" \
|
||||
-O "https://download.qt.io/official_releases/qt/${QT%.*}/$QT/submodules/qtwayland-everywhere-src-$QT.tar.xz"
|
||||
|
||||
shasum -a 256 --check SHASUMS
|
||||
|
||||
echo "Building SDL..."
|
||||
tar xf "$SDL.tar.gz"
|
||||
cd "$SDL"
|
||||
./configure --prefix "$INSTALLDIR" --disable-dbus --without-x --disable-video-opengl --disable-video-opengles --disable-video-vulkan --disable-wayland-shared --disable-ime --disable-oss --disable-alsa --disable-jack --disable-esd --disable-pipewire --disable-pulseaudio --disable-arts --disable-nas --disable-sndio --disable-fusionsound --disable-diskaudio
|
||||
make "-j$NPROCS"
|
||||
make install
|
||||
cd ..
|
||||
|
||||
# Couple notes:
|
||||
# -fontconfig is needed otherwise Qt Widgets render only boxes.
|
||||
# -qt-doubleconversion avoids a dependency on libdouble-conversion.
|
||||
# ICU avoids pulling in a bunch of large libraries, and hopefully we can get away without it.
|
||||
# OpenGL is needed to render window decorations in Wayland, apparently.
|
||||
echo "Building Qt Base..."
|
||||
tar xf "qtbase-everywhere-src-$QT.tar.xz"
|
||||
cd "qtbase-everywhere-src-$QT"
|
||||
mkdir build
|
||||
cd build
|
||||
../configure -prefix "$INSTALLDIR" -release -no-dbus -gui -widgets -fontconfig -qt-doubleconversion -openssl-runtime -opengl desktop -qpa xcb,wayland -xkbcommon -- -DFEATURE_dbus=OFF -DFEATURE_icu=OFF -DFEATURE_printsupport=OFF -DFEATURE_sql=OFF
|
||||
cmake --build . --parallel
|
||||
cmake --install .
|
||||
cd ../../
|
||||
|
||||
echo "Building Qt SVG..."
|
||||
tar xf "qtsvg-everywhere-src-$QT.tar.xz"
|
||||
cd "qtsvg-everywhere-src-$QT"
|
||||
mkdir build
|
||||
cd build
|
||||
cmake -G Ninja -DCMAKE_PREFIX_PATH="$INSTALLDIR" -DCMAKE_INSTALL_PREFIX="$INSTALLDIR" -DCMAKE_BUILD_TYPE=Release ..
|
||||
cmake --build . --parallel
|
||||
cmake --install .
|
||||
cd ../../
|
||||
|
||||
echo "Building Qt Wayland..."
|
||||
tar xf "qtwayland-everywhere-src-$QT.tar.xz"
|
||||
cd "qtwayland-everywhere-src-$QT"
|
||||
# qtwayland does not build without qml/qtdeclarative in 6.3.1. Work around it.
|
||||
patch -u src/compositor/CMakeLists.txt <<EOF
|
||||
--- src/compositor/CMakeLists.txt 2022-06-08 13:44:30.000000000 +1000
|
||||
+++ src/compositor/CMakeLists.txt 2022-07-17 20:05:25.461881785 +1000
|
||||
@@ -46,7 +46,6 @@
|
||||
global/qtwaylandcompositorglobal.h
|
||||
global/qtwaylandqmlinclude.h
|
||||
global/qwaylandcompositorextension.cpp global/qwaylandcompositorextension.h global/qwaylandcompositorextension_p.h
|
||||
- global/qwaylandquickextension.cpp global/qwaylandquickextension.h
|
||||
global/qwaylandutils_p.h
|
||||
hardware_integration/qwlclientbufferintegration.cpp hardware_integration/qwlclientbufferintegration_p.h
|
||||
wayland_wrapper/qwlbuffermanager.cpp wayland_wrapper/qwlbuffermanager_p.h
|
||||
EOF
|
||||
mkdir build
|
||||
cd build
|
||||
cmake -G Ninja -DCMAKE_PREFIX_PATH="$INSTALLDIR" -DCMAKE_INSTALL_PREFIX="$INSTALLDIR" -DCMAKE_BUILD_TYPE=Release ..
|
||||
cmake --build . --parallel
|
||||
cmake --install .
|
||||
cd ../../
|
||||
|
||||
echo "Installing Qt Tools..."
|
||||
tar xf "qttools-everywhere-src-$QT.tar.xz"
|
||||
cd "qttools-everywhere-src-$QT"
|
||||
# From Mac build-dependencies.sh:
|
||||
# Linguist relies on a library in the Designer target, which takes 5-7 minutes to build on the CI
|
||||
# Avoid it by not building Linguist, since we only need the tools that come with it
|
||||
patch -u src/linguist/CMakeLists.txt <<EOF
|
||||
--- src/linguist/CMakeLists.txt
|
||||
+++ src/linguist/CMakeLists.txt
|
||||
@@ -14,7 +14,7 @@
|
||||
add_subdirectory(lrelease-pro)
|
||||
add_subdirectory(lupdate)
|
||||
add_subdirectory(lupdate-pro)
|
||||
-if(QT_FEATURE_process AND QT_FEATURE_pushbutton AND QT_FEATURE_toolbutton AND TARGET Qt::Widgets AND NOT no-png)
|
||||
+if(QT_FEATURE_process AND QT_FEATURE_pushbutton AND QT_FEATURE_toolbutton AND TARGET Qt::Widgets AND TARGET Qt::PrintSupport AND NOT no-png)
|
||||
add_subdirectory(linguist)
|
||||
endif()
|
||||
EOF
|
||||
mkdir build
|
||||
cd build
|
||||
cmake -G Ninja -DCMAKE_PREFIX_PATH="$INSTALLDIR" -DCMAKE_INSTALL_PREFIX="$INSTALLDIR" -DCMAKE_BUILD_TYPE=Release -DFEATURE_assistant=OFF -DFEATURE_clang=OFF -DFEATURE_designer=OFF -DFEATURE_kmap2qmap=OFF -DFEATURE_pixeltool=OFF -DFEATURE_pkg_config=OFF -DFEATURE_qev=OFF -DFEATURE_qtattributionsscanner=OFF -DFEATURE_qtdiag=OFF -DFEATURE_qtplugininfo=OFF ..
|
||||
cmake --build . --parallel
|
||||
cmake --install .
|
||||
cd ../../
|
||||
|
||||
echo "Installing Qt Translations..."
|
||||
tar xf "qttranslations-everywhere-src-$QT.tar.xz"
|
||||
cd "qttranslations-everywhere-src-$QT"
|
||||
mkdir build
|
||||
cd build
|
||||
cmake -G Ninja -DCMAKE_PREFIX_PATH="$INSTALLDIR" -DCMAKE_INSTALL_PREFIX="$INSTALLDIR" -DCMAKE_BUILD_TYPE=Release ..
|
||||
cmake --build . --parallel
|
||||
cmake --install .
|
||||
cd ../../
|
||||
|
||||
echo "Cleaning up..."
|
||||
cd ..
|
||||
rm -r deps-build
|
||||
38
.github/workflows/scripts/linux/generate-cmake-qt.sh
vendored
Executable file
38
.github/workflows/scripts/linux/generate-cmake-qt.sh
vendored
Executable file
@@ -0,0 +1,38 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
|
||||
if [ "${COMPILER}" = "clang" ]; then
|
||||
echo "Using clang toolchain"
|
||||
cat > "$HOME/clang-toolchain.cmake" << EOF
|
||||
set(CMAKE_C_COMPILER /usr/bin/clang-12)
|
||||
set(CMAKE_CXX_COMPILER /usr/bin/clang++-12)
|
||||
set(CMAKE_EXE_LINKER_FLAGS_INIT "-fuse-ld=lld")
|
||||
set(CMAKE_MODULE_LINKER_FLAGS_INIT "-fuse-ld=lld")
|
||||
set(CMAKE_SHARED_LINKER_FLAGS_INIT "-fuse-ld=lld")
|
||||
EOF
|
||||
ADDITIONAL_CMAKE_ARGS="$ADDITIONAL_CMAKE_ARGS -DCMAKE_INTERPROCEDURAL_OPTIMIZATION=ON -DCMAKE_TOOLCHAIN_FILE=$HOME/clang-toolchain.cmake"
|
||||
fi
|
||||
|
||||
echo "Additional CMake Args - ${ADDITIONAL_CMAKE_ARGS}"
|
||||
|
||||
# Generate CMake into ./build
|
||||
# DISABLE_ADVANCE_SIMD is needed otherwise we end up doing -march=native.
|
||||
|
||||
# shellcheck disable=SC2086
|
||||
cmake \
|
||||
-B build \
|
||||
-G Ninja \
|
||||
$ADDITIONAL_CMAKE_ARGS \
|
||||
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DQT_BUILD=ON \
|
||||
-DWAYLAND_API=ON \
|
||||
-DXDG_STD=TRUE \
|
||||
-DDISABLE_PCSX2_WRAPPER=ON \
|
||||
-DDISABLE_SETCAP=ON \
|
||||
-DCMAKE_PREFIX_PATH="$HOME/deps" \
|
||||
-DUSE_SYSTEM_SDL2=ON \
|
||||
-DUSE_SYSTEM_ZSTD=OFF \
|
||||
-DDISABLE_ADVANCE_SIMD=TRUE
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
set -e
|
||||
|
||||
if [ "${COMPILER}" = "gcc" ]; then
|
||||
export CC=gcc
|
||||
export CXX=g++
|
||||
export CC=gcc-10
|
||||
export CXX=g++-10
|
||||
else
|
||||
export CC=clang
|
||||
export CXX=clang++
|
||||
@@ -20,13 +20,14 @@ cmake \
|
||||
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DPACKAGE_MODE=TRUE \
|
||||
-DWAYLAND_API=TRUE \
|
||||
-DDISABLE_ADVANCE_SIMD=TRUE \
|
||||
-DCMAKE_INSTALL_LIBDIR="/tmp/" \
|
||||
-DCMAKE_INSTALL_DATADIR="/tmp/" \
|
||||
-DCMAKE_INSTALL_DOCDIR="/tmp/PCSX2" \
|
||||
-DDISABLE_PCSX2_WRAPPER=TRUE \
|
||||
-DCMAKE_INSTALL_PREFIX="squashfs-root/usr/" \
|
||||
-DOpenGL_GL_PREFERENCE="LEGACY" \
|
||||
-DOPENGL_opengl_LIBRARY="" \
|
||||
-DXDG_STD=TRUE \
|
||||
-DUSE_SYSTEM_ZSTD=FALSE \
|
||||
$ADDITIONAL_CMAKE_ARGS \
|
||||
-GNinja \
|
||||
-B build
|
||||
|
||||
72
.github/workflows/scripts/linux/install-packages-qt.sh
vendored
Executable file
72
.github/workflows/scripts/linux/install-packages-qt.sh
vendored
Executable file
@@ -0,0 +1,72 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
# Packages - Build and Qt
|
||||
declare -a BUILD_PACKAGES=(
|
||||
"build-essential"
|
||||
"git"
|
||||
"cmake"
|
||||
"ccache"
|
||||
"ninja-build"
|
||||
"libclang-dev" # Qt goes hunting for libclang-11 specifically.
|
||||
"libclang-11-dev"
|
||||
"libclang-12-dev"
|
||||
"patchelf"
|
||||
"libglib2.0-dev"
|
||||
"libfontconfig1-dev"
|
||||
"libharfbuzz-dev"
|
||||
"libjpeg-dev"
|
||||
"libpng-dev"
|
||||
"libfreetype-dev"
|
||||
"libinput-dev"
|
||||
"libxcb-*-dev"
|
||||
"libxkbcommon-dev"
|
||||
"libxkbcommon-x11-dev"
|
||||
"libxrender-dev"
|
||||
"libwayland-dev"
|
||||
"libgl1-mesa-dev"
|
||||
"libegl-dev"
|
||||
"libegl1-mesa-dev"
|
||||
"libgl1-mesa-dev"
|
||||
"libssl-dev"
|
||||
)
|
||||
|
||||
# Packages - PCSX2
|
||||
declare -a PCSX2_PACKAGES=(
|
||||
"libaio-dev"
|
||||
"libbz2-dev"
|
||||
"libegl1-mesa-dev"
|
||||
"libgl1-mesa-dev"
|
||||
"libgtk-3-dev"
|
||||
"libharfbuzz-dev"
|
||||
"libjpeg-dev"
|
||||
"liblzma-dev"
|
||||
"libpcap0.8-dev"
|
||||
"libpng-dev"
|
||||
"libpulse-dev"
|
||||
"librsvg2-dev"
|
||||
"libsamplerate0-dev"
|
||||
"libsoundtouch-dev"
|
||||
"libudev-dev"
|
||||
"libx11-xcb-dev"
|
||||
"pkg-config"
|
||||
"zlib1g-dev"
|
||||
)
|
||||
|
||||
if [ "${COMPILER}" = "gcc" ]; then
|
||||
BUILD_PACKAGES+=("g++-10")
|
||||
else
|
||||
BUILD_PACKAGES+=("llvm-12" "lld-12" "clang-12")
|
||||
fi
|
||||
|
||||
sudo apt-get -qq update
|
||||
|
||||
# Install packages needed for building
|
||||
echo "Will install the following packages for building - ${BUILD_PACKAGES[*]}"
|
||||
sudo apt-get -y install "${BUILD_PACKAGES[@]}"
|
||||
|
||||
# Install packages needed by pcsx2
|
||||
PCSX2_PACKAGES=("${PCSX2_PACKAGES[@]}")
|
||||
echo "Will install the following packages for pcsx2 - ${PCSX2_PACKAGES[*]}"
|
||||
sudo apt-get -y install "${PCSX2_PACKAGES[@]}"
|
||||
119
.github/workflows/scripts/linux/install-packages.sh
vendored
119
.github/workflows/scripts/linux/install-packages.sh
vendored
@@ -6,100 +6,41 @@ set -e
|
||||
declare -a BUILD_PACKAGES=(
|
||||
"ccache"
|
||||
"cmake"
|
||||
"g++-8-multilib"
|
||||
"ninja-build"
|
||||
)
|
||||
|
||||
declare -a GCC_PACKAGES=(
|
||||
# Nothing Unique Needed
|
||||
)
|
||||
|
||||
declare -a CLANG_PACKAGES=(
|
||||
"clang-format"
|
||||
"clang-tidy"
|
||||
"clang-tools"
|
||||
"clang"
|
||||
"clangd-10"
|
||||
"libc++-dev"
|
||||
"libc++1"
|
||||
"libc++abi-dev"
|
||||
"libc++abi1"
|
||||
"libclang-dev"
|
||||
"libclang1"
|
||||
"liblldb-10-dev"
|
||||
"libllvm-10-ocaml-dev"
|
||||
"libomp-dev"
|
||||
"libomp5"
|
||||
"lld"
|
||||
"lldb"
|
||||
"llvm-dev"
|
||||
"llvm-runtime"
|
||||
"llvm"
|
||||
"python3-clang-10"
|
||||
)
|
||||
|
||||
# Packages - PCSX2
|
||||
declare -a PCSX2_PACKAGES=(
|
||||
"curl"
|
||||
"fuse"
|
||||
"gettext"
|
||||
"libaio-dev"
|
||||
"libasound2-dev"
|
||||
"libatk1.0-dev"
|
||||
"libatk-bridge2.0-dev"
|
||||
"libbz2-dev"
|
||||
"libcairo2-dev"
|
||||
"libcggl"
|
||||
"libdbus-1-dev"
|
||||
"libegl1-mesa-dev"
|
||||
"libfontconfig1-dev"
|
||||
"libgdk-pixbuf2.0-dev"
|
||||
"libgirepository-1.0-1"
|
||||
"libgl-dev"
|
||||
"libgl1-mesa-dev"
|
||||
"libgl1-mesa-dri"
|
||||
"libgl1"
|
||||
"libgles2-mesa-dev"
|
||||
"libglew-dev"
|
||||
"libglib2.0-dev"
|
||||
"libglu1-mesa-dev"
|
||||
"libglu1-mesa"
|
||||
"libglvnd-dev"
|
||||
"libglx-mesa0"
|
||||
"libglx0"
|
||||
"libgtk-3-dev"
|
||||
"libgtk2.0-dev"
|
||||
"libharfbuzz-dev"
|
||||
"libibus-1.0-dev"
|
||||
"libjack-jackd2-dev"
|
||||
"libjpeg-dev"
|
||||
"libllvm10"
|
||||
"liblzma-dev"
|
||||
"liblzma5"
|
||||
"libpango1.0-dev"
|
||||
"libpcap0.8-dev"
|
||||
"libpng-dev"
|
||||
"libportaudiocpp0"
|
||||
"libpulse-dev"
|
||||
"librsvg2-dev"
|
||||
"libsdl1.2-dev"
|
||||
"libsdl2-dev"
|
||||
"libsamplerate0-dev"
|
||||
"libsoundtouch-dev"
|
||||
"libwxgtk3.0-dev"
|
||||
"libwxgtk3.0-gtk3-0v5"
|
||||
"libudev-dev"
|
||||
"libwxgtk3.0-gtk3-dev"
|
||||
"libx11-xcb-dev"
|
||||
"libxext-dev"
|
||||
"libxft-dev"
|
||||
"libxml2-dev"
|
||||
"nvidia-cg-toolkit"
|
||||
"pkg-config"
|
||||
"portaudio19-dev"
|
||||
"python"
|
||||
"zlib1g-dev"
|
||||
)
|
||||
|
||||
if [ "${COMPILER}" = "gcc" ]; then
|
||||
BUILD_PACKAGES+=("g++-10-multilib")
|
||||
else
|
||||
BUILD_PACKAGES+=("clang-9")
|
||||
PCSX2_PACKAGES+=("libstdc++-10-dev")
|
||||
fi
|
||||
|
||||
# - https://github.com/actions/virtual-environments/blob/main/images/linux/Ubuntu2004-README.md
|
||||
ARCH=""
|
||||
echo "${PLATFORM}"
|
||||
@@ -111,45 +52,11 @@ fi
|
||||
sudo apt-get -qq update
|
||||
|
||||
# Install packages needed for building
|
||||
BUILD_PACKAGE_STR=""
|
||||
for i in "${BUILD_PACKAGES[@]}"; do
|
||||
BUILD_PACKAGE_STR="${BUILD_PACKAGE_STR} ${i}"
|
||||
done
|
||||
|
||||
if [ "${COMPILER}" = "gcc" ]; then
|
||||
for i in "${GCC_PACKAGES[@]}"; do
|
||||
BUILD_PACKAGE_STR="${BUILD_PACKAGE_STR} ${i}"
|
||||
done
|
||||
else
|
||||
for i in "${CLANG_PACKAGES[@]}"; do
|
||||
BUILD_PACKAGE_STR="${BUILD_PACKAGE_STR} ${i}"
|
||||
done
|
||||
fi
|
||||
|
||||
echo "Will install the following packages for building - ${BUILD_PACKAGE_STR}"
|
||||
echo "Will install the following packages for building - ${BUILD_PACKAGES[*]}"
|
||||
#sudo apt remove gcc-9 g++-9
|
||||
sudo apt-get -y install ${BUILD_PACKAGE_STR}
|
||||
|
||||
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-8 10
|
||||
sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-8 10
|
||||
sudo update-alternatives --install /usr/bin/cc cc /usr/bin/gcc 30
|
||||
sudo update-alternatives --install /usr/bin/c++ c++ /usr/bin/g++ 30
|
||||
sudo apt-get -y install "${BUILD_PACKAGES[@]}"
|
||||
|
||||
# Install packages needed by pcsx2
|
||||
PCSX2_PACKAGES_STR=""
|
||||
for i in "${PCSX2_PACKAGES[@]}"; do
|
||||
PCSX2_PACKAGES_STR="${PCSX2_PACKAGES_STR} ${i}${ARCH}"
|
||||
done
|
||||
if [ "${PLATFORM}" == "x86" ]; then
|
||||
echo "Installing workaround attempt"
|
||||
sudo apt-get -y install libgcc-s1:i386
|
||||
fi
|
||||
echo "Will install the following packages for pcsx2 - ${PCSX2_PACKAGES_STR}"
|
||||
sudo apt-get -y install ${PCSX2_PACKAGES_STR}
|
||||
|
||||
cd /tmp
|
||||
curl -sSfLO https://github.com/NixOS/patchelf/releases/download/0.12/patchelf-0.12.tar.bz2
|
||||
tar xvf patchelf-0.12.tar.bz2
|
||||
cd patchelf-0.12*/
|
||||
./configure
|
||||
make && sudo make install
|
||||
PCSX2_PACKAGES=("${PCSX2_PACKAGES[@]/%/"${ARCH}"}")
|
||||
echo "Will install the following packages for pcsx2 - ${PCSX2_PACKAGES[*]}"
|
||||
sudo apt-get -y install "${PCSX2_PACKAGES[@]}"
|
||||
|
||||
12
.github/workflows/scripts/linux/pcsx2-qt.desktop
vendored
Normal file
12
.github/workflows/scripts/linux/pcsx2-qt.desktop
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
[Desktop Entry]
|
||||
Version=1.0
|
||||
Terminal=false
|
||||
Type=Application
|
||||
Name=PCSX2
|
||||
StartupWMClass=PCSX2
|
||||
GenericName=PlayStation 2 Emulator
|
||||
Comment=Sony PlayStation 2 emulator
|
||||
Exec=pcsx2-qt
|
||||
Icon=PCSX2
|
||||
Keywords=game;emulator;
|
||||
Categories=Game;Emulator;
|
||||
164
.github/workflows/scripts/macos/build-dependencies.sh
vendored
Executable file
164
.github/workflows/scripts/macos/build-dependencies.sh
vendored
Executable file
@@ -0,0 +1,164 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
if [ "$GUI" == "Qt" ]; then
|
||||
export MACOSX_DEPLOYMENT_TARGET=10.14
|
||||
else
|
||||
export MACOSX_DEPLOYMENT_TARGET=10.13
|
||||
fi
|
||||
INSTALLDIR="$HOME/deps"
|
||||
NPROCS="$(getconf _NPROCESSORS_ONLN)"
|
||||
SDL=SDL2-2.0.22
|
||||
PNG=1.6.37
|
||||
JPG=9e
|
||||
SAMPLERATE=libsamplerate-0.1.9
|
||||
PORTAUDIO=pa_stable_v190700_20210406
|
||||
SOUNDTOUCH=soundtouch-2.3.1
|
||||
WXWIDGETS=3.1.6
|
||||
QT=6.3.1
|
||||
|
||||
mkdir deps-build
|
||||
cd deps-build
|
||||
|
||||
export PKG_CONFIG_PATH="$INSTALLDIR/lib/pkgconfig:$PKG_CONFIG_PATH"
|
||||
export LDFLAGS="-L$INSTALLDIR/lib -dead_strip $LDFLAGS"
|
||||
export CFLAGS="-I$INSTALLDIR/include -Os $CFLAGS"
|
||||
export CXXFLAGS="-I$INSTALLDIR/include -Os $CXXFLAGS"
|
||||
|
||||
cat > SHASUMS <<EOF
|
||||
fe7cbf3127882e3fc7259a75a0cb585620272c51745d3852ab9dd87960697f2e $SDL.tar.gz
|
||||
505e70834d35383537b6491e7ae8641f1a4bed1876dbfe361201fc80868d88ca libpng-$PNG.tar.xz
|
||||
4077d6a6a75aeb01884f708919d25934c93305e49f7e3f36db9129320e6f4f3d jpegsrc.v$JPG.tar.gz
|
||||
0a7eb168e2f21353fb6d84da152e4512126f7dc48ccb0be80578c565413444c1 $SAMPLERATE.tar.gz
|
||||
47efbf42c77c19a05d22e627d42873e991ec0c1357219c0d74ce6a2948cb2def $PORTAUDIO.tgz
|
||||
6900996607258496ce126924a19fe9d598af9d892cf3f33d1e4daaa9b42ae0b1 $SOUNDTOUCH.tar.gz
|
||||
4980e86c6494adcd527a41fc0a4e436777ba41d1893717d7b7176c59c2061c25 wxWidgets-$WXWIDGETS.tar.bz2
|
||||
0a64421d9c2469c2c48490a032ab91d547017c9cc171f3f8070bc31888f24e03 qtbase-everywhere-src-$QT.tar.xz
|
||||
7b19f418e6f7b8e23344082dd04440aacf5da23c5a73980ba22ae4eba4f87df7 qtsvg-everywhere-src-$QT.tar.xz
|
||||
c412750f2aa3beb93fce5f30517c607f55daaeb7d0407af206a8adf917e126c1 qttools-everywhere-src-$QT.tar.xz
|
||||
d7bdd55e2908ded901dcc262157100af2a490bf04d31e32995f6d91d78dfdb97 qttranslations-everywhere-src-$QT.tar.xz
|
||||
EOF
|
||||
|
||||
curl -L \
|
||||
-O "https://libsdl.org/release/$SDL.tar.gz" \
|
||||
-O "https://downloads.sourceforge.net/project/libpng/libpng16/$PNG/libpng-$PNG.tar.xz" \
|
||||
-O "https://www.ijg.org/files/jpegsrc.v$JPG.tar.gz" \
|
||||
-O "http://www.mega-nerd.com/SRC/$SAMPLERATE.tar.gz" \
|
||||
-O "http://files.portaudio.com/archives/$PORTAUDIO.tgz" \
|
||||
-O "https://www.surina.net/soundtouch/$SOUNDTOUCH.tar.gz" \
|
||||
-O "https://github.com/wxWidgets/wxWidgets/releases/download/v$WXWIDGETS/wxWidgets-$WXWIDGETS.tar.bz2" \
|
||||
-O "https://download.qt.io/official_releases/qt/${QT%.*}/$QT/submodules/qtbase-everywhere-src-$QT.tar.xz" \
|
||||
-O "https://download.qt.io/official_releases/qt/${QT%.*}/$QT/submodules/qtsvg-everywhere-src-$QT.tar.xz" \
|
||||
-O "https://download.qt.io/official_releases/qt/${QT%.*}/$QT/submodules/qttools-everywhere-src-$QT.tar.xz" \
|
||||
-O "https://download.qt.io/official_releases/qt/${QT%.*}/$QT/submodules/qttranslations-everywhere-src-$QT.tar.xz" \
|
||||
|
||||
shasum -a 256 --check SHASUMS
|
||||
|
||||
echo "Installing SDL..."
|
||||
tar xf "$SDL.tar.gz"
|
||||
cd "$SDL"
|
||||
./configure --prefix "$INSTALLDIR" --without-x
|
||||
make "-j$NPROCS"
|
||||
make install
|
||||
cd ..
|
||||
|
||||
echo "Installing libpng..."
|
||||
tar xf "libpng-$PNG.tar.xz"
|
||||
cd "libpng-$PNG"
|
||||
./configure --prefix "$INSTALLDIR" --disable-dependency-tracking
|
||||
make "-j$NPROCS"
|
||||
make install
|
||||
cd ..
|
||||
|
||||
echo "Installing libjpeg..."
|
||||
tar xf "jpegsrc.v$JPG.tar.gz"
|
||||
cd "jpeg-$JPG"
|
||||
./configure --prefix "$INSTALLDIR" --disable-dependency-tracking
|
||||
make "-j$NPROCS"
|
||||
make install
|
||||
cd ..
|
||||
|
||||
echo "Installing libsamplerate..."
|
||||
tar xf "$SAMPLERATE.tar.gz"
|
||||
cd "$SAMPLERATE"
|
||||
sed -i "" "s/Carbon.h/Carbon\\/Carbon.h/" examples/audio_out.c
|
||||
./configure --prefix "$INSTALLDIR" --disable-dependency-tracking --disable-sndfile
|
||||
make "-j$NPROCS"
|
||||
make install
|
||||
cd ..
|
||||
|
||||
echo "Installing portaudio..."
|
||||
tar xf "$PORTAUDIO.tgz"
|
||||
cd portaudio
|
||||
./configure --prefix "$INSTALLDIR" --enable-mac-universal=no
|
||||
make "-j$NPROCS"
|
||||
make install
|
||||
cd ..
|
||||
|
||||
echo "Installing soundtouch..."
|
||||
tar xf "$SOUNDTOUCH.tar.gz"
|
||||
cd "$SOUNDTOUCH"
|
||||
cmake -B build -DCMAKE_INSTALL_PREFIX="$INSTALLDIR" -DCMAKE_BUILD_TYPE=MinSizeRel
|
||||
make -C build "-j$NPROCS"
|
||||
make -C build install
|
||||
cd ..
|
||||
|
||||
if [ "$GUI" == "wxWidgets" ]; then
|
||||
echo "Installing wx..."
|
||||
tar xf "wxWidgets-$WXWIDGETS.tar.bz2"
|
||||
cd "wxWidgets-$WXWIDGETS"
|
||||
./configure --prefix "$INSTALLDIR" --with-macosx-version-min="$MACOSX_DEPLOYMENT_TARGET" --enable-clipboard --enable-dnd --enable-std_string --with-cocoa --with-libiconv --with-libjpeg --with-libpng --with-zlib --without-libtiff --without-regex
|
||||
make "-j$NPROCS"
|
||||
make install
|
||||
cd ..
|
||||
fi
|
||||
|
||||
if [ "$GUI" == "Qt" ]; then
|
||||
echo "Installing Qt Base..."
|
||||
tar xf "qtbase-everywhere-src-$QT.tar.xz"
|
||||
cd "qtbase-everywhere-src-$QT"
|
||||
cmake -B build -DCMAKE_PREFIX_PATH="$INSTALLDIR" -DCMAKE_INSTALL_PREFIX="$INSTALLDIR" -DCMAKE_BUILD_TYPE=Release -DFEATURE_optimize_size=ON -DFEATURE_dbus=OFF -DFEATURE_framework=OFF -DFEATURE_icu=OFF -DFEATURE_opengl=OFF -DFEATURE_printsupport=OFF -DFEATURE_sql=OFF
|
||||
make -C build "-j$NPROCS"
|
||||
make -C build install
|
||||
cd ..
|
||||
echo "Installing Qt SVG..."
|
||||
tar xf "qtsvg-everywhere-src-$QT.tar.xz"
|
||||
cd "qtsvg-everywhere-src-$QT"
|
||||
cmake -B build -DCMAKE_PREFIX_PATH="$INSTALLDIR" -DCMAKE_INSTALL_PREFIX="$INSTALLDIR" -DCMAKE_BUILD_TYPE=MinSizeRel
|
||||
make -C build "-j$NPROCS"
|
||||
make -C build install
|
||||
cd ..
|
||||
echo "Installing Qt Tools..."
|
||||
tar xf "qttools-everywhere-src-$QT.tar.xz"
|
||||
cd "qttools-everywhere-src-$QT"
|
||||
# Linguist relies on a library in the Designer target, which takes 5-7 minutes to build on the CI
|
||||
# Avoid it by not building Linguist, since we only need the tools that come with it
|
||||
patch -u src/linguist/CMakeLists.txt <<EOF
|
||||
--- src/linguist/CMakeLists.txt
|
||||
+++ src/linguist/CMakeLists.txt
|
||||
@@ -14,7 +14,7 @@
|
||||
add_subdirectory(lrelease-pro)
|
||||
add_subdirectory(lupdate)
|
||||
add_subdirectory(lupdate-pro)
|
||||
-if(QT_FEATURE_process AND QT_FEATURE_pushbutton AND QT_FEATURE_toolbutton AND TARGET Qt::Widgets AND NOT no-png)
|
||||
+if(QT_FEATURE_process AND QT_FEATURE_pushbutton AND QT_FEATURE_toolbutton AND TARGET Qt::Widgets AND TARGET Qt::PrintSupport AND NOT no-png)
|
||||
add_subdirectory(linguist)
|
||||
endif()
|
||||
EOF
|
||||
cmake -B build -DCMAKE_PREFIX_PATH="$INSTALLDIR" -DCMAKE_INSTALL_PREFIX="$INSTALLDIR" -DCMAKE_BUILD_TYPE=Release -DFEATURE_assistant=OFF -DFEATURE_clang=OFF -DFEATURE_designer=OFF -DFEATURE_kmap2qmap=OFF -DFEATURE_pixeltool=OFF -DFEATURE_pkg_config=OFF -DFEATURE_qev=OFF -DFEATURE_qtattributionsscanner=OFF -DFEATURE_qtdiag=OFF -DFEATURE_qtplugininfo=OFF
|
||||
make -C build "-j$NPROCS"
|
||||
make -C build install
|
||||
cd ..
|
||||
echo "Installing Qt Translations..."
|
||||
tar xf "qttranslations-everywhere-src-$QT.tar.xz"
|
||||
cd "qttranslations-everywhere-src-$QT"
|
||||
cmake -B build -DCMAKE_PREFIX_PATH="$INSTALLDIR" -DCMAKE_INSTALL_PREFIX="$INSTALLDIR" -DCMAKE_BUILD_TYPE=Release
|
||||
make -C build "-j$NPROCS"
|
||||
make -C build install
|
||||
cd ..
|
||||
fi
|
||||
|
||||
echo "Cleaning up..."
|
||||
cd ..
|
||||
rm -r deps-build
|
||||
@@ -1,39 +1,24 @@
|
||||
import { MessageEmbed, WebhookClient } from "discord.js";
|
||||
import * as github from '@actions/github';
|
||||
|
||||
const assets = github.context.payload.release.assets;
|
||||
let windowsAssetLinks = "";
|
||||
let linuxAssetLinks = "";
|
||||
const releaseInfo = github.context.payload.release;
|
||||
|
||||
for (var i = 0; i < assets.length; i++) {
|
||||
let asset = assets[i];
|
||||
if (asset.name.includes("symbols")) {
|
||||
continue;
|
||||
}
|
||||
if (asset.name.includes("windows")) {
|
||||
windowsAssetLinks += `- [${asset.name}](${asset.browser_download_url})\n`
|
||||
} else if (asset.name.includes("linux")) {
|
||||
linuxAssetLinks += `- [${asset.name}](${asset.browser_download_url})\n`
|
||||
}
|
||||
if (!releaseInfo.prerelease) {
|
||||
console.log("Not announcing - release was not a pre-release (aka a Nightly)");
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
// Publish Webhook
|
||||
const embed = new MessageEmbed()
|
||||
.setColor('#FF8000')
|
||||
.setTitle('New PCSX2 Nightly Build Available!')
|
||||
.setDescription("To download the latest or previous builds, [visit the official downloads page](https://pcsx2.net/downloads/).")
|
||||
.addFields(
|
||||
{ name: 'Version', value: github.context.payload.release.tag_name, inline: true },
|
||||
{ name: 'Release Link', value: `[Github Release](${github.context.payload.release.html_url})`, inline: true },
|
||||
{ name: 'Installation Steps', value: '[See Here](https://github.com/PCSX2/pcsx2/wiki/Nightly-Build-Usage-Guide)', inline: true }
|
||||
{ name: 'Version', value: releaseInfo.tag_name, inline: true },
|
||||
{ name: 'Installation Steps', value: '[See Here](https://github.com/PCSX2/pcsx2/wiki/Nightly-Build-Usage-Guide)', inline: true },
|
||||
{ name: 'Included Changes', value: releaseInfo.body, inline: false }
|
||||
);
|
||||
|
||||
if (windowsAssetLinks != "") {
|
||||
embed.addField('Windows Downloads', windowsAssetLinks, false);
|
||||
}
|
||||
if (linuxAssetLinks != "") {
|
||||
embed.addField('Linux Downloads', linuxAssetLinks, false);
|
||||
}
|
||||
|
||||
const webhookClient = new WebhookClient({ url: process.env.DISCORD_BUILD_WEBHOOK });
|
||||
await webhookClient.send({
|
||||
embeds: [embed],
|
||||
|
||||
20
.github/workflows/scripts/releases/announce-release/package-lock.json
generated
vendored
20
.github/workflows/scripts/releases/announce-release/package-lock.json
generated
vendored
@@ -328,14 +328,22 @@
|
||||
}
|
||||
},
|
||||
"node_modules/node-fetch": {
|
||||
"version": "2.6.5",
|
||||
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.5.tgz",
|
||||
"integrity": "sha512-mmlIVHJEu5rnIxgEgez6b9GgWXbkZj5YZ7fx+2r94a2E+Uirsp6HsPTPlomfdHtpt/B0cdKviwkoaM6pyvUOpQ==",
|
||||
"version": "2.6.7",
|
||||
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz",
|
||||
"integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==",
|
||||
"dependencies": {
|
||||
"whatwg-url": "^5.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "4.x || >=6.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"encoding": "^0.1.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"encoding": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/once": {
|
||||
@@ -714,9 +722,9 @@
|
||||
}
|
||||
},
|
||||
"node-fetch": {
|
||||
"version": "2.6.5",
|
||||
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.5.tgz",
|
||||
"integrity": "sha512-mmlIVHJEu5rnIxgEgez6b9GgWXbkZj5YZ7fx+2r94a2E+Uirsp6HsPTPlomfdHtpt/B0cdKviwkoaM6pyvUOpQ==",
|
||||
"version": "2.6.7",
|
||||
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz",
|
||||
"integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==",
|
||||
"requires": {
|
||||
"whatwg-url": "^5.0.0"
|
||||
}
|
||||
|
||||
@@ -1,11 +1,15 @@
|
||||
import { Octokit } from "@octokit/rest";
|
||||
import { throttling } from "@octokit/plugin-throttling";
|
||||
import { retry } from "@octokit/plugin-retry";
|
||||
|
||||
let owner = process.env.OWNER;
|
||||
let repo = process.env.REPO;
|
||||
|
||||
Octokit.plugin(throttling);
|
||||
Octokit.plugin(retry);
|
||||
const octokit = new Octokit({
|
||||
auth: process.env.GITHUB_TOKEN,
|
||||
userAgent: 'PCSX2/pcsx2',
|
||||
userAgent: `${owner}/${repo}`,
|
||||
log: {
|
||||
debug: () => { },
|
||||
info: () => { },
|
||||
@@ -39,14 +43,14 @@ let commitSha = process.env.COMMIT_SHA;
|
||||
console.log(`Searching for Commit - ${commitSha}`);
|
||||
|
||||
const { data: commit } = await octokit.rest.repos.getCommit({
|
||||
owner: "PCSX2",
|
||||
repo: "pcsx2",
|
||||
owner: owner,
|
||||
repo: repo,
|
||||
ref: commitSha,
|
||||
});
|
||||
|
||||
const { data: associatedPulls } = await octokit.rest.repos.listPullRequestsAssociatedWithCommit({
|
||||
owner: "PCSX2",
|
||||
repo: "pcsx2",
|
||||
owner: owner,
|
||||
repo: repo,
|
||||
commit_sha: commit.sha,
|
||||
});
|
||||
|
||||
|
||||
6
.github/workflows/scripts/releases/generate-release-notes/package-lock.json
generated
vendored
6
.github/workflows/scripts/releases/generate-release-notes/package-lock.json
generated
vendored
@@ -154,9 +154,9 @@
|
||||
"integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q=="
|
||||
},
|
||||
"node-fetch": {
|
||||
"version": "2.6.5",
|
||||
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.5.tgz",
|
||||
"integrity": "sha512-mmlIVHJEu5rnIxgEgez6b9GgWXbkZj5YZ7fx+2r94a2E+Uirsp6HsPTPlomfdHtpt/B0cdKviwkoaM6pyvUOpQ==",
|
||||
"version": "2.6.7",
|
||||
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz",
|
||||
"integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==",
|
||||
"requires": {
|
||||
"whatwg-url": "^5.0.0"
|
||||
}
|
||||
|
||||
49
.github/workflows/scripts/releases/rename-release-assets.py
vendored
Normal file
49
.github/workflows/scripts/releases/rename-release-assets.py
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
import os
|
||||
import shutil
|
||||
|
||||
tag = os.environ['TAG'].split("refs/tags/")[1]
|
||||
scan_dir = os.environ['SCAN_DIR']
|
||||
output_dir = os.environ['OUT_DIR']
|
||||
accepted_exts = ["AppImage", "tar.gz", "7z"]
|
||||
|
||||
|
||||
for dir_name in os.listdir(scan_dir):
|
||||
asset_name = "pcsx2-{}".format(tag)
|
||||
if "macos" in dir_name.lower():
|
||||
asset_name += "-macos"
|
||||
elif "linux" in dir_name.lower():
|
||||
asset_name += "-linux-AppImage-64bit"
|
||||
elif "windows" in dir_name.lower():
|
||||
asset_name += "-windows-64bit"
|
||||
else:
|
||||
continue;
|
||||
|
||||
if "avx2" in dir_name.lower():
|
||||
asset_name += "-AVX2"
|
||||
elif "sse4" in dir_name.lower():
|
||||
asset_name += "-SSE4"
|
||||
|
||||
if "wxwidgets" in dir_name.lower():
|
||||
asset_name += "-wxWidgets"
|
||||
else:
|
||||
asset_name += "-Qt"
|
||||
|
||||
if "symbols" in dir_name.lower():
|
||||
asset_name += "-symbols"
|
||||
|
||||
print(asset_name)
|
||||
|
||||
dir_handled = False
|
||||
for file in os.listdir(os.path.join(scan_dir, dir_name)):
|
||||
for ext in accepted_exts:
|
||||
if file.endswith(ext):
|
||||
dir_handled = True
|
||||
print("Moving {} to out dir".format(file))
|
||||
shutil.move(os.path.join(scan_dir, dir_name, file), os.path.join(output_dir, asset_name + "." + ext))
|
||||
break
|
||||
if dir_handled:
|
||||
break
|
||||
|
||||
if not dir_handled:
|
||||
print("Could not find asset in directory when one was expected")
|
||||
exit(1)
|
||||
@@ -1,2 +0,0 @@
|
||||
node_modules/
|
||||
*.md
|
||||
@@ -1,145 +0,0 @@
|
||||
import { Octokit } from "@octokit/rest";
|
||||
import { throttling } from "@octokit/plugin-throttling";
|
||||
import { retry } from "@octokit/plugin-retry";
|
||||
Octokit.plugin(throttling);
|
||||
Octokit.plugin(retry);
|
||||
const octokit = new Octokit({
|
||||
auth: process.env.GITHUB_TOKEN,
|
||||
userAgent: 'PCSX2/pcsx2',
|
||||
log: {
|
||||
debug: () => { },
|
||||
info: () => { },
|
||||
warn: console.warn,
|
||||
error: console.error
|
||||
},
|
||||
throttle: {
|
||||
onRateLimit: (retryAfter, options) => {
|
||||
octokit.log.warn(
|
||||
`Request quota exhausted for request ${options.method} ${options.url}`
|
||||
);
|
||||
|
||||
// Retry twice after hitting a rate limit error, then give up
|
||||
if (options.request.retryCount <= 2) {
|
||||
console.log(`Retrying after ${retryAfter} seconds!`);
|
||||
return true;
|
||||
}
|
||||
},
|
||||
onAbuseLimit: (retryAfter, options) => {
|
||||
// does not retry, only logs a warning
|
||||
octokit.log.warn(
|
||||
`Abuse detected for request ${options.method} ${options.url}`
|
||||
);
|
||||
},
|
||||
}
|
||||
});
|
||||
|
||||
let assetDir = process.env.ASSET_DIR;
|
||||
let tagToSearchFor = process.env.TAG_TO_SEARCH_FOR.split("refs/tags/")[1];
|
||||
|
||||
console.log(`Searching in - ${assetDir}`);
|
||||
console.log(`Searching for tag - ${tagToSearchFor}`);
|
||||
|
||||
const { data: recentReleases } = await octokit.rest.repos.listReleases({
|
||||
owner: "PCSX2",
|
||||
repo: "pcsx2",
|
||||
per_page: 100
|
||||
});
|
||||
|
||||
let release = undefined;
|
||||
for (var i = 0; i < recentReleases.length; i++) {
|
||||
if (recentReleases[i].tag_name == tagToSearchFor) {
|
||||
release = recentReleases[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (release == undefined) {
|
||||
console.log(`Unable to find release with tag - ${tagToSearchFor}`);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
// Upload any assets we need to, don't upload assets that are already there!
|
||||
const { data: releaseAssetsPre } = await octokit.rest.repos.listReleaseAssets({
|
||||
owner: "PCSX2",
|
||||
repo: "pcsx2",
|
||||
release_id: release.id,
|
||||
per_page: 100
|
||||
});
|
||||
|
||||
import glob from 'glob';
|
||||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
glob(assetDir + `/**/*${process.env.ASSET_EXTENSION}`, {}, async (err, files) => {
|
||||
for (var i = 0; i < files.length; i++) {
|
||||
let foundDuplicate = false;
|
||||
for (var j = 0; j < releaseAssetsPre.length; j++) {
|
||||
let existingAsset = releaseAssetsPre[j];
|
||||
if (existingAsset.name == `pcsx2-${release.tag_name}-${path.basename(files[i])}`) {
|
||||
foundDuplicate = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (foundDuplicate) {
|
||||
continue;
|
||||
}
|
||||
|
||||
var assetBytes = fs.readFileSync(files[i], null);
|
||||
const { data: uploadAsset } = await octokit.rest.repos.uploadReleaseAsset({
|
||||
owner: "PCSX2",
|
||||
repo: "pcsx2",
|
||||
release_id: release.id,
|
||||
name: `pcsx2-${release.tag_name}-${path.basename(files[i])}`,
|
||||
data: assetBytes,
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// Ideally there would be a webhook event for when an artifact is added to a draft release
|
||||
// unfortunately, such a thing does not exist yet. Therefore, we have to wait a bit
|
||||
// for the API to become consistent
|
||||
// TODO - future work - we could check previous draft releases to become eventually consistent as well
|
||||
// - draft releases should only be a temporary state, so anything that remains a draft had a problem
|
||||
await new Promise(resolve => setTimeout(resolve, 10 * 1000));
|
||||
|
||||
// Poll the release, and check to see if it's ready to be published
|
||||
const { data: releaseAssetsPost } = await octokit.rest.repos.listReleaseAssets({
|
||||
owner: "PCSX2",
|
||||
repo: "pcsx2",
|
||||
release_id: release.id,
|
||||
per_page: 100
|
||||
});
|
||||
|
||||
// Expected Assets, if we have all of them, we will publish it
|
||||
let expectedAssets = {
|
||||
"windows-32bit-sse4": false,
|
||||
"windows-32bit-avx2": false,
|
||||
"windows-64bit-sse4": false,
|
||||
"windows-64bit-avx2": false,
|
||||
"linux-appimage-32bit": false,
|
||||
"linux-appimage-64bit": false
|
||||
}
|
||||
|
||||
for (var i = 0; i < releaseAssetsPost.length; i++) {
|
||||
let asset = releaseAssetsPost[i];
|
||||
if (asset.name.includes("symbols")) {
|
||||
continue;
|
||||
}
|
||||
for (var j = 0; j < Object.keys(expectedAssets).length; j++) {
|
||||
let expectedNamePrefix = Object.keys(expectedAssets)[j];
|
||||
if (asset.name.toLowerCase().includes(expectedNamePrefix)) {
|
||||
expectedAssets[expectedNamePrefix] = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
console.log(expectedAssets);
|
||||
|
||||
if (Object.values(expectedAssets).every(Boolean)) {
|
||||
await octokit.rest.repos.updateRelease({
|
||||
owner: "PCSX2",
|
||||
repo: "pcsx2",
|
||||
release_id: release.id,
|
||||
draft: false
|
||||
});
|
||||
}
|
||||
973
.github/workflows/scripts/releases/upload-release-artifacts/package-lock.json
generated
vendored
973
.github/workflows/scripts/releases/upload-release-artifacts/package-lock.json
generated
vendored
@@ -1,973 +0,0 @@
|
||||
{
|
||||
"name": "upload-release-artifacts",
|
||||
"version": "1.0.0",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"version": "1.0.0",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@octokit/plugin-retry": "^3.0.9",
|
||||
"@octokit/plugin-throttling": "^3.5.2",
|
||||
"@octokit/rest": "^18.12.0",
|
||||
"discord.js": "^13.2.0",
|
||||
"glob": "^7.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@discordjs/builders": {
|
||||
"version": "0.6.0",
|
||||
"resolved": "https://registry.npmjs.org/@discordjs/builders/-/builders-0.6.0.tgz",
|
||||
"integrity": "sha512-mH3Gx61LKk2CD05laCI9K5wp+a3NyASHDUGx83DGJFkqJlRlSV5WMJNY6RS37A5SjqDtGMF4wVR9jzFaqShe6Q==",
|
||||
"dependencies": {
|
||||
"@sindresorhus/is": "^4.0.1",
|
||||
"discord-api-types": "^0.22.0",
|
||||
"ow": "^0.27.0",
|
||||
"ts-mixer": "^6.0.0",
|
||||
"tslib": "^2.3.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.0.0",
|
||||
"npm": ">=7.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@discordjs/builders/node_modules/discord-api-types": {
|
||||
"version": "0.22.0",
|
||||
"resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.22.0.tgz",
|
||||
"integrity": "sha512-l8yD/2zRbZItUQpy7ZxBJwaLX/Bs2TGaCthRppk8Sw24LOIWg12t9JEreezPoYD0SQcC2htNNo27kYEpYW/Srg==",
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@discordjs/collection": {
|
||||
"version": "0.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-0.2.1.tgz",
|
||||
"integrity": "sha512-vhxqzzM8gkomw0TYRF3tgx7SwElzUlXT/Aa41O7mOcyN6wIJfj5JmDWaO5XGKsGSsNx7F3i5oIlrucCCWV1Nog==",
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@discordjs/form-data": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@discordjs/form-data/-/form-data-3.0.1.tgz",
|
||||
"integrity": "sha512-ZfFsbgEXW71Rw/6EtBdrP5VxBJy4dthyC0tpQKGKmYFImlmmrykO14Za+BiIVduwjte0jXEBlhSKf0MWbFp9Eg==",
|
||||
"dependencies": {
|
||||
"asynckit": "^0.4.0",
|
||||
"combined-stream": "^1.0.8",
|
||||
"mime-types": "^2.1.12"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/auth-token": {
|
||||
"version": "2.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-2.5.0.tgz",
|
||||
"integrity": "sha512-r5FVUJCOLl19AxiuZD2VRZ/ORjp/4IN98Of6YJoJOkY75CIBuYfmiNHGrDwXr+aLGG55igl9QrxX3hbiXlLb+g==",
|
||||
"dependencies": {
|
||||
"@octokit/types": "^6.0.3"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/core": {
|
||||
"version": "3.5.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/core/-/core-3.5.1.tgz",
|
||||
"integrity": "sha512-omncwpLVxMP+GLpLPgeGJBF6IWJFjXDS5flY5VbppePYX9XehevbDykRH9PdCdvqt9TS5AOTiDide7h0qrkHjw==",
|
||||
"dependencies": {
|
||||
"@octokit/auth-token": "^2.4.4",
|
||||
"@octokit/graphql": "^4.5.8",
|
||||
"@octokit/request": "^5.6.0",
|
||||
"@octokit/request-error": "^2.0.5",
|
||||
"@octokit/types": "^6.0.3",
|
||||
"before-after-hook": "^2.2.0",
|
||||
"universal-user-agent": "^6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/endpoint": {
|
||||
"version": "6.0.12",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-6.0.12.tgz",
|
||||
"integrity": "sha512-lF3puPwkQWGfkMClXb4k/eUT/nZKQfxinRWJrdZaJO85Dqwo/G0yOC434Jr2ojwafWJMYqFGFa5ms4jJUgujdA==",
|
||||
"dependencies": {
|
||||
"@octokit/types": "^6.0.3",
|
||||
"is-plain-object": "^5.0.0",
|
||||
"universal-user-agent": "^6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/graphql": {
|
||||
"version": "4.8.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-4.8.0.tgz",
|
||||
"integrity": "sha512-0gv+qLSBLKF0z8TKaSKTsS39scVKF9dbMxJpj3U0vC7wjNWFuIpL/z76Qe2fiuCbDRcJSavkXsVtMS6/dtQQsg==",
|
||||
"dependencies": {
|
||||
"@octokit/request": "^5.6.0",
|
||||
"@octokit/types": "^6.0.3",
|
||||
"universal-user-agent": "^6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/openapi-types": {
|
||||
"version": "11.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-11.1.0.tgz",
|
||||
"integrity": "sha512-dWZfYvCCdjZzDYA3lIAMF72Q0jld8xidqCq5Ryw09eBJXZdcM6he0vWBTvw/b5UnGYqexxOyHWgfrsTlUJL3Gw=="
|
||||
},
|
||||
"node_modules/@octokit/plugin-paginate-rest": {
|
||||
"version": "2.16.9",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-2.16.9.tgz",
|
||||
"integrity": "sha512-gfSCMgz5scFKsR0dW4jaYsDJVt/UwCHp4dF7sHlmSekZvwzvLiOAGZ4MQkEsL5DW9hIk2W+UQkYZMTA1b6Wsqw==",
|
||||
"dependencies": {
|
||||
"@octokit/types": "^6.33.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/plugin-request-log": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-1.0.4.tgz",
|
||||
"integrity": "sha512-mLUsMkgP7K/cnFEw07kWqXGF5LKrOkD+lhCrKvPHXWDywAwuDUeDwWBpc69XK3pNX0uKiVt8g5z96PJ6z9xCFA=="
|
||||
},
|
||||
"node_modules/@octokit/plugin-rest-endpoint-methods": {
|
||||
"version": "5.12.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-5.12.1.tgz",
|
||||
"integrity": "sha512-0nY3htfl6x9UkPcqv8pm9vOC/bTA7f4IMDWln13neHRdNWQvOQgZ9fRxK7BAc74rye4yVINEFi9Yb9rnGUvosA==",
|
||||
"dependencies": {
|
||||
"@octokit/types": "^6.33.0",
|
||||
"deprecation": "^2.3.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/plugin-retry": {
|
||||
"version": "3.0.9",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/plugin-retry/-/plugin-retry-3.0.9.tgz",
|
||||
"integrity": "sha512-r+fArdP5+TG6l1Rv/C9hVoty6tldw6cE2pRHNGmFPdyfrc696R6JjrQ3d7HdVqGwuzfyrcaLAKD7K8TX8aehUQ==",
|
||||
"dependencies": {
|
||||
"@octokit/types": "^6.0.3",
|
||||
"bottleneck": "^2.15.3"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/plugin-throttling": {
|
||||
"version": "3.5.2",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/plugin-throttling/-/plugin-throttling-3.5.2.tgz",
|
||||
"integrity": "sha512-Eu7kfJxU8vmHqWGNszWpg+GVp2tnAfax3XQV5CkYPEE69C+KvInJXW9WajgSeW+cxYe0UVdouzCtcreGNuJo7A==",
|
||||
"dependencies": {
|
||||
"@octokit/types": "^6.0.1",
|
||||
"bottleneck": "^2.15.3"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/request": {
|
||||
"version": "5.6.2",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.6.2.tgz",
|
||||
"integrity": "sha512-je66CvSEVf0jCpRISxkUcCa0UkxmFs6eGDRSbfJtAVwbLH5ceqF+YEyC8lj8ystKyZTy8adWr0qmkY52EfOeLA==",
|
||||
"dependencies": {
|
||||
"@octokit/endpoint": "^6.0.1",
|
||||
"@octokit/request-error": "^2.1.0",
|
||||
"@octokit/types": "^6.16.1",
|
||||
"is-plain-object": "^5.0.0",
|
||||
"node-fetch": "^2.6.1",
|
||||
"universal-user-agent": "^6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/request-error": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-2.1.0.tgz",
|
||||
"integrity": "sha512-1VIvgXxs9WHSjicsRwq8PlR2LR2x6DwsJAaFgzdi0JfJoGSO8mYI/cHJQ+9FbN21aa+DrgNLnwObmyeSC8Rmpg==",
|
||||
"dependencies": {
|
||||
"@octokit/types": "^6.0.3",
|
||||
"deprecation": "^2.0.0",
|
||||
"once": "^1.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/rest": {
|
||||
"version": "18.12.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-18.12.0.tgz",
|
||||
"integrity": "sha512-gDPiOHlyGavxr72y0guQEhLsemgVjwRePayJ+FcKc2SJqKUbxbkvf5kAZEWA/MKvsfYlQAMVzNJE3ezQcxMJ2Q==",
|
||||
"dependencies": {
|
||||
"@octokit/core": "^3.5.1",
|
||||
"@octokit/plugin-paginate-rest": "^2.16.8",
|
||||
"@octokit/plugin-request-log": "^1.0.4",
|
||||
"@octokit/plugin-rest-endpoint-methods": "^5.12.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/types": {
|
||||
"version": "6.33.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-6.33.0.tgz",
|
||||
"integrity": "sha512-0zffZ048M0UhthyPXQHLz4038Ak46nMWZXkzlXvXB/M/L1jYPBceq4iZj4qjKVrvveaJrrgKdJ9+3yUuITfcCw==",
|
||||
"dependencies": {
|
||||
"@octokit/openapi-types": "^11.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@sapphire/async-queue": {
|
||||
"version": "1.1.6",
|
||||
"resolved": "https://registry.npmjs.org/@sapphire/async-queue/-/async-queue-1.1.6.tgz",
|
||||
"integrity": "sha512-M5CbgMgesemMUCQo5G/InGHvp+GZx6uuJNV1iwvSWD8EFNVrfxaTcqhcAXM3MPYkjlxvNnoDNk0R1lfzvca6LA==",
|
||||
"engines": {
|
||||
"node": ">=v14.18.0",
|
||||
"npm": ">=7.24.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@sindresorhus/is": {
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.2.0.tgz",
|
||||
"integrity": "sha512-VkE3KLBmJwcCaVARtQpfuKcKv8gcBmUubrfHGF84dXuuW6jgsRYxPtzcIhPyK9WAPpRt2/xY6zkD9MnRaJzSyw==",
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sindresorhus/is?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "16.10.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-16.10.3.tgz",
|
||||
"integrity": "sha512-ho3Ruq+fFnBrZhUYI46n/bV2GjwzSkwuT4dTf0GkuNFmnb8nq4ny2z9JEVemFi6bdEJanHLlYfy9c6FN9B9McQ=="
|
||||
},
|
||||
"node_modules/@types/ws": {
|
||||
"version": "8.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.2.0.tgz",
|
||||
"integrity": "sha512-cyeefcUCgJlEk+hk2h3N+MqKKsPViQgF5boi9TTHSK+PoR9KWBb/C5ccPcDyAqgsbAYHTwulch725DV84+pSpg==",
|
||||
"dependencies": {
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/asynckit": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
|
||||
"integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k="
|
||||
},
|
||||
"node_modules/balanced-match": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
|
||||
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
|
||||
},
|
||||
"node_modules/before-after-hook": {
|
||||
"version": "2.2.2",
|
||||
"resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.2.tgz",
|
||||
"integrity": "sha512-3pZEU3NT5BFUo/AD5ERPWOgQOCZITni6iavr5AUw5AUwQjMlI0kzu5btnyD39AF0gUEsDPwJT+oY1ORBJijPjQ=="
|
||||
},
|
||||
"node_modules/bottleneck": {
|
||||
"version": "2.19.5",
|
||||
"resolved": "https://registry.npmjs.org/bottleneck/-/bottleneck-2.19.5.tgz",
|
||||
"integrity": "sha512-VHiNCbI1lKdl44tGrhNfU3lup0Tj/ZBMJB5/2ZbNXRCPuRCO7ed2mgcK4r17y+KB2EfuYuRaVlwNbAeaWGSpbw=="
|
||||
},
|
||||
"node_modules/brace-expansion": {
|
||||
"version": "1.1.11",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
||||
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
|
||||
"dependencies": {
|
||||
"balanced-match": "^1.0.0",
|
||||
"concat-map": "0.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/callsites": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
|
||||
"integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/combined-stream": {
|
||||
"version": "1.0.8",
|
||||
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
|
||||
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
|
||||
"dependencies": {
|
||||
"delayed-stream": "~1.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/concat-map": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
||||
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
|
||||
},
|
||||
"node_modules/delayed-stream": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
|
||||
"integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=",
|
||||
"engines": {
|
||||
"node": ">=0.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/deprecation": {
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz",
|
||||
"integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ=="
|
||||
},
|
||||
"node_modules/discord-api-types": {
|
||||
"version": "0.23.1",
|
||||
"resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.23.1.tgz",
|
||||
"integrity": "sha512-igWmn+45mzXRWNEPU25I/pr8MwxHb767wAr51oy3VRLRcTlp5ADBbrBR0lq3SA1Rfw3MtM4TQu1xo3kxscfVdQ==",
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/discord.js": {
|
||||
"version": "13.2.0",
|
||||
"resolved": "https://registry.npmjs.org/discord.js/-/discord.js-13.2.0.tgz",
|
||||
"integrity": "sha512-nyxUvL8wuQG38zx13wUMkpcA8koFszyiXdkSLwwM9opKW2LC2H5gD0cTZxImeJ6GtEnKPWT8xBiE8lLBmbNIhw==",
|
||||
"dependencies": {
|
||||
"@discordjs/builders": "^0.6.0",
|
||||
"@discordjs/collection": "^0.2.1",
|
||||
"@discordjs/form-data": "^3.0.1",
|
||||
"@sapphire/async-queue": "^1.1.5",
|
||||
"@types/ws": "^8.2.0",
|
||||
"discord-api-types": "^0.23.1",
|
||||
"node-fetch": "^2.6.1",
|
||||
"ws": "^8.2.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16.6.0",
|
||||
"npm": ">=7.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/dot-prop": {
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-6.0.1.tgz",
|
||||
"integrity": "sha512-tE7ztYzXHIeyvc7N+hR3oi7FIbf/NIjVP9hmAt3yMXzrQ072/fpjGLx2GxNxGxUl5V73MEqYzioOMoVhGMJ5cA==",
|
||||
"dependencies": {
|
||||
"is-obj": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/fs.realpath": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
|
||||
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
|
||||
},
|
||||
"node_modules/glob": {
|
||||
"version": "7.2.0",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz",
|
||||
"integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==",
|
||||
"dependencies": {
|
||||
"fs.realpath": "^1.0.0",
|
||||
"inflight": "^1.0.4",
|
||||
"inherits": "2",
|
||||
"minimatch": "^3.0.4",
|
||||
"once": "^1.3.0",
|
||||
"path-is-absolute": "^1.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/inflight": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
|
||||
"integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
|
||||
"dependencies": {
|
||||
"once": "^1.3.0",
|
||||
"wrappy": "1"
|
||||
}
|
||||
},
|
||||
"node_modules/inherits": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
|
||||
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
|
||||
},
|
||||
"node_modules/is-obj": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz",
|
||||
"integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/is-plain-object": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz",
|
||||
"integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/lodash.isequal": {
|
||||
"version": "4.5.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz",
|
||||
"integrity": "sha1-QVxEePK8wwEgwizhDtMib30+GOA="
|
||||
},
|
||||
"node_modules/mime-db": {
|
||||
"version": "1.50.0",
|
||||
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.50.0.tgz",
|
||||
"integrity": "sha512-9tMZCDlYHqeERXEHO9f/hKfNXhre5dK2eE/krIvUjZbS2KPcqGDfNShIWS1uW9XOTKQKqK6qbeOci18rbfW77A==",
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/mime-types": {
|
||||
"version": "2.1.33",
|
||||
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.33.tgz",
|
||||
"integrity": "sha512-plLElXp7pRDd0bNZHw+nMd52vRYjLwQjygaNg7ddJ2uJtTlmnTCjWuPKxVu6//AdaRuME84SvLW91sIkBqGT0g==",
|
||||
"dependencies": {
|
||||
"mime-db": "1.50.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/minimatch": {
|
||||
"version": "3.0.4",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
|
||||
"integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
|
||||
"dependencies": {
|
||||
"brace-expansion": "^1.1.7"
|
||||
},
|
||||
"engines": {
|
||||
"node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/node-fetch": {
|
||||
"version": "2.6.5",
|
||||
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.5.tgz",
|
||||
"integrity": "sha512-mmlIVHJEu5rnIxgEgez6b9GgWXbkZj5YZ7fx+2r94a2E+Uirsp6HsPTPlomfdHtpt/B0cdKviwkoaM6pyvUOpQ==",
|
||||
"dependencies": {
|
||||
"whatwg-url": "^5.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "4.x || >=6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/once": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
|
||||
"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
|
||||
"dependencies": {
|
||||
"wrappy": "1"
|
||||
}
|
||||
},
|
||||
"node_modules/ow": {
|
||||
"version": "0.27.0",
|
||||
"resolved": "https://registry.npmjs.org/ow/-/ow-0.27.0.tgz",
|
||||
"integrity": "sha512-SGnrGUbhn4VaUGdU0EJLMwZWSupPmF46hnTRII7aCLCrqixTAC5eKo8kI4/XXf1eaaI8YEVT+3FeGNJI9himAQ==",
|
||||
"dependencies": {
|
||||
"@sindresorhus/is": "^4.0.1",
|
||||
"callsites": "^3.1.0",
|
||||
"dot-prop": "^6.0.1",
|
||||
"lodash.isequal": "^4.5.0",
|
||||
"type-fest": "^1.2.1",
|
||||
"vali-date": "^1.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/path-is-absolute": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
|
||||
"integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/tr46": {
|
||||
"version": "0.0.3",
|
||||
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
|
||||
"integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o="
|
||||
},
|
||||
"node_modules/ts-mixer": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ts-mixer/-/ts-mixer-6.0.0.tgz",
|
||||
"integrity": "sha512-nXIb1fvdY5CBSrDIblLn73NW0qRDk5yJ0Sk1qPBF560OdJfQp9jhl+0tzcY09OZ9U+6GpeoI9RjwoIKFIoB9MQ=="
|
||||
},
|
||||
"node_modules/tslib": {
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",
|
||||
"integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw=="
|
||||
},
|
||||
"node_modules/type-fest": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz",
|
||||
"integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==",
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/universal-user-agent": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.0.tgz",
|
||||
"integrity": "sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w=="
|
||||
},
|
||||
"node_modules/vali-date": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/vali-date/-/vali-date-1.0.0.tgz",
|
||||
"integrity": "sha1-G5BKWWCfsyjvB4E4Qgk09rhnCaY=",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/webidl-conversions": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
|
||||
"integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE="
|
||||
},
|
||||
"node_modules/whatwg-url": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
|
||||
"integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=",
|
||||
"dependencies": {
|
||||
"tr46": "~0.0.3",
|
||||
"webidl-conversions": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/wrappy": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
|
||||
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
|
||||
},
|
||||
"node_modules/ws": {
|
||||
"version": "8.2.3",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-8.2.3.tgz",
|
||||
"integrity": "sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA==",
|
||||
"engines": {
|
||||
"node": ">=10.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"bufferutil": "^4.0.1",
|
||||
"utf-8-validate": "^5.0.2"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"bufferutil": {
|
||||
"optional": true
|
||||
},
|
||||
"utf-8-validate": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"@discordjs/builders": {
|
||||
"version": "0.6.0",
|
||||
"resolved": "https://registry.npmjs.org/@discordjs/builders/-/builders-0.6.0.tgz",
|
||||
"integrity": "sha512-mH3Gx61LKk2CD05laCI9K5wp+a3NyASHDUGx83DGJFkqJlRlSV5WMJNY6RS37A5SjqDtGMF4wVR9jzFaqShe6Q==",
|
||||
"requires": {
|
||||
"@sindresorhus/is": "^4.0.1",
|
||||
"discord-api-types": "^0.22.0",
|
||||
"ow": "^0.27.0",
|
||||
"ts-mixer": "^6.0.0",
|
||||
"tslib": "^2.3.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"discord-api-types": {
|
||||
"version": "0.22.0",
|
||||
"resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.22.0.tgz",
|
||||
"integrity": "sha512-l8yD/2zRbZItUQpy7ZxBJwaLX/Bs2TGaCthRppk8Sw24LOIWg12t9JEreezPoYD0SQcC2htNNo27kYEpYW/Srg=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"@discordjs/collection": {
|
||||
"version": "0.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-0.2.1.tgz",
|
||||
"integrity": "sha512-vhxqzzM8gkomw0TYRF3tgx7SwElzUlXT/Aa41O7mOcyN6wIJfj5JmDWaO5XGKsGSsNx7F3i5oIlrucCCWV1Nog=="
|
||||
},
|
||||
"@discordjs/form-data": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@discordjs/form-data/-/form-data-3.0.1.tgz",
|
||||
"integrity": "sha512-ZfFsbgEXW71Rw/6EtBdrP5VxBJy4dthyC0tpQKGKmYFImlmmrykO14Za+BiIVduwjte0jXEBlhSKf0MWbFp9Eg==",
|
||||
"requires": {
|
||||
"asynckit": "^0.4.0",
|
||||
"combined-stream": "^1.0.8",
|
||||
"mime-types": "^2.1.12"
|
||||
}
|
||||
},
|
||||
"@octokit/auth-token": {
|
||||
"version": "2.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-2.5.0.tgz",
|
||||
"integrity": "sha512-r5FVUJCOLl19AxiuZD2VRZ/ORjp/4IN98Of6YJoJOkY75CIBuYfmiNHGrDwXr+aLGG55igl9QrxX3hbiXlLb+g==",
|
||||
"requires": {
|
||||
"@octokit/types": "^6.0.3"
|
||||
}
|
||||
},
|
||||
"@octokit/core": {
|
||||
"version": "3.5.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/core/-/core-3.5.1.tgz",
|
||||
"integrity": "sha512-omncwpLVxMP+GLpLPgeGJBF6IWJFjXDS5flY5VbppePYX9XehevbDykRH9PdCdvqt9TS5AOTiDide7h0qrkHjw==",
|
||||
"requires": {
|
||||
"@octokit/auth-token": "^2.4.4",
|
||||
"@octokit/graphql": "^4.5.8",
|
||||
"@octokit/request": "^5.6.0",
|
||||
"@octokit/request-error": "^2.0.5",
|
||||
"@octokit/types": "^6.0.3",
|
||||
"before-after-hook": "^2.2.0",
|
||||
"universal-user-agent": "^6.0.0"
|
||||
}
|
||||
},
|
||||
"@octokit/endpoint": {
|
||||
"version": "6.0.12",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-6.0.12.tgz",
|
||||
"integrity": "sha512-lF3puPwkQWGfkMClXb4k/eUT/nZKQfxinRWJrdZaJO85Dqwo/G0yOC434Jr2ojwafWJMYqFGFa5ms4jJUgujdA==",
|
||||
"requires": {
|
||||
"@octokit/types": "^6.0.3",
|
||||
"is-plain-object": "^5.0.0",
|
||||
"universal-user-agent": "^6.0.0"
|
||||
}
|
||||
},
|
||||
"@octokit/graphql": {
|
||||
"version": "4.8.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-4.8.0.tgz",
|
||||
"integrity": "sha512-0gv+qLSBLKF0z8TKaSKTsS39scVKF9dbMxJpj3U0vC7wjNWFuIpL/z76Qe2fiuCbDRcJSavkXsVtMS6/dtQQsg==",
|
||||
"requires": {
|
||||
"@octokit/request": "^5.6.0",
|
||||
"@octokit/types": "^6.0.3",
|
||||
"universal-user-agent": "^6.0.0"
|
||||
}
|
||||
},
|
||||
"@octokit/openapi-types": {
|
||||
"version": "11.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-11.1.0.tgz",
|
||||
"integrity": "sha512-dWZfYvCCdjZzDYA3lIAMF72Q0jld8xidqCq5Ryw09eBJXZdcM6he0vWBTvw/b5UnGYqexxOyHWgfrsTlUJL3Gw=="
|
||||
},
|
||||
"@octokit/plugin-paginate-rest": {
|
||||
"version": "2.16.9",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-2.16.9.tgz",
|
||||
"integrity": "sha512-gfSCMgz5scFKsR0dW4jaYsDJVt/UwCHp4dF7sHlmSekZvwzvLiOAGZ4MQkEsL5DW9hIk2W+UQkYZMTA1b6Wsqw==",
|
||||
"requires": {
|
||||
"@octokit/types": "^6.33.0"
|
||||
}
|
||||
},
|
||||
"@octokit/plugin-request-log": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-1.0.4.tgz",
|
||||
"integrity": "sha512-mLUsMkgP7K/cnFEw07kWqXGF5LKrOkD+lhCrKvPHXWDywAwuDUeDwWBpc69XK3pNX0uKiVt8g5z96PJ6z9xCFA=="
|
||||
},
|
||||
"@octokit/plugin-rest-endpoint-methods": {
|
||||
"version": "5.12.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-5.12.1.tgz",
|
||||
"integrity": "sha512-0nY3htfl6x9UkPcqv8pm9vOC/bTA7f4IMDWln13neHRdNWQvOQgZ9fRxK7BAc74rye4yVINEFi9Yb9rnGUvosA==",
|
||||
"requires": {
|
||||
"@octokit/types": "^6.33.0",
|
||||
"deprecation": "^2.3.1"
|
||||
}
|
||||
},
|
||||
"@octokit/plugin-retry": {
|
||||
"version": "3.0.9",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/plugin-retry/-/plugin-retry-3.0.9.tgz",
|
||||
"integrity": "sha512-r+fArdP5+TG6l1Rv/C9hVoty6tldw6cE2pRHNGmFPdyfrc696R6JjrQ3d7HdVqGwuzfyrcaLAKD7K8TX8aehUQ==",
|
||||
"requires": {
|
||||
"@octokit/types": "^6.0.3",
|
||||
"bottleneck": "^2.15.3"
|
||||
}
|
||||
},
|
||||
"@octokit/plugin-throttling": {
|
||||
"version": "3.5.2",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/plugin-throttling/-/plugin-throttling-3.5.2.tgz",
|
||||
"integrity": "sha512-Eu7kfJxU8vmHqWGNszWpg+GVp2tnAfax3XQV5CkYPEE69C+KvInJXW9WajgSeW+cxYe0UVdouzCtcreGNuJo7A==",
|
||||
"requires": {
|
||||
"@octokit/types": "^6.0.1",
|
||||
"bottleneck": "^2.15.3"
|
||||
}
|
||||
},
|
||||
"@octokit/request": {
|
||||
"version": "5.6.2",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.6.2.tgz",
|
||||
"integrity": "sha512-je66CvSEVf0jCpRISxkUcCa0UkxmFs6eGDRSbfJtAVwbLH5ceqF+YEyC8lj8ystKyZTy8adWr0qmkY52EfOeLA==",
|
||||
"requires": {
|
||||
"@octokit/endpoint": "^6.0.1",
|
||||
"@octokit/request-error": "^2.1.0",
|
||||
"@octokit/types": "^6.16.1",
|
||||
"is-plain-object": "^5.0.0",
|
||||
"node-fetch": "^2.6.1",
|
||||
"universal-user-agent": "^6.0.0"
|
||||
}
|
||||
},
|
||||
"@octokit/request-error": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-2.1.0.tgz",
|
||||
"integrity": "sha512-1VIvgXxs9WHSjicsRwq8PlR2LR2x6DwsJAaFgzdi0JfJoGSO8mYI/cHJQ+9FbN21aa+DrgNLnwObmyeSC8Rmpg==",
|
||||
"requires": {
|
||||
"@octokit/types": "^6.0.3",
|
||||
"deprecation": "^2.0.0",
|
||||
"once": "^1.4.0"
|
||||
}
|
||||
},
|
||||
"@octokit/rest": {
|
||||
"version": "18.12.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-18.12.0.tgz",
|
||||
"integrity": "sha512-gDPiOHlyGavxr72y0guQEhLsemgVjwRePayJ+FcKc2SJqKUbxbkvf5kAZEWA/MKvsfYlQAMVzNJE3ezQcxMJ2Q==",
|
||||
"requires": {
|
||||
"@octokit/core": "^3.5.1",
|
||||
"@octokit/plugin-paginate-rest": "^2.16.8",
|
||||
"@octokit/plugin-request-log": "^1.0.4",
|
||||
"@octokit/plugin-rest-endpoint-methods": "^5.12.0"
|
||||
}
|
||||
},
|
||||
"@octokit/types": {
|
||||
"version": "6.33.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-6.33.0.tgz",
|
||||
"integrity": "sha512-0zffZ048M0UhthyPXQHLz4038Ak46nMWZXkzlXvXB/M/L1jYPBceq4iZj4qjKVrvveaJrrgKdJ9+3yUuITfcCw==",
|
||||
"requires": {
|
||||
"@octokit/openapi-types": "^11.1.0"
|
||||
}
|
||||
},
|
||||
"@sapphire/async-queue": {
|
||||
"version": "1.1.6",
|
||||
"resolved": "https://registry.npmjs.org/@sapphire/async-queue/-/async-queue-1.1.6.tgz",
|
||||
"integrity": "sha512-M5CbgMgesemMUCQo5G/InGHvp+GZx6uuJNV1iwvSWD8EFNVrfxaTcqhcAXM3MPYkjlxvNnoDNk0R1lfzvca6LA=="
|
||||
},
|
||||
"@sindresorhus/is": {
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.2.0.tgz",
|
||||
"integrity": "sha512-VkE3KLBmJwcCaVARtQpfuKcKv8gcBmUubrfHGF84dXuuW6jgsRYxPtzcIhPyK9WAPpRt2/xY6zkD9MnRaJzSyw=="
|
||||
},
|
||||
"@types/node": {
|
||||
"version": "16.10.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-16.10.3.tgz",
|
||||
"integrity": "sha512-ho3Ruq+fFnBrZhUYI46n/bV2GjwzSkwuT4dTf0GkuNFmnb8nq4ny2z9JEVemFi6bdEJanHLlYfy9c6FN9B9McQ=="
|
||||
},
|
||||
"@types/ws": {
|
||||
"version": "8.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.2.0.tgz",
|
||||
"integrity": "sha512-cyeefcUCgJlEk+hk2h3N+MqKKsPViQgF5boi9TTHSK+PoR9KWBb/C5ccPcDyAqgsbAYHTwulch725DV84+pSpg==",
|
||||
"requires": {
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"asynckit": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
|
||||
"integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k="
|
||||
},
|
||||
"balanced-match": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
|
||||
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
|
||||
},
|
||||
"before-after-hook": {
|
||||
"version": "2.2.2",
|
||||
"resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.2.tgz",
|
||||
"integrity": "sha512-3pZEU3NT5BFUo/AD5ERPWOgQOCZITni6iavr5AUw5AUwQjMlI0kzu5btnyD39AF0gUEsDPwJT+oY1ORBJijPjQ=="
|
||||
},
|
||||
"bottleneck": {
|
||||
"version": "2.19.5",
|
||||
"resolved": "https://registry.npmjs.org/bottleneck/-/bottleneck-2.19.5.tgz",
|
||||
"integrity": "sha512-VHiNCbI1lKdl44tGrhNfU3lup0Tj/ZBMJB5/2ZbNXRCPuRCO7ed2mgcK4r17y+KB2EfuYuRaVlwNbAeaWGSpbw=="
|
||||
},
|
||||
"brace-expansion": {
|
||||
"version": "1.1.11",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
||||
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
|
||||
"requires": {
|
||||
"balanced-match": "^1.0.0",
|
||||
"concat-map": "0.0.1"
|
||||
}
|
||||
},
|
||||
"callsites": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
|
||||
"integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ=="
|
||||
},
|
||||
"combined-stream": {
|
||||
"version": "1.0.8",
|
||||
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
|
||||
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
|
||||
"requires": {
|
||||
"delayed-stream": "~1.0.0"
|
||||
}
|
||||
},
|
||||
"concat-map": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
||||
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
|
||||
},
|
||||
"delayed-stream": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
|
||||
"integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk="
|
||||
},
|
||||
"deprecation": {
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz",
|
||||
"integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ=="
|
||||
},
|
||||
"discord-api-types": {
|
||||
"version": "0.23.1",
|
||||
"resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.23.1.tgz",
|
||||
"integrity": "sha512-igWmn+45mzXRWNEPU25I/pr8MwxHb767wAr51oy3VRLRcTlp5ADBbrBR0lq3SA1Rfw3MtM4TQu1xo3kxscfVdQ=="
|
||||
},
|
||||
"discord.js": {
|
||||
"version": "13.2.0",
|
||||
"resolved": "https://registry.npmjs.org/discord.js/-/discord.js-13.2.0.tgz",
|
||||
"integrity": "sha512-nyxUvL8wuQG38zx13wUMkpcA8koFszyiXdkSLwwM9opKW2LC2H5gD0cTZxImeJ6GtEnKPWT8xBiE8lLBmbNIhw==",
|
||||
"requires": {
|
||||
"@discordjs/builders": "^0.6.0",
|
||||
"@discordjs/collection": "^0.2.1",
|
||||
"@discordjs/form-data": "^3.0.1",
|
||||
"@sapphire/async-queue": "^1.1.5",
|
||||
"@types/ws": "^8.2.0",
|
||||
"discord-api-types": "^0.23.1",
|
||||
"node-fetch": "^2.6.1",
|
||||
"ws": "^8.2.3"
|
||||
}
|
||||
},
|
||||
"dot-prop": {
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-6.0.1.tgz",
|
||||
"integrity": "sha512-tE7ztYzXHIeyvc7N+hR3oi7FIbf/NIjVP9hmAt3yMXzrQ072/fpjGLx2GxNxGxUl5V73MEqYzioOMoVhGMJ5cA==",
|
||||
"requires": {
|
||||
"is-obj": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"fs.realpath": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
|
||||
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
|
||||
},
|
||||
"glob": {
|
||||
"version": "7.2.0",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz",
|
||||
"integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==",
|
||||
"requires": {
|
||||
"fs.realpath": "^1.0.0",
|
||||
"inflight": "^1.0.4",
|
||||
"inherits": "2",
|
||||
"minimatch": "^3.0.4",
|
||||
"once": "^1.3.0",
|
||||
"path-is-absolute": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"inflight": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
|
||||
"integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
|
||||
"requires": {
|
||||
"once": "^1.3.0",
|
||||
"wrappy": "1"
|
||||
}
|
||||
},
|
||||
"inherits": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
|
||||
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
|
||||
},
|
||||
"is-obj": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz",
|
||||
"integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w=="
|
||||
},
|
||||
"is-plain-object": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz",
|
||||
"integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q=="
|
||||
},
|
||||
"lodash.isequal": {
|
||||
"version": "4.5.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz",
|
||||
"integrity": "sha1-QVxEePK8wwEgwizhDtMib30+GOA="
|
||||
},
|
||||
"mime-db": {
|
||||
"version": "1.50.0",
|
||||
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.50.0.tgz",
|
||||
"integrity": "sha512-9tMZCDlYHqeERXEHO9f/hKfNXhre5dK2eE/krIvUjZbS2KPcqGDfNShIWS1uW9XOTKQKqK6qbeOci18rbfW77A=="
|
||||
},
|
||||
"mime-types": {
|
||||
"version": "2.1.33",
|
||||
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.33.tgz",
|
||||
"integrity": "sha512-plLElXp7pRDd0bNZHw+nMd52vRYjLwQjygaNg7ddJ2uJtTlmnTCjWuPKxVu6//AdaRuME84SvLW91sIkBqGT0g==",
|
||||
"requires": {
|
||||
"mime-db": "1.50.0"
|
||||
}
|
||||
},
|
||||
"minimatch": {
|
||||
"version": "3.0.4",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
|
||||
"integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
|
||||
"requires": {
|
||||
"brace-expansion": "^1.1.7"
|
||||
}
|
||||
},
|
||||
"node-fetch": {
|
||||
"version": "2.6.5",
|
||||
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.5.tgz",
|
||||
"integrity": "sha512-mmlIVHJEu5rnIxgEgez6b9GgWXbkZj5YZ7fx+2r94a2E+Uirsp6HsPTPlomfdHtpt/B0cdKviwkoaM6pyvUOpQ==",
|
||||
"requires": {
|
||||
"whatwg-url": "^5.0.0"
|
||||
}
|
||||
},
|
||||
"once": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
|
||||
"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
|
||||
"requires": {
|
||||
"wrappy": "1"
|
||||
}
|
||||
},
|
||||
"ow": {
|
||||
"version": "0.27.0",
|
||||
"resolved": "https://registry.npmjs.org/ow/-/ow-0.27.0.tgz",
|
||||
"integrity": "sha512-SGnrGUbhn4VaUGdU0EJLMwZWSupPmF46hnTRII7aCLCrqixTAC5eKo8kI4/XXf1eaaI8YEVT+3FeGNJI9himAQ==",
|
||||
"requires": {
|
||||
"@sindresorhus/is": "^4.0.1",
|
||||
"callsites": "^3.1.0",
|
||||
"dot-prop": "^6.0.1",
|
||||
"lodash.isequal": "^4.5.0",
|
||||
"type-fest": "^1.2.1",
|
||||
"vali-date": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"path-is-absolute": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
|
||||
"integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18="
|
||||
},
|
||||
"tr46": {
|
||||
"version": "0.0.3",
|
||||
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
|
||||
"integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o="
|
||||
},
|
||||
"ts-mixer": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ts-mixer/-/ts-mixer-6.0.0.tgz",
|
||||
"integrity": "sha512-nXIb1fvdY5CBSrDIblLn73NW0qRDk5yJ0Sk1qPBF560OdJfQp9jhl+0tzcY09OZ9U+6GpeoI9RjwoIKFIoB9MQ=="
|
||||
},
|
||||
"tslib": {
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",
|
||||
"integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw=="
|
||||
},
|
||||
"type-fest": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz",
|
||||
"integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA=="
|
||||
},
|
||||
"universal-user-agent": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.0.tgz",
|
||||
"integrity": "sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w=="
|
||||
},
|
||||
"vali-date": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/vali-date/-/vali-date-1.0.0.tgz",
|
||||
"integrity": "sha1-G5BKWWCfsyjvB4E4Qgk09rhnCaY="
|
||||
},
|
||||
"webidl-conversions": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
|
||||
"integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE="
|
||||
},
|
||||
"whatwg-url": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
|
||||
"integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=",
|
||||
"requires": {
|
||||
"tr46": "~0.0.3",
|
||||
"webidl-conversions": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"wrappy": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
|
||||
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
|
||||
},
|
||||
"ws": {
|
||||
"version": "8.2.3",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-8.2.3.tgz",
|
||||
"integrity": "sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA==",
|
||||
"requires": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
{
|
||||
"name": "upload-release-artifacts",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@octokit/plugin-retry": "^3.0.9",
|
||||
"@octokit/plugin-throttling": "^3.5.2",
|
||||
"@octokit/rest": "^18.12.0",
|
||||
"glob": "^7.2.0"
|
||||
}
|
||||
}
|
||||
191
.github/workflows/windows-workflow.yml
vendored
191
.github/workflows/windows-workflow.yml
vendored
@@ -1,191 +0,0 @@
|
||||
name: 🖥️ Windows Builds
|
||||
|
||||
# Controls when the action will run. Triggers the workflow on push or pull request
|
||||
# events but only for the master branch
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
tags:
|
||||
- v*
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
paths-ignore:
|
||||
- '**/*.md'
|
||||
- '.clang-format'
|
||||
- '.codacy.yaml'
|
||||
- '.github/*'
|
||||
- '.github/workflows/lint-gamedb.yml'
|
||||
- '.github/workflows/linux-workflow.yml'
|
||||
- '.github/workflows/macos-workflow.yml'
|
||||
- '.github/workflows/scripts/linux/**'
|
||||
- '.github/workflows/scripts/validation/**'
|
||||
- '.gitignore'
|
||||
- 'bin/PCSX2_keys.ini.default'
|
||||
- 'build.sh'
|
||||
- 'buildbot.xml'
|
||||
- 'linux_various/**'
|
||||
- 'mscompile.cmd'
|
||||
- 'pcsx2/CDVD/Linux/**'
|
||||
- 'pcsx2/DEV9/Linux/**'
|
||||
- 'pcsx2/Linux/**'
|
||||
- 'pcsx2/PAD/Linux/**'
|
||||
- 'pcsx2/SPU2/Linux/**'
|
||||
- 'pcsx2/USB/linux/**'
|
||||
|
||||
jobs:
|
||||
build:
|
||||
strategy:
|
||||
# Prevent one build from failing everything (although maybe those should be included as experimental builds instead)
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [windows-2019]
|
||||
platform: [Win32, x64]
|
||||
configuration: [Release, Release AVX2, CMake]
|
||||
experimental: [false]
|
||||
|
||||
name: ${{ matrix.platform }} | ${{ matrix.configuration }}
|
||||
runs-on: ${{ matrix.os }}
|
||||
continue-on-error: ${{ matrix.experimental }}
|
||||
# Set some sort of timeout in the event of run-away builds. We are limited on concurrent jobs so, get rid of them.
|
||||
timeout-minutes: 60
|
||||
|
||||
env:
|
||||
POWERSHELL_TELEMETRY_OPTOUT: 1
|
||||
BUILDCACHE_COMPRESS_FORMAT: ZSTD
|
||||
BUILDCACHE_COMPRESS_LEVEL: 9
|
||||
BUILDCACHE_MAX_CACHE_SIZE: 536870912 # 512MB
|
||||
BUILDCACHE_DIRECT_MODE: true
|
||||
BUILDCACHE_LOG_FILE: ${{ github.workspace }}\buildcache.log
|
||||
|
||||
steps:
|
||||
- name: Checkout Repository
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Checkout Submodules
|
||||
run: git submodule update --init --recursive -j $env:NUMBER_OF_PROCESSORS
|
||||
|
||||
- name: Setup Buildcache
|
||||
uses: mikehardy/buildcache-action@v1.2.2
|
||||
with:
|
||||
cache_key: ${{ matrix.os }} ${{ matrix.platform }} ${{ matrix.configuration }}
|
||||
if: matrix.configuration == 'CMake' # TODO: buildcache on VS
|
||||
|
||||
- name: Verify VS Project Files
|
||||
run: .github\workflows\scripts\windows\validate-vs-filters.ps1
|
||||
if: matrix.configuration != 'CMake'
|
||||
|
||||
- name: Setup msbuild
|
||||
uses: microsoft/setup-msbuild@v1
|
||||
if: matrix.configuration != 'CMake'
|
||||
|
||||
- name: Generate CMake
|
||||
id: cmake
|
||||
shell: cmd
|
||||
run: |
|
||||
if "${{ github.event.inputs.retainDebugArtifacts }}"=="true" (SET type=RelWithDebInfo) else (SET type=Release)
|
||||
if "${{ matrix.platform }}"=="Win32" (SET vcvars=vcvarsamd64_x86.bat) else (SET vcvars=vcvars64.bat)
|
||||
call "%ProgramFiles(x86)%\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\%vcvars%"
|
||||
echo ::set-output name=buildtype::%type%
|
||||
echo ::set-output name=vcvars::%vcvars%
|
||||
cmake . -B build -DCMAKE_BUILD_TYPE=%type% -DLTO_PCSX2_CORE=ON -G Ninja -DCMAKE_C_COMPILER_LAUNCHER=..\buildcache\bin\buildcache.exe -DCMAKE_CXX_COMPILER_LAUNCHER=..\buildcache\bin\buildcache.exe -DCMAKE_DISABLE_PRECOMPILE_HEADERS=ON
|
||||
if: matrix.configuration == 'CMake'
|
||||
|
||||
- name: Build PCSX2
|
||||
shell: cmd
|
||||
env:
|
||||
# Set to 'true' to retain the .pdb / .exp / .lib, etc files which can be useful for repro'ing issues that only occur in the compiled .exe
|
||||
RetainDebuggingArtifacts: ${{ github.event.inputs.retainDebugArtifacts == 'true' }}
|
||||
run: |
|
||||
if "${{ matrix.configuration }}"=="CMake" (
|
||||
call "%ProgramFiles(x86)%\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\${{ steps.cmake.outputs.vcvars }}"
|
||||
cmake --build build --config ${{ steps.cmake.outputs.buildtype }}
|
||||
) else (
|
||||
msbuild "PCSX2_suite.sln" /m /v:m /p:Configuration="${{ matrix.configuration }}" /p:Platform="${{ matrix.platform }}"
|
||||
)
|
||||
|
||||
- name: Run Tests
|
||||
shell: cmd
|
||||
run: |
|
||||
call "%ProgramFiles(x86)%\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\${{ steps.cmake.outputs.vcvars }}"
|
||||
cmake --build build --config ${{ steps.cmake.outputs.buildtype }} --target unittests
|
||||
if: matrix.configuration == 'CMake'
|
||||
|
||||
- name: Prepare Artifact Metadata
|
||||
id: artifact-metadata
|
||||
shell: bash
|
||||
run: |
|
||||
ARCH=$([ "${{ matrix.platform }}" == Win32 ] && echo "32bit" || echo "64bit")
|
||||
case "${{ matrix.configuration }}" in
|
||||
Release) SIMD="SSE4";;
|
||||
*AVX2) SIMD="AVX2";;
|
||||
CMake) SIMD="CMake"
|
||||
cp build/pcsx2/PCSX2* bin/ ;;
|
||||
*) SIMD="UNKNOWN";;
|
||||
esac
|
||||
if [ ${{ github.event_name }} == "pull_request" ]; then
|
||||
PR_SHA=$(git rev-parse --short "${{ github.event.pull_request.head.sha }}")
|
||||
ARTIFACT_NAME="PCSX2-${ARCH}-${SIMD}"
|
||||
if [ ! -z "${{ github.event.pull_request.number }}" ]; then
|
||||
PR_NUM=${{ github.event.pull_request.number }}
|
||||
ARTIFACT_NAME="${ARTIFACT_NAME}-pr[${PR_NUM}]"
|
||||
fi
|
||||
ARTIFACT_NAME="${ARTIFACT_NAME}-sha[${PR_SHA}]"
|
||||
if [ ! -z "${{ github.event.pull_request.title }}" ]; then
|
||||
PR_TITLE=$(echo "${{ github.event.pull_request.title }}" | tr -cd '[a-zA-Z0-9[:space:]]_-')
|
||||
ARTIFACT_NAME="${ARTIFACT_NAME}-title["${PR_TITLE}""
|
||||
fi
|
||||
else
|
||||
SHA=$(git rev-parse --short "$GITHUB_SHA")
|
||||
ARTIFACT_NAME="PCSX2-${ARCH}-${SIMD}-sha[${SHA}"
|
||||
fi
|
||||
TRIMMED_ARTIFACT_NAME=$(printf "%.199s]" "$ARTIFACT_NAME")
|
||||
echo "name=$TRIMMED_ARTIFACT_NAME"
|
||||
echo "##[set-output name=name;]${TRIMMED_ARTIFACT_NAME}"
|
||||
echo "##[set-output name=arch;]${ARCH}"
|
||||
echo "##[set-output name=simd;]${SIMD}"
|
||||
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@v2
|
||||
continue-on-error: true
|
||||
with:
|
||||
name: ${{ steps.artifact-metadata.outputs.name }}
|
||||
path: |
|
||||
./bin
|
||||
!./bin/**/*.bsc
|
||||
!./bin/**/*.exp
|
||||
!./bin/**/*.ilk
|
||||
!./bin/**/*.iobj
|
||||
!./bin/**/*.ipdb
|
||||
!./bin/**/*.pdb
|
||||
!./bin/**/*.lib
|
||||
|
||||
- name: Upload artifact - with symbols
|
||||
if: matrix.configuration != 'CMake'
|
||||
uses: actions/upload-artifact@v2
|
||||
continue-on-error: true
|
||||
with:
|
||||
name: ${{ steps.artifact-metadata.outputs.name }}-symbols
|
||||
path: ./bin/**/*.pdb
|
||||
|
||||
# ---- Release / Tagging related steps ----
|
||||
- name: Prepare Build Artifacts
|
||||
if: github.repository == 'PCSX2/pcsx2' && startsWith(github.ref, 'refs/tags/') && matrix.configuration != 'CMake'
|
||||
run: |
|
||||
mkdir -p ./ci-artifacts/
|
||||
7z a ./ci-artifacts/windows-${{ steps.artifact-metadata.outputs.arch }}-${{ steps.artifact-metadata.outputs.simd }}.7z ./bin/* '-xr!*bsc' '-xr!*.exp' '-xr!*.ilk' '-xr!*.iobj' '-xr!*.ipdb' '-xr!*.pdb' '-xr!*.lib'
|
||||
7z a ./ci-artifacts/windows-${{ steps.artifact-metadata.outputs.arch }}-${{ steps.artifact-metadata.outputs.simd }}-symbols.7z ./bin/*.pdb
|
||||
ls ./ci-artifacts/
|
||||
|
||||
- name: Upload Assets and Potential Publish Release
|
||||
if: github.repository == 'PCSX2/pcsx2' && startsWith(github.ref, 'refs/tags/') && matrix.configuration != 'CMake'
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.BOT_PAT }}
|
||||
ASSET_DIR: ${{ github.WORKSPACE }}/ci-artifacts
|
||||
ASSET_EXTENSION: 7z
|
||||
TAG_TO_SEARCH_FOR: ${{ github.REF }}
|
||||
run: |
|
||||
cd ./.github/workflows/scripts/releases/upload-release-artifacts
|
||||
npm ci
|
||||
node index.js
|
||||
68
.github/workflows/windows_build_matrix.yml
vendored
Normal file
68
.github/workflows/windows_build_matrix.yml
vendored
Normal file
@@ -0,0 +1,68 @@
|
||||
name: 🖥️ Windows Builds
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- '*'
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
|
||||
jobs:
|
||||
# MSBUILD
|
||||
lint_vs_proj_files:
|
||||
name: Lint VS Project Files
|
||||
runs-on: windows-2019
|
||||
steps:
|
||||
- name: Checkout Repository
|
||||
uses: actions/checkout@v3
|
||||
- name: Verify VS Project Files
|
||||
run: .github\workflows\scripts\windows\validate-vs-filters.ps1
|
||||
|
||||
build_wx_sse4:
|
||||
needs: lint_vs_proj_files
|
||||
name: "SSE4"
|
||||
uses: ./.github/workflows/windows_build_wx.yml
|
||||
with:
|
||||
jobName: wxWidgets
|
||||
configuration: Release
|
||||
simd: "SSE4"
|
||||
secrets: inherit
|
||||
|
||||
build_wx_avx2:
|
||||
needs: lint_vs_proj_files
|
||||
name: "AVX2"
|
||||
uses: ./.github/workflows/windows_build_wx.yml
|
||||
with:
|
||||
jobName: wxWidgets
|
||||
configuration: Release AVX2
|
||||
secrets: inherit
|
||||
|
||||
build_qt_sse4:
|
||||
needs: lint_vs_proj_files
|
||||
name: "SSE4"
|
||||
uses: ./.github/workflows/windows_build_qt.yml
|
||||
with:
|
||||
jobName: Qt
|
||||
configuration: Release
|
||||
simd: "SSE4"
|
||||
secrets: inherit
|
||||
|
||||
build_qt_avx2:
|
||||
needs: lint_vs_proj_files
|
||||
name: "AVX2"
|
||||
uses: ./.github/workflows/windows_build_qt.yml
|
||||
with:
|
||||
jobName: Qt
|
||||
configuration: Release AVX2
|
||||
secrets: inherit
|
||||
|
||||
# CMAKE
|
||||
build_wx_avx2_cmake:
|
||||
name: "CMake AVX2"
|
||||
uses: ./.github/workflows/windows_build_wx.yml
|
||||
with:
|
||||
jobName: wxWidgets
|
||||
configuration: CMake
|
||||
buildSystem: cmake
|
||||
secrets: inherit
|
||||
109
.github/workflows/windows_build_qt.yml
vendored
Normal file
109
.github/workflows/windows_build_qt.yml
vendored
Normal file
@@ -0,0 +1,109 @@
|
||||
name: Windows Build Steps - Qt
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
jobName:
|
||||
required: true
|
||||
type: string
|
||||
os:
|
||||
required: false
|
||||
type: string
|
||||
default: windows-2019
|
||||
platform:
|
||||
required: false
|
||||
type: string
|
||||
default: x64
|
||||
configuration:
|
||||
required: true
|
||||
type: string
|
||||
simd:
|
||||
required: false
|
||||
type: string
|
||||
default: AVX2
|
||||
buildSystem:
|
||||
required: false
|
||||
type: string
|
||||
default: msbuild
|
||||
qt_binary_url:
|
||||
required: false
|
||||
type: string
|
||||
default: https://github.com/PCSX2/pcsx2-windows-dependencies/releases/download/2022-07-24/qt-6.3.1-x64.7z
|
||||
|
||||
jobs:
|
||||
build_windows_qt:
|
||||
name: ${{ inputs.jobName }}
|
||||
runs-on: ${{ inputs.os }}
|
||||
# Set some sort of timeout in the event of run-away builds. We are limited on concurrent jobs so, get rid of them.
|
||||
timeout-minutes: 60
|
||||
env:
|
||||
POWERSHELL_TELEMETRY_OPTOUT: 1
|
||||
BUILDCACHE_COMPRESS_FORMAT: ZSTD
|
||||
BUILDCACHE_COMPRESS_LEVEL: 9
|
||||
BUILDCACHE_MAX_CACHE_SIZE: 536870912 # 512MB
|
||||
BUILDCACHE_DIRECT_MODE: true
|
||||
BUILDCACHE_LOG_FILE: ${{ github.workspace }}\buildcache.log
|
||||
|
||||
steps:
|
||||
- name: Checkout Repository
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: Prepare Artifact Metadata
|
||||
id: artifact-metadata
|
||||
shell: bash
|
||||
env:
|
||||
OS: windows
|
||||
BUILD_SYSTEM: ${{ inputs.buildSystem }}
|
||||
GUI_FRAMEWORK: Qt
|
||||
ARCH: ${{ inputs.platform }}
|
||||
SIMD: ${{ inputs.simd }}
|
||||
EVENT_NAME: ${{ github.event_name }}
|
||||
PR_TITLE: ${{ github.event.pull_request.title }}
|
||||
PR_NUM: ${{ github.event.pull_request.number }}
|
||||
PR_SHA: ${{ github.event.pull_request.head.sha }}
|
||||
run: ./.github/workflows/scripts/common/name-artifacts.sh
|
||||
|
||||
- name: Setup msbuild
|
||||
if: inputs.configuration != 'CMake'
|
||||
uses: microsoft/setup-msbuild@v1
|
||||
|
||||
- name: Download Qt build files
|
||||
shell: cmd
|
||||
run: |
|
||||
cd 3rdparty\qt
|
||||
aria2c ${{ inputs.qt_binary_url }}
|
||||
7z x qt-*-x64.7z
|
||||
del qt-*-x64.7z
|
||||
|
||||
- name: Build PCSX2
|
||||
shell: cmd
|
||||
run: |
|
||||
if "${{ inputs.configuration }}"=="CMake" (
|
||||
call "%ProgramFiles(x86)%\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\${{ steps.cmake.outputs.vcvars }}"
|
||||
cmake --build build --config ${{ steps.cmake.outputs.buildtype }}
|
||||
) else (
|
||||
msbuild "PCSX2_qt.sln" /m /v:m /p:Configuration="${{ inputs.configuration }}" /p:Platform="${{ inputs.platform }}"
|
||||
)
|
||||
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: ${{ steps.artifact-metadata.outputs.artifact-name }}
|
||||
path: |
|
||||
./bin
|
||||
!./bin/**/*.bsc
|
||||
!./bin/**/*.exp
|
||||
!./bin/**/*.ilk
|
||||
!./bin/**/*.iobj
|
||||
!./bin/**/*.ipdb
|
||||
!./bin/**/*.pdb
|
||||
!./bin/**/*.lib
|
||||
|
||||
- name: Upload artifact - with symbols
|
||||
if: inputs.configuration != 'CMake'
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: ${{ steps.artifact-metadata.outputs.artifact-name }}-symbols
|
||||
path: ./bin/**/*.pdb
|
||||
123
.github/workflows/windows_build_wx.yml
vendored
Normal file
123
.github/workflows/windows_build_wx.yml
vendored
Normal file
@@ -0,0 +1,123 @@
|
||||
name: Windows Build Steps - wxWidgets
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
jobName:
|
||||
required: true
|
||||
type: string
|
||||
os:
|
||||
required: false
|
||||
type: string
|
||||
default: windows-2019
|
||||
platform:
|
||||
required: false
|
||||
type: string
|
||||
default: x64
|
||||
simd:
|
||||
required: false
|
||||
type: string
|
||||
default: AVX2
|
||||
buildSystem:
|
||||
required: false
|
||||
type: string
|
||||
default: msbuild
|
||||
configuration:
|
||||
required: true
|
||||
type: string
|
||||
|
||||
jobs:
|
||||
build_windows_wx:
|
||||
name: ${{ inputs.jobName }}
|
||||
runs-on: ${{ inputs.os }}
|
||||
# Set some sort of timeout in the event of run-away builds. We are limited on concurrent jobs so, get rid of them.
|
||||
timeout-minutes: 60
|
||||
env:
|
||||
POWERSHELL_TELEMETRY_OPTOUT: 1
|
||||
BUILDCACHE_COMPRESS_FORMAT: ZSTD
|
||||
BUILDCACHE_COMPRESS_LEVEL: 9
|
||||
BUILDCACHE_MAX_CACHE_SIZE: 536870912 # 512MB
|
||||
BUILDCACHE_DIRECT_MODE: true
|
||||
BUILDCACHE_LOG_FILE: ${{ github.workspace }}\buildcache.log
|
||||
|
||||
steps:
|
||||
- name: Checkout Repository
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: Prepare Artifact Metadata
|
||||
id: artifact-metadata
|
||||
shell: bash
|
||||
env:
|
||||
OS: windows
|
||||
BUILD_SYSTEM: ${{ inputs.buildSystem }}
|
||||
GUI_FRAMEWORK: wxWidgets
|
||||
ARCH: ${{ inputs.platform }}
|
||||
SIMD: ${{ inputs.simd }}
|
||||
EVENT_NAME: ${{ github.event_name }}
|
||||
PR_TITLE: ${{ github.event.pull_request.title }}
|
||||
PR_NUM: ${{ github.event.pull_request.number }}
|
||||
PR_SHA: ${{ github.event.pull_request.head.sha }}
|
||||
run: ./.github/workflows/scripts/common/name-artifacts.sh
|
||||
|
||||
- name: Setup Buildcache
|
||||
if: inputs.configuration == 'CMake' # TODO: buildcache on VS
|
||||
uses: mikehardy/buildcache-action@v1.3.0
|
||||
with:
|
||||
cache_key: ${{ inputs.os }} ${{ inputs.platform }} ${{ inputs.configuration }}
|
||||
|
||||
- name: Setup msbuild
|
||||
if: inputs.configuration != 'CMake'
|
||||
uses: microsoft/setup-msbuild@v1
|
||||
|
||||
- name: Generate CMake
|
||||
if: inputs.configuration == 'CMake'
|
||||
id: cmake
|
||||
shell: cmd
|
||||
run: |
|
||||
if "${{ github.event.inputs.retainDebugArtifacts }}"=="true" (SET type=RelWithDebInfo) else (SET type=Release)
|
||||
if "${{ inputs.platform }}"=="Win32" (SET vcvars=vcvarsamd64_x86.bat) else (SET vcvars=vcvars64.bat)
|
||||
call "%ProgramFiles(x86)%\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\%vcvars%"
|
||||
echo ::set-output name=buildtype::%type%
|
||||
echo ::set-output name=vcvars::%vcvars%
|
||||
cmake . -B build -DCMAKE_BUILD_TYPE=%type% -DLTO_PCSX2_CORE=ON -G Ninja -DCMAKE_C_COMPILER_LAUNCHER=..\buildcache\bin\buildcache.exe -DCMAKE_CXX_COMPILER_LAUNCHER=..\buildcache\bin\buildcache.exe -DCMAKE_DISABLE_PRECOMPILE_HEADERS=ON
|
||||
|
||||
- name: Build PCSX2
|
||||
shell: cmd
|
||||
run: |
|
||||
if "${{ inputs.configuration }}"=="CMake" (
|
||||
call "%ProgramFiles(x86)%\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\${{ steps.cmake.outputs.vcvars }}"
|
||||
cmake --build build --config ${{ steps.cmake.outputs.buildtype }}
|
||||
cp build/pcsx2/pcsx2* bin/
|
||||
) else (
|
||||
msbuild "PCSX2_suite.sln" /m /v:m /p:Configuration="${{ inputs.configuration }}" /p:Platform="${{ inputs.platform }}"
|
||||
)
|
||||
|
||||
- name: Run Tests
|
||||
if: inputs.configuration == 'CMake'
|
||||
shell: cmd
|
||||
run: |
|
||||
call "%ProgramFiles(x86)%\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\${{ steps.cmake.outputs.vcvars }}"
|
||||
cmake --build build --config ${{ steps.cmake.outputs.buildtype }} --target unittests
|
||||
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: ${{ steps.artifact-metadata.outputs.artifact-name }}
|
||||
path: |
|
||||
./bin
|
||||
!./bin/**/*.bsc
|
||||
!./bin/**/*.exp
|
||||
!./bin/**/*.ilk
|
||||
!./bin/**/*.iobj
|
||||
!./bin/**/*.ipdb
|
||||
!./bin/**/*.pdb
|
||||
!./bin/**/*.lib
|
||||
|
||||
- name: Upload artifact - with symbols
|
||||
if: inputs.configuration != 'CMake'
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: ${{ steps.artifact-metadata.outputs.artifact-name }}-symbols
|
||||
path: ./bin/**/*.pdb
|
||||
29
.gitignore
vendored
29
.gitignore
vendored
@@ -48,8 +48,7 @@ Thumbs.db
|
||||
Debug.txt
|
||||
install_log.txt
|
||||
padLog.txt
|
||||
GS_opengl_debug_hw.txt
|
||||
GS_opengl_debug_sw.txt
|
||||
GS_opengl_debug.txt
|
||||
|
||||
Debug
|
||||
Release
|
||||
@@ -69,17 +68,22 @@ oprofile_data/
|
||||
/.vscode*
|
||||
|
||||
/bin/**/*.dll
|
||||
/bin/**/*.dmp
|
||||
/bin/**/*.exp
|
||||
/bin/**/*.ilk
|
||||
/bin/**/*.lib
|
||||
/bin/**/*.pdb
|
||||
/bin/PCSX2
|
||||
/bin/pcsx2
|
||||
/bin/PCSX2-linux.sh
|
||||
/bin/*ReplayLoader
|
||||
/bin/PCSX2-linux.sh
|
||||
/bin/GS*.txt
|
||||
/bin/qt.conf
|
||||
/bin/bios
|
||||
/bin/cache
|
||||
/bin/cheats
|
||||
/bin/covers
|
||||
/bin/dumps
|
||||
/bin/gamesettings
|
||||
/bin/help
|
||||
/bin/inis
|
||||
/bin/logs
|
||||
@@ -87,24 +91,13 @@ oprofile_data/
|
||||
/bin/plugins
|
||||
/bin/snaps
|
||||
/bin/sstates
|
||||
/bin/textures
|
||||
/bin/translations
|
||||
/bin/inputprofiles
|
||||
/deps
|
||||
/ipch
|
||||
|
||||
!/3rdparty/libjpeg/change.log
|
||||
/3rdparty/portaudio/portaudio-2.0.pc
|
||||
/3rdparty/portaudio/bin
|
||||
/3rdparty/portaudio/bin-*
|
||||
/3rdparty/portaudio/autom4te.cache
|
||||
/3rdparty/portaudio/libtool
|
||||
/3rdparty/portaudio/config.*
|
||||
/3rdparty/portaudio/lib-stamp
|
||||
/3rdparty/portaudio/Makefile
|
||||
/3rdparty/portaudio/bindings
|
||||
/3rdparty/portaudio/test
|
||||
/3rdparty/portaudio/testcvs
|
||||
/3rdparty/portaudio/src/hostapi/asio/ASIOSDK/common
|
||||
/3rdparty/portaudio/src/hostapi/asio/ASIOSDK/host
|
||||
/3rdparty/portaudio/src/hostapi/wasapi/mingw-include
|
||||
/3rdparty/**/include/wx/setup.h
|
||||
/3rdparty/**/wx/msw/rcdefs.h
|
||||
/pcsx2/gui/Resources/*.h
|
||||
|
||||
33
.gitmodules
vendored
33
.gitmodules
vendored
@@ -1,24 +1,41 @@
|
||||
[submodule "3rdparty/xz/xz"]
|
||||
path = 3rdparty/xz/xz
|
||||
url = https://github.com/PCSX2/xz.git
|
||||
shallow = true
|
||||
[submodule "3rdparty/gtest"]
|
||||
path = 3rdparty/gtest
|
||||
url = https://github.com/google/googletest.git
|
||||
shallow = true
|
||||
[submodule "3rdparty/fmt/fmt"]
|
||||
path = 3rdparty/fmt/fmt
|
||||
url = https://github.com/fmtlib/fmt.git
|
||||
shallow = true
|
||||
[submodule "3rdparty/yaml-cpp/yaml-cpp"]
|
||||
path = 3rdparty/yaml-cpp/yaml-cpp
|
||||
url = https://github.com/jbeder/yaml-cpp.git
|
||||
shallow = true
|
||||
[submodule "3rdparty/libchdr/libchdr"]
|
||||
path = 3rdparty/libchdr/libchdr
|
||||
url = https://github.com/rtissera/libchdr.git
|
||||
shallow = true
|
||||
[submodule "3rdparty/wil"]
|
||||
path = 3rdparty/wil
|
||||
url = https://github.com/microsoft/wil.git
|
||||
branch = master
|
||||
[submodule "3rdparty/cubeb/cubeb"]
|
||||
path = 3rdparty/cubeb/cubeb
|
||||
url = https://github.com/mozilla/cubeb.git
|
||||
[submodule "3rdparty/rapidyaml/rapidyaml"]
|
||||
path = 3rdparty/rapidyaml/rapidyaml
|
||||
url = https://github.com/biojppm/rapidyaml.git
|
||||
branch = master
|
||||
[submodule "3rdparty/imgui/imgui"]
|
||||
path = 3rdparty/imgui/imgui
|
||||
url = https://github.com/ocornut/imgui.git
|
||||
[submodule "3rdparty/glslang/glslang"]
|
||||
path = 3rdparty/glslang/glslang
|
||||
url = https://github.com/KhronosGroup/glslang.git
|
||||
[submodule "3rdparty/vulkan-headers"]
|
||||
path = 3rdparty/vulkan-headers
|
||||
url = https://github.com/KhronosGroup/Vulkan-Headers.git
|
||||
[submodule "3rdparty/sdl2/SDL"]
|
||||
path = 3rdparty/sdl2/SDL
|
||||
url = https://github.com/libsdl-org/SDL.git
|
||||
[submodule "3rdparty/libzip/libzip"]
|
||||
path = 3rdparty/libzip/libzip
|
||||
url = https://github.com/nih-at/libzip.git
|
||||
[submodule "3rdparty/zstd/zstd"]
|
||||
path = 3rdparty/zstd/zstd
|
||||
url = https://github.com/facebook/zstd.git
|
||||
|
||||
8
.prettierrc.yaml
Normal file
8
.prettierrc.yaml
Normal file
@@ -0,0 +1,8 @@
|
||||
overrides:
|
||||
- files: "**/GameIndex.yaml"
|
||||
options:
|
||||
tabWidth: 2
|
||||
useTabs: false
|
||||
quoteProps: consistent
|
||||
endOfLine: auto
|
||||
proseWrap: preserve
|
||||
21
3rdparty/cpuinfo/.gitignore
vendored
Normal file
21
3rdparty/cpuinfo/.gitignore
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
# Ninja files
|
||||
build.ninja
|
||||
|
||||
# Build objects and artifacts
|
||||
deps/
|
||||
build/
|
||||
bin/
|
||||
lib/
|
||||
libs/
|
||||
obj/
|
||||
*.pyc
|
||||
*.pyo
|
||||
|
||||
# System files
|
||||
.DS_Store
|
||||
.DS_Store?
|
||||
._*
|
||||
.Spotlight-V100
|
||||
.Trashes
|
||||
ehthumbs.db
|
||||
Thumbs.db
|
||||
223
3rdparty/cpuinfo/CMakeLists.txt
vendored
Normal file
223
3rdparty/cpuinfo/CMakeLists.txt
vendored
Normal file
@@ -0,0 +1,223 @@
|
||||
CMAKE_MINIMUM_REQUIRED(VERSION 3.5 FATAL_ERROR)
|
||||
|
||||
# ---[ Setup project
|
||||
PROJECT(
|
||||
cpuinfo
|
||||
LANGUAGES C CXX
|
||||
)
|
||||
|
||||
# ---[ Options.
|
||||
SET(CPUINFO_LIBRARY_TYPE "default" CACHE STRING "Type of cpuinfo library (shared, static, or default) to build")
|
||||
SET_PROPERTY(CACHE CPUINFO_LIBRARY_TYPE PROPERTY STRINGS default static shared)
|
||||
SET(CPUINFO_RUNTIME_TYPE "default" CACHE STRING "Type of runtime library (shared, static, or default) to use")
|
||||
SET_PROPERTY(CACHE CPUINFO_RUNTIME_TYPE PROPERTY STRINGS default static shared)
|
||||
SET(CPUINFO_LOG_LEVEL "default" CACHE STRING "Minimum logging level (info with lower severity will be ignored)")
|
||||
SET_PROPERTY(CACHE CPUINFO_LOG_LEVEL PROPERTY STRINGS default debug info warning error fatal none)
|
||||
|
||||
MACRO(CPUINFO_TARGET_ENABLE_C99 target)
|
||||
SET_TARGET_PROPERTIES(${target} PROPERTIES
|
||||
C_STANDARD 99
|
||||
C_EXTENSIONS NO)
|
||||
ENDMACRO()
|
||||
|
||||
MACRO(CPUINFO_TARGET_ENABLE_CXX11 target)
|
||||
SET_TARGET_PROPERTIES(${target} PROPERTIES
|
||||
CXX_STANDARD 11
|
||||
CXX_EXTENSIONS NO)
|
||||
ENDMACRO()
|
||||
|
||||
MACRO(CPUINFO_TARGET_RUNTIME_LIBRARY target)
|
||||
IF(MSVC AND NOT CPUINFO_RUNTIME_TYPE STREQUAL "default")
|
||||
IF(CPUINFO_RUNTIME_TYPE STREQUAL "shared")
|
||||
TARGET_COMPILE_OPTIONS(${target} PRIVATE
|
||||
"/MD$<$<CONFIG:Debug>:d>")
|
||||
ELSEIF(CPUINFO_RUNTIME_TYPE STREQUAL "static")
|
||||
TARGET_COMPILE_OPTIONS(${target} PRIVATE
|
||||
"/MT$<$<CONFIG:Debug>:d>")
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
ENDMACRO()
|
||||
|
||||
# -- [ Determine target processor
|
||||
SET(CPUINFO_TARGET_PROCESSOR "${CMAKE_SYSTEM_PROCESSOR}")
|
||||
IF(CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND CMAKE_OSX_ARCHITECTURES MATCHES "^(x86_64|arm64)$")
|
||||
SET(CPUINFO_TARGET_PROCESSOR "${CMAKE_OSX_ARCHITECTURES}")
|
||||
ENDIF()
|
||||
|
||||
# ---[ Build flags
|
||||
SET(CPUINFO_SUPPORTED_PLATFORM TRUE)
|
||||
IF(NOT CMAKE_SYSTEM_PROCESSOR)
|
||||
IF(NOT IOS)
|
||||
MESSAGE(WARNING
|
||||
"Target processor architecture is not specified. "
|
||||
"cpuinfo will compile, but cpuinfo_initialize() will always fail.")
|
||||
SET(CPUINFO_SUPPORTED_PLATFORM FALSE)
|
||||
ENDIF()
|
||||
ELSEIF(NOT CPUINFO_TARGET_PROCESSOR MATCHES "^(i[3-6]86|AMD64|x86(_64)?|armv[5-8].*|aarch64|arm64)$")
|
||||
MESSAGE(WARNING
|
||||
"Target processor architecture \"${CPUINFO_TARGET_PROCESSOR}\" is not supported in cpuinfo. "
|
||||
"cpuinfo will compile, but cpuinfo_initialize() will always fail.")
|
||||
SET(CPUINFO_SUPPORTED_PLATFORM FALSE)
|
||||
ENDIF()
|
||||
|
||||
IF(NOT CMAKE_SYSTEM_NAME)
|
||||
MESSAGE(WARNING
|
||||
"Target operating system is not specified. "
|
||||
"cpuinfo will compile, but cpuinfo_initialize() will always fail.")
|
||||
SET(CPUINFO_SUPPORTED_PLATFORM FALSE)
|
||||
ELSEIF(NOT CMAKE_SYSTEM_NAME MATCHES "^(Windows|CYGWIN|MSYS|Darwin|Linux|Android)$")
|
||||
IF(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.14" AND NOT CMAKE_SYSTEM_NAME STREQUAL "iOS")
|
||||
MESSAGE(WARNING
|
||||
"Target operating system \"${CMAKE_SYSTEM_NAME}\" is not supported in cpuinfo. "
|
||||
"cpuinfo will compile, but cpuinfo_initialize() will always fail.")
|
||||
SET(CPUINFO_SUPPORTED_PLATFORM FALSE)
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
|
||||
# ---[ cpuinfo library
|
||||
SET(CPUINFO_SRCS
|
||||
src/init.c
|
||||
src/api.c
|
||||
src/cache.c)
|
||||
|
||||
IF(CPUINFO_SUPPORTED_PLATFORM)
|
||||
IF(NOT CMAKE_SYSTEM_NAME STREQUAL "Emscripten" AND (CPUINFO_TARGET_PROCESSOR MATCHES "^(i[3-6]86|AMD64|x86(_64)?)$" OR IOS_ARCH MATCHES "^(i386|x86_64)$"))
|
||||
LIST(APPEND CPUINFO_SRCS
|
||||
src/x86/init.c
|
||||
src/x86/info.c
|
||||
src/x86/vendor.c
|
||||
src/x86/uarch.c
|
||||
src/x86/name.c
|
||||
src/x86/topology.c
|
||||
src/x86/isa.c
|
||||
src/x86/cache/init.c
|
||||
src/x86/cache/descriptor.c
|
||||
src/x86/cache/deterministic.c)
|
||||
IF(CMAKE_SYSTEM_NAME STREQUAL "Linux" OR CMAKE_SYSTEM_NAME STREQUAL "Android")
|
||||
LIST(APPEND CPUINFO_SRCS
|
||||
src/x86/linux/init.c
|
||||
src/x86/linux/cpuinfo.c)
|
||||
ELSEIF(CMAKE_SYSTEM_NAME STREQUAL "Darwin" OR CMAKE_SYSTEM_NAME STREQUAL "iOS")
|
||||
LIST(APPEND CPUINFO_SRCS src/x86/mach/init.c)
|
||||
ELSEIF(CMAKE_SYSTEM_NAME MATCHES "^(Windows|CYGWIN|MSYS)$")
|
||||
LIST(APPEND CPUINFO_SRCS src/x86/windows/init.c)
|
||||
ENDIF()
|
||||
ELSEIF(CPUINFO_TARGET_PROCESSOR MATCHES "^(armv[5-8].*|aarch64|arm64)$" OR IOS_ARCH MATCHES "^(armv7.*|arm64.*)$")
|
||||
LIST(APPEND CPUINFO_SRCS
|
||||
src/arm/uarch.c
|
||||
src/arm/cache.c)
|
||||
IF(CMAKE_SYSTEM_NAME STREQUAL "Linux" OR CMAKE_SYSTEM_NAME STREQUAL "Android")
|
||||
LIST(APPEND CPUINFO_SRCS
|
||||
src/arm/linux/init.c
|
||||
src/arm/linux/cpuinfo.c
|
||||
src/arm/linux/clusters.c
|
||||
src/arm/linux/chipset.c
|
||||
src/arm/linux/midr.c
|
||||
src/arm/linux/hwcap.c)
|
||||
IF(CMAKE_SYSTEM_PROCESSOR MATCHES "^armv[5-8]")
|
||||
LIST(APPEND CPUINFO_SRCS src/arm/linux/aarch32-isa.c)
|
||||
IF(CMAKE_SYSTEM_NAME STREQUAL "Android" AND ANDROID_ABI STREQUAL "armeabi")
|
||||
SET_SOURCE_FILES_PROPERTIES(src/arm/linux/aarch32-isa.c PROPERTIES COMPILE_FLAGS -marm)
|
||||
ENDIF()
|
||||
ELSEIF(CMAKE_SYSTEM_PROCESSOR MATCHES "^(aarch64|arm64)$")
|
||||
LIST(APPEND CPUINFO_SRCS src/arm/linux/aarch64-isa.c)
|
||||
ENDIF()
|
||||
ELSEIF(IOS OR (CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND CPUINFO_TARGET_PROCESSOR STREQUAL "arm64"))
|
||||
LIST(APPEND CPUINFO_SRCS src/arm/mach/init.c)
|
||||
ENDIF()
|
||||
IF(CMAKE_SYSTEM_NAME STREQUAL "Android")
|
||||
LIST(APPEND CPUINFO_SRCS
|
||||
src/arm/android/properties.c)
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
|
||||
IF(CMAKE_SYSTEM_NAME STREQUAL "Emscripten")
|
||||
LIST(APPEND CPUINFO_SRCS
|
||||
src/emscripten/init.c)
|
||||
ENDIF()
|
||||
|
||||
IF(CMAKE_SYSTEM_NAME STREQUAL "Linux" OR CMAKE_SYSTEM_NAME STREQUAL "Android")
|
||||
LIST(APPEND CPUINFO_SRCS
|
||||
src/linux/smallfile.c
|
||||
src/linux/multiline.c
|
||||
src/linux/cpulist.c
|
||||
src/linux/processors.c)
|
||||
ELSEIF(CMAKE_SYSTEM_NAME STREQUAL "Darwin" OR CMAKE_SYSTEM_NAME STREQUAL "iOS")
|
||||
LIST(APPEND CPUINFO_SRCS src/mach/topology.c)
|
||||
ENDIF()
|
||||
|
||||
IF(CMAKE_SYSTEM_NAME STREQUAL "Linux" OR CMAKE_SYSTEM_NAME STREQUAL "Android")
|
||||
SET(CMAKE_THREAD_PREFER_PTHREAD TRUE)
|
||||
SET(THREADS_PREFER_PTHREAD_FLAG TRUE)
|
||||
FIND_PACKAGE(Threads REQUIRED)
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
|
||||
IF(CPUINFO_LIBRARY_TYPE STREQUAL "default")
|
||||
ADD_LIBRARY(cpuinfo ${CPUINFO_SRCS})
|
||||
ELSEIF(CPUINFO_LIBRARY_TYPE STREQUAL "shared")
|
||||
ADD_LIBRARY(cpuinfo SHARED ${CPUINFO_SRCS})
|
||||
ELSEIF(CPUINFO_LIBRARY_TYPE STREQUAL "static")
|
||||
ADD_LIBRARY(cpuinfo STATIC ${CPUINFO_SRCS})
|
||||
ELSE()
|
||||
MESSAGE(FATAL_ERROR "Unsupported library type ${CPUINFO_LIBRARY_TYPE}")
|
||||
ENDIF()
|
||||
ADD_LIBRARY(cpuinfo_internals STATIC ${CPUINFO_SRCS})
|
||||
CPUINFO_TARGET_ENABLE_C99(cpuinfo)
|
||||
CPUINFO_TARGET_ENABLE_C99(cpuinfo_internals)
|
||||
CPUINFO_TARGET_RUNTIME_LIBRARY(cpuinfo)
|
||||
IF(CMAKE_SYSTEM_NAME MATCHES "^(Windows|CYGWIN|MSYS)$")
|
||||
# Target Windows 7+ API
|
||||
TARGET_COMPILE_DEFINITIONS(cpuinfo PRIVATE _WIN32_WINNT=0x0601)
|
||||
TARGET_COMPILE_DEFINITIONS(cpuinfo_internals PRIVATE _WIN32_WINNT=0x0601)
|
||||
ENDIF()
|
||||
SET_TARGET_PROPERTIES(cpuinfo PROPERTIES PUBLIC_HEADER include/cpuinfo.h)
|
||||
TARGET_INCLUDE_DIRECTORIES(cpuinfo BEFORE PUBLIC include)
|
||||
TARGET_INCLUDE_DIRECTORIES(cpuinfo BEFORE PRIVATE src)
|
||||
TARGET_INCLUDE_DIRECTORIES(cpuinfo_internals BEFORE PUBLIC include src)
|
||||
IF(CPUINFO_LOG_LEVEL STREQUAL "default")
|
||||
# default logging level: error (subject to change)
|
||||
TARGET_COMPILE_DEFINITIONS(cpuinfo PRIVATE CPUINFO_LOG_LEVEL=2)
|
||||
ELSEIF(CPUINFO_LOG_LEVEL STREQUAL "debug")
|
||||
TARGET_COMPILE_DEFINITIONS(cpuinfo PRIVATE CPUINFO_LOG_LEVEL=5)
|
||||
ELSEIF(CPUINFO_LOG_LEVEL STREQUAL "info")
|
||||
TARGET_COMPILE_DEFINITIONS(cpuinfo PRIVATE CPUINFO_LOG_LEVEL=4)
|
||||
ELSEIF(CPUINFO_LOG_LEVEL STREQUAL "warning")
|
||||
TARGET_COMPILE_DEFINITIONS(cpuinfo PRIVATE CPUINFO_LOG_LEVEL=3)
|
||||
ELSEIF(CPUINFO_LOG_LEVEL STREQUAL "error")
|
||||
TARGET_COMPILE_DEFINITIONS(cpuinfo PRIVATE CPUINFO_LOG_LEVEL=2)
|
||||
ELSEIF(CPUINFO_LOG_LEVEL STREQUAL "fatal")
|
||||
TARGET_COMPILE_DEFINITIONS(cpuinfo PRIVATE CPUINFO_LOG_LEVEL=1)
|
||||
ELSEIF(CPUINFO_LOG_LEVEL STREQUAL "none")
|
||||
TARGET_COMPILE_DEFINITIONS(cpuinfo PRIVATE CPUINFO_LOG_LEVEL=0)
|
||||
ELSE()
|
||||
MESSAGE(FATAL_ERROR "Unsupported logging level ${CPUINFO_LOG_LEVEL}")
|
||||
ENDIF()
|
||||
TARGET_COMPILE_DEFINITIONS(cpuinfo_internals PRIVATE CPUINFO_LOG_LEVEL=0)
|
||||
|
||||
IF(CPUINFO_SUPPORTED_PLATFORM)
|
||||
TARGET_COMPILE_DEFINITIONS(cpuinfo INTERFACE CPUINFO_SUPPORTED_PLATFORM=1)
|
||||
IF(CMAKE_SYSTEM_NAME STREQUAL "Linux" OR CMAKE_SYSTEM_NAME STREQUAL "Android")
|
||||
TARGET_LINK_LIBRARIES(cpuinfo PUBLIC ${CMAKE_THREAD_LIBS_INIT})
|
||||
TARGET_LINK_LIBRARIES(cpuinfo_internals PUBLIC ${CMAKE_THREAD_LIBS_INIT})
|
||||
TARGET_COMPILE_DEFINITIONS(cpuinfo PRIVATE _GNU_SOURCE=1)
|
||||
TARGET_COMPILE_DEFINITIONS(cpuinfo_internals PRIVATE _GNU_SOURCE=1)
|
||||
ENDIF()
|
||||
ELSE()
|
||||
TARGET_COMPILE_DEFINITIONS(cpuinfo INTERFACE CPUINFO_SUPPORTED_PLATFORM=0)
|
||||
ENDIF()
|
||||
|
||||
# ---[ cpuinfo dependencies: clog
|
||||
IF(NOT DEFINED CLOG_SOURCE_DIR)
|
||||
SET(CLOG_SOURCE_DIR "${PROJECT_SOURCE_DIR}/deps/clog")
|
||||
ENDIF()
|
||||
IF(NOT TARGET clog)
|
||||
SET(CLOG_BUILD_TESTS OFF CACHE BOOL "")
|
||||
SET(CLOG_RUNTIME_TYPE "${CPUINFO_RUNTIME_TYPE}" CACHE STRING "")
|
||||
ADD_SUBDIRECTORY(
|
||||
"${CLOG_SOURCE_DIR}")
|
||||
# We build static version of clog but a dynamic library may indirectly depend on it
|
||||
SET_PROPERTY(TARGET clog PROPERTY POSITION_INDEPENDENT_CODE ON)
|
||||
ENDIF()
|
||||
TARGET_LINK_LIBRARIES(cpuinfo PRIVATE clog)
|
||||
TARGET_LINK_LIBRARIES(cpuinfo_internals PRIVATE clog)
|
||||
27
3rdparty/cpuinfo/LICENSE
vendored
Normal file
27
3rdparty/cpuinfo/LICENSE
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
Copyright (c) 2019 Google LLC
|
||||
Copyright (c) 2017-2018 Facebook Inc.
|
||||
Copyright (C) 2012-2017 Georgia Institute of Technology
|
||||
Copyright (C) 2010-2012 Marat Dukhan
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
283
3rdparty/cpuinfo/README.md
vendored
Normal file
283
3rdparty/cpuinfo/README.md
vendored
Normal file
@@ -0,0 +1,283 @@
|
||||
# CPU INFOrmation library
|
||||
|
||||
[](https://github.com/pytorch/cpuinfo/blob/master/LICENSE)
|
||||
[](https://travis-ci.org/pytorch/cpuinfo)
|
||||
[](https://ci.appveyor.com/project/MaratDukhan/cpuinfo/branch/master)
|
||||
|
||||
cpuinfo is a library to detect essential for performance optimization information about host CPU.
|
||||
|
||||
## Features
|
||||
|
||||
- **Cross-platform** availability:
|
||||
- Linux, Windows, macOS, Android, and iOS operating systems
|
||||
- x86, x86-64, ARM, and ARM64 architectures
|
||||
- Modern **C/C++ interface**
|
||||
- Thread-safe
|
||||
- No memory allocation after initialization
|
||||
- No exceptions thrown
|
||||
- Detection of **supported instruction sets**, up to AVX512 (x86) and ARMv8.3 extensions
|
||||
- Detection of SoC and core information:
|
||||
- **Processor (SoC) name**
|
||||
- Vendor and **microarchitecture** for each CPU core
|
||||
- ID (**MIDR** on ARM, **CPUID** leaf 1 EAX value on x86) for each CPU core
|
||||
- Detection of **cache information**:
|
||||
- Cache type (instruction/data/unified), size and line size
|
||||
- Cache associativity
|
||||
- Cores and logical processors (hyper-threads) sharing the cache
|
||||
- Detection of **topology information** (relative between logical processors, cores, and processor packages)
|
||||
- Well-tested **production-quality** code:
|
||||
- 60+ mock tests based on data from real devices
|
||||
- Includes work-arounds for common bugs in hardware and OS kernels
|
||||
- Supports systems with heterogenous cores, such as **big.LITTLE** and Max.Med.Min
|
||||
- Permissive **open-source** license (Simplified BSD)
|
||||
|
||||
## Examples
|
||||
|
||||
Log processor name:
|
||||
|
||||
```c
|
||||
cpuinfo_initialize();
|
||||
printf("Running on %s CPU\n", cpuinfo_get_package(0)->name);
|
||||
```
|
||||
|
||||
Detect if target is a 32-bit or 64-bit ARM system:
|
||||
|
||||
```c
|
||||
#if CPUINFO_ARCH_ARM || CPUINFO_ARCH_ARM64
|
||||
/* 32-bit ARM-specific code here */
|
||||
#endif
|
||||
```
|
||||
|
||||
Check if the host CPU support ARM NEON
|
||||
|
||||
```c
|
||||
cpuinfo_initialize();
|
||||
if (cpuinfo_has_arm_neon()) {
|
||||
neon_implementation(arguments);
|
||||
}
|
||||
```
|
||||
|
||||
Check if the host CPU supports x86 AVX
|
||||
|
||||
```c
|
||||
cpuinfo_initialize();
|
||||
if (cpuinfo_has_x86_avx()) {
|
||||
avx_implementation(arguments);
|
||||
}
|
||||
```
|
||||
|
||||
Check if the thread runs on a Cortex-A53 core
|
||||
|
||||
```c
|
||||
cpuinfo_initialize();
|
||||
switch (cpuinfo_get_current_core()->uarch) {
|
||||
case cpuinfo_uarch_cortex_a53:
|
||||
cortex_a53_implementation(arguments);
|
||||
break;
|
||||
default:
|
||||
generic_implementation(arguments);
|
||||
break;
|
||||
}
|
||||
```
|
||||
|
||||
Get the size of level 1 data cache on the fastest core in the processor (e.g. big core in big.LITTLE ARM systems):
|
||||
|
||||
```c
|
||||
cpuinfo_initialize();
|
||||
const size_t l1_size = cpuinfo_get_processor(0)->cache.l1d->size;
|
||||
```
|
||||
|
||||
Pin thread to cores sharing L2 cache with the current core (Linux or Android)
|
||||
|
||||
```c
|
||||
cpuinfo_initialize();
|
||||
cpu_set_t cpu_set;
|
||||
CPU_ZERO(&cpu_set);
|
||||
const struct cpuinfo_cache* current_l2 = cpuinfo_get_current_processor()->cache.l2;
|
||||
for (uint32_t i = 0; i < current_l2->processor_count; i++) {
|
||||
CPU_SET(cpuinfo_get_processor(current_l2->processor_start + i)->linux_id, &cpu_set);
|
||||
}
|
||||
pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpu_set);
|
||||
```
|
||||
|
||||
## Use via pkg-config
|
||||
|
||||
If you would like to provide your project's build environment with the necessary compiler and linker flags in a portable manner, the library by default when built enables `CPUINFO_BUILD_PKG_CONFIG` and will generate a [pkg-config](https://www.freedesktop.org/wiki/Software/pkg-config/) manifest (_libcpuinfo.pc_). Here are several examples of how to use it:
|
||||
|
||||
### Command Line
|
||||
|
||||
If you used your distro's package manager to install the library, you can verify that it is available to your build environment like so:
|
||||
|
||||
```console
|
||||
$ pkg-config --cflags --libs libcpuinfo
|
||||
-I/usr/include/x86_64-linux-gnu/ -L/lib/x86_64-linux-gnu/ -lcpuinfo
|
||||
```
|
||||
|
||||
If you have installed the library from source into a non-standard prefix, pkg-config may need help finding it:
|
||||
|
||||
```console
|
||||
$ PKG_CONFIG_PATH="/home/me/projects/cpuinfo/prefix/lib/pkgconfig/:$PKG_CONFIG_PATH" pkg-config --cflags --libs libcpuinfo
|
||||
-I/home/me/projects/cpuinfo/prefix/include -L/home/me/projects/cpuinfo/prefix/lib -lcpuinfo
|
||||
```
|
||||
|
||||
### GNU Autotools
|
||||
|
||||
To [use](https://autotools.io/pkgconfig/pkg_check_modules.html) with the GNU Autotools include the following snippet in your project's `configure.ac`:
|
||||
|
||||
```makefile
|
||||
# CPU INFOrmation library...
|
||||
PKG_CHECK_MODULES(
|
||||
[libcpuinfo], [libcpuinfo], [],
|
||||
[AC_MSG_ERROR([libcpuinfo missing...])])
|
||||
YOURPROJECT_CXXFLAGS="$YOURPROJECT_CXXFLAGS $libcpuinfo_CFLAGS"
|
||||
YOURPROJECT_LIBS="$YOURPROJECT_LIBS $libcpuinfo_LIBS"
|
||||
```
|
||||
|
||||
### Meson
|
||||
|
||||
To use with Meson you just need to add `dependency('libcpuinfo')` as a dependency for your executable.
|
||||
|
||||
```meson
|
||||
project(
|
||||
'MyCpuInfoProject',
|
||||
'cpp',
|
||||
meson_version: '>=0.55.0'
|
||||
)
|
||||
|
||||
executable(
|
||||
'MyCpuInfoExecutable',
|
||||
sources: 'main.cpp',
|
||||
dependencies: dependency('libcpuinfo')
|
||||
)
|
||||
```
|
||||
|
||||
### CMake
|
||||
|
||||
To use with CMake use the [FindPkgConfig](https://cmake.org/cmake/help/latest/module/FindPkgConfig.html) module. Here is an example:
|
||||
|
||||
```cmake
|
||||
cmake_minimum_required(VERSION 3.6)
|
||||
project("MyCpuInfoProject")
|
||||
|
||||
find_package(PkgConfig)
|
||||
pkg_check_modules(CpuInfo REQUIRED IMPORTED_TARGET libcpuinfo)
|
||||
|
||||
add_executable(${PROJECT_NAME} main.cpp)
|
||||
target_link_libraries(${PROJECT_NAME} PkgConfig::CpuInfo)
|
||||
```
|
||||
|
||||
### Makefile
|
||||
|
||||
To use within a vanilla makefile, you can call pkg-config directly to supply compiler and linker flags using shell substitution.
|
||||
|
||||
```makefile
|
||||
CFLAGS=-g3 -Wall -Wextra -Werror ...
|
||||
LDFLAGS=-lfoo ...
|
||||
...
|
||||
CFLAGS+= $(pkg-config --cflags libcpuinfo)
|
||||
LDFLAGS+= $(pkg-config --libs libcpuinfo)
|
||||
```
|
||||
|
||||
## Exposed information
|
||||
- [x] Processor (SoC) name
|
||||
- [x] Microarchitecture
|
||||
- [x] Usable instruction sets
|
||||
- [ ] CPU frequency
|
||||
- [x] Cache
|
||||
- [x] Size
|
||||
- [x] Associativity
|
||||
- [x] Line size
|
||||
- [x] Number of partitions
|
||||
- [x] Flags (unified, inclusive, complex hash function)
|
||||
- [x] Topology (logical processors that share this cache level)
|
||||
- [ ] TLB
|
||||
- [ ] Number of entries
|
||||
- [ ] Associativity
|
||||
- [ ] Covered page types (instruction, data)
|
||||
- [ ] Covered page sizes
|
||||
- [x] Topology information
|
||||
- [x] Logical processors
|
||||
- [x] Cores
|
||||
- [x] Packages (sockets)
|
||||
|
||||
## Supported environments:
|
||||
- [x] Android
|
||||
- [x] x86 ABI
|
||||
- [x] x86_64 ABI
|
||||
- [x] armeabi ABI
|
||||
- [x] armeabiv7-a ABI
|
||||
- [x] arm64-v8a ABI
|
||||
- [ ] ~~mips ABI~~
|
||||
- [ ] ~~mips64 ABI~~
|
||||
- [x] Linux
|
||||
- [x] x86
|
||||
- [x] x86-64
|
||||
- [x] 32-bit ARM (ARMv5T and later)
|
||||
- [x] ARM64
|
||||
- [ ] PowerPC64
|
||||
- [x] iOS
|
||||
- [x] x86 (iPhone simulator)
|
||||
- [x] x86-64 (iPhone simulator)
|
||||
- [x] ARMv7
|
||||
- [x] ARM64
|
||||
- [x] OS X
|
||||
- [x] x86
|
||||
- [x] x86-64
|
||||
- [x] Windows
|
||||
- [x] x86
|
||||
- [x] x86-64
|
||||
|
||||
## Methods
|
||||
|
||||
- Processor (SoC) name detection
|
||||
- [x] Using CPUID leaves 0x80000002–0x80000004 on x86/x86-64
|
||||
- [x] Using `/proc/cpuinfo` on ARM
|
||||
- [x] Using `ro.chipname`, `ro.board.platform`, `ro.product.board`, `ro.mediatek.platform`, `ro.arch` properties (Android)
|
||||
- [ ] Using kernel log (`dmesg`) on ARM Linux
|
||||
- Vendor and microarchitecture detection
|
||||
- [x] Intel-designed x86/x86-64 cores (up to Sunny Cove, Goldmont Plus, and Knights Mill)
|
||||
- [x] AMD-designed x86/x86-64 cores (up to Puma/Jaguar and Zen 2)
|
||||
- [ ] VIA-designed x86/x86-64 cores
|
||||
- [ ] Other x86 cores (DM&P, RDC, Transmeta, Cyrix, Rise)
|
||||
- [x] ARM-designed ARM cores (up to Cortex-A55, Cortex-A77, and Neoverse E1/N1)
|
||||
- [x] Qualcomm-designed ARM cores (Scorpion, Krait, and Kryo)
|
||||
- [x] Nvidia-designed ARM cores (Denver and Carmel)
|
||||
- [x] Samsung-designed ARM cores (Exynos)
|
||||
- [x] Intel-designed ARM cores (XScale up to 3rd-gen)
|
||||
- [x] Apple-designed ARM cores (up to Lightning and Thunder)
|
||||
- [x] Cavium-designed ARM cores (ThunderX)
|
||||
- [x] AppliedMicro-designed ARM cores (X-Gene)
|
||||
- Instruction set detection
|
||||
- [x] Using CPUID (x86/x86-64)
|
||||
- [x] Using `/proc/cpuinfo` on 32-bit ARM EABI (Linux)
|
||||
- [x] Using microarchitecture heuristics on (32-bit ARM)
|
||||
- [x] Using `FPSID` and `WCID` registers (32-bit ARM)
|
||||
- [x] Using `getauxval` (Linux/ARM)
|
||||
- [x] Using `/proc/self/auxv` (Android/ARM)
|
||||
- [ ] Using instruction probing on ARM (Linux)
|
||||
- [ ] Using CPUID registers on ARM64 (Linux)
|
||||
- Cache detection
|
||||
- [x] Using CPUID leaf 0x00000002 (x86/x86-64)
|
||||
- [x] Using CPUID leaf 0x00000004 (non-AMD x86/x86-64)
|
||||
- [ ] Using CPUID leaves 0x80000005-0x80000006 (AMD x86/x86-64)
|
||||
- [x] Using CPUID leaf 0x8000001D (AMD x86/x86-64)
|
||||
- [x] Using `/proc/cpuinfo` (Linux/pre-ARMv7)
|
||||
- [x] Using microarchitecture heuristics (ARM)
|
||||
- [x] Using chipset name (ARM)
|
||||
- [x] Using `sysctlbyname` (Mach)
|
||||
- [x] Using sysfs `typology` directories (ARM/Linux)
|
||||
- [ ] Using sysfs `cache` directories (Linux)
|
||||
- TLB detection
|
||||
- [x] Using CPUID leaf 0x00000002 (x86/x86-64)
|
||||
- [ ] Using CPUID leaves 0x80000005-0x80000006 and 0x80000019 (AMD x86/x86-64)
|
||||
- [x] Using microarchitecture heuristics (ARM)
|
||||
- Topology detection
|
||||
- [x] Using CPUID leaf 0x00000001 on x86/x86-64 (legacy APIC ID)
|
||||
- [x] Using CPUID leaf 0x0000000B on x86/x86-64 (Intel APIC ID)
|
||||
- [ ] Using CPUID leaf 0x8000001E on x86/x86-64 (AMD APIC ID)
|
||||
- [x] Using `/proc/cpuinfo` (Linux)
|
||||
- [x] Using `host_info` (Mach)
|
||||
- [x] Using `GetLogicalProcessorInformationEx` (Windows)
|
||||
- [x] Using sysfs (Linux)
|
||||
- [x] Using chipset name (ARM/Linux)
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(SolutionDir)common\vsprops\BaseProjectConfig.props" />
|
||||
<Import Project="$(SolutionDir)common\vsprops\WinSDK.props" />
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{48329442-E41B-4A1F-8364-36EEE1B71343}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<ProjectGuid>{7E183337-A7E9-460C-9D3D-568BC9F9BCC1}</ProjectGuid>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Label="Configuration">
|
||||
@@ -29,47 +28,42 @@
|
||||
<PropertyGroup>
|
||||
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="deps\clog\src\clog.c" />
|
||||
<ClCompile Include="src\api.c" />
|
||||
<ClCompile Include="src\cache.c" />
|
||||
<ClCompile Include="src\init.c" />
|
||||
<ClCompile Include="src\x86\cache\descriptor.c" />
|
||||
<ClCompile Include="src\x86\cache\deterministic.c" />
|
||||
<ClCompile Include="src\x86\cache\init.c" />
|
||||
<ClCompile Include="src\x86\info.c" />
|
||||
<ClCompile Include="src\x86\init.c" />
|
||||
<ClCompile Include="src\x86\isa.c" />
|
||||
<ClCompile Include="src\x86\name.c" />
|
||||
<ClCompile Include="src\x86\topology.c" />
|
||||
<ClCompile Include="src\x86\uarch.c" />
|
||||
<ClCompile Include="src\x86\vendor.c" />
|
||||
<ClCompile Include="src\x86\windows\init.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="deps\clog\include\clog.h" />
|
||||
<ClInclude Include="include\cpuinfo.h" />
|
||||
<ClInclude Include="src\cpuinfo\common.h" />
|
||||
<ClInclude Include="src\cpuinfo\internal-api.h" />
|
||||
<ClInclude Include="src\cpuinfo\log.h" />
|
||||
<ClInclude Include="src\cpuinfo\utils.h" />
|
||||
<ClInclude Include="src\x86\api.h" />
|
||||
<ClInclude Include="src\x86\cpuid.h" />
|
||||
<ClInclude Include="src\x86\windows\api.h" />
|
||||
</ItemGroup>
|
||||
<ItemDefinitionGroup>
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<WarningLevel>TurnOffAllWarnings</WarningLevel>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir)/yaml-cpp/include/;$(ProjectDir)/yaml-cpp/src/;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir)include;$(ProjectDir)src;$(ProjectDir)deps\clog\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<ObjectFileName>$(IntDir)%(RelativeDir)</ObjectFileName>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="yaml-cpp\src\contrib\graphbuilder.cpp" />
|
||||
<ClCompile Include="yaml-cpp\src\contrib\graphbuilderadapter.cpp" />
|
||||
<ClCompile Include="yaml-cpp\src\binary.cpp" />
|
||||
<ClCompile Include="yaml-cpp\src\convert.cpp" />
|
||||
<ClCompile Include="yaml-cpp\src\depthguard.cpp" />
|
||||
<ClCompile Include="yaml-cpp\src\directives.cpp" />
|
||||
<ClCompile Include="yaml-cpp\src\emit.cpp" />
|
||||
<ClCompile Include="yaml-cpp\src\emitfromevents.cpp" />
|
||||
<ClCompile Include="yaml-cpp\src\emitter.cpp" />
|
||||
<ClCompile Include="yaml-cpp\src\emitterstate.cpp" />
|
||||
<ClCompile Include="yaml-cpp\src\emitterutils.cpp" />
|
||||
<ClCompile Include="yaml-cpp\src\exceptions.cpp" />
|
||||
<ClCompile Include="yaml-cpp\src\exp.cpp" />
|
||||
<ClCompile Include="yaml-cpp\src\memory.cpp" />
|
||||
<ClCompile Include="yaml-cpp\src\node.cpp" />
|
||||
<ClCompile Include="yaml-cpp\src\node_data.cpp" />
|
||||
<ClCompile Include="yaml-cpp\src\nodebuilder.cpp" />
|
||||
<ClCompile Include="yaml-cpp\src\nodeevents.cpp" />
|
||||
<ClCompile Include="yaml-cpp\src\null.cpp" />
|
||||
<ClCompile Include="yaml-cpp\src\ostream_wrapper.cpp" />
|
||||
<ClCompile Include="yaml-cpp\src\parse.cpp" />
|
||||
<ClCompile Include="yaml-cpp\src\parser.cpp" />
|
||||
<ClCompile Include="yaml-cpp\src\regex_yaml.cpp" />
|
||||
<ClCompile Include="yaml-cpp\src\scanner.cpp" />
|
||||
<ClCompile Include="yaml-cpp\src\scanscalar.cpp" />
|
||||
<ClCompile Include="yaml-cpp\src\scantag.cpp" />
|
||||
<ClCompile Include="yaml-cpp\src\scantoken.cpp" />
|
||||
<ClCompile Include="yaml-cpp\src\simplekey.cpp" />
|
||||
<ClCompile Include="yaml-cpp\src\singledocparser.cpp" />
|
||||
<ClCompile Include="yaml-cpp\src\stream.cpp" />
|
||||
<ClCompile Include="yaml-cpp\src\tag.cpp" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets" />
|
||||
</Project>
|
||||
88
3rdparty/cpuinfo/cpuinfo.vcxproj.filters
vendored
Normal file
88
3rdparty/cpuinfo/cpuinfo.vcxproj.filters
vendored
Normal file
@@ -0,0 +1,88 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="x86">
|
||||
<UniqueIdentifier>{8fc9f543-ff04-48fb-ae1a-7c575a8aed13}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="x86\windows">
|
||||
<UniqueIdentifier>{0b540baa-aafb-4e51-8cbf-b7e7c00d9a4d}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="x86\descriptor">
|
||||
<UniqueIdentifier>{53ef3c40-8e03-46d1-aeb3-6446c40469da}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="cpuinfo">
|
||||
<UniqueIdentifier>{26002d26-399a-41bb-93cb-42fb9be21c1f}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="clog">
|
||||
<UniqueIdentifier>{7f0aba4c-ca06-4a7b-aed1-4f1e6976e839}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="src\x86\isa.c">
|
||||
<Filter>x86</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\x86\name.c">
|
||||
<Filter>x86</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\x86\topology.c">
|
||||
<Filter>x86</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\x86\uarch.c">
|
||||
<Filter>x86</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\x86\vendor.c">
|
||||
<Filter>x86</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\x86\info.c">
|
||||
<Filter>x86</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\x86\init.c">
|
||||
<Filter>x86</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\x86\windows\init.c">
|
||||
<Filter>x86\windows</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\x86\cache\deterministic.c">
|
||||
<Filter>x86\descriptor</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\x86\cache\init.c">
|
||||
<Filter>x86\descriptor</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\x86\cache\descriptor.c">
|
||||
<Filter>x86\descriptor</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\api.c" />
|
||||
<ClCompile Include="src\cache.c" />
|
||||
<ClCompile Include="src\init.c" />
|
||||
<ClCompile Include="deps\clog\src\clog.c">
|
||||
<Filter>clog</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="src\x86\api.h">
|
||||
<Filter>x86</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\x86\cpuid.h">
|
||||
<Filter>x86</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\x86\windows\api.h">
|
||||
<Filter>x86\windows</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\cpuinfo\internal-api.h">
|
||||
<Filter>cpuinfo</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\cpuinfo\log.h">
|
||||
<Filter>cpuinfo</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\cpuinfo\utils.h">
|
||||
<Filter>cpuinfo</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\cpuinfo\common.h">
|
||||
<Filter>cpuinfo</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="include\cpuinfo.h" />
|
||||
<ClInclude Include="deps\clog\include\clog.h">
|
||||
<Filter>clog</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
19
3rdparty/cpuinfo/deps/clog/.gitignore
vendored
Normal file
19
3rdparty/cpuinfo/deps/clog/.gitignore
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
# Ninja files
|
||||
build.ninja
|
||||
|
||||
# Build objects and artifacts
|
||||
deps/
|
||||
build/
|
||||
bin/
|
||||
lib/
|
||||
*.pyc
|
||||
*.pyo
|
||||
|
||||
# System files
|
||||
.DS_Store
|
||||
.DS_Store?
|
||||
._*
|
||||
.Spotlight-V100
|
||||
.Trashes
|
||||
ehthumbs.db
|
||||
Thumbs.db
|
||||
42
3rdparty/cpuinfo/deps/clog/CMakeLists.txt
vendored
Normal file
42
3rdparty/cpuinfo/deps/clog/CMakeLists.txt
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
CMAKE_MINIMUM_REQUIRED(VERSION 3.1 FATAL_ERROR)
|
||||
|
||||
# ---[ Project and semantic versioning.
|
||||
PROJECT(clog C CXX)
|
||||
|
||||
# ---[ Options.
|
||||
SET(CLOG_RUNTIME_TYPE "default" CACHE STRING "Type of runtime library (shared, static, or default) to use")
|
||||
SET_PROPERTY(CACHE CLOG_RUNTIME_TYPE PROPERTY STRINGS default static shared)
|
||||
IF(ANDROID)
|
||||
OPTION(CLOG_LOG_TO_STDIO "Log errors, warnings, and information to stdout/stderr" OFF)
|
||||
ELSE()
|
||||
OPTION(CLOG_LOG_TO_STDIO "Log errors, warnings, and information to stdout/stderr" ON)
|
||||
ENDIF()
|
||||
|
||||
MACRO(CLOG_TARGET_RUNTIME_LIBRARY target)
|
||||
IF(MSVC AND NOT CLOG_RUNTIME_TYPE STREQUAL "default")
|
||||
IF(CLOG_RUNTIME_TYPE STREQUAL "shared")
|
||||
TARGET_COMPILE_OPTIONS(${target} PRIVATE
|
||||
"/MD$<$<CONFIG:Debug>:d>")
|
||||
ELSEIF(CLOG_RUNTIME_TYPE STREQUAL "static")
|
||||
TARGET_COMPILE_OPTIONS(${target} PRIVATE
|
||||
"/MT$<$<CONFIG:Debug>:d>")
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
ENDMACRO()
|
||||
|
||||
# ---[ clog library
|
||||
ADD_LIBRARY(clog STATIC src/clog.c)
|
||||
SET_TARGET_PROPERTIES(clog PROPERTIES
|
||||
C_STANDARD 99
|
||||
C_EXTENSIONS NO)
|
||||
CLOG_TARGET_RUNTIME_LIBRARY(clog)
|
||||
SET_TARGET_PROPERTIES(clog PROPERTIES PUBLIC_HEADER include/clog.h)
|
||||
TARGET_INCLUDE_DIRECTORIES(clog BEFORE PUBLIC include)
|
||||
IF(CLOG_LOG_TO_STDIO)
|
||||
TARGET_COMPILE_DEFINITIONS(clog PRIVATE CLOG_LOG_TO_STDIO=1)
|
||||
ELSE()
|
||||
TARGET_COMPILE_DEFINITIONS(clog PRIVATE CLOG_LOG_TO_STDIO=0)
|
||||
ENDIF()
|
||||
IF(ANDROID AND NOT CLOG_LOG_TO_STDIO)
|
||||
TARGET_LINK_LIBRARIES(clog PRIVATE log)
|
||||
ENDIF()
|
||||
26
3rdparty/cpuinfo/deps/clog/LICENSE
vendored
Normal file
26
3rdparty/cpuinfo/deps/clog/LICENSE
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
Copyright (C) 2018 Marat Dukhan
|
||||
Copyright (c) 2017-2018 Facebook Inc.
|
||||
Copyright (c) 2017 Georgia Institute of Technology
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
57
3rdparty/cpuinfo/deps/clog/README.md
vendored
Normal file
57
3rdparty/cpuinfo/deps/clog/README.md
vendored
Normal file
@@ -0,0 +1,57 @@
|
||||
# clog: C-style (a-la printf) logging library
|
||||
|
||||
[](https://github.com/pytorch/cpuinfo/blob/master/deps/clog/LICENSE)
|
||||
|
||||
C-style library for logging errors, warnings, information notes, and debug information.
|
||||
|
||||
## Features
|
||||
|
||||
- printf-style interface for formatting variadic parameters.
|
||||
- Separate functions for logging errors, warnings, information notes, and debug information.
|
||||
- Independent logging settings for different modules.
|
||||
- Logging to logcat on Android and stderr/stdout on other platforms.
|
||||
- Compatible with C99 and C++.
|
||||
- Covered with unit tests.
|
||||
|
||||
## Example
|
||||
|
||||
```c
|
||||
#include <clog.h>
|
||||
|
||||
#ifndef MYMODULE_LOG_LEVEL
|
||||
#define MYMODULE_LOG_LEVEL CLOG_DEBUG
|
||||
#endif
|
||||
|
||||
CLOG_DEFINE_LOG_DEBUG(mymodule_, "My Module", MYMODULE_LOG_LEVEL);
|
||||
CLOG_DEFINE_LOG_INFO(mymodule_, "My Module", MYMODULE_LOG_LEVEL);
|
||||
CLOG_DEFINE_LOG_WARNING(mymodule_, "My Module", MYMODULE_LOG_LEVEL);
|
||||
CLOG_DEFINE_LOG_ERROR(mymodule_, "My Module", MYMODULE_LOG_LEVEL);
|
||||
|
||||
...
|
||||
|
||||
void some_function(...) {
|
||||
int status = ...
|
||||
if (status != 0) {
|
||||
mymodule_log_error(
|
||||
"something really bad happened: "
|
||||
"operation failed with status %d", status);
|
||||
}
|
||||
|
||||
uint32_t expected_zero = ...
|
||||
if (expected_zero != 0) {
|
||||
mymodule_log_warning(
|
||||
"something suspicious happened (var = %"PRIu32"), "
|
||||
"fall back to generic implementation", expected_zero);
|
||||
}
|
||||
|
||||
void* usually_non_null = ...
|
||||
if (usually_non_null == NULL) {
|
||||
mymodule_log_info(
|
||||
"something unusual, but common, happened: "
|
||||
"enabling work-around");
|
||||
}
|
||||
|
||||
float a = ...
|
||||
mymodule_log_debug("computed a = %.7f", a);
|
||||
}
|
||||
```
|
||||
100
3rdparty/cpuinfo/deps/clog/include/clog.h
vendored
Normal file
100
3rdparty/cpuinfo/deps/clog/include/clog.h
vendored
Normal file
@@ -0,0 +1,100 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#define CLOG_NONE 0
|
||||
#define CLOG_FATAL 1
|
||||
#define CLOG_ERROR 2
|
||||
#define CLOG_WARNING 3
|
||||
#define CLOG_INFO 4
|
||||
#define CLOG_DEBUG 5
|
||||
|
||||
#ifndef CLOG_VISIBILITY
|
||||
#if defined(__ELF__)
|
||||
#define CLOG_VISIBILITY __attribute__((__visibility__("internal")))
|
||||
#elif defined(__MACH__)
|
||||
#define CLOG_VISIBILITY __attribute__((__visibility__("hidden")))
|
||||
#else
|
||||
#define CLOG_VISIBILITY
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef CLOG_ARGUMENTS_FORMAT
|
||||
#if defined(__GNUC__)
|
||||
#define CLOG_ARGUMENTS_FORMAT __attribute__((__format__(__printf__, 1, 2)))
|
||||
#else
|
||||
#define CLOG_ARGUMENTS_FORMAT
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
CLOG_VISIBILITY void clog_vlog_debug(const char* module, const char* format, va_list args);
|
||||
CLOG_VISIBILITY void clog_vlog_info(const char* module, const char* format, va_list args);
|
||||
CLOG_VISIBILITY void clog_vlog_warning(const char* module, const char* format, va_list args);
|
||||
CLOG_VISIBILITY void clog_vlog_error(const char* module, const char* format, va_list args);
|
||||
CLOG_VISIBILITY void clog_vlog_fatal(const char* module, const char* format, va_list args);
|
||||
|
||||
#define CLOG_DEFINE_LOG_DEBUG(log_debug_function_name, module, level) \
|
||||
CLOG_ARGUMENTS_FORMAT \
|
||||
inline static void log_debug_function_name(const char* format, ...) { \
|
||||
if (level >= CLOG_DEBUG) { \
|
||||
va_list args; \
|
||||
va_start(args, format); \
|
||||
clog_vlog_debug(module, format, args); \
|
||||
va_end(args); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define CLOG_DEFINE_LOG_INFO(log_info_function_name, module, level) \
|
||||
CLOG_ARGUMENTS_FORMAT \
|
||||
inline static void log_info_function_name(const char* format, ...) { \
|
||||
if (level >= CLOG_INFO) { \
|
||||
va_list args; \
|
||||
va_start(args, format); \
|
||||
clog_vlog_info(module, format, args); \
|
||||
va_end(args); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define CLOG_DEFINE_LOG_WARNING(log_warning_function_name, module, level) \
|
||||
CLOG_ARGUMENTS_FORMAT \
|
||||
inline static void log_warning_function_name(const char* format, ...) { \
|
||||
if (level >= CLOG_WARNING) { \
|
||||
va_list args; \
|
||||
va_start(args, format); \
|
||||
clog_vlog_warning(module, format, args); \
|
||||
va_end(args); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define CLOG_DEFINE_LOG_ERROR(log_error_function_name, module, level) \
|
||||
CLOG_ARGUMENTS_FORMAT \
|
||||
inline static void log_error_function_name(const char* format, ...) { \
|
||||
if (level >= CLOG_ERROR) { \
|
||||
va_list args; \
|
||||
va_start(args, format); \
|
||||
clog_vlog_error(module, format, args); \
|
||||
va_end(args); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define CLOG_DEFINE_LOG_FATAL(log_fatal_function_name, module, level) \
|
||||
CLOG_ARGUMENTS_FORMAT \
|
||||
inline static void log_fatal_function_name(const char* format, ...) { \
|
||||
if (level >= CLOG_FATAL) { \
|
||||
va_list args; \
|
||||
va_start(args, format); \
|
||||
clog_vlog_fatal(module, format, args); \
|
||||
va_end(args); \
|
||||
} \
|
||||
abort(); \
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
423
3rdparty/cpuinfo/deps/clog/src/clog.c
vendored
Normal file
423
3rdparty/cpuinfo/deps/clog/src/clog.c
vendored
Normal file
@@ -0,0 +1,423 @@
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#ifdef __ANDROID__
|
||||
#include <android/log.h>
|
||||
#endif
|
||||
|
||||
#ifndef CLOG_LOG_TO_STDIO
|
||||
#ifdef __ANDROID__
|
||||
#define CLOG_LOG_TO_STDIO 0
|
||||
#else
|
||||
#define CLOG_LOG_TO_STDIO 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <clog.h>
|
||||
|
||||
|
||||
/* Messages up to this size are formatted entirely on-stack, and don't allocate heap memory */
|
||||
#define CLOG_STACK_BUFFER_SIZE 1024
|
||||
|
||||
#define CLOG_FATAL_PREFIX "Fatal error: "
|
||||
#define CLOG_FATAL_PREFIX_LENGTH 13
|
||||
#define CLOG_FATAL_PREFIX_FORMAT "Fatal error in %s: "
|
||||
#define CLOG_ERROR_PREFIX "Error: "
|
||||
#define CLOG_ERROR_PREFIX_LENGTH 7
|
||||
#define CLOG_ERROR_PREFIX_FORMAT "Error in %s: "
|
||||
#define CLOG_WARNING_PREFIX "Warning: "
|
||||
#define CLOG_WARNING_PREFIX_LENGTH 9
|
||||
#define CLOG_WARNING_PREFIX_FORMAT "Warning in %s: "
|
||||
#define CLOG_INFO_PREFIX "Note: "
|
||||
#define CLOG_INFO_PREFIX_LENGTH 6
|
||||
#define CLOG_INFO_PREFIX_FORMAT "Note (%s): "
|
||||
#define CLOG_DEBUG_PREFIX "Debug: "
|
||||
#define CLOG_DEBUG_PREFIX_LENGTH 7
|
||||
#define CLOG_DEBUG_PREFIX_FORMAT "Debug (%s): "
|
||||
#define CLOG_SUFFIX_LENGTH 1
|
||||
|
||||
void clog_vlog_fatal(const char* module, const char* format, va_list args) {
|
||||
#if defined(__ANDROID__) && !CLOG_LOG_TO_STDIO
|
||||
__android_log_vprint(ANDROID_LOG_FATAL, module, format, args);
|
||||
#else
|
||||
char stack_buffer[CLOG_STACK_BUFFER_SIZE];
|
||||
char* heap_buffer = NULL;
|
||||
char* out_buffer = &stack_buffer[0];
|
||||
|
||||
/* The first call to vsnprintf will clobber args, thus need a copy in case a second vsnprintf call is needed */
|
||||
va_list args_copy;
|
||||
va_copy(args_copy, args);
|
||||
|
||||
int prefix_chars = CLOG_FATAL_PREFIX_LENGTH;
|
||||
if (module == NULL) {
|
||||
memcpy(stack_buffer, CLOG_FATAL_PREFIX, CLOG_FATAL_PREFIX_LENGTH);
|
||||
} else {
|
||||
prefix_chars = snprintf(stack_buffer, CLOG_STACK_BUFFER_SIZE, CLOG_FATAL_PREFIX_FORMAT, module);
|
||||
if (prefix_chars < 0) {
|
||||
/* Format error in prefix (possible if prefix is modified): skip prefix and continue as if nothing happened. */
|
||||
prefix_chars = 0;
|
||||
}
|
||||
}
|
||||
|
||||
int format_chars;
|
||||
if (prefix_chars + CLOG_SUFFIX_LENGTH >= CLOG_STACK_BUFFER_SIZE) {
|
||||
/*
|
||||
* Prefix + suffix alone would overflow the on-stack buffer, thus need to use on-heap buffer.
|
||||
* Do not even try to format the string into on-stack buffer.
|
||||
*/
|
||||
format_chars = vsnprintf(NULL, 0, format, args);
|
||||
} else {
|
||||
format_chars =
|
||||
vsnprintf(
|
||||
&stack_buffer[prefix_chars],
|
||||
CLOG_STACK_BUFFER_SIZE - prefix_chars - CLOG_SUFFIX_LENGTH,
|
||||
format,
|
||||
args);
|
||||
}
|
||||
if (format_chars < 0) {
|
||||
/* Format error in the message: silently ignore this particular message. */
|
||||
goto cleanup;
|
||||
}
|
||||
if (prefix_chars + format_chars + CLOG_SUFFIX_LENGTH > CLOG_STACK_BUFFER_SIZE) {
|
||||
/* Allocate a buffer on heap, and vsnprintf to this buffer */
|
||||
heap_buffer = malloc(prefix_chars + format_chars + CLOG_SUFFIX_LENGTH);
|
||||
if (heap_buffer == NULL) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (prefix_chars > CLOG_STACK_BUFFER_SIZE) {
|
||||
/* Prefix didn't fit into on-stack buffer, re-format it again to on-heap buffer */
|
||||
snprintf(heap_buffer, prefix_chars + 1 /* for '\0'-terminator */, CLOG_FATAL_PREFIX_FORMAT, module);
|
||||
} else {
|
||||
/* Copy pre-formatted prefix from on-stack buffer to on-heap buffer */
|
||||
memcpy(heap_buffer, stack_buffer, prefix_chars);
|
||||
}
|
||||
vsnprintf(heap_buffer + prefix_chars, format_chars + CLOG_SUFFIX_LENGTH, format, args_copy);
|
||||
out_buffer = heap_buffer;
|
||||
}
|
||||
out_buffer[prefix_chars + format_chars] = '\n';
|
||||
#ifdef _WIN32
|
||||
DWORD bytes_written;
|
||||
WriteFile(
|
||||
GetStdHandle(STD_ERROR_HANDLE),
|
||||
out_buffer, prefix_chars + format_chars + CLOG_SUFFIX_LENGTH,
|
||||
&bytes_written, NULL);
|
||||
#else
|
||||
write(STDERR_FILENO, out_buffer, prefix_chars + format_chars + CLOG_SUFFIX_LENGTH);
|
||||
#endif
|
||||
|
||||
cleanup:
|
||||
free(heap_buffer);
|
||||
va_end(args_copy);
|
||||
#endif
|
||||
}
|
||||
|
||||
void clog_vlog_error(const char* module, const char* format, va_list args) {
|
||||
#if defined(__ANDROID__) && !CLOG_LOG_TO_STDIO
|
||||
__android_log_vprint(ANDROID_LOG_ERROR, module, format, args);
|
||||
#else
|
||||
char stack_buffer[CLOG_STACK_BUFFER_SIZE];
|
||||
char* heap_buffer = NULL;
|
||||
char* out_buffer = &stack_buffer[0];
|
||||
|
||||
/* The first call to vsnprintf will clobber args, thus need a copy in case a second vsnprintf call is needed */
|
||||
va_list args_copy;
|
||||
va_copy(args_copy, args);
|
||||
|
||||
int prefix_chars = CLOG_ERROR_PREFIX_LENGTH;
|
||||
if (module == NULL) {
|
||||
memcpy(stack_buffer, CLOG_ERROR_PREFIX, CLOG_ERROR_PREFIX_LENGTH);
|
||||
} else {
|
||||
prefix_chars = snprintf(stack_buffer, CLOG_STACK_BUFFER_SIZE, CLOG_ERROR_PREFIX_FORMAT, module);
|
||||
if (prefix_chars < 0) {
|
||||
/* Format error in prefix (possible if prefix is modified): skip prefix and continue as if nothing happened. */
|
||||
prefix_chars = 0;
|
||||
}
|
||||
}
|
||||
|
||||
int format_chars;
|
||||
if (prefix_chars + CLOG_SUFFIX_LENGTH >= CLOG_STACK_BUFFER_SIZE) {
|
||||
/*
|
||||
* Prefix + suffix alone would overflow the on-stack buffer, thus need to use on-heap buffer.
|
||||
* Do not even try to format the string into on-stack buffer.
|
||||
*/
|
||||
format_chars = vsnprintf(NULL, 0, format, args);
|
||||
} else {
|
||||
format_chars =
|
||||
vsnprintf(
|
||||
&stack_buffer[prefix_chars],
|
||||
CLOG_STACK_BUFFER_SIZE - prefix_chars - CLOG_SUFFIX_LENGTH,
|
||||
format,
|
||||
args);
|
||||
}
|
||||
if (format_chars < 0) {
|
||||
/* Format error in the message: silently ignore this particular message. */
|
||||
goto cleanup;
|
||||
}
|
||||
if (prefix_chars + format_chars + CLOG_SUFFIX_LENGTH > CLOG_STACK_BUFFER_SIZE) {
|
||||
/* Allocate a buffer on heap, and vsnprintf to this buffer */
|
||||
heap_buffer = malloc(prefix_chars + format_chars + CLOG_SUFFIX_LENGTH);
|
||||
if (heap_buffer == NULL) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (prefix_chars > CLOG_STACK_BUFFER_SIZE) {
|
||||
/* Prefix didn't fit into on-stack buffer, re-format it again to on-heap buffer */
|
||||
snprintf(heap_buffer, prefix_chars + 1 /* for '\0'-terminator */, CLOG_ERROR_PREFIX_FORMAT, module);
|
||||
} else {
|
||||
/* Copy pre-formatted prefix from on-stack buffer to on-heap buffer */
|
||||
memcpy(heap_buffer, stack_buffer, prefix_chars);
|
||||
}
|
||||
vsnprintf(heap_buffer + prefix_chars, format_chars + CLOG_SUFFIX_LENGTH, format, args_copy);
|
||||
out_buffer = heap_buffer;
|
||||
}
|
||||
out_buffer[prefix_chars + format_chars] = '\n';
|
||||
#ifdef _WIN32
|
||||
DWORD bytes_written;
|
||||
WriteFile(
|
||||
GetStdHandle(STD_ERROR_HANDLE),
|
||||
out_buffer, prefix_chars + format_chars + CLOG_SUFFIX_LENGTH,
|
||||
&bytes_written, NULL);
|
||||
#else
|
||||
write(STDERR_FILENO, out_buffer, prefix_chars + format_chars + CLOG_SUFFIX_LENGTH);
|
||||
#endif
|
||||
|
||||
cleanup:
|
||||
free(heap_buffer);
|
||||
va_end(args_copy);
|
||||
#endif
|
||||
}
|
||||
|
||||
void clog_vlog_warning(const char* module, const char* format, va_list args) {
|
||||
#if defined(__ANDROID__) && !CLOG_LOG_TO_STDIO
|
||||
__android_log_vprint(ANDROID_LOG_WARN, module, format, args);
|
||||
#else
|
||||
char stack_buffer[CLOG_STACK_BUFFER_SIZE];
|
||||
char* heap_buffer = NULL;
|
||||
char* out_buffer = &stack_buffer[0];
|
||||
|
||||
/* The first call to vsnprintf will clobber args, thus need a copy in case a second vsnprintf call is needed */
|
||||
va_list args_copy;
|
||||
va_copy(args_copy, args);
|
||||
|
||||
int prefix_chars = CLOG_WARNING_PREFIX_LENGTH;
|
||||
if (module == NULL) {
|
||||
memcpy(stack_buffer, CLOG_WARNING_PREFIX, CLOG_WARNING_PREFIX_LENGTH);
|
||||
} else {
|
||||
prefix_chars = snprintf(stack_buffer, CLOG_STACK_BUFFER_SIZE, CLOG_WARNING_PREFIX_FORMAT, module);
|
||||
if (prefix_chars < 0) {
|
||||
/* Format error in prefix (possible if prefix is modified): skip prefix and continue as if nothing happened. */
|
||||
prefix_chars = 0;
|
||||
}
|
||||
}
|
||||
|
||||
int format_chars;
|
||||
if (prefix_chars + CLOG_SUFFIX_LENGTH >= CLOG_STACK_BUFFER_SIZE) {
|
||||
/*
|
||||
* Prefix + suffix alone would overflow the on-stack buffer, thus need to use on-heap buffer.
|
||||
* Do not even try to format the string into on-stack buffer.
|
||||
*/
|
||||
format_chars = vsnprintf(NULL, 0, format, args);
|
||||
} else {
|
||||
format_chars =
|
||||
vsnprintf(
|
||||
&stack_buffer[prefix_chars],
|
||||
CLOG_STACK_BUFFER_SIZE - prefix_chars - CLOG_SUFFIX_LENGTH,
|
||||
format,
|
||||
args);
|
||||
}
|
||||
if (format_chars < 0) {
|
||||
/* Format error in the message: silently ignore this particular message. */
|
||||
goto cleanup;
|
||||
}
|
||||
if (prefix_chars + format_chars + CLOG_SUFFIX_LENGTH > CLOG_STACK_BUFFER_SIZE) {
|
||||
/* Allocate a buffer on heap, and vsnprintf to this buffer */
|
||||
heap_buffer = malloc(prefix_chars + format_chars + CLOG_SUFFIX_LENGTH);
|
||||
if (heap_buffer == NULL) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (prefix_chars > CLOG_STACK_BUFFER_SIZE) {
|
||||
/* Prefix didn't fit into on-stack buffer, re-format it again to on-heap buffer */
|
||||
snprintf(heap_buffer, prefix_chars + 1 /* for '\0'-terminator */, CLOG_WARNING_PREFIX_FORMAT, module);
|
||||
} else {
|
||||
/* Copy pre-formatted prefix from on-stack buffer to on-heap buffer */
|
||||
memcpy(heap_buffer, stack_buffer, prefix_chars);
|
||||
}
|
||||
vsnprintf(heap_buffer + prefix_chars, format_chars + CLOG_SUFFIX_LENGTH, format, args_copy);
|
||||
out_buffer = heap_buffer;
|
||||
}
|
||||
out_buffer[prefix_chars + format_chars] = '\n';
|
||||
#ifdef _WIN32
|
||||
DWORD bytes_written;
|
||||
WriteFile(
|
||||
GetStdHandle(STD_ERROR_HANDLE),
|
||||
out_buffer, prefix_chars + format_chars + CLOG_SUFFIX_LENGTH,
|
||||
&bytes_written, NULL);
|
||||
#else
|
||||
write(STDERR_FILENO, out_buffer, prefix_chars + format_chars + CLOG_SUFFIX_LENGTH);
|
||||
#endif
|
||||
|
||||
cleanup:
|
||||
free(heap_buffer);
|
||||
va_end(args_copy);
|
||||
#endif
|
||||
}
|
||||
|
||||
void clog_vlog_info(const char* module, const char* format, va_list args) {
|
||||
#if defined(__ANDROID__) && !CLOG_LOG_TO_STDIO
|
||||
__android_log_vprint(ANDROID_LOG_INFO, module, format, args);
|
||||
#else
|
||||
char stack_buffer[CLOG_STACK_BUFFER_SIZE];
|
||||
char* heap_buffer = NULL;
|
||||
char* out_buffer = &stack_buffer[0];
|
||||
|
||||
/* The first call to vsnprintf will clobber args, thus need a copy in case a second vsnprintf call is needed */
|
||||
va_list args_copy;
|
||||
va_copy(args_copy, args);
|
||||
|
||||
int prefix_chars = CLOG_INFO_PREFIX_LENGTH;
|
||||
if (module == NULL) {
|
||||
memcpy(stack_buffer, CLOG_INFO_PREFIX, CLOG_INFO_PREFIX_LENGTH);
|
||||
} else {
|
||||
prefix_chars = snprintf(stack_buffer, CLOG_STACK_BUFFER_SIZE, CLOG_INFO_PREFIX_FORMAT, module);
|
||||
if (prefix_chars < 0) {
|
||||
/* Format error in prefix (possible if prefix is modified): skip prefix and continue as if nothing happened. */
|
||||
prefix_chars = 0;
|
||||
}
|
||||
}
|
||||
|
||||
int format_chars;
|
||||
if (prefix_chars + CLOG_SUFFIX_LENGTH >= CLOG_STACK_BUFFER_SIZE) {
|
||||
/*
|
||||
* Prefix + suffix alone would overflow the on-stack buffer, thus need to use on-heap buffer.
|
||||
* Do not even try to format the string into on-stack buffer.
|
||||
*/
|
||||
format_chars = vsnprintf(NULL, 0, format, args);
|
||||
} else {
|
||||
format_chars =
|
||||
vsnprintf(
|
||||
&stack_buffer[prefix_chars],
|
||||
CLOG_STACK_BUFFER_SIZE - prefix_chars - CLOG_SUFFIX_LENGTH,
|
||||
format,
|
||||
args);
|
||||
}
|
||||
if (format_chars < 0) {
|
||||
/* Format error in the message: silently ignore this particular message. */
|
||||
goto cleanup;
|
||||
}
|
||||
if (prefix_chars + format_chars + CLOG_SUFFIX_LENGTH > CLOG_STACK_BUFFER_SIZE) {
|
||||
/* Allocate a buffer on heap, and vsnprintf to this buffer */
|
||||
heap_buffer = malloc(prefix_chars + format_chars + CLOG_SUFFIX_LENGTH);
|
||||
if (heap_buffer == NULL) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (prefix_chars > CLOG_STACK_BUFFER_SIZE) {
|
||||
/* Prefix didn't fit into on-stack buffer, re-format it again to on-heap buffer */
|
||||
snprintf(heap_buffer, prefix_chars + 1 /* for '\0'-terminator */, CLOG_INFO_PREFIX_FORMAT, module);
|
||||
} else {
|
||||
/* Copy pre-formatted prefix from on-stack buffer to on-heap buffer */
|
||||
memcpy(heap_buffer, stack_buffer, prefix_chars);
|
||||
}
|
||||
vsnprintf(heap_buffer + prefix_chars, format_chars + CLOG_SUFFIX_LENGTH, format, args_copy);
|
||||
out_buffer = heap_buffer;
|
||||
}
|
||||
out_buffer[prefix_chars + format_chars] = '\n';
|
||||
#ifdef _WIN32
|
||||
DWORD bytes_written;
|
||||
WriteFile(
|
||||
GetStdHandle(STD_OUTPUT_HANDLE),
|
||||
out_buffer, prefix_chars + format_chars + CLOG_SUFFIX_LENGTH,
|
||||
&bytes_written, NULL);
|
||||
#else
|
||||
write(STDOUT_FILENO, out_buffer, prefix_chars + format_chars + CLOG_SUFFIX_LENGTH);
|
||||
#endif
|
||||
|
||||
cleanup:
|
||||
free(heap_buffer);
|
||||
va_end(args_copy);
|
||||
#endif
|
||||
}
|
||||
|
||||
void clog_vlog_debug(const char* module, const char* format, va_list args) {
|
||||
#if defined(__ANDROID__) && !CLOG_LOG_TO_STDIO
|
||||
__android_log_vprint(ANDROID_LOG_DEBUG, module, format, args);
|
||||
#else
|
||||
char stack_buffer[CLOG_STACK_BUFFER_SIZE];
|
||||
char* heap_buffer = NULL;
|
||||
char* out_buffer = &stack_buffer[0];
|
||||
|
||||
/* The first call to vsnprintf will clobber args, thus need a copy in case a second vsnprintf call is needed */
|
||||
va_list args_copy;
|
||||
va_copy(args_copy, args);
|
||||
|
||||
int prefix_chars = CLOG_DEBUG_PREFIX_LENGTH;
|
||||
if (module == NULL) {
|
||||
memcpy(stack_buffer, CLOG_DEBUG_PREFIX, CLOG_DEBUG_PREFIX_LENGTH);
|
||||
} else {
|
||||
prefix_chars = snprintf(stack_buffer, CLOG_STACK_BUFFER_SIZE, CLOG_DEBUG_PREFIX_FORMAT, module);
|
||||
if (prefix_chars < 0) {
|
||||
/* Format error in prefix (possible if prefix is modified): skip prefix and continue as if nothing happened. */
|
||||
prefix_chars = 0;
|
||||
}
|
||||
}
|
||||
|
||||
int format_chars;
|
||||
if (prefix_chars + CLOG_SUFFIX_LENGTH >= CLOG_STACK_BUFFER_SIZE) {
|
||||
/*
|
||||
* Prefix + suffix alone would overflow the on-stack buffer, thus need to use on-heap buffer.
|
||||
* Do not even try to format the string into on-stack buffer.
|
||||
*/
|
||||
format_chars = vsnprintf(NULL, 0, format, args);
|
||||
} else {
|
||||
format_chars =
|
||||
vsnprintf(
|
||||
&stack_buffer[prefix_chars],
|
||||
CLOG_STACK_BUFFER_SIZE - prefix_chars - CLOG_SUFFIX_LENGTH,
|
||||
format,
|
||||
args);
|
||||
}
|
||||
if (format_chars < 0) {
|
||||
/* Format error in the message: silently ignore this particular message. */
|
||||
goto cleanup;
|
||||
}
|
||||
if (prefix_chars + format_chars + CLOG_SUFFIX_LENGTH > CLOG_STACK_BUFFER_SIZE) {
|
||||
/* Allocate a buffer on heap, and vsnprintf to this buffer */
|
||||
heap_buffer = malloc(prefix_chars + format_chars + CLOG_SUFFIX_LENGTH);
|
||||
if (heap_buffer == NULL) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (prefix_chars > CLOG_STACK_BUFFER_SIZE) {
|
||||
/* Prefix didn't fit into on-stack buffer, re-format it again to on-heap buffer */
|
||||
snprintf(heap_buffer, prefix_chars + 1 /* for '\0'-terminator */, CLOG_DEBUG_PREFIX_FORMAT, module);
|
||||
} else {
|
||||
/* Copy pre-formatted prefix from on-stack buffer to on-heap buffer */
|
||||
memcpy(heap_buffer, stack_buffer, prefix_chars);
|
||||
}
|
||||
vsnprintf(heap_buffer + prefix_chars, format_chars + CLOG_SUFFIX_LENGTH, format, args_copy);
|
||||
out_buffer = heap_buffer;
|
||||
}
|
||||
out_buffer[prefix_chars + format_chars] = '\n';
|
||||
#ifdef _WIN32
|
||||
DWORD bytes_written;
|
||||
WriteFile(
|
||||
GetStdHandle(STD_OUTPUT_HANDLE),
|
||||
out_buffer, prefix_chars + format_chars + CLOG_SUFFIX_LENGTH,
|
||||
&bytes_written, NULL);
|
||||
#else
|
||||
write(STDOUT_FILENO, out_buffer, prefix_chars + format_chars + CLOG_SUFFIX_LENGTH);
|
||||
#endif
|
||||
|
||||
cleanup:
|
||||
free(heap_buffer);
|
||||
va_end(args_copy);
|
||||
#endif
|
||||
}
|
||||
78
3rdparty/cpuinfo/include/cpuinfo-mock.h
vendored
Normal file
78
3rdparty/cpuinfo/include/cpuinfo-mock.h
vendored
Normal file
@@ -0,0 +1,78 @@
|
||||
#pragma once
|
||||
#ifndef CPUINFO_MOCK_H
|
||||
#define CPUINFO_MOCK_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <cpuinfo.h>
|
||||
#if defined(__linux__)
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
|
||||
#if !defined(CPUINFO_MOCK) || !(CPUINFO_MOCK)
|
||||
#error This header is intended only for test use
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
#if CPUINFO_ARCH_ARM
|
||||
void CPUINFO_ABI cpuinfo_set_fpsid(uint32_t fpsid);
|
||||
void CPUINFO_ABI cpuinfo_set_wcid(uint32_t wcid);
|
||||
#endif /* CPUINFO_ARCH_ARM */
|
||||
|
||||
#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
|
||||
struct cpuinfo_mock_cpuid {
|
||||
uint32_t input_eax;
|
||||
uint32_t input_ecx;
|
||||
uint32_t eax;
|
||||
uint32_t ebx;
|
||||
uint32_t ecx;
|
||||
uint32_t edx;
|
||||
};
|
||||
|
||||
void CPUINFO_ABI cpuinfo_mock_set_cpuid(struct cpuinfo_mock_cpuid* dump, size_t entries);
|
||||
void CPUINFO_ABI cpuinfo_mock_get_cpuid(uint32_t eax, uint32_t regs[4]);
|
||||
void CPUINFO_ABI cpuinfo_mock_get_cpuidex(uint32_t eax, uint32_t ecx, uint32_t regs[4]);
|
||||
#endif /* CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 */
|
||||
|
||||
struct cpuinfo_mock_file {
|
||||
const char* path;
|
||||
size_t size;
|
||||
const char* content;
|
||||
size_t offset;
|
||||
};
|
||||
|
||||
struct cpuinfo_mock_property {
|
||||
const char* key;
|
||||
const char* value;
|
||||
};
|
||||
|
||||
#if defined(__linux__)
|
||||
void CPUINFO_ABI cpuinfo_mock_filesystem(struct cpuinfo_mock_file* files);
|
||||
int CPUINFO_ABI cpuinfo_mock_open(const char* path, int oflag);
|
||||
int CPUINFO_ABI cpuinfo_mock_close(int fd);
|
||||
ssize_t CPUINFO_ABI cpuinfo_mock_read(int fd, void* buffer, size_t capacity);
|
||||
|
||||
#if CPUINFO_ARCH_ARM || CPUINFO_ARCH_ARM64
|
||||
void CPUINFO_ABI cpuinfo_set_hwcap(uint32_t hwcap);
|
||||
#endif
|
||||
#if CPUINFO_ARCH_ARM
|
||||
void CPUINFO_ABI cpuinfo_set_hwcap2(uint32_t hwcap2);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(__ANDROID__)
|
||||
void CPUINFO_ABI cpuinfo_mock_android_properties(struct cpuinfo_mock_property* properties);
|
||||
void CPUINFO_ABI cpuinfo_mock_gl_renderer(const char* renderer);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* CPUINFO_MOCK_H */
|
||||
1872
3rdparty/cpuinfo/include/cpuinfo.h
vendored
Normal file
1872
3rdparty/cpuinfo/include/cpuinfo.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
410
3rdparty/cpuinfo/src/api.c
vendored
Normal file
410
3rdparty/cpuinfo/src/api.c
vendored
Normal file
@@ -0,0 +1,410 @@
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include <cpuinfo.h>
|
||||
#include <cpuinfo/internal-api.h>
|
||||
#include <cpuinfo/log.h>
|
||||
|
||||
#ifdef __linux__
|
||||
#include <linux/api.h>
|
||||
|
||||
#include <unistd.h>
|
||||
#include <sys/syscall.h>
|
||||
#if !defined(__NR_getcpu)
|
||||
#include <asm-generic/unistd.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
bool cpuinfo_is_initialized = false;
|
||||
|
||||
struct cpuinfo_processor* cpuinfo_processors = NULL;
|
||||
struct cpuinfo_core* cpuinfo_cores = NULL;
|
||||
struct cpuinfo_cluster* cpuinfo_clusters = NULL;
|
||||
struct cpuinfo_package* cpuinfo_packages = NULL;
|
||||
struct cpuinfo_cache* cpuinfo_cache[cpuinfo_cache_level_max] = { NULL };
|
||||
|
||||
uint32_t cpuinfo_processors_count = 0;
|
||||
uint32_t cpuinfo_cores_count = 0;
|
||||
uint32_t cpuinfo_clusters_count = 0;
|
||||
uint32_t cpuinfo_packages_count = 0;
|
||||
uint32_t cpuinfo_cache_count[cpuinfo_cache_level_max] = { 0 };
|
||||
uint32_t cpuinfo_max_cache_size = 0;
|
||||
|
||||
#if CPUINFO_ARCH_ARM || CPUINFO_ARCH_ARM64
|
||||
struct cpuinfo_uarch_info* cpuinfo_uarchs = NULL;
|
||||
uint32_t cpuinfo_uarchs_count = 0;
|
||||
#else
|
||||
struct cpuinfo_uarch_info cpuinfo_global_uarch = { cpuinfo_uarch_unknown };
|
||||
#endif
|
||||
|
||||
#ifdef __linux__
|
||||
uint32_t cpuinfo_linux_cpu_max = 0;
|
||||
const struct cpuinfo_processor** cpuinfo_linux_cpu_to_processor_map = NULL;
|
||||
const struct cpuinfo_core** cpuinfo_linux_cpu_to_core_map = NULL;
|
||||
#if CPUINFO_ARCH_ARM || CPUINFO_ARCH_ARM64
|
||||
const uint32_t* cpuinfo_linux_cpu_to_uarch_index_map = NULL;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
const struct cpuinfo_processor* cpuinfo_get_processors(void) {
|
||||
if CPUINFO_UNLIKELY(!cpuinfo_is_initialized) {
|
||||
cpuinfo_log_fatal("cpuinfo_get_%s called before cpuinfo is initialized", "processors");
|
||||
}
|
||||
return cpuinfo_processors;
|
||||
}
|
||||
|
||||
const struct cpuinfo_core* cpuinfo_get_cores(void) {
|
||||
if CPUINFO_UNLIKELY(!cpuinfo_is_initialized) {
|
||||
cpuinfo_log_fatal("cpuinfo_get_%s called before cpuinfo is initialized", "core");
|
||||
}
|
||||
return cpuinfo_cores;
|
||||
}
|
||||
|
||||
const struct cpuinfo_cluster* cpuinfo_get_clusters(void) {
|
||||
if CPUINFO_UNLIKELY(!cpuinfo_is_initialized) {
|
||||
cpuinfo_log_fatal("cpuinfo_get_%s called before cpuinfo is initialized", "clusters");
|
||||
}
|
||||
return cpuinfo_clusters;
|
||||
}
|
||||
|
||||
const struct cpuinfo_package* cpuinfo_get_packages(void) {
|
||||
if CPUINFO_UNLIKELY(!cpuinfo_is_initialized) {
|
||||
cpuinfo_log_fatal("cpuinfo_get_%s called before cpuinfo is initialized", "packages");
|
||||
}
|
||||
return cpuinfo_packages;
|
||||
}
|
||||
|
||||
const struct cpuinfo_uarch_info* cpuinfo_get_uarchs() {
|
||||
if (!cpuinfo_is_initialized) {
|
||||
cpuinfo_log_fatal("cpuinfo_get_%s called before cpuinfo is initialized", "uarchs");
|
||||
}
|
||||
#if CPUINFO_ARCH_ARM || CPUINFO_ARCH_ARM64
|
||||
return cpuinfo_uarchs;
|
||||
#else
|
||||
return &cpuinfo_global_uarch;
|
||||
#endif
|
||||
}
|
||||
|
||||
const struct cpuinfo_processor* cpuinfo_get_processor(uint32_t index) {
|
||||
if CPUINFO_UNLIKELY(!cpuinfo_is_initialized) {
|
||||
cpuinfo_log_fatal("cpuinfo_get_%s called before cpuinfo is initialized", "processor");
|
||||
}
|
||||
if CPUINFO_UNLIKELY(index >= cpuinfo_processors_count) {
|
||||
return NULL;
|
||||
}
|
||||
return &cpuinfo_processors[index];
|
||||
}
|
||||
|
||||
const struct cpuinfo_core* cpuinfo_get_core(uint32_t index) {
|
||||
if CPUINFO_UNLIKELY(!cpuinfo_is_initialized) {
|
||||
cpuinfo_log_fatal("cpuinfo_get_%s called before cpuinfo is initialized", "core");
|
||||
}
|
||||
if CPUINFO_UNLIKELY(index >= cpuinfo_cores_count) {
|
||||
return NULL;
|
||||
}
|
||||
return &cpuinfo_cores[index];
|
||||
}
|
||||
|
||||
const struct cpuinfo_cluster* cpuinfo_get_cluster(uint32_t index) {
|
||||
if CPUINFO_UNLIKELY(!cpuinfo_is_initialized) {
|
||||
cpuinfo_log_fatal("cpuinfo_get_%s called before cpuinfo is initialized", "cluster");
|
||||
}
|
||||
if CPUINFO_UNLIKELY(index >= cpuinfo_clusters_count) {
|
||||
return NULL;
|
||||
}
|
||||
return &cpuinfo_clusters[index];
|
||||
}
|
||||
|
||||
const struct cpuinfo_package* cpuinfo_get_package(uint32_t index) {
|
||||
if CPUINFO_UNLIKELY(!cpuinfo_is_initialized) {
|
||||
cpuinfo_log_fatal("cpuinfo_get_%s called before cpuinfo is initialized", "package");
|
||||
}
|
||||
if CPUINFO_UNLIKELY(index >= cpuinfo_packages_count) {
|
||||
return NULL;
|
||||
}
|
||||
return &cpuinfo_packages[index];
|
||||
}
|
||||
|
||||
const struct cpuinfo_uarch_info* cpuinfo_get_uarch(uint32_t index) {
|
||||
if (!cpuinfo_is_initialized) {
|
||||
cpuinfo_log_fatal("cpuinfo_get_%s called before cpuinfo is initialized", "uarch");
|
||||
}
|
||||
#if CPUINFO_ARCH_ARM || CPUINFO_ARCH_ARM64
|
||||
if CPUINFO_UNLIKELY(index >= cpuinfo_uarchs_count) {
|
||||
return NULL;
|
||||
}
|
||||
return &cpuinfo_uarchs[index];
|
||||
#else
|
||||
if CPUINFO_UNLIKELY(index != 0) {
|
||||
return NULL;
|
||||
}
|
||||
return &cpuinfo_global_uarch;
|
||||
#endif
|
||||
}
|
||||
|
||||
uint32_t cpuinfo_get_processors_count(void) {
|
||||
if CPUINFO_UNLIKELY(!cpuinfo_is_initialized) {
|
||||
cpuinfo_log_fatal("cpuinfo_get_%s called before cpuinfo is initialized", "processors_count");
|
||||
}
|
||||
return cpuinfo_processors_count;
|
||||
}
|
||||
|
||||
uint32_t cpuinfo_get_cores_count(void) {
|
||||
if CPUINFO_UNLIKELY(!cpuinfo_is_initialized) {
|
||||
cpuinfo_log_fatal("cpuinfo_get_%s called before cpuinfo is initialized", "cores_count");
|
||||
}
|
||||
return cpuinfo_cores_count;
|
||||
}
|
||||
|
||||
uint32_t cpuinfo_get_clusters_count(void) {
|
||||
if CPUINFO_UNLIKELY(!cpuinfo_is_initialized) {
|
||||
cpuinfo_log_fatal("cpuinfo_get_%s called before cpuinfo is initialized", "clusters_count");
|
||||
}
|
||||
return cpuinfo_clusters_count;
|
||||
}
|
||||
|
||||
uint32_t cpuinfo_get_packages_count(void) {
|
||||
if CPUINFO_UNLIKELY(!cpuinfo_is_initialized) {
|
||||
cpuinfo_log_fatal("cpuinfo_get_%s called before cpuinfo is initialized", "packages_count");
|
||||
}
|
||||
return cpuinfo_packages_count;
|
||||
}
|
||||
|
||||
uint32_t cpuinfo_get_uarchs_count(void) {
|
||||
if (!cpuinfo_is_initialized) {
|
||||
cpuinfo_log_fatal("cpuinfo_get_%s called before cpuinfo is initialized", "uarchs_count");
|
||||
}
|
||||
#if CPUINFO_ARCH_ARM || CPUINFO_ARCH_ARM64
|
||||
return cpuinfo_uarchs_count;
|
||||
#else
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
const struct cpuinfo_cache* CPUINFO_ABI cpuinfo_get_l1i_caches(void) {
|
||||
if CPUINFO_UNLIKELY(!cpuinfo_is_initialized) {
|
||||
cpuinfo_log_fatal("cpuinfo_get_%s called before cpuinfo is initialized", "l1i_caches");
|
||||
}
|
||||
return cpuinfo_cache[cpuinfo_cache_level_1i];
|
||||
}
|
||||
|
||||
const struct cpuinfo_cache* CPUINFO_ABI cpuinfo_get_l1d_caches(void) {
|
||||
if CPUINFO_UNLIKELY(!cpuinfo_is_initialized) {
|
||||
cpuinfo_log_fatal("cpuinfo_get_%s called before cpuinfo is initialized", "l1d_caches");
|
||||
}
|
||||
return cpuinfo_cache[cpuinfo_cache_level_1d];
|
||||
}
|
||||
|
||||
const struct cpuinfo_cache* CPUINFO_ABI cpuinfo_get_l2_caches(void) {
|
||||
if CPUINFO_UNLIKELY(!cpuinfo_is_initialized) {
|
||||
cpuinfo_log_fatal("cpuinfo_get_%s called before cpuinfo is initialized", "l2_caches");
|
||||
}
|
||||
return cpuinfo_cache[cpuinfo_cache_level_2];
|
||||
}
|
||||
|
||||
const struct cpuinfo_cache* CPUINFO_ABI cpuinfo_get_l3_caches(void) {
|
||||
if CPUINFO_UNLIKELY(!cpuinfo_is_initialized) {
|
||||
cpuinfo_log_fatal("cpuinfo_get_%s called before cpuinfo is initialized", "l3_caches");
|
||||
}
|
||||
return cpuinfo_cache[cpuinfo_cache_level_3];
|
||||
}
|
||||
|
||||
const struct cpuinfo_cache* CPUINFO_ABI cpuinfo_get_l4_caches(void) {
|
||||
if CPUINFO_UNLIKELY(!cpuinfo_is_initialized) {
|
||||
cpuinfo_log_fatal("cpuinfo_get_%s called before cpuinfo is initialized", "l4_caches");
|
||||
}
|
||||
return cpuinfo_cache[cpuinfo_cache_level_4];
|
||||
}
|
||||
|
||||
const struct cpuinfo_cache* CPUINFO_ABI cpuinfo_get_l1i_cache(uint32_t index) {
|
||||
if CPUINFO_UNLIKELY(!cpuinfo_is_initialized) {
|
||||
cpuinfo_log_fatal("cpuinfo_get_%s called before cpuinfo is initialized", "l1i_cache");
|
||||
}
|
||||
if CPUINFO_UNLIKELY(index >= cpuinfo_cache_count[cpuinfo_cache_level_1i]) {
|
||||
return NULL;
|
||||
}
|
||||
return &cpuinfo_cache[cpuinfo_cache_level_1i][index];
|
||||
}
|
||||
|
||||
const struct cpuinfo_cache* CPUINFO_ABI cpuinfo_get_l1d_cache(uint32_t index) {
|
||||
if CPUINFO_UNLIKELY(!cpuinfo_is_initialized) {
|
||||
cpuinfo_log_fatal("cpuinfo_get_%s called before cpuinfo is initialized", "l1d_cache");
|
||||
}
|
||||
if CPUINFO_UNLIKELY(index >= cpuinfo_cache_count[cpuinfo_cache_level_1d]) {
|
||||
return NULL;
|
||||
}
|
||||
return &cpuinfo_cache[cpuinfo_cache_level_1d][index];
|
||||
}
|
||||
|
||||
const struct cpuinfo_cache* CPUINFO_ABI cpuinfo_get_l2_cache(uint32_t index) {
|
||||
if CPUINFO_UNLIKELY(!cpuinfo_is_initialized) {
|
||||
cpuinfo_log_fatal("cpuinfo_get_%s called before cpuinfo is initialized", "l2_cache");
|
||||
}
|
||||
if CPUINFO_UNLIKELY(index >= cpuinfo_cache_count[cpuinfo_cache_level_2]) {
|
||||
return NULL;
|
||||
}
|
||||
return &cpuinfo_cache[cpuinfo_cache_level_2][index];
|
||||
}
|
||||
|
||||
const struct cpuinfo_cache* CPUINFO_ABI cpuinfo_get_l3_cache(uint32_t index) {
|
||||
if CPUINFO_UNLIKELY(!cpuinfo_is_initialized) {
|
||||
cpuinfo_log_fatal("cpuinfo_get_%s called before cpuinfo is initialized", "l3_cache");
|
||||
}
|
||||
if CPUINFO_UNLIKELY(index >= cpuinfo_cache_count[cpuinfo_cache_level_3]) {
|
||||
return NULL;
|
||||
}
|
||||
return &cpuinfo_cache[cpuinfo_cache_level_3][index];
|
||||
}
|
||||
|
||||
const struct cpuinfo_cache* CPUINFO_ABI cpuinfo_get_l4_cache(uint32_t index) {
|
||||
if CPUINFO_UNLIKELY(!cpuinfo_is_initialized) {
|
||||
cpuinfo_log_fatal("cpuinfo_get_%s called before cpuinfo is initialized", "l4_cache");
|
||||
}
|
||||
if CPUINFO_UNLIKELY(index >= cpuinfo_cache_count[cpuinfo_cache_level_4]) {
|
||||
return NULL;
|
||||
}
|
||||
return &cpuinfo_cache[cpuinfo_cache_level_4][index];
|
||||
}
|
||||
|
||||
uint32_t CPUINFO_ABI cpuinfo_get_l1i_caches_count(void) {
|
||||
if CPUINFO_UNLIKELY(!cpuinfo_is_initialized) {
|
||||
cpuinfo_log_fatal("cpuinfo_get_%s called before cpuinfo is initialized", "l1i_caches_count");
|
||||
}
|
||||
return cpuinfo_cache_count[cpuinfo_cache_level_1i];
|
||||
}
|
||||
|
||||
uint32_t CPUINFO_ABI cpuinfo_get_l1d_caches_count(void) {
|
||||
if CPUINFO_UNLIKELY(!cpuinfo_is_initialized) {
|
||||
cpuinfo_log_fatal("cpuinfo_get_%s called before cpuinfo is initialized", "l1d_caches_count");
|
||||
}
|
||||
return cpuinfo_cache_count[cpuinfo_cache_level_1d];
|
||||
}
|
||||
|
||||
uint32_t CPUINFO_ABI cpuinfo_get_l2_caches_count(void) {
|
||||
if CPUINFO_UNLIKELY(!cpuinfo_is_initialized) {
|
||||
cpuinfo_log_fatal("cpuinfo_get_%s called before cpuinfo is initialized", "l2_caches_count");
|
||||
}
|
||||
return cpuinfo_cache_count[cpuinfo_cache_level_2];
|
||||
}
|
||||
|
||||
uint32_t CPUINFO_ABI cpuinfo_get_l3_caches_count(void) {
|
||||
if CPUINFO_UNLIKELY(!cpuinfo_is_initialized) {
|
||||
cpuinfo_log_fatal("cpuinfo_get_%s called before cpuinfo is initialized", "l3_caches_count");
|
||||
}
|
||||
return cpuinfo_cache_count[cpuinfo_cache_level_3];
|
||||
}
|
||||
|
||||
uint32_t CPUINFO_ABI cpuinfo_get_l4_caches_count(void) {
|
||||
if CPUINFO_UNLIKELY(!cpuinfo_is_initialized) {
|
||||
cpuinfo_log_fatal("cpuinfo_get_%s called before cpuinfo is initialized", "l4_caches_count");
|
||||
}
|
||||
return cpuinfo_cache_count[cpuinfo_cache_level_4];
|
||||
}
|
||||
|
||||
uint32_t CPUINFO_ABI cpuinfo_get_max_cache_size(void) {
|
||||
if CPUINFO_UNLIKELY(!cpuinfo_is_initialized) {
|
||||
cpuinfo_log_fatal("cpuinfo_get_%s called before cpuinfo is initialized", "max_cache_size");
|
||||
}
|
||||
return cpuinfo_max_cache_size;
|
||||
}
|
||||
|
||||
const struct cpuinfo_processor* CPUINFO_ABI cpuinfo_get_current_processor(void) {
|
||||
if CPUINFO_UNLIKELY(!cpuinfo_is_initialized) {
|
||||
cpuinfo_log_fatal("cpuinfo_get_%s called before cpuinfo is initialized", "current_processor");
|
||||
}
|
||||
#ifdef __linux__
|
||||
/* Initializing this variable silences a MemorySanitizer error. */
|
||||
unsigned cpu = 0;
|
||||
if CPUINFO_UNLIKELY(syscall(__NR_getcpu, &cpu, NULL, NULL) != 0) {
|
||||
return 0;
|
||||
}
|
||||
if CPUINFO_UNLIKELY((uint32_t) cpu >= cpuinfo_linux_cpu_max) {
|
||||
return 0;
|
||||
}
|
||||
return cpuinfo_linux_cpu_to_processor_map[cpu];
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
const struct cpuinfo_core* CPUINFO_ABI cpuinfo_get_current_core(void) {
|
||||
if CPUINFO_UNLIKELY(!cpuinfo_is_initialized) {
|
||||
cpuinfo_log_fatal("cpuinfo_get_%s called before cpuinfo is initialized", "current_core");
|
||||
}
|
||||
#ifdef __linux__
|
||||
/* Initializing this variable silences a MemorySanitizer error. */
|
||||
unsigned cpu = 0;
|
||||
if CPUINFO_UNLIKELY(syscall(__NR_getcpu, &cpu, NULL, NULL) != 0) {
|
||||
return 0;
|
||||
}
|
||||
if CPUINFO_UNLIKELY((uint32_t) cpu >= cpuinfo_linux_cpu_max) {
|
||||
return 0;
|
||||
}
|
||||
return cpuinfo_linux_cpu_to_core_map[cpu];
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
uint32_t CPUINFO_ABI cpuinfo_get_current_uarch_index(void) {
|
||||
if CPUINFO_UNLIKELY(!cpuinfo_is_initialized) {
|
||||
cpuinfo_log_fatal("cpuinfo_get_%s called before cpuinfo is initialized", "current_uarch_index");
|
||||
}
|
||||
#if CPUINFO_ARCH_ARM || CPUINFO_ARCH_ARM64
|
||||
#ifdef __linux__
|
||||
if (cpuinfo_linux_cpu_to_uarch_index_map == NULL) {
|
||||
/* Special case: avoid syscall on systems with only a single type of cores */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* General case */
|
||||
/* Initializing this variable silences a MemorySanitizer error. */
|
||||
unsigned cpu = 0;
|
||||
if CPUINFO_UNLIKELY(syscall(__NR_getcpu, &cpu, NULL, NULL) != 0) {
|
||||
return 0;
|
||||
}
|
||||
if CPUINFO_UNLIKELY((uint32_t) cpu >= cpuinfo_linux_cpu_max) {
|
||||
return 0;
|
||||
}
|
||||
return cpuinfo_linux_cpu_to_uarch_index_map[cpu];
|
||||
#else
|
||||
/* Fallback: pretend to be on the big core. */
|
||||
return 0;
|
||||
#endif
|
||||
#else
|
||||
/* Only ARM/ARM64 processors may include cores of different types in the same package. */
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
uint32_t CPUINFO_ABI cpuinfo_get_current_uarch_index_with_default(uint32_t default_uarch_index) {
|
||||
if CPUINFO_UNLIKELY(!cpuinfo_is_initialized) {
|
||||
cpuinfo_log_fatal("cpuinfo_get_%s called before cpuinfo is initialized", "current_uarch_index_with_default");
|
||||
}
|
||||
#if CPUINFO_ARCH_ARM || CPUINFO_ARCH_ARM64
|
||||
#ifdef __linux__
|
||||
if (cpuinfo_linux_cpu_to_uarch_index_map == NULL) {
|
||||
/* Special case: avoid syscall on systems with only a single type of cores */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* General case */
|
||||
/* Initializing this variable silences a MemorySanitizer error. */
|
||||
unsigned cpu = 0;
|
||||
if CPUINFO_UNLIKELY(syscall(__NR_getcpu, &cpu, NULL, NULL) != 0) {
|
||||
return default_uarch_index;
|
||||
}
|
||||
if CPUINFO_UNLIKELY((uint32_t) cpu >= cpuinfo_linux_cpu_max) {
|
||||
return default_uarch_index;
|
||||
}
|
||||
return cpuinfo_linux_cpu_to_uarch_index_map[cpu];
|
||||
#else
|
||||
/* Fallback: no API to query current core, use default uarch index. */
|
||||
return default_uarch_index;
|
||||
#endif
|
||||
#else
|
||||
/* Only ARM/ARM64 processors may include cores of different types in the same package. */
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
20
3rdparty/cpuinfo/src/arm/android/api.h
vendored
Normal file
20
3rdparty/cpuinfo/src/arm/android/api.h
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
#pragma once
|
||||
|
||||
#include <cpuinfo.h>
|
||||
#include <cpuinfo/common.h>
|
||||
#include <arm/api.h>
|
||||
#include <arm/linux/api.h>
|
||||
|
||||
enum cpuinfo_android_chipset_property {
|
||||
cpuinfo_android_chipset_property_proc_cpuinfo_hardware = 0,
|
||||
cpuinfo_android_chipset_property_ro_product_board,
|
||||
cpuinfo_android_chipset_property_ro_board_platform,
|
||||
cpuinfo_android_chipset_property_ro_mediatek_platform,
|
||||
cpuinfo_android_chipset_property_ro_arch,
|
||||
cpuinfo_android_chipset_property_ro_chipname,
|
||||
cpuinfo_android_chipset_property_ro_hardware_chipname,
|
||||
cpuinfo_android_chipset_property_max,
|
||||
};
|
||||
|
||||
CPUINFO_INTERNAL void cpuinfo_arm_android_parse_properties(
|
||||
struct cpuinfo_android_properties properties[restrict static 1]);
|
||||
67
3rdparty/cpuinfo/src/arm/android/properties.c
vendored
Normal file
67
3rdparty/cpuinfo/src/arm/android/properties.c
vendored
Normal file
@@ -0,0 +1,67 @@
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <sys/system_properties.h>
|
||||
|
||||
#include <linux/api.h>
|
||||
#include <arm/android/api.h>
|
||||
#include <arm/linux/api.h>
|
||||
#include <cpuinfo/log.h>
|
||||
|
||||
#if CPUINFO_MOCK
|
||||
#include <cpuinfo-mock.h>
|
||||
|
||||
static struct cpuinfo_mock_property* cpuinfo_mock_properties = NULL;
|
||||
|
||||
void CPUINFO_ABI cpuinfo_mock_android_properties(struct cpuinfo_mock_property* properties) {
|
||||
cpuinfo_log_info("Android properties mocking enabled");
|
||||
cpuinfo_mock_properties = properties;
|
||||
}
|
||||
|
||||
static int cpuinfo_android_property_get(const char* key, char* value) {
|
||||
if (cpuinfo_mock_properties != NULL) {
|
||||
for (const struct cpuinfo_mock_property* prop = cpuinfo_mock_properties; prop->key != NULL; prop++) {
|
||||
if (strncmp(key, prop->key, CPUINFO_BUILD_PROP_NAME_MAX) == 0) {
|
||||
strncpy(value, prop->value, CPUINFO_BUILD_PROP_VALUE_MAX);
|
||||
return (int) strnlen(prop->value, CPUINFO_BUILD_PROP_VALUE_MAX);
|
||||
}
|
||||
}
|
||||
}
|
||||
*value = '\0';
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
static inline int cpuinfo_android_property_get(const char* key, char* value) {
|
||||
return __system_property_get(key, value);
|
||||
}
|
||||
#endif
|
||||
|
||||
void cpuinfo_arm_android_parse_properties(struct cpuinfo_android_properties properties[restrict static 1]) {
|
||||
const int ro_product_board_length =
|
||||
cpuinfo_android_property_get("ro.product.board", properties->ro_product_board);
|
||||
cpuinfo_log_debug("read ro.product.board = \"%.*s\"", ro_product_board_length, properties->ro_product_board);
|
||||
|
||||
const int ro_board_platform_length =
|
||||
cpuinfo_android_property_get("ro.board.platform", properties->ro_board_platform);
|
||||
cpuinfo_log_debug("read ro.board.platform = \"%.*s\"", ro_board_platform_length, properties->ro_board_platform);
|
||||
|
||||
const int ro_mediatek_platform_length =
|
||||
cpuinfo_android_property_get("ro.mediatek.platform", properties->ro_mediatek_platform);
|
||||
cpuinfo_log_debug("read ro.mediatek.platform = \"%.*s\"",
|
||||
ro_mediatek_platform_length, properties->ro_mediatek_platform);
|
||||
|
||||
const int ro_arch_length =
|
||||
cpuinfo_android_property_get("ro.arch", properties->ro_arch);
|
||||
cpuinfo_log_debug("read ro.arch = \"%.*s\"", ro_arch_length, properties->ro_arch);
|
||||
|
||||
const int ro_chipname_length =
|
||||
cpuinfo_android_property_get("ro.chipname", properties->ro_chipname);
|
||||
cpuinfo_log_debug("read ro.chipname = \"%.*s\"", ro_chipname_length, properties->ro_chipname);
|
||||
|
||||
const int ro_hardware_chipname_length =
|
||||
cpuinfo_android_property_get("ro.hardware.chipname", properties->ro_hardware_chipname);
|
||||
cpuinfo_log_debug("read ro.hardware.chipname = \"%.*s\"", ro_hardware_chipname_length, properties->ro_hardware_chipname);
|
||||
}
|
||||
122
3rdparty/cpuinfo/src/arm/api.h
vendored
Normal file
122
3rdparty/cpuinfo/src/arm/api.h
vendored
Normal file
@@ -0,0 +1,122 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <cpuinfo.h>
|
||||
#include <cpuinfo/common.h>
|
||||
|
||||
enum cpuinfo_arm_chipset_vendor {
|
||||
cpuinfo_arm_chipset_vendor_unknown = 0,
|
||||
cpuinfo_arm_chipset_vendor_qualcomm,
|
||||
cpuinfo_arm_chipset_vendor_mediatek,
|
||||
cpuinfo_arm_chipset_vendor_samsung,
|
||||
cpuinfo_arm_chipset_vendor_hisilicon,
|
||||
cpuinfo_arm_chipset_vendor_actions,
|
||||
cpuinfo_arm_chipset_vendor_allwinner,
|
||||
cpuinfo_arm_chipset_vendor_amlogic,
|
||||
cpuinfo_arm_chipset_vendor_broadcom,
|
||||
cpuinfo_arm_chipset_vendor_lg,
|
||||
cpuinfo_arm_chipset_vendor_leadcore,
|
||||
cpuinfo_arm_chipset_vendor_marvell,
|
||||
cpuinfo_arm_chipset_vendor_mstar,
|
||||
cpuinfo_arm_chipset_vendor_novathor,
|
||||
cpuinfo_arm_chipset_vendor_nvidia,
|
||||
cpuinfo_arm_chipset_vendor_pinecone,
|
||||
cpuinfo_arm_chipset_vendor_renesas,
|
||||
cpuinfo_arm_chipset_vendor_rockchip,
|
||||
cpuinfo_arm_chipset_vendor_spreadtrum,
|
||||
cpuinfo_arm_chipset_vendor_telechips,
|
||||
cpuinfo_arm_chipset_vendor_texas_instruments,
|
||||
cpuinfo_arm_chipset_vendor_wondermedia,
|
||||
cpuinfo_arm_chipset_vendor_max,
|
||||
};
|
||||
|
||||
enum cpuinfo_arm_chipset_series {
|
||||
cpuinfo_arm_chipset_series_unknown = 0,
|
||||
cpuinfo_arm_chipset_series_qualcomm_qsd,
|
||||
cpuinfo_arm_chipset_series_qualcomm_msm,
|
||||
cpuinfo_arm_chipset_series_qualcomm_apq,
|
||||
cpuinfo_arm_chipset_series_qualcomm_snapdragon,
|
||||
cpuinfo_arm_chipset_series_mediatek_mt,
|
||||
cpuinfo_arm_chipset_series_samsung_exynos,
|
||||
cpuinfo_arm_chipset_series_hisilicon_k3v,
|
||||
cpuinfo_arm_chipset_series_hisilicon_hi,
|
||||
cpuinfo_arm_chipset_series_hisilicon_kirin,
|
||||
cpuinfo_arm_chipset_series_actions_atm,
|
||||
cpuinfo_arm_chipset_series_allwinner_a,
|
||||
cpuinfo_arm_chipset_series_amlogic_aml,
|
||||
cpuinfo_arm_chipset_series_amlogic_s,
|
||||
cpuinfo_arm_chipset_series_broadcom_bcm,
|
||||
cpuinfo_arm_chipset_series_lg_nuclun,
|
||||
cpuinfo_arm_chipset_series_leadcore_lc,
|
||||
cpuinfo_arm_chipset_series_marvell_pxa,
|
||||
cpuinfo_arm_chipset_series_mstar_6a,
|
||||
cpuinfo_arm_chipset_series_novathor_u,
|
||||
cpuinfo_arm_chipset_series_nvidia_tegra_t,
|
||||
cpuinfo_arm_chipset_series_nvidia_tegra_ap,
|
||||
cpuinfo_arm_chipset_series_nvidia_tegra_sl,
|
||||
cpuinfo_arm_chipset_series_pinecone_surge_s,
|
||||
cpuinfo_arm_chipset_series_renesas_mp,
|
||||
cpuinfo_arm_chipset_series_rockchip_rk,
|
||||
cpuinfo_arm_chipset_series_spreadtrum_sc,
|
||||
cpuinfo_arm_chipset_series_telechips_tcc,
|
||||
cpuinfo_arm_chipset_series_texas_instruments_omap,
|
||||
cpuinfo_arm_chipset_series_wondermedia_wm,
|
||||
cpuinfo_arm_chipset_series_max,
|
||||
};
|
||||
|
||||
#define CPUINFO_ARM_CHIPSET_SUFFIX_MAX 8
|
||||
|
||||
struct cpuinfo_arm_chipset {
|
||||
enum cpuinfo_arm_chipset_vendor vendor;
|
||||
enum cpuinfo_arm_chipset_series series;
|
||||
uint32_t model;
|
||||
char suffix[CPUINFO_ARM_CHIPSET_SUFFIX_MAX];
|
||||
};
|
||||
|
||||
#define CPUINFO_ARM_CHIPSET_NAME_MAX CPUINFO_PACKAGE_NAME_MAX
|
||||
|
||||
#ifndef __cplusplus
|
||||
CPUINFO_INTERNAL void cpuinfo_arm_chipset_to_string(
|
||||
const struct cpuinfo_arm_chipset chipset[restrict static 1],
|
||||
char name[restrict static CPUINFO_ARM_CHIPSET_NAME_MAX]);
|
||||
|
||||
CPUINFO_INTERNAL void cpuinfo_arm_fixup_chipset(
|
||||
struct cpuinfo_arm_chipset chipset[restrict static 1], uint32_t cores, uint32_t max_cpu_freq_max);
|
||||
|
||||
CPUINFO_INTERNAL void cpuinfo_arm_decode_vendor_uarch(
|
||||
uint32_t midr,
|
||||
#if CPUINFO_ARCH_ARM
|
||||
bool has_vfpv4,
|
||||
#endif
|
||||
enum cpuinfo_vendor vendor[restrict static 1],
|
||||
enum cpuinfo_uarch uarch[restrict static 1]);
|
||||
|
||||
CPUINFO_INTERNAL void cpuinfo_arm_decode_cache(
|
||||
enum cpuinfo_uarch uarch,
|
||||
uint32_t cluster_cores,
|
||||
uint32_t midr,
|
||||
const struct cpuinfo_arm_chipset chipset[restrict static 1],
|
||||
uint32_t cluster_id,
|
||||
uint32_t arch_version,
|
||||
struct cpuinfo_cache l1i[restrict static 1],
|
||||
struct cpuinfo_cache l1d[restrict static 1],
|
||||
struct cpuinfo_cache l2[restrict static 1],
|
||||
struct cpuinfo_cache l3[restrict static 1]);
|
||||
|
||||
CPUINFO_INTERNAL uint32_t cpuinfo_arm_compute_max_cache_size(
|
||||
const struct cpuinfo_processor processor[restrict static 1]);
|
||||
#else /* defined(__cplusplus) */
|
||||
CPUINFO_INTERNAL void cpuinfo_arm_decode_cache(
|
||||
enum cpuinfo_uarch uarch,
|
||||
uint32_t cluster_cores,
|
||||
uint32_t midr,
|
||||
const struct cpuinfo_arm_chipset chipset[1],
|
||||
uint32_t cluster_id,
|
||||
uint32_t arch_version,
|
||||
struct cpuinfo_cache l1i[1],
|
||||
struct cpuinfo_cache l1d[1],
|
||||
struct cpuinfo_cache l2[1],
|
||||
struct cpuinfo_cache l3[1]);
|
||||
#endif
|
||||
1676
3rdparty/cpuinfo/src/arm/cache.c
vendored
Normal file
1676
3rdparty/cpuinfo/src/arm/cache.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
267
3rdparty/cpuinfo/src/arm/linux/aarch32-isa.c
vendored
Normal file
267
3rdparty/cpuinfo/src/arm/linux/aarch32-isa.c
vendored
Normal file
@@ -0,0 +1,267 @@
|
||||
#include <stdint.h>
|
||||
|
||||
#if CPUINFO_MOCK
|
||||
#include <cpuinfo-mock.h>
|
||||
#endif
|
||||
#include <arm/linux/api.h>
|
||||
#include <arm/linux/cp.h>
|
||||
#include <arm/midr.h>
|
||||
#include <cpuinfo/log.h>
|
||||
|
||||
|
||||
#if CPUINFO_MOCK
|
||||
uint32_t cpuinfo_arm_fpsid = 0;
|
||||
uint32_t cpuinfo_arm_mvfr0 = 0;
|
||||
uint32_t cpuinfo_arm_wcid = 0;
|
||||
|
||||
void cpuinfo_set_fpsid(uint32_t fpsid) {
|
||||
cpuinfo_arm_fpsid = fpsid;
|
||||
}
|
||||
|
||||
void cpuinfo_set_wcid(uint32_t wcid) {
|
||||
cpuinfo_arm_wcid = wcid;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
void cpuinfo_arm_linux_decode_isa_from_proc_cpuinfo(
|
||||
uint32_t features,
|
||||
uint32_t features2,
|
||||
uint32_t midr,
|
||||
uint32_t architecture_version,
|
||||
uint32_t architecture_flags,
|
||||
const struct cpuinfo_arm_chipset chipset[restrict static 1],
|
||||
struct cpuinfo_arm_isa isa[restrict static 1])
|
||||
{
|
||||
if (architecture_version >= 8) {
|
||||
/*
|
||||
* ARMv7 code running on ARMv8: IDIV, VFP, NEON are always supported,
|
||||
* but may be not reported in /proc/cpuinfo features.
|
||||
*/
|
||||
isa->armv5e = true;
|
||||
isa->armv6 = true;
|
||||
isa->armv6k = true;
|
||||
isa->armv7 = true;
|
||||
isa->armv7mp = true;
|
||||
isa->armv8 = true;
|
||||
isa->thumb = true;
|
||||
isa->thumb2 = true;
|
||||
isa->idiv = true;
|
||||
isa->vfpv3 = true;
|
||||
isa->d32 = true;
|
||||
isa->fp16 = true;
|
||||
isa->fma = true;
|
||||
isa->neon = true;
|
||||
|
||||
/*
|
||||
* NEON FP16 compute extension and VQRDMLAH/VQRDMLSH instructions are not indicated in /proc/cpuinfo.
|
||||
* Use a MIDR-based heuristic to whitelist processors known to support it:
|
||||
* - Processors with Cortex-A55 cores
|
||||
* - Processors with Cortex-A65 cores
|
||||
* - Processors with Cortex-A75 cores
|
||||
* - Processors with Cortex-A76 cores
|
||||
* - Processors with Cortex-A77 cores
|
||||
* - Processors with Exynos M4 cores
|
||||
* - Processors with Exynos M5 cores
|
||||
* - Neoverse N1 cores
|
||||
*/
|
||||
if (chipset->series == cpuinfo_arm_chipset_series_samsung_exynos && chipset->model == 9810) {
|
||||
/* Only little cores of Exynos 9810 support FP16 & RDM */
|
||||
cpuinfo_log_warning("FP16 arithmetics and RDM disabled: only little cores in Exynos 9810 support these extensions");
|
||||
} else {
|
||||
switch (midr & (CPUINFO_ARM_MIDR_IMPLEMENTER_MASK | CPUINFO_ARM_MIDR_PART_MASK)) {
|
||||
case UINT32_C(0x4100D050): /* Cortex-A55 */
|
||||
case UINT32_C(0x4100D060): /* Cortex-A65 */
|
||||
case UINT32_C(0x4100D0B0): /* Cortex-A76 */
|
||||
case UINT32_C(0x4100D0C0): /* Neoverse N1 */
|
||||
case UINT32_C(0x4100D0D0): /* Cortex-A77 */
|
||||
case UINT32_C(0x4100D0E0): /* Cortex-A76AE */
|
||||
case UINT32_C(0x4800D400): /* Cortex-A76 (HiSilicon) */
|
||||
case UINT32_C(0x51008020): /* Kryo 385 Gold (Cortex-A75) */
|
||||
case UINT32_C(0x51008030): /* Kryo 385 Silver (Cortex-A55) */
|
||||
case UINT32_C(0x51008040): /* Kryo 485 Gold (Cortex-A76) */
|
||||
case UINT32_C(0x51008050): /* Kryo 485 Silver (Cortex-A55) */
|
||||
case UINT32_C(0x53000030): /* Exynos M4 */
|
||||
case UINT32_C(0x53000040): /* Exynos M5 */
|
||||
isa->fp16arith = true;
|
||||
isa->rdm = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* NEON VDOT instructions are not indicated in /proc/cpuinfo.
|
||||
* Use a MIDR-based heuristic to whitelist processors known to support it.
|
||||
*/
|
||||
switch (midr & (CPUINFO_ARM_MIDR_IMPLEMENTER_MASK | CPUINFO_ARM_MIDR_PART_MASK)) {
|
||||
case UINT32_C(0x4100D0B0): /* Cortex-A76 */
|
||||
case UINT32_C(0x4100D0D0): /* Cortex-A77 */
|
||||
case UINT32_C(0x4100D0E0): /* Cortex-A76AE */
|
||||
case UINT32_C(0x4800D400): /* Cortex-A76 (HiSilicon) */
|
||||
case UINT32_C(0x51008040): /* Kryo 485 Gold (Cortex-A76) */
|
||||
case UINT32_C(0x51008050): /* Kryo 485 Silver (Cortex-A55) */
|
||||
case UINT32_C(0x53000030): /* Exynos-M4 */
|
||||
case UINT32_C(0x53000040): /* Exynos-M5 */
|
||||
isa->dot = true;
|
||||
break;
|
||||
case UINT32_C(0x4100D050): /* Cortex A55: revision 1 or later only */
|
||||
isa->dot = !!(midr_get_variant(midr) >= 1);
|
||||
break;
|
||||
case UINT32_C(0x4100D0A0): /* Cortex A75: revision 2 or later only */
|
||||
isa->dot = !!(midr_get_variant(midr) >= 2);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
/* ARMv7 or lower: use feature flags to detect optional features */
|
||||
|
||||
/*
|
||||
* ARM11 (ARM 1136/1156/1176/11 MPCore) processors can report v7 architecture
|
||||
* even though they support only ARMv6 instruction set.
|
||||
*/
|
||||
if (architecture_version == 7 && midr_is_arm11(midr)) {
|
||||
cpuinfo_log_warning("kernel-reported architecture ARMv7 ignored due to mismatch with processor microarchitecture (ARM11)");
|
||||
architecture_version = 6;
|
||||
}
|
||||
|
||||
if (architecture_version < 7) {
|
||||
const uint32_t armv7_features_mask = CPUINFO_ARM_LINUX_FEATURE_VFPV3 | CPUINFO_ARM_LINUX_FEATURE_VFPV3D16 | CPUINFO_ARM_LINUX_FEATURE_VFPD32 |
|
||||
CPUINFO_ARM_LINUX_FEATURE_VFPV4 | CPUINFO_ARM_LINUX_FEATURE_NEON | CPUINFO_ARM_LINUX_FEATURE_IDIVT | CPUINFO_ARM_LINUX_FEATURE_IDIVA;
|
||||
if (features & armv7_features_mask) {
|
||||
architecture_version = 7;
|
||||
}
|
||||
}
|
||||
if ((architecture_version >= 6) || (features & CPUINFO_ARM_LINUX_FEATURE_EDSP) || (architecture_flags & CPUINFO_ARM_LINUX_ARCH_E)) {
|
||||
isa->armv5e = true;
|
||||
}
|
||||
if (architecture_version >= 6) {
|
||||
isa->armv6 = true;
|
||||
}
|
||||
if (architecture_version >= 7) {
|
||||
isa->armv6k = true;
|
||||
isa->armv7 = true;
|
||||
|
||||
/*
|
||||
* ARMv7 MP extension (PLDW instruction) is not indicated in /proc/cpuinfo.
|
||||
* Use heuristic list of supporting processors:
|
||||
* - Processors supporting UDIV/SDIV instructions ("idiva" + "idivt" features in /proc/cpuinfo)
|
||||
* - Cortex-A5
|
||||
* - Cortex-A9
|
||||
* - Dual-Core Scorpion
|
||||
* - Krait (supports UDIV/SDIV, but kernels may not report it in /proc/cpuinfo)
|
||||
*
|
||||
* TODO: check single-core Qualcomm Scorpion.
|
||||
*/
|
||||
switch (midr & (CPUINFO_ARM_MIDR_IMPLEMENTER_MASK | CPUINFO_ARM_MIDR_PART_MASK)) {
|
||||
case UINT32_C(0x4100C050): /* Cortex-A5 */
|
||||
case UINT32_C(0x4100C090): /* Cortex-A9 */
|
||||
case UINT32_C(0x510002D0): /* Scorpion (dual-core) */
|
||||
case UINT32_C(0x510004D0): /* Krait (dual-core) */
|
||||
case UINT32_C(0x510006F0): /* Krait (quad-core) */
|
||||
isa->armv7mp = true;
|
||||
break;
|
||||
default:
|
||||
/* In practice IDIV instruction implies ARMv7+MP ISA */
|
||||
isa->armv7mp = (features & CPUINFO_ARM_LINUX_FEATURE_IDIV) == CPUINFO_ARM_LINUX_FEATURE_IDIV;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (features & CPUINFO_ARM_LINUX_FEATURE_IWMMXT) {
|
||||
const uint32_t wcid = read_wcid();
|
||||
cpuinfo_log_debug("WCID = 0x%08"PRIx32, wcid);
|
||||
const uint32_t coprocessor_type = (wcid >> 8) & UINT32_C(0xFF);
|
||||
if (coprocessor_type >= 0x10) {
|
||||
isa->wmmx = true;
|
||||
if (coprocessor_type >= 0x20) {
|
||||
isa->wmmx2 = true;
|
||||
}
|
||||
} else {
|
||||
cpuinfo_log_warning("WMMX ISA disabled: OS reported iwmmxt feature, "
|
||||
"but WCID coprocessor type 0x%"PRIx32" indicates no WMMX support",
|
||||
coprocessor_type);
|
||||
}
|
||||
}
|
||||
|
||||
if ((features & CPUINFO_ARM_LINUX_FEATURE_THUMB) || (architecture_flags & CPUINFO_ARM_LINUX_ARCH_T)) {
|
||||
isa->thumb = true;
|
||||
|
||||
/*
|
||||
* There is no separate feature flag for Thumb 2.
|
||||
* All ARMv7 processors and ARM 1156 support Thumb 2.
|
||||
*/
|
||||
if (architecture_version >= 7 || midr_is_arm1156(midr)) {
|
||||
isa->thumb2 = true;
|
||||
}
|
||||
}
|
||||
if (features & CPUINFO_ARM_LINUX_FEATURE_THUMBEE) {
|
||||
isa->thumbee = true;
|
||||
}
|
||||
if ((features & CPUINFO_ARM_LINUX_FEATURE_JAVA) || (architecture_flags & CPUINFO_ARM_LINUX_ARCH_J)) {
|
||||
isa->jazelle = true;
|
||||
}
|
||||
|
||||
/* Qualcomm Krait may have buggy kernel configuration that doesn't report IDIV */
|
||||
if ((features & CPUINFO_ARM_LINUX_FEATURE_IDIV) == CPUINFO_ARM_LINUX_FEATURE_IDIV || midr_is_krait(midr)) {
|
||||
isa->idiv = true;
|
||||
}
|
||||
|
||||
const uint32_t vfp_mask = \
|
||||
CPUINFO_ARM_LINUX_FEATURE_VFP | CPUINFO_ARM_LINUX_FEATURE_VFPV3 | CPUINFO_ARM_LINUX_FEATURE_VFPV3D16 | \
|
||||
CPUINFO_ARM_LINUX_FEATURE_VFPD32 | CPUINFO_ARM_LINUX_FEATURE_VFPV4 | CPUINFO_ARM_LINUX_FEATURE_NEON;
|
||||
if (features & vfp_mask) {
|
||||
const uint32_t vfpv3_mask = CPUINFO_ARM_LINUX_FEATURE_VFPV3 | CPUINFO_ARM_LINUX_FEATURE_VFPV3D16 | \
|
||||
CPUINFO_ARM_LINUX_FEATURE_VFPD32 | CPUINFO_ARM_LINUX_FEATURE_VFPV4 | CPUINFO_ARM_LINUX_FEATURE_NEON;
|
||||
if ((architecture_version >= 7) || (features & vfpv3_mask)) {
|
||||
isa->vfpv3 = true;
|
||||
|
||||
const uint32_t d32_mask = CPUINFO_ARM_LINUX_FEATURE_VFPD32 | CPUINFO_ARM_LINUX_FEATURE_NEON;
|
||||
if (features & d32_mask) {
|
||||
isa->d32 = true;
|
||||
}
|
||||
} else {
|
||||
#if defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_8A__) || defined(__ARM_ARCH) && (__ARM_ARCH >= 7)
|
||||
isa->vfpv3 = true;
|
||||
#else
|
||||
const uint32_t fpsid = read_fpsid();
|
||||
cpuinfo_log_debug("FPSID = 0x%08"PRIx32, fpsid);
|
||||
const uint32_t subarchitecture = (fpsid >> 16) & UINT32_C(0x7F);
|
||||
if (subarchitecture >= 0x01) {
|
||||
isa->vfpv2 = true;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
if (features & CPUINFO_ARM_LINUX_FEATURE_NEON) {
|
||||
isa->neon = true;
|
||||
}
|
||||
|
||||
/*
|
||||
* There is no separate feature flag for FP16 support.
|
||||
* VFPv4 implies VFPv3-FP16 support (and in practice, NEON-HP as well).
|
||||
* Additionally, ARM Cortex-A9 and Qualcomm Scorpion support FP16.
|
||||
*/
|
||||
if ((features & CPUINFO_ARM_LINUX_FEATURE_VFPV4) || midr_is_cortex_a9(midr) || midr_is_scorpion(midr)) {
|
||||
isa->fp16 = true;
|
||||
}
|
||||
|
||||
if (features & CPUINFO_ARM_LINUX_FEATURE_VFPV4) {
|
||||
isa->fma = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (features2 & CPUINFO_ARM_LINUX_FEATURE2_AES) {
|
||||
isa->aes = true;
|
||||
}
|
||||
if (features2 & CPUINFO_ARM_LINUX_FEATURE2_PMULL) {
|
||||
isa->pmull = true;
|
||||
}
|
||||
if (features2 & CPUINFO_ARM_LINUX_FEATURE2_SHA1) {
|
||||
isa->sha1 = true;
|
||||
}
|
||||
if (features2 & CPUINFO_ARM_LINUX_FEATURE2_SHA2) {
|
||||
isa->sha2 = true;
|
||||
}
|
||||
if (features2 & CPUINFO_ARM_LINUX_FEATURE2_CRC32) {
|
||||
isa->crc32 = true;
|
||||
}
|
||||
}
|
||||
127
3rdparty/cpuinfo/src/arm/linux/aarch64-isa.c
vendored
Normal file
127
3rdparty/cpuinfo/src/arm/linux/aarch64-isa.c
vendored
Normal file
@@ -0,0 +1,127 @@
|
||||
#include <stdint.h>
|
||||
|
||||
#include <arm/linux/api.h>
|
||||
#include <cpuinfo/log.h>
|
||||
|
||||
|
||||
void cpuinfo_arm64_linux_decode_isa_from_proc_cpuinfo(
|
||||
uint32_t features,
|
||||
uint32_t features2,
|
||||
uint32_t midr,
|
||||
const struct cpuinfo_arm_chipset chipset[restrict static 1],
|
||||
struct cpuinfo_arm_isa isa[restrict static 1])
|
||||
{
|
||||
if (features & CPUINFO_ARM_LINUX_FEATURE_AES) {
|
||||
isa->aes = true;
|
||||
}
|
||||
if (features & CPUINFO_ARM_LINUX_FEATURE_PMULL) {
|
||||
isa->pmull = true;
|
||||
}
|
||||
if (features & CPUINFO_ARM_LINUX_FEATURE_SHA1) {
|
||||
isa->sha1 = true;
|
||||
}
|
||||
if (features & CPUINFO_ARM_LINUX_FEATURE_SHA2) {
|
||||
isa->sha2 = true;
|
||||
}
|
||||
if (features & CPUINFO_ARM_LINUX_FEATURE_CRC32) {
|
||||
isa->crc32 = true;
|
||||
}
|
||||
if (features & CPUINFO_ARM_LINUX_FEATURE_ATOMICS) {
|
||||
isa->atomics = true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Some phones ship with an old kernel configuration that doesn't report NEON FP16 compute extension and SQRDMLAH/SQRDMLSH/UQRDMLAH/UQRDMLSH instructions.
|
||||
* Use a MIDR-based heuristic to whitelist processors known to support it:
|
||||
* - Processors with Cortex-A55 cores
|
||||
* - Processors with Cortex-A65 cores
|
||||
* - Processors with Cortex-A75 cores
|
||||
* - Processors with Cortex-A76 cores
|
||||
* - Processors with Cortex-A77 cores
|
||||
* - Processors with Exynos M4 cores
|
||||
* - Processors with Exynos M5 cores
|
||||
* - Neoverse N1 cores
|
||||
*/
|
||||
if (chipset->series == cpuinfo_arm_chipset_series_samsung_exynos && chipset->model == 9810) {
|
||||
/* Exynos 9810 reports that it supports FP16 compute, but in fact only little cores do */
|
||||
cpuinfo_log_warning("FP16 arithmetics and RDM disabled: only little cores in Exynos 9810 support these extensions");
|
||||
} else {
|
||||
const uint32_t fp16arith_mask = CPUINFO_ARM_LINUX_FEATURE_FPHP | CPUINFO_ARM_LINUX_FEATURE_ASIMDHP;
|
||||
switch (midr & (CPUINFO_ARM_MIDR_IMPLEMENTER_MASK | CPUINFO_ARM_MIDR_PART_MASK)) {
|
||||
case UINT32_C(0x4100D050): /* Cortex-A55 */
|
||||
case UINT32_C(0x4100D060): /* Cortex-A65 */
|
||||
case UINT32_C(0x4100D0B0): /* Cortex-A76 */
|
||||
case UINT32_C(0x4100D0C0): /* Neoverse N1 */
|
||||
case UINT32_C(0x4100D0D0): /* Cortex-A77 */
|
||||
case UINT32_C(0x4100D0E0): /* Cortex-A76AE */
|
||||
case UINT32_C(0x4800D400): /* Cortex-A76 (HiSilicon) */
|
||||
case UINT32_C(0x51008020): /* Kryo 385 Gold (Cortex-A75) */
|
||||
case UINT32_C(0x51008030): /* Kryo 385 Silver (Cortex-A55) */
|
||||
case UINT32_C(0x51008040): /* Kryo 485 Gold (Cortex-A76) */
|
||||
case UINT32_C(0x51008050): /* Kryo 485 Silver (Cortex-A55) */
|
||||
case UINT32_C(0x53000030): /* Exynos M4 */
|
||||
case UINT32_C(0x53000040): /* Exynos M5 */
|
||||
isa->fp16arith = true;
|
||||
isa->rdm = true;
|
||||
break;
|
||||
default:
|
||||
if ((features & fp16arith_mask) == fp16arith_mask) {
|
||||
isa->fp16arith = true;
|
||||
} else if (features & CPUINFO_ARM_LINUX_FEATURE_FPHP) {
|
||||
cpuinfo_log_warning("FP16 arithmetics disabled: detected support only for scalar operations");
|
||||
} else if (features & CPUINFO_ARM_LINUX_FEATURE_ASIMDHP) {
|
||||
cpuinfo_log_warning("FP16 arithmetics disabled: detected support only for SIMD operations");
|
||||
}
|
||||
if (features & CPUINFO_ARM_LINUX_FEATURE_ASIMDRDM) {
|
||||
isa->rdm = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Many phones ship with an old kernel configuration that doesn't report UDOT/SDOT instructions.
|
||||
* Use a MIDR-based heuristic to whitelist processors known to support it.
|
||||
*/
|
||||
switch (midr & (CPUINFO_ARM_MIDR_IMPLEMENTER_MASK | CPUINFO_ARM_MIDR_PART_MASK)) {
|
||||
case UINT32_C(0x4100D060): /* Cortex-A65 */
|
||||
case UINT32_C(0x4100D0B0): /* Cortex-A76 */
|
||||
case UINT32_C(0x4100D0C0): /* Neoverse N1 */
|
||||
case UINT32_C(0x4100D0D0): /* Cortex-A77 */
|
||||
case UINT32_C(0x4100D0E0): /* Cortex-A76AE */
|
||||
case UINT32_C(0x4100D4A0): /* Neoverse E1 */
|
||||
case UINT32_C(0x4800D400): /* Cortex-A76 (HiSilicon) */
|
||||
case UINT32_C(0x51008040): /* Kryo 485 Gold (Cortex-A76) */
|
||||
case UINT32_C(0x51008050): /* Kryo 485 Silver (Cortex-A55) */
|
||||
case UINT32_C(0x53000030): /* Exynos-M4 */
|
||||
case UINT32_C(0x53000040): /* Exynos-M5 */
|
||||
isa->dot = true;
|
||||
break;
|
||||
case UINT32_C(0x4100D050): /* Cortex A55: revision 1 or later only */
|
||||
isa->dot = !!(midr_get_variant(midr) >= 1);
|
||||
break;
|
||||
case UINT32_C(0x4100D0A0): /* Cortex A75: revision 2 or later only */
|
||||
isa->dot = !!(midr_get_variant(midr) >= 2);
|
||||
break;
|
||||
default:
|
||||
if (features & CPUINFO_ARM_LINUX_FEATURE_ASIMDDP) {
|
||||
isa->dot = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (features & CPUINFO_ARM_LINUX_FEATURE_JSCVT) {
|
||||
isa->jscvt = true;
|
||||
}
|
||||
if (features & CPUINFO_ARM_LINUX_FEATURE_JSCVT) {
|
||||
isa->jscvt = true;
|
||||
}
|
||||
if (features & CPUINFO_ARM_LINUX_FEATURE_FCMA) {
|
||||
isa->fcma = true;
|
||||
}
|
||||
if (features & CPUINFO_ARM_LINUX_FEATURE_SVE) {
|
||||
isa->sve = true;
|
||||
}
|
||||
if (features2 & CPUINFO_ARM_LINUX_FEATURE2_SVE2) {
|
||||
isa->sve2 = true;
|
||||
}
|
||||
}
|
||||
384
3rdparty/cpuinfo/src/arm/linux/api.h
vendored
Normal file
384
3rdparty/cpuinfo/src/arm/linux/api.h
vendored
Normal file
@@ -0,0 +1,384 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <cpuinfo.h>
|
||||
#include <cpuinfo/common.h>
|
||||
#include <arm/midr.h>
|
||||
#include <arm/api.h>
|
||||
#include <linux/api.h>
|
||||
|
||||
/* No hard limit in the kernel, maximum length observed on non-rogue kernels is 64 */
|
||||
#define CPUINFO_HARDWARE_VALUE_MAX 64
|
||||
/* No hard limit in the kernel, maximum length on Raspberry Pi is 8. Add 1 symbol to detect overly large revision strings */
|
||||
#define CPUINFO_REVISION_VALUE_MAX 9
|
||||
|
||||
#ifdef __ANDROID__
|
||||
/* As per include/sys/system_properties.h in Android NDK */
|
||||
#define CPUINFO_BUILD_PROP_NAME_MAX 32
|
||||
#define CPUINFO_BUILD_PROP_VALUE_MAX 92
|
||||
|
||||
struct cpuinfo_android_properties {
|
||||
char proc_cpuinfo_hardware[CPUINFO_HARDWARE_VALUE_MAX];
|
||||
char ro_product_board[CPUINFO_BUILD_PROP_VALUE_MAX];
|
||||
char ro_board_platform[CPUINFO_BUILD_PROP_VALUE_MAX];
|
||||
char ro_mediatek_platform[CPUINFO_BUILD_PROP_VALUE_MAX];
|
||||
char ro_arch[CPUINFO_BUILD_PROP_VALUE_MAX];
|
||||
char ro_chipname[CPUINFO_BUILD_PROP_VALUE_MAX];
|
||||
char ro_hardware_chipname[CPUINFO_BUILD_PROP_VALUE_MAX];
|
||||
};
|
||||
#endif
|
||||
|
||||
#define CPUINFO_ARM_LINUX_ARCH_T UINT32_C(0x00000001)
|
||||
#define CPUINFO_ARM_LINUX_ARCH_E UINT32_C(0x00000002)
|
||||
#define CPUINFO_ARM_LINUX_ARCH_J UINT32_C(0x00000004)
|
||||
|
||||
#define CPUINFO_ARM_LINUX_ARCH_TE UINT32_C(0x00000003)
|
||||
#define CPUINFO_ARM_LINUX_ARCH_TEJ UINT32_C(0x00000007)
|
||||
|
||||
struct cpuinfo_arm_linux_proc_cpuinfo_cache {
|
||||
uint32_t i_size;
|
||||
uint32_t i_assoc;
|
||||
uint32_t i_line_length;
|
||||
uint32_t i_sets;
|
||||
uint32_t d_size;
|
||||
uint32_t d_assoc;
|
||||
uint32_t d_line_length;
|
||||
uint32_t d_sets;
|
||||
};
|
||||
|
||||
#if CPUINFO_ARCH_ARM
|
||||
/* arch/arm/include/uapi/asm/hwcap.h */
|
||||
|
||||
#define CPUINFO_ARM_LINUX_FEATURE_SWP UINT32_C(0x00000001)
|
||||
#define CPUINFO_ARM_LINUX_FEATURE_HALF UINT32_C(0x00000002)
|
||||
#define CPUINFO_ARM_LINUX_FEATURE_THUMB UINT32_C(0x00000004)
|
||||
#define CPUINFO_ARM_LINUX_FEATURE_26BIT UINT32_C(0x00000008)
|
||||
#define CPUINFO_ARM_LINUX_FEATURE_FASTMULT UINT32_C(0x00000010)
|
||||
#define CPUINFO_ARM_LINUX_FEATURE_FPA UINT32_C(0x00000020)
|
||||
#define CPUINFO_ARM_LINUX_FEATURE_VFP UINT32_C(0x00000040)
|
||||
#define CPUINFO_ARM_LINUX_FEATURE_EDSP UINT32_C(0x00000080)
|
||||
#define CPUINFO_ARM_LINUX_FEATURE_JAVA UINT32_C(0x00000100)
|
||||
#define CPUINFO_ARM_LINUX_FEATURE_IWMMXT UINT32_C(0x00000200)
|
||||
#define CPUINFO_ARM_LINUX_FEATURE_CRUNCH UINT32_C(0x00000400)
|
||||
#define CPUINFO_ARM_LINUX_FEATURE_THUMBEE UINT32_C(0x00000800)
|
||||
#define CPUINFO_ARM_LINUX_FEATURE_NEON UINT32_C(0x00001000)
|
||||
#define CPUINFO_ARM_LINUX_FEATURE_VFPV3 UINT32_C(0x00002000)
|
||||
#define CPUINFO_ARM_LINUX_FEATURE_VFPV3D16 UINT32_C(0x00004000) /* Also set for VFPv4 with 16 double-precision registers */
|
||||
#define CPUINFO_ARM_LINUX_FEATURE_TLS UINT32_C(0x00008000)
|
||||
#define CPUINFO_ARM_LINUX_FEATURE_VFPV4 UINT32_C(0x00010000)
|
||||
#define CPUINFO_ARM_LINUX_FEATURE_IDIVA UINT32_C(0x00020000)
|
||||
#define CPUINFO_ARM_LINUX_FEATURE_IDIVT UINT32_C(0x00040000)
|
||||
#define CPUINFO_ARM_LINUX_FEATURE_IDIV UINT32_C(0x00060000)
|
||||
#define CPUINFO_ARM_LINUX_FEATURE_VFPD32 UINT32_C(0x00080000)
|
||||
#define CPUINFO_ARM_LINUX_FEATURE_LPAE UINT32_C(0x00100000)
|
||||
#define CPUINFO_ARM_LINUX_FEATURE_EVTSTRM UINT32_C(0x00200000)
|
||||
|
||||
#define CPUINFO_ARM_LINUX_FEATURE2_AES UINT32_C(0x00000001)
|
||||
#define CPUINFO_ARM_LINUX_FEATURE2_PMULL UINT32_C(0x00000002)
|
||||
#define CPUINFO_ARM_LINUX_FEATURE2_SHA1 UINT32_C(0x00000004)
|
||||
#define CPUINFO_ARM_LINUX_FEATURE2_SHA2 UINT32_C(0x00000008)
|
||||
#define CPUINFO_ARM_LINUX_FEATURE2_CRC32 UINT32_C(0x00000010)
|
||||
#elif CPUINFO_ARCH_ARM64
|
||||
/* arch/arm64/include/uapi/asm/hwcap.h */
|
||||
#define CPUINFO_ARM_LINUX_FEATURE_FP UINT32_C(0x00000001)
|
||||
#define CPUINFO_ARM_LINUX_FEATURE_ASIMD UINT32_C(0x00000002)
|
||||
#define CPUINFO_ARM_LINUX_FEATURE_EVTSTRM UINT32_C(0x00000004)
|
||||
#define CPUINFO_ARM_LINUX_FEATURE_AES UINT32_C(0x00000008)
|
||||
#define CPUINFO_ARM_LINUX_FEATURE_PMULL UINT32_C(0x00000010)
|
||||
#define CPUINFO_ARM_LINUX_FEATURE_SHA1 UINT32_C(0x00000020)
|
||||
#define CPUINFO_ARM_LINUX_FEATURE_SHA2 UINT32_C(0x00000040)
|
||||
#define CPUINFO_ARM_LINUX_FEATURE_CRC32 UINT32_C(0x00000080)
|
||||
#define CPUINFO_ARM_LINUX_FEATURE_ATOMICS UINT32_C(0x00000100)
|
||||
#define CPUINFO_ARM_LINUX_FEATURE_FPHP UINT32_C(0x00000200)
|
||||
#define CPUINFO_ARM_LINUX_FEATURE_ASIMDHP UINT32_C(0x00000400)
|
||||
#define CPUINFO_ARM_LINUX_FEATURE_CPUID UINT32_C(0x00000800)
|
||||
#define CPUINFO_ARM_LINUX_FEATURE_ASIMDRDM UINT32_C(0x00001000)
|
||||
#define CPUINFO_ARM_LINUX_FEATURE_JSCVT UINT32_C(0x00002000)
|
||||
#define CPUINFO_ARM_LINUX_FEATURE_FCMA UINT32_C(0x00004000)
|
||||
#define CPUINFO_ARM_LINUX_FEATURE_LRCPC UINT32_C(0x00008000)
|
||||
#define CPUINFO_ARM_LINUX_FEATURE_DCPOP UINT32_C(0x00010000)
|
||||
#define CPUINFO_ARM_LINUX_FEATURE_SHA3 UINT32_C(0x00020000)
|
||||
#define CPUINFO_ARM_LINUX_FEATURE_SM3 UINT32_C(0x00040000)
|
||||
#define CPUINFO_ARM_LINUX_FEATURE_SM4 UINT32_C(0x00080000)
|
||||
#define CPUINFO_ARM_LINUX_FEATURE_ASIMDDP UINT32_C(0x00100000)
|
||||
#define CPUINFO_ARM_LINUX_FEATURE_SHA512 UINT32_C(0x00200000)
|
||||
#define CPUINFO_ARM_LINUX_FEATURE_SVE UINT32_C(0x00400000)
|
||||
#define CPUINFO_ARM_LINUX_FEATURE_ASIMDFHM UINT32_C(0x00800000)
|
||||
#define CPUINFO_ARM_LINUX_FEATURE_DIT UINT32_C(0x01000000)
|
||||
#define CPUINFO_ARM_LINUX_FEATURE_USCAT UINT32_C(0x02000000)
|
||||
#define CPUINFO_ARM_LINUX_FEATURE_ILRCPC UINT32_C(0x04000000)
|
||||
#define CPUINFO_ARM_LINUX_FEATURE_FLAGM UINT32_C(0x08000000)
|
||||
#define CPUINFO_ARM_LINUX_FEATURE_SSBS UINT32_C(0x10000000)
|
||||
#define CPUINFO_ARM_LINUX_FEATURE_SB UINT32_C(0x20000000)
|
||||
#define CPUINFO_ARM_LINUX_FEATURE_PACA UINT32_C(0x40000000)
|
||||
#define CPUINFO_ARM_LINUX_FEATURE_PACG UINT32_C(0x80000000)
|
||||
|
||||
#define CPUINFO_ARM_LINUX_FEATURE2_DCPODP UINT32_C(0x00000001)
|
||||
#define CPUINFO_ARM_LINUX_FEATURE2_SVE2 UINT32_C(0x00000002)
|
||||
#define CPUINFO_ARM_LINUX_FEATURE2_SVEAES UINT32_C(0x00000004)
|
||||
#define CPUINFO_ARM_LINUX_FEATURE2_SVEPMULL UINT32_C(0x00000008)
|
||||
#define CPUINFO_ARM_LINUX_FEATURE2_SVEBITPERM UINT32_C(0x00000010)
|
||||
#define CPUINFO_ARM_LINUX_FEATURE2_SVESHA3 UINT32_C(0x00000020)
|
||||
#define CPUINFO_ARM_LINUX_FEATURE2_SVESM4 UINT32_C(0x00000040)
|
||||
#define CPUINFO_ARM_LINUX_FEATURE2_FLAGM2 UINT32_C(0x00000080)
|
||||
#define CPUINFO_ARM_LINUX_FEATURE2_FRINT UINT32_C(0x00000100)
|
||||
#define CPUINFO_ARM_LINUX_FEATURE2_SVEI8MM UINT32_C(0x00000200)
|
||||
#define CPUINFO_ARM_LINUX_FEATURE2_SVEF32MM UINT32_C(0x00000400)
|
||||
#define CPUINFO_ARM_LINUX_FEATURE2_SVEF64MM UINT32_C(0x00000800)
|
||||
#define CPUINFO_ARM_LINUX_FEATURE2_SVEBF16 UINT32_C(0x00001000)
|
||||
#define CPUINFO_ARM_LINUX_FEATURE2_I8MM UINT32_C(0x00002000)
|
||||
#define CPUINFO_ARM_LINUX_FEATURE2_BF16 UINT32_C(0x00004000)
|
||||
#define CPUINFO_ARM_LINUX_FEATURE2_DGH UINT32_C(0x00008000)
|
||||
#define CPUINFO_ARM_LINUX_FEATURE2_RNG UINT32_C(0x00010000)
|
||||
#define CPUINFO_ARM_LINUX_FEATURE2_BTI UINT32_C(0x00020000)
|
||||
#endif
|
||||
|
||||
#define CPUINFO_ARM_LINUX_VALID_ARCHITECTURE UINT32_C(0x00010000)
|
||||
#define CPUINFO_ARM_LINUX_VALID_IMPLEMENTER UINT32_C(0x00020000)
|
||||
#define CPUINFO_ARM_LINUX_VALID_VARIANT UINT32_C(0x00040000)
|
||||
#define CPUINFO_ARM_LINUX_VALID_PART UINT32_C(0x00080000)
|
||||
#define CPUINFO_ARM_LINUX_VALID_REVISION UINT32_C(0x00100000)
|
||||
#define CPUINFO_ARM_LINUX_VALID_PROCESSOR UINT32_C(0x00200000)
|
||||
#define CPUINFO_ARM_LINUX_VALID_FEATURES UINT32_C(0x00400000)
|
||||
#if CPUINFO_ARCH_ARM
|
||||
#define CPUINFO_ARM_LINUX_VALID_ICACHE_SIZE UINT32_C(0x01000000)
|
||||
#define CPUINFO_ARM_LINUX_VALID_ICACHE_SETS UINT32_C(0x02000000)
|
||||
#define CPUINFO_ARM_LINUX_VALID_ICACHE_WAYS UINT32_C(0x04000000)
|
||||
#define CPUINFO_ARM_LINUX_VALID_ICACHE_LINE UINT32_C(0x08000000)
|
||||
#define CPUINFO_ARM_LINUX_VALID_DCACHE_SIZE UINT32_C(0x10000000)
|
||||
#define CPUINFO_ARM_LINUX_VALID_DCACHE_SETS UINT32_C(0x20000000)
|
||||
#define CPUINFO_ARM_LINUX_VALID_DCACHE_WAYS UINT32_C(0x40000000)
|
||||
#define CPUINFO_ARM_LINUX_VALID_DCACHE_LINE UINT32_C(0x80000000)
|
||||
#endif
|
||||
|
||||
#define CPUINFO_ARM_LINUX_VALID_INFO UINT32_C(0x007F0000)
|
||||
#define CPUINFO_ARM_LINUX_VALID_MIDR UINT32_C(0x003F0000)
|
||||
#if CPUINFO_ARCH_ARM
|
||||
#define CPUINFO_ARM_LINUX_VALID_ICACHE UINT32_C(0x0F000000)
|
||||
#define CPUINFO_ARM_LINUX_VALID_DCACHE UINT32_C(0xF0000000)
|
||||
#define CPUINFO_ARM_LINUX_VALID_CACHE_LINE UINT32_C(0x88000000)
|
||||
#endif
|
||||
|
||||
struct cpuinfo_arm_linux_processor {
|
||||
uint32_t architecture_version;
|
||||
#if CPUINFO_ARCH_ARM
|
||||
uint32_t architecture_flags;
|
||||
struct cpuinfo_arm_linux_proc_cpuinfo_cache proc_cpuinfo_cache;
|
||||
#endif
|
||||
uint32_t features;
|
||||
uint32_t features2;
|
||||
/**
|
||||
* Main ID Register value.
|
||||
*/
|
||||
uint32_t midr;
|
||||
enum cpuinfo_vendor vendor;
|
||||
enum cpuinfo_uarch uarch;
|
||||
uint32_t uarch_index;
|
||||
/**
|
||||
* ID of the physical package which includes this logical processor.
|
||||
* The value is parsed from /sys/devices/system/cpu/cpu<N>/topology/physical_package_id
|
||||
*/
|
||||
uint32_t package_id;
|
||||
/**
|
||||
* Minimum processor ID on the package which includes this logical processor.
|
||||
* This value can serve as an ID for the cluster of logical processors: it is the
|
||||
* same for all logical processors on the same package.
|
||||
*/
|
||||
uint32_t package_leader_id;
|
||||
/**
|
||||
* Number of logical processors in the package.
|
||||
*/
|
||||
uint32_t package_processor_count;
|
||||
/**
|
||||
* Maximum frequency, in kHZ.
|
||||
* The value is parsed from /sys/devices/system/cpu/cpu<N>/cpufreq/cpuinfo_max_freq
|
||||
* If failed to read or parse the file, the value is 0.
|
||||
*/
|
||||
uint32_t max_frequency;
|
||||
/**
|
||||
* Minimum frequency, in kHZ.
|
||||
* The value is parsed from /sys/devices/system/cpu/cpu<N>/cpufreq/cpuinfo_min_freq
|
||||
* If failed to read or parse the file, the value is 0.
|
||||
*/
|
||||
uint32_t min_frequency;
|
||||
/** Linux processor ID */
|
||||
uint32_t system_processor_id;
|
||||
uint32_t flags;
|
||||
};
|
||||
|
||||
struct cpuinfo_arm_linux_cluster {
|
||||
uint32_t processor_id_min;
|
||||
uint32_t processor_id_max;
|
||||
};
|
||||
|
||||
/* Returns true if the two processors do belong to the same cluster */
|
||||
static inline bool cpuinfo_arm_linux_processor_equals(
|
||||
struct cpuinfo_arm_linux_processor processor_i[restrict static 1],
|
||||
struct cpuinfo_arm_linux_processor processor_j[restrict static 1])
|
||||
{
|
||||
const uint32_t joint_flags = processor_i->flags & processor_j->flags;
|
||||
|
||||
bool same_max_frequency = false;
|
||||
if (joint_flags & CPUINFO_LINUX_FLAG_MAX_FREQUENCY) {
|
||||
if (processor_i->max_frequency != processor_j->max_frequency) {
|
||||
return false;
|
||||
} else {
|
||||
same_max_frequency = true;
|
||||
}
|
||||
}
|
||||
|
||||
bool same_min_frequency = false;
|
||||
if (joint_flags & CPUINFO_LINUX_FLAG_MIN_FREQUENCY) {
|
||||
if (processor_i->min_frequency != processor_j->min_frequency) {
|
||||
return false;
|
||||
} else {
|
||||
same_min_frequency = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ((joint_flags & CPUINFO_ARM_LINUX_VALID_MIDR) == CPUINFO_ARM_LINUX_VALID_MIDR) {
|
||||
if (processor_i->midr == processor_j->midr) {
|
||||
if (midr_is_cortex_a53(processor_i->midr)) {
|
||||
return same_min_frequency & same_max_frequency;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return same_max_frequency && same_min_frequency;
|
||||
}
|
||||
|
||||
/* Returns true if the two processors certainly don't belong to the same cluster */
|
||||
static inline bool cpuinfo_arm_linux_processor_not_equals(
|
||||
struct cpuinfo_arm_linux_processor processor_i[restrict static 1],
|
||||
struct cpuinfo_arm_linux_processor processor_j[restrict static 1])
|
||||
{
|
||||
const uint32_t joint_flags = processor_i->flags & processor_j->flags;
|
||||
|
||||
if (joint_flags & CPUINFO_LINUX_FLAG_MAX_FREQUENCY) {
|
||||
if (processor_i->max_frequency != processor_j->max_frequency) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (joint_flags & CPUINFO_LINUX_FLAG_MIN_FREQUENCY) {
|
||||
if (processor_i->min_frequency != processor_j->min_frequency) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if ((joint_flags & CPUINFO_ARM_LINUX_VALID_MIDR) == CPUINFO_ARM_LINUX_VALID_MIDR) {
|
||||
if (processor_i->midr != processor_j->midr) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
CPUINFO_INTERNAL bool cpuinfo_arm_linux_parse_proc_cpuinfo(
|
||||
char hardware[restrict static CPUINFO_HARDWARE_VALUE_MAX],
|
||||
char revision[restrict static CPUINFO_REVISION_VALUE_MAX],
|
||||
uint32_t max_processors_count,
|
||||
struct cpuinfo_arm_linux_processor processors[restrict static max_processors_count]);
|
||||
|
||||
#if CPUINFO_ARCH_ARM
|
||||
CPUINFO_INTERNAL bool cpuinfo_arm_linux_hwcap_from_getauxval(
|
||||
uint32_t hwcap[restrict static 1],
|
||||
uint32_t hwcap2[restrict static 1]);
|
||||
CPUINFO_INTERNAL bool cpuinfo_arm_linux_hwcap_from_procfs(
|
||||
uint32_t hwcap[restrict static 1],
|
||||
uint32_t hwcap2[restrict static 1]);
|
||||
|
||||
CPUINFO_INTERNAL void cpuinfo_arm_linux_decode_isa_from_proc_cpuinfo(
|
||||
uint32_t features,
|
||||
uint32_t features2,
|
||||
uint32_t midr,
|
||||
uint32_t architecture_version,
|
||||
uint32_t architecture_flags,
|
||||
const struct cpuinfo_arm_chipset chipset[restrict static 1],
|
||||
struct cpuinfo_arm_isa isa[restrict static 1]);
|
||||
#elif CPUINFO_ARCH_ARM64
|
||||
CPUINFO_INTERNAL void cpuinfo_arm_linux_hwcap_from_getauxval(
|
||||
uint32_t hwcap[restrict static 1],
|
||||
uint32_t hwcap2[restrict static 1]);
|
||||
|
||||
CPUINFO_INTERNAL void cpuinfo_arm64_linux_decode_isa_from_proc_cpuinfo(
|
||||
uint32_t features,
|
||||
uint32_t features2,
|
||||
uint32_t midr,
|
||||
const struct cpuinfo_arm_chipset chipset[restrict static 1],
|
||||
struct cpuinfo_arm_isa isa[restrict static 1]);
|
||||
#endif
|
||||
|
||||
#ifdef __ANDROID__
|
||||
CPUINFO_INTERNAL struct cpuinfo_arm_chipset
|
||||
cpuinfo_arm_android_decode_chipset(
|
||||
const struct cpuinfo_android_properties properties[restrict static 1],
|
||||
uint32_t cores,
|
||||
uint32_t max_cpu_freq_max);
|
||||
#else
|
||||
CPUINFO_INTERNAL struct cpuinfo_arm_chipset
|
||||
cpuinfo_arm_linux_decode_chipset(
|
||||
const char hardware[restrict static CPUINFO_HARDWARE_VALUE_MAX],
|
||||
const char revision[restrict static CPUINFO_REVISION_VALUE_MAX],
|
||||
uint32_t cores,
|
||||
uint32_t max_cpu_freq_max);
|
||||
#endif
|
||||
|
||||
CPUINFO_INTERNAL struct cpuinfo_arm_chipset
|
||||
cpuinfo_arm_linux_decode_chipset_from_proc_cpuinfo_hardware(
|
||||
const char proc_cpuinfo_hardware[restrict static CPUINFO_HARDWARE_VALUE_MAX],
|
||||
uint32_t cores, uint32_t max_cpu_freq_max, bool is_tegra);
|
||||
|
||||
#ifdef __ANDROID__
|
||||
CPUINFO_INTERNAL struct cpuinfo_arm_chipset
|
||||
cpuinfo_arm_android_decode_chipset_from_ro_product_board(
|
||||
const char ro_product_board[restrict static CPUINFO_BUILD_PROP_VALUE_MAX],
|
||||
uint32_t cores, uint32_t max_cpu_freq_max);
|
||||
CPUINFO_INTERNAL struct cpuinfo_arm_chipset
|
||||
cpuinfo_arm_android_decode_chipset_from_ro_board_platform(
|
||||
const char ro_board_platform[restrict static CPUINFO_BUILD_PROP_VALUE_MAX],
|
||||
uint32_t cores, uint32_t max_cpu_freq_max);
|
||||
CPUINFO_INTERNAL struct cpuinfo_arm_chipset
|
||||
cpuinfo_arm_android_decode_chipset_from_ro_mediatek_platform(
|
||||
const char ro_mediatek_platform[restrict static CPUINFO_BUILD_PROP_VALUE_MAX]);
|
||||
CPUINFO_INTERNAL struct cpuinfo_arm_chipset
|
||||
cpuinfo_arm_android_decode_chipset_from_ro_arch(
|
||||
const char ro_arch[restrict static CPUINFO_BUILD_PROP_VALUE_MAX]);
|
||||
CPUINFO_INTERNAL struct cpuinfo_arm_chipset
|
||||
cpuinfo_arm_android_decode_chipset_from_ro_chipname(
|
||||
const char ro_chipname[restrict static CPUINFO_BUILD_PROP_VALUE_MAX]);
|
||||
CPUINFO_INTERNAL struct cpuinfo_arm_chipset
|
||||
cpuinfo_arm_android_decode_chipset_from_ro_hardware_chipname(
|
||||
const char ro_hardware_chipname[restrict static CPUINFO_BUILD_PROP_VALUE_MAX]);
|
||||
#else
|
||||
CPUINFO_INTERNAL struct cpuinfo_arm_chipset
|
||||
cpuinfo_arm_linux_decode_chipset_from_proc_cpuinfo_revision(
|
||||
const char proc_cpuinfo_revision[restrict static CPUINFO_REVISION_VALUE_MAX]);
|
||||
#endif
|
||||
|
||||
CPUINFO_INTERNAL bool cpuinfo_arm_linux_detect_core_clusters_by_heuristic(
|
||||
uint32_t usable_processors,
|
||||
uint32_t max_processors,
|
||||
struct cpuinfo_arm_linux_processor processors[restrict static max_processors]);
|
||||
|
||||
CPUINFO_INTERNAL void cpuinfo_arm_linux_detect_core_clusters_by_sequential_scan(
|
||||
uint32_t max_processors,
|
||||
struct cpuinfo_arm_linux_processor processors[restrict static max_processors]);
|
||||
|
||||
CPUINFO_INTERNAL void cpuinfo_arm_linux_count_cluster_processors(
|
||||
uint32_t max_processors,
|
||||
struct cpuinfo_arm_linux_processor processors[restrict static max_processors]);
|
||||
|
||||
CPUINFO_INTERNAL uint32_t cpuinfo_arm_linux_detect_cluster_midr(
|
||||
const struct cpuinfo_arm_chipset chipset[restrict static 1],
|
||||
uint32_t max_processors,
|
||||
uint32_t usable_processors,
|
||||
struct cpuinfo_arm_linux_processor processors[restrict static max_processors]);
|
||||
|
||||
extern CPUINFO_INTERNAL const uint32_t* cpuinfo_linux_cpu_to_uarch_index_map;
|
||||
extern CPUINFO_INTERNAL uint32_t cpuinfo_linux_cpu_to_uarch_index_map_entries;
|
||||
3860
3rdparty/cpuinfo/src/arm/linux/chipset.c
vendored
Normal file
3860
3rdparty/cpuinfo/src/arm/linux/chipset.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
493
3rdparty/cpuinfo/src/arm/linux/clusters.c
vendored
Normal file
493
3rdparty/cpuinfo/src/arm/linux/clusters.c
vendored
Normal file
@@ -0,0 +1,493 @@
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <cpuinfo.h>
|
||||
#include <arm/linux/api.h>
|
||||
#if defined(__ANDROID__)
|
||||
#include <arm/android/api.h>
|
||||
#endif
|
||||
#include <arm/api.h>
|
||||
#include <arm/midr.h>
|
||||
#include <linux/api.h>
|
||||
#include <cpuinfo/internal-api.h>
|
||||
#include <cpuinfo/log.h>
|
||||
|
||||
static inline bool bitmask_all(uint32_t bitfield, uint32_t mask) {
|
||||
return (bitfield & mask) == mask;
|
||||
}
|
||||
|
||||
/*
|
||||
* Assigns logical processors to clusters of cores using heuristic based on the typical configuration of clusters for
|
||||
* 5, 6, 8, and 10 cores:
|
||||
* - 5 cores (ARM32 Android only): 2 clusters of 4+1 cores
|
||||
* - 6 cores: 2 clusters of 4+2 cores
|
||||
* - 8 cores: 2 clusters of 4+4 cores
|
||||
* - 10 cores: 3 clusters of 4+4+2 cores
|
||||
*
|
||||
* The function must be called after parsing OS-provided information on core clusters.
|
||||
* Its purpose is to detect clusters of cores when OS-provided information is lacking or incomplete, i.e.
|
||||
* - Linux kernel is not configured to report information in sysfs topology leaf.
|
||||
* - Linux kernel reports topology information only for online cores, and only cores on one cluster are online, e.g.:
|
||||
* - Exynos 8890 has 8 cores in 4+4 clusters, but only the first cluster of 4 cores is reported, and cluster
|
||||
* configuration of logical processors 4-7 is not reported (all remaining processors 4-7 form cluster 1)
|
||||
* - MT6797 has 10 cores in 4+4+2, but only the first cluster of 4 cores is reported, and cluster configuration
|
||||
* of logical processors 4-9 is not reported (processors 4-7 form cluster 1, and processors 8-9 form cluster 2).
|
||||
*
|
||||
* Heuristic assignment of processors to the above pre-defined clusters fails if such assignment would contradict
|
||||
* information provided by the operating system:
|
||||
* - Any of the OS-reported processor clusters is different than the corresponding heuristic cluster.
|
||||
* - Processors in a heuristic cluster have no OS-provided cluster siblings information, but have known and different
|
||||
* minimum/maximum frequency.
|
||||
* - Processors in a heuristic cluster have no OS-provided cluster siblings information, but have known and different
|
||||
* MIDR components.
|
||||
*
|
||||
* If the heuristic assignment of processors to clusters of cores fails, all processors' clusters are unchanged.
|
||||
*
|
||||
* @param usable_processors - number of processors in the @p processors array with CPUINFO_LINUX_FLAG_VALID flags.
|
||||
* @param max_processors - number of elements in the @p processors array.
|
||||
* @param[in,out] processors - processor descriptors with pre-parsed POSSIBLE and PRESENT flags, minimum/maximum
|
||||
* frequency, MIDR infromation, and core cluster (package siblings list) information.
|
||||
*
|
||||
* @retval true if the heuristic successfully assigned all processors into clusters of cores.
|
||||
* @retval false if known details about processors contradict the heuristic configuration of core clusters.
|
||||
*/
|
||||
bool cpuinfo_arm_linux_detect_core_clusters_by_heuristic(
|
||||
uint32_t usable_processors,
|
||||
uint32_t max_processors,
|
||||
struct cpuinfo_arm_linux_processor processors[restrict static max_processors])
|
||||
{
|
||||
uint32_t cluster_processors[3];
|
||||
switch (usable_processors) {
|
||||
case 10:
|
||||
cluster_processors[0] = 4;
|
||||
cluster_processors[1] = 4;
|
||||
cluster_processors[2] = 2;
|
||||
break;
|
||||
case 8:
|
||||
cluster_processors[0] = 4;
|
||||
cluster_processors[1] = 4;
|
||||
break;
|
||||
case 6:
|
||||
cluster_processors[0] = 4;
|
||||
cluster_processors[1] = 2;
|
||||
break;
|
||||
#if defined(__ANDROID__) && CPUINFO_ARCH_ARM
|
||||
case 5:
|
||||
/*
|
||||
* The only processor with 5 cores is Leadcore L1860C (ARMv7, mobile),
|
||||
* but this configuration is not too unreasonable for a virtualized ARM server.
|
||||
*/
|
||||
cluster_processors[0] = 4;
|
||||
cluster_processors[1] = 1;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Assignment of processors to core clusters is done in two passes:
|
||||
* 1. Verify that the clusters proposed by heuristic are compatible with known details about processors.
|
||||
* 2. If verification passed, update core clusters for the processors.
|
||||
*/
|
||||
|
||||
uint32_t cluster = 0;
|
||||
uint32_t expected_cluster_processors = 0;
|
||||
uint32_t cluster_start, cluster_flags, cluster_midr, cluster_max_frequency, cluster_min_frequency;
|
||||
bool expected_cluster_exists;
|
||||
for (uint32_t i = 0; i < max_processors; i++) {
|
||||
if (bitmask_all(processors[i].flags, CPUINFO_LINUX_FLAG_VALID)) {
|
||||
if (expected_cluster_processors == 0) {
|
||||
/* Expect this processor to start a new cluster */
|
||||
|
||||
expected_cluster_exists = !!(processors[i].flags & CPUINFO_LINUX_FLAG_PACKAGE_CLUSTER);
|
||||
if (expected_cluster_exists) {
|
||||
if (processors[i].package_leader_id != i) {
|
||||
cpuinfo_log_debug(
|
||||
"heuristic detection of core clusters failed: "
|
||||
"processor %"PRIu32" is expected to start a new cluster #%"PRIu32" with %"PRIu32" cores, "
|
||||
"but system siblings lists reported it as a sibling of processor %"PRIu32,
|
||||
i, cluster, cluster_processors[cluster], processors[i].package_leader_id);
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
cluster_flags = 0;
|
||||
}
|
||||
|
||||
cluster_start = i;
|
||||
expected_cluster_processors = cluster_processors[cluster++];
|
||||
} else {
|
||||
/* Expect this processor to belong to the same cluster as processor */
|
||||
|
||||
if (expected_cluster_exists) {
|
||||
/*
|
||||
* The cluster suggested by the heuristic was already parsed from system siblings lists.
|
||||
* For all processors we expect in the cluster, check that:
|
||||
* - They have pre-assigned cluster from siblings lists (CPUINFO_LINUX_FLAG_PACKAGE_CLUSTER flag).
|
||||
* - They were assigned to the same cluster based on siblings lists
|
||||
* (package_leader_id points to the first processor in the cluster).
|
||||
*/
|
||||
|
||||
if ((processors[i].flags & CPUINFO_LINUX_FLAG_PACKAGE_CLUSTER) == 0) {
|
||||
cpuinfo_log_debug(
|
||||
"heuristic detection of core clusters failed: "
|
||||
"processor %"PRIu32" is expected to belong to the cluster of processor %"PRIu32", "
|
||||
"but system siblings lists did not report it as a sibling of processor %"PRIu32,
|
||||
i, cluster_start, cluster_start);
|
||||
return false;
|
||||
}
|
||||
if (processors[i].package_leader_id != cluster_start) {
|
||||
cpuinfo_log_debug(
|
||||
"heuristic detection of core clusters failed: "
|
||||
"processor %"PRIu32" is expected to belong to the cluster of processor %"PRIu32", "
|
||||
"but system siblings lists reported it to belong to the cluster of processor %"PRIu32,
|
||||
i, cluster_start, cluster_start);
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* The cluster suggest by the heuristic was not parsed from system siblings lists.
|
||||
* For all processors we expect in the cluster, check that:
|
||||
* - They have no pre-assigned cluster from siblings lists.
|
||||
* - If their min/max CPU frequency is known, it is the same.
|
||||
* - If any part of their MIDR (Implementer, Variant, Part, Revision) is known, it is the same.
|
||||
*/
|
||||
|
||||
if (processors[i].flags & CPUINFO_LINUX_FLAG_PACKAGE_CLUSTER) {
|
||||
cpuinfo_log_debug(
|
||||
"heuristic detection of core clusters failed: "
|
||||
"processor %"PRIu32" is expected to be unassigned to any cluster, "
|
||||
"but system siblings lists reported it to belong to the cluster of processor %"PRIu32,
|
||||
i, processors[i].package_leader_id);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (processors[i].flags & CPUINFO_LINUX_FLAG_MIN_FREQUENCY) {
|
||||
if (cluster_flags & CPUINFO_LINUX_FLAG_MIN_FREQUENCY) {
|
||||
if (cluster_min_frequency != processors[i].min_frequency) {
|
||||
cpuinfo_log_debug(
|
||||
"heuristic detection of core clusters failed: "
|
||||
"minimum frequency of processor %"PRIu32" (%"PRIu32" KHz) is different than of its expected cluster (%"PRIu32" KHz)",
|
||||
i, processors[i].min_frequency, cluster_min_frequency);
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
cluster_min_frequency = processors[i].min_frequency;
|
||||
cluster_flags |= CPUINFO_LINUX_FLAG_MIN_FREQUENCY;
|
||||
}
|
||||
}
|
||||
|
||||
if (processors[i].flags & CPUINFO_LINUX_FLAG_MAX_FREQUENCY) {
|
||||
if (cluster_flags & CPUINFO_LINUX_FLAG_MAX_FREQUENCY) {
|
||||
if (cluster_max_frequency != processors[i].max_frequency) {
|
||||
cpuinfo_log_debug(
|
||||
"heuristic detection of core clusters failed: "
|
||||
"maximum frequency of processor %"PRIu32" (%"PRIu32" KHz) is different than of its expected cluster (%"PRIu32" KHz)",
|
||||
i, processors[i].max_frequency, cluster_max_frequency);
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
cluster_max_frequency = processors[i].max_frequency;
|
||||
cluster_flags |= CPUINFO_LINUX_FLAG_MAX_FREQUENCY;
|
||||
}
|
||||
}
|
||||
|
||||
if (processors[i].flags & CPUINFO_ARM_LINUX_VALID_IMPLEMENTER) {
|
||||
if (cluster_flags & CPUINFO_ARM_LINUX_VALID_IMPLEMENTER) {
|
||||
if ((cluster_midr & CPUINFO_ARM_MIDR_IMPLEMENTER_MASK) != (processors[i].midr & CPUINFO_ARM_MIDR_IMPLEMENTER_MASK)) {
|
||||
cpuinfo_log_debug(
|
||||
"heuristic detection of core clusters failed: "
|
||||
"CPU Implementer of processor %"PRIu32" (0x%02"PRIx32") is different than of its expected cluster (0x%02"PRIx32")",
|
||||
i, midr_get_implementer(processors[i].midr), midr_get_implementer(cluster_midr));
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
cluster_midr = midr_copy_implementer(cluster_midr, processors[i].midr);
|
||||
cluster_flags |= CPUINFO_ARM_LINUX_VALID_IMPLEMENTER;
|
||||
}
|
||||
}
|
||||
|
||||
if (processors[i].flags & CPUINFO_ARM_LINUX_VALID_VARIANT) {
|
||||
if (cluster_flags & CPUINFO_ARM_LINUX_VALID_VARIANT) {
|
||||
if ((cluster_midr & CPUINFO_ARM_MIDR_VARIANT_MASK) != (processors[i].midr & CPUINFO_ARM_MIDR_VARIANT_MASK)) {
|
||||
cpuinfo_log_debug(
|
||||
"heuristic detection of core clusters failed: "
|
||||
"CPU Variant of processor %"PRIu32" (0x%"PRIx32") is different than of its expected cluster (0x%"PRIx32")",
|
||||
i, midr_get_variant(processors[i].midr), midr_get_variant(cluster_midr));
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
cluster_midr = midr_copy_variant(cluster_midr, processors[i].midr);
|
||||
cluster_flags |= CPUINFO_ARM_LINUX_VALID_VARIANT;
|
||||
}
|
||||
}
|
||||
|
||||
if (processors[i].flags & CPUINFO_ARM_LINUX_VALID_PART) {
|
||||
if (cluster_flags & CPUINFO_ARM_LINUX_VALID_PART) {
|
||||
if ((cluster_midr & CPUINFO_ARM_MIDR_PART_MASK) != (processors[i].midr & CPUINFO_ARM_MIDR_PART_MASK)) {
|
||||
cpuinfo_log_debug(
|
||||
"heuristic detection of core clusters failed: "
|
||||
"CPU Part of processor %"PRIu32" (0x%03"PRIx32") is different than of its expected cluster (0x%03"PRIx32")",
|
||||
i, midr_get_part(processors[i].midr), midr_get_part(cluster_midr));
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
cluster_midr = midr_copy_part(cluster_midr, processors[i].midr);
|
||||
cluster_flags |= CPUINFO_ARM_LINUX_VALID_PART;
|
||||
}
|
||||
}
|
||||
|
||||
if (processors[i].flags & CPUINFO_ARM_LINUX_VALID_REVISION) {
|
||||
if (cluster_flags & CPUINFO_ARM_LINUX_VALID_REVISION) {
|
||||
if ((cluster_midr & CPUINFO_ARM_MIDR_REVISION_MASK) != (processors[i].midr & CPUINFO_ARM_MIDR_REVISION_MASK)) {
|
||||
cpuinfo_log_debug(
|
||||
"heuristic detection of core clusters failed: "
|
||||
"CPU Revision of processor %"PRIu32" (0x%"PRIx32") is different than of its expected cluster (0x%"PRIx32")",
|
||||
i, midr_get_revision(cluster_midr), midr_get_revision(processors[i].midr));
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
cluster_midr = midr_copy_revision(cluster_midr, processors[i].midr);
|
||||
cluster_flags |= CPUINFO_ARM_LINUX_VALID_REVISION;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
expected_cluster_processors--;
|
||||
}
|
||||
}
|
||||
|
||||
/* Verification passed, assign all processors to new clusters */
|
||||
cluster = 0;
|
||||
expected_cluster_processors = 0;
|
||||
for (uint32_t i = 0; i < max_processors; i++) {
|
||||
if (bitmask_all(processors[i].flags, CPUINFO_LINUX_FLAG_VALID)) {
|
||||
if (expected_cluster_processors == 0) {
|
||||
/* Expect this processor to start a new cluster */
|
||||
|
||||
cluster_start = i;
|
||||
expected_cluster_processors = cluster_processors[cluster++];
|
||||
} else {
|
||||
/* Expect this processor to belong to the same cluster as processor */
|
||||
|
||||
if (!(processors[i].flags & CPUINFO_LINUX_FLAG_PACKAGE_CLUSTER)) {
|
||||
cpuinfo_log_debug("assigned processor %"PRIu32" to cluster of processor %"PRIu32" based on heuristic",
|
||||
i, cluster_start);
|
||||
}
|
||||
|
||||
processors[i].package_leader_id = cluster_start;
|
||||
processors[i].flags |= CPUINFO_LINUX_FLAG_PACKAGE_CLUSTER;
|
||||
}
|
||||
expected_cluster_processors--;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Assigns logical processors to clusters of cores in sequential manner:
|
||||
* - Clusters detected from OS-provided information are unchanged:
|
||||
* - Processors assigned to these clusters stay assigned to the same clusters
|
||||
* - No new processors are added to these clusters
|
||||
* - Processors without pre-assigned cluster are clustered in one sequential scan:
|
||||
* - If known details (min/max frequency, MIDR components) of a processor are compatible with a preceeding
|
||||
* processor, without pre-assigned cluster, the processor is assigned to the cluster of the preceeding processor.
|
||||
* - If known details (min/max frequency, MIDR components) of a processor are not compatible with a preceeding
|
||||
* processor, the processor is assigned to a newly created cluster.
|
||||
*
|
||||
* The function must be called after parsing OS-provided information on core clusters, and usually is called only
|
||||
* if heuristic assignment of processors to clusters (cpuinfo_arm_linux_cluster_processors_by_heuristic) failed.
|
||||
*
|
||||
* Its purpose is to detect clusters of cores when OS-provided information is lacking or incomplete, i.e.
|
||||
* - Linux kernel is not configured to report information in sysfs topology leaf.
|
||||
* - Linux kernel reports topology information only for online cores, and all cores on some of the clusters are offline.
|
||||
*
|
||||
* Sequential assignment of processors to clusters always succeeds, and upon exit, all usable processors in the
|
||||
* @p processors array have cluster information.
|
||||
*
|
||||
* @param max_processors - number of elements in the @p processors array.
|
||||
* @param[in,out] processors - processor descriptors with pre-parsed POSSIBLE and PRESENT flags, minimum/maximum
|
||||
* frequency, MIDR infromation, and core cluster (package siblings list) information.
|
||||
*
|
||||
* @retval true if the heuristic successfully assigned all processors into clusters of cores.
|
||||
* @retval false if known details about processors contradict the heuristic configuration of core clusters.
|
||||
*/
|
||||
void cpuinfo_arm_linux_detect_core_clusters_by_sequential_scan(
|
||||
uint32_t max_processors,
|
||||
struct cpuinfo_arm_linux_processor processors[restrict static max_processors])
|
||||
{
|
||||
uint32_t cluster_flags = 0;
|
||||
uint32_t cluster_processors = 0;
|
||||
uint32_t cluster_start, cluster_midr, cluster_max_frequency, cluster_min_frequency;
|
||||
for (uint32_t i = 0; i < max_processors; i++) {
|
||||
if ((processors[i].flags & (CPUINFO_LINUX_FLAG_VALID | CPUINFO_LINUX_FLAG_PACKAGE_CLUSTER)) == CPUINFO_LINUX_FLAG_VALID) {
|
||||
if (cluster_processors == 0) {
|
||||
goto new_cluster;
|
||||
}
|
||||
|
||||
if (processors[i].flags & CPUINFO_LINUX_FLAG_MIN_FREQUENCY) {
|
||||
if (cluster_flags & CPUINFO_LINUX_FLAG_MIN_FREQUENCY) {
|
||||
if (cluster_min_frequency != processors[i].min_frequency) {
|
||||
cpuinfo_log_info(
|
||||
"minimum frequency of processor %"PRIu32" (%"PRIu32" KHz) is different than of preceeding cluster (%"PRIu32" KHz); "
|
||||
"processor %"PRIu32" starts to a new cluster",
|
||||
i, processors[i].min_frequency, cluster_min_frequency, i);
|
||||
goto new_cluster;
|
||||
}
|
||||
} else {
|
||||
cluster_min_frequency = processors[i].min_frequency;
|
||||
cluster_flags |= CPUINFO_LINUX_FLAG_MIN_FREQUENCY;
|
||||
}
|
||||
}
|
||||
|
||||
if (processors[i].flags & CPUINFO_LINUX_FLAG_MAX_FREQUENCY) {
|
||||
if (cluster_flags & CPUINFO_LINUX_FLAG_MAX_FREQUENCY) {
|
||||
if (cluster_max_frequency != processors[i].max_frequency) {
|
||||
cpuinfo_log_debug(
|
||||
"maximum frequency of processor %"PRIu32" (%"PRIu32" KHz) is different than of preceeding cluster (%"PRIu32" KHz); "
|
||||
"processor %"PRIu32" starts a new cluster",
|
||||
i, processors[i].max_frequency, cluster_max_frequency, i);
|
||||
goto new_cluster;
|
||||
}
|
||||
} else {
|
||||
cluster_max_frequency = processors[i].max_frequency;
|
||||
cluster_flags |= CPUINFO_LINUX_FLAG_MAX_FREQUENCY;
|
||||
}
|
||||
}
|
||||
|
||||
if (processors[i].flags & CPUINFO_ARM_LINUX_VALID_IMPLEMENTER) {
|
||||
if (cluster_flags & CPUINFO_ARM_LINUX_VALID_IMPLEMENTER) {
|
||||
if ((cluster_midr & CPUINFO_ARM_MIDR_IMPLEMENTER_MASK) != (processors[i].midr & CPUINFO_ARM_MIDR_IMPLEMENTER_MASK)) {
|
||||
cpuinfo_log_debug(
|
||||
"CPU Implementer of processor %"PRIu32" (0x%02"PRIx32") is different than of preceeding cluster (0x%02"PRIx32"); "
|
||||
"processor %"PRIu32" starts to a new cluster",
|
||||
i, midr_get_implementer(processors[i].midr), midr_get_implementer(cluster_midr), i);
|
||||
goto new_cluster;
|
||||
}
|
||||
} else {
|
||||
cluster_midr = midr_copy_implementer(cluster_midr, processors[i].midr);
|
||||
cluster_flags |= CPUINFO_ARM_LINUX_VALID_IMPLEMENTER;
|
||||
}
|
||||
}
|
||||
|
||||
if (processors[i].flags & CPUINFO_ARM_LINUX_VALID_VARIANT) {
|
||||
if (cluster_flags & CPUINFO_ARM_LINUX_VALID_VARIANT) {
|
||||
if ((cluster_midr & CPUINFO_ARM_MIDR_VARIANT_MASK) != (processors[i].midr & CPUINFO_ARM_MIDR_VARIANT_MASK)) {
|
||||
cpuinfo_log_debug(
|
||||
"CPU Variant of processor %"PRIu32" (0x%"PRIx32") is different than of its expected cluster (0x%"PRIx32")"
|
||||
"processor %"PRIu32" starts to a new cluster",
|
||||
i, midr_get_variant(processors[i].midr), midr_get_variant(cluster_midr), i);
|
||||
goto new_cluster;
|
||||
}
|
||||
} else {
|
||||
cluster_midr = midr_copy_variant(cluster_midr, processors[i].midr);
|
||||
cluster_flags |= CPUINFO_ARM_LINUX_VALID_VARIANT;
|
||||
}
|
||||
}
|
||||
|
||||
if (processors[i].flags & CPUINFO_ARM_LINUX_VALID_PART) {
|
||||
if (cluster_flags & CPUINFO_ARM_LINUX_VALID_PART) {
|
||||
if ((cluster_midr & CPUINFO_ARM_MIDR_PART_MASK) != (processors[i].midr & CPUINFO_ARM_MIDR_PART_MASK)) {
|
||||
cpuinfo_log_debug(
|
||||
"CPU Part of processor %"PRIu32" (0x%03"PRIx32") is different than of its expected cluster (0x%03"PRIx32")"
|
||||
"processor %"PRIu32" starts to a new cluster",
|
||||
i, midr_get_part(processors[i].midr), midr_get_part(cluster_midr), i);
|
||||
goto new_cluster;
|
||||
}
|
||||
} else {
|
||||
cluster_midr = midr_copy_part(cluster_midr, processors[i].midr);
|
||||
cluster_flags |= CPUINFO_ARM_LINUX_VALID_PART;
|
||||
}
|
||||
}
|
||||
|
||||
if (processors[i].flags & CPUINFO_ARM_LINUX_VALID_REVISION) {
|
||||
if (cluster_flags & CPUINFO_ARM_LINUX_VALID_REVISION) {
|
||||
if ((cluster_midr & CPUINFO_ARM_MIDR_REVISION_MASK) != (processors[i].midr & CPUINFO_ARM_MIDR_REVISION_MASK)) {
|
||||
cpuinfo_log_debug(
|
||||
"CPU Revision of processor %"PRIu32" (0x%"PRIx32") is different than of its expected cluster (0x%"PRIx32")"
|
||||
"processor %"PRIu32" starts to a new cluster",
|
||||
i, midr_get_revision(cluster_midr), midr_get_revision(processors[i].midr), i);
|
||||
goto new_cluster;
|
||||
}
|
||||
} else {
|
||||
cluster_midr = midr_copy_revision(cluster_midr, processors[i].midr);
|
||||
cluster_flags |= CPUINFO_ARM_LINUX_VALID_REVISION;
|
||||
}
|
||||
}
|
||||
|
||||
/* All checks passed, attach processor to the preceeding cluster */
|
||||
cluster_processors++;
|
||||
processors[i].package_leader_id = cluster_start;
|
||||
processors[i].flags |= CPUINFO_LINUX_FLAG_PACKAGE_CLUSTER;
|
||||
cpuinfo_log_debug("assigned processor %"PRIu32" to preceeding cluster of processor %"PRIu32, i, cluster_start);
|
||||
continue;
|
||||
|
||||
new_cluster:
|
||||
/* Create a new cluster starting with processor i */
|
||||
cluster_start = i;
|
||||
processors[i].package_leader_id = i;
|
||||
processors[i].flags |= CPUINFO_LINUX_FLAG_PACKAGE_CLUSTER;
|
||||
cluster_processors = 1;
|
||||
|
||||
/* Copy known information from processor to cluster, and set the flags accordingly */
|
||||
cluster_flags = 0;
|
||||
if (processors[i].flags & CPUINFO_LINUX_FLAG_MIN_FREQUENCY) {
|
||||
cluster_min_frequency = processors[i].min_frequency;
|
||||
cluster_flags |= CPUINFO_LINUX_FLAG_MIN_FREQUENCY;
|
||||
}
|
||||
if (processors[i].flags & CPUINFO_LINUX_FLAG_MAX_FREQUENCY) {
|
||||
cluster_max_frequency = processors[i].max_frequency;
|
||||
cluster_flags |= CPUINFO_LINUX_FLAG_MAX_FREQUENCY;
|
||||
}
|
||||
if (processors[i].flags & CPUINFO_ARM_LINUX_VALID_IMPLEMENTER) {
|
||||
cluster_midr = midr_copy_implementer(cluster_midr, processors[i].midr);
|
||||
cluster_flags |= CPUINFO_ARM_LINUX_VALID_IMPLEMENTER;
|
||||
}
|
||||
if (processors[i].flags & CPUINFO_ARM_LINUX_VALID_VARIANT) {
|
||||
cluster_midr = midr_copy_variant(cluster_midr, processors[i].midr);
|
||||
cluster_flags |= CPUINFO_ARM_LINUX_VALID_VARIANT;
|
||||
}
|
||||
if (processors[i].flags & CPUINFO_ARM_LINUX_VALID_PART) {
|
||||
cluster_midr = midr_copy_part(cluster_midr, processors[i].midr);
|
||||
cluster_flags |= CPUINFO_ARM_LINUX_VALID_PART;
|
||||
}
|
||||
if (processors[i].flags & CPUINFO_ARM_LINUX_VALID_REVISION) {
|
||||
cluster_midr = midr_copy_revision(cluster_midr, processors[i].midr);
|
||||
cluster_flags |= CPUINFO_ARM_LINUX_VALID_REVISION;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Counts the number of logical processors in each core cluster.
|
||||
* This function should be called after all processors are assigned to core clusters.
|
||||
*
|
||||
* @param max_processors - number of elements in the @p processors array.
|
||||
* @param[in,out] processors - processor descriptors with pre-parsed POSSIBLE and PRESENT flags,
|
||||
* and decoded core cluster (package_leader_id) information.
|
||||
* The function expects the value of processors[i].package_processor_count to be zero.
|
||||
* Upon return, processors[i].package_processor_count will contain the number of logical
|
||||
* processors in the respective core cluster.
|
||||
*/
|
||||
void cpuinfo_arm_linux_count_cluster_processors(
|
||||
uint32_t max_processors,
|
||||
struct cpuinfo_arm_linux_processor processors[restrict static max_processors])
|
||||
{
|
||||
/* First pass: accumulate the number of processors at the group leader's package_processor_count */
|
||||
for (uint32_t i = 0; i < max_processors; i++) {
|
||||
if (bitmask_all(processors[i].flags, CPUINFO_LINUX_FLAG_VALID)) {
|
||||
const uint32_t package_leader_id = processors[i].package_leader_id;
|
||||
processors[package_leader_id].package_processor_count += 1;
|
||||
}
|
||||
}
|
||||
/* Second pass: copy the package_processor_count from the group leader processor */
|
||||
for (uint32_t i = 0; i < max_processors; i++) {
|
||||
if (bitmask_all(processors[i].flags, CPUINFO_LINUX_FLAG_VALID)) {
|
||||
const uint32_t package_leader_id = processors[i].package_leader_id;
|
||||
processors[i].package_processor_count = processors[package_leader_id].package_processor_count;
|
||||
}
|
||||
}
|
||||
}
|
||||
44
3rdparty/cpuinfo/src/arm/linux/cp.h
vendored
Normal file
44
3rdparty/cpuinfo/src/arm/linux/cp.h
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
#if CPUINFO_MOCK
|
||||
extern uint32_t cpuinfo_arm_fpsid;
|
||||
extern uint32_t cpuinfo_arm_mvfr0;
|
||||
extern uint32_t cpuinfo_arm_wcid;
|
||||
|
||||
static inline uint32_t read_fpsid(void) {
|
||||
return cpuinfo_arm_fpsid;
|
||||
}
|
||||
|
||||
static inline uint32_t read_mvfr0(void) {
|
||||
return cpuinfo_arm_mvfr0;
|
||||
}
|
||||
|
||||
static inline uint32_t read_wcid(void) {
|
||||
return cpuinfo_arm_wcid;
|
||||
}
|
||||
#else
|
||||
#if !defined(__ARM_ARCH_7A__) && !defined(__ARM_ARCH_8A__) && !(defined(__ARM_ARCH) && (__ARM_ARCH >= 7))
|
||||
/*
|
||||
* CoProcessor 10 is inaccessible from user mode since ARMv7,
|
||||
* and clang refuses to compile inline assembly when targeting ARMv7+
|
||||
*/
|
||||
static inline uint32_t read_fpsid(void) {
|
||||
uint32_t fpsid;
|
||||
__asm__ __volatile__("MRC p10, 0x7, %[fpsid], cr0, cr0, 0" : [fpsid] "=r" (fpsid));
|
||||
return fpsid;
|
||||
}
|
||||
|
||||
static inline uint32_t read_mvfr0(void) {
|
||||
uint32_t mvfr0;
|
||||
__asm__ __volatile__("MRC p10, 0x7, %[mvfr0], cr7, cr0, 0" : [mvfr0] "=r" (mvfr0));
|
||||
return mvfr0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline uint32_t read_wcid(void) {
|
||||
uint32_t wcid;
|
||||
__asm__ __volatile__("MRC p1, 0, %[wcid], c0, c0" : [wcid] "=r" (wcid));
|
||||
return wcid;
|
||||
}
|
||||
#endif
|
||||
908
3rdparty/cpuinfo/src/arm/linux/cpuinfo.c
vendored
Normal file
908
3rdparty/cpuinfo/src/arm/linux/cpuinfo.c
vendored
Normal file
@@ -0,0 +1,908 @@
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <linux/api.h>
|
||||
#include <arm/linux/api.h>
|
||||
#include <arm/midr.h>
|
||||
#include <cpuinfo/log.h>
|
||||
|
||||
/*
|
||||
* Size, in chars, of the on-stack buffer used for parsing lines of /proc/cpuinfo.
|
||||
* This is also the limit on the length of a single line.
|
||||
*/
|
||||
#define BUFFER_SIZE 1024
|
||||
|
||||
|
||||
static uint32_t parse_processor_number(
|
||||
const char* processor_start,
|
||||
const char* processor_end)
|
||||
{
|
||||
const size_t processor_length = (size_t) (processor_end - processor_start);
|
||||
|
||||
if (processor_length == 0) {
|
||||
cpuinfo_log_warning("Processor number in /proc/cpuinfo is ignored: string is empty");
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t processor_number = 0;
|
||||
for (const char* digit_ptr = processor_start; digit_ptr != processor_end; digit_ptr++) {
|
||||
const uint32_t digit = (uint32_t) (*digit_ptr - '0');
|
||||
if (digit > 10) {
|
||||
cpuinfo_log_warning("non-decimal suffix %.*s in /proc/cpuinfo processor number is ignored",
|
||||
(int) (processor_end - digit_ptr), digit_ptr);
|
||||
break;
|
||||
}
|
||||
|
||||
processor_number = processor_number * 10 + digit;
|
||||
}
|
||||
|
||||
return processor_number;
|
||||
}
|
||||
|
||||
/*
|
||||
* Full list of ARM features reported in /proc/cpuinfo:
|
||||
*
|
||||
* * swp - support for SWP instruction (deprecated in ARMv7, can be removed in future)
|
||||
* * half - support for half-word loads and stores. These instruction are part of ARMv4,
|
||||
* so no need to check it on supported CPUs.
|
||||
* * thumb - support for 16-bit Thumb instruction set. Note that BX instruction is detected
|
||||
* by ARMv4T architecture, not by this flag.
|
||||
* * 26bit - old CPUs merged 26-bit PC and program status register (flags) into 32-bit PC
|
||||
* and had special instructions for working with packed PC. Now it is all deprecated.
|
||||
* * fastmult - most old ARM CPUs could only compute 2 bits of multiplication result per clock
|
||||
* cycle, but CPUs with M suffix (e.g. ARM7TDMI) could compute 4 bits per cycle.
|
||||
* Of course, now it makes no sense.
|
||||
* * fpa - floating point accelerator available. On original ARM ABI all floating-point operations
|
||||
* generated FPA instructions. If FPA was not available, these instructions generated
|
||||
* "illegal operation" interrupts, and the OS processed them by emulating the FPA instructions.
|
||||
* Debian used this ABI before it switched to EABI. Now FPA is deprecated.
|
||||
* * vfp - vector floating point instructions. Available on most modern CPUs (as part of VFPv3).
|
||||
* Required by Android ARMv7A ABI and by Ubuntu on ARM.
|
||||
* Note: there is no flag for VFPv2.
|
||||
* * edsp - V5E instructions: saturating add/sub and 16-bit x 16-bit -> 32/64-bit multiplications.
|
||||
* Required on Android, supported by all CPUs in production.
|
||||
* * java - Jazelle extension. Supported on most CPUs.
|
||||
* * iwmmxt - Intel/Marvell Wireless MMX instructions. 64-bit integer SIMD.
|
||||
* Supported on XScale (Since PXA270) and Sheeva (PJ1, PJ4) architectures.
|
||||
* Note that there is no flag for WMMX2 instructions.
|
||||
* * crunch - Maverick Crunch instructions. Junk.
|
||||
* * thumbee - ThumbEE instructions. Almost no documentation is available.
|
||||
* * neon - NEON instructions (aka Advanced SIMD). MVFR1 register gives more
|
||||
* fine-grained information on particular supported features, but
|
||||
* the Linux kernel exports only a single flag for all of them.
|
||||
* According to ARMv7A docs it also implies the availability of VFPv3
|
||||
* (with 32 double-precision registers d0-d31).
|
||||
* * vfpv3 - VFPv3 instructions. Available on most modern CPUs. Augment VFPv2 by
|
||||
* conversion to/from integers and load constant instructions.
|
||||
* Required by Android ARMv7A ABI and by Ubuntu on ARM.
|
||||
* * vfpv3d16 - VFPv3 instructions with only 16 double-precision registers (d0-d15).
|
||||
* * tls - software thread ID registers.
|
||||
* Used by kernel (and likely libc) for efficient implementation of TLS.
|
||||
* * vfpv4 - fused multiply-add instructions.
|
||||
* * idiva - DIV instructions available in ARM mode.
|
||||
* * idivt - DIV instructions available in Thumb mode.
|
||||
* * vfpd32 - VFP (of any version) with 32 double-precision registers d0-d31.
|
||||
* * lpae - Large Physical Address Extension (physical address up to 40 bits).
|
||||
* * evtstrm - generation of Event Stream by timer.
|
||||
* * aes - AES instructions.
|
||||
* * pmull - Polinomial Multiplication instructions.
|
||||
* * sha1 - SHA1 instructions.
|
||||
* * sha2 - SHA2 instructions.
|
||||
* * crc32 - CRC32 instructions.
|
||||
*
|
||||
* /proc/cpuinfo on ARM is populated in file arch/arm/kernel/setup.c in Linux kernel
|
||||
* Note that some devices may use patched Linux kernels with different feature names.
|
||||
* However, the names above were checked on a large number of /proc/cpuinfo listings.
|
||||
*/
|
||||
static void parse_features(
|
||||
const char* features_start,
|
||||
const char* features_end,
|
||||
struct cpuinfo_arm_linux_processor processor[restrict static 1])
|
||||
{
|
||||
const char* feature_start = features_start;
|
||||
const char* feature_end;
|
||||
|
||||
/* Mark the features as valid */
|
||||
processor->flags |= CPUINFO_ARM_LINUX_VALID_FEATURES | CPUINFO_ARM_LINUX_VALID_PROCESSOR;
|
||||
|
||||
do {
|
||||
feature_end = feature_start + 1;
|
||||
for (; feature_end != features_end; feature_end++) {
|
||||
if (*feature_end == ' ') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
const size_t feature_length = (size_t) (feature_end - feature_start);
|
||||
|
||||
switch (feature_length) {
|
||||
case 2:
|
||||
if (memcmp(feature_start, "fp", feature_length) == 0) {
|
||||
#if CPUINFO_ARCH_ARM64
|
||||
processor->features |= CPUINFO_ARM_LINUX_FEATURE_FP;
|
||||
#endif
|
||||
#if CPUINFO_ARCH_ARM
|
||||
} else if (memcmp(feature_start, "wp", feature_length) == 0) {
|
||||
/*
|
||||
* Some AArch64 kernels, including the one on Nexus 5X,
|
||||
* erroneously report "swp" as "wp" to AArch32 programs
|
||||
*/
|
||||
processor->features |= CPUINFO_ARM_LINUX_FEATURE_SWP;
|
||||
#endif
|
||||
} else {
|
||||
goto unexpected;
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
if (memcmp(feature_start, "aes", feature_length) == 0) {
|
||||
#if CPUINFO_ARCH_ARM
|
||||
processor->features2 |= CPUINFO_ARM_LINUX_FEATURE2_AES;
|
||||
#elif CPUINFO_ARCH_ARM64
|
||||
processor->features |= CPUINFO_ARM_LINUX_FEATURE_AES;
|
||||
#endif
|
||||
#if CPUINFO_ARCH_ARM
|
||||
} else if (memcmp(feature_start, "swp", feature_length) == 0) {
|
||||
processor->features |= CPUINFO_ARM_LINUX_FEATURE_SWP;
|
||||
} else if (memcmp(feature_start, "fpa", feature_length) == 0) {
|
||||
processor->features |= CPUINFO_ARM_LINUX_FEATURE_FPA;
|
||||
} else if (memcmp(feature_start, "vfp", feature_length) == 0) {
|
||||
processor->features |= CPUINFO_ARM_LINUX_FEATURE_VFP;
|
||||
} else if (memcmp(feature_start, "tls", feature_length) == 0) {
|
||||
processor->features |= CPUINFO_ARM_LINUX_FEATURE_TLS;
|
||||
#endif /* CPUINFO_ARCH_ARM */
|
||||
} else {
|
||||
goto unexpected;
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
if (memcmp(feature_start, "sha1", feature_length) == 0) {
|
||||
#if CPUINFO_ARCH_ARM
|
||||
processor->features2 |= CPUINFO_ARM_LINUX_FEATURE2_SHA1;
|
||||
#elif CPUINFO_ARCH_ARM64
|
||||
processor->features |= CPUINFO_ARM_LINUX_FEATURE_SHA1;
|
||||
#endif
|
||||
} else if (memcmp(feature_start, "sha2", feature_length) == 0) {
|
||||
#if CPUINFO_ARCH_ARM
|
||||
processor->features2 |= CPUINFO_ARM_LINUX_FEATURE2_SHA2;
|
||||
#elif CPUINFO_ARCH_ARM64
|
||||
processor->features |= CPUINFO_ARM_LINUX_FEATURE_SHA2;
|
||||
#endif
|
||||
} else if (memcmp(feature_start, "fphp", feature_length) == 0) {
|
||||
#if CPUINFO_ARCH_ARM64
|
||||
processor->features |= CPUINFO_ARM_LINUX_FEATURE_FPHP;
|
||||
#endif
|
||||
} else if (memcmp(feature_start, "fcma", feature_length) == 0) {
|
||||
#if CPUINFO_ARCH_ARM64
|
||||
processor->features |= CPUINFO_ARM_LINUX_FEATURE_FCMA;
|
||||
#endif
|
||||
#if CPUINFO_ARCH_ARM
|
||||
} else if (memcmp(feature_start, "half", feature_length) == 0) {
|
||||
processor->features |= CPUINFO_ARM_LINUX_FEATURE_HALF;
|
||||
} else if (memcmp(feature_start, "edsp", feature_length) == 0) {
|
||||
processor->features |= CPUINFO_ARM_LINUX_FEATURE_EDSP;
|
||||
} else if (memcmp(feature_start, "java", feature_length) == 0) {
|
||||
processor->features |= CPUINFO_ARM_LINUX_FEATURE_JAVA;
|
||||
} else if (memcmp(feature_start, "neon", feature_length) == 0) {
|
||||
processor->features |= CPUINFO_ARM_LINUX_FEATURE_NEON;
|
||||
} else if (memcmp(feature_start, "lpae", feature_length) == 0) {
|
||||
processor->features |= CPUINFO_ARM_LINUX_FEATURE_LPAE;
|
||||
} else if (memcmp(feature_start, "tlsi", feature_length) == 0) {
|
||||
/*
|
||||
* Some AArch64 kernels, including the one on Nexus 5X,
|
||||
* erroneously report "tls" as "tlsi" to AArch32 programs
|
||||
*/
|
||||
processor->features |= CPUINFO_ARM_LINUX_FEATURE_TLS;
|
||||
#endif /* CPUINFO_ARCH_ARM */
|
||||
} else {
|
||||
goto unexpected;
|
||||
}
|
||||
break;
|
||||
case 5:
|
||||
if (memcmp(feature_start, "pmull", feature_length) == 0) {
|
||||
#if CPUINFO_ARCH_ARM
|
||||
processor->features2 |= CPUINFO_ARM_LINUX_FEATURE2_PMULL;
|
||||
#elif CPUINFO_ARCH_ARM64
|
||||
processor->features |= CPUINFO_ARM_LINUX_FEATURE_PMULL;
|
||||
#endif
|
||||
} else if (memcmp(feature_start, "crc32", feature_length) == 0) {
|
||||
#if CPUINFO_ARCH_ARM
|
||||
processor->features2 |= CPUINFO_ARM_LINUX_FEATURE2_CRC32;
|
||||
#elif CPUINFO_ARCH_ARM64
|
||||
processor->features |= CPUINFO_ARM_LINUX_FEATURE_CRC32;
|
||||
#endif
|
||||
} else if (memcmp(feature_start, "asimd", feature_length) == 0) {
|
||||
#if CPUINFO_ARCH_ARM64
|
||||
processor->features |= CPUINFO_ARM_LINUX_FEATURE_ASIMD;
|
||||
#endif
|
||||
} else if (memcmp(feature_start, "cpuid", feature_length) == 0) {
|
||||
#if CPUINFO_ARCH_ARM64
|
||||
processor->features |= CPUINFO_ARM_LINUX_FEATURE_CPUID;
|
||||
#endif
|
||||
} else if (memcmp(feature_start, "jscvt", feature_length) == 0) {
|
||||
#if CPUINFO_ARCH_ARM64
|
||||
processor->features |= CPUINFO_ARM_LINUX_FEATURE_JSCVT;
|
||||
#endif
|
||||
} else if (memcmp(feature_start, "lrcpc", feature_length) == 0) {
|
||||
#if CPUINFO_ARCH_ARM64
|
||||
processor->features |= CPUINFO_ARM_LINUX_FEATURE_LRCPC;
|
||||
#endif
|
||||
#if CPUINFO_ARCH_ARM
|
||||
} else if (memcmp(feature_start, "thumb", feature_length) == 0) {
|
||||
processor->features |= CPUINFO_ARM_LINUX_FEATURE_THUMB;
|
||||
} else if (memcmp(feature_start, "26bit", feature_length) == 0) {
|
||||
processor->features |= CPUINFO_ARM_LINUX_FEATURE_26BIT;
|
||||
} else if (memcmp(feature_start, "vfpv3", feature_length) == 0) {
|
||||
processor->features |= CPUINFO_ARM_LINUX_FEATURE_VFPV3;
|
||||
} else if (memcmp(feature_start, "vfpv4", feature_length) == 0) {
|
||||
processor->features |= CPUINFO_ARM_LINUX_FEATURE_VFPV4;
|
||||
} else if (memcmp(feature_start, "idiva", feature_length) == 0) {
|
||||
processor->features |= CPUINFO_ARM_LINUX_FEATURE_IDIVA;
|
||||
} else if (memcmp(feature_start, "idivt", feature_length) == 0) {
|
||||
processor->features |= CPUINFO_ARM_LINUX_FEATURE_IDIVT;
|
||||
#endif /* CPUINFO_ARCH_ARM */
|
||||
} else {
|
||||
goto unexpected;
|
||||
}
|
||||
break;
|
||||
#if CPUINFO_ARCH_ARM
|
||||
case 6:
|
||||
if (memcmp(feature_start, "iwmmxt", feature_length) == 0) {
|
||||
processor->features |= CPUINFO_ARM_LINUX_FEATURE_IWMMXT;
|
||||
} else if (memcmp(feature_start, "crunch", feature_length) == 0) {
|
||||
processor->features |= CPUINFO_ARM_LINUX_FEATURE_CRUNCH;
|
||||
} else if (memcmp(feature_start, "vfpd32", feature_length) == 0) {
|
||||
processor->features |= CPUINFO_ARM_LINUX_FEATURE_VFPD32;
|
||||
} else {
|
||||
goto unexpected;
|
||||
}
|
||||
break;
|
||||
#endif /* CPUINFO_ARCH_ARM */
|
||||
case 7:
|
||||
if (memcmp(feature_start, "evtstrm", feature_length) == 0) {
|
||||
processor->features |= CPUINFO_ARM_LINUX_FEATURE_EVTSTRM;
|
||||
} else if (memcmp(feature_start, "atomics", feature_length) == 0) {
|
||||
#if CPUINFO_ARCH_ARM64
|
||||
processor->features |= CPUINFO_ARM_LINUX_FEATURE_ATOMICS;
|
||||
#endif
|
||||
} else if (memcmp(feature_start, "asimdhp", feature_length) == 0) {
|
||||
#if CPUINFO_ARCH_ARM64
|
||||
processor->features |= CPUINFO_ARM_LINUX_FEATURE_ASIMDHP;
|
||||
#endif
|
||||
#if CPUINFO_ARCH_ARM
|
||||
} else if (memcmp(feature_start, "thumbee", feature_length) == 0) {
|
||||
processor->features |= CPUINFO_ARM_LINUX_FEATURE_THUMBEE;
|
||||
#endif /* CPUINFO_ARCH_ARM */
|
||||
} else {
|
||||
goto unexpected;
|
||||
}
|
||||
break;
|
||||
case 8:
|
||||
if (memcmp(feature_start, "asimdrdm", feature_length) == 0) {
|
||||
#if CPUINFO_ARCH_ARM64
|
||||
processor->features |= CPUINFO_ARM_LINUX_FEATURE_ASIMDRDM;
|
||||
#endif
|
||||
#if CPUINFO_ARCH_ARM
|
||||
} else if (memcmp(feature_start, "fastmult", feature_length) == 0) {
|
||||
processor->features |= CPUINFO_ARM_LINUX_FEATURE_FASTMULT;
|
||||
} else if (memcmp(feature_start, "vfpv3d16", feature_length) == 0) {
|
||||
processor->features |= CPUINFO_ARM_LINUX_FEATURE_VFPV3D16;
|
||||
#endif /* CPUINFO_ARCH_ARM */
|
||||
} else {
|
||||
goto unexpected;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
unexpected:
|
||||
cpuinfo_log_warning("unexpected /proc/cpuinfo feature \"%.*s\" is ignored",
|
||||
(int) feature_length, feature_start);
|
||||
break;
|
||||
}
|
||||
feature_start = feature_end;
|
||||
for (; feature_start != features_end; feature_start++) {
|
||||
if (*feature_start != ' ') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} while (feature_start != feature_end);
|
||||
}
|
||||
|
||||
static void parse_cpu_architecture(
|
||||
const char* cpu_architecture_start,
|
||||
const char* cpu_architecture_end,
|
||||
struct cpuinfo_arm_linux_processor processor[restrict static 1])
|
||||
{
|
||||
const size_t cpu_architecture_length = (size_t) (cpu_architecture_end - cpu_architecture_start);
|
||||
/* Early AArch64 kernels report "CPU architecture: AArch64" instead of a numeric value 8 */
|
||||
if (cpu_architecture_length == 7) {
|
||||
if (memcmp(cpu_architecture_start, "AArch64", cpu_architecture_length) == 0) {
|
||||
processor->midr = midr_set_architecture(processor->midr, UINT32_C(0xF));
|
||||
processor->architecture_version = 8;
|
||||
processor->flags |= CPUINFO_ARM_LINUX_VALID_ARCHITECTURE | CPUINFO_ARM_LINUX_VALID_PROCESSOR;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
uint32_t architecture = 0;
|
||||
const char* cpu_architecture_ptr = cpu_architecture_start;
|
||||
for (; cpu_architecture_ptr != cpu_architecture_end; cpu_architecture_ptr++) {
|
||||
const uint32_t digit = (*cpu_architecture_ptr) - '0';
|
||||
|
||||
/* Verify that CPU architecture is a decimal number */
|
||||
if (digit >= 10) {
|
||||
break;
|
||||
}
|
||||
|
||||
architecture = architecture * 10 + digit;
|
||||
}
|
||||
|
||||
if (cpu_architecture_ptr == cpu_architecture_start) {
|
||||
cpuinfo_log_warning("CPU architecture %.*s in /proc/cpuinfo is ignored due to non-digit at the beginning of the string",
|
||||
(int) cpu_architecture_length, cpu_architecture_start);
|
||||
} else {
|
||||
if (architecture != 0) {
|
||||
processor->architecture_version = architecture;
|
||||
processor->flags |= CPUINFO_ARM_LINUX_VALID_ARCHITECTURE | CPUINFO_ARM_LINUX_VALID_PROCESSOR;
|
||||
|
||||
for (; cpu_architecture_ptr != cpu_architecture_end; cpu_architecture_ptr++) {
|
||||
const char feature = *cpu_architecture_ptr;
|
||||
switch (feature) {
|
||||
#if CPUINFO_ARCH_ARM
|
||||
case 'T':
|
||||
processor->architecture_flags |= CPUINFO_ARM_LINUX_ARCH_T;
|
||||
break;
|
||||
case 'E':
|
||||
processor->architecture_flags |= CPUINFO_ARM_LINUX_ARCH_E;
|
||||
break;
|
||||
case 'J':
|
||||
processor->architecture_flags |= CPUINFO_ARM_LINUX_ARCH_J;
|
||||
break;
|
||||
#endif /* CPUINFO_ARCH_ARM */
|
||||
case ' ':
|
||||
case '\t':
|
||||
/* Ignore whitespace at the end */
|
||||
break;
|
||||
default:
|
||||
cpuinfo_log_warning("skipped unknown architectural feature '%c' for ARMv%"PRIu32,
|
||||
feature, architecture);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
cpuinfo_log_warning("CPU architecture %.*s in /proc/cpuinfo is ignored due to invalid value (0)",
|
||||
(int) cpu_architecture_length, cpu_architecture_start);
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t midr_architecture = UINT32_C(0xF);
|
||||
#if CPUINFO_ARCH_ARM
|
||||
switch (processor->architecture_version) {
|
||||
case 6:
|
||||
midr_architecture = UINT32_C(0x7); /* ARMv6 */
|
||||
break;
|
||||
case 5:
|
||||
if ((processor->architecture_flags & CPUINFO_ARM_LINUX_ARCH_TEJ) == CPUINFO_ARM_LINUX_ARCH_TEJ) {
|
||||
midr_architecture = UINT32_C(0x6); /* ARMv5TEJ */
|
||||
} else if ((processor->architecture_flags & CPUINFO_ARM_LINUX_ARCH_TE) == CPUINFO_ARM_LINUX_ARCH_TE) {
|
||||
midr_architecture = UINT32_C(0x5); /* ARMv5TE */
|
||||
} else {
|
||||
midr_architecture = UINT32_C(0x4); /* ARMv5T */
|
||||
}
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
processor->midr = midr_set_architecture(processor->midr, midr_architecture);
|
||||
}
|
||||
|
||||
static void parse_cpu_part(
|
||||
const char* cpu_part_start,
|
||||
const char* cpu_part_end,
|
||||
struct cpuinfo_arm_linux_processor processor[restrict static 1])
|
||||
{
|
||||
const size_t cpu_part_length = (size_t) (cpu_part_end - cpu_part_start);
|
||||
|
||||
/*
|
||||
* CPU part should contain hex prefix (0x) and one to three hex digits.
|
||||
* I have never seen less than three digits as a value of this field,
|
||||
* but I don't think it is impossible to see such values in future.
|
||||
* Value can not contain more than three hex digits since
|
||||
* Main ID Register (MIDR) assigns only a 12-bit value for CPU part.
|
||||
*/
|
||||
if (cpu_part_length < 3 || cpu_part_length > 5) {
|
||||
cpuinfo_log_warning("CPU part %.*s in /proc/cpuinfo is ignored due to unexpected length (%zu)",
|
||||
(int) cpu_part_length, cpu_part_start, cpu_part_length);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Verify the presence of hex prefix */
|
||||
if (cpu_part_start[0] != '0' || cpu_part_start[1] != 'x') {
|
||||
cpuinfo_log_warning("CPU part %.*s in /proc/cpuinfo is ignored due to lack of 0x prefix",
|
||||
(int) cpu_part_length, cpu_part_start);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Verify that characters after hex prefix are hexadecimal digits and decode them */
|
||||
uint32_t cpu_part = 0;
|
||||
for (const char* digit_ptr = cpu_part_start + 2; digit_ptr != cpu_part_end; digit_ptr++) {
|
||||
const char digit_char = *digit_ptr;
|
||||
uint32_t digit;
|
||||
if (digit_char >= '0' && digit_char <= '9') {
|
||||
digit = digit_char - '0';
|
||||
} else if ((uint32_t) (digit_char - 'A') < 6) {
|
||||
digit = 10 + (digit_char - 'A');
|
||||
} else if ((uint32_t) (digit_char - 'a') < 6) {
|
||||
digit = 10 + (digit_char - 'a');
|
||||
} else {
|
||||
cpuinfo_log_warning("CPU part %.*s in /proc/cpuinfo is ignored due to unexpected non-hex character %c at offset %zu",
|
||||
(int) cpu_part_length, cpu_part_start, digit_char, (size_t) (digit_ptr - cpu_part_start));
|
||||
return;
|
||||
}
|
||||
cpu_part = cpu_part * 16 + digit;
|
||||
}
|
||||
|
||||
processor->midr = midr_set_part(processor->midr, cpu_part);
|
||||
processor->flags |= CPUINFO_ARM_LINUX_VALID_PART | CPUINFO_ARM_LINUX_VALID_PROCESSOR;
|
||||
}
|
||||
|
||||
static void parse_cpu_implementer(
|
||||
const char* cpu_implementer_start,
|
||||
const char* cpu_implementer_end,
|
||||
struct cpuinfo_arm_linux_processor processor[restrict static 1])
|
||||
{
|
||||
const size_t cpu_implementer_length = cpu_implementer_end - cpu_implementer_start;
|
||||
|
||||
/*
|
||||
* Value should contain hex prefix (0x) and one or two hex digits.
|
||||
* I have never seen single hex digit as a value of this field,
|
||||
* but I don't think it is impossible in future.
|
||||
* Value can not contain more than two hex digits since
|
||||
* Main ID Register (MIDR) assigns only an 8-bit value for CPU implementer.
|
||||
*/
|
||||
switch (cpu_implementer_length) {
|
||||
case 3:
|
||||
case 4:
|
||||
break;
|
||||
default:
|
||||
cpuinfo_log_warning("CPU implementer %.*s in /proc/cpuinfo is ignored due to unexpected length (%zu)",
|
||||
(int) cpu_implementer_length, cpu_implementer_start, cpu_implementer_length);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Verify the presence of hex prefix */
|
||||
if (cpu_implementer_start[0] != '0' || cpu_implementer_start[1] != 'x') {
|
||||
cpuinfo_log_warning("CPU implementer %.*s in /proc/cpuinfo is ignored due to lack of 0x prefix",
|
||||
(int) cpu_implementer_length, cpu_implementer_start);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Verify that characters after hex prefix are hexadecimal digits and decode them */
|
||||
uint32_t cpu_implementer = 0;
|
||||
for (const char* digit_ptr = cpu_implementer_start + 2; digit_ptr != cpu_implementer_end; digit_ptr++) {
|
||||
const char digit_char = *digit_ptr;
|
||||
uint32_t digit;
|
||||
if (digit_char >= '0' && digit_char <= '9') {
|
||||
digit = digit_char - '0';
|
||||
} else if ((uint32_t) (digit_char - 'A') < 6) {
|
||||
digit = 10 + (digit_char - 'A');
|
||||
} else if ((uint32_t) (digit_char - 'a') < 6) {
|
||||
digit = 10 + (digit_char - 'a');
|
||||
} else {
|
||||
cpuinfo_log_warning("CPU implementer %.*s in /proc/cpuinfo is ignored due to unexpected non-hex character '%c' at offset %zu",
|
||||
(int) cpu_implementer_length, cpu_implementer_start, digit_char, (size_t) (digit_ptr - cpu_implementer_start));
|
||||
return;
|
||||
}
|
||||
cpu_implementer = cpu_implementer * 16 + digit;
|
||||
}
|
||||
|
||||
processor->midr = midr_set_implementer(processor->midr, cpu_implementer);
|
||||
processor->flags |= CPUINFO_ARM_LINUX_VALID_IMPLEMENTER | CPUINFO_ARM_LINUX_VALID_PROCESSOR;
|
||||
}
|
||||
|
||||
static void parse_cpu_variant(
|
||||
const char* cpu_variant_start,
|
||||
const char* cpu_variant_end,
|
||||
struct cpuinfo_arm_linux_processor processor[restrict static 1])
|
||||
{
|
||||
const size_t cpu_variant_length = cpu_variant_end - cpu_variant_start;
|
||||
|
||||
/*
|
||||
* Value should contain hex prefix (0x) and one hex digit.
|
||||
* Value can not contain more than one hex digits since
|
||||
* Main ID Register (MIDR) assigns only a 4-bit value for CPU variant.
|
||||
*/
|
||||
if (cpu_variant_length != 3) {
|
||||
cpuinfo_log_warning("CPU variant %.*s in /proc/cpuinfo is ignored due to unexpected length (%zu)",
|
||||
(int) cpu_variant_length, cpu_variant_start, cpu_variant_length);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Skip if there is no hex prefix (0x) */
|
||||
if (cpu_variant_start[0] != '0' || cpu_variant_start[1] != 'x') {
|
||||
cpuinfo_log_warning("CPU variant %.*s in /proc/cpuinfo is ignored due to lack of 0x prefix",
|
||||
(int) cpu_variant_length, cpu_variant_start);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Check if the value after hex prefix is indeed a hex digit and decode it. */
|
||||
const char digit_char = cpu_variant_start[2];
|
||||
uint32_t cpu_variant;
|
||||
if ((uint32_t) (digit_char - '0') < 10) {
|
||||
cpu_variant = (uint32_t) (digit_char - '0');
|
||||
} else if ((uint32_t) (digit_char - 'A') < 6) {
|
||||
cpu_variant = 10 + (uint32_t) (digit_char - 'A');
|
||||
} else if ((uint32_t) (digit_char - 'a') < 6) {
|
||||
cpu_variant = 10 + (uint32_t) (digit_char - 'a');
|
||||
} else {
|
||||
cpuinfo_log_warning("CPU variant %.*s in /proc/cpuinfo is ignored due to unexpected non-hex character '%c'",
|
||||
(int) cpu_variant_length, cpu_variant_start, digit_char);
|
||||
return;
|
||||
}
|
||||
|
||||
processor->midr = midr_set_variant(processor->midr, cpu_variant);
|
||||
processor->flags |= CPUINFO_ARM_LINUX_VALID_VARIANT | CPUINFO_ARM_LINUX_VALID_PROCESSOR;
|
||||
}
|
||||
|
||||
static void parse_cpu_revision(
|
||||
const char* cpu_revision_start,
|
||||
const char* cpu_revision_end,
|
||||
struct cpuinfo_arm_linux_processor processor[restrict static 1])
|
||||
{
|
||||
uint32_t cpu_revision = 0;
|
||||
for (const char* digit_ptr = cpu_revision_start; digit_ptr != cpu_revision_end; digit_ptr++) {
|
||||
const uint32_t digit = (uint32_t) (*digit_ptr - '0');
|
||||
|
||||
/* Verify that the character in CPU revision is a decimal digit */
|
||||
if (digit >= 10) {
|
||||
cpuinfo_log_warning("CPU revision %.*s in /proc/cpuinfo is ignored due to unexpected non-digit character '%c' at offset %zu",
|
||||
(int) (cpu_revision_end - cpu_revision_start), cpu_revision_start,
|
||||
*digit_ptr, (size_t) (digit_ptr - cpu_revision_start));
|
||||
return;
|
||||
}
|
||||
|
||||
cpu_revision = cpu_revision * 10 + digit;
|
||||
}
|
||||
|
||||
processor->midr = midr_set_revision(processor->midr, cpu_revision);
|
||||
processor->flags |= CPUINFO_ARM_LINUX_VALID_REVISION | CPUINFO_ARM_LINUX_VALID_PROCESSOR;
|
||||
}
|
||||
|
||||
#if CPUINFO_ARCH_ARM
|
||||
/*
|
||||
* Decode one of the cache-related numbers reported by Linux kernel
|
||||
* for pre-ARMv7 architecture.
|
||||
* An example cache-related information in /proc/cpuinfo:
|
||||
*
|
||||
* I size : 32768
|
||||
* I assoc : 4
|
||||
* I line length : 32
|
||||
* I sets : 256
|
||||
* D size : 16384
|
||||
* D assoc : 4
|
||||
* D line length : 32
|
||||
* D sets : 128
|
||||
*
|
||||
*/
|
||||
static void parse_cache_number(
|
||||
const char* number_start,
|
||||
const char* number_end,
|
||||
const char* number_name,
|
||||
uint32_t number_ptr[restrict static 1],
|
||||
uint32_t flags[restrict static 1],
|
||||
uint32_t number_mask)
|
||||
{
|
||||
uint32_t number = 0;
|
||||
for (const char* digit_ptr = number_start; digit_ptr != number_end; digit_ptr++) {
|
||||
const uint32_t digit = *digit_ptr - '0';
|
||||
if (digit >= 10) {
|
||||
cpuinfo_log_warning("%s %.*s in /proc/cpuinfo is ignored due to unexpected non-digit character '%c' at offset %zu",
|
||||
number_name, (int) (number_end - number_start), number_start,
|
||||
*digit_ptr, (size_t) (digit_ptr - number_start));
|
||||
return;
|
||||
}
|
||||
|
||||
number = number * 10 + digit;
|
||||
}
|
||||
|
||||
if (number == 0) {
|
||||
cpuinfo_log_warning("%s %.*s in /proc/cpuinfo is ignored due to invalid value of zero reported by the kernel",
|
||||
number_name, (int) (number_end - number_start), number_start);
|
||||
}
|
||||
|
||||
/* If the number specifies a cache line size, verify that is a reasonable power of 2 */
|
||||
if (number_mask & CPUINFO_ARM_LINUX_VALID_CACHE_LINE) {
|
||||
switch (number) {
|
||||
case 16:
|
||||
case 32:
|
||||
case 64:
|
||||
case 128:
|
||||
break;
|
||||
default:
|
||||
cpuinfo_log_warning("invalid %s %.*s is ignored: a value of 16, 32, 64, or 128 expected",
|
||||
number_name, (int) (number_end - number_start), number_start);
|
||||
}
|
||||
}
|
||||
|
||||
*number_ptr = number;
|
||||
*flags |= number_mask | CPUINFO_ARM_LINUX_VALID_PROCESSOR;
|
||||
}
|
||||
#endif /* CPUINFO_ARCH_ARM */
|
||||
|
||||
struct proc_cpuinfo_parser_state {
|
||||
char* hardware;
|
||||
char* revision;
|
||||
uint32_t processor_index;
|
||||
uint32_t max_processors_count;
|
||||
struct cpuinfo_arm_linux_processor* processors;
|
||||
struct cpuinfo_arm_linux_processor dummy_processor;
|
||||
};
|
||||
|
||||
/*
|
||||
* Decode a single line of /proc/cpuinfo information.
|
||||
* Lines have format <words-with-spaces>[ ]*:[ ]<space-separated words>
|
||||
* An example of /proc/cpuinfo (from Pandaboard-ES):
|
||||
*
|
||||
* Processor : ARMv7 Processor rev 10 (v7l)
|
||||
* processor : 0
|
||||
* BogoMIPS : 1392.74
|
||||
*
|
||||
* processor : 1
|
||||
* BogoMIPS : 1363.33
|
||||
*
|
||||
* Features : swp half thumb fastmult vfp edsp thumbee neon vfpv3
|
||||
* CPU implementer : 0x41
|
||||
* CPU architecture: 7
|
||||
* CPU variant : 0x2
|
||||
* CPU part : 0xc09
|
||||
* CPU revision : 10
|
||||
*
|
||||
* Hardware : OMAP4 Panda board
|
||||
* Revision : 0020
|
||||
* Serial : 0000000000000000
|
||||
*/
|
||||
static bool parse_line(
|
||||
const char* line_start,
|
||||
const char* line_end,
|
||||
struct proc_cpuinfo_parser_state state[restrict static 1],
|
||||
uint64_t line_number)
|
||||
{
|
||||
/* Empty line. Skip. */
|
||||
if (line_start == line_end) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Search for ':' on the line. */
|
||||
const char* separator = line_start;
|
||||
for (; separator != line_end; separator++) {
|
||||
if (*separator == ':') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* Skip line if no ':' separator was found. */
|
||||
if (separator == line_end) {
|
||||
cpuinfo_log_info("Line %.*s in /proc/cpuinfo is ignored: key/value separator ':' not found",
|
||||
(int) (line_end - line_start), line_start);
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Skip trailing spaces in key part. */
|
||||
const char* key_end = separator;
|
||||
for (; key_end != line_start; key_end--) {
|
||||
if (key_end[-1] != ' ' && key_end[-1] != '\t') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* Skip line if key contains nothing but spaces. */
|
||||
if (key_end == line_start) {
|
||||
cpuinfo_log_info("Line %.*s in /proc/cpuinfo is ignored: key contains only spaces",
|
||||
(int) (line_end - line_start), line_start);
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Skip leading spaces in value part. */
|
||||
const char* value_start = separator + 1;
|
||||
for (; value_start != line_end; value_start++) {
|
||||
if (*value_start != ' ') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* Value part contains nothing but spaces. Skip line. */
|
||||
if (value_start == line_end) {
|
||||
cpuinfo_log_info("Line %.*s in /proc/cpuinfo is ignored: value contains only spaces",
|
||||
(int) (line_end - line_start), line_start);
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Skip trailing spaces in value part (if any) */
|
||||
const char* value_end = line_end;
|
||||
for (; value_end != value_start; value_end--) {
|
||||
if (value_end[-1] != ' ') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const uint32_t processor_index = state->processor_index;
|
||||
const uint32_t max_processors_count = state->max_processors_count;
|
||||
struct cpuinfo_arm_linux_processor* processors = state->processors;
|
||||
struct cpuinfo_arm_linux_processor* processor = &state->dummy_processor;
|
||||
if (processor_index < max_processors_count) {
|
||||
processor = &processors[processor_index];
|
||||
}
|
||||
|
||||
const size_t key_length = key_end - line_start;
|
||||
switch (key_length) {
|
||||
case 6:
|
||||
if (memcmp(line_start, "Serial", key_length) == 0) {
|
||||
/* Usually contains just zeros, useless */
|
||||
#if CPUINFO_ARCH_ARM
|
||||
} else if (memcmp(line_start, "I size", key_length) == 0) {
|
||||
parse_cache_number(value_start, value_end,
|
||||
"instruction cache size", &processor->proc_cpuinfo_cache.i_size,
|
||||
&processor->flags, CPUINFO_ARM_LINUX_VALID_ICACHE_SIZE);
|
||||
} else if (memcmp(line_start, "I sets", key_length) == 0) {
|
||||
parse_cache_number(value_start, value_end,
|
||||
"instruction cache sets", &processor->proc_cpuinfo_cache.i_sets,
|
||||
&processor->flags, CPUINFO_ARM_LINUX_VALID_ICACHE_SETS);
|
||||
} else if (memcmp(line_start, "D size", key_length) == 0) {
|
||||
parse_cache_number(value_start, value_end,
|
||||
"data cache size", &processor->proc_cpuinfo_cache.d_size,
|
||||
&processor->flags, CPUINFO_ARM_LINUX_VALID_DCACHE_SIZE);
|
||||
} else if (memcmp(line_start, "D sets", key_length) == 0) {
|
||||
parse_cache_number(value_start, value_end,
|
||||
"data cache sets", &processor->proc_cpuinfo_cache.d_sets,
|
||||
&processor->flags, CPUINFO_ARM_LINUX_VALID_DCACHE_SETS);
|
||||
#endif /* CPUINFO_ARCH_ARM */
|
||||
} else {
|
||||
goto unknown;
|
||||
}
|
||||
break;
|
||||
#if CPUINFO_ARCH_ARM
|
||||
case 7:
|
||||
if (memcmp(line_start, "I assoc", key_length) == 0) {
|
||||
parse_cache_number(value_start, value_end,
|
||||
"instruction cache associativity", &processor->proc_cpuinfo_cache.i_assoc,
|
||||
&processor->flags, CPUINFO_ARM_LINUX_VALID_ICACHE_WAYS);
|
||||
} else if (memcmp(line_start, "D assoc", key_length) == 0) {
|
||||
parse_cache_number(value_start, value_end,
|
||||
"data cache associativity", &processor->proc_cpuinfo_cache.d_assoc,
|
||||
&processor->flags, CPUINFO_ARM_LINUX_VALID_DCACHE_WAYS);
|
||||
} else {
|
||||
goto unknown;
|
||||
}
|
||||
break;
|
||||
#endif /* CPUINFO_ARCH_ARM */
|
||||
case 8:
|
||||
if (memcmp(line_start, "CPU part", key_length) == 0) {
|
||||
parse_cpu_part(value_start, value_end, processor);
|
||||
} else if (memcmp(line_start, "Features", key_length) == 0) {
|
||||
parse_features(value_start, value_end, processor);
|
||||
} else if (memcmp(line_start, "BogoMIPS", key_length) == 0) {
|
||||
/* BogoMIPS is useless, don't parse */
|
||||
} else if (memcmp(line_start, "Hardware", key_length) == 0) {
|
||||
size_t value_length = value_end - value_start;
|
||||
if (value_length > CPUINFO_HARDWARE_VALUE_MAX) {
|
||||
cpuinfo_log_info(
|
||||
"length of Hardware value \"%.*s\" in /proc/cpuinfo exceeds limit (%d): truncating to the limit",
|
||||
(int) value_length, value_start, CPUINFO_HARDWARE_VALUE_MAX);
|
||||
value_length = CPUINFO_HARDWARE_VALUE_MAX;
|
||||
} else {
|
||||
state->hardware[value_length] = '\0';
|
||||
}
|
||||
memcpy(state->hardware, value_start, value_length);
|
||||
cpuinfo_log_debug("parsed /proc/cpuinfo Hardware = \"%.*s\"", (int) value_length, value_start);
|
||||
} else if (memcmp(line_start, "Revision", key_length) == 0) {
|
||||
size_t value_length = value_end - value_start;
|
||||
if (value_length > CPUINFO_REVISION_VALUE_MAX) {
|
||||
cpuinfo_log_info(
|
||||
"length of Revision value \"%.*s\" in /proc/cpuinfo exceeds limit (%d): truncating to the limit",
|
||||
(int) value_length, value_start, CPUINFO_REVISION_VALUE_MAX);
|
||||
value_length = CPUINFO_REVISION_VALUE_MAX;
|
||||
} else {
|
||||
state->revision[value_length] = '\0';
|
||||
}
|
||||
memcpy(state->revision, value_start, value_length);
|
||||
cpuinfo_log_debug("parsed /proc/cpuinfo Revision = \"%.*s\"", (int) value_length, value_start);
|
||||
} else {
|
||||
goto unknown;
|
||||
}
|
||||
break;
|
||||
case 9:
|
||||
if (memcmp(line_start, "processor", key_length) == 0) {
|
||||
const uint32_t new_processor_index = parse_processor_number(value_start, value_end);
|
||||
if (new_processor_index < processor_index) {
|
||||
/* Strange: decreasing processor number */
|
||||
cpuinfo_log_warning(
|
||||
"unexpectedly low processor number %"PRIu32" following processor %"PRIu32" in /proc/cpuinfo",
|
||||
new_processor_index, processor_index);
|
||||
} else if (new_processor_index > processor_index + 1) {
|
||||
/* Strange, but common: skipped processor $(processor_index + 1) */
|
||||
cpuinfo_log_info(
|
||||
"unexpectedly high processor number %"PRIu32" following processor %"PRIu32" in /proc/cpuinfo",
|
||||
new_processor_index, processor_index);
|
||||
}
|
||||
if (new_processor_index < max_processors_count) {
|
||||
/* Record that the processor was mentioned in /proc/cpuinfo */
|
||||
processors[new_processor_index].flags |= CPUINFO_ARM_LINUX_VALID_PROCESSOR;
|
||||
} else {
|
||||
/* Log and ignore processor */
|
||||
cpuinfo_log_warning("processor %"PRIu32" in /proc/cpuinfo is ignored: index exceeds system limit %"PRIu32,
|
||||
new_processor_index, max_processors_count - 1);
|
||||
}
|
||||
state->processor_index = new_processor_index;
|
||||
return true;
|
||||
} else if (memcmp(line_start, "Processor", key_length) == 0) {
|
||||
/* TODO: parse to fix misreported architecture, similar to Android's cpufeatures */
|
||||
} else {
|
||||
goto unknown;
|
||||
}
|
||||
break;
|
||||
case 11:
|
||||
if (memcmp(line_start, "CPU variant", key_length) == 0) {
|
||||
parse_cpu_variant(value_start, value_end, processor);
|
||||
} else {
|
||||
goto unknown;
|
||||
}
|
||||
break;
|
||||
case 12:
|
||||
if (memcmp(line_start, "CPU revision", key_length) == 0) {
|
||||
parse_cpu_revision(value_start, value_end, processor);
|
||||
} else {
|
||||
goto unknown;
|
||||
}
|
||||
break;
|
||||
#if CPUINFO_ARCH_ARM
|
||||
case 13:
|
||||
if (memcmp(line_start, "I line length", key_length) == 0) {
|
||||
parse_cache_number(value_start, value_end,
|
||||
"instruction cache line size", &processor->proc_cpuinfo_cache.i_line_length,
|
||||
&processor->flags, CPUINFO_ARM_LINUX_VALID_ICACHE_LINE);
|
||||
} else if (memcmp(line_start, "D line length", key_length) == 0) {
|
||||
parse_cache_number(value_start, value_end,
|
||||
"data cache line size", &processor->proc_cpuinfo_cache.d_line_length,
|
||||
&processor->flags, CPUINFO_ARM_LINUX_VALID_DCACHE_LINE);
|
||||
} else {
|
||||
goto unknown;
|
||||
}
|
||||
break;
|
||||
#endif /* CPUINFO_ARCH_ARM */
|
||||
case 15:
|
||||
if (memcmp(line_start, "CPU implementer", key_length) == 0) {
|
||||
parse_cpu_implementer(value_start, value_end, processor);
|
||||
} else if (memcmp(line_start, "CPU implementor", key_length) == 0) {
|
||||
parse_cpu_implementer(value_start, value_end, processor);
|
||||
} else {
|
||||
goto unknown;
|
||||
}
|
||||
break;
|
||||
case 16:
|
||||
if (memcmp(line_start, "CPU architecture", key_length) == 0) {
|
||||
parse_cpu_architecture(value_start, value_end, processor);
|
||||
} else {
|
||||
goto unknown;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
unknown:
|
||||
cpuinfo_log_debug("unknown /proc/cpuinfo key: %.*s", (int) key_length, line_start);
|
||||
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool cpuinfo_arm_linux_parse_proc_cpuinfo(
|
||||
char hardware[restrict static CPUINFO_HARDWARE_VALUE_MAX],
|
||||
char revision[restrict static CPUINFO_REVISION_VALUE_MAX],
|
||||
uint32_t max_processors_count,
|
||||
struct cpuinfo_arm_linux_processor processors[restrict static max_processors_count])
|
||||
{
|
||||
struct proc_cpuinfo_parser_state state = {
|
||||
.hardware = hardware,
|
||||
.revision = revision,
|
||||
.processor_index = 0,
|
||||
.max_processors_count = max_processors_count,
|
||||
.processors = processors,
|
||||
};
|
||||
return cpuinfo_linux_parse_multiline_file("/proc/cpuinfo", BUFFER_SIZE,
|
||||
(cpuinfo_line_callback) parse_line, &state);
|
||||
}
|
||||
159
3rdparty/cpuinfo/src/arm/linux/hwcap.c
vendored
Normal file
159
3rdparty/cpuinfo/src/arm/linux/hwcap.c
vendored
Normal file
@@ -0,0 +1,159 @@
|
||||
#include <string.h>
|
||||
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <dlfcn.h>
|
||||
#include <elf.h>
|
||||
|
||||
#if CPUINFO_MOCK
|
||||
#include <cpuinfo-mock.h>
|
||||
#endif
|
||||
#include <cpuinfo.h>
|
||||
#include <arm/linux/api.h>
|
||||
#include <cpuinfo/log.h>
|
||||
|
||||
#if CPUINFO_ARCH_ARM64 || CPUINFO_ARCH_ARM && !defined(__ANDROID__)
|
||||
#include <sys/auxv.h>
|
||||
#else
|
||||
#define AT_HWCAP 16
|
||||
#define AT_HWCAP2 26
|
||||
#endif
|
||||
|
||||
|
||||
#if CPUINFO_MOCK
|
||||
static uint32_t mock_hwcap = 0;
|
||||
void cpuinfo_set_hwcap(uint32_t hwcap) {
|
||||
mock_hwcap = hwcap;
|
||||
}
|
||||
|
||||
static uint32_t mock_hwcap2 = 0;
|
||||
void cpuinfo_set_hwcap2(uint32_t hwcap2) {
|
||||
mock_hwcap2 = hwcap2;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#if CPUINFO_ARCH_ARM
|
||||
typedef unsigned long (*getauxval_function_t)(unsigned long);
|
||||
|
||||
bool cpuinfo_arm_linux_hwcap_from_getauxval(
|
||||
uint32_t hwcap[restrict static 1],
|
||||
uint32_t hwcap2[restrict static 1])
|
||||
{
|
||||
#if CPUINFO_MOCK
|
||||
*hwcap = mock_hwcap;
|
||||
*hwcap2 = mock_hwcap2;
|
||||
return true;
|
||||
#elif defined(__ANDROID__)
|
||||
/* Android: dynamically check if getauxval is supported */
|
||||
void* libc = NULL;
|
||||
getauxval_function_t getauxval = NULL;
|
||||
|
||||
dlerror();
|
||||
libc = dlopen("libc.so", RTLD_LAZY);
|
||||
if (libc == NULL) {
|
||||
cpuinfo_log_warning("failed to load libc.so: %s", dlerror());
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
getauxval = (getauxval_function_t) dlsym(libc, "getauxval");
|
||||
if (getauxval == NULL) {
|
||||
cpuinfo_log_info("failed to locate getauxval in libc.so: %s", dlerror());
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
*hwcap = getauxval(AT_HWCAP);
|
||||
*hwcap2 = getauxval(AT_HWCAP2);
|
||||
|
||||
cleanup:
|
||||
if (libc != NULL) {
|
||||
dlclose(libc);
|
||||
libc = NULL;
|
||||
}
|
||||
return getauxval != NULL;
|
||||
#else
|
||||
/* GNU/Linux: getauxval is always supported */
|
||||
*hwcap = getauxval(AT_HWCAP);
|
||||
*hwcap2 = getauxval(AT_HWCAP2);
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef __ANDROID__
|
||||
bool cpuinfo_arm_linux_hwcap_from_procfs(
|
||||
uint32_t hwcap[restrict static 1],
|
||||
uint32_t hwcap2[restrict static 1])
|
||||
{
|
||||
#if CPUINFO_MOCK
|
||||
*hwcap = mock_hwcap;
|
||||
*hwcap2 = mock_hwcap2;
|
||||
return true;
|
||||
#else
|
||||
uint32_t hwcaps[2] = { 0, 0 };
|
||||
bool result = false;
|
||||
int file = -1;
|
||||
|
||||
file = open("/proc/self/auxv", O_RDONLY);
|
||||
if (file == -1) {
|
||||
cpuinfo_log_warning("failed to open /proc/self/auxv: %s", strerror(errno));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
ssize_t bytes_read;
|
||||
do {
|
||||
Elf32_auxv_t elf_auxv;
|
||||
bytes_read = read(file, &elf_auxv, sizeof(Elf32_auxv_t));
|
||||
if (bytes_read < 0) {
|
||||
cpuinfo_log_warning("failed to read /proc/self/auxv: %s", strerror(errno));
|
||||
goto cleanup;
|
||||
} else if (bytes_read > 0) {
|
||||
if (bytes_read == sizeof(elf_auxv)) {
|
||||
switch (elf_auxv.a_type) {
|
||||
case AT_HWCAP:
|
||||
hwcaps[0] = (uint32_t) elf_auxv.a_un.a_val;
|
||||
break;
|
||||
case AT_HWCAP2:
|
||||
hwcaps[1] = (uint32_t) elf_auxv.a_un.a_val;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
cpuinfo_log_warning(
|
||||
"failed to read %zu bytes from /proc/self/auxv: %zu bytes available",
|
||||
sizeof(elf_auxv), (size_t) bytes_read);
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
} while (bytes_read == sizeof(Elf32_auxv_t));
|
||||
|
||||
/* Success, commit results */
|
||||
*hwcap = hwcaps[0];
|
||||
*hwcap2 = hwcaps[1];
|
||||
result = true;
|
||||
|
||||
cleanup:
|
||||
if (file != -1) {
|
||||
close(file);
|
||||
file = -1;
|
||||
}
|
||||
return result;
|
||||
#endif
|
||||
}
|
||||
#endif /* __ANDROID__ */
|
||||
#elif CPUINFO_ARCH_ARM64
|
||||
void cpuinfo_arm_linux_hwcap_from_getauxval(
|
||||
uint32_t hwcap[restrict static 1],
|
||||
uint32_t hwcap2[restrict static 1])
|
||||
{
|
||||
#if CPUINFO_MOCK
|
||||
*hwcap = mock_hwcap;
|
||||
*hwcap2 = mock_hwcap2;
|
||||
#else
|
||||
*hwcap = (uint32_t) getauxval(AT_HWCAP);
|
||||
*hwcap2 = (uint32_t) getauxval(AT_HWCAP2);
|
||||
return ;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
765
3rdparty/cpuinfo/src/arm/linux/init.c
vendored
Normal file
765
3rdparty/cpuinfo/src/arm/linux/init.c
vendored
Normal file
@@ -0,0 +1,765 @@
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <cpuinfo.h>
|
||||
#include <arm/linux/api.h>
|
||||
#if defined(__ANDROID__)
|
||||
#include <arm/android/api.h>
|
||||
#endif
|
||||
#include <arm/api.h>
|
||||
#include <arm/midr.h>
|
||||
#include <linux/api.h>
|
||||
#include <cpuinfo/internal-api.h>
|
||||
#include <cpuinfo/log.h>
|
||||
|
||||
|
||||
struct cpuinfo_arm_isa cpuinfo_isa = { 0 };
|
||||
|
||||
static struct cpuinfo_package package = { { 0 } };
|
||||
|
||||
static inline bool bitmask_all(uint32_t bitfield, uint32_t mask) {
|
||||
return (bitfield & mask) == mask;
|
||||
}
|
||||
|
||||
static inline uint32_t min(uint32_t a, uint32_t b) {
|
||||
return a < b ? a : b;
|
||||
}
|
||||
|
||||
static inline int cmp(uint32_t a, uint32_t b) {
|
||||
return (a > b) - (a < b);
|
||||
}
|
||||
|
||||
static bool cluster_siblings_parser(
|
||||
uint32_t processor, uint32_t siblings_start, uint32_t siblings_end,
|
||||
struct cpuinfo_arm_linux_processor* processors)
|
||||
{
|
||||
processors[processor].flags |= CPUINFO_LINUX_FLAG_PACKAGE_CLUSTER;
|
||||
uint32_t package_leader_id = processors[processor].package_leader_id;
|
||||
|
||||
for (uint32_t sibling = siblings_start; sibling < siblings_end; sibling++) {
|
||||
if (!bitmask_all(processors[sibling].flags, CPUINFO_LINUX_FLAG_VALID)) {
|
||||
cpuinfo_log_info("invalid processor %"PRIu32" reported as a sibling for processor %"PRIu32,
|
||||
sibling, processor);
|
||||
continue;
|
||||
}
|
||||
|
||||
const uint32_t sibling_package_leader_id = processors[sibling].package_leader_id;
|
||||
if (sibling_package_leader_id < package_leader_id) {
|
||||
package_leader_id = sibling_package_leader_id;
|
||||
}
|
||||
|
||||
processors[sibling].package_leader_id = package_leader_id;
|
||||
processors[sibling].flags |= CPUINFO_LINUX_FLAG_PACKAGE_CLUSTER;
|
||||
}
|
||||
|
||||
processors[processor].package_leader_id = package_leader_id;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static int cmp_arm_linux_processor(const void* ptr_a, const void* ptr_b) {
|
||||
const struct cpuinfo_arm_linux_processor* processor_a = (const struct cpuinfo_arm_linux_processor*) ptr_a;
|
||||
const struct cpuinfo_arm_linux_processor* processor_b = (const struct cpuinfo_arm_linux_processor*) ptr_b;
|
||||
|
||||
/* Move usable processors towards the start of the array */
|
||||
const bool usable_a = bitmask_all(processor_a->flags, CPUINFO_LINUX_FLAG_VALID);
|
||||
const bool usable_b = bitmask_all(processor_b->flags, CPUINFO_LINUX_FLAG_VALID);
|
||||
if (usable_a != usable_b) {
|
||||
return (int) usable_b - (int) usable_a;
|
||||
}
|
||||
|
||||
/* Compare based on core type (e.g. Cortex-A57 < Cortex-A53) */
|
||||
const uint32_t midr_a = processor_a->midr;
|
||||
const uint32_t midr_b = processor_b->midr;
|
||||
if (midr_a != midr_b) {
|
||||
const uint32_t score_a = midr_score_core(midr_a);
|
||||
const uint32_t score_b = midr_score_core(midr_b);
|
||||
if (score_a != score_b) {
|
||||
return score_a > score_b ? -1 : 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Compare based on core frequency (e.g. 2.0 GHz < 1.2 GHz) */
|
||||
const uint32_t frequency_a = processor_a->max_frequency;
|
||||
const uint32_t frequency_b = processor_b->max_frequency;
|
||||
if (frequency_a != frequency_b) {
|
||||
return frequency_a > frequency_b ? -1 : 1;
|
||||
}
|
||||
|
||||
/* Compare based on cluster leader id (i.e. cluster 1 < cluster 0) */
|
||||
const uint32_t cluster_a = processor_a->package_leader_id;
|
||||
const uint32_t cluster_b = processor_b->package_leader_id;
|
||||
if (cluster_a != cluster_b) {
|
||||
return cluster_a > cluster_b ? -1 : 1;
|
||||
}
|
||||
|
||||
/* Compare based on system processor id (i.e. processor 0 < processor 1) */
|
||||
const uint32_t id_a = processor_a->system_processor_id;
|
||||
const uint32_t id_b = processor_b->system_processor_id;
|
||||
return cmp(id_a, id_b);
|
||||
}
|
||||
|
||||
void cpuinfo_arm_linux_init(void) {
|
||||
struct cpuinfo_arm_linux_processor* arm_linux_processors = NULL;
|
||||
struct cpuinfo_processor* processors = NULL;
|
||||
struct cpuinfo_core* cores = NULL;
|
||||
struct cpuinfo_cluster* clusters = NULL;
|
||||
struct cpuinfo_uarch_info* uarchs = NULL;
|
||||
struct cpuinfo_cache* l1i = NULL;
|
||||
struct cpuinfo_cache* l1d = NULL;
|
||||
struct cpuinfo_cache* l2 = NULL;
|
||||
struct cpuinfo_cache* l3 = NULL;
|
||||
const struct cpuinfo_processor** linux_cpu_to_processor_map = NULL;
|
||||
const struct cpuinfo_core** linux_cpu_to_core_map = NULL;
|
||||
uint32_t* linux_cpu_to_uarch_index_map = NULL;
|
||||
|
||||
const uint32_t max_processors_count = cpuinfo_linux_get_max_processors_count();
|
||||
cpuinfo_log_debug("system maximum processors count: %"PRIu32, max_processors_count);
|
||||
|
||||
const uint32_t max_possible_processors_count = 1 +
|
||||
cpuinfo_linux_get_max_possible_processor(max_processors_count);
|
||||
cpuinfo_log_debug("maximum possible processors count: %"PRIu32, max_possible_processors_count);
|
||||
const uint32_t max_present_processors_count = 1 +
|
||||
cpuinfo_linux_get_max_present_processor(max_processors_count);
|
||||
cpuinfo_log_debug("maximum present processors count: %"PRIu32, max_present_processors_count);
|
||||
|
||||
uint32_t valid_processor_mask = 0;
|
||||
uint32_t arm_linux_processors_count = max_processors_count;
|
||||
if (max_present_processors_count != 0) {
|
||||
arm_linux_processors_count = min(arm_linux_processors_count, max_present_processors_count);
|
||||
valid_processor_mask = CPUINFO_LINUX_FLAG_PRESENT;
|
||||
}
|
||||
if (max_possible_processors_count != 0) {
|
||||
arm_linux_processors_count = min(arm_linux_processors_count, max_possible_processors_count);
|
||||
valid_processor_mask |= CPUINFO_LINUX_FLAG_POSSIBLE;
|
||||
}
|
||||
if ((max_present_processors_count | max_possible_processors_count) == 0) {
|
||||
cpuinfo_log_error("failed to parse both lists of possible and present processors");
|
||||
return;
|
||||
}
|
||||
|
||||
arm_linux_processors = calloc(arm_linux_processors_count, sizeof(struct cpuinfo_arm_linux_processor));
|
||||
if (arm_linux_processors == NULL) {
|
||||
cpuinfo_log_error(
|
||||
"failed to allocate %zu bytes for descriptions of %"PRIu32" ARM logical processors",
|
||||
arm_linux_processors_count * sizeof(struct cpuinfo_arm_linux_processor),
|
||||
arm_linux_processors_count);
|
||||
return;
|
||||
}
|
||||
|
||||
if (max_possible_processors_count) {
|
||||
cpuinfo_linux_detect_possible_processors(
|
||||
arm_linux_processors_count, &arm_linux_processors->flags,
|
||||
sizeof(struct cpuinfo_arm_linux_processor),
|
||||
CPUINFO_LINUX_FLAG_POSSIBLE);
|
||||
}
|
||||
|
||||
if (max_present_processors_count) {
|
||||
cpuinfo_linux_detect_present_processors(
|
||||
arm_linux_processors_count, &arm_linux_processors->flags,
|
||||
sizeof(struct cpuinfo_arm_linux_processor),
|
||||
CPUINFO_LINUX_FLAG_PRESENT);
|
||||
}
|
||||
|
||||
#if defined(__ANDROID__)
|
||||
struct cpuinfo_android_properties android_properties;
|
||||
cpuinfo_arm_android_parse_properties(&android_properties);
|
||||
#else
|
||||
char proc_cpuinfo_hardware[CPUINFO_HARDWARE_VALUE_MAX];
|
||||
#endif
|
||||
char proc_cpuinfo_revision[CPUINFO_REVISION_VALUE_MAX];
|
||||
|
||||
if (!cpuinfo_arm_linux_parse_proc_cpuinfo(
|
||||
#if defined(__ANDROID__)
|
||||
android_properties.proc_cpuinfo_hardware,
|
||||
#else
|
||||
proc_cpuinfo_hardware,
|
||||
#endif
|
||||
proc_cpuinfo_revision,
|
||||
arm_linux_processors_count,
|
||||
arm_linux_processors)) {
|
||||
cpuinfo_log_error("failed to parse processor information from /proc/cpuinfo");
|
||||
return;
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < arm_linux_processors_count; i++) {
|
||||
if (bitmask_all(arm_linux_processors[i].flags, valid_processor_mask)) {
|
||||
arm_linux_processors[i].flags |= CPUINFO_LINUX_FLAG_VALID;
|
||||
cpuinfo_log_debug("parsed processor %"PRIu32" MIDR 0x%08"PRIx32,
|
||||
i, arm_linux_processors[i].midr);
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t valid_processors = 0, last_midr = 0;
|
||||
#if CPUINFO_ARCH_ARM
|
||||
uint32_t last_architecture_version = 0, last_architecture_flags = 0;
|
||||
#endif
|
||||
for (uint32_t i = 0; i < arm_linux_processors_count; i++) {
|
||||
arm_linux_processors[i].system_processor_id = i;
|
||||
if (bitmask_all(arm_linux_processors[i].flags, CPUINFO_LINUX_FLAG_VALID)) {
|
||||
valid_processors += 1;
|
||||
|
||||
if (!(arm_linux_processors[i].flags & CPUINFO_ARM_LINUX_VALID_PROCESSOR)) {
|
||||
/*
|
||||
* Processor is in possible and present lists, but not reported in /proc/cpuinfo.
|
||||
* This is fairly common: high-index processors can be not reported if they are offline.
|
||||
*/
|
||||
cpuinfo_log_info("processor %"PRIu32" is not listed in /proc/cpuinfo", i);
|
||||
}
|
||||
|
||||
if (bitmask_all(arm_linux_processors[i].flags, CPUINFO_ARM_LINUX_VALID_MIDR)) {
|
||||
last_midr = arm_linux_processors[i].midr;
|
||||
}
|
||||
#if CPUINFO_ARCH_ARM
|
||||
if (bitmask_all(arm_linux_processors[i].flags, CPUINFO_ARM_LINUX_VALID_ARCHITECTURE)) {
|
||||
last_architecture_version = arm_linux_processors[i].architecture_version;
|
||||
last_architecture_flags = arm_linux_processors[i].architecture_flags;
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
/* Processor reported in /proc/cpuinfo, but not in possible and/or present lists: log and ignore */
|
||||
if (!(arm_linux_processors[i].flags & CPUINFO_ARM_LINUX_VALID_PROCESSOR)) {
|
||||
cpuinfo_log_warning("invalid processor %"PRIu32" reported in /proc/cpuinfo", i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(__ANDROID__)
|
||||
const struct cpuinfo_arm_chipset chipset =
|
||||
cpuinfo_arm_android_decode_chipset(&android_properties, valid_processors, 0);
|
||||
#else
|
||||
const struct cpuinfo_arm_chipset chipset =
|
||||
cpuinfo_arm_linux_decode_chipset(proc_cpuinfo_hardware, proc_cpuinfo_revision, valid_processors, 0);
|
||||
#endif
|
||||
|
||||
#if CPUINFO_ARCH_ARM
|
||||
uint32_t isa_features = 0, isa_features2 = 0;
|
||||
#ifdef __ANDROID__
|
||||
/*
|
||||
* On Android before API 20, libc.so does not provide getauxval function.
|
||||
* Thus, we try to dynamically find it, or use two fallback mechanisms:
|
||||
* 1. dlopen libc.so, and try to find getauxval
|
||||
* 2. Parse /proc/self/auxv procfs file
|
||||
* 3. Use features reported in /proc/cpuinfo
|
||||
*/
|
||||
if (!cpuinfo_arm_linux_hwcap_from_getauxval(&isa_features, &isa_features2)) {
|
||||
/* getauxval can't be used, fall back to parsing /proc/self/auxv */
|
||||
if (!cpuinfo_arm_linux_hwcap_from_procfs(&isa_features, &isa_features2)) {
|
||||
/*
|
||||
* Reading /proc/self/auxv failed, probably due to file permissions.
|
||||
* Use information from /proc/cpuinfo to detect ISA.
|
||||
*
|
||||
* If different processors report different ISA features, take the intersection.
|
||||
*/
|
||||
uint32_t processors_with_features = 0;
|
||||
for (uint32_t i = 0; i < arm_linux_processors_count; i++) {
|
||||
if (bitmask_all(arm_linux_processors[i].flags, CPUINFO_LINUX_FLAG_VALID | CPUINFO_ARM_LINUX_VALID_FEATURES)) {
|
||||
if (processors_with_features == 0) {
|
||||
isa_features = arm_linux_processors[i].features;
|
||||
isa_features2 = arm_linux_processors[i].features2;
|
||||
} else {
|
||||
isa_features &= arm_linux_processors[i].features;
|
||||
isa_features2 &= arm_linux_processors[i].features2;
|
||||
}
|
||||
processors_with_features += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
/* On GNU/Linux getauxval is always available */
|
||||
cpuinfo_arm_linux_hwcap_from_getauxval(&isa_features, &isa_features2);
|
||||
#endif
|
||||
cpuinfo_arm_linux_decode_isa_from_proc_cpuinfo(
|
||||
isa_features, isa_features2,
|
||||
last_midr, last_architecture_version, last_architecture_flags,
|
||||
&chipset, &cpuinfo_isa);
|
||||
#elif CPUINFO_ARCH_ARM64
|
||||
uint32_t isa_features = 0, isa_features2 = 0;
|
||||
/* getauxval is always available on ARM64 Android */
|
||||
cpuinfo_arm_linux_hwcap_from_getauxval(&isa_features, &isa_features2);
|
||||
cpuinfo_arm64_linux_decode_isa_from_proc_cpuinfo(
|
||||
isa_features, isa_features2, last_midr, &chipset, &cpuinfo_isa);
|
||||
#endif
|
||||
|
||||
/* Detect min/max frequency and package ID */
|
||||
for (uint32_t i = 0; i < arm_linux_processors_count; i++) {
|
||||
if (bitmask_all(arm_linux_processors[i].flags, CPUINFO_LINUX_FLAG_VALID)) {
|
||||
const uint32_t max_frequency = cpuinfo_linux_get_processor_max_frequency(i);
|
||||
if (max_frequency != 0) {
|
||||
arm_linux_processors[i].max_frequency = max_frequency;
|
||||
arm_linux_processors[i].flags |= CPUINFO_LINUX_FLAG_MAX_FREQUENCY;
|
||||
}
|
||||
|
||||
const uint32_t min_frequency = cpuinfo_linux_get_processor_min_frequency(i);
|
||||
if (min_frequency != 0) {
|
||||
arm_linux_processors[i].min_frequency = min_frequency;
|
||||
arm_linux_processors[i].flags |= CPUINFO_LINUX_FLAG_MIN_FREQUENCY;
|
||||
}
|
||||
|
||||
if (cpuinfo_linux_get_processor_package_id(i, &arm_linux_processors[i].package_id)) {
|
||||
arm_linux_processors[i].flags |= CPUINFO_LINUX_FLAG_PACKAGE_ID;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Initialize topology group IDs */
|
||||
for (uint32_t i = 0; i < arm_linux_processors_count; i++) {
|
||||
arm_linux_processors[i].package_leader_id = i;
|
||||
}
|
||||
|
||||
/* Propagate topology group IDs among siblings */
|
||||
for (uint32_t i = 0; i < arm_linux_processors_count; i++) {
|
||||
if (!bitmask_all(arm_linux_processors[i].flags, CPUINFO_LINUX_FLAG_VALID)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (arm_linux_processors[i].flags & CPUINFO_LINUX_FLAG_PACKAGE_ID) {
|
||||
cpuinfo_linux_detect_core_siblings(
|
||||
arm_linux_processors_count, i,
|
||||
(cpuinfo_siblings_callback) cluster_siblings_parser,
|
||||
arm_linux_processors);
|
||||
}
|
||||
}
|
||||
|
||||
/* Propagate all cluster IDs */
|
||||
uint32_t clustered_processors = 0;
|
||||
for (uint32_t i = 0; i < arm_linux_processors_count; i++) {
|
||||
if (bitmask_all(arm_linux_processors[i].flags, CPUINFO_LINUX_FLAG_VALID | CPUINFO_LINUX_FLAG_PACKAGE_CLUSTER)) {
|
||||
clustered_processors += 1;
|
||||
|
||||
const uint32_t package_leader_id = arm_linux_processors[i].package_leader_id;
|
||||
if (package_leader_id < i) {
|
||||
arm_linux_processors[i].package_leader_id = arm_linux_processors[package_leader_id].package_leader_id;
|
||||
}
|
||||
|
||||
cpuinfo_log_debug("processor %"PRIu32" clustered with processor %"PRIu32" as inferred from system siblings lists",
|
||||
i, arm_linux_processors[i].package_leader_id);
|
||||
}
|
||||
}
|
||||
|
||||
if (clustered_processors != valid_processors) {
|
||||
/*
|
||||
* Topology information about some or all logical processors may be unavailable, for the following reasons:
|
||||
* - Linux kernel is too old, or configured without support for topology information in sysfs.
|
||||
* - Core is offline, and Linux kernel is configured to not report topology for offline cores.
|
||||
*
|
||||
* In this case, we assign processors to clusters using two methods:
|
||||
* - Try heuristic cluster configurations (e.g. 6-core SoC usually has 4+2 big.LITTLE configuration).
|
||||
* - If heuristic failed, assign processors to core clusters in a sequential scan.
|
||||
*/
|
||||
if (!cpuinfo_arm_linux_detect_core_clusters_by_heuristic(valid_processors, arm_linux_processors_count, arm_linux_processors)) {
|
||||
cpuinfo_arm_linux_detect_core_clusters_by_sequential_scan(arm_linux_processors_count, arm_linux_processors);
|
||||
}
|
||||
}
|
||||
|
||||
cpuinfo_arm_linux_count_cluster_processors(arm_linux_processors_count, arm_linux_processors);
|
||||
|
||||
const uint32_t cluster_count = cpuinfo_arm_linux_detect_cluster_midr(
|
||||
&chipset,
|
||||
arm_linux_processors_count, valid_processors, arm_linux_processors);
|
||||
|
||||
/* Initialize core vendor, uarch, MIDR, and frequency for every logical processor */
|
||||
for (uint32_t i = 0; i < arm_linux_processors_count; i++) {
|
||||
if (bitmask_all(arm_linux_processors[i].flags, CPUINFO_LINUX_FLAG_VALID)) {
|
||||
const uint32_t cluster_leader = arm_linux_processors[i].package_leader_id;
|
||||
if (cluster_leader == i) {
|
||||
/* Cluster leader: decode core vendor and uarch */
|
||||
cpuinfo_arm_decode_vendor_uarch(
|
||||
arm_linux_processors[cluster_leader].midr,
|
||||
#if CPUINFO_ARCH_ARM
|
||||
!!(arm_linux_processors[cluster_leader].features & CPUINFO_ARM_LINUX_FEATURE_VFPV4),
|
||||
#endif
|
||||
&arm_linux_processors[cluster_leader].vendor,
|
||||
&arm_linux_processors[cluster_leader].uarch);
|
||||
} else {
|
||||
/* Cluster non-leader: copy vendor, uarch, MIDR, and frequency from cluster leader */
|
||||
arm_linux_processors[i].flags |= arm_linux_processors[cluster_leader].flags &
|
||||
(CPUINFO_ARM_LINUX_VALID_MIDR | CPUINFO_LINUX_FLAG_MAX_FREQUENCY);
|
||||
arm_linux_processors[i].midr = arm_linux_processors[cluster_leader].midr;
|
||||
arm_linux_processors[i].vendor = arm_linux_processors[cluster_leader].vendor;
|
||||
arm_linux_processors[i].uarch = arm_linux_processors[cluster_leader].uarch;
|
||||
arm_linux_processors[i].max_frequency = arm_linux_processors[cluster_leader].max_frequency;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < arm_linux_processors_count; i++) {
|
||||
if (bitmask_all(arm_linux_processors[i].flags, CPUINFO_LINUX_FLAG_VALID)) {
|
||||
cpuinfo_log_debug("post-analysis processor %"PRIu32": MIDR %08"PRIx32" frequency %"PRIu32,
|
||||
i, arm_linux_processors[i].midr, arm_linux_processors[i].max_frequency);
|
||||
}
|
||||
}
|
||||
|
||||
qsort(arm_linux_processors, arm_linux_processors_count,
|
||||
sizeof(struct cpuinfo_arm_linux_processor), cmp_arm_linux_processor);
|
||||
|
||||
for (uint32_t i = 0; i < arm_linux_processors_count; i++) {
|
||||
if (bitmask_all(arm_linux_processors[i].flags, CPUINFO_LINUX_FLAG_VALID)) {
|
||||
cpuinfo_log_debug("post-sort processor %"PRIu32": system id %"PRIu32" MIDR %08"PRIx32" frequency %"PRIu32,
|
||||
i, arm_linux_processors[i].system_processor_id, arm_linux_processors[i].midr, arm_linux_processors[i].max_frequency);
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t uarchs_count = 0;
|
||||
enum cpuinfo_uarch last_uarch;
|
||||
for (uint32_t i = 0; i < arm_linux_processors_count; i++) {
|
||||
if (bitmask_all(arm_linux_processors[i].flags, CPUINFO_LINUX_FLAG_VALID)) {
|
||||
if (uarchs_count == 0 || arm_linux_processors[i].uarch != last_uarch) {
|
||||
last_uarch = arm_linux_processors[i].uarch;
|
||||
uarchs_count += 1;
|
||||
}
|
||||
arm_linux_processors[i].uarch_index = uarchs_count - 1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Assumptions:
|
||||
* - No SMP (i.e. each core supports only one hardware thread).
|
||||
* - Level 1 instruction and data caches are private to the core clusters.
|
||||
* - Level 2 and level 3 cache is shared between cores in the same cluster.
|
||||
*/
|
||||
cpuinfo_arm_chipset_to_string(&chipset, package.name);
|
||||
package.processor_count = valid_processors;
|
||||
package.core_count = valid_processors;
|
||||
package.cluster_count = cluster_count;
|
||||
|
||||
processors = calloc(valid_processors, sizeof(struct cpuinfo_processor));
|
||||
if (processors == NULL) {
|
||||
cpuinfo_log_error("failed to allocate %zu bytes for descriptions of %"PRIu32" logical processors",
|
||||
valid_processors * sizeof(struct cpuinfo_processor), valid_processors);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
cores = calloc(valid_processors, sizeof(struct cpuinfo_core));
|
||||
if (cores == NULL) {
|
||||
cpuinfo_log_error("failed to allocate %zu bytes for descriptions of %"PRIu32" cores",
|
||||
valid_processors * sizeof(struct cpuinfo_core), valid_processors);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
clusters = calloc(cluster_count, sizeof(struct cpuinfo_cluster));
|
||||
if (clusters == NULL) {
|
||||
cpuinfo_log_error("failed to allocate %zu bytes for descriptions of %"PRIu32" core clusters",
|
||||
cluster_count * sizeof(struct cpuinfo_cluster), cluster_count);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
uarchs = calloc(uarchs_count, sizeof(struct cpuinfo_uarch_info));
|
||||
if (uarchs == NULL) {
|
||||
cpuinfo_log_error("failed to allocate %zu bytes for descriptions of %"PRIu32" microarchitectures",
|
||||
uarchs_count * sizeof(struct cpuinfo_uarch_info), uarchs_count);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
linux_cpu_to_processor_map = calloc(arm_linux_processors_count, sizeof(struct cpuinfo_processor*));
|
||||
if (linux_cpu_to_processor_map == NULL) {
|
||||
cpuinfo_log_error("failed to allocate %zu bytes for %"PRIu32" logical processor mapping entries",
|
||||
arm_linux_processors_count * sizeof(struct cpuinfo_processor*), arm_linux_processors_count);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
linux_cpu_to_core_map = calloc(arm_linux_processors_count, sizeof(struct cpuinfo_core*));
|
||||
if (linux_cpu_to_core_map == NULL) {
|
||||
cpuinfo_log_error("failed to allocate %zu bytes for %"PRIu32" core mapping entries",
|
||||
arm_linux_processors_count * sizeof(struct cpuinfo_core*), arm_linux_processors_count);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (uarchs_count > 1) {
|
||||
linux_cpu_to_uarch_index_map = calloc(arm_linux_processors_count, sizeof(uint32_t));
|
||||
if (linux_cpu_to_uarch_index_map == NULL) {
|
||||
cpuinfo_log_error("failed to allocate %zu bytes for %"PRIu32" uarch index mapping entries",
|
||||
arm_linux_processors_count * sizeof(uint32_t), arm_linux_processors_count);
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
l1i = calloc(valid_processors, sizeof(struct cpuinfo_cache));
|
||||
if (l1i == NULL) {
|
||||
cpuinfo_log_error("failed to allocate %zu bytes for descriptions of %"PRIu32" L1I caches",
|
||||
valid_processors * sizeof(struct cpuinfo_cache), valid_processors);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
l1d = calloc(valid_processors, sizeof(struct cpuinfo_cache));
|
||||
if (l1d == NULL) {
|
||||
cpuinfo_log_error("failed to allocate %zu bytes for descriptions of %"PRIu32" L1D caches",
|
||||
valid_processors * sizeof(struct cpuinfo_cache), valid_processors);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
uint32_t uarchs_index = 0;
|
||||
for (uint32_t i = 0; i < arm_linux_processors_count; i++) {
|
||||
if (bitmask_all(arm_linux_processors[i].flags, CPUINFO_LINUX_FLAG_VALID)) {
|
||||
if (uarchs_index == 0 || arm_linux_processors[i].uarch != last_uarch) {
|
||||
last_uarch = arm_linux_processors[i].uarch;
|
||||
uarchs[uarchs_index] = (struct cpuinfo_uarch_info) {
|
||||
.uarch = arm_linux_processors[i].uarch,
|
||||
.midr = arm_linux_processors[i].midr,
|
||||
};
|
||||
uarchs_index += 1;
|
||||
}
|
||||
uarchs[uarchs_index - 1].processor_count += 1;
|
||||
uarchs[uarchs_index - 1].core_count += 1;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t l2_count = 0, l3_count = 0, big_l3_size = 0, cluster_id = UINT32_MAX;
|
||||
/* Indication whether L3 (if it exists) is shared between all cores */
|
||||
bool shared_l3 = true;
|
||||
/* Populate cache infromation structures in l1i, l1d */
|
||||
for (uint32_t i = 0; i < valid_processors; i++) {
|
||||
if (arm_linux_processors[i].package_leader_id == arm_linux_processors[i].system_processor_id) {
|
||||
cluster_id += 1;
|
||||
clusters[cluster_id] = (struct cpuinfo_cluster) {
|
||||
.processor_start = i,
|
||||
.processor_count = arm_linux_processors[i].package_processor_count,
|
||||
.core_start = i,
|
||||
.core_count = arm_linux_processors[i].package_processor_count,
|
||||
.cluster_id = cluster_id,
|
||||
.package = &package,
|
||||
.vendor = arm_linux_processors[i].vendor,
|
||||
.uarch = arm_linux_processors[i].uarch,
|
||||
.midr = arm_linux_processors[i].midr,
|
||||
};
|
||||
}
|
||||
|
||||
processors[i].smt_id = 0;
|
||||
processors[i].core = cores + i;
|
||||
processors[i].cluster = clusters + cluster_id;
|
||||
processors[i].package = &package;
|
||||
processors[i].linux_id = (int) arm_linux_processors[i].system_processor_id;
|
||||
processors[i].cache.l1i = l1i + i;
|
||||
processors[i].cache.l1d = l1d + i;
|
||||
linux_cpu_to_processor_map[arm_linux_processors[i].system_processor_id] = &processors[i];
|
||||
|
||||
cores[i].processor_start = i;
|
||||
cores[i].processor_count = 1;
|
||||
cores[i].core_id = i;
|
||||
cores[i].cluster = clusters + cluster_id;
|
||||
cores[i].package = &package;
|
||||
cores[i].vendor = arm_linux_processors[i].vendor;
|
||||
cores[i].uarch = arm_linux_processors[i].uarch;
|
||||
cores[i].midr = arm_linux_processors[i].midr;
|
||||
linux_cpu_to_core_map[arm_linux_processors[i].system_processor_id] = &cores[i];
|
||||
|
||||
if (linux_cpu_to_uarch_index_map != NULL) {
|
||||
linux_cpu_to_uarch_index_map[arm_linux_processors[i].system_processor_id] =
|
||||
arm_linux_processors[i].uarch_index;
|
||||
}
|
||||
|
||||
struct cpuinfo_cache temp_l2 = { 0 }, temp_l3 = { 0 };
|
||||
cpuinfo_arm_decode_cache(
|
||||
arm_linux_processors[i].uarch,
|
||||
arm_linux_processors[i].package_processor_count,
|
||||
arm_linux_processors[i].midr,
|
||||
&chipset,
|
||||
cluster_id,
|
||||
arm_linux_processors[i].architecture_version,
|
||||
&l1i[i], &l1d[i], &temp_l2, &temp_l3);
|
||||
l1i[i].processor_start = l1d[i].processor_start = i;
|
||||
l1i[i].processor_count = l1d[i].processor_count = 1;
|
||||
#if CPUINFO_ARCH_ARM
|
||||
/* L1I reported in /proc/cpuinfo overrides defaults */
|
||||
if (bitmask_all(arm_linux_processors[i].flags, CPUINFO_ARM_LINUX_VALID_ICACHE)) {
|
||||
l1i[i] = (struct cpuinfo_cache) {
|
||||
.size = arm_linux_processors[i].proc_cpuinfo_cache.i_size,
|
||||
.associativity = arm_linux_processors[i].proc_cpuinfo_cache.i_assoc,
|
||||
.sets = arm_linux_processors[i].proc_cpuinfo_cache.i_sets,
|
||||
.partitions = 1,
|
||||
.line_size = arm_linux_processors[i].proc_cpuinfo_cache.i_line_length
|
||||
};
|
||||
}
|
||||
/* L1D reported in /proc/cpuinfo overrides defaults */
|
||||
if (bitmask_all(arm_linux_processors[i].flags, CPUINFO_ARM_LINUX_VALID_DCACHE)) {
|
||||
l1d[i] = (struct cpuinfo_cache) {
|
||||
.size = arm_linux_processors[i].proc_cpuinfo_cache.d_size,
|
||||
.associativity = arm_linux_processors[i].proc_cpuinfo_cache.d_assoc,
|
||||
.sets = arm_linux_processors[i].proc_cpuinfo_cache.d_sets,
|
||||
.partitions = 1,
|
||||
.line_size = arm_linux_processors[i].proc_cpuinfo_cache.d_line_length
|
||||
};
|
||||
}
|
||||
#endif
|
||||
|
||||
if (temp_l3.size != 0) {
|
||||
/*
|
||||
* Assumptions:
|
||||
* - L2 is private to each core
|
||||
* - L3 is shared by cores in the same cluster
|
||||
* - If cores in different clusters report the same L3, it is shared between all cores.
|
||||
*/
|
||||
l2_count += 1;
|
||||
if (arm_linux_processors[i].package_leader_id == arm_linux_processors[i].system_processor_id) {
|
||||
if (cluster_id == 0) {
|
||||
big_l3_size = temp_l3.size;
|
||||
l3_count = 1;
|
||||
} else if (temp_l3.size != big_l3_size) {
|
||||
/* If some cores have different L3 size, L3 is not shared between all cores */
|
||||
shared_l3 = false;
|
||||
l3_count += 1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* If some cores don't have L3 cache, L3 is not shared between all cores */
|
||||
shared_l3 = false;
|
||||
if (temp_l2.size != 0) {
|
||||
/* Assume L2 is shared by cores in the same cluster */
|
||||
if (arm_linux_processors[i].package_leader_id == arm_linux_processors[i].system_processor_id) {
|
||||
l2_count += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (l2_count != 0) {
|
||||
l2 = calloc(l2_count, sizeof(struct cpuinfo_cache));
|
||||
if (l2 == NULL) {
|
||||
cpuinfo_log_error("failed to allocate %zu bytes for descriptions of %"PRIu32" L2 caches",
|
||||
l2_count * sizeof(struct cpuinfo_cache), l2_count);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (l3_count != 0) {
|
||||
l3 = calloc(l3_count, sizeof(struct cpuinfo_cache));
|
||||
if (l3 == NULL) {
|
||||
cpuinfo_log_error("failed to allocate %zu bytes for descriptions of %"PRIu32" L3 caches",
|
||||
l3_count * sizeof(struct cpuinfo_cache), l3_count);
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cluster_id = UINT32_MAX;
|
||||
uint32_t l2_index = UINT32_MAX, l3_index = UINT32_MAX;
|
||||
for (uint32_t i = 0; i < valid_processors; i++) {
|
||||
if (arm_linux_processors[i].package_leader_id == arm_linux_processors[i].system_processor_id) {
|
||||
cluster_id++;
|
||||
}
|
||||
|
||||
struct cpuinfo_cache dummy_l1i, dummy_l1d, temp_l2 = { 0 }, temp_l3 = { 0 };
|
||||
cpuinfo_arm_decode_cache(
|
||||
arm_linux_processors[i].uarch,
|
||||
arm_linux_processors[i].package_processor_count,
|
||||
arm_linux_processors[i].midr,
|
||||
&chipset,
|
||||
cluster_id,
|
||||
arm_linux_processors[i].architecture_version,
|
||||
&dummy_l1i, &dummy_l1d, &temp_l2, &temp_l3);
|
||||
|
||||
if (temp_l3.size != 0) {
|
||||
/*
|
||||
* Assumptions:
|
||||
* - L2 is private to each core
|
||||
* - L3 is shared by cores in the same cluster
|
||||
* - If cores in different clusters report the same L3, it is shared between all cores.
|
||||
*/
|
||||
l2_index += 1;
|
||||
l2[l2_index] = (struct cpuinfo_cache) {
|
||||
.size = temp_l2.size,
|
||||
.associativity = temp_l2.associativity,
|
||||
.sets = temp_l2.sets,
|
||||
.partitions = 1,
|
||||
.line_size = temp_l2.line_size,
|
||||
.flags = temp_l2.flags,
|
||||
.processor_start = i,
|
||||
.processor_count = 1,
|
||||
};
|
||||
processors[i].cache.l2 = l2 + l2_index;
|
||||
if (arm_linux_processors[i].package_leader_id == arm_linux_processors[i].system_processor_id) {
|
||||
l3_index += 1;
|
||||
if (l3_index < l3_count) {
|
||||
l3[l3_index] = (struct cpuinfo_cache) {
|
||||
.size = temp_l3.size,
|
||||
.associativity = temp_l3.associativity,
|
||||
.sets = temp_l3.sets,
|
||||
.partitions = 1,
|
||||
.line_size = temp_l3.line_size,
|
||||
.flags = temp_l3.flags,
|
||||
.processor_start = i,
|
||||
.processor_count =
|
||||
shared_l3 ? valid_processors : arm_linux_processors[i].package_processor_count,
|
||||
};
|
||||
}
|
||||
}
|
||||
if (shared_l3) {
|
||||
processors[i].cache.l3 = l3;
|
||||
} else if (l3_index < l3_count) {
|
||||
processors[i].cache.l3 = l3 + l3_index;
|
||||
}
|
||||
} else if (temp_l2.size != 0) {
|
||||
/* Assume L2 is shared by cores in the same cluster */
|
||||
if (arm_linux_processors[i].package_leader_id == arm_linux_processors[i].system_processor_id) {
|
||||
l2_index += 1;
|
||||
l2[l2_index] = (struct cpuinfo_cache) {
|
||||
.size = temp_l2.size,
|
||||
.associativity = temp_l2.associativity,
|
||||
.sets = temp_l2.sets,
|
||||
.partitions = 1,
|
||||
.line_size = temp_l2.line_size,
|
||||
.flags = temp_l2.flags,
|
||||
.processor_start = i,
|
||||
.processor_count = arm_linux_processors[i].package_processor_count,
|
||||
};
|
||||
}
|
||||
processors[i].cache.l2 = l2 + l2_index;
|
||||
}
|
||||
}
|
||||
|
||||
/* Commit */
|
||||
cpuinfo_processors = processors;
|
||||
cpuinfo_cores = cores;
|
||||
cpuinfo_clusters = clusters;
|
||||
cpuinfo_packages = &package;
|
||||
cpuinfo_uarchs = uarchs;
|
||||
cpuinfo_cache[cpuinfo_cache_level_1i] = l1i;
|
||||
cpuinfo_cache[cpuinfo_cache_level_1d] = l1d;
|
||||
cpuinfo_cache[cpuinfo_cache_level_2] = l2;
|
||||
cpuinfo_cache[cpuinfo_cache_level_3] = l3;
|
||||
|
||||
cpuinfo_processors_count = valid_processors;
|
||||
cpuinfo_cores_count = valid_processors;
|
||||
cpuinfo_clusters_count = cluster_count;
|
||||
cpuinfo_packages_count = 1;
|
||||
cpuinfo_uarchs_count = uarchs_count;
|
||||
cpuinfo_cache_count[cpuinfo_cache_level_1i] = valid_processors;
|
||||
cpuinfo_cache_count[cpuinfo_cache_level_1d] = valid_processors;
|
||||
cpuinfo_cache_count[cpuinfo_cache_level_2] = l2_count;
|
||||
cpuinfo_cache_count[cpuinfo_cache_level_3] = l3_count;
|
||||
cpuinfo_max_cache_size = cpuinfo_arm_compute_max_cache_size(&processors[0]);
|
||||
|
||||
cpuinfo_linux_cpu_max = arm_linux_processors_count;
|
||||
cpuinfo_linux_cpu_to_processor_map = linux_cpu_to_processor_map;
|
||||
cpuinfo_linux_cpu_to_core_map = linux_cpu_to_core_map;
|
||||
cpuinfo_linux_cpu_to_uarch_index_map = linux_cpu_to_uarch_index_map;
|
||||
|
||||
__sync_synchronize();
|
||||
|
||||
cpuinfo_is_initialized = true;
|
||||
|
||||
processors = NULL;
|
||||
cores = NULL;
|
||||
clusters = NULL;
|
||||
uarchs = NULL;
|
||||
l1i = l1d = l2 = l3 = NULL;
|
||||
linux_cpu_to_processor_map = NULL;
|
||||
linux_cpu_to_core_map = NULL;
|
||||
linux_cpu_to_uarch_index_map = NULL;
|
||||
|
||||
cleanup:
|
||||
free(arm_linux_processors);
|
||||
free(processors);
|
||||
free(cores);
|
||||
free(clusters);
|
||||
free(uarchs);
|
||||
free(l1i);
|
||||
free(l1d);
|
||||
free(l2);
|
||||
free(l3);
|
||||
free(linux_cpu_to_processor_map);
|
||||
free(linux_cpu_to_core_map);
|
||||
free(linux_cpu_to_uarch_index_map);
|
||||
}
|
||||
863
3rdparty/cpuinfo/src/arm/linux/midr.c
vendored
Normal file
863
3rdparty/cpuinfo/src/arm/linux/midr.c
vendored
Normal file
@@ -0,0 +1,863 @@
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <cpuinfo.h>
|
||||
#include <arm/linux/api.h>
|
||||
#if defined(__ANDROID__)
|
||||
#include <arm/android/api.h>
|
||||
#endif
|
||||
#include <arm/api.h>
|
||||
#include <arm/midr.h>
|
||||
#include <linux/api.h>
|
||||
#include <cpuinfo/internal-api.h>
|
||||
#include <cpuinfo/log.h>
|
||||
#include <cpuinfo/common.h>
|
||||
|
||||
|
||||
#define CLUSTERS_MAX 3
|
||||
|
||||
static inline bool bitmask_all(uint32_t bitfield, uint32_t mask) {
|
||||
return (bitfield & mask) == mask;
|
||||
}
|
||||
|
||||
/* Description of core clusters configuration in a chipset (identified by series and model number) */
|
||||
struct cluster_config {
|
||||
/* Number of cores (logical processors) */
|
||||
uint8_t cores;
|
||||
/* ARM chipset series (see cpuinfo_arm_chipset_series enum) */
|
||||
uint8_t series;
|
||||
/* Chipset model number (see cpuinfo_arm_chipset struct) */
|
||||
uint16_t model;
|
||||
/* Number of heterogenous clusters in the CPU package */
|
||||
uint8_t clusters;
|
||||
/*
|
||||
* Number of cores in each cluster:
|
||||
# - Symmetric configurations: [0] = # cores
|
||||
* - big.LITTLE configurations: [0] = # LITTLE cores, [1] = # big cores
|
||||
* - Max.Med.Min configurations: [0] = # Min cores, [1] = # Med cores, [2] = # Max cores
|
||||
*/
|
||||
uint8_t cluster_cores[CLUSTERS_MAX];
|
||||
/*
|
||||
* MIDR of cores in each cluster:
|
||||
* - Symmetric configurations: [0] = core MIDR
|
||||
* - big.LITTLE configurations: [0] = LITTLE core MIDR, [1] = big core MIDR
|
||||
* - Max.Med.Min configurations: [0] = Min core MIDR, [1] = Med core MIDR, [2] = Max core MIDR
|
||||
*/
|
||||
uint32_t cluster_midr[CLUSTERS_MAX];
|
||||
};
|
||||
|
||||
/*
|
||||
* The list of chipsets where MIDR may not be unambigiously decoded at least on some devices.
|
||||
* The typical reasons for impossibility to decoded MIDRs are buggy kernels, which either do not report all MIDR
|
||||
* information (e.g. on ATM7029 kernel doesn't report CPU Part), or chipsets have more than one type of cores
|
||||
* (i.e. 4x Cortex-A53 + 4x Cortex-A53 is out) and buggy kernels report MIDR information only about some cores
|
||||
* in /proc/cpuinfo (either only online cores, or only the core that reads /proc/cpuinfo). On these kernels/chipsets,
|
||||
* it is not possible to detect all core types by just parsing /proc/cpuinfo, so we use chipset name and this table to
|
||||
* find their MIDR (and thus microarchitecture, cache, etc).
|
||||
*
|
||||
* Note: not all chipsets with heterogeneous multiprocessing need an entry in this table. The following HMP
|
||||
* chipsets always list information about all cores in /proc/cpuinfo:
|
||||
*
|
||||
* - Snapdragon 660
|
||||
* - Snapdragon 820 (MSM8996)
|
||||
* - Snapdragon 821 (MSM8996PRO)
|
||||
* - Snapdragon 835 (MSM8998)
|
||||
* - Exynos 8895
|
||||
* - Kirin 960
|
||||
*
|
||||
* As these are all new processors, there is hope that this table won't uncontrollably grow over time.
|
||||
*/
|
||||
static const struct cluster_config cluster_configs[] = {
|
||||
#if CPUINFO_ARCH_ARM
|
||||
{
|
||||
/*
|
||||
* MSM8916 (Snapdragon 410): 4x Cortex-A53
|
||||
* Some AArch32 phones use non-standard /proc/cpuinfo format.
|
||||
*/
|
||||
.cores = 4,
|
||||
.series = cpuinfo_arm_chipset_series_qualcomm_msm,
|
||||
.model = UINT16_C(8916),
|
||||
.clusters = 1,
|
||||
.cluster_cores = {
|
||||
[0] = 4,
|
||||
},
|
||||
.cluster_midr = {
|
||||
[0] = UINT32_C(0x410FD030),
|
||||
},
|
||||
},
|
||||
{
|
||||
/*
|
||||
* MSM8939 (Snapdragon 615): 4x Cortex-A53 + 4x Cortex-A53
|
||||
* Some AArch32 phones use non-standard /proc/cpuinfo format.
|
||||
*/
|
||||
.cores = 8,
|
||||
.series = cpuinfo_arm_chipset_series_qualcomm_msm,
|
||||
.model = UINT16_C(8939),
|
||||
.clusters = 2,
|
||||
.cluster_cores = {
|
||||
[0] = 4,
|
||||
[1] = 4,
|
||||
},
|
||||
.cluster_midr = {
|
||||
[0] = UINT32_C(0x410FD034),
|
||||
[1] = UINT32_C(0x410FD034),
|
||||
},
|
||||
},
|
||||
#endif
|
||||
{
|
||||
/* MSM8956 (Snapdragon 650): 2x Cortex-A72 + 4x Cortex-A53 */
|
||||
.cores = 6,
|
||||
.series = cpuinfo_arm_chipset_series_qualcomm_msm,
|
||||
.model = UINT16_C(8956),
|
||||
.clusters = 2,
|
||||
.cluster_cores = {
|
||||
[0] = 4,
|
||||
[1] = 2,
|
||||
},
|
||||
.cluster_midr = {
|
||||
[0] = UINT32_C(0x410FD034),
|
||||
[1] = UINT32_C(0x410FD080),
|
||||
},
|
||||
},
|
||||
{
|
||||
/* MSM8976/MSM8976PRO (Snapdragon 652/653): 4x Cortex-A72 + 4x Cortex-A53 */
|
||||
.cores = 8,
|
||||
.series = cpuinfo_arm_chipset_series_qualcomm_msm,
|
||||
.model = UINT16_C(8976),
|
||||
.clusters = 2,
|
||||
.cluster_cores = {
|
||||
[0] = 4,
|
||||
[1] = 4,
|
||||
},
|
||||
.cluster_midr = {
|
||||
[0] = UINT32_C(0x410FD034),
|
||||
[1] = UINT32_C(0x410FD080),
|
||||
},
|
||||
},
|
||||
{
|
||||
/* MSM8992 (Snapdragon 808): 2x Cortex-A57 + 4x Cortex-A53 */
|
||||
.cores = 6,
|
||||
.series = cpuinfo_arm_chipset_series_qualcomm_msm,
|
||||
.model = UINT16_C(8992),
|
||||
.clusters = 2,
|
||||
.cluster_cores = {
|
||||
[0] = 4,
|
||||
[1] = 2,
|
||||
},
|
||||
.cluster_midr = {
|
||||
[0] = UINT32_C(0x410FD033),
|
||||
[1] = UINT32_C(0x411FD072),
|
||||
},
|
||||
},
|
||||
{
|
||||
/* MSM8994/MSM8994V (Snapdragon 810): 4x Cortex-A57 + 4x Cortex-A53 */
|
||||
.cores = 8,
|
||||
.series = cpuinfo_arm_chipset_series_qualcomm_msm,
|
||||
.model = UINT16_C(8994),
|
||||
.clusters = 2,
|
||||
.cluster_cores = {
|
||||
[0] = 4,
|
||||
[1] = 4,
|
||||
},
|
||||
.cluster_midr = {
|
||||
[0] = UINT32_C(0x410FD032),
|
||||
[1] = UINT32_C(0x411FD071),
|
||||
},
|
||||
},
|
||||
#if CPUINFO_ARCH_ARM
|
||||
{
|
||||
/* Exynos 5422: 4x Cortex-A15 + 4x Cortex-A7 */
|
||||
.cores = 8,
|
||||
.series = cpuinfo_arm_chipset_series_samsung_exynos,
|
||||
.model = UINT16_C(5422),
|
||||
.clusters = 2,
|
||||
.cluster_cores = {
|
||||
[0] = 4,
|
||||
[1] = 4,
|
||||
},
|
||||
.cluster_midr = {
|
||||
[0] = UINT32_C(0x410FC073),
|
||||
[1] = UINT32_C(0x412FC0F3),
|
||||
},
|
||||
},
|
||||
{
|
||||
/* Exynos 5430: 4x Cortex-A15 + 4x Cortex-A7 */
|
||||
.cores = 8,
|
||||
.series = cpuinfo_arm_chipset_series_samsung_exynos,
|
||||
.model = UINT16_C(5430),
|
||||
.clusters = 2,
|
||||
.cluster_cores = {
|
||||
[0] = 4,
|
||||
[1] = 4,
|
||||
},
|
||||
.cluster_midr = {
|
||||
[0] = UINT32_C(0x410FC074),
|
||||
[1] = UINT32_C(0x413FC0F3),
|
||||
},
|
||||
},
|
||||
#endif /* CPUINFO_ARCH_ARM */
|
||||
{
|
||||
/* Exynos 5433: 4x Cortex-A57 + 4x Cortex-A53 */
|
||||
.cores = 8,
|
||||
.series = cpuinfo_arm_chipset_series_samsung_exynos,
|
||||
.model = UINT16_C(5433),
|
||||
.clusters = 2,
|
||||
.cluster_cores = {
|
||||
[0] = 4,
|
||||
[1] = 4,
|
||||
},
|
||||
.cluster_midr = {
|
||||
[0] = UINT32_C(0x410FD031),
|
||||
[1] = UINT32_C(0x411FD070),
|
||||
},
|
||||
},
|
||||
{
|
||||
/* Exynos 7420: 4x Cortex-A57 + 4x Cortex-A53 */
|
||||
.cores = 8,
|
||||
.series = cpuinfo_arm_chipset_series_samsung_exynos,
|
||||
.model = UINT16_C(7420),
|
||||
.clusters = 2,
|
||||
.cluster_cores = {
|
||||
[0] = 4,
|
||||
[1] = 4,
|
||||
},
|
||||
.cluster_midr = {
|
||||
[0] = UINT32_C(0x410FD032),
|
||||
[1] = UINT32_C(0x411FD070),
|
||||
},
|
||||
},
|
||||
{
|
||||
/* Exynos 8890: 4x Exynos M1 + 4x Cortex-A53 */
|
||||
.cores = 8,
|
||||
.series = cpuinfo_arm_chipset_series_samsung_exynos,
|
||||
.model = UINT16_C(8890),
|
||||
.clusters = 2,
|
||||
.cluster_cores = {
|
||||
[0] = 4,
|
||||
[1] = 4,
|
||||
},
|
||||
.cluster_midr = {
|
||||
[0] = UINT32_C(0x410FD034),
|
||||
[1] = UINT32_C(0x531F0011),
|
||||
},
|
||||
},
|
||||
#if CPUINFO_ARCH_ARM
|
||||
{
|
||||
/* Kirin 920: 4x Cortex-A15 + 4x Cortex-A7 */
|
||||
.cores = 8,
|
||||
.series = cpuinfo_arm_chipset_series_hisilicon_kirin,
|
||||
.model = UINT16_C(920),
|
||||
.clusters = 2,
|
||||
.cluster_cores = {
|
||||
[0] = 4,
|
||||
[1] = 4,
|
||||
},
|
||||
.cluster_midr = {
|
||||
[0] = UINT32_C(0x410FC075),
|
||||
[1] = UINT32_C(0x413FC0F3),
|
||||
},
|
||||
},
|
||||
{
|
||||
/* Kirin 925: 4x Cortex-A15 + 4x Cortex-A7 */
|
||||
.cores = 8,
|
||||
.series = cpuinfo_arm_chipset_series_hisilicon_kirin,
|
||||
.model = UINT16_C(925),
|
||||
.clusters = 2,
|
||||
.cluster_cores = {
|
||||
[0] = 4,
|
||||
[1] = 4,
|
||||
},
|
||||
.cluster_midr = {
|
||||
[0] = UINT32_C(0x410FC075),
|
||||
[1] = UINT32_C(0x413FC0F3),
|
||||
},
|
||||
},
|
||||
{
|
||||
/* Kirin 928: 4x Cortex-A15 + 4x Cortex-A7 */
|
||||
.cores = 8,
|
||||
.series = cpuinfo_arm_chipset_series_hisilicon_kirin,
|
||||
.model = UINT16_C(928),
|
||||
.clusters = 2,
|
||||
.cluster_cores = {
|
||||
[0] = 4,
|
||||
[1] = 4,
|
||||
},
|
||||
.cluster_midr = {
|
||||
[0] = UINT32_C(0x410FC075),
|
||||
[1] = UINT32_C(0x413FC0F3),
|
||||
},
|
||||
},
|
||||
#endif /* CPUINFO_ARCH_ARM */
|
||||
{
|
||||
/* Kirin 950: 4x Cortex-A72 + 4x Cortex-A53 */
|
||||
.cores = 8,
|
||||
.series = cpuinfo_arm_chipset_series_hisilicon_kirin,
|
||||
.model = UINT16_C(950),
|
||||
.clusters = 2,
|
||||
.cluster_cores = {
|
||||
[0] = 4,
|
||||
[1] = 4,
|
||||
},
|
||||
.cluster_midr = {
|
||||
[0] = UINT32_C(0x410FD034),
|
||||
[1] = UINT32_C(0x410FD080),
|
||||
},
|
||||
},
|
||||
{
|
||||
/* Kirin 955: 4x Cortex-A72 + 4x Cortex-A53 */
|
||||
.cores = 8,
|
||||
.series = cpuinfo_arm_chipset_series_hisilicon_kirin,
|
||||
.model = UINT16_C(955),
|
||||
.clusters = 2,
|
||||
.cluster_cores = {
|
||||
[0] = 4,
|
||||
[1] = 4,
|
||||
},
|
||||
.cluster_midr = {
|
||||
[0] = UINT32_C(0x410FD034),
|
||||
[1] = UINT32_C(0x410FD080),
|
||||
},
|
||||
},
|
||||
#if CPUINFO_ARCH_ARM
|
||||
{
|
||||
/* MediaTek MT8135: 2x Cortex-A7 + 2x Cortex-A15 */
|
||||
.cores = 4,
|
||||
.series = cpuinfo_arm_chipset_series_mediatek_mt,
|
||||
.model = UINT16_C(8135),
|
||||
.clusters = 2,
|
||||
.cluster_cores = {
|
||||
[0] = 2,
|
||||
[1] = 2,
|
||||
},
|
||||
.cluster_midr = {
|
||||
[0] = UINT32_C(0x410FC073),
|
||||
[1] = UINT32_C(0x413FC0F2),
|
||||
},
|
||||
},
|
||||
#endif
|
||||
{
|
||||
/* MediaTek MT8173: 2x Cortex-A72 + 2x Cortex-A53 */
|
||||
.cores = 4,
|
||||
.series = cpuinfo_arm_chipset_series_mediatek_mt,
|
||||
.model = UINT16_C(8173),
|
||||
.clusters = 2,
|
||||
.cluster_cores = {
|
||||
[0] = 2,
|
||||
[1] = 2,
|
||||
},
|
||||
.cluster_midr = {
|
||||
[0] = UINT32_C(0x410FD032),
|
||||
[1] = UINT32_C(0x410FD080),
|
||||
},
|
||||
},
|
||||
{
|
||||
/* MediaTek MT8176: 2x Cortex-A72 + 4x Cortex-A53 */
|
||||
.cores = 6,
|
||||
.series = cpuinfo_arm_chipset_series_mediatek_mt,
|
||||
.model = UINT16_C(8176),
|
||||
.clusters = 2,
|
||||
.cluster_cores = {
|
||||
[0] = 4,
|
||||
[1] = 2,
|
||||
},
|
||||
.cluster_midr = {
|
||||
[0] = UINT32_C(0x410FD032),
|
||||
[1] = UINT32_C(0x410FD080),
|
||||
},
|
||||
},
|
||||
#if CPUINFO_ARCH_ARM64
|
||||
{
|
||||
/*
|
||||
* MediaTek MT8735: 4x Cortex-A53
|
||||
* Some AArch64 phones use non-standard /proc/cpuinfo format.
|
||||
*/
|
||||
.cores = 4,
|
||||
.series = cpuinfo_arm_chipset_series_mediatek_mt,
|
||||
.model = UINT16_C(8735),
|
||||
.clusters = 1,
|
||||
.cluster_cores = {
|
||||
[0] = 4,
|
||||
},
|
||||
.cluster_midr = {
|
||||
[0] = UINT32_C(0x410FD034),
|
||||
},
|
||||
},
|
||||
#endif
|
||||
#if CPUINFO_ARCH_ARM
|
||||
{
|
||||
/*
|
||||
* MediaTek MT6592: 4x Cortex-A7 + 4x Cortex-A7
|
||||
* Some phones use non-standard /proc/cpuinfo format.
|
||||
*/
|
||||
.cores = 4,
|
||||
.series = cpuinfo_arm_chipset_series_mediatek_mt,
|
||||
.model = UINT16_C(6592),
|
||||
.clusters = 2,
|
||||
.cluster_cores = {
|
||||
[0] = 4,
|
||||
[1] = 4,
|
||||
},
|
||||
.cluster_midr = {
|
||||
[0] = UINT32_C(0x410FC074),
|
||||
[1] = UINT32_C(0x410FC074),
|
||||
},
|
||||
},
|
||||
{
|
||||
/* MediaTek MT6595: 4x Cortex-A17 + 4x Cortex-A7 */
|
||||
.cores = 8,
|
||||
.series = cpuinfo_arm_chipset_series_mediatek_mt,
|
||||
.model = UINT16_C(6595),
|
||||
.clusters = 2,
|
||||
.cluster_cores = {
|
||||
[0] = 4,
|
||||
[1] = 4,
|
||||
},
|
||||
.cluster_midr = {
|
||||
[0] = UINT32_C(0x410FC075),
|
||||
[1] = UINT32_C(0x410FC0E0),
|
||||
},
|
||||
},
|
||||
#endif
|
||||
{
|
||||
/* MediaTek MT6797: 2x Cortex-A72 + 4x Cortex-A53 + 4x Cortex-A53 */
|
||||
.cores = 10,
|
||||
.series = cpuinfo_arm_chipset_series_mediatek_mt,
|
||||
.model = UINT16_C(6797),
|
||||
.clusters = 3,
|
||||
.cluster_cores = {
|
||||
[0] = 4,
|
||||
[1] = 4,
|
||||
[2] = 2,
|
||||
},
|
||||
.cluster_midr = {
|
||||
[0] = UINT32_C(0x410FD034),
|
||||
[1] = UINT32_C(0x410FD034),
|
||||
[2] = UINT32_C(0x410FD081),
|
||||
},
|
||||
},
|
||||
{
|
||||
/* MediaTek MT6799: 2x Cortex-A73 + 4x Cortex-A53 + 4x Cortex-A35 */
|
||||
.cores = 10,
|
||||
.series = cpuinfo_arm_chipset_series_mediatek_mt,
|
||||
.model = UINT16_C(6799),
|
||||
.clusters = 3,
|
||||
.cluster_cores = {
|
||||
[0] = 4,
|
||||
[1] = 4,
|
||||
[2] = 2,
|
||||
},
|
||||
.cluster_midr = {
|
||||
[0] = UINT32_C(0x410FD041),
|
||||
[1] = UINT32_C(0x410FD034),
|
||||
[2] = UINT32_C(0x410FD092),
|
||||
},
|
||||
},
|
||||
{
|
||||
/* Rockchip RK3399: 2x Cortex-A72 + 4x Cortex-A53 */
|
||||
.cores = 6,
|
||||
.series = cpuinfo_arm_chipset_series_rockchip_rk,
|
||||
.model = UINT16_C(3399),
|
||||
.clusters = 2,
|
||||
.cluster_cores = {
|
||||
[0] = 4,
|
||||
[1] = 2,
|
||||
},
|
||||
.cluster_midr = {
|
||||
[0] = UINT32_C(0x410FD034),
|
||||
[1] = UINT32_C(0x410FD082),
|
||||
},
|
||||
},
|
||||
#if CPUINFO_ARCH_ARM
|
||||
{
|
||||
/* Actions ATM8029: 4x Cortex-A5
|
||||
* Most devices use non-standard /proc/cpuinfo format.
|
||||
*/
|
||||
.cores = 4,
|
||||
.series = cpuinfo_arm_chipset_series_actions_atm,
|
||||
.model = UINT16_C(7029),
|
||||
.clusters = 1,
|
||||
.cluster_cores = {
|
||||
[0] = 4,
|
||||
},
|
||||
.cluster_midr = {
|
||||
[0] = UINT32_C(0x410FC051),
|
||||
},
|
||||
},
|
||||
#endif
|
||||
};
|
||||
|
||||
/*
|
||||
* Searches chipset name in mapping of chipset name to cores' MIDR values. If match is successful, initializes MIDR
|
||||
* for all clusters' leaders with tabulated values.
|
||||
*
|
||||
* @param[in] chipset - chipset (SoC) name information.
|
||||
* @param clusters_count - number of CPU core clusters detected in the SoC.
|
||||
* @param cluster_leaders - indices of core clusters' leaders in the @p processors array.
|
||||
* @param processors_count - number of usable logical processors in the system.
|
||||
* @param[in,out] processors - array of logical processor descriptions with pre-parsed MIDR, maximum frequency,
|
||||
* and decoded core cluster (package_leader_id) information.
|
||||
* Upon successful return, processors[i].midr for all clusters' leaders contains the
|
||||
* tabulated MIDR values.
|
||||
* @param verify_midr - indicated whether the function should check that the MIDR values to be assigned to leaders of
|
||||
* core clusters are consistent with known parts of their parsed values.
|
||||
* Set if to false if the only MIDR value parsed from /proc/cpuinfo is for the last processor
|
||||
* reported in /proc/cpuinfo and thus can't be unambiguously attributed to that processor.
|
||||
*
|
||||
* @retval true if the chipset was found in the mapping and core clusters' leaders initialized with MIDR values.
|
||||
* @retval false if the chipset was not found in the mapping, or any consistency check failed.
|
||||
*/
|
||||
static bool cpuinfo_arm_linux_detect_cluster_midr_by_chipset(
|
||||
const struct cpuinfo_arm_chipset chipset[restrict static 1],
|
||||
uint32_t clusters_count,
|
||||
const uint32_t cluster_leaders[restrict static CLUSTERS_MAX],
|
||||
uint32_t processors_count,
|
||||
struct cpuinfo_arm_linux_processor processors[restrict static processors_count],
|
||||
bool verify_midr)
|
||||
{
|
||||
if (clusters_count <= CLUSTERS_MAX) {
|
||||
for (uint32_t c = 0; c < CPUINFO_COUNT_OF(cluster_configs); c++) {
|
||||
if (cluster_configs[c].model == chipset->model && cluster_configs[c].series == chipset->series) {
|
||||
/* Verify that the total number of cores and clusters of cores matches expectation */
|
||||
if (cluster_configs[c].cores != processors_count || cluster_configs[c].clusters != clusters_count) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Verify that core cluster configuration matches expectation */
|
||||
for (uint32_t cluster = 0; cluster < clusters_count; cluster++) {
|
||||
const uint32_t cluster_leader = cluster_leaders[cluster];
|
||||
if (cluster_configs[c].cluster_cores[cluster] != processors[cluster_leader].package_processor_count) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (verify_midr) {
|
||||
/* Verify known parts of MIDR */
|
||||
for (uint32_t cluster = 0; cluster < clusters_count; cluster++) {
|
||||
const uint32_t cluster_leader = cluster_leaders[cluster];
|
||||
|
||||
/* Create a mask of known midr bits */
|
||||
uint32_t midr_mask = 0;
|
||||
if (processors[cluster_leader].flags & CPUINFO_ARM_LINUX_VALID_IMPLEMENTER) {
|
||||
midr_mask |= CPUINFO_ARM_MIDR_IMPLEMENTER_MASK;
|
||||
}
|
||||
if (processors[cluster_leader].flags & CPUINFO_ARM_LINUX_VALID_VARIANT) {
|
||||
midr_mask |= CPUINFO_ARM_MIDR_VARIANT_MASK;
|
||||
}
|
||||
if (processors[cluster_leader].flags & CPUINFO_ARM_LINUX_VALID_PART) {
|
||||
midr_mask |= CPUINFO_ARM_MIDR_PART_MASK;
|
||||
}
|
||||
if (processors[cluster_leader].flags & CPUINFO_ARM_LINUX_VALID_REVISION) {
|
||||
midr_mask |= CPUINFO_ARM_MIDR_REVISION_MASK;
|
||||
}
|
||||
|
||||
/* Verify the bits under the mask */
|
||||
if ((processors[cluster_leader].midr ^ cluster_configs[c].cluster_midr[cluster]) & midr_mask) {
|
||||
cpuinfo_log_debug("parsed MIDR of cluster %08"PRIu32" does not match tabulated value %08"PRIu32,
|
||||
processors[cluster_leader].midr, cluster_configs[c].cluster_midr[cluster]);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Assign MIDRs according to tabulated configurations */
|
||||
for (uint32_t cluster = 0; cluster < clusters_count; cluster++) {
|
||||
const uint32_t cluster_leader = cluster_leaders[cluster];
|
||||
processors[cluster_leader].midr = cluster_configs[c].cluster_midr[cluster];
|
||||
processors[cluster_leader].flags |= CPUINFO_ARM_LINUX_VALID_MIDR;
|
||||
cpuinfo_log_debug("cluster %"PRIu32" MIDR = 0x%08"PRIx32, cluster, cluster_configs[c].cluster_midr[cluster]);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Initializes MIDR for leaders of core clusters using a heuristic for big.LITTLE systems:
|
||||
* - If the only known MIDR is for the big core cluster, guess the matching MIDR for the LITTLE cluster.
|
||||
* - Estimate which of the clusters is big using maximum frequency, if known, otherwise using system processor ID.
|
||||
* - Initialize the MIDR for big and LITTLE core clusters using the guesstimates values.
|
||||
*
|
||||
* @param clusters_count - number of CPU core clusters detected in the SoC.
|
||||
* @param cluster_with_midr_count - number of CPU core clusters in the SoC with known MIDR values.
|
||||
* @param last_processor_with_midr - index of the last logical processor with known MIDR in the @p processors array.
|
||||
* @param cluster_leaders - indices of core clusters' leaders in the @p processors array.
|
||||
* @param[in,out] processors - array of logical processor descriptions with pre-parsed MIDR, maximum frequency,
|
||||
* and decoded core cluster (package_leader_id) information.
|
||||
* Upon successful return, processors[i].midr for all core clusters' leaders contains
|
||||
* the heuristically detected MIDR value.
|
||||
* @param verify_midr - indicated whether the function should check that the MIDR values to be assigned to leaders of
|
||||
* core clusters are consistent with known parts of their parsed values.
|
||||
* Set if to false if the only MIDR value parsed from /proc/cpuinfo is for the last processor
|
||||
* reported in /proc/cpuinfo and thus can't be unambiguously attributed to that processor.
|
||||
*
|
||||
* @retval true if this is a big.LITTLE system with only one known MIDR and the CPU core clusters' leaders were
|
||||
* initialized with MIDR values.
|
||||
* @retval false if this is not a big.LITTLE system.
|
||||
*/
|
||||
static bool cpuinfo_arm_linux_detect_cluster_midr_by_big_little_heuristic(
|
||||
uint32_t clusters_count,
|
||||
uint32_t cluster_with_midr_count,
|
||||
uint32_t last_processor_with_midr,
|
||||
const uint32_t cluster_leaders[restrict static CLUSTERS_MAX],
|
||||
struct cpuinfo_arm_linux_processor processors[restrict static last_processor_with_midr],
|
||||
bool verify_midr)
|
||||
{
|
||||
if (clusters_count != 2 || cluster_with_midr_count != 1) {
|
||||
/* Not a big.LITTLE system, or MIDR is known for both/neither clusters */
|
||||
return false;
|
||||
}
|
||||
|
||||
const uint32_t midr_flags =
|
||||
(processors[processors[last_processor_with_midr].package_leader_id].flags & CPUINFO_ARM_LINUX_VALID_MIDR);
|
||||
const uint32_t big_midr = processors[processors[last_processor_with_midr].package_leader_id].midr;
|
||||
const uint32_t little_midr = midr_little_core_for_big(big_midr);
|
||||
|
||||
/* Default assumption: the first reported cluster is LITTLE cluster (this holds on most Linux kernels) */
|
||||
uint32_t little_cluster_leader = cluster_leaders[0];
|
||||
const uint32_t other_cluster_leader = cluster_leaders[1];
|
||||
/* If maximum frequency is known for both clusters, assume LITTLE cluster is the one with lower frequency */
|
||||
if (processors[little_cluster_leader].flags & processors[other_cluster_leader].flags & CPUINFO_LINUX_FLAG_MAX_FREQUENCY) {
|
||||
if (processors[little_cluster_leader].max_frequency > processors[other_cluster_leader].max_frequency) {
|
||||
little_cluster_leader = other_cluster_leader;
|
||||
}
|
||||
}
|
||||
|
||||
if (verify_midr) {
|
||||
/* Verify known parts of MIDR */
|
||||
for (uint32_t cluster = 0; cluster < clusters_count; cluster++) {
|
||||
const uint32_t cluster_leader = cluster_leaders[cluster];
|
||||
|
||||
/* Create a mask of known midr bits */
|
||||
uint32_t midr_mask = 0;
|
||||
if (processors[cluster_leader].flags & CPUINFO_ARM_LINUX_VALID_IMPLEMENTER) {
|
||||
midr_mask |= CPUINFO_ARM_MIDR_IMPLEMENTER_MASK;
|
||||
}
|
||||
if (processors[cluster_leader].flags & CPUINFO_ARM_LINUX_VALID_VARIANT) {
|
||||
midr_mask |= CPUINFO_ARM_MIDR_VARIANT_MASK;
|
||||
}
|
||||
if (processors[cluster_leader].flags & CPUINFO_ARM_LINUX_VALID_PART) {
|
||||
midr_mask |= CPUINFO_ARM_MIDR_PART_MASK;
|
||||
}
|
||||
if (processors[cluster_leader].flags & CPUINFO_ARM_LINUX_VALID_REVISION) {
|
||||
midr_mask |= CPUINFO_ARM_MIDR_REVISION_MASK;
|
||||
}
|
||||
|
||||
/* Verify the bits under the mask */
|
||||
const uint32_t midr = (cluster_leader == little_cluster_leader) ? little_midr : big_midr;
|
||||
if ((processors[cluster_leader].midr ^ midr) & midr_mask) {
|
||||
cpuinfo_log_debug(
|
||||
"parsed MIDR %08"PRIu32" of cluster leader %"PRIu32" is inconsistent with expected value %08"PRIu32,
|
||||
processors[cluster_leader].midr, cluster_leader, midr);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (uint32_t c = 0; c < clusters_count; c++) {
|
||||
/* Skip cluster with already assigned MIDR */
|
||||
const uint32_t cluster_leader = cluster_leaders[c];
|
||||
if (bitmask_all(processors[cluster_leader].flags, CPUINFO_ARM_LINUX_VALID_MIDR)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const uint32_t midr = (cluster_leader == little_cluster_leader) ? little_midr : big_midr;
|
||||
cpuinfo_log_info("assume processor %"PRIu32" to have MIDR %08"PRIx32, cluster_leader, midr);
|
||||
/* To be consistent, we copy the MIDR entirely, rather than by parts */
|
||||
processors[cluster_leader].midr = midr;
|
||||
processors[cluster_leader].flags |= midr_flags;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Initializes MIDR for leaders of core clusters in a single sequential scan:
|
||||
* - Clusters preceeding the first reported MIDR value are assumed to have default MIDR value.
|
||||
* - Clusters following any reported MIDR value to have that MIDR value.
|
||||
*
|
||||
* @param default_midr - MIDR value that will be assigned to cluster leaders preceeding any reported MIDR value.
|
||||
* @param processors_count - number of logical processor descriptions in the @p processors array.
|
||||
* @param[in,out] processors - array of logical processor descriptions with pre-parsed MIDR, maximum frequency,
|
||||
* and decoded core cluster (package_leader_id) information.
|
||||
* Upon successful return, processors[i].midr for all core clusters' leaders contains
|
||||
* the assigned MIDR value.
|
||||
*/
|
||||
static void cpuinfo_arm_linux_detect_cluster_midr_by_sequential_scan(
|
||||
uint32_t default_midr,
|
||||
uint32_t processors_count,
|
||||
struct cpuinfo_arm_linux_processor processors[restrict static processors_count])
|
||||
{
|
||||
uint32_t midr = default_midr;
|
||||
for (uint32_t i = 0; i < processors_count; i++) {
|
||||
if (bitmask_all(processors[i].flags, CPUINFO_LINUX_FLAG_VALID)) {
|
||||
if (processors[i].package_leader_id == i) {
|
||||
if (bitmask_all(processors[i].flags, CPUINFO_ARM_LINUX_VALID_MIDR)) {
|
||||
midr = processors[i].midr;
|
||||
} else {
|
||||
cpuinfo_log_info("assume processor %"PRIu32" to have MIDR %08"PRIx32, i, midr);
|
||||
/* To be consistent, we copy the MIDR entirely, rather than by parts */
|
||||
processors[i].midr = midr;
|
||||
processors[i].flags |= CPUINFO_ARM_LINUX_VALID_MIDR;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Detects MIDR of each CPU core clusters' leader.
|
||||
*
|
||||
* @param[in] chipset - chipset (SoC) name information.
|
||||
* @param max_processors - number of processor descriptions in the @p processors array.
|
||||
* @param usable_processors - number of processor descriptions in the @p processors array with both POSSIBLE and
|
||||
* PRESENT flags.
|
||||
* @param[in,out] processors - array of logical processor descriptions with pre-parsed MIDR, maximum frequency,
|
||||
* and decoded core cluster (package_leader_id) information.
|
||||
* Upon return, processors[i].midr for all clusters' leaders contains the MIDR value.
|
||||
*
|
||||
* @returns The number of core clusters
|
||||
*/
|
||||
uint32_t cpuinfo_arm_linux_detect_cluster_midr(
|
||||
const struct cpuinfo_arm_chipset chipset[restrict static 1],
|
||||
uint32_t max_processors,
|
||||
uint32_t usable_processors,
|
||||
struct cpuinfo_arm_linux_processor processors[restrict static max_processors])
|
||||
{
|
||||
uint32_t clusters_count = 0;
|
||||
uint32_t cluster_leaders[CLUSTERS_MAX];
|
||||
uint32_t last_processor_in_cpuinfo = max_processors;
|
||||
uint32_t last_processor_with_midr = max_processors;
|
||||
uint32_t processors_with_midr_count = 0;
|
||||
for (uint32_t i = 0; i < max_processors; i++) {
|
||||
if (bitmask_all(processors[i].flags, CPUINFO_LINUX_FLAG_VALID)) {
|
||||
if (processors[i].flags & CPUINFO_ARM_LINUX_VALID_PROCESSOR) {
|
||||
last_processor_in_cpuinfo = i;
|
||||
}
|
||||
if (bitmask_all(processors[i].flags, CPUINFO_ARM_LINUX_VALID_IMPLEMENTER | CPUINFO_ARM_LINUX_VALID_PART)) {
|
||||
last_processor_with_midr = i;
|
||||
processors_with_midr_count += 1;
|
||||
}
|
||||
const uint32_t group_leader = processors[i].package_leader_id;
|
||||
if (group_leader == i) {
|
||||
if (clusters_count < CLUSTERS_MAX) {
|
||||
cluster_leaders[clusters_count] = i;
|
||||
}
|
||||
clusters_count += 1;
|
||||
} else {
|
||||
/* Copy known bits of information to cluster leader */
|
||||
|
||||
if ((processors[i].flags & ~processors[group_leader].flags) & CPUINFO_LINUX_FLAG_MAX_FREQUENCY) {
|
||||
processors[group_leader].max_frequency = processors[i].max_frequency;
|
||||
processors[group_leader].flags |= CPUINFO_LINUX_FLAG_MAX_FREQUENCY;
|
||||
}
|
||||
if (!bitmask_all(processors[group_leader].flags, CPUINFO_ARM_LINUX_VALID_MIDR) &&
|
||||
bitmask_all(processors[i].flags, CPUINFO_ARM_LINUX_VALID_MIDR))
|
||||
{
|
||||
processors[group_leader].midr = processors[i].midr;
|
||||
processors[group_leader].flags |= CPUINFO_ARM_LINUX_VALID_MIDR;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
cpuinfo_log_debug("detected %"PRIu32" core clusters", clusters_count);
|
||||
|
||||
/*
|
||||
* Two relations between reported /proc/cpuinfo information, and cores is possible:
|
||||
* - /proc/cpuinfo reports information for all or some of the cores below the corresponding
|
||||
* "processor : <number>" lines. Information on offline cores may be missing.
|
||||
* - /proc/cpuinfo reports information only once, after all "processor : <number>" lines.
|
||||
* The reported information may relate to processor #0 or to the processor which
|
||||
* executed the system calls to read /proc/cpuinfo. It is also indistinguishable
|
||||
* from /proc/cpuinfo reporting information only for the last core (e.g. if all other
|
||||
* cores are offline).
|
||||
*
|
||||
* We detect the second case by checking if /proc/cpuinfo contains valid MIDR only for one,
|
||||
* last reported, processor. Note, that the last reported core may be not the last
|
||||
* present & possible processor, as /proc/cpuinfo may non-report high-index offline cores.
|
||||
*/
|
||||
if (processors_with_midr_count == 1 && last_processor_in_cpuinfo == last_processor_with_midr && clusters_count > 1) {
|
||||
/*
|
||||
* There are multiple core clusters, but /proc/cpuinfo reported MIDR only for one
|
||||
* processor, and we don't even know which logical processor this information refers to.
|
||||
*
|
||||
* We make three attempts to detect MIDR for all clusters:
|
||||
* 1. Search tabulated MIDR values for chipsets which have heterogeneous clusters and ship with Linux
|
||||
* kernels which do not always report all cores in /proc/cpuinfo. If found, use the tabulated values.
|
||||
* 2. For systems with 2 clusters and MIDR known for one cluster, assume big.LITTLE configuration,
|
||||
* and estimate MIDR for the other cluster under assumption that MIDR for the big cluster is known.
|
||||
* 3. Initialize MIDRs for all core clusters to the only parsed MIDR value.
|
||||
*/
|
||||
cpuinfo_log_debug("the only reported MIDR can not be attributed to a particular processor");
|
||||
|
||||
if (cpuinfo_arm_linux_detect_cluster_midr_by_chipset(
|
||||
chipset, clusters_count, cluster_leaders, usable_processors, processors, false))
|
||||
{
|
||||
return clusters_count;
|
||||
}
|
||||
|
||||
/* Try big.LITTLE heuristic */
|
||||
if (cpuinfo_arm_linux_detect_cluster_midr_by_big_little_heuristic(
|
||||
clusters_count, 1, last_processor_with_midr,
|
||||
cluster_leaders, processors, false))
|
||||
{
|
||||
return clusters_count;
|
||||
}
|
||||
|
||||
/* Fall back to sequential initialization of MIDR values for core clusters */
|
||||
cpuinfo_arm_linux_detect_cluster_midr_by_sequential_scan(
|
||||
processors[processors[last_processor_with_midr].package_leader_id].midr,
|
||||
max_processors, processors);
|
||||
} else if (processors_with_midr_count < usable_processors) {
|
||||
/*
|
||||
* /proc/cpuinfo reported MIDR only for some processors, and probably some core clusters do not have MIDR
|
||||
* for any of the cores. Check if this is the case.
|
||||
*/
|
||||
uint32_t clusters_with_midr_count = 0;
|
||||
for (uint32_t i = 0; i < max_processors; i++) {
|
||||
if (bitmask_all(processors[i].flags, CPUINFO_LINUX_FLAG_VALID | CPUINFO_ARM_LINUX_VALID_MIDR)) {
|
||||
if (processors[i].package_leader_id == i) {
|
||||
clusters_with_midr_count += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (clusters_with_midr_count < clusters_count) {
|
||||
/*
|
||||
* /proc/cpuinfo reported MIDR only for some clusters, need to reconstruct others.
|
||||
* We make three attempts to detect MIDR for clusters without it:
|
||||
* 1. Search tabulated MIDR values for chipsets which have heterogeneous clusters and ship with Linux
|
||||
* kernels which do not always report all cores in /proc/cpuinfo. If found, use the tabulated values.
|
||||
* 2. For systems with 2 clusters and MIDR known for one cluster, assume big.LITTLE configuration,
|
||||
* and estimate MIDR for the other cluster under assumption that MIDR for the big cluster is known.
|
||||
* 3. Initialize MIDRs for core clusters in a single sequential scan:
|
||||
* - Clusters preceeding the first reported MIDR value are assumed to have the last reported MIDR value.
|
||||
* - Clusters following any reported MIDR value to have that MIDR value.
|
||||
*/
|
||||
|
||||
if (cpuinfo_arm_linux_detect_cluster_midr_by_chipset(
|
||||
chipset, clusters_count, cluster_leaders, usable_processors, processors, true))
|
||||
{
|
||||
return clusters_count;
|
||||
}
|
||||
|
||||
if (last_processor_with_midr != max_processors) {
|
||||
/* Try big.LITTLE heuristic */
|
||||
if (cpuinfo_arm_linux_detect_cluster_midr_by_big_little_heuristic(
|
||||
clusters_count, processors_with_midr_count, last_processor_with_midr,
|
||||
cluster_leaders, processors, true))
|
||||
{
|
||||
return clusters_count;
|
||||
}
|
||||
|
||||
/* Fall back to sequential initialization of MIDR values for core clusters */
|
||||
cpuinfo_arm_linux_detect_cluster_midr_by_sequential_scan(
|
||||
processors[processors[last_processor_with_midr].package_leader_id].midr,
|
||||
max_processors, processors);
|
||||
}
|
||||
}
|
||||
}
|
||||
return clusters_count;
|
||||
}
|
||||
619
3rdparty/cpuinfo/src/arm/mach/init.c
vendored
Normal file
619
3rdparty/cpuinfo/src/arm/mach/init.c
vendored
Normal file
@@ -0,0 +1,619 @@
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <alloca.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <mach/machine.h>
|
||||
|
||||
#include <cpuinfo.h>
|
||||
#include <mach/api.h>
|
||||
#include <cpuinfo/internal-api.h>
|
||||
#include <cpuinfo/log.h>
|
||||
|
||||
/* Polyfill recent CPUFAMILY_ARM_* values for older SDKs */
|
||||
#ifndef CPUFAMILY_ARM_MONSOON_MISTRAL
|
||||
#define CPUFAMILY_ARM_MONSOON_MISTRAL 0xE81E7EF6
|
||||
#endif
|
||||
#ifndef CPUFAMILY_ARM_VORTEX_TEMPEST
|
||||
#define CPUFAMILY_ARM_VORTEX_TEMPEST 0x07D34B9F
|
||||
#endif
|
||||
#ifndef CPUFAMILY_ARM_LIGHTNING_THUNDER
|
||||
#define CPUFAMILY_ARM_LIGHTNING_THUNDER 0x462504D2
|
||||
#endif
|
||||
#ifndef CPUFAMILY_ARM_FIRESTORM_ICESTORM
|
||||
#define CPUFAMILY_ARM_FIRESTORM_ICESTORM 0x1B588BB3
|
||||
#endif
|
||||
|
||||
struct cpuinfo_arm_isa cpuinfo_isa = {
|
||||
#if CPUINFO_ARCH_ARM
|
||||
.thumb = true,
|
||||
.thumb2 = true,
|
||||
.thumbee = false,
|
||||
.jazelle = false,
|
||||
.armv5e = true,
|
||||
.armv6 = true,
|
||||
.armv6k = true,
|
||||
.armv7 = true,
|
||||
.vfpv2 = false,
|
||||
.vfpv3 = true,
|
||||
.d32 = true,
|
||||
.wmmx = false,
|
||||
.wmmx2 = false,
|
||||
.neon = true,
|
||||
#endif
|
||||
#if CPUINFO_ARCH_ARM64
|
||||
.aes = true,
|
||||
.sha1 = true,
|
||||
.sha2 = true,
|
||||
.pmull = true,
|
||||
.crc32 = true,
|
||||
#endif
|
||||
};
|
||||
|
||||
static uint32_t get_sys_info(int type_specifier, const char* name) {
|
||||
size_t size = 0;
|
||||
uint32_t result = 0;
|
||||
int mib[2] = { CTL_HW, type_specifier };
|
||||
if (sysctl(mib, 2, NULL, &size, NULL, 0) != 0) {
|
||||
cpuinfo_log_info("sysctl(\"%s\") failed: %s", name, strerror(errno));
|
||||
} else if (size == sizeof(uint32_t)) {
|
||||
sysctl(mib, 2, &result, &size, NULL, 0);
|
||||
cpuinfo_log_debug("%s: %"PRIu32 ", size = %lu", name, result, size);
|
||||
} else {
|
||||
cpuinfo_log_info("sysctl does not support non-integer lookup for (\"%s\")", name);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static uint32_t get_sys_info_by_name(const char* type_specifier) {
|
||||
size_t size = 0;
|
||||
uint32_t result = 0;
|
||||
if (sysctlbyname(type_specifier, NULL, &size, NULL, 0) != 0) {
|
||||
cpuinfo_log_info("sysctlbyname(\"%s\") failed: %s", type_specifier, strerror(errno));
|
||||
} else if (size == sizeof(uint32_t)) {
|
||||
sysctlbyname(type_specifier, &result, &size, NULL, 0);
|
||||
cpuinfo_log_debug("%s: %"PRIu32 ", size = %lu", type_specifier, result, size);
|
||||
} else {
|
||||
cpuinfo_log_info("sysctl does not support non-integer lookup for (\"%s\")", type_specifier);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static enum cpuinfo_uarch decode_uarch(uint32_t cpu_family, uint32_t cpu_subtype, uint32_t core_index, uint32_t core_count) {
|
||||
switch (cpu_family) {
|
||||
case CPUFAMILY_ARM_SWIFT:
|
||||
return cpuinfo_uarch_swift;
|
||||
case CPUFAMILY_ARM_CYCLONE:
|
||||
return cpuinfo_uarch_cyclone;
|
||||
case CPUFAMILY_ARM_TYPHOON:
|
||||
return cpuinfo_uarch_typhoon;
|
||||
case CPUFAMILY_ARM_TWISTER:
|
||||
return cpuinfo_uarch_twister;
|
||||
case CPUFAMILY_ARM_HURRICANE:
|
||||
return cpuinfo_uarch_hurricane;
|
||||
case CPUFAMILY_ARM_MONSOON_MISTRAL:
|
||||
/* 2x Monsoon + 4x Mistral cores */
|
||||
return core_index < 2 ? cpuinfo_uarch_monsoon : cpuinfo_uarch_mistral;
|
||||
case CPUFAMILY_ARM_VORTEX_TEMPEST:
|
||||
/* Hexa-core: 2x Vortex + 4x Tempest; Octa-core: 4x Cortex + 4x Tempest */
|
||||
return core_index + 4 < core_count ? cpuinfo_uarch_vortex : cpuinfo_uarch_tempest;
|
||||
case CPUFAMILY_ARM_LIGHTNING_THUNDER:
|
||||
/* Hexa-core: 2x Lightning + 4x Thunder; Octa-core (presumed): 4x Lightning + 4x Thunder */
|
||||
return core_index + 4 < core_count ? cpuinfo_uarch_lightning : cpuinfo_uarch_thunder;
|
||||
case CPUFAMILY_ARM_FIRESTORM_ICESTORM:
|
||||
/* Hexa-core: 2x Firestorm + 4x Icestorm; Octa-core: 4x Firestorm + 4x Icestorm */
|
||||
return core_index + 4 < core_count ? cpuinfo_uarch_firestorm : cpuinfo_uarch_icestorm;
|
||||
default:
|
||||
/* Use hw.cpusubtype for detection */
|
||||
break;
|
||||
}
|
||||
|
||||
#if CPUINFO_ARCH_ARM
|
||||
switch (cpu_subtype) {
|
||||
case CPU_SUBTYPE_ARM_V7:
|
||||
return cpuinfo_uarch_cortex_a8;
|
||||
case CPU_SUBTYPE_ARM_V7F:
|
||||
return cpuinfo_uarch_cortex_a9;
|
||||
case CPU_SUBTYPE_ARM_V7K:
|
||||
return cpuinfo_uarch_cortex_a7;
|
||||
default:
|
||||
return cpuinfo_uarch_unknown;
|
||||
}
|
||||
#else
|
||||
return cpuinfo_uarch_unknown;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void decode_package_name(char* package_name) {
|
||||
size_t size;
|
||||
if (sysctlbyname("hw.machine", NULL, &size, NULL, 0) != 0) {
|
||||
cpuinfo_log_warning("sysctlbyname(\"hw.machine\") failed: %s", strerror(errno));
|
||||
return;
|
||||
}
|
||||
|
||||
char *machine_name = alloca(size);
|
||||
if (sysctlbyname("hw.machine", machine_name, &size, NULL, 0) != 0) {
|
||||
cpuinfo_log_warning("sysctlbyname(\"hw.machine\") failed: %s", strerror(errno));
|
||||
return;
|
||||
}
|
||||
cpuinfo_log_debug("hw.machine: %s", machine_name);
|
||||
|
||||
char name[10];
|
||||
uint32_t major = 0, minor = 0;
|
||||
if (sscanf(machine_name, "%9[^,0123456789]%"SCNu32",%"SCNu32, name, &major, &minor) != 3) {
|
||||
cpuinfo_log_warning("parsing \"hw.machine\" failed: %s", strerror(errno));
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t chip_model = 0;
|
||||
char suffix = '\0';
|
||||
if (strcmp(name, "iPhone") == 0) {
|
||||
/*
|
||||
* iPhone 4 and up are supported:
|
||||
* - iPhone 4 [A4]: iPhone3,1, iPhone3,2, iPhone3,3
|
||||
* - iPhone 4S [A5]: iPhone4,1
|
||||
* - iPhone 5 [A6]: iPhone5,1, iPhone5,2
|
||||
* - iPhone 5c [A6]: iPhone5,3, iPhone5,4
|
||||
* - iPhone 5s [A7]: iPhone6,1, iPhone6,2
|
||||
* - iPhone 6 [A8]: iPhone7,2
|
||||
* - iPhone 6 Plus [A8]: iPhone7,1
|
||||
* - iPhone 6s [A9]: iPhone8,1
|
||||
* - iPhone 6s Plus [A9]: iPhone8,2
|
||||
* - iPhone SE [A9]: iPhone8,4
|
||||
* - iPhone 7 [A10]: iPhone9,1, iPhone9,3
|
||||
* - iPhone 7 Plus [A10]: iPhone9,2, iPhone9,4
|
||||
* - iPhone 8 [A11]: iPhone10,1, iPhone10,4
|
||||
* - iPhone 8 Plus [A11]: iPhone10,2, iPhone10,5
|
||||
* - iPhone X [A11]: iPhone10,3, iPhone10,6
|
||||
* - iPhone XS [A12]: iPhone11,2,
|
||||
* - iPhone XS Max [A12]: iPhone11,4, iPhone11,6
|
||||
* - iPhone XR [A12]: iPhone11,8
|
||||
*/
|
||||
chip_model = major + 1;
|
||||
} else if (strcmp(name, "iPad") == 0) {
|
||||
switch (major) {
|
||||
/* iPad 2 and up are supported */
|
||||
case 2:
|
||||
/*
|
||||
* iPad 2 [A5]: iPad2,1, iPad2,2, iPad2,3, iPad2,4
|
||||
* iPad mini [A5]: iPad2,5, iPad2,6, iPad2,7
|
||||
*/
|
||||
chip_model = major + 3;
|
||||
break;
|
||||
case 3:
|
||||
/*
|
||||
* iPad 3rd Gen [A5X]: iPad3,1, iPad3,2, iPad3,3
|
||||
* iPad 4th Gen [A6X]: iPad3,4, iPad3,5, iPad3,6
|
||||
*/
|
||||
chip_model = (minor <= 3) ? 5 : 6;
|
||||
suffix = 'X';
|
||||
break;
|
||||
case 4:
|
||||
/*
|
||||
* iPad Air [A7]: iPad4,1, iPad4,2, iPad4,3
|
||||
* iPad mini Retina [A7]: iPad4,4, iPad4,5, iPad4,6
|
||||
* iPad mini 3 [A7]: iPad4,7, iPad4,8, iPad4,9
|
||||
*/
|
||||
chip_model = major + 3;
|
||||
break;
|
||||
case 5:
|
||||
/*
|
||||
* iPad mini 4 [A8]: iPad5,1, iPad5,2
|
||||
* iPad Air 2 [A8X]: iPad5,3, iPad5,4
|
||||
*/
|
||||
chip_model = major + 3;
|
||||
suffix = (minor <= 2) ? '\0' : 'X';
|
||||
break;
|
||||
case 6:
|
||||
/*
|
||||
* iPad Pro 9.7" [A9X]: iPad6,3, iPad6,4
|
||||
* iPad Pro [A9X]: iPad6,7, iPad6,8
|
||||
* iPad 5th Gen [A9]: iPad6,11, iPad6,12
|
||||
*/
|
||||
chip_model = major + 3;
|
||||
suffix = minor <= 8 ? 'X' : '\0';
|
||||
break;
|
||||
case 7:
|
||||
/*
|
||||
* iPad Pro 12.9" [A10X]: iPad7,1, iPad7,2
|
||||
* iPad Pro 10.5" [A10X]: iPad7,3, iPad7,4
|
||||
* iPad 6th Gen [A10]: iPad7,5, iPad7,6
|
||||
*/
|
||||
chip_model = major + 3;
|
||||
suffix = minor <= 4 ? 'X' : '\0';
|
||||
break;
|
||||
default:
|
||||
cpuinfo_log_info("unknown iPad: %s", machine_name);
|
||||
break;
|
||||
}
|
||||
} else if (strcmp(name, "iPod") == 0) {
|
||||
switch (major) {
|
||||
case 5:
|
||||
chip_model = 5;
|
||||
break;
|
||||
/* iPod touch (5th Gen) [A5]: iPod5,1 */
|
||||
case 7:
|
||||
/* iPod touch (6th Gen, 2015) [A8]: iPod7,1 */
|
||||
chip_model = 8;
|
||||
break;
|
||||
default:
|
||||
cpuinfo_log_info("unknown iPod: %s", machine_name);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
cpuinfo_log_info("unknown device: %s", machine_name);
|
||||
}
|
||||
if (chip_model != 0) {
|
||||
snprintf(package_name, CPUINFO_PACKAGE_NAME_MAX, "Apple A%"PRIu32"%c", chip_model, suffix);
|
||||
}
|
||||
}
|
||||
|
||||
void cpuinfo_arm_mach_init(void) {
|
||||
struct cpuinfo_processor* processors = NULL;
|
||||
struct cpuinfo_core* cores = NULL;
|
||||
struct cpuinfo_cluster* clusters = NULL;
|
||||
struct cpuinfo_package* packages = NULL;
|
||||
struct cpuinfo_uarch_info* uarchs = NULL;
|
||||
struct cpuinfo_cache* l1i = NULL;
|
||||
struct cpuinfo_cache* l1d = NULL;
|
||||
struct cpuinfo_cache* l2 = NULL;
|
||||
struct cpuinfo_cache* l3 = NULL;
|
||||
|
||||
struct cpuinfo_mach_topology mach_topology = cpuinfo_mach_detect_topology();
|
||||
processors = calloc(mach_topology.threads, sizeof(struct cpuinfo_processor));
|
||||
if (processors == NULL) {
|
||||
cpuinfo_log_error("failed to allocate %zu bytes for descriptions of %"PRIu32" logical processors",
|
||||
mach_topology.threads * sizeof(struct cpuinfo_processor), mach_topology.threads);
|
||||
goto cleanup;
|
||||
}
|
||||
cores = calloc(mach_topology.cores, sizeof(struct cpuinfo_core));
|
||||
if (cores == NULL) {
|
||||
cpuinfo_log_error("failed to allocate %zu bytes for descriptions of %"PRIu32" cores",
|
||||
mach_topology.cores * sizeof(struct cpuinfo_core), mach_topology.cores);
|
||||
goto cleanup;
|
||||
}
|
||||
packages = calloc(mach_topology.packages, sizeof(struct cpuinfo_package));
|
||||
if (packages == NULL) {
|
||||
cpuinfo_log_error("failed to allocate %zu bytes for descriptions of %"PRIu32" packages",
|
||||
mach_topology.packages * sizeof(struct cpuinfo_package), mach_topology.packages);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
const uint32_t threads_per_core = mach_topology.threads / mach_topology.cores;
|
||||
const uint32_t threads_per_package = mach_topology.threads / mach_topology.packages;
|
||||
const uint32_t cores_per_package = mach_topology.cores / mach_topology.packages;
|
||||
|
||||
for (uint32_t i = 0; i < mach_topology.packages; i++) {
|
||||
packages[i] = (struct cpuinfo_package) {
|
||||
.processor_start = i * threads_per_package,
|
||||
.processor_count = threads_per_package,
|
||||
.core_start = i * cores_per_package,
|
||||
.core_count = cores_per_package,
|
||||
};
|
||||
decode_package_name(packages[i].name);
|
||||
}
|
||||
|
||||
|
||||
const uint32_t cpu_family = get_sys_info_by_name("hw.cpufamily");
|
||||
const uint32_t cpu_type = get_sys_info_by_name("hw.cputype");
|
||||
const uint32_t cpu_subtype = get_sys_info_by_name("hw.cpusubtype");
|
||||
switch (cpu_type) {
|
||||
case CPU_TYPE_ARM64:
|
||||
cpuinfo_isa.aes = true;
|
||||
cpuinfo_isa.sha1 = true;
|
||||
cpuinfo_isa.sha2 = true;
|
||||
cpuinfo_isa.pmull = true;
|
||||
cpuinfo_isa.crc32 = true;
|
||||
break;
|
||||
#if CPUINFO_ARCH_ARM
|
||||
case CPU_TYPE_ARM:
|
||||
switch (cpu_subtype) {
|
||||
case CPU_SUBTYPE_ARM_V8:
|
||||
cpuinfo_isa.armv8 = true;
|
||||
cpuinfo_isa.aes = true;
|
||||
cpuinfo_isa.sha1 = true;
|
||||
cpuinfo_isa.sha2 = true;
|
||||
cpuinfo_isa.pmull = true;
|
||||
cpuinfo_isa.crc32 = true;
|
||||
/* Fall-through to add ARMv7S features */
|
||||
case CPU_SUBTYPE_ARM_V7S:
|
||||
case CPU_SUBTYPE_ARM_V7K:
|
||||
cpuinfo_isa.fma = true;
|
||||
/* Fall-through to add ARMv7F features */
|
||||
case CPU_SUBTYPE_ARM_V7F:
|
||||
cpuinfo_isa.armv7mp = true;
|
||||
cpuinfo_isa.fp16 = true;
|
||||
/* Fall-through to add ARMv7 features */
|
||||
case CPU_SUBTYPE_ARM_V7:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
/*
|
||||
* Support for ARMv8.1 Atomics & FP16 arithmetic instructions is supposed to be detected via
|
||||
* sysctlbyname calls with "hw.optional.armv8_1_atomics" and "hw.optional.neon_fp16" arguments
|
||||
* (see https://devstreaming-cdn.apple.com/videos/wwdc/2018/409t8zw7rumablsh/409/409_whats_new_in_llvm.pdf),
|
||||
* but on new iOS versions these calls just fail with EPERM.
|
||||
*
|
||||
* Thus, we whitelist CPUs known to support these instructions.
|
||||
*/
|
||||
switch (cpu_family) {
|
||||
case CPUFAMILY_ARM_MONSOON_MISTRAL:
|
||||
case CPUFAMILY_ARM_VORTEX_TEMPEST:
|
||||
case CPUFAMILY_ARM_LIGHTNING_THUNDER:
|
||||
case CPUFAMILY_ARM_FIRESTORM_ICESTORM:
|
||||
#if CPUINFO_ARCH_ARM64
|
||||
cpuinfo_isa.atomics = true;
|
||||
#endif
|
||||
cpuinfo_isa.fp16arith = true;
|
||||
}
|
||||
|
||||
/*
|
||||
* There does not yet seem to exist an OS mechanism to detect support for
|
||||
* ARMv8.2 optional dot-product instructions, so we currently whitelist CPUs
|
||||
* known to support these instruction.
|
||||
*/
|
||||
switch (cpu_family) {
|
||||
case CPUFAMILY_ARM_LIGHTNING_THUNDER:
|
||||
case CPUFAMILY_ARM_FIRESTORM_ICESTORM:
|
||||
cpuinfo_isa.dot = true;
|
||||
}
|
||||
|
||||
uint32_t num_clusters = 1;
|
||||
for (uint32_t i = 0; i < mach_topology.cores; i++) {
|
||||
cores[i] = (struct cpuinfo_core) {
|
||||
.processor_start = i * threads_per_core,
|
||||
.processor_count = threads_per_core,
|
||||
.core_id = i % cores_per_package,
|
||||
.package = packages + i / cores_per_package,
|
||||
.vendor = cpuinfo_vendor_apple,
|
||||
.uarch = decode_uarch(cpu_family, cpu_subtype, i, mach_topology.cores),
|
||||
};
|
||||
if (i != 0 && cores[i].uarch != cores[i - 1].uarch) {
|
||||
num_clusters++;
|
||||
}
|
||||
}
|
||||
for (uint32_t i = 0; i < mach_topology.threads; i++) {
|
||||
const uint32_t smt_id = i % threads_per_core;
|
||||
const uint32_t core_id = i / threads_per_core;
|
||||
const uint32_t package_id = i / threads_per_package;
|
||||
|
||||
processors[i].smt_id = smt_id;
|
||||
processors[i].core = &cores[core_id];
|
||||
processors[i].package = &packages[package_id];
|
||||
}
|
||||
|
||||
clusters = calloc(num_clusters, sizeof(struct cpuinfo_cluster));
|
||||
if (clusters == NULL) {
|
||||
cpuinfo_log_error(
|
||||
"failed to allocate %zu bytes for descriptions of %"PRIu32" clusters",
|
||||
num_clusters * sizeof(struct cpuinfo_cluster), num_clusters);
|
||||
goto cleanup;
|
||||
}
|
||||
uarchs = calloc(num_clusters, sizeof(struct cpuinfo_uarch_info));
|
||||
if (uarchs == NULL) {
|
||||
cpuinfo_log_error(
|
||||
"failed to allocate %zu bytes for descriptions of %"PRIu32" uarchs",
|
||||
num_clusters * sizeof(enum cpuinfo_uarch), num_clusters);
|
||||
goto cleanup;
|
||||
}
|
||||
uint32_t cluster_idx = UINT32_MAX;
|
||||
for (uint32_t i = 0; i < mach_topology.cores; i++) {
|
||||
if (i == 0 || cores[i].uarch != cores[i - 1].uarch) {
|
||||
cluster_idx++;
|
||||
uarchs[cluster_idx] = (struct cpuinfo_uarch_info) {
|
||||
.uarch = cores[i].uarch,
|
||||
.processor_count = 1,
|
||||
.core_count = 1,
|
||||
};
|
||||
clusters[cluster_idx] = (struct cpuinfo_cluster) {
|
||||
.processor_start = i * threads_per_core,
|
||||
.processor_count = 1,
|
||||
.core_start = i,
|
||||
.core_count = 1,
|
||||
.cluster_id = cluster_idx,
|
||||
.package = cores[i].package,
|
||||
.vendor = cores[i].vendor,
|
||||
.uarch = cores[i].uarch,
|
||||
};
|
||||
} else {
|
||||
uarchs[cluster_idx].processor_count++;
|
||||
uarchs[cluster_idx].core_count++;
|
||||
clusters[cluster_idx].processor_count++;
|
||||
clusters[cluster_idx].core_count++;
|
||||
}
|
||||
cores[i].cluster = &clusters[cluster_idx];
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < mach_topology.threads; i++) {
|
||||
const uint32_t core_id = i / threads_per_core;
|
||||
processors[i].cluster = cores[core_id].cluster;
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < mach_topology.packages; i++) {
|
||||
packages[i].cluster_start = 0;
|
||||
packages[i].cluster_count = num_clusters;
|
||||
}
|
||||
|
||||
const uint32_t cacheline_size = get_sys_info(HW_CACHELINE, "HW_CACHELINE");
|
||||
const uint32_t l1d_cache_size = get_sys_info(HW_L1DCACHESIZE, "HW_L1DCACHESIZE");
|
||||
const uint32_t l1i_cache_size = get_sys_info(HW_L1ICACHESIZE, "HW_L1ICACHESIZE");
|
||||
const uint32_t l2_cache_size = get_sys_info(HW_L2CACHESIZE, "HW_L2CACHESIZE");
|
||||
const uint32_t l3_cache_size = get_sys_info(HW_L3CACHESIZE, "HW_L3CACHESIZE");
|
||||
const uint32_t l1_cache_associativity = 4;
|
||||
const uint32_t l2_cache_associativity = 8;
|
||||
const uint32_t l3_cache_associativity = 16;
|
||||
const uint32_t cache_partitions = 1;
|
||||
const uint32_t cache_flags = 0;
|
||||
|
||||
uint32_t threads_per_l1 = 0, l1_count = 0;
|
||||
if (l1i_cache_size != 0 || l1d_cache_size != 0) {
|
||||
/* Assume L1 caches are private to each core */
|
||||
threads_per_l1 = 1;
|
||||
l1_count = mach_topology.threads / threads_per_l1;
|
||||
cpuinfo_log_debug("detected %"PRIu32" L1 caches", l1_count);
|
||||
}
|
||||
|
||||
uint32_t threads_per_l2 = 0, l2_count = 0;
|
||||
if (l2_cache_size != 0) {
|
||||
/* Assume L2 cache is shared between all cores */
|
||||
threads_per_l2 = mach_topology.cores;
|
||||
l2_count = 1;
|
||||
cpuinfo_log_debug("detected %"PRIu32" L2 caches", l2_count);
|
||||
}
|
||||
|
||||
uint32_t threads_per_l3 = 0, l3_count = 0;
|
||||
if (l3_cache_size != 0) {
|
||||
/* Assume L3 cache is shared between all cores */
|
||||
threads_per_l3 = mach_topology.cores;
|
||||
l3_count = 1;
|
||||
cpuinfo_log_debug("detected %"PRIu32" L3 caches", l3_count);
|
||||
}
|
||||
|
||||
if (l1i_cache_size != 0) {
|
||||
l1i = calloc(l1_count, sizeof(struct cpuinfo_cache));
|
||||
if (l1i == NULL) {
|
||||
cpuinfo_log_error("failed to allocate %zu bytes for descriptions of %"PRIu32" L1I caches",
|
||||
l1_count * sizeof(struct cpuinfo_cache), l1_count);
|
||||
goto cleanup;
|
||||
}
|
||||
for (uint32_t c = 0; c < l1_count; c++) {
|
||||
l1i[c] = (struct cpuinfo_cache) {
|
||||
.size = l1i_cache_size,
|
||||
.associativity = l1_cache_associativity,
|
||||
.sets = l1i_cache_size / (l1_cache_associativity * cacheline_size),
|
||||
.partitions = cache_partitions,
|
||||
.line_size = cacheline_size,
|
||||
.flags = cache_flags,
|
||||
.processor_start = c * threads_per_l1,
|
||||
.processor_count = threads_per_l1,
|
||||
};
|
||||
}
|
||||
for (uint32_t t = 0; t < mach_topology.threads; t++) {
|
||||
processors[t].cache.l1i = &l1i[t / threads_per_l1];
|
||||
}
|
||||
}
|
||||
|
||||
if (l1d_cache_size != 0) {
|
||||
l1d = calloc(l1_count, sizeof(struct cpuinfo_cache));
|
||||
if (l1d == NULL) {
|
||||
cpuinfo_log_error("failed to allocate %zu bytes for descriptions of %"PRIu32" L1D caches",
|
||||
l1_count * sizeof(struct cpuinfo_cache), l1_count);
|
||||
goto cleanup;
|
||||
}
|
||||
for (uint32_t c = 0; c < l1_count; c++) {
|
||||
l1d[c] = (struct cpuinfo_cache) {
|
||||
.size = l1d_cache_size,
|
||||
.associativity = l1_cache_associativity,
|
||||
.sets = l1d_cache_size / (l1_cache_associativity * cacheline_size),
|
||||
.partitions = cache_partitions,
|
||||
.line_size = cacheline_size,
|
||||
.flags = cache_flags,
|
||||
.processor_start = c * threads_per_l1,
|
||||
.processor_count = threads_per_l1,
|
||||
};
|
||||
}
|
||||
for (uint32_t t = 0; t < mach_topology.threads; t++) {
|
||||
processors[t].cache.l1d = &l1d[t / threads_per_l1];
|
||||
}
|
||||
}
|
||||
|
||||
if (l2_count != 0) {
|
||||
l2 = calloc(l2_count, sizeof(struct cpuinfo_cache));
|
||||
if (l2 == NULL) {
|
||||
cpuinfo_log_error("failed to allocate %zu bytes for descriptions of %"PRIu32" L2 caches",
|
||||
l2_count * sizeof(struct cpuinfo_cache), l2_count);
|
||||
goto cleanup;
|
||||
}
|
||||
for (uint32_t c = 0; c < l2_count; c++) {
|
||||
l2[c] = (struct cpuinfo_cache) {
|
||||
.size = l2_cache_size,
|
||||
.associativity = l2_cache_associativity,
|
||||
.sets = l2_cache_size / (l2_cache_associativity * cacheline_size),
|
||||
.partitions = cache_partitions,
|
||||
.line_size = cacheline_size,
|
||||
.flags = cache_flags,
|
||||
.processor_start = c * threads_per_l2,
|
||||
.processor_count = threads_per_l2,
|
||||
};
|
||||
}
|
||||
for (uint32_t t = 0; t < mach_topology.threads; t++) {
|
||||
processors[t].cache.l2 = &l2[0];
|
||||
}
|
||||
}
|
||||
|
||||
if (l3_count != 0) {
|
||||
l3 = calloc(l3_count, sizeof(struct cpuinfo_cache));
|
||||
if (l3 == NULL) {
|
||||
cpuinfo_log_error("failed to allocate %zu bytes for descriptions of %"PRIu32" L3 caches",
|
||||
l3_count * sizeof(struct cpuinfo_cache), l3_count);
|
||||
goto cleanup;
|
||||
}
|
||||
for (uint32_t c = 0; c < l3_count; c++) {
|
||||
l3[c] = (struct cpuinfo_cache) {
|
||||
.size = l3_cache_size,
|
||||
.associativity = l3_cache_associativity,
|
||||
.sets = l3_cache_size / (l3_cache_associativity * cacheline_size),
|
||||
.partitions = cache_partitions,
|
||||
.line_size = cacheline_size,
|
||||
.flags = cache_flags,
|
||||
.processor_start = c * threads_per_l3,
|
||||
.processor_count = threads_per_l3,
|
||||
};
|
||||
}
|
||||
for (uint32_t t = 0; t < mach_topology.threads; t++) {
|
||||
processors[t].cache.l3 = &l3[0];
|
||||
}
|
||||
}
|
||||
|
||||
/* Commit changes */
|
||||
cpuinfo_processors = processors;
|
||||
cpuinfo_cores = cores;
|
||||
cpuinfo_clusters = clusters;
|
||||
cpuinfo_packages = packages;
|
||||
cpuinfo_uarchs = uarchs;
|
||||
cpuinfo_cache[cpuinfo_cache_level_1i] = l1i;
|
||||
cpuinfo_cache[cpuinfo_cache_level_1d] = l1d;
|
||||
cpuinfo_cache[cpuinfo_cache_level_2] = l2;
|
||||
cpuinfo_cache[cpuinfo_cache_level_3] = l3;
|
||||
|
||||
cpuinfo_processors_count = mach_topology.threads;
|
||||
cpuinfo_cores_count = mach_topology.cores;
|
||||
cpuinfo_clusters_count = num_clusters;
|
||||
cpuinfo_packages_count = mach_topology.packages;
|
||||
cpuinfo_uarchs_count = num_clusters;
|
||||
cpuinfo_cache_count[cpuinfo_cache_level_1i] = l1_count;
|
||||
cpuinfo_cache_count[cpuinfo_cache_level_1d] = l1_count;
|
||||
cpuinfo_cache_count[cpuinfo_cache_level_2] = l2_count;
|
||||
cpuinfo_cache_count[cpuinfo_cache_level_3] = l3_count;
|
||||
cpuinfo_max_cache_size = cpuinfo_compute_max_cache_size(&processors[0]);
|
||||
|
||||
__sync_synchronize();
|
||||
|
||||
cpuinfo_is_initialized = true;
|
||||
|
||||
processors = NULL;
|
||||
cores = NULL;
|
||||
clusters = NULL;
|
||||
packages = NULL;
|
||||
uarchs = NULL;
|
||||
l1i = l1d = l2 = l3 = NULL;
|
||||
|
||||
cleanup:
|
||||
free(processors);
|
||||
free(cores);
|
||||
free(clusters);
|
||||
free(packages);
|
||||
free(uarchs);
|
||||
free(l1i);
|
||||
free(l1d);
|
||||
free(l2);
|
||||
free(l3);
|
||||
}
|
||||
257
3rdparty/cpuinfo/src/arm/midr.h
vendored
Normal file
257
3rdparty/cpuinfo/src/arm/midr.h
vendored
Normal file
@@ -0,0 +1,257 @@
|
||||
#pragma once
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
#define CPUINFO_ARM_MIDR_IMPLEMENTER_MASK UINT32_C(0xFF000000)
|
||||
#define CPUINFO_ARM_MIDR_VARIANT_MASK UINT32_C(0x00F00000)
|
||||
#define CPUINFO_ARM_MIDR_ARCHITECTURE_MASK UINT32_C(0x000F0000)
|
||||
#define CPUINFO_ARM_MIDR_PART_MASK UINT32_C(0x0000FFF0)
|
||||
#define CPUINFO_ARM_MIDR_REVISION_MASK UINT32_C(0x0000000F)
|
||||
|
||||
#define CPUINFO_ARM_MIDR_IMPLEMENTER_OFFSET 24
|
||||
#define CPUINFO_ARM_MIDR_VARIANT_OFFSET 20
|
||||
#define CPUINFO_ARM_MIDR_ARCHITECTURE_OFFSET 16
|
||||
#define CPUINFO_ARM_MIDR_PART_OFFSET 4
|
||||
#define CPUINFO_ARM_MIDR_REVISION_OFFSET 0
|
||||
|
||||
#define CPUINFO_ARM_MIDR_ARM1156 UINT32_C(0x410FB560)
|
||||
#define CPUINFO_ARM_MIDR_CORTEX_A7 UINT32_C(0x410FC070)
|
||||
#define CPUINFO_ARM_MIDR_CORTEX_A9 UINT32_C(0x410FC090)
|
||||
#define CPUINFO_ARM_MIDR_CORTEX_A15 UINT32_C(0x410FC0F0)
|
||||
#define CPUINFO_ARM_MIDR_CORTEX_A17 UINT32_C(0x410FC0E0)
|
||||
#define CPUINFO_ARM_MIDR_CORTEX_A35 UINT32_C(0x410FD040)
|
||||
#define CPUINFO_ARM_MIDR_CORTEX_A53 UINT32_C(0x410FD030)
|
||||
#define CPUINFO_ARM_MIDR_CORTEX_A55 UINT32_C(0x410FD050)
|
||||
#define CPUINFO_ARM_MIDR_CORTEX_A57 UINT32_C(0x410FD070)
|
||||
#define CPUINFO_ARM_MIDR_CORTEX_A72 UINT32_C(0x410FD080)
|
||||
#define CPUINFO_ARM_MIDR_CORTEX_A73 UINT32_C(0x410FD090)
|
||||
#define CPUINFO_ARM_MIDR_CORTEX_A75 UINT32_C(0x410FD0A0)
|
||||
#define CPUINFO_ARM_MIDR_KRYO280_GOLD UINT32_C(0x51AF8001)
|
||||
#define CPUINFO_ARM_MIDR_KRYO280_SILVER UINT32_C(0x51AF8014)
|
||||
#define CPUINFO_ARM_MIDR_KRYO385_GOLD UINT32_C(0x518F802D)
|
||||
#define CPUINFO_ARM_MIDR_KRYO385_SILVER UINT32_C(0x518F803C)
|
||||
#define CPUINFO_ARM_MIDR_KRYO_SILVER_821 UINT32_C(0x510F2010)
|
||||
#define CPUINFO_ARM_MIDR_KRYO_GOLD UINT32_C(0x510F2050)
|
||||
#define CPUINFO_ARM_MIDR_KRYO_SILVER_820 UINT32_C(0x510F2110)
|
||||
#define CPUINFO_ARM_MIDR_EXYNOS_M1_M2 UINT32_C(0x530F0010)
|
||||
#define CPUINFO_ARM_MIDR_DENVER2 UINT32_C(0x4E0F0030)
|
||||
|
||||
inline static uint32_t midr_set_implementer(uint32_t midr, uint32_t implementer) {
|
||||
return (midr & ~CPUINFO_ARM_MIDR_IMPLEMENTER_MASK) |
|
||||
((implementer << CPUINFO_ARM_MIDR_IMPLEMENTER_OFFSET) & CPUINFO_ARM_MIDR_IMPLEMENTER_MASK);
|
||||
}
|
||||
|
||||
inline static uint32_t midr_set_variant(uint32_t midr, uint32_t variant) {
|
||||
return (midr & ~CPUINFO_ARM_MIDR_VARIANT_MASK) |
|
||||
((variant << CPUINFO_ARM_MIDR_VARIANT_OFFSET) & CPUINFO_ARM_MIDR_VARIANT_MASK);
|
||||
}
|
||||
|
||||
inline static uint32_t midr_set_architecture(uint32_t midr, uint32_t architecture) {
|
||||
return (midr & ~CPUINFO_ARM_MIDR_ARCHITECTURE_MASK) |
|
||||
((architecture << CPUINFO_ARM_MIDR_ARCHITECTURE_OFFSET) & CPUINFO_ARM_MIDR_ARCHITECTURE_MASK);
|
||||
}
|
||||
|
||||
inline static uint32_t midr_set_part(uint32_t midr, uint32_t part) {
|
||||
return (midr & ~CPUINFO_ARM_MIDR_PART_MASK) |
|
||||
((part << CPUINFO_ARM_MIDR_PART_OFFSET) & CPUINFO_ARM_MIDR_PART_MASK);
|
||||
}
|
||||
|
||||
inline static uint32_t midr_set_revision(uint32_t midr, uint32_t revision) {
|
||||
return (midr & ~CPUINFO_ARM_MIDR_REVISION_MASK) |
|
||||
((revision << CPUINFO_ARM_MIDR_REVISION_OFFSET) & CPUINFO_ARM_MIDR_REVISION_MASK);
|
||||
}
|
||||
|
||||
inline static uint32_t midr_get_variant(uint32_t midr) {
|
||||
return (midr & CPUINFO_ARM_MIDR_VARIANT_MASK) >> CPUINFO_ARM_MIDR_VARIANT_OFFSET;
|
||||
}
|
||||
|
||||
inline static uint32_t midr_get_implementer(uint32_t midr) {
|
||||
return (midr & CPUINFO_ARM_MIDR_IMPLEMENTER_MASK) >> CPUINFO_ARM_MIDR_IMPLEMENTER_OFFSET;
|
||||
}
|
||||
|
||||
inline static uint32_t midr_get_part(uint32_t midr) {
|
||||
return (midr & CPUINFO_ARM_MIDR_PART_MASK) >> CPUINFO_ARM_MIDR_PART_OFFSET;
|
||||
}
|
||||
|
||||
inline static uint32_t midr_get_revision(uint32_t midr) {
|
||||
return (midr & CPUINFO_ARM_MIDR_REVISION_MASK) >> CPUINFO_ARM_MIDR_REVISION_OFFSET;
|
||||
}
|
||||
|
||||
inline static uint32_t midr_copy_implementer(uint32_t midr, uint32_t other_midr) {
|
||||
return (midr & ~CPUINFO_ARM_MIDR_IMPLEMENTER_MASK) | (other_midr & CPUINFO_ARM_MIDR_IMPLEMENTER_MASK);
|
||||
}
|
||||
|
||||
inline static uint32_t midr_copy_variant(uint32_t midr, uint32_t other_midr) {
|
||||
return (midr & ~CPUINFO_ARM_MIDR_VARIANT_MASK) | (other_midr & CPUINFO_ARM_MIDR_VARIANT_MASK);
|
||||
}
|
||||
|
||||
inline static uint32_t midr_copy_architecture(uint32_t midr, uint32_t other_midr) {
|
||||
return (midr & ~CPUINFO_ARM_MIDR_ARCHITECTURE_MASK) | (other_midr & CPUINFO_ARM_MIDR_ARCHITECTURE_MASK);
|
||||
}
|
||||
|
||||
inline static uint32_t midr_copy_part(uint32_t midr, uint32_t other_midr) {
|
||||
return (midr & ~CPUINFO_ARM_MIDR_PART_MASK) | (other_midr & CPUINFO_ARM_MIDR_PART_MASK);
|
||||
}
|
||||
|
||||
inline static uint32_t midr_copy_revision(uint32_t midr, uint32_t other_midr) {
|
||||
return (midr & ~CPUINFO_ARM_MIDR_REVISION_MASK) | (other_midr & CPUINFO_ARM_MIDR_REVISION_MASK);
|
||||
}
|
||||
|
||||
inline static bool midr_is_arm1156(uint32_t midr) {
|
||||
const uint32_t uarch_mask = CPUINFO_ARM_MIDR_IMPLEMENTER_MASK | CPUINFO_ARM_MIDR_PART_MASK;
|
||||
return (midr & uarch_mask) == (CPUINFO_ARM_MIDR_ARM1156 & uarch_mask);
|
||||
}
|
||||
|
||||
inline static bool midr_is_arm11(uint32_t midr) {
|
||||
return (midr & (CPUINFO_ARM_MIDR_IMPLEMENTER_MASK | 0x0000F000)) == UINT32_C(0x4100B000);
|
||||
}
|
||||
|
||||
inline static bool midr_is_cortex_a9(uint32_t midr) {
|
||||
const uint32_t uarch_mask = CPUINFO_ARM_MIDR_IMPLEMENTER_MASK | CPUINFO_ARM_MIDR_PART_MASK;
|
||||
return (midr & uarch_mask) == (CPUINFO_ARM_MIDR_CORTEX_A9 & uarch_mask);
|
||||
}
|
||||
|
||||
inline static bool midr_is_scorpion(uint32_t midr) {
|
||||
switch (midr & (CPUINFO_ARM_MIDR_IMPLEMENTER_MASK | CPUINFO_ARM_MIDR_PART_MASK)) {
|
||||
case UINT32_C(0x510000F0):
|
||||
case UINT32_C(0x510002D0):
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
inline static bool midr_is_krait(uint32_t midr) {
|
||||
switch (midr & (CPUINFO_ARM_MIDR_IMPLEMENTER_MASK | CPUINFO_ARM_MIDR_PART_MASK)) {
|
||||
case UINT32_C(0x510004D0):
|
||||
case UINT32_C(0x510006F0):
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
inline static bool midr_is_cortex_a53(uint32_t midr) {
|
||||
const uint32_t uarch_mask = CPUINFO_ARM_MIDR_IMPLEMENTER_MASK | CPUINFO_ARM_MIDR_PART_MASK;
|
||||
return (midr & uarch_mask) == (CPUINFO_ARM_MIDR_CORTEX_A53 & uarch_mask);
|
||||
}
|
||||
|
||||
inline static bool midr_is_qualcomm_cortex_a53_silver(uint32_t midr) {
|
||||
const uint32_t uarch_mask = CPUINFO_ARM_MIDR_IMPLEMENTER_MASK | CPUINFO_ARM_MIDR_PART_MASK;
|
||||
return (midr & uarch_mask) == (CPUINFO_ARM_MIDR_KRYO280_SILVER & uarch_mask);
|
||||
}
|
||||
|
||||
inline static bool midr_is_qualcomm_cortex_a55_silver(uint32_t midr) {
|
||||
const uint32_t uarch_mask = CPUINFO_ARM_MIDR_IMPLEMENTER_MASK | CPUINFO_ARM_MIDR_PART_MASK;
|
||||
return (midr & uarch_mask) == (CPUINFO_ARM_MIDR_KRYO385_SILVER & uarch_mask);
|
||||
}
|
||||
|
||||
inline static bool midr_is_kryo280_gold(uint32_t midr) {
|
||||
const uint32_t uarch_mask = CPUINFO_ARM_MIDR_IMPLEMENTER_MASK | CPUINFO_ARM_MIDR_PART_MASK;
|
||||
return (midr & uarch_mask) == (CPUINFO_ARM_MIDR_KRYO280_GOLD & uarch_mask);
|
||||
}
|
||||
|
||||
inline static bool midr_is_kryo_silver(uint32_t midr) {
|
||||
const uint32_t uarch_mask =
|
||||
CPUINFO_ARM_MIDR_IMPLEMENTER_MASK | CPUINFO_ARM_MIDR_ARCHITECTURE_MASK | CPUINFO_ARM_MIDR_PART_MASK;
|
||||
switch (midr & uarch_mask) {
|
||||
case CPUINFO_ARM_MIDR_KRYO_SILVER_820:
|
||||
case CPUINFO_ARM_MIDR_KRYO_SILVER_821:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
inline static bool midr_is_kryo_gold(uint32_t midr) {
|
||||
const uint32_t uarch_mask = CPUINFO_ARM_MIDR_IMPLEMENTER_MASK | CPUINFO_ARM_MIDR_PART_MASK;
|
||||
return (midr & uarch_mask) == (CPUINFO_ARM_MIDR_KRYO_GOLD & uarch_mask);
|
||||
}
|
||||
|
||||
inline static uint32_t midr_score_core(uint32_t midr) {
|
||||
const uint32_t core_mask = CPUINFO_ARM_MIDR_IMPLEMENTER_MASK | CPUINFO_ARM_MIDR_PART_MASK;
|
||||
switch (midr & core_mask) {
|
||||
case UINT32_C(0x53000030): /* Exynos M4 */
|
||||
case UINT32_C(0x53000040): /* Exynos M5 */
|
||||
case UINT32_C(0x4100D440): /* Cortex-X1 */
|
||||
/* These cores are in big role w.r.t Cortex-A75/-A76/-A77/-A78 */
|
||||
return 6;
|
||||
case UINT32_C(0x4E000030): /* Denver 2 */
|
||||
case UINT32_C(0x53000010): /* Exynos M1 and Exynos M2 */
|
||||
case UINT32_C(0x53000020): /* Exynos M3 */
|
||||
case UINT32_C(0x51008040): /* Kryo 485 Gold / Gold Prime */
|
||||
case UINT32_C(0x51008020): /* Kryo 385 Gold */
|
||||
case UINT32_C(0x51008000): /* Kryo 260 / 280 Gold */
|
||||
case UINT32_C(0x51002050): /* Kryo Gold */
|
||||
case UINT32_C(0x4800D400): /* Cortex-A76 (HiSilicon) */
|
||||
case UINT32_C(0x4100D410): /* Cortex-A78 */
|
||||
case UINT32_C(0x4100D0D0): /* Cortex-A77 */
|
||||
case UINT32_C(0x4100D0E0): /* Cortex-A76AE */
|
||||
case UINT32_C(0x4100D0B0): /* Cortex-A76 */
|
||||
case UINT32_C(0x4100D0A0): /* Cortex-A75 */
|
||||
case UINT32_C(0x4100D090): /* Cortex-A73 */
|
||||
case UINT32_C(0x4100D080): /* Cortex-A72 */
|
||||
#if CPUINFO_ARCH_ARM
|
||||
case UINT32_C(0x4100C0F0): /* Cortex-A15 */
|
||||
case UINT32_C(0x4100C0E0): /* Cortex-A17 */
|
||||
case UINT32_C(0x4100C0D0): /* Rockchip RK3288 cores */
|
||||
case UINT32_C(0x4100C0C0): /* Cortex-A12 */
|
||||
#endif /* CPUINFO_ARCH_ARM */
|
||||
/* These cores are always in big role */
|
||||
return 5;
|
||||
case UINT32_C(0x4100D070): /* Cortex-A57 */
|
||||
/* Cortex-A57 can be in LITTLE role w.r.t. Denver 2, or in big role w.r.t. Cortex-A53 */
|
||||
return 4;
|
||||
#if CPUINFO_ARCH_ARM64
|
||||
case UINT32_C(0x4100D060): /* Cortex-A65 */
|
||||
#endif /* CPUINFO_ARCH_ARM64 */
|
||||
case UINT32_C(0x4100D050): /* Cortex-A55 */
|
||||
case UINT32_C(0x4100D030): /* Cortex-A53 */
|
||||
/* Cortex-A53 is usually in LITTLE role, but can be in big role w.r.t. Cortex-A35 */
|
||||
return 2;
|
||||
case UINT32_C(0x4100D040): /* Cortex-A35 */
|
||||
#if CPUINFO_ARCH_ARM
|
||||
case UINT32_C(0x4100C070): /* Cortex-A7 */
|
||||
#endif /* CPUINFO_ARCH_ARM */
|
||||
case UINT32_C(0x51008050): /* Kryo 485 Silver */
|
||||
case UINT32_C(0x51008030): /* Kryo 385 Silver */
|
||||
case UINT32_C(0x51008010): /* Kryo 260 / 280 Silver */
|
||||
case UINT32_C(0x51002110): /* Kryo Silver (Snapdragon 820) */
|
||||
case UINT32_C(0x51002010): /* Kryo Silver (Snapdragon 821) */
|
||||
/* These cores are always in LITTLE core */
|
||||
return 1;
|
||||
default:
|
||||
/*
|
||||
* Unknown cores, or cores which do not have big/LITTLE roles.
|
||||
* To be future-proof w.r.t. cores not yet recognized in cpuinfo, assume position between
|
||||
* Cortex-A57/A72/A73/A75 and Cortex-A53/A55. Then at least future cores paired with
|
||||
* one of these known cores will be properly scored.
|
||||
*/
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
|
||||
inline static uint32_t midr_little_core_for_big(uint32_t midr) {
|
||||
const uint32_t core_mask =
|
||||
CPUINFO_ARM_MIDR_IMPLEMENTER_MASK | CPUINFO_ARM_MIDR_ARCHITECTURE_MASK | CPUINFO_ARM_MIDR_PART_MASK;
|
||||
switch (midr & core_mask) {
|
||||
case CPUINFO_ARM_MIDR_CORTEX_A75:
|
||||
return CPUINFO_ARM_MIDR_CORTEX_A55;
|
||||
case CPUINFO_ARM_MIDR_CORTEX_A73:
|
||||
case CPUINFO_ARM_MIDR_CORTEX_A72:
|
||||
case CPUINFO_ARM_MIDR_CORTEX_A57:
|
||||
case CPUINFO_ARM_MIDR_EXYNOS_M1_M2:
|
||||
return CPUINFO_ARM_MIDR_CORTEX_A53;
|
||||
case CPUINFO_ARM_MIDR_CORTEX_A17:
|
||||
case CPUINFO_ARM_MIDR_CORTEX_A15:
|
||||
return CPUINFO_ARM_MIDR_CORTEX_A7;
|
||||
case CPUINFO_ARM_MIDR_KRYO280_GOLD:
|
||||
return CPUINFO_ARM_MIDR_KRYO280_SILVER;
|
||||
case CPUINFO_ARM_MIDR_KRYO_GOLD:
|
||||
return CPUINFO_ARM_MIDR_KRYO_SILVER_820;
|
||||
case CPUINFO_ARM_MIDR_DENVER2:
|
||||
return CPUINFO_ARM_MIDR_CORTEX_A57;
|
||||
default:
|
||||
return midr;
|
||||
}
|
||||
}
|
||||
133
3rdparty/cpuinfo/src/arm/tlb.c
vendored
Normal file
133
3rdparty/cpuinfo/src/arm/tlb.c
vendored
Normal file
@@ -0,0 +1,133 @@
|
||||
|
||||
|
||||
switch (uarch) {
|
||||
case cpuinfo_uarch_cortex_a5:
|
||||
/*
|
||||
* Cortex-A5 Technical Reference Manual:
|
||||
* 6.3.1. Micro TLB
|
||||
* The first level of caching for the page table information is a micro TLB of
|
||||
* 10 entries that is implemented on each of the instruction and data sides.
|
||||
* 6.3.2. Main TLB
|
||||
* Misses from the instruction and data micro TLBs are handled by a unified main TLB.
|
||||
* The main TLB is 128-entry two-way set-associative.
|
||||
*/
|
||||
break;
|
||||
case cpuinfo_uarch_cortex_a7:
|
||||
/*
|
||||
* Cortex-A7 MPCore Technical Reference Manual:
|
||||
* 5.3.1. Micro TLB
|
||||
* The first level of caching for the page table information is a micro TLB of
|
||||
* 10 entries that is implemented on each of the instruction and data sides.
|
||||
* 5.3.2. Main TLB
|
||||
* Misses from the micro TLBs are handled by a unified main TLB. This is a 256-entry 2-way
|
||||
* set-associative structure. The main TLB supports all the VMSAv7 page sizes of
|
||||
* 4KB, 64KB, 1MB and 16MB in addition to the LPAE page sizes of 2MB and 1G.
|
||||
*/
|
||||
break;
|
||||
case cpuinfo_uarch_cortex_a8:
|
||||
/*
|
||||
* Cortex-A8 Technical Reference Manual:
|
||||
* 6.1. About the MMU
|
||||
* The MMU features include the following:
|
||||
* - separate, fully-associative, 32-entry data and instruction TLBs
|
||||
* - TLB entries that support 4KB, 64KB, 1MB, and 16MB pages
|
||||
*/
|
||||
break;
|
||||
case cpuinfo_uarch_cortex_a9:
|
||||
/*
|
||||
* ARM Cortex‑A9 Technical Reference Manual:
|
||||
* 6.2.1 Micro TLB
|
||||
* The first level of caching for the page table information is a micro TLB of 32 entries on the data side,
|
||||
* and configurable 32 or 64 entries on the instruction side.
|
||||
* 6.2.2 Main TLB
|
||||
* The main TLB is implemented as a combination of:
|
||||
* - A fully-associative, lockable array of four elements.
|
||||
* - A 2-way associative structure of 2x32, 2x64, 2x128 or 2x256 entries.
|
||||
*/
|
||||
break;
|
||||
case cpuinfo_uarch_cortex_a15:
|
||||
/*
|
||||
* ARM Cortex-A15 MPCore Processor Technical Reference Manual:
|
||||
* 5.2.1. L1 instruction TLB
|
||||
* The L1 instruction TLB is a 32-entry fully-associative structure. This TLB caches entries at the 4KB
|
||||
* granularity of Virtual Address (VA) to Physical Address (PA) mapping only. If the page tables map the
|
||||
* memory region to a larger granularity than 4K, it only allocates one mapping for the particular 4K region
|
||||
* to which the current access corresponds.
|
||||
* 5.2.2. L1 data TLB
|
||||
* There are two separate 32-entry fully-associative TLBs that are used for data loads and stores,
|
||||
* respectively. Similar to the L1 instruction TLB, both of these cache entries at the 4KB granularity of
|
||||
* VA to PA mappings only. At implementation time, the Cortex-A15 MPCore processor can be configured with
|
||||
* the -l1tlb_1m option, to have the L1 data TLB cache entries at both the 4KB and 1MB granularity.
|
||||
* With this configuration, any translation that results in a 1MB or larger page is cached in the L1 data
|
||||
* TLB as a 1MB entry. Any translation that results in a page smaller than 1MB is cached in the L1 data TLB
|
||||
* as a 4KB entry. By default, all translations are cached in the L1 data TLB as a 4KB entry.
|
||||
* 5.2.3. L2 TLB
|
||||
* Misses from the L1 instruction and data TLBs are handled by a unified L2 TLB. This is a 512-entry 4-way
|
||||
* set-associative structure. The L2 TLB supports all the VMSAv7 page sizes of 4K, 64K, 1MB and 16MB in
|
||||
* addition to the LPAE page sizes of 2MB and 1GB.
|
||||
*/
|
||||
break;
|
||||
case cpuinfo_uarch_cortex_a17:
|
||||
/*
|
||||
* ARM Cortex-A17 MPCore Processor Technical Reference Manual:
|
||||
* 5.2.1. Instruction micro TLB
|
||||
* The instruction micro TLB is implemented as a 32, 48 or 64 entry, fully-associative structure. This TLB
|
||||
* caches entries at the 4KB and 1MB granularity of Virtual Address (VA) to Physical Address (PA) mapping
|
||||
* only. If the translation tables map the memory region to a larger granularity than 4KB or 1MB, it only
|
||||
* allocates one mapping for the particular 4KB region to which the current access corresponds.
|
||||
* 5.2.2. Data micro TLB
|
||||
* The data micro TLB is a 32 entry fully-associative TLB that is used for data loads and stores. The cache
|
||||
* entries have a 4KB and 1MB granularity of VA to PA mappings only.
|
||||
* 5.2.3. Unified main TLB
|
||||
* Misses from the instruction and data micro TLBs are handled by a unified main TLB. This is a 1024 entry
|
||||
* 4-way set-associative structure. The main TLB supports all the VMSAv7 page sizes of 4K, 64K, 1MB and 16MB
|
||||
* in addition to the LPAE page sizes of 2MB and 1GB.
|
||||
*/
|
||||
break;
|
||||
case cpuinfo_uarch_cortex_a35:
|
||||
/*
|
||||
* ARM Cortex‑A35 Processor Technical Reference Manual:
|
||||
* A6.2 TLB Organization
|
||||
* Micro TLB
|
||||
* The first level of caching for the translation table information is a micro TLB of ten entries that
|
||||
* is implemented on each of the instruction and data sides.
|
||||
* Main TLB
|
||||
* A unified main TLB handles misses from the micro TLBs. It has a 512-entry, 2-way, set-associative
|
||||
* structure and supports all VMSAv8 block sizes, except 1GB. If it fetches a 1GB block, the TLB splits
|
||||
* it into 512MB blocks and stores the appropriate block for the lookup.
|
||||
*/
|
||||
break;
|
||||
case cpuinfo_uarch_cortex_a53:
|
||||
/*
|
||||
* ARM Cortex-A53 MPCore Processor Technical Reference Manual:
|
||||
* 5.2.1. Micro TLB
|
||||
* The first level of caching for the translation table information is a micro TLB of ten entries that is
|
||||
* implemented on each of the instruction and data sides.
|
||||
* 5.2.2. Main TLB
|
||||
* A unified main TLB handles misses from the micro TLBs. This is a 512-entry, 4-way, set-associative
|
||||
* structure. The main TLB supports all VMSAv8 block sizes, except 1GB. If a 1GB block is fetched, it is
|
||||
* split into 512MB blocks and the appropriate block for the lookup stored.
|
||||
*/
|
||||
break;
|
||||
case cpuinfo_uarch_cortex_a57:
|
||||
/*
|
||||
* ARM® Cortex-A57 MPCore Processor Technical Reference Manual:
|
||||
* 5.2.1 L1 instruction TLB
|
||||
* The L1 instruction TLB is a 48-entry fully-associative structure. This TLB caches entries of three
|
||||
* different page sizes, natively 4KB, 64KB, and 1MB, of VA to PA mappings. If the page tables map the memory
|
||||
* region to a larger granularity than 1MB, it only allocates one mapping for the particular 1MB region to
|
||||
* which the current access corresponds.
|
||||
* 5.2.2 L1 data TLB
|
||||
* The L1 data TLB is a 32-entry fully-associative TLB that is used for data loads and stores. This TLB
|
||||
* caches entries of three different page sizes, natively 4KB, 64KB, and 1MB, of VA to PA mappings.
|
||||
* 5.2.3 L2 TLB
|
||||
* Misses from the L1 instruction and data TLBs are handled by a unified L2 TLB. This is a 1024-entry 4-way
|
||||
* set-associative structure. The L2 TLB supports the page sizes of 4K, 64K, 1MB and 16MB. It also supports
|
||||
* page sizes of 2MB and 1GB for the long descriptor format translation in AArch32 state and in AArch64 state
|
||||
* when using the 4KB translation granule. In addition, the L2 TLB supports the 512MB page map size defined
|
||||
* for the AArch64 translations that use a 64KB translation granule.
|
||||
*/
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
362
3rdparty/cpuinfo/src/arm/uarch.c
vendored
Normal file
362
3rdparty/cpuinfo/src/arm/uarch.c
vendored
Normal file
@@ -0,0 +1,362 @@
|
||||
#include <stdint.h>
|
||||
|
||||
#include <arm/api.h>
|
||||
#include <arm/midr.h>
|
||||
#include <cpuinfo/log.h>
|
||||
|
||||
|
||||
void cpuinfo_arm_decode_vendor_uarch(
|
||||
uint32_t midr,
|
||||
#if CPUINFO_ARCH_ARM
|
||||
bool has_vfpv4,
|
||||
#endif /* CPUINFO_ARCH_ARM */
|
||||
enum cpuinfo_vendor vendor[restrict static 1],
|
||||
enum cpuinfo_uarch uarch[restrict static 1])
|
||||
{
|
||||
switch (midr_get_implementer(midr)) {
|
||||
case 'A':
|
||||
*vendor = cpuinfo_vendor_arm;
|
||||
switch (midr_get_part(midr)) {
|
||||
#if CPUINFO_ARCH_ARM
|
||||
case 0xC05:
|
||||
*uarch = cpuinfo_uarch_cortex_a5;
|
||||
break;
|
||||
case 0xC07:
|
||||
*uarch = cpuinfo_uarch_cortex_a7;
|
||||
break;
|
||||
case 0xC08:
|
||||
*uarch = cpuinfo_uarch_cortex_a8;
|
||||
break;
|
||||
case 0xC09:
|
||||
*uarch = cpuinfo_uarch_cortex_a9;
|
||||
break;
|
||||
case 0xC0C:
|
||||
*uarch = cpuinfo_uarch_cortex_a12;
|
||||
break;
|
||||
case 0xC0E:
|
||||
*uarch = cpuinfo_uarch_cortex_a17;
|
||||
break;
|
||||
case 0xC0D:
|
||||
/*
|
||||
* Rockchip RK3288 only.
|
||||
* Core information is ambiguous: some sources specify Cortex-A12, others - Cortex-A17.
|
||||
* Assume it is Cortex-A12.
|
||||
*/
|
||||
*uarch = cpuinfo_uarch_cortex_a12;
|
||||
break;
|
||||
case 0xC0F:
|
||||
*uarch = cpuinfo_uarch_cortex_a15;
|
||||
break;
|
||||
#endif /* CPUINFO_ARCH_ARM */
|
||||
case 0xD01:
|
||||
*uarch = cpuinfo_uarch_cortex_a32;
|
||||
break;
|
||||
case 0xD03:
|
||||
*uarch = cpuinfo_uarch_cortex_a53;
|
||||
break;
|
||||
case 0xD04:
|
||||
*uarch = cpuinfo_uarch_cortex_a35;
|
||||
break;
|
||||
case 0xD05:
|
||||
// Note: use Variant, not Revision, field
|
||||
*uarch = (midr & CPUINFO_ARM_MIDR_VARIANT_MASK) == 0 ?
|
||||
cpuinfo_uarch_cortex_a55r0 : cpuinfo_uarch_cortex_a55;
|
||||
break;
|
||||
case 0xD06:
|
||||
*uarch = cpuinfo_uarch_cortex_a65;
|
||||
break;
|
||||
case 0xD07:
|
||||
*uarch = cpuinfo_uarch_cortex_a57;
|
||||
break;
|
||||
case 0xD08:
|
||||
*uarch = cpuinfo_uarch_cortex_a72;
|
||||
break;
|
||||
case 0xD09:
|
||||
*uarch = cpuinfo_uarch_cortex_a73;
|
||||
break;
|
||||
case 0xD0A:
|
||||
*uarch = cpuinfo_uarch_cortex_a75;
|
||||
break;
|
||||
case 0xD0B:
|
||||
*uarch = cpuinfo_uarch_cortex_a76;
|
||||
break;
|
||||
#if CPUINFO_ARCH_ARM64 && !defined(__ANDROID__)
|
||||
case 0xD0C:
|
||||
*uarch = cpuinfo_uarch_neoverse_n1;
|
||||
break;
|
||||
#endif /* CPUINFO_ARCH_ARM64 && !defined(__ANDROID__) */
|
||||
case 0xD0D:
|
||||
*uarch = cpuinfo_uarch_cortex_a77;
|
||||
break;
|
||||
case 0xD0E: /* Cortex-A76AE */
|
||||
*uarch = cpuinfo_uarch_cortex_a76;
|
||||
break;
|
||||
case 0xD41: /* Cortex-A78 */
|
||||
*uarch = cpuinfo_uarch_cortex_a78;
|
||||
break;
|
||||
case 0xD44: /* Cortex-X1 */
|
||||
*uarch = cpuinfo_uarch_cortex_x1;
|
||||
break;
|
||||
#if CPUINFO_ARCH_ARM64 && !defined(__ANDROID__)
|
||||
case 0xD4A:
|
||||
*uarch = cpuinfo_uarch_neoverse_e1;
|
||||
break;
|
||||
#endif /* CPUINFO_ARCH_ARM64 && !defined(__ANDROID__) */
|
||||
default:
|
||||
switch (midr_get_part(midr) >> 8) {
|
||||
#if CPUINFO_ARCH_ARM
|
||||
case 7:
|
||||
*uarch = cpuinfo_uarch_arm7;
|
||||
break;
|
||||
case 9:
|
||||
*uarch = cpuinfo_uarch_arm9;
|
||||
break;
|
||||
case 11:
|
||||
*uarch = cpuinfo_uarch_arm11;
|
||||
break;
|
||||
#endif /* CPUINFO_ARCH_ARM */
|
||||
default:
|
||||
cpuinfo_log_warning("unknown ARM CPU part 0x%03"PRIx32" ignored", midr_get_part(midr));
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'B':
|
||||
*vendor = cpuinfo_vendor_broadcom;
|
||||
switch (midr_get_part(midr)) {
|
||||
case 0x00F:
|
||||
*uarch = cpuinfo_uarch_brahma_b15;
|
||||
break;
|
||||
case 0x100:
|
||||
*uarch = cpuinfo_uarch_brahma_b53;
|
||||
break;
|
||||
#if CPUINFO_ARCH_ARM64 && !defined(__ANDROID__)
|
||||
case 0x516:
|
||||
/* Broadcom Vulkan was sold to Cavium before it reached the market, so we identify it as Cavium ThunderX2 */
|
||||
*vendor = cpuinfo_vendor_cavium;
|
||||
*uarch = cpuinfo_uarch_thunderx2;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
cpuinfo_log_warning("unknown Broadcom CPU part 0x%03"PRIx32" ignored", midr_get_part(midr));
|
||||
}
|
||||
break;
|
||||
#if CPUINFO_ARCH_ARM64 && !defined(__ANDROID__)
|
||||
case 'C':
|
||||
*vendor = cpuinfo_vendor_cavium;
|
||||
switch (midr_get_part(midr)) {
|
||||
case 0x0A0: /* ThunderX */
|
||||
case 0x0A1: /* ThunderX 88XX */
|
||||
case 0x0A2: /* ThunderX 81XX */
|
||||
case 0x0A3: /* ThunderX 83XX */
|
||||
*uarch = cpuinfo_uarch_thunderx;
|
||||
break;
|
||||
case 0x0AF: /* ThunderX2 99XX */
|
||||
*uarch = cpuinfo_uarch_thunderx2;
|
||||
break;
|
||||
default:
|
||||
cpuinfo_log_warning("unknown Cavium CPU part 0x%03"PRIx32" ignored", midr_get_part(midr));
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
case 'H':
|
||||
*vendor = cpuinfo_vendor_huawei;
|
||||
switch (midr_get_part(midr)) {
|
||||
#if CPUINFO_ARCH_ARM64 && !defined(__ANDROID__)
|
||||
case 0xD01: /* Kunpeng 920 series */
|
||||
*uarch = cpuinfo_uarch_taishan_v110;
|
||||
break;
|
||||
#endif
|
||||
case 0xD40: /* Kirin 980 Big/Medium cores -> Cortex-A76 */
|
||||
*vendor = cpuinfo_vendor_arm;
|
||||
*uarch = cpuinfo_uarch_cortex_a76;
|
||||
break;
|
||||
default:
|
||||
cpuinfo_log_warning("unknown Huawei CPU part 0x%03"PRIx32" ignored", midr_get_part(midr));
|
||||
}
|
||||
break;
|
||||
#if CPUINFO_ARCH_ARM
|
||||
case 'i':
|
||||
*vendor = cpuinfo_vendor_intel;
|
||||
switch (midr_get_part(midr) >> 8) {
|
||||
case 2: /* PXA 210/25X/26X */
|
||||
case 4: /* PXA 27X */
|
||||
case 6: /* PXA 3XX */
|
||||
*uarch = cpuinfo_uarch_xscale;
|
||||
break;
|
||||
default:
|
||||
cpuinfo_log_warning("unknown Intel CPU part 0x%03"PRIx32" ignored", midr_get_part(midr));
|
||||
}
|
||||
break;
|
||||
#endif /* CPUINFO_ARCH_ARM */
|
||||
case 'N':
|
||||
*vendor = cpuinfo_vendor_nvidia;
|
||||
switch (midr_get_part(midr)) {
|
||||
case 0x000:
|
||||
*uarch = cpuinfo_uarch_denver;
|
||||
break;
|
||||
case 0x003:
|
||||
*uarch = cpuinfo_uarch_denver2;
|
||||
break;
|
||||
case 0x004:
|
||||
*uarch = cpuinfo_uarch_carmel;
|
||||
break;
|
||||
default:
|
||||
cpuinfo_log_warning("unknown Nvidia CPU part 0x%03"PRIx32" ignored", midr_get_part(midr));
|
||||
}
|
||||
break;
|
||||
#if !defined(__ANDROID__)
|
||||
case 'P':
|
||||
*vendor = cpuinfo_vendor_apm;
|
||||
switch (midr_get_part(midr)) {
|
||||
case 0x000:
|
||||
*uarch = cpuinfo_uarch_xgene;
|
||||
break;
|
||||
default:
|
||||
cpuinfo_log_warning("unknown Applied Micro CPU part 0x%03"PRIx32" ignored", midr_get_part(midr));
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
case 'Q':
|
||||
*vendor = cpuinfo_vendor_qualcomm;
|
||||
switch (midr_get_part(midr)) {
|
||||
#if CPUINFO_ARCH_ARM
|
||||
case 0x00F:
|
||||
/* Mostly Scorpions, but some Cortex A5 may report this value as well */
|
||||
if (has_vfpv4) {
|
||||
/* Unlike Scorpion, Cortex-A5 comes with VFPv4 */
|
||||
*vendor = cpuinfo_vendor_arm;
|
||||
*uarch = cpuinfo_uarch_cortex_a5;
|
||||
} else {
|
||||
*uarch = cpuinfo_uarch_scorpion;
|
||||
}
|
||||
break;
|
||||
case 0x02D: /* Dual-core Scorpions */
|
||||
*uarch = cpuinfo_uarch_scorpion;
|
||||
break;
|
||||
case 0x04D:
|
||||
/*
|
||||
* Dual-core Krait:
|
||||
* - r1p0 -> Krait 200
|
||||
* - r1p4 -> Krait 200
|
||||
* - r2p0 -> Krait 300
|
||||
*/
|
||||
case 0x06F:
|
||||
/*
|
||||
* Quad-core Krait:
|
||||
* - r0p1 -> Krait 200
|
||||
* - r0p2 -> Krait 200
|
||||
* - r1p0 -> Krait 300
|
||||
* - r2p0 -> Krait 400 (Snapdragon 800 MSMxxxx)
|
||||
* - r2p1 -> Krait 400 (Snapdragon 801 MSMxxxxPRO)
|
||||
* - r3p1 -> Krait 450
|
||||
*/
|
||||
*uarch = cpuinfo_uarch_krait;
|
||||
break;
|
||||
#endif /* CPUINFO_ARCH_ARM */
|
||||
case 0x201: /* Qualcomm Snapdragon 821: Low-power Kryo "Silver" */
|
||||
case 0x205: /* Qualcomm Snapdragon 820 & 821: High-performance Kryo "Gold" */
|
||||
case 0x211: /* Qualcomm Snapdragon 820: Low-power Kryo "Silver" */
|
||||
*uarch = cpuinfo_uarch_kryo;
|
||||
break;
|
||||
case 0x800: /* High-performance Kryo 260 (r10p2) / Kryo 280 (r10p1) "Gold" -> Cortex-A73 */
|
||||
*vendor = cpuinfo_vendor_arm;
|
||||
*uarch = cpuinfo_uarch_cortex_a73;
|
||||
break;
|
||||
case 0x801: /* Low-power Kryo 260 / 280 "Silver" -> Cortex-A53 */
|
||||
*vendor = cpuinfo_vendor_arm;
|
||||
*uarch = cpuinfo_uarch_cortex_a53;
|
||||
break;
|
||||
case 0x802: /* High-performance Kryo 385 "Gold" -> Cortex-A75 */
|
||||
*vendor = cpuinfo_vendor_arm;
|
||||
*uarch = cpuinfo_uarch_cortex_a75;
|
||||
break;
|
||||
case 0x803: /* Low-power Kryo 385 "Silver" -> Cortex-A55r0 */
|
||||
*vendor = cpuinfo_vendor_arm;
|
||||
*uarch = cpuinfo_uarch_cortex_a55r0;
|
||||
break;
|
||||
case 0x804: /* High-performance Kryo 485 "Gold" / "Gold Prime" -> Cortex-A76 */
|
||||
*vendor = cpuinfo_vendor_arm;
|
||||
*uarch = cpuinfo_uarch_cortex_a76;
|
||||
break;
|
||||
case 0x805: /* Low-performance Kryo 485 "Silver" -> Cortex-A55 */
|
||||
*vendor = cpuinfo_vendor_arm;
|
||||
*uarch = cpuinfo_uarch_cortex_a55;
|
||||
break;
|
||||
#if CPUINFO_ARCH_ARM64 && !defined(__ANDROID__)
|
||||
case 0xC00:
|
||||
*uarch = cpuinfo_uarch_falkor;
|
||||
break;
|
||||
case 0xC01:
|
||||
*uarch = cpuinfo_uarch_saphira;
|
||||
break;
|
||||
#endif /* CPUINFO_ARCH_ARM64 && !defined(__ANDROID__) */
|
||||
default:
|
||||
cpuinfo_log_warning("unknown Qualcomm CPU part 0x%03"PRIx32" ignored", midr_get_part(midr));
|
||||
}
|
||||
break;
|
||||
case 'S':
|
||||
*vendor = cpuinfo_vendor_samsung;
|
||||
switch (midr & (CPUINFO_ARM_MIDR_VARIANT_MASK | CPUINFO_ARM_MIDR_PART_MASK)) {
|
||||
case 0x00100010:
|
||||
/*
|
||||
* Exynos 8890 MIDR = 0x531F0011, assume Exynos M1 has:
|
||||
* - CPU variant 0x1
|
||||
* - CPU part 0x001
|
||||
*/
|
||||
*uarch = cpuinfo_uarch_exynos_m1;
|
||||
break;
|
||||
case 0x00400010:
|
||||
/*
|
||||
* Exynos 8895 MIDR = 0x534F0010, assume Exynos M2 has:
|
||||
* - CPU variant 0x4
|
||||
* - CPU part 0x001
|
||||
*/
|
||||
*uarch = cpuinfo_uarch_exynos_m2;
|
||||
break;
|
||||
case 0x00100020:
|
||||
/*
|
||||
* Exynos 9810 MIDR = 0x531F0020, assume Exynos M3 has:
|
||||
* - CPU variant 0x1
|
||||
* - CPU part 0x002
|
||||
*/
|
||||
*uarch = cpuinfo_uarch_exynos_m3;
|
||||
break;
|
||||
case 0x00100030:
|
||||
/*
|
||||
* Exynos 9820 MIDR = 0x531F0030, assume Exynos M4 has:
|
||||
* - CPU variant 0x1
|
||||
* - CPU part 0x003
|
||||
*/
|
||||
*uarch = cpuinfo_uarch_exynos_m4;
|
||||
break;
|
||||
case 0x00100040:
|
||||
/*
|
||||
* Exynos 9820 MIDR = 0x531F0040, assume Exynos M5 has:
|
||||
* - CPU variant 0x1
|
||||
* - CPU part 0x004
|
||||
*/
|
||||
*uarch = cpuinfo_uarch_exynos_m5;
|
||||
break;
|
||||
default:
|
||||
cpuinfo_log_warning("unknown Samsung CPU variant 0x%01"PRIx32" part 0x%03"PRIx32" ignored",
|
||||
midr_get_variant(midr), midr_get_part(midr));
|
||||
}
|
||||
break;
|
||||
#if CPUINFO_ARCH_ARM
|
||||
case 'V':
|
||||
*vendor = cpuinfo_vendor_marvell;
|
||||
switch (midr_get_part(midr)) {
|
||||
case 0x581: /* PJ4 / PJ4B */
|
||||
case 0x584: /* PJ4B-MP / PJ4C */
|
||||
*uarch = cpuinfo_uarch_pj4;
|
||||
break;
|
||||
default:
|
||||
cpuinfo_log_warning("unknown Marvell CPU part 0x%03"PRIx32" ignored", midr_get_part(midr));
|
||||
}
|
||||
break;
|
||||
#endif /* CPUINFO_ARCH_ARM */
|
||||
default:
|
||||
cpuinfo_log_warning("unknown CPU implementer '%c' (0x%02"PRIx32") with CPU part 0x%03"PRIx32" ignored",
|
||||
(char) midr_get_implementer(midr), midr_get_implementer(midr), midr_get_part(midr));
|
||||
}
|
||||
}
|
||||
18
3rdparty/cpuinfo/src/cache.c
vendored
Normal file
18
3rdparty/cpuinfo/src/cache.c
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
#include <stddef.h>
|
||||
|
||||
#include <cpuinfo.h>
|
||||
#include <cpuinfo/internal-api.h>
|
||||
|
||||
|
||||
uint32_t cpuinfo_compute_max_cache_size(const struct cpuinfo_processor* processor) {
|
||||
if (processor->cache.l4 != NULL) {
|
||||
return processor->cache.l4->size;
|
||||
} else if (processor->cache.l3 != NULL) {
|
||||
return processor->cache.l3->size;
|
||||
} else if (processor->cache.l2 != NULL) {
|
||||
return processor->cache.l2->size;
|
||||
} else if (processor->cache.l1d != NULL) {
|
||||
return processor->cache.l1d->size;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
40
3rdparty/cpuinfo/src/cpuinfo/common.h
vendored
Normal file
40
3rdparty/cpuinfo/src/cpuinfo/common.h
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
#define CPUINFO_COUNT_OF(array) (sizeof(array) / sizeof(0[array]))
|
||||
|
||||
#if defined(__GNUC__)
|
||||
#define CPUINFO_LIKELY(condition) (__builtin_expect(!!(condition), 1))
|
||||
#define CPUINFO_UNLIKELY(condition) (__builtin_expect(!!(condition), 0))
|
||||
#else
|
||||
#define CPUINFO_LIKELY(condition) (!!(condition))
|
||||
#define CPUINFO_UNLIKELY(condition) (!!(condition))
|
||||
#endif
|
||||
|
||||
#ifndef CPUINFO_INTERNAL
|
||||
#if defined(__ELF__)
|
||||
#define CPUINFO_INTERNAL __attribute__((__visibility__("internal")))
|
||||
#elif defined(__MACH__)
|
||||
#define CPUINFO_INTERNAL __attribute__((__visibility__("hidden")))
|
||||
#else
|
||||
#define CPUINFO_INTERNAL
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef CPUINFO_PRIVATE
|
||||
#if defined(__ELF__)
|
||||
#define CPUINFO_PRIVATE __attribute__((__visibility__("hidden")))
|
||||
#elif defined(__MACH__)
|
||||
#define CPUINFO_PRIVATE __attribute__((__visibility__("hidden")))
|
||||
#else
|
||||
#define CPUINFO_PRIVATE
|
||||
#endif
|
||||
#endif
|
||||
62
3rdparty/cpuinfo/src/cpuinfo/internal-api.h
vendored
Normal file
62
3rdparty/cpuinfo/src/cpuinfo/internal-api.h
vendored
Normal file
@@ -0,0 +1,62 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#if defined(_WIN32) || defined(__CYGWIN__)
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#include <cpuinfo.h>
|
||||
#include <cpuinfo/common.h>
|
||||
|
||||
|
||||
enum cpuinfo_cache_level {
|
||||
cpuinfo_cache_level_1i = 0,
|
||||
cpuinfo_cache_level_1d = 1,
|
||||
cpuinfo_cache_level_2 = 2,
|
||||
cpuinfo_cache_level_3 = 3,
|
||||
cpuinfo_cache_level_4 = 4,
|
||||
cpuinfo_cache_level_max = 5,
|
||||
};
|
||||
|
||||
extern CPUINFO_INTERNAL bool cpuinfo_is_initialized;
|
||||
|
||||
extern CPUINFO_INTERNAL struct cpuinfo_processor* cpuinfo_processors;
|
||||
extern CPUINFO_INTERNAL struct cpuinfo_core* cpuinfo_cores;
|
||||
extern CPUINFO_INTERNAL struct cpuinfo_cluster* cpuinfo_clusters;
|
||||
extern CPUINFO_INTERNAL struct cpuinfo_package* cpuinfo_packages;
|
||||
extern CPUINFO_INTERNAL struct cpuinfo_cache* cpuinfo_cache[cpuinfo_cache_level_max];
|
||||
|
||||
extern CPUINFO_INTERNAL uint32_t cpuinfo_processors_count;
|
||||
extern CPUINFO_INTERNAL uint32_t cpuinfo_cores_count;
|
||||
extern CPUINFO_INTERNAL uint32_t cpuinfo_clusters_count;
|
||||
extern CPUINFO_INTERNAL uint32_t cpuinfo_packages_count;
|
||||
extern CPUINFO_INTERNAL uint32_t cpuinfo_cache_count[cpuinfo_cache_level_max];
|
||||
extern CPUINFO_INTERNAL uint32_t cpuinfo_max_cache_size;
|
||||
|
||||
#if CPUINFO_ARCH_ARM || CPUINFO_ARCH_ARM64
|
||||
extern CPUINFO_INTERNAL struct cpuinfo_uarch_info* cpuinfo_uarchs;
|
||||
extern CPUINFO_INTERNAL uint32_t cpuinfo_uarchs_count;
|
||||
#else
|
||||
extern CPUINFO_INTERNAL struct cpuinfo_uarch_info cpuinfo_global_uarch;
|
||||
#endif
|
||||
|
||||
#ifdef __linux__
|
||||
extern CPUINFO_INTERNAL uint32_t cpuinfo_linux_cpu_max;
|
||||
extern CPUINFO_INTERNAL const struct cpuinfo_processor** cpuinfo_linux_cpu_to_processor_map;
|
||||
extern CPUINFO_INTERNAL const struct cpuinfo_core** cpuinfo_linux_cpu_to_core_map;
|
||||
#endif
|
||||
|
||||
CPUINFO_PRIVATE void cpuinfo_x86_mach_init(void);
|
||||
CPUINFO_PRIVATE void cpuinfo_x86_linux_init(void);
|
||||
#if defined(_WIN32) || defined(__CYGWIN__)
|
||||
CPUINFO_PRIVATE BOOL CALLBACK cpuinfo_x86_windows_init(PINIT_ONCE init_once, PVOID parameter, PVOID* context);
|
||||
#endif
|
||||
CPUINFO_PRIVATE void cpuinfo_arm_mach_init(void);
|
||||
CPUINFO_PRIVATE void cpuinfo_arm_linux_init(void);
|
||||
CPUINFO_PRIVATE void cpuinfo_emscripten_init(void);
|
||||
|
||||
CPUINFO_PRIVATE uint32_t cpuinfo_compute_max_cache_size(const struct cpuinfo_processor* processor);
|
||||
|
||||
typedef void (*cpuinfo_processor_callback)(uint32_t);
|
||||
17
3rdparty/cpuinfo/src/cpuinfo/log.h
vendored
Normal file
17
3rdparty/cpuinfo/src/cpuinfo/log.h
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
#include <clog.h>
|
||||
|
||||
#define CPUINFO_LOG_DEBUG_PARSERS 0
|
||||
|
||||
#ifndef CPUINFO_LOG_LEVEL
|
||||
#define CPUINFO_LOG_LEVEL CLOG_ERROR
|
||||
#endif
|
||||
|
||||
CLOG_DEFINE_LOG_DEBUG(cpuinfo_log_debug, "cpuinfo", CPUINFO_LOG_LEVEL);
|
||||
CLOG_DEFINE_LOG_INFO(cpuinfo_log_info, "cpuinfo", CPUINFO_LOG_LEVEL);
|
||||
CLOG_DEFINE_LOG_WARNING(cpuinfo_log_warning, "cpuinfo", CPUINFO_LOG_LEVEL);
|
||||
CLOG_DEFINE_LOG_ERROR(cpuinfo_log_error, "cpuinfo", CPUINFO_LOG_LEVEL);
|
||||
CLOG_DEFINE_LOG_FATAL(cpuinfo_log_fatal, "cpuinfo", CPUINFO_LOG_LEVEL);
|
||||
19
3rdparty/cpuinfo/src/cpuinfo/utils.h
vendored
Normal file
19
3rdparty/cpuinfo/src/cpuinfo/utils.h
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
inline static uint32_t bit_length(uint32_t n) {
|
||||
const uint32_t n_minus_1 = n - 1;
|
||||
if (n_minus_1 == 0) {
|
||||
return 0;
|
||||
} else {
|
||||
#ifdef _MSC_VER
|
||||
unsigned long bsr;
|
||||
_BitScanReverse(&bsr, n_minus_1);
|
||||
return bsr + 1;
|
||||
#else
|
||||
return 32 - __builtin_clz(n_minus_1);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
277
3rdparty/cpuinfo/src/emscripten/init.c
vendored
Normal file
277
3rdparty/cpuinfo/src/emscripten/init.c
vendored
Normal file
@@ -0,0 +1,277 @@
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
#include <emscripten/threading.h>
|
||||
|
||||
#include <cpuinfo.h>
|
||||
#include <cpuinfo/internal-api.h>
|
||||
#include <cpuinfo/log.h>
|
||||
|
||||
|
||||
static const volatile float infinity = INFINITY;
|
||||
|
||||
static struct cpuinfo_package static_package = { };
|
||||
|
||||
static struct cpuinfo_cache static_x86_l3 = {
|
||||
.size = 2 * 1024 * 1024,
|
||||
.associativity = 16,
|
||||
.sets = 2048,
|
||||
.partitions = 1,
|
||||
.line_size = 64,
|
||||
};
|
||||
|
||||
void cpuinfo_emscripten_init(void) {
|
||||
struct cpuinfo_processor* processors = NULL;
|
||||
struct cpuinfo_core* cores = NULL;
|
||||
struct cpuinfo_cluster* clusters = NULL;
|
||||
struct cpuinfo_cache* l1i = NULL;
|
||||
struct cpuinfo_cache* l1d = NULL;
|
||||
struct cpuinfo_cache* l2 = NULL;
|
||||
|
||||
const bool is_x86 = signbit(infinity - infinity);
|
||||
|
||||
int logical_cores_count = emscripten_num_logical_cores();
|
||||
if (logical_cores_count <= 0) {
|
||||
logical_cores_count = 1;
|
||||
}
|
||||
uint32_t processor_count = (uint32_t) logical_cores_count;
|
||||
uint32_t core_count = processor_count;
|
||||
uint32_t cluster_count = 1;
|
||||
uint32_t big_cluster_core_count = core_count;
|
||||
uint32_t processors_per_core = 1;
|
||||
if (is_x86) {
|
||||
if (processor_count % 2 == 0) {
|
||||
processors_per_core = 2;
|
||||
core_count = processor_count / 2;
|
||||
big_cluster_core_count = core_count;
|
||||
}
|
||||
} else {
|
||||
/* Assume ARM/ARM64 */
|
||||
if (processor_count > 4) {
|
||||
/* Assume big.LITTLE architecture */
|
||||
cluster_count = 2;
|
||||
big_cluster_core_count = processor_count >= 8 ? 4 : 2;
|
||||
}
|
||||
}
|
||||
uint32_t l2_count = is_x86 ? core_count : cluster_count;
|
||||
|
||||
processors = calloc(processor_count, sizeof(struct cpuinfo_processor));
|
||||
if (processors == NULL) {
|
||||
cpuinfo_log_error("failed to allocate %zu bytes for descriptions of %"PRIu32" logical processors",
|
||||
processor_count * sizeof(struct cpuinfo_processor), processor_count);
|
||||
goto cleanup;
|
||||
}
|
||||
cores = calloc(processor_count, sizeof(struct cpuinfo_core));
|
||||
if (cores == NULL) {
|
||||
cpuinfo_log_error("failed to allocate %zu bytes for descriptions of %"PRIu32" cores",
|
||||
processor_count * sizeof(struct cpuinfo_core), processor_count);
|
||||
goto cleanup;
|
||||
}
|
||||
clusters = calloc(cluster_count, sizeof(struct cpuinfo_cluster));
|
||||
if (clusters == NULL) {
|
||||
cpuinfo_log_error("failed to allocate %zu bytes for descriptions of %"PRIu32" clusters",
|
||||
cluster_count * sizeof(struct cpuinfo_cluster), cluster_count);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
l1i = calloc(core_count, sizeof(struct cpuinfo_cache));
|
||||
if (l1i == NULL) {
|
||||
cpuinfo_log_error("failed to allocate %zu bytes for descriptions of %"PRIu32" L1I caches",
|
||||
core_count * sizeof(struct cpuinfo_cache), core_count);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
l1d = calloc(core_count, sizeof(struct cpuinfo_cache));
|
||||
if (l1d == NULL) {
|
||||
cpuinfo_log_error("failed to allocate %zu bytes for descriptions of %"PRIu32" L1D caches",
|
||||
core_count * sizeof(struct cpuinfo_cache), core_count);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
l2 = calloc(l2_count, sizeof(struct cpuinfo_cache));
|
||||
if (l2 == NULL) {
|
||||
cpuinfo_log_error("failed to allocate %zu bytes for descriptions of %"PRIu32" L2 caches",
|
||||
l2_count * sizeof(struct cpuinfo_cache), l2_count);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
static_package.processor_count = processor_count;
|
||||
static_package.core_count = core_count;
|
||||
static_package.cluster_count = cluster_count;
|
||||
if (is_x86) {
|
||||
strncpy(static_package.name, "x86 vCPU", CPUINFO_PACKAGE_NAME_MAX);
|
||||
} else {
|
||||
strncpy(static_package.name, "ARM vCPU", CPUINFO_PACKAGE_NAME_MAX);
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < core_count; i++) {
|
||||
for (uint32_t j = 0; j < processors_per_core; j++) {
|
||||
processors[i * processors_per_core + j] = (struct cpuinfo_processor) {
|
||||
.smt_id = j,
|
||||
.core = cores + i,
|
||||
.cluster = clusters + (uint32_t) (i >= big_cluster_core_count),
|
||||
.package = &static_package,
|
||||
.cache.l1i = l1i + i,
|
||||
.cache.l1d = l1d + i,
|
||||
.cache.l2 = is_x86 ? l2 + i : l2 + (uint32_t) (i >= big_cluster_core_count),
|
||||
.cache.l3 = is_x86 ? &static_x86_l3 : NULL,
|
||||
};
|
||||
}
|
||||
|
||||
cores[i] = (struct cpuinfo_core) {
|
||||
.processor_start = i * processors_per_core,
|
||||
.processor_count = processors_per_core,
|
||||
.core_id = i,
|
||||
.cluster = clusters + (uint32_t) (i >= big_cluster_core_count),
|
||||
.package = &static_package,
|
||||
.vendor = cpuinfo_vendor_unknown,
|
||||
.uarch = cpuinfo_uarch_unknown,
|
||||
.frequency = 0,
|
||||
};
|
||||
|
||||
l1i[i] = (struct cpuinfo_cache) {
|
||||
.size = 32 * 1024,
|
||||
.associativity = 4,
|
||||
.sets = 128,
|
||||
.partitions = 1,
|
||||
.line_size = 64,
|
||||
.processor_start = i * processors_per_core,
|
||||
.processor_count = processors_per_core,
|
||||
};
|
||||
|
||||
l1d[i] = (struct cpuinfo_cache) {
|
||||
.size = 32 * 1024,
|
||||
.associativity = 4,
|
||||
.sets = 128,
|
||||
.partitions = 1,
|
||||
.line_size = 64,
|
||||
.processor_start = i * processors_per_core,
|
||||
.processor_count = processors_per_core,
|
||||
};
|
||||
|
||||
if (is_x86) {
|
||||
l2[i] = (struct cpuinfo_cache) {
|
||||
.size = 256 * 1024,
|
||||
.associativity = 8,
|
||||
.sets = 512,
|
||||
.partitions = 1,
|
||||
.line_size = 64,
|
||||
.processor_start = i * processors_per_core,
|
||||
.processor_count = processors_per_core,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
if (is_x86) {
|
||||
clusters[0] = (struct cpuinfo_cluster) {
|
||||
.processor_start = 0,
|
||||
.processor_count = processor_count,
|
||||
.core_start = 0,
|
||||
.core_count = core_count,
|
||||
.cluster_id = 0,
|
||||
.package = &static_package,
|
||||
.vendor = cpuinfo_vendor_unknown,
|
||||
.uarch = cpuinfo_uarch_unknown,
|
||||
.frequency = 0,
|
||||
};
|
||||
|
||||
static_x86_l3.processor_count = processor_count;
|
||||
} else {
|
||||
clusters[0] = (struct cpuinfo_cluster) {
|
||||
.processor_start = 0,
|
||||
.processor_count = big_cluster_core_count,
|
||||
.core_start = 0,
|
||||
.core_count = big_cluster_core_count,
|
||||
.cluster_id = 0,
|
||||
.package = &static_package,
|
||||
.vendor = cpuinfo_vendor_unknown,
|
||||
.uarch = cpuinfo_uarch_unknown,
|
||||
.frequency = 0,
|
||||
};
|
||||
|
||||
l2[0] = (struct cpuinfo_cache) {
|
||||
.size = 1024 * 1024,
|
||||
.associativity = 8,
|
||||
.sets = 2048,
|
||||
.partitions = 1,
|
||||
.line_size = 64,
|
||||
.processor_start = 0,
|
||||
.processor_count = big_cluster_core_count,
|
||||
};
|
||||
|
||||
if (cluster_count > 1) {
|
||||
l2[1] = (struct cpuinfo_cache) {
|
||||
.size = 256 * 1024,
|
||||
.associativity = 8,
|
||||
.sets = 512,
|
||||
.partitions = 1,
|
||||
.line_size = 64,
|
||||
.processor_start = big_cluster_core_count,
|
||||
.processor_count = processor_count - big_cluster_core_count,
|
||||
};
|
||||
|
||||
clusters[1] = (struct cpuinfo_cluster) {
|
||||
.processor_start = big_cluster_core_count,
|
||||
.processor_count = processor_count - big_cluster_core_count,
|
||||
.core_start = big_cluster_core_count,
|
||||
.core_count = processor_count - big_cluster_core_count,
|
||||
.cluster_id = 1,
|
||||
.package = &static_package,
|
||||
.vendor = cpuinfo_vendor_unknown,
|
||||
.uarch = cpuinfo_uarch_unknown,
|
||||
.frequency = 0,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/* Commit changes */
|
||||
cpuinfo_cache[cpuinfo_cache_level_1i] = l1i;
|
||||
cpuinfo_cache[cpuinfo_cache_level_1d] = l1d;
|
||||
cpuinfo_cache[cpuinfo_cache_level_2] = l2;
|
||||
if (is_x86) {
|
||||
cpuinfo_cache[cpuinfo_cache_level_3] = &static_x86_l3;
|
||||
}
|
||||
|
||||
cpuinfo_processors = processors;
|
||||
cpuinfo_cores = cores;
|
||||
cpuinfo_clusters = clusters;
|
||||
cpuinfo_packages = &static_package;
|
||||
|
||||
cpuinfo_cache_count[cpuinfo_cache_level_1i] = processor_count;
|
||||
cpuinfo_cache_count[cpuinfo_cache_level_1d] = processor_count;
|
||||
cpuinfo_cache_count[cpuinfo_cache_level_2] = l2_count;
|
||||
if (is_x86) {
|
||||
cpuinfo_cache_count[cpuinfo_cache_level_3] = 1;
|
||||
}
|
||||
|
||||
cpuinfo_global_uarch = (struct cpuinfo_uarch_info) {
|
||||
.uarch = cpuinfo_uarch_unknown,
|
||||
.processor_count = processor_count,
|
||||
.core_count = core_count,
|
||||
};
|
||||
|
||||
cpuinfo_processors_count = processor_count;
|
||||
cpuinfo_cores_count = processor_count;
|
||||
cpuinfo_clusters_count = cluster_count;
|
||||
cpuinfo_packages_count = 1;
|
||||
|
||||
cpuinfo_max_cache_size = is_x86 ? 128 * 1024 * 1024 : 8 * 1024 * 1024;
|
||||
|
||||
cpuinfo_is_initialized = true;
|
||||
|
||||
processors = NULL;
|
||||
cores = NULL;
|
||||
clusters = NULL;
|
||||
l1i = l1d = l2 = NULL;
|
||||
|
||||
cleanup:
|
||||
free(processors);
|
||||
free(cores);
|
||||
free(clusters);
|
||||
free(l1i);
|
||||
free(l1d);
|
||||
free(l2);
|
||||
}
|
||||
59
3rdparty/cpuinfo/src/init.c
vendored
Normal file
59
3rdparty/cpuinfo/src/init.c
vendored
Normal file
@@ -0,0 +1,59 @@
|
||||
#if defined(_WIN32) || defined(__CYGWIN__)
|
||||
#include <windows.h>
|
||||
#elif !defined(__EMSCRIPTEN__) || defined(__EMSCRIPTEN_PTHREADS__)
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
|
||||
#include <cpuinfo.h>
|
||||
#include <cpuinfo/internal-api.h>
|
||||
#include <cpuinfo/log.h>
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include "TargetConditionals.h"
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(_WIN32) || defined(__CYGWIN__)
|
||||
static INIT_ONCE init_guard = INIT_ONCE_STATIC_INIT;
|
||||
#elif !defined(__EMSCRIPTEN__) || defined(__EMSCRIPTEN_PTHREADS__)
|
||||
static pthread_once_t init_guard = PTHREAD_ONCE_INIT;
|
||||
#else
|
||||
static bool init_guard = false;
|
||||
#endif
|
||||
|
||||
bool CPUINFO_ABI cpuinfo_initialize(void) {
|
||||
#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
|
||||
#if defined(__MACH__) && defined(__APPLE__)
|
||||
pthread_once(&init_guard, &cpuinfo_x86_mach_init);
|
||||
#elif defined(__linux__)
|
||||
pthread_once(&init_guard, &cpuinfo_x86_linux_init);
|
||||
#elif defined(_WIN32) || defined(__CYGWIN__)
|
||||
InitOnceExecuteOnce(&init_guard, &cpuinfo_x86_windows_init, NULL, NULL);
|
||||
#else
|
||||
cpuinfo_log_error("operating system is not supported in cpuinfo");
|
||||
#endif
|
||||
#elif CPUINFO_ARCH_ARM || CPUINFO_ARCH_ARM64
|
||||
#if defined(__linux__)
|
||||
pthread_once(&init_guard, &cpuinfo_arm_linux_init);
|
||||
#elif defined(__MACH__) && defined(__APPLE__)
|
||||
pthread_once(&init_guard, &cpuinfo_arm_mach_init);
|
||||
#else
|
||||
cpuinfo_log_error("operating system is not supported in cpuinfo");
|
||||
#endif
|
||||
#elif CPUINFO_ARCH_ASMJS || CPUINFO_ARCH_WASM || CPUINFO_ARCH_WASMSIMD
|
||||
#if defined(__EMSCRIPTEN_PTHREADS__)
|
||||
pthread_once(&init_guard, &cpuinfo_emscripten_init);
|
||||
#else
|
||||
if (!init_guard) {
|
||||
cpuinfo_emscripten_init();
|
||||
}
|
||||
init_guard = true;
|
||||
#endif
|
||||
#else
|
||||
cpuinfo_log_error("processor architecture is not supported in cpuinfo");
|
||||
#endif
|
||||
return cpuinfo_is_initialized;
|
||||
}
|
||||
|
||||
void CPUINFO_ABI cpuinfo_deinitialize(void) {
|
||||
}
|
||||
59
3rdparty/cpuinfo/src/linux/api.h
vendored
Normal file
59
3rdparty/cpuinfo/src/linux/api.h
vendored
Normal file
@@ -0,0 +1,59 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include <cpuinfo.h>
|
||||
#include <cpuinfo/common.h>
|
||||
|
||||
|
||||
#define CPUINFO_LINUX_FLAG_PRESENT UINT32_C(0x00000001)
|
||||
#define CPUINFO_LINUX_FLAG_POSSIBLE UINT32_C(0x00000002)
|
||||
#define CPUINFO_LINUX_FLAG_MAX_FREQUENCY UINT32_C(0x00000004)
|
||||
#define CPUINFO_LINUX_FLAG_MIN_FREQUENCY UINT32_C(0x00000008)
|
||||
#define CPUINFO_LINUX_FLAG_SMT_ID UINT32_C(0x00000010)
|
||||
#define CPUINFO_LINUX_FLAG_CORE_ID UINT32_C(0x00000020)
|
||||
#define CPUINFO_LINUX_FLAG_PACKAGE_ID UINT32_C(0x00000040)
|
||||
#define CPUINFO_LINUX_FLAG_APIC_ID UINT32_C(0x00000080)
|
||||
#define CPUINFO_LINUX_FLAG_SMT_CLUSTER UINT32_C(0x00000100)
|
||||
#define CPUINFO_LINUX_FLAG_CORE_CLUSTER UINT32_C(0x00000200)
|
||||
#define CPUINFO_LINUX_FLAG_PACKAGE_CLUSTER UINT32_C(0x00000400)
|
||||
#define CPUINFO_LINUX_FLAG_PROC_CPUINFO UINT32_C(0x00000800)
|
||||
#define CPUINFO_LINUX_FLAG_VALID UINT32_C(0x00001000)
|
||||
|
||||
|
||||
typedef bool (*cpuinfo_cpulist_callback)(uint32_t, uint32_t, void*);
|
||||
CPUINFO_INTERNAL bool cpuinfo_linux_parse_cpulist(const char* filename, cpuinfo_cpulist_callback callback, void* context);
|
||||
typedef bool (*cpuinfo_smallfile_callback)(const char*, const char*, void*);
|
||||
CPUINFO_INTERNAL bool cpuinfo_linux_parse_small_file(const char* filename, size_t buffer_size, cpuinfo_smallfile_callback, void* context);
|
||||
typedef bool (*cpuinfo_line_callback)(const char*, const char*, void*, uint64_t);
|
||||
CPUINFO_INTERNAL bool cpuinfo_linux_parse_multiline_file(const char* filename, size_t buffer_size, cpuinfo_line_callback, void* context);
|
||||
|
||||
CPUINFO_INTERNAL uint32_t cpuinfo_linux_get_max_processors_count(void);
|
||||
CPUINFO_INTERNAL uint32_t cpuinfo_linux_get_max_possible_processor(uint32_t max_processors_count);
|
||||
CPUINFO_INTERNAL uint32_t cpuinfo_linux_get_max_present_processor(uint32_t max_processors_count);
|
||||
CPUINFO_INTERNAL uint32_t cpuinfo_linux_get_processor_min_frequency(uint32_t processor);
|
||||
CPUINFO_INTERNAL uint32_t cpuinfo_linux_get_processor_max_frequency(uint32_t processor);
|
||||
CPUINFO_INTERNAL bool cpuinfo_linux_get_processor_package_id(uint32_t processor, uint32_t package_id[restrict static 1]);
|
||||
CPUINFO_INTERNAL bool cpuinfo_linux_get_processor_core_id(uint32_t processor, uint32_t core_id[restrict static 1]);
|
||||
|
||||
CPUINFO_INTERNAL bool cpuinfo_linux_detect_possible_processors(uint32_t max_processors_count,
|
||||
uint32_t* processor0_flags, uint32_t processor_struct_size, uint32_t possible_flag);
|
||||
CPUINFO_INTERNAL bool cpuinfo_linux_detect_present_processors(uint32_t max_processors_count,
|
||||
uint32_t* processor0_flags, uint32_t processor_struct_size, uint32_t present_flag);
|
||||
|
||||
typedef bool (*cpuinfo_siblings_callback)(uint32_t, uint32_t, uint32_t, void*);
|
||||
CPUINFO_INTERNAL bool cpuinfo_linux_detect_core_siblings(
|
||||
uint32_t max_processors_count,
|
||||
uint32_t processor,
|
||||
cpuinfo_siblings_callback callback,
|
||||
void* context);
|
||||
CPUINFO_INTERNAL bool cpuinfo_linux_detect_thread_siblings(
|
||||
uint32_t max_processors_count,
|
||||
uint32_t processor,
|
||||
cpuinfo_siblings_callback callback,
|
||||
void* context);
|
||||
|
||||
extern CPUINFO_INTERNAL const struct cpuinfo_processor** cpuinfo_linux_cpu_to_processor_map;
|
||||
extern CPUINFO_INTERNAL const struct cpuinfo_core** cpuinfo_linux_cpu_to_core_map;
|
||||
214
3rdparty/cpuinfo/src/linux/cpulist.c
vendored
Normal file
214
3rdparty/cpuinfo/src/linux/cpulist.c
vendored
Normal file
@@ -0,0 +1,214 @@
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <sched.h>
|
||||
|
||||
#if CPUINFO_MOCK
|
||||
#include <cpuinfo-mock.h>
|
||||
#endif
|
||||
#include <linux/api.h>
|
||||
#include <cpuinfo/log.h>
|
||||
|
||||
|
||||
/*
|
||||
* Size, in chars, of the on-stack buffer used for parsing cpu lists.
|
||||
* This is also the limit on the length of a single entry
|
||||
* (<cpu-number> or <cpu-number-start>-<cpu-number-end>)
|
||||
* in the cpu list.
|
||||
*/
|
||||
#define BUFFER_SIZE 256
|
||||
|
||||
|
||||
/* Locale-independent */
|
||||
inline static bool is_whitespace(char c) {
|
||||
switch (c) {
|
||||
case ' ':
|
||||
case '\t':
|
||||
case '\n':
|
||||
case '\r':
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
inline static const char* parse_number(const char* string, const char* end, uint32_t number_ptr[restrict static 1]) {
|
||||
uint32_t number = 0;
|
||||
while (string != end) {
|
||||
const uint32_t digit = (uint32_t) (*string) - (uint32_t) '0';
|
||||
if (digit >= 10) {
|
||||
break;
|
||||
}
|
||||
number = number * UINT32_C(10) + digit;
|
||||
string += 1;
|
||||
}
|
||||
*number_ptr = number;
|
||||
return string;
|
||||
}
|
||||
|
||||
inline static bool parse_entry(const char* entry_start, const char* entry_end, cpuinfo_cpulist_callback callback, void* context) {
|
||||
/* Skip whitespace at the beginning of an entry */
|
||||
for (; entry_start != entry_end; entry_start++) {
|
||||
if (!is_whitespace(*entry_start)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* Skip whitespace at the end of an entry */
|
||||
for (; entry_end != entry_start; entry_end--) {
|
||||
if (!is_whitespace(entry_end[-1])) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const size_t entry_length = (size_t) (entry_end - entry_start);
|
||||
if (entry_length == 0) {
|
||||
cpuinfo_log_warning("unexpected zero-length cpu list entry ignored");
|
||||
return false;
|
||||
}
|
||||
|
||||
#if CPUINFO_LOG_DEBUG_PARSERS
|
||||
cpuinfo_log_debug("parse cpu list entry \"%.*s\" (%zu chars)", (int) entry_length, entry_start, entry_length);
|
||||
#endif
|
||||
uint32_t first_cpu, last_cpu;
|
||||
|
||||
const char* number_end = parse_number(entry_start, entry_end, &first_cpu);
|
||||
if (number_end == entry_start) {
|
||||
/* Failed to parse the number; ignore the entry */
|
||||
cpuinfo_log_warning("invalid character '%c' in the cpu list entry \"%.*s\": entry is ignored",
|
||||
entry_start[0], (int) entry_length, entry_start);
|
||||
return false;
|
||||
} else if (number_end == entry_end) {
|
||||
/* Completely parsed the entry */
|
||||
#if CPUINFO_LOG_DEBUG_PARSERS
|
||||
cpuinfo_log_debug("cpulist: call callback with list_start = %"PRIu32", list_end = %"PRIu32,
|
||||
first_cpu, first_cpu + 1);
|
||||
#endif
|
||||
return callback(first_cpu, first_cpu + 1, context);
|
||||
}
|
||||
|
||||
/* Parse the second part of the entry */
|
||||
if (*number_end != '-') {
|
||||
cpuinfo_log_warning("invalid character '%c' in the cpu list entry \"%.*s\": entry is ignored",
|
||||
*number_end, (int) entry_length, entry_start);
|
||||
return false;
|
||||
}
|
||||
|
||||
const char* number_start = number_end + 1;
|
||||
number_end = parse_number(number_start, entry_end, &last_cpu);
|
||||
if (number_end == number_start) {
|
||||
/* Failed to parse the second number; ignore the entry */
|
||||
cpuinfo_log_warning("invalid character '%c' in the cpu list entry \"%.*s\": entry is ignored",
|
||||
*number_start, (int) entry_length, entry_start);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (number_end != entry_end) {
|
||||
/* Partially parsed the entry; ignore unparsed characters and continue with the parsed part */
|
||||
cpuinfo_log_warning("ignored invalid characters \"%.*s\" at the end of cpu list entry \"%.*s\"",
|
||||
(int) (entry_end - number_end), number_start, (int) entry_length, entry_start);
|
||||
}
|
||||
|
||||
if (last_cpu < first_cpu) {
|
||||
cpuinfo_log_warning("ignored cpu list entry \"%.*s\": invalid range %"PRIu32"-%"PRIu32,
|
||||
(int) entry_length, entry_start, first_cpu, last_cpu);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Parsed both parts of the entry; update CPU set */
|
||||
#if CPUINFO_LOG_DEBUG_PARSERS
|
||||
cpuinfo_log_debug("cpulist: call callback with list_start = %"PRIu32", list_end = %"PRIu32,
|
||||
first_cpu, last_cpu + 1);
|
||||
#endif
|
||||
return callback(first_cpu, last_cpu + 1, context);
|
||||
}
|
||||
|
||||
bool cpuinfo_linux_parse_cpulist(const char* filename, cpuinfo_cpulist_callback callback, void* context) {
|
||||
bool status = true;
|
||||
int file = -1;
|
||||
char buffer[BUFFER_SIZE];
|
||||
#if CPUINFO_LOG_DEBUG_PARSERS
|
||||
cpuinfo_log_debug("parsing cpu list from file %s", filename);
|
||||
#endif
|
||||
|
||||
#if CPUINFO_MOCK
|
||||
file = cpuinfo_mock_open(filename, O_RDONLY);
|
||||
#else
|
||||
file = open(filename, O_RDONLY);
|
||||
#endif
|
||||
if (file == -1) {
|
||||
cpuinfo_log_info("failed to open %s: %s", filename, strerror(errno));
|
||||
status = false;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
size_t position = 0;
|
||||
const char* buffer_end = &buffer[BUFFER_SIZE];
|
||||
char* data_start = buffer;
|
||||
ssize_t bytes_read;
|
||||
do {
|
||||
#if CPUINFO_MOCK
|
||||
bytes_read = cpuinfo_mock_read(file, data_start, (size_t) (buffer_end - data_start));
|
||||
#else
|
||||
bytes_read = read(file, data_start, (size_t) (buffer_end - data_start));
|
||||
#endif
|
||||
if (bytes_read < 0) {
|
||||
cpuinfo_log_info("failed to read file %s at position %zu: %s", filename, position, strerror(errno));
|
||||
status = false;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
position += (size_t) bytes_read;
|
||||
const char* data_end = data_start + (size_t) bytes_read;
|
||||
const char* entry_start = buffer;
|
||||
|
||||
if (bytes_read == 0) {
|
||||
/* No more data in the file: process the remaining text in the buffer as a single entry */
|
||||
const char* entry_end = data_end;
|
||||
const bool entry_status = parse_entry(entry_start, entry_end, callback, context);
|
||||
status &= entry_status;
|
||||
} else {
|
||||
const char* entry_end;
|
||||
do {
|
||||
/* Find the end of the entry, as indicated by a comma (',') */
|
||||
for (entry_end = entry_start; entry_end != data_end; entry_end++) {
|
||||
if (*entry_end == ',') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* If we located separator at the end of the entry, parse it.
|
||||
* Otherwise, there may be more data at the end; read the file once again.
|
||||
*/
|
||||
if (entry_end != data_end) {
|
||||
const bool entry_status = parse_entry(entry_start, entry_end, callback, context);
|
||||
status &= entry_status;
|
||||
entry_start = entry_end + 1;
|
||||
}
|
||||
} while (entry_end != data_end);
|
||||
|
||||
/* Move remaining partial entry data at the end to the beginning of the buffer */
|
||||
const size_t entry_length = (size_t) (entry_end - entry_start);
|
||||
memmove(buffer, entry_start, entry_length);
|
||||
data_start = &buffer[entry_length];
|
||||
}
|
||||
} while (bytes_read != 0);
|
||||
|
||||
cleanup:
|
||||
if (file != -1) {
|
||||
#if CPUINFO_MOCK
|
||||
cpuinfo_mock_close(file);
|
||||
#else
|
||||
close(file);
|
||||
#endif
|
||||
file = -1;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
105
3rdparty/cpuinfo/src/linux/mockfile.c
vendored
Normal file
105
3rdparty/cpuinfo/src/linux/mockfile.c
vendored
Normal file
@@ -0,0 +1,105 @@
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <sched.h>
|
||||
|
||||
#if !CPUINFO_MOCK
|
||||
#error This file should be built only in mock mode
|
||||
#endif
|
||||
|
||||
#include <cpuinfo-mock.h>
|
||||
#include <arm/linux/api.h>
|
||||
#include <arm/midr.h>
|
||||
#include <cpuinfo/log.h>
|
||||
|
||||
|
||||
static struct cpuinfo_mock_file* cpuinfo_mock_files = NULL;
|
||||
static uint32_t cpuinfo_mock_file_count = 0;
|
||||
|
||||
|
||||
void CPUINFO_ABI cpuinfo_mock_filesystem(struct cpuinfo_mock_file* files) {
|
||||
cpuinfo_log_info("filesystem mocking enabled");
|
||||
uint32_t file_count = 0;
|
||||
while (files[file_count].path != NULL) {
|
||||
/* Indicate that file is not opened */
|
||||
files[file_count].offset = SIZE_MAX;
|
||||
file_count += 1;
|
||||
}
|
||||
cpuinfo_mock_files = files;
|
||||
cpuinfo_mock_file_count = file_count;
|
||||
}
|
||||
|
||||
int CPUINFO_ABI cpuinfo_mock_open(const char* path, int oflag) {
|
||||
if (cpuinfo_mock_files == NULL) {
|
||||
cpuinfo_log_warning("cpuinfo_mock_open called without mock filesystem; redictering to open");
|
||||
return open(path, oflag);
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < cpuinfo_mock_file_count; i++) {
|
||||
if (strcmp(cpuinfo_mock_files[i].path, path) == 0) {
|
||||
if (oflag != O_RDONLY) {
|
||||
errno = EACCES;
|
||||
return -1;
|
||||
}
|
||||
if (cpuinfo_mock_files[i].offset != SIZE_MAX) {
|
||||
errno = ENFILE;
|
||||
return -1;
|
||||
}
|
||||
cpuinfo_mock_files[i].offset = 0;
|
||||
return (int) i;
|
||||
}
|
||||
}
|
||||
errno = ENOENT;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int CPUINFO_ABI cpuinfo_mock_close(int fd) {
|
||||
if (cpuinfo_mock_files == NULL) {
|
||||
cpuinfo_log_warning("cpuinfo_mock_close called without mock filesystem; redictering to close");
|
||||
return close(fd);
|
||||
}
|
||||
|
||||
if ((unsigned int) fd >= cpuinfo_mock_file_count) {
|
||||
errno = EBADF;
|
||||
return -1;
|
||||
}
|
||||
if (cpuinfo_mock_files[fd].offset == SIZE_MAX) {
|
||||
errno = EBADF;
|
||||
return -1;
|
||||
}
|
||||
cpuinfo_mock_files[fd].offset = SIZE_MAX;
|
||||
return 0;
|
||||
}
|
||||
|
||||
ssize_t CPUINFO_ABI cpuinfo_mock_read(int fd, void* buffer, size_t capacity) {
|
||||
if (cpuinfo_mock_files == NULL) {
|
||||
cpuinfo_log_warning("cpuinfo_mock_read called without mock filesystem; redictering to read");
|
||||
return read(fd, buffer, capacity);
|
||||
}
|
||||
|
||||
if ((unsigned int) fd >= cpuinfo_mock_file_count) {
|
||||
errno = EBADF;
|
||||
return -1;
|
||||
}
|
||||
if (cpuinfo_mock_files[fd].offset == SIZE_MAX) {
|
||||
errno = EBADF;
|
||||
return -1;
|
||||
}
|
||||
|
||||
const size_t offset = cpuinfo_mock_files[fd].offset;
|
||||
size_t count = cpuinfo_mock_files[fd].size - offset;
|
||||
if (count > capacity) {
|
||||
count = capacity;
|
||||
}
|
||||
memcpy(buffer, (void*) cpuinfo_mock_files[fd].content + offset, count);
|
||||
cpuinfo_mock_files[fd].offset += count;
|
||||
return (ssize_t) count;
|
||||
}
|
||||
106
3rdparty/cpuinfo/src/linux/multiline.c
vendored
Normal file
106
3rdparty/cpuinfo/src/linux/multiline.c
vendored
Normal file
@@ -0,0 +1,106 @@
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <alloca.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#if CPUINFO_MOCK
|
||||
#include <cpuinfo-mock.h>
|
||||
#endif
|
||||
#include <linux/api.h>
|
||||
#include <cpuinfo/log.h>
|
||||
|
||||
|
||||
bool cpuinfo_linux_parse_multiline_file(const char* filename, size_t buffer_size, cpuinfo_line_callback callback, void* context)
|
||||
{
|
||||
int file = -1;
|
||||
bool status = false;
|
||||
char* buffer = (char*) alloca(buffer_size);
|
||||
|
||||
#if CPUINFO_MOCK
|
||||
file = cpuinfo_mock_open(filename, O_RDONLY);
|
||||
#else
|
||||
file = open(filename, O_RDONLY);
|
||||
#endif
|
||||
if (file == -1) {
|
||||
cpuinfo_log_info("failed to open %s: %s", filename, strerror(errno));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Only used for error reporting */
|
||||
size_t position = 0;
|
||||
uint64_t line_number = 1;
|
||||
const char* buffer_end = &buffer[buffer_size];
|
||||
char* data_start = buffer;
|
||||
ssize_t bytes_read;
|
||||
do {
|
||||
#if CPUINFO_MOCK
|
||||
bytes_read = cpuinfo_mock_read(file, data_start, (size_t) (buffer_end - data_start));
|
||||
#else
|
||||
bytes_read = read(file, data_start, (size_t) (buffer_end - data_start));
|
||||
#endif
|
||||
if (bytes_read < 0) {
|
||||
cpuinfo_log_info("failed to read file %s at position %zu: %s",
|
||||
filename, position, strerror(errno));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
position += (size_t) bytes_read;
|
||||
const char* data_end = data_start + (size_t) bytes_read;
|
||||
const char* line_start = buffer;
|
||||
|
||||
if (bytes_read == 0) {
|
||||
/* No more data in the file: process the remaining text in the buffer as a single entry */
|
||||
const char* line_end = data_end;
|
||||
if (!callback(line_start, line_end, context, line_number)) {
|
||||
goto cleanup;
|
||||
}
|
||||
} else {
|
||||
const char* line_end;
|
||||
do {
|
||||
/* Find the end of the entry, as indicated by newline character ('\n') */
|
||||
for (line_end = line_start; line_end != data_end; line_end++) {
|
||||
if (*line_end == '\n') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* If we located separator at the end of the entry, parse it.
|
||||
* Otherwise, there may be more data at the end; read the file once again.
|
||||
*/
|
||||
if (line_end != data_end) {
|
||||
if (!callback(line_start, line_end, context, line_number++)) {
|
||||
goto cleanup;
|
||||
}
|
||||
line_start = line_end + 1;
|
||||
}
|
||||
} while (line_end != data_end);
|
||||
|
||||
/* Move remaining partial line data at the end to the beginning of the buffer */
|
||||
const size_t line_length = (size_t) (line_end - line_start);
|
||||
memmove(buffer, line_start, line_length);
|
||||
data_start = &buffer[line_length];
|
||||
}
|
||||
} while (bytes_read != 0);
|
||||
|
||||
/* Commit */
|
||||
status = true;
|
||||
|
||||
cleanup:
|
||||
if (file != -1) {
|
||||
#if CPUINFO_MOCK
|
||||
cpuinfo_mock_close(file);
|
||||
#else
|
||||
close(file);
|
||||
#endif
|
||||
file = -1;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
406
3rdparty/cpuinfo/src/linux/processors.c
vendored
Normal file
406
3rdparty/cpuinfo/src/linux/processors.c
vendored
Normal file
@@ -0,0 +1,406 @@
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#if !defined(__ANDROID__)
|
||||
/*
|
||||
* sched.h is only used for CPU_SETSIZE constant.
|
||||
* Android NDK headers before platform 21 do have this constant in sched.h
|
||||
*/
|
||||
#include <sched.h>
|
||||
#endif
|
||||
|
||||
#include <linux/api.h>
|
||||
#include <cpuinfo/log.h>
|
||||
|
||||
|
||||
#define STRINGIFY(token) #token
|
||||
|
||||
#define KERNEL_MAX_FILENAME "/sys/devices/system/cpu/kernel_max"
|
||||
#define KERNEL_MAX_FILESIZE 32
|
||||
#define FREQUENCY_FILENAME_SIZE (sizeof("/sys/devices/system/cpu/cpu" STRINGIFY(UINT32_MAX) "/cpufreq/cpuinfo_max_freq"))
|
||||
#define MAX_FREQUENCY_FILENAME_FORMAT "/sys/devices/system/cpu/cpu%" PRIu32 "/cpufreq/cpuinfo_max_freq"
|
||||
#define MIN_FREQUENCY_FILENAME_FORMAT "/sys/devices/system/cpu/cpu%" PRIu32 "/cpufreq/cpuinfo_min_freq"
|
||||
#define FREQUENCY_FILESIZE 32
|
||||
#define PACKAGE_ID_FILENAME_SIZE (sizeof("/sys/devices/system/cpu/cpu" STRINGIFY(UINT32_MAX) "/topology/physical_package_id"))
|
||||
#define PACKAGE_ID_FILENAME_FORMAT "/sys/devices/system/cpu/cpu%" PRIu32 "/topology/physical_package_id"
|
||||
#define PACKAGE_ID_FILESIZE 32
|
||||
#define CORE_ID_FILENAME_SIZE (sizeof("/sys/devices/system/cpu/cpu" STRINGIFY(UINT32_MAX) "/topology/core_id"))
|
||||
#define CORE_ID_FILENAME_FORMAT "/sys/devices/system/cpu/cpu%" PRIu32 "/topology/core_id"
|
||||
#define CORE_ID_FILESIZE 32
|
||||
|
||||
#define CORE_SIBLINGS_FILENAME_SIZE (sizeof("/sys/devices/system/cpu/cpu" STRINGIFY(UINT32_MAX) "/topology/core_siblings_list"))
|
||||
#define CORE_SIBLINGS_FILENAME_FORMAT "/sys/devices/system/cpu/cpu%" PRIu32 "/topology/core_siblings_list"
|
||||
#define THREAD_SIBLINGS_FILENAME_SIZE (sizeof("/sys/devices/system/cpu/cpu" STRINGIFY(UINT32_MAX) "/topology/thread_siblings_list"))
|
||||
#define THREAD_SIBLINGS_FILENAME_FORMAT "/sys/devices/system/cpu/cpu%" PRIu32 "/topology/thread_siblings_list"
|
||||
|
||||
#define POSSIBLE_CPULIST_FILENAME "/sys/devices/system/cpu/possible"
|
||||
#define PRESENT_CPULIST_FILENAME "/sys/devices/system/cpu/present"
|
||||
|
||||
|
||||
inline static const char* parse_number(const char* start, const char* end, uint32_t number_ptr[restrict static 1]) {
|
||||
uint32_t number = 0;
|
||||
const char* parsed = start;
|
||||
for (; parsed != end; parsed++) {
|
||||
const uint32_t digit = (uint32_t) (uint8_t) (*parsed) - (uint32_t) '0';
|
||||
if (digit >= 10) {
|
||||
break;
|
||||
}
|
||||
number = number * UINT32_C(10) + digit;
|
||||
}
|
||||
*number_ptr = number;
|
||||
return parsed;
|
||||
}
|
||||
|
||||
/* Locale-independent */
|
||||
inline static bool is_whitespace(char c) {
|
||||
switch (c) {
|
||||
case ' ':
|
||||
case '\t':
|
||||
case '\n':
|
||||
case '\r':
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(__ANDROID__) && !defined(CPU_SETSIZE)
|
||||
/*
|
||||
* Android NDK headers before platform 21 do not define CPU_SETSIZE,
|
||||
* so we hard-code its value, as defined in platform 21 headers
|
||||
*/
|
||||
#if defined(__LP64__)
|
||||
static const uint32_t default_max_processors_count = 1024;
|
||||
#else
|
||||
static const uint32_t default_max_processors_count = 32;
|
||||
#endif
|
||||
#else
|
||||
static const uint32_t default_max_processors_count = CPU_SETSIZE;
|
||||
#endif
|
||||
|
||||
static bool uint32_parser(const char* text_start, const char* text_end, void* context) {
|
||||
if (text_start == text_end) {
|
||||
cpuinfo_log_error("failed to parse file %s: file is empty", KERNEL_MAX_FILENAME);
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t kernel_max = 0;
|
||||
const char* parsed_end = parse_number(text_start, text_end, &kernel_max);
|
||||
if (parsed_end == text_start) {
|
||||
cpuinfo_log_error("failed to parse file %s: \"%.*s\" is not an unsigned number",
|
||||
KERNEL_MAX_FILENAME, (int) (text_end - text_start), text_start);
|
||||
return false;
|
||||
} else {
|
||||
for (const char* char_ptr = parsed_end; char_ptr != text_end; char_ptr++) {
|
||||
if (!is_whitespace(*char_ptr)) {
|
||||
cpuinfo_log_warning("non-whitespace characters \"%.*s\" following number in file %s are ignored",
|
||||
(int) (text_end - char_ptr), char_ptr, KERNEL_MAX_FILENAME);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t* kernel_max_ptr = (uint32_t*) context;
|
||||
*kernel_max_ptr = kernel_max;
|
||||
return true;
|
||||
}
|
||||
|
||||
uint32_t cpuinfo_linux_get_max_processors_count(void) {
|
||||
uint32_t kernel_max;
|
||||
if (cpuinfo_linux_parse_small_file(KERNEL_MAX_FILENAME, KERNEL_MAX_FILESIZE, uint32_parser, &kernel_max)) {
|
||||
cpuinfo_log_debug("parsed kernel_max value of %"PRIu32" from %s", kernel_max, KERNEL_MAX_FILENAME);
|
||||
|
||||
if (kernel_max >= default_max_processors_count) {
|
||||
cpuinfo_log_warning("kernel_max value of %"PRIu32" parsed from %s exceeds platform-default limit %"PRIu32,
|
||||
kernel_max, KERNEL_MAX_FILENAME, default_max_processors_count - 1);
|
||||
}
|
||||
|
||||
return kernel_max + 1;
|
||||
} else {
|
||||
cpuinfo_log_warning("using platform-default max processors count = %"PRIu32, default_max_processors_count);
|
||||
return default_max_processors_count;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t cpuinfo_linux_get_processor_max_frequency(uint32_t processor) {
|
||||
char max_frequency_filename[FREQUENCY_FILENAME_SIZE];
|
||||
const int chars_formatted = snprintf(
|
||||
max_frequency_filename, FREQUENCY_FILENAME_SIZE, MAX_FREQUENCY_FILENAME_FORMAT, processor);
|
||||
if ((unsigned int) chars_formatted >= FREQUENCY_FILENAME_SIZE) {
|
||||
cpuinfo_log_warning("failed to format filename for max frequency of processor %"PRIu32, processor);
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t max_frequency;
|
||||
if (cpuinfo_linux_parse_small_file(max_frequency_filename, FREQUENCY_FILESIZE, uint32_parser, &max_frequency)) {
|
||||
cpuinfo_log_debug("parsed max frequency value of %"PRIu32" KHz for logical processor %"PRIu32" from %s",
|
||||
max_frequency, processor, max_frequency_filename);
|
||||
return max_frequency;
|
||||
} else {
|
||||
cpuinfo_log_warning("failed to parse max frequency for processor %"PRIu32" from %s",
|
||||
processor, max_frequency_filename);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t cpuinfo_linux_get_processor_min_frequency(uint32_t processor) {
|
||||
char min_frequency_filename[FREQUENCY_FILENAME_SIZE];
|
||||
const int chars_formatted = snprintf(
|
||||
min_frequency_filename, FREQUENCY_FILENAME_SIZE, MIN_FREQUENCY_FILENAME_FORMAT, processor);
|
||||
if ((unsigned int) chars_formatted >= FREQUENCY_FILENAME_SIZE) {
|
||||
cpuinfo_log_warning("failed to format filename for min frequency of processor %"PRIu32, processor);
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t min_frequency;
|
||||
if (cpuinfo_linux_parse_small_file(min_frequency_filename, FREQUENCY_FILESIZE, uint32_parser, &min_frequency)) {
|
||||
cpuinfo_log_debug("parsed min frequency value of %"PRIu32" KHz for logical processor %"PRIu32" from %s",
|
||||
min_frequency, processor, min_frequency_filename);
|
||||
return min_frequency;
|
||||
} else {
|
||||
/*
|
||||
* This error is less severe than parsing max frequency, because min frequency is only useful for clustering,
|
||||
* while max frequency is also needed for peak FLOPS calculation.
|
||||
*/
|
||||
cpuinfo_log_info("failed to parse min frequency for processor %"PRIu32" from %s",
|
||||
processor, min_frequency_filename);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool cpuinfo_linux_get_processor_core_id(uint32_t processor, uint32_t core_id_ptr[restrict static 1]) {
|
||||
char core_id_filename[PACKAGE_ID_FILENAME_SIZE];
|
||||
const int chars_formatted = snprintf(
|
||||
core_id_filename, CORE_ID_FILENAME_SIZE, CORE_ID_FILENAME_FORMAT, processor);
|
||||
if ((unsigned int) chars_formatted >= CORE_ID_FILENAME_SIZE) {
|
||||
cpuinfo_log_warning("failed to format filename for core id of processor %"PRIu32, processor);
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t core_id;
|
||||
if (cpuinfo_linux_parse_small_file(core_id_filename, CORE_ID_FILESIZE, uint32_parser, &core_id)) {
|
||||
cpuinfo_log_debug("parsed core id value of %"PRIu32" for logical processor %"PRIu32" from %s",
|
||||
core_id, processor, core_id_filename);
|
||||
*core_id_ptr = core_id;
|
||||
return true;
|
||||
} else {
|
||||
cpuinfo_log_info("failed to parse core id for processor %"PRIu32" from %s",
|
||||
processor, core_id_filename);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool cpuinfo_linux_get_processor_package_id(uint32_t processor, uint32_t package_id_ptr[restrict static 1]) {
|
||||
char package_id_filename[PACKAGE_ID_FILENAME_SIZE];
|
||||
const int chars_formatted = snprintf(
|
||||
package_id_filename, PACKAGE_ID_FILENAME_SIZE, PACKAGE_ID_FILENAME_FORMAT, processor);
|
||||
if ((unsigned int) chars_formatted >= PACKAGE_ID_FILENAME_SIZE) {
|
||||
cpuinfo_log_warning("failed to format filename for package id of processor %"PRIu32, processor);
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t package_id;
|
||||
if (cpuinfo_linux_parse_small_file(package_id_filename, PACKAGE_ID_FILESIZE, uint32_parser, &package_id)) {
|
||||
cpuinfo_log_debug("parsed package id value of %"PRIu32" for logical processor %"PRIu32" from %s",
|
||||
package_id, processor, package_id_filename);
|
||||
*package_id_ptr = package_id;
|
||||
return true;
|
||||
} else {
|
||||
cpuinfo_log_info("failed to parse package id for processor %"PRIu32" from %s",
|
||||
processor, package_id_filename);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static bool max_processor_number_parser(uint32_t processor_list_start, uint32_t processor_list_end, void* context) {
|
||||
uint32_t* processor_number_ptr = (uint32_t*) context;
|
||||
const uint32_t processor_list_last = processor_list_end - 1;
|
||||
if (*processor_number_ptr < processor_list_last) {
|
||||
*processor_number_ptr = processor_list_last;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
uint32_t cpuinfo_linux_get_max_possible_processor(uint32_t max_processors_count) {
|
||||
uint32_t max_possible_processor = 0;
|
||||
if (!cpuinfo_linux_parse_cpulist(POSSIBLE_CPULIST_FILENAME, max_processor_number_parser, &max_possible_processor)) {
|
||||
#if CPUINFO_ARCH_ARM || CPUINFO_ARCH_ARM64
|
||||
cpuinfo_log_error("failed to parse the list of possible processors in %s", POSSIBLE_CPULIST_FILENAME);
|
||||
#else
|
||||
cpuinfo_log_warning("failed to parse the list of possible processors in %s", POSSIBLE_CPULIST_FILENAME);
|
||||
#endif
|
||||
return UINT32_MAX;
|
||||
}
|
||||
if (max_possible_processor >= max_processors_count) {
|
||||
cpuinfo_log_warning(
|
||||
"maximum possible processor number %"PRIu32" exceeds system limit %"PRIu32": truncating to the latter",
|
||||
max_possible_processor, max_processors_count - 1);
|
||||
max_possible_processor = max_processors_count - 1;
|
||||
}
|
||||
return max_possible_processor;
|
||||
}
|
||||
|
||||
uint32_t cpuinfo_linux_get_max_present_processor(uint32_t max_processors_count) {
|
||||
uint32_t max_present_processor = 0;
|
||||
if (!cpuinfo_linux_parse_cpulist(PRESENT_CPULIST_FILENAME, max_processor_number_parser, &max_present_processor)) {
|
||||
#if CPUINFO_ARCH_ARM || CPUINFO_ARCH_ARM64
|
||||
cpuinfo_log_error("failed to parse the list of present processors in %s", PRESENT_CPULIST_FILENAME);
|
||||
#else
|
||||
cpuinfo_log_warning("failed to parse the list of present processors in %s", PRESENT_CPULIST_FILENAME);
|
||||
#endif
|
||||
return UINT32_MAX;
|
||||
}
|
||||
if (max_present_processor >= max_processors_count) {
|
||||
cpuinfo_log_warning(
|
||||
"maximum present processor number %"PRIu32" exceeds system limit %"PRIu32": truncating to the latter",
|
||||
max_present_processor, max_processors_count - 1);
|
||||
max_present_processor = max_processors_count - 1;
|
||||
}
|
||||
return max_present_processor;
|
||||
}
|
||||
|
||||
struct detect_processors_context {
|
||||
uint32_t max_processors_count;
|
||||
uint32_t* processor0_flags;
|
||||
uint32_t processor_struct_size;
|
||||
uint32_t detected_flag;
|
||||
};
|
||||
|
||||
static bool detect_processor_parser(uint32_t processor_list_start, uint32_t processor_list_end, void* context) {
|
||||
const uint32_t max_processors_count = ((struct detect_processors_context*) context)->max_processors_count;
|
||||
const uint32_t* processor0_flags = ((struct detect_processors_context*) context)->processor0_flags;
|
||||
const uint32_t processor_struct_size = ((struct detect_processors_context*) context)->processor_struct_size;
|
||||
const uint32_t detected_flag = ((struct detect_processors_context*) context)->detected_flag;
|
||||
|
||||
for (uint32_t processor = processor_list_start; processor < processor_list_end; processor++) {
|
||||
if (processor >= max_processors_count) {
|
||||
break;
|
||||
}
|
||||
*((uint32_t*) ((uintptr_t) processor0_flags + processor_struct_size * processor)) |= detected_flag;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool cpuinfo_linux_detect_possible_processors(uint32_t max_processors_count,
|
||||
uint32_t* processor0_flags, uint32_t processor_struct_size, uint32_t possible_flag)
|
||||
{
|
||||
struct detect_processors_context context = {
|
||||
.max_processors_count = max_processors_count,
|
||||
.processor0_flags = processor0_flags,
|
||||
.processor_struct_size = processor_struct_size,
|
||||
.detected_flag = possible_flag,
|
||||
};
|
||||
if (cpuinfo_linux_parse_cpulist(POSSIBLE_CPULIST_FILENAME, detect_processor_parser, &context)) {
|
||||
return true;
|
||||
} else {
|
||||
cpuinfo_log_warning("failed to parse the list of possible processors in %s", POSSIBLE_CPULIST_FILENAME);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool cpuinfo_linux_detect_present_processors(uint32_t max_processors_count,
|
||||
uint32_t* processor0_flags, uint32_t processor_struct_size, uint32_t present_flag)
|
||||
{
|
||||
struct detect_processors_context context = {
|
||||
.max_processors_count = max_processors_count,
|
||||
.processor0_flags = processor0_flags,
|
||||
.processor_struct_size = processor_struct_size,
|
||||
.detected_flag = present_flag,
|
||||
};
|
||||
if (cpuinfo_linux_parse_cpulist(PRESENT_CPULIST_FILENAME, detect_processor_parser, &context)) {
|
||||
return true;
|
||||
} else {
|
||||
cpuinfo_log_warning("failed to parse the list of present processors in %s", PRESENT_CPULIST_FILENAME);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
struct siblings_context {
|
||||
const char* group_name;
|
||||
uint32_t max_processors_count;
|
||||
uint32_t processor;
|
||||
cpuinfo_siblings_callback callback;
|
||||
void* callback_context;
|
||||
};
|
||||
|
||||
static bool siblings_parser(uint32_t sibling_list_start, uint32_t sibling_list_end, struct siblings_context* context) {
|
||||
const char* group_name = context->group_name;
|
||||
const uint32_t max_processors_count = context->max_processors_count;
|
||||
const uint32_t processor = context->processor;
|
||||
|
||||
if (sibling_list_end > max_processors_count) {
|
||||
cpuinfo_log_warning("ignore %s siblings %"PRIu32"-%"PRIu32" of processor %"PRIu32,
|
||||
group_name, max_processors_count, sibling_list_end - 1, processor);
|
||||
sibling_list_end = max_processors_count;
|
||||
}
|
||||
|
||||
return context->callback(processor, sibling_list_start, sibling_list_end, context->callback_context);
|
||||
}
|
||||
|
||||
bool cpuinfo_linux_detect_core_siblings(
|
||||
uint32_t max_processors_count,
|
||||
uint32_t processor,
|
||||
cpuinfo_siblings_callback callback,
|
||||
void* context)
|
||||
{
|
||||
char core_siblings_filename[CORE_SIBLINGS_FILENAME_SIZE];
|
||||
const int chars_formatted = snprintf(
|
||||
core_siblings_filename, CORE_SIBLINGS_FILENAME_SIZE, CORE_SIBLINGS_FILENAME_FORMAT, processor);
|
||||
if ((unsigned int) chars_formatted >= CORE_SIBLINGS_FILENAME_SIZE) {
|
||||
cpuinfo_log_warning("failed to format filename for core siblings of processor %"PRIu32, processor);
|
||||
return false;
|
||||
}
|
||||
|
||||
struct siblings_context siblings_context = {
|
||||
.group_name = "package",
|
||||
.max_processors_count = max_processors_count,
|
||||
.processor = processor,
|
||||
.callback = callback,
|
||||
.callback_context = context,
|
||||
};
|
||||
if (cpuinfo_linux_parse_cpulist(core_siblings_filename,
|
||||
(cpuinfo_cpulist_callback) siblings_parser, &siblings_context))
|
||||
{
|
||||
return true;
|
||||
} else {
|
||||
cpuinfo_log_info("failed to parse the list of core siblings for processor %"PRIu32" from %s",
|
||||
processor, core_siblings_filename);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool cpuinfo_linux_detect_thread_siblings(
|
||||
uint32_t max_processors_count,
|
||||
uint32_t processor,
|
||||
cpuinfo_siblings_callback callback,
|
||||
void* context)
|
||||
{
|
||||
char thread_siblings_filename[THREAD_SIBLINGS_FILENAME_SIZE];
|
||||
const int chars_formatted = snprintf(
|
||||
thread_siblings_filename, THREAD_SIBLINGS_FILENAME_SIZE, THREAD_SIBLINGS_FILENAME_FORMAT, processor);
|
||||
if ((unsigned int) chars_formatted >= THREAD_SIBLINGS_FILENAME_SIZE) {
|
||||
cpuinfo_log_warning("failed to format filename for thread siblings of processor %"PRIu32, processor);
|
||||
return false;
|
||||
}
|
||||
|
||||
struct siblings_context siblings_context = {
|
||||
.group_name = "core",
|
||||
.max_processors_count = max_processors_count,
|
||||
.processor = processor,
|
||||
.callback = callback,
|
||||
.callback_context = context,
|
||||
};
|
||||
if (cpuinfo_linux_parse_cpulist(thread_siblings_filename,
|
||||
(cpuinfo_cpulist_callback) siblings_parser, &siblings_context))
|
||||
{
|
||||
return true;
|
||||
} else {
|
||||
cpuinfo_log_info("failed to parse the list of thread siblings for processor %"PRIu32" from %s",
|
||||
processor, thread_siblings_filename);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
70
3rdparty/cpuinfo/src/linux/smallfile.c
vendored
Normal file
70
3rdparty/cpuinfo/src/linux/smallfile.c
vendored
Normal file
@@ -0,0 +1,70 @@
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <alloca.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#if CPUINFO_MOCK
|
||||
#include <cpuinfo-mock.h>
|
||||
#endif
|
||||
#include <linux/api.h>
|
||||
#include <cpuinfo/log.h>
|
||||
|
||||
|
||||
bool cpuinfo_linux_parse_small_file(const char* filename, size_t buffer_size, cpuinfo_smallfile_callback callback, void* context) {
|
||||
int file = -1;
|
||||
bool status = false;
|
||||
char* buffer = (char*) alloca(buffer_size);
|
||||
|
||||
#if CPUINFO_LOG_DEBUG_PARSERS
|
||||
cpuinfo_log_debug("parsing small file %s", filename);
|
||||
#endif
|
||||
|
||||
#if CPUINFO_MOCK
|
||||
file = cpuinfo_mock_open(filename, O_RDONLY);
|
||||
#else
|
||||
file = open(filename, O_RDONLY);
|
||||
#endif
|
||||
if (file == -1) {
|
||||
cpuinfo_log_info("failed to open %s: %s", filename, strerror(errno));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
size_t buffer_position = 0;
|
||||
ssize_t bytes_read;
|
||||
do {
|
||||
#if CPUINFO_MOCK
|
||||
bytes_read = cpuinfo_mock_read(file, &buffer[buffer_position], buffer_size - buffer_position);
|
||||
#else
|
||||
bytes_read = read(file, &buffer[buffer_position], buffer_size - buffer_position);
|
||||
#endif
|
||||
if (bytes_read < 0) {
|
||||
cpuinfo_log_info("failed to read file %s at position %zu: %s", filename, buffer_position, strerror(errno));
|
||||
goto cleanup;
|
||||
}
|
||||
buffer_position += (size_t) bytes_read;
|
||||
if (buffer_position >= buffer_size) {
|
||||
cpuinfo_log_error("failed to read file %s: insufficient buffer of size %zu", filename, buffer_size);
|
||||
goto cleanup;
|
||||
}
|
||||
} while (bytes_read != 0);
|
||||
|
||||
status = callback(buffer, &buffer[buffer_position], context);
|
||||
|
||||
cleanup:
|
||||
if (file != -1) {
|
||||
#if CPUINFO_MOCK
|
||||
cpuinfo_mock_close(file);
|
||||
#else
|
||||
close(file);
|
||||
#endif
|
||||
file = -1;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user