From d1d8d3da345062af7fc1719f64635936f6a9cc52 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Thu, 22 Feb 2018 17:50:19 -0800 Subject: [PATCH] Switch all MMIO to the new access style --- exosphere/pmc.c | 11 -- exosphere/pmc.h | 8 +- exosphere/se.c | 272 ++++++++++++++++++++------------------------- exosphere/se.h | 1 - exosphere/timers.c | 10 -- exosphere/timers.h | 6 +- exosphere/uart.c | 10 -- exosphere/uart.h | 16 +-- 8 files changed, 137 insertions(+), 197 deletions(-) delete mode 100644 exosphere/pmc.c diff --git a/exosphere/pmc.c b/exosphere/pmc.c deleted file mode 100644 index afc0fd4a9..000000000 --- a/exosphere/pmc.c +++ /dev/null @@ -1,11 +0,0 @@ -#include "pmc.h" - -volatile void *g_pmc_registers = NULL; - -void set_pmc_address(void *pmc_base) { - g_pmc_registers = pmc_base; -} - -inline void *get_pmc_address(void) { - return g_pmc_registers; -} \ No newline at end of file diff --git a/exosphere/pmc.h b/exosphere/pmc.h index 8140bfc4b..6bbac0862 100644 --- a/exosphere/pmc.h +++ b/exosphere/pmc.h @@ -2,13 +2,13 @@ #define EXOSPHERE_PMC_H #include +#include "mmu.h" /* Exosphere register definitions for the Tegra X1 PMC. */ -void set_pmc_address(void *pmc_base); -void *get_pmc_address(void); /* This is inlined in pmc.c */ +#define PMC_BASE (mmio_get_device_address(MMIO_DEVID_RTC_PMC) + 0x400ULL) -#define APBDEV_PMC_PWRGATE_TOGGLE_0 (*((volatile uint32_t *)(get_pmc_address() + 0x430))) -#define APBDEV_PMC_PWRGATE_STATUS_0 (*((volatile uint32_t *)(get_pmc_address() + 0x438))) +#define APBDEV_PMC_PWRGATE_TOGGLE_0 (*((volatile uint32_t *)(PMC_BASE + 0x30))) +#define APBDEV_PMC_PWRGATE_STATUS_0 (*((volatile uint32_t *)(PMC_BASE + 0x38))) #endif \ No newline at end of file diff --git a/exosphere/se.c b/exosphere/se.c index 6a203cdee..94bc40994 100644 --- a/exosphere/se.c +++ b/exosphere/se.c @@ -2,15 +2,17 @@ #include #include "utils.h" +#include "mmu.h" #include "cache.h" #include "se.h" +/* Macro for the SE registers. */ +#define SECURITY_ENGINE ((volatile security_engine_t *)(mmio_get_device_address(MMIO_DEVID_SE))) + void trigger_se_rsa_op(void *buf, size_t size); void trigger_se_blocking_op(unsigned int op, void *dst, size_t dst_size, const void *src, size_t src_size); /* Globals for driver. */ -volatile security_engine_t *g_security_engine; - unsigned int (*g_se_callback)(void); unsigned int g_se_modulus_sizes[KEYSLOT_RSA_MAX]; @@ -32,14 +34,9 @@ void ll_init(se_ll_t *ll, void *buffer, size_t size) { flush_dcache_range((uint8_t *)ll, (uint8_t *)ll + sizeof(*ll)); } -/* Set the global security engine pointer. */ -void set_security_engine_address(security_engine_t *security_engine) { - g_security_engine = security_engine; -} - -/* Get the global security engine pointer. */ +/* Gets security engine pointer. */ security_engine_t *get_security_engine_address(void) { - return g_security_engine; + return SECURITY_ENGINE; } void set_security_engine_callback(unsigned int (*callback)(void)) { @@ -52,10 +49,7 @@ void set_security_engine_callback(unsigned int (*callback)(void)) { /* Fires on Security Engine operation completion. */ void se_operation_completed(void) { - if (g_security_engine == NULL) { - panic(); - } - g_security_engine->INT_ENABLE_REG = 0; + SECURITY_ENGINE->INT_ENABLE_REG = 0; if (g_se_callback != NULL) { g_se_callback(); g_se_callback = NULL; @@ -64,11 +58,7 @@ void se_operation_completed(void) { void se_check_for_error(void) { - if (g_security_engine == NULL) { - panic(); - } - - if (g_security_engine->INT_STATUS_REG & 0x10000 || g_security_engine->FLAGS_REG & 3 || g_security_engine->ERR_STATUS_REG) { + if (SECURITY_ENGINE->INT_STATUS_REG & 0x10000 || SECURITY_ENGINE->FLAGS_REG & 3 || SECURITY_ENGINE->ERR_STATUS_REG) { panic(); } } @@ -78,7 +68,7 @@ void se_trigger_intrrupt(void) { } void se_verify_flags_cleared(void) { - if (g_security_engine == NULL || g_security_engine->FLAGS_REG & 3) { + if (SECURITY_ENGINE->FLAGS_REG & 3) { panic(); } } @@ -89,93 +79,93 @@ void se_clear_interrupts(void) { /* Set the flags for an AES keyslot. */ void set_aes_keyslot_flags(unsigned int keyslot, unsigned int flags) { - if (g_security_engine == NULL || keyslot >= KEYSLOT_AES_MAX) { + if (keyslot >= KEYSLOT_AES_MAX) { panic(); } /* Misc flags. */ if (flags & ~0x80) { - g_security_engine->AES_KEYSLOT_FLAGS[keyslot] = ~flags; + SECURITY_ENGINE->AES_KEYSLOT_FLAGS[keyslot] = ~flags; } /* Disable keyslot reads. */ if (flags & 0x80) { - g_security_engine->AES_KEY_READ_DISABLE_REG &= ~(1 << keyslot); + SECURITY_ENGINE->AES_KEY_READ_DISABLE_REG &= ~(1 << keyslot); } } /* Set the flags for an RSA keyslot. */ void set_rsa_keyslot_flags(unsigned int keyslot, unsigned int flags) { - if (g_security_engine == NULL || keyslot >= KEYSLOT_RSA_MAX) { + if (keyslot >= KEYSLOT_RSA_MAX) { panic(); } /* Misc flags. */ if (flags & ~0x80) { /* TODO: Why are flags assigned this way? */ - g_security_engine->RSA_KEYSLOT_FLAGS[keyslot] = (((flags >> 4) & 4) | (flags & 3)) ^ 7; + SECURITY_ENGINE->RSA_KEYSLOT_FLAGS[keyslot] = (((flags >> 4) & 4) | (flags & 3)) ^ 7; } /* Disable keyslot reads. */ if (flags & 0x80) { - g_security_engine->RSA_KEY_READ_DISABLE_REG &= ~(1 << keyslot); + SECURITY_ENGINE->RSA_KEY_READ_DISABLE_REG &= ~(1 << keyslot); } } void clear_aes_keyslot(unsigned int keyslot) { - if (g_security_engine == NULL || keyslot >= KEYSLOT_AES_MAX) { + if (keyslot >= KEYSLOT_AES_MAX) { panic(); } /* Zero out the whole keyslot and IV. */ for (unsigned int i = 0; i < 0x10; i++) { - g_security_engine->AES_KEYTABLE_ADDR = (keyslot << 4) | i; - g_security_engine->AES_KEYTABLE_DATA = 0; + SECURITY_ENGINE->AES_KEYTABLE_ADDR = (keyslot << 4) | i; + SECURITY_ENGINE->AES_KEYTABLE_DATA = 0; } } void clear_rsa_keyslot(unsigned int keyslot) { - if (g_security_engine == NULL || keyslot >= KEYSLOT_RSA_MAX) { + if (keyslot >= KEYSLOT_RSA_MAX) { panic(); } /* Zero out the whole keyslot. */ for (unsigned int i = 0; i < 0x40; i++) { /* Select Keyslot Modulus[i] */ - g_security_engine->RSA_KEYTABLE_ADDR = (keyslot << 7) | i | 0x40; - g_security_engine->RSA_KEYTABLE_DATA = 0; + SECURITY_ENGINE->RSA_KEYTABLE_ADDR = (keyslot << 7) | i | 0x40; + SECURITY_ENGINE->RSA_KEYTABLE_DATA = 0; } for (unsigned int i = 0; i < 0x40; i++) { /* Select Keyslot Expontent[i] */ - g_security_engine->RSA_KEYTABLE_ADDR = (keyslot << 7) | i; - g_security_engine->RSA_KEYTABLE_DATA = 0; + SECURITY_ENGINE->RSA_KEYTABLE_ADDR = (keyslot << 7) | i; + SECURITY_ENGINE->RSA_KEYTABLE_DATA = 0; } } void set_aes_keyslot(unsigned int keyslot, const void *key, size_t key_size) { - if (g_security_engine == NULL || keyslot >= KEYSLOT_AES_MAX || key_size > KEYSIZE_AES_MAX) { + if (keyslot >= KEYSLOT_AES_MAX || key_size > KEYSIZE_AES_MAX) { panic(); } for (size_t i = 0; i < (key_size >> 2); i++) { - g_security_engine->AES_KEYTABLE_ADDR = (keyslot << 4) | i; - g_security_engine->AES_KEYTABLE_DATA = read32le(key, 4 * i); + SECURITY_ENGINE->AES_KEYTABLE_ADDR = (keyslot << 4) | i; + SECURITY_ENGINE->AES_KEYTABLE_DATA = read32le(key, 4 * i); } } void set_rsa_keyslot(unsigned int keyslot, const void *modulus, size_t modulus_size, const void *exponent, size_t exp_size) { - if (g_security_engine == NULL || keyslot >= KEYSLOT_RSA_MAX || modulus_size > KEYSIZE_RSA_MAX || exp_size > KEYSIZE_RSA_MAX) { + if (keyslot >= KEYSLOT_RSA_MAX || modulus_size > KEYSIZE_RSA_MAX || exp_size > KEYSIZE_RSA_MAX) { panic(); } for (size_t i = 0; i < (modulus_size >> 2); i++) { - g_security_engine->RSA_KEYTABLE_ADDR = (keyslot << 7) | 0x40 | i; - g_security_engine->RSA_KEYTABLE_DATA = read32be(modulus, 4 * i); + SECURITY_ENGINE->RSA_KEYTABLE_ADDR = (keyslot << 7) | 0x40 | i; + SECURITY_ENGINE->RSA_KEYTABLE_DATA = read32be(modulus, 4 * i); } for (size_t i = 0; i < (exp_size >> 2); i++) { - g_security_engine->RSA_KEYTABLE_ADDR = (keyslot << 7) | i; - g_security_engine->RSA_KEYTABLE_DATA = read32be(exponent, 4 * i); + SECURITY_ENGINE->RSA_KEYTABLE_ADDR = (keyslot << 7) | i; + SECURITY_ENGINE->RSA_KEYTABLE_DATA = read32be(exponent, 4 * i); } g_se_modulus_sizes[keyslot] = modulus_size; @@ -183,53 +173,49 @@ void set_rsa_keyslot(unsigned int keyslot, const void *modulus, size_t modulus_ } void set_aes_keyslot_iv(unsigned int keyslot, const void *iv, size_t iv_size) { - if (g_security_engine == NULL || keyslot >= KEYSLOT_AES_MAX || iv_size > 0x10) { + if (keyslot >= KEYSLOT_AES_MAX || iv_size > 0x10) { panic(); } for (size_t i = 0; i < (iv_size >> 2); i++) { - g_security_engine->AES_KEYTABLE_ADDR = (keyslot << 4) | 8 | i; - g_security_engine->AES_KEYTABLE_DATA = read32le(iv, 4 * i); + SECURITY_ENGINE->AES_KEYTABLE_ADDR = (keyslot << 4) | 8 | i; + SECURITY_ENGINE->AES_KEYTABLE_DATA = read32le(iv, 4 * i); } } void clear_aes_keyslot_iv(unsigned int keyslot) { - if (g_security_engine == NULL || keyslot >= KEYSLOT_AES_MAX) { + if (keyslot >= KEYSLOT_AES_MAX) { panic(); } for (size_t i = 0; i < (0x10 >> 2); i++) { - g_security_engine->AES_KEYTABLE_ADDR = (keyslot << 4) | 8; - g_security_engine->AES_KEYTABLE_DATA = 0; + SECURITY_ENGINE->AES_KEYTABLE_ADDR = (keyslot << 4) | 8; + SECURITY_ENGINE->AES_KEYTABLE_DATA = 0; } } void set_se_ctr(const void *ctr) { - if (g_security_engine == NULL) { - panic(); - } - for (unsigned int i = 0; i < 4; i++) { - g_security_engine->CRYPTO_CTR_REG[i] = read32le(ctr, i * 4); + SECURITY_ENGINE->CRYPTO_CTR_REG[i] = read32le(ctr, i * 4); } } void decrypt_data_into_keyslot(unsigned int keyslot_dst, unsigned int keyslot_src, const void *wrapped_key, size_t wrapped_key_size) { - if (g_security_engine == NULL || keyslot_dst >= KEYSLOT_AES_MAX || keyslot_src >= KEYSIZE_AES_MAX || wrapped_key_size > KEYSIZE_AES_MAX) { + if (keyslot_dst >= KEYSLOT_AES_MAX || keyslot_src >= KEYSIZE_AES_MAX || wrapped_key_size > KEYSIZE_AES_MAX) { panic(); } - g_security_engine->CONFIG_REG = (ALG_AES_DEC | DST_KEYTAB); - g_security_engine->CRYPTO_REG = keyslot_src << 24; - g_security_engine->BLOCK_COUNT_REG = 0; - g_security_engine->CRYPTO_KEYTABLE_DST_REG = keyslot_dst << 8; + SECURITY_ENGINE->CONFIG_REG = (ALG_AES_DEC | DST_KEYTAB); + SECURITY_ENGINE->CRYPTO_REG = keyslot_src << 24; + SECURITY_ENGINE->BLOCK_COUNT_REG = 0; + SECURITY_ENGINE->CRYPTO_KEYTABLE_DST_REG = keyslot_dst << 8; flush_dcache_range(wrapped_key, (const uint8_t *)wrapped_key + wrapped_key_size); trigger_se_aes_op(OP_START, NULL, 0, wrapped_key, wrapped_key_size); } void se_aes_crypt_insecure_internal(unsigned int keyslot, uint32_t out_ll_paddr, uint32_t in_ll_paddr, size_t size, unsigned int crypt_config, int encrypt, unsigned int (*callback)(void)) { - if (g_security_engine == NULL || keyslot >= KEYSLOT_AES_MAX) { + if (keyslot >= KEYSLOT_AES_MAX) { panic(); } @@ -240,64 +226,52 @@ void se_aes_crypt_insecure_internal(unsigned int keyslot, uint32_t out_ll_paddr, /* Setup Config register. */ encrypt &= 1; if (encrypt) { - g_security_engine->CONFIG_REG = (ALG_AES_ENC | DST_MEMORY); + SECURITY_ENGINE->CONFIG_REG = (ALG_AES_ENC | DST_MEMORY); } else { - g_security_engine->CONFIG_REG = (ALG_AES_DEC | DST_MEMORY); + SECURITY_ENGINE->CONFIG_REG = (ALG_AES_DEC | DST_MEMORY); } /* Setup Crypto register. */ - g_security_engine->CRYPTO_REG = crypt_config | (keyslot << 24) | (encrypt << 8); + SECURITY_ENGINE->CRYPTO_REG = crypt_config | (keyslot << 24) | (encrypt << 8); /* Mark this encryption as insecure -- this makes the SE not a secure busmaster. */ - g_security_engine->CRYPTO_REG |= 0x80000000; + SECURITY_ENGINE->CRYPTO_REG |= 0x80000000; /* Appropriate number of blocks. */ - g_security_engine->BLOCK_COUNT_REG = (size >> 4) - 1; + SECURITY_ENGINE->BLOCK_COUNT_REG = (size >> 4) - 1; /* Set the callback, for after the async operation. */ set_security_engine_callback(callback); /* Enable SE Interrupt firing for async op. */ - g_security_engine->INT_ENABLE_REG = 0x10; + SECURITY_ENGINE->INT_ENABLE_REG = 0x10; /* Setup Input/Output lists */ - g_security_engine->IN_LL_ADDR_REG = in_ll_paddr; - g_security_engine->OUT_LL_ADDR_REG = out_ll_paddr; + SECURITY_ENGINE->IN_LL_ADDR_REG = in_ll_paddr; + SECURITY_ENGINE->OUT_LL_ADDR_REG = out_ll_paddr; /* Set registers for operation. */ - g_security_engine->ERR_STATUS_REG = g_security_engine->ERR_STATUS_REG; - g_security_engine->INT_STATUS_REG = g_security_engine->INT_STATUS_REG; - g_security_engine->OPERATION_REG = 1; + SECURITY_ENGINE->ERR_STATUS_REG = SECURITY_ENGINE->ERR_STATUS_REG; + SECURITY_ENGINE->INT_STATUS_REG = SECURITY_ENGINE->INT_STATUS_REG; + SECURITY_ENGINE->OPERATION_REG = 1; /* Ensure writes go through. */ __asm__ __volatile__ ("dsb ish" : : : "memory"); } void se_aes_ctr_crypt_insecure(unsigned int keyslot, uint32_t out_ll_paddr, uint32_t in_ll_paddr, size_t size, const void *ctr, unsigned int (*callback)(void)) { - if (g_security_engine == NULL) { - panic(); - } - /* Unknown what this write does, but official code writes it for CTR mode. */ - g_security_engine->_0x80C = 1; + SECURITY_ENGINE->_0x80C = 1; set_se_ctr(ctr); se_aes_crypt_insecure_internal(keyslot, out_ll_paddr, in_ll_paddr, size, 0x81E, 1, callback); } void se_aes_cbc_encrypt_insecure(unsigned int keyslot, uint32_t out_ll_paddr, uint32_t in_ll_paddr, size_t size, const void *iv, unsigned int (*callback)(void)) { - if (g_security_engine == NULL) { - panic(); - } - set_aes_keyslot_iv(keyslot, iv, 0x10); se_aes_crypt_insecure_internal(keyslot, out_ll_paddr, in_ll_paddr, size, 0x44, 1, callback); } -void se_aes_cbc_decrypt_insecure(unsigned int keyslot, uint32_t out_ll_paddr, uint32_t in_ll_paddr, size_t size, const void *iv, unsigned int (*callback)(void)) { - if (g_security_engine == NULL) { - panic(); - } - +void se_aes_cbc_decrypt_insecure(unsigned int keyslot, uint32_t out_ll_paddr, uint32_t in_ll_paddr, size_t size, const void *iv, unsigned int (*callback)(void)) { set_aes_keyslot_iv(keyslot, iv, 0x10); se_aes_crypt_insecure_internal(keyslot, out_ll_paddr, in_ll_paddr, size, 0x66, 0, callback); } @@ -306,7 +280,7 @@ void se_aes_cbc_decrypt_insecure(unsigned int keyslot, uint32_t out_ll_paddr, ui void se_exp_mod(unsigned int keyslot, void *buf, size_t size, unsigned int (*callback)(void)) { uint8_t stack_buf[KEYSIZE_RSA_MAX]; - if (g_security_engine == NULL || keyslot >= KEYSLOT_RSA_MAX || size > KEYSIZE_RSA_MAX) { + if (keyslot >= KEYSLOT_RSA_MAX || size > KEYSIZE_RSA_MAX) { panic(); } @@ -316,26 +290,26 @@ void se_exp_mod(unsigned int keyslot, void *buf, size_t size, unsigned int (*cal } - g_security_engine->CONFIG_REG = (ALG_RSA | DST_RSAREG); - g_security_engine->RSA_CONFIG = keyslot << 24; - g_security_engine->RSA_KEY_SIZE_REG = (g_se_modulus_sizes[keyslot] >> 6) - 1; - g_security_engine->RSA_EXP_SIZE_REG = g_se_exp_sizes[keyslot] >> 2; + SECURITY_ENGINE->CONFIG_REG = (ALG_RSA | DST_RSAREG); + SECURITY_ENGINE->RSA_CONFIG = keyslot << 24; + SECURITY_ENGINE->RSA_KEY_SIZE_REG = (g_se_modulus_sizes[keyslot] >> 6) - 1; + SECURITY_ENGINE->RSA_EXP_SIZE_REG = g_se_exp_sizes[keyslot] >> 2; set_security_engine_callback(callback); /* Enable SE Interrupt firing for async op. */ - g_security_engine->INT_ENABLE_REG = 0x10; + SECURITY_ENGINE->INT_ENABLE_REG = 0x10; flush_dcache_range(stack_buf, stack_buf + KEYSIZE_RSA_MAX); trigger_se_rsa_op(stack_buf, size); - while (!(g_security_engine->INT_STATUS_REG & 2)) { /* Wait a while */ } + while (!(SECURITY_ENGINE->INT_STATUS_REG & 2)) { /* Wait a while */ } } void se_synchronous_exp_mod(unsigned int keyslot, void *dst, size_t dst_size, const void *src, size_t src_size) { uint8_t stack_buf[KEYSIZE_RSA_MAX]; - if (g_security_engine == NULL || keyslot >= KEYSLOT_RSA_MAX || src_size > KEYSIZE_RSA_MAX || dst_size > KEYSIZE_RSA_MAX) { + if (keyslot >= KEYSLOT_RSA_MAX || src_size > KEYSIZE_RSA_MAX || dst_size > KEYSIZE_RSA_MAX) { panic(); } @@ -344,10 +318,10 @@ void se_synchronous_exp_mod(unsigned int keyslot, void *dst, size_t dst_size, co stack_buf[i] = *((uint8_t *)buf + size - i); } - g_security_engine->CONFIG_REG = (ALG_RSA | DST_RSAREG); - g_security_engine->RSA_CONFIG = keyslot << 24; - g_security_engine->RSA_KEY_SIZE_REG = (g_se_modulus_sizes[keyslot] >> 6) - 1; - g_security_engine->RSA_EXP_SIZE_REG = g_se_exp_sizes[keyslot] >> 2; + SECURITY_ENGINE->CONFIG_REG = (ALG_RSA | DST_RSAREG); + SECURITY_ENGINE->RSA_CONFIG = keyslot << 24; + SECURITY_ENGINE->RSA_KEY_SIZE_REG = (g_se_modulus_sizes[keyslot] >> 6) - 1; + SECURITY_ENGINE->RSA_EXP_SIZE_REG = g_se_exp_sizes[keyslot] >> 2; flush_dcache_range(stack_buf, stack_buf + KEYSIZE_RSA_MAX); @@ -366,7 +340,7 @@ void se_get_exp_mod_output(void *buf, size_t size) { /* Copy endian swapped output. */ while (num_dwords) { - *p_out = read32be(g_security_engine->RSA_OUTPUT, offset); + *p_out = read32be(SECURITY_ENGINE->RSA_OUTPUT, offset); offset += 4; p_out--; num_dwords--; @@ -378,12 +352,12 @@ void trigger_se_rsa_op(void *buf, size_t size) { ll_init(&in_ll, buf, size); /* Set the input LL. */ - g_security_engine->IN_LL_ADDR_REG = get_physical_address(&in_ll); + SECURITY_ENGINE->IN_LL_ADDR_REG = get_physical_address(&in_ll); /* Set registers for operation. */ - g_security_engine->ERR_STATUS_REG = g_security_engine->ERR_STATUS_REG; - g_security_engine->INT_STATUS_REG = g_security_engine->INT_STATUS_REG; - g_security_engine->OPERATION_REG = 1; + SECURITY_ENGINE->ERR_STATUS_REG = SECURITY_ENGINE->ERR_STATUS_REG; + SECURITY_ENGINE->INT_STATUS_REG = SECURITY_ENGINE->INT_STATUS_REG; + SECURITY_ENGINE->OPERATION_REG = 1; /* Ensure writes go through. */ __asm__ __volatile__ ("dsb ish" : : : "memory"); @@ -397,15 +371,15 @@ void trigger_se_blocking_op(unsigned int op, void *dst, size_t dst_size, const v ll_init(&out_ll, dst, dst_size); /* Set the LLs. */ - g_security_engine->IN_LL_ADDR_REG = get_physical_address(&in_ll); + SECURITY_ENGINE->IN_LL_ADDR_REG = get_physical_address(&in_ll); g_security_enging->OUT_LL_ADDR_REG = get_physical_address(&out_ll); /* Set registers for operation. */ - g_security_engine->ERR_STATUS_REG = g_security_engine->ERR_STATUS_REG; - g_security_engine->INT_STATUS_REG = g_security_engine->INT_STATUS_REG; - g_security_engine->OPERATION_REG = op; + SECURITY_ENGINE->ERR_STATUS_REG = SECURITY_ENGINE->ERR_STATUS_REG; + SECURITY_ENGINE->INT_STATUS_REG = SECURITY_ENGINE->INT_STATUS_REG; + SECURITY_ENGINE->OPERATION_REG = op; - while (!(g_security_engine->INT_STATUS_REG & 0x10)) { /* Wait a while */ } + while (!(SECURITY_ENGINE->INT_STATUS_REG & 0x10)) { /* Wait a while */ } se_check_for_error(); } @@ -414,7 +388,7 @@ void trigger_se_blocking_op(unsigned int op, void *dst, size_t dst_size, const v void se_perform_aes_block_operation(void *dst, size_t dst_size, const void *src, size_t src_size) { uint8_t block[0x10]; - if (g_security_engine == NULL || src_size > sizeof(block) || dst_size > sizeof(block)) { + if (src_size > sizeof(block) || dst_size > sizeof(block)) { panic(); } @@ -424,7 +398,7 @@ void se_perform_aes_block_operation(void *dst, size_t dst_size, const void *src, flush_dcache_range(block, block + sizeof(block)); /* Trigger AES operation. */ - g_security_engine->BLOCK_COUNT_REG = 0; + SECURITY_ENGINE->BLOCK_COUNT_REG = 0; trigger_se_blocking_op(1, block, sizeof(block), block, sizeof(block)); /* Copy output data into dst. */ @@ -433,22 +407,22 @@ void se_perform_aes_block_operation(void *dst, size_t dst_size, const void *src, } void se_aes_ctr_crypt(unsigned int keyslot, void *dst, size_t dst_size, const void *src, size_t src_size, const void *ctr, size_t ctr_size) { - if (g_security_engine == NULL || keyslot >= KEYSLOT_AES_MAX || ctr_size != 0x10) { + if (keyslot >= KEYSLOT_AES_MAX || ctr_size != 0x10) { panic(); } unsigned int num_blocks = src_size >> 4; /* Unknown what this write does, but official code writes it for CTR mode. */ - g_security_engine->_0x80C = 1; - g_security_engine->CONFIG_REG = (ALG_AES_ENC | DST_MEMORY); - g_security_engine->CRYPTO_REG = (keyslot << 24) | 0x91E; + SECURITY_ENGINE->_0x80C = 1; + SECURITY_ENGINE->CONFIG_REG = (ALG_AES_ENC | DST_MEMORY); + SECURITY_ENGINE->CRYPTO_REG = (keyslot << 24) | 0x91E; set_se_ctr(ctr, ctr_size); /* Handle any aligned blocks. */ size_t aligned_size = (size_t)num_blocks << 4; if (aligned_size) { - g_security_engine->BLOCK_COUNT_REG = num_blocks - 1; + SECURITY_ENGINE->BLOCK_COUNT_REG = num_blocks - 1; trigger_se_blocking_op(1, dst, dst_size, src, aligned_size); } @@ -463,13 +437,13 @@ void se_aes_ctr_crypt(unsigned int keyslot, void *dst, size_t dst_size, const vo } void se_aes_ecb_encrypt_block(unsigned int keyslot, void *dst, size_t dst_size, const void *src, size_t src_size, unsigned int config_high) { - if (g_security_engine == NULL || keyslot >= KEYSLOT_AES_MAX || dst_size != 0x10 || src_size != 0x10) { + if (keyslot >= KEYSLOT_AES_MAX || dst_size != 0x10 || src_size != 0x10) { panic(); } /* Set configuration high (256-bit vs 128-bit) based on parameter. */ - g_security_engine->CONFIG_REG = (ALG_AES_ENC | DST_MEMORY) | (config_high << 16); - g_security_engine->CRYPTO_REG = keyslot << 24; + SECURITY_ENGINE->CONFIG_REG = (ALG_AES_ENC | DST_MEMORY) | (config_high << 16); + SECURITY_ENGINE->CRYPTO_REG = keyslot << 24; se_perform_aes_block_operation(1, dst, 0x10, src, 0x10); } @@ -484,12 +458,12 @@ void se_aes_256_ecb_encrypt_block(unsigned int keyslot, void *dst, size_t dst_si void se_aes_ecb_decrypt_block(unsigned int keyslot, void *dst, size_t dst_size, const void *src, size_t src_size) { - if (g_security_engine == NULL || keyslot >= KEYSLOT_AES_MAX || dst_size != 0x10 || src_size != 0x10) { + if (keyslot >= KEYSLOT_AES_MAX || dst_size != 0x10 || src_size != 0x10) { panic(); } - g_security_engine->CONFIG_REG = (ALG_AES_DEC | DST_MEMORY); - g_security_engine->CRYPTO_REG = keyslot << 24; + SECURITY_ENGINE->CONFIG_REG = (ALG_AES_DEC | DST_MEMORY); + SECURITY_ENGINE->CRYPTO_REG = keyslot << 24; se_perform_aes_block_operation(1, dst, 0x10, src, 0x10); } @@ -506,7 +480,7 @@ void shift_left_xor_rb(uint8_t *key) { } void se_compute_aes_cmac(unsigned int keyslot, void *cmac, size_t cmac_size, const void *data, size_t data_size, unsigned int config_high) { - if (g_security_engine == NULL || keyslot >= KEYSLOT_AES_MAX) { + if (keyslot >= KEYSLOT_AES_MAX) { panic(); } @@ -519,16 +493,16 @@ void se_compute_aes_cmac(unsigned int keyslot, void *cmac, size_t cmac_size, con shift_left_xor_rb(derived_key); } - g_security_engine->CONFIG_REG = (ALG_AES_ENC | DST_HASHREG) | (config_high << 16); - g_security_engine->CRYPTO_REG = (keyslot << 24) | (0x145); + SECURITY_ENGINE->CONFIG_REG = (ALG_AES_ENC | DST_HASHREG) | (config_high << 16); + SECURITY_ENGINE->CRYPTO_REG = (keyslot << 24) | (0x145); clear_aes_keyslot_iv(keyslot); unsigned int num_blocks = (data_size + 0xF) >> 4; /* Handle aligned blocks. */ if (num_blocks > 1) { - g_security_engine->BLOCK_COUNT_REG = num_blocks - 2; + SECURITY_ENGINE->BLOCK_COUNT_REG = num_blocks - 2; trigger_se_blocking_op(1, NULL, 0, data, data_size); - g_security_engine->CRYPTO_REG |= 0x80; + SECURITY_ENGINE->CRYPTO_REG |= 0x80; } /* Create final block. */ @@ -552,7 +526,7 @@ void se_compute_aes_cmac(unsigned int keyslot, void *cmac, size_t cmac_size, con /* Copy output CMAC. */ for (unsigned int i = 0; i < (cmac_size >> 2); i++) { - ((uint32_t *)cmac)[i] = read32le(g_security_engine->HASH_RESULT_REG, i << 2); + ((uint32_t *)cmac)[i] = read32le(SECURITY_ENGINE->HASH_RESULT_REG, i << 2); } } @@ -565,34 +539,30 @@ void se_compute_aes_256_cmac(unsigned int keyslot, void *cmac, size_t cmac_size, /* SHA256 Implementation. */ void se_calculate_sha256(void *dst, const void *src, size_t src_size) { - if (g_security_engine == NULL) { - panic(); - } - /* Setup config for SHA256, size = BITS(src_size) */ - g_security_engine->CONFIG_REG = (ENCMODE_SHA256 | ALG_SHA | DST_HASHREG); - g_security_engine->SHA_CONFIG_REG = 1; - g_security_engine->SHA_MSG_LENGTH_REG = (unsigned int)(src_size << 3); - g_security_engine->_0x20C = 0; - g_security_engine->_0x210 = 0; - g_security_engine->SHA_MSG_LEFT_REG = 0; - g_security_engine->_0x218 = (unsigned int)(src_size << 3); - g_security_engine->_0x21C = 0; - g_security_engine->_0x220 = 0; - g_security_engine->_0x224 = 0; + SECURITY_ENGINE->CONFIG_REG = (ENCMODE_SHA256 | ALG_SHA | DST_HASHREG); + SECURITY_ENGINE->SHA_CONFIG_REG = 1; + SECURITY_ENGINE->SHA_MSG_LENGTH_REG = (unsigned int)(src_size << 3); + SECURITY_ENGINE->_0x20C = 0; + SECURITY_ENGINE->_0x210 = 0; + SECURITY_ENGINE->SHA_MSG_LEFT_REG = 0; + SECURITY_ENGINE->_0x218 = (unsigned int)(src_size << 3); + SECURITY_ENGINE->_0x21C = 0; + SECURITY_ENGINE->_0x220 = 0; + SECURITY_ENGINE->_0x224 = 0; /* Trigger the operation. */ trigger_se_blocking_op(1, NULL, 0, src, src_size); /* Copy output hash. */ for (unsigned int i = 0; i < (0x20 >> 2); i++) { - ((uint32_t *)dst)[i] = read32be(g_security_engine->HASH_RESULT_REG, i << 2); + ((uint32_t *)dst)[i] = read32be(SECURITY_ENGINE->HASH_RESULT_REG, i << 2); } } /* RNG API */ void se_initialize_rng(unsigned int keyslot) { - if (g_security_engine == NULL || keyslot >= KEYSLOT_AES_MAX) { + if (keyslot >= KEYSLOT_AES_MAX) { panic(); } @@ -600,28 +570,28 @@ void se_initialize_rng(unsigned int keyslot) { /* This will be discarded, when done. */ uint8_t output_buf[0x10]; - g_security_engine->RNG_SRC_CONFIG_REG = 3; /* Entropy enable + Entropy lock enable */ - g_security_engine->RNG_RESEED_INTERVAL_REG = 70001; - g_security_engine->CONFIG_REG = (ALG_RNG | DST_MEMORY); - g_security_engine->CRYPTO_REG = (keyslot << 24) | 0x108; - g_security_engine->RNG_CONFIG_REG = 5; - g_security_engine->BLOCK_COUNT_REG = 0; + SECURITY_ENGINE->RNG_SRC_CONFIG_REG = 3; /* Entropy enable + Entropy lock enable */ + SECURITY_ENGINE->RNG_RESEED_INTERVAL_REG = 70001; + SECURITY_ENGINE->CONFIG_REG = (ALG_RNG | DST_MEMORY); + SECURITY_ENGINE->CRYPTO_REG = (keyslot << 24) | 0x108; + SECURITY_ENGINE->RNG_CONFIG_REG = 5; + SECURITY_ENGINE->BLOCK_COUNT_REG = 0; trigger_se_blocking_op(1, output_buf, 0x10, NULL, 0); } void se_generate_random(unsigned int keyslot, void *dst, size_t size) { - if (g_security_engine == NULL || keyslot >= KEYSLOT_AES_MAX) { + if (keyslot >= KEYSLOT_AES_MAX) { panic(); } uint32_t num_blocks = size >> 4; size_t aligned_size = num_blocks << 4; - g_security_engine->CONFIG_REG = (ALG_RNG | DST_MEMORY); - g_security_engine->CRYPTO_REG = (keyslot << 24) | 0x108; - g_security_engine->RNG_CONFIG_REG = 4; + SECURITY_ENGINE->CONFIG_REG = (ALG_RNG | DST_MEMORY); + SECURITY_ENGINE->CRYPTO_REG = (keyslot << 24) | 0x108; + SECURITY_ENGINE->RNG_CONFIG_REG = 4; if (num_blocks >= 1) { - g_security_engine->BLOCK_COUNT_REG = num_blocks - 1; + SECURITY_ENGINE->BLOCK_COUNT_REG = num_blocks - 1; trigger_se_blocking_op(1, dst, aligned_size, NULL, 0); } if (size > aligned_size) { diff --git a/exosphere/se.h b/exosphere/se.h index d41d53ed1..de1f99825 100644 --- a/exosphere/se.h +++ b/exosphere/se.h @@ -139,7 +139,6 @@ typedef struct { /* This function MUST be registered to fire on the appropriate interrupt. */ void se_operation_completed(void); -void set_security_engine_address(security_engine_t *security_engine); security_engine_t *get_security_engine_address(void); void se_check_for_error(void); diff --git a/exosphere/timers.c b/exosphere/timers.c index 38b2026ad..051f6b7fe 100644 --- a/exosphere/timers.c +++ b/exosphere/timers.c @@ -1,15 +1,5 @@ #include "timers.h" -volatile void *g_timer_registers = NULL; - -void set_timer_address(void *timer_base) { - g_timer_registers = timer_base; -} - -inline void *get_timer_address(void) { - return g_timer_registers; -} - void wait(uint32_t microseconds) { uint32_t old_time = TIMERUS_CNTR_1US_0; while (TIMERUS_CNTR_1US_0 - old_time <= result) { diff --git a/exosphere/timers.h b/exosphere/timers.h index db82ce7af..91d16b6d1 100644 --- a/exosphere/timers.h +++ b/exosphere/timers.h @@ -2,13 +2,13 @@ #define EXOSPHERE_TIMERS_H #include +#include "mmu.h" /* Exosphere driver for the Tegra X1 Timers. */ -void set_timer_address(void *timer_base); -void *get_timer_address(void); /* This is inlined in timers.c */ +#define TIMERS_BASE (mmio_get_device_address(MMIO_DEVID_TMRs_WDTs)) -#define TIMERUS_CNTR_1US_0 (*((volatile uint32_t *)(get_timer_address() + 0x10))) +#define TIMERUS_CNTR_1US_0 (*((volatile uint32_t *)(TIMERS_BASE + 0x10))) void wait(uint32_t microseconds); diff --git a/exosphere/uart.c b/exosphere/uart.c index 86b10d6e4..409d04dce 100644 --- a/exosphere/uart.c +++ b/exosphere/uart.c @@ -1,15 +1,5 @@ #include "uart.h" -volatile void *g_uart_registers = NULL; - -void set_uart_address(void *uart_base) { - g_uart_registers = uart_base; -} - -inline void *get_uart_address(void) { - return g_uart_registers; -} - void uart_initialize(uint16_t divider) { /* Setup UART in 16450 mode. We assume the relevant UART clock has been enabled. */ diff --git a/exosphere/uart.h b/exosphere/uart.h index 3da1219bf..5a431cc3d 100644 --- a/exosphere/uart.h +++ b/exosphere/uart.h @@ -2,17 +2,19 @@ #define EXOSPHERE_UART_H #include +#include "mmu.h" /* Exosphere driver for the Tegra X1 UARTs. */ -void set_uart_address(void *uart_base); -void *get_uart_address(void); /* This is inlined in uart.c */ +/* TODO: Should we bother with support UARTB-D? */ -#define UART_THR_DLAB_0_0 (*((volatile uint32_t *)(get_uart_address() + 0x0))) -#define UART_IER_DLAB_0_0 (*((volatile uint32_t *)(get_uart_address() + 0x4))) -#define UART_IIR_FCR_0 (*((volatile uint32_t *)(get_uart_address() + 0x8))) -#define UART_LCR_0 (*((volatile uint32_t *)(get_uart_address() + 0xC))) -#define UART_LSR_0 (*((volatile uint32_t *)(get_uart_address() + 0x14))) +#define UARTA_BASE (mmio_get_device_address(MMIO_DEVID_UART_A)) + +#define UART_THR_DLAB_0_0 (*((volatile uint32_t *)(UARTA_BASE + 0x0))) +#define UART_IER_DLAB_0_0 (*((volatile uint32_t *)(UARTA_BASE + 0x4))) +#define UART_IIR_FCR_0 (*((volatile uint32_t *)(UARTA_BASE+ 0x8))) +#define UART_LCR_0 (*((volatile uint32_t *)(UARTA_BASE + 0xC))) +#define UART_LSR_0 (*((volatile uint32_t *)(UARTA_BASE + 0x14))) void uart_initialize(uint16_t divider); void uart_transmit_char(char ch);