⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 intr.s

📁 深圳市微逻辑电子有限公司 巨果&#8226 Kingmos&reg 系统核心
💻 S
📖 第 1 页 / 共 2 页
字号:
/* ******************************************************
 * @copyright(c) 版权所有,1998-2003微逻辑。保留所有权利。
 * ******************************************************
 * 
 * ******************************************************
 * 文件说明:中断异常处理
 * 版本号:1.0.0
 * 开发时期:2001-04-04
 * 作者:周兵
 * 修改记录:
 * *******************************************************
 */

.nolist
.include "linkage.inc"
.list

.globl		INTR_OFF
.globl		INTR_ON
.globl		ES_VectorTable

.extern		INTR_Interrupt
.extern		INTR_Software
.extern		INTR_PrefetchAbort
.extern		INTR_DataAbort
.extern		INTR_FastIntr
.extern		DefaultHandler
.extern		DebugValue
.extern		GetTryFlagAdr
.extern		LoadFailurePage
.extern		MakeAPICall
.extern        MakeSysCall
.extern		APICallReturn
.extern        KL_ExitThread
@.extern        INTR_GetAbortStack
.extern        lpCurThread
@.extern 		AllocThreadKernelStackPage

@ ARM processor modes
.equ	USER_MODE	,	0x10	@2_10000
.equ	FIQ_MODE	,	0x11	@2_10001
.equ	IRQ_MODE	,	0x12	@2_10010
.equ	SVC_MODE	,	0x13	@2_10011
.equ	ABORT_MODE	,	0x17	@2_10111
.equ	UNDEF_MODE	,	0x1b	@2_11011
.equ	SYS_MODE ,	0x1f	@2_11111

	.macro mtc15, cpureg, cp15reg
	    mcr		p15,0,\cpureg,\cp15reg,c0,0
	.endm

	.macro mfc15, cpureg, cp15reg
	    mrc		p15,0,\cpureg,\cp15reg,c0,0
	.endm

	.text
	.type	 ES_VectorTable, #object	
ES_VectorTable:
        .word   ES_ResetHandler
        .word   ES_UndefExceptionHandler
        .word   ES_SWIHandler
        .word   ES_PrefetchAbortHandler
        .word   ES_DataAbortHandler
        .word   ES_UnusedHandler
        .word   ES_IRQHandler
        .word   ES_FIQHandler
	    .size	ES_VectorTable, . - ES_VectorTable

@=======================================================
@=======================================================
	ENTRY ES_ResetHandler
	nop

@=======================================================
@=======================================================
    ENTRY ES_UndefExceptionHandler
	nop

@=======================================================
@=======================================================
    ENTRY ES_SWIHandler

	sub     r12, r12, #0xF0000000
	cmp     r12, #0x00200000                @ 是否是系统 API调用 ? must sync with api bit define in eapisrv.h
	blo     HandleAPICall                   @ 是,到HandleAPICall

    add     r12, r12, #0xF0000000           @ 否,处理错误,这里恢复r12的值
    
	msr     cpsr_c, #SYS_MODE | 0x80        @ switch to sys_mode and IRQs disabled
	stmfd   sp!, {r0-r3, r12, lr}           @ save r0-r3,r12, and lr

	msr     cpsr_c, #SVC_MODE | 0x80        @ switch back to svc_mode and IRQs disabled
	mov     r0, lr
    mrs     r1, spsr

	msr     cpsr_c, #SYS_MODE | 0x80        @ switch to sys_mode and IRQs disabled
	stmfd   sp!, {r0-r1}                    @ 保存lr and spsr到sys_mode的stack里( save lr and spsr)

    mov     r1, r12                         @ 为INTR_Software准备参数
	msr     cpsr_c, #SYS_MODE               @ IRQs enable
	bl      INTR_Software                   @ 调用C异常处理函数
    
    msr     cpsr_c, #SYS_MODE | 0x80        @ switch to sys_mode and IRQs disabled
	ldmfd   sp!, {r0-r1}                    @ restore lr and spsr
	msr     cpsr_c, #SVC_MODE | 0x80        @ switch back to svc_mode and IRQs disabled
    mov     lr, r0                          @ restore svc_mode lr and spsr
	msr     spsr, r1

	msr     cpsr_c, #SYS_MODE | 0x80        @ switch to svc_mode and IRQs disabled
	ldmfd   sp!, {r0-r3, r12, lr}           @ restore r0-r3,r12, and lr

	msr     cpsr_c, #SVC_MODE | 0x80        @ switch to svc_mode and IRQs disabled
    movs    pc, lr                          @ 返回


HandleAPICall:

@typedef struct _SYSCALL
@{
@	UINT uiCallMode;	// 输入之前的模式; 输出,将要切换到的新模式
@	DWORD dwCallInfo;
@	PFNVOID pfnRetAdress;
@	UINT uiArg[1];		//可变长度
@}SYSCALL, FAR * LPSYSCALL;

	 msr     cpsr_c, #SYS_MODE | 0x80              @ switch to sys_mode and IRQs disabled

@ 将r0-r3压入sp

	 stmfd   sp!, {r0-r3}
	 
	 msr     cpsr_c, #SVC_MODE | 0x80              @ switch to svc_mode and IRQs disabled	 
	 
	 mrs     r1, spsr                              @ 为SYSCALL准备数据 = 之前的模式
	 
     msr     cpsr_c, #SYS_MODE                     @ switch to sys_mode and IRQs enable

@
@ sp[0] = r0 - 参数0(arg0)
@ sp[1] = r1 - 参数1(arg1)
@ sp[2] = r2 - 参数2(arg2)
@ sp[3] = r3 - 参数3(arg3)
@ sp[4] =  - 参数4(arg4)
@ sp[5] = - 参数5(arg5)
@ ...
@

     stmfd   sp!, { r1, r12, lr}    @ 准备 SYSCALL 结构成员数据

	 mov     r0, sp                @ r0 = SYSCALL ptr
     bl      MakeSysCall           @ MakeSysCall 将返回需要调用的系统功能地址并做其他切换

	 cmp     r0, #0x0              @ r0 = 调用地址, 系统功能是否有效 ?
	 beq     DirectRet             @ 否,到DirectRet

	 ldr     r12, [sp]             @ r12  = 返回模式 , 必定是SYS or USER mode
     add     sp, sp, #12		   @ 清除sp

	 ldr     lr, =0xF0100000       @ 返回地址

	 msr     cpsr_c, #SVC_MODE | 0x80              @ switch to svc_mode and IRQs disabled	 
	 msr     spsr_c, r12                   @返回模式 
	 mov     lr, r0

     msr     cpsr_c, #SYS_MODE | 0x80              @ switch to sys_mode and IRQs disabled	 
	 ldmfd   sp!, {r0-r3}          @ 从sp弹出 参数0 至 参数3 到 r0-r3
     
	 msr     cpsr_c, #SVC_MODE | 0x80              @ switch to svc_mode and IRQs disabled	 

     movs    pc, lr               @ 调用系统功能

APICallRet:
                                   @ 系统功能完成并返回到只这里,r0等于系统功能返回值
     stmfd   sp!, {r0}             @ 保存 r0

     bl      DefaultHandler        @ 调用默认处理
     
	 sub     sp, sp, #0x4                 @ APICallReturn( LPDWORD * lpdwState ) 需要参数
	 mov     r0, sp
     bl      APICallReturn         @ 默认处理完成,得到返回地址并做其他切换
	                               @ r0 = 需要返回的PC地址
	 ldmfd   sp!, {r1}             @ r1 = spsr
	 mov     r12, r0               @ r12=返回到调用者
     
	 ldmfd   sp!, {r0}             @ 恢复 r0

	 msr     cpsr_c, #SVC_MODE | 0x80              @ switch to svc_mode and IRQs disabled	 
	 msr     spsr, r1              @
	 movs    pc, r12

DirectRet:

     stmfd   sp!, {r0}             @ 保存 r0

     bl      DefaultHandler        @ 调用默认处理

	 ldmfd   sp!, {r0}             @ 恢复 r0
	 ldmfd   sp!, { r1, r2, r3}    @ 恢复 cpsr, callinfo, return adr

     add     sp, sp, #0x10         @ 弹出 之前压入的 r0-r3 sp
     
     msr     cpsr_c, #SVC_MODE | 0x80              @ switch to svc_mode and IRQs disabled
     
     msr     spsr, r1
	 mov     lr, r3
     movs    pc, lr                @ 返回到调用者

@-----------------------------------------------------------
@-----------------------------------------------------------
    ENTRY ES_PrefetchAbortHandler

	sub     lr, lr, #0xF0000004
	cmp     lr, #0x00200000                @ 是否是系统 API调用返回 ? must sync with api bit define in eapisrv.h
	blo     _HandleCallReturn                   @ 是,到_HandleCallReturn

    add     lr, lr, #0xF0000000
    stmfd   sp!, {r0-r3, r12, lr}

    mov     r0, lr                          @ (r0) = faulting address
	mov     r1, lr                          @ (r1) = faulting address
    mfc15   r2, c13                         @ (r2) = process base address
    tst     r0, #0xFE000000                 @ slot 0 reference?
    orreq   r0, r0, r2                      @ (r0) = process slot based address
    bl      LoadFailurePage                 @ 装入页(r0) = !0 if entry loaded

	cmp     r0, #0x0	                    @ not handle the page failure
	ldmnefd sp!, {r0-r3,r12,pc}^            @
   
	ldmfd   sp!, {r0-r3,r12,lr}             @ 恢复r0-r3,r12,lr
   	                                        @ 装入页错误, 以下处理错误
	stmfd   sp!, {r4}           			@ save r4

	msr     cpsr_c, #SYS_MODE | 0x80        @ switch to system mode w/IRQs disabled
	
	@ 切换到 sys sp	
	ldr     r4, =lpCurThread
	ldr     r4, [r4]
	add     sp, r4, #0x400        @=0xC00-4
	sub     sp, sp, #4
	
	
	stmfd   sp!, {r0-r3, r12, lr}           @ save r0-r3,r12, and lr

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -