cacheALib.s
上传用户:yuanda199
上传日期:2022-06-26
资源大小:412k
文件大小:13k
源码类别:

VxWorks

开发平台:

C/C++

  1. /*
  2.     Copyright 2001, Broadcom Corporation
  3.     All Rights Reserved.
  4.     
  5.     This is UNPUBLISHED PROPRIETARY SOURCE CODE of Broadcom Corporation;
  6.     the contents of this file may not be disclosed to third parties, copied or
  7.     duplicated in any form, in whole or in part, without the prior written
  8.     permission of Broadcom Corporation.
  9. */
  10. /*
  11.  * $Id: cacheALib.s,v 1.1 Broadcom SDK $
  12.  */
  13. #define _ASMLANGUAGE
  14. #include <vxWorks.h>
  15. #include "asm.h"
  16. #include "arch/mips/ivMips.h"
  17. #include "arch/mips/asmMips.h"
  18. #include "arch/mips/archMips.h"
  19. #include "arch/mips/esfMips.h"
  20. #define WAR_ADDR 0xb8006f9c
  21. #define CACHE_OP( code, type ) ( ((code) << 2) | (type) )
  22. #define ICACHE_INDEX_INVALIDATE CACHE_OP(0x0, 0)
  23. #define ICACHE_INDEX_LOAD_TAG CACHE_OP(0x1, 0)
  24. #define ICACHE_INDEX_STORE_TAG CACHE_OP(0x2, 0)
  25. #define DCACHE_INDEX_WRITEBACK_INVALIDATE CACHE_OP(0x0, 1)
  26. #define DCACHE_INDEX_LOAD_TAG CACHE_OP(0x1, 1)
  27. #define DCACHE_INDEX_STORE_TAG CACHE_OP(0x2, 1)
  28. #define ICACHE_ADDR_HIT_INVALIDATE CACHE_OP(0x4, 0)
  29. #define ICACHE_ADDR_FILL CACHE_OP(0x5, 0)
  30. #define ICACHE_ADDR_FETCH_LOCK CACHE_OP(0x7, 0)
  31. #define DCACHE_ADDR_HIT_INVALIDATE CACHE_OP(0x4, 1)
  32. #define DCACHE_ADDR_HIT_WRITEBACK_INVALIDATE CACHE_OP(0x5, 1)
  33. #define DCACHE_ADDR_HIT_WRITEBACK CACHE_OP(0x6, 1)
  34. #define DCACHE_ADDR_FETCH_LOCK CACHE_OP(0x7, 1)
  35. #define CACHELINE_SIZE                  16
  36. #define INSTRUCTION_CACHE_SIZE          (8*1024)
  37. #define DATA_CACHE_SIZE                 (4*1024)
  38. #define KSEG0BASE                       0x80000000
  39. #define KSEG1BASE                 0xA0000000
  40. #define C0_TAGLO                        $28
  41. #define C0_TAGHI                        $29
  42. #define ALIGN_4W         0xf
  43. .text
  44.         .globl  FlushAll_Dcache
  45. .globl  FlushAll_Icache
  46.         .globl  Flush_Dcache
  47.         .globl  Invalidate_Dcache
  48.         .globl  Clear_Dcache
  49. .globl  Invalidate_Icache
  50.         .globl  readtag
  51.         .globl  loadtag
  52.         .globl  reset_caches
  53.         
  54. /************************************************************************/
  55. /* FlushAll_Dcache: invaldates the entire data cache          */
  56. /* */
  57. /* Syntax: void Sys_Flush_Dcache(void) */
  58. /*   Note: */
  59. /************************************************************************/
  60.     .ent    FlushAll_Dcache 
  61. FlushAll_Dcache:
  62.      
  63.         .set    noreorder
  64.     
  65.         mfc0    t7, C0_SR           # save SR 
  66.         nop
  67.         and     t0, t7, ~SR_IE      # dissable interrupts 
  68.         mtc0    t0, C0_SR
  69.         nop
  70.         
  71.         li      t0, DATA_CACHE_SIZE
  72.         li      t1, CACHELINE_SIZE 
  73. mtc0    zero, C0_TAGLO
  74. mtc0    zero, C0_TAGHI       /* TagHi is not really used */
  75. /* Calc an address that will correspond to the first cache line */
  76. li t2, KSEG0BASE
  77. /* Calc an address that will correspond to the last cache line  */
  78. addu t3, t2, t0
  79. subu    t3, t1
  80. li t0, WAR_ADDR
  81. /* Loop through all lines, invalidating each of them */
  82. 1:
  83. lw t4, 0(t0)
  84. .set mips3
  85. cache DCACHE_INDEX_WRITEBACK_INVALIDATE, 0(t2) /* clear tag */
  86. .set mips0
  87. bne t2, t3, 1b
  88. addu t2, t1
  89.                 
  90.         mtc0    t7, C0_SR           # restore SR
  91.         nop
  92. jr ra
  93. nop
  94.                                                  
  95.         .set    reorder
  96.         .end    FlushAll_Dcache
  97. /************************************************************************/
  98. /************************************************************************/
  99. /************************************************************************/
  100. /************************************************************************/
  101. /* FlushAll_Icache: invaldates the entire instruction  cache               */
  102. /* */
  103. /* Syntax: void Flush_Icache(void)         */
  104. /*   Note: */
  105. /************************************************************************/
  106. .ent FlushAll_Icache
  107. FlushAll_Icache:
  108.         .set    noreorder
  109.         
  110.         mfc0    t7, C0_SR           # save SR 
  111.         nop
  112.         and     t0, t7, ~SR_IE      # dissable interrupts 
  113.         mtc0    t0, C0_SR
  114.         nop
  115.         
  116.         li      t0, INSTRUCTION_CACHE_SIZE
  117.         li      t1, CACHELINE_SIZE 
  118. mtc0    zero, C0_TAGLO 
  119. mtc0    zero, C0_TAGHI      /* TagHi is not really used */
  120. /* Calc an address that will correspond to the first cache line */
  121. li t2, KSEG0BASE
  122. /* Calc an address that will correspond to the last cache line  */
  123. addu t3, t2, t0
  124. subu    t3, t1
  125. /* Loop through all lines, invalidating each of them */
  126. 1:
  127. .set mips3
  128. cache ICACHE_INDEX_INVALIDATE, 0(t2) /* clear tag */
  129. .set mips0
  130. bne t2, t3, 1b
  131. addu t2, t1
  132.         
  133.         mtc0    t7, C0_SR           # restore SR
  134.         nop
  135.         
  136.         j       ra
  137.         nop
  138.                 
  139.         .end FlushAll_Icache
  140.         .set reorder
  141.         
  142. /************************************************************************/
  143. /************************************************************************/
  144. /************************************************************************/
  145. /************************************************************************/
  146. /* Invalidate_Icache: Invaldates a portion of the Instruction Cache     */
  147. /*         */
  148. /* Syntax: void Invalidate_Icache(ulong base_addr, ulong bcount    */
  149. /*   Note: */
  150. /************************************************************************/
  151. .ent Invalidate_Icache
  152. Invalidate_Icache:
  153.           
  154.                 .set noreorder
  155. mfc0 t7, C0_SR # save SR
  156. and t0, t7, ~SR_IE # disable interrupts
  157. mtc0 t0, C0_SR
  158. nop
  159. move t5, a0
  160. li t1, ~ALIGN_4W
  161. and  t5, t1 # align start of cache 16 bytes (line)
  162.         .set  reorder
  163. li t0, ~0xf0000000 # make sure that t5 is in Kseg0
  164. and t5, t0
  165. li t0, K0BASE
  166. or t5, t0
  167. move t4, a1
  168. 1:
  169. addu t4, a0 # arg0(startaddr)+min(cachesize,arg1)
  170. li t0, ~0xf0000000 # make sure that t4 is in Kseg0
  171. and t4, t0
  172. li t0, K0BASE
  173. or t4, t0
  174. la t0, 1f         # switch to Kseg1
  175. li t1, K1BASE
  176. or t0, t1
  177. j t0
  178. nop
  179. 1:
  180. move t0, t5 # move loop variable to t0
  181. 2:      
  182.         .set    mips3        
  183. cache ICACHE_ADDR_HIT_INVALIDATE, 0x0000(t0)             
  184.         .set    mips0
  185. addu t0, t0, 16 # Add cacheline length
  186. bltu t0, t4, 2b # while index 
  187. nop
  188. # restore status register
  189.         .set noreorder
  190. mtc0 t7, C0_SR # restore SR
  191. nop
  192. j ra
  193. nop
  194. .end Invalidate_Icache
  195.         .set reorder
  196.         
  197. /************************************************************************/
  198. /************************************************************************/
  199. /************************************************************************/
  200.         
  201. .ent Clear_Dcache
  202. Clear_Dcache:  
  203. .set noreorder
  204.         
  205. mfc0 t7, C0_SR # save SR
  206.         nop
  207.         
  208.         and t0, t7, ~SR_IE # disable interrupts
  209. mtc0 t0, C0_SR
  210.         nop
  211.         .set  reorder
  212. move t5, a0
  213. li      t1, ~ALIGN_4W
  214. and  t5, t1 # align start of region to 16 bytes
  215. li t0, ~0xf0000000 # make sure that t5 is in Kseg0
  216. and t5, t0
  217. li t0, K0BASE
  218. or t5, t0
  219. move t4, a1
  220. 1:
  221. addu t4, a0 # arg0(startaddr)+min(cachesize, arg1)
  222. li t0, ~0xf0000000 # make sure that t4 is in Kseg0
  223. and t4, t0
  224. li t0, K0BASE
  225. or t4, t0
  226.  
  227. move t0, t5
  228.         
  229.         li      t2, WAR_ADDR
  230. 2:      # Clear out the Data Cache!!
  231.         .set    mips3
  232.         lw      t1, 0(t2)
  233. cache DCACHE_ADDR_HIT_WRITEBACK_INVALIDATE, 0x0000(t0) 
  234.         .set    mips0        
  235.         addu t0, t0, 16 # Add cacheline length
  236. bltu t0, t4, 2b # while index < endaddr
  237. nop
  238.           
  239. # restore status register
  240. .set noreorder
  241. mtc0 t7, C0_SR # restore SR
  242. nop
  243. j ra
  244. nop
  245. .set reorder
  246. .end Clear_Dcache
  247. /************************************************************************/
  248. /************************************************************************/
  249. /************************************************************************/
  250.         
  251. /************************************************************************/
  252. /************************************************************************/
  253. /************************************************************************/
  254.         
  255. /************************************************************************/
  256. /* Invalidate_Dcache: Invaldates a portion of the Data Cache             */
  257. /* */
  258. /* Syntax: void Invalidate_Dcache(ulong base_addr, ulong bcount) */
  259. /*   Note: */
  260. /************************************************************************/
  261. .ent Invalidate_Dcache
  262. Invalidate_Dcache:  
  263. .set noreorder
  264.         
  265. mfc0 t7, C0_SR # save SR
  266.         nop
  267.         
  268.         and t0, t7, ~SR_IE # disable interrupts
  269. mtc0 t0, C0_SR
  270.         nop
  271.         .set  reorder
  272. move t5, a0
  273. li      t1, ~ALIGN_4W
  274. and  t5, t1 # align start of region to 16 bytes
  275. li t0, ~0xf0000000 # make sure that t5 is in Kseg0
  276. and t5, t0
  277. li t0, K0BASE
  278. or t5, t0
  279. move t4, a1
  280. 1:
  281. addu t4, a0 # arg0(startaddr)+min(cachesize, arg1)
  282. li t0, ~0xf0000000 # make sure that t4 is in Kseg0
  283. and t4, t0
  284. li t0, K0BASE
  285. or t4, t0
  286. move t0, t5         
  287.        
  288. 2:      # Clear out the Data Cache!!
  289.         .set    mips3
  290. cache DCACHE_ADDR_HIT_WRITEBACK_INVALIDATE, 0x0000(t0) 
  291.         .set    mips0        
  292.         addu t0, t0, 16 # Add cacheline length
  293. bltu t0, t4, 2b # while index < endaddr
  294. nop
  295.           
  296. # restore status register
  297. .set noreorder
  298. mtc0 t7, C0_SR # restore SR
  299. nop
  300. j ra
  301. nop
  302. .set reorder
  303. .end Invalidate_Dcache
  304. /************************************************************************/
  305. /************************************************************************/
  306. /************************************************************************/
  307.         
  308. /************************************************************************/
  309. /************************************************************************/
  310. /************************************************************************/
  311. /* DEBUG CODE */        
  312.         .ent    loadtag
  313. loadtag:
  314.         
  315.         .set noreorder
  316.         .set    mips3
  317. cache DCACHE_INDEX_LOAD_TAG, 0(a0) 
  318.         .set    mips0        
  319.         
  320.         j       ra
  321.         nop
  322.         
  323.         .set noreorder
  324.         .end loadtag    
  325.         .ent    readtag
  326. readtag:
  327.         
  328.         .set noreorder
  329.         mfc0    v0, $28
  330.         nop
  331.         
  332.         j       ra
  333.         nop
  334.         
  335.         .set noreorder
  336.         .end readtag    
  337. /************************************************************************/
  338. /* Flush_Dcache: Invaldates a portion of the Data Cache             */
  339. /* */
  340. /* Syntax: void Flush_Dcache(ulong base_addr, ulong bcount) */
  341. /*   Note: */
  342. /************************************************************************/
  343. .ent Flush_Dcache
  344. Flush_Dcache:  
  345. .set noreorder
  346.         
  347. mfc0 t7, C0_SR # save SR
  348.         nop
  349.         
  350.         and t0, t7, ~SR_IE # disable interrupts
  351. mtc0 t0, C0_SR
  352.         nop
  353.         .set  reorder
  354. move t5, a0
  355. li      t1, ~ALIGN_4W
  356. and  t5, t1 # align start of region to 16 bytes
  357. li t0, ~0xf0000000 # make sure that t5 is in Kseg0
  358. and t5, t0
  359. li t0, K0BASE
  360. or t5, t0
  361. move t4, a1
  362. 1:
  363. addu t4, a0 # arg0(startaddr)+min(cachesize, arg1)
  364. li t0, ~0xf0000000 # make sure that t4 is in Kseg0
  365. and t4, t0
  366. li t0, K0BASE
  367. or t4, t0
  368. move t0, t5       
  369.         
  370.         li      t2, WAR_ADDR         
  371. 2:      # Clear out the Data Cache!!
  372.         .set    mips3
  373.         lw      t1, 0(t2)
  374. #if 1  /* Jimmy, this is original */
  375. cache DCACHE_ADDR_HIT_WRITEBACK, 0x0000(t0) 
  376. #else  /* Try flush + invalidate */
  377. cache DCACHE_ADDR_HIT_WRITEBACK_INVALIDATE, 0x0000(t0) 
  378. #endif
  379.         .set    mips0        
  380.         addu t0, t0, 16 # Add cacheline length
  381. bltu t0, t4, 2b # while index < endaddr
  382. nop
  383.           
  384. # restore status register
  385. .set noreorder
  386. mtc0 t7, C0_SR # restore SR
  387. nop
  388. j ra
  389. nop
  390. .set reorder
  391. .end Flush_Dcache
  392. /************************************************************************/
  393. /* reset_caches: Init the D & I cache                                   */
  394. /* */
  395. /************************************************************************/
  396. .ent reset_caches
  397. reset_caches: 
  398.         /* init the data cache */
  399.         .set noreorder
  400.         li      t0, DATA_CACHE_SIZE
  401.         li      t1, CACHELINE_SIZE 
  402. mtc0    zero, C0_TAGLO 
  403. mtc0    zero, C0_TAGHI      /* TagHi is not really used */
  404. /* Calc an address that will correspond to the first cache line */
  405. li t2, KSEG0BASE
  406. /* Calc an address that will correspond to the last cache line  */
  407. addu t3, t2, t0
  408. subu    t3, t1
  409. /* Loop through all lines, invalidating each of them */
  410. 1:
  411. .set mips3
  412. cache DCACHE_INDEX_STORE_TAG, 0(t2) /* clear tag */
  413. .set mips0
  414. bne t2, t3, 1b
  415. addu t2, t1
  416.         
  417.         /* init the instr. cache */
  418.         
  419.         li      t0, INSTRUCTION_CACHE_SIZE
  420.         li      t1, CACHELINE_SIZE 
  421. mtc0    zero, C0_TAGLO 
  422. mtc0    zero, C0_TAGHI      /* TagHi is not really used */
  423. /* Calc an address that will correspond to the first cache line */
  424. li t2, KSEG0BASE
  425. /* Calc an address that will correspond to the last cache line  */
  426. addu t3, t2, t0
  427. subu    t3, t1
  428. /* Loop through all lines, invalidating each of them */
  429. 1:
  430. .set mips3
  431. cache ICACHE_INDEX_STORE_TAG, 0(t2) /* clear tag */
  432. .set mips0
  433. bne t2, t3, 1b
  434. addu t2, t1
  435. jr ra
  436. nop
  437.         .set reorder
  438.         .end reset_caches
  439. /************************************************************************/
  440. /************************************************************************/
  441. /************************************************************************/