2 * arch/sh/kernel/cpu/sh5/entry.S
4 * Copyright (C) 2000, 2001 Paolo Alberelli
5 * Copyright (C) 2004 - 2008 Paul Mundt
6 * Copyright (C) 2003, 2004 Richard Curnow
8 * This file is subject to the terms and conditions of the GNU General Public
9 * License. See the file "COPYING" in the main directory of this archive
12 #include <linux/errno.h>
13 #include <linux/init.h>
14 #include <linux/sys.h>
15 #include <cpu/registers.h>
16 #include <asm/processor.h>
17 #include <asm/unistd.h>
18 #include <asm/thread_info.h>
19 #include <asm/asm-offsets.h>
24 #define SR_ASID_MASK 0x00ff0000
25 #define SR_FD_MASK 0x00008000
26 #define SR_SS 0x08000000
27 #define SR_BL 0x10000000
28 #define SR_MD 0x40000000
33 #define EVENT_INTERRUPT 0
34 #define EVENT_FAULT_TLB 1
35 #define EVENT_FAULT_NOT_TLB 2
39 #define RESET_CAUSE 0x20
40 #define DEBUGSS_CAUSE 0x980
43 * Frame layout. Quad index.
45 #define FRAME_T(x) FRAME_TBASE+(x*8)
46 #define FRAME_R(x) FRAME_RBASE+(x*8)
47 #define FRAME_S(x) FRAME_SBASE+(x*8)
52 /* Arrange the save frame to be a multiple of 32 bytes long */
54 #define FRAME_RBASE (FRAME_SBASE+(3*8)) /* SYSCALL_ID - SSR - SPC */
55 #define FRAME_TBASE (FRAME_RBASE+(63*8)) /* r0 - r62 */
56 #define FRAME_PBASE (FRAME_TBASE+(8*8)) /* tr0 -tr7 */
57 #define FRAME_SIZE (FRAME_PBASE+(2*8)) /* pad0-pad1 */
59 #define FP_FRAME_SIZE FP_FRAME_BASE+(33*8) /* dr0 - dr31 + fpscr */
60 #define FP_FRAME_BASE 0
70 /* These are the registers saved in the TLB path that aren't saved in the first
71 level of the normal one. */
72 #define TLB_SAVED_R25 7*8
73 #define TLB_SAVED_TR1 8*8
74 #define TLB_SAVED_TR2 9*8
75 #define TLB_SAVED_TR3 10*8
76 #define TLB_SAVED_TR4 11*8
77 /* Save R0/R1 : PT-migrating compiler currently dishounours -ffixed-r0 and -ffixed-r1 causing
78 breakage otherwise. */
79 #define TLB_SAVED_R0 12*8
80 #define TLB_SAVED_R1 13*8
93 # define preempt_stop() CLI()
95 # define preempt_stop()
96 # define resume_kernel restore_all
101 #define FAST_TLBMISS_STACK_CACHELINES 4
102 #define FAST_TLBMISS_STACK_QUADWORDS (4*FAST_TLBMISS_STACK_CACHELINES)
104 /* Register back-up area for all exceptions */
106 /* Allow for 16 quadwords to be pushed by fast tlbmiss handling
107 * register saves etc. */
108 .fill FAST_TLBMISS_STACK_QUADWORDS, 8, 0x0
109 /* This is 32 byte aligned by construction */
110 /* Register back-up area for all exceptions */
130 /* Save area for RESVEC exceptions. We cannot use reg_save_area because of
131 * reentrancy. Note this area may be accessed via physical address.
132 * Align so this fits a whole single cache line, for ease of purging.
143 /* Jump table of 3rd level handlers */
145 .long do_exception_error /* 0x000 */
146 .long do_exception_error /* 0x020 */
148 .long tlb_miss_load /* 0x040 */
149 .long tlb_miss_store /* 0x060 */
151 .long do_exception_error
152 .long do_exception_error
154 ! ARTIFICIAL pseudo-EXPEVT setting
155 .long do_debug_interrupt /* 0x080 */
157 .long tlb_miss_load /* 0x0A0 */
158 .long tlb_miss_store /* 0x0C0 */
160 .long do_exception_error
161 .long do_exception_error
163 .long do_address_error_load /* 0x0E0 */
164 .long do_address_error_store /* 0x100 */
166 .long do_fpu_error /* 0x120 */
168 .long do_exception_error /* 0x120 */
170 .long do_exception_error /* 0x140 */
171 .long system_call /* 0x160 */
172 .long do_reserved_inst /* 0x180 */
173 .long do_illegal_slot_inst /* 0x1A0 */
174 .long do_exception_error /* 0x1C0 - NMI */
175 .long do_exception_error /* 0x1E0 */
177 .long do_IRQ /* 0x200 - 0x3C0 */
179 .long do_exception_error /* 0x3E0 */
181 .long do_IRQ /* 0x400 - 0x7E0 */
183 .long fpu_error_or_IRQA /* 0x800 */
184 .long fpu_error_or_IRQB /* 0x820 */
185 .long do_IRQ /* 0x840 */
186 .long do_IRQ /* 0x860 */
188 .long do_exception_error /* 0x880 - 0x920 */
190 .long breakpoint_trap_handler /* 0x940 */
191 .long do_exception_error /* 0x960 */
192 .long do_single_step /* 0x980 */
195 .long do_exception_error /* 0x9A0 - 0x9E0 */
197 .long do_IRQ /* 0xA00 */
198 .long do_IRQ /* 0xA20 */
200 .long itlb_miss_or_IRQ /* 0xA40 */
204 .long do_IRQ /* 0xA60 */
205 .long do_IRQ /* 0xA80 */
207 .long itlb_miss_or_IRQ /* 0xAA0 */
211 .long do_exception_error /* 0xAC0 */
212 .long do_address_error_exec /* 0xAE0 */
214 .long do_exception_error /* 0xB00 - 0xBE0 */
217 .long do_IRQ /* 0xC00 - 0xE20 */
220 .section .text64, "ax"
223 * --- Exception/Interrupt/Event Handling Section
227 * VBR and RESVEC blocks.
229 * First level handler for VBR-based exceptions.
231 * To avoid waste of space, align to the maximum text block size.
232 * This is assumed to be at most 128 bytes or 32 instructions.
233 * DO NOT EXCEED 32 instructions on the first level handlers !
235 * Also note that RESVEC is contained within the VBR block
236 * where the room left (1KB - TEXT_SIZE) allows placing
237 * the RESVEC block (at most 512B + TEXT_SIZE).
239 * So first (and only) level handler for RESVEC-based exceptions.
241 * Where the fault/interrupt is handled (not_a_tlb_miss, tlb_miss
242 * and interrupt) we are a lot tight with register space until
243 * saving onto the stack frame, which is done in handle_exception().
247 #define TEXT_SIZE 128
248 #define BLOCK_SIZE 1664 /* Dynamic check, 13*128 */
252 .space 256, 0 /* Power-on class handler, */
253 /* not required here */
255 synco /* TAKum03020 (but probably a good idea anyway.) */
256 /* Save original stack pointer into KCR1 */
259 /* Save other original registers into reg_save_area */
260 movi reg_save_area, SP
261 st.q SP, SAVED_R2, r2
262 st.q SP, SAVED_R3, r3
263 st.q SP, SAVED_R4, r4
264 st.q SP, SAVED_R5, r5
265 st.q SP, SAVED_R6, r6
266 st.q SP, SAVED_R18, r18
268 st.q SP, SAVED_TR0, r3
270 /* Set args for Non-debug, Not a TLB miss class handler */
272 movi ret_from_exception, r3
274 movi EVENT_FAULT_NOT_TLB, r4
277 pta handle_exception, tr0
288 * Instead of the natural .balign 1024 place RESVEC here
289 * respecting the final 1KB alignment.
293 * Instead of '.space 1024-TEXT_SIZE' place the RESVEC
294 * block making sure the final alignment is correct.
298 synco /* TAKum03020 (but probably a good idea anyway.) */
300 movi reg_save_area, SP
301 /* SP is guaranteed 32-byte aligned. */
302 st.q SP, TLB_SAVED_R0 , r0
303 st.q SP, TLB_SAVED_R1 , r1
304 st.q SP, SAVED_R2 , r2
305 st.q SP, SAVED_R3 , r3
306 st.q SP, SAVED_R4 , r4
307 st.q SP, SAVED_R5 , r5
308 st.q SP, SAVED_R6 , r6
309 st.q SP, SAVED_R18, r18
311 /* Save R25 for safety; as/ld may want to use it to achieve the call to
312 * the code in mm/tlbmiss.c */
313 st.q SP, TLB_SAVED_R25, r25
319 st.q SP, SAVED_TR0 , r2
320 st.q SP, TLB_SAVED_TR1 , r3
321 st.q SP, TLB_SAVED_TR2 , r4
322 st.q SP, TLB_SAVED_TR3 , r5
323 st.q SP, TLB_SAVED_TR4 , r18
325 pt do_fast_page_fault, tr0
330 andi r2, 1, r2 /* r2 = SSR.MD */
333 pt fixup_to_invoke_general_handler, tr1
335 /* If the fast path handler fixed the fault, just drop through quickly
336 to the restore code right away to return to the excepting context.
340 fast_tlb_miss_restore:
341 ld.q SP, SAVED_TR0, r2
342 ld.q SP, TLB_SAVED_TR1, r3
343 ld.q SP, TLB_SAVED_TR2, r4
345 ld.q SP, TLB_SAVED_TR3, r5
346 ld.q SP, TLB_SAVED_TR4, r18
354 ld.q SP, TLB_SAVED_R0, r0
355 ld.q SP, TLB_SAVED_R1, r1
356 ld.q SP, SAVED_R2, r2
357 ld.q SP, SAVED_R3, r3
358 ld.q SP, SAVED_R4, r4
359 ld.q SP, SAVED_R5, r5
360 ld.q SP, SAVED_R6, r6
361 ld.q SP, SAVED_R18, r18
362 ld.q SP, TLB_SAVED_R25, r25
366 nop /* for safety, in case the code is run on sh5-101 cut1.x */
368 fixup_to_invoke_general_handler:
370 /* OK, new method. Restore stuff that's not expected to get saved into
371 the 'first-level' reg save area, then just fall through to setting
372 up the registers and calling the second-level handler. */
374 /* 2nd level expects r2,3,4,5,6,18,tr0 to be saved. So we must restore
375 r25,tr1-4 and save r6 to get into the right state. */
377 ld.q SP, TLB_SAVED_TR1, r3
378 ld.q SP, TLB_SAVED_TR2, r4
379 ld.q SP, TLB_SAVED_TR3, r5
380 ld.q SP, TLB_SAVED_TR4, r18
381 ld.q SP, TLB_SAVED_R25, r25
383 ld.q SP, TLB_SAVED_R0, r0
384 ld.q SP, TLB_SAVED_R1, r1
391 /* Set args for Non-debug, TLB miss class handler */
393 movi ret_from_exception, r3
395 movi EVENT_FAULT_TLB, r4
398 pta handle_exception, tr0
400 #else /* CONFIG_MMU */
404 /* NB TAKE GREAT CARE HERE TO ENSURE THAT THE INTERRUPT CODE
405 DOES END UP AT VBR+0x600 */
417 synco /* TAKum03020 (but probably a good idea anyway.) */
418 /* Save original stack pointer into KCR1 */
421 /* Save other original registers into reg_save_area */
422 movi reg_save_area, SP
423 st.q SP, SAVED_R2, r2
424 st.q SP, SAVED_R3, r3
425 st.q SP, SAVED_R4, r4
426 st.q SP, SAVED_R5, r5
427 st.q SP, SAVED_R6, r6
428 st.q SP, SAVED_R18, r18
430 st.q SP, SAVED_TR0, r3
432 /* Set args for interrupt class handler */
434 movi ret_from_irq, r3
436 movi EVENT_INTERRUPT, r4
439 pta handle_exception, tr0
441 .balign TEXT_SIZE /* let's waste the bare minimum */
443 LVBR_block_end: /* Marker. Used for total checking */
447 /* Panic handler. Called with MMU off. Possible causes/actions:
448 * - Reset: Jump to program start.
449 * - Single Step: Turn off Single Step & return.
450 * - Others: Call panic handler, passing PC as arg.
451 * (this may need to be extended...)
454 synco /* TAKum03020 (but probably a good idea anyway.) */
456 /* First save r0-1 and tr0, as we need to use these */
457 movi resvec_save_area-CONFIG_PAGE_OFFSET, SP
466 sub r1, r0, r1 /* r1=0 if reset */
467 movi _stext-CONFIG_PAGE_OFFSET, r0
470 beqi r1, 0, tr0 /* Jump to start address if reset */
473 movi DEBUGSS_CAUSE, r1
474 sub r1, r0, r1 /* r1=0 if single step */
475 pta single_step_panic, tr0
476 beqi r1, 0, tr0 /* jump if single step */
478 /* Now jump to where we save the registers. */
479 movi panic_stash_regs-CONFIG_PAGE_OFFSET, r1
484 /* We are in a handler with Single Step set. We need to resume the
485 * handler, by turning on MMU & turning off Single Step. */
492 /* Restore EXPEVT, as the rte won't do this */
507 synco /* TAKum03020 (but probably a good idea anyway.) */
509 * Single step/software_break_point first level handler.
510 * Called with MMU off, so the first thing we do is enable it
511 * by doing an rte with appropriate SSR.
514 /* Save SSR & SPC, together with R0 & R1, as we need to use 2 regs. */
515 movi resvec_save_area-CONFIG_PAGE_OFFSET, SP
517 /* With the MMU off, we are bypassing the cache, so purge any
518 * data that will be made stale by the following stores.
530 /* Enable MMU, block exceptions, set priv mode, disable single step */
531 movi SR_MMU | SR_BL | SR_MD, r1
536 /* Force control to debug_exception_2 when rte is executed */
537 movi debug_exeception_2, r0
538 ori r0, 1, r0 /* force SHmedia, just in case */
544 /* Restore saved regs */
546 movi resvec_save_area, SP
554 /* Save other original registers into reg_save_area */
555 movi reg_save_area, SP
556 st.q SP, SAVED_R2, r2
557 st.q SP, SAVED_R3, r3
558 st.q SP, SAVED_R4, r4
559 st.q SP, SAVED_R5, r5
560 st.q SP, SAVED_R6, r6
561 st.q SP, SAVED_R18, r18
563 st.q SP, SAVED_TR0, r3
565 /* Set args for debug class handler */
567 movi ret_from_exception, r3
572 pta handle_exception, tr0
577 /* !!! WE COME HERE IN REAL MODE !!! */
578 /* Hook-up debug interrupt to allow various debugging options to be
579 * hooked into its handler. */
580 /* Save original stack pointer into KCR1 */
583 movi resvec_save_area-CONFIG_PAGE_OFFSET, SP
588 /* Save other original registers into reg_save_area thru real addresses */
589 st.q SP, SAVED_R2, r2
590 st.q SP, SAVED_R3, r3
591 st.q SP, SAVED_R4, r4
592 st.q SP, SAVED_R5, r5
593 st.q SP, SAVED_R6, r6
594 st.q SP, SAVED_R18, r18
596 st.q SP, SAVED_TR0, r3
598 /* move (spc,ssr)->(pspc,pssr). The rte will shift
599 them back again, so that they look like the originals
600 as far as the real handler code is concerned. */
606 ! construct useful SR for handle_exception
613 ! SSR is now the current SR with the MD and MMU bits set
614 ! i.e. the rte will switch back to priv mode and put
618 movi handle_exception, r18
619 ori r18, 1, r18 ! for safety (do we need this?)
622 /* Set args for Non-debug, Not a TLB miss class handler */
624 ! EXPEVT==0x80 is unused, so 'steal' this value to put the
625 ! debug interrupt handler in the vectoring table
627 movi ret_from_exception, r3
629 movi EVENT_FAULT_NOT_TLB, r4
632 movi CONFIG_PAGE_OFFSET, r6
637 rte ! -> handle_exception, switch back to priv mode again
639 LRESVEC_block_end: /* Marker. Unused. */
644 * Second level handler for VBR-based exceptions. Pre-handler.
645 * In common to all stack-frame sensitive handlers.
648 * (KCR0) Current [current task union]
651 * (r3) appropriate return address
652 * (r4) Event (0 = interrupt, 1 = TLB miss fault, 2 = Not TLB miss fault, 3=debug)
653 * (r5) Pointer to reg_save_area
656 * Available registers:
663 /* Common 2nd level handler. */
665 /* First thing we need an appropriate stack pointer */
670 bne r6, ZERO, tr0 /* Original stack pointer is fine */
672 /* Set stack pointer for user fault */
674 movi THREAD_SIZE, r6 /* Point to the end */
679 /* DEBUG : check for underflow/overflow of the kernel stack */
680 pta no_underflow, tr0
684 bge SP, r6, tr0 ! ? below 1k from bottom of stack : danger zone
686 /* Just panic to cause a crash. */
694 movi THREAD_SIZE, r18
696 bgt SP, r6, tr0 ! sp above the stack
698 /* Make some room for the BASIC frame. */
699 movi -(FRAME_SIZE), r6
702 /* Could do this with no stalling if we had another spare register, but the
703 code below will be OK. */
704 ld.q r5, SAVED_R2, r6
705 ld.q r5, SAVED_R3, r18
706 st.q SP, FRAME_R(2), r6
707 ld.q r5, SAVED_R4, r6
708 st.q SP, FRAME_R(3), r18
709 ld.q r5, SAVED_R5, r18
710 st.q SP, FRAME_R(4), r6
711 ld.q r5, SAVED_R6, r6
712 st.q SP, FRAME_R(5), r18
713 ld.q r5, SAVED_R18, r18
714 st.q SP, FRAME_R(6), r6
715 ld.q r5, SAVED_TR0, r6
716 st.q SP, FRAME_R(18), r18
717 st.q SP, FRAME_T(0), r6
719 /* Keep old SP around */
722 /* Save the rest of the general purpose registers */
723 st.q SP, FRAME_R(0), r0
724 st.q SP, FRAME_R(1), r1
725 st.q SP, FRAME_R(7), r7
726 st.q SP, FRAME_R(8), r8
727 st.q SP, FRAME_R(9), r9
728 st.q SP, FRAME_R(10), r10
729 st.q SP, FRAME_R(11), r11
730 st.q SP, FRAME_R(12), r12
731 st.q SP, FRAME_R(13), r13
732 st.q SP, FRAME_R(14), r14
734 /* SP is somewhere else */
735 st.q SP, FRAME_R(15), r6
737 st.q SP, FRAME_R(16), r16
738 st.q SP, FRAME_R(17), r17
739 /* r18 is saved earlier. */
740 st.q SP, FRAME_R(19), r19
741 st.q SP, FRAME_R(20), r20
742 st.q SP, FRAME_R(21), r21
743 st.q SP, FRAME_R(22), r22
744 st.q SP, FRAME_R(23), r23
745 st.q SP, FRAME_R(24), r24
746 st.q SP, FRAME_R(25), r25
747 st.q SP, FRAME_R(26), r26
748 st.q SP, FRAME_R(27), r27
749 st.q SP, FRAME_R(28), r28
750 st.q SP, FRAME_R(29), r29
751 st.q SP, FRAME_R(30), r30
752 st.q SP, FRAME_R(31), r31
753 st.q SP, FRAME_R(32), r32
754 st.q SP, FRAME_R(33), r33
755 st.q SP, FRAME_R(34), r34
756 st.q SP, FRAME_R(35), r35
757 st.q SP, FRAME_R(36), r36
758 st.q SP, FRAME_R(37), r37
759 st.q SP, FRAME_R(38), r38
760 st.q SP, FRAME_R(39), r39
761 st.q SP, FRAME_R(40), r40
762 st.q SP, FRAME_R(41), r41
763 st.q SP, FRAME_R(42), r42
764 st.q SP, FRAME_R(43), r43
765 st.q SP, FRAME_R(44), r44
766 st.q SP, FRAME_R(45), r45
767 st.q SP, FRAME_R(46), r46
768 st.q SP, FRAME_R(47), r47
769 st.q SP, FRAME_R(48), r48
770 st.q SP, FRAME_R(49), r49
771 st.q SP, FRAME_R(50), r50
772 st.q SP, FRAME_R(51), r51
773 st.q SP, FRAME_R(52), r52
774 st.q SP, FRAME_R(53), r53
775 st.q SP, FRAME_R(54), r54
776 st.q SP, FRAME_R(55), r55
777 st.q SP, FRAME_R(56), r56
778 st.q SP, FRAME_R(57), r57
779 st.q SP, FRAME_R(58), r58
780 st.q SP, FRAME_R(59), r59
781 st.q SP, FRAME_R(60), r60
782 st.q SP, FRAME_R(61), r61
783 st.q SP, FRAME_R(62), r62
786 * Save the S* registers.
789 st.q SP, FRAME_S(FSSR), r61
791 st.q SP, FRAME_S(FSPC), r62
792 movi -1, r62 /* Reset syscall_nr */
793 st.q SP, FRAME_S(FSYSCALL_ID), r62
795 /* Save the rest of the target registers */
797 st.q SP, FRAME_T(1), r6
799 st.q SP, FRAME_T(2), r6
801 st.q SP, FRAME_T(3), r6
803 st.q SP, FRAME_T(4), r6
805 st.q SP, FRAME_T(5), r6
807 st.q SP, FRAME_T(6), r6
809 st.q SP, FRAME_T(7), r6
811 ! setup FP so that unwinder can wind back through nested kernel mode
815 /* For syscall and debug race condition, get TRA now */
818 /* We are in a safe position to turn SR.BL off, but set IMASK=0xf
819 * Also set FD, to catch FPU usage in the kernel.
821 * benedict.gaster@superh.com 29/07/2002
823 * On all SH5-101 revisions it is unsafe to raise the IMASK and at the
824 * same time change BL from 1->0, as any pending interrupt of a level
825 * higher than he previous value of IMASK will leak through and be
826 * taken unexpectedly.
828 * To avoid this we raise the IMASK and then issue another PUTCON to
832 movi SR_IMASK | SR_FD, r7
835 movi SR_UNBLOCK_EXC, r7
840 /* Now call the appropriate 3rd level handler */
851 * Second level handler for VBR-based exceptions. Post-handlers.
853 * Post-handlers for interrupts (ret_from_irq), exceptions
854 * (ret_from_exception) and common reentrance doors (restore_all
855 * to get back to the original context, ret_from_syscall loop to
856 * check kernel exiting).
858 * ret_with_reschedule and work_notifysig are an inner lables of
859 * the ret_from_syscall loop.
861 * In common to all stack-frame sensitive handlers.
864 * (SP) struct pt_regs *, original register's frame pointer (basic)
869 ld.q SP, FRAME_S(FSSR), r6
872 pta resume_kernel, tr0
873 bne r6, ZERO, tr0 /* no further checks */
875 pta ret_with_reschedule, tr0
876 blink tr0, ZERO /* Do not check softirqs */
878 .global ret_from_exception
882 ld.q SP, FRAME_S(FSSR), r6
885 pta resume_kernel, tr0
886 bne r6, ZERO, tr0 /* no further checks */
890 #ifdef CONFIG_PREEMPT
891 pta ret_from_syscall, tr0
900 ld.l r6, TI_PRE_COUNT, r7
904 ld.l r6, TI_FLAGS, r7
905 movi (1 << TIF_NEED_RESCHED), r8
913 movi preempt_schedule_irq, r7
918 pta need_resched, tr1
922 .global ret_from_syscall
926 getcon KCR0, r6 ! r6 contains current_thread_info
927 ld.l r6, TI_FLAGS, r7 ! r7 contains current_thread_info->flags
929 movi _TIF_NEED_RESCHED, r8
931 pta work_resched, tr0
936 movi (_TIF_SIGPENDING|_TIF_NOTIFY_RESUME), r8
938 pta work_notifysig, tr0
944 pta ret_from_syscall, tr0
948 blink tr0, ZERO /* Call schedule(), return on top */
953 movi do_notify_resume, r6
957 blink tr0, LINK /* Call do_notify_resume(regs, current_thread_info->flags), return here */
962 ld.q SP, FRAME_T(0), r6
963 ld.q SP, FRAME_T(1), r7
964 ld.q SP, FRAME_T(2), r8
965 ld.q SP, FRAME_T(3), r9
970 ld.q SP, FRAME_T(4), r6
971 ld.q SP, FRAME_T(5), r7
972 ld.q SP, FRAME_T(6), r8
973 ld.q SP, FRAME_T(7), r9
979 ld.q SP, FRAME_R(0), r0
980 ld.q SP, FRAME_R(1), r1
981 ld.q SP, FRAME_R(2), r2
982 ld.q SP, FRAME_R(3), r3
983 ld.q SP, FRAME_R(4), r4
984 ld.q SP, FRAME_R(5), r5
985 ld.q SP, FRAME_R(6), r6
986 ld.q SP, FRAME_R(7), r7
987 ld.q SP, FRAME_R(8), r8
988 ld.q SP, FRAME_R(9), r9
989 ld.q SP, FRAME_R(10), r10
990 ld.q SP, FRAME_R(11), r11
991 ld.q SP, FRAME_R(12), r12
992 ld.q SP, FRAME_R(13), r13
993 ld.q SP, FRAME_R(14), r14
995 ld.q SP, FRAME_R(16), r16
996 ld.q SP, FRAME_R(17), r17
997 ld.q SP, FRAME_R(18), r18
998 ld.q SP, FRAME_R(19), r19
999 ld.q SP, FRAME_R(20), r20
1000 ld.q SP, FRAME_R(21), r21
1001 ld.q SP, FRAME_R(22), r22
1002 ld.q SP, FRAME_R(23), r23
1003 ld.q SP, FRAME_R(24), r24
1004 ld.q SP, FRAME_R(25), r25
1005 ld.q SP, FRAME_R(26), r26
1006 ld.q SP, FRAME_R(27), r27
1007 ld.q SP, FRAME_R(28), r28
1008 ld.q SP, FRAME_R(29), r29
1009 ld.q SP, FRAME_R(30), r30
1010 ld.q SP, FRAME_R(31), r31
1011 ld.q SP, FRAME_R(32), r32
1012 ld.q SP, FRAME_R(33), r33
1013 ld.q SP, FRAME_R(34), r34
1014 ld.q SP, FRAME_R(35), r35
1015 ld.q SP, FRAME_R(36), r36
1016 ld.q SP, FRAME_R(37), r37
1017 ld.q SP, FRAME_R(38), r38
1018 ld.q SP, FRAME_R(39), r39
1019 ld.q SP, FRAME_R(40), r40
1020 ld.q SP, FRAME_R(41), r41
1021 ld.q SP, FRAME_R(42), r42
1022 ld.q SP, FRAME_R(43), r43
1023 ld.q SP, FRAME_R(44), r44
1024 ld.q SP, FRAME_R(45), r45
1025 ld.q SP, FRAME_R(46), r46
1026 ld.q SP, FRAME_R(47), r47
1027 ld.q SP, FRAME_R(48), r48
1028 ld.q SP, FRAME_R(49), r49
1029 ld.q SP, FRAME_R(50), r50
1030 ld.q SP, FRAME_R(51), r51
1031 ld.q SP, FRAME_R(52), r52
1032 ld.q SP, FRAME_R(53), r53
1033 ld.q SP, FRAME_R(54), r54
1034 ld.q SP, FRAME_R(55), r55
1035 ld.q SP, FRAME_R(56), r56
1036 ld.q SP, FRAME_R(57), r57
1037 ld.q SP, FRAME_R(58), r58
1040 movi SR_BLOCK_EXC, r60
1042 putcon r59, SR /* SR.BL = 1, keep nesting out */
1043 ld.q SP, FRAME_S(FSSR), r61
1044 ld.q SP, FRAME_S(FSPC), r62
1045 movi SR_ASID_MASK, r60
1047 andc r61, r60, r61 /* Clear out older ASID */
1048 or r59, r61, r61 /* Retain current ASID */
1052 /* Ignore FSYSCALL_ID */
1054 ld.q SP, FRAME_R(59), r59
1055 ld.q SP, FRAME_R(60), r60
1056 ld.q SP, FRAME_R(61), r61
1057 ld.q SP, FRAME_R(62), r62
1060 ld.q SP, FRAME_R(15), SP
1065 * Third level handlers for VBR-based exceptions. Adapting args to
1066 * and/or deflecting to fourth level handlers.
1068 * Fourth level handlers interface.
1069 * Most are C-coded handlers directly pointed by the trap_jtable.
1070 * (Third = Fourth level)
1072 * (r2) fault/interrupt code, entry number (e.g. NMI = 14,
1073 * IRL0-3 (0000) = 16, RTLBMISS = 2, SYSCALL = 11, etc ...)
1074 * (r3) struct pt_regs *, original register's frame pointer
1075 * (r4) Event (0 = interrupt, 1 = TLB miss fault, 2 = Not TLB miss fault)
1076 * (r5) TRA control register (for syscall/debug benefit only)
1077 * (LINK) return address
1080 * Kernel TLB fault handlers will get a slightly different interface.
1081 * (r2) struct pt_regs *, original register's frame pointer
1082 * (r3) page fault error code (see asm/thread_info.h)
1083 * (r4) Effective Address of fault
1084 * (LINK) return address
1087 * fpu_error_or_IRQ? is a helper to deflect to the right cause.
1093 or ZERO, ZERO, r3 /* Read */
1095 pta call_do_page_fault, tr0
1100 movi FAULT_CODE_WRITE, r3 /* Write */
1102 pta call_do_page_fault, tr0
1107 beqi/u r4, EVENT_INTERRUPT, tr0
1111 movi FAULT_CODE_ITLB, r3
1116 movi do_page_fault, r6
1119 #endif /* CONFIG_MMU */
1123 beqi/l r4, EVENT_INTERRUPT, tr0
1124 #ifdef CONFIG_SH_FPU
1125 movi fpu_state_restore_trap_handler, r6
1127 movi do_exception_error, r6
1134 beqi/l r4, EVENT_INTERRUPT, tr0
1135 #ifdef CONFIG_SH_FPU
1136 movi fpu_state_restore_trap_handler, r6
1138 movi do_exception_error, r6
1149 * system_call/unknown_trap third level handler:
1152 * (r2) fault/interrupt code, entry number (TRAP = 11)
1153 * (r3) struct pt_regs *, original register's frame pointer
1154 * (r4) Not used. Event (0=interrupt, 1=TLB miss fault, 2=Not TLB miss fault)
1155 * (r5) TRA Control Reg (0x00xyzzzz: x=1 SYSCALL, y = #args, z=nr)
1157 * (LINK) return address: ret_from_exception
1158 * (*r3) Syscall parms: SC#, arg0, arg1, ..., arg5 in order (Saved r2/r7)
1161 * (*r3) Syscall reply (Saved r2)
1162 * (LINK) In case of syscall only it can be scrapped.
1163 * Common second level post handler will be ret_from_syscall.
1164 * Common (non-trace) exit point to that is syscall_ret (saving
1165 * result to r2). Common bad exit point is syscall_bad (returning
1166 * ENOSYS then saved to r2).
1171 /* Unknown Trap or User Trace */
1172 movi do_unknown_trapa, r6
1174 ld.q r3, FRAME_R(9), r2 /* r2 = #arg << 16 | syscall # */
1175 andi r2, 0x1ff, r2 /* r2 = syscall # */
1178 pta syscall_ret, tr0
1181 /* New syscall implementation*/
1183 pta unknown_trap, tr0
1184 or r5, ZERO, r4 /* TRA (=r5) -> r4 */
1186 bnei r4, 1, tr0 /* unknown_trap if not 0x1yzzzz */
1188 /* It's a system call */
1189 st.q r3, FRAME_S(FSYSCALL_ID), r5 /* ID (0x1yzzzz) -> stack */
1190 andi r5, 0x1ff, r5 /* syscall # -> r5 */
1194 pta syscall_allowed, tr0
1195 movi NR_syscalls - 1, r4 /* Last valid */
1199 /* Return ENOSYS ! */
1200 movi -(ENOSYS), r2 /* Fall-through */
1204 st.q SP, FRAME_R(9), r2 /* Expecting SP back to BASIC frame */
1205 ld.q SP, FRAME_S(FSPC), r2
1206 addi r2, 4, r2 /* Move PC, being pre-execution event */
1207 st.q SP, FRAME_S(FSPC), r2
1208 pta ret_from_syscall, tr0
1212 /* A different return path for ret_from_fork, because we now need
1213 * to call schedule_tail with the later kernels. Because prev is
1214 * loaded into r2 by switch_to() means we can just call it straight away
1217 .global ret_from_fork
1220 movi schedule_tail,r5
1225 ld.q SP, FRAME_S(FSPC), r2
1226 addi r2, 4, r2 /* Move PC, being pre-execution event */
1227 st.q SP, FRAME_S(FSPC), r2
1228 pta ret_from_syscall, tr0
1231 .global ret_from_kernel_thread
1232 ret_from_kernel_thread:
1234 movi schedule_tail,r5
1239 ld.q SP, FRAME_R(2), r2
1240 ld.q SP, FRAME_R(3), r3
1244 ld.q SP, FRAME_S(FSPC), r2
1245 addi r2, 4, r2 /* Move PC, being pre-execution event */
1246 st.q SP, FRAME_S(FSPC), r2
1247 pta ret_from_syscall, tr0
1251 /* Use LINK to deflect the exit point, default is syscall_ret */
1252 pta syscall_ret, tr0
1254 pta syscall_notrace, tr0
1257 ld.l r2, TI_FLAGS, r4
1258 movi _TIF_WORK_SYSCALL_MASK, r6
1262 /* Trace it by calling syscall_trace before and after */
1263 movi do_syscall_trace_enter, r4
1268 /* Save the retval */
1269 st.q SP, FRAME_R(2), r2
1271 /* Reload syscall number as r5 is trashed by do_syscall_trace_enter */
1272 ld.q SP, FRAME_S(FSYSCALL_ID), r5
1275 pta syscall_ret_trace, tr0
1279 /* Now point to the appropriate 4th level syscall handler */
1280 movi sys_call_table, r4
1285 /* Prepare original args */
1286 ld.q SP, FRAME_R(2), r2
1287 ld.q SP, FRAME_R(3), r3
1288 ld.q SP, FRAME_R(4), r4
1289 ld.q SP, FRAME_R(5), r5
1290 ld.q SP, FRAME_R(6), r6
1291 ld.q SP, FRAME_R(7), r7
1293 /* And now the trick for those syscalls requiring regs * ! */
1297 blink tr0, ZERO /* LINK is already properly set */
1300 /* We get back here only if under trace */
1301 st.q SP, FRAME_R(9), r2 /* Save return value */
1303 movi do_syscall_trace_leave, LINK
1308 /* This needs to be done after any syscall tracing */
1309 ld.q SP, FRAME_S(FSPC), r2
1310 addi r2, 4, r2 /* Move PC, being pre-execution event */
1311 st.q SP, FRAME_S(FSPC), r2
1313 pta ret_from_syscall, tr0
1314 blink tr0, ZERO /* Resume normal return sequence */
1317 * --- Switch to running under a particular ASID and return the previous ASID value
1318 * --- The caller is assumed to have done a cli before calling this.
1320 * Input r2 : new ASID
1321 * Output r2 : old ASID
1324 .global switch_and_save_asid
1325 switch_and_save_asid:
1328 shlli r4, 16, r4 /* r4 = mask to select ASID */
1329 and r0, r4, r3 /* r3 = shifted old ASID */
1330 andi r2, 255, r2 /* mask down new ASID */
1331 shlli r2, 16, r2 /* align new ASID against SR.ASID */
1332 andc r0, r4, r0 /* efface old ASID from SR */
1333 or r0, r2, r0 /* insert the new ASID */
1341 shlri r3, 16, r2 /* r2 = old ASID */
1344 .global route_to_panic_handler
1345 route_to_panic_handler:
1346 /* Switch to real mode, goto panic_handler, don't return. Useful for
1347 last-chance debugging, e.g. if no output wants to go to the console.
1350 movi panic_handler - CONFIG_PAGE_OFFSET, r1
1362 1: /* Now in real mode */
1366 .global peek_real_address_q
1367 peek_real_address_q:
1369 r2 : real mode address to peek
1370 r2(out) : result quadword
1372 This is provided as a cheapskate way of manipulating device
1373 registers for debugging (to avoid the need to ioremap the debug
1374 module, and to avoid the need to ioremap the watchpoint
1375 controller in a way that identity maps sufficient bits to avoid the
1376 SH5-101 cut2 silicon defect).
1378 This code is not performance critical
1381 add.l r2, r63, r2 /* sign extend address */
1382 getcon sr, r0 /* r0 = saved original SR */
1385 or r0, r1, r1 /* r0 with block bit set */
1386 putcon r1, sr /* now in critical section */
1389 andc r1, r36, r1 /* turn sr.mmu off in real mode section */
1392 movi .peek0 - CONFIG_PAGE_OFFSET, r36 /* real mode target address */
1393 movi 1f, r37 /* virtual mode return addr */
1400 .peek0: /* come here in real mode, don't touch caches!!
1401 still in critical section (sr.bl==1) */
1404 /* Here's the actual peek. If the address is bad, all bets are now off
1405 * what will happen (handlers invoked in real-mode = bad news) */
1408 rte /* Back to virtual mode */
1415 .global poke_real_address_q
1416 poke_real_address_q:
1418 r2 : real mode address to poke
1419 r3 : quadword value to write.
1421 This is provided as a cheapskate way of manipulating device
1422 registers for debugging (to avoid the need to ioremap the debug
1423 module, and to avoid the need to ioremap the watchpoint
1424 controller in a way that identity maps sufficient bits to avoid the
1425 SH5-101 cut2 silicon defect).
1427 This code is not performance critical
1430 add.l r2, r63, r2 /* sign extend address */
1431 getcon sr, r0 /* r0 = saved original SR */
1434 or r0, r1, r1 /* r0 with block bit set */
1435 putcon r1, sr /* now in critical section */
1438 andc r1, r36, r1 /* turn sr.mmu off in real mode section */
1441 movi .poke0-CONFIG_PAGE_OFFSET, r36 /* real mode target address */
1442 movi 1f, r37 /* virtual mode return addr */
1449 .poke0: /* come here in real mode, don't touch caches!!
1450 still in critical section (sr.bl==1) */
1453 /* Here's the actual poke. If the address is bad, all bets are now off
1454 * what will happen (handlers invoked in real-mode = bad news) */
1457 rte /* Back to virtual mode */
1466 * --- User Access Handling Section
1470 * User Access support. It all moved to non inlined Assembler
1471 * functions in here.
1473 * __kernel_size_t __copy_user(void *__to, const void *__from,
1474 * __kernel_size_t __n)
1477 * (r2) target address
1478 * (r3) source address
1479 * (r4) size in bytes
1483 * (r2) non-copied bytes
1485 * If a fault occurs on the user pointer, bail out early and return the
1486 * number of bytes not copied in r2.
1487 * Strategy : for large blocks, call a real memcpy function which can
1488 * move >1 byte at a time using unaligned ld/st instructions, and can
1489 * manipulate the cache using prefetch + alloco to improve the speed
1490 * further. If a fault occurs in that function, just revert to the
1491 * byte-by-byte approach used for small blocks; this is rare so the
1492 * performance hit for that case does not matter.
1494 * For small blocks it's not worth the overhead of setting up and calling
1495 * the memcpy routine; do the copy a byte at a time.
1500 pta __copy_user_byte_by_byte, tr1
1501 movi 16, r0 ! this value is a best guess, should tune it by benchmarking
1503 pta copy_user_memcpy, tr0
1505 /* Save arguments in case we have to fix-up unhandled page fault */
1509 st.q SP, 24, r35 ! r35 is callee-save
1510 /* Save LINK in a register to reduce RTS time later (otherwise
1511 ld SP,*,LINK;ptabs LINK;trn;blink trn,r63 becomes a critical path) */
1515 /* Copy completed normally if we get back here */
1518 /* don't restore r2-r4, pointless */
1519 /* set result=r2 to zero as the copy must have succeeded. */
1522 blink tr0, r63 ! RTS
1524 .global __copy_user_fixup
1526 /* Restore stack frame */
1533 /* Fall through to original code, in the 'same' state we entered with */
1535 /* The slow byte-by-byte method is used if the fast copy traps due to a bad
1536 user address. In that rare case, the speed drop can be tolerated. */
1537 __copy_user_byte_by_byte:
1538 pta ___copy_user_exit, tr1
1539 pta ___copy_user1, tr0
1540 beq/u r4, r63, tr1 /* early exit for zero length copy */
1545 ld.b r3, 0, r5 /* Fault address 1 */
1547 /* Could rewrite this to use just 1 add, but the second comes 'free'
1548 due to load latency */
1550 addi r4, -1, r4 /* No real fixup required */
1552 stx.b r3, r0, r5 /* Fault address 2 */
1561 * __kernel_size_t __clear_user(void *addr, __kernel_size_t size)
1564 * (r2) target address
1565 * (r3) size in bytes
1568 * (*r2) zero-ed target data
1569 * (r2) non-zero-ed bytes
1571 .global __clear_user
1573 pta ___clear_user_exit, tr1
1574 pta ___clear_user1, tr0
1578 st.b r2, 0, ZERO /* Fault address */
1580 addi r3, -1, r3 /* No real fixup required */
1588 #endif /* CONFIG_MMU */
1591 * extern long __get_user_asm_?(void *val, long addr)
1595 * (r3) source address (in User Space)
1598 * (r2) -EFAULT (faulting)
1601 .global __get_user_asm_b
1604 movi -(EFAULT), r2 /* r2 = reply, no real fixup */
1607 ld.b r3, 0, r5 /* r5 = data */
1611 ___get_user_asm_b_exit:
1616 .global __get_user_asm_w
1619 movi -(EFAULT), r2 /* r2 = reply, no real fixup */
1622 ld.w r3, 0, r5 /* r5 = data */
1626 ___get_user_asm_w_exit:
1631 .global __get_user_asm_l
1634 movi -(EFAULT), r2 /* r2 = reply, no real fixup */
1637 ld.l r3, 0, r5 /* r5 = data */
1641 ___get_user_asm_l_exit:
1646 .global __get_user_asm_q
1649 movi -(EFAULT), r2 /* r2 = reply, no real fixup */
1652 ld.q r3, 0, r5 /* r5 = data */
1656 ___get_user_asm_q_exit:
1661 * extern long __put_user_asm_?(void *pval, long addr)
1664 * (r2) kernel pointer to value
1665 * (r3) dest address (in User Space)
1668 * (r2) -EFAULT (faulting)
1671 .global __put_user_asm_b
1673 ld.b r2, 0, r4 /* r4 = data */
1674 movi -(EFAULT), r2 /* r2 = reply, no real fixup */
1680 ___put_user_asm_b_exit:
1685 .global __put_user_asm_w
1687 ld.w r2, 0, r4 /* r4 = data */
1688 movi -(EFAULT), r2 /* r2 = reply, no real fixup */
1694 ___put_user_asm_w_exit:
1699 .global __put_user_asm_l
1701 ld.l r2, 0, r4 /* r4 = data */
1702 movi -(EFAULT), r2 /* r2 = reply, no real fixup */
1708 ___put_user_asm_l_exit:
1713 .global __put_user_asm_q
1715 ld.q r2, 0, r4 /* r4 = data */
1716 movi -(EFAULT), r2 /* r2 = reply, no real fixup */
1722 ___put_user_asm_q_exit:
1727 /* The idea is : when we get an unhandled panic, we dump the registers
1728 to a known memory location, the just sit in a tight loop.
1729 This allows the human to look at the memory region through the GDB
1730 session (assuming the debug module's SHwy initiator isn't locked up
1731 or anything), to hopefully analyze the cause of the panic. */
1733 /* On entry, former r15 (SP) is in DCR
1734 former r0 is at resvec_saved_area + 0
1735 former r1 is at resvec_saved_area + 8
1736 former tr0 is at resvec_saved_area + 32
1737 DCR is the only register whose value is lost altogether.
1740 movi 0xffffffff80000000, r0 ! phy of dump area
1741 ld.q SP, 0x000, r1 ! former r0
1743 ld.q SP, 0x008, r1 ! former r1
1807 st.q r0, 0x1f8, r63 ! bogus, but for consistency's sake...
1809 ld.q SP, 0x020, r1 ! former tr0
1859 /* Prepare to jump to C - physical address */
1860 movi panic_handler-CONFIG_PAGE_OFFSET, r1
1874 * --- Signal Handling Section
1878 * extern long long _sa_default_rt_restorer
1879 * extern long long _sa_default_restorer
1883 * extern void _sa_default_rt_restorer(void)
1884 * extern void _sa_default_restorer(void)
1886 * Code prototypes to do a sys_rt_sigreturn() or sys_sysreturn()
1887 * from user space. Copied into user space by signal management.
1888 * Both must be quad aligned and 2 quad long (4 instructions).
1892 .global sa_default_rt_restorer
1893 sa_default_rt_restorer:
1895 shori __NR_rt_sigreturn, r9
1900 .global sa_default_restorer
1901 sa_default_restorer:
1903 shori __NR_sigreturn, r9
1908 * --- __ex_table Section
1912 * User Access Exception Table.
1914 .section __ex_table, "a"
1916 .global asm_uaccess_start /* Just a marker */
1920 .long ___copy_user1, ___copy_user_exit
1921 .long ___copy_user2, ___copy_user_exit
1922 .long ___clear_user1, ___clear_user_exit
1924 .long ___get_user_asm_b1, ___get_user_asm_b_exit
1925 .long ___get_user_asm_w1, ___get_user_asm_w_exit
1926 .long ___get_user_asm_l1, ___get_user_asm_l_exit
1927 .long ___get_user_asm_q1, ___get_user_asm_q_exit
1928 .long ___put_user_asm_b1, ___put_user_asm_b_exit
1929 .long ___put_user_asm_w1, ___put_user_asm_w_exit
1930 .long ___put_user_asm_l1, ___put_user_asm_l_exit
1931 .long ___put_user_asm_q1, ___put_user_asm_q_exit
1933 .global asm_uaccess_end /* Just a marker */
1940 * --- .init.text Section
1946 * void trap_init (void)
1951 addi SP, -24, SP /* Room to save r28/r29/r30 */
1956 /* Set VBR and RESVEC */
1957 movi LVBR_block, r19
1958 andi r19, -4, r19 /* reset MMUOFF + reserved */
1959 /* For RESVEC exceptions we force the MMU off, which means we need the
1960 physical address. */
1961 movi LRESVEC_block-CONFIG_PAGE_OFFSET, r20
1962 andi r20, -4, r20 /* reset reserved */
1963 ori r20, 1, r20 /* set MMUOFF */
1968 movi LVBR_block_end, r21
1970 movi BLOCK_SIZE, r29 /* r29 = expected size */
1975 * Ugly, but better loop forever now than crash afterwards.
1976 * We should print a message, but if we touch LVBR or
1977 * LRESVEC blocks we should not be surprised if we get stuck
1980 pta trap_init_loop, tr1
1981 gettr tr1, r28 /* r28 = trap_init_loop */
1982 sub r21, r30, r30 /* r30 = actual size */
1985 * VBR/RESVEC handlers overlap by being bigger than
1986 * allowed. Very bad. Just loop forever.
1987 * (r28) panic/loop address
1988 * (r29) expected size
1994 /* Now that exception vectors are set up reset SR.BL */
1996 movi SR_UNBLOCK_EXC, r23