📄 callout_interrupt_ibm_uic.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.#.ifdef PPC_CPUOP_ENABLED .cpu 403.endif .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 R3 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.#uic_patcher: # r3 syspage_paddr # r4 syspage_vaddr # r5 rtn_off # r6 rw_off # r7 patch_data # r8 callout_rtn * add %r3,%r3,%r5 # point to rtn destination lwz %r9,8(%r8) # get length of routine loadi %r10,41: lwz %r4,0(%r3) # get instruction rlwinm %r5,%r4,0,21,5 # isolate instruction bits loadi %r6,0x7c000286 # compare with mfdcr ?,? cmplw %r5,%r6 # ... beq 2f # yup? loadi %r6,0x7c000386 # compare with mtdcr ?,? cmplw %r5,%r6 # ... bne 3f # nope?2: # # is a m[t/f]dcr instruction - calculate real register value # rlwinm %r5,%r4,21+5,22,26 # extract the DCR offset rlwimi %r5,%r4,21-5,27,31 # ... add %r5,%r5,%r7 # add on base DCR value rlwimi %r4,%r5,11+5,11,15 # put the new DCR value back rlwimi %r4,%r5,11-5,16,20 # ... stw %r4,0(%r3)3: add %r3,%r3,%r10 # do next instruction sub. %r9,%r9,%r10 bne 1b blr # # int interrupt_id(void)## Returns: interrupt level, masks it off#CALLOUT_START interrupt_id_ibm_uic, 0, uic_patcher li %r14,-1 mfdcr %r5,PPCIBM_DCROFF_UIC_MSR cmplwi %r5,0 beq- 1f mfdcr %r4,PPCIBM_DCROFF_UIC_ER cntlzw %r14,%r5 lis %r5,0x8000 srw %r5,%r5,%r14 andc %r4,%r4,%r5 mtdcr PPCIBM_DCROFF_UIC_ER,%r41:CALLOUT_END interrupt_id_ibm_uic # # interrupt_eoi## Send an end-of-interrupt, then unmask the level (interrupt_id masked it)#CALLOUT_START interrupt_eoi_ibm_uic, 0, uic_patcher lis %r5,0x8000 srw %r5,%r5,%r14 mtdcr PPCIBM_DCROFF_UIC_SR,%r5 cmplwi %r18,0 bgt 1f mfdcr %r6,PPCIBM_DCROFF_UIC_ER or %r5,%r5,%r6 mtdcr PPCIBM_DCROFF_UIC_ER,%r51:CALLOUT_END interrupt_eoi_ibm_uic ## int interrupt_unmask(struct syspage_entry *sysp, int intr)## Unmask the passed hardware interrupt number.#CALLOUT_START interrupt_unmask_ibm_uic, 0, uic_patcher mfdcr %r5,PPCIBM_DCROFF_UIC_ER lis %r6,0x8000 srw %r6,%r6,%r4 or %r5,%r5,%r6 mfdcr %r6,PPCIBM_DCROFF_UIC_TR andc %r6,%r5,%r6 mtdcr PPCIBM_DCROFF_UIC_SR,%r6 mtdcr PPCIBM_DCROFF_UIC_ER,%r5 li %r3,0 blrCALLOUT_END interrupt_unmask_ibm_uic ## int interrupt_mask(struct syspage_entry *sysp, int intr)## Mask the passed hardware interrupt number.#CALLOUT_START interrupt_mask_ibm_uic, 0, uic_patcher mfdcr %r5,PPCIBM_DCROFF_UIC_ER lis %r6,0x8000 srw %r6,%r6,%r4 andc %r5,%r5,%r6 mtdcr PPCIBM_DCROFF_UIC_ER,%r5 li %r3,0 blrCALLOUT_END interrupt_mask_ibm_uic
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -