Compare commits

...

122 Commits

Author SHA1 Message Date
Michael Scire
ca2cc5e179 git subrepo push libraries
subrepo:
  subdir:   "libraries"
  merged:   "5a18bea6"
upstream:
  origin:   "https://github.com/Atmosphere-NX/Atmosphere-libs"
  branch:   "master"
  commit:   "5a18bea6"
git-subrepo:
  version:  "0.4.1"
  origin:   "https://github.com/ingydotnet/git-subrepo"
  commit:   "a04d8c2"
2020-12-11 03:49:45 -08:00
Michael Scire
17c8c390fc kern: fix building debug config 2020-12-11 03:48:34 -08:00
Michael Scire
d8ae1d873c ams: update changelog for 0.16.1 2020-12-11 03:22:28 -08:00
Michael Scire
63e3c02688 fusee/exo: support dynamic control of invert flag for logging 2020-12-11 03:18:21 -08:00
Michael Scire
14a415c4b2 ams: bump version to 0.16.1 2020-12-11 03:06:47 -08:00
Michael Scire
734122f20a fusee: update for 11.0.1 2020-12-11 03:06:17 -08:00
Michael Scire
7fb902d8fb kern: update for 11.0.1 2020-12-11 02:59:09 -08:00
Michael Scire
be8473cf65 kern: implement memory debug 2020-12-10 16:32:19 -08:00
Michael Scire
6df26d674c kern/sm: fix debug port output 2020-12-10 04:06:02 -08:00
Michael Scire
1a6e003a5d kern: add kernel object debug 2020-12-10 03:31:57 -08:00
Michael Scire
0acd79c8c2 kern: implement port debug 2020-12-10 01:44:27 -08:00
Michael Scire
8a4bf6a0a8 kern: add handle table/process/suspend/resume debug 2020-12-09 23:44:36 -08:00
Michael Scire
af259eabda kern: implement thread call stack debug 2020-12-09 22:49:04 -08:00
Michael Scire
16e2f46aed fatal: prevent crash on fatal from currently-debugged process 2020-12-09 06:45:19 -08:00
Michael Scire
bcc7eed037 kern: add debug thread dump 2020-12-09 05:59:54 -08:00
Michael Scire
abd7ad2720 meso: properly initialize per-thread CFI-value for 11.x 2020-12-08 16:16:49 -08:00
Michael Scire
58c3c8c19a fusee: take three tries for a basic assignment 2020-12-07 19:34:13 -08:00
Michael Scire
f62330c73b fusee: update for exo flags arr-type 2020-12-07 19:33:29 -08:00
Michael Scire
2de85c633a exo/meso/fusee: support dynamic control of log port/baud rate 2020-12-07 19:25:06 -08:00
Michael Scire
121c981bb4 sept: be more forgiving about entrypoint 2020-12-07 03:20:01 -08:00
Michael Scire
15396dbbc2 fs: add ProgramIndexMapInfo 2020-12-07 01:03:39 -08:00
Michael Scire
9ca1d3a7f7 loader: fix process handle management on create process error 2020-12-06 21:20:42 -08:00
Michael Scire
32803d9920 fs: update + consolidate path normalization logic 2020-12-06 19:56:45 -08:00
Michael Scire
5ef93778f6 fs: move file storage to common 2020-12-05 03:31:12 -08:00
Michael Scire
7548940efa IStorage: rename access check helpers 2020-12-05 03:15:48 -08:00
Michael Scire
bf55776241 fsa: *Impl -> Do* 2020-12-05 03:05:06 -08:00
Michael Scire
73167448cc fs/system: deduplicate RomFs code 2020-12-04 22:08:33 -08:00
Michael Scire
c45088d1cd kern: add support for InfoType_FreeThreadCount 2020-12-04 18:20:56 -08:00
Michael Scire
7336dc2b7a git subrepo push libraries
subrepo:
  subdir:   "libraries"
  merged:   "2c3ccef1"
upstream:
  origin:   "https://github.com/Atmosphere-NX/Atmosphere-libs"
  branch:   "master"
  commit:   "2c3ccef1"
git-subrepo:
  version:  "0.4.1"
  origin:   "???"
  commit:   "???"
2020-12-03 12:54:44 -08:00
Michael Scire
d2f48d5e36 err: fix narrowing conversion 2020-12-03 12:53:20 -08:00
Michael Scire
422e9434d8 git subrepo push libraries
subrepo:
  subdir:   "libraries"
  merged:   "49c1ace8"
upstream:
  origin:   "https://github.com/Atmosphere-NX/Atmosphere-libs"
  branch:   "master"
  commit:   "49c1ace8"
git-subrepo:
  version:  "0.4.1"
  origin:   "???"
  commit:   "???"
2020-12-03 12:48:41 -08:00
Michael Scire
2b93bbd9ee git subrepo pull emummc
subrepo:
  subdir:   "emummc"
  merged:   "5eed18eb"
upstream:
  origin:   "https://github.com/m4xw/emuMMC"
  branch:   "develop"
  commit:   "5eed18eb"
git-subrepo:
  version:  "0.4.1"
  origin:   "???"
  commit:   "???"
2020-12-03 12:48:06 -08:00
Michael Scire
021b29d2db erpt: give access to ectx:r 2020-12-03 11:22:18 -08:00
Michael Scire
6da28f4a27 erpt: update for 11.0.0 (closes #1218) 2020-12-03 11:13:35 -08:00
Michael Scire
bba99d49da kern: fix inverted conditional in UnmapProcessCodeMemory 2020-12-02 11:31:50 -08:00
Michael Scire
e760a9d4b0 kern: fix reboot to fatal error 2020-12-02 11:31:15 -08:00
Michael Scire
ee91f3fde0 git subrepo push libraries
subrepo:
  subdir:   "libraries"
  merged:   "78510a74"
upstream:
  origin:   "https://github.com/Atmosphere-NX/Atmosphere-libs"
  branch:   "master"
  commit:   "78510a74"
git-subrepo:
  version:  "0.4.1"
  origin:   "???"
  commit:   "???"
2020-12-02 10:00:52 -08:00
Michael Scire
f72475872a exo: add new dram IDs 2020-12-02 09:59:53 -08:00
Michael Scire
199a9aec8b exo: explicitly TODO the warmboot magic 2020-12-02 09:16:34 -08:00
Michael Scire
1b83f5169a docs: typo 2020-12-02 08:36:35 -08:00
Michael Scire
7bb77f44af docs: clarify wording 2020-12-02 08:36:19 -08:00
Michael Scire
801ce24622 docs: usb homebrew is broken, not ams's fault but worth mentioning 2020-12-02 08:28:44 -08:00
Michael Scire
1d778b2dc8 docs: update changelog for 0.16.0 2020-12-02 08:23:05 -08:00
Michael Scire
7c9608021d git subrepo push libraries
subrepo:
  subdir:   "libraries"
  merged:   "8233fa00"
upstream:
  origin:   "https://github.com/Atmosphere-NX/Atmosphere-libs"
  branch:   "master"
  commit:   "8233fa00"
git-subrepo:
  version:  "0.4.1"
  origin:   "???"
  commit:   "???"
2020-12-02 06:55:24 -08:00
Michael Scire
b8fbd0baff fssystem: fix bug in BufferedStorage 2020-12-02 06:48:42 -08:00
Michael Scire
525da05629 erpt: update category list 2020-12-02 06:47:50 -08:00
Michael Scire
2e9db4d113 git subrepo push emummc
subrepo:
  subdir:   "emummc"
  merged:   "6fd752da"
upstream:
  origin:   "https://github.com/m4xw/emuMMC"
  branch:   "develop"
  commit:   "6fd752da"
git-subrepo:
  version:  "0.4.1"
  origin:   "???"
  commit:   "???"
2020-12-02 06:45:38 -08:00
Michael Scire
4f1a4e7499 kernel patches: fuck armconverter.com 2020-12-02 06:43:37 -08:00
Michael Scire
972283032a kern: tweak KScopedAutoObject 2020-12-02 06:43:37 -08:00
Michael Scire
57f935391d kern: allow non-inline GetObjectForIpc 2020-12-02 06:43:37 -08:00
Michael Scire
4804e1e1e0 kern: fix KHandleTable null deref in ipc 2020-12-02 06:43:37 -08:00
Michael Scire
4ae74b9b4e kern: session mapping getters are on the hotpath 2020-12-02 06:43:37 -08:00
Michael Scire
726d7b6e4d kern: tweak optimization settings for hot paths 2020-12-02 06:43:37 -08:00
Michael Scire
390bdc7b6b kern: more iterator adjustments 2020-12-02 06:43:37 -08:00
Michael Scire
2d8acf9c64 strat: add new npdm field 2020-12-02 06:43:37 -08:00
Michael Scire
9743f63f0d ams.mitm: fix old hid api references 2020-12-02 06:43:37 -08:00
Michael Scire
ccd2798ae2 ams: this version will be 0.16.0 2020-12-02 06:43:37 -08:00
Adubbz
f3dbab4876 daybreak: update for hid refactor (#1222) 2020-12-02 06:43:37 -08:00
Michael Scire
41a53075e5 hot path: just in case 2020-12-02 06:43:37 -08:00
Michael Scire
ab8de72db0 microkernel: hot paths are pretty fucking hot 2020-12-02 06:43:37 -08:00
Michael Scire
331fa1d00d kern: update KConditionVariable to support new has_waiter_flag rules 2020-12-02 06:43:37 -08:00
Michael Scire
fd745ab2d3 kern: fix SvcGetResourceLimitPeakValue 2020-12-02 06:43:37 -08:00
Michael Scire
972b396f61 kern: fix copy/paste error 2020-12-02 06:43:37 -08:00
Michael Scire
3c8e7de915 kern: fix bugs caused by UB + transition to -Os 2020-12-02 06:43:37 -08:00
Michael Scire
1b164613a6 loader: support 11.x DisableDeviceAddressSpaceMerge 2020-12-02 06:43:37 -08:00
Michael Scire
3d4ab95ab2 kern: allow non-inline KSchedulerLock::Lock 2020-12-02 06:43:37 -08:00
Michael Scire
152def19c0 kern: build as -Os instead of -O2 2020-12-02 06:43:37 -08:00
Michael Scire
63974d9bce kern: reduce KMemoryRegionAllocator slab size 2020-12-02 06:43:37 -08:00
Michael Scire
2b483866c7 kern: assume that uart has been setup by secmon 2020-12-02 06:43:37 -08:00
Michael Scire
7e1da15f6e kern: update Initialize0 to account for new ordering 2020-12-02 06:43:37 -08:00
Michael Scire
0a1465f198 kern: add new overflow checks on KMemoryRegions 2020-12-02 06:43:37 -08:00
Michael Scire
748893fe77 kern: fix assertion in the multi-region pool partition code 2020-12-02 06:43:37 -08:00
Michael Scire
1ca64cf2a1 kern: improve KMemoryManager pool detection 2020-12-02 06:43:37 -08:00
Michael Scire
aac8af8bf5 kern: update KMemoryRegion to store last address rather than size 2020-12-02 06:43:37 -08:00
Michael Scire
5da6b60008 kern: add KAlpha/KBeta 2020-12-02 06:43:37 -08:00
Michael Scire
e400e2afc7 kern: stubs for Svc39, 3A, 46, 47 2020-12-02 06:43:37 -08:00
Michael Scire
56c6e4244a kern: remove now unused SetupFor*Compare funcs 2020-12-02 06:43:37 -08:00
Michael Scire
c8ebd7eea0 KConditionVariable/KAddressArbiter: no need for global compare thread 2020-12-02 06:43:37 -08:00
Michael Scire
550f5690bf kern: set EL2 id registers on deprivilege 2020-12-02 06:43:37 -08:00
Michael Scire
28f9b534b6 kern: implement 64-virtual-core interface 2020-12-02 06:43:37 -08:00
fincs
3fd59b61bc reboot_to_payload: Update for new libnx HID interface 2020-12-02 06:43:37 -08:00
fincs
f86059de70 strat/cfg: Update for new libnx HID interface 2020-12-02 06:43:37 -08:00
fincs
a03ee7b148 strat/hid: Update for new libnx HID interface 2020-12-02 06:43:37 -08:00
Michael Scire
8b2ed36698 kern: cleanup KThread, optimize/normalize KThreadQueue/KWaitObject 2020-12-02 06:43:37 -08:00
Michael Scire
1852fe8612 kern: improve KSynchronizationObject, kill KSynchronization 2020-12-02 06:43:37 -08:00
Michael Scire
b60054dba1 kern: update for new interrupt event locking scheme 2020-12-02 06:43:37 -08:00
Michael Scire
c7f37f81ee kern: fix sleep save/resume for new x18/tpidr scheme 2020-12-02 06:43:37 -08:00
Michael Scire
19a279ce45 kern: fix race-crash on interrupt controller save, improve fatal output 2020-12-02 06:43:37 -08:00
Michael Scire
783f1077be kern: KObjectContainer::Register -> void 2020-12-02 06:43:37 -08:00
Michael Scire
b0debd72a7 kern: Kill KCoreLocalRegion 2020-12-02 06:43:37 -08:00
Michael Scire
24d545701c kern: remove more of clc 2020-12-02 06:43:37 -08:00
Michael Scire
aae565629e kern: move scheduler/interrupt task manager out of core local region 2020-12-02 06:43:37 -08:00
Michael Scire
bee629b8ad kern: update KHardwareTimer, move out of KCoreLocalRegion 2020-12-02 06:43:37 -08:00
Michael Scire
5cb237d030 kern: use single interrupt manager object 2020-12-02 06:43:37 -08:00
Michael Scire
a4e09fc6c4 kern: fix unnecessary align-down 2020-12-02 06:43:37 -08:00
Michael Scire
73d9d5ff47 kern: fix error in SeparatePages 2020-12-02 06:43:37 -08:00
Michael Scire
08cfee54fa kern: fix re-order/assert in KMemoryBlock 2020-12-02 06:43:37 -08:00
Michael Scire
7b279ab863 kern: remove KPageTableBase::MakeAndOpenContiguousPageGroup 2020-12-02 06:43:37 -08:00
Michael Scire
6a85f7225d kern: implement DisableDeviceAddressSpaceMerge 2020-12-02 06:43:37 -08:00
Michael Scire
f469dfbeb3 kern: SvcGetResourceLimitPeakValue 2020-12-02 06:43:37 -08:00
Michael Scire
cc11d452e5 kern: KMemoryManager::Allocate -> AllocateAndOpen 2020-12-02 06:43:37 -08:00
Michael Scire
3bce008170 kern: implement kmemoryblock/kmemoryinfo merge disable 2020-12-02 06:43:37 -08:00
Michael Scire
3383509da6 kern: remove KMemoryAttribute_AnyLocked 2020-12-02 06:43:37 -08:00
Michael Scire
281dcf232a kern: update KMemoryBlockManagerUpdateAllocator api 2020-12-02 06:43:37 -08:00
Michael Scire
71a2fe1bb6 kern: implement new software-reserved page table bits 2020-12-02 06:43:37 -08:00
Michael Scire
4a216dc928 kern: update KPageTableBase for new disable-merge attrs 2020-12-02 06:43:37 -08:00
Michael Scire
18099e19b1 fusee: recognize/support 11.x kernel 2020-12-02 06:43:37 -08:00
Michael Scire
a0a45853dd nogc: update for new lafw 2020-12-02 06:43:37 -08:00
Michael Scire
fe9a4cd2fc fusee: whoops 2020-12-02 06:43:37 -08:00
Michael Scire
88a66c89e2 fusee: fix 11.x pk21 support 2020-12-02 06:43:37 -08:00
Michael Scire
93128b6b17 fusee-secondary: update for 11.0.0 erista 2020-12-02 06:43:37 -08:00
Michael Scire
db2de8ef31 erpt: lightly update (TODO: use context, do new svc stuff) 2020-12-02 06:43:37 -08:00
Michael Scire
05832cec73 sm: implement UserService::DetachClient 2020-12-02 06:43:37 -08:00
Michael Scire
632c8984c8 loader: update for 11.0.0 (anti-dg + set program args abi) 2020-12-02 06:43:37 -08:00
Michael Scire
694e3b579e pgl: update for 11.0.0 2020-12-02 06:43:37 -08:00
Michael Scire
20eba0dc98 fs: nogc patches for 11.0.0 2020-12-02 06:43:37 -08:00
Michael Scire
730ef6d6db emummc: untested 11.0.0 support 2020-12-02 06:43:37 -08:00
Michael Scire
7cb24713ab kldr: update for 11.0.0 2020-12-02 06:43:37 -08:00
Michael Scire
a685842804 exo: update for 11.0.0 2020-12-02 06:43:37 -08:00
Michael Scire
ad6dd60474 result: update for accurate ::Includes 2020-12-02 06:43:37 -08:00
Michael Scire
05af215191 erpt: add update autogenerated ids 2020-12-02 06:43:37 -08:00
hexkyz
e06b73aafa boot: add missing RegisterWrite in DisplayConfigDsi01Init03 2020-11-30 19:35:06 +00:00
331 changed files with 7881 additions and 5263 deletions

View File

@@ -141,15 +141,16 @@ dist: dist-no-debug
cp stratosphere/creport/creport.elf atmosphere-$(AMSVER)-debug/creport.elf cp stratosphere/creport/creport.elf atmosphere-$(AMSVER)-debug/creport.elf
cp stratosphere/dmnt/dmnt.elf atmosphere-$(AMSVER)-debug/dmnt.elf cp stratosphere/dmnt/dmnt.elf atmosphere-$(AMSVER)-debug/dmnt.elf
cp stratosphere/eclct.stub/eclct.stub.elf atmosphere-$(AMSVER)-debug/eclct.stub.elf cp stratosphere/eclct.stub/eclct.stub.elf atmosphere-$(AMSVER)-debug/eclct.stub.elf
cp stratosphere/erpt/erpt.elf atmosphere-$(AMSVER)-debug/erpt.elf
cp stratosphere/fatal/fatal.elf atmosphere-$(AMSVER)-debug/fatal.elf cp stratosphere/fatal/fatal.elf atmosphere-$(AMSVER)-debug/fatal.elf
cp stratosphere/jpegdec/jpegdec.elf atmosphere-$(AMSVER)-debug/jpegdec.elf
cp stratosphere/loader/loader.elf atmosphere-$(AMSVER)-debug/loader.elf cp stratosphere/loader/loader.elf atmosphere-$(AMSVER)-debug/loader.elf
cp stratosphere/ncm/ncm.elf atmosphere-$(AMSVER)-debug/ncm.elf
cp stratosphere/pgl/pgl.elf atmosphere-$(AMSVER)-debug/pgl.elf
cp stratosphere/pm/pm.elf atmosphere-$(AMSVER)-debug/pm.elf cp stratosphere/pm/pm.elf atmosphere-$(AMSVER)-debug/pm.elf
cp stratosphere/ro/ro.elf atmosphere-$(AMSVER)-debug/ro.elf cp stratosphere/ro/ro.elf atmosphere-$(AMSVER)-debug/ro.elf
cp stratosphere/sm/sm.elf atmosphere-$(AMSVER)-debug/sm.elf cp stratosphere/sm/sm.elf atmosphere-$(AMSVER)-debug/sm.elf
cp stratosphere/spl/spl.elf atmosphere-$(AMSVER)-debug/spl.elf cp stratosphere/spl/spl.elf atmosphere-$(AMSVER)-debug/spl.elf
cp stratosphere/erpt/erpt.elf atmosphere-$(AMSVER)-debug/erpt.elf
cp stratosphere/jpegdec/jpegdec.elf atmosphere-$(AMSVER)-debug/jpegdec.elf
cp stratosphere/pgl/pgl.elf atmosphere-$(AMSVER)-debug/pgl.elf
cp troposphere/daybreak/daybreak.elf atmosphere-$(AMSVER)-debug/daybreak.elf cp troposphere/daybreak/daybreak.elf atmosphere-$(AMSVER)-debug/daybreak.elf
cd atmosphere-$(AMSVER)-debug; zip -r ../atmosphere-$(AMSVER)-debug.zip ./*; cd ../; cd atmosphere-$(AMSVER)-debug; zip -r ../atmosphere-$(AMSVER)-debug.zip ./*; cd ../;
rm -r atmosphere-$(AMSVER)-debug rm -r atmosphere-$(AMSVER)-debug

View File

@@ -35,6 +35,17 @@
# mmc space, encrypted to prevent detection. This backup can be used # mmc space, encrypted to prevent detection. This backup can be used
# to prevent unrecoverable edits in emergencies. # to prevent unrecoverable edits in emergencies.
# Key: log_port, default: 0.
# Desc: Controls what uart port exosphere will set up for logging.
# NOTE: 0 = UART-A, 1 = UART-B, 2 = UART-C, 3 = UART-D
# Key: log_baud_rate, default: 115200
# Desc: Controls the baud rate exosphere will set up for logging.
# NOTE: 0 is treated as equivalent to 115200.
# Key: log_inverted, default: 0.
# Desc: Controls whether the logging uart port is inverted.
[exosphere] [exosphere]
debugmode=1 debugmode=1
debugmode_user=0 debugmode_user=0
@@ -43,3 +54,6 @@ enable_user_pmu_access=0
blank_prodinfo_sysmmc=0 blank_prodinfo_sysmmc=0
blank_prodinfo_emummc=0 blank_prodinfo_emummc=0
allow_writing_to_cal_sysmmc=0 allow_writing_to_cal_sysmmc=0
log_port=0
log_baud_rate=115200
log_inverted=0

View File

@@ -1,4 +1,50 @@
# Changelog # Changelog
## 0.16.1
+ Support was added for 11.0.1.
+ `mesosphère` was updated to reflect the latest official kernel behavior.
+ A new svc::InfoType added in 11.0.0 was implemented (it wasn't discovered before 0.16.0 released).
+ The new Control Flow Integrity (CFI) logic added in 11.0.0 kernel was implemented.
+ `fs` logic was refactored and cleaned up to reflect some newer sysmodule behavioral and structural changes.
+ `exosphère` was updated to allow dynamic control of what uart port is used for logging.
+ This can be controlled by editing the `log_port`, `log_baud_rate`, and `log_inverted` fields in `exosphere.ini`.
+ `mesosphère` was updated to improve debugging capabilities ().
+ This is still a work in progress, but developers may be interested.
+ A bug was fixed that caused `fatal` to fatal error if the fatal process was already being debugged.
+ Several issues were fixed, and usability and stability were improved.
## 0.16.0
+ Support was added for 11.0.0.
+ `exosphère` was updated to reflect the latest official secure monitor behavior.
+ `mesosphère` was updated to reflect the latest official kernel behavior.
+ `loader`, `sm`, `boot`, `pgl` were updated to reflect the latest official behaviors.
+ **Please Note**: 11.0.0 implements an opt-in version of the atmosphère `sm` extension that allows for closing session without unregistering services.
+ Correspondingly, the extension will be deprecated in favor of the new official opt-in command. In 0.17.0, it will be removed entirely.
+ If your custom system module relies on this extension (however unlikely that seems to me), please update it accordingly.
+ `erpt` was partially updated to provide compatibility with 11.0.0.
+ The latest firmware attaches additional fields and context information to logs.
+ A future atmosphère update will implement this logic, so that users who are interested can also get the new information when examining their logs.
+ **Please Note**: 11.0.0 introduced breaking changes to the `usb` system module's `usb:ds` API.
+ Homebrew which uses the `usb:ds` service should rebuild with the latest libnx version to support running on 11.0.0.
+ The `boot` system module was rewritten to reflect the huge driver changes introduced in 8.0.0.
+ This includes a number of improvements to both logo display and battery management logic.
+ Support was added for configuring the address space width for `hbl`.
+ The `hbl_config!override_address_space_(#)` and `hbl_config!override_any_app_address_space` can now be set to `39_bit`, `36_bit`, or `32_bit` to control the address space for hbl on a per-override basis.
+ If a configuration has not been set, hbl will now default to 39-bit address space.
+ Previously, a legacy 36-bit address space was always used to maintain compatibility with 1.0.0.
+ A new loader extension was added to support 39-bit whenever possible (including mesosphere-on-1.0.0), with fallback to 36-bit when unavailable.
+ Support was added to a number of components for running on Mariko hardware.
+ The `boot` system module can now safely be run on mariko hardware, performing correct hardware initialization.
+ Daybreak (and generally, system update logic) were updated to be usable on Mariko.
+ Boot0 protection/management logic was updated to perform correct actions on Mariko.
+ Reboot to payload does not and cannot work on Mariko. Correspondingly, A "fatal error" handler was written, to display and save fatal errors from within TrustZone.
+ **Please Note:** Atmosphere is still not properly usable on Mariko hardware.
+ In particular, wake-from-sleep will not properly function (the magic numbers aren't set correctly), among a few other minor issues.
+ `exosphère` received support for building under debug configuration.
+ A small (otherwise unused) portion of IRAM is now reserved for debug-only exosphere code (this region is unused/untouched under release config).
+ This enables logging (including printf) to uart from the secure monitor, for those interested.
+ A number of bugs were fixed, including:
+ Minor issues in a number of filesystem related code were fixed.
+ An issue was fixed that could cause NCM to abort on consoles which came with 3.0.x and were never updated.
+ Several issues were fixed, and usability and stability were improved.
## 0.15.0 ## 0.15.0
+ fusee-primary's panic display was updated to automatically identify and give suggestions to resolve many of the most common errors users encounter. + fusee-primary's panic display was updated to automatically identify and give suggestions to resolve many of the most common errors users encounter.
+ Having been tested as well as I can alone, `mesosphere` (atmosphère's reimplementation of the Nintendo Switch kernel) is now available for users interested in trying it. + Having been tested as well as I can alone, `mesosphere` (atmosphère's reimplementation of the Nintendo Switch kernel) is now available for users interested in trying it.

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 = 25075973d31a5be6f2e769f1ea0fff44daf0cdfa commit = 5eed18eb527bbaa63aee5323c26de5b0cca6d28e
parent = 8ba513fefbcfd8278a433090e59017963ba9887f parent = 021b29d2dbc8ed0469bc822393e58c9f0d174d57
method = rebase method = rebase
cmdver = 0.4.1 cmdver = 0.4.1

View File

@@ -2,7 +2,7 @@
*A SDMMC driver replacement for Nintendo's Filesystem Services, by **m4xw*** *A SDMMC driver replacement for Nintendo's Filesystem Services, by **m4xw***
### Supported Horizon Versions ### Supported Horizon Versions
**1.0.0 - 10.0.0** **1.0.0 - 11.0.0**
## Features ## Features
* Arbitrary SDMMC backend selection * Arbitrary SDMMC backend selection

View File

@@ -49,6 +49,8 @@
#include "offsets/1000_exfat.h" #include "offsets/1000_exfat.h"
#include "offsets/1020.h" #include "offsets/1020.h"
#include "offsets/1020_exfat.h" #include "offsets/1020_exfat.h"
#include "offsets/1100.h"
#include "offsets/1100_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
@@ -69,6 +71,7 @@ static const fs_offsets_t GET_OFFSET_STRUCT_NAME(vers) = { \
.nand_mutex = FS_OFFSET##vers##_NAND_MUTEX, \ .nand_mutex = FS_OFFSET##vers##_NAND_MUTEX, \
.active_partition = FS_OFFSET##vers##_ACTIVE_PARTITION, \ .active_partition = FS_OFFSET##vers##_ACTIVE_PARTITION, \
.sdmmc_das_handle = FS_OFFSET##vers##_SDMMC_DAS_HANDLE, \ .sdmmc_das_handle = FS_OFFSET##vers##_SDMMC_DAS_HANDLE, \
.sdmmc_accessor_controller_open = FS_OFFSET##vers##_SDMMC_WRAPPER_CONTROLLER_OPEN, \
.sdmmc_accessor_controller_close = FS_OFFSET##vers##_SDMMC_WRAPPER_CONTROLLER_CLOSE, \ .sdmmc_accessor_controller_close = FS_OFFSET##vers##_SDMMC_WRAPPER_CONTROLLER_CLOSE, \
.sd_das_init = FS_OFFSET##vers##_SD_DAS_INIT, \ .sd_das_init = FS_OFFSET##vers##_SD_DAS_INIT, \
.nintendo_paths = FS_OFFSET##vers##_NINTENDO_PATHS, \ .nintendo_paths = FS_OFFSET##vers##_NINTENDO_PATHS, \
@@ -108,6 +111,8 @@ DEFINE_OFFSET_STRUCT(_1000);
DEFINE_OFFSET_STRUCT(_1000_EXFAT); DEFINE_OFFSET_STRUCT(_1000_EXFAT);
DEFINE_OFFSET_STRUCT(_1020); DEFINE_OFFSET_STRUCT(_1020);
DEFINE_OFFSET_STRUCT(_1020_EXFAT); DEFINE_OFFSET_STRUCT(_1020_EXFAT);
DEFINE_OFFSET_STRUCT(_1100);
DEFINE_OFFSET_STRUCT(_1100_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) {
@@ -177,6 +182,10 @@ const fs_offsets_t *get_fs_offsets(enum FS_VER version) {
return &(GET_OFFSET_STRUCT_NAME(_1020)); return &(GET_OFFSET_STRUCT_NAME(_1020));
case FS_VER_10_2_0_EXFAT: case FS_VER_10_2_0_EXFAT:
return &(GET_OFFSET_STRUCT_NAME(_1020_EXFAT)); return &(GET_OFFSET_STRUCT_NAME(_1020_EXFAT));
case FS_VER_11_0_0:
return &(GET_OFFSET_STRUCT_NAME(_1100));
case FS_VER_11_0_0_EXFAT:
return &(GET_OFFSET_STRUCT_NAME(_1100_EXFAT));
default: default:
fatal_abort(Fatal_UnknownVersion); fatal_abort(Fatal_UnknownVersion);
} }

View File

@@ -41,6 +41,7 @@ typedef struct {
// Misc funcs // Misc funcs
uintptr_t lock_mutex; uintptr_t lock_mutex;
uintptr_t unlock_mutex; uintptr_t unlock_mutex;
uintptr_t sdmmc_accessor_controller_open;
uintptr_t sdmmc_accessor_controller_close; uintptr_t sdmmc_accessor_controller_close;
// Misc data // Misc data
uintptr_t sd_mutex; uintptr_t sd_mutex;

View File

@@ -35,7 +35,7 @@ typedef struct sdmmc_accessor_vt
void *dtor; void *dtor;
void *map_device_addr_space; void *map_device_addr_space;
void *unmap_device_addr_space; void *unmap_device_addr_space;
void *controller_open; uint64_t (*sdmmc_accessor_controller_open)(void *);
uint64_t (*sdmmc_accessor_controller_close)(void *); uint64_t (*sdmmc_accessor_controller_close)(void *);
uint64_t (*read_write)(void *, uint64_t, uint64_t, void *, uint64_t, uint64_t); uint64_t (*read_write)(void *, uint64_t, uint64_t, void *, uint64_t, uint64_t);
// More not included because we don't use it. // More not included because we don't use it.

View File

@@ -71,6 +71,9 @@ enum FS_VER
FS_VER_10_2_0, FS_VER_10_2_0,
FS_VER_10_2_0_EXFAT, FS_VER_10_2_0_EXFAT,
FS_VER_11_0_0,
FS_VER_11_0_0_EXFAT,
FS_VER_MAX, FS_VER_MAX,
}; };

View File

@@ -34,6 +34,7 @@
#define FS_OFFSET_100_LOCK_MUTEX 0x2884 #define FS_OFFSET_100_LOCK_MUTEX 0x2884
#define FS_OFFSET_100_UNLOCK_MUTEX 0x28F0 #define FS_OFFSET_100_UNLOCK_MUTEX 0x28F0
#define FS_OFFSET_100_SDMMC_WRAPPER_CONTROLLER_OPEN 0
#define FS_OFFSET_100_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x6A8AC #define FS_OFFSET_100_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x6A8AC
// Misc Data // Misc Data

View File

@@ -34,6 +34,7 @@
#define FS_OFFSET_1000_LOCK_MUTEX 0x28910 #define FS_OFFSET_1000_LOCK_MUTEX 0x28910
#define FS_OFFSET_1000_UNLOCK_MUTEX 0x28960 #define FS_OFFSET_1000_UNLOCK_MUTEX 0x28960
#define FS_OFFSET_1000_SDMMC_WRAPPER_CONTROLLER_OPEN 0
#define FS_OFFSET_1000_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x1422E0 #define FS_OFFSET_1000_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x1422E0
// Misc Data // Misc Data

View File

@@ -34,6 +34,7 @@
#define FS_OFFSET_1000_EXFAT_LOCK_MUTEX 0x28910 #define FS_OFFSET_1000_EXFAT_LOCK_MUTEX 0x28910
#define FS_OFFSET_1000_EXFAT_UNLOCK_MUTEX 0x28960 #define FS_OFFSET_1000_EXFAT_UNLOCK_MUTEX 0x28960
#define FS_OFFSET_1000_EXFAT_SDMMC_WRAPPER_CONTROLLER_OPEN 0
#define FS_OFFSET_1000_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x1422E0 #define FS_OFFSET_1000_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x1422E0
// Misc Data // Misc Data

View File

@@ -34,6 +34,7 @@
#define FS_OFFSET_1020_LOCK_MUTEX 0x28910 #define FS_OFFSET_1020_LOCK_MUTEX 0x28910
#define FS_OFFSET_1020_UNLOCK_MUTEX 0x28960 #define FS_OFFSET_1020_UNLOCK_MUTEX 0x28960
#define FS_OFFSET_1020_SDMMC_WRAPPER_CONTROLLER_OPEN 0
#define FS_OFFSET_1020_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x142740 #define FS_OFFSET_1020_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x142740
// Misc Data // Misc Data

View File

@@ -34,6 +34,7 @@
#define FS_OFFSET_1020_EXFAT_LOCK_MUTEX 0x28910 #define FS_OFFSET_1020_EXFAT_LOCK_MUTEX 0x28910
#define FS_OFFSET_1020_EXFAT_UNLOCK_MUTEX 0x28960 #define FS_OFFSET_1020_EXFAT_UNLOCK_MUTEX 0x28960
#define FS_OFFSET_1020_EXFAT_SDMMC_WRAPPER_CONTROLLER_OPEN 0
#define FS_OFFSET_1020_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x142740 #define FS_OFFSET_1020_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x142740
// Misc Data // Misc Data

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_1100_H__
#define __FS_1100_H__
// Accessor vtable getters
#define FS_OFFSET_1100_SDMMC_ACCESSOR_GC 0x156D90
#define FS_OFFSET_1100_SDMMC_ACCESSOR_SD 0x154F40
#define FS_OFFSET_1100_SDMMC_ACCESSOR_NAND 0x1500F0
// Hooks
#define FS_OFFSET_1100_SDMMC_WRAPPER_READ 0x14B990
#define FS_OFFSET_1100_SDMMC_WRAPPER_WRITE 0x14BA70
#define FS_OFFSET_1100_RTLD 0x688
#define FS_OFFSET_1100_RTLD_DESTINATION ((uintptr_t)(INT64_C(-0x3C)))
#define FS_OFFSET_1100_CLKRST_SET_MIN_V_CLK_RATE 0x14AC40
// Misc funcs
#define FS_OFFSET_1100_LOCK_MUTEX 0x28FF0
#define FS_OFFSET_1100_UNLOCK_MUTEX 0x29040
#define FS_OFFSET_1100_SDMMC_WRAPPER_CONTROLLER_OPEN 0x14B840
#define FS_OFFSET_1100_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x14B8F0
// Misc Data
#define FS_OFFSET_1100_SD_MUTEX 0xE323E8
#define FS_OFFSET_1100_NAND_MUTEX 0xE2D338
#define FS_OFFSET_1100_ACTIVE_PARTITION 0xE2D378
#define FS_OFFSET_1100_SDMMC_DAS_HANDLE 0xE15D40
// NOPs
#define FS_OFFSET_1100_SD_DAS_INIT 0x273B4
// Nintendo Paths
#define FS_OFFSET_1100_NINTENDO_PATHS \
{ \
{.opcode_reg = 3, .adrp_offset = 0x0006D944, .add_rel_offset = 0x00000004}, \
{.opcode_reg = 3, .adrp_offset = 0x0007A3C0, .add_rel_offset = 0x00000004}, \
{.opcode_reg = 3, .adrp_offset = 0x00080708, .add_rel_offset = 0x00000004}, \
{.opcode_reg = 4, .adrp_offset = 0x00092198, .add_rel_offset = 0x00000004}, \
{.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0}, \
}
#endif // __FS_1100_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_1100_EXFAT_H__
#define __FS_1100_EXFAT_H__
// Accessor vtable getters
#define FS_OFFSET_1100_EXFAT_SDMMC_ACCESSOR_GC 0x156D90
#define FS_OFFSET_1100_EXFAT_SDMMC_ACCESSOR_SD 0x154F40
#define FS_OFFSET_1100_EXFAT_SDMMC_ACCESSOR_NAND 0x1500F0
// Hooks
#define FS_OFFSET_1100_EXFAT_SDMMC_WRAPPER_READ 0x14B990
#define FS_OFFSET_1100_EXFAT_SDMMC_WRAPPER_WRITE 0x14BA70
#define FS_OFFSET_1100_EXFAT_RTLD 0x688
#define FS_OFFSET_1100_EXFAT_RTLD_DESTINATION ((uintptr_t)(INT64_C(-0x3C)))
#define FS_OFFSET_1100_EXFAT_CLKRST_SET_MIN_V_CLK_RATE 0x14AC40
// Misc funcs
#define FS_OFFSET_1100_EXFAT_LOCK_MUTEX 0x28FF0
#define FS_OFFSET_1100_EXFAT_UNLOCK_MUTEX 0x29040
#define FS_OFFSET_1100_EXFAT_SDMMC_WRAPPER_CONTROLLER_OPEN 0x14B840
#define FS_OFFSET_1100_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x14B8F0
// Misc Data
#define FS_OFFSET_1100_EXFAT_SD_MUTEX 0xE403E8
#define FS_OFFSET_1100_EXFAT_NAND_MUTEX 0xE3B338
#define FS_OFFSET_1100_EXFAT_ACTIVE_PARTITION 0xE3B378
#define FS_OFFSET_1100_EXFAT_SDMMC_DAS_HANDLE 0xE23D40
// NOPs
#define FS_OFFSET_1100_EXFAT_SD_DAS_INIT 0x273B4
// Nintendo Paths
#define FS_OFFSET_1100_EXFAT_NINTENDO_PATHS \
{ \
{.opcode_reg = 3, .adrp_offset = 0x0006D944, .add_rel_offset = 0x00000004}, \
{.opcode_reg = 3, .adrp_offset = 0x0007A3C0, .add_rel_offset = 0x00000004}, \
{.opcode_reg = 3, .adrp_offset = 0x00080708, .add_rel_offset = 0x00000004}, \
{.opcode_reg = 4, .adrp_offset = 0x00092198, .add_rel_offset = 0x00000004}, \
{.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0}, \
}
#endif // __FS_1100_EXFAT_H__

View File

@@ -34,6 +34,7 @@
#define FS_OFFSET_200_LOCK_MUTEX 0x3264 #define FS_OFFSET_200_LOCK_MUTEX 0x3264
#define FS_OFFSET_200_UNLOCK_MUTEX 0x32D0 #define FS_OFFSET_200_UNLOCK_MUTEX 0x32D0
#define FS_OFFSET_200_SDMMC_WRAPPER_CONTROLLER_OPEN 0
#define FS_OFFSET_200_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x733F4 #define FS_OFFSET_200_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x733F4
// Misc Data // Misc Data

View File

@@ -34,6 +34,7 @@
#define FS_OFFSET_200_EXFAT_LOCK_MUTEX 0x3264 #define FS_OFFSET_200_EXFAT_LOCK_MUTEX 0x3264
#define FS_OFFSET_200_EXFAT_UNLOCK_MUTEX 0x32D0 #define FS_OFFSET_200_EXFAT_UNLOCK_MUTEX 0x32D0
#define FS_OFFSET_200_EXFAT_SDMMC_WRAPPER_CONTROLLER_OPEN 0
#define FS_OFFSET_200_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x733F4 #define FS_OFFSET_200_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x733F4
// Misc Data // Misc Data

View File

@@ -34,6 +34,7 @@
#define FS_OFFSET_210_LOCK_MUTEX 0x3264 #define FS_OFFSET_210_LOCK_MUTEX 0x3264
#define FS_OFFSET_210_UNLOCK_MUTEX 0x32D0 #define FS_OFFSET_210_UNLOCK_MUTEX 0x32D0
#define FS_OFFSET_210_SDMMC_WRAPPER_CONTROLLER_OPEN 0
#define FS_OFFSET_210_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x737D4 #define FS_OFFSET_210_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x737D4
// Misc Data // Misc Data

View File

@@ -34,6 +34,7 @@
#define FS_OFFSET_210_EXFAT_LOCK_MUTEX 0x3264 #define FS_OFFSET_210_EXFAT_LOCK_MUTEX 0x3264
#define FS_OFFSET_210_EXFAT_UNLOCK_MUTEX 0x32D0 #define FS_OFFSET_210_EXFAT_UNLOCK_MUTEX 0x32D0
#define FS_OFFSET_210_EXFAT_SDMMC_WRAPPER_CONTROLLER_OPEN 0
#define FS_OFFSET_210_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x737D4 #define FS_OFFSET_210_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x737D4
// Misc Data // Misc Data

View File

@@ -34,6 +34,7 @@
#define FS_OFFSET_300_LOCK_MUTEX 0x35CC #define FS_OFFSET_300_LOCK_MUTEX 0x35CC
#define FS_OFFSET_300_UNLOCK_MUTEX 0x3638 #define FS_OFFSET_300_UNLOCK_MUTEX 0x3638
#define FS_OFFSET_300_SDMMC_WRAPPER_CONTROLLER_OPEN 0
#define FS_OFFSET_300_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x8A270 #define FS_OFFSET_300_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x8A270
// Misc Data // Misc Data

View File

@@ -34,6 +34,7 @@
#define FS_OFFSET_300_EXFAT_LOCK_MUTEX 0x35CC #define FS_OFFSET_300_EXFAT_LOCK_MUTEX 0x35CC
#define FS_OFFSET_300_EXFAT_UNLOCK_MUTEX 0x3638 #define FS_OFFSET_300_EXFAT_UNLOCK_MUTEX 0x3638
#define FS_OFFSET_300_EXFAT_SDMMC_WRAPPER_CONTROLLER_OPEN 0
#define FS_OFFSET_300_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x8A270 #define FS_OFFSET_300_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x8A270
// Misc Data // Misc Data

View File

@@ -34,6 +34,7 @@
#define FS_OFFSET_301_LOCK_MUTEX 0x3638 #define FS_OFFSET_301_LOCK_MUTEX 0x3638
#define FS_OFFSET_301_UNLOCK_MUTEX 0x36A4 #define FS_OFFSET_301_UNLOCK_MUTEX 0x36A4
#define FS_OFFSET_301_SDMMC_WRAPPER_CONTROLLER_OPEN 0
#define FS_OFFSET_301_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x8A32C #define FS_OFFSET_301_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x8A32C
// Misc Data // Misc Data

View File

@@ -34,6 +34,7 @@
#define FS_OFFSET_301_EXFAT_LOCK_MUTEX 0x3638 #define FS_OFFSET_301_EXFAT_LOCK_MUTEX 0x3638
#define FS_OFFSET_301_EXFAT_UNLOCK_MUTEX 0x36A4 #define FS_OFFSET_301_EXFAT_UNLOCK_MUTEX 0x36A4
#define FS_OFFSET_301_EXFAT_SDMMC_WRAPPER_CONTROLLER_OPEN 0
#define FS_OFFSET_301_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x8A32C #define FS_OFFSET_301_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x8A32C
// Misc Data // Misc Data

View File

@@ -34,6 +34,7 @@
#define FS_OFFSET_400_LOCK_MUTEX 0x39A0 #define FS_OFFSET_400_LOCK_MUTEX 0x39A0
#define FS_OFFSET_400_UNLOCK_MUTEX 0x3A0C #define FS_OFFSET_400_UNLOCK_MUTEX 0x3A0C
#define FS_OFFSET_400_SDMMC_WRAPPER_CONTROLLER_OPEN 0
#define FS_OFFSET_400_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x9DB48 #define FS_OFFSET_400_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x9DB48
// Misc Data // Misc Data

View File

@@ -34,6 +34,7 @@
#define FS_OFFSET_400_EXFAT_LOCK_MUTEX 0x39A0 #define FS_OFFSET_400_EXFAT_LOCK_MUTEX 0x39A0
#define FS_OFFSET_400_EXFAT_UNLOCK_MUTEX 0x3A0C #define FS_OFFSET_400_EXFAT_UNLOCK_MUTEX 0x3A0C
#define FS_OFFSET_400_EXFAT_SDMMC_WRAPPER_CONTROLLER_OPEN 0
#define FS_OFFSET_400_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x9DB48 #define FS_OFFSET_400_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x9DB48
// Misc Data // Misc Data

View File

@@ -34,7 +34,8 @@
#define FS_OFFSET_410_LOCK_MUTEX 0x39A0 #define FS_OFFSET_410_LOCK_MUTEX 0x39A0
#define FS_OFFSET_410_UNLOCK_MUTEX 0x3A0C #define FS_OFFSET_410_UNLOCK_MUTEX 0x3A0C
#define FS_OFFSET_410_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x9DBAC #define FS_OFFSET_410_SDMMC_WRAPPER_CONTROLLER_OPEN 0
#define FS_OFFSET_410_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x9DBAC
// Misc Data // Misc Data
#define FS_OFFSET_410_SD_MUTEX 0xE80268 #define FS_OFFSET_410_SD_MUTEX 0xE80268

View File

@@ -34,6 +34,7 @@
#define FS_OFFSET_410_EXFAT_LOCK_MUTEX 0x39A0 #define FS_OFFSET_410_EXFAT_LOCK_MUTEX 0x39A0
#define FS_OFFSET_410_EXFAT_UNLOCK_MUTEX 0x3A0C #define FS_OFFSET_410_EXFAT_UNLOCK_MUTEX 0x3A0C
#define FS_OFFSET_410_EXFAT_SDMMC_WRAPPER_CONTROLLER_OPEN 0
#define FS_OFFSET_410_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x9DBAC #define FS_OFFSET_410_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x9DBAC
// Misc Data // Misc Data

View File

@@ -34,6 +34,7 @@
#define FS_OFFSET_500_LOCK_MUTEX 0x4080 #define FS_OFFSET_500_LOCK_MUTEX 0x4080
#define FS_OFFSET_500_UNLOCK_MUTEX 0x40D0 #define FS_OFFSET_500_UNLOCK_MUTEX 0x40D0
#define FS_OFFSET_500_SDMMC_WRAPPER_CONTROLLER_OPEN 0
#define FS_OFFSET_500_SDMMC_WRAPPER_CONTROLLER_CLOSE 0xC9380 #define FS_OFFSET_500_SDMMC_WRAPPER_CONTROLLER_CLOSE 0xC9380
// Misc Data // Misc Data

View File

@@ -34,6 +34,7 @@
#define FS_OFFSET_500_EXFAT_LOCK_MUTEX 0x4080 #define FS_OFFSET_500_EXFAT_LOCK_MUTEX 0x4080
#define FS_OFFSET_500_EXFAT_UNLOCK_MUTEX 0x40D0 #define FS_OFFSET_500_EXFAT_UNLOCK_MUTEX 0x40D0
#define FS_OFFSET_500_EXFAT_SDMMC_WRAPPER_CONTROLLER_OPEN 0
#define FS_OFFSET_500_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0xC9380 #define FS_OFFSET_500_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0xC9380
// Misc Data // Misc Data

View File

@@ -34,6 +34,7 @@
#define FS_OFFSET_510_LOCK_MUTEX 0x4080 #define FS_OFFSET_510_LOCK_MUTEX 0x4080
#define FS_OFFSET_510_UNLOCK_MUTEX 0x40D0 #define FS_OFFSET_510_UNLOCK_MUTEX 0x40D0
#define FS_OFFSET_510_SDMMC_WRAPPER_CONTROLLER_OPEN 0
#define FS_OFFSET_510_SDMMC_WRAPPER_CONTROLLER_CLOSE 0xC9750 #define FS_OFFSET_510_SDMMC_WRAPPER_CONTROLLER_CLOSE 0xC9750
// Misc Data // Misc Data

View File

@@ -34,6 +34,7 @@
#define FS_OFFSET_510_EXFAT_LOCK_MUTEX 0x4080 #define FS_OFFSET_510_EXFAT_LOCK_MUTEX 0x4080
#define FS_OFFSET_510_EXFAT_UNLOCK_MUTEX 0x40D0 #define FS_OFFSET_510_EXFAT_UNLOCK_MUTEX 0x40D0
#define FS_OFFSET_510_EXFAT_SDMMC_WRAPPER_CONTROLLER_OPEN 0
#define FS_OFFSET_510_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0xC9750 #define FS_OFFSET_510_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0xC9750
// Misc Data // Misc Data

View File

@@ -34,6 +34,7 @@
#define FS_OFFSET_600_LOCK_MUTEX 0x1412C0 #define FS_OFFSET_600_LOCK_MUTEX 0x1412C0
#define FS_OFFSET_600_UNLOCK_MUTEX 0x141310 #define FS_OFFSET_600_UNLOCK_MUTEX 0x141310
#define FS_OFFSET_600_SDMMC_WRAPPER_CONTROLLER_OPEN 0
#define FS_OFFSET_600_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x148500 #define FS_OFFSET_600_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x148500
// Misc Data // Misc Data

View File

@@ -34,6 +34,7 @@
#define FS_OFFSET_600_EXFAT_LOCK_MUTEX 0x14C9C0 #define FS_OFFSET_600_EXFAT_LOCK_MUTEX 0x14C9C0
#define FS_OFFSET_600_EXFAT_UNLOCK_MUTEX 0x14CA10 #define FS_OFFSET_600_EXFAT_UNLOCK_MUTEX 0x14CA10
#define FS_OFFSET_600_EXFAT_SDMMC_WRAPPER_CONTROLLER_OPEN 0
#define FS_OFFSET_600_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x153C00 #define FS_OFFSET_600_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x153C00
// Misc Data // Misc Data

View File

@@ -34,6 +34,7 @@
#define FS_OFFSET_700_LOCK_MUTEX 0x148A90 #define FS_OFFSET_700_LOCK_MUTEX 0x148A90
#define FS_OFFSET_700_UNLOCK_MUTEX 0x148AE0 #define FS_OFFSET_700_UNLOCK_MUTEX 0x148AE0
#define FS_OFFSET_700_SDMMC_WRAPPER_CONTROLLER_OPEN 0
#define FS_OFFSET_700_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x14FD50 #define FS_OFFSET_700_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x14FD50
// Misc Data // Misc Data

View File

@@ -34,6 +34,7 @@
#define FS_OFFSET_700_EXFAT_LOCK_MUTEX 0x154040 #define FS_OFFSET_700_EXFAT_LOCK_MUTEX 0x154040
#define FS_OFFSET_700_EXFAT_UNLOCK_MUTEX 0x154090 #define FS_OFFSET_700_EXFAT_UNLOCK_MUTEX 0x154090
#define FS_OFFSET_700_EXFAT_SDMMC_WRAPPER_CONTROLLER_OPEN 0
#define FS_OFFSET_700_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x15B300 #define FS_OFFSET_700_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x15B300
// Misc Data // Misc Data

View File

@@ -34,6 +34,7 @@
#define FS_OFFSET_800_LOCK_MUTEX 0x14B6D0 #define FS_OFFSET_800_LOCK_MUTEX 0x14B6D0
#define FS_OFFSET_800_UNLOCK_MUTEX 0x14B720 #define FS_OFFSET_800_UNLOCK_MUTEX 0x14B720
#define FS_OFFSET_800_SDMMC_WRAPPER_CONTROLLER_OPEN 0
#define FS_OFFSET_800_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x1529E0 #define FS_OFFSET_800_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x1529E0
// Misc Data // Misc Data

View File

@@ -34,6 +34,7 @@
#define FS_OFFSET_800_EXFAT_LOCK_MUTEX 0x156C80 #define FS_OFFSET_800_EXFAT_LOCK_MUTEX 0x156C80
#define FS_OFFSET_800_EXFAT_UNLOCK_MUTEX 0x156CD0 #define FS_OFFSET_800_EXFAT_UNLOCK_MUTEX 0x156CD0
#define FS_OFFSET_800_EXFAT_SDMMC_WRAPPER_CONTROLLER_OPEN 0
#define FS_OFFSET_800_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x15DF90 #define FS_OFFSET_800_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x15DF90
// Misc Data // Misc Data

View File

@@ -34,6 +34,7 @@
#define FS_OFFSET_810_LOCK_MUTEX 0x14B6D0 #define FS_OFFSET_810_LOCK_MUTEX 0x14B6D0
#define FS_OFFSET_810_UNLOCK_MUTEX 0x14B720 #define FS_OFFSET_810_UNLOCK_MUTEX 0x14B720
#define FS_OFFSET_810_SDMMC_WRAPPER_CONTROLLER_OPEN 0
#define FS_OFFSET_810_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x1529E0 #define FS_OFFSET_810_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x1529E0
// Misc Data // Misc Data

View File

@@ -34,6 +34,7 @@
#define FS_OFFSET_810_EXFAT_LOCK_MUTEX 0x156C80 #define FS_OFFSET_810_EXFAT_LOCK_MUTEX 0x156C80
#define FS_OFFSET_810_EXFAT_UNLOCK_MUTEX 0x156CD0 #define FS_OFFSET_810_EXFAT_UNLOCK_MUTEX 0x156CD0
#define FS_OFFSET_810_EXFAT_SDMMC_WRAPPER_CONTROLLER_OPEN 0
#define FS_OFFSET_810_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x15DF90 #define FS_OFFSET_810_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x15DF90
// Misc Data // Misc Data

View File

@@ -34,6 +34,7 @@
#define FS_OFFSET_900_LOCK_MUTEX 0x25280 #define FS_OFFSET_900_LOCK_MUTEX 0x25280
#define FS_OFFSET_900_UNLOCK_MUTEX 0x252D0 #define FS_OFFSET_900_UNLOCK_MUTEX 0x252D0
#define FS_OFFSET_900_SDMMC_WRAPPER_CONTROLLER_OPEN 0
#define FS_OFFSET_900_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x137740 #define FS_OFFSET_900_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x137740
// Misc Data // Misc Data

View File

@@ -34,6 +34,7 @@
#define FS_OFFSET_900_EXFAT_LOCK_MUTEX 0x25280 #define FS_OFFSET_900_EXFAT_LOCK_MUTEX 0x25280
#define FS_OFFSET_900_EXFAT_UNLOCK_MUTEX 0x252D0 #define FS_OFFSET_900_EXFAT_UNLOCK_MUTEX 0x252D0
#define FS_OFFSET_900_EXFAT_SDMMC_WRAPPER_CONTROLLER_OPEN 0
#define FS_OFFSET_900_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x137740 #define FS_OFFSET_900_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x137740
// Misc Data // Misc Data

View File

@@ -34,6 +34,7 @@
#define FS_OFFSET_910_LOCK_MUTEX 0x25280 #define FS_OFFSET_910_LOCK_MUTEX 0x25280
#define FS_OFFSET_910_UNLOCK_MUTEX 0x252D0 #define FS_OFFSET_910_UNLOCK_MUTEX 0x252D0
#define FS_OFFSET_910_SDMMC_WRAPPER_CONTROLLER_OPEN 0
#define FS_OFFSET_910_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x137750 #define FS_OFFSET_910_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x137750
// Misc Data // Misc Data

View File

@@ -34,6 +34,7 @@
#define FS_OFFSET_910_EXFAT_LOCK_MUTEX 0x25280 #define FS_OFFSET_910_EXFAT_LOCK_MUTEX 0x25280
#define FS_OFFSET_910_EXFAT_UNLOCK_MUTEX 0x252D0 #define FS_OFFSET_910_EXFAT_UNLOCK_MUTEX 0x252D0
#define FS_OFFSET_910_EXFAT_SDMMC_WRAPPER_CONTROLLER_OPEN 0
#define FS_OFFSET_910_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x137750 #define FS_OFFSET_910_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x137750
// Misc Data // Misc Data

View File

@@ -271,7 +271,7 @@ int sdmmc_nand_get_active_partition_index()
static uint64_t emummc_read_write_inner(void *buf, unsigned int sector, unsigned int num_sectors, bool is_write) static uint64_t emummc_read_write_inner(void *buf, unsigned int sector, unsigned int num_sectors, bool is_write)
{ {
if ((emuMMC_ctx.EMMC_Type == emuMMC_SD)) if ((emuMMC_ctx.EMMC_Type == emuMMC_SD_Raw))
{ {
// raw partition sector offset: emuMMC_ctx.EMMC_StoragePartitionOffset. // raw partition sector offset: emuMMC_ctx.EMMC_StoragePartitionOffset.
sector += emuMMC_ctx.EMMC_StoragePartitionOffset; sector += emuMMC_ctx.EMMC_StoragePartitionOffset;
@@ -318,6 +318,31 @@ static uint64_t emummc_read_write_inner(void *buf, unsigned int sector, unsigned
return res; return res;
} }
// Controller open wrapper
uint64_t sdmmc_wrapper_controller_open(int mmc_id)
{
uint64_t result;
sdmmc_accessor_t *_this;
_this = sdmmc_accessor_get(mmc_id);
if (_this != NULL)
{
// Lock eMMC xfer while SD card is being initialized by FS.
if (_this == sdmmc_accessor_get(FS_SDMMC_SD))
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);
// Unlock eMMC.
if (_this == sdmmc_accessor_get(FS_SDMMC_SD))
mutex_unlock_handler(FS_SDMMC_EMMC);
return result;
}
fatal_abort(Fatal_OpenAccessor);
}
// Controller close wrapper // Controller close wrapper
uint64_t sdmmc_wrapper_controller_close(int mmc_id) uint64_t sdmmc_wrapper_controller_close(int mmc_id)
{ {
@@ -389,7 +414,7 @@ uint64_t sdmmc_wrapper_read(void *buf, uint64_t bufSize, int mmc_id, unsigned in
if (first_sd_read) if (first_sd_read)
{ {
first_sd_read = false; first_sd_read = false;
if (emuMMC_ctx.EMMC_Type == emuMMC_SD) if (emuMMC_ctx.EMMC_Type == emuMMC_SD_Raw)
{ {
// Because some SD cards have issues with emuMMC's driver // Because some SD cards have issues with emuMMC's driver
// we currently swap to FS's driver after first SD read // we currently swap to FS's driver after first SD read
@@ -400,7 +425,7 @@ uint64_t sdmmc_wrapper_read(void *buf, uint64_t bufSize, int mmc_id, unsigned in
} }
} }
// Call hekates driver. // Call hekate's driver.
if (sdmmc_storage_read(&sd_storage, sector, num_sectors, buf)) if (sdmmc_storage_read(&sd_storage, sector, num_sectors, buf))
{ {
mutex_unlock_handler(mmc_id); mutex_unlock_handler(mmc_id);

View File

@@ -52,6 +52,7 @@ void mutex_lock_handler(int mmc_id);
void mutex_unlock_handler(int mmc_id); void mutex_unlock_handler(int mmc_id);
// Hooks // Hooks
uint64_t sdmmc_wrapper_controller_open(int mmc_id);
uint64_t sdmmc_wrapper_controller_close(int mmc_id); uint64_t sdmmc_wrapper_controller_close(int mmc_id);
uint64_t sdmmc_wrapper_read(void *buf, uint64_t bufSize, int mmc_id, unsigned int sector, unsigned int num_sectors); uint64_t sdmmc_wrapper_read(void *buf, uint64_t bufSize, int mmc_id, unsigned int sector, unsigned int num_sectors);
uint64_t sdmmc_wrapper_write(int mmc_id, unsigned int sector, unsigned int num_sectors, void *buf, uint64_t bufSize); uint64_t sdmmc_wrapper_write(int mmc_id, unsigned int sector, unsigned int num_sectors, void *buf, uint64_t bufSize);

View File

@@ -30,7 +30,7 @@ enum emuMMC_Type
emuMMC_EMMC = 0, emuMMC_EMMC = 0,
// SD Device raw // SD Device raw
emuMMC_SD, emuMMC_SD_Raw,
// SD Device File // SD Device File
emuMMC_SD_File, emuMMC_SD_File,

View File

@@ -92,7 +92,7 @@ volatile __attribute__((aligned(0x1000))) emuMMC_ctx_t emuMMC_ctx = {
.fs_ver = FS_VER_MAX, .fs_ver = FS_VER_MAX,
// SD Default Metadata // SD Default Metadata
.SD_Type = emuMMC_SD, .SD_Type = emuMMC_SD_Raw,
.SD_StoragePartitionOffset = 0, .SD_StoragePartitionOffset = 0,
// EMMC Default Metadata // EMMC Default Metadata
@@ -285,6 +285,9 @@ void setup_hooks(void)
INJECT_HOOK(fs_offsets->sdmmc_wrapper_read, sdmmc_wrapper_read); INJECT_HOOK(fs_offsets->sdmmc_wrapper_read, sdmmc_wrapper_read);
// sdmmc_wrapper_write hook // sdmmc_wrapper_write hook
INJECT_HOOK(fs_offsets->sdmmc_wrapper_write, sdmmc_wrapper_write); INJECT_HOOK(fs_offsets->sdmmc_wrapper_write, sdmmc_wrapper_write);
// sdmmc_wrapper_controller_open hook
if (fs_offsets->sdmmc_accessor_controller_open)
INJECT_HOOK(fs_offsets->sdmmc_accessor_controller_open, sdmmc_wrapper_controller_open);
// sdmmc_wrapper_controller_close hook // sdmmc_wrapper_controller_close hook
INJECT_HOOK(fs_offsets->sdmmc_accessor_controller_close, sdmmc_wrapper_controller_close); INJECT_HOOK(fs_offsets->sdmmc_accessor_controller_close, sdmmc_wrapper_controller_close);
@@ -346,7 +349,7 @@ static void load_emummc_ctx(void)
emuMMC_ctx.id = config.base_cfg.id; emuMMC_ctx.id = config.base_cfg.id;
emuMMC_ctx.EMMC_Type = (enum emuMMC_Type)config.base_cfg.type; emuMMC_ctx.EMMC_Type = (enum emuMMC_Type)config.base_cfg.type;
emuMMC_ctx.fs_ver = (enum FS_VER)config.base_cfg.fs_version; emuMMC_ctx.fs_ver = (enum FS_VER)config.base_cfg.fs_version;
if (emuMMC_ctx.EMMC_Type == emuMMC_SD) if (emuMMC_ctx.EMMC_Type == emuMMC_SD_Raw)
{ {
emuMMC_ctx.EMMC_StoragePartitionOffset = config.partition_cfg.start_sector; emuMMC_ctx.EMMC_StoragePartitionOffset = config.partition_cfg.start_sector;
} }

View File

@@ -72,6 +72,9 @@ namespace ams::secmon::boot {
/* care of it here. Perhaps we should read the number of anti-downgrade fuses burnt, and translate that */ /* care of it here. Perhaps we should read the number of anti-downgrade fuses burnt, and translate that */
/* to the warmboot key? To be decided during the process of implementing ams-on-mariko support. */ /* to the warmboot key? To be decided during the process of implementing ams-on-mariko support. */
reg::Write(pmc + APBDEV_PMC_SECURE_SCRATCH32, 0x129); reg::Write(pmc + APBDEV_PMC_SECURE_SCRATCH32, 0x129);
/* TODO: Fix to ensure correct scratch contents on mariko, as otherwise wb is broken. */
AMS_ABORT_UNLESS(fuse::GetSocType() != fuse::SocType_Mariko);
} }
/* This function derives the master kek and device keys using the tsec root key. */ /* This function derives the master kek and device keys using the tsec root key. */

View File

@@ -960,7 +960,7 @@ namespace ams::secmon {
} }
void SetupLogForBoot() { void SetupLogForBoot() {
log::Initialize(); log::Initialize(secmon::GetLogPort(), secmon::GetLogBaudRate(), secmon::GetLogFlags());
log::SendText("OHAYO\n", 6); log::SendText("OHAYO\n", 6);
log::Flush(); log::Flush();
} }

View File

@@ -47,7 +47,7 @@ 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_CopperSamsung4GB] = pkg1::MemorySize_4GB, [fuse::DramId_FiveHynix1y4GB] = pkg1::MemorySize_4GB,
[fuse::DramId_IcosaSamsung6GB] = pkg1::MemorySize_6GB, [fuse::DramId_IcosaSamsung6GB] = pkg1::MemorySize_6GB,
[fuse::DramId_CopperHynix4GB] = pkg1::MemorySize_4GB, [fuse::DramId_CopperHynix4GB] = pkg1::MemorySize_4GB,
[fuse::DramId_CopperMicron4GB] = pkg1::MemorySize_4GB, [fuse::DramId_CopperMicron4GB] = pkg1::MemorySize_4GB,
@@ -66,9 +66,13 @@ namespace ams::secmon::smc {
[fuse::DramId_HoagSamsung1y4GBX] = pkg1::MemorySize_4GB, [fuse::DramId_HoagSamsung1y4GBX] = pkg1::MemorySize_4GB,
[fuse::DramId_IowaSamsung1y4GBY] = pkg1::MemorySize_4GB, [fuse::DramId_IowaSamsung1y4GBY] = pkg1::MemorySize_4GB,
[fuse::DramId_IowaSamsung1y8GBY] = pkg1::MemorySize_8GB, [fuse::DramId_IowaSamsung1y8GBY] = pkg1::MemorySize_8GB,
[fuse::DramId_IowaSamsung1y4GBA] = pkg1::MemorySize_4GB, [fuse::DramId_FiveSamsung1y4GB] = pkg1::MemorySize_4GB,
[fuse::DramId_FiveSamsung1y8GBX] = pkg1::MemorySize_8GB, [fuse::DramId_HoagSamsung1y8GBX] = pkg1::MemorySize_8GB,
[fuse::DramId_FiveSamsung1y4GBX] = pkg1::MemorySize_4GB, [fuse::DramId_FiveSamsung1y4GBX] = pkg1::MemorySize_4GB,
[fuse::DramId_IowaMicron1y4GB] = pkg1::MemorySize_4GB,
[fuse::DramId_HoagMicron1y4GB] = pkg1::MemorySize_4GB,
[fuse::DramId_FiveMicron1y4GB] = pkg1::MemorySize_4GB,
[fuse::DramId_FiveSamsung1y8GBX] = pkg1::MemorySize_8GB,
}; };
constexpr const pkg1::MemoryMode MemoryModes[] = { constexpr const pkg1::MemoryMode MemoryModes[] = {
@@ -278,6 +282,10 @@ namespace ams::secmon::smc {
return SmcResult::NotInitialized; return SmcResult::NotInitialized;
} }
break; break;
case ConfigItem::ExosphereLogConfiguration:
/* Get the log configuration. */
args.r[1] = (static_cast<u64>(static_cast<u8>(secmon::GetLogPort())) << 32) | static_cast<u64>(secmon::GetLogBaudRate());
break;
default: default:
return SmcResult::InvalidArgument; return SmcResult::InvalidArgument;
} }

View File

@@ -40,15 +40,16 @@ namespace ams::secmon::smc {
Package2Hash = 17, Package2Hash = 17,
/* Extension config items for exosphere. */ /* Extension config items for exosphere. */
ExosphereApiVersion = 65000, ExosphereApiVersion = 65000,
ExosphereNeedsReboot = 65001, ExosphereNeedsReboot = 65001,
ExosphereNeedsShutdown = 65002, ExosphereNeedsShutdown = 65002,
ExosphereGitCommitHash = 65003, ExosphereGitCommitHash = 65003,
ExosphereHasRcmBugPatch = 65004, ExosphereHasRcmBugPatch = 65004,
ExosphereBlankProdInfo = 65005, ExosphereBlankProdInfo = 65005,
ExosphereAllowCalWrites = 65006, ExosphereAllowCalWrites = 65006,
ExosphereEmummcType = 65007, ExosphereEmummcType = 65007,
ExospherePayloadAddress = 65008, ExospherePayloadAddress = 65008,
ExosphereLogConfiguration = 65009,
}; };
SmcResult SmcGetConfigUser(SmcArguments &args); SmcResult SmcGetConfigUser(SmcArguments &args);

View File

@@ -409,6 +409,7 @@ namespace ams::secmon::smc {
/* NOTE: Nintendo only does this on dev, but we will always do it. */ /* NOTE: Nintendo only does this on dev, but we will always do it. */
if (true /* !pkg1::IsProduction() */) { if (true /* !pkg1::IsProduction() */) {
log::SendText("OYASUMI\n", 8); log::SendText("OYASUMI\n", 8);
log::Flush();
} }
/* If we're on erista, configure the bootrom to allow our custom warmboot firmware. */ /* If we're on erista, configure the bootrom to allow our custom warmboot firmware. */

View File

@@ -88,6 +88,9 @@ typedef enum {
FS_VER_10_2_0, FS_VER_10_2_0,
FS_VER_10_2_0_EXFAT, FS_VER_10_2_0_EXFAT,
FS_VER_11_0_0,
FS_VER_11_0_0_EXFAT,
FS_VER_MAX, FS_VER_MAX,
} emummc_fs_ver_t; } emummc_fs_ver_t;

View File

@@ -34,11 +34,17 @@
#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_LOG_FLAG_INVERTED (1 << 0u)
typedef struct { typedef struct {
uint32_t magic; uint32_t magic;
uint32_t target_firmware; uint32_t target_firmware;
uint32_t flags; uint32_t flags[2];
uint32_t reserved[5]; uint16_t lcd_vendor;
uint8_t log_port;
uint8_t log_flags;
uint32_t log_baud_rate;
uint32_t reserved1[2];
exo_emummc_config_t emummc_cfg; exo_emummc_config_t emummc_cfg;
} exosphere_config_t; } exosphere_config_t;
@@ -54,6 +60,9 @@ _Static_assert(sizeof(exosphere_config_t) == 0x20 + sizeof(exo_emummc_config_t),
#define EXOSPHERE_BLANK_PRODINFO_SYSMMC_KEY "blank_prodinfo_sysmmc" #define EXOSPHERE_BLANK_PRODINFO_SYSMMC_KEY "blank_prodinfo_sysmmc"
#define EXOSPHERE_BLANK_PRODINFO_EMUMMC_KEY "blank_prodinfo_emummc" #define EXOSPHERE_BLANK_PRODINFO_EMUMMC_KEY "blank_prodinfo_emummc"
#define EXOSPHERE_ALLOW_WRITING_TO_CAL_SYSMMC_KEY "allow_writing_to_cal_sysmmc" #define EXOSPHERE_ALLOW_WRITING_TO_CAL_SYSMMC_KEY "allow_writing_to_cal_sysmmc"
#define EXOSPHERE_LOG_PORT_KEY "log_port"
#define EXOSPHERE_LOG_BAUD_RATE_KEY "log_baud_rate"
#define EXOSPHERE_LOG_INVERTED_KEY "log_inverted"
typedef struct { typedef struct {
int debugmode; int debugmode;
@@ -63,6 +72,9 @@ typedef struct {
int blank_prodinfo_sysmmc; int blank_prodinfo_sysmmc;
int blank_prodinfo_emummc; int blank_prodinfo_emummc;
int allow_writing_to_cal_sysmmc; int allow_writing_to_cal_sysmmc;
int log_port;
int log_baud_rate;
int log_inverted;
} exosphere_parse_cfg_t; } exosphere_parse_cfg_t;
#endif #endif

View File

@@ -423,6 +423,9 @@ static const uint8_t g_fs_hashes[FS_VER_MAX][0x8] = {
"\xA9\x52\xB6\x57\xAD\xF9\xC2\xBA", /* FS_VER_10_2_0 */ "\xA9\x52\xB6\x57\xAD\xF9\xC2\xBA", /* FS_VER_10_2_0 */
"\x16\x0D\x3E\x10\x4E\xAD\x61\x76", /* FS_VER_10_2_0_EXFAT */ "\x16\x0D\x3E\x10\x4E\xAD\x61\x76", /* FS_VER_10_2_0_EXFAT */
"\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 */
}; };
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

@@ -541,6 +541,60 @@ static const instruction_t MAKE_KERNEL_PATCH_NAME(1000, proc_id_send)[] = {0xA9B
static const uint8_t MAKE_KERNEL_PATTERN_NAME(1000, proc_id_recv)[] = {0x88, 0x03, 0x40, 0xF9, 0x08, 0x1D, 0x40, 0xF9, 0xE0, 0x03, 0x1C, 0xAA, 0x00, 0x01, 0x3F, 0xD6, 0xE8, 0x87, 0x40, 0xF9, 0x08, 0x49, 0x3A, 0x8B, 0x09, 0xFC, 0x60, 0xD3}; static const uint8_t MAKE_KERNEL_PATTERN_NAME(1000, proc_id_recv)[] = {0x88, 0x03, 0x40, 0xF9, 0x08, 0x1D, 0x40, 0xF9, 0xE0, 0x03, 0x1C, 0xAA, 0x00, 0x01, 0x3F, 0xD6, 0xE8, 0x87, 0x40, 0xF9, 0x08, 0x49, 0x3A, 0x8B, 0x09, 0xFC, 0x60, 0xD3};
static const instruction_t MAKE_KERNEL_PATCH_NAME(1000, proc_id_recv)[] = {0xA9BF2FEA, 0xF94067EB, 0x2A1A03EA, 0xD37EF54A, 0xF86A696A, 0x92FFFFE9, 0x8A090148, 0xD2FFFFE9, 0x8A09014A, 0xD2FFFFC9, 0xEB09015F, 0x54000100, 0xA9BF27E8, 0xF9400388, 0xF9401D08, 0xAA1C03E0, 0xD63F0100, 0xA8C127E8, 0xAA0003E8, 0xA8C12FEA, 0xAA0803E0}; static const instruction_t MAKE_KERNEL_PATCH_NAME(1000, proc_id_recv)[] = {0xA9BF2FEA, 0xF94067EB, 0x2A1A03EA, 0xD37EF54A, 0xF86A696A, 0x92FFFFE9, 0x8A090148, 0xD2FFFFE9, 0x8A09014A, 0xD2FFFFC9, 0xEB09015F, 0x54000100, 0xA9BF27E8, 0xF9400388, 0xF9401D08, 0xAA1C03E0, 0xD63F0100, 0xA8C127E8, 0xAA0003E8, 0xA8C12FEA, 0xAA0803E0};
/*
stp x10, x11, [sp, #-0x10]!
ldr x11, [sp, #0x80]
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, [x21]
ldr x8, [x8, #0x38]
mov x0, x21
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(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};
/*
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, [x24]
ldr x8, [x8, #0x38]
mov x0, x24
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(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};
/* svcControlCodeMemory Patches */ /* svcControlCodeMemory Patches */
/* b.eq -> nop */ /* b.eq -> nop */
@@ -550,6 +604,7 @@ static const instruction_t MAKE_KERNEL_PATCH_NAME(700, svc_control_codememory)[
static const instruction_t MAKE_KERNEL_PATCH_NAME(800, svc_control_codememory)[] = {MAKE_NOP}; static const instruction_t MAKE_KERNEL_PATCH_NAME(800, 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(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(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 */
@@ -557,6 +612,7 @@ static const instruction_t MAKE_KERNEL_PATCH_NAME(700, system_memory_increase)[
static const instruction_t MAKE_KERNEL_PATCH_NAME(800, system_memory_increase)[] = {0x52A3B013}; /* MOV W19, #0x1D800000 */ static const instruction_t MAKE_KERNEL_PATCH_NAME(800, 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(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 */
/* Hook Definitions. */ /* Hook Definitions. */
static const kernel_patch_t g_kernel_patches_100[] = { static const kernel_patch_t g_kernel_patches_100[] = {
@@ -821,6 +877,64 @@ static const kernel_patch_t g_kernel_patches_1000[] = {
} }
}; };
static const kernel_patch_t g_kernel_patches_1100[] = {
{ /* Send Message Process ID Patch. */
.pattern_size = 0x1C,
.pattern = MAKE_KERNEL_PATTERN_NAME(1100, proc_id_send),
.pattern_hook_offset = 0x0,
.payload_num_instructions = sizeof(MAKE_KERNEL_PATCH_NAME(1100, proc_id_send))/sizeof(instruction_t),
.branch_back_offset = 0x10,
.payload = MAKE_KERNEL_PATCH_NAME(1100, proc_id_send)
},
{ /* Receive Message Process ID Patch. */
.pattern_size = 0x1C,
.pattern = MAKE_KERNEL_PATTERN_NAME(1100, proc_id_recv),
.pattern_hook_offset = 0x0,
.payload_num_instructions = sizeof(MAKE_KERNEL_PATCH_NAME(1100, proc_id_recv))/sizeof(instruction_t),
.branch_back_offset = 0x10,
.payload = MAKE_KERNEL_PATCH_NAME(1100, proc_id_recv)
},
{ /* svcControlCodeMemory Patch. */
.payload_num_instructions = sizeof(MAKE_KERNEL_PATCH_NAME(1100, svc_control_codememory))/sizeof(instruction_t),
.payload = MAKE_KERNEL_PATCH_NAME(1100, svc_control_codememory),
.patch_offset = 0x2FCE0,
},
{ /* System Memory Increase Patch. */
.payload_num_instructions = sizeof(MAKE_KERNEL_PATCH_NAME(1100, system_memory_increase))/sizeof(instruction_t),
.payload = MAKE_KERNEL_PATCH_NAME(1100, system_memory_increase),
.patch_offset = 0x490C4,
}
};
static const kernel_patch_t g_kernel_patches_1101[] = {
{ /* Send Message Process ID Patch. */
.pattern_size = 0x1C,
.pattern = MAKE_KERNEL_PATTERN_NAME(1100, proc_id_send),
.pattern_hook_offset = 0x0,
.payload_num_instructions = sizeof(MAKE_KERNEL_PATCH_NAME(1100, proc_id_send))/sizeof(instruction_t),
.branch_back_offset = 0x10,
.payload = MAKE_KERNEL_PATCH_NAME(1100, proc_id_send)
},
{ /* Receive Message Process ID Patch. */
.pattern_size = 0x1C,
.pattern = MAKE_KERNEL_PATTERN_NAME(1100, proc_id_recv),
.pattern_hook_offset = 0x0,
.payload_num_instructions = sizeof(MAKE_KERNEL_PATCH_NAME(1100, proc_id_recv))/sizeof(instruction_t),
.branch_back_offset = 0x10,
.payload = MAKE_KERNEL_PATCH_NAME(1100, proc_id_recv)
},
{ /* svcControlCodeMemory Patch. */
.payload_num_instructions = sizeof(MAKE_KERNEL_PATCH_NAME(1100, svc_control_codememory))/sizeof(instruction_t),
.payload = MAKE_KERNEL_PATCH_NAME(1100, svc_control_codememory),
.patch_offset = 0x2FD04,
},
{ /* System Memory Increase Patch. */
.payload_num_instructions = sizeof(MAKE_KERNEL_PATCH_NAME(1100, system_memory_increase))/sizeof(instruction_t),
.payload = MAKE_KERNEL_PATCH_NAME(1100, system_memory_increase),
.patch_offset = 0x490C4,
}
};
#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. */
@@ -906,6 +1020,24 @@ static const kernel_info_t g_kernel_infos[] = {
.embedded_ini_ptr = 0x178, .embedded_ini_ptr = 0x178,
.free_code_space_offset = 0x67790, .free_code_space_offset = 0x67790,
KERNEL_PATCHES(1000) KERNEL_PATCHES(1000)
},
{ /* 11.0.0. */
.hash = {0xC2, 0x0E, 0xB3, 0x1B, 0xBF, 0x0B, 0x82, 0xF3, 0x3D, 0xFD, 0x47, 0x04, 0xB4, 0x44, 0x38, 0x47, 0x64, 0xAB, 0xD8, 0x70, 0x2F, 0x0E, 0x0C, 0x37, 0x82, 0x28, 0x02, 0x24, 0xB8, 0x6E, 0xCE, 0x05, },
.hash_offset = 0x1C4,
.hash_size = 0x69000 - 0x1C4,
.embedded_ini_offset = 0x69000,
.embedded_ini_ptr = 0x180,
.free_code_space_offset = 0x49EE8,
KERNEL_PATCHES(1100)
},
{ /* 11.0.1. */
.hash = {0x68, 0xB9, 0x72, 0xB7, 0x97, 0x55, 0x87, 0x5E, 0x24, 0x95, 0x8D, 0x99, 0x0A, 0x77, 0xAB, 0xF1, 0xC5, 0xC1, 0x32, 0x80, 0x67, 0xF0, 0xA2, 0xEC, 0x9C, 0xEF, 0xC3, 0x22, 0xE3, 0x42, 0xC0, 0x4D, },
.hash_offset = 0x1C4,
.hash_size = 0x69000 - 0x1C4,
.embedded_ini_offset = 0x69000,
.embedded_ini_ptr = 0x180,
.free_code_space_offset = 0x49EE8,
KERNEL_PATCHES(1101)
} }
}; };
@@ -967,13 +1099,6 @@ void package2_patch_kernel(void *_kernel, size_t *kernel_size, bool is_sd_kernel
} }
if (kernel_info->embedded_ini_offset != 0) { if (kernel_info->embedded_ini_offset != 0) {
/* Copy in our kernel loader. */
const uint32_t kernel_ldr_offset = *((volatile uint64_t *)((uintptr_t)_kernel + kernel_info->embedded_ini_ptr + 8));
memcpy((void *)((uintptr_t)_kernel + kernel_ldr_offset), kernel_ldr_bin, kernel_ldr_bin_size);
/* Update size. */
*kernel_size = kernel_ldr_offset + kernel_ldr_bin_size;
/* Set output INI ptr. */ /* Set output INI ptr. */
*out_ini1 = (void *)((uintptr_t)_kernel + kernel_info->embedded_ini_offset); *out_ini1 = (void *)((uintptr_t)_kernel + kernel_info->embedded_ini_offset);
*((volatile uint64_t *)((uintptr_t)_kernel + kernel_info->embedded_ini_ptr)) = (uint64_t)*kernel_size; *((volatile uint64_t *)((uintptr_t)_kernel + kernel_info->embedded_ini_ptr)) = (uint64_t)*kernel_size;
@@ -1003,7 +1128,7 @@ void package2_patch_kernel(void *_kernel, size_t *kernel_size, bool is_sd_kernel
uint8_t *pattern_loc = search_pattern(kernel, *kernel_size, kernel_info->patches[i].pattern, kernel_info->patches[i].pattern_size); uint8_t *pattern_loc = search_pattern(kernel, *kernel_size, kernel_info->patches[i].pattern, kernel_info->patches[i].pattern_size);
if (pattern_loc == NULL) { if (pattern_loc == NULL) {
/* TODO: Should we print an error/abort here? */ fatal_error("kernel_patcher: failed to identify patch location!\n");
continue; continue;
} }
/* Patch kernel to branch to our hook at the desired place. */ /* Patch kernel to branch to our hook at the desired place. */

View File

@@ -196,6 +196,27 @@ static int exosphere_ini_handler(void *user, const char *section, const char *na
} else if (tmp == 0) { } else if (tmp == 0) {
parse_cfg->allow_writing_to_cal_sysmmc = 0; parse_cfg->allow_writing_to_cal_sysmmc = 0;
} }
} else if (strcmp(name, EXOSPHERE_LOG_PORT_KEY) == 0) {
sscanf(value, "%d", &tmp);
if (0 <= tmp && tmp < 4) {
parse_cfg->log_port = tmp;
} else {
parse_cfg->log_port = 0;
}
} else if (strcmp(name, EXOSPHERE_LOG_BAUD_RATE_KEY) == 0) {
sscanf(value, "%d", &tmp);
if (tmp > 0) {
parse_cfg->log_baud_rate = tmp;
} else {
parse_cfg->log_baud_rate = 115200;
}
} else if (strcmp(name, EXOSPHERE_LOG_INVERTED_KEY) == 0) {
sscanf(value, "%d", &tmp);
if (tmp == 1) {
parse_cfg->log_inverted = 1;
} else if (tmp == 0) {
parse_cfg->log_inverted = 0;
}
} else { } else {
return 0; return 0;
} }
@@ -239,7 +260,10 @@ 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_10_0_0) { if (target_firmware >= ATMOSPHERE_TARGET_FIRMWARE_11_0_0) {
CHECK_NCA("56211c7a5ed20a5332f5cdda67121e37", 11_0_1);
CHECK_NCA("594c90bcdbcccad6b062eadba0cd0e7e", 11_0_0);
} else if (target_firmware >= ATMOSPHERE_TARGET_FIRMWARE_10_0_0) {
CHECK_NCA("26325de4db3909e0ef2379787c7e671d", 10_2_0); CHECK_NCA("26325de4db3909e0ef2379787c7e671d", 10_2_0);
CHECK_NCA("5077973537f6735b564dd7475b779f87", 10_1_1); /* Exclusive to China. */ CHECK_NCA("5077973537f6735b564dd7475b779f87", 10_1_1); /* Exclusive to China. */
CHECK_NCA("fd1faed0ca750700d254c0915b93d506", 10_1_0); CHECK_NCA("fd1faed0ca750700d254c0915b93d506", 10_1_0);
@@ -337,6 +361,8 @@ static uint32_t nxboot_get_target_firmware(const void *package1loader) {
return ATMOSPHERE_TARGET_FIRMWARE_9_1_0; return ATMOSPHERE_TARGET_FIRMWARE_9_1_0;
} else if (memcmp(package1loader_header->build_timestamp, "20200303", 8) == 0) { } else if (memcmp(package1loader_header->build_timestamp, "20200303", 8) == 0) {
return ATMOSPHERE_TARGET_FIRMWARE_10_0_0; return ATMOSPHERE_TARGET_FIRMWARE_10_0_0;
} else if (memcmp(package1loader_header->build_timestamp, "20201030", 8) == 0) {
return ATMOSPHERE_TARGET_FIRMWARE_11_0_0;
} else { } else {
fatal_error("[NXBOOT] Unable to identify package1!\n"); fatal_error("[NXBOOT] Unable to identify package1!\n");
} }
@@ -460,9 +486,9 @@ static void nxboot_configure_exosphere(uint32_t target_firmware, unsigned int ke
const bool is_emummc = exo_emummc_cfg->base_cfg.magic == MAGIC_EMUMMC_CONFIG && exo_emummc_cfg->base_cfg.type != EMUMMC_TYPE_NONE; const bool is_emummc = exo_emummc_cfg->base_cfg.magic == MAGIC_EMUMMC_CONFIG && exo_emummc_cfg->base_cfg.type != EMUMMC_TYPE_NONE;
if (keygen_type) { if (keygen_type) {
exo_cfg.flags = EXOSPHERE_FLAG_PERFORM_620_KEYGEN; exo_cfg.flags[0] = EXOSPHERE_FLAG_PERFORM_620_KEYGEN;
} else { } else {
exo_cfg.flags = 0; exo_cfg.flags[0] = 0;
} }
/* Setup exosphere parse configuration with defaults. */ /* Setup exosphere parse configuration with defaults. */
@@ -474,6 +500,9 @@ static void nxboot_configure_exosphere(uint32_t target_firmware, unsigned int ke
.blank_prodinfo_sysmmc = 0, .blank_prodinfo_sysmmc = 0,
.blank_prodinfo_emummc = 0, .blank_prodinfo_emummc = 0,
.allow_writing_to_cal_sysmmc = 0, .allow_writing_to_cal_sysmmc = 0,
.log_port = 0,
.log_baud_rate = 115200,
.log_inverted = 0,
}; };
/* If we have an ini to read, parse it. */ /* If we have an ini to read, parse it. */
@@ -486,13 +515,17 @@ static void nxboot_configure_exosphere(uint32_t target_firmware, unsigned int ke
free(exosphere_ini); free(exosphere_ini);
/* Apply parse config. */ /* Apply parse config. */
if (parse_cfg.debugmode) exo_cfg.flags |= EXOSPHERE_FLAG_IS_DEBUGMODE_PRIV; if (parse_cfg.debugmode) exo_cfg.flags[0] |= EXOSPHERE_FLAG_IS_DEBUGMODE_PRIV;
if (parse_cfg.debugmode_user) exo_cfg.flags |= EXOSPHERE_FLAG_IS_DEBUGMODE_USER; if (parse_cfg.debugmode_user) exo_cfg.flags[0] |= EXOSPHERE_FLAG_IS_DEBUGMODE_USER;
if (parse_cfg.disable_user_exception_handlers) exo_cfg.flags |= EXOSPHERE_FLAG_DISABLE_USERMODE_EXCEPTION_HANDLERS; if (parse_cfg.disable_user_exception_handlers) exo_cfg.flags[0] |= EXOSPHERE_FLAG_DISABLE_USERMODE_EXCEPTION_HANDLERS;
if (parse_cfg.enable_user_pmu_access) exo_cfg.flags |= EXOSPHERE_FLAG_ENABLE_USERMODE_PMU_ACCESS; if (parse_cfg.enable_user_pmu_access) exo_cfg.flags[0] |= EXOSPHERE_FLAG_ENABLE_USERMODE_PMU_ACCESS;
if (parse_cfg.blank_prodinfo_sysmmc && !is_emummc) exo_cfg.flags |= EXOSPHERE_FLAG_BLANK_PRODINFO; if (parse_cfg.blank_prodinfo_sysmmc && !is_emummc) exo_cfg.flags[0] |= EXOSPHERE_FLAG_BLANK_PRODINFO;
if (parse_cfg.blank_prodinfo_emummc && is_emummc) exo_cfg.flags |= EXOSPHERE_FLAG_BLANK_PRODINFO; if (parse_cfg.blank_prodinfo_emummc && is_emummc) exo_cfg.flags[0] |= EXOSPHERE_FLAG_BLANK_PRODINFO;
if (parse_cfg.allow_writing_to_cal_sysmmc) exo_cfg.flags |= EXOSPHERE_FLAG_ALLOW_WRITING_TO_CAL_SYSMMC; if (parse_cfg.allow_writing_to_cal_sysmmc) exo_cfg.flags[0] |= EXOSPHERE_FLAG_ALLOW_WRITING_TO_CAL_SYSMMC;
exo_cfg.log_port = parse_cfg.log_port;
exo_cfg.log_baud_rate = parse_cfg.log_baud_rate;
if (parse_cfg.log_inverted) exo_cfg.log_flags |= EXOSPHERE_LOG_FLAG_INVERTED;
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");
@@ -521,6 +554,10 @@ static void nxboot_configure_stratosphere(uint32_t target_firmware) {
if (target_firmware >= ATMOSPHERE_TARGET_FIRMWARE_9_0_0 && !(fuse_get_reserved_odm(7) & ~0x000003FF)) { if (target_firmware >= ATMOSPHERE_TARGET_FIRMWARE_9_0_0 && !(fuse_get_reserved_odm(7) & ~0x000003FF)) {
kip_patches_set_enable_nogc(); kip_patches_set_enable_nogc();
} }
/* Check if the fuses are < 11.0.0, but firmware is >= 11.0.0 */
if (target_firmware >= ATMOSPHERE_TARGET_FIRMWARE_11_0_0 && !(fuse_get_reserved_odm(7) & ~0x00001FFF)) {
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_1000_CURRENT) { if (metadata->version_max >= PACKAGE2_MINVER_THEORETICAL && metadata->version_min < PACKAGE2_MAXVER_1100_CURRENT) {
return true; return true;
} }

View File

@@ -40,7 +40,8 @@
#define PACKAGE2_MAXVER_810 0xB #define PACKAGE2_MAXVER_810 0xB
#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_CURRENT 0xE #define PACKAGE2_MAXVER_1000 0xE
#define PACKAGE2_MAXVER_1100_CURRENT 0xF
#define PACKAGE2_MINVER_100 0x3 #define PACKAGE2_MINVER_100 0x3
#define PACKAGE2_MINVER_200 0x4 #define PACKAGE2_MINVER_200 0x4
@@ -54,7 +55,8 @@
#define PACKAGE2_MINVER_810 0xC #define PACKAGE2_MINVER_810 0xC
#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_CURRENT 0xF #define PACKAGE2_MINVER_1000 0xF
#define PACKAGE2_MINVER_1100_CURRENT 0x10
#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 = 10e9e0e8f926b11c2c7de16ffe15bea7d7ec2cdf commit = 5a18bea64545105c52d642d7789029b5ca875864
parent = 2ee2a4f1ac04bc7f15de8be8d57ad04d7e73f735 parent = 17c8c390fc84d059b89f563a8fae6936649d0d45
method = merge method = merge
cmdver = 0.4.1 cmdver = 0.4.1

View File

@@ -7,7 +7,7 @@ include $(dir $(abspath $(lastword $(MAKEFILE_LIST))))/../common.mk
# options for code generation # options for code generation
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
export DEFINES := $(ATMOSPHERE_DEFINES) -DATMOSPHERE_IS_MESOSPHERE export DEFINES := $(ATMOSPHERE_DEFINES) -DATMOSPHERE_IS_MESOSPHERE
export SETTINGS := $(ATMOSPHERE_SETTINGS) -O2 -mgeneral-regs-only -ffixed-x18 -Wextra -Werror -fno-non-call-exceptions export SETTINGS := $(ATMOSPHERE_SETTINGS) -Os -mgeneral-regs-only -ffixed-x18 -Wextra -Werror -fno-non-call-exceptions
export CFLAGS := $(ATMOSPHERE_CFLAGS) $(SETTINGS) $(DEFINES) $(INCLUDE) 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)

View File

@@ -51,7 +51,7 @@ namespace ams::fuse {
DramId_IcosaSamsung4GB = 0, DramId_IcosaSamsung4GB = 0,
DramId_IcosaHynix4GB = 1, DramId_IcosaHynix4GB = 1,
DramId_IcosaMicron4GB = 2, DramId_IcosaMicron4GB = 2,
DramId_CopperSamsung4GB = 3, DramId_FiveHynix1y4GB = 3,
DramId_IcosaSamsung6GB = 4, DramId_IcosaSamsung6GB = 4,
DramId_CopperHynix4GB = 5, DramId_CopperHynix4GB = 5,
DramId_CopperMicron4GB = 6, DramId_CopperMicron4GB = 6,
@@ -70,9 +70,13 @@ namespace ams::fuse {
DramId_HoagSamsung1y4GBX = 19, DramId_HoagSamsung1y4GBX = 19,
DramId_IowaSamsung1y4GBY = 20, DramId_IowaSamsung1y4GBY = 20,
DramId_IowaSamsung1y8GBY = 21, DramId_IowaSamsung1y8GBY = 21,
DramId_IowaSamsung1y4GBA = 22, DramId_FiveSamsung1y4GB = 22,
DramId_FiveSamsung1y8GBX = 23, DramId_HoagSamsung1y8GBX = 23,
DramId_FiveSamsung1y4GBX = 24, DramId_FiveSamsung1y4GBX = 24,
DramId_IowaMicron1y4GB = 25,
DramId_HoagMicron1y4GB = 26,
DramId_FiveMicron1y4GB = 27,
DramId_FiveSamsung1y8GBX = 28,
DramId_Count, DramId_Count,
}; };

View File

@@ -35,6 +35,7 @@ namespace ams::log {
#endif #endif
void Initialize(); void Initialize();
void Initialize(uart::Port port, u32 baud_rate, u32 flags);
void Finalize(); void Finalize();
void Printf(const char *fmt, ...) __attribute__((format(printf, 1, 2))); void Printf(const char *fmt, ...) __attribute__((format(printf, 1, 2)));

View File

@@ -24,7 +24,7 @@ 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 0x10 in Nintendo's code. */
constexpr inline int CurrentBootloaderVersion = 0xD; constexpr inline int CurrentBootloaderVersion = 0xE;
struct Package2Meta { struct Package2Meta {
using Magic = util::FourCC<'P','K','2','1'>; using Magic = util::FourCC<'P','K','2','1'>;

View File

@@ -116,6 +116,18 @@ namespace ams::secmon {
return GetSecmonConfiguration().GetLcdVendor(); return GetSecmonConfiguration().GetLcdVendor();
} }
ALWAYS_INLINE uart::Port GetLogPort() {
return GetSecmonConfiguration().GetLogPort();
}
ALWAYS_INLINE u8 GetLogFlags() {
return GetSecmonConfiguration().GetLogFlags();
}
ALWAYS_INLINE u32 GetLogBaudRate() {
return GetSecmonConfiguration().GetLogBaudRate();
}
ALWAYS_INLINE bool IsProduction() { ALWAYS_INLINE bool IsProduction() {
return GetSecmonConfiguration().IsProduction(); return GetSecmonConfiguration().IsProduction();
} }

View File

@@ -16,6 +16,7 @@
#pragma once #pragma once
#include <vapours.hpp> #include <vapours.hpp>
#include <exosphere/fuse.hpp> #include <exosphere/fuse.hpp>
#include <exosphere/uart.hpp>
#include <exosphere/secmon/secmon_emummc_context.hpp> #include <exosphere/secmon/secmon_emummc_context.hpp>
namespace ams::secmon { namespace ams::secmon {
@@ -39,8 +40,10 @@ namespace ams::secmon {
ams::TargetFirmware target_firmware; ams::TargetFirmware target_firmware;
u32 flags[2]; u32 flags[2];
u16 lcd_vendor; u16 lcd_vendor;
u16 reserved0; u8 log_port;
u32 reserved1[3]; u8 log_flags;
u32 log_baud_rate;
u32 reserved1[2];
EmummcConfiguration emummc_cfg; EmummcConfiguration emummc_cfg;
constexpr bool IsValid() const { return this->magic == Magic; } constexpr bool IsValid() const { return this->magic == Magic; }
@@ -54,17 +57,22 @@ namespace ams::secmon {
u8 hardware_type; u8 hardware_type;
u8 soc_type; u8 soc_type;
u8 hardware_state; u8 hardware_state;
u8 pad_0B[1]; u8 log_port;
u32 flags[2]; u32 flags[2];
u16 lcd_vendor; u16 lcd_vendor;
u16 reserved0; u8 log_flags;
u32 reserved1[(0x80 - 0x18) / sizeof(u32)]; u8 reserved0;
u32 log_baud_rate;
u32 reserved1[(0x80 - 0x1C) / sizeof(u32)];
constexpr void CopyFrom(const SecureMonitorStorageConfiguration &storage) { constexpr void CopyFrom(const SecureMonitorStorageConfiguration &storage) {
this->target_firmware = storage.target_firmware; this->target_firmware = storage.target_firmware;
this->flags[0] = storage.flags[0]; this->flags[0] = storage.flags[0];
this->flags[1] = storage.flags[1]; this->flags[1] = storage.flags[1];
this->lcd_vendor = storage.lcd_vendor; this->lcd_vendor = storage.lcd_vendor;
this->log_port = storage.log_port;
this->log_flags = storage.log_flags;
this->log_baud_rate = storage.log_baud_rate != 0 ? storage.log_baud_rate : 115200;
} }
void SetFuseInfo() { void SetFuseInfo() {
@@ -78,9 +86,13 @@ namespace ams::secmon {
constexpr fuse::HardwareType GetHardwareType() const { return static_cast<fuse::HardwareType>(this->hardware_type); } constexpr fuse::HardwareType GetHardwareType() const { return static_cast<fuse::HardwareType>(this->hardware_type); }
constexpr fuse::SocType GetSocType() const { return static_cast<fuse::SocType>(this->soc_type); } constexpr fuse::SocType GetSocType() const { return static_cast<fuse::SocType>(this->soc_type); }
constexpr fuse::HardwareState GetHardwareState() const { return static_cast<fuse::HardwareState>(this->hardware_state); } constexpr fuse::HardwareState GetHardwareState() const { return static_cast<fuse::HardwareState>(this->hardware_state); }
constexpr uart::Port GetLogPort() const { return static_cast<uart::Port>(this->log_port); }
constexpr u8 GetLogFlags() const { return this->log_flags; }
constexpr u16 GetLcdVendor() const { return this->lcd_vendor; } constexpr u16 GetLcdVendor() const { return this->lcd_vendor; }
constexpr u32 GetLogBaudRate() const { return this->log_baud_rate; }
constexpr bool IsProduction() const { return this->GetHardwareState() != fuse::HardwareState_Development; } constexpr bool IsProduction() const { return this->GetHardwareState() != fuse::HardwareState_Development; }
constexpr bool IsDevelopmentFunctionEnabledForKernel() const { return (this->flags[0] & SecureMonitorConfigurationFlag_IsDevelopmentFunctionEnabledForKernel) != 0; } constexpr bool IsDevelopmentFunctionEnabledForKernel() const { return (this->flags[0] & SecureMonitorConfigurationFlag_IsDevelopmentFunctionEnabledForKernel) != 0; }
@@ -101,10 +113,12 @@ namespace ams::secmon {
.hardware_type = {}, .hardware_type = {},
.soc_type = {}, .soc_type = {},
.hardware_state = {}, .hardware_state = {},
.pad_0B = {}, .log_port = uart::Port_ReservedDebug,
.flags = { SecureMonitorConfigurationFlag_Default, SecureMonitorConfigurationFlag_None }, .flags = { SecureMonitorConfigurationFlag_Default, SecureMonitorConfigurationFlag_None },
.lcd_vendor = {}, .lcd_vendor = {},
.log_flags = {},
.reserved0 = {}, .reserved0 = {},
.log_baud_rate = 115200,
.reserved1 = {}, .reserved1 = {},
}; };

View File

@@ -165,6 +165,7 @@ namespace ams::fuse {
} }
constexpr const TargetFirmware FuseVersionIncrementFirmwares[] = { constexpr const TargetFirmware FuseVersionIncrementFirmwares[] = {
TargetFirmware_11_0_0,
TargetFirmware_10_0_0, TargetFirmware_10_0_0,
TargetFirmware_9_1_0, TargetFirmware_9_1_0,
TargetFirmware_9_0_0, TargetFirmware_9_0_0,
@@ -207,7 +208,7 @@ namespace ams::fuse {
return 0; return 0;
} }
static_assert(GetExpectedFuseVersionImpl(TargetFirmware_10_0_0) == 13); static_assert(GetExpectedFuseVersionImpl(TargetFirmware_11_0_0) == 14);
static_assert(GetExpectedFuseVersionImpl(TargetFirmware_1_0_0) == 1); static_assert(GetExpectedFuseVersionImpl(TargetFirmware_1_0_0) == 1);
static_assert(GetExpectedFuseVersionImpl(static_cast<TargetFirmware>(0)) == 0); static_assert(GetExpectedFuseVersionImpl(static_cast<TargetFirmware>(0)) == 0);

View File

@@ -19,58 +19,46 @@ namespace ams::log {
namespace { namespace {
constexpr inline uart::Port UartLogPort = uart::Port_ReservedDebug; constexpr inline uart::Port DefaultLogPort = uart::Port_ReservedDebug;
constexpr inline int UartBaudRate = 115200; constexpr inline u32 DefaultLogFlags = static_cast<u32>(uart::Flag_None);
constexpr inline int DefaultBaudRate = 115200;
constinit uart::Port g_log_port = DefaultLogPort;
constinit bool g_initialized_uart = false; constinit bool g_initialized_uart = false;
constexpr inline u32 UartPortFlags = [] { ALWAYS_INLINE void SetupUartClock(uart::Port port) {
if constexpr (UartLogPort == uart::Port_ReservedDebug) { /* The debug port must always be set up, for compatibility with official hos. */
/* Logging to the debug port. */ pinmux::SetupUartA();
/* Don't invert transactions. */ clkrst::EnableUartAClock();
return uart::Flag_None;
} else if constexpr (UartLogPort == uart::Port_LeftJoyCon) {
/* Logging to left joy-con (e.g. with Joyless). */
/* Invert transactions. */
return uart::Flag_Inverted;
} else if constexpr (UartLogPort == uart::Port_RightJoyCon) {
/* Logging to right joy-con (e.g. with Joyless). */
/* Invert transactions. */
return uart::Flag_Inverted;
} else {
__builtin_unreachable();
}
}();
ALWAYS_INLINE void SetupUart() { /* If logging to a joy-con port, configure appropriately. */
if constexpr (UartLogPort == uart::Port_ReservedDebug) { if (port == uart::Port_LeftJoyCon) {
/* Logging to the debug port. */
pinmux::SetupUartA();
clkrst::EnableUartAClock();
} else if constexpr (UartLogPort == uart::Port_LeftJoyCon) {
/* Logging to left joy-con (e.g. with Joyless). */ /* Logging to left joy-con (e.g. with Joyless). */
static_assert(uart::Port_LeftJoyCon == uart::Port_C); static_assert(uart::Port_LeftJoyCon == uart::Port_C);
pinmux::SetupUartC(); pinmux::SetupUartC();
clkrst::EnableUartCClock(); clkrst::EnableUartCClock();
} else if constexpr (UartLogPort == uart::Port_RightJoyCon) { } else if (port == uart::Port_RightJoyCon) {
/* Logging to right joy-con (e.g. with Joyless). */ /* Logging to right joy-con (e.g. with Joyless). */
static_assert(uart::Port_RightJoyCon == uart::Port_B); static_assert(uart::Port_RightJoyCon == uart::Port_B);
pinmux::SetupUartB(); pinmux::SetupUartB();
clkrst::EnableUartBClock(); clkrst::EnableUartBClock();
} else {
__builtin_unreachable();
} }
} }
} }
void Initialize() { void Initialize() {
return Initialize(DefaultLogPort, DefaultBaudRate, DefaultLogFlags);
}
void Initialize(uart::Port port, u32 baud_rate, u32 flags) {
/* Initialize pinmux and clock for the target uart port. */ /* Initialize pinmux and clock for the target uart port. */
SetupUart(); SetupUartClock(port);
/* Initialize the target uart port. */ /* Initialize the target uart port. */
uart::Initialize(UartLogPort, UartBaudRate, UartPortFlags); uart::Initialize(port, baud_rate, flags);
/* Note that we've initialized. */ /* Note that we've initialized. */
g_log_port = port;
g_initialized_uart = true; g_initialized_uart = true;
} }
@@ -84,7 +72,7 @@ namespace ams::log {
const auto len = util::TVSNPrintf(log_buf, sizeof(log_buf), fmt, vl); const auto len = util::TVSNPrintf(log_buf, sizeof(log_buf), fmt, vl);
if (g_initialized_uart) { if (g_initialized_uart) {
uart::SendText(UartLogPort, log_buf, len); uart::SendText(g_log_port, log_buf, len);
} }
} }
@@ -115,13 +103,13 @@ namespace ams::log {
void SendText(const void *text, size_t size) { void SendText(const void *text, size_t size) {
if (g_initialized_uart) { if (g_initialized_uart) {
uart::SendText(UartLogPort, text, size); uart::SendText(g_log_port, text, size);
} }
} }
void Flush() { void Flush() {
if (g_initialized_uart) { if (g_initialized_uart) {
uart::WaitFlush(UartLogPort); uart::WaitFlush(g_log_port);
} }
} }

View File

@@ -11,7 +11,7 @@ include $(CURRENT_DIRECTORY)/../config/common.mk
PRECOMPILED_HEADERS := include/mesosphere.hpp PRECOMPILED_HEADERS := include/mesosphere.hpp
DEFINES := $(ATMOSPHERE_DEFINES) -DATMOSPHERE_IS_MESOSPHERE DEFINES := $(ATMOSPHERE_DEFINES) -DATMOSPHERE_IS_MESOSPHERE
SETTINGS := $(ATMOSPHERE_SETTINGS) -O2 -mgeneral-regs-only -ffixed-x18 -Wextra -Werror -fno-non-call-exceptions SETTINGS := $(ATMOSPHERE_SETTINGS) -Os -mgeneral-regs-only -ffixed-x18 -Wextra -Werror -fno-non-call-exceptions
CFLAGS := $(ATMOSPHERE_CFLAGS) $(SETTINGS) $(DEFINES) $(INCLUDE) CFLAGS := $(ATMOSPHERE_CFLAGS) $(SETTINGS) $(DEFINES) $(INCLUDE)
CXXFLAGS := $(CFLAGS) $(ATMOSPHERE_CXXFLAGS) -fno-use-cxa-atexit -flto CXXFLAGS := $(CFLAGS) $(ATMOSPHERE_CXXFLAGS) -fno-use-cxa-atexit -flto
ASFLAGS := $(ATMOSPHERE_ASFLAGS) $(SETTINGS) $(DEFINES) $(INCLUDE) ASFLAGS := $(ATMOSPHERE_ASFLAGS) $(SETTINGS) $(DEFINES) $(INCLUDE)

View File

@@ -48,13 +48,13 @@
#include <mesosphere/kern_k_spin_lock.hpp> #include <mesosphere/kern_k_spin_lock.hpp>
#include <mesosphere/kern_k_memory_manager.hpp> #include <mesosphere/kern_k_memory_manager.hpp>
#include <mesosphere/kern_k_interrupt_task_manager.hpp> #include <mesosphere/kern_k_interrupt_task_manager.hpp>
#include <mesosphere/kern_k_core_local_region.hpp>
#include <mesosphere/kern_k_slab_heap.hpp> #include <mesosphere/kern_k_slab_heap.hpp>
#include <mesosphere/kern_k_light_lock.hpp> #include <mesosphere/kern_k_light_lock.hpp>
#include <mesosphere/kern_k_dpc_manager.hpp> #include <mesosphere/kern_k_dpc_manager.hpp>
#include <mesosphere/kern_kernel.hpp> #include <mesosphere/kern_kernel.hpp>
#include <mesosphere/kern_k_page_table_manager.hpp> #include <mesosphere/kern_k_page_table_manager.hpp>
#include <mesosphere/kern_select_page_table.hpp> #include <mesosphere/kern_select_page_table.hpp>
#include <mesosphere/kern_k_dump_object.hpp>
/* Miscellaneous objects. */ /* Miscellaneous objects. */
#include <mesosphere/kern_k_shared_memory_info.hpp> #include <mesosphere/kern_k_shared_memory_info.hpp>
@@ -78,7 +78,8 @@
#include <mesosphere/kern_select_debug.hpp> #include <mesosphere/kern_select_debug.hpp>
#include <mesosphere/kern_k_process.hpp> #include <mesosphere/kern_k_process.hpp>
#include <mesosphere/kern_k_resource_limit.hpp> #include <mesosphere/kern_k_resource_limit.hpp>
#include <mesosphere/kern_k_synchronization.hpp> #include <mesosphere/kern_k_alpha.hpp>
#include <mesosphere/kern_k_beta.hpp>
/* More Miscellaneous objects. */ /* More Miscellaneous objects. */
#include <mesosphere/kern_k_object_name.hpp> #include <mesosphere/kern_k_object_name.hpp>

View File

@@ -29,6 +29,7 @@ namespace ams::kern::init {
u64 entrypoint; u64 entrypoint;
u64 argument; u64 argument;
u64 setup_function; u64 setup_function;
u64 exception_stack;
}; };
} }

View File

@@ -305,7 +305,7 @@ namespace ams::kern::arch::arm64::init {
/* 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) {
*l1_entry = L1PageTableEntry(PageTableEntry::BlockTag{}, phys_addr, attr, false); *l1_entry = L1PageTableEntry(PageTableEntry::BlockTag{}, phys_addr, attr, PageTableEntry::SoftwareReservedBit_None, false);
cpu::DataSynchronizationBarrierInnerShareable(); cpu::DataSynchronizationBarrierInnerShareable();
virt_addr += L1BlockSize; virt_addr += L1BlockSize;
@@ -327,7 +327,7 @@ namespace ams::kern::arch::arm64::init {
/* Can we make a contiguous L2 block? */ /* Can we make a contiguous L2 block? */
if (util::IsAligned(GetInteger(virt_addr), L2ContiguousBlockSize) && util::IsAligned(GetInteger(phys_addr), L2ContiguousBlockSize) && size >= L2ContiguousBlockSize) { if (util::IsAligned(GetInteger(virt_addr), L2ContiguousBlockSize) && util::IsAligned(GetInteger(phys_addr), L2ContiguousBlockSize) && size >= L2ContiguousBlockSize) {
for (size_t i = 0; i < L2ContiguousBlockSize / L2BlockSize; i++) { for (size_t i = 0; i < L2ContiguousBlockSize / L2BlockSize; i++) {
l2_entry[i] = L2PageTableEntry(PageTableEntry::BlockTag{}, phys_addr, attr, true); l2_entry[i] = L2PageTableEntry(PageTableEntry::BlockTag{}, phys_addr, attr, PageTableEntry::SoftwareReservedBit_None, true);
cpu::DataSynchronizationBarrierInnerShareable(); cpu::DataSynchronizationBarrierInnerShareable();
virt_addr += L2BlockSize; virt_addr += L2BlockSize;
@@ -339,7 +339,7 @@ namespace ams::kern::arch::arm64::init {
/* Can we make an L2 block? */ /* Can we make an L2 block? */
if (util::IsAligned(GetInteger(virt_addr), L2BlockSize) && util::IsAligned(GetInteger(phys_addr), L2BlockSize) && size >= L2BlockSize) { if (util::IsAligned(GetInteger(virt_addr), L2BlockSize) && util::IsAligned(GetInteger(phys_addr), L2BlockSize) && size >= L2BlockSize) {
*l2_entry = L2PageTableEntry(PageTableEntry::BlockTag{}, phys_addr, attr, false); *l2_entry = L2PageTableEntry(PageTableEntry::BlockTag{}, phys_addr, attr, PageTableEntry::SoftwareReservedBit_None, false);
cpu::DataSynchronizationBarrierInnerShareable(); cpu::DataSynchronizationBarrierInnerShareable();
virt_addr += L2BlockSize; virt_addr += L2BlockSize;
@@ -361,7 +361,7 @@ namespace ams::kern::arch::arm64::init {
/* Can we make a contiguous L3 block? */ /* Can we make a contiguous L3 block? */
if (util::IsAligned(GetInteger(virt_addr), L3ContiguousBlockSize) && util::IsAligned(GetInteger(phys_addr), L3ContiguousBlockSize) && size >= L3ContiguousBlockSize) { if (util::IsAligned(GetInteger(virt_addr), L3ContiguousBlockSize) && util::IsAligned(GetInteger(phys_addr), L3ContiguousBlockSize) && size >= L3ContiguousBlockSize) {
for (size_t i = 0; i < L3ContiguousBlockSize / L3BlockSize; i++) { for (size_t i = 0; i < L3ContiguousBlockSize / L3BlockSize; i++) {
l3_entry[i] = L3PageTableEntry(PageTableEntry::BlockTag{}, phys_addr, attr, true); l3_entry[i] = L3PageTableEntry(PageTableEntry::BlockTag{}, phys_addr, attr, PageTableEntry::SoftwareReservedBit_None, true);
cpu::DataSynchronizationBarrierInnerShareable(); cpu::DataSynchronizationBarrierInnerShareable();
virt_addr += L3BlockSize; virt_addr += L3BlockSize;
@@ -372,7 +372,7 @@ namespace ams::kern::arch::arm64::init {
} }
/* Make an L3 block. */ /* Make an L3 block. */
*l3_entry = L3PageTableEntry(PageTableEntry::BlockTag{}, phys_addr, attr, false); *l3_entry = L3PageTableEntry(PageTableEntry::BlockTag{}, phys_addr, attr, PageTableEntry::SoftwareReservedBit_None, false);
cpu::DataSynchronizationBarrierInnerShareable(); cpu::DataSynchronizationBarrierInnerShareable();
virt_addr += L3BlockSize; virt_addr += L3BlockSize;
phys_addr += L3BlockSize; phys_addr += L3BlockSize;
@@ -542,7 +542,7 @@ namespace ams::kern::arch::arm64::init {
const KPhysicalAddress block = l1_entry->GetBlock(); const KPhysicalAddress block = l1_entry->GetBlock();
MESOSPHERE_INIT_ABORT_UNLESS(util::IsAligned(GetInteger(virt_addr), L1BlockSize)); MESOSPHERE_INIT_ABORT_UNLESS(util::IsAligned(GetInteger(virt_addr), L1BlockSize));
MESOSPHERE_INIT_ABORT_UNLESS(size >= L1BlockSize); MESOSPHERE_INIT_ABORT_UNLESS(size >= L1BlockSize);
MESOSPHERE_INIT_ABORT_UNLESS(l1_entry->IsCompatibleWithAttribute(attr_before, false)); MESOSPHERE_INIT_ABORT_UNLESS(l1_entry->IsCompatibleWithAttribute(attr_before, PageTableEntry::SoftwareReservedBit_None, false));
/* Invalidate the existing L1 block. */ /* Invalidate the existing L1 block. */
*static_cast<PageTableEntry *>(l1_entry) = InvalidPageTableEntry; *static_cast<PageTableEntry *>(l1_entry) = InvalidPageTableEntry;
@@ -550,7 +550,7 @@ namespace ams::kern::arch::arm64::init {
cpu::InvalidateEntireTlb(); cpu::InvalidateEntireTlb();
/* Create new L1 block. */ /* Create new L1 block. */
*l1_entry = L1PageTableEntry(PageTableEntry::BlockTag{}, block, attr_after, false); *l1_entry = L1PageTableEntry(PageTableEntry::BlockTag{}, block, attr_after, PageTableEntry::SoftwareReservedBit_None, false);
virt_addr += L1BlockSize; virt_addr += L1BlockSize;
size -= L1BlockSize; size -= L1BlockSize;
@@ -573,7 +573,7 @@ namespace ams::kern::arch::arm64::init {
/* Invalidate the existing contiguous L2 block. */ /* Invalidate the existing contiguous L2 block. */
for (size_t i = 0; i < L2ContiguousBlockSize / L2BlockSize; i++) { for (size_t i = 0; i < L2ContiguousBlockSize / L2BlockSize; i++) {
/* Ensure that the entry is valid. */ /* Ensure that the entry is valid. */
MESOSPHERE_INIT_ABORT_UNLESS(l2_entry[i].IsCompatibleWithAttribute(attr_before, true)); MESOSPHERE_INIT_ABORT_UNLESS(l2_entry[i].IsCompatibleWithAttribute(attr_before, PageTableEntry::SoftwareReservedBit_None, true));
static_cast<PageTableEntry *>(l2_entry)[i] = InvalidPageTableEntry; static_cast<PageTableEntry *>(l2_entry)[i] = InvalidPageTableEntry;
} }
cpu::DataSynchronizationBarrierInnerShareable(); cpu::DataSynchronizationBarrierInnerShareable();
@@ -581,7 +581,7 @@ namespace ams::kern::arch::arm64::init {
/* Create a new contiguous L2 block. */ /* Create a new contiguous L2 block. */
for (size_t i = 0; i < L2ContiguousBlockSize / L2BlockSize; i++) { for (size_t i = 0; i < L2ContiguousBlockSize / L2BlockSize; i++) {
l2_entry[i] = L2PageTableEntry(PageTableEntry::BlockTag{}, block + L2BlockSize * i, attr_after, true); l2_entry[i] = L2PageTableEntry(PageTableEntry::BlockTag{}, block + L2BlockSize * i, attr_after, PageTableEntry::SoftwareReservedBit_None, true);
} }
virt_addr += L2ContiguousBlockSize; virt_addr += L2ContiguousBlockSize;
@@ -591,7 +591,7 @@ namespace ams::kern::arch::arm64::init {
MESOSPHERE_INIT_ABORT_UNLESS(util::IsAligned(GetInteger(virt_addr), L2BlockSize)); MESOSPHERE_INIT_ABORT_UNLESS(util::IsAligned(GetInteger(virt_addr), L2BlockSize));
MESOSPHERE_INIT_ABORT_UNLESS(util::IsAligned(GetInteger(block), L2BlockSize)); MESOSPHERE_INIT_ABORT_UNLESS(util::IsAligned(GetInteger(block), L2BlockSize));
MESOSPHERE_INIT_ABORT_UNLESS(size >= L2BlockSize); MESOSPHERE_INIT_ABORT_UNLESS(size >= L2BlockSize);
MESOSPHERE_INIT_ABORT_UNLESS(l2_entry->IsCompatibleWithAttribute(attr_before, false)); MESOSPHERE_INIT_ABORT_UNLESS(l2_entry->IsCompatibleWithAttribute(attr_before, PageTableEntry::SoftwareReservedBit_None, false));
/* Invalidate the existing L2 block. */ /* Invalidate the existing L2 block. */
*static_cast<PageTableEntry *>(l2_entry) = InvalidPageTableEntry; *static_cast<PageTableEntry *>(l2_entry) = InvalidPageTableEntry;
@@ -599,7 +599,7 @@ namespace ams::kern::arch::arm64::init {
cpu::InvalidateEntireTlb(); cpu::InvalidateEntireTlb();
/* Create new L2 block. */ /* Create new L2 block. */
*l2_entry = L2PageTableEntry(PageTableEntry::BlockTag{}, block, attr_after, false); *l2_entry = L2PageTableEntry(PageTableEntry::BlockTag{}, block, attr_after, PageTableEntry::SoftwareReservedBit_None, false);
virt_addr += L2BlockSize; virt_addr += L2BlockSize;
size -= L2BlockSize; size -= L2BlockSize;
@@ -625,7 +625,7 @@ namespace ams::kern::arch::arm64::init {
/* Invalidate the existing contiguous L3 block. */ /* Invalidate the existing contiguous L3 block. */
for (size_t i = 0; i < L3ContiguousBlockSize / L3BlockSize; i++) { for (size_t i = 0; i < L3ContiguousBlockSize / L3BlockSize; i++) {
/* Ensure that the entry is valid. */ /* Ensure that the entry is valid. */
MESOSPHERE_INIT_ABORT_UNLESS(l3_entry[i].IsCompatibleWithAttribute(attr_before, true)); MESOSPHERE_INIT_ABORT_UNLESS(l3_entry[i].IsCompatibleWithAttribute(attr_before, PageTableEntry::SoftwareReservedBit_None, true));
static_cast<PageTableEntry *>(l3_entry)[i] = InvalidPageTableEntry; static_cast<PageTableEntry *>(l3_entry)[i] = InvalidPageTableEntry;
} }
cpu::DataSynchronizationBarrierInnerShareable(); cpu::DataSynchronizationBarrierInnerShareable();
@@ -633,7 +633,7 @@ namespace ams::kern::arch::arm64::init {
/* Create a new contiguous L3 block. */ /* Create a new contiguous L3 block. */
for (size_t i = 0; i < L3ContiguousBlockSize / L3BlockSize; i++) { for (size_t i = 0; i < L3ContiguousBlockSize / L3BlockSize; i++) {
l3_entry[i] = L3PageTableEntry(PageTableEntry::BlockTag{}, block + L3BlockSize * i, attr_after, true); l3_entry[i] = L3PageTableEntry(PageTableEntry::BlockTag{}, block + L3BlockSize * i, attr_after, PageTableEntry::SoftwareReservedBit_None, true);
} }
virt_addr += L3ContiguousBlockSize; virt_addr += L3ContiguousBlockSize;
@@ -643,7 +643,7 @@ namespace ams::kern::arch::arm64::init {
MESOSPHERE_INIT_ABORT_UNLESS(util::IsAligned(GetInteger(virt_addr), L3BlockSize)); MESOSPHERE_INIT_ABORT_UNLESS(util::IsAligned(GetInteger(virt_addr), L3BlockSize));
MESOSPHERE_INIT_ABORT_UNLESS(util::IsAligned(GetInteger(block), L3BlockSize)); MESOSPHERE_INIT_ABORT_UNLESS(util::IsAligned(GetInteger(block), L3BlockSize));
MESOSPHERE_INIT_ABORT_UNLESS(size >= L3BlockSize); MESOSPHERE_INIT_ABORT_UNLESS(size >= L3BlockSize);
MESOSPHERE_INIT_ABORT_UNLESS(l3_entry->IsCompatibleWithAttribute(attr_before, false)); MESOSPHERE_INIT_ABORT_UNLESS(l3_entry->IsCompatibleWithAttribute(attr_before, PageTableEntry::SoftwareReservedBit_None, false));
/* Invalidate the existing L3 block. */ /* Invalidate the existing L3 block. */
*static_cast<PageTableEntry *>(l3_entry) = InvalidPageTableEntry; *static_cast<PageTableEntry *>(l3_entry) = InvalidPageTableEntry;
@@ -651,7 +651,7 @@ namespace ams::kern::arch::arm64::init {
cpu::InvalidateEntireTlb(); cpu::InvalidateEntireTlb();
/* Create new L3 block. */ /* Create new L3 block. */
*l3_entry = L3PageTableEntry(PageTableEntry::BlockTag{}, block, attr_after, false); *l3_entry = L3PageTableEntry(PageTableEntry::BlockTag{}, block, attr_after, PageTableEntry::SoftwareReservedBit_None, false);
virt_addr += L3BlockSize; virt_addr += L3BlockSize;
size -= L3BlockSize; size -= L3BlockSize;
@@ -668,6 +668,7 @@ namespace ams::kern::arch::arm64::init {
this->PhysicallyRandomize(virt_addr, size, L2BlockSize, do_copy); this->PhysicallyRandomize(virt_addr, size, L2BlockSize, do_copy);
this->PhysicallyRandomize(virt_addr, size, L3ContiguousBlockSize, do_copy); this->PhysicallyRandomize(virt_addr, size, L3ContiguousBlockSize, do_copy);
this->PhysicallyRandomize(virt_addr, size, L3BlockSize, do_copy); this->PhysicallyRandomize(virt_addr, size, L3BlockSize, do_copy);
cpu::StoreEntireCacheForInit();
} }
}; };

View File

@@ -220,16 +220,19 @@ namespace ams::kern::arch::arm64::cpu {
DataSynchronizationBarrier(); DataSynchronizationBarrier();
} }
ALWAYS_INLINE uintptr_t GetCoreLocalRegionAddress() { ALWAYS_INLINE uintptr_t GetCurrentThreadPointerValue() {
register uintptr_t x18 asm("x18"); register uintptr_t x18 asm("x18");
__asm__ __volatile__("" : [x18]"=r"(x18)); __asm__ __volatile__("" : [x18]"=r"(x18));
return x18; return x18;
} }
ALWAYS_INLINE void SetCoreLocalRegionAddress(uintptr_t value) { ALWAYS_INLINE void SetCurrentThreadPointerValue(uintptr_t value) {
register uintptr_t x18 asm("x18") = value; register uintptr_t x18 asm("x18") = value;
__asm__ __volatile__("":: [x18]"r"(x18)); __asm__ __volatile__("":: [x18]"r"(x18));
SetTpidrEl1(value); }
ALWAYS_INLINE void SetExceptionThreadStackTop(uintptr_t top) {
SetTpidrEl1(top);
} }
ALWAYS_INLINE void SwitchThreadLocalRegion(uintptr_t tlr) { ALWAYS_INLINE void SwitchThreadLocalRegion(uintptr_t tlr) {

View File

@@ -44,6 +44,9 @@ namespace ams::kern::arch::arm64 {
static uintptr_t GetProgramCounter(const KThread &thread); static uintptr_t GetProgramCounter(const KThread &thread);
static void SetPreviousProgramCounter(); static void SetPreviousProgramCounter();
static void PrintRegister(KThread *thread = nullptr);
static void PrintBacktrace(KThread *thread = nullptr);
static Result BreakIfAttached(ams::svc::BreakReason break_reason, uintptr_t address, size_t size); static Result BreakIfAttached(ams::svc::BreakReason break_reason, uintptr_t address, size_t size);
static Result SetHardwareBreakPoint(ams::svc::HardwareBreakPointRegisterName name, u64 flags, u64 value); static Result SetHardwareBreakPoint(ams::svc::HardwareBreakPointRegisterName name, u64 flags, u64 value);
@@ -61,8 +64,6 @@ namespace ams::kern::arch::arm64 {
} }
} }
} }
/* TODO: This is a placeholder definition. */
}; };
} }

View File

@@ -19,18 +19,14 @@
namespace ams::kern::arch::arm64 { namespace ams::kern::arch::arm64 {
namespace impl { class KHardwareTimer : public KInterruptTask, public KHardwareTimerBase {
private:
class KHardwareTimerInterruptTask; s64 maximum_time;
}
class KHardwareTimer : public KHardwareTimerBase {
public: public:
constexpr KHardwareTimer() : KHardwareTimerBase() { /* ... */ } constexpr KHardwareTimer() : KInterruptTask(), KHardwareTimerBase(), maximum_time(std::numeric_limits<s64>::max()) { /* ... */ }
public: public:
/* Public API. */ /* Public API. */
NOINLINE void Initialize(s32 core_id); NOINLINE void Initialize();
NOINLINE void Finalize(); NOINLINE void Finalize();
static s64 GetTick() { static s64 GetTick() {
@@ -42,13 +38,12 @@ namespace ams::kern::arch::arm64 {
KScopedSpinLock lk(this->GetLock()); KScopedSpinLock lk(this->GetLock());
if (this->RegisterAbsoluteTaskImpl(task, task_time)) { if (this->RegisterAbsoluteTaskImpl(task, task_time)) {
SetCompareValue(task_time); if (task_time <= this->maximum_time) {
EnableInterrupt(); SetCompareValue(task_time);
EnableInterrupt();
}
} }
} }
private:
friend class impl::KHardwareTimerInterruptTask;
NOINLINE void DoInterruptTask();
private: private:
/* Hardware register accessors. */ /* Hardware register accessors. */
static ALWAYS_INLINE void InitializeGlobalTimer() { static ALWAYS_INLINE void InitializeGlobalTimer() {
@@ -88,7 +83,13 @@ namespace ams::kern::arch::arm64 {
static ALWAYS_INLINE void SetCompareValue(s64 value) { static ALWAYS_INLINE void SetCompareValue(s64 value) {
cpu::CounterTimerPhysicalTimerCompareValueRegisterAccessor(0).SetCompareValue(static_cast<u64>(value)).Store(); cpu::CounterTimerPhysicalTimerCompareValueRegisterAccessor(0).SetCompareValue(static_cast<u64>(value)).Store();
} }
public:
virtual KInterruptTask *OnInterrupt(s32 interrupt_id) override {
MESOSPHERE_UNUSED(interrupt_id);
return this;
}
virtual void DoTask() override;
}; };
} }

View File

@@ -47,23 +47,23 @@ namespace ams::kern::arch::arm64 {
constexpr KGlobalInterruptEntry() : handler(nullptr), manually_cleared(false), needs_clear(false) { /* ... */ } constexpr KGlobalInterruptEntry() : handler(nullptr), manually_cleared(false), needs_clear(false) { /* ... */ }
}; };
private: private:
static KSpinLock s_lock; KCoreLocalInterruptEntry core_local_interrupts[cpu::NumCores][KInterruptController::NumLocalInterrupts]{};
static std::array<KGlobalInterruptEntry, KInterruptController::NumGlobalInterrupts> s_global_interrupts; KInterruptController interrupt_controller{};
static KInterruptController::GlobalState s_global_state; KInterruptController::LocalState local_states[cpu::NumCores]{};
static bool s_global_state_saved; bool local_state_saved[cpu::NumCores]{};
mutable KSpinLock global_interrupt_lock{};
KGlobalInterruptEntry global_interrupts[KInterruptController::NumGlobalInterrupts]{};
KInterruptController::GlobalState global_state{};
bool global_state_saved{};
private: private:
KCoreLocalInterruptEntry core_local_interrupts[KInterruptController::NumLocalInterrupts]; ALWAYS_INLINE KSpinLock &GetGlobalInterruptLock() const { return this->global_interrupt_lock; }
KInterruptController interrupt_controller; ALWAYS_INLINE KGlobalInterruptEntry &GetGlobalInterruptEntry(s32 irq) { return this->global_interrupts[KInterruptController::GetGlobalInterruptIndex(irq)]; }
KInterruptController::LocalState local_state; ALWAYS_INLINE KCoreLocalInterruptEntry &GetLocalInterruptEntry(s32 irq) { return this->core_local_interrupts[GetCurrentCoreId()][KInterruptController::GetLocalInterruptIndex(irq)]; }
bool local_state_saved;
private:
static ALWAYS_INLINE KSpinLock &GetLock() { return s_lock; }
static ALWAYS_INLINE KGlobalInterruptEntry &GetGlobalInterruptEntry(s32 irq) { return s_global_interrupts[KInterruptController::GetGlobalInterruptIndex(irq)]; }
ALWAYS_INLINE KCoreLocalInterruptEntry &GetLocalInterruptEntry(s32 irq) { return this->core_local_interrupts[KInterruptController::GetLocalInterruptIndex(irq)]; }
bool OnHandleInterrupt(); bool OnHandleInterrupt();
public: public:
constexpr KInterruptManager() : core_local_interrupts(), interrupt_controller(), local_state(), local_state_saved(false) { /* ... */ } constexpr KInterruptManager() = default;
NOINLINE void Initialize(s32 core_id); NOINLINE void Initialize(s32 core_id);
NOINLINE void Finalize(s32 core_id); NOINLINE void Finalize(s32 core_id);

View File

@@ -134,9 +134,6 @@ namespace ams::kern::arch::arm64 {
entry.SetUserExecuteNever(true); entry.SetUserExecuteNever(true);
} }
/* Set can be contiguous. */
entry.SetContiguousAllowed(!properties.non_contiguous);
/* Set AP[1] based on perm. */ /* Set AP[1] based on perm. */
switch (properties.perm & KMemoryPermission_UserReadWrite) { switch (properties.perm & KMemoryPermission_UserReadWrite) {
case KMemoryPermission_UserReadWrite: case KMemoryPermission_UserReadWrite:
@@ -179,19 +176,19 @@ 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 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);
Result Finalize(); Result Finalize();
private: private:
Result MapL1Blocks(KProcessAddress virt_addr, KPhysicalAddress phys_addr, size_t num_pages, PageTableEntry entry_template, 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);
Result MapL2Blocks(KProcessAddress virt_addr, KPhysicalAddress phys_addr, size_t num_pages, PageTableEntry entry_template, PageLinkedList *page_list, bool reuse_ll); Result MapL2Blocks(KProcessAddress virt_addr, KPhysicalAddress phys_addr, size_t num_pages, PageTableEntry entry_template, bool disable_head_merge, PageLinkedList *page_list, bool reuse_ll);
Result MapL3Blocks(KProcessAddress virt_addr, KPhysicalAddress phys_addr, size_t num_pages, PageTableEntry entry_template, PageLinkedList *page_list, bool reuse_ll); Result MapL3Blocks(KProcessAddress virt_addr, KPhysicalAddress phys_addr, size_t num_pages, PageTableEntry entry_template, bool disable_head_merge, PageLinkedList *page_list, bool reuse_ll);
Result Unmap(KProcessAddress virt_addr, size_t num_pages, PageLinkedList *page_list, bool force, bool reuse_ll); Result Unmap(KProcessAddress virt_addr, size_t num_pages, PageLinkedList *page_list, bool force, bool reuse_ll);
Result Map(KProcessAddress virt_addr, KPhysicalAddress phys_addr, size_t num_pages, PageTableEntry entry_template, size_t page_size, PageLinkedList *page_list, bool reuse_ll) { Result Map(KProcessAddress virt_addr, KPhysicalAddress phys_addr, size_t num_pages, PageTableEntry entry_template, bool disable_head_merge, size_t page_size, PageLinkedList *page_list, bool reuse_ll) {
switch (page_size) { switch (page_size) {
case L1BlockSize: case L1BlockSize:
return this->MapL1Blocks(virt_addr, phys_addr, num_pages, entry_template, page_list, reuse_ll); return this->MapL1Blocks(virt_addr, phys_addr, num_pages, entry_template, disable_head_merge, page_list, reuse_ll);
case L2ContiguousBlockSize: case L2ContiguousBlockSize:
entry_template.SetContiguous(true); entry_template.SetContiguous(true);
[[fallthrough]]; [[fallthrough]];
@@ -199,25 +196,25 @@ namespace ams::kern::arch::arm64 {
case L2TegraSmmuBlockSize: case L2TegraSmmuBlockSize:
#endif #endif
case L2BlockSize: case L2BlockSize:
return this->MapL2Blocks(virt_addr, phys_addr, num_pages, entry_template, page_list, reuse_ll); return this->MapL2Blocks(virt_addr, phys_addr, num_pages, entry_template, disable_head_merge, page_list, reuse_ll);
case L3ContiguousBlockSize: case L3ContiguousBlockSize:
entry_template.SetContiguous(true); entry_template.SetContiguous(true);
[[fallthrough]]; [[fallthrough]];
case L3BlockSize: case L3BlockSize:
return this->MapL3Blocks(virt_addr, phys_addr, num_pages, entry_template, page_list, reuse_ll); return this->MapL3Blocks(virt_addr, phys_addr, num_pages, entry_template, disable_head_merge, page_list, reuse_ll);
MESOSPHERE_UNREACHABLE_DEFAULT_CASE(); MESOSPHERE_UNREACHABLE_DEFAULT_CASE();
} }
} }
Result MapContiguous(KProcessAddress virt_addr, KPhysicalAddress phys_addr, size_t num_pages, PageTableEntry entry_template, PageLinkedList *page_list, bool reuse_ll); Result MapContiguous(KProcessAddress virt_addr, KPhysicalAddress phys_addr, size_t num_pages, PageTableEntry entry_template, bool disable_head_merge, PageLinkedList *page_list, bool reuse_ll);
Result MapGroup(KProcessAddress virt_addr, const KPageGroup &pg, size_t num_pages, PageTableEntry entry_template, PageLinkedList *page_list, bool reuse_ll); Result MapGroup(KProcessAddress virt_addr, const KPageGroup &pg, size_t num_pages, PageTableEntry entry_template, bool disable_head_merge, PageLinkedList *page_list, bool reuse_ll);
bool MergePages(KProcessAddress virt_addr, PageLinkedList *page_list); bool MergePages(KProcessAddress virt_addr, PageLinkedList *page_list);
ALWAYS_INLINE Result SeparatePagesImpl(KProcessAddress virt_addr, size_t block_size, PageLinkedList *page_list, bool reuse_ll); ALWAYS_INLINE Result SeparatePagesImpl(KProcessAddress virt_addr, size_t block_size, PageLinkedList *page_list, bool reuse_ll);
Result SeparatePages(KProcessAddress virt_addr, size_t block_size, PageLinkedList *page_list, bool reuse_ll); Result SeparatePages(KProcessAddress virt_addr, size_t block_size, PageLinkedList *page_list, bool reuse_ll);
Result ChangePermissions(KProcessAddress virt_addr, size_t num_pages, PageTableEntry entry_template, bool refresh_mapping, PageLinkedList *page_list, bool reuse_ll); Result ChangePermissions(KProcessAddress virt_addr, size_t num_pages, PageTableEntry entry_template, DisableMergeAttribute disable_merge_attr, bool refresh_mapping, PageLinkedList *page_list, bool reuse_ll);
static void PteDataSynchronizationBarrier() { static void PteDataSynchronizationBarrier() {
cpu::DataSynchronizationBarrierInnerShareable(); cpu::DataSynchronizationBarrierInnerShareable();

View File

@@ -69,9 +69,23 @@ namespace ams::kern::arch::arm64 {
MappingFlag_Mapped = (1 << 0), MappingFlag_Mapped = (1 << 0),
}; };
enum SoftwareReservedBit : u8 {
SoftwareReservedBit_None = 0,
SoftwareReservedBit_DisableMergeHead = (1u << 0),
SoftwareReservedBit_DisableMergeHeadAndBody = (1u << 1),
SoftwareReservedBit_DisableMergeHeadTail = (1u << 2),
SoftwareReservedBit_Valid = (1u << 3),
};
static constexpr ALWAYS_INLINE std::underlying_type<SoftwareReservedBit>::type EncodeSoftwareReservedBits(bool head, bool head_body, bool tail) {
return (head ? SoftwareReservedBit_DisableMergeHead : SoftwareReservedBit_None) | (head_body ? SoftwareReservedBit_DisableMergeHeadAndBody : SoftwareReservedBit_None) | (tail ? SoftwareReservedBit_DisableMergeHeadTail : SoftwareReservedBit_None);
}
enum ExtensionFlag : u64 { enum ExtensionFlag : u64 {
ExtensionFlag_NotContiguous = (1ul << 55), ExtensionFlag_DisableMergeHead = (static_cast<u64>(SoftwareReservedBit_DisableMergeHead) << 55),
ExtensionFlag_Valid = (1ul << 56), ExtensionFlag_DisableMergeHeadAndBody = (static_cast<u64>(SoftwareReservedBit_DisableMergeHeadAndBody) << 55),
ExtensionFlag_DisableMergeTail = (static_cast<u64>(SoftwareReservedBit_DisableMergeHeadTail) << 55),
ExtensionFlag_Valid = (static_cast<u64>(SoftwareReservedBit_Valid) << 55),
ExtensionFlag_ValidAndMapped = (ExtensionFlag_Valid | MappingFlag_Mapped), ExtensionFlag_ValidAndMapped = (ExtensionFlag_Valid | MappingFlag_Mapped),
ExtensionFlag_TestTableMask = (ExtensionFlag_Valid | (1ul << 1)), ExtensionFlag_TestTableMask = (ExtensionFlag_Valid | (1ul << 1)),
@@ -138,23 +152,26 @@ namespace ams::kern::arch::arm64 {
} }
} }
public: public:
constexpr ALWAYS_INLINE bool IsContiguousAllowed() const { return this->GetBits(55, 1) == 0; } constexpr ALWAYS_INLINE u8 GetSoftwareReservedBits() const { return this->GetBits(55, 3); }
constexpr ALWAYS_INLINE bool IsUserExecuteNever() const { return this->GetBits(54, 1) != 0; } constexpr ALWAYS_INLINE bool IsHeadMergeDisabled() const { return (this->GetSoftwareReservedBits() & SoftwareReservedBit_DisableMergeHead) != 0; }
constexpr ALWAYS_INLINE bool IsPrivilegedExecuteNever() const { return this->GetBits(53, 1) != 0; } constexpr ALWAYS_INLINE bool IsHeadAndBodyMergeDisabled() const { return (this->GetSoftwareReservedBits() & SoftwareReservedBit_DisableMergeHeadAndBody) != 0; }
constexpr ALWAYS_INLINE bool IsContiguous() const { return this->GetBits(52, 1) != 0; } constexpr ALWAYS_INLINE bool IsTailMergeDisabled() const { return (this->GetSoftwareReservedBits() & SoftwareReservedBit_DisableMergeHeadTail) != 0; }
constexpr ALWAYS_INLINE bool IsGlobal() const { return this->GetBits(11, 1) == 0; } constexpr ALWAYS_INLINE bool IsHeadOrHeadAndBodyMergeDisabled() const { return (this->GetSoftwareReservedBits() & (SoftwareReservedBit_DisableMergeHead | SoftwareReservedBit_DisableMergeHeadAndBody)) != 0; }
constexpr ALWAYS_INLINE AccessFlag GetAccessFlag() const { return static_cast<AccessFlag>(this->GetBits(10, 1)); } constexpr ALWAYS_INLINE bool IsUserExecuteNever() const { return this->GetBits(54, 1) != 0; }
constexpr ALWAYS_INLINE Shareable GetShareable() const { return static_cast<Shareable>(this->GetBits(8, 2)); } constexpr ALWAYS_INLINE bool IsPrivilegedExecuteNever() const { return this->GetBits(53, 1) != 0; }
constexpr ALWAYS_INLINE PageAttribute GetPageAttribute() const { return static_cast<PageAttribute>(this->GetBits(2, 3)); } constexpr ALWAYS_INLINE bool IsContiguous() const { return this->GetBits(52, 1) != 0; }
constexpr ALWAYS_INLINE bool IsReadOnly() const { return this->GetBits(7, 1) != 0; } constexpr ALWAYS_INLINE bool IsGlobal() const { return this->GetBits(11, 1) == 0; }
constexpr ALWAYS_INLINE bool IsUserAccessible() const { return this->GetBits(6, 1) != 0; } constexpr ALWAYS_INLINE AccessFlag GetAccessFlag() const { return static_cast<AccessFlag>(this->GetBits(10, 1)); }
constexpr ALWAYS_INLINE bool IsNonSecure() const { return this->GetBits(5, 1) != 0; } constexpr ALWAYS_INLINE Shareable GetShareable() const { return static_cast<Shareable>(this->GetBits(8, 2)); }
constexpr ALWAYS_INLINE bool IsBlock() const { return (this->attributes & ExtensionFlag_TestTableMask) == ExtensionFlag_Valid; } constexpr ALWAYS_INLINE PageAttribute GetPageAttribute() const { return static_cast<PageAttribute>(this->GetBits(2, 3)); }
constexpr ALWAYS_INLINE bool IsTable() const { return (this->attributes & ExtensionFlag_TestTableMask) == 2; } constexpr ALWAYS_INLINE bool IsReadOnly() const { return this->GetBits(7, 1) != 0; }
constexpr ALWAYS_INLINE bool IsEmpty() const { return (this->attributes & ExtensionFlag_TestTableMask) == 0; } constexpr ALWAYS_INLINE bool IsUserAccessible() const { return this->GetBits(6, 1) != 0; }
constexpr ALWAYS_INLINE bool IsMapped() const { return this->GetBits(0, 1) != 0; } constexpr ALWAYS_INLINE bool IsNonSecure() const { return this->GetBits(5, 1) != 0; }
constexpr ALWAYS_INLINE bool IsBlock() const { return (this->attributes & ExtensionFlag_TestTableMask) == ExtensionFlag_Valid; }
constexpr ALWAYS_INLINE bool IsTable() const { return (this->attributes & ExtensionFlag_TestTableMask) == 2; }
constexpr ALWAYS_INLINE bool IsEmpty() const { return (this->attributes & ExtensionFlag_TestTableMask) == 0; }
constexpr ALWAYS_INLINE bool IsMapped() const { return this->GetBits(0, 1) != 0; }
constexpr ALWAYS_INLINE decltype(auto) SetContiguousAllowed(bool en) { this->SetBit(55, !en); return *this; }
constexpr ALWAYS_INLINE decltype(auto) SetUserExecuteNever(bool en) { this->SetBit(54, en); return *this; } constexpr ALWAYS_INLINE decltype(auto) SetUserExecuteNever(bool en) { this->SetBit(54, en); return *this; }
constexpr ALWAYS_INLINE decltype(auto) SetPrivilegedExecuteNever(bool en) { this->SetBit(53, en); return *this; } constexpr ALWAYS_INLINE decltype(auto) SetPrivilegedExecuteNever(bool en) { this->SetBit(53, en); return *this; }
constexpr ALWAYS_INLINE decltype(auto) SetContiguous(bool en) { this->SetBit(52, en); return *this; } constexpr ALWAYS_INLINE decltype(auto) SetContiguous(bool en) { this->SetBit(52, en); return *this; }
@@ -166,13 +183,14 @@ namespace ams::kern::arch::arm64 {
constexpr ALWAYS_INLINE decltype(auto) SetPageAttribute(PageAttribute a) { this->SetBitsDirect(2, 3, a); return *this; } constexpr ALWAYS_INLINE decltype(auto) SetPageAttribute(PageAttribute a) { this->SetBitsDirect(2, 3, a); return *this; }
constexpr ALWAYS_INLINE decltype(auto) SetMapped(bool m) { static_assert(static_cast<u64>(MappingFlag_Mapped == (1 << 0))); this->SetBit(0, m); return *this; } constexpr ALWAYS_INLINE decltype(auto) SetMapped(bool m) { static_assert(static_cast<u64>(MappingFlag_Mapped == (1 << 0))); this->SetBit(0, m); return *this; }
constexpr ALWAYS_INLINE u64 GetEntryTemplate() const { constexpr ALWAYS_INLINE u64 GetEntryTemplateForMerge() const {
constexpr u64 Mask = (0xFFF0000000000FFFul & ~u64((0x1ul << 52) | ExtensionFlag_TestTableMask)); constexpr u64 BaseMask = (0xFFF0000000000FFFul & ~static_cast<u64>((0x1ul << 52) | ExtensionFlag_TestTableMask | ExtensionFlag_DisableMergeHead | ExtensionFlag_DisableMergeHeadAndBody | ExtensionFlag_DisableMergeTail));
return this->attributes & Mask; return this->attributes & BaseMask;
} }
constexpr ALWAYS_INLINE bool Is(u64 attr) const { constexpr ALWAYS_INLINE bool IsForMerge(u64 attr) const {
return this->attributes == attr; constexpr u64 BaseMaskForMerge = ~static_cast<u64>(ExtensionFlag_DisableMergeHead | ExtensionFlag_DisableMergeHeadAndBody | ExtensionFlag_DisableMergeTail);
return (this->attributes & BaseMaskForMerge) == attr;
} }
constexpr ALWAYS_INLINE u64 GetRawAttributesUnsafeForSwap() const { constexpr ALWAYS_INLINE u64 GetRawAttributesUnsafeForSwap() const {
@@ -207,8 +225,8 @@ namespace ams::kern::arch::arm64 {
/* ... */ /* ... */
} }
constexpr explicit ALWAYS_INLINE L1PageTableEntry(BlockTag, KPhysicalAddress phys_addr, const PageTableEntry &attr, bool contig) constexpr explicit ALWAYS_INLINE L1PageTableEntry(BlockTag, KPhysicalAddress phys_addr, const PageTableEntry &attr, u8 sw_reserved_bits, bool contig)
: PageTableEntry(attr, (static_cast<u64>(contig) << 52) | GetInteger(phys_addr) | PageTableEntry::ExtensionFlag_Valid) : PageTableEntry(attr, (static_cast<u64>(sw_reserved_bits) << 55) | (static_cast<u64>(contig) << 52) | GetInteger(phys_addr) | PageTableEntry::ExtensionFlag_Valid)
{ {
/* ... */ /* ... */
} }
@@ -230,9 +248,26 @@ namespace ams::kern::arch::arm64 {
} }
} }
constexpr ALWAYS_INLINE bool IsCompatibleWithAttribute(const PageTableEntry &rhs, bool contig) const { static constexpr ALWAYS_INLINE u64 GetEntryTemplateForL2BlockMask(size_t idx) {
constexpr u64 BaseMask = (0xFFF0000000000FFFul & ~static_cast<u64>((0x1ul << 52) | ExtensionFlag_TestTableMask | ExtensionFlag_DisableMergeHead | ExtensionFlag_DisableMergeHeadAndBody | ExtensionFlag_DisableMergeTail));
if (idx == 0) {
return BaseMask | ExtensionFlag_DisableMergeHead | ExtensionFlag_DisableMergeHeadAndBody;
} else if (idx < L2ContiguousBlockSize / L2BlockSize) {
return BaseMask | ExtensionFlag_DisableMergeHeadAndBody;
} else if (idx < (L1BlockSize - L2ContiguousBlockSize) / L2BlockSize) {
return BaseMask;
} else {
return BaseMask | ExtensionFlag_DisableMergeTail;
}
}
constexpr ALWAYS_INLINE u64 GetEntryTemplateForL2Block(size_t idx) const {
return this->attributes & GetEntryTemplateForL2BlockMask(idx);
}
constexpr ALWAYS_INLINE bool IsCompatibleWithAttribute(const PageTableEntry &rhs, u8 sw_reserved_bits, bool contig) const {
/* Check whether this has the same permission/etc as the desired attributes. */ /* Check whether this has the same permission/etc as the desired attributes. */
return L1PageTableEntry(BlockTag{}, this->GetBlock(), rhs, contig).GetRawAttributes() == this->GetRawAttributes(); return L1PageTableEntry(BlockTag{}, this->GetBlock(), rhs, sw_reserved_bits, contig).GetRawAttributes() == this->GetRawAttributes();
} }
}; };
@@ -252,8 +287,8 @@ namespace ams::kern::arch::arm64 {
/* ... */ /* ... */
} }
constexpr explicit ALWAYS_INLINE L2PageTableEntry(BlockTag, KPhysicalAddress phys_addr, const PageTableEntry &attr, bool contig) constexpr explicit ALWAYS_INLINE L2PageTableEntry(BlockTag, KPhysicalAddress phys_addr, const PageTableEntry &attr, u8 sw_reserved_bits, bool contig)
: PageTableEntry(attr, (static_cast<u64>(contig) << 52) | GetInteger(phys_addr) | PageTableEntry::ExtensionFlag_Valid) : PageTableEntry(attr, (static_cast<u64>(sw_reserved_bits) << 55) | (static_cast<u64>(contig) << 52) | GetInteger(phys_addr) | PageTableEntry::ExtensionFlag_Valid)
{ {
/* ... */ /* ... */
} }
@@ -275,9 +310,41 @@ namespace ams::kern::arch::arm64 {
} }
} }
constexpr ALWAYS_INLINE bool IsCompatibleWithAttribute(const PageTableEntry &rhs, bool contig) const { static constexpr ALWAYS_INLINE u64 GetEntryTemplateForL2BlockMask(size_t idx) {
constexpr u64 BaseMask = (0xFFF0000000000FFFul & ~static_cast<u64>((0x1ul << 52) | ExtensionFlag_TestTableMask | ExtensionFlag_DisableMergeHead | ExtensionFlag_DisableMergeHeadAndBody | ExtensionFlag_DisableMergeTail));
if (idx == 0) {
return BaseMask | ExtensionFlag_DisableMergeHead | ExtensionFlag_DisableMergeHeadAndBody;
} else if (idx < (L2ContiguousBlockSize / L2BlockSize) - 1) {
return BaseMask;
} else {
return BaseMask | ExtensionFlag_DisableMergeTail;
}
}
constexpr ALWAYS_INLINE u64 GetEntryTemplateForL2Block(size_t idx) const {
return this->attributes & GetEntryTemplateForL2BlockMask(idx);
}
static constexpr ALWAYS_INLINE u64 GetEntryTemplateForL3BlockMask(size_t idx) {
constexpr u64 BaseMask = (0xFFF0000000000FFFul & ~static_cast<u64>((0x1ul << 52) | ExtensionFlag_TestTableMask | ExtensionFlag_DisableMergeHead | ExtensionFlag_DisableMergeHeadAndBody | ExtensionFlag_DisableMergeTail));
if (idx == 0) {
return BaseMask | ExtensionFlag_DisableMergeHead | ExtensionFlag_DisableMergeHeadAndBody;
} else if (idx < L3ContiguousBlockSize / L3BlockSize) {
return BaseMask | ExtensionFlag_DisableMergeHeadAndBody;
} else if (idx < (L2BlockSize - L3ContiguousBlockSize) / L3BlockSize) {
return BaseMask;
} else {
return BaseMask | ExtensionFlag_DisableMergeTail;
}
}
constexpr ALWAYS_INLINE u64 GetEntryTemplateForL3Block(size_t idx) const {
return this->attributes & GetEntryTemplateForL3BlockMask(idx);
}
constexpr ALWAYS_INLINE bool IsCompatibleWithAttribute(const PageTableEntry &rhs, u8 sw_reserved_bits, bool contig) const {
/* Check whether this has the same permission/etc as the desired attributes. */ /* Check whether this has the same permission/etc as the desired attributes. */
return L2PageTableEntry(BlockTag{}, this->GetBlock(), rhs, contig).GetRawAttributes() == this->GetRawAttributes(); return L2PageTableEntry(BlockTag{}, this->GetBlock(), rhs, sw_reserved_bits, contig).GetRawAttributes() == this->GetRawAttributes();
} }
}; };
@@ -285,8 +352,8 @@ namespace ams::kern::arch::arm64 {
public: public:
constexpr explicit ALWAYS_INLINE L3PageTableEntry(InvalidTag) : PageTableEntry(InvalidTag{}) { /* ... */ } constexpr explicit ALWAYS_INLINE L3PageTableEntry(InvalidTag) : PageTableEntry(InvalidTag{}) { /* ... */ }
constexpr explicit ALWAYS_INLINE L3PageTableEntry(BlockTag, KPhysicalAddress phys_addr, const PageTableEntry &attr, bool contig) constexpr explicit ALWAYS_INLINE L3PageTableEntry(BlockTag, KPhysicalAddress phys_addr, const PageTableEntry &attr, u8 sw_reserved_bits, bool contig)
: PageTableEntry(attr, (static_cast<u64>(contig) << 52) | GetInteger(phys_addr) | static_cast<u64>(ExtensionFlag_TestTableMask)) : PageTableEntry(attr, (static_cast<u64>(sw_reserved_bits) << 55) | (static_cast<u64>(contig) << 52) | GetInteger(phys_addr) | static_cast<u64>(ExtensionFlag_TestTableMask))
{ {
/* ... */ /* ... */
} }
@@ -297,9 +364,24 @@ namespace ams::kern::arch::arm64 {
return this->SelectBits(12, 36); return this->SelectBits(12, 36);
} }
constexpr ALWAYS_INLINE bool IsCompatibleWithAttribute(const PageTableEntry &rhs, bool contig) const { static constexpr ALWAYS_INLINE u64 GetEntryTemplateForL3BlockMask(size_t idx) {
constexpr u64 BaseMask = (0xFFF0000000000FFFul & ~static_cast<u64>((0x1ul << 52) | ExtensionFlag_TestTableMask | ExtensionFlag_DisableMergeHead | ExtensionFlag_DisableMergeHeadAndBody | ExtensionFlag_DisableMergeTail));
if (idx == 0) {
return BaseMask | ExtensionFlag_DisableMergeHead | ExtensionFlag_DisableMergeHeadAndBody;
} else if (idx < (L3ContiguousBlockSize / L3BlockSize) - 1) {
return BaseMask;
} else {
return BaseMask | ExtensionFlag_DisableMergeTail;
}
}
constexpr ALWAYS_INLINE u64 GetEntryTemplateForL3Block(size_t idx) const {
return this->attributes & GetEntryTemplateForL3BlockMask(idx);
}
constexpr ALWAYS_INLINE bool IsCompatibleWithAttribute(const PageTableEntry &rhs, u8 sw_reserved_bits, bool contig) const {
/* Check whether this has the same permission/etc as the desired attributes. */ /* Check whether this has the same permission/etc as the desired attributes. */
return L3PageTableEntry(BlockTag{}, this->GetBlock(), rhs, contig).GetRawAttributes() == this->GetRawAttributes(); return L3PageTableEntry(BlockTag{}, this->GetBlock(), rhs, sw_reserved_bits, contig).GetRawAttributes() == this->GetRawAttributes();
} }
}; };

View File

@@ -29,6 +29,11 @@ namespace ams::kern::arch::arm64 {
struct TraversalEntry { struct TraversalEntry {
KPhysicalAddress phys_addr; KPhysicalAddress phys_addr;
size_t block_size; size_t block_size;
u8 sw_reserved_bits;
constexpr bool IsHeadMergeDisabled() const { return (this->sw_reserved_bits & PageTableEntry::SoftwareReservedBit_DisableMergeHead) != 0; }
constexpr bool IsHeadAndBodyMergeDisabled() const { return (this->sw_reserved_bits & PageTableEntry::SoftwareReservedBit_DisableMergeHeadAndBody) != 0; }
constexpr bool IsTailMergeDisabled() const { return (this->sw_reserved_bits & PageTableEntry::SoftwareReservedBit_DisableMergeHeadTail) != 0; }
}; };
struct TraversalContext { struct TraversalContext {
@@ -107,6 +112,7 @@ namespace ams::kern::arch::arm64 {
L1PageTableEntry *Finalize(); L1PageTableEntry *Finalize();
void Dump(uintptr_t start, size_t size) const; void Dump(uintptr_t start, size_t size) const;
size_t CountPageTables() const;
bool BeginTraversal(TraversalEntry *out_entry, TraversalContext *out_context, KProcessAddress address) const; bool BeginTraversal(TraversalEntry *out_entry, TraversalContext *out_context, KProcessAddress address) const;
bool ContinueTraversal(TraversalEntry *out_entry, TraversalContext *context) const; bool ContinueTraversal(TraversalEntry *out_entry, TraversalContext *context) const;

View File

@@ -30,8 +30,8 @@ namespace ams::kern::arch::arm64 {
this->page_table.Activate(id); this->page_table.Activate(id);
} }
Result Initialize(u32 id, ams::svc::CreateProcessFlag as_type, bool enable_aslr, 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) {
return this->page_table.InitializeForProcess(id, as_type, enable_aslr, from_back, pool, code_address, code_size, mem_block_slab_manager, block_info_manager, pt_manager); return this->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);
} }
void Finalize() { this->page_table.Finalize(); } void Finalize() { this->page_table.Finalize(); }
@@ -128,10 +128,6 @@ namespace ams::kern::arch::arm64 {
return this->page_table.MakeAndOpenPageGroup(out, address, num_pages, state_mask, state, perm_mask, perm, attr_mask, attr); return this->page_table.MakeAndOpenPageGroup(out, address, num_pages, state_mask, state, perm_mask, perm, attr_mask, attr);
} }
Result MakeAndOpenPageGroupContiguous(KPageGroup *out, KProcessAddress address, size_t num_pages, u32 state_mask, u32 state, u32 perm_mask, u32 perm, u32 attr_mask, u32 attr) {
return this->page_table.MakeAndOpenPageGroupContiguous(out, address, num_pages, state_mask, state, perm_mask, perm, attr_mask, attr);
}
Result InvalidateProcessDataCache(KProcessAddress address, size_t size) { Result InvalidateProcessDataCache(KProcessAddress address, size_t size) {
return this->page_table.InvalidateProcessDataCache(address, size); return this->page_table.InvalidateProcessDataCache(address, size);
} }
@@ -152,6 +148,14 @@ namespace ams::kern::arch::arm64 {
return this->page_table.UnlockForDeviceAddressSpace(address, size); return this->page_table.UnlockForDeviceAddressSpace(address, size);
} }
Result MakePageGroupForUnmapDeviceAddressSpace(KPageGroup *out, KProcessAddress address, size_t size) {
return this->page_table.MakePageGroupForUnmapDeviceAddressSpace(out, address, size);
}
Result UnlockForDeviceAddressSpacePartialMap(KProcessAddress address, size_t size, size_t mapped_size) {
return this->page_table.UnlockForDeviceAddressSpacePartialMap(address, size, mapped_size);
}
Result LockForIpcUserBuffer(KPhysicalAddress *out, KProcessAddress address, size_t size) { Result LockForIpcUserBuffer(KPhysicalAddress *out, KProcessAddress address, size_t size) {
return this->page_table.LockForIpcUserBuffer(out, address, size); return this->page_table.LockForIpcUserBuffer(out, address, size);
} }
@@ -228,14 +232,18 @@ namespace ams::kern::arch::arm64 {
return this->page_table.UnmapPhysicalMemoryUnsafe(address, size); return this->page_table.UnmapPhysicalMemoryUnsafe(address, size);
} }
void DumpTable() const {
return this->page_table.DumpTable();
}
void DumpMemoryBlocks() const { void DumpMemoryBlocks() const {
return this->page_table.DumpMemoryBlocks(); return this->page_table.DumpMemoryBlocks();
} }
void DumpPageTable() const {
return this->page_table.DumpPageTable();
}
size_t CountPageTables() const {
return this->page_table.CountPageTables();
}
bool GetPhysicalAddress(KPhysicalAddress *out, KProcessAddress address) const { bool GetPhysicalAddress(KPhysicalAddress *out, KProcessAddress address) const {
return this->page_table.GetPhysicalAddress(out, address); return this->page_table.GetPhysicalAddress(out, address);
} }
@@ -263,12 +271,22 @@ namespace ams::kern::arch::arm64 {
size_t GetNormalMemorySize() const { return this->page_table.GetNormalMemorySize(); } size_t GetNormalMemorySize() const { return this->page_table.GetNormalMemorySize(); }
size_t GetCodeSize() const { return this->page_table.GetCodeSize(); }
size_t GetCodeDataSize() const { return this->page_table.GetCodeDataSize(); }
size_t GetAliasCodeSize() const { return this->page_table.GetAliasCodeSize(); }
size_t GetAliasCodeDataSize() const { return this->page_table.GetAliasCodeDataSize(); }
u32 GetAllocateOption() const { return this->page_table.GetAllocateOption(); } u32 GetAllocateOption() const { return this->page_table.GetAllocateOption(); }
KPhysicalAddress GetHeapPhysicalAddress(KVirtualAddress address) const { KPhysicalAddress GetHeapPhysicalAddress(KVirtualAddress address) const {
return this->page_table.GetHeapPhysicalAddress(address); return this->page_table.GetHeapPhysicalAddress(address);
} }
KVirtualAddress GetHeapVirtualAddress(KPhysicalAddress address) const {
return this->page_table.GetHeapVirtualAddress(address);
}
KBlockInfoManager *GetBlockInfoManager() { KBlockInfoManager *GetBlockInfoManager() {
return this->page_table.GetBlockInfoManager(); return this->page_table.GetBlockInfoManager();
} }

View File

@@ -25,7 +25,7 @@ namespace ams::kern::arch::arm64 {
public: public:
constexpr KNotAlignedSpinLock() : packed_tickets(0) { /* ... */ } constexpr KNotAlignedSpinLock() : packed_tickets(0) { /* ... */ }
void Lock() { ALWAYS_INLINE void Lock() {
u32 tmp0, tmp1, tmp2; u32 tmp0, tmp1, tmp2;
__asm__ __volatile__( __asm__ __volatile__(
@@ -52,7 +52,7 @@ namespace ams::kern::arch::arm64 {
); );
} }
void Unlock() { ALWAYS_INLINE void Unlock() {
const u32 value = this->packed_tickets + 1; const u32 value = this->packed_tickets + 1;
__asm__ __volatile__( __asm__ __volatile__(
" stlrh %w[value], %[packed_tickets]\n" " stlrh %w[value], %[packed_tickets]\n"
@@ -71,7 +71,7 @@ namespace ams::kern::arch::arm64 {
public: public:
constexpr KAlignedSpinLock() : current_ticket(0), next_ticket(0) { /* ... */ } constexpr KAlignedSpinLock() : current_ticket(0), next_ticket(0) { /* ... */ }
void Lock() { ALWAYS_INLINE void Lock() {
u32 tmp0, tmp1, got_lock; u32 tmp0, tmp1, got_lock;
__asm__ __volatile__( __asm__ __volatile__(
@@ -94,7 +94,7 @@ namespace ams::kern::arch::arm64 {
); );
} }
void Unlock() { ALWAYS_INLINE void Unlock() {
const u32 value = this->current_ticket + 1; const u32 value = this->current_ticket + 1;
__asm__ __volatile__( __asm__ __volatile__(
" stlrh %w[value], %[current_ticket]\n" " stlrh %w[value], %[current_ticket]\n"

View File

@@ -62,6 +62,18 @@ namespace ams::kern::arch::arm64 {
} }
constexpr u64 GetIdentityMapTtbr0(s32 core_id) const { return this->ttbr0_identity[core_id]; } constexpr u64 GetIdentityMapTtbr0(s32 core_id) const { return this->ttbr0_identity[core_id]; }
void DumpMemoryBlocks() const {
return this->page_table.DumpMemoryBlocks();
}
void DumpPageTable() const {
return this->page_table.DumpPageTable();
}
size_t CountPageTables() const {
return this->page_table.CountPageTables();
}
}; };
} }

View File

@@ -0,0 +1,33 @@
/*
* 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>
namespace ams::kern::board::nintendo::nx::impl::cpu {
/* Virtual to Physical core map. */
constexpr inline const s32 VirtualToPhysicalCoreMap[BITSIZEOF(u64)] = {
0, 1, 2, 3, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 3,
};
}

View File

@@ -71,6 +71,10 @@ namespace ams::kern::board::nintendo::nx {
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, const KPageGroup &pg, KDeviceVirtualAddress device_address, ams::svc::MemoryPermission device_perm, bool refresh_mappings);
Result Unmap(const KPageGroup &pg, KDeviceVirtualAddress device_address); Result Unmap(const KPageGroup &pg, KDeviceVirtualAddress device_address);
void Unmap(KDeviceVirtualAddress device_address, size_t size) {
return this->UnmapImpl(device_address, size, false);
}
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);

View File

@@ -30,6 +30,7 @@ namespace ams::kern::board::nintendo::nx {
static size_t GetApplicationPoolSize(); static size_t GetApplicationPoolSize();
static size_t GetAppletPoolSize(); static size_t GetAppletPoolSize();
static size_t GetMinimumNonSecureSystemPoolSize(); static size_t GetMinimumNonSecureSystemPoolSize();
static u8 GetDebugLogUartPort();
/* Randomness. */ /* Randomness. */
static void GenerateRandomBytes(void *dst, size_t size); static void GenerateRandomBytes(void *dst, size_t size);

View File

@@ -25,6 +25,5 @@
namespace ams::kern::init { namespace ams::kern::init {
KPhysicalAddress GetInitArgumentsAddress(s32 core_id); KPhysicalAddress GetInitArgumentsAddress(s32 core_id);
void SetInitArguments(s32 core_id, KPhysicalAddress address, uintptr_t arg);
} }

View File

@@ -34,6 +34,8 @@ namespace ams::kern::init {
size_t num_KObjectName; size_t num_KObjectName;
size_t num_KResourceLimit; size_t num_KResourceLimit;
size_t num_KDebug; size_t num_KDebug;
size_t num_KAlpha;
size_t num_KBeta;
}; };
NOINLINE void InitializeSlabResourceCounts(); NOINLINE void InitializeSlabResourceCounts();

View File

@@ -26,6 +26,7 @@
#ifdef MESOSPHERE_BUILD_FOR_DEBUGGING #ifdef MESOSPHERE_BUILD_FOR_DEBUGGING
#define MESOSPHERE_ENABLE_ASSERTIONS #define MESOSPHERE_ENABLE_ASSERTIONS
#define MESOSPHERE_ENABLE_DEBUG_PRINT #define MESOSPHERE_ENABLE_DEBUG_PRINT
#define MESOSPHERE_ENABLE_KERNEL_STACK_USAGE
#endif #endif
//#define MESOSPHERE_BUILD_FOR_TRACING //#define MESOSPHERE_BUILD_FOR_TRACING

View File

@@ -40,7 +40,7 @@ namespace ams::kern {
#ifndef MESOSPHERE_DEBUG_LOG_SELECTED #ifndef MESOSPHERE_DEBUG_LOG_SELECTED
#ifdef ATMOSPHERE_BOARD_NINTENDO_NX #ifdef ATMOSPHERE_BOARD_NINTENDO_NX
#define MESOSPHERE_DEBUG_LOG_USE_UART_A #define MESOSPHERE_DEBUG_LOG_USE_UART
#else #else
#error "Unknown board for Default Debug Log Source" #error "Unknown board for Default Debug Log Source"
#endif #endif

View File

@@ -0,0 +1,41 @@
/*
* 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_auto_object.hpp>
#include <mesosphere/kern_slab_helpers.hpp>
namespace ams::kern {
class KAlpha final : public KAutoObjectWithSlabHeapAndContainer<KAlpha, KAutoObjectWithList> {
MESOSPHERE_AUTOOBJECT_TRAITS(KAlpha, KAutoObject);
private:
/* NOTE: Official KAlpha has size 0x50, corresponding to 0x20 bytes of fields. */
/* TODO: Add these fields, if KAlpha is ever instantiable in the NX kernel. */
public:
explicit KAlpha() {
/* ... */
}
virtual ~KAlpha() { /* ... */ }
/* virtual void Finalize() override; */
virtual bool IsInitialized() const override { return false /* TODO */; }
static void PostDestroy(uintptr_t arg) { MESOSPHERE_UNUSED(arg); /* ... */ }
};
}

View File

@@ -198,7 +198,7 @@ namespace ams::kern {
} }
} }
ALWAYS_INLINE ~KScopedAutoObject() { ~KScopedAutoObject() {
if (this->obj != nullptr) { if (this->obj != nullptr) {
this->obj->Close(); this->obj->Close();
} }
@@ -206,7 +206,7 @@ namespace ams::kern {
} }
template<typename U> requires (std::derived_from<T, U> || std::derived_from<U, T>) template<typename U> requires (std::derived_from<T, U> || std::derived_from<U, T>)
constexpr ALWAYS_INLINE KScopedAutoObject(KScopedAutoObject<U> &&rhs) { constexpr KScopedAutoObject(KScopedAutoObject<U> &&rhs) {
if constexpr (std::derived_from<U, T>) { if constexpr (std::derived_from<U, T>) {
/* Upcast. */ /* Upcast. */
this->obj = rhs.obj; this->obj = rhs.obj;

View File

@@ -56,8 +56,8 @@ namespace ams::kern {
void Initialize() { MESOSPHERE_ASSERT_THIS(); } void Initialize() { MESOSPHERE_ASSERT_THIS(); }
void Finalize() { MESOSPHERE_ASSERT_THIS(); } void Finalize() { MESOSPHERE_ASSERT_THIS(); }
Result Register(KAutoObjectWithList *obj); void Register(KAutoObjectWithList *obj);
Result Unregister(KAutoObjectWithList *obj); void Unregister(KAutoObjectWithList *obj);
size_t GetOwnedCount(KProcess *owner); size_t GetOwnedCount(KProcess *owner);
}; };

View File

@@ -0,0 +1,48 @@
/*
* 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_auto_object.hpp>
#include <mesosphere/kern_slab_helpers.hpp>
namespace ams::kern {
class KProcess;
class KBeta final : public KAutoObjectWithSlabHeapAndContainer<KBeta, KAutoObjectWithList> {
MESOSPHERE_AUTOOBJECT_TRAITS(KBeta, KAutoObject);
private:
friend class KProcess;
private:
/* NOTE: Official KBeta has size 0x88, corresponding to 0x58 bytes of fields. */
/* TODO: Add these fields, if KBeta is ever instantiable in the NX kernel. */
util::IntrusiveListNode process_list_node;
public:
explicit KBeta()
: process_list_node()
{
/* ... */
}
virtual ~KBeta() { /* ... */ }
/* virtual void Finalize() override; */
virtual bool IsInitialized() const override { return false /* TODO */; }
static void PostDestroy(uintptr_t arg) { MESOSPHERE_UNUSED(arg); /* ... */ }
};
}

View File

@@ -112,6 +112,10 @@ namespace ams::kern {
KSessionRequest, KSessionRequest,
KCodeMemory, KCodeMemory,
/* NOTE: True order for these has not been determined yet. */
KAlpha,
KBeta,
FinalClassesEnd = FinalClassesStart + NumFinalClasses, FinalClassesEnd = FinalClassesStart + NumFinalClasses,
}; };

View File

@@ -42,6 +42,10 @@ namespace ams::kern {
constexpr const KPort *GetParent() const { return this->parent; } constexpr const KPort *GetParent() const { return this->parent; }
ALWAYS_INLINE s32 GetNumSessions() const { return this->num_sessions; }
ALWAYS_INLINE s32 GetPeakSessions() const { return this->peak_sessions; }
ALWAYS_INLINE s32 GetMaxSessions() const { return this->max_sessions; }
bool IsLight() const; bool IsLight() const;
/* Overridden virtual functions. */ /* Overridden virtual functions. */

View File

@@ -20,8 +20,6 @@
namespace ams::kern { namespace ams::kern {
extern KThread g_cv_arbiter_compare_thread;
class KConditionVariable { class KConditionVariable {
public: public:
using ThreadTree = typename KThread::ConditionVariableThreadTreeType; using ThreadTree = typename KThread::ConditionVariableThreadTreeType;

View File

@@ -1,61 +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_select_cpu.hpp>
#include <mesosphere/kern_k_current_context.hpp>
#include <mesosphere/kern_k_scheduler.hpp>
#include <mesosphere/kern_k_interrupt_task_manager.hpp>
#include <mesosphere/kern_select_interrupt_manager.hpp>
#include <mesosphere/kern_select_hardware_timer.hpp>
#include <mesosphere/kern_k_memory_manager.hpp>
namespace ams::kern {
struct KCoreLocalContext {
KCurrentContext current;
KScheduler scheduler;
KInterruptTaskManager interrupt_task_manager;
KInterruptManager interrupt_manager;
KHardwareTimer hardware_timer;
/* Everything after this point is for debugging. */
/* Retail kernel doesn't even consistently update these fields. */
u64 num_sw_interrupts;
u64 num_hw_interrupts;
std::atomic<u64> num_svc;
u64 num_process_switches;
u64 num_thread_switches;
u64 num_fpu_switches;
u64 num_scheduler_updates;
u64 num_invoked_scheduler_updates;
std::atomic<u64> num_specific_svc[0x80];
u32 perf_counters[6];
};
static_assert(sizeof(KCoreLocalContext) < PageSize);
struct KCoreLocalPage {
KCoreLocalContext context;
u8 padding[PageSize - sizeof(KCoreLocalContext)];
};
static_assert(sizeof(KCoreLocalPage) == PageSize);
struct KCoreLocalRegion {
KCoreLocalPage current;
KCoreLocalPage absolute[cpu::NumCores];
};
static_assert(sizeof(KCoreLocalRegion) == PageSize * (1 + cpu::NumCores));
}

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