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

📄 int3_medpri_dispatcher.s

📁 uCOS-II ports on Tensilica HiFi330 core.
💻 S
字号:
// Medium-Priority Interrupt Dispatcher Template// $Id: //depot/rel/BearValley/Xtensa/OS/xtos/int-medpri-dispatcher.S#1 $// Customer ID=4654; Build=0x116b0; Copyright (c) 2004 by Tensilica Inc.  ALL RIGHTS RESERVED.// These coded instructions, statements, and computer programs are the// copyrighted works and confidential proprietary information of Tensilica Inc.// They may not be modified, copied, reproduced, distributed, or disclosed to// third parties in any manner, medium, or form, in whole or in part, without// the prior written consent of Tensilica Inc.//// By default, this file is included by inth-template.S .// The default Makefile defines _INTERRUPT_LEVEL when assembling// inth-template.S for each medium and high priority interrupt level.//// To use this template file, define a macro called _INTERRUPT_LEVEL// to be the interrupt priority level of the vector, then include this file.#include <xtensa/coreasm.h>#include "internal.h"#define _INTERRUPT_LEVEL 3#define INTERRUPT_MASK		XCHAL_INTLEVEL_MASK(_INTERRUPT_LEVEL)#define SINGLE_INT_NUM		XCHAL_INTLEVEL_NUM(_INTERRUPT_LEVEL)#define STRUCT_BEGIN		.pushsection .text; .struct 0#define STRUCT_FIELD(ctype,size,pre,name)	pre##name:	.space	size#define STRUCT_AFIELD(ctype,size,pre,name,n)	pre##name:	.space	(size)*(n)#define STRUCT_END(sname)	sname##Size:; .popsectionSTRUCT_BEGINSTRUCT_FIELD (long,4,UEXC_,pc)STRUCT_FIELD (long,4,UEXC_,ps)STRUCT_FIELD (long,4,UEXC_,sar)STRUCT_FIELD (long,4,UEXC_,vpri)/*STRUCT_AFIELD(long,4,UEXC_,areg, 4)*/	/* a2,a3,a4,a5  OR  a2,a3,a8,a9 */STRUCT_FIELD (long,4,UEXC_,a2)STRUCT_FIELD (long,4,UEXC_,a3)STRUCT_FIELD (long,4,UEXC_,a4_a8)	/* a8 if call8-only configured */STRUCT_FIELD (long,4,UEXC_,a5_a9)	/* a9 if call8-only configured */STRUCT_FIELD (long,4,UEXC_,exccause)	/* NOTE: can probably rid of this one (pass direct) *//*STRUCT_FIELD (long,4,UEXC_,excvaddr)*/#if XCHAL_HAVE_LOOPSSTRUCT_FIELD (long,4,UEXC_,lcount)STRUCT_FIELD (long,4,UEXC_,lbeg)STRUCT_FIELD (long,4,UEXC_,lend)#endif#if XCHAL_HAVE_MAC16STRUCT_FIELD (long,4,UEXC_,acclo)STRUCT_FIELD (long,4,UEXC_,acchi)STRUCT_AFIELD(long,4,UEXC_,mr, 4)#endif#define ALIGNPAD	((3 + XCHAL_HAVE_LOOPS + XCHAL_HAVE_MAC16*2) & 3)	/* 16-byte alignment padding */#if ALIGNPADSTRUCT_AFIELD(long,4,UEXC_,pad, ALIGNPAD)	/* 16-byte alignment padding */#endif/*STRUCT_AFIELD(char,1,UEXC_,ureg, (XCHAL_CPEXTRA_SA_SIZE_TOR2+3)&-4)*/	/* not used, and doesn't take alignment into account */STRUCT_END(UserFrame)//  Strict non-preemptive prioritization#if XCHAL_HAVE_CALL4AND12# define  A4		a4# define  A5		a5#else# define  A4		a8# define  A5		a9#endif/*  Check for UserFrameSize small enough not to require rounding...:  */	/*  Skip 16-byte save area, then 16-byte GCC nested func chaining area,	 *  then exception stack frame, then space for 8 regs for call12 below:  */	.set	UserFrameTotalSize, 16+16+UserFrameSize+32	/*  Greater than 112 bytes? (max range of ADDI, both signs, when aligned to 16 bytes):  */	.ifgt	UserFrameTotalSize-112	/*  Round up to 256-byte multiple to accelerate immediate adds:  */	.set	UserFrameTotalSize, ((UserFrameTotalSize+255) & 0xFFFFFF00)	.endif# define ESF_TOTALSIZE	UserFrameTotalSize//  Strict non-preemptive prioritization	.text	.align	4	.global	_Level3InterruptHandler_Level3InterruptHandler:/* Allocate an exception stack frame, save a2, a4, and a5, and fix PS as: * *	- enable windowing for 'entry' (ps.woe=1, ps.excm=0) *	- setup ps.callinc to simulate call4 *	- preserve user mode *	- mask all interrupts at EXCM_LEVEL and lower * * Then deallocate the stack, 'rsync' for the write to PS, then use * 'entry' to re-allocate the stack frame and rotate the register * window (like a call4, preserving a0..a3). */	rsr	    a2, EXCSAVE_3	addi	a1, a1, -ESF_TOTALSIZE	s32i	a2, a1, UEXC_a2	movi	a2, PS_WOE|PS_CALLINC(1)|PS_UM|PS_INTLEVEL(XCHAL_EXCM_LEVEL)	s32i	a4, a1, UEXC_a4_a8	s32i	a5, a1, UEXC_a5_a9	wsr	a2, PS	addi	a1, a1, ESF_TOTALSIZE	rsync	movi	a4, 0			/* terminate stack frames, overflow check */	_entry	a1, ESF_TOTALSIZE/* Reset the interrupt level to mask all interrupts at the current * priority level and lower.  Note the current priority level may be * less than or equal to EXCM_LEVEL. */	rsil	a15, _INTERRUPT_LEVEL/* Get bit list of pending interrupts at the current interrupt priority level. * If bit list is empty, interrupt is spurious (can happen if a * genuine interrupt brings control this direction, but the interrupt * goes away before we read the INTERRUPT register).  Also save off * sar, loops, and mac16 registers. */	rsr	a15, INTERRUPT	rsr	a12, INTENABLE	movi	a13, INTERRUPT_MASK	and	a15, a15, a12	and	a15, a15, a13	rsr	a14, SAR	_beqz	a15, spurious_int	s32i	a14, a1, UEXC_sar	save_loops_mac16	a1, a13, a14/* Loop to handle all pending interrupts. */L1_loop0:	neg	a12, a15	and	a12, a12, a15	wsr	a12, INTCLEAR	// clear if edge-trig or s/w or wr/err (else no effect)	movi	a13, intHandlers	find_ms_setbit	a15, a12, a14, 0	addx4	a12, a15, a13	l32i	a13, a12, 0	mov	a15, a1	callx12	a13	rsr	a15, INTERRUPT	rsr	a12, INTENABLE	movi	a13, INTERRUPT_MASK	and	a15, a15, a12	and	a15, a15, a13	_bnez	a15, L1_loop0/* Restore everything, and return.  Raise the interrupt mask before * returning to avoid a race condition where we deallocate the * exception stack frame but still have more register values to * restore from it. */	restore_loops_mac16	a1, a13, a14, a15	l32i	a14, a1, UEXC_sarspurious_int:	movi	a0, return_from_exc	movi	a13, 0xC0000000	wsr	a14, SAR	or	a0, a0, a13	addx2	a0, a13, a0#if _INTERRUPT_LEVEL < XCHAL_EXCM_LEVEL	rsil	a14, XCHAL_EXCM_LEVEL#endif	retwreturn_from_exc:	l32i	a2, a5, UEXC_a2	l32i	a4, a5, UEXC_a4_a8	l32i	a5, a5, UEXC_a5_a9	rfi	_INTERRUPT_LEVEL

⌨️ 快捷键说明

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