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 "utils.h"
|
||||
#include "configitem.h"
|
||||
#include "cpu_context.h"
|
||||
#include "smc_api.h"
|
||||
#include "smc_user.h"
|
||||
|
@ -129,6 +130,12 @@ void call_smc_handler(uint32_t handler_id, smc_args_t *args) {
|
|||
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 */
|
||||
if ((smc_id = (unsigned char)args->X[0]) >= g_smc_tables[handler_id].num_handlers) {
|
||||
panic();
|
||||
|
@ -185,6 +192,19 @@ uint32_t smc_wrapper_async(smc_args_t *args, uint32_t (*handler)(smc_args_t *),
|
|||
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) {
|
||||
if (g_smc_callback_key == 0) {
|
||||
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) {
|
||||
unsigned int core_id;
|
||||
__asm__ __volatile__ ("mrs %0, MPIDR_EL1" : "=r"(core_id));
|
||||
return core_id;
|
||||
return core_id & 3;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue