📄 entry.s
字号:
/* entry.S: FR-V entry * * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved. * Written by David Howells (dhowells@redhat.com) * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. * * * Entry to the kernel is "interesting": * (1) There are no stack pointers, not even for the kernel * (2) General Registers should not be clobbered * (3) There are no kernel-only data registers * (4) Since all addressing modes are wrt to a General Register, no global * variables can be reached * * We deal with this by declaring that we shall kill GR28 on entering the * kernel from userspace * * However, since break interrupts can interrupt the CPU even when PSR.ET==0, * they can't rely on GR28 to be anything useful, and so need to clobber a * separate register (GR31). Break interrupts are managed in break.S * * GR29 _is_ saved, and holds the current task pointer globally * */#include <linux/sys.h>#include <linux/config.h>#include <linux/linkage.h>#include <asm/thread_info.h>#include <asm/setup.h>#include <asm/segment.h>#include <asm/ptrace.h>#include <asm/errno.h>#include <asm/cache.h>#include <asm/spr-regs.h>#define nr_syscalls ((syscall_table_size)/4) .text .balign 4.macro LEDS val# sethi.p %hi(0xe1200004),gr30# setlo %lo(0xe1200004),gr30# setlos #~\val,gr31# st gr31,@(gr30,gr0)# sethi.p %hi(0xffc00100),gr30# setlo %lo(0xffc00100),gr30# sth gr0,@(gr30,gr0)# membar.endm.macro LEDS32# not gr31,gr31# sethi.p %hi(0xe1200004),gr30# setlo %lo(0xe1200004),gr30# st.p gr31,@(gr30,gr0)# srli gr31,#16,gr31# sethi.p %hi(0xffc00100),gr30# setlo %lo(0xffc00100),gr30# sth gr31,@(gr30,gr0)# membar.endm################################################################################# entry point for External interrupts received whilst executing userspace code################################################################################ .globl __entry_uspace_external_interrupt .type __entry_uspace_external_interrupt,@function__entry_uspace_external_interrupt: LEDS 0x6200 sethi.p %hi(__kernel_frame0_ptr),gr28 setlo %lo(__kernel_frame0_ptr),gr28 ldi @(gr28,#0),gr28 # handle h/w single-step through exceptions sti gr0,@(gr28,#REG__STATUS) .globl __entry_uspace_external_interrupt_reentry__entry_uspace_external_interrupt_reentry: LEDS 0x6201 setlos #REG__END,gr30 dcpl gr28,gr30,#0 # finish building the exception frame sti sp, @(gr28,#REG_SP) stdi gr2, @(gr28,#REG_GR(2)) stdi gr4, @(gr28,#REG_GR(4)) stdi gr6, @(gr28,#REG_GR(6)) stdi gr8, @(gr28,#REG_GR(8)) stdi gr10,@(gr28,#REG_GR(10)) stdi gr12,@(gr28,#REG_GR(12)) stdi gr14,@(gr28,#REG_GR(14)) stdi gr16,@(gr28,#REG_GR(16)) stdi gr18,@(gr28,#REG_GR(18)) stdi gr20,@(gr28,#REG_GR(20)) stdi gr22,@(gr28,#REG_GR(22)) stdi gr24,@(gr28,#REG_GR(24)) stdi gr26,@(gr28,#REG_GR(26)) sti gr0, @(gr28,#REG_GR(28)) sti gr29,@(gr28,#REG_GR(29)) stdi.p gr30,@(gr28,#REG_GR(30)) # set up the kernel stack pointer ori gr28,0,sp movsg tbr ,gr20 movsg psr ,gr22 movsg pcsr,gr21 movsg isr ,gr23 movsg ccr ,gr24 movsg cccr,gr25 movsg lr ,gr26 movsg lcr ,gr27 setlos.p #-1,gr4 andi gr22,#PSR_PS,gr5 /* try to rebuild original PSR value */ andi.p gr22,#~(PSR_PS|PSR_S),gr6 slli gr5,#1,gr5 or gr6,gr5,gr5 andi gr5,#~PSR_ET,gr5 sti gr20,@(gr28,#REG_TBR) sti gr21,@(gr28,#REG_PC) sti gr5 ,@(gr28,#REG_PSR) sti gr23,@(gr28,#REG_ISR) stdi gr24,@(gr28,#REG_CCR) stdi gr26,@(gr28,#REG_LR) sti gr4 ,@(gr28,#REG_SYSCALLNO) movsg iacc0h,gr4 movsg iacc0l,gr5 stdi gr4,@(gr28,#REG_IACC0) movsg gner0,gr4 movsg gner1,gr5 stdi gr4,@(gr28,#REG_GNER0) # set up kernel global registers sethi.p %hi(__kernel_current_task),gr5 setlo %lo(__kernel_current_task),gr5 sethi.p %hi(_gp),gr16 setlo %lo(_gp),gr16 ldi @(gr5,#0),gr29 ldi.p @(gr29,#4),gr15 ; __current_thread_info = current->thread_info # make sure we (the kernel) get div-zero and misalignment exceptions setlos #ISR_EDE|ISR_DTT_DIVBYZERO|ISR_EMAM_EXCEPTION,gr5 movgs gr5,isr # switch to the kernel trap table sethi.p %hi(__entry_kerneltrap_table),gr6 setlo %lo(__entry_kerneltrap_table),gr6 movgs gr6,tbr # set the return address sethi.p %hi(__entry_return_from_user_interrupt),gr4 setlo %lo(__entry_return_from_user_interrupt),gr4 movgs gr4,lr # raise the minimum interrupt priority to 15 (NMI only) and enable exceptions movsg psr,gr4 ori gr4,#PSR_PIL_14,gr4 movgs gr4,psr ori gr4,#PSR_PIL_14|PSR_ET,gr4 movgs gr4,psr LEDS 0x6202 bra do_IRQ .size __entry_uspace_external_interrupt,.-__entry_uspace_external_interrupt################################################################################# entry point for External interrupts received whilst executing kernel code# - on arriving here, the following registers should already be set up:# GR15 - current thread_info struct pointer# GR16 - kernel GP-REL pointer# GR29 - current task struct pointer# TBR - kernel trap vector table# ISR - kernel's preferred integer controls################################################################################ .globl __entry_kernel_external_interrupt .type __entry_kernel_external_interrupt,@function__entry_kernel_external_interrupt: LEDS 0x6210 sub sp,gr15,gr31 LEDS32 # set up the stack pointer or.p sp,gr0,gr30 subi sp,#REG__END,sp sti gr30,@(sp,#REG_SP) # handle h/w single-step through exceptions sti gr0,@(sp,#REG__STATUS) .globl __entry_kernel_external_interrupt_reentry__entry_kernel_external_interrupt_reentry: LEDS 0x6211 # set up the exception frame setlos #REG__END,gr30 dcpl sp,gr30,#0 sti.p gr28,@(sp,#REG_GR(28)) ori sp,0,gr28 # finish building the exception frame stdi gr2,@(gr28,#REG_GR(2)) stdi gr4,@(gr28,#REG_GR(4)) stdi gr6,@(gr28,#REG_GR(6)) stdi gr8,@(gr28,#REG_GR(8)) stdi gr10,@(gr28,#REG_GR(10)) stdi gr12,@(gr28,#REG_GR(12)) stdi gr14,@(gr28,#REG_GR(14)) stdi gr16,@(gr28,#REG_GR(16)) stdi gr18,@(gr28,#REG_GR(18)) stdi gr20,@(gr28,#REG_GR(20)) stdi gr22,@(gr28,#REG_GR(22)) stdi gr24,@(gr28,#REG_GR(24)) stdi gr26,@(gr28,#REG_GR(26)) sti gr29,@(gr28,#REG_GR(29)) stdi gr30,@(gr28,#REG_GR(30)) movsg tbr ,gr20 movsg psr ,gr22 movsg pcsr,gr21 movsg isr ,gr23 movsg ccr ,gr24 movsg cccr,gr25 movsg lr ,gr26 movsg lcr ,gr27 setlos.p #-1,gr4 andi gr22,#PSR_PS,gr5 /* try to rebuild original PSR value */ andi.p gr22,#~(PSR_PS|PSR_S),gr6 slli gr5,#1,gr5 or gr6,gr5,gr5 andi.p gr5,#~PSR_ET,gr5 # set CCCR.CC3 to Undefined to abort atomic-modify completion inside the kernel # - for an explanation of how it works, see: Documentation/fujitsu/frv/atomic-ops.txt andi gr25,#~0xc0,gr25 sti gr20,@(gr28,#REG_TBR) sti gr21,@(gr28,#REG_PC) sti gr5 ,@(gr28,#REG_PSR) sti gr23,@(gr28,#REG_ISR) stdi gr24,@(gr28,#REG_CCR) stdi gr26,@(gr28,#REG_LR) sti gr4 ,@(gr28,#REG_SYSCALLNO) movsg iacc0h,gr4 movsg iacc0l,gr5 stdi gr4,@(gr28,#REG_IACC0) movsg gner0,gr4 movsg gner1,gr5 stdi gr4,@(gr28,#REG_GNER0) # set the return address sethi.p %hi(__entry_return_from_kernel_interrupt),gr4 setlo %lo(__entry_return_from_kernel_interrupt),gr4 movgs gr4,lr # clear power-saving mode flags movsg hsr0,gr4 andi gr4,#~HSR0_PDM,gr4 movgs gr4,hsr0 # raise the minimum interrupt priority to 15 (NMI only) and enable exceptions movsg psr,gr4 ori gr4,#PSR_PIL_14,gr4 movgs gr4,psr ori gr4,#PSR_ET,gr4 movgs gr4,psr LEDS 0x6212 bra do_IRQ .size __entry_kernel_external_interrupt,.-__entry_kernel_external_interrupt################################################################################# entry point for Software and Progam interrupts generated whilst executing userspace code################################################################################ .globl __entry_uspace_softprog_interrupt .type __entry_uspace_softprog_interrupt,@function .globl __entry_uspace_handle_mmu_fault__entry_uspace_softprog_interrupt: LEDS 0x6000#ifdef CONFIG_MMU movsg ear0,gr28__entry_uspace_handle_mmu_fault: movgs gr28,scr2#endif sethi.p %hi(__kernel_frame0_ptr),gr28 setlo %lo(__kernel_frame0_ptr),gr28 ldi @(gr28,#0),gr28 # handle h/w single-step through exceptions sti gr0,@(gr28,#REG__STATUS) .globl __entry_uspace_softprog_interrupt_reentry__entry_uspace_softprog_interrupt_reentry: LEDS 0x6001 setlos #REG__END,gr30 dcpl gr28,gr30,#0 # set up the kernel stack pointer sti.p sp,@(gr28,#REG_SP) ori gr28,0,sp sti gr0,@(gr28,#REG_GR(28)) stdi gr20,@(gr28,#REG_GR(20)) stdi gr22,@(gr28,#REG_GR(22)) movsg tbr,gr20 movsg pcsr,gr21 movsg psr,gr22 sethi.p %hi(__entry_return_from_user_exception),gr23 setlo %lo(__entry_return_from_user_exception),gr23 bra __entry_common .size __entry_uspace_softprog_interrupt,.-__entry_uspace_softprog_interrupt # single-stepping was disabled on entry to a TLB handler that then faulted#ifdef CONFIG_MMU .globl __entry_uspace_handle_mmu_fault_sstep__entry_uspace_handle_mmu_fault_sstep: movgs gr28,scr2 sethi.p %hi(__kernel_frame0_ptr),gr28 setlo %lo(__kernel_frame0_ptr),gr28 ldi @(gr28,#0),gr28 # flag single-step re-enablement sti gr0,@(gr28,#REG__STATUS) bra __entry_uspace_softprog_interrupt_reentry#endif################################################################################# entry point for Software and Progam interrupts generated whilst executing kernel code################################################################################ .globl __entry_kernel_softprog_interrupt .type __entry_kernel_softprog_interrupt,@function__entry_kernel_softprog_interrupt: LEDS 0x6004#ifdef CONFIG_MMU movsg ear0,gr30 movgs gr30,scr2#endif .globl __entry_kernel_handle_mmu_fault__entry_kernel_handle_mmu_fault: # set up the stack pointer subi sp,#REG__END,sp sti sp,@(sp,#REG_SP) sti sp,@(sp,#REG_SP-4) andi sp,#~7,sp # handle h/w single-step through exceptions sti gr0,@(sp,#REG__STATUS) .globl __entry_kernel_softprog_interrupt_reentry__entry_kernel_softprog_interrupt_reentry: LEDS 0x6005 setlos #REG__END,gr30 dcpl sp,gr30,#0 # set up the exception frame sti.p gr28,@(sp,#REG_GR(28)) ori sp,0,gr28 stdi gr20,@(gr28,#REG_GR(20)) stdi gr22,@(gr28,#REG_GR(22)) ldi @(sp,#REG_SP),gr22 /* reconstruct the old SP */ addi gr22,#REG__END,gr22 sti gr22,@(sp,#REG_SP) # set CCCR.CC3 to Undefined to abort atomic-modify completion inside the kernel # - for an explanation of how it works, see: Documentation/fujitsu/frv/atomic-ops.txt movsg cccr,gr20 andi gr20,#~0xc0,gr20 movgs gr20,cccr movsg tbr,gr20 movsg pcsr,gr21 movsg psr,gr22 sethi.p %hi(__entry_return_from_kernel_exception),gr23 setlo %lo(__entry_return_from_kernel_exception),gr23 bra __entry_common .size __entry_kernel_softprog_interrupt,.-__entry_kernel_softprog_interrupt # single-stepping was disabled on entry to a TLB handler that then faulted#ifdef CONFIG_MMU .globl __entry_kernel_handle_mmu_fault_sstep__entry_kernel_handle_mmu_fault_sstep: # set up the stack pointer subi sp,#REG__END,sp sti sp,@(sp,#REG_SP) sti sp,@(sp,#REG_SP-4) andi sp,#~7,sp # flag single-step re-enablement sethi #REG__STATUS_STEP,gr30 sti gr30,@(sp,#REG__STATUS) bra __entry_kernel_softprog_interrupt_reentry#endif################################################################################# the rest of the kernel entry point code# - on arriving here, the following registers should be set up:# GR1 - kernel stack pointer# GR7 - syscall number (trap 0 only)# GR8-13 - syscall args (trap 0 only)# GR20 - saved TBR# GR21 - saved PC# GR22 - saved PSR# GR23 - return handler address# GR28 - exception frame on stack# SCR2 - saved EAR0 where applicable (clobbered by ICI & ICEF insns on FR451)# PSR - PSR.S 1, PSR.ET 0################################################################################ .globl __entry_common .type __entry_common,@function__entry_common: LEDS 0x6008 # finish building the exception frame stdi gr2,@(gr28,#REG_GR(2)) stdi gr4,@(gr28,#REG_GR(4)) stdi gr6,@(gr28,#REG_GR(6)) stdi gr8,@(gr28,#REG_GR(8)) stdi gr10,@(gr28,#REG_GR(10)) stdi gr12,@(gr28,#REG_GR(12)) stdi gr14,@(gr28,#REG_GR(14)) stdi gr16,@(gr28,#REG_GR(16)) stdi gr18,@(gr28,#REG_GR(18)) stdi gr24,@(gr28,#REG_GR(24)) stdi gr26,@(gr28,#REG_GR(26)) sti gr29,@(gr28,#REG_GR(29)) stdi gr30,@(gr28,#REG_GR(30)) movsg lcr ,gr27 movsg lr ,gr26 movgs gr23,lr movsg cccr,gr25 movsg ccr ,gr24 movsg isr ,gr23 setlos.p #-1,gr4
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -