Compare commits
122 Commits
hid_refact
...
0.16.1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ca2cc5e179 | ||
|
|
17c8c390fc | ||
|
|
d8ae1d873c | ||
|
|
63e3c02688 | ||
|
|
14a415c4b2 | ||
|
|
734122f20a | ||
|
|
7fb902d8fb | ||
|
|
be8473cf65 | ||
|
|
6df26d674c | ||
|
|
1a6e003a5d | ||
|
|
0acd79c8c2 | ||
|
|
8a4bf6a0a8 | ||
|
|
af259eabda | ||
|
|
16e2f46aed | ||
|
|
bcc7eed037 | ||
|
|
abd7ad2720 | ||
|
|
58c3c8c19a | ||
|
|
f62330c73b | ||
|
|
2de85c633a | ||
|
|
121c981bb4 | ||
|
|
15396dbbc2 | ||
|
|
9ca1d3a7f7 | ||
|
|
32803d9920 | ||
|
|
5ef93778f6 | ||
|
|
7548940efa | ||
|
|
bf55776241 | ||
|
|
73167448cc | ||
|
|
c45088d1cd | ||
|
|
7336dc2b7a | ||
|
|
d2f48d5e36 | ||
|
|
422e9434d8 | ||
|
|
2b93bbd9ee | ||
|
|
021b29d2db | ||
|
|
6da28f4a27 | ||
|
|
bba99d49da | ||
|
|
e760a9d4b0 | ||
|
|
ee91f3fde0 | ||
|
|
f72475872a | ||
|
|
199a9aec8b | ||
|
|
1b83f5169a | ||
|
|
7bb77f44af | ||
|
|
801ce24622 | ||
|
|
1d778b2dc8 | ||
|
|
7c9608021d | ||
|
|
b8fbd0baff | ||
|
|
525da05629 | ||
|
|
2e9db4d113 | ||
|
|
4f1a4e7499 | ||
|
|
972283032a | ||
|
|
57f935391d | ||
|
|
4804e1e1e0 | ||
|
|
4ae74b9b4e | ||
|
|
726d7b6e4d | ||
|
|
390bdc7b6b | ||
|
|
2d8acf9c64 | ||
|
|
9743f63f0d | ||
|
|
ccd2798ae2 | ||
|
|
f3dbab4876 | ||
|
|
41a53075e5 | ||
|
|
ab8de72db0 | ||
|
|
331fa1d00d | ||
|
|
fd745ab2d3 | ||
|
|
972b396f61 | ||
|
|
3c8e7de915 | ||
|
|
1b164613a6 | ||
|
|
3d4ab95ab2 | ||
|
|
152def19c0 | ||
|
|
63974d9bce | ||
|
|
2b483866c7 | ||
|
|
7e1da15f6e | ||
|
|
0a1465f198 | ||
|
|
748893fe77 | ||
|
|
1ca64cf2a1 | ||
|
|
aac8af8bf5 | ||
|
|
5da6b60008 | ||
|
|
e400e2afc7 | ||
|
|
56c6e4244a | ||
|
|
c8ebd7eea0 | ||
|
|
550f5690bf | ||
|
|
28f9b534b6 | ||
|
|
3fd59b61bc | ||
|
|
f86059de70 | ||
|
|
a03ee7b148 | ||
|
|
8b2ed36698 | ||
|
|
1852fe8612 | ||
|
|
b60054dba1 | ||
|
|
c7f37f81ee | ||
|
|
19a279ce45 | ||
|
|
783f1077be | ||
|
|
b0debd72a7 | ||
|
|
24d545701c | ||
|
|
aae565629e | ||
|
|
bee629b8ad | ||
|
|
5cb237d030 | ||
|
|
a4e09fc6c4 | ||
|
|
73d9d5ff47 | ||
|
|
08cfee54fa | ||
|
|
7b279ab863 | ||
|
|
6a85f7225d | ||
|
|
f469dfbeb3 | ||
|
|
cc11d452e5 | ||
|
|
3bce008170 | ||
|
|
3383509da6 | ||
|
|
281dcf232a | ||
|
|
71a2fe1bb6 | ||
|
|
4a216dc928 | ||
|
|
18099e19b1 | ||
|
|
a0a45853dd | ||
|
|
fe9a4cd2fc | ||
|
|
88a66c89e2 | ||
|
|
93128b6b17 | ||
|
|
db2de8ef31 | ||
|
|
05832cec73 | ||
|
|
632c8984c8 | ||
|
|
694e3b579e | ||
|
|
20eba0dc98 | ||
|
|
730ef6d6db | ||
|
|
7cb24713ab | ||
|
|
a685842804 | ||
|
|
ad6dd60474 | ||
|
|
05af215191 | ||
|
|
e06b73aafa |
7
Makefile
7
Makefile
@@ -141,15 +141,16 @@ dist: dist-no-debug
|
|||||||
cp stratosphere/creport/creport.elf atmosphere-$(AMSVER)-debug/creport.elf
|
cp stratosphere/creport/creport.elf atmosphere-$(AMSVER)-debug/creport.elf
|
||||||
cp stratosphere/dmnt/dmnt.elf atmosphere-$(AMSVER)-debug/dmnt.elf
|
cp stratosphere/dmnt/dmnt.elf atmosphere-$(AMSVER)-debug/dmnt.elf
|
||||||
cp stratosphere/eclct.stub/eclct.stub.elf atmosphere-$(AMSVER)-debug/eclct.stub.elf
|
cp stratosphere/eclct.stub/eclct.stub.elf atmosphere-$(AMSVER)-debug/eclct.stub.elf
|
||||||
|
cp stratosphere/erpt/erpt.elf atmosphere-$(AMSVER)-debug/erpt.elf
|
||||||
cp stratosphere/fatal/fatal.elf atmosphere-$(AMSVER)-debug/fatal.elf
|
cp stratosphere/fatal/fatal.elf atmosphere-$(AMSVER)-debug/fatal.elf
|
||||||
|
cp stratosphere/jpegdec/jpegdec.elf atmosphere-$(AMSVER)-debug/jpegdec.elf
|
||||||
cp stratosphere/loader/loader.elf atmosphere-$(AMSVER)-debug/loader.elf
|
cp stratosphere/loader/loader.elf atmosphere-$(AMSVER)-debug/loader.elf
|
||||||
|
cp stratosphere/ncm/ncm.elf atmosphere-$(AMSVER)-debug/ncm.elf
|
||||||
|
cp stratosphere/pgl/pgl.elf atmosphere-$(AMSVER)-debug/pgl.elf
|
||||||
cp stratosphere/pm/pm.elf atmosphere-$(AMSVER)-debug/pm.elf
|
cp stratosphere/pm/pm.elf atmosphere-$(AMSVER)-debug/pm.elf
|
||||||
cp stratosphere/ro/ro.elf atmosphere-$(AMSVER)-debug/ro.elf
|
cp stratosphere/ro/ro.elf atmosphere-$(AMSVER)-debug/ro.elf
|
||||||
cp stratosphere/sm/sm.elf atmosphere-$(AMSVER)-debug/sm.elf
|
cp stratosphere/sm/sm.elf atmosphere-$(AMSVER)-debug/sm.elf
|
||||||
cp stratosphere/spl/spl.elf atmosphere-$(AMSVER)-debug/spl.elf
|
cp stratosphere/spl/spl.elf atmosphere-$(AMSVER)-debug/spl.elf
|
||||||
cp stratosphere/erpt/erpt.elf atmosphere-$(AMSVER)-debug/erpt.elf
|
|
||||||
cp stratosphere/jpegdec/jpegdec.elf atmosphere-$(AMSVER)-debug/jpegdec.elf
|
|
||||||
cp stratosphere/pgl/pgl.elf atmosphere-$(AMSVER)-debug/pgl.elf
|
|
||||||
cp troposphere/daybreak/daybreak.elf atmosphere-$(AMSVER)-debug/daybreak.elf
|
cp troposphere/daybreak/daybreak.elf atmosphere-$(AMSVER)-debug/daybreak.elf
|
||||||
cd atmosphere-$(AMSVER)-debug; zip -r ../atmosphere-$(AMSVER)-debug.zip ./*; cd ../;
|
cd atmosphere-$(AMSVER)-debug; zip -r ../atmosphere-$(AMSVER)-debug.zip ./*; cd ../;
|
||||||
rm -r atmosphere-$(AMSVER)-debug
|
rm -r atmosphere-$(AMSVER)-debug
|
||||||
|
|||||||
@@ -35,6 +35,17 @@
|
|||||||
# mmc space, encrypted to prevent detection. This backup can be used
|
# mmc space, encrypted to prevent detection. This backup can be used
|
||||||
# to prevent unrecoverable edits in emergencies.
|
# to prevent unrecoverable edits in emergencies.
|
||||||
|
|
||||||
|
# Key: log_port, default: 0.
|
||||||
|
# Desc: Controls what uart port exosphere will set up for logging.
|
||||||
|
# NOTE: 0 = UART-A, 1 = UART-B, 2 = UART-C, 3 = UART-D
|
||||||
|
|
||||||
|
# Key: log_baud_rate, default: 115200
|
||||||
|
# Desc: Controls the baud rate exosphere will set up for logging.
|
||||||
|
# NOTE: 0 is treated as equivalent to 115200.
|
||||||
|
|
||||||
|
# Key: log_inverted, default: 0.
|
||||||
|
# Desc: Controls whether the logging uart port is inverted.
|
||||||
|
|
||||||
[exosphere]
|
[exosphere]
|
||||||
debugmode=1
|
debugmode=1
|
||||||
debugmode_user=0
|
debugmode_user=0
|
||||||
@@ -43,3 +54,6 @@ enable_user_pmu_access=0
|
|||||||
blank_prodinfo_sysmmc=0
|
blank_prodinfo_sysmmc=0
|
||||||
blank_prodinfo_emummc=0
|
blank_prodinfo_emummc=0
|
||||||
allow_writing_to_cal_sysmmc=0
|
allow_writing_to_cal_sysmmc=0
|
||||||
|
log_port=0
|
||||||
|
log_baud_rate=115200
|
||||||
|
log_inverted=0
|
||||||
|
|||||||
@@ -1,4 +1,50 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
## 0.16.1
|
||||||
|
+ Support was added for 11.0.1.
|
||||||
|
+ `mesosphère` was updated to reflect the latest official kernel behavior.
|
||||||
|
+ A new svc::InfoType added in 11.0.0 was implemented (it wasn't discovered before 0.16.0 released).
|
||||||
|
+ The new Control Flow Integrity (CFI) logic added in 11.0.0 kernel was implemented.
|
||||||
|
+ `fs` logic was refactored and cleaned up to reflect some newer sysmodule behavioral and structural changes.
|
||||||
|
+ `exosphère` was updated to allow dynamic control of what uart port is used for logging.
|
||||||
|
+ This can be controlled by editing the `log_port`, `log_baud_rate`, and `log_inverted` fields in `exosphere.ini`.
|
||||||
|
+ `mesosphère` was updated to improve debugging capabilities ().
|
||||||
|
+ This is still a work in progress, but developers may be interested.
|
||||||
|
+ A bug was fixed that caused `fatal` to fatal error if the fatal process was already being debugged.
|
||||||
|
+ Several issues were fixed, and usability and stability were improved.
|
||||||
|
## 0.16.0
|
||||||
|
+ Support was added for 11.0.0.
|
||||||
|
+ `exosphère` was updated to reflect the latest official secure monitor behavior.
|
||||||
|
+ `mesosphère` was updated to reflect the latest official kernel behavior.
|
||||||
|
+ `loader`, `sm`, `boot`, `pgl` were updated to reflect the latest official behaviors.
|
||||||
|
+ **Please Note**: 11.0.0 implements an opt-in version of the atmosphère `sm` extension that allows for closing session without unregistering services.
|
||||||
|
+ Correspondingly, the extension will be deprecated in favor of the new official opt-in command. In 0.17.0, it will be removed entirely.
|
||||||
|
+ If your custom system module relies on this extension (however unlikely that seems to me), please update it accordingly.
|
||||||
|
+ `erpt` was partially updated to provide compatibility with 11.0.0.
|
||||||
|
+ The latest firmware attaches additional fields and context information to logs.
|
||||||
|
+ A future atmosphère update will implement this logic, so that users who are interested can also get the new information when examining their logs.
|
||||||
|
+ **Please Note**: 11.0.0 introduced breaking changes to the `usb` system module's `usb:ds` API.
|
||||||
|
+ Homebrew which uses the `usb:ds` service should rebuild with the latest libnx version to support running on 11.0.0.
|
||||||
|
+ The `boot` system module was rewritten to reflect the huge driver changes introduced in 8.0.0.
|
||||||
|
+ This includes a number of improvements to both logo display and battery management logic.
|
||||||
|
+ Support was added for configuring the address space width for `hbl`.
|
||||||
|
+ The `hbl_config!override_address_space_(#)` and `hbl_config!override_any_app_address_space` can now be set to `39_bit`, `36_bit`, or `32_bit` to control the address space for hbl on a per-override basis.
|
||||||
|
+ If a configuration has not been set, hbl will now default to 39-bit address space.
|
||||||
|
+ Previously, a legacy 36-bit address space was always used to maintain compatibility with 1.0.0.
|
||||||
|
+ A new loader extension was added to support 39-bit whenever possible (including mesosphere-on-1.0.0), with fallback to 36-bit when unavailable.
|
||||||
|
+ Support was added to a number of components for running on Mariko hardware.
|
||||||
|
+ The `boot` system module can now safely be run on mariko hardware, performing correct hardware initialization.
|
||||||
|
+ Daybreak (and generally, system update logic) were updated to be usable on Mariko.
|
||||||
|
+ Boot0 protection/management logic was updated to perform correct actions on Mariko.
|
||||||
|
+ Reboot to payload does not and cannot work on Mariko. Correspondingly, A "fatal error" handler was written, to display and save fatal errors from within TrustZone.
|
||||||
|
+ **Please Note:** Atmosphere is still not properly usable on Mariko hardware.
|
||||||
|
+ In particular, wake-from-sleep will not properly function (the magic numbers aren't set correctly), among a few other minor issues.
|
||||||
|
+ `exosphère` received support for building under debug configuration.
|
||||||
|
+ A small (otherwise unused) portion of IRAM is now reserved for debug-only exosphere code (this region is unused/untouched under release config).
|
||||||
|
+ This enables logging (including printf) to uart from the secure monitor, for those interested.
|
||||||
|
+ A number of bugs were fixed, including:
|
||||||
|
+ Minor issues in a number of filesystem related code were fixed.
|
||||||
|
+ An issue was fixed that could cause NCM to abort on consoles which came with 3.0.x and were never updated.
|
||||||
|
+ Several issues were fixed, and usability and stability were improved.
|
||||||
## 0.15.0
|
## 0.15.0
|
||||||
+ fusee-primary's panic display was updated to automatically identify and give suggestions to resolve many of the most common errors users encounter.
|
+ fusee-primary's panic display was updated to automatically identify and give suggestions to resolve many of the most common errors users encounter.
|
||||||
+ Having been tested as well as I can alone, `mesosphere` (atmosphère's reimplementation of the Nintendo Switch kernel) is now available for users interested in trying it.
|
+ Having been tested as well as I can alone, `mesosphere` (atmosphère's reimplementation of the Nintendo Switch kernel) is now available for users interested in trying it.
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
[subrepo]
|
[subrepo]
|
||||||
remote = https://github.com/m4xw/emuMMC
|
remote = https://github.com/m4xw/emuMMC
|
||||||
branch = develop
|
branch = develop
|
||||||
commit = 25075973d31a5be6f2e769f1ea0fff44daf0cdfa
|
commit = 5eed18eb527bbaa63aee5323c26de5b0cca6d28e
|
||||||
parent = 8ba513fefbcfd8278a433090e59017963ba9887f
|
parent = 021b29d2dbc8ed0469bc822393e58c9f0d174d57
|
||||||
method = rebase
|
method = rebase
|
||||||
cmdver = 0.4.1
|
cmdver = 0.4.1
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
*A SDMMC driver replacement for Nintendo's Filesystem Services, by **m4xw***
|
*A SDMMC driver replacement for Nintendo's Filesystem Services, by **m4xw***
|
||||||
|
|
||||||
### Supported Horizon Versions
|
### Supported Horizon Versions
|
||||||
**1.0.0 - 10.0.0**
|
**1.0.0 - 11.0.0**
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
* Arbitrary SDMMC backend selection
|
* Arbitrary SDMMC backend selection
|
||||||
|
|||||||
@@ -71,6 +71,7 @@ static const fs_offsets_t GET_OFFSET_STRUCT_NAME(vers) = { \
|
|||||||
.nand_mutex = FS_OFFSET##vers##_NAND_MUTEX, \
|
.nand_mutex = FS_OFFSET##vers##_NAND_MUTEX, \
|
||||||
.active_partition = FS_OFFSET##vers##_ACTIVE_PARTITION, \
|
.active_partition = FS_OFFSET##vers##_ACTIVE_PARTITION, \
|
||||||
.sdmmc_das_handle = FS_OFFSET##vers##_SDMMC_DAS_HANDLE, \
|
.sdmmc_das_handle = FS_OFFSET##vers##_SDMMC_DAS_HANDLE, \
|
||||||
|
.sdmmc_accessor_controller_open = FS_OFFSET##vers##_SDMMC_WRAPPER_CONTROLLER_OPEN, \
|
||||||
.sdmmc_accessor_controller_close = FS_OFFSET##vers##_SDMMC_WRAPPER_CONTROLLER_CLOSE, \
|
.sdmmc_accessor_controller_close = FS_OFFSET##vers##_SDMMC_WRAPPER_CONTROLLER_CLOSE, \
|
||||||
.sd_das_init = FS_OFFSET##vers##_SD_DAS_INIT, \
|
.sd_das_init = FS_OFFSET##vers##_SD_DAS_INIT, \
|
||||||
.nintendo_paths = FS_OFFSET##vers##_NINTENDO_PATHS, \
|
.nintendo_paths = FS_OFFSET##vers##_NINTENDO_PATHS, \
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ typedef struct {
|
|||||||
// Misc funcs
|
// Misc funcs
|
||||||
uintptr_t lock_mutex;
|
uintptr_t lock_mutex;
|
||||||
uintptr_t unlock_mutex;
|
uintptr_t unlock_mutex;
|
||||||
|
uintptr_t sdmmc_accessor_controller_open;
|
||||||
uintptr_t sdmmc_accessor_controller_close;
|
uintptr_t sdmmc_accessor_controller_close;
|
||||||
// Misc data
|
// Misc data
|
||||||
uintptr_t sd_mutex;
|
uintptr_t sd_mutex;
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ typedef struct sdmmc_accessor_vt
|
|||||||
void *dtor;
|
void *dtor;
|
||||||
void *map_device_addr_space;
|
void *map_device_addr_space;
|
||||||
void *unmap_device_addr_space;
|
void *unmap_device_addr_space;
|
||||||
void *controller_open;
|
uint64_t (*sdmmc_accessor_controller_open)(void *);
|
||||||
uint64_t (*sdmmc_accessor_controller_close)(void *);
|
uint64_t (*sdmmc_accessor_controller_close)(void *);
|
||||||
uint64_t (*read_write)(void *, uint64_t, uint64_t, void *, uint64_t, uint64_t);
|
uint64_t (*read_write)(void *, uint64_t, uint64_t, void *, uint64_t, uint64_t);
|
||||||
// More not included because we don't use it.
|
// More not included because we don't use it.
|
||||||
|
|||||||
@@ -34,6 +34,7 @@
|
|||||||
#define FS_OFFSET_100_LOCK_MUTEX 0x2884
|
#define FS_OFFSET_100_LOCK_MUTEX 0x2884
|
||||||
#define FS_OFFSET_100_UNLOCK_MUTEX 0x28F0
|
#define FS_OFFSET_100_UNLOCK_MUTEX 0x28F0
|
||||||
|
|
||||||
|
#define FS_OFFSET_100_SDMMC_WRAPPER_CONTROLLER_OPEN 0
|
||||||
#define FS_OFFSET_100_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x6A8AC
|
#define FS_OFFSET_100_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x6A8AC
|
||||||
|
|
||||||
// Misc Data
|
// Misc Data
|
||||||
|
|||||||
@@ -34,6 +34,7 @@
|
|||||||
#define FS_OFFSET_1000_LOCK_MUTEX 0x28910
|
#define FS_OFFSET_1000_LOCK_MUTEX 0x28910
|
||||||
#define FS_OFFSET_1000_UNLOCK_MUTEX 0x28960
|
#define FS_OFFSET_1000_UNLOCK_MUTEX 0x28960
|
||||||
|
|
||||||
|
#define FS_OFFSET_1000_SDMMC_WRAPPER_CONTROLLER_OPEN 0
|
||||||
#define FS_OFFSET_1000_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x1422E0
|
#define FS_OFFSET_1000_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x1422E0
|
||||||
|
|
||||||
// Misc Data
|
// Misc Data
|
||||||
|
|||||||
@@ -34,6 +34,7 @@
|
|||||||
#define FS_OFFSET_1000_EXFAT_LOCK_MUTEX 0x28910
|
#define FS_OFFSET_1000_EXFAT_LOCK_MUTEX 0x28910
|
||||||
#define FS_OFFSET_1000_EXFAT_UNLOCK_MUTEX 0x28960
|
#define FS_OFFSET_1000_EXFAT_UNLOCK_MUTEX 0x28960
|
||||||
|
|
||||||
|
#define FS_OFFSET_1000_EXFAT_SDMMC_WRAPPER_CONTROLLER_OPEN 0
|
||||||
#define FS_OFFSET_1000_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x1422E0
|
#define FS_OFFSET_1000_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x1422E0
|
||||||
|
|
||||||
// Misc Data
|
// Misc Data
|
||||||
|
|||||||
@@ -34,6 +34,7 @@
|
|||||||
#define FS_OFFSET_1020_LOCK_MUTEX 0x28910
|
#define FS_OFFSET_1020_LOCK_MUTEX 0x28910
|
||||||
#define FS_OFFSET_1020_UNLOCK_MUTEX 0x28960
|
#define FS_OFFSET_1020_UNLOCK_MUTEX 0x28960
|
||||||
|
|
||||||
|
#define FS_OFFSET_1020_SDMMC_WRAPPER_CONTROLLER_OPEN 0
|
||||||
#define FS_OFFSET_1020_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x142740
|
#define FS_OFFSET_1020_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x142740
|
||||||
|
|
||||||
// Misc Data
|
// Misc Data
|
||||||
|
|||||||
@@ -34,6 +34,7 @@
|
|||||||
#define FS_OFFSET_1020_EXFAT_LOCK_MUTEX 0x28910
|
#define FS_OFFSET_1020_EXFAT_LOCK_MUTEX 0x28910
|
||||||
#define FS_OFFSET_1020_EXFAT_UNLOCK_MUTEX 0x28960
|
#define FS_OFFSET_1020_EXFAT_UNLOCK_MUTEX 0x28960
|
||||||
|
|
||||||
|
#define FS_OFFSET_1020_EXFAT_SDMMC_WRAPPER_CONTROLLER_OPEN 0
|
||||||
#define FS_OFFSET_1020_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x142740
|
#define FS_OFFSET_1020_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x142740
|
||||||
|
|
||||||
// Misc Data
|
// Misc Data
|
||||||
|
|||||||
@@ -34,6 +34,7 @@
|
|||||||
#define FS_OFFSET_1100_LOCK_MUTEX 0x28FF0
|
#define FS_OFFSET_1100_LOCK_MUTEX 0x28FF0
|
||||||
#define FS_OFFSET_1100_UNLOCK_MUTEX 0x29040
|
#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
|
#define FS_OFFSET_1100_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x14B8F0
|
||||||
|
|
||||||
// Misc Data
|
// Misc Data
|
||||||
|
|||||||
@@ -34,6 +34,7 @@
|
|||||||
#define FS_OFFSET_1100_EXFAT_LOCK_MUTEX 0x28FF0
|
#define FS_OFFSET_1100_EXFAT_LOCK_MUTEX 0x28FF0
|
||||||
#define FS_OFFSET_1100_EXFAT_UNLOCK_MUTEX 0x29040
|
#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
|
#define FS_OFFSET_1100_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x14B8F0
|
||||||
|
|
||||||
// Misc Data
|
// Misc Data
|
||||||
|
|||||||
@@ -34,6 +34,7 @@
|
|||||||
#define FS_OFFSET_200_LOCK_MUTEX 0x3264
|
#define FS_OFFSET_200_LOCK_MUTEX 0x3264
|
||||||
#define FS_OFFSET_200_UNLOCK_MUTEX 0x32D0
|
#define FS_OFFSET_200_UNLOCK_MUTEX 0x32D0
|
||||||
|
|
||||||
|
#define FS_OFFSET_200_SDMMC_WRAPPER_CONTROLLER_OPEN 0
|
||||||
#define FS_OFFSET_200_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x733F4
|
#define FS_OFFSET_200_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x733F4
|
||||||
|
|
||||||
// Misc Data
|
// Misc Data
|
||||||
|
|||||||
@@ -34,6 +34,7 @@
|
|||||||
#define FS_OFFSET_200_EXFAT_LOCK_MUTEX 0x3264
|
#define FS_OFFSET_200_EXFAT_LOCK_MUTEX 0x3264
|
||||||
#define FS_OFFSET_200_EXFAT_UNLOCK_MUTEX 0x32D0
|
#define FS_OFFSET_200_EXFAT_UNLOCK_MUTEX 0x32D0
|
||||||
|
|
||||||
|
#define FS_OFFSET_200_EXFAT_SDMMC_WRAPPER_CONTROLLER_OPEN 0
|
||||||
#define FS_OFFSET_200_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x733F4
|
#define FS_OFFSET_200_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x733F4
|
||||||
|
|
||||||
// Misc Data
|
// Misc Data
|
||||||
|
|||||||
@@ -34,6 +34,7 @@
|
|||||||
#define FS_OFFSET_210_LOCK_MUTEX 0x3264
|
#define FS_OFFSET_210_LOCK_MUTEX 0x3264
|
||||||
#define FS_OFFSET_210_UNLOCK_MUTEX 0x32D0
|
#define FS_OFFSET_210_UNLOCK_MUTEX 0x32D0
|
||||||
|
|
||||||
|
#define FS_OFFSET_210_SDMMC_WRAPPER_CONTROLLER_OPEN 0
|
||||||
#define FS_OFFSET_210_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x737D4
|
#define FS_OFFSET_210_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x737D4
|
||||||
|
|
||||||
// Misc Data
|
// Misc Data
|
||||||
|
|||||||
@@ -34,6 +34,7 @@
|
|||||||
#define FS_OFFSET_210_EXFAT_LOCK_MUTEX 0x3264
|
#define FS_OFFSET_210_EXFAT_LOCK_MUTEX 0x3264
|
||||||
#define FS_OFFSET_210_EXFAT_UNLOCK_MUTEX 0x32D0
|
#define FS_OFFSET_210_EXFAT_UNLOCK_MUTEX 0x32D0
|
||||||
|
|
||||||
|
#define FS_OFFSET_210_EXFAT_SDMMC_WRAPPER_CONTROLLER_OPEN 0
|
||||||
#define FS_OFFSET_210_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x737D4
|
#define FS_OFFSET_210_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x737D4
|
||||||
|
|
||||||
// Misc Data
|
// Misc Data
|
||||||
|
|||||||
@@ -34,6 +34,7 @@
|
|||||||
#define FS_OFFSET_300_LOCK_MUTEX 0x35CC
|
#define FS_OFFSET_300_LOCK_MUTEX 0x35CC
|
||||||
#define FS_OFFSET_300_UNLOCK_MUTEX 0x3638
|
#define FS_OFFSET_300_UNLOCK_MUTEX 0x3638
|
||||||
|
|
||||||
|
#define FS_OFFSET_300_SDMMC_WRAPPER_CONTROLLER_OPEN 0
|
||||||
#define FS_OFFSET_300_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x8A270
|
#define FS_OFFSET_300_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x8A270
|
||||||
|
|
||||||
// Misc Data
|
// Misc Data
|
||||||
|
|||||||
@@ -34,6 +34,7 @@
|
|||||||
#define FS_OFFSET_300_EXFAT_LOCK_MUTEX 0x35CC
|
#define FS_OFFSET_300_EXFAT_LOCK_MUTEX 0x35CC
|
||||||
#define FS_OFFSET_300_EXFAT_UNLOCK_MUTEX 0x3638
|
#define FS_OFFSET_300_EXFAT_UNLOCK_MUTEX 0x3638
|
||||||
|
|
||||||
|
#define FS_OFFSET_300_EXFAT_SDMMC_WRAPPER_CONTROLLER_OPEN 0
|
||||||
#define FS_OFFSET_300_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x8A270
|
#define FS_OFFSET_300_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x8A270
|
||||||
|
|
||||||
// Misc Data
|
// Misc Data
|
||||||
|
|||||||
@@ -34,6 +34,7 @@
|
|||||||
#define FS_OFFSET_301_LOCK_MUTEX 0x3638
|
#define FS_OFFSET_301_LOCK_MUTEX 0x3638
|
||||||
#define FS_OFFSET_301_UNLOCK_MUTEX 0x36A4
|
#define FS_OFFSET_301_UNLOCK_MUTEX 0x36A4
|
||||||
|
|
||||||
|
#define FS_OFFSET_301_SDMMC_WRAPPER_CONTROLLER_OPEN 0
|
||||||
#define FS_OFFSET_301_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x8A32C
|
#define FS_OFFSET_301_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x8A32C
|
||||||
|
|
||||||
// Misc Data
|
// Misc Data
|
||||||
|
|||||||
@@ -34,6 +34,7 @@
|
|||||||
#define FS_OFFSET_301_EXFAT_LOCK_MUTEX 0x3638
|
#define FS_OFFSET_301_EXFAT_LOCK_MUTEX 0x3638
|
||||||
#define FS_OFFSET_301_EXFAT_UNLOCK_MUTEX 0x36A4
|
#define FS_OFFSET_301_EXFAT_UNLOCK_MUTEX 0x36A4
|
||||||
|
|
||||||
|
#define FS_OFFSET_301_EXFAT_SDMMC_WRAPPER_CONTROLLER_OPEN 0
|
||||||
#define FS_OFFSET_301_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x8A32C
|
#define FS_OFFSET_301_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x8A32C
|
||||||
|
|
||||||
// Misc Data
|
// Misc Data
|
||||||
|
|||||||
@@ -34,6 +34,7 @@
|
|||||||
#define FS_OFFSET_400_LOCK_MUTEX 0x39A0
|
#define FS_OFFSET_400_LOCK_MUTEX 0x39A0
|
||||||
#define FS_OFFSET_400_UNLOCK_MUTEX 0x3A0C
|
#define FS_OFFSET_400_UNLOCK_MUTEX 0x3A0C
|
||||||
|
|
||||||
|
#define FS_OFFSET_400_SDMMC_WRAPPER_CONTROLLER_OPEN 0
|
||||||
#define FS_OFFSET_400_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x9DB48
|
#define FS_OFFSET_400_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x9DB48
|
||||||
|
|
||||||
// Misc Data
|
// Misc Data
|
||||||
|
|||||||
@@ -34,6 +34,7 @@
|
|||||||
#define FS_OFFSET_400_EXFAT_LOCK_MUTEX 0x39A0
|
#define FS_OFFSET_400_EXFAT_LOCK_MUTEX 0x39A0
|
||||||
#define FS_OFFSET_400_EXFAT_UNLOCK_MUTEX 0x3A0C
|
#define FS_OFFSET_400_EXFAT_UNLOCK_MUTEX 0x3A0C
|
||||||
|
|
||||||
|
#define FS_OFFSET_400_EXFAT_SDMMC_WRAPPER_CONTROLLER_OPEN 0
|
||||||
#define FS_OFFSET_400_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x9DB48
|
#define FS_OFFSET_400_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x9DB48
|
||||||
|
|
||||||
// Misc Data
|
// Misc Data
|
||||||
|
|||||||
@@ -34,7 +34,8 @@
|
|||||||
#define FS_OFFSET_410_LOCK_MUTEX 0x39A0
|
#define FS_OFFSET_410_LOCK_MUTEX 0x39A0
|
||||||
#define FS_OFFSET_410_UNLOCK_MUTEX 0x3A0C
|
#define FS_OFFSET_410_UNLOCK_MUTEX 0x3A0C
|
||||||
|
|
||||||
#define FS_OFFSET_410_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x9DBAC
|
#define FS_OFFSET_410_SDMMC_WRAPPER_CONTROLLER_OPEN 0
|
||||||
|
#define FS_OFFSET_410_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x9DBAC
|
||||||
|
|
||||||
// Misc Data
|
// Misc Data
|
||||||
#define FS_OFFSET_410_SD_MUTEX 0xE80268
|
#define FS_OFFSET_410_SD_MUTEX 0xE80268
|
||||||
|
|||||||
@@ -34,6 +34,7 @@
|
|||||||
#define FS_OFFSET_410_EXFAT_LOCK_MUTEX 0x39A0
|
#define FS_OFFSET_410_EXFAT_LOCK_MUTEX 0x39A0
|
||||||
#define FS_OFFSET_410_EXFAT_UNLOCK_MUTEX 0x3A0C
|
#define FS_OFFSET_410_EXFAT_UNLOCK_MUTEX 0x3A0C
|
||||||
|
|
||||||
|
#define FS_OFFSET_410_EXFAT_SDMMC_WRAPPER_CONTROLLER_OPEN 0
|
||||||
#define FS_OFFSET_410_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x9DBAC
|
#define FS_OFFSET_410_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x9DBAC
|
||||||
|
|
||||||
// Misc Data
|
// Misc Data
|
||||||
|
|||||||
@@ -34,6 +34,7 @@
|
|||||||
#define FS_OFFSET_500_LOCK_MUTEX 0x4080
|
#define FS_OFFSET_500_LOCK_MUTEX 0x4080
|
||||||
#define FS_OFFSET_500_UNLOCK_MUTEX 0x40D0
|
#define FS_OFFSET_500_UNLOCK_MUTEX 0x40D0
|
||||||
|
|
||||||
|
#define FS_OFFSET_500_SDMMC_WRAPPER_CONTROLLER_OPEN 0
|
||||||
#define FS_OFFSET_500_SDMMC_WRAPPER_CONTROLLER_CLOSE 0xC9380
|
#define FS_OFFSET_500_SDMMC_WRAPPER_CONTROLLER_CLOSE 0xC9380
|
||||||
|
|
||||||
// Misc Data
|
// Misc Data
|
||||||
|
|||||||
@@ -34,6 +34,7 @@
|
|||||||
#define FS_OFFSET_500_EXFAT_LOCK_MUTEX 0x4080
|
#define FS_OFFSET_500_EXFAT_LOCK_MUTEX 0x4080
|
||||||
#define FS_OFFSET_500_EXFAT_UNLOCK_MUTEX 0x40D0
|
#define FS_OFFSET_500_EXFAT_UNLOCK_MUTEX 0x40D0
|
||||||
|
|
||||||
|
#define FS_OFFSET_500_EXFAT_SDMMC_WRAPPER_CONTROLLER_OPEN 0
|
||||||
#define FS_OFFSET_500_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0xC9380
|
#define FS_OFFSET_500_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0xC9380
|
||||||
|
|
||||||
// Misc Data
|
// Misc Data
|
||||||
|
|||||||
@@ -34,6 +34,7 @@
|
|||||||
#define FS_OFFSET_510_LOCK_MUTEX 0x4080
|
#define FS_OFFSET_510_LOCK_MUTEX 0x4080
|
||||||
#define FS_OFFSET_510_UNLOCK_MUTEX 0x40D0
|
#define FS_OFFSET_510_UNLOCK_MUTEX 0x40D0
|
||||||
|
|
||||||
|
#define FS_OFFSET_510_SDMMC_WRAPPER_CONTROLLER_OPEN 0
|
||||||
#define FS_OFFSET_510_SDMMC_WRAPPER_CONTROLLER_CLOSE 0xC9750
|
#define FS_OFFSET_510_SDMMC_WRAPPER_CONTROLLER_CLOSE 0xC9750
|
||||||
|
|
||||||
// Misc Data
|
// Misc Data
|
||||||
|
|||||||
@@ -34,6 +34,7 @@
|
|||||||
#define FS_OFFSET_510_EXFAT_LOCK_MUTEX 0x4080
|
#define FS_OFFSET_510_EXFAT_LOCK_MUTEX 0x4080
|
||||||
#define FS_OFFSET_510_EXFAT_UNLOCK_MUTEX 0x40D0
|
#define FS_OFFSET_510_EXFAT_UNLOCK_MUTEX 0x40D0
|
||||||
|
|
||||||
|
#define FS_OFFSET_510_EXFAT_SDMMC_WRAPPER_CONTROLLER_OPEN 0
|
||||||
#define FS_OFFSET_510_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0xC9750
|
#define FS_OFFSET_510_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0xC9750
|
||||||
|
|
||||||
// Misc Data
|
// Misc Data
|
||||||
|
|||||||
@@ -34,6 +34,7 @@
|
|||||||
#define FS_OFFSET_600_LOCK_MUTEX 0x1412C0
|
#define FS_OFFSET_600_LOCK_MUTEX 0x1412C0
|
||||||
#define FS_OFFSET_600_UNLOCK_MUTEX 0x141310
|
#define FS_OFFSET_600_UNLOCK_MUTEX 0x141310
|
||||||
|
|
||||||
|
#define FS_OFFSET_600_SDMMC_WRAPPER_CONTROLLER_OPEN 0
|
||||||
#define FS_OFFSET_600_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x148500
|
#define FS_OFFSET_600_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x148500
|
||||||
|
|
||||||
// Misc Data
|
// Misc Data
|
||||||
|
|||||||
@@ -34,6 +34,7 @@
|
|||||||
#define FS_OFFSET_600_EXFAT_LOCK_MUTEX 0x14C9C0
|
#define FS_OFFSET_600_EXFAT_LOCK_MUTEX 0x14C9C0
|
||||||
#define FS_OFFSET_600_EXFAT_UNLOCK_MUTEX 0x14CA10
|
#define FS_OFFSET_600_EXFAT_UNLOCK_MUTEX 0x14CA10
|
||||||
|
|
||||||
|
#define FS_OFFSET_600_EXFAT_SDMMC_WRAPPER_CONTROLLER_OPEN 0
|
||||||
#define FS_OFFSET_600_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x153C00
|
#define FS_OFFSET_600_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x153C00
|
||||||
|
|
||||||
// Misc Data
|
// Misc Data
|
||||||
|
|||||||
@@ -34,6 +34,7 @@
|
|||||||
#define FS_OFFSET_700_LOCK_MUTEX 0x148A90
|
#define FS_OFFSET_700_LOCK_MUTEX 0x148A90
|
||||||
#define FS_OFFSET_700_UNLOCK_MUTEX 0x148AE0
|
#define FS_OFFSET_700_UNLOCK_MUTEX 0x148AE0
|
||||||
|
|
||||||
|
#define FS_OFFSET_700_SDMMC_WRAPPER_CONTROLLER_OPEN 0
|
||||||
#define FS_OFFSET_700_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x14FD50
|
#define FS_OFFSET_700_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x14FD50
|
||||||
|
|
||||||
// Misc Data
|
// Misc Data
|
||||||
|
|||||||
@@ -34,6 +34,7 @@
|
|||||||
#define FS_OFFSET_700_EXFAT_LOCK_MUTEX 0x154040
|
#define FS_OFFSET_700_EXFAT_LOCK_MUTEX 0x154040
|
||||||
#define FS_OFFSET_700_EXFAT_UNLOCK_MUTEX 0x154090
|
#define FS_OFFSET_700_EXFAT_UNLOCK_MUTEX 0x154090
|
||||||
|
|
||||||
|
#define FS_OFFSET_700_EXFAT_SDMMC_WRAPPER_CONTROLLER_OPEN 0
|
||||||
#define FS_OFFSET_700_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x15B300
|
#define FS_OFFSET_700_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x15B300
|
||||||
|
|
||||||
// Misc Data
|
// Misc Data
|
||||||
|
|||||||
@@ -34,6 +34,7 @@
|
|||||||
#define FS_OFFSET_800_LOCK_MUTEX 0x14B6D0
|
#define FS_OFFSET_800_LOCK_MUTEX 0x14B6D0
|
||||||
#define FS_OFFSET_800_UNLOCK_MUTEX 0x14B720
|
#define FS_OFFSET_800_UNLOCK_MUTEX 0x14B720
|
||||||
|
|
||||||
|
#define FS_OFFSET_800_SDMMC_WRAPPER_CONTROLLER_OPEN 0
|
||||||
#define FS_OFFSET_800_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x1529E0
|
#define FS_OFFSET_800_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x1529E0
|
||||||
|
|
||||||
// Misc Data
|
// Misc Data
|
||||||
|
|||||||
@@ -34,6 +34,7 @@
|
|||||||
#define FS_OFFSET_800_EXFAT_LOCK_MUTEX 0x156C80
|
#define FS_OFFSET_800_EXFAT_LOCK_MUTEX 0x156C80
|
||||||
#define FS_OFFSET_800_EXFAT_UNLOCK_MUTEX 0x156CD0
|
#define FS_OFFSET_800_EXFAT_UNLOCK_MUTEX 0x156CD0
|
||||||
|
|
||||||
|
#define FS_OFFSET_800_EXFAT_SDMMC_WRAPPER_CONTROLLER_OPEN 0
|
||||||
#define FS_OFFSET_800_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x15DF90
|
#define FS_OFFSET_800_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x15DF90
|
||||||
|
|
||||||
// Misc Data
|
// Misc Data
|
||||||
|
|||||||
@@ -34,6 +34,7 @@
|
|||||||
#define FS_OFFSET_810_LOCK_MUTEX 0x14B6D0
|
#define FS_OFFSET_810_LOCK_MUTEX 0x14B6D0
|
||||||
#define FS_OFFSET_810_UNLOCK_MUTEX 0x14B720
|
#define FS_OFFSET_810_UNLOCK_MUTEX 0x14B720
|
||||||
|
|
||||||
|
#define FS_OFFSET_810_SDMMC_WRAPPER_CONTROLLER_OPEN 0
|
||||||
#define FS_OFFSET_810_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x1529E0
|
#define FS_OFFSET_810_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x1529E0
|
||||||
|
|
||||||
// Misc Data
|
// Misc Data
|
||||||
|
|||||||
@@ -34,6 +34,7 @@
|
|||||||
#define FS_OFFSET_810_EXFAT_LOCK_MUTEX 0x156C80
|
#define FS_OFFSET_810_EXFAT_LOCK_MUTEX 0x156C80
|
||||||
#define FS_OFFSET_810_EXFAT_UNLOCK_MUTEX 0x156CD0
|
#define FS_OFFSET_810_EXFAT_UNLOCK_MUTEX 0x156CD0
|
||||||
|
|
||||||
|
#define FS_OFFSET_810_EXFAT_SDMMC_WRAPPER_CONTROLLER_OPEN 0
|
||||||
#define FS_OFFSET_810_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x15DF90
|
#define FS_OFFSET_810_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x15DF90
|
||||||
|
|
||||||
// Misc Data
|
// Misc Data
|
||||||
|
|||||||
@@ -34,6 +34,7 @@
|
|||||||
#define FS_OFFSET_900_LOCK_MUTEX 0x25280
|
#define FS_OFFSET_900_LOCK_MUTEX 0x25280
|
||||||
#define FS_OFFSET_900_UNLOCK_MUTEX 0x252D0
|
#define FS_OFFSET_900_UNLOCK_MUTEX 0x252D0
|
||||||
|
|
||||||
|
#define FS_OFFSET_900_SDMMC_WRAPPER_CONTROLLER_OPEN 0
|
||||||
#define FS_OFFSET_900_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x137740
|
#define FS_OFFSET_900_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x137740
|
||||||
|
|
||||||
// Misc Data
|
// Misc Data
|
||||||
|
|||||||
@@ -34,6 +34,7 @@
|
|||||||
#define FS_OFFSET_900_EXFAT_LOCK_MUTEX 0x25280
|
#define FS_OFFSET_900_EXFAT_LOCK_MUTEX 0x25280
|
||||||
#define FS_OFFSET_900_EXFAT_UNLOCK_MUTEX 0x252D0
|
#define FS_OFFSET_900_EXFAT_UNLOCK_MUTEX 0x252D0
|
||||||
|
|
||||||
|
#define FS_OFFSET_900_EXFAT_SDMMC_WRAPPER_CONTROLLER_OPEN 0
|
||||||
#define FS_OFFSET_900_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x137740
|
#define FS_OFFSET_900_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x137740
|
||||||
|
|
||||||
// Misc Data
|
// Misc Data
|
||||||
|
|||||||
@@ -34,6 +34,7 @@
|
|||||||
#define FS_OFFSET_910_LOCK_MUTEX 0x25280
|
#define FS_OFFSET_910_LOCK_MUTEX 0x25280
|
||||||
#define FS_OFFSET_910_UNLOCK_MUTEX 0x252D0
|
#define FS_OFFSET_910_UNLOCK_MUTEX 0x252D0
|
||||||
|
|
||||||
|
#define FS_OFFSET_910_SDMMC_WRAPPER_CONTROLLER_OPEN 0
|
||||||
#define FS_OFFSET_910_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x137750
|
#define FS_OFFSET_910_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x137750
|
||||||
|
|
||||||
// Misc Data
|
// Misc Data
|
||||||
|
|||||||
@@ -34,6 +34,7 @@
|
|||||||
#define FS_OFFSET_910_EXFAT_LOCK_MUTEX 0x25280
|
#define FS_OFFSET_910_EXFAT_LOCK_MUTEX 0x25280
|
||||||
#define FS_OFFSET_910_EXFAT_UNLOCK_MUTEX 0x252D0
|
#define FS_OFFSET_910_EXFAT_UNLOCK_MUTEX 0x252D0
|
||||||
|
|
||||||
|
#define FS_OFFSET_910_EXFAT_SDMMC_WRAPPER_CONTROLLER_OPEN 0
|
||||||
#define FS_OFFSET_910_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x137750
|
#define FS_OFFSET_910_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x137750
|
||||||
|
|
||||||
// Misc Data
|
// Misc Data
|
||||||
|
|||||||
@@ -271,7 +271,7 @@ int sdmmc_nand_get_active_partition_index()
|
|||||||
|
|
||||||
static uint64_t emummc_read_write_inner(void *buf, unsigned int sector, unsigned int num_sectors, bool is_write)
|
static uint64_t emummc_read_write_inner(void *buf, unsigned int sector, unsigned int num_sectors, bool is_write)
|
||||||
{
|
{
|
||||||
if ((emuMMC_ctx.EMMC_Type == emuMMC_SD))
|
if ((emuMMC_ctx.EMMC_Type == emuMMC_SD_Raw))
|
||||||
{
|
{
|
||||||
// raw partition sector offset: emuMMC_ctx.EMMC_StoragePartitionOffset.
|
// raw partition sector offset: emuMMC_ctx.EMMC_StoragePartitionOffset.
|
||||||
sector += emuMMC_ctx.EMMC_StoragePartitionOffset;
|
sector += emuMMC_ctx.EMMC_StoragePartitionOffset;
|
||||||
@@ -318,6 +318,31 @@ static uint64_t emummc_read_write_inner(void *buf, unsigned int sector, unsigned
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Controller open wrapper
|
||||||
|
uint64_t sdmmc_wrapper_controller_open(int mmc_id)
|
||||||
|
{
|
||||||
|
uint64_t result;
|
||||||
|
sdmmc_accessor_t *_this;
|
||||||
|
_this = sdmmc_accessor_get(mmc_id);
|
||||||
|
|
||||||
|
if (_this != NULL)
|
||||||
|
{
|
||||||
|
// Lock eMMC xfer while SD card is being initialized by FS.
|
||||||
|
if (_this == sdmmc_accessor_get(FS_SDMMC_SD))
|
||||||
|
mutex_lock_handler(FS_SDMMC_EMMC); // Recursive Mutex, handler will lock SD as well if custom_driver
|
||||||
|
|
||||||
|
result = _this->vtab->sdmmc_accessor_controller_open(_this);
|
||||||
|
|
||||||
|
// Unlock eMMC.
|
||||||
|
if (_this == sdmmc_accessor_get(FS_SDMMC_SD))
|
||||||
|
mutex_unlock_handler(FS_SDMMC_EMMC);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
fatal_abort(Fatal_OpenAccessor);
|
||||||
|
}
|
||||||
|
|
||||||
// Controller close wrapper
|
// Controller close wrapper
|
||||||
uint64_t sdmmc_wrapper_controller_close(int mmc_id)
|
uint64_t sdmmc_wrapper_controller_close(int mmc_id)
|
||||||
{
|
{
|
||||||
@@ -389,7 +414,7 @@ uint64_t sdmmc_wrapper_read(void *buf, uint64_t bufSize, int mmc_id, unsigned in
|
|||||||
if (first_sd_read)
|
if (first_sd_read)
|
||||||
{
|
{
|
||||||
first_sd_read = false;
|
first_sd_read = false;
|
||||||
if (emuMMC_ctx.EMMC_Type == emuMMC_SD)
|
if (emuMMC_ctx.EMMC_Type == emuMMC_SD_Raw)
|
||||||
{
|
{
|
||||||
// Because some SD cards have issues with emuMMC's driver
|
// Because some SD cards have issues with emuMMC's driver
|
||||||
// we currently swap to FS's driver after first SD read
|
// we currently swap to FS's driver after first SD read
|
||||||
@@ -400,7 +425,7 @@ uint64_t sdmmc_wrapper_read(void *buf, uint64_t bufSize, int mmc_id, unsigned in
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Call hekates driver.
|
// Call hekate's driver.
|
||||||
if (sdmmc_storage_read(&sd_storage, sector, num_sectors, buf))
|
if (sdmmc_storage_read(&sd_storage, sector, num_sectors, buf))
|
||||||
{
|
{
|
||||||
mutex_unlock_handler(mmc_id);
|
mutex_unlock_handler(mmc_id);
|
||||||
|
|||||||
@@ -52,6 +52,7 @@ void mutex_lock_handler(int mmc_id);
|
|||||||
void mutex_unlock_handler(int mmc_id);
|
void mutex_unlock_handler(int mmc_id);
|
||||||
|
|
||||||
// Hooks
|
// Hooks
|
||||||
|
uint64_t sdmmc_wrapper_controller_open(int mmc_id);
|
||||||
uint64_t sdmmc_wrapper_controller_close(int mmc_id);
|
uint64_t sdmmc_wrapper_controller_close(int mmc_id);
|
||||||
uint64_t sdmmc_wrapper_read(void *buf, uint64_t bufSize, int mmc_id, unsigned int sector, unsigned int num_sectors);
|
uint64_t sdmmc_wrapper_read(void *buf, uint64_t bufSize, int mmc_id, unsigned int sector, unsigned int num_sectors);
|
||||||
uint64_t sdmmc_wrapper_write(int mmc_id, unsigned int sector, unsigned int num_sectors, void *buf, uint64_t bufSize);
|
uint64_t sdmmc_wrapper_write(int mmc_id, unsigned int sector, unsigned int num_sectors, void *buf, uint64_t bufSize);
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ enum emuMMC_Type
|
|||||||
emuMMC_EMMC = 0,
|
emuMMC_EMMC = 0,
|
||||||
|
|
||||||
// SD Device raw
|
// SD Device raw
|
||||||
emuMMC_SD,
|
emuMMC_SD_Raw,
|
||||||
// SD Device File
|
// SD Device File
|
||||||
emuMMC_SD_File,
|
emuMMC_SD_File,
|
||||||
|
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ volatile __attribute__((aligned(0x1000))) emuMMC_ctx_t emuMMC_ctx = {
|
|||||||
.fs_ver = FS_VER_MAX,
|
.fs_ver = FS_VER_MAX,
|
||||||
|
|
||||||
// SD Default Metadata
|
// SD Default Metadata
|
||||||
.SD_Type = emuMMC_SD,
|
.SD_Type = emuMMC_SD_Raw,
|
||||||
.SD_StoragePartitionOffset = 0,
|
.SD_StoragePartitionOffset = 0,
|
||||||
|
|
||||||
// EMMC Default Metadata
|
// EMMC Default Metadata
|
||||||
@@ -285,6 +285,9 @@ void setup_hooks(void)
|
|||||||
INJECT_HOOK(fs_offsets->sdmmc_wrapper_read, sdmmc_wrapper_read);
|
INJECT_HOOK(fs_offsets->sdmmc_wrapper_read, sdmmc_wrapper_read);
|
||||||
// sdmmc_wrapper_write hook
|
// sdmmc_wrapper_write hook
|
||||||
INJECT_HOOK(fs_offsets->sdmmc_wrapper_write, sdmmc_wrapper_write);
|
INJECT_HOOK(fs_offsets->sdmmc_wrapper_write, sdmmc_wrapper_write);
|
||||||
|
// sdmmc_wrapper_controller_open hook
|
||||||
|
if (fs_offsets->sdmmc_accessor_controller_open)
|
||||||
|
INJECT_HOOK(fs_offsets->sdmmc_accessor_controller_open, sdmmc_wrapper_controller_open);
|
||||||
// sdmmc_wrapper_controller_close hook
|
// sdmmc_wrapper_controller_close hook
|
||||||
INJECT_HOOK(fs_offsets->sdmmc_accessor_controller_close, sdmmc_wrapper_controller_close);
|
INJECT_HOOK(fs_offsets->sdmmc_accessor_controller_close, sdmmc_wrapper_controller_close);
|
||||||
|
|
||||||
@@ -346,7 +349,7 @@ static void load_emummc_ctx(void)
|
|||||||
emuMMC_ctx.id = config.base_cfg.id;
|
emuMMC_ctx.id = config.base_cfg.id;
|
||||||
emuMMC_ctx.EMMC_Type = (enum emuMMC_Type)config.base_cfg.type;
|
emuMMC_ctx.EMMC_Type = (enum emuMMC_Type)config.base_cfg.type;
|
||||||
emuMMC_ctx.fs_ver = (enum FS_VER)config.base_cfg.fs_version;
|
emuMMC_ctx.fs_ver = (enum FS_VER)config.base_cfg.fs_version;
|
||||||
if (emuMMC_ctx.EMMC_Type == emuMMC_SD)
|
if (emuMMC_ctx.EMMC_Type == emuMMC_SD_Raw)
|
||||||
{
|
{
|
||||||
emuMMC_ctx.EMMC_StoragePartitionOffset = config.partition_cfg.start_sector;
|
emuMMC_ctx.EMMC_StoragePartitionOffset = config.partition_cfg.start_sector;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -72,6 +72,9 @@ namespace ams::secmon::boot {
|
|||||||
/* care of it here. Perhaps we should read the number of anti-downgrade fuses burnt, and translate that */
|
/* care of it here. Perhaps we should read the number of anti-downgrade fuses burnt, and translate that */
|
||||||
/* to the warmboot key? To be decided during the process of implementing ams-on-mariko support. */
|
/* to the warmboot key? To be decided during the process of implementing ams-on-mariko support. */
|
||||||
reg::Write(pmc + APBDEV_PMC_SECURE_SCRATCH32, 0x129);
|
reg::Write(pmc + APBDEV_PMC_SECURE_SCRATCH32, 0x129);
|
||||||
|
|
||||||
|
/* TODO: Fix to ensure correct scratch contents on mariko, as otherwise wb is broken. */
|
||||||
|
AMS_ABORT_UNLESS(fuse::GetSocType() != fuse::SocType_Mariko);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This function derives the master kek and device keys using the tsec root key. */
|
/* This function derives the master kek and device keys using the tsec root key. */
|
||||||
|
|||||||
@@ -960,7 +960,7 @@ namespace ams::secmon {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void SetupLogForBoot() {
|
void SetupLogForBoot() {
|
||||||
log::Initialize();
|
log::Initialize(secmon::GetLogPort(), secmon::GetLogBaudRate(), secmon::GetLogFlags());
|
||||||
log::SendText("OHAYO\n", 6);
|
log::SendText("OHAYO\n", 6);
|
||||||
log::Flush();
|
log::Flush();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ namespace ams::secmon::smc {
|
|||||||
[fuse::DramId_IcosaSamsung4GB] = pkg1::MemorySize_4GB,
|
[fuse::DramId_IcosaSamsung4GB] = pkg1::MemorySize_4GB,
|
||||||
[fuse::DramId_IcosaHynix4GB] = pkg1::MemorySize_4GB,
|
[fuse::DramId_IcosaHynix4GB] = pkg1::MemorySize_4GB,
|
||||||
[fuse::DramId_IcosaMicron4GB] = pkg1::MemorySize_4GB,
|
[fuse::DramId_IcosaMicron4GB] = pkg1::MemorySize_4GB,
|
||||||
[fuse::DramId_CopperSamsung4GB] = pkg1::MemorySize_4GB,
|
[fuse::DramId_FiveHynix1y4GB] = pkg1::MemorySize_4GB,
|
||||||
[fuse::DramId_IcosaSamsung6GB] = pkg1::MemorySize_6GB,
|
[fuse::DramId_IcosaSamsung6GB] = pkg1::MemorySize_6GB,
|
||||||
[fuse::DramId_CopperHynix4GB] = pkg1::MemorySize_4GB,
|
[fuse::DramId_CopperHynix4GB] = pkg1::MemorySize_4GB,
|
||||||
[fuse::DramId_CopperMicron4GB] = pkg1::MemorySize_4GB,
|
[fuse::DramId_CopperMicron4GB] = pkg1::MemorySize_4GB,
|
||||||
@@ -66,9 +66,13 @@ namespace ams::secmon::smc {
|
|||||||
[fuse::DramId_HoagSamsung1y4GBX] = pkg1::MemorySize_4GB,
|
[fuse::DramId_HoagSamsung1y4GBX] = pkg1::MemorySize_4GB,
|
||||||
[fuse::DramId_IowaSamsung1y4GBY] = pkg1::MemorySize_4GB,
|
[fuse::DramId_IowaSamsung1y4GBY] = pkg1::MemorySize_4GB,
|
||||||
[fuse::DramId_IowaSamsung1y8GBY] = pkg1::MemorySize_8GB,
|
[fuse::DramId_IowaSamsung1y8GBY] = pkg1::MemorySize_8GB,
|
||||||
[fuse::DramId_IowaSamsung1y4GBA] = pkg1::MemorySize_4GB,
|
[fuse::DramId_FiveSamsung1y4GB] = pkg1::MemorySize_4GB,
|
||||||
[fuse::DramId_FiveSamsung1y8GBX] = pkg1::MemorySize_8GB,
|
[fuse::DramId_HoagSamsung1y8GBX] = pkg1::MemorySize_8GB,
|
||||||
[fuse::DramId_FiveSamsung1y4GBX] = pkg1::MemorySize_4GB,
|
[fuse::DramId_FiveSamsung1y4GBX] = pkg1::MemorySize_4GB,
|
||||||
|
[fuse::DramId_IowaMicron1y4GB] = pkg1::MemorySize_4GB,
|
||||||
|
[fuse::DramId_HoagMicron1y4GB] = pkg1::MemorySize_4GB,
|
||||||
|
[fuse::DramId_FiveMicron1y4GB] = pkg1::MemorySize_4GB,
|
||||||
|
[fuse::DramId_FiveSamsung1y8GBX] = pkg1::MemorySize_8GB,
|
||||||
};
|
};
|
||||||
|
|
||||||
constexpr const pkg1::MemoryMode MemoryModes[] = {
|
constexpr const pkg1::MemoryMode MemoryModes[] = {
|
||||||
@@ -278,6 +282,10 @@ namespace ams::secmon::smc {
|
|||||||
return SmcResult::NotInitialized;
|
return SmcResult::NotInitialized;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case ConfigItem::ExosphereLogConfiguration:
|
||||||
|
/* Get the log configuration. */
|
||||||
|
args.r[1] = (static_cast<u64>(static_cast<u8>(secmon::GetLogPort())) << 32) | static_cast<u64>(secmon::GetLogBaudRate());
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return SmcResult::InvalidArgument;
|
return SmcResult::InvalidArgument;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,15 +40,16 @@ namespace ams::secmon::smc {
|
|||||||
Package2Hash = 17,
|
Package2Hash = 17,
|
||||||
|
|
||||||
/* Extension config items for exosphere. */
|
/* Extension config items for exosphere. */
|
||||||
ExosphereApiVersion = 65000,
|
ExosphereApiVersion = 65000,
|
||||||
ExosphereNeedsReboot = 65001,
|
ExosphereNeedsReboot = 65001,
|
||||||
ExosphereNeedsShutdown = 65002,
|
ExosphereNeedsShutdown = 65002,
|
||||||
ExosphereGitCommitHash = 65003,
|
ExosphereGitCommitHash = 65003,
|
||||||
ExosphereHasRcmBugPatch = 65004,
|
ExosphereHasRcmBugPatch = 65004,
|
||||||
ExosphereBlankProdInfo = 65005,
|
ExosphereBlankProdInfo = 65005,
|
||||||
ExosphereAllowCalWrites = 65006,
|
ExosphereAllowCalWrites = 65006,
|
||||||
ExosphereEmummcType = 65007,
|
ExosphereEmummcType = 65007,
|
||||||
ExospherePayloadAddress = 65008,
|
ExospherePayloadAddress = 65008,
|
||||||
|
ExosphereLogConfiguration = 65009,
|
||||||
};
|
};
|
||||||
|
|
||||||
SmcResult SmcGetConfigUser(SmcArguments &args);
|
SmcResult SmcGetConfigUser(SmcArguments &args);
|
||||||
|
|||||||
@@ -409,6 +409,7 @@ namespace ams::secmon::smc {
|
|||||||
/* NOTE: Nintendo only does this on dev, but we will always do it. */
|
/* NOTE: Nintendo only does this on dev, but we will always do it. */
|
||||||
if (true /* !pkg1::IsProduction() */) {
|
if (true /* !pkg1::IsProduction() */) {
|
||||||
log::SendText("OYASUMI\n", 8);
|
log::SendText("OYASUMI\n", 8);
|
||||||
|
log::Flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If we're on erista, configure the bootrom to allow our custom warmboot firmware. */
|
/* If we're on erista, configure the bootrom to allow our custom warmboot firmware. */
|
||||||
|
|||||||
@@ -34,11 +34,17 @@
|
|||||||
#define EXOSPHERE_FLAG_BLANK_PRODINFO (1 << 5u)
|
#define EXOSPHERE_FLAG_BLANK_PRODINFO (1 << 5u)
|
||||||
#define EXOSPHERE_FLAG_ALLOW_WRITING_TO_CAL_SYSMMC (1 << 6u)
|
#define EXOSPHERE_FLAG_ALLOW_WRITING_TO_CAL_SYSMMC (1 << 6u)
|
||||||
|
|
||||||
|
#define EXOSPHERE_LOG_FLAG_INVERTED (1 << 0u)
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t magic;
|
uint32_t magic;
|
||||||
uint32_t target_firmware;
|
uint32_t target_firmware;
|
||||||
uint32_t flags;
|
uint32_t flags[2];
|
||||||
uint32_t reserved[5];
|
uint16_t lcd_vendor;
|
||||||
|
uint8_t log_port;
|
||||||
|
uint8_t log_flags;
|
||||||
|
uint32_t log_baud_rate;
|
||||||
|
uint32_t reserved1[2];
|
||||||
exo_emummc_config_t emummc_cfg;
|
exo_emummc_config_t emummc_cfg;
|
||||||
} exosphere_config_t;
|
} exosphere_config_t;
|
||||||
|
|
||||||
@@ -54,6 +60,9 @@ _Static_assert(sizeof(exosphere_config_t) == 0x20 + sizeof(exo_emummc_config_t),
|
|||||||
#define EXOSPHERE_BLANK_PRODINFO_SYSMMC_KEY "blank_prodinfo_sysmmc"
|
#define EXOSPHERE_BLANK_PRODINFO_SYSMMC_KEY "blank_prodinfo_sysmmc"
|
||||||
#define EXOSPHERE_BLANK_PRODINFO_EMUMMC_KEY "blank_prodinfo_emummc"
|
#define EXOSPHERE_BLANK_PRODINFO_EMUMMC_KEY "blank_prodinfo_emummc"
|
||||||
#define EXOSPHERE_ALLOW_WRITING_TO_CAL_SYSMMC_KEY "allow_writing_to_cal_sysmmc"
|
#define EXOSPHERE_ALLOW_WRITING_TO_CAL_SYSMMC_KEY "allow_writing_to_cal_sysmmc"
|
||||||
|
#define EXOSPHERE_LOG_PORT_KEY "log_port"
|
||||||
|
#define EXOSPHERE_LOG_BAUD_RATE_KEY "log_baud_rate"
|
||||||
|
#define EXOSPHERE_LOG_INVERTED_KEY "log_inverted"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int debugmode;
|
int debugmode;
|
||||||
@@ -63,6 +72,9 @@ typedef struct {
|
|||||||
int blank_prodinfo_sysmmc;
|
int blank_prodinfo_sysmmc;
|
||||||
int blank_prodinfo_emummc;
|
int blank_prodinfo_emummc;
|
||||||
int allow_writing_to_cal_sysmmc;
|
int allow_writing_to_cal_sysmmc;
|
||||||
|
int log_port;
|
||||||
|
int log_baud_rate;
|
||||||
|
int log_inverted;
|
||||||
} exosphere_parse_cfg_t;
|
} exosphere_parse_cfg_t;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -543,8 +543,8 @@ static const instruction_t MAKE_KERNEL_PATCH_NAME(1000, proc_id_recv)[] = {0xA9B
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
stp x10, x11, [sp, #-0x10]!
|
stp x10, x11, [sp, #-0x10]!
|
||||||
ldr x11, [sp, #0x90]
|
ldr x11, [sp, #0x80]
|
||||||
mov w10, w28
|
mov w10, #3
|
||||||
lsl x10, x10, #2
|
lsl x10, x10, #2
|
||||||
ldr x10, [x11, x10]
|
ldr x10, [x11, x10]
|
||||||
mov x9, #0x0000ffffffffffff
|
mov x9, #0x0000ffffffffffff
|
||||||
@@ -567,11 +567,11 @@ static const instruction_t MAKE_KERNEL_PATCH_NAME(1000, proc_id_recv)[] = {0xA9B
|
|||||||
mov x0, x8
|
mov x0, x8
|
||||||
*/
|
*/
|
||||||
static const uint8_t MAKE_KERNEL_PATTERN_NAME(1100, proc_id_send)[] = {0xE0, 0x03, 0x15, 0xAA, 0xA8, 0x02, 0x40, 0xF9, 0x08, 0x1D, 0x40, 0xF9, 0x00, 0x01, 0x3F, 0xD6, 0x88, 0x4A, 0x3C, 0x8B, 0x09, 0xFC, 0x60, 0xD3, 0x00, 0x25, 0x00, 0x29};
|
static const uint8_t MAKE_KERNEL_PATTERN_NAME(1100, proc_id_send)[] = {0xE0, 0x03, 0x15, 0xAA, 0xA8, 0x02, 0x40, 0xF9, 0x08, 0x1D, 0x40, 0xF9, 0x00, 0x01, 0x3F, 0xD6, 0x88, 0x4A, 0x3C, 0x8B, 0x09, 0xFC, 0x60, 0xD3, 0x00, 0x25, 0x00, 0x29};
|
||||||
static const instruction_t MAKE_KERNEL_PATCH_NAME(1100, proc_id_send)[] = {0xA9BF2FEA, 0xF9404BEB, 0x2A1C03EA, 0xD37EF54A, 0xF86A696A, 0x92FFFFE9, 0x8A090148, 0xD2FFFFE9, 0x8A09014A, 0xD2FFFFC9, 0xEB09015F, 0x54FFFFA0, 0xA9BF27E8, 0xF94002A8, 0xF9401D08, 0xAA1503E0, 0xD63F0100, 0xA8C127E8, 0xAA0003E8, 0xA8C12FEA, 0xAA0803E0};
|
static const instruction_t MAKE_KERNEL_PATCH_NAME(1100, proc_id_send)[] = {0xA9BF2FEA, 0xF94043EB, 0x5280006A, 0xD37EF54A, 0xF86A696A, 0x92FFFFE9, 0x8A090148, 0xD2FFFFE9, 0x8A09014A, 0xD2FFFFC9, 0xEB09015F, 0x54000100, 0xA9BF27E8, 0xF94002A8, 0xF9401D08, 0xAA1503E0, 0xD63F0100, 0xA8C127E8, 0xAA0003E8, 0xA8C12FEA, 0xAA0803E0};
|
||||||
/*
|
/*
|
||||||
stp x10, x11, [sp, #-0x10]!
|
stp x10, x11, [sp, #-0x10]!
|
||||||
ldr x11, [sp, #0xE0]
|
ldr x11, [sp, #0xE0]
|
||||||
ldr w10, [sp, #0xC0]
|
mov w10, #3
|
||||||
lsl x10, x10, #2
|
lsl x10, x10, #2
|
||||||
ldr x10, [x11, x10]
|
ldr x10, [x11, x10]
|
||||||
mov x9, #0x0000ffffffffffff
|
mov x9, #0x0000ffffffffffff
|
||||||
@@ -594,7 +594,7 @@ static const instruction_t MAKE_KERNEL_PATCH_NAME(1100, proc_id_send)[] = {0xA9B
|
|||||||
mov x0, x8
|
mov x0, x8
|
||||||
*/
|
*/
|
||||||
static const uint8_t MAKE_KERNEL_PATTERN_NAME(1100, proc_id_recv)[] = {0x08, 0x03, 0x40, 0xF9, 0xE0, 0x03, 0x18, 0xAA, 0x08, 0x1D, 0x40, 0xF9, 0x00, 0x01, 0x3F, 0xD6, 0xE8, 0x7F, 0x40, 0xF9, 0x09, 0xFC, 0x60, 0xD3, 0xEA, 0x5B, 0x40, 0xF9};
|
static const uint8_t MAKE_KERNEL_PATTERN_NAME(1100, proc_id_recv)[] = {0x08, 0x03, 0x40, 0xF9, 0xE0, 0x03, 0x18, 0xAA, 0x08, 0x1D, 0x40, 0xF9, 0x00, 0x01, 0x3F, 0xD6, 0xE8, 0x7F, 0x40, 0xF9, 0x09, 0xFC, 0x60, 0xD3, 0xEA, 0x5B, 0x40, 0xF9};
|
||||||
static const instruction_t MAKE_KERNEL_PATCH_NAME(1100, proc_id_recv)[] = {0xA9BF2FEA, 0xF94073EB, 0xB940C3EA, 0xD37EF54A, 0xF86A696A, 0x92FFFFE9, 0x8A090148, 0xD2FFFFE9, 0x8A09014A, 0xD2FFFFC9, 0xEB09015F, 0x54FFFFA0, 0xA9BF27E8, 0xF9400308, 0xF9401D08, 0xAA1803E0, 0xD63F0100, 0xA8C127E8, 0xAA0003E8, 0xA8C12FEA, 0xAA0803E0};
|
static const instruction_t MAKE_KERNEL_PATCH_NAME(1100, proc_id_recv)[] = {0xA9BF2FEA, 0xF94073EB, 0x5280006A, 0xD37EF54A, 0xF86A696A, 0x92FFFFE9, 0x8A090148, 0xD2FFFFE9, 0x8A09014A, 0xD2FFFFC9, 0xEB09015F, 0x54000100, 0xA9BF27E8, 0xF9400308, 0xF9401D08, 0xAA1803E0, 0xD63F0100, 0xA8C127E8, 0xAA0003E8, 0xA8C12FEA, 0xAA0803E0};
|
||||||
|
|
||||||
/* svcControlCodeMemory Patches */
|
/* svcControlCodeMemory Patches */
|
||||||
/* b.eq -> nop */
|
/* b.eq -> nop */
|
||||||
@@ -906,6 +906,35 @@ 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,
|
#define KERNEL_PATCHES(vers) .num_patches = sizeof(g_kernel_patches_##vers)/sizeof(kernel_patch_t), .patches = g_kernel_patches_##vers,
|
||||||
|
|
||||||
/* Kernel Infos. */
|
/* Kernel Infos. */
|
||||||
@@ -1000,6 +1029,15 @@ static const kernel_info_t g_kernel_infos[] = {
|
|||||||
.embedded_ini_ptr = 0x180,
|
.embedded_ini_ptr = 0x180,
|
||||||
.free_code_space_offset = 0x49EE8,
|
.free_code_space_offset = 0x49EE8,
|
||||||
KERNEL_PATCHES(1100)
|
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)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1090,7 +1128,7 @@ void package2_patch_kernel(void *_kernel, size_t *kernel_size, bool is_sd_kernel
|
|||||||
|
|
||||||
uint8_t *pattern_loc = search_pattern(kernel, *kernel_size, kernel_info->patches[i].pattern, kernel_info->patches[i].pattern_size);
|
uint8_t *pattern_loc = search_pattern(kernel, *kernel_size, kernel_info->patches[i].pattern, kernel_info->patches[i].pattern_size);
|
||||||
if (pattern_loc == NULL) {
|
if (pattern_loc == NULL) {
|
||||||
/* TODO: Should we print an error/abort here? */
|
fatal_error("kernel_patcher: failed to identify patch location!\n");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
/* Patch kernel to branch to our hook at the desired place. */
|
/* Patch kernel to branch to our hook at the desired place. */
|
||||||
|
|||||||
@@ -196,6 +196,27 @@ static int exosphere_ini_handler(void *user, const char *section, const char *na
|
|||||||
} else if (tmp == 0) {
|
} else if (tmp == 0) {
|
||||||
parse_cfg->allow_writing_to_cal_sysmmc = 0;
|
parse_cfg->allow_writing_to_cal_sysmmc = 0;
|
||||||
}
|
}
|
||||||
|
} else if (strcmp(name, EXOSPHERE_LOG_PORT_KEY) == 0) {
|
||||||
|
sscanf(value, "%d", &tmp);
|
||||||
|
if (0 <= tmp && tmp < 4) {
|
||||||
|
parse_cfg->log_port = tmp;
|
||||||
|
} else {
|
||||||
|
parse_cfg->log_port = 0;
|
||||||
|
}
|
||||||
|
} else if (strcmp(name, EXOSPHERE_LOG_BAUD_RATE_KEY) == 0) {
|
||||||
|
sscanf(value, "%d", &tmp);
|
||||||
|
if (tmp > 0) {
|
||||||
|
parse_cfg->log_baud_rate = tmp;
|
||||||
|
} else {
|
||||||
|
parse_cfg->log_baud_rate = 115200;
|
||||||
|
}
|
||||||
|
} else if (strcmp(name, EXOSPHERE_LOG_INVERTED_KEY) == 0) {
|
||||||
|
sscanf(value, "%d", &tmp);
|
||||||
|
if (tmp == 1) {
|
||||||
|
parse_cfg->log_inverted = 1;
|
||||||
|
} else if (tmp == 0) {
|
||||||
|
parse_cfg->log_inverted = 0;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -240,6 +261,7 @@ static uint32_t nxboot_get_specific_target_firmware(uint32_t target_firmware){
|
|||||||
#define CHECK_NCA(NCA_ID, VERSION) do { if (is_nca_present(NCA_ID)) { return ATMOSPHERE_TARGET_FIRMWARE_##VERSION; } } while(0)
|
#define CHECK_NCA(NCA_ID, VERSION) do { if (is_nca_present(NCA_ID)) { return ATMOSPHERE_TARGET_FIRMWARE_##VERSION; } } while(0)
|
||||||
|
|
||||||
if (target_firmware >= ATMOSPHERE_TARGET_FIRMWARE_11_0_0) {
|
if (target_firmware >= ATMOSPHERE_TARGET_FIRMWARE_11_0_0) {
|
||||||
|
CHECK_NCA("56211c7a5ed20a5332f5cdda67121e37", 11_0_1);
|
||||||
CHECK_NCA("594c90bcdbcccad6b062eadba0cd0e7e", 11_0_0);
|
CHECK_NCA("594c90bcdbcccad6b062eadba0cd0e7e", 11_0_0);
|
||||||
} else if (target_firmware >= ATMOSPHERE_TARGET_FIRMWARE_10_0_0) {
|
} else if (target_firmware >= ATMOSPHERE_TARGET_FIRMWARE_10_0_0) {
|
||||||
CHECK_NCA("26325de4db3909e0ef2379787c7e671d", 10_2_0);
|
CHECK_NCA("26325de4db3909e0ef2379787c7e671d", 10_2_0);
|
||||||
@@ -464,9 +486,9 @@ static void nxboot_configure_exosphere(uint32_t target_firmware, unsigned int ke
|
|||||||
const bool is_emummc = exo_emummc_cfg->base_cfg.magic == MAGIC_EMUMMC_CONFIG && exo_emummc_cfg->base_cfg.type != EMUMMC_TYPE_NONE;
|
const bool is_emummc = exo_emummc_cfg->base_cfg.magic == MAGIC_EMUMMC_CONFIG && exo_emummc_cfg->base_cfg.type != EMUMMC_TYPE_NONE;
|
||||||
|
|
||||||
if (keygen_type) {
|
if (keygen_type) {
|
||||||
exo_cfg.flags = EXOSPHERE_FLAG_PERFORM_620_KEYGEN;
|
exo_cfg.flags[0] = EXOSPHERE_FLAG_PERFORM_620_KEYGEN;
|
||||||
} else {
|
} else {
|
||||||
exo_cfg.flags = 0;
|
exo_cfg.flags[0] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Setup exosphere parse configuration with defaults. */
|
/* Setup exosphere parse configuration with defaults. */
|
||||||
@@ -478,6 +500,9 @@ static void nxboot_configure_exosphere(uint32_t target_firmware, unsigned int ke
|
|||||||
.blank_prodinfo_sysmmc = 0,
|
.blank_prodinfo_sysmmc = 0,
|
||||||
.blank_prodinfo_emummc = 0,
|
.blank_prodinfo_emummc = 0,
|
||||||
.allow_writing_to_cal_sysmmc = 0,
|
.allow_writing_to_cal_sysmmc = 0,
|
||||||
|
.log_port = 0,
|
||||||
|
.log_baud_rate = 115200,
|
||||||
|
.log_inverted = 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* If we have an ini to read, parse it. */
|
/* If we have an ini to read, parse it. */
|
||||||
@@ -490,13 +515,17 @@ static void nxboot_configure_exosphere(uint32_t target_firmware, unsigned int ke
|
|||||||
free(exosphere_ini);
|
free(exosphere_ini);
|
||||||
|
|
||||||
/* Apply parse config. */
|
/* Apply parse config. */
|
||||||
if (parse_cfg.debugmode) exo_cfg.flags |= EXOSPHERE_FLAG_IS_DEBUGMODE_PRIV;
|
if (parse_cfg.debugmode) exo_cfg.flags[0] |= EXOSPHERE_FLAG_IS_DEBUGMODE_PRIV;
|
||||||
if (parse_cfg.debugmode_user) exo_cfg.flags |= EXOSPHERE_FLAG_IS_DEBUGMODE_USER;
|
if (parse_cfg.debugmode_user) exo_cfg.flags[0] |= EXOSPHERE_FLAG_IS_DEBUGMODE_USER;
|
||||||
if (parse_cfg.disable_user_exception_handlers) exo_cfg.flags |= EXOSPHERE_FLAG_DISABLE_USERMODE_EXCEPTION_HANDLERS;
|
if (parse_cfg.disable_user_exception_handlers) exo_cfg.flags[0] |= EXOSPHERE_FLAG_DISABLE_USERMODE_EXCEPTION_HANDLERS;
|
||||||
if (parse_cfg.enable_user_pmu_access) exo_cfg.flags |= EXOSPHERE_FLAG_ENABLE_USERMODE_PMU_ACCESS;
|
if (parse_cfg.enable_user_pmu_access) exo_cfg.flags[0] |= EXOSPHERE_FLAG_ENABLE_USERMODE_PMU_ACCESS;
|
||||||
if (parse_cfg.blank_prodinfo_sysmmc && !is_emummc) exo_cfg.flags |= EXOSPHERE_FLAG_BLANK_PRODINFO;
|
if (parse_cfg.blank_prodinfo_sysmmc && !is_emummc) exo_cfg.flags[0] |= EXOSPHERE_FLAG_BLANK_PRODINFO;
|
||||||
if (parse_cfg.blank_prodinfo_emummc && is_emummc) exo_cfg.flags |= EXOSPHERE_FLAG_BLANK_PRODINFO;
|
if (parse_cfg.blank_prodinfo_emummc && is_emummc) exo_cfg.flags[0] |= EXOSPHERE_FLAG_BLANK_PRODINFO;
|
||||||
if (parse_cfg.allow_writing_to_cal_sysmmc) exo_cfg.flags |= EXOSPHERE_FLAG_ALLOW_WRITING_TO_CAL_SYSMMC;
|
if (parse_cfg.allow_writing_to_cal_sysmmc) exo_cfg.flags[0] |= EXOSPHERE_FLAG_ALLOW_WRITING_TO_CAL_SYSMMC;
|
||||||
|
|
||||||
|
exo_cfg.log_port = parse_cfg.log_port;
|
||||||
|
exo_cfg.log_baud_rate = parse_cfg.log_baud_rate;
|
||||||
|
if (parse_cfg.log_inverted) exo_cfg.log_flags |= EXOSPHERE_LOG_FLAG_INVERTED;
|
||||||
|
|
||||||
if ((exo_cfg.target_firmware < ATMOSPHERE_TARGET_FIRMWARE_MIN) || (exo_cfg.target_firmware > ATMOSPHERE_TARGET_FIRMWARE_MAX)) {
|
if ((exo_cfg.target_firmware < ATMOSPHERE_TARGET_FIRMWARE_MIN) || (exo_cfg.target_firmware > ATMOSPHERE_TARGET_FIRMWARE_MAX)) {
|
||||||
fatal_error("[NXBOOT] Invalid Exosphere target firmware!\n");
|
fatal_error("[NXBOOT] Invalid Exosphere target firmware!\n");
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
[subrepo]
|
[subrepo]
|
||||||
remote = https://github.com/Atmosphere-NX/Atmosphere-libs
|
remote = https://github.com/Atmosphere-NX/Atmosphere-libs
|
||||||
branch = master
|
branch = master
|
||||||
commit = 10e9e0e8f926b11c2c7de16ffe15bea7d7ec2cdf
|
commit = 5a18bea64545105c52d642d7789029b5ca875864
|
||||||
parent = 2ee2a4f1ac04bc7f15de8be8d57ad04d7e73f735
|
parent = 17c8c390fc84d059b89f563a8fae6936649d0d45
|
||||||
method = merge
|
method = merge
|
||||||
cmdver = 0.4.1
|
cmdver = 0.4.1
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ include $(dir $(abspath $(lastword $(MAKEFILE_LIST))))/../common.mk
|
|||||||
# options for code generation
|
# options for code generation
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
export DEFINES := $(ATMOSPHERE_DEFINES) -DATMOSPHERE_IS_MESOSPHERE
|
export DEFINES := $(ATMOSPHERE_DEFINES) -DATMOSPHERE_IS_MESOSPHERE
|
||||||
export SETTINGS := $(ATMOSPHERE_SETTINGS) -O2 -mgeneral-regs-only -ffixed-x18 -Wextra -Werror -fno-non-call-exceptions
|
export SETTINGS := $(ATMOSPHERE_SETTINGS) -Os -mgeneral-regs-only -ffixed-x18 -Wextra -Werror -fno-non-call-exceptions
|
||||||
export CFLAGS := $(ATMOSPHERE_CFLAGS) $(SETTINGS) $(DEFINES) $(INCLUDE)
|
export CFLAGS := $(ATMOSPHERE_CFLAGS) $(SETTINGS) $(DEFINES) $(INCLUDE)
|
||||||
export CXXFLAGS := $(CFLAGS) $(ATMOSPHERE_CXXFLAGS) -fno-use-cxa-atexit
|
export CXXFLAGS := $(CFLAGS) $(ATMOSPHERE_CXXFLAGS) -fno-use-cxa-atexit
|
||||||
export ASFLAGS := $(ATMOSPHERE_ASFLAGS) $(SETTINGS) $(DEFINES) $(INCLUDE)
|
export ASFLAGS := $(ATMOSPHERE_ASFLAGS) $(SETTINGS) $(DEFINES) $(INCLUDE)
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ namespace ams::fuse {
|
|||||||
DramId_IcosaSamsung4GB = 0,
|
DramId_IcosaSamsung4GB = 0,
|
||||||
DramId_IcosaHynix4GB = 1,
|
DramId_IcosaHynix4GB = 1,
|
||||||
DramId_IcosaMicron4GB = 2,
|
DramId_IcosaMicron4GB = 2,
|
||||||
DramId_CopperSamsung4GB = 3,
|
DramId_FiveHynix1y4GB = 3,
|
||||||
DramId_IcosaSamsung6GB = 4,
|
DramId_IcosaSamsung6GB = 4,
|
||||||
DramId_CopperHynix4GB = 5,
|
DramId_CopperHynix4GB = 5,
|
||||||
DramId_CopperMicron4GB = 6,
|
DramId_CopperMicron4GB = 6,
|
||||||
@@ -70,9 +70,13 @@ namespace ams::fuse {
|
|||||||
DramId_HoagSamsung1y4GBX = 19,
|
DramId_HoagSamsung1y4GBX = 19,
|
||||||
DramId_IowaSamsung1y4GBY = 20,
|
DramId_IowaSamsung1y4GBY = 20,
|
||||||
DramId_IowaSamsung1y8GBY = 21,
|
DramId_IowaSamsung1y8GBY = 21,
|
||||||
DramId_IowaSamsung1y4GBA = 22,
|
DramId_FiveSamsung1y4GB = 22,
|
||||||
DramId_FiveSamsung1y8GBX = 23,
|
DramId_HoagSamsung1y8GBX = 23,
|
||||||
DramId_FiveSamsung1y4GBX = 24,
|
DramId_FiveSamsung1y4GBX = 24,
|
||||||
|
DramId_IowaMicron1y4GB = 25,
|
||||||
|
DramId_HoagMicron1y4GB = 26,
|
||||||
|
DramId_FiveMicron1y4GB = 27,
|
||||||
|
DramId_FiveSamsung1y8GBX = 28,
|
||||||
|
|
||||||
DramId_Count,
|
DramId_Count,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ namespace ams::log {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
void Initialize();
|
void Initialize();
|
||||||
|
void Initialize(uart::Port port, u32 baud_rate, u32 flags);
|
||||||
void Finalize();
|
void Finalize();
|
||||||
|
|
||||||
void Printf(const char *fmt, ...) __attribute__((format(printf, 1, 2)));
|
void Printf(const char *fmt, ...) __attribute__((format(printf, 1, 2)));
|
||||||
|
|||||||
@@ -116,6 +116,18 @@ namespace ams::secmon {
|
|||||||
return GetSecmonConfiguration().GetLcdVendor();
|
return GetSecmonConfiguration().GetLcdVendor();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ALWAYS_INLINE uart::Port GetLogPort() {
|
||||||
|
return GetSecmonConfiguration().GetLogPort();
|
||||||
|
}
|
||||||
|
|
||||||
|
ALWAYS_INLINE u8 GetLogFlags() {
|
||||||
|
return GetSecmonConfiguration().GetLogFlags();
|
||||||
|
}
|
||||||
|
|
||||||
|
ALWAYS_INLINE u32 GetLogBaudRate() {
|
||||||
|
return GetSecmonConfiguration().GetLogBaudRate();
|
||||||
|
}
|
||||||
|
|
||||||
ALWAYS_INLINE bool IsProduction() {
|
ALWAYS_INLINE bool IsProduction() {
|
||||||
return GetSecmonConfiguration().IsProduction();
|
return GetSecmonConfiguration().IsProduction();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <vapours.hpp>
|
#include <vapours.hpp>
|
||||||
#include <exosphere/fuse.hpp>
|
#include <exosphere/fuse.hpp>
|
||||||
|
#include <exosphere/uart.hpp>
|
||||||
#include <exosphere/secmon/secmon_emummc_context.hpp>
|
#include <exosphere/secmon/secmon_emummc_context.hpp>
|
||||||
|
|
||||||
namespace ams::secmon {
|
namespace ams::secmon {
|
||||||
@@ -39,8 +40,10 @@ namespace ams::secmon {
|
|||||||
ams::TargetFirmware target_firmware;
|
ams::TargetFirmware target_firmware;
|
||||||
u32 flags[2];
|
u32 flags[2];
|
||||||
u16 lcd_vendor;
|
u16 lcd_vendor;
|
||||||
u16 reserved0;
|
u8 log_port;
|
||||||
u32 reserved1[3];
|
u8 log_flags;
|
||||||
|
u32 log_baud_rate;
|
||||||
|
u32 reserved1[2];
|
||||||
EmummcConfiguration emummc_cfg;
|
EmummcConfiguration emummc_cfg;
|
||||||
|
|
||||||
constexpr bool IsValid() const { return this->magic == Magic; }
|
constexpr bool IsValid() const { return this->magic == Magic; }
|
||||||
@@ -54,17 +57,22 @@ namespace ams::secmon {
|
|||||||
u8 hardware_type;
|
u8 hardware_type;
|
||||||
u8 soc_type;
|
u8 soc_type;
|
||||||
u8 hardware_state;
|
u8 hardware_state;
|
||||||
u8 pad_0B[1];
|
u8 log_port;
|
||||||
u32 flags[2];
|
u32 flags[2];
|
||||||
u16 lcd_vendor;
|
u16 lcd_vendor;
|
||||||
u16 reserved0;
|
u8 log_flags;
|
||||||
u32 reserved1[(0x80 - 0x18) / sizeof(u32)];
|
u8 reserved0;
|
||||||
|
u32 log_baud_rate;
|
||||||
|
u32 reserved1[(0x80 - 0x1C) / sizeof(u32)];
|
||||||
|
|
||||||
constexpr void CopyFrom(const SecureMonitorStorageConfiguration &storage) {
|
constexpr void CopyFrom(const SecureMonitorStorageConfiguration &storage) {
|
||||||
this->target_firmware = storage.target_firmware;
|
this->target_firmware = storage.target_firmware;
|
||||||
this->flags[0] = storage.flags[0];
|
this->flags[0] = storage.flags[0];
|
||||||
this->flags[1] = storage.flags[1];
|
this->flags[1] = storage.flags[1];
|
||||||
this->lcd_vendor = storage.lcd_vendor;
|
this->lcd_vendor = storage.lcd_vendor;
|
||||||
|
this->log_port = storage.log_port;
|
||||||
|
this->log_flags = storage.log_flags;
|
||||||
|
this->log_baud_rate = storage.log_baud_rate != 0 ? storage.log_baud_rate : 115200;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetFuseInfo() {
|
void SetFuseInfo() {
|
||||||
@@ -78,9 +86,13 @@ namespace ams::secmon {
|
|||||||
constexpr fuse::HardwareType GetHardwareType() const { return static_cast<fuse::HardwareType>(this->hardware_type); }
|
constexpr fuse::HardwareType GetHardwareType() const { return static_cast<fuse::HardwareType>(this->hardware_type); }
|
||||||
constexpr fuse::SocType GetSocType() const { return static_cast<fuse::SocType>(this->soc_type); }
|
constexpr fuse::SocType GetSocType() const { return static_cast<fuse::SocType>(this->soc_type); }
|
||||||
constexpr fuse::HardwareState GetHardwareState() const { return static_cast<fuse::HardwareState>(this->hardware_state); }
|
constexpr fuse::HardwareState GetHardwareState() const { return static_cast<fuse::HardwareState>(this->hardware_state); }
|
||||||
|
constexpr uart::Port GetLogPort() const { return static_cast<uart::Port>(this->log_port); }
|
||||||
|
constexpr u8 GetLogFlags() const { return this->log_flags; }
|
||||||
|
|
||||||
constexpr u16 GetLcdVendor() const { return this->lcd_vendor; }
|
constexpr u16 GetLcdVendor() const { return this->lcd_vendor; }
|
||||||
|
|
||||||
|
constexpr u32 GetLogBaudRate() const { return this->log_baud_rate; }
|
||||||
|
|
||||||
constexpr bool IsProduction() const { return this->GetHardwareState() != fuse::HardwareState_Development; }
|
constexpr bool IsProduction() const { return this->GetHardwareState() != fuse::HardwareState_Development; }
|
||||||
|
|
||||||
constexpr bool IsDevelopmentFunctionEnabledForKernel() const { return (this->flags[0] & SecureMonitorConfigurationFlag_IsDevelopmentFunctionEnabledForKernel) != 0; }
|
constexpr bool IsDevelopmentFunctionEnabledForKernel() const { return (this->flags[0] & SecureMonitorConfigurationFlag_IsDevelopmentFunctionEnabledForKernel) != 0; }
|
||||||
@@ -101,10 +113,12 @@ namespace ams::secmon {
|
|||||||
.hardware_type = {},
|
.hardware_type = {},
|
||||||
.soc_type = {},
|
.soc_type = {},
|
||||||
.hardware_state = {},
|
.hardware_state = {},
|
||||||
.pad_0B = {},
|
.log_port = uart::Port_ReservedDebug,
|
||||||
.flags = { SecureMonitorConfigurationFlag_Default, SecureMonitorConfigurationFlag_None },
|
.flags = { SecureMonitorConfigurationFlag_Default, SecureMonitorConfigurationFlag_None },
|
||||||
.lcd_vendor = {},
|
.lcd_vendor = {},
|
||||||
|
.log_flags = {},
|
||||||
.reserved0 = {},
|
.reserved0 = {},
|
||||||
|
.log_baud_rate = 115200,
|
||||||
.reserved1 = {},
|
.reserved1 = {},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -19,58 +19,46 @@ namespace ams::log {
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
constexpr inline uart::Port UartLogPort = uart::Port_ReservedDebug;
|
constexpr inline uart::Port DefaultLogPort = uart::Port_ReservedDebug;
|
||||||
constexpr inline int UartBaudRate = 115200;
|
constexpr inline u32 DefaultLogFlags = static_cast<u32>(uart::Flag_None);
|
||||||
|
constexpr inline int DefaultBaudRate = 115200;
|
||||||
|
constinit uart::Port g_log_port = DefaultLogPort;
|
||||||
constinit bool g_initialized_uart = false;
|
constinit bool g_initialized_uart = false;
|
||||||
|
|
||||||
constexpr inline u32 UartPortFlags = [] {
|
ALWAYS_INLINE void SetupUartClock(uart::Port port) {
|
||||||
if constexpr (UartLogPort == uart::Port_ReservedDebug) {
|
/* The debug port must always be set up, for compatibility with official hos. */
|
||||||
/* Logging to the debug port. */
|
pinmux::SetupUartA();
|
||||||
/* Don't invert transactions. */
|
clkrst::EnableUartAClock();
|
||||||
return uart::Flag_None;
|
|
||||||
} else if constexpr (UartLogPort == uart::Port_LeftJoyCon) {
|
|
||||||
/* Logging to left joy-con (e.g. with Joyless). */
|
|
||||||
/* Invert transactions. */
|
|
||||||
return uart::Flag_Inverted;
|
|
||||||
} else if constexpr (UartLogPort == uart::Port_RightJoyCon) {
|
|
||||||
/* Logging to right joy-con (e.g. with Joyless). */
|
|
||||||
/* Invert transactions. */
|
|
||||||
return uart::Flag_Inverted;
|
|
||||||
} else {
|
|
||||||
__builtin_unreachable();
|
|
||||||
}
|
|
||||||
}();
|
|
||||||
|
|
||||||
ALWAYS_INLINE void SetupUart() {
|
/* If logging to a joy-con port, configure appropriately. */
|
||||||
if constexpr (UartLogPort == uart::Port_ReservedDebug) {
|
if (port == uart::Port_LeftJoyCon) {
|
||||||
/* Logging to the debug port. */
|
|
||||||
pinmux::SetupUartA();
|
|
||||||
clkrst::EnableUartAClock();
|
|
||||||
} else if constexpr (UartLogPort == uart::Port_LeftJoyCon) {
|
|
||||||
/* Logging to left joy-con (e.g. with Joyless). */
|
/* Logging to left joy-con (e.g. with Joyless). */
|
||||||
static_assert(uart::Port_LeftJoyCon == uart::Port_C);
|
static_assert(uart::Port_LeftJoyCon == uart::Port_C);
|
||||||
pinmux::SetupUartC();
|
pinmux::SetupUartC();
|
||||||
clkrst::EnableUartCClock();
|
clkrst::EnableUartCClock();
|
||||||
} else if constexpr (UartLogPort == uart::Port_RightJoyCon) {
|
} else if (port == uart::Port_RightJoyCon) {
|
||||||
/* Logging to right joy-con (e.g. with Joyless). */
|
/* Logging to right joy-con (e.g. with Joyless). */
|
||||||
static_assert(uart::Port_RightJoyCon == uart::Port_B);
|
static_assert(uart::Port_RightJoyCon == uart::Port_B);
|
||||||
pinmux::SetupUartB();
|
pinmux::SetupUartB();
|
||||||
clkrst::EnableUartBClock();
|
clkrst::EnableUartBClock();
|
||||||
} else {
|
|
||||||
__builtin_unreachable();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Initialize() {
|
void Initialize() {
|
||||||
|
return Initialize(DefaultLogPort, DefaultBaudRate, DefaultLogFlags);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Initialize(uart::Port port, u32 baud_rate, u32 flags) {
|
||||||
/* Initialize pinmux and clock for the target uart port. */
|
/* Initialize pinmux and clock for the target uart port. */
|
||||||
SetupUart();
|
SetupUartClock(port);
|
||||||
|
|
||||||
/* Initialize the target uart port. */
|
/* Initialize the target uart port. */
|
||||||
uart::Initialize(UartLogPort, UartBaudRate, UartPortFlags);
|
uart::Initialize(port, baud_rate, flags);
|
||||||
|
|
||||||
/* Note that we've initialized. */
|
/* Note that we've initialized. */
|
||||||
|
g_log_port = port;
|
||||||
g_initialized_uart = true;
|
g_initialized_uart = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -84,7 +72,7 @@ namespace ams::log {
|
|||||||
const auto len = util::TVSNPrintf(log_buf, sizeof(log_buf), fmt, vl);
|
const auto len = util::TVSNPrintf(log_buf, sizeof(log_buf), fmt, vl);
|
||||||
|
|
||||||
if (g_initialized_uart) {
|
if (g_initialized_uart) {
|
||||||
uart::SendText(UartLogPort, log_buf, len);
|
uart::SendText(g_log_port, log_buf, len);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -115,13 +103,13 @@ namespace ams::log {
|
|||||||
|
|
||||||
void SendText(const void *text, size_t size) {
|
void SendText(const void *text, size_t size) {
|
||||||
if (g_initialized_uart) {
|
if (g_initialized_uart) {
|
||||||
uart::SendText(UartLogPort, text, size);
|
uart::SendText(g_log_port, text, size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Flush() {
|
void Flush() {
|
||||||
if (g_initialized_uart) {
|
if (g_initialized_uart) {
|
||||||
uart::WaitFlush(UartLogPort);
|
uart::WaitFlush(g_log_port);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ include $(CURRENT_DIRECTORY)/../config/common.mk
|
|||||||
PRECOMPILED_HEADERS := include/mesosphere.hpp
|
PRECOMPILED_HEADERS := include/mesosphere.hpp
|
||||||
|
|
||||||
DEFINES := $(ATMOSPHERE_DEFINES) -DATMOSPHERE_IS_MESOSPHERE
|
DEFINES := $(ATMOSPHERE_DEFINES) -DATMOSPHERE_IS_MESOSPHERE
|
||||||
SETTINGS := $(ATMOSPHERE_SETTINGS) -O2 -mgeneral-regs-only -ffixed-x18 -Wextra -Werror -fno-non-call-exceptions
|
SETTINGS := $(ATMOSPHERE_SETTINGS) -Os -mgeneral-regs-only -ffixed-x18 -Wextra -Werror -fno-non-call-exceptions
|
||||||
CFLAGS := $(ATMOSPHERE_CFLAGS) $(SETTINGS) $(DEFINES) $(INCLUDE)
|
CFLAGS := $(ATMOSPHERE_CFLAGS) $(SETTINGS) $(DEFINES) $(INCLUDE)
|
||||||
CXXFLAGS := $(CFLAGS) $(ATMOSPHERE_CXXFLAGS) -fno-use-cxa-atexit -flto
|
CXXFLAGS := $(CFLAGS) $(ATMOSPHERE_CXXFLAGS) -fno-use-cxa-atexit -flto
|
||||||
ASFLAGS := $(ATMOSPHERE_ASFLAGS) $(SETTINGS) $(DEFINES) $(INCLUDE)
|
ASFLAGS := $(ATMOSPHERE_ASFLAGS) $(SETTINGS) $(DEFINES) $(INCLUDE)
|
||||||
|
|||||||
@@ -54,6 +54,7 @@
|
|||||||
#include <mesosphere/kern_kernel.hpp>
|
#include <mesosphere/kern_kernel.hpp>
|
||||||
#include <mesosphere/kern_k_page_table_manager.hpp>
|
#include <mesosphere/kern_k_page_table_manager.hpp>
|
||||||
#include <mesosphere/kern_select_page_table.hpp>
|
#include <mesosphere/kern_select_page_table.hpp>
|
||||||
|
#include <mesosphere/kern_k_dump_object.hpp>
|
||||||
|
|
||||||
/* Miscellaneous objects. */
|
/* Miscellaneous objects. */
|
||||||
#include <mesosphere/kern_k_shared_memory_info.hpp>
|
#include <mesosphere/kern_k_shared_memory_info.hpp>
|
||||||
@@ -77,6 +78,8 @@
|
|||||||
#include <mesosphere/kern_select_debug.hpp>
|
#include <mesosphere/kern_select_debug.hpp>
|
||||||
#include <mesosphere/kern_k_process.hpp>
|
#include <mesosphere/kern_k_process.hpp>
|
||||||
#include <mesosphere/kern_k_resource_limit.hpp>
|
#include <mesosphere/kern_k_resource_limit.hpp>
|
||||||
|
#include <mesosphere/kern_k_alpha.hpp>
|
||||||
|
#include <mesosphere/kern_k_beta.hpp>
|
||||||
|
|
||||||
/* More Miscellaneous objects. */
|
/* More Miscellaneous objects. */
|
||||||
#include <mesosphere/kern_k_object_name.hpp>
|
#include <mesosphere/kern_k_object_name.hpp>
|
||||||
|
|||||||
@@ -668,6 +668,7 @@ namespace ams::kern::arch::arm64::init {
|
|||||||
this->PhysicallyRandomize(virt_addr, size, L2BlockSize, do_copy);
|
this->PhysicallyRandomize(virt_addr, size, L2BlockSize, do_copy);
|
||||||
this->PhysicallyRandomize(virt_addr, size, L3ContiguousBlockSize, do_copy);
|
this->PhysicallyRandomize(virt_addr, size, L3ContiguousBlockSize, do_copy);
|
||||||
this->PhysicallyRandomize(virt_addr, size, L3BlockSize, do_copy);
|
this->PhysicallyRandomize(virt_addr, size, L3BlockSize, do_copy);
|
||||||
|
cpu::StoreEntireCacheForInit();
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -44,6 +44,9 @@ namespace ams::kern::arch::arm64 {
|
|||||||
static uintptr_t GetProgramCounter(const KThread &thread);
|
static uintptr_t GetProgramCounter(const KThread &thread);
|
||||||
static void SetPreviousProgramCounter();
|
static void SetPreviousProgramCounter();
|
||||||
|
|
||||||
|
static void PrintRegister(KThread *thread = nullptr);
|
||||||
|
static void PrintBacktrace(KThread *thread = nullptr);
|
||||||
|
|
||||||
static Result BreakIfAttached(ams::svc::BreakReason break_reason, uintptr_t address, size_t size);
|
static Result BreakIfAttached(ams::svc::BreakReason break_reason, uintptr_t address, size_t size);
|
||||||
static Result SetHardwareBreakPoint(ams::svc::HardwareBreakPointRegisterName name, u64 flags, u64 value);
|
static Result SetHardwareBreakPoint(ams::svc::HardwareBreakPointRegisterName name, u64 flags, u64 value);
|
||||||
|
|
||||||
@@ -61,8 +64,6 @@ namespace ams::kern::arch::arm64 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO: This is a placeholder definition. */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -112,6 +112,7 @@ namespace ams::kern::arch::arm64 {
|
|||||||
L1PageTableEntry *Finalize();
|
L1PageTableEntry *Finalize();
|
||||||
|
|
||||||
void Dump(uintptr_t start, size_t size) const;
|
void Dump(uintptr_t start, size_t size) const;
|
||||||
|
size_t CountPageTables() const;
|
||||||
|
|
||||||
bool BeginTraversal(TraversalEntry *out_entry, TraversalContext *out_context, KProcessAddress address) const;
|
bool BeginTraversal(TraversalEntry *out_entry, TraversalContext *out_context, KProcessAddress address) const;
|
||||||
bool ContinueTraversal(TraversalEntry *out_entry, TraversalContext *context) const;
|
bool ContinueTraversal(TraversalEntry *out_entry, TraversalContext *context) const;
|
||||||
|
|||||||
@@ -232,14 +232,18 @@ namespace ams::kern::arch::arm64 {
|
|||||||
return this->page_table.UnmapPhysicalMemoryUnsafe(address, size);
|
return this->page_table.UnmapPhysicalMemoryUnsafe(address, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DumpTable() const {
|
|
||||||
return this->page_table.DumpTable();
|
|
||||||
}
|
|
||||||
|
|
||||||
void DumpMemoryBlocks() const {
|
void DumpMemoryBlocks() const {
|
||||||
return this->page_table.DumpMemoryBlocks();
|
return this->page_table.DumpMemoryBlocks();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DumpPageTable() const {
|
||||||
|
return this->page_table.DumpPageTable();
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t CountPageTables() const {
|
||||||
|
return this->page_table.CountPageTables();
|
||||||
|
}
|
||||||
|
|
||||||
bool GetPhysicalAddress(KPhysicalAddress *out, KProcessAddress address) const {
|
bool GetPhysicalAddress(KPhysicalAddress *out, KProcessAddress address) const {
|
||||||
return this->page_table.GetPhysicalAddress(out, address);
|
return this->page_table.GetPhysicalAddress(out, address);
|
||||||
}
|
}
|
||||||
@@ -267,12 +271,22 @@ namespace ams::kern::arch::arm64 {
|
|||||||
|
|
||||||
size_t GetNormalMemorySize() const { return this->page_table.GetNormalMemorySize(); }
|
size_t GetNormalMemorySize() const { return this->page_table.GetNormalMemorySize(); }
|
||||||
|
|
||||||
|
size_t GetCodeSize() const { return this->page_table.GetCodeSize(); }
|
||||||
|
size_t GetCodeDataSize() const { return this->page_table.GetCodeDataSize(); }
|
||||||
|
|
||||||
|
size_t GetAliasCodeSize() const { return this->page_table.GetAliasCodeSize(); }
|
||||||
|
size_t GetAliasCodeDataSize() const { return this->page_table.GetAliasCodeDataSize(); }
|
||||||
|
|
||||||
u32 GetAllocateOption() const { return this->page_table.GetAllocateOption(); }
|
u32 GetAllocateOption() const { return this->page_table.GetAllocateOption(); }
|
||||||
|
|
||||||
KPhysicalAddress GetHeapPhysicalAddress(KVirtualAddress address) const {
|
KPhysicalAddress GetHeapPhysicalAddress(KVirtualAddress address) const {
|
||||||
return this->page_table.GetHeapPhysicalAddress(address);
|
return this->page_table.GetHeapPhysicalAddress(address);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
KVirtualAddress GetHeapVirtualAddress(KPhysicalAddress address) const {
|
||||||
|
return this->page_table.GetHeapVirtualAddress(address);
|
||||||
|
}
|
||||||
|
|
||||||
KBlockInfoManager *GetBlockInfoManager() {
|
KBlockInfoManager *GetBlockInfoManager() {
|
||||||
return this->page_table.GetBlockInfoManager();
|
return this->page_table.GetBlockInfoManager();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ namespace ams::kern::arch::arm64 {
|
|||||||
public:
|
public:
|
||||||
constexpr KNotAlignedSpinLock() : packed_tickets(0) { /* ... */ }
|
constexpr KNotAlignedSpinLock() : packed_tickets(0) { /* ... */ }
|
||||||
|
|
||||||
void Lock() {
|
ALWAYS_INLINE void Lock() {
|
||||||
u32 tmp0, tmp1, tmp2;
|
u32 tmp0, tmp1, tmp2;
|
||||||
|
|
||||||
__asm__ __volatile__(
|
__asm__ __volatile__(
|
||||||
@@ -52,7 +52,7 @@ namespace ams::kern::arch::arm64 {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Unlock() {
|
ALWAYS_INLINE void Unlock() {
|
||||||
const u32 value = this->packed_tickets + 1;
|
const u32 value = this->packed_tickets + 1;
|
||||||
__asm__ __volatile__(
|
__asm__ __volatile__(
|
||||||
" stlrh %w[value], %[packed_tickets]\n"
|
" stlrh %w[value], %[packed_tickets]\n"
|
||||||
@@ -71,7 +71,7 @@ namespace ams::kern::arch::arm64 {
|
|||||||
public:
|
public:
|
||||||
constexpr KAlignedSpinLock() : current_ticket(0), next_ticket(0) { /* ... */ }
|
constexpr KAlignedSpinLock() : current_ticket(0), next_ticket(0) { /* ... */ }
|
||||||
|
|
||||||
void Lock() {
|
ALWAYS_INLINE void Lock() {
|
||||||
u32 tmp0, tmp1, got_lock;
|
u32 tmp0, tmp1, got_lock;
|
||||||
|
|
||||||
__asm__ __volatile__(
|
__asm__ __volatile__(
|
||||||
@@ -94,7 +94,7 @@ namespace ams::kern::arch::arm64 {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Unlock() {
|
ALWAYS_INLINE void Unlock() {
|
||||||
const u32 value = this->current_ticket + 1;
|
const u32 value = this->current_ticket + 1;
|
||||||
__asm__ __volatile__(
|
__asm__ __volatile__(
|
||||||
" stlrh %w[value], %[current_ticket]\n"
|
" stlrh %w[value], %[current_ticket]\n"
|
||||||
|
|||||||
@@ -62,6 +62,18 @@ namespace ams::kern::arch::arm64 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
constexpr u64 GetIdentityMapTtbr0(s32 core_id) const { return this->ttbr0_identity[core_id]; }
|
constexpr u64 GetIdentityMapTtbr0(s32 core_id) const { return this->ttbr0_identity[core_id]; }
|
||||||
|
|
||||||
|
void DumpMemoryBlocks() const {
|
||||||
|
return this->page_table.DumpMemoryBlocks();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DumpPageTable() const {
|
||||||
|
return this->page_table.DumpPageTable();
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t CountPageTables() const {
|
||||||
|
return this->page_table.CountPageTables();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,33 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018-2020 Atmosphère-NX
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms and conditions of the GNU General Public License,
|
||||||
|
* version 2, as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
* more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
#include <mesosphere/kern_common.hpp>
|
||||||
|
|
||||||
|
namespace ams::kern::board::nintendo::nx::impl::cpu {
|
||||||
|
|
||||||
|
/* Virtual to Physical core map. */
|
||||||
|
constexpr inline const s32 VirtualToPhysicalCoreMap[BITSIZEOF(u64)] = {
|
||||||
|
0, 1, 2, 3, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 3,
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
@@ -30,6 +30,7 @@ namespace ams::kern::board::nintendo::nx {
|
|||||||
static size_t GetApplicationPoolSize();
|
static size_t GetApplicationPoolSize();
|
||||||
static size_t GetAppletPoolSize();
|
static size_t GetAppletPoolSize();
|
||||||
static size_t GetMinimumNonSecureSystemPoolSize();
|
static size_t GetMinimumNonSecureSystemPoolSize();
|
||||||
|
static u8 GetDebugLogUartPort();
|
||||||
|
|
||||||
/* Randomness. */
|
/* Randomness. */
|
||||||
static void GenerateRandomBytes(void *dst, size_t size);
|
static void GenerateRandomBytes(void *dst, size_t size);
|
||||||
|
|||||||
@@ -34,6 +34,8 @@ namespace ams::kern::init {
|
|||||||
size_t num_KObjectName;
|
size_t num_KObjectName;
|
||||||
size_t num_KResourceLimit;
|
size_t num_KResourceLimit;
|
||||||
size_t num_KDebug;
|
size_t num_KDebug;
|
||||||
|
size_t num_KAlpha;
|
||||||
|
size_t num_KBeta;
|
||||||
};
|
};
|
||||||
|
|
||||||
NOINLINE void InitializeSlabResourceCounts();
|
NOINLINE void InitializeSlabResourceCounts();
|
||||||
|
|||||||
@@ -26,6 +26,7 @@
|
|||||||
#ifdef MESOSPHERE_BUILD_FOR_DEBUGGING
|
#ifdef MESOSPHERE_BUILD_FOR_DEBUGGING
|
||||||
#define MESOSPHERE_ENABLE_ASSERTIONS
|
#define MESOSPHERE_ENABLE_ASSERTIONS
|
||||||
#define MESOSPHERE_ENABLE_DEBUG_PRINT
|
#define MESOSPHERE_ENABLE_DEBUG_PRINT
|
||||||
|
#define MESOSPHERE_ENABLE_KERNEL_STACK_USAGE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//#define MESOSPHERE_BUILD_FOR_TRACING
|
//#define MESOSPHERE_BUILD_FOR_TRACING
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ namespace ams::kern {
|
|||||||
#ifndef MESOSPHERE_DEBUG_LOG_SELECTED
|
#ifndef MESOSPHERE_DEBUG_LOG_SELECTED
|
||||||
|
|
||||||
#ifdef ATMOSPHERE_BOARD_NINTENDO_NX
|
#ifdef ATMOSPHERE_BOARD_NINTENDO_NX
|
||||||
#define MESOSPHERE_DEBUG_LOG_USE_UART_A
|
#define MESOSPHERE_DEBUG_LOG_USE_UART
|
||||||
#else
|
#else
|
||||||
#error "Unknown board for Default Debug Log Source"
|
#error "Unknown board for Default Debug Log Source"
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
41
libraries/libmesosphere/include/mesosphere/kern_k_alpha.hpp
Normal file
41
libraries/libmesosphere/include/mesosphere/kern_k_alpha.hpp
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018-2020 Atmosphère-NX
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms and conditions of the GNU General Public License,
|
||||||
|
* version 2, as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
* more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
#include <mesosphere/kern_common.hpp>
|
||||||
|
#include <mesosphere/kern_k_auto_object.hpp>
|
||||||
|
#include <mesosphere/kern_slab_helpers.hpp>
|
||||||
|
|
||||||
|
namespace ams::kern {
|
||||||
|
|
||||||
|
class KAlpha final : public KAutoObjectWithSlabHeapAndContainer<KAlpha, KAutoObjectWithList> {
|
||||||
|
MESOSPHERE_AUTOOBJECT_TRAITS(KAlpha, KAutoObject);
|
||||||
|
private:
|
||||||
|
/* NOTE: Official KAlpha has size 0x50, corresponding to 0x20 bytes of fields. */
|
||||||
|
/* TODO: Add these fields, if KAlpha is ever instantiable in the NX kernel. */
|
||||||
|
public:
|
||||||
|
explicit KAlpha() {
|
||||||
|
/* ... */
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ~KAlpha() { /* ... */ }
|
||||||
|
|
||||||
|
/* virtual void Finalize() override; */
|
||||||
|
|
||||||
|
virtual bool IsInitialized() const override { return false /* TODO */; }
|
||||||
|
static void PostDestroy(uintptr_t arg) { MESOSPHERE_UNUSED(arg); /* ... */ }
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
@@ -198,7 +198,7 @@ namespace ams::kern {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ALWAYS_INLINE ~KScopedAutoObject() {
|
~KScopedAutoObject() {
|
||||||
if (this->obj != nullptr) {
|
if (this->obj != nullptr) {
|
||||||
this->obj->Close();
|
this->obj->Close();
|
||||||
}
|
}
|
||||||
@@ -206,7 +206,7 @@ namespace ams::kern {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename U> requires (std::derived_from<T, U> || std::derived_from<U, T>)
|
template<typename U> requires (std::derived_from<T, U> || std::derived_from<U, T>)
|
||||||
constexpr ALWAYS_INLINE KScopedAutoObject(KScopedAutoObject<U> &&rhs) {
|
constexpr KScopedAutoObject(KScopedAutoObject<U> &&rhs) {
|
||||||
if constexpr (std::derived_from<U, T>) {
|
if constexpr (std::derived_from<U, T>) {
|
||||||
/* Upcast. */
|
/* Upcast. */
|
||||||
this->obj = rhs.obj;
|
this->obj = rhs.obj;
|
||||||
|
|||||||
48
libraries/libmesosphere/include/mesosphere/kern_k_beta.hpp
Normal file
48
libraries/libmesosphere/include/mesosphere/kern_k_beta.hpp
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018-2020 Atmosphère-NX
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms and conditions of the GNU General Public License,
|
||||||
|
* version 2, as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
* more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
#include <mesosphere/kern_common.hpp>
|
||||||
|
#include <mesosphere/kern_k_auto_object.hpp>
|
||||||
|
#include <mesosphere/kern_slab_helpers.hpp>
|
||||||
|
|
||||||
|
namespace ams::kern {
|
||||||
|
|
||||||
|
class KProcess;
|
||||||
|
|
||||||
|
class KBeta final : public KAutoObjectWithSlabHeapAndContainer<KBeta, KAutoObjectWithList> {
|
||||||
|
MESOSPHERE_AUTOOBJECT_TRAITS(KBeta, KAutoObject);
|
||||||
|
private:
|
||||||
|
friend class KProcess;
|
||||||
|
private:
|
||||||
|
/* NOTE: Official KBeta has size 0x88, corresponding to 0x58 bytes of fields. */
|
||||||
|
/* TODO: Add these fields, if KBeta is ever instantiable in the NX kernel. */
|
||||||
|
util::IntrusiveListNode process_list_node;
|
||||||
|
public:
|
||||||
|
explicit KBeta()
|
||||||
|
: process_list_node()
|
||||||
|
{
|
||||||
|
/* ... */
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ~KBeta() { /* ... */ }
|
||||||
|
|
||||||
|
/* virtual void Finalize() override; */
|
||||||
|
|
||||||
|
virtual bool IsInitialized() const override { return false /* TODO */; }
|
||||||
|
static void PostDestroy(uintptr_t arg) { MESOSPHERE_UNUSED(arg); /* ... */ }
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
@@ -112,6 +112,10 @@ namespace ams::kern {
|
|||||||
KSessionRequest,
|
KSessionRequest,
|
||||||
KCodeMemory,
|
KCodeMemory,
|
||||||
|
|
||||||
|
/* NOTE: True order for these has not been determined yet. */
|
||||||
|
KAlpha,
|
||||||
|
KBeta,
|
||||||
|
|
||||||
FinalClassesEnd = FinalClassesStart + NumFinalClasses,
|
FinalClassesEnd = FinalClassesStart + NumFinalClasses,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -42,6 +42,10 @@ namespace ams::kern {
|
|||||||
|
|
||||||
constexpr const KPort *GetParent() const { return this->parent; }
|
constexpr const KPort *GetParent() const { return this->parent; }
|
||||||
|
|
||||||
|
ALWAYS_INLINE s32 GetNumSessions() const { return this->num_sessions; }
|
||||||
|
ALWAYS_INLINE s32 GetPeakSessions() const { return this->peak_sessions; }
|
||||||
|
ALWAYS_INLINE s32 GetMaxSessions() const { return this->max_sessions; }
|
||||||
|
|
||||||
bool IsLight() const;
|
bool IsLight() const;
|
||||||
|
|
||||||
/* Overridden virtual functions. */
|
/* Overridden virtual functions. */
|
||||||
|
|||||||
@@ -20,8 +20,6 @@
|
|||||||
|
|
||||||
namespace ams::kern {
|
namespace ams::kern {
|
||||||
|
|
||||||
extern KThread g_cv_arbiter_compare_thread;
|
|
||||||
|
|
||||||
class KConditionVariable {
|
class KConditionVariable {
|
||||||
public:
|
public:
|
||||||
using ThreadTree = typename KThread::ConditionVariableThreadTreeType;
|
using ThreadTree = typename KThread::ConditionVariableThreadTreeType;
|
||||||
|
|||||||
@@ -0,0 +1,43 @@
|
|||||||
|
/*
|
||||||
|
* 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);
|
||||||
|
|
||||||
|
}
|
||||||
@@ -160,14 +160,16 @@ namespace ams::kern {
|
|||||||
return this->template GetObjectWithoutPseudoHandle<T>(handle);
|
return this->template GetObjectWithoutPseudoHandle<T>(handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
ALWAYS_INLINE KScopedAutoObject<KAutoObject> GetObjectForIpcWithoutPseudoHandle(ams::svc::Handle handle) const {
|
KScopedAutoObject<KAutoObject> GetObjectForIpcWithoutPseudoHandle(ams::svc::Handle handle) const {
|
||||||
/* Lock and look up in table. */
|
/* Lock and look up in table. */
|
||||||
KScopedDisableDispatch dd;
|
KScopedDisableDispatch dd;
|
||||||
KScopedSpinLock lk(this->lock);
|
KScopedSpinLock lk(this->lock);
|
||||||
|
|
||||||
KAutoObject *obj = this->GetObjectImpl(handle);
|
KAutoObject *obj = this->GetObjectImpl(handle);
|
||||||
if (obj->DynamicCast<KInterruptEvent *>() != nullptr) {
|
if (AMS_LIKELY(obj != nullptr)) {
|
||||||
return nullptr;
|
if (AMS_UNLIKELY(obj->DynamicCast<KInterruptEvent *>() != nullptr)) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return obj;
|
return obj;
|
||||||
|
|||||||
@@ -112,7 +112,9 @@ namespace ams::kern {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static ALWAYS_INLINE KVirtualAddress GetStackTopAddress(s32 core_id, KMemoryRegionType type) {
|
static ALWAYS_INLINE KVirtualAddress GetStackTopAddress(s32 core_id, KMemoryRegionType type) {
|
||||||
return Dereference(GetVirtualMemoryRegionTree().FindByTypeAndAttribute(type, static_cast<u32>(core_id))).GetEndAddress();
|
const auto ®ion = Dereference(GetVirtualMemoryRegionTree().FindByTypeAndAttribute(type, static_cast<u32>(core_id)));
|
||||||
|
MESOSPHERE_INIT_ABORT_UNLESS(region.GetEndAddress() != 0);
|
||||||
|
return region.GetEndAddress();
|
||||||
}
|
}
|
||||||
public:
|
public:
|
||||||
static ALWAYS_INLINE KMemoryRegionTree &GetVirtualMemoryRegionTree() { return s_virtual_tree; }
|
static ALWAYS_INLINE KMemoryRegionTree &GetVirtualMemoryRegionTree() { return s_virtual_tree; }
|
||||||
|
|||||||
@@ -70,11 +70,13 @@ namespace ams::kern {
|
|||||||
public:
|
public:
|
||||||
Impl() : heap(), page_reference_counts(), management_region(), pool(), next(), prev() { /* ... */ }
|
Impl() : heap(), page_reference_counts(), management_region(), pool(), next(), prev() { /* ... */ }
|
||||||
|
|
||||||
size_t Initialize(const KMemoryRegion *region, Pool pool, KVirtualAddress management_region, KVirtualAddress management_region_end);
|
size_t Initialize(uintptr_t address, size_t size, KVirtualAddress management, KVirtualAddress management_end, Pool p);
|
||||||
|
|
||||||
KVirtualAddress AllocateBlock(s32 index, bool random) { return this->heap.AllocateBlock(index, random); }
|
KVirtualAddress AllocateBlock(s32 index, bool random) { return this->heap.AllocateBlock(index, random); }
|
||||||
void Free(KVirtualAddress addr, size_t num_pages) { this->heap.Free(addr, num_pages); }
|
void Free(KVirtualAddress addr, size_t num_pages) { this->heap.Free(addr, num_pages); }
|
||||||
|
|
||||||
|
void UpdateUsedHeapSize() { this->heap.UpdateUsedSize(); }
|
||||||
|
|
||||||
void InitializeOptimizedMemory() { std::memset(GetVoidPointer(this->management_region), 0, CalculateOptimizedProcessOverheadSize(this->heap.GetSize())); }
|
void InitializeOptimizedMemory() { std::memset(GetVoidPointer(this->management_region), 0, CalculateOptimizedProcessOverheadSize(this->heap.GetSize())); }
|
||||||
|
|
||||||
void TrackUnoptimizedAllocation(KVirtualAddress block, size_t num_pages);
|
void TrackUnoptimizedAllocation(KVirtualAddress block, size_t num_pages);
|
||||||
@@ -88,6 +90,8 @@ namespace ams::kern {
|
|||||||
|
|
||||||
size_t GetFreeSize() const { return this->heap.GetFreeSize(); }
|
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 GetPageOffset(KVirtualAddress address) const { return this->heap.GetPageOffset(address); }
|
||||||
constexpr size_t GetPageOffsetToEnd(KVirtualAddress address) const { return this->heap.GetPageOffsetToEnd(address); }
|
constexpr size_t GetPageOffsetToEnd(KVirtualAddress address) const { return this->heap.GetPageOffsetToEnd(address); }
|
||||||
|
|
||||||
@@ -245,12 +249,15 @@ namespace ams::kern {
|
|||||||
size_t GetFreeSize() {
|
size_t GetFreeSize() {
|
||||||
size_t total = 0;
|
size_t total = 0;
|
||||||
for (size_t i = 0; i < this->num_managers; i++) {
|
for (size_t i = 0; i < this->num_managers; i++) {
|
||||||
|
KScopedLightLock lk(this->pool_locks[this->managers[i].GetPool()]);
|
||||||
total += this->managers[i].GetFreeSize();
|
total += this->managers[i].GetFreeSize();
|
||||||
}
|
}
|
||||||
return total;
|
return total;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t GetFreeSize(Pool pool) {
|
size_t GetFreeSize(Pool pool) {
|
||||||
|
KScopedLightLock lk(this->pool_locks[pool]);
|
||||||
|
|
||||||
constexpr Direction GetSizeDirection = Direction_FromFront;
|
constexpr Direction GetSizeDirection = Direction_FromFront;
|
||||||
size_t total = 0;
|
size_t total = 0;
|
||||||
for (auto *manager = this->GetFirstManager(pool, GetSizeDirection); manager != nullptr; manager = this->GetNextManager(manager, GetSizeDirection)) {
|
for (auto *manager = this->GetFirstManager(pool, GetSizeDirection); manager != nullptr; manager = this->GetNextManager(manager, GetSizeDirection)) {
|
||||||
@@ -258,6 +265,15 @@ namespace ams::kern {
|
|||||||
}
|
}
|
||||||
return total;
|
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:
|
public:
|
||||||
static size_t CalculateManagementOverheadSize(size_t region_size) {
|
static size_t CalculateManagementOverheadSize(size_t region_size) {
|
||||||
return Impl::CalculateManagementOverheadSize(region_size);
|
return Impl::CalculateManagementOverheadSize(region_size);
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ namespace ams::kern {
|
|||||||
private:
|
private:
|
||||||
uintptr_t address;
|
uintptr_t address;
|
||||||
uintptr_t pair_address;
|
uintptr_t pair_address;
|
||||||
size_t region_size;
|
uintptr_t last_address;
|
||||||
u32 attributes;
|
u32 attributes;
|
||||||
u32 type_id;
|
u32 type_id;
|
||||||
public:
|
public:
|
||||||
@@ -43,18 +43,18 @@ namespace ams::kern {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
public:
|
public:
|
||||||
constexpr ALWAYS_INLINE KMemoryRegion() : address(0), pair_address(0), region_size(0), attributes(0), type_id(0) { /* ... */ }
|
constexpr ALWAYS_INLINE KMemoryRegion() : address(0), pair_address(0), last_address(0), attributes(0), type_id(0) { /* ... */ }
|
||||||
constexpr ALWAYS_INLINE KMemoryRegion(uintptr_t a, size_t rs, uintptr_t p, u32 r, u32 t) :
|
constexpr ALWAYS_INLINE KMemoryRegion(uintptr_t a, size_t la, uintptr_t p, u32 r, u32 t) :
|
||||||
address(a), pair_address(p), region_size(rs), attributes(r), type_id(t)
|
address(a), pair_address(p), last_address(la), attributes(r), type_id(t)
|
||||||
{
|
{
|
||||||
/* ... */
|
/* ... */
|
||||||
}
|
}
|
||||||
constexpr ALWAYS_INLINE KMemoryRegion(uintptr_t a, size_t rs, u32 r, u32 t) : KMemoryRegion(a, rs, std::numeric_limits<uintptr_t>::max(), r, t) { /* ... */ }
|
constexpr ALWAYS_INLINE KMemoryRegion(uintptr_t a, size_t la, u32 r, u32 t) : KMemoryRegion(a, la, std::numeric_limits<uintptr_t>::max(), r, t) { /* ... */ }
|
||||||
private:
|
private:
|
||||||
constexpr ALWAYS_INLINE void Reset(uintptr_t a, uintptr_t rs, uintptr_t p, u32 r, u32 t) {
|
constexpr ALWAYS_INLINE void Reset(uintptr_t a, uintptr_t la, uintptr_t p, u32 r, u32 t) {
|
||||||
this->address = a;
|
this->address = a;
|
||||||
this->pair_address = p;
|
this->pair_address = p;
|
||||||
this->region_size = rs;
|
this->last_address = la;
|
||||||
this->attributes = r;
|
this->attributes = r;
|
||||||
this->type_id = t;
|
this->type_id = t;
|
||||||
}
|
}
|
||||||
@@ -67,16 +67,16 @@ namespace ams::kern {
|
|||||||
return this->pair_address;
|
return this->pair_address;
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr ALWAYS_INLINE size_t GetSize() const {
|
constexpr ALWAYS_INLINE uintptr_t GetLastAddress() const {
|
||||||
return this->region_size;
|
return this->last_address;
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr ALWAYS_INLINE uintptr_t GetEndAddress() const {
|
constexpr ALWAYS_INLINE uintptr_t GetEndAddress() const {
|
||||||
return this->GetAddress() + this->GetSize();
|
return this->GetLastAddress() + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr ALWAYS_INLINE uintptr_t GetLastAddress() const {
|
constexpr ALWAYS_INLINE size_t GetSize() const {
|
||||||
return this->GetEndAddress() - 1;
|
return this->GetEndAddress() - this->GetAddress();
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr ALWAYS_INLINE u32 GetAttributes() const {
|
constexpr ALWAYS_INLINE u32 GetAttributes() const {
|
||||||
@@ -93,6 +93,7 @@ namespace ams::kern {
|
|||||||
}
|
}
|
||||||
|
|
||||||
constexpr ALWAYS_INLINE bool Contains(uintptr_t address) const {
|
constexpr ALWAYS_INLINE bool Contains(uintptr_t address) const {
|
||||||
|
MESOSPHERE_INIT_ABORT_UNLESS(this->GetEndAddress() != 0);
|
||||||
return this->GetAddress() <= address && address <= this->GetLastAddress();
|
return this->GetAddress() <= address && address <= this->GetLastAddress();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -130,17 +131,17 @@ namespace ams::kern {
|
|||||||
return this->first_region->GetAddress();
|
return this->first_region->GetAddress();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
constexpr ALWAYS_INLINE uintptr_t GetLastAddress() const {
|
||||||
|
return this->last_region->GetLastAddress();
|
||||||
|
}
|
||||||
|
|
||||||
constexpr ALWAYS_INLINE uintptr_t GetEndAddress() const {
|
constexpr ALWAYS_INLINE uintptr_t GetEndAddress() const {
|
||||||
return this->last_region->GetEndAddress();
|
return this->GetLastAddress() + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr ALWAYS_INLINE size_t GetSize() const {
|
constexpr ALWAYS_INLINE size_t GetSize() const {
|
||||||
return this->GetEndAddress() - this->GetAddress();
|
return this->GetEndAddress() - this->GetAddress();
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr ALWAYS_INLINE uintptr_t GetLastAddress() const {
|
|
||||||
return this->GetEndAddress() - 1;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
private:
|
private:
|
||||||
using TreeType = util::IntrusiveRedBlackTreeBaseTraits<KMemoryRegion>::TreeType<KMemoryRegion>;
|
using TreeType = util::IntrusiveRedBlackTreeBaseTraits<KMemoryRegion>::TreeType<KMemoryRegion>;
|
||||||
@@ -160,7 +161,7 @@ namespace ams::kern {
|
|||||||
constexpr ALWAYS_INLINE KMemoryRegionTree() : tree() { /* ... */ }
|
constexpr ALWAYS_INLINE KMemoryRegionTree() : tree() { /* ... */ }
|
||||||
public:
|
public:
|
||||||
KMemoryRegion *FindModifiable(uintptr_t address) {
|
KMemoryRegion *FindModifiable(uintptr_t address) {
|
||||||
if (auto it = this->find(KMemoryRegion(address, 1, 0, 0)); it != this->end()) {
|
if (auto it = this->find(KMemoryRegion(address, address, 0, 0)); it != this->end()) {
|
||||||
return std::addressof(*it);
|
return std::addressof(*it);
|
||||||
} else {
|
} else {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@@ -168,7 +169,7 @@ namespace ams::kern {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const KMemoryRegion *Find(uintptr_t address) const {
|
const KMemoryRegion *Find(uintptr_t address) const {
|
||||||
if (auto it = this->find(KMemoryRegion(address, 1, 0, 0)); it != this->cend()) {
|
if (auto it = this->find(KMemoryRegion(address, address, 0, 0)); it != this->cend()) {
|
||||||
return std::addressof(*it);
|
return std::addressof(*it);
|
||||||
} else {
|
} else {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@@ -234,7 +235,7 @@ namespace ams::kern {
|
|||||||
return extents;
|
return extents;
|
||||||
}
|
}
|
||||||
public:
|
public:
|
||||||
NOINLINE void InsertDirectly(uintptr_t address, size_t size, u32 attr = 0, u32 type_id = 0);
|
NOINLINE void InsertDirectly(uintptr_t address, uintptr_t last_address, u32 attr = 0, u32 type_id = 0);
|
||||||
NOINLINE bool Insert(uintptr_t address, size_t size, u32 type_id, u32 new_attr = 0, u32 old_attr = 0);
|
NOINLINE bool Insert(uintptr_t address, size_t size, u32 type_id, u32 new_attr = 0, u32 old_attr = 0);
|
||||||
|
|
||||||
NOINLINE KVirtualAddress GetRandomAlignedRegion(size_t size, size_t alignment, u32 type_id);
|
NOINLINE KVirtualAddress GetRandomAlignedRegion(size_t size, size_t alignment, u32 type_id);
|
||||||
|
|||||||
@@ -147,6 +147,7 @@ namespace ams::kern {
|
|||||||
}
|
}
|
||||||
|
|
||||||
size_t GetFreeSize() const { return this->GetNumFreePages() * PageSize; }
|
size_t GetFreeSize() const { return this->GetNumFreePages() * PageSize; }
|
||||||
|
void DumpFreeList() const;
|
||||||
|
|
||||||
void UpdateUsedSize() {
|
void UpdateUsedSize() {
|
||||||
this->used_size = this->heap_size - (this->GetNumFreePages() * PageSize);
|
this->used_size = this->heap_size - (this->GetNumFreePages() * PageSize);
|
||||||
|
|||||||
@@ -301,6 +301,8 @@ 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 SetupForIpcClient(PageLinkedList *page_list, size_t *out_blocks_needed, KProcessAddress address, size_t size, KMemoryPermission test_perm, KMemoryState dst_state);
|
||||||
Result SetupForIpcServer(KProcessAddress *out_addr, size_t size, KProcessAddress src_addr, KMemoryPermission test_perm, KMemoryState dst_state, KPageTableBase &src_page_table, bool send);
|
Result SetupForIpcServer(KProcessAddress *out_addr, size_t size, KProcessAddress src_addr, KMemoryPermission test_perm, KMemoryState dst_state, KPageTableBase &src_page_table, bool send);
|
||||||
void CleanupForIpcClientOnServerSetupFailure(PageLinkedList *page_list, KProcessAddress address, size_t size, KMemoryPermission prot_perm);
|
void CleanupForIpcClientOnServerSetupFailure(PageLinkedList *page_list, KProcessAddress address, size_t size, KMemoryPermission prot_perm);
|
||||||
|
|
||||||
|
size_t GetSize(KMemoryState state) const;
|
||||||
public:
|
public:
|
||||||
bool GetPhysicalAddress(KPhysicalAddress *out, KProcessAddress virt_addr) const {
|
bool GetPhysicalAddress(KPhysicalAddress *out, KProcessAddress virt_addr) const {
|
||||||
return this->GetImpl().GetPhysicalAddress(out, virt_addr);
|
return this->GetImpl().GetPhysicalAddress(out, virt_addr);
|
||||||
@@ -382,9 +384,9 @@ namespace ams::kern {
|
|||||||
Result MapPhysicalMemoryUnsafe(KProcessAddress address, size_t size);
|
Result MapPhysicalMemoryUnsafe(KProcessAddress address, size_t size);
|
||||||
Result UnmapPhysicalMemoryUnsafe(KProcessAddress address, size_t size);
|
Result UnmapPhysicalMemoryUnsafe(KProcessAddress address, size_t size);
|
||||||
|
|
||||||
void DumpTable() const {
|
void DumpMemoryBlocksLocked() const {
|
||||||
KScopedLightLock lk(this->general_lock);
|
MESOSPHERE_ASSERT(this->IsLockedByCurrentThread());
|
||||||
this->GetImpl().Dump(GetInteger(this->address_space_start), this->address_space_end - this->address_space_start);
|
this->memory_block_manager.DumpBlocks();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DumpMemoryBlocks() const {
|
void DumpMemoryBlocks() const {
|
||||||
@@ -392,9 +394,14 @@ namespace ams::kern {
|
|||||||
this->DumpMemoryBlocksLocked();
|
this->DumpMemoryBlocksLocked();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DumpMemoryBlocksLocked() const {
|
void DumpPageTable() const {
|
||||||
MESOSPHERE_ASSERT(this->IsLockedByCurrentThread());
|
KScopedLightLock lk(this->general_lock);
|
||||||
this->memory_block_manager.DumpBlocks();
|
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();
|
||||||
}
|
}
|
||||||
public:
|
public:
|
||||||
KProcessAddress GetAddressSpaceStart() const { return this->address_space_start; }
|
KProcessAddress GetAddressSpaceStart() const { return this->address_space_start; }
|
||||||
@@ -418,6 +425,11 @@ namespace ams::kern {
|
|||||||
return (this->current_heap_end - this->heap_region_start) + this->mapped_physical_memory_size;
|
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; }
|
u32 GetAllocateOption() const { return this->allocate_option; }
|
||||||
public:
|
public:
|
||||||
static ALWAYS_INLINE KVirtualAddress GetLinearMappedVirtualAddress(KPhysicalAddress addr) {
|
static ALWAYS_INLINE KVirtualAddress GetLinearMappedVirtualAddress(KPhysicalAddress addr) {
|
||||||
|
|||||||
@@ -22,6 +22,7 @@
|
|||||||
#include <mesosphere/kern_k_thread.hpp>
|
#include <mesosphere/kern_k_thread.hpp>
|
||||||
#include <mesosphere/kern_k_thread_local_page.hpp>
|
#include <mesosphere/kern_k_thread_local_page.hpp>
|
||||||
#include <mesosphere/kern_k_shared_memory_info.hpp>
|
#include <mesosphere/kern_k_shared_memory_info.hpp>
|
||||||
|
#include <mesosphere/kern_k_beta.hpp>
|
||||||
#include <mesosphere/kern_k_worker_task.hpp>
|
#include <mesosphere/kern_k_worker_task.hpp>
|
||||||
#include <mesosphere/kern_select_page_table.hpp>
|
#include <mesosphere/kern_select_page_table.hpp>
|
||||||
#include <mesosphere/kern_k_condition_variable.hpp>
|
#include <mesosphere/kern_k_condition_variable.hpp>
|
||||||
@@ -52,6 +53,7 @@ namespace ams::kern {
|
|||||||
static constexpr size_t AslrAlignment = KernelAslrAlignment;
|
static constexpr size_t AslrAlignment = KernelAslrAlignment;
|
||||||
private:
|
private:
|
||||||
using SharedMemoryInfoList = util::IntrusiveListBaseTraits<KSharedMemoryInfo>::ListType;
|
using SharedMemoryInfoList = util::IntrusiveListBaseTraits<KSharedMemoryInfo>::ListType;
|
||||||
|
using BetaList = util::IntrusiveListMemberTraits<&KBeta::process_list_node>::ListType;
|
||||||
using TLPTree = util::IntrusiveRedBlackTreeBaseTraits<KThreadLocalPage>::TreeType<KThreadLocalPage>;
|
using TLPTree = util::IntrusiveRedBlackTreeBaseTraits<KThreadLocalPage>::TreeType<KThreadLocalPage>;
|
||||||
using TLPIterator = TLPTree::iterator;
|
using TLPIterator = TLPTree::iterator;
|
||||||
private:
|
private:
|
||||||
@@ -95,6 +97,7 @@ namespace ams::kern {
|
|||||||
KThread *exception_thread{};
|
KThread *exception_thread{};
|
||||||
ThreadList thread_list{};
|
ThreadList thread_list{};
|
||||||
SharedMemoryInfoList shared_memory_list{};
|
SharedMemoryInfoList shared_memory_list{};
|
||||||
|
BetaList beta_list{};
|
||||||
bool is_suspended{};
|
bool is_suspended{};
|
||||||
bool is_jit_debug{};
|
bool is_jit_debug{};
|
||||||
ams::svc::DebugEvent jit_debug_event_type{};
|
ams::svc::DebugEvent jit_debug_event_type{};
|
||||||
@@ -167,6 +170,8 @@ namespace ams::kern {
|
|||||||
|
|
||||||
constexpr KProcessAddress GetEntryPoint() const { return this->code_address; }
|
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 KMemoryManager::Pool GetMemoryPool() const { return this->memory_pool; }
|
||||||
|
|
||||||
constexpr u64 GetRandomEntropy(size_t i) const { return this->entropy[i]; }
|
constexpr u64 GetRandomEntropy(size_t i) const { return this->entropy[i]; }
|
||||||
@@ -302,6 +307,11 @@ 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 KThread *GetRunningThread(s32 core) const { return this->running_threads[core]; }
|
||||||
constexpr u64 GetRunningThreadIdleCount(s32 core) const { return this->running_thread_idle_counts[core]; }
|
constexpr u64 GetRunningThreadIdleCount(s32 core) const { return this->running_thread_idle_counts[core]; }
|
||||||
|
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ namespace ams::kern {
|
|||||||
return this->owner_thread == GetCurrentThreadPointer();
|
return this->owner_thread == GetCurrentThreadPointer();
|
||||||
}
|
}
|
||||||
|
|
||||||
ALWAYS_INLINE void Lock() {
|
void Lock() {
|
||||||
MESOSPHERE_ASSERT_THIS();
|
MESOSPHERE_ASSERT_THIS();
|
||||||
|
|
||||||
if (this->IsLockedByCurrentThread()) {
|
if (this->IsLockedByCurrentThread()) {
|
||||||
@@ -67,7 +67,7 @@ namespace ams::kern {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ALWAYS_INLINE void Unlock() {
|
void Unlock() {
|
||||||
MESOSPHERE_ASSERT_THIS();
|
MESOSPHERE_ASSERT_THIS();
|
||||||
MESOSPHERE_ASSERT(this->IsLockedByCurrentThread());
|
MESOSPHERE_ASSERT(this->IsLockedByCurrentThread());
|
||||||
MESOSPHERE_ASSERT(this->lock_count > 0);
|
MESOSPHERE_ASSERT(this->lock_count > 0);
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ namespace ams::kern {
|
|||||||
*out_timer = this->timer;
|
*out_timer = this->timer;
|
||||||
}
|
}
|
||||||
|
|
||||||
ALWAYS_INLINE ~KScopedSchedulerLockAndSleep() {
|
~KScopedSchedulerLockAndSleep() {
|
||||||
/* Register the sleep. */
|
/* Register the sleep. */
|
||||||
if (this->timeout_tick > 0) {
|
if (this->timeout_tick > 0) {
|
||||||
this->timer->RegisterAbsoluteTask(this->thread, this->timeout_tick);
|
this->timer->RegisterAbsoluteTask(this->thread, this->timeout_tick);
|
||||||
|
|||||||
@@ -50,6 +50,8 @@ namespace ams::kern {
|
|||||||
Result SendReply(uintptr_t message, uintptr_t buffer_size, KPhysicalAddress message_paddr);
|
Result SendReply(uintptr_t message, uintptr_t buffer_size, KPhysicalAddress message_paddr);
|
||||||
|
|
||||||
void OnClientClosed();
|
void OnClientClosed();
|
||||||
|
|
||||||
|
void Dump();
|
||||||
private:
|
private:
|
||||||
bool IsSignaledImpl() const;
|
bool IsSignaledImpl() const;
|
||||||
void CleanupRequests();
|
void CleanupRequests();
|
||||||
|
|||||||
@@ -71,6 +71,8 @@ namespace ams::kern {
|
|||||||
KServerSession &GetServerSession() { return this->server; }
|
KServerSession &GetServerSession() { return this->server; }
|
||||||
const KClientSession &GetClientSession() const { return this->client; }
|
const KClientSession &GetClientSession() const { return this->client; }
|
||||||
const KServerSession &GetServerSession() const { return this->server; }
|
const KServerSession &GetServerSession() const { return this->server; }
|
||||||
|
|
||||||
|
const KClientPort *GetParent() const { return this->port; }
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,10 +45,10 @@ namespace ams::kern {
|
|||||||
this->state = st;
|
this->state = st;
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr KProcessAddress GetClientAddress() const { return this->client_address; }
|
constexpr ALWAYS_INLINE KProcessAddress GetClientAddress() const { return this->client_address; }
|
||||||
constexpr KProcessAddress GetServerAddress() const { return this->server_address; }
|
constexpr ALWAYS_INLINE KProcessAddress GetServerAddress() const { return this->server_address; }
|
||||||
constexpr size_t GetSize() const { return this->size; }
|
constexpr ALWAYS_INLINE size_t GetSize() const { return this->size; }
|
||||||
constexpr KMemoryState GetMemoryState() const { return this->state; }
|
constexpr ALWAYS_INLINE KMemoryState GetMemoryState() const { return this->state; }
|
||||||
};
|
};
|
||||||
private:
|
private:
|
||||||
Mapping static_mappings[NumStaticMappings];
|
Mapping static_mappings[NumStaticMappings];
|
||||||
@@ -62,32 +62,32 @@ namespace ams::kern {
|
|||||||
void Initialize() { /* ... */ }
|
void Initialize() { /* ... */ }
|
||||||
void Finalize();
|
void Finalize();
|
||||||
|
|
||||||
constexpr size_t GetSendCount() const { return this->num_send; }
|
constexpr ALWAYS_INLINE size_t GetSendCount() const { return this->num_send; }
|
||||||
constexpr size_t GetReceiveCount() const { return this->num_recv; }
|
constexpr ALWAYS_INLINE size_t GetReceiveCount() const { return this->num_recv; }
|
||||||
constexpr size_t GetExchangeCount() const { return this->num_exch; }
|
constexpr ALWAYS_INLINE size_t GetExchangeCount() const { return this->num_exch; }
|
||||||
|
|
||||||
Result PushSend(KProcessAddress client, KProcessAddress server, size_t size, KMemoryState state);
|
Result PushSend(KProcessAddress client, KProcessAddress server, size_t size, KMemoryState state);
|
||||||
Result PushReceive(KProcessAddress client, KProcessAddress server, size_t size, KMemoryState state);
|
Result PushReceive(KProcessAddress client, KProcessAddress server, size_t size, KMemoryState state);
|
||||||
Result PushExchange(KProcessAddress client, KProcessAddress server, size_t size, KMemoryState state);
|
Result PushExchange(KProcessAddress client, KProcessAddress server, size_t size, KMemoryState state);
|
||||||
|
|
||||||
constexpr KProcessAddress GetSendClientAddress(size_t i) const { return GetSendMapping(i).GetClientAddress(); }
|
constexpr ALWAYS_INLINE KProcessAddress GetSendClientAddress(size_t i) const { return GetSendMapping(i).GetClientAddress(); }
|
||||||
constexpr KProcessAddress GetSendServerAddress(size_t i) const { return GetSendMapping(i).GetServerAddress(); }
|
constexpr ALWAYS_INLINE KProcessAddress GetSendServerAddress(size_t i) const { return GetSendMapping(i).GetServerAddress(); }
|
||||||
constexpr size_t GetSendSize(size_t i) const { return GetSendMapping(i).GetSize(); }
|
constexpr ALWAYS_INLINE size_t GetSendSize(size_t i) const { return GetSendMapping(i).GetSize(); }
|
||||||
constexpr KMemoryState GetSendMemoryState(size_t i) const { return GetSendMapping(i).GetMemoryState(); }
|
constexpr ALWAYS_INLINE KMemoryState GetSendMemoryState(size_t i) const { return GetSendMapping(i).GetMemoryState(); }
|
||||||
|
|
||||||
constexpr KProcessAddress GetReceiveClientAddress(size_t i) const { return GetReceiveMapping(i).GetClientAddress(); }
|
constexpr ALWAYS_INLINE KProcessAddress GetReceiveClientAddress(size_t i) const { return GetReceiveMapping(i).GetClientAddress(); }
|
||||||
constexpr KProcessAddress GetReceiveServerAddress(size_t i) const { return GetReceiveMapping(i).GetServerAddress(); }
|
constexpr ALWAYS_INLINE KProcessAddress GetReceiveServerAddress(size_t i) const { return GetReceiveMapping(i).GetServerAddress(); }
|
||||||
constexpr size_t GetReceiveSize(size_t i) const { return GetReceiveMapping(i).GetSize(); }
|
constexpr ALWAYS_INLINE size_t GetReceiveSize(size_t i) const { return GetReceiveMapping(i).GetSize(); }
|
||||||
constexpr KMemoryState GetReceiveMemoryState(size_t i) const { return GetReceiveMapping(i).GetMemoryState(); }
|
constexpr ALWAYS_INLINE KMemoryState GetReceiveMemoryState(size_t i) const { return GetReceiveMapping(i).GetMemoryState(); }
|
||||||
|
|
||||||
constexpr KProcessAddress GetExchangeClientAddress(size_t i) const { return GetExchangeMapping(i).GetClientAddress(); }
|
constexpr ALWAYS_INLINE KProcessAddress GetExchangeClientAddress(size_t i) const { return GetExchangeMapping(i).GetClientAddress(); }
|
||||||
constexpr KProcessAddress GetExchangeServerAddress(size_t i) const { return GetExchangeMapping(i).GetServerAddress(); }
|
constexpr ALWAYS_INLINE KProcessAddress GetExchangeServerAddress(size_t i) const { return GetExchangeMapping(i).GetServerAddress(); }
|
||||||
constexpr size_t GetExchangeSize(size_t i) const { return GetExchangeMapping(i).GetSize(); }
|
constexpr ALWAYS_INLINE size_t GetExchangeSize(size_t i) const { return GetExchangeMapping(i).GetSize(); }
|
||||||
constexpr KMemoryState GetExchangeMemoryState(size_t i) const { return GetExchangeMapping(i).GetMemoryState(); }
|
constexpr ALWAYS_INLINE KMemoryState GetExchangeMemoryState(size_t i) const { return GetExchangeMapping(i).GetMemoryState(); }
|
||||||
private:
|
private:
|
||||||
Result PushMap(KProcessAddress client, KProcessAddress server, size_t size, KMemoryState state, size_t index);
|
Result PushMap(KProcessAddress client, KProcessAddress server, size_t size, KMemoryState state, size_t index);
|
||||||
|
|
||||||
constexpr const Mapping &GetSendMapping(size_t i) const {
|
constexpr ALWAYS_INLINE const Mapping &GetSendMapping(size_t i) const {
|
||||||
MESOSPHERE_ASSERT(i < this->num_send);
|
MESOSPHERE_ASSERT(i < this->num_send);
|
||||||
|
|
||||||
const size_t index = i;
|
const size_t index = i;
|
||||||
@@ -98,7 +98,7 @@ namespace ams::kern {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr const Mapping &GetReceiveMapping(size_t i) const {
|
constexpr ALWAYS_INLINE const Mapping &GetReceiveMapping(size_t i) const {
|
||||||
MESOSPHERE_ASSERT(i < this->num_recv);
|
MESOSPHERE_ASSERT(i < this->num_recv);
|
||||||
|
|
||||||
const size_t index = this->num_send + i;
|
const size_t index = this->num_send + i;
|
||||||
@@ -109,7 +109,7 @@ namespace ams::kern {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr const Mapping &GetExchangeMapping(size_t i) const {
|
constexpr ALWAYS_INLINE const Mapping &GetExchangeMapping(size_t i) const {
|
||||||
MESOSPHERE_ASSERT(i < this->num_exch);
|
MESOSPHERE_ASSERT(i < this->num_exch);
|
||||||
|
|
||||||
const size_t index = this->num_send + this->num_recv + i;
|
const size_t index = this->num_send + this->num_recv + i;
|
||||||
@@ -176,50 +176,50 @@ namespace ams::kern {
|
|||||||
|
|
||||||
static void PostDestroy(uintptr_t arg) { MESOSPHERE_UNUSED(arg); /* ... */ }
|
static void PostDestroy(uintptr_t arg) { MESOSPHERE_UNUSED(arg); /* ... */ }
|
||||||
|
|
||||||
constexpr KThread *GetThread() const { return this->thread; }
|
constexpr ALWAYS_INLINE KThread *GetThread() const { return this->thread; }
|
||||||
constexpr KWritableEvent *GetEvent() const { return this->event; }
|
constexpr ALWAYS_INLINE KWritableEvent *GetEvent() const { return this->event; }
|
||||||
constexpr uintptr_t GetAddress() const { return this->address; }
|
constexpr ALWAYS_INLINE uintptr_t GetAddress() const { return this->address; }
|
||||||
constexpr size_t GetSize() const { return this->size; }
|
constexpr ALWAYS_INLINE size_t GetSize() const { return this->size; }
|
||||||
constexpr KProcess *GetServerProcess() const { return this->server; }
|
constexpr ALWAYS_INLINE KProcess *GetServerProcess() const { return this->server; }
|
||||||
|
|
||||||
void SetServerProcess(KProcess *process) {
|
void ALWAYS_INLINE SetServerProcess(KProcess *process) {
|
||||||
this->server = process;
|
this->server = process;
|
||||||
this->server->Open();
|
this->server->Open();
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr void ClearThread() { this->thread = nullptr; }
|
constexpr ALWAYS_INLINE void ClearThread() { this->thread = nullptr; }
|
||||||
constexpr void ClearEvent() { this->event = nullptr; }
|
constexpr ALWAYS_INLINE void ClearEvent() { this->event = nullptr; }
|
||||||
|
|
||||||
constexpr size_t GetSendCount() const { return this->mappings.GetSendCount(); }
|
constexpr ALWAYS_INLINE size_t GetSendCount() const { return this->mappings.GetSendCount(); }
|
||||||
constexpr size_t GetReceiveCount() const { return this->mappings.GetReceiveCount(); }
|
constexpr ALWAYS_INLINE size_t GetReceiveCount() const { return this->mappings.GetReceiveCount(); }
|
||||||
constexpr size_t GetExchangeCount() const { return this->mappings.GetExchangeCount(); }
|
constexpr ALWAYS_INLINE size_t GetExchangeCount() const { return this->mappings.GetExchangeCount(); }
|
||||||
|
|
||||||
Result PushSend(KProcessAddress client, KProcessAddress server, size_t size, KMemoryState state) {
|
ALWAYS_INLINE Result PushSend(KProcessAddress client, KProcessAddress server, size_t size, KMemoryState state) {
|
||||||
return this->mappings.PushSend(client, server, size, state);
|
return this->mappings.PushSend(client, server, size, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result PushReceive(KProcessAddress client, KProcessAddress server, size_t size, KMemoryState state) {
|
ALWAYS_INLINE Result PushReceive(KProcessAddress client, KProcessAddress server, size_t size, KMemoryState state) {
|
||||||
return this->mappings.PushReceive(client, server, size, state);
|
return this->mappings.PushReceive(client, server, size, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result PushExchange(KProcessAddress client, KProcessAddress server, size_t size, KMemoryState state) {
|
ALWAYS_INLINE Result PushExchange(KProcessAddress client, KProcessAddress server, size_t size, KMemoryState state) {
|
||||||
return this->mappings.PushExchange(client, server, size, state);
|
return this->mappings.PushExchange(client, server, size, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr KProcessAddress GetSendClientAddress(size_t i) const { return this->mappings.GetSendClientAddress(i); }
|
constexpr ALWAYS_INLINE KProcessAddress GetSendClientAddress(size_t i) const { return this->mappings.GetSendClientAddress(i); }
|
||||||
constexpr KProcessAddress GetSendServerAddress(size_t i) const { return this->mappings.GetSendServerAddress(i); }
|
constexpr ALWAYS_INLINE KProcessAddress GetSendServerAddress(size_t i) const { return this->mappings.GetSendServerAddress(i); }
|
||||||
constexpr size_t GetSendSize(size_t i) const { return this->mappings.GetSendSize(i); }
|
constexpr ALWAYS_INLINE size_t GetSendSize(size_t i) const { return this->mappings.GetSendSize(i); }
|
||||||
constexpr KMemoryState GetSendMemoryState(size_t i) const { return this->mappings.GetSendMemoryState(i); }
|
constexpr ALWAYS_INLINE KMemoryState GetSendMemoryState(size_t i) const { return this->mappings.GetSendMemoryState(i); }
|
||||||
|
|
||||||
constexpr KProcessAddress GetReceiveClientAddress(size_t i) const { return this->mappings.GetReceiveClientAddress(i); }
|
constexpr ALWAYS_INLINE KProcessAddress GetReceiveClientAddress(size_t i) const { return this->mappings.GetReceiveClientAddress(i); }
|
||||||
constexpr KProcessAddress GetReceiveServerAddress(size_t i) const { return this->mappings.GetReceiveServerAddress(i); }
|
constexpr ALWAYS_INLINE KProcessAddress GetReceiveServerAddress(size_t i) const { return this->mappings.GetReceiveServerAddress(i); }
|
||||||
constexpr size_t GetReceiveSize(size_t i) const { return this->mappings.GetReceiveSize(i); }
|
constexpr ALWAYS_INLINE size_t GetReceiveSize(size_t i) const { return this->mappings.GetReceiveSize(i); }
|
||||||
constexpr KMemoryState GetReceiveMemoryState(size_t i) const { return this->mappings.GetReceiveMemoryState(i); }
|
constexpr ALWAYS_INLINE KMemoryState GetReceiveMemoryState(size_t i) const { return this->mappings.GetReceiveMemoryState(i); }
|
||||||
|
|
||||||
constexpr KProcessAddress GetExchangeClientAddress(size_t i) const { return this->mappings.GetExchangeClientAddress(i); }
|
constexpr ALWAYS_INLINE KProcessAddress GetExchangeClientAddress(size_t i) const { return this->mappings.GetExchangeClientAddress(i); }
|
||||||
constexpr KProcessAddress GetExchangeServerAddress(size_t i) const { return this->mappings.GetExchangeServerAddress(i); }
|
constexpr ALWAYS_INLINE KProcessAddress GetExchangeServerAddress(size_t i) const { return this->mappings.GetExchangeServerAddress(i); }
|
||||||
constexpr size_t GetExchangeSize(size_t i) const { return this->mappings.GetExchangeSize(i); }
|
constexpr ALWAYS_INLINE size_t GetExchangeSize(size_t i) const { return this->mappings.GetExchangeSize(i); }
|
||||||
constexpr KMemoryState GetExchangeMemoryState(size_t i) const { return this->mappings.GetExchangeMemoryState(i); }
|
constexpr ALWAYS_INLINE KMemoryState GetExchangeMemoryState(size_t i) const { return this->mappings.GetExchangeMemoryState(i); }
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -140,7 +140,21 @@ namespace ams::kern {
|
|||||||
|
|
||||||
void *obj = this->GetImpl()->Allocate();
|
void *obj = this->GetImpl()->Allocate();
|
||||||
|
|
||||||
/* TODO: under some debug define, track the peak for statistics, as N does? */
|
/* 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
|
||||||
|
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
@@ -165,6 +179,29 @@ namespace ams::kern {
|
|||||||
uintptr_t GetSlabHeapAddress() const {
|
uintptr_t GetSlabHeapAddress() const {
|
||||||
return this->start;
|
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>
|
template<typename T>
|
||||||
|
|||||||
@@ -30,9 +30,10 @@ namespace ams::kern {
|
|||||||
KThread *thread;
|
KThread *thread;
|
||||||
};
|
};
|
||||||
private:
|
private:
|
||||||
ThreadListNode *thread_list_root;
|
ThreadListNode *thread_list_head;
|
||||||
|
ThreadListNode *thread_list_tail;
|
||||||
protected:
|
protected:
|
||||||
constexpr ALWAYS_INLINE explicit KSynchronizationObject() : KAutoObjectWithList(), thread_list_root() { MESOSPHERE_ASSERT_THIS(); }
|
constexpr ALWAYS_INLINE explicit KSynchronizationObject() : KAutoObjectWithList(), thread_list_head(), thread_list_tail() { MESOSPHERE_ASSERT_THIS(); }
|
||||||
virtual ~KSynchronizationObject() { MESOSPHERE_ASSERT_THIS(); }
|
virtual ~KSynchronizationObject() { MESOSPHERE_ASSERT_THIS(); }
|
||||||
|
|
||||||
virtual void OnFinalizeSynchronizationObject() { MESOSPHERE_ASSERT_THIS(); }
|
virtual void OnFinalizeSynchronizationObject() { MESOSPHERE_ASSERT_THIS(); }
|
||||||
@@ -46,7 +47,7 @@ namespace ams::kern {
|
|||||||
public:
|
public:
|
||||||
virtual void Finalize() override;
|
virtual void Finalize() override;
|
||||||
virtual bool IsSignaled() const = 0;
|
virtual bool IsSignaled() const = 0;
|
||||||
virtual void DebugWaiters();
|
virtual void DumpWaiters();
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,11 +49,11 @@ namespace ams::kern {
|
|||||||
};
|
};
|
||||||
|
|
||||||
enum SuspendType : u32 {
|
enum SuspendType : u32 {
|
||||||
SuspendType_Process = 0,
|
SuspendType_Process = 0,
|
||||||
SuspendType_Thread = 1,
|
SuspendType_Thread = 1,
|
||||||
SuspendType_Debug = 2,
|
SuspendType_Debug = 2,
|
||||||
SuspendType_Unk3 = 3,
|
SuspendType_Backtrace = 3,
|
||||||
SuspendType_Init = 4,
|
SuspendType_Init = 4,
|
||||||
|
|
||||||
SuspendType_Count,
|
SuspendType_Count,
|
||||||
};
|
};
|
||||||
@@ -67,13 +67,13 @@ namespace ams::kern {
|
|||||||
ThreadState_SuspendShift = 4,
|
ThreadState_SuspendShift = 4,
|
||||||
ThreadState_Mask = (1 << ThreadState_SuspendShift) - 1,
|
ThreadState_Mask = (1 << ThreadState_SuspendShift) - 1,
|
||||||
|
|
||||||
ThreadState_ProcessSuspended = (1 << (SuspendType_Process + ThreadState_SuspendShift)),
|
ThreadState_ProcessSuspended = (1 << (SuspendType_Process + ThreadState_SuspendShift)),
|
||||||
ThreadState_ThreadSuspended = (1 << (SuspendType_Thread + ThreadState_SuspendShift)),
|
ThreadState_ThreadSuspended = (1 << (SuspendType_Thread + ThreadState_SuspendShift)),
|
||||||
ThreadState_DebugSuspended = (1 << (SuspendType_Debug + ThreadState_SuspendShift)),
|
ThreadState_DebugSuspended = (1 << (SuspendType_Debug + ThreadState_SuspendShift)),
|
||||||
ThreadState_Unk3Suspended = (1 << (SuspendType_Unk3 + ThreadState_SuspendShift)),
|
ThreadState_BacktraceSuspended = (1 << (SuspendType_Backtrace + ThreadState_SuspendShift)),
|
||||||
ThreadState_InitSuspended = (1 << (SuspendType_Init + 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 {
|
enum DpcFlag : u32 {
|
||||||
@@ -124,7 +124,21 @@ namespace ams::kern {
|
|||||||
static_assert(sizeof(SyncObjectBuffer::sync_objects) == sizeof(SyncObjectBuffer::handles));
|
static_assert(sizeof(SyncObjectBuffer::sync_objects) == sizeof(SyncObjectBuffer::handles));
|
||||||
|
|
||||||
struct ConditionVariableComparator {
|
struct ConditionVariableComparator {
|
||||||
static constexpr ALWAYS_INLINE int Compare(const KThread &lhs, const KThread &rhs) {
|
struct LightCompareType {
|
||||||
|
uintptr_t cv_key;
|
||||||
|
s32 priority;
|
||||||
|
|
||||||
|
constexpr ALWAYS_INLINE uintptr_t GetConditionVariableKey() const {
|
||||||
|
return this->cv_key;
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr ALWAYS_INLINE s32 GetPriority() const {
|
||||||
|
return this->priority;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T> requires (std::same_as<T, KThread> || std::same_as<T, LightCompareType>)
|
||||||
|
static constexpr ALWAYS_INLINE int Compare(const T &lhs, const KThread &rhs) {
|
||||||
const uintptr_t l_key = lhs.GetConditionVariableKey();
|
const uintptr_t l_key = lhs.GetConditionVariableKey();
|
||||||
const uintptr_t r_key = rhs.GetConditionVariableKey();
|
const uintptr_t r_key = rhs.GetConditionVariableKey();
|
||||||
|
|
||||||
@@ -139,6 +153,8 @@ namespace ams::kern {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
static_assert(ams::util::HasLightCompareType<ConditionVariableComparator>);
|
||||||
|
static_assert(std::same_as<ams::util::LightCompareType<ConditionVariableComparator, void>, ConditionVariableComparator::LightCompareType>);
|
||||||
private:
|
private:
|
||||||
static inline std::atomic<u64> s_next_thread_id = 0;
|
static inline std::atomic<u64> s_next_thread_id = 0;
|
||||||
private:
|
private:
|
||||||
@@ -152,7 +168,8 @@ namespace ams::kern {
|
|||||||
|
|
||||||
ConditionVariableThreadTree *condvar_tree{};
|
ConditionVariableThreadTree *condvar_tree{};
|
||||||
uintptr_t condvar_key{};
|
uintptr_t condvar_key{};
|
||||||
KAffinityMask affinity_mask{};
|
u64 virtual_affinity_mask{};
|
||||||
|
KAffinityMask physical_affinity_mask{};
|
||||||
u64 thread_id{};
|
u64 thread_id{};
|
||||||
std::atomic<s64> cpu_time{};
|
std::atomic<s64> cpu_time{};
|
||||||
KSynchronizationObject *synced_object{};
|
KSynchronizationObject *synced_object{};
|
||||||
@@ -181,12 +198,13 @@ namespace ams::kern {
|
|||||||
Result wait_result;
|
Result wait_result;
|
||||||
Result debug_exception_result;
|
Result debug_exception_result;
|
||||||
s32 base_priority{};
|
s32 base_priority{};
|
||||||
s32 ideal_core_id{};
|
s32 physical_ideal_core_id{};
|
||||||
|
s32 virtual_ideal_core_id{};
|
||||||
s32 num_kernel_waiters{};
|
s32 num_kernel_waiters{};
|
||||||
s32 current_core_id{};
|
s32 current_core_id{};
|
||||||
s32 core_id{};
|
s32 core_id{};
|
||||||
KAffinityMask original_affinity_mask{};
|
KAffinityMask original_physical_affinity_mask{};
|
||||||
s32 original_ideal_core_id{};
|
s32 original_physical_ideal_core_id{};
|
||||||
s32 num_core_migration_disables{};
|
s32 num_core_migration_disables{};
|
||||||
ThreadState thread_state{};
|
ThreadState thread_state{};
|
||||||
std::atomic<bool> termination_requested{};
|
std::atomic<bool> termination_requested{};
|
||||||
@@ -202,21 +220,21 @@ namespace ams::kern {
|
|||||||
|
|
||||||
virtual ~KThread() { /* ... */ }
|
virtual ~KThread() { /* ... */ }
|
||||||
|
|
||||||
Result Initialize(KThreadFunction func, uintptr_t arg, void *kern_stack_top, KProcessAddress user_stack_top, s32 prio, s32 core, KProcess *owner, ThreadType type);
|
Result Initialize(KThreadFunction func, uintptr_t arg, void *kern_stack_top, KProcessAddress user_stack_top, s32 prio, s32 virt_core, KProcess *owner, ThreadType type);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static Result InitializeThread(KThread *thread, KThreadFunction func, uintptr_t arg, KProcessAddress user_stack_top, s32 prio, s32 core, KProcess *owner, ThreadType type);
|
static Result InitializeThread(KThread *thread, KThreadFunction func, uintptr_t arg, KProcessAddress user_stack_top, s32 prio, s32 virt_core, KProcess *owner, ThreadType type);
|
||||||
public:
|
public:
|
||||||
static Result InitializeKernelThread(KThread *thread, KThreadFunction func, uintptr_t arg, s32 prio, s32 core) {
|
static Result InitializeKernelThread(KThread *thread, KThreadFunction func, uintptr_t arg, s32 prio, s32 virt_core) {
|
||||||
return InitializeThread(thread, func, arg, Null<KProcessAddress>, prio, core, nullptr, ThreadType_Kernel);
|
return InitializeThread(thread, func, arg, Null<KProcessAddress>, prio, virt_core, nullptr, ThreadType_Kernel);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Result InitializeHighPriorityThread(KThread *thread, KThreadFunction func, uintptr_t arg) {
|
static Result InitializeHighPriorityThread(KThread *thread, KThreadFunction func, uintptr_t arg) {
|
||||||
return InitializeThread(thread, func, arg, Null<KProcessAddress>, 0, GetCurrentCoreId(), nullptr, ThreadType_HighPriority);
|
return InitializeThread(thread, func, arg, Null<KProcessAddress>, 0, GetCurrentCoreId(), nullptr, ThreadType_HighPriority);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Result InitializeUserThread(KThread *thread, KThreadFunction func, uintptr_t arg, KProcessAddress user_stack_top, s32 prio, s32 core, KProcess *owner) {
|
static Result InitializeUserThread(KThread *thread, KThreadFunction func, uintptr_t arg, KProcessAddress user_stack_top, s32 prio, s32 virt_core, KProcess *owner) {
|
||||||
return InitializeThread(thread, func, arg, user_stack_top, prio, core, owner, ThreadType_User);
|
return InitializeThread(thread, func, arg, user_stack_top, prio, virt_core, owner, ThreadType_User);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ResumeThreadsSuspendedForInit();
|
static void ResumeThreadsSuspendedForInit();
|
||||||
@@ -323,10 +341,14 @@ namespace ams::kern {
|
|||||||
constexpr KThreadContext &GetContext() { return this->thread_context; }
|
constexpr KThreadContext &GetContext() { return this->thread_context; }
|
||||||
constexpr const KThreadContext &GetContext() const { return this->thread_context; }
|
constexpr const KThreadContext &GetContext() const { return this->thread_context; }
|
||||||
|
|
||||||
constexpr const KAffinityMask &GetAffinityMask() const { return this->affinity_mask; }
|
constexpr u64 GetVirtualAffinityMask() const { return this->virtual_affinity_mask; }
|
||||||
|
constexpr const KAffinityMask &GetAffinityMask() const { return this->physical_affinity_mask; }
|
||||||
|
|
||||||
Result GetCoreMask(int32_t *out_ideal_core, u64 *out_affinity_mask);
|
Result GetCoreMask(int32_t *out_ideal_core, u64 *out_affinity_mask);
|
||||||
Result SetCoreMask(int32_t ideal_core, u64 affinity_mask);
|
Result SetCoreMask(int32_t ideal_core, u64 affinity_mask);
|
||||||
|
|
||||||
|
Result GetPhysicalCoreMask(int32_t *out_ideal_core, u64 *out_affinity_mask);
|
||||||
|
|
||||||
constexpr ThreadState GetState() const { return static_cast<ThreadState>(this->thread_state & ThreadState_Mask); }
|
constexpr ThreadState GetState() const { return static_cast<ThreadState>(this->thread_state & ThreadState_Mask); }
|
||||||
constexpr ThreadState GetRawState() const { return this->thread_state; }
|
constexpr ThreadState GetRawState() const { return this->thread_state; }
|
||||||
NOINLINE void SetState(ThreadState state);
|
NOINLINE void SetState(ThreadState state);
|
||||||
@@ -336,11 +358,6 @@ namespace ams::kern {
|
|||||||
constexpr uintptr_t GetConditionVariableKey() const { return this->condvar_key; }
|
constexpr uintptr_t GetConditionVariableKey() const { return this->condvar_key; }
|
||||||
constexpr uintptr_t GetAddressArbiterKey() const { return this->condvar_key; }
|
constexpr uintptr_t GetAddressArbiterKey() const { return this->condvar_key; }
|
||||||
|
|
||||||
constexpr void SetupForConditionVariableCompare(uintptr_t cv_key, int priority) {
|
|
||||||
this->condvar_key = cv_key;
|
|
||||||
this->priority = priority;
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr void SetConditionVariable(ConditionVariableThreadTree *tree, KProcessAddress address, uintptr_t cv_key, u32 value) {
|
constexpr void SetConditionVariable(ConditionVariableThreadTree *tree, KProcessAddress address, uintptr_t cv_key, u32 value) {
|
||||||
this->condvar_tree = tree;
|
this->condvar_tree = tree;
|
||||||
this->condvar_key = cv_key;
|
this->condvar_key = cv_key;
|
||||||
@@ -356,11 +373,6 @@ namespace ams::kern {
|
|||||||
return this->condvar_tree != nullptr;
|
return this->condvar_tree != nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr void SetupForAddressArbiterCompare(uintptr_t address, int priority) {
|
|
||||||
this->condvar_key = address;
|
|
||||||
this->priority = priority;
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr void SetAddressArbiter(ConditionVariableThreadTree *tree, uintptr_t address) {
|
constexpr void SetAddressArbiter(ConditionVariableThreadTree *tree, uintptr_t address) {
|
||||||
this->condvar_tree = tree;
|
this->condvar_tree = tree;
|
||||||
this->condvar_key = address;
|
this->condvar_key = address;
|
||||||
@@ -374,7 +386,9 @@ namespace ams::kern {
|
|||||||
return this->condvar_tree != nullptr;
|
return this->condvar_tree != nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr s32 GetIdealCore() const { return this->ideal_core_id; }
|
constexpr s32 GetIdealVirtualCore() const { return this->virtual_ideal_core_id; }
|
||||||
|
constexpr s32 GetIdealPhysicalCore() const { return this->physical_ideal_core_id; }
|
||||||
|
|
||||||
constexpr s32 GetActiveCore() const { return this->core_id; }
|
constexpr s32 GetActiveCore() const { return this->core_id; }
|
||||||
constexpr void SetActiveCore(s32 core) { this->core_id = core; }
|
constexpr void SetActiveCore(s32 core) { this->core_id = core; }
|
||||||
|
|
||||||
@@ -519,6 +533,7 @@ namespace ams::kern {
|
|||||||
return this->termination_requested || this->GetRawState() == ThreadState_Terminated;
|
return this->termination_requested || this->GetRawState() == ThreadState_Terminated;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t GetKernelStackUsage() const;
|
||||||
public:
|
public:
|
||||||
/* Overridden parent functions. */
|
/* Overridden parent functions. */
|
||||||
virtual u64 GetId() const override final { return this->GetThreadId(); }
|
virtual u64 GetId() const override final { return this->GetThreadId(); }
|
||||||
|
|||||||
@@ -28,3 +28,24 @@
|
|||||||
#else
|
#else
|
||||||
#error "Unknown architecture for CPU"
|
#error "Unknown architecture for CPU"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef ATMOSPHERE_BOARD_NINTENDO_NX
|
||||||
|
|
||||||
|
#include <mesosphere/board/nintendo/nx/kern_cpu_map.hpp>
|
||||||
|
|
||||||
|
namespace ams::kern::cpu {
|
||||||
|
|
||||||
|
using namespace ams::kern::board::nintendo::nx::impl::cpu;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
#error "Unknown board for CPU Map"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace ams::kern {
|
||||||
|
|
||||||
|
static_assert(cpu::NumCores <= static_cast<s32>(BITSIZEOF(u64)));
|
||||||
|
static_assert(util::size(cpu::VirtualToPhysicalCoreMap) == BITSIZEOF(u64));
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ namespace ams::kern {
|
|||||||
u32 prev_intr_state;
|
u32 prev_intr_state;
|
||||||
public:
|
public:
|
||||||
ALWAYS_INLINE KScopedInterruptDisable() : prev_intr_state(KInterruptManager::DisableInterrupts()) { /* ... */ }
|
ALWAYS_INLINE KScopedInterruptDisable() : prev_intr_state(KInterruptManager::DisableInterrupts()) { /* ... */ }
|
||||||
~KScopedInterruptDisable() { KInterruptManager::RestoreInterrupts(prev_intr_state); }
|
ALWAYS_INLINE ~KScopedInterruptDisable() { KInterruptManager::RestoreInterrupts(prev_intr_state); }
|
||||||
};
|
};
|
||||||
|
|
||||||
class KScopedInterruptEnable {
|
class KScopedInterruptEnable {
|
||||||
@@ -52,7 +52,7 @@ namespace ams::kern {
|
|||||||
u32 prev_intr_state;
|
u32 prev_intr_state;
|
||||||
public:
|
public:
|
||||||
ALWAYS_INLINE KScopedInterruptEnable() : prev_intr_state(KInterruptManager::EnableInterrupts()) { /* ... */ }
|
ALWAYS_INLINE KScopedInterruptEnable() : prev_intr_state(KInterruptManager::EnableInterrupts()) { /* ... */ }
|
||||||
~KScopedInterruptEnable() { KInterruptManager::RestoreInterrupts(prev_intr_state); }
|
ALWAYS_INLINE ~KScopedInterruptEnable() { KInterruptManager::RestoreInterrupts(prev_intr_state); }
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,6 +48,8 @@ namespace ams::kern {
|
|||||||
static size_t GetSlabHeapSize() { return s_slab_heap.GetSlabHeapSize(); }
|
static size_t GetSlabHeapSize() { return s_slab_heap.GetSlabHeapSize(); }
|
||||||
static size_t GetPeakIndex() { return s_slab_heap.GetPeakIndex(); }
|
static size_t GetPeakIndex() { return s_slab_heap.GetPeakIndex(); }
|
||||||
static uintptr_t GetSlabHeapAddress() { return s_slab_heap.GetSlabHeapAddress(); }
|
static uintptr_t GetSlabHeapAddress() { return s_slab_heap.GetSlabHeapAddress(); }
|
||||||
|
|
||||||
|
static size_t GetNumRemaining() { return s_slab_heap.GetNumRemaining(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename Derived, typename Base>
|
template<typename Derived, typename Base>
|
||||||
@@ -92,7 +94,7 @@ namespace ams::kern {
|
|||||||
virtual uintptr_t GetPostDestroyArgument() const { return 0; }
|
virtual uintptr_t GetPostDestroyArgument() const { return 0; }
|
||||||
|
|
||||||
size_t GetSlabIndex() const {
|
size_t GetSlabIndex() const {
|
||||||
return s_slab_heap.GetIndex(static_cast<const Derived *>(this));
|
return s_slab_heap.GetObjectIndex(static_cast<const Derived *>(this));
|
||||||
}
|
}
|
||||||
public:
|
public:
|
||||||
static void InitializeSlabHeap(void *memory, size_t memory_size) {
|
static void InitializeSlabHeap(void *memory, size_t memory_size) {
|
||||||
@@ -116,6 +118,8 @@ namespace ams::kern {
|
|||||||
static size_t GetSlabHeapSize() { return s_slab_heap.GetSlabHeapSize(); }
|
static size_t GetSlabHeapSize() { return s_slab_heap.GetSlabHeapSize(); }
|
||||||
static size_t GetPeakIndex() { return s_slab_heap.GetPeakIndex(); }
|
static size_t GetPeakIndex() { return s_slab_heap.GetPeakIndex(); }
|
||||||
static uintptr_t GetSlabHeapAddress() { return s_slab_heap.GetSlabHeapAddress(); }
|
static uintptr_t GetSlabHeapAddress() { return s_slab_heap.GetSlabHeapAddress(); }
|
||||||
|
|
||||||
|
static size_t GetNumRemaining() { return s_slab_heap.GetNumRemaining(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user