]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blame - drivers/gpu/drm/nouveau/nv98_crypt.fuc
drm/nouveau/gem: use bo.offset rather than mm_node.start
[mirror_ubuntu-bionic-kernel.git] / drivers / gpu / drm / nouveau / nv98_crypt.fuc
CommitLineData
b3550969
BS
1/*
2 * fuc microcode for nv98 pcrypt engine
3 * Copyright (C) 2010 Marcin Koƛcielnicki
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20.section #nv98_pcrypt_data
21
22ctx_dma:
23ctx_dma_query: .b32 0
24ctx_dma_src: .b32 0
25ctx_dma_dst: .b32 0
26.equ #dma_count 3
27ctx_query_address_high: .b32 0
28ctx_query_address_low: .b32 0
29ctx_query_counter: .b32 0
30ctx_cond_address_high: .b32 0
31ctx_cond_address_low: .b32 0
32ctx_cond_off: .b32 0
33ctx_src_address_high: .b32 0
34ctx_src_address_low: .b32 0
35ctx_dst_address_high: .b32 0
36ctx_dst_address_low: .b32 0
37ctx_mode: .b32 0
38.align 16
39ctx_key: .skip 16
40ctx_iv: .skip 16
41
42.align 0x80
43swap:
44.skip 32
45
46.align 8
47common_cmd_dtable:
48.b32 #ctx_query_address_high + 0x20000 ~0xff
49.b32 #ctx_query_address_low + 0x20000 ~0xfffffff0
50.b32 #ctx_query_counter + 0x20000 ~0xffffffff
51.b32 #cmd_query_get + 0x00000 ~1
52.b32 #ctx_cond_address_high + 0x20000 ~0xff
53.b32 #ctx_cond_address_low + 0x20000 ~0xfffffff0
54.b32 #cmd_cond_mode + 0x00000 ~7
55.b32 #cmd_wrcache_flush + 0x00000 ~0
56.equ #common_cmd_max 0x88
57
58
59.align 8
60engine_cmd_dtable:
61.b32 #ctx_key + 0x0 + 0x20000 ~0xffffffff
62.b32 #ctx_key + 0x4 + 0x20000 ~0xffffffff
63.b32 #ctx_key + 0x8 + 0x20000 ~0xffffffff
64.b32 #ctx_key + 0xc + 0x20000 ~0xffffffff
65.b32 #ctx_iv + 0x0 + 0x20000 ~0xffffffff
66.b32 #ctx_iv + 0x4 + 0x20000 ~0xffffffff
67.b32 #ctx_iv + 0x8 + 0x20000 ~0xffffffff
68.b32 #ctx_iv + 0xc + 0x20000 ~0xffffffff
69.b32 #ctx_src_address_high + 0x20000 ~0xff
70.b32 #ctx_src_address_low + 0x20000 ~0xfffffff0
71.b32 #ctx_dst_address_high + 0x20000 ~0xff
72.b32 #ctx_dst_address_low + 0x20000 ~0xfffffff0
73.b32 #crypt_cmd_mode + 0x00000 ~0xf
74.b32 #crypt_cmd_length + 0x10000 ~0x0ffffff0
75.equ #engine_cmd_max 0xce
76
77.align 4
78crypt_dtable:
79.b16 #crypt_copy_prep #crypt_do_inout
80.b16 #crypt_store_prep #crypt_do_out
81.b16 #crypt_ecb_e_prep #crypt_do_inout
82.b16 #crypt_ecb_d_prep #crypt_do_inout
83.b16 #crypt_cbc_e_prep #crypt_do_inout
84.b16 #crypt_cbc_d_prep #crypt_do_inout
85.b16 #crypt_pcbc_e_prep #crypt_do_inout
86.b16 #crypt_pcbc_d_prep #crypt_do_inout
87.b16 #crypt_cfb_e_prep #crypt_do_inout
88.b16 #crypt_cfb_d_prep #crypt_do_inout
89.b16 #crypt_ofb_prep #crypt_do_inout
90.b16 #crypt_ctr_prep #crypt_do_inout
91.b16 #crypt_cbc_mac_prep #crypt_do_in
92.b16 #crypt_cmac_finish_complete_prep #crypt_do_in
93.b16 #crypt_cmac_finish_partial_prep #crypt_do_in
94
95.align 0x100
96
97.section #nv98_pcrypt_code
98
99 // $r0 is always set to 0 in our code - this allows some space savings.
100 clear b32 $r0
101
102 // set up the interrupt handler
103 mov $r1 #ih
104 mov $iv0 $r1
105
106 // init stack pointer
107 mov $sp $r0
108
109 // set interrupt dispatch - route timer, fifo, ctxswitch to i0, others to host
110 movw $r1 0xfff0
111 sethi $r1 0
112 mov $r2 0x400
113 iowr I[$r2 + 0x300] $r1
114
115 // enable the interrupts
116 or $r1 0xc
117 iowr I[$r2] $r1
118
119 // enable fifo access and context switching
120 mov $r1 3
121 mov $r2 0x1200
122 iowr I[$r2] $r1
123
124 // enable i0 delivery
125 bset $flags ie0
126
127 // sleep forver, waking only for interrupts.
128 bset $flags $p0
129 spin:
130 sleep $p0
131 bra #spin
132
133// i0 handler
134ih:
135 // see which interrupts we got
136 iord $r1 I[$r0 + 0x200]
137
138 and $r2 $r1 0x8
139 cmpu b32 $r2 0
140 bra e #noctx
141
142 // context switch... prepare the regs for xfer
143 mov $r2 0x7700
144 mov $xtargets $r2
145 mov $xdbase $r0
146 // 128-byte context.
147 mov $r2 0
148 sethi $r2 0x50000
149
150 // read current channel
151 mov $r3 0x1400
152 iord $r4 I[$r3]
153 // if bit 30 set, it's active, so we have to unload it first.
154 shl b32 $r5 $r4 1
155 cmps b32 $r5 0
156 bra nc #ctxload
157
158 // unload the current channel - save the context
159 xdst $r0 $r2
160 xdwait
161 // and clear bit 30, then write back
162 bclr $r4 0x1e
163 iowr I[$r3] $r4
164 // tell PFIFO we unloaded
165 mov $r4 1
166 iowr I[$r3 + 0x200] $r4
167
168 bra #noctx
169
170 ctxload:
171 // no channel loaded - perhaps we're requested to load one
172 iord $r4 I[$r3 + 0x100]
173 shl b32 $r15 $r4 1
174 cmps b32 $r15 0
175 // if bit 30 of next channel not set, probably PFIFO is just
176 // killing a context. do a faux load, without the active bit.
177 bra nc #dummyload
178
179 // ok, do a real context load.
180 xdld $r0 $r2
181 xdwait
182 mov $r5 #ctx_dma
183 mov $r6 #dma_count - 1
184 ctxload_dma_loop:
185 ld b32 $r7 D[$r5 + $r6 * 4]
186 add b32 $r8 $r6 0x180
187 shl b32 $r8 8
188 iowr I[$r8] $r7
189 sub b32 $r6 1
190 bra nc #ctxload_dma_loop
191
192 dummyload:
193 // tell PFIFO we're done
194 mov $r5 2
195 iowr I[$r3 + 0x200] $r5
196
197 noctx:
198 and $r2 $r1 0x4
199 cmpu b32 $r2 0
200 bra e #nocmd
201
202 // incoming fifo command.
203 mov $r3 0x1900
204 iord $r2 I[$r3 + 0x100]
205 iord $r3 I[$r3]
206 // extract the method
207 and $r4 $r2 0x7ff
208 // shift the addr to proper position if we need to interrupt later
209 shl b32 $r2 0x10
210
211 // mthd 0 and 0x100 [NAME, NOP]: ignore
212 and $r5 $r4 0x7bf
213 cmpu b32 $r5 0
214 bra e #cmddone
215
216 mov $r5 #engine_cmd_dtable - 0xc0 * 8
217 mov $r6 #engine_cmd_max
218 cmpu b32 $r4 0xc0
219 bra nc #dtable_cmd
220 mov $r5 #common_cmd_dtable - 0x80 * 8
221 mov $r6 #common_cmd_max
222 cmpu b32 $r4 0x80
223 bra nc #dtable_cmd
224 cmpu b32 $r4 0x60
225 bra nc #dma_cmd
226 cmpu b32 $r4 0x50
227 bra ne #illegal_mthd
228
229 // mthd 0x140: PM_TRIGGER
230 mov $r2 0x2200
231 clear b32 $r3
232 sethi $r3 0x20000
233 iowr I[$r2] $r3
234 bra #cmddone
235
236 dma_cmd:
237 // mthd 0x180...: DMA_*
238 cmpu b32 $r4 0x60+#dma_count
239 bra nc #illegal_mthd
240 shl b32 $r5 $r4 2
241 add b32 $r5 (#ctx_dma - 0x60 * 4) & 0xffff
242 bset $r3 0x1e
243 st b32 D[$r5] $r3
244 add b32 $r4 0x180 - 0x60
245 shl b32 $r4 8
246 iowr I[$r4] $r3
247 bra #cmddone
248
249 dtable_cmd:
250 cmpu b32 $r4 $r6
251 bra nc #illegal_mthd
252 shl b32 $r4 3
253 add b32 $r4 $r5
254 ld b32 $r5 D[$r4 + 4]
255 and $r5 $r3
256 cmpu b32 $r5 0
257 bra ne #invalid_bitfield
258 ld b16 $r5 D[$r4]
259 ld b16 $r6 D[$r4 + 2]
260 cmpu b32 $r6 2
261 bra e #cmd_setctx
262 ld b32 $r7 D[$r0 + #ctx_cond_off]
263 and $r6 $r7
264 cmpu b32 $r6 1
265 bra e #cmddone
266 call $r5
267 bra $p1 #dispatch_error
268 bra #cmddone
269
270 cmd_setctx:
271 st b32 D[$r5] $r3
272 bra #cmddone
273
274
275 invalid_bitfield:
276 or $r2 1
277 dispatch_error:
278 illegal_mthd:
279 mov $r4 0x1000
280 iowr I[$r4] $r2
281 iowr I[$r4 + 0x100] $r3
282 mov $r4 0x40
283 iowr I[$r0] $r4
284
285 im_loop:
286 iord $r4 I[$r0 + 0x200]
287 and $r4 0x40
288 cmpu b32 $r4 0
289 bra ne #im_loop
290
291 cmddone:
292 // remove the command from FIFO
293 mov $r3 0x1d00
294 mov $r4 1
295 iowr I[$r3] $r4
296
297 nocmd:
298 // ack the processed interrupts
299 and $r1 $r1 0xc
300 iowr I[$r0 + 0x100] $r1
301iret
302
303cmd_query_get:
304 // if bit 0 of param set, trigger interrupt afterwards.
305 setp $p1 $r3
306 or $r2 3
307
308 // read PTIMER, beware of races...
309 mov $r4 0xb00
310 ptimer_retry:
311 iord $r6 I[$r4 + 0x100]
312 iord $r5 I[$r4]
313 iord $r7 I[$r4 + 0x100]
314 cmpu b32 $r6 $r7
315 bra ne #ptimer_retry
316
317 // prepare the query structure
318 ld b32 $r4 D[$r0 + #ctx_query_counter]
319 st b32 D[$r0 + #swap + 0x0] $r4
320 st b32 D[$r0 + #swap + 0x4] $r0
321 st b32 D[$r0 + #swap + 0x8] $r5
322 st b32 D[$r0 + #swap + 0xc] $r6
323
324 // will use target 0, DMA_QUERY.
325 mov $xtargets $r0
326
327 ld b32 $r4 D[$r0 + #ctx_query_address_high]
328 shl b32 $r4 0x18
329 mov $xdbase $r4
330
331 ld b32 $r4 D[$r0 + #ctx_query_address_low]
332 mov $r5 #swap
333 sethi $r5 0x20000
334 xdst $r4 $r5
335 xdwait
336
337 ret
338
339cmd_cond_mode:
340 // if >= 5, INVALID_ENUM
341 bset $flags $p1
342 or $r2 2
343 cmpu b32 $r3 5
344 bra nc #return
345
346 // otherwise, no error.
347 bclr $flags $p1
348
349 // if < 2, no QUERY object is involved
350 cmpu b32 $r3 2
351 bra nc #cmd_cond_mode_queryful
352
353 xor $r3 1
354 st b32 D[$r0 + #ctx_cond_off] $r3
355 return:
356 ret
357
358 cmd_cond_mode_queryful:
359 // ok, will need to pull a QUERY object, prepare offsets
360 ld b32 $r4 D[$r0 + #ctx_cond_address_high]
361 ld b32 $r5 D[$r0 + #ctx_cond_address_low]
362 and $r6 $r5 0xff
363 shr b32 $r5 8
364 shl b32 $r4 0x18
365 or $r4 $r5
366 mov $xdbase $r4
367 mov $xtargets $r0
368
369 // pull the first one
370 mov $r5 #swap
371 sethi $r5 0x20000
372 xdld $r6 $r5
373
374 // if == 2, only a single QUERY is involved...
375 cmpu b32 $r3 2
376 bra ne #cmd_cond_mode_double
377
378 xdwait
379 ld b32 $r4 D[$r0 + #swap + 4]
380 cmpu b32 $r4 0
381 xbit $r4 $flags z
382 st b32 D[$r0 + #ctx_cond_off] $r4
383 ret
384
385 // ok, we'll need to pull second one too
386 cmd_cond_mode_double:
387 add b32 $r6 0x10
388 add b32 $r5 0x10
389 xdld $r6 $r5
390 xdwait
391
392 // compare COUNTERs
393 ld b32 $r5 D[$r0 + #swap + 0x00]
394 ld b32 $r6 D[$r0 + #swap + 0x10]
395 cmpu b32 $r5 $r6
396 xbit $r4 $flags z
397
398 // compare RESen
399 ld b32 $r5 D[$r0 + #swap + 0x04]
400 ld b32 $r6 D[$r0 + #swap + 0x14]
401 cmpu b32 $r5 $r6
402 xbit $r5 $flags z
403 and $r4 $r5
404
405 // and negate or not, depending on mode
406 cmpu b32 $r3 3
407 xbit $r5 $flags z
408 xor $r4 $r5
409 st b32 D[$r0 + #ctx_cond_off] $r4
410 ret
411
412cmd_wrcache_flush:
413 bclr $flags $p1
414 mov $r2 0x2200
415 clear b32 $r3
416 sethi $r3 0x10000
417 iowr I[$r2] $r3
418 ret
419
420crypt_cmd_mode:
421 // if >= 0xf, INVALID_ENUM
422 bset $flags $p1
423 or $r2 2
424 cmpu b32 $r3 0xf
425 bra nc #crypt_cmd_mode_return
426
427 bclr $flags $p1
428 st b32 D[$r0 + #ctx_mode] $r3
429
430 crypt_cmd_mode_return:
431 ret
432
433crypt_cmd_length:
434 // nop if length == 0
435 cmpu b32 $r3 0
436 bra e #crypt_cmd_mode_return
437
438 // init key, IV
439 cxset 3
440 mov $r4 #ctx_key
441 sethi $r4 0x70000
442 xdst $r0 $r4
443 mov $r4 #ctx_iv
444 sethi $r4 0x60000
445 xdst $r0 $r4
446 xdwait
447 ckeyreg $c7
448
449 // prepare the targets
450 mov $r4 0x2100
451 mov $xtargets $r4
452
453 // prepare src address
454 ld b32 $r4 D[$r0 + #ctx_src_address_high]
455 ld b32 $r5 D[$r0 + #ctx_src_address_low]
456 shr b32 $r8 $r5 8
457 shl b32 $r4 0x18
458 or $r4 $r8
459 and $r5 $r5 0xff
460
461 // prepare dst address
462 ld b32 $r6 D[$r0 + #ctx_dst_address_high]
463 ld b32 $r7 D[$r0 + #ctx_dst_address_low]
464 shr b32 $r8 $r7 8
465 shl b32 $r6 0x18
466 or $r6 $r8
467 and $r7 $r7 0xff
468
469 // find the proper prep & do functions
470 ld b32 $r8 D[$r0 + #ctx_mode]
471 shl b32 $r8 2
472
473 // run prep
474 ld b16 $r9 D[$r8 + #crypt_dtable]
475 call $r9
476
477 // do it
478 ld b16 $r9 D[$r8 + #crypt_dtable + 2]
479 call $r9
480 cxset 1
481 xdwait
482 cxset 0x61
483 xdwait
484 xdwait
485
486 // update src address
487 shr b32 $r8 $r4 0x18
488 shl b32 $r9 $r4 8
489 add b32 $r9 $r5
490 adc b32 $r8 0
491 st b32 D[$r0 + #ctx_src_address_high] $r8
492 st b32 D[$r0 + #ctx_src_address_low] $r9
493
494 // update dst address
495 shr b32 $r8 $r6 0x18
496 shl b32 $r9 $r6 8
497 add b32 $r9 $r7
498 adc b32 $r8 0
499 st b32 D[$r0 + #ctx_dst_address_high] $r8
500 st b32 D[$r0 + #ctx_dst_address_low] $r9
501
502 // pull updated IV
503 cxset 2
504 mov $r4 #ctx_iv
505 sethi $r4 0x60000
506 xdld $r0 $r4
507 xdwait
508
509 ret
510
511
512crypt_copy_prep:
513 cs0begin 2
514 cxsin $c0
515 cxsout $c0
516 ret
517
518crypt_store_prep:
519 cs0begin 1
520 cxsout $c6
521 ret
522
523crypt_ecb_e_prep:
524 cs0begin 3
525 cxsin $c0
526 cenc $c0 $c0
527 cxsout $c0
528 ret
529
530crypt_ecb_d_prep:
531 ckexp $c7 $c7
532 cs0begin 3
533 cxsin $c0
534 cdec $c0 $c0
535 cxsout $c0
536 ret
537
538crypt_cbc_e_prep:
539 cs0begin 4
540 cxsin $c0
541 cxor $c6 $c0
542 cenc $c6 $c6
543 cxsout $c6
544 ret
545
546crypt_cbc_d_prep:
547 ckexp $c7 $c7
548 cs0begin 5
549 cmov $c2 $c6
550 cxsin $c6
551 cdec $c0 $c6
552 cxor $c0 $c2
553 cxsout $c0
554 ret
555
556crypt_pcbc_e_prep:
557 cs0begin 5
558 cxsin $c0
559 cxor $c6 $c0
560 cenc $c6 $c6
561 cxsout $c6
562 cxor $c6 $c0
563 ret
564
565crypt_pcbc_d_prep:
566 ckexp $c7 $c7
567 cs0begin 5
568 cxsin $c0
569 cdec $c1 $c0
570 cxor $c6 $c1
571 cxsout $c6
572 cxor $c6 $c0
573 ret
574
575crypt_cfb_e_prep:
576 cs0begin 4
577 cenc $c6 $c6
578 cxsin $c0
579 cxor $c6 $c0
580 cxsout $c6
581 ret
582
583crypt_cfb_d_prep:
584 cs0begin 4
585 cenc $c0 $c6
586 cxsin $c6
587 cxor $c0 $c6
588 cxsout $c0
589 ret
590
591crypt_ofb_prep:
592 cs0begin 4
593 cenc $c6 $c6
594 cxsin $c0
595 cxor $c0 $c6
596 cxsout $c0
597 ret
598
599crypt_ctr_prep:
600 cs0begin 5
601 cenc $c1 $c6
602 cadd $c6 1
603 cxsin $c0
604 cxor $c0 $c1
605 cxsout $c0
606 ret
607
608crypt_cbc_mac_prep:
609 cs0begin 3
610 cxsin $c0
611 cxor $c6 $c0
612 cenc $c6 $c6
613 ret
614
615crypt_cmac_finish_complete_prep:
616 cs0begin 7
617 cxsin $c0
618 cxor $c6 $c0
619 cxor $c0 $c0
620 cenc $c0 $c0
621 cprecmac $c0 $c0
622 cxor $c6 $c0
623 cenc $c6 $c6
624 ret
625
626crypt_cmac_finish_partial_prep:
627 cs0begin 8
628 cxsin $c0
629 cxor $c6 $c0
630 cxor $c0 $c0
631 cenc $c0 $c0
632 cprecmac $c0 $c0
633 cprecmac $c0 $c0
634 cxor $c6 $c0
635 cenc $c6 $c6
636 ret
637
638// TODO
639crypt_do_in:
640 add b32 $r3 $r5
641 mov $xdbase $r4
642 mov $r9 #swap
643 sethi $r9 0x20000
644 crypt_do_in_loop:
645 xdld $r5 $r9
646 xdwait
647 cxset 0x22
648 xdst $r0 $r9
649 cs0exec 1
650 xdwait
651 add b32 $r5 0x10
652 cmpu b32 $r5 $r3
653 bra ne #crypt_do_in_loop
654 cxset 1
655 xdwait
656 ret
657
658crypt_do_out:
659 add b32 $r3 $r7
660 mov $xdbase $r6
661 mov $r9 #swap
662 sethi $r9 0x20000
663 crypt_do_out_loop:
664 cs0exec 1
665 cxset 0x61
666 xdld $r7 $r9
667 xdst $r7 $r9
668 cxset 1
669 xdwait
670 add b32 $r7 0x10
671 cmpu b32 $r7 $r3
672 bra ne #crypt_do_out_loop
673 ret
674
675crypt_do_inout:
676 add b32 $r3 $r5
677 mov $r9 #swap
678 sethi $r9 0x20000
679 crypt_do_inout_loop:
680 mov $xdbase $r4
681 xdld $r5 $r9
682 xdwait
683 cxset 0x21
684 xdst $r0 $r9
685 cs0exec 1
686 cxset 0x61
687 mov $xdbase $r6
688 xdld $r7 $r9
689 xdst $r7 $r9
690 cxset 1
691 xdwait
692 add b32 $r5 0x10
693 add b32 $r7 0x10
694 cmpu b32 $r5 $r3
695 bra ne #crypt_do_inout_loop
696 ret
697
698.align 0x100