mirror of
https://github.com/Atmosphere-NX/Atmosphere
synced 2024-12-22 12:21:18 +00:00
Skeleton for smcGetConfig and smcSetConfig
This commit is contained in:
parent
f629a629d1
commit
f77cae48d0
4 changed files with 114 additions and 1 deletions
67
exosphere/configitem.c
Normal file
67
exosphere/configitem.c
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "utils.h"
|
||||||
|
#include "configitem.h"
|
||||||
|
|
||||||
|
int g_battery_profile = 0;
|
||||||
|
|
||||||
|
uint32_t configitem_set(enum ConfigItem item, uint64_t value) {
|
||||||
|
if (item != CONFIGITEM_BATTERYPROFILE) {
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_battery_profile = ((int)(value != 0)) & 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t configitem_get(enum ConfigItem item, uint64_t *p_outvalue) {
|
||||||
|
uint32_t result = 0;
|
||||||
|
switch (item) {
|
||||||
|
case CONFIGITEM_DISABLEPROGRAMVERIFICATION:
|
||||||
|
/* TODO: This is loaded from BootConfig on dev units, always zero on retail. How should we support? */
|
||||||
|
*p_outvalue = 0;
|
||||||
|
break;
|
||||||
|
case CONFIGITEM_MEMORYCONFIGURATION:
|
||||||
|
/* TODO: Fuse driver */
|
||||||
|
break;
|
||||||
|
case CONFIGITEM_SECURITYENGINEIRQ:
|
||||||
|
/* SE is interrupt #44. */
|
||||||
|
*p_outvalue = 0x2C;
|
||||||
|
break;
|
||||||
|
case CONFIGITEM_UNK04:
|
||||||
|
/* Always returns 2 on hardware. */
|
||||||
|
*p_outvalue = 2;
|
||||||
|
break;
|
||||||
|
case CONFIGITEM_HARDWARETYPE:
|
||||||
|
/* TODO: Fuse driver */
|
||||||
|
break;
|
||||||
|
case CONFIGITEM_ISRETAIL:
|
||||||
|
/* TODO: Fuse driver */
|
||||||
|
break;
|
||||||
|
case CONFIGITEM_ISRECOVERYBOOT:
|
||||||
|
/* TODO: This is just a constant, hardcoded into TZ on retail. How should we support? */
|
||||||
|
*p_outvalue = 0;
|
||||||
|
break;
|
||||||
|
case CONFIGITEM_DEVICEID:
|
||||||
|
/* TODO: Fuse driver */
|
||||||
|
break;
|
||||||
|
case CONFIGITEM_BOOTREASON:
|
||||||
|
/* TODO: This requires reading values passed to crt0 via NX_Bootloader. TBD pending crt0 implementation. */
|
||||||
|
break;
|
||||||
|
case CONFIGITEM_MEMORYARRANGE:
|
||||||
|
/* TODO: More BootConfig stuff. */
|
||||||
|
break;
|
||||||
|
case CONFIGITEM_ISDEBUGMODE:
|
||||||
|
/* TODO: More BootConfig stuff. */
|
||||||
|
break;
|
||||||
|
case CONFIGITEM_KERNELMEMORYCONFIGURATION:
|
||||||
|
/* TODO: More BootConfig stuff. */
|
||||||
|
break;
|
||||||
|
case CONFIGITEM_BATTERYPROFILE:
|
||||||
|
*p_outvalue = g_battery_profile;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
result = 2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
26
exosphere/configitem.h
Normal file
26
exosphere/configitem.h
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
#ifndef EXOSPHERE_CFG_ITEM_H
|
||||||
|
#define EXOSPHERE_CFG_ITEM_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
|
||||||
|
enum ConfigItem {
|
||||||
|
CONFIGITEM_DISABLEPROGRAMVERIFICATION = 1,
|
||||||
|
CONFIGITEM_MEMORYCONFIGURATION = 2,
|
||||||
|
CONFIGITEM_SECURITYENGINEIRQ = 3,
|
||||||
|
CONFIGITEM_UNK04 = 4,
|
||||||
|
CONFIGITEM_HARDWARETYPE = 5,
|
||||||
|
CONFIGITEM_ISRETAIL = 6,
|
||||||
|
CONFIGITEM_ISRECOVERYBOOT = 7,
|
||||||
|
CONFIGITEM_DEVICEID = 8,
|
||||||
|
CONFIGITEM_BOOTREASON = 9,
|
||||||
|
CONFIGITEM_MEMORYARRANGE = 10,
|
||||||
|
CONFIGITEM_ISDEBUGMODE = 11,
|
||||||
|
CONFIGITEM_KERNELMEMORYCONFIGURATION = 12,
|
||||||
|
CONFIGITEM_BATTERYPROFILE = 13
|
||||||
|
};
|
||||||
|
|
||||||
|
uint32_t configitem_set(enum ConfigItem item, uint64_t value);
|
||||||
|
uint32_t configitem_get(enum ConfigItem item, uint64_t *p_outvalue);
|
||||||
|
|
||||||
|
#endif
|
|
@ -1,6 +1,7 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
#include "configitem.h"
|
||||||
#include "cpu_context.h"
|
#include "cpu_context.h"
|
||||||
#include "smc_api.h"
|
#include "smc_api.h"
|
||||||
#include "smc_user.h"
|
#include "smc_user.h"
|
||||||
|
@ -129,6 +130,12 @@ void call_smc_handler(uint32_t handler_id, smc_args_t *args) {
|
||||||
panic();
|
panic();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Validate core is appropriate for handler. */
|
||||||
|
if (handler_id == SMC_HANDLER_USER && get_core_id() != 3) {
|
||||||
|
/* USER SMCs must be called via svcCallSecureMonitor on core 3 (where spl runs) */
|
||||||
|
panic();
|
||||||
|
}
|
||||||
|
|
||||||
/* Validate sub-handler index */
|
/* Validate sub-handler index */
|
||||||
if ((smc_id = (unsigned char)args->X[0]) >= g_smc_tables[handler_id].num_handlers) {
|
if ((smc_id = (unsigned char)args->X[0]) >= g_smc_tables[handler_id].num_handlers) {
|
||||||
panic();
|
panic();
|
||||||
|
@ -185,6 +192,19 @@ uint32_t smc_wrapper_async(smc_args_t *args, uint32_t (*handler)(smc_args_t *),
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t smc_set_config(smc_args_t *args) {
|
||||||
|
/* Actual value presumed in X3 on hardware. */
|
||||||
|
return configitem_set((enum ConfigItem)args->X[1], args->X[3]);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t smc_get_config(smc_args_t *args) {
|
||||||
|
uint64_t out_item = 0;
|
||||||
|
uint32_t result;
|
||||||
|
result = configitem_get((enum ConfigItem)args->X[1], &out_item);
|
||||||
|
args->X[1] = out_item;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t smc_check_status(smc_args_t *args) {
|
uint32_t smc_check_status(smc_args_t *args) {
|
||||||
if (g_smc_callback_key == 0) {
|
if (g_smc_callback_key == 0) {
|
||||||
return 4;
|
return 4;
|
||||||
|
|
|
@ -17,7 +17,7 @@ static inline uint32_t read32be(const unsigned char *dword, size_t offset) {
|
||||||
static inline unsigned int get_core_id(void) {
|
static inline unsigned int get_core_id(void) {
|
||||||
unsigned int core_id;
|
unsigned int core_id;
|
||||||
__asm__ __volatile__ ("mrs %0, MPIDR_EL1" : "=r"(core_id));
|
__asm__ __volatile__ ("mrs %0, MPIDR_EL1" : "=r"(core_id));
|
||||||
return core_id;
|
return core_id & 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue