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#include <config.h>
9#include <machine/assembler.h>
10#include <arch/machine/hardware.h>
11#include <arch/api/syscall.h>
12#include <arch/machine/registerset.h>
13#include <util.h>
14
15#define REGBYTES (CONFIG_WORD_SIZE / 8)
16
17.section .text
18
19.global trap_entry
20.extern c_handle_syscall
21.extern c_handle_fastpath_reply_recv
22.extern c_handle_fastpath_call
23.extern c_handle_interrupt
24.extern c_handle_exception
25
26trap_entry:
27
28#ifdef ENABLE_SMP_SUPPORT
29/* The sscratch contains the stack for the current core */
30  csrrw sp, sscratch, sp
31/* Now we have a valid kernel stack */
32  STORE t0, (-2*REGBYTES)(sp)
33  LOAD  t0, (-1*REGBYTES)(sp)
34#else
35  csrrw t0, sscratch, t0
36#endif
37  STORE ra, (0*REGBYTES)(t0)
38#ifndef ENABLE_SMP_SUPPORT
39  STORE sp, (1*REGBYTES)(t0)
40#endif
41  STORE gp, (2*REGBYTES)(t0)
42  STORE tp, (3*REGBYTES)(t0)
43  STORE t1, (5*REGBYTES)(t0)
44  STORE t2, (6*REGBYTES)(t0)
45  STORE s0, (7*REGBYTES)(t0)
46  STORE s1, (8*REGBYTES)(t0)
47  STORE a0, (9*REGBYTES)(t0)
48  STORE a1, (10*REGBYTES)(t0)
49  STORE a2, (11*REGBYTES)(t0)
50  STORE a3, (12*REGBYTES)(t0)
51  STORE a4, (13*REGBYTES)(t0)
52  STORE a5, (14*REGBYTES)(t0)
53  STORE a6, (15*REGBYTES)(t0)
54  STORE a7, (16*REGBYTES)(t0)
55  STORE s2, (17*REGBYTES)(t0)
56  STORE s3, (18*REGBYTES)(t0)
57  STORE s4, (19*REGBYTES)(t0)
58  STORE s5, (20*REGBYTES)(t0)
59  STORE s6, (21*REGBYTES)(t0)
60  STORE s7, (22*REGBYTES)(t0)
61  STORE s8, (23*REGBYTES)(t0)
62  STORE s9, (24*REGBYTES)(t0)
63  STORE s10, (25*REGBYTES)(t0)
64  STORE s11, (26*REGBYTES)(t0)
65  STORE t3, (27*REGBYTES)(t0)
66  STORE t4, (28*REGBYTES)(t0)
67  STORE t5, (29*REGBYTES)(t0)
68  STORE t6, (30*REGBYTES)(t0)
69  /* save t0 value */
70#ifdef ENABLE_SMP_SUPPORT
71  LOAD  x1, (-2*REGBYTES)(sp)
72#else
73  csrr  x1, sscratch
74#endif
75  STORE    x1, (4*REGBYTES)(t0)
76
77  csrr x1, sstatus
78  STORE x1, (32*REGBYTES)(t0)
79
80  csrr s0, scause
81  STORE s0, (31*REGBYTES)(t0)
82
83  la gp, __global_pointer$
84
85#ifdef ENABLE_SMP_SUPPORT
86  /* save the user sp */
87  csrr  x1, sscratch
88  STORE x1, (1*REGBYTES)(t0)
89  /* restore the sscratch */
90  csrw  sscratch, sp
91#else
92  /* Load kernel's stack address */
93  la sp, (kernel_stack_alloc + BIT(CONFIG_KERNEL_STACK_BITS))
94#endif
95
96  /* Save exception PC */
97  csrr x1,  sepc
98  STORE   x1, (33*REGBYTES)(t0)
99
100  /* Check if it's an interrupt */
101  bltz s0, interrupt
102
103  /* ratified priv has value 8 for ecall from U-mode exception */
104  li   s4, 8
105  bne  s0, s4, exception
106
107handle_syscall:
108  /* Set the return address to sepc + 4 in the case of a system/environment call */
109  addi x1, x1, 4
110  /* Save NextIP */
111  STORE   x1, (34*REGBYTES)(t0)
112
113#ifdef CONFIG_FASTPATH
114  li t3, SYSCALL_CALL
115  beq a7, t3, c_handle_fastpath_call
116
117  li t3, SYSCALL_REPLY_RECV
118#ifdef CONFIG_KERNEL_MCS
119  /* move reply to 3rd argument */
120  mv a2, a6
121#endif
122  beq a7, t3, c_handle_fastpath_reply_recv
123#endif
124
125  /* move syscall number to 3rd argument */
126  mv a2, a7
127
128  j c_handle_syscall
129
130/* Not an interrupt or a syscall */
131exception:
132  /* Save NextIP */
133  STORE   x1, (34*REGBYTES)(t0)
134  j c_handle_exception
135
136interrupt:
137  /* Save NextIP */
138  STORE   x1, (34*REGBYTES)(t0)
139  j c_handle_interrupt
140