diff options
author | Angelos Mouzakitis <a.mouzakitis@virtualopensystems.com> | 2023-10-10 14:33:42 +0000 |
---|---|---|
committer | Angelos Mouzakitis <a.mouzakitis@virtualopensystems.com> | 2023-10-10 14:33:42 +0000 |
commit | af1a266670d040d2f4083ff309d732d648afba2a (patch) | |
tree | 2fc46203448ddcc6f81546d379abfaeb323575e9 /roms/opensbi/lib/sbi/sbi_system.c | |
parent | e02cda008591317b1625707ff8e115a4841aa889 (diff) |
Change-Id: Iaf8d18082d3991dec7c0ebbea540f092188eb4ec
Diffstat (limited to 'roms/opensbi/lib/sbi/sbi_system.c')
-rw-r--r-- | roms/opensbi/lib/sbi/sbi_system.c | 56 |
1 files changed, 56 insertions, 0 deletions
diff --git a/roms/opensbi/lib/sbi/sbi_system.c b/roms/opensbi/lib/sbi/sbi_system.c new file mode 100644 index 000000000..08a8b47c7 --- /dev/null +++ b/roms/opensbi/lib/sbi/sbi_system.c @@ -0,0 +1,56 @@ +/* + * 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/riscv_asm.h> +#include <sbi/sbi_bitops.h> +#include <sbi/sbi_domain.h> +#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> + +bool sbi_system_reset_supported(u32 reset_type, u32 reset_reason) +{ + if (sbi_platform_system_reset_check(sbi_platform_thishart_ptr(), + reset_type, reset_reason)) + return TRUE; + + return FALSE; +} + +void __noreturn sbi_system_reset(u32 reset_type, u32 reset_reason) +{ + ulong hbase = 0, hmask; + u32 cur_hartid = current_hartid(); + struct sbi_domain *dom = sbi_domain_thishart_ptr(); + struct sbi_scratch *scratch = sbi_scratch_thishart_ptr(); + + /* Send HALT IPI to every hart other than the current hart */ + while (!sbi_hsm_hart_started_mask(dom, hbase, &hmask)) { + if (hbase <= cur_hartid) + hmask &= ~(1UL << (cur_hartid - hbase)); + if (hmask) + sbi_ipi_send_halt(hmask, hbase); + hbase += BITS_PER_LONG; + } + + /* Stop current HART */ + sbi_hsm_hart_stop(scratch, FALSE); + + /* Platform specific reset if domain allowed system reset */ + if (dom->system_reset_allowed) + sbi_platform_system_reset(sbi_platform_ptr(scratch), + reset_type, reset_reason); + + /* If platform specific reset did not work then do sbi_exit() */ + sbi_exit(scratch); +} |