summaryrefslogtreecommitdiff
path: root/include/sbi
diff options
context:
space:
mode:
authorAtish Patra <atish.patra@wdc.com>2020-02-12 04:32:37 +0300
committerAnup Patel <anup@brainfault.org>2020-02-24 15:37:55 +0300
commitb677a9b8d641f1c16a4f8f52e00019a9bc747893 (patch)
tree5fa5b11867958b81cbeec0678819b60512fb9386 /include/sbi
parentf64f4b92e411709227ee830bc1e9f8f87c72423e (diff)
downloadopensbi-b677a9b8d641f1c16a4f8f52e00019a9bc747893.tar.xz
lib: Implement hart hotplug
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>
Diffstat (limited to 'include/sbi')
-rw-r--r--include/sbi/sbi_error.h1
-rw-r--r--include/sbi/sbi_hart.h2
-rw-r--r--include/sbi/sbi_hsm.h30
-rw-r--r--include/sbi/sbi_platform.h43
4 files changed, 76 insertions, 0 deletions
diff --git a/include/sbi/sbi_error.h b/include/sbi/sbi_error.h
index 4b7dd12..91ba2ee 100644
--- a/include/sbi/sbi_error.h
+++ b/include/sbi/sbi_error.h
@@ -28,6 +28,7 @@
#define SBI_ETRAP -13
#define SBI_EUNKNOWN -14
#define SBI_ENOENT -15
+#define SBI_EALREADY_STARTED -16
/* clang-format on */
diff --git a/include/sbi/sbi_hart.h b/include/sbi/sbi_hart.h
index 065cb0c..d88c7de 100644
--- a/include/sbi/sbi_hart.h
+++ b/include/sbi/sbi_hart.h
@@ -22,6 +22,8 @@ void sbi_hart_set_trap_info(struct sbi_scratch *scratch, void *data);
void sbi_hart_delegation_dump(struct sbi_scratch *scratch);
void sbi_hart_pmp_dump(struct sbi_scratch *scratch);
+int sbi_hart_pmp_check_addr(struct sbi_scratch *scratch, unsigned long daddr,
+ unsigned long attr);
void __attribute__((noreturn)) sbi_hart_hang(void);
diff --git a/include/sbi/sbi_hsm.h b/include/sbi/sbi_hsm.h
new file mode 100644
index 0000000..2566afb
--- /dev/null
+++ b/include/sbi/sbi_hsm.h
@@ -0,0 +1,30 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2020 Western Digital Corporation or its affiliates.
+ *
+ * Authors:
+ * Atish Patra <atish.patra@wdc.com>
+ */
+
+#ifndef __SBI_HSM_H__
+#define __SBI_HSM_H__
+
+#include <sbi/sbi_types.h>
+
+/** Hart state values **/
+#define SBI_HART_STOPPED 0
+#define SBI_HART_STOPPING 1
+#define SBI_HART_STARTING 2
+#define SBI_HART_STARTED 3
+
+int sbi_hsm_init(struct sbi_scratch *scratch, u32 hartid, bool cold_boot);
+void __noreturn sbi_hsm_exit(struct sbi_scratch *scratch);
+
+int sbi_hsm_hart_start(struct sbi_scratch *scratch, u32 hartid,
+ ulong saddr, ulong priv);
+int sbi_hsm_hart_stop(struct sbi_scratch *scratch, bool exitnow);
+int sbi_hsm_hart_get_state(struct sbi_scratch *scratch, u32 hartid);
+bool sbi_hsm_hart_started(struct sbi_scratch *scratch, u32 hartid);
+void sbi_hsm_prepare_next_jump(struct sbi_scratch *scratch, u32 hartid);
+#endif
diff --git a/include/sbi/sbi_platform.h b/include/sbi/sbi_platform.h
index 16ee05c..462006e 100644
--- a/include/sbi/sbi_platform.h
+++ b/include/sbi/sbi_platform.h
@@ -135,6 +135,14 @@ struct sbi_platform_operations {
/** Exit platform timer for current HART */
void (*timer_exit)(void);
+ /** Bringup the given hart from previous stage **/
+ int (*hart_start)(u32 hartid, ulong saddr, ulong priv);
+ /**
+ * Stop the current hart from running. This call doesn't expect to
+ * return if success.
+ */
+ int (*hart_stop)(void);
+
/** Reboot the platform */
int (*system_reboot)(u32 type);
/** Shutdown or poweroff the platform */
@@ -285,6 +293,41 @@ static inline u32 sbi_platform_hart_stack_size(const struct sbi_platform *plat)
}
/**
+ * Bringup a given hart from previous stage. Platform should implement this
+ * operation if they support a custom mechanism to start a hart. Otherwise,
+ * a generic WFI based approach will be used to start/stop a hart in OpenSBI.
+ *
+ * @param plat pointer to struct sbi_platform
+ * @param hartid Hart ID
+ * @param saddr Physical address in supervisor mode for hart to jump after
+ * OpenSBI
+ * @param priv A private context data from the caller
+ *
+ * @return 0 if sucessful and negative error code on failure
+ */
+static inline int sbi_platform_hart_start(const struct sbi_platform *plat,
+ u32 hartid, ulong saddr, ulong priv)
+{
+ if (plat && sbi_platform_ops(plat)->hart_start)
+ return sbi_platform_ops(plat)->hart_start(hartid, saddr, priv);
+ return SBI_ENOTSUPP;
+}
+
+/**
+ * Stop the current hart in OpenSBI.
+ *
+ * @param plat pointer to struct sbi_platform
+ *
+ * @return Negative error code on failure. It doesn't return on success.
+ */
+static inline int sbi_platform_hart_stop(const struct sbi_platform *plat)
+{
+ if (plat && sbi_platform_ops(plat)->hart_stop)
+ return sbi_platform_ops(plat)->hart_stop();
+ return SBI_ENOTSUPP;
+}
+
+/**
* Early initialization for current HART
*
* @param plat pointer to struct sbi_platform