~ubuntu-branches/ubuntu/precise/linux-lowlatency/precise

« back to all changes in this revision

Viewing changes to arch/microblaze/kernel/entry-nommu.S

  • Committer: Package Import Robot
  • Author(s): Alessio Igor Bogani
  • Date: 2011-10-26 11:13:05 UTC
  • Revision ID: package-import@ubuntu.com-20111026111305-tz023xykf0i6eosh
Tags: upstream-3.2.0
ImportĀ upstreamĀ versionĀ 3.2.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (C) 2007-2009 Michal Simek <monstr@monstr.eu>
 
3
 * Copyright (C) 2007-2009 PetaLogix
 
4
 * Copyright (C) 2006 Atmark Techno, Inc.
 
5
 *
 
6
 * This file is subject to the terms and conditions of the GNU General Public
 
7
 * License. See the file "COPYING" in the main directory of this archive
 
8
 * for more details.
 
9
 */
 
10
 
 
11
#include <linux/linkage.h>
 
12
#include <asm/thread_info.h>
 
13
#include <linux/errno.h>
 
14
#include <asm/entry.h>
 
15
#include <asm/asm-offsets.h>
 
16
#include <asm/registers.h>
 
17
#include <asm/unistd.h>
 
18
#include <asm/percpu.h>
 
19
#include <asm/signal.h>
 
20
 
 
21
#if CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR
 
22
        .macro  disable_irq
 
23
        msrclr r0, MSR_IE
 
24
        .endm
 
25
 
 
26
        .macro  enable_irq
 
27
        msrset r0, MSR_IE
 
28
        .endm
 
29
 
 
30
        .macro  clear_bip
 
31
        msrclr r0, MSR_BIP
 
32
        .endm
 
33
#else
 
34
        .macro  disable_irq
 
35
        mfs r11, rmsr
 
36
        andi r11, r11, ~MSR_IE
 
37
        mts rmsr, r11
 
38
        .endm
 
39
 
 
40
        .macro  enable_irq
 
41
        mfs r11, rmsr
 
42
        ori r11, r11, MSR_IE
 
43
        mts rmsr, r11
 
44
        .endm
 
45
 
 
46
        .macro  clear_bip
 
47
        mfs r11, rmsr
 
48
        andi r11, r11, ~MSR_BIP
 
49
        mts rmsr, r11
 
50
        .endm
 
51
#endif
 
52
 
 
53
ENTRY(_interrupt)
 
54
        swi     r1, r0, PER_CPU(ENTRY_SP)       /* save the current sp */
 
55
        swi     r11, r0, PER_CPU(R11_SAVE)      /* temporarily save r11 */
 
56
        lwi     r11, r0, PER_CPU(KM)            /* load mode indicator */
 
57
        beqid   r11, 1f
 
58
        nop
 
59
        brid    2f                              /* jump over */
 
60
        addik   r1, r1, (-PT_SIZE)      /* room for pt_regs (delay slot) */
 
61
1:                                              /* switch to kernel stack */
 
62
        lwi     r1, r0, PER_CPU(CURRENT_SAVE)   /* get the saved current */
 
63
        lwi     r1, r1, TS_THREAD_INFO          /* get the thread info */
 
64
        /* calculate kernel stack pointer */
 
65
        addik   r1, r1, THREAD_SIZE - PT_SIZE
 
66
2:
 
67
        swi     r11, r1, PT_MODE                /* store the mode */
 
68
        lwi     r11, r0, PER_CPU(R11_SAVE)      /* reload r11 */
 
69
        swi     r2, r1, PT_R2
 
70
        swi     r3, r1, PT_R3
 
71
        swi     r4, r1, PT_R4
 
72
        swi     r5, r1, PT_R5
 
73
        swi     r6, r1, PT_R6
 
74
        swi     r7, r1, PT_R7
 
75
        swi     r8, r1, PT_R8
 
76
        swi     r9, r1, PT_R9
 
77
        swi     r10, r1, PT_R10
 
78
        swi     r11, r1, PT_R11
 
79
        swi     r12, r1, PT_R12
 
80
        swi     r13, r1, PT_R13
 
81
        swi     r14, r1, PT_R14
 
82
        swi     r14, r1, PT_PC
 
83
        swi     r15, r1, PT_R15
 
84
        swi     r16, r1, PT_R16
 
85
        swi     r17, r1, PT_R17
 
86
        swi     r18, r1, PT_R18
 
87
        swi     r19, r1, PT_R19
 
88
        swi     r20, r1, PT_R20
 
89
        swi     r21, r1, PT_R21
 
90
        swi     r22, r1, PT_R22
 
91
        swi     r23, r1, PT_R23
 
92
        swi     r24, r1, PT_R24
 
93
        swi     r25, r1, PT_R25
 
94
        swi     r26, r1, PT_R26
 
95
        swi     r27, r1, PT_R27
 
96
        swi     r28, r1, PT_R28
 
97
        swi     r29, r1, PT_R29
 
98
        swi     r30, r1, PT_R30
 
99
        swi     r31, r1, PT_R31
 
100
        /* special purpose registers */
 
101
        mfs     r11, rmsr
 
102
        swi     r11, r1, PT_MSR
 
103
        mfs     r11, rear
 
104
        swi     r11, r1, PT_EAR
 
105
        mfs     r11, resr
 
106
        swi     r11, r1, PT_ESR
 
107
        mfs     r11, rfsr
 
108
        swi     r11, r1, PT_FSR
 
109
        /* reload original stack pointer and save it */
 
110
        lwi     r11, r0, PER_CPU(ENTRY_SP)
 
111
        swi     r11, r1, PT_R1
 
112
        /* update mode indicator we are in kernel mode */
 
113
        addik   r11, r0, 1
 
114
        swi     r11, r0, PER_CPU(KM)
 
115
        /* restore r31 */
 
116
        lwi     r31, r0, PER_CPU(CURRENT_SAVE)
 
117
        /* prepare the link register, the argument and jump */
 
118
        addik   r15, r0, ret_from_intr - 8
 
119
        addk    r6, r0, r15
 
120
        braid   do_IRQ
 
121
        add     r5, r0, r1
 
122
 
 
123
ret_from_intr:
 
124
        lwi     r11, r1, PT_MODE
 
125
        bneid   r11, no_intr_resched
 
126
 
 
127
        lwi     r6, r31, TS_THREAD_INFO /* get thread info */
 
128
        lwi     r19, r6, TI_FLAGS       /* get flags in thread info */
 
129
                                /* do an extra work if any bits are set */
 
130
 
 
131
        andi    r11, r19, _TIF_NEED_RESCHED
 
132
        beqi    r11, 1f
 
133
        bralid  r15, schedule
 
134
        nop
 
135
1:      andi    r11, r19, _TIF_SIGPENDING
 
136
        beqid   r11, no_intr_resched
 
137
        addk    r5, r1, r0
 
138
        addk    r7, r0, r0
 
139
        bralid  r15, do_signal
 
140
        addk    r6, r0, r0
 
141
 
 
142
no_intr_resched:
 
143
        /* Disable interrupts, we are now committed to the state restore */
 
144
        disable_irq
 
145
 
 
146
        /* save mode indicator */
 
147
        lwi     r11, r1, PT_MODE
 
148
        swi     r11, r0, PER_CPU(KM)
 
149
 
 
150
        /* save r31 */
 
151
        swi     r31, r0, PER_CPU(CURRENT_SAVE)
 
152
restore_context:
 
153
        /* special purpose registers */
 
154
        lwi     r11, r1, PT_FSR
 
155
        mts     rfsr, r11
 
156
        lwi     r11, r1, PT_ESR
 
157
        mts     resr, r11
 
158
        lwi     r11, r1, PT_EAR
 
159
        mts     rear, r11
 
160
        lwi     r11, r1, PT_MSR
 
161
        mts     rmsr, r11
 
162
 
 
163
        lwi     r31, r1, PT_R31
 
164
        lwi     r30, r1, PT_R30
 
165
        lwi     r29, r1, PT_R29
 
166
        lwi     r28, r1, PT_R28
 
167
        lwi     r27, r1, PT_R27
 
168
        lwi     r26, r1, PT_R26
 
169
        lwi     r25, r1, PT_R25
 
170
        lwi     r24, r1, PT_R24
 
171
        lwi     r23, r1, PT_R23
 
172
        lwi     r22, r1, PT_R22
 
173
        lwi     r21, r1, PT_R21
 
174
        lwi     r20, r1, PT_R20
 
175
        lwi     r19, r1, PT_R19
 
176
        lwi     r18, r1, PT_R18
 
177
        lwi     r17, r1, PT_R17
 
178
        lwi     r16, r1, PT_R16
 
179
        lwi     r15, r1, PT_R15
 
180
        lwi     r14, r1, PT_PC
 
181
        lwi     r13, r1, PT_R13
 
182
        lwi     r12, r1, PT_R12
 
183
        lwi     r11, r1, PT_R11
 
184
        lwi     r10, r1, PT_R10
 
185
        lwi     r9, r1, PT_R9
 
186
        lwi     r8, r1, PT_R8
 
187
        lwi     r7, r1, PT_R7
 
188
        lwi     r6, r1, PT_R6
 
189
        lwi     r5, r1, PT_R5
 
190
        lwi     r4, r1, PT_R4
 
191
        lwi     r3, r1, PT_R3
 
192
        lwi     r2, r1, PT_R2
 
193
        lwi     r1, r1, PT_R1
 
194
        rtid    r14, 0
 
195
        nop
 
196
 
 
197
ENTRY(_reset)
 
198
        brai    0;
 
199
 
 
200
ENTRY(_user_exception)
 
201
        swi     r1, r0, PER_CPU(ENTRY_SP)       /* save the current sp */
 
202
        swi     r11, r0, PER_CPU(R11_SAVE)      /* temporarily save r11 */
 
203
        lwi     r11, r0, PER_CPU(KM)            /* load mode indicator */
 
204
        beqid   r11, 1f                         /* Already in kernel mode? */
 
205
        nop
 
206
        brid    2f                              /* jump over */
 
207
        addik   r1, r1, (-PT_SIZE)      /* Room for pt_regs (delay slot) */
 
208
1:                                              /* Switch to kernel stack */
 
209
        lwi     r1, r0, PER_CPU(CURRENT_SAVE)   /* get the saved current */
 
210
        lwi     r1, r1, TS_THREAD_INFO          /* get the thread info */
 
211
        /* calculate kernel stack pointer */
 
212
        addik   r1, r1, THREAD_SIZE - PT_SIZE
 
213
2:
 
214
        swi     r11, r1, PT_MODE                /* store the mode */
 
215
        lwi     r11, r0, PER_CPU(R11_SAVE)      /* reload r11 */
 
216
        /* save them on stack */
 
217
        swi     r2, r1, PT_R2
 
218
        swi     r3, r1, PT_R3 /* r3: _always_ in clobber list; see unistd.h */
 
219
        swi     r4, r1, PT_R4 /* r4: _always_ in clobber list; see unistd.h */
 
220
        swi     r5, r1, PT_R5
 
221
        swi     r6, r1, PT_R6
 
222
        swi     r7, r1, PT_R7
 
223
        swi     r8, r1, PT_R8
 
224
        swi     r9, r1, PT_R9
 
225
        swi     r10, r1, PT_R10
 
226
        swi     r11, r1, PT_R11
 
227
        /* r12: _always_ in clobber list; see unistd.h */
 
228
        swi     r12, r1, PT_R12
 
229
        swi     r13, r1, PT_R13
 
230
        /* r14: _always_ in clobber list; see unistd.h */
 
231
        swi     r14, r1, PT_R14
 
232
        /* but we want to return to the next inst. */
 
233
        addik   r14, r14, 0x4
 
234
        swi     r14, r1, PT_PC          /* increment by 4 and store in pc */
 
235
        swi     r15, r1, PT_R15
 
236
        swi     r16, r1, PT_R16
 
237
        swi     r17, r1, PT_R17
 
238
        swi     r18, r1, PT_R18
 
239
        swi     r19, r1, PT_R19
 
240
        swi     r20, r1, PT_R20
 
241
        swi     r21, r1, PT_R21
 
242
        swi     r22, r1, PT_R22
 
243
        swi     r23, r1, PT_R23
 
244
        swi     r24, r1, PT_R24
 
245
        swi     r25, r1, PT_R25
 
246
        swi     r26, r1, PT_R26
 
247
        swi     r27, r1, PT_R27
 
248
        swi     r28, r1, PT_R28
 
249
        swi     r29, r1, PT_R29
 
250
        swi     r30, r1, PT_R30
 
251
        swi     r31, r1, PT_R31
 
252
 
 
253
        disable_irq
 
254
        nop             /* make sure IE bit is in effect */
 
255
        clear_bip       /* once IE is in effect it is safe to clear BIP */
 
256
        nop
 
257
 
 
258
        /* special purpose registers */
 
259
        mfs     r11, rmsr
 
260
        swi     r11, r1, PT_MSR
 
261
        mfs     r11, rear
 
262
        swi     r11, r1, PT_EAR
 
263
        mfs     r11, resr
 
264
        swi     r11, r1, PT_ESR
 
265
        mfs     r11, rfsr
 
266
        swi     r11, r1, PT_FSR
 
267
        /* reload original stack pointer and save it */
 
268
        lwi     r11, r0, PER_CPU(ENTRY_SP)
 
269
        swi     r11, r1, PT_R1
 
270
        /* update mode indicator we are in kernel mode */
 
271
        addik   r11, r0, 1
 
272
        swi     r11, r0, PER_CPU(KM)
 
273
        /* restore r31 */
 
274
        lwi     r31, r0, PER_CPU(CURRENT_SAVE)
 
275
        /* re-enable interrupts now we are in kernel mode */
 
276
        enable_irq
 
277
 
 
278
        /* See if the system call number is valid. */
 
279
        addi    r11, r12, -__NR_syscalls
 
280
        bgei    r11, 1f                 /* return to user if not valid */
 
281
        /* Figure out which function to use for this system call. */
 
282
        /* Note Microblaze barrel shift is optional, so don't rely on it */
 
283
        add     r12, r12, r12                   /* convert num -> ptr */
 
284
        add     r12, r12, r12
 
285
        lwi     r12, r12, sys_call_table        /* Get function pointer */
 
286
        addik   r15, r0, ret_to_user-8          /* set return address */
 
287
        bra     r12                             /* Make the system call. */
 
288
        bri     0                               /* won't reach here */
 
289
1:
 
290
        brid    ret_to_user                     /* jump to syscall epilogue */
 
291
        addi    r3, r0, -ENOSYS                 /* set errno in delay slot */
 
292
 
 
293
/*
 
294
 * Debug traps are like a system call, but entered via brki r14, 0x60
 
295
 * All we need to do is send the SIGTRAP signal to current, ptrace and do_signal
 
296
 * will handle the rest
 
297
 */
 
298
ENTRY(_debug_exception)
 
299
        swi     r1, r0, PER_CPU(ENTRY_SP)       /* save the current sp */
 
300
        lwi     r1, r0, PER_CPU(CURRENT_SAVE)   /* get the saved current */
 
301
        lwi     r1, r1, TS_THREAD_INFO          /* get the thread info */
 
302
        addik   r1, r1, THREAD_SIZE - PT_SIZE   /* get the kernel stack */
 
303
        swi     r11, r0, PER_CPU(R11_SAVE)      /* temporarily save r11 */
 
304
        lwi     r11, r0, PER_CPU(KM)            /* load mode indicator */
 
305
//save_context:
 
306
        swi     r11, r1, PT_MODE        /* store the mode */
 
307
        lwi     r11, r0, PER_CPU(R11_SAVE)      /* reload r11 */
 
308
        /* save them on stack */
 
309
        swi     r2, r1, PT_R2
 
310
        swi     r3, r1, PT_R3 /* r3: _always_ in clobber list; see unistd.h */
 
311
        swi     r4, r1, PT_R4 /* r4: _always_ in clobber list; see unistd.h */
 
312
        swi     r5, r1, PT_R5
 
313
        swi     r6, r1, PT_R6
 
314
        swi     r7, r1, PT_R7
 
315
        swi     r8, r1, PT_R8
 
316
        swi     r9, r1, PT_R9
 
317
        swi     r10, r1, PT_R10
 
318
        swi     r11, r1, PT_R11
 
319
        /* r12: _always_ in clobber list; see unistd.h */
 
320
        swi     r12, r1, PT_R12
 
321
        swi     r13, r1, PT_R13
 
322
        /* r14: _always_ in clobber list; see unistd.h */
 
323
        swi     r14, r1, PT_R14
 
324
        swi     r14, r1, PT_PC /* Will return to interrupted instruction */
 
325
        swi     r15, r1, PT_R15
 
326
        swi     r16, r1, PT_R16
 
327
        swi     r17, r1, PT_R17
 
328
        swi     r18, r1, PT_R18
 
329
        swi     r19, r1, PT_R19
 
330
        swi     r20, r1, PT_R20
 
331
        swi     r21, r1, PT_R21
 
332
        swi     r22, r1, PT_R22
 
333
        swi     r23, r1, PT_R23
 
334
        swi     r24, r1, PT_R24
 
335
        swi     r25, r1, PT_R25
 
336
        swi     r26, r1, PT_R26
 
337
        swi     r27, r1, PT_R27
 
338
        swi     r28, r1, PT_R28
 
339
        swi     r29, r1, PT_R29
 
340
        swi     r30, r1, PT_R30
 
341
        swi     r31, r1, PT_R31
 
342
 
 
343
        disable_irq
 
344
        nop             /* make sure IE bit is in effect */
 
345
        clear_bip       /* once IE is in effect it is safe to clear BIP */
 
346
        nop
 
347
 
 
348
        /* special purpose registers */
 
349
        mfs     r11, rmsr
 
350
        swi     r11, r1, PT_MSR
 
351
        mfs     r11, rear
 
352
        swi     r11, r1, PT_EAR
 
353
        mfs     r11, resr
 
354
        swi     r11, r1, PT_ESR
 
355
        mfs     r11, rfsr
 
356
        swi     r11, r1, PT_FSR
 
357
        /* reload original stack pointer and save it */
 
358
        lwi     r11, r0, PER_CPU(ENTRY_SP)
 
359
        swi     r11, r1, PT_R1
 
360
        /* update mode indicator we are in kernel mode */
 
361
        addik   r11, r0, 1
 
362
        swi     r11, r0, PER_CPU(KM)
 
363
        /* restore r31 */
 
364
        lwi     r31, r0, PER_CPU(CURRENT_SAVE)
 
365
        /* re-enable interrupts now we are in kernel mode */
 
366
        enable_irq
 
367
 
 
368
        addi    r5, r0, SIGTRAP                 /* sending the trap signal */
 
369
        add     r6, r0, r31                     /* to current */
 
370
        bralid  r15, send_sig
 
371
        add     r7, r0, r0                      /* 3rd param zero */
 
372
 
 
373
        /* Restore r3/r4 to work around how ret_to_user works */
 
374
        lwi     r3, r1, PT_R3
 
375
        lwi     r4, r1, PT_R4
 
376
        bri     ret_to_user
 
377
 
 
378
ENTRY(_break)
 
379
        bri     0
 
380
 
 
381
/* struct task_struct *_switch_to(struct thread_info *prev,
 
382
                                        struct thread_info *next); */
 
383
ENTRY(_switch_to)
 
384
        /* prepare return value */
 
385
        addk    r3, r0, r31
 
386
 
 
387
        /* save registers in cpu_context */
 
388
        /* use r11 and r12, volatile registers, as temp register */
 
389
        addik   r11, r5, TI_CPU_CONTEXT
 
390
        swi     r1, r11, CC_R1
 
391
        swi     r2, r11, CC_R2
 
392
        /* skip volatile registers.
 
393
         * they are saved on stack when we jumped to _switch_to() */
 
394
        /* dedicated registers */
 
395
        swi     r13, r11, CC_R13
 
396
        swi     r14, r11, CC_R14
 
397
        swi     r15, r11, CC_R15
 
398
        swi     r16, r11, CC_R16
 
399
        swi     r17, r11, CC_R17
 
400
        swi     r18, r11, CC_R18
 
401
        /* save non-volatile registers */
 
402
        swi     r19, r11, CC_R19
 
403
        swi     r20, r11, CC_R20
 
404
        swi     r21, r11, CC_R21
 
405
        swi     r22, r11, CC_R22
 
406
        swi     r23, r11, CC_R23
 
407
        swi     r24, r11, CC_R24
 
408
        swi     r25, r11, CC_R25
 
409
        swi     r26, r11, CC_R26
 
410
        swi     r27, r11, CC_R27
 
411
        swi     r28, r11, CC_R28
 
412
        swi     r29, r11, CC_R29
 
413
        swi     r30, r11, CC_R30
 
414
        /* special purpose registers */
 
415
        mfs     r12, rmsr
 
416
        swi     r12, r11, CC_MSR
 
417
        mfs     r12, rear
 
418
        swi     r12, r11, CC_EAR
 
419
        mfs     r12, resr
 
420
        swi     r12, r11, CC_ESR
 
421
        mfs     r12, rfsr
 
422
        swi     r12, r11, CC_FSR
 
423
 
 
424
        /* update r31, the current */
 
425
        lwi     r31, r6, TI_TASK
 
426
        swi     r31, r0, PER_CPU(CURRENT_SAVE)
 
427
 
 
428
        /* get new process' cpu context and restore */
 
429
        addik   r11, r6, TI_CPU_CONTEXT
 
430
 
 
431
        /* special purpose registers */
 
432
        lwi     r12, r11, CC_FSR
 
433
        mts     rfsr, r12
 
434
        lwi     r12, r11, CC_ESR
 
435
        mts     resr, r12
 
436
        lwi     r12, r11, CC_EAR
 
437
        mts     rear, r12
 
438
        lwi     r12, r11, CC_MSR
 
439
        mts     rmsr, r12
 
440
        /* non-volatile registers */
 
441
        lwi     r30, r11, CC_R30
 
442
        lwi     r29, r11, CC_R29
 
443
        lwi     r28, r11, CC_R28
 
444
        lwi     r27, r11, CC_R27
 
445
        lwi     r26, r11, CC_R26
 
446
        lwi     r25, r11, CC_R25
 
447
        lwi     r24, r11, CC_R24
 
448
        lwi     r23, r11, CC_R23
 
449
        lwi     r22, r11, CC_R22
 
450
        lwi     r21, r11, CC_R21
 
451
        lwi     r20, r11, CC_R20
 
452
        lwi     r19, r11, CC_R19
 
453
        /* dedicated registers */
 
454
        lwi     r18, r11, CC_R18
 
455
        lwi     r17, r11, CC_R17
 
456
        lwi     r16, r11, CC_R16
 
457
        lwi     r15, r11, CC_R15
 
458
        lwi     r14, r11, CC_R14
 
459
        lwi     r13, r11, CC_R13
 
460
        /* skip volatile registers */
 
461
        lwi     r2, r11, CC_R2
 
462
        lwi     r1, r11, CC_R1
 
463
 
 
464
        rtsd    r15, 8
 
465
        nop
 
466
 
 
467
ENTRY(ret_from_fork)
 
468
        addk    r5, r0, r3
 
469
        addk    r6, r0, r1
 
470
        brlid   r15, schedule_tail
 
471
        nop
 
472
        swi     r31, r1, PT_R31         /* save r31 in user context. */
 
473
                        /* will soon be restored to r31 in ret_to_user */
 
474
        addk    r3, r0, r0
 
475
        brid    ret_to_user
 
476
        nop
 
477
 
 
478
work_pending:
 
479
        enable_irq
 
480
 
 
481
        andi    r11, r19, _TIF_NEED_RESCHED
 
482
        beqi    r11, 1f
 
483
        bralid  r15, schedule
 
484
        nop
 
485
1:      andi    r11, r19, _TIF_SIGPENDING
 
486
        beqi    r11, no_work_pending
 
487
        addk    r5, r1, r0
 
488
        addik   r7, r0, 1
 
489
        bralid  r15, do_signal
 
490
        addk    r6, r0, r0
 
491
        bri     no_work_pending
 
492
 
 
493
ENTRY(ret_to_user)
 
494
        disable_irq
 
495
 
 
496
        swi     r4, r1, PT_R4           /* return val */
 
497
        swi     r3, r1, PT_R3           /* return val */
 
498
 
 
499
        lwi     r6, r31, TS_THREAD_INFO /* get thread info */
 
500
        lwi     r19, r6, TI_FLAGS /* get flags in thread info */
 
501
        bnei    r19, work_pending /* do an extra work if any bits are set */
 
502
no_work_pending:
 
503
        disable_irq
 
504
 
 
505
        /* save r31 */
 
506
        swi     r31, r0, PER_CPU(CURRENT_SAVE)
 
507
        /* save mode indicator */
 
508
        lwi     r18, r1, PT_MODE
 
509
        swi     r18, r0, PER_CPU(KM)
 
510
//restore_context:
 
511
        /* special purpose registers */
 
512
        lwi     r18, r1, PT_FSR
 
513
        mts     rfsr, r18
 
514
        lwi     r18, r1, PT_ESR
 
515
        mts     resr, r18
 
516
        lwi     r18, r1, PT_EAR
 
517
        mts     rear, r18
 
518
        lwi     r18, r1, PT_MSR
 
519
        mts     rmsr, r18
 
520
 
 
521
        lwi     r31, r1, PT_R31
 
522
        lwi     r30, r1, PT_R30
 
523
        lwi     r29, r1, PT_R29
 
524
        lwi     r28, r1, PT_R28
 
525
        lwi     r27, r1, PT_R27
 
526
        lwi     r26, r1, PT_R26
 
527
        lwi     r25, r1, PT_R25
 
528
        lwi     r24, r1, PT_R24
 
529
        lwi     r23, r1, PT_R23
 
530
        lwi     r22, r1, PT_R22
 
531
        lwi     r21, r1, PT_R21
 
532
        lwi     r20, r1, PT_R20
 
533
        lwi     r19, r1, PT_R19
 
534
        lwi     r18, r1, PT_R18
 
535
        lwi     r17, r1, PT_R17
 
536
        lwi     r16, r1, PT_R16
 
537
        lwi     r15, r1, PT_R15
 
538
        lwi     r14, r1, PT_PC
 
539
        lwi     r13, r1, PT_R13
 
540
        lwi     r12, r1, PT_R12
 
541
        lwi     r11, r1, PT_R11
 
542
        lwi     r10, r1, PT_R10
 
543
        lwi     r9, r1, PT_R9
 
544
        lwi     r8, r1, PT_R8
 
545
        lwi     r7, r1, PT_R7
 
546
        lwi     r6, r1, PT_R6
 
547
        lwi     r5, r1, PT_R5
 
548
        lwi     r4, r1, PT_R4           /* return val */
 
549
        lwi     r3, r1, PT_R3           /* return val */
 
550
        lwi     r2, r1, PT_R2
 
551
        lwi     r1, r1, PT_R1
 
552
 
 
553
        rtid    r14, 0
 
554
        nop
 
555
 
 
556
sys_vfork:
 
557
        brid    microblaze_vfork
 
558
        addk    r5, r1, r0
 
559
 
 
560
sys_clone:
 
561
        brid    microblaze_clone
 
562
        addk    r7, r1, r0
 
563
 
 
564
sys_execve:
 
565
        brid    microblaze_execve
 
566
        addk    r8, r1, r0
 
567
 
 
568
sys_rt_sigreturn_wrapper:
 
569
        brid    sys_rt_sigreturn
 
570
        addk    r5, r1, r0
 
571
 
 
572
sys_rt_sigsuspend_wrapper:
 
573
        brid    sys_rt_sigsuspend
 
574
        addk    r7, r1, r0
 
575
 
 
576
        /* Interrupt vector table */
 
577
        .section        .init.ivt, "ax"
 
578
        .org 0x0
 
579
        brai    _reset
 
580
        brai    _user_exception
 
581
        brai    _interrupt
 
582
        brai    _break
 
583
        brai    _hw_exception_handler
 
584
        .org 0x60
 
585
        brai    _debug_exception
 
586
 
 
587
.section .rodata,"a"
 
588
#include "syscall_table.S"
 
589
 
 
590
syscall_table_size=(.-sys_call_table)
 
591
 
 
592
type_SYSCALL:
 
593
        .ascii "SYSCALL\0"
 
594
type_IRQ:
 
595
        .ascii "IRQ\0"
 
596
type_IRQ_PREEMPT:
 
597
        .ascii "IRQ (PREEMPTED)\0"
 
598
type_SYSCALL_PREEMPT:
 
599
        .ascii " SYSCALL (PREEMPTED)\0"
 
600
 
 
601
        /*
 
602
         * Trap decoding for stack unwinder
 
603
         * Tuples are (start addr, end addr, string)
 
604
         * If return address lies on [start addr, end addr],
 
605
         * unwinder displays 'string'
 
606
         */
 
607
 
 
608
        .align 4
 
609
.global microblaze_trap_handlers
 
610
microblaze_trap_handlers:
 
611
        /* Exact matches come first */
 
612
        .word ret_to_user  ; .word ret_to_user    ; .word type_SYSCALL
 
613
        .word ret_from_intr; .word ret_from_intr  ; .word type_IRQ
 
614
        /* Fuzzy matches go here */
 
615
        .word ret_from_intr; .word no_intr_resched; .word type_IRQ_PREEMPT
 
616
        .word work_pending ; .word no_work_pending; .word type_SYSCALL_PREEMPT
 
617
        /* End of table */
 
618
        .word 0             ; .word 0               ; .word 0