cacheasm.h 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962
  1. /*
  2. * xtensa/cacheasm.h -- assembler-specific cache related definitions
  3. * that depend on CORE configuration
  4. *
  5. * This file is logically part of xtensa/coreasm.h ,
  6. * but is kept separate for modularity / compilation-performance.
  7. */
  8. /*
  9. * Copyright (c) 2001-2014 Cadence Design Systems, Inc.
  10. *
  11. * Permission is hereby granted, free of charge, to any person obtaining
  12. * a copy of this software and associated documentation files (the
  13. * "Software"), to deal in the Software without restriction, including
  14. * without limitation the rights to use, copy, modify, merge, publish,
  15. * distribute, sublicense, and/or sell copies of the Software, and to
  16. * permit persons to whom the Software is furnished to do so, subject to
  17. * the following conditions:
  18. *
  19. * The above copyright notice and this permission notice shall be included
  20. * in all copies or substantial portions of the Software.
  21. *
  22. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  23. * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  24. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  25. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  26. * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  27. * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  28. * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  29. */
  30. #ifndef XTENSA_CACHEASM_H
  31. #define XTENSA_CACHEASM_H
  32. #include <xtensa/coreasm.h>
  33. #include <xtensa/corebits.h>
  34. #include <xtensa/xtensa-xer.h>
  35. #include <xtensa/xtensa-versions.h>
  36. /*
  37. * This header file defines assembler macros of the form:
  38. * <x>cache_<func>
  39. * where <x> is 'i' or 'd' for instruction and data caches,
  40. * and <func> indicates the function of the macro.
  41. *
  42. * The following functions <func> are defined,
  43. * and apply only to the specified cache (I or D):
  44. *
  45. * reset
  46. * Resets the cache.
  47. *
  48. * sync
  49. * Makes sure any previous cache instructions have been completed;
  50. * ie. makes sure any previous cache control operations
  51. * have had full effect and been synchronized to memory.
  52. * Eg. any invalidate completed [so as not to generate a hit],
  53. * any writebacks or other pipelined writes written to memory, etc.
  54. *
  55. * invalidate_line (single cache line)
  56. * invalidate_region (specified memory range)
  57. * invalidate_all (entire cache)
  58. * Invalidates all cache entries that cache
  59. * data from the specified memory range.
  60. * NOTE: locked entries are not invalidated.
  61. *
  62. * writeback_line (single cache line)
  63. * writeback_region (specified memory range)
  64. * writeback_all (entire cache)
  65. * Writes back to memory all dirty cache entries
  66. * that cache data from the specified memory range,
  67. * and marks these entries as clean.
  68. * NOTE: on some future implementations, this might
  69. * also invalidate.
  70. * NOTE: locked entries are written back, but never invalidated.
  71. * NOTE: instruction caches never implement writeback.
  72. *
  73. * writeback_inv_line (single cache line)
  74. * writeback_inv_region (specified memory range)
  75. * writeback_inv_all (entire cache)
  76. * Writes back to memory all dirty cache entries
  77. * that cache data from the specified memory range,
  78. * and invalidates these entries (including all clean
  79. * cache entries that cache data from that range).
  80. * NOTE: locked entries are written back but not invalidated.
  81. * NOTE: instruction caches never implement writeback.
  82. *
  83. * lock_line (single cache line)
  84. * lock_region (specified memory range)
  85. * Prefetch and lock the specified memory range into cache.
  86. * NOTE: if any part of the specified memory range cannot
  87. * be locked, a Load/Store Error (for dcache) or Instruction
  88. * Fetch Error (for icache) exception occurs. These macros don't
  89. * do anything special (yet anyway) to handle this situation.
  90. *
  91. * unlock_line (single cache line)
  92. * unlock_region (specified memory range)
  93. * unlock_all (entire cache)
  94. * Unlock cache entries that cache the specified memory range.
  95. * Entries not already locked are unaffected.
  96. *
  97. * coherence_on
  98. * coherence_off
  99. * Turn off and on cache coherence
  100. *
  101. */
  102. /*************************** GENERIC -- ALL CACHES ***************************/
  103. /*
  104. * The following macros assume the following cache size/parameter limits
  105. * in the current Xtensa core implementation:
  106. * cache size: 1024 bytes minimum
  107. * line size: 16 - 64 bytes
  108. * way count: 1 - 4
  109. *
  110. * Minimum entries per way (ie. per associativity) = 1024 / 64 / 4 = 4
  111. * Hence the assumption that each loop can execute four cache instructions.
  112. *
  113. * Correspondingly, the offset range of instructions is assumed able to cover
  114. * four lines, ie. offsets {0,1,2,3} * line_size are assumed valid for
  115. * both hit and indexed cache instructions. Ie. these offsets are all
  116. * valid: 0, 16, 32, 48, 64, 96, 128, 192 (for line sizes 16, 32, 64).
  117. * This is true of all original cache instructions
  118. * (dhi, ihi, dhwb, dhwbi, dii, iii) which have offsets
  119. * of 0 to 1020 in multiples of 4 (ie. 8 bits shifted by 2).
  120. * This is also true of subsequent cache instructions
  121. * (dhu, ihu, diu, iiu, diwb, diwbi, dpfl, ipfl) which have offsets
  122. * of 0 to 240 in multiples of 16 (ie. 4 bits shifted by 4).
  123. *
  124. * (Maximum cache size, currently 32k, doesn't affect the following macros.
  125. * Cache ways > MMU min page size cause aliasing but that's another matter.)
  126. */
  127. /*
  128. * Macro to apply an 'indexed' cache instruction to the entire cache.
  129. *
  130. * Parameters:
  131. * cainst instruction/ that takes an address register parameter
  132. * and an offset parameter (in range 0 .. 3*linesize).
  133. * size size of cache in bytes
  134. * linesize size of cache line in bytes (always power-of-2)
  135. * assoc_or1 number of associativities (ways/sets) in cache
  136. * if all sets affected by cainst,
  137. * or 1 if only one set (or not all sets) of the cache
  138. * is affected by cainst (eg. DIWB or DIWBI [not yet ISA defined]).
  139. * aa, ab unique address registers (temporaries).
  140. * awb set to other than a0 if wb type of instruction
  141. * loopokay 1 allows use of zero-overhead loops, 0 does not
  142. * immrange range (max value) of cainst's immediate offset parameter, in bytes
  143. * (NOTE: macro assumes immrange allows power-of-2 number of lines)
  144. */
  145. .macro cache_index_all cainst, size, linesize, assoc_or1, aa, ab, loopokay, maxofs, awb=a0
  146. // Number of indices in cache (lines per way):
  147. .set .Lindices, (\size / (\linesize * \assoc_or1))
  148. // Number of indices processed per loop iteration (max 4):
  149. .set .Lperloop, .Lindices
  150. .ifgt .Lperloop - 4
  151. .set .Lperloop, 4
  152. .endif
  153. // Also limit instructions per loop if cache line size exceeds immediate range:
  154. .set .Lmaxperloop, (\maxofs / \linesize) + 1
  155. .ifgt .Lperloop - .Lmaxperloop
  156. .set .Lperloop, .Lmaxperloop
  157. .endif
  158. // Avoid addi of 128 which takes two instructions (addmi,addi):
  159. .ifeq .Lperloop*\linesize - 128
  160. .ifgt .Lperloop - 1
  161. .set .Lperloop, .Lperloop / 2
  162. .endif
  163. .endif
  164. // \size byte cache, \linesize byte lines, \assoc_or1 way(s) affected by each \cainst.
  165. // XCHAL_ERRATUM_497 - don't execute using loop, to reduce the amount of added code
  166. .ifne (\loopokay & XCHAL_HAVE_LOOPS && !XCHAL_ERRATUM_497)
  167. movi \aa, .Lindices / .Lperloop // number of loop iterations
  168. // Possible improvement: need only loop if \aa > 1 ;
  169. // however \aa == 1 is highly unlikely.
  170. movi \ab, 0 // to iterate over cache
  171. loop \aa, .Lend_cachex\@
  172. .set .Li, 0 ; .rept .Lperloop
  173. \cainst \ab, .Li*\linesize
  174. .set .Li, .Li+1 ; .endr
  175. addi \ab, \ab, .Lperloop*\linesize // move to next line
  176. .Lend_cachex\@:
  177. .else
  178. movi \aa, (\size / \assoc_or1)
  179. // Possible improvement: need only loop if \aa > 1 ;
  180. // however \aa == 1 is highly unlikely.
  181. movi \ab, 0 // to iterate over cache
  182. .ifne ((\awb !=a0) & XCHAL_ERRATUM_497) // don't use awb if set to a0
  183. movi \awb, 0
  184. .endif
  185. .Lstart_cachex\@:
  186. .set .Li, 0 ; .rept .Lperloop
  187. \cainst \ab, .Li*\linesize
  188. .set .Li, .Li+1 ; .endr
  189. .ifne ((\awb !=a0) & XCHAL_ERRATUM_497) // do memw after 8 cainst wb instructions
  190. addi \awb, \awb, .Lperloop
  191. blti \awb, 8, .Lstart_memw\@
  192. memw
  193. movi \awb, 0
  194. .Lstart_memw\@:
  195. .endif
  196. addi \ab, \ab, .Lperloop*\linesize // move to next line
  197. bltu \ab, \aa, .Lstart_cachex\@
  198. .endif
  199. .endm
  200. /*
  201. * Macro to apply a 'hit' cache instruction to a memory region,
  202. * ie. to any cache entries that cache a specified portion (region) of memory.
  203. * Takes care of the unaligned cases, ie. may apply to one
  204. * more cache line than $asize / lineSize if $aaddr is not aligned.
  205. *
  206. *
  207. * Parameters are:
  208. * cainst instruction/macro that takes an address register parameter
  209. * and an offset parameter (currently always zero)
  210. * and generates a cache instruction (eg. "dhi", "dhwb", "ihi", etc.)
  211. * linesize_log2 log2(size of cache line in bytes)
  212. * addr register containing start address of region (clobbered)
  213. * asize register containing size of the region in bytes (clobbered)
  214. * askew unique register used as temporary
  215. * awb unique register used as temporary for erratum 497.
  216. *
  217. * Note: A possible optimization to this macro is to apply the operation
  218. * to the entire cache if the region exceeds the size of the cache
  219. * by some empirically determined amount or factor. Some experimentation
  220. * is required to determine the appropriate factors, which also need
  221. * to be tunable if required.
  222. */
  223. .macro cache_hit_region cainst, linesize_log2, addr, asize, askew, awb=a0
  224. // Make \asize the number of iterations:
  225. extui \askew, \addr, 0, \linesize_log2 // get unalignment amount of \addr
  226. add \asize, \asize, \askew // ... and add it to \asize
  227. addi \asize, \asize, (1 << \linesize_log2) - 1 // round up!
  228. srli \asize, \asize, \linesize_log2
  229. // Iterate over region:
  230. .ifne ((\awb !=a0) & XCHAL_ERRATUM_497) // don't use awb if set to a0
  231. movi \awb, 0
  232. .endif
  233. floopnez \asize, cacheh\@
  234. \cainst \addr, 0
  235. .ifne ((\awb !=a0) & XCHAL_ERRATUM_497) // do memw after 8 cainst wb instructions
  236. addi \awb, \awb, 1
  237. blti \awb, 8, .Lstart_memw\@
  238. memw
  239. movi \awb, 0
  240. .Lstart_memw\@:
  241. .endif
  242. addi \addr, \addr, (1 << \linesize_log2) // move to next line
  243. floopend \asize, cacheh\@
  244. .endm
  245. /*************************** INSTRUCTION CACHE ***************************/
  246. /*
  247. * Reset/initialize the instruction cache by simply invalidating it:
  248. * (need to unlock first also, if cache locking implemented):
  249. *
  250. * Parameters:
  251. * aa, ab unique address registers (temporaries)
  252. */
  253. .macro icache_reset aa, ab, loopokay=0
  254. icache_unlock_all \aa, \ab, \loopokay
  255. icache_invalidate_all \aa, \ab, \loopokay
  256. .endm
  257. /*
  258. * Synchronize after an instruction cache operation,
  259. * to be sure everything is in sync with memory as to be
  260. * expected following any previous instruction cache control operations.
  261. *
  262. * Even if a config doesn't have caches, an isync is still needed
  263. * when instructions in any memory are modified, whether by a loader
  264. * or self-modifying code. Therefore, this macro always produces
  265. * an isync, whether or not an icache is present.
  266. *
  267. * Parameters are:
  268. * ar an address register (temporary) (currently unused, but may be used in future)
  269. */
  270. .macro icache_sync ar
  271. isync
  272. .endm
  273. /*
  274. * Invalidate a single line of the instruction cache.
  275. * Parameters are:
  276. * ar address register that contains (virtual) address to invalidate
  277. * (may get clobbered in a future implementation, but not currently)
  278. * offset (optional) offset to add to \ar to compute effective address to invalidate
  279. * (note: some number of lsbits are ignored)
  280. */
  281. .macro icache_invalidate_line ar, offset
  282. #if XCHAL_ICACHE_SIZE > 0
  283. ihi \ar, \offset // invalidate icache line
  284. icache_sync \ar
  285. #endif
  286. .endm
  287. /*
  288. * Invalidate instruction cache entries that cache a specified portion of memory.
  289. * Parameters are:
  290. * astart start address (register gets clobbered)
  291. * asize size of the region in bytes (register gets clobbered)
  292. * ac unique register used as temporary
  293. */
  294. .macro icache_invalidate_region astart, asize, ac
  295. #if XCHAL_ICACHE_SIZE > 0
  296. // Instruction cache region invalidation:
  297. cache_hit_region ihi, XCHAL_ICACHE_LINEWIDTH, \astart, \asize, \ac
  298. icache_sync \ac
  299. // End of instruction cache region invalidation
  300. #endif
  301. .endm
  302. /*
  303. * Invalidate entire instruction cache.
  304. *
  305. * Parameters:
  306. * aa, ab unique address registers (temporaries)
  307. */
  308. .macro icache_invalidate_all aa, ab, loopokay=1
  309. #if XCHAL_ICACHE_SIZE > 0
  310. // Instruction cache invalidation:
  311. cache_index_all iii, XCHAL_ICACHE_SIZE, XCHAL_ICACHE_LINESIZE, XCHAL_ICACHE_WAYS, \aa, \ab, \loopokay, 1020
  312. icache_sync \aa
  313. // End of instruction cache invalidation
  314. #endif
  315. .endm
  316. /*
  317. * Lock (prefetch & lock) a single line of the instruction cache.
  318. *
  319. * Parameters are:
  320. * ar address register that contains (virtual) address to lock
  321. * (may get clobbered in a future implementation, but not currently)
  322. * offset offset to add to \ar to compute effective address to lock
  323. * (note: some number of lsbits are ignored)
  324. */
  325. .macro icache_lock_line ar, offset
  326. #if XCHAL_ICACHE_SIZE > 0 && XCHAL_ICACHE_LINE_LOCKABLE
  327. ipfl \ar, \offset /* prefetch and lock icache line */
  328. icache_sync \ar
  329. #endif
  330. .endm
  331. /*
  332. * Lock (prefetch & lock) a specified portion of memory into the instruction cache.
  333. * Parameters are:
  334. * astart start address (register gets clobbered)
  335. * asize size of the region in bytes (register gets clobbered)
  336. * ac unique register used as temporary
  337. */
  338. .macro icache_lock_region astart, asize, ac
  339. #if XCHAL_ICACHE_SIZE > 0 && XCHAL_ICACHE_LINE_LOCKABLE
  340. // Instruction cache region lock:
  341. cache_hit_region ipfl, XCHAL_ICACHE_LINEWIDTH, \astart, \asize, \ac
  342. icache_sync \ac
  343. // End of instruction cache region lock
  344. #endif
  345. .endm
  346. /*
  347. * Unlock a single line of the instruction cache.
  348. *
  349. * Parameters are:
  350. * ar address register that contains (virtual) address to unlock
  351. * (may get clobbered in a future implementation, but not currently)
  352. * offset offset to add to \ar to compute effective address to unlock
  353. * (note: some number of lsbits are ignored)
  354. */
  355. .macro icache_unlock_line ar, offset
  356. #if XCHAL_ICACHE_SIZE > 0 && XCHAL_ICACHE_LINE_LOCKABLE
  357. ihu \ar, \offset /* unlock icache line */
  358. icache_sync \ar
  359. #endif
  360. .endm
  361. /*
  362. * Unlock a specified portion of memory from the instruction cache.
  363. * Parameters are:
  364. * astart start address (register gets clobbered)
  365. * asize size of the region in bytes (register gets clobbered)
  366. * ac unique register used as temporary
  367. */
  368. .macro icache_unlock_region astart, asize, ac
  369. #if XCHAL_ICACHE_SIZE > 0 && XCHAL_ICACHE_LINE_LOCKABLE
  370. // Instruction cache region unlock:
  371. cache_hit_region ihu, XCHAL_ICACHE_LINEWIDTH, \astart, \asize, \ac
  372. icache_sync \ac
  373. // End of instruction cache region unlock
  374. #endif
  375. .endm
  376. /*
  377. * Unlock entire instruction cache.
  378. *
  379. * Parameters:
  380. * aa, ab unique address registers (temporaries)
  381. */
  382. .macro icache_unlock_all aa, ab, loopokay=1
  383. #if XCHAL_ICACHE_SIZE > 0 && XCHAL_ICACHE_LINE_LOCKABLE
  384. // Instruction cache unlock:
  385. cache_index_all iiu, XCHAL_ICACHE_SIZE, XCHAL_ICACHE_LINESIZE, 1, \aa, \ab, \loopokay, 240
  386. icache_sync \aa
  387. // End of instruction cache unlock
  388. #endif
  389. .endm
  390. /*************************** DATA CACHE ***************************/
  391. /*
  392. * Reset/initialize the data cache by simply invalidating it
  393. * (need to unlock first also, if cache locking implemented):
  394. *
  395. * Parameters:
  396. * aa, ab unique address registers (temporaries)
  397. */
  398. .macro dcache_reset aa, ab, loopokay=0
  399. dcache_unlock_all \aa, \ab, \loopokay
  400. dcache_invalidate_all \aa, \ab, \loopokay
  401. .endm
  402. /*
  403. * Synchronize after a data cache operation,
  404. * to be sure everything is in sync with memory as to be
  405. * expected following any previous data cache control operations.
  406. *
  407. * Parameters are:
  408. * ar an address register (temporary) (currently unused, but may be used in future)
  409. */
  410. .macro dcache_sync ar, wbtype=0
  411. #if XCHAL_DCACHE_SIZE > 0
  412. // No synchronization is needed.
  413. // (memw may be desired e.g. after writeback operation to help ensure subsequent
  414. // external accesses are seen to follow that writeback, however that's outside
  415. // the scope of this macro)
  416. //dsync
  417. .ifne (\wbtype & XCHAL_ERRATUM_497)
  418. memw
  419. .endif
  420. #endif
  421. .endm
  422. /*
  423. * Turn on cache coherence.
  424. *
  425. * WARNING: for RE-201x.x and later hardware, any interrupt that tries
  426. * to change MEMCTL will see its changes dropped if the interrupt comes
  427. * in the middle of this routine. If this might be an issue, call this
  428. * routine with interrupts disabled.
  429. *
  430. * Parameters are:
  431. * ar,at two scratch address registers (both clobbered)
  432. */
  433. .macro cache_coherence_on ar at
  434. #if XCHAL_DCACHE_IS_COHERENT
  435. # if XCHAL_HW_MIN_VERSION >= XTENSA_HWVERSION_RE_2012_0
  436. /* Have MEMCTL. Enable snoop responses. */
  437. rsr.memctl \ar
  438. movi \at, MEMCTL_SNOOP_EN
  439. or \ar, \ar, \at
  440. wsr.memctl \ar
  441. # elif XCHAL_HAVE_EXTERN_REGS && XCHAL_HAVE_MX
  442. /* Opt into coherence for MX (for backward compatibility / testing). */
  443. movi \ar, 1
  444. movi \at, XER_CCON
  445. wer \ar, \at
  446. extw
  447. # endif
  448. #endif
  449. .endm
  450. /*
  451. * Turn off cache coherence.
  452. *
  453. * NOTE: this is generally preceded by emptying the cache;
  454. * see xthal_cache_coherence_optout() in hal/coherence.c for details.
  455. *
  456. * WARNING: for RE-201x.x and later hardware, any interrupt that tries
  457. * to change MEMCTL will see its changes dropped if the interrupt comes
  458. * in the middle of this routine. If this might be an issue, call this
  459. * routine with interrupts disabled.
  460. *
  461. * Parameters are:
  462. * ar,at two scratch address registers (both clobbered)
  463. */
  464. .macro cache_coherence_off ar at
  465. #if XCHAL_DCACHE_IS_COHERENT
  466. # if XCHAL_HW_MIN_VERSION >= XTENSA_HWVERSION_RE_2012_0
  467. /* Have MEMCTL. Disable snoop responses. */
  468. rsr.memctl \ar
  469. movi \at, ~MEMCTL_SNOOP_EN
  470. and \ar, \ar, \at
  471. wsr.memctl \ar
  472. # elif XCHAL_HAVE_EXTERN_REGS && XCHAL_HAVE_MX
  473. /* Opt out of coherence, for MX (for backward compatibility / testing). */
  474. extw
  475. movi \at, 0
  476. movi \ar, XER_CCON
  477. wer \at, \ar
  478. extw
  479. # endif
  480. #endif
  481. .endm
  482. /*
  483. * Synchronize after a data store operation,
  484. * to be sure the stored data is completely off the processor
  485. * (and assuming there is no buffering outside the processor,
  486. * that the data is in memory). This may be required to
  487. * ensure that the processor's write buffers are emptied.
  488. * A MEMW followed by a read guarantees this, by definition.
  489. * We also try to make sure the read itself completes.
  490. *
  491. * Parameters are:
  492. * ar an address register (temporary)
  493. */
  494. .macro write_sync ar
  495. memw // ensure previous memory accesses are complete prior to subsequent memory accesses
  496. l32i \ar, sp, 0 // completing this read ensures any previous write has completed, because of MEMW
  497. //slot
  498. add \ar, \ar, \ar // use the result of the read to help ensure the read completes (in future architectures)
  499. .endm
  500. /*
  501. * Invalidate a single line of the data cache.
  502. * Parameters are:
  503. * ar address register that contains (virtual) address to invalidate
  504. * (may get clobbered in a future implementation, but not currently)
  505. * offset (optional) offset to add to \ar to compute effective address to invalidate
  506. * (note: some number of lsbits are ignored)
  507. */
  508. .macro dcache_invalidate_line ar, offset
  509. #if XCHAL_DCACHE_SIZE > 0
  510. dhi \ar, \offset
  511. dcache_sync \ar
  512. #endif
  513. .endm
  514. /*
  515. * Invalidate data cache entries that cache a specified portion of memory.
  516. * Parameters are:
  517. * astart start address (register gets clobbered)
  518. * asize size of the region in bytes (register gets clobbered)
  519. * ac unique register used as temporary
  520. */
  521. .macro dcache_invalidate_region astart, asize, ac
  522. #if XCHAL_DCACHE_SIZE > 0
  523. // Data cache region invalidation:
  524. cache_hit_region dhi, XCHAL_DCACHE_LINEWIDTH, \astart, \asize, \ac
  525. dcache_sync \ac
  526. // End of data cache region invalidation
  527. #endif
  528. .endm
  529. /*
  530. * Invalidate entire data cache.
  531. *
  532. * Parameters:
  533. * aa, ab unique address registers (temporaries)
  534. */
  535. .macro dcache_invalidate_all aa, ab, loopokay=1
  536. #if XCHAL_DCACHE_SIZE > 0
  537. // Data cache invalidation:
  538. cache_index_all dii, XCHAL_DCACHE_SIZE, XCHAL_DCACHE_LINESIZE, XCHAL_DCACHE_WAYS, \aa, \ab, \loopokay, 1020
  539. dcache_sync \aa
  540. // End of data cache invalidation
  541. #endif
  542. .endm
  543. /*
  544. * Writeback a single line of the data cache.
  545. * Parameters are:
  546. * ar address register that contains (virtual) address to writeback
  547. * (may get clobbered in a future implementation, but not currently)
  548. * offset offset to add to \ar to compute effective address to writeback
  549. * (note: some number of lsbits are ignored)
  550. */
  551. .macro dcache_writeback_line ar, offset
  552. #if XCHAL_DCACHE_SIZE > 0 && XCHAL_DCACHE_IS_WRITEBACK
  553. dhwb \ar, \offset
  554. dcache_sync \ar, wbtype=1
  555. #endif
  556. .endm
  557. /*
  558. * Writeback dirty data cache entries that cache a specified portion of memory.
  559. * Parameters are:
  560. * astart start address (register gets clobbered)
  561. * asize size of the region in bytes (register gets clobbered)
  562. * ac unique register used as temporary
  563. */
  564. .macro dcache_writeback_region astart, asize, ac, awb
  565. #if XCHAL_DCACHE_SIZE > 0 && XCHAL_DCACHE_IS_WRITEBACK
  566. // Data cache region writeback:
  567. cache_hit_region dhwb, XCHAL_DCACHE_LINEWIDTH, \astart, \asize, \ac, \awb
  568. dcache_sync \ac, wbtype=1
  569. // End of data cache region writeback
  570. #endif
  571. .endm
  572. /*
  573. * Writeback entire data cache.
  574. * Parameters:
  575. * aa, ab unique address registers (temporaries)
  576. */
  577. .macro dcache_writeback_all aa, ab, awb, loopokay=1
  578. #if XCHAL_DCACHE_SIZE > 0 && XCHAL_DCACHE_IS_WRITEBACK
  579. // Data cache writeback:
  580. cache_index_all diwb, XCHAL_DCACHE_SIZE, XCHAL_DCACHE_LINESIZE, 1, \aa, \ab, \loopokay, 240, \awb,
  581. dcache_sync \aa, wbtype=1
  582. // End of data cache writeback
  583. #endif
  584. .endm
  585. /*
  586. * Writeback and invalidate a single line of the data cache.
  587. * Parameters are:
  588. * ar address register that contains (virtual) address to writeback and invalidate
  589. * (may get clobbered in a future implementation, but not currently)
  590. * offset offset to add to \ar to compute effective address to writeback and invalidate
  591. * (note: some number of lsbits are ignored)
  592. */
  593. .macro dcache_writeback_inv_line ar, offset
  594. #if XCHAL_DCACHE_SIZE > 0
  595. dhwbi \ar, \offset /* writeback and invalidate dcache line */
  596. dcache_sync \ar, wbtype=1
  597. #endif
  598. .endm
  599. /*
  600. * Writeback and invalidate data cache entries that cache a specified portion of memory.
  601. * Parameters are:
  602. * astart start address (register gets clobbered)
  603. * asize size of the region in bytes (register gets clobbered)
  604. * ac unique register used as temporary
  605. */
  606. .macro dcache_writeback_inv_region astart, asize, ac, awb
  607. #if XCHAL_DCACHE_SIZE > 0
  608. // Data cache region writeback and invalidate:
  609. cache_hit_region dhwbi, XCHAL_DCACHE_LINEWIDTH, \astart, \asize, \ac, \awb
  610. dcache_sync \ac, wbtype=1
  611. // End of data cache region writeback and invalidate
  612. #endif
  613. .endm
  614. /*
  615. * Writeback and invalidate entire data cache.
  616. * Parameters:
  617. * aa, ab unique address registers (temporaries)
  618. */
  619. .macro dcache_writeback_inv_all aa, ab, awb, loopokay=1
  620. #if XCHAL_DCACHE_SIZE > 0
  621. // Data cache writeback and invalidate:
  622. #if XCHAL_DCACHE_IS_WRITEBACK
  623. cache_index_all diwbi, XCHAL_DCACHE_SIZE, XCHAL_DCACHE_LINESIZE, 1, \aa, \ab, \loopokay, 240, \awb
  624. dcache_sync \aa, wbtype=1
  625. #else /*writeback*/
  626. // Data cache does not support writeback, so just invalidate: */
  627. dcache_invalidate_all \aa, \ab, \loopokay
  628. #endif /*writeback*/
  629. // End of data cache writeback and invalidate
  630. #endif
  631. .endm
  632. /*
  633. * Lock (prefetch & lock) a single line of the data cache.
  634. *
  635. * Parameters are:
  636. * ar address register that contains (virtual) address to lock
  637. * (may get clobbered in a future implementation, but not currently)
  638. * offset offset to add to \ar to compute effective address to lock
  639. * (note: some number of lsbits are ignored)
  640. */
  641. .macro dcache_lock_line ar, offset
  642. #if XCHAL_DCACHE_SIZE > 0 && XCHAL_DCACHE_LINE_LOCKABLE
  643. dpfl \ar, \offset /* prefetch and lock dcache line */
  644. dcache_sync \ar
  645. #endif
  646. .endm
  647. /*
  648. * Lock (prefetch & lock) a specified portion of memory into the data cache.
  649. * Parameters are:
  650. * astart start address (register gets clobbered)
  651. * asize size of the region in bytes (register gets clobbered)
  652. * ac unique register used as temporary
  653. */
  654. .macro dcache_lock_region astart, asize, ac
  655. #if XCHAL_DCACHE_SIZE > 0 && XCHAL_DCACHE_LINE_LOCKABLE
  656. // Data cache region lock:
  657. cache_hit_region dpfl, XCHAL_DCACHE_LINEWIDTH, \astart, \asize, \ac
  658. dcache_sync \ac
  659. // End of data cache region lock
  660. #endif
  661. .endm
  662. /*
  663. * Unlock a single line of the data cache.
  664. *
  665. * Parameters are:
  666. * ar address register that contains (virtual) address to unlock
  667. * (may get clobbered in a future implementation, but not currently)
  668. * offset offset to add to \ar to compute effective address to unlock
  669. * (note: some number of lsbits are ignored)
  670. */
  671. .macro dcache_unlock_line ar, offset
  672. #if XCHAL_DCACHE_SIZE > 0 && XCHAL_DCACHE_LINE_LOCKABLE
  673. dhu \ar, \offset /* unlock dcache line */
  674. dcache_sync \ar
  675. #endif
  676. .endm
  677. /*
  678. * Unlock a specified portion of memory from the data cache.
  679. * Parameters are:
  680. * astart start address (register gets clobbered)
  681. * asize size of the region in bytes (register gets clobbered)
  682. * ac unique register used as temporary
  683. */
  684. .macro dcache_unlock_region astart, asize, ac
  685. #if XCHAL_DCACHE_SIZE > 0 && XCHAL_DCACHE_LINE_LOCKABLE
  686. // Data cache region unlock:
  687. cache_hit_region dhu, XCHAL_DCACHE_LINEWIDTH, \astart, \asize, \ac
  688. dcache_sync \ac
  689. // End of data cache region unlock
  690. #endif
  691. .endm
  692. /*
  693. * Unlock entire data cache.
  694. *
  695. * Parameters:
  696. * aa, ab unique address registers (temporaries)
  697. */
  698. .macro dcache_unlock_all aa, ab, loopokay=1
  699. #if XCHAL_DCACHE_SIZE > 0 && XCHAL_DCACHE_LINE_LOCKABLE
  700. // Data cache unlock:
  701. cache_index_all diu, XCHAL_DCACHE_SIZE, XCHAL_DCACHE_LINESIZE, 1, \aa, \ab, \loopokay, 240
  702. dcache_sync \aa
  703. // End of data cache unlock
  704. #endif
  705. .endm
  706. /*
  707. * Get the number of enabled icache ways. Note that this may
  708. * be different from the value read from the MEMCTL register.
  709. *
  710. * Parameters:
  711. * aa address register where value is returned
  712. */
  713. .macro icache_get_ways aa
  714. #if XCHAL_ICACHE_SIZE > 0
  715. #if XCHAL_HAVE_ICACHE_DYN_WAYS
  716. // Read from MEMCTL and shift/mask
  717. rsr \aa, MEMCTL
  718. extui \aa, \aa, MEMCTL_ICWU_SHIFT, MEMCTL_ICWU_BITS
  719. blti \aa, XCHAL_ICACHE_WAYS, .Licgw
  720. movi \aa, XCHAL_ICACHE_WAYS
  721. .Licgw:
  722. #else
  723. // All ways are always enabled
  724. movi \aa, XCHAL_ICACHE_WAYS
  725. #endif
  726. #else
  727. // No icache
  728. movi \aa, 0
  729. #endif
  730. .endm
  731. /*
  732. * Set the number of enabled icache ways.
  733. *
  734. * Parameters:
  735. * aa address register specifying number of ways (trashed)
  736. * ab,ac address register for scratch use (trashed)
  737. */
  738. .macro icache_set_ways aa, ab, ac
  739. #if XCHAL_ICACHE_SIZE > 0
  740. #if XCHAL_HAVE_ICACHE_DYN_WAYS
  741. movi \ac, MEMCTL_ICWU_CLR_MASK // set up to clear bits 18-22
  742. rsr \ab, MEMCTL
  743. and \ab, \ab, \ac
  744. movi \ac, MEMCTL_INV_EN // set bit 23
  745. slli \aa, \aa, MEMCTL_ICWU_SHIFT // move to right spot
  746. or \ab, \ab, \aa
  747. or \ab, \ab, \ac
  748. wsr \ab, MEMCTL
  749. isync
  750. #else
  751. // All ways are always enabled
  752. #endif
  753. #else
  754. // No icache
  755. #endif
  756. .endm
  757. /*
  758. * Get the number of enabled dcache ways. Note that this may
  759. * be different from the value read from the MEMCTL register.
  760. *
  761. * Parameters:
  762. * aa address register where value is returned
  763. */
  764. .macro dcache_get_ways aa
  765. #if XCHAL_DCACHE_SIZE > 0
  766. #if XCHAL_HAVE_DCACHE_DYN_WAYS
  767. // Read from MEMCTL and shift/mask
  768. rsr \aa, MEMCTL
  769. extui \aa, \aa, MEMCTL_DCWU_SHIFT, MEMCTL_DCWU_BITS
  770. blti \aa, XCHAL_DCACHE_WAYS, .Ldcgw
  771. movi \aa, XCHAL_DCACHE_WAYS
  772. .Ldcgw:
  773. #else
  774. // All ways are always enabled
  775. movi \aa, XCHAL_DCACHE_WAYS
  776. #endif
  777. #else
  778. // No dcache
  779. movi \aa, 0
  780. #endif
  781. .endm
  782. /*
  783. * Set the number of enabled dcache ways.
  784. *
  785. * Parameters:
  786. * aa address register specifying number of ways (trashed)
  787. * ab,ac address register for scratch use (trashed)
  788. */
  789. .macro dcache_set_ways aa, ab, ac
  790. #if (XCHAL_DCACHE_SIZE > 0) && XCHAL_HAVE_DCACHE_DYN_WAYS
  791. movi \ac, MEMCTL_DCWA_CLR_MASK // set up to clear bits 13-17
  792. rsr \ab, MEMCTL
  793. and \ab, \ab, \ac // clear ways allocatable
  794. slli \ac, \aa, MEMCTL_DCWA_SHIFT
  795. or \ab, \ab, \ac // set ways allocatable
  796. wsr \ab, MEMCTL
  797. #if XCHAL_DCACHE_IS_WRITEBACK
  798. // Check if the way count is increasing or decreasing
  799. extui \ac, \ab, MEMCTL_DCWU_SHIFT, MEMCTL_DCWU_BITS // bits 8-12 - ways in use
  800. bge \aa, \ac, .Ldsw3 // equal or increasing
  801. slli \ab, \aa, XCHAL_DCACHE_LINEWIDTH + XCHAL_DCACHE_SETWIDTH // start way number
  802. slli \ac, \ac, XCHAL_DCACHE_LINEWIDTH + XCHAL_DCACHE_SETWIDTH // end way number
  803. .Ldsw1:
  804. diwbui.p \ab // auto-increments ab
  805. bge \ab, \ac, .Ldsw2
  806. beqz \ab, .Ldsw2
  807. j .Ldsw1
  808. .Ldsw2:
  809. rsr \ab, MEMCTL
  810. #endif
  811. .Ldsw3:
  812. // No dirty data to write back, just set the new number of ways
  813. movi \ac, MEMCTL_DCWU_CLR_MASK // set up to clear bits 8-12
  814. and \ab, \ab, \ac // clear ways in use
  815. movi \ac, MEMCTL_INV_EN
  816. or \ab, \ab, \ac // set bit 23
  817. slli \aa, \aa, MEMCTL_DCWU_SHIFT
  818. or \ab, \ab, \aa // set ways in use
  819. wsr \ab, MEMCTL
  820. #else
  821. // No dcache or no way disable support
  822. #endif
  823. .endm
  824. #endif /*XTENSA_CACHEASM_H*/