Compare commits
653 Commits
v6.2.1
...
v9.0-joyco
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1182d3a627 | ||
|
|
938cb6492f | ||
|
|
fed62855cb | ||
|
|
4f54596658 | ||
|
|
0b41ed04d5 | ||
|
|
9509a86998 | ||
|
|
6d4d80a798 | ||
|
|
76d274cfe2 | ||
|
|
ccf13be964 | ||
|
|
e36b27ccf0 | ||
|
|
34c80ad476 | ||
|
|
97ae106d8e | ||
|
|
7cb74b74d7 | ||
|
|
337205eb08 | ||
|
|
f36977017b | ||
|
|
e40b547bb6 | ||
|
|
1fd689f5da | ||
|
|
c5c8dca14c | ||
|
|
11f820efa7 | ||
|
|
9074688491 | ||
|
|
1de27c54f1 | ||
|
|
3e67e64faa | ||
|
|
553f8d2533 | ||
|
|
ec7ae35da1 | ||
|
|
7e8da0d236 | ||
|
|
b3e6561072 | ||
|
|
41f32ed983 | ||
|
|
bbadf840ef | ||
|
|
acc50aae46 | ||
|
|
6a68a77973 | ||
|
|
0f4d66dd61 | ||
|
|
d28642d2c3 | ||
|
|
ca4685cc42 | ||
|
|
522f10582d | ||
|
|
239d113177 | ||
|
|
fd80294bf2 | ||
|
|
b379d83469 | ||
|
|
27f352fdf1 | ||
|
|
bfec874a7c | ||
|
|
93561003e8 | ||
|
|
1572bfd989 | ||
|
|
cb945612a3 | ||
|
|
1b440f7f3b | ||
|
|
78791f7b66 | ||
|
|
5def0c18e2 | ||
|
|
0e67b0f026 | ||
|
|
8052946517 | ||
|
|
b6d6cc9750 | ||
|
|
2a840f2c79 | ||
|
|
4eaf791849 | ||
|
|
be0f50b19c | ||
|
|
f30b7b9fb3 | ||
|
|
6a0f332e3c | ||
|
|
16530d3a52 | ||
|
|
20af9c6750 | ||
|
|
fee9f6b427 | ||
|
|
57d03d6333 | ||
|
|
0075fe2aa0 | ||
|
|
d54417ac0a | ||
|
|
648801d432 | ||
|
|
2be2826b0b | ||
|
|
37a9fa1bf4 | ||
|
|
65af93c8ce | ||
|
|
8353b84944 | ||
|
|
d6a89db495 | ||
|
|
f156aa8cdb | ||
|
|
f9adbcc9d9 | ||
|
|
cf8696ac70 | ||
|
|
9c5766f649 | ||
|
|
c9701f93b9 | ||
|
|
56e54cd110 | ||
|
|
55836b48af | ||
|
|
09bfdb9ee1 | ||
|
|
1c2e8dec11 | ||
|
|
506b16db37 | ||
|
|
8f03234e58 | ||
|
|
44b5e10323 | ||
|
|
48303604b0 | ||
|
|
ab2ddbc2ee | ||
|
|
9495bf30bf | ||
|
|
a4899a1bec | ||
|
|
882c6cf0d4 | ||
|
|
a5e18c82d1 | ||
|
|
22a8661fe1 | ||
|
|
8258a98647 | ||
|
|
76dde0e6db | ||
|
|
1a39cb27e4 | ||
|
|
95d2d0a6bd | ||
|
|
98d4345858 | ||
|
|
1e4431dcc9 | ||
|
|
348b175994 | ||
|
|
76f057dafb | ||
|
|
188400c5a9 | ||
|
|
a74d9c6d3e | ||
|
|
f8bcfb2f58 | ||
|
|
d63fc2bc82 | ||
|
|
8e31784996 | ||
|
|
f27cdb4543 | ||
|
|
a39adc8ac1 | ||
|
|
97bef66018 | ||
|
|
bb5518b0f6 | ||
|
|
ac73a96ce2 | ||
|
|
7075004e58 | ||
|
|
ddf8ba5116 | ||
|
|
f46773ba64 | ||
|
|
f67d333457 | ||
|
|
4116c1e00f | ||
|
|
bc1aa15dd7 | ||
|
|
ecd27f7eaa | ||
|
|
618ce671ac | ||
|
|
2a6a655804 | ||
|
|
33436ae2a6 | ||
|
|
9f2b66ac51 | ||
|
|
df93e4797e | ||
|
|
538d1dec77 | ||
|
|
2492c8273a | ||
|
|
d358df48a6 | ||
|
|
f619dafff1 | ||
|
|
0419fc4e30 | ||
|
|
13317b9548 | ||
|
|
18db70a669 | ||
|
|
f79923814d | ||
|
|
c92de03a5f | ||
|
|
3f356da879 | ||
|
|
9efac01c86 | ||
|
|
ca2622af7c | ||
|
|
aa8e0bda8c | ||
|
|
c79f11ee99 | ||
|
|
04d0770b90 | ||
|
|
fbf8a1b6d9 | ||
|
|
a3cb6a622d | ||
|
|
0790a3ceb3 | ||
|
|
4fa12f90fc | ||
|
|
d5d56e7634 | ||
|
|
a964089df4 | ||
|
|
5fd5b4da89 | ||
|
|
322a7050aa | ||
|
|
b7f4ac02c8 | ||
|
|
009f61a8b6 | ||
|
|
26d0cafb39 | ||
|
|
bd1d4a77fe | ||
|
|
f235bc83a8 | ||
|
|
9c6b540905 | ||
|
|
d2e911a58e | ||
|
|
9344a7b434 | ||
|
|
cd194fa5b2 | ||
|
|
49c0ab65df | ||
|
|
8f9c1305e4 | ||
|
|
d4193ec11d | ||
|
|
6b9b0472bc | ||
|
|
7e74258363 | ||
|
|
f6483ec602 | ||
|
|
36c1da1d61 | ||
|
|
6bcb1f8679 | ||
|
|
62932a9639 | ||
|
|
a4629e4b65 | ||
|
|
a0c2b43b34 | ||
|
|
3907c46980 | ||
|
|
7e7ab124a3 | ||
|
|
cfc6cf24bf | ||
|
|
46e9cb6b23 | ||
|
|
ba14efe1f4 | ||
|
|
3d8f62d38f | ||
|
|
3edaf0af64 | ||
|
|
9273a88db7 | ||
|
|
37ba2c15de | ||
|
|
557f2057f7 | ||
|
|
6b5cc93780 | ||
|
|
9760191af8 | ||
|
|
8845e4dd20 | ||
|
|
8cf823f548 | ||
|
|
2538769f3a | ||
|
|
89fca38807 | ||
|
|
dcc0eed69c | ||
|
|
817475257e | ||
|
|
f2861058ba | ||
|
|
5d2a7315d5 | ||
|
|
1520ab7555 | ||
|
|
d4d0fbd73b | ||
|
|
ddb8e98e95 | ||
|
|
fd69b4169f | ||
|
|
b48e0b5c5b | ||
|
|
31e2243c5c | ||
|
|
da0ee2e442 | ||
|
|
b88dc9ac6a | ||
|
|
9f78d7f62b | ||
|
|
e67c6ed3ee | ||
|
|
2e111ca91b | ||
|
|
62d51fd99d | ||
|
|
a9289b1f21 | ||
|
|
d42e938232 | ||
|
|
3d3dcb1f28 | ||
|
|
82143212ce | ||
|
|
7246a2664e | ||
|
|
1291f2520a | ||
|
|
042ecf5343 | ||
|
|
6e54dcc24c | ||
|
|
91378ef3c1 | ||
|
|
0377cbd2b4 | ||
|
|
786ecf4fe4 | ||
|
|
0fbdee313f | ||
|
|
9b8e2b933d | ||
|
|
cc64ef9670 | ||
|
|
31ff6a1da8 | ||
|
|
94532e9cea | ||
|
|
3f93bc5988 | ||
|
|
39ca23d609 | ||
|
|
47a9c1b576 | ||
|
|
d819cfd58f | ||
|
|
17828273a5 | ||
|
|
2363817265 | ||
|
|
b31018ab17 | ||
|
|
c610ec3319 | ||
|
|
b71dedccfc | ||
|
|
9ccfacd06d | ||
|
|
12b561a27d | ||
|
|
cc41003e1c | ||
|
|
3d534c9a81 | ||
|
|
24de7c5272 | ||
|
|
a1b2ea2c5b | ||
|
|
19d68b6df4 | ||
|
|
2ab41dbd01 | ||
|
|
da30c0b0f0 | ||
|
|
005684d865 | ||
|
|
da1eff82ba | ||
|
|
a17311c955 | ||
|
|
e1d0602f25 | ||
|
|
2ff9718510 | ||
|
|
33af9cfe09 | ||
|
|
79709a7ae7 | ||
|
|
a796a70d01 | ||
|
|
53e2ef24f1 | ||
|
|
c0059c83ac | ||
|
|
37eb21d297 | ||
|
|
52a18831a7 | ||
|
|
0d7cca7b20 | ||
|
|
bea73c51ae | ||
|
|
0c68750056 | ||
|
|
ae8ea7da16 | ||
|
|
69762c5dce | ||
|
|
901d4992c0 | ||
|
|
4d47d891d1 | ||
|
|
a7046909ec | ||
|
|
4bc95979de | ||
|
|
949d219c72 | ||
|
|
9a3d9aed30 | ||
|
|
4d99143da0 | ||
|
|
461035b212 | ||
|
|
0694ea8367 | ||
|
|
427a05997d | ||
|
|
84d736c2eb | ||
|
|
a16d1ebe33 | ||
|
|
43f3c84316 | ||
|
|
44cafe3f46 | ||
|
|
76d7a035bd | ||
|
|
a5b638ae7b | ||
|
|
174089e4f3 | ||
|
|
4d219813fe | ||
|
|
a798f453d2 | ||
|
|
6ec21611c0 | ||
|
|
31f4419eec | ||
|
|
60d136f9b5 | ||
|
|
0ba7f9dba0 | ||
|
|
0ac6db006a | ||
|
|
26dd61e4e6 | ||
|
|
dda11206db | ||
|
|
e8565d30a9 | ||
|
|
2d4c103854 | ||
|
|
d0b9e36908 | ||
|
|
21db0d45bd | ||
|
|
4429cb2095 | ||
|
|
cab54d1b31 | ||
|
|
1d2909ea03 | ||
|
|
d802e5329c | ||
|
|
118f81d347 | ||
|
|
ba3740a77a | ||
|
|
47369c8f5e | ||
|
|
7a05dee453 | ||
|
|
9e47369365 | ||
|
|
5379c05001 | ||
|
|
5b34b2d114 | ||
|
|
3ea8734fdd | ||
|
|
8e22080e05 | ||
|
|
692a94fe5e | ||
|
|
01c760ab88 | ||
|
|
28e5d8107f | ||
|
|
710d8cd15c | ||
|
|
8395540288 | ||
|
|
d57d8aaae7 | ||
|
|
10f555b6fb | ||
|
|
9f30244bfb | ||
|
|
0b65fcbdd7 | ||
|
|
067e217909 | ||
|
|
d6c6c421e9 | ||
|
|
90b54581b0 | ||
|
|
68d9674ca3 | ||
|
|
a9a8edeaf4 | ||
|
|
dd21a3930d | ||
|
|
53209b9be0 | ||
|
|
8308e1a8b8 | ||
|
|
986a2fb5d8 | ||
|
|
9570e6cbec | ||
|
|
93a08c5ef9 | ||
|
|
a187c0c7ce | ||
|
|
43f4475272 | ||
|
|
a7ed32e206 | ||
|
|
6eadac23b3 | ||
|
|
1c7eb8f97a | ||
|
|
a71c5f42fc | ||
|
|
de0f1dc156 | ||
|
|
bb05961f70 | ||
|
|
57900e91ba | ||
|
|
98f650a5de | ||
|
|
55b2db4a8d | ||
|
|
fbe3088744 | ||
|
|
336ab6a64c | ||
|
|
c73fec46e6 | ||
|
|
b493e2bd5f | ||
|
|
78a7d6c5af | ||
|
|
a8b2e9a50c | ||
|
|
2d7c1e42d8 | ||
|
|
64ebec3ea4 | ||
|
|
252d32aafe | ||
|
|
2349370960 | ||
|
|
6ccc0f0538 | ||
|
|
9f12a47cfc | ||
|
|
ee880802c8 | ||
|
|
ab14e77b50 | ||
|
|
1d4245e582 | ||
|
|
8636a74ba4 | ||
|
|
3b766de306 | ||
|
|
1f300e1b75 | ||
|
|
56efe6035f | ||
|
|
73e363d159 | ||
|
|
3ac134bc16 | ||
|
|
c7bb1f9655 | ||
|
|
7847646b3e | ||
|
|
ec6e9f73bb | ||
|
|
bd62f033ab | ||
|
|
ba88ec25f6 | ||
|
|
b9bc41a772 | ||
|
|
e029458b09 | ||
|
|
b3ecf1776b | ||
|
|
5fe83588eb | ||
|
|
18b8eaabae | ||
|
|
e11695c2f0 | ||
|
|
91edbf71c8 | ||
|
|
5b9b22021b | ||
|
|
033d90b866 | ||
|
|
540c0df918 | ||
|
|
6de167467f | ||
|
|
c746326eb3 | ||
|
|
0fbd384a73 | ||
|
|
e8d4a98c7b | ||
|
|
f5aa63936c | ||
|
|
62a57d0f47 | ||
|
|
958fb4c739 | ||
|
|
e231275cbe | ||
|
|
5a404c3a35 | ||
|
|
b1c07c6204 | ||
|
|
60f158d488 | ||
|
|
1887c6fae3 | ||
|
|
725a825762 | ||
|
|
b81f59d5ae | ||
|
|
39c2b8927b | ||
|
|
89dfdac7bf | ||
|
|
c087edf2ba | ||
|
|
db33c315f2 | ||
|
|
c7e7dd8248 | ||
|
|
b10d82a883 | ||
|
|
e151b3d4ef | ||
|
|
5ccf4a45c1 | ||
|
|
c5369a5cad | ||
|
|
b5eba765a5 | ||
|
|
a5ddc38477 | ||
|
|
8d102256a2 | ||
|
|
2e561f7ea9 | ||
|
|
9656fe1b6f | ||
|
|
48c23f2a43 | ||
|
|
6d82649c3c | ||
|
|
81dea35754 | ||
|
|
fdbe43421b | ||
|
|
0d71560785 | ||
|
|
108e8a0cd4 | ||
|
|
653e81c48e | ||
|
|
0dc0783094 | ||
|
|
13ef1bf6be | ||
|
|
7ea80353f6 | ||
|
|
07bbff7d11 | ||
|
|
2ff4fc3cdd | ||
|
|
c9456055ea | ||
|
|
2900f2d67b | ||
|
|
93c8c90804 | ||
|
|
36e54642d2 | ||
|
|
e04cb28711 | ||
|
|
ad1dc51e06 | ||
|
|
5b6bab7a58 | ||
|
|
9bd2fc659d | ||
|
|
f18633f65f | ||
|
|
1026bc7b4f | ||
|
|
f1dee68142 | ||
|
|
f7cc2d295c | ||
|
|
a6f254b5cf | ||
|
|
00dbbe1b28 | ||
|
|
7f33309903 | ||
|
|
c95808fa2d | ||
|
|
5b6bd048a9 | ||
|
|
28e6ad3372 | ||
|
|
9b128ebba5 | ||
|
|
71f49180c3 | ||
|
|
4a042241a8 | ||
|
|
0eab9127e3 | ||
|
|
9f11991410 | ||
|
|
fec0b95098 | ||
|
|
5081439f53 | ||
|
|
c44aebee4d | ||
|
|
706cd50f25 | ||
|
|
b1b81c87f2 | ||
|
|
bf7e30539e | ||
|
|
5f8a61201b | ||
|
|
ed8aee8b8c | ||
|
|
92ec2af587 | ||
|
|
7960c87579 | ||
|
|
700d572732 | ||
|
|
014a0d86f1 | ||
|
|
88db59405f | ||
|
|
ef2e008700 | ||
|
|
07101c053a | ||
|
|
6c5f6ac475 | ||
|
|
61ecd9a617 | ||
|
|
6f56a9bfe9 | ||
|
|
416875ee46 | ||
|
|
c875b506ea | ||
|
|
ff4517e583 | ||
|
|
92cc989dc9 | ||
|
|
6e5987e3ca | ||
|
|
f03e232b90 | ||
|
|
1eb18c1790 | ||
|
|
3076d56973 | ||
|
|
b35707edf9 | ||
|
|
dfbd0dc9e7 | ||
|
|
620ad7ba71 | ||
|
|
5e4fd53243 | ||
|
|
0ba7630354 | ||
|
|
028d0ec0d5 | ||
|
|
751fa05fcd | ||
|
|
f89845257e | ||
|
|
2f274e2f47 | ||
|
|
38088e80e1 | ||
|
|
14162828ea | ||
|
|
ab8507e09d | ||
|
|
0d25c07333 | ||
|
|
bfc8ba8447 | ||
|
|
a45f8293d9 | ||
|
|
f29b9d14d7 | ||
|
|
9c9fd2deef | ||
|
|
3bb01ffd68 | ||
|
|
bc6d9994dc | ||
|
|
e177f9e0fe | ||
|
|
c5d75d2de9 | ||
|
|
cc0cade4d2 | ||
|
|
1e3362250f | ||
|
|
db16e8d602 | ||
|
|
2a563eddd0 | ||
|
|
6b8474b7b9 | ||
|
|
b5336c81cc | ||
|
|
1fcab825bf | ||
|
|
0306556032 | ||
|
|
b093578046 | ||
|
|
9332b9eb33 | ||
|
|
141c7817a0 | ||
|
|
f155026d8f | ||
|
|
37e467ba60 | ||
|
|
3572b835b5 | ||
|
|
da4f3a72af | ||
|
|
2938bbd11f | ||
|
|
abf3017eb2 | ||
|
|
5c855ea52f | ||
|
|
c83edea7ad | ||
|
|
6d3113c8c3 | ||
|
|
48c48c7bbc | ||
|
|
e4093ed988 | ||
|
|
c79af52720 | ||
|
|
61eeaca6d5 | ||
|
|
320a79ba72 | ||
|
|
2e1b943805 | ||
|
|
bc167dde2d | ||
|
|
7d9a8b4211 | ||
|
|
0b16d88756 | ||
|
|
796cb31ed7 | ||
|
|
d7fd2f26c1 | ||
|
|
5adb8749de | ||
|
|
3474faa4a2 | ||
|
|
acd9c04ff6 | ||
|
|
833c9406b0 | ||
|
|
2f1253e27f | ||
|
|
53b847e31c | ||
|
|
7efa33dd7f | ||
|
|
4011970a57 | ||
|
|
a2cfa2be16 | ||
|
|
c4b691d688 | ||
|
|
72a7a8eee5 | ||
|
|
52d352385f | ||
|
|
c1f85650bd | ||
|
|
b830909504 | ||
|
|
4ad6b1c220 | ||
|
|
429488a4ba | ||
|
|
40c6cc11a5 | ||
|
|
594881c6ce | ||
|
|
1cc64a0fbc | ||
|
|
f492318e3c | ||
|
|
4b06bb7795 | ||
|
|
f7e570383a | ||
|
|
896a088199 | ||
|
|
f3322bd003 | ||
|
|
cef947d67d | ||
|
|
b6640d118d | ||
|
|
273d0b2ce9 | ||
|
|
9b724d776e | ||
|
|
3eaa706ccf | ||
|
|
b4c854dfe8 | ||
|
|
9cdadbe834 | ||
|
|
b3f38a8764 | ||
|
|
5d868284c6 | ||
|
|
035751980d | ||
|
|
6b80bc08d5 | ||
|
|
2089959d1b | ||
|
|
67b00ec28d | ||
|
|
127ae6b945 | ||
|
|
4f53b3ce35 | ||
|
|
c3092b482a | ||
|
|
080219f88d | ||
|
|
3fd783cd01 | ||
|
|
211cd964d7 | ||
|
|
04f42f0be4 | ||
|
|
e00ef893d0 | ||
|
|
858efa604e | ||
|
|
b63b17c54f | ||
|
|
f0e111c20e | ||
|
|
7339f57138 | ||
|
|
1e39c999f9 | ||
|
|
62f7a06192 | ||
|
|
a0531b7930 | ||
|
|
0619d04939 | ||
|
|
cd76476d26 | ||
|
|
53b6c17e33 | ||
|
|
3b7b66b272 | ||
|
|
a795a45c34 | ||
|
|
b58cbd228c | ||
|
|
fc994285f9 | ||
|
|
d5e74b91c7 | ||
|
|
c5eb2e1070 | ||
|
|
d613cb057e | ||
|
|
121792bebe | ||
|
|
e07c230106 | ||
|
|
d5ce3044c8 | ||
|
|
98ff43b4d2 | ||
|
|
1704fbcd62 | ||
|
|
014ac1cf72 | ||
|
|
b499c7ee75 | ||
|
|
2e069e326c | ||
|
|
e47d42da22 | ||
|
|
615e5dfaa7 | ||
|
|
fde2c371ef | ||
|
|
a0b4e7fd5d | ||
|
|
45c36bbcae | ||
|
|
66c041ad93 | ||
|
|
32d5c52b5f | ||
|
|
9cf5b01633 | ||
|
|
d4cf22d370 | ||
|
|
973640f023 | ||
|
|
248ea82f76 | ||
|
|
a868079a93 | ||
|
|
d270d5b9ca | ||
|
|
e9692a438b | ||
|
|
06ea123dbd | ||
|
|
85141d5eda | ||
|
|
fa13b8fbd0 | ||
|
|
5b4712644a | ||
|
|
aa422914bd | ||
|
|
22c453e297 | ||
|
|
e5f40cec5a | ||
|
|
50b24bf6c2 | ||
|
|
b575ee9e28 | ||
|
|
37030621ac | ||
|
|
f005da4d12 | ||
|
|
6295559d9c | ||
|
|
f36ff303d9 | ||
|
|
1a62e91c01 | ||
|
|
7f314dfe11 | ||
|
|
0caf9f4214 | ||
|
|
1ad600c81a | ||
|
|
bd6c7b7fdb | ||
|
|
5f93724845 | ||
|
|
ad60eac6ef | ||
|
|
b3e3a2937a | ||
|
|
d010038228 | ||
|
|
c28eada93e | ||
|
|
9d84a92b1f | ||
|
|
7884be106d | ||
|
|
5fe7c7e7e1 | ||
|
|
f244b95aad | ||
|
|
3b5a5759b8 | ||
|
|
528e7ee33b | ||
|
|
c1f55735fc | ||
|
|
185ea86284 | ||
|
|
618262f015 | ||
|
|
c0f41ac10e | ||
|
|
3010699f20 | ||
|
|
fb274538e1 | ||
|
|
1a5d953a98 | ||
|
|
2dd1baebb3 | ||
|
|
d46beac22a | ||
|
|
6ed8741006 | ||
|
|
6845e42f2c | ||
|
|
5196869634 | ||
|
|
083806bfc9 | ||
|
|
11d29368ce | ||
|
|
100c3d9e36 | ||
|
|
01fbf8c3a5 | ||
|
|
a36556d7e4 | ||
|
|
4f11162fae | ||
|
|
2cbaf39fd5 | ||
|
|
2cc46c618b | ||
|
|
a0325e91f9 | ||
|
|
e11edd5dee | ||
|
|
5e8990f571 | ||
|
|
a3fd55036a | ||
|
|
7a3d15c48b | ||
|
|
a5b52a2470 | ||
|
|
a8cd14dafd | ||
|
|
2b249bd496 | ||
|
|
c8586cfe26 | ||
|
|
f228cb241f | ||
|
|
fd33ef8496 | ||
|
|
ba1cf6473a | ||
|
|
f418dcdb7b | ||
|
|
f91c26d752 | ||
|
|
f7156f2ff2 | ||
|
|
e444b587cf | ||
|
|
a7fcc6a5cf | ||
|
|
872b1ccbb6 | ||
|
|
b7b3400296 | ||
|
|
420ccdcb82 | ||
|
|
eaa4d6323e | ||
|
|
4e7ac41a6c | ||
|
|
92f3a736a7 | ||
|
|
5a30b2b298 | ||
|
|
85aaae67bf | ||
|
|
efe66bc72e | ||
|
|
d7bdf3fc19 | ||
|
|
c4e5f4410c | ||
|
|
f5039dca56 |
90
.github/ISSUE_TEMPLATE.md
vendored
Normal file
90
.github/ISSUE_TEMPLATE.md
vendored
Normal file
@@ -0,0 +1,90 @@
|
||||
<!--
|
||||
-- THIS IS NOT A SUPPORT FORUM! For support go here:
|
||||
-- Nintendo Homebrew: https://discord.gg/MjzatM8
|
||||
--
|
||||
-- Rosalina feature requests go here: https://github.com/AuroraWright/Luma3DS/issues/752
|
||||
--
|
||||
-- Also check the Wiki (https://github.com/AuroraWright/Luma3DS/wiki) before making an issue.
|
||||
--
|
||||
-- For GBA/DSiWare/DS/AGB_FIRM/TWL_FIRM problems: https://3ds.guide/troubleshooting
|
||||
-- If you're using an emu/redNAND try installing anything on it to sysNAND.
|
||||
-- Please make sure to read "Enable game patching" https://github.com/AuroraWright/Luma3DS/wiki/Options-and-usage before posting any issues about the "Enable game patching" option(s).
|
||||
--
|
||||
-- Luma updaters that don't support Boot9Strap/Sighax won't work.
|
||||
-- This is due to support for non-B9S/Sighax entrypoints being dropped.
|
||||
--
|
||||
-- Please fill in the placeholders.-->
|
||||
**System model:**
|
||||
|
||||
[e.g. 2DS, New 3DS, Old 3DS]
|
||||
|
||||
**SysNAND version (+emu/redNAND version if applicable):**
|
||||
|
||||
[e.g. 11.6.0-39U SysNAND, 11.6.0-39J EmuNAND]
|
||||
|
||||
**Entrypoint (How/what you're using to boot Luma3DS):**
|
||||
|
||||
[e.g. Boot9Strap/Sighax, etc.]
|
||||
|
||||
**Luma3DS version:**
|
||||
|
||||
[e.g. 8.1.1 stable or if using nightly/hourly specify the commit like this https://github.com/AuroraWright/Luma3DS/commit/9570e6cbeca53128433abbf5e3473cb8a07fe69e]
|
||||
<!--You can check which version you're on in System Settings. It will be on the bottom right of the top screen.-->
|
||||
|
||||
|
||||
**Luma3DS configuration/options:**
|
||||
|
||||
Default EmuNAND: ( )
|
||||
|
||||
Screen brightness: ( )
|
||||
|
||||
Splash: ( )
|
||||
|
||||
PIN lock: ( )
|
||||
|
||||
New 3DS CPU: ( )
|
||||
<!--This option is only available for New 3DS/2DS.-->
|
||||
|
||||
--
|
||||
|
||||
Autoboot EmuNAND: ( )
|
||||
|
||||
Use EmuNAND FIRM if booting with R: ( )
|
||||
|
||||
Enable loading external FIRMs and modules: ( )
|
||||
<!--Firmware (.bin) files are not required by Luma, or NTR CFW anymore.
|
||||
-- If you're having issues with this option enabled try deleting them from the luma folder on the root of the SD card or /rw/luma on CTRNAND and disabling this option.-->
|
||||
|
||||
Enable game patching: ( )
|
||||
|
||||
Show NAND or user string in System Settings: ( )
|
||||
|
||||
Show GBA boot screen in patched AGB_FIRM: ( )
|
||||
|
||||
Patch ARM9 access: ( )
|
||||
|
||||
Set developer UNITINFO: ( )
|
||||
|
||||
Disable ARM11 exception handlers: ( )
|
||||
|
||||
--
|
||||
|
||||
|
||||
**Explanation of the issue:**
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
**Steps to reproduce:**
|
||||
|
||||
1.
|
||||
|
||||
2.
|
||||
|
||||
|
||||
**Dump file:**
|
||||
<!--If the issue leads to a crash you must uncheck the "Disable ARM11 exception handlers" option.
|
||||
-- The error message will tell you where the dump is.
|
||||
-- Zip the dmp file and drag & drop it below.-->
|
||||
18
.gitignore
vendored
18
.gitignore
vendored
@@ -1,12 +1,20 @@
|
||||
.vscode
|
||||
out
|
||||
build
|
||||
loader/build
|
||||
injector/build
|
||||
arm11/build
|
||||
sysmodules/loader/build
|
||||
sysmodules/rosalina/build
|
||||
chainloader/build
|
||||
exceptions/arm9/build
|
||||
exceptions/arm11/build
|
||||
*.bin
|
||||
*.3dsx
|
||||
*.smdh
|
||||
*.firm
|
||||
*.o
|
||||
*.d
|
||||
*.elf
|
||||
*.elf
|
||||
*.cxi
|
||||
.DS_Store
|
||||
*.dmp
|
||||
.project
|
||||
.cproject
|
||||
.settings
|
||||
|
||||
6
.gitmodules
vendored
6
.gitmodules
vendored
@@ -1,6 +0,0 @@
|
||||
[submodule "CakeBrah"]
|
||||
path = CakeBrah
|
||||
url = https://github.com/mid-kid/CakeBrah
|
||||
[submodule "CakeHax"]
|
||||
path = CakeHax
|
||||
url = https://github.com/mid-kid/CakeHax
|
||||
1
CakeBrah
1
CakeBrah
Submodule CakeBrah deleted from 9f7cea77d4
1
CakeHax
1
CakeHax
Submodule CakeHax deleted from 5245c7b9dc
234
Makefile
234
Makefile
@@ -4,166 +4,174 @@ ifeq ($(strip $(DEVKITARM)),)
|
||||
$(error "Please set DEVKITARM in your environment. export DEVKITARM=<path to>devkitARM")
|
||||
endif
|
||||
|
||||
include $(DEVKITARM)/3ds_rules
|
||||
ifneq ($(strip $(shell firmtool -v 2>&1 | grep usage)),)
|
||||
$(error "Please install firmtool v1.1 or greater")
|
||||
endif
|
||||
|
||||
CC := arm-none-eabi-gcc
|
||||
AS := arm-none-eabi-as
|
||||
LD := arm-none-eabi-ld
|
||||
OC := arm-none-eabi-objcopy
|
||||
include $(DEVKITARM)/base_tools
|
||||
|
||||
name := Luma3DS
|
||||
revision := $(shell git describe --tags --match v[0-9]* --abbrev=8 | sed 's/-[0-9]*-g/-/i')
|
||||
revision := $(shell git describe --tags --match v[0-9]* --abbrev=8 | sed 's/-[0-9]*-g/-/')
|
||||
version_major := $(shell git describe --tags --match v[0-9]* | cut -c2- | cut -f1 -d- | cut -f1 -d.)
|
||||
version_minor := $(shell git describe --tags --match v[0-9]* | cut -c2- | cut -f1 -d- | cut -f2 -d.)
|
||||
version_build := $(shell git describe --tags --match v[0-9]* | cut -c2- | cut -f1 -d- | cut -f3 -d.)
|
||||
commit := $(shell git rev-parse --short=8 HEAD)
|
||||
is_release := 0
|
||||
|
||||
ifeq ($(strip $(revision)),)
|
||||
revision := v0.0.0-0
|
||||
version_major := 0
|
||||
version_minor := 0
|
||||
version_build := 0
|
||||
endif
|
||||
|
||||
ifeq ($(strip $(commit)),)
|
||||
commit := 0
|
||||
endif
|
||||
|
||||
ifeq ($(strip $(version_build)),)
|
||||
version_build := 0
|
||||
endif
|
||||
|
||||
ifeq ($(strip $(shell git describe --tags --match v[0-9]* | grep -)),)
|
||||
is_release := 1
|
||||
endif
|
||||
|
||||
dir_source := source
|
||||
dir_patches := patches
|
||||
dir_loader := loader
|
||||
dir_injector := injector
|
||||
dir_arm11 := arm11
|
||||
dir_chainloader := chainloader
|
||||
dir_exceptions := exceptions
|
||||
dir_arm9_exceptions := $(dir_exceptions)/arm9
|
||||
dir_arm11_exceptions := $(dir_exceptions)/arm11
|
||||
dir_mset := CakeHax
|
||||
dir_ninjhax := CakeBrah
|
||||
dir_menuhax := menuhax
|
||||
dir_pathchanger := pathchanger
|
||||
dir_k11_extension := k11_extension
|
||||
dir_sysmodules := sysmodules
|
||||
dir_loader := $(dir_sysmodules)/loader
|
||||
dir_rosalina := $(dir_sysmodules)/rosalina
|
||||
dir_sm := $(dir_sysmodules)/sm
|
||||
dir_pxi := $(dir_sysmodules)/pxi
|
||||
dir_build := build
|
||||
dir_out := out
|
||||
|
||||
ASFLAGS := -mcpu=arm946e-s
|
||||
CFLAGS := -Wall -Wextra -MMD -MP -marm $(ASFLAGS) -fno-builtin -fshort-wchar -std=c11 -Wno-main -O2 -flto -ffast-math
|
||||
LDFLAGS := -nostartfiles
|
||||
FLAGS := name=$(name).dat dir_out=$(abspath $(dir_out)) ICON=$(abspath icon.png) APP_DESCRIPTION="Noob-friendly 3DS CFW." APP_AUTHOR="Aurora Wright/TuxSH" --no-print-directory
|
||||
CFLAGS := -Wall -Wextra $(ASFLAGS) -fno-builtin -std=c11 -Wno-main -O2 -flto -ffast-math
|
||||
LDFLAGS := -nostartfiles -Wl,--nmagic
|
||||
|
||||
objects = $(patsubst $(dir_source)/%.s, $(dir_build)/%.o, \
|
||||
$(patsubst $(dir_source)/%.c, $(dir_build)/%.o, \
|
||||
$(call rwildcard, $(dir_source), *.s *.c)))
|
||||
|
||||
bundled = $(dir_build)/rebootpatch.h $(dir_build)/emunandpatch.h $(dir_build)/svcGetCFWInfopatch.h $(dir_build)/injector.h $(dir_build)/loader.h
|
||||
bundled = $(dir_build)/reboot.bin.o $(dir_build)/emunand.bin.o $(dir_build)/chainloader.bin.o $(dir_build)/arm9_exceptions.bin.o
|
||||
|
||||
ifeq ($(strip $(DEV)),TRUE)
|
||||
CFLAGS += -DDEV
|
||||
bundled += $(dir_build)/k11modulespatch.h $(dir_build)/arm9_exceptions.h $(dir_build)/arm11_exceptions.h
|
||||
title := \"$(name) $(revision) (dev) configuration\"
|
||||
else
|
||||
title := \"$(name) $(revision) configuration\"
|
||||
endif
|
||||
modules = $(dir_build)/loader.cxi $(dir_build)/rosalina.cxi $(dir_build)/sm.cxi $(dir_build)/pxi.cxi
|
||||
|
||||
define bin2o
|
||||
bin2s $< | $(AS) -o $(@)
|
||||
endef
|
||||
|
||||
.PHONY: all
|
||||
all: launcher a9lh ninjhax menuhax
|
||||
|
||||
.PHONY: launcher
|
||||
launcher: $(dir_out)/$(name).dat
|
||||
|
||||
.PHONY: a9lh
|
||||
a9lh: $(dir_out)/arm9loaderhax.bin
|
||||
|
||||
.PHONY: ninjhax
|
||||
ninjhax: $(dir_out)/3ds/$(name)
|
||||
|
||||
.PHONY: menuhax
|
||||
menuhax: $(dir_out)/menuhax/boot.3dsx
|
||||
all: firm
|
||||
|
||||
.PHONY: release
|
||||
ifeq ($(strip $(DEV)),TRUE)
|
||||
release: $(dir_out)/$(name)$(revision)-dev.7z
|
||||
else
|
||||
release: $(dir_out)/$(name)$(revision).7z
|
||||
endif
|
||||
|
||||
.PHONY: firm
|
||||
firm: $(dir_out)/boot.firm
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
@$(MAKE) $(FLAGS) -C $(dir_mset) clean
|
||||
@$(MAKE) $(FLAGS) -C $(dir_ninjhax) clean
|
||||
@$(MAKE) -C $(dir_loader) clean
|
||||
@$(MAKE) -C $(dir_arm11) clean
|
||||
@$(MAKE) -C $(dir_chainloader) clean
|
||||
@$(MAKE) -C $(dir_arm9_exceptions) clean
|
||||
@$(MAKE) -C $(dir_arm11_exceptions) clean
|
||||
@$(MAKE) -C $(dir_injector) clean
|
||||
@$(MAKE) -C $(dir_k11_extension) clean
|
||||
@$(MAKE) -C $(dir_loader) clean
|
||||
@$(MAKE) -C $(dir_rosalina) clean
|
||||
@$(MAKE) -C $(dir_sm) clean
|
||||
@$(MAKE) -C $(dir_pxi) clean
|
||||
@rm -rf $(dir_out) $(dir_build)
|
||||
|
||||
$(dir_out):
|
||||
@mkdir -p "$(dir_out)"
|
||||
.PRECIOUS: $(dir_build)/%.bin
|
||||
|
||||
$(dir_out)/$(name).dat: $(dir_build)/main.bin $(dir_out)
|
||||
@$(MAKE) $(FLAGS) -C $(dir_mset) launcher
|
||||
@dd if=$(dir_build)/main.bin of=$@ bs=512 seek=144
|
||||
.PHONY: $(dir_arm11)
|
||||
.PHONY: $(dir_chainloader)
|
||||
.PHONY: $(dir_arm9_exceptions)
|
||||
.PHONY: $(dir_k11_extension)
|
||||
.PHONY: $(dir_loader)
|
||||
.PHONY: $(dir_rosalina)
|
||||
.PHONY: $(dir_sm)
|
||||
.PHONY: $(dir_pxi)
|
||||
|
||||
$(dir_out)/menuhax/boot.3dsx: $(dir_menuhax)/menuhax.diff $(dir_out)
|
||||
|
||||
$(dir_out)/$(name)$(revision).7z: all
|
||||
@mkdir -p "$(@D)"
|
||||
@cd $(dir_ninjhax); patch -p1 < ../$(dir_menuhax)/menuhax.diff; $(MAKE) $(FLAGS); git reset --hard
|
||||
@mv $(dir_out)/$(name).3dsx $@
|
||||
@rm $(dir_out)/$(name).smdh
|
||||
@[ -f "$@" ] || 7z a -mx $@ ./$(@D)/* ./$(dir_exceptions)/exception_dump_parser -xr!.DS_Store
|
||||
|
||||
$(dir_out)/arm9loaderhax.bin: $(dir_build)/main.bin $(dir_out)
|
||||
@cp -a $(dir_build)/main.bin $@
|
||||
$(dir_out)/boot.firm: $(dir_build)/modules.bin $(dir_build)/arm11.elf $(dir_build)/main.elf $(dir_build)/k11_extension.bin
|
||||
@mkdir -p "$(@D)"
|
||||
@firmtool build $@ -D $^ -A 0x18180000 0x18000000 -C XDMA XDMA NDMA XDMA
|
||||
|
||||
$(dir_out)/3ds/$(name): $(dir_out)
|
||||
@mkdir -p "$@"
|
||||
@$(MAKE) $(FLAGS) -C $(dir_ninjhax)
|
||||
@mv $(dir_out)/$(name).3dsx $(dir_out)/$(name).smdh $@
|
||||
$(dir_build)/modules.bin: $(modules)
|
||||
@mkdir -p "$(@D)"
|
||||
cat $^ > $@
|
||||
|
||||
$(dir_out)/pathchanger: $(dir_pathchanger)/pathchanger.py $(dir_pathchanger)/prebuilt $(dir_out)
|
||||
@mkdir -p "$@"
|
||||
@cp $(dir_pathchanger)/pathchanger.py $@
|
||||
@cp -rfT $(dir_pathchanger)/prebuilt $@
|
||||
$(dir_build)/arm11.elf: $(dir_arm11)
|
||||
@mkdir -p "$(@D)"
|
||||
@$(MAKE) -C $<
|
||||
|
||||
$(dir_out)/$(name)$(revision).7z: all $(dir_out)/pathchanger
|
||||
@7z a -mx $@ ./$(@D)/*
|
||||
|
||||
$(dir_out)/$(name)$(revision)-dev.7z: all $(dir_out)/pathchanger
|
||||
@7z a -mx $@ ./$(@D)/* ./$(dir_exceptions)/exception_dump_parser.py
|
||||
|
||||
$(dir_build)/main.bin: $(dir_build)/main.elf
|
||||
$(OC) -S -O binary $< $@
|
||||
|
||||
$(dir_build)/main.elf: $(objects)
|
||||
$(dir_build)/main.elf: $(bundled) $(objects)
|
||||
$(LINK.o) -T linker.ld $(OUTPUT_OPTION) $^
|
||||
|
||||
$(dir_build)/emunandpatch.h: $(dir_patches)/emunand.s
|
||||
$(dir_build)/k11_extension.bin: $(dir_k11_extension)
|
||||
@mkdir -p "$(@D)"
|
||||
@$(MAKE) -C $<
|
||||
|
||||
$(dir_build)/loader.cxi: $(dir_loader)
|
||||
@mkdir -p "$(@D)"
|
||||
@$(MAKE) -C $<
|
||||
|
||||
$(dir_build)/rosalina.cxi: $(dir_rosalina)
|
||||
@mkdir -p "$(@D)"
|
||||
@$(MAKE) -C $<
|
||||
|
||||
$(dir_build)/sm.cxi: $(dir_sm)
|
||||
@mkdir -p "$(@D)"
|
||||
@$(MAKE) -C $<
|
||||
|
||||
$(dir_build)/pxi.cxi: $(dir_pxi)
|
||||
@mkdir -p "$(@D)"
|
||||
@$(MAKE) -C $<
|
||||
|
||||
$(dir_build)/%.bin.o: $(dir_build)/%.bin
|
||||
@$(bin2o)
|
||||
|
||||
$(dir_build)/chainloader.bin: $(dir_chainloader)
|
||||
@mkdir -p "$(@D)"
|
||||
@$(MAKE) -C $<
|
||||
|
||||
$(dir_build)/arm9_exceptions.bin: $(dir_arm9_exceptions)
|
||||
@mkdir -p "$(@D)"
|
||||
@$(MAKE) -C $<
|
||||
|
||||
$(dir_build)/%.bin: $(dir_patches)/%.s
|
||||
@mkdir -p "$(@D)"
|
||||
@armips $<
|
||||
@bin2c -o $@ -n emunand $(@D)/emunand.bin
|
||||
|
||||
$(dir_build)/rebootpatch.h: $(dir_patches)/reboot.s
|
||||
@mkdir -p "$(@D)"
|
||||
@armips $<
|
||||
@bin2c -o $@ -n reboot $(@D)/reboot.bin
|
||||
|
||||
$(dir_build)/svcGetCFWInfopatch.h: $(dir_patches)/svcGetCFWInfo.s
|
||||
@mkdir -p "$(@D)"
|
||||
@armips $<
|
||||
@bin2c -o $@ -n svcGetCFWInfo $(@D)/svcGetCFWInfo.bin
|
||||
|
||||
$(dir_build)/injector.h: $(dir_injector)/Makefile
|
||||
@mkdir -p "$(@D)"
|
||||
@$(MAKE) -C $(dir_injector) DEV=$(DEV)
|
||||
@bin2c -o $@ -n injector $(@D)/injector.cxi
|
||||
|
||||
$(dir_build)/loader.h: $(dir_loader)/Makefile
|
||||
@$(MAKE) -C $(dir_loader)
|
||||
@bin2c -o $@ -n loader $(@D)/loader.bin
|
||||
|
||||
$(dir_build)/k11modulespatch.h: $(dir_patches)/k11modules.s
|
||||
@mkdir -p "$(@D)"
|
||||
@armips $<
|
||||
@bin2c -o $@ -n k11modules $(@D)/k11modules.bin
|
||||
|
||||
$(dir_build)/arm9_exceptions.h: $(dir_arm9_exceptions)/Makefile
|
||||
@$(MAKE) -C $(dir_arm9_exceptions)
|
||||
@bin2c -o $@ -n arm9_exceptions $(@D)/arm9_exceptions.bin
|
||||
|
||||
$(dir_build)/arm11_exceptions.h: $(dir_arm11_exceptions)/Makefile
|
||||
@$(MAKE) -C $(dir_arm11_exceptions)
|
||||
@bin2c -o $@ -n arm11_exceptions $(@D)/arm11_exceptions.bin
|
||||
|
||||
$(dir_build)/memory.o $(dir_build)/strings.o: CFLAGS += -O3
|
||||
$(dir_build)/config.o: CFLAGS += -DCONFIG_TITLE="$(title)"
|
||||
$(dir_build)/patches.o: CFLAGS += -DREVISION=\"$(revision)\" -DCOMMIT_HASH="0x$(commit)"
|
||||
$(dir_build)/config.o: CFLAGS += -DCONFIG_TITLE="\"$(name) $(revision) configuration\""
|
||||
$(dir_build)/patches.o: CFLAGS += -DVERSION_MAJOR="$(version_major)" -DVERSION_MINOR="$(version_minor)"\
|
||||
-DVERSION_BUILD="$(version_build)" -DISRELEASE="$(is_release)" -DCOMMIT_HASH="0x$(commit)"
|
||||
$(dir_build)/firm.o: $(dir_build)/modules.bin
|
||||
$(dir_build)/firm.o: CFLAGS += -DLUMA_SECTION0_SIZE="$(shell wc -c $(dir_build)/modules.bin | tr -d [:space:][:alpha:][:punct:])"
|
||||
|
||||
$(dir_build)/%.o: $(dir_source)/%.c $(bundled)
|
||||
$(dir_build)/bundled.h: $(bundled)
|
||||
@$(foreach f, $(bundled),\
|
||||
echo "extern const u8" `(echo $(basename $(notdir $(f))) | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`"[];" >> $@;\
|
||||
echo "extern const u32" `(echo $(basename $(notdir $(f)))| sed -e 's/^\([0-9]\)/_\1/' | tr . _)`_size";" >> $@;\
|
||||
)
|
||||
|
||||
$(dir_build)/%.o: $(dir_source)/%.c $(dir_build)/bundled.h
|
||||
@mkdir -p "$(@D)"
|
||||
$(COMPILE.c) $(OUTPUT_OPTION) $<
|
||||
|
||||
$(dir_build)/%.o: $(dir_source)/%.s
|
||||
@mkdir -p "$(@D)"
|
||||
$(COMPILE.s) $(OUTPUT_OPTION) $<
|
||||
include $(call rwildcard, $(dir_build), *.d)
|
||||
|
||||
13
README.md
13
README.md
@@ -5,16 +5,19 @@
|
||||
|
||||
**Luma3DS** is a program to patch the system software of (New) Nintendo 3DS handheld consoles "on the fly", adding features (such as per-game language settings and debugging capabilities for developers) and removing restrictions enforced by Nintendo (such as the region lock).
|
||||
It also allows you to run unauthorized ("homebrew") content by removing signature checks.
|
||||
To use it, you will need a console capable of running homebrew software on the ARM9 processor. We recommend [Plailect's guide](https://github.com/Plailect/Guide/wiki) for details on how to get your system ready.
|
||||
To use it, you will need a console capable of running homebrew software on the ARM9 processor. We recommend [Plailect's guide](https://3ds.guide/) for details on how to get your system ready.
|
||||
|
||||
Since Luma3DS v8.0, Luma3DS has its own in-game menu, triggerable by `L+Down+Select` (see the [release notes](https://github.com/AuroraWright/Luma3DS/releases/tag/v8.0)).
|
||||
|
||||
---
|
||||
|
||||
## Compiling
|
||||
|
||||
First you need to clone the repository recursively with: `git clone --recursive https://github.com/AuroraWright/Luma3DS.git`
|
||||
To compile, you'll need [armips](https://github.com/Kingcom/armips), [bin2c](https://sourceforge.net/projects/bin2c/), and a recent build of [makerom](https://github.com/profi200/Project_CTR) added to your PATH.
|
||||
For your convenience, here are [Windows](http://www91.zippyshare.com/v/ePGpjk9r/file.html) and [Linux](https://mega.nz/#!uQ1T1IAD!Q91O0e12LXKiaXh_YjXD3D5m8_W3FuMI-hEa6KVMRDQ) builds of armips (thanks to who compiled them!).
|
||||
Finally just run `make` (for the regular version) or `make DEV=TRUE` (for the dev version) and everything should work!
|
||||
First you need to clone the repository with: `git clone https://github.com/AuroraWright/Luma3DS.git`
|
||||
To compile, you'll need [armips](https://github.com/Kingcom/armips) and a build of a recent commit of [makerom](https://github.com/profi200/Project_CTR) added to your PATH. You'll also need to install [firmtool](https://github.com/TuxSH/firmtool), its README contains installation instructions.
|
||||
You'll also need to update your [libctru](https://github.com/smealum/ctrulib) install, building from the latest commit.
|
||||
Here are [Windows](https://buildbot.orphis.net/armips/) and [Linux](https://mega.nz/#!uQ1T1IAD!Q91O0e12LXKiaXh_YjXD3D5m8_W3FuMI-hEa6KVMRDQ) builds of armips (thanks to who compiled them!) and [makerom](https://github.com/Steveice10/buildtools/tree/master/3ds) (thanks @Steveice10!).
|
||||
Run `make` and everything should work!
|
||||
You can find the compiled files in the `out` folder.
|
||||
|
||||
---
|
||||
|
||||
@@ -4,38 +4,31 @@ ifeq ($(strip $(DEVKITARM)),)
|
||||
$(error "Please set DEVKITARM in your environment. export DEVKITARM=<path to>devkitARM")
|
||||
endif
|
||||
|
||||
include $(DEVKITARM)/3ds_rules
|
||||
include $(DEVKITARM)/base_tools
|
||||
|
||||
CC := arm-none-eabi-gcc
|
||||
AS := arm-none-eabi-as
|
||||
LD := arm-none-eabi-ld
|
||||
OC := arm-none-eabi-objcopy
|
||||
|
||||
name := arm11_exceptions
|
||||
name := $(shell basename $(CURDIR))
|
||||
|
||||
dir_source := source
|
||||
dir_build := build
|
||||
dir_out := ../$(dir_build)
|
||||
|
||||
ASFLAGS := -mcpu=mpcore -mfpu=vfp
|
||||
CFLAGS := -Wall -Wextra -MMD -MP -mthumb -mthumb-interwork $(ASFLAGS) -fno-builtin -std=c11 -Wno-main -O2 -flto -ffast-math
|
||||
LDFLAGS := -nostdlib
|
||||
ASFLAGS := -mcpu=mpcore
|
||||
CFLAGS := -Wall -Wextra -MMD -MP -marm $(ASFLAGS) -fno-builtin -std=c11 -Wno-main -O2 -flto -ffast-math
|
||||
LDFLAGS := -nostartfiles -Wl,--nmagic
|
||||
|
||||
objects = $(patsubst $(dir_source)/%.s, $(dir_build)/%.o, \
|
||||
$(patsubst $(dir_source)/%.c, $(dir_build)/%.o, \
|
||||
$(call rwildcard, $(dir_source), *.s *.c)))
|
||||
|
||||
.PHONY: all
|
||||
all: ../../$(dir_build)/$(name).bin
|
||||
all: $(dir_out)/$(name).elf
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
@rm -rf $(dir_build)
|
||||
|
||||
../../$(dir_build)/$(name).bin: $(dir_build)/$(name).elf
|
||||
$(OC) -S -O binary $< $@
|
||||
|
||||
$(dir_build)/$(name).elf: $(objects)
|
||||
$(CC) $(LDFLAGS) -T linker.ld $(OUTPUT_OPTION) $^
|
||||
$(dir_out)/$(name).elf: $(objects)
|
||||
$(LINK.o) -T linker.ld $(OUTPUT_OPTION) $^
|
||||
|
||||
$(dir_build)/%.o: $(dir_source)/%.c
|
||||
@mkdir -p "$(@D)"
|
||||
@@ -44,4 +37,3 @@ $(dir_build)/%.o: $(dir_source)/%.c
|
||||
$(dir_build)/%.o: $(dir_source)/%.s
|
||||
@mkdir -p "$(@D)"
|
||||
$(COMPILE.s) $(OUTPUT_OPTION) $<
|
||||
include $(call rwildcard, $(dir_build), *.d)
|
||||
16
arm11/linker.ld
Normal file
16
arm11/linker.ld
Normal file
@@ -0,0 +1,16 @@
|
||||
OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")
|
||||
OUTPUT_ARCH(arm)
|
||||
|
||||
ENTRY(_start)
|
||||
SECTIONS
|
||||
{
|
||||
. = 0x1FF80000;
|
||||
|
||||
.text : ALIGN(4) { *(.text.start) *(.text*); . = ALIGN(4); }
|
||||
.rodata : ALIGN(4) { *(.rodata*); . = ALIGN(4); }
|
||||
.data : ALIGN(4) { *(.data*); . = ALIGN(4); }
|
||||
.bss : ALIGN(8) { __bss_start = .; *(.bss* COMMON); . = ALIGN(8); __bss_end = .; }
|
||||
|
||||
__stack_top__ = 0x1FFFE000;
|
||||
. = ALIGN(4);
|
||||
}
|
||||
211
arm11/source/main.c
Normal file
211
arm11/source/main.c
Normal file
@@ -0,0 +1,211 @@
|
||||
/*
|
||||
* This file is part of Luma3DS
|
||||
* Copyright (C) 2016-2017 Aurora Wright, TuxSH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
|
||||
* * Requiring preservation of specified reasonable legal notices or
|
||||
* author attributions in that material or in the Appropriate Legal
|
||||
* Notices displayed by works containing it.
|
||||
* * Prohibiting misrepresentation of the origin of that material,
|
||||
* or requiring that modified versions of such material be marked in
|
||||
* reasonable ways as different from the original version.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Screen init code by dark_samus, bil1s, Normmatt, delebile and others
|
||||
* LCD deinit code by tiniVi
|
||||
*/
|
||||
|
||||
#include "types.h"
|
||||
#include "memory.h"
|
||||
|
||||
void prepareForFirmlaunch(void);
|
||||
extern u32 prepareForFirmlaunchSize;
|
||||
|
||||
extern volatile Arm11Operation operation;
|
||||
|
||||
static void initScreens(u32 brightnessLevel, struct fb *fbs)
|
||||
{
|
||||
*(vu32 *)0x10141200 = 0x1007F;
|
||||
*(vu32 *)0x10202014 = 0x00000001;
|
||||
*(vu32 *)0x1020200C &= 0xFFFEFFFE;
|
||||
*(vu32 *)0x10202240 = brightnessLevel;
|
||||
*(vu32 *)0x10202A40 = brightnessLevel;
|
||||
*(vu32 *)0x10202244 = 0x1023E;
|
||||
*(vu32 *)0x10202A44 = 0x1023E;
|
||||
|
||||
//Top screen
|
||||
*(vu32 *)0x10400400 = 0x000001c2;
|
||||
*(vu32 *)0x10400404 = 0x000000d1;
|
||||
*(vu32 *)0x10400408 = 0x000001c1;
|
||||
*(vu32 *)0x1040040c = 0x000001c1;
|
||||
*(vu32 *)0x10400410 = 0x00000000;
|
||||
*(vu32 *)0x10400414 = 0x000000cf;
|
||||
*(vu32 *)0x10400418 = 0x000000d1;
|
||||
*(vu32 *)0x1040041c = 0x01c501c1;
|
||||
*(vu32 *)0x10400420 = 0x00010000;
|
||||
*(vu32 *)0x10400424 = 0x0000019d;
|
||||
*(vu32 *)0x10400428 = 0x00000002;
|
||||
*(vu32 *)0x1040042c = 0x00000192;
|
||||
*(vu32 *)0x10400430 = 0x00000192;
|
||||
*(vu32 *)0x10400434 = 0x00000192;
|
||||
*(vu32 *)0x10400438 = 0x00000001;
|
||||
*(vu32 *)0x1040043c = 0x00000002;
|
||||
*(vu32 *)0x10400440 = 0x01960192;
|
||||
*(vu32 *)0x10400444 = 0x00000000;
|
||||
*(vu32 *)0x10400448 = 0x00000000;
|
||||
*(vu32 *)0x1040045C = 0x00f00190;
|
||||
*(vu32 *)0x10400460 = 0x01c100d1;
|
||||
*(vu32 *)0x10400464 = 0x01920002;
|
||||
*(vu32 *)0x10400468 = (u32)fbs[0].top_left;
|
||||
*(vu32 *)0x1040046C = (u32)fbs[1].top_left;
|
||||
*(vu32 *)0x10400470 = 0x80341;
|
||||
*(vu32 *)0x10400474 = 0x00010501;
|
||||
*(vu32 *)0x10400478 = 0;
|
||||
*(vu32 *)0x10400494 = (u32)fbs[0].top_right;
|
||||
*(vu32 *)0x10400498 = (u32)fbs[1].top_right;
|
||||
*(vu32 *)0x10400490 = 0x000002D0;
|
||||
*(vu32 *)0x1040049C = 0x00000000;
|
||||
|
||||
//Disco register
|
||||
for(u32 i = 0; i < 256; i++)
|
||||
*(vu32 *)0x10400484 = 0x10101 * i;
|
||||
|
||||
//Bottom screen
|
||||
*(vu32 *)0x10400500 = 0x000001c2;
|
||||
*(vu32 *)0x10400504 = 0x000000d1;
|
||||
*(vu32 *)0x10400508 = 0x000001c1;
|
||||
*(vu32 *)0x1040050c = 0x000001c1;
|
||||
*(vu32 *)0x10400510 = 0x000000cd;
|
||||
*(vu32 *)0x10400514 = 0x000000cf;
|
||||
*(vu32 *)0x10400518 = 0x000000d1;
|
||||
*(vu32 *)0x1040051c = 0x01c501c1;
|
||||
*(vu32 *)0x10400520 = 0x00010000;
|
||||
*(vu32 *)0x10400524 = 0x0000019d;
|
||||
*(vu32 *)0x10400528 = 0x00000052;
|
||||
*(vu32 *)0x1040052c = 0x00000192;
|
||||
*(vu32 *)0x10400530 = 0x00000192;
|
||||
*(vu32 *)0x10400534 = 0x0000004f;
|
||||
*(vu32 *)0x10400538 = 0x00000050;
|
||||
*(vu32 *)0x1040053c = 0x00000052;
|
||||
*(vu32 *)0x10400540 = 0x01980194;
|
||||
*(vu32 *)0x10400544 = 0x00000000;
|
||||
*(vu32 *)0x10400548 = 0x00000011;
|
||||
*(vu32 *)0x1040055C = 0x00f00140;
|
||||
*(vu32 *)0x10400560 = 0x01c100d1;
|
||||
*(vu32 *)0x10400564 = 0x01920052;
|
||||
*(vu32 *)0x10400568 = (u32)fbs[0].bottom;
|
||||
*(vu32 *)0x1040056C = (u32)fbs[1].bottom;
|
||||
*(vu32 *)0x10400570 = 0x80301;
|
||||
*(vu32 *)0x10400574 = 0x00010501;
|
||||
*(vu32 *)0x10400578 = 0;
|
||||
*(vu32 *)0x10400590 = 0x000002D0;
|
||||
*(vu32 *)0x1040059C = 0x00000000;
|
||||
|
||||
//Disco register
|
||||
for(u32 i = 0; i < 256; i++)
|
||||
*(vu32 *)0x10400584 = 0x10101 * i;
|
||||
}
|
||||
|
||||
static void setupFramebuffers(struct fb *fbs)
|
||||
{
|
||||
*(vu32 *)0x10400468 = (u32)fbs[0].top_left;
|
||||
*(vu32 *)0x1040046c = (u32)fbs[1].top_left;
|
||||
*(vu32 *)0x10400494 = (u32)fbs[0].top_right;
|
||||
*(vu32 *)0x10400498 = (u32)fbs[1].top_right;
|
||||
*(vu32 *)0x10400568 = (u32)fbs[0].bottom;
|
||||
*(vu32 *)0x1040056c = (u32)fbs[1].bottom;
|
||||
}
|
||||
|
||||
static void clearScreens(struct fb *fb)
|
||||
{
|
||||
//Setting up two simultaneous memory fills using the GPU
|
||||
|
||||
vu32 *REGs_PSC0 = (vu32 *)0x10400010,
|
||||
*REGs_PSC1 = (vu32 *)0x10400020;
|
||||
|
||||
REGs_PSC0[0] = (u32)fb->top_left >> 3; //Start address
|
||||
REGs_PSC0[1] = (u32)(fb->top_left + SCREEN_TOP_FBSIZE) >> 3; //End address
|
||||
REGs_PSC0[2] = 0; //Fill value
|
||||
REGs_PSC0[3] = (2 << 8) | 1; //32-bit pattern; start
|
||||
|
||||
REGs_PSC1[0] = (u32)fb->bottom >> 3; //Start address
|
||||
REGs_PSC1[1] = (u32)(fb->bottom + SCREEN_BOTTOM_FBSIZE) >> 3; //End address
|
||||
REGs_PSC1[2] = 0; //Fill value
|
||||
REGs_PSC1[3] = (2 << 8) | 1; //32-bit pattern; start
|
||||
|
||||
while(!((REGs_PSC0[3] & 2) && (REGs_PSC1[3] & 2)));
|
||||
}
|
||||
|
||||
static void swapFramebuffers(bool isAlternate)
|
||||
{
|
||||
u32 isAlternateTmp = isAlternate ? 1 : 0;
|
||||
*(vu32 *)0x10400478 = (*(vu32 *)0x10400478 & 0xFFFFFFFE) | isAlternateTmp;
|
||||
*(vu32 *)0x10400578 = (*(vu32 *)0x10400478 & 0xFFFFFFFE) | isAlternateTmp;
|
||||
}
|
||||
|
||||
static void updateBrightness(u32 brightnessLevel)
|
||||
{
|
||||
//Change brightness
|
||||
*(vu32 *)0x10202240 = brightnessLevel;
|
||||
*(vu32 *)0x10202A40 = brightnessLevel;
|
||||
}
|
||||
|
||||
static void deinitScreens(void)
|
||||
{
|
||||
//Shutdown LCDs
|
||||
*(vu32 *)0x10202A44 = 0;
|
||||
*(vu32 *)0x10202244 = 0;
|
||||
*(vu32 *)0x10202014 = 0;
|
||||
}
|
||||
|
||||
void main(void)
|
||||
{
|
||||
operation = ARM11_READY;
|
||||
|
||||
while(true)
|
||||
{
|
||||
switch(operation)
|
||||
{
|
||||
case ARM11_READY:
|
||||
continue;
|
||||
case INIT_SCREENS:
|
||||
initScreens(*(vu32 *)ARM11_PARAMETERS_ADDRESS, (struct fb *)(ARM11_PARAMETERS_ADDRESS + 4));
|
||||
break;
|
||||
case SETUP_FRAMEBUFFERS:
|
||||
setupFramebuffers((struct fb *)ARM11_PARAMETERS_ADDRESS);
|
||||
break;
|
||||
case CLEAR_SCREENS:
|
||||
clearScreens((struct fb *)ARM11_PARAMETERS_ADDRESS);
|
||||
break;
|
||||
case SWAP_FRAMEBUFFERS:
|
||||
swapFramebuffers(*(volatile bool *)ARM11_PARAMETERS_ADDRESS);
|
||||
break;
|
||||
case UPDATE_BRIGHTNESS:
|
||||
updateBrightness(*(vu32 *)ARM11_PARAMETERS_ADDRESS);
|
||||
break;
|
||||
case DEINIT_SCREENS:
|
||||
deinitScreens();
|
||||
break;
|
||||
case PREPARE_ARM11_FOR_FIRMLAUNCH:
|
||||
memcpy((void *)0x1FFFFC00, (void *)prepareForFirmlaunch, prepareForFirmlaunchSize);
|
||||
*(vu32 *)0x1FFFFFFC = 0;
|
||||
((void (*)(u32, volatile Arm11Operation *))0x1FFFFC00)(ARM11_READY, &operation);
|
||||
}
|
||||
|
||||
operation = ARM11_READY;
|
||||
}
|
||||
}
|
||||
56
arm11/source/memory.c
Normal file
56
arm11/source/memory.c
Normal file
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* This file is part of Luma3DS
|
||||
* Copyright (C) 2016-2017 Aurora Wright, TuxSH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
|
||||
* * Requiring preservation of specified reasonable legal notices or
|
||||
* author attributions in that material or in the Appropriate Legal
|
||||
* Notices displayed by works containing it.
|
||||
* * Prohibiting misrepresentation of the origin of that material,
|
||||
* or requiring that modified versions of such material be marked in
|
||||
* reasonable ways as different from the original version.
|
||||
*/
|
||||
|
||||
/*
|
||||
* memcpy adapted from https://github.com/mid-kid/CakesForeveryWan/blob/557a8e8605ab3ee173af6497486e8f22c261d0e2/source/memfuncs.c
|
||||
*/
|
||||
|
||||
#include "memory.h"
|
||||
|
||||
void memcpy(void *dest, const void *src, u32 size)
|
||||
{
|
||||
u8 *destc = (u8 *)dest;
|
||||
const u8 *srcc = (const u8 *)src;
|
||||
|
||||
for(u32 i = 0; i < size; i++)
|
||||
destc[i] = srcc[i];
|
||||
}
|
||||
|
||||
void memset(void *dest, u32 filler, u32 size)
|
||||
{
|
||||
u8 *destc = (u8 *)dest;
|
||||
|
||||
for(u32 i = 0; i < size; i++)
|
||||
destc[i] = (u8)filler;
|
||||
}
|
||||
|
||||
void memset32(void *dest, u32 filler, u32 size)
|
||||
{
|
||||
u32 *dest32 = (u32 *)dest;
|
||||
|
||||
for(u32 i = 0; i < size / 4; i++)
|
||||
dest32[i] = filler;
|
||||
}
|
||||
37
arm11/source/memory.h
Normal file
37
arm11/source/memory.h
Normal file
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* This file is part of Luma3DS
|
||||
* Copyright (C) 2016-2017 Aurora Wright, TuxSH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
|
||||
* * Requiring preservation of specified reasonable legal notices or
|
||||
* author attributions in that material or in the Appropriate Legal
|
||||
* Notices displayed by works containing it.
|
||||
* * Prohibiting misrepresentation of the origin of that material,
|
||||
* or requiring that modified versions of such material be marked in
|
||||
* reasonable ways as different from the original version.
|
||||
*/
|
||||
|
||||
/*
|
||||
* memcpy adapted from https://github.com/mid-kid/CakesForeveryWan/blob/557a8e8605ab3ee173af6497486e8f22c261d0e2/source/memfuncs.c
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "types.h"
|
||||
|
||||
void memcpy(void *dest, const void *src, u32 size);
|
||||
void memset(void *dest, u32 value, u32 size) __attribute__((used));
|
||||
void memset32(void *dest, u32 filler, u32 size);
|
||||
81
arm11/source/start.s
Normal file
81
arm11/source/start.s
Normal file
@@ -0,0 +1,81 @@
|
||||
@ This file is part of Luma3DS
|
||||
@ Copyright (C) 2016-2017 Aurora Wright, TuxSH
|
||||
@
|
||||
@ This program is free software: you can redistribute it and/or modify
|
||||
@ it under the terms of the GNU General Public License as published by
|
||||
@ the Free Software Foundation, either version 3 of the License, or
|
||||
@ (at your option) any later version.
|
||||
@
|
||||
@ This program is distributed in the hope that it will be useful,
|
||||
@ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
@ GNU General Public License for more details.
|
||||
@
|
||||
@ You should have received a copy of the GNU General Public License
|
||||
@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
@
|
||||
@ Additional Terms 7.b and 7.c of GPLv3 apply to this file:
|
||||
@ * Requiring preservation of specified reasonable legal notices or
|
||||
@ author attributions in that material or in the Appropriate Legal
|
||||
@ Notices displayed by works containing it.
|
||||
@ * Prohibiting misrepresentation of the origin of that material,
|
||||
@ or requiring that modified versions of such material be marked in
|
||||
@ reasonable ways as different from the original version.
|
||||
|
||||
.section .text.start
|
||||
.align 4
|
||||
.global _start
|
||||
.type _start, %function
|
||||
_start:
|
||||
b start
|
||||
|
||||
.global operation
|
||||
operation:
|
||||
.word 0
|
||||
|
||||
start:
|
||||
@ Disable interrupts and switch to supervisor mode
|
||||
cpsid aif, #0x13
|
||||
|
||||
@ Set the control register to reset default: everything disabled
|
||||
ldr r0, =0x54078
|
||||
mcr p15, 0, r0, c1, c0, 0
|
||||
|
||||
@ Set the auxiliary control register to reset default.
|
||||
@ Enables instruction folding, static branch prediction,
|
||||
@ dynamic branch prediction, and return stack.
|
||||
mov r0, #0xF
|
||||
mcr p15, 0, r0, c1, c0, 1
|
||||
|
||||
@ Invalidate both caches, flush the prefetch buffer then DSB
|
||||
mov r0, #0
|
||||
mcr p15, 0, r0, c7, c5, 4
|
||||
mcr p15, 0, r0, c7, c7, 0
|
||||
mcr p15, 0, r0, c7, c10, 4
|
||||
|
||||
@ Clear BSS
|
||||
ldr r0, =__bss_start
|
||||
mov r1, #0
|
||||
ldr r2, =__bss_end
|
||||
sub r2, r0
|
||||
bl memset32
|
||||
|
||||
ldr sp, =__stack_top__
|
||||
b main
|
||||
|
||||
.global prepareForFirmlaunch
|
||||
.type prepareForFirmlaunch, %function
|
||||
prepareForFirmlaunch:
|
||||
str r0, [r1] @ tell ARM9 we're done
|
||||
mov r0, #0x20000000
|
||||
|
||||
_wait_for_core0_entrypoint_loop:
|
||||
ldr r1, [r0, #-4] @ check if core0's entrypoint is 0
|
||||
cmp r1, #0
|
||||
beq _wait_for_core0_entrypoint_loop
|
||||
|
||||
bx r1 @ jump to core0's entrypoint
|
||||
prepareForFirmlaunchEnd:
|
||||
|
||||
.global prepareForFirmlaunchSize
|
||||
prepareForFirmlaunchSize: .word prepareForFirmlaunchEnd - prepareForFirmlaunch
|
||||
65
arm11/source/types.h
Normal file
65
arm11/source/types.h
Normal file
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* This file is part of Luma3DS
|
||||
* Copyright (C) 2016-2017 Aurora Wright, TuxSH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
|
||||
* * Requiring preservation of specified reasonable legal notices or
|
||||
* author attributions in that material or in the Appropriate Legal
|
||||
* Notices displayed by works containing it.
|
||||
* * Prohibiting misrepresentation of the origin of that material,
|
||||
* or requiring that modified versions of such material be marked in
|
||||
* reasonable ways as different from the original version.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
//Common data types
|
||||
typedef uint8_t u8;
|
||||
typedef uint16_t u16;
|
||||
typedef uint32_t u32;
|
||||
typedef uint64_t u64;
|
||||
typedef volatile u8 vu8;
|
||||
typedef volatile u16 vu16;
|
||||
typedef volatile u32 vu32;
|
||||
typedef volatile u64 vu64;
|
||||
|
||||
#define SCREEN_TOP_WIDTH 400
|
||||
#define SCREEN_BOTTOM_WIDTH 320
|
||||
#define SCREEN_HEIGHT 240
|
||||
#define SCREEN_TOP_FBSIZE (3 * SCREEN_TOP_WIDTH * SCREEN_HEIGHT)
|
||||
#define SCREEN_BOTTOM_FBSIZE (3 * SCREEN_BOTTOM_WIDTH * SCREEN_HEIGHT)
|
||||
#define ARM11_PARAMETERS_ADDRESS 0x1FFFF000
|
||||
|
||||
struct fb {
|
||||
u8 *top_left;
|
||||
u8 *top_right;
|
||||
u8 *bottom;
|
||||
};
|
||||
|
||||
typedef enum
|
||||
{
|
||||
INIT_SCREENS = 0,
|
||||
SETUP_FRAMEBUFFERS,
|
||||
CLEAR_SCREENS,
|
||||
SWAP_FRAMEBUFFERS,
|
||||
UPDATE_BRIGHTNESS,
|
||||
DEINIT_SCREENS,
|
||||
PREPARE_ARM11_FOR_FIRMLAUNCH,
|
||||
ARM11_READY,
|
||||
} Arm11Operation;
|
||||
@@ -4,35 +4,31 @@ ifeq ($(strip $(DEVKITARM)),)
|
||||
$(error "Please set DEVKITARM in your environment. export DEVKITARM=<path to>devkitARM")
|
||||
endif
|
||||
|
||||
include $(DEVKITARM)/3ds_rules
|
||||
|
||||
CC := arm-none-eabi-gcc
|
||||
AS := arm-none-eabi-as
|
||||
LD := arm-none-eabi-ld
|
||||
OC := arm-none-eabi-objcopy
|
||||
include $(DEVKITARM)/base_tools
|
||||
|
||||
name := $(shell basename $(CURDIR))
|
||||
|
||||
dir_source := source
|
||||
dir_build := build
|
||||
dir_out := ../$(dir_build)
|
||||
|
||||
ASFLAGS := -mcpu=arm946e-s
|
||||
CFLAGS := -Wall -Wextra -MMD -MP -mthumb -mthumb-interwork $(ASFLAGS) -fno-builtin -std=c11 -Wno-main -O2 -flto -ffast-math
|
||||
LDFLAGS := -nostdlib
|
||||
CFLAGS := -Wall -Wextra -marm $(ASFLAGS) -fno-builtin -std=c11 -Wno-main -O2 -flto -ffast-math
|
||||
LDFLAGS := -nostartfiles -Wl,--nmagic
|
||||
|
||||
objects = $(patsubst $(dir_source)/%.s, $(dir_build)/%.o, \
|
||||
$(patsubst $(dir_source)/%.c, $(dir_build)/%.o, \
|
||||
$(call rwildcard, $(dir_source), *.s *.c)))
|
||||
|
||||
.PHONY: all
|
||||
all: ../$(dir_build)/$(name).bin
|
||||
all: $(dir_out)/$(name).bin
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
@rm -rf $(dir_build)
|
||||
|
||||
../$(dir_build)/$(name).bin: $(dir_build)/$(name).elf
|
||||
$(OC) -S -O binary $< $@
|
||||
$(dir_out)/$(name).bin: $(dir_build)/$(name).elf
|
||||
$(OBJCOPY) -S -O binary $< $@
|
||||
|
||||
$(dir_build)/$(name).elf: $(objects)
|
||||
$(LINK.o) -T linker.ld $(OUTPUT_OPTION) $^
|
||||
@@ -46,4 +42,3 @@ $(dir_build)/%.o: $(dir_source)/%.c
|
||||
$(dir_build)/%.o: $(dir_source)/%.s
|
||||
@mkdir -p "$(@D)"
|
||||
$(COMPILE.s) $(OUTPUT_OPTION) $<
|
||||
include $(call rwildcard, $(dir_build), *.d)
|
||||
21
chainloader/linker.ld
Normal file
21
chainloader/linker.ld
Normal file
@@ -0,0 +1,21 @@
|
||||
OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")
|
||||
OUTPUT_ARCH(arm)
|
||||
|
||||
ENTRY(_start)
|
||||
SECTIONS
|
||||
{
|
||||
. = 0x01FF9000;
|
||||
|
||||
__start__ = ABSOLUTE(.);
|
||||
|
||||
.text : ALIGN(4) { *(.text.start) *(.text*); . = ALIGN(4); }
|
||||
.rodata : ALIGN(4) { *(.rodata*); . = ALIGN(4); }
|
||||
.data : ALIGN(4) { *(.data*); . = ALIGN(8); *(.bss* COMMON); . = ALIGN(8); }
|
||||
|
||||
. = ALIGN(4);
|
||||
|
||||
__end__ = ABSOLUTE(.);
|
||||
|
||||
__stack_top__ = 0x01FFB800;
|
||||
__stack_bottom__ = 0x01FFA800;
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Luma3DS
|
||||
* Copyright (C) 2016 Aurora Wright, TuxSH
|
||||
* Copyright (C) 2016-2017 Aurora Wright, TuxSH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -15,13 +15,17 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Additional Terms 7.b of GPLv3 applies to this file: Requiring preservation of specified
|
||||
* reasonable legal notices or author attributions in that material or in the Appropriate Legal
|
||||
* Notices displayed by works containing it.
|
||||
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
|
||||
* * Requiring preservation of specified reasonable legal notices or
|
||||
* author attributions in that material or in the Appropriate Legal
|
||||
* Notices displayed by works containing it.
|
||||
* * Prohibiting misrepresentation of the origin of that material,
|
||||
* or requiring that modified versions of such material be marked in
|
||||
* reasonable ways as different from the original version.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "types.h"
|
||||
|
||||
void flushCaches(void);
|
||||
void flushCaches(void);
|
||||
@@ -1,5 +1,5 @@
|
||||
@ This file is part of Luma3DS
|
||||
@ Copyright (C) 2016 Aurora Wright, TuxSH
|
||||
@ Copyright (C) 2016-2017 Aurora Wright, TuxSH
|
||||
@
|
||||
@ This program is free software: you can redistribute it and/or modify
|
||||
@ it under the terms of the GNU General Public License as published by
|
||||
@@ -14,20 +14,28 @@
|
||||
@ You should have received a copy of the GNU General Public License
|
||||
@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
@
|
||||
@ Additional Terms 7.b of GPLv3 applies to this file: Requiring preservation of specified
|
||||
@ reasonable legal notices or author attributions in that material or in the Appropriate Legal
|
||||
@ Notices displayed by works containing it.
|
||||
@ Additional Terms 7.b and 7.c of GPLv3 apply to this file:
|
||||
@ * Requiring preservation of specified reasonable legal notices or
|
||||
@ author attributions in that material or in the Appropriate Legal
|
||||
@ Notices displayed by works containing it.
|
||||
@ * Prohibiting misrepresentation of the origin of that material,
|
||||
@ or requiring that modified versions of such material be marked in
|
||||
@ reasonable ways as different from the original version.
|
||||
|
||||
.text
|
||||
.arm
|
||||
.global flushCaches
|
||||
.type flushCaches STT_FUNC
|
||||
.align 4
|
||||
|
||||
.global flushCaches
|
||||
.type flushCaches, %function
|
||||
flushCaches:
|
||||
@ Clean and flush data cache
|
||||
@ Clean and flush both the data cache and instruction caches
|
||||
|
||||
@ Adpated from http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0155a/ch03s03s05.html ,
|
||||
@ and https://github.com/gemarcano/libctr9_io/blob/master/src/ctr_system_ARM.c#L39 as well
|
||||
@ Note: ARM's example is actually for a 8KB DCache (which is what the 3DS has)
|
||||
@ Implemented in bootROM at address 0xffff0830
|
||||
|
||||
@ Implemented in bootROM at addresses 0xffff0830 (DCache) and 0xffff0ab4 (ICache)
|
||||
|
||||
mov r1, #0 @ segment counter
|
||||
outer_loop:
|
||||
42
chainloader/source/firm.c
Normal file
42
chainloader/source/firm.c
Normal file
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* This file is part of Luma3DS
|
||||
* Copyright (C) 2016-2017 Aurora Wright, TuxSH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
|
||||
* * Requiring preservation of specified reasonable legal notices or
|
||||
* author attributions in that material or in the Appropriate Legal
|
||||
* Notices displayed by works containing it.
|
||||
* * Prohibiting misrepresentation of the origin of that material,
|
||||
* or requiring that modified versions of such material be marked in
|
||||
* reasonable ways as different from the original version.
|
||||
*/
|
||||
|
||||
#include "firm.h"
|
||||
#include "memory.h"
|
||||
#include "cache.h"
|
||||
|
||||
void disableMpuAndJumpToEntrypoints(int argc, char **argv, void *arm11Entry, void *arm9Entry);
|
||||
|
||||
void launchFirm(Firm *firm, int argc, char **argv)
|
||||
{
|
||||
//Copy FIRM sections to respective memory locations
|
||||
for(u32 sectionNum = 0; sectionNum < 4; sectionNum++)
|
||||
memcpy(firm->section[sectionNum].address, (u8 *)firm + firm->section[sectionNum].offset, firm->section[sectionNum].size);
|
||||
|
||||
disableMpuAndJumpToEntrypoints(argc, argv, firm->arm9Entry, firm->arm11Entry);
|
||||
|
||||
__builtin_unreachable();
|
||||
}
|
||||
50
chainloader/source/firm.h
Normal file
50
chainloader/source/firm.h
Normal file
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* This file is part of Luma3DS
|
||||
* Copyright (C) 2016-2017 Aurora Wright, TuxSH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
|
||||
* * Requiring preservation of specified reasonable legal notices or
|
||||
* author attributions in that material or in the Appropriate Legal
|
||||
* Notices displayed by works containing it.
|
||||
* * Prohibiting misrepresentation of the origin of that material,
|
||||
* or requiring that modified versions of such material be marked in
|
||||
* reasonable ways as different from the original version.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "types.h"
|
||||
|
||||
typedef struct __attribute__((packed))
|
||||
{
|
||||
u32 offset;
|
||||
u8 *address;
|
||||
u32 size;
|
||||
u32 procType;
|
||||
u8 hash[0x20];
|
||||
} FirmSection;
|
||||
|
||||
typedef struct __attribute__((packed))
|
||||
{
|
||||
char magic[4];
|
||||
u32 reserved1;
|
||||
u8 *arm11Entry;
|
||||
u8 *arm9Entry;
|
||||
u8 reserved2[0x30];
|
||||
FirmSection section[4];
|
||||
} Firm;
|
||||
|
||||
void launchFirm(Firm *firm, int argc, char **argv);
|
||||
58
chainloader/source/main.c
Normal file
58
chainloader/source/main.c
Normal file
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* This file is part of Luma3DS
|
||||
* Copyright (C) 2016-2017 Aurora Wright, TuxSH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
|
||||
* * Requiring preservation of specified reasonable legal notices or
|
||||
* author attributions in that material or in the Appropriate Legal
|
||||
* Notices displayed by works containing it.
|
||||
* * Prohibiting misrepresentation of the origin of that material,
|
||||
* or requiring that modified versions of such material be marked in
|
||||
* reasonable ways as different from the original version.
|
||||
*/
|
||||
|
||||
#include "memory.h"
|
||||
#include "cache.h"
|
||||
#include "firm.h"
|
||||
|
||||
void main(int argc, char **argv, Firm *firm)
|
||||
{
|
||||
char *argvPassed[2],
|
||||
absPath[24 + 255];
|
||||
struct fb fbs[2];
|
||||
|
||||
if(argc > 0)
|
||||
{
|
||||
u32 i;
|
||||
for(i = 0; i < sizeof(absPath) - 1 && argv[0][i] != 0; i++)
|
||||
absPath[i] = argv[0][i];
|
||||
absPath[i] = 0;
|
||||
|
||||
argvPassed[0] = (char *)absPath;
|
||||
}
|
||||
|
||||
if(argc == 2)
|
||||
{
|
||||
struct fb *fbsrc = (struct fb *)argv[1];
|
||||
|
||||
fbs[0] = fbsrc[0];
|
||||
fbs[1] = fbsrc[1];
|
||||
|
||||
argvPassed[1] = (char *)&fbs;
|
||||
}
|
||||
|
||||
launchFirm(firm, argc, argvPassed);
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Luma3DS
|
||||
* Copyright (C) 2016 Aurora Wright, TuxSH
|
||||
* Copyright (C) 2016-2017 Aurora Wright, TuxSH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -15,12 +15,15 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Additional Terms 7.b of GPLv3 applies to this file: Requiring preservation of specified
|
||||
* reasonable legal notices or author attributions in that material or in the Appropriate Legal
|
||||
* Notices displayed by works containing it.
|
||||
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
|
||||
* * Requiring preservation of specified reasonable legal notices or
|
||||
* author attributions in that material or in the Appropriate Legal
|
||||
* Notices displayed by works containing it.
|
||||
* * Prohibiting misrepresentation of the origin of that material,
|
||||
* or requiring that modified versions of such material be marked in
|
||||
* reasonable ways as different from the original version.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* memcpy adapted from https://github.com/mid-kid/CakesForeveryWan/blob/557a8e8605ab3ee173af6497486e8f22c261d0e2/source/memfuncs.c
|
||||
*/
|
||||
@@ -34,4 +37,4 @@ void memcpy(void *dest, const void *src, u32 size)
|
||||
|
||||
for(u32 i = 0; i < size; i++)
|
||||
destc[i] = srcc[i];
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Luma3DS
|
||||
* Copyright (C) 2016 Aurora Wright, TuxSH
|
||||
* Copyright (C) 2016-2017 Aurora Wright, TuxSH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -15,12 +15,15 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Additional Terms 7.b of GPLv3 applies to this file: Requiring preservation of specified
|
||||
* reasonable legal notices or author attributions in that material or in the Appropriate Legal
|
||||
* Notices displayed by works containing it.
|
||||
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
|
||||
* * Requiring preservation of specified reasonable legal notices or
|
||||
* author attributions in that material or in the Appropriate Legal
|
||||
* Notices displayed by works containing it.
|
||||
* * Prohibiting misrepresentation of the origin of that material,
|
||||
* or requiring that modified versions of such material be marked in
|
||||
* reasonable ways as different from the original version.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* memcpy adapted from https://github.com/mid-kid/CakesForeveryWan/blob/557a8e8605ab3ee173af6497486e8f22c261d0e2/source/memfuncs.c
|
||||
*/
|
||||
@@ -29,4 +32,4 @@
|
||||
|
||||
#include "types.h"
|
||||
|
||||
void memcpy(void *dest, const void *src, u32 size);
|
||||
void memcpy(void *dest, const void *src, u32 size);
|
||||
60
chainloader/source/start.s
Normal file
60
chainloader/source/start.s
Normal file
@@ -0,0 +1,60 @@
|
||||
@ This file is part of Luma3DS
|
||||
@ Copyright (C) 2016-2017 Aurora Wright, TuxSH
|
||||
@
|
||||
@ This program is free software: you can redistribute it and/or modify
|
||||
@ it under the terms of the GNU General Public License as published by
|
||||
@ the Free Software Foundation, either version 3 of the License, or
|
||||
@ (at your option) any later version.
|
||||
@
|
||||
@ This program is distributed in the hope that it will be useful,
|
||||
@ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
@ GNU General Public License for more details.
|
||||
@
|
||||
@ You should have received a copy of the GNU General Public License
|
||||
@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
@
|
||||
@ Additional Terms 7.b and 7.c of GPLv3 apply to this file:
|
||||
@ * Requiring preservation of specified reasonable legal notices or
|
||||
@ author attributions in that material or in the Appropriate Legal
|
||||
@ Notices displayed by works containing it.
|
||||
@ * Prohibiting misrepresentation of the origin of that material,
|
||||
@ or requiring that modified versions of such material be marked in
|
||||
@ reasonable ways as different from the original version.
|
||||
.arm
|
||||
|
||||
.section .text.start
|
||||
.align 4
|
||||
.global _start
|
||||
_start:
|
||||
ldr sp, =__stack_top__
|
||||
b main
|
||||
|
||||
.text
|
||||
.balign 4
|
||||
.global disableMpuAndJumpToEntrypoints
|
||||
.type disableMpuAndJumpToEntrypoints, %function
|
||||
disableMpuAndJumpToEntrypoints:
|
||||
mov r4, r0
|
||||
mov r5, r1
|
||||
mov r6, r2
|
||||
mov r7, r3
|
||||
|
||||
bl flushCaches
|
||||
|
||||
@ Disable caches / MPU
|
||||
mrc p15, 0, r0, c1, c0, 0 @ read control register
|
||||
bic r0, #(1<<12) @ - instruction cache disable
|
||||
bic r0, #(1<<2) @ - data cache disable
|
||||
bic r0, #(1<<0) @ - MPU disable
|
||||
mcr p15, 0, r0, c1, c0, 0 @ write control register
|
||||
|
||||
@ Set the ARM11 entrypoint
|
||||
mov r0, #0x20000000
|
||||
str r7, [r0, #-4]
|
||||
|
||||
@ Jump to the ARM9 entrypoint
|
||||
mov r0, r4
|
||||
mov r1, r5
|
||||
ldr r2, =0x3BEEF
|
||||
bx r6
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Luma3DS
|
||||
* Copyright (C) 2016 Aurora Wright, TuxSH
|
||||
* Copyright (C) 2016-2017 Aurora Wright, TuxSH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -15,16 +15,18 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Additional Terms 7.b of GPLv3 applies to this file: Requiring preservation of specified
|
||||
* reasonable legal notices or author attributions in that material or in the Appropriate Legal
|
||||
* Notices displayed by works containing it.
|
||||
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
|
||||
* * Requiring preservation of specified reasonable legal notices or
|
||||
* author attributions in that material or in the Appropriate Legal
|
||||
* Notices displayed by works containing it.
|
||||
* * Prohibiting misrepresentation of the origin of that material,
|
||||
* or requiring that modified versions of such material be marked in
|
||||
* reasonable ways as different from the original version.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
//Common data types
|
||||
typedef uint8_t u8;
|
||||
@@ -34,4 +36,10 @@ typedef uint64_t u64;
|
||||
typedef volatile u8 vu8;
|
||||
typedef volatile u16 vu16;
|
||||
typedef volatile u32 vu32;
|
||||
typedef volatile u64 vu64;
|
||||
typedef volatile u64 vu64;
|
||||
|
||||
struct fb {
|
||||
u8 *top_left;
|
||||
u8 *top_right;
|
||||
u8 *bottom;
|
||||
};
|
||||
@@ -1,11 +0,0 @@
|
||||
ENTRY(_start)
|
||||
SECTIONS
|
||||
{
|
||||
. = 0;
|
||||
.text.start : { *(.text.start) }
|
||||
.text : { *(.text) }
|
||||
.data : { *(.data) }
|
||||
.bss : { *(.bss COMMON) }
|
||||
.rodata : { *(.rodata) }
|
||||
. = ALIGN(4);
|
||||
}
|
||||
@@ -1,150 +0,0 @@
|
||||
@ This file is part of Luma3DS
|
||||
@ Copyright (C) 2016 Aurora Wright, TuxSH
|
||||
@
|
||||
@ This program is free software: you can redistribute it and/or modify
|
||||
@ it under the terms of the GNU General Public License as published by
|
||||
@ the Free Software Foundation, either version 3 of the License, or
|
||||
@ (at your option) any later version.
|
||||
@
|
||||
@ This program is distributed in the hope that it will be useful,
|
||||
@ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
@ GNU General Public License for more details.
|
||||
@
|
||||
@ You should have received a copy of the GNU General Public License
|
||||
@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
@
|
||||
@ Additional Terms 7.b of GPLv3 applies to this file: Requiring preservation of specified
|
||||
@ reasonable legal notices or author attributions in that material or in the Appropriate Legal
|
||||
@ Notices displayed by works containing it.
|
||||
|
||||
.macro GEN_HANDLER name
|
||||
.global \name
|
||||
.type \name, %function
|
||||
\name:
|
||||
ldr sp, =#0xffff3000
|
||||
stmfd sp!, {r0-r7}
|
||||
mov r1, #\@ @ macro expansion counter
|
||||
b _commonHandler
|
||||
|
||||
.size \name, . - \name
|
||||
.endm
|
||||
|
||||
.text
|
||||
.arm
|
||||
.align 4
|
||||
|
||||
.global _commonHandler
|
||||
.type _commonHandler, %function
|
||||
_commonHandler:
|
||||
clrex
|
||||
cpsid aif
|
||||
mrs r2, spsr
|
||||
mov r6, sp
|
||||
mrs r3, cpsr
|
||||
|
||||
tst r2, #0x20
|
||||
bne noFPUInitNorSvcBreak
|
||||
sub r0, lr, #4
|
||||
stmfd sp!, {lr}
|
||||
bl cannotAccessVA
|
||||
ldmfd sp!, {lr}
|
||||
cmp r0, #0
|
||||
bne noFPUInitNorSvcBreak
|
||||
ldr r4, [lr, #-4]
|
||||
cmp r1, #1
|
||||
bne noFPUInit
|
||||
|
||||
lsl r4, #4
|
||||
sub r4, #0xc0000000
|
||||
cmp r4, #0x30000000
|
||||
bcs noFPUInitNorSvcBreak
|
||||
fmrx r0, fpexc
|
||||
tst r0, #0x40000000
|
||||
bne noFPUInitNorSvcBreak
|
||||
|
||||
sub lr, #4
|
||||
srsfd sp!, #0x13
|
||||
ldmfd sp!, {r0-r7} @ restore context
|
||||
cps #0x13 @ FPU init
|
||||
stmfd sp, {r0-r3, r11-lr}^
|
||||
sub sp, #0x20
|
||||
bl . @ will be replaced
|
||||
ldmfd sp, {r0-r3, r11-lr}^
|
||||
add sp, #0x20
|
||||
rfefd sp!
|
||||
|
||||
noFPUInit:
|
||||
cmp r1, #2
|
||||
bne noFPUInitNorSvcBreak
|
||||
ldr r5, =#0xe12fff7f
|
||||
cmp r4, r5
|
||||
bne noFPUInitNorSvcBreak
|
||||
cps #0x13 @ switch to supervisor mode
|
||||
cmp r10, #0
|
||||
addne sp, #0x28
|
||||
ldr r2, [sp, #0x1c] @ implementation details of the official svc handler
|
||||
ldr r4, [sp, #0x18]
|
||||
msr cpsr_c, r3 @ restore processor mode
|
||||
tst r2, #0x20
|
||||
addne lr, r4, #2 @ adjust address for later
|
||||
moveq lr, r4
|
||||
|
||||
noFPUInitNorSvcBreak:
|
||||
ands r4, r2, #0xf @ get the mode that triggered the exception
|
||||
moveq r4, #0xf @ usr => sys
|
||||
bic r5, r3, #0xf
|
||||
orr r5, r4
|
||||
msr cpsr_c, r5 @ change processor mode
|
||||
stmfd r6!, {r8-lr}
|
||||
msr cpsr_c, r3 @ restore processor mode
|
||||
mov sp, r6
|
||||
|
||||
stmfd sp!, {r2,lr}
|
||||
|
||||
mrc p15,0,r4,c5,c0,0 @ dfsr
|
||||
mrc p15,0,r5,c5,c0,1 @ ifsr
|
||||
mrc p15,0,r6,c6,c0,0 @ far
|
||||
fmrx r7, fpexc
|
||||
fmrx r8, fpinst
|
||||
fmrx r9, fpinst2
|
||||
|
||||
stmfd sp!, {r4-r9} @ it's a bit of a mess, but we will fix that later
|
||||
@ order of saved regs now: dfsr, ifsr, far, fpexc, fpinst, fpinst2, cpsr, pc + (2/4/8), r8-r14, r0-r7
|
||||
|
||||
bic r3, #(1<<31)
|
||||
fmxr fpexc, r3 @ clear the VFP11 exception flag (if it's set)
|
||||
|
||||
mov r0, sp
|
||||
mrc p15,0,r2,c0,c0,5 @ CPU ID register
|
||||
|
||||
b mainHandler
|
||||
|
||||
GEN_HANDLER FIQHandler
|
||||
GEN_HANDLER undefinedInstructionHandler
|
||||
GEN_HANDLER prefetchAbortHandler
|
||||
GEN_HANDLER dataAbortHandler
|
||||
|
||||
.global mcuReboot
|
||||
.type mcuReboot, %function
|
||||
mcuReboot:
|
||||
b . @ will be replaced
|
||||
|
||||
.global cleanInvalidateDCacheAndDMB
|
||||
.type cleanInvalidateDCacheAndDMB, %function
|
||||
cleanInvalidateDCacheAndDMB:
|
||||
mov r0, #0
|
||||
mcr p15,0,r0,c7,c14,0 @ Clean and Invalidate Entire Data Cache
|
||||
mcr p15,0,r0,c7,c10,4 @ Drain Memory Barrier
|
||||
bx lr
|
||||
|
||||
.global cannotAccessVA
|
||||
.type cannotAccessVA, %function
|
||||
cannotAccessVA:
|
||||
@ Thanks yellows8 for the hint
|
||||
lsr r0, #12
|
||||
lsl r0, #12
|
||||
mcr p15,0,r0,c7,c8,0 @ VA to PA translation with privileged read permission check
|
||||
mrc p15,0,r0,c7,c4,0 @ read PA register
|
||||
and r0, #1 @ failure bit
|
||||
bx lr
|
||||
@@ -1,110 +0,0 @@
|
||||
/*
|
||||
* This file is part of Luma3DS
|
||||
* Copyright (C) 2016 Aurora Wright, TuxSH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Additional Terms 7.b of GPLv3 applies to this file: Requiring preservation of specified
|
||||
* reasonable legal notices or author attributions in that material or in the Appropriate Legal
|
||||
* Notices displayed by works containing it.
|
||||
*/
|
||||
|
||||
#include "handlers.h"
|
||||
|
||||
#define FINAL_BUFFER 0xE5000000 //0x25000000
|
||||
|
||||
#define REG_DUMP_SIZE 4 * 23
|
||||
#define CODE_DUMP_SIZE 48
|
||||
|
||||
#define CODESET_OFFSET 0xBEEFBEEF
|
||||
|
||||
static u32 __attribute__((noinline)) copyMemory(void *dst, const void *src, u32 size, u32 alignment)
|
||||
{
|
||||
u8 *out = (u8 *)dst;
|
||||
const u8 *in = (const u8 *)src;
|
||||
|
||||
if(((u32)src & (alignment - 1)) != 0 || cannotAccessVA(src) || (size != 0 && cannotAccessVA((u8 *)src + size - 1)))
|
||||
return 0;
|
||||
|
||||
for(u32 i = 0; i < size; i++)
|
||||
*out++ = *in++;
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
void __attribute__((noreturn)) mainHandler(u32 *regs, u32 type, u32 cpuId)
|
||||
{
|
||||
ExceptionDumpHeader dumpHeader;
|
||||
|
||||
u32 registerDump[REG_DUMP_SIZE / 4];
|
||||
u8 codeDump[CODE_DUMP_SIZE];
|
||||
u8 *final = (u8 *)FINAL_BUFFER;
|
||||
|
||||
while(*(vu32 *)final == 0xDEADC0DE && *((vu32 *)final + 1) == 0xDEADCAFE);
|
||||
|
||||
dumpHeader.magic[0] = 0xDEADC0DE;
|
||||
dumpHeader.magic[1] = 0xDEADCAFE;
|
||||
dumpHeader.versionMajor = 1;
|
||||
dumpHeader.versionMinor = 2;
|
||||
|
||||
dumpHeader.processor = 11;
|
||||
dumpHeader.core = cpuId & 0xF;
|
||||
dumpHeader.type = type;
|
||||
|
||||
dumpHeader.registerDumpSize = REG_DUMP_SIZE;
|
||||
dumpHeader.codeDumpSize = CODE_DUMP_SIZE;
|
||||
|
||||
//Dump registers
|
||||
//Current order of saved regs: dfsr, ifsr, far, fpexc, fpinst, fpinst2, cpsr, pc, r8-r12, sp, lr, r0-r7
|
||||
u32 cpsr = regs[6];
|
||||
u32 pc = regs[7] - (type < 3 ? (((cpsr & 0x20) != 0 && type == 1) ? 2 : 4) : 8);
|
||||
|
||||
registerDump[15] = pc;
|
||||
registerDump[16] = cpsr;
|
||||
for(u32 i = 0; i < 6; i++) registerDump[17 + i] = regs[i];
|
||||
for(u32 i = 0; i < 7; i++) registerDump[8 + i] = regs[8 + i];
|
||||
for(u32 i = 0; i < 8; i++) registerDump[i] = regs[15 + i];
|
||||
|
||||
//Dump code
|
||||
u8 *instr = (u8 *)pc + ((cpsr & 0x20) ? 2 : 4) - dumpHeader.codeDumpSize; //Doesn't work well on 32-bit Thumb instructions, but it isn't much of a problem
|
||||
dumpHeader.codeDumpSize = copyMemory(codeDump, instr, dumpHeader.codeDumpSize, ((cpsr & 0x20) != 0) ? 2 : 4);
|
||||
|
||||
//Copy register dump and code dump
|
||||
final = (u8 *)(FINAL_BUFFER + sizeof(ExceptionDumpHeader));
|
||||
final += copyMemory(final, registerDump, dumpHeader.registerDumpSize, 1);
|
||||
final += copyMemory(final, codeDump, dumpHeader.codeDumpSize, 1);
|
||||
|
||||
//Dump stack in place
|
||||
dumpHeader.stackDumpSize = copyMemory(final, (const void *)registerDump[13], 0x1000 - (registerDump[13] & 0xFFF), 1);
|
||||
final += dumpHeader.stackDumpSize;
|
||||
|
||||
if(!cannotAccessVA((u8 *)0xFFFF9004))
|
||||
{
|
||||
vu64 *additionalData = (vu64 *)final;
|
||||
dumpHeader.additionalDataSize = 16;
|
||||
vu8 *currentKCodeSet = *(vu8 **)(*(vu8 **)0xFFFF9004 + CODESET_OFFSET); //currentKProcess + CodeSet
|
||||
|
||||
additionalData[0] = *(vu64 *)(currentKCodeSet + 0x50); //Process name
|
||||
additionalData[1] = *(vu64 *)(currentKCodeSet + 0x5C); //Title ID
|
||||
}
|
||||
else dumpHeader.additionalDataSize = 0;
|
||||
|
||||
dumpHeader.totalSize = sizeof(ExceptionDumpHeader) + dumpHeader.registerDumpSize + dumpHeader.codeDumpSize + dumpHeader.stackDumpSize + dumpHeader.additionalDataSize;
|
||||
|
||||
//Copy header (actually optimized by the compiler)
|
||||
*(ExceptionDumpHeader *)FINAL_BUFFER = dumpHeader;
|
||||
|
||||
cleanInvalidateDCacheAndDMB();
|
||||
mcuReboot(); //Also contains DCache-cleaning code
|
||||
}
|
||||
@@ -4,35 +4,31 @@ ifeq ($(strip $(DEVKITARM)),)
|
||||
$(error "Please set DEVKITARM in your environment. export DEVKITARM=<path to>devkitARM")
|
||||
endif
|
||||
|
||||
include $(DEVKITARM)/3ds_rules
|
||||
|
||||
CC := arm-none-eabi-gcc
|
||||
AS := arm-none-eabi-as
|
||||
LD := arm-none-eabi-ld
|
||||
OC := arm-none-eabi-objcopy
|
||||
include $(DEVKITARM)/base_tools
|
||||
|
||||
name := arm9_exceptions
|
||||
|
||||
dir_source := source
|
||||
dir_build := build
|
||||
dir_out := ../../$(dir_build)
|
||||
|
||||
ASFLAGS := -mcpu=arm946e-s
|
||||
CFLAGS := -Wall -Wextra -MMD -MP -mthumb -mthumb-interwork $(ASFLAGS) -fno-builtin -std=c11 -Wno-main -O2 -flto -ffast-math
|
||||
LDFLAGS := -nostdlib
|
||||
CFLAGS := -Wall -Wextra -marm $(ASFLAGS) -fno-builtin -std=c11 -Wno-main -Os -ffast-math
|
||||
LDFLAGS := -nostartfiles -Wl,--nmagic
|
||||
|
||||
objects = $(patsubst $(dir_source)/%.s, $(dir_build)/%.o, \
|
||||
$(patsubst $(dir_source)/%.c, $(dir_build)/%.o, \
|
||||
$(call rwildcard, $(dir_source), *.s *.c)))
|
||||
|
||||
.PHONY: all
|
||||
all: ../../$(dir_build)/$(name).bin
|
||||
all: $(dir_out)/$(name).bin
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
@rm -rf $(dir_build)
|
||||
|
||||
../../$(dir_build)/$(name).bin: $(dir_build)/$(name).elf
|
||||
$(OC) -S -O binary $< $@
|
||||
$(dir_out)/$(name).bin: $(dir_build)/$(name).elf
|
||||
$(OBJCOPY) -S -O binary $< $@
|
||||
|
||||
$(dir_build)/$(name).elf: $(objects)
|
||||
$(CC) $(LDFLAGS) -T linker.ld $(OUTPUT_OPTION) $^
|
||||
@@ -44,4 +40,3 @@ $(dir_build)/%.o: $(dir_source)/%.c
|
||||
$(dir_build)/%.o: $(dir_source)/%.s
|
||||
@mkdir -p "$(@D)"
|
||||
$(COMPILE.s) $(OUTPUT_OPTION) $<
|
||||
include $(call rwildcard, $(dir_build), *.d)
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")
|
||||
OUTPUT_ARCH(arm)
|
||||
|
||||
ENTRY(_start)
|
||||
SECTIONS
|
||||
{
|
||||
. = 0x01FF7FE0;
|
||||
.text.start : { *(.text.start) }
|
||||
.text : { *(.text) }
|
||||
.data : { *(.data) }
|
||||
.bss : { *(.bss COMMON) }
|
||||
.rodata : { *(.rodata) }
|
||||
. = 0x01FF8000;
|
||||
|
||||
.text : ALIGN(4) { *(.text.start) *(.text*); . = ALIGN(4); }
|
||||
.rodata : ALIGN(4) { *(.rodata*); . = ALIGN(4); }
|
||||
.data : ALIGN(4) { *(.data*); . = ALIGN(8); *(.bss* COMMON); . = ALIGN(8); }
|
||||
|
||||
. = ALIGN(4);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Luma3DS
|
||||
* Copyright (C) 2016 Aurora Wright, TuxSH
|
||||
* Copyright (C) 2016-2017 Aurora Wright, TuxSH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -15,9 +15,13 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Additional Terms 7.b of GPLv3 applies to this file: Requiring preservation of specified
|
||||
* reasonable legal notices or author attributions in that material or in the Appropriate Legal
|
||||
* Notices displayed by works containing it.
|
||||
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
|
||||
* * Requiring preservation of specified reasonable legal notices or
|
||||
* author attributions in that material or in the Appropriate Legal
|
||||
* Notices displayed by works containing it.
|
||||
* * Prohibiting misrepresentation of the origin of that material,
|
||||
* or requiring that modified versions of such material be marked in
|
||||
* reasonable ways as different from the original version.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
@@ -39,8 +43,9 @@ typedef struct __attribute__((packed))
|
||||
u32 additionalDataSize;
|
||||
} ExceptionDumpHeader;
|
||||
|
||||
u32 readMPUConfig(u32 *regionSettings);
|
||||
void FIQHandler(void);
|
||||
void undefinedInstructionHandler(void);
|
||||
void dataAbortHandler(void);
|
||||
void prefetchAbortHandler(void);
|
||||
void prefetchAbortHandler(void);
|
||||
|
||||
u32 safecpy(void *dst, const void *src, u32 len);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
@ This file is part of Luma3DS
|
||||
@ Copyright (C) 2016 Aurora Wright, TuxSH
|
||||
@ Copyright (C) 2016-2017 Aurora Wright, TuxSH
|
||||
@
|
||||
@ This program is free software: you can redistribute it and/or modify
|
||||
@ it under the terms of the GNU General Public License as published by
|
||||
@@ -14,95 +14,139 @@
|
||||
@ You should have received a copy of the GNU General Public License
|
||||
@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
@
|
||||
@ Additional Terms 7.b of GPLv3 applies to this file: Requiring preservation of specified
|
||||
@ reasonable legal notices or author attributions in that material or in the Appropriate Legal
|
||||
@ Notices displayed by works containing it.
|
||||
@ Additional Terms 7.b and 7.c of GPLv3 apply to this file:
|
||||
@ * Requiring preservation of specified reasonable legal notices or
|
||||
@ author attributions in that material or in the Appropriate Legal
|
||||
@ Notices displayed by works containing it.
|
||||
@ * Prohibiting misrepresentation of the origin of that material,
|
||||
@ or requiring that modified versions of such material be marked in
|
||||
@ reasonable ways as different from the original version.
|
||||
|
||||
.macro GEN_HANDLER name
|
||||
.global \name
|
||||
.type \name, %function
|
||||
\name:
|
||||
ldr sp, =#0x02000000 @ We make the (full descending) stack point to the end of ITCM for our exception handlers.
|
||||
@ It doesn't matter if we're overwriting stuff here, since we're going to reboot.
|
||||
.macro GEN_USUAL_HANDLER name, index
|
||||
\name\()Handler:
|
||||
ldr sp, =_regs
|
||||
stmia sp, {r0-r7}
|
||||
|
||||
stmfd sp!, {r0-r7} @ FIQ has its own r8-r14 regs
|
||||
ldr r1, =\@ @ macro expansion counter
|
||||
mov r0, #\index
|
||||
b _commonHandler
|
||||
|
||||
.size \name, . - \name
|
||||
.endm
|
||||
|
||||
.text
|
||||
.arm
|
||||
.align 4
|
||||
.balign 4
|
||||
|
||||
.global _commonHandler
|
||||
.type _commonHandler, %function
|
||||
_commonHandler:
|
||||
mov r1, r0
|
||||
mov r0, sp
|
||||
mrs r2, spsr
|
||||
mov r6, sp
|
||||
mrs r3, cpsr
|
||||
add r6, r0, #(8 * 4)
|
||||
|
||||
orr r3, #0x1c0 @ disable Imprecise Aborts, IRQ and FIQ (equivalent to "cpsid aif" on arm11)
|
||||
orr r3, #0xc0 @ mask interrupts
|
||||
msr cpsr_cx, r3
|
||||
|
||||
tst r2, #0x20
|
||||
bne noSvcBreak
|
||||
cmp r1, #2
|
||||
bne noSvcBreak
|
||||
|
||||
sub r0, lr, #4 @ calling cannotAccessAddress cause more problems that it actually solves... (I've to save a lot of regs and that's a pain tbh)
|
||||
lsr r0, #20 @ we'll just do some address checks (to see if it's in ARM9 internal memory)
|
||||
cmp r0, #0x80
|
||||
bne noSvcBreak
|
||||
ldr r4, [lr, #-4]
|
||||
ldr r5, =#0xe12fff7f
|
||||
cmp r4, r5
|
||||
bne noSvcBreak
|
||||
bic r5, r3, #0xf
|
||||
orr r5, #0x3
|
||||
msr cpsr_c, r5 @ switch to supervisor mode
|
||||
ldr r2, [sp, #0x1c] @ implementation details of the official svc handler
|
||||
ldr r4, [sp, #0x18]
|
||||
msr cpsr_c, r3 @ restore processor mode
|
||||
tst r2, #0x20
|
||||
addne lr, r4, #2 @ adjust address for later
|
||||
moveq lr, r4
|
||||
|
||||
noSvcBreak:
|
||||
ands r4, r2, #0xf @ get the mode that triggered the exception
|
||||
moveq r4, #0xf @ usr => sys
|
||||
bic r5, r3, #0xf
|
||||
orr r5, r4
|
||||
msr cpsr_c, r5 @ change processor mode
|
||||
stmfd r6!, {r8-lr}
|
||||
stmia r6!, {r8-lr}
|
||||
msr cpsr_c, r3 @ restore processor mode
|
||||
mov sp, r6
|
||||
|
||||
stmfd sp!, {r2,lr} @ it's a bit of a mess, but we will fix that later
|
||||
@ order of saved regs now: cpsr, pc + (2/4/8), r8-r14, r0-r7
|
||||
|
||||
mov r0, sp
|
||||
str lr, [r6], #4
|
||||
str r2, [r6]
|
||||
|
||||
msr cpsr_cxsf, #0xdf @ finally, switch to system mode, mask interrupts and clear flags (in case of double faults)
|
||||
ldr sp, =0x02000000
|
||||
b mainHandler
|
||||
|
||||
GEN_HANDLER FIQHandler
|
||||
GEN_HANDLER undefinedInstructionHandler
|
||||
GEN_HANDLER prefetchAbortHandler
|
||||
GEN_HANDLER dataAbortHandler
|
||||
|
||||
.global readMPUConfig
|
||||
.type readMPUConfig, %function
|
||||
readMPUConfig:
|
||||
stmfd sp!, {r4-r8, lr}
|
||||
mrc p15,0,r1,c6,c0,0
|
||||
mrc p15,0,r2,c6,c1,0
|
||||
mrc p15,0,r3,c6,c2,0
|
||||
mrc p15,0,r4,c6,c3,0
|
||||
mrc p15,0,r5,c6,c4,0
|
||||
mrc p15,0,r6,c6,c5,0
|
||||
mrc p15,0,r7,c6,c6,0
|
||||
mrc p15,0,r8,c6,c7,0
|
||||
stmia r0, {r1-r8}
|
||||
mrc p15,0,r0,c5,c0,2 @ read data access permission bits
|
||||
ldmfd sp!, {r4-r8, pc}
|
||||
.global FIQHandler
|
||||
.type FIQHandler, %function
|
||||
GEN_USUAL_HANDLER FIQ, 0
|
||||
|
||||
.global undefinedInstructionHandler
|
||||
.type undefinedInstructionHandler, %function
|
||||
GEN_USUAL_HANDLER undefinedInstruction, 1
|
||||
|
||||
.global prefetchAbortHandler
|
||||
.type prefetchAbortHandler, %function
|
||||
prefetchAbortHandler:
|
||||
msr cpsr_cx, #0xd7 @ mask interrupts (abort mode)
|
||||
mrs sp, spsr
|
||||
and sp, #0x3f
|
||||
cmp sp, #0x13
|
||||
bne _prefetchAbortNormalHandler
|
||||
|
||||
ldr sp, =BreakPtr
|
||||
ldr sp, [sp]
|
||||
cmp sp, #0
|
||||
beq _prefetchAbortNormalHandler
|
||||
add sp, #(1*4 + 4)
|
||||
cmp lr, sp
|
||||
bne _prefetchAbortNormalHandler
|
||||
|
||||
mov sp, r8
|
||||
pop {r8-r11}
|
||||
ldr lr, [sp, #8]!
|
||||
ldr sp, [sp, #4]
|
||||
msr spsr_cxsf, sp
|
||||
tst sp, #0x20
|
||||
addne lr, #2 @ adjust address for later
|
||||
|
||||
GEN_USUAL_HANDLER _prefetchAbortNormal, 2
|
||||
|
||||
.global dataAbortHandler
|
||||
.type dataAbortHandler, %function
|
||||
dataAbortHandler:
|
||||
msr cpsr_cx, #0xd7 @ mask interrupts (abort mode)
|
||||
mrs sp, spsr
|
||||
and sp, #0x3f
|
||||
cmp sp, #0x1f
|
||||
bne _dataAbortNormalHandler
|
||||
|
||||
sub lr, #8
|
||||
adr sp, safecpy
|
||||
cmp lr, sp
|
||||
blo _j_dataAbortNormalHandler
|
||||
adr sp, _safecpy_end
|
||||
cmp lr, sp
|
||||
bhs _j_dataAbortNormalHandler
|
||||
|
||||
msr spsr_f, #(1 << 30)
|
||||
mov r12, #0
|
||||
adds pc, lr, #4
|
||||
|
||||
_j_dataAbortNormalHandler:
|
||||
add lr, #8
|
||||
|
||||
GEN_USUAL_HANDLER _dataAbortNormal, 3
|
||||
|
||||
|
||||
.global safecpy
|
||||
.type safecpy, %function
|
||||
safecpy:
|
||||
push {r4, lr}
|
||||
mov r3, #0
|
||||
movs r12, #1
|
||||
|
||||
_safecpy_loop:
|
||||
ldrb r4, [r1, r3]
|
||||
cmp r12, #0
|
||||
beq _safecpy_loop_end
|
||||
strb r4, [r0, r3]
|
||||
add r3, #1
|
||||
cmp r3, r2
|
||||
blo _safecpy_loop
|
||||
|
||||
_safecpy_loop_end:
|
||||
mov r0, r3
|
||||
pop {r4, pc}
|
||||
|
||||
_safecpy_end:
|
||||
|
||||
.bss
|
||||
.balign 4
|
||||
_regs: .skip (4 * 17)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Luma3DS
|
||||
* Copyright (C) 2016 Aurora Wright, TuxSH
|
||||
* Copyright (C) 2016-2017 Aurora Wright, TuxSH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -15,13 +15,17 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Additional Terms 7.b of GPLv3 applies to this file: Requiring preservation of specified
|
||||
* reasonable legal notices or author attributions in that material or in the Appropriate Legal
|
||||
* Notices displayed by works containing it.
|
||||
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
|
||||
* * Requiring preservation of specified reasonable legal notices or
|
||||
* author attributions in that material or in the Appropriate Legal
|
||||
* Notices displayed by works containing it.
|
||||
* * Prohibiting misrepresentation of the origin of that material,
|
||||
* or requiring that modified versions of such material be marked in
|
||||
* reasonable ways as different from the original version.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Thanks to the everyone who contributed in the development of this file
|
||||
* Thanks to whoever contributed in the development of this file
|
||||
*/
|
||||
|
||||
#include "i2c.h"
|
||||
@@ -136,4 +140,4 @@ bool i2cWriteRegister(u8 dev_id, u8 reg, u8 data)
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Luma3DS
|
||||
* Copyright (C) 2016 Aurora Wright, TuxSH
|
||||
* Copyright (C) 2016-2017 Aurora Wright, TuxSH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -15,13 +15,17 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Additional Terms 7.b of GPLv3 applies to this file: Requiring preservation of specified
|
||||
* reasonable legal notices or author attributions in that material or in the Appropriate Legal
|
||||
* Notices displayed by works containing it.
|
||||
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
|
||||
* * Requiring preservation of specified reasonable legal notices or
|
||||
* author attributions in that material or in the Appropriate Legal
|
||||
* Notices displayed by works containing it.
|
||||
* * Prohibiting misrepresentation of the origin of that material,
|
||||
* or requiring that modified versions of such material be marked in
|
||||
* reasonable ways as different from the original version.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Thanks to the everyone who contributed in the development of this file
|
||||
* Thanks to whoever contributed in the development of this file
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
@@ -41,4 +45,4 @@
|
||||
#define I2C_DEV_GYRO 10
|
||||
#define I2C_DEV_IR 13
|
||||
|
||||
bool i2cWriteRegister(u8 dev_id, u8 reg, u8 data);
|
||||
bool i2cWriteRegister(u8 dev_id, u8 reg, u8 data);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Luma3DS
|
||||
* Copyright (C) 2016 Aurora Wright, TuxSH
|
||||
* Copyright (C) 2016-2017 Aurora Wright, TuxSH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -15,9 +15,13 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Additional Terms 7.b of GPLv3 applies to this file: Requiring preservation of specified
|
||||
* reasonable legal notices or author attributions in that material or in the Appropriate Legal
|
||||
* Notices displayed by works containing it.
|
||||
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
|
||||
* * Requiring preservation of specified reasonable legal notices or
|
||||
* author attributions in that material or in the Appropriate Legal
|
||||
* Notices displayed by works containing it.
|
||||
* * Prohibiting misrepresentation of the origin of that material,
|
||||
* or requiring that modified versions of such material be marked in
|
||||
* reasonable ways as different from the original version.
|
||||
*/
|
||||
|
||||
#include "i2c.h"
|
||||
@@ -28,48 +32,10 @@
|
||||
#define REG_DUMP_SIZE 4 * 17
|
||||
#define CODE_DUMP_SIZE 48
|
||||
|
||||
bool cannotAccessAddress(const void *address)
|
||||
{
|
||||
u32 regionSettings[8];
|
||||
u32 addr = (u32)address;
|
||||
|
||||
u32 dataAccessPermissions = readMPUConfig(regionSettings);
|
||||
for(u32 i = 0; i < 8; i++)
|
||||
{
|
||||
if((dataAccessPermissions & 0xF) == 0 || (regionSettings[i] & 1) == 0)
|
||||
continue; //No access / region not enabled
|
||||
|
||||
u32 regionAddrBase = regionSettings[i] & ~0xFFF;
|
||||
u32 regionSize = 1 << (((regionSettings[i] >> 1) & 0x1F) + 1);
|
||||
|
||||
if(addr >= regionAddrBase && addr < regionAddrBase + regionSize)
|
||||
return false;
|
||||
|
||||
dataAccessPermissions >>= 4;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static u32 __attribute__((noinline)) copyMemory(void *dst, const void *src, u32 size, u32 alignment)
|
||||
{
|
||||
u8 *out = (u8 *)dst;
|
||||
const u8 *in = (const u8 *)src;
|
||||
|
||||
if(((u32)src & (alignment - 1)) != 0 || cannotAccessAddress(src) || (size != 0 && cannotAccessAddress((u8 *)src + size - 1)))
|
||||
return 0;
|
||||
|
||||
for(u32 i = 0; i < size; i++)
|
||||
*out++ = *in++;
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
void __attribute__((noreturn)) mainHandler(u32 *regs, u32 type)
|
||||
void __attribute__((noreturn)) mainHandler(u32 *registerDump, u32 type)
|
||||
{
|
||||
ExceptionDumpHeader dumpHeader;
|
||||
|
||||
u32 registerDump[REG_DUMP_SIZE / 4];
|
||||
u8 codeDump[CODE_DUMP_SIZE];
|
||||
|
||||
dumpHeader.magic[0] = 0xDEADC0DE;
|
||||
@@ -85,34 +51,32 @@ void __attribute__((noreturn)) mainHandler(u32 *regs, u32 type)
|
||||
dumpHeader.codeDumpSize = CODE_DUMP_SIZE;
|
||||
dumpHeader.additionalDataSize = 0;
|
||||
|
||||
//Dump registers
|
||||
//Current order of saved regs: cpsr, pc, r8-r14, r0-r7
|
||||
u32 cpsr = regs[0];
|
||||
u32 pc = regs[1] - (type < 3 ? (((cpsr & 0x20) != 0 && type == 1) ? 2 : 4) : 8);
|
||||
u32 cpsr = registerDump[16];
|
||||
u32 pc = registerDump[15] - (type < 3 ? (((cpsr & 0x20) != 0 && type == 1) ? 2 : 4) : 8);
|
||||
|
||||
registerDump[15] = pc;
|
||||
registerDump[16] = cpsr;
|
||||
for(u32 i = 0; i < 7; i++) registerDump[8 + i] = regs[2 + i];
|
||||
for(u32 i = 0; i < 8; i++) registerDump[i] = regs[9 + i];
|
||||
|
||||
//Dump code
|
||||
u8 *instr = (u8 *)pc + ((cpsr & 0x20) ? 2 : 4) - dumpHeader.codeDumpSize; //Doesn't work well on 32-bit Thumb instructions, but it isn't much of a problem
|
||||
dumpHeader.codeDumpSize = copyMemory(codeDump, instr, dumpHeader.codeDumpSize, ((cpsr & 0x20) != 0) ? 2 : 4);
|
||||
u8 *instr = (u8 *)pc + ((cpsr & 0x20) ? 2 : 4) - dumpHeader.codeDumpSize; //wouldn't work well on 32-bit Thumb instructions, but it isn't much of a problem
|
||||
dumpHeader.codeDumpSize = ((u32)instr & (((cpsr & 0x20) != 0) ? 1 : 3)) != 0 ? 0 : safecpy(codeDump, instr, dumpHeader.codeDumpSize);
|
||||
|
||||
//Copy register dump and code dump
|
||||
//Copy register dump and code dump
|
||||
u8 *final = (u8 *)(FINAL_BUFFER + sizeof(ExceptionDumpHeader));
|
||||
final += copyMemory(final, registerDump, dumpHeader.registerDumpSize, 1);
|
||||
final += copyMemory(final, codeDump, dumpHeader.codeDumpSize, 1);
|
||||
final += safecpy(final, registerDump, dumpHeader.registerDumpSize);
|
||||
final += safecpy(final, codeDump, dumpHeader.codeDumpSize);
|
||||
|
||||
//Dump stack in place
|
||||
dumpHeader.stackDumpSize = copyMemory(final, (const void *)registerDump[13], 0x1000 - (registerDump[13] & 0xFFF), 1);
|
||||
dumpHeader.stackDumpSize = safecpy(final, (const void *)registerDump[13], 0x1000 - (registerDump[13] & 0xFFF));
|
||||
|
||||
dumpHeader.totalSize = sizeof(ExceptionDumpHeader) + dumpHeader.registerDumpSize + dumpHeader.codeDumpSize + dumpHeader.stackDumpSize + dumpHeader.additionalDataSize;
|
||||
|
||||
//Copy header (actually optimized by the compiler)
|
||||
*(ExceptionDumpHeader *)FINAL_BUFFER = dumpHeader;
|
||||
|
||||
if(ARESCREENSINITIALIZED) i2cWriteRegister(I2C_DEV_MCU, 0x22, 1 << 0); //Shutdown LCD
|
||||
|
||||
((void (*)())0xFFFF0830)(); //Ensure that all memory transfers have completed and that the data cache has been flushed
|
||||
|
||||
i2cWriteRegister(I2C_DEV_MCU, 0x20, 1 << 2); //Reboot
|
||||
while(true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
@ This file is part of Luma3DS
|
||||
@ Copyright (C) 2016 Aurora Wright, TuxSH
|
||||
@ Copyright (C) 2016-2017 Aurora Wright, TuxSH
|
||||
@
|
||||
@ This program is free software: you can redistribute it and/or modify
|
||||
@ it under the terms of the GNU General Public License as published by
|
||||
@@ -14,16 +14,24 @@
|
||||
@ You should have received a copy of the GNU General Public License
|
||||
@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
@
|
||||
@ Additional Terms 7.b of GPLv3 applies to this file: Requiring preservation of specified
|
||||
@ reasonable legal notices or author attributions in that material or in the Appropriate Legal
|
||||
@ Notices displayed by works containing it.
|
||||
@ Additional Terms 7.b and 7.c of GPLv3 apply to this file:
|
||||
@ * Requiring preservation of specified reasonable legal notices or
|
||||
@ author attributions in that material or in the Appropriate Legal
|
||||
@ Notices displayed by works containing it.
|
||||
@ * Prohibiting misrepresentation of the origin of that material,
|
||||
@ or requiring that modified versions of such material be marked in
|
||||
@ reasonable ways as different from the original version.
|
||||
|
||||
.section .text.start
|
||||
.align 4
|
||||
.global _start
|
||||
_start:
|
||||
add pc, r0, #(handlers - .) @ Dummy instruction to prevent compiler optimizations
|
||||
add pc, r0, #(handlers - .) @ Dummy instruction
|
||||
|
||||
.global BreakPtr
|
||||
BreakPtr: .word 0
|
||||
|
||||
.global handlers
|
||||
handlers:
|
||||
.word FIQHandler
|
||||
.word undefinedInstructionHandler
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Luma3DS
|
||||
* Copyright (C) 2016 Aurora Wright, TuxSH
|
||||
* Copyright (C) 2016-2017 Aurora Wright, TuxSH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -15,9 +15,13 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Additional Terms 7.b of GPLv3 applies to this file: Requiring preservation of specified
|
||||
* reasonable legal notices or author attributions in that material or in the Appropriate Legal
|
||||
* Notices displayed by works containing it.
|
||||
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
|
||||
* * Requiring preservation of specified reasonable legal notices or
|
||||
* author attributions in that material or in the Appropriate Legal
|
||||
* Notices displayed by works containing it.
|
||||
* * Prohibiting misrepresentation of the origin of that material,
|
||||
* or requiring that modified versions of such material be marked in
|
||||
* reasonable ways as different from the original version.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
@@ -34,4 +38,8 @@ typedef uint64_t u64;
|
||||
typedef volatile u8 vu8;
|
||||
typedef volatile u16 vu16;
|
||||
typedef volatile u32 vu32;
|
||||
typedef volatile u64 vu64;
|
||||
typedef volatile u64 vu64;
|
||||
|
||||
#define PDN_GPU_CNT (*(vu8 *)0x10141200)
|
||||
|
||||
#define ARESCREENSINITIALIZED (PDN_GPU_CNT != 1)
|
||||
|
||||
81
exceptions/exception_dump_parser.py → exceptions/exception_dump_parser/luma3ds_exception_dump_parser/__main__.py
Normal file → Executable file
81
exceptions/exception_dump_parser.py → exceptions/exception_dump_parser/luma3ds_exception_dump_parser/__main__.py
Normal file → Executable file
@@ -22,9 +22,9 @@
|
||||
# Notices displayed by works containing it.
|
||||
|
||||
__author__ = "TuxSH"
|
||||
__copyright__ = "Copyright (c) 2016 TuxSH"
|
||||
__copyright__ = "Copyright (c) 2016 TuxSH"
|
||||
__license__ = "GPLv3"
|
||||
__version__ = "v1.0"
|
||||
__version__ = "v1.2"
|
||||
|
||||
"""
|
||||
Parses Luma3DS exception dumps
|
||||
@@ -33,6 +33,9 @@ Parses Luma3DS exception dumps
|
||||
import argparse
|
||||
from struct import unpack_from
|
||||
|
||||
import os
|
||||
import subprocess
|
||||
|
||||
# Source of hexdump: https://gist.github.com/ImmortalPC/c340564823f283fe530b
|
||||
# Credits for hexdump go to the original authors
|
||||
# Slightly edited by TuxSH
|
||||
@@ -76,19 +79,26 @@ def hexdump(addr, src, length=16, sep='.' ):
|
||||
text += chr(c)
|
||||
else:
|
||||
text += sep
|
||||
result.append(('%08X: %-'+str(length*(2+1)+1)+'s |%s|') % (addr + i, hexa, text))
|
||||
result.append(('%08x: %-'+str(length*(2+1)+1)+'s |%s|') % (addr + i, hexa, text))
|
||||
|
||||
return '\n'.join(result)
|
||||
|
||||
|
||||
|
||||
def makeRegisterLine(A, rA, B, rB):
|
||||
return "{0:<15}{1:<20}{2:<15}{3:<20}".format(A, "{0:08x}".format(rA), B, "{0:08x}".format(rB))
|
||||
|
||||
|
||||
handledExceptionNames = ("FIQ", "undefined instruction", "prefetch abort", "data abort")
|
||||
registerNames = tuple("r{0}".format(i) for i in range(13)) + ("sp", "lr", "pc", "cpsr") + ("dfsr", "ifsr", "far") + ("fpexc", "fpinst", "fpinst2")
|
||||
svcBreakReasons = ("(svcBreak: panic)", "(svcBreak: assertion failed)", "(svcBreak: user-related)")
|
||||
faultStatusSources = {
|
||||
0b1:'Alignment', 0b100:'Instruction cache maintenance operation fault',
|
||||
0b1100:'External Abort on translation - First-level', 0b1110:'External Abort on translation - Second-level',
|
||||
0b101:'Translation - Section', 0b111:'Translation - Page', 0b11:'Access bit - Section', 0b110:'Access bit - Page',
|
||||
0b1001:'Domain - Section', 0b1011:'Domain - Page', 0b1101:'Permission - Section', 0b1111:'Permission - Page',
|
||||
0b1000:'Precise External Abort', 0b10110:'Imprecise External Abort', 0b10:'Debug event'
|
||||
}
|
||||
|
||||
if __name__ == "__main__":
|
||||
def main(args=None):
|
||||
parser = argparse.ArgumentParser(description="Parse Luma3DS exception dumps")
|
||||
parser.add_argument("filename")
|
||||
args = parser.parse_args()
|
||||
@@ -96,23 +106,24 @@ if __name__ == "__main__":
|
||||
with open(args.filename, "rb") as f: data = f.read()
|
||||
if unpack_from("<2I", data) != (0xdeadc0de, 0xdeadcafe):
|
||||
raise SystemExit("Invalid file format")
|
||||
|
||||
|
||||
version, processor, exceptionType, _, nbRegisters, codeDumpSize, stackDumpSize, additionalDataSize = unpack_from("<8I", data, 8)
|
||||
nbRegisters //= 4
|
||||
|
||||
|
||||
if version < (1 << 16) | 2:
|
||||
raise SystemExit("Incompatible format version, please use the appropriate parser.")
|
||||
|
||||
|
||||
registers = unpack_from("<{0}I".format(nbRegisters), data, 40)
|
||||
codeDump = data[40 + 4 * nbRegisters : 40 + 4 * nbRegisters + codeDumpSize]
|
||||
stackOffset = 40 + 4 * nbRegisters + codeDumpSize
|
||||
codeOffset = 40 + 4 * nbRegisters
|
||||
codeDump = data[codeOffset : codeOffset + codeDumpSize]
|
||||
stackOffset = codeOffset + codeDumpSize
|
||||
stackDump = data[stackOffset : stackOffset + stackDumpSize]
|
||||
addtionalDataOffset = stackOffset + stackDumpSize
|
||||
additionalData = data[addtionalDataOffset : addtionalDataOffset + additionalDataSize]
|
||||
|
||||
|
||||
if processor == 9: print("Processor: ARM9")
|
||||
else: print("Processor: ARM11 (core {0})".format(processor >> 16))
|
||||
|
||||
|
||||
typeDetailsStr = ""
|
||||
if exceptionType == 2:
|
||||
if (registers[16] & 0x20) == 0 and codeDumpSize >= 4:
|
||||
@@ -125,23 +136,53 @@ if __name__ == "__main__":
|
||||
instr = unpack_from("<I", codeDump[-4:])[0]
|
||||
if instr == 0xdf3c:
|
||||
typeDetailsStr = " " + (svcBreakReasons[registers[0]] if registers[0] < 3 else "(svcBreak)")
|
||||
|
||||
|
||||
elif processor != 9 and (registers[20] & 0x80000000) != 0:
|
||||
typeDetailsStr = " (VFP exception)"
|
||||
|
||||
|
||||
print("Exception type: {0}{1}".format("unknown" if exceptionType >= len(handledExceptionNames) else handledExceptionNames[exceptionType], typeDetailsStr))
|
||||
|
||||
if processor == 11 and exceptionType >= 2:
|
||||
xfsr = registers[18] if exceptionType == 2 else registers[17]
|
||||
print("Fault status: " + faultStatusSources[xfsr & 0xf])
|
||||
|
||||
if additionalDataSize != 0:
|
||||
print("Current process: {0} ({1:016x})".format(additionalData[:8].decode("ascii"), unpack_from("<Q", additionalData, 8)[0]))
|
||||
|
||||
|
||||
print("\nRegister dump:\n")
|
||||
for i in range(0, nbRegisters - (nbRegisters % 2), 2):
|
||||
if i == 16: print("")
|
||||
print(makeRegisterLine(registerNames[i], registers[i], registerNames[i+1], registers[i+1]))
|
||||
if nbRegisters % 2 == 1: print("{0:<15}{1:<20}".format(registerNames[nbRegisters - 1], "{0:08x}".format(registers[nbRegisters - 1])))
|
||||
|
||||
|
||||
if processor == 11 and exceptionType == 3:
|
||||
print("{0:<15}{1:<20}Access type: {2}".format("FAR", "{0:08x}".format(registers[19]), "Write" if registers[17] & (1 << 11) != 0 else "Read"))
|
||||
|
||||
thumb = registers[16] & 0x20 != 0
|
||||
addr = registers[15] - codeDumpSize + (2 if thumb else 4)
|
||||
|
||||
print("\nCode dump:\n")
|
||||
print(hexdump(registers[15] - codeDumpSize + (4 if (registers[16] & 0x20 == 0) else 2), codeDump))
|
||||
|
||||
|
||||
objdump_res = ""
|
||||
try:
|
||||
path = os.path.join(os.environ["DEVKITARM"], "bin", "arm-none-eabi-objdump")
|
||||
|
||||
if os.name == "nt" and path[0] == '/':
|
||||
path = ''.join((path[1], ':', path[2:]))
|
||||
|
||||
objdump_res = subprocess.check_output((
|
||||
path, "-marm", "-b", "binary",
|
||||
"--adjust-vma="+hex(addr - codeOffset), "--start-address="+hex(addr),
|
||||
"--stop-address="+hex(addr + codeDumpSize), "-D", "-z", "-M",
|
||||
"reg-names-std" + (",force-thumb" if thumb else ""), args.filename
|
||||
)).decode("utf-8")
|
||||
objdump_res = '\n'.join(objdump_res[objdump_res.find('<.data+'):].split('\n')[1:])
|
||||
except: objdump_res = ""
|
||||
|
||||
print(objdump_res if objdump_res != "" else hexdump(addr, codeDump))
|
||||
|
||||
print("\nStack dump:\n")
|
||||
print(hexdump(registers[13], stackDump))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
13
exceptions/exception_dump_parser/setup.py
Normal file
13
exceptions/exception_dump_parser/setup.py
Normal file
@@ -0,0 +1,13 @@
|
||||
from setuptools import setup, find_packages
|
||||
|
||||
setup(
|
||||
name='luma3ds_exception_dump_parser',
|
||||
version='1.2',
|
||||
url='https://github.com/AuroraWright/Luma3DS',
|
||||
author='TuxSH',
|
||||
license='GPLv3',
|
||||
description='Parses Luma3DS exception dumps',
|
||||
install_requires=[''],
|
||||
packages=find_packages(),
|
||||
entry_points={'console_scripts': ['luma3ds_exception_dump_parser=luma3ds_exception_dump_parser.__main__:main']},
|
||||
)
|
||||
@@ -1,19 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <3ds/types.h>
|
||||
|
||||
typedef struct __attribute__((packed))
|
||||
{
|
||||
char magic[4];
|
||||
|
||||
u8 versionMajor;
|
||||
u8 versionMinor;
|
||||
u8 versionBuild;
|
||||
u8 flags; /* bit 0: dev branch; bit 1: is release */
|
||||
|
||||
u32 commitHash;
|
||||
|
||||
u32 config;
|
||||
} CFWInfo;
|
||||
|
||||
u32 svcGetCFWInfo(CFWInfo *info);
|
||||
@@ -1,9 +0,0 @@
|
||||
.text
|
||||
.arm
|
||||
.align 4
|
||||
|
||||
.global svcGetCFWInfo
|
||||
.type svcGetCFWInfo, %function
|
||||
svcGetCFWInfo:
|
||||
svc 0x2e
|
||||
bx lr
|
||||
@@ -1,97 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <3ds/types.h>
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u8 reserved[5];
|
||||
u8 flag;
|
||||
u8 remasterversion[2];
|
||||
} PACKED exheader_systeminfoflags;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u32 address;
|
||||
u32 nummaxpages;
|
||||
u32 codesize;
|
||||
} PACKED exheader_codesegmentinfo;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u8 name[8];
|
||||
exheader_systeminfoflags flags;
|
||||
exheader_codesegmentinfo text;
|
||||
u8 stacksize[4];
|
||||
exheader_codesegmentinfo ro;
|
||||
u8 reserved[4];
|
||||
exheader_codesegmentinfo data;
|
||||
u32 bsssize;
|
||||
} PACKED exheader_codesetinfo;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u64 programid[0x30];
|
||||
} PACKED exheader_dependencylist;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u8 savedatasize[4];
|
||||
u8 reserved[4];
|
||||
u8 jumpid[8];
|
||||
u8 reserved2[0x30];
|
||||
} PACKED exheader_systeminfo;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u8 extsavedataid[8];
|
||||
u8 systemsavedataid[8];
|
||||
u8 reserved[8];
|
||||
u8 accessinfo[7];
|
||||
u8 otherattributes;
|
||||
} PACKED exheader_storageinfo;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u64 programid;
|
||||
u8 flags[8];
|
||||
u16 resourcelimitdescriptor[0x10];
|
||||
exheader_storageinfo storageinfo;
|
||||
u64 serviceaccesscontrol[0x20];
|
||||
u8 reserved[0x1f];
|
||||
u8 resourcelimitcategory;
|
||||
} PACKED exheader_arm11systemlocalcaps;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u32 descriptors[28];
|
||||
u8 reserved[0x10];
|
||||
} PACKED exheader_arm11kernelcapabilities;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u8 descriptors[15];
|
||||
u8 descversion;
|
||||
} PACKED exheader_arm9accesscontrol;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
// systemcontrol info {
|
||||
// coreinfo {
|
||||
exheader_codesetinfo codesetinfo;
|
||||
exheader_dependencylist deplist;
|
||||
// }
|
||||
exheader_systeminfo systeminfo;
|
||||
// }
|
||||
// accesscontrolinfo {
|
||||
exheader_arm11systemlocalcaps arm11systemlocalcaps;
|
||||
exheader_arm11kernelcapabilities arm11kernelcaps;
|
||||
exheader_arm9accesscontrol arm9accesscontrol;
|
||||
// }
|
||||
struct {
|
||||
u8 signature[0x100];
|
||||
u8 ncchpubkeymodulus[0x100];
|
||||
exheader_arm11systemlocalcaps arm11systemlocalcaps;
|
||||
exheader_arm11kernelcapabilities arm11kernelcaps;
|
||||
exheader_arm9accesscontrol arm9accesscontrol;
|
||||
} PACKED accessdesc;
|
||||
} PACKED exheader_header;
|
||||
@@ -1,643 +0,0 @@
|
||||
#include <3ds.h>
|
||||
#include "patcher.h"
|
||||
#include "memory.h"
|
||||
#include "strings.h"
|
||||
#include "ifile.h"
|
||||
#include "CFWInfo.h"
|
||||
|
||||
static CFWInfo info;
|
||||
|
||||
static void patchMemory(u8 *start, u32 size, const void *pattern, u32 patSize, int offset, const void *replace, u32 repSize, u32 count)
|
||||
{
|
||||
for(u32 i = 0; i < count; i++)
|
||||
{
|
||||
u8 *found = memsearch(start, pattern, size, patSize);
|
||||
|
||||
if(found == NULL) break;
|
||||
|
||||
memcpy(found + offset, replace, repSize);
|
||||
|
||||
u32 at = (u32)(found - start);
|
||||
|
||||
if(at + patSize > size) break;
|
||||
|
||||
size -= at + patSize;
|
||||
start = found + patSize;
|
||||
}
|
||||
}
|
||||
|
||||
static int fileOpen(IFile *file, FS_ArchiveID archiveId, const char *path, int flags)
|
||||
{
|
||||
FS_Path filePath = {PATH_ASCII, strnlen(path, 255) + 1, path},
|
||||
archivePath = {PATH_EMPTY, 1, (u8 *)""};
|
||||
|
||||
return IFile_Open(file, archiveId, archivePath, filePath, flags);
|
||||
}
|
||||
|
||||
static void loadCFWInfo(void)
|
||||
{
|
||||
static bool infoLoaded = false;
|
||||
|
||||
if(!infoLoaded)
|
||||
{
|
||||
svcGetCFWInfo(&info);
|
||||
|
||||
IFile file;
|
||||
if(BOOTCFG_SAFEMODE != 0 && R_SUCCEEDED(fileOpen(&file, ARCHIVE_SDMC, "/", FS_OPEN_READ))) //Init SD card if SAFE_MODE is being booted
|
||||
IFile_Close(&file);
|
||||
|
||||
infoLoaded = true;
|
||||
}
|
||||
}
|
||||
|
||||
static bool secureInfoExists(void)
|
||||
{
|
||||
static bool exists = false;
|
||||
|
||||
if(!exists)
|
||||
{
|
||||
IFile file;
|
||||
if(R_SUCCEEDED(fileOpen(&file, ARCHIVE_NAND_RW, "/sys/SecureInfo_C", FS_OPEN_READ)))
|
||||
{
|
||||
exists = true;
|
||||
IFile_Close(&file);
|
||||
}
|
||||
}
|
||||
|
||||
return exists;
|
||||
}
|
||||
|
||||
static void loadCustomVerString(u16 *out, u32 *verStringSize)
|
||||
{
|
||||
static const char path[] = "/luma/customversion.txt";
|
||||
|
||||
IFile file;
|
||||
|
||||
if(R_SUCCEEDED(fileOpen(&file, ARCHIVE_SDMC, path, FS_OPEN_READ)))
|
||||
{
|
||||
u64 fileSize;
|
||||
|
||||
if(R_SUCCEEDED(IFile_GetSize(&file, &fileSize)) && fileSize <= 57)
|
||||
{
|
||||
u8 buf[57];
|
||||
u64 total;
|
||||
|
||||
if(R_SUCCEEDED(IFile_Read(&file, &total, buf, fileSize)))
|
||||
{
|
||||
u32 finalSize = 0;
|
||||
|
||||
for(u32 i = 0, fileSizeTmp = (u32)fileSize, increase; i < fileSizeTmp && finalSize <= 18; i += increase)
|
||||
{
|
||||
if((buf[i] & 0x80) == 0)
|
||||
{
|
||||
increase = 1;
|
||||
out[finalSize++] = (u16)buf[i];
|
||||
}
|
||||
else if((buf[i] & 0xE0) == 0xC0 && i + 1 < fileSizeTmp && (buf[i + 1] & 0xC0) == 0x80)
|
||||
{
|
||||
increase = 2;
|
||||
out[finalSize++] = (u16)(((buf[i] & 0x1F) << 6) | (buf[i + 1] & 0x3F));
|
||||
}
|
||||
else if((buf[i] & 0xF0) == 0xE0 && i + 2 < fileSizeTmp && (buf[i + 1] & 0xC0) == 0x80 && (buf[i + 2] & 0xC0) == 0x80)
|
||||
{
|
||||
increase = 3;
|
||||
out[finalSize++] = (u16)(((buf[i] & 0xF) << 12) | ((buf[i + 1] & 0x3F) << 6) | (buf[i + 2] & 0x3F));
|
||||
}
|
||||
else break;
|
||||
}
|
||||
|
||||
if(finalSize > 0) *verStringSize = finalSize * 2;
|
||||
}
|
||||
}
|
||||
|
||||
IFile_Close(&file);
|
||||
}
|
||||
}
|
||||
|
||||
static void loadTitleCodeSection(u64 progId, u8 *code, u32 size)
|
||||
{
|
||||
/* Here we look for "/luma/code_sections/[u64 titleID in hex, uppercase].bin"
|
||||
If it exists it should be a decompressed binary code file */
|
||||
|
||||
char path[] = "/luma/code_sections/0000000000000000.bin";
|
||||
progIdToStr(path + 35, progId);
|
||||
|
||||
IFile file;
|
||||
|
||||
if(R_SUCCEEDED(fileOpen(&file, ARCHIVE_SDMC, path, FS_OPEN_READ)))
|
||||
{
|
||||
u64 fileSize;
|
||||
|
||||
if(R_SUCCEEDED(IFile_GetSize(&file, &fileSize)) && fileSize <= size)
|
||||
{
|
||||
u64 total;
|
||||
IFile_Read(&file, &total, code, fileSize);
|
||||
}
|
||||
|
||||
IFile_Close(&file);
|
||||
}
|
||||
}
|
||||
|
||||
static void loadTitleLocaleConfig(u64 progId, u8 *regionId, u8 *languageId)
|
||||
{
|
||||
/* Here we look for "/luma/locales/[u64 titleID in hex, uppercase].txt"
|
||||
If it exists it should contain, for example, "EUR IT" */
|
||||
|
||||
char path[] = "/luma/locales/0000000000000000.txt";
|
||||
progIdToStr(path + 29, progId);
|
||||
|
||||
IFile file;
|
||||
|
||||
if(R_SUCCEEDED(fileOpen(&file, ARCHIVE_SDMC, path, FS_OPEN_READ)))
|
||||
{
|
||||
u64 fileSize;
|
||||
|
||||
if(R_SUCCEEDED(IFile_GetSize(&file, &fileSize)) && fileSize == 6)
|
||||
{
|
||||
char buf[6];
|
||||
u64 total;
|
||||
|
||||
if(R_SUCCEEDED(IFile_Read(&file, &total, buf, 6)))
|
||||
{
|
||||
for(u32 i = 0; i < 7; i++)
|
||||
{
|
||||
static const char *regions[] = {"JPN", "USA", "EUR", "AUS", "CHN", "KOR", "TWN"};
|
||||
|
||||
if(memcmp(buf, regions[i], 3) == 0)
|
||||
{
|
||||
*regionId = (u8)i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for(u32 i = 0; i < 12; i++)
|
||||
{
|
||||
static const char *languages[] = {"JP", "EN", "FR", "DE", "IT", "ES", "ZH", "KO", "NL", "PT", "RU", "TW"};
|
||||
|
||||
if(memcmp(buf + 4, languages[i], 2) == 0)
|
||||
{
|
||||
*languageId = (u8)i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
IFile_Close(&file);
|
||||
}
|
||||
}
|
||||
|
||||
static u8 *getCfgOffsets(u8 *code, u32 size, u32 *CFGUHandleOffset)
|
||||
{
|
||||
/* HANS:
|
||||
Look for error code which is known to be stored near cfg:u handle
|
||||
this way we can find the right candidate
|
||||
(handle should also be stored right after end of candidate function) */
|
||||
|
||||
u32 n = 0,
|
||||
possible[24];
|
||||
|
||||
for(u8 *pos = code + 4; n < 24 && pos < code + size - 4; pos += 4)
|
||||
{
|
||||
if(*(u32 *)pos == 0xD8A103F9)
|
||||
{
|
||||
for(u32 *l = (u32 *)pos - 4; n < 24 && l < (u32 *)pos + 4; l++)
|
||||
if(*l <= 0x10000000) possible[n++] = *l;
|
||||
}
|
||||
}
|
||||
|
||||
for(u8 *CFGU_GetConfigInfoBlk2_endPos = code; CFGU_GetConfigInfoBlk2_endPos < code + size - 8; CFGU_GetConfigInfoBlk2_endPos += 4)
|
||||
{
|
||||
static const u32 CFGU_GetConfigInfoBlk2_endPattern[] = {0xE8BD8010, 0x00010082};
|
||||
|
||||
//There might be multiple implementations of GetConfigInfoBlk2 but let's search for the one we want
|
||||
u32 *cmp = (u32 *)CFGU_GetConfigInfoBlk2_endPos;
|
||||
|
||||
if(cmp[0] == CFGU_GetConfigInfoBlk2_endPattern[0] && cmp[1] == CFGU_GetConfigInfoBlk2_endPattern[1])
|
||||
{
|
||||
*CFGUHandleOffset = *((u32 *)CFGU_GetConfigInfoBlk2_endPos + 2);
|
||||
|
||||
for(u32 i = 0; i < n; i++)
|
||||
if(possible[i] == *CFGUHandleOffset) return CFGU_GetConfigInfoBlk2_endPos;
|
||||
|
||||
CFGU_GetConfigInfoBlk2_endPos += 4;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void patchCfgGetLanguage(u8 *code, u32 size, u8 languageId, u8 *CFGU_GetConfigInfoBlk2_endPos)
|
||||
{
|
||||
u8 *CFGU_GetConfigInfoBlk2_startPos; //Let's find STMFD SP (there might be a NOP before, but nevermind)
|
||||
|
||||
for(CFGU_GetConfigInfoBlk2_startPos = CFGU_GetConfigInfoBlk2_endPos - 4;
|
||||
CFGU_GetConfigInfoBlk2_startPos >= code && *((u16 *)CFGU_GetConfigInfoBlk2_startPos + 1) != 0xE92D;
|
||||
CFGU_GetConfigInfoBlk2_startPos -= 2);
|
||||
|
||||
for(u8 *languageBlkIdPos = code; languageBlkIdPos < code + size; languageBlkIdPos += 4)
|
||||
{
|
||||
if(*(u32 *)languageBlkIdPos == 0xA0002)
|
||||
{
|
||||
for(u8 *instr = languageBlkIdPos - 8; instr >= languageBlkIdPos - 0x1008 && instr >= code + 4; instr -= 4) //Should be enough
|
||||
{
|
||||
if(instr[3] == 0xEB) //We're looking for BL
|
||||
{
|
||||
u8 *calledFunction = instr;
|
||||
u32 i = 0;
|
||||
bool found;
|
||||
|
||||
do
|
||||
{
|
||||
u32 low24 = (*(u32 *)calledFunction & 0x00FFFFFF) << 2;
|
||||
u32 signMask = (u32)(-(low24 >> 25)) & 0xFC000000; //Sign extension
|
||||
s32 offset = (s32)(low24 | signMask) + 8; //Branch offset + 8 for prefetch
|
||||
|
||||
calledFunction += offset;
|
||||
|
||||
found = calledFunction >= CFGU_GetConfigInfoBlk2_startPos - 4 && calledFunction <= CFGU_GetConfigInfoBlk2_endPos;
|
||||
i++;
|
||||
}
|
||||
while(i < 2 && !found && calledFunction[3] == 0xEA);
|
||||
|
||||
if(found)
|
||||
{
|
||||
*((u32 *)instr - 1) = 0xE3A00000 | languageId; // mov r0, sp => mov r0, =languageId
|
||||
*(u32 *)instr = 0xE5CD0000; // bl CFGU_GetConfigInfoBlk2 => strb r0, [sp]
|
||||
*((u32 *)instr + 1) = 0xE3B00000; // (1 or 2 instructions) => movs r0, 0 (result code)
|
||||
|
||||
//We're done
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void patchCfgGetRegion(u8 *code, u32 size, u8 regionId, u32 CFGUHandleOffset)
|
||||
{
|
||||
for(u8 *cmdPos = code; cmdPos < code + size - 28; cmdPos += 4)
|
||||
{
|
||||
static const u32 cfgSecureInfoGetRegionCmdPattern[] = {0xEE1D4F70, 0xE3A00802, 0xE5A40080};
|
||||
|
||||
u32 *cmp = (u32 *)cmdPos;
|
||||
|
||||
if(cmp[0] == cfgSecureInfoGetRegionCmdPattern[0] && cmp[1] == cfgSecureInfoGetRegionCmdPattern[1] &&
|
||||
cmp[2] == cfgSecureInfoGetRegionCmdPattern[2] && *((u16 *)cmdPos + 7) == 0xE59F &&
|
||||
*(u32 *)(cmdPos + 20 + *((u16 *)cmdPos + 6)) == CFGUHandleOffset)
|
||||
{
|
||||
*((u32 *)cmdPos + 4) = 0xE3A00000 | regionId; // mov r0, =regionId
|
||||
*((u32 *)cmdPos + 5) = 0xE5C40008; // strb r0, [r4, 8]
|
||||
*((u32 *)cmdPos + 6) = 0xE3B00000; // movs r0, 0 (result code) ('s' not needed but nvm)
|
||||
*((u32 *)cmdPos + 7) = 0xE5840004; // str r0, [r4, 4]
|
||||
|
||||
//The remaining, not patched, function code will do the rest for us
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void patchCode(u64 progId, u8 *code, u32 size)
|
||||
{
|
||||
loadCFWInfo();
|
||||
|
||||
switch(progId)
|
||||
{
|
||||
case 0x0004003000008F02LL: // USA Menu
|
||||
case 0x0004003000008202LL: // EUR Menu
|
||||
case 0x0004003000009802LL: // JPN Menu
|
||||
case 0x000400300000A102LL: // CHN Menu
|
||||
case 0x000400300000A902LL: // KOR Menu
|
||||
case 0x000400300000B102LL: // TWN Menu
|
||||
{
|
||||
static const u8 regionFreePattern[] = {
|
||||
0x00, 0x00, 0x55, 0xE3, 0x01, 0x10, 0xA0
|
||||
};
|
||||
static const u8 regionFreePatch[] = {
|
||||
0x01, 0x00, 0xA0, 0xE3, 0x1E, 0xFF, 0x2F, 0xE1
|
||||
};
|
||||
|
||||
//Patch SMDH region checks
|
||||
patchMemory(code, size,
|
||||
regionFreePattern,
|
||||
sizeof(regionFreePattern), -16,
|
||||
regionFreePatch,
|
||||
sizeof(regionFreePatch), 1
|
||||
);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x0004013000002C02LL: // NIM
|
||||
{
|
||||
static const u8 blockAutoUpdatesPattern[] = {
|
||||
0x25, 0x79, 0x0B, 0x99
|
||||
};
|
||||
static const u8 blockAutoUpdatesPatch[] = {
|
||||
0xE3, 0xA0
|
||||
};
|
||||
|
||||
//Block silent auto-updates
|
||||
patchMemory(code, size,
|
||||
blockAutoUpdatesPattern,
|
||||
sizeof(blockAutoUpdatesPattern), 0,
|
||||
blockAutoUpdatesPatch,
|
||||
sizeof(blockAutoUpdatesPatch), 1
|
||||
);
|
||||
|
||||
//Apply only if the user booted with R
|
||||
if((BOOTCFG_NAND != 0) != (BOOTCFG_FIRM != 0))
|
||||
{
|
||||
static const u8 skipEshopUpdateCheckPattern[] = {
|
||||
0x30, 0xB5, 0xF1, 0xB0
|
||||
};
|
||||
static const u8 skipEshopUpdateCheckPatch[] = {
|
||||
0x00, 0x20, 0x08, 0x60, 0x70, 0x47
|
||||
};
|
||||
|
||||
//Skip update checks to access the EShop
|
||||
patchMemory(code, size,
|
||||
skipEshopUpdateCheckPattern,
|
||||
sizeof(skipEshopUpdateCheckPattern), 0,
|
||||
skipEshopUpdateCheckPatch,
|
||||
sizeof(skipEshopUpdateCheckPatch), 1
|
||||
);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x0004013000003202LL: // FRIENDS
|
||||
{
|
||||
static const u8 fpdVerPattern[] = {
|
||||
0xE0, 0x1E, 0xFF, 0x2F, 0xE1, 0x01, 0x01
|
||||
};
|
||||
|
||||
u8 mostRecentFpdVer = 7;
|
||||
|
||||
u8 *fpdVer = memsearch(code, fpdVerPattern, size, sizeof(fpdVerPattern));
|
||||
|
||||
//Allow online access to work with old friends modules
|
||||
if(fpdVer != NULL && fpdVer[9] < mostRecentFpdVer) fpdVer[9] = mostRecentFpdVer;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x0004001000021000LL: // USA MSET
|
||||
case 0x0004001000020000LL: // JPN MSET
|
||||
case 0x0004001000022000LL: // EUR MSET
|
||||
case 0x0004001000026000LL: // CHN MSET
|
||||
case 0x0004001000027000LL: // KOR MSET
|
||||
case 0x0004001000028000LL: // TWN MSET
|
||||
{
|
||||
if(CONFIG(PATCHVERSTRING))
|
||||
{
|
||||
static const u16 verPattern[] = u"Ver.";
|
||||
static u16 *verString;
|
||||
u32 verStringSize = 0;
|
||||
|
||||
u16 customVerString[19];
|
||||
loadCustomVerString(customVerString, &verStringSize);
|
||||
|
||||
if(verStringSize != 0) verString = customVerString;
|
||||
else
|
||||
{
|
||||
verStringSize = 8;
|
||||
u32 currentNand = BOOTCFG_NAND,
|
||||
currentFirm = BOOTCFG_FIRM;
|
||||
bool matchingFirm = (currentFirm != 0) == (currentNand != 0);
|
||||
|
||||
static u16 verStringEmu[] = u"Emu ",
|
||||
verStringEmuSys[] = u"Em S",
|
||||
verStringSysEmu[] = u"SyE ";
|
||||
|
||||
switch(currentNand)
|
||||
{
|
||||
case 1:
|
||||
verString = matchingFirm ? u" Emu" : u"EmuS";
|
||||
break;
|
||||
case 2:
|
||||
case 3:
|
||||
case 4:
|
||||
{
|
||||
if(matchingFirm)
|
||||
{
|
||||
verStringEmu[3] = '0' + currentNand;
|
||||
verString = verStringEmu;
|
||||
}
|
||||
else
|
||||
{
|
||||
verStringEmuSys[2] = '0' + currentNand;
|
||||
verString = verStringEmuSys;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
if(matchingFirm) verString = u" Sys";
|
||||
else
|
||||
{
|
||||
if(currentFirm == 1) verString = u"SysE";
|
||||
else
|
||||
{
|
||||
verStringSysEmu[3] = '0' + currentFirm;
|
||||
verString = verStringSysEmu;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//Patch Ver. string
|
||||
patchMemory(code, size,
|
||||
verPattern,
|
||||
sizeof(verPattern) - 2, 0,
|
||||
verString,
|
||||
verStringSize, 1
|
||||
);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x0004013000008002LL: // NS
|
||||
{
|
||||
static const u8 stopCartUpdatesPattern[] = {
|
||||
0x0C, 0x18, 0xE1, 0xD8
|
||||
};
|
||||
static const u8 stopCartUpdatesPatch[] = {
|
||||
0x0B, 0x18, 0x21, 0xC8
|
||||
};
|
||||
|
||||
//Disable updates from foreign carts (makes carts region-free)
|
||||
patchMemory(code, size,
|
||||
stopCartUpdatesPattern,
|
||||
sizeof(stopCartUpdatesPattern), 0,
|
||||
stopCartUpdatesPatch,
|
||||
sizeof(stopCartUpdatesPatch), 2
|
||||
);
|
||||
|
||||
u32 cpuSetting = MULTICONFIG(NEWCPU);
|
||||
|
||||
if(cpuSetting != 0)
|
||||
{
|
||||
static const u8 cfgN3dsCpuPattern[] = {
|
||||
0x00, 0x40, 0xA0, 0xE1, 0x07
|
||||
};
|
||||
|
||||
u32 *cfgN3dsCpuLoc = (u32 *)memsearch(code, cfgN3dsCpuPattern, size, sizeof(cfgN3dsCpuPattern));
|
||||
|
||||
//Patch N3DS CPU Clock and L2 cache setting
|
||||
if(cfgN3dsCpuLoc != NULL)
|
||||
{
|
||||
*(cfgN3dsCpuLoc + 1) = 0xE1A00000;
|
||||
*(cfgN3dsCpuLoc + 8) = 0xE3A00000 | cpuSetting;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x0004013000001702LL: // CFG
|
||||
{
|
||||
static const u8 secureinfoSigCheckPattern[] = {
|
||||
0x06, 0x46, 0x10, 0x48
|
||||
};
|
||||
static const u8 secureinfoSigCheckPatch[] = {
|
||||
0x00, 0x26
|
||||
};
|
||||
|
||||
//Disable SecureInfo signature check
|
||||
patchMemory(code, size,
|
||||
secureinfoSigCheckPattern,
|
||||
sizeof(secureinfoSigCheckPattern), 0,
|
||||
secureinfoSigCheckPatch,
|
||||
sizeof(secureinfoSigCheckPatch), 1
|
||||
);
|
||||
|
||||
if(secureInfoExists())
|
||||
{
|
||||
static const u16 secureinfoFilenamePattern[] = u"SecureInfo_";
|
||||
static const u16 secureinfoFilenamePatch[] = u"C";
|
||||
|
||||
//Use SecureInfo_C
|
||||
patchMemory(code, size,
|
||||
secureinfoFilenamePattern,
|
||||
sizeof(secureinfoFilenamePattern) - 2,
|
||||
sizeof(secureinfoFilenamePattern) - 2,
|
||||
secureinfoFilenamePatch,
|
||||
sizeof(secureinfoFilenamePatch) - 2, 2
|
||||
);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x0004013000003702LL: // RO
|
||||
{
|
||||
static const u8 sigCheckPattern[] = {
|
||||
0x30, 0x40, 0x2D, 0xE9, 0x02
|
||||
};
|
||||
static const u8 sha256ChecksPattern1[] = {
|
||||
0x30, 0x40, 0x2D, 0xE9, 0x24
|
||||
};
|
||||
static const u8 sha256ChecksPattern2[] = {
|
||||
0xF8, 0x4F, 0x2D, 0xE9, 0x01
|
||||
};
|
||||
|
||||
static const u8 stub[] = {
|
||||
0x00, 0x00, 0xA0, 0xE3, 0x1E, 0xFF, 0x2F, 0xE1 // mov r0, #0; bx lr
|
||||
};
|
||||
|
||||
//Disable CRR0 signature (RSA2048 with SHA256) check
|
||||
patchMemory(code, size,
|
||||
sigCheckPattern,
|
||||
sizeof(sigCheckPattern), 0,
|
||||
stub,
|
||||
sizeof(stub), 1
|
||||
);
|
||||
|
||||
//Disable CRO0/CRR0 SHA256 hash checks (section hashes, and hash table)
|
||||
patchMemory(code, size,
|
||||
sha256ChecksPattern1,
|
||||
sizeof(sha256ChecksPattern1), 0,
|
||||
stub,
|
||||
sizeof(stub), 1
|
||||
);
|
||||
|
||||
patchMemory(code, size,
|
||||
sha256ChecksPattern2,
|
||||
sizeof(sha256ChecksPattern2), 0,
|
||||
stub,
|
||||
sizeof(stub), 1
|
||||
);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef DEV
|
||||
case 0x0004003000008A02LL: // ErrDisp
|
||||
{
|
||||
if(MULTICONFIG(DEVOPTIONS) == 0)
|
||||
{
|
||||
static const u8 unitinfoCheckPattern1[] = {
|
||||
0x14, 0x00, 0xD0, 0xE5, 0xDB
|
||||
};
|
||||
|
||||
static const u8 unitinfoCheckPattern2[] = {
|
||||
0x14, 0x00, 0xD0, 0xE5, 0x01
|
||||
} ;
|
||||
|
||||
static const u8 unitinfoCheckPatch[] = {
|
||||
0x00, 0x00, 0xA0, 0xE3
|
||||
} ;
|
||||
|
||||
patchMemory(code, size,
|
||||
unitinfoCheckPattern1,
|
||||
sizeof(unitinfoCheckPattern1), 0,
|
||||
unitinfoCheckPatch,
|
||||
sizeof(unitinfoCheckPatch), 1
|
||||
);
|
||||
|
||||
patchMemory(code, size,
|
||||
unitinfoCheckPattern2,
|
||||
sizeof(unitinfoCheckPattern2), 0,
|
||||
unitinfoCheckPatch,
|
||||
sizeof(unitinfoCheckPatch), 3
|
||||
);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
default:
|
||||
if(CONFIG(USELANGEMUANDCODE))
|
||||
{
|
||||
if((u32)((progId & 0xFFFFFFF000000000LL) >> 0x24) == 0x0004000)
|
||||
{
|
||||
//External .code section loading
|
||||
loadTitleCodeSection(progId, code, size);
|
||||
|
||||
//Language emulation
|
||||
u8 regionId = 0xFF,
|
||||
languageId = 0xFF;
|
||||
loadTitleLocaleConfig(progId, ®ionId, &languageId);
|
||||
|
||||
if(regionId != 0xFF || regionId != 0xFF)
|
||||
{
|
||||
u32 CFGUHandleOffset;
|
||||
u8 *CFGU_GetConfigInfoBlk2_endPos = getCfgOffsets(code, size, &CFGUHandleOffset);
|
||||
|
||||
if(CFGU_GetConfigInfoBlk2_endPos != NULL)
|
||||
{
|
||||
if(languageId != 0xFF) patchCfgGetLanguage(code, size, languageId, CFGU_GetConfigInfoBlk2_endPos);
|
||||
if(regionId != 0xFF) patchCfgGetRegion(code, size, regionId, CFGUHandleOffset);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <3ds/types.h>
|
||||
|
||||
#define CONFIG(a) (((info.config >> (a + 21)) & 1) != 0)
|
||||
#define MULTICONFIG(a) ((info.config >> (a * 2 + 9)) & 3)
|
||||
#define BOOTCONFIG(a, b) ((info.config >> a) & b)
|
||||
|
||||
#define BOOTCFG_NAND BOOTCONFIG(0, 7)
|
||||
#define BOOTCFG_FIRM BOOTCONFIG(3, 7)
|
||||
#define BOOTCFG_A9LH BOOTCONFIG(6, 1)
|
||||
#define BOOTCFG_NOFORCEFLAG BOOTCONFIG(7, 1)
|
||||
#define BOOTCFG_SAFEMODE BOOTCONFIG(8, 1)
|
||||
|
||||
enum multiOptions
|
||||
{
|
||||
DEFAULTEMU = 0,
|
||||
BRIGHTNESS,
|
||||
PIN,
|
||||
NEWCPU
|
||||
#ifdef DEV
|
||||
, DEVOPTIONS
|
||||
#endif
|
||||
};
|
||||
|
||||
enum singleOptions
|
||||
{
|
||||
AUTOBOOTSYS = 0,
|
||||
USESYSFIRM,
|
||||
USELANGEMUANDCODE,
|
||||
PATCHVERSTRING,
|
||||
SHOWGBABOOT,
|
||||
PAYLOADSPLASH
|
||||
#ifdef DEV
|
||||
, PATCHACCESS
|
||||
#endif
|
||||
};
|
||||
|
||||
void patchCode(u64 progId, u8 *code, u32 size);
|
||||
47
k11_extension/Makefile
Normal file
47
k11_extension/Makefile
Normal file
@@ -0,0 +1,47 @@
|
||||
rwildcard = $(foreach d, $(wildcard $1*), $(filter $(subst *, %, $2), $d) $(call rwildcard, $d/, $2))
|
||||
|
||||
ifeq ($(strip $(DEVKITARM)),)
|
||||
$(error "Please set DEVKITARM in your environment. export DEVKITARM=<path to>devkitARM")
|
||||
endif
|
||||
|
||||
include $(DEVKITARM)/base_tools
|
||||
|
||||
name := k11_extension
|
||||
|
||||
dir_source := source
|
||||
dir_include := include
|
||||
dir_build := build
|
||||
|
||||
ARCH := -mcpu=mpcore -mfpu=vfp
|
||||
ASFLAGS := $(ARCH)
|
||||
CFLAGS := -Wall -Wextra -MMD -MP -marm $(ASFLAGS) -I$(dir_include) -fno-builtin -std=c11 -Wno-main -g -flto -O2 -ffast-math \
|
||||
-mword-relocations -ffunction-sections -fdata-sections
|
||||
LDFLAGS := -nostdlib -Wl,--gc-sections,--nmagic $(ARCH)
|
||||
|
||||
objects = $(patsubst $(dir_source)/%.s, $(dir_build)/%.o, \
|
||||
$(patsubst $(dir_source)/%.c, $(dir_build)/%.o, \
|
||||
$(call rwildcard, $(dir_source), *.s *.c)))
|
||||
|
||||
.PHONY: all
|
||||
all: ../$(dir_build)/$(name).bin
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
@rm -rf $(dir_build)
|
||||
|
||||
../$(dir_build)/$(name).bin: $(dir_build)/$(name).elf
|
||||
$(OBJCOPY) -S -O binary $< $@
|
||||
|
||||
$(dir_build)/$(name).elf: $(objects)
|
||||
$(CC) $(LDFLAGS) -T linker.ld $(OUTPUT_OPTION) $^
|
||||
|
||||
$(dir_build)/memory.o : CFLAGS += -O3 -marm
|
||||
|
||||
$(dir_build)/%.o: $(dir_source)/%.c
|
||||
@mkdir -p "$(@D)"
|
||||
$(COMPILE.c) $(OUTPUT_OPTION) $<
|
||||
|
||||
$(dir_build)/%.o: $(dir_source)/%.s
|
||||
@mkdir -p "$(@D)"
|
||||
$(COMPILE.s) $(OUTPUT_OPTION) $<
|
||||
include $(call rwildcard, $(dir_build), *.d)
|
||||
37
k11_extension/include/config.h
Normal file
37
k11_extension/include/config.h
Normal file
@@ -0,0 +1,37 @@
|
||||
#pragma once
|
||||
|
||||
#include "types.h"
|
||||
|
||||
#define MAKE_BRANCH(src,dst) (0xEA000000 | ((u32)((((u8 *)(dst) - (u8 *)(src)) >> 2) - 2) & 0xFFFFFF))
|
||||
#define MAKE_BRANCH_LINK(src,dst) (0xEB000000 | ((u32)((((u8 *)(dst) - (u8 *)(src)) >> 2) - 2) & 0xFFFFFF))
|
||||
|
||||
#define CONFIG(a) (((cfwInfo.config >> (a)) & 1) != 0)
|
||||
#define MULTICONFIG(a) ((cfwInfo.multiConfig >> (2 * (a))) & 3)
|
||||
#define BOOTCONFIG(a, b) ((cfwInfo.bootConfig >> (a)) & (b))
|
||||
|
||||
#define BOOTCFG_NAND BOOTCONFIG(0, 7)
|
||||
#define BOOTCFG_FIRM BOOTCONFIG(3, 7)
|
||||
#define BOOTCFG_NOFORCEFLAG BOOTCONFIG(6, 1)
|
||||
#define BOOTCFG_NTRCARDBOOT BOOTCONFIG(7, 1)
|
||||
|
||||
enum multiOptions
|
||||
{
|
||||
DEFAULTEMU = 0,
|
||||
BRIGHTNESS,
|
||||
SPLASH,
|
||||
SPLASH_DURATION,
|
||||
PIN,
|
||||
NEWCPU
|
||||
};
|
||||
|
||||
enum singleOptions
|
||||
{
|
||||
AUTOBOOTEMU = 0,
|
||||
USEEMUFIRM,
|
||||
LOADEXTFIRMSANDMODULES,
|
||||
PATCHGAMES,
|
||||
PATCHVERSTRING,
|
||||
SHOWGBABOOT,
|
||||
PATCHUNITINFO,
|
||||
DISABLEARM11EXCHANDLERS
|
||||
};
|
||||
39
k11_extension/include/debug.h
Normal file
39
k11_extension/include/debug.h
Normal file
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* This file is part of Luma3DS
|
||||
* Copyright (C) 2016-2017 Aurora Wright, TuxSH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
|
||||
* * Requiring preservation of specified reasonable legal notices or
|
||||
* author attributions in that material or in the Appropriate Legal
|
||||
* Notices displayed by works containing it.
|
||||
* * Prohibiting misrepresentation of the origin of that material,
|
||||
* or requiring that modified versions of such material be marked in
|
||||
* reasonable ways as different from the original version.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "types.h"
|
||||
#include "globals.h"
|
||||
#include "kernel.h"
|
||||
#include "utils.h"
|
||||
|
||||
extern KRecursiveLock dbgParamsLock;
|
||||
extern u32 dbgParamWatchpointId, dbgParamDVA, dbgParamWCR, dbgParamContextId;
|
||||
|
||||
KSchedulableInterruptEvent *enableMonitorModeDebugging(KBaseInterruptEvent *this, u32 interruptID);
|
||||
KSchedulableInterruptEvent *disableWatchpoint(KBaseInterruptEvent *this, u32 interruptID);
|
||||
KSchedulableInterruptEvent *setWatchpointWithContextId(KBaseInterruptEvent *this, u32 interruptID);
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Luma3DS
|
||||
* Copyright (C) 2016 Aurora Wright, TuxSH
|
||||
* Copyright (C) 2016-2017 Aurora Wright, TuxSH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -15,15 +15,27 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Additional Terms 7.b of GPLv3 applies to this file: Requiring preservation of specified
|
||||
* reasonable legal notices or author attributions in that material or in the Appropriate Legal
|
||||
* Notices displayed by works containing it.
|
||||
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
|
||||
* * Requiring preservation of specified reasonable legal notices or
|
||||
* author attributions in that material or in the Appropriate Legal
|
||||
* Notices displayed by works containing it.
|
||||
* * Prohibiting misrepresentation of the origin of that material,
|
||||
* or requiring that modified versions of such material be marked in
|
||||
* reasonable ways as different from the original version.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "types.h"
|
||||
|
||||
bool isExceptionFatal(u32 spsr, u32 *regs, u32 index);
|
||||
bool isDataAbortExceptionRangeControlled(u32 spsr, u32 addr);
|
||||
|
||||
void FIQHandler(void);
|
||||
void undefinedInstructionHandler(void);
|
||||
void prefetchAbortHandler(void);
|
||||
void dataAbortHandler(void);
|
||||
|
||||
typedef struct __attribute__((packed))
|
||||
{
|
||||
u32 magic[2];
|
||||
@@ -38,11 +50,3 @@ typedef struct __attribute__((packed))
|
||||
u32 stackDumpSize;
|
||||
u32 additionalDataSize;
|
||||
} ExceptionDumpHeader;
|
||||
|
||||
void __attribute__((noreturn)) mcuReboot(void);
|
||||
void cleanInvalidateDCacheAndDMB(void);
|
||||
bool cannotAccessVA(const void *address);
|
||||
void FIQHandler(void);
|
||||
void undefinedInstructionHandler(void);
|
||||
void dataAbortHandler(void);
|
||||
void prefetchAbortHandler(void);
|
||||
137
k11_extension/include/globals.h
Normal file
137
k11_extension/include/globals.h
Normal file
@@ -0,0 +1,137 @@
|
||||
/*
|
||||
* This file is part of Luma3DS
|
||||
* Copyright (C) 2016-2017 Aurora Wright, TuxSH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
|
||||
* * Requiring preservation of specified reasonable legal notices or
|
||||
* author attributions in that material or in the Appropriate Legal
|
||||
* Notices displayed by works containing it.
|
||||
* * Prohibiting misrepresentation of the origin of that material,
|
||||
* or requiring that modified versions of such material be marked in
|
||||
* reasonable ways as different from the original version.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "config.h"
|
||||
#include "kernel.h"
|
||||
|
||||
extern KRecursiveLock *criticalSectionLock;
|
||||
extern KObjectList *threadList;
|
||||
extern KObjectMutex *synchronizationMutex;
|
||||
|
||||
extern void (*KRecursiveLock__Lock)(KRecursiveLock *this);
|
||||
extern void (*KRecursiveLock__Unlock)(KRecursiveLock *this);
|
||||
|
||||
extern void (*KAutoObject__AddReference)(KAutoObject *this);
|
||||
|
||||
extern KProcess * (*KProcessHandleTable__ToKProcess)(KProcessHandleTable *this, Handle processHandle);
|
||||
extern KThread * (*KProcessHandleTable__ToKThread)(KProcessHandleTable *this, Handle threadHandle);
|
||||
extern KAutoObject * (*KProcessHandleTable__ToKAutoObject)(KProcessHandleTable *this, Handle handle);
|
||||
extern void (*KSynchronizationObject__Signal)(KSynchronizationObject *this, bool isPulse);
|
||||
extern Result (*WaitSynchronization1)(void *this_unused, KThread *thread, KSynchronizationObject *syncObject, s64 timeout);
|
||||
extern Result (*KProcessHandleTable__CreateHandle)(KProcessHandleTable *this, Handle *out, KAutoObject *obj, u8 token);
|
||||
extern Result (*KProcessHwInfo__MapProcessMemory)(KProcessHwInfo *this, KProcessHwInfo *other, void *dst, void *src, u32 nbPages);
|
||||
extern Result (*KProcessHwInfo__UnmapProcessMemory)(KProcessHwInfo *this, void *addr, u32 nbPages);
|
||||
extern Result (*KEvent__Clear)(KEvent *this);
|
||||
extern void (*KObjectMutex__WaitAndAcquire)(KObjectMutex *this);
|
||||
extern void (*KObjectMutex__ErrorOccured)(void);
|
||||
|
||||
extern void (*KScheduler__AdjustThread)(KScheduler *this, KThread *thread, u32 oldSchedulingMask);
|
||||
extern void (*KScheduler__AttemptSwitchingThreadContext)(KScheduler *this);
|
||||
|
||||
extern Result (*ControlMemory)(u32 *addrOut, u32 addr0, u32 addr1, u32 size, MemOp op, MemPerm perm, bool isLoader);
|
||||
extern void (*SleepThread)(s64 ns);
|
||||
extern Result (*CloseHandle)(Handle handle);
|
||||
extern Result (*GetHandleInfo)(s64 *out, Handle handle, u32 type);
|
||||
extern Result (*GetSystemInfo)(s64 *out, s32 type, s32 param);
|
||||
extern Result (*GetProcessInfo)(s64 *out, Handle processHandle, u32 type);
|
||||
extern Result (*GetThreadInfo)(s64 *out, Handle threadHandle, u32 type);
|
||||
extern Result (*ConnectToPort)(Handle *out, const char *name);
|
||||
extern Result (*SendSyncRequest)(Handle handle);
|
||||
extern Result (*OpenProcess)(Handle *out, u32 processId);
|
||||
extern Result (*GetProcessId)(u32 *out, Handle process);
|
||||
extern Result (*DebugActiveProcess)(Handle *out, u32 processId);
|
||||
extern Result (*UnmapProcessMemory)(Handle processHandle, void *dst, u32 size);
|
||||
extern Result (*KernelSetState)(u32 type, u32 varg1, u32 varg2, u32 varg3);
|
||||
|
||||
extern void (*flushDataCacheRange)(void *addr, u32 len);
|
||||
extern void (*invalidateInstructionCacheRange)(void *addr, u32 len);
|
||||
|
||||
extern bool (*usrToKernelMemcpy8)(void *dst, const void *src, u32 len);
|
||||
extern bool (*usrToKernelMemcpy32)(u32 *dst, const u32 *src, u32 len);
|
||||
extern s32 (*usrToKernelStrncpy)(char *dst, const char *src, u32 len);
|
||||
extern bool (*kernelToUsrMemcpy8)(void *dst, const void *src, u32 len);
|
||||
extern bool (*kernelToUsrMemcpy32)(u32 *dst, const u32 *src, u32 len);
|
||||
extern s32 (*kernelToUsrStrncpy)(char *dst, const char *src, u32 len);
|
||||
|
||||
extern void (*svcFallbackHandler)(u8 svcId);
|
||||
extern void (*kernelpanic)(void);
|
||||
extern void (*officialPostProcessSvc)(void);
|
||||
|
||||
extern Result (*SignalDebugEvent)(DebugEventType type, u32 info, ...);
|
||||
|
||||
extern bool isN3DS;
|
||||
extern u32 *exceptionStackTop;
|
||||
|
||||
extern u32 TTBCR;
|
||||
extern u32 L1MMUTableAddrs[4];
|
||||
|
||||
extern void *kernelUsrCopyFuncsStart, *kernelUsrCopyFuncsEnd;
|
||||
|
||||
extern bool *isDevUnit;
|
||||
|
||||
extern vu8 *configPage;
|
||||
extern u32 kernelVersion;
|
||||
extern FcramLayout fcramLayout;
|
||||
|
||||
extern KCoreContext *coreCtxs;
|
||||
|
||||
extern void *originalHandlers[8];
|
||||
extern u32 nbSection0Modules;
|
||||
|
||||
extern u8 __start__[], __end__[], __bss_start__[], __bss_end__[];
|
||||
|
||||
extern Result (*InterruptManager__MapInterrupt)(InterruptManager *manager, KBaseInterruptEvent *iEvent, u32 interruptID,
|
||||
u32 coreID, u32 priority, bool disableUponReceipt, bool levelHighActive);
|
||||
extern InterruptManager *interruptManager;
|
||||
extern KBaseInterruptEvent *customInterruptEvent;
|
||||
|
||||
extern void (*initFPU)(void);
|
||||
extern void (*mcuReboot)(void);
|
||||
extern void (*coreBarrier)(void);
|
||||
|
||||
typedef struct CfwInfo
|
||||
{
|
||||
char magic[4];
|
||||
|
||||
u8 versionMajor;
|
||||
u8 versionMinor;
|
||||
u8 versionBuild;
|
||||
u8 flags;
|
||||
|
||||
u32 commitHash;
|
||||
|
||||
u16 configFormatVersionMajor, configFormatVersionMinor;
|
||||
u32 config, multiConfig, bootConfig;
|
||||
u64 hbldr3dsxTitleId;
|
||||
u32 rosalinaMenuCombo;
|
||||
} CfwInfo;
|
||||
|
||||
extern CfwInfo cfwInfo;
|
||||
|
||||
extern vu32 rosalinaState;
|
||||
extern bool hasStartedRosalinaNetworkFuncsOnce;
|
||||
61
k11_extension/include/ipc.h
Normal file
61
k11_extension/include/ipc.h
Normal file
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* This file is part of Luma3DS
|
||||
* Copyright (C) 2016-2017 Aurora Wright, TuxSH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
|
||||
* * Requiring preservation of specified reasonable legal notices or
|
||||
* author attributions in that material or in the Appropriate Legal
|
||||
* Notices displayed by works containing it.
|
||||
* * Prohibiting misrepresentation of the origin of that material,
|
||||
* or requiring that modified versions of such material be marked in
|
||||
* reasonable ways as different from the original version.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "types.h"
|
||||
#include "globals.h"
|
||||
#include "kernel.h"
|
||||
#include "utils.h"
|
||||
|
||||
#define MAX_SESSION 345
|
||||
|
||||
// the structure of sessions is apparently not the same on older versions...
|
||||
|
||||
typedef struct SessionInfo
|
||||
{
|
||||
KSession *session;
|
||||
char name[12];
|
||||
} SessionInfo;
|
||||
|
||||
typedef struct LangemuAttributes
|
||||
{
|
||||
u64 titleId;
|
||||
u8 mask, region, language, country, state;
|
||||
} LangemuAttributes;
|
||||
|
||||
extern KRecursiveLock processLangemuLock;
|
||||
extern LangemuAttributes processLangemuAttributes[0x40];
|
||||
|
||||
SessionInfo *SessionInfo_Lookup(KSession *session);
|
||||
SessionInfo *SessionInfo_FindFirst(const char *name);
|
||||
void SessionInfo_ChangeVtable(KSession *session);
|
||||
void SessionInfo_Add(KSession *session, const char *name);
|
||||
void SessionInfo_Remove(KSession *session);
|
||||
|
||||
bool doLangEmu(Result *res, u32 *cmdbuf);
|
||||
Result doPublishToProcessHook(Handle handle, u32 *cmdbuf);
|
||||
bool doErrfThrowHook(u32 *cmdbuf);
|
||||
1224
k11_extension/include/kernel.h
Normal file
1224
k11_extension/include/kernel.h
Normal file
File diff suppressed because it is too large
Load Diff
42
k11_extension/include/memory.h
Normal file
42
k11_extension/include/memory.h
Normal file
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* This file is part of Luma3DS
|
||||
* Copyright (C) 2016-2017 Aurora Wright, TuxSH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
|
||||
* * Requiring preservation of specified reasonable legal notices or
|
||||
* author attributions in that material or in the Appropriate Legal
|
||||
* Notices displayed by works containing it.
|
||||
* * Prohibiting misrepresentation of the origin of that material,
|
||||
* or requiring that modified versions of such material be marked in
|
||||
* reasonable ways as different from the original version.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "types.h"
|
||||
|
||||
void *memcpy(void *dest, const void *src, u32 size) USED;
|
||||
int memcmp(const void *buf1, const void *buf2, u32 size) USED;
|
||||
void *memset(void *dest, u32 value, u32 size) USED; // thanks binutils for the nice bug involving memset.
|
||||
void *memset32(void *dest, u32 value, u32 size);
|
||||
u8 *memsearch(u8 *startPos, const void *pattern, u32 size, u32 patternSize);
|
||||
char *strcpy(char *dest, const char *src);
|
||||
char *strncpy(char *dest, const char *src, u32 size);
|
||||
s32 strnlen(const char *string, s32 maxlen);
|
||||
s32 strlen(const char *string);
|
||||
s32 strcmp(const char *str1, const char *str2);
|
||||
s32 strncmp(const char *str1, const char *str2, u32 size);
|
||||
void hexItoa(u64 number, char *out, u32 digits, bool uppercase);
|
||||
38
k11_extension/include/svc.h
Normal file
38
k11_extension/include/svc.h
Normal file
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* This file is part of Luma3DS
|
||||
* Copyright (C) 2016-2017 Aurora Wright, TuxSH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
|
||||
* * Requiring preservation of specified reasonable legal notices or
|
||||
* author attributions in that material or in the Appropriate Legal
|
||||
* Notices displayed by works containing it.
|
||||
* * Prohibiting misrepresentation of the origin of that material,
|
||||
* or requiring that modified versions of such material be marked in
|
||||
* reasonable ways as different from the original version.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "types.h"
|
||||
#include "globals.h"
|
||||
#include "kernel.h"
|
||||
#include "utils.h"
|
||||
|
||||
extern void *officialSVCs[0x7E];
|
||||
|
||||
void postprocessSvc(void);
|
||||
void svcDefaultHandler(u8 svcId);
|
||||
void *svcHook(u8 *pageEnd);
|
||||
33
k11_extension/include/svc/Backdoor.h
Normal file
33
k11_extension/include/svc/Backdoor.h
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* This file is part of Luma3DS
|
||||
* Copyright (C) 2016-2017 Aurora Wright, TuxSH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
|
||||
* * Requiring preservation of specified reasonable legal notices or
|
||||
* author attributions in that material or in the Appropriate Legal
|
||||
* Notices displayed by works containing it.
|
||||
* * Prohibiting misrepresentation of the origin of that material,
|
||||
* or requiring that modified versions of such material be marked in
|
||||
* reasonable ways as different from the original version.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "utils.h"
|
||||
#include "kernel.h"
|
||||
#include "svc.h"
|
||||
|
||||
void Backdoor(void *function);
|
||||
32
k11_extension/include/svc/Break.h
Normal file
32
k11_extension/include/svc/Break.h
Normal file
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* This file is part of Luma3DS
|
||||
* Copyright (C) 2016-2017 Aurora Wright, TuxSH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
|
||||
* * Requiring preservation of specified reasonable legal notices or
|
||||
* author attributions in that material or in the Appropriate Legal
|
||||
* Notices displayed by works containing it.
|
||||
* * Prohibiting misrepresentation of the origin of that material,
|
||||
* or requiring that modified versions of such material be marked in
|
||||
* reasonable ways as different from the original version.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "utils.h"
|
||||
#include "kernel.h"
|
||||
|
||||
void __attribute__((noreturn)) Break(UserBreakType type, ...);
|
||||
34
k11_extension/include/svc/ConnectToPort.h
Normal file
34
k11_extension/include/svc/ConnectToPort.h
Normal file
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* This file is part of Luma3DS
|
||||
* Copyright (C) 2016-2017 Aurora Wright, TuxSH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
|
||||
* * Requiring preservation of specified reasonable legal notices or
|
||||
* author attributions in that material or in the Appropriate Legal
|
||||
* Notices displayed by works containing it.
|
||||
* * Prohibiting misrepresentation of the origin of that material,
|
||||
* or requiring that modified versions of such material be marked in
|
||||
* reasonable ways as different from the original version.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "utils.h"
|
||||
#include "kernel.h"
|
||||
#include "svc.h"
|
||||
|
||||
Result ConnectToPortHookWrapper(u32 dummy, const char *name);
|
||||
Result ConnectToPortHook(Handle *out, const char *name);
|
||||
35
k11_extension/include/svc/ControlMemory.h
Normal file
35
k11_extension/include/svc/ControlMemory.h
Normal file
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* This file is part of Luma3DS
|
||||
* Copyright (C) 2016-2017 Aurora Wright, TuxSH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
|
||||
* * Requiring preservation of specified reasonable legal notices or
|
||||
* author attributions in that material or in the Appropriate Legal
|
||||
* Notices displayed by works containing it.
|
||||
* * Prohibiting misrepresentation of the origin of that material,
|
||||
* or requiring that modified versions of such material be marked in
|
||||
* reasonable ways as different from the original version.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "utils.h"
|
||||
#include "kernel.h"
|
||||
#include "svc.h"
|
||||
|
||||
Result ControlMemoryHookWrapper(u32 *addrOut, u32 addr0, u32 addr1, u32 size, MemOp op, MemPerm perm);
|
||||
Result ControlMemoryHook(u32 *addrOut, u32 addr0, u32 addr1, u32 size, MemOp op, MemPerm perm);
|
||||
Result ControlMemoryEx(u32 *addrOut, u32 addr0, u32 addr1, u32 size, MemOp op, MemPerm perm, bool isLoader);
|
||||
40
k11_extension/include/svc/ControlService.h
Normal file
40
k11_extension/include/svc/ControlService.h
Normal file
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* This file is part of Luma3DS
|
||||
* Copyright (C) 2016-2017 Aurora Wright, TuxSH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
|
||||
* * Requiring preservation of specified reasonable legal notices or
|
||||
* author attributions in that material or in the Appropriate Legal
|
||||
* Notices displayed by works containing it.
|
||||
* * Prohibiting misrepresentation of the origin of that material,
|
||||
* or requiring that modified versions of such material be marked in
|
||||
* reasonable ways as different from the original version.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "utils.h"
|
||||
#include "kernel.h"
|
||||
#include "svc.h"
|
||||
|
||||
/// Operations for svcControlService
|
||||
typedef enum ServiceOp
|
||||
{
|
||||
SERVICEOP_STEAL_CLIENT_SESSION = 0, ///< Steal a client session given a service or global port name
|
||||
SERVICEOP_GET_NAME, ///< Get the name of a service or global port given a client or session handle
|
||||
} ServiceOp;
|
||||
|
||||
Result ControlService(ServiceOp op, u32 varg1, u32 varg2);
|
||||
34
k11_extension/include/svc/CopyHandle.h
Normal file
34
k11_extension/include/svc/CopyHandle.h
Normal file
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* This file is part of Luma3DS
|
||||
* Copyright (C) 2016-2017 Aurora Wright, TuxSH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
|
||||
* * Requiring preservation of specified reasonable legal notices or
|
||||
* author attributions in that material or in the Appropriate Legal
|
||||
* Notices displayed by works containing it.
|
||||
* * Prohibiting misrepresentation of the origin of that material,
|
||||
* or requiring that modified versions of such material be marked in
|
||||
* reasonable ways as different from the original version.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "utils.h"
|
||||
#include "kernel.h"
|
||||
#include "svc.h"
|
||||
|
||||
Result CopyHandleWrapper(Handle *outHandle, Handle outProcessHandle, Handle inHandle, Handle inProcessHandle);
|
||||
Result CopyHandle(Handle *outHandle, Handle outProcessHandle, Handle inHandle, Handle inProcessHandle);
|
||||
33
k11_extension/include/svc/CustomBackdoor.h
Normal file
33
k11_extension/include/svc/CustomBackdoor.h
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* This file is part of Luma3DS
|
||||
* Copyright (C) 2016-2017 Aurora Wright, TuxSH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
|
||||
* * Requiring preservation of specified reasonable legal notices or
|
||||
* author attributions in that material or in the Appropriate Legal
|
||||
* Notices displayed by works containing it.
|
||||
* * Prohibiting misrepresentation of the origin of that material,
|
||||
* or requiring that modified versions of such material be marked in
|
||||
* reasonable ways as different from the original version.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "utils.h"
|
||||
#include "kernel.h"
|
||||
#include "svc.h"
|
||||
|
||||
void CustomBackdoor(void *function, ...);
|
||||
35
k11_extension/include/svc/GetCFWInfo.h
Normal file
35
k11_extension/include/svc/GetCFWInfo.h
Normal file
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* This file is part of Luma3DS
|
||||
* Copyright (C) 2016-2017 Aurora Wright, TuxSH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
|
||||
* * Requiring preservation of specified reasonable legal notices or
|
||||
* author attributions in that material or in the Appropriate Legal
|
||||
* Notices displayed by works containing it.
|
||||
* * Prohibiting misrepresentation of the origin of that material,
|
||||
* or requiring that modified versions of such material be marked in
|
||||
* reasonable ways as different from the original version.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "utils.h"
|
||||
#include "kernel.h"
|
||||
#include "svc.h"
|
||||
#include "globals.h"
|
||||
|
||||
// DEPRECATED
|
||||
Result GetCFWInfo(CfwInfo *out);
|
||||
34
k11_extension/include/svc/GetHandleInfo.h
Normal file
34
k11_extension/include/svc/GetHandleInfo.h
Normal file
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* This file is part of Luma3DS
|
||||
* Copyright (C) 2016-2017 Aurora Wright, TuxSH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
|
||||
* * Requiring preservation of specified reasonable legal notices or
|
||||
* author attributions in that material or in the Appropriate Legal
|
||||
* Notices displayed by works containing it.
|
||||
* * Prohibiting misrepresentation of the origin of that material,
|
||||
* or requiring that modified versions of such material be marked in
|
||||
* reasonable ways as different from the original version.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "utils.h"
|
||||
#include "kernel.h"
|
||||
#include "svc.h"
|
||||
|
||||
Result GetHandleInfoHookWrapper(u32 dummy, Handle handle, u32 type);
|
||||
Result GetHandleInfoHook(s64 *out, Handle handle, u32 type);
|
||||
34
k11_extension/include/svc/GetProcessInfo.h
Normal file
34
k11_extension/include/svc/GetProcessInfo.h
Normal file
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* This file is part of Luma3DS
|
||||
* Copyright (C) 2016-2017 Aurora Wright, TuxSH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
|
||||
* * Requiring preservation of specified reasonable legal notices or
|
||||
* author attributions in that material or in the Appropriate Legal
|
||||
* Notices displayed by works containing it.
|
||||
* * Prohibiting misrepresentation of the origin of that material,
|
||||
* or requiring that modified versions of such material be marked in
|
||||
* reasonable ways as different from the original version.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "utils.h"
|
||||
#include "kernel.h"
|
||||
#include "svc.h"
|
||||
|
||||
Result GetProcessInfoHookWrapper(u32 dummy, Handle processHandle, u32 type);
|
||||
Result GetProcessInfoHook(s64 *out, Handle processHandle, u32 type);
|
||||
34
k11_extension/include/svc/GetSystemInfo.h
Normal file
34
k11_extension/include/svc/GetSystemInfo.h
Normal file
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* This file is part of Luma3DS
|
||||
* Copyright (C) 2016-2017 Aurora Wright, TuxSH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
|
||||
* * Requiring preservation of specified reasonable legal notices or
|
||||
* author attributions in that material or in the Appropriate Legal
|
||||
* Notices displayed by works containing it.
|
||||
* * Prohibiting misrepresentation of the origin of that material,
|
||||
* or requiring that modified versions of such material be marked in
|
||||
* reasonable ways as different from the original version.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "utils.h"
|
||||
#include "kernel.h"
|
||||
#include "svc.h"
|
||||
|
||||
Result GetSystemInfoHookWrapper(u32 dummy, s32 type, s32 param);
|
||||
Result GetSystemInfoHook(s64 *out, s32 type, s32 param);
|
||||
34
k11_extension/include/svc/GetThreadInfo.h
Normal file
34
k11_extension/include/svc/GetThreadInfo.h
Normal file
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* This file is part of Luma3DS
|
||||
* Copyright (C) 2016-2017 Aurora Wright, TuxSH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
|
||||
* * Requiring preservation of specified reasonable legal notices or
|
||||
* author attributions in that material or in the Appropriate Legal
|
||||
* Notices displayed by works containing it.
|
||||
* * Prohibiting misrepresentation of the origin of that material,
|
||||
* or requiring that modified versions of such material be marked in
|
||||
* reasonable ways as different from the original version.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "utils.h"
|
||||
#include "kernel.h"
|
||||
#include "svc.h"
|
||||
|
||||
Result GetThreadInfoHookWrapper(u32 dummy, Handle threadHandle, u32 type);
|
||||
Result GetThreadInfoHook(s64 *out, Handle threadHandle, u32 type);
|
||||
34
k11_extension/include/svc/KernelSetState.h
Normal file
34
k11_extension/include/svc/KernelSetState.h
Normal file
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* This file is part of Luma3DS
|
||||
* Copyright (C) 2016-2017 Aurora Wright, TuxSH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
|
||||
* * Requiring preservation of specified reasonable legal notices or
|
||||
* author attributions in that material or in the Appropriate Legal
|
||||
* Notices displayed by works containing it.
|
||||
* * Prohibiting misrepresentation of the origin of that material,
|
||||
* or requiring that modified versions of such material be marked in
|
||||
* reasonable ways as different from the original version.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "utils.h"
|
||||
#include "kernel.h"
|
||||
#include "svc.h"
|
||||
|
||||
bool shouldSignalSyscallDebugEvent(KProcess *process, u8 svcId);
|
||||
Result KernelSetStateHook(u32 type, u32 varg1, u32 varg2, u32 varg3);
|
||||
33
k11_extension/include/svc/MapProcessMemoryEx.h
Normal file
33
k11_extension/include/svc/MapProcessMemoryEx.h
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* This file is part of Luma3DS
|
||||
* Copyright (C) 2016-2017 Aurora Wright, TuxSH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
|
||||
* * Requiring preservation of specified reasonable legal notices or
|
||||
* author attributions in that material or in the Appropriate Legal
|
||||
* Notices displayed by works containing it.
|
||||
* * Prohibiting misrepresentation of the origin of that material,
|
||||
* or requiring that modified versions of such material be marked in
|
||||
* reasonable ways as different from the original version.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "utils.h"
|
||||
#include "kernel.h"
|
||||
#include "svc.h"
|
||||
|
||||
Result MapProcessMemoryEx(Handle processHandle, void *dst, void *src, u32 size);
|
||||
33
k11_extension/include/svc/SendSyncRequest.h
Normal file
33
k11_extension/include/svc/SendSyncRequest.h
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* This file is part of Luma3DS
|
||||
* Copyright (C) 2016-2017 Aurora Wright, TuxSH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
|
||||
* * Requiring preservation of specified reasonable legal notices or
|
||||
* author attributions in that material or in the Appropriate Legal
|
||||
* Notices displayed by works containing it.
|
||||
* * Prohibiting misrepresentation of the origin of that material,
|
||||
* or requiring that modified versions of such material be marked in
|
||||
* reasonable ways as different from the original version.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "utils.h"
|
||||
#include "kernel.h"
|
||||
#include "svc.h"
|
||||
|
||||
Result SendSyncRequestHook(Handle handle);
|
||||
33
k11_extension/include/svc/SetGpuProt.h
Normal file
33
k11_extension/include/svc/SetGpuProt.h
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* This file is part of Luma3DS
|
||||
* Copyright (C) 2016-2017 Aurora Wright, TuxSH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
|
||||
* * Requiring preservation of specified reasonable legal notices or
|
||||
* author attributions in that material or in the Appropriate Legal
|
||||
* Notices displayed by works containing it.
|
||||
* * Prohibiting misrepresentation of the origin of that material,
|
||||
* or requiring that modified versions of such material be marked in
|
||||
* reasonable ways as different from the original version.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "utils.h"
|
||||
#include "kernel.h"
|
||||
#include "svc.h"
|
||||
|
||||
Result SetGpuProt(bool prot);
|
||||
33
k11_extension/include/svc/SetWifiEnabled.h
Normal file
33
k11_extension/include/svc/SetWifiEnabled.h
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* This file is part of Luma3DS
|
||||
* Copyright (C) 2016-2017 Aurora Wright, TuxSH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
|
||||
* * Requiring preservation of specified reasonable legal notices or
|
||||
* author attributions in that material or in the Appropriate Legal
|
||||
* Notices displayed by works containing it.
|
||||
* * Prohibiting misrepresentation of the origin of that material,
|
||||
* or requiring that modified versions of such material be marked in
|
||||
* reasonable ways as different from the original version.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "utils.h"
|
||||
#include "kernel.h"
|
||||
#include "svc.h"
|
||||
|
||||
Result SetWifiEnabled(bool enable);
|
||||
34
k11_extension/include/svc/TranslateHandle.h
Normal file
34
k11_extension/include/svc/TranslateHandle.h
Normal file
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* This file is part of Luma3DS
|
||||
* Copyright (C) 2016-2017 Aurora Wright, TuxSH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
|
||||
* * Requiring preservation of specified reasonable legal notices or
|
||||
* author attributions in that material or in the Appropriate Legal
|
||||
* Notices displayed by works containing it.
|
||||
* * Prohibiting misrepresentation of the origin of that material,
|
||||
* or requiring that modified versions of such material be marked in
|
||||
* reasonable ways as different from the original version.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "utils.h"
|
||||
#include "kernel.h"
|
||||
#include "svc.h"
|
||||
|
||||
Result TranslateHandleWrapper(u32 *outKAddr, char *outClassName, Handle handle);
|
||||
Result TranslateHandle(u32 *outKAddr, char *outClassName, Handle handle);
|
||||
33
k11_extension/include/svc/UnmapProcessMemoryEx.h
Normal file
33
k11_extension/include/svc/UnmapProcessMemoryEx.h
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* This file is part of Luma3DS
|
||||
* Copyright (C) 2016-2017 Aurora Wright, TuxSH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
|
||||
* * Requiring preservation of specified reasonable legal notices or
|
||||
* author attributions in that material or in the Appropriate Legal
|
||||
* Notices displayed by works containing it.
|
||||
* * Prohibiting misrepresentation of the origin of that material,
|
||||
* or requiring that modified versions of such material be marked in
|
||||
* reasonable ways as different from the original version.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "utils.h"
|
||||
#include "kernel.h"
|
||||
#include "svc.h"
|
||||
|
||||
Result UnmapProcessMemoryEx(Handle processHandle, void *dst, u32 size);
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Luma3DS
|
||||
* Copyright (C) 2016 Aurora Wright, TuxSH
|
||||
* Copyright (C) 2016-2017 Aurora Wright, TuxSH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -15,21 +15,15 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Additional Terms 7.b of GPLv3 applies to this file: Requiring preservation of specified
|
||||
* reasonable legal notices or author attributions in that material or in the Appropriate Legal
|
||||
* Notices displayed by works containing it.
|
||||
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
|
||||
* * Requiring preservation of specified reasonable legal notices or
|
||||
* author attributions in that material or in the Appropriate Legal
|
||||
* Notices displayed by works containing it.
|
||||
* * Prohibiting misrepresentation of the origin of that material,
|
||||
* or requiring that modified versions of such material be marked in
|
||||
* reasonable ways as different from the original version.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
//Common data types
|
||||
typedef uint8_t u8;
|
||||
typedef uint16_t u16;
|
||||
typedef uint32_t u32;
|
||||
typedef uint64_t u64;
|
||||
typedef volatile u8 vu8;
|
||||
typedef volatile u16 vu16;
|
||||
typedef volatile u32 vu32;
|
||||
typedef volatile u64 vu64;
|
||||
void svcHandler(void);
|
||||
119
k11_extension/include/synchronization.h
Normal file
119
k11_extension/include/synchronization.h
Normal file
@@ -0,0 +1,119 @@
|
||||
/*
|
||||
* This file is part of Luma3DS
|
||||
* Copyright (C) 2016-2017 Aurora Wright, TuxSH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
|
||||
* * Requiring preservation of specified reasonable legal notices or
|
||||
* author attributions in that material or in the Appropriate Legal
|
||||
* Notices displayed by works containing it.
|
||||
* * Prohibiting misrepresentation of the origin of that material,
|
||||
* or requiring that modified versions of such material be marked in
|
||||
* reasonable ways as different from the original version.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "types.h"
|
||||
#include "kernel.h"
|
||||
|
||||
typedef KSchedulableInterruptEvent* (*SGI0Handler_t)(KBaseInterruptEvent *this, u32 interruptID);
|
||||
|
||||
// http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0360f/CCHDIFIJ.html
|
||||
void executeFunctionOnCores(SGI0Handler_t func, u8 targetList, u8 targetListFilter);
|
||||
|
||||
void KScheduler__TriggerCrossCoreInterrupt(KScheduler *this);
|
||||
void KThread__DebugReschedule(KThread *this, bool lock);
|
||||
bool rosalinaThreadLockPredicate(KThread *thread);
|
||||
void rosalinaRescheduleThread(KThread *thread, bool lock);
|
||||
void rosalinaLockThread(KThread *thread);
|
||||
void rosalinaLockAllThreads(void);
|
||||
void rosalinaUnlockAllThreads(void);
|
||||
|
||||
// Taken from ctrulib:
|
||||
|
||||
static inline void __dsb(void)
|
||||
{
|
||||
__asm__ __volatile__("mcr p15, 0, %[val], c7, c10, 4" :: [val] "r" (0) : "memory");
|
||||
}
|
||||
|
||||
static inline void __clrex(void)
|
||||
{
|
||||
__asm__ __volatile__("clrex" ::: "memory");
|
||||
}
|
||||
|
||||
static inline s32 __ldrex(s32* addr)
|
||||
{
|
||||
s32 val;
|
||||
__asm__ __volatile__("ldrex %[val], %[addr]" : [val] "=r" (val) : [addr] "Q" (*addr));
|
||||
return val;
|
||||
}
|
||||
|
||||
static inline bool __strex(s32* addr, s32 val)
|
||||
{
|
||||
bool res;
|
||||
__asm__ __volatile__("strex %[res], %[val], %[addr]" : [res] "=&r" (res) : [val] "r" (val), [addr] "Q" (*addr));
|
||||
return res;
|
||||
}
|
||||
|
||||
static inline s8 __ldrex8(s8* addr)
|
||||
{
|
||||
s8 val;
|
||||
__asm__ __volatile__("ldrexb %[val], %[addr]" : [val] "=r" (val) : [addr] "Q" (*addr));
|
||||
return val;
|
||||
}
|
||||
|
||||
static inline bool __strex8(s8* addr, s8 val)
|
||||
{
|
||||
bool res;
|
||||
__asm__ __volatile__("strexb %[res], %[val], %[addr]" : [res] "=&r" (res) : [val] "r" (val), [addr] "Q" (*addr));
|
||||
return res;
|
||||
}
|
||||
|
||||
static inline s16 __ldrex16(s16* addr)
|
||||
{
|
||||
s16 val;
|
||||
__asm__ __volatile__("ldrexh %[val], %[addr]" : [val] "=r" (val) : [addr] "Q" (*addr));
|
||||
return val;
|
||||
}
|
||||
|
||||
static inline bool __strex16(s16* addr, s16 val)
|
||||
{
|
||||
bool res;
|
||||
__asm__ __volatile__("strexh %[res], %[val], %[addr]" : [res] "=&r" (res) : [val] "r" (val), [addr] "Q" (*addr));
|
||||
return res;
|
||||
}
|
||||
|
||||
static inline u32 __get_cpsr(void)
|
||||
{
|
||||
u32 cpsr;
|
||||
__asm__ __volatile__("mrs %0, cpsr" : "=r"(cpsr));
|
||||
return cpsr;
|
||||
}
|
||||
|
||||
static inline void __set_cpsr_cx(u32 cpsr)
|
||||
{
|
||||
__asm__ __volatile__("msr cpsr_cx, %0" :: "r"(cpsr));
|
||||
}
|
||||
|
||||
static inline void __enable_irq(void)
|
||||
{
|
||||
__asm__ __volatile__("cpsie i");
|
||||
}
|
||||
|
||||
static inline void __disable_irq(void)
|
||||
{
|
||||
__asm__ __volatile__("cpsid i");
|
||||
}
|
||||
97
k11_extension/include/types.h
Normal file
97
k11_extension/include/types.h
Normal file
@@ -0,0 +1,97 @@
|
||||
/*
|
||||
* This file is part of Luma3DS
|
||||
* Copyright (C) 2016-2017 Aurora Wright, TuxSH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
|
||||
* * Requiring preservation of specified reasonable legal notices or
|
||||
* author attributions in that material or in the Appropriate Legal
|
||||
* Notices displayed by works containing it.
|
||||
* * Prohibiting misrepresentation of the origin of that material,
|
||||
* or requiring that modified versions of such material be marked in
|
||||
* reasonable ways as different from the original version.
|
||||
*/
|
||||
|
||||
// Taken from ctrulib
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
|
||||
/// The maximum value of a u64.
|
||||
#define U64_MAX UINT64_MAX
|
||||
|
||||
/// would be nice if newlib had this already
|
||||
#ifndef SSIZE_MAX
|
||||
#ifdef SIZE_MAX
|
||||
#define SSIZE_MAX ((SIZE_MAX) >> 1)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
typedef uint8_t u8; ///< 8-bit unsigned integer
|
||||
typedef uint16_t u16; ///< 16-bit unsigned integer
|
||||
typedef uint32_t u32; ///< 32-bit unsigned integer
|
||||
typedef uint64_t u64; ///< 64-bit unsigned integer
|
||||
|
||||
typedef int8_t s8; ///< 8-bit signed integer
|
||||
typedef int16_t s16; ///< 16-bit signed integer
|
||||
typedef int32_t s32; ///< 32-bit signed integer
|
||||
typedef int64_t s64; ///< 64-bit signed integer
|
||||
|
||||
typedef volatile u8 vu8; ///< 8-bit volatile unsigned integer.
|
||||
typedef volatile u16 vu16; ///< 16-bit volatile unsigned integer.
|
||||
typedef volatile u32 vu32; ///< 32-bit volatile unsigned integer.
|
||||
typedef volatile u64 vu64; ///< 64-bit volatile unsigned integer.
|
||||
|
||||
typedef volatile s8 vs8; ///< 8-bit volatile signed integer.
|
||||
typedef volatile s16 vs16; ///< 16-bit volatile signed integer.
|
||||
typedef volatile s32 vs32; ///< 32-bit volatile signed integer.
|
||||
typedef volatile s64 vs64; ///< 64-bit volatile signed integer.
|
||||
|
||||
typedef u32 Handle; ///< Resource handle.
|
||||
typedef s32 Result; ///< Function result.
|
||||
|
||||
/// Creates a bitmask from a bit number.
|
||||
#define BIT(n) (1U<<(n))
|
||||
|
||||
/// Aligns a struct (and other types?) to m, making sure that the size of the struct is a multiple of m.
|
||||
#define ALIGN(m) __attribute__((aligned(m)))
|
||||
/// Packs a struct (and other types?) so it won't include padding bytes.
|
||||
#define PACKED __attribute__((packed))
|
||||
#define USED __attribute__((used))
|
||||
#define UNUSED __attribute__((unused))
|
||||
/// Packs a system version from its components.
|
||||
#define SYSTEM_VERSION(major, minor, revision) \
|
||||
(((major)<<24)|((minor)<<16)|((revision)<<8))
|
||||
|
||||
#define CUR_THREAD_HANDLE 0xFFFF8000
|
||||
#define CUR_PROCESS_HANDLE 0xFFFF8001
|
||||
|
||||
#define MPCORE_REGS_BASE (0x17E00000 | (1u << 31))
|
||||
#define MPCORE_SCU_CFG (*(vu32 *)(MPCORE_REGS_BASE + 4))
|
||||
#define MPCORE_INT_ACK (*(vu32 *)(MPCORE_REGS_BASE + 0x10C))
|
||||
|
||||
#define MPCORE_GID_REGS_BASE (MPCORE_REGS_BASE + 0x1000)
|
||||
#define MPCORE_GID_SGI (*(vu32 *)(MPCORE_GID_REGS_BASE + 0xF00))
|
||||
|
||||
#define CFG11_REGS_BASE (0x10140000 | (1u << 31))
|
||||
#define CFG11_WIFICNT (*(vu8 *)(CFG11_REGS_BASE + 0x180))
|
||||
#define CFG11_MPCORE_CFG (*(vu16 *)(CFG11_REGS_BASE + 0xFFC))
|
||||
#define CFG11_MPCORE_CLKCNT (*(vu16 *)(CFG11_REGS_BASE + 0x1300))
|
||||
|
||||
#define L2C_REGS_BASE (0x17E10000 | (1u << 31))
|
||||
#define L2C_CTRL (*(vu32 *)(L2C_REGS_BASE + 0x100))
|
||||
87
k11_extension/include/utils.h
Normal file
87
k11_extension/include/utils.h
Normal file
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* This file is part of Luma3DS
|
||||
* Copyright (C) 2016-2017 Aurora Wright, TuxSH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
|
||||
* * Requiring preservation of specified reasonable legal notices or
|
||||
* author attributions in that material or in the Appropriate Legal
|
||||
* Notices displayed by works containing it.
|
||||
* * Prohibiting misrepresentation of the origin of that material,
|
||||
* or requiring that modified versions of such material be marked in
|
||||
* reasonable ways as different from the original version.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "types.h"
|
||||
#include "kernel.h"
|
||||
|
||||
// For accessing physmem uncached (and directly)
|
||||
#define PA_PTR(addr) (void *)((u32)(addr) | 1u << 31)
|
||||
#define PA_FROM_VA_PTR(addr) PA_PTR(convertVAToPA(addr, false))
|
||||
|
||||
static inline u32 makeARMBranch(const void *src, const void *dst, bool link) // the macros for those are ugly and buggy
|
||||
{
|
||||
u32 instrBase = link ? 0xEB000000 : 0xEA000000;
|
||||
u32 off = (u32)((const u8 *)dst - ((const u8 *)src + 8)); // the PC is always two instructions ahead of the one being executed
|
||||
|
||||
return instrBase | ((off >> 2) & 0xFFFFFF);
|
||||
}
|
||||
|
||||
static inline void *decodeARMBranch(const void *src)
|
||||
{
|
||||
u32 instr = *(const u32 *)src;
|
||||
s32 off = (instr & 0xFFFFFF) << 2;
|
||||
off = (off << 6) >> 6; // sign extend
|
||||
|
||||
return (void *)((const u8 *)src + 8 + off);
|
||||
}
|
||||
|
||||
// For ARM prologs in the form of: push {regs} ... sub sp, #off (this obviously doesn't intend to cover all cases)
|
||||
static inline u32 computeARMFrameSize(const u32 *prolog)
|
||||
{
|
||||
const u32 *off;
|
||||
|
||||
for(off = prolog; (*off >> 16) != 0xE92D; off++); // look for stmfd sp! = push
|
||||
u32 nbPushedRegs = 0;
|
||||
for(u32 val = *off & 0xFFFF; val != 0; val >>= 1) // 1 bit = 1 pushed register
|
||||
nbPushedRegs += val & 1;
|
||||
for(; (*off >> 8) != 0xE24DD0; off++); // look for sub sp, #offset
|
||||
u32 localVariablesSpaceSize = *off & 0xFF;
|
||||
|
||||
return 4 * nbPushedRegs + localVariablesSpaceSize;
|
||||
}
|
||||
|
||||
static inline u32 getNumberOfCores(void)
|
||||
{
|
||||
return (MPCORE_SCU_CFG & 3) + 1;
|
||||
}
|
||||
|
||||
static inline u32 getCurrentCoreID(void)
|
||||
{
|
||||
u32 coreId;
|
||||
__asm__ volatile("mrc p15, 0, %0, c0, c0, 5" : "=r"(coreId));
|
||||
return coreId & 3;
|
||||
}
|
||||
|
||||
u32 convertVAToPA(const void *addr, bool writeCheck);
|
||||
|
||||
u32 safecpy(void *dst, const void *src, u32 len);
|
||||
void KObjectMutex__Acquire(KObjectMutex *this);
|
||||
void KObjectMutex__Release(KObjectMutex *this);
|
||||
|
||||
void flushEntireDataCache(void);
|
||||
void invalidateEntireInstructionCache(void);
|
||||
19
k11_extension/linker.ld
Normal file
19
k11_extension/linker.ld
Normal file
@@ -0,0 +1,19 @@
|
||||
OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")
|
||||
OUTPUT_ARCH(arm)
|
||||
|
||||
ENTRY(_start)
|
||||
SECTIONS
|
||||
{
|
||||
. = 0x40000000;
|
||||
|
||||
__start__ = .;
|
||||
|
||||
.text : ALIGN(4) { *(.text.start) *(.text*); . = ALIGN(4); }
|
||||
.rodata : ALIGN(4) { *(.rodata*); . = ALIGN(4); }
|
||||
.data : ALIGN(4) { *(.data*); . = ALIGN(4); }
|
||||
.bss : ALIGN(8) { __bss_start__ = .; *(.bss* COMMON); . = ALIGN(8); __bss_end__ = .; }
|
||||
|
||||
. = ALIGN(0x1000);
|
||||
|
||||
__end__ = .;
|
||||
}
|
||||
147
k11_extension/source/debug.c
Normal file
147
k11_extension/source/debug.c
Normal file
@@ -0,0 +1,147 @@
|
||||
/*
|
||||
* This file is part of Luma3DS
|
||||
* Copyright (C) 2016-2017 Aurora Wright, TuxSH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
|
||||
* * Requiring preservation of specified reasonable legal notices or
|
||||
* author attributions in that material or in the Appropriate Legal
|
||||
* Notices displayed by works containing it.
|
||||
* * Prohibiting misrepresentation of the origin of that material,
|
||||
* or requiring that modified versions of such material be marked in
|
||||
* reasonable ways as different from the original version.
|
||||
*/
|
||||
|
||||
#include "debug.h"
|
||||
#include "memory.h"
|
||||
#include "synchronization.h"
|
||||
|
||||
KRecursiveLock dbgParamsLock = { NULL };
|
||||
u32 dbgParamWatchpointId, dbgParamDVA, dbgParamWCR, dbgParamContextId;
|
||||
|
||||
KSchedulableInterruptEvent *enableMonitorModeDebugging(KBaseInterruptEvent *this UNUSED, u32 interruptID UNUSED)
|
||||
{
|
||||
coreBarrier();
|
||||
|
||||
u32 DSCR;
|
||||
__asm__ __volatile__("mrc p14, 0, %[val], c0, c1, 0" : [val] "=r" (DSCR));
|
||||
DSCR |= 0x8000;
|
||||
__asm__ __volatile__("mcr p14, 0, %[val], c0, c1, 0" :: [val] "r" (DSCR));
|
||||
|
||||
__dsb();
|
||||
coreBarrier();
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void disableWatchpoint0(void)
|
||||
{
|
||||
u32 control;
|
||||
|
||||
// WCR0
|
||||
__asm__ __volatile__("mrc p14, 0, %[val], c0, c0, 7" : [val] "=r" (control));
|
||||
control &= ~1;
|
||||
__asm__ __volatile__("mcr p14, 0, %[val], c0, c0, 7" :: [val] "r" (control));
|
||||
|
||||
// BCR4
|
||||
__asm__ __volatile__("mrc p14, 0, %[val], c0, c4, 5" : [val] "=r" (control));
|
||||
control &= ~1;
|
||||
__asm__ __volatile__("mcr p14, 0, %[val], c0, c4, 5" :: [val] "r" (control));
|
||||
}
|
||||
|
||||
static void disableWatchpoint1(void)
|
||||
{
|
||||
u32 control;
|
||||
|
||||
// WCR1
|
||||
__asm__ __volatile__("mrc p14, 0, %[val], c0, c1, 7" : [val] "=r" (control));
|
||||
control &= ~1;
|
||||
__asm__ __volatile__("mcr p14, 0, %[val], c0, c1, 7" :: [val] "r" (control));
|
||||
|
||||
// BCR5
|
||||
__asm__ __volatile__("mrc p14, 0, %[val], c0, c5, 5" : [val] "=r" (control));
|
||||
control &= ~1;
|
||||
__asm__ __volatile__("mcr p14, 0, %[val], c0, c5, 5" :: [val] "r" (control));
|
||||
}
|
||||
|
||||
KSchedulableInterruptEvent *disableWatchpoint(KBaseInterruptEvent *this UNUSED, u32 interruptID UNUSED)
|
||||
{
|
||||
coreBarrier();
|
||||
|
||||
if(dbgParamWatchpointId == 0)
|
||||
disableWatchpoint0();
|
||||
else
|
||||
disableWatchpoint1();
|
||||
|
||||
__dsb();
|
||||
coreBarrier();
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void setWatchpoint0WithContextId(u32 DVA, u32 WCR, u32 contextId)
|
||||
{
|
||||
// http://infocenter.arm.com/help/topic/com.arm.doc.ddi0360f/CEGCFFDF.html
|
||||
u32 BCR =
|
||||
(1 << 21) | /* compare with context ID */
|
||||
(1 << 20) | /* linked (with a WRP in our case) */
|
||||
(0xf << 5) | /* byte address select, +0 to +3 as mandated when linking with a WRP */
|
||||
(3 << 1) | /* either privileged modes or user mode, as mandated when linking with a WRP */
|
||||
(1 << 0) ; /* enabled */
|
||||
|
||||
disableWatchpoint0();
|
||||
|
||||
__asm__ __volatile__("mcr p14, 0, %[val], c0, c0, 6" :: [val] "r" (DVA));
|
||||
__asm__ __volatile__("mcr p14, 0, %[val], c0, c4, 4" :: [val] "r" (contextId));
|
||||
__asm__ __volatile__("mcr p14, 0, %[val], c0, c0, 7" :: [val] "r" (WCR));
|
||||
__asm__ __volatile__("mcr p14, 0, %[val], c0, c4, 5" :: [val] "r" (BCR));
|
||||
|
||||
__asm__ __volatile__("mcr p15, 0, %[val], c7, c10, 5" :: [val] "r" (0) : "memory"); // DMB
|
||||
}
|
||||
|
||||
static void setWatchpoint1WithContextId(u32 DVA, u32 WCR, u32 contextId)
|
||||
{
|
||||
// http://infocenter.arm.com/help/topic/com.arm.doc.ddi0360f/CEGCFFDF.html
|
||||
u32 BCR =
|
||||
(1 << 21) | /* compare with context ID */
|
||||
(1 << 20) | /* linked (with a WRP in our case) */
|
||||
(0xf << 5) | /* byte address select, +0 to +3 as mandated when linking with a WRP */
|
||||
(3 << 1) | /* either privileged modes or user mode, as mandated when linking with a WRP */
|
||||
(1 << 0) ; /* enabled */
|
||||
|
||||
disableWatchpoint1();
|
||||
|
||||
__asm__ __volatile__("mcr p14, 0, %[val], c0, c1, 6" :: [val] "r" (DVA));
|
||||
__asm__ __volatile__("mcr p14, 0, %[val], c0, c5, 4" :: [val] "r" (contextId));
|
||||
__asm__ __volatile__("mcr p14, 0, %[val], c0, c1, 7" :: [val] "r" (WCR));
|
||||
__asm__ __volatile__("mcr p14, 0, %[val], c0, c5, 5" :: [val] "r" (BCR));
|
||||
|
||||
__asm__ __volatile__("mcr p15, 0, %[val], c7, c10, 5" :: [val] "r" (0) : "memory"); // DMB
|
||||
}
|
||||
|
||||
KSchedulableInterruptEvent *setWatchpointWithContextId(KBaseInterruptEvent *this UNUSED, u32 interruptID UNUSED)
|
||||
{
|
||||
coreBarrier();
|
||||
|
||||
if(dbgParamWatchpointId == 0)
|
||||
setWatchpoint0WithContextId(dbgParamDVA, dbgParamWCR, dbgParamContextId);
|
||||
else
|
||||
setWatchpoint1WithContextId(dbgParamDVA, dbgParamWCR, dbgParamContextId);
|
||||
|
||||
__dsb();
|
||||
coreBarrier();
|
||||
|
||||
return NULL;
|
||||
}
|
||||
252
k11_extension/source/fatalExceptionHandlers.s
Normal file
252
k11_extension/source/fatalExceptionHandlers.s
Normal file
@@ -0,0 +1,252 @@
|
||||
@ This file is part of Luma3DS
|
||||
@ Copyright (C) 2016-2017 Aurora Wright, TuxSH
|
||||
@
|
||||
@ This program is free software: you can redistribute it and/or modify
|
||||
@ it under the terms of the GNU General Public License as published by
|
||||
@ the Free Software Foundation, either version 3 of the License, or
|
||||
@ (at your option) any later version.
|
||||
@
|
||||
@ This program is distributed in the hope that it will be useful,
|
||||
@ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
@ GNU General Public License for more details.
|
||||
@
|
||||
@ You should have received a copy of the GNU General Public License
|
||||
@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
@
|
||||
@ Additional Terms 7.b and 7.c of GPLv3 apply to this file:
|
||||
@ * Requiring preservation of specified reasonable legal notices or
|
||||
@ author attributions in that material or in the Appropriate Legal
|
||||
@ Notices displayed by works containing it.
|
||||
@ * Prohibiting misrepresentation of the origin of that material,
|
||||
@ or requiring that modified versions of such material be marked in
|
||||
@ reasonable ways as different from the original version.
|
||||
|
||||
.macro TEST_IF_MODE_AND_ARM_INST_OR_JUMP lbl, mode
|
||||
cpsid aif
|
||||
mrs sp, spsr
|
||||
tst sp, #0x20
|
||||
bne \lbl
|
||||
and sp, #0x1f @ get previous processor mode
|
||||
cmp sp, #\mode
|
||||
bne \lbl
|
||||
|
||||
sub sp, lr, #4
|
||||
mcr p15, 0, sp, c7, c8, 0 @ VA to PA translation with privileged read permission check
|
||||
mrc p15, 0, sp, c7, c4, 0 @ read PA register
|
||||
tst sp, #1 @ failure bit
|
||||
bne \lbl
|
||||
.endm
|
||||
|
||||
|
||||
.macro GEN_USUAL_HANDLER name, index, pos
|
||||
\name\()Handler:
|
||||
ldr sp, =exceptionStackTop
|
||||
ldr sp, [sp]
|
||||
sub sp, #0x100
|
||||
|
||||
push {r0-r12, lr}
|
||||
mrs r0, spsr
|
||||
mov r1, sp
|
||||
mov r2, #\index
|
||||
bl isExceptionFatal
|
||||
cmp r0, #0
|
||||
pop {r0-r12, lr}
|
||||
bne _exc_is_fatal_\name
|
||||
|
||||
ldr sp, =originalHandlers
|
||||
ldr sp, [sp, #\pos]
|
||||
bx sp
|
||||
|
||||
_exc_is_fatal_\name:
|
||||
push {r8, r9}
|
||||
mov r8, #\index
|
||||
b _commonHandler
|
||||
.endm
|
||||
|
||||
.text
|
||||
.arm
|
||||
.balign 4
|
||||
|
||||
_die:
|
||||
cpsid aif
|
||||
_die_loop:
|
||||
wfi
|
||||
b _die_loop
|
||||
|
||||
_commonHandler:
|
||||
cpsid aif
|
||||
|
||||
push {r0}
|
||||
ldr r0, =_fatalExceptionOccured
|
||||
ldr r0, [r0]
|
||||
cmp r0, #0
|
||||
bne _die_loop
|
||||
pop {r0}
|
||||
|
||||
ldr r9, =_regs
|
||||
stmia r9, {r0-r7}
|
||||
mov r1, r8
|
||||
pop {r8,r9}
|
||||
|
||||
ldr r0, =_fatalExceptionOccured
|
||||
mov r4, #1
|
||||
|
||||
_try_lock:
|
||||
ldrex r2, [r0]
|
||||
strex r3, r4, [r0]
|
||||
cmp r3, #0
|
||||
bne _try_lock
|
||||
|
||||
push {r1, r12, lr} @ attempt to hang the other cores
|
||||
adr r0, _die
|
||||
mov r1, #0xf
|
||||
mov r2, #1
|
||||
mov r3, #0
|
||||
bl executeFunctionOnCores
|
||||
pop {r1, r12, lr}
|
||||
|
||||
mrs r2, spsr
|
||||
mrs r3, cpsr
|
||||
ldr r6, =_regs
|
||||
add r6, #0x20
|
||||
|
||||
ands r4, r2, #0xf @ get the mode that triggered the exception
|
||||
moveq r4, #0xf @ usr => sys
|
||||
bic r5, r3, #0xf
|
||||
orr r5, r4
|
||||
msr cpsr_c, r5 @ change processor mode
|
||||
stmia r6!, {r8-lr}
|
||||
msr cpsr_c, r3 @ restore processor mode
|
||||
|
||||
str lr, [r6], #4
|
||||
str r2, [r6], #4
|
||||
|
||||
mov r0, r6
|
||||
|
||||
mrc p15, 0, r4, c5, c0, 0 @ dfsr
|
||||
mrc p15, 0, r5, c5, c0, 1 @ ifsr
|
||||
mrc p15, 0, r6, c6, c0, 0 @ far
|
||||
fmrx r7, fpexc
|
||||
fmrx r8, fpinst
|
||||
fmrx r9, fpinst2
|
||||
bic r3, #(1<<31)
|
||||
fmxr fpexc, r3 @ clear the VFP11 exception flag (if it's set)
|
||||
|
||||
stmia r0!, {r4-r9}
|
||||
|
||||
mov r0, #0
|
||||
mcr p15, 0, r0, c7, c14, 0 @ Clean and Invalidate Entire Data Cache
|
||||
mcr p15, 0, r0, c7, c10, 4 @ Drain Synchronization Barrier
|
||||
|
||||
ldr r0, =isN3DS
|
||||
ldrb r0, [r0]
|
||||
cmp r0, #0
|
||||
beq _no_L2C
|
||||
ldr r0, =(0x17e10100 | 1 << 31)
|
||||
ldr r0, [r0]
|
||||
tst r0, #1 @ is the L2C enabled?
|
||||
beq _no_L2C
|
||||
|
||||
ldr r0, =0xffff
|
||||
ldr r2, =(0x17e10730 | 1 << 31)
|
||||
str r0, [r2, #0x4c] @ invalidate by way
|
||||
|
||||
_L2C_sync:
|
||||
ldr r0, [r2] @ L2C cache sync register
|
||||
tst r0, #1
|
||||
bne _L2C_sync
|
||||
|
||||
_no_L2C:
|
||||
|
||||
msr cpsr_cxsf, #0xdf @ finally, switch to system mode, mask interrupts and clear flags (in case of double faults)
|
||||
ldr sp, =exceptionStackTop
|
||||
ldr sp, [sp]
|
||||
sub sp, #0x100
|
||||
|
||||
mov r0, #0
|
||||
mcr p15, 0, r0, c7, c10, 5 @ Drain Memory Barrier
|
||||
ldr r0, =_regs
|
||||
mrc p15, 0, r2, c0, c0, 5 @ CPU ID register
|
||||
bl fatalExceptionHandlersMain
|
||||
|
||||
ldr r12, =mcuReboot
|
||||
ldr r12, [r12]
|
||||
bx r12
|
||||
|
||||
.global FIQHandler
|
||||
.type FIQHandler, %function
|
||||
GEN_USUAL_HANDLER FIQ, 0, 28
|
||||
|
||||
.global undefinedInstructionHandler
|
||||
.type undefinedInstructionHandler, %function
|
||||
undefinedInstructionHandler:
|
||||
TEST_IF_MODE_AND_ARM_INST_OR_JUMP _undefinedInstructionNormalHandler, 0x10
|
||||
|
||||
ldr sp, [lr, #-4] @ test if it's an VFP instruction that was aborted
|
||||
lsl sp, #4
|
||||
sub sp, #0xc0000000
|
||||
cmp sp, #0x30000000
|
||||
bcs _undefinedInstructionNormalHandler
|
||||
fmrx sp, fpexc
|
||||
tst sp, #0x40000000
|
||||
bne _undefinedInstructionNormalHandler
|
||||
|
||||
@ FPU init
|
||||
sub lr, #4
|
||||
srsfd sp!, #0x13
|
||||
cps #0x13
|
||||
stmfd sp, {r0-r3, r11-lr}^
|
||||
sub sp, #0x20
|
||||
ldr r12, =initFPU
|
||||
ldr r12, [r12]
|
||||
blx r12
|
||||
ldmfd sp, {r0-r3, r11-lr}^
|
||||
add sp, #0x20
|
||||
rfefd sp! @ retry aborted instruction
|
||||
|
||||
GEN_USUAL_HANDLER _undefinedInstructionNormal, 1, 4
|
||||
|
||||
.global prefetchAbortHandler
|
||||
.type prefetchAbortHandler, %function
|
||||
prefetchAbortHandler:
|
||||
TEST_IF_MODE_AND_ARM_INST_OR_JUMP _prefetchAbortNormalHandler, 0x13
|
||||
|
||||
ldr sp, =(Break + 3*4 + 4)
|
||||
cmp lr, sp
|
||||
bne _prefetchAbortNormalHandler
|
||||
|
||||
sub sp, r0, #0x110
|
||||
pop {r0-r7, r12, lr}
|
||||
pop {r8-r11}
|
||||
ldr lr, [sp, #8]!
|
||||
ldr sp, [sp, #4]
|
||||
msr spsr_cxsf, sp
|
||||
tst sp, #0x20
|
||||
addne lr, #2 @ adjust address for later
|
||||
|
||||
GEN_USUAL_HANDLER _prefetchAbortNormal, 2, 12
|
||||
|
||||
.global dataAbortHandler
|
||||
.type dataAbortHandler, %function
|
||||
dataAbortHandler:
|
||||
ldr sp, =exceptionStackTop
|
||||
ldr sp, [sp]
|
||||
push {r0-r12, lr}
|
||||
mrs r0, spsr
|
||||
sub r1, lr, #8
|
||||
bl isDataAbortExceptionRangeControlled
|
||||
cmp r0, #0
|
||||
pop {r0-r12, lr}
|
||||
beq _dataAbortNormalHandler
|
||||
|
||||
msr spsr_f, #(1 << 30)
|
||||
mov r12, #0
|
||||
subs pc, lr, #4
|
||||
|
||||
GEN_USUAL_HANDLER _dataAbortNormal, 3, 16
|
||||
|
||||
.bss
|
||||
.balign 4
|
||||
_regs: .skip (4 * 23)
|
||||
_fatalExceptionOccured: .word 0
|
||||
131
k11_extension/source/fatalExceptionHandlersMain.c
Normal file
131
k11_extension/source/fatalExceptionHandlersMain.c
Normal file
@@ -0,0 +1,131 @@
|
||||
/*
|
||||
* This file is part of Luma3DS
|
||||
* Copyright (C) 2016-2017 Aurora Wright, TuxSH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
|
||||
* * Requiring preservation of specified reasonable legal notices or
|
||||
* author attributions in that material or in the Appropriate Legal
|
||||
* Notices displayed by works containing it.
|
||||
* * Prohibiting misrepresentation of the origin of that material,
|
||||
* or requiring that modified versions of such material be marked in
|
||||
* reasonable ways as different from the original version.
|
||||
*/
|
||||
|
||||
#include "fatalExceptionHandlers.h"
|
||||
#include "utils.h"
|
||||
#include "kernel.h"
|
||||
#include "memory.h"
|
||||
#include "globals.h"
|
||||
|
||||
#define REG_DUMP_SIZE 4 * 23
|
||||
#define CODE_DUMP_SIZE 48
|
||||
|
||||
bool isExceptionFatal(u32 spsr, u32 *regs, u32 index)
|
||||
{
|
||||
if(CONFIG(DISABLEARM11EXCHANDLERS)) return false;
|
||||
|
||||
if((spsr & 0x1F) != 0x10) return true;
|
||||
|
||||
KThread *thread = currentCoreContext->objectContext.currentThread;
|
||||
KProcess *currentProcess = currentCoreContext->objectContext.currentProcess;
|
||||
|
||||
if(thread != NULL && thread->threadLocalStorage != NULL && *((vu32 *)thread->threadLocalStorage + 0x10) != 0)
|
||||
return false;
|
||||
|
||||
if(currentProcess != NULL)
|
||||
{
|
||||
if(debugOfProcess(currentProcess) != NULL)
|
||||
return false;
|
||||
|
||||
thread = KPROCESS_GET_RVALUE(currentProcess, mainThread);
|
||||
if(thread != NULL && thread->threadLocalStorage != NULL && *((vu32 *)thread->threadLocalStorage + 0x10) != 0)
|
||||
return false;
|
||||
|
||||
if(index == 3 && strcmp(codeSetOfProcess(currentProcess)->processName, "menu") == 0 && // workaround a Home Menu bug leading to a dabort
|
||||
regs[0] == 0x3FFF && regs[2] == 0 && regs[5] == 2 && regs[7] == 1)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
extern u32 safecpy_sz;
|
||||
bool isDataAbortExceptionRangeControlled(u32 spsr, u32 addr)
|
||||
{
|
||||
return (!(spsr & 0x20) && (spsr & 0x1F) != 0x10) && (
|
||||
((u32)kernelUsrCopyFuncsStart <= addr && addr < (u32)kernelUsrCopyFuncsEnd) ||
|
||||
((u32)safecpy <= addr && addr < (u32)safecpy + safecpy_sz)
|
||||
);
|
||||
}
|
||||
void fatalExceptionHandlersMain(u32 *registerDump, u32 type, u32 cpuId)
|
||||
{
|
||||
ExceptionDumpHeader dumpHeader;
|
||||
|
||||
u8 codeDump[CODE_DUMP_SIZE];
|
||||
u8 *finalBuffer = (u8 *)PA_PTR(0x25000000);
|
||||
u8 *final = finalBuffer;
|
||||
|
||||
dumpHeader.magic[0] = 0xDEADC0DE;
|
||||
dumpHeader.magic[1] = 0xDEADCAFE;
|
||||
dumpHeader.versionMajor = 1;
|
||||
dumpHeader.versionMinor = 2;
|
||||
|
||||
dumpHeader.processor = 11;
|
||||
dumpHeader.core = cpuId & 0xF;
|
||||
dumpHeader.type = type;
|
||||
|
||||
dumpHeader.registerDumpSize = REG_DUMP_SIZE;
|
||||
dumpHeader.codeDumpSize = CODE_DUMP_SIZE;
|
||||
|
||||
u32 cpsr = registerDump[16];
|
||||
u32 pc = registerDump[15] - (type < 3 ? (((cpsr & 0x20) != 0 && type == 1) ? 2 : 4) : 8);
|
||||
|
||||
registerDump[15] = pc;
|
||||
|
||||
//Dump code
|
||||
u8 *instr = (u8 *)pc + ((cpsr & 0x20) ? 2 : 4) - dumpHeader.codeDumpSize; //wouldn't work well on 32-bit Thumb instructions, but it isn't much of a problem
|
||||
dumpHeader.codeDumpSize = ((u32)instr & (((cpsr & 0x20) != 0) ? 1 : 3)) != 0 ? 0 : safecpy(codeDump, instr, dumpHeader.codeDumpSize);
|
||||
|
||||
//Copy register dump and code dump
|
||||
final = (u8 *)(finalBuffer + sizeof(ExceptionDumpHeader));
|
||||
memcpy(final, registerDump, dumpHeader.registerDumpSize);
|
||||
final += dumpHeader.registerDumpSize;
|
||||
memcpy(final, codeDump, dumpHeader.codeDumpSize);
|
||||
final += dumpHeader.codeDumpSize;
|
||||
|
||||
//Dump stack in place
|
||||
dumpHeader.stackDumpSize = safecpy(final, (const void *)registerDump[13], 0x1000 - (registerDump[13] & 0xFFF));
|
||||
final += dumpHeader.stackDumpSize;
|
||||
|
||||
if(currentCoreContext->objectContext.currentProcess)
|
||||
{
|
||||
vu64 *additionalData = (vu64 *)final;
|
||||
KCodeSet *currentCodeSet = codeSetOfProcess(currentCoreContext->objectContext.currentProcess);
|
||||
if(currentCodeSet != NULL)
|
||||
{
|
||||
dumpHeader.additionalDataSize = 16;
|
||||
memcpy((void *)additionalData, currentCodeSet->processName, 8);
|
||||
additionalData[1] = currentCodeSet->titleId;
|
||||
}
|
||||
else dumpHeader.additionalDataSize = 0;
|
||||
}
|
||||
else dumpHeader.additionalDataSize = 0;
|
||||
|
||||
dumpHeader.totalSize = sizeof(ExceptionDumpHeader) + dumpHeader.registerDumpSize + dumpHeader.codeDumpSize + dumpHeader.stackDumpSize + dumpHeader.additionalDataSize;
|
||||
|
||||
//Copy header (actually optimized by the compiler)
|
||||
*(ExceptionDumpHeader *)finalBuffer = dumpHeader;
|
||||
}
|
||||
114
k11_extension/source/globals.c
Normal file
114
k11_extension/source/globals.c
Normal file
@@ -0,0 +1,114 @@
|
||||
/*
|
||||
* This file is part of Luma3DS
|
||||
* Copyright (C) 2016-2017 Aurora Wright, TuxSH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
|
||||
* * Requiring preservation of specified reasonable legal notices or
|
||||
* author attributions in that material or in the Appropriate Legal
|
||||
* Notices displayed by works containing it.
|
||||
* * Prohibiting misrepresentation of the origin of that material,
|
||||
* or requiring that modified versions of such material be marked in
|
||||
* reasonable ways as different from the original version.
|
||||
*/
|
||||
|
||||
#include "globals.h"
|
||||
|
||||
KRecursiveLock *criticalSectionLock;
|
||||
KObjectList *threadList;
|
||||
KObjectMutex *synchronizationMutex;
|
||||
|
||||
void (*KRecursiveLock__Lock)(KRecursiveLock *this);
|
||||
void (*KRecursiveLock__Unlock)(KRecursiveLock *this);
|
||||
|
||||
void (*KAutoObject__AddReference)(KAutoObject *this);
|
||||
KProcess * (*KProcessHandleTable__ToKProcess)(KProcessHandleTable *this, Handle processHandle);
|
||||
KThread * (*KProcessHandleTable__ToKThread)(KProcessHandleTable *this, Handle threadHandle);
|
||||
KAutoObject * (*KProcessHandleTable__ToKAutoObject)(KProcessHandleTable *this, Handle handle);
|
||||
void (*KSynchronizationObject__Signal)(KSynchronizationObject *this, bool isPulse);
|
||||
Result (*WaitSynchronization1)(void *this_unused, KThread *thread, KSynchronizationObject *syncObject, s64 timeout);
|
||||
Result (*KProcessHandleTable__CreateHandle)(KProcessHandleTable *this, Handle *out, KAutoObject *obj, u8 token);
|
||||
Result (*KProcessHwInfo__MapProcessMemory)(KProcessHwInfo *this, KProcessHwInfo *other, void *dst, void *src, u32 nbPages);
|
||||
Result (*KProcessHwInfo__UnmapProcessMemory)(KProcessHwInfo *this, void *addr, u32 nbPages);
|
||||
Result (*KEvent__Clear)(KEvent *this);
|
||||
void (*KObjectMutex__WaitAndAcquire)(KObjectMutex *this);
|
||||
void (*KObjectMutex__ErrorOccured)(void);
|
||||
|
||||
void (*KScheduler__AdjustThread)(KScheduler *this, KThread *thread, u32 oldSchedulingMask);
|
||||
void (*KScheduler__AttemptSwitchingThreadContext)(KScheduler *this);
|
||||
|
||||
Result (*ControlMemory)(u32 *addrOut, u32 addr0, u32 addr1, u32 size, MemOp op, MemPerm perm, bool isLoader);
|
||||
void (*SleepThread)(s64 ns);
|
||||
Result (*CloseHandle)(Handle handle);
|
||||
Result (*GetHandleInfo)(s64 *out, Handle handle, u32 type);
|
||||
Result (*GetSystemInfo)(s64 *out, s32 type, s32 param);
|
||||
Result (*GetProcessInfo)(s64 *out, Handle processHandle, u32 type);
|
||||
Result (*GetThreadInfo)(s64 *out, Handle threadHandle, u32 type);
|
||||
Result (*ConnectToPort)(Handle *out, const char *name);
|
||||
Result (*SendSyncRequest)(Handle handle);
|
||||
Result (*OpenProcess)(Handle *out, u32 processId);
|
||||
Result (*GetProcessId)(u32 *out, Handle process);
|
||||
Result (*DebugActiveProcess)(Handle *out, u32 processId);
|
||||
Result (*UnmapProcessMemory)(Handle processHandle, void *dst, u32 size);
|
||||
Result (*KernelSetState)(u32 type, u32 varg1, u32 varg2, u32 varg3);
|
||||
|
||||
void (*flushDataCacheRange)(void *addr, u32 len);
|
||||
void (*invalidateInstructionCacheRange)(void *addr, u32 len);
|
||||
|
||||
bool (*usrToKernelMemcpy8)(void *dst, const void *src, u32 len);
|
||||
bool (*usrToKernelMemcpy32)(u32 *dst, const u32 *src, u32 len);
|
||||
s32 (*usrToKernelStrncpy)(char *dst, const char *src, u32 len);
|
||||
bool (*kernelToUsrMemcpy8)(void *dst, const void *src, u32 len);
|
||||
bool (*kernelToUsrMemcpy32)(u32 *dst, const u32 *src, u32 len);
|
||||
s32 (*kernelToUsrStrncpy)(char *dst, const char *src, u32 len);
|
||||
|
||||
void (*svcFallbackHandler)(u8 svcId);
|
||||
void (*kernelpanic)(void);
|
||||
void (*officialPostProcessSvc)(void);
|
||||
|
||||
Result (*SignalDebugEvent)(DebugEventType type, u32 info, ...);
|
||||
|
||||
bool isN3DS;
|
||||
u32 *exceptionStackTop;
|
||||
|
||||
u32 TTBCR;
|
||||
u32 L1MMUTableAddrs[4];
|
||||
|
||||
void *kernelUsrCopyFuncsStart, *kernelUsrCopyFuncsEnd;
|
||||
|
||||
bool *isDevUnit;
|
||||
|
||||
vu8 *configPage;
|
||||
u32 kernelVersion;
|
||||
FcramLayout fcramLayout;
|
||||
KCoreContext *coreCtxs;
|
||||
|
||||
void *originalHandlers[8] = {NULL};
|
||||
|
||||
u32 nbSection0Modules;
|
||||
|
||||
Result (*InterruptManager__MapInterrupt)(InterruptManager *manager, KBaseInterruptEvent *iEvent, u32 interruptID,
|
||||
u32 coreID, u32 priority, bool disableUponReceipt, bool levelHighActive);
|
||||
InterruptManager *interruptManager;
|
||||
KBaseInterruptEvent *customInterruptEvent;
|
||||
|
||||
void (*initFPU)(void);
|
||||
void (*mcuReboot)(void);
|
||||
void (*coreBarrier)(void);
|
||||
|
||||
CfwInfo cfwInfo;
|
||||
|
||||
vu32 rosalinaState;
|
||||
bool hasStartedRosalinaNetworkFuncsOnce;
|
||||
318
k11_extension/source/ipc.c
Normal file
318
k11_extension/source/ipc.c
Normal file
@@ -0,0 +1,318 @@
|
||||
/*
|
||||
* This file is part of Luma3DS
|
||||
* Copyright (C) 2016-2017 Aurora Wright, TuxSH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
|
||||
* * Requiring preservation of specified reasonable legal notices or
|
||||
* author attributions in that material or in the Appropriate Legal
|
||||
* Notices displayed by works containing it.
|
||||
* * Prohibiting misrepresentation of the origin of that material,
|
||||
* or requiring that modified versions of such material be marked in
|
||||
* reasonable ways as different from the original version.
|
||||
*/
|
||||
|
||||
#include "ipc.h"
|
||||
#include "memory.h"
|
||||
|
||||
static SessionInfo sessionInfos[MAX_SESSION] = { {NULL} };
|
||||
static u32 nbActiveSessions = 0;
|
||||
static KRecursiveLock sessionInfosLock = { NULL };
|
||||
|
||||
KRecursiveLock processLangemuLock;
|
||||
LangemuAttributes processLangemuAttributes[0x40];
|
||||
|
||||
static void *customSessionVtable[0x10] = { NULL }; // should be enough
|
||||
|
||||
static u32 SessionInfo_FindClosestSlot(KSession *session)
|
||||
{
|
||||
if(nbActiveSessions == 0 || session <= sessionInfos[0].session)
|
||||
return 0;
|
||||
else if(session > sessionInfos[nbActiveSessions - 1].session)
|
||||
return nbActiveSessions;
|
||||
|
||||
u32 a = 0, b = nbActiveSessions - 1, m;
|
||||
|
||||
do
|
||||
{
|
||||
m = (a + b) / 2;
|
||||
if(sessionInfos[m].session < session)
|
||||
a = m;
|
||||
else if(sessionInfos[m].session > session)
|
||||
b = m;
|
||||
else
|
||||
return m;
|
||||
}
|
||||
while(b - a > 1);
|
||||
|
||||
return b;
|
||||
}
|
||||
|
||||
SessionInfo *SessionInfo_Lookup(KSession *session)
|
||||
{
|
||||
KRecursiveLock__Lock(criticalSectionLock);
|
||||
KRecursiveLock__Lock(&sessionInfosLock);
|
||||
|
||||
SessionInfo *ret;
|
||||
u32 id = SessionInfo_FindClosestSlot(session);
|
||||
if(id == nbActiveSessions)
|
||||
ret = NULL;
|
||||
else
|
||||
ret = (void **)(sessionInfos[id].session->autoObject.vtable) == customSessionVtable ? &sessionInfos[id] : NULL;
|
||||
|
||||
KRecursiveLock__Unlock(&sessionInfosLock);
|
||||
KRecursiveLock__Unlock(criticalSectionLock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
SessionInfo *SessionInfo_FindFirst(const char *name)
|
||||
{
|
||||
KRecursiveLock__Lock(criticalSectionLock);
|
||||
KRecursiveLock__Lock(&sessionInfosLock);
|
||||
|
||||
SessionInfo *ret;
|
||||
u32 id;
|
||||
for(id = 0; id < nbActiveSessions && strncmp(sessionInfos[id].name, name, 12) != 0; id++);
|
||||
if(id == nbActiveSessions)
|
||||
ret = NULL;
|
||||
else
|
||||
ret = (void **)(sessionInfos[id].session->autoObject.vtable) == customSessionVtable ? &sessionInfos[id] : NULL;
|
||||
|
||||
KRecursiveLock__Unlock(&sessionInfosLock);
|
||||
KRecursiveLock__Unlock(criticalSectionLock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void SessionInfo_Add(KSession *session, const char *name)
|
||||
{
|
||||
KAutoObject__AddReference(&session->autoObject);
|
||||
SessionInfo_ChangeVtable(session);
|
||||
session->autoObject.vtable->DecrementReferenceCount(&session->autoObject);
|
||||
|
||||
KRecursiveLock__Lock(criticalSectionLock);
|
||||
KRecursiveLock__Lock(&sessionInfosLock);
|
||||
|
||||
if(nbActiveSessions == MAX_SESSION)
|
||||
{
|
||||
KRecursiveLock__Unlock(&sessionInfosLock);
|
||||
KRecursiveLock__Unlock(criticalSectionLock);
|
||||
return;
|
||||
}
|
||||
|
||||
u32 id = SessionInfo_FindClosestSlot(session);
|
||||
|
||||
if(id != nbActiveSessions && sessionInfos[id].session == session)
|
||||
{
|
||||
KRecursiveLock__Unlock(&sessionInfosLock);
|
||||
KRecursiveLock__Unlock(criticalSectionLock);
|
||||
return;
|
||||
}
|
||||
|
||||
for(u32 i = nbActiveSessions; i > id && i != 0; i--)
|
||||
sessionInfos[i] = sessionInfos[i - 1];
|
||||
|
||||
nbActiveSessions++;
|
||||
|
||||
sessionInfos[id].session = session;
|
||||
strncpy(sessionInfos[id].name, name, 12);
|
||||
|
||||
KRecursiveLock__Unlock(&sessionInfosLock);
|
||||
KRecursiveLock__Unlock(criticalSectionLock);
|
||||
}
|
||||
|
||||
void SessionInfo_Remove(KSession *session)
|
||||
{
|
||||
KRecursiveLock__Lock(criticalSectionLock);
|
||||
KRecursiveLock__Lock(&sessionInfosLock);
|
||||
|
||||
if(nbActiveSessions == MAX_SESSION)
|
||||
{
|
||||
KRecursiveLock__Unlock(&sessionInfosLock);
|
||||
KRecursiveLock__Unlock(criticalSectionLock);
|
||||
return;
|
||||
}
|
||||
|
||||
u32 id = SessionInfo_FindClosestSlot(session);
|
||||
|
||||
if(id == nbActiveSessions)
|
||||
{
|
||||
KRecursiveLock__Unlock(&sessionInfosLock);
|
||||
KRecursiveLock__Unlock(criticalSectionLock);
|
||||
return;
|
||||
}
|
||||
|
||||
for(u32 i = id; i < nbActiveSessions - 1; i++)
|
||||
sessionInfos[i] = sessionInfos[i + 1];
|
||||
|
||||
memset(&sessionInfos[--nbActiveSessions], 0, sizeof(SessionInfo));
|
||||
|
||||
KRecursiveLock__Unlock(&sessionInfosLock);
|
||||
KRecursiveLock__Unlock(criticalSectionLock);
|
||||
}
|
||||
|
||||
static void (*KSession__dtor_orig)(KAutoObject *this);
|
||||
static void KSession__dtor_hook(KAutoObject *this)
|
||||
{
|
||||
KSession__dtor_orig(this);
|
||||
SessionInfo_Remove((KSession *)this);
|
||||
}
|
||||
|
||||
void SessionInfo_ChangeVtable(KSession *session)
|
||||
{
|
||||
if(customSessionVtable[2] == NULL)
|
||||
{
|
||||
memcpy(customSessionVtable, session->autoObject.vtable, 0x40);
|
||||
KSession__dtor_orig = session->autoObject.vtable->dtor;
|
||||
customSessionVtable[2] = (void *)KSession__dtor_hook;
|
||||
}
|
||||
session->autoObject.vtable = (Vtable__KAutoObject *)customSessionVtable;
|
||||
}
|
||||
|
||||
bool doLangEmu(Result *res, u32 *cmdbuf)
|
||||
{
|
||||
KRecursiveLock__Lock(criticalSectionLock);
|
||||
KRecursiveLock__Lock(&processLangemuLock);
|
||||
|
||||
u64 titleId = codeSetOfProcess(currentCoreContext->objectContext.currentProcess)->titleId;
|
||||
LangemuAttributes *attribs = NULL;
|
||||
bool skip = true;
|
||||
|
||||
*res = 0;
|
||||
for(u32 i = 0; i < 0x40; i++)
|
||||
{
|
||||
if(processLangemuAttributes[i].titleId == titleId)
|
||||
attribs = &processLangemuAttributes[i];
|
||||
}
|
||||
|
||||
if(attribs == NULL)
|
||||
{
|
||||
KRecursiveLock__Unlock(&processLangemuLock);
|
||||
KRecursiveLock__Unlock(criticalSectionLock);
|
||||
return false;
|
||||
}
|
||||
|
||||
if((cmdbuf[0] == 0x20000 || cmdbuf[0] == 0x4060000 || cmdbuf[0] == 0x8160000) && (attribs->mask & 1)) // SecureInfoGetRegion
|
||||
{
|
||||
cmdbuf[0] = (cmdbuf[0] & 0xFFFF0000) | 0x80;
|
||||
cmdbuf[1] = 0;
|
||||
cmdbuf[2] = attribs->region;
|
||||
}
|
||||
else if(cmdbuf[1] == 1 && cmdbuf[2] == 0xA0002 && cmdbuf[3] == 0x1C && (attribs->mask & 2))
|
||||
{
|
||||
cmdbuf[0] = (cmdbuf[0] & 0xFFFF0000) | 0x40;
|
||||
cmdbuf[1] = 0;
|
||||
*(u8 *)cmdbuf[4] = attribs->language;
|
||||
}
|
||||
else if(cmdbuf[1] == 4 && cmdbuf[2] == 0xB0000 && cmdbuf[3] == 0x4C && (attribs->mask & 0xC))
|
||||
{
|
||||
u8 *ptr = (u8 *)cmdbuf[4];
|
||||
if(attribs->mask & 4)
|
||||
ptr[3] = attribs->country;
|
||||
if(attribs->mask & 8)
|
||||
ptr[2] = attribs->state;
|
||||
|
||||
ptr[0] = ptr[1] = 0;
|
||||
}
|
||||
else
|
||||
skip = false;
|
||||
|
||||
KRecursiveLock__Unlock(&processLangemuLock);
|
||||
KRecursiveLock__Unlock(criticalSectionLock);
|
||||
return skip;
|
||||
}
|
||||
|
||||
Result doPublishToProcessHook(Handle handle, u32 *cmdbuf)
|
||||
{
|
||||
Result res = 0;
|
||||
u32 pid;
|
||||
bool terminateRosalina = cmdbuf[1] == 0x100 && cmdbuf[2] == 0; // cmdbuf[2] to check for well-formed requests
|
||||
u32 savedCmdbuf[4];
|
||||
memcpy(savedCmdbuf, cmdbuf, 16);
|
||||
|
||||
if(!terminateRosalina || GetProcessId(&pid, cmdbuf[3]) != 0)
|
||||
terminateRosalina = false;
|
||||
else
|
||||
{
|
||||
KProcessHandleTable *handleTable = handleTableOfProcess(currentCoreContext->objectContext.currentProcess);
|
||||
KProcess *process = KProcessHandleTable__ToKProcess(handleTable, cmdbuf[3]);
|
||||
if((strcmp(codeSetOfProcess(process)->processName, "socket") == 0 && (rosalinaState & 2)) ||
|
||||
strcmp(codeSetOfProcess(process)->processName, "pxi") == 0)
|
||||
terminateRosalina = true;
|
||||
else
|
||||
terminateRosalina = false;
|
||||
((KAutoObject *)process)->vtable->DecrementReferenceCount((KAutoObject *)process);
|
||||
}
|
||||
|
||||
if(terminateRosalina && nbSection0Modules == 6)
|
||||
{
|
||||
Handle rosalinaProcessHandle;
|
||||
res = OpenProcess(&rosalinaProcessHandle, 5);
|
||||
if(res == 0)
|
||||
{
|
||||
cmdbuf[0] = cmdbuf[0];
|
||||
cmdbuf[1] = 0x100;
|
||||
cmdbuf[2] = 0;
|
||||
cmdbuf[3] = rosalinaProcessHandle;
|
||||
|
||||
res = SendSyncRequest(handle);
|
||||
CloseHandle(rosalinaProcessHandle);
|
||||
memcpy(cmdbuf, savedCmdbuf, 16);
|
||||
}
|
||||
}
|
||||
|
||||
return SendSyncRequest(handle);
|
||||
}
|
||||
|
||||
bool doErrfThrowHook(u32 *cmdbuf)
|
||||
{
|
||||
// If fatalErrorInfo->type is "card removed" or "logged", returning from ERRF:Throw is a no-op
|
||||
// for the SDK function
|
||||
|
||||
// r6 (arm) or r4 (thumb) is copied into cmdbuf[1..31]
|
||||
u32 *r0_to_r7_r12_usr = (u32 *)((u8 *)currentCoreContext->objectContext.currentThread->endOfThreadContext - 0x110);
|
||||
u32 spsr = *(u32 *)((u8 *)currentCoreContext->objectContext.currentThread->endOfThreadContext - 0xCC);
|
||||
u8 *srcerrbuf = (u8 *)r0_to_r7_r12_usr[(spsr & 0x20) ? 4 : 6];
|
||||
const char *pname = codeSetOfProcess(currentCoreContext->objectContext.currentProcess)->processName;
|
||||
|
||||
static const struct
|
||||
{
|
||||
const char *name;
|
||||
Result errCode;
|
||||
} errorCodesToIgnore[] =
|
||||
{
|
||||
/*
|
||||
If you're getting this error, you have broken your head-tracking hardware,
|
||||
and should uncomment the following line:
|
||||
*/
|
||||
//{ "qtm", (Result)0xF96183FE },
|
||||
|
||||
{ "", 0 }, // impossible case to ensure the array has at least 1 element
|
||||
};
|
||||
|
||||
for(u32 i = 0; i < sizeof(errorCodesToIgnore) / sizeof(errorCodesToIgnore[0]); i++)
|
||||
{
|
||||
if(strcmp(pname, errorCodesToIgnore[i].name) == 0 && (Result)cmdbuf[2] == errorCodesToIgnore[i].errCode)
|
||||
{
|
||||
srcerrbuf[0] = 5;
|
||||
cmdbuf[0] = 0x10040;
|
||||
cmdbuf[1] = 0;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
282
k11_extension/source/main.c
Normal file
282
k11_extension/source/main.c
Normal file
@@ -0,0 +1,282 @@
|
||||
/*
|
||||
* This file is part of Luma3DS
|
||||
* Copyright (C) 2016-2017 Aurora Wright, TuxSH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
|
||||
* * Requiring preservation of specified reasonable legal notices or
|
||||
* author attributions in that material or in the Appropriate Legal
|
||||
* Notices displayed by works containing it.
|
||||
* * Prohibiting misrepresentation of the origin of that material,
|
||||
* or requiring that modified versions of such material be marked in
|
||||
* reasonable ways as different from the original version.
|
||||
*/
|
||||
|
||||
#include "utils.h"
|
||||
#include "globals.h"
|
||||
#include "synchronization.h"
|
||||
#include "fatalExceptionHandlers.h"
|
||||
#include "svc.h"
|
||||
#include "svc/ConnectToPort.h"
|
||||
#include "svcHandler.h"
|
||||
#include "memory.h"
|
||||
|
||||
struct KExtParameters
|
||||
{
|
||||
u32 ALIGN(0x400) L2MMUTableFor0x40000000[256];
|
||||
u32 basePA;
|
||||
void *originalHandlers[4];
|
||||
u32 L1MMUTableAddrs[4];
|
||||
|
||||
CfwInfo cfwInfo;
|
||||
} kExtParameters = { .basePA = 0x12345678 }; // place this in .data
|
||||
|
||||
void relocateAndSetupMMU(u32 coreId, u32 *L1Table)
|
||||
{
|
||||
struct KExtParameters *p0 = (struct KExtParameters *)((u32)&kExtParameters - 0x40000000 + 0x18000000);
|
||||
struct KExtParameters *p = (struct KExtParameters *)((u32)&kExtParameters - 0x40000000 + p0->basePA);
|
||||
|
||||
if(coreId == 0)
|
||||
{
|
||||
// Relocate ourselves, and clear BSS
|
||||
memcpy((void *)p0->basePA, (const void *)0x18000000, __bss_start__ - __start__);
|
||||
memset32((u32 *)(p0->basePA + (__bss_start__ - __start__)), 0, __bss_end__ - __bss_start__);
|
||||
|
||||
// Map the kernel ext to 0x40000000
|
||||
// 4KB extended small pages: [SYS:RW USR:-- X TYP:NORMAL SHARED OUTER NOCACHE, INNER CACHED WB WA]
|
||||
for(u32 offset = 0; offset < (u32)(__end__ - __start__); offset += 0x1000)
|
||||
p->L2MMUTableFor0x40000000[offset >> 12] = (p0->basePA + offset) | 0x516;
|
||||
|
||||
__asm__ __volatile__ ("sev");
|
||||
}
|
||||
else
|
||||
__asm__ __volatile__ ("wfe");
|
||||
|
||||
// bit31 idea thanks to SALT
|
||||
// Maps physmem so that, if addr is in physmem(0, 0x30000000), it can be accessed uncached&rwx as addr|(1<<31)
|
||||
u32 attribs = 0x40C02; // supersection (rwx for all) of strongly ordered memory, shared
|
||||
for(u32 PA = 0; PA < 0x30000000; PA += 0x01000000)
|
||||
{
|
||||
u32 VA = (1 << 31) | PA;
|
||||
for(u32 i = 0; i < 16; i++)
|
||||
L1Table[i + (VA >> 20)] = PA | attribs;
|
||||
}
|
||||
|
||||
L1Table[0x40000000 >> 20] = (u32)p->L2MMUTableFor0x40000000 | 1;
|
||||
|
||||
p->L1MMUTableAddrs[coreId] = (u32)L1Table;
|
||||
}
|
||||
|
||||
void bindSGI0Hook(void)
|
||||
{
|
||||
if(InterruptManager__MapInterrupt(interruptManager, customInterruptEvent, 0, getCurrentCoreID(), 0, false, false) != 0)
|
||||
__asm__ __volatile__ ("bkpt 0xdead");
|
||||
}
|
||||
|
||||
void configHook(vu8 *cfgPage)
|
||||
{
|
||||
configPage = cfgPage;
|
||||
|
||||
kernelVersion = *(vu32 *)configPage;
|
||||
*(vu32 *)(configPage + 0x40) = fcramLayout.applicationSize;
|
||||
*(vu32 *)(configPage + 0x44) = fcramLayout.systemSize;
|
||||
*(vu32 *)(configPage + 0x48) = fcramLayout.baseSize;
|
||||
*isDevUnit = true; // enable debug features
|
||||
}
|
||||
|
||||
static void findUsefulSymbols(void)
|
||||
{
|
||||
u32 *off;
|
||||
|
||||
for(off = (u32 *)0xFFFF0000; *off != 0xE1A0D002; off++);
|
||||
off += 3;
|
||||
initFPU = (void (*) (void))off;
|
||||
|
||||
for(; *off != 0xE3A0A0C2; off++);
|
||||
mcuReboot = (void (*) (void))--off;
|
||||
coreBarrier = (void (*) (void))decodeARMBranch(off - 4);
|
||||
|
||||
for(off = (u32 *)originalHandlers[2]; *off != 0xE1A00009; off++);
|
||||
svcFallbackHandler = (void (*)(u8))decodeARMBranch(off + 1);
|
||||
for(; *off != 0xE92D000F; off++);
|
||||
officialPostProcessSvc = (void (*)(void))decodeARMBranch(off + 1);
|
||||
|
||||
KProcessHandleTable__ToKProcess = (KProcess * (*)(KProcessHandleTable *, Handle))decodeARMBranch(5 + (u32 *)officialSVCs[0x76]);
|
||||
|
||||
for(off = (u32 *)KProcessHandleTable__ToKProcess; *off != 0xE1A00004; off++);
|
||||
KAutoObject__AddReference = (void (*)(KAutoObject *))decodeARMBranch(off + 1);
|
||||
|
||||
for(; *off != 0xE320F000; off++);
|
||||
KProcessHandleTable__ToKAutoObject = (KAutoObject * (*)(KProcessHandleTable *, Handle))decodeARMBranch(off + 1);
|
||||
|
||||
for(off = (u32 *)decodeARMBranch(3 + (u32 *)officialSVCs[9]); /* KThread::Terminate */ *off != 0xE5D42034; off++);
|
||||
off -= 2;
|
||||
criticalSectionLock = (KRecursiveLock *)off[2 + (off[0] & 0xFF) / 4];
|
||||
KRecursiveLock__Lock = (void (*)(KRecursiveLock *))decodeARMBranch(off + 1);
|
||||
off += 4;
|
||||
|
||||
for(; (*off >> 16) != 0xE59F; off++);
|
||||
KRecursiveLock__Unlock = (void (*)(KRecursiveLock *))decodeARMBranch(off + 1);
|
||||
|
||||
for(; *off != 0xE5C4007D; off++);
|
||||
KSynchronizationObject__Signal = (void (*)(KSynchronizationObject *, bool))decodeARMBranch(off + 3);
|
||||
|
||||
for(off = (u32 *)officialSVCs[0x19]; *off != 0xE1A04005; off++);
|
||||
KEvent__Clear = (Result (*)(KEvent *))decodeARMBranch(off + 1);
|
||||
for(off = (u32 *)KEvent__Clear; *off != 0xE8BD8070; off++);
|
||||
synchronizationMutex = *(KObjectMutex **)(off + 1);
|
||||
|
||||
for(off = (u32 *)officialSVCs[0x24]; *off != 0xE59F004C; off++);
|
||||
WaitSynchronization1 = (Result (*)(void *, KThread *, KSynchronizationObject *, s64))decodeARMBranch(off + 6);
|
||||
|
||||
for(off = (u32 *)decodeARMBranch(3 + (u32 *)officialSVCs[0x33]) /* OpenProcess */ ; *off != 0xE1A05000; off++);
|
||||
KProcessHandleTable__CreateHandle = (Result (*)(KProcessHandleTable *, Handle *, KAutoObject *, u8))decodeARMBranch(off - 1);
|
||||
|
||||
for(off = (u32 *)decodeARMBranch(3 + (u32 *)officialSVCs[0x34]) /* OpenThread */; *off != 0xD9001BF7; off++);
|
||||
threadList = *(KObjectList **)(off + 1);
|
||||
|
||||
KProcessHandleTable__ToKThread = (KThread * (*)(KProcessHandleTable *, Handle))decodeARMBranch((u32 *)decodeARMBranch((u32 *)officialSVCs[0x37] + 3) /* GetThreadId */ + 5);
|
||||
|
||||
for(off = (u32 *)officialSVCs[0x50]; off[0] != 0xE1A05000 || off[1] != 0xE2100102 || off[2] != 0x5A00000B; off++);
|
||||
InterruptManager__MapInterrupt = (Result (*)(InterruptManager *, KBaseInterruptEvent *, u32, u32, u32, bool, bool))decodeARMBranch(--off);
|
||||
interruptManager = *(InterruptManager **)(off - 4 + (off[-6] & 0xFFF) / 4);
|
||||
for(off = (u32 *)officialSVCs[0x54]; *off != 0xE8BD8008; off++);
|
||||
flushDataCacheRange = (void (*)(void *, u32))(*(u32 **)(off[1]) + 3);
|
||||
|
||||
for(off = (u32 *)officialSVCs[0x71]; *off != 0xE2101102; off++);
|
||||
KProcessHwInfo__MapProcessMemory = (Result (*)(KProcessHwInfo *, KProcessHwInfo *, void *, void *, u32))decodeARMBranch(off - 1);
|
||||
|
||||
// From 4.x to 6.x the pattern will match but the result will be wrong
|
||||
for(off = (u32 *)officialSVCs[0x72]; *off != 0xE2041102; off++);
|
||||
KProcessHwInfo__UnmapProcessMemory = (Result (*)(KProcessHwInfo *, void *, u32))decodeARMBranch(off - 1);
|
||||
|
||||
for(off = (u32 *)officialSVCs[0x7C]; *off != 0x03530000; off++);
|
||||
KObjectMutex__WaitAndAcquire = (void (*)(KObjectMutex *))decodeARMBranch(++off);
|
||||
for(; *off != 0xE320F000; off++);
|
||||
KObjectMutex__ErrorOccured = (void (*)(void))decodeARMBranch(off + 1);
|
||||
|
||||
for(off = (u32 *)originalHandlers[4]; *off != (u32)exceptionStackTop; off++);
|
||||
kernelUsrCopyFuncsStart = (void *)off[1];
|
||||
kernelUsrCopyFuncsEnd = (void *)off[2];
|
||||
|
||||
u32 n_cmp_0;
|
||||
for(off = (u32 *)kernelUsrCopyFuncsStart, n_cmp_0 = 1; n_cmp_0 <= 6; off++)
|
||||
{
|
||||
if(*off == 0xE3520000)
|
||||
{
|
||||
// We're missing some funcs
|
||||
switch(n_cmp_0)
|
||||
{
|
||||
case 1:
|
||||
usrToKernelMemcpy8 = (bool (*)(void *, const void *, u32))off;
|
||||
break;
|
||||
case 2:
|
||||
usrToKernelMemcpy32 = (bool (*)(u32 *, const u32 *, u32))off;
|
||||
break;
|
||||
case 3:
|
||||
usrToKernelStrncpy = (s32 (*)(char *, const char *, u32))off;
|
||||
break;
|
||||
case 4:
|
||||
kernelToUsrMemcpy8 = (bool (*)(void *, const void *, u32))off;
|
||||
break;
|
||||
case 5:
|
||||
kernelToUsrMemcpy32 = (bool (*)(u32 *, const u32 *, u32))off;
|
||||
break;
|
||||
case 6:
|
||||
kernelToUsrStrncpy = (s32 (*)(char *, const char *, u32))off;
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
n_cmp_0++;
|
||||
}
|
||||
}
|
||||
|
||||
// The official prototype of ControlMemory doesn't have that extra param'
|
||||
ControlMemory = (Result (*)(u32 *, u32, u32, u32, MemOp, MemPerm, bool))
|
||||
decodeARMBranch((u32 *)officialSVCs[0x01] + 5);
|
||||
SleepThread = (void (*)(s64))officialSVCs[0x0A];
|
||||
CloseHandle = (Result (*)(Handle))officialSVCs[0x23];
|
||||
GetHandleInfo = (Result (*)(s64 *, Handle, u32))decodeARMBranch((u32 *)officialSVCs[0x29] + 3);
|
||||
GetSystemInfo = (Result (*)(s64 *, s32, s32))decodeARMBranch((u32 *)officialSVCs[0x2A] + 3);
|
||||
GetProcessInfo = (Result (*)(s64 *, Handle, u32))decodeARMBranch((u32 *)officialSVCs[0x2B] + 3);
|
||||
GetThreadInfo = (Result (*)(s64 *, Handle, u32))decodeARMBranch((u32 *)officialSVCs[0x2C] + 3);
|
||||
ConnectToPort = (Result (*)(Handle *, const char*))decodeARMBranch((u32 *)officialSVCs[0x2D] + 3);
|
||||
SendSyncRequest = (Result (*)(Handle))officialSVCs[0x32];
|
||||
OpenProcess = (Result (*)(Handle *, u32))decodeARMBranch((u32 *)officialSVCs[0x33] + 3);
|
||||
GetProcessId = (Result (*)(u32 *, Handle))decodeARMBranch((u32 *)officialSVCs[0x35] + 3);
|
||||
DebugActiveProcess = (Result (*)(Handle *, u32))decodeARMBranch((u32 *)officialSVCs[0x60] + 3);
|
||||
UnmapProcessMemory = (Result (*)(Handle, void *, u32))officialSVCs[0x72];
|
||||
KernelSetState = (Result (*)(u32, u32, u32, u32))((u32 *)officialSVCs[0x7C] + 1);
|
||||
|
||||
for(off = (u32 *)svcFallbackHandler; *off != 0xE8BD4010; off++);
|
||||
kernelpanic = (void (*)(void))decodeARMBranch(off + 1);
|
||||
|
||||
for(off = (u32 *)0xFFFF0000; off[0] != 0xE3A01002 || off[1] != 0xE3A00004; off++);
|
||||
SignalDebugEvent = (Result (*)(DebugEventType type, u32 info, ...))decodeARMBranch(off + 2);
|
||||
|
||||
for(; *off != 0x96007F9; off++);
|
||||
isDevUnit = *(bool **)(off - 1);
|
||||
|
||||
///////////////////////////////////////////
|
||||
|
||||
// Shitty/lazy heuristic but it works on even 4.5, so...
|
||||
u32 textStart = ((u32)originalHandlers[2]) & ~0xFFFF;
|
||||
u32 rodataStart = (u32)(interruptManager->N3DS.privateInterrupts[1][0x1D].interruptEvent->vtable) & ~0xFFF;
|
||||
u32 textSize = rodataStart - textStart;
|
||||
for(off = (u32 *)textStart; off < (u32 *)(textStart + textSize - 12); off++)
|
||||
{
|
||||
if(off[0] == 0xE5D13034 && off[1] == 0xE1530002)
|
||||
KScheduler__AdjustThread = (void (*)(KScheduler *, KThread *, u32))off;
|
||||
else if(off[0] == (u32)interruptManager && off[1] == (u32)¤tCoreContext->objectContext)
|
||||
KScheduler__AttemptSwitchingThreadContext = (void (*)(KScheduler *))(off - 2);
|
||||
else if(off[0] == 0xE3510B1A && off[1] == 0xE3A06000)
|
||||
{
|
||||
u32 *off2;
|
||||
for(off2 = off; *off2 != 0xE92D40F8; off2--);
|
||||
invalidateInstructionCacheRange = (void (*)(void *, u32))off2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void main(FcramLayout *layout, KCoreContext *ctxs)
|
||||
{
|
||||
struct KExtParameters *p = &kExtParameters;
|
||||
u32 TTBCR_;
|
||||
s64 nb;
|
||||
|
||||
layout->systemSize -= __end__ - __start__;
|
||||
fcramLayout = *layout;
|
||||
coreCtxs = ctxs;
|
||||
|
||||
__asm__ __volatile__("mrc p15, 0, %0, c2, c0, 2" : "=r"(TTBCR_));
|
||||
TTBCR = TTBCR_;
|
||||
isN3DS = getNumberOfCores() == 4;
|
||||
memcpy(L1MMUTableAddrs, (const void *)p->L1MMUTableAddrs, 16);
|
||||
exceptionStackTop = (u32 *)0xFFFF2000 + (1 << (32 - TTBCR - 20));
|
||||
cfwInfo = p->cfwInfo;
|
||||
|
||||
memcpy(originalHandlers + 1, p->originalHandlers, 16);
|
||||
void **arm11SvcTable = (void**)originalHandlers[2];
|
||||
while(*arm11SvcTable != NULL) arm11SvcTable++; //Look for SVC0 (NULL)
|
||||
memcpy(officialSVCs, arm11SvcTable, 4 * 0x7E);
|
||||
|
||||
findUsefulSymbols();
|
||||
|
||||
GetSystemInfo(&nb, 26, 0);
|
||||
nbSection0Modules = (u32)nb;
|
||||
|
||||
rosalinaState = 0;
|
||||
hasStartedRosalinaNetworkFuncsOnce = false;
|
||||
}
|
||||
176
k11_extension/source/memory.c
Normal file
176
k11_extension/source/memory.c
Normal file
@@ -0,0 +1,176 @@
|
||||
/*
|
||||
* This file is part of Luma3DS
|
||||
* Copyright (C) 2016-2017 Aurora Wright, TuxSH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
|
||||
* * Requiring preservation of specified reasonable legal notices or
|
||||
* author attributions in that material or in the Appropriate Legal
|
||||
* Notices displayed by works containing it.
|
||||
* * Prohibiting misrepresentation of the origin of that material,
|
||||
* or requiring that modified versions of such material be marked in
|
||||
* reasonable ways as different from the original version.
|
||||
*/
|
||||
|
||||
#include "memory.h"
|
||||
#include "utils.h"
|
||||
|
||||
void *memcpy(void *dest, const void *src, u32 size)
|
||||
{
|
||||
u8 *destc = (u8 *)dest;
|
||||
const u8 *srcc = (const u8 *)src;
|
||||
|
||||
for(u32 i = 0; i < size; i++)
|
||||
destc[i] = srcc[i];
|
||||
|
||||
return dest;
|
||||
}
|
||||
|
||||
int memcmp(const void *buf1, const void *buf2, u32 size)
|
||||
{
|
||||
const u8 *buf1c = (const u8 *)buf1;
|
||||
const u8 *buf2c = (const u8 *)buf2;
|
||||
|
||||
for(u32 i = 0; i < size; i++)
|
||||
{
|
||||
int cmp = buf1c[i] - buf2c[i];
|
||||
if(cmp)
|
||||
return cmp;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void *memset(void *dest, u32 value, u32 size)
|
||||
{
|
||||
u8 *destc = (u8 *)dest;
|
||||
|
||||
for(u32 i = 0; i < size; i++) destc[i] = (u8)value;
|
||||
|
||||
return dest;
|
||||
}
|
||||
|
||||
void *memset32(void *dest, u32 value, u32 size)
|
||||
{
|
||||
u32 *dest32 = (u32 *)dest;
|
||||
|
||||
for(u32 i = 0; i < size/4; i++) dest32[i] = value;
|
||||
|
||||
return dest;
|
||||
}
|
||||
|
||||
//Boyer-Moore Horspool algorithm, adapted from http://www-igm.univ-mlv.fr/~lecroq/string/node18.html#SECTION00180
|
||||
u8 *memsearch(u8 *startPos, const void *pattern, u32 size, u32 patternSize)
|
||||
{
|
||||
const u8 *patternc = (const u8 *)pattern;
|
||||
u32 table[256];
|
||||
|
||||
//Preprocessing
|
||||
for(u32 i = 0; i < 256; i++)
|
||||
table[i] = patternSize;
|
||||
for(u32 i = 0; i < patternSize - 1; i++)
|
||||
table[patternc[i]] = patternSize - i - 1;
|
||||
|
||||
//Searching
|
||||
u32 j = 0;
|
||||
while(j <= size - patternSize)
|
||||
{
|
||||
u8 c = startPos[j + patternSize - 1];
|
||||
if(patternc[patternSize - 1] == c && memcmp(pattern, startPos + j, patternSize - 1) == 0)
|
||||
return startPos + j;
|
||||
j += table[c];
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *strcpy(char *dest, const char *src)
|
||||
{
|
||||
u32 i;
|
||||
for(i = 0; src[i] != 0; i++)
|
||||
dest[i] = src[i];
|
||||
|
||||
dest[i] = 0;
|
||||
|
||||
return dest;
|
||||
}
|
||||
|
||||
char *strncpy(char *dest, const char *src, u32 size)
|
||||
{
|
||||
u32 i;
|
||||
for(i = 0; i < size && src[i] != 0; i++)
|
||||
dest[i] = src[i];
|
||||
|
||||
for(; i < size; i++)
|
||||
dest[i] = 0;
|
||||
|
||||
return dest;
|
||||
}
|
||||
|
||||
s32 strnlen(const char *string, s32 maxlen)
|
||||
{
|
||||
s32 size;
|
||||
for(size = 0; *string && size < maxlen; string++, size++);
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
s32 strlen(const char *string)
|
||||
{
|
||||
char *stringEnd = (char *)string;
|
||||
while(*stringEnd) stringEnd++;
|
||||
|
||||
return stringEnd - string;
|
||||
}
|
||||
|
||||
s32 strcmp(const char *str1, const char *str2)
|
||||
{
|
||||
while(*str1 && (*str1 == *str2))
|
||||
{
|
||||
str1++;
|
||||
str2++;
|
||||
}
|
||||
|
||||
return *str1 - *str2;
|
||||
}
|
||||
|
||||
s32 strncmp(const char *str1, const char *str2, u32 size)
|
||||
{
|
||||
while(size && *str1 && (*str1 == *str2))
|
||||
{
|
||||
str1++;
|
||||
str2++;
|
||||
size--;
|
||||
}
|
||||
if (!size)
|
||||
return 0;
|
||||
else
|
||||
return *str1 - *str2;
|
||||
}
|
||||
|
||||
void hexItoa(u64 number, char *out, u32 digits, bool uppercase)
|
||||
{
|
||||
const char hexDigits[] = "0123456789ABCDEF";
|
||||
const char hexDigitsLowercase[] = "0123456789abcdef";
|
||||
u32 i = 0;
|
||||
|
||||
while(number > 0)
|
||||
{
|
||||
out[digits - 1 - i++] = uppercase ? hexDigits[number & 0xF] : hexDigitsLowercase[number & 0xF];
|
||||
number >>= 4;
|
||||
}
|
||||
|
||||
while(i < digits) out[digits - 1 - i++] = '0';
|
||||
}
|
||||
72
k11_extension/source/start.s
Normal file
72
k11_extension/source/start.s
Normal file
@@ -0,0 +1,72 @@
|
||||
@ This file is part of Luma3DS
|
||||
@ Copyright (C) 2016-2017 Aurora Wright, TuxSH
|
||||
@
|
||||
@ This program is free software: you can redistribute it and/or modify
|
||||
@ it under the terms of the GNU General Public License as published by
|
||||
@ the Free Software Foundation, either version 3 of the License, or
|
||||
@ (at your option) any later version.
|
||||
@
|
||||
@ This program is distributed in the hope that it will be useful,
|
||||
@ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
@ GNU General Public License for more details.
|
||||
@
|
||||
@ You should have received a copy of the GNU General Public License
|
||||
@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
@
|
||||
@ Additional Terms 7.b and 7.c of GPLv3 apply to this file:
|
||||
@ * Requiring preservation of specified reasonable legal notices or
|
||||
@ author attributions in that material or in the Appropriate Legal
|
||||
@ Notices displayed by works containing it.
|
||||
@ * Prohibiting misrepresentation of the origin of that material,
|
||||
@ or requiring that modified versions of such material be marked in
|
||||
@ reasonable ways as different from the original version.
|
||||
|
||||
.section .text.start
|
||||
.balign 4
|
||||
.global _start
|
||||
_start:
|
||||
b start
|
||||
b startPhys
|
||||
|
||||
b _bindSGI0Hook
|
||||
b configHook
|
||||
|
||||
b undefinedInstructionHandler
|
||||
b svcHandler
|
||||
b prefetchAbortHandler
|
||||
b dataAbortHandler
|
||||
|
||||
.word __end__
|
||||
.word kExtParameters
|
||||
.word 1 @ enableUserExceptionHandlersForCPUExc
|
||||
|
||||
b KThread__DebugReschedule
|
||||
start:
|
||||
@ Only core0 executes this, the other cores are running coreBarrier
|
||||
|
||||
@ Skipped instruction:
|
||||
str r1, [r4, #0x8]
|
||||
|
||||
push {r0-r12, lr}
|
||||
|
||||
sub r0, r4, #8
|
||||
sub r1, r8, #0x8000
|
||||
bl main
|
||||
|
||||
pop {r0-r12, pc}
|
||||
|
||||
startPhys:
|
||||
push {r0-r12, lr}
|
||||
mrc p15, 0, r0, c0, c0, 5 @ CPUID register
|
||||
and r0, #3
|
||||
mov r1, r2
|
||||
bl relocateAndSetupMMU
|
||||
pop {r0-r12, lr}
|
||||
mov r12, #0x20000000 @ instruction that has been patched
|
||||
bx lr
|
||||
|
||||
_bindSGI0Hook:
|
||||
push {r0-r12, lr}
|
||||
bl bindSGI0Hook
|
||||
pop {r0-r12, pc}
|
||||
171
k11_extension/source/svc.c
Normal file
171
k11_extension/source/svc.c
Normal file
@@ -0,0 +1,171 @@
|
||||
/*
|
||||
* This file is part of Luma3DS
|
||||
* Copyright (C) 2016-2017 Aurora Wright, TuxSH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
|
||||
* * Requiring preservation of specified reasonable legal notices or
|
||||
* author attributions in that material or in the Appropriate Legal
|
||||
* Notices displayed by works containing it.
|
||||
* * Prohibiting misrepresentation of the origin of that material,
|
||||
* or requiring that modified versions of such material be marked in
|
||||
* reasonable ways as different from the original version.
|
||||
*/
|
||||
|
||||
#include "memory.h"
|
||||
#include "synchronization.h"
|
||||
#include "svc.h"
|
||||
#include "svc/ControlMemory.h"
|
||||
#include "svc/GetHandleInfo.h"
|
||||
#include "svc/GetSystemInfo.h"
|
||||
#include "svc/GetProcessInfo.h"
|
||||
#include "svc/GetThreadInfo.h"
|
||||
#include "svc/GetCFWInfo.h"
|
||||
#include "svc/ConnectToPort.h"
|
||||
#include "svc/SendSyncRequest.h"
|
||||
#include "svc/Break.h"
|
||||
#include "svc/SetGpuProt.h"
|
||||
#include "svc/SetWifiEnabled.h"
|
||||
#include "svc/Backdoor.h"
|
||||
#include "svc/KernelSetState.h"
|
||||
#include "svc/CustomBackdoor.h"
|
||||
#include "svc/MapProcessMemoryEx.h"
|
||||
#include "svc/UnmapProcessMemoryEx.h"
|
||||
#include "svc/ControlService.h"
|
||||
#include "svc/CopyHandle.h"
|
||||
#include "svc/TranslateHandle.h"
|
||||
|
||||
void *officialSVCs[0x7E] = {NULL};
|
||||
|
||||
void signalSvcEntry(u8 *pageEnd)
|
||||
{
|
||||
u32 svcId = (u32) *(u8 *)(pageEnd - 0xB5);
|
||||
KProcess *currentProcess = currentCoreContext->objectContext.currentProcess;
|
||||
|
||||
if(svcId == 0xFE)
|
||||
svcId = *(u32 *)(pageEnd - 0x110 + 8 * 4); // r12 ; note: max theortical SVC atm: 0x3FFFFFFF. We don't support catching svcIds >= 0x100 atm either
|
||||
|
||||
// Since DBGEVENT_SYSCALL_ENTRY is non blocking, we'll cheat using EXCEVENT_UNDEFINED_SYSCALL (debug->svcId is fortunately an u16!)
|
||||
if(debugOfProcess(currentProcess) != NULL && shouldSignalSyscallDebugEvent(currentProcess, svcId))
|
||||
SignalDebugEvent(DBGEVENT_OUTPUT_STRING, 0xFFFFFFFE, svcId);
|
||||
}
|
||||
|
||||
void signalSvcReturn(u8 *pageEnd)
|
||||
{
|
||||
u32 svcId = (u32) *(u8 *)(pageEnd - 0xB5);
|
||||
KProcess *currentProcess = currentCoreContext->objectContext.currentProcess;
|
||||
|
||||
if(svcId == 0xFE)
|
||||
svcId = *(u32 *)(pageEnd - 0x110 + 8 * 4); // r12 ; note: max theortical SVC atm: 0x1FFFFFFF. We don't support catching svcIds >= 0x100 atm either
|
||||
|
||||
// Since DBGEVENT_SYSCALL_RETURN is non blocking, we'll cheat using EXCEVENT_UNDEFINED_SYSCALL (debug->svcId is fortunately an u16!)
|
||||
if(debugOfProcess(currentProcess) != NULL && shouldSignalSyscallDebugEvent(currentProcess, svcId))
|
||||
SignalDebugEvent(DBGEVENT_OUTPUT_STRING, 0xFFFFFFFF, svcId);
|
||||
}
|
||||
|
||||
void postprocessSvc(void)
|
||||
{
|
||||
KThread *currentThread = currentCoreContext->objectContext.currentThread;
|
||||
if(!currentThread->shallTerminate && rosalinaThreadLockPredicate(currentThread))
|
||||
rosalinaRescheduleThread(currentThread, true);
|
||||
|
||||
officialPostProcessSvc();
|
||||
}
|
||||
|
||||
static bool doingVeryShittyPmResLimitWorkaround = false; // I feel dirty
|
||||
|
||||
void *svcHook(u8 *pageEnd)
|
||||
{
|
||||
KProcess *currentProcess = currentCoreContext->objectContext.currentProcess;
|
||||
|
||||
u32 svcId = *(u8 *)(pageEnd - 0xB5);
|
||||
if(svcId == 0xFE)
|
||||
svcId = *(u32 *)(pageEnd - 0x110 + 8 * 4); // r12 ; note: max theortical SVC atm: 0x3FFFFFFF. We don't support catching svcIds >= 0x100 atm either
|
||||
switch(svcId)
|
||||
{
|
||||
case 0x01:
|
||||
return ControlMemoryHookWrapper;
|
||||
case 0x17:
|
||||
if(strcmp(codeSetOfProcess(currentProcess)->processName, "pm") == 0) // only called twice in pm, by the same function
|
||||
{
|
||||
*(vu32 *)(configPage + 0x44) += __end__ - __start__;
|
||||
doingVeryShittyPmResLimitWorkaround = true;
|
||||
}
|
||||
return officialSVCs[0x17];
|
||||
case 0x29:
|
||||
return GetHandleInfoHookWrapper;
|
||||
case 0x2A:
|
||||
return GetSystemInfoHookWrapper;
|
||||
case 0x2B:
|
||||
return GetProcessInfoHookWrapper;
|
||||
case 0x2C:
|
||||
return GetThreadInfoHookWrapper;
|
||||
case 0x2D:
|
||||
return ConnectToPortHookWrapper;
|
||||
case 0x2E:
|
||||
return GetCFWInfo; // DEPRECATED
|
||||
case 0x32:
|
||||
return SendSyncRequestHook;
|
||||
case 0x3C:
|
||||
return (debugOfProcess(currentProcess) != NULL) ? officialSVCs[0x3C] : (void *)Break;
|
||||
case 0x59:
|
||||
return SetGpuProt;
|
||||
case 0x5A:
|
||||
return SetWifiEnabled;
|
||||
case 0x79:
|
||||
if(doingVeryShittyPmResLimitWorkaround)
|
||||
{
|
||||
*(vu32 *)(configPage + 0x44) -= __end__ - __start__;
|
||||
doingVeryShittyPmResLimitWorkaround = false;
|
||||
}
|
||||
return officialSVCs[0x79];
|
||||
case 0x7B:
|
||||
return Backdoor;
|
||||
case 0x7C:
|
||||
return KernelSetStateHook;
|
||||
|
||||
|
||||
case 0x80:
|
||||
return CustomBackdoor;
|
||||
|
||||
case 0x90:
|
||||
return convertVAToPA;
|
||||
case 0x91:
|
||||
return flushDataCacheRange;
|
||||
case 0x92:
|
||||
return flushEntireDataCache;
|
||||
case 0x93:
|
||||
return invalidateInstructionCacheRange;
|
||||
case 0x94:
|
||||
return invalidateEntireInstructionCache;
|
||||
|
||||
case 0xA0:
|
||||
return MapProcessMemoryEx;
|
||||
case 0xA1:
|
||||
return UnmapProcessMemoryEx;
|
||||
case 0xA2:
|
||||
return ControlMemoryEx;
|
||||
|
||||
case 0xB0:
|
||||
return ControlService;
|
||||
case 0xB1:
|
||||
return CopyHandleWrapper;
|
||||
case 0xB2:
|
||||
return TranslateHandleWrapper;
|
||||
|
||||
default:
|
||||
return (svcId <= 0x7D) ? officialSVCs[svcId] : NULL;
|
||||
}
|
||||
}
|
||||
43
k11_extension/source/svc/Backdoor.s
Normal file
43
k11_extension/source/svc/Backdoor.s
Normal file
@@ -0,0 +1,43 @@
|
||||
@ This file is part of Luma3DS
|
||||
@ Copyright (C) 2016-2017 Aurora Wright, TuxSH
|
||||
@
|
||||
@ This program is free software: you can redistribute it and/or modify
|
||||
@ it under the terms of the GNU General Public License as published by
|
||||
@ the Free Software Foundation, either version 3 of the License, or
|
||||
@ (at your option) any later version.
|
||||
@
|
||||
@ This program is distributed in the hope that it will be useful,
|
||||
@ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
@ GNU General Public License for more details.
|
||||
@
|
||||
@ You should have received a copy of the GNU General Public License
|
||||
@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
@
|
||||
@ Additional Terms 7.b and 7.c of GPLv3 apply to this file:
|
||||
@ * Requiring preservation of specified reasonable legal notices or
|
||||
@ author attributions in that material or in the Appropriate Legal
|
||||
@ Notices displayed by works containing it.
|
||||
@ * Prohibiting misrepresentation of the origin of that material,
|
||||
@ or requiring that modified versions of such material be marked in
|
||||
@ reasonable ways as different from the original version.
|
||||
|
||||
.text
|
||||
.arm
|
||||
.balign 4
|
||||
|
||||
.global Backdoor
|
||||
.type Backdoor, %function
|
||||
Backdoor:
|
||||
@ Nintendo's code
|
||||
bic r1, sp, #0xff
|
||||
orr r1, r1, #0xf00
|
||||
add r1, r1, #0x28 @ get user stack.
|
||||
|
||||
ldr r2, [r1]
|
||||
stmdb r2!, {sp, lr}
|
||||
mov sp, r2 @ sp_svc = sp_usr. You'll get nice crashes if an interrupt or context switch occurs during svcBackdoor
|
||||
blx r0
|
||||
pop {r0, r1}
|
||||
mov sp, r0
|
||||
bx r1
|
||||
@@ -1,5 +1,5 @@
|
||||
@ This file is part of Luma3DS
|
||||
@ Copyright (C) 2016 Aurora Wright, TuxSH
|
||||
@ Copyright (C) 2016-2017 Aurora Wright, TuxSH
|
||||
@
|
||||
@ This program is free software: you can redistribute it and/or modify
|
||||
@ it under the terms of the GNU General Public License as published by
|
||||
@@ -14,18 +14,22 @@
|
||||
@ You should have received a copy of the GNU General Public License
|
||||
@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
@
|
||||
@ Additional Terms 7.b of GPLv3 applies to this file: Requiring preservation of specified
|
||||
@ reasonable legal notices or author attributions in that material or in the Appropriate Legal
|
||||
@ Notices displayed by works containing it.
|
||||
@ Additional Terms 7.b and 7.c of GPLv3 apply to this file:
|
||||
@ * Requiring preservation of specified reasonable legal notices or
|
||||
@ author attributions in that material or in the Appropriate Legal
|
||||
@ Notices displayed by works containing it.
|
||||
@ * Prohibiting misrepresentation of the origin of that material,
|
||||
@ or requiring that modified versions of such material be marked in
|
||||
@ reasonable ways as different from the original version.
|
||||
|
||||
.section .text.start
|
||||
.align 4
|
||||
.global _start
|
||||
_start:
|
||||
add pc, r0, #(handlers - .) @ Dummy instruction to prevent compiler optimizations
|
||||
.text
|
||||
.arm
|
||||
.balign 4
|
||||
|
||||
handlers:
|
||||
.word FIQHandler
|
||||
.word undefinedInstructionHandler
|
||||
.word prefetchAbortHandler
|
||||
.word dataAbortHandler
|
||||
.global Break
|
||||
.type Break, %function
|
||||
Break:
|
||||
bic r0, sp, #0xf00
|
||||
bic r0, #0xff
|
||||
add r0, #0x1000 @ get page context top
|
||||
bkpt 0xffff
|
||||
56
k11_extension/source/svc/ConnectToPort.c
Normal file
56
k11_extension/source/svc/ConnectToPort.c
Normal file
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* This file is part of Luma3DS
|
||||
* Copyright (C) 2016-2017 Aurora Wright, TuxSH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
|
||||
* * Requiring preservation of specified reasonable legal notices or
|
||||
* author attributions in that material or in the Appropriate Legal
|
||||
* Notices displayed by works containing it.
|
||||
* * Prohibiting misrepresentation of the origin of that material,
|
||||
* or requiring that modified versions of such material be marked in
|
||||
* reasonable ways as different from the original version.
|
||||
*/
|
||||
|
||||
#include "svc/ConnectToPort.h"
|
||||
#include "memory.h"
|
||||
#include "ipc.h"
|
||||
|
||||
Result ConnectToPortHook(Handle *out, const char *name)
|
||||
{
|
||||
char portName[12] = {0};
|
||||
Result res = 0;
|
||||
if(name != NULL)
|
||||
{
|
||||
s32 nb = usrToKernelStrncpy(portName, name, 12);
|
||||
if(nb < 0)
|
||||
return 0xD9001814;
|
||||
else if(nb == 12 && portName[11] != 0)
|
||||
return 0xE0E0181E;
|
||||
}
|
||||
res = ConnectToPort(out, name);
|
||||
if(res != 0)
|
||||
return res;
|
||||
|
||||
KProcessHandleTable *handleTable = handleTableOfProcess(currentCoreContext->objectContext.currentProcess);
|
||||
KClientSession *clientSession = (KClientSession *)KProcessHandleTable__ToKAutoObject(handleTable, *out);
|
||||
if(clientSession != NULL)
|
||||
{
|
||||
SessionInfo_Add(clientSession->parentSession, portName);
|
||||
clientSession->syncObject.autoObject.vtable->DecrementReferenceCount(&clientSession->syncObject.autoObject);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
34
k11_extension/source/svc/ControlMemory.c
Normal file
34
k11_extension/source/svc/ControlMemory.c
Normal file
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* This file is part of Luma3DS
|
||||
* Copyright (C) 2016-2017 Aurora Wright, TuxSH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
|
||||
* * Requiring preservation of specified reasonable legal notices or
|
||||
* author attributions in that material or in the Appropriate Legal
|
||||
* Notices displayed by works containing it.
|
||||
* * Prohibiting misrepresentation of the origin of that material,
|
||||
* or requiring that modified versions of such material be marked in
|
||||
* reasonable ways as different from the original version.
|
||||
*/
|
||||
|
||||
#include "svc/ControlMemory.h"
|
||||
|
||||
Result ControlMemoryHook(u32 *addrOut, u32 addr0, u32 addr1, u32 size, MemOp op, MemPerm perm)
|
||||
{
|
||||
KProcess *currentProcess = currentCoreContext->objectContext.currentProcess;
|
||||
return ControlMemory(addrOut, addr0, addr1, size, op, perm, idOfProcess(currentProcess) == 1);
|
||||
}
|
||||
|
||||
100
k11_extension/source/svc/ControlService.c
Normal file
100
k11_extension/source/svc/ControlService.c
Normal file
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
* This file is part of Luma3DS
|
||||
* Copyright (C) 2016-2017 Aurora Wright, TuxSH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
|
||||
* * Requiring preservation of specified reasonable legal notices or
|
||||
* author attributions in that material or in the Appropriate Legal
|
||||
* Notices displayed by works containing it.
|
||||
* * Prohibiting misrepresentation of the origin of that material,
|
||||
* or requiring that modified versions of such material be marked in
|
||||
* reasonable ways as different from the original version.
|
||||
*/
|
||||
|
||||
#include "svc/ControlService.h"
|
||||
#include "memory.h"
|
||||
#include "ipc.h"
|
||||
|
||||
Result ControlService(ServiceOp op, u32 varg1, u32 varg2)
|
||||
{
|
||||
Result res = 0;
|
||||
KProcessHandleTable *handleTable = handleTableOfProcess(currentCoreContext->objectContext.currentProcess);
|
||||
|
||||
switch(op)
|
||||
{
|
||||
case SERVICEOP_GET_NAME:
|
||||
{
|
||||
KSession *session = NULL;
|
||||
SessionInfo *info = NULL;
|
||||
KAutoObject *obj = KProcessHandleTable__ToKAutoObject(handleTable, (Handle)varg2);
|
||||
if(obj == NULL)
|
||||
return 0xD8E007F7; // invalid handle
|
||||
else
|
||||
{
|
||||
// not the exact same tests but it should work
|
||||
if(strcmp(classNameOfAutoObject(obj), "KServerSession") == 0)
|
||||
session = ((KServerSession *)obj)->parentSession;
|
||||
else if(strcmp(classNameOfAutoObject(obj), "KClientSession") == 0)
|
||||
session = ((KClientSession *)obj)->parentSession;
|
||||
}
|
||||
|
||||
if(session != NULL)
|
||||
info = SessionInfo_Lookup(session);
|
||||
|
||||
if(info == NULL)
|
||||
res = 0xD8E007F7;
|
||||
else
|
||||
{
|
||||
// names are limited to 11 characters (for ports)
|
||||
// kernelToUsrStrncpy doesn't clear trailing bytes
|
||||
char name[12] = { 0 };
|
||||
strncpy(name, info->name, 12);
|
||||
res = kernelToUsrMemcpy8((void *)varg1, name, strlen(name) + 1) ? 0 : 0xE0E01BF5;
|
||||
}
|
||||
|
||||
obj->vtable->DecrementReferenceCount(obj);
|
||||
return res;
|
||||
}
|
||||
|
||||
case SERVICEOP_STEAL_CLIENT_SESSION:
|
||||
{
|
||||
char name[12] = { 0 };
|
||||
SessionInfo *info = NULL;
|
||||
if(name != NULL)
|
||||
{
|
||||
s32 nb = usrToKernelStrncpy(name, (const char *)varg2, 12);
|
||||
if(nb < 0)
|
||||
return 0xD9001814;
|
||||
else if(nb == 12 && name[11] != 0)
|
||||
return 0xE0E0181E;
|
||||
}
|
||||
|
||||
info = SessionInfo_FindFirst(name);
|
||||
|
||||
if(info == NULL)
|
||||
return 0x9401BFE; // timeout (the wanted service is likely not initalized)
|
||||
else
|
||||
{
|
||||
Handle out;
|
||||
res = createHandleForThisProcess(&out, &info->session->clientSession.syncObject.autoObject);
|
||||
return (res != 0) ? res : (kernelToUsrMemcpy32((u32 *)varg1, (u32 *)&out, 4) ? 0 : (Result)0xE0E01BF5);
|
||||
}
|
||||
}
|
||||
|
||||
default:
|
||||
return 0xF8C007F4;
|
||||
}
|
||||
}
|
||||
76
k11_extension/source/svc/CopyHandle.c
Normal file
76
k11_extension/source/svc/CopyHandle.c
Normal file
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* This file is part of Luma3DS
|
||||
* Copyright (C) 2016-2017 Aurora Wright, TuxSH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
|
||||
* * Requiring preservation of specified reasonable legal notices or
|
||||
* author attributions in that material or in the Appropriate Legal
|
||||
* Notices displayed by works containing it.
|
||||
* * Prohibiting misrepresentation of the origin of that material,
|
||||
* or requiring that modified versions of such material be marked in
|
||||
* reasonable ways as different from the original version.
|
||||
*/
|
||||
|
||||
#include "svc/CopyHandle.h"
|
||||
#include "memory.h"
|
||||
|
||||
Result CopyHandle(Handle *outHandle, Handle outProcessHandle, Handle inHandle, Handle inProcessHandle)
|
||||
{
|
||||
KProcessHandleTable *handleTable = handleTableOfProcess(currentCoreContext->objectContext.currentProcess);
|
||||
KProcess *inProcess, *outProcess;
|
||||
Result res;
|
||||
|
||||
if(inProcessHandle == CUR_PROCESS_HANDLE)
|
||||
{
|
||||
inProcess = currentCoreContext->objectContext.currentProcess;
|
||||
KAutoObject__AddReference((KAutoObject *)inProcess);
|
||||
}
|
||||
else
|
||||
inProcess = KProcessHandleTable__ToKProcess(handleTable, inProcessHandle);
|
||||
|
||||
if(inProcess == NULL)
|
||||
return 0xD8E007F7; // invalid handle
|
||||
|
||||
if(outProcessHandle == CUR_PROCESS_HANDLE)
|
||||
{
|
||||
outProcess = currentCoreContext->objectContext.currentProcess;
|
||||
KAutoObject__AddReference((KAutoObject *)outProcess);
|
||||
}
|
||||
else
|
||||
outProcess = KProcessHandleTable__ToKProcess(handleTable, outProcessHandle);
|
||||
|
||||
if(outProcess == NULL)
|
||||
{
|
||||
((KAutoObject *)inProcess)->vtable->DecrementReferenceCount((KAutoObject *)inProcess);
|
||||
return 0xD8E007F7; // invalid handle
|
||||
}
|
||||
|
||||
KAutoObject *obj = KProcessHandleTable__ToKAutoObject(handleTableOfProcess(inProcess), inHandle);
|
||||
if(obj == NULL)
|
||||
{
|
||||
((KAutoObject *)inProcess)->vtable->DecrementReferenceCount((KAutoObject *)inProcess);
|
||||
((KAutoObject *)outProcess)->vtable->DecrementReferenceCount((KAutoObject *)outProcess);
|
||||
return 0xD8E007F7; // invalid handle
|
||||
}
|
||||
|
||||
res = createHandleForProcess(outHandle, outProcess, obj);
|
||||
|
||||
obj->vtable->DecrementReferenceCount(obj);
|
||||
((KAutoObject *)inProcess)->vtable->DecrementReferenceCount((KAutoObject *)inProcess);
|
||||
((KAutoObject *)outProcess)->vtable->DecrementReferenceCount((KAutoObject *)outProcess);
|
||||
|
||||
return res;
|
||||
}
|
||||
38
k11_extension/source/svc/CustomBackdoor.s
Normal file
38
k11_extension/source/svc/CustomBackdoor.s
Normal file
@@ -0,0 +1,38 @@
|
||||
@ This file is part of Luma3DS
|
||||
@ Copyright (C) 2016-2017 Aurora Wright, TuxSH
|
||||
@
|
||||
@ This program is free software: you can redistribute it and/or modify
|
||||
@ it under the terms of the GNU General Public License as published by
|
||||
@ the Free Software Foundation, either version 3 of the License, or
|
||||
@ (at your option) any later version.
|
||||
@
|
||||
@ This program is distributed in the hope that it will be useful,
|
||||
@ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
@ GNU General Public License for more details.
|
||||
@
|
||||
@ You should have received a copy of the GNU General Public License
|
||||
@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
@
|
||||
@ Additional Terms 7.b and 7.c of GPLv3 apply to this file:
|
||||
@ * Requiring preservation of specified reasonable legal notices or
|
||||
@ author attributions in that material or in the Appropriate Legal
|
||||
@ Notices displayed by works containing it.
|
||||
@ * Prohibiting misrepresentation of the origin of that material,
|
||||
@ or requiring that modified versions of such material be marked in
|
||||
@ reasonable ways as different from the original version.
|
||||
|
||||
.text
|
||||
.arm
|
||||
.balign 4
|
||||
|
||||
.global CustomBackdoor
|
||||
.type CustomBackdoor, %function
|
||||
CustomBackdoor:
|
||||
push {r4, lr}
|
||||
mov r4, r0
|
||||
mov r0, r1
|
||||
mov r1, r2
|
||||
mov r2, r3
|
||||
blx r4
|
||||
pop {r4, pc}
|
||||
33
k11_extension/source/svc/GetCFWInfo.c
Normal file
33
k11_extension/source/svc/GetCFWInfo.c
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* This file is part of Luma3DS
|
||||
* Copyright (C) 2016-2017 Aurora Wright, TuxSH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
|
||||
* * Requiring preservation of specified reasonable legal notices or
|
||||
* author attributions in that material or in the Appropriate Legal
|
||||
* Notices displayed by works containing it.
|
||||
* * Prohibiting misrepresentation of the origin of that material,
|
||||
* or requiring that modified versions of such material be marked in
|
||||
* reasonable ways as different from the original version.
|
||||
*/
|
||||
|
||||
#include "svc/GetCFWInfo.h"
|
||||
|
||||
// DEPRECATED
|
||||
Result GetCFWInfo(CfwInfo *out)
|
||||
{
|
||||
return kernelToUsrMemcpy8(out, &cfwInfo, 16) ? 0 : 0xE0E01BF5;
|
||||
}
|
||||
62
k11_extension/source/svc/GetHandleInfo.c
Normal file
62
k11_extension/source/svc/GetHandleInfo.c
Normal file
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* This file is part of Luma3DS
|
||||
* Copyright (C) 2016-2017 Aurora Wright, TuxSH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
|
||||
* * Requiring preservation of specified reasonable legal notices or
|
||||
* author attributions in that material or in the Appropriate Legal
|
||||
* Notices displayed by works containing it.
|
||||
* * Prohibiting misrepresentation of the origin of that material,
|
||||
* or requiring that modified versions of such material be marked in
|
||||
* reasonable ways as different from the original version.
|
||||
*/
|
||||
|
||||
#include "svc/GetThreadInfo.h"
|
||||
#include "memory.h"
|
||||
|
||||
Result GetHandleInfoHook(s64 *out, Handle handle, u32 type)
|
||||
{
|
||||
if(type == 0x10000) // KDebug and KProcess: get context ID
|
||||
{
|
||||
KProcessHwInfo *hwInfo;
|
||||
KProcessHandleTable *handleTable = handleTableOfProcess(currentCoreContext->objectContext.currentProcess);
|
||||
KAutoObject *obj;
|
||||
if(handle == CUR_PROCESS_HANDLE)
|
||||
{
|
||||
obj = (KAutoObject *)(currentCoreContext->objectContext.currentProcess);
|
||||
KAutoObject__AddReference(obj);
|
||||
}
|
||||
else
|
||||
obj = KProcessHandleTable__ToKAutoObject(handleTable, handle);
|
||||
|
||||
if(obj == NULL)
|
||||
return 0xD8E007F7;
|
||||
|
||||
if(strcmp(classNameOfAutoObject(obj), "KDebug") == 0)
|
||||
hwInfo = hwInfoOfProcess(((KDebug *)obj)->owner);
|
||||
else if(strcmp(classNameOfAutoObject(obj), "KProcess") == 0)
|
||||
hwInfo = hwInfoOfProcess((KProcess *)obj);
|
||||
else
|
||||
hwInfo = NULL;
|
||||
|
||||
*out = hwInfo != NULL ? KPROCESSHWINFO_GET_RVALUE(hwInfo, contextId) : -1;
|
||||
|
||||
obj->vtable->DecrementReferenceCount(obj);
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
return GetHandleInfo(out, handle, type);
|
||||
}
|
||||
94
k11_extension/source/svc/GetProcessInfo.c
Normal file
94
k11_extension/source/svc/GetProcessInfo.c
Normal file
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* This file is part of Luma3DS
|
||||
* Copyright (C) 2016-2017 Aurora Wright, TuxSH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
|
||||
* * Requiring preservation of specified reasonable legal notices or
|
||||
* author attributions in that material or in the Appropriate Legal
|
||||
* Notices displayed by works containing it.
|
||||
* * Prohibiting misrepresentation of the origin of that material,
|
||||
* or requiring that modified versions of such material be marked in
|
||||
* reasonable ways as different from the original version.
|
||||
*/
|
||||
|
||||
#include "svc/GetProcessInfo.h"
|
||||
#include "memory.h"
|
||||
|
||||
Result GetProcessInfoHook(s64 *out, Handle processHandle, u32 type)
|
||||
{
|
||||
Result res = 0;
|
||||
|
||||
if(type >= 0x10000)
|
||||
{
|
||||
KProcessHandleTable *handleTable = handleTableOfProcess(currentCoreContext->objectContext.currentProcess);
|
||||
KProcess *process;
|
||||
if(processHandle == CUR_PROCESS_HANDLE)
|
||||
{
|
||||
process = currentCoreContext->objectContext.currentProcess;
|
||||
KAutoObject__AddReference((KAutoObject *)process);
|
||||
}
|
||||
else
|
||||
process = KProcessHandleTable__ToKProcess(handleTable, processHandle);
|
||||
|
||||
if(process == NULL)
|
||||
return 0xD8E007F7; // invalid handle
|
||||
|
||||
switch(type)
|
||||
{
|
||||
case 0x10000:
|
||||
memcpy(out, codeSetOfProcess(process)->processName, 8);
|
||||
break;
|
||||
case 0x10001:
|
||||
*(u64 *)out = codeSetOfProcess(process)->titleId;
|
||||
break;
|
||||
case 0x10002:
|
||||
*out = codeSetOfProcess(process)->nbTextPages << 12;
|
||||
break;
|
||||
case 0x10003:
|
||||
*out = codeSetOfProcess(process)->nbRodataPages << 12;
|
||||
break;
|
||||
case 0x10004:
|
||||
*out = codeSetOfProcess(process)->nbRwPages << 12;
|
||||
break;
|
||||
case 0x10005:
|
||||
*out = (s64)(u64)(u32)codeSetOfProcess(process)->textSection.section.loadAddress;
|
||||
break;
|
||||
case 0x10006:
|
||||
*out = (s64)(u64)(u32)codeSetOfProcess(process)->rodataSection.section.loadAddress;
|
||||
break;
|
||||
case 0x10007:
|
||||
*out = (s64)(u64)(u32)codeSetOfProcess(process)->dataSection.section.loadAddress;
|
||||
break;
|
||||
case 0x10008:
|
||||
{
|
||||
KProcessHwInfo *hwInfo = hwInfoOfProcess(process);
|
||||
u32 ttb = KPROCESSHWINFO_GET_RVALUE(hwInfo, translationTableBase);
|
||||
*out = ttb & ~((1 << (14 - TTBCR)) - 1);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
res = 0xD8E007ED; // invalid enum value
|
||||
break;
|
||||
}
|
||||
|
||||
((KAutoObject *)process)->vtable->DecrementReferenceCount((KAutoObject *)process);
|
||||
}
|
||||
|
||||
else
|
||||
res = GetProcessInfo(out, processHandle, type);
|
||||
|
||||
return res;
|
||||
}
|
||||
140
k11_extension/source/svc/GetSystemInfo.c
Normal file
140
k11_extension/source/svc/GetSystemInfo.c
Normal file
@@ -0,0 +1,140 @@
|
||||
/*
|
||||
* This file is part of Luma3DS
|
||||
* Copyright (C) 2016-2017 Aurora Wright, TuxSH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
|
||||
* * Requiring preservation of specified reasonable legal notices or
|
||||
* author attributions in that material or in the Appropriate Legal
|
||||
* Notices displayed by works containing it.
|
||||
* * Prohibiting misrepresentation of the origin of that material,
|
||||
* or requiring that modified versions of such material be marked in
|
||||
* reasonable ways as different from the original version.
|
||||
*/
|
||||
|
||||
#include "svc/GetSystemInfo.h"
|
||||
#include "utils.h"
|
||||
#include "ipc.h"
|
||||
#include "synchronization.h"
|
||||
|
||||
Result GetSystemInfoHook(s64 *out, s32 type, s32 param)
|
||||
{
|
||||
Result res = 0;
|
||||
|
||||
switch(type)
|
||||
{
|
||||
case 0x10000:
|
||||
{
|
||||
switch(param)
|
||||
{
|
||||
case 0:
|
||||
*out = SYSTEM_VERSION(cfwInfo.versionMajor, cfwInfo.versionMinor, cfwInfo.versionBuild);
|
||||
break;
|
||||
case 1:
|
||||
*out = cfwInfo.commitHash;
|
||||
break;
|
||||
case 2:
|
||||
*out = (cfwInfo.configFormatVersionMajor << 16) | cfwInfo.configFormatVersionMinor;
|
||||
break;
|
||||
case 3:
|
||||
*out = cfwInfo.config;
|
||||
break;
|
||||
case 4:
|
||||
*out = cfwInfo.multiConfig;
|
||||
break;
|
||||
case 5:
|
||||
*out = cfwInfo.bootConfig;
|
||||
break;
|
||||
|
||||
case 0x100:
|
||||
*out = (s64)cfwInfo.hbldr3dsxTitleId;
|
||||
break;
|
||||
case 0x101:
|
||||
*out = cfwInfo.rosalinaMenuCombo;
|
||||
break;
|
||||
|
||||
case 0x200: // isRelease
|
||||
*out = cfwInfo.flags & 1;
|
||||
break;
|
||||
case 0x201: // isN3DS
|
||||
*out = (cfwInfo.flags >> 4) & 1;
|
||||
break;
|
||||
case 0x202: // isSafeMode
|
||||
*out = (cfwInfo.flags >> 5) & 1;
|
||||
break;
|
||||
case 0x203: // isSdMode
|
||||
*out = (cfwInfo.flags >> 6) & 1;
|
||||
break;
|
||||
default:
|
||||
res = 0xF8C007F4; // not implemented
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x10001: // N3DS-related info
|
||||
{
|
||||
if(isN3DS)
|
||||
{
|
||||
switch(param)
|
||||
{
|
||||
case 0: // current clock rate
|
||||
*out = (((CFG11_MPCORE_CLKCNT >> 1) & 3) + 1) * 268;
|
||||
break;
|
||||
case 1: // higher clock rate
|
||||
*out = (((CFG11_MPCORE_CFG >> 2) & 1) + 2) * 268;
|
||||
break;
|
||||
case 2: // L2C enabled status
|
||||
*out = L2C_CTRL & 1;
|
||||
break;
|
||||
default:
|
||||
res = 0xF8C007F4;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
res = 0xF8C007F4;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x10002: // MMU config (cached values from booting)
|
||||
{
|
||||
switch(param)
|
||||
{
|
||||
case 0:
|
||||
*out = TTBCR;
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
if((u32)param <= getNumberOfCores())
|
||||
*out = L1MMUTableAddrs[param - 1];
|
||||
else
|
||||
res = 0xF8C007F4;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
GetSystemInfo(out, type, param);
|
||||
break;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
60
k11_extension/source/svc/GetThreadInfo.c
Normal file
60
k11_extension/source/svc/GetThreadInfo.c
Normal file
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* This file is part of Luma3DS
|
||||
* Copyright (C) 2016-2017 Aurora Wright, TuxSH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
|
||||
* * Requiring preservation of specified reasonable legal notices or
|
||||
* author attributions in that material or in the Appropriate Legal
|
||||
* Notices displayed by works containing it.
|
||||
* * Prohibiting misrepresentation of the origin of that material,
|
||||
* or requiring that modified versions of such material be marked in
|
||||
* reasonable ways as different from the original version.
|
||||
*/
|
||||
|
||||
#include "svc/GetThreadInfo.h"
|
||||
#include "memory.h"
|
||||
|
||||
Result GetThreadInfoHook(s64 *out, Handle threadHandle, u32 type)
|
||||
{
|
||||
Result res = 0;
|
||||
|
||||
if(type == 0x10000) // Get TLS
|
||||
{
|
||||
KProcessHandleTable *handleTable = handleTableOfProcess(currentCoreContext->objectContext.currentProcess);
|
||||
KThread *thread;
|
||||
|
||||
if(threadHandle == CUR_THREAD_HANDLE)
|
||||
{
|
||||
thread = currentCoreContext->objectContext.currentThread;
|
||||
KAutoObject__AddReference(&thread->syncObject.autoObject);
|
||||
}
|
||||
else
|
||||
thread = KProcessHandleTable__ToKThread(handleTable, threadHandle);
|
||||
|
||||
if(thread == NULL)
|
||||
return 0xD8E007F7; // invalid handle
|
||||
|
||||
*out = (s64)(u64)(u32)thread->threadLocalStorage;
|
||||
|
||||
KAutoObject *obj = (KAutoObject *)thread;
|
||||
obj->vtable->DecrementReferenceCount(obj);
|
||||
}
|
||||
|
||||
else
|
||||
res = GetThreadInfo(out, threadHandle, type);
|
||||
|
||||
return res;
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user