diff --git a/common/defaults/BCT.ini b/common/defaults/BCT.ini
index 66072d982..d483c810e 100644
--- a/common/defaults/BCT.ini
+++ b/common/defaults/BCT.ini
@@ -12,6 +12,8 @@ debugmode_user = 0
; Note: Disabling usermode exception handlers will cause atmosphere to not fail gracefully under error conditions.
; Support will not be provided to users who disable these. If you do not know what you are doing, leave them on.
disable_user_exception_handlers = 0
+; Note: It's currently unknown what effects enabling the usermode PMU register access may have on official code.
+enable_user_pmu_access = 0
[stratosphere]
; To force-enable nogc, add nogc = 1
diff --git a/docs/changelog.md b/docs/changelog.md
index 94637bdae..de0f5c3f2 100644
--- a/docs/changelog.md
+++ b/docs/changelog.md
@@ -47,6 +47,8 @@
+ An extension was added to pm:info to allow querying a process's override status.
+ Thanks to process override capture improvements, hbl html behavior has been greatly improved.
+ Web applets launched by hbl will now always see the /atmosphere/hbl_html filesystem
++ Support was added to exosphere for enabling usermode access to the PMU registers.
+ + This can be controlled via exosphere!enable_user_pmu_access in BCT.ini.
+ An enormous number of minor bugs were fixed.
+ dmnt's cheat VM had a fix for an inversion in opcode behavior.
+ An issue was fixed in fs.mitm's management of domain object IDs that could lead to system corruption in rare cases.
diff --git a/exosphere/src/configitem.c b/exosphere/src/configitem.c
index b53421d6f..84ca86acb 100644
--- a/exosphere/src/configitem.c
+++ b/exosphere/src/configitem.c
@@ -13,7 +13,7 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
-
+
#include
#include
@@ -38,6 +38,7 @@
static bool g_hiz_mode_enabled = false;
static bool g_debugmode_override_user = false, g_debugmode_override_priv = false;
static bool g_enable_usermode_exception_handlers = true;
+static bool g_enable_usermode_pmu_access = false;
uint32_t configitem_set(bool privileged, ConfigItem item, uint64_t value) {
switch (item) {
@@ -63,14 +64,14 @@ uint32_t configitem_set(bool privileged, ConfigItem item, uint64_t value) {
/* Set SVC handler to jump to reboot stub in IRAM. */
MAKE_REG32(MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_RTC_PMC) + 0x520ull) = 0x4003F000;
MAKE_REG32(MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_RTC_PMC) + 0x53Cull) = 0x6000F208;
-
+
/* Copy reboot stub payload. */
ams_map_irampage(0x4003F000);
for (unsigned int i = 0; i < rebootstub_bin_size; i += 4) {
MAKE_REG32(MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_AMS_IRAM_PAGE) + i) = read32le(rebootstub_bin, i);
}
ams_unmap_irampage();
-
+
/* Ensure stub is flushed. */
flush_dcache_all();
break;
@@ -95,7 +96,7 @@ uint32_t configitem_set(bool privileged, ConfigItem item, uint64_t value) {
/* Set SVC handler to jump to reboot stub in IRAM. */
MAKE_REG32(MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_RTC_PMC) + 0x520ull) = 0x4003F000;
MAKE_REG32(MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_RTC_PMC) + 0x53Cull) = 0x6000F208;
-
+
/* Copy reboot stub payload. */
ams_map_irampage(0x4003F000);
for (unsigned int i = 0; i < rebootstub_bin_size; i += 4) {
@@ -104,7 +105,7 @@ uint32_t configitem_set(bool privileged, ConfigItem item, uint64_t value) {
/* Tell rebootstub to shut down. */
MAKE_REG32(MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_AMS_IRAM_PAGE) + 0x10) = 0x0;
ams_unmap_irampage();
-
+
MAKE_REG32(MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_RTC_PMC) + 0x400ull) = 0x10;
while (1) { }
}
@@ -112,7 +113,7 @@ uint32_t configitem_set(bool privileged, ConfigItem item, uint64_t value) {
default:
return 2;
}
-
+
return 0;
}
@@ -168,6 +169,10 @@ void configitem_disable_usermode_exception_handlers(void) {
g_enable_usermode_exception_handlers = false;
}
+void configitem_enable_usermode_pmu_access(void) {
+ g_enable_usermode_pmu_access = true;
+}
+
uint32_t configitem_get(bool privileged, ConfigItem item, uint64_t *p_outvalue) {
uint32_t result = 0;
switch (item) {
@@ -222,6 +227,10 @@ uint32_t configitem_get(bool privileged, ConfigItem item, uint64_t *p_outvalue)
if (g_enable_usermode_exception_handlers) {
config |= KERNELCONFIGFLAG_ENABLE_USER_EXCEPTION_HANDLERS;
}
+ /* Allow for enabling usermode pmu access. */
+ if (g_enable_usermode_pmu_access) {
+ config |= KERNELCONFIGFLAG_ENABLE_USER_PMU_ACCESS;
+ }
*p_outvalue = config;
}
break;
@@ -262,7 +271,7 @@ uint32_t configitem_get(bool privileged, ConfigItem item, uint64_t *p_outvalue)
break;
case CONFIGITEM_EXOSPHERE_VERSION:
/* UNOFFICIAL: Gets information about the current exosphere version. */
- *p_outvalue = ((uint64_t)(ATMOSPHERE_RELEASE_VERSION_MAJOR & 0xFF) << 32ull) |
+ *p_outvalue = ((uint64_t)(ATMOSPHERE_RELEASE_VERSION_MAJOR & 0xFF) << 32ull) |
((uint64_t)(ATMOSPHERE_RELEASE_VERSION_MINOR & 0xFF) << 24ull) |
((uint64_t)(ATMOSPHERE_RELEASE_VERSION_MICRO & 0xFF) << 16ull) |
((uint64_t)(exosphere_get_target_firmware() & 0xFF) << 8ull) |
diff --git a/exosphere/src/configitem.h b/exosphere/src/configitem.h
index b9600c833..4cadc3d71 100644
--- a/exosphere/src/configitem.h
+++ b/exosphere/src/configitem.h
@@ -13,7 +13,7 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
-
+
#ifndef EXOSPHERE_CFG_ITEM_H
#define EXOSPHERE_CFG_ITEM_H
@@ -38,7 +38,7 @@ typedef enum {
CONFIGITEM_NEWHARDWARETYPE_5X = 15,
CONFIGITEM_NEWKEYGENERATION_5X = 16,
CONFIGITEM_PACKAGE2HASH_5X = 17,
-
+
/* These are unofficial, for usage by Exosphere. */
CONFIGITEM_EXOSPHERE_VERSION = 65000,
CONFIGITEM_NEEDS_REBOOT = 65001,
@@ -61,6 +61,7 @@ bool configitem_is_debugmode_priv(void);
void configitem_set_debugmode_override(bool user, bool priv);
void configitem_disable_usermode_exception_handlers(void);
+void configitem_enable_usermode_pmu_access(void);
void configitem_set_hiz_mode_enabled(bool enabled);
uint64_t configitem_get_hardware_type(void);
diff --git a/exosphere/src/exocfg.c b/exosphere/src/exocfg.c
index 974766178..00827c69f 100644
--- a/exosphere/src/exocfg.c
+++ b/exosphere/src/exocfg.c
@@ -84,6 +84,14 @@ unsigned int exosphere_should_disable_usermode_exception_handlers(void) {
return EXOSPHERE_CHECK_FLAG(EXOSPHERE_FLAG_DISABLE_USERMODE_EXCEPTION_HANDLERS);
}
+unsigned int exosphere_should_enable_usermode_pmu_access(void) {
+ if (!g_has_loaded_config) {
+ generic_panic();
+ }
+
+ return EXOSPHERE_CHECK_FLAG(EXOSPHERE_FLAG_ENABLE_USERMODE_PMU_ACCESS);
+}
+
const exo_emummc_config_t *exosphere_get_emummc_config(void) {
if (!g_has_loaded_config) {
generic_panic();
diff --git a/exosphere/src/exocfg.h b/exosphere/src/exocfg.h
index 16f37ec19..902ab02e0 100644
--- a/exosphere/src/exocfg.h
+++ b/exosphere/src/exocfg.h
@@ -40,6 +40,7 @@
#define EXOSPHERE_FLAG_IS_DEBUGMODE_PRIV (1 << 1u)
#define EXOSPHERE_FLAG_IS_DEBUGMODE_USER (1 << 2u)
#define EXOSPHERE_FLAG_DISABLE_USERMODE_EXCEPTION_HANDLERS (1 << 3u)
+#define EXOSPHERE_FLAG_ENABLE_USERMODE_PMU_ACCESS (1 << 4u)
#define EXOSPHERE_FLAGS_DEFAULT (EXOSPHERE_FLAG_IS_DEBUGMODE_PRIV)
typedef struct {
@@ -58,6 +59,7 @@ unsigned int exosphere_should_perform_620_keygen(void);
unsigned int exosphere_should_override_debugmode_priv(void);
unsigned int exosphere_should_override_debugmode_user(void);
unsigned int exosphere_should_disable_usermode_exception_handlers(void);
+unsigned int exosphere_should_enable_usermode_pmu_access(void);
const exo_emummc_config_t *exosphere_get_emummc_config(void);
diff --git a/exosphere/src/package2.c b/exosphere/src/package2.c
index 6935e8bca..4fe2b6623 100644
--- a/exosphere/src/package2.c
+++ b/exosphere/src/package2.c
@@ -512,6 +512,9 @@ void load_package2(coldboot_crt0_reloc_list_t *reloc_list) {
if (exosphere_should_disable_usermode_exception_handlers() != 0) {
configitem_disable_usermode_exception_handlers();
}
+ if (exosphere_should_enable_usermode_pmu_access()) {
+ configitem_enable_usermode_pmu_access();
+ }
/* Setup the Security Engine. */
setup_se();
diff --git a/fusee/fusee-secondary/src/exocfg.h b/fusee/fusee-secondary/src/exocfg.h
index dc00de45e..685b15ce8 100644
--- a/fusee/fusee-secondary/src/exocfg.h
+++ b/fusee/fusee-secondary/src/exocfg.h
@@ -13,7 +13,7 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
-
+
#ifndef FUSEE_EXOSPHERE_CONFIG_H
#define FUSEE_EXOSPHERE_CONFIG_H
@@ -30,6 +30,7 @@
#define EXOSPHERE_FLAG_IS_DEBUGMODE_PRIV (1 << 1u)
#define EXOSPHERE_FLAG_IS_DEBUGMODE_USER (1 << 2u)
#define EXOSPHERE_FLAG_DISABLE_USERMODE_EXCEPTION_HANDLERS (1 << 3u)
+#define EXOSPHERE_FLAG_ENABLE_USERMODE_PMU_ACCESS (1 << 4u)
#define EXOSPHERE_FLAGS_DEFAULT (EXOSPHERE_FLAG_IS_DEBUGMODE_PRIV)
typedef struct {
@@ -48,5 +49,6 @@ _Static_assert(sizeof(exosphere_config_t) == 0x20 + sizeof(exo_emummc_config_t),
#define EXOSPHERE_DEBUGMODE_PRIV_KEY "debugmode"
#define EXOSPHERE_DEBUGMODE_USER_KEY "debugmode_user"
#define EXOSPHERE_DISABLE_USERMODE_EXCEPTION_HANDLERS_KEY "disable_user_exception_handlers"
+#define EXOSPHERE_ENABLE_USERMODE_PMU_ACCESS_KEY "enable_user_pmu_access"
#endif
\ No newline at end of file
diff --git a/fusee/fusee-secondary/src/nxboot.c b/fusee/fusee-secondary/src/nxboot.c
index ddc5c32ce..201f2ceeb 100644
--- a/fusee/fusee-secondary/src/nxboot.c
+++ b/fusee/fusee-secondary/src/nxboot.c
@@ -158,6 +158,13 @@ static int exosphere_ini_handler(void *user, const char *section, const char *na
} else {
exo_cfg->flags &= ~(EXOSPHERE_FLAG_DISABLE_USERMODE_EXCEPTION_HANDLERS);
}
+ } else if (strcmp(name, EXOSPHERE_ENABLE_USERMODE_PMU_ACCESS_KEY) == 0) {
+ sscanf(value, "%d", &tmp);
+ if (tmp) {
+ exo_cfg->flags |= EXOSPHERE_FLAG_ENABLE_USERMODE_PMU_ACCESS;
+ } else {
+ exo_cfg->flags &= ~(EXOSPHERE_FLAG_ENABLE_USERMODE_PMU_ACCESS);
+ }
} else {
return 0;
}