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

📄 int.s

📁 ADS环境下的类似linux内核的操作系统
💻 S
字号:
;; MShowTec - www.mshowtec.com
;; msLinux int.s ver1.0
;; 20051221 lmjx create limiao@mshowtec.com
;;
;;

;;  MSLINUX_INT_S

	IMPORT mslinux_irq_handler
	 
	CODE32
	AREA	|C$$code|, CODE, READONLY
	GET snds.s
	
	EXPORT undef
	IMPORT cpu_block_undef
undef
	b cpu_block_undef
	
	IMPORT mslinux_top_swi_stack
	EXPORT swi	
swi
	ldr		r2, =mslinux_top_swi_stack
	ldr		r2,	[r2]
	mov     sp, r2            ;
    stmfd   sp!,{r0-r3, r12, lr}
    mov     r1, sp                  ;
    mrs     r3, spsr
    ldr		r0, [lr,#-4]            ; get arm swi no.
    bic		r0, r0, #0xFF000000     ;
    
    ldmfd   sp!, {r0-r3, r12, pc}^
    
	
	EXPORT prefetch
	IMPORT cpu_block_prefatch
prefetch
	b cpu_block_prefatch
	
	EXPORT data
	IMPORT cpu_block_data
data
	b cpu_block_data

	IMPORT timer_resched_cnt
	IMPORT mslinux_irq_nesting
	IMPORT mslinux_top_irq_stack
	IMPORT errno_print
	IMPORT schedule
	EXPORT irq
irq

    sub	lr,lr,#4
    stmfd   sp!, {r0-r12, lr}	; Save all scratch registers
    mrs     r0, SPSR		; Save the task status register
    stmfd	sp!,{r0}		;   necessary to allow nested interrupts 
    
    ; Count number of region entrys (disable task switch for nested interrupts)
	ldr		r2,=mslinux_irq_nesting
	ldrb	r3,[r2]
	add		r3,r3,#1
	strb	r3,[r2]
	tst		r3,#0xff
	mov		r0,#1	;1 for enter int nesting over
	beq		errno_print
	
	; We must switch in systeme mode because the IRQ lr can be corrupted
	;	if a new IRQ is entered after a function call in the user
	;	interrupthandler
	orr 	r1, r0,#(Mode_SYS | I_BIT) 
	msr		CPSR_cf,r1
	
	; Switch on irq stack
	ldr		r1,=mslinux_top_irq_stack	; Load top of irq stack address
	ldr		r1,[r1]
	mov		r3,sp			; save old stack pointer
	ldr		r0,=mslinux_irq_nesting
	ldrb	r2,[r0]
	cmp     r2, #1			; if no irq nesting
	moveq	sp,r1			; if no then load sp with top of irq stack
	stmfd	sp!,{r3,lr}		; Push system lr and old sp in new stack


	bl	mslinux_irq_handler	; call irq handler
	
	
	; Pop registers and come back to tasks sp
	ldmfd	sp,{sp,lr}		; Restore lr and sp
	
	; Return in IRQ mode
	mov		r1,#(Mode_IRQ | I_BIT)
    msr		CPSR_cf,r1
    
    ; Decrement region counter, if not equal to zero a task switch 
	; is not possible we must return from FIQ 
	ldr		r2,=mslinux_irq_nesting	; Load counter adress
	ldrb    r3,[r2]			; load counter
    	cmp		r3,#0			; if nul -> error
    	mov		r0,#2	;2 for out int nesting over
	beq		errno_print		
	subs	r3,r3,#1		; decrement counter
	strb	r3,[r2]			; store counter
	bne		mslinux_return_irq		; if not nul interrupt return ( no switch possible)
	
	ldr		r2,=timer_resched_cnt	; Load timer_resched_cnt adress
	ldr     r3,[r2]			; load counter
    cmp		r3,#0			; if nul -> do not resched
    beq		mslinux_return_irq ;int return
    
    sub 	r3,r3,#1		; decrement counter
	str     r3,[r2]			; store counter
    
	; We now need to perform a task switch.
	; We must call the switch function in systeme mode	
    ldmfd	sp!,{r0,r1}	; Pop SPSR and r0 (scratch register) from the stack
	ldr		r2,[sp,#12*4]	; Load irq lr in the stack = task adress
	
	; switch in systeme mode to create a fake system stack 
	; which contains {SPSR, r0, Task adress}
	mov	r3,#(Mode_SYS | I_BIT) ; switch in system mode
	msr	CPSR_cf,r3	
	
	stmfd	sp!,{r0-r2}	; push {SPSR, r0 , Tasks adress} in system stack
	
	; Switch in IRQ mode to empty the stack and pop all registers
	mov		r1,#(Mode_IRQ | I_BIT)		; Go to exception mode
    msr		CPSR_cf,r1

	ldmfd	sp!,{r1-r12, lr}; Empty the IRQ stack
	
	; so we switch in system mode to call the task switch
	mov	r0,#(Mode_SYS | I_BIT) ; switch in system mode
	msr	CPSR_cf,r0
	
	; Call task switch and save/restore task lr which was not saved
	stmfd	sp!,{lr}	; Save Systeme lr which was not saved 
	bl		schedule	; call the task switch
	ldmfd	sp!,{lr}		; pop systeme mode lr
	
	; Task was in ARM mode we restore the CPSR and return in task
	ldmfd	sp!,{r0}	; Pop the SPSR	
	msr	CPSR_cf,r0		; restore CPSR
	ldmfd	sp!,{r0,pc}	; Return in task

	; Interrupt return if no task switching
mslinux_return_irq
    ldmfd	sp!,{r1}	; Transfert PSR in SPSR for interrupt return
	msr	SPSR_cf,r1

	ldmfd	sp!,{r0-r12, pc}^; Return from interrupt 	
	EXPORT fiq	
fiq
	b fiq
	
	AREA	|C$$data|

int_swi_top_stack
	%	4		

	
	END

⌨️ 快捷键说明

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