hc
2025-02-14 bbb9540dc49f70f6b703d1c8d1b85fa5f602d86e
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
/* SPDX-License-Identifier: GPL-2.0 */
// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
 
#include <linux/linkage.h>
#include <abi/entry.h>
#include <abi/pgtable-bits.h>
#include <asm/errno.h>
#include <asm/setup.h>
#include <asm/unistd.h>
#include <asm/asm-offsets.h>
#include <linux/threads.h>
#include <asm/setup.h>
#include <asm/page.h>
#include <asm/thread_info.h>
 
#define PTE_INDX_MSK    0xffc
#define PTE_INDX_SHIFT  10
#define _PGDIR_SHIFT    22
 
.macro    zero_fp
#ifdef CONFIG_STACKTRACE
   movi    r8, 0
#endif
.endm
 
.macro    context_tracking
#ifdef CONFIG_CONTEXT_TRACKING
   mfcr    a0, epsr
   btsti    a0, 31
   bt    1f
   jbsr    context_tracking_user_exit
   ldw    a0, (sp, LSAVE_A0)
   ldw    a1, (sp, LSAVE_A1)
   ldw    a2, (sp, LSAVE_A2)
   ldw    a3, (sp, LSAVE_A3)
#if defined(__CSKYABIV1__)
   ldw    r6, (sp, LSAVE_A4)
   ldw    r7, (sp, LSAVE_A5)
#endif
1:
#endif
.endm
 
.macro tlbop_begin name, val0, val1, val2
ENTRY(csky_\name)
   mtcr    a3, ss2
   mtcr    r6, ss3
   mtcr    a2, ss4
 
   RD_PGDR    r6
   RD_MEH    a3
#ifdef CONFIG_CPU_HAS_TLBI
   tlbi.vaas a3
   sync.is
 
   btsti    a3, 31
   bf    1f
   RD_PGDR_K r6
1:
#else
   bgeni    a2, 31
   WR_MCIR    a2
   bgeni    a2, 25
   WR_MCIR    a2
#endif
   bclri   r6, 0
   lrw    a2, va_pa_offset
   ld.w    a2, (a2, 0)
   subu    r6, a2
   bseti    r6, 31
 
   mov     a2, a3
   lsri    a2, _PGDIR_SHIFT
   lsli    a2, 2
   addu    r6, a2
   ldw     r6, (r6)
 
   lrw    a2, va_pa_offset
   ld.w    a2, (a2, 0)
   subu    r6, a2
   bseti    r6, 31
 
   lsri    a3, PTE_INDX_SHIFT
   lrw     a2, PTE_INDX_MSK
   and     a3, a2
   addu    r6, a3
   ldw     a3, (r6)
 
   movi    a2, (_PAGE_PRESENT | \val0)
   and     a3, a2
   cmpne   a3, a2
   bt    \name
 
   /* First read/write the page, just update the flags */
   ldw     a3, (r6)
   bgeni   a2, PAGE_VALID_BIT
   bseti   a2, PAGE_ACCESSED_BIT
   bseti   a2, \val1
   bseti   a2, \val2
   or      a3, a2
   stw     a3, (r6)
 
   /* Some cpu tlb-hardrefill bypass the cache */
#ifdef CONFIG_CPU_NEED_TLBSYNC
   movi    a2, 0x22
   bseti    a2, 6
   mtcr    r6, cr22
   mtcr    a2, cr17
   sync
#endif
 
   mfcr    a3, ss2
   mfcr    r6, ss3
   mfcr    a2, ss4
   rte
\name:
   mfcr    a3, ss2
   mfcr    r6, ss3
   mfcr    a2, ss4
   SAVE_ALL 0
.endm
.macro tlbop_end is_write
   zero_fp
   context_tracking
   RD_MEH    a2
   psrset  ee, ie
   mov     a0, sp
   movi    a1, \is_write
   jbsr    do_page_fault
   jmpi    ret_from_exception
.endm
 
.text
 
tlbop_begin tlbinvalidl, _PAGE_READ, PAGE_VALID_BIT, PAGE_ACCESSED_BIT
tlbop_end 0
 
tlbop_begin tlbinvalids, _PAGE_WRITE, PAGE_DIRTY_BIT, PAGE_MODIFIED_BIT
tlbop_end 1
 
tlbop_begin tlbmodified, _PAGE_WRITE, PAGE_DIRTY_BIT, PAGE_MODIFIED_BIT
#ifndef CONFIG_CPU_HAS_LDSTEX
jbsr csky_cmpxchg_fixup
#endif
tlbop_end 1
 
ENTRY(csky_systemcall)
   SAVE_ALL TRAP0_SIZE
   zero_fp
   context_tracking
   psrset  ee, ie
 
   lrw     r9, __NR_syscalls
   cmphs   syscallid, r9        /* Check nr of syscall */
   bt      1f
 
   lrw     r9, sys_call_table
   ixw     r9, syscallid
   ldw     syscallid, (r9)
   cmpnei  syscallid, 0
   bf      ret_from_exception
 
   mov     r9, sp
   bmaski  r10, THREAD_SHIFT
   andn    r9, r10
   ldw     r10, (r9, TINFO_FLAGS)
   lrw    r9, _TIF_SYSCALL_WORK
   and    r10, r9
   cmpnei    r10, 0
   bt      csky_syscall_trace
#if defined(__CSKYABIV2__)
   subi    sp, 8
   stw      r5, (sp, 0x4)
   stw      r4, (sp, 0x0)
   jsr     syscallid                      /* Do system call */
   addi     sp, 8
#else
   jsr     syscallid
#endif
   stw     a0, (sp, LSAVE_A0)      /* Save return value */
1:
#ifdef CONFIG_DEBUG_RSEQ
   mov    a0, sp
   jbsr    rseq_syscall
#endif
   jmpi    ret_from_exception
 
csky_syscall_trace:
   mov    a0, sp                  /* sp = pt_regs pointer */
   jbsr    syscall_trace_enter
   cmpnei    a0, 0
   bt    1f
   /* Prepare args before do system call */
   ldw    a0, (sp, LSAVE_A0)
   ldw    a1, (sp, LSAVE_A1)
   ldw    a2, (sp, LSAVE_A2)
   ldw    a3, (sp, LSAVE_A3)
#if defined(__CSKYABIV2__)
   subi    sp, 8
   ldw    r9, (sp, LSAVE_A4)
   stw    r9, (sp, 0x0)
   ldw    r9, (sp, LSAVE_A5)
   stw    r9, (sp, 0x4)
   jsr    syscallid                     /* Do system call */
   addi    sp, 8
#else
   ldw    r6, (sp, LSAVE_A4)
   ldw    r7, (sp, LSAVE_A5)
   jsr    syscallid                     /* Do system call */
#endif
   stw    a0, (sp, LSAVE_A0)    /* Save return value */
 
1:
#ifdef CONFIG_DEBUG_RSEQ
   mov    a0, sp
   jbsr    rseq_syscall
#endif
   mov     a0, sp                  /* right now, sp --> pt_regs */
   jbsr    syscall_trace_exit
   br    ret_from_exception
 
ENTRY(ret_from_kernel_thread)
   jbsr    schedule_tail
   mov    a0, r10
   jsr    r9
   jbsr    ret_from_exception
 
ENTRY(ret_from_fork)
   jbsr    schedule_tail
   mov    r9, sp
   bmaski    r10, THREAD_SHIFT
   andn    r9, r10
   ldw    r10, (r9, TINFO_FLAGS)
   lrw    r9, _TIF_SYSCALL_WORK
   and    r10, r9
   cmpnei    r10, 0
   bf    ret_from_exception
   mov    a0, sp            /* sp = pt_regs pointer */
   jbsr    syscall_trace_exit
 
ret_from_exception:
   psrclr    ie
   ld    r9, (sp, LSAVE_PSR)
   btsti    r9, 31
 
   bt    1f
   /*
    * Load address of current->thread_info, Then get address of task_struct
    * Get task_needreshed in task_struct
    */
   mov    r9, sp
   bmaski    r10, THREAD_SHIFT
   andn    r9, r10
 
   ldw    r10, (r9, TINFO_FLAGS)
   lrw    r9, _TIF_WORK_MASK
   and    r10, r9
   cmpnei    r10, 0
   bt    exit_work
#ifdef CONFIG_CONTEXT_TRACKING
   jbsr    context_tracking_user_enter
#endif
1:
#ifdef CONFIG_PREEMPTION
   mov    r9, sp
   bmaski    r10, THREAD_SHIFT
   andn    r9, r10
 
   ldw    r10, (r9, TINFO_PREEMPT)
   cmpnei    r10, 0
   bt    2f
   jbsr    preempt_schedule_irq    /* irq en/disable is done inside */
2:
#endif
 
#ifdef CONFIG_TRACE_IRQFLAGS
   ld    r10, (sp, LSAVE_PSR)
   btsti    r10, 6
   bf    2f
   jbsr    trace_hardirqs_on
2:
#endif
   RESTORE_ALL
 
exit_work:
   lrw    r9, ret_from_exception
   mov    lr, r9
 
   btsti    r10, TIF_NEED_RESCHED
   bt    work_resched
 
   psrset    ie
   mov    a0, sp
   mov    a1, r10
   jmpi    do_notify_resume
 
work_resched:
   jmpi    schedule
 
ENTRY(csky_trap)
   SAVE_ALL 0
   zero_fp
   context_tracking
   psrset    ee
   mov    a0, sp                 /* Push Stack pointer arg */
   jbsr    trap_c                 /* Call C-level trap handler */
   jmpi    ret_from_exception
 
/*
 * Prototype from libc for abiv1:
 * register unsigned int __result asm("a0");
 * asm( "trap 3" :"=r"(__result)::);
 */
ENTRY(csky_get_tls)
   USPTOKSP
 
   /* increase epc for continue */
   mfcr    a0, epc
   addi    a0, TRAP0_SIZE
   mtcr    a0, epc
 
   /* get current task thread_info with kernel 8K stack */
   bmaski    a0, THREAD_SHIFT
   not    a0
   subi    sp, 1
   and    a0, sp
   addi    sp, 1
 
   /* get tls */
   ldw    a0, (a0, TINFO_TP_VALUE)
 
   KSPTOUSP
   rte
 
ENTRY(csky_irq)
   SAVE_ALL 0
   zero_fp
   context_tracking
   psrset    ee
 
#ifdef CONFIG_TRACE_IRQFLAGS
   jbsr    trace_hardirqs_off
#endif
 
 
   mov    a0, sp
   jbsr    csky_do_IRQ
 
   jmpi    ret_from_exception
 
/*
 * a0 =  prev task_struct *
 * a1 =  next task_struct *
 * a0 =  return next
 */
ENTRY(__switch_to)
   lrw    a3, TASK_THREAD
   addu    a3, a0
 
   SAVE_SWITCH_STACK
 
   stw    sp, (a3, THREAD_KSP)
 
   /* Set up next process to run */
   lrw    a3, TASK_THREAD
   addu    a3, a1
 
   ldw    sp, (a3, THREAD_KSP)    /* Set next kernel sp */
 
#if  defined(__CSKYABIV2__)
   addi    a3, a1, TASK_THREAD_INFO
   ldw    tls, (a3, TINFO_TP_VALUE)
#endif
 
   RESTORE_SWITCH_STACK
 
   rts
ENDPROC(__switch_to)