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

📄 callout_interrupt_82xx_pci.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.# #		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.## MPC82xxADS uses CPLD for PCI Interrupt.patcher:	# R3: syspage paddr	# R4: syspage vaddr	# R5: rtn dst offset	# R6: r/w offset	# R7: patch data	# R8: rtn src	stwu    %r1,-32(%r1)	mflr    %r0	stw     %r31,28(%r1)	stw     %r0,36(%r1)	add     %r31,%r3,%r5	mr      %r4,%r7	li		%r3, 0x08	bl      callout_io_map_indirect	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.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# # int interrupt_id(void)## Returns: interrupt level in r14, masks it off.#CALLOUT_START	interrupt_id_82xxads_pci, 0, patcher	DEVBASE %r6, 0x12345678 		# get PCI interrupt controller base address (patched)	li		%r14, -1				# put 0x7fffffff into r14	lwz		%r5, 0(%r6)				# load value of status register into r5	lwz		%r4, 4(%r6)				# load value of mask register into r4	eieio	andc	%r5, %r5, %r4			# only look the first 12 bits	cmpwi	%r5, 0					# if no interrupts, we're done	beq		1f	cntlzw	%r14, %r5				# count leading zeros in r5, place resulting interrupt value in r14	lis		%r5, 0x8000	srw		%r5, %r5, %r14			# shift mask bit right to position of interrupt we wish to mask	or		%r4, %r4, %r5			# and r7 with one's compliment of mask bit, set relevant bit	stw		%r4, 4(%r6)				# load new enable mask into mask register	eieio1:CALLOUT_END interrupt_id_82xxads_pci# # void interrupt_eoi(struct syspage_entry *sysp, int intr)## Send an end-of-interrupt, then unmask the level (interrupt_id masked it).# r14 contains the interrupt value.#CALLOUT_START	interrupt_eoi_82xxads_pci, 0, patcher	DEVBASE %r6, 0x12345678 		# get PCI interrupt controller base address (patched)	cmplwi	%r18, 0					# if intr mask count > 0, don't unmask int	bgt		1f	lis		%r5, 0x8000	srw		%r5, %r5, %r14			# shift unmask bit to proper position	lwz		%r4, 4(%r6)				# load value of status register into r4	eieio	andc	%r5, %r4, %r5	stw		%r5, 4(%r6)				# write new mask value	eieio1:CALLOUT_END	interrupt_eoi_82xxads_pci## int interrupt_unmask(struct syspage_entry *sysp, int intr)## Unmask the passed hardware interrupt number. The interrupt gets# passed in r4. Unmask is performed by clearing (enabling) the bit# in the interrupt mask register corresponds to the value in r4.#CALLOUT_START	interrupt_unmask_82xxads_pci, 0, patcher	DEVBASE %r6, 0x12345678 		# get PCI interrupt controller base address (patched)	lis		%r5, 0x8000	srw		%r5, %r5, %r4			# shift unmask bit to proper position	lwz		%r7, 4(%r6)				# load status into r7	eieio	andc	%r5, %r7, %r5	stw		%r5, 4(%r6)				# store new mask register value	eieio	li		%r3, 0	blrCALLOUT_END	interrupt_unmask_82xxads_pci	## void interrupt_mask(struct syspage_entry *sysp, int intr)## Mask the passed hardware interrupt number. Masking is performed by setting# (disabling) the bit in the interrupt mask register which corresponds to the # value passed in r4.#CALLOUT_START	interrupt_mask_82xxads_pci, 0, patcher	DEVBASE %r6, 0x12345678 		# get PCI interrupt controller base address (patched)	lwz		%r5, 4(%r6)				# load contents of status register into r5	eieio	lis		%r7, 0x8000	srw		%r7, %r7, %r4			# shift mask bit to proper position in r6	or		%r5, %r5, %r7			# and r5 with one's compliment of r6 to mask interrupt	stw		%r5, 4(%r6)				# load new interrupt mask into mask register	eieio	li		%r3, 0	blrCALLOUT_END	interrupt_mask_82xxads_pci		

⌨️ 快捷键说明

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