diff options
-rw-r--r-- | include/sbi/sbi_platform.h | 35 | ||||
-rw-r--r-- | include/sbi/sbi_system.h | 4 | ||||
-rw-r--r-- | include/sbi_utils/reset/fdt_reset.h | 7 | ||||
-rw-r--r-- | include/sbi_utils/sys/htif.h | 4 | ||||
-rw-r--r-- | include/sbi_utils/sys/sifive_test.h | 4 | ||||
-rw-r--r-- | lib/sbi/sbi_ecall_legacy.c | 3 | ||||
-rw-r--r-- | lib/sbi/sbi_system.c | 13 | ||||
-rw-r--r-- | lib/utils/reset/fdt_reset.c | 13 | ||||
-rw-r--r-- | lib/utils/reset/fdt_reset_htif.c | 1 | ||||
-rw-r--r-- | lib/utils/reset/fdt_reset_sifive.c | 1 | ||||
-rw-r--r-- | lib/utils/sys/htif.c | 7 | ||||
-rw-r--r-- | lib/utils/sys/sifive_test.c | 23 | ||||
-rw-r--r-- | platform/generic/include/platform_override.h | 5 | ||||
-rw-r--r-- | platform/generic/platform.c | 23 | ||||
-rw-r--r-- | platform/nuclei/ux600/platform.c | 9 | ||||
-rw-r--r-- | platform/template/platform.c | 12 | ||||
-rw-r--r-- | platform/thead/c910/platform.c | 9 |
17 files changed, 137 insertions, 36 deletions
diff --git a/include/sbi/sbi_platform.h b/include/sbi/sbi_platform.h index b06aaa6..ee72323 100644 --- a/include/sbi/sbi_platform.h +++ b/include/sbi/sbi_platform.h @@ -137,8 +137,10 @@ struct sbi_platform_operations { */ int (*hart_stop)(void); + /* Check whether reset type and reason supported by the platform */ + int (*system_reset_check)(u32 reset_type, u32 reset_reason); /** Reset the platform */ - int (*system_reset)(u32 reset_type); + void (*system_reset)(u32 reset_type, u32 reset_reason); /** platform specific SBI extension implementation probe function */ int (*vendor_ext_check)(long extid); @@ -653,22 +655,41 @@ static inline void sbi_platform_timer_exit(const struct sbi_platform *plat) } /** - * Reset the platform + * Check whether reset type and reason supported by the platform * * @param plat pointer to struct sbi_platform * @param reset_type type of reset + * @param reset_reason reason for reset * - * @return 0 on success and negative error code on failure + * @return 0 if reset type and reason not supported and 1 if supported */ -static inline int sbi_platform_system_reset(const struct sbi_platform *plat, - u32 reset_type) +static inline int sbi_platform_system_reset_check( + const struct sbi_platform *plat, + u32 reset_type, u32 reset_reason) { - if (plat && sbi_platform_ops(plat)->system_reset) - return sbi_platform_ops(plat)->system_reset(reset_type); + if (plat && sbi_platform_ops(plat)->system_reset_check) + return sbi_platform_ops(plat)->system_reset_check(reset_type, + reset_reason); return 0; } /** + * Reset the platform + * + * This function will not return for supported reset type and reset reason + * + * @param plat pointer to struct sbi_platform + * @param reset_type type of reset + * @param reset_reason reason for reset + */ +static inline void sbi_platform_system_reset(const struct sbi_platform *plat, + u32 reset_type, u32 reset_reason) +{ + if (plat && sbi_platform_ops(plat)->system_reset) + sbi_platform_ops(plat)->system_reset(reset_type, reset_reason); +} + +/** * Check if a vendor extension is implemented or not. * * @param plat pointer to struct sbi_platform diff --git a/include/sbi/sbi_system.h b/include/sbi/sbi_system.h index 309e263..34ba766 100644 --- a/include/sbi/sbi_system.h +++ b/include/sbi/sbi_system.h @@ -12,6 +12,8 @@ #include <sbi/sbi_types.h> -void __noreturn sbi_system_reset(u32 reset_type); +bool sbi_system_reset_supported(u32 reset_type, u32 reset_reason); + +void __noreturn sbi_system_reset(u32 reset_type, u32 reset_reason); #endif diff --git a/include/sbi_utils/reset/fdt_reset.h b/include/sbi_utils/reset/fdt_reset.h index 789a6ac..cce441a 100644 --- a/include/sbi_utils/reset/fdt_reset.h +++ b/include/sbi_utils/reset/fdt_reset.h @@ -15,10 +15,13 @@ struct fdt_reset { const struct fdt_match *match_table; int (*init)(void *fdt, int nodeoff, const struct fdt_match *match); - int (*system_reset)(u32 reset_type); + int (*system_reset_check)(u32 reset_type, u32 reset_reason); + void (*system_reset)(u32 reset_type, u32 reset_reason); }; -int fdt_system_reset(u32 reset_type); +int fdt_system_reset_check(u32 reset_type, u32 reset_reason); + +void fdt_system_reset(u32 reset_type, u32 reset_reason); int fdt_reset_init(void); diff --git a/include/sbi_utils/sys/htif.h b/include/sbi_utils/sys/htif.h index 7384b48..a431723 100644 --- a/include/sbi_utils/sys/htif.h +++ b/include/sbi_utils/sys/htif.h @@ -14,6 +14,8 @@ void htif_putc(char ch); int htif_getc(void); -int htif_system_reset(u32 type); +int htif_system_reset_check(u32 type, u32 reason); + +void htif_system_reset(u32 type, u32 reason); #endif diff --git a/include/sbi_utils/sys/sifive_test.h b/include/sbi_utils/sys/sifive_test.h index 7e153d5..958622e 100644 --- a/include/sbi_utils/sys/sifive_test.h +++ b/include/sbi_utils/sys/sifive_test.h @@ -12,7 +12,9 @@ #include <sbi/sbi_types.h> -int sifive_test_system_reset(u32 type); +int sifive_test_system_reset_check(u32 type, u32 reason); + +void sifive_test_system_reset(u32 type, u32 reason); int sifive_test_init(unsigned long base); diff --git a/lib/sbi/sbi_ecall_legacy.c b/lib/sbi/sbi_ecall_legacy.c index 683b8dc..7844fbb 100644 --- a/lib/sbi/sbi_ecall_legacy.c +++ b/lib/sbi/sbi_ecall_legacy.c @@ -103,7 +103,8 @@ static int sbi_ecall_legacy_handler(unsigned long extid, unsigned long funcid, } break; case SBI_EXT_0_1_SHUTDOWN: - sbi_system_reset(SBI_SRST_RESET_TYPE_SHUTDOWN); + sbi_system_reset(SBI_SRST_RESET_TYPE_SHUTDOWN, + SBI_SRST_RESET_REASON_NONE); break; default: ret = SBI_ENOTSUPP; diff --git a/lib/sbi/sbi_system.c b/lib/sbi/sbi_system.c index 2f1b7fb..08a8b47 100644 --- a/lib/sbi/sbi_system.c +++ b/lib/sbi/sbi_system.c @@ -18,7 +18,16 @@ #include <sbi/sbi_ipi.h> #include <sbi/sbi_init.h> -void __noreturn sbi_system_reset(u32 reset_type) +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(); @@ -40,7 +49,7 @@ void __noreturn sbi_system_reset(u32 reset_type) /* Platform specific reset if domain allowed system reset */ if (dom->system_reset_allowed) sbi_platform_system_reset(sbi_platform_ptr(scratch), - reset_type); + reset_type, reset_reason); /* If platform specific reset did not work then do sbi_exit() */ sbi_exit(scratch); diff --git a/lib/utils/reset/fdt_reset.c b/lib/utils/reset/fdt_reset.c index dfbd33e..dead8a3 100644 --- a/lib/utils/reset/fdt_reset.c +++ b/lib/utils/reset/fdt_reset.c @@ -21,13 +21,20 @@ static struct fdt_reset *reset_drivers[] = { static struct fdt_reset *current_driver = NULL; -int fdt_system_reset(u32 reset_type) +int fdt_system_reset_check(u32 reset_type, u32 reset_reason) { - if (current_driver && current_driver->system_reset) - return current_driver->system_reset(reset_type); + if (current_driver && current_driver->system_reset_check) + return current_driver->system_reset_check(reset_type, + reset_reason); return 0; } +void fdt_system_reset(u32 reset_type, u32 reset_reason) +{ + if (current_driver && current_driver->system_reset) + current_driver->system_reset(reset_type, reset_reason); +} + int fdt_reset_init(void) { int pos, noff, rc; diff --git a/lib/utils/reset/fdt_reset_htif.c b/lib/utils/reset/fdt_reset_htif.c index e453d05..587e7d6 100644 --- a/lib/utils/reset/fdt_reset_htif.c +++ b/lib/utils/reset/fdt_reset_htif.c @@ -18,5 +18,6 @@ static const struct fdt_match htif_reset_match[] = { struct fdt_reset fdt_reset_htif = { .match_table = htif_reset_match, + .system_reset_check = htif_system_reset_check, .system_reset = htif_system_reset }; diff --git a/lib/utils/reset/fdt_reset_sifive.c b/lib/utils/reset/fdt_reset_sifive.c index 6a171ca..38b520c 100644 --- a/lib/utils/reset/fdt_reset_sifive.c +++ b/lib/utils/reset/fdt_reset_sifive.c @@ -33,5 +33,6 @@ static const struct fdt_match sifive_test_reset_match[] = { struct fdt_reset fdt_reset_sifive = { .match_table = sifive_test_reset_match, .init = sifive_test_reset_init, + .system_reset_check = sifive_test_system_reset_check, .system_reset = sifive_test_system_reset }; diff --git a/lib/utils/sys/htif.c b/lib/utils/sys/htif.c index ed800a5..fd70fb9 100644 --- a/lib/utils/sys/htif.c +++ b/lib/utils/sys/htif.c @@ -140,7 +140,12 @@ int htif_getc(void) return ch - 1; } -int htif_system_reset(u32 type) +int htif_system_reset_check(u32 type, u32 reason) +{ + return 1; +} + +void htif_system_reset(u32 type, u32 reason) { while (1) { fromhost = 0; diff --git a/lib/utils/sys/sifive_test.c b/lib/utils/sys/sifive_test.c index 06fbfb2..fdf3169 100644 --- a/lib/utils/sys/sifive_test.c +++ b/lib/utils/sys/sifive_test.c @@ -8,7 +8,7 @@ */ #include <sbi/riscv_io.h> -#include <sbi/sbi_platform.h> +#include <sbi/sbi_ecall_interface.h> #include <sbi_utils/sys/sifive_test.h> #define FINISHER_FAIL 0x3333 @@ -17,7 +17,19 @@ static void *sifive_test_base; -int sifive_test_system_reset(u32 type) +int sifive_test_system_reset_check(u32 type, u32 reason) +{ + switch (type) { + case SBI_SRST_RESET_TYPE_SHUTDOWN: + case SBI_SRST_RESET_TYPE_COLD_REBOOT: + case SBI_SRST_RESET_TYPE_WARM_REBOOT: + return 1; + } + + return 0; +} + +void sifive_test_system_reset(u32 type, u32 reason) { /* * Tell the "finisher" that the simulation @@ -25,15 +37,16 @@ int sifive_test_system_reset(u32 type) */ switch (type) { case SBI_SRST_RESET_TYPE_SHUTDOWN: - writew(FINISHER_PASS, sifive_test_base); + if (reason == SBI_SRST_RESET_REASON_NONE) + writew(FINISHER_PASS, sifive_test_base); + else + writew(FINISHER_FAIL, sifive_test_base); break; case SBI_SRST_RESET_TYPE_COLD_REBOOT: case SBI_SRST_RESET_TYPE_WARM_REBOOT: writew(FINISHER_RESET, sifive_test_base); break; } - - return 0; } int sifive_test_init(unsigned long base) diff --git a/platform/generic/include/platform_override.h b/platform/generic/include/platform_override.h index 8a53cdf..77a90d6 100644 --- a/platform/generic/include/platform_override.h +++ b/platform/generic/include/platform_override.h @@ -20,7 +20,10 @@ struct platform_override { int (*final_init)(bool cold_boot, const struct fdt_match *match); void (*early_exit)(const struct fdt_match *match); void (*final_exit)(const struct fdt_match *match); - int (*system_reset)(u32 reset_type, const struct fdt_match *match); + int (*system_reset_check)(u32 reset_type, u32 reset_reason, + const struct fdt_match *match); + void (*system_reset)(u32 reset_type, u32 reset_reason, + const struct fdt_match *match); int (*fdt_fixup)(void *fdt, const struct fdt_match *match); }; diff --git a/platform/generic/platform.c b/platform/generic/platform.c index d902e71..abb696a 100644 --- a/platform/generic/platform.c +++ b/platform/generic/platform.c @@ -177,12 +177,24 @@ static u64 generic_tlbr_flush_limit(void) return SBI_PLATFORM_TLB_RANGE_FLUSH_LIMIT_DEFAULT; } -static int generic_system_reset(u32 reset_type) +static int generic_system_reset_check(u32 reset_type, u32 reset_reason) { - if (generic_plat && generic_plat->system_reset) - return generic_plat->system_reset(reset_type, - generic_plat_match); - return fdt_system_reset(reset_type); + if (generic_plat && generic_plat->system_reset_check) + return generic_plat->system_reset_check(reset_type, + reset_reason, + generic_plat_match); + return fdt_system_reset_check(reset_type, reset_reason); +} + +static void generic_system_reset(u32 reset_type, u32 reset_reason) +{ + if (generic_plat && generic_plat->system_reset) { + generic_plat->system_reset(reset_type, reset_reason, + generic_plat_match); + return; + } + + fdt_system_reset(reset_type, reset_reason); } const struct sbi_platform_operations platform_ops = { @@ -205,6 +217,7 @@ const struct sbi_platform_operations platform_ops = { .timer_event_start = fdt_timer_event_start, .timer_init = fdt_timer_init, .timer_exit = fdt_timer_exit, + .system_reset_check = generic_system_reset_check, .system_reset = generic_system_reset, }; diff --git a/platform/nuclei/ux600/platform.c b/platform/nuclei/ux600/platform.c index ba6803e..d0a45a2 100644 --- a/platform/nuclei/ux600/platform.c +++ b/platform/nuclei/ux600/platform.c @@ -186,13 +186,17 @@ static int ux600_timer_init(bool cold_boot) return clint_warm_timer_init(); } -static int ux600_system_reset(u32 type) +static int ux600_system_reset_check(u32 type, u32 reason) +{ + return 1; +} + +static void ux600_system_reset(u32 type, u32 reason) { /* Reset system using MSFTRST register in Nuclei Timer. */ writel(UX600_NUCLEI_TIMER_MSFTRST_KEY, (void *)(UX600_NUCLEI_TIMER_ADDR + UX600_NUCLEI_TIMER_MSFTRST_OFS)); while(1); - return 0; } const struct sbi_platform_operations platform_ops = { @@ -209,6 +213,7 @@ const struct sbi_platform_operations platform_ops = { .timer_event_stop = clint_timer_event_stop, .timer_event_start = clint_timer_event_start, .timer_init = ux600_timer_init, + .system_reset_check = ux600_system_reset_check, .system_reset = ux600_system_reset }; diff --git a/platform/template/platform.c b/platform/template/platform.c index 9cd750e..758e95f 100644 --- a/platform/template/platform.c +++ b/platform/template/platform.c @@ -178,14 +178,21 @@ static void platform_timer_event_stop(void) } /* - * Reset the platform. + * Check reset type and reason supported by the platform. */ -static int platform_system_reset(u32 type) +static int platform_system_reset_check(u32 type, u32 reason) { return 0; } /* + * Reset the platform. + */ +static void platform_system_reset(u32 type, u32 reason) +{ +} + +/* * Platform descriptor. */ const struct sbi_platform_operations platform_ops = { @@ -202,6 +209,7 @@ const struct sbi_platform_operations platform_ops = { .timer_event_stop = platform_timer_event_stop, .timer_event_start = platform_timer_event_start, .timer_init = platform_timer_init, + .system_reset_check = platform_system_reset_check, .system_reset = platform_system_reset }; const struct sbi_platform platform = { diff --git a/platform/thead/c910/platform.c b/platform/thead/c910/platform.c index df7658a..dfa484a 100644 --- a/platform/thead/c910/platform.c +++ b/platform/thead/c910/platform.c @@ -108,10 +108,14 @@ static int c910_timer_init(bool cold_boot) return clint_warm_timer_init(); } -static int c910_system_reset(u32 type) +static int c910_system_reset_check(u32 type, u32 reason) +{ + return 1; +} + +static void c910_system_reset(u32 type, u32 reason) { asm volatile ("ebreak"); - return 0; } int c910_hart_start(u32 hartid, ulong saddr) @@ -135,6 +139,7 @@ const struct sbi_platform_operations platform_ops = { .timer_init = c910_timer_init, .timer_event_start = clint_timer_event_start, + .system_reset_check = c910_system_reset_check, .system_reset = c910_system_reset, .hart_start = c910_hart_start, |