X-Git-Url: https://jxself.org/git/?p=open-ath9k-htc-firmware.git;a=blobdiff_plain;f=target_firmware%2Fmagpie_fw_dev%2Fbuild%2Fmagpie_1_1%2Fsboot%2Fathos%2Fsrc%2Fxtos%2Fmemerror-vector.S;fp=target_firmware%2Fmagpie_fw_dev%2Fbuild%2Fmagpie_1_1%2Fsboot%2Fathos%2Fsrc%2Fxtos%2Fmemerror-vector.S;h=0000000000000000000000000000000000000000;hp=04f7c0d2dca54b9d893399614be69ba2d6830f39;hb=ff66305a044be28464fa0969ea2d605bb268d478;hpb=60b496560eec004ded92ae4dad43b3d102c6658d diff --git a/target_firmware/magpie_fw_dev/build/magpie_1_1/sboot/athos/src/xtos/memerror-vector.S b/target_firmware/magpie_fw_dev/build/magpie_1_1/sboot/athos/src/xtos/memerror-vector.S deleted file mode 100755 index 04f7c0d..0000000 --- a/target_firmware/magpie_fw_dev/build/magpie_1_1/sboot/athos/src/xtos/memerror-vector.S +++ /dev/null @@ -1,482 +0,0 @@ -/* memerror-vector.S -- Memory Error Exception Vector and Handler */ - -/* $Id: //depot/rel/Cottonwood/Xtensa/OS/xtos/memerror-vector.S#3 $ */ - -/* - * Copyright (c) 2006-2010 Tensilica Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -//#include -#include -#include - -#if XCHAL_HAVE_MEM_ECC_PARITY -# if defined(__SPLIT__vector) - - // Place this code in the memory error exception vector: - .begin literal_prefix .MemoryExceptionVector - .section .MemoryExceptionVector.text, "ax" - - .global _MemErrorVector - .align 4 -_MemErrorVector: -# if 0 /* XCHAL_HAVE_DEBUG */ - // Memory errors raise PS.INTLEVEL above DEBUGLEVEL, so - // break instructions have no effect within them (debug - // exceptions are masked). So leave commented out for now. - break 1, 5 // unhandled memory error exception -# endif - wsr a0, MESAVE - movi a0, _MemErrorHandler - jx a0 - - .size _MemErrorVector, . - _MemErrorVector - .text - .end literal_prefix - - -# elif defined(__SPLIT__handler) - -/* - * Some rules and assumptions: - * - * Anything that can interrupt this handler (e.g. NMI): - * - must not lock or unlock cache lines - */ - - -#define ICACHE_WAYWIDTH (XCHAL_ICACHE_SETWIDTH + XCHAL_ICACHE_LINEWIDTH) /* LICT's "iis" */ -#define DCACHE_WAYWIDTH (XCHAL_DCACHE_SETWIDTH + XCHAL_DCACHE_LINEWIDTH) /* LDCT's "dis" */ -/* NOTE: Memory ECC/parity is not supported on XLMI or on local ROMs: */ -#define HAVE_LOCAL_RAM (XCHAL_NUM_DATARAM || XCHAL_NUM_INSTRAM /*|| XCHAL_NUM_URAM || XCHAL_NUM_XLMI*/) - - - //.lcomm _MemErrorSave, 8 - .comm _MemErrorSave, 8, 4 - - .text - .align 4 - .global _MemErrorHandler -_MemErrorHandler: - rsr a0, MESR - bbsi.l a0, MESR_DME_SHIFT, .L_fatal_dme -# if XCHAL_ICACHE_SIZE > 0 || XCHAL_DCACHE_SIZE > 0 - bbsi.l a0, MESR_MEMTYPE_SHIFT+1, .L_cache // branch if error on a cache -# endif - // Error in a local memory. -# if HAVE_LOCAL_RAM - bbsi.l a0, MESR_ERRTYPE_SHIFT, .L_uncorrectable_local - // Correctable error in a local memory (IRAM or DRAM). - // (MEVADDR has all 32 bits, so XSR preserves a register:) - xsr a2, MEVADDR - // Note: MEVADDR is always 4-byte aligned, - // so we can just do L32I/S32I to correct the error. - // However, that's not atomic, and NMI can store in between; - // that's usually a problem for D rather than I, avoid the - // issue using S32C1I if configured (else NMI must not write DataRAM!?!): -# if (XCHAL_HAVE_S32C1I && (XCHAL_NUM_DATARAM /*|| XCHAL_NUM_URAM || XCHAL_NUM_XLMI*/)) - bbci.l a0, MESR_MEMTYPE_SHIFT, .L_instram // branch if error on InstRAM - // Unfortunately we need 3 registers to do S32C1I (data,addr,SCOMPARE1) so - // we need to save to _MemErrorSave: - movi a0, _MemErrorSave - s32i a4, a0, 0 // save a4 - l32i a4, a2, 0 // load data (re-correct) - rsr a0, SCOMPARE1 // save SCOMPARE1 - wsr a4, SCOMPARE1 - s32c1i a4, a2, 0 // store if still contains same value (else other store corrected error) - movi a4, _MemErrorSave - wsr a0, SCOMPARE1 // restore SCOMPARE1 - l32i a4, a4, 0 // restore a4 - j 2f -.L_instram: -# endif - l32i a0, a2, 0 // load data (re-correct) - s32i a0, a2, 0 // store data to correct ECC bits -2: xsr a2, MEVADDR -# endif /* HAVE_LOCAL_RAM */ -.L_done: - rsr a0, MESAVE - rfme - - - // Weak reference: if unresolved, links okay but with zero value: - .weak _xtos_merr_hook_fatal_dme -.L_fatal_dme: - // Fatal (unrecoverable) error, double memory exception - movi a0, _xtos_merr_hook_fatal_dme -1: beqz a0, 1b // fatal double memory error, no hook, so infinite loop - jx a0 // jump to user hook, if present - - -# if HAVE_LOCAL_RAM - // Weak reference: if unresolved, links okay but with zero value: - .weak _xtos_merr_hook_uncorrectable_local -.L_uncorrectable_local: - // Fatal (unrecoverable) error in IRAM or DRAM: parity or uncorrectable ECC error - movi a0, _xtos_merr_hook_uncorrectable_local -1: beqz a0, 1b // fatal memory error, no hook provided, so infinite loop - jx a0 // jump to user hook, if present -# endif - - -# if XCHAL_ICACHE_SIZE > 0 || XCHAL_DCACHE_SIZE > 0 -.L_cache: - // Error in one of the caches. -# endif - -# if XCHAL_ICACHE_SIZE > 0 -# if XCHAL_DCACHE_SIZE > 0 - bbsi.l a0, MESR_MEMTYPE_SHIFT, .L_dcache // branch if data cache error -# endif - // Error in the instruction cache. - bbsi.l a0, MESR_ERRTYPE_SHIFT, .L_icache_noncorr // branch if uncorrectable - // Correctable error in the instruction cache. - xsr a2, MEVADDR - // TODO FIXME: remove these 5 lines if waynum is in MEVADDR!? by using III if tag and IHI otherwise!?!?!?: -# if XCHAL_ICACHE_WAYS > 1 - extui a0, a0, MESR_WAYNUM_SHIFT, 2 - slli a0, a0, ICACHE_WAYWIDTH - slli a2, a2, 32 - ICACHE_WAYWIDTH - srli a2, a2, 32 - ICACHE_WAYWIDTH - or a2, a2, a0 -# endif - iii a2, 0 // invalidate line (whole set!) if not locked -# if XCHAL_ICACHE_LINE_LOCKABLE - // III has no effect if the line is locked; for that case, need to do more: - lict a0, a2 - bbci.l a0, XCHAL_ICACHE_TAG_L_SHIFT, .L_icache_done // branch if unlocked - // Correctable error in a locked instruction cache line. - // Fix both tag and one word, quicker than figuring out whether error is in tag or data: - sict a0, a2 // fix tag - licw a0, a2 - sicw a0, a2 // fix data word -# endif -.L_icache_done: - xsr a2, MEVADDR - j .L_done - -.L_icache_noncorr: - // Non-correctable error in the instruction cache. - bbsi.l a0, MESR_MEMTYPE_SHIFT+2, .L_icache_tag_noncorr // branch if tag error - // Non-correctable error in the instruction cache data. - // Just invalidate the line if we can. -# if XCHAL_ICACHE_LINE_LOCKABLE - // If locked, need a different fix sequence. - xsr a2, MEVADDR - -# if XCHAL_ICACHE_WAYS > 1 - // This sequence is shorter, but does not retain original MEVADDR so - // prevents subsequent use of instructions requiring a virtual address - // (such as LICW, IPFL, etc): -// extui a0, a0, MESR_WAYNUM_SHIFT, 2 -// slli a0, a0, ICACHE_WAYWIDTH -// slli a2, a2, 32 - ICACHE_WAYWIDTH -// srli a2, a2, 32 - ICACHE_WAYWIDTH -// or a2, a2, a0 - - extui a0, a0, MESR_WAYNUM_SHIFT, 2 // id of way with mem error - slli a0, a0, ICACHE_WAYWIDTH - xor a0, a2, a0 // xor corresponding bits of addr - extui a0, a0, ICACHE_WAYWIDTH, 2 // take 2 xor'ed way bits - or a2, a2, a0 // save them at bottom of addr - slli a0, a0, ICACHE_WAYWIDTH - xor a2, a2, a0 // and change 2 way bits of addr -# endif - lict a0, a2 - bbsi.l a0, XCHAL_ICACHE_TAG_L_SHIFT, .L_icache_locked_uncor // branch if locked - // Cache line is not locked, just invalidate: -# if XCHAL_ICACHE_WAYS > 1 - iii a2, 0 -# else - ihi a2, 0 -# endif - j .L_icache_done - - // NOTE: we don't use the LICW/SICW sequence below unless the line is locked, - // otherwise the i-cache line might get replaced between LICW and SICW - // (if we're not extremely careful), which would be disastrous. - // Also, for locked lines, LICW/SICW is much safer than IHU/IHI/IPFL - // because it doesn't leave a window where the line is unlocked; - // however, if the error is non-correctable, we have no choice. - -.L_icache_locked_uncor: - // If locked and uncorrectable however, the only recourse is relocking. - // So we need to recover the virtual address so we can do IPFL. - // Note: can't use MEPC instead of MEVADDR, because (a) it might not - // point to the correct cache line, and (b) it might be completely wrong - // in the case where the mem error happened e.g. during an LICW or IPFL. -# if XCHAL_ICACHE_WAYS > 1 - // Recover virtual address in a2: - extui a0, a2, 0, 2 // get saved xor'ed bits at bottom - slli a0, a0, ICACHE_WAYWIDTH // line them up - xor a2, a2, a0 // restore original MEVADDR -# endif - ihu a2, 0 // unlock line - ihi a2, 0 // invalidate line - ipfl a2, 0 // refetch-and-lock the line - j .L_icache_done -# else /* LOCKABLE */ - rsr a0, MEVADDR - ihi a0, 0 // invalidate that cache line - j .L_done -# endif /* LOCKABLE */ - -.L_icache_tag_noncorr: - // Non-correctable error in the instruction cache tag. - // Just invalidate the tag or the entire set. -# if XCHAL_ICACHE_LINE_LOCKABLE - // Note: can't use either IIU or III, as these don't write the entire tag, - // so they'll get the exception again. So, have to use SICT. -# if XCHAL_ICACHE_WAYS > 1 - // TODO FIXME: avoid this 8-line alternative if waynum is in MEVADDR!?: - xsr a2, MEVADDR - extui a0, a0, MESR_WAYNUM_SHIFT, 2 - slli a0, a0, ICACHE_WAYWIDTH - slli a2, a2, 32 - ICACHE_WAYWIDTH - srli a2, a2, 32 - ICACHE_WAYWIDTH - or a2, a2, a0 - iiu a2, 0 // unlock line ==> also invalidates! (I-side only) - xsr a2, MEVADDR -# else - rsr a0, MEVADDR - iiu a0, 0 // unlock line ==> also invalidates! (I-side only) -# endif - // If line was locked, can't recover lock state, need external info to recover. - // User can provide an assembler hook routine _xtos_merr_hook_icache_relock - // to relock the icache at the index in a2: - // - any number of lines might still be locked at that index, - // including all of them - // - no stack is provided, a0 must be used as starting point to - // load a save area and saved registers as necessary - // - unless routine just does ret (i.e. does not modify any - // register, only possible if it does nothing), it needs to - // return by restoring all registers it modified, ending with: - // rsr a0, MESAVE - // rfme - // CAVEAT EMPTOR: this hook mechanism is subject to change. - .weak _xtos_merr_hook_icache_relock // if unresolved, links with zero value - movi a0, _xtos_merr_hook_icache_relock -1: beqz a0, 1b // if no hook to recover lock state on icache tag mem error, loop forever - callx0 a0 // invoke user hook to relock i-cache (index in MEVADDR) -# else - rsr a0, MEVADDR - iii a0, 0 // invalidate entire set -# endif - j .L_done -# endif /* have ICACHE */ - - -# if XCHAL_DCACHE_SIZE > 0 -# if XCHAL_ICACHE_SIZE > 0 -.L_dcache: -# endif - // Error in the data cache. -# if XCHAL_DCACHE_IS_WRITEBACK || XCHAL_DCACHE_LINE_LOCKABLE - bbsi.l a0, MESR_ERRTYPE_SHIFT, .L_dcache_noncorr // branch if uncorrectable - // Uncorrectable error on a writeback dcache might be unrecoverable: -# endif - bbsi.l a0, MESR_MEMTYPE_SHIFT+2, .L_dcache_tag // branch if tag error - // Error in the data cache data (correctable, or non-correctable in writethru+unlockable cache). - // MEVADDR always a real vaddr here; might point to cache-isolate mode area though. -# if XCHAL_DCACHE_LINE_LOCKABLE - // Correctable error on lockable dcache data. - // If locked, need to refetch the line (or load/store its contents, which is less safe): - xsr a2, MEVADDR -# if XCHAL_DCACHE_WAYS > 1 - // Need some extra computation to get the correct dcache way's tag: - movi a0, _MemErrorSave - s32i a4, a0, 0 // save a4 - s32i a5, a0, 4 // save a5 - rsr a4, MESR - extui a4, a4, MESR_WAYNUM_SHIFT, 2 - slli a4, a4, DCACHE_WAYWIDTH - slli a5, a2, 32 - DCACHE_WAYWIDTH - srli a5, a5, 32 - DCACHE_WAYWIDTH - add a4, a4, a5 - mov a5, a0 - ldct a0, a4 - l32i a4, a5, 0 // restore a4 - l32i a5, a5, 4 // restore a5 -# else - ldct a0, a2 -# endif - // FIXME: if castout, a2 is a physical address! doesn't work with any address translation. -# if 0 /* translation */ - movi a4, _xtos_vmap_vaddr // FIXME: do we need two variables for full MMU? -1: beqz a4, 1b // if no vaddr to use, loop forever (FIXME: caxlt: could assume V==P) - rdtlb1 a5, a4 // save current contents - ... clear lower bits of a4 ... - xx = some function of a2 - wdtlb xx, a4 - a2 = virtual address, i.e. some function of a2 and a4 ... - ... do the sequence below ... - ... - wdtlb a5, a4 // restore TLB entry -# endif - // NOTE: the following sequence leaves the line temporarily unlocked, if locked. - // We assume NMI handlers don't lock lines or rely on their being locked. - // We could have used "l32i a0,a2,0; s32i a0,a2,0" but that's not atomic on the data. - dhu a2, 0 // unlock the cache line, if locked - dhwbi a2, 0 // writeback and invalidate cache line - bbci.l a0, XCHAL_DCACHE_TAG_L_SHIFT, 1f - dpfl a2, 0 // re-prefetch-and-lock the cache line -1: xsr a2, MEVADDR -# else /* LOCKABLE */ - // Error in unlockable data cache data (correctable, or non-correctable in writethru cache). - rsr a0, MEVADDR - // USELESS NOTE: if writethru dcache and NMI handlers don't store to this, we could use DHI instead: - // FIXME: if castout, a0 is a physical address! doesn't work with any address translation. - dhwbi a0, 0 // writeback (if correctable) and invalidate that cache line -# endif /* LOCKABLE */ - j .L_done - -.L_dcache_tag: - // Error in data cache tag (correctable, or non-correctable in writethru+unlockable cache). - // MEVADDR only contains cache index here (not waynum), don't expect a vaddr (the ISA - // says upper bits are undefined; actual hw does put a vaddr, but in future might not). - // Whether or not correctable, just invalidate the particular way's line: - xsr a2, MEVADDR - // NOTE: could remove these 5 lines if hw were designed with waynum in MEVADDR (but is not): -# if XCHAL_DCACHE_WAYS > 1 - extui a0, a0, MESR_WAYNUM_SHIFT, 2 - slli a0, a0, DCACHE_WAYWIDTH - slli a2, a2, 32 - DCACHE_WAYWIDTH - srli a2, a2, 32 - DCACHE_WAYWIDTH - or a2, a2, a0 -# endif -# if XCHAL_DCACHE_LINE_LOCKABLE - ldct a0, a2 // invalidate and unlock that cache tag - bbci.l a0, XCHAL_DCACHE_TAG_L_SHIFT, 1f // branch if not locked - sdct a0, a2 // if locked, this safely writes whole tag -# endif -1: diwbi a2, 0 // writeback (if correctable) and invalidate the line - xsr a2, MEVADDR - j .L_done - - - -# if XCHAL_DCACHE_IS_WRITEBACK || XCHAL_DCACHE_LINE_LOCKABLE -.L_dcache_noncorr: - // Uncorrectable error on a (writeback and/or lockable) data cache. -# if XCHAL_DCACHE_IS_WRITEBACK - // On tag errors we don't know whether the line is dirty, so this is unrecoverable: - bbsi.l a0, MESR_MEMTYPE_SHIFT+2, .L_uncorrectable_dtag // branch if tag error - // Castouts are by definition dirty, uncorrectable errors on these are unrecoverable: - bbsi.l a0, MESR_ACCTYPE_SHIFT, .L_uncorrectable_dirty // branch if castout - // Note: could still be an error on dirty dcache data, also unrecoverable. -# else - bbsi.l a0, MESR_MEMTYPE_SHIFT+2, .L_dcache_tag_noncorr // branch if tag error -# endif - // Uncorrectable error in dcache data. - // May be dirty or locked, so get tag to find out. - xsr a2, MEVADDR -# if XCHAL_DCACHE_WAYS > 1 - extui a0, a0, MESR_WAYNUM_SHIFT, 2 // id of way with mem error - slli a0, a0, DCACHE_WAYWIDTH - xor a0, a2, a0 // xor corresponding bits of addr - extui a0, a0, DCACHE_WAYWIDTH, 2 // take 2 xor'ed way bits - or a2, a2, a0 // save them at bottom of addr - slli a0, a0, DCACHE_WAYWIDTH - xor a2, a2, a0 // and change 2 way bits of addr -# endif - ldct a0, a2 // get dcache tag -# if XCHAL_DCACHE_IS_WRITEBACK - bbsi.l a0, XCHAL_DCACHE_TAG_D_SHIFT, .L_uncorrectable_dirty_2 // branch if dirty -# endif - // Data cache line is clean. -# if XCHAL_DCACHE_LINE_LOCKABLE - bbsi.l a0, XCHAL_DCACHE_TAG_L_SHIFT, .L_dcache_nc_locked -# endif - // Data cache line is clean and unlocked. Just invalidate it. - // FIXME: any stores to this line by an NMI handler will be lost. - // On the other hand, if we use DHWBI, any stores by an NMI handler - // that don't happen to fix the error result in an unrecoverable castout. - // -# if XCHAL_ICACHE_WAYS > 1 - // Recover virtual address in a2: - extui a0, a2, 0, 2 // get saved xor'ed bits at bottom - slli a0, a0, ICACHE_WAYWIDTH // line them up - xor a2, a2, a0 // restore original MEVADDR -# endif - dhi a2, 0 // invalidate that data cache line - xsr a2, MEVADDR - j .L_done - -# if XCHAL_DCACHE_LINE_LOCKABLE -.L_dcache_nc_locked: -# if XCHAL_ICACHE_WAYS > 1 - // Recover virtual address in a2: - extui a0, a2, 0, 2 // get saved xor'ed bits at bottom - slli a0, a0, ICACHE_WAYWIDTH // line them up - xor a2, a2, a0 // restore original MEVADDR -# endif - // Unlock, invalidate, and relock it: - dhu a2, 0 // unlock that data cache line - dhi a2, 0 // invalidate that data cache line - dpfl a2, 0 // prefetch-and-lock the line again - xsr a2, MEVADDR - j .L_done -# endif - -# if XCHAL_DCACHE_IS_WRITEBACK - // Weak reference: if unresolved, links okay but with zero value: - .weak _xtos_merr_hook_uncor_dtag -.L_uncorrectable_dtag: - // Fatal (unrecoverable) error in dcache tag (maybe dirty): parity or uncorrectable ECC error - movi a0, _xtos_merr_hook_uncor_dtag -1: beqz a0, 1b // fatal non-corr dcache tag, no hook, so infinite loop - jx a0 // jump to user hook, if present - - // Weak reference: if unresolved, links okay but with zero value: - .weak _xtos_merr_hook_uncor_dirty -.L_uncorrectable_dirty_2: - xsr a2, MEVADDR -.L_uncorrectable_dirty: - // Fatal (unrecoverable) error, parity or non-correctable ECC error on dirty cache data - movi a0, _xtos_merr_hook_uncor_dirty -1: beqz a0, 1b // fatal non-corr dirty cache line, no hook, so infinite loop - jx a0 // jump to user hook, if present -# else -.L_dcache_tag_noncorr: - // Uncorrectable error on a lockable writethru data cache tag. - // We have to invalidate the line, but that way we lose the lock bit. - // Provide a hook to relock if necessary (using knowledge outside this module - // about what needs to be locked). See _xtos_merr_hook_icache_relock for details. - // CAVEAT EMPTOR: this hook mechanism is subject to change. - .weak _xtos_merr_hook_dcache_relock // if unresolved, links with zero value - movi a0, _xtos_merr_hook_dcache_relock -1: beqz a0, 1b // if no hook to recover lock state on dcache tag mem error, loop forever - callx0 a0 // invoke user hook to relock d-cache (index in MEVADDR) - j .L_done -# endif - -# endif /* DCACHE IS WRITEBACK || LINE_LOCKABLE */ - -# endif /* have DCACHE */ - - .size _MemErrorHandler, . - _MemErrorHandler - - - -# endif /* splitting */ -#endif /* XCHAL_HAVE_MEM_ECC_PARITY */ -