📄 callout_interrupt_85xx_extnd.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.# # 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,1024*1024 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.endm # # int interrupt_id(void)## Returns: interrupt level#CALLOUT_START interrupt_id_ppc85xx_extnd, 0, patcher DEVBASE %r9,PPC85xx_CCSR_OFF_PC_IACK /* EOI register address stored in r7 */ addi %r7,%r9,(PPC85xx_CCSR_OFF_PC_EOI - PPC85xx_CCSR_OFF_PC_IACK) loadi %r0,0 mfmsr %r12 loadi %r11,PPC_MSR_EE|PPC_MSR_CE|PPC_MSR_DR andc %r11,%r12,%r11 mtmsr %r11 isync lwz %r14,0(%r9) /* Don't handle vector < 150 or > 174 */ cmplwi %r14, 150 blt- 3f cmplwi %r14, 175 blt+ 1f3: /* EOI the interrupt so it gets re-asserted and can be picked up by the next handler. If we don't EOI, then the next handler will read the spurious vector value from the IACK register instead of the vector last read. */ stw %r0,0(%r7) li %r14, -1 b 2f1: # Subtract extended base to get offset for this range. subi %r14,%r14,1502: mtmsr %r12 isyncCALLOUT_END interrupt_id_ppc85xx_extnd # # void interrupt_eoi(struct syspage_entry *sysp, int intr)## EOI the interrupt#CALLOUT_START interrupt_eoi_ppc85xx_extnd, 0, patcher DEVBASE %r9,PPC85xx_CCSR_OFF_PC_EOI loadi %r0,0 mfmsr %r12 loadi %r11,PPC_MSR_EE|PPC_MSR_CE|PPC_MSR_DR andc %r11,%r12,%r11 mtmsr %r11 isync stw %r0,0(%r9) mtmsr %r12 isyncCALLOUT_END interrupt_eoi_ppc85xx_extnd## int interrupt_unmask(struct syspage_entry *sysp, int intr)## Unmask the passed hardware interrupt number.#CALLOUT_START interrupt_unmask_ppc85xx_extnd, 0, patcher DEVBASE %r9,0 loadi %r7,5 cmplwi %r4,16 blt 1f # Shared messages loadi %r5,PPC85xx_CCSR_OFF_MSIVPR0 loadi %r6,16 b 2f1: # Extended internal interrupts run from 0-8 loadi %r5,PPC85xx_CCSR_OFF_IIVPR0 # Extended internal interrupts must start at internal interrupt 32 # so offset starting point by 32 loadi %r6,-32 b 2f2: sub %r4,%r4,%r6 slw %r4,%r4,%r7 add %r9,%r9,%r5 mfmsr %r12 loadi %r11,PPC_MSR_EE|PPC_MSR_CE|PPC_MSR_DR andc %r11,%r12,%r11 mtmsr %r11 isync lwzx %r0,%r9,%r4 bitclr %r0,%r0,0x80000000 stwx %r0,%r9,%r4 mtmsr %r12 isync4: li %r3,0 blrCALLOUT_END interrupt_unmask_ppc85xx_extnd ## void interrupt_mask(struct syspage_entry *sysp, int intr)## Mask the passed hardware interrupt number.#CALLOUT_START interrupt_mask_ppc85xx_extnd, 0, patcher DEVBASE %r9,0 loadi %r7,5 cmplwi %r4,16 blt 1f # shared messages loadi %r5,PPC85xx_CCSR_OFF_MSIVPR0 loadi %r6,16 b 2f1: # Extended internal interrupts loadi %r5,PPC85xx_CCSR_OFF_IIVPR0 # Extended internal interrupts must start at internal interrupt 32 # so offset starting point by 32 loadi %r6,-32 b 2f2: sub %r4,%r4,%r6 slw %r4,%r4,%r7 add %r9,%r9,%r5 mfmsr %r12 loadi %r11,PPC_MSR_EE|PPC_MSR_CE|PPC_MSR_DR andc %r11,%r12,%r11 mtmsr %r11 isync lwzx %r0,%r9,%r4 bitset %r0,%r0,0x80000000 stwx %r0,%r9,%r4 mtmsr %r12 isync4: li %r3,0 blrCALLOUT_END interrupt_mask_ppc85xx_extnd## Return special config for the passed hardware interrupt number.#CALLOUT_START interrupt_config_ppc85xx_extnd, 0, 0 li %r3,0 blrCALLOUT_END interrupt_config_ppc85xx_extnd
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -