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

📄 callout_interrupt_mv64360.s

📁 qnx powerpc MPC8245的 BSP源文件
💻 S
字号:
#  # Copyright 2007, QNX Software Systems. #  # Licensed under the Apache License, Version 2.0 (the "License"). You # may not reproduce, modify or distribute this software except in # compliance with the License. You may obtain a copy of the License # at: http://www.apache.org/licenses/LICENSE-2.0 #  # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" basis, # WITHOUT WARRANTIES OF ANY KIND, either express or implied.# # This file may contain contributions from others, either as # contributors under the License or as licensors under other terms.  # Please review this entire file for other proprietary rights or license # notices, as well as the QNX Development Suite License Guide at # http://licensing.qnx.com/license-guide/ for other information.# # An entry point for a hardware kernel callout.# It may be called by an interrupt handler.# This code MUST be position independant.#	.include "callout.ah"## Interrupts are always off in this code.## Note that interrupt_id_* and interrupt_eoi_* are not actually# called by the kernel. For performance reasons, they are instead# copied into place and intermixed with other kernel code. As such,# they don't follow normal calling conventions. They should just fall out # their bottoms when done rather than attempting to do a return # instruction. The 'id' routine should return the interrupt level in# the r14 register. The 'eoi' routine will find it still there. # By turning on various INTR_GENFLAG_* bits in the intrinfo_entry,# the following values can be loaded before entry to this code.# #		cpu number			=> r15#		syspage_ptr			=> r16#		intrinfo_entry		=> r17#		intr mask count		=> r18 (only available in EOI routine)## If the INTR_FLAG_CPU_FAULT bit is on, the eoi routine should set# the A0 register to the following value to indicate the exception# that has occurred:# 		R3 = (fault_number << 16) | (signal_code << 8) | (signal_number)# Set R3 to zero if no exception has occured. If the exception is memory# related, set R4 to referenced address that caused the exception, zero# if there is no address.#		.extern	mv64360_base# R3: syspage paddr# R4: syspage vaddr# R5: rtn dst offset# R6: r/w offset# R7: patch data# R8: rtn srcpatcher:	stwu	%r1,-32(%r1)	mflr	%r0	stw		%r31,28(%r1)	stw		%r0,36(%r1)		add		%r31,%r3,%r5	   	mr		%r4,%r7	loadi	%r3,0x30000	bl		callout_io_map_indirect	lhz		%r4,6(%r31)	lhz		%r5,2(%r31)	slwi	%r5,%r5,16	or		%r4,%r4,%r5	add		%r3,%r3,%r4	sth		%r3,6(%r31)	srwi	%r3,%r3,16	sth		%r3,2(%r31)		lwz		%r0,36(%r1)	mtlr	%r0	lwz		%r31,28(%r1)	addi	%r1,%r1,32	blr	.ifdef __LITTLEENDIAN__.error lwbrx's used below assume that we're running big endian.endif.macro DEVBASE reg,dev_reg_off	# the instruction immediate values are patched by the above routine	lis		&reg,(&dev_reg_off) >> 16	ori		&reg,&reg,(&dev_reg_off) & 0xffff.endm# offsets from the base of the system controller.set CPU_CAUSE,				0x0024.set CPUMASK_LO,			0x0014.set CPUMASK_HI,			0x001c.set CPUMASK1_LO,			0x0014.set CPUMASK1_HI,			0x001c.set GPP_CAUSE,				0xf108.set GPP_MASK,				0xf10c.set CPU0_DOORBELL_CLEAR,  	0x021c.set CPU1_DOORBELL_CLEAR,	0x022c		# # int interrupt_id(void)## Returns: interrupt level, masks it off#CALLOUT_START	interrupt_id_mv64360, 0, patcher	DEVBASE	%r9,0	slwi	%r11,%r15,5	add		%r11,%r11,%r9	loadi	%r5,CPU_CAUSE		lwbrx	%r3,%r11,%r5			# read cause#	andis.	%r0,%r3,0x8000#	beq-	3f	andis.	%r0,%r3,0x4000	bne	1f	# Low cause is set	loadi	%r5,CPUMASK_LO	lwbrx	%r4,%r11,%r5			# read mask		and		%r4,%r3,%r4	rlwinm	%r3,%r4,0,2,31	cntlzw	%r7,%r3	cmpwi	%r7,32	beq-	3f	subfic	%r8,%r7,31	rlwinm	%r3,%r8,0,0,29	cmpwi	%r3,24	beq		2f	cmplwi	%r8,28	# Don't mask doorbell CPU 1 doorbell int	bne		11f	mr		%r14,%r8    loadi   %r7,CPU1_DOORBELL_CLEAR    li  	%r6,0x01    stbx 	%r6,%r7,%r9	b		4f11:	# Vector in %r8; now mask	li		%r6,1	slw		%r6,%r6,%r8	lwbrx	%r3,%r11,%r5	andc	%r3,%r3,%r6	stwbrx	%r3,%r11,%r5	mr		%r14,%r8	b		4f1:		# High cause is set	loadi	%r5,CPUMASK_HI	lwbrx	%r4,%r11,%r5			# read mask		and		%r4,%r3,%r4	rlwinm	%r3,%r4,0,2,31	cntlzw	%r7,%r3	cmpwi	%r7,32	beq-	3f	subfic	%r8,%r7,31	rlwinm	%r3,%r8,0,0,29	cmpwi	%r3,24	beq		2f	cmplwi	%r8,28	# Don't mask doorbell CPU 0 doorbell int	bne	12f	addi	%r14,%r8,32	loadi   %r7,CPU0_DOORBELL_CLEAR	li  	%r6,0x01	stbx 	%r6,%r7,%r9	b	4f12:	# Vector in %r8; now mask	li		%r6,1	slw		%r6,%r6,%r8	lwbrx	%r3,%r11,%r5	andc	%r3,%r3,%r6	stwbrx	%r3,%r11,%r5	addi	%r14,%r8,32	b		4f2:	# GPP pin active	loadi	%r5,GPP_CAUSE	lwbrx	%r3,%r5,%r9	loadi	%r5,GPP_MASK	lwbrx	%r4,%r5,%r9	and		%r3,%r4,%r3	cntlzw	%r7,%r3	cmpwi	%r7,32	beq-	3f	subfic	%r8,%r7,31	# %r8 has the vector -- now mask GPP level	li		%r6,1	loadi	%r5,GPP_MASK	slw		%r6,%r6,%r8	lwbrx	%r3,%r5,%r9	andc	%r3,%r3,%r6	stwbrx	%r3,%r5,%r9	# And clear cause register bit we're interested in	not		%r6,%r6	loadi	%r5,GPP_CAUSE	stwbrx	%r6,%r5,%r9	addi	%r14,%r8,64	b		6f3:	# Spurious int	li		%r14,-14:6:CALLOUT_END	interrupt_id_mv64360		# # void interrupt_eoi(struct syspage_entry *sysp, int intr)## Unmask the level (interrupt_id masked it)#CALLOUT_START	interrupt_eoi_mv64360, 0, patcher	DEVBASE	%r9,0	# Unmask the level -- r14 still has the level	cmplwi	%r18,0	bgt		3f	slwi	%r11,%r15,5	add		%r11,%r11,%r9	# What logical unit does it go to?	cmplwi 	%r14,64	bge		1f	cmplwi 	%r14,32	bge 	2f	# CAUSE low	loadi	%r5,CPUMASK_LO	li		%r6,1	slw		%r6,%r6,%r14	lwbrx	%r3,%r11,%r5	or		%r3,%r3,%r6	stwbrx	%r3,%r11,%r5	b		3f2:	# CAUSE high	subi	%r4,%r14,32	loadi	%r5,CPUMASK_HI	li		%r6,1	slw		%r6,%r6,%r4	lwbrx	%r3,%r11,%r5	or		%r3,%r3,%r6	stwbrx	%r3,%r11,%r5	b		3f1:	# GPP interrupt	loadi	%r5,GPP_MASK	subi	%r4,%r14,64	li		%r6,1	slw		%r6,%r6,%r4	lwbrx	%r0,%r5,%r9	or		%r0,%r0,%r6	stwbrx	%r0,%r5,%r93:CALLOUT_END	interrupt_eoi_mv64360## int interrupt_unmask(struct syspage_entry *sysp, int intr)## Unmask the passed hardware interrupt number.#CALLOUT_START	interrupt_unmask_mv64360, 0, patcher	DEVBASE		%r9,0	# What logical unit does it go to?	cmplwi 	%r4,64	bge		1f	cmplwi 	%r4,32	bge 	2f	# CAUSE low	loadi	%r5,CPUMASK_LO	b		3f2:	# CAUSE high	subi	%r4,%r4,32	loadi	%r5,CPUMASK_HI	b		3f1:	# GPP interrupt	subi	%r4,%r4,64	loadi	%r5,GPP_MASK3:	li		%r6,1	slw		%r6,%r6,%r4	lwbrx	%r0,%r5,%r9	or		%r0,%r0,%r6	stwbrx	%r0,%r5,%r9	li		%r3,0	blrCALLOUT_END	interrupt_unmask_mv64360	## void interrupt_mask(struct syspage_entry *sysp, int intr)## Mask the passed hardware interrupt number.#CALLOUT_START	interrupt_mask_mv64360, 0, patcher	DEVBASE	%r9,0	# What logical unit does it go to?	cmplwi 	%r4,64	bge		1f	cmplwi 	%r4,32	bge 	2f	# CAUSE low	loadi	%r5,CPUMASK_LO	b		3f2:	# CAUSE high	subi	%r4,%r4,32	loadi	%r5,CPUMASK_HI	b		3f1:	# GPP interrupt	subi	%r4,%r4,64	loadi	%r5,GPP_MASK3:	li		%r6,1	slw		%r6,%r6,%r4	lwbrx	%r0,%r5,%r9	andc	%r0,%r0,%r6	stwbrx	%r0,%r5,%r9	li		%r3,0	blrCALLOUT_END	interrupt_mask_mv64360## Return special config for the passed hardware interrupt number.#CALLOUT_START   interrupt_config_mv64360, 0, 0# on MV64360, CPU 1's doorbell interrupt maps to IRQ 28, and CPU 0's# doorbell interrupt maps to IRQ 60    cmpwi   %r5,28    beq 	1f    cmpwi   %r5,60    beq 	1f    li  	%r3,0    blr1:	li		%r3,INTR_CONFIG_FLAG_IPI|INTR_CONFIG_FLAG_DISALLOWED    blrCALLOUT_END interrupt_config_mv64360

⌨️ 快捷键说明

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