Skip to content

Commit a4c3733

Browse files
Christoph Hellwigpaul-walmsley-sifive
authored andcommitted
riscv: abstract out CSR names for supervisor vs machine mode
Many of the privileged CSRs exist in a supervisor and machine version that are used very similarly. Provide versions of the CSR names and fields that map to either the S-mode or M-mode variant depending on a new CONFIG_RISCV_M_MODE kconfig symbol. Contains contributions from Damien Le Moal <[email protected]> and Paul Walmsley <[email protected]>. Signed-off-by: Christoph Hellwig <[email protected]> Acked-by: Thomas Gleixner <[email protected]> # for drivers/clocksource, drivers/irqchip [[email protected]: updated to apply] Signed-off-by: Paul Walmsley <[email protected]>
1 parent 0c3ac28 commit a4c3733

File tree

21 files changed

+199
-135
lines changed

21 files changed

+199
-135
lines changed

arch/riscv/Kconfig

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,10 @@ config ARCH_MMAP_RND_BITS_MAX
7272
default 24 if 64BIT # SV39 based
7373
default 17
7474

75+
# set if we run in machine mode, cleared if we run in supervisor mode
76+
config RISCV_M_MODE
77+
bool
78+
7579
config MMU
7680
def_bool y
7781

arch/riscv/include/asm/csr.h

Lines changed: 62 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,11 @@
1111

1212
/* Status register flags */
1313
#define SR_SIE _AC(0x00000002, UL) /* Supervisor Interrupt Enable */
14+
#define SR_MIE _AC(0x00000008, UL) /* Machine Interrupt Enable */
1415
#define SR_SPIE _AC(0x00000020, UL) /* Previous Supervisor IE */
16+
#define SR_MPIE _AC(0x00000080, UL) /* Previous Machine IE */
1517
#define SR_SPP _AC(0x00000100, UL) /* Previously Supervisor */
18+
#define SR_MPP _AC(0x00001800, UL) /* Previously Machine */
1619
#define SR_SUM _AC(0x00040000, UL) /* Supervisor User Memory Access */
1720

1821
#define SR_FS _AC(0x00006000, UL) /* Floating-point Status */
@@ -44,9 +47,10 @@
4447
#define SATP_MODE SATP_MODE_39
4548
#endif
4649

47-
/* SCAUSE */
48-
#define SCAUSE_IRQ_FLAG (_AC(1, UL) << (__riscv_xlen - 1))
50+
/* Exception cause high bit - is an interrupt if set */
51+
#define CAUSE_IRQ_FLAG (_AC(1, UL) << (__riscv_xlen - 1))
4952

53+
/* Interrupt causes (minus the high bit) */
5054
#define IRQ_U_SOFT 0
5155
#define IRQ_S_SOFT 1
5256
#define IRQ_M_SOFT 3
@@ -57,6 +61,7 @@
5761
#define IRQ_S_EXT 9
5862
#define IRQ_M_EXT 11
5963

64+
/* Exception causes */
6065
#define EXC_INST_MISALIGNED 0
6166
#define EXC_INST_ACCESS 1
6267
#define EXC_BREAKPOINT 3
@@ -67,14 +72,14 @@
6772
#define EXC_LOAD_PAGE_FAULT 13
6873
#define EXC_STORE_PAGE_FAULT 15
6974

70-
/* SIE (Interrupt Enable) and SIP (Interrupt Pending) flags */
71-
#define SIE_SSIE (_AC(0x1, UL) << IRQ_S_SOFT)
72-
#define SIE_STIE (_AC(0x1, UL) << IRQ_S_TIMER)
73-
#define SIE_SEIE (_AC(0x1, UL) << IRQ_S_EXT)
74-
75+
/* symbolic CSR names: */
7576
#define CSR_CYCLE 0xc00
7677
#define CSR_TIME 0xc01
7778
#define CSR_INSTRET 0xc02
79+
#define CSR_CYCLEH 0xc80
80+
#define CSR_TIMEH 0xc81
81+
#define CSR_INSTRETH 0xc82
82+
7883
#define CSR_SSTATUS 0x100
7984
#define CSR_SIE 0x104
8085
#define CSR_STVEC 0x105
@@ -85,9 +90,56 @@
8590
#define CSR_STVAL 0x143
8691
#define CSR_SIP 0x144
8792
#define CSR_SATP 0x180
88-
#define CSR_CYCLEH 0xc80
89-
#define CSR_TIMEH 0xc81
90-
#define CSR_INSTRETH 0xc82
93+
94+
#define CSR_MSTATUS 0x300
95+
#define CSR_MIE 0x304
96+
#define CSR_MTVEC 0x305
97+
#define CSR_MSCRATCH 0x340
98+
#define CSR_MEPC 0x341
99+
#define CSR_MCAUSE 0x342
100+
#define CSR_MTVAL 0x343
101+
#define CSR_MIP 0x344
102+
103+
#ifdef CONFIG_RISCV_M_MODE
104+
# define CSR_STATUS CSR_MSTATUS
105+
# define CSR_IE CSR_MIE
106+
# define CSR_TVEC CSR_MTVEC
107+
# define CSR_SCRATCH CSR_MSCRATCH
108+
# define CSR_EPC CSR_MEPC
109+
# define CSR_CAUSE CSR_MCAUSE
110+
# define CSR_TVAL CSR_MTVAL
111+
# define CSR_IP CSR_MIP
112+
113+
# define SR_IE SR_MIE
114+
# define SR_PIE SR_MPIE
115+
# define SR_PP SR_MPP
116+
117+
# define IRQ_SOFT IRQ_M_SOFT
118+
# define IRQ_TIMER IRQ_M_TIMER
119+
# define IRQ_EXT IRQ_M_EXT
120+
#else /* CONFIG_RISCV_M_MODE */
121+
# define CSR_STATUS CSR_SSTATUS
122+
# define CSR_IE CSR_SIE
123+
# define CSR_TVEC CSR_STVEC
124+
# define CSR_SCRATCH CSR_SSCRATCH
125+
# define CSR_EPC CSR_SEPC
126+
# define CSR_CAUSE CSR_SCAUSE
127+
# define CSR_TVAL CSR_STVAL
128+
# define CSR_IP CSR_SIP
129+
130+
# define SR_IE SR_SIE
131+
# define SR_PIE SR_SPIE
132+
# define SR_PP SR_SPP
133+
134+
# define IRQ_SOFT IRQ_S_SOFT
135+
# define IRQ_TIMER IRQ_S_TIMER
136+
# define IRQ_EXT IRQ_S_EXT
137+
#endif /* CONFIG_RISCV_M_MODE */
138+
139+
/* IE/IP (Supervisor/Machine Interrupt Enable/Pending) flags */
140+
#define IE_SIE (_AC(0x1, UL) << IRQ_SOFT)
141+
#define IE_TIE (_AC(0x1, UL) << IRQ_TIMER)
142+
#define IE_EIE (_AC(0x1, UL) << IRQ_EXT)
91143

92144
#ifndef __ASSEMBLY__
93145

arch/riscv/include/asm/irqflags.h

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,31 +13,31 @@
1313
/* read interrupt enabled status */
1414
static inline unsigned long arch_local_save_flags(void)
1515
{
16-
return csr_read(CSR_SSTATUS);
16+
return csr_read(CSR_STATUS);
1717
}
1818

1919
/* unconditionally enable interrupts */
2020
static inline void arch_local_irq_enable(void)
2121
{
22-
csr_set(CSR_SSTATUS, SR_SIE);
22+
csr_set(CSR_STATUS, SR_IE);
2323
}
2424

2525
/* unconditionally disable interrupts */
2626
static inline void arch_local_irq_disable(void)
2727
{
28-
csr_clear(CSR_SSTATUS, SR_SIE);
28+
csr_clear(CSR_STATUS, SR_IE);
2929
}
3030

3131
/* get status and disable interrupts */
3232
static inline unsigned long arch_local_irq_save(void)
3333
{
34-
return csr_read_clear(CSR_SSTATUS, SR_SIE);
34+
return csr_read_clear(CSR_STATUS, SR_IE);
3535
}
3636

3737
/* test flags */
3838
static inline int arch_irqs_disabled_flags(unsigned long flags)
3939
{
40-
return !(flags & SR_SIE);
40+
return !(flags & SR_IE);
4141
}
4242

4343
/* test hardware interrupt enable bit */
@@ -49,7 +49,7 @@ static inline int arch_irqs_disabled(void)
4949
/* set interrupt enabled status */
5050
static inline void arch_local_irq_restore(unsigned long flags)
5151
{
52-
csr_set(CSR_SSTATUS, flags & SR_SIE);
52+
csr_set(CSR_STATUS, flags & SR_IE);
5353
}
5454

5555
#endif /* _ASM_RISCV_IRQFLAGS_H */

arch/riscv/include/asm/processor.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ struct thread_struct {
4242
((struct pt_regs *)(task_stack_page(tsk) + THREAD_SIZE \
4343
- ALIGN(sizeof(struct pt_regs), STACK_ALIGN)))
4444

45-
#define KSTK_EIP(tsk) (task_pt_regs(tsk)->sepc)
45+
#define KSTK_EIP(tsk) (task_pt_regs(tsk)->epc)
4646
#define KSTK_ESP(tsk) (task_pt_regs(tsk)->sp)
4747

4848

arch/riscv/include/asm/ptrace.h

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
#ifndef __ASSEMBLY__
1313

1414
struct pt_regs {
15-
unsigned long sepc;
15+
unsigned long epc;
1616
unsigned long ra;
1717
unsigned long sp;
1818
unsigned long gp;
@@ -44,10 +44,10 @@ struct pt_regs {
4444
unsigned long t4;
4545
unsigned long t5;
4646
unsigned long t6;
47-
/* Supervisor CSRs */
48-
unsigned long sstatus;
49-
unsigned long sbadaddr;
50-
unsigned long scause;
47+
/* Supervisor/Machine CSRs */
48+
unsigned long status;
49+
unsigned long badaddr;
50+
unsigned long cause;
5151
/* a0 value before the syscall */
5252
unsigned long orig_a0;
5353
};
@@ -58,18 +58,18 @@ struct pt_regs {
5858
#define REG_FMT "%08lx"
5959
#endif
6060

61-
#define user_mode(regs) (((regs)->sstatus & SR_SPP) == 0)
61+
#define user_mode(regs) (((regs)->status & SR_PP) == 0)
6262

6363

6464
/* Helpers for working with the instruction pointer */
6565
static inline unsigned long instruction_pointer(struct pt_regs *regs)
6666
{
67-
return regs->sepc;
67+
return regs->epc;
6868
}
6969
static inline void instruction_pointer_set(struct pt_regs *regs,
7070
unsigned long val)
7171
{
72-
regs->sepc = val;
72+
regs->epc = val;
7373
}
7474

7575
#define profile_pc(regs) instruction_pointer(regs)

arch/riscv/include/asm/switch_to.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,19 +17,19 @@ extern void __fstate_restore(struct task_struct *restore_from);
1717

1818
static inline void __fstate_clean(struct pt_regs *regs)
1919
{
20-
regs->sstatus = (regs->sstatus & ~SR_FS) | SR_FS_CLEAN;
20+
regs->status = (regs->status & ~SR_FS) | SR_FS_CLEAN;
2121
}
2222

2323
static inline void fstate_off(struct task_struct *task,
2424
struct pt_regs *regs)
2525
{
26-
regs->sstatus = (regs->sstatus & ~SR_FS) | SR_FS_OFF;
26+
regs->status = (regs->status & ~SR_FS) | SR_FS_OFF;
2727
}
2828

2929
static inline void fstate_save(struct task_struct *task,
3030
struct pt_regs *regs)
3131
{
32-
if ((regs->sstatus & SR_FS) == SR_FS_DIRTY) {
32+
if ((regs->status & SR_FS) == SR_FS_DIRTY) {
3333
__fstate_save(task);
3434
__fstate_clean(regs);
3535
}
@@ -38,7 +38,7 @@ static inline void fstate_save(struct task_struct *task,
3838
static inline void fstate_restore(struct task_struct *task,
3939
struct pt_regs *regs)
4040
{
41-
if ((regs->sstatus & SR_FS) != SR_FS_OFF) {
41+
if ((regs->status & SR_FS) != SR_FS_OFF) {
4242
__fstate_restore(task);
4343
__fstate_clean(regs);
4444
}
@@ -50,7 +50,7 @@ static inline void __switch_to_aux(struct task_struct *prev,
5050
struct pt_regs *regs;
5151

5252
regs = task_pt_regs(prev);
53-
if (unlikely(regs->sstatus & SR_SD))
53+
if (unlikely(regs->status & SR_SD))
5454
fstate_save(prev, regs);
5555
fstate_restore(next, task_pt_regs(next));
5656
}

arch/riscv/kernel/asm-offsets.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ void asm_offsets(void)
7171
OFFSET(TASK_THREAD_FCSR, task_struct, thread.fstate.fcsr);
7272

7373
DEFINE(PT_SIZE, sizeof(struct pt_regs));
74-
OFFSET(PT_SEPC, pt_regs, sepc);
74+
OFFSET(PT_EPC, pt_regs, epc);
7575
OFFSET(PT_RA, pt_regs, ra);
7676
OFFSET(PT_FP, pt_regs, s0);
7777
OFFSET(PT_S0, pt_regs, s0);
@@ -105,9 +105,9 @@ void asm_offsets(void)
105105
OFFSET(PT_T6, pt_regs, t6);
106106
OFFSET(PT_GP, pt_regs, gp);
107107
OFFSET(PT_ORIG_A0, pt_regs, orig_a0);
108-
OFFSET(PT_SSTATUS, pt_regs, sstatus);
109-
OFFSET(PT_SBADADDR, pt_regs, sbadaddr);
110-
OFFSET(PT_SCAUSE, pt_regs, scause);
108+
OFFSET(PT_STATUS, pt_regs, status);
109+
OFFSET(PT_BADADDR, pt_regs, badaddr);
110+
OFFSET(PT_CAUSE, pt_regs, cause);
111111

112112
/*
113113
* THREAD_{F,X}* might be larger than a S-type offset can handle, but

0 commit comments

Comments
 (0)