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