Exosphere: Fix bugs, now boots 5.1.0 successfully.

This commit is contained in:
Michael Scire 2018-06-01 22:20:04 -06:00
parent b566d04036
commit fa4c219395
10 changed files with 66 additions and 17 deletions

View file

@ -75,6 +75,14 @@ bool bootconfig_take_extabt_serror_to_el3(void) {
return (LOADED_BOOTCONFIG->unsigned_config.data[0x10] & 6) != 6;
}
uint64_t bootconfig_get_value_for_sysctr0(void) {
if (LOADED_BOOTCONFIG->unsigned_config.data[0x24] & 1) {
return *(volatile uint64_t *)(&(LOADED_BOOTCONFIG->unsigned_config.data[0x30]));
} else {
return 0ULL;
}
}
uint64_t bootconfig_get_memory_arrangement(void) {
if (bootconfig_is_debug_mode()) {
if (fuse_get_dram_id() == 4) {

View file

@ -59,6 +59,8 @@ bool bootconfig_is_debug_mode(void);
bool bootconfig_take_extabt_serror_to_el3(void);
uint64_t bootconfig_get_value_for_sysctr0(void);
uint64_t bootconfig_get_memory_arrangement(void);
uint64_t bootconfig_get_kernel_memory_configuration(void);

View file

@ -231,11 +231,17 @@ void setup_4x_mmio(void) {
AHB_ARBITRATION_DISABLE_0 |= 2;
/* Set SMMU for BPMP/APB-DMA to point to TZRAM. */
MC_SMMU_PTB_ASID_0 = 1;
(void)(MAKE_MC_REG(0x014));
MC_SMMU_PTB_DATA_0 = 0x70012;
MC_SMMU_AVPC_ASID_0 = 0x80000001;
MC_SMMU_PPCS1_ASID_0 = 0x80000001;
(void)(MAKE_MC_REG(0x014));
MAKE_MC_REG(0x34) = 0;
(void)(MAKE_MC_REG(0x014));
MAKE_MC_REG(0x30) = 0;
(void)(MAKE_MC_REG(0x014));
/* Wait for the BPMP to halt. */
while ((FLOW_CTLR_HALT_COP_EVENTS_0 >> 28) != 5) {
while ((FLOW_CTLR_HALT_COP_EVENTS_0 >> 29) != 2) {
wait(1);
}
/* If not in a debugging context, setup the activity monitor. */

View file

@ -18,7 +18,7 @@
#define EXOSPHERE_TARGET_FIRMWARE_500 5
/* TODO: What should this be, for release? */
#define EXOSPHERE_TARGET_FIRMWARE_DEFAULT_FOR_DEBUG EXOSPHERE_TARGET_FIRMWARE_100
#define EXOSPHERE_TARGET_FIRMWARE_DEFAULT_FOR_DEBUG EXOSPHERE_TARGET_FIRMWARE_500
#define EXOSPHERE_LOOSEN_PACKAGE2_RESTRICTIONS_FOR_DEBUG 1
#define MAILBOX_BASE_PHYS (MMIO_GET_DEVICE_PA(MMIO_DEVID_NXBOOTLOADER_MAILBOX))

View file

@ -106,8 +106,8 @@ void configure_kernel_carveout(unsigned int carveout_id, uint64_t address, uint6
carveout->flags_2 = 0x303C00;
carveout->flags_3 = 0xCF0830BB;
carveout->flags_4 = 0x3;
carveout->flags_5 = 0;
carveout->flags_6 = 0;
carveout->flags_5 = exosphere_get_target_firmware() >= EXOSPHERE_TARGET_FIRMWARE_400 && carveout_id == 4 ? 0x8000 : 0;
carveout->flags_6 = exosphere_get_target_firmware() >= EXOSPHERE_TARGET_FIRMWARE_400 && carveout_id == 4 ? 0x40000 : 0;
carveout->flags_7 = 0;
carveout->flags_8 = 0;
carveout->flags_9 = 0;

View file

@ -15,6 +15,7 @@
#include "randomcache.h"
#include "timers.h"
#include "bootconfig.h"
#include "sysctr0.h"
#include "exocfg.h"
#include "smc_api.h"
@ -407,6 +408,14 @@ void load_package2(coldboot_crt0_reloc_list_t *reloc_list) {
/* Setup the Security Engine. */
setup_se();
/* Perform initial PMC register writes, if relevant. */
if (exosphere_get_target_firmware() >= EXOSPHERE_TARGET_FIRMWARE_400) {
MAKE_REG32(PMC_BASE + 0x0A0) &= 0xFFF3FFFF;
MAKE_REG32(PMC_BASE + 0x818) &= 0xFFFFFFFE;
MAKE_REG32(PMC_BASE + 0x334) |= 0x10;
MAKE_REG32(PMC_BASE + 0x360) = 6;
}
wait(1000);
bootup_misc_mmio();
@ -433,6 +442,14 @@ void load_package2(coldboot_crt0_reloc_list_t *reloc_list) {
/* Load Boot Config into global. */
setup_boot_config();
/* Set sysctr0 registers based on bootconfig. */
if (exosphere_get_target_firmware() >= EXOSPHERE_TARGET_FIRMWARE_400) {
uint64_t sysctr0_val = bootconfig_get_value_for_sysctr0();
MAKE_SYSCTR0_REG(0x8) = (uint32_t)((sysctr0_val >> 0) & 0xFFFFFFFFULL);
MAKE_SYSCTR0_REG(0xC) = (uint32_t)((sysctr0_val >> 32) & 0xFFFFFFFFULL);
MAKE_SYSCTR0_REG(0x0) = 3;
}
/* Synchronize with NX BOOTLOADER. */
if (exosphere_get_target_firmware() >= EXOSPHERE_TARGET_FIRMWARE_400) {
sync_with_nx_bootloader(NX_BOOTLOADER_STATE_DRAM_INITIALIZED_4X);

View file

@ -234,16 +234,28 @@ void call_smc_handler(uint32_t handler_id, smc_args_t *args) {
generic_panic();
}
bool is_aes_kek = handler_id == SMC_HANDLER_USER && args->X[0] == 0xC3000007;
#if DEBUG_LOG_SMCS
uint64_t num;
if (handler_id == SMC_HANDLER_USER) {
uint64_t num = atomic_fetch_add(&num_smcs_called, 1);
*(volatile smc_args_t *)(get_iram_address_for_debug() + 0x100 + ((0x40 * num) & 0x3FFF)) = *args;
num = atomic_fetch_add(&num_smcs_called, 1);
*(volatile smc_args_t *)(get_iram_address_for_debug() + 0x100 + ((0x80 * num) & 0x3FFF)) = *args;
}
#endif
/* Call function. */
args->X[0] = smc_handler(args);
if (args->X[0])
#if DEBUG_LOG_SMCS
if (handler_id == SMC_HANDLER_USER) {
*(volatile smc_args_t *)(get_iram_address_for_debug() + 0x100 + ((0x80 * num + 0x40) & 0x3FFF)) = *args;
/*if (num >= 0x69) {
panic(PANIC_REBOOT);
}*/
}
#endif
if (args->X[0] && (!is_aes_kek || args->X[3] <= EXOSPHERE_TARGET_FIRMWARE_DEFAULT_FOR_DEBUG))
{
MAKE_REG32(get_iram_address_for_debug() + 0x4FF0) = handler_id;
MAKE_REG32(get_iram_address_for_debug() + 0x4FF4) = smc_id;

View file

@ -113,7 +113,7 @@ uint32_t user_generate_aes_kek(smc_args_t *args) {
master_key_rev -= 1; /* GenerateAesKek offsets by one. */
}
if (master_key_rev >= MASTERKEY_REVISION_MAX) {
if (master_key_rev >= MASTERKEY_REVISION_MAX || master_key_rev > mkey_get_revision()) {
return 2;
}
@ -628,8 +628,10 @@ uint32_t user_unwrap_rsa_oaep_wrapped_titlekey(smc_args_t *args) {
master_key_rev -= 1;
}
if (exosphere_get_target_firmware() >= EXOSPHERE_TARGET_FIRMWARE_300 && master_key_rev >= MASTERKEY_REVISION_MAX) {
return 2;
if (exosphere_get_target_firmware() >= EXOSPHERE_TARGET_FIRMWARE_300) {
if (master_key_rev >= MASTERKEY_REVISION_MAX) {
return 2;
}
} else {
master_key_rev = 0;
}
@ -690,8 +692,10 @@ uint32_t user_unwrap_aes_wrapped_titlekey(smc_args_t *args) {
if (master_key_rev > 0) {
master_key_rev -= 1;
}
if (exosphere_get_target_firmware() >= EXOSPHERE_TARGET_FIRMWARE_300 && master_key_rev >= MASTERKEY_REVISION_MAX) {
return 2;
if (exosphere_get_target_firmware() >= EXOSPHERE_TARGET_FIRMWARE_300) {
if (master_key_rev >= MASTERKEY_REVISION_MAX) {
return 2;
}
} else {
master_key_rev = 0;
}
@ -782,8 +786,8 @@ uint32_t user_decrypt_or_import_rsa_key(smc_args_t *args) {
size_t size;
upage_ref_t page_ref;
/* This function no longer exists in 5.x+. */
if (exosphere_get_target_firmware() >= EXOSPHERE_TARGET_FIRMWARE_500) {
/* This function only exists in 5.x+. */
if (exosphere_get_target_firmware() < EXOSPHERE_TARGET_FIRMWARE_500) {
generic_panic();
}

View file

@ -133,7 +133,7 @@ size_t tkey_rsa_oaep_unwrap(void *dst, size_t dst_size, void *src, size_t src_si
/* Extract the wrapped key. */
memcpy(dst, &db[wrapped_key_offset_in_db], wrapped_titlekey_size);
return wrapped_key_offset_in_db;
return wrapped_titlekey_size;
}
void tkey_aes_unwrap(void *dst, size_t dst_size, const void *src, size_t src_size) {

View file

@ -27,7 +27,7 @@ __attribute__ ((noreturn)) void panic(uint32_t code) {
/* For now, just use NX BOOTLOADER's panic. */
fuse_disable_programming();
APBDEV_PMC_CRYPTO_OP_0 = 1; /* Disable all SE operations. */
while (1) { }
// while (1) { }
watchdog_reboot();
}