📄 excarchlib.c
字号:
/* excArchLib.c - SH exception handling facilities *//* Copyright 1994-2001 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------02n,24oct01,hk added excPciMapInit() to extend virtual PCI space on SH7751.02m,10sep01,zl FP exception info for _WRS_HW_FP_SUPPORT only.02l,03sep00,hk change excVecInit() to load VBR-relative stubs to physical memory by way of their virtual address. delete #include for unreferenced headers. simplify excBErrVecInit().02k,21aug00,hk merge SH7729 to SH7700. merge SH7410 and SH7040 to SH7600.02j,12jul00,hk added denormalized FP exception handler for SH7750.02i,20apr00,hk changed sysBErrVecNum to excBErrVecNum. changed excTasRetry() to call _func_excBErrIntAck instead of sysBErrIntAck(). moved bus interrupt vector setup to excBErrVecInit(). changed excVecInit() to copy vxMemProbeIntStub. added FUNCPTR casting to intVecSet() argument to suppress compilation warning.02h,10apr00,hk added VBR relative loading of intPrioTable, excBErrStub, vxMemProbeTrap. adjusted intVecSet() for sysBErrVecNum.02g,15sep98,hk unified SH7750_ macros to SH7700_ macros. simplified SH7750 conditional code in excGetInfoFromFSF().02f,16jul98,st added SH7750 support.02f,07may98,jmc added support for SH-DSP and SH3-DSP.02f,12may98,hk supported FPSCR on ESFSH. moved fppSave to excGetInfoFromESF.02d,26nov97,hms add fppLib support operation.02e,04jan98,hk fixed range check for sysBErrVecNum.02d,25nov97,hk changed to use sequential interrupt vector number for SH7700.02c,01may97,hk made windview instrumentation conditionally compiled.02b,28apr97,hk changed SH704X to SH7040.02b,07mar97,st added for windview02a,17feb97,hk deleted mmuEnabled reference from excGetInfoFromESF().01z,17feb97,hk improved excGetInfoFromESF() for SH7700 to distinguish trap events from other exceptions. restored previous vector range for valid access address.01y,16feb97,hk deleted intVecSet() for INUM_SPURIOUS_INTERRUPT. merged zero divide trap init to loop. added null check for sysBErrVecNum. changed vector range for valid aa in excGetInfoFromESF().01x,09feb97,hk changed excGetInfoFromESF() to get info from ESFSH for SH7700. changed zero divide trap num to 1 in excVecInit() for SH7700.01w,28jan97,hk added casting to suppress compiler warnings (not complete).01v,28jan97,hk added notes on excVecInit().01u,18jan97,hk validate EXC_ACCESS_ADDR if mmu is on.01t,15nov96,wt changed excStub to mmuStub as TLB miss handler.01s,17sep96,hk restored intVecSet() for excExcHandle, added excBErrStub setup.01r,02sep96,hk deleted intVecSet() for excExcHandle, now it's called directly.01q,22aug96,hk changed to use '#if 0' for disabling excRegsShow().01p,19aug96,hk added INUM_SPURIOUS_INTERRUPT, changed zero div. to 254.01o,19aug96,hk changed excGetInfoFromESF for SH7700 to get sr/pc from pRegs.01n,13aug96,hk changed to call excIntStub for uninitialized interrupts.01m,09aug96,hk made excVecInit() for SH7700 to looping style.01l,09aug96,hk added 'trapa #0' vector set for SH7700 to excVecInit.01k,08aug96,hk changed SH7700_OFF_xxx according to new ivSh.h(01t).01j,04aug96,hk changed code layout.01i,29jul96,ja added exception vector table initialization for SH7700.01h,29jul96,hk deleted intStub copy in excVecInit(), made excLib removable.01g,11jul96,ja added support for SH7700 in excVecInit.01f,13jun96,hk added support for SH7700.01e,21may96,hk workarounded excVecInit() for SH7700 build.01d,01apr95,hk added INTERNAL comment for excVecInit.01c,27mar95,hk added bus error support, copyright 1995.01b,30oct94,hk restored 68k code, adjusted for SH. faked excTasRetry().01a,18jul94,hk derived from 03f of 68k. Just a stub.*//*This module contains SH architecture dependent portions of theexception handling facilities. See excLib for the portions that arearchitecture independent.SEE ALSO: dbgLib, sigLib, intLib, "Debugging"*/#include "vxWorks.h"#include "cacheLib.h" /* for CACHE_TEXT_UPDATE() */#include "esf.h"#include "iv.h"#include "sysLib.h" /* for BOOT_WARM_AUTOBOOT */#include "intLib.h" /* for intVecSet() */#include "qLib.h" /* for Q_FIRST() */#include "string.h" /* for bcopy() */#include "rebootLib.h" /* for reboot() */#include "excLib.h"#include "private/eventP.h" /* for EVT_CTX_1() */#include "private/funcBindP.h"#include "private/kernelLibP.h" /* for activeQHead */#include "private/taskLibP.h" /* for pTaskLastFpTcb, and taskLib.h */#include "fppLib.h" /* for fppSave(), fppExcHandle() */#include "taskLib.h" /* for taskIdCurrent, taskIdDefault() *//* imports */#if (CPU==SH7750 || CPU==SH7700)IMPORT void excIntStub (int vecNum); /* excALib */IMPORT void excBErrStub (int vecNum); /* excALib */IMPORT UINT32 excBErrStubSize; /* excALib */IMPORT void vxMemProbeIntStub (void); /* vxALib */IMPORT UINT32 vxMemProbeIntStubSize; /* vxALib */#endif/* globals */void (* _func_excBErrIntAck)(void) = NULL;int excBErrVecNum = NONE; /* for excALib, excArchShow, and sigLib */#if (CPU==SH7750)UINT32 excMmuCrVal = 0; /* for mmuSh7750Lib.c */#endif /* CPU==SH7750 *//* local variables */LOCAL int excTasErrors; /* count of TAS bus errors - just curiosity *//* forward global function prototypes (accessed from external assembly code)*/void excExcHandle (int vecNum, ESFSH * pEsf, REG_SET * pRegs);/* forward static function prototypes */LOCAL BOOL excTasRetry (int vecNum, ESFSH *pEsf, REG_SET *pRegs);LOCAL void excGetInfoFromESF (int vecNum, ESFSH *pEsf, REG_SET *pRegs, EXC_INFO *pExcInfo);/******************************************************************************** excVecInit - initialize the exception/interrupt vectors** This routine sets all exception vectors to point to the appropriate* default exception handlers. These handlers will safely trap and report* exceptions caused by program errors or unexpected hardware interrupts.* All vectors from vector 2 (address 0x0008) to 255 (address 0x03fc) are* initialized. Vectors 0 and 1 contain the reset stack pointer and program* counter.** WHEN TO CALL* This routine is usually called from the system start-up routine* usrInit() in usrConfig, before interrupts are enabled.** RETURNS: OK, or ERROR.*/STATUS excVecInit (void) { STATUS status = OK; /* OK is 0, so we can record ERROR(-1) by OR */ int vecNum;#if (CPU==SH7750 || CPU==SH7700) UINT virtAddr = (UINT)excVecInit; /* where am I? */ UINT virtBase; UINT vecAddr; virtBase = ((UINT)intVecBaseGet() & 0x1fffffff) | (virtAddr & 0xe0000000); /* load bus error stub */ vecAddr = virtBase + SH7700_EXC_BERR_STUB_OFFSET; bcopy ((char *)excBErrStub, (char *)vecAddr, excBErrStubSize); status |= CACHE_TEXT_UPDATE ((void *)vecAddr, excBErrStubSize); /* load vxMemProbeIntStub */ vecAddr = virtBase + SH7700_MEMPROBE_INT_STUB_OFFSET; bcopy ((char *)vxMemProbeIntStub, (char *)vecAddr, vxMemProbeIntStubSize); status |= CACHE_TEXT_UPDATE ((void *)vecAddr, vxMemProbeIntStubSize); /* load exception handling stub */ vecAddr = virtBase + SH7700_EXC_STUB_OFFSET; bcopy ((char *)excStub, (char *)vecAddr, excStubSize); status |= CACHE_TEXT_UPDATE ((void *)vecAddr, excStubSize); /* load TLB mishit handling stub */ vecAddr = virtBase + SH7700_TLB_STUB_OFFSET; bcopy ((char *)mmuStub, (char *)vecAddr, mmuStubSize); status |= CACHE_TEXT_UPDATE ((void *)vecAddr, mmuStubSize); /* initialize virtual exception vector table */ for (vecNum = INUM_EXC_LOW; vecNum <= INUM_EXC_HIGH; ++vecNum) intVecSet ((FUNCPTR *)INUM_TO_IVEC(vecNum), (FUNCPTR)excExcHandle); intVecSet ((FUNCPTR *)INUM_TO_IVEC(INUM_NMI), (FUNCPTR)excIntStub); /* set uninitialized interrupt handler */ for (vecNum = INUM_INTR_LOW; vecNum <= INUM_INTR_HIGH; ++vecNum) intVecSet ((FUNCPTR *)INUM_TO_IVEC(vecNum), (FUNCPTR)excIntStub); /* set uninitialized trap handler */ for (vecNum = INUM_TRAP_128; vecNum <= INUM_TRAP_255; ++vecNum) intVecSet ((FUNCPTR *)INUM_TO_IVEC(vecNum), (FUNCPTR)excExcHandle);#elif (CPU==SH7600 || CPU==SH7000) /* make exception vectors point to proper place in bsr table */ for (vecNum = LOW_VEC; vecNum <= HIGH_VEC; ++vecNum) intVecSet ((FUNCPTR *)INUM_TO_IVEC(vecNum),(FUNCPTR)&excBsrTbl[vecNum]);#endif /* CPU==SH7600 || CPU==SH7000 */ return status; }#if (CPU==SH7750)/******************************************************************************** excPciMapInit - initialize the virtual PCI space mapping (SH7751 only)** This routine installs a special TLB mishit exception handler which virtually* extends the limited PCI window size of SH7751. The original PCI window size* is 16MB for memory space and 256KB for IO space, but this new handler allows* you to extend them to an any multiple of the original window size. The first* three arguments describe the mapping of PCI memory space, and their every* lower 24 bits are discarded to force 16MB (0x1000000) alignment. The last* three arguments describe the mapping of PCI IO space, and their every lower* 18 bits are discarded to force 256KB (0x40000) alignment. These virtual PCI* space descriptions and sysPhysMemDesc[] entries should not overlap.* If you set ioSpaceSize to zero, the PCI IO space support is removed from* the new TLB mishit handler to give a better performance over the non-PCI* virtual space. However the removal of PCI memory space support is not* implemented so that you should not set memSpaceSize to zero.* The virtual PCI page attribute is fixed to read/writable and non-cacheable,* and the page size is 1MB on PCI memory space, and 64KB on PCI IO space.** WHEN TO CALL* This routine overwrites the default TLB mishit handler and it tells* mmuSh7750LibInit() to reserve some UTLB entries for virtual PCI mapping.* Therefore it must be called after excVecInit(), and before usrMmuInit().** RETURNS: ERROR if memSpaceSize is zero or virtual spaces overlap,* OK otherwise.*/STATUS excPciMapInit ( void *memCpuAddr, /* CPU address of virtual PCI memory space */ void *memBusAddr, /* PCI bus address for PCI memory space */ UINT memSpaceSize, /* byte length of PCI memory space */ void *ioCpuAddr, /* CPU address of virtual PCI IO space */ void *ioBusAddr, /* PCI bus address for PCI IO space */ UINT ioSpaceSize /* byte length of PCI IO space */ ) { UINT paramAddr; UINT vecAddr =(((UINT)intVecBaseGet() & 0x1fffffff) | ((UINT)excPciMapInit & 0xe0000000)) + SH7700_TLB_STUB_OFFSET; if (memSpaceSize == 0) return ERROR; /* unsupported */ if (!(ioCpuAddr >= memCpuAddr + memSpaceSize || memCpuAddr >= ioCpuAddr + ioSpaceSize)) return ERROR; /* overlap in virtual space */ /* install PCI memory space handler */ { bcopy ((char *)mmuPciStub, (char *)vecAddr, mmuPciStubSize); /* setup PCI memory space parameters */ paramAddr = vecAddr + mmuPciStubParams; *(UINT32 *)(paramAddr + 0) = (UINT32)memCpuAddr & 0xff000000; *(UINT32 *)(paramAddr + 4) =((UINT32)memCpuAddr & 0xff000000) + (memSpaceSize & 0xff000000); *(UINT32 *)(paramAddr + 8) =((UINT32)memBusAddr & 0xff000000) - ((UINT32)memCpuAddr & 0xff000000); CACHE_TEXT_UPDATE ((void *)vecAddr, mmuPciStubSize); vecAddr += mmuPciStubSize; } /* concatenate PCI IO space handler if necessary */ if (ioSpaceSize) { bcopy ((char *)mmuPciIoStub, (char *)vecAddr, mmuPciIoStubSize); /* setup PCI IO space parameters */ paramAddr = vecAddr + mmuPciIoStubParams; *(UINT32 *)(paramAddr + 0) = (UINT32)ioCpuAddr & 0xfffc0000; *(UINT32 *)(paramAddr + 4) =((UINT32)ioCpuAddr & 0xfffc0000) + (ioSpaceSize & 0xfffc0000); *(UINT32 *)(paramAddr + 8) =((UINT32)ioBusAddr & 0xfffc0000) - ((UINT32)ioCpuAddr & 0xfffc0000); CACHE_TEXT_UPDATE ((void *)vecAddr, mmuPciIoStubSize); vecAddr += mmuPciIoStubSize; } /* terminate PCI space handler with proper TLB mishit part */ { bcopy ((char *)mmuStubProper, (char *)vecAddr, mmuStubProperSize); CACHE_TEXT_UPDATE ((void *)vecAddr, mmuStubProperSize); } /* tell mmuSh7750LibInit() to reserve some UTLB entries for PCI space */ excMmuCrVal = ioSpaceSize ? 0x00fb0104 : 0x00fc0104; /* MMUCR: URB=62/63 SV=1 TI=1 AT=0 */ return OK; }#endif /* CPU==SH7750 */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -