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

📄 xvectors.s

📁 基于Xilinx-XUPV2P开发平台的嵌入式系统实验例程:实验4编写基本的应用程序
💻 S
字号:
#ifdef __GNUC__/* $Id: xvectors.S,v 1.3 2004/12/01 21:33:57 vasanth Exp $ *//******************************************************************************* Copyright (c) 2004 Xilinx, Inc.  All rights reserved. * * Xilinx, Inc. * XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A * COURTESY TO YOU.  BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS * ONE POSSIBLE   IMPLEMENTATION OF THIS FEATURE, APPLICATION OR * STANDARD, XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION * IS FREE FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE * FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION. * XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO * THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO * ANY WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE * FROM CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS FOR A PARTICULAR PURPOSE.******************************************************************************//****************************************************************************//**** @file xvectors.S** This file contains low-level functions for the PowerPC exception handler.** <pre>* MODIFICATION HISTORY:** Ver   Who  Date     Changes* ----- ---- -------- -----------------------------------------------* 1.00a ch   06/18/02 First release* </pre>******************************************************************************//*-----------------------------------------------------------------------------//// Documentation:////    This is the structure of the PPC 405 interrupt stack frame that is//    pushed onto the stack during an exception.////    This interrupt frame only saves the User Model register sets that//    could be used/genterated by compiler generated code. Any usage of//    registers in an ISR beyond this set must be save/restored by the//    ISR routine.////    In general, this interrupt frame conforms to a standard PPC EABI//    Stack Call Frame. The entire frame is 160 bytes (40 words) in size,//    which is an exact multible of 8 bytes as required the PPC EABI.//    And by using the standard EABI frame header, debuggers should still//    be able to display the Stack Call Chain even for break points in an//    exception handler function.////    However, there are a few exceptions to EABI conventions :////        1. The frame saves ALL registers instead of just registers that//           will be modified. Exceptions can occur at any point instead//           of just at function call branch points. Hence, saving the entire//           context means an exception will never disturb the interrupted//           code's register usage.////        2. The current LR register contents is NOT save in the previous//           Stack Frame as in standard EABI conventions. Rather, it is//           saved in the local frame. This done to avoid corrupting the//           previous Stack Frame's LR field, when the exception occurs//           during an interrupted function's entry prologue process.////        3. Unlike standard EABI frames, the interrupted PC location, and//           MSR state is also saved to the frame. This may seem unnecessary//           since registers SRR0 - SRR3 in the 405 are used exclusively to//           save the PC and MSR during exceptions. However, always saving//           the PC and MSR prepares this code for use in a multi-threaded//           environment.////        4. The USPRG0 register is also saved even though compilers will//           never generate code to use it. Once again, this prepares the//           way for use in a multi-threaded environment. This register//           would be used to contain a pointer to the TCB (Task Control//           Block) for the current task that is being interrupted.//           Subsequent system code could then switch the memory map/context//           from the TCB; such as the PID register.////    +------------+//    |     r31    | +156//    |      .     |//    |      .     |//    |      .     |//    |     r3     | +44//    +------------+//    |     r2     | +40//    +------------+//    |     r0     | +36//    +------------+//    |   USPRG0   | +32//    +------------+//    |     CR     | +28//    +------------+//    |     XER    | +24//    +------------+//    |     CTR    | +20//    +------------+//    |     LR     | +16//    +------------+//    |     PC     | +12//    +------------+//    |     MSR    | +8//    +------------+//    |   Next LR  | +4//    +------------+//    | Back Chain | +0//    +------------+////---------------------------------------------------------------------------*/	#endif		#include "xreg405.h"	.file "xvectors.S"	.section ".vectors","ax"	#ifdef __DCC__#define // ;#define MACRO0(name)name:	.macro#define MACRO1(name, param1)name:	.macro	param1#define MACRO2(name, param1, param2)name:	.macro	param1, param2#define CONCAT(left, right) left##&&##right	#define CONCAT3(left, parammiddle, right) left##&&##parammiddle##right	#define PARAM(param) param	#else	#include <ppc-asm.h>#define r1 1#define r2 2#define MACRO0(name) .macro	name#define MACRO1(name, param1) .macro	name	param1#define MACRO2(name, param1, param2) .macro	name	param1 param2#define CONCAT(left,right) left##right		#define PARAM(param) param		#endif			//---------------------------------------------------------------------	//	// Define interrupt frame structure offsets.	//	//---------------------------------------------------------------------	.set	BChainField, 0	.set	NextLRField, BChainField + 4	.set	MSRField,    NextLRField + 4	.set	PCField,     MSRField    + 4	.set	LRField,     PCField     + 4	.set	CTRField,    LRField     + 4	.set	XERField,    CTRField    + 4	.set	CRField,     XERField    + 4	.set	USPRG0Field, CRField     + 4	.set	r0Field,     USPRG0Field + 4	.set	r2Field,     r0Field     + 4	.set	r3r31Field,  r2Field     + 4	.set	IFrameSize,  r3r31Field  + ( ( 31 - 3 ) + 1 ) * 4			//---------------------------------------------------------------------	//	// Macro for the interrupt frame prologue.	//	//---------------------------------------------------------------------			MACRO1(int_prologue, base)		.org	_vectorbase + CONCAT(0x,\base)	.globl	CONCAT(_vector,\base)#ifdef __DCC__CONCAT3(_vector, base, :)#else_vector\base:                   #endif        	stwu	XREG_GPR1,-IFrameSize(XREG_GPR1)	// Save Back chain and move SP		// Save r0 and r2.	stw	XREG_GPR0, r0Field(XREG_GPR1)	stw	XREG_GPR2, r2Field(XREG_GPR1)	stmw	XREG_GPR3, r3r31Field(XREG_GPR1)	// Save the remaining GPR registers r3-r31		// Save current Link register	mflr	XREG_GPR0	stw	XREG_GPR0, LRField(XREG_GPR1)		// Save Counter register	mfctr	XREG_GPR0	stw	XREG_GPR0,CTRField(XREG_GPR1)		// Save Fixed Point Exception register	mfxer	XREG_GPR0	stw	XREG_GPR0,XERField(XREG_GPR1)		// Save Condition register	mfcr	XREG_GPR0	stw	XREG_GPR0,CRField(XREG_GPR1)		// Save USPRG0 register	mfspr	XREG_GPR0,0x100	stw	XREG_GPR0,USPRG0Field(XREG_GPR1)		.endm			//---------------------------------------------------------------------	//	// Macro for the interrupt frame epilogue.	//	//---------------------------------------------------------------------		MACRO0(int_epilogue)		// Save USPRG0 register	lwz	XREG_GPR0,USPRG0Field(XREG_GPR1)	mtspr	0x100,XREG_GPR0		// Restore Condition register	lwz	XREG_GPR0,CRField(XREG_GPR1)	mtcr	XREG_GPR0		// Restore Fixed Point Exception register	lwz	XREG_GPR0,XERField(XREG_GPR1)	mtxer	XREG_GPR0		// Restore Counter register	lwz	XREG_GPR0,CTRField(XREG_GPR1)	mtctr	XREG_GPR0		// Restore Link register	lwz	XREG_GPR0,LRField(XREG_GPR1)	mtlr	XREG_GPR0		// Restore remaining GPR registers.	lmw	XREG_GPR3,r3r31Field(XREG_GPR1)		// Restore r0 and r2.	lwz	XREG_GPR0,r0Field(XREG_GPR1)	lwz	XREG_GPR2,r2Field(XREG_GPR1)		// Remove frame from stack	addi	XREG_GPR1,XREG_GPR1,IFrameSize		.endm			//---------------------------------------------------------------------	//	// Macro for vector handler calling.	//	//---------------------------------------------------------------------		MACRO1(call_vector_hander, int_num)			// Pass the exception ordinal for this exception.	li	XREG_GPR3, PARAM(\int_num)	  	  	// Get address of the vector table in r9.	lis	XREG_GPR9,XExc_VectorTable@ha	la	XREG_GPR9,XExc_VectorTable@l(XREG_GPR9)		// Multiply vectorNumber (from r3) by 16 into r0.	mr	XREG_GPR11,XREG_GPR3	slwi	XREG_GPR0,XREG_GPR11,4	//mulli	r0,r11,12  	  	// Get the Nth vector element at r9 + r0 into r9.	add	XREG_GPR9,XREG_GPR9,XREG_GPR0  	  	// Get the vector address into r11.	lwz	XREG_GPR11,0(XREG_GPR9)  	  	// Get the user data value into r4.	lwz	XREG_GPR3,4(XREG_GPR9)  	  	// Get the read only small data area pointer into r2.	lwz	XREG_GPR2,8(XREG_GPR9)  	  	// Get the read/write small data area pointer into r13.	lwz	XREG_GPR13,12(XREG_GPR9)	// NOT! Pass exception ordinal parameter in r3.	// Pass user data value parameter in r4.  	  	// Move the vector address to the LR and call it.	mtlr	XREG_GPR11	blrl		.endm			//---------------------------------------------------------------------	//	// Macro for critical interrupts vector code.	//	//---------------------------------------------------------------------		MACRO2(critical_interrupt, base, int_num)		int_prologue PARAM(\base)			// Save MSR register from SRR3.	mfsrr3	XREG_GPR0	stw	XREG_GPR0,MSRField(XREG_GPR1)		// Save current PC location from SRR2.	mfsrr2	XREG_GPR0	stw	XREG_GPR0,PCField(XREG_GPR1)		// Call the vector handler for this exception.	call_vector_hander PARAM(\int_num)				// Restore MSR register to SRR3.	lwz	XREG_GPR0,MSRField(XREG_GPR1)	mtsrr3	XREG_GPR0		// Restore current PC location to SRR2.	lwz	XREG_GPR0,PCField(XREG_GPR1)	mtsrr2	XREG_GPR0		int_epilogue		// Return to the interrupted code	rfci		.endm			//---------------------------------------------------------------------	//	// Macro for non-critical interrupts vector code.	//	//---------------------------------------------------------------------		MACRO2(non_critical_interrupt, base, int_num)		int_prologue PARAM(\base)		// Save MSR register from SRR1.	mfsrr1	XREG_GPR0	stw	XREG_GPR0,MSRField(XREG_GPR1)		// Save current PC location from SRR0.	mfsrr0	XREG_GPR0	stw	XREG_GPR0,PCField(XREG_GPR1)		// Call the vector handler for this exception.	call_vector_hander PARAM(\int_num)		// Restore MSR register to SRR1.	lwz	XREG_GPR0,MSRField(XREG_GPR1)	mtsrr1	XREG_GPR0		// Restore current PC location to SRR0.	lwz	XREG_GPR0,PCField(XREG_GPR1)	mtsrr0	XREG_GPR0		int_epilogue		// Return to the interrupted code	rfi		.endm			//---------------------------------------------------------------------	//	// Vector table.	//	// Define the vector table for all exceptions. The code for each	// exception is assembled inline at each vector entry point. Most	// PPC exceptions are 0x100 bytes apart, so there is 256 bytes of	// code space to handle an exception. The current exception code	// spans about 160 bytes, this code size fits.	//	// NOTE:	//	// Vectors 0x1010 (fixed interval timer) and 0x1020 (watchdog timer)	// are only 16 bytes apart and don't have enough room for the exception	// handling code to fit between them. Fortunately, there is a hole in	// the exception location sequence. Vectors 0x1100 through 0x1F00 are	// not used in the 405. So as a work-around, relocate the exception	// code for vectors 0x1010 and 0x1020 (where there isn't space) to	// the unused locations 0x1300 and 0x1400 (where the is room).	// Locations 0x1010 and 0x1020 merely contain a branch to the proper	// reloacated exception code; which fits within the 16 bytes of space	// of these "special" vector locations.	//	// If in the future this code is used for a different PPC processor,	// this vector table may need to be changed.	//	//---------------------------------------------------------------------		.globl	_vectorbase	_vectorbase:		// Vector 0x0000, Jump to zero.	critical_interrupt 0000, 0		// Vector 0x0100, Critical interrupt.	critical_interrupt 0100, 1		// Vector 0x0200, Machine Check interrupt.	critical_interrupt 0200, 2		// Vector 0x0300, Data Storage interrupt.	non_critical_interrupt 0300, 3		// Vector 0x0400, Instruction Storage interrupt.	non_critical_interrupt 0400, 4		// Vector 0x0500, External interrupt.	non_critical_interrupt 0500, 5		// Vector 0x0600, Alignment interrupt.	non_critical_interrupt 0600, 6		// Vector 0x0700, Program interrupt.	non_critical_interrupt 0700, 7		// Vector 0x0800, FPU Unavailable interrupt.	non_critical_interrupt 0800, 8		// Vector 0x0C00, System Call interrupt.	non_critical_interrupt 0C00, 9		// Vector 0x0F20, APU Available interrupt.	non_critical_interrupt 0F20, 10		// Vector 0x1000, PIT interrupt.	// This vector need the workaround described above	.org _vectorbase + 0x1000	b _vector1300			// Vector 0x1010, FIT interrupt.	// This vector need the workaround described above	.org _vectorbase + 0x1010	b _vector1400		// Vector 0x1020, Watchdog Timer interrupt.	.org _vectorbase + 0x1020	critical_interrupt 1020, 13		// Vector 0x1100, Data TLB Miss interrupt.	non_critical_interrupt 1100, 14		// Vector 0x1200, Instruction TLB Miss interrupt.	non_critical_interrupt 1200, 15	// Work-around!!! Real vector 0x1000, PIT	// interrupt exception code. This gets around	// the vector space/span problem. See title	// block above.	non_critical_interrupt 1300, 11	// Work-around!!! Real vector 0x1010, FIT	// interrupt exception code. This gets	// around the vector space/span problem. See	// title block above.	non_critical_interrupt 1400, 12		// Vector 0x2000, Debug interrupt.	critical_interrupt 2000, 16

⌨️ 快捷键说明

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