Skip to content

Commit c8cdf01

Browse files
clementlegeravpatel
authored andcommitted
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>
1 parent 76d7e9b commit c8cdf01

File tree

7 files changed

+1322
-1
lines changed

7 files changed

+1322
-1
lines changed

include/sbi/sbi_ecall_interface.h

Lines changed: 78 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
#define SBI_EXT_SUSP 0x53555350
3434
#define SBI_EXT_CPPC 0x43505043
3535
#define SBI_EXT_DBTR 0x44425452
36+
#define SBI_EXT_SSE 0x535345
3637

3738
/* SBI function IDs for BASE extension*/
3839
#define SBI_EXT_BASE_GET_SPEC_VERSION 0x0
@@ -304,6 +305,80 @@ enum sbi_cppc_reg_id {
304305
SBI_CPPC_NON_ACPI_LAST = SBI_CPPC_TRANSITION_LATENCY,
305306
};
306307

308+
/* SBI Function IDs for SSE extension */
309+
#define SBI_EXT_SSE_READ_ATTR 0x00000000
310+
#define SBI_EXT_SSE_WRITE_ATTR 0x00000001
311+
#define SBI_EXT_SSE_REGISTER 0x00000002
312+
#define SBI_EXT_SSE_UNREGISTER 0x00000003
313+
#define SBI_EXT_SSE_ENABLE 0x00000004
314+
#define SBI_EXT_SSE_DISABLE 0x00000005
315+
#define SBI_EXT_SSE_COMPLETE 0x00000006
316+
#define SBI_EXT_SSE_INJECT 0x00000007
317+
318+
/* SBI SSE Event Attributes. */
319+
enum sbi_sse_attr_id {
320+
SBI_SSE_ATTR_STATUS = 0x00000000,
321+
SBI_SSE_ATTR_PRIO = 0x00000001,
322+
SBI_SSE_ATTR_CONFIG = 0x00000002,
323+
SBI_SSE_ATTR_PREFERRED_HART = 0x00000003,
324+
SBI_SSE_ATTR_ENTRY_PC = 0x00000004,
325+
SBI_SSE_ATTR_ENTRY_ARG = 0x00000005,
326+
SBI_SSE_ATTR_INTERRUPTED_SEPC = 0x00000006,
327+
SBI_SSE_ATTR_INTERRUPTED_FLAGS = 0x00000007,
328+
SBI_SSE_ATTR_INTERRUPTED_A6 = 0x00000008,
329+
SBI_SSE_ATTR_INTERRUPTED_A7 = 0x00000009,
330+
331+
SBI_SSE_ATTR_MAX = 0x0000000A
332+
};
333+
334+
#define SBI_SSE_ATTR_STATUS_STATE_OFFSET 0
335+
#define SBI_SSE_ATTR_STATUS_STATE_MASK 0x3
336+
#define SBI_SSE_ATTR_STATUS_PENDING_OFFSET 2
337+
#define SBI_SSE_ATTR_STATUS_INJECT_OFFSET 3
338+
339+
#define SBI_SSE_ATTR_CONFIG_ONESHOT (1 << 0)
340+
341+
#define SBI_SSE_ATTR_INTERRUPTED_FLAGS_STATUS_SPP BIT(0)
342+
#define SBI_SSE_ATTR_INTERRUPTED_FLAGS_STATUS_SPIE BIT(1)
343+
#define SBI_SSE_ATTR_INTERRUPTED_FLAGS_HSTATUS_SPV BIT(2)
344+
#define SBI_SSE_ATTR_INTERRUPTED_FLAGS_HSTATUS_SPVP BIT(3)
345+
346+
enum sbi_sse_state {
347+
SBI_SSE_STATE_UNUSED = 0,
348+
SBI_SSE_STATE_REGISTERED = 1,
349+
SBI_SSE_STATE_ENABLED = 2,
350+
SBI_SSE_STATE_RUNNING = 3,
351+
};
352+
353+
/* SBI SSE Event IDs. */
354+
#define SBI_SSE_EVENT_LOCAL_RAS 0x00000000
355+
#define SBI_SSE_EVENT_LOCAL_PLAT_0_START 0x00004000
356+
#define SBI_SSE_EVENT_LOCAL_PLAT_0_END 0x00007fff
357+
#define SBI_SSE_EVENT_GLOBAL_RAS 0x00008000
358+
#define SBI_SSE_EVENT_GLOBAL_PLAT_0_START 0x00004000
359+
#define SBI_SSE_EVENT_GLOBAL_PLAT_0_END 0x00007fff
360+
361+
#define SBI_SSE_EVENT_LOCAL_PMU 0x00010000
362+
#define SBI_SSE_EVENT_LOCAL_PLAT_1_START 0x00014000
363+
#define SBI_SSE_EVENT_LOCAL_PLAT_1_END 0x00017fff
364+
#define SBI_SSE_EVENT_GLOBAL_PLAT_1_START 0x0001c000
365+
#define SBI_SSE_EVENT_GLOBAL_PLAT_1_END 0x0001ffff
366+
367+
#define SBI_SSE_EVENT_LOCAL_PLAT_2_START 0x00024000
368+
#define SBI_SSE_EVENT_LOCAL_PLAT_2_END 0x00027fff
369+
#define SBI_SSE_EVENT_GLOBAL_PLAT_2_START 0x0002c000
370+
#define SBI_SSE_EVENT_GLOBAL_PLAT_2_END 0x0002ffff
371+
372+
#define SBI_SSE_EVENT_LOCAL_SOFTWARE 0xffff0000
373+
#define SBI_SSE_EVENT_LOCAL_PLAT_3_START 0xffff4000
374+
#define SBI_SSE_EVENT_LOCAL_PLAT_3_END 0xffff7fff
375+
#define SBI_SSE_EVENT_GLOBAL_SOFTWARE 0xffff8000
376+
#define SBI_SSE_EVENT_GLOBAL_PLAT_3_START 0xffffc000
377+
#define SBI_SSE_EVENT_GLOBAL_PLAT_3_END 0xffffffff
378+
379+
#define SBI_SSE_EVENT_GLOBAL_BIT (1 << 15)
380+
#define SBI_SSE_EVENT_PLATFORM_BIT (1 << 14)
381+
307382
/* SBI base specification related macros */
308383
#define SBI_SPEC_VERSION_MAJOR_OFFSET 24
309384
#define SBI_SPEC_VERSION_MAJOR_MASK 0x7f
@@ -324,8 +399,10 @@ enum sbi_cppc_reg_id {
324399
#define SBI_ERR_ALREADY_STARTED -7
325400
#define SBI_ERR_ALREADY_STOPPED -8
326401
#define SBI_ERR_NO_SHMEM -9
402+
#define SBI_ERR_INVALID_STATE -10
403+
#define SBI_ERR_BAD_RANGE -11
327404

328-
#define SBI_LAST_ERR SBI_ERR_NO_SHMEM
405+
#define SBI_LAST_ERR SBI_ERR_BAD_RANGE
329406

330407
/* clang-format on */
331408

include/sbi/sbi_error.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
#define SBI_EALREADY_STARTED SBI_ERR_ALREADY_STARTED
2525
#define SBI_EALREADY_STOPPED SBI_ERR_ALREADY_STOPPED
2626
#define SBI_ENO_SHMEM SBI_ERR_NO_SHMEM
27+
#define SBI_EINVALID_STATE SBI_ERR_INVALID_STATE
28+
#define SBI_EBAD_RANGE SBI_ERR_BAD_RANGE
2729

2830
#define SBI_ENODEV -1000
2931
#define SBI_ENOSYS -1001

include/sbi/sbi_sse.h

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
/*
2+
* SPDX-License-Identifier: BSD-2-Clause
3+
*
4+
* Copyright (c) 2023 Rivos Systems.
5+
*/
6+
7+
#ifndef __SBI_SSE_H__
8+
#define __SBI_SSE_H__
9+
10+
#include <sbi/sbi_types.h>
11+
#include <sbi/sbi_list.h>
12+
#include <sbi/riscv_locks.h>
13+
14+
struct sbi_scratch;
15+
struct sbi_trap_regs;
16+
struct sbi_ecall_return;
17+
18+
#define EXC_MODE_PP_SHIFT 0
19+
#define EXC_MODE_PP BIT(EXC_MODE_PP_SHIFT)
20+
#define EXC_MODE_PV_SHIFT 1
21+
#define EXC_MODE_PV BIT(EXC_MODE_PV_SHIFT)
22+
#define EXC_MODE_SSTATUS_SPIE_SHIFT 2
23+
#define EXC_MODE_SSTATUS_SPIE BIT(EXC_MODE_SSTATUS_SPIE_SHIFT)
24+
25+
struct sbi_sse_cb_ops {
26+
/**
27+
* Called when hart_id is changed on the event.
28+
*/
29+
void (*set_hartid_cb)(uint32_t event_id, unsigned long hart_id);
30+
31+
/**
32+
* Called when the SBI_EXT_SSE_COMPLETE is invoked on the event.
33+
*/
34+
void (*complete_cb)(uint32_t event_id);
35+
36+
/**
37+
* Called when the SBI_EXT_SSE_REGISTER is invoked on the event.
38+
*/
39+
void (*register_cb)(uint32_t event_id);
40+
41+
/**
42+
* Called when the SBI_EXT_SSE_UNREGISTER is invoked on the event.
43+
*/
44+
void (*unregister_cb)(uint32_t event_id);
45+
46+
/**
47+
* Called when the SBI_EXT_SSE_ENABLE is invoked on the event.
48+
*/
49+
void (*enable_cb)(uint32_t event_id);
50+
51+
/**
52+
* Called when the SBI_EXT_SSE_DISABLE is invoked on the event.
53+
*/
54+
void (*disable_cb)(uint32_t event_id);
55+
};
56+
57+
/* Set the callback operations for an event
58+
* @param event_id Event identifier (SBI_SSE_EVENT_*)
59+
* @param cb_ops Callback operations
60+
* @return 0 on success, error otherwise
61+
*/
62+
int sbi_sse_set_cb_ops(uint32_t event_id, const struct sbi_sse_cb_ops *cb_ops);
63+
64+
/* Inject an event to the current hard
65+
* @param event_id Event identifier (SBI_SSE_EVENT_*)
66+
* @param regs Registers that were used on SBI entry
67+
* @return 0 on success, error otherwise
68+
*/
69+
int sbi_sse_inject_event(uint32_t event_id);
70+
71+
void sbi_sse_process_pending_events(struct sbi_trap_regs *regs);
72+
73+
74+
int sbi_sse_init(struct sbi_scratch *scratch, bool cold_boot);
75+
void sbi_sse_exit(struct sbi_scratch *scratch);
76+
77+
/* Interface called from sbi_ecall_sse.c */
78+
int sbi_sse_register(uint32_t event_id, unsigned long handler_entry_pc,
79+
unsigned long handler_entry_arg);
80+
int sbi_sse_unregister(uint32_t event_id);
81+
int sbi_sse_enable(uint32_t event_id);
82+
int sbi_sse_disable(uint32_t event_id);
83+
int sbi_sse_complete(struct sbi_trap_regs *regs, struct sbi_ecall_return *out);
84+
int sbi_sse_inject_from_ecall(uint32_t event_id, unsigned long hart_id,
85+
struct sbi_ecall_return *out);
86+
int sbi_sse_read_attrs(uint32_t event_id, uint32_t base_attr_id,
87+
uint32_t attr_count, unsigned long output_phys_lo,
88+
unsigned long output_phys_hi);
89+
int sbi_sse_write_attrs(uint32_t event_id, uint32_t base_attr_id,
90+
uint32_t attr_count, unsigned long input_phys_lo,
91+
unsigned long input_phys_hi);
92+
93+
#endif

lib/sbi/objects.mk

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ libsbi-objs-y += sbi_platform.o
7575
libsbi-objs-y += sbi_pmu.o
7676
libsbi-objs-y += sbi_dbtr.o
7777
libsbi-objs-y += sbi_scratch.o
78+
libsbi-objs-y += sbi_sse.o
7879
libsbi-objs-y += sbi_string.o
7980
libsbi-objs-y += sbi_system.o
8081
libsbi-objs-y += sbi_timer.o

lib/sbi/sbi_init.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include <sbi/sbi_platform.h>
2525
#include <sbi/sbi_pmu.h>
2626
#include <sbi/sbi_dbtr.h>
27+
#include <sbi/sbi_sse.h>
2728
#include <sbi/sbi_system.h>
2829
#include <sbi/sbi_string.h>
2930
#include <sbi/sbi_timer.h>
@@ -319,6 +320,12 @@ static void __noreturn init_coldboot(struct sbi_scratch *scratch, u32 hartid)
319320
if (rc)
320321
sbi_hart_hang();
321322

323+
rc = sbi_sse_init(scratch, true);
324+
if (rc) {
325+
sbi_printf("%s: sse init failed (error %d)\n", __func__, rc);
326+
sbi_hart_hang();
327+
}
328+
322329
rc = sbi_pmu_init(scratch, true);
323330
if (rc) {
324331
sbi_printf("%s: pmu init failed (error %d)\n",
@@ -445,6 +452,10 @@ static void __noreturn init_warm_startup(struct sbi_scratch *scratch,
445452
if (rc)
446453
sbi_hart_hang();
447454

455+
rc = sbi_sse_init(scratch, false);
456+
if (rc)
457+
sbi_hart_hang();
458+
448459
rc = sbi_pmu_init(scratch, false);
449460
if (rc)
450461
sbi_hart_hang();
@@ -653,6 +664,8 @@ void __noreturn sbi_exit(struct sbi_scratch *scratch)
653664

654665
sbi_platform_early_exit(plat);
655666

667+
sbi_sse_exit(scratch);
668+
656669
sbi_pmu_exit(scratch);
657670

658671
sbi_timer_exit(scratch);

0 commit comments

Comments
 (0)