⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 callout_interrupt_mgt5200.s

📁 qnx powerpc MPC8245的 BSP源文件
💻 S
📖 第 1 页 / 共 3 页
字号:
/* * $QNXLicenseC:  * 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"/* * int interrupt_unmask(struct syspage_entry *sysp, int intr) * * Unmask the passed hardware interrupt number. */.set MGT5200_PIMR,            0x0500.set MGT5200_PP_HLSR_1,       0x0504.set MGT5200_PP_HLSR_2,       0x0508.set MGT5200_PP_HLSR_3,       0x050C.set MGT5200_EE_ETR,          0x0510.set MGT5200_CP_MIMR,         0x0514.set MGT5200_MIP_SMI_1,       0x0518.set MGT5200_MIP_SMI_2,       0x051C.set MGT5200_ALL_STAT_ENC,    0x0524.set MGT5200_CISR,            0x0528.set MGT5200_MISR,            0x052C.set MGT5200_PISR,            0x0530.set MGT5200_GPIOSIE,		  0x0B20.set MGT5200_GPIOSIIE,		  0x0B30.set MGT5200_GPIOSSR,		  0x0B3C.set MGT5200_GPIOWIE,		  0x0C14.set MGT5200_GPIOWSR,		  0x0C24.set MGT5200_SCIMR,           0x1218.set MGT5200_SCIPR,           0x1214.set MGT5200_SLC_0_TERM,	  0x0700.set MGT5200_SLC_0_CTRL,	  0x0704.set MGT5200_SLC_0_STAT,	  0x070c.set MGT5200_SCTMR,			  0x0400.set MGT5200_SCTSR,			  0x0400patcher:	# 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	li		%r3, 0x08	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     &reg,(&dev_reg_off) >> 16	ori     &reg,&reg,(&dev_reg_off) & 0xffff.endm/*************************************************************************** * Callout : 	interrupt_id_mgt5200 * * Description: Determine critical or main interrupt level and mask it off *				(if appropriate) * * On Entry:	Nothing * * On Exit:		r14 = interrupt level * * Notes: * *	Test for core critical interrupts first:  * 	If the interrupt is 0, (UART1_4), mask it by clearing bit 20 of EE_ETR. * 	If the interrupt is 1 (slice timer 0), then we mask it by clearing the * 	interrupt enable bit of Slice Timer 0 Control Register. If it's 2, it's  * 	a cascade from some peripheral that's programmed to generate a HI int, * 	and we can't mask it directly, but it'll be taken care of by the *	peripheral callouts. * **************************************************************************/CALLOUT_START	interrupt_id_mgt5200, 0, patcher	DEVBASE %r6, 0x12345678	li		%r14,0	/* get all interrupt status, encoded */	lwz		%r5,MGT5200_ALL_STAT_ENC(%r6)			li		%r0, 0x0400		/* Critical Status flag */	and		%r0, %r0, %r5	/* clear all bits except status */	cmplwi	%r0,0	beq		4f				/* no critical interrupt, proceed to main interrupt id */	/* bits 22 and 23 represent the level. Load it into r14. */	srawi	%r14, %r5, 8	andi.	%r14, %r14, 3	cmplwi	%r14,0	bgt		1f	/* interrupt is 0, clear bit 20 of EE_ETR */    lwz     %r5,MGT5200_EE_ETR(%r6)    li      %r4,0x800               /* bit 20 is IRQ 0 enable bit */    andc    %r5,%r5,%r4             /* mask (clear) bit by ANDing with one's compliment of r4 */    stw     %r5, MGT5200_EE_ETR(%r6)             /* store new value */	b		6f	/* done */1:	cmplwi	%r14,1	bgt		3f		 	/* interrupt is 1, mask slice timer 0 interrupts */    lwz     %r5,MGT5200_SLC_0_CTRL(%r6)                 	lis		%r0,0x0200	andc	%r5, %r5, %r0	stw		%r5,MGT5200_SLC_0_CTRL(%r6)    lwz     %r5,MGT5200_SLC_0_STAT(%r6)	b		6f	/* done */2:    cmplwi  %r14,2    bgt     3f    /* For now, we'll pretend that this is a LO peripheral interrupt, since there seems to     * be a problem cascading from the HI source.     */    li      %r14,4  /* LO int is main level 4 (QNX vector 8) */    b       5f	3:	b		6f		/* placeholder for CCS module wakeup from sleep. */4:		/* main interrupt ID - r5 still contains Interrupt Status Register (encoded) */    /* bits 15 - 11 represent the level. Load it into r14. */	li	%r14, -1 	    srawi   %r8, %r5, 16    andi.   %r8, %r8, 0x3f        cmplwi	%r8,0		beq		6f	andi.	%r14, %r8, 0x1f	5:   /*    * now, load the main interrupt mask register, and set the appropriate bit    * to mask the interrupt    *    * Note: May want to prevent LO-int from being masked here and leave it to the peripheral    *       handler to mask only the peripheral causing the LO-int.    */   lwz     %r5,MGT5200_CP_MIMR(%r6)   lis     %r4, 1              /* puts 0x00010000 into r4 (bit 15) */   srw     %r4, %r4, %r14      /* shift the bit to the proper position */   or      %r5, %r5, %r4   stw     %r5, MGT5200_CP_MIMR(%r6)         /* write new mask value */    /*     * Master interrupts start at offset 4 from the base of the critical interrupts, but     * the value in r14 represents the relative master interrupt, so we need to compensate     */    addi    %r14, %r14, 4	/* done */6:CALLOUT_END	interrupt_id_mgt5200/*************************************************************************** * Callout : 	interrupt_eoi_mgt5200 * * Description: Clear the interrupt, then unmask the level (it was masked in *				interrupt_id) * * On Entry:	r14 = interrupt level * * On Exit:		Nothing * * Notes: * **************************************************************************/CALLOUT_START	interrupt_eoi_mgt5200, 0, patcher/* * r14 = 0 - write a 1 to bit 20 of EE_ETR, to unmask * r14 = 1 - write a 1 to slice timer 0 status bit to clear, and enable timer interrupts * r14 = 2 or 3 - do nothing for now * r14 = 4 - 20 - unmask the appropriate main interrupt */	DEVBASE %r6, 0x12345678	cmplwi	%r18,0	bgt		3f	cmplwi	%r14,0	bgt		1f	/* UART 1_4 interrupt */  	lwz     %r5,MGT5200_EE_ETR(%r6)    ori     %r5, %r5, 0x800 /* unmask interrupt 0 (bit 20) */	stw		%r5,MGT5200_EE_ETR(%r6)    b       3f	/* done */1:	cmplwi	%r14, 1	bgt		2f	/* slice timer 0 interrupt */    lwz     %r5,MGT5200_SLC_0_STAT(%r6)/* clear int */	lis		%r0,0x0100	stw		%r0,MGT5200_SLC_0_STAT(%r6)/* unmask the interrupt */	lis		%r0,0x0700	stw		%r0,MGT5200_SLC_0_CTRL(%r6)	b		3f	/* done */2:	cmplwi	%r14,3	ble		3f		/* if it's 2 or 3, do nothing */	/* main interrupt */	cmplwi	%r14, 20	bgt		3f    lwz         %r5,MGT5200_CP_MIMR(%r6)    lis         %r4, 0x10 /* int 4 == main interrupt 0, this is so srw by r14 puts bit in proper position */    srw         %r4, %r4, %r14  /* r14 will be 4 or greater */    andc        %r5, %r5, %r4   /* clear bit to unmask */    stw         %r5, MGT5200_CP_MIMR(%r6)3:/* done */CALLOUT_END	interrupt_eoi_mgt5200/*************************************************************************** * Callout : 	interrupt_mask_mgt5200 * * Description: Mask the given interrupt level * * On Entry:	r4 = interrupt level * * On Exit:		Nothing * * Notes: * **************************************************************************/CALLOUT_START	interrupt_mask_mgt5200, 0, patcher/* * If the level passed here in r4 is 0, unmask external INT 0 by setting bit 20 * of the External Enable and External Types register. * If it's 1, enable slice timer 0 interrupts. * Otherwise, load the Critical Priority and Main Interrupt Mask register, * and clear the appropriate bit for the level to be unmasked. */ 	DEVBASE %r6, 0x12345678 		cmplwi	%r4, 0	bgt		1f	lwz %r5, MGT5200_EE_ETR(%r6)                 /* load contents of EE_ETR into r5 */	li      %r8,0x800				/* bit 20 is IRQ 0 enable bit */	andc    %r5,%r5,%r8             /* mask  (clear) bit by ANDing with one's compliment of r6 */	stw     %r5, MGT5200_EE_ETR(%r6)             /* store new value */	b		3f1:	cmplwi	%r4,1	bgt		2f    /* interrupt is 1, mask slice timer 0 interrupts */    lwz     %r5,MGT5200_SLC_0_CTRL(%r6)    lis     %r0,0x0200    andc    %r5, %r5, %r0    stw     %r5,MGT5200_SLC_0_CTRL(%r6)	b		3f2:	cmplwi	%r4, 3					/* check for level 2 or 3 */	ble		3f						/* can't mask */	/* set bit to mask in MIMR */	lwz %r5, MGT5200_CP_MIMR(%r6)                 /* load contents of CP_MIMR into r5 */									/* bits 15 - 31 represent interrupt levels 4 - 20, respectively */	lis		%r8, 0x10				/* bit 11 */	srw     %r8,%r8,%r4             /* shift mask bit to proper position in r6 */	or      %r5,%r5,%r8             	eieio	stw     %r5, MGT5200_CP_MIMR(%r6)             /* load new interrupt mask */3:	sync	blrCALLOUT_END	interrupt_mask_mgt5200	/*************************************************************************** * Callout : 	interrupt_unmask_mgt5200 * * Description: Unmask the given interrupt level * * On Entry:	r4 = interrupt level * * On Exit:		Nothing * * Notes: * **************************************************************************/CALLOUT_START	interrupt_unmask_mgt5200, 0, patcher/* * If the level passed here is 0, unmask external INT 0 by setting bit 20 * of the External Enable and External Types register. * If it's 1, enable slice timer 0 interrupts. * Otherwise, load the Critical Priority and Main Interrupt Mask register, * and clear the appropriate bit for the level to be unmasked. */ 	DEVBASE %r6, 0x12345678 		cmplwi	%r4, 0	bgt		1f	lwz %r5, MGT5200_EE_ETR(%r6)                 /* load contents of EE_ETR into r5 */	li      %r8,0x800				/* bit 20 is IRQ 0 enable bit */	or      %r5,%r5,%r8             /* unmask bit */	stw     %r5, MGT5200_EE_ETR(%r6)             /* store new value */	b		3f1:	cmplwi	%r4, 1	bgt		2f/* unmask slice timer 0 interrupt */    lis     %r0,0x0700    stw     %r0,MGT5200_SLC_0_CTRL(%r6)	b		3f2:	cmplwi	%r4, 3					/* check for level 2 or 3 */	ble		3f						/* can't unmask */	/* unmask a main interrupt - clear bit to unmask in MIMR */	lwz %r5, MGT5200_CP_MIMR(%r6)                 /* load contents of CP_MIMR into r5 */									/* bits 15 - 31 represent interrupt levels 4 - 20, respectively */	lis		%r8, 0x10				/* bit 11 */	srw     %r8,%r8,%r4             /* shift mask bit to proper position in r6 */	andc    %r5,%r5,%r8             /* and r5 with one's compliment of r6 to unmask interrupt */	eieio	stw     %r5, MGT5200_CP_MIMR(%r6)             /* load new interrupt mask */3:	sync	blrCALLOUT_END	interrupt_unmask_mgt5200/*************************************************************************** * * Peripheral Interrupt Callouts * ***************************************************************************//*************************************************************************** * Callout : 	interrupt_unmask_mgt5200_per_hi * * Description: Unmask the given peripheral interrupt level for interrupts  *              configured as HI

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -