memx.fuc 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447
  1. /*
  2. * Copyright 2013 Red Hat Inc.
  3. *
  4. * Permission is hereby granted, free of charge, to any person obtaining a
  5. * copy of this software and associated documentation files (the "Software"),
  6. * to deal in the Software without restriction, including without limitation
  7. * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  8. * and/or sell copies of the Software, and to permit persons to whom the
  9. * Software is furnished to do so, subject to the following conditions:
  10. *
  11. * The above copyright notice and this permission notice shall be included in
  12. * all copies or substantial portions of the Software.
  13. *
  14. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  17. * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
  18. * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  19. * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  20. * OTHER DEALINGS IN THE SOFTWARE.
  21. *
  22. * Authors: Ben Skeggs
  23. */
  24. #ifdef INCLUDE_PROC
  25. process(PROC_MEMX, #memx_init, #memx_recv)
  26. #endif
  27. /******************************************************************************
  28. * MEMX data segment
  29. *****************************************************************************/
  30. #ifdef INCLUDE_DATA
  31. .equ #memx_opcode 0
  32. .equ #memx_header 2
  33. .equ #memx_length 4
  34. .equ #memx_func 8
  35. #define handler(cmd,hdr,len,func) /*
  36. */ .b16 MEMX_##cmd /*
  37. */ .b16 hdr /*
  38. */ .b16 len /*
  39. */ .b16 0 /*
  40. */ .b32 func
  41. memx_func_head:
  42. handler(ENTER , 0x0000, 0x0000, #memx_func_enter)
  43. memx_func_next:
  44. handler(LEAVE , 0x0000, 0x0000, #memx_func_leave)
  45. handler(WR32 , 0x0000, 0x0002, #memx_func_wr32)
  46. handler(WAIT , 0x0004, 0x0000, #memx_func_wait)
  47. handler(DELAY , 0x0001, 0x0000, #memx_func_delay)
  48. handler(VBLANK, 0x0001, 0x0000, #memx_func_wait_vblank)
  49. handler(TRAIN , 0x0000, 0x0000, #memx_func_train)
  50. memx_func_tail:
  51. .equ #memx_func_size #memx_func_next - #memx_func_head
  52. .equ #memx_func_num (#memx_func_tail - #memx_func_head) / #memx_func_size
  53. memx_ts_start:
  54. .b32 0
  55. memx_ts_end:
  56. .b32 0
  57. memx_data_head:
  58. .skip 0x0800
  59. memx_data_tail:
  60. memx_train_head:
  61. .skip 0x0100
  62. memx_train_tail:
  63. #endif
  64. /******************************************************************************
  65. * MEMX code segment
  66. *****************************************************************************/
  67. #ifdef INCLUDE_CODE
  68. // description
  69. //
  70. // $r15 - current (memx)
  71. // $r4 - packet length
  72. // $r3 - opcode desciption
  73. // $r0 - zero
  74. memx_func_enter:
  75. #if NVKM_PPWR_CHIPSET == GT215
  76. movw $r8 0x1610
  77. nv_rd32($r7, $r8)
  78. imm32($r6, 0xfffffffc)
  79. and $r7 $r6
  80. movw $r6 0x2
  81. or $r7 $r6
  82. nv_wr32($r8, $r7)
  83. #else
  84. movw $r6 0x001620
  85. imm32($r7, ~0x00000aa2);
  86. nv_rd32($r8, $r6)
  87. and $r8 $r7
  88. nv_wr32($r6, $r8)
  89. imm32($r7, ~0x00000001)
  90. nv_rd32($r8, $r6)
  91. and $r8 $r7
  92. nv_wr32($r6, $r8)
  93. movw $r6 0x0026f0
  94. nv_rd32($r8, $r6)
  95. and $r8 $r7
  96. nv_wr32($r6, $r8)
  97. #endif
  98. mov $r6 NV_PPWR_OUTPUT_SET_FB_PAUSE
  99. nv_iowr(NV_PPWR_OUTPUT_SET, $r6)
  100. memx_func_enter_wait:
  101. nv_iord($r6, NV_PPWR_OUTPUT)
  102. and $r6 NV_PPWR_OUTPUT_FB_PAUSE
  103. bra z #memx_func_enter_wait
  104. nv_iord($r6, NV_PPWR_TIMER_LOW)
  105. st b32 D[$r0 + #memx_ts_start] $r6
  106. ret
  107. // description
  108. //
  109. // $r15 - current (memx)
  110. // $r4 - packet length
  111. // $r3 - opcode desciption
  112. // $r0 - zero
  113. memx_func_leave:
  114. nv_iord($r6, NV_PPWR_TIMER_LOW)
  115. st b32 D[$r0 + #memx_ts_end] $r6
  116. mov $r6 NV_PPWR_OUTPUT_CLR_FB_PAUSE
  117. nv_iowr(NV_PPWR_OUTPUT_CLR, $r6)
  118. memx_func_leave_wait:
  119. nv_iord($r6, NV_PPWR_OUTPUT)
  120. and $r6 NV_PPWR_OUTPUT_FB_PAUSE
  121. bra nz #memx_func_leave_wait
  122. #if NVKM_PPWR_CHIPSET == GT215
  123. movw $r8 0x1610
  124. nv_rd32($r7, $r8)
  125. imm32($r6, 0xffffffcc)
  126. and $r7 $r6
  127. nv_wr32($r8, $r7)
  128. #else
  129. movw $r6 0x0026f0
  130. imm32($r7, 0x00000001)
  131. nv_rd32($r8, $r6)
  132. or $r8 $r7
  133. nv_wr32($r6, $r8)
  134. movw $r6 0x001620
  135. nv_rd32($r8, $r6)
  136. or $r8 $r7
  137. nv_wr32($r6, $r8)
  138. imm32($r7, 0x00000aa2);
  139. nv_rd32($r8, $r6)
  140. or $r8 $r7
  141. nv_wr32($r6, $r8)
  142. #endif
  143. ret
  144. #if NVKM_PPWR_CHIPSET < GF119
  145. // description
  146. //
  147. // $r15 - current (memx)
  148. // $r4 - packet length
  149. // +00: head to wait for vblank on
  150. // $r3 - opcode desciption
  151. // $r0 - zero
  152. memx_func_wait_vblank:
  153. ld b32 $r6 D[$r1 + 0x00]
  154. cmp b32 $r6 0x0
  155. bra z #memx_func_wait_vblank_head0
  156. cmp b32 $r6 0x1
  157. bra z #memx_func_wait_vblank_head1
  158. bra #memx_func_wait_vblank_fini
  159. memx_func_wait_vblank_head1:
  160. movw $r7 0x20
  161. bra #memx_func_wait_vblank_0
  162. memx_func_wait_vblank_head0:
  163. movw $r7 0x8
  164. memx_func_wait_vblank_0:
  165. nv_iord($r6, NV_PPWR_INPUT)
  166. and $r6 $r7
  167. bra nz #memx_func_wait_vblank_0
  168. memx_func_wait_vblank_1:
  169. nv_iord($r6, NV_PPWR_INPUT)
  170. and $r6 $r7
  171. bra z #memx_func_wait_vblank_1
  172. memx_func_wait_vblank_fini:
  173. add b32 $r1 0x4
  174. ret
  175. #else
  176. // XXX: currently no-op
  177. //
  178. // $r15 - current (memx)
  179. // $r4 - packet length
  180. // +00: head to wait for vblank on
  181. // $r3 - opcode desciption
  182. // $r0 - zero
  183. memx_func_wait_vblank:
  184. add b32 $r1 0x4
  185. ret
  186. #endif
  187. // description
  188. //
  189. // $r15 - current (memx)
  190. // $r4 - packet length
  191. // +00*n: addr
  192. // +04*n: data
  193. // $r3 - opcode desciption
  194. // $r0 - zero
  195. memx_func_wr32:
  196. ld b32 $r6 D[$r1 + 0x00]
  197. ld b32 $r5 D[$r1 + 0x04]
  198. add b32 $r1 0x08
  199. nv_wr32($r6, $r5)
  200. sub b32 $r4 0x02
  201. bra nz #memx_func_wr32
  202. ret
  203. // description
  204. //
  205. // $r15 - current (memx)
  206. // $r4 - packet length
  207. // +00: addr
  208. // +04: mask
  209. // +08: data
  210. // +0c: timeout (ns)
  211. // $r3 - opcode desciption
  212. // $r0 - zero
  213. memx_func_wait:
  214. nv_iord($r8, NV_PPWR_TIMER_LOW)
  215. ld b32 $r14 D[$r1 + 0x00]
  216. ld b32 $r13 D[$r1 + 0x04]
  217. ld b32 $r12 D[$r1 + 0x08]
  218. ld b32 $r11 D[$r1 + 0x0c]
  219. add b32 $r1 0x10
  220. call(wait)
  221. ret
  222. // description
  223. //
  224. // $r15 - current (memx)
  225. // $r4 - packet length
  226. // +00: time (ns)
  227. // $r3 - opcode desciption
  228. // $r0 - zero
  229. memx_func_delay:
  230. ld b32 $r14 D[$r1 + 0x00]
  231. add b32 $r1 0x04
  232. call(nsec)
  233. ret
  234. // description
  235. //
  236. // $r15 - current (memx)
  237. // $r4 - packet length
  238. // $r3 - opcode desciption
  239. // $r0 - zero
  240. memx_func_train:
  241. #if NVKM_PPWR_CHIPSET == GT215
  242. // $r5 - outer loop counter
  243. // $r6 - inner loop counter
  244. // $r7 - entry counter (#memx_train_head + $r7)
  245. movw $r5 0x3
  246. movw $r7 0x0
  247. // Read random memory to wake up... things
  248. imm32($r9, 0x700000)
  249. nv_rd32($r8,$r9)
  250. movw $r14 0x2710
  251. call(nsec)
  252. memx_func_train_loop_outer:
  253. mulu $r8 $r5 0x101
  254. sethi $r8 0x02000000
  255. imm32($r9, 0x1111e0)
  256. nv_wr32($r9, $r8)
  257. push $r5
  258. movw $r6 0x0
  259. memx_func_train_loop_inner:
  260. movw $r8 0x1111
  261. mulu $r9 $r6 $r8
  262. shl b32 $r8 $r9 0x10
  263. or $r8 $r9
  264. imm32($r9, 0x100720)
  265. nv_wr32($r9, $r8)
  266. imm32($r9, 0x100080)
  267. nv_rd32($r8, $r9)
  268. or $r8 $r8 0x20
  269. nv_wr32($r9, $r8)
  270. imm32($r9, 0x10053c)
  271. imm32($r8, 0x80003002)
  272. nv_wr32($r9, $r8)
  273. imm32($r14, 0x100560)
  274. imm32($r13, 0x80000000)
  275. add b32 $r12 $r13 0
  276. imm32($r11, 0x001e8480)
  277. call(wait)
  278. // $r5 - inner inner loop counter
  279. // $r9 - result
  280. movw $r5 0
  281. imm32($r9, 0x8300ffff)
  282. memx_func_train_loop_4x:
  283. imm32($r10, 0x100080)
  284. nv_rd32($r8, $r10)
  285. imm32($r11, 0xffffffdf)
  286. and $r8 $r11
  287. nv_wr32($r10, $r8)
  288. imm32($r10, 0x10053c)
  289. imm32($r8, 0x80003002)
  290. nv_wr32($r10, $r8)
  291. imm32($r14, 0x100560)
  292. imm32($r13, 0x80000000)
  293. mov b32 $r12 $r13
  294. imm32($r11, 0x00002710)
  295. call(wait)
  296. nv_rd32($r13, $r14)
  297. and $r9 $r9 $r13
  298. add b32 $r5 1
  299. cmp b16 $r5 0x4
  300. bra l #memx_func_train_loop_4x
  301. add b32 $r10 $r7 #memx_train_head
  302. st b32 D[$r10 + 0] $r9
  303. add b32 $r6 1
  304. add b32 $r7 4
  305. cmp b16 $r6 0x10
  306. bra l #memx_func_train_loop_inner
  307. pop $r5
  308. add b32 $r5 1
  309. cmp b16 $r5 7
  310. bra l #memx_func_train_loop_outer
  311. #endif
  312. ret
  313. // description
  314. //
  315. // $r15 - current (memx)
  316. // $r14 - sender process name
  317. // $r13 - message (exec)
  318. // $r12 - head of script
  319. // $r11 - tail of script
  320. // $r0 - zero
  321. memx_exec:
  322. push $r14
  323. push $r13
  324. mov b32 $r1 $r12
  325. mov b32 $r2 $r11
  326. memx_exec_next:
  327. // fetch the packet header
  328. ld b32 $r3 D[$r1]
  329. add b32 $r1 4
  330. extr $r4 $r3 16:31
  331. extr $r3 $r3 0:15
  332. // execute the opcode handler
  333. sub b32 $r3 1
  334. mulu $r3 #memx_func_size
  335. ld b32 $r5 D[$r3 + #memx_func_head + #memx_func]
  336. call $r5
  337. // keep going, if we haven't reached the end
  338. cmp b32 $r1 $r2
  339. bra l #memx_exec_next
  340. // send completion reply
  341. ld b32 $r11 D[$r0 + #memx_ts_start]
  342. ld b32 $r12 D[$r0 + #memx_ts_end]
  343. sub b32 $r12 $r11
  344. nv_iord($r11, NV_PPWR_INPUT)
  345. pop $r13
  346. pop $r14
  347. call(send)
  348. ret
  349. // description
  350. //
  351. // $r15 - current (memx)
  352. // $r14 - sender process name
  353. // $r13 - message
  354. // $r12 - data0
  355. // $r11 - data1
  356. // $r0 - zero
  357. memx_info:
  358. cmp b16 $r12 0x1
  359. bra e #memx_info_train
  360. memx_info_data:
  361. mov $r12 #memx_data_head
  362. mov $r11 #memx_data_tail - #memx_data_head
  363. bra #memx_info_send
  364. memx_info_train:
  365. mov $r12 #memx_train_head
  366. mov $r11 #memx_train_tail - #memx_train_head
  367. memx_info_send:
  368. call(send)
  369. ret
  370. // description
  371. //
  372. // $r15 - current (memx)
  373. // $r14 - sender process name
  374. // $r13 - message
  375. // $r12 - data0
  376. // $r11 - data1
  377. // $r0 - zero
  378. memx_recv:
  379. cmp b32 $r13 MEMX_MSG_EXEC
  380. bra e #memx_exec
  381. cmp b32 $r13 MEMX_MSG_INFO
  382. bra e #memx_info
  383. ret
  384. // description
  385. //
  386. // $r15 - current (memx)
  387. // $r0 - zero
  388. memx_init:
  389. ret
  390. #endif