Compare commits

..

75 Commits

Author SHA1 Message Date
Michael Scire
feb765c40d kernel patches: fuck armconverter.com 2020-12-02 06:03:26 -08:00
Michael Scire
d7429b74a4 kern: tweak KScopedAutoObject 2020-12-02 04:08:06 -08:00
Michael Scire
53aae17b64 kern: allow non-inline GetObjectForIpc 2020-12-02 04:07:01 -08:00
Michael Scire
94d818db90 kern: fix KHandleTable null deref in ipc 2020-12-02 04:05:16 -08:00
Michael Scire
eccadf2958 kern: session mapping getters are on the hotpath 2020-12-02 03:52:08 -08:00
Michael Scire
60ea4a1b1c kern: tweak optimization settings for hot paths 2020-12-02 03:39:07 -08:00
Michael Scire
464f336016 kern: more iterator adjustments 2020-12-02 03:33:10 -08:00
Michael Scire
c788f7a3fc strat: add new npdm field 2020-12-02 02:51:02 -08:00
Michael Scire
bbfed7be66 ams.mitm: fix old hid api references 2020-12-02 02:37:48 -08:00
Michael Scire
e38f87b182 ams: this version will be 0.16.0 2020-12-02 02:26:22 -08:00
Michael Scire
e4677d3a9d Merge remote-tracking branch 'origin/hid_refactor' into 11_support 2020-12-02 02:24:18 -08:00
Adubbz
3b18db914c daybreak: update for hid refactor (#1222) 2020-12-02 02:21:05 -08:00
Michael Scire
01a5f4094b hot path: just in case 2020-12-02 02:17:32 -08:00
Michael Scire
2f12dd039f microkernel: hot paths are pretty fucking hot 2020-12-02 02:14:24 -08:00
Michael Scire
f058d04933 kern: update KConditionVariable to support new has_waiter_flag rules 2020-12-02 01:28:21 -08:00
Michael Scire
8e1a46b951 kern: fix SvcGetResourceLimitPeakValue 2020-12-01 19:29:17 -08:00
Michael Scire
24db70602f kern: fix copy/paste error 2020-12-01 19:21:45 -08:00
Michael Scire
4ce3778d87 kern: fix bugs caused by UB + transition to -Os 2020-12-01 18:41:44 -08:00
Michael Scire
95bbb20cb0 loader: support 11.x DisableDeviceAddressSpaceMerge 2020-12-01 17:47:48 -08:00
Michael Scire
f089cd4b76 kern: allow non-inline KSchedulerLock::Lock 2020-12-01 17:36:14 -08:00
Michael Scire
6f95b738dc kern: build as -Os instead of -O2 2020-12-01 17:34:09 -08:00
Michael Scire
6cc21e4d98 kern: reduce KMemoryRegionAllocator slab size 2020-12-01 17:31:21 -08:00
Michael Scire
8936e4d5d9 kern: assume that uart has been setup by secmon 2020-12-01 17:30:42 -08:00
Michael Scire
3b3cb337f0 kern: update Initialize0 to account for new ordering 2020-12-01 17:29:42 -08:00
Michael Scire
a56bdab820 kern: add new overflow checks on KMemoryRegions 2020-12-01 17:14:23 -08:00
Michael Scire
866310937a kern: fix assertion in the multi-region pool partition code 2020-12-01 17:03:42 -08:00
Michael Scire
cc7cf49c88 kern: improve KMemoryManager pool detection 2020-12-01 17:03:00 -08:00
Michael Scire
1e9a3c3f91 kern: update KMemoryRegion to store last address rather than size 2020-12-01 16:42:25 -08:00
Michael Scire
5002b17c71 kern: add KAlpha/KBeta 2020-12-01 16:32:30 -08:00
Michael Scire
3886c8707f kern: stubs for Svc39, 3A, 46, 47 2020-12-01 16:23:09 -08:00
Michael Scire
4c8dad3ea2 kern: remove now unused SetupFor*Compare funcs 2020-12-01 16:20:20 -08:00
Michael Scire
25e1d34017 KConditionVariable/KAddressArbiter: no need for global compare thread 2020-12-01 16:19:39 -08:00
Michael Scire
4f00303daf kern: set EL2 id registers on deprivilege 2020-12-01 15:57:45 -08:00
Michael Scire
b421e3eadb kern: implement 64-virtual-core interface 2020-12-01 15:54:31 -08:00
fincs
b69bf07d9c reboot_to_payload: Update for new libnx HID interface 2020-12-02 00:51:02 +01:00
fincs
09978eafb9 strat/cfg: Update for new libnx HID interface 2020-12-02 00:50:14 +01:00
fincs
8070de693d strat/hid: Update for new libnx HID interface 2020-12-02 00:42:13 +01:00
Michael Scire
72671d39ab kern: cleanup KThread, optimize/normalize KThreadQueue/KWaitObject 2020-12-01 15:19:29 -08:00
Michael Scire
a4c4cf22c9 kern: improve KSynchronizationObject, kill KSynchronization 2020-12-01 14:58:35 -08:00
Michael Scire
6ea1955e94 kern: update for new interrupt event locking scheme 2020-12-01 14:17:25 -08:00
Michael Scire
e81025af2e kern: fix sleep save/resume for new x18/tpidr scheme 2020-12-01 14:09:09 -08:00
Michael Scire
791638e6ba kern: fix race-crash on interrupt controller save, improve fatal output 2020-12-01 13:56:01 -08:00
Michael Scire
2e0378c724 kern: KObjectContainer::Register -> void 2020-12-01 13:49:30 -08:00
Michael Scire
59ada14680 kern: Kill KCoreLocalRegion 2020-12-01 13:41:37 -08:00
Michael Scire
25e944f519 kern: remove more of clc 2020-12-01 13:08:47 -08:00
Michael Scire
3e87b8ff17 kern: move scheduler/interrupt task manager out of core local region 2020-12-01 13:03:44 -08:00
Michael Scire
55502fcd0c kern: update KHardwareTimer, move out of KCoreLocalRegion 2020-12-01 07:47:29 -08:00
Michael Scire
d3e3292bb8 kern: use single interrupt manager object 2020-12-01 07:35:43 -08:00
Michael Scire
33c568963d kern: fix unnecessary align-down 2020-12-01 07:22:05 -08:00
Michael Scire
c374f1c5ce kern: fix error in SeparatePages 2020-12-01 07:19:03 -08:00
Michael Scire
825e2df2e0 kern: fix re-order/assert in KMemoryBlock 2020-12-01 06:55:50 -08:00
Michael Scire
b3efdebeaf kern: remove KPageTableBase::MakeAndOpenContiguousPageGroup 2020-12-01 06:54:53 -08:00
Michael Scire
b393f8f348 kern: implement DisableDeviceAddressSpaceMerge 2020-12-01 06:53:22 -08:00
Michael Scire
74e0ea1033 kern: SvcGetResourceLimitPeakValue 2020-12-01 06:07:18 -08:00
Michael Scire
1738a308c4 kern: KMemoryManager::Allocate -> AllocateAndOpen 2020-12-01 06:01:44 -08:00
Michael Scire
8fe7373ad2 kern: implement kmemoryblock/kmemoryinfo merge disable 2020-12-01 04:57:09 -08:00
Michael Scire
83dd25b894 kern: remove KMemoryAttribute_AnyLocked 2020-12-01 04:33:46 -08:00
Michael Scire
5217a78637 kern: update KMemoryBlockManagerUpdateAllocator api 2020-12-01 04:25:05 -08:00
Michael Scire
2f0470ff1c kern: implement new software-reserved page table bits 2020-12-01 04:14:58 -08:00
Michael Scire
e6733fb2d4 kern: update KPageTableBase for new disable-merge attrs 2020-12-01 03:33:46 -08:00
Michael Scire
5be5be9e5c fusee: recognize/support 11.x kernel 2020-12-01 03:28:23 -08:00
Michael Scire
f86d23cb2c nogc: update for new lafw 2020-12-01 00:58:21 -08:00
Michael Scire
a7bc540fed fusee: whoops 2020-11-30 23:34:37 -08:00
Michael Scire
0f7853417a fusee: fix 11.x pk21 support 2020-11-30 23:31:58 -08:00
Michael Scire
11f90f03d9 fusee-secondary: update for 11.0.0 erista 2020-11-30 22:49:30 -08:00
Michael Scire
7e2449b347 erpt: lightly update (TODO: use context, do new svc stuff) 2020-11-30 22:41:16 -08:00
Michael Scire
abe57ac5b2 sm: implement UserService::DetachClient 2020-11-30 22:18:18 -08:00
Michael Scire
8d458b44d7 loader: update for 11.0.0 (anti-dg + set program args abi) 2020-11-30 22:06:52 -08:00
Michael Scire
1352690ece pgl: update for 11.0.0 2020-11-30 21:47:18 -08:00
Michael Scire
ac6fc7b965 fs: nogc patches for 11.0.0 2020-11-30 21:34:06 -08:00
Michael Scire
d0e6fdb3da emummc: untested 11.0.0 support 2020-11-30 21:28:12 -08:00
Michael Scire
4c581d21f6 kldr: update for 11.0.0 2020-11-30 20:47:00 -08:00
Michael Scire
1365814b8d exo: update for 11.0.0 2020-11-30 20:18:25 -08:00
Michael Scire
f63d79d8f9 result: update for accurate ::Includes 2020-11-30 17:16:00 -08:00
Michael Scire
14d50c0e39 erpt: add update autogenerated ids 2020-11-30 16:09:31 -08:00
194 changed files with 2941 additions and 4206 deletions

View File

@@ -35,17 +35,6 @@
# mmc space, encrypted to prevent detection. This backup can be used
# 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]
debugmode=1
debugmode_user=0
@@ -54,6 +43,3 @@ enable_user_pmu_access=0
blank_prodinfo_sysmmc=0
blank_prodinfo_emummc=0
allow_writing_to_cal_sysmmc=0
log_port=0
log_baud_rate=115200
log_inverted=0

View File

@@ -1,50 +1,4 @@
# 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
+ 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.

View File

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

View File

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

View File

@@ -71,7 +71,6 @@ static const fs_offsets_t GET_OFFSET_STRUCT_NAME(vers) = { \
.nand_mutex = FS_OFFSET##vers##_NAND_MUTEX, \
.active_partition = FS_OFFSET##vers##_ACTIVE_PARTITION, \
.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, \
.sd_das_init = FS_OFFSET##vers##_SD_DAS_INIT, \
.nintendo_paths = FS_OFFSET##vers##_NINTENDO_PATHS, \

View File

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

View File

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

View File

@@ -34,7 +34,6 @@
#define FS_OFFSET_100_LOCK_MUTEX 0x2884
#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
// Misc Data

View File

@@ -34,7 +34,6 @@
#define FS_OFFSET_1000_LOCK_MUTEX 0x28910
#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
// Misc Data

View File

@@ -34,7 +34,6 @@
#define FS_OFFSET_1000_EXFAT_LOCK_MUTEX 0x28910
#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
// Misc Data

View File

@@ -34,7 +34,6 @@
#define FS_OFFSET_1020_LOCK_MUTEX 0x28910
#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
// Misc Data

View File

@@ -34,7 +34,6 @@
#define FS_OFFSET_1020_EXFAT_LOCK_MUTEX 0x28910
#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
// Misc Data

View File

@@ -34,7 +34,6 @@
#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

View File

@@ -34,7 +34,6 @@
#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

View File

@@ -34,7 +34,6 @@
#define FS_OFFSET_200_LOCK_MUTEX 0x3264
#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
// Misc Data

View File

@@ -34,7 +34,6 @@
#define FS_OFFSET_200_EXFAT_LOCK_MUTEX 0x3264
#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
// Misc Data

View File

@@ -34,7 +34,6 @@
#define FS_OFFSET_210_LOCK_MUTEX 0x3264
#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
// Misc Data

View File

@@ -34,7 +34,6 @@
#define FS_OFFSET_210_EXFAT_LOCK_MUTEX 0x3264
#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
// Misc Data

View File

@@ -34,7 +34,6 @@
#define FS_OFFSET_300_LOCK_MUTEX 0x35CC
#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
// Misc Data

View File

@@ -34,7 +34,6 @@
#define FS_OFFSET_300_EXFAT_LOCK_MUTEX 0x35CC
#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
// Misc Data

View File

@@ -34,7 +34,6 @@
#define FS_OFFSET_301_LOCK_MUTEX 0x3638
#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
// Misc Data

View File

@@ -34,7 +34,6 @@
#define FS_OFFSET_301_EXFAT_LOCK_MUTEX 0x3638
#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
// Misc Data

View File

@@ -34,7 +34,6 @@
#define FS_OFFSET_400_LOCK_MUTEX 0x39A0
#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
// Misc Data

View File

@@ -34,7 +34,6 @@
#define FS_OFFSET_400_EXFAT_LOCK_MUTEX 0x39A0
#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
// Misc Data

View File

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

View File

@@ -34,7 +34,6 @@
#define FS_OFFSET_410_EXFAT_LOCK_MUTEX 0x39A0
#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
// Misc Data

View File

@@ -34,7 +34,6 @@
#define FS_OFFSET_500_LOCK_MUTEX 0x4080
#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
// Misc Data

View File

@@ -34,7 +34,6 @@
#define FS_OFFSET_500_EXFAT_LOCK_MUTEX 0x4080
#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
// Misc Data

View File

@@ -34,7 +34,6 @@
#define FS_OFFSET_510_LOCK_MUTEX 0x4080
#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
// Misc Data

View File

@@ -34,7 +34,6 @@
#define FS_OFFSET_510_EXFAT_LOCK_MUTEX 0x4080
#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
// Misc Data

View File

@@ -34,7 +34,6 @@
#define FS_OFFSET_600_LOCK_MUTEX 0x1412C0
#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
// Misc Data

View File

@@ -34,7 +34,6 @@
#define FS_OFFSET_600_EXFAT_LOCK_MUTEX 0x14C9C0
#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
// Misc Data

View File

@@ -34,7 +34,6 @@
#define FS_OFFSET_700_LOCK_MUTEX 0x148A90
#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
// Misc Data

View File

@@ -34,7 +34,6 @@
#define FS_OFFSET_700_EXFAT_LOCK_MUTEX 0x154040
#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
// Misc Data

View File

@@ -34,7 +34,6 @@
#define FS_OFFSET_800_LOCK_MUTEX 0x14B6D0
#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
// Misc Data

View File

@@ -34,7 +34,6 @@
#define FS_OFFSET_800_EXFAT_LOCK_MUTEX 0x156C80
#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
// Misc Data

View File

@@ -34,7 +34,6 @@
#define FS_OFFSET_810_LOCK_MUTEX 0x14B6D0
#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
// Misc Data

View File

@@ -34,7 +34,6 @@
#define FS_OFFSET_810_EXFAT_LOCK_MUTEX 0x156C80
#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
// Misc Data

View File

@@ -34,7 +34,6 @@
#define FS_OFFSET_900_LOCK_MUTEX 0x25280
#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
// Misc Data

View File

@@ -34,7 +34,6 @@
#define FS_OFFSET_900_EXFAT_LOCK_MUTEX 0x25280
#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
// Misc Data

View File

@@ -34,7 +34,6 @@
#define FS_OFFSET_910_LOCK_MUTEX 0x25280
#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
// Misc Data

View File

@@ -34,7 +34,6 @@
#define FS_OFFSET_910_EXFAT_LOCK_MUTEX 0x25280
#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
// 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)
{
if ((emuMMC_ctx.EMMC_Type == emuMMC_SD_Raw))
if ((emuMMC_ctx.EMMC_Type == emuMMC_SD))
{
// raw partition sector offset: emuMMC_ctx.EMMC_StoragePartitionOffset.
sector += emuMMC_ctx.EMMC_StoragePartitionOffset;
@@ -318,31 +318,6 @@ static uint64_t emummc_read_write_inner(void *buf, unsigned int sector, unsigned
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
uint64_t sdmmc_wrapper_controller_close(int mmc_id)
{
@@ -414,7 +389,7 @@ uint64_t sdmmc_wrapper_read(void *buf, uint64_t bufSize, int mmc_id, unsigned in
if (first_sd_read)
{
first_sd_read = false;
if (emuMMC_ctx.EMMC_Type == emuMMC_SD_Raw)
if (emuMMC_ctx.EMMC_Type == emuMMC_SD)
{
// Because some SD cards have issues with emuMMC's driver
// we currently swap to FS's driver after first SD read
@@ -425,7 +400,7 @@ uint64_t sdmmc_wrapper_read(void *buf, uint64_t bufSize, int mmc_id, unsigned in
}
}
// Call hekate's driver.
// Call hekates driver.
if (sdmmc_storage_read(&sd_storage, sector, num_sectors, buf))
{
mutex_unlock_handler(mmc_id);

View File

@@ -52,7 +52,6 @@ void mutex_lock_handler(int mmc_id);
void mutex_unlock_handler(int mmc_id);
// Hooks
uint64_t sdmmc_wrapper_controller_open(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_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,
// SD Device raw
emuMMC_SD_Raw,
emuMMC_SD,
// SD Device File
emuMMC_SD_File,

View File

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

View File

@@ -72,9 +72,6 @@ namespace ams::secmon::boot {
/* 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. */
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. */

View File

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

View File

@@ -47,7 +47,7 @@ namespace ams::secmon::smc {
[fuse::DramId_IcosaSamsung4GB] = pkg1::MemorySize_4GB,
[fuse::DramId_IcosaHynix4GB] = pkg1::MemorySize_4GB,
[fuse::DramId_IcosaMicron4GB] = pkg1::MemorySize_4GB,
[fuse::DramId_FiveHynix1y4GB] = pkg1::MemorySize_4GB,
[fuse::DramId_CopperSamsung4GB] = pkg1::MemorySize_4GB,
[fuse::DramId_IcosaSamsung6GB] = pkg1::MemorySize_6GB,
[fuse::DramId_CopperHynix4GB] = pkg1::MemorySize_4GB,
[fuse::DramId_CopperMicron4GB] = pkg1::MemorySize_4GB,
@@ -66,13 +66,9 @@ namespace ams::secmon::smc {
[fuse::DramId_HoagSamsung1y4GBX] = pkg1::MemorySize_4GB,
[fuse::DramId_IowaSamsung1y4GBY] = pkg1::MemorySize_4GB,
[fuse::DramId_IowaSamsung1y8GBY] = pkg1::MemorySize_8GB,
[fuse::DramId_FiveSamsung1y4GB] = pkg1::MemorySize_4GB,
[fuse::DramId_HoagSamsung1y8GBX] = pkg1::MemorySize_8GB,
[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_IowaSamsung1y4GBA] = pkg1::MemorySize_4GB,
[fuse::DramId_FiveSamsung1y8GBX] = pkg1::MemorySize_8GB,
[fuse::DramId_FiveSamsung1y4GBX] = pkg1::MemorySize_4GB,
};
constexpr const pkg1::MemoryMode MemoryModes[] = {
@@ -282,10 +278,6 @@ namespace ams::secmon::smc {
return SmcResult::NotInitialized;
}
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:
return SmcResult::InvalidArgument;
}

View File

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

View File

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

View File

@@ -34,17 +34,11 @@
#define EXOSPHERE_FLAG_BLANK_PRODINFO (1 << 5u)
#define EXOSPHERE_FLAG_ALLOW_WRITING_TO_CAL_SYSMMC (1 << 6u)
#define EXOSPHERE_LOG_FLAG_INVERTED (1 << 0u)
typedef struct {
uint32_t magic;
uint32_t target_firmware;
uint32_t flags[2];
uint16_t lcd_vendor;
uint8_t log_port;
uint8_t log_flags;
uint32_t log_baud_rate;
uint32_t reserved1[2];
uint32_t flags;
uint32_t reserved[5];
exo_emummc_config_t emummc_cfg;
} exosphere_config_t;
@@ -60,9 +54,6 @@ _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_EMUMMC_KEY "blank_prodinfo_emummc"
#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 {
int debugmode;
@@ -72,9 +63,6 @@ typedef struct {
int blank_prodinfo_sysmmc;
int blank_prodinfo_emummc;
int allow_writing_to_cal_sysmmc;
int log_port;
int log_baud_rate;
int log_inverted;
} exosphere_parse_cfg_t;
#endif

View File

@@ -906,35 +906,6 @@ static const kernel_patch_t g_kernel_patches_1100[] = {
}
};
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,
/* Kernel Infos. */
@@ -1029,15 +1000,6 @@ static const kernel_info_t g_kernel_infos[] = {
.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)
}
};

View File

@@ -196,27 +196,6 @@ static int exosphere_ini_handler(void *user, const char *section, const char *na
} else if (tmp == 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 {
return 0;
}
@@ -261,7 +240,6 @@ 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)
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);
@@ -486,9 +464,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;
if (keygen_type) {
exo_cfg.flags[0] = EXOSPHERE_FLAG_PERFORM_620_KEYGEN;
exo_cfg.flags = EXOSPHERE_FLAG_PERFORM_620_KEYGEN;
} else {
exo_cfg.flags[0] = 0;
exo_cfg.flags = 0;
}
/* Setup exosphere parse configuration with defaults. */
@@ -500,9 +478,6 @@ static void nxboot_configure_exosphere(uint32_t target_firmware, unsigned int ke
.blank_prodinfo_sysmmc = 0,
.blank_prodinfo_emummc = 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. */
@@ -515,17 +490,13 @@ static void nxboot_configure_exosphere(uint32_t target_firmware, unsigned int ke
free(exosphere_ini);
/* Apply parse config. */
if (parse_cfg.debugmode) exo_cfg.flags[0] |= EXOSPHERE_FLAG_IS_DEBUGMODE_PRIV;
if (parse_cfg.debugmode_user) exo_cfg.flags[0] |= EXOSPHERE_FLAG_IS_DEBUGMODE_USER;
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[0] |= EXOSPHERE_FLAG_ENABLE_USERMODE_PMU_ACCESS;
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[0] |= EXOSPHERE_FLAG_BLANK_PRODINFO;
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 (parse_cfg.debugmode) exo_cfg.flags |= EXOSPHERE_FLAG_IS_DEBUGMODE_PRIV;
if (parse_cfg.debugmode_user) exo_cfg.flags |= EXOSPHERE_FLAG_IS_DEBUGMODE_USER;
if (parse_cfg.disable_user_exception_handlers) exo_cfg.flags |= 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.blank_prodinfo_sysmmc && !is_emummc) exo_cfg.flags |= EXOSPHERE_FLAG_BLANK_PRODINFO;
if (parse_cfg.blank_prodinfo_emummc && is_emummc) exo_cfg.flags |= EXOSPHERE_FLAG_BLANK_PRODINFO;
if (parse_cfg.allow_writing_to_cal_sysmmc) exo_cfg.flags |= EXOSPHERE_FLAG_ALLOW_WRITING_TO_CAL_SYSMMC;
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");

View File

@@ -6,7 +6,7 @@
[subrepo]
remote = https://github.com/Atmosphere-NX/Atmosphere-libs
branch = master
commit = 5a18bea64545105c52d642d7789029b5ca875864
parent = 17c8c390fc84d059b89f563a8fae6936649d0d45
commit = 10e9e0e8f926b11c2c7de16ffe15bea7d7ec2cdf
parent = 2ee2a4f1ac04bc7f15de8be8d57ad04d7e73f735
method = merge
cmdver = 0.4.1

View File

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

View File

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

View File

@@ -116,18 +116,6 @@ namespace ams::secmon {
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() {
return GetSecmonConfiguration().IsProduction();
}

View File

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

View File

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

View File

@@ -54,7 +54,6 @@
#include <mesosphere/kern_kernel.hpp>
#include <mesosphere/kern_k_page_table_manager.hpp>
#include <mesosphere/kern_select_page_table.hpp>
#include <mesosphere/kern_k_dump_object.hpp>
/* Miscellaneous objects. */
#include <mesosphere/kern_k_shared_memory_info.hpp>

View File

@@ -44,9 +44,6 @@ namespace ams::kern::arch::arm64 {
static uintptr_t GetProgramCounter(const KThread &thread);
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 SetHardwareBreakPoint(ams::svc::HardwareBreakPointRegisterName name, u64 flags, u64 value);
@@ -64,6 +61,8 @@ namespace ams::kern::arch::arm64 {
}
}
}
/* TODO: This is a placeholder definition. */
};
}

View File

@@ -112,7 +112,6 @@ namespace ams::kern::arch::arm64 {
L1PageTableEntry *Finalize();
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 ContinueTraversal(TraversalEntry *out_entry, TraversalContext *context) const;

View File

@@ -232,18 +232,14 @@ namespace ams::kern::arch::arm64 {
return this->page_table.UnmapPhysicalMemoryUnsafe(address, size);
}
void DumpTable() const {
return this->page_table.DumpTable();
}
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();
}
bool GetPhysicalAddress(KPhysicalAddress *out, KProcessAddress address) const {
return this->page_table.GetPhysicalAddress(out, address);
}
@@ -271,22 +267,12 @@ namespace ams::kern::arch::arm64 {
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(); }
KPhysicalAddress GetHeapPhysicalAddress(KVirtualAddress address) const {
return this->page_table.GetHeapPhysicalAddress(address);
}
KVirtualAddress GetHeapVirtualAddress(KPhysicalAddress address) const {
return this->page_table.GetHeapVirtualAddress(address);
}
KBlockInfoManager *GetBlockInfoManager() {
return this->page_table.GetBlockInfoManager();
}

View File

@@ -62,18 +62,6 @@ namespace ams::kern::arch::arm64 {
}
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

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

View File

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

View File

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

View File

@@ -42,10 +42,6 @@ namespace ams::kern {
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;
/* Overridden virtual functions. */

View File

@@ -1,43 +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>
namespace ams::kern::KDumpObject {
void DumpThread();
void DumpThread(u64 thread_id);
void DumpThreadCallStack();
void DumpThreadCallStack(u64 thread_id);
void DumpKernelObject();
void DumpHandle();
void DumpHandle(u64 process_id);
void DumpKernelMemory();
void DumpMemory();
void DumpMemory(u64 process_id);
void DumpProcess();
void DumpProcess(u64 process_id);
void DumpPort();
void DumpPort(u64 process_id);
}

View File

@@ -90,8 +90,6 @@ namespace ams::kern {
size_t GetFreeSize() const { return this->heap.GetFreeSize(); }
void DumpFreeList() const { return this->heap.DumpFreeList(); }
constexpr size_t GetPageOffset(KVirtualAddress address) const { return this->heap.GetPageOffset(address); }
constexpr size_t GetPageOffsetToEnd(KVirtualAddress address) const { return this->heap.GetPageOffsetToEnd(address); }
@@ -249,15 +247,12 @@ namespace ams::kern {
size_t GetFreeSize() {
size_t total = 0;
for (size_t i = 0; i < this->num_managers; i++) {
KScopedLightLock lk(this->pool_locks[this->managers[i].GetPool()]);
total += this->managers[i].GetFreeSize();
}
return total;
}
size_t GetFreeSize(Pool pool) {
KScopedLightLock lk(this->pool_locks[pool]);
constexpr Direction GetSizeDirection = Direction_FromFront;
size_t total = 0;
for (auto *manager = this->GetFirstManager(pool, GetSizeDirection); manager != nullptr; manager = this->GetNextManager(manager, GetSizeDirection)) {
@@ -265,15 +260,6 @@ namespace ams::kern {
}
return total;
}
void DumpFreeList(Pool pool) {
KScopedLightLock lk(this->pool_locks[pool]);
constexpr Direction DumpDirection = Direction_FromFront;
for (auto *manager = this->GetFirstManager(pool, DumpDirection); manager != nullptr; manager = this->GetNextManager(manager, DumpDirection)) {
manager->DumpFreeList();
}
}
public:
static size_t CalculateManagementOverheadSize(size_t region_size) {
return Impl::CalculateManagementOverheadSize(region_size);

View File

@@ -147,7 +147,6 @@ namespace ams::kern {
}
size_t GetFreeSize() const { return this->GetNumFreePages() * PageSize; }
void DumpFreeList() const;
void UpdateUsedSize() {
this->used_size = this->heap_size - (this->GetNumFreePages() * PageSize);

View File

@@ -301,8 +301,6 @@ namespace ams::kern {
Result SetupForIpcClient(PageLinkedList *page_list, size_t *out_blocks_needed, KProcessAddress address, size_t size, KMemoryPermission test_perm, KMemoryState dst_state);
Result SetupForIpcServer(KProcessAddress *out_addr, size_t size, KProcessAddress src_addr, KMemoryPermission test_perm, KMemoryState dst_state, KPageTableBase &src_page_table, bool send);
void CleanupForIpcClientOnServerSetupFailure(PageLinkedList *page_list, KProcessAddress address, size_t size, KMemoryPermission prot_perm);
size_t GetSize(KMemoryState state) const;
public:
bool GetPhysicalAddress(KPhysicalAddress *out, KProcessAddress virt_addr) const {
return this->GetImpl().GetPhysicalAddress(out, virt_addr);
@@ -384,9 +382,9 @@ namespace ams::kern {
Result MapPhysicalMemoryUnsafe(KProcessAddress address, size_t size);
Result UnmapPhysicalMemoryUnsafe(KProcessAddress address, size_t size);
void DumpMemoryBlocksLocked() const {
MESOSPHERE_ASSERT(this->IsLockedByCurrentThread());
this->memory_block_manager.DumpBlocks();
void DumpTable() const {
KScopedLightLock lk(this->general_lock);
this->GetImpl().Dump(GetInteger(this->address_space_start), this->address_space_end - this->address_space_start);
}
void DumpMemoryBlocks() const {
@@ -394,14 +392,9 @@ namespace ams::kern {
this->DumpMemoryBlocksLocked();
}
void DumpPageTable() const {
KScopedLightLock lk(this->general_lock);
this->GetImpl().Dump(GetInteger(this->address_space_start), this->address_space_end - this->address_space_start);
}
size_t CountPageTables() const {
KScopedLightLock lk(this->general_lock);
return this->GetImpl().CountPageTables();
void DumpMemoryBlocksLocked() const {
MESOSPHERE_ASSERT(this->IsLockedByCurrentThread());
this->memory_block_manager.DumpBlocks();
}
public:
KProcessAddress GetAddressSpaceStart() const { return this->address_space_start; }
@@ -425,11 +418,6 @@ namespace ams::kern {
return (this->current_heap_end - this->heap_region_start) + this->mapped_physical_memory_size;
}
size_t GetCodeSize() const;
size_t GetCodeDataSize() const;
size_t GetAliasCodeSize() const;
size_t GetAliasCodeDataSize() const;
u32 GetAllocateOption() const { return this->allocate_option; }
public:
static ALWAYS_INLINE KVirtualAddress GetLinearMappedVirtualAddress(KPhysicalAddress addr) {

View File

@@ -170,8 +170,6 @@ namespace ams::kern {
constexpr KProcessAddress GetEntryPoint() const { return this->code_address; }
constexpr size_t GetMainStackSize() const { return this->main_thread_stack_size; }
constexpr KMemoryManager::Pool GetMemoryPool() const { return this->memory_pool; }
constexpr u64 GetRandomEntropy(size_t i) const { return this->entropy[i]; }
@@ -307,11 +305,6 @@ namespace ams::kern {
}
}
const KDynamicPageManager &GetDynamicPageManager() const { return this->dynamic_page_manager; }
const KMemoryBlockSlabManager &GetMemoryBlockSlabManager() const { return this->memory_block_slab_manager; }
const KBlockInfoManager &GetBlockInfoManager() const { return this->block_info_manager; }
const KPageTableManager &GetPageTableManager() const { return this->page_table_manager; }
constexpr KThread *GetRunningThread(s32 core) const { return this->running_threads[core]; }
constexpr u64 GetRunningThreadIdleCount(s32 core) const { return this->running_thread_idle_counts[core]; }

View File

@@ -50,8 +50,6 @@ namespace ams::kern {
Result SendReply(uintptr_t message, uintptr_t buffer_size, KPhysicalAddress message_paddr);
void OnClientClosed();
void Dump();
private:
bool IsSignaledImpl() const;
void CleanupRequests();

View File

@@ -71,8 +71,6 @@ namespace ams::kern {
KServerSession &GetServerSession() { return this->server; }
const KClientSession &GetClientSession() const { return this->client; }
const KServerSession &GetServerSession() const { return this->server; }
const KClientPort *GetParent() const { return this->port; }
};
}

View File

@@ -140,21 +140,7 @@ namespace ams::kern {
void *obj = this->GetImpl()->Allocate();
/* Track the allocated peak. */
#if defined(MESOSPHERE_BUILD_FOR_DEBUGGING)
if (AMS_LIKELY(obj != nullptr)) {
static_assert(std::atomic_ref<uintptr_t>::is_always_lock_free);
std::atomic_ref<uintptr_t> peak_ref(this->peak);
const uintptr_t alloc_peak = reinterpret_cast<uintptr_t>(obj) + this->GetObjectSize();
uintptr_t cur_peak = this->peak;
do {
if (alloc_peak <= cur_peak) {
break;
}
} while (!peak_ref.compare_exchange_strong(cur_peak, alloc_peak));
}
#endif
/* TODO: under some debug define, track the peak for statistics, as N does? */
return obj;
}
@@ -179,29 +165,6 @@ namespace ams::kern {
uintptr_t GetSlabHeapAddress() const {
return this->start;
}
size_t GetNumRemaining() const {
size_t remaining = 0;
/* Only calculate the number of remaining objects under debug configuration. */
#if defined(MESOSPHERE_BUILD_FOR_DEBUGGING)
while (true) {
auto *cur = this->GetImpl()->GetHead();
remaining = 0;
while (this->Contains(reinterpret_cast<uintptr_t>(cur))) {
++remaining;
cur = cur->next;
}
if (cur == nullptr) {
break;
}
}
#endif
return remaining;
}
};
template<typename T>

View File

@@ -30,10 +30,9 @@ namespace ams::kern {
KThread *thread;
};
private:
ThreadListNode *thread_list_head;
ThreadListNode *thread_list_tail;
ThreadListNode *thread_list_root;
protected:
constexpr ALWAYS_INLINE explicit KSynchronizationObject() : KAutoObjectWithList(), thread_list_head(), thread_list_tail() { MESOSPHERE_ASSERT_THIS(); }
constexpr ALWAYS_INLINE explicit KSynchronizationObject() : KAutoObjectWithList(), thread_list_root() { MESOSPHERE_ASSERT_THIS(); }
virtual ~KSynchronizationObject() { MESOSPHERE_ASSERT_THIS(); }
virtual void OnFinalizeSynchronizationObject() { MESOSPHERE_ASSERT_THIS(); }
@@ -47,7 +46,7 @@ namespace ams::kern {
public:
virtual void Finalize() override;
virtual bool IsSignaled() const = 0;
virtual void DumpWaiters();
virtual void DebugWaiters();
};
}

View File

@@ -49,11 +49,11 @@ namespace ams::kern {
};
enum SuspendType : u32 {
SuspendType_Process = 0,
SuspendType_Thread = 1,
SuspendType_Debug = 2,
SuspendType_Backtrace = 3,
SuspendType_Init = 4,
SuspendType_Process = 0,
SuspendType_Thread = 1,
SuspendType_Debug = 2,
SuspendType_Unk3 = 3,
SuspendType_Init = 4,
SuspendType_Count,
};
@@ -67,13 +67,13 @@ namespace ams::kern {
ThreadState_SuspendShift = 4,
ThreadState_Mask = (1 << ThreadState_SuspendShift) - 1,
ThreadState_ProcessSuspended = (1 << (SuspendType_Process + ThreadState_SuspendShift)),
ThreadState_ThreadSuspended = (1 << (SuspendType_Thread + ThreadState_SuspendShift)),
ThreadState_DebugSuspended = (1 << (SuspendType_Debug + ThreadState_SuspendShift)),
ThreadState_BacktraceSuspended = (1 << (SuspendType_Backtrace + ThreadState_SuspendShift)),
ThreadState_InitSuspended = (1 << (SuspendType_Init + ThreadState_SuspendShift)),
ThreadState_ProcessSuspended = (1 << (SuspendType_Process + ThreadState_SuspendShift)),
ThreadState_ThreadSuspended = (1 << (SuspendType_Thread + ThreadState_SuspendShift)),
ThreadState_DebugSuspended = (1 << (SuspendType_Debug + ThreadState_SuspendShift)),
ThreadState_Unk3Suspended = (1 << (SuspendType_Unk3 + ThreadState_SuspendShift)),
ThreadState_InitSuspended = (1 << (SuspendType_Init + ThreadState_SuspendShift)),
ThreadState_SuspendFlagMask = ((1 << SuspendType_Count) - 1) << ThreadState_SuspendShift,
ThreadState_SuspendFlagMask = ((1 << SuspendType_Count) - 1) << ThreadState_SuspendShift,
};
enum DpcFlag : u32 {
@@ -533,7 +533,6 @@ namespace ams::kern {
return this->termination_requested || this->GetRawState() == ThreadState_Terminated;
}
size_t GetKernelStackUsage() const;
public:
/* Overridden parent functions. */
virtual u64 GetId() const override final { return this->GetThreadId(); }

View File

@@ -48,8 +48,6 @@ namespace ams::kern {
static size_t GetSlabHeapSize() { return s_slab_heap.GetSlabHeapSize(); }
static size_t GetPeakIndex() { return s_slab_heap.GetPeakIndex(); }
static uintptr_t GetSlabHeapAddress() { return s_slab_heap.GetSlabHeapAddress(); }
static size_t GetNumRemaining() { return s_slab_heap.GetNumRemaining(); }
};
template<typename Derived, typename Base>
@@ -94,7 +92,7 @@ namespace ams::kern {
virtual uintptr_t GetPostDestroyArgument() const { return 0; }
size_t GetSlabIndex() const {
return s_slab_heap.GetObjectIndex(static_cast<const Derived *>(this));
return s_slab_heap.GetIndex(static_cast<const Derived *>(this));
}
public:
static void InitializeSlabHeap(void *memory, size_t memory_size) {
@@ -118,8 +116,6 @@ namespace ams::kern {
static size_t GetSlabHeapSize() { return s_slab_heap.GetSlabHeapSize(); }
static size_t GetPeakIndex() { return s_slab_heap.GetPeakIndex(); }
static uintptr_t GetSlabHeapAddress() { return s_slab_heap.GetSlabHeapAddress(); }
static size_t GetNumRemaining() { return s_slab_heap.GetNumRemaining(); }
};
}

View File

@@ -384,541 +384,4 @@ namespace ams::kern::arch::arm64 {
#undef MESOSPHERE_SET_HW_WATCH_POINT
#undef MESOSPHERE_SET_HW_BREAK_POINT
void KDebug::PrintRegister(KThread *thread) {
#if defined(MESOSPHERE_BUILD_FOR_DEBUGGING)
{
/* Treat no thread as current thread. */
if (thread == nullptr) {
thread = GetCurrentThreadPointer();
}
/* Get the exception context. */
KExceptionContext *e_ctx = GetExceptionContext(thread);
/* Get the owner process. */
if (auto *process = thread->GetOwnerProcess(); process != nullptr) {
/* Lock the owner process. */
KScopedLightLock state_lk(process->GetStateLock());
KScopedLightLock list_lk(process->GetListLock());
/* Suspend all the process's threads. */
{
KScopedSchedulerLock sl;
auto end = process->GetThreadList().end();
for (auto it = process->GetThreadList().begin(); it != end; ++it) {
if (std::addressof(*it) != GetCurrentThreadPointer()) {
it->RequestSuspend(KThread::SuspendType_Backtrace);
}
}
}
/* Print the registers. */
MESOSPHERE_RELEASE_LOG("Registers\n");
if ((e_ctx->psr & 0x10) == 0) {
/* 64-bit thread. */
for (auto i = 0; i < 31; ++i) {
MESOSPHERE_RELEASE_LOG(" X[%2d]: 0x%016lx\n", i, e_ctx->x[i]);
}
MESOSPHERE_RELEASE_LOG(" SP: 0x%016lx\n", e_ctx->sp);
MESOSPHERE_RELEASE_LOG(" PC: 0x%016lx\n", e_ctx->pc - sizeof(u32));
MESOSPHERE_RELEASE_LOG(" PSR: 0x%08x\n", e_ctx->psr);
MESOSPHERE_RELEASE_LOG(" TPIDR_EL0: 0x%016lx\n", e_ctx->tpidr);
} else {
/* 32-bit thread. */
for (auto i = 0; i < 13; ++i) {
MESOSPHERE_RELEASE_LOG(" R[%2d]: 0x%08x\n", i, static_cast<u32>(e_ctx->x[i]));
}
MESOSPHERE_RELEASE_LOG(" SP: 0x%08x\n", static_cast<u32>(e_ctx->x[13]));
MESOSPHERE_RELEASE_LOG(" LR: 0x%08x\n", static_cast<u32>(e_ctx->x[14]));
MESOSPHERE_RELEASE_LOG(" PC: 0x%08x\n", static_cast<u32>(e_ctx->pc) - static_cast<u32>((e_ctx->psr & 0x20) ? sizeof(u16) : sizeof(u32)));
MESOSPHERE_RELEASE_LOG(" PSR: 0x%08x\n", e_ctx->psr);
MESOSPHERE_RELEASE_LOG(" TPIDR: 0x%08x\n", static_cast<u32>(e_ctx->tpidr));
}
/* Resume the threads that we suspended. */
{
KScopedSchedulerLock sl;
auto end = process->GetThreadList().end();
for (auto it = process->GetThreadList().begin(); it != end; ++it) {
if (std::addressof(*it) != GetCurrentThreadPointer()) {
it->Resume(KThread::SuspendType_Backtrace);
}
}
}
}
}
#else
MESOSPHERE_UNUSED(thread);
#endif
}
#if defined(MESOSPHERE_BUILD_FOR_DEBUGGING)
namespace {
bool IsHeapPhysicalAddress(KPhysicalAddress phys_addr) {
const KMemoryRegion *cached = nullptr;
return KMemoryLayout::IsHeapPhysicalAddress(cached, phys_addr);
}
template<typename T>
bool ReadValue(T *out, KProcess *process, uintptr_t address) {
KPhysicalAddress phys_addr;
KMemoryInfo mem_info;
ams::svc::PageInfo page_info;
if (!util::IsAligned(address, sizeof(T))) {
return false;
}
if (R_FAILED(process->GetPageTable().QueryInfo(std::addressof(mem_info), std::addressof(page_info), address))) {
return false;
}
if ((mem_info.GetPermission() & KMemoryPermission_UserRead) != KMemoryPermission_UserRead) {
return false;
}
if (!process->GetPageTable().GetPhysicalAddress(std::addressof(phys_addr), address)) {
return false;
}
if (!IsHeapPhysicalAddress(phys_addr)) {
return false;
}
*out = *GetPointer<T>(process->GetPageTable().GetHeapVirtualAddress(phys_addr));
return true;
}
bool GetModuleName(char *dst, size_t dst_size, KProcess *process, uintptr_t base_address) {
/* Locate .rodata. */
KMemoryInfo mem_info;
ams::svc::PageInfo page_info;
KMemoryState mem_state = KMemoryState_None;
while (true) {
if (R_FAILED(process->GetPageTable().QueryInfo(std::addressof(mem_info), std::addressof(page_info), base_address))) {
return false;
}
if (mem_state == KMemoryState_None) {
mem_state = mem_info.GetState();
if (mem_state != KMemoryState_Code && mem_state != KMemoryState_AliasCode) {
return false;
}
}
if (mem_info.GetState() != mem_state) {
return false;
}
if (mem_info.GetPermission() == KMemoryPermission_UserRead) {
break;
}
base_address = mem_info.GetEndAddress();
}
/* Check that first value is 0. */
u32 val;
if (!ReadValue(std::addressof(val), process, base_address)) {
return false;
}
if (val != 0) {
return false;
}
/* Read the name length. */
if (!ReadValue(std::addressof(val), process, base_address + sizeof(u32))) {
return false;
}
if (!(0 < val && val < dst_size)) {
return false;
}
const size_t name_len = val;
/* Read the name, one character at a time. */
for (size_t i = 0; i < name_len; ++i) {
if (!ReadValue(dst + i, process, base_address + 2 * sizeof(u32) + i)) {
return false;
}
if (!(0 < dst[i] && dst[i] <= 0x7F)) {
return false;
}
}
/* NULL-terminate. */
dst[name_len] = 0;
return true;
}
void PrintAddress(uintptr_t address) {
MESOSPHERE_RELEASE_LOG(" %p\n", reinterpret_cast<void *>(address));
}
void PrintAddressWithModuleName(uintptr_t address, bool has_module_name, const char *module_name, uintptr_t base_address) {
if (has_module_name) {
MESOSPHERE_RELEASE_LOG(" %p [%10s + %8lx]\n", reinterpret_cast<void *>(address), module_name, address - base_address);
} else {
MESOSPHERE_RELEASE_LOG(" %p [%10lx + %8lx]\n", reinterpret_cast<void *>(address), base_address, address - base_address);
}
}
void PrintAddressWithSymbol(uintptr_t address, bool has_module_name, const char *module_name, uintptr_t base_address, const char *symbol_name, uintptr_t func_address) {
if (has_module_name) {
MESOSPHERE_RELEASE_LOG(" %p [%10s + %8lx] (%s + %lx)\n", reinterpret_cast<void *>(address), module_name, address - base_address, symbol_name, address - func_address);
} else {
MESOSPHERE_RELEASE_LOG(" %p [%10lx + %8lx] (%s + %lx)\n", reinterpret_cast<void *>(address), base_address, address - base_address, symbol_name, address - func_address);
}
}
void PrintCodeAddress(KProcess *process, uintptr_t address, bool is_lr = true) {
/* Prepare to parse + print the address. */
uintptr_t test_address = is_lr ? address - sizeof(u32) : address;
uintptr_t base_address = address;
uintptr_t dyn_address = 0;
uintptr_t sym_tab = 0;
uintptr_t str_tab = 0;
size_t num_sym = 0;
u64 temp_64;
u32 temp_32;
/* Locate the start of .text. */
KMemoryInfo mem_info;
ams::svc::PageInfo page_info;
KMemoryState mem_state = KMemoryState_None;
while (true) {
if (R_FAILED(process->GetPageTable().QueryInfo(std::addressof(mem_info), std::addressof(page_info), base_address))) {
return PrintAddress(address);
}
if (mem_state == KMemoryState_None) {
mem_state = mem_info.GetState();
if (mem_state != KMemoryState_Code && mem_state != KMemoryState_AliasCode) {
return PrintAddress(address);
}
} else if (mem_info.GetState() != mem_state) {
return PrintAddress(address);
}
if (mem_info.GetPermission() != KMemoryPermission_UserReadExecute) {
return PrintAddress(address);
}
base_address = mem_info.GetAddress();
if (R_FAILED(process->GetPageTable().QueryInfo(std::addressof(mem_info), std::addressof(page_info), base_address - 1))) {
return PrintAddress(address);
}
if (mem_info.GetState() != mem_state) {
break;
}
if (mem_info.GetPermission() != KMemoryPermission_UserReadExecute) {
break;
}
}
/* Read the first instruction. */
if (!ReadValue(std::addressof(temp_32), process, base_address)) {
return PrintAddress(address);
}
/* Get the module name. */
char module_name[0x20];
const bool has_module_name = GetModuleName(module_name, sizeof(module_name), process, base_address);
/* If the process is 32-bit, just print the module. */
if (!process->Is64Bit()) {
return PrintAddressWithModuleName(address, has_module_name, module_name, base_address);
}
if (temp_32 == 0) {
/* Module is dynamically loaded by rtld. */
u32 mod_offset;
if (!ReadValue(std::addressof(mod_offset), process, base_address + sizeof(u32))) {
return PrintAddressWithModuleName(address, has_module_name, module_name, base_address);
}
if (!ReadValue(std::addressof(temp_32), process, base_address + mod_offset)) {
return PrintAddressWithModuleName(address, has_module_name, module_name, base_address);
}
if (temp_32 != 0x30444F4D) { /* MOD0 */
return PrintAddressWithModuleName(address, has_module_name, module_name, base_address);
}
if (!ReadValue(std::addressof(temp_32), process, base_address + mod_offset + sizeof(u32))) {
return PrintAddressWithModuleName(address, has_module_name, module_name, base_address);
}
dyn_address = base_address + mod_offset + temp_32;
} else if (temp_32 == 0x14000002) {
/* Module embeds rtld. */
if (!ReadValue(std::addressof(temp_32), process, base_address + 0x5C)) {
return PrintAddressWithModuleName(address, has_module_name, module_name, base_address);
}
if (temp_32 != 0x94000002) {
return PrintAddressWithModuleName(address, has_module_name, module_name, base_address);
}
if (!ReadValue(std::addressof(temp_32), process, base_address + 0x60)) {
return PrintAddressWithModuleName(address, has_module_name, module_name, base_address);
}
dyn_address = base_address + 0x60 + temp_32;
} else {
return PrintAddressWithModuleName(address, has_module_name, module_name, base_address);
}
/* Locate tables inside .dyn. */
for (size_t ofs = 0; /* ... */; ofs += 0x10) {
/* Read the DynamicTag. */
if (!ReadValue(std::addressof(temp_64), process, dyn_address + ofs)) {
return PrintAddressWithModuleName(address, has_module_name, module_name, base_address);
}
if (temp_64 == 0) {
/* We're done parsing .dyn. */
break;
} else if (temp_64 == 4) {
/* We found DT_HASH */
if (!ReadValue(std::addressof(temp_64), process, dyn_address + ofs + sizeof(u64))) {
return PrintAddressWithModuleName(address, has_module_name, module_name, base_address);
}
/* Read nchain, to get the number of symbols. */
if (!ReadValue(std::addressof(temp_32), process, base_address + temp_64 + sizeof(u32))) {
return PrintAddressWithModuleName(address, has_module_name, module_name, base_address);
}
num_sym = temp_32;
} else if (temp_64 == 5) {
/* We found DT_STRTAB */
if (!ReadValue(std::addressof(temp_64), process, dyn_address + ofs + sizeof(u64))) {
return PrintAddressWithModuleName(address, has_module_name, module_name, base_address);
}
str_tab = base_address + temp_64;
} else if (temp_64 == 6) {
/* We found DT_SYMTAB */
if (!ReadValue(std::addressof(temp_64), process, dyn_address + ofs + sizeof(u64))) {
return PrintAddressWithModuleName(address, has_module_name, module_name, base_address);
}
sym_tab = base_address + temp_64;
}
}
/* Check that we found all the tables. */
if (!(sym_tab != 0 && str_tab != 0 && num_sym != 0)) {
return PrintAddressWithModuleName(address, has_module_name, module_name, base_address);
}
/* Try to locate an appropriate symbol. */
for (size_t i = 0; i < num_sym; ++i) {
/* Read the symbol from userspace. */
struct {
u32 st_name;
u8 st_info;
u8 st_other;
u16 st_shndx;
u64 st_value;
u64 st_size;
} sym;
{
u64 x[sizeof(sym) / sizeof(u64)];
for (size_t j = 0; j < util::size(x); ++j) {
if (!ReadValue(x + j, process, sym_tab + sizeof(sym) * i + sizeof(u64) * j)) {
return PrintAddressWithModuleName(address, has_module_name, module_name, base_address);
}
}
std::memcpy(std::addressof(sym), x, sizeof(sym));
}
/* Check the symbol is valid/STT_FUNC. */
if (sym.st_shndx == 0 || ((sym.st_shndx & 0xFF00) == 0xFF00)) {
continue;
}
if ((sym.st_info & 0xF) != 2) {
continue;
}
/* Check the address. */
const uintptr_t func_start = base_address + sym.st_value;
if (func_start <= test_address && test_address < func_start + sym.st_size) {
/* Read the symbol name. */
const uintptr_t sym_address = str_tab + sym.st_name;
char sym_name[0x80];
sym_name[util::size(sym_name) - 1] = 0;
for (size_t j = 0; j < util::size(sym_name) - 1; ++j) {
if (!ReadValue(sym_name + j, process, sym_address + j)) {
return PrintAddressWithModuleName(address, has_module_name, module_name, base_address);
}
if (sym_name[j] == 0) {
break;
}
}
/* Print the symbol. */
return PrintAddressWithSymbol(address, has_module_name, module_name, base_address, sym_name, func_start);
}
}
/* Fall back to printing the module. */
return PrintAddressWithModuleName(address, has_module_name, module_name, base_address);
}
}
#endif
void KDebug::PrintBacktrace(KThread *thread) {
#if defined(MESOSPHERE_BUILD_FOR_DEBUGGING)
{
/* Treat no thread as current thread. */
if (thread == nullptr) {
thread = GetCurrentThreadPointer();
}
/* Get the exception context. */
KExceptionContext *e_ctx = GetExceptionContext(thread);
/* Get the owner process. */
if (auto *process = thread->GetOwnerProcess(); process != nullptr) {
/* Lock the owner process. */
KScopedLightLock state_lk(process->GetStateLock());
KScopedLightLock list_lk(process->GetListLock());
/* Suspend all the process's threads. */
{
KScopedSchedulerLock sl;
auto end = process->GetThreadList().end();
for (auto it = process->GetThreadList().begin(); it != end; ++it) {
if (std::addressof(*it) != GetCurrentThreadPointer()) {
it->RequestSuspend(KThread::SuspendType_Backtrace);
}
}
}
/* Print the backtrace. */
MESOSPHERE_RELEASE_LOG("User Backtrace\n");
if ((e_ctx->psr & 0x10) == 0) {
/* 64-bit thread. */
PrintCodeAddress(process, e_ctx->pc, false);
PrintCodeAddress(process, e_ctx->x[30]);
/* Walk the stack frames. */
uintptr_t fp = static_cast<uintptr_t>(e_ctx->x[29]);
for (auto i = 0; i < 0x20 && fp != 0 && util::IsAligned(fp, 0x10); ++i) {
/* Read the next frame. */
struct {
u64 fp;
u64 lr;
} stack_frame;
{
KMemoryInfo mem_info;
ams::svc::PageInfo page_info;
KPhysicalAddress phys_addr;
if (R_FAILED(process->GetPageTable().QueryInfo(std::addressof(mem_info), std::addressof(page_info), fp))) {
break;
}
if ((mem_info.GetState() & KMemoryState_FlagReferenceCounted) == 0) {
break;
}
if ((mem_info.GetAttribute() & KMemoryAttribute_Uncached) != 0) {
break;
}
if ((mem_info.GetPermission() & KMemoryPermission_UserRead) != KMemoryPermission_UserRead) {
break;
}
if (!process->GetPageTable().GetPhysicalAddress(std::addressof(phys_addr), fp)) {
break;
}
if (!IsHeapPhysicalAddress(phys_addr)) {
break;
}
u64 *frame_ptr = GetPointer<u64>(process->GetPageTable().GetHeapVirtualAddress(phys_addr));
stack_frame.fp = frame_ptr[0];
stack_frame.lr = frame_ptr[1];
}
/* Print and advance. */
PrintCodeAddress(process, stack_frame.lr);
fp = stack_frame.fp;
}
} else {
/* 32-bit thread. */
PrintCodeAddress(process, e_ctx->pc, false);
PrintCodeAddress(process, e_ctx->x[14]);
/* Walk the stack frames. */
uintptr_t fp = static_cast<uintptr_t>(e_ctx->x[11]);
for (auto i = 0; i < 0x20 && fp != 0 && util::IsAligned(fp, 4); ++i) {
/* Read the next frame. */
struct {
u32 fp;
u32 lr;
} stack_frame;
{
KMemoryInfo mem_info;
ams::svc::PageInfo page_info;
KPhysicalAddress phys_addr;
/* Read FP */
if (R_FAILED(process->GetPageTable().QueryInfo(std::addressof(mem_info), std::addressof(page_info), fp))) {
break;
}
if ((mem_info.GetState() & KMemoryState_FlagReferenceCounted) == 0) {
break;
}
if ((mem_info.GetAttribute() & KMemoryAttribute_Uncached) != 0) {
break;
}
if ((mem_info.GetPermission() & KMemoryPermission_UserRead) != KMemoryPermission_UserRead) {
break;
}
if (!process->GetPageTable().GetPhysicalAddress(std::addressof(phys_addr), fp)) {
break;
}
if (!IsHeapPhysicalAddress(phys_addr)) {
break;
}
stack_frame.fp = *GetPointer<u32>(process->GetPageTable().GetHeapVirtualAddress(phys_addr));
/* Read LR. */
uintptr_t lr_ptr = (e_ctx->x[13] <= stack_frame.fp && stack_frame.fp < e_ctx->x[13] + PageSize) ? fp + 4 : fp - 4;
if (R_FAILED(process->GetPageTable().QueryInfo(std::addressof(mem_info), std::addressof(page_info), lr_ptr))) {
break;
}
if ((mem_info.GetState() & KMemoryState_FlagReferenceCounted) == 0) {
break;
}
if ((mem_info.GetAttribute() & KMemoryAttribute_Uncached) != 0) {
break;
}
if ((mem_info.GetPermission() & KMemoryPermission_UserRead) != KMemoryPermission_UserRead) {
break;
}
if (!process->GetPageTable().GetPhysicalAddress(std::addressof(phys_addr), lr_ptr)) {
break;
}
if (!IsHeapPhysicalAddress(phys_addr)) {
break;
}
stack_frame.lr = *GetPointer<u32>(process->GetPageTable().GetHeapVirtualAddress(phys_addr));
}
/* Print and advance. */
PrintCodeAddress(process, stack_frame.lr);
fp = stack_frame.fp;
}
}
/* Resume the threads that we suspended. */
{
KScopedSchedulerLock sl;
auto end = process->GetThreadList().end();
for (auto it = process->GetThreadList().begin(); it != end; ++it) {
if (std::addressof(*it) != GetCurrentThreadPointer()) {
it->Resume(KThread::SuspendType_Backtrace);
}
}
}
}
}
#else
MESOSPHERE_UNUSED(thread);
#endif
}
}

View File

@@ -431,28 +431,5 @@ namespace ams::kern::arch::arm64 {
}
}
size_t KPageTableImpl::CountPageTables() const {
size_t num_tables = 0;
#if defined(MESOSPHERE_BUILD_FOR_DEBUGGING)
{
++num_tables;
for (size_t l1_index = 0; l1_index < this->num_entries; ++l1_index) {
auto &l1_entry = this->table[l1_index];
if (l1_entry.IsTable()) {
++num_tables;
for (size_t l2_index = 0; l2_index < MaxPageTableEntries; ++l2_index) {
auto *l2_entry = GetPointer<L2PageTableEntry>(GetTableEntry(KMemoryLayout::GetLinearVirtualAddress(l1_entry.GetTable()), l2_index));
if (l2_entry->IsTable()) {
++num_tables;
}
}
}
}
}
#endif
return num_tables;
}
}

View File

@@ -51,7 +51,7 @@ namespace ams::kern::arch::arm64 {
cpu::InstructionMemoryBarrier();
}
uintptr_t SetupStackForUserModeThreadStarter(KVirtualAddress pc, KVirtualAddress k_sp, KVirtualAddress u_sp, uintptr_t arg, const bool is_64_bit) {
uintptr_t SetupStackForUserModeThreadStarter(KVirtualAddress pc, KVirtualAddress k_sp, KVirtualAddress u_sp, uintptr_t arg, bool is_64_bit) {
/* NOTE: Stack layout on entry looks like following: */
/* SP */
/* | */
@@ -76,11 +76,6 @@ namespace ams::kern::arch::arm64 {
MESOSPHERE_LOG("Creating User 32-Thread, %016lx\n", GetInteger(pc));
}
/* Set CFI-value. */
if (is_64_bit) {
ctx->x[18] = KSystemControl::GenerateRandomU64() | 1;
}
/* Set stack pointer. */
if (is_64_bit) {
ctx->sp = GetInteger(u_sp);

View File

@@ -409,15 +409,6 @@ namespace ams::kern::board::nintendo::nx {
return MinimumSize;
}
u8 KSystemControl::Init::GetDebugLogUartPort() {
/* Get the log configuration. */
u64 value = 0;
smc::init::GetConfig(std::addressof(value), 1, smc::ConfigItem::ExosphereLogConfiguration);
/* Extract the port. */
return static_cast<u8>((value >> 32) & 0xFF);
}
void KSystemControl::Init::CpuOn(u64 core_id, uintptr_t entrypoint, uintptr_t arg) {
smc::init::CpuOn(core_id, entrypoint, arg);
}
@@ -567,7 +558,7 @@ namespace ams::kern::board::nintendo::nx {
/* NOTE: Atmosphere extension; if we received an exception context from Panic(), */
/* generate a fatal error report using it. */
const KExceptionContext *e_ctx = static_cast<const KExceptionContext *>(arg);
auto *f_ctx = GetPointer<::ams::impl::FatalErrorContext>(iram_address + 0x2E000);
auto *f_ctx = GetPointer<::ams::impl::FatalErrorContext>(iram_address + RebootPayloadSize);
/* Clear the fatal context. */
std::memset(f_ctx, 0xCC, sizeof(*f_ctx));

View File

@@ -55,16 +55,15 @@ namespace ams::kern::board::nintendo::nx::smc {
Package2Hash = 17,
/* Extension config items for exosphere. */
ExosphereApiVersion = 65000,
ExosphereNeedsReboot = 65001,
ExosphereNeedsShutdown = 65002,
ExosphereGitCommitHash = 65003,
ExosphereHasRcmBugPatch = 65004,
ExosphereBlankProdInfo = 65005,
ExosphereAllowCalWrites = 65006,
ExosphereEmummcType = 65007,
ExospherePayloadAddress = 65008,
ExosphereLogConfiguration = 65009,
ExosphereApiVersion = 65000,
ExosphereNeedsReboot = 65001,
ExosphereNeedsShutdown = 65002,
ExosphereGitCommitHash = 65003,
ExosphereHasRcmBugPatch = 65004,
ExosphereBlankProdInfo = 65005,
ExosphereAllowCalWrites = 65006,
ExosphereEmummcType = 65007,
ExospherePayloadAddress = 65008,
};
enum class SmcResult {

View File

@@ -22,7 +22,7 @@ namespace ams::kern::init {
#define FOREACH_SLAB_TYPE(HANDLER, ...) \
HANDLER(KProcess, (SLAB_COUNT(KProcess)), ## __VA_ARGS__) \
HANDLER(KThread, (SLAB_COUNT(KThread)), ## __VA_ARGS__) \
HANDLER(KLinkedListNode, (SLAB_COUNT(KThread)), ## __VA_ARGS__) \
HANDLER(KLinkedListNode, (SLAB_COUNT(KThread) * 17), ## __VA_ARGS__) \
HANDLER(KEvent, (SLAB_COUNT(KEvent)), ## __VA_ARGS__) \
HANDLER(KInterruptEvent, (SLAB_COUNT(KInterruptEvent)), ## __VA_ARGS__) \
HANDLER(KInterruptEventTask, (SLAB_COUNT(KInterruptEvent)), ## __VA_ARGS__) \
@@ -77,7 +77,7 @@ namespace ams::kern::init {
namespace test {
constexpr size_t RequiredSizeForExtraThreadCount = SlabCountExtraKThread * (sizeof(KThread) + sizeof(KLinkedListNode) + (sizeof(KThreadLocalPage) / 8) + sizeof(KEventInfo));
constexpr size_t RequiredSizeForExtraThreadCount = SlabCountExtraKThread * (sizeof(KThread) + (sizeof(KLinkedListNode) * 17) + (sizeof(KThreadLocalPage) / 8) + sizeof(KEventInfo));
static_assert(RequiredSizeForExtraThreadCount <= KernelSlabHeapAdditionalSize);
}

View File

@@ -18,12 +18,10 @@
namespace ams::kern {
#if defined(MESOSPHERE_DEBUG_LOG_USE_UART)
#if defined(MESOSPHERE_DEBUG_LOG_USE_UART_A) || defined(MESOSPHERE_DEBUG_LOG_USE_UART_B) || defined(MESOSPHERE_DEBUG_LOG_USE_UART_C) || defined(MESOSPHERE_DEBUG_LOG_USE_UART_D)
namespace {
constexpr bool DoSaveAndRestore = false;
enum UartRegister {
UartRegister_THR = 0,
UartRegister_IER = 1,
@@ -40,13 +38,13 @@ namespace ams::kern {
KVirtualAddress g_uart_address = 0;
[[maybe_unused]] constinit u32 g_saved_registers[5];
constinit u32 g_saved_registers[5];
ALWAYS_INLINE u32 ReadUartRegister(UartRegister which) {
NOINLINE u32 ReadUartRegister(UartRegister which) {
return GetPointer<volatile u32>(g_uart_address)[which];
}
ALWAYS_INLINE void WriteUartRegister(UartRegister which, u32 value) {
NOINLINE void WriteUartRegister(UartRegister which, u32 value) {
GetPointer<volatile u32>(g_uart_address)[which] = value;
}
@@ -88,47 +86,43 @@ namespace ams::kern {
}
void KDebugLogImpl::Save() {
if constexpr (DoSaveAndRestore) {
/* Save LCR, IER, FCR. */
g_saved_registers[0] = ReadUartRegister(UartRegister_LCR);
g_saved_registers[1] = ReadUartRegister(UartRegister_IER);
g_saved_registers[2] = ReadUartRegister(UartRegister_FCR);
/* Save LCR, IER, FCR. */
g_saved_registers[0] = ReadUartRegister(UartRegister_LCR);
g_saved_registers[1] = ReadUartRegister(UartRegister_IER);
g_saved_registers[2] = ReadUartRegister(UartRegister_FCR);
/* Set Divisor Latch Access bit, to allow access to DLL/DLH */
WriteUartRegister(UartRegister_LCR, 0x80);
ReadUartRegister(UartRegister_LCR);
/* Set Divisor Latch Access bit, to allow access to DLL/DLH */
WriteUartRegister(UartRegister_LCR, 0x80);
ReadUartRegister(UartRegister_LCR);
/* Save DLL/DLH. */
g_saved_registers[3] = ReadUartRegister(UartRegister_DLL);
g_saved_registers[4] = ReadUartRegister(UartRegister_DLH);
/* Save DLL/DLH. */
g_saved_registers[3] = ReadUartRegister(UartRegister_DLL);
g_saved_registers[4] = ReadUartRegister(UartRegister_DLH);
/* Restore Divisor Latch Access bit. */
WriteUartRegister(UartRegister_LCR, g_saved_registers[0]);
ReadUartRegister(UartRegister_LCR);
}
/* Restore Divisor Latch Access bit. */
WriteUartRegister(UartRegister_LCR, g_saved_registers[0]);
ReadUartRegister(UartRegister_LCR);
}
void KDebugLogImpl::Restore() {
if constexpr (DoSaveAndRestore) {
/* Set Divisor Latch Access bit, to allow access to DLL/DLH */
WriteUartRegister(UartRegister_LCR, 0x80);
ReadUartRegister(UartRegister_LCR);
/* Set Divisor Latch Access bit, to allow access to DLL/DLH */
WriteUartRegister(UartRegister_LCR, 0x80);
ReadUartRegister(UartRegister_LCR);
/* Restore DLL/DLH. */
WriteUartRegister(UartRegister_DLL, g_saved_registers[3]);
WriteUartRegister(UartRegister_DLH, g_saved_registers[4]);
ReadUartRegister(UartRegister_DLH);
/* Restore DLL/DLH. */
WriteUartRegister(UartRegister_DLL, g_saved_registers[3]);
WriteUartRegister(UartRegister_DLH, g_saved_registers[4]);
ReadUartRegister(UartRegister_DLH);
/* Restore Divisor Latch Access bit. */
WriteUartRegister(UartRegister_LCR, g_saved_registers[0]);
ReadUartRegister(UartRegister_LCR);
/* Restore Divisor Latch Access bit. */
WriteUartRegister(UartRegister_LCR, g_saved_registers[0]);
ReadUartRegister(UartRegister_LCR);
/* Restore IER and FCR. */
WriteUartRegister(UartRegister_IER, g_saved_registers[1]);
WriteUartRegister(UartRegister_FCR, g_saved_registers[2] | 2);
WriteUartRegister(UartRegister_IRDA_CSR, 0x02);
ReadUartRegister(UartRegister_FCR);
}
/* Restore IER and FCR. */
WriteUartRegister(UartRegister_IER, g_saved_registers[1]);
WriteUartRegister(UartRegister_FCR, g_saved_registers[2] | 2);
WriteUartRegister(UartRegister_IRDA_CSR, 0x02);
ReadUartRegister(UartRegister_FCR);
}
#elif defined(MESOSPHERE_DEBUG_LOG_USE_IRAM_RINGBUFFER)

View File

@@ -1,651 +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/>.
*/
#include <mesosphere.hpp>
namespace ams::kern::KDumpObject {
namespace {
constexpr const char * const ThreadStates[] = {
[KThread::ThreadState_Initialized] = "Initialized",
[KThread::ThreadState_Waiting] = "Waiting",
[KThread::ThreadState_Runnable] = "Runnable",
[KThread::ThreadState_Terminated] = "Terminated",
};
void DumpThread(KThread *thread) {
if (KProcess *process = thread->GetOwnerProcess(); process != nullptr) {
MESOSPHERE_RELEASE_LOG("Thread ID=%5lu pid=%3lu %-11s Pri=%2d %-11s KernelStack=%4zu/%4zu Run=%d Ideal=%d (%d) Affinity=%016lx (%016lx)\n",
thread->GetId(), process->GetId(), process->GetName(), thread->GetPriority(), ThreadStates[thread->GetState()],
thread->GetKernelStackUsage(), PageSize, thread->GetActiveCore(), thread->GetIdealVirtualCore(), thread->GetIdealPhysicalCore(),
thread->GetVirtualAffinityMask(), thread->GetAffinityMask().GetAffinityMask());
MESOSPHERE_RELEASE_LOG(" State: 0x%04x Suspend: 0x%04x Dpc: 0x%x\n", thread->GetRawState(), thread->GetSuspendFlags(), thread->GetDpc());
MESOSPHERE_RELEASE_LOG(" TLS: %p (%p)\n", GetVoidPointer(thread->GetThreadLocalRegionAddress()), thread->GetThreadLocalRegionHeapAddress());
} else {
MESOSPHERE_RELEASE_LOG("Thread ID=%5lu pid=%3d %-11s Pri=%2d %-11s KernelStack=%4zu/%4zu Run=%d Ideal=%d (%d) Affinity=%016lx (%016lx)\n",
thread->GetId(), -1, "(kernel)", thread->GetPriority(), ThreadStates[thread->GetState()],
thread->GetKernelStackUsage(), PageSize, thread->GetActiveCore(), thread->GetIdealVirtualCore(), thread->GetIdealPhysicalCore(),
thread->GetVirtualAffinityMask(), thread->GetAffinityMask().GetAffinityMask());
}
}
void DumpThreadCallStack(KThread *thread) {
if (KProcess *process = thread->GetOwnerProcess(); process != nullptr) {
MESOSPHERE_RELEASE_LOG("Thread ID=%5lu pid=%3lu %-11s Pri=%2d %-11s KernelStack=%4zu/%4zu\n",
thread->GetId(), process->GetId(), process->GetName(), thread->GetPriority(), ThreadStates[thread->GetState()], thread->GetKernelStackUsage(), PageSize);
KDebug::PrintRegister(thread);
KDebug::PrintBacktrace(thread);
} else {
MESOSPHERE_RELEASE_LOG("Thread ID=%5lu pid=%3d %-11s Pri=%2d %-11s KernelStack=%4zu/%4zu\n",
thread->GetId(), -1, "(kernel)", thread->GetPriority(), ThreadStates[thread->GetState()], thread->GetKernelStackUsage(), PageSize);
}
}
void DumpHandle(const KProcess::ListAccessor &accessor, KProcess *process) {
MESOSPHERE_RELEASE_LOG("Process ID=%lu (%s)\n", process->GetId(), process->GetName());
const auto end = accessor.end();
const auto &handle_table = process->GetHandleTable();
const size_t max_handles = handle_table.GetMaxCount();
for (size_t i = 0; i < max_handles; ++i) {
/* Get the object + handle. */
ams::svc::Handle handle = ams::svc::InvalidHandle;
KScopedAutoObject obj = handle_table.GetObjectByIndex(std::addressof(handle), i);
if (obj.IsNotNull()) {
if (auto *target = obj->DynamicCast<KServerSession *>(); target != nullptr) {
MESOSPHERE_RELEASE_LOG("Handle %08x Obj=%p Ref=%d Type=%s Client=%p\n", handle, obj.GetPointerUnsafe(), obj->GetReferenceCount() - 1, obj->GetTypeName(), std::addressof(target->GetParent()->GetClientSession()));
target->Dump();
} else if (auto *target = obj->DynamicCast<KClientSession *>(); target != nullptr) {
MESOSPHERE_RELEASE_LOG("Handle %08x Obj=%p Ref=%d Type=%s Server=%p\n", handle, obj.GetPointerUnsafe(), obj->GetReferenceCount() - 1, obj->GetTypeName(), std::addressof(target->GetParent()->GetServerSession()));
} else if (auto *target = obj->DynamicCast<KThread *>(); target != nullptr) {
KProcess *target_owner = target->GetOwnerProcess();
const s32 owner_pid = target_owner != nullptr ? static_cast<s32>(target_owner->GetId()) : -1;
MESOSPHERE_RELEASE_LOG("Handle %08x Obj=%p Ref=%d Type=%s ID=%d PID=%d\n", handle, obj.GetPointerUnsafe(), obj->GetReferenceCount() - 1, obj->GetTypeName(), static_cast<s32>(target->GetId()), owner_pid);
} else if (auto *target = obj->DynamicCast<KProcess *>(); target != nullptr) {
MESOSPHERE_RELEASE_LOG("Handle %08x Obj=%p Ref=%d Type=%s ID=%d\n", handle, obj.GetPointerUnsafe(), obj->GetReferenceCount() - 1, obj->GetTypeName(), static_cast<s32>(target->GetId()));
} else if (auto *target = obj->DynamicCast<KSharedMemory *>(); target != nullptr) {
/* Find the owner. */
KProcess *target_owner = nullptr;
for (auto it = accessor.begin(); it != end; ++it) {
if (static_cast<KProcess *>(std::addressof(*it))->GetId() == target->GetOwnerProcessId()) {
target_owner = static_cast<KProcess *>(std::addressof(*it));
break;
}
}
MESOSPHERE_ASSERT(target_owner != nullptr);
MESOSPHERE_RELEASE_LOG("Handle %08x Obj=%p Ref=%d Type=%s Size=%zu KB OwnerPID=%d (%s)\n", handle, obj.GetPointerUnsafe(), obj->GetReferenceCount() - 1, obj->GetTypeName(), target->GetSize() / 1_KB, static_cast<s32>(target_owner->GetId()), target_owner->GetName());
} else if (auto *target = obj->DynamicCast<KTransferMemory *>(); target != nullptr) {
KProcess *target_owner = target->GetOwner();
MESOSPHERE_RELEASE_LOG("Handle %08x Obj=%p Ref=%d Type=%s OwnerPID=%d (%s) OwnerAddress=%lx Size=%zu KB\n", handle, obj.GetPointerUnsafe(), obj->GetReferenceCount() - 1, obj->GetTypeName(), static_cast<s32>(target_owner->GetId()), target_owner->GetName(), GetInteger(target->GetSourceAddress()), target->GetSize() / 1_KB);
} else if (auto *target = obj->DynamicCast<KCodeMemory *>(); target != nullptr) {
KProcess *target_owner = target->GetOwner();
MESOSPHERE_RELEASE_LOG("Handle %08x Obj=%p Ref=%d Type=%s OwnerPID=%d (%s) OwnerAddress=%lx Size=%zu KB\n", handle, obj.GetPointerUnsafe(), obj->GetReferenceCount() - 1, obj->GetTypeName(), static_cast<s32>(target_owner->GetId()), target_owner->GetName(), GetInteger(target->GetSourceAddress()), target->GetSize() / 1_KB);
} else if (auto *target = obj->DynamicCast<KInterruptEvent *>(); target != nullptr) {
MESOSPHERE_RELEASE_LOG("Handle %08x Obj=%p Ref=%d Type=%s irq=%d\n", handle, obj.GetPointerUnsafe(), obj->GetReferenceCount() - 1, obj->GetTypeName(), target->GetInterruptId());
} else if (auto *target = obj->DynamicCast<KWritableEvent *>(); target != nullptr) {
if (KEvent *event = target->GetParent(); event != nullptr) {
MESOSPHERE_RELEASE_LOG("Handle %08x Obj=%p Ref=%d Type=%s Pair=%p\n", handle, obj.GetPointerUnsafe(), obj->GetReferenceCount() - 1, obj->GetTypeName(), std::addressof(event->GetReadableEvent()));
} else {
MESOSPHERE_RELEASE_LOG("Handle %08x Obj=%p Ref=%d Type=%s\n", handle, obj.GetPointerUnsafe(), obj->GetReferenceCount() - 1, obj->GetTypeName());
}
} else if (auto *target = obj->DynamicCast<KReadableEvent *>(); target != nullptr) {
if (KEvent *event = target->GetParent(); event != nullptr) {
MESOSPHERE_RELEASE_LOG("Handle %08x Obj=%p Ref=%d Type=%s Pair=%p\n", handle, obj.GetPointerUnsafe(), obj->GetReferenceCount() - 1, obj->GetTypeName(), std::addressof(event->GetWritableEvent()));
} else {
MESOSPHERE_RELEASE_LOG("Handle %08x Obj=%p Ref=%d Type=%s\n", handle, obj.GetPointerUnsafe(), obj->GetReferenceCount() - 1, obj->GetTypeName());
}
} else {
MESOSPHERE_RELEASE_LOG("Handle %08x Obj=%p Ref=%d Type=%s\n", handle, obj.GetPointerUnsafe(), obj->GetReferenceCount() - 1, obj->GetTypeName());
}
if (auto *sync = obj->DynamicCast<KSynchronizationObject *>(); sync != nullptr) {
sync->DumpWaiters();
}
}
}
MESOSPHERE_RELEASE_LOG("%zu(max %zu)/%zu used.\n", handle_table.GetCount(), max_handles, handle_table.GetTableSize());
MESOSPHERE_RELEASE_LOG("\n\n");
}
void DumpMemory(KProcess *process) {
const auto process_id = process->GetId();
MESOSPHERE_RELEASE_LOG("Process ID=%3lu (%s)\n", process_id, process->GetName());
/* Dump the memory blocks. */
process->GetPageTable().DumpMemoryBlocks();
/* Collect information about memory totals. */
const size_t code = process->GetPageTable().GetCodeSize();
const size_t code_data = process->GetPageTable().GetCodeDataSize();
const size_t alias_code = process->GetPageTable().GetAliasCodeSize();
const size_t alias_code_data = process->GetPageTable().GetAliasCodeDataSize();
const size_t normal = process->GetPageTable().GetNormalMemorySize();
const size_t main_stack = process->GetMainStackSize();
size_t shared = 0;
{
KSharedMemory::ListAccessor accessor;
const auto end = accessor.end();
for (auto it = accessor.begin(); it != end; ++it) {
KSharedMemory *shared_mem = static_cast<KSharedMemory *>(std::addressof(*it));
if (shared_mem->GetOwnerProcessId() == process_id) {
shared += shared_mem->GetSize();
}
}
}
/* Dump the totals. */
MESOSPHERE_RELEASE_LOG("---\n");
MESOSPHERE_RELEASE_LOG("Code %8zu KB\n", code / 1_KB);
MESOSPHERE_RELEASE_LOG("CodeData %8zu KB\n", code_data / 1_KB);
MESOSPHERE_RELEASE_LOG("AliasCode %8zu KB\n", alias_code / 1_KB);
MESOSPHERE_RELEASE_LOG("AliasCodeData %8zu KB\n", alias_code_data / 1_KB);
MESOSPHERE_RELEASE_LOG("Heap %8zu KB\n", normal / 1_KB);
MESOSPHERE_RELEASE_LOG("SharedMemory %8zu KB\n", shared / 1_KB);
MESOSPHERE_RELEASE_LOG("InitialStack %8zu KB\n", main_stack / 1_KB);
MESOSPHERE_RELEASE_LOG("---\n");
MESOSPHERE_RELEASE_LOG("TOTAL %8zu KB\n", (code + code_data + alias_code + alias_code_data + normal + main_stack + shared) / 1_KB);
MESOSPHERE_RELEASE_LOG("\n\n");
}
void DumpProcess(KProcess *process) {
MESOSPHERE_RELEASE_LOG("Process ID=%3lu index=%3zu State=%d (%s)\n", process->GetId(), process->GetSlabIndex(), process->GetState(), process->GetName());
}
void DumpPort(const KProcess::ListAccessor &accessor, KProcess *process) {
MESOSPHERE_RELEASE_LOG("Dump Port Process ID=%lu (%s)\n", process->GetId(), process->GetName());
const auto end = accessor.end();
const auto &handle_table = process->GetHandleTable();
const size_t max_handles = handle_table.GetMaxCount();
for (size_t i = 0; i < max_handles; ++i) {
/* Get the object + handle. */
ams::svc::Handle handle = ams::svc::InvalidHandle;
KScopedAutoObject obj = handle_table.GetObjectByIndex(std::addressof(handle), i);
if (obj.IsNull()) {
continue;
}
/* Process the object as a port. */
if (auto *server = obj->DynamicCast<KServerPort *>(); server != nullptr) {
const KClientPort *client = std::addressof(server->GetParent()->GetClientPort());
const uintptr_t port_name = server->GetParent()->GetName();
/* Get the port name. */
char name[9] = {};
{
/* Find the client port process. */
KScopedAutoObject<KProcess> client_port_process;
{
for (auto it = accessor.begin(); it != end && client_port_process.IsNull(); ++it) {
KProcess *cur = static_cast<KProcess *>(std::addressof(*it));
for (size_t j = 0; j < cur->GetHandleTable().GetMaxCount(); ++j) {
ams::svc::Handle cur_h = ams::svc::InvalidHandle;
KScopedAutoObject cur_o = cur->GetHandleTable().GetObjectByIndex(std::addressof(cur_h), j);
if (cur_o.IsNotNull()) {
if (cur_o.GetPointerUnsafe() == client) {
client_port_process = cur;
break;
}
}
}
}
}
/* Read the port name. */
if (client_port_process.IsNotNull()) {
if (R_FAILED(client_port_process->GetPageTable().CopyMemoryFromLinearToKernel(KProcessAddress(name), 8, port_name, KMemoryState_None, KMemoryState_None, KMemoryPermission_UserRead, KMemoryAttribute_None, KMemoryAttribute_None))) {
std::memset(name, 0, sizeof(name));
}
for (size_t i = 0; i < 8 && name[i] != 0; i++) {
if (name[i] > 0x7F) {
std::memset(name, 0, sizeof(name));
break;
}
}
}
}
MESOSPHERE_RELEASE_LOG("%-9s: Handle %08x Obj=%p Cur=%3d Peak=%3d Max=%3d\n", name, handle, obj.GetPointerUnsafe(), client->GetNumSessions(), client->GetPeakSessions(), client->GetMaxSessions());
/* Identify any sessions. */
{
for (auto it = accessor.begin(); it != end; ++it) {
KProcess *cur = static_cast<KProcess *>(std::addressof(*it));
for (size_t j = 0; j < cur->GetHandleTable().GetMaxCount(); ++j) {
ams::svc::Handle cur_h = ams::svc::InvalidHandle;
KScopedAutoObject cur_o = cur->GetHandleTable().GetObjectByIndex(std::addressof(cur_h), j);
if (cur_o.IsNull()) {
continue;
}
if (auto *session = cur_o->DynamicCast<KClientSession *>(); session != nullptr && session->GetParent()->GetParent() == client) {
MESOSPHERE_RELEASE_LOG(" Client %p Server %p %-12s: PID=%3lu\n", session, std::addressof(session->GetParent()->GetServerSession()), cur->GetName(), cur->GetId());
}
}
}
}
}
}
}
}
void DumpThread() {
MESOSPHERE_RELEASE_LOG("Dump Thread\n");
{
/* Lock the list. */
KThread::ListAccessor accessor;
const auto end = accessor.end();
/* Dump each thread. */
for (auto it = accessor.begin(); it != end; ++it) {
DumpThread(static_cast<KThread *>(std::addressof(*it)));
}
}
MESOSPHERE_RELEASE_LOG("\n");
}
void DumpThread(u64 thread_id) {
MESOSPHERE_RELEASE_LOG("Dump Thread\n");
{
/* Find and dump the target thread. */
if (KThread *thread = KThread::GetThreadFromId(thread_id); thread != nullptr) {
ON_SCOPE_EXIT { thread->Close(); };
DumpThread(thread);
}
}
MESOSPHERE_RELEASE_LOG("\n");
}
void DumpThreadCallStack() {
MESOSPHERE_RELEASE_LOG("Dump Thread\n");
{
/* Lock the list. */
KThread::ListAccessor accessor;
const auto end = accessor.end();
/* Dump each thread. */
for (auto it = accessor.begin(); it != end; ++it) {
DumpThreadCallStack(static_cast<KThread *>(std::addressof(*it)));
}
}
MESOSPHERE_RELEASE_LOG("\n");
}
void DumpThreadCallStack(u64 thread_id) {
MESOSPHERE_RELEASE_LOG("Dump Thread\n");
{
/* Find and dump the target thread. */
if (KThread *thread = KThread::GetThreadFromId(thread_id); thread != nullptr) {
ON_SCOPE_EXIT { thread->Close(); };
DumpThreadCallStack(thread);
}
}
MESOSPHERE_RELEASE_LOG("\n");
}
void DumpKernelObject() {
MESOSPHERE_LOG("Dump Kernel Object\n");
{
/* Static slab heaps. */
{
#define DUMP_KSLABOBJ(__OBJECT__) \
MESOSPHERE_RELEASE_LOG(#__OBJECT__ "\n"); \
MESOSPHERE_RELEASE_LOG(" Cur=%3zu Peak=%3zu Max=%3zu\n", __OBJECT__::GetSlabHeapSize() - __OBJECT__::GetNumRemaining(), __OBJECT__::GetPeakIndex(), __OBJECT__::GetSlabHeapSize())
DUMP_KSLABOBJ(KPageBuffer);
DUMP_KSLABOBJ(KEvent);
DUMP_KSLABOBJ(KInterruptEvent);
DUMP_KSLABOBJ(KProcess);
DUMP_KSLABOBJ(KThread);
DUMP_KSLABOBJ(KPort);
DUMP_KSLABOBJ(KSharedMemory);
DUMP_KSLABOBJ(KTransferMemory);
DUMP_KSLABOBJ(KDeviceAddressSpace);
DUMP_KSLABOBJ(KDebug);
DUMP_KSLABOBJ(KSession);
DUMP_KSLABOBJ(KLightSession);
DUMP_KSLABOBJ(KLinkedListNode);
DUMP_KSLABOBJ(KThreadLocalPage);
DUMP_KSLABOBJ(KObjectName);
DUMP_KSLABOBJ(KEventInfo);
DUMP_KSLABOBJ(KSessionRequest);
DUMP_KSLABOBJ(KResourceLimit);
DUMP_KSLABOBJ(KAlpha);
DUMP_KSLABOBJ(KBeta);
#undef DUMP_KSLABOBJ
}
MESOSPHERE_RELEASE_LOG("\n");
/* Dynamic slab heaps. */
{
/* Memory block slabs. */
{
MESOSPHERE_RELEASE_LOG("App Memory Block\n");
auto &app = Kernel::GetApplicationMemoryBlockManager();
MESOSPHERE_RELEASE_LOG(" Cur=%6zu Peak=%6zu Max=%6zu\n", app.GetUsed(), app.GetPeak(), app.GetCount());
MESOSPHERE_RELEASE_LOG("Sys Memory Block\n");
auto &sys = Kernel::GetSystemMemoryBlockManager();
MESOSPHERE_RELEASE_LOG(" Cur=%6zu Peak=%6zu Max=%6zu\n", sys.GetUsed(), sys.GetPeak(), sys.GetCount());
}
/* KBlockInfo slab. */
{
MESOSPHERE_RELEASE_LOG("KBlockInfo\n");
auto &manager = Kernel::GetBlockInfoManager();
MESOSPHERE_RELEASE_LOG(" Cur=%6zu Peak=%6zu Max=%6zu\n", manager.GetUsed(), manager.GetPeak(), manager.GetCount());
}
/* Page Table slab. */
{
MESOSPHERE_RELEASE_LOG("Page Table\n");
auto &manager = Kernel::GetPageTableManager();
MESOSPHERE_RELEASE_LOG(" Cur=%6zu Peak=%6zu Max=%6zu\n", manager.GetUsed(), manager.GetPeak(), manager.GetCount());
}
}
MESOSPHERE_RELEASE_LOG("\n");
/* Process resources. */
{
KProcess::ListAccessor accessor;
size_t process_pts = 0;
const auto end = accessor.end();
for (auto it = accessor.begin(); it != end; ++it) {
KProcess *process = static_cast<KProcess *>(std::addressof(*it));
/* Count the number of threads. */
int threads = 0;
{
KThread::ListAccessor thr_accessor;
const auto thr_end = thr_accessor.end();
for (auto thr_it = thr_accessor.begin(); thr_it != thr_end; ++thr_it) {
KThread *thread = static_cast<KThread *>(std::addressof(*thr_it));
if (thread->GetOwnerProcess() == process) {
++threads;
}
}
}
/* Count the number of events. */
int events = 0;
{
KEvent::ListAccessor ev_accessor;
const auto ev_end = ev_accessor.end();
for (auto ev_it = ev_accessor.begin(); ev_it != ev_end; ++ev_it) {
KEvent *event = static_cast<KEvent *>(std::addressof(*ev_it));
if (event->GetOwner() == process) {
++events;
}
}
}
size_t pts = process->GetPageTable().CountPageTables();
process_pts += pts;
MESOSPHERE_RELEASE_LOG("%-12s: PID=%3lu Thread %4d / Event %4d / PageTable %5zu\n", process->GetName(), process->GetId(), threads, events, pts);
if (process->GetTotalSystemResourceSize() != 0) {
MESOSPHERE_RELEASE_LOG(" System Resource\n");
MESOSPHERE_RELEASE_LOG(" Cur=%6zu Peak=%6zu Max=%6zu\n", process->GetDynamicPageManager().GetUsed(), process->GetDynamicPageManager().GetPeak(), process->GetDynamicPageManager().GetCount());
MESOSPHERE_RELEASE_LOG(" Memory Block\n");
MESOSPHERE_RELEASE_LOG(" Cur=%6zu Peak=%6zu Max=%6zu\n", process->GetMemoryBlockSlabManager().GetUsed(), process->GetMemoryBlockSlabManager().GetPeak(), process->GetMemoryBlockSlabManager().GetCount());
MESOSPHERE_RELEASE_LOG(" Page Table\n");
MESOSPHERE_RELEASE_LOG(" Cur=%6zu Peak=%6zu Max=%6zu\n", process->GetPageTableManager().GetUsed(), process->GetPageTableManager().GetPeak(), process->GetPageTableManager().GetCount());
MESOSPHERE_RELEASE_LOG(" Block Info\n");
MESOSPHERE_RELEASE_LOG(" Cur=%6zu Peak=%6zu Max=%6zu\n", process->GetBlockInfoManager().GetUsed(), process->GetBlockInfoManager().GetPeak(), process->GetBlockInfoManager().GetCount());
}
}
MESOSPHERE_RELEASE_LOG("Process Page Table %zu\n", process_pts);
MESOSPHERE_RELEASE_LOG("Kernel Page Table %zu\n", Kernel::GetKernelPageTable().CountPageTables());
}
MESOSPHERE_RELEASE_LOG("\n");
/* Resource limits. */
{
auto &sys_rl = Kernel::GetSystemResourceLimit();
u64 cur = sys_rl.GetCurrentValue(ams::svc::LimitableResource_PhysicalMemoryMax);
u64 lim = sys_rl.GetLimitValue(ams::svc::LimitableResource_PhysicalMemoryMax);
MESOSPHERE_RELEASE_LOG("System ResourceLimit PhysicalMemory 0x%01x_%08x / 0x%01x_%08x\n", static_cast<u32>(cur >> 32), static_cast<u32>(cur), static_cast<u32>(lim >> 32), static_cast<u32>(lim));
cur = sys_rl.GetCurrentValue(ams::svc::LimitableResource_ThreadCountMax);
lim = sys_rl.GetLimitValue(ams::svc::LimitableResource_ThreadCountMax);
MESOSPHERE_RELEASE_LOG("System ResourceLimit Thread %4lu / %4lu\n", cur, lim);
cur = sys_rl.GetCurrentValue(ams::svc::LimitableResource_EventCountMax);
lim = sys_rl.GetLimitValue(ams::svc::LimitableResource_EventCountMax);
MESOSPHERE_RELEASE_LOG("System ResourceLimit Event %4lu / %4lu\n", cur, lim);
cur = sys_rl.GetCurrentValue(ams::svc::LimitableResource_TransferMemoryCountMax);
lim = sys_rl.GetLimitValue(ams::svc::LimitableResource_TransferMemoryCountMax);
MESOSPHERE_RELEASE_LOG("System ResourceLimit TransferMemory %4lu / %4lu\n", cur, lim);
cur = sys_rl.GetCurrentValue(ams::svc::LimitableResource_SessionCountMax);
lim = sys_rl.GetLimitValue(ams::svc::LimitableResource_SessionCountMax);
MESOSPHERE_RELEASE_LOG("System ResourceLimit Session %4lu / %4lu\n", cur, lim);
{
KResourceLimit::ListAccessor accessor;
const auto end = accessor.end();
for (auto it = accessor.begin(); it != end; ++it) {
KResourceLimit *rl = static_cast<KResourceLimit *>(std::addressof(*it));
cur = rl->GetCurrentValue(ams::svc::LimitableResource_PhysicalMemoryMax);
lim = rl->GetLimitValue(ams::svc::LimitableResource_PhysicalMemoryMax);
MESOSPHERE_RELEASE_LOG("ResourceLimit %zu PhysicalMemory 0x%01x_%08x / 0x%01x_%08x\n", rl->GetSlabIndex(), static_cast<u32>(cur >> 32), static_cast<u32>(cur), static_cast<u32>(lim >> 32), static_cast<u32>(lim));
}
}
}
MESOSPHERE_RELEASE_LOG("\n");
/* Memory Manager. */
{
auto &mm = Kernel::GetMemoryManager();
u64 max = mm.GetSize();
u64 cur = max - mm.GetFreeSize();
MESOSPHERE_RELEASE_LOG("Kernel Heap Size 0x%01x_%08x / 0x%01x_%08x\n", static_cast<u32>(cur >> 32), static_cast<u32>(cur), static_cast<u32>(max >> 32), static_cast<u32>(max));
MESOSPHERE_RELEASE_LOG("\n");
max = mm.GetSize(KMemoryManager::Pool_Application);
cur = max - mm.GetFreeSize(KMemoryManager::Pool_Application);
MESOSPHERE_RELEASE_LOG("Application 0x%01x_%08x / 0x%01x_%08x\n", static_cast<u32>(cur >> 32), static_cast<u32>(cur), static_cast<u32>(max >> 32), static_cast<u32>(max));
mm.DumpFreeList(KMemoryManager::Pool_Application);
MESOSPHERE_RELEASE_LOG("\n");
max = mm.GetSize(KMemoryManager::Pool_Applet);
cur = max - mm.GetFreeSize(KMemoryManager::Pool_Applet);
MESOSPHERE_RELEASE_LOG("Applet 0x%01x_%08x / 0x%01x_%08x\n", static_cast<u32>(cur >> 32), static_cast<u32>(cur), static_cast<u32>(max >> 32), static_cast<u32>(max));
mm.DumpFreeList(KMemoryManager::Pool_Applet);
MESOSPHERE_RELEASE_LOG("\n");
max = mm.GetSize(KMemoryManager::Pool_System);
cur = max - mm.GetFreeSize(KMemoryManager::Pool_System);
MESOSPHERE_RELEASE_LOG("System 0x%01x_%08x / 0x%01x_%08x\n", static_cast<u32>(cur >> 32), static_cast<u32>(cur), static_cast<u32>(max >> 32), static_cast<u32>(max));
mm.DumpFreeList(KMemoryManager::Pool_System);
MESOSPHERE_RELEASE_LOG("\n");
max = mm.GetSize(KMemoryManager::Pool_SystemNonSecure);
cur = max - mm.GetFreeSize(KMemoryManager::Pool_SystemNonSecure);
MESOSPHERE_RELEASE_LOG("SystemNonSecure 0x%01x_%08x / 0x%01x_%08x\n", static_cast<u32>(cur >> 32), static_cast<u32>(cur), static_cast<u32>(max >> 32), static_cast<u32>(max));
mm.DumpFreeList(KMemoryManager::Pool_SystemNonSecure);
MESOSPHERE_RELEASE_LOG("\n");
}
MESOSPHERE_RELEASE_LOG("\n");
}
MESOSPHERE_RELEASE_LOG("\n");
}
void DumpHandle() {
MESOSPHERE_RELEASE_LOG("Dump Handle\n");
{
/* Lock the list. */
KProcess::ListAccessor accessor;
const auto end = accessor.end();
/* Dump each process. */
for (auto it = accessor.begin(); it != end; ++it) {
DumpHandle(accessor, static_cast<KProcess *>(std::addressof(*it)));
}
}
MESOSPHERE_RELEASE_LOG("\n");
}
void DumpHandle(u64 process_id) {
MESOSPHERE_RELEASE_LOG("Dump Handle\n");
{
/* Find and dump the target process. */
if (KProcess *process = KProcess::GetProcessFromId(process_id); process != nullptr) {
ON_SCOPE_EXIT { process->Close(); };
/* Lock the list. */
KProcess::ListAccessor accessor;
DumpHandle(accessor, process);
}
}
MESOSPHERE_RELEASE_LOG("\n");
}
void DumpKernelMemory() {
MESOSPHERE_RELEASE_LOG("Dump Kernel Memory Info\n");
{
Kernel::GetKernelPageTable().DumpMemoryBlocks();
}
MESOSPHERE_RELEASE_LOG("\n");
}
void DumpMemory() {
MESOSPHERE_RELEASE_LOG("Dump Memory Info\n");
{
/* Lock the list. */
KProcess::ListAccessor accessor;
const auto end = accessor.end();
/* Dump each process. */
for (auto it = accessor.begin(); it != end; ++it) {
DumpMemory(static_cast<KProcess *>(std::addressof(*it)));
}
}
MESOSPHERE_RELEASE_LOG("\n");
}
void DumpMemory(u64 process_id) {
MESOSPHERE_RELEASE_LOG("Dump Memory Info\n");
{
/* Find and dump the target process. */
if (KProcess *process = KProcess::GetProcessFromId(process_id); process != nullptr) {
ON_SCOPE_EXIT { process->Close(); };
DumpMemory(process);
}
}
MESOSPHERE_RELEASE_LOG("\n");
}
void DumpProcess() {
MESOSPHERE_RELEASE_LOG("Dump Process\n");
{
/* Lock the list. */
KProcess::ListAccessor accessor;
const auto end = accessor.end();
/* Dump each process. */
for (auto it = accessor.begin(); it != end; ++it) {
DumpProcess(static_cast<KProcess *>(std::addressof(*it)));
}
}
MESOSPHERE_RELEASE_LOG("\n");
}
void DumpProcess(u64 process_id) {
MESOSPHERE_RELEASE_LOG("Dump Process\n");
{
/* Find and dump the target process. */
if (KProcess *process = KProcess::GetProcessFromId(process_id); process != nullptr) {
ON_SCOPE_EXIT { process->Close(); };
DumpProcess(process);
}
}
MESOSPHERE_RELEASE_LOG("\n");
}
void DumpPort() {
MESOSPHERE_RELEASE_LOG("Dump Port\n");
{
/* Lock the list. */
KProcess::ListAccessor accessor;
const auto end = accessor.end();
/* Dump each process. */
for (auto it = accessor.begin(); it != end; ++it) {
DumpPort(accessor, static_cast<KProcess *>(std::addressof(*it)));
}
}
MESOSPHERE_RELEASE_LOG("\n");
}
void DumpPort(u64 process_id) {
MESOSPHERE_RELEASE_LOG("Dump Port\n");
{
/* Find and dump the target process. */
if (KProcess *process = KProcess::GetProcessFromId(process_id); process != nullptr) {
ON_SCOPE_EXIT { process->Close(); };
/* Lock the list. */
KProcess::ListAccessor accessor;
DumpPort(accessor, process);
}
}
MESOSPHERE_RELEASE_LOG("\n");
}
}

View File

@@ -70,10 +70,10 @@ namespace ams::kern {
}
void DumpMemoryInfo(const KMemoryInfo &info) {
const char *state = GetMemoryStateName(info.state);
const char *perm = GetMemoryPermissionString(info);
const uintptr_t start = info.GetAddress();
const uintptr_t end = info.GetLastAddress();
const char *state = GetMemoryStateName(info.state);
const char *perm = GetMemoryPermissionString(info);
const void *start = reinterpret_cast<void *>(info.GetAddress());
const void *end = reinterpret_cast<void *>(info.GetLastAddress());
const size_t kb = info.GetSize() / 1_KB;
const char l = (info.attribute & KMemoryAttribute_Locked) ? 'L' : '-';
@@ -81,7 +81,7 @@ namespace ams::kern {
const char d = (info.attribute & KMemoryAttribute_DeviceShared) ? 'D' : '-';
const char u = (info.attribute & KMemoryAttribute_Uncached) ? 'U' : '-';
MESOSPHERE_LOG("0x%10lx - 0x%10lx (%9zu KB) %s %s %c%c%c%c [%d, %d]\n", start, end, kb, perm, state, l, i, d, u, info.ipc_lock_count, info.device_use_count);
MESOSPHERE_LOG("%p - %p (%9zu KB) %s %s %c%c%c%c [%d, %d]\n", start, end, kb, perm, state, l, i, d, u, info.ipc_lock_count, info.device_use_count);
}
}

View File

@@ -26,14 +26,14 @@ namespace ams::kern {
constexpr size_t CarveoutSizeMax = 512_MB - CarveoutAlignment;
ALWAYS_INLINE bool SetupUartPhysicalMemoryRegion() {
#if defined(MESOSPHERE_DEBUG_LOG_USE_UART)
switch (KSystemControl::Init::GetDebugLogUartPort()) {
case 0: return KMemoryLayout::GetPhysicalMemoryRegionTree().Insert(0x70006000, 0x40, KMemoryRegionType_Uart | KMemoryRegionAttr_ShouldKernelMap);
case 1: return KMemoryLayout::GetPhysicalMemoryRegionTree().Insert(0x70006040, 0x40, KMemoryRegionType_Uart | KMemoryRegionAttr_ShouldKernelMap);
case 2: return KMemoryLayout::GetPhysicalMemoryRegionTree().Insert(0x70006200, 0x100, KMemoryRegionType_Uart | KMemoryRegionAttr_ShouldKernelMap);
case 3: return KMemoryLayout::GetPhysicalMemoryRegionTree().Insert(0x70006300, 0x100, KMemoryRegionType_Uart | KMemoryRegionAttr_ShouldKernelMap);
default: return false;
}
#if defined(MESOSPHERE_DEBUG_LOG_USE_UART_A)
return KMemoryLayout::GetPhysicalMemoryRegionTree().Insert(0x70006000, 0x40, KMemoryRegionType_Uart | KMemoryRegionAttr_ShouldKernelMap);
#elif defined(MESOSPHERE_DEBUG_LOG_USE_UART_B)
return KMemoryLayout::GetPhysicalMemoryRegionTree().Insert(0x70006040, 0x40, KMemoryRegionType_Uart | KMemoryRegionAttr_ShouldKernelMap);
#elif defined(MESOSPHERE_DEBUG_LOG_USE_UART_C)
return KMemoryLayout::GetPhysicalMemoryRegionTree().Insert(0x70006200, 0x100, KMemoryRegionType_Uart | KMemoryRegionAttr_ShouldKernelMap);
#elif defined(MESOSPHERE_DEBUG_LOG_USE_UART_D)
return KMemoryLayout::GetPhysicalMemoryRegionTree().Insert(0x70006300, 0x100, KMemoryRegionType_Uart | KMemoryRegionAttr_ShouldKernelMap);
#elif defined(MESOSPHERE_DEBUG_LOG_USE_IRAM_RINGBUFFER)
return true;
#else

View File

@@ -132,29 +132,4 @@ namespace ams::kern {
return util::AlignUp(overhead_size, PageSize);
}
void KPageHeap::DumpFreeList() const {
MESOSPHERE_RELEASE_LOG("KPageHeap::DumpFreeList %p\n", this);
for (size_t i = 0; i < this->num_blocks; ++i) {
const size_t block_size = this->blocks[i].GetSize();
const char *suffix;
size_t size;
if (block_size >= 1_GB) {
suffix = "GiB";
size = block_size / 1_GB;
} else if (block_size >= 1_MB) {
suffix = "MiB";
size = block_size / 1_MB;
} else if (block_size >= 1_KB) {
suffix = "KiB";
size = block_size / 1_KB;
} else {
suffix = "B";
size = block_size;
}
MESOSPHERE_RELEASE_LOG(" %4zu %s block x %zu\n", size, suffix, this->blocks[i].GetNumFreeBlocks());
}
}
}

View File

@@ -908,7 +908,7 @@ namespace ams::kern {
}
/* Check if we're done. */
if (dst_address + size - 1 <= info.GetLastAddress()) {
if (dst_address + size - 1 > info.GetLastAddress()) {
break;
}
@@ -1018,39 +1018,6 @@ namespace ams::kern {
return address;
}
size_t KPageTableBase::GetSize(KMemoryState state) const {
/* Lock the table. */
KScopedLightLock lk(this->general_lock);
/* Iterate, counting blocks with the desired state. */
size_t total_size = 0;
for (KMemoryBlockManager::const_iterator it = this->memory_block_manager.FindIterator(this->address_space_start); it != this->memory_block_manager.end(); ++it) {
/* Get the memory info. */
const KMemoryInfo info = it->GetMemoryInfo();
if (info.GetState() == state) {
total_size += info.GetSize();
}
}
return total_size;
}
size_t KPageTableBase::GetCodeSize() const {
return this->GetSize(KMemoryState_Code);
}
size_t KPageTableBase::GetCodeDataSize() const {
return this->GetSize(KMemoryState_CodeData);
}
size_t KPageTableBase::GetAliasCodeSize() const {
return this->GetSize(KMemoryState_AliasCode);
}
size_t KPageTableBase::GetAliasCodeDataSize() const {
return this->GetSize(KMemoryState_AliasCodeData);
}
Result KPageTableBase::AllocateAndMapPagesImpl(PageLinkedList *page_list, KProcessAddress address, size_t num_pages, KMemoryPermission perm) {
MESOSPHERE_ASSERT(this->IsLockedByCurrentThread());

View File

@@ -1367,36 +1367,4 @@ namespace ams::kern {
#pragma GCC pop_options
void KServerSession::Dump() {
MESOSPHERE_ASSERT_THIS();
KScopedLightLock lk(this->lock);
{
KScopedSchedulerLock sl;
MESOSPHERE_RELEASE_LOG("Dump Session %p\n", this);
/* Dump current request. */
bool has_request = false;
if (this->current_request != nullptr) {
KThread *thread = this->current_request->GetThread();
const s32 thread_id = thread != nullptr ? static_cast<s32>(thread->GetId()) : -1;
MESOSPHERE_RELEASE_LOG(" CurrentReq %p Thread=%p ID=%d\n", this->current_request, thread, thread_id);
has_request = true;
}
/* Dump all rqeuests in list. */
for (auto it = this->request_list.begin(); it != this->request_list.end(); ++it) {
KThread *thread = it->GetThread();
const s32 thread_id = thread != nullptr ? static_cast<s32>(thread->GetId()) : -1;
MESOSPHERE_RELEASE_LOG(" Req %p Thread=%p ID=%d\n", this->current_request, thread, thread_id);
has_request = true;
}
/* If we didn't have any requests, print so. */
if (!has_request) {
MESOSPHERE_RELEASE_LOG(" None\n");
}
}
}
}

View File

@@ -81,15 +81,8 @@ namespace ams::kern {
/* Add the waiters. */
for (auto i = 0; i < num_objects; ++i) {
thread_nodes[i].thread = thread;
thread_nodes[i].next = nullptr;
if (objects[i]->thread_list_tail == nullptr) {
objects[i]->thread_list_head = std::addressof(thread_nodes[i]);
} else {
objects[i]->thread_list_tail->next = std::addressof(thread_nodes[i]);
}
objects[i]->thread_list_tail = std::addressof(thread_nodes[i]);
thread_nodes[i].next = objects[i]->thread_list_root;
objects[i]->thread_list_root = std::addressof(thread_nodes[i]);
}
/* Mark the thread as waiting. */
@@ -118,22 +111,11 @@ namespace ams::kern {
for (auto i = 0; i < num_objects; ++i) {
/* Unlink the object from the list. */
ThreadListNode *prev_ptr = reinterpret_cast<ThreadListNode *>(std::addressof(objects[i]->thread_list_head));
ThreadListNode *prev_val = nullptr;
ThreadListNode *prev, *tail_prev;
do {
prev = prev_ptr;
prev_ptr = prev_ptr->next;
tail_prev = prev_val;
prev_val = prev_ptr;
} while (prev_ptr != std::addressof(thread_nodes[i]));
if (objects[i]->thread_list_tail == std::addressof(thread_nodes[i])) {
objects[i]->thread_list_tail = tail_prev;
ThreadListNode **link = std::addressof(objects[i]->thread_list_root);
while (*link != std::addressof(thread_nodes[i])) {
link = std::addressof((*link)->next);
}
prev->next = thread_nodes[i].next;
*link = thread_nodes[i].next;
if (objects[i] == synced_obj) {
sync_index = i;
@@ -157,7 +139,7 @@ namespace ams::kern {
}
/* Iterate over each thread. */
for (auto *cur_node = this->thread_list_head; cur_node != nullptr; cur_node = cur_node->next) {
for (auto *cur_node = this->thread_list_root; cur_node != nullptr; cur_node = cur_node->next) {
KThread *thread = cur_node->thread;
if (thread->GetState() == KThread::ThreadState_Waiting) {
thread->SetSyncedObject(this, result);
@@ -166,7 +148,7 @@ namespace ams::kern {
}
}
void KSynchronizationObject::DumpWaiters() {
void KSynchronizationObject::DebugWaiters() {
MESOSPHERE_ASSERT_THIS();
/* If debugging, dump the list of waiters. */
@@ -176,7 +158,8 @@ namespace ams::kern {
MESOSPHERE_RELEASE_LOG("Threads waiting on %p:\n", this);
for (auto *cur_node = this->thread_list_head; cur_node != nullptr; cur_node = cur_node->next) {
bool has_waiters = false;
for (auto *cur_node = this->thread_list_root; cur_node != nullptr; cur_node = cur_node->next) {
KThread *thread = cur_node->thread;
if (KProcess *process = thread->GetOwnerProcess(); process != nullptr) {
@@ -184,10 +167,12 @@ namespace ams::kern {
} else {
MESOSPHERE_RELEASE_LOG(" %p tid=%ld (Kernel)\n", thread, thread->GetId());
}
has_waiters = true;
}
/* If we didn't have any waiters, print so. */
if (this->thread_list_head != nullptr) {
if (!has_waiters) {
MESOSPHERE_RELEASE_LOG(" None\n");
}
}

View File

@@ -24,15 +24,6 @@ namespace ams::kern {
return KernelVirtualAddressSpaceBase <= key_uptr && key_uptr <= KernelVirtualAddressSpaceLast;
}
void InitializeKernelStack(uintptr_t stack_top) {
#if defined(MESOSPHERE_ENABLE_KERNEL_STACK_USAGE)
const uintptr_t stack_bottom = stack_top - PageSize;
std::memset(reinterpret_cast<void *>(stack_bottom), 0xCC, PageSize - sizeof(KThread::StackParameters));
#else
MESOSPHERE_UNUSED(stack_top);
#endif
}
void CleanupKernelStack(uintptr_t stack_top) {
const uintptr_t stack_bottom = stack_top - PageSize;
@@ -162,11 +153,6 @@ namespace ams::kern {
this->resource_limit_release_hint = 0;
this->cpu_time = 0;
/* Setup our kernel stack. */
if (type != ThreadType_Main) {
InitializeKernelStack(reinterpret_cast<uintptr_t>(kern_stack_top));
}
/* Clear our stack parameters. */
std::memset(static_cast<void *>(std::addressof(this->GetStackParameters())), 0, sizeof(StackParameters));
@@ -817,26 +803,6 @@ namespace ams::kern {
KScheduler::OnThreadStateChanged(this, old_state);
}
size_t KThread::GetKernelStackUsage() const {
MESOSPHERE_ASSERT_THIS();
MESOSPHERE_ASSERT(this->kernel_stack_top != nullptr);
#if defined(MESOSPHERE_ENABLE_KERNEL_STACK_USAGE)
const u8 *stack = static_cast<const u8 *>(this->kernel_stack_top) - PageSize;
size_t i;
for (i = 0; i < PageSize; ++i) {
if (stack[i] != 0xCC) {
break;
}
}
return PageSize - i;
#else
return 0;
#endif
}
Result KThread::SetActivity(ams::svc::ThreadActivity activity) {
/* Lock ourselves. */
KScopedLightLock lk(this->activity_pause_lock);

View File

@@ -97,20 +97,25 @@ namespace ams::kern {
/* Print the state. */
MESOSPHERE_RELEASE_LOG("Core[%d] Current State:\n", core_id);
/* Print registers and user backtrace. */
KDebug::PrintRegister();
KDebug::PrintBacktrace();
#ifdef ATMOSPHERE_ARCH_ARM64
/* Print kernel backtrace. */
MESOSPHERE_RELEASE_LOG("Backtrace:\n");
/* Print registers. */
if (core_ctx != nullptr) {
MESOSPHERE_RELEASE_LOG(" Registers:\n");
for (size_t i = 0; i < util::size(core_ctx->x); ++i) {
MESOSPHERE_RELEASE_LOG(" X[%02zx]: %p\n", i, reinterpret_cast<void *>(core_ctx->x[i]));
}
MESOSPHERE_RELEASE_LOG(" SP: %p\n", reinterpret_cast<void *>(core_ctx->x[30]));
}
/* Print backtrace. */
MESOSPHERE_RELEASE_LOG(" Backtrace:\n");
uintptr_t fp = core_ctx != nullptr ? core_ctx->x[29] : reinterpret_cast<uintptr_t>(__builtin_frame_address(0));
for (size_t i = 0; i < 32 && fp && util::IsAligned(fp, 0x10) && cpu::GetPhysicalAddressWritable(nullptr, fp, true); i++) {
struct {
uintptr_t fp;
uintptr_t lr;
} *stack_frame = reinterpret_cast<decltype(stack_frame)>(fp);
MESOSPHERE_RELEASE_LOG(" [%02zx]: %p\n", i, reinterpret_cast<void *>(stack_frame->lr));
MESOSPHERE_RELEASE_LOG(" [%02zx]: %p\n", i, reinterpret_cast<void *>(stack_frame->lr));
fp = stack_frame->fp;
}
#endif
@@ -132,7 +137,7 @@ namespace ams::kern {
}
NORETURN WEAK_SYMBOL void PanicImpl(const char *file, int line, const char *format, ...) {
NORETURN void PanicImpl(const char *file, int line, const char *format, ...) {
#ifdef MESOSPHERE_BUILD_FOR_DEBUGGING
/* Wait for it to be our turn to print. */
WaitCoreTicket();
@@ -153,7 +158,7 @@ namespace ams::kern {
StopSystem();
}
NORETURN WEAK_SYMBOL void PanicImpl() {
NORETURN void PanicImpl() {
StopSystem();
}

View File

@@ -21,18 +21,16 @@ namespace ams::kern::svc {
namespace {
#if defined(MESOSPHERE_BUILD_FOR_DEBUGGING)
void PrintBreak(ams::svc::BreakReason break_reason) {
[[maybe_unused]] void PrintBreak(ams::svc::BreakReason break_reason) {
/* Print that break was called. */
MESOSPHERE_RELEASE_LOG("%s: svc::Break(%d) was called, pid=%ld, tid=%ld\n", GetCurrentProcess().GetName(), static_cast<s32>(break_reason), GetCurrentProcess().GetId(), GetCurrentThread().GetId());
/* Print the current thread's registers. */
KDebug::PrintRegister();
/* TODO: KDebug::PrintRegisters(); */
/* Print a backtrace. */
KDebug::PrintBacktrace();
/* TODO: KDebug::PrintBacktrace(); */
}
#endif
void Break(ams::svc::BreakReason break_reason, uintptr_t address, size_t size) {
/* Determine whether the break is only a notification. */
@@ -40,7 +38,7 @@ namespace ams::kern::svc {
/* If the break isn't a notification, print it. */
if (!is_notification) {
#if defined(MESOSPHERE_BUILD_FOR_DEBUGGING)
#ifdef MESOSPHERE_BUILD_FOR_DEBUGGING
PrintBreak(break_reason);
#endif
}

View File

@@ -59,7 +59,6 @@ namespace ams::kern::svc {
case ams::svc::InfoType_TotalNonSystemMemorySize:
case ams::svc::InfoType_UsedNonSystemMemorySize:
case ams::svc::InfoType_IsApplication:
case ams::svc::InfoType_FreeThreadCount:
{
/* These info types don't support non-zero subtypes. */
R_UNLESS(info_subtype == 0, svc::ResultInvalidCombination());
@@ -126,15 +125,6 @@ namespace ams::kern::svc {
case ams::svc::InfoType_IsApplication:
*out = process->IsApplication();
break;
case ams::svc::InfoType_FreeThreadCount:
if (KResourceLimit *resource_limit = process->GetResourceLimit(); resource_limit != nullptr) {
const auto current_value = resource_limit->GetCurrentValue(ams::svc::LimitableResource_ThreadCountMax);
const auto limit_value = resource_limit->GetLimitValue(ams::svc::LimitableResource_ThreadCountMax);
*out = limit_value - current_value;
} else {
*out = 0;
}
break;
MESOSPHERE_UNREACHABLE_DEFAULT_CASE();
}
}

View File

@@ -22,85 +22,19 @@ namespace ams::kern::svc {
namespace {
void KernelDebug(ams::svc::KernelDebugType kern_debug_type, uint64_t arg0, uint64_t arg1, uint64_t arg2) {
MESOSPHERE_UNUSED(kern_debug_type, arg0, arg1, arg2);
#ifdef MESOSPHERE_BUILD_FOR_DEBUGGING
#ifdef ATMOSPHERE_BUILD_FOR_DEBUGGING
{
switch (kern_debug_type) {
case ams::svc::KernelDebugType_Thread:
if (arg0 == static_cast<u64>(-1)) {
KDumpObject::DumpThread();
} else {
KDumpObject::DumpThread(arg0);
}
break;
case ams::svc::KernelDebugType_ThreadCallStack:
if (arg0 == static_cast<u64>(-1)) {
KDumpObject::DumpThreadCallStack();
} else {
KDumpObject::DumpThreadCallStack(arg0);
}
break;
case ams::svc::KernelDebugType_KernelObject:
KDumpObject::DumpKernelObject();
break;
case ams::svc::KernelDebugType_Handle:
if (arg0 == static_cast<u64>(-1)) {
KDumpObject::DumpHandle();
} else {
KDumpObject::DumpHandle(arg0);
}
break;
case ams::svc::KernelDebugType_Memory:
if (arg0 == static_cast<u64>(-2)) {
KDumpObject::DumpKernelMemory();
} else if (arg0 == static_cast<u64>(-1)) {
KDumpObject::DumpMemory();
} else {
KDumpObject::DumpMemory(arg0);
}
break;
case ams::svc::KernelDebugType_Process:
if (arg0 == static_cast<u64>(-1)) {
KDumpObject::DumpProcess();
} else {
KDumpObject::DumpProcess(arg0);
}
break;
case ams::svc::KernelDebugType_SuspendProcess:
if (KProcess *process = KProcess::GetProcessFromId(arg0); process != nullptr) {
ON_SCOPE_EXIT { process->Close(); };
if (R_SUCCEEDED(process->SetActivity(ams::svc::ProcessActivity_Paused))) {
MESOSPHERE_RELEASE_LOG("Suspend Process ID=%3lu\n", process->GetId());
}
}
break;
case ams::svc::KernelDebugType_ResumeProcess:
if (KProcess *process = KProcess::GetProcessFromId(arg0); process != nullptr) {
ON_SCOPE_EXIT { process->Close(); };
if (R_SUCCEEDED(process->SetActivity(ams::svc::ProcessActivity_Runnable))) {
MESOSPHERE_RELEASE_LOG("Resume Process ID=%3lu\n", process->GetId());
}
}
break;
case ams::svc::KernelDebugType_Port:
if (arg0 == static_cast<u64>(-1)) {
KDumpObject::DumpPort();
} else {
KDumpObject::DumpPort(arg0);
}
break;
default:
break;
}
/* TODO: Implement Kernel Debugging. */
}
#else
{
MESOSPHERE_UNUSED(kern_debug_type, arg0, arg1, arg2);
}
#endif
}
void ChangeKernelTraceState(ams::svc::KernelTraceState kern_trace_state) {
#ifdef MESOSPHERE_BUILD_FOR_DEBUGGING
#ifdef ATMOSPHERE_BUILD_FOR_DEBUGGING
{
switch (kern_trace_state) {
case ams::svc::KernelTraceState_Enabled:

View File

@@ -164,10 +164,10 @@
HANDLER(UsbStateInfo, 123) \
HANDLER(NvHostErrInfo, 124) \
HANDLER(RunningUlaInfo, 125) \
HANDLER(InternalPanelInfo, 126) \
HANDLER(ResourceLimitLimitInfo, 127) \
HANDLER(ResourceLimitPeakInfo, 128) \
HANDLER(TouchScreenInfo, 129) \
HANDLER(Category_Unknown126, 126) \
HANDLER(Category_Unknown127, 127) \
HANDLER(Category_Unknown128, 128) \
HANDLER(Category_Unknown129, 129) \
#define AMS_ERPT_FOREACH_FIELD(HANDLER) \
HANDLER(TestU64, 0, Test, FieldType_NumericU64, FieldFlag_None ) \
@@ -782,22 +782,22 @@
HANDLER(NANDTotalSizeOfSystem, 609, NANDFreeSpaceInfo, FieldType_NumericU64, FieldFlag_None ) \
HANDLER(NANDFreeSpaceOfSystem, 610, NANDFreeSpaceInfo, FieldType_NumericU64, FieldFlag_None ) \
HANDLER(AccessPointSSIDAsHex, 611, AccessPointInfo, FieldType_String, FieldFlag_None ) \
HANDLER(PanelVendorId, 612, InternalPanelInfo, FieldType_NumericU8, FieldFlag_None ) \
HANDLER(PanelRevisionId, 613, InternalPanelInfo, FieldType_NumericU8, FieldFlag_None ) \
HANDLER(PanelModelId, 614, InternalPanelInfo, FieldType_NumericU8, FieldFlag_None ) \
HANDLER(PanelVendorId, 612, Category_Unknown126, FieldType_NumericU8, FieldFlag_None ) \
HANDLER(PanelRevisionId, 613, Category_Unknown126, FieldType_NumericU8, FieldFlag_None ) \
HANDLER(PanelModelId, 614, Category_Unknown126, FieldType_NumericU8, FieldFlag_None ) \
HANDLER(ErrorContext, 615, ErrorInfoAuto, FieldType_U8Array, FieldFlag_None ) \
HANDLER(ErrorContextSize, 616, ErrorInfoAuto, FieldType_NumericU64, FieldFlag_None ) \
HANDLER(ErrorContextTotalSize, 617, ErrorInfoAuto, FieldType_NumericU64, FieldFlag_None ) \
HANDLER(SystemPhysicalMemoryLimit, 618, ResourceLimitLimitInfo, FieldType_NumericI64, FieldFlag_None ) \
HANDLER(SystemThreadCountLimit, 619, ResourceLimitLimitInfo, FieldType_NumericI64, FieldFlag_None ) \
HANDLER(SystemEventCountLimit, 620, ResourceLimitLimitInfo, FieldType_NumericI64, FieldFlag_None ) \
HANDLER(SystemTransferMemoryCountLimit, 621, ResourceLimitLimitInfo, FieldType_NumericI64, FieldFlag_None ) \
HANDLER(SystemSessionCountLimit, 622, ResourceLimitLimitInfo, FieldType_NumericI64, FieldFlag_None ) \
HANDLER(SystemPhysicalMemoryPeak, 623, ResourceLimitPeakInfo, FieldType_NumericI64, FieldFlag_None ) \
HANDLER(SystemThreadCountPeak, 624, ResourceLimitPeakInfo, FieldType_NumericI64, FieldFlag_None ) \
HANDLER(SystemEventCountPeak, 625, ResourceLimitPeakInfo, FieldType_NumericI64, FieldFlag_None ) \
HANDLER(SystemTransferMemoryCountPeak, 626, ResourceLimitPeakInfo, FieldType_NumericI64, FieldFlag_None ) \
HANDLER(SystemSessionCountPeak, 627, ResourceLimitPeakInfo, FieldType_NumericI64, FieldFlag_None ) \
HANDLER(SystemPhysicalMemoryLimit, 618, Category_Unknown127, FieldType_NumericI64, FieldFlag_None ) \
HANDLER(SystemThreadCountLimit, 619, Category_Unknown127, FieldType_NumericI64, FieldFlag_None ) \
HANDLER(SystemEventCountLimit, 620, Category_Unknown127, FieldType_NumericI64, FieldFlag_None ) \
HANDLER(SystemTransferMemoryCountLimit, 621, Category_Unknown127, FieldType_NumericI64, FieldFlag_None ) \
HANDLER(SystemSessionCountLimit, 622, Category_Unknown127, FieldType_NumericI64, FieldFlag_None ) \
HANDLER(SystemPhysicalMemoryPeak, 623, Category_Unknown128, FieldType_NumericI64, FieldFlag_None ) \
HANDLER(SystemThreadCountPeak, 624, Category_Unknown128, FieldType_NumericI64, FieldFlag_None ) \
HANDLER(SystemEventCountPeak, 625, Category_Unknown128, FieldType_NumericI64, FieldFlag_None ) \
HANDLER(SystemTransferMemoryCountPeak, 626, Category_Unknown128, FieldType_NumericI64, FieldFlag_None ) \
HANDLER(SystemSessionCountPeak, 627, Category_Unknown128, FieldType_NumericI64, FieldFlag_None ) \
HANDLER(GpuCrashHash, 628, GpuCrashInfo, FieldType_U8Array, FieldFlag_None ) \
HANDLER(TouchScreenPanelGpioValue, 629, TouchScreenInfo, FieldType_NumericU8, FieldFlag_None ) \
HANDLER(TouchScreenPanelGpioValue, 629, Category_Unknown129, FieldType_NumericU8, FieldFlag_None ) \

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