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

📄 ipiarchlib.c

📁 VXWORKS源代码
💻 C
字号:
/* ipiArchLib.c - I86 Inter Processor Interrupt (IPI) handling facilities *//* Copyright 1984-2002 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------01d,28feb02,hdn  initialized ipiHandlerTbl[] with NULL		 moved IPI_MAX_XXX macros to ipiI86Lib.h01c,27feb02,hdn  moved BSP part of shutdown code to sysShutdownSup()01b,26feb02,hdn  replaced loApicIpiIntNumGet() to ipiIntNum01a,20feb02,hdn  written*//*This module contains I80X86 architecture dependent portions of theInter Processor Interrupt (IPI) handling facilities.  See ipiALib for the companion assembly routines.SEE ALSO: ipiALib*/#include "vxWorks.h"#include "esf.h"#include "iv.h"#include "sysLib.h"#include "intLib.h"#include "taskLib.h"#include "qLib.h"#include "errno.h"#include "string.h"#include "vxLib.h"#include "logLib.h"#include "arch/i86/pentiumLib.h"#include "arch/i86/ipiI86Lib.h"#include "drv/intrCtl/loApic.h"/* defines */#undef	IPI_DBG#ifdef	IPI_DBG#   define IPI_DBG_MSG(STR,VALUE)	printf(STR,VALUE);#else#   define IPI_DBG_MSG(STR,VALUE)#endif	/* IPI_DEBUG *//* externals */IMPORT int	sysCsExc;		/* CS for IPI */IMPORT volatile UINT32 * sysNipi;	/* IPI counter */IMPORT void 	sysShutdownSup ();	/* BSP shutdown routine *//* globals */VOIDFUNCPTR	ipiHandlerTbl [IPI_MAX_HANDLERS] = {NULL}; /* IPI handlers *//* locals */LOCAL UINT32	ipiIntNum;		/* IPI base intNum *//* forward static functions *//********************************************************************************* ipiVecInit - initialize the IPI vectors** This routine sets all IPI vectors in IDT and assigns the default handlers.* IPI_MAX_HANDLERS vectors are initialized starting from the IPI base vector.** RETURNS: OK (always).*/void ipiVecInit     (    UINT32 intNum		/* IPI base intNum */    )    {    INT32 ix;    ipiIntNum = intNum;		/* remember it */    /* make all IPI vectors point to generic IPI handler */    for (ix = 0; ix < IPI_MAX_HANDLERS; ix++, intNum++)	{	intVecSet2 ((FUNCPTR *)INUM_TO_IVEC (intNum),		    (FUNCPTR) &ipiCallTbl[ix << 3],		    IDT_INT_GATE, sysCsExc);	}    }/********************************************************************************* ipiConnect - connect a C routine to the Inter Processor Interrupt** This routine connects a specified C routine to a specified Inter Processor * Interrupt vector.  The address of <routine> is stored in ipiHandlerTbl[] * that is called by ipiHandler(index) when the IPI occurs.  The connected * routine is invoked in supervisor mode in the interrupt level. ** The routine can be any normal C code, except that it must not invoke* certain operating system functions that may block or perform I/O* operations.** NOMANUAL*/STATUS ipiConnect    (    UINT32	intNum,		/* IPI interrupt number */    VOIDFUNCPTR	routine		/* routine to be called */    )    {    /* sanity check */      if ((intNum < ipiIntNum) ||         (intNum >= (ipiIntNum + IPI_MAX_HANDLERS)))        {	return (ERROR);	}    /* register the routine */    ipiHandlerTbl[intNum - ipiIntNum] = routine;    return (OK);    }/********************************************************************************* ipiHandler - interrupt level IPI handling routine** This routine handles Inter Processor Interrupt (IPI).  It is never to be * called except from the special assembly language interrupt stub routine.* Since it runs in the interrupt level, the task level work may be deferred * by excJobAdd()/logMsg(). ** RETURNS: N/A** NOMANUAL*/void ipiHandler    (    UINT32	index		/* index in the ipiHandlerTbl[] */    )    {    /* send EOI */    *(int *)(loApicBase + LOAPIC_EOI) = 0;    /* sanity check */      if (index >= IPI_MAX_HANDLERS)	return;    /* increment the counter */    sysNipi[index]++;    /* call the registered IPI handler */    if (ipiHandlerTbl[index] != NULL)        (*(ipiHandlerTbl[index])) ();    }/********************************************************************************* ipiHandlerShutdown - interrupt level Shutdown IPI handling routine** This routine handles Shutdown Inter Processor Interrupt (IPI).** Note that this routine runs in the context of the task that got the IPI.** RETURNS: N/A** NOMANUAL*/void ipiHandlerShutdown (void)    {    /*      * do it in the interrupt level or task level?     * doing it in the interrupt level      * - is more reliable (works even if the kernel is misbehaving)     * - doesn't require context switch (to excTask) working     * - happens immediatly (may be nested interrupt)     * doing it in the task level      * - is more graceful     * - require context switch (to excTask) working     * - servicing interrupts will be completed     * What about having two handlers, one for each?     */         sysShutdownSup ();			/* shutdown the included components */    loApicEnable (FALSE);		/* disable the LOAPIC */    intLock ();				/* LOCK INTERRUPTS */    ipiShutdownSup ();			/* never come back */    }/********************************************************************************* ipiStartup - start up the specified Application Processor (AP)** This routine starts up the specified Application Processor (AP).** RETURNS: N/A** NOMANUAL*/STATUS ipiStartup    (    UINT32	apicId,		/* AP's local APIC ID */    UINT32	vector,		/* entry point address */    UINT32	nTimes		/* send SIPI nTimes */    )    {    INT32 ix;    /* BSP sends AP an INIT IPI */    if (loApicIpi (apicId, 0, 0, 1, 0, 5, 0) != OK)	{	IPI_DBG_MSG ("failed - 1st INIT %d\n",0)	return (ERROR);	}    if (loApicIpi (apicId, 0, 1, 0, 0, 5, 0) != OK)	{	IPI_DBG_MSG ("failed - 2nd INIT %d\n",0)	return (ERROR);	}    /* BSP delay 10msec */    for (ix = 0; ix < 15000; ix++)	/* 15000*720 ~= 10.8 msec */         sysDelay ();			/* 720ns */    while (nTimes-- > 0)	{        /* BSP sends AP a STARTUP IPI again */        if (loApicIpi (apicId, 0, 0, 1, 0, 6, (vector >> 12)) != OK)	    {	    IPI_DBG_MSG ("failed - SIPI %d\n", nTimes)	    return (ERROR);	    }        /* BSP delays 200usec again */            for (ix = 0; ix < 300; ix++)	/* 300*720 ~= 216usec */             sysDelay ();		/* 720ns */	}    return (OK);    }/********************************************************************************* ipiShutdown - shutdown the specified Application Processor (AP)** This routine shutdowns the specified Application Processor (AP).** NOMANUAL*/STATUS ipiShutdown    (    UINT32	apicId,		/* AP's local APIC ID */    UINT32	intNum		/* intNum of IPI_SHUTDOWN */    )    {    STATUS status = OK;    INT32 retry = 0;    /* BP sends AP a SHUTDOWN IPI */    while (loApicIpi (apicId, 0, 0, 1, 0, 0, intNum) != OK)	{        taskDelay (1);	if (retry++ > IPI_MAX_RETRIES)	    {            status = ERROR;	    break;	    }	}    return (status);    }#if	FALSE	/* XXX will be done soon *//********************************************************************************* ipiFixedDest - send IPI to the specified Application Processor** This routine sends IPI to the specified Application Processor** NOMANUAL*/STATUS ipiFixedDest    (    UINT32	apicId,		/* AP's local APIC ID */    UINT32	intNum		/* intNum to send */    )    {    }/********************************************************************************* ipiFixedSelf - send IPI to myself** This routine sends IPI to myself** NOMANUAL*/STATUS ipiFixedSelf    (    UINT32	intNum		/* intNum to send */    )    {    }/********************************************************************************* ipiFixedAlli - send IPI to all processors including self** This routine sends IPI to all processors including self** NOMANUAL*/STATUS ipiFixedAlli    (    UINT32	intNum		/* intNum to send */    )    {    }/********************************************************************************* ipiFixedAlle - send IPI to all processors excluding self** This routine sends IPI to all processors excluding self** NOMANUAL*/STATUS ipiFixedAlle    (    UINT32	intNum		/* intNum to send */    )    {    }/********************************************************************************* ipiNmiDest - send NMI to the specified Application Processor** This routine sends NMI to the specified Application Processor** NOMANUAL*/STATUS ipiNmiDest    (    UINT32	apicId		/* AP's local APIC ID */    )    {    }/********************************************************************************* ipiNmiSelf - send NMI to myself** This routine sends NMI to myself** NOMANUAL*/STATUS ipiNmiSelf (void)    {    }/********************************************************************************* ipiNmiAlli - send NMI to all processors including self** This routine sends NMI to all processors including self** NOMANUAL*/STATUS ipiNmiAlli (void)    {    }/********************************************************************************* ipiNmiAlle - send NMI to all processors excluding self** This routine sends NMI to all processors excluding self** NOMANUAL*/STATUS ipiNmiAlle (void)    {    }/********************************************************************************* ipiLowestAlli - send IPI to the lowest priority processor including self** This routine sends IPI to the lowest priority processor including self** NOMANUAL*/STATUS ipiLowestAlli    (    UINT32	intNum		/* intNum to send */    )    {    }/********************************************************************************* ipiLowestAlle - send IPI to the lowest priority processor excluding self** This routine sends IPI to the lowest priority processor excluding self** NOMANUAL*/STATUS ipiLowestAlle    (    UINT32	intNum		/* intNum to send */    )    {    }#endif

⌨️ 快捷键说明

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