1/*
2 * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230)
3 * Copyright 2015, 2016 Hesham Almatary <heshamelmatary@gmail.com>
4 *
5 * SPDX-License-Identifier: GPL-2.0-only
6 */
7
8#pragma once
9
10#include "hardware.h"
11
12#ifndef __ASSEMBLER__
13
14#include <stdint.h>
15#include <util.h>
16#include <arch/types.h>
17
18enum _register {
19
20    ra = 0, LR = 0,
21
22    sp = 1, SP = 1,
23    gp = 2, GP = 2,
24    tp = 3, TP = 3,
25    TLS_BASE = tp,
26
27    t0 = 4,
28#ifdef CONFIG_KERNEL_MCS
29    nbsendRecvDest = 4,
30#endif
31    t1 = 5,
32    t2 = 6,
33    s0 = 7,
34    s1 = 8,
35
36    /* x10-x17 > a0-a7 */
37    a0 = 9, capRegister = 9, badgeRegister = 9,
38    a1 = 10, msgInfoRegister = 10,
39    a2 = 11,
40    a3 = 12,
41    a4 = 13,
42    a5 = 14,
43    a6 = 15,
44#ifdef CONFIG_KERNEL_MCS
45    replyRegister = 15,
46#endif
47    a7 = 16,
48    s2 = 17,
49    s3 = 18,
50    s4 = 19,
51    s5 = 20,
52    s6 = 21,
53    s7 = 22,
54    s8 = 23,
55    s9 = 24,
56    s10 = 25,
57    s11 = 26,
58
59    t3 = 27,
60    t4 = 28,
61    t5 = 29,
62    t6 = 30,
63
64    /* End of GP registers, the following are additional kernel-saved state. */
65    SCAUSE = 31,
66    SSTATUS = 32,
67    FaultIP = 33, /* SEPC */
68    NextIP = 34,
69
70    /* TODO: add other user-level CSRs if needed (i.e. to avoid channels) */
71
72    n_contextRegisters
73};
74
75typedef word_t register_t;
76
77enum messageSizes {
78    n_msgRegisters = 4,
79    n_frameRegisters = 16,
80    n_gpRegisters = 16,
81    n_exceptionMessage = 2,
82    n_syscallMessage = 10,
83#ifdef CONFIG_KERNEL_MCS
84    n_timeoutMessage = 32,
85#endif
86};
87
88extern const register_t msgRegisters[] VISIBLE;
89extern const register_t frameRegisters[] VISIBLE;
90extern const register_t gpRegisters[] VISIBLE;
91
92#ifdef CONFIG_HAVE_FPU
93
94#define RISCV_NUM_FP_REGS   32
95
96#if defined(CONFIG_RISCV_EXT_D)
97typedef uint64_t fp_reg_t;
98#elif defined(CONFIG_RISCV_EXT_F)
99typedef uint32_t fp_reg_t;
100#else
101#error Unknown RISCV FPU extension
102#endif
103
104typedef struct user_fpu_state {
105    fp_reg_t regs[RISCV_NUM_FP_REGS];
106    uint32_t fcsr;
107} user_fpu_state_t;
108
109#endif
110
111struct user_context {
112    word_t registers[n_contextRegisters];
113#ifdef CONFIG_HAVE_FPU
114    user_fpu_state_t fpuState;
115#endif
116};
117typedef struct user_context user_context_t;
118
119static inline void Arch_initContext(user_context_t *context)
120{
121    /* Enable supervisor interrupts (when going to user-mode) */
122    context->registers[SSTATUS] = SSTATUS_SPIE;
123}
124
125static inline word_t CONST sanitiseRegister(register_t reg, word_t v, bool_t archInfo)
126{
127    return v;
128}
129
130
131#define EXCEPTION_MESSAGE \
132 {\
133    [seL4_UserException_FaultIP] = FaultIP,\
134    [seL4_UserException_SP] = SP,\
135 }
136
137#define SYSCALL_MESSAGE \
138{\
139    [seL4_UnknownSyscall_FaultIP] = FaultIP,\
140    [seL4_UnknownSyscall_SP] = SP,\
141    [seL4_UnknownSyscall_RA] = LR,\
142    [seL4_UnknownSyscall_A0] = a0,\
143    [seL4_UnknownSyscall_A1] = a1,\
144    [seL4_UnknownSyscall_A2] = a2,\
145    [seL4_UnknownSyscall_A3] = a3,\
146    [seL4_UnknownSyscall_A4] = a4,\
147    [seL4_UnknownSyscall_A5] = a5,\
148    [seL4_UnknownSyscall_A6] = a6,\
149}
150
151#define TIMEOUT_REPLY_MESSAGE \
152{\
153    [seL4_TimeoutReply_FaultIP] = FaultIP,\
154    [seL4_TimeoutReply_LR] = LR, \
155    [seL4_TimeoutReply_SP] = SP, \
156    [seL4_TimeoutReply_GP] = GP, \
157    [seL4_TimeoutReply_s0] = s0, \
158    [seL4_TimeoutReply_s1] = s1, \
159    [seL4_TimeoutReply_s2] = s2, \
160    [seL4_TimeoutReply_s3] = s3, \
161    [seL4_TimeoutReply_s4] = s4, \
162    [seL4_TimeoutReply_s5] = s5, \
163    [seL4_TimeoutReply_s6] = s6, \
164    [seL4_TimeoutReply_s7] = s7, \
165    [seL4_TimeoutReply_s8] = s8, \
166    [seL4_TimeoutReply_s9] = s9, \
167    [seL4_TimeoutReply_s10] = s10, \
168    [seL4_TimeoutReply_s11] = s11, \
169    [seL4_TimeoutReply_a0] = a0, \
170    [seL4_TimeoutReply_a1] = a1, \
171    [seL4_TimeoutReply_a2] = a2, \
172    [seL4_TimeoutReply_a3] = a3, \
173    [seL4_TimeoutReply_a4] = a4, \
174    [seL4_TimeoutReply_a5] = a5, \
175    [seL4_TimeoutReply_a6] = a6, \
176    [seL4_TimeoutReply_a7] = a7, \
177    [seL4_TimeoutReply_t0] = t0, \
178    [seL4_TimeoutReply_t1] = t1, \
179    [seL4_TimeoutReply_t2] = t2, \
180    [seL4_TimeoutReply_t3] = t3, \
181    [seL4_TimeoutReply_t4] = t4, \
182    [seL4_TimeoutReply_t5] = t5, \
183    [seL4_TimeoutReply_t6] = t6, \
184    [seL4_TimeoutReply_TP] = TP, \
185}
186
187#endif /* __ASSEMBLER__ */
188
189