📄 callout_interrupt_epic.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.#.set EPIC_BASE, 0xfc040000.set EPIC_INTREG_BASE, 0x10200.set EPIC_INTACK_1, 0x200a0.set EPIC_INTEOI_1, 0x200b0.set EPIC_INT_DES_OFF, 0x10.set EPIC_INT_REGOFF_SFT, 5.set EPIC_INT_NUM, 0x1a.set EPIC_DUART_INTREG_BASE, 0x11120.set EPIC_DUART_REGOFF_SFT, 5.set EPIC_DUART_VECTOR_SHIFT, -16 .set EPIC_TIMER_INTREG_BASE, 0x1120.set EPIC_TIMER_REGOFF_SFT, 6.set EPIC_TIMER_VECTOR_SHIFT, -22.set EPIC_I2C_DMA_INTREG_BASE, 0x11020.set EPIC_I2C_DMA_REGOFF_SFT, 5.set EPIC_I2C_DMA_VECTOR_SHIFT, -25.set EPIC_MSG_INTREG_BASE, 0x110c0.set EPIC_MSG_REGOFF_SFT, 5.set EPIC_MSG_VECTOR_SHIFT, -26# 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.macro DEVBASE reg,dev_reg_off # the instruction immediate values are patched by the above routine lis ®,(&dev_reg_off) >> 16 ori ®,®,(&dev_reg_off) & 0xffff.endmCALLOUT_START interrupt_unmask_epic, 0, patcher DEVBASE %r5,0 cmpwi %r4,16 bge 1f loadi %r6,EPIC_INTREG_BASE add %r5,%r5,%r6 li %r6,EPIC_INT_REGOFF_SFT slw %r6,%r4,%r6 add %r5,%r5,%r6 b 5f1: cmpwi %r4,18 bge 2f loadi %r6,EPIC_DUART_INTREG_BASE add %r5,%r5,%r6 addi %r4,%r4,EPIC_DUART_VECTOR_SHIFT li %r6,EPIC_DUART_REGOFF_SFT slw %r6,%r4,%r6 add %r5,%r5,%r6 b 5f2: cmpwi %r4,22 bge 3f loadi %r6,EPIC_TIMER_INTREG_BASE add %r5,%r5,%r6 addi %r4,%r4,EPIC_TIMER_VECTOR_SHIFT li %r6,EPIC_TIMER_REGOFF_SFT slw %r6,%r4,%r6 add %r5,%r5,%r6 b 5f3: cmpwi %r4,25 bge 4f loadi %r6,EPIC_I2C_DMA_INTREG_BASE add %r5,%r5,%r6 addi %r4,%r4,EPIC_I2C_DMA_VECTOR_SHIFT li %r6,EPIC_I2C_DMA_REGOFF_SFT slw %r6,%r4,%r6 add %r5,%r5,%r6 b 5f4: loadi %r6,EPIC_MSG_INTREG_BASE add %r5,%r5,%r6 addi %r4,%r4,EPIC_MSG_VECTOR_SHIFT li %r6,EPIC_MSG_REGOFF_SFT slw %r6,%r4,%r6 add %r5,%r5,%r6 b 5f5: lwz %r6,0(%r5) rlwinm %r6,%r6,0,25,23 eieio stw %r6,0(%r5) sync li %r3,0 blrCALLOUT_END interrupt_unmask_epicCALLOUT_START interrupt_mask_epic, 0, patcher DEVBASE %r5,0 cmpwi %r4,16 bge 1f loadi %r6,EPIC_INTREG_BASE add %r5,%r5,%r6 li %r6,EPIC_INT_REGOFF_SFT slw %r6,%r4,%r6 add %r5,%r5,%r6 b 5f1: cmpwi %r4,18 bge 2f loadi %r6,EPIC_DUART_INTREG_BASE add %r5,%r5,%r6 addi %r4,%r4,EPIC_DUART_VECTOR_SHIFT li %r6,EPIC_DUART_REGOFF_SFT slw %r6,%r4,%r6 add %r5,%r5,%r6 b 5f2: cmpwi %r4,22 bge 3f loadi %r6,EPIC_TIMER_INTREG_BASE add %r5,%r5,%r6 addi %r4,%r4,EPIC_TIMER_VECTOR_SHIFT li %r6,EPIC_TIMER_REGOFF_SFT slw %r6,%r4,%r6 add %r5,%r5,%r6 b 5f3: cmpwi %r4,25 bge 4f loadi %r6,EPIC_I2C_DMA_INTREG_BASE add %r5,%r5,%r6 addi %r4,%r4,EPIC_I2C_DMA_VECTOR_SHIFT li %r6,EPIC_I2C_DMA_REGOFF_SFT slw %r6,%r4,%r6 add %r5,%r5,%r6 b 5f4: loadi %r6,EPIC_MSG_INTREG_BASE add %r5,%r5,%r6 addi %r4,%r4,EPIC_MSG_VECTOR_SHIFT li %r6,EPIC_MSG_REGOFF_SFT slw %r6,%r4,%r6 add %r5,%r5,%r6 b 5f5: lwz %r6,0(%r5) ori %r6,%r6,0x80 eieio stw %r6,0(%r5) sync li %r3,0 blrCALLOUT_END interrupt_mask_epicCALLOUT_START interrupt_id_epic, 0, patcher DEVBASE %r5,EPIC_INTACK_1 # address of PCI INTACK eieio lwbrx %r6,0,%r5 # ack int for PCI bus cmpwi %r6,0xff bne+ 1f li %r6,-11: mr %r14,%r6 CALLOUT_END interrupt_id_epicCALLOUT_START interrupt_eoi_epic, 0, patcher DEVBASE %r5,EPIC_INTEOI_1 # address of PCI INTEOI li %r0,0 eieio stw %r0,0(%r5) # ack int for PCI bus CALLOUT_END interrupt_eoi_epic
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -