aboutsummaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorClément Léger <cleger@rivosinc.com>2024-03-21 16:57:16 +0100
committerAnup Patel <anup@brainfault.org>2024-04-05 15:47:30 +0530
commitc8cdf01d8f3a87a581c5b03d157dbf12913e9fb5 (patch)
treeb3a8b43fc7ab8cf7c4e2902743c34454a80ffe56 /include
parent76d7e9b8ee72c226cd8424d5483827bcf4c792fa (diff)
downloadopensbi-c8cdf01d8f3a87a581c5b03d157dbf12913e9fb5.zip
opensbi-c8cdf01d8f3a87a581c5b03d157dbf12913e9fb5.tar.gz
opensbi-c8cdf01d8f3a87a581c5b03d157dbf12913e9fb5.tar.bz2
lib: sbi: Add support for Supervisor Software Events extension
This extension [1] allows to deliver events from SBI to supervisor via a software mechanism. This extension defines events (either local or global) which are signaled by the SBI on specific signal sources (IRQ, exceptions, etc) and are injected to be executed in supervisor mode. [1] https://lists.riscv.org/g/tech-prs/message/798 Signed-off-by: Clément Léger <cleger@rivosinc.com> Reviewed-by: Himanshu Chauhan <hchauhan@ventanamicro.com> Reviewed-by: Anup Patel <anup@brainfault.org>
Diffstat (limited to 'include')
-rw-r--r--include/sbi/sbi_ecall_interface.h79
-rw-r--r--include/sbi/sbi_error.h2
-rw-r--r--include/sbi/sbi_sse.h93
3 files changed, 173 insertions, 1 deletions
diff --git a/include/sbi/sbi_ecall_interface.h b/include/sbi/sbi_ecall_interface.h
index 690c31b..a511e0b 100644
--- a/include/sbi/sbi_ecall_interface.h
+++ b/include/sbi/sbi_ecall_interface.h
@@ -33,6 +33,7 @@
#define SBI_EXT_SUSP 0x53555350
#define SBI_EXT_CPPC 0x43505043
#define SBI_EXT_DBTR 0x44425452
+#define SBI_EXT_SSE 0x535345
/* SBI function IDs for BASE extension*/
#define SBI_EXT_BASE_GET_SPEC_VERSION 0x0
@@ -304,6 +305,80 @@ enum sbi_cppc_reg_id {
SBI_CPPC_NON_ACPI_LAST = SBI_CPPC_TRANSITION_LATENCY,
};
+/* SBI Function IDs for SSE extension */
+#define SBI_EXT_SSE_READ_ATTR 0x00000000
+#define SBI_EXT_SSE_WRITE_ATTR 0x00000001
+#define SBI_EXT_SSE_REGISTER 0x00000002
+#define SBI_EXT_SSE_UNREGISTER 0x00000003
+#define SBI_EXT_SSE_ENABLE 0x00000004
+#define SBI_EXT_SSE_DISABLE 0x00000005
+#define SBI_EXT_SSE_COMPLETE 0x00000006
+#define SBI_EXT_SSE_INJECT 0x00000007
+
+/* SBI SSE Event Attributes. */
+enum sbi_sse_attr_id {
+ SBI_SSE_ATTR_STATUS = 0x00000000,
+ SBI_SSE_ATTR_PRIO = 0x00000001,
+ SBI_SSE_ATTR_CONFIG = 0x00000002,
+ SBI_SSE_ATTR_PREFERRED_HART = 0x00000003,
+ SBI_SSE_ATTR_ENTRY_PC = 0x00000004,
+ SBI_SSE_ATTR_ENTRY_ARG = 0x00000005,
+ SBI_SSE_ATTR_INTERRUPTED_SEPC = 0x00000006,
+ SBI_SSE_ATTR_INTERRUPTED_FLAGS = 0x00000007,
+ SBI_SSE_ATTR_INTERRUPTED_A6 = 0x00000008,
+ SBI_SSE_ATTR_INTERRUPTED_A7 = 0x00000009,
+
+ SBI_SSE_ATTR_MAX = 0x0000000A
+};
+
+#define SBI_SSE_ATTR_STATUS_STATE_OFFSET 0
+#define SBI_SSE_ATTR_STATUS_STATE_MASK 0x3
+#define SBI_SSE_ATTR_STATUS_PENDING_OFFSET 2
+#define SBI_SSE_ATTR_STATUS_INJECT_OFFSET 3
+
+#define SBI_SSE_ATTR_CONFIG_ONESHOT (1 << 0)
+
+#define SBI_SSE_ATTR_INTERRUPTED_FLAGS_STATUS_SPP BIT(0)
+#define SBI_SSE_ATTR_INTERRUPTED_FLAGS_STATUS_SPIE BIT(1)
+#define SBI_SSE_ATTR_INTERRUPTED_FLAGS_HSTATUS_SPV BIT(2)
+#define SBI_SSE_ATTR_INTERRUPTED_FLAGS_HSTATUS_SPVP BIT(3)
+
+enum sbi_sse_state {
+ SBI_SSE_STATE_UNUSED = 0,
+ SBI_SSE_STATE_REGISTERED = 1,
+ SBI_SSE_STATE_ENABLED = 2,
+ SBI_SSE_STATE_RUNNING = 3,
+};
+
+/* SBI SSE Event IDs. */
+#define SBI_SSE_EVENT_LOCAL_RAS 0x00000000
+#define SBI_SSE_EVENT_LOCAL_PLAT_0_START 0x00004000
+#define SBI_SSE_EVENT_LOCAL_PLAT_0_END 0x00007fff
+#define SBI_SSE_EVENT_GLOBAL_RAS 0x00008000
+#define SBI_SSE_EVENT_GLOBAL_PLAT_0_START 0x00004000
+#define SBI_SSE_EVENT_GLOBAL_PLAT_0_END 0x00007fff
+
+#define SBI_SSE_EVENT_LOCAL_PMU 0x00010000
+#define SBI_SSE_EVENT_LOCAL_PLAT_1_START 0x00014000
+#define SBI_SSE_EVENT_LOCAL_PLAT_1_END 0x00017fff
+#define SBI_SSE_EVENT_GLOBAL_PLAT_1_START 0x0001c000
+#define SBI_SSE_EVENT_GLOBAL_PLAT_1_END 0x0001ffff
+
+#define SBI_SSE_EVENT_LOCAL_PLAT_2_START 0x00024000
+#define SBI_SSE_EVENT_LOCAL_PLAT_2_END 0x00027fff
+#define SBI_SSE_EVENT_GLOBAL_PLAT_2_START 0x0002c000
+#define SBI_SSE_EVENT_GLOBAL_PLAT_2_END 0x0002ffff
+
+#define SBI_SSE_EVENT_LOCAL_SOFTWARE 0xffff0000
+#define SBI_SSE_EVENT_LOCAL_PLAT_3_START 0xffff4000
+#define SBI_SSE_EVENT_LOCAL_PLAT_3_END 0xffff7fff
+#define SBI_SSE_EVENT_GLOBAL_SOFTWARE 0xffff8000
+#define SBI_SSE_EVENT_GLOBAL_PLAT_3_START 0xffffc000
+#define SBI_SSE_EVENT_GLOBAL_PLAT_3_END 0xffffffff
+
+#define SBI_SSE_EVENT_GLOBAL_BIT (1 << 15)
+#define SBI_SSE_EVENT_PLATFORM_BIT (1 << 14)
+
/* SBI base specification related macros */
#define SBI_SPEC_VERSION_MAJOR_OFFSET 24
#define SBI_SPEC_VERSION_MAJOR_MASK 0x7f
@@ -324,8 +399,10 @@ enum sbi_cppc_reg_id {
#define SBI_ERR_ALREADY_STARTED -7
#define SBI_ERR_ALREADY_STOPPED -8
#define SBI_ERR_NO_SHMEM -9
+#define SBI_ERR_INVALID_STATE -10
+#define SBI_ERR_BAD_RANGE -11
-#define SBI_LAST_ERR SBI_ERR_NO_SHMEM
+#define SBI_LAST_ERR SBI_ERR_BAD_RANGE
/* clang-format on */
diff --git a/include/sbi/sbi_error.h b/include/sbi/sbi_error.h
index a77e3f8..fb78bf6 100644
--- a/include/sbi/sbi_error.h
+++ b/include/sbi/sbi_error.h
@@ -24,6 +24,8 @@
#define SBI_EALREADY_STARTED SBI_ERR_ALREADY_STARTED
#define SBI_EALREADY_STOPPED SBI_ERR_ALREADY_STOPPED
#define SBI_ENO_SHMEM SBI_ERR_NO_SHMEM
+#define SBI_EINVALID_STATE SBI_ERR_INVALID_STATE
+#define SBI_EBAD_RANGE SBI_ERR_BAD_RANGE
#define SBI_ENODEV -1000
#define SBI_ENOSYS -1001
diff --git a/include/sbi/sbi_sse.h b/include/sbi/sbi_sse.h
new file mode 100644
index 0000000..e5b0ad6
--- /dev/null
+++ b/include/sbi/sbi_sse.h
@@ -0,0 +1,93 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2023 Rivos Systems.
+ */
+
+#ifndef __SBI_SSE_H__
+#define __SBI_SSE_H__
+
+#include <sbi/sbi_types.h>
+#include <sbi/sbi_list.h>
+#include <sbi/riscv_locks.h>
+
+struct sbi_scratch;
+struct sbi_trap_regs;
+struct sbi_ecall_return;
+
+#define EXC_MODE_PP_SHIFT 0
+#define EXC_MODE_PP BIT(EXC_MODE_PP_SHIFT)
+#define EXC_MODE_PV_SHIFT 1
+#define EXC_MODE_PV BIT(EXC_MODE_PV_SHIFT)
+#define EXC_MODE_SSTATUS_SPIE_SHIFT 2
+#define EXC_MODE_SSTATUS_SPIE BIT(EXC_MODE_SSTATUS_SPIE_SHIFT)
+
+struct sbi_sse_cb_ops {
+ /**
+ * Called when hart_id is changed on the event.
+ */
+ void (*set_hartid_cb)(uint32_t event_id, unsigned long hart_id);
+
+ /**
+ * Called when the SBI_EXT_SSE_COMPLETE is invoked on the event.
+ */
+ void (*complete_cb)(uint32_t event_id);
+
+ /**
+ * Called when the SBI_EXT_SSE_REGISTER is invoked on the event.
+ */
+ void (*register_cb)(uint32_t event_id);
+
+ /**
+ * Called when the SBI_EXT_SSE_UNREGISTER is invoked on the event.
+ */
+ void (*unregister_cb)(uint32_t event_id);
+
+ /**
+ * Called when the SBI_EXT_SSE_ENABLE is invoked on the event.
+ */
+ void (*enable_cb)(uint32_t event_id);
+
+ /**
+ * Called when the SBI_EXT_SSE_DISABLE is invoked on the event.
+ */
+ void (*disable_cb)(uint32_t event_id);
+};
+
+/* Set the callback operations for an event
+ * @param event_id Event identifier (SBI_SSE_EVENT_*)
+ * @param cb_ops Callback operations
+ * @return 0 on success, error otherwise
+ */
+int sbi_sse_set_cb_ops(uint32_t event_id, const struct sbi_sse_cb_ops *cb_ops);
+
+/* Inject an event to the current hard
+ * @param event_id Event identifier (SBI_SSE_EVENT_*)
+ * @param regs Registers that were used on SBI entry
+ * @return 0 on success, error otherwise
+ */
+int sbi_sse_inject_event(uint32_t event_id);
+
+void sbi_sse_process_pending_events(struct sbi_trap_regs *regs);
+
+
+int sbi_sse_init(struct sbi_scratch *scratch, bool cold_boot);
+void sbi_sse_exit(struct sbi_scratch *scratch);
+
+/* Interface called from sbi_ecall_sse.c */
+int sbi_sse_register(uint32_t event_id, unsigned long handler_entry_pc,
+ unsigned long handler_entry_arg);
+int sbi_sse_unregister(uint32_t event_id);
+int sbi_sse_enable(uint32_t event_id);
+int sbi_sse_disable(uint32_t event_id);
+int sbi_sse_complete(struct sbi_trap_regs *regs, struct sbi_ecall_return *out);
+int sbi_sse_inject_from_ecall(uint32_t event_id, unsigned long hart_id,
+ struct sbi_ecall_return *out);
+int sbi_sse_read_attrs(uint32_t event_id, uint32_t base_attr_id,
+ uint32_t attr_count, unsigned long output_phys_lo,
+ unsigned long output_phys_hi);
+int sbi_sse_write_attrs(uint32_t event_id, uint32_t base_attr_id,
+ uint32_t attr_count, unsigned long input_phys_lo,
+ unsigned long input_phys_hi);
+
+#endif