📄 entry.s
字号:
movi resvec_save_area, SP ld.q SP, 24, r0 putcon r0, SSR ld.q SP, 16, r0 putcon r0, SPC ld.q SP, 0, r0 ld.q SP, 8, r1 /* Save other original registers into reg_save_area */ movi reg_save_area, SP st.q SP, SAVED_R2, r2 st.q SP, SAVED_R3, r3 st.q SP, SAVED_R4, r4 st.q SP, SAVED_R5, r5 st.q SP, SAVED_R6, r6 st.q SP, SAVED_R18, r18 gettr tr0, r3 st.q SP, SAVED_TR0, r3 /* Set args for debug class handler */ getcon EXPEVT, r2 movi ret_from_exception, r3 ori r3, 1, r3 movi EVENT_DEBUG, r4 or SP, ZERO, r5 getcon KCR1, SP pta handle_exception, tr0 blink tr0, ZERO .balign 256debug_interrupt: /* !!! WE COME HERE IN REAL MODE !!! */ /* Hook-up debug interrupt to allow various debugging options to be * hooked into its handler. */ /* Save original stack pointer into KCR1 */ synco putcon SP, KCR1 movi resvec_save_area-CONFIG_CACHED_MEMORY_OFFSET, SP ocbp SP, 0 ocbp SP, 32 synco /* Save other original registers into reg_save_area thru real addresses */ st.q SP, SAVED_R2, r2 st.q SP, SAVED_R3, r3 st.q SP, SAVED_R4, r4 st.q SP, SAVED_R5, r5 st.q SP, SAVED_R6, r6 st.q SP, SAVED_R18, r18 gettr tr0, r3 st.q SP, SAVED_TR0, r3 /* move (spc,ssr)->(pspc,pssr). The rte will shift them back again, so that they look like the originals as far as the real handler code is concerned. */ getcon spc, r6 putcon r6, pspc getcon ssr, r6 putcon r6, pssr ! construct useful SR for handle_exception movi 3, r6 shlli r6, 30, r6 getcon sr, r18 or r18, r6, r6 putcon r6, ssr ! SSR is now the current SR with the MD and MMU bits set ! i.e. the rte will switch back to priv mode and put ! the mmu back on ! construct spc movi handle_exception, r18 ori r18, 1, r18 ! for safety (do we need this?) putcon r18, spc /* Set args for Non-debug, Not a TLB miss class handler */ ! EXPEVT==0x80 is unused, so 'steal' this value to put the ! debug interrupt handler in the vectoring table movi 0x80, r2 movi ret_from_exception, r3 ori r3, 1, r3 movi EVENT_FAULT_NOT_TLB, r4 or SP, ZERO, r5 movi CONFIG_CACHED_MEMORY_OFFSET, r6 add r6, r5, r5 getcon KCR1, SP synco ! for safety rte ! -> handle_exception, switch back to priv mode againLRESVEC_block_end: /* Marker. Unused. */ .balign TEXT_SIZE/* * Second level handler for VBR-based exceptions. Pre-handler. * In common to all stack-frame sensitive handlers. * * Inputs: * (KCR0) Current [current task union] * (KCR1) Original SP * (r2) INTEVT/EXPEVT * (r3) appropriate return address * (r4) Event (0 = interrupt, 1 = TLB miss fault, 2 = Not TLB miss fault, 3=debug) * (r5) Pointer to reg_save_area * (SP) Original SP * * Available registers: * (r6) * (r18) * (tr0) * */handle_exception: /* Common 2nd level handler. */ /* First thing we need an appropriate stack pointer */ getcon SSR, r6 shlri r6, 30, r6 andi r6, 1, r6 pta stack_ok, tr0 bne r6, ZERO, tr0 /* Original stack pointer is fine */ /* Set stack pointer for user fault */ getcon KCR0, SP movi THREAD_SIZE, r6 /* Point to the end */ add SP, r6, SPstack_ok:/* DEBUG : check for underflow/overflow of the kernel stack */ pta no_underflow, tr0 getcon KCR0, r6 movi 1024, r18 add r6, r18, r6 bge SP, r6, tr0 ! ? below 1k from bottom of stack : danger zone/* Just panic to cause a crash. */bad_sp: ld.b r63, 0, r6 nopno_underflow: pta bad_sp, tr0 getcon kcr0, r6 movi THREAD_SIZE, r18 add r18, r6, r6 bgt SP, r6, tr0 ! sp above the stack /* Make some room for the BASIC frame. */ movi -(FRAME_SIZE), r6 add SP, r6, SP/* Could do this with no stalling if we had another spare register, but the code below will be OK. */ ld.q r5, SAVED_R2, r6 ld.q r5, SAVED_R3, r18 st.q SP, FRAME_R(2), r6 ld.q r5, SAVED_R4, r6 st.q SP, FRAME_R(3), r18 ld.q r5, SAVED_R5, r18 st.q SP, FRAME_R(4), r6 ld.q r5, SAVED_R6, r6 st.q SP, FRAME_R(5), r18 ld.q r5, SAVED_R18, r18 st.q SP, FRAME_R(6), r6 ld.q r5, SAVED_TR0, r6 st.q SP, FRAME_R(18), r18 st.q SP, FRAME_T(0), r6 /* Keep old SP around */ getcon KCR1, r6 /* Save the rest of the general purpose registers */ st.q SP, FRAME_R(0), r0 st.q SP, FRAME_R(1), r1 st.q SP, FRAME_R(7), r7 st.q SP, FRAME_R(8), r8 st.q SP, FRAME_R(9), r9 st.q SP, FRAME_R(10), r10 st.q SP, FRAME_R(11), r11 st.q SP, FRAME_R(12), r12 st.q SP, FRAME_R(13), r13 st.q SP, FRAME_R(14), r14 /* SP is somewhere else */ st.q SP, FRAME_R(15), r6 st.q SP, FRAME_R(16), r16 st.q SP, FRAME_R(17), r17 /* r18 is saved earlier. */ st.q SP, FRAME_R(19), r19 st.q SP, FRAME_R(20), r20 st.q SP, FRAME_R(21), r21 st.q SP, FRAME_R(22), r22 st.q SP, FRAME_R(23), r23 st.q SP, FRAME_R(24), r24 st.q SP, FRAME_R(25), r25 st.q SP, FRAME_R(26), r26 st.q SP, FRAME_R(27), r27 st.q SP, FRAME_R(28), r28 st.q SP, FRAME_R(29), r29 st.q SP, FRAME_R(30), r30 st.q SP, FRAME_R(31), r31 st.q SP, FRAME_R(32), r32 st.q SP, FRAME_R(33), r33 st.q SP, FRAME_R(34), r34 st.q SP, FRAME_R(35), r35 st.q SP, FRAME_R(36), r36 st.q SP, FRAME_R(37), r37 st.q SP, FRAME_R(38), r38 st.q SP, FRAME_R(39), r39 st.q SP, FRAME_R(40), r40 st.q SP, FRAME_R(41), r41 st.q SP, FRAME_R(42), r42 st.q SP, FRAME_R(43), r43 st.q SP, FRAME_R(44), r44 st.q SP, FRAME_R(45), r45 st.q SP, FRAME_R(46), r46 st.q SP, FRAME_R(47), r47 st.q SP, FRAME_R(48), r48 st.q SP, FRAME_R(49), r49 st.q SP, FRAME_R(50), r50 st.q SP, FRAME_R(51), r51 st.q SP, FRAME_R(52), r52 st.q SP, FRAME_R(53), r53 st.q SP, FRAME_R(54), r54 st.q SP, FRAME_R(55), r55 st.q SP, FRAME_R(56), r56 st.q SP, FRAME_R(57), r57 st.q SP, FRAME_R(58), r58 st.q SP, FRAME_R(59), r59 st.q SP, FRAME_R(60), r60 st.q SP, FRAME_R(61), r61 st.q SP, FRAME_R(62), r62 /* * Save the S* registers. */ getcon SSR, r61 st.q SP, FRAME_S(FSSR), r61 getcon SPC, r62 st.q SP, FRAME_S(FSPC), r62 movi -1, r62 /* Reset syscall_nr */ st.q SP, FRAME_S(FSYSCALL_ID), r62 /* Save the rest of the target registers */ gettr tr1, r6 st.q SP, FRAME_T(1), r6 gettr tr2, r6 st.q SP, FRAME_T(2), r6 gettr tr3, r6 st.q SP, FRAME_T(3), r6 gettr tr4, r6 st.q SP, FRAME_T(4), r6 gettr tr5, r6 st.q SP, FRAME_T(5), r6 gettr tr6, r6 st.q SP, FRAME_T(6), r6 gettr tr7, r6 st.q SP, FRAME_T(7), r6 ! setup FP so that unwinder can wind back through nested kernel mode ! exceptions add SP, ZERO, r14#ifdef CONFIG_POOR_MANS_STRACE /* We've pushed all the registers now, so only r2-r4 hold anything * useful. Move them into callee save registers */ or r2, ZERO, r28 or r3, ZERO, r29 or r4, ZERO, r30 /* Preserve r2 as the event code */ movi evt_debug, r3 ori r3, 1, r3 ptabs r3, tr0 or SP, ZERO, r6 getcon TRA, r5 blink tr0, LINK or r28, ZERO, r2 or r29, ZERO, r3 or r30, ZERO, r4#endif /* For syscall and debug race condition, get TRA now */ getcon TRA, r5 /* We are in a safe position to turn SR.BL off, but set IMASK=0xf * Also set FD, to catch FPU usage in the kernel. * * benedict.gaster@superh.com 29/07/2002 * * On all SH5-101 revisions it is unsafe to raise the IMASK and at the * same time change BL from 1->0, as any pending interrupt of a level * higher than he previous value of IMASK will leak through and be * taken unexpectedly. * * To avoid this we raise the IMASK and then issue another PUTCON to * enable interrupts. */ getcon SR, r6 movi SR_IMASK | SR_FD, r7 or r6, r7, r6 putcon r6, SR movi SR_UNBLOCK_EXC, r7 and r6, r7, r6 putcon r6, SR /* Now call the appropriate 3rd level handler */ or r3, ZERO, LINK movi trap_jtable, r3 shlri r2, 3, r2 ldx.l r2, r3, r3 shlri r2, 2, r2 ptabs r3, tr0 or SP, ZERO, r3 blink tr0, ZERO/* * Second level handler for VBR-based exceptions. Post-handlers. * * Post-handlers for interrupts (ret_from_irq), exceptions * (ret_from_exception) and common reentrance doors (restore_all * to get back to the original context, ret_from_syscall loop to * check kernel exiting). * * ret_with_reschedule and work_notifysig are an inner lables of * the ret_from_syscall loop. * * In common to all stack-frame sensitive handlers. * * Inputs: * (SP) struct pt_regs *, original register's frame pointer (basic) * */ .global ret_from_irqret_from_irq:#ifdef CONFIG_POOR_MANS_STRACE pta evt_debug_ret_from_irq, tr0 ori SP, 0, r2 blink tr0, LINK#endif ld.q SP, FRAME_S(FSSR), r6 shlri r6, 30, r6 andi r6, 1, r6 pta resume_kernel, tr0 bne r6, ZERO, tr0 /* no further checks */ STI() pta ret_with_reschedule, tr0 blink tr0, ZERO /* Do not check softirqs */ .global ret_from_exceptionret_from_exception: preempt_stop()#ifdef CONFIG_POOR_MANS_STRACE pta evt_debug_ret_from_exc, tr0 ori SP, 0, r2 blink tr0, LINK#endif ld.q SP, FRAME_S(FSSR), r6 shlri r6, 30, r6 andi r6, 1, r6 pta resume_kernel, tr0 bne r6, ZERO, tr0 /* no further checks */ /* Check softirqs */#ifdef CONFIG_PREEMPT pta ret_from_syscall, tr0 blink tr0, ZEROresume_kernel: pta restore_all, tr0 getcon KCR0, r6 ld.l r6, TI_PRE_COUNT, r7 beq/u r7, ZERO, tr0need_resched: ld.l r6, TI_FLAGS, r7 movi (1 << TIF_NEED_RESCHED), r8 and r8, r7, r8 bne r8, ZERO, tr0 getcon SR, r7 andi r7, 0xf0, r7 bne r7, ZERO, tr0 movi ((PREEMPT_ACTIVE >> 16) & 65535), r8 shori (PREEMPT_ACTIVE & 65535), r8 st.l r6, TI_PRE_COUNT, r8 STI() movi schedule, r7 ori r7, 1, r7 ptabs r7, tr1 blink tr1, LINK st.l r6, TI_PRE_COUNT, ZERO CLI() pta need_resched, tr1 blink tr1, ZERO#endif .global ret_from_syscallret_from_syscall:ret_with_reschedule: getcon KCR0, r6 ! r6 contains current_thread_info ld.l r6, TI_FLAGS, r7 ! r7 contains current_thread_info->flags ! FIXME:!!! ! no handling of TIF_SYSCALL_TRACE yet!! movi (1 << TIF_NEED_RESCHED), r8 and r8, r7, r8 pta work_resched, tr0 bne r8, ZERO, tr0 pta restore_all, tr1 movi (1 << TIF_SIGPENDING), r8 and r8, r7, r8 pta work_notifysig, tr0 bne r8, ZERO, tr0 blink tr1, ZEROwork_resched: pta ret_from_syscall, tr0 gettr tr0, LINK movi schedule, r6 ptabs r6, tr0 blink tr0, ZERO /* Call schedule(), return on top */work_notifysig: gettr tr1, LINK movi do_signal, r6 ptabs r6, tr0 or SP, ZERO, r2 or ZERO, ZERO, r3 blink tr0, LINK /* Call do_signal(regs, 0), return here */restore_all: /* Do prefetches */ ld.q SP, FRAME_T(0), r6 ld.q SP, FRAME_T(1), r7 ld.q SP, FRAME_T(2), r8 ld.q SP, FRAME_T(3), r9 ptabs r6, tr0 ptabs r7, tr1 ptabs r8, tr2 ptabs r9, tr3 ld.q SP, FRAME_T(4), r6 ld.q SP, FRAME_T(5), r7 ld.q SP, FRAME_T(6), r8 ld.q SP, FRAME_T(7), r9 ptabs r6, tr4 ptabs r7, tr5 ptabs r8, tr6 ptabs r9, tr7 ld.q SP, FRAME_R(0), r0 ld.q SP, FRAME_R(1), r1 ld.q SP, FRAME_R(2), r2 ld.q SP, FRAME_R(3), r3 ld.q SP, FRAME_R(4), r4 ld.q SP, FRAME_R(5), r5 ld.q SP, FRAME_R(6), r6 ld.q SP, FRAME_R(7), r7 ld.q SP, FRAME_R(8), r8 ld.q SP, FRAME_R(9), r9 ld.q SP, FRAME_R(10), r10 ld.q SP, FRAME_R(11), r11 ld.q SP, FRAME_R(12), r12 ld.q SP, FRAME_R(13), r13 ld.q SP, FRAME_R(14), r14 ld.q SP, FRAME_R(16), r16 ld.q SP, FRAME_R(17), r17 ld.q SP, FRAME_R(18), r18 ld.q SP, FRAME_R(19), r19 ld.q SP, FRAME_R(20), r20 ld.q SP, FRAME_R(21), r21 ld.q SP, FRAME_R(22), r22 ld.q SP, FRAME_R(23), r23 ld.q SP, FRAME_R(24), r24 ld.q SP, FRAME_R(25), r25 ld.q SP, FRAME_R(26), r26 ld.q SP, FRAME_R(27), r27 ld.q SP, FRAME_R(28), r28 ld.q SP, FRAME_R(29), r29 ld.q SP, FRAME_R(30), r30 ld.q SP, FRAME_R(31), r31 ld.q SP, FRAME_R(32), r32 ld.q SP, FRAME_R(33), r33 ld.q SP, FRAME_R(34), r34 ld.q SP, FRAME_R(35), r35 ld.q SP, FRAME_R(36), r36 ld.q SP, FRAME_R(37), r37 ld.q SP, FRAME_R(38), r38 ld.q SP, FRAME_R(39), r39 ld.q SP, FRAME_R(40), r40 ld.q SP, FRAME_R(41), r41 ld.q SP, FRAME_R(42), r42 ld.q SP, FRAME_R(43), r43 ld.q SP, FRAME_R(44), r44 ld.q SP, FRAME_R(45), r45 ld.q SP, FRAME_R(46), r46 ld.q SP, FRAME_R(47), r47 ld.q SP, FRAME_R(48), r48 ld.q SP, FRAME_R(49), r49 ld.q SP, FRAME_R(50), r50 ld.q SP, FRAME_R(51), r51
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -