📄 callout_interrupt_83xx.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" .include "ppc/util.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.#.equ IPIC_SICFR, 0x0700.equ IPIC_SIVCR, 0x0704.equ IPIC_SIPNR_H, 0x0708.equ IPIC_SIPNR_L, 0x070C.equ IPIC_SIMSR_H, 0x0720.equ IPIC_SIMSR_L, 0x0724.equ IPIC_SEPNR, 0x072C.equ IPIC_SEMSR, 0x0738patcher: # 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 loadi %r3, 0x800 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 ®,(&dev_reg_off) >> 16 ori ®,®,(&dev_reg_off) & 0xffff.endm# # int interrupt_id(void)## Returns: interrupt level, masks it off#CALLOUT_START interrupt_id_83xx, 0, patcher # get id DEVBASE %r5, 0x12345678 lbz %r14, IPIC_SIVCR + 3(%r5) # mask interrupt # later opt it to a lookup table cmplwi %r14, 16 bgt 1f # SPI to UART1 addi %r6, %r14, 15 li %r8, IPIC_SIMSR_H b 2f1: mr %r6, %r14 cmpwi %r6, 48 bne 1f li %r6, 161: cmplwi %r6, 23 bgt 1f # External interrupt 0 to 7 subi %r6, %r6, 16 li %r8, IPIC_SEMSR b 2f1: cmplwi %r14, 63 bgt 1f # TSEC1 to USBMPH subi %r6, %r14, 32 li %r8, IPIC_SIMSR_H b 2f # 64 to 911: subi %r6, %r14, 64 li %r8, IPIC_SIMSR_L2: lis %r7, 0x8000 srw %r7, %r7, %r6 # mask it lwzx %r6, %r5, %r8 andc %r6, %r6, %r7 stwx %r6, %r5, %r8CALLOUT_END interrupt_id_83xx # # void interrupt_eoi## Send an end-of-interrupt, then unmask the level (interrupt_id masked it)#CALLOUT_START interrupt_eoi_83xx, 0, patcher # later opt it to a lookup table DEVBASE %r5, 0x12345678 cmplwi %r14, 16 bgt 1f # SPI to UART1 addi %r6, %r14, 15 li %r8, IPIC_SIMSR_H li %r9, IPIC_SIPNR_H b 2f1: mr %r6, %r14 cmpwi %r6, 48 bne 1f li %r6, 161: cmplwi %r6, 23 bgt 1f # External interrupt 0 to 7 subi %r6, %r6, 16 li %r8, IPIC_SEMSR li %r9, IPIC_SEPNR b 2f1: cmplwi %r14, 63 bgt 1f # TSEC1 to USBMPH subi %r6, %r14, 32 li %r8, IPIC_SIMSR_H li %r9, IPIC_SIPNR_H b 2f # 64 to 911: subi %r6, %r14, 64 li %r8, IPIC_SIMSR_L li %r9, IPIC_SIPNR_L2: lis %r7, 0x8000 srw %r7, %r7, %r6 # eoi first # some sources with event registers might not need it NIY stwx %r7, %r5, %r9 cmplwi %r18, 0 bgt 1f # unmask it lwzx %r6, %r5, %r8 or %r6, %r6, %r7 stwx %r6, %r5, %r81:CALLOUT_END interrupt_eoi_83xx ## int interrupt_unmask(struct syspage_entry *sysp, int intr)## Unmask the passed hardware interrupt number.#CALLOUT_START interrupt_unmask_83xx, 0, patcher # later opt it to a lookup table DEVBASE %r5, 0x12345678 cmplwi %r4, 16 bgt 1f # SPI to UART1 addi %r6, %r4, 15 li %r8, IPIC_SIMSR_H b 2f1: mr %r6, %r4 cmplwi %r6, 48 bne 1f li %r6, 161: cmplwi %r6, 23 bgt 1f # External interrupt 0 to 7 subi %r6, %r6, 16 li %r8, IPIC_SEMSR b 2f1: cmplwi %r4, 63 bgt 1f # TSEC1 to USBMPH subi %r6, %r4, 32 li %r8, IPIC_SIMSR_H b 2f # 64 to 911: subi %r6, %r4, 64 li %r8, IPIC_SIMSR_L2: # unmask it lis %r7, 0x8000 srw %r7, %r7, %r6 lwzx %r6, %r5, %r8 or %r6, %r6, %r7 stwx %r6, %r5, %r8 li %r3, 0 blrCALLOUT_END interrupt_unmask_83xx ## int interrupt_mask(struct syspage_entry *sysp, int intr)## Mask the passed hardware interrupt number.#CALLOUT_START interrupt_mask_83xx, 0, patcher # later opt it to a lookup table DEVBASE %r5, 0x12345678 cmplwi %r4, 16 bgt 1f # SPI to UART1 addi %r6, %r4, 15 li %r8, IPIC_SIMSR_H b 2f1: mr %r6, %r4 cmplwi %r6, 48 bne 1f li %r6, 161: cmplwi %r6, 23 bgt 1f # External interrupt 0 to 7 subi %r6, %r6, 16 li %r8, IPIC_SEMSR b 2f1: cmplwi %r4, 63 bgt 1f # TSEC1 to USBMPH subi %r6, %r4, 32 li %r8, IPIC_SIMSR_H b 2f # 64 to 911: subi %r6, %r4, 64 li %r8, IPIC_SIMSR_L2: lis %r7, 0x8000 srw %r7, %r7, %r6 # mask it lwzx %r6, %r5, %r8 andc %r6, %r6, %r7 stwx %r6, %r5, %r8 li %r3, 0 blrCALLOUT_END interrupt_mask_83xx
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -