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

📄 irqlib.s

📁 HAL硬件抽象层源码
💻 S
字号:
;******************************************************************************
; Copyright ?Intel Corporation, March 18th 1998.  All rights reserved.
; Copyright ?ARM Limited 1998, 1999.  All rights reserved.
;******************************************************************************
;/*****************************************************************************

;  General IRQ change code. NewIRQ installs the given 'C' routine as the
; high level handler for interrupt as well as the actual vector. Routines
; to en/disable IRQs.

;	$Id: irqlib.s,v 1.4 1999/08/02 15:24:05 mquinn Exp $

;******************************************************************************/

	INCLUDE	sizes.s
	INCLUDE except_h.s

	IMPORT	uHALp_HandleIRQ
	IMPORT	uHALir_TrapIRQ		; Simple IRQ Trap Handler
;	IMPORT	uHALir_CleanDCacheEntry
	IMPORT	uHALir_EnterSvcMode	; Enter Supervisor mode.
	IMPORT	uHALir_ExitSvcMode	; Exit Supervisor mode.

	EXPORT	uHALir_NewVector
	EXPORT	uHALir_NewIRQ		; Routine to install 'C' routine
	EXPORT	uHALir_DisableInt	; Disable IRQ.
	EXPORT	uHALir_EnableInt
	EXPORT  uHALir_DoSWI

	AREA	uHAL_IRQs, CODE, READONLY


; ------------------------------------------------------------------
; int uHALir_NewVector(void *vector, pHandler newHandler)

; Vector substitution mechanism (from NewIRQ), replaces the specified
; exception vector handler with the newHandler. Returns 0 for fail.
;
; NOTE: This routine is not ACPS-compliant as it may be called before
; stacks etc. are defined. Must be called in Supervisor mode.

uHALir_NewVector
	MOV	r2, r0
	MOV	r0, #0			; Default retval = 0
        ; Many programs don't put the vectors straight after the jump
	; table (the table may be in ROM, with the vectors in RAM). By
	; reading the real offset, we can be sure we're putting the vector
	; in the right place.
        LDR     r4, [r2]                ; Read the instruction
        LDR     r5, =0x0FFF
        LDR     r7, =0xE59FF000         ; Bit pattern for LDR PC, ... 
        BIC     r6, r4, r5              ; Clear bottom 12 bits (the offset)
        CMP     r7, r6			; Is the vector a LDR PC
        BNE     %F2
        AND     r4, r4, r5		; Clear all but the offset
        ADD     r4, r4, r2		; Add vector to calculate real address
        ADD     r4, r4, #8		; Add pipeline offset
	MOV	r0, #1			; Set return status
        B       %F3

	; The exception vector was not a LDR PC so there is no indirect
	; vector to overwrite. Instead we will try and construct a branch
	; instruction and write this into the exception vector. This will
	; only work if handler routine we are trying to install is within
	; the first 32M of memory.
	; According to the Architectural Reference Manual, branch back
	; past 0 is unpredictable.

2	SUB     r7, r1, r2		; Subtract vector and pipeline offset
	SUB     r7, r7, #8
        CMP     r7, #SZ_32M             ; Is the routine within first 32M
	BGE	%F4                     ; Fail if it isn't
        MOV     r7, r7, LSR #2          ; Shift right and mask
        BIC     r7, r7, #0xFF000000
        ORR     r1, r7, #0xEA000000     ; Build branch instruction
	MOV	r4, r2
	MOV	r0, #2			; Set return status

3	LDR     r2, [r4]		; Make a note of the old vector
        STR     r1, [r4]		; Overwrite with new vector

	MOV     r5, #0

	; Drain write buffer & caches to make sure everything is flushed.
;Remarked for 7092	WRCACHE_CleanDCentry	r4

;Remarked for 7092	WRCACHE_DrainWriteBuffer	r5

;Remarked for 7092	WRCACHE_FlushIC		r4	; Flush ICache

	; Now check that instruction wrote correctly
	LDR	r6, [r4]
	CMP	r6, r1
	MOVNE	r0, #0			; No, must be read-only retval = 0

4
	; On return:
	;	r2 - old vector / branch / NULL
	;	r1 - new vector / branch / NULL
	;	r0 - status:	0 couldn't write new exception vector
	;			1 Old exception was an LDR PC,..
	;			2 Old exception was something else

	MOV	pc, r14


; ------------------------------------------------------------------
;void *int uHALr_NewIRQ(uHALr_DispatchIRQ, uHALp_VectorIRQ)
;	pHandler NewHandler - Address of a new high level handler.
;
;       Install a new IRQ trap wrapper in the ARM execptions vector.
;	*** Call with interrupts disabled.
;

; Indirect pointers to IRQ handling routines.
_pHandleIRQ	DCD uHALp_HandleIRQ	    

uHALir_NewIRQ
	STMFD	sp!, {r4-r7, r14}	; save working registers
	;; Store the address of the high-level handler in the vector. We
	;; use an indirect vector so we don't have to worry about branch
	;; ranges.
	LDR	r4, _pHandleIRQ
	STR	r0, [r4]

	; Cache flushes need to be in Supervisor mode (as may vector access).
	BL	uHALir_EnterSvcMode	; Returns SPSR in r0

	CMP	r1, #0			; If no low-level vector is given
					; use the one from the library.
	LDREQ	r1, =uHALir_TrapIRQ	; This is where we want to go today

	MOV	r0, #IrqV		; IRQ vector lives here

	BL	uHALir_NewVector
	CMP	r0, #0			; Check for failure
1	BEQ	%1			; What do we do now? Spin..

	BL	uHALir_ExitSvcMode	; Needs SPSR in r0
	LDMFD	sp!, {r4-r7, pc}	; restore registers & return


; ------------------------------------------------------------------
;	void uHALir_DisableInt(void)
;	void uHALir_EnableInt(void)
;
;	Disable and enable IRQ, preserving current CPU mode.
;
uHALir_DisableInt
	STMFD	sp!, {r4}
	MRS	r4, cpsr
	ORR	r4, r4, #NoIRQ
	MSR	cpsr_c, r4
	LDMFD	sp!, {r4}
	MOV	pc, r14

uHALir_EnableInt
	STMFD	sp!, {r4}
	MRS	r4, cpsr
	BIC	r4, r4, #NoIRQ
	MSR	cpsr_c, r4
	LDMFD	sp!, {r4}
	MOV	pc, r14


; ------------------------------------------------------------------
; Routine to process known SWIs from 'C'
; Expects SWI in r0 & parameter (if any) in r1
uHALir_DoSWI
	STMFD	sp!, {r4-r12, r14}	; save working registers

	CMP	r0, #angel_SWI_SYS_READC	; Is it a GetByte?
	SWIEQ	SWI_Angel

	CMP	r0, #angel_SWI_SYS_WRITEC	; Is it a PutByte?
	SWIEQ	SWI_Angel

	LDMFD	sp!, {r4-r12, pc}	; restore registers & return


	END				; End of file

⌨️ 快捷键说明

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