exosphere: support enabling usermode pmu regs (closes #703)
This commit is contained in:
@@ -13,7 +13,7 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include <stdint.h>
|
||||
#include <atmosphere/version.h>
|
||||
|
||||
@@ -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) |
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef 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);
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user