mirror of
https://github.com/riscv-software-src/opensbi.git
synced 2025-08-24 23:41:23 +01:00

This patch adds support for hart hotplug in OpenSBI using a generic WFI based approach. Hart hotplug can be achieved via SBI HSM extension which allows supervisor mode software to start or stop any harts anytime. Any platform wishes to implement platform specific hart hotplug must implement both hart_start and hart_stop in addition to enable platform feature SBI_PLATFORM_HAS_HART_HOTPLUG. Signed-off-by: Atish Patra <atish.patra@wdc.com> Reviewed-by: Anup Patel <anup.patel@wdc.com>
71 lines
1.9 KiB
C
71 lines
1.9 KiB
C
/*
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
|
*
|
|
* Copyright (c) 2019 Western Digital Corporation or its affiliates.
|
|
*
|
|
* Authors:
|
|
* Anup Patel <anup.patel@wdc.com>
|
|
* Nick Kossifidis <mick@ics.forth.gr>
|
|
*/
|
|
|
|
#include <sbi/sbi_hart.h>
|
|
#include <sbi/sbi_hsm.h>
|
|
#include <sbi/sbi_platform.h>
|
|
#include <sbi/sbi_system.h>
|
|
#include <sbi/sbi_ipi.h>
|
|
#include <sbi/sbi_init.h>
|
|
|
|
int sbi_system_early_init(struct sbi_scratch *scratch, bool cold_boot)
|
|
{
|
|
return sbi_platform_early_init(sbi_platform_ptr(scratch), cold_boot);
|
|
}
|
|
|
|
int sbi_system_final_init(struct sbi_scratch *scratch, bool cold_boot)
|
|
{
|
|
return sbi_platform_final_init(sbi_platform_ptr(scratch), cold_boot);
|
|
}
|
|
|
|
void sbi_system_early_exit(struct sbi_scratch *scratch)
|
|
{
|
|
sbi_platform_early_exit(sbi_platform_ptr(scratch));
|
|
}
|
|
|
|
void sbi_system_final_exit(struct sbi_scratch *scratch)
|
|
{
|
|
sbi_platform_final_exit(sbi_platform_ptr(scratch));
|
|
}
|
|
|
|
void __noreturn sbi_system_reboot(struct sbi_scratch *scratch, u32 type)
|
|
{
|
|
u32 current_hartid_mask = 1UL << sbi_current_hartid();
|
|
|
|
/* Send HALT IPI to every hart other than the current hart */
|
|
sbi_ipi_send_halt(scratch,
|
|
sbi_hart_available_mask() & ~current_hartid_mask, 0);
|
|
|
|
sbi_hsm_hart_stop(scratch, FALSE);
|
|
|
|
/* Platform specific reooot */
|
|
sbi_platform_system_reboot(sbi_platform_ptr(scratch), type);
|
|
|
|
/* If platform specific reboot did not work then do sbi_exit() */
|
|
sbi_exit(scratch);
|
|
}
|
|
|
|
void __noreturn sbi_system_shutdown(struct sbi_scratch *scratch, u32 type)
|
|
{
|
|
u32 current_hartid_mask = 1UL << sbi_current_hartid();
|
|
|
|
/* Send HALT IPI to every hart other than the current hart */
|
|
sbi_ipi_send_halt(scratch,
|
|
sbi_hart_available_mask() & ~current_hartid_mask, 0);
|
|
|
|
sbi_hsm_hart_stop(scratch, FALSE);
|
|
|
|
/* Platform specific shutdown */
|
|
sbi_platform_system_shutdown(sbi_platform_ptr(scratch), type);
|
|
|
|
/* If platform specific shutdown did not work then do sbi_exit() */
|
|
sbi_exit(scratch);
|
|
}
|