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

📄 loapicintr.c

📁 VxWorks实时系统中的中断控制器驱动程序源代码。
💻 C
📖 第 1 页 / 共 2 页
字号:
#endif	/* defined (SYMMETRIC_IO_MODE) */	/* if the original mode is PIC mode, disable the Local APIC */	if ((loApicOldSvr & LOAPIC_ENABLE) == 0)	    {            *(int *)(loApicBase + LOAPIC_SVR) &= ~LOAPIC_ENABLE;	    }	else	    {	    /* restore the original value */    	    *(int *)(loApicBase + LOAPIC_SVR)   = loApicOldSvr;    	    *(int *)(loApicBase + LOAPIC_LINT0) = loApicOldLint0;    	    *(int *)(loApicBase + LOAPIC_LINT1) = loApicOldLint1;	    }	}    intUnlock (oldLevel);		/* UNLOCK INTERRUPTS */    }/********************************************************************************* loApicIntLock - lock out all Local APIC interrupts** This routine locks out all Local APIC interrupts* It should be called in the interrupt disable state(IF bit is 0).** RETURNS: N/A** SEE ALSO: loApicIntUnlock()** ARGSUSED0*/LOCAL void loApicIntLock (void)    {    if (!(*(int *)(loApicBase + LOAPIC_TIMER) & LOAPIC_MASK))	{        sysIntMaskLocalApic |= LOCKED_TIMER;        *(int *)(loApicBase + LOAPIC_TIMER) |= LOAPIC_MASK;	}    if (!(*(int *)(loApicBase + LOAPIC_LINT0) & LOAPIC_MASK))	{        sysIntMaskLocalApic |= LOCKED_LINT0;        *(int *)(loApicBase + LOAPIC_LINT0) |= LOAPIC_MASK;	}    if (!(*(int *)(loApicBase + LOAPIC_LINT1) & LOAPIC_MASK))	{        sysIntMaskLocalApic |= LOCKED_LINT1;        *(int *)(loApicBase + LOAPIC_LINT1) |= LOAPIC_MASK;	}    if (!(*(int *)(loApicBase + LOAPIC_ERROR) & LOAPIC_MASK))	{        sysIntMaskLocalApic |= LOCKED_ERROR;        *(int *)(loApicBase + LOAPIC_ERROR) |= LOAPIC_MASK;	}    if ((loApicMaxLvt >= LOAPIC_LVT_P6) &&        (!(*(int *)(loApicBase + LOAPIC_PMC) & LOAPIC_MASK)))	{        sysIntMaskLocalApic |= LOCKED_PMC;        *(int *)(loApicBase + LOAPIC_PMC)   |= LOAPIC_MASK;	}    if ((loApicMaxLvt >= LOAPIC_LVT_PENTIUM4) &&        (!(*(int *)(loApicBase + LOAPIC_THERMAL) & LOAPIC_MASK)))	{        sysIntMaskLocalApic |= LOCKED_THERMAL;        *(int *)(loApicBase + LOAPIC_THERMAL) |= LOAPIC_MASK;	}    }/********************************************************************************* loApicIntUnlock - unlock the Local APIC interrupts** This routine unlocks the Local APIC interrupts* It should be called in the interrupt disable state(IF bit is 0).** RETURNS: N/A** SEE ALSO: loApicIntLock()** ARGSUSED0*/LOCAL void loApicIntUnlock (void)    {    if (sysIntMaskLocalApic & LOCKED_TIMER)        *(int *)(loApicBase + LOAPIC_TIMER) &= ~LOAPIC_MASK;    if (sysIntMaskLocalApic & LOCKED_LINT0)        *(int *)(loApicBase + LOAPIC_LINT0) &= ~LOAPIC_MASK;    if (sysIntMaskLocalApic & LOCKED_LINT1)        *(int *)(loApicBase + LOAPIC_LINT1) &= ~LOAPIC_MASK;    if (sysIntMaskLocalApic & LOCKED_ERROR)        *(int *)(loApicBase + LOAPIC_ERROR) &= ~LOAPIC_MASK;    if ((loApicMaxLvt >= LOAPIC_LVT_P6) && 	(sysIntMaskLocalApic & LOCKED_PMC))        *(int *)(loApicBase + LOAPIC_PMC)   &= ~LOAPIC_MASK;    if ((loApicMaxLvt >= LOAPIC_LVT_PENTIUM4) && 	(sysIntMaskLocalApic & LOCKED_THERMAL))        *(int *)(loApicBase + LOAPIC_THERMAL) &= ~LOAPIC_MASK;    sysIntMaskLocalApic = 0;	/* reset the flags */    }/********************************************************************************* loApicIntEoi -  send EOI (End Of Interrupt) signal to Local APIC** This routine sends an EOI signal to the Local APIC's interrupting source.** RETURNS: N/A*/LOCAL void loApicIntEoi    (    INT32 irqNo		/* INIIN number to send EOI */    )    {#ifdef	SYS_INT_DEBUG    extern UINT32 sysIntCount [];    sysIntCount [irqNo]++;#endif	/* SYS_INT_DEBUG */    *(int *)(loApicBase + LOAPIC_EOI) = 0;    }/********************************************************************************* loApicMpConfigTableInit -  initialize pointers to MP configuration table** This routine scans the memory areas specified in MP ver1.4, to find the* MP signature and initializes pointers to MP configuration tables.  This* is not comprehensive and the only data used by VxWorks is the * APIC IDs and APIC base addresses.** RETURNS: OK, or ERROR if not MP compliant**/LOCAL STATUS loApicMpConfigTableInit (void)    {    MP_FPS * pFps = NULL;    MP_HEADER * mpHdr;    MP_CPU * mpCpu;    MP_IOAPIC * mpIOApic;    INT8 * p;    INT32 ix;    /* scan for the MP Floating Point Structure */    pFps = (MP_FPS *)loApicMpScan ((char *)EBDA_START, (char *)EBDA_END);    if (pFps == NULL)        pFps = (MP_FPS *)loApicMpScan ((char *)BIOS_ROM_START, 				       (char *)BIOS_ROM_END);    if (pFps == NULL)	return (ERROR);        /*      * If featurebyte1 (array element 0) is non-zero, then we use      * standard configuration return ERROR and let the error handle use     * standard addresses and Local and IO APIC ID's.     */    if ((pFps->featureByte[0] != 0) || (pFps->configTableAddr == 0))	return (ERROR);    /* check if the IMCR exists or not */    loApicImcr = (pFps->featureByte[1] & 0x80) ? TRUE : FALSE;    /* get MP header pointer */    mpHdr = (MP_HEADER *) pFps->configTableAddr;    /* get Local APIC Base Address  */    loApicBase = (UINT32)(mpHdr->localApicBaseAddr);    /* We only need CPU and IO APIC entries, ignore the rest */    p =  (char *)mpHdr + sizeof(MP_HEADER);    for(ix = 0; ix < mpHdr->entryCount; ix++)	{	switch(*p)	    {	    case MP_ENTRY_CPU:		/* Processor Configuration Entry */		mpCpu = (MP_CPU *)p;		loApicNcpu++;		/* increment the CPU counter */		p += sizeof (MP_CPU);		break;	    case MP_ENTRY_IOAPIC:	/* IO Apic Configuration Entry  */		mpIOApic = (MP_IOAPIC *)p;		loApicNioApic++;	/* increment the IO APIC counter */		p += sizeof (MP_IOAPIC);		break;	    default:			/* Others..ignore, for now  */		p += 8;			/* wild guess */	    }	}    return(OK);    }/********************************************************************************* loApicMpScan -  scans given memory range for the string "_MP_"** This routine scans the memory areas specified in its argument for the* Intel MP signature string "_MP_".  ** RETURNS: pointer to "_MP_"  in the range , or NULL**/LOCAL INT8 * loApicMpScan     (    INT8 * start,		/* start address to scan */    INT8 * end			/* end address to scan */    )    {    INT8 * p;    for (p = start; (p+3) < end; p++)	{	if (strncmp (p, "_MP_", 4) == 0)	    return (p);	}    return (NULL);    }/******************************************************************************** loApicIpi - generate a Inter Processor Interrupt** This routine delivers an Inter-Processor interrupt to the specified CPU* in the specified mode, with the specified vectorNo.  Level should always* be 1 except INIT De-assert mode.** RETURNS: OK, or ERROR if the delivery status is not idle*/STATUS loApicIpi    (    INT32 apicId,	/* APIC ID number to send the interrupt */    INT32 shortHand,	/* destination short hand */    INT32 trigger,	/* trigger mode. 0: edge or 1: level */    INT32 level,	/* level. 0: de-assert or 1: assert */    INT32 destMode,	/* destination mode. 0: physical or 1: logical */    INT32 deliMode,	/* delivery mode. 000: fixed ... 110: startup */    INT32 vectorNo	/* vector number */    )    {    UINT32 icrHi = (*(int *)(loApicBase + LOAPIC_ICRHI)) & 0xf0ffffff;    UINT32 icrLo = (*(int *)(loApicBase + LOAPIC_ICRLO)) & 0xfff33000;     /* ShortHand, Trigger, Level, DeliveryMode and Vector */    icrLo |= ((shortHand << 18) & 0xc0000) | 	     ((trigger << 15) & 0x8000) | 	     ((level << 14) & 0x4000) |	     ((destMode << 11) & 0x800) | 	     ((deliMode << 8) & 0x700) | 	     (vectorNo & 0xff);     /* Destination Apic Id */    icrHi |= (apicId << 24) & 0xff000000;     /* is the interrupt idle? */    if (*(int *)(loApicBase + LOAPIC_ICRLO) & STATUS_PEND)        {	loApicBusy++;	LOAPIC_DBG_MSG ("ipi: LOAPIC busy 0x%x\n", 			*(int *)(loApicBase + LOAPIC_ESR))        return (ERROR);	}    /* reset the error status register */    *(int *)(loApicBase + LOAPIC_ESR) = 0;    *(int *)(loApicBase + LOAPIC_ESR) = 0;        if (*(int *)(loApicBase + LOAPIC_ESR) != 0)	    {	    LOAPIC_DBG_MSG ("ipi: 0. ESR=0x%x\n", 			    *(int *)(loApicBase + LOAPIC_ESR))	    return (ERROR);	    }    /* Send it! */    *(int *)(loApicBase + LOAPIC_ICRHI) = icrHi;    *(int *)(loApicBase + LOAPIC_ICRLO) = icrLo;     /* Wait till interrupt is sent */    while (*(int *)(loApicBase + LOAPIC_ICRLO) & STATUS_PEND)        if (*(int *)(loApicBase + LOAPIC_ESR) != 0)	    {	    LOAPIC_DBG_MSG ("ipi: 1. ESR=0x%x\n", 			    *(int *)(loApicBase + LOAPIC_ESR))	    return (ERROR);	    }     return(OK);    }

⌨️ 快捷键说明

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