Compare commits

..

296 Commits

Author SHA1 Message Date
Michael Scire
9df13781c2 git subrepo push libraries
subrepo:
  subdir:   "libraries"
  merged:   "eb667fea5"
upstream:
  origin:   "https://github.com/Atmosphere-NX/Atmosphere-libs"
  branch:   "master"
  commit:   "eb667fea5"
git-subrepo:
  version:  "0.4.0"
  origin:   "???"
  commit:   "???"
2021-07-06 07:29:10 -07:00
Michael Scire
283736878d docs: add changelog for 0.19.5 2021-07-06 07:28:12 -07:00
Michael Scire
f863164648 ams: basic support for 12.1.0 2021-07-06 07:13:56 -07:00
Michael Scire
3eb76fcd16 exo: update for 12.1.0 2021-07-06 06:55:59 -07:00
Michael Scire
2088c5a34a kern: fix handling of is_aligned parameter in DevicePageTable 2021-07-04 10:45:14 -07:00
Michael Scire
846cde52e0 fs.mitm: ns registers program index map info, not am 2021-06-28 22:43:56 -07:00
Michael Scire
a3dd445b32 fs.mitm: add OpenDataStorageWithProgramIndex support (theoretically, closes #1250) 2021-06-28 22:24:26 -07:00
Michael Scire
c362838e11 erpt: fix 0x100 byte memory leak on creation of new report 2021-06-28 17:36:42 -07:00
Michael Scire
e086022b77 build: use DWARFv4 explicitly for IDA compatibility with debug elfs 2021-06-25 23:48:41 -07:00
Michael Scire
70c1bad08b git subrepo push emummc
subrepo:
  subdir:   "emummc"
  merged:   "cbc294c3"
upstream:
  origin:   "https://github.com/m4xw/emuMMC"
  branch:   "develop"
  commit:   "cbc294c3"
git-subrepo:
  version:  "0.4.1"
  origin:   "???"
  commit:   "???"
2021-06-22 16:13:04 -07:00
Michael Scire
38f9a76ba0 emummc: add custom ld/specs file 2021-06-22 16:12:27 -07:00
Michael Scire
4892ffae15 kern: implement improved [new page tables are zero] invariant 2021-06-17 13:03:46 -07:00
Michael Scire
25305257d6 kern: fix missing peak set in KResourceLimit::SetLimitValue 2021-06-17 12:57:56 -07:00
Michael Scire
e423aef033 kern: ensure InitArguments do not cross page boundaries 2021-06-17 12:49:25 -07:00
Michael Scire
8a6afe7909 dns.mitm: fix wildcardcmp failure case (#1539) 2021-06-15 16:35:26 -07:00
Aurora
c02f32f1bf reboot_to_payload: Use ams:bpc API to set payload, reboot safely and prevent usage on Mariko (#1543) 2021-06-13 16:55:46 -05:00
Michael Scire
2ab01ad33c git subrepo push libraries
subrepo:
  subdir:   "libraries"
  merged:   "11ea38a7"
upstream:
  origin:   "https://github.com/Atmosphere-NX/Atmosphere-libs"
  branch:   "master"
  commit:   "11ea38a7"
git-subrepo:
  version:  "0.4.1"
  origin:   "???"
  commit:   "???"
2021-06-08 08:09:48 -07:00
Michael Scire
3dbc79dd5c ams: bump version to 0.19.4 2021-06-08 08:09:05 -07:00
Michael Scire
90b54c03b3 git subrepo pull emummc
subrepo:
  subdir:   "emummc"
  merged:   "219c723c"
upstream:
  origin:   "https://github.com/m4xw/emuMMC"
  branch:   "develop"
  commit:   "219c723c"
git-subrepo:
  version:  "0.4.1"
  origin:   "???"
  commit:   "???"
2021-06-08 07:50:35 -07:00
Michael Scire
7821241356 kern: fix enormous whoops 2021-05-31 04:20:59 -07:00
Michael Scire
8fea8d9b2e sm: lighten abort restrictions on mitm handle acquisition (closes #1528) 2021-05-30 22:53:32 -07:00
Michael Scire
dcdf46f576 kern: slightly improve genericity of debugger break event 2021-05-30 21:13:42 -07:00
Michael Scire
df5537b748 mem: actually fully fix the heap bug, add comments for future self 2021-05-26 23:21:08 -07:00
Michael Scire
0f2855ada8 mem: fix rare crash/logic error in heap allocation code 2021-05-26 20:43:03 -07:00
Michael Scire
c790d03693 libstrat: fix override operator new to be noexcept (closes #1494) 2021-05-16 23:10:13 -07:00
Michael Scire
25be7c5b1b git subrepo push libraries
subrepo:
  subdir:   "libraries"
  merged:   "b5b55f60"
upstream:
  origin:   "https://github.com/Atmosphere-NX/Atmosphere-libs"
  branch:   "master"
  commit:   "b5b55f60"
git-subrepo:
  version:  "0.4.1"
  origin:   "???"
  commit:   "???"
2021-05-12 22:47:42 -07:00
Michael Scire
7e05e12b83 sf/tipc: treat min/max as true min/max, rather than numeric 2021-05-12 22:43:39 -07:00
Michael Scire
99d7f72c51 warmboot: remove superfluous firmware version check 2021-05-12 16:57:10 -07:00
Michael Scire
691a453d77 docs: amend changelog 2021-05-12 09:11:19 -07:00
Michael Scire
88246f475c git subrepo push libraries
subrepo:
  subdir:   "libraries"
  merged:   "9ac6f527"
upstream:
  origin:   "https://github.com/Atmosphere-NX/Atmosphere-libs"
  branch:   "master"
  commit:   "9ac6f527"
git-subrepo:
  version:  "0.4.1"
  origin:   "???"
  commit:   "???"
2021-05-12 09:10:13 -07:00
Michael Scire
269d4496b2 docs: update changelog for 0.19.3 2021-05-12 09:08:55 -07:00
Michael Scire
bb4c7a390b ams: update for 12.0.2 2021-05-12 09:08:47 -07:00
Dark-Mind
b846628362 Update issue template to ask whether sysmmc or emummc. 2021-05-12 08:27:21 -07:00
Michael Scire
26fb201518 dns.mitm: handle nullptr hostname 2021-05-10 13:27:14 -07:00
Michael Scire
01ce7cef14 exo: revert section sorting 2021-05-10 07:59:38 -07:00
Michael Scire
3f3aaa01fa git subrepo clone --force https://github.com/m4xw/emummc
subrepo:
  subdir:   "emummc"
  merged:   "c6717b93"
upstream:
  origin:   "https://github.com/m4xw/emummc"
  branch:   "develop"
  commit:   "c6717b93"
git-subrepo:
  version:  "0.4.1"
  origin:   "???"
  commit:   "???"
2021-05-10 07:50:39 -07:00
Michael Scire
bf8de39e69 ams: move around abort handler to avoid linker errors 2021-05-07 17:49:10 -07:00
Michael Scire
6bb4253df5 emummc: style-change 2021-05-05 09:34:29 -07:00
Michael Scire
cfd7121574 emummc: advance buffer for multi-file case 2021-05-05 08:44:53 -07:00
Michael Scire
972681c57e emummc: fix file-based accesses that cross file boundaries 2021-05-05 08:37:02 -07:00
Michael Scire
0a11cbc2d6 exo: sort sections by alignment 2021-05-02 10:50:18 -07:00
Michael Scire
32f487abfb sm: update to excise unnecessary library code 2021-05-02 10:33:15 -07:00
Michael Scire
7d61cab01c fs: add access log strings for DirectoryEntryType 2021-04-30 19:19:22 -07:00
Michael Scire
14ed4e4057 erpt: fix reading files that don't exist 2021-04-30 14:44:53 -07:00
Michael Scire
e8ba632606 git subrepo push libraries
subrepo:
  subdir:   "libraries"
  merged:   "acee57e8"
upstream:
  origin:   "https://github.com/Atmosphere-NX/Atmosphere-libs"
  branch:   "master"
  commit:   "acee57e8"
git-subrepo:
  version:  "0.4.1"
  origin:   "???"
  commit:   "???"
2021-04-30 10:04:30 -07:00
Michael Scire
dbcb1e1564 loader: avoid UB when doing count trailing zeros 2021-04-30 10:03:54 -07:00
Michael Scire
15381409dc fs: fix missed operation rename 2021-04-30 09:02:58 -07:00
Michael Scire
10ad6934ac git subrepo push libraries
subrepo:
  subdir:   "libraries"
  merged:   "1c5df037"
upstream:
  origin:   "https://github.com/Atmosphere-NX/Atmosphere-libs"
  branch:   "master"
  commit:   "1c5df037"
git-subrepo:
  version:  "0.4.1"
  origin:   "???"
  commit:   "???"
2021-04-30 08:56:36 -07:00
Michael Scire
03e66efd85 docs: add changelog for 0.19.2 2021-04-30 08:56:03 -07:00
Michael Scire
7040e8976d i2c: add aula pmic device code 2021-04-30 08:42:25 -07:00
Michael Scire
296a6af058 boot: update all autogenerated parameters other than charge 2021-04-30 08:37:51 -07:00
Michael Scire
2c332d1cf8 ams: bump api version to 0.19.2 2021-04-30 05:00:25 -07:00
Michael Scire
243d7dc777 ams: write-protect stratosphere.romfs 2021-04-30 04:57:46 -07:00
Michael Scire
355010ad84 erpt: implement forced shutdown detection 2021-04-30 04:21:03 -07:00
Michael Scire
ef0c15b764 erpt: Implement 12.0.0 AppletTotalActiveTime tracking 2021-04-29 21:48:47 -07:00
Michael Scire
0dc308d92a fs: properly implement OperateRangeWithBuffer, correct OperationId names. 2021-04-29 20:09:45 -07:00
Michael Scire
eb5542963f git subrepo push libraries
subrepo:
  subdir:   "libraries"
  merged:   "4a48e0ee"
upstream:
  origin:   "https://github.com/Atmosphere-NX/Atmosphere-libs"
  branch:   "master"
  commit:   "4a48e0ee"
git-subrepo:
  version:  "0.4.1"
  origin:   "???"
  commit:   "???"
2021-04-29 03:05:29 -07:00
Michael Scire
18673d96cb daybreak: fix compat with newer deko3d 2021-04-29 01:21:09 -07:00
Michael Scire
36f6bdc3a0 fusee/sept: update to suppress spurious gcc warnings 2021-04-29 01:13:48 -07:00
Michael Scire
d6fff49845 exo: remove duplicate flags 2021-04-29 01:07:01 -07:00
Michael Scire
d05e8fb23a exo: fix for newer binutils 2021-04-29 01:04:26 -07:00
Michael Scire
0767d9f8da ams: assume gcc 11 2021-04-28 15:13:29 -07:00
Michael Scire
21f3d29df7 strat: compat with gcc 11 2021-04-26 20:06:28 -07:00
Michael Scire
4f16106702 exo/meso: update for gcc 11 compatibility 2021-04-26 20:06:18 -07:00
Michael Scire
19be54ff95 kern: fix initial process binary load on 2.0.0-4.1.0 (closes #1460) 2021-04-21 19:24:41 -07:00
Michael Scire
ed80d6ec8c util: add compile-time validation tests for intrusive red black trees 2021-04-21 05:06:11 -07:00
Michael Scire
57b6c71c1c util: implement red black trees as templates over macros 2021-04-20 16:56:33 -07:00
Michael Scire
0a11d341b7 kern: fix constant evaluation correctness, codegen tweak 2021-04-20 14:25:06 -07:00
Michael Scire
8010290472 kern: tweak KHandleTable codegen 2021-04-19 18:04:02 -07:00
Michael Scire
fbc526d163 kern: tweak KAutoObject::Open/Close codegen 2021-04-19 18:03:27 -07:00
Michael Scire
5bb790e4a7 erpt: implement AppletActiveTimeInfoList 2021-04-16 00:55:22 -07:00
Michael Scire
0a6219e6e0 kern: add names/links to kern_assembly_offsets.h 2021-04-15 15:43:29 -07:00
Michael Scire
037b04ac60 kern: mostly kill magic numbers in assembly, fix SVCs >= 0x80 2021-04-14 18:01:08 -07:00
Michael Scire
9e563d590b pm: account for 12.0.0 resource limit changes 2021-04-14 00:41:31 -07:00
Michael Scire
bdcf02a3ef tipc: ports use objects in the object manager 2021-04-14 00:34:46 -07:00
Michael Scire
88ac85c423 sm: save 0x1000 in data costs by not aligning server manager to 0x1000 2021-04-14 00:12:21 -07:00
Michael Scire
2e1a93f1d1 strat: no longer materially constrained by sm session limit 2021-04-13 23:58:10 -07:00
Michael Scire
997e4dd665 git subrepo push libraries
subrepo:
  subdir:   "libraries"
  merged:   "86c2eec8"
upstream:
  origin:   "https://github.com/Atmosphere-NX/Atmosphere-libs"
  branch:   "master"
  commit:   "86c2eec8"
git-subrepo:
  version:  "0.4.1"
  origin:   "???"
  commit:   "???"
2021-04-12 17:14:38 -07:00
Michael Scire
aa2d03d8e1 ams: bump to 0.19.1 2021-04-12 17:14:07 -07:00
Michael Scire
274c1deae4 git subrepo push libraries
subrepo:
  subdir:   "libraries"
  merged:   "68ddbc73"
upstream:
  origin:   "https://github.com/Atmosphere-NX/Atmosphere-libs"
  branch:   "master"
  commit:   "68ddbc73"
git-subrepo:
  version:  "0.4.1"
  origin:   "???"
  commit:   "???"
2021-04-12 17:13:43 -07:00
Michael Scire
d5bbf32a26 docs: add 0.19.1 changelog 2021-04-12 17:13:12 -07:00
Michael Scire
97a251b4b2 ncm: fix iteration of nested-subdirectory content files 2021-04-12 17:10:27 -07:00
Michael Scire
9d30917f4e boot2: migration also not launched in 12.0.0 2021-04-11 10:37:04 -07:00
Michael Scire
c67c29ebd5 ncm: fix random error when deleting content 2021-04-11 05:44:13 -07:00
Michael Scire
88dd414721 git subrepo push libraries
subrepo:
  subdir:   "libraries"
  merged:   "44279dbac"
upstream:
  origin:   "https://github.com/Atmosphere-NX/Atmosphere-libs"
  branch:   "master"
  commit:   "44279dbac"
git-subrepo:
  version:  "0.4.1"
  origin:   "https://github.com/ingydotnet/git-subrepo"
  commit:   "a04d8c2"
2021-04-11 04:02:17 -07:00
Michael Scire
0f6f13a1ac git subrepo push emummc
subrepo:
  subdir:   "emummc"
  merged:   "b355ee6a8"
upstream:
  origin:   "https://github.com/m4xw/emuMMC"
  branch:   "develop"
  commit:   "b355ee6a8"
git-subrepo:
  version:  "0.4.1"
  origin:   "https://github.com/ingydotnet/git-subrepo"
  commit:   "a04d8c2"
2021-04-11 03:58:13 -07:00
Michael Scire
b24784f5c1 git subrepo pull emummc
subrepo:
  subdir:   "emummc"
  merged:   "38ed90b6e"
upstream:
  origin:   "https://github.com/m4xw/emuMMC"
  branch:   "develop"
  commit:   "5a29e1b2c"
git-subrepo:
  version:  "0.4.1"
  origin:   "https://github.com/ingydotnet/git-subrepo"
  commit:   "a04d8c2"
2021-04-11 03:51:53 -07:00
Michael Scire
3b3082cf58 changelog: add note about extensions needing recompile 2021-04-11 03:42:16 -07:00
Michael Scire
38a2fdcd76 docs: add changelog for 0.19.0 2021-04-11 03:42:16 -07:00
Michael Scire
0ca2f962de usb: add usb3.0 patches for 12.0.0 2021-04-11 03:42:16 -07:00
Michael Scire
03a98635d8 fs: add (stubbed) OperateRangeWithBuffer implementation 2021-04-11 03:42:16 -07:00
Michael Scire
461e2ced6f erpt: add (stubbed, TODO after 0.19.0) support for 12.0.0 2021-04-11 03:42:16 -07:00
Michael Scire
b2d2f65b87 boot2: grc is no longer launched by boot2 on 12.0.0+ 2021-04-11 03:42:16 -07:00
Michael Scire
b2b0c50802 pgl: update to use tipc (untested) 2021-04-11 03:42:16 -07:00
Michael Scire
1118421fa6 strat: changes for sm tipc (boots 11.0.1, now) 2021-04-11 03:42:16 -07:00
Michael Scire
b1b3914ccf tipc: Result is first raw data word, not last 2021-04-11 03:42:16 -07:00
Michael Scire
9be8b32311 tipc/sm: various fixes for issues 2021-04-11 03:42:16 -07:00
Michael Scire
57c8bc432d sm: reimplement using tipc instead of cmif (probably broken, untested) 2021-04-11 03:42:16 -07:00
Michael Scire
58776f5ba8 tipc: server processor fixes (compiles!) 2021-04-11 03:42:16 -07:00
Michael Scire
affeeb2724 tipc: implement ServerManager processing logic 2021-04-11 03:42:16 -07:00
Michael Scire
822875ecf5 tipc: implement framework/server support logic (except for actual processing) 2021-04-11 03:42:16 -07:00
Michael Scire
e3a65b1405 tipc: fix deserialization of buffers 2021-04-11 03:42:16 -07:00
Michael Scire
20a7fa1588 tipc: hard-enforce boolean constraints in command processing generation 2021-04-11 03:42:16 -07:00
Michael Scire
315b7bdf22 tipc: implement service object interface generation 2021-04-11 03:42:16 -07:00
Michael Scire
ec988c5a99 tipc: first draft object allocation logic 2021-04-11 03:42:16 -07:00
Michael Scire
21b883a75c tipc: fix compilation issues with core serialization routines 2021-04-11 03:42:16 -07:00
Michael Scire
e93d71d932 tipc: tentative core serialization logic (missing imports, won't compile) 2021-04-11 03:42:16 -07:00
Michael Scire
dc6a0d7562 ams: add target firmware 12.0.0, fusee recognition 2021-04-11 03:42:16 -07:00
Michael Scire
1d2be0a2eb kern: mesosphere now implements kernel/sdk 12.3 2021-04-11 03:42:16 -07:00
Michael Scire
96937a611d kern: fuck the KPolice^H^H^H^H^H^HPageGroups 2021-04-11 03:42:16 -07:00
Michael Scire
dc7862882f kern: who needs __purecall? 2021-04-11 03:42:16 -07:00
Michael Scire
6faa3534bf kern: update pinning semantics for terminating threads 2021-04-11 03:42:16 -07:00
Michael Scire
afb1d68d06 kern: ensure handle table is finalized when deferring termination 2021-04-11 03:42:16 -07:00
Michael Scire
911e431d65 kern: simplify handle table registration for port/session 2021-04-11 03:42:16 -07:00
Michael Scire
ee91063bbb kern: update kdebug process management semantics 2021-04-11 03:42:16 -07:00
Michael Scire
cbdf33260e kern: update port/session state semantics 2021-04-11 03:42:16 -07:00
Michael Scire
c62a7381f8 kern: update KLightConditionVariable 2021-04-11 03:42:16 -07:00
Michael Scire
b4498734e4 kern: optimize KHandleTable to use indices instead of pointers 2021-04-11 03:42:16 -07:00
Michael Scire
4407237f5b kern: KAutoObject destruction is now scheduled for next dpc-time 2021-04-11 03:42:16 -07:00
Michael Scire
15956fcf9a kern: update for new slab resource counts/extents 2021-04-11 03:42:16 -07:00
Michael Scire
6a368d3d1a kern: reallocate pool distributions for 8GB units 2021-04-11 03:42:16 -07:00
Michael Scire
8e4be9aef9 kern: simplify global rng initialization 2021-04-11 03:42:16 -07:00
Michael Scire
0f8b7be2d2 kern: load initial process binary from user pool, rather than from pt heap 2021-04-11 03:42:16 -07:00
Michael Scire
a1e137cc1c kern: update Initialize0 for new changes 2021-04-11 03:42:16 -07:00
Michael Scire
504472af4e kern: update KConditionVariable::WaitForAddress/Wait 2021-04-11 03:42:16 -07:00
Michael Scire
19b253fd17 kern: trivially optimize userspace io memory write 2021-04-11 03:42:16 -07:00
Michael Scire
01f5c89902 kern: add bounds checking to KHandleTable::Register/Unreserve 2021-04-11 03:42:16 -07:00
Michael Scire
44ccbc2a7b kern: update set/way cache operations for new semantics 2021-04-11 03:42:16 -07:00
Michael Scire
6e4664ee05 kern: if a page table region is zero-size, nothing overlaps it 2021-04-11 03:42:16 -07:00
Michael Scire
85f9355184 kern: use KScopedLightLockPair helper for page table pair-locks 2021-04-11 03:42:16 -07:00
Michael Scire
60b5bd73b7 kern: track mapped ipc server memory in page table 2021-04-11 03:42:16 -07:00
Michael Scire
53e7aa0a20 kern: add KPageTableBase::Read/WriteDebugIoMemory 2021-04-11 03:42:16 -07:00
Michael Scire
561a16a348 kern: flush memory before reading in KPageTableBase::ReadDebugMemory 2021-04-11 03:42:16 -07:00
Michael Scire
1fce7b08b1 kern: update KMemoryBlockManagerUpdaterAllocator for new ctor/init semantics 2021-04-11 03:42:16 -07:00
Michael Scire
c216f92a91 kern: swap tpidr_el1/cntv_cval_el0 as scratch vs exception stack 2021-04-11 03:42:16 -07:00
Michael Scire
2f930c2d5f kern: support immortal processes 2021-04-11 03:42:16 -07:00
Michael Scire
256eb92f4c kern: update process/thread for new running/termination semantics 2021-04-11 03:42:16 -07:00
Michael Scire
ec1d9c4c49 kern: unconditionally set thread state when appropriate 2021-04-11 03:42:16 -07:00
Michael Scire
3356eddcba kern: update kernel waiter management rules 2021-04-11 03:42:16 -07:00
Michael Scire
f67d1b7026 kern: update KInterruptEvent to store core id 2021-04-11 03:42:16 -07:00
Michael Scire
e64fef109c kern: update pinned thread priority rules 2021-04-11 03:42:16 -07:00
Michael Scire
1b2cf173b3 kern: add new checks to SetThreadPriority/CoreMask 2021-04-11 03:42:16 -07:00
Michael Scire
2fb258ca7e kern: update KInitialPageTable/KInitialPageAllocator 2021-04-11 03:42:16 -07:00
Michael Scire
962cf97150 kern: KLinkedList no longer exists 2021-04-11 03:42:16 -07:00
Michael Scire
b3bd443636 svc: sanitize booleans in autogenerated abi stubs 2021-04-11 03:42:16 -07:00
Michael Scire
4b9e7c7d27 kern: bump svc limit to 192 from 128 2021-04-11 03:42:16 -07:00
hexkyz
46612156f4 exo: add new dram ID 2021-04-11 03:42:16 -07:00
Michael Scire
279bb863df fusee: add support for 12.0.0 kernel 2021-04-11 03:42:16 -07:00
Michael Scire
252ea97ca5 nogc: add patches for 12.0.0 2021-04-11 03:42:16 -07:00
Michael Scire
f89cfe41da emummc: update for 12.0.0 2021-04-11 03:42:16 -07:00
Easy World
e3e3679cfe Update dmnt_cheat_vm.cpp
* fix case fallthrough in function "LogOpcode"
* use same attribute name in one opcode case
2021-04-07 18:46:23 -07:00
Michael Scire
75a2052144 ncm: fix GameCardStorageRoot mount point (closes #1404) 2021-03-24 07:17:03 -07:00
Adubbz
5666c59657 ncm: Updated ListContentId for 11.0.0 2021-03-22 14:58:28 -07:00
Michael Scire
c99ce36d7d ams: convert to util::ConstructAt where appropriate 2021-03-21 20:36:49 -07:00
Michael Scire
d84dcb653d ams: prefer construct_at/destroy_at over placement new/explicit destructor 2021-03-21 20:30:40 -07:00
Michael Scire
aff0da9427 ams: remove TYPED_STORAGE() macro in favor of template 2021-03-21 18:47:30 -07:00
Michael Scire
8d9174b227 ams: bump version to 0.19.0.
Release (probably) not actually imminent, I just don't want to forget.
2021-03-21 13:16:49 -07:00
Michael Scire
c8404e8452 boot2: clean up pre-0.19.0 ams contents on upgrade 2021-03-21 13:16:30 -07:00
Michael Scire
79e4c82d7e ams: distribute sysmodules in single file as stratosphere.romfs 2021-03-21 13:16:30 -07:00
Adubbz
3afd9a737c daybreak: Added a warning when resetting to factory settings 2021-03-18 21:08:22 -07:00
Michael Scire
a7564cf303 kern: add extension InfoType for retrieving current process handle. 2021-03-17 17:48:30 -07:00
SciresM
5362ee9450 [tma2] [Ongoing] Continue implementing modules for tma2. (#1388)
* cs: add stub sysmodule to host command shell server

* cs: implement logic for main (linker error paradise, for now)

* cs: implement more of the system module's skeleton

* htcs: update client type names for libnx pr merge
2021-03-16 17:13:30 -07:00
Michael Scire
021d4c88fa kern: use fix usage of incorrect page table for UserBuffer ipc 2021-03-13 15:14:36 -08:00
Michael Scire
deb4aece9a kern: fix inverted conditional in KDebugBase::SetThreadContext 2021-03-11 12:53:43 -08:00
SciresM
a6729171d3 set.mitm: fake compatibility for usb!usb30_force_enabled on 9.0.0+ (#1391)
* set.mitm: fake compatibility for usb!usb30_force_enabled on 9.0.0+

* set.mitm: add value meaning comment for usb!usb30_force_enabled

* loader: pretend to be polite about patch ordering
2021-03-01 14:18:27 -08:00
Michael Scire
c9015581ca boot2: fix tma launch when htc is disabled 2021-02-26 08:08:05 -08:00
Michael Scire
35c816d62f htclow: fix ordering of channels, uninitialized bug in service json parse 2021-02-26 04:49:20 -08:00
Michael Scire
18031ae107 tio: fix wrong body size on optimized ListDirectory 2021-02-26 04:49:20 -08:00
Michael Scire
c7e4f963e8 fs: fix GetFileTimeStampRawForDebug 2021-02-26 04:49:20 -08:00
Michael Scire
97875c7d2f tio: fix bug in body receive 2021-02-26 04:49:20 -08:00
Michael Scire
0da3b2b273 tio: implement SdCardObserver (finishes sysmodule) 2021-02-26 04:49:20 -08:00
Michael Scire
3cbd99a709 tio: implement all command processor logic 2021-02-26 04:49:20 -08:00
Michael Scire
6ce2076d92 tio: implement server/dispatch logic. 2021-02-26 04:49:20 -08:00
Michael Scire
cee1ecd06f tio: add stub sysmodule to host target io server 2021-02-26 04:49:20 -08:00
Michael Scire
a739e3fb20 docs: remove deprecated hid mitm from settings template 2021-02-24 04:08:15 -08:00
Michael Scire
953246a175 htc: disable socket driver, needs design thought before we can turn it on for real. 2021-02-24 04:06:54 -08:00
Michael Scire
d8faa37de0 socket: fix config size calculations 2021-02-24 04:06:54 -08:00
Michael Scire
64c7c6b2a5 ams: implement socket api for htclow socket driver 2021-02-24 04:06:54 -08:00
Michael Scire
1c974a387c htc: implement socket driver (socket api not really impl'd yet) 2021-02-24 04:06:54 -08:00
Michael Scire
b5ab491603 htc: implement htcmisc service object commands 2021-02-24 04:06:54 -08:00
Michael Scire
8b32b9eadf kern: Increase reserved system memory, require mesosphere for htc/tma 2021-02-24 04:06:54 -08:00
Michael Scire
ce149f996c htc: configure usage via system setting 2021-02-24 04:06:54 -08:00
Michael Scire
0ec54ed492 htcs: fixes, echo server is now fully functional 2021-02-24 04:06:54 -08:00
Michael Scire
72de4d85f3 htcs: implement remaining client bindings 2021-02-24 04:06:54 -08:00
Michael Scire
d0673aa2fb htcs: implement client socket bindings 2021-02-24 04:06:54 -08:00
Michael Scire
f7fcb54622 htcs: implement virtual socket collection 2021-02-24 04:06:54 -08:00
Michael Scire
ec643789ab htcs: implement data channel manager 2021-02-24 04:06:54 -08:00
Michael Scire
70caadafd5 htcs: implement rpc tasks 2021-02-24 04:06:54 -08:00
Michael Scire
7667104961 htcs: hook up HtcsService to rpc client 2021-02-24 04:06:54 -08:00
Michael Scire
0c791f2279 htcs: fix magic template argument deduction, do Close/Connect/Bind 2021-02-24 04:06:54 -08:00
Michael Scire
f71943c03a htcs: declare all rpc tasks 2021-02-24 04:06:54 -08:00
Michael Scire
536e3e99a8 htcs: hook up CreateSocket/RpcClient Begin<>/End<> 2021-02-24 04:06:54 -08:00
Michael Scire
abff428212 htcs: hook up manager impl to (unimplemented) service 2021-02-24 04:06:54 -08:00
Michael Scire
1541985222 htcs: hook manager up to (unimplemented) manager impl 2021-02-24 04:06:54 -08:00
Michael Scire
61929d6e21 htcs: hook service objects up to (unimplemented) manager apis 2021-02-24 04:06:54 -08:00
Michael Scire
f0ef9fb918 htc: fixes for WriteFileLarge/sending over data channel 2021-02-24 04:06:54 -08:00
Michael Scire
7621bd4e13 htcfs: fix CreateFile packet header 2021-02-24 04:06:54 -08:00
Michael Scire
d20bceff75 htc: implement the remaining commands for htcfs 2021-02-24 04:06:54 -08:00
Michael Scire
1961cb1034 htc: ReadDirectoryLarge/data channel support 2021-02-24 04:06:54 -08:00
Michael Scire
9daec3a66a htc: Implement (almost) all host-directory commands 2021-02-24 04:06:54 -08:00
Michael Scire
e79417c37c htcfs: implement OpenDirectory/CloseDirectory 2021-02-24 04:06:54 -08:00
Michael Scire
b371487525 sf: optimize argument parsing for const LargeData & 2021-02-24 04:06:54 -08:00
Michael Scire
5c97469348 htc: implement htcfs protocol bringup 2021-02-24 04:06:54 -08:00
Michael Scire
99a38dce32 htc: fix event wait loops for rpc clients 2021-02-24 04:06:54 -08:00
Michael Scire
f28a410ba0 htc: fixes, can now enter ReadyState with wip starlink code 2021-02-24 04:06:54 -08:00
Michael Scire
5fc1981061 htc: fix htcfs sf definition 2021-02-24 04:06:54 -08:00
Michael Scire
1bd0094bee htc: finish last code for Main() 2021-02-24 04:06:54 -08:00
Michael Scire
870b45f208 htc: add htcfs server/service object skeletons 2021-02-24 04:06:54 -08:00
Michael Scire
9fbbb9fadb htclow: add Channel wrapper class 2021-02-24 04:06:54 -08:00
Michael Scire
dec06ff649 htc: add htcfs service api definitions 2021-02-24 04:06:54 -08:00
Michael Scire
b898241112 htcs: add hipc server/service object skeletons 2021-02-24 04:06:54 -08:00
Michael Scire
10255f7f51 htc: skeleton HtcsManagerImpl, implement HtcsMonitor 2021-02-24 04:06:54 -08:00
Michael Scire
cb5a706659 htcs: add sf interface info/types 2021-02-24 04:06:54 -08:00
Michael Scire
4d86863f2c htc: ObserverThread (mostly), system now boots + works with htc in bg 2021-02-24 04:06:54 -08:00
Michael Scire
79a3f442d6 htc: implement psc/pm loop 2021-02-24 04:06:54 -08:00
Michael Scire
7485a1968a htc: implement HtcmiscImpl::ServerThread/HtcmiscRpcServer::ReceiveThread 2021-02-24 04:06:54 -08:00
Michael Scire
3be005b638 htc: Implement RpcClient::ReceiveThread + SendThread 2021-02-24 04:06:54 -08:00
Michael Scire
d60b1abed0 htc: Implement HtcmiscImpl::ClientThread 2021-02-24 04:06:54 -08:00
Michael Scire
1867c31f63 htc: add RpcTaskQueue/RpcTaskIdFreeList 2021-02-24 04:06:54 -08:00
Michael Scire
82757cd1b4 htc: nullptr != false 2021-02-24 04:06:54 -08:00
Michael Scire
f5e98de1a3 htc: add RpcTaskTable 2021-02-24 04:06:54 -08:00
Michael Scire
0880cebc4d htc: implement htcmisc rpc tasks 2021-02-24 04:06:54 -08:00
Michael Scire
1f03b11dbc htc: skeleton constructors for htcmisc 2021-02-24 04:06:54 -08:00
Michael Scire
b925344c3b htc: implement remainder of Mux/Tasks 2021-02-24 04:06:54 -08:00
Michael Scire
42cf3f50d7 htc: implement mux side of connecting (and more) 2021-02-24 04:06:54 -08:00
Michael Scire
70aae4e27a htc: fix driver manager c/p error 2021-02-24 04:06:54 -08:00
Michael Scire
87165e0f08 htc: implement remaining htclow::HtclowManagerImpl funcs (mux impls pending) 2021-02-24 04:06:54 -08:00
Michael Scire
e20c2450ce htc: declare and begin impl of HtclowManagerImpl interface 2021-02-24 04:06:54 -08:00
Michael Scire
968ce12492 htc: optimize Mux::QuerySendPacket 2021-02-24 04:06:54 -08:00
Michael Scire
00ab210e66 mux: optimize many accesses to O(log(n)) vs Nintendo's O(log(n)^2) 2021-02-24 04:06:54 -08:00
Michael Scire
4cb6c63516 htc: implement HtclowDriver 2021-02-24 04:06:54 -08:00
Michael Scire
1963ae7ec0 htc: begin skeletoning types for HtcmiscImpl 2021-02-24 04:06:54 -08:00
Michael Scire
889f144b27 htc: hook up creation of the htc manager service object 2021-02-24 04:06:54 -08:00
Michael Scire
4408ad6a47 htc: module id names, skeleton rest of main 2021-02-24 04:06:54 -08:00
Michael Scire
4ed665bcd3 htc: implement remaining worker thread send logic (for channel mux) 2021-02-24 04:06:54 -08:00
Michael Scire
df3d62df84 htc: send logic for HtcctrlService, bugfixes (thanks @misson20000) 2021-02-24 04:06:54 -08:00
Michael Scire
0977ee72ca rapidjson: add customization point for allocation/asserts 2021-02-24 04:06:54 -08:00
Michael Scire
2cdfde6637 htc: add remaining worker receive thread logic 2021-02-24 04:06:54 -08:00
Michael Scire
6fc24d8883 htc: implement service channel parsing (ReceiveReadyPacket) 2021-02-24 04:06:54 -08:00
Michael Scire
4e9bc617bb rapidjson: import -master as ams::rapidjson 2021-02-24 04:06:54 -08:00
Michael Scire
679fec2ddc htc: implement much of worker receive logic 2021-02-24 04:06:54 -08:00
Michael Scire
8f85cc17dc htc: fix copy/paste error in usb driver 2021-02-24 04:06:54 -08:00
Michael Scire
e40eece74e htc: free ourselves from the tyranny of numerical enums 2021-02-24 04:06:54 -08:00
Michael Scire
2341f18edd htc: implement htclow listener thread 2021-02-24 04:06:54 -08:00
Michael Scire
c9c41e0e8d htc: actually use the usb driver 2021-02-24 04:06:54 -08:00
Michael Scire
c59388caf1 htc: implement complete usb driver 2021-02-24 04:06:54 -08:00
Michael Scire
c878123274 htc: implement (fixing linker errors) through HtclowManagerImpl::OpenDriver 2021-02-24 04:06:54 -08:00
Michael Scire
1687bf2e07 htclow: fix copyright headers, skeleton more manager types 2021-02-24 04:06:54 -08:00
Michael Scire
cf99f54a34 htc: skeleton much of the type hierarchy for htclow manager 2021-02-24 04:06:54 -08:00
Michael Scire
83c1c175ba htc: skeleton some more of main 2021-02-24 04:06:54 -08:00
Michael Scire
fc060d3777 htc: skeleton main file/sysmodule dir 2021-02-24 04:06:54 -08:00
Michael Scire
eb50e99748 kern: alleviate a little KPort pressure. 2021-02-23 14:31:24 -08:00
Michael Scire
287f4e6fa1 sm: fix abort on RegisterService while at port limit
closes #1382
2021-02-23 14:21:46 -08:00
Michael Scire
cbf3ba9b75 General system stability improvements to enhance the user's experience. 2021-02-21 23:50:01 -08:00
Michael Scire
95a6b0828f dmnt: set the debug process handle slightly more carefully 2021-02-20 17:37:59 -08:00
Michael Scire
1545fa9d44 git subrepo push libraries
subrepo:
  subdir:   "libraries"
  merged:   "bc08912d"
upstream:
  origin:   "https://github.com/Atmosphere-NX/Atmosphere-libs"
  branch:   "master"
  commit:   "bc08912d"
git-subrepo:
  version:  "0.4.1"
  origin:   "???"
  commit:   "???"
2021-02-15 19:52:28 -08:00
Michael Scire
71add1add8 ams: bump version to 0.18.1 2021-02-15 19:51:48 -08:00
Michael Scire
a96786fd2c ams: add kernel to debug elf zip 2021-02-15 19:40:00 -08:00
Michael Scire
74e4e70053 fs.mitm: fix cache of non-current-process data storages (closes #1371) 2021-02-15 19:39:32 -08:00
znxDomain
26b6216fa0 Correct ams_mitm.md formatting
Move set_mitm H3's under correct H2 element
2021-02-11 05:47:31 -08:00
Michael Scire
fe5c850e69 psc: fix pm module init 2021-02-10 02:57:22 -08:00
Michael Scire
2b825d56dc usb: fix wrong command id for AppendConfigurationData 2021-02-07 17:14:48 -08:00
Michael Scire
13b17a5848 usb: add ds client api 2021-02-07 16:29:38 -08:00
Michael Scire
621520c30b kern: fix support for virtual core IDs 2021-02-05 14:59:03 -08:00
Michael Scire
846cc0b47a util: add FixedSet 2021-02-04 02:29:54 -08:00
Michael Scire
e82ad1cdc5 util: add FixedMap::clear 2021-02-04 02:16:37 -08:00
Michael Scire
b40da8f445 ams: add transient unit testing sysmodule to gitignore 2021-02-04 02:08:49 -08:00
Michael Scire
a9c6476416 util: various FixedMap fixes 2021-02-04 02:08:21 -08:00
Michael Scire
c1d93a9495 util: add FixedMap/FixedTree 2021-02-04 01:00:19 -08:00
Michael Scire
201b17f100 util: impl::AvailableIndexFinder 2021-02-03 17:47:32 -08:00
Michael Scire
c0e3cee657 dns.mitm: allow nullptr for port string (closes #1352) 2021-02-03 12:41:23 -08:00
Michael Scire
26d8db74f8 git subrepo push libraries
subrepo:
  subdir:   "libraries"
  merged:   "17960517"
upstream:
  origin:   "https://github.com/Atmosphere-NX/Atmosphere-libs"
  branch:   "master"
  commit:   "17960517"
git-subrepo:
  version:  "0.4.1"
  origin:   "???"
  commit:   "???"
2021-02-02 18:33:22 -08:00
Michael Scire
ee2e9d50fd hid: fix sm usage 2021-02-02 18:32:29 -08:00
Michael Scire
fd1a39996e ncm: fix ContentStorageImplBase constructor 2021-02-02 17:12:02 -08:00
Michael Scire
8eb65ab401 dns.mitm: fix hosts file parsing bug 2021-02-02 17:11:53 -08:00
Michael Scire
bcda834980 dns.mitm: make line ordering explicit, rather than implicit.
This doesn't actually change functionality, because this is how std::unordered_map worked anyway...

...but it's better for us to be explicit, I think.
2021-02-02 13:48:40 -08:00
Michael Scire
408b81b881 docs: fix missing meme (important) 2021-02-02 12:17:00 -08:00
Michael Scire
d854b94382 git subrepo push libraries
subrepo:
  subdir:   "libraries"
  merged:   "90d85295"
upstream:
  origin:   "https://github.com/Atmosphere-NX/Atmosphere-libs"
  branch:   "master"
  commit:   "90d85295"
git-subrepo:
  version:  "0.4.1"
  origin:   "???"
  commit:   "???"
2021-02-02 12:16:49 -08:00
Michael Scire
63440cab18 ams: bump version to 0.18.0 2021-02-02 12:15:53 -08:00
Michael Scire
4fa585a23f docs: expand dns_mitm wildcard wording 2021-02-02 11:41:49 -08:00
Michael Scire
e521ae805d dns.mitm: add documentation 2021-02-02 11:41:49 -08:00
Michael Scire
6950989552 dns.mitm: support % in hosts file as stand-in for environment identifier 2021-02-02 11:41:49 -08:00
Michael Scire
ffbdf29c10 dns.mitm: fix ABORT_UNLESS -> ABORT 2021-02-02 11:41:49 -08:00
Michael Scire
135d42ffee dns.mitm: hint = {} fix in options 2021-02-02 11:41:49 -08:00
Michael Scire
1306d03136 dns.mitm: add GetAddrInfo redir, AtmosphereReloadHostsFile, debug logging control 2021-02-02 11:41:49 -08:00
Michael Scire
97aa209c43 dns.mitm: fix inverted hostname detection 2021-02-02 11:41:49 -08:00
Michael Scire
4ce2a6deb3 meso: update for new fatal encoding 2021-02-02 11:41:49 -08:00
Michael Scire
e45d8cd7d8 ams: take three tries to edit a structure 2021-02-02 11:41:49 -08:00
Michael Scire
79211e1159 ams: afsr0 -> 32 bits in fatal error 2021-02-02 11:41:49 -08:00
Michael Scire
ca8e8ce487 ams: fix fatal error context 2021-02-02 11:41:49 -08:00
Michael Scire
b30311be65 dns.mitm: support wildcards in hosts 2021-02-02 11:41:49 -08:00
Michael Scire
6694d8c2d9 dns.mitm: edit default behavior/hosts filenames 2021-02-02 11:41:49 -08:00
Michael Scire
658389fc60 dns.mitm: fix issue in host file parsing 2021-02-02 11:41:49 -08:00
Michael Scire
d6477cf024 dns.mitm: parse redirections from hosts file 2021-02-02 11:41:49 -08:00
Michael Scire
400f5142ee dns: implement GetHostByName redirection (backend TODO) 2021-02-02 11:41:49 -08:00
Michael Scire
8bf8df43e2 dns: skeleton passthrough mitm 2021-02-02 11:41:49 -08:00
799 changed files with 59306 additions and 5508 deletions

View File

@@ -49,6 +49,8 @@ X.X.X</br>
- [ Ex: Kosmos' distribution of Atmosphère ] - [ Ex: Kosmos' distribution of Atmosphère ]
- Do you have additional kips or sysmodules you're loading: - Do you have additional kips or sysmodules you're loading:
- Homebrew software installed: [ * ] - Homebrew software installed: [ * ]
- EmuMMC or SysNAND:
- [ If using an EmuMMC, include whether it's partition-based or file-based. ]
### Additional context? ### Additional context?

2
.gitignore vendored
View File

@@ -95,3 +95,5 @@ sept/sept-secondary/KEYS.py
**/build_nintendo_nx_arm **/build_nintendo_nx_arm
**/build_nintendo_nx_x64 **/build_nintendo_nx_x64
**/build_nintendo_nx_x86 **/build_nintendo_nx_x86
stratosphere/test/

View File

@@ -1,3 +1,9 @@
ifeq ($(strip $(DEVKITPRO)),)
$(error "Please set DEVKITPRO in your environment. export DEVKITPRO=<path to>devkitPro)
endif
include $(DEVKITPRO)/devkitA64/base_tools
TOPTARGETS := all clean dist-no-debug dist TOPTARGETS := all clean dist-no-debug dist
AMSBRANCH := $(shell git symbolic-ref --short HEAD) AMSBRANCH := $(shell git symbolic-ref --short HEAD)
AMSHASH := $(shell git rev-parse --short HEAD) AMSHASH := $(shell git rev-parse --short HEAD)
@@ -37,6 +43,7 @@ libraries:
clean: clean:
$(MAKE) -C fusee clean $(MAKE) -C fusee clean
$(MAKE) -C emummc clean
rm -rf out rm -rf out
dist-no-debug: all dist-no-debug: all
@@ -56,18 +63,11 @@ dist-no-debug: all
mkdir atmosphere-$(AMSVER)/atmosphere mkdir atmosphere-$(AMSVER)/atmosphere
mkdir atmosphere-$(AMSVER)/sept mkdir atmosphere-$(AMSVER)/sept
mkdir atmosphere-$(AMSVER)/switch mkdir atmosphere-$(AMSVER)/switch
mkdir -p atmosphere-$(AMSVER)/atmosphere/contents/0100000000000008
mkdir -p atmosphere-$(AMSVER)/atmosphere/contents/010000000000000D
mkdir -p atmosphere-$(AMSVER)/atmosphere/contents/010000000000002B
mkdir -p atmosphere-$(AMSVER)/atmosphere/contents/0100000000000032
mkdir -p atmosphere-$(AMSVER)/atmosphere/contents/0100000000000034
mkdir -p atmosphere-$(AMSVER)/atmosphere/contents/0100000000000036
mkdir -p atmosphere-$(AMSVER)/atmosphere/contents/0100000000000037
mkdir -p atmosphere-$(AMSVER)/atmosphere/contents/010000000000003C
mkdir -p atmosphere-$(AMSVER)/atmosphere/contents/0100000000000042
mkdir -p atmosphere-$(AMSVER)/atmosphere/fatal_errors mkdir -p atmosphere-$(AMSVER)/atmosphere/fatal_errors
mkdir -p atmosphere-$(AMSVER)/atmosphere/config_templates mkdir -p atmosphere-$(AMSVER)/atmosphere/config_templates
mkdir -p atmosphere-$(AMSVER)/atmosphere/config mkdir -p atmosphere-$(AMSVER)/atmosphere/config
mkdir -p atmosphere-$(AMSVER)/atmosphere/flags
touch atmosphere-$(AMSVER)/atmosphere/flags/clean_stratosphere_for_0.19.0.flag
cp fusee/fusee-primary/fusee-primary.bin atmosphere-$(AMSVER)/atmosphere/reboot_payload.bin cp fusee/fusee-primary/fusee-primary.bin atmosphere-$(AMSVER)/atmosphere/reboot_payload.bin
cp fusee/fusee-mtc/fusee-mtc.bin atmosphere-$(AMSVER)/atmosphere/fusee-mtc.bin cp fusee/fusee-mtc/fusee-mtc.bin atmosphere-$(AMSVER)/atmosphere/fusee-mtc.bin
cp fusee/fusee-secondary/fusee-secondary-experimental.bin atmosphere-$(AMSVER)/atmosphere/fusee-secondary.bin cp fusee/fusee-secondary/fusee-secondary-experimental.bin atmosphere-$(AMSVER)/atmosphere/fusee-secondary.bin
@@ -84,19 +84,27 @@ dist-no-debug: all
cp config_templates/exosphere.ini atmosphere-$(AMSVER)/atmosphere/config_templates/exosphere.ini cp config_templates/exosphere.ini atmosphere-$(AMSVER)/atmosphere/config_templates/exosphere.ini
cp -r config_templates/kip_patches atmosphere-$(AMSVER)/atmosphere/kip_patches cp -r config_templates/kip_patches atmosphere-$(AMSVER)/atmosphere/kip_patches
cp -r config_templates/hbl_html atmosphere-$(AMSVER)/atmosphere/hbl_html cp -r config_templates/hbl_html atmosphere-$(AMSVER)/atmosphere/hbl_html
cp stratosphere/boot2/boot2.nsp atmosphere-$(AMSVER)/atmosphere/contents/0100000000000008/exefs.nsp mkdir -p atmosphere-$(AMSVER)/stratosphere_romfs/atmosphere/contents/0100000000000008
cp stratosphere/dmnt/dmnt.nsp atmosphere-$(AMSVER)/atmosphere/contents/010000000000000D/exefs.nsp mkdir -p atmosphere-$(AMSVER)/stratosphere_romfs/atmosphere/contents/0100000000000008
cp stratosphere/erpt/erpt.nsp atmosphere-$(AMSVER)/atmosphere/contents/010000000000002B/exefs.nsp mkdir -p atmosphere-$(AMSVER)/stratosphere_romfs/atmosphere/contents/010000000000000D
cp stratosphere/eclct.stub/eclct.stub.nsp atmosphere-$(AMSVER)/atmosphere/contents/0100000000000032/exefs.nsp mkdir -p atmosphere-$(AMSVER)/stratosphere_romfs/atmosphere/contents/010000000000002B
cp stratosphere/fatal/fatal.nsp atmosphere-$(AMSVER)/atmosphere/contents/0100000000000034/exefs.nsp mkdir -p atmosphere-$(AMSVER)/stratosphere_romfs/atmosphere/contents/0100000000000032
cp stratosphere/creport/creport.nsp atmosphere-$(AMSVER)/atmosphere/contents/0100000000000036/exefs.nsp mkdir -p atmosphere-$(AMSVER)/stratosphere_romfs/atmosphere/contents/0100000000000034
cp stratosphere/ro/ro.nsp atmosphere-$(AMSVER)/atmosphere/contents/0100000000000037/exefs.nsp mkdir -p atmosphere-$(AMSVER)/stratosphere_romfs/atmosphere/contents/0100000000000036
cp stratosphere/jpegdec/jpegdec.nsp atmosphere-$(AMSVER)/atmosphere/contents/010000000000003C/exefs.nsp mkdir -p atmosphere-$(AMSVER)/stratosphere_romfs/atmosphere/contents/0100000000000037
cp stratosphere/pgl/pgl.nsp atmosphere-$(AMSVER)/atmosphere/contents/0100000000000042/exefs.nsp mkdir -p atmosphere-$(AMSVER)/stratosphere_romfs/atmosphere/contents/010000000000003C
mkdir -p atmosphere-$(AMSVER)/atmosphere/contents/0100000000000032/flags mkdir -p atmosphere-$(AMSVER)/stratosphere_romfs/atmosphere/contents/0100000000000042
touch atmosphere-$(AMSVER)/atmosphere/contents/0100000000000032/flags/boot2.flag cp stratosphere/boot2/boot2.nsp atmosphere-$(AMSVER)/stratosphere_romfs/atmosphere/contents/0100000000000008/exefs.nsp
mkdir -p atmosphere-$(AMSVER)/atmosphere/contents/0100000000000037/flags cp stratosphere/dmnt/dmnt.nsp atmosphere-$(AMSVER)/stratosphere_romfs/atmosphere/contents/010000000000000D/exefs.nsp
touch atmosphere-$(AMSVER)/atmosphere/contents/0100000000000037/flags/boot2.flag cp stratosphere/erpt/erpt.nsp atmosphere-$(AMSVER)/stratosphere_romfs/atmosphere/contents/010000000000002B/exefs.nsp
cp stratosphere/eclct.stub/eclct.stub.nsp atmosphere-$(AMSVER)/stratosphere_romfs/atmosphere/contents/0100000000000032/exefs.nsp
cp stratosphere/fatal/fatal.nsp atmosphere-$(AMSVER)/stratosphere_romfs/atmosphere/contents/0100000000000034/exefs.nsp
cp stratosphere/creport/creport.nsp atmosphere-$(AMSVER)/stratosphere_romfs/atmosphere/contents/0100000000000036/exefs.nsp
cp stratosphere/ro/ro.nsp atmosphere-$(AMSVER)/stratosphere_romfs/atmosphere/contents/0100000000000037/exefs.nsp
cp stratosphere/jpegdec/jpegdec.nsp atmosphere-$(AMSVER)/stratosphere_romfs/atmosphere/contents/010000000000003C/exefs.nsp
cp stratosphere/pgl/pgl.nsp atmosphere-$(AMSVER)/stratosphere_romfs/atmosphere/contents/0100000000000042/exefs.nsp
@build_romfs atmosphere-$(AMSVER)/stratosphere_romfs atmosphere-$(AMSVER)/atmosphere/stratosphere.romfs
rm -r atmosphere-$(AMSVER)/stratosphere_romfs
cp troposphere/reboot_to_payload/reboot_to_payload.nro atmosphere-$(AMSVER)/switch/reboot_to_payload.nro cp troposphere/reboot_to_payload/reboot_to_payload.nro atmosphere-$(AMSVER)/switch/reboot_to_payload.nro
cp troposphere/daybreak/daybreak.nro atmosphere-$(AMSVER)/switch/daybreak.nro cp troposphere/daybreak/daybreak.nro atmosphere-$(AMSVER)/switch/daybreak.nro
cd atmosphere-$(AMSVER); zip -r ../atmosphere-$(AMSVER).zip ./*; cd ../; cd atmosphere-$(AMSVER); zip -r ../atmosphere-$(AMSVER).zip ./*; cd ../;
@@ -135,6 +143,7 @@ dist: dist-no-debug
cp exosphere/program/sc7fw/sc7fw.elf atmosphere-$(AMSVER)-debug/exosphere-sc7fw.elf cp exosphere/program/sc7fw/sc7fw.elf atmosphere-$(AMSVER)-debug/exosphere-sc7fw.elf
cp exosphere/program/rebootstub/rebootstub.elf atmosphere-$(AMSVER)-debug/exosphere-rebootstub.elf cp exosphere/program/rebootstub/rebootstub.elf atmosphere-$(AMSVER)-debug/exosphere-rebootstub.elf
cp mesosphere/kernel_ldr/kernel_ldr.elf atmosphere-$(AMSVER)-debug/kernel_ldr.elf cp mesosphere/kernel_ldr/kernel_ldr.elf atmosphere-$(AMSVER)-debug/kernel_ldr.elf
cp mesosphere/kernel/kernel.elf atmosphere-$(AMSVER)-debug/kernel.elf
cp stratosphere/ams_mitm/ams_mitm.elf atmosphere-$(AMSVER)-debug/ams_mitm.elf cp stratosphere/ams_mitm/ams_mitm.elf atmosphere-$(AMSVER)-debug/ams_mitm.elf
cp stratosphere/boot/boot.elf atmosphere-$(AMSVER)-debug/boot.elf cp stratosphere/boot/boot.elf atmosphere-$(AMSVER)-debug/boot.elf
cp stratosphere/boot2/boot2.elf atmosphere-$(AMSVER)-debug/boot2.elf cp stratosphere/boot2/boot2.elf atmosphere-$(AMSVER)-debug/boot2.elf

View File

@@ -1,9 +1,13 @@
; Disable uploading error reports to Nintendo
[eupld] [eupld]
; Disable uploading error reports to Nintendo
; upload_enabled = u8!0x0 ; upload_enabled = u8!0x0
[usb]
; Enable USB 3.0 superspeed for homebrew
; 0 = USB 3.0 support is system default (usually disabled), 1 = USB 3.0 support is enabled.
; usb30_force_enabled = u8!0x0
[ro]
; Control whether RO should ease its validation of NROs. ; Control whether RO should ease its validation of NROs.
; (note: this is normally not necessary, and ips patches can be used.) ; (note: this is normally not necessary, and ips patches can be used.)
[ro]
; ease_nro_restriction = u8!0x1 ; ease_nro_restriction = u8!0x1
; Atmosphere custom settings ; Atmosphere custom settings
[atmosphere] [atmosphere]
@@ -32,12 +36,6 @@
; NOTE: EXPERIMENTAL ; NOTE: EXPERIMENTAL
; If you do not know what you are doing, do not touch this yet. ; If you do not know what you are doing, do not touch this yet.
; fsmitm_redirect_saves_to_sd = u8!0x0 ; fsmitm_redirect_saves_to_sd = u8!0x0
; Controls whether to enable the deprecated hid mitm
; to fix compatibility with old homebrew.
; 0 = Do not enable, 1 = Enable.
; Please note this setting may be removed in a
; future release of Atmosphere.
; enable_deprecated_hid_mitm = u8!0x0
; Controls whether am sees system settings "DebugModeFlag" as ; Controls whether am sees system settings "DebugModeFlag" as
; enabled or disabled. ; enabled or disabled.
; 0 = Disabled (not debug mode), 1 = Enabled (debug mode) ; 0 = Disabled (not debug mode), 1 = Enabled (debug mode)
@@ -52,6 +50,9 @@
; Controls whether dns.mitm logs to the sd card for debugging ; Controls whether dns.mitm logs to the sd card for debugging
; 0 = Disabled, 1 = Enabled ; 0 = Disabled, 1 = Enabled
; enable_dns_mitm_debug_log = u8!0x0 ; enable_dns_mitm_debug_log = u8!0x0
; Controls whether htc is enabled
; 0 = Disabled, 1 = Enabled
; enable_htc = u8!0x0
[hbloader] [hbloader]
; Controls the size of the homebrew heap when running as applet. ; Controls the size of the homebrew heap when running as applet.
; If set to zero, all available applet memory is used as heap. ; If set to zero, all available applet memory is used as heap.

View File

@@ -1,4 +1,114 @@
# Changelog # Changelog
## 0.19.5
+ Support was added for 12.1.0.
+ LayeredFS support was added for OpenDataStorageWithProgramIndex commands.
+ Certain games using newer (7.0.0+ APIs) which include multiple programs under a single title previously could not be modified.
+ These are now supported as normal, and LayeredFS should have 100% compatibility again.
+ A number of minor issues were fixed, including:
+ The Reboot to Payload NRO was updated to allow the OS to save state prior to rebooting (thanks @AuroraWright)!
+ An issue was fixed that could cause dns.mitm to fail when games requested resolution of an empty string.
+ An issue was fixed that caused a memory leak in the erpt system module.
+ This would eventually cause a system crash after ~540 reports were generated without rebooting.
+ A number of minor improvements were made to improve mesosphere's accuracy.
+ General system stability improvements to enhance the user's experience.
## 0.19.4
+ Support was added for 12.0.3.
+ A number of minor issues were fixed, including:
+ An issue was fixed that could cause heap memory corruption when allocation was highly contended.
+ An issue was fixed that could cause sleep to fail under certain conditions.
+ An issue was fixed that could cause a scheduler slow path to be taken more often than necessary.
+ General system stability improvements to enhance the user's experience.
## 0.19.3
+ Support was added for 12.0.2.
+ A number of minor issues were fixed, including:
+ An issue was fixed in dns.mitm that caused a crash when games attempted to resolve the IP address of nullptr.
+ An issue was fixed in erpt that would cause an abort when booting without having ever booted stock previously.
+ An issue was fixed in (file-based) emummc that caused an error on system format/downloading certain games.
+ General system stability improvements to enhance the user's experience.
## 0.19.2
+ Atmosphère's components were further updated to reflect latest official behaviors as of 12.0.0.
+ Notably, `erpt` was updated to implement the new forced shutdown detection feature.
+ When a forced-shutdown occurs, an erpt_report will be generated and saved to the SD card on the next boot.
+ Atmosphere-libs was updated to use GCC 11 (latest devkitA64/devkitARM releases).
+ Initial inspections show mild-to-moderate optimizer improvements in several important places (kernel is 0x3000 smaller).
+ General system stability improvements to enhance the user's experience.
+ A number of minor issues were fixed, including:
+ A bug was fixed that caused a black screen when attempting to boot firmware versions 2.0.0-4.1.0.
+ A bug was fixed that caused sm to abort when at the session limit, rather than returning error codes.
+ A bug was fixed that allowed for resource exhaustion on 12.0.0, under certain circumstances.
+ Several issues were fixed, and usability and stability were improved.
## 0.19.1
+ An issue was fixed that caused a fatal error when using official `migration` services to transfer data between consoles.
+ An issue was fixed in `ncm` that caused an error when the OS tried to enumerate installed SD card content.
+ Several issues were fixed, and usability and stability were improved.
## 0.19.0
+ Support was added for 12.0.0.
+ `mesosphère` was updated to reflect the latest official kernel behavior.
+ `sm`, `boot2`, `pgl` were updated to reflect the latest official behaviors.
+ **Please Note**: 12.0.0 added a new protocol for IPC ("tipc"), which has been freshly reimplemented in its entirety.
+ It is possible there may be as of yet unfound issues; if there are, please send the appropriate crash reports to SciresM (SciresM#0524 on discord).
+ Homebrew which uses atmosphere extensions (including the mitm API) will need to be re-compiled in order to function on 0.19.0.
+ I apologize for this, but it's unavoidable for technical reasons. If you're affected by this and mad about it, please contact SciresM to complain.
+ `erpt` was partially updated to reflect the latest official behaviors.
+ New features were added to erpt to track the activity of running applets, and to detect when a forced shutdown occurs.
+ These behaviors have been temporarily stubbed, as they are not necessary for 12.0.0 to run (and their outputs won't be saved anywhere).
+ A future atmosphère update will implement these behaviors, in the interest of reflecting official logic as faithfully as we can.
+ Atmosphère no longer uses the /contents/ folder for its own programs.
+ Atmosphère's system modules are now bundled together in the single file "stratosphere.romfs".
+ For those working on developing for atmosphère, executables inside the /contents/ directory will be preferred to those in "stratosphere.romfs".
+ **Please Note**: In order to facilitate this change (and the desired behavior), the first time you boot after extracting a release zip, atmosphère system modules inside /contents/ will be deleted.
+ This will have no impact on user programs (it only removes programs with specific program ids).
+ Improvements were made to mesosphere, including:
+ An extension InfoType was added for getting the current process handle, without having to spawn a thread and do IPC with oneself.
+ An issue was fixed in SvcSetDebugThreadContext.
+ An issue was fixed when doing IPC with user buffers.
+ Support was fixed for toggling the custom setting `usb!usb30_force_enabled` on 9.0.0+.
+ This was broken by Nintendo's introducing a dependency that made USB a requirement to launch before custom settings are parsed.
+ Since the fix, you can now toggle the setting (as you could prior to atmosphère 0.9.4), and it will work as expected.
+ **Please Note**: Enabling USB 3.0 often severely impacts wireless communications.
+ Because of this, the setting will default to off. If you experience issues with it enabled, consider disabling it.
+ A warning was added to daybreak when resetting the console to factory settings.
+ Substantial work was completed towards atmosphere's upcoming implementation of the host target connection protocol.
+ Once completed, users will be able to interact with a Switch running atmosphère via a PC application ("Starlink") currently under development.
+ Planned eventual features for connected consoles include a gdbstub, interacting with memory (for cheat development), streaming gameplay audio and video, and accessing the Switch's SD card filesystem.
+ Switch homebrew will also have access to a (configurable and sandboxed) filesystem on the host PC, while connected.
+ Towards this end, the following was accomplished:
+ The "htc" system module was reimplemented completely.
+ The system module which provides remote access to the SD card was reimplemented completely.
+ This is currently the active focus of atmosphère's development.
+ **Please Note**: Support is not yet completed, and users are disadvised from interacting with the related settings for the time being, unless they particularly know what they're doing.
+ A number of minor issues were fixed, including:
+ A bug was fixed in `dmnt` that could cause a fatal when launching certain games with cheats active.
+ An issue was fixed that could cause an abort in `sm` when using a large number of custom system modules.
+ An issue was fixed that prevented launching gamecards on 1.0.0.
+ Minor issues were fixed in the cheat virtual machine's behavior.
+ Several issues were fixed, and usability and stability were improved.
## 0.18.1
+ A number of minor issues were fixed, including:
+ The new `dns.mitm` module added in 0.18.0 no longer fatal errors when receiving port=nullptr.
+ This fixes youtube ad-blocking, and possibly other usecases.
+ A bug was fixed that caused ams.mitm to incorrectly cache data storages.
+ This potentially broke DLC when using romfs mods, and could have caused other issues (e.g. with custom themes, and maybe other cases).
+ A bug was fixed in power state control module registration.
+ This might fix a weird edge case with system module dependencies on sleep/wake, but probably nobody should notice any differences.
+ A bug was fixed where mesosphere sometimes treated virtual core IDs as though they were physical core IDs.
+ This had zero impact, because for Switch virtual core == physical core, but it could have affected future platforms if it had remained unresolved.
+ Several issues were fixed, and usability and stability were improved.
## 0.18.0
+ A new mitm module was added (`dns.mitm`).
+ This provides a highly configurable mechanism for redirecting DNS resolution requests.
+ By default atmosphère redirects resolution requests for official telemetry servers to a loopback address.
+ Documentation on how to configure `dns.mitm` to meet your more specific needs may be found [here](https://github.com/Atmosphere-NX/Atmosphere/blob/master/docs/features/dns_mitm.md).
+ The service framework API (`sf`) was refactored to be more accurate to official logic and greatly reduce memory requirements.
+ The comparison of atmosphère module memory usage versus Nintendo's found [here](https://github.com/Atmosphere-NX/Atmosphere/wiki/Memory-Comparisons) was updated to reflect this.
+ **Please Note**: If you are a developer using the libstratosphere service APIs, some updating may be required. Contact SciresM#0524 on discord for assistance if required.
+ A number of deprecations were removed, following a general codebase cleanup:
+ The `sm` extension to not unregister services on connection close was superseded by official opt-in logic in 11.0.0, and has been removed in favor of official logic.
+ This should have zero impact on users.
+ The temporary `hid-mitm` added in 0.9.0 has finally been removed, following over a year of deprecation.
+ There shouldn't be any homebrew in use still affected by this, but the situation will be monitored.
+ If this is somehow still a real issue, an unaffiliated hid mitm sysmodule providing the same functionality can be created and released, separate from atmosphère itself.
+ Several issues were fixed, and usability and stability were improved.
## 0.17.1 ## 0.17.1
+ A number of atmosphère's modules were using more memory than their Nintendo equivalent's in 0.17.0; a number of code generatio tweaks have been applied to fix this across the board. + A number of atmosphère's modules were using more memory than their Nintendo equivalent's in 0.17.0; a number of code generatio tweaks have been applied to fix this across the board.
+ A detailed comparison of atmosphère module memory usage versus Nintendo's was made and can be found [here](https://github.com/Atmosphere-NX/Atmosphere/wiki/Memory-Comparisons). + A detailed comparison of atmosphère module memory usage versus Nintendo's was made and can be found [here](https://github.com/Atmosphere-NX/Atmosphere/wiki/Memory-Comparisons).
@@ -15,7 +125,7 @@
+ This also substantially improves power drain when the system is shut off; consoles powered off from Atmosphere should now drain battery at the same reduced rate as original firmware. + This also substantially improves power drain when the system is shut off; consoles powered off from Atmosphere should now drain battery at the same reduced rate as original firmware.
+ A number of minor changes were made, including: + A number of minor changes were made, including:
+ A number of inconsistencies in the build system were fixed. + A number of inconsistencies in the build system were fixed.
+ Fow those building atmosphère at home, the `boot` sysmodule will no longer rebuild every time make is invoked. + For those building atmosphère at home, the `boot` sysmodule will no longer rebuild every time make is invoked.
+ This substantially improves build times during development iteration. + This substantially improves build times during development iteration.
+ `sm` was updated to more accurately reflect how official code manages request deferral. + `sm` was updated to more accurately reflect how official code manages request deferral.
+ `mesosphère` was updated to more accurately reflect official kernel management of the trace buffer. + `mesosphère` was updated to more accurately reflect official kernel management of the trace buffer.

View File

@@ -25,12 +25,6 @@ set_mitm enables intercepting requests to the system settings service. It curren
+ `ns` system module and games (to allow for overriding game locales) + `ns` system module and games (to allow for overriding game locales)
+ All firmware debug settings requests (to allow modification of system settings not directly exposed to the user) + All firmware debug settings requests (to allow modification of system settings not directly exposed to the user)
## dns_mitm
dns_mitm enables intercepting requests to dns resolution services, to enable redirecting requests for specified hostnames.
For documentation, see [here](../../features/dns_mitm.md).
### Firmware Version ### Firmware Version
set_mitm intercepts the `GetFirmwareVersion` command, if the requester is `qlaunch` or `maintenance`. set_mitm intercepts the `GetFirmwareVersion` command, if the requester is `qlaunch` or `maintenance`.
It modifies the `display_version` field of the returned system version, causing the version to display It modifies the `display_version` field of the returned system version, causing the version to display
@@ -39,3 +33,8 @@ in settings as `#.#.#|AMS #.#.#|?` with `? = S` when running under system eMMC o
### System Settings ### System Settings
set_mitm intercepts the `GetSettingsItemValueSize` and `GetSettingsItemValue` commands for all requesters. set_mitm intercepts the `GetSettingsItemValueSize` and `GetSettingsItemValue` commands for all requesters.
It does so in order to enable user configuration of system settings, which are parsed from `/atmosphere/system_settings.ini` on boot. See [here](../../features/configurations.md) for more information on the system settings format. It does so in order to enable user configuration of system settings, which are parsed from `/atmosphere/system_settings.ini` on boot. See [here](../../features/configurations.md) for more information on the system settings format.
## dns_mitm
dns_mitm enables intercepting requests to dns resolution services, to enable redirecting requests for specified hostnames.
For documentation, see [here](../../features/dns_mitm.md).

View File

@@ -11,6 +11,8 @@ In particular, hosts files parsed by DNS.mitm have the following extensions to t
+ `*` is treated as a wildcard character, matching any collection of 0 or more characters wherever it occurs in a hostname. + `*` is treated as a wildcard character, matching any collection of 0 or more characters wherever it occurs in a hostname.
+ `%` is treated as a stand-in for the value of `nsd!environment_identifier`. This is always `lp1`, on production devices. + `%` is treated as a stand-in for the value of `nsd!environment_identifier`. This is always `lp1`, on production devices.
If multiple entries in a host file match a domain, the last-defined match is used.
Please note that homebrew may trigger a hosts file re-parse by sending the extension IPC command 65000 ("AtmosphereReloadHostsFile") to a connected `sfdnsres` session. Please note that homebrew may trigger a hosts file re-parse by sending the extension IPC command 65000 ("AtmosphereReloadHostsFile") to a connected `sfdnsres` session.
### Hosts file selection ### Hosts file selection

View File

@@ -6,7 +6,7 @@
[subrepo] [subrepo]
remote = https://github.com/m4xw/emuMMC remote = https://github.com/m4xw/emuMMC
branch = develop branch = develop
commit = 5eed18eb527bbaa63aee5323c26de5b0cca6d28e commit = cbc294c390ed73bb281bc1028a8899c053427112
parent = 021b29d2dbc8ed0469bc822393e58c9f0d174d57 parent = 38f9a76ba028995ed3274da3a45b0254f09d1f59
method = rebase method = rebase
cmdver = 0.4.1 cmdver = 0.4.1

View File

@@ -32,7 +32,7 @@ CFLAGS += $(INCLUDE) -D__SWITCH__
CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++17 CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++17
ASFLAGS := -g $(ARCH) ASFLAGS := -g $(ARCH)
LDFLAGS = -specs=$(DEVKITPRO)/libnx/switch.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map) LDFLAGS = -specs=$(EMUMMCDIR)/emummc.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map)
ifneq ($(BUILD),$(notdir $(CURDIR))) ifneq ($(BUILD),$(notdir $(CURDIR)))

201
emummc/emummc.ld Normal file
View File

@@ -0,0 +1,201 @@
OUTPUT_ARCH(aarch64)
ENTRY(_start)
PHDRS
{
code PT_LOAD FLAGS(5) /* Read | Execute */;
rodata PT_LOAD FLAGS(4) /* Read */;
data PT_LOAD FLAGS(6) /* Read | Write */;
dyn PT_DYNAMIC;
}
SECTIONS
{
/* =========== CODE section =========== */
PROVIDE(__start__ = 0x0);
. = __start__;
__code_start = . ;
.crt0 :
{
KEEP (*(.crt0))
. = ALIGN(8);
} :code
.init :
{
KEEP( *(.init) )
. = ALIGN(8);
} :code
.plt :
{
*(.plt)
*(.iplt)
. = ALIGN(8);
} :code
.text :
{
*(.text.unlikely .text.*_unlikely .text.unlikely.*)
*(.text.exit .text.exit.*)
*(.text.startup .text.startup.*)
*(.text.hot .text.hot.*)
*(.text .stub .text.* .gnu.linkonce.t.*)
. = ALIGN(8);
} :code
.fini :
{
KEEP( *(.fini) )
. = ALIGN(8);
} :code
/* =========== RODATA section =========== */
. = ALIGN(0x1000);
__rodata_start = . ;
.nx-module-name : { KEEP (*(.nx-module-name)) } :rodata
.rodata :
{
*(.rodata .rodata.* .gnu.linkonce.r.*)
. = ALIGN(8);
} :rodata
.eh_frame_hdr : { __eh_frame_hdr_start = .; *(.eh_frame_hdr) *(.eh_frame_entry .eh_frame_entry.*) __eh_frame_hdr_end = .; } :rodata
.eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) *(.eh_frame.*) } :rodata
.gcc_except_table : ONLY_IF_RO { *(.gcc_except_table .gcc_except_table.*) } :rodata
.gnu_extab : ONLY_IF_RO { *(.gnu_extab*) } : rodata
.dynamic : { *(.dynamic) } :rodata :dyn
.dynsym : { *(.dynsym) } :rodata
.dynstr : { *(.dynstr) } :rodata
.rela.dyn : { *(.rela.*) } :rodata
.interp : { *(.interp) } :rodata
.hash : { *(.hash) } :rodata
.gnu.hash : { *(.gnu.hash) } :rodata
.gnu.version : { *(.gnu.version) } :rodata
.gnu.version_d : { *(.gnu.version_d) } :rodata
.gnu.version_r : { *(.gnu.version_r) } :rodata
.note.gnu.build-id : { *(.note.gnu.build-id) } :rodata
/* =========== DATA section =========== */
. = ALIGN(0x1000);
__data_start = . ;
.eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) *(.eh_frame.*) } :data
.gcc_except_table : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) } :data
.gnu_extab : ONLY_IF_RW { *(.gnu_extab*) } : data
.exception_ranges : ONLY_IF_RW { *(.exception_ranges .exception_ranges*) } :data
.tdata ALIGN(8) :
{
__tdata_lma = .;
*(.tdata .tdata.* .gnu.linkonce.td.*)
. = ALIGN(8);
__tdata_lma_end = .;
} :data
.tbss ALIGN(8) :
{
*(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon)
. = ALIGN(8);
} :data
.preinit_array ALIGN(8) :
{
PROVIDE (__preinit_array_start = .);
KEEP (*(.preinit_array))
PROVIDE (__preinit_array_end = .);
} :data
.init_array ALIGN(8) :
{
PROVIDE (__init_array_start = .);
KEEP( *(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)) )
KEEP( *(.init_array .ctors) )
PROVIDE (__init_array_end = .);
} :data
.fini_array ALIGN(8) :
{
PROVIDE (__fini_array_start = .);
KEEP( *(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)) )
KEEP( *(.fini_array .dtors) )
PROVIDE (__fini_array_end = .);
} :data
__got_start__ = .;
.got : { *(.got) *(.igot) } :data
.got.plt : { *(.got.plt) *(.igot.plt) } :data
__got_end__ = .;
.data ALIGN(8) :
{
*(.data .data.* .gnu.linkonce.d.*)
SORT(CONSTRUCTORS)
} :data
__bss_start__ = .;
.bss ALIGN(8) :
{
*(.dynbss)
*(.bss .bss.* .gnu.linkonce.b.*)
*(COMMON)
. = ALIGN(8);
/* Reserve space for the TLS segment of the main thread */
__tls_start = .;
. += + SIZEOF(.tdata) + SIZEOF(.tbss);
__tls_end = .;
} : data
__bss_end__ = .;
__end__ = ABSOLUTE(.) ;
. = ALIGN(0x1000);
__argdata__ = ABSOLUTE(.) ;
/* ==================
==== Metadata ====
================== */
/* Discard sections that difficult post-processing */
/DISCARD/ : { *(.group .comment .note) }
/* Stabs debugging sections. */
.stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) }
.stab.excl 0 : { *(.stab.excl) }
.stab.exclstr 0 : { *(.stab.exclstr) }
.stab.index 0 : { *(.stab.index) }
.stab.indexstr 0 : { *(.stab.indexstr) }
/* DWARF debug sections.
Symbols in the DWARF debugging sections are relative to the beginning
of the section so we begin them at 0. */
/* DWARF 1 */
.debug 0 : { *(.debug) }
.line 0 : { *(.line) }
/* GNU DWARF 1 extensions */
.debug_srcinfo 0 : { *(.debug_srcinfo) }
.debug_sfnames 0 : { *(.debug_sfnames) }
/* DWARF 1.1 and DWARF 2 */
.debug_aranges 0 : { *(.debug_aranges) }
.debug_pubnames 0 : { *(.debug_pubnames) }
/* DWARF 2 */
.debug_info 0 : { *(.debug_info) }
.debug_abbrev 0 : { *(.debug_abbrev) }
.debug_line 0 : { *(.debug_line) }
.debug_frame 0 : { *(.debug_frame) }
.debug_str 0 : { *(.debug_str) }
.debug_loc 0 : { *(.debug_loc) }
.debug_macinfo 0 : { *(.debug_macinfo) }
}

8
emummc/emummc.specs Normal file
View File

@@ -0,0 +1,8 @@
%rename link old_link
*link:
%(old_link) -T %:getenv(TOPDIR /emummc.ld) -pie --no-dynamic-linker --spare-dynamic-tags=0 --gc-sections -z text -z nodynamic-undefined-weak --build-id=sha1 --nx-module-name
*startfile:
crti%O%s crtbegin%O%s

View File

@@ -51,6 +51,10 @@
#include "offsets/1020_exfat.h" #include "offsets/1020_exfat.h"
#include "offsets/1100.h" #include "offsets/1100.h"
#include "offsets/1100_exfat.h" #include "offsets/1100_exfat.h"
#include "offsets/1200.h"
#include "offsets/1200_exfat.h"
#include "offsets/1203.h"
#include "offsets/1203_exfat.h"
#include "../utils/fatal.h" #include "../utils/fatal.h"
#define GET_OFFSET_STRUCT_NAME(vers) g_offsets##vers #define GET_OFFSET_STRUCT_NAME(vers) g_offsets##vers
@@ -113,6 +117,10 @@ DEFINE_OFFSET_STRUCT(_1020);
DEFINE_OFFSET_STRUCT(_1020_EXFAT); DEFINE_OFFSET_STRUCT(_1020_EXFAT);
DEFINE_OFFSET_STRUCT(_1100); DEFINE_OFFSET_STRUCT(_1100);
DEFINE_OFFSET_STRUCT(_1100_EXFAT); DEFINE_OFFSET_STRUCT(_1100_EXFAT);
DEFINE_OFFSET_STRUCT(_1200);
DEFINE_OFFSET_STRUCT(_1200_EXFAT);
DEFINE_OFFSET_STRUCT(_1203);
DEFINE_OFFSET_STRUCT(_1203_EXFAT);
const fs_offsets_t *get_fs_offsets(enum FS_VER version) { const fs_offsets_t *get_fs_offsets(enum FS_VER version) {
switch (version) { switch (version) {
@@ -186,6 +194,14 @@ const fs_offsets_t *get_fs_offsets(enum FS_VER version) {
return &(GET_OFFSET_STRUCT_NAME(_1100)); return &(GET_OFFSET_STRUCT_NAME(_1100));
case FS_VER_11_0_0_EXFAT: case FS_VER_11_0_0_EXFAT:
return &(GET_OFFSET_STRUCT_NAME(_1100_EXFAT)); return &(GET_OFFSET_STRUCT_NAME(_1100_EXFAT));
case FS_VER_12_0_0:
return &(GET_OFFSET_STRUCT_NAME(_1200));
case FS_VER_12_0_0_EXFAT:
return &(GET_OFFSET_STRUCT_NAME(_1200_EXFAT));
case FS_VER_12_0_3:
return &(GET_OFFSET_STRUCT_NAME(_1203));
case FS_VER_12_0_3_EXFAT:
return &(GET_OFFSET_STRUCT_NAME(_1203_EXFAT));
default: default:
fatal_abort(Fatal_UnknownVersion); fatal_abort(Fatal_UnknownVersion);
} }

View File

@@ -74,6 +74,12 @@ enum FS_VER
FS_VER_11_0_0, FS_VER_11_0_0,
FS_VER_11_0_0_EXFAT, FS_VER_11_0_0_EXFAT,
FS_VER_12_0_0,
FS_VER_12_0_0_EXFAT,
FS_VER_12_0_3,
FS_VER_12_0_3_EXFAT,
FS_VER_MAX, FS_VER_MAX,
}; };

View File

@@ -0,0 +1,59 @@
/*
* Copyright (c) 2019 m4xw <m4x@m4xw.net>
* Copyright (c) 2019 Atmosphere-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope 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/>.
*/
#ifndef __FS_1200_H__
#define __FS_1200_H__
// Accessor vtable getters
#define FS_OFFSET_1200_SDMMC_ACCESSOR_GC 0x154FD0
#define FS_OFFSET_1200_SDMMC_ACCESSOR_SD 0x156DE0
#define FS_OFFSET_1200_SDMMC_ACCESSOR_NAND 0x155500
// Hooks
#define FS_OFFSET_1200_SDMMC_WRAPPER_READ 0x150970
#define FS_OFFSET_1200_SDMMC_WRAPPER_WRITE 0x150A30
#define FS_OFFSET_1200_RTLD 0x688
#define FS_OFFSET_1200_RTLD_DESTINATION ((uintptr_t)(INT64_C(-0x3C)))
#define FS_OFFSET_1200_CLKRST_SET_MIN_V_CLK_RATE 0x14FCC0
// Misc funcs
#define FS_OFFSET_1200_LOCK_MUTEX 0x29350
#define FS_OFFSET_1200_UNLOCK_MUTEX 0x293A0
#define FS_OFFSET_1200_SDMMC_WRAPPER_CONTROLLER_OPEN 0x150850
#define FS_OFFSET_1200_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x1508E0
// Misc Data
#define FS_OFFSET_1200_SD_MUTEX 0xE3D3E8
#define FS_OFFSET_1200_NAND_MUTEX 0xE38768
#define FS_OFFSET_1200_ACTIVE_PARTITION 0xE387A8
#define FS_OFFSET_1200_SDMMC_DAS_HANDLE 0xE20DB0
// NOPs
#define FS_OFFSET_1200_SD_DAS_INIT 0x27244
// Nintendo Paths
#define FS_OFFSET_1200_NINTENDO_PATHS \
{ \
{.opcode_reg = 3, .adrp_offset = 0x0006E810, .add_rel_offset = 0x00000004}, \
{.opcode_reg = 3, .adrp_offset = 0x0007AEC0, .add_rel_offset = 0x00000004}, \
{.opcode_reg = 4, .adrp_offset = 0x00081254, .add_rel_offset = 0x00000004}, \
{.opcode_reg = 4, .adrp_offset = 0x00092850, .add_rel_offset = 0x00000004}, \
{.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0}, \
}
#endif // __FS_1200_H__

View File

@@ -0,0 +1,59 @@
/*
* Copyright (c) 2019 m4xw <m4x@m4xw.net>
* Copyright (c) 2019 Atmosphere-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope 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/>.
*/
#ifndef __FS_1200_EXFAT_H__
#define __FS_1200_EXFAT_H__
// Accessor vtable getters
#define FS_OFFSET_1200_EXFAT_SDMMC_ACCESSOR_GC 0x154FD0
#define FS_OFFSET_1200_EXFAT_SDMMC_ACCESSOR_SD 0x156DE0
#define FS_OFFSET_1200_EXFAT_SDMMC_ACCESSOR_NAND 0x155500
// Hooks
#define FS_OFFSET_1200_EXFAT_SDMMC_WRAPPER_READ 0x150970
#define FS_OFFSET_1200_EXFAT_SDMMC_WRAPPER_WRITE 0x150A30
#define FS_OFFSET_1200_EXFAT_RTLD 0x688
#define FS_OFFSET_1200_EXFAT_RTLD_DESTINATION ((uintptr_t)(INT64_C(-0x3C)))
#define FS_OFFSET_1200_EXFAT_CLKRST_SET_MIN_V_CLK_RATE 0x14FCC0
// Misc funcs
#define FS_OFFSET_1200_EXFAT_LOCK_MUTEX 0x29350
#define FS_OFFSET_1200_EXFAT_UNLOCK_MUTEX 0x293A0
#define FS_OFFSET_1200_EXFAT_SDMMC_WRAPPER_CONTROLLER_OPEN 0x150850
#define FS_OFFSET_1200_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x1508E0
// Misc Data
#define FS_OFFSET_1200_EXFAT_SD_MUTEX 0xE4B3E8
#define FS_OFFSET_1200_EXFAT_NAND_MUTEX 0xE46768
#define FS_OFFSET_1200_EXFAT_ACTIVE_PARTITION 0xE467A8
#define FS_OFFSET_1200_EXFAT_SDMMC_DAS_HANDLE 0xE2EDB0
// NOPs
#define FS_OFFSET_1200_EXFAT_SD_DAS_INIT 0x27244
// Nintendo Paths
#define FS_OFFSET_1200_EXFAT_NINTENDO_PATHS \
{ \
{.opcode_reg = 3, .adrp_offset = 0x0006E810, .add_rel_offset = 0x00000004}, \
{.opcode_reg = 3, .adrp_offset = 0x0007AEC0, .add_rel_offset = 0x00000004}, \
{.opcode_reg = 4, .adrp_offset = 0x00081254, .add_rel_offset = 0x00000004}, \
{.opcode_reg = 4, .adrp_offset = 0x00092850, .add_rel_offset = 0x00000004}, \
{.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0}, \
}
#endif // __FS_1200_EXFAT_H__

View File

@@ -0,0 +1,60 @@
/*
* Copyright (c) 2019 m4xw <m4x@m4xw.net>
* Copyright (c) 2019 Atmosphere-NX
* Copyright (c) 2021 CTCaer
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope 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/>.
*/
#ifndef __FS_1203_H__
#define __FS_1203_H__
// Accessor vtable getters
#define FS_OFFSET_1203_SDMMC_ACCESSOR_GC 0x1550E0
#define FS_OFFSET_1203_SDMMC_ACCESSOR_SD 0x156EF0
#define FS_OFFSET_1203_SDMMC_ACCESSOR_NAND 0x155610
// Hooks
#define FS_OFFSET_1203_SDMMC_WRAPPER_READ 0x150A80
#define FS_OFFSET_1203_SDMMC_WRAPPER_WRITE 0x150B40
#define FS_OFFSET_1203_RTLD 0x688
#define FS_OFFSET_1203_RTLD_DESTINATION ((uintptr_t)(INT64_C(-0x3C)))
#define FS_OFFSET_1203_CLKRST_SET_MIN_V_CLK_RATE 0x14FDD0
// Misc funcs
#define FS_OFFSET_1203_LOCK_MUTEX 0x29350
#define FS_OFFSET_1203_UNLOCK_MUTEX 0x293A0
#define FS_OFFSET_1203_SDMMC_WRAPPER_CONTROLLER_OPEN 0x150960
#define FS_OFFSET_1203_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x1509F0
// Misc Data
#define FS_OFFSET_1203_SD_MUTEX 0xE3D3E8
#define FS_OFFSET_1203_NAND_MUTEX 0xE38768
#define FS_OFFSET_1203_ACTIVE_PARTITION 0xE387A8
#define FS_OFFSET_1203_SDMMC_DAS_HANDLE 0xE20DB0
// NOPs
#define FS_OFFSET_1203_SD_DAS_INIT 0x27244
// Nintendo Paths
#define FS_OFFSET_1203_NINTENDO_PATHS \
{ \
{.opcode_reg = 3, .adrp_offset = 0x0006E920, .add_rel_offset = 0x00000004}, \
{.opcode_reg = 3, .adrp_offset = 0x0007AFD0, .add_rel_offset = 0x00000004}, \
{.opcode_reg = 4, .adrp_offset = 0x00081364, .add_rel_offset = 0x00000004}, \
{.opcode_reg = 4, .adrp_offset = 0x00092960, .add_rel_offset = 0x00000004}, \
{.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0}, \
}
#endif // __FS_1203_H__

View File

@@ -0,0 +1,60 @@
/*
* Copyright (c) 2019 m4xw <m4x@m4xw.net>
* Copyright (c) 2019 Atmosphere-NX
* Copyright (c) 2021 CTCaer
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope 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/>.
*/
#ifndef __FS_1203_EXFAT_H__
#define __FS_1203_EXFAT_H__
// Accessor vtable getters
#define FS_OFFSET_1203_EXFAT_SDMMC_ACCESSOR_GC 0x1550E0
#define FS_OFFSET_1203_EXFAT_SDMMC_ACCESSOR_SD 0x156EF0
#define FS_OFFSET_1203_EXFAT_SDMMC_ACCESSOR_NAND 0x155610
// Hooks
#define FS_OFFSET_1203_EXFAT_SDMMC_WRAPPER_READ 0x150A80
#define FS_OFFSET_1203_EXFAT_SDMMC_WRAPPER_WRITE 0x150B40
#define FS_OFFSET_1203_EXFAT_RTLD 0x688
#define FS_OFFSET_1203_EXFAT_RTLD_DESTINATION ((uintptr_t)(INT64_C(-0x3C)))
#define FS_OFFSET_1203_EXFAT_CLKRST_SET_MIN_V_CLK_RATE 0x14FDD0
// Misc funcs
#define FS_OFFSET_1203_EXFAT_LOCK_MUTEX 0x29350
#define FS_OFFSET_1203_EXFAT_UNLOCK_MUTEX 0x293A0
#define FS_OFFSET_1203_EXFAT_SDMMC_WRAPPER_CONTROLLER_OPEN 0x150960
#define FS_OFFSET_1203_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x1509F0
// Misc Data
#define FS_OFFSET_1203_EXFAT_SD_MUTEX 0xE4B3E8
#define FS_OFFSET_1203_EXFAT_NAND_MUTEX 0xE46768
#define FS_OFFSET_1203_EXFAT_ACTIVE_PARTITION 0xE467A8
#define FS_OFFSET_1203_EXFAT_SDMMC_DAS_HANDLE 0xE2EDB0
// NOPs
#define FS_OFFSET_1203_EXFAT_SD_DAS_INIT 0x27244
// Nintendo Paths
#define FS_OFFSET_1203_EXFAT_NINTENDO_PATHS \
{ \
{.opcode_reg = 3, .adrp_offset = 0x0006E920, .add_rel_offset = 0x00000004}, \
{.opcode_reg = 3, .adrp_offset = 0x0007AFD0, .add_rel_offset = 0x00000004}, \
{.opcode_reg = 4, .adrp_offset = 0x00081364, .add_rel_offset = 0x00000004}, \
{.opcode_reg = 4, .adrp_offset = 0x00092960, .add_rel_offset = 0x00000004}, \
{.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0}, \
}
#endif // __FS_1203_EXFAT_H__

View File

@@ -292,6 +292,36 @@ static uint64_t emummc_read_write_inner(void *buf, unsigned int sector, unsigned
{ {
fp = &f_emu.fp_gpp[sector / f_emu.part_size]; fp = &f_emu.fp_gpp[sector / f_emu.part_size];
sector = sector % f_emu.part_size; sector = sector % f_emu.part_size;
// Special handling for reads/writes which cross file-boundaries.
if (__builtin_expect(sector + num_sectors > f_emu.part_size, 0))
{
unsigned int remaining = num_sectors;
while (remaining > 0) {
const unsigned int cur_sectors = MIN(remaining, f_emu.part_size - sector);
if (f_lseek(fp, (u64)sector << 9) != FR_OK)
return 0; // Out of bounds.
if (is_write)
{
if (f_write_fast(fp, buf, (u64)cur_sectors << 9) != FR_OK)
return 0;
}
else
{
if (f_read_fast(fp, buf, (u64)cur_sectors << 9) != FR_OK)
return 0;
}
buf = (char *)buf + ((u64)cur_sectors << 9);
remaining -= cur_sectors;
sector = 0;
++fp;
}
return 1;
}
} }
else else
{ {
@@ -306,14 +336,14 @@ static uint64_t emummc_read_write_inner(void *buf, unsigned int sector, unsigned
break; break;
} }
if (f_lseek(fp, sector << 9) != FR_OK) if (f_lseek(fp, (u64)sector << 9) != FR_OK)
return 0; // Out of bounds. return 0; // Out of bounds.
uint64_t res = 0; uint64_t res = 0;
if (!is_write) if (!is_write)
res = !f_read_fast(fp, buf, num_sectors << 9); res = !f_read_fast(fp, buf, (u64)num_sectors << 9);
else else
res = !f_write_fast(fp, buf, num_sectors << 9); res = !f_write_fast(fp, buf, (u64)num_sectors << 9);
return res; return res;
} }
@@ -328,13 +358,13 @@ uint64_t sdmmc_wrapper_controller_open(int mmc_id)
if (_this != NULL) if (_this != NULL)
{ {
// Lock eMMC xfer while SD card is being initialized by FS. // Lock eMMC xfer while SD card is being initialized by FS.
if (_this == sdmmc_accessor_get(FS_SDMMC_SD)) if (mmc_id == FS_SDMMC_SD)
mutex_lock_handler(FS_SDMMC_EMMC); // Recursive Mutex, handler will lock SD as well if custom_driver mutex_lock_handler(FS_SDMMC_EMMC); // Recursive Mutex, handler will lock SD as well if custom_driver
result = _this->vtab->sdmmc_accessor_controller_open(_this); result = _this->vtab->sdmmc_accessor_controller_open(_this);
// Unlock eMMC. // Unlock eMMC.
if (_this == sdmmc_accessor_get(FS_SDMMC_SD)) if (mmc_id == FS_SDMMC_SD)
mutex_unlock_handler(FS_SDMMC_EMMC); mutex_unlock_handler(FS_SDMMC_EMMC);
return result; return result;

View File

@@ -1,7 +1,4 @@
%rename link old_link %rename link old_link
*link: *link:
%(old_link) -T %:getenv(TOPDIR /loader_stub.ld) --gc-sections --nmagic -nostdlib -nostartfiles %(old_link) -T %:getenv(TOPDIR /loader_stub.ld) --gc-sections --nmagic
*startfile:
crti%O%s crtbegin%O%s

View File

@@ -1,7 +1,4 @@
%rename link old_link %rename link old_link
*link: *link:
%(old_link) -T %:getenv(TOPDIR /mariko_fatal.ld) --gc-sections --nmagic -nostdlib -nostartfiles %(old_link) -T %:getenv(TOPDIR /mariko_fatal.ld) --gc-sections --nmagic
*startfile:
crti%O%s crtbegin%O%s

View File

@@ -1,4 +1,4 @@
%rename link old_link %rename link old_link
*link: *link:
%(old_link) -T %:getenv(TOPDIR /program.ld) --gc-sections --nmagic -nostdlib -nostartfiles %(old_link) -T %:getenv(TOPDIR /program.ld) --gc-sections --nmagic

View File

@@ -1,7 +1,4 @@
%rename link old_link %rename link old_link
*link: *link:
%(old_link) -T %:getenv(TOPDIR /rebootstub.ld) --gc-sections --nmagic -nostdlib -nostartfiles %(old_link) -T %:getenv(TOPDIR /rebootstub.ld) --gc-sections --nmagic
*startfile:
crti%O%s crtbegin%O%s

View File

@@ -1,7 +1,4 @@
%rename link old_link %rename link old_link
*link: *link:
%(old_link) -T %:getenv(TOPDIR /sc7fw.ld) --gc-sections --nmagic -nostdlib -nostartfiles %(old_link) -T %:getenv(TOPDIR /sc7fw.ld) --gc-sections --nmagic
*startfile:
crti%O%s crtbegin%O%s

View File

@@ -85,10 +85,10 @@ _ZN3ams6secmon4boot15VolatileKeyDataE:
/* We can get away with only including latest because exosphere supports newer-than-expected master key in engine. */ /* We can get away with only including latest because exosphere supports newer-than-expected master key in engine. */
/* TODO: Update on next change of keys. */ /* TODO: Update on next change of keys. */
/* Mariko Development Master Kek Source. */ /* Mariko Development Master Kek Source. */
.byte 0xF9, 0x37, 0xCF, 0x9A, 0xBD, 0x86, 0xBB, 0xA9, 0x9C, 0x9E, 0x03, 0xC4, 0xFC, 0xBC, 0x3B, 0xCE .byte 0x75, 0x2D, 0x2E, 0xF3, 0x2F, 0x3F, 0xFE, 0x65, 0xF4, 0xA9, 0x83, 0xB4, 0xED, 0x42, 0x63, 0xBA
/* Mariko Production Master Kek Source. */ /* Mariko Production Master Kek Source. */
.byte 0x0E, 0x44, 0x0C, 0xED, 0xB4, 0x36, 0xC0, 0x3F, 0xAA, 0x1D, 0xAE, 0xBF, 0x62, 0xB1, 0x09, 0x82 .byte 0xE5, 0x41, 0xAC, 0xEC, 0xD1, 0xA7, 0xD1, 0xAB, 0xED, 0x03, 0x77, 0xF1, 0x27, 0xCA, 0xF8, 0xF1
/* Development Master Key Vectors. */ /* Development Master Key Vectors. */
.byte 0x46, 0x22, 0xB4, 0x51, 0x9A, 0x7E, 0xA7, 0x7F, 0x62, 0xA1, 0x1F, 0x8F, 0xC5, 0x3A, 0xDB, 0xFE /* Zeroes encrypted with Master Key 00. */ .byte 0x46, 0x22, 0xB4, 0x51, 0x9A, 0x7E, 0xA7, 0x7F, 0x62, 0xA1, 0x1F, 0x8F, 0xC5, 0x3A, 0xDB, 0xFE /* Zeroes encrypted with Master Key 00. */
@@ -102,6 +102,7 @@ _ZN3ams6secmon4boot15VolatileKeyDataE:
.byte 0xEC, 0xE1, 0x46, 0x89, 0x37, 0xFD, 0xD2, 0x15, 0x8C, 0x3F, 0x24, 0x82, 0xEF, 0x49, 0x68, 0x04 /* Master key 07 encrypted with Master key 08. */ .byte 0xEC, 0xE1, 0x46, 0x89, 0x37, 0xFD, 0xD2, 0x15, 0x8C, 0x3F, 0x24, 0x82, 0xEF, 0x49, 0x68, 0x04 /* Master key 07 encrypted with Master key 08. */
.byte 0x43, 0x3D, 0xC5, 0x3B, 0xEF, 0x91, 0x02, 0x21, 0x61, 0x54, 0x63, 0x8A, 0x35, 0xE7, 0xCA, 0xEE /* Master key 08 encrypted with Master key 09. */ .byte 0x43, 0x3D, 0xC5, 0x3B, 0xEF, 0x91, 0x02, 0x21, 0x61, 0x54, 0x63, 0x8A, 0x35, 0xE7, 0xCA, 0xEE /* Master key 08 encrypted with Master key 09. */
.byte 0x6C, 0x2E, 0xCD, 0xB3, 0x34, 0x61, 0x77, 0xF5, 0xF9, 0xB1, 0xDD, 0x61, 0x98, 0x19, 0x3E, 0xD4 /* Master key 09 encrypted with Master key 0A. */ .byte 0x6C, 0x2E, 0xCD, 0xB3, 0x34, 0x61, 0x77, 0xF5, 0xF9, 0xB1, 0xDD, 0x61, 0x98, 0x19, 0x3E, 0xD4 /* Master key 09 encrypted with Master key 0A. */
.byte 0x21, 0x88, 0x6B, 0x10, 0x9E, 0x83, 0xD6, 0x52, 0xAB, 0x08, 0xDB, 0x6D, 0x39, 0xFF, 0x1C, 0x9C /* Master key 0A encrypted with Master key 0B. */
/* Production Master Key Vectors. */ /* Production Master Key Vectors. */
.byte 0x0C, 0xF0, 0x59, 0xAC, 0x85, 0xF6, 0x26, 0x65, 0xE1, 0xE9, 0x19, 0x55, 0xE6, 0xF2, 0x67, 0x3D /* Zeroes encrypted with Master Key 00. */ .byte 0x0C, 0xF0, 0x59, 0xAC, 0x85, 0xF6, 0x26, 0x65, 0xE1, 0xE9, 0x19, 0x55, 0xE6, 0xF2, 0x67, 0x3D /* Zeroes encrypted with Master Key 00. */
@@ -115,33 +116,37 @@ _ZN3ams6secmon4boot15VolatileKeyDataE:
.byte 0xEA, 0x60, 0xB3, 0xEA, 0xCE, 0x8F, 0x24, 0x46, 0x7D, 0x33, 0x9C, 0xD1, 0xBC, 0x24, 0x98, 0x29 /* Master key 07 encrypted with Master key 08. */ .byte 0xEA, 0x60, 0xB3, 0xEA, 0xCE, 0x8F, 0x24, 0x46, 0x7D, 0x33, 0x9C, 0xD1, 0xBC, 0x24, 0x98, 0x29 /* Master key 07 encrypted with Master key 08. */
.byte 0x4D, 0xD9, 0x98, 0x42, 0x45, 0x0D, 0xB1, 0x3C, 0x52, 0x0C, 0x9A, 0x44, 0xBB, 0xAD, 0xAF, 0x80 /* Master key 08 encrypted with Master key 09. */ .byte 0x4D, 0xD9, 0x98, 0x42, 0x45, 0x0D, 0xB1, 0x3C, 0x52, 0x0C, 0x9A, 0x44, 0xBB, 0xAD, 0xAF, 0x80 /* Master key 08 encrypted with Master key 09. */
.byte 0xB8, 0x96, 0x9E, 0x4A, 0x00, 0x0D, 0xD6, 0x28, 0xB3, 0xD1, 0xDB, 0x68, 0x5F, 0xFB, 0xE1, 0x2A /* Master key 09 encrypted with Master key 0A. */ .byte 0xB8, 0x96, 0x9E, 0x4A, 0x00, 0x0D, 0xD6, 0x28, 0xB3, 0xD1, 0xDB, 0x68, 0x5F, 0xFB, 0xE1, 0x2A /* Master key 09 encrypted with Master key 0A. */
.byte 0xC1, 0x8D, 0x16, 0xBB, 0x2A, 0xE4, 0x1D, 0xD4, 0xC2, 0xC1, 0xB6, 0x40, 0x94, 0x35, 0x63, 0x98 /* Master key 0A encrypted with Master key 0B. */
/* Device Master Key Source Sources. */ /* Device Master Key Source Sources. */
.byte 0x8B, 0x4E, 0x1C, 0x22, 0x42, 0x07, 0xC8, 0x73, 0x56, 0x94, 0x08, 0x8B, 0xCC, 0x47, 0x0F, 0x5D /* 4.0.0 Device Master Key Source Source. */ .byte 0x8B, 0x4E, 0x1C, 0x22, 0x42, 0x07, 0xC8, 0x73, 0x56, 0x94, 0x08, 0x8B, 0xCC, 0x47, 0x0F, 0x5D /* 4.0.0 Device Master Key Source Source. */
.byte 0x6C, 0xEF, 0xC6, 0x27, 0x8B, 0xEC, 0x8A, 0x91, 0x99, 0xAB, 0x24, 0xAC, 0x4F, 0x1C, 0x8F, 0x1C /* 5.0.0 Device Master Key Source Source. */ .byte 0x6C, 0xEF, 0xC6, 0x27, 0x8B, 0xEC, 0x8A, 0x91, 0x99, 0xAB, 0x24, 0xAC, 0x4F, 0x1C, 0x8F, 0x1C /* 5.0.0 Device Master Key Source Source. */
.byte 0x70, 0x08, 0x1B, 0x97, 0x44, 0x64, 0xF8, 0x91, 0x54, 0x9D, 0xC6, 0x84, 0x8F, 0x1A, 0xB2, 0xE4 /* 6.0.0 Device Master Key Source Source. */ .byte 0x70, 0x08, 0x1B, 0x97, 0x44, 0x64, 0xF8, 0x91, 0x54, 0x9D, 0xC6, 0x84, 0x8F, 0x1A, 0xB2, 0xE4 /* 6.0.0 Device Master Key Source Source. */
.byte 0x8E, 0x09, 0x1F, 0x7A, 0xBB, 0xCA, 0x6A, 0xFB, 0xB8, 0x9B, 0xD5, 0xC1, 0x25, 0x9C, 0xA9, 0x17 /* 6.2.0 Device Master Key Source Source. */ .byte 0x8E, 0x09, 0x1F, 0x7A, 0xBB, 0xCA, 0x6A, 0xFB, 0xB8, 0x9B, 0xD5, 0xC1, 0x25, 0x9C, 0xA9, 0x17 /* 6.2.0 Device Master Key Source Source. */
.byte 0x8F, 0x77, 0x5A, 0x96, 0xB0, 0x94, 0xFD, 0x8D, 0x28, 0xE4, 0x19, 0xC8, 0x16, 0x1C, 0xDB, 0x3D /* 7.0.0 Device Master Key Source Source. */ .byte 0x8F, 0x77, 0x5A, 0x96, 0xB0, 0x94, 0xFD, 0x8D, 0x28, 0xE4, 0x19, 0xC8, 0x16, 0x1C, 0xDB, 0x3D /* 7.0.0 Device Master Key Source Source. */
.byte 0x67, 0x62, 0xD4, 0x8E, 0x55, 0xCF, 0xFF, 0x41, 0x31, 0x15, 0x3B, 0x24, 0x0C, 0x7C, 0x07, 0xAE /* 8.1.0 Device Master Key Source Source. */ .byte 0x67, 0x62, 0xD4, 0x8E, 0x55, 0xCF, 0xFF, 0x41, 0x31, 0x15, 0x3B, 0x24, 0x0C, 0x7C, 0x07, 0xAE /* 8.1.0 Device Master Key Source Source. */
.byte 0x4A, 0xC3, 0x4E, 0x14, 0x8B, 0x96, 0x4A, 0xD5, 0xD4, 0x99, 0x73, 0xC4, 0x45, 0xAB, 0x8B, 0x49 /* 9.0.0 Device Master Key Source Source. */ .byte 0x4A, 0xC3, 0x4E, 0x14, 0x8B, 0x96, 0x4A, 0xD5, 0xD4, 0x99, 0x73, 0xC4, 0x45, 0xAB, 0x8B, 0x49 /* 9.0.0 Device Master Key Source Source. */
.byte 0x14, 0xB8, 0x74, 0x12, 0xCB, 0xBD, 0x0B, 0x8F, 0x20, 0xFB, 0x30, 0xDA, 0x27, 0xE4, 0x58, 0x94 /* 9.1.0 Device Master Key Source Source. */ .byte 0x14, 0xB8, 0x74, 0x12, 0xCB, 0xBD, 0x0B, 0x8F, 0x20, 0xFB, 0x30, 0xDA, 0x27, 0xE4, 0x58, 0x94 /* 9.1.0 Device Master Key Source Source. */
.byte 0xAA, 0xFD, 0xBC, 0xBB, 0x25, 0xC3, 0xA4, 0xEF, 0xE3, 0xEE, 0x58, 0x53, 0xB7, 0xF8, 0xDD, 0xD6 /* 12.1.0 Device Master Key Source Source. */
/* Development Device Master Kek Sources. */ /* Development Device Master Kek Sources. */
.byte 0xD6, 0xBD, 0x9F, 0xC6, 0x18, 0x09, 0xE1, 0x96, 0x20, 0x39, 0x60, 0xD2, 0x89, 0x83, 0x31, 0x34 /* 4.0.0 Device Master Kek Source. */ .byte 0xD6, 0xBD, 0x9F, 0xC6, 0x18, 0x09, 0xE1, 0x96, 0x20, 0x39, 0x60, 0xD2, 0x89, 0x83, 0x31, 0x34 /* 4.0.0 Device Master Kek Source. */
.byte 0x59, 0x2D, 0x20, 0x69, 0x33, 0xB5, 0x17, 0xBA, 0xCF, 0xB1, 0x4E, 0xFD, 0xE4, 0xC2, 0x7B, 0xA8 /* 5.0.0 Device Master Kek Source. */ .byte 0x59, 0x2D, 0x20, 0x69, 0x33, 0xB5, 0x17, 0xBA, 0xCF, 0xB1, 0x4E, 0xFD, 0xE4, 0xC2, 0x7B, 0xA8 /* 5.0.0 Device Master Kek Source. */
.byte 0xF6, 0xD8, 0x59, 0x63, 0x8F, 0x47, 0xCB, 0x4A, 0xD8, 0x74, 0x05, 0x7F, 0x88, 0x92, 0x33, 0xA5 /* 6.0.0 Device Master Kek Source. */ .byte 0xF6, 0xD8, 0x59, 0x63, 0x8F, 0x47, 0xCB, 0x4A, 0xD8, 0x74, 0x05, 0x7F, 0x88, 0x92, 0x33, 0xA5 /* 6.0.0 Device Master Kek Source. */
.byte 0x20, 0xAB, 0xF2, 0x0F, 0x05, 0xE3, 0xDE, 0x2E, 0xA1, 0xFB, 0x37, 0x5E, 0x8B, 0x22, 0x1A, 0x38 /* 6.2.0 Device Master Kek Source. */ .byte 0x20, 0xAB, 0xF2, 0x0F, 0x05, 0xE3, 0xDE, 0x2E, 0xA1, 0xFB, 0x37, 0x5E, 0x8B, 0x22, 0x1A, 0x38 /* 6.2.0 Device Master Kek Source. */
.byte 0x60, 0xAE, 0x56, 0x68, 0x11, 0xE2, 0x0C, 0x99, 0xDE, 0x05, 0xAE, 0x68, 0x78, 0x85, 0x04, 0xAE /* 7.0.0 Device Master Kek Source. */ .byte 0x60, 0xAE, 0x56, 0x68, 0x11, 0xE2, 0x0C, 0x99, 0xDE, 0x05, 0xAE, 0x68, 0x78, 0x85, 0x04, 0xAE /* 7.0.0 Device Master Kek Source. */
.byte 0x94, 0xD6, 0xA8, 0xC0, 0x95, 0xAF, 0xD0, 0xA6, 0x27, 0x53, 0x5E, 0xE5, 0x8E, 0x70, 0x1F, 0x87 /* 8.1.0 Device Master Kek Source. */ .byte 0x94, 0xD6, 0xA8, 0xC0, 0x95, 0xAF, 0xD0, 0xA6, 0x27, 0x53, 0x5E, 0xE5, 0x8E, 0x70, 0x1F, 0x87 /* 8.1.0 Device Master Kek Source. */
.byte 0x61, 0x6A, 0x88, 0x21, 0xA3, 0x52, 0xB0, 0x19, 0x16, 0x25, 0xA4, 0xE3, 0x4C, 0x54, 0x02, 0x0F /* 9.0.0 Device Master Kek Source. */ .byte 0x61, 0x6A, 0x88, 0x21, 0xA3, 0x52, 0xB0, 0x19, 0x16, 0x25, 0xA4, 0xE3, 0x4C, 0x54, 0x02, 0x0F /* 9.0.0 Device Master Kek Source. */
.byte 0x9D, 0xB1, 0xAE, 0xCB, 0xF6, 0xF6, 0xE3, 0xFE, 0xAB, 0x6F, 0xCB, 0xAF, 0x38, 0x03, 0xFC, 0x7B /* 9.1.0 Device Master Kek Source. */ .byte 0x9D, 0xB1, 0xAE, 0xCB, 0xF6, 0xF6, 0xE3, 0xFE, 0xAB, 0x6F, 0xCB, 0xAF, 0x38, 0x03, 0xFC, 0x7B /* 9.1.0 Device Master Kek Source. */
.byte 0xC4, 0xBB, 0xF3, 0x9F, 0xA3, 0xAA, 0x00, 0x99, 0x7C, 0x97, 0xAD, 0x91, 0x8F, 0xE8, 0x45, 0xCB /* 12.1.0 Device Master Kek Source. */
/* Production Device Master Kek Sources. */ /* Production Device Master Kek Sources. */
.byte 0x88, 0x62, 0x34, 0x6E, 0xFA, 0xF7, 0xD8, 0x3F, 0xE1, 0x30, 0x39, 0x50, 0xF0, 0xB7, 0x5D, 0x5D /* 4.0.0 Device Master Kek Source. */ .byte 0x88, 0x62, 0x34, 0x6E, 0xFA, 0xF7, 0xD8, 0x3F, 0xE1, 0x30, 0x39, 0x50, 0xF0, 0xB7, 0x5D, 0x5D /* 4.0.0 Device Master Kek Source. */
.byte 0x06, 0x1E, 0x7B, 0xE9, 0x6D, 0x47, 0x8C, 0x77, 0xC5, 0xC8, 0xE7, 0x94, 0x9A, 0xA8, 0x5F, 0x2E /* 5.0.0 Device Master Kek Source. */ .byte 0x06, 0x1E, 0x7B, 0xE9, 0x6D, 0x47, 0x8C, 0x77, 0xC5, 0xC8, 0xE7, 0x94, 0x9A, 0xA8, 0x5F, 0x2E /* 5.0.0 Device Master Kek Source. */
.byte 0x99, 0xFA, 0x98, 0xBD, 0x15, 0x1C, 0x72, 0xFD, 0x7D, 0x9A, 0xD5, 0x41, 0x00, 0xFD, 0xB2, 0xEF /* 6.0.0 Device Master Kek Source. */ .byte 0x99, 0xFA, 0x98, 0xBD, 0x15, 0x1C, 0x72, 0xFD, 0x7D, 0x9A, 0xD5, 0x41, 0x00, 0xFD, 0xB2, 0xEF /* 6.0.0 Device Master Kek Source. */
.byte 0x81, 0x3C, 0x6C, 0xBF, 0x5D, 0x21, 0xDE, 0x77, 0x20, 0xD9, 0x6C, 0xE3, 0x22, 0x06, 0xAE, 0xBB /* 6.2.0 Device Master Kek Source. */ .byte 0x81, 0x3C, 0x6C, 0xBF, 0x5D, 0x21, 0xDE, 0x77, 0x20, 0xD9, 0x6C, 0xE3, 0x22, 0x06, 0xAE, 0xBB /* 6.2.0 Device Master Kek Source. */
.byte 0x86, 0x61, 0xB0, 0x16, 0xFA, 0x7A, 0x9A, 0xEA, 0xF6, 0xF5, 0xBE, 0x1A, 0x13, 0x5B, 0x6D, 0x9E /* 7.0.0 Device Master Kek Source. */ .byte 0x86, 0x61, 0xB0, 0x16, 0xFA, 0x7A, 0x9A, 0xEA, 0xF6, 0xF5, 0xBE, 0x1A, 0x13, 0x5B, 0x6D, 0x9E /* 7.0.0 Device Master Kek Source. */
.byte 0xA6, 0x81, 0x71, 0xE7, 0xB5, 0x23, 0x74, 0xB0, 0x39, 0x8C, 0xB7, 0xFF, 0xA0, 0x62, 0x9F, 0x8D /* 8.1.0 Device Master Kek Source. */ .byte 0xA6, 0x81, 0x71, 0xE7, 0xB5, 0x23, 0x74, 0xB0, 0x39, 0x8C, 0xB7, 0xFF, 0xA0, 0x62, 0x9F, 0x8D /* 8.1.0 Device Master Kek Source. */
.byte 0x03, 0xE7, 0xEB, 0x43, 0x1B, 0xCF, 0x5F, 0xB5, 0xED, 0xDC, 0x97, 0xAE, 0x21, 0x8D, 0x19, 0xED /* 9.0.0 Device Master Kek Source. */ .byte 0x03, 0xE7, 0xEB, 0x43, 0x1B, 0xCF, 0x5F, 0xB5, 0xED, 0xDC, 0x97, 0xAE, 0x21, 0x8D, 0x19, 0xED /* 9.0.0 Device Master Kek Source. */
.byte 0xCE, 0xFE, 0x41, 0x0F, 0x46, 0x9A, 0x30, 0xD6, 0xF2, 0xE9, 0x0C, 0x6B, 0xB7, 0x15, 0x91, 0x36 /* 9.1.0 Device Master Kek Source. */ .byte 0xCE, 0xFE, 0x41, 0x0F, 0x46, 0x9A, 0x30, 0xD6, 0xF2, 0xE9, 0x0C, 0x6B, 0xB7, 0x15, 0x91, 0x36 /* 9.1.0 Device Master Kek Source. */
.byte 0xC2, 0x65, 0x34, 0x6E, 0xC7, 0xC6, 0x5D, 0x97, 0x3E, 0x34, 0x5C, 0x6B, 0xB3, 0x7E, 0xC6, 0xE3 /* 12.1.0 Device Master Kek Source. */

View File

@@ -94,7 +94,7 @@ namespace ams::secmon::boot {
} }
/* Check that the key generation is one that we can use. */ /* Check that the key generation is one that we can use. */
static_assert(pkg1::KeyGeneration_Count == 11); static_assert(pkg1::KeyGeneration_Count == 12);
if (key_generation >= pkg1::KeyGeneration_Count) { if (key_generation >= pkg1::KeyGeneration_Count) {
return false; return false;
} }

View File

@@ -47,9 +47,9 @@ namespace ams::secmon::smc {
[fuse::DramId_IcosaSamsung4GB] = pkg1::MemorySize_4GB, [fuse::DramId_IcosaSamsung4GB] = pkg1::MemorySize_4GB,
[fuse::DramId_IcosaHynix4GB] = pkg1::MemorySize_4GB, [fuse::DramId_IcosaHynix4GB] = pkg1::MemorySize_4GB,
[fuse::DramId_IcosaMicron4GB] = pkg1::MemorySize_4GB, [fuse::DramId_IcosaMicron4GB] = pkg1::MemorySize_4GB,
[fuse::DramId_AulaHynix1y4GB] = pkg1::MemorySize_4GB, [fuse::DramId_IowaHynix1y4GB] = pkg1::MemorySize_4GB,
[fuse::DramId_IcosaSamsung6GB] = pkg1::MemorySize_6GB, [fuse::DramId_IcosaSamsung6GB] = pkg1::MemorySize_6GB,
[fuse::DramId_CopperHynix4GB] = pkg1::MemorySize_4GB, [fuse::DramId_HoagHynix1y4GB] = pkg1::MemorySize_4GB,
[fuse::DramId_CopperMicron4GB] = pkg1::MemorySize_4GB, [fuse::DramId_CopperMicron4GB] = pkg1::MemorySize_4GB,
[fuse::DramId_IowaX1X2Samsung4GB] = pkg1::MemorySize_4GB, [fuse::DramId_IowaX1X2Samsung4GB] = pkg1::MemorySize_4GB,
[fuse::DramId_IowaSansung4GB] = pkg1::MemorySize_4GB, [fuse::DramId_IowaSansung4GB] = pkg1::MemorySize_4GB,
@@ -286,6 +286,10 @@ namespace ams::secmon::smc {
/* Get the log configuration. */ /* Get the log configuration. */
args.r[1] = (static_cast<u64>(static_cast<u8>(secmon::GetLogPort())) << 32) | static_cast<u64>(secmon::GetLogBaudRate()); args.r[1] = (static_cast<u64>(static_cast<u8>(secmon::GetLogPort())) << 32) | static_cast<u64>(secmon::GetLogBaudRate());
break; break;
case ConfigItem::ExosphereForceEnableUsb30:
/* Get whether usb 3.0 should be force-enabled. */
args.r[1] = GetSecmonConfiguration().IsUsb30ForceEnabled();
break;
default: default:
return SmcResult::InvalidArgument; return SmcResult::InvalidArgument;
} }

View File

@@ -50,6 +50,7 @@ namespace ams::secmon::smc {
ExosphereEmummcType = 65007, ExosphereEmummcType = 65007,
ExospherePayloadAddress = 65008, ExospherePayloadAddress = 65008,
ExosphereLogConfiguration = 65009, ExosphereLogConfiguration = 65009,
ExosphereForceEnableUsb30 = 65010,
}; };
SmcResult SmcGetConfigUser(SmcArguments &args); SmcResult SmcGetConfigUser(SmcArguments &args);

View File

@@ -1,7 +1,4 @@
%rename link old_link %rename link old_link
*link: *link:
%(old_link) -T %:getenv(TOPDIR /sdmmc_test.ld) --gc-sections --nmagic -nostdlib -nostartfiles %(old_link) -T %:getenv(TOPDIR /sdmmc_test.ld) --gc-sections --nmagic
*startfile:
crti%O%s crtbegin%O%s

View File

@@ -36,7 +36,6 @@ namespace ams::warmboot {
void Main(const Metadata *metadata) { void Main(const Metadata *metadata) {
/* Ensure that we're running under vaguely sane conditions. */ /* Ensure that we're running under vaguely sane conditions. */
AMS_ABORT_UNLESS(metadata->magic == Metadata::Magic); AMS_ABORT_UNLESS(metadata->magic == Metadata::Magic);
AMS_ABORT_UNLESS(metadata->target_firmware <= ams::TargetFirmware_Max);
/* Restrict the bpmp's access to dram. */ /* Restrict the bpmp's access to dram. */
if (metadata->target_firmware >= TargetFirmware_4_0_0) { if (metadata->target_firmware >= TargetFirmware_4_0_0) {

View File

@@ -1,7 +1,4 @@
%rename link old_link %rename link old_link
*link: *link:
%(old_link) -T %:getenv(TOPDIR /warmboot.ld) --gc-sections --nmagic -nostdlib -nostartfiles %(old_link) -T %:getenv(TOPDIR /warmboot.ld) --gc-sections --nmagic
*startfile:
crti%O%s crtbegin%O%s

View File

@@ -39,6 +39,7 @@ DEFINES := -D__BPMP__ -DFUSEE_MTC_SRC -DATMOSPHERE_GIT_BRANCH=\"$(AMSBRANCH)\" -
CFLAGS := \ CFLAGS := \
-g \ -g \
-gdwarf-4 \
-O2 \ -O2 \
-fomit-frame-pointer \ -fomit-frame-pointer \
-ffunction-sections \ -ffunction-sections \
@@ -46,6 +47,9 @@ CFLAGS := \
-std=gnu11 \ -std=gnu11 \
-Werror \ -Werror \
-Wall \ -Wall \
-Wno-array-bounds \
-Wno-stringop-overflow \
-Wno-stringop-overread \
-fstrict-volatile-bitfields \ -fstrict-volatile-bitfields \
$(ARCH) $(DEFINES) $(ARCH) $(DEFINES)
@@ -53,8 +57,8 @@ CFLAGS += $(INCLUDE)
CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++11 CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++11
ASFLAGS := -g $(ARCH) ASFLAGS := -g -gdwarf-4 $(ARCH)
LDFLAGS = -specs=$(TOPDIR)/linker.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map) LDFLAGS = -specs=$(TOPDIR)/linker.specs -g -gdwarf-4 $(ARCH) -Wl,-Map,$(notdir $*.map)
LIBS := LIBS :=

View File

@@ -46,6 +46,7 @@ DEFINES := -D__BPMP__ -DFUSEE_STAGE1_SRC -DATMOSPHERE_GIT_BRANCH=\"$(AMSBRANCH)\
CFLAGS := \ CFLAGS := \
-g \ -g \
-gdwarf-4 \
-O2 \ -O2 \
-fomit-frame-pointer \ -fomit-frame-pointer \
-ffunction-sections \ -ffunction-sections \
@@ -53,6 +54,9 @@ CFLAGS := \
-std=gnu11 \ -std=gnu11 \
-Werror \ -Werror \
-Wall \ -Wall \
-Wno-array-bounds \
-Wno-stringop-overflow \
-Wno-stringop-overread \
-fstrict-volatile-bitfields \ -fstrict-volatile-bitfields \
$(ARCH) $(DEFINES) $(ARCH) $(DEFINES)
@@ -60,8 +64,8 @@ CFLAGS += $(INCLUDE)
CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++11 CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++11
ASFLAGS := -g $(ARCH) ASFLAGS := -g -gdwarf-4 $(ARCH)
LDFLAGS = -specs=$(TOPDIR)/linker.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map) LDFLAGS = -specs=$(TOPDIR)/linker.specs -g -gdwarf-4 $(ARCH) -Wl,-Map,$(notdir $*.map)
LIBS := LIBS :=

View File

@@ -39,6 +39,7 @@ DEFINES := -D__BPMP__ -DFUSEE_STAGE1_SRC -DATMOSPHERE_GIT_BRANCH=\"$(AMSBRANCH)\
CFLAGS := \ CFLAGS := \
-g \ -g \
-gdwarf-4 \
-O2 \ -O2 \
-fomit-frame-pointer \ -fomit-frame-pointer \
-ffunction-sections \ -ffunction-sections \
@@ -46,6 +47,9 @@ CFLAGS := \
-std=gnu11 \ -std=gnu11 \
-Werror \ -Werror \
-Wall \ -Wall \
-Wno-array-bounds \
-Wno-stringop-overflow \
-Wno-stringop-overread \
-fstrict-volatile-bitfields \ -fstrict-volatile-bitfields \
$(ARCH) $(DEFINES) $(ARCH) $(DEFINES)
@@ -53,8 +57,8 @@ CFLAGS += $(INCLUDE)
CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++11 CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++11
ASFLAGS := -g $(ARCH) ASFLAGS := -g -gdwarf-4 $(ARCH)
LDFLAGS = -specs=$(TOPDIR)/linker.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map) LDFLAGS = -specs=$(TOPDIR)/linker.specs -g -gdwarf-4 $(ARCH) -Wl,-Map,$(notdir $*.map)
LIBS := LIBS :=

View File

@@ -48,6 +48,7 @@ DEFINES := -D__BPMP__ -DFUSEE_STAGE2_SRC -DATMOSPHERE_GIT_BRANCH=\"$(AMSBRANCH)\
CFLAGS := \ CFLAGS := \
-g \ -g \
-gdwarf-4 \
-O2 \ -O2 \
-fomit-frame-pointer \ -fomit-frame-pointer \
-ffunction-sections \ -ffunction-sections \
@@ -55,6 +56,9 @@ CFLAGS := \
-std=gnu11 \ -std=gnu11 \
-Werror \ -Werror \
-Wall \ -Wall \
-Wno-array-bounds \
-Wno-stringop-overflow \
-Wno-stringop-overread \
-fstrict-volatile-bitfields \ -fstrict-volatile-bitfields \
$(ARCH) $(DEFINES) $(ARCH) $(DEFINES)
@@ -62,8 +66,8 @@ CFLAGS += $(INCLUDE)
CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++11 CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++11
ASFLAGS := -g $(ARCH) $(INCLUDE) $(DEFINES) ASFLAGS := -g -gdwarf-4 $(ARCH) $(INCLUDE) $(DEFINES)
LDFLAGS = -specs=$(TOPDIR)/linker.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map) LDFLAGS = -specs=$(TOPDIR)/linker.specs -g -gdwarf-4 $(ARCH) -Wl,-Map,$(notdir $*.map)
LIBS := LIBS :=

View File

@@ -91,6 +91,12 @@ typedef enum {
FS_VER_11_0_0, FS_VER_11_0_0,
FS_VER_11_0_0_EXFAT, FS_VER_11_0_0_EXFAT,
FS_VER_12_0_0,
FS_VER_12_0_0_EXFAT,
FS_VER_12_0_3,
FS_VER_12_0_3_EXFAT,
FS_VER_MAX, FS_VER_MAX,
} emummc_fs_ver_t; } emummc_fs_ver_t;

View File

@@ -33,6 +33,7 @@
#define EXOSPHERE_FLAG_ENABLE_USERMODE_PMU_ACCESS (1 << 4u) #define EXOSPHERE_FLAG_ENABLE_USERMODE_PMU_ACCESS (1 << 4u)
#define EXOSPHERE_FLAG_BLANK_PRODINFO (1 << 5u) #define EXOSPHERE_FLAG_BLANK_PRODINFO (1 << 5u)
#define EXOSPHERE_FLAG_ALLOW_WRITING_TO_CAL_SYSMMC (1 << 6u) #define EXOSPHERE_FLAG_ALLOW_WRITING_TO_CAL_SYSMMC (1 << 6u)
#define EXOSPHERE_FLAG_FORCE_ENABLE_USB_30 (1 << 7u)
#define EXOSPHERE_LOG_FLAG_INVERTED (1 << 0u) #define EXOSPHERE_LOG_FLAG_INVERTED (1 << 0u)

View File

@@ -348,6 +348,7 @@ uint32_t fuse_get_regulator(void) {
static const uint32_t fuse_version_increment_firmwares[] = { static const uint32_t fuse_version_increment_firmwares[] = {
ATMOSPHERE_TARGET_FIRMWARE_12_0_2,
ATMOSPHERE_TARGET_FIRMWARE_11_0_0, ATMOSPHERE_TARGET_FIRMWARE_11_0_0,
ATMOSPHERE_TARGET_FIRMWARE_10_0_0, ATMOSPHERE_TARGET_FIRMWARE_10_0_0,
ATMOSPHERE_TARGET_FIRMWARE_9_1_0, ATMOSPHERE_TARGET_FIRMWARE_9_1_0,

View File

@@ -426,6 +426,12 @@ static const uint8_t g_fs_hashes[FS_VER_MAX][0x8] = {
"\xE3\x99\x15\x6E\x84\x4E\xB0\xAA", /* FS_VER_11_0_0 */ "\xE3\x99\x15\x6E\x84\x4E\xB0\xAA", /* FS_VER_11_0_0 */
"\x0B\xA1\x5B\xB3\x04\xB5\x05\x63", /* FS_VER_11_0_0_EXFAT */ "\x0B\xA1\x5B\xB3\x04\xB5\x05\x63", /* FS_VER_11_0_0_EXFAT */
"\xDC\x2A\x08\x49\x96\xBB\x3C\x01", /* FS_VER_12_0_0 */
"\xD5\xA5\xBF\x36\x64\x0C\x49\xEA", /* FS_VER_12_0_0_EXFAT */
"\xC8\x67\x62\xBE\x19\xA5\x1F\xA0", /* FS_VER_12_0_3 */
"\xE1\xE8\xD3\xD6\xA2\xFE\x0B\x10", /* FS_VER_12_0_3_EXFAT */
}; };
kip1_header_t *apply_kip_ips_patches(kip1_header_t *kip, size_t kip_size, emummc_fs_ver_t *out_fs_ver) { kip1_header_t *apply_kip_ips_patches(kip1_header_t *kip, size_t kip_size, emummc_fs_ver_t *out_fs_ver) {

View File

@@ -568,6 +568,7 @@ static const instruction_t MAKE_KERNEL_PATCH_NAME(1000, proc_id_recv)[] = {0xA9B
*/ */
static const uint8_t MAKE_KERNEL_PATTERN_NAME(1100, proc_id_send)[] = {0xE0, 0x03, 0x15, 0xAA, 0xA8, 0x02, 0x40, 0xF9, 0x08, 0x1D, 0x40, 0xF9, 0x00, 0x01, 0x3F, 0xD6, 0x88, 0x4A, 0x3C, 0x8B, 0x09, 0xFC, 0x60, 0xD3, 0x00, 0x25, 0x00, 0x29}; static const uint8_t MAKE_KERNEL_PATTERN_NAME(1100, proc_id_send)[] = {0xE0, 0x03, 0x15, 0xAA, 0xA8, 0x02, 0x40, 0xF9, 0x08, 0x1D, 0x40, 0xF9, 0x00, 0x01, 0x3F, 0xD6, 0x88, 0x4A, 0x3C, 0x8B, 0x09, 0xFC, 0x60, 0xD3, 0x00, 0x25, 0x00, 0x29};
static const instruction_t MAKE_KERNEL_PATCH_NAME(1100, proc_id_send)[] = {0xA9BF2FEA, 0xF94043EB, 0x5280006A, 0xD37EF54A, 0xF86A696A, 0x92FFFFE9, 0x8A090148, 0xD2FFFFE9, 0x8A09014A, 0xD2FFFFC9, 0xEB09015F, 0x54000100, 0xA9BF27E8, 0xF94002A8, 0xF9401D08, 0xAA1503E0, 0xD63F0100, 0xA8C127E8, 0xAA0003E8, 0xA8C12FEA, 0xAA0803E0}; static const instruction_t MAKE_KERNEL_PATCH_NAME(1100, proc_id_send)[] = {0xA9BF2FEA, 0xF94043EB, 0x5280006A, 0xD37EF54A, 0xF86A696A, 0x92FFFFE9, 0x8A090148, 0xD2FFFFE9, 0x8A09014A, 0xD2FFFFC9, 0xEB09015F, 0x54000100, 0xA9BF27E8, 0xF94002A8, 0xF9401D08, 0xAA1503E0, 0xD63F0100, 0xA8C127E8, 0xAA0003E8, 0xA8C12FEA, 0xAA0803E0};
/* /*
stp x10, x11, [sp, #-0x10]! stp x10, x11, [sp, #-0x10]!
ldr x11, [sp, #0xE0] ldr x11, [sp, #0xE0]
@@ -596,6 +597,63 @@ static const instruction_t MAKE_KERNEL_PATCH_NAME(1100, proc_id_send)[] = {0xA9B
static const uint8_t MAKE_KERNEL_PATTERN_NAME(1100, proc_id_recv)[] = {0x08, 0x03, 0x40, 0xF9, 0xE0, 0x03, 0x18, 0xAA, 0x08, 0x1D, 0x40, 0xF9, 0x00, 0x01, 0x3F, 0xD6, 0xE8, 0x7F, 0x40, 0xF9, 0x09, 0xFC, 0x60, 0xD3, 0xEA, 0x5B, 0x40, 0xF9}; static const uint8_t MAKE_KERNEL_PATTERN_NAME(1100, proc_id_recv)[] = {0x08, 0x03, 0x40, 0xF9, 0xE0, 0x03, 0x18, 0xAA, 0x08, 0x1D, 0x40, 0xF9, 0x00, 0x01, 0x3F, 0xD6, 0xE8, 0x7F, 0x40, 0xF9, 0x09, 0xFC, 0x60, 0xD3, 0xEA, 0x5B, 0x40, 0xF9};
static const instruction_t MAKE_KERNEL_PATCH_NAME(1100, proc_id_recv)[] = {0xA9BF2FEA, 0xF94073EB, 0x5280006A, 0xD37EF54A, 0xF86A696A, 0x92FFFFE9, 0x8A090148, 0xD2FFFFE9, 0x8A09014A, 0xD2FFFFC9, 0xEB09015F, 0x54000100, 0xA9BF27E8, 0xF9400308, 0xF9401D08, 0xAA1803E0, 0xD63F0100, 0xA8C127E8, 0xAA0003E8, 0xA8C12FEA, 0xAA0803E0}; static const instruction_t MAKE_KERNEL_PATCH_NAME(1100, proc_id_recv)[] = {0xA9BF2FEA, 0xF94073EB, 0x5280006A, 0xD37EF54A, 0xF86A696A, 0x92FFFFE9, 0x8A090148, 0xD2FFFFE9, 0x8A09014A, 0xD2FFFFC9, 0xEB09015F, 0x54000100, 0xA9BF27E8, 0xF9400308, 0xF9401D08, 0xAA1803E0, 0xD63F0100, 0xA8C127E8, 0xAA0003E8, 0xA8C12FEA, 0xAA0803E0};
/*
stp x10, x11, [sp, #-0x10]!
ldr x11, [sp, #0x98]
mov w10, #3
lsl x10, x10, #2
ldr x10, [x11, x10]
mov x9, #0x0000ffffffffffff
and x8, x10, x9
mov x9, #0xffff000000000000
and x10, x10, x9
mov x9, #0xfffe000000000000
cmp x10, x9
beq #0x20
stp x8, x9, [sp, #-0x10]!
ldr x8, [x22]
ldr x8, [x8, #0x38]
mov x0, x22
blr x8
ldp x8, x9, [sp],#0x10
mov x8, x0
ldp x10, x11, [sp],#0x10
mov x0, x8
*/
static const uint8_t MAKE_KERNEL_PATTERN_NAME(1200, proc_id_send)[] = {0xE0, 0x03, 0x16, 0xAA, 0xC8, 0x02, 0x40, 0xF9, 0x08, 0x1D, 0x40, 0xF9, 0x00, 0x01, 0x3F, 0xD6, 0xA8, 0x4A, 0x3B, 0x8B, 0x09, 0xFC, 0x60, 0xD3, 0x00, 0x25, 0x00, 0x29};
static const instruction_t MAKE_KERNEL_PATCH_NAME(1200, proc_id_send)[] = {0xA9BF2FEA, 0xF9404FEB, 0x5280006A, 0xD37EF54A, 0xF86A696A, 0x92FFFFE9, 0x8A090148, 0xD2FFFFE9, 0x8A09014A, 0xD2FFFFC9, 0xEB09015F, 0x54000100, 0xA9BF27E8, 0xF94002C8, 0xF9401D08, 0xAA1603E0, 0xD63F0100, 0xA8C127E8, 0xAA0003E8, 0xA8C12FEA, 0xAA0803E0};
/*
stp x10, x11, [sp, #-0x10]!
ldr x11, [sp, #0xE0]
mov w10, #3
lsl x10, x10, #2
ldr x10, [x11, x10]
mov x9, #0x0000ffffffffffff
and x8, x10, x9
mov x9, #0xffff000000000000
and x10, x10, x9
mov x9, #0xfffe000000000000
cmp x10, x9
beq #0x20
stp x8, x9, [sp, #-0x10]!
ldr x8, [x28]
ldr x8, [x8, #0x38]
mov x0, x28
blr x8
ldp x8, x9, [sp],#0x10
mov x8, x0
ldp x10, x11, [sp],#0x10
mov x0, x8
*/
static const uint8_t MAKE_KERNEL_PATTERN_NAME(1200, proc_id_recv)[] = {0x88, 0x03, 0x40, 0xF9, 0xE0, 0x03, 0x1C, 0xAA, 0x08, 0x1D, 0x40, 0xF9, 0x00, 0x01, 0x3F, 0xD6, 0x08, 0x4B, 0x3A, 0x8B, 0x09, 0xFC, 0x60, 0xD3, 0x00, 0x25, 0x00, 0x29};
static const instruction_t MAKE_KERNEL_PATCH_NAME(1200, proc_id_recv)[] = {0xA9BF2FEA, 0xF94073EB, 0x5280006A, 0xD37EF54A, 0xF86A696A, 0x92FFFFE9, 0x8A090148, 0xD2FFFFE9, 0x8A09014A, 0xD2FFFFC9, 0xEB09015F, 0x54000100, 0xA9BF27E8, 0xF9400388, 0xF9401D08, 0xAA1C03E0, 0xD63F0100, 0xA8C127E8, 0xAA0003E8, 0xA8C12FEA, 0xAA0803E0};
/* svcControlCodeMemory Patches */ /* svcControlCodeMemory Patches */
/* b.eq -> nop */ /* b.eq -> nop */
static const instruction_t MAKE_KERNEL_PATCH_NAME(500, svc_control_codememory)[] = {MAKE_NOP}; static const instruction_t MAKE_KERNEL_PATCH_NAME(500, svc_control_codememory)[] = {MAKE_NOP};
@@ -605,6 +663,7 @@ static const instruction_t MAKE_KERNEL_PATCH_NAME(800, svc_control_codememory)[
static const instruction_t MAKE_KERNEL_PATCH_NAME(900, svc_control_codememory)[] = {MAKE_NOP}; static const instruction_t MAKE_KERNEL_PATCH_NAME(900, svc_control_codememory)[] = {MAKE_NOP};
static const instruction_t MAKE_KERNEL_PATCH_NAME(1000, svc_control_codememory)[] = {MAKE_NOP}; static const instruction_t MAKE_KERNEL_PATCH_NAME(1000, svc_control_codememory)[] = {MAKE_NOP};
static const instruction_t MAKE_KERNEL_PATCH_NAME(1100, svc_control_codememory)[] = {MAKE_NOP}; static const instruction_t MAKE_KERNEL_PATCH_NAME(1100, svc_control_codememory)[] = {MAKE_NOP};
static const instruction_t MAKE_KERNEL_PATCH_NAME(1200, svc_control_codememory)[] = {MAKE_NOP};
static const instruction_t MAKE_KERNEL_PATCH_NAME(500, system_memory_increase)[] = {0x52A3C008}; /* MOV W8, #0x1E000000 */ static const instruction_t MAKE_KERNEL_PATCH_NAME(500, system_memory_increase)[] = {0x52A3C008}; /* MOV W8, #0x1E000000 */
static const instruction_t MAKE_KERNEL_PATCH_NAME(600, system_memory_increase)[] = {0x52A3B008}; /* MOV W8, #0x1D800000 */ static const instruction_t MAKE_KERNEL_PATCH_NAME(600, system_memory_increase)[] = {0x52A3B008}; /* MOV W8, #0x1D800000 */
@@ -613,6 +672,7 @@ static const instruction_t MAKE_KERNEL_PATCH_NAME(800, system_memory_increase)[
static const instruction_t MAKE_KERNEL_PATCH_NAME(900, system_memory_increase)[] = {0x52A3B013}; /* MOV W19, #0x1D800000 */ static const instruction_t MAKE_KERNEL_PATCH_NAME(900, system_memory_increase)[] = {0x52A3B013}; /* MOV W19, #0x1D800000 */
static const instruction_t MAKE_KERNEL_PATCH_NAME(1000, system_memory_increase)[] = {0x52A3B013}; /* MOV W19, #0x1D800000 */ static const instruction_t MAKE_KERNEL_PATCH_NAME(1000, system_memory_increase)[] = {0x52A3B013}; /* MOV W19, #0x1D800000 */
static const instruction_t MAKE_KERNEL_PATCH_NAME(1100, system_memory_increase)[] = {0x52A3B015}; /* MOV W21, #0x1D800000 */ static const instruction_t MAKE_KERNEL_PATCH_NAME(1100, system_memory_increase)[] = {0x52A3B015}; /* MOV W21, #0x1D800000 */
static const instruction_t MAKE_KERNEL_PATCH_NAME(1200, system_memory_increase)[] = {0x52A3B015}; /* MOV W21, #0x1D800000 */
/* Hook Definitions. */ /* Hook Definitions. */
static const kernel_patch_t g_kernel_patches_100[] = { static const kernel_patch_t g_kernel_patches_100[] = {
@@ -935,6 +995,35 @@ static const kernel_patch_t g_kernel_patches_1101[] = {
} }
}; };
static const kernel_patch_t g_kernel_patches_1200[] = {
{ /* Send Message Process ID Patch. */
.pattern_size = 0x1C,
.pattern = MAKE_KERNEL_PATTERN_NAME(1200, proc_id_send),
.pattern_hook_offset = 0x0,
.payload_num_instructions = sizeof(MAKE_KERNEL_PATCH_NAME(1200, proc_id_send))/sizeof(instruction_t),
.branch_back_offset = 0x10,
.payload = MAKE_KERNEL_PATCH_NAME(1200, proc_id_send)
},
{ /* Receive Message Process ID Patch. */
.pattern_size = 0x1C,
.pattern = MAKE_KERNEL_PATTERN_NAME(1200, proc_id_recv),
.pattern_hook_offset = 0x0,
.payload_num_instructions = sizeof(MAKE_KERNEL_PATCH_NAME(1200, proc_id_recv))/sizeof(instruction_t),
.branch_back_offset = 0x10,
.payload = MAKE_KERNEL_PATCH_NAME(1200, proc_id_recv)
},
{ /* svcControlCodeMemory Patch. */
.payload_num_instructions = sizeof(MAKE_KERNEL_PATCH_NAME(1200, svc_control_codememory))/sizeof(instruction_t),
.payload = MAKE_KERNEL_PATCH_NAME(1200, svc_control_codememory),
.patch_offset = 0x2FCB4,
},
{ /* System Memory Increase Patch. */
.payload_num_instructions = sizeof(MAKE_KERNEL_PATCH_NAME(1200, system_memory_increase))/sizeof(instruction_t),
.payload = MAKE_KERNEL_PATCH_NAME(1200, system_memory_increase),
.patch_offset = 0x4809C,
}
};
#define KERNEL_PATCHES(vers) .num_patches = sizeof(g_kernel_patches_##vers)/sizeof(kernel_patch_t), .patches = g_kernel_patches_##vers, #define KERNEL_PATCHES(vers) .num_patches = sizeof(g_kernel_patches_##vers)/sizeof(kernel_patch_t), .patches = g_kernel_patches_##vers,
/* Kernel Infos. */ /* Kernel Infos. */
@@ -1038,6 +1127,15 @@ static const kernel_info_t g_kernel_infos[] = {
.embedded_ini_ptr = 0x180, .embedded_ini_ptr = 0x180,
.free_code_space_offset = 0x49EE8, .free_code_space_offset = 0x49EE8,
KERNEL_PATCHES(1101) KERNEL_PATCHES(1101)
},
{ /* 12.0.0. */
.hash = {0x8D, 0x4A, 0x1E, 0xFC, 0xCC, 0x6C, 0xFE, 0x6C, 0x45, 0x14, 0x13, 0xA1, 0x7F, 0xF6, 0xDF, 0xFD, 0x7E, 0x5D, 0xD1, 0x38, 0xCE, 0x86, 0x11, 0x8B, 0x58, 0x5F, 0x89, 0x67, 0x84, 0x48, 0xA8, 0x17, },
.hash_offset = 0x1C4,
.hash_size = 0x68000 - 0x1C4,
.embedded_ini_offset = 0x68000,
.embedded_ini_ptr = 0x180,
.free_code_space_offset = 0x48810,
KERNEL_PATCHES(1200)
} }
}; };

View File

@@ -62,7 +62,7 @@ static const uint8_t AL16 new_master_kek_seeds[MASTERKEY_REVISION_700_800 - MAST
}; };
static const uint8_t AL16 master_kek_seed_mariko[0x10] = { /* TODO: Update on next change of keys. */ static const uint8_t AL16 master_kek_seed_mariko[0x10] = { /* TODO: Update on next change of keys. */
0x0E, 0x44, 0x0C, 0xED, 0xB4, 0x36, 0xC0, 0x3F, 0xAA, 0x1D, 0xAE, 0xBF, 0x62, 0xB1, 0x09, 0x82, /* Mariko MasterKek seed 0A. */ 0xE5, 0x41, 0xAC, 0xEC, 0xD1, 0xA7, 0xD1, 0xAB, 0xED, 0x03, 0x77, 0xF1, 0x27, 0xCA, 0xF8, 0xF1, /* Mariko MasterKek seed 0B. */
}; };
static nx_dec_keyblob_t AL16 g_dec_keyblobs[32]; static nx_dec_keyblob_t AL16 g_dec_keyblobs[32];
@@ -153,7 +153,7 @@ int derive_nx_keydata_erista(uint32_t target_firmware, const nx_keyblob_t *keybl
if (target_firmware >= ATMOSPHERE_TARGET_FIRMWARE_8_1_0) { if (target_firmware >= ATMOSPHERE_TARGET_FIRMWARE_8_1_0) {
/* NOTE: We load in the current key for all >= 8.1.0 firmwares to reduce sept binaries. */ /* NOTE: We load in the current key for all >= 8.1.0 firmwares to reduce sept binaries. */
desired_keyblob = MASTERKEY_REVISION_910_CURRENT; desired_keyblob = MASTERKEY_REVISION_C10_CURRENT;
} else if (target_firmware >= ATMOSPHERE_TARGET_FIRMWARE_7_0_0) { } else if (target_firmware >= ATMOSPHERE_TARGET_FIRMWARE_7_0_0) {
desired_keyblob = MASTERKEY_REVISION_700_800; desired_keyblob = MASTERKEY_REVISION_700_800;
} else { } else {

View File

@@ -44,6 +44,7 @@ static const uint8_t mkey_vectors_dev[MASTERKEY_REVISION_MAX][0x10] = {
{0xEC, 0xE1, 0x46, 0x89, 0x37, 0xFD, 0xD2, 0x15, 0x8C, 0x3F, 0x24, 0x82, 0xEF, 0x49, 0x68, 0x04}, /* Master key 07 encrypted with Master key 08. */ {0xEC, 0xE1, 0x46, 0x89, 0x37, 0xFD, 0xD2, 0x15, 0x8C, 0x3F, 0x24, 0x82, 0xEF, 0x49, 0x68, 0x04}, /* Master key 07 encrypted with Master key 08. */
{0x43, 0x3D, 0xC5, 0x3B, 0xEF, 0x91, 0x02, 0x21, 0x61, 0x54, 0x63, 0x8A, 0x35, 0xE7, 0xCA, 0xEE}, /* Master key 08 encrypted with Master key 09. */ {0x43, 0x3D, 0xC5, 0x3B, 0xEF, 0x91, 0x02, 0x21, 0x61, 0x54, 0x63, 0x8A, 0x35, 0xE7, 0xCA, 0xEE}, /* Master key 08 encrypted with Master key 09. */
{0x6C, 0x2E, 0xCD, 0xB3, 0x34, 0x61, 0x77, 0xF5, 0xF9, 0xB1, 0xDD, 0x61, 0x98, 0x19, 0x3E, 0xD4}, /* Master key 09 encrypted with Master key 0A. */ {0x6C, 0x2E, 0xCD, 0xB3, 0x34, 0x61, 0x77, 0xF5, 0xF9, 0xB1, 0xDD, 0x61, 0x98, 0x19, 0x3E, 0xD4}, /* Master key 09 encrypted with Master key 0A. */
{0x21, 0x88, 0x6B, 0x10, 0x9E, 0x83, 0xD6, 0x52, 0xAB, 0x08, 0xDB, 0x6D, 0x39, 0xFF, 0x1C, 0x9C}, /* Master key 0A encrypted with Master key 0B. */
}; };
/* Retail unit keys. */ /* Retail unit keys. */
@@ -59,17 +60,19 @@ static const uint8_t mkey_vectors[MASTERKEY_REVISION_MAX][0x10] = {
{0xEA, 0x60, 0xB3, 0xEA, 0xCE, 0x8F, 0x24, 0x46, 0x7D, 0x33, 0x9C, 0xD1, 0xBC, 0x24, 0x98, 0x29}, /* Master key 07 encrypted with Master key 08. */ {0xEA, 0x60, 0xB3, 0xEA, 0xCE, 0x8F, 0x24, 0x46, 0x7D, 0x33, 0x9C, 0xD1, 0xBC, 0x24, 0x98, 0x29}, /* Master key 07 encrypted with Master key 08. */
{0x4D, 0xD9, 0x98, 0x42, 0x45, 0x0D, 0xB1, 0x3C, 0x52, 0x0C, 0x9A, 0x44, 0xBB, 0xAD, 0xAF, 0x80}, /* Master key 08 encrypted with Master key 09. */ {0x4D, 0xD9, 0x98, 0x42, 0x45, 0x0D, 0xB1, 0x3C, 0x52, 0x0C, 0x9A, 0x44, 0xBB, 0xAD, 0xAF, 0x80}, /* Master key 08 encrypted with Master key 09. */
{0xB8, 0x96, 0x9E, 0x4A, 0x00, 0x0D, 0xD6, 0x28, 0xB3, 0xD1, 0xDB, 0x68, 0x5F, 0xFB, 0xE1, 0x2A}, /* Master key 09 encrypted with Master key 0A. */ {0xB8, 0x96, 0x9E, 0x4A, 0x00, 0x0D, 0xD6, 0x28, 0xB3, 0xD1, 0xDB, 0x68, 0x5F, 0xFB, 0xE1, 0x2A}, /* Master key 09 encrypted with Master key 0A. */
{0xC1, 0x8D, 0x16, 0xBB, 0x2A, 0xE4, 0x1D, 0xD4, 0xC2, 0xC1, 0xB6, 0x40, 0x94, 0x35, 0x63, 0x98}, /* Master key 0A encrypted with Master key 0B. */
}; };
static const uint8_t new_device_key_sources[MASTERKEY_NUM_NEW_DEVICE_KEYS][0x10] = { static const uint8_t new_device_key_sources[MASTERKEY_NUM_NEW_DEVICE_KEYS][0x10] = {
{0x8B, 0x4E, 0x1C, 0x22, 0x42, 0x07, 0xC8, 0x73, 0x56, 0x94, 0x08, 0x8B, 0xCC, 0x47, 0x0F, 0x5D}, /* 4.x New Device Key Source. */ {0x8B, 0x4E, 0x1C, 0x22, 0x42, 0x07, 0xC8, 0x73, 0x56, 0x94, 0x08, 0x8B, 0xCC, 0x47, 0x0F, 0x5D}, /* 4.x New Device Key Source. */
{0x6C, 0xEF, 0xC6, 0x27, 0x8B, 0xEC, 0x8A, 0x91, 0x99, 0xAB, 0x24, 0xAC, 0x4F, 0x1C, 0x8F, 0x1C}, /* 5.x New Device Key Source. */ {0x6C, 0xEF, 0xC6, 0x27, 0x8B, 0xEC, 0x8A, 0x91, 0x99, 0xAB, 0x24, 0xAC, 0x4F, 0x1C, 0x8F, 0x1C}, /* 5.x New Device Key Source. */
{0x70, 0x08, 0x1B, 0x97, 0x44, 0x64, 0xF8, 0x91, 0x54, 0x9D, 0xC6, 0x84, 0x8F, 0x1A, 0xB2, 0xE4}, /* 6.x New Device Key Source. */ {0x70, 0x08, 0x1B, 0x97, 0x44, 0x64, 0xF8, 0x91, 0x54, 0x9D, 0xC6, 0x84, 0x8F, 0x1A, 0xB2, 0xE4}, /* 6.x New Device Key Source. */
{0x8E, 0x09, 0x1F, 0x7A, 0xBB, 0xCA, 0x6A, 0xFB, 0xB8, 0x9B, 0xD5, 0xC1, 0x25, 0x9C, 0xA9, 0x17}, /* 6.2.0 New Device Key Source. */ {0x8E, 0x09, 0x1F, 0x7A, 0xBB, 0xCA, 0x6A, 0xFB, 0xB8, 0x9B, 0xD5, 0xC1, 0x25, 0x9C, 0xA9, 0x17}, /* 6.2.0 New Device Key Source. */
{0x8F, 0x77, 0x5A, 0x96, 0xB0, 0x94, 0xFD, 0x8D, 0x28, 0xE4, 0x19, 0xC8, 0x16, 0x1C, 0xDB, 0x3D}, /* 7.0.0 New Device Key Source. */ {0x8F, 0x77, 0x5A, 0x96, 0xB0, 0x94, 0xFD, 0x8D, 0x28, 0xE4, 0x19, 0xC8, 0x16, 0x1C, 0xDB, 0x3D}, /* 7.0.0 New Device Key Source. */
{0x67, 0x62, 0xD4, 0x8E, 0x55, 0xCF, 0xFF, 0x41, 0x31, 0x15, 0x3B, 0x24, 0x0C, 0x7C, 0x07, 0xAE}, /* 8.1.0 New Device Key Source. */ {0x67, 0x62, 0xD4, 0x8E, 0x55, 0xCF, 0xFF, 0x41, 0x31, 0x15, 0x3B, 0x24, 0x0C, 0x7C, 0x07, 0xAE}, /* 8.1.0 New Device Key Source. */
{0x4A, 0xC3, 0x4E, 0x14, 0x8B, 0x96, 0x4A, 0xD5, 0xD4, 0x99, 0x73, 0xC4, 0x45, 0xAB, 0x8B, 0x49}, /* 9.0.0 New Device Key Source. */ {0x4A, 0xC3, 0x4E, 0x14, 0x8B, 0x96, 0x4A, 0xD5, 0xD4, 0x99, 0x73, 0xC4, 0x45, 0xAB, 0x8B, 0x49}, /* 9.0.0 New Device Key Source. */
{0x14, 0xB8, 0x74, 0x12, 0xCB, 0xBD, 0x0B, 0x8F, 0x20, 0xFB, 0x30, 0xDA, 0x27, 0xE4, 0x58, 0x94}, /* 9.1.0 New Device Key Source. */ {0x14, 0xB8, 0x74, 0x12, 0xCB, 0xBD, 0x0B, 0x8F, 0x20, 0xFB, 0x30, 0xDA, 0x27, 0xE4, 0x58, 0x94}, /* 9.1.0 New Device Key Source. */
{0xAA, 0xFD, 0xBC, 0xBB, 0x25, 0xC3, 0xA4, 0xEF, 0xE3, 0xEE, 0x58, 0x53, 0xB7, 0xF8, 0xDD, 0xD6}, /* 12.1.0 New Device Key Source. */
}; };
static const uint8_t new_device_keygen_sources[MASTERKEY_NUM_NEW_DEVICE_KEYS][0x10] = { static const uint8_t new_device_keygen_sources[MASTERKEY_NUM_NEW_DEVICE_KEYS][0x10] = {
@@ -80,7 +83,8 @@ static const uint8_t new_device_keygen_sources[MASTERKEY_NUM_NEW_DEVICE_KEYS][0x
{0x86, 0x61, 0xB0, 0x16, 0xFA, 0x7A, 0x9A, 0xEA, 0xF6, 0xF5, 0xBE, 0x1A, 0x13, 0x5B, 0x6D, 0x9E}, /* 7.0.0 New Device Keygen Source. */ {0x86, 0x61, 0xB0, 0x16, 0xFA, 0x7A, 0x9A, 0xEA, 0xF6, 0xF5, 0xBE, 0x1A, 0x13, 0x5B, 0x6D, 0x9E}, /* 7.0.0 New Device Keygen Source. */
{0xA6, 0x81, 0x71, 0xE7, 0xB5, 0x23, 0x74, 0xB0, 0x39, 0x8C, 0xB7, 0xFF, 0xA0, 0x62, 0x9F, 0x8D}, /* 8.1.0 New Device Keygen Source. */ {0xA6, 0x81, 0x71, 0xE7, 0xB5, 0x23, 0x74, 0xB0, 0x39, 0x8C, 0xB7, 0xFF, 0xA0, 0x62, 0x9F, 0x8D}, /* 8.1.0 New Device Keygen Source. */
{0x03, 0xE7, 0xEB, 0x43, 0x1B, 0xCF, 0x5F, 0xB5, 0xED, 0xDC, 0x97, 0xAE, 0x21, 0x8D, 0x19, 0xED}, /* 9.0.0 New Device Keygen Source. */ {0x03, 0xE7, 0xEB, 0x43, 0x1B, 0xCF, 0x5F, 0xB5, 0xED, 0xDC, 0x97, 0xAE, 0x21, 0x8D, 0x19, 0xED}, /* 9.0.0 New Device Keygen Source. */
{0xCE, 0xFE, 0x41, 0x0F, 0x46, 0x9A, 0x30, 0xD6, 0xF2, 0xE9, 0x0C, 0x6B, 0xB7, 0x15, 0x91, 0x36}, /* 9.1.0 New Device Keygen Source to be added on next change-of-keys. */ {0xCE, 0xFE, 0x41, 0x0F, 0x46, 0x9A, 0x30, 0xD6, 0xF2, 0xE9, 0x0C, 0x6B, 0xB7, 0x15, 0x91, 0x36}, /* 9.1.0 New Device Keygen Source. */
{0xC2, 0x65, 0x34, 0x6E, 0xC7, 0xC6, 0x5D, 0x97, 0x3E, 0x34, 0x5C, 0x6B, 0xB3, 0x7E, 0xC6, 0xE3}, /* 12.1.0 New Device Keygen Source. */
}; };
static const uint8_t new_device_keygen_sources_dev[MASTERKEY_NUM_NEW_DEVICE_KEYS][0x10] = { static const uint8_t new_device_keygen_sources_dev[MASTERKEY_NUM_NEW_DEVICE_KEYS][0x10] = {
@@ -91,7 +95,8 @@ static const uint8_t new_device_keygen_sources_dev[MASTERKEY_NUM_NEW_DEVICE_KEYS
{0x60, 0xAE, 0x56, 0x68, 0x11, 0xE2, 0x0C, 0x99, 0xDE, 0x05, 0xAE, 0x68, 0x78, 0x85, 0x04, 0xAE}, /* 7.0.0 New Device Keygen Source. */ {0x60, 0xAE, 0x56, 0x68, 0x11, 0xE2, 0x0C, 0x99, 0xDE, 0x05, 0xAE, 0x68, 0x78, 0x85, 0x04, 0xAE}, /* 7.0.0 New Device Keygen Source. */
{0x94, 0xD6, 0xA8, 0xC0, 0x95, 0xAF, 0xD0, 0xA6, 0x27, 0x53, 0x5E, 0xE5, 0x8E, 0x70, 0x1F, 0x87}, /* 8.1.0 New Device Keygen Source. */ {0x94, 0xD6, 0xA8, 0xC0, 0x95, 0xAF, 0xD0, 0xA6, 0x27, 0x53, 0x5E, 0xE5, 0x8E, 0x70, 0x1F, 0x87}, /* 8.1.0 New Device Keygen Source. */
{0x61, 0x6A, 0x88, 0x21, 0xA3, 0x52, 0xB0, 0x19, 0x16, 0x25, 0xA4, 0xE3, 0x4C, 0x54, 0x02, 0x0F}, /* 9.0.0 New Device Keygen Source. */ {0x61, 0x6A, 0x88, 0x21, 0xA3, 0x52, 0xB0, 0x19, 0x16, 0x25, 0xA4, 0xE3, 0x4C, 0x54, 0x02, 0x0F}, /* 9.0.0 New Device Keygen Source. */
{0x9D, 0xB1, 0xAE, 0xCB, 0xF6, 0xF6, 0xE3, 0xFE, 0xAB, 0x6F, 0xCB, 0xAF, 0x38, 0x03, 0xFC, 0x7B}, /* 9.1.0 New Device Keygen Source to be added on next change-of-keys. */ {0x9D, 0xB1, 0xAE, 0xCB, 0xF6, 0xF6, 0xE3, 0xFE, 0xAB, 0x6F, 0xCB, 0xAF, 0x38, 0x03, 0xFC, 0x7B}, /* 9.1.0 New Device Keygen Source. */
{0xC4, 0xBB, 0xF3, 0x9F, 0xA3, 0xAA, 0x00, 0x99, 0x7C, 0x97, 0xAD, 0x91, 0x8F, 0xE8, 0x45, 0xCB}, /* 12.1.0 New Device Keygen Source. */
}; };
/* Determine the current SoC for Mariko specific code. */ /* Determine the current SoC for Mariko specific code. */

View File

@@ -19,8 +19,8 @@
/* This is glue code to enable master key support across versions. */ /* This is glue code to enable master key support across versions. */
/* TODO: Update to 0xC on release of new master key. */ /* TODO: Update to 0xD on release of new master key. */
#define MASTERKEY_REVISION_MAX 0xB #define MASTERKEY_REVISION_MAX 0xC
#define MASTERKEY_REVISION_100_230 0x00 #define MASTERKEY_REVISION_100_230 0x00
#define MASTERKEY_REVISION_300 0x01 #define MASTERKEY_REVISION_300 0x01
@@ -32,7 +32,8 @@
#define MASTERKEY_REVISION_700_800 0x07 #define MASTERKEY_REVISION_700_800 0x07
#define MASTERKEY_REVISION_810 0x08 #define MASTERKEY_REVISION_810 0x08
#define MASTERKEY_REVISION_900 0x09 #define MASTERKEY_REVISION_900 0x09
#define MASTERKEY_REVISION_910_CURRENT 0x0A #define MASTERKEY_REVISION_910_1203 0x0A
#define MASTERKEY_REVISION_C10_CURRENT 0x0B
#define MASTERKEY_NUM_NEW_DEVICE_KEYS (MASTERKEY_REVISION_MAX - MASTERKEY_REVISION_400_410) #define MASTERKEY_NUM_NEW_DEVICE_KEYS (MASTERKEY_REVISION_MAX - MASTERKEY_REVISION_400_410)

View File

@@ -256,6 +256,24 @@ static int stratosphere_ini_handler(void *user, const char *section, const char
return 1; return 1;
} }
static int system_settings_ini_handler(void *user, const char *section, const char *name, const char *value) {
uint32_t *flags = (uint32_t *)user;
if (strcmp(section, "usb") == 0) {
if (strcmp(name, "usb30_force_enabled") == 0) {
if (strcmp(value, "u8!0x1") == 0) {
*flags |= EXOSPHERE_FLAG_FORCE_ENABLE_USB_30;
} else if (strcmp(value, "u8!0x0") == 0) {
*flags &= ~(EXOSPHERE_FLAG_FORCE_ENABLE_USB_30);
}
} else {
return 0;
}
} else {
return 0;
}
return 1;
}
static bool is_nca_present(const char *nca_name) { static bool is_nca_present(const char *nca_name) {
char path[0x100]; char path[0x100];
snprintf(path, sizeof(path), "system:/contents/registered/%s.nca", nca_name); snprintf(path, sizeof(path), "system:/contents/registered/%s.nca", nca_name);
@@ -267,7 +285,15 @@ static bool is_nca_present(const char *nca_name) {
static uint32_t nxboot_get_specific_target_firmware(uint32_t target_firmware){ static uint32_t nxboot_get_specific_target_firmware(uint32_t target_firmware){
#define CHECK_NCA(NCA_ID, VERSION) do { if (is_nca_present(NCA_ID)) { return ATMOSPHERE_TARGET_FIRMWARE_##VERSION; } } while(0) #define CHECK_NCA(NCA_ID, VERSION) do { if (is_nca_present(NCA_ID)) { return ATMOSPHERE_TARGET_FIRMWARE_##VERSION; } } while(0)
if (target_firmware >= ATMOSPHERE_TARGET_FIRMWARE_11_0_0) { if (target_firmware >= ATMOSPHERE_TARGET_FIRMWARE_12_1_0) {
CHECK_NCA("9d9d83d68d9517f245f3e8cd7f93c416", 12_1_0);
} else if (target_firmware >= ATMOSPHERE_TARGET_FIRMWARE_12_0_2) {
CHECK_NCA("a1863a5c0e1cedd442f5e60b0422dc15", 12_0_3);
CHECK_NCA("63d928b5a3016fe8cc0e76d2f06f4e98", 12_0_2);
} else if (target_firmware >= ATMOSPHERE_TARGET_FIRMWARE_12_0_0) {
CHECK_NCA("e65114b456f9d0b566a80e53bade2d89", 12_0_1);
CHECK_NCA("bd4185843550fbba125b20787005d1d2", 12_0_0);
} else if (target_firmware >= ATMOSPHERE_TARGET_FIRMWARE_11_0_0) {
CHECK_NCA("56211c7a5ed20a5332f5cdda67121e37", 11_0_1); CHECK_NCA("56211c7a5ed20a5332f5cdda67121e37", 11_0_1);
CHECK_NCA("594c90bcdbcccad6b062eadba0cd0e7e", 11_0_0); CHECK_NCA("594c90bcdbcccad6b062eadba0cd0e7e", 11_0_0);
} else if (target_firmware >= ATMOSPHERE_TARGET_FIRMWARE_10_0_0) { } else if (target_firmware >= ATMOSPHERE_TARGET_FIRMWARE_10_0_0) {
@@ -370,6 +396,12 @@ static uint32_t nxboot_get_target_firmware(const void *package1loader) {
return ATMOSPHERE_TARGET_FIRMWARE_10_0_0; return ATMOSPHERE_TARGET_FIRMWARE_10_0_0;
} else if (memcmp(package1loader_header->build_timestamp, "20201030", 8) == 0) { } else if (memcmp(package1loader_header->build_timestamp, "20201030", 8) == 0) {
return ATMOSPHERE_TARGET_FIRMWARE_11_0_0; return ATMOSPHERE_TARGET_FIRMWARE_11_0_0;
} else if (memcmp(package1loader_header->build_timestamp, "20210129", 8) == 0) {
return ATMOSPHERE_TARGET_FIRMWARE_12_0_0;
} else if (memcmp(package1loader_header->build_timestamp, "20210422", 8) == 0) {
return ATMOSPHERE_TARGET_FIRMWARE_12_0_2;
} else if (memcmp(package1loader_header->build_timestamp, "20210607", 8) == 0) {
return ATMOSPHERE_TARGET_FIRMWARE_12_1_0;
} else { } else {
fatal_error("[NXBOOT] Unable to identify package1!\n"); fatal_error("[NXBOOT] Unable to identify package1!\n");
} }
@@ -537,6 +569,15 @@ static void nxboot_configure_exosphere(uint32_t target_firmware, unsigned int ke
/* Apply lcd vendor. */ /* Apply lcd vendor. */
exo_cfg.lcd_vendor = display_get_lcd_vendor(); exo_cfg.lcd_vendor = display_get_lcd_vendor();
/* Read and parse system settings.ini to determine usb 3.0 enable. */
char *settings_ini = calloc(1, 0x20000);
if (read_from_file(settings_ini, 0x1FFFF, "atmosphere/config/system_settings.ini")) {
if (ini_parse_string(settings_ini, system_settings_ini_handler, &exo_cfg.flags[0]) < 0) {
fatal_error("[NXBOOT] Failed to parse system_settings.ini!\n");
}
}
free(settings_ini);
if ((exo_cfg.target_firmware < ATMOSPHERE_TARGET_FIRMWARE_MIN) || (exo_cfg.target_firmware > ATMOSPHERE_TARGET_FIRMWARE_MAX)) { if ((exo_cfg.target_firmware < ATMOSPHERE_TARGET_FIRMWARE_MIN) || (exo_cfg.target_firmware > ATMOSPHERE_TARGET_FIRMWARE_MAX)) {
fatal_error("[NXBOOT] Invalid Exosphere target firmware!\n"); fatal_error("[NXBOOT] Invalid Exosphere target firmware!\n");
} }
@@ -568,6 +609,15 @@ static void nxboot_configure_stratosphere(uint32_t target_firmware) {
if (target_firmware >= ATMOSPHERE_TARGET_FIRMWARE_11_0_0 && !(fuse_get_reserved_odm(7) & ~0x00001FFF)) { if (target_firmware >= ATMOSPHERE_TARGET_FIRMWARE_11_0_0 && !(fuse_get_reserved_odm(7) & ~0x00001FFF)) {
kip_patches_set_enable_nogc(); kip_patches_set_enable_nogc();
} }
/* NOTE: 12.0.0 added a new lotus firmware, but did not burn a fuse. */
/* This is literally undetectable using normal fuses.... */
/* C'est la vie. */
/* Check if the fuses are < 12.0.0, but firmware is >= 12.0.0 */
if (target_firmware >= ATMOSPHERE_TARGET_FIRMWARE_12_0_2 && !(fuse_get_reserved_odm(7) & ~0x00003FFF)) {
kip_patches_set_enable_nogc();
}
} }
} }

View File

@@ -250,7 +250,7 @@ static bool package2_validate_metadata(package2_meta_t *metadata, uint8_t data[]
/* Perform version checks. */ /* Perform version checks. */
/* We will be compatible with all package2s released before current, but not newer ones. */ /* We will be compatible with all package2s released before current, but not newer ones. */
if (metadata->version_max >= PACKAGE2_MINVER_THEORETICAL && metadata->version_min < PACKAGE2_MAXVER_1100_CURRENT) { if (metadata->version_max >= PACKAGE2_MINVER_THEORETICAL && metadata->version_min < PACKAGE2_MAXVER_1202_CURRENT) {
return true; return true;
} }

View File

@@ -41,7 +41,8 @@
#define PACKAGE2_MAXVER_900 0xC #define PACKAGE2_MAXVER_900 0xC
#define PACKAGE2_MAXVER_910_920 0xD #define PACKAGE2_MAXVER_910_920 0xD
#define PACKAGE2_MAXVER_1000 0xE #define PACKAGE2_MAXVER_1000 0xE
#define PACKAGE2_MAXVER_1100_CURRENT 0xF #define PACKAGE2_MAXVER_1100 0xF
#define PACKAGE2_MAXVER_1202_CURRENT 0x10
#define PACKAGE2_MINVER_100 0x3 #define PACKAGE2_MINVER_100 0x3
#define PACKAGE2_MINVER_200 0x4 #define PACKAGE2_MINVER_200 0x4
@@ -56,7 +57,8 @@
#define PACKAGE2_MINVER_900 0xD #define PACKAGE2_MINVER_900 0xD
#define PACKAGE2_MINVER_910_920 0xE #define PACKAGE2_MINVER_910_920 0xE
#define PACKAGE2_MINVER_1000 0xF #define PACKAGE2_MINVER_1000 0xF
#define PACKAGE2_MINVER_1100_CURRENT 0x10 #define PACKAGE2_MINVER_1100 0x10
#define PACKAGE2_MINVER_1202_CURRENT 0x11
#define NX_BOOTLOADER_PACKAGE2_LOAD_ADDRESS ((void *)(0xA9800000ull)) #define NX_BOOTLOADER_PACKAGE2_LOAD_ADDRESS ((void *)(0xA9800000ull))

View File

@@ -6,7 +6,7 @@
[subrepo] [subrepo]
remote = https://github.com/Atmosphere-NX/Atmosphere-libs remote = https://github.com/Atmosphere-NX/Atmosphere-libs
branch = master branch = master
commit = 6c11c07e2a7f03952a4e70eb89b47bf528de39c6 commit = eb667fea5142fd35caf539289603748dd6f4f87e
parent = 9e104bb83f1302e9f126542fbf57c7f666aae953 parent = 283736878ddf2cf1cad731b4bf21f916c7e87054
method = merge method = merge
cmdver = 0.4.1 cmdver = 0.4.0

View File

@@ -18,7 +18,7 @@ endif
ATMOSPHERE_BUILD_SETTINGS ?= ATMOSPHERE_BUILD_SETTINGS ?=
export ATMOSPHERE_DEFINES := -DATMOSPHERE export ATMOSPHERE_DEFINES := -DATMOSPHERE
export ATMOSPHERE_SETTINGS := -fPIE -g $(ATMOSPHERE_BUILD_SETTINGS) export ATMOSPHERE_SETTINGS := -fPIE -g -gdwarf-4 $(ATMOSPHERE_BUILD_SETTINGS)
export ATMOSPHERE_CFLAGS := -Wall -ffunction-sections -fdata-sections -fno-strict-aliasing -fwrapv \ export ATMOSPHERE_CFLAGS := -Wall -ffunction-sections -fdata-sections -fno-strict-aliasing -fwrapv \
-fno-asynchronous-unwind-tables -fno-unwind-tables -fno-stack-protector \ -fno-asynchronous-unwind-tables -fno-unwind-tables -fno-stack-protector \
-Wno-format-truncation -Wno-format-zero-length -Wno-stringop-truncation -Wno-format-truncation -Wno-format-zero-length -Wno-stringop-truncation

View File

@@ -8,19 +8,25 @@ include $(dir $(abspath $(lastword $(MAKEFILE_LIST))))/../common.mk
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
ifeq ($(strip $(ATMOSPHERE_ARCH_NAME)),arm64) ifeq ($(strip $(ATMOSPHERE_ARCH_NAME)),arm64)
DEFINES := $(ATMOSPHERE_DEFINES) -DATMOSPHERE_IS_EXOSPHERE DEFINES := $(ATMOSPHERE_DEFINES) -DATMOSPHERE_IS_EXOSPHERE
SETTINGS := $(ATMOSPHERE_SETTINGS) -mgeneral-regs-only -ffixed-x18 -Os -Wextra -Werror -fno-non-call-exceptions SETTINGS := $(ATMOSPHERE_SETTINGS) -mgeneral-regs-only -ffixed-x18 -Os -Wextra -Werror -fno-non-call-exceptions \
-Wno-array-bounds \
-Wno-stringop-overflow \
-Wno-stringop-overread
CFLAGS := $(ATMOSPHERE_CFLAGS) $(SETTINGS) $(DEFINES) $(INCLUDE) CFLAGS := $(ATMOSPHERE_CFLAGS) $(SETTINGS) $(DEFINES) $(INCLUDE)
CXXFLAGS := $(CFLAGS) $(ATMOSPHERE_CXXFLAGS) -fno-use-cxa-atexit CXXFLAGS := $(CFLAGS) $(ATMOSPHERE_CXXFLAGS) -fno-use-cxa-atexit
ASFLAGS := $(ATMOSPHERE_ASFLAGS) $(SETTINGS) ASFLAGS := $(ATMOSPHERE_ASFLAGS) $(SETTINGS)
else ifeq ($(strip $(ATMOSPHERE_ARCH_NAME)),arm) else ifeq ($(strip $(ATMOSPHERE_ARCH_NAME)),arm)
DEFINES := $(ATMOSPHERE_DEFINES) -DATMOSPHERE_IS_EXOSPHERE DEFINES := $(ATMOSPHERE_DEFINES) -DATMOSPHERE_IS_EXOSPHERE
SETTINGS := $(ATMOSPHERE_SETTINGS) -Os -Werror -fno-non-call-exceptions SETTINGS := $(ATMOSPHERE_SETTINGS) -Os -Werror -fno-non-call-exceptions \
-Wno-array-bounds \
-Wno-stringop-overflow \
-Wno-stringop-overread
CFLAGS := $(ATMOSPHERE_CFLAGS) $(SETTINGS) $(DEFINES) $(INCLUDE) CFLAGS := $(ATMOSPHERE_CFLAGS) $(SETTINGS) $(DEFINES) $(INCLUDE)
CXXFLAGS := $(CFLAGS) $(ATMOSPHERE_CXXFLAGS) -fno-use-cxa-atexit CXXFLAGS := $(CFLAGS) $(ATMOSPHERE_CXXFLAGS) -fno-use-cxa-atexit
ASFLAGS := $(ATMOSPHERE_ASFLAGS) $(SETTINGS) ASFLAGS := $(ATMOSPHERE_ASFLAGS) $(SETTINGS)
endif endif
export LDFLAGS = -specs=$(TOPDIR)/$(notdir $(TOPDIR)).specs -fno-asynchronous-unwind-tables -fno-unwind-tables -fno-exceptions -fno-rtti -fno-use-cxa-atexit -nostdlib -nostartfiles -g $(SETTINGS) -Wl,-Map,$(notdir $*.map) -Wl,-z,relro,-z,now export LDFLAGS = -specs=$(TOPDIR)/$(notdir $(TOPDIR)).specs -fno-asynchronous-unwind-tables -fno-unwind-tables -fno-exceptions -fno-rtti -fno-use-cxa-atexit -nostdlib -nostartfiles -g -gdwarf-4 $(SETTINGS) -Wl,-Map,$(notdir $*.map) -Wl,-z,relro,-z,now
export CXXWRAPS := -Wl,--wrap,__cxa_pure_virtual \ export CXXWRAPS := -Wl,--wrap,__cxa_pure_virtual \
-Wl,--wrap,__cxa_throw \ -Wl,--wrap,__cxa_throw \

View File

@@ -12,7 +12,7 @@ export CFLAGS := $(ATMOSPHERE_CFLAGS) $(SETTINGS) $(DEFINES) $(INCLUDE)
export CXXFLAGS := $(CFLAGS) $(ATMOSPHERE_CXXFLAGS) -fno-use-cxa-atexit export CXXFLAGS := $(CFLAGS) $(ATMOSPHERE_CXXFLAGS) -fno-use-cxa-atexit
export ASFLAGS := $(ATMOSPHERE_ASFLAGS) $(SETTINGS) $(DEFINES) $(INCLUDE) export ASFLAGS := $(ATMOSPHERE_ASFLAGS) $(SETTINGS) $(DEFINES) $(INCLUDE)
export LDFLAGS = -specs=$(TOPDIR)/$(notdir $(TOPDIR)).specs -fno-asynchronous-unwind-tables -fno-unwind-tables -nostdlib -nostartfiles -g $(SETTINGS) -Wl,-Map,$(notdir $*.map) -Wl,-z,relro,-z,now export LDFLAGS = -specs=$(TOPDIR)/$(notdir $(TOPDIR)).specs -fno-asynchronous-unwind-tables -fno-unwind-tables -nostdlib -nostartfiles -g -gdwarf-4 $(SETTINGS) -Wl,-Map,$(notdir $*.map) -Wl,-z,relro,-z,now
export CXXWRAPS := -Wl,--wrap,__cxa_pure_virtual \ export CXXWRAPS := -Wl,--wrap,__cxa_pure_virtual \
-Wl,--wrap,__cxa_throw \ -Wl,--wrap,__cxa_throw \

View File

@@ -34,7 +34,8 @@ export CXXWRAPS := -Wl,--wrap,__cxa_pure_virtual \
-Wl,--wrap,_Unwind_Resume \ -Wl,--wrap,_Unwind_Resume \
-Wl,--wrap,_ZSt19__throw_logic_errorPKc \ -Wl,--wrap,_ZSt19__throw_logic_errorPKc \
-Wl,--wrap,_ZSt20__throw_length_errorPKc \ -Wl,--wrap,_ZSt20__throw_length_errorPKc \
-Wl,--wrap,_ZNSt11logic_errorC2EPKc -Wl,--wrap,_ZNSt11logic_errorC2EPKc \
-Wl,--wrap,exit
export LDFLAGS = -specs=$(ATMOSPHERE_LIBRARIES_DIR)/libstratosphere/stratosphere.specs -specs=$(DEVKITPRO)/libnx/switch.specs $(SETTINGS) $(CXXWRAPS) -Wl,-Map,$(notdir $*.map) export LDFLAGS = -specs=$(ATMOSPHERE_LIBRARIES_DIR)/libstratosphere/stratosphere.specs -specs=$(DEVKITPRO)/libnx/switch.specs $(SETTINGS) $(CXXWRAPS) -Wl,-Map,$(notdir $*.map)

View File

@@ -16,7 +16,10 @@ include $(dir $(abspath $(lastword $(MAKEFILE_LIST))))/../config/common.mk
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
DEFINES := $(ATMOSPHERE_DEFINES) -DATMOSPHERE_IS_EXOSPHERE DEFINES := $(ATMOSPHERE_DEFINES) -DATMOSPHERE_IS_EXOSPHERE
SETTINGS := $(ATMOSPHERE_SETTINGS) -Os -Wextra -Werror -flto -fno-non-call-exceptions SETTINGS := $(ATMOSPHERE_SETTINGS) -Os -Wextra -Werror -flto -fno-non-call-exceptions \
-Wno-array-bounds \
-Wno-stringop-overflow \
-Wno-stringop-overread
CFLAGS := $(ATMOSPHERE_CFLAGS) $(SETTINGS) $(DEFINES) $(INCLUDE) CFLAGS := $(ATMOSPHERE_CFLAGS) $(SETTINGS) $(DEFINES) $(INCLUDE)
CXXFLAGS := $(CFLAGS) $(ATMOSPHERE_CXXFLAGS) -fno-use-cxa-atexit CXXFLAGS := $(CFLAGS) $(ATMOSPHERE_CXXFLAGS) -fno-use-cxa-atexit
ASFLAGS := $(ATMOSPHERE_ASFLAGS) $(SETTINGS) $(DEFINES) $(INCLUDE) ASFLAGS := $(ATMOSPHERE_ASFLAGS) $(SETTINGS) $(DEFINES) $(INCLUDE)

View File

@@ -16,7 +16,10 @@ include $(dir $(abspath $(lastword $(MAKEFILE_LIST))))/../config/common.mk
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
DEFINES := $(ATMOSPHERE_DEFINES) -DATMOSPHERE_IS_EXOSPHERE DEFINES := $(ATMOSPHERE_DEFINES) -DATMOSPHERE_IS_EXOSPHERE
SETTINGS := $(ATMOSPHERE_SETTINGS) -mgeneral-regs-only -ffixed-x18 -Os -Wextra -Werror -fno-non-call-exceptions SETTINGS := $(ATMOSPHERE_SETTINGS) -mgeneral-regs-only -ffixed-x18 -Os -Wextra -Werror -fno-non-call-exceptions \
-Wno-array-bounds \
-Wno-stringop-overflow \
-Wno-stringop-overread
CFLAGS := $(ATMOSPHERE_CFLAGS) $(SETTINGS) $(DEFINES) $(INCLUDE) CFLAGS := $(ATMOSPHERE_CFLAGS) $(SETTINGS) $(DEFINES) $(INCLUDE)
CXXFLAGS := $(CFLAGS) $(ATMOSPHERE_CXXFLAGS) -fno-use-cxa-atexit CXXFLAGS := $(CFLAGS) $(ATMOSPHERE_CXXFLAGS) -fno-use-cxa-atexit
ASFLAGS := $(ATMOSPHERE_ASFLAGS) $(SETTINGS) $(DEFINES) $(INCLUDE) ASFLAGS := $(ATMOSPHERE_ASFLAGS) $(SETTINGS) $(DEFINES) $(INCLUDE)

View File

@@ -51,9 +51,9 @@ namespace ams::fuse {
DramId_IcosaSamsung4GB = 0, DramId_IcosaSamsung4GB = 0,
DramId_IcosaHynix4GB = 1, DramId_IcosaHynix4GB = 1,
DramId_IcosaMicron4GB = 2, DramId_IcosaMicron4GB = 2,
DramId_AulaHynix1y4GB = 3, DramId_IowaHynix1y4GB = 3,
DramId_IcosaSamsung6GB = 4, DramId_IcosaSamsung6GB = 4,
DramId_CopperHynix4GB = 5, DramId_HoagHynix1y4GB = 5,
DramId_CopperMicron4GB = 6, DramId_CopperMicron4GB = 6,
DramId_IowaX1X2Samsung4GB = 7, DramId_IowaX1X2Samsung4GB = 7,
DramId_IowaSansung4GB = 8, DramId_IowaSansung4GB = 8,

View File

@@ -20,17 +20,18 @@ namespace ams::pkg1 {
enum KeyGeneration : int { enum KeyGeneration : int {
KeyGeneration_1_0_0 = 0x00, KeyGeneration_1_0_0 = 0x00,
KeyGeneration_3_0_0 = 0x01, KeyGeneration_3_0_0 = 0x01,
KeyGeneration_3_0_1 = 0x02, KeyGeneration_3_0_1 = 0x02,
KeyGeneration_4_0_0 = 0x03, KeyGeneration_4_0_0 = 0x03,
KeyGeneration_5_0_0 = 0x04, KeyGeneration_5_0_0 = 0x04,
KeyGeneration_6_0_0 = 0x05, KeyGeneration_6_0_0 = 0x05,
KeyGeneration_6_2_0 = 0x06, KeyGeneration_6_2_0 = 0x06,
KeyGeneration_7_0_0 = 0x07, KeyGeneration_7_0_0 = 0x07,
KeyGeneration_8_1_0 = 0x08, KeyGeneration_8_1_0 = 0x08,
KeyGeneration_9_0_0 = 0x09, KeyGeneration_9_0_0 = 0x09,
KeyGeneration_9_1_0 = 0x0A, KeyGeneration_9_1_0 = 0x0A,
KeyGeneration_12_1_0 = 0x0B,
KeyGeneration_Count, KeyGeneration_Count,

View File

@@ -23,8 +23,8 @@ namespace ams::pkg2 {
constexpr inline int PayloadCount = 3; constexpr inline int PayloadCount = 3;
constexpr inline int MinimumValidDataVersion = 0; /* We allow older package2 to load; this value is currently 0x10 in Nintendo's code. */ constexpr inline int MinimumValidDataVersion = 0; /* We allow older package2 to load; this value is currently 0x13 in Nintendo's code. */
constexpr inline int CurrentBootloaderVersion = 0xE; constexpr inline int CurrentBootloaderVersion = 0xF;
struct Package2Meta { struct Package2Meta {
using Magic = util::FourCC<'P','K','2','1'>; using Magic = util::FourCC<'P','K','2','1'>;

View File

@@ -29,6 +29,7 @@ namespace ams::secmon {
SecureMonitorConfigurationFlag_EnableUserModePerformanceCounterAccess = (1u << 4), SecureMonitorConfigurationFlag_EnableUserModePerformanceCounterAccess = (1u << 4),
SecureMonitorConfigurationFlag_ShouldUseBlankCalibrationBinary = (1u << 5), SecureMonitorConfigurationFlag_ShouldUseBlankCalibrationBinary = (1u << 5),
SecureMonitorConfigurationFlag_AllowWritingToCalibrationBinarySysmmc = (1u << 6), SecureMonitorConfigurationFlag_AllowWritingToCalibrationBinarySysmmc = (1u << 6),
SecureMonitorConfigurationFlag_ForceEnableUsb30 = (1u << 7),
SecureMonitorConfigurationFlag_Default = SecureMonitorConfigurationFlag_IsDevelopmentFunctionEnabledForKernel, SecureMonitorConfigurationFlag_Default = SecureMonitorConfigurationFlag_IsDevelopmentFunctionEnabledForKernel,
}; };
@@ -101,6 +102,7 @@ namespace ams::secmon {
constexpr bool EnableUserModePerformanceCounterAccess() const { return (this->flags[0] & SecureMonitorConfigurationFlag_EnableUserModePerformanceCounterAccess) != 0; } constexpr bool EnableUserModePerformanceCounterAccess() const { return (this->flags[0] & SecureMonitorConfigurationFlag_EnableUserModePerformanceCounterAccess) != 0; }
constexpr bool ShouldUseBlankCalibrationBinary() const { return (this->flags[0] & SecureMonitorConfigurationFlag_ShouldUseBlankCalibrationBinary) != 0; } constexpr bool ShouldUseBlankCalibrationBinary() const { return (this->flags[0] & SecureMonitorConfigurationFlag_ShouldUseBlankCalibrationBinary) != 0; }
constexpr bool AllowWritingToCalibrationBinarySysmmc() const { return (this->flags[0] & SecureMonitorConfigurationFlag_AllowWritingToCalibrationBinarySysmmc) != 0; } constexpr bool AllowWritingToCalibrationBinarySysmmc() const { return (this->flags[0] & SecureMonitorConfigurationFlag_AllowWritingToCalibrationBinarySysmmc) != 0; }
constexpr bool IsUsb30ForceEnabled() const { return (this->flags[0] & SecureMonitorConfigurationFlag_ForceEnableUsb30) != 0; }
constexpr bool IsDevelopmentFunctionEnabled(bool for_kern) const { return for_kern ? this->IsDevelopmentFunctionEnabledForKernel() : this->IsDevelopmentFunctionEnabledForUser(); } constexpr bool IsDevelopmentFunctionEnabled(bool for_kern) const { return for_kern ? this->IsDevelopmentFunctionEnabledForKernel() : this->IsDevelopmentFunctionEnabledForUser(); }
}; };

View File

@@ -165,6 +165,7 @@ namespace ams::fuse {
} }
constexpr const TargetFirmware FuseVersionIncrementFirmwares[] = { constexpr const TargetFirmware FuseVersionIncrementFirmwares[] = {
TargetFirmware_12_0_2,
TargetFirmware_11_0_0, TargetFirmware_11_0_0,
TargetFirmware_10_0_0, TargetFirmware_10_0_0,
TargetFirmware_9_1_0, TargetFirmware_9_1_0,

View File

@@ -140,6 +140,8 @@ $(OFILES_SRC) : $(HFILES_BIN)
kern_libc_generic.o: CFLAGS += -fno-builtin kern_libc_generic.o: CFLAGS += -fno-builtin
kern_k_auto_object.o: CXXFLAGS += -fno-lto
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
%_bin.h %.bin.o : %.bin %_bin.h %.bin.o : %.bin
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------

View File

@@ -14,10 +14,11 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#pragma once #pragma once
#include <mesosphere/kern_select_assembly_offsets.h>
namespace ams::kern::init { namespace ams::kern::init {
struct KInitArguments { struct alignas(util::CeilingPowerOfTwo(INIT_ARGUMENTS_SIZE)) KInitArguments {
u64 ttbr0; u64 ttbr0;
u64 ttbr1; u64 ttbr1;
u64 tcr; u64 tcr;
@@ -31,5 +32,20 @@ namespace ams::kern::init {
u64 setup_function; u64 setup_function;
u64 exception_stack; u64 exception_stack;
}; };
static_assert(alignof(KInitArguments) == util::CeilingPowerOfTwo(INIT_ARGUMENTS_SIZE));
static_assert(sizeof(KInitArguments) == std::max(INIT_ARGUMENTS_SIZE, util::CeilingPowerOfTwo(INIT_ARGUMENTS_SIZE)));
static_assert(__builtin_offsetof(KInitArguments, ttbr0) == INIT_ARGUMENTS_TTBR0);
static_assert(__builtin_offsetof(KInitArguments, ttbr1) == INIT_ARGUMENTS_TTBR1);
static_assert(__builtin_offsetof(KInitArguments, tcr) == INIT_ARGUMENTS_TCR);
static_assert(__builtin_offsetof(KInitArguments, mair) == INIT_ARGUMENTS_MAIR);
static_assert(__builtin_offsetof(KInitArguments, cpuactlr) == INIT_ARGUMENTS_CPUACTLR);
static_assert(__builtin_offsetof(KInitArguments, cpuectlr) == INIT_ARGUMENTS_CPUECTLR);
static_assert(__builtin_offsetof(KInitArguments, sctlr) == INIT_ARGUMENTS_SCTLR);
static_assert(__builtin_offsetof(KInitArguments, sp) == INIT_ARGUMENTS_SP);
static_assert(__builtin_offsetof(KInitArguments, entrypoint) == INIT_ARGUMENTS_ENTRYPOINT);
static_assert(__builtin_offsetof(KInitArguments, argument) == INIT_ARGUMENTS_ARGUMENT);
static_assert(__builtin_offsetof(KInitArguments, setup_function) == INIT_ARGUMENTS_SETUP_FUNCTION);
static_assert(__builtin_offsetof(KInitArguments, exception_stack) == INIT_ARGUMENTS_EXCEPTION_STACK);
} }

View File

@@ -38,37 +38,67 @@ namespace ams::kern::arch::arm64::init {
public: public:
class IPageAllocator { class IPageAllocator {
public: public:
virtual KPhysicalAddress Allocate() { return Null<KPhysicalAddress>; } virtual KPhysicalAddress Allocate(size_t size) = 0;
virtual void Free(KPhysicalAddress phys_addr) { /* Nothing to do here. */ (void)(phys_addr); } virtual void Free(KPhysicalAddress phys_addr, size_t size) = 0;
}; };
struct NoClear{};
private: private:
KPhysicalAddress m_l1_table; KPhysicalAddress m_l1_tables[2];
u32 m_num_entries[2];
public: public:
constexpr ALWAYS_INLINE KInitialPageTable(KPhysicalAddress l1, NoClear) : m_l1_table(l1) { /* ... */ } KInitialPageTable(KVirtualAddress start_address, KVirtualAddress end_address, IPageAllocator &allocator) {
/* Set tables. */
m_l1_tables[0] = AllocateNewPageTable(allocator);
m_l1_tables[1] = AllocateNewPageTable(allocator);
constexpr ALWAYS_INLINE KInitialPageTable(KPhysicalAddress l1) : KInitialPageTable(l1, NoClear{}) { /* Set counts. */
ClearNewPageTable(m_l1_table); m_num_entries[0] = MaxPageTableEntries;
m_num_entries[1] = ((end_address / L1BlockSize) & (MaxPageTableEntries - 1)) - ((start_address / L1BlockSize) & (MaxPageTableEntries - 1)) + 1;
} }
constexpr ALWAYS_INLINE uintptr_t GetL1TableAddress() const { KInitialPageTable() {
return GetInteger(m_l1_table); /* Set tables. */
m_l1_tables[0] = util::AlignDown(cpu::GetTtbr0El1(), PageSize);
m_l1_tables[1] = util::AlignDown(cpu::GetTtbr1El1(), PageSize);
/* Set counts. */
cpu::TranslationControlRegisterAccessor tcr;
m_num_entries[0] = tcr.GetT0Size() / L1BlockSize;
m_num_entries[1] = tcr.GetT1Size() / L1BlockSize;
/* Check counts. */
MESOSPHERE_INIT_ABORT_UNLESS(0 < m_num_entries[0] && m_num_entries[0] <= MaxPageTableEntries);
MESOSPHERE_INIT_ABORT_UNLESS(0 < m_num_entries[1] && m_num_entries[1] <= MaxPageTableEntries);
}
constexpr ALWAYS_INLINE uintptr_t GetTtbr0L1TableAddress() const {
return GetInteger(m_l1_tables[0]);
}
constexpr ALWAYS_INLINE uintptr_t GetTtbr1L1TableAddress() const {
return GetInteger(m_l1_tables[1]);
} }
private: private:
static constexpr ALWAYS_INLINE L1PageTableEntry *GetL1Entry(KPhysicalAddress _l1_table, KVirtualAddress address) { constexpr ALWAYS_INLINE L1PageTableEntry *GetL1Entry(KVirtualAddress address) const {
L1PageTableEntry *l1_table = reinterpret_cast<L1PageTableEntry *>(GetInteger(_l1_table)); const size_t index = (GetInteger(address) >> (BITSIZEOF(address) - 1)) & 1;
return l1_table + ((GetInteger(address) >> 30) & (MaxPageTableEntries - 1)); L1PageTableEntry *l1_table = reinterpret_cast<L1PageTableEntry *>(GetInteger(m_l1_tables[index]));
return l1_table + ((GetInteger(address) / L1BlockSize) & (m_num_entries[index] - 1));
} }
static constexpr ALWAYS_INLINE L2PageTableEntry *GetL2Entry(const L1PageTableEntry *entry, KVirtualAddress address) { static constexpr ALWAYS_INLINE L2PageTableEntry *GetL2Entry(const L1PageTableEntry *entry, KVirtualAddress address) {
L2PageTableEntry *l2_table = reinterpret_cast<L2PageTableEntry *>(GetInteger(entry->GetTable())); L2PageTableEntry *l2_table = reinterpret_cast<L2PageTableEntry *>(GetInteger(entry->GetTable()));
return l2_table + ((GetInteger(address) >> 21) & (MaxPageTableEntries - 1)); return l2_table + ((GetInteger(address) / L2BlockSize) & (MaxPageTableEntries - 1));
} }
static constexpr ALWAYS_INLINE L3PageTableEntry *GetL3Entry(const L2PageTableEntry *entry, KVirtualAddress address) { static constexpr ALWAYS_INLINE L3PageTableEntry *GetL3Entry(const L2PageTableEntry *entry, KVirtualAddress address) {
L3PageTableEntry *l3_table = reinterpret_cast<L3PageTableEntry *>(GetInteger(entry->GetTable())); L3PageTableEntry *l3_table = reinterpret_cast<L3PageTableEntry *>(GetInteger(entry->GetTable()));
return l3_table + ((GetInteger(address) >> 12) & (MaxPageTableEntries - 1)); return l3_table + ((GetInteger(address) / L3BlockSize) & (MaxPageTableEntries - 1));
}
static ALWAYS_INLINE KPhysicalAddress AllocateNewPageTable(IPageAllocator &allocator) {
auto address = allocator.Allocate(PageSize);
ClearNewPageTable(address);
return address;
} }
static ALWAYS_INLINE void ClearNewPageTable(KPhysicalAddress address) { static ALWAYS_INLINE void ClearNewPageTable(KPhysicalAddress address) {
@@ -83,7 +113,7 @@ namespace ams::kern::arch::arm64::init {
const KVirtualAddress end_virt_addr = virt_addr + size; const KVirtualAddress end_virt_addr = virt_addr + size;
size_t count = 0; size_t count = 0;
while (virt_addr < end_virt_addr) { while (virt_addr < end_virt_addr) {
L1PageTableEntry *l1_entry = GetL1Entry(m_l1_table, virt_addr); L1PageTableEntry *l1_entry = this->GetL1Entry(virt_addr);
/* If an L1 block is mapped or we're empty, advance by L1BlockSize. */ /* If an L1 block is mapped or we're empty, advance by L1BlockSize. */
if (l1_entry->IsBlock() || l1_entry->IsEmpty()) { if (l1_entry->IsBlock() || l1_entry->IsEmpty()) {
@@ -137,7 +167,7 @@ namespace ams::kern::arch::arm64::init {
const KVirtualAddress end_virt_addr = virt_addr + size; const KVirtualAddress end_virt_addr = virt_addr + size;
size_t count = 0; size_t count = 0;
while (virt_addr < end_virt_addr) { while (virt_addr < end_virt_addr) {
L1PageTableEntry *l1_entry = GetL1Entry(m_l1_table, virt_addr); L1PageTableEntry *l1_entry = this->GetL1Entry(virt_addr);
/* If an L1 block is mapped or we're empty, advance by L1BlockSize. */ /* If an L1 block is mapped or we're empty, advance by L1BlockSize. */
if (l1_entry->IsBlock() || l1_entry->IsEmpty()) { if (l1_entry->IsBlock() || l1_entry->IsEmpty()) {
@@ -194,7 +224,7 @@ namespace ams::kern::arch::arm64::init {
} }
PageTableEntry *GetMappingEntry(KVirtualAddress virt_addr, size_t block_size) { PageTableEntry *GetMappingEntry(KVirtualAddress virt_addr, size_t block_size) {
L1PageTableEntry *l1_entry = GetL1Entry(m_l1_table, virt_addr); L1PageTableEntry *l1_entry = this->GetL1Entry(virt_addr);
if (l1_entry->IsBlock()) { if (l1_entry->IsBlock()) {
MESOSPHERE_INIT_ABORT_UNLESS(block_size == L1BlockSize); MESOSPHERE_INIT_ABORT_UNLESS(block_size == L1BlockSize);
@@ -301,7 +331,7 @@ namespace ams::kern::arch::arm64::init {
/* Iteratively map pages until the requested region is mapped. */ /* Iteratively map pages until the requested region is mapped. */
while (size > 0) { while (size > 0) {
L1PageTableEntry *l1_entry = GetL1Entry(m_l1_table, virt_addr); L1PageTableEntry *l1_entry = this->GetL1Entry(virt_addr);
/* Can we make an L1 block? */ /* Can we make an L1 block? */
if (util::IsAligned(GetInteger(virt_addr), L1BlockSize) && util::IsAligned(GetInteger(phys_addr), L1BlockSize) && size >= L1BlockSize) { if (util::IsAligned(GetInteger(virt_addr), L1BlockSize) && util::IsAligned(GetInteger(phys_addr), L1BlockSize) && size >= L1BlockSize) {
@@ -316,7 +346,7 @@ namespace ams::kern::arch::arm64::init {
/* If we don't already have an L2 table, we need to make a new one. */ /* If we don't already have an L2 table, we need to make a new one. */
if (!l1_entry->IsTable()) { if (!l1_entry->IsTable()) {
KPhysicalAddress new_table = allocator.Allocate(); KPhysicalAddress new_table = AllocateNewPageTable(allocator);
ClearNewPageTable(new_table); ClearNewPageTable(new_table);
*l1_entry = L1PageTableEntry(PageTableEntry::TableTag{}, new_table, attr.IsPrivilegedExecuteNever()); *l1_entry = L1PageTableEntry(PageTableEntry::TableTag{}, new_table, attr.IsPrivilegedExecuteNever());
cpu::DataSynchronizationBarrierInnerShareable(); cpu::DataSynchronizationBarrierInnerShareable();
@@ -350,7 +380,7 @@ namespace ams::kern::arch::arm64::init {
/* If we don't already have an L3 table, we need to make a new one. */ /* If we don't already have an L3 table, we need to make a new one. */
if (!l2_entry->IsTable()) { if (!l2_entry->IsTable()) {
KPhysicalAddress new_table = allocator.Allocate(); KPhysicalAddress new_table = AllocateNewPageTable(allocator);
ClearNewPageTable(new_table); ClearNewPageTable(new_table);
*l2_entry = L2PageTableEntry(PageTableEntry::TableTag{}, new_table, attr.IsPrivilegedExecuteNever()); *l2_entry = L2PageTableEntry(PageTableEntry::TableTag{}, new_table, attr.IsPrivilegedExecuteNever());
cpu::DataSynchronizationBarrierInnerShareable(); cpu::DataSynchronizationBarrierInnerShareable();
@@ -382,7 +412,7 @@ namespace ams::kern::arch::arm64::init {
KPhysicalAddress GetPhysicalAddress(KVirtualAddress virt_addr) const { KPhysicalAddress GetPhysicalAddress(KVirtualAddress virt_addr) const {
/* Get the L1 entry. */ /* Get the L1 entry. */
const L1PageTableEntry *l1_entry = GetL1Entry(m_l1_table, virt_addr); const L1PageTableEntry *l1_entry = this->GetL1Entry(virt_addr);
if (l1_entry->IsBlock()) { if (l1_entry->IsBlock()) {
return l1_entry->GetBlock() + (GetInteger(virt_addr) & (L1BlockSize - 1)); return l1_entry->GetBlock() + (GetInteger(virt_addr) & (L1BlockSize - 1));
@@ -444,7 +474,7 @@ namespace ams::kern::arch::arm64::init {
}; };
while (virt_addr < end_virt_addr) { while (virt_addr < end_virt_addr) {
L1PageTableEntry *l1_entry = GetL1Entry(m_l1_table, virt_addr); L1PageTableEntry *l1_entry = this->GetL1Entry(virt_addr);
/* If an L1 block is mapped, update. */ /* If an L1 block is mapped, update. */
if (l1_entry->IsBlock()) { if (l1_entry->IsBlock()) {
@@ -485,7 +515,7 @@ namespace ams::kern::arch::arm64::init {
const KVirtualAddress end_virt_addr = virt_addr + size; const KVirtualAddress end_virt_addr = virt_addr + size;
while (virt_addr < end_virt_addr) { while (virt_addr < end_virt_addr) {
L1PageTableEntry *l1_entry = GetL1Entry(m_l1_table, virt_addr); L1PageTableEntry *l1_entry = this->GetL1Entry(virt_addr);
/* If an L1 block is mapped, the address isn't free. */ /* If an L1 block is mapped, the address isn't free. */
if (l1_entry->IsBlock()) { if (l1_entry->IsBlock()) {
@@ -534,7 +564,7 @@ namespace ams::kern::arch::arm64::init {
/* Iteratively reprotect pages until the requested region is reprotected. */ /* Iteratively reprotect pages until the requested region is reprotected. */
while (size > 0) { while (size > 0) {
L1PageTableEntry *l1_entry = GetL1Entry(m_l1_table, virt_addr); L1PageTableEntry *l1_entry = this->GetL1Entry(virt_addr);
/* Check if an L1 block is present. */ /* Check if an L1 block is present. */
if (l1_entry->IsBlock()) { if (l1_entry->IsBlock()) {
@@ -673,11 +703,18 @@ namespace ams::kern::arch::arm64::init {
}; };
class KInitialPageAllocator : public KInitialPageTable::IPageAllocator { class KInitialPageAllocator final : public KInitialPageTable::IPageAllocator {
private:
static constexpr inline size_t FreeUnitSize = BITSIZEOF(u64) * PageSize;
struct FreeListEntry {
FreeListEntry *next;
size_t size;
};
public: public:
struct State { struct State {
uintptr_t next_address; uintptr_t start_address;
uintptr_t free_bitmap; uintptr_t end_address;
FreeListEntry *free_head;
}; };
private: private:
State m_state; State m_state;
@@ -685,8 +722,8 @@ namespace ams::kern::arch::arm64::init {
constexpr ALWAYS_INLINE KInitialPageAllocator() : m_state{} { /* ... */ } constexpr ALWAYS_INLINE KInitialPageAllocator() : m_state{} { /* ... */ }
ALWAYS_INLINE void Initialize(uintptr_t address) { ALWAYS_INLINE void Initialize(uintptr_t address) {
m_state.next_address = address + BITSIZEOF(m_state.free_bitmap) * PageSize; m_state.start_address = address;
m_state.free_bitmap = ~uintptr_t(); m_state.end_address = address;
} }
ALWAYS_INLINE void InitializeFromState(uintptr_t state_val) { ALWAYS_INLINE void InitializeFromState(uintptr_t state_val) {
@@ -697,28 +734,134 @@ namespace ams::kern::arch::arm64::init {
*out = m_state; *out = m_state;
m_state = {}; m_state = {};
} }
public: private:
virtual KPhysicalAddress Allocate() override { bool CanAllocate(size_t align, size_t size) const {
MESOSPHERE_INIT_ABORT_UNLESS(m_state.next_address != Null<uintptr_t>); for (auto *cur = m_state.free_head; cur != nullptr; cur = cur->next) {
uintptr_t allocated = m_state.next_address; const uintptr_t cur_last = reinterpret_cast<uintptr_t>(cur) + cur->size - 1;
if (m_state.free_bitmap != 0) { const uintptr_t alloc_last = util::AlignUp(reinterpret_cast<uintptr_t>(cur), align) + size - 1;
u64 index; if (alloc_last <= cur_last) {
uintptr_t mask; return true;
do { }
index = KSystemControl::Init::GenerateRandomRange(0, BITSIZEOF(m_state.free_bitmap) - 1);
mask = (static_cast<uintptr_t>(1) << index);
} while ((m_state.free_bitmap & mask) == 0);
m_state.free_bitmap &= ~mask;
allocated = m_state.next_address - ((BITSIZEOF(m_state.free_bitmap) - index) * PageSize);
} else {
m_state.next_address += PageSize;
} }
return false;
ClearPhysicalMemory(allocated, PageSize);
return allocated;
} }
/* No need to override free. The default does nothing, and so would we. */ bool TryAllocate(uintptr_t address, size_t size) {
/* Try to allocate the region. */
auto **prev_next = std::addressof(m_state.free_head);
for (auto *cur = m_state.free_head; cur != nullptr; prev_next = std::addressof(cur->next), cur = cur->next) {
const uintptr_t cur_start = reinterpret_cast<uintptr_t>(cur);
const uintptr_t cur_last = cur_start + cur->size - 1;
if (cur_start <= address && address + size - 1 <= cur_last) {
auto *alloc = reinterpret_cast<FreeListEntry *>(address);
/* Perform fragmentation at front. */
if (cur != alloc) {
prev_next = std::addressof(cur->next);
*alloc = {
.next = cur->next,
.size = cur_start + cur->size - address,
};
*cur = {
.next = alloc,
.size = address - cur_start,
};
}
/* Perform fragmentation at tail. */
if (alloc->size != size) {
auto *next = reinterpret_cast<FreeListEntry *>(address + size);
*next = {
.next = alloc->next,
.size = alloc->size - size,
};
*alloc = {
.next = next,
.size = size,
};
}
*prev_next = alloc->next;
return true;
}
}
return false;
}
public:
KPhysicalAddress Allocate(size_t align, size_t size) {
/* Ensure that the free list is non-empty. */
while (!this->CanAllocate(align, size)) {
this->Free(m_state.end_address, FreeUnitSize);
m_state.end_address += FreeUnitSize;
}
/* Allocate a random address. */
const uintptr_t aligned_start = util::AlignUp(m_state.start_address, align);
const uintptr_t aligned_end = util::AlignDown(m_state.end_address, align);
const size_t ind_max = ((aligned_end - aligned_start) / align) - 1;
while (true) {
if (const uintptr_t random_address = aligned_start + (KSystemControl::Init::GenerateRandomRange(0, ind_max) * align); this->TryAllocate(random_address, size)) {
return random_address;
}
}
}
virtual KPhysicalAddress Allocate(size_t size) override {
return this->Allocate(size, size);
}
virtual void Free(KPhysicalAddress phys_addr, size_t size) override {
auto **prev_next = std::addressof(m_state.free_head);
auto *new_chunk = reinterpret_cast<FreeListEntry *>(GetInteger(phys_addr));
if (auto *cur = m_state.free_head; cur != nullptr) {
const uintptr_t new_start = reinterpret_cast<uintptr_t>(new_chunk);
const uintptr_t new_end = GetInteger(phys_addr) + size;
while (true) {
/* Attempt coalescing. */
const uintptr_t cur_start = reinterpret_cast<uintptr_t>(cur);
const uintptr_t cur_end = cur_start + cur->size;
if (new_start < new_end) {
if (new_end < cur_start) {
*new_chunk = {
.next = cur,
.size = size,
};
break;
} else if (new_end == cur_start) {
*new_chunk = {
.next = cur->next,
.size = cur->size + size,
};
break;
}
} else if (cur_end == new_start) {
cur->size += size;
return;
}
prev_next = std::addressof(cur->next);
if (cur->next != nullptr) {
cur = cur->next;
} else {
*new_chunk = {
.next = nullptr,
.size = size,
};
cur->next = new_chunk;
return;
}
}
} else {
*new_chunk = {
.next = nullptr,
.size = size,
};
}
*prev_next = new_chunk;
}
}; };
} }

View File

@@ -0,0 +1,157 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope 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/>.
*/
#pragma once
/* TODO: Different header for this? */
#define AMS_KERN_NUM_SUPERVISOR_CALLS 0xC0
/* ams::kern::KThread::StackParameters, https://github.com/Atmosphere-NX/Atmosphere/blob/master/libraries/libmesosphere/include/mesosphere/kern_k_thread.hpp */
#define THREAD_STACK_PARAMETERS_SIZE 0x30
#define THREAD_STACK_PARAMETERS_SVC_PERMISSION 0x00
#define THREAD_STACK_PARAMETERS_CONTEXT 0x18
#define THREAD_STACK_PARAMETERS_CUR_THREAD 0x20
#define THREAD_STACK_PARAMETERS_DISABLE_COUNT 0x28
#define THREAD_STACK_PARAMETERS_DPC_FLAGS 0x2A
#define THREAD_STACK_PARAMETERS_CURRENT_SVC_ID 0x2B
#define THREAD_STACK_PARAMETERS_IS_CALLING_SVC 0x2C
#define THREAD_STACK_PARAMETERS_IS_IN_EXCEPTION_HANDLER 0x2D
#define THREAD_STACK_PARAMETERS_IS_PINNED 0x2E
/* ams::kern::arch::arm64::KThreadContext, https://github.com/Atmosphere-NX/Atmosphere/blob/master/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_thread_context.hpp */
#define THREAD_CONTEXT_SIZE 0x290
#define THREAD_CONTEXT_CPU_REGISTERS 0x000
#define THREAD_CONTEXT_X19 0x000
#define THREAD_CONTEXT_X20 0x008
#define THREAD_CONTEXT_X21 0x010
#define THREAD_CONTEXT_X22 0x018
#define THREAD_CONTEXT_X23 0x020
#define THREAD_CONTEXT_X24 0x028
#define THREAD_CONTEXT_X25 0x030
#define THREAD_CONTEXT_X26 0x038
#define THREAD_CONTEXT_X27 0x040
#define THREAD_CONTEXT_X28 0x048
#define THREAD_CONTEXT_X29 0x050
#define THREAD_CONTEXT_LR 0x058
#define THREAD_CONTEXT_SP 0x060
#define THREAD_CONTEXT_CPACR 0x068
#define THREAD_CONTEXT_FPCR 0x070
#define THREAD_CONTEXT_FPSR 0x078
#define THREAD_CONTEXT_FPU_REGISTERS 0x080
#define THREAD_CONTEXT_LOCKED 0x280
#define THREAD_CONTEXT_X19_X20 THREAD_CONTEXT_X19
#define THREAD_CONTEXT_X21_X22 THREAD_CONTEXT_X21
#define THREAD_CONTEXT_X23_X24 THREAD_CONTEXT_X23
#define THREAD_CONTEXT_X25_X26 THREAD_CONTEXT_X25
#define THREAD_CONTEXT_X27_X28 THREAD_CONTEXT_X27
#define THREAD_CONTEXT_X29_X30 THREAD_CONTEXT_X29
#define THREAD_CONTEXT_LR_SP THREAD_CONTEXT_LR
#define THREAD_CONTEXT_SP_CPACR THREAD_CONTEXT_SP
#define THREAD_CONTEXT_FPCR_FPSR THREAD_CONTEXT_FPCR
/* ams::kern::arch::arm64::KExceptionContext, https://github.com/Atmosphere-NX/Atmosphere/blob/master/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_exception_context.hpp */
#define EXCEPTION_CONTEXT_SIZE 0x120
#define EXCEPTION_CONTEXT_X0 0x000
#define EXCEPTION_CONTEXT_X1 0x008
#define EXCEPTION_CONTEXT_X2 0x010
#define EXCEPTION_CONTEXT_X3 0x018
#define EXCEPTION_CONTEXT_X4 0x020
#define EXCEPTION_CONTEXT_X5 0x028
#define EXCEPTION_CONTEXT_X6 0x030
#define EXCEPTION_CONTEXT_X7 0x038
#define EXCEPTION_CONTEXT_X8 0x040
#define EXCEPTION_CONTEXT_X9 0x048
#define EXCEPTION_CONTEXT_X10 0x050
#define EXCEPTION_CONTEXT_X11 0x058
#define EXCEPTION_CONTEXT_X12 0x060
#define EXCEPTION_CONTEXT_X13 0x068
#define EXCEPTION_CONTEXT_X14 0x070
#define EXCEPTION_CONTEXT_X15 0x078
#define EXCEPTION_CONTEXT_X16 0x080
#define EXCEPTION_CONTEXT_X17 0x088
#define EXCEPTION_CONTEXT_X18 0x090
#define EXCEPTION_CONTEXT_X19 0x098
#define EXCEPTION_CONTEXT_X20 0x0A0
#define EXCEPTION_CONTEXT_X21 0x0A8
#define EXCEPTION_CONTEXT_X22 0x0B0
#define EXCEPTION_CONTEXT_X23 0x0B8
#define EXCEPTION_CONTEXT_X24 0x0C0
#define EXCEPTION_CONTEXT_X25 0x0C8
#define EXCEPTION_CONTEXT_X26 0x0D0
#define EXCEPTION_CONTEXT_X27 0x0D8
#define EXCEPTION_CONTEXT_X28 0x0E0
#define EXCEPTION_CONTEXT_X29 0x0E8
#define EXCEPTION_CONTEXT_X30 0x0F0
#define EXCEPTION_CONTEXT_SP 0x0F8
#define EXCEPTION_CONTEXT_PC 0x100
#define EXCEPTION_CONTEXT_PSR 0x108
#define EXCEPTION_CONTEXT_TPIDR 0x110
#define EXCEPTION_CONTEXT_X0_X1 EXCEPTION_CONTEXT_X0
#define EXCEPTION_CONTEXT_X2_X3 EXCEPTION_CONTEXT_X2
#define EXCEPTION_CONTEXT_X4_X5 EXCEPTION_CONTEXT_X4
#define EXCEPTION_CONTEXT_X6_X7 EXCEPTION_CONTEXT_X6
#define EXCEPTION_CONTEXT_X8_X9 EXCEPTION_CONTEXT_X8
#define EXCEPTION_CONTEXT_X10_X11 EXCEPTION_CONTEXT_X10
#define EXCEPTION_CONTEXT_X12_X13 EXCEPTION_CONTEXT_X12
#define EXCEPTION_CONTEXT_X14_X15 EXCEPTION_CONTEXT_X14
#define EXCEPTION_CONTEXT_X16_X17 EXCEPTION_CONTEXT_X16
#define EXCEPTION_CONTEXT_X18_X19 EXCEPTION_CONTEXT_X18
#define EXCEPTION_CONTEXT_X20_X21 EXCEPTION_CONTEXT_X20
#define EXCEPTION_CONTEXT_X22_X23 EXCEPTION_CONTEXT_X22
#define EXCEPTION_CONTEXT_X24_X25 EXCEPTION_CONTEXT_X24
#define EXCEPTION_CONTEXT_X26_X27 EXCEPTION_CONTEXT_X26
#define EXCEPTION_CONTEXT_X28_X29 EXCEPTION_CONTEXT_X28
#define EXCEPTION_CONTEXT_X30_SP EXCEPTION_CONTEXT_X30
#define EXCEPTION_CONTEXT_PC_PSR EXCEPTION_CONTEXT_PC
#define EXCEPTION_CONTEXT_X9_X10 EXCEPTION_CONTEXT_X9
#define EXCEPTION_CONTEXT_X19_X20 EXCEPTION_CONTEXT_X19
#define EXCEPTION_CONTEXT_X21_X22 EXCEPTION_CONTEXT_X21
#define EXCEPTION_CONTEXT_X23_X24 EXCEPTION_CONTEXT_X23
#define EXCEPTION_CONTEXT_X25_X26 EXCEPTION_CONTEXT_X25
#define EXCEPTION_CONTEXT_X27_X28 EXCEPTION_CONTEXT_X27
#define EXCEPTION_CONTEXT_X29_X30 EXCEPTION_CONTEXT_X29
#define EXCEPTION_CONTEXT_SP_PC EXCEPTION_CONTEXT_SP
#define EXCEPTION_CONTEXT_PSR_TPIDR EXCEPTION_CONTEXT_PSR
/* ams::svc::arch::arm64::ThreadLocalRegion, https://github.com/Atmosphere-NX/Atmosphere/blob/master/libraries/libvapours/include/vapours/svc/arch/arm64/svc_thread_local_region.hpp */
#define THREAD_LOCAL_REGION_MESSAGE_BUFFER 0x000
#define THREAD_LOCAL_REGION_DISABLE_COUNT 0x100
#define THREAD_LOCAL_REGION_INTERRUPT_FLAG 0x102
#define THREAD_LOCAL_REGION_SIZE 0x200
/* ams::kern::init::KInitArguments, https://github.com/Atmosphere-NX/Atmosphere/blob/master/libraries/libmesosphere/include/mesosphere/arch/arm64/init/kern_k_init_arguments.hpp */
#define INIT_ARGUMENTS_SIZE 0x60
#define INIT_ARGUMENTS_TTBR0 0x00
#define INIT_ARGUMENTS_TTBR1 0x08
#define INIT_ARGUMENTS_TCR 0x10
#define INIT_ARGUMENTS_MAIR 0x18
#define INIT_ARGUMENTS_CPUACTLR 0x20
#define INIT_ARGUMENTS_CPUECTLR 0x28
#define INIT_ARGUMENTS_SCTLR 0x30
#define INIT_ARGUMENTS_SP 0x38
#define INIT_ARGUMENTS_ENTRYPOINT 0x40
#define INIT_ARGUMENTS_ARGUMENT 0x48
#define INIT_ARGUMENTS_SETUP_FUNCTION 0x50
#define INIT_ARGUMENTS_EXCEPTION_STACK 0x58
/* ams::kern::KScheduler (::SchedulingState), https://github.com/Atmosphere-NX/Atmosphere/blob/master/libraries/libmesosphere/include/mesosphere/kern_k_scheduler.hpp */
/* NOTE: Due to constraints on ldarb relative offsets, KSCHEDULER_NEEDS_SCHEDULING cannot trivially be changed, and will require assembly edits. */
#define KSCHEDULER_NEEDS_SCHEDULING 0x00
#define KSCHEDULER_INTERRUPT_TASK_THREAD_RUNNABLE 0x01
#define KSCHEDULER_HIGHEST_PRIORITY_THREAD 0x10
#define KSCHEDULER_IDLE_THREAD_STACK 0x18

View File

@@ -232,7 +232,7 @@ namespace ams::kern::arch::arm64::cpu {
} }
ALWAYS_INLINE void SetExceptionThreadStackTop(uintptr_t top) { ALWAYS_INLINE void SetExceptionThreadStackTop(uintptr_t top) {
SetTpidrEl1(top); cpu::SetCntvCvalEl0(top);
} }
ALWAYS_INLINE void SwitchThreadLocalRegion(uintptr_t tlr) { ALWAYS_INLINE void SwitchThreadLocalRegion(uintptr_t tlr) {

View File

@@ -74,6 +74,7 @@ namespace ams::kern::arch::arm64::cpu {
MESOSPHERE_CPU_DEFINE_SYSREG_ACCESSORS(CntkCtlEl1, cntkctl_el1) MESOSPHERE_CPU_DEFINE_SYSREG_ACCESSORS(CntkCtlEl1, cntkctl_el1)
MESOSPHERE_CPU_DEFINE_SYSREG_ACCESSORS(CntpCtlEl0, cntp_ctl_el0) MESOSPHERE_CPU_DEFINE_SYSREG_ACCESSORS(CntpCtlEl0, cntp_ctl_el0)
MESOSPHERE_CPU_DEFINE_SYSREG_ACCESSORS(CntpCvalEl0, cntp_cval_el0) MESOSPHERE_CPU_DEFINE_SYSREG_ACCESSORS(CntpCvalEl0, cntp_cval_el0)
MESOSPHERE_CPU_DEFINE_SYSREG_ACCESSORS(CntvCvalEl0, cntv_cval_el0)
MESOSPHERE_CPU_DEFINE_SYSREG_ACCESSORS(Daif, daif) MESOSPHERE_CPU_DEFINE_SYSREG_ACCESSORS(Daif, daif)
@@ -197,6 +198,11 @@ namespace ams::kern::arch::arm64::cpu {
public: public:
MESOSPHERE_CPU_SYSREG_ACCESSOR_CLASS_FUNCTIONS(TranslationControl, tcr_el1) MESOSPHERE_CPU_SYSREG_ACCESSOR_CLASS_FUNCTIONS(TranslationControl, tcr_el1)
constexpr ALWAYS_INLINE size_t GetT0Size() const {
const size_t shift_value = this->GetBits(0, 6);
return size_t(1) << (size_t(64) - shift_value);
}
constexpr ALWAYS_INLINE size_t GetT1Size() const { constexpr ALWAYS_INLINE size_t GetT1Size() const {
const size_t shift_value = this->GetBits(16, 6); const size_t shift_value = this->GetBits(16, 6);
return size_t(1) << (size_t(64) - shift_value); return size_t(1) << (size_t(64) - shift_value);

View File

@@ -43,6 +43,42 @@ namespace ams::kern::arch::arm64 {
} }
} }
}; };
static_assert(sizeof(KExceptionContext) == 0x120); static_assert(sizeof(KExceptionContext) == EXCEPTION_CONTEXT_SIZE);
static_assert(__builtin_offsetof(KExceptionContext, x[ 0]) == EXCEPTION_CONTEXT_X0);
static_assert(__builtin_offsetof(KExceptionContext, x[ 1]) == EXCEPTION_CONTEXT_X1);
static_assert(__builtin_offsetof(KExceptionContext, x[ 2]) == EXCEPTION_CONTEXT_X2);
static_assert(__builtin_offsetof(KExceptionContext, x[ 3]) == EXCEPTION_CONTEXT_X3);
static_assert(__builtin_offsetof(KExceptionContext, x[ 4]) == EXCEPTION_CONTEXT_X4);
static_assert(__builtin_offsetof(KExceptionContext, x[ 5]) == EXCEPTION_CONTEXT_X5);
static_assert(__builtin_offsetof(KExceptionContext, x[ 6]) == EXCEPTION_CONTEXT_X6);
static_assert(__builtin_offsetof(KExceptionContext, x[ 7]) == EXCEPTION_CONTEXT_X7);
static_assert(__builtin_offsetof(KExceptionContext, x[ 8]) == EXCEPTION_CONTEXT_X8);
static_assert(__builtin_offsetof(KExceptionContext, x[ 9]) == EXCEPTION_CONTEXT_X9);
static_assert(__builtin_offsetof(KExceptionContext, x[10]) == EXCEPTION_CONTEXT_X10);
static_assert(__builtin_offsetof(KExceptionContext, x[11]) == EXCEPTION_CONTEXT_X11);
static_assert(__builtin_offsetof(KExceptionContext, x[12]) == EXCEPTION_CONTEXT_X12);
static_assert(__builtin_offsetof(KExceptionContext, x[13]) == EXCEPTION_CONTEXT_X13);
static_assert(__builtin_offsetof(KExceptionContext, x[14]) == EXCEPTION_CONTEXT_X14);
static_assert(__builtin_offsetof(KExceptionContext, x[15]) == EXCEPTION_CONTEXT_X15);
static_assert(__builtin_offsetof(KExceptionContext, x[16]) == EXCEPTION_CONTEXT_X16);
static_assert(__builtin_offsetof(KExceptionContext, x[17]) == EXCEPTION_CONTEXT_X17);
static_assert(__builtin_offsetof(KExceptionContext, x[18]) == EXCEPTION_CONTEXT_X18);
static_assert(__builtin_offsetof(KExceptionContext, x[19]) == EXCEPTION_CONTEXT_X19);
static_assert(__builtin_offsetof(KExceptionContext, x[20]) == EXCEPTION_CONTEXT_X20);
static_assert(__builtin_offsetof(KExceptionContext, x[21]) == EXCEPTION_CONTEXT_X21);
static_assert(__builtin_offsetof(KExceptionContext, x[22]) == EXCEPTION_CONTEXT_X22);
static_assert(__builtin_offsetof(KExceptionContext, x[23]) == EXCEPTION_CONTEXT_X23);
static_assert(__builtin_offsetof(KExceptionContext, x[24]) == EXCEPTION_CONTEXT_X24);
static_assert(__builtin_offsetof(KExceptionContext, x[25]) == EXCEPTION_CONTEXT_X25);
static_assert(__builtin_offsetof(KExceptionContext, x[26]) == EXCEPTION_CONTEXT_X26);
static_assert(__builtin_offsetof(KExceptionContext, x[27]) == EXCEPTION_CONTEXT_X27);
static_assert(__builtin_offsetof(KExceptionContext, x[28]) == EXCEPTION_CONTEXT_X28);
static_assert(__builtin_offsetof(KExceptionContext, x[29]) == EXCEPTION_CONTEXT_X29);
static_assert(__builtin_offsetof(KExceptionContext, x[30]) == EXCEPTION_CONTEXT_X30);
static_assert(__builtin_offsetof(KExceptionContext, sp) == EXCEPTION_CONTEXT_SP);
static_assert(__builtin_offsetof(KExceptionContext, pc) == EXCEPTION_CONTEXT_PC);
static_assert(__builtin_offsetof(KExceptionContext, psr) == EXCEPTION_CONTEXT_PSR);
static_assert(__builtin_offsetof(KExceptionContext, tpidr) == EXCEPTION_CONTEXT_TPIDR);
} }

View File

@@ -85,7 +85,6 @@ namespace ams::kern::arch::arm64 {
NOINLINE Result BindHandler(KInterruptHandler *handler, s32 irq, s32 core_id, s32 priority, bool manual_clear, bool level); NOINLINE Result BindHandler(KInterruptHandler *handler, s32 irq, s32 core_id, s32 priority, bool manual_clear, bool level);
NOINLINE Result UnbindHandler(s32 irq, s32 core); NOINLINE Result UnbindHandler(s32 irq, s32 core);
NOINLINE Result ClearInterrupt(s32 irq);
NOINLINE Result ClearInterrupt(s32 irq, s32 core_id); NOINLINE Result ClearInterrupt(s32 irq, s32 core_id);
ALWAYS_INLINE void SendInterProcessorInterrupt(s32 irq, u64 core_mask) { ALWAYS_INLINE void SendInterProcessorInterrupt(s32 irq, u64 core_mask) {

View File

@@ -176,7 +176,7 @@ namespace ams::kern::arch::arm64 {
} }
NOINLINE Result InitializeForKernel(void *table, KVirtualAddress start, KVirtualAddress end); NOINLINE Result InitializeForKernel(void *table, KVirtualAddress start, KVirtualAddress end);
NOINLINE Result InitializeForProcess(u32 id, ams::svc::CreateProcessFlag as_type, bool enable_aslr, bool enable_das_merge, bool from_back, KMemoryManager::Pool pool, KProcessAddress code_address, size_t code_size, KMemoryBlockSlabManager *mem_block_slab_manager, KBlockInfoManager *block_info_manager, KPageTableManager *pt_manager); NOINLINE Result InitializeForProcess(u32 id, ams::svc::CreateProcessFlag as_type, bool enable_aslr, bool enable_das_merge, bool from_back, KMemoryManager::Pool pool, KProcessAddress code_address, size_t code_size, KMemoryBlockSlabManager *mem_block_slab_manager, KBlockInfoManager *block_info_manager, KPageTableManager *pt_manager, KResourceLimit *resource_limit);
Result Finalize(); Result Finalize();
private: private:
Result MapL1Blocks(KProcessAddress virt_addr, KPhysicalAddress phys_addr, size_t num_pages, PageTableEntry entry_template, bool disable_head_merge, PageLinkedList *page_list, bool reuse_ll); Result MapL1Blocks(KProcessAddress virt_addr, KPhysicalAddress phys_addr, size_t num_pages, PageTableEntry entry_template, bool disable_head_merge, PageLinkedList *page_list, bool reuse_ll);

View File

@@ -30,12 +30,16 @@ namespace ams::kern::arch::arm64 {
m_page_table.Activate(id); m_page_table.Activate(id);
} }
Result Initialize(u32 id, ams::svc::CreateProcessFlag as_type, bool enable_aslr, bool enable_das_merge, bool from_back, KMemoryManager::Pool pool, KProcessAddress code_address, size_t code_size, KMemoryBlockSlabManager *mem_block_slab_manager, KBlockInfoManager *block_info_manager, KPageTableManager *pt_manager) { Result Initialize(u32 id, ams::svc::CreateProcessFlag as_type, bool enable_aslr, bool enable_das_merge, bool from_back, KMemoryManager::Pool pool, KProcessAddress code_address, size_t code_size, KMemoryBlockSlabManager *mem_block_slab_manager, KBlockInfoManager *block_info_manager, KPageTableManager *pt_manager, KResourceLimit *resource_limit) {
return m_page_table.InitializeForProcess(id, as_type, enable_aslr, enable_das_merge, from_back, pool, code_address, code_size, mem_block_slab_manager, block_info_manager, pt_manager); return m_page_table.InitializeForProcess(id, as_type, enable_aslr, enable_das_merge, from_back, pool, code_address, code_size, mem_block_slab_manager, block_info_manager, pt_manager, resource_limit);
} }
void Finalize() { m_page_table.Finalize(); } void Finalize() { m_page_table.Finalize(); }
ALWAYS_INLINE KScopedLightLock AcquireDeviceMapLock() {
return m_page_table.AcquireDeviceMapLock();
}
Result SetMemoryPermission(KProcessAddress addr, size_t size, ams::svc::MemoryPermission perm) { Result SetMemoryPermission(KProcessAddress addr, size_t size, ams::svc::MemoryPermission perm) {
return m_page_table.SetMemoryPermission(addr, size, perm); return m_page_table.SetMemoryPermission(addr, size, perm);
} }
@@ -136,26 +140,42 @@ namespace ams::kern::arch::arm64 {
return m_page_table.ReadDebugMemory(buffer, address, size); return m_page_table.ReadDebugMemory(buffer, address, size);
} }
Result ReadDebugIoMemory(void *buffer, KProcessAddress address, size_t size) {
return m_page_table.ReadDebugIoMemory(buffer, address, size);
}
Result WriteDebugMemory(KProcessAddress address, const void *buffer, size_t size) { Result WriteDebugMemory(KProcessAddress address, const void *buffer, size_t size) {
return m_page_table.WriteDebugMemory(address, buffer, size); return m_page_table.WriteDebugMemory(address, buffer, size);
} }
Result LockForDeviceAddressSpace(KPageGroup *out, KProcessAddress address, size_t size, KMemoryPermission perm, bool is_aligned) { Result WriteDebugIoMemory(KProcessAddress address, const void *buffer, size_t size) {
return m_page_table.LockForDeviceAddressSpace(out, address, size, perm, is_aligned); return m_page_table.WriteDebugIoMemory(address, buffer, size);
}
Result LockForMapDeviceAddressSpace(KProcessAddress address, size_t size, KMemoryPermission perm, bool is_aligned) {
return m_page_table.LockForMapDeviceAddressSpace(address, size, perm, is_aligned);
}
Result LockForUnmapDeviceAddressSpace(KProcessAddress address, size_t size) {
return m_page_table.LockForUnmapDeviceAddressSpace(address, size);
} }
Result UnlockForDeviceAddressSpace(KProcessAddress address, size_t size) { Result UnlockForDeviceAddressSpace(KProcessAddress address, size_t size) {
return m_page_table.UnlockForDeviceAddressSpace(address, size); return m_page_table.UnlockForDeviceAddressSpace(address, size);
} }
Result MakePageGroupForUnmapDeviceAddressSpace(KPageGroup *out, KProcessAddress address, size_t size) {
return m_page_table.MakePageGroupForUnmapDeviceAddressSpace(out, address, size);
}
Result UnlockForDeviceAddressSpacePartialMap(KProcessAddress address, size_t size, size_t mapped_size) { Result UnlockForDeviceAddressSpacePartialMap(KProcessAddress address, size_t size, size_t mapped_size) {
return m_page_table.UnlockForDeviceAddressSpacePartialMap(address, size, mapped_size); return m_page_table.UnlockForDeviceAddressSpacePartialMap(address, size, mapped_size);
} }
Result OpenMemoryRangeForMapDeviceAddressSpace(KPageTableBase::MemoryRange *out, KProcessAddress address, size_t size, KMemoryPermission perm, bool is_aligned) {
return m_page_table.OpenMemoryRangeForMapDeviceAddressSpace(out, address, size, perm, is_aligned);
}
Result OpenMemoryRangeForUnmapDeviceAddressSpace(KPageTableBase::MemoryRange *out, KProcessAddress address, size_t size) {
return m_page_table.OpenMemoryRangeForUnmapDeviceAddressSpace(out, address, size);
}
Result LockForIpcUserBuffer(KPhysicalAddress *out, KProcessAddress address, size_t size) { Result LockForIpcUserBuffer(KPhysicalAddress *out, KProcessAddress address, size_t size) {
return m_page_table.LockForIpcUserBuffer(out, address, size); return m_page_table.LockForIpcUserBuffer(out, address, size);
} }
@@ -180,6 +200,10 @@ namespace ams::kern::arch::arm64 {
return m_page_table.UnlockForCodeMemory(address, size, pg); return m_page_table.UnlockForCodeMemory(address, size, pg);
} }
Result OpenMemoryRangeForProcessCacheOperation(KPageTableBase::MemoryRange *out, KProcessAddress address, size_t size) {
return m_page_table.OpenMemoryRangeForProcessCacheOperation(out, address, size);
}
Result CopyMemoryFromLinearToUser(KProcessAddress dst_addr, size_t size, KProcessAddress src_addr, u32 src_state_mask, u32 src_state, KMemoryPermission src_test_perm, u32 src_attr_mask, u32 src_attr) { Result CopyMemoryFromLinearToUser(KProcessAddress dst_addr, size_t size, KProcessAddress src_addr, u32 src_state_mask, u32 src_state, KMemoryPermission src_test_perm, u32 src_attr_mask, u32 src_attr) {
return m_page_table.CopyMemoryFromLinearToUser(dst_addr, size, src_addr, src_state_mask, src_state, src_test_perm, src_attr_mask, src_attr); return m_page_table.CopyMemoryFromLinearToUser(dst_addr, size, src_addr, src_state_mask, src_state, src_test_perm, src_attr_mask, src_attr);
} }
@@ -208,8 +232,8 @@ namespace ams::kern::arch::arm64 {
return m_page_table.SetupForIpc(out_dst_addr, size, src_addr, src_page_table.m_page_table, test_perm, dst_state, send); return m_page_table.SetupForIpc(out_dst_addr, size, src_addr, src_page_table.m_page_table, test_perm, dst_state, send);
} }
Result CleanupForIpcServer(KProcessAddress address, size_t size, KMemoryState dst_state, KProcess *server_process) { Result CleanupForIpcServer(KProcessAddress address, size_t size, KMemoryState dst_state) {
return m_page_table.CleanupForIpcServer(address, size, dst_state, server_process); return m_page_table.CleanupForIpcServer(address, size, dst_state);
} }
Result CleanupForIpcClient(KProcessAddress address, size_t size, KMemoryState dst_state) { Result CleanupForIpcClient(KProcessAddress address, size_t size, KMemoryState dst_state) {
@@ -232,6 +256,10 @@ namespace ams::kern::arch::arm64 {
return m_page_table.UnmapPhysicalMemoryUnsafe(address, size); return m_page_table.UnmapPhysicalMemoryUnsafe(address, size);
} }
Result UnmapProcessMemory(KProcessAddress dst_address, size_t size, KProcessPageTable &src_page_table, KProcessAddress src_address) {
return m_page_table.UnmapProcessMemory(dst_address, size, src_page_table.m_page_table, src_address);
}
void DumpMemoryBlocks() const { void DumpMemoryBlocks() const {
return m_page_table.DumpMemoryBlocks(); return m_page_table.DumpMemoryBlocks();
} }
@@ -290,6 +318,10 @@ namespace ams::kern::arch::arm64 {
KBlockInfoManager *GetBlockInfoManager() { KBlockInfoManager *GetBlockInfoManager() {
return m_page_table.GetBlockInfoManager(); return m_page_table.GetBlockInfoManager();
} }
KPageTableBase &GetBasePageTable() {
return m_page_table;
}
}; };
} }

View File

@@ -79,8 +79,38 @@ namespace ams::kern::arch::arm64 {
const u128 *GetFpuRegisters() const { return m_fpu_registers; } const u128 *GetFpuRegisters() const { return m_fpu_registers; }
public: public:
static void OnThreadTerminating(const KThread *thread); static void OnThreadTerminating(const KThread *thread);
public:
static consteval bool ValidateOffsets();
}; };
consteval bool KThreadContext::ValidateOffsets() {
static_assert(sizeof(KThreadContext) == THREAD_CONTEXT_SIZE);
static_assert(__builtin_offsetof(KThreadContext, m_callee_saved.registers) == THREAD_CONTEXT_CPU_REGISTERS);
static_assert(__builtin_offsetof(KThreadContext, m_callee_saved.x19) == THREAD_CONTEXT_X19);
static_assert(__builtin_offsetof(KThreadContext, m_callee_saved.x20) == THREAD_CONTEXT_X20);
static_assert(__builtin_offsetof(KThreadContext, m_callee_saved.x21) == THREAD_CONTEXT_X21);
static_assert(__builtin_offsetof(KThreadContext, m_callee_saved.x22) == THREAD_CONTEXT_X22);
static_assert(__builtin_offsetof(KThreadContext, m_callee_saved.x23) == THREAD_CONTEXT_X23);
static_assert(__builtin_offsetof(KThreadContext, m_callee_saved.x24) == THREAD_CONTEXT_X24);
static_assert(__builtin_offsetof(KThreadContext, m_callee_saved.x25) == THREAD_CONTEXT_X25);
static_assert(__builtin_offsetof(KThreadContext, m_callee_saved.x26) == THREAD_CONTEXT_X26);
static_assert(__builtin_offsetof(KThreadContext, m_callee_saved.x27) == THREAD_CONTEXT_X27);
static_assert(__builtin_offsetof(KThreadContext, m_callee_saved.x28) == THREAD_CONTEXT_X28);
static_assert(__builtin_offsetof(KThreadContext, m_callee_saved.x29) == THREAD_CONTEXT_X29);
static_assert(__builtin_offsetof(KThreadContext, m_lr) == THREAD_CONTEXT_LR);
static_assert(__builtin_offsetof(KThreadContext, m_sp) == THREAD_CONTEXT_SP);
static_assert(__builtin_offsetof(KThreadContext, m_cpacr) == THREAD_CONTEXT_CPACR);
static_assert(__builtin_offsetof(KThreadContext, m_fpcr) == THREAD_CONTEXT_FPCR);
static_assert(__builtin_offsetof(KThreadContext, m_fpsr) == THREAD_CONTEXT_FPSR);
static_assert(__builtin_offsetof(KThreadContext, m_fpu_registers) == THREAD_CONTEXT_FPU_REGISTERS);
static_assert(__builtin_offsetof(KThreadContext, m_locked) == THREAD_CONTEXT_LOCKED);
return true;
}
static_assert(KThreadContext::ValidateOffsets());
void GetUserContext(ams::svc::ThreadContext *out, const KThread *thread); void GetUserContext(ams::svc::ThreadContext *out, const KThread *thread);
} }

View File

@@ -69,8 +69,8 @@ namespace ams::kern::board::nintendo::nx {
Result Attach(ams::svc::DeviceName device_name, u64 space_address, u64 space_size); Result Attach(ams::svc::DeviceName device_name, u64 space_address, u64 space_size);
Result Detach(ams::svc::DeviceName device_name); Result Detach(ams::svc::DeviceName device_name);
Result Map(size_t *out_mapped_size, const KPageGroup &pg, KDeviceVirtualAddress device_address, ams::svc::MemoryPermission device_perm, bool refresh_mappings); Result Map(size_t *out_mapped_size, KProcessPageTable *page_table, KProcessAddress process_address, size_t size, KDeviceVirtualAddress device_address, ams::svc::MemoryPermission device_perm, bool is_aligned, bool refresh_mappings);
Result Unmap(const KPageGroup &pg, KDeviceVirtualAddress device_address); Result Unmap(KProcessPageTable *page_table, KProcessAddress process_address, size_t size, KDeviceVirtualAddress device_address);
void Unmap(KDeviceVirtualAddress device_address, size_t size) { void Unmap(KDeviceVirtualAddress device_address, size_t size) {
return this->UnmapImpl(device_address, size, false); return this->UnmapImpl(device_address, size, false);
@@ -78,12 +78,11 @@ namespace ams::kern::board::nintendo::nx {
private: private:
Result MapDevicePage(size_t *out_mapped_size, s32 &num_pt, s32 max_pt, KPhysicalAddress phys_addr, u64 size, KDeviceVirtualAddress address, ams::svc::MemoryPermission device_perm); Result MapDevicePage(size_t *out_mapped_size, s32 &num_pt, s32 max_pt, KPhysicalAddress phys_addr, u64 size, KDeviceVirtualAddress address, ams::svc::MemoryPermission device_perm);
Result MapImpl(size_t *out_mapped_size, s32 &num_pt, s32 max_pt, const KPageGroup &pg, KDeviceVirtualAddress device_address, ams::svc::MemoryPermission device_perm); Result MapImpl(size_t *out_mapped_size, s32 &num_pt, s32 max_pt, KProcessPageTable *page_table, KProcessAddress process_address, size_t size, KDeviceVirtualAddress device_address, ams::svc::MemoryPermission device_perm, bool is_aligned);
void UnmapImpl(KDeviceVirtualAddress address, u64 size, bool force); void UnmapImpl(KDeviceVirtualAddress address, u64 size, bool force);
bool IsFree(KDeviceVirtualAddress address, u64 size) const; bool IsFree(KDeviceVirtualAddress address, u64 size) const;
Result MakePageGroup(KPageGroup *out, KDeviceVirtualAddress address, u64 size) const; bool Compare(KProcessPageTable *page_table, KProcessAddress process_address, size_t size, KDeviceVirtualAddress device_address) const;
bool Compare(const KPageGroup &pg, KDeviceVirtualAddress device_address) const;
public: public:
static void Initialize(); static void Initialize();

View File

@@ -25,6 +25,7 @@ namespace ams::kern::board::nintendo::nx {
/* Initialization. */ /* Initialization. */
static size_t GetIntendedMemorySize(); static size_t GetIntendedMemorySize();
static KPhysicalAddress GetKernelPhysicalBaseAddress(uintptr_t base_address); static KPhysicalAddress GetKernelPhysicalBaseAddress(uintptr_t base_address);
static KPhysicalAddress GetInitialProcessBinaryPhysicalAddress();
static bool ShouldIncreaseThreadResourceLimit(); static bool ShouldIncreaseThreadResourceLimit();
static void CpuOn(u64 core_id, uintptr_t entrypoint, uintptr_t arg); static void CpuOn(u64 core_id, uintptr_t entrypoint, uintptr_t arg);
static size_t GetApplicationPoolSize(); static size_t GetApplicationPoolSize();

View File

@@ -24,6 +24,8 @@
namespace ams::kern::init { namespace ams::kern::init {
static_assert(util::IsPowerOfTwo(alignof(KInitArguments)) && util::IsPowerOfTwo(sizeof(KInitArguments)));
KPhysicalAddress GetInitArgumentsAddress(s32 core_id); KPhysicalAddress GetInitArgumentsAddress(s32 core_id);
} }

View File

@@ -27,7 +27,7 @@ namespace ams::kern::init {
u32 rw_end_offset; u32 rw_end_offset;
u32 bss_offset; u32 bss_offset;
u32 bss_end_offset; u32 bss_end_offset;
u32 ini_load_offset; u32 resource_offset;
u32 dynamic_offset; u32 dynamic_offset;
u32 init_array_offset; u32 init_array_offset;
u32 init_array_end_offset; u32 init_array_end_offset;

View File

@@ -17,6 +17,7 @@
#include <vapours.hpp> #include <vapours.hpp>
#include <mesosphere/kern_build_config.hpp> #include <mesosphere/kern_build_config.hpp>
#include <mesosphere/svc/kern_svc_results.hpp> #include <mesosphere/svc/kern_svc_results.hpp>
#include <mesosphere/kern_select_assembly_offsets.h>
namespace ams::kern { namespace ams::kern {

View File

@@ -29,11 +29,14 @@ namespace ams::kern {
u32 reserved; u32 reserved;
}; };
NOINLINE void CopyInitialProcessBinaryToKernelMemory(); NOINLINE size_t CopyInitialProcessBinaryToKernelMemory();
NOINLINE void CreateAndRunInitialProcesses(); NOINLINE void CreateAndRunInitialProcesses();
u64 GetInitialProcessIdMin(); u64 GetInitialProcessIdMin();
u64 GetInitialProcessIdMax(); u64 GetInitialProcessIdMax();
KVirtualAddress GetInitialProcessBinaryAddress();
size_t GetInitialProcessesSecureMemorySize(); size_t GetInitialProcessesSecureMemorySize();
void LoadInitialProcessBinaryHeaderDeprecated(KPhysicalAddress pool_end);
} }

View File

@@ -69,11 +69,12 @@ namespace ams::kern {
private: private:
MESOSPHERE_AUTOOBJECT_TRAITS(KAutoObject, KAutoObject); MESOSPHERE_AUTOOBJECT_TRAITS(KAutoObject, KAutoObject);
private: private:
KAutoObject *m_next_closed_object;
std::atomic<u32> m_ref_count; std::atomic<u32> m_ref_count;
public: public:
static KAutoObject *Create(KAutoObject *ptr); static KAutoObject *Create(KAutoObject *ptr);
public: public:
constexpr ALWAYS_INLINE explicit KAutoObject() : m_ref_count(0) { MESOSPHERE_ASSERT_THIS(); } constexpr ALWAYS_INLINE explicit KAutoObject() : m_next_closed_object(nullptr), m_ref_count(0) { MESOSPHERE_ASSERT_THIS(); }
virtual ~KAutoObject() { MESOSPHERE_ASSERT_THIS(); } virtual ~KAutoObject() { MESOSPHERE_ASSERT_THIS(); }
/* Destroy is responsible for destroying the auto object's resources when ref_count hits zero. */ /* Destroy is responsible for destroying the auto object's resources when ref_count hits zero. */
@@ -120,36 +121,16 @@ namespace ams::kern {
} }
} }
ALWAYS_INLINE bool Open() { bool Open();
MESOSPHERE_ASSERT_THIS(); void Close();
private:
/* Atomically increment the reference count, only if it's positive. */ /* NOTE: This has to be defined *after* KThread is defined. */
u32 cur_ref_count = m_ref_count.load(std::memory_order_acquire); /* Nintendo seems to handle this by defining Open/Close() in a cpp, but we'd like them to remain in headers. */
do { /* Implementation for this will be inside kern_k_thread.hpp, so it can be ALWAYS_INLINE. */
if (AMS_UNLIKELY(cur_ref_count == 0)) { void ScheduleDestruction();
MESOSPHERE_AUDIT(cur_ref_count != 0); public:
return false; /* Getter, for KThread. */
} ALWAYS_INLINE KAutoObject *GetNextClosedObject() { return m_next_closed_object; }
MESOSPHERE_ABORT_UNLESS(cur_ref_count < cur_ref_count + 1);
} while (!m_ref_count.compare_exchange_weak(cur_ref_count, cur_ref_count + 1, std::memory_order_relaxed));
return true;
}
ALWAYS_INLINE void Close() {
MESOSPHERE_ASSERT_THIS();
/* Atomically decrement the reference count, not allowing it to become negative. */
u32 cur_ref_count = m_ref_count.load(std::memory_order_acquire);
do {
MESOSPHERE_ABORT_UNLESS(cur_ref_count > 0);
} while (!m_ref_count.compare_exchange_weak(cur_ref_count, cur_ref_count - 1, std::memory_order_relaxed));
/* If ref count hits zero, destroy the object. */
if (cur_ref_count - 1 == 0) {
this->Destroy();
}
}
}; };
class KAutoObjectWithListContainer; class KAutoObjectWithListContainer;
@@ -198,7 +179,7 @@ namespace ams::kern {
} }
} }
~KScopedAutoObject() { ALWAYS_INLINE ~KScopedAutoObject() {
if (m_obj != nullptr) { if (m_obj != nullptr) {
m_obj->Close(); m_obj->Close();
} }

View File

@@ -47,6 +47,7 @@ namespace ams::kern {
ALWAYS_INLINE s32 GetMaxSessions() const { return m_max_sessions; } ALWAYS_INLINE s32 GetMaxSessions() const { return m_max_sessions; }
bool IsLight() const; bool IsLight() const;
bool IsServerClosed() const;
/* Overridden virtual functions. */ /* Overridden virtual functions. */
virtual void Destroy() override; virtual void Destroy() override;

View File

@@ -23,7 +23,7 @@ namespace ams::kern {
class KCodeMemory final : public KAutoObjectWithSlabHeapAndContainer<KCodeMemory, KAutoObjectWithList> { class KCodeMemory final : public KAutoObjectWithSlabHeapAndContainer<KCodeMemory, KAutoObjectWithList> {
MESOSPHERE_AUTOOBJECT_TRAITS(KCodeMemory, KAutoObject); MESOSPHERE_AUTOOBJECT_TRAITS(KCodeMemory, KAutoObject);
private: private:
TYPED_STORAGE(KPageGroup) m_page_group; util::TypedStorage<KPageGroup> m_page_group;
KProcess *m_owner; KProcess *m_owner;
KProcessAddress m_address; KProcessAddress m_address;
KLightLock m_lock; KLightLock m_lock;

View File

@@ -36,7 +36,7 @@ namespace ams::kern {
void Signal(uintptr_t cv_key, s32 count); void Signal(uintptr_t cv_key, s32 count);
Result Wait(KProcessAddress addr, uintptr_t key, u32 value, s64 timeout); Result Wait(KProcessAddress addr, uintptr_t key, u32 value, s64 timeout);
private: private:
KThread *SignalImpl(KThread *thread); void SignalImpl(KThread *thread);
}; };
ALWAYS_INLINE void BeforeUpdatePriority(KConditionVariable::ThreadTree *tree, KThread *thread) { ALWAYS_INLINE void BeforeUpdatePriority(KConditionVariable::ThreadTree *tree, KThread *thread) {

View File

@@ -64,8 +64,11 @@ namespace ams::kern {
m_page_bitmap.Initialize(management_ptr, m_count); m_page_bitmap.Initialize(management_ptr, m_count);
/* Free the pages to the bitmap. */ /* Free the pages to the bitmap. */
std::memset(GetPointer<PageBuffer>(m_address), 0, m_count * sizeof(PageBuffer));
for (size_t i = 0; i < m_count; i++) { for (size_t i = 0; i < m_count; i++) {
/* Ensure the freed page is all-zero. */
cpu::ClearPageToZero(GetPointer<PageBuffer>(m_address) + i);
/* Set the bit for the free page. */
m_page_bitmap.SetBit(i); m_page_bitmap.SetBit(i);
} }
@@ -99,6 +102,9 @@ namespace ams::kern {
} }
void Free(PageBuffer *pb) { void Free(PageBuffer *pb) {
/* Ensure all pages in the heap are zero. */
cpu::ClearPageToZero(pb);
/* Take the lock. */ /* Take the lock. */
KScopedInterruptDisable di; KScopedInterruptDisable di;
KScopedSpinLock lk(m_lock); KScopedSpinLock lk(m_lock);

View File

@@ -22,7 +22,7 @@
namespace ams::kern { namespace ams::kern {
template<typename T> template<typename T, bool ClearNode = false>
class KDynamicSlabHeap { class KDynamicSlabHeap {
NON_COPYABLE(KDynamicSlabHeap); NON_COPYABLE(KDynamicSlabHeap);
NON_MOVEABLE(KDynamicSlabHeap); NON_MOVEABLE(KDynamicSlabHeap);
@@ -97,6 +97,13 @@ namespace ams::kern {
T *Allocate() { T *Allocate() {
T *allocated = reinterpret_cast<T *>(this->GetImpl()->Allocate()); T *allocated = reinterpret_cast<T *>(this->GetImpl()->Allocate());
/* If we successfully allocated and we should clear the node, do so. */
if constexpr (ClearNode) {
if (AMS_LIKELY(allocated != nullptr)) {
reinterpret_cast<Impl::Node *>(allocated)->next = nullptr;
}
}
/* If we fail to allocate, try to get a new page from our next allocator. */ /* If we fail to allocate, try to get a new page from our next allocator. */
if (AMS_UNLIKELY(allocated == nullptr)) { if (AMS_UNLIKELY(allocated == nullptr)) {
if (m_page_allocator != nullptr) { if (m_page_allocator != nullptr) {
@@ -113,7 +120,7 @@ namespace ams::kern {
if (AMS_LIKELY(allocated != nullptr)) { if (AMS_LIKELY(allocated != nullptr)) {
/* Construct the object. */ /* Construct the object. */
new (allocated) T(); std::construct_at(allocated);
/* Update our tracking. */ /* Update our tracking. */
size_t used = m_used.fetch_add(1) + 1; size_t used = m_used.fetch_add(1) + 1;

View File

@@ -53,46 +53,29 @@ namespace ams::kern {
return pack.Get<HandleEncoded>(); return pack.Get<HandleEncoded>();
} }
class Entry { union EntryInfo {
private: struct {
union { u16 linear_id;
struct { u16 type;
u16 linear_id; } info;
u16 type; s32 next_free_index;
} info;
Entry *next_free_entry;
} m_meta;
KAutoObject *m_object;
public:
constexpr Entry() : m_meta(), m_object(nullptr) { /* ... */ }
constexpr ALWAYS_INLINE void SetFree(Entry *next) { constexpr ALWAYS_INLINE u16 GetLinearId() const { return info.linear_id; }
m_object = nullptr; constexpr ALWAYS_INLINE u16 GetType() const { return info.type; }
m_meta.next_free_entry = next; constexpr ALWAYS_INLINE s32 GetNextFreeIndex() const { return next_free_index; }
}
constexpr ALWAYS_INLINE void SetUsed(KAutoObject *obj, u16 linear_id, u16 type) {
m_object = obj;
m_meta.info = { linear_id, type };
}
constexpr ALWAYS_INLINE KAutoObject *GetObject() const { return m_object; }
constexpr ALWAYS_INLINE Entry *GetNextFreeEntry() const { return m_meta.next_free_entry; }
constexpr ALWAYS_INLINE u16 GetLinearId() const { return m_meta.info.linear_id; }
constexpr ALWAYS_INLINE u16 GetType() const { return m_meta.info.type; }
}; };
private: private:
mutable KSpinLock m_lock; EntryInfo m_entry_infos[MaxTableSize];
Entry *m_table; KAutoObject *m_objects[MaxTableSize];
Entry *m_free_head; s32 m_free_head_index;
Entry m_entries[MaxTableSize];
u16 m_table_size; u16 m_table_size;
u16 m_max_count; u16 m_max_count;
u16 m_next_linear_id; u16 m_next_linear_id;
u16 m_count; u16 m_count;
mutable KSpinLock m_lock;
public: public:
constexpr KHandleTable() : constexpr KHandleTable() :
m_lock(), m_table(nullptr), m_free_head(nullptr), m_entries(), m_table_size(0), m_max_count(0), m_next_linear_id(MinLinearId), m_count(0) m_entry_infos(), m_objects(), m_free_head_index(-1), m_table_size(0), m_max_count(0), m_next_linear_id(MinLinearId), m_count(0), m_lock()
{ MESOSPHERE_ASSERT_THIS(); } { MESOSPHERE_ASSERT_THIS(); }
constexpr NOINLINE Result Initialize(s32 size) { constexpr NOINLINE Result Initialize(s32 size) {
@@ -101,19 +84,18 @@ namespace ams::kern {
R_UNLESS(size <= static_cast<s32>(MaxTableSize), svc::ResultOutOfMemory()); R_UNLESS(size <= static_cast<s32>(MaxTableSize), svc::ResultOutOfMemory());
/* Initialize all fields. */ /* Initialize all fields. */
m_table = m_entries; m_max_count = 0;
m_table_size = (size <= 0) ? MaxTableSize : size; m_table_size = (size <= 0) ? MaxTableSize : size;
m_next_linear_id = MinLinearId; m_next_linear_id = MinLinearId;
m_count = 0; m_count = 0;
m_max_count = 0; m_free_head_index = -1;
/* Free all entries. */ /* Free all entries. */
for (size_t i = 0; i < static_cast<size_t>(m_table_size - 1); i++) { for (s32 i = 0; i < static_cast<s32>(m_table_size); ++i) {
m_entries[i].SetFree(std::addressof(m_entries[i + 1])); m_objects[i] = nullptr;
m_entry_infos[i].next_free_index = i - 1;
m_free_head_index = i;
} }
m_entries[m_table_size - 1].SetFree(nullptr);
m_free_head = std::addressof(m_entries[0]);
return ResultSuccess(); return ResultSuccess();
} }
@@ -134,7 +116,7 @@ namespace ams::kern {
if constexpr (std::is_same<T, KAutoObject>::value) { if constexpr (std::is_same<T, KAutoObject>::value) {
return this->GetObjectImpl(handle); return this->GetObjectImpl(handle);
} else { } else {
if (auto *obj = this->GetObjectImpl(handle); obj != nullptr) { if (auto *obj = this->GetObjectImpl(handle); AMS_LIKELY(obj != nullptr)) {
return obj->DynamicCast<T*>(); return obj->DynamicCast<T*>();
} else { } else {
return nullptr; return nullptr;
@@ -149,11 +131,15 @@ namespace ams::kern {
/* Handle pseudo-handles. */ /* Handle pseudo-handles. */
if constexpr (std::derived_from<KProcess, T>) { if constexpr (std::derived_from<KProcess, T>) {
if (handle == ams::svc::PseudoHandle::CurrentProcess) { if (handle == ams::svc::PseudoHandle::CurrentProcess) {
return GetCurrentProcessPointer(); auto * const cur_process = GetCurrentProcessPointer();
AMS_ASSUME(cur_process != nullptr);
return cur_process;
} }
} else if constexpr (std::derived_from<KThread, T>) { } else if constexpr (std::derived_from<KThread, T>) {
if (handle == ams::svc::PseudoHandle::CurrentThread) { if (handle == ams::svc::PseudoHandle::CurrentThread) {
return GetCurrentThreadPointer(); auto * const cur_thread = GetCurrentThreadPointer();
AMS_ASSUME(cur_thread != nullptr);
return cur_thread;
} }
} }
@@ -177,8 +163,11 @@ namespace ams::kern {
ALWAYS_INLINE KScopedAutoObject<KAutoObject> GetObjectForIpc(ams::svc::Handle handle, KThread *cur_thread) const { ALWAYS_INLINE KScopedAutoObject<KAutoObject> GetObjectForIpc(ams::svc::Handle handle, KThread *cur_thread) const {
/* Handle pseudo-handles. */ /* Handle pseudo-handles. */
AMS_ASSUME(cur_thread != nullptr);
if (handle == ams::svc::PseudoHandle::CurrentProcess) { if (handle == ams::svc::PseudoHandle::CurrentProcess) {
return static_cast<KAutoObject *>(static_cast<void *>(cur_thread->GetOwnerProcess())); auto * const cur_process = static_cast<KAutoObject *>(static_cast<void *>(cur_thread->GetOwnerProcess()));
AMS_ASSUME(cur_process != nullptr);
return cur_process;
} }
if (handle == ams::svc::PseudoHandle::CurrentThread) { if (handle == ams::svc::PseudoHandle::CurrentThread) {
return static_cast<KAutoObject *>(cur_thread); return static_cast<KAutoObject *>(cur_thread);
@@ -256,27 +245,29 @@ namespace ams::kern {
NOINLINE Result Add(ams::svc::Handle *out_handle, KAutoObject *obj, u16 type); NOINLINE Result Add(ams::svc::Handle *out_handle, KAutoObject *obj, u16 type);
NOINLINE void Register(ams::svc::Handle handle, KAutoObject *obj, u16 type); NOINLINE void Register(ams::svc::Handle handle, KAutoObject *obj, u16 type);
constexpr ALWAYS_INLINE Entry *AllocateEntry() { constexpr ALWAYS_INLINE s32 AllocateEntry() {
MESOSPHERE_ASSERT_THIS(); MESOSPHERE_ASSERT_THIS();
MESOSPHERE_ASSERT(m_count < m_table_size); MESOSPHERE_ASSERT(m_count < m_table_size);
Entry *entry = m_free_head; const auto index = m_free_head_index;
m_free_head = entry->GetNextFreeEntry();
m_count++; m_free_head_index = m_entry_infos[index].GetNextFreeIndex();
m_max_count = std::max(m_max_count, m_count);
return entry; m_max_count = std::max(m_max_count, ++m_count);
return index;
} }
constexpr ALWAYS_INLINE void FreeEntry(Entry *entry) { constexpr ALWAYS_INLINE void FreeEntry(s32 index) {
MESOSPHERE_ASSERT_THIS(); MESOSPHERE_ASSERT_THIS();
MESOSPHERE_ASSERT(m_count > 0); MESOSPHERE_ASSERT(m_count > 0);
entry->SetFree(m_free_head); m_objects[index] = nullptr;
m_free_head = entry; m_entry_infos[index].next_free_index = m_free_head_index;
m_count--; m_free_head_index = index;
--m_count;
} }
constexpr ALWAYS_INLINE u16 AllocateLinearId() { constexpr ALWAYS_INLINE u16 AllocateLinearId() {
@@ -287,13 +278,7 @@ namespace ams::kern {
return id; return id;
} }
constexpr ALWAYS_INLINE size_t GetEntryIndex(Entry *entry) { constexpr ALWAYS_INLINE bool IsValidHandle(ams::svc::Handle handle) const {
const size_t index = entry - m_table;
MESOSPHERE_ASSERT(index < m_table_size);
return index;
}
constexpr ALWAYS_INLINE Entry *FindEntry(ams::svc::Handle handle) const {
MESOSPHERE_ASSERT_THIS(); MESOSPHERE_ASSERT_THIS();
/* Unpack the handle. */ /* Unpack the handle. */
@@ -306,38 +291,38 @@ namespace ams::kern {
MESOSPHERE_UNUSED(reserved); MESOSPHERE_UNUSED(reserved);
/* Validate our indexing information. */ /* Validate our indexing information. */
if (raw_value == 0) { if (AMS_UNLIKELY(raw_value == 0)) {
return nullptr; return false;
} }
if (linear_id == 0) { if (AMS_UNLIKELY(linear_id == 0)) {
return nullptr; return false;
} }
if (index >= m_table_size) { if (AMS_UNLIKELY(index >= m_table_size)) {
return nullptr; return false;
} }
/* Get the entry, and ensure our serial id is correct. */ /* Check that there's an object, and our serial id is correct. */
Entry *entry = std::addressof(m_table[index]); if (AMS_UNLIKELY(m_objects[index] == nullptr)) {
if (entry->GetObject() == nullptr) { return false;
return nullptr;
} }
if (entry->GetLinearId() != linear_id) { if (AMS_UNLIKELY(m_entry_infos[index].GetLinearId() != linear_id)) {
return nullptr; return false;
} }
return entry; return true;
} }
constexpr ALWAYS_INLINE KAutoObject *GetObjectImpl(ams::svc::Handle handle) const { constexpr NOINLINE KAutoObject *GetObjectImpl(ams::svc::Handle handle) const {
MESOSPHERE_ASSERT_THIS(); MESOSPHERE_ASSERT_THIS();
/* Handles must not have reserved bits set. */ /* Handles must not have reserved bits set. */
if (GetHandleBitPack(handle).Get<HandleReserved>() != 0) { const auto handle_pack = GetHandleBitPack(handle);
if (AMS_UNLIKELY(handle_pack.Get<HandleReserved>() != 0)) {
return nullptr; return nullptr;
} }
if (Entry *entry = this->FindEntry(handle); entry != nullptr) { if (AMS_LIKELY(this->IsValidHandle(handle))) {
return entry->GetObject(); return m_objects[handle_pack.Get<HandleIndex>()];
} else { } else {
return nullptr; return nullptr;
} }
@@ -347,18 +332,17 @@ namespace ams::kern {
MESOSPHERE_ASSERT_THIS(); MESOSPHERE_ASSERT_THIS();
/* Index must be in bounds. */ /* Index must be in bounds. */
if (index >= m_table_size || m_table == nullptr) { if (AMS_UNLIKELY(index >= m_table_size)) {
return nullptr; return nullptr;
} }
/* Ensure entry has an object. */ /* Ensure entry has an object. */
Entry *entry = std::addressof(m_table[index]); if (KAutoObject *obj = m_objects[index]; obj != nullptr) {
if (entry->GetObject() == nullptr) { *out_handle = EncodeHandle(index, m_entry_infos[index].GetLinearId());
return obj;
} else {
return nullptr; return nullptr;
} }
*out_handle = EncodeHandle(index, entry->GetLinearId());
return entry->GetObject();
} }
}; };

View File

@@ -70,6 +70,7 @@ namespace ams::kern {
constexpr bool Is64Bit() const { return (m_flags & (1 << 3)); } constexpr bool Is64Bit() const { return (m_flags & (1 << 3)); }
constexpr bool Is64BitAddressSpace() const { return (m_flags & (1 << 4)); } constexpr bool Is64BitAddressSpace() const { return (m_flags & (1 << 4)); }
constexpr bool UsesSecureMemory() const { return (m_flags & (1 << 5)); } constexpr bool UsesSecureMemory() const { return (m_flags & (1 << 5)); }
constexpr bool IsImmortal() const { return (m_flags & (1 << 6)); }
constexpr u32 GetRxAddress() const { return m_rx_address; } constexpr u32 GetRxAddress() const { return m_rx_address; }
constexpr u32 GetRxSize() const { return m_rx_size; } constexpr u32 GetRxSize() const { return m_rx_size; }
@@ -90,45 +91,49 @@ namespace ams::kern {
class KInitialProcessReader { class KInitialProcessReader {
private: private:
KInitialProcessHeader *m_kip_header; KInitialProcessHeader m_kip_header;
public: public:
constexpr KInitialProcessReader() : m_kip_header() { /* ... */ } constexpr KInitialProcessReader() : m_kip_header() { /* ... */ }
constexpr const u32 *GetCapabilities() const { return m_kip_header->GetCapabilities(); } constexpr const u32 *GetCapabilities() const { return m_kip_header.GetCapabilities(); }
constexpr size_t GetNumCapabilities() const { return m_kip_header->GetNumCapabilities(); } constexpr size_t GetNumCapabilities() const { return m_kip_header.GetNumCapabilities(); }
constexpr size_t GetBinarySize() const { constexpr size_t GetBinarySize() const {
return sizeof(*m_kip_header) + m_kip_header->GetRxCompressedSize() + m_kip_header->GetRoCompressedSize() + m_kip_header->GetRwCompressedSize(); return m_kip_header.GetRxCompressedSize() + m_kip_header.GetRoCompressedSize() + m_kip_header.GetRwCompressedSize();
} }
constexpr size_t GetSize() const { constexpr size_t GetSize() const {
if (const size_t bss_size = m_kip_header->GetBssSize(); bss_size != 0) { if (const size_t bss_size = m_kip_header.GetBssSize(); bss_size != 0) {
return m_kip_header->GetBssAddress() + m_kip_header->GetBssSize(); return util::AlignUp(m_kip_header.GetBssAddress() + m_kip_header.GetBssSize(), PageSize);
} else { } else {
return m_kip_header->GetRwAddress() + m_kip_header->GetRwSize(); return util::AlignUp(m_kip_header.GetRwAddress() + m_kip_header.GetRwSize(), PageSize);
} }
} }
constexpr u8 GetPriority() const { return m_kip_header->GetPriority(); } constexpr u8 GetPriority() const { return m_kip_header.GetPriority(); }
constexpr u8 GetIdealCoreId() const { return m_kip_header->GetIdealCoreId(); } constexpr u8 GetIdealCoreId() const { return m_kip_header.GetIdealCoreId(); }
constexpr u32 GetAffinityMask() const { return m_kip_header->GetAffinityMask(); } constexpr u32 GetAffinityMask() const { return m_kip_header.GetAffinityMask(); }
constexpr u32 GetStackSize() const { return m_kip_header->GetStackSize(); } constexpr u32 GetStackSize() const { return m_kip_header.GetStackSize(); }
constexpr bool Is64Bit() const { return m_kip_header->Is64Bit(); } constexpr bool Is64Bit() const { return m_kip_header.Is64Bit(); }
constexpr bool Is64BitAddressSpace() const { return m_kip_header->Is64BitAddressSpace(); } constexpr bool Is64BitAddressSpace() const { return m_kip_header.Is64BitAddressSpace(); }
constexpr bool UsesSecureMemory() const { return m_kip_header->UsesSecureMemory(); } constexpr bool UsesSecureMemory() const { return m_kip_header.UsesSecureMemory(); }
constexpr bool IsImmortal() const { return m_kip_header.IsImmortal(); }
bool Attach(u8 *bin) { KVirtualAddress Attach(KVirtualAddress bin) {
if (KInitialProcessHeader *header = reinterpret_cast<KInitialProcessHeader *>(bin); header->IsValid()) { /* Copy the header. */
m_kip_header = header; m_kip_header = *GetPointer<const KInitialProcessHeader>(bin);
return true;
/* Check that it's valid. */
if (m_kip_header.IsValid()) {
return bin + sizeof(KInitialProcessHeader);
} else { } else {
return false; return Null<KVirtualAddress>;
} }
} }
Result MakeCreateProcessParameter(ams::svc::CreateProcessParameter *out, bool enable_aslr) const; Result MakeCreateProcessParameter(ams::svc::CreateProcessParameter *out, bool enable_aslr) const;
Result Load(KProcessAddress address, const ams::svc::CreateProcessParameter &params) const; Result Load(KProcessAddress address, const ams::svc::CreateProcessParameter &params, KProcessAddress src) const;
Result SetMemoryPermissions(KProcessPageTable &page_table, const ams::svc::CreateProcessParameter &params) const; Result SetMemoryPermissions(KProcessPageTable &page_table, const ams::svc::CreateProcessParameter &params) const;
}; };

View File

@@ -28,9 +28,10 @@ namespace ams::kern {
MESOSPHERE_AUTOOBJECT_TRAITS(KInterruptEvent, KReadableEvent); MESOSPHERE_AUTOOBJECT_TRAITS(KInterruptEvent, KReadableEvent);
private: private:
s32 m_interrupt_id; s32 m_interrupt_id;
s32 m_core_id;
bool m_is_initialized; bool m_is_initialized;
public: public:
constexpr KInterruptEvent() : m_interrupt_id(-1), m_is_initialized(false) { /* ... */ } constexpr KInterruptEvent() : m_interrupt_id(-1), m_core_id(-1), m_is_initialized(false) { /* ... */ }
virtual ~KInterruptEvent() { /* ... */ } virtual ~KInterruptEvent() { /* ... */ }
Result Initialize(int32_t interrupt_name, ams::svc::InterruptType type); Result Initialize(int32_t interrupt_name, ams::svc::InterruptType type);
@@ -58,9 +59,9 @@ namespace ams::kern {
virtual KInterruptTask *OnInterrupt(s32 interrupt_id) override; virtual KInterruptTask *OnInterrupt(s32 interrupt_id) override;
virtual void DoTask() override; virtual void DoTask() override;
void Unregister(s32 interrupt_id); void Unregister(s32 interrupt_id, s32 core_id);
public: public:
static Result Register(s32 interrupt_id, bool level, KInterruptEvent *event); static Result Register(s32 interrupt_id, s32 core_id, bool level, KInterruptEvent *event);
}; };
} }

View File

@@ -24,40 +24,59 @@ namespace ams::kern {
class KLightConditionVariable { class KLightConditionVariable {
private: private:
KThreadQueue m_thread_queue; KThread::WaiterList m_wait_list;
public: public:
constexpr ALWAYS_INLINE KLightConditionVariable() : m_thread_queue() { /* ... */ } constexpr ALWAYS_INLINE KLightConditionVariable() : m_wait_list() { /* ... */ }
private: private:
void WaitImpl(KLightLock *lock, s64 timeout) { void WaitImpl(KLightLock *lock, s64 timeout, bool allow_terminating_thread) {
KThread *owner = GetCurrentThreadPointer(); KThread *owner = GetCurrentThreadPointer();
KHardwareTimer *timer; KHardwareTimer *timer;
/* Sleep the thread. */ /* Sleep the thread. */
{ {
KScopedSchedulerLockAndSleep lk(&timer, owner, timeout); KScopedSchedulerLockAndSleep lk(&timer, owner, timeout);
lock->Unlock();
if (!m_thread_queue.SleepThread(owner)) { if (!allow_terminating_thread && owner->IsTerminationRequested()) {
lk.CancelSleep(); lk.CancelSleep();
return; return;
} }
lock->Unlock();
/* Set the thread as waiting. */
GetCurrentThread().SetState(KThread::ThreadState_Waiting);
/* Add the thread to the queue. */
m_wait_list.push_back(GetCurrentThread());
}
/* Remove the thread from the wait list. */
{
KScopedSchedulerLock sl;
m_wait_list.erase(m_wait_list.iterator_to(GetCurrentThread()));
} }
/* Cancel the task that the sleep setup. */ /* Cancel the task that the sleep setup. */
if (timer != nullptr) { if (timer != nullptr) {
timer->CancelTask(owner); timer->CancelTask(owner);
} }
/* Re-acquire the lock. */
lock->Lock();
} }
public: public:
void Wait(KLightLock *lock, s64 timeout = -1ll) { void Wait(KLightLock *lock, s64 timeout = -1ll, bool allow_terminating_thread = true) {
this->WaitImpl(lock, timeout); this->WaitImpl(lock, timeout, allow_terminating_thread);
lock->Lock();
} }
void Broadcast() { void Broadcast() {
KScopedSchedulerLock lk; KScopedSchedulerLock lk;
while (m_thread_queue.WakeupFrontThread() != nullptr) {
/* We want to signal all threads, and so should continue waking up until there's nothing to wake. */ /* Signal all threads. */
for (auto &thread : m_wait_list) {
thread.SetState(KThread::ThreadState_Runnable);
} }
} }

View File

@@ -1,236 +0,0 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope 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/>.
*/
#pragma once
#include <mesosphere/kern_common.hpp>
#include <mesosphere/kern_k_typed_address.hpp>
#include <mesosphere/kern_slab_helpers.hpp>
namespace ams::kern {
class KLinkedListNode : public util::IntrusiveListBaseNode<KLinkedListNode>, public KSlabAllocated<KLinkedListNode> {
private:
void *m_item;
public:
constexpr KLinkedListNode() : util::IntrusiveListBaseNode<KLinkedListNode>(), m_item(nullptr) { MESOSPHERE_ASSERT_THIS(); }
constexpr void Initialize(void *it) {
MESOSPHERE_ASSERT_THIS();
m_item = it;
}
constexpr void *GetItem() const {
return m_item;
}
};
static_assert(sizeof(KLinkedListNode) == sizeof(util::IntrusiveListNode) + sizeof(void *));
template<typename T>
class KLinkedList : private util::IntrusiveListBaseTraits<KLinkedListNode>::ListType {
private:
using BaseList = util::IntrusiveListBaseTraits<KLinkedListNode>::ListType;
public:
template<bool Const>
class Iterator;
using value_type = T;
using size_type = size_t;
using difference_type = ptrdiff_t;
using pointer = value_type *;
using const_pointer = const value_type *;
using reference = value_type &;
using const_reference = const value_type &;
using iterator = Iterator<false>;
using const_iterator = Iterator<true>;
using reverse_iterator = std::reverse_iterator<iterator>;
using const_reverse_iterator = std::reverse_iterator<const_iterator>;
template<bool Const>
class Iterator {
private:
using BaseIterator = BaseList::Iterator<Const>;
friend class KLinkedList;
public:
using iterator_category = std::bidirectional_iterator_tag;
using value_type = typename KLinkedList::value_type;
using difference_type = typename KLinkedList::difference_type;
using pointer = typename std::conditional<Const, KLinkedList::const_pointer, KLinkedList::pointer>::type;
using reference = typename std::conditional<Const, KLinkedList::const_reference, KLinkedList::reference>::type;
private:
BaseIterator m_base_it;
public:
explicit Iterator(BaseIterator it) : m_base_it(it) { /* ... */ }
pointer GetItem() const {
return static_cast<pointer>(m_base_it->GetItem());
}
bool operator==(const Iterator &rhs) const {
return m_base_it == rhs.m_base_it;
}
bool operator!=(const Iterator &rhs) const {
return !(*this == rhs);
}
pointer operator->() const {
return this->GetItem();
}
reference operator*() const {
return *this->GetItem();
}
Iterator &operator++() {
++m_base_it;
return *this;
}
Iterator &operator--() {
--m_base_it;
return *this;
}
Iterator operator++(int) {
const Iterator it{*this};
++(*this);
return it;
}
Iterator operator--(int) {
const Iterator it{*this};
--(*this);
return it;
}
operator Iterator<true>() const {
return Iterator<true>(m_base_it);
}
};
public:
constexpr KLinkedList() : BaseList() { /* ... */ }
~KLinkedList() {
/* Erase all elements. */
for (auto it = this->begin(); it != this->end(); it = this->erase(it)) {
/* ... */
}
/* Ensure we succeeded. */
MESOSPHERE_ASSERT(this->empty());
}
/* Iterator accessors. */
iterator begin() {
return iterator(BaseList::begin());
}
const_iterator begin() const {
return const_iterator(BaseList::begin());
}
iterator end() {
return iterator(BaseList::end());
}
const_iterator end() const {
return const_iterator(BaseList::end());
}
const_iterator cbegin() const {
return this->begin();
}
const_iterator cend() const {
return this->end();
}
reverse_iterator rbegin() {
return reverse_iterator(this->end());
}
const_reverse_iterator rbegin() const {
return const_reverse_iterator(this->end());
}
reverse_iterator rend() {
return reverse_iterator(this->begin());
}
const_reverse_iterator rend() const {
return const_reverse_iterator(this->begin());
}
const_reverse_iterator crbegin() const {
return this->rbegin();
}
const_reverse_iterator crend() const {
return this->rend();
}
/* Content management. */
using BaseList::empty;
using BaseList::size;
reference back() {
return *(--this->end());
}
const_reference back() const {
return *(--this->end());
}
reference front() {
return *this->begin();
}
const_reference front() const {
return *this->begin();
}
iterator insert(const_iterator pos, reference ref) {
KLinkedListNode *node = KLinkedListNode::Allocate();
MESOSPHERE_ABORT_UNLESS(node != nullptr);
node->Initialize(std::addressof(ref));
return iterator(BaseList::insert(pos.m_base_it, *node));
}
void push_back(reference ref) {
this->insert(this->end(), ref);
}
void push_front(reference ref) {
this->insert(this->begin(), ref);
}
void pop_back() {
this->erase(--this->end());
}
void pop_front() {
this->erase(this->begin());
}
iterator erase(const iterator pos) {
KLinkedListNode *freed_node = std::addressof(*pos.m_base_it);
iterator ret = iterator(BaseList::erase(pos.m_base_it));
KLinkedListNode::Free(freed_node);
return ret;
}
};
}

View File

@@ -160,7 +160,7 @@ namespace ams::kern {
}; };
constexpr KMemoryPermission ConvertToKMemoryPermission(ams::svc::MemoryPermission perm) { constexpr KMemoryPermission ConvertToKMemoryPermission(ams::svc::MemoryPermission perm) {
return static_cast<KMemoryPermission>((perm & KMemoryPermission_UserMask) | KMemoryPermission_KernelRead | ((perm & KMemoryPermission_UserWrite) << KMemoryPermission_KernelShift) | (perm == ams::svc::MemoryPermission_None ? KMemoryPermission_NotMapped : KMemoryPermission_None)); return static_cast<KMemoryPermission>((util::ToUnderlying(perm) & KMemoryPermission_UserMask) | KMemoryPermission_KernelRead | ((util::ToUnderlying(perm) & KMemoryPermission_UserWrite) << KMemoryPermission_KernelShift) | (perm == ams::svc::MemoryPermission_None ? KMemoryPermission_NotMapped : KMemoryPermission_None));
} }
enum KMemoryAttribute : u8 { enum KMemoryAttribute : u8 {

View File

@@ -27,18 +27,8 @@ namespace ams::kern {
KMemoryBlock *m_blocks[MaxBlocks]; KMemoryBlock *m_blocks[MaxBlocks];
size_t m_index; size_t m_index;
KMemoryBlockSlabManager *m_slab_manager; KMemoryBlockSlabManager *m_slab_manager;
public: private:
constexpr explicit KMemoryBlockManagerUpdateAllocator(KMemoryBlockSlabManager *sm) : m_blocks(), m_index(MaxBlocks), m_slab_manager(sm) { /* ... */ } ALWAYS_INLINE Result Initialize(size_t num_blocks) {
~KMemoryBlockManagerUpdateAllocator() {
for (const auto &block : m_blocks) {
if (block != nullptr) {
m_slab_manager->Free(block);
}
}
}
Result Initialize(size_t num_blocks) {
/* Check num blocks. */ /* Check num blocks. */
MESOSPHERE_ASSERT(num_blocks <= MaxBlocks); MESOSPHERE_ASSERT(num_blocks <= MaxBlocks);
@@ -53,6 +43,18 @@ namespace ams::kern {
return ResultSuccess(); return ResultSuccess();
} }
public:
KMemoryBlockManagerUpdateAllocator(Result *out_result, KMemoryBlockSlabManager *sm, size_t num_blocks = MaxBlocks) : m_blocks(), m_index(MaxBlocks), m_slab_manager(sm) {
*out_result = this->Initialize(num_blocks);
}
~KMemoryBlockManagerUpdateAllocator() {
for (const auto &block : m_blocks) {
if (block != nullptr) {
m_slab_manager->Free(block);
}
}
}
KMemoryBlock *Allocate() { KMemoryBlock *Allocate() {
MESOSPHERE_ABORT_UNLESS(m_index < MaxBlocks); MESOSPHERE_ABORT_UNLESS(m_index < MaxBlocks);

View File

@@ -44,9 +44,8 @@ namespace ams::kern {
constexpr size_t KernelInitialPageHeapSize = 128_KB; constexpr size_t KernelInitialPageHeapSize = 128_KB;
constexpr size_t KernelSlabHeapDataSize = 5_MB; constexpr size_t KernelSlabHeapDataSize = 5_MB;
constexpr size_t KernelSlabHeapGapsSize = 2_MB - 64_KB; constexpr size_t KernelSlabHeapGapsSizeMax = 2_MB - 64_KB;
constexpr size_t KernelSlabHeapGapsSizeDeprecated = 2_MB; constexpr size_t KernelSlabHeapSize = KernelSlabHeapDataSize + KernelSlabHeapGapsSizeMax;
constexpr size_t KernelSlabHeapSize = KernelSlabHeapDataSize + KernelSlabHeapGapsSize;
/* NOTE: This is calculated from KThread slab counts, assuming KThread size <= 0x860. */ /* NOTE: This is calculated from KThread slab counts, assuming KThread size <= 0x860. */
constexpr size_t KernelSlabHeapAdditionalSize = 0x68000; constexpr size_t KernelSlabHeapAdditionalSize = 0x68000;
@@ -176,7 +175,14 @@ namespace ams::kern {
return std::make_tuple(total_size, kernel_size); return std::make_tuple(total_size, kernel_size);
} }
static void InitializeLinearMemoryRegionTrees(KPhysicalAddress aligned_linear_phys_start, KVirtualAddress linear_virtual_start); static void InitializeLinearMemoryAddresses(KPhysicalAddress aligned_linear_phys_start, KVirtualAddress linear_virtual_start) {
/* Set static differences. */
s_linear_phys_to_virt_diff = GetInteger(linear_virtual_start) - GetInteger(aligned_linear_phys_start);
s_linear_virt_to_phys_diff = GetInteger(aligned_linear_phys_start) - GetInteger(linear_virtual_start);
}
static void InitializeLinearMemoryRegionTrees();
static size_t GetResourceRegionSizeForInit(); static size_t GetResourceRegionSizeForInit();
static NOINLINE auto GetKernelRegionExtents() { return GetVirtualMemoryRegionTree().GetDerivedRegionExtents(KMemoryRegionType_Kernel); } static NOINLINE auto GetKernelRegionExtents() { return GetVirtualMemoryRegionTree().GetDerivedRegionExtents(KMemoryRegionType_Kernel); }

View File

@@ -75,7 +75,7 @@ namespace ams::kern {
KVirtualAddress AllocateBlock(s32 index, bool random) { return m_heap.AllocateBlock(index, random); } KVirtualAddress AllocateBlock(s32 index, bool random) { return m_heap.AllocateBlock(index, random); }
void Free(KVirtualAddress addr, size_t num_pages) { m_heap.Free(addr, num_pages); } void Free(KVirtualAddress addr, size_t num_pages) { m_heap.Free(addr, num_pages); }
void UpdateUsedHeapSize() { m_heap.UpdateUsedSize(); } void SetInitialUsedHeapSize(size_t reserved_size) { m_heap.SetInitialUsedSize(reserved_size); }
void InitializeOptimizedMemory() { std::memset(GetVoidPointer(m_management_region), 0, CalculateOptimizedProcessOverheadSize(m_heap.GetSize())); } void InitializeOptimizedMemory() { std::memset(GetVoidPointer(m_management_region), 0, CalculateOptimizedProcessOverheadSize(m_heap.GetSize())); }
@@ -168,6 +168,10 @@ namespace ams::kern {
return m_managers[KMemoryLayout::GetVirtualLinearRegion(address).GetAttributes()]; return m_managers[KMemoryLayout::GetVirtualLinearRegion(address).GetAttributes()];
} }
const Impl &GetManager(KVirtualAddress address) const {
return m_managers[KMemoryLayout::GetVirtualLinearRegion(address).GetAttributes()];
}
constexpr Impl *GetFirstManager(Pool pool, Direction dir) { constexpr Impl *GetFirstManager(Pool pool, Direction dir) {
return dir == Direction_FromBack ? m_pool_managers_tail[pool] : m_pool_managers_head[pool]; return dir == Direction_FromBack ? m_pool_managers_tail[pool] : m_pool_managers_head[pool];
} }
@@ -197,6 +201,10 @@ namespace ams::kern {
NOINLINE Result AllocateAndOpen(KPageGroup *out, size_t num_pages, u32 option); NOINLINE Result AllocateAndOpen(KPageGroup *out, size_t num_pages, u32 option);
NOINLINE Result AllocateAndOpenForProcess(KPageGroup *out, size_t num_pages, u32 option, u64 process_id, u8 fill_pattern); NOINLINE Result AllocateAndOpenForProcess(KPageGroup *out, size_t num_pages, u32 option, u64 process_id, u8 fill_pattern);
Pool GetPool(KVirtualAddress address) const {
return this->GetManager(address).GetPool();
}
void Open(KVirtualAddress address, size_t num_pages) { void Open(KVirtualAddress address, size_t num_pages) {
/* Repeatedly open references until we've done so for all pages. */ /* Repeatedly open references until we've done so for all pages. */
while (num_pages) { while (num_pages) {

View File

@@ -21,7 +21,8 @@ namespace ams::kern {
enum KMemoryRegionType : u32 {}; enum KMemoryRegionType : u32 {};
enum KMemoryRegionAttr : typename std::underlying_type<KMemoryRegionType>::type { enum KMemoryRegionAttr : typename std::underlying_type<KMemoryRegionType>::type {
KMemoryRegionAttr_CarveoutProtected = 0x04000000, KMemoryRegionAttr_CarveoutProtected = 0x02000000,
KMemoryRegionAttr_Uncached = 0x04000000,
KMemoryRegionAttr_DidKernelMap = 0x08000000, KMemoryRegionAttr_DidKernelMap = 0x08000000,
KMemoryRegionAttr_ShouldKernelMap = 0x10000000, KMemoryRegionAttr_ShouldKernelMap = 0x10000000,
KMemoryRegionAttr_UserReadOnly = 0x20000000, KMemoryRegionAttr_UserReadOnly = 0x20000000,
@@ -65,11 +66,41 @@ namespace ams::kern {
consteval operator KMemoryRegionType() const { return static_cast<KMemoryRegionType>(m_value); } consteval operator KMemoryRegionType() const { return static_cast<KMemoryRegionType>(m_value); }
consteval ValueType GetValue() const { return m_value; } consteval ValueType GetValue() const { return m_value; }
consteval const KMemoryRegionTypeValue &Finalize() { m_finalized = true; return *this; } consteval const KMemoryRegionTypeValue Finalize() {
consteval const KMemoryRegionTypeValue &SetSparseOnly() { m_sparse_only = true; return *this; } AMS_ASSUME(!m_finalized);
consteval const KMemoryRegionTypeValue &SetDenseOnly() { m_dense_only = true; return *this; }
consteval KMemoryRegionTypeValue &SetAttribute(KMemoryRegionAttr attr) { AMS_ASSUME(!m_finalized); m_value |= attr; return *this; } KMemoryRegionTypeValue new_type = *this;
new_type.m_finalized = true;
return new_type;
}
consteval const KMemoryRegionTypeValue SetSparseOnly() {
AMS_ASSUME(!m_finalized);
AMS_ASSUME(!m_sparse_only);
AMS_ASSUME(!m_dense_only);
KMemoryRegionTypeValue new_type = *this;
new_type.m_sparse_only = true;
return new_type;
}
consteval const KMemoryRegionTypeValue SetDenseOnly() {
AMS_ASSUME(!m_finalized);
AMS_ASSUME(!m_sparse_only);
AMS_ASSUME(!m_dense_only);
KMemoryRegionTypeValue new_type = *this;
new_type.m_dense_only = true;
return new_type;
}
consteval KMemoryRegionTypeValue SetAttribute(KMemoryRegionAttr attr) {
AMS_ASSUME(!m_finalized);
KMemoryRegionTypeValue new_type = *this;
new_type.m_value |= attr;
return new_type;
}
consteval KMemoryRegionTypeValue DeriveInitial(size_t i, size_t next = BITSIZEOF(ValueType)) const { consteval KMemoryRegionTypeValue DeriveInitial(size_t i, size_t next = BITSIZEOF(ValueType)) const {
AMS_ASSUME(!m_finalized); AMS_ASSUME(!m_finalized);
@@ -216,6 +247,10 @@ namespace ams::kern {
static_assert(KMemoryRegionType_VirtualDramKernelPtHeap .GetValue() == 0x2A); static_assert(KMemoryRegionType_VirtualDramKernelPtHeap .GetValue() == 0x2A);
static_assert(KMemoryRegionType_VirtualDramKernelTraceBuffer.GetValue() == 0x4A); static_assert(KMemoryRegionType_VirtualDramKernelTraceBuffer.GetValue() == 0x4A);
/* UNUSED: .DeriveSparse(2, 2, 0); */
constexpr inline const auto KMemoryRegionType_VirtualDramUnknownDebug = KMemoryRegionType_Dram.DeriveSparse(2, 2, 1);
static_assert(KMemoryRegionType_VirtualDramUnknownDebug.GetValue() == (0x52));
constexpr inline const auto KMemoryRegionType_VirtualDramKernelInitPt = KMemoryRegionType_VirtualDramHeapBase.Derive(3, 0); constexpr inline const auto KMemoryRegionType_VirtualDramKernelInitPt = KMemoryRegionType_VirtualDramHeapBase.Derive(3, 0);
constexpr inline const auto KMemoryRegionType_VirtualDramPoolManagement = KMemoryRegionType_VirtualDramHeapBase.Derive(3, 1); constexpr inline const auto KMemoryRegionType_VirtualDramPoolManagement = KMemoryRegionType_VirtualDramHeapBase.Derive(3, 1);
constexpr inline const auto KMemoryRegionType_VirtualDramUserPool = KMemoryRegionType_VirtualDramHeapBase.Derive(3, 2); constexpr inline const auto KMemoryRegionType_VirtualDramUserPool = KMemoryRegionType_VirtualDramHeapBase.Derive(3, 2);
@@ -292,6 +327,8 @@ namespace ams::kern {
return KMemoryRegionType_VirtualDramKernelTraceBuffer; return KMemoryRegionType_VirtualDramKernelTraceBuffer;
} else if (KMemoryRegionType_DramKernelPtHeap.IsAncestorOf(type_id)) { } else if (KMemoryRegionType_DramKernelPtHeap.IsAncestorOf(type_id)) {
return KMemoryRegionType_VirtualDramKernelPtHeap; return KMemoryRegionType_VirtualDramKernelPtHeap;
} else if ((type_id | KMemoryRegionAttr_ShouldKernelMap) == type_id) {
return KMemoryRegionType_VirtualDramUnknownDebug;
} else { } else {
return KMemoryRegionType_Dram; return KMemoryRegionType_Dram;
} }

View File

@@ -47,6 +47,9 @@ namespace ams::kern {
Derived *derived = obj->DynamicCast<Derived *>(); Derived *derived = obj->DynamicCast<Derived *>();
R_UNLESS(derived != nullptr, svc::ResultNotFound()); R_UNLESS(derived != nullptr, svc::ResultNotFound());
/* Check that the object is closed. */
R_UNLESS(derived->IsServerClosed(), svc::ResultInvalidState());
return Delete(obj.GetPointerUnsafe(), name); return Delete(obj.GetPointerUnsafe(), name);
} }

View File

@@ -125,7 +125,7 @@ namespace ams::kern {
private: private:
KVirtualAddress m_heap_address; KVirtualAddress m_heap_address;
size_t m_heap_size; size_t m_heap_size;
size_t m_used_size; size_t m_initial_used_size;
size_t m_num_blocks; size_t m_num_blocks;
Block m_blocks[NumMemoryBlockPageShifts]; Block m_blocks[NumMemoryBlockPageShifts];
private: private:
@@ -134,7 +134,7 @@ namespace ams::kern {
void FreeBlock(KVirtualAddress block, s32 index); void FreeBlock(KVirtualAddress block, s32 index);
public: public:
KPageHeap() : m_heap_address(), m_heap_size(), m_used_size(), m_num_blocks(), m_blocks() { /* ... */ } KPageHeap() : m_heap_address(), m_heap_size(), m_initial_used_size(), m_num_blocks(), m_blocks() { /* ... */ }
constexpr KVirtualAddress GetAddress() const { return m_heap_address; } constexpr KVirtualAddress GetAddress() const { return m_heap_address; }
constexpr size_t GetSize() const { return m_heap_size; } constexpr size_t GetSize() const { return m_heap_size; }
@@ -149,8 +149,13 @@ namespace ams::kern {
size_t GetFreeSize() const { return this->GetNumFreePages() * PageSize; } size_t GetFreeSize() const { return this->GetNumFreePages() * PageSize; }
void DumpFreeList() const; void DumpFreeList() const;
void UpdateUsedSize() { void SetInitialUsedSize(size_t reserved_size) {
m_used_size = m_heap_size - (this->GetNumFreePages() * PageSize); /* Check that the reserved size is valid. */
const size_t free_size = this->GetNumFreePages() * PageSize;
MESOSPHERE_ABORT_UNLESS(m_heap_size >= free_size + reserved_size);
/* Set the initial used size. */
m_initial_used_size = m_heap_size - free_size - reserved_size;
} }
KVirtualAddress AllocateBlock(s32 index, bool random); KVirtualAddress AllocateBlock(s32 index, bool random);

View File

@@ -47,12 +47,21 @@ namespace ams::kern {
static_assert(std::is_trivial<KPageProperties>::value); static_assert(std::is_trivial<KPageProperties>::value);
static_assert(sizeof(KPageProperties) == sizeof(u32)); static_assert(sizeof(KPageProperties) == sizeof(u32));
class KResourceLimit;
class KPageTableBase { class KPageTableBase {
NON_COPYABLE(KPageTableBase); NON_COPYABLE(KPageTableBase);
NON_MOVEABLE(KPageTableBase); NON_MOVEABLE(KPageTableBase);
public: public:
using TraversalEntry = KPageTableImpl::TraversalEntry; using TraversalEntry = KPageTableImpl::TraversalEntry;
using TraversalContext = KPageTableImpl::TraversalContext; using TraversalContext = KPageTableImpl::TraversalContext;
struct MemoryRange {
KVirtualAddress address;
size_t size;
void Close();
};
protected: protected:
enum MemoryFillValue { enum MemoryFillValue {
MemoryFillValue_Zero = 0, MemoryFillValue_Zero = 0,
@@ -98,8 +107,11 @@ namespace ams::kern {
Node *Peek() const { return m_root; } Node *Peek() const { return m_root; }
Node *Pop() { Node *Pop() {
Node *r = m_root; Node * const r = m_root;
m_root = m_root->m_next;
m_root = r->m_next;
r->m_next = nullptr;
return r; return r;
} }
}; };
@@ -150,8 +162,10 @@ namespace ams::kern {
size_t m_max_heap_size{}; size_t m_max_heap_size{};
size_t m_mapped_physical_memory_size{}; size_t m_mapped_physical_memory_size{};
size_t m_mapped_unsafe_physical_memory{}; size_t m_mapped_unsafe_physical_memory{};
size_t m_mapped_ipc_server_memory{};
mutable KLightLock m_general_lock{}; mutable KLightLock m_general_lock{};
mutable KLightLock m_map_physical_memory_lock{}; mutable KLightLock m_map_physical_memory_lock{};
KLightLock m_device_map_lock{};
KPageTableImpl m_impl{}; KPageTableImpl m_impl{};
KMemoryBlockManager m_memory_block_manager{}; KMemoryBlockManager m_memory_block_manager{};
u32 m_allocate_option{}; u32 m_allocate_option{};
@@ -161,6 +175,7 @@ namespace ams::kern {
bool m_enable_device_address_space_merge{}; bool m_enable_device_address_space_merge{};
KMemoryBlockSlabManager *m_memory_block_slab_manager{}; KMemoryBlockSlabManager *m_memory_block_slab_manager{};
KBlockInfoManager *m_block_info_manager{}; KBlockInfoManager *m_block_info_manager{};
KResourceLimit *m_resource_limit{};
const KMemoryRegion *m_cached_physical_linear_region{}; const KMemoryRegion *m_cached_physical_linear_region{};
const KMemoryRegion *m_cached_physical_heap_region{}; const KMemoryRegion *m_cached_physical_heap_region{};
const KMemoryRegion *m_cached_virtual_heap_region{}; const KMemoryRegion *m_cached_virtual_heap_region{};
@@ -171,7 +186,7 @@ namespace ams::kern {
constexpr KPageTableBase() { /* ... */ } constexpr KPageTableBase() { /* ... */ }
NOINLINE Result InitializeForKernel(bool is_64_bit, void *table, KVirtualAddress start, KVirtualAddress end); NOINLINE Result InitializeForKernel(bool is_64_bit, void *table, KVirtualAddress start, KVirtualAddress end);
NOINLINE Result InitializeForProcess(ams::svc::CreateProcessFlag as_type, bool enable_aslr, bool enable_device_address_space_merge, bool from_back, KMemoryManager::Pool pool, void *table, KProcessAddress start, KProcessAddress end, KProcessAddress code_address, size_t code_size, KMemoryBlockSlabManager *mem_block_slab_manager, KBlockInfoManager *block_info_manager); NOINLINE Result InitializeForProcess(ams::svc::CreateProcessFlag as_type, bool enable_aslr, bool enable_device_address_space_merge, bool from_back, KMemoryManager::Pool pool, void *table, KProcessAddress start, KProcessAddress end, KProcessAddress code_address, size_t code_size, KMemoryBlockSlabManager *mem_block_slab_manager, KBlockInfoManager *block_info_manager, KResourceLimit *resource_limit);
void Finalize(); void Finalize();
@@ -195,6 +210,10 @@ namespace ams::kern {
return this->CanContain(addr, size, KMemoryState_AliasCode); return this->CanContain(addr, size, KMemoryState_AliasCode);
} }
ALWAYS_INLINE KScopedLightLock AcquireDeviceMapLock() {
return KScopedLightLock(m_device_map_lock);
}
KProcessAddress GetRegionAddress(KMemoryState state) const; KProcessAddress GetRegionAddress(KMemoryState state) const;
size_t GetRegionSize(KMemoryState state) const; size_t GetRegionSize(KMemoryState state) const;
bool CanContain(KProcessAddress addr, size_t size, KMemoryState state) const; bool CanContain(KProcessAddress addr, size_t size, KMemoryState state) const;
@@ -286,16 +305,35 @@ namespace ams::kern {
Result MakePageGroup(KPageGroup &pg, KProcessAddress addr, size_t num_pages); Result MakePageGroup(KPageGroup &pg, KProcessAddress addr, size_t num_pages);
bool IsValidPageGroup(const KPageGroup &pg, KProcessAddress addr, size_t num_pages); bool IsValidPageGroup(const KPageGroup &pg, KProcessAddress addr, size_t num_pages);
Result GetContiguousMemoryRangeWithState(MemoryRange *out, KProcessAddress address, size_t size, u32 state_mask, u32 state, u32 perm_mask, u32 perm, u32 attr_mask, u32 attr);
NOINLINE Result MapPages(KProcessAddress *out_addr, size_t num_pages, size_t alignment, KPhysicalAddress phys_addr, bool is_pa_valid, KProcessAddress region_start, size_t region_num_pages, KMemoryState state, KMemoryPermission perm); NOINLINE Result MapPages(KProcessAddress *out_addr, size_t num_pages, size_t alignment, KPhysicalAddress phys_addr, bool is_pa_valid, KProcessAddress region_start, size_t region_num_pages, KMemoryState state, KMemoryPermission perm);
Result MapIoImpl(KProcessAddress *out, PageLinkedList *page_list, KPhysicalAddress phys_addr, size_t size, KMemoryPermission perm);
Result ReadIoMemoryImpl(void *buffer, KPhysicalAddress phys_addr, size_t size);
Result WriteIoMemoryImpl(KPhysicalAddress phys_addr, const void *buffer, size_t size);
Result SetupForIpcClient(PageLinkedList *page_list, size_t *out_blocks_needed, KProcessAddress address, size_t size, KMemoryPermission test_perm, KMemoryState dst_state); Result SetupForIpcClient(PageLinkedList *page_list, size_t *out_blocks_needed, KProcessAddress address, size_t size, KMemoryPermission test_perm, KMemoryState dst_state);
Result SetupForIpcServer(KProcessAddress *out_addr, size_t size, KProcessAddress src_addr, KMemoryPermission test_perm, KMemoryState dst_state, KPageTableBase &src_page_table, bool send); Result SetupForIpcServer(KProcessAddress *out_addr, size_t size, KProcessAddress src_addr, KMemoryPermission test_perm, KMemoryState dst_state, KPageTableBase &src_page_table, bool send);
void CleanupForIpcClientOnServerSetupFailure(PageLinkedList *page_list, KProcessAddress address, size_t size, KMemoryPermission prot_perm); void CleanupForIpcClientOnServerSetupFailure(PageLinkedList *page_list, KProcessAddress address, size_t size, KMemoryPermission prot_perm);
size_t GetSize(KMemoryState state) const; size_t GetSize(KMemoryState state) const;
ALWAYS_INLINE bool GetPhysicalAddressLocked(KPhysicalAddress *out, KProcessAddress virt_addr) const {
/* Validate pre-conditions. */
MESOSPHERE_AUDIT(this->IsLockedByCurrentThread());
return this->GetImpl().GetPhysicalAddress(out, virt_addr);
}
public: public:
bool GetPhysicalAddress(KPhysicalAddress *out, KProcessAddress virt_addr) const { bool GetPhysicalAddress(KPhysicalAddress *out, KProcessAddress virt_addr) const {
return this->GetImpl().GetPhysicalAddress(out, virt_addr); /* Validate pre-conditions. */
MESOSPHERE_AUDIT(!this->IsLockedByCurrentThread());
/* Acquire exclusive access to the table while doing address translation. */
KScopedLightLock lk(m_general_lock);
return this->GetPhysicalAddressLocked(out, virt_addr);
} }
KBlockInfoManager *GetBlockInfoManager() const { return m_block_info_manager; } KBlockInfoManager *GetBlockInfoManager() const { return m_block_info_manager; }
@@ -341,14 +379,20 @@ namespace ams::kern {
Result InvalidateProcessDataCache(KProcessAddress address, size_t size); Result InvalidateProcessDataCache(KProcessAddress address, size_t size);
Result ReadDebugMemory(void *buffer, KProcessAddress address, size_t size); Result ReadDebugMemory(void *buffer, KProcessAddress address, size_t size);
Result ReadDebugIoMemory(void *buffer, KProcessAddress address, size_t size);
Result WriteDebugMemory(KProcessAddress address, const void *buffer, size_t size); Result WriteDebugMemory(KProcessAddress address, const void *buffer, size_t size);
Result WriteDebugIoMemory(KProcessAddress address, const void *buffer, size_t size);
Result LockForMapDeviceAddressSpace(KProcessAddress address, size_t size, KMemoryPermission perm, bool is_aligned);
Result LockForUnmapDeviceAddressSpace(KProcessAddress address, size_t size);
Result LockForDeviceAddressSpace(KPageGroup *out, KProcessAddress address, size_t size, KMemoryPermission perm, bool is_aligned);
Result UnlockForDeviceAddressSpace(KProcessAddress address, size_t size); Result UnlockForDeviceAddressSpace(KProcessAddress address, size_t size);
Result MakePageGroupForUnmapDeviceAddressSpace(KPageGroup *out, KProcessAddress address, size_t size);
Result UnlockForDeviceAddressSpacePartialMap(KProcessAddress address, size_t size, size_t mapped_size); Result UnlockForDeviceAddressSpacePartialMap(KProcessAddress address, size_t size, size_t mapped_size);
Result OpenMemoryRangeForMapDeviceAddressSpace(KPageTableBase::MemoryRange *out, KProcessAddress address, size_t size, KMemoryPermission perm, bool is_aligned);
Result OpenMemoryRangeForUnmapDeviceAddressSpace(MemoryRange *out, KProcessAddress address, size_t size);
Result LockForIpcUserBuffer(KPhysicalAddress *out, KProcessAddress address, size_t size); Result LockForIpcUserBuffer(KPhysicalAddress *out, KProcessAddress address, size_t size);
Result UnlockForIpcUserBuffer(KProcessAddress address, size_t size); Result UnlockForIpcUserBuffer(KProcessAddress address, size_t size);
@@ -357,6 +401,8 @@ namespace ams::kern {
Result LockForCodeMemory(KPageGroup *out, KProcessAddress address, size_t size); Result LockForCodeMemory(KPageGroup *out, KProcessAddress address, size_t size);
Result UnlockForCodeMemory(KProcessAddress address, size_t size, const KPageGroup &pg); Result UnlockForCodeMemory(KProcessAddress address, size_t size, const KPageGroup &pg);
Result OpenMemoryRangeForProcessCacheOperation(MemoryRange *out, KProcessAddress address, size_t size);
Result CopyMemoryFromLinearToUser(KProcessAddress dst_addr, size_t size, KProcessAddress src_addr, u32 src_state_mask, u32 src_state, KMemoryPermission src_test_perm, u32 src_attr_mask, u32 src_attr); Result CopyMemoryFromLinearToUser(KProcessAddress dst_addr, size_t size, KProcessAddress src_addr, u32 src_state_mask, u32 src_state, KMemoryPermission src_test_perm, u32 src_attr_mask, u32 src_attr);
Result CopyMemoryFromLinearToKernel(KProcessAddress dst_addr, size_t size, KProcessAddress src_addr, u32 src_state_mask, u32 src_state, KMemoryPermission src_test_perm, u32 src_attr_mask, u32 src_attr); Result CopyMemoryFromLinearToKernel(KProcessAddress dst_addr, size_t size, KProcessAddress src_addr, u32 src_state_mask, u32 src_state, KMemoryPermission src_test_perm, u32 src_attr_mask, u32 src_attr);
Result CopyMemoryFromUserToLinear(KProcessAddress dst_addr, size_t size, u32 dst_state_mask, u32 dst_state, KMemoryPermission dst_test_perm, u32 dst_attr_mask, u32 dst_attr, KProcessAddress src_addr); Result CopyMemoryFromUserToLinear(KProcessAddress dst_addr, size_t size, u32 dst_state_mask, u32 dst_state, KMemoryPermission dst_test_perm, u32 dst_attr_mask, u32 dst_attr, KProcessAddress src_addr);
@@ -365,7 +411,7 @@ namespace ams::kern {
Result CopyMemoryFromHeapToHeapWithoutCheckDestination(KPageTableBase &dst_page_table, KProcessAddress dst_addr, size_t size, u32 dst_state_mask, u32 dst_state, KMemoryPermission dst_test_perm, u32 dst_attr_mask, u32 dst_attr, KProcessAddress src_addr, u32 src_state_mask, u32 src_state, KMemoryPermission src_test_perm, u32 src_attr_mask, u32 src_attr); Result CopyMemoryFromHeapToHeapWithoutCheckDestination(KPageTableBase &dst_page_table, KProcessAddress dst_addr, size_t size, u32 dst_state_mask, u32 dst_state, KMemoryPermission dst_test_perm, u32 dst_attr_mask, u32 dst_attr, KProcessAddress src_addr, u32 src_state_mask, u32 src_state, KMemoryPermission src_test_perm, u32 src_attr_mask, u32 src_attr);
Result SetupForIpc(KProcessAddress *out_dst_addr, size_t size, KProcessAddress src_addr, KPageTableBase &src_page_table, KMemoryPermission test_perm, KMemoryState dst_state, bool send); Result SetupForIpc(KProcessAddress *out_dst_addr, size_t size, KProcessAddress src_addr, KPageTableBase &src_page_table, KMemoryPermission test_perm, KMemoryState dst_state, bool send);
Result CleanupForIpcServer(KProcessAddress address, size_t size, KMemoryState dst_state, KProcess *server_process); Result CleanupForIpcServer(KProcessAddress address, size_t size, KMemoryState dst_state);
Result CleanupForIpcClient(KProcessAddress address, size_t size, KMemoryState dst_state); Result CleanupForIpcClient(KProcessAddress address, size_t size, KMemoryState dst_state);
Result MapPhysicalMemory(KProcessAddress address, size_t size); Result MapPhysicalMemory(KProcessAddress address, size_t size);
@@ -374,6 +420,8 @@ namespace ams::kern {
Result MapPhysicalMemoryUnsafe(KProcessAddress address, size_t size); Result MapPhysicalMemoryUnsafe(KProcessAddress address, size_t size);
Result UnmapPhysicalMemoryUnsafe(KProcessAddress address, size_t size); Result UnmapPhysicalMemoryUnsafe(KProcessAddress address, size_t size);
Result UnmapProcessMemory(KProcessAddress dst_address, size_t size, KPageTableBase &src_pt, KProcessAddress src_address);
void DumpMemoryBlocksLocked() const { void DumpMemoryBlocksLocked() const {
MESOSPHERE_ASSERT(this->IsLockedByCurrentThread()); MESOSPHERE_ASSERT(this->IsLockedByCurrentThread());
m_memory_block_manager.DumpBlocks(); m_memory_block_manager.DumpBlocks();

View File

@@ -25,18 +25,20 @@ namespace ams::kern {
class PageTablePage { class PageTablePage {
private: private:
u8 m_buffer[PageSize]; u8 m_buffer[PageSize];
public:
ALWAYS_INLINE PageTablePage() { /* Do not initialize anything. */ }
}; };
static_assert(sizeof(PageTablePage) == PageSize); static_assert(sizeof(PageTablePage) == PageSize);
} }
class KPageTableManager : public KDynamicSlabHeap<impl::PageTablePage> { class KPageTableManager : public KDynamicSlabHeap<impl::PageTablePage, true> {
public: public:
using RefCount = u16; using RefCount = u16;
static constexpr size_t PageTableSize = sizeof(impl::PageTablePage); static constexpr size_t PageTableSize = sizeof(impl::PageTablePage);
static_assert(PageTableSize == PageSize); static_assert(PageTableSize == PageSize);
private: private:
using BaseHeap = KDynamicSlabHeap<impl::PageTablePage>; using BaseHeap = KDynamicSlabHeap<impl::PageTablePage, true>;
private: private:
RefCount *m_ref_counts; RefCount *m_ref_counts;
public: public:
@@ -72,9 +74,6 @@ namespace ams::kern {
} }
void Free(KVirtualAddress addr) { void Free(KVirtualAddress addr) {
/* Ensure all pages in the heap are zero. */
cpu::ClearPageToZero(GetVoidPointer(addr));
/* Free the page. */ /* Free the page. */
BaseHeap::Free(GetPointer<impl::PageTablePage>(addr)); BaseHeap::Free(GetPointer<impl::PageTablePage>(addr));
} }

View File

@@ -53,6 +53,11 @@ namespace ams::kern {
uintptr_t GetName() const { return m_name; } uintptr_t GetName() const { return m_name; }
bool IsLight() const { return m_is_light; } bool IsLight() const { return m_is_light; }
bool IsServerClosed() const {
KScopedSchedulerLock sl;
return m_state == State::ServerClosed;
}
Result EnqueueSession(KServerSession *session); Result EnqueueSession(KServerSession *session);
Result EnqueueSession(KLightServerSession *session); Result EnqueueSession(KLightServerSession *session);

View File

@@ -77,8 +77,7 @@ namespace ams::kern {
bool m_is_initialized{}; bool m_is_initialized{};
bool m_is_application{}; bool m_is_application{};
char m_name[13]{}; char m_name[13]{};
std::atomic<u16> m_num_threads{}; std::atomic<u16> m_num_running_threads{};
u16 m_peak_num_threads{};
u32 m_flags{}; u32 m_flags{};
KMemoryManager::Pool m_memory_pool{}; KMemoryManager::Pool m_memory_pool{};
s64 m_schedule_count{}; s64 m_schedule_count{};
@@ -99,7 +98,9 @@ namespace ams::kern {
SharedMemoryInfoList m_shared_memory_list{}; SharedMemoryInfoList m_shared_memory_list{};
BetaList m_beta_list{}; BetaList m_beta_list{};
bool m_is_suspended{}; bool m_is_suspended{};
bool m_is_immortal{};
bool m_is_jit_debug{}; bool m_is_jit_debug{};
bool m_is_handle_table_initialized{};
ams::svc::DebugEvent m_jit_debug_event_type{}; ams::svc::DebugEvent m_jit_debug_event_type{};
ams::svc::DebugException m_jit_debug_exception_type{}; ams::svc::DebugException m_jit_debug_exception_type{};
uintptr_t m_jit_debug_params[4]{}; uintptr_t m_jit_debug_params[4]{};
@@ -108,7 +109,6 @@ namespace ams::kern {
KThread *m_running_threads[cpu::NumCores]{}; KThread *m_running_threads[cpu::NumCores]{};
u64 m_running_thread_idle_counts[cpu::NumCores]{}; u64 m_running_thread_idle_counts[cpu::NumCores]{};
KThread *m_pinned_threads[cpu::NumCores]{}; KThread *m_pinned_threads[cpu::NumCores]{};
std::atomic<s32> m_num_created_threads{};
std::atomic<s64> m_cpu_time{}; std::atomic<s64> m_cpu_time{};
std::atomic<s64> m_num_process_switches{}; std::atomic<s64> m_num_process_switches{};
std::atomic<s64> m_num_thread_switches{}; std::atomic<s64> m_num_thread_switches{};
@@ -124,17 +124,17 @@ namespace ams::kern {
private: private:
Result Initialize(const ams::svc::CreateProcessParameter &params); Result Initialize(const ams::svc::CreateProcessParameter &params);
void StartTermination(); Result StartTermination();
void FinishTermination(); void FinishTermination();
void PinThread(s32 core_id, KThread *thread) { ALWAYS_INLINE void PinThread(s32 core_id, KThread *thread) {
MESOSPHERE_ASSERT(0 <= core_id && core_id < static_cast<s32>(cpu::NumCores)); MESOSPHERE_ASSERT(0 <= core_id && core_id < static_cast<s32>(cpu::NumCores));
MESOSPHERE_ASSERT(thread != nullptr); MESOSPHERE_ASSERT(thread != nullptr);
MESOSPHERE_ASSERT(m_pinned_threads[core_id] == nullptr); MESOSPHERE_ASSERT(m_pinned_threads[core_id] == nullptr);
m_pinned_threads[core_id] = thread; m_pinned_threads[core_id] = thread;
} }
void UnpinThread(s32 core_id, KThread *thread) { ALWAYS_INLINE void UnpinThread(s32 core_id, KThread *thread) {
MESOSPHERE_UNUSED(thread); MESOSPHERE_UNUSED(thread);
MESOSPHERE_ASSERT(0 <= core_id && core_id < static_cast<s32>(cpu::NumCores)); MESOSPHERE_ASSERT(0 <= core_id && core_id < static_cast<s32>(cpu::NumCores));
MESOSPHERE_ASSERT(thread != nullptr); MESOSPHERE_ASSERT(thread != nullptr);
@@ -145,7 +145,7 @@ namespace ams::kern {
KProcess() { /* ... */ } KProcess() { /* ... */ }
virtual ~KProcess() { /* ... */ } virtual ~KProcess() { /* ... */ }
Result Initialize(const ams::svc::CreateProcessParameter &params, const KPageGroup &pg, const u32 *caps, s32 num_caps, KResourceLimit *res_limit, KMemoryManager::Pool pool); Result Initialize(const ams::svc::CreateProcessParameter &params, const KPageGroup &pg, const u32 *caps, s32 num_caps, KResourceLimit *res_limit, KMemoryManager::Pool pool, bool immortal);
Result Initialize(const ams::svc::CreateProcessParameter &params, svc::KUserPointer<const u32 *> caps, s32 num_caps, KResourceLimit *res_limit, KMemoryManager::Pool pool); Result Initialize(const ams::svc::CreateProcessParameter &params, svc::KUserPointer<const u32 *> caps, s32 num_caps, KResourceLimit *res_limit, KMemoryManager::Pool pool);
void Exit(); void Exit();
@@ -285,8 +285,8 @@ namespace ams::kern {
constexpr s64 GetScheduledCount() const { return m_schedule_count; } constexpr s64 GetScheduledCount() const { return m_schedule_count; }
void IncrementScheduledCount() { ++m_schedule_count; } void IncrementScheduledCount() { ++m_schedule_count; }
void IncrementThreadCount(); void IncrementRunningThreadCount();
void DecrementThreadCount(); void DecrementRunningThreadCount();
size_t GetTotalSystemResourceSize() const { return m_system_resource_num_pages * PageSize; } size_t GetTotalSystemResourceSize() const { return m_system_resource_num_pages * PageSize; }
size_t GetUsedSystemResourceSize() const { size_t GetUsedSystemResourceSize() const {
@@ -340,6 +340,7 @@ namespace ams::kern {
void PinCurrentThread(); void PinCurrentThread();
void UnpinCurrentThread(); void UnpinCurrentThread();
void UnpinThread(KThread *thread);
Result SignalToAddress(KProcessAddress address) { Result SignalToAddress(KProcessAddress address) {
return m_cond_var.SignalToAddress(address); return m_cond_var.SignalToAddress(address);
@@ -405,6 +406,23 @@ namespace ams::kern {
this->NotifyAvailable(); this->NotifyAvailable();
} }
} }
ALWAYS_INLINE Result InitializeHandleTable(s32 size) {
/* Try to initialize the handle table. */
R_TRY(m_handle_table.Initialize(size));
/* We succeeded, so note that we did. */
m_is_handle_table_initialized = true;
return ResultSuccess();
}
ALWAYS_INLINE void FinalizeHandleTable() {
/* Finalize the table. */
m_handle_table.Finalize();
/* Note that the table is finalized. */
m_is_handle_table_initialized = false;
}
}; };
} }

Some files were not shown because too many files have changed in this diff Show More