summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAtish Patra <atish.patra@wdc.com>2020-02-12 04:32:39 +0300
committerAnup Patel <anup@brainfault.org>2020-02-24 15:43:23 +0300
commite3f69fc1e934ce7815d9cde2d13dd2038a2894a6 (patch)
tree12a3d9846f29bcda30c622efa2368d70d51752f3
parent5b4824082ff8826f77d6bc670e16068d0744ff7f (diff)
downloadopensbi-e3f69fc1e934ce7815d9cde2d13dd2038a2894a6.tar.xz
lib: Implement Hart State Management (HSM) SBI extension
This patch adds support HSM extension. The specification is available at https://github.com/riscv/riscv-sbi-doc. It allows to implement hart hotplug and fixed ordered hart booting in supervisor. Signed-off-by: Atish Patra <atish.patra@wdc.com> Reviewed-by: Anup Patel <anup.patel@wdc.com>
-rw-r--r--include/sbi/sbi_ecall.h1
-rw-r--r--include/sbi/sbi_ecall_interface.h6
-rw-r--r--lib/sbi/objects.mk1
-rw-r--r--lib/sbi/sbi_ecall.c3
-rw-r--r--lib/sbi/sbi_ecall_hsm.c51
5 files changed, 62 insertions, 0 deletions
diff --git a/include/sbi/sbi_ecall.h b/include/sbi/sbi_ecall.h
index 2a3500f..1b56496 100644
--- a/include/sbi/sbi_ecall.h
+++ b/include/sbi/sbi_ecall.h
@@ -39,6 +39,7 @@ extern struct sbi_ecall_extension ecall_time;
extern struct sbi_ecall_extension ecall_rfence;
extern struct sbi_ecall_extension ecall_ipi;
extern struct sbi_ecall_extension ecall_vendor;
+extern struct sbi_ecall_extension ecall_hsm;
u16 sbi_ecall_version_major(void);
diff --git a/include/sbi/sbi_ecall_interface.h b/include/sbi/sbi_ecall_interface.h
index ba88e8b..727a545 100644
--- a/include/sbi/sbi_ecall_interface.h
+++ b/include/sbi/sbi_ecall_interface.h
@@ -26,6 +26,7 @@
#define SBI_EXT_TIME 0x54494D45
#define SBI_EXT_IPI 0x735049
#define SBI_EXT_RFENCE 0x52464E43
+#define SBI_EXT_HSM 0x48534D
/* SBI function IDs for BASE extension*/
#define SBI_EXT_BASE_GET_SPEC_VERSION 0x0
@@ -51,6 +52,11 @@
#define SBI_EXT_RFENCE_REMOTE_HFENCE_VVMA 0x5
#define SBI_EXT_RFENCE_REMOTE_HFENCE_VVMA_ASID 0x6
+/* SBI function IDs for HSM extension */
+#define SBI_EXT_HSM_HART_START 0x0
+#define SBI_EXT_HSM_HART_STOP 0x1
+#define SBI_EXT_HSM_HART_GET_STATUS 0x2
+
#define SBI_HSM_HART_STATUS_STARTED 0x0
#define SBI_HSM_HART_STATUS_STOPPED 0x1
#define SBI_HSM_HART_STATUS_START_PENDING 0x2
diff --git a/lib/sbi/objects.mk b/lib/sbi/objects.mk
index dc52a9f..39e9295 100644
--- a/lib/sbi/objects.mk
+++ b/lib/sbi/objects.mk
@@ -18,6 +18,7 @@ libsbi-objs-y += sbi_ecall_base.o
libsbi-objs-y += sbi_ecall_legacy.o
libsbi-objs-y += sbi_ecall_replace.o
libsbi-objs-y += sbi_ecall_vendor.o
+libsbi-objs-y += sbi_ecall_hsm.o
libsbi-objs-y += sbi_emulate_csr.o
libsbi-objs-y += sbi_fifo.o
libsbi-objs-y += sbi_hfence.o
diff --git a/lib/sbi/sbi_ecall.c b/lib/sbi/sbi_ecall.c
index 82397c4..2383e4f 100644
--- a/lib/sbi/sbi_ecall.c
+++ b/lib/sbi/sbi_ecall.c
@@ -138,6 +138,9 @@ int sbi_ecall_init(void)
ret = sbi_ecall_register_extension(&ecall_base);
if (ret)
return ret;
+ ret = sbi_ecall_register_extension(&ecall_hsm);
+ if (ret)
+ return ret;
ret = sbi_ecall_register_extension(&ecall_legacy);
if (ret)
return ret;
diff --git a/lib/sbi/sbi_ecall_hsm.c b/lib/sbi/sbi_ecall_hsm.c
new file mode 100644
index 0000000..528bc80
--- /dev/null
+++ b/lib/sbi/sbi_ecall_hsm.c
@@ -0,0 +1,51 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2020 Western Digital Corporation or its affiliates.
+ *
+ * Authors:
+ * Atish Patra <atish.patra@wdc.com>
+ */
+
+#include <sbi/sbi_ecall.h>
+#include <sbi/sbi_ecall_interface.h>
+#include <sbi/sbi_error.h>
+#include <sbi/sbi_version.h>
+#include <sbi/sbi_hsm.h>
+#include <sbi/riscv_asm.h>
+
+static int sbi_ecall_hsm_handler(struct sbi_scratch *scratch,
+ unsigned long extid, unsigned long funcid,
+ unsigned long *args, unsigned long *out_val,
+ struct sbi_trap_info *out_trap)
+{
+ int ret = 0;
+ int hstate;
+
+ switch (funcid) {
+ case SBI_EXT_HSM_HART_START:
+ ret = sbi_hsm_hart_start(scratch, args[0], args[1], args[2]);
+ break;
+ case SBI_EXT_HSM_HART_STOP:
+ ret = sbi_hsm_hart_stop(scratch, TRUE);
+ break;
+ case SBI_EXT_HSM_HART_GET_STATUS:
+ hstate = sbi_hsm_hart_get_state(scratch, args[0]);
+ ret = sbi_hsm_hart_state_to_status(hstate);
+ break;
+ default:
+ ret = SBI_ENOTSUPP;
+ };
+ if (ret >= 0) {
+ *out_val = ret;
+ ret = 0;
+ }
+
+ return ret;
+}
+
+struct sbi_ecall_extension ecall_hsm = {
+ .extid_start = SBI_EXT_HSM,
+ .extid_end = SBI_EXT_HSM,
+ .handle = sbi_ecall_hsm_handler,
+};