mirror of
https://github.com/Atmosphere-NX/Atmosphere.git
synced 2024-11-24 07:40:26 +01:00
Add wrapper for async SMCs
This commit is contained in:
parent
8ea1ac0ecc
commit
49e1e6f41e
@ -108,6 +108,8 @@ void set_se_ctr(const char *ctr);
|
|||||||
void se_crypt_aes(unsigned int keyslot, unsigned char *dst, unsigned int dst_size, const unsigned char *src, unsigned int src_size, unsigned int config, unsigned int mode, unsigned int (*callback)(void));
|
void se_crypt_aes(unsigned int keyslot, unsigned char *dst, unsigned int dst_size, const unsigned char *src, unsigned int src_size, unsigned int config, unsigned int mode, unsigned int (*callback)(void));
|
||||||
void se_exp_mod(unsigned int keyslot, unsigned char *buf, unsigned int size, unsigned int (*callback)(void));
|
void se_exp_mod(unsigned int keyslot, unsigned char *buf, unsigned int size, unsigned int (*callback)(void));
|
||||||
|
|
||||||
|
void se_generate_random(unsigned int keyslot, unsigned char *dst, unsigned int size);
|
||||||
|
|
||||||
/* TODO: SE context save API, consider extending AES API for secure world vs non-secure world operations. */
|
/* TODO: SE context save API, consider extending AES API for secure world vs non-secure world operations. */
|
||||||
/* In particular, smc_crypt_aes takes in raw DMA lists, and we need to support that. */
|
/* In particular, smc_crypt_aes takes in raw DMA lists, and we need to support that. */
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "smc_api.h"
|
#include "smc_api.h"
|
||||||
|
#include "se.h"
|
||||||
|
|
||||||
#define SMC_USER_HANDLERS 0x13
|
#define SMC_USER_HANDLERS 0x13
|
||||||
#define SMC_PRIV_HANDLERS 0x9
|
#define SMC_PRIV_HANDLERS 0x9
|
||||||
@ -92,6 +93,29 @@ smc_table_t g_smc_tables[2] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
int g_is_smc_in_progress = 0;
|
int g_is_smc_in_progress = 0;
|
||||||
|
uint32_t (*g_smc_callback)(uint64_t, uint64_t) = NULL;
|
||||||
|
uint64_t g_smc_callback_key = 0;
|
||||||
|
|
||||||
|
uint64_t try_set_smc_callback(uint32_t (*callback)(uint64_t, uint64_t)) {
|
||||||
|
uint64_t key;
|
||||||
|
/* TODO: Atomics... */
|
||||||
|
if (g_smc_callback_key) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TODO: Keyslot defines. */
|
||||||
|
se_generate_random(0xB, &key, sizeof(uint64_t));
|
||||||
|
g_smc_callback_key = key;
|
||||||
|
g_smc_callback = callback;
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
|
||||||
|
void clear_smc_callback(uint64_t key) {
|
||||||
|
/* TODO: Atomics... */
|
||||||
|
if (g_smc_callback_key == key) {
|
||||||
|
g_smc_callback_key = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void call_smc_handler(uint32_t handler_id, smc_args_t *args) {
|
void call_smc_handler(uint32_t handler_id, smc_args_t *args) {
|
||||||
unsigned char smc_id;
|
unsigned char smc_id;
|
||||||
@ -134,4 +158,27 @@ uint32_t smc_wrapper_sync(smc_args_t *args, uint32_t (*handler)(smc_args_t *)) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t smc_wrapper_async(smc_args_t *args, uint32_t (*handler)(smc_args_t *), uint32_t (*callback)(void, void));
|
uint32_t smc_wrapper_async(smc_args_t *args, uint32_t (*handler)(smc_args_t *), uint32_t (*callback)(uint64_t, uint64_t)) {
|
||||||
|
uint32_t result;
|
||||||
|
uint64_t key;
|
||||||
|
/* TODO: Make g_is_smc_in_progress atomic. */
|
||||||
|
if (g_is_smc_in_progress) {
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
g_is_smc_in_progress = 1;
|
||||||
|
if ((key = try_set_smc_callback(callback)) != 0) {
|
||||||
|
result = handler(args);
|
||||||
|
if (result == 0) {
|
||||||
|
/* Pass the status check key back to userland. */
|
||||||
|
args->X[1] = key;
|
||||||
|
} else {
|
||||||
|
/* No status to check. */
|
||||||
|
clear_smc_callback(key);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* smcCheckStatus needs to be called. */
|
||||||
|
result = 3;
|
||||||
|
}
|
||||||
|
g_is_smc_in_progress = 0;
|
||||||
|
return result;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user