Compare commits
673 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
df8eb43074 | ||
|
|
8b5aedd463 | ||
|
|
b0c0dc53b1 | ||
|
|
17dcb961ec | ||
|
|
ef307e8ec6 | ||
|
|
b8684777e0 | ||
|
|
446025fb65 | ||
|
|
19105542e5 | ||
|
|
467c2408c4 | ||
|
|
f87a4fcd4e | ||
|
|
9120318594 | ||
|
|
982442eb00 | ||
|
|
40274f5fac | ||
|
|
a03804b09d | ||
|
|
a9f40cf608 | ||
|
|
82025bacad | ||
|
|
2640cea175 | ||
|
|
63265728d4 | ||
|
|
69a3b6dad7 | ||
|
|
30aed15090 | ||
|
|
f7ae2e2220 | ||
|
|
f93d80b8d2 | ||
|
|
a6632625f4 | ||
|
|
b353d68193 | ||
|
|
b46b6363ff | ||
|
|
3be4b103a2 | ||
|
|
dc5efeecbb | ||
|
|
6dea9a4b63 | ||
|
|
4e5a796e50 | ||
|
|
9620f040cb | ||
|
|
d20c77c618 | ||
|
|
ba610864c7 | ||
|
|
d7bf156b30 | ||
|
|
195b635f74 | ||
|
|
c0ae77cd64 | ||
|
|
57b2d6dbd8 | ||
|
|
4e3ba66b0c | ||
|
|
278876c19d | ||
|
|
68a6007fd9 | ||
|
|
346c172b32 | ||
|
|
5ddac353a0 | ||
|
|
4545256b49 | ||
|
|
db23e4966e | ||
|
|
5146429d19 | ||
|
|
0e80c19d3d | ||
|
|
401e662f0b | ||
|
|
ad5ebae304 | ||
|
|
7d5feb943f | ||
|
|
b6d4fb698c | ||
|
|
e3ecd73cd8 | ||
|
|
5dfc6ae62e | ||
|
|
343622d4e5 | ||
|
|
9945ebab34 | ||
|
|
42774d94c0 | ||
|
|
dd535158f2 | ||
|
|
a7245116b6 | ||
|
|
2aef7176ab | ||
|
|
5e1e056623 | ||
|
|
da5c1e9833 | ||
|
|
b6218a1121 | ||
|
|
17ca402aa0 | ||
|
|
cd037aca15 | ||
|
|
bdae812274 | ||
|
|
f1246f84e0 | ||
|
|
9b75acf0b5 | ||
|
|
42d7f4245d | ||
|
|
fd25d3babc | ||
|
|
3f8dfbd5b2 | ||
|
|
0394f29f70 | ||
|
|
0a07a7af01 | ||
|
|
a30ef5b3dc | ||
|
|
2750ec8ef9 | ||
|
|
850999727c | ||
|
|
3dd029b1ac | ||
|
|
75e7fe941b | ||
|
|
cbd2d9d625 | ||
|
|
1d30322820 | ||
|
|
e0246df26b | ||
|
|
e845379b1e | ||
|
|
c631ec5ef5 | ||
|
|
44d3918e4f | ||
|
|
19f9496889 | ||
|
|
2dd78beb92 | ||
|
|
7bb6b21c65 | ||
|
|
11eef8d892 | ||
|
|
4d9b33ecd4 | ||
|
|
421fe33dc0 | ||
|
|
5c82e5ba1b | ||
|
|
b3aaddadc8 | ||
|
|
939022bb5e | ||
|
|
950360fddc | ||
|
|
2ff7a0864b | ||
|
|
488f2df869 | ||
|
|
6877944d17 | ||
|
|
5083d3d13e | ||
|
|
eeef23c2b7 | ||
|
|
a3fff889d1 | ||
|
|
9f3e682b89 | ||
|
|
411c8c4cb3 | ||
|
|
c1d9b35e7c | ||
|
|
cd9b85b555 | ||
|
|
5f88f5ed02 | ||
|
|
a6ec294f63 | ||
|
|
4d5ed8157c | ||
|
|
042f061d86 | ||
|
|
99de8454cd | ||
|
|
348b64ebb0 | ||
|
|
3c44bf55eb | ||
|
|
af7b9bde29 | ||
|
|
1fb47318c0 | ||
|
|
13b39ae730 | ||
|
|
037e42da1d | ||
|
|
25522a8450 | ||
|
|
300bf9c2c5 | ||
|
|
cade24a7ce | ||
|
|
fd93023440 | ||
|
|
762e755b13 | ||
|
|
c536da7279 | ||
|
|
f250a33e9b | ||
|
|
c23a1bfabb | ||
|
|
d60f8ed8d5 | ||
|
|
6317e3ad00 | ||
|
|
7d8535af22 | ||
|
|
c9d713fc7f | ||
|
|
186724e751 | ||
|
|
80f815c020 | ||
|
|
28068ed36d | ||
|
|
f79fe2e056 | ||
|
|
e19177d3ed | ||
|
|
75b5d11181 | ||
|
|
03d4a9ba3c | ||
|
|
8f529046a9 | ||
|
|
d36b2d8057 | ||
|
|
4dc9675a6c | ||
|
|
2b16b69afa | ||
|
|
76beee62c3 | ||
|
|
59d7271fb5 | ||
|
|
d675d6e54b | ||
|
|
ea9d20a250 | ||
|
|
fce22b0d35 | ||
|
|
363d30eadc | ||
|
|
5e2cfab7ba | ||
|
|
5524ca5b25 | ||
|
|
1802c5ea2e | ||
|
|
269324c553 | ||
|
|
ec9e34c970 | ||
|
|
b88cd1d41f | ||
|
|
0b2df134ce | ||
|
|
12e893e11f | ||
|
|
972a35bdef | ||
|
|
edfc5ab8b4 | ||
|
|
37e385e783 | ||
|
|
746291dc67 | ||
|
|
c07c39f8ed | ||
|
|
9fbbd8b954 | ||
|
|
910fde3b2c | ||
|
|
82333ceb82 | ||
|
|
ec58d1c309 | ||
|
|
e408142ca5 | ||
|
|
55c9faaa79 | ||
|
|
0ae489f49d | ||
|
|
e05e05b13a | ||
|
|
6190b05a13 | ||
|
|
19a799656a | ||
|
|
4436145eaf | ||
|
|
6a41446185 | ||
|
|
2d6987341c | ||
|
|
257158fd95 | ||
|
|
f9a967caf7 | ||
|
|
cf22ed57a2 | ||
|
|
b6772ac2ea | ||
|
|
f0025dbc47 | ||
|
|
2a347942bc | ||
|
|
36da65e15b | ||
|
|
214ff3eff0 | ||
|
|
8c0d52d0fe | ||
|
|
793bba95b5 | ||
|
|
2d4a65c654 | ||
|
|
872f178d94 | ||
|
|
70d6094f46 | ||
|
|
31289436f5 | ||
|
|
5e7792c11f | ||
|
|
e73064a438 | ||
|
|
72787c0652 | ||
|
|
c88170f6e0 | ||
|
|
a65ecb157d | ||
|
|
eb8a3c0e09 | ||
|
|
572fade7ff | ||
|
|
b5885ae35f | ||
|
|
335bc01185 | ||
|
|
c87563a520 | ||
|
|
e4aafca7c3 | ||
|
|
fe05d45cde | ||
|
|
b3861decc3 | ||
|
|
b3f59acf7e | ||
|
|
4f8e35e409 | ||
|
|
b898949ffc | ||
|
|
2244764777 | ||
|
|
e4c8a36577 | ||
|
|
41eb45402e | ||
|
|
33ed95bd8e | ||
|
|
4985b2d1f4 | ||
|
|
68a2250886 | ||
|
|
8575939b20 | ||
|
|
634a1c5f6a | ||
|
|
c364e30240 | ||
|
|
3595c3a440 | ||
|
|
c3dd65457d | ||
|
|
3aa909b917 | ||
|
|
35d8d2ab2d | ||
|
|
e3ebaeb2c8 | ||
|
|
71dc332dae | ||
|
|
211a3c2358 | ||
|
|
16b9d4fd8b | ||
|
|
c0f304559f | ||
|
|
8d325184ad | ||
|
|
0df93eaa98 | ||
|
|
aae18fd035 | ||
|
|
fd8552ca3a | ||
|
|
452457412b | ||
|
|
521df1f4b7 | ||
|
|
0ae2f935af | ||
|
|
3282a3ae34 | ||
|
|
cb612c36ea | ||
|
|
14aad62e02 | ||
|
|
847d7ab38d | ||
|
|
99ef9166ae | ||
|
|
0305830e32 | ||
|
|
9f342dff49 | ||
|
|
02766d82eb | ||
|
|
3e372faf5e | ||
|
|
786b4ea8c0 | ||
|
|
20ff0ed30b | ||
|
|
2a490a1bbc | ||
|
|
89391e5be1 | ||
|
|
c3cb41f78a | ||
|
|
c3a0266354 | ||
|
|
55a5c97034 | ||
|
|
dcb8a3f3fb | ||
|
|
3dffe564af | ||
|
|
1820972fb7 | ||
|
|
67534faa78 | ||
|
|
12605843ce | ||
|
|
8dbdebff3f | ||
|
|
61845b8761 | ||
|
|
1ba44c99d1 | ||
|
|
6716ab251f | ||
|
|
e3b9c0140a | ||
|
|
d1c0723b44 | ||
|
|
14ed6af433 | ||
|
|
1325706c7c | ||
|
|
f5ab00a055 | ||
|
|
dcdfc30c45 | ||
|
|
a0d165c79b | ||
|
|
7b23310d8b | ||
|
|
e477dea5c7 | ||
|
|
dccb136c99 | ||
|
|
6af29a7181 | ||
| 7ca3a19eed | |||
| 7fcb4efab6 | |||
| a8024d3dd3 | |||
| 8bb78c95a8 | |||
| 19cbf1ca67 | |||
|
|
e70eb5a926 | ||
| 7bdde2d359 | |||
|
|
3daa07e311 | ||
|
|
47fab631d0 | ||
| 2e3d7b1656 | |||
| bf600a7608 | |||
| 6b00805d04 | |||
| 82b7082fc5 | |||
| 8bb9e22218 | |||
| 2ad90dcb5c | |||
| 97ea77bd27 | |||
| 1904e240cf | |||
| 4ccaa2dfea | |||
| da38006f44 | |||
| 87b0a93d32 | |||
| ff78c951f0 | |||
| 2d44e8112b | |||
| f7f8bb3f45 | |||
| 67ebc58812 | |||
| 13aee1755e | |||
| 0e0975e5f6 | |||
| d4283731e4 | |||
| 6780ab1b67 | |||
| 41eac2764a | |||
| 113d14c440 | |||
| abe523be77 | |||
| 1b392a0551 | |||
| deb2fa0a09 | |||
| 671a0ce0fb | |||
| ac67111b83 | |||
| 09575370ce | |||
| 9aa08a70cf | |||
| ca7f78565d | |||
| dcb4d1823f | |||
| e8564c755b | |||
| 9dee5e4138 | |||
| 245f260d67 | |||
| 5f27727e52 | |||
| 1238608430 | |||
| 71cd7af17b | |||
| 8490472581 | |||
| 8534d8d3c5 | |||
| 53d260cc6e | |||
| 53a4682418 | |||
| 42455873ff | |||
| 724b846ee4 | |||
| f27b133089 | |||
| 773617cbf3 | |||
| 44e29b3c4a | |||
| 95a35cd0bf | |||
| 28b800a497 | |||
| 838776d7df | |||
| e19fa377d7 | |||
| d63a30728c | |||
| 4819920b4e | |||
| bbb9aae198 | |||
| 0d94776c46 | |||
| 565a5ee960 | |||
| e7f9d8f1d7 | |||
| 55bc49598e | |||
| 579eaaf4a0 | |||
| b98334db28 | |||
| e1b1b5d357 | |||
| cf582c4ce4 | |||
| 911b4c0b10 | |||
| 94c1f0d3fc | |||
| 73221dfe34 | |||
| 4ffd4949ca | |||
| 3f137805bc | |||
| 6a00057817 | |||
| 58bc5acb1e | |||
| d3e9d92466 | |||
| ae3290c53d | |||
| 4cf222a5bb | |||
| c3abe035c8 | |||
| ef5c333030 | |||
| f4cbb9498f | |||
| 794c86f9b4 | |||
|
|
8687fe3786 | ||
|
|
0a28d2db07 | ||
|
|
6c468a134b | ||
|
|
9b67f87062 | ||
|
|
b4adc29d7f | ||
|
|
a10aca573d | ||
|
|
ea1224e213 | ||
|
|
64ad65fa1b | ||
|
|
b881b2639d | ||
|
|
a5f72edf82 | ||
|
|
ea2a3e6f16 | ||
|
|
2125f043b6 | ||
|
|
655b5c88d4 | ||
|
|
88b090fe94 | ||
|
|
c6c3a556b3 | ||
|
|
67b5f33d46 | ||
|
|
b675dfd014 | ||
|
|
fc2b884af9 | ||
|
|
cbd19fa070 | ||
|
|
83b330bf2b | ||
|
|
cc9cde9bfe | ||
|
|
774f6fc334 | ||
|
|
bfd13e7a9b | ||
|
|
35b1d37df0 | ||
|
|
fc3d919f25 | ||
|
|
75641a4394 | ||
|
|
ce0bcbd3b6 | ||
|
|
3194b460cc | ||
|
|
e1d148a34d | ||
|
|
b491a09686 | ||
|
|
6a538ad4f3 | ||
|
|
6ccc172f33 | ||
|
|
66ca3a3f9b | ||
|
|
4f4a35a7be | ||
|
|
c9722a07f3 | ||
|
|
42dfa6ccfe | ||
|
|
2adef874ee | ||
|
|
a6e4995963 | ||
|
|
2bd91c2d94 | ||
|
|
c713f4ff6f | ||
|
|
21b0b08908 | ||
|
|
88ace0a99f | ||
|
|
10c8f6e4b5 | ||
|
|
9aa749e877 | ||
|
|
f78a99927a | ||
|
|
ec794f4f99 | ||
|
|
884182217c | ||
|
|
d94907ae79 | ||
|
|
4accfd136e | ||
|
|
1a223d6ef5 | ||
|
|
36b3ad8154 | ||
|
|
460973954e | ||
|
|
303a78065e | ||
|
|
93f0b70eba | ||
|
|
6f5a2a3d3f | ||
|
|
ec563ea8e4 | ||
|
|
570638bba6 | ||
|
|
f627ea7de0 | ||
|
|
521c132801 | ||
|
|
bc5115b9ea | ||
|
|
6963304c01 | ||
|
|
ae651a4fcd | ||
|
|
17c2fe6e4e | ||
|
|
f066ac3ffd | ||
|
|
edcf633e84 | ||
|
|
d09a454b8b | ||
|
|
d6329ea9bf | ||
|
|
83897048ab | ||
|
|
7cc59770b8 | ||
|
|
b056d95920 | ||
|
|
19cd01ef8d | ||
|
|
b3f88bbe02 | ||
|
|
f57f38edbd | ||
|
|
12377ae730 | ||
|
|
bb93dcef44 | ||
|
|
678a12dc90 | ||
|
|
c3dacb2906 | ||
|
|
3a68ec439d | ||
|
|
7ce418aabc | ||
|
|
8ee5091f41 | ||
|
|
6285517ef7 | ||
|
|
2b0cd6f2f2 | ||
|
|
a653c55941 | ||
|
|
ce035d2a43 | ||
|
|
2d54eb5143 | ||
|
|
b9c8edb657 | ||
|
|
88315c25a5 | ||
|
|
806bfd1fbf | ||
|
|
910b5116f4 | ||
|
|
6302e8b73a | ||
|
|
fd1adc0262 | ||
|
|
070be0b005 | ||
|
|
5034ffbe59 | ||
|
|
cd13b88540 | ||
|
|
e050d6f151 | ||
|
|
863555ec6b | ||
|
|
c605793a9d | ||
|
|
8375870af6 | ||
|
|
11a53e792f | ||
|
|
ca2362f858 | ||
|
|
5cdbedd4d1 | ||
|
|
ee6d69bcd2 | ||
|
|
f9193b4602 | ||
|
|
979e5f036e | ||
|
|
39baec852b | ||
|
|
ed3f9410a6 | ||
|
|
b18243f098 | ||
|
|
9472dab522 | ||
|
|
9067f8d298 | ||
|
|
866073ae8a | ||
|
|
91cb00fde2 | ||
|
|
c435bcfb67 | ||
|
|
7fe1b7d1f5 | ||
|
|
39524b2b9f | ||
|
|
c592f5f537 | ||
|
|
94c491d286 | ||
|
|
645938a194 | ||
|
|
73756820bd | ||
|
|
33374ab257 | ||
|
|
bf8286d15f | ||
|
|
6410c898c5 | ||
|
|
be007c6278 | ||
|
|
f7558e3d18 | ||
|
|
97e8f2c69a | ||
|
|
49bdf47514 | ||
|
|
81162f30dc | ||
|
|
4379256c11 | ||
|
|
870ca1db45 | ||
|
|
74a5c301f8 | ||
|
|
2955e6c9c1 | ||
|
|
cd2ccb4e06 | ||
|
|
722ee4c52c | ||
|
|
67b9f45004 | ||
|
|
2035fffa1c | ||
|
|
97ac3c09fa | ||
|
|
241e1dacb0 | ||
|
|
ac19d3f532 | ||
|
|
194527e0fe | ||
|
|
28cf5562ac | ||
|
|
8cdc39fdee | ||
|
|
626eec4a31 | ||
|
|
5901237fee | ||
|
|
24316ca0c4 | ||
|
|
f9d964cccb | ||
|
|
a9ac30b991 | ||
|
|
61df9cf32c | ||
|
|
bbd31929ba | ||
|
|
ec20e9f3d9 | ||
|
|
3bcd83f5a3 | ||
|
|
341ba5146a | ||
|
|
83b37ef536 | ||
|
|
1965197ccd | ||
|
|
29747f4891 | ||
|
|
aca442ee87 | ||
|
|
8e85ae5318 | ||
|
|
8c32471e0d | ||
|
|
79711be46a | ||
|
|
863e5bda15 | ||
|
|
d19cedb12a | ||
|
|
f2d39f7df8 | ||
|
|
579f6f64e6 | ||
|
|
a71af1be96 | ||
|
|
237c242f96 | ||
|
|
c4dc52c06c | ||
|
|
e1d8dd3124 | ||
|
|
38a1197d9e | ||
|
|
bc01a37452 | ||
|
|
acdca19f59 | ||
|
|
a1fe745a53 | ||
|
|
73df20d195 | ||
|
|
7e1933d79b | ||
|
|
8d23fac6cc | ||
|
|
0f8efdb55e | ||
|
|
523d0b3b8c | ||
|
|
591ca7c83c | ||
|
|
dffdcc095d | ||
|
|
229c1e4965 | ||
|
|
d8399e3c07 | ||
|
|
f1bb3556eb | ||
|
|
cef0a71bce | ||
|
|
a9d72b8102 | ||
|
|
d469482a7f | ||
|
|
c67c1bd6a2 | ||
|
|
5e6769036c | ||
|
|
482b9f50fc | ||
|
|
f4e7eaeb40 | ||
|
|
8c2ff33c40 | ||
|
|
1308864061 | ||
|
|
62c559043d | ||
|
|
c2f85ce61b | ||
|
|
5808599005 | ||
|
|
fafe582802 | ||
|
|
593cda3ee8 | ||
|
|
d5c44645eb | ||
|
|
e7a509176d | ||
|
|
3a39d9440a | ||
|
|
cabfec3f1e | ||
|
|
956efabd8f | ||
|
|
f146a96298 | ||
|
|
585abe9a18 | ||
|
|
3d0b262435 | ||
|
|
3f264b4490 | ||
|
|
1758ee4215 | ||
|
|
dc40c2f6ad | ||
|
|
2fb92e8592 | ||
|
|
57829e1b79 | ||
|
|
bc26d7d01d | ||
|
|
b93519e06f | ||
|
|
5d861d243a | ||
|
|
f1b84ab370 | ||
|
|
d5b8902d8f | ||
|
|
799fbbdd10 | ||
|
|
d33f1bc6f2 | ||
|
|
28a90e550e | ||
|
|
647801f096 | ||
|
|
1664566bd2 | ||
|
|
cd09c17d71 | ||
|
|
f74f3f03d1 | ||
|
|
23006b2b43 | ||
|
|
7f69a6c9b1 | ||
|
|
1726d10554 | ||
|
|
757bc21550 | ||
|
|
e187679f93 | ||
|
|
2597e2002b | ||
|
|
e6f819ed90 | ||
|
|
0c8bcb2400 | ||
|
|
c5761cc51e | ||
|
|
24ccf65aba | ||
|
|
814d6f1de6 | ||
|
|
bfaab294e6 | ||
|
|
0ddcf668cb | ||
|
|
4005e9e791 | ||
|
|
abaa007c54 | ||
|
|
87d80f84c2 | ||
|
|
3fdf246a22 | ||
|
|
79b95d0045 | ||
|
|
1e66e5cd82 | ||
|
|
193d9939f0 | ||
|
|
81fc559802 | ||
|
|
0d75cc999c | ||
|
|
a5da56d02f | ||
|
|
a7e20fd390 | ||
|
|
9f38e7e5f5 | ||
|
|
93e60cc136 | ||
|
|
5f7ec50055 | ||
|
|
ff0019841f | ||
|
|
7eeeced2ca | ||
|
|
0fc369789e | ||
|
|
09f72f5ac6 | ||
|
|
716109bab5 | ||
|
|
0684fcf7e9 | ||
|
|
289104cde0 | ||
|
|
c9277e4b12 | ||
|
|
08125fc2a5 | ||
|
|
d06dd2ef43 | ||
|
|
8ae3eea19c | ||
|
|
a1bc76f305 | ||
|
|
045bede481 | ||
|
|
0a231f2e0e | ||
|
|
87e7c5f00a | ||
|
|
7ded9fe219 | ||
|
|
b389e75d33 | ||
|
|
9128bfc5f1 | ||
|
|
bb227d2c37 | ||
|
|
954da93301 | ||
|
|
1dce0f265d | ||
|
|
0f54630725 | ||
|
|
712cd69242 | ||
|
|
ff3bd640f0 | ||
|
|
abb347e1a8 | ||
|
|
949c9c0b8c | ||
|
|
627a9f7972 | ||
|
|
cce892e92f | ||
|
|
97fb8ef653 | ||
|
|
649d6169c9 | ||
|
|
9efb97c2a7 | ||
|
|
d876aa141c | ||
|
|
f64efad057 | ||
|
|
20edb87505 | ||
|
|
34156c55ae | ||
|
|
569bc243f1 | ||
|
|
bc6a42735c | ||
|
|
b2f2a9c721 | ||
|
|
8a00b9c77d | ||
|
|
d7506b6aaf | ||
|
|
3a86e89116 | ||
|
|
0e71bdab65 | ||
|
|
0c553b3406 | ||
|
|
33012f35ef | ||
|
|
a6b915f6b4 | ||
|
|
772c981c39 | ||
|
|
05905f8c3c | ||
|
|
9542bd8a44 | ||
|
|
d9fe457b44 | ||
|
|
59700b07db | ||
|
|
428e4563d0 | ||
|
|
6c3bbaa686 | ||
|
|
7009bb6d05 | ||
|
|
23a5692d59 | ||
|
|
2d4e7cfdee | ||
|
|
99222d8ab9 | ||
|
|
a845fee689 | ||
|
|
cfecf4f1d4 | ||
|
|
b3e49590a7 | ||
|
|
358837ed69 | ||
|
|
2a353830c2 | ||
|
|
14f51436d7 | ||
|
|
57e5465c2d | ||
|
|
d9619e65a2 | ||
|
|
9754994e0c | ||
|
|
34c894b15d | ||
|
|
a2665d9247 | ||
|
|
1e3ae67646 | ||
|
|
25b9625635 | ||
|
|
2404b22c1f | ||
|
|
bed882f41c | ||
|
|
fd9e0944cb | ||
|
|
7e462319c9 | ||
|
|
94de87ef86 | ||
|
|
eb13f1f4fb | ||
|
|
0a6c39ded4 | ||
|
|
ff1aac64c1 | ||
|
|
ef24894211 | ||
|
|
1113164505 | ||
|
|
1de73de2e3 | ||
|
|
571cc5a1da | ||
|
|
8cb0803605 | ||
|
|
95d52b87f4 | ||
|
|
07fd3abe2c | ||
|
|
5dedd2e0e0 | ||
|
|
57abb03deb | ||
|
|
4a38a74b16 |
@@ -1,21 +0,0 @@
|
|||||||
---
|
|
||||||
Language: Cpp
|
|
||||||
BasedOnStyle: LLVM
|
|
||||||
|
|
||||||
ColumnLimit: 100
|
|
||||||
IndentWidth: 4
|
|
||||||
TabWidth: 4
|
|
||||||
UseTab: Always
|
|
||||||
|
|
||||||
AccessModifierOffset: -4
|
|
||||||
|
|
||||||
AlignEscapedNewlinesLeft: true
|
|
||||||
|
|
||||||
AllowShortIfStatementsOnASingleLine: true
|
|
||||||
AllowShortLoopsOnASingleLine: true
|
|
||||||
|
|
||||||
AlwaysBreakAfterReturnType: AllDefinitions
|
|
||||||
AlwaysBreakBeforeMultilineStrings: true
|
|
||||||
AlwaysBreakTemplateDeclarations: true
|
|
||||||
|
|
||||||
BreakBeforeBraces: Linux
|
|
||||||
11
.git-commit-template
Normal file
11
.git-commit-template
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
[section] Imperative-voiced title in less than 50
|
||||||
|
|
||||||
|
# Body describes what was done, and why. New obviously-needed features
|
||||||
|
# don't necessarily require a why.
|
||||||
|
|
||||||
|
# Links to relevant bugs or web pages
|
||||||
|
See: Github bug #242
|
||||||
|
See: [frobozz blog post](https://jsix.dev/posts/frobozz/)
|
||||||
|
|
||||||
|
# Tags and keywords useful for searching
|
||||||
|
Tags:
|
||||||
15
.gitignore
vendored
15
.gitignore
vendored
@@ -1,6 +1,15 @@
|
|||||||
|
.cache
|
||||||
.lock*
|
.lock*
|
||||||
build
|
/build*
|
||||||
*.bak
|
*.bak
|
||||||
tags
|
tags
|
||||||
.gdbinit
|
jsix.log
|
||||||
popcorn.log
|
*.out
|
||||||
|
*.o
|
||||||
|
*.a
|
||||||
|
sysroot
|
||||||
|
.gdb_history
|
||||||
|
.peru
|
||||||
|
__pycache__
|
||||||
|
/venv
|
||||||
|
compile_commands.json
|
||||||
|
|||||||
3
.gitmodules
vendored
3
.gitmodules
vendored
@@ -1,3 +0,0 @@
|
|||||||
[submodule "external/gnu-efi"]
|
|
||||||
path = external/gnu-efi
|
|
||||||
url = https://github.com/justinian/gnu-efi.git
|
|
||||||
|
|||||||
354
LICENSE.md
Normal file
354
LICENSE.md
Normal file
@@ -0,0 +1,354 @@
|
|||||||
|
# License
|
||||||
|
|
||||||
|
jsix is (c) 2017-2019 Justin C Miller, and distributed under the terms of the
|
||||||
|
Mozilla Public License 2.0.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Mozilla Public License Version 2.0
|
||||||
|
|
||||||
|
### 1. Definitions
|
||||||
|
|
||||||
|
#### 1.1. "Contributor"
|
||||||
|
|
||||||
|
means each individual or legal entity that creates, contributes to the creation
|
||||||
|
of, or owns Covered Software.
|
||||||
|
|
||||||
|
#### 1.2. "Contributor Version"
|
||||||
|
|
||||||
|
means the combination of the Contributions of others (if any) used by a
|
||||||
|
Contributor and that particular Contributor's Contribution.
|
||||||
|
|
||||||
|
#### 1.3. "Contribution
|
||||||
|
|
||||||
|
means Covered Software of a particular Contributor.
|
||||||
|
|
||||||
|
#### 1.4. "Covered Software"
|
||||||
|
|
||||||
|
means Source Code Form to which the initial Contributor has attached the notice
|
||||||
|
in Exhibit A, the Executable Form of such Source Code Form, and Modifications
|
||||||
|
of such Source Code Form, in each case including portions thereof.
|
||||||
|
|
||||||
|
#### 1.5. "Incompatible With Secondary Licenses"
|
||||||
|
|
||||||
|
means
|
||||||
|
|
||||||
|
* **(a)** that the initial Contributor has attached the notice described in
|
||||||
|
Exhibit B to the Covered Software; or
|
||||||
|
* **(b)** that the Covered Software was made available under the terms of
|
||||||
|
version 1.1 or earlier of the License, but not also under the terms of a
|
||||||
|
Secondary License.
|
||||||
|
|
||||||
|
#### 1.6. "Executable Form"
|
||||||
|
|
||||||
|
means any form of the work other than Source Code Form.
|
||||||
|
|
||||||
|
#### 1.7. "Larger Work"
|
||||||
|
|
||||||
|
means a work that combines Covered Software with other material, in a separate
|
||||||
|
file or files, that is not Covered Software.
|
||||||
|
|
||||||
|
#### 1.8. "License"
|
||||||
|
|
||||||
|
means this document.
|
||||||
|
|
||||||
|
#### 1.9. "Licensable"
|
||||||
|
|
||||||
|
means having the right to grant, to the maximum extent possible, whether at the
|
||||||
|
time of the initial grant or subsequently, any and all of the rights conveyed
|
||||||
|
by this License.
|
||||||
|
|
||||||
|
#### 1.10. "Modifications"
|
||||||
|
|
||||||
|
means any of the following:
|
||||||
|
|
||||||
|
* **(a)** any file in Source Code Form that results from an addition to,
|
||||||
|
deletion from, or modification of the contents of Covered Software; or
|
||||||
|
* **(b)** any new file in Source Code Form that contains any Covered Software.
|
||||||
|
|
||||||
|
#### 1.11. "Patent Claims" of a Contributor
|
||||||
|
|
||||||
|
means any patent claim(s), including without limitation, method, process, and
|
||||||
|
apparatus claims, in any patent Licensable by such Contributor that would be
|
||||||
|
infringed, but for the grant of the License, by the making, using, selling,
|
||||||
|
offering for sale, having made, import, or transfer of either its Contributions
|
||||||
|
or its Contributor Version.
|
||||||
|
|
||||||
|
#### 1.12. "Secondary License"
|
||||||
|
|
||||||
|
means either the GNU General Public License, Version 2.0, the GNU Lesser
|
||||||
|
General Public License, Version 2.1, the GNU Affero General Public License,
|
||||||
|
Version 3.0, or any later versions of those licenses.
|
||||||
|
|
||||||
|
#### 1.13. "Source Code Form"
|
||||||
|
|
||||||
|
means the form of the work preferred for making modifications.
|
||||||
|
|
||||||
|
#### 1.14. "You" (or "Your")
|
||||||
|
|
||||||
|
means an individual or a legal entity exercising rights under this License. For
|
||||||
|
legal entities, "You" includes any entity that controls, is controlled by, or
|
||||||
|
is under common control with You. For purposes of this definition, "control"
|
||||||
|
means **(a)** the power, direct or indirect, to cause the direction or
|
||||||
|
management of such entity, whether by contract or otherwise, or **(b)**
|
||||||
|
ownership of more than fifty percent (50%) of the outstanding shares or
|
||||||
|
beneficial ownership of such entity.
|
||||||
|
|
||||||
|
|
||||||
|
### 2. License Grants and Conditions
|
||||||
|
|
||||||
|
#### 2.1. Grants
|
||||||
|
|
||||||
|
Each Contributor hereby grants You a world-wide, royalty-free, non-exclusive
|
||||||
|
license:
|
||||||
|
|
||||||
|
* **(a)** under intellectual property rights (other than patent or trademark)
|
||||||
|
Licensable by such Contributor to use, reproduce, make available, modify,
|
||||||
|
display, perform, distribute, and otherwise exploit its Contributions, either
|
||||||
|
on an unmodified basis, with Modifications, or as part of a Larger Work; and
|
||||||
|
* **(b)** under Patent Claims of such Contributor to make, use, sell, offer for
|
||||||
|
sale, have made, import, and otherwise transfer either its Contributions or
|
||||||
|
its Contributor Version.
|
||||||
|
|
||||||
|
#### 2.2. Effective Date
|
||||||
|
|
||||||
|
The licenses granted in Section 2.1 with respect to any Contribution become
|
||||||
|
effective for each Contribution on the date the Contributor first distributes
|
||||||
|
such Contribution.
|
||||||
|
|
||||||
|
#### 2.3. Limitations on Grant Scope
|
||||||
|
|
||||||
|
The licenses granted in this Section 2 are the only rights granted under this
|
||||||
|
License. No additional rights or licenses will be implied from the distribution
|
||||||
|
or licensing of Covered Software under this License. Notwithstanding Section
|
||||||
|
2.1(b) above, no patent license is granted by a Contributor:
|
||||||
|
|
||||||
|
* **(a)** for any code that a Contributor has removed from Covered Software; or
|
||||||
|
* **(b)** for infringements caused by: **(i)** Your and any other third party's
|
||||||
|
modifications of Covered Software, or **(ii)** the combination of its
|
||||||
|
Contributions with other software (except as part of its Contributor
|
||||||
|
Version); or
|
||||||
|
* **(c)** under Patent Claims infringed by Covered Software in the absence of
|
||||||
|
its Contributions.
|
||||||
|
|
||||||
|
This License does not grant any rights in the trademarks, service marks, or
|
||||||
|
logos of any Contributor (except as may be necessary to comply with the notice
|
||||||
|
requirements in Section 3.4).
|
||||||
|
|
||||||
|
#### 2.4. Subsequent Licenses
|
||||||
|
|
||||||
|
No Contributor makes additional grants as a result of Your choice to distribute
|
||||||
|
the Covered Software under a subsequent version of this License (see Section
|
||||||
|
10.2) or under the terms of a Secondary License (if permitted under the terms
|
||||||
|
of Section 3.3).
|
||||||
|
|
||||||
|
#### 2.5. Representation
|
||||||
|
|
||||||
|
Each Contributor represents that the Contributor believes its Contributions are
|
||||||
|
its original creation(s) or it has sufficient rights to grant the rights to its
|
||||||
|
Contributions conveyed by this License.
|
||||||
|
|
||||||
|
#### 2.6. Fair Use
|
||||||
|
|
||||||
|
This License is not intended to limit any rights You have under applicable
|
||||||
|
copyright doctrines of fair use, fair dealing, or other equivalents.
|
||||||
|
|
||||||
|
#### 2.7. Conditions
|
||||||
|
|
||||||
|
Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in
|
||||||
|
Section 2.1.
|
||||||
|
|
||||||
|
|
||||||
|
### 3. Responsibilities
|
||||||
|
|
||||||
|
#### 3.1. Distribution of Source Form
|
||||||
|
|
||||||
|
All distribution of Covered Software in Source Code Form, including any
|
||||||
|
Modifications that You create or to which You contribute, must be under the
|
||||||
|
terms of this License. You must inform recipients that the Source Code Form of
|
||||||
|
the Covered Software is governed by the terms of this License, and how they can
|
||||||
|
obtain a copy of this License. You may not attempt to alter or restrict the
|
||||||
|
recipients' rights in the Source Code Form.
|
||||||
|
|
||||||
|
#### 3.2. Distribution of Executable Form
|
||||||
|
|
||||||
|
If You distribute Covered Software in Executable Form then:
|
||||||
|
|
||||||
|
* **(a)** such Covered Software must also be made available in Source Code
|
||||||
|
Form, as described in Section 3.1, and You must inform recipients of the
|
||||||
|
Executable Form how they can obtain a copy of such Source Code Form by
|
||||||
|
reasonable means in a timely manner, at a charge no more than the cost of
|
||||||
|
distribution to the recipient; and
|
||||||
|
* **(b)** You may distribute such Executable Form under the terms of this
|
||||||
|
License, or sublicense it under different terms, provided that the license
|
||||||
|
for the Executable Form does not attempt to limit or alter the recipients'
|
||||||
|
rights in the Source Code Form under this License.
|
||||||
|
|
||||||
|
#### 3.3. Distribution of a Larger Work
|
||||||
|
|
||||||
|
You may create and distribute a Larger Work under terms of Your choice,
|
||||||
|
provided that You also comply with the requirements of this License for the
|
||||||
|
Covered Software. If the Larger Work is a combination of Covered Software with
|
||||||
|
a work governed by one or more Secondary Licenses, and the Covered Software is
|
||||||
|
not Incompatible With Secondary Licenses, this License permits You to
|
||||||
|
additionally distribute such Covered Software under the terms of such Secondary
|
||||||
|
License(s), so that the recipient of the Larger Work may, at their option,
|
||||||
|
further distribute the Covered Software under the terms of either this License
|
||||||
|
or such Secondary License(s).
|
||||||
|
|
||||||
|
#### 3.4. Notices
|
||||||
|
|
||||||
|
You may not remove or alter the substance of any license notices (including
|
||||||
|
copyright notices, patent notices, disclaimers of warranty, or limitations of
|
||||||
|
liability) contained within the Source Code Form of the Covered Software,
|
||||||
|
except that You may alter any license notices to the extent required to remedy
|
||||||
|
known factual inaccuracies.
|
||||||
|
|
||||||
|
#### 3.5. Application of Additional Terms
|
||||||
|
|
||||||
|
You may choose to offer, and to charge a fee for, warranty, support, indemnity
|
||||||
|
or liability obligations to one or more recipients of Covered Software.
|
||||||
|
However, You may do so only on Your own behalf, and not on behalf of any
|
||||||
|
Contributor. You must make it absolutely clear that any such warranty, support,
|
||||||
|
indemnity, or liability obligation is offered by You alone, and You hereby
|
||||||
|
agree to indemnify every Contributor for any liability incurred by such
|
||||||
|
Contributor as a result of warranty, support, indemnity or liability terms You
|
||||||
|
offer. You may include additional disclaimers of warranty and limitations of
|
||||||
|
liability specific to any jurisdiction.
|
||||||
|
|
||||||
|
|
||||||
|
### 4. Inability to Comply Due to Statute or Regulation
|
||||||
|
|
||||||
|
If it is impossible for You to comply with any of the terms of this License
|
||||||
|
with respect to some or all of the Covered Software due to statute, judicial
|
||||||
|
order, or regulation then You must: **(a)** comply with the terms of this
|
||||||
|
License to the maximum extent possible; and **(b)** describe the limitations
|
||||||
|
and the code they affect. Such description must be placed in a text file
|
||||||
|
included with all distributions of the Covered Software under this License.
|
||||||
|
Except to the extent prohibited by statute or regulation, such description must
|
||||||
|
be sufficiently detailed for a recipient of ordinary skill to be able to
|
||||||
|
understand it.
|
||||||
|
|
||||||
|
|
||||||
|
### 5. Termination
|
||||||
|
|
||||||
|
**5.1.** The rights granted under this License will terminate automatically if
|
||||||
|
You fail to comply with any of its terms. However, if You become compliant,
|
||||||
|
then the rights granted under this License from a particular Contributor are
|
||||||
|
reinstated **(a)** provisionally, unless and until such Contributor explicitly
|
||||||
|
and finally terminates Your grants, and **(b)** on an ongoing basis, if such
|
||||||
|
Contributor fails to notify You of the non-compliance by some reasonable means
|
||||||
|
prior to 60 days after You have come back into compliance. Moreover, Your
|
||||||
|
grants from a particular Contributor are reinstated on an ongoing basis if such
|
||||||
|
Contributor notifies You of the non-compliance by some reasonable means, this
|
||||||
|
is the first time You have received notice of non-compliance with this License
|
||||||
|
from such Contributor, and You become compliant prior to 30 days after Your
|
||||||
|
receipt of the notice.
|
||||||
|
|
||||||
|
**5.2.** If You initiate litigation against any entity by asserting a patent
|
||||||
|
infringement claim (excluding declaratory judgment actions, counter-claims, and
|
||||||
|
cross-claims) alleging that a Contributor Version directly or indirectly
|
||||||
|
infringes any patent, then the rights granted to You by any and all
|
||||||
|
Contributors for the Covered Software under Section 2.1 of this License shall
|
||||||
|
terminate.
|
||||||
|
|
||||||
|
**5.3.** In the event of termination under Sections 5.1 or 5.2 above, all end
|
||||||
|
user license agreements (excluding distributors and resellers) which have been
|
||||||
|
validly granted by You or Your distributors under this License prior to
|
||||||
|
termination shall survive termination.
|
||||||
|
|
||||||
|
|
||||||
|
### 6. Disclaimer of Warranty
|
||||||
|
|
||||||
|
> Covered Software is provided under this License on an "as is" basis, without
|
||||||
|
> warranty of any kind, either expressed, implied, or statutory, including,
|
||||||
|
> without limitation, warranties that the Covered Software is free of defects,
|
||||||
|
> merchantable, fit for a particular purpose or non-infringing. The entire risk
|
||||||
|
> as to the quality and performance of the Covered Software is with You.
|
||||||
|
> Should any Covered Software prove defective in any respect, You (not any
|
||||||
|
> Contributor) assume the cost of any necessary servicing, repair, or
|
||||||
|
> correction. This disclaimer of warranty constitutes an essential part of this
|
||||||
|
> License. No use of any Covered Software is authorized under this License
|
||||||
|
> except under this disclaimer.
|
||||||
|
|
||||||
|
### 7. Limitation of Liability
|
||||||
|
|
||||||
|
> Under no circumstances and under no legal theory, whether tort (including
|
||||||
|
> negligence), contract, or otherwise, shall any Contributor, or anyone who
|
||||||
|
> distributes Covered Software as permitted above, be liable to You for any
|
||||||
|
> direct, indirect, special, incidental, or consequential damages of any
|
||||||
|
> character including, without limitation, damages for lost profits, loss of
|
||||||
|
> goodwill, work stoppage, computer failure or malfunction, or any and all
|
||||||
|
> other commercial damages or losses, even if such party shall have been
|
||||||
|
> informed of the possibility of such damages. This limitation of liability
|
||||||
|
> shall not apply to liability for death or personal injury resulting from such
|
||||||
|
> party's negligence to the extent applicable law prohibits such limitation.
|
||||||
|
> Some jurisdictions do not allow the exclusion or limitation of incidental or
|
||||||
|
> consequential damages, so this exclusion and limitation may not apply to You.
|
||||||
|
|
||||||
|
|
||||||
|
### 8. Litigation
|
||||||
|
|
||||||
|
Any litigation relating to this License may be brought only in the courts of a
|
||||||
|
jurisdiction where the defendant maintains its principal place of business and
|
||||||
|
such litigation shall be governed by laws of that jurisdiction, without
|
||||||
|
reference to its conflict-of-law provisions. Nothing in this Section shall
|
||||||
|
prevent a party's ability to bring cross-claims or counter-claims.
|
||||||
|
|
||||||
|
|
||||||
|
### 9. Miscellaneous
|
||||||
|
|
||||||
|
This License represents the complete agreement concerning the subject matter
|
||||||
|
hereof. If any provision of this License is held to be unenforceable, such
|
||||||
|
provision shall be reformed only to the extent necessary to make it
|
||||||
|
enforceable. Any law or regulation which provides that the language of a
|
||||||
|
contract shall be construed against the drafter shall not be used to construe
|
||||||
|
this License against a Contributor.
|
||||||
|
|
||||||
|
|
||||||
|
### 10. Versions of the License
|
||||||
|
|
||||||
|
#### 10.1. New Versions
|
||||||
|
|
||||||
|
Mozilla Foundation is the license steward. Except as provided in Section 10.3,
|
||||||
|
no one other than the license steward has the right to modify or publish new
|
||||||
|
versions of this License. Each version will be given a distinguishing version
|
||||||
|
number.
|
||||||
|
|
||||||
|
#### 10.2. Effect of New Versions
|
||||||
|
|
||||||
|
You may distribute the Covered Software under the terms of the version of the
|
||||||
|
License under which You originally received the Covered Software, or under the
|
||||||
|
terms of any subsequent version published by the license steward.
|
||||||
|
|
||||||
|
#### 10.3. Modified Versions
|
||||||
|
|
||||||
|
If you create software not governed by this License, and you want to create a
|
||||||
|
new license for such software, you may create and use a modified version of
|
||||||
|
this License if you rename the license and remove any references to the name of
|
||||||
|
the license steward (except to note that such modified license differs from
|
||||||
|
this License).
|
||||||
|
|
||||||
|
#### 10.4. Distributing Source Code Form that is Incompatible With Secondary Licenses
|
||||||
|
|
||||||
|
If You choose to distribute Source Code Form that is Incompatible With
|
||||||
|
Secondary Licenses under the terms of this version of the License, the notice
|
||||||
|
described in Exhibit B of this License must be attached.
|
||||||
|
|
||||||
|
### Exhibit A - Source Code Form License Notice
|
||||||
|
|
||||||
|
This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||||
|
You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
|
||||||
|
If it is not possible or desirable to put the notice in a particular file, then
|
||||||
|
You may include the notice in a location (such as a LICENSE file in a relevant
|
||||||
|
directory) where a recipient would be likely to look for such a notice.
|
||||||
|
|
||||||
|
You may add additional accurate notices of copyright ownership.
|
||||||
|
|
||||||
|
### Exhibit B - "Incompatible With Secondary Licenses" Notice
|
||||||
|
|
||||||
|
This Source Code Form is "Incompatible With Secondary Licenses", as defined
|
||||||
|
by the Mozilla Public License, v. 2.0.
|
||||||
|
|
||||||
241
Makefile
241
Makefile
@@ -1,241 +0,0 @@
|
|||||||
ARCH ?= x86_64
|
|
||||||
|
|
||||||
include src/arch/$(ARCH)/config.mk
|
|
||||||
|
|
||||||
BUILD_D := build
|
|
||||||
KERN_D := src/kernel
|
|
||||||
ARCH_D := src/arch/$(ARCH)
|
|
||||||
VERSION ?= $(shell git describe --dirty --always)
|
|
||||||
GITSHA ?= $(shell git rev-parse --short HEAD)
|
|
||||||
|
|
||||||
KERNEL_FILENAME:= popcorn.bin
|
|
||||||
KERNEL_FONT := assets/fonts/tamsyn8x16r.psf
|
|
||||||
|
|
||||||
MODULES := kutil
|
|
||||||
|
|
||||||
|
|
||||||
EFI_DIR := external/gnu-efi
|
|
||||||
EFI_DATA := $(EFI_DIR)/gnuefi
|
|
||||||
EFI_LDS := $(EFI_DATA)/elf_$(ARCH)_efi.lds
|
|
||||||
EFI_ARCH_DIR := $(EFI_DIR)/$(ARCH)
|
|
||||||
EFI_ARCH_DATA := $(EFI_ARCH_DIR)/gnuefi
|
|
||||||
EFI_CRT_OBJ := $(EFI_ARCH_DATA)/crt0-efi-$(ARCH).o
|
|
||||||
EFI_LIB := $(EFI_ARCH_DIR)/lib/libefi.a
|
|
||||||
EFI_INCLUDES := $(EFI_DIR)/inc
|
|
||||||
|
|
||||||
DEPENDFLAGS := -MMD
|
|
||||||
|
|
||||||
INCLUDES := -I $(ARCH_D)
|
|
||||||
INCLUDES += -I src/modules
|
|
||||||
INCLUDES += -I src/include
|
|
||||||
INCLUDES += -isystem $(EFI_INCLUDES)
|
|
||||||
INCLUDES += -isystem $(EFI_INCLUDES)/$(ARCH)
|
|
||||||
INCLUDES += -isystem $(EFI_INCLUDES)/protocol
|
|
||||||
|
|
||||||
BASEFLAGS := -ggdb -nostdlib
|
|
||||||
BASEFLAGS += -ffreestanding -nodefaultlibs
|
|
||||||
BASEFLAGS += -fno-builtin -fomit-frame-pointer
|
|
||||||
BASEFLAGS += -mno-red-zone -fno-stack-protector
|
|
||||||
|
|
||||||
ifdef CPU
|
|
||||||
BASEFLAGS += -mcpu=$(CPU)
|
|
||||||
endif
|
|
||||||
|
|
||||||
# Removed Flags:: -Wcast-align
|
|
||||||
WARNFLAGS += -Wformat=2 -Winit-self -Wfloat-equal -Winline
|
|
||||||
WARNFLAGS += -Winvalid-pch -Wmissing-format-attribute
|
|
||||||
WARNFLAGS += -Wmissing-include-dirs -Wswitch -Wundef
|
|
||||||
WARNFLAGS += -Wdisabled-optimization -Wpointer-arith
|
|
||||||
|
|
||||||
WARNFLAGS += -Wno-attributes -Wno-sign-compare -Wno-multichar
|
|
||||||
WARNFLAGS += -Wno-div-by-zero -Wno-endif-labels -Wno-pragmas
|
|
||||||
WARNFLAGS += -Wno-format-extra-args -Wno-unused-result
|
|
||||||
WARNFLAGS += -Wno-deprecated-declarations -Wno-unused-function
|
|
||||||
WARNFLAGS += -Wno-unused-but-set-parameter
|
|
||||||
|
|
||||||
ASFLAGS ?=
|
|
||||||
ASFLAGS += -p $(BUILD_D)/versions.s
|
|
||||||
|
|
||||||
CFLAGS := $(INCLUDES) $(DEPENDFLAGS) $(BASEFLAGS) $(WARNFLAGS)
|
|
||||||
CFLAGS += -DGIT_VERSION="\"$(VERSION)\""
|
|
||||||
CFLAGS += -std=c11 -mcmodel=large
|
|
||||||
|
|
||||||
CXXFLAGS := $(INCLUDES) $(DEPENDFLAGS) $(BASEFLAGS) $(WARNFLAGS)
|
|
||||||
CXXFLAGS += -DGIT_VERSION="\"$(VERSION)\""
|
|
||||||
CXXFLAGS += -std=c++14 -mcmodel=large
|
|
||||||
|
|
||||||
BOOT_CFLAGS := $(INCLUDES) $(DEPENDFLAGS) $(BASEFLAGS) $(WARNFLAGS)
|
|
||||||
BOOT_CFLAGS += -std=c11 -I src/boot -fPIC -fshort-wchar
|
|
||||||
BOOT_CFLAGS += -DKERNEL_FILENAME="L\"$(KERNEL_FILENAME)\""
|
|
||||||
BOOT_CFLAGS += -DGIT_VERSION_WIDE="L\"$(VERSION)\""
|
|
||||||
BOOT_CFLAGS += -DGNU_EFI_USE_MS_ABI -DHAVE_USE_MS_ABI
|
|
||||||
BOOT_CFLAGS += -DEFI_DEBUG=0 -DEFI_DEBUG_CLEAR_MEMORY=0
|
|
||||||
#BOOT_CFLAGS += -DEFI_FUNCTION_WRAPPER
|
|
||||||
|
|
||||||
ifdef MAX_HRES
|
|
||||||
BOOT_CFLAGS += -DMAX_HRES=$(MAX_HRES)
|
|
||||||
endif
|
|
||||||
|
|
||||||
LDFLAGS := -L $(BUILD_D) -ggdb
|
|
||||||
LDFLAGS += -nostdlib -znocombreloc -Bsymbolic -nostartfiles
|
|
||||||
|
|
||||||
BOOT_LDFLAGS := $(LDFLAGS) -shared
|
|
||||||
BOOT_LDFLAGS += -L $(EFI_ARCH_DIR)/lib -L $(EFI_ARCH_DIR)/gnuefi
|
|
||||||
|
|
||||||
AS ?= $(CROSS)nasm
|
|
||||||
AR ?= $(CROSS)ar
|
|
||||||
CC ?= $(CROSS)gcc
|
|
||||||
CXX ?= $(CROSS)g++
|
|
||||||
LD ?= $(CROSS)ld
|
|
||||||
OBJC := $(CROSS)objcopy
|
|
||||||
OBJD := $(CROSS)objdump
|
|
||||||
|
|
||||||
INIT_DEP := $(BUILD_D)/.builddir
|
|
||||||
|
|
||||||
BOOT_SRCS := $(wildcard src/boot/*.c)
|
|
||||||
BOBJS += $(patsubst src/boot/%,$(BUILD_D)/boot/%,$(patsubst %,%.o,$(BOOT_SRCS)))
|
|
||||||
|
|
||||||
KERN_SRCS := $(wildcard $(KERN_D)/*.s)
|
|
||||||
KERN_SRCS += $(wildcard $(KERN_D)/*.c)
|
|
||||||
KERN_SRCS += $(wildcard $(KERN_D)/*.cpp)
|
|
||||||
KERN_SRCS += $(wildcard $(ARCH_D)/*.s)
|
|
||||||
KERN_SRCS += $(wildcard $(ARCH_D)/*.c)
|
|
||||||
|
|
||||||
KERN_OBJS := $(patsubst src/%, $(BUILD_D)/%, $(patsubst %,%.o,$(KERN_SRCS)))
|
|
||||||
|
|
||||||
MOD_TARGETS :=
|
|
||||||
|
|
||||||
PARTED ?= /sbin/parted
|
|
||||||
QEMU ?= qemu-system-x86_64
|
|
||||||
GDBPORT ?= 27006
|
|
||||||
CPUS ?= 1
|
|
||||||
OVMF ?= assets/ovmf/x64/OVMF.fd
|
|
||||||
|
|
||||||
QEMUOPTS := -pflash $(BUILD_D)/flash.img
|
|
||||||
QEMUOPTS += -drive file=$(BUILD_D)/fs.img,format=raw
|
|
||||||
QEMUOPTS += -smp $(CPUS)
|
|
||||||
QEMUOPTS += -m 512
|
|
||||||
QEMUOPTS += -d guest_errors
|
|
||||||
QEMUOPTS += $(QEMUEXTRA)
|
|
||||||
|
|
||||||
|
|
||||||
all: $(BUILD_D)/fs.img
|
|
||||||
init: $(INIT_DEP)
|
|
||||||
|
|
||||||
$(INIT_DEP):
|
|
||||||
mkdir -p $(BUILD_D) $(patsubst %,$(BUILD_D)/d.%,$(MODULES))
|
|
||||||
mkdir -p $(BUILD_D)/boot
|
|
||||||
mkdir -p $(patsubst src/%,$(BUILD_D)/%,$(ARCH_D))
|
|
||||||
mkdir -p $(patsubst src/%,$(BUILD_D)/%,$(KERN_D))
|
|
||||||
touch $(INIT_DEP)
|
|
||||||
|
|
||||||
clean:
|
|
||||||
rm -rf $(BUILD_D)/* $(BUILD_D)/.version $(BUILD_D)/.builddir
|
|
||||||
|
|
||||||
vars:
|
|
||||||
@echo "KERN_SRCS: " $(KERN_SRCS)
|
|
||||||
@echo "KERN_OBJS: " $(KERN_OBJS)
|
|
||||||
|
|
||||||
dist-clean: clean
|
|
||||||
make -C external/gnu-efi clean
|
|
||||||
|
|
||||||
dump: $(BUILD_D)/kernel.dump
|
|
||||||
vim $<
|
|
||||||
|
|
||||||
.PHONY: all clean dist-clean init dump vars
|
|
||||||
|
|
||||||
$(BUILD_D)/.version:
|
|
||||||
echo '$(VERSION)' | cmp -s - $@ || echo '$(VERSION)' > $@
|
|
||||||
|
|
||||||
$(BUILD_D)/versions.s:
|
|
||||||
./parse_version.py "$(VERSION)" "$(GITSHA)" > $@
|
|
||||||
|
|
||||||
-include x $(patsubst %,src/modules/%/module.mk,$(MODULES))
|
|
||||||
-include x $(shell find $(BUILD_D) -type f -name '*.d')
|
|
||||||
|
|
||||||
$(EFI_LIB):
|
|
||||||
make -C external/gnu-efi all
|
|
||||||
|
|
||||||
$(BUILD_D)/boot.elf: $(BOBJS) $(EFI_LIB)
|
|
||||||
$(LD) $(BOOT_LDFLAGS) -T $(EFI_LDS) -o $@ \
|
|
||||||
$(EFI_CRT_OBJ) $(BOBJS) -lefi -lgnuefi
|
|
||||||
|
|
||||||
$(BUILD_D)/boot.efi: $(BUILD_D)/boot.elf
|
|
||||||
$(OBJC) -j .text -j .sdata -j .data -j .dynamic \
|
|
||||||
-j .dynsym -j .rel -j .rela -j .reloc \
|
|
||||||
--target=efi-app-$(ARCH) $^ $@
|
|
||||||
|
|
||||||
$(BUILD_D)/boot.debug.efi: $(BUILD_D)/boot.elf
|
|
||||||
$(OBJC) -j .text -j .sdata -j .data -j .dynamic \
|
|
||||||
-j .dynsym -j .rel -j .rela -j .reloc \
|
|
||||||
-j .debug_info -j .debug_abbrev -j .debug_loc -j .debug_str \
|
|
||||||
-j .debug_aranges -j .debug_line -j .debug_macinfo \
|
|
||||||
--target=efi-app-$(ARCH) $^ $@
|
|
||||||
|
|
||||||
$(BUILD_D)/%.bin: $(BUILD_D)/%.elf
|
|
||||||
$(OBJC) $< -O binary $@
|
|
||||||
|
|
||||||
$(BUILD_D)/boot.dump: $(BUILD_D)/boot.efi
|
|
||||||
$(OBJD) -D -S $< > $@
|
|
||||||
|
|
||||||
$(BUILD_D)/boot/%.s.o: src/boot/%.s $(BUILD_D)/versions.s $(INIT_DEP)
|
|
||||||
$(AS) $(ASFLAGS) -i src/boot/ -o $@ $<
|
|
||||||
|
|
||||||
$(BUILD_D)/boot/%.c.o: src/boot/%.c $(INIT_DEP)
|
|
||||||
$(CC) $(BOOT_CFLAGS) -c -o $@ $<
|
|
||||||
|
|
||||||
$(BUILD_D)/kernel.elf: $(KERN_OBJS) $(MOD_TARGETS) $(ARCH_D)/kernel.ld
|
|
||||||
$(LD) $(LDFLAGS) -u _header -T $(ARCH_D)/kernel.ld -o $@ $(KERN_OBJS) $(patsubst %,-l%,$(MODULES))
|
|
||||||
$(OBJC) --only-keep-debug $@ $@.sym
|
|
||||||
|
|
||||||
$(BUILD_D)/kernel.dump: $(BUILD_D)/kernel.elf
|
|
||||||
$(OBJD) -D -S $< > $@
|
|
||||||
|
|
||||||
$(BUILD_D)/%.s.o: src/%.s $(BUILD_D)/versions.s $(INIT_DEP)
|
|
||||||
$(AS) $(ASFLAGS) -i $(ARCH_D)/ -i $(KERN_D)/ -o $@ $<
|
|
||||||
|
|
||||||
$(BUILD_D)/%.c.o: src/%.c $(INIT_DEP)
|
|
||||||
$(CC) $(CFLAGS) -c -o $@ $<
|
|
||||||
|
|
||||||
$(BUILD_D)/%.cpp.o: src/%.cpp $(INIT_DEP)
|
|
||||||
$(CXX) $(CXXFLAGS) -c -o $@ $<
|
|
||||||
|
|
||||||
$(BUILD_D)/flash.img: $(OVMF)
|
|
||||||
cp $^ $@
|
|
||||||
|
|
||||||
$(BUILD_D)/screenfont.psf: $(KERNEL_FONT)
|
|
||||||
cp $^ $@
|
|
||||||
|
|
||||||
$(BUILD_D)/fs.img: $(BUILD_D)/boot.efi $(BUILD_D)/kernel.bin $(BUILD_D)/screenfont.psf
|
|
||||||
$(eval TEMPFILE := $(shell mktemp --suffix=.img))
|
|
||||||
dd if=/dev/zero of=$@.tmp bs=512 count=93750
|
|
||||||
$(PARTED) $@.tmp -s -a minimal mklabel gpt
|
|
||||||
$(PARTED) $@.tmp -s -a minimal mkpart EFI FAT16 2048s 93716s
|
|
||||||
$(PARTED) $@.tmp -s -a minimal toggle 1 boot
|
|
||||||
dd if=/dev/zero of=$(TEMPFILE) bs=512 count=91669
|
|
||||||
mformat -i $(TEMPFILE) -h 32 -t 32 -n 64 -c 1
|
|
||||||
mmd -i $(TEMPFILE) ::/EFI
|
|
||||||
mmd -i $(TEMPFILE) ::/EFI/BOOT
|
|
||||||
mcopy -i $(TEMPFILE) $(BUILD_D)/boot.efi ::/EFI/BOOT/BOOTX64.efi
|
|
||||||
mcopy -i $(TEMPFILE) $(BUILD_D)/kernel.bin ::$(KERNEL_FILENAME)
|
|
||||||
mcopy -i $(TEMPFILE) $(BUILD_D)/screenfont.psf ::screenfont.psf
|
|
||||||
mlabel -i $(TEMPFILE) ::Popcorn_OS
|
|
||||||
dd if=$(TEMPFILE) of=$@.tmp bs=512 count=91669 seek=2048 conv=notrunc
|
|
||||||
rm $(TEMPFILE)
|
|
||||||
mv $@.tmp $@
|
|
||||||
|
|
||||||
$(BUILD_D)/fs.iso: $(BUILD_D)/fs.img
|
|
||||||
mkdir -p $(BUILD_D)/iso
|
|
||||||
cp $< $(BUILD_D)/iso/
|
|
||||||
xorriso -as mkisofs -R -f -e fs.img -no-emul-boot -o $@ $(BUILD_D)/iso
|
|
||||||
|
|
||||||
qemu: $(BUILD_D)/fs.img $(BUILD_D)/flash.img
|
|
||||||
"$(QEMU)" $(QEMUOPTS) -nographic
|
|
||||||
|
|
||||||
qemu-window: $(BUILD_D)/fs.img $(BUILD_D)/flash.img
|
|
||||||
"$(QEMU)" $(QEMUOPTS)
|
|
||||||
|
|
||||||
qemu-gdb: $(BUILD_D)/fs.img $(BUILD_D)/boot.debug.efi $(BUILD_D)/flash.img $(BUILD_D)/kernel.elf
|
|
||||||
"$(QEMU)" $(QEMUOPTS) -d mmu,guest_errors,page -D popcorn.log -s -nographic
|
|
||||||
|
|
||||||
# vim: ft=make ts=4
|
|
||||||
7
NOTES.md
7
NOTES.md
@@ -1,7 +0,0 @@
|
|||||||
# Design / WIP notes
|
|
||||||
|
|
||||||
## TODO
|
|
||||||
|
|
||||||
- Better page-allocation model
|
|
||||||
- Allow for more than one IOAPIC in ACPI module
|
|
||||||
|
|
||||||
184
README.md
184
README.md
@@ -1,7 +1,181 @@
|
|||||||
# popcorn: A toy microkernel x64 UEFI OS
|

|
||||||
|
|
||||||
**popcorn** is a hobby OS for x64 UEFI environments to play with building a
|
# The jsix operating system
|
||||||
microkenerl architecture. It's far from finished, or even being usable - for
|
|
||||||
now, it's a sandbox for me to explore the UEFI architecture, microkernels, and
|
|
||||||
OS-related concepts that I want to play with.
|
|
||||||
|
|
||||||
|
**jsix** is a custom multi-core x64 operating system that I am building from
|
||||||
|
scratch. It's far from finished, or even being usable (see the *Status and
|
||||||
|
Roadmap* section, below) but all currently-planned major kernel features are
|
||||||
|
now implemented to at least a passable level.
|
||||||
|
|
||||||
|
The design goals of the project are:
|
||||||
|
|
||||||
|
* Modernity - I'm not interested in designing for legacy systems, or running on
|
||||||
|
all hardware out there. My target is only 64 bit architectures, and modern
|
||||||
|
commodity hardware. Currently that means x64 systems with Nehalem or newer
|
||||||
|
CPUs and UEFI firmware. (See [this list][cpu_features] for the currently
|
||||||
|
required CPU features.) Eventually I'd like to work on an AArch64 port,
|
||||||
|
partly to force myself to factor out the architecture-dependent pieces of the
|
||||||
|
code base.
|
||||||
|
|
||||||
|
* Modularity - I'd like to pull as much of the system out into separate
|
||||||
|
processes as possible, in the microkernel fashion. A sub-goal of this is to
|
||||||
|
explore where the bottlenecks of such a microkernel are now, and whether
|
||||||
|
eschewing legacy hardware will let me design a system that's less bogged down
|
||||||
|
by the traditional microkernel problems.
|
||||||
|
|
||||||
|
* Exploration - I'm really mostly doing this to have fun learning and exploring
|
||||||
|
modern OS development. Initial feature implementations may temporarily throw
|
||||||
|
away modular design to allow for exploration of the related hardware.
|
||||||
|
|
||||||
|
A note on the name: This kernel was originally named Popcorn, but I have since
|
||||||
|
discovered that the Popcorn Linux project is also developing a kernel with that
|
||||||
|
name, started around the same time as this project. So I've renamed this kernel
|
||||||
|
jsix (Always styled _jsix_ or `j6`, never capitalized) as an homage to L4, xv6,
|
||||||
|
and my wonderful wife.
|
||||||
|
|
||||||
|
[cpu_features]: https://github.com/justinian/jsix/blob/master/src/libraries/cpu/include/cpu/features.inc
|
||||||
|
|
||||||
|
## Status and Roadmap
|
||||||
|
|
||||||
|
The following major feature areas are targets for jsix development:
|
||||||
|
|
||||||
|
#### UEFI boot loader
|
||||||
|
|
||||||
|
_Done._ The bootloader loads the kernel and initial userspace programs, and
|
||||||
|
sets up necessary kernel arguments about the memory map and EFI GOP
|
||||||
|
framebuffer. Possible future ideas:
|
||||||
|
|
||||||
|
- take over more init-time functions from the kernel
|
||||||
|
- rewrite it in Zig
|
||||||
|
|
||||||
|
#### Memory
|
||||||
|
|
||||||
|
_Virtual memory: Sufficient._ The kernel manages virtual memory with a number
|
||||||
|
of kinds of `vm_area` objects representing mapped areas, which can belong to
|
||||||
|
one or more `vm_space` objects which represent a whole virtual memory space.
|
||||||
|
(Each process has a `vm_space`, and so does the kernel itself.)
|
||||||
|
|
||||||
|
Remaining to do:
|
||||||
|
|
||||||
|
- TLB shootdowns
|
||||||
|
- Page swapping
|
||||||
|
- Large / huge page support
|
||||||
|
|
||||||
|
_Physical page allocation: Sufficient._ The current physical page allocator
|
||||||
|
implementation uses a group of blocks representing up-to-1GiB areas of usable
|
||||||
|
memory as defined by the bootloader. Each block has a three-level bitmap
|
||||||
|
denoting free/used pages.
|
||||||
|
|
||||||
|
Future work:
|
||||||
|
|
||||||
|
- Align blocks so that their first page is 1GiB-aligned, making finding free
|
||||||
|
large/huge pages easier.
|
||||||
|
|
||||||
|
#### Multitasking
|
||||||
|
|
||||||
|
_Sufficient._ The global scheduler object keeps separate ready/blocked lists
|
||||||
|
per core. Cores periodically attempt to balance load via work stealing.
|
||||||
|
|
||||||
|
User-space tasks are able to create threads as well as other processes.
|
||||||
|
|
||||||
|
#### API
|
||||||
|
|
||||||
|
_Syscalls: Sufficient._ User-space tasks are able to make syscalls to the
|
||||||
|
kernel via fast SYSCALL/SYSRET instructions. Syscalls made via `libj6` look to
|
||||||
|
both the callee and the caller like standard SysV ABI function calls. The
|
||||||
|
implementations are wrapped in generated wrapper functions which validate the
|
||||||
|
request, check capabilities, and find the appropriate kernel objects or handles
|
||||||
|
before calling the implementation functions.
|
||||||
|
|
||||||
|
_IPC: Working, needs optimization._ The current IPC primitives are:
|
||||||
|
|
||||||
|
- _Mailboxes_: endpoints for asynchronously-delivered small messages. Currently
|
||||||
|
these messages are double-copied - once from the caller into a kernel buffer,
|
||||||
|
and once from the kernel to the receiver. This works and is not a major cause
|
||||||
|
of slowdown, but will need to be optimized in the future.
|
||||||
|
- _Channels_: endpoints for asynchronous uni-directional streams of bytes.
|
||||||
|
Currently these also suffer from a double-copy problem, and should probably
|
||||||
|
be replaced eventually by userspace shared memory communication.
|
||||||
|
- _Events_: objects that can be signalled to send asynchronous notifications to
|
||||||
|
waiting threads.
|
||||||
|
|
||||||
|
#### Hardware Support
|
||||||
|
|
||||||
|
- Framebuffer driver: _In progress._ Currently on machines with a video
|
||||||
|
device accessible by UEFI, jsix starts a user-space framebuffer driver that
|
||||||
|
only prints out kernel logs.
|
||||||
|
- Serial driver: _In progress._ The current UART currently only exposes COM1
|
||||||
|
as an output channel, but no input or other serial ports are exposed.
|
||||||
|
- USB driver: _To do_
|
||||||
|
- AHCI (SATA) driver: _To do_
|
||||||
|
|
||||||
|
## Building
|
||||||
|
|
||||||
|
jsix uses the [Ninja][] build tool, and generates the build files for it with
|
||||||
|
the `configure` script. The build also relies on a custom toolchain sysroot, which can be
|
||||||
|
downloaded or built using the scripts in [jsix-os/toolchain][].
|
||||||
|
|
||||||
|
[Ninja]: https://ninja-build.org
|
||||||
|
[jsix-os/toolchain]: https://github.com/jsix-os/toolchain
|
||||||
|
|
||||||
|
Other build dependencies:
|
||||||
|
|
||||||
|
* [clang][]: the C/C++ compiler
|
||||||
|
* [nasm][]: the assembler
|
||||||
|
* [lld][]: the linker
|
||||||
|
* [mtools][]: for creating the FAT image
|
||||||
|
|
||||||
|
[clang]: https://clang.llvm.org
|
||||||
|
[nasm]: https://www.nasm.us
|
||||||
|
[lld]: https://lld.llvm.org
|
||||||
|
[mtools]: https://www.gnu.org/software/mtools/
|
||||||
|
|
||||||
|
The `configure` script has some Python dependencies - these can be installed via
|
||||||
|
`pip`, though doing so in a python virtual environment is recommended.
|
||||||
|
Installing via `pip` will also install `ninja`.
|
||||||
|
|
||||||
|
A Debian 11 (Bullseye) system can be configured with the necessary build
|
||||||
|
dependencies by running the following commands from the jsix repository root:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo apt install clang lld nasm mtools python3-pip python3-venv
|
||||||
|
python3 -m venv ./venv
|
||||||
|
source venv/bin/activate
|
||||||
|
pip install -r requirements.txt
|
||||||
|
peru sync
|
||||||
|
```
|
||||||
|
|
||||||
|
### Setting up the sysroot
|
||||||
|
|
||||||
|
Build or download the toolchain sysroot as mentioned above with
|
||||||
|
[jsix-os/toolchain][], and symlink the built toolchain directory as `sysroot`
|
||||||
|
at the root of this project.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Example if both the toolchain and this project are cloned under ~/src
|
||||||
|
ln -s ~/src/toolchain/toolchains/llvm-13 ~/src/jsix/sysroot
|
||||||
|
```
|
||||||
|
|
||||||
|
### Building and running jsix
|
||||||
|
|
||||||
|
Once the toolchain has been set up, running the `./configure` script (see
|
||||||
|
`./configure --help` for available options) will set up the build configuration,
|
||||||
|
and `ninja -C build` (or wherever you put the build directory) will actually run
|
||||||
|
the build. If you have `qemu-system-x86_64` installed, the `qemu.sh` script will
|
||||||
|
to run jsix in QEMU `-nographic` mode.
|
||||||
|
|
||||||
|
I personally run this either from a real debian amd64 bullseye machine or
|
||||||
|
a windows WSL debian bullseye installation. Your mileage may vary with other
|
||||||
|
setups and distros.
|
||||||
|
|
||||||
|
### Running the test suite
|
||||||
|
|
||||||
|
jsix now has the `test_runner` userspace program that runs various automated
|
||||||
|
tests. It is not included in the default build, but if you use the `test.yml`
|
||||||
|
manifest it will be built, and can be run with the `test.sh` script or the
|
||||||
|
`qemu.sh` script.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./configure --manifest=assets/manifests/test.yml
|
||||||
|
if ./test.sh; then echo "All tests passed!"; else echo "Failed."; fi
|
||||||
|
```
|
||||||
|
|||||||
269
assets/debugging/jsix.elf-gdb.py
Normal file
269
assets/debugging/jsix.elf-gdb.py
Normal file
@@ -0,0 +1,269 @@
|
|||||||
|
import gdb
|
||||||
|
|
||||||
|
class PrintStackCommand(gdb.Command):
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__("j6stack", gdb.COMMAND_DATA)
|
||||||
|
|
||||||
|
def invoke(self, arg, from_tty):
|
||||||
|
args = gdb.string_to_argv(arg)
|
||||||
|
|
||||||
|
base = "$rsp"
|
||||||
|
if len(args) > 0:
|
||||||
|
base = args[0]
|
||||||
|
base = int(gdb.parse_and_eval(base))
|
||||||
|
|
||||||
|
depth = 22
|
||||||
|
if len(args) > 1:
|
||||||
|
depth = int(args[1])
|
||||||
|
|
||||||
|
for i in range(depth-1, -1, -1):
|
||||||
|
try:
|
||||||
|
offset = i * 8
|
||||||
|
value = gdb.parse_and_eval(f"*(uint64_t*)({base:#x} + {offset:#x})")
|
||||||
|
print("{:016x} (+{:04x}): {:016x}".format(base + offset, offset, int(value)))
|
||||||
|
except Exception as e:
|
||||||
|
print(e)
|
||||||
|
continue
|
||||||
|
|
||||||
|
|
||||||
|
def stack_walk(frame, depth):
|
||||||
|
for i in range(depth-1, -1, -1):
|
||||||
|
ret = gdb.parse_and_eval(f"*(uint64_t*)({frame:#x} + 0x8)")
|
||||||
|
|
||||||
|
name = ""
|
||||||
|
try:
|
||||||
|
block = gdb.block_for_pc(int(ret))
|
||||||
|
if block:
|
||||||
|
name = block.function or ""
|
||||||
|
except RuntimeError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
try:
|
||||||
|
print("{:016x}: {:016x} {}".format(int(frame), int(ret), name))
|
||||||
|
frame = int(gdb.parse_and_eval(f"*(uint64_t*)({frame:#x})"))
|
||||||
|
except gdb.MemoryError:
|
||||||
|
return
|
||||||
|
|
||||||
|
if frame == 0 or ret == 0:
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
class PrintBacktraceCommand(gdb.Command):
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__("j6bt", gdb.COMMAND_DATA)
|
||||||
|
|
||||||
|
def invoke(self, arg, from_tty):
|
||||||
|
args = gdb.string_to_argv(arg)
|
||||||
|
|
||||||
|
frame = "$rbp"
|
||||||
|
if len(args) > 0:
|
||||||
|
frame = args[0]
|
||||||
|
|
||||||
|
frame = int(gdb.parse_and_eval(f"{frame}"))
|
||||||
|
|
||||||
|
depth = 30
|
||||||
|
if len(args) > 1:
|
||||||
|
depth = int(gdb.parse_and_eval(args[1]))
|
||||||
|
|
||||||
|
stack_walk(frame, depth)
|
||||||
|
|
||||||
|
|
||||||
|
class TableWalkCommand(gdb.Command):
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__("j6tw", gdb.COMMAND_DATA)
|
||||||
|
|
||||||
|
def invoke(self, arg, from_tty):
|
||||||
|
args = gdb.string_to_argv(arg)
|
||||||
|
if len(args) < 2:
|
||||||
|
raise Exception("Must be: j6tw <pml4> <addr>")
|
||||||
|
|
||||||
|
pml4 = int(gdb.parse_and_eval(args[0]))
|
||||||
|
addr = int(gdb.parse_and_eval(args[1]))
|
||||||
|
|
||||||
|
indices = [
|
||||||
|
(addr >> 39) & 0x1ff,
|
||||||
|
(addr >> 30) & 0x1ff,
|
||||||
|
(addr >> 21) & 0x1ff,
|
||||||
|
(addr >> 12) & 0x1ff,
|
||||||
|
]
|
||||||
|
|
||||||
|
names = ["PML4", "PDP", "PD", "PT"]
|
||||||
|
|
||||||
|
table_flags = [
|
||||||
|
(0x0001, "present"),
|
||||||
|
(0x0002, "write"),
|
||||||
|
(0x0004, "user"),
|
||||||
|
(0x0008, "pwt"),
|
||||||
|
(0x0010, "pcd"),
|
||||||
|
(0x0020, "accessed"),
|
||||||
|
(0x0040, "dirty"),
|
||||||
|
(0x0080, "largepage"),
|
||||||
|
(0x0100, "global"),
|
||||||
|
(0x1080, "pat"),
|
||||||
|
((1<<63), "xd"),
|
||||||
|
]
|
||||||
|
|
||||||
|
page_flags = [
|
||||||
|
(0x0001, "present"),
|
||||||
|
(0x0002, "write"),
|
||||||
|
(0x0004, "user"),
|
||||||
|
(0x0008, "pwt"),
|
||||||
|
(0x0010, "pcd"),
|
||||||
|
(0x0020, "accessed"),
|
||||||
|
(0x0040, "dirty"),
|
||||||
|
(0x0080, "pat"),
|
||||||
|
(0x0100, "global"),
|
||||||
|
((1<<63), "xd"),
|
||||||
|
]
|
||||||
|
|
||||||
|
flagsets = [table_flags, table_flags, table_flags, page_flags]
|
||||||
|
|
||||||
|
table = pml4
|
||||||
|
entry = 0
|
||||||
|
for i in range(len(indices)):
|
||||||
|
entry = int(gdb.parse_and_eval(f'((uint64_t*)0x{table:x})[0x{indices[i]:x}]'))
|
||||||
|
flagset = flagsets[i]
|
||||||
|
flag_names = " | ".join([f[1] for f in flagset if (entry & f[0]) == f[0]])
|
||||||
|
|
||||||
|
print(f"{names[i]:>4}: {table:016x}")
|
||||||
|
print(f" index: {indices[i]:3} {entry:016x}")
|
||||||
|
print(f" flags: {flag_names}")
|
||||||
|
|
||||||
|
if (entry & 1) == 0 or (i < 3 and (entry & 0x80)):
|
||||||
|
break
|
||||||
|
|
||||||
|
table = (entry & 0x7ffffffffffffe00) | 0xffffc00000000000
|
||||||
|
|
||||||
|
|
||||||
|
class GetThreadsCommand(gdb.Command):
|
||||||
|
FLAGS = {
|
||||||
|
"ready": 0x01,
|
||||||
|
"loading": 0x02,
|
||||||
|
"exited": 0x04,
|
||||||
|
"constant": 0x80,
|
||||||
|
}
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__("j6threads", gdb.COMMAND_DATA)
|
||||||
|
|
||||||
|
def get_flags(self, bitset):
|
||||||
|
flags = []
|
||||||
|
for k, v in GetThreadsCommand.FLAGS.items():
|
||||||
|
if bitset & v:
|
||||||
|
flags.append(k)
|
||||||
|
return " ".join(flags)
|
||||||
|
|
||||||
|
def print_thread(self, addr):
|
||||||
|
if addr == 0:
|
||||||
|
print(" <no thread>\n")
|
||||||
|
return
|
||||||
|
|
||||||
|
tcb = f"((TCB*){addr:#x})"
|
||||||
|
thread = f"({tcb}->thread)"
|
||||||
|
stack = int(gdb.parse_and_eval(f"{tcb}->kernel_stack"))
|
||||||
|
rsp = int(gdb.parse_and_eval(f"{tcb}->rsp"))
|
||||||
|
pri = int(gdb.parse_and_eval(f"{tcb}->priority"))
|
||||||
|
flags = int(gdb.parse_and_eval(f"{thread}->m_state"))
|
||||||
|
koid = int(gdb.parse_and_eval(f"{thread}->m_koid"))
|
||||||
|
proc = int(gdb.parse_and_eval(f"{thread}->m_parent.m_koid"))
|
||||||
|
|
||||||
|
creator = int(gdb.parse_and_eval(f"{thread}->m_creator"))
|
||||||
|
if creator != 0:
|
||||||
|
creator_koid = int(gdb.parse_and_eval(f"{thread}->m_creator->m_koid"))
|
||||||
|
creator = f"{creator_koid:x}"
|
||||||
|
else:
|
||||||
|
creator = "<no thread>"
|
||||||
|
|
||||||
|
print(f" Thread {proc:x}:{koid:x}")
|
||||||
|
print(f" creator: {creator}")
|
||||||
|
print(f" priority: {pri}")
|
||||||
|
print(f" flags: {self.get_flags(flags)}")
|
||||||
|
print(f" kstack: {stack:#x}")
|
||||||
|
print(f" rsp: {rsp:#x}")
|
||||||
|
print("------------------------------------")
|
||||||
|
|
||||||
|
if stack != 0:
|
||||||
|
rsp = int(gdb.parse_and_eval(f"{tcb}->rsp"))
|
||||||
|
stack_walk(rsp + 5*8, 5)
|
||||||
|
|
||||||
|
print("")
|
||||||
|
|
||||||
|
def print_thread_list(self, addr, name):
|
||||||
|
if addr == 0:
|
||||||
|
return
|
||||||
|
|
||||||
|
print(f"=== {name} ===")
|
||||||
|
|
||||||
|
while addr != 0:
|
||||||
|
self.print_thread(addr)
|
||||||
|
addr = int(gdb.parse_and_eval(f"((tcb_node*){addr:#x})->m_next"))
|
||||||
|
|
||||||
|
|
||||||
|
def invoke(self, arg, from_tty):
|
||||||
|
args = gdb.string_to_argv(arg)
|
||||||
|
if len(args) > 1:
|
||||||
|
raise RuntimeError("Usage: j6threads [cpu]")
|
||||||
|
|
||||||
|
ncpus = int(gdb.parse_and_eval("g_num_cpus"))
|
||||||
|
cpus = list(range(ncpus))
|
||||||
|
if len(args) == 1:
|
||||||
|
cpus = [int(args[0])]
|
||||||
|
|
||||||
|
for cpu in cpus:
|
||||||
|
runlist = f"scheduler::s_instance->m_run_queues.m_elements[{cpu:#x}]"
|
||||||
|
|
||||||
|
print(f"=== CPU {cpu:2}: CURRENT ===")
|
||||||
|
current = int(gdb.parse_and_eval(f"{runlist}.current"))
|
||||||
|
self.print_thread(current)
|
||||||
|
|
||||||
|
for pri in range(8):
|
||||||
|
ready = int(gdb.parse_and_eval(f"{runlist}.ready[{pri:#x}].m_head"))
|
||||||
|
self.print_thread_list(ready, f"CPU {cpu:2}: PRIORITY {pri}")
|
||||||
|
|
||||||
|
blocked = int(gdb.parse_and_eval(f"{runlist}.blocked.m_head"))
|
||||||
|
self.print_thread_list(blocked, f"CPU {cpu:2}: BLOCKED")
|
||||||
|
|
||||||
|
|
||||||
|
class PrintProfilesCommand(gdb.Command):
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__("j6prof", gdb.COMMAND_DATA)
|
||||||
|
|
||||||
|
def invoke(self, arg, from_tty):
|
||||||
|
args = gdb.string_to_argv(arg)
|
||||||
|
if len(args) != 1:
|
||||||
|
raise RuntimeError("Usage: j6prof <profiler class>")
|
||||||
|
|
||||||
|
profclass = args[0]
|
||||||
|
root_type = f"profile_class<{profclass}>"
|
||||||
|
|
||||||
|
try:
|
||||||
|
baseclass = gdb.lookup_type(root_type)
|
||||||
|
except Exception as e:
|
||||||
|
print(e)
|
||||||
|
return
|
||||||
|
|
||||||
|
results = {}
|
||||||
|
max_len = 0
|
||||||
|
count = gdb.parse_and_eval(f"{profclass}::count")
|
||||||
|
for i in range(count):
|
||||||
|
name = gdb.parse_and_eval(f"{root_type}::function_names[{i:#x}]")
|
||||||
|
if name == 0: continue
|
||||||
|
|
||||||
|
call_counts = gdb.parse_and_eval(f"{root_type}::call_counts[{i:#x}]")
|
||||||
|
call_durations = gdb.parse_and_eval(f"{root_type}::call_durations[{i:#x}]")
|
||||||
|
results[name.string()] = float(call_durations) / float(call_counts)
|
||||||
|
max_len = max(max_len, len(name.string()))
|
||||||
|
|
||||||
|
for name, avg in results.items():
|
||||||
|
print(f"{name:>{max_len}}: {avg:15.3f}")
|
||||||
|
|
||||||
|
PrintStackCommand()
|
||||||
|
PrintBacktraceCommand()
|
||||||
|
TableWalkCommand()
|
||||||
|
GetThreadsCommand()
|
||||||
|
PrintProfilesCommand()
|
||||||
|
|
||||||
|
gdb.execute("display/i $rip")
|
||||||
|
if not gdb.selected_inferior().was_attached:
|
||||||
|
gdb.execute("add-symbol-file build/panic.serial.elf")
|
||||||
|
gdb.execute("target remote :1234")
|
||||||
BIN
assets/diskbase.img
Normal file
BIN
assets/diskbase.img
Normal file
Binary file not shown.
BIN
assets/floppy.img
Normal file
BIN
assets/floppy.img
Normal file
Binary file not shown.
47
assets/grammars/definitions.g
Normal file
47
assets/grammars/definitions.g
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
start: import_statement* (object|interface)+
|
||||||
|
|
||||||
|
import_statement: "import" PATH
|
||||||
|
|
||||||
|
object: description? "object" name options? super? "{" uid cname? capabilities? method* "}"
|
||||||
|
|
||||||
|
interface: description? "interface" name options? "{" uid interface_param* "}"
|
||||||
|
|
||||||
|
?interface_param: expose | function
|
||||||
|
|
||||||
|
expose: "expose" type
|
||||||
|
|
||||||
|
uid: "uid" UID
|
||||||
|
|
||||||
|
cname: "cname" IDENTIFIER
|
||||||
|
|
||||||
|
capabilities: "capabilities" "[" IDENTIFIER+ "]"
|
||||||
|
|
||||||
|
super: ":" name
|
||||||
|
|
||||||
|
function: description? "function" name options? ("{" param* "}")?
|
||||||
|
|
||||||
|
method: description? "method" name options? ("{" param* "}")?
|
||||||
|
|
||||||
|
param: "param" name type options? description?
|
||||||
|
|
||||||
|
?type: PRIMITIVE | object_name
|
||||||
|
|
||||||
|
object_name: "ref" name
|
||||||
|
|
||||||
|
id: NUMBER
|
||||||
|
name: IDENTIFIER
|
||||||
|
options: "[" ( OPTION | IDENTIFIER )+ "]"
|
||||||
|
description: COMMENT+
|
||||||
|
|
||||||
|
PRIMITIVE: INT_TYPE | "size" | "string" | "buffer" | "address"
|
||||||
|
INT_TYPE: /u?int(8|16|32|64)?/
|
||||||
|
NUMBER: /(0x)?[0-9a-fA-F]+/
|
||||||
|
UID: /[0-9a-fA-F]{16}/
|
||||||
|
OPTION.2: IDENTIFIER ":" IDENTIFIER
|
||||||
|
COMMENT: /#.*/
|
||||||
|
PATH: /"[^"]*"/
|
||||||
|
|
||||||
|
%import common.LETTER
|
||||||
|
%import common.CNAME -> IDENTIFIER
|
||||||
|
%import common.WS
|
||||||
|
%ignore WS
|
||||||
1
assets/jsix.svg
Executable file
1
assets/jsix.svg
Executable file
@@ -0,0 +1 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?><!-- Generator: Gravit.io --><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="isolation:isolate" viewBox="176.562 356.069 211.11 113" width="211.11pt" height="113pt"><g><g><rect x="176.562" y="356.069" width="211.11" height="113" transform="matrix(1,0,0,1,0,0)" fill="rgb(255,255,255)"/><g><path d=" M 212.981 372.36 L 219.564 376.16 L 226.147 379.961 L 226.147 387.563 L 226.147 395.164 L 219.564 398.965 L 212.981 402.766 L 206.398 398.965 L 199.815 395.164 L 199.815 387.563 L 199.815 379.961 L 206.398 376.16 L 212.981 372.36 L 212.981 372.36 L 212.981 372.36 Z M 256.292 397.366 L 262.875 401.166 L 269.458 404.967 L 269.458 412.569 L 269.458 420.17 L 262.875 423.971 L 256.292 427.772 L 249.709 423.971 L 243.126 420.17 L 243.126 412.569 L 243.126 404.967 L 249.709 401.166 L 256.292 397.366 L 256.292 397.366 Z M 183.622 387.283 L 205.52 374.64 L 227.418 361.997 L 249.316 374.64 L 271.214 387.283 L 271.214 412.569 L 271.214 437.854 L 249.316 450.497 L 227.418 463.14 L 205.52 450.497 L 183.622 437.854 L 183.622 412.569 L 183.622 387.283 L 183.622 387.283 L 183.622 387.283 Z M 241.855 372.36 L 248.438 376.16 L 255.021 379.961 L 255.021 387.563 L 255.021 395.164 L 248.438 398.965 L 241.855 402.766 L 235.272 398.965 L 228.689 395.164 L 228.689 387.563 L 228.689 379.961 L 235.272 376.16 L 241.855 372.36 Z " fill-rule="evenodd" fill="rgb(49,79,128)"/><path d=" M 298.642 379.579 L 291.621 379.579 L 291.621 372.558 L 298.642 372.558 L 298.642 379.579 Z M 285.214 446.718 L 285.214 441.452 L 287.32 441.452 L 287.32 441.452 Q 289.339 441.452 290.524 440.092 L 290.524 440.092 L 290.524 440.092 Q 291.708 438.731 291.708 436.625 L 291.708 436.625 L 291.708 387.039 L 298.729 387.039 L 298.729 436.011 L 298.729 436.011 Q 298.729 440.925 295.921 443.822 L 295.921 443.822 L 295.921 443.822 Q 293.113 446.718 288.286 446.718 L 288.286 446.718 L 285.214 446.718 Z M 306.628 432.676 L 306.628 427.41 L 314.088 427.41 L 314.088 427.41 Q 317.862 427.41 319.573 425.347 L 319.573 425.347 L 319.573 425.347 Q 321.285 423.285 321.285 419.95 L 321.285 419.95 L 321.285 419.95 Q 321.285 417.317 319.705 415.474 L 319.705 415.474 L 319.705 415.474 Q 318.125 413.631 314.966 411.174 L 314.966 411.174 L 314.966 411.174 Q 312.245 408.98 310.621 407.356 L 310.621 407.356 L 310.621 407.356 Q 308.998 405.732 307.813 403.319 L 307.813 403.319 L 307.813 403.319 Q 306.628 400.905 306.628 397.746 L 306.628 397.746 L 306.628 397.746 Q 306.628 393.095 309.744 390.067 L 309.744 390.067 L 309.744 390.067 Q 312.859 387.039 318.125 387.039 L 318.125 387.039 L 325.76 387.039 L 325.76 392.305 L 319.441 392.305 L 319.441 392.305 Q 313.21 392.305 313.21 398.185 L 313.21 398.185 L 313.21 398.185 Q 313.21 400.467 314.615 402.134 L 314.615 402.134 L 314.615 402.134 Q 316.019 403.802 319.003 406.083 L 319.003 406.083 L 319.003 406.083 Q 321.723 408.19 323.479 409.901 L 323.479 409.901 L 323.479 409.901 Q 325.234 411.613 326.463 414.202 L 326.463 414.202 L 326.463 414.202 Q 327.691 416.791 327.691 420.301 L 327.691 420.301 L 327.691 420.301 Q 327.691 426.532 324.4 429.604 L 324.4 429.604 L 324.4 429.604 Q 321.109 432.676 315.141 432.676 L 315.141 432.676 L 306.628 432.676 Z M 342.611 379.579 L 335.59 379.579 L 335.59 372.558 L 342.611 372.558 L 342.611 379.579 Z M 342.611 432.676 L 335.59 432.676 L 335.59 387.039 L 342.611 387.039 L 342.611 432.676 Z M 356.126 432.676 L 348.754 432.676 L 361.392 409.77 L 349.632 387.039 L 356.39 387.039 L 364.639 403.187 L 372.977 387.039 L 379.735 387.039 L 367.974 409.77 L 380.612 432.676 L 373.24 432.676 L 364.639 416.001 L 356.126 432.676 Z " fill="rgb(49,79,128)"/></g></g></g></svg>
|
||||||
|
After Width: | Height: | Size: 3.6 KiB |
8
assets/manifests/default.yaml
Normal file
8
assets/manifests/default.yaml
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
---
|
||||||
|
init: srv.init
|
||||||
|
programs:
|
||||||
|
- name: panic.serial
|
||||||
|
target: kernel
|
||||||
|
flags: panic
|
||||||
|
- name: srv.logger
|
||||||
|
- name: drv.uart
|
||||||
9
assets/manifests/test.yaml
Normal file
9
assets/manifests/test.yaml
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
---
|
||||||
|
init: srv.init
|
||||||
|
flags: ["test"]
|
||||||
|
programs:
|
||||||
|
- name: panic.serial
|
||||||
|
target: kernel
|
||||||
|
flags: panic
|
||||||
|
- name: drv.uart
|
||||||
|
- name: test_runner
|
||||||
Binary file not shown.
BIN
assets/ovmf/x64/ovmf_code.fd
Normal file
BIN
assets/ovmf/x64/ovmf_code.fd
Normal file
Binary file not shown.
BIN
assets/ovmf/x64/ovmf_vars.fd
Normal file
BIN
assets/ovmf/x64/ovmf_vars.fd
Normal file
Binary file not shown.
BIN
assets/ovmf/x64/ovmf_vars_d.fd
Normal file
BIN
assets/ovmf/x64/ovmf_vars_d.fd
Normal file
Binary file not shown.
39
configs/base.yaml
Normal file
39
configs/base.yaml
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
---
|
||||||
|
variables:
|
||||||
|
cc: "${source_root}/sysroot/bin/clang"
|
||||||
|
cxx: "${source_root}/sysroot/bin/clang++"
|
||||||
|
ld: "${source_root}/sysroot/bin/ld.lld"
|
||||||
|
ar: ar
|
||||||
|
nasm: nasm
|
||||||
|
objcopy: objcopy
|
||||||
|
|
||||||
|
ccflags: [
|
||||||
|
"-I${source_root}/src/include",
|
||||||
|
"-I${source_root}/src/include/x86_64",
|
||||||
|
"-fcolor-diagnostics",
|
||||||
|
"-U__STDCPP_THREADS__",
|
||||||
|
"-D_LIBCPP_HAS_NO_THREADS",
|
||||||
|
"-DVERSION_MAJOR=${version_major}",
|
||||||
|
"-DVERSION_MINOR=${version_minor}",
|
||||||
|
"-DVERSION_PATCH=${version_patch}",
|
||||||
|
"-DVERSION_GITSHA=0x${version_sha}",
|
||||||
|
'-DGIT_VERSION=\"${version_major}.${version_minor}.${version_patch}+${version_sha}\"',
|
||||||
|
'-DGIT_VERSION_WIDE=L\"${version_major}.${version_minor}.${version_patch}+${version_sha}\"',
|
||||||
|
|
||||||
|
"-Wformat=2", "-Winit-self", "-Wfloat-equal", "-Winline", "-Wmissing-format-attribute",
|
||||||
|
"-Wmissing-include-dirs", "-Wswitch", "-Wundef", "-Wdisabled-optimization",
|
||||||
|
"-Wpointer-arith", "-Wno-attributes", "-Wno-sign-compare", "-Wno-multichar",
|
||||||
|
"-Wno-div-by-zero", "-Wno-endif-labels", "-Wno-pragmas", "-Wno-format-extra-args",
|
||||||
|
"-Wno-unused-result", "-Wno-deprecated-declarations", "-Wno-unused-function",
|
||||||
|
"-Wno-address-of-packed-member", "-Wno-invalid-offsetof", "-Wno-format-nonliteral",
|
||||||
|
"-Werror" ]
|
||||||
|
|
||||||
|
asflags: [
|
||||||
|
"-DVERSION_MAJOR=${version_major}",
|
||||||
|
"-DVERSION_MINOR=${version_minor}",
|
||||||
|
"-DVERSION_PATCH=${version_patch}",
|
||||||
|
"-DVERSION_GITSHA=0x${version_sha}",
|
||||||
|
"-I${source_root}/src/include" ]
|
||||||
|
|
||||||
|
cflags: [ "-std=c11" ]
|
||||||
|
cxxflags: [ "-std=c++17" ]
|
||||||
30
configs/boot-debug.yaml
Normal file
30
configs/boot-debug.yaml
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
---
|
||||||
|
extends: base
|
||||||
|
|
||||||
|
variables:
|
||||||
|
ld: clang++
|
||||||
|
|
||||||
|
ccflags: [
|
||||||
|
"-nostdlib",
|
||||||
|
"-nodefaultlibs",
|
||||||
|
"-fno-builtin",
|
||||||
|
|
||||||
|
"-I${source_root}/external",
|
||||||
|
"--target=x86_64-unknown-windows",
|
||||||
|
"-ffreestanding",
|
||||||
|
"-mno-red-zone",
|
||||||
|
"-fshort-wchar",
|
||||||
|
"-fno-omit-frame-pointer",
|
||||||
|
"-ggdb",
|
||||||
|
"-g3" ]
|
||||||
|
|
||||||
|
cxxflags: [ "-fno-exceptions", "-fno-rtti" ]
|
||||||
|
|
||||||
|
ldflags: [
|
||||||
|
"--target=x86_64-unknown-windows",
|
||||||
|
"-nostdlib",
|
||||||
|
"-Wl,-entry:efi_main",
|
||||||
|
"-Wl,-subsystem:efi_application",
|
||||||
|
"-fuse-ld=lld-link",
|
||||||
|
"-g" ]
|
||||||
|
|
||||||
55
configs/kernel-debug.yaml
Normal file
55
configs/kernel-debug.yaml
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
---
|
||||||
|
extends: base
|
||||||
|
|
||||||
|
variables:
|
||||||
|
asflags: [ "-I${source_root}/src/kernel/" ]
|
||||||
|
|
||||||
|
ccflags: [
|
||||||
|
"--target=x86_64-jsix-elf",
|
||||||
|
"-fno-stack-protector",
|
||||||
|
|
||||||
|
"-I${source_root}/external",
|
||||||
|
|
||||||
|
"-nostdinc",
|
||||||
|
"-nostdlib",
|
||||||
|
"-ffreestanding",
|
||||||
|
"-nodefaultlibs",
|
||||||
|
"-fno-builtin",
|
||||||
|
|
||||||
|
"-mno-sse",
|
||||||
|
"-fno-omit-frame-pointer",
|
||||||
|
"-mno-red-zone",
|
||||||
|
"-mcmodel=kernel",
|
||||||
|
|
||||||
|
"-g3",
|
||||||
|
"-ggdb",
|
||||||
|
|
||||||
|
"-D__ELF__",
|
||||||
|
"-D__jsix__",
|
||||||
|
"-D__j6kernel",
|
||||||
|
"-U__linux",
|
||||||
|
"-U__linux__",
|
||||||
|
"-DPRINTF_ALIAS_STANDARD_FUNCTION_NAMES=1",
|
||||||
|
"-DPRINTF_INCLUDE_CONFIG_H=1",
|
||||||
|
|
||||||
|
"-isystem${build_root}/include/libc",
|
||||||
|
"-isystem${source_root}/sysroot/include",
|
||||||
|
"--sysroot='${source_root}/sysroot'" ]
|
||||||
|
|
||||||
|
|
||||||
|
cflags: [ '-nostdinc' ]
|
||||||
|
|
||||||
|
cxxflags: [
|
||||||
|
"-fno-exceptions",
|
||||||
|
"-fno-rtti",
|
||||||
|
"-nostdinc",
|
||||||
|
"-isystem${source_root}/sysroot/include/c++/v1" ]
|
||||||
|
|
||||||
|
ldflags: [
|
||||||
|
"-g",
|
||||||
|
"-nostdlib",
|
||||||
|
"-Bstatic",
|
||||||
|
"--no-eh-frame-hdr",
|
||||||
|
"-z", "norelro",
|
||||||
|
"-z", "separate-code" ]
|
||||||
|
|
||||||
81
configs/rules.ninja
Normal file
81
configs/rules.ninja
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
# This file is automatically generated by bonnibel
|
||||||
|
|
||||||
|
rule compile.c
|
||||||
|
command = $cc -MMD -MF $out.d $cflags $ccflags -o $out -c $in
|
||||||
|
description = Compiling $name
|
||||||
|
depfile = $out.d
|
||||||
|
deps = gcc
|
||||||
|
|
||||||
|
rule dump_c_defs
|
||||||
|
command = echo | $cc $ccflags $cflags -dM -E - > $out
|
||||||
|
description = Dumping C defines for $target
|
||||||
|
|
||||||
|
rule dump_c_run
|
||||||
|
command = echo '#!/bin/bash' > $out; echo '$cc $ccflags $cflags $$*' >> $
|
||||||
|
$out; chmod a+x $out
|
||||||
|
description = Dumping C arguments for $target
|
||||||
|
|
||||||
|
rule compile.cpp
|
||||||
|
command = $cxx -MMD -MF $out.d $cxxflags $ccflags -o $out -c $in
|
||||||
|
description = Compiling $name
|
||||||
|
depfile = $out.d
|
||||||
|
deps = gcc
|
||||||
|
|
||||||
|
rule dump_cpp_defs
|
||||||
|
command = echo | $cxx -x c++ $ccflags $cxxflags -dM -E - > $out
|
||||||
|
description = Dumping C++ defines for $target
|
||||||
|
|
||||||
|
rule dump_cpp_run
|
||||||
|
command = echo '#!/bin/bash' > $out; echo '$cxx $ccflags $cxxflags $$*' $
|
||||||
|
>> $out; chmod a+x $out
|
||||||
|
description = Dumping C++ arguments for $target
|
||||||
|
|
||||||
|
rule compile.s
|
||||||
|
command = $nasm -o $out -felf64 -MD $out.d $asflags $in
|
||||||
|
description = Assembling $name
|
||||||
|
depfile = $out.d
|
||||||
|
deps = gcc
|
||||||
|
|
||||||
|
rule parse.cog
|
||||||
|
command = cog -o $out -d -D target=$target $cogflags $in
|
||||||
|
description = Parsing $name
|
||||||
|
|
||||||
|
rule exe
|
||||||
|
command = $ld $ldflags -o $out $in $libs
|
||||||
|
description = Linking $name
|
||||||
|
|
||||||
|
rule lib
|
||||||
|
command = $ar qcs $out $in
|
||||||
|
description = Archiving $name
|
||||||
|
|
||||||
|
rule cp
|
||||||
|
command = cp $in $out
|
||||||
|
description = Copying $name
|
||||||
|
|
||||||
|
rule dump
|
||||||
|
command = objdump -DSC -M intel $in > $out
|
||||||
|
description = Dumping decompiled $name
|
||||||
|
|
||||||
|
rule makest
|
||||||
|
description = Making symbol table
|
||||||
|
command = nm -n -S --demangle $in | ${source_root}/scripts/build_symbol_table.py $out
|
||||||
|
|
||||||
|
rule makefat
|
||||||
|
description = Creating $name
|
||||||
|
command = $
|
||||||
|
cp $in $out; $
|
||||||
|
mcopy -s -D o -i $out@@1M ${build_root}/fatroot/* ::/
|
||||||
|
|
||||||
|
rule strip
|
||||||
|
description = Stripping $name
|
||||||
|
command = $
|
||||||
|
cp $in $out; $
|
||||||
|
objcopy --only-keep-debug $out $debug; $
|
||||||
|
strip -g $out; $
|
||||||
|
objcopy --add-gnu-debuglink=$debug $out
|
||||||
|
|
||||||
|
rule touch
|
||||||
|
command = touch $out
|
||||||
|
|
||||||
|
rule compdb
|
||||||
|
command = ninja -t compdb > $out
|
||||||
39
configs/user-debug.yaml
Normal file
39
configs/user-debug.yaml
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
---
|
||||||
|
extends: base
|
||||||
|
|
||||||
|
variables:
|
||||||
|
asflags: [ "-I${source_root}/src/kernel/" ]
|
||||||
|
|
||||||
|
ccflags: [
|
||||||
|
"--target=x86_64-jsix-elf",
|
||||||
|
"-mno-sse",
|
||||||
|
"-fno-omit-frame-pointer",
|
||||||
|
"-fno-stack-protector",
|
||||||
|
|
||||||
|
"-g",
|
||||||
|
|
||||||
|
"-D__ELF__",
|
||||||
|
"-D__jsix__",
|
||||||
|
"-U__linux",
|
||||||
|
"-U__linux__",
|
||||||
|
|
||||||
|
"-isystem${source_root}/sysroot/include",
|
||||||
|
"-isystem${build_root}/include/libc",
|
||||||
|
"--sysroot='${source_root}/sysroot'" ]
|
||||||
|
|
||||||
|
|
||||||
|
cxxflags: [
|
||||||
|
"-fno-exceptions",
|
||||||
|
"-fno-rtti",
|
||||||
|
"-isystem${source_root}/sysroot/include/c++/v1" ]
|
||||||
|
|
||||||
|
ldflags: [
|
||||||
|
"-g",
|
||||||
|
"-Bstatic",
|
||||||
|
"--sysroot='${source_root}/sysroot'",
|
||||||
|
"-L", "${source_root}/sysroot/lib",
|
||||||
|
"-z", "separate-code",
|
||||||
|
"-lc++", "-lc++abi", "-lunwind",
|
||||||
|
"--no-dependent-libraries",
|
||||||
|
]
|
||||||
|
|
||||||
70
configure
vendored
Executable file
70
configure
vendored
Executable file
@@ -0,0 +1,70 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
def generate(output, config, manifest):
|
||||||
|
from os import makedirs, walk
|
||||||
|
from pathlib import Path
|
||||||
|
from bonnibel.module import Module
|
||||||
|
from bonnibel.project import Project
|
||||||
|
|
||||||
|
root = Path(__file__).parent.resolve()
|
||||||
|
project = Project(root)
|
||||||
|
|
||||||
|
output = root / output
|
||||||
|
sources = root / "src"
|
||||||
|
manifest = root / manifest
|
||||||
|
|
||||||
|
modules = {}
|
||||||
|
for base, dirs, files in walk(sources):
|
||||||
|
path = Path(base)
|
||||||
|
for f in files:
|
||||||
|
if f.endswith(".module"):
|
||||||
|
fullpath = path / f
|
||||||
|
|
||||||
|
def module_init(name, **kwargs):
|
||||||
|
m = Module(name, fullpath, path, **kwargs)
|
||||||
|
modules[m.name] = m
|
||||||
|
return m
|
||||||
|
|
||||||
|
glo = {
|
||||||
|
"module": module_init,
|
||||||
|
"source_root": root,
|
||||||
|
"built_root": output,
|
||||||
|
"module_root": path,
|
||||||
|
}
|
||||||
|
code = compile(open(fullpath, 'r').read(), fullpath, "exec")
|
||||||
|
|
||||||
|
loc = {}
|
||||||
|
exec(code, glo, loc)
|
||||||
|
|
||||||
|
Module.update(modules)
|
||||||
|
|
||||||
|
makedirs(output.resolve(), exist_ok=True)
|
||||||
|
project.generate(root, output, modules, config, manifest)
|
||||||
|
for mod in modules.values():
|
||||||
|
mod.generate(output)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
import sys
|
||||||
|
from pathlib import Path
|
||||||
|
sys.path.insert(0, str(Path(__file__).parent / "scripts"))
|
||||||
|
|
||||||
|
from argparse import ArgumentParser
|
||||||
|
from bonnibel import BonnibelError
|
||||||
|
|
||||||
|
p = ArgumentParser(description="Generate jsix build files")
|
||||||
|
p.add_argument("--manifest", "-m", metavar="FILE", default="assets/manifests/default.yaml",
|
||||||
|
help="File to use as the system manifest")
|
||||||
|
p.add_argument("--config", "-c", metavar="NAME", default="debug",
|
||||||
|
help="Configuration to build (eg, 'debug' or 'release')")
|
||||||
|
p.add_argument("output", metavar="DIR", default="build", nargs='?',
|
||||||
|
help="Where to create the build root")
|
||||||
|
|
||||||
|
args = p.parse_args()
|
||||||
|
|
||||||
|
try:
|
||||||
|
generate(args.output, args.config, args.manifest)
|
||||||
|
|
||||||
|
except BonnibelError as be:
|
||||||
|
import sys
|
||||||
|
print(f"Error: {be}", file=sys.stderr)
|
||||||
|
sys.exit(1)
|
||||||
20
definitions/memory_layout.yaml
Normal file
20
definitions/memory_layout.yaml
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
---
|
||||||
|
- name: linear
|
||||||
|
size: 64T
|
||||||
|
shared: true
|
||||||
|
|
||||||
|
- name: bitmap
|
||||||
|
size: 1T
|
||||||
|
shared: true
|
||||||
|
|
||||||
|
- name: heap
|
||||||
|
size: 64G
|
||||||
|
|
||||||
|
- name: stacks
|
||||||
|
size: 64G
|
||||||
|
|
||||||
|
- name: buffers
|
||||||
|
size: 64G
|
||||||
|
|
||||||
|
- name: slabs
|
||||||
|
size: 64G
|
||||||
21
definitions/objects/channel.def
Normal file
21
definitions/objects/channel.def
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
object channel : object {
|
||||||
|
uid 3ea38b96aa0e54c8
|
||||||
|
|
||||||
|
capabilities [
|
||||||
|
send
|
||||||
|
receive
|
||||||
|
close
|
||||||
|
]
|
||||||
|
|
||||||
|
method create [constructor]
|
||||||
|
method close [destructor cap:close]
|
||||||
|
|
||||||
|
method send [cap:send] {
|
||||||
|
param data buffer [inout]
|
||||||
|
}
|
||||||
|
|
||||||
|
method receive [cap:receive] {
|
||||||
|
param data buffer [out]
|
||||||
|
param flags uint64
|
||||||
|
}
|
||||||
|
}
|
||||||
22
definitions/objects/event.def
Normal file
22
definitions/objects/event.def
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
object event : object {
|
||||||
|
uid f441e03da5516b1a
|
||||||
|
|
||||||
|
capabilities [
|
||||||
|
signal
|
||||||
|
wait
|
||||||
|
]
|
||||||
|
|
||||||
|
method create [constructor]
|
||||||
|
|
||||||
|
# Signal events on this object
|
||||||
|
method signal [cap:signal] {
|
||||||
|
param signals uint64 # A bitset of which events to signal
|
||||||
|
}
|
||||||
|
|
||||||
|
# Wait for signaled events on this object
|
||||||
|
method wait [cap:wait] {
|
||||||
|
param signals uint64 [out] # A bitset of which events were signaled
|
||||||
|
param timeout uint64 # Wait timeout in nanoseconds
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
65
definitions/objects/mailbox.def
Normal file
65
definitions/objects/mailbox.def
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
# Mailboxes are objects that enable synchronous or asynchronous
|
||||||
|
# IPC via short message-passing of bytes and handles.
|
||||||
|
|
||||||
|
object mailbox : object {
|
||||||
|
uid 99934ad04ece1e07
|
||||||
|
|
||||||
|
capabilities [
|
||||||
|
send
|
||||||
|
receive
|
||||||
|
close
|
||||||
|
]
|
||||||
|
|
||||||
|
method create [constructor]
|
||||||
|
method close [destructor cap:close]
|
||||||
|
|
||||||
|
# Asynchronously send a message to the reciever
|
||||||
|
method send [cap:send handle] {
|
||||||
|
param tag uint64
|
||||||
|
param data buffer [zero_ok]
|
||||||
|
param handles ref object [list]
|
||||||
|
}
|
||||||
|
|
||||||
|
# Receive a pending message, or block waiting for a message to
|
||||||
|
# arrive if block is true.
|
||||||
|
method receive [cap:receive] {
|
||||||
|
param tag uint64 [out]
|
||||||
|
param data buffer [out zero_ok]
|
||||||
|
param handles ref object [out list zero_ok]
|
||||||
|
param reply_tag uint16 [out optional]
|
||||||
|
param badge uint64 [out optional]
|
||||||
|
param flags uint64
|
||||||
|
}
|
||||||
|
|
||||||
|
# Send a message to the reciever, and block until a
|
||||||
|
# response is sent. Note that getting this response
|
||||||
|
# does not require the receive capability.
|
||||||
|
method call [cap:send handle] {
|
||||||
|
param tag uint64 [inout]
|
||||||
|
param data buffer [inout zero_ok]
|
||||||
|
param handles ref object [inout list zero_ok]
|
||||||
|
}
|
||||||
|
|
||||||
|
# Respond to a message sent using call. Note that this
|
||||||
|
# requires the receive capability and not the send capability.
|
||||||
|
method respond [cap:receive] {
|
||||||
|
param tag uint64
|
||||||
|
param data buffer [zero_ok]
|
||||||
|
param handles ref object [list zero_ok]
|
||||||
|
param reply_tag uint16
|
||||||
|
}
|
||||||
|
|
||||||
|
# Respond to a message sent using call, and wait for another
|
||||||
|
# message to arrive. Note that this does not require the send
|
||||||
|
# capability.
|
||||||
|
method respond_receive [cap:receive] {
|
||||||
|
param tag uint64 [inout]
|
||||||
|
param data buffer [inout zero_ok]
|
||||||
|
param data_in size
|
||||||
|
param handles ref object [inout list zero_ok]
|
||||||
|
param handles_in size
|
||||||
|
param reply_tag uint16 [inout]
|
||||||
|
param badge uint64 [out optional]
|
||||||
|
param flags uint64
|
||||||
|
}
|
||||||
|
}
|
||||||
14
definitions/objects/object.def
Normal file
14
definitions/objects/object.def
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
# The base type of all kernel-exposed objects
|
||||||
|
object object [virtual] {
|
||||||
|
uid 667f61fb2cd57bb4
|
||||||
|
cname kobject
|
||||||
|
|
||||||
|
capabilities [
|
||||||
|
clone
|
||||||
|
]
|
||||||
|
|
||||||
|
# Get the internal kernel object id of an object
|
||||||
|
method koid {
|
||||||
|
param koid uint64 [out]
|
||||||
|
}
|
||||||
|
}
|
||||||
31
definitions/objects/process.def
Normal file
31
definitions/objects/process.def
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
import "objects/object.def"
|
||||||
|
|
||||||
|
# Processes are a collection of handles and a virtual memory
|
||||||
|
# space inside which threads are run.
|
||||||
|
|
||||||
|
object process : object {
|
||||||
|
uid 0c69ee0b7502ba31
|
||||||
|
|
||||||
|
capabilities [
|
||||||
|
kill
|
||||||
|
create_thread
|
||||||
|
]
|
||||||
|
|
||||||
|
# Create a new empty process
|
||||||
|
method create [constructor]
|
||||||
|
|
||||||
|
# Stop all threads and exit the given process
|
||||||
|
method kill [destructor cap:kill]
|
||||||
|
|
||||||
|
# Stop all threads and exit the current process
|
||||||
|
method exit [static noreturn] {
|
||||||
|
param result int32 # The result to retrun to the parent process
|
||||||
|
}
|
||||||
|
|
||||||
|
# Give the given process a handle that points to the same
|
||||||
|
# object as the specified handle.
|
||||||
|
method give_handle {
|
||||||
|
param target ref object [handle] # A handle in the caller process to send
|
||||||
|
param received ref object [out optional] # The handle as the recipient will see it
|
||||||
|
}
|
||||||
|
}
|
||||||
40
definitions/objects/system.def
Normal file
40
definitions/objects/system.def
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
# The system object represents a handle to kernel functionality
|
||||||
|
# needed by drivers and other priviledged services
|
||||||
|
object system : object {
|
||||||
|
uid fa72506a2cf71a30
|
||||||
|
|
||||||
|
capabilities [
|
||||||
|
get_log
|
||||||
|
bind_irq
|
||||||
|
map_phys
|
||||||
|
change_iopl
|
||||||
|
]
|
||||||
|
|
||||||
|
# Get a log line from the kernel log
|
||||||
|
method get_log [cap:get_log] {
|
||||||
|
param buffer buffer [out zero_ok] # Buffer for the log message data structure
|
||||||
|
}
|
||||||
|
|
||||||
|
# Ask the kernel to send this process messages whenever
|
||||||
|
# the given IRQ fires
|
||||||
|
method bind_irq [cap:bind_irq] {
|
||||||
|
param dest ref event # Event object that will receive messages
|
||||||
|
param irq uint # IRQ number to bind
|
||||||
|
param signal uint # Signal number on the event to bind to
|
||||||
|
}
|
||||||
|
|
||||||
|
# Create a VMA and map an area of physical memory into it,
|
||||||
|
# also mapping that VMA into the current process
|
||||||
|
method map_phys [cap:map_phys] {
|
||||||
|
param area ref vma [out] # Receives a handle to the VMA created
|
||||||
|
param phys address # The physical address of the area
|
||||||
|
param size size # Size of the area, in pages
|
||||||
|
param flags uint32 # Flags to apply to the created VMA
|
||||||
|
}
|
||||||
|
|
||||||
|
# Request the kernel change the IOPL for this process. The only values
|
||||||
|
# that make sense are 0 and 3.
|
||||||
|
method request_iopl [cap:change_iopl] {
|
||||||
|
param iopl uint # The IOPL to set for this process
|
||||||
|
}
|
||||||
|
}
|
||||||
23
definitions/objects/thread.def
Normal file
23
definitions/objects/thread.def
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
object thread : object {
|
||||||
|
uid 11f23e593d5761bd
|
||||||
|
|
||||||
|
capabilities [
|
||||||
|
kill
|
||||||
|
]
|
||||||
|
|
||||||
|
method create [constructor] {
|
||||||
|
param process ref process [cap:create_thread]
|
||||||
|
param stack_top address
|
||||||
|
param entrypoint address
|
||||||
|
}
|
||||||
|
|
||||||
|
method kill [destructor cap:kill]
|
||||||
|
|
||||||
|
method exit [static] {
|
||||||
|
param status int32
|
||||||
|
}
|
||||||
|
|
||||||
|
method sleep [static] {
|
||||||
|
param duration uint64
|
||||||
|
}
|
||||||
|
}
|
||||||
36
definitions/objects/vma.def
Normal file
36
definitions/objects/vma.def
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
import "objects/process.def"
|
||||||
|
|
||||||
|
object vma : object {
|
||||||
|
uid d6a12b63b3ed3937
|
||||||
|
cname vm_area
|
||||||
|
|
||||||
|
capabilities [
|
||||||
|
map
|
||||||
|
unmap
|
||||||
|
resize
|
||||||
|
]
|
||||||
|
|
||||||
|
method create [constructor] {
|
||||||
|
param size size
|
||||||
|
param flags uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
method create_map [constructor cap:map] {
|
||||||
|
param size size
|
||||||
|
param address address
|
||||||
|
param flags uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
method map [cap:map] {
|
||||||
|
param process ref process
|
||||||
|
param address address
|
||||||
|
}
|
||||||
|
|
||||||
|
method unmap [cap:unmap] {
|
||||||
|
param process ref process
|
||||||
|
}
|
||||||
|
|
||||||
|
method resize [cap:resize] {
|
||||||
|
param size size [inout]
|
||||||
|
}
|
||||||
|
}
|
||||||
50
definitions/syscalls.def
Normal file
50
definitions/syscalls.def
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
import "objects/object.def"
|
||||||
|
|
||||||
|
import "objects/channel.def"
|
||||||
|
import "objects/event.def"
|
||||||
|
import "objects/mailbox.def"
|
||||||
|
import "objects/process.def"
|
||||||
|
import "objects/system.def"
|
||||||
|
import "objects/thread.def"
|
||||||
|
import "objects/vma.def"
|
||||||
|
|
||||||
|
interface syscalls [syscall] {
|
||||||
|
uid 01d9b6a948961097
|
||||||
|
|
||||||
|
expose ref object
|
||||||
|
expose ref system
|
||||||
|
expose ref event
|
||||||
|
expose ref process
|
||||||
|
expose ref thread
|
||||||
|
expose ref mailbox
|
||||||
|
expose ref channel
|
||||||
|
expose ref vma
|
||||||
|
|
||||||
|
# Simple no-op syscall for testing
|
||||||
|
function noop
|
||||||
|
|
||||||
|
# Write a message to the kernel log
|
||||||
|
function log {
|
||||||
|
param message string
|
||||||
|
}
|
||||||
|
|
||||||
|
# Get a list of handles owned by this process. If the
|
||||||
|
# supplied list is not big enough, will set the size
|
||||||
|
# needed in `size` and return j6_err_insufficient
|
||||||
|
function handle_list {
|
||||||
|
param handles ref object [list inout zero_ok] # A list of handles to be filled
|
||||||
|
}
|
||||||
|
|
||||||
|
# Create a clone of an existing handle, possibly with
|
||||||
|
# some capabilities masked out.
|
||||||
|
function handle_clone {
|
||||||
|
param orig ref object [handle cap:clone] # The handle to clone
|
||||||
|
param clone ref object [out] # The new handle
|
||||||
|
param mask uint32 # The capability bitmask
|
||||||
|
}
|
||||||
|
|
||||||
|
# Testing mode only: Have the kernel finish and exit QEMU with the given exit code
|
||||||
|
function test_finish [test] {
|
||||||
|
param exit_code uint32
|
||||||
|
}
|
||||||
|
}
|
||||||
34
definitions/sysconf.yaml
Normal file
34
definitions/sysconf.yaml
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
---
|
||||||
|
address: 0x6a360000
|
||||||
|
vars:
|
||||||
|
- name: version_major
|
||||||
|
section: kernel
|
||||||
|
type: uint8_t
|
||||||
|
|
||||||
|
- name: version_minor
|
||||||
|
section: kernel
|
||||||
|
type: uint8_t
|
||||||
|
|
||||||
|
- name: version_patch
|
||||||
|
section: kernel
|
||||||
|
type: uint16_t
|
||||||
|
|
||||||
|
- name: version_gitsha
|
||||||
|
section: kernel
|
||||||
|
type: uint32_t
|
||||||
|
|
||||||
|
- name: page_size
|
||||||
|
section: sys
|
||||||
|
type: size_t
|
||||||
|
|
||||||
|
- name: large_page_size
|
||||||
|
section: sys
|
||||||
|
type: size_t
|
||||||
|
|
||||||
|
- name: huge_page_size
|
||||||
|
section: sys
|
||||||
|
type: size_t
|
||||||
|
|
||||||
|
- name: num_cpus
|
||||||
|
section: sys
|
||||||
|
type: uint32_t
|
||||||
17802
external/catch/catch.hpp
vendored
Normal file
17802
external/catch/catch.hpp
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1
external/gnu-efi
vendored
1
external/gnu-efi
vendored
Submodule external/gnu-efi deleted from fc5af9e47f
103
external/uefi/boot_services.h
vendored
Normal file
103
external/uefi/boot_services.h
vendored
Normal file
@@ -0,0 +1,103 @@
|
|||||||
|
#pragma once
|
||||||
|
#ifndef _uefi_boot_services_h_
|
||||||
|
#define _uefi_boot_services_h_
|
||||||
|
|
||||||
|
// This Source Code Form is part of the j6-uefi-headers project and is subject
|
||||||
|
// to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was
|
||||||
|
// not distributed with this file, You can obtain one at
|
||||||
|
// http://mozilla.org/MPL/2.0/.
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <uefi/tables.h>
|
||||||
|
#include <uefi/types.h>
|
||||||
|
|
||||||
|
namespace uefi {
|
||||||
|
namespace bs_impl {
|
||||||
|
using allocate_pages = status (*)(allocate_type, memory_type, size_t, void**);
|
||||||
|
using free_pages = status (*)(void*, size_t);
|
||||||
|
using get_memory_map = status (*)(size_t*, memory_descriptor*, size_t*, size_t*, uint32_t*);
|
||||||
|
using allocate_pool = status (*)(memory_type, uint64_t, void**);
|
||||||
|
using free_pool = status (*)(void*);
|
||||||
|
using handle_protocol = status (*)(handle, const guid*, void**);
|
||||||
|
using create_event = status (*)(evt, tpl, event_notify, void*, event*);
|
||||||
|
using exit_boot_services = status (*)(handle, size_t);
|
||||||
|
using locate_protocol = status (*)(const guid*, void*, void**);
|
||||||
|
using copy_mem = void (*)(void*, void*, size_t);
|
||||||
|
using set_mem = void (*)(void*, uint64_t, uint8_t);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct boot_services {
|
||||||
|
static constexpr uint64_t signature = 0x56524553544f4f42ull;
|
||||||
|
|
||||||
|
table_header header;
|
||||||
|
|
||||||
|
// Task Priority Level management
|
||||||
|
void *raise_tpl;
|
||||||
|
void *restore_tpl;
|
||||||
|
|
||||||
|
// Memory Services
|
||||||
|
bs_impl::allocate_pages allocate_pages;
|
||||||
|
bs_impl::free_pages free_pages;
|
||||||
|
bs_impl::get_memory_map get_memory_map;
|
||||||
|
bs_impl::allocate_pool allocate_pool;
|
||||||
|
bs_impl::free_pool free_pool;
|
||||||
|
|
||||||
|
// Event & Timer Services
|
||||||
|
bs_impl::create_event create_event;
|
||||||
|
void *set_timer;
|
||||||
|
void *wait_for_event;
|
||||||
|
void *signal_event;
|
||||||
|
void *close_event;
|
||||||
|
void *check_event;
|
||||||
|
|
||||||
|
// Protocol Handler Services
|
||||||
|
void *install_protocol_interface;
|
||||||
|
void *reinstall_protocol_interface;
|
||||||
|
void *uninstall_protocol_interface;
|
||||||
|
bs_impl::handle_protocol handle_protocol;
|
||||||
|
void *_reserved;
|
||||||
|
void *register_protocol_notify;
|
||||||
|
void *locate_handle;
|
||||||
|
void *locate_device_path;
|
||||||
|
void *install_configuration_table;
|
||||||
|
|
||||||
|
// Image Services
|
||||||
|
void *load_image;
|
||||||
|
void *start_image;
|
||||||
|
void *exit;
|
||||||
|
void *unload_image;
|
||||||
|
bs_impl::exit_boot_services exit_boot_services;
|
||||||
|
|
||||||
|
// Miscellaneous Services
|
||||||
|
void *get_next_monotonic_count;
|
||||||
|
void *stall;
|
||||||
|
void *set_watchdog_timer;
|
||||||
|
|
||||||
|
// DriverSupport Services
|
||||||
|
void *connect_controller;
|
||||||
|
void *disconnect_controller;
|
||||||
|
|
||||||
|
// Open and Close Protocol Services
|
||||||
|
void *open_protocol;
|
||||||
|
void *close_protocol;
|
||||||
|
void *open_protocol_information;
|
||||||
|
|
||||||
|
// Library Services
|
||||||
|
void *protocols_per_handle;
|
||||||
|
void *locate_handle_buffer;
|
||||||
|
bs_impl::locate_protocol locate_protocol;
|
||||||
|
void *install_multiple_protocol_interfaces;
|
||||||
|
void *uninstall_multiple_protocol_interfaces;
|
||||||
|
|
||||||
|
// 32-bit CRC Services
|
||||||
|
void *calculate_crc32;
|
||||||
|
|
||||||
|
// Miscellaneous Services
|
||||||
|
bs_impl::copy_mem copy_mem;
|
||||||
|
bs_impl::set_mem set_mem;
|
||||||
|
void *create_event_ex;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace uefi
|
||||||
|
|
||||||
|
#endif
|
||||||
39
external/uefi/errors.inc
vendored
Normal file
39
external/uefi/errors.inc
vendored
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
STATUS_WARNING( warn_unknown_glyph, 1)
|
||||||
|
STATUS_WARNING( warn_delete_failure, 2)
|
||||||
|
STATUS_WARNING( warn_write_failure, 3)
|
||||||
|
STATUS_WARNING( warn_buffer_too_small,4)
|
||||||
|
STATUS_WARNING( warn_stale_data, 5)
|
||||||
|
STATUS_WARNING( warn_file_system, 6)
|
||||||
|
|
||||||
|
STATUS_ERROR( load_error, 1)
|
||||||
|
STATUS_ERROR( invalid_parameter, 2)
|
||||||
|
STATUS_ERROR( unsupported, 3)
|
||||||
|
STATUS_ERROR( bad_buffer_size, 4)
|
||||||
|
STATUS_ERROR( buffer_too_small, 5)
|
||||||
|
STATUS_ERROR( not_ready, 6)
|
||||||
|
STATUS_ERROR( device_error, 7)
|
||||||
|
STATUS_ERROR( write_protected, 8)
|
||||||
|
STATUS_ERROR( out_of_resources, 9)
|
||||||
|
STATUS_ERROR( volume_corrupted, 10)
|
||||||
|
STATUS_ERROR( volume_full, 11)
|
||||||
|
STATUS_ERROR( no_media, 12)
|
||||||
|
STATUS_ERROR( media_changed, 13)
|
||||||
|
STATUS_ERROR( not_found, 14)
|
||||||
|
STATUS_ERROR( access_denied, 15)
|
||||||
|
STATUS_ERROR( no_response, 16)
|
||||||
|
STATUS_ERROR( no_mapping, 17)
|
||||||
|
STATUS_ERROR( timeout, 18)
|
||||||
|
STATUS_ERROR( not_started, 19)
|
||||||
|
STATUS_ERROR( already_started, 20)
|
||||||
|
STATUS_ERROR( aborted, 21)
|
||||||
|
STATUS_ERROR( icmp_error, 22)
|
||||||
|
STATUS_ERROR( tftp_error, 23)
|
||||||
|
STATUS_ERROR( protocol_error, 24)
|
||||||
|
STATUS_ERROR( incompatible_version, 25)
|
||||||
|
STATUS_ERROR( security_violation, 26)
|
||||||
|
STATUS_ERROR( crc_error, 27)
|
||||||
|
STATUS_ERROR( end_of_media, 28)
|
||||||
|
STATUS_ERROR( end_of_file, 31)
|
||||||
|
STATUS_ERROR( invalid_language, 32)
|
||||||
|
STATUS_ERROR( compromised_data, 33)
|
||||||
|
STATUS_ERROR( http_error, 35)
|
||||||
92
external/uefi/graphics.h
vendored
Normal file
92
external/uefi/graphics.h
vendored
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
#pragma once
|
||||||
|
#ifndef _uefi_graphics_h_
|
||||||
|
#define _uefi_graphics_h_
|
||||||
|
|
||||||
|
// This Source Code Form is part of the j6-uefi-headers project and is subject
|
||||||
|
// to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was
|
||||||
|
// not distributed with this file, You can obtain one at
|
||||||
|
// http://mozilla.org/MPL/2.0/.
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <uefi/types.h>
|
||||||
|
|
||||||
|
namespace uefi {
|
||||||
|
|
||||||
|
struct text_output_mode
|
||||||
|
{
|
||||||
|
int32_t max_mode;
|
||||||
|
int32_t mode;
|
||||||
|
int32_t attribute;
|
||||||
|
int32_t cursor_column;
|
||||||
|
int32_t cursor_row;
|
||||||
|
bool cursor_visible;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct pixel_bitmask
|
||||||
|
{
|
||||||
|
uint32_t red_mask;
|
||||||
|
uint32_t green_mask;
|
||||||
|
uint32_t blue_mask;
|
||||||
|
uint32_t reserved_mask;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class pixel_format
|
||||||
|
{
|
||||||
|
rgb8,
|
||||||
|
bgr8,
|
||||||
|
bitmask,
|
||||||
|
blt_only
|
||||||
|
};
|
||||||
|
|
||||||
|
struct graphics_output_mode_info
|
||||||
|
{
|
||||||
|
uint32_t version;
|
||||||
|
uint32_t horizontal_resolution;
|
||||||
|
uint32_t vertical_resolution;
|
||||||
|
pixel_format pixel_format;
|
||||||
|
pixel_bitmask pixel_information;
|
||||||
|
uint32_t pixels_per_scanline;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct graphics_output_mode
|
||||||
|
{
|
||||||
|
uint32_t max_mode;
|
||||||
|
uint32_t mode;
|
||||||
|
graphics_output_mode_info *info;
|
||||||
|
uint64_t size_of_info;
|
||||||
|
uintptr_t frame_buffer_base;
|
||||||
|
uint64_t frame_buffer_size;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class attribute : uint64_t
|
||||||
|
{
|
||||||
|
black,
|
||||||
|
blue,
|
||||||
|
green,
|
||||||
|
cyan,
|
||||||
|
red,
|
||||||
|
magenta,
|
||||||
|
brown,
|
||||||
|
light_gray,
|
||||||
|
dark_gray,
|
||||||
|
light_blue,
|
||||||
|
light_green,
|
||||||
|
light_cyan,
|
||||||
|
light_red,
|
||||||
|
light_magenta,
|
||||||
|
yellow,
|
||||||
|
white,
|
||||||
|
|
||||||
|
background_black = 0x00,
|
||||||
|
background_blue = 0x10,
|
||||||
|
background_green = 0x20,
|
||||||
|
background_cyan = 0x30,
|
||||||
|
background_red = 0x40,
|
||||||
|
background_magenta = 0x50,
|
||||||
|
background_brown = 0x60,
|
||||||
|
background_light_gray = 0x70,
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace uefi
|
||||||
|
|
||||||
|
#endif
|
||||||
29
external/uefi/guid.h
vendored
Normal file
29
external/uefi/guid.h
vendored
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
#pragma once
|
||||||
|
#ifndef _uefi_guid_h_
|
||||||
|
#define _uefi_guid_h_
|
||||||
|
|
||||||
|
// This Source Code Form is part of the j6-uefi-headers project and is subject
|
||||||
|
// to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was
|
||||||
|
// not distributed with this file, You can obtain one at
|
||||||
|
// http://mozilla.org/MPL/2.0/.
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
namespace uefi {
|
||||||
|
|
||||||
|
struct guid
|
||||||
|
{
|
||||||
|
uint32_t data1;
|
||||||
|
uint16_t data2;
|
||||||
|
uint16_t data3;
|
||||||
|
uint8_t data4[8];
|
||||||
|
|
||||||
|
inline bool operator==(const guid &other) const {
|
||||||
|
return reinterpret_cast<const uint64_t*>(this)[0] == reinterpret_cast<const uint64_t*>(&other)[0]
|
||||||
|
&& reinterpret_cast<const uint64_t*>(this)[1] == reinterpret_cast<const uint64_t*>(&other)[1];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace uefi
|
||||||
|
|
||||||
|
#endif
|
||||||
390
external/uefi/networking.h
vendored
Normal file
390
external/uefi/networking.h
vendored
Normal file
@@ -0,0 +1,390 @@
|
|||||||
|
#pragma once
|
||||||
|
#ifndef _uefi_networking_h_
|
||||||
|
#define _uefi_networking_h_
|
||||||
|
|
||||||
|
// This Source Code Form is part of the j6-uefi-headers project and is subject
|
||||||
|
// to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was
|
||||||
|
// not distributed with this file, You can obtain one at
|
||||||
|
// http://mozilla.org/MPL/2.0/.
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <uefi/types.h>
|
||||||
|
|
||||||
|
namespace uefi {
|
||||||
|
|
||||||
|
//
|
||||||
|
// IPv4 definitions
|
||||||
|
//
|
||||||
|
struct ipv4_address
|
||||||
|
{
|
||||||
|
uint8_t addr[4];
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
// IPv6 definitions
|
||||||
|
//
|
||||||
|
struct ipv6_address
|
||||||
|
{
|
||||||
|
uint8_t addr[16];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ip6_address_info
|
||||||
|
{
|
||||||
|
ipv6_address address;
|
||||||
|
uint8_t prefix_length;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ip6_route_table
|
||||||
|
{
|
||||||
|
ipv6_address gateway;
|
||||||
|
ipv6_address destination;
|
||||||
|
uint8_t prefix_length;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class ip6_neighbor_state : int {
|
||||||
|
incomplete,
|
||||||
|
reachable,
|
||||||
|
stale,
|
||||||
|
delay,
|
||||||
|
probe,
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ip6_neighbor_cache
|
||||||
|
{
|
||||||
|
ipv6_address neighbor;
|
||||||
|
mac_address link_address;
|
||||||
|
ip6_neighbor_state state;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class icmpv6_type : uint8_t
|
||||||
|
{
|
||||||
|
dest_unreachable = 0x1,
|
||||||
|
packet_too_big = 0x2,
|
||||||
|
time_exceeded = 0x3,
|
||||||
|
parameter_problem = 0x4,
|
||||||
|
echo_request = 0x80,
|
||||||
|
echo_reply = 0x81,
|
||||||
|
listener_query = 0x82,
|
||||||
|
listener_report = 0x83,
|
||||||
|
listener_done = 0x84,
|
||||||
|
router_solicit = 0x85,
|
||||||
|
router_advertise = 0x86,
|
||||||
|
neighbor_solicit = 0x87,
|
||||||
|
neighbor_advertise = 0x88,
|
||||||
|
redirect = 0x89,
|
||||||
|
listener_report_2 = 0x8f,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class icmpv6_code : uint8_t
|
||||||
|
{
|
||||||
|
// codes for icmpv6_type::dest_unreachable
|
||||||
|
no_route_to_dest = 0x0,
|
||||||
|
comm_prohibited = 0x1,
|
||||||
|
beyond_scope = 0x2,
|
||||||
|
addr_unreachable = 0x3,
|
||||||
|
port_unreachable = 0x4,
|
||||||
|
source_addr_failed = 0x5,
|
||||||
|
route_rejected = 0x6,
|
||||||
|
|
||||||
|
// codes for icmpv6_type::time_exceeded
|
||||||
|
timeout_hop_limit = 0x0,
|
||||||
|
timeout_reassemble = 0x1,
|
||||||
|
|
||||||
|
// codes for icmpv6_type::parameter_problem
|
||||||
|
erroneous_header = 0x0,
|
||||||
|
unrecognize_next_hdr = 0x1,
|
||||||
|
unrecognize_option = 0x2,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ip6_icmp_type
|
||||||
|
{
|
||||||
|
icmpv6_type type;
|
||||||
|
icmpv6_code code;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ip6_config_data
|
||||||
|
{
|
||||||
|
uint8_t default_protocol;
|
||||||
|
bool accept_any_protocol;
|
||||||
|
bool accept_icmp_errors;
|
||||||
|
bool accept_promiscuous;
|
||||||
|
ipv6_address destination_address;
|
||||||
|
ipv6_address station_address;
|
||||||
|
uint8_t traffic_class;
|
||||||
|
uint8_t hop_limit;
|
||||||
|
uint32_t flow_label;
|
||||||
|
uint32_t receive_timeout;
|
||||||
|
uint32_t transmit_timeout;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ip6_mode_data
|
||||||
|
{
|
||||||
|
bool is_started;
|
||||||
|
uint32_t max_packet_size;
|
||||||
|
ip6_config_data config_data;
|
||||||
|
bool is_configured;
|
||||||
|
uint32_t address_count;
|
||||||
|
ip6_address_info * address_list;
|
||||||
|
uint32_t group_count;
|
||||||
|
ipv6_address * group_table;
|
||||||
|
uint32_t route_count;
|
||||||
|
ip6_route_table * route_table;
|
||||||
|
uint32_t neighbor_count;
|
||||||
|
ip6_neighbor_cache * neighbor_cache;
|
||||||
|
uint32_t prefix_count;
|
||||||
|
ip6_address_info * prefix_table;
|
||||||
|
uint32_t icmp_type_count;
|
||||||
|
* icmp_type_list;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ip6_header
|
||||||
|
{
|
||||||
|
uint8_t traffic_class_h : 4;
|
||||||
|
uint8_t version : 4;
|
||||||
|
uint8_t flow_label_h : 4;
|
||||||
|
uint8_t traffic_class_l : 4;
|
||||||
|
uint16_t flow_label_l;
|
||||||
|
uint16_t payload_length;
|
||||||
|
uint8_t next_header;
|
||||||
|
uint8_t hop_limit;
|
||||||
|
ipv6_address source_address;
|
||||||
|
ipv6_address destination_address;
|
||||||
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
|
struct ip6_fragment_data
|
||||||
|
{
|
||||||
|
uint32_t fragment_length;
|
||||||
|
void *fragment_buffer;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ip6_override_data
|
||||||
|
{
|
||||||
|
uint8_t protocol;
|
||||||
|
uint8_t hop_limit;
|
||||||
|
uint32_t flow_label;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ip6_receive_data
|
||||||
|
{
|
||||||
|
time time_stamp;
|
||||||
|
event recycle_signal;
|
||||||
|
uint32_t header_length;
|
||||||
|
ip6_header *header;
|
||||||
|
uint32_t data_length;
|
||||||
|
uint32_t fragment_count;
|
||||||
|
ip6_fragment_data fragment_table[1];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ip6_transmit_data
|
||||||
|
{
|
||||||
|
ipv6_address destination_address;
|
||||||
|
ip6_override_data *override_data;
|
||||||
|
|
||||||
|
uint32_t ext_hdrs_length;
|
||||||
|
void *ext_hdrs;
|
||||||
|
uint8_t next_header;
|
||||||
|
uint32_t data_length;
|
||||||
|
uint32_t fragment_count;
|
||||||
|
ip6_fragment_data fragment_table[1];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ip6_completion_token
|
||||||
|
{
|
||||||
|
event event;
|
||||||
|
status status;
|
||||||
|
union {
|
||||||
|
ip6_receive_data *rx_data;
|
||||||
|
ip6_transmit_data *tx_data;
|
||||||
|
} packet;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class ip6_config_data_type : int
|
||||||
|
{
|
||||||
|
interface_info,
|
||||||
|
alt_interface_id,
|
||||||
|
policy,
|
||||||
|
dup_addr_detect_transmits,
|
||||||
|
manual_address,
|
||||||
|
gateway,
|
||||||
|
dns_server,
|
||||||
|
maximum
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ip6_config_interface_info
|
||||||
|
{
|
||||||
|
wchar_t name[32];
|
||||||
|
uint8_t if_type;
|
||||||
|
uint32_t hw_address_size;
|
||||||
|
mac_address hw_address;
|
||||||
|
uint32_t address_info_count;
|
||||||
|
ip6_address_info *address_info;
|
||||||
|
uint32_t route_count;
|
||||||
|
ip6_route_table *route_table;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ip6_config_interface_id
|
||||||
|
{
|
||||||
|
uint8_t id[8];
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class ip6_config_policy : int
|
||||||
|
{
|
||||||
|
manual,
|
||||||
|
automatic
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ip6_config_dup_addr_detect_transmits
|
||||||
|
{
|
||||||
|
uint32_t dup_addr_detect_transmits;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ip6_config_manual_address
|
||||||
|
{
|
||||||
|
ipv6_address address;
|
||||||
|
bool is_anycast;
|
||||||
|
uint8_t prefix_length;
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
// IP definitions
|
||||||
|
//
|
||||||
|
union ip_address
|
||||||
|
{
|
||||||
|
uint8_t addr[4];
|
||||||
|
ipv4_address v4;
|
||||||
|
ipv6_address v6;
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
// HTTP definitions
|
||||||
|
//
|
||||||
|
struct httpv4_access_point
|
||||||
|
{
|
||||||
|
bool use_default_address;
|
||||||
|
ipv4_address local_address;
|
||||||
|
ipv4_address local_subnet;
|
||||||
|
uint16_t local_port;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct httpv6_access_point
|
||||||
|
{
|
||||||
|
ipv6_address local_address;
|
||||||
|
uint16_t local_port;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class http_version : int {
|
||||||
|
v10,
|
||||||
|
v11,
|
||||||
|
unsupported,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct http_config_data
|
||||||
|
{
|
||||||
|
http_version http_version;
|
||||||
|
uint32_t time_out_millisec;
|
||||||
|
bool local_address_is_ipv6;
|
||||||
|
union {
|
||||||
|
httpv4_access_point *ipv4_node;
|
||||||
|
httpv6_access_point *ipv6_node;
|
||||||
|
} access_point;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class http_method : int {
|
||||||
|
get,
|
||||||
|
post,
|
||||||
|
patch,
|
||||||
|
options,
|
||||||
|
connect,
|
||||||
|
head,
|
||||||
|
put,
|
||||||
|
delete_,
|
||||||
|
trace,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct http_request_data
|
||||||
|
{
|
||||||
|
http_method method;
|
||||||
|
wchar_t *url;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class http_status_code : int {
|
||||||
|
unsupported,
|
||||||
|
continue_,
|
||||||
|
switching_protocols,
|
||||||
|
ok,
|
||||||
|
created,
|
||||||
|
accepted,
|
||||||
|
non_authoritative_information,
|
||||||
|
no_content,
|
||||||
|
reset_content,
|
||||||
|
partial_content,
|
||||||
|
multiple_choices,
|
||||||
|
moved_permanently,
|
||||||
|
found,
|
||||||
|
see_other,
|
||||||
|
not_modified,
|
||||||
|
use_proxy,
|
||||||
|
temporary_redirect,
|
||||||
|
bad_request,
|
||||||
|
unauthorized,
|
||||||
|
payment_required,
|
||||||
|
forbidden,
|
||||||
|
not_found,
|
||||||
|
method_not_allowed,
|
||||||
|
not_acceptable,
|
||||||
|
proxy_authentication_required,
|
||||||
|
request_time_out,
|
||||||
|
conflict,
|
||||||
|
gone,
|
||||||
|
length_required,
|
||||||
|
precondition_failed,
|
||||||
|
request_entity_too_large,
|
||||||
|
request_uri_too_large,
|
||||||
|
unsupported_media_type,
|
||||||
|
requested_range_not_satisfied,
|
||||||
|
expectation_failed,
|
||||||
|
internal_server_error,
|
||||||
|
not_implemented,
|
||||||
|
bad_gateway,
|
||||||
|
service_unavailable,
|
||||||
|
gateway_timeout,
|
||||||
|
http_version_not_supported,
|
||||||
|
permanent_redirect, // I hate your decisions, uefi.
|
||||||
|
};
|
||||||
|
|
||||||
|
struct http_response_data
|
||||||
|
{
|
||||||
|
http_status_code status_code;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct http_header
|
||||||
|
{
|
||||||
|
char *field_name;
|
||||||
|
char *field_value;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct http_message
|
||||||
|
{
|
||||||
|
union {
|
||||||
|
http_request_data *request;
|
||||||
|
http_response_data *response;
|
||||||
|
} data;
|
||||||
|
|
||||||
|
size_t header_count;
|
||||||
|
http_header *headers;
|
||||||
|
|
||||||
|
size_t body_length;
|
||||||
|
void *body;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct http_token
|
||||||
|
{
|
||||||
|
event event;
|
||||||
|
status status;
|
||||||
|
http_message *message;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace uefi
|
||||||
|
|
||||||
|
#endif
|
||||||
31
external/uefi/protos/device_path.h
vendored
Normal file
31
external/uefi/protos/device_path.h
vendored
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
#pragma once
|
||||||
|
#ifndef _uefi_protos_device_path_h_
|
||||||
|
#define _uefi_protos_device_path_h_
|
||||||
|
|
||||||
|
// This file was auto generated by the j6-uefi-headers project. Please see
|
||||||
|
// https://github.com/justinian/j6-uefi-headers for more information.
|
||||||
|
|
||||||
|
#include <uefi/guid.h>
|
||||||
|
#include <uefi/types.h>
|
||||||
|
|
||||||
|
namespace uefi {
|
||||||
|
namespace protos {
|
||||||
|
struct device_path;
|
||||||
|
|
||||||
|
struct device_path
|
||||||
|
{
|
||||||
|
static constexpr uefi::guid guid{ 0x09576e91,0x6d3f,0x11d2,{0x8e,0x39,0x00,0xa0,0xc9,0x69,0x72,0x3b} };
|
||||||
|
|
||||||
|
|
||||||
|
uint8_t type;
|
||||||
|
uint8_t sub_type;
|
||||||
|
uint16_t length;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
public:
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace protos
|
||||||
|
} // namespace uefi
|
||||||
|
|
||||||
|
#endif // _uefi_protos_device_path_h_
|
||||||
126
external/uefi/protos/file.h
vendored
Normal file
126
external/uefi/protos/file.h
vendored
Normal file
@@ -0,0 +1,126 @@
|
|||||||
|
#pragma once
|
||||||
|
#ifndef _uefi_protos_file_h_
|
||||||
|
#define _uefi_protos_file_h_
|
||||||
|
|
||||||
|
// This file was auto generated by the j6-uefi-headers project. Please see
|
||||||
|
// https://github.com/justinian/j6-uefi-headers for more information.
|
||||||
|
|
||||||
|
#include <uefi/guid.h>
|
||||||
|
#include <uefi/types.h>
|
||||||
|
|
||||||
|
namespace uefi {
|
||||||
|
namespace protos {
|
||||||
|
struct file;
|
||||||
|
|
||||||
|
struct file
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
inline uefi::status open(file ** new_handle, const wchar_t * file_name, file_mode open_mode, file_attr attributes) {
|
||||||
|
return _open(this, new_handle, file_name, open_mode, attributes);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline uefi::status close() {
|
||||||
|
return _close(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline uefi::status delete_file() {
|
||||||
|
return _delete_file(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline uefi::status read(uint64_t * buffer_size, void * buffer) {
|
||||||
|
return _read(this, buffer_size, buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline uefi::status write(uint64_t * buffer_size, void * buffer) {
|
||||||
|
return _write(this, buffer_size, buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline uefi::status get_position(uint64_t * position) {
|
||||||
|
return _get_position(this, position);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline uefi::status set_position(uint64_t position) {
|
||||||
|
return _set_position(this, position);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline uefi::status get_info(const guid * info_type, uint64_t * buffer_size, void * buffer) {
|
||||||
|
return _get_info(this, info_type, buffer_size, buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline uefi::status set_info(const guid * info_type, uint64_t buffer_size, void * buffer) {
|
||||||
|
return _set_info(this, info_type, buffer_size, buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline uefi::status flush() {
|
||||||
|
return _flush(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline uefi::status open_ex(file ** new_handle, const wchar_t * file_name, uint64_t open_mode, uint64_t attributes, file_io_token * token) {
|
||||||
|
return _open_ex(this, new_handle, file_name, open_mode, attributes, token);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline uefi::status read_ex(file_io_token * token) {
|
||||||
|
return _read_ex(this, token);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline uefi::status write_ex(file_io_token * token) {
|
||||||
|
return _write_ex(this, token);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline uefi::status flush_ex(file_io_token * token) {
|
||||||
|
return _flush_ex(this, token);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t revision;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
using _open_def = uefi::status (*)(uefi::protos::file *, file **, const wchar_t *, file_mode, file_attr);
|
||||||
|
_open_def _open;
|
||||||
|
|
||||||
|
using _close_def = uefi::status (*)(uefi::protos::file *);
|
||||||
|
_close_def _close;
|
||||||
|
|
||||||
|
using _delete_file_def = uefi::status (*)(uefi::protos::file *);
|
||||||
|
_delete_file_def _delete_file;
|
||||||
|
|
||||||
|
using _read_def = uefi::status (*)(uefi::protos::file *, uint64_t *, void *);
|
||||||
|
_read_def _read;
|
||||||
|
|
||||||
|
using _write_def = uefi::status (*)(uefi::protos::file *, uint64_t *, void *);
|
||||||
|
_write_def _write;
|
||||||
|
|
||||||
|
using _get_position_def = uefi::status (*)(uefi::protos::file *, uint64_t *);
|
||||||
|
_get_position_def _get_position;
|
||||||
|
|
||||||
|
using _set_position_def = uefi::status (*)(uefi::protos::file *, uint64_t);
|
||||||
|
_set_position_def _set_position;
|
||||||
|
|
||||||
|
using _get_info_def = uefi::status (*)(uefi::protos::file *, const guid *, uint64_t *, void *);
|
||||||
|
_get_info_def _get_info;
|
||||||
|
|
||||||
|
using _set_info_def = uefi::status (*)(uefi::protos::file *, const guid *, uint64_t, void *);
|
||||||
|
_set_info_def _set_info;
|
||||||
|
|
||||||
|
using _flush_def = uefi::status (*)(uefi::protos::file *);
|
||||||
|
_flush_def _flush;
|
||||||
|
|
||||||
|
using _open_ex_def = uefi::status (*)(uefi::protos::file *, file **, const wchar_t *, uint64_t, uint64_t, file_io_token *);
|
||||||
|
_open_ex_def _open_ex;
|
||||||
|
|
||||||
|
using _read_ex_def = uefi::status (*)(uefi::protos::file *, file_io_token *);
|
||||||
|
_read_ex_def _read_ex;
|
||||||
|
|
||||||
|
using _write_ex_def = uefi::status (*)(uefi::protos::file *, file_io_token *);
|
||||||
|
_write_ex_def _write_ex;
|
||||||
|
|
||||||
|
using _flush_ex_def = uefi::status (*)(uefi::protos::file *, file_io_token *);
|
||||||
|
_flush_ex_def _flush_ex;
|
||||||
|
|
||||||
|
public:
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace protos
|
||||||
|
} // namespace uefi
|
||||||
|
|
||||||
|
#endif // _uefi_protos_file_h_
|
||||||
36
external/uefi/protos/file_info.h
vendored
Normal file
36
external/uefi/protos/file_info.h
vendored
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
#pragma once
|
||||||
|
#ifndef _uefi_protos_file_info_h_
|
||||||
|
#define _uefi_protos_file_info_h_
|
||||||
|
|
||||||
|
// This file was auto generated by the j6-uefi-headers project. Please see
|
||||||
|
// https://github.com/justinian/j6-uefi-headers for more information.
|
||||||
|
|
||||||
|
#include <uefi/guid.h>
|
||||||
|
#include <uefi/types.h>
|
||||||
|
|
||||||
|
namespace uefi {
|
||||||
|
namespace protos {
|
||||||
|
struct file_info;
|
||||||
|
|
||||||
|
struct file_info
|
||||||
|
{
|
||||||
|
static constexpr uefi::guid guid{ 0x09576e92,0x6d3f,0x11d2,{0x8e,0x39,0x00,0xa0,0xc9,0x69,0x72,0x3b} };
|
||||||
|
|
||||||
|
|
||||||
|
uint64_t size;
|
||||||
|
uint64_t file_size;
|
||||||
|
uint64_t physical_size;
|
||||||
|
time create_time;
|
||||||
|
time last_access_time;
|
||||||
|
time modification_time;
|
||||||
|
uint64_t attribute;
|
||||||
|
wchar_t file_name[];
|
||||||
|
|
||||||
|
protected:
|
||||||
|
public:
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace protos
|
||||||
|
} // namespace uefi
|
||||||
|
|
||||||
|
#endif // _uefi_protos_file_info_h_
|
||||||
51
external/uefi/protos/graphics_output.h
vendored
Normal file
51
external/uefi/protos/graphics_output.h
vendored
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
#pragma once
|
||||||
|
#ifndef _uefi_protos_graphics_output_h_
|
||||||
|
#define _uefi_protos_graphics_output_h_
|
||||||
|
|
||||||
|
// This file was auto generated by the j6-uefi-headers project. Please see
|
||||||
|
// https://github.com/justinian/j6-uefi-headers for more information.
|
||||||
|
|
||||||
|
#include <uefi/guid.h>
|
||||||
|
#include <uefi/types.h>
|
||||||
|
#include <uefi/graphics.h>
|
||||||
|
|
||||||
|
namespace uefi {
|
||||||
|
namespace protos {
|
||||||
|
struct graphics_output;
|
||||||
|
|
||||||
|
struct graphics_output
|
||||||
|
{
|
||||||
|
static constexpr uefi::guid guid{ 0x9042a9de,0x23dc,0x4a38,{0x96,0xfb,0x7a,0xde,0xd0,0x80,0x51,0x6a} };
|
||||||
|
|
||||||
|
|
||||||
|
inline uefi::status query_mode(uint32_t mode_number, uint64_t * size_of_info, uefi::graphics_output_mode_info ** info) {
|
||||||
|
return _query_mode(this, mode_number, size_of_info, info);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline uefi::status set_mode(uint32_t mode_number) {
|
||||||
|
return _set_mode(this, mode_number);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline uefi::status blt() {
|
||||||
|
return _blt(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected:
|
||||||
|
using _query_mode_def = uefi::status (*)(uefi::protos::graphics_output *, uint32_t, uint64_t *, uefi::graphics_output_mode_info **);
|
||||||
|
_query_mode_def _query_mode;
|
||||||
|
|
||||||
|
using _set_mode_def = uefi::status (*)(uefi::protos::graphics_output *, uint32_t);
|
||||||
|
_set_mode_def _set_mode;
|
||||||
|
|
||||||
|
using _blt_def = uefi::status (*)(uefi::protos::graphics_output *);
|
||||||
|
_blt_def _blt;
|
||||||
|
|
||||||
|
public:
|
||||||
|
uefi::graphics_output_mode * mode;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace protos
|
||||||
|
} // namespace uefi
|
||||||
|
|
||||||
|
#endif // _uefi_protos_graphics_output_h_
|
||||||
72
external/uefi/protos/http.h
vendored
Normal file
72
external/uefi/protos/http.h
vendored
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
#pragma once
|
||||||
|
#ifndef _uefi_protos_http_h_
|
||||||
|
#define _uefi_protos_http_h_
|
||||||
|
|
||||||
|
// This file was auto generated by the j6-uefi-headers project. Please see
|
||||||
|
// https://github.com/justinian/j6-uefi-headers for more information.
|
||||||
|
|
||||||
|
#include <uefi/guid.h>
|
||||||
|
#include <uefi/types.h>
|
||||||
|
#include <uefi/networking.h>
|
||||||
|
|
||||||
|
namespace uefi {
|
||||||
|
namespace protos {
|
||||||
|
struct http;
|
||||||
|
|
||||||
|
struct http
|
||||||
|
{
|
||||||
|
static constexpr uefi::guid guid{ 0x7a59b29b,0x910b,0x4171,{0x82,0x42,0xa8,0x5a,0x0d,0xf2,0x5b,0x5b} };
|
||||||
|
static constexpr uefi::guid service_binding{ 0xbdc8e6af,0xd9bc,0x4379,{0xa7,0x2a,0xe0,0xc4,0xe7,0x5d,0xae,0x1c} };
|
||||||
|
|
||||||
|
|
||||||
|
inline uefi::status get_mode_data(uefi::http_config_data * http_config_data) {
|
||||||
|
return _get_mode_data(this, http_config_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline uefi::status configure(uefi::http_config_data * http_config_data) {
|
||||||
|
return _configure(this, http_config_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline uefi::status request(uefi::http_token * token) {
|
||||||
|
return _request(this, token);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline uefi::status cancel(uefi::http_token * token) {
|
||||||
|
return _cancel(this, token);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline uefi::status response(uefi::http_token * token) {
|
||||||
|
return _response(this, token);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline uefi::status poll() {
|
||||||
|
return _poll(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected:
|
||||||
|
using _get_mode_data_def = uefi::status (*)(uefi::protos::http *, uefi::http_config_data *);
|
||||||
|
_get_mode_data_def _get_mode_data;
|
||||||
|
|
||||||
|
using _configure_def = uefi::status (*)(uefi::protos::http *, uefi::http_config_data *);
|
||||||
|
_configure_def _configure;
|
||||||
|
|
||||||
|
using _request_def = uefi::status (*)(uefi::protos::http *, uefi::http_token *);
|
||||||
|
_request_def _request;
|
||||||
|
|
||||||
|
using _cancel_def = uefi::status (*)(uefi::protos::http *, uefi::http_token *);
|
||||||
|
_cancel_def _cancel;
|
||||||
|
|
||||||
|
using _response_def = uefi::status (*)(uefi::protos::http *, uefi::http_token *);
|
||||||
|
_response_def _response;
|
||||||
|
|
||||||
|
using _poll_def = uefi::status (*)(uefi::protos::http *);
|
||||||
|
_poll_def _poll;
|
||||||
|
|
||||||
|
public:
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace protos
|
||||||
|
} // namespace uefi
|
||||||
|
|
||||||
|
#endif // _uefi_protos_http_h_
|
||||||
93
external/uefi/protos/ip6.h
vendored
Normal file
93
external/uefi/protos/ip6.h
vendored
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
#pragma once
|
||||||
|
#ifndef _uefi_protos_ip6_h_
|
||||||
|
#define _uefi_protos_ip6_h_
|
||||||
|
|
||||||
|
// This file was auto generated by the j6-uefi-headers project. Please see
|
||||||
|
// https://github.com/justinian/j6-uefi-headers for more information.
|
||||||
|
|
||||||
|
#include <uefi/guid.h>
|
||||||
|
#include <uefi/types.h>
|
||||||
|
#include <uefi/networking.h>
|
||||||
|
|
||||||
|
namespace uefi {
|
||||||
|
namespace protos {
|
||||||
|
struct ip6;
|
||||||
|
|
||||||
|
struct ip6
|
||||||
|
{
|
||||||
|
static constexpr uefi::guid guid{ 0x2c8759d5,0x5c2d,0x66ef,{0x92,0x5f,0xb6,0x6c,0x10,0x19,0x57,0xe2} };
|
||||||
|
static constexpr uefi::guid service_binding{ 0xec835dd3,0xfe0f,0x617b,{0xa6,0x21,0xb3,0x50,0xc3,0xe1,0x33,0x88} };
|
||||||
|
|
||||||
|
|
||||||
|
inline uefi::status get_mode_data(uefi::ip6_mode_data * ip6_mode_data, uefi::managed_network_config_data * mnp_config_data, uefi::simple_network_mode * snp_config_data) {
|
||||||
|
return _get_mode_data(this, ip6_mode_data, mnp_config_data, snp_config_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline uefi::status configure(uefi::ip6_config_data * ip6_config_data) {
|
||||||
|
return _configure(this, ip6_config_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline uefi::status groups(bool join_flag, uefi::ipv6_address * group_address) {
|
||||||
|
return _groups(this, join_flag, group_address);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline uefi::status routes(bool delete_route, uefi::ipv6_address * destination, uint8_t prefix_length, uefi::ipv6_address * gateway_address) {
|
||||||
|
return _routes(this, delete_route, destination, prefix_length, gateway_address);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline uefi::status neighbors(bool delete_flag, uefi::ipv6_address * target_ip6_address, uefi::mac_address * target_link_address, uint32_t timeout, bool override) {
|
||||||
|
return _neighbors(this, delete_flag, target_ip6_address, target_link_address, timeout, override);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline uefi::status transmit(uefi::ip6_completion_token * token) {
|
||||||
|
return _transmit(this, token);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline uefi::status receive(uefi::ip6_completion_token * token) {
|
||||||
|
return _receive(this, token);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline uefi::status cancel(uefi::ip6_completion_token * token) {
|
||||||
|
return _cancel(this, token);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline uefi::status poll() {
|
||||||
|
return _poll(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected:
|
||||||
|
using _get_mode_data_def = uefi::status (*)(uefi::protos::ip6 *, uefi::ip6_mode_data *, uefi::managed_network_config_data *, uefi::simple_network_mode *);
|
||||||
|
_get_mode_data_def _get_mode_data;
|
||||||
|
|
||||||
|
using _configure_def = uefi::status (*)(uefi::protos::ip6 *, uefi::ip6_config_data *);
|
||||||
|
_configure_def _configure;
|
||||||
|
|
||||||
|
using _groups_def = uefi::status (*)(uefi::protos::ip6 *, bool, uefi::ipv6_address *);
|
||||||
|
_groups_def _groups;
|
||||||
|
|
||||||
|
using _routes_def = uefi::status (*)(uefi::protos::ip6 *, bool, uefi::ipv6_address *, uint8_t, uefi::ipv6_address *);
|
||||||
|
_routes_def _routes;
|
||||||
|
|
||||||
|
using _neighbors_def = uefi::status (*)(uefi::protos::ip6 *, bool, uefi::ipv6_address *, uefi::mac_address *, uint32_t, bool);
|
||||||
|
_neighbors_def _neighbors;
|
||||||
|
|
||||||
|
using _transmit_def = uefi::status (*)(uefi::protos::ip6 *, uefi::ip6_completion_token *);
|
||||||
|
_transmit_def _transmit;
|
||||||
|
|
||||||
|
using _receive_def = uefi::status (*)(uefi::protos::ip6 *, uefi::ip6_completion_token *);
|
||||||
|
_receive_def _receive;
|
||||||
|
|
||||||
|
using _cancel_def = uefi::status (*)(uefi::protos::ip6 *, uefi::ip6_completion_token *);
|
||||||
|
_cancel_def _cancel;
|
||||||
|
|
||||||
|
using _poll_def = uefi::status (*)(uefi::protos::ip6 *);
|
||||||
|
_poll_def _poll;
|
||||||
|
|
||||||
|
public:
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace protos
|
||||||
|
} // namespace uefi
|
||||||
|
|
||||||
|
#endif // _uefi_protos_ip6_h_
|
||||||
57
external/uefi/protos/ip6_config.h
vendored
Normal file
57
external/uefi/protos/ip6_config.h
vendored
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
#pragma once
|
||||||
|
#ifndef _uefi_protos_ip6_config_h_
|
||||||
|
#define _uefi_protos_ip6_config_h_
|
||||||
|
|
||||||
|
// This file was auto generated by the j6-uefi-headers project. Please see
|
||||||
|
// https://github.com/justinian/j6-uefi-headers for more information.
|
||||||
|
|
||||||
|
#include <uefi/guid.h>
|
||||||
|
#include <uefi/types.h>
|
||||||
|
#include <uefi/networking.h>
|
||||||
|
|
||||||
|
namespace uefi {
|
||||||
|
namespace protos {
|
||||||
|
struct ip6_config;
|
||||||
|
|
||||||
|
struct ip6_config
|
||||||
|
{
|
||||||
|
static constexpr uefi::guid guid{ 0x937fe521,0x95ae,0x4d1a,{0x89,0x29,0x48,0xbc,0xd9,0x0a,0xd3,0x1a} };
|
||||||
|
|
||||||
|
|
||||||
|
inline uefi::status set_data(uefi::ip6_config_data_type data_type, size_t data_size, void * data) {
|
||||||
|
return _set_data(this, data_type, data_size, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline uefi::status get_data(uefi::ip6_config_data_type data_type, size_t data_size, void * data) {
|
||||||
|
return _get_data(this, data_type, data_size, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline uefi::status register_data_notify(uefi::ip6_config_data_type data_type, uefi::event event) {
|
||||||
|
return _register_data_notify(this, data_type, event);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline uefi::status unregister_data_notify(uefi::ip6_config_data_type data_type, uefi::event event) {
|
||||||
|
return _unregister_data_notify(this, data_type, event);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected:
|
||||||
|
using _set_data_def = uefi::status (*)(uefi::protos::ip6_config *, uefi::ip6_config_data_type, size_t, void *);
|
||||||
|
_set_data_def _set_data;
|
||||||
|
|
||||||
|
using _get_data_def = uefi::status (*)(uefi::protos::ip6_config *, uefi::ip6_config_data_type, size_t, void *);
|
||||||
|
_get_data_def _get_data;
|
||||||
|
|
||||||
|
using _register_data_notify_def = uefi::status (*)(uefi::protos::ip6_config *, uefi::ip6_config_data_type, uefi::event);
|
||||||
|
_register_data_notify_def _register_data_notify;
|
||||||
|
|
||||||
|
using _unregister_data_notify_def = uefi::status (*)(uefi::protos::ip6_config *, uefi::ip6_config_data_type, uefi::event);
|
||||||
|
_unregister_data_notify_def _unregister_data_notify;
|
||||||
|
|
||||||
|
public:
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace protos
|
||||||
|
} // namespace uefi
|
||||||
|
|
||||||
|
#endif // _uefi_protos_ip6_config_h_
|
||||||
36
external/uefi/protos/load_file.h
vendored
Normal file
36
external/uefi/protos/load_file.h
vendored
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
#pragma once
|
||||||
|
#ifndef _uefi_protos_load_file_h_
|
||||||
|
#define _uefi_protos_load_file_h_
|
||||||
|
|
||||||
|
// This file was auto generated by the j6-uefi-headers project. Please see
|
||||||
|
// https://github.com/justinian/j6-uefi-headers for more information.
|
||||||
|
|
||||||
|
#include <uefi/guid.h>
|
||||||
|
#include <uefi/types.h>
|
||||||
|
#include <uefi/protos/device_path.h>
|
||||||
|
|
||||||
|
namespace uefi {
|
||||||
|
namespace protos {
|
||||||
|
struct load_file;
|
||||||
|
|
||||||
|
struct load_file
|
||||||
|
{
|
||||||
|
static constexpr uefi::guid guid{ {0x56ec3091,0x954c,0x11d2,{0x8e,0x3f,0x00,0xa0,0xc9,0x69,0x72,0x3b} };
|
||||||
|
|
||||||
|
|
||||||
|
inline uefi::status load_file(uefi::protos::device_path * file_path, bool boot_policy, size_t * buffer_size, void * buffer) {
|
||||||
|
return _load_file(this, file_path, boot_policy, buffer_size, buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected:
|
||||||
|
using _load_file_def = uefi::status (*)(uefi::protos::load_file *, uefi::protos::device_path *, bool, size_t *, void *);
|
||||||
|
_load_file_def _load_file;
|
||||||
|
|
||||||
|
public:
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace protos
|
||||||
|
} // namespace uefi
|
||||||
|
|
||||||
|
#endif // _uefi_protos_load_file_h_
|
||||||
49
external/uefi/protos/loaded_image.h
vendored
Normal file
49
external/uefi/protos/loaded_image.h
vendored
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
#pragma once
|
||||||
|
#ifndef _uefi_protos_loaded_image_h_
|
||||||
|
#define _uefi_protos_loaded_image_h_
|
||||||
|
|
||||||
|
// This file was auto generated by the j6-uefi-headers project. Please see
|
||||||
|
// https://github.com/justinian/j6-uefi-headers for more information.
|
||||||
|
|
||||||
|
#include <uefi/guid.h>
|
||||||
|
#include <uefi/types.h>
|
||||||
|
#include <uefi/tables.h>
|
||||||
|
#include <uefi/protos/device_path.h>
|
||||||
|
|
||||||
|
namespace uefi {
|
||||||
|
namespace protos {
|
||||||
|
struct loaded_image;
|
||||||
|
|
||||||
|
struct loaded_image
|
||||||
|
{
|
||||||
|
static constexpr uefi::guid guid{ 0x5b1b31a1,0x9562,0x11d2,{0x8e,0x3f,0x00,0xa0,0xc9,0x69,0x72,0x3b} };
|
||||||
|
|
||||||
|
|
||||||
|
inline uefi::status unload(uefi::handle image_handle) {
|
||||||
|
return _unload(image_handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t revision;
|
||||||
|
uefi::handle parent_handle;
|
||||||
|
uefi::system_table * system_table;
|
||||||
|
uefi::handle device_handle;
|
||||||
|
uefi::protos::device_path * file_path;
|
||||||
|
void * reserved;
|
||||||
|
uint32_t load_options_size;
|
||||||
|
void * load_options;
|
||||||
|
void * image_base;
|
||||||
|
uint64_t image_size;
|
||||||
|
uefi::memory_type image_code_type;
|
||||||
|
uefi::memory_type image_data_type;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
using _unload_def = uefi::status (*)(uefi::handle);
|
||||||
|
_unload_def _unload;
|
||||||
|
|
||||||
|
public:
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace protos
|
||||||
|
} // namespace uefi
|
||||||
|
|
||||||
|
#endif // _uefi_protos_loaded_image_h_
|
||||||
41
external/uefi/protos/service_binding.h
vendored
Normal file
41
external/uefi/protos/service_binding.h
vendored
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
#pragma once
|
||||||
|
#ifndef _uefi_protos_service_binding_h_
|
||||||
|
#define _uefi_protos_service_binding_h_
|
||||||
|
|
||||||
|
// This file was auto generated by the j6-uefi-headers project. Please see
|
||||||
|
// https://github.com/justinian/j6-uefi-headers for more information.
|
||||||
|
|
||||||
|
#include <uefi/guid.h>
|
||||||
|
#include <uefi/types.h>
|
||||||
|
|
||||||
|
namespace uefi {
|
||||||
|
namespace protos {
|
||||||
|
struct service_binding;
|
||||||
|
|
||||||
|
struct service_binding
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
inline uefi::status create_child(uefi::handle * child_handle) {
|
||||||
|
return _create_child(this, child_handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline uefi::status destroy_child(uefi::handle child_handle) {
|
||||||
|
return _destroy_child(this, child_handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected:
|
||||||
|
using _create_child_def = uefi::status (*)(uefi::protos::service_binding *, uefi::handle *);
|
||||||
|
_create_child_def _create_child;
|
||||||
|
|
||||||
|
using _destroy_child_def = uefi::status (*)(uefi::protos::service_binding *, uefi::handle);
|
||||||
|
_destroy_child_def _destroy_child;
|
||||||
|
|
||||||
|
public:
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace protos
|
||||||
|
} // namespace uefi
|
||||||
|
|
||||||
|
#endif // _uefi_protos_service_binding_h_
|
||||||
37
external/uefi/protos/simple_file_system.h
vendored
Normal file
37
external/uefi/protos/simple_file_system.h
vendored
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
#pragma once
|
||||||
|
#ifndef _uefi_protos_simple_file_system_h_
|
||||||
|
#define _uefi_protos_simple_file_system_h_
|
||||||
|
|
||||||
|
// This file was auto generated by the j6-uefi-headers project. Please see
|
||||||
|
// https://github.com/justinian/j6-uefi-headers for more information.
|
||||||
|
|
||||||
|
#include <uefi/guid.h>
|
||||||
|
#include <uefi/types.h>
|
||||||
|
#include <uefi/protos/file.h>
|
||||||
|
|
||||||
|
namespace uefi {
|
||||||
|
namespace protos {
|
||||||
|
struct simple_file_system;
|
||||||
|
|
||||||
|
struct simple_file_system
|
||||||
|
{
|
||||||
|
static constexpr uefi::guid guid{ 0x0964e5b22,0x6459,0x11d2,{0x8e,0x39,0x00,0xa0,0xc9,0x69,0x72,0x3b} };
|
||||||
|
|
||||||
|
|
||||||
|
inline uefi::status open_volume(uefi::protos::file ** root) {
|
||||||
|
return _open_volume(this, root);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t revision;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
using _open_volume_def = uefi::status (*)(uefi::protos::simple_file_system *, uefi::protos::file **);
|
||||||
|
_open_volume_def _open_volume;
|
||||||
|
|
||||||
|
public:
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace protos
|
||||||
|
} // namespace uefi
|
||||||
|
|
||||||
|
#endif // _uefi_protos_simple_file_system_h_
|
||||||
93
external/uefi/protos/simple_text_output.h
vendored
Normal file
93
external/uefi/protos/simple_text_output.h
vendored
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
#pragma once
|
||||||
|
#ifndef _uefi_protos_simple_text_output_h_
|
||||||
|
#define _uefi_protos_simple_text_output_h_
|
||||||
|
|
||||||
|
// This file was auto generated by the j6-uefi-headers project. Please see
|
||||||
|
// https://github.com/justinian/j6-uefi-headers for more information.
|
||||||
|
|
||||||
|
#include <uefi/guid.h>
|
||||||
|
#include <uefi/types.h>
|
||||||
|
#include <uefi/graphics.h>
|
||||||
|
|
||||||
|
namespace uefi {
|
||||||
|
namespace protos {
|
||||||
|
struct simple_text_output;
|
||||||
|
|
||||||
|
struct simple_text_output
|
||||||
|
{
|
||||||
|
static constexpr uefi::guid guid{ 0x387477c2,0x69c7,0x11d2,{0x8e,0x39,0x00,0xa0,0xc9,0x69,0x72,0x3b} };
|
||||||
|
|
||||||
|
|
||||||
|
inline uefi::status reset(bool extended_verification) {
|
||||||
|
return _reset(this, extended_verification);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline uefi::status output_string(const wchar_t * string) {
|
||||||
|
return _output_string(this, string);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline uefi::status test_string(const wchar_t * string) {
|
||||||
|
return _test_string(this, string);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline uefi::status query_mode(uint64_t mode_number, uint64_t * columns, uint64_t * rows) {
|
||||||
|
return _query_mode(this, mode_number, columns, rows);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline uefi::status set_mode(uint64_t mode_number) {
|
||||||
|
return _set_mode(this, mode_number);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline uefi::status set_attribute(uefi::attribute attribute) {
|
||||||
|
return _set_attribute(this, attribute);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline uefi::status clear_screen() {
|
||||||
|
return _clear_screen(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline uefi::status set_cursor_position(uint64_t column, uint64_t row) {
|
||||||
|
return _set_cursor_position(this, column, row);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline uefi::status enable_cursor(bool visible) {
|
||||||
|
return _enable_cursor(this, visible);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected:
|
||||||
|
using _reset_def = uefi::status (*)(uefi::protos::simple_text_output *, bool);
|
||||||
|
_reset_def _reset;
|
||||||
|
|
||||||
|
using _output_string_def = uefi::status (*)(uefi::protos::simple_text_output *, const wchar_t *);
|
||||||
|
_output_string_def _output_string;
|
||||||
|
|
||||||
|
using _test_string_def = uefi::status (*)(uefi::protos::simple_text_output *, const wchar_t *);
|
||||||
|
_test_string_def _test_string;
|
||||||
|
|
||||||
|
using _query_mode_def = uefi::status (*)(uefi::protos::simple_text_output *, uint64_t, uint64_t *, uint64_t *);
|
||||||
|
_query_mode_def _query_mode;
|
||||||
|
|
||||||
|
using _set_mode_def = uefi::status (*)(uefi::protos::simple_text_output *, uint64_t);
|
||||||
|
_set_mode_def _set_mode;
|
||||||
|
|
||||||
|
using _set_attribute_def = uefi::status (*)(uefi::protos::simple_text_output *, uefi::attribute);
|
||||||
|
_set_attribute_def _set_attribute;
|
||||||
|
|
||||||
|
using _clear_screen_def = uefi::status (*)(uefi::protos::simple_text_output *);
|
||||||
|
_clear_screen_def _clear_screen;
|
||||||
|
|
||||||
|
using _set_cursor_position_def = uefi::status (*)(uefi::protos::simple_text_output *, uint64_t, uint64_t);
|
||||||
|
_set_cursor_position_def _set_cursor_position;
|
||||||
|
|
||||||
|
using _enable_cursor_def = uefi::status (*)(uefi::protos::simple_text_output *, bool);
|
||||||
|
_enable_cursor_def _enable_cursor;
|
||||||
|
|
||||||
|
public:
|
||||||
|
uefi::text_output_mode * mode;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace protos
|
||||||
|
} // namespace uefi
|
||||||
|
|
||||||
|
#endif // _uefi_protos_simple_text_output_h_
|
||||||
52
external/uefi/runtime_services.h
vendored
Normal file
52
external/uefi/runtime_services.h
vendored
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
#pragma once
|
||||||
|
#ifndef _uefi_runtime_services_h_
|
||||||
|
#define _uefi_runtime_services_h_
|
||||||
|
|
||||||
|
// This Source Code Form is part of the j6-uefi-headers project and is subject
|
||||||
|
// to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was
|
||||||
|
// not distributed with this file, You can obtain one at
|
||||||
|
// http://mozilla.org/MPL/2.0/.
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <uefi/tables.h>
|
||||||
|
|
||||||
|
namespace uefi {
|
||||||
|
namespace rs_impl {
|
||||||
|
using convert_pointer = uefi::status (*)(uint64_t, void **);
|
||||||
|
using set_virtual_address_map = uefi::status (*)(size_t, size_t, uint32_t, memory_descriptor *);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct runtime_services {
|
||||||
|
static constexpr uint64_t signature = 0x56524553544e5552ull;
|
||||||
|
|
||||||
|
table_header header;
|
||||||
|
|
||||||
|
// Time Services
|
||||||
|
void *get_time;
|
||||||
|
void *set_time;
|
||||||
|
void *get_wakeup_time;
|
||||||
|
void *set_wakeup_time;
|
||||||
|
|
||||||
|
// Virtual Memory Services
|
||||||
|
rs_impl::set_virtual_address_map set_virtual_address_map;
|
||||||
|
rs_impl::convert_pointer convert_pointer;
|
||||||
|
|
||||||
|
// Variable Services
|
||||||
|
void *get_variable;
|
||||||
|
void *get_next_variable_name;
|
||||||
|
void *set_variable;
|
||||||
|
|
||||||
|
// Miscellaneous Services
|
||||||
|
void *get_next_high_monotonic_count;
|
||||||
|
void *reset_system;
|
||||||
|
|
||||||
|
// UEFI 2.0 Capsule Services
|
||||||
|
void *update_capsule;
|
||||||
|
void *query_capsule_capabilities;
|
||||||
|
|
||||||
|
// Miscellaneous UEFI 2.0 Service
|
||||||
|
void *query_variable_info;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace uefi
|
||||||
|
#endif
|
||||||
73
external/uefi/tables.h
vendored
Normal file
73
external/uefi/tables.h
vendored
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
#pragma once
|
||||||
|
#ifndef _uefi_tables_h_
|
||||||
|
#define _uefi_tables_h_
|
||||||
|
|
||||||
|
// This Source Code Form is part of the j6-uefi-headers project and is subject
|
||||||
|
// to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was
|
||||||
|
// not distributed with this file, You can obtain one at
|
||||||
|
// http://mozilla.org/MPL/2.0/.
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <uefi/guid.h>
|
||||||
|
#include <uefi/types.h>
|
||||||
|
|
||||||
|
namespace uefi {
|
||||||
|
|
||||||
|
struct runtime_services;
|
||||||
|
struct boot_services;
|
||||||
|
namespace protos {
|
||||||
|
struct simple_text_input;
|
||||||
|
struct simple_text_output;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct table_header
|
||||||
|
{
|
||||||
|
uint64_t signature;
|
||||||
|
uint32_t revision;
|
||||||
|
uint32_t header_size;
|
||||||
|
uint32_t crc32;
|
||||||
|
uint32_t reserved;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct configuration_table
|
||||||
|
{
|
||||||
|
guid vendor_guid;
|
||||||
|
void *vendor_table;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct system_table
|
||||||
|
{
|
||||||
|
table_header header;
|
||||||
|
|
||||||
|
char16_t *firmware_vendor;
|
||||||
|
uint32_t firmware_revision;
|
||||||
|
|
||||||
|
handle console_in_handle;
|
||||||
|
protos::simple_text_input *con_in;
|
||||||
|
handle console_out_handle;
|
||||||
|
protos::simple_text_output *con_out;
|
||||||
|
handle standard_error_handle;
|
||||||
|
protos::simple_text_output *std_err;
|
||||||
|
|
||||||
|
runtime_services *runtime_services;
|
||||||
|
boot_services *boot_services;
|
||||||
|
|
||||||
|
unsigned int number_of_table_entries;
|
||||||
|
configuration_table *configuration_table;
|
||||||
|
};
|
||||||
|
|
||||||
|
constexpr uint32_t make_system_table_revision(int major, int minor) {
|
||||||
|
return (major << 16) | minor;
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr uint64_t system_table_signature = 0x5453595320494249ull;
|
||||||
|
constexpr uint32_t system_table_revision = make_system_table_revision(2, 70);
|
||||||
|
constexpr uint32_t specification_revision = system_table_revision;
|
||||||
|
|
||||||
|
namespace vendor_guids {
|
||||||
|
constexpr guid acpi1{ 0xeb9d2d30,0x2d88,0x11d3,{0x9a,0x16,0x00,0x90,0x27,0x3f,0xc1,0x4d} };
|
||||||
|
constexpr guid acpi2{ 0x8868e871,0xe4f1,0x11d3,{0xbc,0x22,0x00,0x80,0xc7,0x3c,0x88,0x81} };
|
||||||
|
} // namespace vendor_guids
|
||||||
|
} // namespace uefi
|
||||||
|
|
||||||
|
#endif
|
||||||
157
external/uefi/types.h
vendored
Normal file
157
external/uefi/types.h
vendored
Normal file
@@ -0,0 +1,157 @@
|
|||||||
|
#pragma once
|
||||||
|
#ifndef _uefi_types_h_
|
||||||
|
#define _uefi_types_h_
|
||||||
|
|
||||||
|
// This Source Code Form is part of the j6-uefi-headers project and is subject
|
||||||
|
// to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was
|
||||||
|
// not distributed with this file, You can obtain one at
|
||||||
|
// http://mozilla.org/MPL/2.0/.
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
namespace uefi {
|
||||||
|
|
||||||
|
using handle = void *;
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Error and status code definitions
|
||||||
|
//
|
||||||
|
constexpr uint64_t error_bit = 0x8000000000000000ull;
|
||||||
|
constexpr uint64_t make_error(uint64_t e) { return e|error_bit; }
|
||||||
|
|
||||||
|
enum class status : uint64_t
|
||||||
|
{
|
||||||
|
success = 0,
|
||||||
|
|
||||||
|
#define STATUS_WARNING(name, num) name = num,
|
||||||
|
#define STATUS_ERROR(name, num) name = make_error(num),
|
||||||
|
#include "uefi/errors.inc"
|
||||||
|
#undef STATUS_WARNING
|
||||||
|
#undef STATUS_ERROR
|
||||||
|
};
|
||||||
|
|
||||||
|
inline bool is_error(status s) { return static_cast<uint64_t>(s) & error_bit; }
|
||||||
|
inline bool is_warning(status s) { return !is_error(s) && s != status::success; }
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Time defitions
|
||||||
|
//
|
||||||
|
struct time
|
||||||
|
{
|
||||||
|
uint16_t year;
|
||||||
|
uint8_t month;
|
||||||
|
uint8_t day;
|
||||||
|
uint8_t hour;
|
||||||
|
uint8_t minute;
|
||||||
|
uint8_t second;
|
||||||
|
uint8_t _pad0;
|
||||||
|
uint32_t nanosecond;
|
||||||
|
int16_t time_zone;
|
||||||
|
uint8_t daylight;
|
||||||
|
uint8_t _pad1;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Memory and allocation defitions
|
||||||
|
//
|
||||||
|
enum class memory_type : uint32_t
|
||||||
|
{
|
||||||
|
reserved,
|
||||||
|
loader_code,
|
||||||
|
loader_data,
|
||||||
|
boot_services_code,
|
||||||
|
boot_services_data,
|
||||||
|
runtime_services_code,
|
||||||
|
runtime_services_data,
|
||||||
|
conventional_memory,
|
||||||
|
unusable_memory,
|
||||||
|
acpi_reclaim_memory,
|
||||||
|
acpi_memory_nvs,
|
||||||
|
memory_mapped_io,
|
||||||
|
memory_mapped_io_port_space,
|
||||||
|
pal_code,
|
||||||
|
persistent_memory,
|
||||||
|
max_memory_type
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class allocate_type : uint32_t
|
||||||
|
{
|
||||||
|
any_pages,
|
||||||
|
max_address,
|
||||||
|
address
|
||||||
|
};
|
||||||
|
|
||||||
|
struct memory_descriptor
|
||||||
|
{
|
||||||
|
memory_type type;
|
||||||
|
uintptr_t physical_start;
|
||||||
|
uintptr_t virtual_start;
|
||||||
|
uint64_t number_of_pages;
|
||||||
|
uint64_t attribute;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Event handling defitions
|
||||||
|
//
|
||||||
|
using event = void *;
|
||||||
|
|
||||||
|
enum class evt : uint32_t
|
||||||
|
{
|
||||||
|
notify_wait = 0x00000100,
|
||||||
|
notify_signal = 0x00000200,
|
||||||
|
|
||||||
|
signal_exit_boot_services = 0x00000201,
|
||||||
|
signal_virtual_address_change = 0x60000202,
|
||||||
|
|
||||||
|
runtime = 0x40000000,
|
||||||
|
timer = 0x80000000
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class tpl : uint64_t
|
||||||
|
{
|
||||||
|
application = 4,
|
||||||
|
callback = 8,
|
||||||
|
notify = 16,
|
||||||
|
high_level = 31
|
||||||
|
};
|
||||||
|
|
||||||
|
using event_notify = void (*)(event, void*);
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// File IO defitions
|
||||||
|
//
|
||||||
|
struct file_io_token
|
||||||
|
{
|
||||||
|
event event;
|
||||||
|
status status;
|
||||||
|
uint64_t buffer_size;
|
||||||
|
void *buffer;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class file_mode : uint64_t
|
||||||
|
{
|
||||||
|
read = 0x0000000000000001ull,
|
||||||
|
write = 0x0000000000000002ull,
|
||||||
|
|
||||||
|
create = 0x8000000000000000ull
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class file_attr : uint64_t
|
||||||
|
{
|
||||||
|
none = 0,
|
||||||
|
read_only = 0x0000000000000001ull,
|
||||||
|
hidden = 0x0000000000000002ull,
|
||||||
|
system = 0x0000000000000004ull,
|
||||||
|
reserved = 0x0000000000000008ull,
|
||||||
|
directory = 0x0000000000000010ull,
|
||||||
|
archive = 0x0000000000000020ull
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace uefi
|
||||||
|
|
||||||
|
#endif
|
||||||
6
make.bat
6
make.bat
@@ -1,6 +0,0 @@
|
|||||||
@echo off
|
|
||||||
if exist C:\Windows\Sysnative\bash.exe (
|
|
||||||
C:\Windows\Sysnative\bash.exe -c "make %*"
|
|
||||||
) else (
|
|
||||||
C:\Windows\System32\bash.exe -c "make %*"
|
|
||||||
)
|
|
||||||
35
modules.mk
35
modules.mk
@@ -1,35 +0,0 @@
|
|||||||
ifeq "$(MOD_NAME)" ""
|
|
||||||
include "you must specify a MOD_NAME"
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifndef SOURCES
|
|
||||||
SOURCES := $(wildcard src/modules/$(MOD_NAME)/*.c)
|
|
||||||
SOURCES += $(wildcard src/modules/$(MOD_NAME)/*.cpp)
|
|
||||||
SOURCES += $(wildcard src/modules/$(MOD_NAME)/*.s)
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq "$(SOURCES)" ""
|
|
||||||
include "you must specify a SOURCES list"
|
|
||||||
endif
|
|
||||||
|
|
||||||
MOD_SRC_D := src/modules/$(MOD_NAME)
|
|
||||||
MOD_BUILD_D := $(BUILD_D)/d.$(MOD_NAME)
|
|
||||||
MOD_LIBNAME := $(BUILD_D)/lib$(MOD_NAME).a
|
|
||||||
MOD_TARGETS += $(MOD_LIBNAME)
|
|
||||||
|
|
||||||
OBJS_$(MOD_NAME) := $(patsubst %,build/d.%.o,$(patsubst src/modules/%,%,$(SOURCES)))
|
|
||||||
|
|
||||||
$(MOD_LIBNAME): $(OBJS_$(MOD_NAME))
|
|
||||||
$(AR) cr $@ $(OBJS_$(MOD_NAME))
|
|
||||||
|
|
||||||
$(MOD_BUILD_D)/%.c.o: $(MOD_SRC_D)/%.c $(INIT_DEP)
|
|
||||||
$(CC) $(CFLAGS) -c -o $@ $<
|
|
||||||
|
|
||||||
$(MOD_BUILD_D)/%.cpp.o: $(MOD_SRC_D)/%.cpp $(INIT_DEP)
|
|
||||||
$(CXX) $(CXXFLAGS) -c -o $@ $<
|
|
||||||
|
|
||||||
$(MOD_BUILD_D)/%.s.o: $(MOD_SRC_D)/%.s $(BUILD_D)/versions.s $(INIT_DEP)
|
|
||||||
$(AS) $(ASFLAGS) -i $(MOD_SRC_D)/ -o $@ $<
|
|
||||||
|
|
||||||
DEPS += $(patsubst %.o,%.d,$(OBJS_$(MOD_NAME)))
|
|
||||||
|
|
||||||
65
other_software.md
Normal file
65
other_software.md
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
# Included works
|
||||||
|
|
||||||
|
jsix includes and/or is derived from a number of other works, listed here.
|
||||||
|
|
||||||
|
## Catch2
|
||||||
|
|
||||||
|
jsix uses [Catch2][] for testing. Catch2 is released under the terms of the
|
||||||
|
Boost Software license:
|
||||||
|
|
||||||
|
[Catch2]: https://github.com/catchorg/Catch2
|
||||||
|
|
||||||
|
> Boost Software License - Version 1.0 - August 17th, 2003
|
||||||
|
>
|
||||||
|
> Permission is hereby granted, free of charge, to any person or organization
|
||||||
|
> obtaining a copy of the software and accompanying documentation covered by
|
||||||
|
> this license (the "Software") to use, reproduce, display, distribute,
|
||||||
|
> execute, and transmit the Software, and to prepare derivative works of the
|
||||||
|
> Software, and to permit third-parties to whom the Software is furnished to
|
||||||
|
> do so, all subject to the following:
|
||||||
|
>
|
||||||
|
> The copyright notices in the Software and this entire statement, including
|
||||||
|
> the above license grant, this restriction and the following disclaimer,
|
||||||
|
> must be included in all copies of the Software, in whole or in part, and
|
||||||
|
> all derivative works of the Software, unless such copies or derivative
|
||||||
|
> works are solely in the form of machine-executable object code generated by
|
||||||
|
> a source language processor.
|
||||||
|
>
|
||||||
|
> 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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||||
|
> SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||||
|
> FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||||
|
> ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
> DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
## printf
|
||||||
|
|
||||||
|
The implementation of jsix's `*printf()` family of functions is derived from
|
||||||
|
Marco Paland and Eyal Rozenberg's tiny [printf][] library, which is also
|
||||||
|
released under the terms of the MIT license:
|
||||||
|
|
||||||
|
[printf]: https://github.com/eyalroz/printf
|
||||||
|
|
||||||
|
> The MIT License (MIT)
|
||||||
|
>
|
||||||
|
> Copyright (c) 2014 Marco Paland
|
||||||
|
> Copyright (c) 2021 Eyal Rozenberg
|
||||||
|
>
|
||||||
|
> Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
> of this software and associated documentation files (the "Software"), to deal
|
||||||
|
> in the Software without restriction, including without limitation the rights
|
||||||
|
> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
> copies of the Software, and to permit persons to whom the Software is
|
||||||
|
> furnished to do so, subject to the following conditions:
|
||||||
|
>
|
||||||
|
> The above copyright notice and this permission notice shall be included in all
|
||||||
|
> copies or substantial portions of the Software.
|
||||||
|
>
|
||||||
|
> 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 OR COPYRIGHT HOLDERS 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.
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
#
|
|
||||||
# parse_version.py - Create a NASM version definition file given
|
|
||||||
# version inputs. Usage:
|
|
||||||
#
|
|
||||||
# parse_version.py <git-describe version> <git short sha>
|
|
||||||
|
|
||||||
|
|
||||||
def split_version(version_string):
|
|
||||||
major, minor, patch_dirty = version_string.split(".")
|
|
||||||
patch_dirty = patch_dirty.split("-")
|
|
||||||
|
|
||||||
return major, minor, patch_dirty[0], len(patch_dirty) > 1
|
|
||||||
|
|
||||||
|
|
||||||
def make_nasm(major, minor, patch, dirty, sha):
|
|
||||||
if dirty:
|
|
||||||
dirty = "1"
|
|
||||||
else:
|
|
||||||
dirty = "0"
|
|
||||||
|
|
||||||
lines = [
|
|
||||||
"%define VERSION_MAJOR {}".format(major),
|
|
||||||
"%define VERSION_MINOR {}".format(minor),
|
|
||||||
"%define VERSION_PATCH {}".format(patch),
|
|
||||||
"%define VERSION_GITSHA 0x{}{}".format(dirty, sha),
|
|
||||||
]
|
|
||||||
return "\n".join(lines)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
import sys
|
|
||||||
if len(sys.argv) != 3:
|
|
||||||
print("Usage: {} <desc version> <git sha>".format(sys.argv[0]), file=sys.stderr)
|
|
||||||
sys.exit(1)
|
|
||||||
print(make_nasm(*split_version(sys.argv[1]), sys.argv[2]))
|
|
||||||
3
qemu.bat
3
qemu.bat
@@ -1,3 +0,0 @@
|
|||||||
call make.bat
|
|
||||||
del popcorn.log
|
|
||||||
qemu-system-x86_64.exe -bios .\assets\ovmf\x64\OVMF.fd -hda .\build\fs.img -m 512 -vga cirrus -d guest_errors,int -D popcorn.log -no-reboot
|
|
||||||
98
qemu.sh
Executable file
98
qemu.sh
Executable file
@@ -0,0 +1,98 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
build="$(dirname $0)/build"
|
||||||
|
assets="$(dirname $0)/assets"
|
||||||
|
debug=""
|
||||||
|
isaexit='-device isa-debug-exit,iobase=0xf4,iosize=0x04'
|
||||||
|
debugtarget="${build}/jsix.elf"
|
||||||
|
gfx="-nographic"
|
||||||
|
vga="-vga none"
|
||||||
|
log=""
|
||||||
|
kvm=""
|
||||||
|
cpu="Broadwell,+pdpe1gb"
|
||||||
|
smp=4
|
||||||
|
|
||||||
|
while true; do
|
||||||
|
case "$1" in
|
||||||
|
-b | --debugboot)
|
||||||
|
debug="-s -S"
|
||||||
|
debugtarget="${build}/boot/boot.efi"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
-d | --debug)
|
||||||
|
debug="-s -S"
|
||||||
|
isaexit=""
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
-g | --gfx)
|
||||||
|
gfx=""
|
||||||
|
vga=""
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
-v | --vga)
|
||||||
|
vga=""
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
-k | --kvm)
|
||||||
|
kvm="-enable-kvm"
|
||||||
|
cpu="host"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
-c | --cpus)
|
||||||
|
smp=$2
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
|
-l | --log)
|
||||||
|
log="-d mmu,int,guest_errors -D jsix.log"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
if [ -d "$1" ]; then
|
||||||
|
build="$1"
|
||||||
|
shift
|
||||||
|
fi
|
||||||
|
break
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
if [[ ! -c /dev/kvm ]]; then
|
||||||
|
kvm=""
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! ninja -C "${build}"; then
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -n $TMUX ]]; then
|
||||||
|
if [[ -n $debug ]]; then
|
||||||
|
tmux split-window -h "gdb ${debugtarget}" &
|
||||||
|
else
|
||||||
|
tmux split-window -h -l 80 "sleep 1; telnet localhost 45455" &
|
||||||
|
tmux last-pane
|
||||||
|
tmux split-window -l 10 "sleep 1; telnet localhost 45454" &
|
||||||
|
fi
|
||||||
|
elif [[ $DESKTOP_SESSION = "i3" ]]; then
|
||||||
|
if [[ -n $debug ]]; then
|
||||||
|
i3-msg exec i3-sensible-terminal -- -e "gdb ${debugtarget}" &
|
||||||
|
else
|
||||||
|
i3-msg exec i3-sensible-terminal -- -e 'telnet localhost 45454' &
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
qemu-system-x86_64 \
|
||||||
|
-drive "if=pflash,format=raw,readonly,file=${assets}/ovmf/x64/ovmf_code.fd" \
|
||||||
|
-drive "if=pflash,format=raw,file=${build}/ovmf_vars.fd" \
|
||||||
|
-drive "format=raw,file=${build}/jsix.img" \
|
||||||
|
-monitor telnet:localhost:45454,server,nowait \
|
||||||
|
-serial stdio \
|
||||||
|
-serial telnet:localhost:45455,server,nowait \
|
||||||
|
-smp "${smp}" \
|
||||||
|
-m 4096 \
|
||||||
|
-cpu "${cpu}" \
|
||||||
|
-M q35 \
|
||||||
|
-no-reboot \
|
||||||
|
$isaexit $log $gfx $vga $kvm $debug
|
||||||
|
|
||||||
|
((result = ($? >> 1) - 1))
|
||||||
|
exit $result
|
||||||
5
requirements.txt
Normal file
5
requirements.txt
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
cogapp >= 3
|
||||||
|
ninja >= 1.10.2
|
||||||
|
peru >= 1.2.1
|
||||||
|
pyyaml >= 5.4
|
||||||
|
lark == 0.12.0
|
||||||
25
scripts/bonnibel/__init__.py
Normal file
25
scripts/bonnibel/__init__.py
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
from os.path import join
|
||||||
|
|
||||||
|
class BonnibelError(Exception):
|
||||||
|
def __init__(self, message):
|
||||||
|
self.message = message
|
||||||
|
|
||||||
|
def load_config(filename):
|
||||||
|
from yaml import safe_load
|
||||||
|
with open(filename, 'r') as infile:
|
||||||
|
return safe_load(infile.read())
|
||||||
|
|
||||||
|
def mod_rel(path):
|
||||||
|
return join("${module_dir}", path)
|
||||||
|
|
||||||
|
def target_rel(path, module=None):
|
||||||
|
if module:
|
||||||
|
return join("${target_dir}", module + ".dir", path)
|
||||||
|
else:
|
||||||
|
return join("${target_dir}", path)
|
||||||
|
|
||||||
|
def include_rel(path, module=None):
|
||||||
|
if module:
|
||||||
|
return join("${build_root}", "include", module, path)
|
||||||
|
else:
|
||||||
|
return join("${build_root}", "include", path)
|
||||||
103
scripts/bonnibel/manifest.py
Normal file
103
scripts/bonnibel/manifest.py
Normal file
@@ -0,0 +1,103 @@
|
|||||||
|
from . import BonnibelError
|
||||||
|
|
||||||
|
class Manifest:
|
||||||
|
from collections import namedtuple
|
||||||
|
Entry = namedtuple("Entry", ("module", "target", "output", "location", "description", "flags"))
|
||||||
|
|
||||||
|
flags = {
|
||||||
|
"graphical": 0x01,
|
||||||
|
"panic": 0x02,
|
||||||
|
"symbols": 0x04,
|
||||||
|
}
|
||||||
|
|
||||||
|
boot_flags = {
|
||||||
|
"debug": 0x01,
|
||||||
|
"test": 0x02,
|
||||||
|
}
|
||||||
|
|
||||||
|
def __init__(self, path, modules):
|
||||||
|
from . import load_config
|
||||||
|
|
||||||
|
config = load_config(path)
|
||||||
|
|
||||||
|
self.kernel = self.__build_entry(modules,
|
||||||
|
config.get("kernel", dict()),
|
||||||
|
name="kernel", target="kernel")
|
||||||
|
|
||||||
|
self.init = self.__build_entry(modules,
|
||||||
|
config.get("init", None))
|
||||||
|
|
||||||
|
self.programs = [self.__build_entry(modules, i)
|
||||||
|
for i in config.get("programs", tuple())]
|
||||||
|
|
||||||
|
self.flags = config.get("flags", tuple())
|
||||||
|
|
||||||
|
self.data = []
|
||||||
|
for d in config.get("data", tuple()):
|
||||||
|
self.add_data(**d)
|
||||||
|
|
||||||
|
def __build_entry(self, modules, config, target="user", name=None):
|
||||||
|
flags = tuple()
|
||||||
|
|
||||||
|
if isinstance(config, str):
|
||||||
|
name = config
|
||||||
|
elif isinstance(config, dict):
|
||||||
|
name = config.get("name", name)
|
||||||
|
target = config.get("target", target)
|
||||||
|
flags = config.get("flags", tuple())
|
||||||
|
if isinstance(flags, str):
|
||||||
|
flags = flags.split()
|
||||||
|
|
||||||
|
mod = modules.get(name)
|
||||||
|
if not mod:
|
||||||
|
raise BonnibelError(f"Manifest specifies unknown module '{name}'")
|
||||||
|
|
||||||
|
for f in flags:
|
||||||
|
if not f in Manifest.flags:
|
||||||
|
raise BonnibelError(f"Manifest specifies unknown flag '{f}'")
|
||||||
|
|
||||||
|
return Manifest.Entry(name, target, mod.output, mod.location, mod.description, flags)
|
||||||
|
|
||||||
|
def add_data(self, output, location, desc, flags=tuple()):
|
||||||
|
e = Manifest.Entry(None, None, output, location, desc, flags)
|
||||||
|
self.data.append(e)
|
||||||
|
return e
|
||||||
|
|
||||||
|
def write_boot_config(self, path):
|
||||||
|
from os.path import join
|
||||||
|
import struct
|
||||||
|
|
||||||
|
with open(path, 'wb') as outfile:
|
||||||
|
magic = "jsixboot".encode("utf-8") # magic string
|
||||||
|
version = 0
|
||||||
|
reserved = 0
|
||||||
|
|
||||||
|
bootflags = sum([Manifest.boot_flags.get(s, 0) for s in self.flags])
|
||||||
|
|
||||||
|
outfile.write(struct.pack("<8sBBHHH",
|
||||||
|
magic, version, reserved,
|
||||||
|
len(self.programs), len(self.data),
|
||||||
|
bootflags))
|
||||||
|
|
||||||
|
def write_str(s):
|
||||||
|
outfile.write(struct.pack("<H", (len(s)+1)*2))
|
||||||
|
outfile.write(s.encode("utf-16le"))
|
||||||
|
outfile.write(b"\0\0")
|
||||||
|
|
||||||
|
def write_ent(ent):
|
||||||
|
flags = 0
|
||||||
|
for f in ent.flags:
|
||||||
|
flags |= Manifest.flags[f]
|
||||||
|
|
||||||
|
outfile.write(struct.pack("<H", flags))
|
||||||
|
write_str(join(ent.location, ent.output).replace('/','\\'))
|
||||||
|
write_str(ent.description)
|
||||||
|
|
||||||
|
write_ent(self.kernel)
|
||||||
|
write_ent(self.init)
|
||||||
|
|
||||||
|
for p in self.programs:
|
||||||
|
write_ent(p)
|
||||||
|
|
||||||
|
for d in self.data:
|
||||||
|
write_ent(d)
|
||||||
276
scripts/bonnibel/module.py
Normal file
276
scripts/bonnibel/module.py
Normal file
@@ -0,0 +1,276 @@
|
|||||||
|
from . import include_rel, mod_rel, target_rel
|
||||||
|
|
||||||
|
def resolve(path):
|
||||||
|
if path.startswith('/') or path.startswith('$'):
|
||||||
|
return path
|
||||||
|
from pathlib import Path
|
||||||
|
return str(Path(path).resolve())
|
||||||
|
|
||||||
|
class BuildOptions:
|
||||||
|
def __init__(self, includes=tuple(), libs=tuple(), order_only=tuple()):
|
||||||
|
self.includes = list(includes)
|
||||||
|
self.libs = list(libs)
|
||||||
|
self.order_only = list(order_only)
|
||||||
|
|
||||||
|
|
||||||
|
class Module:
|
||||||
|
__fields = {
|
||||||
|
# name: (type, default)
|
||||||
|
"kind": (str, "exe"),
|
||||||
|
"output": (str, None),
|
||||||
|
"targets": (set, ()),
|
||||||
|
"deps": (set, ()),
|
||||||
|
"public_headers": (set, ()),
|
||||||
|
"includes": (tuple, ()),
|
||||||
|
"sources": (tuple, ()),
|
||||||
|
"variables": (dict, ()),
|
||||||
|
"default": (bool, False),
|
||||||
|
"location": (str, "jsix"),
|
||||||
|
"description": (str, None),
|
||||||
|
"no_libc": (bool, False),
|
||||||
|
}
|
||||||
|
|
||||||
|
def __init__(self, name, modfile, root, **kwargs):
|
||||||
|
from .source import make_source
|
||||||
|
|
||||||
|
# Required fields
|
||||||
|
self.root = root
|
||||||
|
self.name = name
|
||||||
|
self.modfile = modfile
|
||||||
|
|
||||||
|
for name, data in self.__fields.items():
|
||||||
|
ctor, default = data
|
||||||
|
value = kwargs.get(name, default)
|
||||||
|
if value is not None:
|
||||||
|
value = ctor(value)
|
||||||
|
|
||||||
|
setattr(self, name, value)
|
||||||
|
|
||||||
|
for name in kwargs:
|
||||||
|
if not name in self.__fields:
|
||||||
|
raise AttributeError(f"No attribute named {name} on Module")
|
||||||
|
|
||||||
|
# Turn strings into real Source objects
|
||||||
|
self.sources = [make_source(root, f) for f in self.sources]
|
||||||
|
self.public_headers = [make_source(root, f) for f in self.public_headers]
|
||||||
|
|
||||||
|
# Filled by Module.update
|
||||||
|
self.depmods = set()
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return "Module {} {}\n\t{}".format(self.kind, self.name, "\n\t".join(map(str, self.sources)))
|
||||||
|
|
||||||
|
@property
|
||||||
|
def output(self):
|
||||||
|
if self.__output is not None:
|
||||||
|
return self.__output
|
||||||
|
|
||||||
|
if self.kind == "lib":
|
||||||
|
return f"lib{self.name}.a"
|
||||||
|
else:
|
||||||
|
return f"{self.name}.elf"
|
||||||
|
|
||||||
|
@output.setter
|
||||||
|
def output(self, value):
|
||||||
|
self.__output = value
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def update(cls, mods):
|
||||||
|
from . import BonnibelError
|
||||||
|
|
||||||
|
def resolve(source, modlist):
|
||||||
|
resolved = set()
|
||||||
|
for dep in modlist:
|
||||||
|
if not dep in mods:
|
||||||
|
raise BonnibelError(f"module '{source.name}' references unknown module '{dep}'")
|
||||||
|
mod = mods[dep]
|
||||||
|
resolved.add(mod)
|
||||||
|
return resolved
|
||||||
|
|
||||||
|
for mod in mods.values():
|
||||||
|
mod.depmods = resolve(mod, mod.deps)
|
||||||
|
|
||||||
|
target_mods = [mod for mod in mods.values() if mod.targets]
|
||||||
|
for mod in target_mods:
|
||||||
|
closed = set()
|
||||||
|
children = set(mod.depmods)
|
||||||
|
while children:
|
||||||
|
child = children.pop()
|
||||||
|
closed.add(child)
|
||||||
|
child.targets |= mod.targets
|
||||||
|
children |= {m for m in child.depmods if not m in closed}
|
||||||
|
|
||||||
|
def generate(self, output):
|
||||||
|
from pathlib import Path
|
||||||
|
from collections import defaultdict
|
||||||
|
from ninja.ninja_syntax import Writer
|
||||||
|
|
||||||
|
def walk_deps(deps):
|
||||||
|
open_set = set(deps)
|
||||||
|
closed_set = set()
|
||||||
|
while open_set:
|
||||||
|
dep = open_set.pop()
|
||||||
|
closed_set.add(dep)
|
||||||
|
open_set |= {m for m in dep.depmods if not m in closed_set}
|
||||||
|
return closed_set
|
||||||
|
|
||||||
|
all_deps = walk_deps(self.depmods)
|
||||||
|
|
||||||
|
def gather_phony(build, deps, child_rel, add_headers=False):
|
||||||
|
phony = ".headers.phony"
|
||||||
|
child_phony = [child_rel(phony, module=c.name)
|
||||||
|
for c in all_deps]
|
||||||
|
|
||||||
|
header_targets = []
|
||||||
|
if add_headers:
|
||||||
|
if not self.no_libc:
|
||||||
|
header_targets.append(f"${{build_root}}/include/libc/{phony}")
|
||||||
|
if self.public_headers:
|
||||||
|
header_targets.append(f"${{build_root}}/include/{self.name}/{phony}")
|
||||||
|
|
||||||
|
build.build(
|
||||||
|
rule = "touch",
|
||||||
|
outputs = [mod_rel(phony)],
|
||||||
|
implicit = child_phony + header_targets,
|
||||||
|
order_only = list(map(mod_rel, deps)),
|
||||||
|
)
|
||||||
|
|
||||||
|
filename = str(output / f"headers.{self.name}.ninja")
|
||||||
|
with open(filename, "w") as buildfile:
|
||||||
|
build = Writer(buildfile)
|
||||||
|
|
||||||
|
build.comment("This file is automatically generated by bonnibel")
|
||||||
|
build.newline()
|
||||||
|
|
||||||
|
build.variable("module_dir", f"${{build_root}}/include/{self.name}")
|
||||||
|
|
||||||
|
header_deps = []
|
||||||
|
|
||||||
|
inputs = []
|
||||||
|
headers = set(self.public_headers)
|
||||||
|
while headers:
|
||||||
|
source = headers.pop()
|
||||||
|
headers.update(source.next)
|
||||||
|
|
||||||
|
if source.action:
|
||||||
|
build.newline()
|
||||||
|
build.build(rule=source.action, **source.args)
|
||||||
|
|
||||||
|
if source.gather:
|
||||||
|
header_deps += list(source.outputs)
|
||||||
|
|
||||||
|
if source.input:
|
||||||
|
inputs.extend(map(mod_rel, source.outputs))
|
||||||
|
|
||||||
|
build.newline()
|
||||||
|
gather_phony(build, header_deps, include_rel)
|
||||||
|
|
||||||
|
filename = str(output / f"module.{self.name}.ninja")
|
||||||
|
with open(filename, "w") as buildfile:
|
||||||
|
build = Writer(buildfile)
|
||||||
|
|
||||||
|
build.comment("This file is automatically generated by bonnibel")
|
||||||
|
build.newline()
|
||||||
|
|
||||||
|
build.variable("module_dir", target_rel(self.name + ".dir"))
|
||||||
|
|
||||||
|
modopts = BuildOptions(
|
||||||
|
includes = [self.root, "${module_dir}"],
|
||||||
|
)
|
||||||
|
if self.public_headers:
|
||||||
|
modopts.includes += [f"${{build_root}}/include/{self.name}"]
|
||||||
|
|
||||||
|
for key, value in self.variables.items():
|
||||||
|
build.variable(key, value)
|
||||||
|
build.newline()
|
||||||
|
|
||||||
|
for include in self.includes:
|
||||||
|
p = Path(include)
|
||||||
|
if p.is_absolute():
|
||||||
|
if not p in modopts.includes:
|
||||||
|
modopts.includes.append(str(p.resolve()))
|
||||||
|
elif include != ".":
|
||||||
|
incpath = self.root / p
|
||||||
|
destpath = mod_rel(p)
|
||||||
|
for header in incpath.rglob("*.h"):
|
||||||
|
dest_header = f"{destpath}/" + str(header.relative_to(incpath))
|
||||||
|
modopts.includes.append(str(incpath))
|
||||||
|
modopts.includes.append(destpath)
|
||||||
|
|
||||||
|
all_deps = walk_deps(self.depmods)
|
||||||
|
for dep in all_deps:
|
||||||
|
if dep.public_headers:
|
||||||
|
modopts.includes += [f"${{build_root}}/include/{dep.name}"]
|
||||||
|
|
||||||
|
if dep.kind == "lib":
|
||||||
|
modopts.libs.append(target_rel(dep.output))
|
||||||
|
else:
|
||||||
|
modopts.order_only.append(target_rel(dep.output))
|
||||||
|
|
||||||
|
if modopts.includes:
|
||||||
|
build.variable("ccflags", ["${ccflags}"] + [f"-I{i}" for i in modopts.includes])
|
||||||
|
build.variable("asflags", ["${asflags}"] + [f"-I{i}" for i in modopts.includes])
|
||||||
|
|
||||||
|
if modopts.libs:
|
||||||
|
build.variable("libs", ["${libs}"] + modopts.libs)
|
||||||
|
|
||||||
|
header_deps = []
|
||||||
|
|
||||||
|
inputs = []
|
||||||
|
sources = set(self.sources)
|
||||||
|
while sources:
|
||||||
|
source = sources.pop()
|
||||||
|
sources.update(source.next)
|
||||||
|
|
||||||
|
if source.action:
|
||||||
|
build.newline()
|
||||||
|
build.build(rule=source.action, **source.args)
|
||||||
|
|
||||||
|
if source.gather:
|
||||||
|
header_deps += list(source.outputs)
|
||||||
|
|
||||||
|
if source.input:
|
||||||
|
inputs.extend(map(mod_rel, source.outputs))
|
||||||
|
|
||||||
|
build.newline()
|
||||||
|
|
||||||
|
gather_phony(build, header_deps, target_rel, add_headers=True)
|
||||||
|
|
||||||
|
output = target_rel(self.output)
|
||||||
|
dump = output + ".dump"
|
||||||
|
build.newline()
|
||||||
|
build.build(
|
||||||
|
rule = self.kind,
|
||||||
|
outputs = output,
|
||||||
|
inputs = inputs,
|
||||||
|
implicit = modopts.libs,
|
||||||
|
order_only = modopts.order_only,
|
||||||
|
)
|
||||||
|
|
||||||
|
build.newline()
|
||||||
|
build.build(
|
||||||
|
rule = "dump",
|
||||||
|
outputs = dump,
|
||||||
|
inputs = output,
|
||||||
|
variables = {"name": self.name},
|
||||||
|
)
|
||||||
|
|
||||||
|
if self.default:
|
||||||
|
build.newline()
|
||||||
|
build.default(output)
|
||||||
|
build.default(dump)
|
||||||
|
|
||||||
|
def add_input(self, path, **kwargs):
|
||||||
|
from .source import Source
|
||||||
|
s = Source(self.root, path, **kwargs)
|
||||||
|
self.sources.append(s)
|
||||||
|
return s.outputs
|
||||||
|
|
||||||
|
def add_depends(self, paths, deps):
|
||||||
|
for source in self.sources:
|
||||||
|
if source.path in paths:
|
||||||
|
source.add_deps(deps)
|
||||||
|
|
||||||
|
for source in self.public_headers:
|
||||||
|
if source.path in paths:
|
||||||
|
source.add_deps(deps)
|
||||||
234
scripts/bonnibel/project.py
Normal file
234
scripts/bonnibel/project.py
Normal file
@@ -0,0 +1,234 @@
|
|||||||
|
from . import BonnibelError
|
||||||
|
|
||||||
|
class Project:
|
||||||
|
def __init__(self, root):
|
||||||
|
from .version import git_version
|
||||||
|
|
||||||
|
self.root = root
|
||||||
|
self.version = git_version(root)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return f"{self.name} {self.version.major}.{self.version.minor}.{self.version.patch}-{self.version.sha}"
|
||||||
|
|
||||||
|
def generate(self, root, output, modules, config, manifest_file):
|
||||||
|
import sys
|
||||||
|
import bonnibel
|
||||||
|
from os.path import join
|
||||||
|
from ninja.ninja_syntax import Writer
|
||||||
|
from .target import Target
|
||||||
|
|
||||||
|
targets = set()
|
||||||
|
for mod in modules.values():
|
||||||
|
targets.update({Target.load(root, t, config) for t in mod.targets})
|
||||||
|
|
||||||
|
with open(output / "build.ninja", "w") as buildfile:
|
||||||
|
build = Writer(buildfile)
|
||||||
|
|
||||||
|
build.comment("This file is automatically generated by bonnibel")
|
||||||
|
build.variable("ninja_required_version", "1.3")
|
||||||
|
build.variable("build_root", output)
|
||||||
|
build.variable("source_root", root)
|
||||||
|
build.newline()
|
||||||
|
|
||||||
|
build.include(root / "configs" / "rules.ninja")
|
||||||
|
build.newline()
|
||||||
|
|
||||||
|
build.variable("version_major", self.version.major)
|
||||||
|
build.variable("version_minor", self.version.minor)
|
||||||
|
build.variable("version_patch", self.version.patch)
|
||||||
|
build.variable("version_sha", self.version.sha)
|
||||||
|
build.newline()
|
||||||
|
|
||||||
|
build.variable("cogflags", [
|
||||||
|
"-I", "${source_root}/scripts",
|
||||||
|
"-D", "definitions_path=${source_root}/definitions",
|
||||||
|
])
|
||||||
|
build.newline()
|
||||||
|
|
||||||
|
for target in targets:
|
||||||
|
build.subninja(output / target.name / "target.ninja")
|
||||||
|
build.newline()
|
||||||
|
|
||||||
|
for mod in modules.values():
|
||||||
|
build.subninja(output / f"headers.{mod.name}.ninja")
|
||||||
|
build.newline()
|
||||||
|
|
||||||
|
build.build(
|
||||||
|
rule = "touch",
|
||||||
|
outputs = "${build_root}/.all_headers",
|
||||||
|
implicit = [f"${{build_root}}/include/{m.name}/.headers.phony"
|
||||||
|
for m in modules.values() if m.public_headers],
|
||||||
|
)
|
||||||
|
build.build(
|
||||||
|
rule = "phony",
|
||||||
|
outputs = ["all-headers"],
|
||||||
|
inputs = ["${build_root}/.all_headers"])
|
||||||
|
|
||||||
|
debugroot = output / ".debug"
|
||||||
|
debugroot.mkdir(exist_ok=True)
|
||||||
|
|
||||||
|
fatroot = output / "fatroot"
|
||||||
|
fatroot.mkdir(exist_ok=True)
|
||||||
|
|
||||||
|
fatroot_content = []
|
||||||
|
|
||||||
|
def add_fatroot(source, entry):
|
||||||
|
output = join(entry.location, entry.output)
|
||||||
|
fatroot_output = f"${{build_root}}/fatroot/{output}"
|
||||||
|
|
||||||
|
build.build(
|
||||||
|
rule = "cp",
|
||||||
|
outputs = [fatroot_output],
|
||||||
|
inputs = [source],
|
||||||
|
variables = {
|
||||||
|
"name": f"Installing {output}",
|
||||||
|
})
|
||||||
|
|
||||||
|
fatroot_content.append(fatroot_output)
|
||||||
|
build.newline()
|
||||||
|
|
||||||
|
def add_fatroot_exe(entry):
|
||||||
|
input_path = f"${{build_root}}/{entry.target}/{entry.output}"
|
||||||
|
intermediary = f"${{build_root}}/{entry.output}"
|
||||||
|
|
||||||
|
build.build(
|
||||||
|
rule = "strip",
|
||||||
|
outputs = [intermediary],
|
||||||
|
inputs = [input_path],
|
||||||
|
implicit = [f"{input_path}.dump"],
|
||||||
|
variables = {
|
||||||
|
"name": f"Stripping {entry.module}",
|
||||||
|
"debug": f"${{build_root}}/.debug/{entry.output}.debug",
|
||||||
|
})
|
||||||
|
|
||||||
|
add_fatroot(intermediary, entry)
|
||||||
|
|
||||||
|
from .manifest import Manifest
|
||||||
|
manifest = Manifest(manifest_file, modules)
|
||||||
|
|
||||||
|
add_fatroot_exe(manifest.kernel)
|
||||||
|
add_fatroot_exe(manifest.init)
|
||||||
|
for program in manifest.programs:
|
||||||
|
add_fatroot_exe(program)
|
||||||
|
|
||||||
|
syms = manifest.add_data("symbol_table.dat",
|
||||||
|
manifest.kernel.location, "Symbol table", ("symbols",))
|
||||||
|
|
||||||
|
sym_out = f"${{build_root}}/symbol_table.dat"
|
||||||
|
build.build(
|
||||||
|
rule = "makest",
|
||||||
|
outputs = [sym_out],
|
||||||
|
inputs = [f"${{build_root}}/{modules['kernel'].output}"],
|
||||||
|
)
|
||||||
|
add_fatroot(sym_out, syms)
|
||||||
|
|
||||||
|
bootloader = "${build_root}/fatroot/efi/boot/bootx64.efi"
|
||||||
|
build.build(
|
||||||
|
rule = "cp",
|
||||||
|
outputs = [bootloader],
|
||||||
|
inputs = ["${build_root}/boot/boot.efi"],
|
||||||
|
variables = {
|
||||||
|
"name": "Installing bootloader",
|
||||||
|
})
|
||||||
|
build.newline()
|
||||||
|
|
||||||
|
boot_config = join(fatroot, "jsix_boot.dat")
|
||||||
|
manifest.write_boot_config(boot_config)
|
||||||
|
|
||||||
|
build.build(
|
||||||
|
rule = "makefat",
|
||||||
|
outputs = ["${build_root}/jsix.img"],
|
||||||
|
inputs = ["${source_root}/assets/diskbase.img"],
|
||||||
|
implicit = fatroot_content + [bootloader],
|
||||||
|
variables = {"name": "jsix.img"},
|
||||||
|
)
|
||||||
|
build.newline()
|
||||||
|
|
||||||
|
default_assets = {
|
||||||
|
"UEFI Variables": ("ovmf/x64/ovmf_vars.fd", "ovmf_vars.fd"),
|
||||||
|
"GDB Debug Helpers": ("debugging/jsix.elf-gdb.py", "jsix.elf-gdb.py"),
|
||||||
|
}
|
||||||
|
|
||||||
|
for name, assets in default_assets.items():
|
||||||
|
p = root / "assets" / assets[0]
|
||||||
|
out = f"${{build_root}}/{assets[1]}"
|
||||||
|
build.build(
|
||||||
|
rule = "cp",
|
||||||
|
outputs = [out],
|
||||||
|
inputs = [str(p)],
|
||||||
|
variables = {"name": name},
|
||||||
|
)
|
||||||
|
build.default([out])
|
||||||
|
build.newline()
|
||||||
|
|
||||||
|
compdb = "${source_root}/compile_commands.json"
|
||||||
|
|
||||||
|
build.rule("regen",
|
||||||
|
command = " ".join([str(root / 'configure')] + sys.argv[1:]),
|
||||||
|
description = "Regenerate build files",
|
||||||
|
generator = True,
|
||||||
|
)
|
||||||
|
build.newline()
|
||||||
|
|
||||||
|
regen_implicits = \
|
||||||
|
[f"{self.root}/configure", str(manifest_file)] + \
|
||||||
|
[str(mod.modfile) for mod in modules.values()]
|
||||||
|
|
||||||
|
for target in targets:
|
||||||
|
regen_implicits += target.depfiles
|
||||||
|
|
||||||
|
build.build(
|
||||||
|
rule = "compdb",
|
||||||
|
outputs = [compdb],
|
||||||
|
implicit = regen_implicits,
|
||||||
|
)
|
||||||
|
build.default([compdb])
|
||||||
|
build.newline()
|
||||||
|
|
||||||
|
build.build(
|
||||||
|
rule = "regen",
|
||||||
|
outputs = ['build.ninja'],
|
||||||
|
implicit = regen_implicits,
|
||||||
|
implicit_outputs =
|
||||||
|
[f"module.{mod.name}.ninja" for mod in modules.values()] +
|
||||||
|
[f"{target.name}/target.ninja" for target in targets] +
|
||||||
|
[boot_config],
|
||||||
|
)
|
||||||
|
|
||||||
|
build.newline()
|
||||||
|
build.default(["${build_root}/jsix.img"])
|
||||||
|
|
||||||
|
for target in targets:
|
||||||
|
mods = [m.name for m in modules.values() if target.name in m.targets]
|
||||||
|
|
||||||
|
targetdir = output / target.name
|
||||||
|
targetdir.mkdir(exist_ok=True)
|
||||||
|
|
||||||
|
buildfilename = str(targetdir / "target.ninja")
|
||||||
|
with open(buildfilename, "w") as buildfile:
|
||||||
|
build = Writer(buildfile)
|
||||||
|
build.comment("This file is automatically generated by bonnibel")
|
||||||
|
build.newline()
|
||||||
|
|
||||||
|
build.variable("target", target.name)
|
||||||
|
build.variable("target_dir", output / target.name)
|
||||||
|
build.newline()
|
||||||
|
|
||||||
|
for name, value in target.items():
|
||||||
|
build.variable(name, value)
|
||||||
|
|
||||||
|
build.newline()
|
||||||
|
for kind in ('defs', 'run'):
|
||||||
|
for lang in ('c', 'cpp'):
|
||||||
|
deffile = str(output / target.name / f"{lang}.{kind}")
|
||||||
|
|
||||||
|
build.build(
|
||||||
|
rule = f"dump_{lang}_{kind}",
|
||||||
|
outputs = [deffile],
|
||||||
|
implicit = [buildfilename],
|
||||||
|
)
|
||||||
|
build.default(deffile)
|
||||||
|
build.newline()
|
||||||
|
|
||||||
|
for mod in mods:
|
||||||
|
build.subninja(f"module.{mod}.ninja")
|
||||||
119
scripts/bonnibel/source.py
Normal file
119
scripts/bonnibel/source.py
Normal file
@@ -0,0 +1,119 @@
|
|||||||
|
from os.path import join, splitext
|
||||||
|
from . import mod_rel
|
||||||
|
|
||||||
|
def _resolve(path):
|
||||||
|
if path.startswith('/') or path.startswith('$'):
|
||||||
|
return path
|
||||||
|
from pathlib import Path
|
||||||
|
return str(Path(path).resolve())
|
||||||
|
|
||||||
|
def _dynamic_action(name):
|
||||||
|
def prop(self):
|
||||||
|
root, suffix = splitext(self.path)
|
||||||
|
return f"{name}{suffix}"
|
||||||
|
return prop
|
||||||
|
|
||||||
|
|
||||||
|
class Source:
|
||||||
|
next = tuple()
|
||||||
|
action = None
|
||||||
|
args = dict()
|
||||||
|
gather = False
|
||||||
|
outputs = tuple()
|
||||||
|
input = False
|
||||||
|
|
||||||
|
def __init__(self, path, root = "${module_dir}", deps=tuple()):
|
||||||
|
self.path = path
|
||||||
|
self.root = root
|
||||||
|
self.deps = deps
|
||||||
|
|
||||||
|
def add_deps(self, deps):
|
||||||
|
self.deps += tuple(deps)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def fullpath(self):
|
||||||
|
return join(self.root, self.path)
|
||||||
|
|
||||||
|
class ParseSource(Source):
|
||||||
|
action = property(_dynamic_action("parse"))
|
||||||
|
|
||||||
|
@property
|
||||||
|
def output(self):
|
||||||
|
root, _ = splitext(self.path)
|
||||||
|
return root
|
||||||
|
|
||||||
|
@property
|
||||||
|
def outputs(self):
|
||||||
|
return (self.output,)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def gather(self):
|
||||||
|
_, suffix = splitext(self.output)
|
||||||
|
return suffix in (".h", ".inc")
|
||||||
|
|
||||||
|
@property
|
||||||
|
def next(self):
|
||||||
|
_, suffix = splitext(self.output)
|
||||||
|
nextType = {
|
||||||
|
".s": CompileSource,
|
||||||
|
".cpp": CompileSource,
|
||||||
|
}.get(suffix)
|
||||||
|
|
||||||
|
if nextType:
|
||||||
|
return (nextType(self.output),)
|
||||||
|
return tuple()
|
||||||
|
|
||||||
|
@property
|
||||||
|
def args(self):
|
||||||
|
return dict(
|
||||||
|
outputs = list(map(mod_rel, self.outputs)),
|
||||||
|
inputs = [self.fullpath],
|
||||||
|
implicit = list(map(_resolve, self.deps)),
|
||||||
|
variables = dict(name=self.path),
|
||||||
|
)
|
||||||
|
|
||||||
|
class HeaderSource(Source):
|
||||||
|
action = "cp"
|
||||||
|
gather = True
|
||||||
|
|
||||||
|
@property
|
||||||
|
def outputs(self):
|
||||||
|
return (self.path,)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def args(self):
|
||||||
|
return dict(
|
||||||
|
outputs = [mod_rel(self.path)],
|
||||||
|
inputs = [join(self.root, self.path)],
|
||||||
|
implicit = list(map(_resolve, self.deps)),
|
||||||
|
variables = dict(name=self.path),
|
||||||
|
)
|
||||||
|
|
||||||
|
class CompileSource(Source):
|
||||||
|
action = property(_dynamic_action("compile"))
|
||||||
|
input = True
|
||||||
|
|
||||||
|
@property
|
||||||
|
def outputs(self):
|
||||||
|
return (self.path + ".o",)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def args(self):
|
||||||
|
return dict(
|
||||||
|
outputs = list(map(mod_rel, self.outputs)),
|
||||||
|
inputs = [join(self.root, self.path)],
|
||||||
|
implicit = list(map(_resolve, self.deps)) + [mod_rel(".headers.phony")],
|
||||||
|
variables = dict(name=self.path),
|
||||||
|
)
|
||||||
|
|
||||||
|
def make_source(root, path):
|
||||||
|
_, suffix = splitext(path)
|
||||||
|
|
||||||
|
if suffix in (".s", ".c", ".cpp"):
|
||||||
|
return CompileSource(path, root)
|
||||||
|
elif suffix in (".cog",):
|
||||||
|
return ParseSource(path, root)
|
||||||
|
elif suffix in (".h", ".inc"):
|
||||||
|
return HeaderSource(path, root)
|
||||||
|
else:
|
||||||
|
raise RuntimeError(f"{path} has no Source type")
|
||||||
50
scripts/bonnibel/target.py
Normal file
50
scripts/bonnibel/target.py
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
class Target(dict):
|
||||||
|
__targets = {}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def load(cls, root, name, config=None):
|
||||||
|
from . import load_config
|
||||||
|
|
||||||
|
if (name, config) in cls.__targets:
|
||||||
|
return cls.__targets[(name, config)]
|
||||||
|
|
||||||
|
configs = root / "configs"
|
||||||
|
|
||||||
|
dicts = []
|
||||||
|
depfiles = []
|
||||||
|
basename = name
|
||||||
|
if config:
|
||||||
|
basename += f"-{config}"
|
||||||
|
|
||||||
|
while basename is not None:
|
||||||
|
filename = str(configs / (basename + ".yaml"))
|
||||||
|
depfiles.append(filename)
|
||||||
|
desc = load_config(filename)
|
||||||
|
basename = desc.get("extends")
|
||||||
|
dicts.append(desc.get("variables", dict()))
|
||||||
|
|
||||||
|
t = Target(name, config, depfiles)
|
||||||
|
for d in reversed(dicts):
|
||||||
|
for k, v in d.items():
|
||||||
|
if isinstance(v, (list, tuple)):
|
||||||
|
t[k] = t.get(k, list()) + list(v)
|
||||||
|
elif isinstance(v, dict):
|
||||||
|
t[k] = t.get(k, dict())
|
||||||
|
t[k].update(v)
|
||||||
|
else:
|
||||||
|
t[k] = v
|
||||||
|
|
||||||
|
cls.__targets[(name, config)] = t
|
||||||
|
return t
|
||||||
|
|
||||||
|
def __init__(self, name, config, depfiles):
|
||||||
|
self.__name = name
|
||||||
|
self.__config = config
|
||||||
|
self.__depfiles = tuple(depfiles)
|
||||||
|
|
||||||
|
def __hash__(self):
|
||||||
|
return hash((self.__name, self.__config))
|
||||||
|
|
||||||
|
name = property(lambda self: self.__name)
|
||||||
|
config = property(lambda self: self.__config)
|
||||||
|
depfiles = property(lambda self: self.__depfiles)
|
||||||
41
scripts/bonnibel/version.py
Normal file
41
scripts/bonnibel/version.py
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
from collections import namedtuple as _namedtuple
|
||||||
|
|
||||||
|
version = _namedtuple('version', [
|
||||||
|
'major',
|
||||||
|
'minor',
|
||||||
|
'patch',
|
||||||
|
'sha',
|
||||||
|
'dirty',
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
|
def _run_git(root, *args):
|
||||||
|
from subprocess import run
|
||||||
|
|
||||||
|
git = run(['git', '-C', root] + list(args),
|
||||||
|
check=True, capture_output=True)
|
||||||
|
return git.stdout.decode('utf-8').strip()
|
||||||
|
|
||||||
|
|
||||||
|
def git_version(root):
|
||||||
|
full_version = _run_git(root, 'describe', '--dirty')
|
||||||
|
full_sha = _run_git(root, 'rev-parse', 'HEAD')
|
||||||
|
|
||||||
|
dirty = False
|
||||||
|
parts1 = full_version.split('-')
|
||||||
|
if parts1[-1] == "dirty":
|
||||||
|
dirty = True
|
||||||
|
parts1 = parts1[:-1]
|
||||||
|
|
||||||
|
if parts1[0][0] == 'v':
|
||||||
|
parts1[0] = parts1[0][1:]
|
||||||
|
|
||||||
|
parts2 = parts1[0].split('.')
|
||||||
|
|
||||||
|
return version(
|
||||||
|
parts2[0],
|
||||||
|
parts2[1],
|
||||||
|
parts2[2],
|
||||||
|
full_sha[:7],
|
||||||
|
dirty)
|
||||||
|
|
||||||
72
scripts/build_symbol_table.py
Executable file
72
scripts/build_symbol_table.py
Executable file
@@ -0,0 +1,72 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
#
|
||||||
|
# Generate the jsix style symbol table. The format in memory of this table
|
||||||
|
# is as follows:
|
||||||
|
#
|
||||||
|
# <num_entires> : 8 bytes
|
||||||
|
# <index> : 24 * N bytes
|
||||||
|
# <name data> : variable
|
||||||
|
#
|
||||||
|
# Each index entry has the format
|
||||||
|
# <symbol address> : 8 bytes
|
||||||
|
# <symbol size> : 8 bytes
|
||||||
|
# <offset of name> : 8 bytes
|
||||||
|
#
|
||||||
|
# Name offsets are from the start of the symbol table as a whole. (ie,
|
||||||
|
# where <num_entries> is located.)
|
||||||
|
|
||||||
|
import re
|
||||||
|
|
||||||
|
sym_re = re.compile(r'([0-9a-fA-F]{16}) ([0-9a-fA-F]{16}) [tTvVwW] (.*)')
|
||||||
|
|
||||||
|
def parse_syms(infile):
|
||||||
|
"""Take the output of the `nm` command, and parse it into a tuple
|
||||||
|
representing the symbols in the text segment of the binary. Returns
|
||||||
|
a list of (address, symbol_name)."""
|
||||||
|
|
||||||
|
syms = []
|
||||||
|
for line in sys.stdin:
|
||||||
|
match = sym_re.match(line)
|
||||||
|
if not match: continue
|
||||||
|
|
||||||
|
addr = int(match.group(1), base=16)
|
||||||
|
size = int(match.group(2), base=16)
|
||||||
|
name = match.group(3)
|
||||||
|
syms.append([addr, size, name, 0])
|
||||||
|
|
||||||
|
return syms
|
||||||
|
|
||||||
|
|
||||||
|
def write_table(syms, outfile):
|
||||||
|
"""Write the given symbol table as generated by parse_syms()
|
||||||
|
to the outfile, index first, and then name character data."""
|
||||||
|
|
||||||
|
import struct
|
||||||
|
|
||||||
|
outfile.write(struct.pack("@Q", len(syms)))
|
||||||
|
index_pos = outfile.tell()
|
||||||
|
|
||||||
|
outfile.seek(struct.calcsize("@QQQ") * len(syms), 1)
|
||||||
|
nul = b'\0'
|
||||||
|
|
||||||
|
for s in syms:
|
||||||
|
s[3] = outfile.tell()
|
||||||
|
outfile.write(s[2].encode('utf-8'))
|
||||||
|
outfile.write(nul)
|
||||||
|
|
||||||
|
outfile.seek(index_pos)
|
||||||
|
for s in syms:
|
||||||
|
addr = s[0]
|
||||||
|
size = s[1]
|
||||||
|
pos = s[3]
|
||||||
|
outfile.write(struct.pack("@QQQ", addr, size, pos))
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
import sys
|
||||||
|
if len(sys.argv) != 2:
|
||||||
|
print(f"Usage: nm -n -S --demangle | {sys.argv[0]} <output>")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
outfile = open(sys.argv[1], "wb")
|
||||||
|
write_table(parse_syms(sys.stdin), outfile)
|
||||||
0
scripts/definitions/__init__.py
Normal file
0
scripts/definitions/__init__.py
Normal file
83
scripts/definitions/context.py
Normal file
83
scripts/definitions/context.py
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
class NotFound(Exception): pass
|
||||||
|
|
||||||
|
class Context:
|
||||||
|
def __init__(self, path, verbose=False):
|
||||||
|
if isinstance(path, str):
|
||||||
|
self.__paths = [path]
|
||||||
|
else:
|
||||||
|
self.__paths = path
|
||||||
|
|
||||||
|
self.__closed = set()
|
||||||
|
self.__verbose = verbose
|
||||||
|
|
||||||
|
self.__deps = {}
|
||||||
|
|
||||||
|
self.objects = dict()
|
||||||
|
self.interfaces = dict()
|
||||||
|
|
||||||
|
verbose = property(lambda self: self.__verbose)
|
||||||
|
|
||||||
|
def find(self, filename):
|
||||||
|
from os.path import exists, isabs, join
|
||||||
|
|
||||||
|
if exists(filename) or isabs(filename):
|
||||||
|
return filename
|
||||||
|
|
||||||
|
for path in self.__paths:
|
||||||
|
full = join(path, filename)
|
||||||
|
if exists(full):
|
||||||
|
return full
|
||||||
|
|
||||||
|
raise NotFound(filename)
|
||||||
|
|
||||||
|
def parse(self, filename):
|
||||||
|
pending = set()
|
||||||
|
pending.add(filename)
|
||||||
|
|
||||||
|
from .parser import LarkError
|
||||||
|
from .parser import Lark_StandAlone as Parser
|
||||||
|
from .transformer import DefTransformer
|
||||||
|
|
||||||
|
objects = {}
|
||||||
|
interfaces = {}
|
||||||
|
|
||||||
|
while pending:
|
||||||
|
name = pending.pop()
|
||||||
|
self.__closed.add(name)
|
||||||
|
|
||||||
|
path = self.find(name)
|
||||||
|
|
||||||
|
parser = Parser(transformer=DefTransformer(name))
|
||||||
|
|
||||||
|
try:
|
||||||
|
imps, objs, ints = parser.parse(open(path, "r").read())
|
||||||
|
except LarkError as e:
|
||||||
|
import sys
|
||||||
|
import textwrap
|
||||||
|
print(f"\nError parsing {name}:", file=sys.stderr)
|
||||||
|
print(textwrap.indent(str(e), " "), file=sys.stderr)
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
objects.update(objs)
|
||||||
|
interfaces.update(ints)
|
||||||
|
|
||||||
|
self.__deps[name] = imps
|
||||||
|
|
||||||
|
pending.update(imps.difference(self.__closed))
|
||||||
|
|
||||||
|
from .types import ObjectRef
|
||||||
|
ObjectRef.connect(objects)
|
||||||
|
|
||||||
|
for obj in objects.values():
|
||||||
|
for method in obj.methods:
|
||||||
|
caps = method.options.get("cap", list())
|
||||||
|
for cap in caps:
|
||||||
|
if not cap in obj.caps:
|
||||||
|
from .errors import UnknownCapError
|
||||||
|
raise UnknownCapError(f"Unknown capability {cap} on {obj.name}::{method.name}")
|
||||||
|
|
||||||
|
self.objects.update(objects)
|
||||||
|
self.interfaces.update(interfaces)
|
||||||
|
|
||||||
|
def deps(self):
|
||||||
|
return {self.find(k): tuple(map(self.find, v)) for k, v in self.__deps.items()}
|
||||||
3
scripts/definitions/errors.py
Normal file
3
scripts/definitions/errors.py
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
class InvalidType(Exception): pass
|
||||||
|
class UnknownTypeError(Exception): pass
|
||||||
|
class UnknownCapError(Exception): pass
|
||||||
2905
scripts/definitions/parser.py
Normal file
2905
scripts/definitions/parser.py
Normal file
File diff suppressed because one or more lines are too long
@@ -0,0 +1,23 @@
|
|||||||
|
%macro SYSCALL 2
|
||||||
|
global __syscall_%1
|
||||||
|
__syscall_%1:
|
||||||
|
push rbp
|
||||||
|
mov rbp, rsp
|
||||||
|
|
||||||
|
; args should already be in rdi, etc, but rcx will
|
||||||
|
; get stomped, so stash it in r10, which isn't a
|
||||||
|
; callee-saved register, but also isn't used in the
|
||||||
|
; function call ABI.
|
||||||
|
mov r10, rcx
|
||||||
|
|
||||||
|
mov rax, %2
|
||||||
|
syscall
|
||||||
|
; result is now already in rax, so just return
|
||||||
|
|
||||||
|
pop rbp
|
||||||
|
ret
|
||||||
|
%endmacro
|
||||||
|
|
||||||
|
{% for id, scope, method in interface.methods %}
|
||||||
|
SYSCALL {% if scope %}{{ scope.name }}_{% endif %}{{ method.name }} {{ id }}
|
||||||
|
{% endfor %}
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
#pragma once
|
||||||
|
/// \file {{filename}}
|
||||||
|
{% if object.super %}
|
||||||
|
|
||||||
|
#include <j6/{{ object.super.name }}.hh>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
namespace j6 {
|
||||||
|
|
||||||
|
{% if object.desc %}
|
||||||
|
{{ object.desc|indent('/// ', first=True) }}
|
||||||
|
{% endif %}
|
||||||
|
class {{ object.name }}
|
||||||
|
{% if object.super %} : public {{ object.super.name }}
|
||||||
|
{% endif %}
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
{% macro argument(type, name, first, options=False) -%}
|
||||||
|
{%- for ctype, suffix in type.c_names(options) -%}
|
||||||
|
{%- if not first or not loop.first %}, {% endif %}{{ ctype }} {{ name }}{{ suffix }}
|
||||||
|
{%- endfor -%}
|
||||||
|
{%- endmacro -%}
|
||||||
|
|
||||||
|
{% for method in object.methods %}
|
||||||
|
{% if method.desc %} /// {{ method.desc|indent(' /// ') }}{% endif %}
|
||||||
|
{% for param in method.params %}
|
||||||
|
{% if param.desc %} /// \arg {{ "%-10s"|format(param.name) }} {{ param.desc }}
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
{%+ if method.static %}static {% endif %}j6_status_t {{ method.name }} (
|
||||||
|
{%- for param in method.params %}{{ argument(param.type, param.name, loop.first, options=param.options) }}{% endfor -%});
|
||||||
|
|
||||||
|
{% endfor %}
|
||||||
|
~{{ object.name }}();
|
||||||
|
|
||||||
|
private:
|
||||||
|
{{ object.name }}(j6_handle_t handle) : m_handle {handle} {}
|
||||||
|
j6_handle_t m_handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace j6
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <j6/types.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
{% macro argument(type, name, first, options=False) -%}
|
||||||
|
{%- for ctype, suffix in type.c_names(options) -%}
|
||||||
|
{%- if not first or not loop.first %}, {% endif %}{{ ctype }} {{ name }}{{ suffix }}
|
||||||
|
{%- endfor -%}
|
||||||
|
{%- endmacro %}
|
||||||
|
|
||||||
|
{% for id, scope, method in interface.methods %}
|
||||||
|
j6_status_t __syscall_{% if scope %}{{ scope.name }}_{% endif %}{{ method.name }} (
|
||||||
|
{%- if not method.static -%}{{ argument(scope.reftype, "self", True) }}{% endif -%}
|
||||||
|
{%- set first = method.static -%}
|
||||||
|
{%- for param in method.params %}{{ argument(param.type, param.name, first, options=param.options) }}{% set first = False %}{% endfor -%}
|
||||||
|
);
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
156
scripts/definitions/transformer.py
Normal file
156
scripts/definitions/transformer.py
Normal file
@@ -0,0 +1,156 @@
|
|||||||
|
from .parser import Transformer, v_args
|
||||||
|
|
||||||
|
def get_opts(args):
|
||||||
|
from .types import Caps, CName, Description, Options, Type, UID
|
||||||
|
|
||||||
|
kinds = {
|
||||||
|
Description: "desc",
|
||||||
|
Options: "opts",
|
||||||
|
CName: "cname",
|
||||||
|
Caps: "caps",
|
||||||
|
UID: "uid",
|
||||||
|
Type: "typename",
|
||||||
|
}
|
||||||
|
|
||||||
|
result = dict()
|
||||||
|
outargs = []
|
||||||
|
for a in args:
|
||||||
|
for kind, name in kinds.items():
|
||||||
|
if isinstance(a, kind):
|
||||||
|
result[name] = a
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
outargs.append(a)
|
||||||
|
|
||||||
|
return result, outargs
|
||||||
|
|
||||||
|
class DefTransformer(Transformer):
|
||||||
|
def __init__(self, filename):
|
||||||
|
self.filename = filename
|
||||||
|
|
||||||
|
def start(self, args):
|
||||||
|
from .types import Import, Interface, Object
|
||||||
|
|
||||||
|
imports = set()
|
||||||
|
objects = dict()
|
||||||
|
interfaces = dict()
|
||||||
|
|
||||||
|
for o in args:
|
||||||
|
if isinstance(o, Object):
|
||||||
|
objects[o.name] = o
|
||||||
|
|
||||||
|
elif isinstance(o, Interface):
|
||||||
|
interfaces[o.name] = o
|
||||||
|
|
||||||
|
elif isinstance(o, Import):
|
||||||
|
imports.add(o)
|
||||||
|
|
||||||
|
return imports, objects, interfaces
|
||||||
|
|
||||||
|
@v_args(inline=True)
|
||||||
|
def import_statement(self, path):
|
||||||
|
from .types import Import
|
||||||
|
return Import(path)
|
||||||
|
|
||||||
|
def object(self, args):
|
||||||
|
from .types import Object
|
||||||
|
specials, args = get_opts(args)
|
||||||
|
name, args = args[0], args[1:]
|
||||||
|
return Object(name, children=args, **specials)
|
||||||
|
|
||||||
|
def interface(self, args):
|
||||||
|
from .types import Interface
|
||||||
|
specials, args = get_opts(args)
|
||||||
|
name, args = args[0], args[1:]
|
||||||
|
return Interface(name, children=args, **specials)
|
||||||
|
|
||||||
|
def method(self, args):
|
||||||
|
from .types import Method
|
||||||
|
specials, args = get_opts(args)
|
||||||
|
name, args = args[0], args[1:]
|
||||||
|
return Method(name, children=args, **specials)
|
||||||
|
|
||||||
|
def function(self, args):
|
||||||
|
from .types import Function
|
||||||
|
specials, args = get_opts(args)
|
||||||
|
name, args = args[0], args[1:]
|
||||||
|
return Function(name, children=args, **specials)
|
||||||
|
|
||||||
|
def param(self, args):
|
||||||
|
from .types import Param
|
||||||
|
specials, args = get_opts(args)
|
||||||
|
name = args[0]
|
||||||
|
return Param(name, **specials)
|
||||||
|
|
||||||
|
@v_args(inline=True)
|
||||||
|
def expose(self, s):
|
||||||
|
from .types import Expose
|
||||||
|
return Expose(s)
|
||||||
|
|
||||||
|
@v_args(inline=True)
|
||||||
|
def uid(self, s):
|
||||||
|
return s
|
||||||
|
|
||||||
|
@v_args(inline=True)
|
||||||
|
def cname(self, s):
|
||||||
|
from .types import CName
|
||||||
|
return CName(s)
|
||||||
|
|
||||||
|
@v_args(inline=True)
|
||||||
|
def name(self, s):
|
||||||
|
return s
|
||||||
|
|
||||||
|
@v_args(inline=True)
|
||||||
|
def type(self, s):
|
||||||
|
return s
|
||||||
|
|
||||||
|
@v_args(inline=True)
|
||||||
|
def super(self, s):
|
||||||
|
from .types import ObjectRef
|
||||||
|
return ObjectRef(s, self.filename)
|
||||||
|
|
||||||
|
def options(self, args):
|
||||||
|
from .types import Options
|
||||||
|
return Options([str(s) for s in args])
|
||||||
|
|
||||||
|
def capabilities(self, args):
|
||||||
|
from .types import Caps
|
||||||
|
return Caps([str(s) for s in args])
|
||||||
|
|
||||||
|
def description(self, s):
|
||||||
|
from .types import Description
|
||||||
|
return Description("\n".join(s))
|
||||||
|
|
||||||
|
@v_args(inline=True)
|
||||||
|
def object_name(self, n):
|
||||||
|
from .types import ObjectRef
|
||||||
|
return ObjectRef(n, self.filename)
|
||||||
|
|
||||||
|
def PRIMITIVE(self, s):
|
||||||
|
from .types import get_primitive
|
||||||
|
return get_primitive(s)
|
||||||
|
|
||||||
|
def UID(self, s):
|
||||||
|
from .types import UID
|
||||||
|
return UID(int(s, base=16))
|
||||||
|
|
||||||
|
def INT_TYPE(self, s):
|
||||||
|
return s
|
||||||
|
|
||||||
|
def NUMBER(self, s):
|
||||||
|
if s.startswith("0x"):
|
||||||
|
return int(s,16)
|
||||||
|
return int(s)
|
||||||
|
|
||||||
|
def COMMENT(self, s):
|
||||||
|
return s[2:].strip()
|
||||||
|
|
||||||
|
def OPTION(self, s):
|
||||||
|
return str(s)
|
||||||
|
|
||||||
|
def IDENTIFIER(self, s):
|
||||||
|
return str(s)
|
||||||
|
|
||||||
|
def PATH(self, s):
|
||||||
|
return str(s[1:-1])
|
||||||
|
|
||||||
26
scripts/definitions/types/__init__.py
Normal file
26
scripts/definitions/types/__init__.py
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
def _indent(x):
|
||||||
|
from textwrap import indent
|
||||||
|
return indent(str(x), ' ')
|
||||||
|
|
||||||
|
class CName(str): pass
|
||||||
|
class Description(str): pass
|
||||||
|
class Import(str): pass
|
||||||
|
class Caps(list): pass
|
||||||
|
|
||||||
|
class Options(dict):
|
||||||
|
def __init__(self, opts = tuple()):
|
||||||
|
for opt in opts:
|
||||||
|
parts = opt.split(":", 1)
|
||||||
|
self[parts[0]] = self.get(parts[0], []) + ["".join(parts[1:])]
|
||||||
|
|
||||||
|
class UID(int):
|
||||||
|
def __str__(self):
|
||||||
|
return f"{self:016x}"
|
||||||
|
|
||||||
|
from .object import Object
|
||||||
|
from .interface import Interface, Expose
|
||||||
|
from .function import Function, Method, Param
|
||||||
|
|
||||||
|
from .type import Type
|
||||||
|
from .primitive import get_primitive
|
||||||
|
from .objref import ObjectRef
|
||||||
68
scripts/definitions/types/function.py
Normal file
68
scripts/definitions/types/function.py
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
from . import _indent
|
||||||
|
from . import Options
|
||||||
|
|
||||||
|
def _hasopt(opt):
|
||||||
|
def test(self):
|
||||||
|
return opt in self.options
|
||||||
|
return test
|
||||||
|
|
||||||
|
class Function:
|
||||||
|
typename = "function"
|
||||||
|
|
||||||
|
def __init__(self, name, opts=Options(), desc="", children=tuple()):
|
||||||
|
self.name = name
|
||||||
|
self.options = opts
|
||||||
|
self.desc = desc
|
||||||
|
self.params = [c for c in children if isinstance(c, Param)]
|
||||||
|
self.id = -1
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
parts = ["{} {}".format(self.typename, self.name)]
|
||||||
|
if self.desc:
|
||||||
|
parts.append(_indent(self.desc))
|
||||||
|
if self.options:
|
||||||
|
parts.append(f" Options: {self.options}")
|
||||||
|
parts.extend(map(_indent, self.params))
|
||||||
|
return "\n".join(parts)
|
||||||
|
|
||||||
|
static = property(lambda x: True)
|
||||||
|
constructor = property(lambda x: False)
|
||||||
|
|
||||||
|
|
||||||
|
class Method(Function):
|
||||||
|
typename = "method"
|
||||||
|
|
||||||
|
static = property(_hasopt("static"))
|
||||||
|
constructor = property(_hasopt("constructor"))
|
||||||
|
|
||||||
|
|
||||||
|
class Param:
|
||||||
|
def __init__(self, name, typename, opts=Options(), desc=""):
|
||||||
|
self.name = name
|
||||||
|
self.type = typename
|
||||||
|
self.options = opts
|
||||||
|
self.desc = desc
|
||||||
|
|
||||||
|
self.caps = set()
|
||||||
|
for key, values in opts.items():
|
||||||
|
if key == "cap":
|
||||||
|
self.caps.update(values)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return "param {} {} {} {}".format(
|
||||||
|
self.name, repr(self.type), self.options, self.desc or "")
|
||||||
|
|
||||||
|
@property
|
||||||
|
def outparam(self):
|
||||||
|
return "out" in self.options or "inout" in self.options
|
||||||
|
|
||||||
|
@property
|
||||||
|
def refparam(self):
|
||||||
|
return self.type.reference or self.outparam
|
||||||
|
|
||||||
|
@property
|
||||||
|
def optional(self):
|
||||||
|
if "optional" in self.options: return "optional"
|
||||||
|
elif "zero_ok" in self.options: return "zero_ok"
|
||||||
|
else: return "required"
|
||||||
|
|
||||||
46
scripts/definitions/types/interface.py
Normal file
46
scripts/definitions/types/interface.py
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
from . import _indent
|
||||||
|
from . import Options
|
||||||
|
|
||||||
|
class Expose(object):
|
||||||
|
def __init__(self, type):
|
||||||
|
self.type = type
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return f'expose {repr(self.type)}'
|
||||||
|
|
||||||
|
class Interface:
|
||||||
|
def __init__(self, name, uid, opts=Options(), desc="", children=tuple()):
|
||||||
|
from .function import Function
|
||||||
|
|
||||||
|
self.name = name
|
||||||
|
self.uid = uid
|
||||||
|
self.options = opts
|
||||||
|
self.desc = desc
|
||||||
|
|
||||||
|
self.functions = [c for c in children if isinstance(c, Function)]
|
||||||
|
self.__exposes = [e.type for e in children if isinstance(e, Expose)]
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
parts = [f"interface {self.name}: {self.uid}"]
|
||||||
|
if self.desc:
|
||||||
|
parts.append(_indent(self.desc))
|
||||||
|
if self.options:
|
||||||
|
parts.append(f" Options: {self.options}")
|
||||||
|
parts.extend(map(_indent, self.exposes))
|
||||||
|
parts.extend(map(_indent, self.functions))
|
||||||
|
return "\n".join(parts)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def methods(self):
|
||||||
|
mm = [(i, None, self.functions[i]) for i in range(len(self.functions))]
|
||||||
|
|
||||||
|
base = len(mm)
|
||||||
|
for o in self.exposes:
|
||||||
|
mm.extend([(base + i, o, o.methods[i]) for i in range(len(o.methods))])
|
||||||
|
base += len(o.methods)
|
||||||
|
|
||||||
|
return mm
|
||||||
|
|
||||||
|
@property
|
||||||
|
def exposes(self):
|
||||||
|
return [ref.object for ref in self.__exposes]
|
||||||
33
scripts/definitions/types/object.py
Normal file
33
scripts/definitions/types/object.py
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
from . import _indent
|
||||||
|
from . import Caps, Options
|
||||||
|
|
||||||
|
class Object:
|
||||||
|
def __init__(self, name, uid, typename=None, opts=Options(), caps=Caps(), desc="", children=tuple(), cname=None):
|
||||||
|
self.name = name
|
||||||
|
self.uid = uid
|
||||||
|
self.options = opts
|
||||||
|
self.desc = desc
|
||||||
|
self.methods = children
|
||||||
|
self.cname = cname or name
|
||||||
|
self.caps = caps
|
||||||
|
|
||||||
|
self.__super = typename
|
||||||
|
|
||||||
|
from . import ObjectRef
|
||||||
|
self.__ref = ObjectRef(name)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
parts = [f"object {self.name}: {self.uid}"]
|
||||||
|
if self.desc:
|
||||||
|
parts.append(_indent(self.desc))
|
||||||
|
if self.options:
|
||||||
|
parts.append(f" Options: {self.options}")
|
||||||
|
parts.extend(map(_indent, self.methods))
|
||||||
|
return "\n".join(parts)
|
||||||
|
|
||||||
|
reftype = property(lambda self: self.__ref)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def super(self):
|
||||||
|
if self.__super is not None:
|
||||||
|
return self.__super.object
|
||||||
49
scripts/definitions/types/objref.py
Normal file
49
scripts/definitions/types/objref.py
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
from .type import Type
|
||||||
|
|
||||||
|
class ObjectRef(Type):
|
||||||
|
all_refs = {}
|
||||||
|
|
||||||
|
def __init__(self, name, filename=None):
|
||||||
|
super().__init__(name)
|
||||||
|
self.__c_type = "j6_handle_t"
|
||||||
|
self.__object = None
|
||||||
|
ObjectRef.all_refs[self] = filename
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return f'ObjectRef({self.name})'
|
||||||
|
|
||||||
|
object = property(lambda self: self.__object)
|
||||||
|
|
||||||
|
def c_names(self, options):
|
||||||
|
one = self.__c_type
|
||||||
|
out = bool({"out", "inout"}.intersection(options))
|
||||||
|
|
||||||
|
if "list" in options:
|
||||||
|
two = "size_t"
|
||||||
|
one = f"{one} *"
|
||||||
|
|
||||||
|
if out:
|
||||||
|
two += " *"
|
||||||
|
return ((one, ""), (two, "_count"))
|
||||||
|
|
||||||
|
else:
|
||||||
|
if out:
|
||||||
|
one += " *"
|
||||||
|
return ((one, ""),)
|
||||||
|
|
||||||
|
def cxx_names(self, options):
|
||||||
|
if not self.needs_object(options):
|
||||||
|
return self.c_names(options)
|
||||||
|
return ((f"obj::{self.name} *", ""),)
|
||||||
|
|
||||||
|
def needs_object(self, options):
|
||||||
|
return not bool({"out", "inout", "list", "handle"}.intersection(options))
|
||||||
|
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def connect(cls, objects):
|
||||||
|
for ref, filename in cls.all_refs.items():
|
||||||
|
ref.__object = objects.get(ref.name)
|
||||||
|
if ref.__object is None:
|
||||||
|
from ..errors import UnknownTypeError
|
||||||
|
raise UnknownTypeError(ref.name, filename)
|
||||||
72
scripts/definitions/types/primitive.py
Normal file
72
scripts/definitions/types/primitive.py
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
from .type import Type
|
||||||
|
|
||||||
|
class Primitive(Type):
|
||||||
|
def __init__(self, name, c_type):
|
||||||
|
super().__init__(name)
|
||||||
|
self.c_type = c_type
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return f'Primitive({self.name})'
|
||||||
|
|
||||||
|
def c_names(self, options=dict()):
|
||||||
|
one = self.c_type
|
||||||
|
if "out" in options or "inout" in options:
|
||||||
|
one += " *"
|
||||||
|
|
||||||
|
return ((one, ""),)
|
||||||
|
|
||||||
|
def cxx_names(self, options):
|
||||||
|
return self.c_names(options)
|
||||||
|
|
||||||
|
class PrimitiveRef(Primitive):
|
||||||
|
def __init__(self, name, c_type, counted=False):
|
||||||
|
super().__init__(name, c_type)
|
||||||
|
self.__counted = counted
|
||||||
|
|
||||||
|
reference = property(lambda self: True)
|
||||||
|
|
||||||
|
def c_names(self, options=dict()):
|
||||||
|
one = f"{self.c_type} *"
|
||||||
|
two = "size_t"
|
||||||
|
|
||||||
|
if "out" in options or "inout" in options:
|
||||||
|
two += " *"
|
||||||
|
else:
|
||||||
|
one = "const " + one
|
||||||
|
|
||||||
|
if self.__counted:
|
||||||
|
return ((one, ""), (two, "_len"))
|
||||||
|
else:
|
||||||
|
return ((one, ""),)
|
||||||
|
|
||||||
|
def cxx_names(self, options):
|
||||||
|
return self.c_names(options)
|
||||||
|
|
||||||
|
_primitives = {
|
||||||
|
"string": PrimitiveRef("string", "char"),
|
||||||
|
"buffer": PrimitiveRef("buffer", "void", counted=True),
|
||||||
|
|
||||||
|
"int": Primitive("int", "int"),
|
||||||
|
"uint": Primitive("uint", "unsigned"),
|
||||||
|
"size": Primitive("size", "size_t"),
|
||||||
|
"address": Primitive("address", "uintptr_t"),
|
||||||
|
|
||||||
|
"int8": Primitive("int8", "int8_t"),
|
||||||
|
"uint8": Primitive("uint8", "uint8_t"),
|
||||||
|
|
||||||
|
"int16": Primitive("int16", "int16_t"),
|
||||||
|
"uint16": Primitive("uint16", "uint16_t"),
|
||||||
|
|
||||||
|
"int32": Primitive("int32", "int32_t"),
|
||||||
|
"uint32": Primitive("uint32", "uint32_t"),
|
||||||
|
|
||||||
|
"int64": Primitive("int64", "int64_t"),
|
||||||
|
"uint64": Primitive("uint64", "uint64_t"),
|
||||||
|
}
|
||||||
|
|
||||||
|
def get_primitive(name):
|
||||||
|
p = _primitives.get(name)
|
||||||
|
if not p:
|
||||||
|
from ..errors import InvalidType
|
||||||
|
raise InvalidType(name)
|
||||||
|
return p
|
||||||
15
scripts/definitions/types/type.py
Normal file
15
scripts/definitions/types/type.py
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
class Type:
|
||||||
|
def __init__(self, name):
|
||||||
|
self.__name = name
|
||||||
|
|
||||||
|
name = property(lambda self: self.__name)
|
||||||
|
reference = property(lambda self: False)
|
||||||
|
|
||||||
|
def c_names(self, options):
|
||||||
|
raise NotImplemented("Call to base Type.c_names")
|
||||||
|
|
||||||
|
def cxx_names(self, options):
|
||||||
|
raise NotImplemented("Call to base Type.c_names")
|
||||||
|
|
||||||
|
def needs_object(self, options):
|
||||||
|
return False
|
||||||
75
scripts/fontpsf.py
Normal file
75
scripts/fontpsf.py
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
_MAGIC = (0x72, 0xb5, 0x4a, 0x86)
|
||||||
|
_VERSION = 0
|
||||||
|
|
||||||
|
class PSF2:
|
||||||
|
from collections import namedtuple
|
||||||
|
Header = namedtuple("PSF2Header",
|
||||||
|
["version", "offset", "flags", "count", "charsize", "height", "width"])
|
||||||
|
|
||||||
|
def __init__(self, filename, header, data):
|
||||||
|
self.__filename = filename
|
||||||
|
self.__header = header
|
||||||
|
self.__data = data
|
||||||
|
|
||||||
|
data = property(lambda self: self.__data)
|
||||||
|
header = property(lambda self: self.__header)
|
||||||
|
count = property(lambda self: self.__header.count)
|
||||||
|
charsize = property(lambda self: self.__header.charsize)
|
||||||
|
dimension = property(lambda self: (self.__header.width, self.__header.height))
|
||||||
|
filename = property(lambda self: self.__filename)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def load(cls, filename):
|
||||||
|
from os.path import basename
|
||||||
|
from struct import unpack_from
|
||||||
|
|
||||||
|
data = open(filename, 'rb').read()
|
||||||
|
|
||||||
|
fmt = "BBBBIIIIIII"
|
||||||
|
values = unpack_from(fmt, data)
|
||||||
|
|
||||||
|
if values[:len(_MAGIC)] != _MAGIC:
|
||||||
|
raise Exception("Bad magic number in header")
|
||||||
|
|
||||||
|
header = PSF2.Header(*values[len(_MAGIC):])
|
||||||
|
if header.version != _VERSION:
|
||||||
|
raise Exception(f"Bad version {header.version} in header")
|
||||||
|
|
||||||
|
return cls(basename(filename), header, data)
|
||||||
|
|
||||||
|
class Glyph:
|
||||||
|
__slots__ = ['index', 'data']
|
||||||
|
def __init__(self, i, data):
|
||||||
|
self.index = i
|
||||||
|
self.data = data
|
||||||
|
def __index__(self):
|
||||||
|
return self.index
|
||||||
|
def empty(self):
|
||||||
|
return not bool([b for b in self.data if b != 0])
|
||||||
|
def description(self):
|
||||||
|
c = chr(self.index)
|
||||||
|
if c.isprintable():
|
||||||
|
return "Glyph {:02x}: '{}'".format(self.index, c)
|
||||||
|
else:
|
||||||
|
return "Glyph {:02x}".format(self.index)
|
||||||
|
|
||||||
|
def __getitem__(self, i):
|
||||||
|
c = self.__header.charsize
|
||||||
|
n = i * c + self.__header.offset
|
||||||
|
return PSF2.Glyph(i, self.__data[n:n+c])
|
||||||
|
|
||||||
|
class __iter:
|
||||||
|
__slots__ = ['font', 'n']
|
||||||
|
def __init__(self, font):
|
||||||
|
self.font = font
|
||||||
|
self.n = 0
|
||||||
|
def __next__(self):
|
||||||
|
if self.n < self.font.count:
|
||||||
|
glyph = self.font[self.n]
|
||||||
|
self.n += 1
|
||||||
|
return glyph
|
||||||
|
else:
|
||||||
|
raise StopIteration
|
||||||
|
|
||||||
|
def __iter__(self):
|
||||||
|
return PSF2.__iter(self)
|
||||||
11
scripts/idgen
Executable file
11
scripts/idgen
Executable file
@@ -0,0 +1,11 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
def hashid(s):
|
||||||
|
from hashlib import shake_128 as sh
|
||||||
|
return sh(s.encode('utf-8')).hexdigest(8)
|
||||||
|
|
||||||
|
import sys
|
||||||
|
|
||||||
|
for arg in sys.argv[1:]:
|
||||||
|
id = hashid(arg)
|
||||||
|
print(f"{arg}: {id}")
|
||||||
56
scripts/j6libc.py
Normal file
56
scripts/j6libc.py
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
import cog
|
||||||
|
|
||||||
|
supported_architectures = {
|
||||||
|
"amd64": "__amd64__",
|
||||||
|
}
|
||||||
|
|
||||||
|
def arch_includes(header):
|
||||||
|
prefix = "if"
|
||||||
|
for arch, define in supported_architectures.items():
|
||||||
|
cog.outl(f"#{prefix} defined({define})")
|
||||||
|
cog.outl(f"#include <__j6libc/arch/{arch}/{header}>")
|
||||||
|
prefix = "elif"
|
||||||
|
cog.outl("#endif")
|
||||||
|
|
||||||
|
|
||||||
|
int_widths = (8, 16, 32, 64)
|
||||||
|
int_mods = ("fast", "least")
|
||||||
|
|
||||||
|
int_types = {
|
||||||
|
# type: abbrev
|
||||||
|
"char": "char",
|
||||||
|
"short": "short",
|
||||||
|
"int": "int",
|
||||||
|
"long": "long",
|
||||||
|
"long long": "llong",
|
||||||
|
}
|
||||||
|
|
||||||
|
def definition(kind, name, val, width=24):
|
||||||
|
cog.outl(f"{kind} {name:{width}} {val}")
|
||||||
|
|
||||||
|
|
||||||
|
atomic_types = {
|
||||||
|
"_Bool": "bool",
|
||||||
|
"signed char": "schar",
|
||||||
|
"char16_t": "char16_t",
|
||||||
|
"char32_t": "char32_t",
|
||||||
|
"wchar_t": "wchar_t",
|
||||||
|
"wchar_t": "wchar_t",
|
||||||
|
"size_t": "size_t",
|
||||||
|
"ptrdiff_t": "ptrdiff_t",
|
||||||
|
"intptr_t": "intptr_t",
|
||||||
|
"uintptr_t": "uintptr_t",
|
||||||
|
"intmax_t": "intmax_t",
|
||||||
|
"uintmax_t": "uintmax_t",
|
||||||
|
}
|
||||||
|
|
||||||
|
for name, abbrev in int_types.items():
|
||||||
|
atomic_types.update({name: abbrev, f"unsigned {name}": f"u{abbrev}"})
|
||||||
|
|
||||||
|
for width in int_widths:
|
||||||
|
atomic_types.update({t: t for t in (
|
||||||
|
f"int_least{width}_t",
|
||||||
|
f"uint_least{width}_t",
|
||||||
|
f"int_fast{width}_t",
|
||||||
|
f"uint_fast{width}_t")})
|
||||||
|
|
||||||
32
scripts/memory.py
Normal file
32
scripts/memory.py
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
class Layout:
|
||||||
|
from collections import namedtuple
|
||||||
|
Region = namedtuple("Region", ("name", "start", "size", "shared"))
|
||||||
|
|
||||||
|
sizes = {'G': 1024 ** 3, 'T': 1024 ** 4}
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_size(desc):
|
||||||
|
size, mag = int(desc[:-1]), desc[-1]
|
||||||
|
|
||||||
|
try:
|
||||||
|
mult = Layout.sizes[mag]
|
||||||
|
except KeyError:
|
||||||
|
raise RuntimeError(f"No magnitude named '{mag}'.")
|
||||||
|
|
||||||
|
return size * mult
|
||||||
|
|
||||||
|
def __init__(self, path):
|
||||||
|
from yaml import safe_load
|
||||||
|
|
||||||
|
regions = []
|
||||||
|
addr = 1 << 64
|
||||||
|
|
||||||
|
with open(path, 'r') as infile:
|
||||||
|
data = safe_load(infile.read())
|
||||||
|
for r in data:
|
||||||
|
size = Layout.get_size(r["size"])
|
||||||
|
addr -= size
|
||||||
|
regions.append(Layout.Region(r["name"], addr, size,
|
||||||
|
r.get("shared", False)))
|
||||||
|
|
||||||
|
self.regions = tuple(regions)
|
||||||
34
scripts/parse_font.py
Normal file → Executable file
34
scripts/parse_font.py
Normal file → Executable file
@@ -1,21 +1,6 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
MAGIC = (0x72, 0xb5, 0x4a, 0x86)
|
from fontpsf import PSF2
|
||||||
|
|
||||||
from collections import namedtuple
|
|
||||||
PSF2 = namedtuple("PSF2", ["version", "offset", "flags", "count", "charsize", "height", "width"])
|
|
||||||
|
|
||||||
def read_header(data):
|
|
||||||
from struct import unpack_from, calcsize
|
|
||||||
|
|
||||||
fmt = "BBBBIIIIIII"
|
|
||||||
|
|
||||||
values = unpack_from(fmt, data)
|
|
||||||
if values[:len(MAGIC)] != MAGIC:
|
|
||||||
raise Exception("Bad magic number in header")
|
|
||||||
|
|
||||||
return PSF2(*values[len(MAGIC):])
|
|
||||||
|
|
||||||
|
|
||||||
def print_glyph(header, data):
|
def print_glyph(header, data):
|
||||||
bw = (header.width + 7) // 8
|
bw = (header.width + 7) // 8
|
||||||
@@ -28,16 +13,15 @@ def print_glyph(header, data):
|
|||||||
|
|
||||||
|
|
||||||
def display_font(filename):
|
def display_font(filename):
|
||||||
data = open(filename, 'rb').read()
|
font = PSF2.load(filename)
|
||||||
|
print(font.header)
|
||||||
|
|
||||||
header = read_header(data)
|
for glyph in font:
|
||||||
print(header)
|
if glyph.empty():
|
||||||
|
print("{}: BLANK".format(glyph.description()))
|
||||||
c = header.charsize
|
else:
|
||||||
for i in range(0, header.count):
|
print("{}:".format(glyph.description()))
|
||||||
n = i * c + header.offset
|
print_glyph(font.header, glyph.data)
|
||||||
print("Glyph {}:".format(i))
|
|
||||||
print_glyph(header, data[n:n+c])
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|||||||
17
scripts/sysconf.py
Normal file
17
scripts/sysconf.py
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
class Sysconf:
|
||||||
|
from collections import namedtuple
|
||||||
|
Var = namedtuple("Var", ("name", "section", "type"))
|
||||||
|
|
||||||
|
def __init__(self, path):
|
||||||
|
from yaml import safe_load
|
||||||
|
|
||||||
|
sys_vars = []
|
||||||
|
|
||||||
|
with open(path, 'r') as infile:
|
||||||
|
data = safe_load(infile.read())
|
||||||
|
self.address = data["address"]
|
||||||
|
|
||||||
|
for v in data["vars"]:
|
||||||
|
sys_vars.append(Sysconf.Var(v["name"], v["section"], v["type"]))
|
||||||
|
|
||||||
|
self.vars = tuple(sys_vars)
|
||||||
12
scripts/vmem_translate.py
Executable file
12
scripts/vmem_translate.py
Executable file
@@ -0,0 +1,12 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
def translate(i4 = 0, i3 = 0, i2 = 0, i1 = 0, offset = 0):
|
||||||
|
addr = (i4 << 39) + (i3 << 30) + (i2 << 21) + (i1 << 12) + offset
|
||||||
|
if addr & (1 << 47):
|
||||||
|
addr |= 0xffff000000000000
|
||||||
|
return addr
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
import sys
|
||||||
|
print("{:016x}".format(translate(*map(int, sys.argv[1:]))))
|
||||||
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
AS := nasm
|
|
||||||
ASFLAGS := -felf64
|
|
||||||
LDFLAGS := -m elf_x86_64
|
|
||||||
CFLAGS := -march=nocona -m64
|
|
||||||
|
|
||||||
# vim:ft=make
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
const char *KERNEL_PLATFORM = "x86_64";
|
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
ENTRY(_start)
|
|
||||||
SECTIONS
|
|
||||||
{
|
|
||||||
OFFSET = 0xFFFF800000000000;
|
|
||||||
. = OFFSET + 0x100000;
|
|
||||||
|
|
||||||
.header : {
|
|
||||||
header = .;
|
|
||||||
KEEP(*(.header))
|
|
||||||
}
|
|
||||||
|
|
||||||
.text : {
|
|
||||||
code = .;
|
|
||||||
*(.text)
|
|
||||||
}
|
|
||||||
|
|
||||||
.data ALIGN(0x1000) : {
|
|
||||||
data = .;
|
|
||||||
*(.data)
|
|
||||||
*(.rodata)
|
|
||||||
}
|
|
||||||
|
|
||||||
.bss ALIGN(0x1000) : {
|
|
||||||
bss = .;
|
|
||||||
*(.bss)
|
|
||||||
}
|
|
||||||
|
|
||||||
.note ALIGN(0x1000) : {
|
|
||||||
*(.note.*)
|
|
||||||
}
|
|
||||||
|
|
||||||
kernel_end = ALIGN(4096);
|
|
||||||
}
|
|
||||||
173
src/boot/allocator.cpp
Normal file
173
src/boot/allocator.cpp
Normal file
@@ -0,0 +1,173 @@
|
|||||||
|
#include <uefi/boot_services.h>
|
||||||
|
#include <uefi/types.h>
|
||||||
|
|
||||||
|
#include <bootproto/init.h>
|
||||||
|
#include <bootproto/kernel.h>
|
||||||
|
#include <util/no_construct.h>
|
||||||
|
#include <util/pointers.h>
|
||||||
|
|
||||||
|
#include "allocator.h"
|
||||||
|
#include "error.h"
|
||||||
|
#include "memory.h"
|
||||||
|
|
||||||
|
namespace boot {
|
||||||
|
|
||||||
|
util::no_construct<memory::allocator> __g_alloc_storage;
|
||||||
|
memory::allocator &g_alloc = __g_alloc_storage.value;
|
||||||
|
|
||||||
|
namespace memory {
|
||||||
|
|
||||||
|
using bootproto::allocation_register;
|
||||||
|
using bootproto::module;
|
||||||
|
using bootproto::page_allocation;
|
||||||
|
|
||||||
|
static_assert(sizeof(allocation_register) == page_size);
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
allocator::init(
|
||||||
|
allocation_register *&allocs,
|
||||||
|
modules_page *&modules,
|
||||||
|
uefi::boot_services *bs)
|
||||||
|
{
|
||||||
|
new (&g_alloc) allocator(*bs);
|
||||||
|
allocs = g_alloc.m_register;
|
||||||
|
modules = g_alloc.m_modules;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
allocator::allocator(uefi::boot_services &bs) :
|
||||||
|
m_bs(bs),
|
||||||
|
m_register(nullptr),
|
||||||
|
m_modules(nullptr)
|
||||||
|
{
|
||||||
|
add_register();
|
||||||
|
add_modules();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
allocator::add_register()
|
||||||
|
{
|
||||||
|
allocation_register *reg = nullptr;
|
||||||
|
|
||||||
|
try_or_raise(
|
||||||
|
m_bs.allocate_pages(uefi::allocate_type::any_pages,
|
||||||
|
uefi::memory_type::loader_data, 1, reinterpret_cast<void**>(®)),
|
||||||
|
L"Failed allocating allocation register page");
|
||||||
|
|
||||||
|
m_bs.set_mem(reg, sizeof(allocation_register), 0);
|
||||||
|
|
||||||
|
if (m_register)
|
||||||
|
m_register->next = reg;
|
||||||
|
|
||||||
|
m_register = reg;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
allocator::add_modules()
|
||||||
|
{
|
||||||
|
modules_page *mods = reinterpret_cast<modules_page*>(
|
||||||
|
allocate_pages(1, alloc_type::init_args, true));
|
||||||
|
|
||||||
|
if (m_modules)
|
||||||
|
m_modules->next = reinterpret_cast<uintptr_t>(mods);
|
||||||
|
|
||||||
|
mods->modules = reinterpret_cast<module*>(mods + 1);
|
||||||
|
m_modules = mods;
|
||||||
|
m_next_mod = mods->modules;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *
|
||||||
|
allocator::allocate_pages(size_t count, alloc_type type, bool zero)
|
||||||
|
{
|
||||||
|
if (count & ~0xffffffffull) {
|
||||||
|
error::raise(uefi::status::unsupported,
|
||||||
|
L"Cannot allocate more than 16TiB in pages at once.",
|
||||||
|
__LINE__);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!m_register || m_register->count == 0xff)
|
||||||
|
add_register();
|
||||||
|
|
||||||
|
void *pages = nullptr;
|
||||||
|
|
||||||
|
try_or_raise(
|
||||||
|
m_bs.allocate_pages(uefi::allocate_type::any_pages,
|
||||||
|
uefi::memory_type::loader_data, count, &pages),
|
||||||
|
L"Failed allocating usable pages");
|
||||||
|
|
||||||
|
page_allocation &ent = m_register->entries[m_register->count++];
|
||||||
|
ent.address = reinterpret_cast<uintptr_t>(pages);
|
||||||
|
ent.count = count;
|
||||||
|
ent.type = type;
|
||||||
|
|
||||||
|
if (zero)
|
||||||
|
m_bs.set_mem(pages, count * page_size, 0);
|
||||||
|
|
||||||
|
return pages;
|
||||||
|
}
|
||||||
|
|
||||||
|
module *
|
||||||
|
allocator::allocate_module_untyped(size_t size)
|
||||||
|
{
|
||||||
|
size_t remaining =
|
||||||
|
reinterpret_cast<uintptr_t>(m_modules) + page_size
|
||||||
|
- reinterpret_cast<uintptr_t>(m_next_mod);
|
||||||
|
|
||||||
|
if (size > remaining)
|
||||||
|
add_modules();
|
||||||
|
|
||||||
|
++m_modules->count;
|
||||||
|
module *m = m_next_mod;
|
||||||
|
m_next_mod = util::offset_pointer(m_next_mod, size);
|
||||||
|
|
||||||
|
m->mod_length = size;
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *
|
||||||
|
allocator::allocate(size_t size, bool zero)
|
||||||
|
{
|
||||||
|
void *p = nullptr;
|
||||||
|
try_or_raise(
|
||||||
|
m_bs.allocate_pool(uefi::memory_type::loader_data, size, &p),
|
||||||
|
L"Could not allocate pool memory");
|
||||||
|
|
||||||
|
if (zero)
|
||||||
|
m_bs.set_mem(p, size, 0);
|
||||||
|
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
allocator::free(void *p)
|
||||||
|
{
|
||||||
|
try_or_raise(
|
||||||
|
m_bs.free_pool(p),
|
||||||
|
L"Freeing pool memory");
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
allocator::memset(void *start, size_t size, uint8_t value)
|
||||||
|
{
|
||||||
|
m_bs.set_mem(start, size, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
allocator::copy(void *to, void *from, size_t size)
|
||||||
|
{
|
||||||
|
m_bs.copy_mem(to, from, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace memory
|
||||||
|
} // namespace boot
|
||||||
|
|
||||||
|
|
||||||
|
void * operator new (size_t size, void *p) { return p; }
|
||||||
|
void * operator new(size_t size) { return boot::g_alloc.allocate(size); }
|
||||||
|
void * operator new [] (size_t size) { return boot::g_alloc.allocate(size); }
|
||||||
|
void operator delete (void *p) noexcept { return boot::g_alloc.free(p); }
|
||||||
|
void operator delete [] (void *p) noexcept { return boot::g_alloc.free(p); }
|
||||||
|
|
||||||
76
src/boot/allocator.h
Normal file
76
src/boot/allocator.h
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
#pragma once
|
||||||
|
/// \file allocator.h
|
||||||
|
/// Page allocator class definition
|
||||||
|
|
||||||
|
namespace uefi {
|
||||||
|
class boot_services;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace bootproto {
|
||||||
|
enum class allocation_type : uint8_t;
|
||||||
|
struct allocation_register;
|
||||||
|
struct module;
|
||||||
|
struct modules_page;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace boot {
|
||||||
|
namespace memory {
|
||||||
|
|
||||||
|
using alloc_type = bootproto::allocation_type;
|
||||||
|
|
||||||
|
class allocator
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using allocation_register = bootproto::allocation_register;
|
||||||
|
using module = bootproto::module;
|
||||||
|
using modules_page = bootproto::modules_page;
|
||||||
|
|
||||||
|
allocator(uefi::boot_services &bs);
|
||||||
|
|
||||||
|
void * allocate(size_t size, bool zero = false);
|
||||||
|
void free(void *p);
|
||||||
|
|
||||||
|
void * allocate_pages(size_t count, alloc_type type, bool zero = false);
|
||||||
|
|
||||||
|
template <typename M>
|
||||||
|
M * allocate_module(size_t extra = 0) {
|
||||||
|
return static_cast<M*>(allocate_module_untyped(sizeof(M) + extra));
|
||||||
|
}
|
||||||
|
|
||||||
|
void memset(void *start, size_t size, uint8_t value);
|
||||||
|
void copy(void *to, void *from, size_t size);
|
||||||
|
|
||||||
|
inline void zero(void *start, size_t size) { memset(start, size, 0); }
|
||||||
|
|
||||||
|
/// Initialize the global allocator
|
||||||
|
/// \arg allocs [out] Poiinter to the initial allocation register
|
||||||
|
/// \arg modules [out] Pointer to the initial modules_page
|
||||||
|
/// \arg bs UEFI boot services
|
||||||
|
static void init(
|
||||||
|
allocation_register *&allocs,
|
||||||
|
modules_page *&modules,
|
||||||
|
uefi::boot_services *bs);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void add_register();
|
||||||
|
void add_modules();
|
||||||
|
module * allocate_module_untyped(size_t size);
|
||||||
|
|
||||||
|
uefi::boot_services &m_bs;
|
||||||
|
|
||||||
|
allocation_register *m_register;
|
||||||
|
modules_page *m_modules;
|
||||||
|
module *m_next_mod;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace memory
|
||||||
|
|
||||||
|
extern memory::allocator &g_alloc;
|
||||||
|
|
||||||
|
} // namespace boot
|
||||||
|
|
||||||
|
void * operator new (size_t size, void *p);
|
||||||
|
void * operator new(size_t size);
|
||||||
|
void * operator new [] (size_t size);
|
||||||
|
void operator delete (void *p) noexcept;
|
||||||
|
void operator delete [] (void *p) noexcept;
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user