exosphere: properly implement reboot-to-payload

This commit is contained in:
Michael Scire 2019-01-24 08:12:10 -08:00
parent c9c8f64f09
commit c6f06e2c40
8 changed files with 262 additions and 11 deletions

View file

@ -26,6 +26,14 @@
#include "utils.h"
#include "masterkey.h"
#include "exocfg.h"
#include "smc_ams.h"
#include "arm.h"
#define u8 uint8_t
#define u32 uint32_t
#include "rebootstub_bin.h"
#undef u8
#undef u32
static bool g_battery_profile = false;
static bool g_debugmode_override_user = false, g_debugmode_override_priv = false;
@ -48,11 +56,22 @@ uint32_t configitem_set(bool privileged, ConfigItem item, uint64_t value) {
case REBOOT_KIND_TO_WB_PAYLOAD:
/* Set reboot kind = warmboot. */
MAKE_REG32(MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_RTC_PMC) + 0x450ull) = 0x1;
/* Patch bootrom to jump to payload. */
MAKE_REG32(MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_RTC_PMC) + 0x630ull) = 0x0010171B; /* Return to bootrom IRAM initialization func. */
MAKE_REG32(MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_RTC_PMC) + 0x634ull) = 0x4000FFA4; /* Overwrite bootrom return address on stack. */
MAKE_REG32(MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_RTC_PMC) + 0x638ull) = 0x40010000; /* Return to start of payload. */
MAKE_REG32(MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_RTC_PMC) + 0x63Cull) = 0x4000FFB4; /* Overwrite bootrom return address on stack. */
/* Patch SDRAM init to perform an SVC immediately after second write */
MAKE_REG32(MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_RTC_PMC) + 0x634ull) = 0x2E38DFFF;
MAKE_REG32(MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_RTC_PMC) + 0x638ull) = 0x6001DC28;
/* Set SVC handler to jump to reboot stub in IRAM. */
MAKE_REG32(MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_RTC_PMC) + 0x520ull) = 0x4003F000;
MAKE_REG32(MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_RTC_PMC) + 0x53Cull) = 0x6000F208;
/* Copy reboot stub payload. */
ams_map_irampage(0x4003F000);
for (unsigned int i = 0; i < rebootstub_bin_size; i += 4) {
MAKE_REG32(MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_AMS_IRAM_PAGE) + i) = read32le(rebootstub_bin, i);
}
ams_unmap_irampage();
/* Ensure stub is flushed. */
flush_dcache_all();
break;
default:
return 2;

View file

@ -72,7 +72,7 @@ static void ams_unmap_userpage(void) {
lock_release(&g_ams_userpage_mapped);
}
static void ams_map_irampage(uintptr_t iram_address) {
void ams_map_irampage(uintptr_t iram_address) {
lock_acquire(&g_ams_iram_page_mapped);
static const uint64_t irampage_attributes = MMU_PTE_BLOCK_XN | MMU_PTE_BLOCK_INNER_SHAREBLE | ATTRIB_MEMTYPE_DEVICE;
uintptr_t *mmu_l3_tbl = (uintptr_t *)TZRAM_GET_SEGMENT_ADDRESS(TZRAM_SEGMENT_ID_L3_TRANSLATION_TABLE);
@ -80,7 +80,7 @@ static void ams_map_irampage(uintptr_t iram_address) {
tlb_invalidate_page_inner_shareable((void *)AMS_IRAM_PAGE_SECURE_MONITOR_ADDR);
}
static void ams_unmap_irampage(void) {
void ams_unmap_irampage(void) {
uintptr_t *mmu_l3_tbl = (uintptr_t *)TZRAM_GET_SEGMENT_ADDRESS(TZRAM_SEGMENT_ID_L3_TRANSLATION_TABLE);
mmu_unmap_page(mmu_l3_tbl, AMS_IRAM_PAGE_SECURE_MONITOR_ADDR);
tlb_invalidate_page_inner_shareable((void *)AMS_IRAM_PAGE_SECURE_MONITOR_ADDR);

View file

@ -21,4 +21,7 @@
uint32_t ams_iram_copy(smc_args_t *args);
void ams_map_irampage(uintptr_t iram_address);
void ams_unmap_irampage(void);
#endif