Add linux-next specific files for 20110831
[linux-2.6/next.git] / arch / microblaze / kernel / entry-nommu.S
blob34b526f59b43782c68e4a66df2f163b2471b3c63
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  */
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>
21 #if CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR
22         .macro  disable_irq
23         msrclr r0, MSR_IE
24         .endm
26         .macro  enable_irq
27         msrset r0, MSR_IE
28         .endm
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
40         .macro  enable_irq
41         mfs r11, rmsr
42         ori r11, r11, MSR_IE
43         mts rmsr, r11
44         .endm
46         .macro  clear_bip
47         mfs r11, rmsr
48         andi r11, r11, ~MSR_BIP
49         mts rmsr, r11
50         .endm
51 #endif
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
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
123 ret_from_intr:
124         lwi     r11, r1, PT_MODE
125         bneid   r11, no_intr_resched
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 */
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
142 no_intr_resched:
143         /* Disable interrupts, we are now committed to the state restore */
144         disable_irq
146         /* save mode indicator */
147         lwi     r11, r1, PT_MODE
148         swi     r11, r0, PER_CPU(KM)
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
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
197 ENTRY(_reset)
198         brai    0;
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
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
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
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
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 */
290         brid    ret_to_user                     /* jump to syscall epilogue */
291         addi    r3, r0, -ENOSYS                 /* set errno in delay slot */
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
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
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
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 */
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
378 ENTRY(_break)
379         bri     0
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
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
424         /* update r31, the current */
425         lwi     r31, r6, TI_TASK
426         swi     r31, r0, PER_CPU(CURRENT_SAVE)
428         /* get new process' cpu context and restore */
429         addik   r11, r6, TI_CPU_CONTEXT
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
464         rtsd    r15, 8
465         nop
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
478 work_pending:
479         enable_irq
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
493 ENTRY(ret_to_user)
494         disable_irq
496         swi     r4, r1, PT_R4           /* return val */
497         swi     r3, r1, PT_R3           /* return val */
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
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
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
553         rtid    r14, 0
554         nop
556 sys_vfork:
557         brid    microblaze_vfork
558         addk    r5, r1, r0
560 sys_clone:
561         brid    microblaze_clone
562         addk    r7, r1, r0
564 sys_execve:
565         brid    microblaze_execve
566         addk    r8, r1, r0
568 sys_rt_sigreturn_wrapper:
569         brid    sys_rt_sigreturn
570         addk    r5, r1, r0
572 sys_rt_sigsuspend_wrapper:
573         brid    sys_rt_sigsuspend
574         addk    r7, r1, r0
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
587 .section .rodata,"a"
588 #include "syscall_table.S"
590 syscall_table_size=(.-sys_call_table)
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"
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          */
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