2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
6 * arch/sh64/kernel/entry.S
8 * Copyright (C) 2000, 2001 Paolo Alberelli
9 * Copyright (C) 2004, 2005 Paul Mundt
10 * Copyright (C) 2003, 2004 Richard Curnow
14 #include <linux/config.h>
15 #include <linux/errno.h>
16 #include <linux/sys.h>
18 #include <asm/processor.h>
19 #include <asm/registers.h>
20 #include <asm/unistd.h>
21 #include <asm/thread_info.h>
22 #include <asm/asm-offsets.h>
27 #define SR_ASID_MASK 0x00ff0000
28 #define SR_FD_MASK 0x00008000
29 #define SR_SS 0x08000000
30 #define SR_BL 0x10000000
31 #define SR_MD 0x40000000
36 #define EVENT_INTERRUPT 0
37 #define EVENT_FAULT_TLB 1
38 #define EVENT_FAULT_NOT_TLB 2
42 #define RESET_CAUSE 0x20
43 #define DEBUGSS_CAUSE 0x980
46 * Frame layout. Quad index.
48 #define FRAME_T(x) FRAME_TBASE+(x*8)
49 #define FRAME_R(x) FRAME_RBASE+(x*8)
50 #define FRAME_S(x) FRAME_SBASE+(x*8)
55 /* Arrange the save frame to be a multiple of 32 bytes long */
57 #define FRAME_RBASE (FRAME_SBASE+(3*8)) /* SYSCALL_ID - SSR - SPC */
58 #define FRAME_TBASE (FRAME_RBASE+(63*8)) /* r0 - r62 */
59 #define FRAME_PBASE (FRAME_TBASE+(8*8)) /* tr0 -tr7 */
60 #define FRAME_SIZE (FRAME_PBASE+(2*8)) /* pad0-pad1 */
62 #define FP_FRAME_SIZE FP_FRAME_BASE+(33*8) /* dr0 - dr31 + fpscr */
63 #define FP_FRAME_BASE 0
73 /* These are the registers saved in the TLB path that aren't saved in the first
74 level of the normal one. */
75 #define TLB_SAVED_R25 7*8
76 #define TLB_SAVED_TR1 8*8
77 #define TLB_SAVED_TR2 9*8
78 #define TLB_SAVED_TR3 10*8
79 #define TLB_SAVED_TR4 11*8
80 /* Save R0/R1 : PT-migrating compiler currently dishounours -ffixed-r0 and -ffixed-r1 causing
81 breakage otherwise. */
82 #define TLB_SAVED_R0 12*8
83 #define TLB_SAVED_R1 13*8
96 # define preempt_stop() CLI()
98 # define preempt_stop()
99 # define resume_kernel restore_all
104 #define FAST_TLBMISS_STACK_CACHELINES 4
105 #define FAST_TLBMISS_STACK_QUADWORDS (4*FAST_TLBMISS_STACK_CACHELINES)
107 /* Register back-up area for all exceptions */
109 /* Allow for 16 quadwords to be pushed by fast tlbmiss handling
110 * register saves etc. */
111 .fill FAST_TLBMISS_STACK_QUADWORDS, 8, 0x0
112 /* This is 32 byte aligned by construction */
113 /* Register back-up area for all exceptions */
133 /* Save area for RESVEC exceptions. We cannot use reg_save_area because of
134 * reentrancy. Note this area may be accessed via physical address.
135 * Align so this fits a whole single cache line, for ease of purging.
146 /* Jump table of 3rd level handlers */
148 .long do_exception_error /* 0x000 */
149 .long do_exception_error /* 0x020 */
150 .long tlb_miss_load /* 0x040 */
151 .long tlb_miss_store /* 0x060 */
152 ! ARTIFICIAL pseudo-EXPEVT setting
153 .long do_debug_interrupt /* 0x080 */
154 .long tlb_miss_load /* 0x0A0 */
155 .long tlb_miss_store /* 0x0C0 */
156 .long do_address_error_load /* 0x0E0 */
157 .long do_address_error_store /* 0x100 */
159 .long do_fpu_error /* 0x120 */
161 .long do_exception_error /* 0x120 */
163 .long do_exception_error /* 0x140 */
164 .long system_call /* 0x160 */
165 .long do_reserved_inst /* 0x180 */
166 .long do_illegal_slot_inst /* 0x1A0 */
167 .long do_NMI /* 0x1C0 */
168 .long do_exception_error /* 0x1E0 */
170 .long do_IRQ /* 0x200 - 0x3C0 */
172 .long do_exception_error /* 0x3E0 */
174 .long do_IRQ /* 0x400 - 0x7E0 */
176 .long fpu_error_or_IRQA /* 0x800 */
177 .long fpu_error_or_IRQB /* 0x820 */
178 .long do_IRQ /* 0x840 */
179 .long do_IRQ /* 0x860 */
181 .long do_exception_error /* 0x880 - 0x920 */
183 .long do_software_break_point /* 0x940 */
184 .long do_exception_error /* 0x960 */
185 .long do_single_step /* 0x980 */
188 .long do_exception_error /* 0x9A0 - 0x9E0 */
190 .long do_IRQ /* 0xA00 */
191 .long do_IRQ /* 0xA20 */
192 .long itlb_miss_or_IRQ /* 0xA40 */
193 .long do_IRQ /* 0xA60 */
194 .long do_IRQ /* 0xA80 */
195 .long itlb_miss_or_IRQ /* 0xAA0 */
196 .long do_exception_error /* 0xAC0 */
197 .long do_address_error_exec /* 0xAE0 */
199 .long do_exception_error /* 0xB00 - 0xBE0 */
202 .long do_IRQ /* 0xC00 - 0xE20 */
205 .section .text64, "ax"
208 * --- Exception/Interrupt/Event Handling Section
212 * VBR and RESVEC blocks.
214 * First level handler for VBR-based exceptions.
216 * To avoid waste of space, align to the maximum text block size.
217 * This is assumed to be at most 128 bytes or 32 instructions.
218 * DO NOT EXCEED 32 instructions on the first level handlers !
220 * Also note that RESVEC is contained within the VBR block
221 * where the room left (1KB - TEXT_SIZE) allows placing
222 * the RESVEC block (at most 512B + TEXT_SIZE).
224 * So first (and only) level handler for RESVEC-based exceptions.
226 * Where the fault/interrupt is handled (not_a_tlb_miss, tlb_miss
227 * and interrupt) we are a lot tight with register space until
228 * saving onto the stack frame, which is done in handle_exception().
232 #define TEXT_SIZE 128
233 #define BLOCK_SIZE 1664 /* Dynamic check, 13*128 */
237 .space 256, 0 /* Power-on class handler, */
238 /* not required here */
240 synco /* TAKum03020 (but probably a good idea anyway.) */
241 /* Save original stack pointer into KCR1 */
244 /* Save other original registers into reg_save_area */
245 movi reg_save_area, SP
246 st.q SP, SAVED_R2, r2
247 st.q SP, SAVED_R3, r3
248 st.q SP, SAVED_R4, r4
249 st.q SP, SAVED_R5, r5
250 st.q SP, SAVED_R6, r6
251 st.q SP, SAVED_R18, r18
253 st.q SP, SAVED_TR0, r3
255 /* Set args for Non-debug, Not a TLB miss class handler */
257 movi ret_from_exception, r3
259 movi EVENT_FAULT_NOT_TLB, r4
262 pta handle_exception, tr0
273 * Instead of the natural .balign 1024 place RESVEC here
274 * respecting the final 1KB alignment.
278 * Instead of '.space 1024-TEXT_SIZE' place the RESVEC
279 * block making sure the final alignment is correct.
282 synco /* TAKum03020 (but probably a good idea anyway.) */
284 movi reg_save_area, SP
285 /* SP is guaranteed 32-byte aligned. */
286 st.q SP, TLB_SAVED_R0 , r0
287 st.q SP, TLB_SAVED_R1 , r1
288 st.q SP, SAVED_R2 , r2
289 st.q SP, SAVED_R3 , r3
290 st.q SP, SAVED_R4 , r4
291 st.q SP, SAVED_R5 , r5
292 st.q SP, SAVED_R6 , r6
293 st.q SP, SAVED_R18, r18
295 /* Save R25 for safety; as/ld may want to use it to achieve the call to
296 * the code in mm/tlbmiss.c */
297 st.q SP, TLB_SAVED_R25, r25
303 st.q SP, SAVED_TR0 , r2
304 st.q SP, TLB_SAVED_TR1 , r3
305 st.q SP, TLB_SAVED_TR2 , r4
306 st.q SP, TLB_SAVED_TR3 , r5
307 st.q SP, TLB_SAVED_TR4 , r18
309 pt do_fast_page_fault, tr0
314 andi r2, 1, r2 /* r2 = SSR.MD */
317 pt fixup_to_invoke_general_handler, tr1
319 /* If the fast path handler fixed the fault, just drop through quickly
320 to the restore code right away to return to the excepting context.
324 fast_tlb_miss_restore:
325 ld.q SP, SAVED_TR0, r2
326 ld.q SP, TLB_SAVED_TR1, r3
327 ld.q SP, TLB_SAVED_TR2, r4
329 ld.q SP, TLB_SAVED_TR3, r5
330 ld.q SP, TLB_SAVED_TR4, r18
338 ld.q SP, TLB_SAVED_R0, r0
339 ld.q SP, TLB_SAVED_R1, r1
340 ld.q SP, SAVED_R2, r2
341 ld.q SP, SAVED_R3, r3
342 ld.q SP, SAVED_R4, r4
343 ld.q SP, SAVED_R5, r5
344 ld.q SP, SAVED_R6, r6
345 ld.q SP, SAVED_R18, r18
346 ld.q SP, TLB_SAVED_R25, r25
350 nop /* for safety, in case the code is run on sh5-101 cut1.x */
352 fixup_to_invoke_general_handler:
354 /* OK, new method. Restore stuff that's not expected to get saved into
355 the 'first-level' reg save area, then just fall through to setting
356 up the registers and calling the second-level handler. */
358 /* 2nd level expects r2,3,4,5,6,18,tr0 to be saved. So we must restore
359 r25,tr1-4 and save r6 to get into the right state. */
361 ld.q SP, TLB_SAVED_TR1, r3
362 ld.q SP, TLB_SAVED_TR2, r4
363 ld.q SP, TLB_SAVED_TR3, r5
364 ld.q SP, TLB_SAVED_TR4, r18
365 ld.q SP, TLB_SAVED_R25, r25
367 ld.q SP, TLB_SAVED_R0, r0
368 ld.q SP, TLB_SAVED_R1, r1
375 /* Set args for Non-debug, TLB miss class handler */
377 movi ret_from_exception, r3
379 movi EVENT_FAULT_TLB, r4
382 pta handle_exception, tr0
385 /* NB TAKE GREAT CARE HERE TO ENSURE THAT THE INTERRUPT CODE
386 DOES END UP AT VBR+0x600 */
398 synco /* TAKum03020 (but probably a good idea anyway.) */
399 /* Save original stack pointer into KCR1 */
402 /* Save other original registers into reg_save_area */
403 movi reg_save_area, SP
404 st.q SP, SAVED_R2, r2
405 st.q SP, SAVED_R3, r3
406 st.q SP, SAVED_R4, r4
407 st.q SP, SAVED_R5, r5
408 st.q SP, SAVED_R6, r6
409 st.q SP, SAVED_R18, r18
411 st.q SP, SAVED_TR0, r3
413 /* Set args for interrupt class handler */
415 movi ret_from_irq, r3
417 movi EVENT_INTERRUPT, r4
420 pta handle_exception, tr0
422 .balign TEXT_SIZE /* let's waste the bare minimum */
424 LVBR_block_end: /* Marker. Used for total checking */
428 /* Panic handler. Called with MMU off. Possible causes/actions:
429 * - Reset: Jump to program start.
430 * - Single Step: Turn off Single Step & return.
431 * - Others: Call panic handler, passing PC as arg.
432 * (this may need to be extended...)
435 synco /* TAKum03020 (but probably a good idea anyway.) */
437 /* First save r0-1 and tr0, as we need to use these */
438 movi resvec_save_area-CONFIG_CACHED_MEMORY_OFFSET, SP
447 sub r1, r0, r1 /* r1=0 if reset */
448 movi _stext-CONFIG_CACHED_MEMORY_OFFSET, r0
451 beqi r1, 0, tr0 /* Jump to start address if reset */
454 movi DEBUGSS_CAUSE, r1
455 sub r1, r0, r1 /* r1=0 if single step */
456 pta single_step_panic, tr0
457 beqi r1, 0, tr0 /* jump if single step */
459 /* Now jump to where we save the registers. */
460 movi panic_stash_regs-CONFIG_CACHED_MEMORY_OFFSET, r1
465 /* We are in a handler with Single Step set. We need to resume the
466 * handler, by turning on MMU & turning off Single Step. */
473 /* Restore EXPEVT, as the rte won't do this */
488 synco /* TAKum03020 (but probably a good idea anyway.) */
490 * Single step/software_break_point first level handler.
491 * Called with MMU off, so the first thing we do is enable it
492 * by doing an rte with appropriate SSR.
495 /* Save SSR & SPC, together with R0 & R1, as we need to use 2 regs. */
496 movi resvec_save_area-CONFIG_CACHED_MEMORY_OFFSET, SP
498 /* With the MMU off, we are bypassing the cache, so purge any
499 * data that will be made stale by the following stores.
511 /* Enable MMU, block exceptions, set priv mode, disable single step */
512 movi SR_MMU | SR_BL | SR_MD, r1
517 /* Force control to debug_exception_2 when rte is executed */
518 movi debug_exeception_2, r0
519 ori r0, 1, r0 /* force SHmedia, just in case */
525 /* Restore saved regs */
527 movi resvec_save_area, SP
535 /* Save other original registers into reg_save_area */
536 movi reg_save_area, SP
537 st.q SP, SAVED_R2, r2
538 st.q SP, SAVED_R3, r3
539 st.q SP, SAVED_R4, r4
540 st.q SP, SAVED_R5, r5
541 st.q SP, SAVED_R6, r6
542 st.q SP, SAVED_R18, r18
544 st.q SP, SAVED_TR0, r3
546 /* Set args for debug class handler */
548 movi ret_from_exception, r3
553 pta handle_exception, tr0
558 /* !!! WE COME HERE IN REAL MODE !!! */
559 /* Hook-up debug interrupt to allow various debugging options to be
560 * hooked into its handler. */
561 /* Save original stack pointer into KCR1 */
564 movi resvec_save_area-CONFIG_CACHED_MEMORY_OFFSET, SP
569 /* Save other original registers into reg_save_area thru real addresses */
570 st.q SP, SAVED_R2, r2
571 st.q SP, SAVED_R3, r3
572 st.q SP, SAVED_R4, r4
573 st.q SP, SAVED_R5, r5
574 st.q SP, SAVED_R6, r6
575 st.q SP, SAVED_R18, r18
577 st.q SP, SAVED_TR0, r3
579 /* move (spc,ssr)->(pspc,pssr). The rte will shift
580 them back again, so that they look like the originals
581 as far as the real handler code is concerned. */
587 ! construct useful SR for handle_exception
594 ! SSR is now the current SR with the MD and MMU bits set
595 ! i.e. the rte will switch back to priv mode and put
599 movi handle_exception, r18
600 ori r18, 1, r18 ! for safety (do we need this?)
603 /* Set args for Non-debug, Not a TLB miss class handler */
605 ! EXPEVT==0x80 is unused, so 'steal' this value to put the
606 ! debug interrupt handler in the vectoring table
608 movi ret_from_exception, r3
610 movi EVENT_FAULT_NOT_TLB, r4
613 movi CONFIG_CACHED_MEMORY_OFFSET, r6
618 rte ! -> handle_exception, switch back to priv mode again
620 LRESVEC_block_end: /* Marker. Unused. */
625 * Second level handler for VBR-based exceptions. Pre-handler.
626 * In common to all stack-frame sensitive handlers.
629 * (KCR0) Current [current task union]
632 * (r3) appropriate return address
633 * (r4) Event (0 = interrupt, 1 = TLB miss fault, 2 = Not TLB miss fault, 3=debug)
634 * (r5) Pointer to reg_save_area
637 * Available registers:
644 /* Common 2nd level handler. */
646 /* First thing we need an appropriate stack pointer */
651 bne r6, ZERO, tr0 /* Original stack pointer is fine */
653 /* Set stack pointer for user fault */
655 movi THREAD_SIZE, r6 /* Point to the end */
660 /* DEBUG : check for underflow/overflow of the kernel stack */
661 pta no_underflow, tr0
665 bge SP, r6, tr0 ! ? below 1k from bottom of stack : danger zone
667 /* Just panic to cause a crash. */
675 movi THREAD_SIZE, r18
677 bgt SP, r6, tr0 ! sp above the stack
679 /* Make some room for the BASIC frame. */
680 movi -(FRAME_SIZE), r6
683 /* Could do this with no stalling if we had another spare register, but the
684 code below will be OK. */
685 ld.q r5, SAVED_R2, r6
686 ld.q r5, SAVED_R3, r18
687 st.q SP, FRAME_R(2), r6
688 ld.q r5, SAVED_R4, r6
689 st.q SP, FRAME_R(3), r18
690 ld.q r5, SAVED_R5, r18
691 st.q SP, FRAME_R(4), r6
692 ld.q r5, SAVED_R6, r6
693 st.q SP, FRAME_R(5), r18
694 ld.q r5, SAVED_R18, r18
695 st.q SP, FRAME_R(6), r6
696 ld.q r5, SAVED_TR0, r6
697 st.q SP, FRAME_R(18), r18
698 st.q SP, FRAME_T(0), r6
700 /* Keep old SP around */
703 /* Save the rest of the general purpose registers */
704 st.q SP, FRAME_R(0), r0
705 st.q SP, FRAME_R(1), r1
706 st.q SP, FRAME_R(7), r7
707 st.q SP, FRAME_R(8), r8
708 st.q SP, FRAME_R(9), r9
709 st.q SP, FRAME_R(10), r10
710 st.q SP, FRAME_R(11), r11
711 st.q SP, FRAME_R(12), r12
712 st.q SP, FRAME_R(13), r13
713 st.q SP, FRAME_R(14), r14
715 /* SP is somewhere else */
716 st.q SP, FRAME_R(15), r6
718 st.q SP, FRAME_R(16), r16
719 st.q SP, FRAME_R(17), r17
720 /* r18 is saved earlier. */
721 st.q SP, FRAME_R(19), r19
722 st.q SP, FRAME_R(20), r20
723 st.q SP, FRAME_R(21), r21
724 st.q SP, FRAME_R(22), r22
725 st.q SP, FRAME_R(23), r23
726 st.q SP, FRAME_R(24), r24
727 st.q SP, FRAME_R(25), r25
728 st.q SP, FRAME_R(26), r26
729 st.q SP, FRAME_R(27), r27
730 st.q SP, FRAME_R(28), r28
731 st.q SP, FRAME_R(29), r29
732 st.q SP, FRAME_R(30), r30
733 st.q SP, FRAME_R(31), r31
734 st.q SP, FRAME_R(32), r32
735 st.q SP, FRAME_R(33), r33
736 st.q SP, FRAME_R(34), r34
737 st.q SP, FRAME_R(35), r35
738 st.q SP, FRAME_R(36), r36
739 st.q SP, FRAME_R(37), r37
740 st.q SP, FRAME_R(38), r38
741 st.q SP, FRAME_R(39), r39
742 st.q SP, FRAME_R(40), r40
743 st.q SP, FRAME_R(41), r41
744 st.q SP, FRAME_R(42), r42
745 st.q SP, FRAME_R(43), r43
746 st.q SP, FRAME_R(44), r44
747 st.q SP, FRAME_R(45), r45
748 st.q SP, FRAME_R(46), r46
749 st.q SP, FRAME_R(47), r47
750 st.q SP, FRAME_R(48), r48
751 st.q SP, FRAME_R(49), r49
752 st.q SP, FRAME_R(50), r50
753 st.q SP, FRAME_R(51), r51
754 st.q SP, FRAME_R(52), r52
755 st.q SP, FRAME_R(53), r53
756 st.q SP, FRAME_R(54), r54
757 st.q SP, FRAME_R(55), r55
758 st.q SP, FRAME_R(56), r56
759 st.q SP, FRAME_R(57), r57
760 st.q SP, FRAME_R(58), r58
761 st.q SP, FRAME_R(59), r59
762 st.q SP, FRAME_R(60), r60
763 st.q SP, FRAME_R(61), r61
764 st.q SP, FRAME_R(62), r62
767 * Save the S* registers.
770 st.q SP, FRAME_S(FSSR), r61
772 st.q SP, FRAME_S(FSPC), r62
773 movi -1, r62 /* Reset syscall_nr */
774 st.q SP, FRAME_S(FSYSCALL_ID), r62
776 /* Save the rest of the target registers */
778 st.q SP, FRAME_T(1), r6
780 st.q SP, FRAME_T(2), r6
782 st.q SP, FRAME_T(3), r6
784 st.q SP, FRAME_T(4), r6
786 st.q SP, FRAME_T(5), r6
788 st.q SP, FRAME_T(6), r6
790 st.q SP, FRAME_T(7), r6
792 ! setup FP so that unwinder can wind back through nested kernel mode
796 #ifdef CONFIG_POOR_MANS_STRACE
797 /* We've pushed all the registers now, so only r2-r4 hold anything
798 * useful. Move them into callee save registers */
803 /* Preserve r2 as the event code */
817 /* For syscall and debug race condition, get TRA now */
820 /* We are in a safe position to turn SR.BL off, but set IMASK=0xf
821 * Also set FD, to catch FPU usage in the kernel.
823 * benedict.gaster@superh.com 29/07/2002
825 * On all SH5-101 revisions it is unsafe to raise the IMASK and at the
826 * same time change BL from 1->0, as any pending interrupt of a level
827 * higher than he previous value of IMASK will leak through and be
828 * taken unexpectedly.
830 * To avoid this we raise the IMASK and then issue another PUTCON to
834 movi SR_IMASK | SR_FD, r7
837 movi SR_UNBLOCK_EXC, r7
842 /* Now call the appropriate 3rd level handler */
853 * Second level handler for VBR-based exceptions. Post-handlers.
855 * Post-handlers for interrupts (ret_from_irq), exceptions
856 * (ret_from_exception) and common reentrance doors (restore_all
857 * to get back to the original context, ret_from_syscall loop to
858 * check kernel exiting).
860 * ret_with_reschedule and work_notifysig are an inner lables of
861 * the ret_from_syscall loop.
863 * In common to all stack-frame sensitive handlers.
866 * (SP) struct pt_regs *, original register's frame pointer (basic)
871 #ifdef CONFIG_POOR_MANS_STRACE
872 pta evt_debug_ret_from_irq, tr0
876 ld.q SP, FRAME_S(FSSR), r6
879 pta resume_kernel, tr0
880 bne r6, ZERO, tr0 /* no further checks */
882 pta ret_with_reschedule, tr0
883 blink tr0, ZERO /* Do not check softirqs */
885 .global ret_from_exception
889 #ifdef CONFIG_POOR_MANS_STRACE
890 pta evt_debug_ret_from_exc, tr0
895 ld.q SP, FRAME_S(FSSR), r6
898 pta resume_kernel, tr0
899 bne r6, ZERO, tr0 /* no further checks */
903 #ifdef CONFIG_PREEMPT
904 pta ret_from_syscall, tr0
911 ld.l r6, TI_PRE_COUNT, r7
915 ld.l r6, TI_FLAGS, r7
916 movi (1 << TIF_NEED_RESCHED), r8
924 movi ((PREEMPT_ACTIVE >> 16) & 65535), r8
925 shori (PREEMPT_ACTIVE & 65535), r8
926 st.l r6, TI_PRE_COUNT, r8
934 st.l r6, TI_PRE_COUNT, ZERO
937 pta need_resched, tr1
941 .global ret_from_syscall
945 getcon KCR0, r6 ! r6 contains current_thread_info
946 ld.l r6, TI_FLAGS, r7 ! r7 contains current_thread_info->flags
949 ! no handling of TIF_SYSCALL_TRACE yet!!
951 movi (1 << TIF_NEED_RESCHED), r8
953 pta work_resched, tr0
958 movi (1 << TIF_SIGPENDING), r8
960 pta work_notifysig, tr0
966 pta ret_from_syscall, tr0
970 blink tr0, ZERO /* Call schedule(), return on top */
979 blink tr0, LINK /* Call do_signal(regs, 0), return here */
984 ld.q SP, FRAME_T(0), r6
985 ld.q SP, FRAME_T(1), r7
986 ld.q SP, FRAME_T(2), r8
987 ld.q SP, FRAME_T(3), r9
992 ld.q SP, FRAME_T(4), r6
993 ld.q SP, FRAME_T(5), r7
994 ld.q SP, FRAME_T(6), r8
995 ld.q SP, FRAME_T(7), r9
1001 ld.q SP, FRAME_R(0), r0
1002 ld.q SP, FRAME_R(1), r1
1003 ld.q SP, FRAME_R(2), r2
1004 ld.q SP, FRAME_R(3), r3
1005 ld.q SP, FRAME_R(4), r4
1006 ld.q SP, FRAME_R(5), r5
1007 ld.q SP, FRAME_R(6), r6
1008 ld.q SP, FRAME_R(7), r7
1009 ld.q SP, FRAME_R(8), r8
1010 ld.q SP, FRAME_R(9), r9
1011 ld.q SP, FRAME_R(10), r10
1012 ld.q SP, FRAME_R(11), r11
1013 ld.q SP, FRAME_R(12), r12
1014 ld.q SP, FRAME_R(13), r13
1015 ld.q SP, FRAME_R(14), r14
1017 ld.q SP, FRAME_R(16), r16
1018 ld.q SP, FRAME_R(17), r17
1019 ld.q SP, FRAME_R(18), r18
1020 ld.q SP, FRAME_R(19), r19
1021 ld.q SP, FRAME_R(20), r20
1022 ld.q SP, FRAME_R(21), r21
1023 ld.q SP, FRAME_R(22), r22
1024 ld.q SP, FRAME_R(23), r23
1025 ld.q SP, FRAME_R(24), r24
1026 ld.q SP, FRAME_R(25), r25
1027 ld.q SP, FRAME_R(26), r26
1028 ld.q SP, FRAME_R(27), r27
1029 ld.q SP, FRAME_R(28), r28
1030 ld.q SP, FRAME_R(29), r29
1031 ld.q SP, FRAME_R(30), r30
1032 ld.q SP, FRAME_R(31), r31
1033 ld.q SP, FRAME_R(32), r32
1034 ld.q SP, FRAME_R(33), r33
1035 ld.q SP, FRAME_R(34), r34
1036 ld.q SP, FRAME_R(35), r35
1037 ld.q SP, FRAME_R(36), r36
1038 ld.q SP, FRAME_R(37), r37
1039 ld.q SP, FRAME_R(38), r38
1040 ld.q SP, FRAME_R(39), r39
1041 ld.q SP, FRAME_R(40), r40
1042 ld.q SP, FRAME_R(41), r41
1043 ld.q SP, FRAME_R(42), r42
1044 ld.q SP, FRAME_R(43), r43
1045 ld.q SP, FRAME_R(44), r44
1046 ld.q SP, FRAME_R(45), r45
1047 ld.q SP, FRAME_R(46), r46
1048 ld.q SP, FRAME_R(47), r47
1049 ld.q SP, FRAME_R(48), r48
1050 ld.q SP, FRAME_R(49), r49
1051 ld.q SP, FRAME_R(50), r50
1052 ld.q SP, FRAME_R(51), r51
1053 ld.q SP, FRAME_R(52), r52
1054 ld.q SP, FRAME_R(53), r53
1055 ld.q SP, FRAME_R(54), r54
1056 ld.q SP, FRAME_R(55), r55
1057 ld.q SP, FRAME_R(56), r56
1058 ld.q SP, FRAME_R(57), r57
1059 ld.q SP, FRAME_R(58), r58
1062 movi SR_BLOCK_EXC, r60
1064 putcon r59, SR /* SR.BL = 1, keep nesting out */
1065 ld.q SP, FRAME_S(FSSR), r61
1066 ld.q SP, FRAME_S(FSPC), r62
1067 movi SR_ASID_MASK, r60
1069 andc r61, r60, r61 /* Clear out older ASID */
1070 or r59, r61, r61 /* Retain current ASID */
1074 /* Ignore FSYSCALL_ID */
1076 ld.q SP, FRAME_R(59), r59
1077 ld.q SP, FRAME_R(60), r60
1078 ld.q SP, FRAME_R(61), r61
1079 ld.q SP, FRAME_R(62), r62
1082 ld.q SP, FRAME_R(15), SP
1087 * Third level handlers for VBR-based exceptions. Adapting args to
1088 * and/or deflecting to fourth level handlers.
1090 * Fourth level handlers interface.
1091 * Most are C-coded handlers directly pointed by the trap_jtable.
1092 * (Third = Fourth level)
1094 * (r2) fault/interrupt code, entry number (e.g. NMI = 14,
1095 * IRL0-3 (0000) = 16, RTLBMISS = 2, SYSCALL = 11, etc ...)
1096 * (r3) struct pt_regs *, original register's frame pointer
1097 * (r4) Event (0 = interrupt, 1 = TLB miss fault, 2 = Not TLB miss fault)
1098 * (r5) TRA control register (for syscall/debug benefit only)
1099 * (LINK) return address
1102 * Kernel TLB fault handlers will get a slightly different interface.
1103 * (r2) struct pt_regs *, original register's frame pointer
1104 * (r3) writeaccess, whether it's a store fault as opposed to load fault
1105 * (r4) execaccess, whether it's a ITLB fault as opposed to DTLB fault
1106 * (r5) Effective Address of fault
1107 * (LINK) return address
1110 * fpu_error_or_IRQ? is a helper to deflect to the right cause.
1115 or ZERO, ZERO, r3 /* Read */
1116 or ZERO, ZERO, r4 /* Data */
1118 pta call_do_page_fault, tr0
1123 movi 1, r3 /* Write */
1124 or ZERO, ZERO, r4 /* Data */
1126 pta call_do_page_fault, tr0
1131 beqi/u r4, EVENT_INTERRUPT, tr0
1133 or ZERO, ZERO, r3 /* Read */
1134 movi 1, r4 /* Text */
1139 movi do_page_fault, r6
1145 beqi/l r4, EVENT_INTERRUPT, tr0
1146 #ifdef CONFIG_SH_FPU
1147 movi do_fpu_state_restore, r6
1149 movi do_exception_error, r6
1156 beqi/l r4, EVENT_INTERRUPT, tr0
1157 #ifdef CONFIG_SH_FPU
1158 movi do_fpu_state_restore, r6
1160 movi do_exception_error, r6
1171 * system_call/unknown_trap third level handler:
1174 * (r2) fault/interrupt code, entry number (TRAP = 11)
1175 * (r3) struct pt_regs *, original register's frame pointer
1176 * (r4) Not used. Event (0=interrupt, 1=TLB miss fault, 2=Not TLB miss fault)
1177 * (r5) TRA Control Reg (0x00xyzzzz: x=1 SYSCALL, y = #args, z=nr)
1179 * (LINK) return address: ret_from_exception
1180 * (*r3) Syscall parms: SC#, arg0, arg1, ..., arg5 in order (Saved r2/r7)
1183 * (*r3) Syscall reply (Saved r2)
1184 * (LINK) In case of syscall only it can be scrapped.
1185 * Common second level post handler will be ret_from_syscall.
1186 * Common (non-trace) exit point to that is syscall_ret (saving
1187 * result to r2). Common bad exit point is syscall_bad (returning
1188 * ENOSYS then saved to r2).
1193 /* Unknown Trap or User Trace */
1194 movi do_unknown_trapa, r6
1196 ld.q r3, FRAME_R(9), r2 /* r2 = #arg << 16 | syscall # */
1197 andi r2, 0x1ff, r2 /* r2 = syscall # */
1200 pta syscall_ret, tr0
1203 /* New syscall implementation*/
1205 pta unknown_trap, tr0
1206 or r5, ZERO, r4 /* TRA (=r5) -> r4 */
1208 bnei r4, 1, tr0 /* unknown_trap if not 0x1yzzzz */
1210 /* It's a system call */
1211 st.q r3, FRAME_S(FSYSCALL_ID), r5 /* ID (0x1yzzzz) -> stack */
1212 andi r5, 0x1ff, r5 /* syscall # -> r5 */
1216 pta syscall_allowed, tr0
1217 movi NR_syscalls - 1, r4 /* Last valid */
1221 /* Return ENOSYS ! */
1222 movi -(ENOSYS), r2 /* Fall-through */
1226 st.q SP, FRAME_R(9), r2 /* Expecting SP back to BASIC frame */
1228 #ifdef CONFIG_POOR_MANS_STRACE
1229 /* nothing useful in registers at this point */
1234 ld.q SP, FRAME_R(9), r2
1239 ld.q SP, FRAME_S(FSPC), r2
1240 addi r2, 4, r2 /* Move PC, being pre-execution event */
1241 st.q SP, FRAME_S(FSPC), r2
1242 pta ret_from_syscall, tr0
1246 /* A different return path for ret_from_fork, because we now need
1247 * to call schedule_tail with the later kernels. Because prev is
1248 * loaded into r2 by switch_to() means we can just call it straight away
1251 .global ret_from_fork
1254 movi schedule_tail,r5
1259 #ifdef CONFIG_POOR_MANS_STRACE
1260 /* nothing useful in registers at this point */
1265 ld.q SP, FRAME_R(9), r2
1270 ld.q SP, FRAME_S(FSPC), r2
1271 addi r2, 4, r2 /* Move PC, being pre-execution event */
1272 st.q SP, FRAME_S(FSPC), r2
1273 pta ret_from_syscall, tr0
1279 /* Use LINK to deflect the exit point, default is syscall_ret */
1280 pta syscall_ret, tr0
1282 pta syscall_notrace, tr0
1285 ld.l r2, TI_FLAGS, r4
1286 movi (1 << TIF_SYSCALL_TRACE), r6
1290 /* Trace it by calling syscall_trace before and after */
1291 movi syscall_trace, r4
1294 /* Reload syscall number as r5 is trashed by syscall_trace */
1295 ld.q SP, FRAME_S(FSYSCALL_ID), r5
1298 pta syscall_ret_trace, tr0
1302 /* Now point to the appropriate 4th level syscall handler */
1303 movi sys_call_table, r4
1308 /* Prepare original args */
1309 ld.q SP, FRAME_R(2), r2
1310 ld.q SP, FRAME_R(3), r3
1311 ld.q SP, FRAME_R(4), r4
1312 ld.q SP, FRAME_R(5), r5
1313 ld.q SP, FRAME_R(6), r6
1314 ld.q SP, FRAME_R(7), r7
1316 /* And now the trick for those syscalls requiring regs * ! */
1320 blink tr0, ZERO /* LINK is already properly set */
1323 /* We get back here only if under trace */
1324 st.q SP, FRAME_R(9), r2 /* Save return value */
1326 movi syscall_trace, LINK
1330 /* This needs to be done after any syscall tracing */
1331 ld.q SP, FRAME_S(FSPC), r2
1332 addi r2, 4, r2 /* Move PC, being pre-execution event */
1333 st.q SP, FRAME_S(FSPC), r2
1335 pta ret_from_syscall, tr0
1336 blink tr0, ZERO /* Resume normal return sequence */
1339 * --- Switch to running under a particular ASID and return the previous ASID value
1340 * --- The caller is assumed to have done a cli before calling this.
1342 * Input r2 : new ASID
1343 * Output r2 : old ASID
1346 .global switch_and_save_asid
1347 switch_and_save_asid:
1350 shlli r4, 16, r4 /* r4 = mask to select ASID */
1351 and r0, r4, r3 /* r3 = shifted old ASID */
1352 andi r2, 255, r2 /* mask down new ASID */
1353 shlli r2, 16, r2 /* align new ASID against SR.ASID */
1354 andc r0, r4, r0 /* efface old ASID from SR */
1355 or r0, r2, r0 /* insert the new ASID */
1363 shlri r3, 16, r2 /* r2 = old ASID */
1366 .global route_to_panic_handler
1367 route_to_panic_handler:
1368 /* Switch to real mode, goto panic_handler, don't return. Useful for
1369 last-chance debugging, e.g. if no output wants to go to the console.
1372 movi panic_handler - CONFIG_CACHED_MEMORY_OFFSET, r1
1384 1: /* Now in real mode */
1388 .global peek_real_address_q
1389 peek_real_address_q:
1391 r2 : real mode address to peek
1392 r2(out) : result quadword
1394 This is provided as a cheapskate way of manipulating device
1395 registers for debugging (to avoid the need to onchip_remap the debug
1396 module, and to avoid the need to onchip_remap the watchpoint
1397 controller in a way that identity maps sufficient bits to avoid the
1398 SH5-101 cut2 silicon defect).
1400 This code is not performance critical
1403 add.l r2, r63, r2 /* sign extend address */
1404 getcon sr, r0 /* r0 = saved original SR */
1407 or r0, r1, r1 /* r0 with block bit set */
1408 putcon r1, sr /* now in critical section */
1411 andc r1, r36, r1 /* turn sr.mmu off in real mode section */
1414 movi .peek0 - CONFIG_CACHED_MEMORY_OFFSET, r36 /* real mode target address */
1415 movi 1f, r37 /* virtual mode return addr */
1422 .peek0: /* come here in real mode, don't touch caches!!
1423 still in critical section (sr.bl==1) */
1426 /* Here's the actual peek. If the address is bad, all bets are now off
1427 * what will happen (handlers invoked in real-mode = bad news) */
1430 rte /* Back to virtual mode */
1437 .global poke_real_address_q
1438 poke_real_address_q:
1440 r2 : real mode address to poke
1441 r3 : quadword value to write.
1443 This is provided as a cheapskate way of manipulating device
1444 registers for debugging (to avoid the need to onchip_remap the debug
1445 module, and to avoid the need to onchip_remap the watchpoint
1446 controller in a way that identity maps sufficient bits to avoid the
1447 SH5-101 cut2 silicon defect).
1449 This code is not performance critical
1452 add.l r2, r63, r2 /* sign extend address */
1453 getcon sr, r0 /* r0 = saved original SR */
1456 or r0, r1, r1 /* r0 with block bit set */
1457 putcon r1, sr /* now in critical section */
1460 andc r1, r36, r1 /* turn sr.mmu off in real mode section */
1463 movi .poke0-CONFIG_CACHED_MEMORY_OFFSET, r36 /* real mode target address */
1464 movi 1f, r37 /* virtual mode return addr */
1471 .poke0: /* come here in real mode, don't touch caches!!
1472 still in critical section (sr.bl==1) */
1475 /* Here's the actual poke. If the address is bad, all bets are now off
1476 * what will happen (handlers invoked in real-mode = bad news) */
1479 rte /* Back to virtual mode */
1487 * --- User Access Handling Section
1491 * User Access support. It all moved to non inlined Assembler
1492 * functions in here.
1494 * __kernel_size_t __copy_user(void *__to, const void *__from,
1495 * __kernel_size_t __n)
1498 * (r2) target address
1499 * (r3) source address
1500 * (r4) size in bytes
1504 * (r2) non-copied bytes
1506 * If a fault occurs on the user pointer, bail out early and return the
1507 * number of bytes not copied in r2.
1508 * Strategy : for large blocks, call a real memcpy function which can
1509 * move >1 byte at a time using unaligned ld/st instructions, and can
1510 * manipulate the cache using prefetch + alloco to improve the speed
1511 * further. If a fault occurs in that function, just revert to the
1512 * byte-by-byte approach used for small blocks; this is rare so the
1513 * performance hit for that case does not matter.
1515 * For small blocks it's not worth the overhead of setting up and calling
1516 * the memcpy routine; do the copy a byte at a time.
1521 pta __copy_user_byte_by_byte, tr1
1522 movi 16, r0 ! this value is a best guess, should tune it by benchmarking
1524 pta copy_user_memcpy, tr0
1526 /* Save arguments in case we have to fix-up unhandled page fault */
1530 st.q SP, 24, r35 ! r35 is callee-save
1531 /* Save LINK in a register to reduce RTS time later (otherwise
1532 ld SP,*,LINK;ptabs LINK;trn;blink trn,r63 becomes a critical path) */
1536 /* Copy completed normally if we get back here */
1539 /* don't restore r2-r4, pointless */
1540 /* set result=r2 to zero as the copy must have succeeded. */
1543 blink tr0, r63 ! RTS
1545 .global __copy_user_fixup
1547 /* Restore stack frame */
1554 /* Fall through to original code, in the 'same' state we entered with */
1556 /* The slow byte-by-byte method is used if the fast copy traps due to a bad
1557 user address. In that rare case, the speed drop can be tolerated. */
1558 __copy_user_byte_by_byte:
1559 pta ___copy_user_exit, tr1
1560 pta ___copy_user1, tr0
1561 beq/u r4, r63, tr1 /* early exit for zero length copy */
1566 ld.b r3, 0, r5 /* Fault address 1 */
1568 /* Could rewrite this to use just 1 add, but the second comes 'free'
1569 due to load latency */
1571 addi r4, -1, r4 /* No real fixup required */
1573 stx.b r3, r0, r5 /* Fault address 2 */
1582 * __kernel_size_t __clear_user(void *addr, __kernel_size_t size)
1585 * (r2) target address
1586 * (r3) size in bytes
1589 * (*r2) zero-ed target data
1590 * (r2) non-zero-ed bytes
1592 .global __clear_user
1594 pta ___clear_user_exit, tr1
1595 pta ___clear_user1, tr0
1599 st.b r2, 0, ZERO /* Fault address */
1601 addi r3, -1, r3 /* No real fixup required */
1611 * int __strncpy_from_user(unsigned long __dest, unsigned long __src,
1615 * (r2) target address
1616 * (r3) source address
1617 * (r4) maximum size in bytes
1621 * (r2) -EFAULT (in case of faulting)
1622 * copied data (otherwise)
1624 .global __strncpy_from_user
1625 __strncpy_from_user:
1626 pta ___strncpy_from_user1, tr0
1627 pta ___strncpy_from_user_done, tr1
1628 or r4, ZERO, r5 /* r5 = original count */
1629 beq/u r4, r63, tr1 /* early exit if r4==0 */
1630 movi -(EFAULT), r6 /* r6 = reply, no real fixup */
1631 or ZERO, ZERO, r7 /* r7 = data, clear top byte of data */
1633 ___strncpy_from_user1:
1634 ld.b r3, 0, r7 /* Fault address: only in reading */
1639 addi r4, -1, r4 /* return real number of copied bytes */
1642 ___strncpy_from_user_done:
1643 sub r5, r4, r6 /* If done, return copied */
1645 ___strncpy_from_user_exit:
1651 * extern long __strnlen_user(const char *__s, long __n)
1654 * (r2) source address
1655 * (r3) source size in bytes
1658 * (r2) -EFAULT (in case of faulting)
1659 * string length (otherwise)
1661 .global __strnlen_user
1663 pta ___strnlen_user_set_reply, tr0
1664 pta ___strnlen_user1, tr1
1665 or ZERO, ZERO, r5 /* r5 = counter */
1666 movi -(EFAULT), r6 /* r6 = reply, no real fixup */
1667 or ZERO, ZERO, r7 /* r7 = data, clear top byte of data */
1671 ldx.b r2, r5, r7 /* Fault address: only in reading */
1672 addi r3, -1, r3 /* No real fixup */
1676 ! The line below used to be active. This meant led to a junk byte lying between each pair
1677 ! of entries in the argv & envp structures in memory. Whilst the program saw the right data
1678 ! via the argv and envp arguments to main, it meant the 'flat' representation visible through
1679 ! /proc/$pid/cmdline was corrupt, causing trouble with ps, for example.
1680 ! addi r5, 1, r5 /* Include '\0' */
1682 ___strnlen_user_set_reply:
1683 or r5, ZERO, r6 /* If done, return counter */
1685 ___strnlen_user_exit:
1691 * extern long __get_user_asm_?(void *val, long addr)
1695 * (r3) source address (in User Space)
1698 * (r2) -EFAULT (faulting)
1701 .global __get_user_asm_b
1704 movi -(EFAULT), r2 /* r2 = reply, no real fixup */
1707 ld.b r3, 0, r5 /* r5 = data */
1711 ___get_user_asm_b_exit:
1716 .global __get_user_asm_w
1719 movi -(EFAULT), r2 /* r2 = reply, no real fixup */
1722 ld.w r3, 0, r5 /* r5 = data */
1726 ___get_user_asm_w_exit:
1731 .global __get_user_asm_l
1734 movi -(EFAULT), r2 /* r2 = reply, no real fixup */
1737 ld.l r3, 0, r5 /* r5 = data */
1741 ___get_user_asm_l_exit:
1746 .global __get_user_asm_q
1749 movi -(EFAULT), r2 /* r2 = reply, no real fixup */
1752 ld.q r3, 0, r5 /* r5 = data */
1756 ___get_user_asm_q_exit:
1761 * extern long __put_user_asm_?(void *pval, long addr)
1764 * (r2) kernel pointer to value
1765 * (r3) dest address (in User Space)
1768 * (r2) -EFAULT (faulting)
1771 .global __put_user_asm_b
1773 ld.b r2, 0, r4 /* r4 = data */
1774 movi -(EFAULT), r2 /* r2 = reply, no real fixup */
1780 ___put_user_asm_b_exit:
1785 .global __put_user_asm_w
1787 ld.w r2, 0, r4 /* r4 = data */
1788 movi -(EFAULT), r2 /* r2 = reply, no real fixup */
1794 ___put_user_asm_w_exit:
1799 .global __put_user_asm_l
1801 ld.l r2, 0, r4 /* r4 = data */
1802 movi -(EFAULT), r2 /* r2 = reply, no real fixup */
1808 ___put_user_asm_l_exit:
1813 .global __put_user_asm_q
1815 ld.q r2, 0, r4 /* r4 = data */
1816 movi -(EFAULT), r2 /* r2 = reply, no real fixup */
1822 ___put_user_asm_q_exit:
1827 /* The idea is : when we get an unhandled panic, we dump the registers
1828 to a known memory location, the just sit in a tight loop.
1829 This allows the human to look at the memory region through the GDB
1830 session (assuming the debug module's SHwy initiator isn't locked up
1831 or anything), to hopefully analyze the cause of the panic. */
1833 /* On entry, former r15 (SP) is in DCR
1834 former r0 is at resvec_saved_area + 0
1835 former r1 is at resvec_saved_area + 8
1836 former tr0 is at resvec_saved_area + 32
1837 DCR is the only register whose value is lost altogether.
1840 movi 0xffffffff80000000, r0 ! phy of dump area
1841 ld.q SP, 0x000, r1 ! former r0
1843 ld.q SP, 0x008, r1 ! former r1
1907 st.q r0, 0x1f8, r63 ! bogus, but for consistency's sake...
1909 ld.q SP, 0x020, r1 ! former tr0
1959 /* Prepare to jump to C - physical address */
1960 movi panic_handler-CONFIG_CACHED_MEMORY_OFFSET, r1
1974 * --- Signal Handling Section
1978 * extern long long _sa_default_rt_restorer
1979 * extern long long _sa_default_restorer
1983 * extern void _sa_default_rt_restorer(void)
1984 * extern void _sa_default_restorer(void)
1986 * Code prototypes to do a sys_rt_sigreturn() or sys_sysreturn()
1987 * from user space. Copied into user space by signal management.
1988 * Both must be quad aligned and 2 quad long (4 instructions).
1992 .global sa_default_rt_restorer
1993 sa_default_rt_restorer:
1995 shori __NR_rt_sigreturn, r9
2000 .global sa_default_restorer
2001 sa_default_restorer:
2003 shori __NR_sigreturn, r9
2008 * --- __ex_table Section
2012 * User Access Exception Table.
2014 .section __ex_table, "a"
2016 .global asm_uaccess_start /* Just a marker */
2019 .long ___copy_user1, ___copy_user_exit
2020 .long ___copy_user2, ___copy_user_exit
2021 .long ___clear_user1, ___clear_user_exit
2022 .long ___strncpy_from_user1, ___strncpy_from_user_exit
2023 .long ___strnlen_user1, ___strnlen_user_exit
2024 .long ___get_user_asm_b1, ___get_user_asm_b_exit
2025 .long ___get_user_asm_w1, ___get_user_asm_w_exit
2026 .long ___get_user_asm_l1, ___get_user_asm_l_exit
2027 .long ___get_user_asm_q1, ___get_user_asm_q_exit
2028 .long ___put_user_asm_b1, ___put_user_asm_b_exit
2029 .long ___put_user_asm_w1, ___put_user_asm_w_exit
2030 .long ___put_user_asm_l1, ___put_user_asm_l_exit
2031 .long ___put_user_asm_q1, ___put_user_asm_q_exit
2033 .global asm_uaccess_end /* Just a marker */
2040 * --- .text.init Section
2043 .section .text.init, "ax"
2046 * void trap_init (void)
2051 addi SP, -24, SP /* Room to save r28/r29/r30 */
2056 /* Set VBR and RESVEC */
2057 movi LVBR_block, r19
2058 andi r19, -4, r19 /* reset MMUOFF + reserved */
2059 /* For RESVEC exceptions we force the MMU off, which means we need the
2060 physical address. */
2061 movi LRESVEC_block-CONFIG_CACHED_MEMORY_OFFSET, r20
2062 andi r20, -4, r20 /* reset reserved */
2063 ori r20, 1, r20 /* set MMUOFF */
2068 movi LVBR_block_end, r21
2070 movi BLOCK_SIZE, r29 /* r29 = expected size */
2075 * Ugly, but better loop forever now than crash afterwards.
2076 * We should print a message, but if we touch LVBR or
2077 * LRESVEC blocks we should not be surprised if we get stuck
2080 pta trap_init_loop, tr1
2081 gettr tr1, r28 /* r28 = trap_init_loop */
2082 sub r21, r30, r30 /* r30 = actual size */
2085 * VBR/RESVEC handlers overlap by being bigger than
2086 * allowed. Very bad. Just loop forever.
2087 * (r28) panic/loop address
2088 * (r29) expected size
2094 /* Now that exception vectors are set up reset SR.BL */
2096 movi SR_UNBLOCK_EXC, r23