[PATCH v2 09/11] lib: sbi: Implement system suspend
Anup Patel
anup at brainfault.org
Mon Feb 27 06:24:46 PST 2023
On Mon, Feb 27, 2023 at 4:01 PM Andrew Jones <ajones at ventanamicro.com> wrote:
>
> Fill the implementation of the system suspend ecall. A platform
> implementation of the suspend callbacks is still required for this
> to do anything.
>
> Signed-off-by: Andrew Jones <ajones at ventanamicro.com>
> Reviewed-by: Anup Patel <anup at brainfault.org>
Applied this patch to the riscv/opensbi repo.
Thanks,
Anup
> ---
> lib/sbi/sbi_system.c | 57 +++++++++++++++++++++++++++++++++++++++++++-
> 1 file changed, 56 insertions(+), 1 deletion(-)
>
> diff --git a/lib/sbi/sbi_system.c b/lib/sbi/sbi_system.c
> index 5c123a6c9d8d..7fa5ea82b7a6 100644
> --- a/lib/sbi/sbi_system.c
> +++ b/lib/sbi/sbi_system.c
> @@ -116,5 +116,60 @@ bool sbi_system_suspend_supported(u32 sleep_type)
>
> int sbi_system_suspend(u32 sleep_type, ulong resume_addr, ulong opaque)
> {
> - return 0;
> + int ret = SBI_ENOTSUPP;
> + const struct sbi_domain *dom = sbi_domain_thishart_ptr();
> + struct sbi_scratch *scratch = sbi_scratch_thishart_ptr();
> + void (*jump_warmboot)(void) = (void (*)(void))scratch->warmboot_addr;
> + unsigned int hartid = current_hartid();
> + unsigned long prev_mode;
> + unsigned long i;
> +
> + if (!dom || !dom->system_suspend_allowed)
> + return SBI_EFAIL;
> +
> + if (!suspend_dev || !suspend_dev->system_suspend)
> + return SBI_EFAIL;
> +
> + if (!sbi_system_suspend_supported(sleep_type))
> + return SBI_ENOTSUPP;
> +
> + prev_mode = (csr_read(CSR_MSTATUS) & MSTATUS_MPP) >> MSTATUS_MPP_SHIFT;
> + if (prev_mode != PRV_S && prev_mode != PRV_U)
> + return SBI_EFAIL;
> +
> + sbi_hartmask_for_each_hart(i, &dom->assigned_harts) {
> + if (i == hartid)
> + continue;
> + if (__sbi_hsm_hart_get_state(i) != SBI_HSM_STATE_STOPPED)
> + return SBI_EFAIL;
> + }
> +
> + if (!sbi_domain_check_addr(dom, resume_addr, prev_mode,
> + SBI_DOMAIN_EXECUTE))
> + return SBI_EINVALID_ADDR;
> +
> + if (!sbi_hsm_hart_change_state(scratch, SBI_HSM_STATE_STARTED,
> + SBI_HSM_STATE_SUSPENDED))
> + return SBI_EFAIL;
> +
> + /* Prepare for resume */
> + scratch->next_mode = prev_mode;
> + scratch->next_addr = resume_addr;
> + scratch->next_arg1 = opaque;
> +
> + __sbi_hsm_suspend_non_ret_save(scratch);
> +
> + /* Suspend */
> + ret = suspend_dev->system_suspend(sleep_type, scratch->warmboot_addr);
> + if (ret != SBI_OK) {
> + if (!sbi_hsm_hart_change_state(scratch, SBI_HSM_STATE_SUSPENDED,
> + SBI_HSM_STATE_STARTED))
> + sbi_hart_hang();
> + return ret;
> + }
> +
> + /* Resume */
> + jump_warmboot();
> +
> + __builtin_unreachable();
> }
> --
> 2.39.1
>
More information about the opensbi
mailing list