Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions MAINTAINERS
Original file line number Diff line number Diff line change
Expand Up @@ -20833,6 +20833,13 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/iommu/linux.git
F: Documentation/devicetree/bindings/iommu/riscv,iommu.yaml
F: drivers/iommu/riscv/

RISC-V FIRMWARE DRIVERS
M: Conor Dooley <conor@kernel.org>
L: linux-riscv@lists.infradead.org
S: Maintained
T: git git://git.kernel.org/pub/scm/linux/kernel/git/conor/linux.git
F: drivers/firmware/riscv/*

RISC-V MICROCHIP FPGA SUPPORT
M: Conor Dooley <conor.dooley@microchip.com>
M: Daire McNamara <daire.mcnamara@microchip.com>
Expand Down Expand Up @@ -20897,6 +20904,14 @@ F: arch/riscv/boot/dts/spacemit/
N: spacemit
K: spacemit

RISC-V SSE DRIVER
M: Clément Léger <cleger@rivosinc.com>
R: Himanshu Chauhan <himanshu@thechauhan.dev>
L: linux-riscv@lists.infradead.org
S: Maintained
F: drivers/firmware/riscv/riscv_sse.c
F: include/linux/riscv_sse.h

RISC-V THEAD SoC SUPPORT
M: Drew Fustini <drew@pdp7.com>
M: Guo Ren <guoren@kernel.org>
Expand Down
14 changes: 11 additions & 3 deletions arch/riscv/include/asm/asm.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,16 +90,24 @@
#define PER_CPU_OFFSET_SHIFT 3
#endif

.macro asm_per_cpu dst sym tmp
REG_L \tmp, TASK_TI_CPU_NUM(tp)
slli \tmp, \tmp, PER_CPU_OFFSET_SHIFT
.macro asm_per_cpu_with_cpu dst sym tmp cpu
slli \tmp, \cpu, PER_CPU_OFFSET_SHIFT
la \dst, __per_cpu_offset
add \dst, \dst, \tmp
REG_L \tmp, 0(\dst)
la \dst, \sym
add \dst, \dst, \tmp
.endm

.macro asm_per_cpu dst sym tmp
REG_L \tmp, TASK_TI_CPU_NUM(tp)
asm_per_cpu_with_cpu \dst \sym \tmp \tmp
.endm
#else /* CONFIG_SMP */
.macro asm_per_cpu_with_cpu dst sym tmp cpu
la \dst, \sym
.endm

.macro asm_per_cpu dst sym tmp
la \dst, \sym
.endm
Expand Down
65 changes: 65 additions & 0 deletions arch/riscv/include/asm/sbi.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ enum sbi_ext_id {
SBI_EXT_DBCN = 0x4442434E,
SBI_EXT_STA = 0x535441,
SBI_EXT_NACL = 0x4E41434C,
SBI_EXT_SSE = 0x535345,

/* Experimentals extensions must lie within this range */
SBI_EXT_EXPERIMENTAL_START = 0x08000000,
Expand Down Expand Up @@ -402,6 +403,66 @@ enum sbi_ext_nacl_feature {
#define SBI_NACL_SHMEM_SRET_X(__i) ((__riscv_xlen / 8) * (__i))
#define SBI_NACL_SHMEM_SRET_X_LAST 31

enum sbi_ext_sse_fid {
SBI_SSE_EVENT_ATTR_READ = 0,
SBI_SSE_EVENT_ATTR_WRITE,
SBI_SSE_EVENT_REGISTER,
SBI_SSE_EVENT_UNREGISTER,
SBI_SSE_EVENT_ENABLE,
SBI_SSE_EVENT_DISABLE,
SBI_SSE_EVENT_COMPLETE,
SBI_SSE_EVENT_SIGNAL,
SBI_SSE_EVENT_HART_UNMASK,
SBI_SSE_EVENT_HART_MASK,
};

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 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_SSTATUS_SPP (1 << 0)
#define SBI_SSE_ATTR_INTERRUPTED_FLAGS_SSTATUS_SPIE (1 << 1)
#define SBI_SSE_ATTR_INTERRUPTED_FLAGS_HSTATUS_SPV (1 << 2)
#define SBI_SSE_ATTR_INTERRUPTED_FLAGS_HSTATUS_SPVP (1 << 3)

#define SBI_SSE_EVENT_LOCAL_HIGH_PRIO_RAS 0x00000000
#define SBI_SSE_EVENT_LOCAL_DOUBLE_TRAP 0x00000001
#define SBI_SSE_EVENT_GLOBAL_HIGH_PRIO_RAS 0x00008000
#define SBI_SSE_EVENT_LOCAL_PMU_OVERFLOW 0x00010000
#define SBI_SSE_EVENT_LOCAL_LOW_PRIO_RAS 0x00100000
#define SBI_SSE_EVENT_GLOBAL_LOW_PRIO_RAS 0x00108000
#define SBI_SSE_EVENT_LOCAL_SOFTWARE_INJECTED 0xffff0000
#define SBI_SSE_EVENT_GLOBAL_SOFTWARE_INJECTED 0xffff8000

#define SBI_SSE_EVENT_PLATFORM (1 << 14)
#define SBI_SSE_EVENT_GLOBAL (1 << 15)

/* SBI spec version fields */
#define SBI_SPEC_VERSION_DEFAULT 0x1
#define SBI_SPEC_VERSION_MAJOR_SHIFT 24
Expand All @@ -419,6 +480,8 @@ enum sbi_ext_nacl_feature {
#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

extern unsigned long sbi_spec_version;
struct sbiret {
Expand Down Expand Up @@ -505,6 +568,8 @@ static inline int sbi_err_map_linux_errno(int err)
case SBI_ERR_DENIED:
return -EPERM;
case SBI_ERR_INVALID_PARAM:
case SBI_ERR_BAD_RANGE:
case SBI_ERR_INVALID_STATE:
return -EINVAL;
case SBI_ERR_INVALID_ADDRESS:
return -EFAULT;
Expand Down
7 changes: 7 additions & 0 deletions arch/riscv/include/asm/scs.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@
load_per_cpu gp, irq_shadow_call_stack_ptr, \tmp
.endm

/* Load the per-CPU IRQ shadow call stack to gp. */
.macro scs_load_sse_stack reg_evt
REG_L gp, SSE_REG_EVT_SHADOW_STACK(\reg_evt)
.endm

/* Load task_scs_sp(current) to gp. */
.macro scs_load_current
REG_L gp, TASK_TI_SCS_SP(tp)
Expand All @@ -41,6 +46,8 @@
.endm
.macro scs_load_irq_stack tmp
.endm
.macro scs_load_sse_stack reg_evt
.endm
.macro scs_load_current
.endm
.macro scs_load_current_if_task_changed prev
Expand Down
45 changes: 45 additions & 0 deletions arch/riscv/include/asm/sse.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (C) 2024 Rivos Inc.
*/
#ifndef __ASM_SSE_H
#define __ASM_SSE_H

#include <asm/sbi.h>

#ifdef CONFIG_RISCV_SSE

struct sse_event_interrupted_state {
unsigned long a6;
unsigned long a7;
};

struct sse_event_arch_data {
void *stack;
void *shadow_stack;
unsigned long tmp;
struct sse_event_interrupted_state interrupted;
unsigned long interrupted_state_phys;
u32 evt_id;
};

static inline bool sse_event_is_global(u32 evt)
{
return !!(evt & SBI_SSE_EVENT_GLOBAL);
}

struct sse_registered_event;
int arch_sse_init_event(struct sse_event_arch_data *arch_evt, u32 evt_id,
int cpu);
void arch_sse_free_event(struct sse_event_arch_data *arch_evt);
int arch_sse_register_event(struct sse_event_arch_data *arch_evt);

void sse_handle_event(struct sse_event_arch_data *arch_evt,
struct pt_regs *regs);
asmlinkage void handle_sse(void);
asmlinkage void do_sse(struct sse_event_arch_data *arch_evt,
struct pt_regs *reg);

#endif

#endif
14 changes: 14 additions & 0 deletions arch/riscv/include/asm/switch_to.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,19 @@ static inline void __switch_to_envcfg(struct task_struct *next)
:: "r" (next->thread.envcfg) : "memory");
}

#ifdef CONFIG_RISCV_SSE
DECLARE_PER_CPU(struct task_struct *, __sse_entry_task);

static inline void __switch_sse_entry_task(struct task_struct *next)
{
__this_cpu_write(__sse_entry_task, next);
}
#else
static inline void __switch_sse_entry_task(struct task_struct *next)
{
}
#endif

extern struct task_struct *__switch_to(struct task_struct *,
struct task_struct *);

Expand Down Expand Up @@ -122,6 +135,7 @@ do { \
if (switch_to_should_flush_icache(__next)) \
local_flush_icache_all(); \
__switch_to_envcfg(__next); \
__switch_sse_entry_task(__next); \
((last) = __switch_to(__prev, __next)); \
} while (0)

Expand Down
1 change: 1 addition & 0 deletions arch/riscv/include/asm/thread_info.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
#define OVERFLOW_STACK_SIZE SZ_4K

#define IRQ_STACK_SIZE THREAD_SIZE
#define SSE_STACK_SIZE THREAD_SIZE

#ifndef __ASSEMBLY__

Expand Down
1 change: 1 addition & 0 deletions arch/riscv/kernel/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ obj-$(CONFIG_DYNAMIC_FTRACE) += mcount-dyn.o
obj-$(CONFIG_PERF_EVENTS) += perf_callchain.o
obj-$(CONFIG_HAVE_PERF_REGS) += perf_regs.o
obj-$(CONFIG_RISCV_SBI) += sbi.o sbi_ecall.o
obj-$(CONFIG_RISCV_SSE) += sse.o sse_entry.o
ifeq ($(CONFIG_RISCV_SBI), y)
obj-$(CONFIG_SMP) += sbi-ipi.o
obj-$(CONFIG_SMP) += cpu_ops_sbi.o
Expand Down
12 changes: 12 additions & 0 deletions arch/riscv/kernel/asm-offsets.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
#include <asm/ptrace.h>
#include <asm/cpu_ops_sbi.h>
#include <asm/stacktrace.h>
#include <asm/sbi.h>
#include <asm/sse.h>
#include <asm/suspend.h>

void asm_offsets(void);
Expand Down Expand Up @@ -510,4 +512,14 @@ void asm_offsets(void)
DEFINE(FREGS_A6, offsetof(struct __arch_ftrace_regs, a6));
DEFINE(FREGS_A7, offsetof(struct __arch_ftrace_regs, a7));
#endif

#ifdef CONFIG_RISCV_SSE
OFFSET(SSE_REG_EVT_STACK, sse_event_arch_data, stack);
OFFSET(SSE_REG_EVT_SHADOW_STACK, sse_event_arch_data, shadow_stack);
OFFSET(SSE_REG_EVT_TMP, sse_event_arch_data, tmp);

DEFINE(SBI_EXT_SSE, SBI_EXT_SSE);
DEFINE(SBI_SSE_EVENT_COMPLETE, SBI_SSE_EVENT_COMPLETE);
DEFINE(NR_CPUS, NR_CPUS);
#endif
}
Loading
Loading