lib: sbi: Implement SBI HSM suspend function

This patch implements the SBI HSM suspend function. Using this
new SBI call, the S-mode software can put calling HART in platform
specific suspend (i.e. low-power) state. For a successful retentive
suspend, the SBI call will return without errors upon resuming
whereas for a successful non-retentive suspend, the SBI call will
resume from a user provided resume address.

Signed-off-by: Anup Patel <anup.patel@wdc.com>
Reviewed-by: Atish Patra <atish.patra@wdc.com>
This commit is contained in:
Anup Patel
2021-02-06 14:48:56 +05:30
committed by Anup Patel
parent 807d71c4ff
commit 74756891cc
4 changed files with 235 additions and 9 deletions

View File

@@ -311,14 +311,12 @@ static void __noreturn init_coldboot(struct sbi_scratch *scratch, u32 hartid)
scratch->next_mode, FALSE);
}
static void __noreturn init_warmboot(struct sbi_scratch *scratch, u32 hartid)
static void init_warm_startup(struct sbi_scratch *scratch, u32 hartid)
{
int rc;
unsigned long *init_count;
const struct sbi_platform *plat = sbi_platform_ptr(scratch);
wait_for_coldboot(scratch, hartid);
if (!init_count_offset)
sbi_hart_hang();
@@ -362,6 +360,40 @@ static void __noreturn init_warmboot(struct sbi_scratch *scratch, u32 hartid)
(*init_count)++;
sbi_hsm_prepare_next_jump(scratch, hartid);
}
static void init_warm_resume(struct sbi_scratch *scratch)
{
int rc;
sbi_hsm_hart_resume_start(scratch);
rc = sbi_hart_reinit(scratch);
if (rc)
sbi_hart_hang();
rc = sbi_hart_pmp_configure(scratch);
if (rc)
sbi_hart_hang();
sbi_hsm_hart_resume_finish(scratch);
}
static void __noreturn init_warmboot(struct sbi_scratch *scratch, u32 hartid)
{
int hstate;
wait_for_coldboot(scratch, hartid);
hstate = sbi_hsm_hart_get_state(sbi_domain_thishart_ptr(), hartid);
if (hstate < 0)
sbi_hart_hang();
if (hstate == SBI_HSM_STATE_SUSPENDED)
init_warm_resume(scratch);
else
init_warm_startup(scratch, hartid);
sbi_hart_switch_mode(hartid, scratch->next_arg1,
scratch->next_addr,
scratch->next_mode, FALSE);