*/
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);
}
/**
- * 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
#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
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);
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
#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);
}
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;
#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();
/* 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);
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;
struct fdt_reset fdt_reset_htif = {
.match_table = htif_reset_match,
+ .system_reset_check = htif_system_reset_check,
.system_reset = htif_system_reset
};
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
};
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;
*/
#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
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
*/
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)
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);
};
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 = {
.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,
};
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 = {
.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
};
}
/*
- * 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 = {
.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 = {
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)
.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,