]> git.karo-electronics.de Git - mv-sheeva.git/blob - arch/microblaze/kernel/entry-nommu.S
Merge branch 'x86-fpu-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
[mv-sheeva.git] / arch / microblaze / kernel / entry-nommu.S
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 <asm/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         la      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, 3f
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_reshed
137         addk    r5, r1, r0
138         addk    r7, r0, r0
139         bralid  r15, do_signal
140         addk    r6, r0, r0
141
142 no_intr_reshed:
143         /* save mode indicator */
144         lwi     r11, r1, PT_MODE
145 3:
146         swi     r11, r0, PER_CPU(KM)
147
148         /* save r31 */
149         swi     r31, r0, PER_CPU(CURRENT_SAVE)
150 restore_context:
151         /* special purpose registers */
152         lwi     r11, r1, PT_FSR
153         mts     rfsr, r11
154         lwi     r11, r1, PT_ESR
155         mts     resr, r11
156         lwi     r11, r1, PT_EAR
157         mts     rear, r11
158         lwi     r11, r1, PT_MSR
159         mts     rmsr, r11
160
161         lwi     r31, r1, PT_R31
162         lwi     r30, r1, PT_R30
163         lwi     r29, r1, PT_R29
164         lwi     r28, r1, PT_R28
165         lwi     r27, r1, PT_R27
166         lwi     r26, r1, PT_R26
167         lwi     r25, r1, PT_R25
168         lwi     r24, r1, PT_R24
169         lwi     r23, r1, PT_R23
170         lwi     r22, r1, PT_R22
171         lwi     r21, r1, PT_R21
172         lwi     r20, r1, PT_R20
173         lwi     r19, r1, PT_R19
174         lwi     r18, r1, PT_R18
175         lwi     r17, r1, PT_R17
176         lwi     r16, r1, PT_R16
177         lwi     r15, r1, PT_R15
178         lwi     r14, r1, PT_PC
179         lwi     r13, r1, PT_R13
180         lwi     r12, r1, PT_R12
181         lwi     r11, r1, PT_R11
182         lwi     r10, r1, PT_R10
183         lwi     r9, r1, PT_R9
184         lwi     r8, r1, PT_R8
185         lwi     r7, r1, PT_R7
186         lwi     r6, r1, PT_R6
187         lwi     r5, r1, PT_R5
188         lwi     r4, r1, PT_R4
189         lwi     r3, r1, PT_R3
190         lwi     r2, r1, PT_R2
191         lwi     r1, r1, PT_R1
192         rtid    r14, 0
193         nop
194
195 ENTRY(_reset)
196         brai    0;
197
198 ENTRY(_user_exception)
199         swi     r1, r0, PER_CPU(ENTRY_SP)       /* save the current sp */
200         swi     r11, r0, PER_CPU(R11_SAVE)      /* temporarily save r11 */
201         lwi     r11, r0, PER_CPU(KM)            /* load mode indicator */
202         beqid   r11, 1f                         /* Already in kernel mode? */
203         nop
204         brid    2f                              /* jump over */
205         addik   r1, r1, (-PT_SIZE)      /* Room for pt_regs (delay slot) */
206 1:                                              /* Switch to kernel stack */
207         lwi     r1, r0, PER_CPU(CURRENT_SAVE)   /* get the saved current */
208         lwi     r1, r1, TS_THREAD_INFO          /* get the thread info */
209         /* calculate kernel stack pointer */
210         addik   r1, r1, THREAD_SIZE - PT_SIZE
211         swi     r11, r0, PER_CPU(R11_SAVE)      /* temporarily save r11 */
212         lwi     r11, r0, PER_CPU(KM)            /* load mode indicator */
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         la      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         andi    r11, r19, _TIF_NEED_RESCHED
480         beqi    r11, 1f
481         bralid  r15, schedule
482         nop
483 1:      andi    r11, r19, _TIF_SIGPENDING
484         beqi    r11, no_work_pending
485         addk    r5, r1, r0
486         addik   r7, r0, 1
487         bralid  r15, do_signal
488         addk    r6, r0, r0
489         bri     no_work_pending
490
491 ENTRY(ret_to_user)
492         disable_irq
493
494         swi     r4, r1, PT_R4           /* return val */
495         swi     r3, r1, PT_R3           /* return val */
496
497         lwi     r6, r31, TS_THREAD_INFO /* get thread info */
498         lwi     r19, r6, TI_FLAGS /* get flags in thread info */
499         bnei    r19, work_pending /* do an extra work if any bits are set */
500 no_work_pending:
501         disable_irq
502
503         /* save r31 */
504         swi     r31, r0, PER_CPU(CURRENT_SAVE)
505         /* save mode indicator */
506         lwi     r18, r1, PT_MODE
507         swi     r18, r0, PER_CPU(KM)
508 //restore_context:
509         /* special purpose registers */
510         lwi     r18, r1, PT_FSR
511         mts     rfsr, r18
512         lwi     r18, r1, PT_ESR
513         mts     resr, r18
514         lwi     r18, r1, PT_EAR
515         mts     rear, r18
516         lwi     r18, r1, PT_MSR
517         mts     rmsr, r18
518
519         lwi     r31, r1, PT_R31
520         lwi     r30, r1, PT_R30
521         lwi     r29, r1, PT_R29
522         lwi     r28, r1, PT_R28
523         lwi     r27, r1, PT_R27
524         lwi     r26, r1, PT_R26
525         lwi     r25, r1, PT_R25
526         lwi     r24, r1, PT_R24
527         lwi     r23, r1, PT_R23
528         lwi     r22, r1, PT_R22
529         lwi     r21, r1, PT_R21
530         lwi     r20, r1, PT_R20
531         lwi     r19, r1, PT_R19
532         lwi     r18, r1, PT_R18
533         lwi     r17, r1, PT_R17
534         lwi     r16, r1, PT_R16
535         lwi     r15, r1, PT_R15
536         lwi     r14, r1, PT_PC
537         lwi     r13, r1, PT_R13
538         lwi     r12, r1, PT_R12
539         lwi     r11, r1, PT_R11
540         lwi     r10, r1, PT_R10
541         lwi     r9, r1, PT_R9
542         lwi     r8, r1, PT_R8
543         lwi     r7, r1, PT_R7
544         lwi     r6, r1, PT_R6
545         lwi     r5, r1, PT_R5
546         lwi     r4, r1, PT_R4           /* return val */
547         lwi     r3, r1, PT_R3           /* return val */
548         lwi     r2, r1, PT_R2
549         lwi     r1, r1, PT_R1
550
551         rtid    r14, 0
552         nop
553
554 sys_vfork_wrapper:
555         brid    sys_vfork
556         addk    r5, r1, r0
557
558 sys_clone_wrapper:
559         brid    sys_clone
560         addk    r7, r1, r0
561
562 sys_execve_wrapper:
563         brid    sys_execve
564         addk    r8, r1, r0
565
566 sys_sigreturn_wrapper:
567         brid    sys_sigreturn
568         addk    r5, r1, r0
569
570 sys_rt_sigreturn_wrapper:
571         brid    sys_rt_sigreturn
572         addk    r5, r1, r0
573
574 sys_sigsuspend_wrapper:
575         brid    sys_rt_sigsuspend
576         addk    r6, r1, r0
577
578 sys_rt_sigsuspend_wrapper:
579         brid    sys_rt_sigsuspend
580         addk    r7, r1, r0
581
582         /* Interrupt vector table */
583         .section        .init.ivt, "ax"
584         .org 0x0
585         brai    _reset
586         brai    _user_exception
587         brai    _interrupt
588         brai    _break
589         brai    _hw_exception_handler
590         .org 0x60
591         brai    _debug_exception
592
593 .section .rodata,"a"
594 #include "syscall_table.S"
595
596 syscall_table_size=(.-sys_call_table)