Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Linux/drivers/gpu/drm/nouveau/nvkm/engine/sec/fuc/   (Open Source Betriebssystem Version 6.17.9©)  Datei vom 24.10.2025 mit Größe 12 kB image not shown  

Quelle  g98.fuc0s   Sprache: unbekannt

 
Spracherkennung für: .fuc0s vermutete Sprache: Unknown {[0] [0] [0]} [Methode: Schwerpunktbildung, einfache Gewichte, sechs Dimensionen]

/*
 *  fuc microcode for g98 sec engine
 *  Copyright (C) 2010  Marcin Kościelnicki
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */

.section #g98_sec_data

ctx_dma:
ctx_dma_query:  .b32 0
ctx_dma_src:  .b32 0
ctx_dma_dst:  .b32 0
.equ #dma_count 3
ctx_query_address_high: .b32 0
ctx_query_address_low: .b32 0
ctx_query_counter: .b32 0
ctx_cond_address_high: .b32 0
ctx_cond_address_low: .b32 0
ctx_cond_off:  .b32 0
ctx_src_address_high: .b32 0
ctx_src_address_low: .b32 0
ctx_dst_address_high: .b32 0
ctx_dst_address_low: .b32 0
ctx_mode:  .b32 0
.align 16
ctx_key:  .skip 16
ctx_iv:   .skip 16

.align 0x80
swap:
.skip 32

.align 8
common_cmd_dtable:
.b32 #ctx_query_address_high + 0x20000 ~0xff
.b32 #ctx_query_address_low + 0x20000 ~0xfffffff0
.b32 #ctx_query_counter + 0x20000 ~0xffffffff
.b32 #cmd_query_get + 0x00000 ~1
.b32 #ctx_cond_address_high + 0x20000 ~0xff
.b32 #ctx_cond_address_low + 0x20000 ~0xfffffff0
.b32 #cmd_cond_mode + 0x00000 ~7
.b32 #cmd_wrcache_flush + 0x00000 ~0
.equ #common_cmd_max 0x88


.align 8
engine_cmd_dtable:
.b32 #ctx_key + 0x0 + 0x20000 ~0xffffffff
.b32 #ctx_key + 0x4 + 0x20000 ~0xffffffff
.b32 #ctx_key + 0x8 + 0x20000 ~0xffffffff
.b32 #ctx_key + 0xc + 0x20000 ~0xffffffff
.b32 #ctx_iv + 0x0 + 0x20000 ~0xffffffff
.b32 #ctx_iv + 0x4 + 0x20000 ~0xffffffff
.b32 #ctx_iv + 0x8 + 0x20000 ~0xffffffff
.b32 #ctx_iv + 0xc + 0x20000 ~0xffffffff
.b32 #ctx_src_address_high + 0x20000 ~0xff
.b32 #ctx_src_address_low + 0x20000 ~0xfffffff0
.b32 #ctx_dst_address_high + 0x20000 ~0xff
.b32 #ctx_dst_address_low + 0x20000 ~0xfffffff0
.b32 #sec_cmd_mode + 0x00000 ~0xf
.b32 #sec_cmd_length + 0x10000 ~0x0ffffff0
.equ #engine_cmd_max 0xce

.align 4
sec_dtable:
.b16 #sec_copy_prep #sec_do_inout
.b16 #sec_store_prep #sec_do_out
.b16 #sec_ecb_e_prep #sec_do_inout
.b16 #sec_ecb_d_prep #sec_do_inout
.b16 #sec_cbc_e_prep #sec_do_inout
.b16 #sec_cbc_d_prep #sec_do_inout
.b16 #sec_pcbc_e_prep #sec_do_inout
.b16 #sec_pcbc_d_prep #sec_do_inout
.b16 #sec_cfb_e_prep #sec_do_inout
.b16 #sec_cfb_d_prep #sec_do_inout
.b16 #sec_ofb_prep #sec_do_inout
.b16 #sec_ctr_prep #sec_do_inout
.b16 #sec_cbc_mac_prep #sec_do_in
.b16 #sec_cmac_finish_complete_prep #sec_do_in
.b16 #sec_cmac_finish_partial_prep #sec_do_in

.align 0x100

.section #g98_sec_code

 // $r0 is always set to 0 in our code - this allows some space savings.
 clear b32 $r0

 // set up the interrupt handler
 mov $r1 #ih
 mov $iv0 $r1

 // init stack pointer
 mov $sp $r0

 // set interrupt dispatch - route timer, fifo, ctxswitch to i0, others to host
 movw $r1 0xfff0
 sethi $r1 0
 mov $r2 0x400
 iowr I[$r2 + 0x300] $r1

 // enable the interrupts
 or $r1 0xc
 iowr I[$r2] $r1

 // enable fifo access and context switching
 mov $r1 3
 mov $r2 0x1200
 iowr I[$r2] $r1

 // enable i0 delivery
 bset $flags ie0

 // sleep forver, waking only for interrupts.
 bset $flags $p0
 spin:
 sleep $p0
 bra #spin

// i0 handler
ih:
 // see which interrupts we got
 iord $r1 I[$r0 + 0x200]

 and $r2 $r1 0x8
 cmpu b32 $r2 0
 bra e #noctx

  // context switch... prepare the regs for xfer
  mov $r2 0x7700
  mov $xtargets $r2
  mov $xdbase $r0
  // 128-byte context.
  mov $r2 0
  sethi $r2 0x50000

  // read current channel
  mov $r3 0x1400
  iord $r4 I[$r3]
  // if bit 30 set, it's active, so we have to unload it first.
  shl b32 $r5 $r4 1
  cmps b32 $r5 0
  bra nc #ctxload

   // unload the current channel - save the context
   xdst $r0 $r2
   xdwait
   // and clear bit 30, then write back
   bclr $r4 0x1e
   iowr I[$r3] $r4
   // tell PFIFO we unloaded
   mov $r4 1
   iowr I[$r3 + 0x200] $r4

  bra #noctx

  ctxload:
   // no channel loaded - perhaps we're requested to load one
   iord $r4 I[$r3 + 0x100]
   shl b32 $r15 $r4 1
   cmps b32 $r15 0
   // if bit 30 of next channel not set, probably PFIFO is just
   // killing a context. do a faux load, without the active bit.
   bra nc #dummyload

    // ok, do a real context load.
    xdld $r0 $r2
    xdwait
    mov $r5 #ctx_dma
    mov $r6 #dma_count - 1
    ctxload_dma_loop:
     ld b32 $r7 D[$r5 + $r6 * 4]
     add b32 $r8 $r6 0x180
     shl b32 $r8 8
     iowr I[$r8] $r7
     sub b32 $r6 1
    bra nc #ctxload_dma_loop

   dummyload:
   // tell PFIFO we're done
   mov $r5 2
   iowr I[$r3 + 0x200] $r5

 noctx:
 and $r2 $r1 0x4
 cmpu b32 $r2 0
 bra e #nocmd

  // incoming fifo command.
  mov $r3 0x1900
  iord $r2 I[$r3 + 0x100]
  iord $r3 I[$r3]
  // extract the method
  and $r4 $r2 0x7ff
  // shift the addr to proper position if we need to interrupt later
  shl b32 $r2 0x10

  // mthd 0 and 0x100 [NAME, NOP]: ignore
  and $r5 $r4 0x7bf
  cmpu b32 $r5 0
  bra e #cmddone

  mov $r5 #engine_cmd_dtable - 0xc0 * 8
  mov $r6 #engine_cmd_max
  cmpu b32 $r4 0xc0
  bra nc #dtable_cmd
  mov $r5 #common_cmd_dtable - 0x80 * 8
  mov $r6 #common_cmd_max
  cmpu b32 $r4 0x80
  bra nc #dtable_cmd
  cmpu b32 $r4 0x60
  bra nc #dma_cmd
  cmpu b32 $r4 0x50
  bra ne #illegal_mthd

   // mthd 0x140: PM_TRIGGER
   mov $r2 0x2200
   clear b32 $r3
   sethi $r3 0x20000
   iowr I[$r2] $r3
   bra #cmddone

  dma_cmd:
   // mthd 0x180...: DMA_*
   cmpu b32 $r4 0x60+#dma_count
   bra nc #illegal_mthd
   shl b32 $r5 $r4 2
   add b32 $r5 ((#ctx_dma - 0x60 * 4) & 0xffff)
   bset $r3 0x1e
   st b32 D[$r5] $r3
   add b32 $r4 0x180 - 0x60
   shl b32 $r4 8
   iowr I[$r4] $r3
   bra #cmddone

  dtable_cmd:
   cmpu b32 $r4 $r6
   bra nc #illegal_mthd
   shl b32 $r4 3
   add b32 $r4 $r5
   ld b32 $r5 D[$r4 + 4]
   and $r5 $r3
   cmpu b32 $r5 0
   bra ne #invalid_bitfield
   ld b16 $r5 D[$r4]
   ld b16 $r6 D[$r4 + 2]
   cmpu b32 $r6 2
   bra e #cmd_setctx
   ld b32 $r7 D[$r0 + #ctx_cond_off]
   and $r6 $r7
   cmpu b32 $r6 1
   bra e #cmddone
   call $r5
   bra $p1 #dispatch_error
   bra #cmddone

  cmd_setctx:
   st b32 D[$r5] $r3
   bra #cmddone


  invalid_bitfield:
   or $r2 1
  dispatch_error:
  illegal_mthd:
   mov $r4 0x1000
   iowr I[$r4] $r2
   iowr I[$r4 + 0x100] $r3
   mov $r4 0x40
   iowr I[$r0] $r4

   im_loop:
    iord $r4 I[$r0 + 0x200]
    and $r4 0x40
    cmpu b32 $r4 0
   bra ne #im_loop

  cmddone:
  // remove the command from FIFO
  mov $r3 0x1d00
  mov $r4 1
  iowr I[$r3] $r4

 nocmd:
 // ack the processed interrupts
 and $r1 $r1 0xc
 iowr I[$r0 + 0x100] $r1
iret

cmd_query_get:
 // if bit 0 of param set, trigger interrupt afterwards.
 setp $p1 $r3
 or $r2 3

 // read PTIMER, beware of races...
 mov $r4 0xb00
 ptimer_retry:
  iord $r6 I[$r4 + 0x100]
  iord $r5 I[$r4]
  iord $r7 I[$r4 + 0x100]
  cmpu b32 $r6 $r7
 bra ne #ptimer_retry

 // prepare the query structure
 ld b32 $r4 D[$r0 + #ctx_query_counter]
 st b32 D[$r0 + #swap + 0x0] $r4
 st b32 D[$r0 + #swap + 0x4] $r0
 st b32 D[$r0 + #swap + 0x8] $r5
 st b32 D[$r0 + #swap + 0xc] $r6

 // will use target 0, DMA_QUERY.
 mov $xtargets $r0

 ld b32 $r4 D[$r0 + #ctx_query_address_high]
 shl b32 $r4 0x18
 mov $xdbase $r4

 ld b32 $r4 D[$r0 + #ctx_query_address_low]
 mov $r5 #swap
 sethi $r5 0x20000
 xdst $r4 $r5
 xdwait

 ret

cmd_cond_mode:
 // if >= 5, INVALID_ENUM
 bset $flags $p1
 or $r2 2
 cmpu b32 $r3 5
 bra nc #return

 // otherwise, no error.
 bclr $flags $p1

 // if < 2, no QUERY object is involved
 cmpu b32 $r3 2
 bra nc #cmd_cond_mode_queryful

  xor $r3 1
  st b32 D[$r0 + #ctx_cond_off] $r3
 return:
  ret

 cmd_cond_mode_queryful:
 // ok, will need to pull a QUERY object, prepare offsets
 ld b32 $r4 D[$r0 + #ctx_cond_address_high]
 ld b32 $r5 D[$r0 + #ctx_cond_address_low]
 and $r6 $r5 0xff
 shr b32 $r5 8
 shl b32 $r4 0x18
 or $r4 $r5
 mov $xdbase $r4
 mov $xtargets $r0

 // pull the first one
 mov $r5 #swap
 sethi $r5 0x20000
 xdld $r6 $r5

 // if == 2, only a single QUERY is involved...
 cmpu b32 $r3 2
 bra ne #cmd_cond_mode_double

  xdwait
  ld b32 $r4 D[$r0 + #swap + 4]
  cmpu b32 $r4 0
  xbit $r4 $flags z
  st b32 D[$r0 + #ctx_cond_off] $r4
  ret

 // ok, we'll need to pull second one too
 cmd_cond_mode_double:
 add b32 $r6 0x10
 add b32 $r5 0x10
 xdld $r6 $r5
 xdwait

 // compare COUNTERs
 ld b32 $r5 D[$r0 + #swap + 0x00]
 ld b32 $r6 D[$r0 + #swap + 0x10]
 cmpu b32 $r5 $r6
 xbit $r4 $flags z

 // compare RESen
 ld b32 $r5 D[$r0 + #swap + 0x04]
 ld b32 $r6 D[$r0 + #swap + 0x14]
 cmpu b32 $r5 $r6
 xbit $r5 $flags z
 and $r4 $r5

 // and negate or not, depending on mode
 cmpu b32 $r3 3
 xbit $r5 $flags z
 xor $r4 $r5
 st b32 D[$r0 + #ctx_cond_off] $r4
 ret

cmd_wrcache_flush:
 bclr $flags $p1
 mov $r2 0x2200
 clear b32 $r3
 sethi $r3 0x10000
 iowr I[$r2] $r3
 ret

sec_cmd_mode:
 // if >= 0xf, INVALID_ENUM
 bset $flags $p1
 or $r2 2
 cmpu b32 $r3 0xf
 bra nc #sec_cmd_mode_return

  bclr $flags $p1
  st b32 D[$r0 + #ctx_mode] $r3

 sec_cmd_mode_return:
 ret

sec_cmd_length:
 // nop if length == 0
 cmpu b32 $r3 0
 bra e #sec_cmd_mode_return

 // init key, IV
 cxset 3
 mov $r4 #ctx_key
 sethi $r4 0x70000
 xdst $r0 $r4
 mov $r4 #ctx_iv
 sethi $r4 0x60000
 xdst $r0 $r4
 xdwait
 ckeyreg $c7

 // prepare the targets
 mov $r4 0x2100
 mov $xtargets $r4

 // prepare src address
 ld b32 $r4 D[$r0 + #ctx_src_address_high]
 ld b32 $r5 D[$r0 + #ctx_src_address_low]
 shr b32 $r8 $r5 8
 shl b32 $r4 0x18
 or $r4 $r8
 and $r5 $r5 0xff

 // prepare dst address
 ld b32 $r6 D[$r0 + #ctx_dst_address_high]
 ld b32 $r7 D[$r0 + #ctx_dst_address_low]
 shr b32 $r8 $r7 8
 shl b32 $r6 0x18
 or $r6 $r8
 and $r7 $r7 0xff

 // find the proper prep & do functions
 ld b32 $r8 D[$r0 + #ctx_mode]
 shl b32 $r8 2

 // run prep
 ld b16 $r9 D[$r8 + #sec_dtable]
 call $r9

 // do it
 ld b16 $r9 D[$r8 + #sec_dtable + 2]
 call $r9
 cxset 1
 xdwait
 cxset 0x61
 xdwait
 xdwait

 // update src address
 shr b32 $r8 $r4 0x18
 shl b32 $r9 $r4 8
 add b32 $r9 $r5
 adc b32 $r8 0
 st b32 D[$r0 + #ctx_src_address_high] $r8
 st b32 D[$r0 + #ctx_src_address_low] $r9

 // update dst address
 shr b32 $r8 $r6 0x18
 shl b32 $r9 $r6 8
 add b32 $r9 $r7
 adc b32 $r8 0
 st b32 D[$r0 + #ctx_dst_address_high] $r8
 st b32 D[$r0 + #ctx_dst_address_low] $r9

 // pull updated IV
 cxset 2
 mov $r4 #ctx_iv
 sethi $r4 0x60000
 xdld $r0 $r4
 xdwait

 ret


sec_copy_prep:
 cs0begin 2
  cxsin $c0
  cxsout $c0
 ret

sec_store_prep:
 cs0begin 1
  cxsout $c6
 ret

sec_ecb_e_prep:
 cs0begin 3
  cxsin $c0
  cenc $c0 $c0
  cxsout $c0
 ret

sec_ecb_d_prep:
 ckexp $c7 $c7
 cs0begin 3
  cxsin $c0
  cdec $c0 $c0
  cxsout $c0
 ret

sec_cbc_e_prep:
 cs0begin 4
  cxsin $c0
  cxor $c6 $c0
  cenc $c6 $c6
  cxsout $c6
 ret

sec_cbc_d_prep:
 ckexp $c7 $c7
 cs0begin 5
  cmov $c2 $c6
  cxsin $c6
  cdec $c0 $c6
  cxor $c0 $c2
  cxsout $c0
 ret

sec_pcbc_e_prep:
 cs0begin 5
  cxsin $c0
  cxor $c6 $c0
  cenc $c6 $c6
  cxsout $c6
  cxor $c6 $c0
 ret

sec_pcbc_d_prep:
 ckexp $c7 $c7
 cs0begin 5
  cxsin $c0
  cdec $c1 $c0
  cxor $c6 $c1
  cxsout $c6
  cxor $c6 $c0
 ret

sec_cfb_e_prep:
 cs0begin 4
  cenc $c6 $c6
  cxsin $c0
  cxor $c6 $c0
  cxsout $c6
 ret

sec_cfb_d_prep:
 cs0begin 4
  cenc $c0 $c6
  cxsin $c6
  cxor $c0 $c6
  cxsout $c0
 ret

sec_ofb_prep:
 cs0begin 4
  cenc $c6 $c6
  cxsin $c0
  cxor $c0 $c6
  cxsout $c0
 ret

sec_ctr_prep:
 cs0begin 5
  cenc $c1 $c6
  cadd $c6 1
  cxsin $c0
  cxor $c0 $c1
  cxsout $c0
 ret

sec_cbc_mac_prep:
 cs0begin 3
  cxsin $c0
  cxor $c6 $c0
  cenc $c6 $c6
 ret

sec_cmac_finish_complete_prep:
 cs0begin 7
  cxsin $c0
  cxor $c6 $c0
  cxor $c0 $c0
  cenc $c0 $c0
  cprecmac $c0 $c0
  cxor $c6 $c0
  cenc $c6 $c6
 ret

sec_cmac_finish_partial_prep:
 cs0begin 8
  cxsin $c0
  cxor $c6 $c0
  cxor $c0 $c0
  cenc $c0 $c0
  cprecmac $c0 $c0
  cprecmac $c0 $c0
  cxor $c6 $c0
  cenc $c6 $c6
 ret

// TODO
sec_do_in:
 add b32 $r3 $r5
 mov $xdbase $r4
 mov $r9 #swap
 sethi $r9 0x20000
 sec_do_in_loop:
  xdld $r5 $r9
  xdwait
  cxset 0x22
  xdst $r0 $r9
  cs0exec 1
  xdwait
  add b32 $r5 0x10
  cmpu b32 $r5 $r3
 bra ne #sec_do_in_loop
 cxset 1
 xdwait
 ret

sec_do_out:
 add b32 $r3 $r7
 mov $xdbase $r6
 mov $r9 #swap
 sethi $r9 0x20000
 sec_do_out_loop:
  cs0exec 1
  cxset 0x61
  xdld $r7 $r9
  xdst $r7 $r9
  cxset 1
  xdwait
  add b32 $r7 0x10
  cmpu b32 $r7 $r3
 bra ne #sec_do_out_loop
 ret

sec_do_inout:
 add b32 $r3 $r5
 mov $r9 #swap
 sethi $r9 0x20000
 sec_do_inout_loop:
  mov $xdbase $r4
  xdld $r5 $r9
  xdwait
  cxset 0x21
  xdst $r0 $r9
  cs0exec 1
  cxset 0x61
  mov $xdbase $r6
  xdld $r7 $r9
  xdst $r7 $r9
  cxset 1
  xdwait
  add b32 $r5 0x10
  add b32 $r7 0x10
  cmpu b32 $r5 $r3
 bra ne #sec_do_inout_loop
 ret

.align 0x100

[ Dauer der Verarbeitung: 0.48 Sekunden  ]