hos: improve warmboot config

Add more checks, simplify it and allow it to be called on non-HOS code.
This commit is contained in:
CTCaer 2022-10-11 08:53:46 +03:00
parent e455fe043f
commit a6d0bf54cd
3 changed files with 19 additions and 21 deletions

View file

@ -904,7 +904,7 @@ int hos_launch(ini_sec_t *cfg)
} }
// Configure and manage Warmboot binary. // Configure and manage Warmboot binary.
if (!pkg1_warmboot_config(&ctxt, warmboot_base)) if (!pkg1_warmboot_config(&ctxt, warmboot_base, ctxt.pkg1_id->fuses, kb))
{ {
// Can only happen on T210B01. // Can only happen on T210B01.
_hos_crit_error("Failed to match warmboot with fuses!\nIf you continue, sleep wont work!"); _hos_crit_error("Failed to match warmboot with fuses!\nIf you continue, sleep wont work!");

View file

@ -341,32 +341,30 @@ static void _warmboot_filename(char *out, u32 fuses)
strcat(out, ".bin"); strcat(out, ".bin");
} }
int pkg1_warmboot_config(void *hos_ctxt, u32 warmboot_base) int pkg1_warmboot_config(void *hos_ctxt, u32 warmboot_base, u32 fuses_fw, u8 kb)
{ {
launch_ctxt_t *ctxt = (launch_ctxt_t *)hos_ctxt; launch_ctxt_t *ctxt = (launch_ctxt_t *)hos_ctxt;
u32 kb = ctxt->pkg1_id->kb;
int res = 1; int res = 1;
// Set warmboot address in PMC if required.
if (kb <= KB_FIRMWARE_VERSION_301)
PMC(APBDEV_PMC_SCRATCH1) = warmboot_base;
if (h_cfg.t210b01) if (h_cfg.t210b01)
{ {
u32 pa_id; u32 pa_id;
u32 fuses_max = 32; // Current ODM7 max. u32 fuses_max = 32; // Current ODM7 max.
u32 fuses_fw = ctxt->pkg1_id->fuses;
u8 burnt_fuses = bit_count(fuse_read_odm(7)); u8 burnt_fuses = bit_count(fuse_read_odm(7));
// Save current warmboot in storage cache (MWS) and check if another one is needed. // Save current warmboot in storage cache (MWS) and check if another one is needed.
if (!ctxt->warmboot) if (!ctxt->warmboot)
{ {
char path[128]; char path[128];
f_mkdir("warmboot_mariko");
strcpy(path, "warmboot_mariko/wb_"); strcpy(path, "warmboot_mariko/wb_");
_warmboot_filename(path, fuses_fw); _warmboot_filename(path, fuses_fw);
if (f_stat(path, NULL))
// Check if warmboot fw exists and save it.
if (ctxt->warmboot_size && f_stat(path, NULL))
{
f_mkdir("warmboot_mariko");
sd_save_to_file((void *)warmboot_base, ctxt->warmboot_size, path); sd_save_to_file((void *)warmboot_base, ctxt->warmboot_size, path);
}
// Load warmboot fw from storage (MWS) if not matched. // Load warmboot fw from storage (MWS) if not matched.
if (burnt_fuses > fuses_fw) if (burnt_fuses > fuses_fw)
@ -386,7 +384,7 @@ int pkg1_warmboot_config(void *hos_ctxt, u32 warmboot_base)
tmp_fuses++; tmp_fuses++;
} }
// Check if proper warmboot firmware was found. // Check if proper warmboot firmware was not found.
if (!ctxt->warmboot) if (!ctxt->warmboot)
res = 0; res = 0;
} }
@ -397,15 +395,11 @@ int pkg1_warmboot_config(void *hos_ctxt, u32 warmboot_base)
// Configure Warmboot parameters. Anything lower is not supported. // Configure Warmboot parameters. Anything lower is not supported.
switch (burnt_fuses) switch (burnt_fuses)
{ {
case 7: case 7 ... 8:
pa_id = 0x87; pa_id = 0x21 * (burnt_fuses - 3) + 3;
break; break;
case 8: // 0x21 raise. default: // From 7.0.0 and up PA id is 0x21 multiplied with fuses.
pa_id = 0xA8; pa_id = 0x21 * burnt_fuses;
break;
default: // From 7.0.0 and up PA id raises by 0x21 with a static base.
pa_id = 0x108;
pa_id += 0x21 * (burnt_fuses - 8);
break; break;
} }
@ -415,6 +409,10 @@ int pkg1_warmboot_config(void *hos_ctxt, u32 warmboot_base)
} }
else else
{ {
// Set warmboot address in PMC if required.
if (kb <= KB_FIRMWARE_VERSION_301)
PMC(APBDEV_PMC_SCRATCH1) = warmboot_base;
// Set Warmboot Physical Address ID for 3.0.0 - 3.0.2. // Set Warmboot Physical Address ID for 3.0.0 - 3.0.2.
if (kb == KB_FIRMWARE_VERSION_300) if (kb == KB_FIRMWARE_VERSION_300)
PMC(APBDEV_PMC_SECURE_SCRATCH32) = 0xE3; // Warmboot 3.0.0 PA address id. PMC(APBDEV_PMC_SECURE_SCRATCH32) = 0xE3; // Warmboot 3.0.0 PA address id.

View file

@ -99,7 +99,7 @@ int pkg1_decrypt(const pkg1_id_t *id, u8 *pkg1);
const u8 *pkg1_unpack(void *wm_dst, u32 *wb_sz, void *sm_dst, void *ldr_dst, const pkg1_id_t *id, u8 *pkg1); const u8 *pkg1_unpack(void *wm_dst, u32 *wb_sz, void *sm_dst, void *ldr_dst, const pkg1_id_t *id, u8 *pkg1);
void pkg1_secmon_patch(void *hos_ctxt, u32 secmon_base, bool t210b01); void pkg1_secmon_patch(void *hos_ctxt, u32 secmon_base, bool t210b01);
void pkg1_warmboot_patch(void *hos_ctxt); void pkg1_warmboot_patch(void *hos_ctxt);
int pkg1_warmboot_config(void *hos_ctxt, u32 warmboot_base); int pkg1_warmboot_config(void *hos_ctxt, u32 warmboot_base, u32 fuses_fw, u8 kb);
void pkg1_warmboot_rsa_mod(u32 warmboot_base); void pkg1_warmboot_rsa_mod(u32 warmboot_base);
#endif #endif