📄 callout_interrupt_85xx.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, 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) cmplwi %r14,64 blt 1f /* 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 real vector. */ stw %r0,0(%r7) li %r14, -11: mtmsr %r12 isyncCALLOUT_END interrupt_id_ppc85xx # # void interrupt_eoi(struct syspage_entry *sysp, int intr)## EOI the interrupt#CALLOUT_START interrupt_eoi_ppc85xx, 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## int interrupt_unmask(struct syspage_entry *sysp, int intr)## Unmask the passed hardware interrupt number.#CALLOUT_START interrupt_unmask_ppc85xx, 0, patcher DEVBASE %r9,0 loadi %r7,5 cmplwi %r4,52 blt 1f # messages loadi %r5,PPC85xx_CCSR_OFF_MIVPR0 loadi %r6,52 b 2f1: cmplwi %r4,48 blt 1f # timers loadi %r5,PPC85xx_CCSR_OFF_GTVPR0 loadi %r6,48 loadi %r7,6 b 2f1: cmplwi %r4,44 blt 1f # IPI loadi %r5,PPC85xx_CCSR_OFF_IPIVPR0 loadi %r6,44 loadi %r7,4 b 2f1: cmplwi %r4,32 blt 1f # external loadi %r5,PPC85xx_CCSR_OFF_EIVPR0 loadi %r6,32 b 2f1: # internal loadi %r5,PPC85xx_CCSR_OFF_IIVPR0 loadi %r6,02: 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 isync li %r3,0 blrCALLOUT_END interrupt_unmask_ppc85xx ## void interrupt_mask(struct syspage_entry *sysp, int intr)## Mask the passed hardware interrupt number.#CALLOUT_START interrupt_mask_ppc85xx, 0, patcher DEVBASE %r9,0 loadi %r7,5 cmplwi %r4,52 blt 1f # messages loadi %r5,PPC85xx_CCSR_OFF_MIVPR0 loadi %r6,52 b 2f1: cmplwi %r4,48 blt 1f # timers loadi %r5,PPC85xx_CCSR_OFF_GTVPR0 loadi %r6,48 loadi %r7,6 b 2f1: cmplwi %r4,44 blt 1f # IPI loadi %r5,PPC85xx_CCSR_OFF_IPIVPR0 loadi %r6,44 loadi %r7,4 b 2f1: cmplwi %r4,32 blt 1f # external loadi %r5,PPC85xx_CCSR_OFF_EIVPR0 loadi %r6,32 b 2f1: # internal loadi %r5,PPC85xx_CCSR_OFF_IIVPR0 loadi %r6,02: 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 isync li %r3,0 blrCALLOUT_END interrupt_mask_ppc85xx## Return special config for the passed hardware interrupt number.#CALLOUT_START interrupt_config_ppc85xx, 0, 0 li %r3,0 blrCALLOUT_END interrupt_config_ppc85xx
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -