Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

926 lines
35 KiB

4 years ago
  1. #if defined(JAZZ)
  2. /*++
  3. Copyright (c) 1991 Microsoft Corporation
  4. Module Name:
  5. memtest.s
  6. Abstract:
  7. This module contains the assembly routine to test memory.
  8. Author:
  9. Lluis Abello (lluis) 10-Aug-91
  10. Environment:
  11. Executes in kernal mode.
  12. --*/
  13. #include "ksmips.h"
  14. #include "selfmap.h"
  15. #include "j4reset.h"
  16. .text
  17. .set noreorder
  18. .set noat
  19. /*++
  20. VOID
  21. WriteMemoryAddressTest(
  22. StartAddress
  23. Size
  24. Xor pattern
  25. )
  26. Routine Description:
  27. This routine will store the address of each location xored with
  28. the Pattern into each location.
  29. It packs together two words and does double word stores to
  30. speed it up.
  31. Arguments:
  32. a0 - supplies start of memory area to test (must be in KSEG0)
  33. a1 - supplies length of memory area in bytes
  34. a2 - supplies the pattern to Xor with.
  35. Note: the values of the arguments are preserved.
  36. Return Value:
  37. This routine returns no value.
  38. --*/
  39. LEAF_ENTRY(WriteMemoryAddressTest)
  40. // add t1,a0,a1 // t1 = last address.
  41. // xor t0,a0,a2 // t0 value to write
  42. // move t2,a0 // t2=current address
  43. //writeaddress:
  44. // mtc1 t0,f0 // move lower word to cop1
  45. // addiu t2,t2,4 // compute next address
  46. // xor t0,t2,a2 // next pattern
  47. // mtc1 t0,f1 // move upper word to cop1
  48. // addiu t2,t2,4 // compute next address
  49. // sdc1 f0,-8(t2) // store even doubleword.
  50. // xor t0,t2,a2 // next pattern
  51. // mtc1 t0,f0 // move lower word to cop1
  52. // addiu t2,t2,4 // compute next address
  53. // xor t0,t2,a2 // next pattern
  54. // mtc1 t0,f1 // move upper word to cop1
  55. // addiu t2,t2,4 // compute next address
  56. // sdc1 f0,-8(t2) // store odd doubleword.
  57. // bne t2,t1, writeaddress // check for end condition
  58. // xor t0,t2,a2 // value to write
  59. // j ra
  60. // nop
  61. //
  62. // Enable parity exceptions. To make sure this works.
  63. //
  64. li t1,(1 << PSR_CU1) | (1 << PSR_BEV)
  65. mtc0 t1,psr
  66. nop
  67. nop
  68. //
  69. // Create dirty exclusive cache blocks and zero the data.
  70. //
  71. mfc0 t5,config // get configuration data
  72. li t4,16 //
  73. srl t0,t5,CONFIG_DB // compute data cache line size
  74. and t0,t0,1 //
  75. sll t4,t4,t0 // 1st fill size
  76. li t1,(1 << CONFIG_SC)
  77. and t0,t5,t1
  78. beq t0,zero,SecondaryCache // if zero secondary cache
  79. PrimaryOnly:
  80. move t0,a0 // put start address in t0
  81. addu t9,t0,a1 // compute ending address
  82. and t8,t4,0x10 // test if 16-byte cache block
  83. //
  84. // Store data using primary data cache only.
  85. //
  86. 30: cache CREATE_DIRTY_EXCLUSIVE_D,0(t0) // create cache block
  87. move t1,t0 // save beginning block address
  88. xor t5,t0,a2 // create pattern to write
  89. mtc1 t5,f0 // move to lower word of double word
  90. addiu t0,t0,4 // increment address
  91. xor t5,t0,a2 // create pattern to write
  92. mtc1 t5,f1 // move to upper word of double word
  93. addiu t0,t0,4 // increment address
  94. sdc1 f0,-8(t0) // store double word
  95. xor t5,t0,a2 // create pattern to write
  96. mtc1 t5,f0 // move to lower word of double word
  97. addiu t0,t0,4 // increment address
  98. xor t5,t0,a2 // create pattern to write
  99. mtc1 t5,f1 // move to upper word of double word
  100. addiu t0,t0,4 // increment address
  101. bne zero,t8,40f // if ne, 16-byte cache line
  102. sdc1 f0,-8(t0) // store double word
  103. xor t5,t0,a2 // create pattern to write
  104. mtc1 t5,f0 // move to lower word of double word
  105. addiu t0,t0,4 // increment address
  106. xor t5,t0,a2 // create pattern to write
  107. mtc1 t5,f1 // move to upper word of double word
  108. addiu t0,t0,4 // increment address
  109. sdc1 f0,-8(t0) // store double word
  110. xor t5,t0,a2 // create pattern to write
  111. mtc1 t5,f0 // move to lower word of double word
  112. addiu t0,t0,4 // increment address
  113. xor t5,t0,a2 // create pattern to write
  114. mtc1 t5,f1 // move to upper word of double word
  115. addiu t0,t0,4 // increment address
  116. sdc1 f0,-8(t0) // store double word
  117. 40: nop
  118. nop
  119. cache INDEX_WRITEBACK_INVALIDATE_D,(t1) // Flush out the data
  120. nop
  121. bne t0,t9,30b // if ne, more blocks to zero
  122. nop
  123. j ra
  124. nop
  125. //
  126. // Store data using primary and secondary data caches.
  127. //
  128. SecondaryCache:
  129. // t4 = primary data cache line size
  130. srl t0,t5,CONFIG_DC // compute primary data cache size
  131. and t0,t0,0x7 //
  132. addu t0,t0,12 //
  133. li t6,1 //
  134. sll t6,t6,t0 // t6 = primary data cache size
  135. srl t0,t5,CONFIG_SB // compute secondary cache line size
  136. and t0,t0,3 //
  137. li t8,16 //
  138. sll t8,t8,t0 // t8 = secondary cache line size
  139. li t5,SECONDARY_CACHE_SIZE // t5 = secondary cache size
  140. //
  141. // Write Back all the dirty data from the primary to the secondary cache.
  142. //
  143. li t1,KSEG0_BASE+(1<<20) // get virtual address to index cache
  144. addu t2,t1,t6 // add cache size
  145. subu t2,t2,t4 // adjust for cache line size.
  146. WriteBackPrimary:
  147. cache INDEX_WRITEBACK_INVALIDATE_D,0(t1) // Invalidate Data cache
  148. bne t1,t2,WriteBackPrimary // loop
  149. addu t1,t1,t4 // increment index by cache line
  150. //
  151. // Write Back all the dirty data from the secondary to memory
  152. //
  153. li t1,KSEG0_BASE+(1<<20) // get virtual address to index cache
  154. addu t2,t1,t5 // add cache size
  155. subu t2,t2,t8 // adjust for cache line size.
  156. WriteBackSecondary:
  157. cache INDEX_WRITEBACK_INVALIDATE_SD,0(t1) // Invalidate Data cache
  158. bne t1,t2,WriteBackSecondary// loop
  159. addu t1,t1,t8 // increment index by cache line
  160. //
  161. // Now all the dirty data has been saved. And both primary and secondary
  162. // Data caches are invalid an clean.
  163. //
  164. move t0,a0 // put start address in t0
  165. addu t9,t0,a1 // compute ending address
  166. li t1,16 // If the secondary line is 16
  167. beq t1,t8,Secondary16 // bytes go do the write
  168. li t1,32 // If the secondary line is 32
  169. beq t1,t8,Secondary32 // bytes go do the write
  170. nop
  171. .globl Secondary64
  172. .align 4
  173. mtc0 zero,taghi
  174. Secondary64:
  175. srl t5,t0,5
  176. andi t5,t5,0x380
  177. ori t5,(5 << TAGLO_SSTATE)
  178. li t2,~KSEG1_BASE
  179. and t2,t2,t0
  180. srl t2,t2,17
  181. sll t2,t2,13
  182. or t2,t5,t2
  183. mtc0 t2,taglo
  184. nop
  185. nop
  186. cache INDEX_STORE_TAG_SD,0(t0)// create cache block
  187. xor t5,t0,a2 // create pattern to write
  188. sw t5,0(t0) // store word
  189. addiu t0,t0,4 // increment address
  190. xor t5,t0,a2 // create pattern to write
  191. sw t5,0(t0) // store word
  192. addiu t0,t0,4 // increment address
  193. xor t5,t0,a2 // create pattern to write
  194. sw t5,0(t0) // store word
  195. addiu t0,t0,4 // increment address
  196. xor t5,t0,a2 // create pattern to write
  197. sw t5,0(t0) // store word
  198. addiu t0,t0,4 // increment address
  199. xor t5,t0,a2 // create pattern to write
  200. sw t5,0(t0) // store word
  201. addiu t0,t0,4 // increment address
  202. xor t5,t0,a2 // create pattern to write
  203. sw t5,0(t0) // store word
  204. addiu t0,t0,4 // increment address
  205. xor t5,t0,a2 // create pattern to write
  206. sw t5,0(t0) // store word
  207. addiu t0,t0,4 // increment address
  208. xor t5,t0,a2 // create pattern to write
  209. sw t5,0(t0) // store word
  210. addiu t0,t0,4 // increment address
  211. xor t5,t0,a2 // create pattern to write
  212. sw t5,0(t0) // store word
  213. addiu t0,t0,4 // increment address
  214. xor t5,t0,a2 // create pattern to write
  215. sw t5,0(t0) // store word
  216. addiu t0,t0,4 // increment address
  217. xor t5,t0,a2 // create pattern to write
  218. sw t5,0(t0) // store word
  219. addiu t0,t0,4 // increment address
  220. xor t5,t0,a2 // create pattern to write
  221. sw t5,0(t0) // store word
  222. addiu t0,t0,4 // increment address
  223. xor t5,t0,a2 // create pattern to write
  224. sw t5,0(t0) // store word
  225. addiu t0,t0,4 // increment address
  226. xor t5,t0,a2 // create pattern to write
  227. sw t5,0(t0) // store word
  228. addiu t0,t0,4 // increment address
  229. xor t5,t0,a2 // create pattern to write
  230. sw t5,0(t0) // store word
  231. addiu t0,t0,4 // increment address
  232. xor t5,t0,a2 // create pattern to write
  233. sw t5,0(t0) // store word
  234. addiu t0,t0,4 // increment address
  235. nop
  236. cache HIT_WRITEBACK_INVALIDATE_SD,-64(t0) // Flush cache block
  237. bne t0,t9,Secondary64 // if ne, more data to zero
  238. nop
  239. j ra
  240. nop
  241. Secondary16:
  242. cache CREATE_DIRTY_EXCLUSIVE_SD,0(t0) // create cache block
  243. xor t5,t0,a2 // create pattern to write
  244. sw t5,0(t0) // store word
  245. addiu t0,t0,4 // increment address
  246. xor t5,t0,a2 // create pattern to write
  247. sw t5,0(t0) // store word
  248. addiu t0,t0,4 // increment address
  249. xor t5,t0,a2 // create pattern to write
  250. sw t5,0(t0) // store word
  251. addiu t0,t0,4 // increment address
  252. xor t5,t0,a2 // create pattern to write
  253. sw t5,0(t0) // store word
  254. addiu t0,t0,4 // increment address
  255. nop
  256. cache HIT_WRITEBACK_INVALIDATE_SD,-16(t0) // Flush cache block
  257. bne t0,t9,Secondary16 // if ne, more data to zero
  258. nop
  259. j ra
  260. nop
  261. Secondary32:
  262. cache CREATE_DIRTY_EXCLUSIVE_SD,0(t0) // create cache block
  263. xor t5,t0,a2 // create pattern to write
  264. sw t5,0(t0) // store word
  265. addiu t0,t0,4 // increment address
  266. xor t5,t0,a2 // create pattern to write
  267. sw t5,0(t0) // store word
  268. addiu t0,t0,4 // increment address
  269. xor t5,t0,a2 // create pattern to write
  270. sw t5,0(t0) // store word
  271. addiu t0,t0,4 // increment address
  272. xor t5,t0,a2 // create pattern to write
  273. sw t5,0(t0) // store word
  274. addiu t0,t0,4 // increment address
  275. xor t5,t0,a2 // create pattern to write
  276. sw t5,0(t0) // store word
  277. addiu t0,t0,4 // increment address
  278. xor t5,t0,a2 // create pattern to write
  279. sw t5,0(t0) // store word
  280. addiu t0,t0,4 // increment address
  281. xor t5,t0,a2 // create pattern to write
  282. sw t5,0(t0) // store word
  283. addiu t0,t0,4 // increment address
  284. xor t5,t0,a2 // create pattern to write
  285. sw t5,0(t0) // store word
  286. addiu t0,t0,4 // increment address
  287. nop
  288. cache HIT_WRITEBACK_INVALIDATE_SD,-32(t0) // Flush cache block
  289. bne t0,t9,Secondary32 // if ne, more data to zero
  290. nop
  291. j ra
  292. nop
  293. .end WriteMemoryAddressTest
  294. /*++
  295. VOID
  296. CheckMemoryAddressTest(
  297. StartAddress
  298. Size
  299. Xor pattern
  300. LedDisplayValue
  301. )
  302. Routine Description:
  303. This routine will check that each location contains it's address
  304. xored with the Pattern as written by WriteMemoryAddressTest.
  305. Note: the values of the arguments are preserved.
  306. Arguments:
  307. This routine will check that each location contains it's address
  308. xored with the Pattern as written by WriteMemoryAddressTest. The memory
  309. is read cached or non cached according to the address specified by a0.
  310. Write address test writes allways KSEG1_ADR=KSEG1_ADR ^ KSEG1_XOR
  311. if a0 is in KSEG0 to read the data cached, then the XOR_PATTERN
  312. Must be such that:
  313. KSEG0_ADR ^ KSEG0_XOR = KSEG1_ADR ^ KSEG1_XOR
  314. Examples:
  315. If XorPattern with which WriteMemoryAddressTest was called is KSEG1_PAT
  316. and the XorPattern this routine needs is KSEG0_PAT:
  317. KSEG1_XOR Written KSEG0_XOR So that
  318. 0x00000000 0xA0 0x20000000 0x80 ^ 0x20 = 0xA0
  319. 0xFFFFFFFF 0x5F 0xDFFFFFFF 0x80 ^ 0xDF = 0x5F
  320. 0x01010101 0xA1 0x21010101 0x80 ^ 0x21 = 0xA1
  321. Note: the values of the arguments are preserved.
  322. a0 - supplies start of memory area to test
  323. a1 - supplies length of memory area in bytes
  324. a2 - supplies the pattern to Xor with.
  325. a3 - suplies the value to display in the led in case of failure
  326. Return Value:
  327. If successful returns a 0, otherwise returns a 1.
  328. --*/
  329. LEAF_ENTRY(CheckMemoryAddressTest)
  330. move t3,a0 // t3 first address.
  331. add t2,t3,a1 // last address.
  332. checkaddress:
  333. lw t1,0(t3) // load from first location
  334. xor t0,t3,a2 // first expected value
  335. bne t1,t0,PatternFail
  336. addiu t3,t3,4 // compute next address
  337. lw t1,0(t3) // load from first location
  338. xor t0,t3,a2 // first expected value
  339. bne t1,t0,PatternFail
  340. addiu t3,t3,4 // compute next address
  341. lw t1,0(t3) // load from first location
  342. xor t0,t3,a2 // first expected value
  343. bne t1,t0,PatternFail
  344. addiu t3,t3,4 // compute next address
  345. lw t1,0(t3) // load from first location
  346. xor t0,t3,a2 // first expected value
  347. bne t1,t0,PatternFail // check last one.
  348. addiu t3,t3,4 // compute next address
  349. bne t3,t2, checkaddress // check for end condition
  350. nop
  351. j ra // return a zero to the caller
  352. move v0,zero // set return value to zero.
  353. PatternFail:
  354. j ra //
  355. // addiu v0,zero,1 // return a 1 to the caller
  356. addu v0,zero,t3 // return failing address to caller
  357. .end CheckMemoryAddressTest
  358. /*++
  359. VOID
  360. WriteVideoMemoryAddressTest(
  361. StartAddress
  362. Size
  363. )
  364. Routine Description:
  365. This routine will store the address of each location
  366. into each location. It packs two double words together
  367. to do sdc1 and speed it up.
  368. Arguments:
  369. a0 - supplies start of memory area to test
  370. a1 - supplies length of memory area in bytes
  371. Note: the values of the arguments are preserved.
  372. Return Value:
  373. This routine returns no value.
  374. --*/
  375. LEAF_ENTRY(WriteVideoMemoryAddressTest)
  376. addu t1,a0,a1 // t1 = last address.
  377. move t2,a0 // t2=current address
  378. 10:
  379. mtc1 t2,f0 // move lower word to cop1
  380. addiu t2,t2,4 // compute next address
  381. mtc1 t2,f1 // move upper word to cop1
  382. addiu t2,t2,4 // compute next address
  383. sdc1 f0,-8(t2) // store even doubleword
  384. mtc1 t2,f2 // move lower word to cop1
  385. addiu t2,t2,4 // compute next address
  386. mtc1 t2,f3 // move upper word to cop1
  387. addiu t2,t2,4 // compute next address
  388. bne t2,t1, 10b // check for end condition
  389. sdc1 f2,-8(t2) // store odd doubleword.
  390. j ra
  391. nop
  392. .end WriteVideoMemoryAddressTest
  393. /*++
  394. VOID
  395. CheckVideoMemoryAddressTest(
  396. StartAddress
  397. Size
  398. )
  399. Routine Description:
  400. This routine will check that each location contains it's address
  401. xored with the Pattern as written by WriteMemoryAddressTest.
  402. Arguments:
  403. Note: the values of the arguments are preserved.
  404. a0 - supplies start of memory area to test
  405. a1 - supplies length of memory area in bytes
  406. Return Value:
  407. This routine returns FALSE if no errors are found.
  408. Otherwise returns true.
  409. --*/
  410. LEAF_ENTRY(CheckVideoMemoryAddressTest)
  411. addu t2,a0,a1 // compute last address.
  412. 10:
  413. ldc1 f0,0(a0) // read data
  414. ldc1 f2,8(a0) // read data
  415. mfc1 t0,f0 // move from cop
  416. mfc1 t1,f1 // move from cop
  417. bne t0,a0,VideoMemoryFail // compare
  418. addiu a0,a0,4 // inc address for next expected value
  419. bne t1,a0,VideoMemoryFail // compare.
  420. mfc1 t0,f2 // move from cop
  421. mfc1 t1,f3 // move from cop
  422. addiu a0,a0,4 // inc address for next expected value
  423. bne t0,a0,VideoMemoryFail // compare
  424. addiu a0,a0,4 // inc address for next expected value
  425. bne t1,a0,VideoMemoryFail // compare.
  426. addiu a0,a0,4
  427. bne a0,t2,10b
  428. nop
  429. j ra // return a zero to the caller
  430. move v0,zero //
  431. VideoMemoryFail:
  432. j ra //
  433. addiu v0,zero,1 // return a 1 to the caller
  434. .end CheckVideoMemoryAddressTest
  435. .set at
  436. LEAF_ENTRY(RomReadMergeWrite)
  437. mfc0 t5,config // read config
  438. lui t0,0xa004 // uncached address
  439. lui t1,0x8004 //8004 // same cached address R4KFIX
  440. li t6,16 // end of loop counter
  441. move t2,zero // byte counter
  442. srl t3,t5,CONFIG_DC // compute data cache size
  443. and t3,t3,0x7 //
  444. addu t3,t3,12 //
  445. li t9,1 //
  446. sll t9,t9,t3 // t9 = data cache size
  447. WriteNextByte:
  448. sw zero,0(t1) // clear memory line
  449. sw zero,4(t1) // clear memory line
  450. sw zero,8(t1) // clear memory line
  451. sw zero,12(t1) // clear memory line
  452. addu t8,t9,t1 // add cache size to address
  453. lw zero,0(t8) // Force a replacement of the cache line -> updates memory
  454. add t4,t0,t2 // compute ith byte address
  455. nor t5,t2,zero // invert value
  456. sb t5,0(t4) // write byte <= read/merge/write
  457. move t3,zero // init read index
  458. CheckNextByte:
  459. add t4,t3,t1 // compute cached address
  460. lb t4,0(t4) // read byte
  461. beq t3,t2, Inverted // if equal is the inverted value
  462. nor t5,t2,zero
  463. move t5,zero // else expect a zero
  464. Inverted:
  465. bne t4,t5, Error // compare with what we wrote.
  466. addiu t3,t3,1 // next byte index
  467. bne t3,t6,CheckNextByte
  468. nop
  469. addiu t2,t2,1 // inc write index
  470. bne t2,t6,WriteNextByte
  471. nop
  472. // do the same storing half words
  473. move t2,zero // byte counter
  474. WriteNextHalf:
  475. sw zero,0(t1) // clear memory line
  476. sw zero,4(t1) // clear memory line
  477. sw zero,8(t1) // clear memory line
  478. sw zero,12(t1) // clear memory line
  479. addu t8,t9,t1 // add cache size to address
  480. lw zero,0(t8) // Force a replacement of the cache line -> updates memory
  481. add t4,t0,t2 // compute ith byte address
  482. nor t5,t2,zero // invert value
  483. sh t5,0(t4) // write half <= read/merge/write
  484. move t3,zero // init read index
  485. CheckNextHalf:
  486. add t4,t3,t1 // compute cached address
  487. lh t4,0(t4) // read half
  488. beq t3,t2,InvertedHalf // if equal is the inverted value
  489. nor t5,t2,zero // invert value
  490. move t5,zero // else expect a zero
  491. InvertedHalf:
  492. bne t4,t5, Error // compare with what we wrote.
  493. addiu t3,t3,2 // next half index
  494. bne t3,t6,CheckNextHalf
  495. nop
  496. addiu t2,t2,2 // inc write index
  497. bne t2,t6,WriteNextHalf
  498. nop
  499. j ra
  500. move v0,zero // return no errors
  501. Error:
  502. sw t4,20(t0)
  503. j ra
  504. addiu v0,zero,1 // return errors
  505. .end RomReadMergeWrite
  506. .set noat
  507. /*++
  508. VOID
  509. FillVideoMemory(
  510. StartAddress
  511. Size
  512. Pattern
  513. )
  514. Routine Description:
  515. This routine will fill the given range of video memory with
  516. the supplied pattern. The fill is done by doing double word
  517. writes and the range must be 16byte aligned.
  518. Arguments:
  519. a0 - supplies start of memory area
  520. a1 - supplies length of memory area
  521. a2 - supplies the pattern to fill video memory with. (1byte)
  522. Return Value:
  523. None.
  524. --*/
  525. LEAF_ENTRY(FillVideoMemory)
  526. andi a2,a2,0xFF // Mask out byte
  527. sll t0,a2,8 // Shift Byte
  528. or t0,t0,a2 // or them to make half
  529. sll a2,t0,16 // shift half
  530. or a2,t0,a2 // or them to make a word
  531. addu t0,a0,a1 // compute last address.
  532. mtc1 a2,f0 // move pattern to cop1
  533. mtc1 a2,f1 // move pattern to cop1
  534. 10:
  535. addiu a0,a0,16 // compute next address
  536. sdc1 f0,-16(a0) // do a store
  537. bne a0,t0,10b // check for end condition
  538. sdc1 f0,-8(a0) // do a store
  539. j ra
  540. nop
  541. .end FillVideoMemory
  542. /*++
  543. VOID FwVideoScroll(
  544. PUCHAR StartAddress,
  545. PUCHAR EndAddress,
  546. PUCHAR Destination
  547. );
  548. Routine Description:
  549. This routine writes the pattern to the specified range of addresses
  550. doing video pipeline writes on double writes.
  551. Arguments:
  552. StartAddress - Suplies the range of addresses to be scrolled
  553. EndAddress - this addresses must be aligned to 256byte boundaries.
  554. Destination - Suplies the Destination address for the scroll
  555. (i.e the contents of StartAddress will be moved
  556. to destination address and so on).
  557. Return Value:
  558. None.
  559. --*/
  560. .set noreorder
  561. .set noat
  562. LEAF_ENTRY(FwVideoScroll)
  563. ScrollRead:
  564. ldc1 f0,0x0(a0) // read video
  565. ldc1 f2,0x8(a0)
  566. ldc1 f4,0x10(a0)
  567. ldc1 f6,0x18(a0)
  568. ldc1 f8,0x20(a0)
  569. ldc1 f10,0x28(a0)
  570. ldc1 f12,0x30(a0)
  571. ldc1 f14,0x38(a0)
  572. ldc1 f16,0x40(a0)
  573. ldc1 f18,0x48(a0)
  574. ldc1 f20,0x50(a0)
  575. ldc1 f22,0x58(a0)
  576. ldc1 f24,0x60(a0)
  577. ldc1 f26,0x68(a0)
  578. ldc1 f28,0x70(a0)
  579. ldc1 f30,0x78(a0)
  580. addiu a0,a0,0x80 // increment source address
  581. sdc1 f0,0x0(a2) // store them pipelining
  582. sdc1 f2,0x8(a2)
  583. sdc1 f4,0x10(a2)
  584. sdc1 f6,0x18(a2)
  585. sdc1 f8,0x20(a2)
  586. sdc1 f10,0x28(a2)
  587. sdc1 f12,0x30(a2)
  588. sdc1 f14,0x38(a2)
  589. sdc1 f16,0x40(a2)
  590. sdc1 f18,0x48(a2)
  591. sdc1 f20,0x50(a2)
  592. sdc1 f22,0x58(a2)
  593. sdc1 f24,0x60(a2)
  594. sdc1 f26,0x68(a2)
  595. sdc1 f28,0x70(a2)
  596. sdc1 f30,0x78(a2)
  597. bne a0,a1,ScrollRead // check for last
  598. addiu a2,a2,0x80 // increment destination
  599. j ra // return to caller
  600. nop
  601. .end FwVideoScroll
  602. /*++
  603. VOID
  604. StoreDoubleWord(
  605. IN ULONG Address,
  606. IN PVOID Value
  607. );
  608. Routine Description:
  609. This routine writes the value pointed by a1 to the address supplied
  610. in a0.
  611. Arguments:
  612. a0 - Address to write double to.
  613. a1 - pointer to value to write.
  614. Return Value:
  615. None.
  616. --*/
  617. LEAF_ENTRY(StoreDoubleWord)
  618. ldc1 f0,0(a1)
  619. nop
  620. sdc1 f0,0(a0)
  621. j ra
  622. nop
  623. .end StoreDoubleWord
  624. /*++
  625. VOID
  626. LoadDoubleWord(
  627. IN ULONG Address,
  628. OUT PVOID Result
  629. );
  630. Routine Description:
  631. This routine reads a double from the address suplied in a0 and
  632. stores the red value in the address supplied by result.
  633. Arguments:
  634. a0 - Address to read double from.
  635. a1 - pointer to double to store result.
  636. Return Value:
  637. None.
  638. --*/
  639. LEAF_ENTRY(LoadDoubleWord)
  640. ldc1 f0,0(a0)
  641. nop
  642. sdc1 f0,0(a1)
  643. j ra
  644. nop
  645. .end
  646. /*++
  647. VOID
  648. WildZeroMemory(
  649. IN ULONG StartAddress,
  650. IN ULONG Size
  651. )
  652. Routine Description:
  653. This routine zeroes the specified range of memory by doing
  654. cache line writes.
  655. Arguments:
  656. a0 - supplies the physical address of the range of memory to
  657. zero. This address must be a multiple of the Data Cache Size.
  658. a1 - supplies length of memory to zero.
  659. This value must be a multiple of the Data Cache Size.
  660. Return Value:
  661. None.
  662. --*/
  663. LEAF_ENTRY(WildZeroMemory)
  664. // TEMPTEMP
  665. // li t0,KSEG1_BASE // get non-cached base
  666. // or t0,t0,a0 // physical address in KSEG1
  667. // addu t1,t0,a1 // end
  668. // mtc1 zero,f0 // set write pattern
  669. // mtc1 zero,f1 //
  670. //
  671. //10:
  672. // sdc1 f0,0(t0)
  673. // addu t0,t0,16
  674. // bne t0,t1,10b
  675. // sdc1 f0,-8(t0)
  676. //
  677. // li t0,KSEG0_BASE // get cached base
  678. // or t0,t0,a0 // physical address in KSEG0
  679. // addu t1,t0,a1 // end
  680. //10:
  681. // lw zero,0(t0)
  682. // addu t0,t0,16
  683. // bne t0,t1,10b
  684. // nop
  685. //
  686. // j ra
  687. // nop
  688. // TEMPTEMP
  689. //
  690. // Create dirty exclusive cache blocks and zero the data.
  691. //
  692. mfc0 t5,config // get configuration data
  693. li t4,16 //
  694. srl t0,t5,CONFIG_DB // compute data cache line size
  695. and t0,t0,1 //
  696. sll t4,t4,t0 // t4 = 1st fill size
  697. li t1,(1 << CONFIG_SC)
  698. and t0,t5,t1
  699. mtc1 zero,f0 // set write pattern
  700. mtc1 zero,f1 //
  701. beq t0,zero,SecondaryWild // if zero secondary cache
  702. PrimaryWild:
  703. li t0,KSEG0_BASE // get cached base
  704. or t0,t0,a0 // physical address in KSEG0
  705. addu t9,t0,a1 // compute ending address
  706. and t8,t4,0x10 // test if 16-byte cache block
  707. //
  708. // Zero data using primary data cache only.
  709. //
  710. 30: cache CREATE_DIRTY_EXCLUSIVE_D,0(t0) // create cache block
  711. move t1,t0 // save beginning block address
  712. addu t0,t0,t4 // compute next block address
  713. bne zero,t8,40f // if ne, 16-byte cache line
  714. sdc1 f0,-16(t0) //
  715. sdc1 f0,-24(t0) // zero 16 bytes
  716. sdc1 f0,-32(t0) //
  717. 40: sdc1 f0,-8(t0) // zero 16 bytes
  718. nop
  719. nop
  720. cache INDEX_WRITEBACK_INVALIDATE_D,0(t1) // Flush out the data
  721. bne t0,t9,30b // if ne, more blocks to zero
  722. nop
  723. j ra
  724. nop
  725. //
  726. // Zero data using primary and secondary data caches.
  727. //
  728. SecondaryWild:
  729. // t4 = primary data cache line size
  730. srl t0,t5,CONFIG_DC // compute primary data cache size
  731. and t0,t0,0x7 //
  732. addu t0,t0,12 //
  733. li t6,1 //
  734. sll t6,t6,t0 // t6 = primary data cache size
  735. srl t0,t5,CONFIG_SB // compute secondary cache line size
  736. and t0,t0,3 //
  737. li t8,16 //
  738. sll t8,t8,t0 // t8 = secondary cache line size
  739. li t5,SECONDARY_CACHE_SIZE // t5 = secondary cache size
  740. //
  741. // Write Back all the dirty data from the primary to the secondary cache.
  742. //
  743. li t1,KSEG0_BASE+(1<<20) // get virtual address to index cache
  744. addu t2,t1,t6 // add cache size
  745. subu t2,t2,t4 // adjust for cache line size.
  746. WriteBackPrimaryW:
  747. cache INDEX_WRITEBACK_INVALIDATE_D,0(t1) // Invalidate Data cache
  748. bne t1,t2,WriteBackPrimaryW // loop
  749. addu t1,t1,t4 // increment index by cache line
  750. //
  751. // Write Back all the dirty data from the secondary to memory
  752. //
  753. li t1,KSEG0_BASE+(1<<20) // get virtual address to index cache
  754. addu t2,t1,t5 // add cache size
  755. subu t2,t2,t8 // adjust for cache line size.
  756. WriteBackSecondaryW:
  757. cache INDEX_WRITEBACK_INVALIDATE_SD,0(t1) // Invalidate Data cache
  758. bne t1,t2,WriteBackSecondaryW // loop
  759. addu t1,t1,t8 // increment index by cache line
  760. //
  761. // Now all the dirty data has been saved. And both primary and secondary
  762. // Data caches are invalid an clean.
  763. //
  764. li t0,KSEG0_BASE // get cached base
  765. or t0,t0,a0 // physical address in KSEG0
  766. addu t9,t0,a1 // compute ending address
  767. subu t9,t9,t8 // adjust last address
  768. li t1,16 // If the secondary line is 16
  769. beq t1,t8,SecondaryW16 // bytes go do the write
  770. li t1,32 // If the secondary line is 32
  771. beq t1,t8,SecondaryW32 // bytes go do the write
  772. nop
  773. SecondaryW64:
  774. cache CREATE_DIRTY_EXCLUSIVE_SD,0(t0) // create cache block
  775. sdc1 f0,0(t0) // store double word
  776. sdc1 f0,8(t0) // store double word
  777. sdc1 f0,16(t0) // store double word
  778. sdc1 f0,24(t0) // store double word
  779. sdc1 f0,32(t0) // store double word
  780. sdc1 f0,40(t0) // store double word
  781. sdc1 f0,48(t0) // store double word
  782. sdc1 f0,56(t0) // store double word
  783. cache HIT_WRITEBACK_INVALIDATE_SD,0(t0) // Flush cache block
  784. bne t0,t9,SecondaryW64 // if ne, more data to zero
  785. addiu t0,t0,64
  786. j ra
  787. nop
  788. SecondaryW32:
  789. cache CREATE_DIRTY_EXCLUSIVE_SD,0(t0) // create cache block
  790. sdc1 f0,0(t0) // store double word
  791. sdc1 f0,8(t0) // store double word
  792. sdc1 f0,16(t0) // store double word
  793. sdc1 f0,24(t0) // store double word
  794. cache HIT_WRITEBACK_INVALIDATE_SD,0(t0) // Flush cache block
  795. bne t0,t9,SecondaryW32 // if ne, more data to zero
  796. addiu t0,t0,32
  797. j ra
  798. nop
  799. SecondaryW16:
  800. cache CREATE_DIRTY_EXCLUSIVE_SD,0(t0) // create cache block
  801. sdc1 f0,0(t0) // store double word
  802. sdc1 f0,8(t0) // store double word
  803. cache HIT_WRITEBACK_INVALIDATE_SD,0(t0) // Flush cache block
  804. bne t0,t9,SecondaryW16 // if ne, more data to zero
  805. addiu t0,t0,16
  806. j ra
  807. nop
  808. .end WildZeroMemory
  809. #endif