1 /* SPDX-License-Identifier: GPL-2.0
3 * arch/sh/kernel/cpu/sh5/entry.S
5 * Copyright (C) 2000, 2001 Paolo Alberelli
6 * Copyright (C) 2004 - 2008 Paul Mundt
7 * Copyright (C) 2003, 2004 Richard Curnow
9 #include <linux/errno.h>
10 #include <linux/init.h>
11 #include <linux/sys.h>
12 #include <cpu/registers.h>
13 #include <asm/processor.h>
14 #include <asm/unistd.h>
15 #include <asm/thread_info.h>
16 #include <asm/asm-offsets.h>
21 #define SR_ASID_MASK 0x00ff0000
22 #define SR_FD_MASK 0x00008000
23 #define SR_SS 0x08000000
24 #define SR_BL 0x10000000
25 #define SR_MD 0x40000000
30 #define EVENT_INTERRUPT 0
31 #define EVENT_FAULT_TLB 1
32 #define EVENT_FAULT_NOT_TLB 2
36 #define RESET_CAUSE 0x20
37 #define DEBUGSS_CAUSE 0x980
40 * Frame layout. Quad index.
42 #define FRAME_T(x) FRAME_TBASE+(x*8)
43 #define FRAME_R(x) FRAME_RBASE+(x*8)
44 #define FRAME_S(x) FRAME_SBASE+(x*8)
49 /* Arrange the save frame to be a multiple of 32 bytes long */
51 #define FRAME_RBASE (FRAME_SBASE+(3*8)) /* SYSCALL_ID - SSR - SPC */
52 #define FRAME_TBASE (FRAME_RBASE+(63*8)) /* r0 - r62 */
53 #define FRAME_PBASE (FRAME_TBASE+(8*8)) /* tr0 -tr7 */
54 #define FRAME_SIZE (FRAME_PBASE+(2*8)) /* pad0-pad1 */
56 #define FP_FRAME_SIZE FP_FRAME_BASE+(33*8) /* dr0 - dr31 + fpscr */
57 #define FP_FRAME_BASE 0
67 /* These are the registers saved in the TLB path that aren't saved in the first
68 level of the normal one. */
69 #define TLB_SAVED_R25 7*8
70 #define TLB_SAVED_TR1 8*8
71 #define TLB_SAVED_TR2 9*8
72 #define TLB_SAVED_TR3 10*8
73 #define TLB_SAVED_TR4 11*8
74 /* Save R0/R1 : PT-migrating compiler currently dishounours -ffixed-r0 and -ffixed-r1 causing
75 breakage otherwise. */
76 #define TLB_SAVED_R0 12*8
77 #define TLB_SAVED_R1 13*8
90 # define preempt_stop() CLI()
92 # define preempt_stop()
93 # define resume_kernel restore_all
98 #define FAST_TLBMISS_STACK_CACHELINES 4
99 #define FAST_TLBMISS_STACK_QUADWORDS (4*FAST_TLBMISS_STACK_CACHELINES)
101 /* Register back-up area for all exceptions */
103 /* Allow for 16 quadwords to be pushed by fast tlbmiss handling
104 * register saves etc. */
105 .fill FAST_TLBMISS_STACK_QUADWORDS, 8, 0x0
106 /* This is 32 byte aligned by construction */
107 /* Register back-up area for all exceptions */
127 /* Save area for RESVEC exceptions. We cannot use reg_save_area because of
128 * reentrancy. Note this area may be accessed via physical address.
129 * Align so this fits a whole single cache line, for ease of purging.
140 /* Jump table of 3rd level handlers */
142 .long do_exception_error /* 0x000 */
143 .long do_exception_error /* 0x020 */
145 .long tlb_miss_load /* 0x040 */
146 .long tlb_miss_store /* 0x060 */
148 .long do_exception_error
149 .long do_exception_error
151 ! ARTIFICIAL pseudo-EXPEVT setting
152 .long do_debug_interrupt /* 0x080 */
154 .long tlb_miss_load /* 0x0A0 */
155 .long tlb_miss_store /* 0x0C0 */
157 .long do_exception_error
158 .long do_exception_error
160 .long do_address_error_load /* 0x0E0 */
161 .long do_address_error_store /* 0x100 */
163 .long do_fpu_error /* 0x120 */
165 .long do_exception_error /* 0x120 */
167 .long do_exception_error /* 0x140 */
168 .long system_call /* 0x160 */
169 .long do_reserved_inst /* 0x180 */
170 .long do_illegal_slot_inst /* 0x1A0 */
171 .long do_exception_error /* 0x1C0 - NMI */
172 .long do_exception_error /* 0x1E0 */
174 .long do_IRQ /* 0x200 - 0x3C0 */
176 .long do_exception_error /* 0x3E0 */
178 .long do_IRQ /* 0x400 - 0x7E0 */
180 .long fpu_error_or_IRQA /* 0x800 */
181 .long fpu_error_or_IRQB /* 0x820 */
182 .long do_IRQ /* 0x840 */
183 .long do_IRQ /* 0x860 */
185 .long do_exception_error /* 0x880 - 0x920 */
187 .long breakpoint_trap_handler /* 0x940 */
188 .long do_exception_error /* 0x960 */
189 .long do_single_step /* 0x980 */
192 .long do_exception_error /* 0x9A0 - 0x9E0 */
194 .long do_IRQ /* 0xA00 */
195 .long do_IRQ /* 0xA20 */
197 .long itlb_miss_or_IRQ /* 0xA40 */
201 .long do_IRQ /* 0xA60 */
202 .long do_IRQ /* 0xA80 */
204 .long itlb_miss_or_IRQ /* 0xAA0 */
208 .long do_exception_error /* 0xAC0 */
209 .long do_address_error_exec /* 0xAE0 */
211 .long do_exception_error /* 0xB00 - 0xBE0 */
214 .long do_IRQ /* 0xC00 - 0xE20 */
217 .section .text64, "ax"
220 * --- Exception/Interrupt/Event Handling Section
224 * VBR and RESVEC blocks.
226 * First level handler for VBR-based exceptions.
228 * To avoid waste of space, align to the maximum text block size.
229 * This is assumed to be at most 128 bytes or 32 instructions.
230 * DO NOT EXCEED 32 instructions on the first level handlers !
232 * Also note that RESVEC is contained within the VBR block
233 * where the room left (1KB - TEXT_SIZE) allows placing
234 * the RESVEC block (at most 512B + TEXT_SIZE).
236 * So first (and only) level handler for RESVEC-based exceptions.
238 * Where the fault/interrupt is handled (not_a_tlb_miss, tlb_miss
239 * and interrupt) we are a lot tight with register space until
240 * saving onto the stack frame, which is done in handle_exception().
244 #define TEXT_SIZE 128
245 #define BLOCK_SIZE 1664 /* Dynamic check, 13*128 */
249 .space 256, 0 /* Power-on class handler, */
250 /* not required here */
252 synco /* TAKum03020 (but probably a good idea anyway.) */
253 /* Save original stack pointer into KCR1 */
256 /* Save other original registers into reg_save_area */
257 movi reg_save_area, SP
258 st.q SP, SAVED_R2, r2
259 st.q SP, SAVED_R3, r3
260 st.q SP, SAVED_R4, r4
261 st.q SP, SAVED_R5, r5
262 st.q SP, SAVED_R6, r6
263 st.q SP, SAVED_R18, r18
265 st.q SP, SAVED_TR0, r3
267 /* Set args for Non-debug, Not a TLB miss class handler */
269 movi ret_from_exception, r3
271 movi EVENT_FAULT_NOT_TLB, r4
274 pta handle_exception, tr0
285 * Instead of the natural .balign 1024 place RESVEC here
286 * respecting the final 1KB alignment.
290 * Instead of '.space 1024-TEXT_SIZE' place the RESVEC
291 * block making sure the final alignment is correct.
295 synco /* TAKum03020 (but probably a good idea anyway.) */
297 movi reg_save_area, SP
298 /* SP is guaranteed 32-byte aligned. */
299 st.q SP, TLB_SAVED_R0 , r0
300 st.q SP, TLB_SAVED_R1 , r1
301 st.q SP, SAVED_R2 , r2
302 st.q SP, SAVED_R3 , r3
303 st.q SP, SAVED_R4 , r4
304 st.q SP, SAVED_R5 , r5
305 st.q SP, SAVED_R6 , r6
306 st.q SP, SAVED_R18, r18
308 /* Save R25 for safety; as/ld may want to use it to achieve the call to
309 * the code in mm/tlbmiss.c */
310 st.q SP, TLB_SAVED_R25, r25
316 st.q SP, SAVED_TR0 , r2
317 st.q SP, TLB_SAVED_TR1 , r3
318 st.q SP, TLB_SAVED_TR2 , r4
319 st.q SP, TLB_SAVED_TR3 , r5
320 st.q SP, TLB_SAVED_TR4 , r18
322 pt do_fast_page_fault, tr0
327 andi r2, 1, r2 /* r2 = SSR.MD */
330 pt fixup_to_invoke_general_handler, tr1
332 /* If the fast path handler fixed the fault, just drop through quickly
333 to the restore code right away to return to the excepting context.
337 fast_tlb_miss_restore:
338 ld.q SP, SAVED_TR0, r2
339 ld.q SP, TLB_SAVED_TR1, r3
340 ld.q SP, TLB_SAVED_TR2, r4
342 ld.q SP, TLB_SAVED_TR3, r5
343 ld.q SP, TLB_SAVED_TR4, r18
351 ld.q SP, TLB_SAVED_R0, r0
352 ld.q SP, TLB_SAVED_R1, r1
353 ld.q SP, SAVED_R2, r2
354 ld.q SP, SAVED_R3, r3
355 ld.q SP, SAVED_R4, r4
356 ld.q SP, SAVED_R5, r5
357 ld.q SP, SAVED_R6, r6
358 ld.q SP, SAVED_R18, r18
359 ld.q SP, TLB_SAVED_R25, r25
363 nop /* for safety, in case the code is run on sh5-101 cut1.x */
365 fixup_to_invoke_general_handler:
367 /* OK, new method. Restore stuff that's not expected to get saved into
368 the 'first-level' reg save area, then just fall through to setting
369 up the registers and calling the second-level handler. */
371 /* 2nd level expects r2,3,4,5,6,18,tr0 to be saved. So we must restore
372 r25,tr1-4 and save r6 to get into the right state. */
374 ld.q SP, TLB_SAVED_TR1, r3
375 ld.q SP, TLB_SAVED_TR2, r4
376 ld.q SP, TLB_SAVED_TR3, r5
377 ld.q SP, TLB_SAVED_TR4, r18
378 ld.q SP, TLB_SAVED_R25, r25
380 ld.q SP, TLB_SAVED_R0, r0
381 ld.q SP, TLB_SAVED_R1, r1
388 /* Set args for Non-debug, TLB miss class handler */
390 movi ret_from_exception, r3
392 movi EVENT_FAULT_TLB, r4
395 pta handle_exception, tr0
397 #else /* CONFIG_MMU */
401 /* NB TAKE GREAT CARE HERE TO ENSURE THAT THE INTERRUPT CODE
402 DOES END UP AT VBR+0x600 */
414 synco /* TAKum03020 (but probably a good idea anyway.) */
415 /* Save original stack pointer into KCR1 */
418 /* Save other original registers into reg_save_area */
419 movi reg_save_area, SP
420 st.q SP, SAVED_R2, r2
421 st.q SP, SAVED_R3, r3
422 st.q SP, SAVED_R4, r4
423 st.q SP, SAVED_R5, r5
424 st.q SP, SAVED_R6, r6
425 st.q SP, SAVED_R18, r18
427 st.q SP, SAVED_TR0, r3
429 /* Set args for interrupt class handler */
431 movi ret_from_irq, r3
433 movi EVENT_INTERRUPT, r4
436 pta handle_exception, tr0
438 .balign TEXT_SIZE /* let's waste the bare minimum */
440 LVBR_block_end: /* Marker. Used for total checking */
444 /* Panic handler. Called with MMU off. Possible causes/actions:
445 * - Reset: Jump to program start.
446 * - Single Step: Turn off Single Step & return.
447 * - Others: Call panic handler, passing PC as arg.
448 * (this may need to be extended...)
451 synco /* TAKum03020 (but probably a good idea anyway.) */
453 /* First save r0-1 and tr0, as we need to use these */
454 movi resvec_save_area-CONFIG_PAGE_OFFSET, SP
463 sub r1, r0, r1 /* r1=0 if reset */
464 movi _stext-CONFIG_PAGE_OFFSET, r0
467 beqi r1, 0, tr0 /* Jump to start address if reset */
470 movi DEBUGSS_CAUSE, r1
471 sub r1, r0, r1 /* r1=0 if single step */
472 pta single_step_panic, tr0
473 beqi r1, 0, tr0 /* jump if single step */
475 /* Now jump to where we save the registers. */
476 movi panic_stash_regs-CONFIG_PAGE_OFFSET, r1
481 /* We are in a handler with Single Step set. We need to resume the
482 * handler, by turning on MMU & turning off Single Step. */
489 /* Restore EXPEVT, as the rte won't do this */
504 synco /* TAKum03020 (but probably a good idea anyway.) */
506 * Single step/software_break_point first level handler.
507 * Called with MMU off, so the first thing we do is enable it
508 * by doing an rte with appropriate SSR.
511 /* Save SSR & SPC, together with R0 & R1, as we need to use 2 regs. */
512 movi resvec_save_area-CONFIG_PAGE_OFFSET, SP
514 /* With the MMU off, we are bypassing the cache, so purge any
515 * data that will be made stale by the following stores.
527 /* Enable MMU, block exceptions, set priv mode, disable single step */
528 movi SR_MMU | SR_BL | SR_MD, r1
533 /* Force control to debug_exception_2 when rte is executed */
534 movi debug_exeception_2, r0
535 ori r0, 1, r0 /* force SHmedia, just in case */
541 /* Restore saved regs */
543 movi resvec_save_area, SP
551 /* Save other original registers into reg_save_area */
552 movi reg_save_area, SP
553 st.q SP, SAVED_R2, r2
554 st.q SP, SAVED_R3, r3
555 st.q SP, SAVED_R4, r4
556 st.q SP, SAVED_R5, r5
557 st.q SP, SAVED_R6, r6
558 st.q SP, SAVED_R18, r18
560 st.q SP, SAVED_TR0, r3
562 /* Set args for debug class handler */
564 movi ret_from_exception, r3
569 pta handle_exception, tr0
574 /* !!! WE COME HERE IN REAL MODE !!! */
575 /* Hook-up debug interrupt to allow various debugging options to be
576 * hooked into its handler. */
577 /* Save original stack pointer into KCR1 */
580 movi resvec_save_area-CONFIG_PAGE_OFFSET, SP
585 /* Save other original registers into reg_save_area thru real addresses */
586 st.q SP, SAVED_R2, r2
587 st.q SP, SAVED_R3, r3
588 st.q SP, SAVED_R4, r4
589 st.q SP, SAVED_R5, r5
590 st.q SP, SAVED_R6, r6
591 st.q SP, SAVED_R18, r18
593 st.q SP, SAVED_TR0, r3
595 /* move (spc,ssr)->(pspc,pssr). The rte will shift
596 them back again, so that they look like the originals
597 as far as the real handler code is concerned. */
603 ! construct useful SR for handle_exception
610 ! SSR is now the current SR with the MD and MMU bits set
611 ! i.e. the rte will switch back to priv mode and put
615 movi handle_exception, r18
616 ori r18, 1, r18 ! for safety (do we need this?)
619 /* Set args for Non-debug, Not a TLB miss class handler */
621 ! EXPEVT==0x80 is unused, so 'steal' this value to put the
622 ! debug interrupt handler in the vectoring table
624 movi ret_from_exception, r3
626 movi EVENT_FAULT_NOT_TLB, r4
629 movi CONFIG_PAGE_OFFSET, r6
634 rte ! -> handle_exception, switch back to priv mode again
636 LRESVEC_block_end: /* Marker. Unused. */
641 * Second level handler for VBR-based exceptions. Pre-handler.
642 * In common to all stack-frame sensitive handlers.
645 * (KCR0) Current [current task union]
648 * (r3) appropriate return address
649 * (r4) Event (0 = interrupt, 1 = TLB miss fault, 2 = Not TLB miss fault, 3=debug)
650 * (r5) Pointer to reg_save_area
653 * Available registers:
660 /* Common 2nd level handler. */
662 /* First thing we need an appropriate stack pointer */
667 bne r6, ZERO, tr0 /* Original stack pointer is fine */
669 /* Set stack pointer for user fault */
671 movi THREAD_SIZE, r6 /* Point to the end */
676 /* DEBUG : check for underflow/overflow of the kernel stack */
677 pta no_underflow, tr0
681 bge SP, r6, tr0 ! ? below 1k from bottom of stack : danger zone
683 /* Just panic to cause a crash. */
691 movi THREAD_SIZE, r18
693 bgt SP, r6, tr0 ! sp above the stack
695 /* Make some room for the BASIC frame. */
696 movi -(FRAME_SIZE), r6
699 /* Could do this with no stalling if we had another spare register, but the
700 code below will be OK. */
701 ld.q r5, SAVED_R2, r6
702 ld.q r5, SAVED_R3, r18
703 st.q SP, FRAME_R(2), r6
704 ld.q r5, SAVED_R4, r6
705 st.q SP, FRAME_R(3), r18
706 ld.q r5, SAVED_R5, r18
707 st.q SP, FRAME_R(4), r6
708 ld.q r5, SAVED_R6, r6
709 st.q SP, FRAME_R(5), r18
710 ld.q r5, SAVED_R18, r18
711 st.q SP, FRAME_R(6), r6
712 ld.q r5, SAVED_TR0, r6
713 st.q SP, FRAME_R(18), r18
714 st.q SP, FRAME_T(0), r6
716 /* Keep old SP around */
719 /* Save the rest of the general purpose registers */
720 st.q SP, FRAME_R(0), r0
721 st.q SP, FRAME_R(1), r1
722 st.q SP, FRAME_R(7), r7
723 st.q SP, FRAME_R(8), r8
724 st.q SP, FRAME_R(9), r9
725 st.q SP, FRAME_R(10), r10
726 st.q SP, FRAME_R(11), r11
727 st.q SP, FRAME_R(12), r12
728 st.q SP, FRAME_R(13), r13
729 st.q SP, FRAME_R(14), r14
731 /* SP is somewhere else */
732 st.q SP, FRAME_R(15), r6
734 st.q SP, FRAME_R(16), r16
735 st.q SP, FRAME_R(17), r17
736 /* r18 is saved earlier. */
737 st.q SP, FRAME_R(19), r19
738 st.q SP, FRAME_R(20), r20
739 st.q SP, FRAME_R(21), r21
740 st.q SP, FRAME_R(22), r22
741 st.q SP, FRAME_R(23), r23
742 st.q SP, FRAME_R(24), r24
743 st.q SP, FRAME_R(25), r25
744 st.q SP, FRAME_R(26), r26
745 st.q SP, FRAME_R(27), r27
746 st.q SP, FRAME_R(28), r28
747 st.q SP, FRAME_R(29), r29
748 st.q SP, FRAME_R(30), r30
749 st.q SP, FRAME_R(31), r31
750 st.q SP, FRAME_R(32), r32
751 st.q SP, FRAME_R(33), r33
752 st.q SP, FRAME_R(34), r34
753 st.q SP, FRAME_R(35), r35
754 st.q SP, FRAME_R(36), r36
755 st.q SP, FRAME_R(37), r37
756 st.q SP, FRAME_R(38), r38
757 st.q SP, FRAME_R(39), r39
758 st.q SP, FRAME_R(40), r40
759 st.q SP, FRAME_R(41), r41
760 st.q SP, FRAME_R(42), r42
761 st.q SP, FRAME_R(43), r43
762 st.q SP, FRAME_R(44), r44
763 st.q SP, FRAME_R(45), r45
764 st.q SP, FRAME_R(46), r46
765 st.q SP, FRAME_R(47), r47
766 st.q SP, FRAME_R(48), r48
767 st.q SP, FRAME_R(49), r49
768 st.q SP, FRAME_R(50), r50
769 st.q SP, FRAME_R(51), r51
770 st.q SP, FRAME_R(52), r52
771 st.q SP, FRAME_R(53), r53
772 st.q SP, FRAME_R(54), r54
773 st.q SP, FRAME_R(55), r55
774 st.q SP, FRAME_R(56), r56
775 st.q SP, FRAME_R(57), r57
776 st.q SP, FRAME_R(58), r58
777 st.q SP, FRAME_R(59), r59
778 st.q SP, FRAME_R(60), r60
779 st.q SP, FRAME_R(61), r61
780 st.q SP, FRAME_R(62), r62
783 * Save the S* registers.
786 st.q SP, FRAME_S(FSSR), r61
788 st.q SP, FRAME_S(FSPC), r62
789 movi -1, r62 /* Reset syscall_nr */
790 st.q SP, FRAME_S(FSYSCALL_ID), r62
792 /* Save the rest of the target registers */
794 st.q SP, FRAME_T(1), r6
796 st.q SP, FRAME_T(2), r6
798 st.q SP, FRAME_T(3), r6
800 st.q SP, FRAME_T(4), r6
802 st.q SP, FRAME_T(5), r6
804 st.q SP, FRAME_T(6), r6
806 st.q SP, FRAME_T(7), r6
808 ! setup FP so that unwinder can wind back through nested kernel mode
812 /* For syscall and debug race condition, get TRA now */
815 /* We are in a safe position to turn SR.BL off, but set IMASK=0xf
816 * Also set FD, to catch FPU usage in the kernel.
818 * benedict.gaster@superh.com 29/07/2002
820 * On all SH5-101 revisions it is unsafe to raise the IMASK and at the
821 * same time change BL from 1->0, as any pending interrupt of a level
822 * higher than he previous value of IMASK will leak through and be
823 * taken unexpectedly.
825 * To avoid this we raise the IMASK and then issue another PUTCON to
829 movi SR_IMASK | SR_FD, r7
832 movi SR_UNBLOCK_EXC, r7
837 /* Now call the appropriate 3rd level handler */
848 * Second level handler for VBR-based exceptions. Post-handlers.
850 * Post-handlers for interrupts (ret_from_irq), exceptions
851 * (ret_from_exception) and common reentrance doors (restore_all
852 * to get back to the original context, ret_from_syscall loop to
853 * check kernel exiting).
855 * ret_with_reschedule and work_notifysig are an inner lables of
856 * the ret_from_syscall loop.
858 * In common to all stack-frame sensitive handlers.
861 * (SP) struct pt_regs *, original register's frame pointer (basic)
866 ld.q SP, FRAME_S(FSSR), r6
869 pta resume_kernel, tr0
870 bne r6, ZERO, tr0 /* no further checks */
872 pta ret_with_reschedule, tr0
873 blink tr0, ZERO /* Do not check softirqs */
875 .global ret_from_exception
879 ld.q SP, FRAME_S(FSSR), r6
882 pta resume_kernel, tr0
883 bne r6, ZERO, tr0 /* no further checks */
887 #ifdef CONFIG_PREEMPT
888 pta ret_from_syscall, tr0
897 ld.l r6, TI_PRE_COUNT, r7
901 ld.l r6, TI_FLAGS, r7
902 movi (1 << TIF_NEED_RESCHED), r8
910 movi preempt_schedule_irq, r7
915 pta need_resched, tr1
919 .global ret_from_syscall
923 getcon KCR0, r6 ! r6 contains current_thread_info
924 ld.l r6, TI_FLAGS, r7 ! r7 contains current_thread_info->flags
926 movi _TIF_NEED_RESCHED, r8
928 pta work_resched, tr0
933 movi (_TIF_SIGPENDING|_TIF_NOTIFY_RESUME), r8
935 pta work_notifysig, tr0
941 pta ret_from_syscall, tr0
945 blink tr0, ZERO /* Call schedule(), return on top */
950 movi do_notify_resume, r6
954 blink tr0, LINK /* Call do_notify_resume(regs, current_thread_info->flags), return here */
959 ld.q SP, FRAME_T(0), r6
960 ld.q SP, FRAME_T(1), r7
961 ld.q SP, FRAME_T(2), r8
962 ld.q SP, FRAME_T(3), r9
967 ld.q SP, FRAME_T(4), r6
968 ld.q SP, FRAME_T(5), r7
969 ld.q SP, FRAME_T(6), r8
970 ld.q SP, FRAME_T(7), r9
976 ld.q SP, FRAME_R(0), r0
977 ld.q SP, FRAME_R(1), r1
978 ld.q SP, FRAME_R(2), r2
979 ld.q SP, FRAME_R(3), r3
980 ld.q SP, FRAME_R(4), r4
981 ld.q SP, FRAME_R(5), r5
982 ld.q SP, FRAME_R(6), r6
983 ld.q SP, FRAME_R(7), r7
984 ld.q SP, FRAME_R(8), r8
985 ld.q SP, FRAME_R(9), r9
986 ld.q SP, FRAME_R(10), r10
987 ld.q SP, FRAME_R(11), r11
988 ld.q SP, FRAME_R(12), r12
989 ld.q SP, FRAME_R(13), r13
990 ld.q SP, FRAME_R(14), r14
992 ld.q SP, FRAME_R(16), r16
993 ld.q SP, FRAME_R(17), r17
994 ld.q SP, FRAME_R(18), r18
995 ld.q SP, FRAME_R(19), r19
996 ld.q SP, FRAME_R(20), r20
997 ld.q SP, FRAME_R(21), r21
998 ld.q SP, FRAME_R(22), r22
999 ld.q SP, FRAME_R(23), r23
1000 ld.q SP, FRAME_R(24), r24
1001 ld.q SP, FRAME_R(25), r25
1002 ld.q SP, FRAME_R(26), r26
1003 ld.q SP, FRAME_R(27), r27
1004 ld.q SP, FRAME_R(28), r28
1005 ld.q SP, FRAME_R(29), r29
1006 ld.q SP, FRAME_R(30), r30
1007 ld.q SP, FRAME_R(31), r31
1008 ld.q SP, FRAME_R(32), r32
1009 ld.q SP, FRAME_R(33), r33
1010 ld.q SP, FRAME_R(34), r34
1011 ld.q SP, FRAME_R(35), r35
1012 ld.q SP, FRAME_R(36), r36
1013 ld.q SP, FRAME_R(37), r37
1014 ld.q SP, FRAME_R(38), r38
1015 ld.q SP, FRAME_R(39), r39
1016 ld.q SP, FRAME_R(40), r40
1017 ld.q SP, FRAME_R(41), r41
1018 ld.q SP, FRAME_R(42), r42
1019 ld.q SP, FRAME_R(43), r43
1020 ld.q SP, FRAME_R(44), r44
1021 ld.q SP, FRAME_R(45), r45
1022 ld.q SP, FRAME_R(46), r46
1023 ld.q SP, FRAME_R(47), r47
1024 ld.q SP, FRAME_R(48), r48
1025 ld.q SP, FRAME_R(49), r49
1026 ld.q SP, FRAME_R(50), r50
1027 ld.q SP, FRAME_R(51), r51
1028 ld.q SP, FRAME_R(52), r52
1029 ld.q SP, FRAME_R(53), r53
1030 ld.q SP, FRAME_R(54), r54
1031 ld.q SP, FRAME_R(55), r55
1032 ld.q SP, FRAME_R(56), r56
1033 ld.q SP, FRAME_R(57), r57
1034 ld.q SP, FRAME_R(58), r58
1037 movi SR_BLOCK_EXC, r60
1039 putcon r59, SR /* SR.BL = 1, keep nesting out */
1040 ld.q SP, FRAME_S(FSSR), r61
1041 ld.q SP, FRAME_S(FSPC), r62
1042 movi SR_ASID_MASK, r60
1044 andc r61, r60, r61 /* Clear out older ASID */
1045 or r59, r61, r61 /* Retain current ASID */
1049 /* Ignore FSYSCALL_ID */
1051 ld.q SP, FRAME_R(59), r59
1052 ld.q SP, FRAME_R(60), r60
1053 ld.q SP, FRAME_R(61), r61
1054 ld.q SP, FRAME_R(62), r62
1057 ld.q SP, FRAME_R(15), SP
1062 * Third level handlers for VBR-based exceptions. Adapting args to
1063 * and/or deflecting to fourth level handlers.
1065 * Fourth level handlers interface.
1066 * Most are C-coded handlers directly pointed by the trap_jtable.
1067 * (Third = Fourth level)
1069 * (r2) fault/interrupt code, entry number (e.g. NMI = 14,
1070 * IRL0-3 (0000) = 16, RTLBMISS = 2, SYSCALL = 11, etc ...)
1071 * (r3) struct pt_regs *, original register's frame pointer
1072 * (r4) Event (0 = interrupt, 1 = TLB miss fault, 2 = Not TLB miss fault)
1073 * (r5) TRA control register (for syscall/debug benefit only)
1074 * (LINK) return address
1077 * Kernel TLB fault handlers will get a slightly different interface.
1078 * (r2) struct pt_regs *, original register's frame pointer
1079 * (r3) page fault error code (see asm/thread_info.h)
1080 * (r4) Effective Address of fault
1081 * (LINK) return address
1084 * fpu_error_or_IRQ? is a helper to deflect to the right cause.
1090 or ZERO, ZERO, r3 /* Read */
1092 pta call_do_page_fault, tr0
1097 movi FAULT_CODE_WRITE, r3 /* Write */
1099 pta call_do_page_fault, tr0
1104 beqi/u r4, EVENT_INTERRUPT, tr0
1108 movi FAULT_CODE_ITLB, r3
1113 movi do_page_fault, r6
1116 #endif /* CONFIG_MMU */
1120 beqi/l r4, EVENT_INTERRUPT, tr0
1121 #ifdef CONFIG_SH_FPU
1122 movi fpu_state_restore_trap_handler, r6
1124 movi do_exception_error, r6
1131 beqi/l r4, EVENT_INTERRUPT, tr0
1132 #ifdef CONFIG_SH_FPU
1133 movi fpu_state_restore_trap_handler, r6
1135 movi do_exception_error, r6
1146 * system_call/unknown_trap third level handler:
1149 * (r2) fault/interrupt code, entry number (TRAP = 11)
1150 * (r3) struct pt_regs *, original register's frame pointer
1151 * (r4) Not used. Event (0=interrupt, 1=TLB miss fault, 2=Not TLB miss fault)
1152 * (r5) TRA Control Reg (0x00xyzzzz: x=1 SYSCALL, y = #args, z=nr)
1154 * (LINK) return address: ret_from_exception
1155 * (*r3) Syscall parms: SC#, arg0, arg1, ..., arg5 in order (Saved r2/r7)
1158 * (*r3) Syscall reply (Saved r2)
1159 * (LINK) In case of syscall only it can be scrapped.
1160 * Common second level post handler will be ret_from_syscall.
1161 * Common (non-trace) exit point to that is syscall_ret (saving
1162 * result to r2). Common bad exit point is syscall_bad (returning
1163 * ENOSYS then saved to r2).
1168 /* Unknown Trap or User Trace */
1169 movi do_unknown_trapa, r6
1171 ld.q r3, FRAME_R(9), r2 /* r2 = #arg << 16 | syscall # */
1172 andi r2, 0x1ff, r2 /* r2 = syscall # */
1175 pta syscall_ret, tr0
1178 /* New syscall implementation*/
1180 pta unknown_trap, tr0
1181 or r5, ZERO, r4 /* TRA (=r5) -> r4 */
1183 bnei r4, 1, tr0 /* unknown_trap if not 0x1yzzzz */
1185 /* It's a system call */
1186 st.q r3, FRAME_S(FSYSCALL_ID), r5 /* ID (0x1yzzzz) -> stack */
1187 andi r5, 0x1ff, r5 /* syscall # -> r5 */
1191 pta syscall_allowed, tr0
1192 movi NR_syscalls - 1, r4 /* Last valid */
1196 /* Return ENOSYS ! */
1197 movi -(ENOSYS), r2 /* Fall-through */
1201 st.q SP, FRAME_R(9), r2 /* Expecting SP back to BASIC frame */
1202 ld.q SP, FRAME_S(FSPC), r2
1203 addi r2, 4, r2 /* Move PC, being pre-execution event */
1204 st.q SP, FRAME_S(FSPC), r2
1205 pta ret_from_syscall, tr0
1209 /* A different return path for ret_from_fork, because we now need
1210 * to call schedule_tail with the later kernels. Because prev is
1211 * loaded into r2 by switch_to() means we can just call it straight away
1214 .global ret_from_fork
1217 movi schedule_tail,r5
1222 ld.q SP, FRAME_S(FSPC), r2
1223 addi r2, 4, r2 /* Move PC, being pre-execution event */
1224 st.q SP, FRAME_S(FSPC), r2
1225 pta ret_from_syscall, tr0
1228 .global ret_from_kernel_thread
1229 ret_from_kernel_thread:
1231 movi schedule_tail,r5
1236 ld.q SP, FRAME_R(2), r2
1237 ld.q SP, FRAME_R(3), r3
1241 ld.q SP, FRAME_S(FSPC), r2
1242 addi r2, 4, r2 /* Move PC, being pre-execution event */
1243 st.q SP, FRAME_S(FSPC), r2
1244 pta ret_from_syscall, tr0
1248 /* Use LINK to deflect the exit point, default is syscall_ret */
1249 pta syscall_ret, tr0
1251 pta syscall_notrace, tr0
1254 ld.l r2, TI_FLAGS, r4
1255 movi _TIF_WORK_SYSCALL_MASK, r6
1259 /* Trace it by calling syscall_trace before and after */
1260 movi do_syscall_trace_enter, r4
1265 /* Save the retval */
1266 st.q SP, FRAME_R(2), r2
1268 /* Reload syscall number as r5 is trashed by do_syscall_trace_enter */
1269 ld.q SP, FRAME_S(FSYSCALL_ID), r5
1272 pta syscall_ret_trace, tr0
1276 /* Now point to the appropriate 4th level syscall handler */
1277 movi sys_call_table, r4
1282 /* Prepare original args */
1283 ld.q SP, FRAME_R(2), r2
1284 ld.q SP, FRAME_R(3), r3
1285 ld.q SP, FRAME_R(4), r4
1286 ld.q SP, FRAME_R(5), r5
1287 ld.q SP, FRAME_R(6), r6
1288 ld.q SP, FRAME_R(7), r7
1290 /* And now the trick for those syscalls requiring regs * ! */
1294 blink tr0, ZERO /* LINK is already properly set */
1297 /* We get back here only if under trace */
1298 st.q SP, FRAME_R(9), r2 /* Save return value */
1300 movi do_syscall_trace_leave, LINK
1305 /* This needs to be done after any syscall tracing */
1306 ld.q SP, FRAME_S(FSPC), r2
1307 addi r2, 4, r2 /* Move PC, being pre-execution event */
1308 st.q SP, FRAME_S(FSPC), r2
1310 pta ret_from_syscall, tr0
1311 blink tr0, ZERO /* Resume normal return sequence */
1314 * --- Switch to running under a particular ASID and return the previous ASID value
1315 * --- The caller is assumed to have done a cli before calling this.
1317 * Input r2 : new ASID
1318 * Output r2 : old ASID
1321 .global switch_and_save_asid
1322 switch_and_save_asid:
1325 shlli r4, 16, r4 /* r4 = mask to select ASID */
1326 and r0, r4, r3 /* r3 = shifted old ASID */
1327 andi r2, 255, r2 /* mask down new ASID */
1328 shlli r2, 16, r2 /* align new ASID against SR.ASID */
1329 andc r0, r4, r0 /* efface old ASID from SR */
1330 or r0, r2, r0 /* insert the new ASID */
1338 shlri r3, 16, r2 /* r2 = old ASID */
1341 .global route_to_panic_handler
1342 route_to_panic_handler:
1343 /* Switch to real mode, goto panic_handler, don't return. Useful for
1344 last-chance debugging, e.g. if no output wants to go to the console.
1347 movi panic_handler - CONFIG_PAGE_OFFSET, r1
1359 1: /* Now in real mode */
1363 .global peek_real_address_q
1364 peek_real_address_q:
1366 r2 : real mode address to peek
1367 r2(out) : result quadword
1369 This is provided as a cheapskate way of manipulating device
1370 registers for debugging (to avoid the need to ioremap the debug
1371 module, and to avoid the need to ioremap the watchpoint
1372 controller in a way that identity maps sufficient bits to avoid the
1373 SH5-101 cut2 silicon defect).
1375 This code is not performance critical
1378 add.l r2, r63, r2 /* sign extend address */
1379 getcon sr, r0 /* r0 = saved original SR */
1382 or r0, r1, r1 /* r0 with block bit set */
1383 putcon r1, sr /* now in critical section */
1386 andc r1, r36, r1 /* turn sr.mmu off in real mode section */
1389 movi .peek0 - CONFIG_PAGE_OFFSET, r36 /* real mode target address */
1390 movi 1f, r37 /* virtual mode return addr */
1397 .peek0: /* come here in real mode, don't touch caches!!
1398 still in critical section (sr.bl==1) */
1401 /* Here's the actual peek. If the address is bad, all bets are now off
1402 * what will happen (handlers invoked in real-mode = bad news) */
1405 rte /* Back to virtual mode */
1412 .global poke_real_address_q
1413 poke_real_address_q:
1415 r2 : real mode address to poke
1416 r3 : quadword value to write.
1418 This is provided as a cheapskate way of manipulating device
1419 registers for debugging (to avoid the need to ioremap the debug
1420 module, and to avoid the need to ioremap the watchpoint
1421 controller in a way that identity maps sufficient bits to avoid the
1422 SH5-101 cut2 silicon defect).
1424 This code is not performance critical
1427 add.l r2, r63, r2 /* sign extend address */
1428 getcon sr, r0 /* r0 = saved original SR */
1431 or r0, r1, r1 /* r0 with block bit set */
1432 putcon r1, sr /* now in critical section */
1435 andc r1, r36, r1 /* turn sr.mmu off in real mode section */
1438 movi .poke0-CONFIG_PAGE_OFFSET, r36 /* real mode target address */
1439 movi 1f, r37 /* virtual mode return addr */
1446 .poke0: /* come here in real mode, don't touch caches!!
1447 still in critical section (sr.bl==1) */
1450 /* Here's the actual poke. If the address is bad, all bets are now off
1451 * what will happen (handlers invoked in real-mode = bad news) */
1454 rte /* Back to virtual mode */
1463 * --- User Access Handling Section
1467 * User Access support. It all moved to non inlined Assembler
1468 * functions in here.
1470 * __kernel_size_t __copy_user(void *__to, const void *__from,
1471 * __kernel_size_t __n)
1474 * (r2) target address
1475 * (r3) source address
1476 * (r4) size in bytes
1480 * (r2) non-copied bytes
1482 * If a fault occurs on the user pointer, bail out early and return the
1483 * number of bytes not copied in r2.
1484 * Strategy : for large blocks, call a real memcpy function which can
1485 * move >1 byte at a time using unaligned ld/st instructions, and can
1486 * manipulate the cache using prefetch + alloco to improve the speed
1487 * further. If a fault occurs in that function, just revert to the
1488 * byte-by-byte approach used for small blocks; this is rare so the
1489 * performance hit for that case does not matter.
1491 * For small blocks it's not worth the overhead of setting up and calling
1492 * the memcpy routine; do the copy a byte at a time.
1497 pta __copy_user_byte_by_byte, tr1
1498 movi 16, r0 ! this value is a best guess, should tune it by benchmarking
1500 pta copy_user_memcpy, tr0
1502 /* Save arguments in case we have to fix-up unhandled page fault */
1506 st.q SP, 24, r35 ! r35 is callee-save
1507 /* Save LINK in a register to reduce RTS time later (otherwise
1508 ld SP,*,LINK;ptabs LINK;trn;blink trn,r63 becomes a critical path) */
1512 /* Copy completed normally if we get back here */
1515 /* don't restore r2-r4, pointless */
1516 /* set result=r2 to zero as the copy must have succeeded. */
1519 blink tr0, r63 ! RTS
1521 .global __copy_user_fixup
1523 /* Restore stack frame */
1530 /* Fall through to original code, in the 'same' state we entered with */
1532 /* The slow byte-by-byte method is used if the fast copy traps due to a bad
1533 user address. In that rare case, the speed drop can be tolerated. */
1534 __copy_user_byte_by_byte:
1535 pta ___copy_user_exit, tr1
1536 pta ___copy_user1, tr0
1537 beq/u r4, r63, tr1 /* early exit for zero length copy */
1542 ld.b r3, 0, r5 /* Fault address 1 */
1544 /* Could rewrite this to use just 1 add, but the second comes 'free'
1545 due to load latency */
1547 addi r4, -1, r4 /* No real fixup required */
1549 stx.b r3, r0, r5 /* Fault address 2 */
1558 * __kernel_size_t __clear_user(void *addr, __kernel_size_t size)
1561 * (r2) target address
1562 * (r3) size in bytes
1565 * (*r2) zero-ed target data
1566 * (r2) non-zero-ed bytes
1568 .global __clear_user
1570 pta ___clear_user_exit, tr1
1571 pta ___clear_user1, tr0
1575 st.b r2, 0, ZERO /* Fault address */
1577 addi r3, -1, r3 /* No real fixup required */
1585 #endif /* CONFIG_MMU */
1588 * extern long __get_user_asm_?(void *val, long addr)
1592 * (r3) source address (in User Space)
1595 * (r2) -EFAULT (faulting)
1598 .global __get_user_asm_b
1601 movi -(EFAULT), r2 /* r2 = reply, no real fixup */
1604 ld.b r3, 0, r5 /* r5 = data */
1608 ___get_user_asm_b_exit:
1613 .global __get_user_asm_w
1616 movi -(EFAULT), r2 /* r2 = reply, no real fixup */
1619 ld.w r3, 0, r5 /* r5 = data */
1623 ___get_user_asm_w_exit:
1628 .global __get_user_asm_l
1631 movi -(EFAULT), r2 /* r2 = reply, no real fixup */
1634 ld.l r3, 0, r5 /* r5 = data */
1638 ___get_user_asm_l_exit:
1643 .global __get_user_asm_q
1646 movi -(EFAULT), r2 /* r2 = reply, no real fixup */
1649 ld.q r3, 0, r5 /* r5 = data */
1653 ___get_user_asm_q_exit:
1658 * extern long __put_user_asm_?(void *pval, long addr)
1661 * (r2) kernel pointer to value
1662 * (r3) dest address (in User Space)
1665 * (r2) -EFAULT (faulting)
1668 .global __put_user_asm_b
1670 ld.b r2, 0, r4 /* r4 = data */
1671 movi -(EFAULT), r2 /* r2 = reply, no real fixup */
1677 ___put_user_asm_b_exit:
1682 .global __put_user_asm_w
1684 ld.w r2, 0, r4 /* r4 = data */
1685 movi -(EFAULT), r2 /* r2 = reply, no real fixup */
1691 ___put_user_asm_w_exit:
1696 .global __put_user_asm_l
1698 ld.l r2, 0, r4 /* r4 = data */
1699 movi -(EFAULT), r2 /* r2 = reply, no real fixup */
1705 ___put_user_asm_l_exit:
1710 .global __put_user_asm_q
1712 ld.q r2, 0, r4 /* r4 = data */
1713 movi -(EFAULT), r2 /* r2 = reply, no real fixup */
1719 ___put_user_asm_q_exit:
1724 /* The idea is : when we get an unhandled panic, we dump the registers
1725 to a known memory location, the just sit in a tight loop.
1726 This allows the human to look at the memory region through the GDB
1727 session (assuming the debug module's SHwy initiator isn't locked up
1728 or anything), to hopefully analyze the cause of the panic. */
1730 /* On entry, former r15 (SP) is in DCR
1731 former r0 is at resvec_saved_area + 0
1732 former r1 is at resvec_saved_area + 8
1733 former tr0 is at resvec_saved_area + 32
1734 DCR is the only register whose value is lost altogether.
1737 movi 0xffffffff80000000, r0 ! phy of dump area
1738 ld.q SP, 0x000, r1 ! former r0
1740 ld.q SP, 0x008, r1 ! former r1
1804 st.q r0, 0x1f8, r63 ! bogus, but for consistency's sake...
1806 ld.q SP, 0x020, r1 ! former tr0
1856 /* Prepare to jump to C - physical address */
1857 movi panic_handler-CONFIG_PAGE_OFFSET, r1
1871 * --- Signal Handling Section
1875 * extern long long _sa_default_rt_restorer
1876 * extern long long _sa_default_restorer
1880 * extern void _sa_default_rt_restorer(void)
1881 * extern void _sa_default_restorer(void)
1883 * Code prototypes to do a sys_rt_sigreturn() or sys_sysreturn()
1884 * from user space. Copied into user space by signal management.
1885 * Both must be quad aligned and 2 quad long (4 instructions).
1889 .global sa_default_rt_restorer
1890 sa_default_rt_restorer:
1892 shori __NR_rt_sigreturn, r9
1897 .global sa_default_restorer
1898 sa_default_restorer:
1900 shori __NR_sigreturn, r9
1905 * --- __ex_table Section
1909 * User Access Exception Table.
1911 .section __ex_table, "a"
1913 .global asm_uaccess_start /* Just a marker */
1917 .long ___copy_user1, ___copy_user_exit
1918 .long ___copy_user2, ___copy_user_exit
1919 .long ___clear_user1, ___clear_user_exit
1921 .long ___get_user_asm_b1, ___get_user_asm_b_exit
1922 .long ___get_user_asm_w1, ___get_user_asm_w_exit
1923 .long ___get_user_asm_l1, ___get_user_asm_l_exit
1924 .long ___get_user_asm_q1, ___get_user_asm_q_exit
1925 .long ___put_user_asm_b1, ___put_user_asm_b_exit
1926 .long ___put_user_asm_w1, ___put_user_asm_w_exit
1927 .long ___put_user_asm_l1, ___put_user_asm_l_exit
1928 .long ___put_user_asm_q1, ___put_user_asm_q_exit
1930 .global asm_uaccess_end /* Just a marker */
1937 * --- .init.text Section
1943 * void trap_init (void)
1948 addi SP, -24, SP /* Room to save r28/r29/r30 */
1953 /* Set VBR and RESVEC */
1954 movi LVBR_block, r19
1955 andi r19, -4, r19 /* reset MMUOFF + reserved */
1956 /* For RESVEC exceptions we force the MMU off, which means we need the
1957 physical address. */
1958 movi LRESVEC_block-CONFIG_PAGE_OFFSET, r20
1959 andi r20, -4, r20 /* reset reserved */
1960 ori r20, 1, r20 /* set MMUOFF */
1965 movi LVBR_block_end, r21
1967 movi BLOCK_SIZE, r29 /* r29 = expected size */
1972 * Ugly, but better loop forever now than crash afterwards.
1973 * We should print a message, but if we touch LVBR or
1974 * LRESVEC blocks we should not be surprised if we get stuck
1977 pta trap_init_loop, tr1
1978 gettr tr1, r28 /* r28 = trap_init_loop */
1979 sub r21, r30, r30 /* r30 = actual size */
1982 * VBR/RESVEC handlers overlap by being bigger than
1983 * allowed. Very bad. Just loop forever.
1984 * (r28) panic/loop address
1985 * (r29) expected size
1991 /* Now that exception vectors are set up reset SR.BL */
1993 movi SR_UNBLOCK_EXC, r23