| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436 |
- /*
- * xtensa/cacheattrasm.h -- assembler-specific CACHEATTR register related definitions
- * that depend on CORE configuration
- *
- * This file is logically part of xtensa/coreasm.h (or perhaps xtensa/cacheasm.h),
- * but is kept separate for modularity / compilation-performance.
- */
- /*
- * Copyright (c) 2001-2009 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.
- */
- #ifndef XTENSA_CACHEATTRASM_H
- #define XTENSA_CACHEATTRASM_H
- #include <xtensa/coreasm.h>
- /* Determine whether cache attributes are controlled using eight 512MB entries: */
- #define XCHAL_CA_8X512 (XCHAL_HAVE_CACHEATTR || XCHAL_HAVE_MIMIC_CACHEATTR || XCHAL_HAVE_XLT_CACHEATTR \
- || (XCHAL_HAVE_PTP_MMU && XCHAL_HAVE_SPANNING_WAY))
- /*
- * This header file defines assembler macros of the form:
- * <x>cacheattr_<func>
- * where:
- * <x> is 'i', 'd' or absent for instruction, data
- * or both caches; and
- * <func> indicates the function of the macro.
- *
- * The following functions are defined:
- *
- * icacheattr_get
- * Reads I-cache CACHEATTR into a2 (clobbers a3-a5).
- *
- * dcacheattr_get
- * Reads D-cache CACHEATTR into a2 (clobbers a3-a5).
- * (Note: for configs with a real CACHEATTR register, the
- * above two macros are identical.)
- *
- * cacheattr_set
- * Writes both I-cache and D-cache CACHEATTRs from a2 (a3-a8 clobbered).
- * Works even when changing one's own code's attributes.
- *
- * icacheattr_is_enabled label
- * Branches to \label if I-cache appears to have been enabled
- * (eg. if CACHEATTR contains a cache-enabled attribute).
- * (clobbers a2-a5,SAR)
- *
- * dcacheattr_is_enabled label
- * Branches to \label if D-cache appears to have been enabled
- * (eg. if CACHEATTR contains a cache-enabled attribute).
- * (clobbers a2-a5,SAR)
- *
- * cacheattr_is_enabled label
- * Branches to \label if either I-cache or D-cache appears to have been enabled
- * (eg. if CACHEATTR contains a cache-enabled attribute).
- * (clobbers a2-a5,SAR)
- *
- * The following macros are only defined under certain conditions:
- *
- * icacheattr_set (if XCHAL_HAVE_MIMIC_CACHEATTR || XCHAL_HAVE_XLT_CACHEATTR)
- * Writes I-cache CACHEATTR from a2 (a3-a8 clobbered).
- *
- * dcacheattr_set (if XCHAL_HAVE_MIMIC_CACHEATTR || XCHAL_HAVE_XLT_CACHEATTR)
- * Writes D-cache CACHEATTR from a2 (a3-a8 clobbered).
- */
- /*************************** GENERIC -- ALL CACHES ***************************/
- /*
- * _cacheattr_get
- *
- * (Internal macro.)
- * Returns value of CACHEATTR register (or closest equivalent) in a2.
- *
- * Entry:
- * (none)
- * Exit:
- * a2 value read from CACHEATTR
- * a3-a5 clobbered (temporaries)
- */
- .macro _cacheattr_get tlb
- #if XCHAL_HAVE_CACHEATTR
- rsr a2, CACHEATTR
- #elif XCHAL_CA_8X512
- // We have a config that "mimics" CACHEATTR using a simplified
- // "MMU" composed of a single statically-mapped way.
- // DTLB and ITLB are independent, so there's no single
- // cache attribute that can describe both. So for now
- // just return the DTLB state.
- movi a5, 0xE0000000
- movi a2, 0
- movi a3, XCHAL_SPANNING_WAY
- 1: add a3, a3, a5 // next segment
- r&tlb&1 a4, a3 // get PPN+CA of segment at 0xE0000000, 0xC0000000, ..., 0
- dsync // interlock???
- slli a2, a2, 4
- extui a4, a4, 0, 4 // extract CA
- or a2, a2, a4
- bgeui a3, 16, 1b
- #else
- // This macro isn't applicable to arbitrary MMU configurations.
- // Just return zero.
- movi a2, 0
- #endif
- .endm
- .macro icacheattr_get
- _cacheattr_get itlb
- .endm
- .macro dcacheattr_get
- _cacheattr_get dtlb
- .endm
- /* Default (powerup/reset) value of CACHEATTR,
- all BYPASS mode (ie. disabled/bypassed caches): */
- #if XCHAL_HAVE_PTP_MMU
- # define XCHAL_CACHEATTR_ALL_BYPASS 0x33333333
- #else
- # define XCHAL_CACHEATTR_ALL_BYPASS 0x22222222
- #endif
- #if XCHAL_CA_8X512
- #if XCHAL_HAVE_PTP_MMU
- # define XCHAL_FCA_ENAMASK 0x0AA0 /* bitmap of fetch attributes that require enabled icache */
- # define XCHAL_LCA_ENAMASK 0x0FF0 /* bitmap of load attributes that require enabled dcache */
- # define XCHAL_SCA_ENAMASK 0x0CC0 /* bitmap of store attributes that require enabled dcache */
- #else
- # define XCHAL_FCA_ENAMASK 0x003A /* bitmap of fetch attributes that require enabled icache */
- # define XCHAL_LCA_ENAMASK 0x0033 /* bitmap of load attributes that require enabled dcache */
- # define XCHAL_SCA_ENAMASK 0x0033 /* bitmap of store attributes that require enabled dcache */
- #endif
- #define XCHAL_LSCA_ENAMASK (XCHAL_LCA_ENAMASK|XCHAL_SCA_ENAMASK) /* l/s attrs requiring enabled dcache */
- #define XCHAL_ALLCA_ENAMASK (XCHAL_FCA_ENAMASK|XCHAL_LSCA_ENAMASK) /* all attrs requiring enabled caches */
- /*
- * _cacheattr_is_enabled
- *
- * (Internal macro.)
- * Branches to \label if CACHEATTR in a2 indicates an enabled
- * cache, using mask in a3.
- *
- * Parameters:
- * label where to branch to if cache is enabled
- * Entry:
- * a2 contains CACHEATTR value used to determine whether
- * caches are enabled
- * a3 16-bit constant where each bit correspond to
- * one of the 16 possible CA values (in a CACHEATTR mask);
- * CA values that indicate the cache is enabled
- * have their corresponding bit set in this mask
- * (eg. use XCHAL_xCA_ENAMASK , above)
- * Exit:
- * a2,a4,a5 clobbered
- * SAR clobbered
- */
- .macro _cacheattr_is_enabled label
- movi a4, 8 // loop 8 times
- .Lcaife\@:
- extui a5, a2, 0, 4 // get CA nibble
- ssr a5 // index into mask according to CA...
- srl a5, a3 // ...and get CA's mask bit in a5 bit 0
- bbsi.l a5, 0, \label // if CA indicates cache enabled, jump to label
- srli a2, a2, 4 // next nibble
- addi a4, a4, -1
- bnez a4, .Lcaife\@ // loop for each nibble
- .endm
- #else /* XCHAL_CA_8X512 */
- .macro _cacheattr_is_enabled label
- j \label // macro not applicable, assume caches always enabled
- .endm
- #endif /* XCHAL_CA_8X512 */
- /*
- * icacheattr_is_enabled
- *
- * Branches to \label if I-cache is enabled.
- *
- * Parameters:
- * label where to branch to if icache is enabled
- * Entry:
- * (none)
- * Exit:
- * a2-a5, SAR clobbered (temporaries)
- */
- .macro icacheattr_is_enabled label
- #if XCHAL_CA_8X512
- icacheattr_get
- movi a3, XCHAL_FCA_ENAMASK
- #endif
- _cacheattr_is_enabled \label
- .endm
- /*
- * dcacheattr_is_enabled
- *
- * Branches to \label if D-cache is enabled.
- *
- * Parameters:
- * label where to branch to if dcache is enabled
- * Entry:
- * (none)
- * Exit:
- * a2-a5, SAR clobbered (temporaries)
- */
- .macro dcacheattr_is_enabled label
- #if XCHAL_CA_8X512
- dcacheattr_get
- movi a3, XCHAL_LSCA_ENAMASK
- #endif
- _cacheattr_is_enabled \label
- .endm
- /*
- * cacheattr_is_enabled
- *
- * Branches to \label if either I-cache or D-cache is enabled.
- *
- * Parameters:
- * label where to branch to if a cache is enabled
- * Entry:
- * (none)
- * Exit:
- * a2-a5, SAR clobbered (temporaries)
- */
- .macro cacheattr_is_enabled label
- #if XCHAL_HAVE_CACHEATTR
- rsr a2, CACHEATTR
- movi a3, XCHAL_ALLCA_ENAMASK
- #elif XCHAL_CA_8X512
- icacheattr_get
- movi a3, XCHAL_FCA_ENAMASK
- _cacheattr_is_enabled \label
- dcacheattr_get
- movi a3, XCHAL_LSCA_ENAMASK
- #endif
- _cacheattr_is_enabled \label
- .endm
- /*
- * The ISA does not have a defined way to change the
- * instruction cache attributes of the running code,
- * ie. of the memory area that encloses the current PC.
- * However, each micro-architecture (or class of
- * configurations within a micro-architecture)
- * provides a way to deal with this issue.
- *
- * Here are a few macros used to implement the relevant
- * approach taken.
- */
- #if XCHAL_CA_8X512 && !XCHAL_HAVE_CACHEATTR
- // We have a config that "mimics" CACHEATTR using a simplified
- // "MMU" composed of a single statically-mapped way.
- /*
- * icacheattr_set
- *
- * Entry:
- * a2 cacheattr value to set
- * Exit:
- * a2 unchanged
- * a3-a8 clobbered (temporaries)
- */
- .macro icacheattr_set
- movi a5, 0xE0000000 // mask of upper 3 bits
- movi a6, 3f // PC where ITLB is set
- movi a3, XCHAL_SPANNING_WAY // start at region 0 (0 .. 7)
- mov a7, a2 // copy a2 so it doesn't get clobbered
- and a6, a6, a5 // upper 3 bits of local PC area
- j 3f
- // Use micro-architecture specific method.
- // The following 4-instruction sequence is aligned such that
- // it all fits within a single I-cache line. Sixteen byte
- // alignment is sufficient for this (using XCHAL_ICACHE_LINESIZE
- // actually causes problems because that can be greater than
- // the alignment of the reset vector, where this macro is often
- // invoked, which would cause the linker to align the reset
- // vector code away from the reset vector!!).
- .begin no-transform
- .align 16 /*XCHAL_ICACHE_LINESIZE*/
- 1: witlb a4, a3 // write wired PTE (CA, no PPN) of 512MB segment to ITLB
- isync
- .end no-transform
- nop
- nop
- sub a3, a3, a5 // next segment (add 0x20000000)
- bltui a3, 16, 4f // done?
- // Note that in the WITLB loop, we don't do any load/stores
- // (may not be an issue here, but it is important in the DTLB case).
- 2: srli a7, a7, 4 // next CA
- 3:
- # if XCHAL_HAVE_MIMIC_CACHEATTR
- extui a4, a7, 0, 4 // extract CA to set
- # else /* have translation, preserve it: */
- ritlb1 a8, a3 // get current PPN+CA of segment
- //dsync // interlock???
- extui a4, a7, 0, 4 // extract CA to set
- srli a8, a8, 4 // clear CA but keep PPN ...
- slli a8, a8, 4 // ...
- add a4, a4, a8 // combine new CA with PPN to preserve
- # endif
- beq a3, a6, 1b // current PC's region? if so, do it in a safe way
- witlb a4, a3 // write wired PTE (CA [+PPN]) of 512MB segment to ITLB
- sub a3, a3, a5 // next segment (add 0x20000000)
- bgeui a3, 16, 2b
- isync // make sure all ifetch changes take effect
- 4:
- .endm // icacheattr_set
- /*
- * dcacheattr_set
- *
- * Entry:
- * a2 cacheattr value to set
- * Exit:
- * a2 unchanged
- * a3-a8 clobbered (temporaries)
- */
- .macro dcacheattr_set
- movi a5, 0xE0000000 // mask of upper 3 bits
- movi a3, XCHAL_SPANNING_WAY // start at region 0 (0 .. 7)
- mov a7, a2 // copy a2 so it doesn't get clobbered
- // Note that in the WDTLB loop, we don't do any load/stores
- 2: // (including implicit l32r via movi) because it isn't safe.
- # if XCHAL_HAVE_MIMIC_CACHEATTR
- extui a4, a7, 0, 4 // extract CA to set
- # else /* have translation, preserve it: */
- rdtlb1 a8, a3 // get current PPN+CA of segment
- //dsync // interlock???
- extui a4, a7, 0, 4 // extract CA to set
- srli a8, a8, 4 // clear CA but keep PPN ...
- slli a8, a8, 4 // ...
- add a4, a4, a8 // combine new CA with PPN to preserve
- # endif
- wdtlb a4, a3 // write wired PTE (CA [+PPN]) of 512MB segment to DTLB
- sub a3, a3, a5 // next segment (add 0x20000000)
- srli a7, a7, 4 // next CA
- bgeui a3, 16, 2b
- dsync // make sure all data path changes take effect
- .endm // dcacheattr_set
- #endif /* XCHAL_CA_8X512 && !XCHAL_HAVE_CACHEATTR */
- /*
- * cacheattr_set
- *
- * Macro that sets the current CACHEATTR safely
- * (both i and d) according to the current contents of a2.
- * It works even when changing the cache attributes of
- * the currently running code.
- *
- * Entry:
- * a2 cacheattr value to set
- * Exit:
- * a2 unchanged
- * a3-a8 clobbered (temporaries)
- */
- .macro cacheattr_set
- #if XCHAL_HAVE_CACHEATTR
- # if XCHAL_ICACHE_LINESIZE < 4
- // No i-cache, so can always safely write to CACHEATTR:
- wsr a2, CACHEATTR
- # else
- // The Athens micro-architecture, when using the old
- // exception architecture option (ie. with the CACHEATTR register)
- // allows changing the cache attributes of the running code
- // using the following exact sequence aligned to be within
- // an instruction cache line. (NOTE: using XCHAL_ICACHE_LINESIZE
- // alignment actually causes problems because that can be greater
- // than the alignment of the reset vector, where this macro is often
- // invoked, which would cause the linker to align the reset
- // vector code away from the reset vector!!).
- j 1f
- .begin no-transform
- .align 16 /*XCHAL_ICACHE_LINESIZE*/ // align to within an I-cache line
- 1: wsr a2, CACHEATTR
- isync
- .end no-transform
- nop
- nop
- # endif
- #elif XCHAL_CA_8X512
- // DTLB and ITLB are independent, but to keep semantics
- // of this macro we simply write to both.
- icacheattr_set
- dcacheattr_set
- #else
- // This macro isn't applicable to arbitrary MMU configurations.
- // Do nothing in this case.
- #endif
- .endm
- #endif /*XTENSA_CACHEATTRASM_H*/
|