aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/sbi/sbi_platform.h35
-rw-r--r--include/sbi/sbi_system.h4
-rw-r--r--include/sbi_utils/reset/fdt_reset.h7
-rw-r--r--include/sbi_utils/sys/htif.h4
-rw-r--r--include/sbi_utils/sys/sifive_test.h4
-rw-r--r--lib/sbi/sbi_ecall_legacy.c3
-rw-r--r--lib/sbi/sbi_system.c13
-rw-r--r--lib/utils/reset/fdt_reset.c13
-rw-r--r--lib/utils/reset/fdt_reset_htif.c1
-rw-r--r--lib/utils/reset/fdt_reset_sifive.c1
-rw-r--r--lib/utils/sys/htif.c7
-rw-r--r--lib/utils/sys/sifive_test.c23
-rw-r--r--platform/generic/include/platform_override.h5
-rw-r--r--platform/generic/platform.c23
-rw-r--r--platform/nuclei/ux600/platform.c9
-rw-r--r--platform/template/platform.c12
-rw-r--r--platform/thead/c910/platform.c9
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,