freedreno/afuc: Decode (sdsN) modifier
This removes the last unknown flag from read/write instructions. Because we now handle the write in CP_SET_DRAW_STATE more correctly when emulating, we also have to update the control register definitions and draw state emulation code to adjust. Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/26691>
This commit is contained in:
parent
55985b7301
commit
d01be55340
12 changed files with 317 additions and 255 deletions
|
|
@ -2,37 +2,37 @@
|
|||
; Version: 01000001
|
||||
|
||||
[01000001]
|
||||
[0100007e]
|
||||
[01000081]
|
||||
mov $01, 0x830 ; CP_SQE_INSTR_BASE
|
||||
mov $02, 0x2
|
||||
cwrite $01, [$00 + @REG_READ_ADDR], 0x0
|
||||
cwrite $02, [$00 + @REG_READ_DWORDS], 0x0
|
||||
cwrite $01, [$00 + @REG_READ_ADDR]
|
||||
cwrite $02, [$00 + @REG_READ_DWORDS]
|
||||
mov $01, $regdata
|
||||
mov $02, $regdata
|
||||
add $01, $01, 0x4
|
||||
addhi $02, $02, 0x0
|
||||
mov $03, 0x1
|
||||
cwrite $01, [$00 + @MEM_READ_ADDR], 0x0
|
||||
cwrite $02, [$00 + @MEM_READ_ADDR+0x1], 0x0
|
||||
cwrite $03, [$00 + @MEM_READ_DWORDS], 0x0
|
||||
cwrite $01, [$00 + @MEM_READ_ADDR]
|
||||
cwrite $02, [$00 + @MEM_READ_ADDR+0x1]
|
||||
cwrite $03, [$00 + @MEM_READ_DWORDS]
|
||||
rot $04, $memdata, 0x8
|
||||
ushr $04, $04, 0x6
|
||||
sub $04, $04, 0x4
|
||||
add $01, $01, $04
|
||||
addhi $02, $02, 0x0
|
||||
mov $rem, 0x80
|
||||
cwrite $01, [$00 + @MEM_READ_ADDR], 0x0
|
||||
cwrite $02, [$00 + @MEM_READ_ADDR+0x1], 0x0
|
||||
cwrite $02, [$00 + @LOAD_STORE_HI], 0x0
|
||||
cwrite $rem, [$00 + @MEM_READ_DWORDS], 0x0
|
||||
cwrite $00, [$00 + @PACKET_TABLE_WRITE_ADDR], 0x0
|
||||
(rep)cwrite $memdata, [$00 + @PACKET_TABLE_WRITE], 0x0
|
||||
cwrite $01, [$00 + @MEM_READ_ADDR]
|
||||
cwrite $02, [$00 + @MEM_READ_ADDR+0x1]
|
||||
cwrite $02, [$00 + @LOAD_STORE_HI]
|
||||
cwrite $rem, [$00 + @MEM_READ_DWORDS]
|
||||
cwrite $00, [$00 + @PACKET_TABLE_WRITE_ADDR]
|
||||
(rep)cwrite $memdata, [$00 + @PACKET_TABLE_WRITE]
|
||||
mov $02, 0x883 ; CP_SCRATCH[0].REG
|
||||
mov $03, 0xbeef
|
||||
mov $04, 0xdead << 16
|
||||
or $03, $03, $04
|
||||
cwrite $02, [$00 + @REG_WRITE_ADDR], 0x0
|
||||
cwrite $03, [$00 + @REG_WRITE], 0x0
|
||||
cwrite $02, [$00 + @REG_WRITE_ADDR]
|
||||
cwrite $03, [$00 + @REG_WRITE]
|
||||
waitin
|
||||
mov $01, $data
|
||||
|
||||
|
|
@ -52,48 +52,53 @@ mov $01, $data
|
|||
|
||||
CP_SCRATCH_WRITE:
|
||||
mov $02, 0xff
|
||||
(rep)cwrite $data, [$02 + 0x1]!, 0x0
|
||||
(rep)cwrite $data, [$02 + 0x1]!
|
||||
waitin
|
||||
mov $01, $data
|
||||
|
||||
CP_SET_DRAW_STATE:
|
||||
(rep)(sds2)cwrite $data, [$00 + @DRAW_STATE_SET_HDR]
|
||||
waitin
|
||||
mov $01, $data
|
||||
|
||||
CP_SET_BIN_DATA5:
|
||||
sread $02, [$00 + %SP], 0x0
|
||||
swrite $02, [$00 + %SP], 0x0
|
||||
sread $02, [$00 + %SP]
|
||||
swrite $02, [$00 + %SP]
|
||||
mov $02, 0x7
|
||||
(rep)swrite $data, [$02 + 0x1]!, 0x0
|
||||
(rep)swrite $data, [$02 + 0x1]!
|
||||
waitin
|
||||
mov $01, $data
|
||||
|
||||
CP_SET_SECURE_MODE:
|
||||
mov $02, $data
|
||||
setsecure $02, #l58
|
||||
l56:
|
||||
jump #l56
|
||||
setsecure $02, #l61
|
||||
l59:
|
||||
jump #l59
|
||||
nop
|
||||
l58:
|
||||
l61:
|
||||
waitin
|
||||
mov $01, $data
|
||||
|
||||
fxn60:
|
||||
l60:
|
||||
fxn63:
|
||||
l63:
|
||||
cmp $04, $02, $03
|
||||
breq $04, b0, #l67
|
||||
brne $04, b1, #l65
|
||||
breq $04, b2, #l60
|
||||
breq $04, b0, #l70
|
||||
brne $04, b1, #l68
|
||||
breq $04, b2, #l63
|
||||
sub $03, $03, $02
|
||||
l65:
|
||||
jump #l60
|
||||
l68:
|
||||
jump #l63
|
||||
sub $02, $02, $03
|
||||
l67:
|
||||
l70:
|
||||
ret
|
||||
nop
|
||||
|
||||
CP_REG_RMW:
|
||||
cwrite $data, [$00 + @REG_READ_ADDR], 0x0
|
||||
cwrite $data, [$00 + @REG_READ_ADDR]
|
||||
add $02, $regdata, 0x42
|
||||
addhi $03, $00, $regdata
|
||||
sub $02, $02, $regdata
|
||||
call #fxn60
|
||||
call #fxn63
|
||||
subhi $03, $03, $regdata
|
||||
and $02, $02, $regdata
|
||||
or $02, $02, 0x1
|
||||
|
|
@ -118,39 +123,39 @@ mov $03, $data
|
|||
mov $04, $data
|
||||
mov $05, $data
|
||||
mov $06, $data
|
||||
l96:
|
||||
breq $06, 0x0, #l102
|
||||
cwrite $03, [$00 + @LOAD_STORE_HI], 0x0
|
||||
load $07, [$02 + 0x4]!, 0x0
|
||||
cwrite $05, [$00 + @LOAD_STORE_HI], 0x0
|
||||
jump #l96
|
||||
store $07, [$04 + 0x4]!, 0x0
|
||||
l102:
|
||||
l99:
|
||||
breq $06, 0x0, #l105
|
||||
cwrite $03, [$00 + @LOAD_STORE_HI]
|
||||
load $07, [$02 + 0x4]!
|
||||
cwrite $05, [$00 + @LOAD_STORE_HI]
|
||||
jump #l99
|
||||
store $07, [$04 + 0x4]!
|
||||
l105:
|
||||
waitin
|
||||
mov $01, $data
|
||||
|
||||
CP_MEM_TO_MEM:
|
||||
cwrite $data, [$00 + @MEM_READ_ADDR], 0x0
|
||||
cwrite $data, [$00 + @MEM_READ_ADDR+0x1], 0x0
|
||||
cwrite $data, [$00 + @MEM_READ_ADDR]
|
||||
cwrite $data, [$00 + @MEM_READ_ADDR+0x1]
|
||||
mov $02, $data
|
||||
cwrite $data, [$00 + @LOAD_STORE_HI], 0x0
|
||||
cwrite $data, [$00 + @LOAD_STORE_HI]
|
||||
mov $rem, $data
|
||||
cwrite $rem, [$00 + @MEM_READ_DWORDS], 0x0
|
||||
(rep)store $memdata, [$02 + 0x4]!, 0x0
|
||||
cwrite $rem, [$00 + @MEM_READ_DWORDS]
|
||||
(rep)store $memdata, [$02 + 0x4]!
|
||||
waitin
|
||||
mov $01, $data
|
||||
|
||||
IN_PREEMPT:
|
||||
cread $02, [$00 + 0x101], 0x0
|
||||
brne $02, 0x1, #l122
|
||||
cread $02, [$00 + 0x101]
|
||||
brne $02, 0x1, #l125
|
||||
nop
|
||||
preemptleave #l56
|
||||
preemptleave #l59
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
waitin
|
||||
mov $01, $data
|
||||
l122:
|
||||
l125:
|
||||
iret
|
||||
nop
|
||||
|
||||
|
|
@ -208,7 +213,6 @@ CP_SET_BIN_DATA5_OFFSET:
|
|||
CP_SET_CONSTANT:
|
||||
CP_SET_CTXSWITCH_IB:
|
||||
CP_SET_DRAW_INIT_FLAGS:
|
||||
CP_SET_DRAW_STATE:
|
||||
CP_SET_MARKER:
|
||||
CP_SET_MODE:
|
||||
CP_SET_PROTECTED_MODE:
|
||||
|
|
@ -275,131 +279,131 @@ UNKN96:
|
|||
UNKN97:
|
||||
waitin
|
||||
mov $01, $data
|
||||
[0000007c]
|
||||
[0000007c]
|
||||
[0000007c]
|
||||
[0000007c]
|
||||
[0000007c]
|
||||
[0000007c]
|
||||
[0000007c]
|
||||
[0000007c]
|
||||
[0000007c]
|
||||
[0000007c]
|
||||
[0000007c]
|
||||
[0000007c]
|
||||
[0000007c]
|
||||
[0000007c]
|
||||
[0000007c]
|
||||
[00000071]
|
||||
[0000007c]
|
||||
[0000007c]
|
||||
[0000007c]
|
||||
[0000007c]
|
||||
[0000007c]
|
||||
[0000007c]
|
||||
[0000007c]
|
||||
[0000007c]
|
||||
[0000007c]
|
||||
[0000007c]
|
||||
[0000007c]
|
||||
[0000007c]
|
||||
[0000007c]
|
||||
[0000007c]
|
||||
[0000007c]
|
||||
[0000007c]
|
||||
[0000007c]
|
||||
[00000045]
|
||||
[0000007c]
|
||||
[0000007c]
|
||||
[0000007c]
|
||||
[0000007c]
|
||||
[0000007c]
|
||||
[0000007c]
|
||||
[0000007c]
|
||||
[0000007c]
|
||||
[0000007c]
|
||||
[0000007c]
|
||||
[0000007c]
|
||||
[0000007c]
|
||||
[0000007c]
|
||||
[00000030]
|
||||
[0000007c]
|
||||
[0000007c]
|
||||
[0000007c]
|
||||
[0000007c]
|
||||
[0000007c]
|
||||
[0000007c]
|
||||
[0000007c]
|
||||
[0000007c]
|
||||
[0000007c]
|
||||
[0000007c]
|
||||
[0000007c]
|
||||
[0000007c]
|
||||
[0000007c]
|
||||
[0000007f]
|
||||
[0000007f]
|
||||
[0000007f]
|
||||
[0000007f]
|
||||
[0000007f]
|
||||
[0000007f]
|
||||
[0000007f]
|
||||
[0000007f]
|
||||
[0000007f]
|
||||
[0000007f]
|
||||
[0000007f]
|
||||
[0000007f]
|
||||
[0000007f]
|
||||
[0000007f]
|
||||
[0000007f]
|
||||
[00000074]
|
||||
[0000007f]
|
||||
[0000007f]
|
||||
[0000007f]
|
||||
[0000007f]
|
||||
[0000007f]
|
||||
[0000007f]
|
||||
[0000007f]
|
||||
[0000007f]
|
||||
[0000007f]
|
||||
[0000007f]
|
||||
[0000007f]
|
||||
[0000007f]
|
||||
[0000007f]
|
||||
[0000007f]
|
||||
[0000007f]
|
||||
[0000007f]
|
||||
[0000007f]
|
||||
[00000048]
|
||||
[0000007f]
|
||||
[0000007f]
|
||||
[0000007f]
|
||||
[0000007f]
|
||||
[0000007f]
|
||||
[0000007f]
|
||||
[0000007f]
|
||||
[0000007f]
|
||||
[0000007f]
|
||||
[0000007f]
|
||||
[0000007f]
|
||||
[0000007f]
|
||||
[0000007f]
|
||||
[00000033]
|
||||
[0000007f]
|
||||
[0000007f]
|
||||
[0000007f]
|
||||
[0000007f]
|
||||
[0000007f]
|
||||
[0000007f]
|
||||
[0000007f]
|
||||
[0000007f]
|
||||
[0000007f]
|
||||
[0000007f]
|
||||
[0000007f]
|
||||
[0000007f]
|
||||
[0000007f]
|
||||
[00000025]
|
||||
[0000007c]
|
||||
[0000007c]
|
||||
[0000007c]
|
||||
[0000007c]
|
||||
[0000007c]
|
||||
[0000007c]
|
||||
[0000007c]
|
||||
[0000007c]
|
||||
[0000007c]
|
||||
[0000007c]
|
||||
[0000007f]
|
||||
[0000007f]
|
||||
[0000007f]
|
||||
[0000007f]
|
||||
[0000007f]
|
||||
[00000030]
|
||||
[0000007f]
|
||||
[0000007f]
|
||||
[0000007f]
|
||||
[0000007f]
|
||||
[00000022]
|
||||
[0000007c]
|
||||
[0000007c]
|
||||
[0000007c]
|
||||
[0000007f]
|
||||
[0000007f]
|
||||
[0000007f]
|
||||
[0000002c]
|
||||
[0000007c]
|
||||
[0000007c]
|
||||
[0000007c]
|
||||
[0000007c]
|
||||
[0000007c]
|
||||
[0000007c]
|
||||
[0000007c]
|
||||
[0000007c]
|
||||
[0000007c]
|
||||
[0000007c]
|
||||
[0000007c]
|
||||
[0000007c]
|
||||
[0000007c]
|
||||
[0000007c]
|
||||
[0000007c]
|
||||
[0000007c]
|
||||
[0000007c]
|
||||
[0000007c]
|
||||
[0000007c]
|
||||
[0000007c]
|
||||
[0000007c]
|
||||
[0000007c]
|
||||
[0000007c]
|
||||
[0000007c]
|
||||
[0000007c]
|
||||
[00000036]
|
||||
[0000007c]
|
||||
[0000007c]
|
||||
[0000007c]
|
||||
[0000007c]
|
||||
[0000007c]
|
||||
[0000007c]
|
||||
[0000007c]
|
||||
[0000007c]
|
||||
[0000007c]
|
||||
[0000007c]
|
||||
[0000007c]
|
||||
[0000007c]
|
||||
[00000068]
|
||||
[0000007c]
|
||||
[0000005b]
|
||||
[0000007c]
|
||||
[0000007c]
|
||||
[0000007c]
|
||||
[0000007c]
|
||||
[0000007c]
|
||||
[0000007c]
|
||||
[0000007c]
|
||||
[0000007c]
|
||||
[0000007c]
|
||||
[0000007c]
|
||||
[0000007f]
|
||||
[0000007f]
|
||||
[0000007f]
|
||||
[0000007f]
|
||||
[0000007f]
|
||||
[0000007f]
|
||||
[0000007f]
|
||||
[0000007f]
|
||||
[0000007f]
|
||||
[0000007f]
|
||||
[0000007f]
|
||||
[0000007f]
|
||||
[0000007f]
|
||||
[0000007f]
|
||||
[0000007f]
|
||||
[0000007f]
|
||||
[0000007f]
|
||||
[0000007f]
|
||||
[0000007f]
|
||||
[0000007f]
|
||||
[0000007f]
|
||||
[0000007f]
|
||||
[0000007f]
|
||||
[0000007f]
|
||||
[0000007f]
|
||||
[00000039]
|
||||
[0000007f]
|
||||
[0000007f]
|
||||
[0000007f]
|
||||
[0000007f]
|
||||
[0000007f]
|
||||
[0000007f]
|
||||
[0000007f]
|
||||
[0000007f]
|
||||
[0000007f]
|
||||
[0000007f]
|
||||
[0000007f]
|
||||
[0000007f]
|
||||
[0000006b]
|
||||
[0000007f]
|
||||
[0000005e]
|
||||
[0000007f]
|
||||
[0000007f]
|
||||
[0000007f]
|
||||
[0000007f]
|
||||
[0000007f]
|
||||
[0000007f]
|
||||
[0000007f]
|
||||
[0000007f]
|
||||
[0000007f]
|
||||
[0000007f]
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -32,8 +32,8 @@ loc02:
|
|||
; packet table loading:
|
||||
mov $01, 0x0830 ; CP_SQE_INSTR_BASE
|
||||
mov $02, 0x0002
|
||||
cwrite $01, [$00 + @REG_READ_ADDR], 0x0
|
||||
cwrite $02, [$00 + @REG_READ_DWORDS], 0x0
|
||||
cwrite $01, [$00 + @REG_READ_ADDR]
|
||||
cwrite $02, [$00 + @REG_READ_DWORDS]
|
||||
; move hi/lo of SQE fw addrs to registers:
|
||||
mov $01, $regdata
|
||||
mov $02, $regdata
|
||||
|
|
@ -41,9 +41,9 @@ mov $02, $regdata
|
|||
add $01, $01, 0x0004
|
||||
addhi $02, $02, 0x0000
|
||||
mov $03, 0x0001
|
||||
cwrite $01, [$00 + @MEM_READ_ADDR], 0x0
|
||||
cwrite $02, [$00 + @MEM_READ_ADDR+0x1], 0x0
|
||||
cwrite $03, [$00 + @MEM_READ_DWORDS], 0x0
|
||||
cwrite $01, [$00 + @MEM_READ_ADDR]
|
||||
cwrite $02, [$00 + @MEM_READ_ADDR+0x1]
|
||||
cwrite $03, [$00 + @MEM_READ_DWORDS]
|
||||
; read 2nd dword of fw, and add offset (minus 4 because we skipped first dword)
|
||||
; to base address of sqe fw
|
||||
rot $04, $memdata, 0x0008
|
||||
|
|
@ -54,19 +54,19 @@ addhi $02, $02, 0x0000
|
|||
|
||||
; load packet table:
|
||||
mov $rem, 0x0080
|
||||
cwrite $01, [$00 + @MEM_READ_ADDR], 0x0
|
||||
cwrite $02, [$00 + @MEM_READ_ADDR+0x1], 0x0
|
||||
cwrite $02, [$00 + @LOAD_STORE_HI], 0x0
|
||||
cwrite $rem, [$00 + @MEM_READ_DWORDS], 0x0
|
||||
cwrite $00, [$00 + @PACKET_TABLE_WRITE_ADDR], 0x0
|
||||
(rep)cwrite $memdata, [$00 + @PACKET_TABLE_WRITE], 0x0
|
||||
cwrite $01, [$00 + @MEM_READ_ADDR]
|
||||
cwrite $02, [$00 + @MEM_READ_ADDR+0x1]
|
||||
cwrite $02, [$00 + @LOAD_STORE_HI]
|
||||
cwrite $rem, [$00 + @MEM_READ_DWORDS]
|
||||
cwrite $00, [$00 + @PACKET_TABLE_WRITE_ADDR]
|
||||
(rep)cwrite $memdata, [$00 + @PACKET_TABLE_WRITE]
|
||||
|
||||
mov $02, 0x883
|
||||
mov $03, 0xbeef
|
||||
mov $04, 0xdead << 16
|
||||
or $03, $03, $04
|
||||
cwrite $02, [$00 + @REG_WRITE_ADDR], 0x0
|
||||
cwrite $03, [$00 + @REG_WRITE], 0x0
|
||||
cwrite $02, [$00 + @REG_WRITE_ADDR]
|
||||
cwrite $03, [$00 + @REG_WRITE]
|
||||
waitin
|
||||
mov $01, $data
|
||||
|
||||
|
|
@ -90,16 +90,22 @@ CP_SCRATCH_WRITE:
|
|||
; test (rep) + flags + non-zero offset with cwrite
|
||||
; TODO: 0x4 flag is actually pre-increment addressing, handle it as such
|
||||
mov $02, 0xff
|
||||
(rep)cwrite $data, [$02 + 0x001]!, 0x0
|
||||
(rep)cwrite $data, [$02 + 0x001]!
|
||||
waitin
|
||||
mov $01, $data
|
||||
|
||||
CP_SET_DRAW_STATE:
|
||||
; test (sds)
|
||||
(rep)(sds2) cwrite $data, [$00 + @DRAW_STATE_SET_HDR]
|
||||
waitin
|
||||
mov $01, $data
|
||||
|
||||
CP_SET_BIN_DATA5:
|
||||
; test SQE registers
|
||||
sread $02, [$00 + %SP], 0x0
|
||||
swrite $02, [$00 + %SP], 0x0
|
||||
sread $02, [$00 + %SP]
|
||||
swrite $02, [$00 + %SP]
|
||||
mov $02, 7
|
||||
(rep)swrite $data, [$02 + 1]!, 0x0
|
||||
(rep)swrite $data, [$02 + 1]!
|
||||
waitin
|
||||
mov $01, $data
|
||||
|
||||
|
|
@ -139,7 +145,7 @@ nop
|
|||
|
||||
CP_REG_RMW:
|
||||
; Test various ALU instructions, and read/write $regdata
|
||||
cwrite $data, [$00 + @REG_READ_ADDR], 0x0
|
||||
cwrite $data, [$00 + @REG_READ_ADDR]
|
||||
add $02, $regdata, 0x42
|
||||
addhi $03, $00, $regdata
|
||||
sub $02, $02, $regdata
|
||||
|
|
@ -171,11 +177,11 @@ mov $05, $data
|
|||
mov $06, $data
|
||||
cpy_header:
|
||||
breq $06, 0, #cpy_exit
|
||||
cwrite $03, [$00 + @LOAD_STORE_HI], 0x0
|
||||
load $07, [$02 + 0x004]!, 0x0
|
||||
cwrite $05, [$00 + @LOAD_STORE_HI], 0x0
|
||||
cwrite $03, [$00 + @LOAD_STORE_HI]
|
||||
load $07, [$02 + 0x004]!
|
||||
cwrite $05, [$00 + @LOAD_STORE_HI]
|
||||
jump #cpy_header
|
||||
store $07, [$04 + 0x004]!, 0x0
|
||||
store $07, [$04 + 0x004]!
|
||||
cpy_exit:
|
||||
waitin
|
||||
mov $01, $data
|
||||
|
|
@ -183,19 +189,19 @@ mov $01, $data
|
|||
CP_MEM_TO_MEM:
|
||||
; implement CP_MEMCPY using mem read control regs
|
||||
; tests @FOO+0x1 for 64-bit control regs, and reading/writing $rem
|
||||
cwrite $data, [$00 + @MEM_READ_ADDR], 0x0
|
||||
cwrite $data, [$00 + @MEM_READ_ADDR+1], 0x0
|
||||
cwrite $data, [$00 + @MEM_READ_ADDR]
|
||||
cwrite $data, [$00 + @MEM_READ_ADDR+1]
|
||||
mov $02, $data
|
||||
cwrite $data, [$00 + @LOAD_STORE_HI], 0x0
|
||||
cwrite $data, [$00 + @LOAD_STORE_HI]
|
||||
mov $rem, $data
|
||||
cwrite $rem, [$00 + @MEM_READ_DWORDS], 0x0
|
||||
(rep)store $memdata, [$02 + 0x004]!, 0x0
|
||||
cwrite $rem, [$00 + @MEM_READ_DWORDS]
|
||||
(rep)store $memdata, [$02 + 0x004]!
|
||||
waitin
|
||||
mov $01, $data
|
||||
|
||||
UNKN15:
|
||||
; test preemptleave + iret + conditional branch w/ immed
|
||||
cread $02, [$00 + 0x101], 0x0
|
||||
cread $02, [$00 + 0x101]
|
||||
brne $02, 0x0001, #exit_iret
|
||||
nop
|
||||
preemptleave #err
|
||||
|
|
@ -271,7 +277,6 @@ CP_INDIRECT_BUFFER:
|
|||
CP_INTERRUPT:
|
||||
CP_EXEC_CS_INDIRECT:
|
||||
CP_MEM_TO_REG:
|
||||
CP_SET_DRAW_STATE:
|
||||
CP_COND_EXEC:
|
||||
CP_COND_WRITE5:
|
||||
CP_EVENT_WRITE:
|
||||
|
|
|
|||
|
|
@ -552,6 +552,28 @@ Although ``(xmovN)`` is often used in combination with ``(rep)``, it doesn't
|
|||
have to be. For example, ``(xmov1)mov $data, $data`` moves the next 2 packet
|
||||
words to 2 successive registers.
|
||||
|
||||
.. _afuc-sds:
|
||||
|
||||
Set Draw State
|
||||
--------------
|
||||
|
||||
``(sdsN)`` is a modifier for ``cwrite`` used to accelerate
|
||||
``CP_SET_DRAW_STATE``. For each draw state group to update,
|
||||
``CP_SET_DRAW_STATE`` needs to copy 3 words from the packet containing the
|
||||
group to update, metadata, and base address plus size. Using the ``(sds2)``
|
||||
modifier as well as ``(rep)``, this can be accomplished in a single
|
||||
instruction::
|
||||
|
||||
(rep)(sds2)cwrite $data, [$00 + @DRAW_STATE_SET_HDR]
|
||||
|
||||
The first word containing the header is written to ``@DRAW_STATE_SET_HDR``, and
|
||||
the second and third words containing the draw state base come from reading the
|
||||
source again twice and are written directly to the draw state RAM.
|
||||
|
||||
In testing with other control registers, ``(sdsN)`` causes the source to be
|
||||
read ``N`` extra times and then thrown away. Only when used in combination with
|
||||
``@DRAW_STATE_SET_HDR`` do the extra source reads have an effect.
|
||||
|
||||
Packet Table
|
||||
============
|
||||
|
||||
|
|
|
|||
|
|
@ -167,6 +167,7 @@ struct afuc_instr {
|
|||
uint8_t shift;
|
||||
uint8_t bit;
|
||||
uint8_t xmov;
|
||||
uint8_t sds;
|
||||
uint32_t literal;
|
||||
int offset;
|
||||
const char *label;
|
||||
|
|
|
|||
|
|
@ -602,20 +602,30 @@ SOFTWARE.
|
|||
<pattern low="27" high="31">01110</pattern>
|
||||
</bitset>
|
||||
|
||||
<enum name="#sds">
|
||||
<doc>
|
||||
Used in combination with writing @DRAW_STATE_SET, the source is
|
||||
read the specified number of times and used to set the draw
|
||||
state base.
|
||||
</doc>
|
||||
<value val="0" display=""/>
|
||||
<value val="1" display="(sds1)"/>
|
||||
<value val="2" display="(sds2)"/>
|
||||
<value val="3" display="(sds3)"/>
|
||||
</enum>
|
||||
|
||||
<bitset name="#control" extends="#instruction-rep">
|
||||
<field name="FLAGS" low="12" high="13" type="hex"/>
|
||||
<field name="PREINCREMENT" pos="14" type="bool" display="!"/>
|
||||
<field name="OFFSET" low="21" high="25" type="#src"/>
|
||||
|
||||
<encode>
|
||||
<map name="FLAGS">src->bit</map>
|
||||
<map name="PREINCREMENT">src->preincrement</map>
|
||||
</encode>
|
||||
</bitset>
|
||||
|
||||
<bitset name="#store" extends="#control">
|
||||
<display>
|
||||
{REP}store {SRC}, [{OFFSET} + 0x{IMMED}]{PREINCREMENT}, 0x{FLAGS}
|
||||
{REP}store {SRC}, [{OFFSET} + 0x{IMMED}]{PREINCREMENT}
|
||||
</display>
|
||||
|
||||
<doc>
|
||||
|
|
@ -624,6 +634,7 @@ SOFTWARE.
|
|||
restored.
|
||||
</doc>
|
||||
|
||||
<pattern low="12" high="13">00</pattern>
|
||||
<field name="IMMED" low="0" high="11" type="hex"/>
|
||||
<field name="SRC" low="16" high="20" type="#src"/>
|
||||
|
||||
|
|
@ -674,16 +685,18 @@ SOFTWARE.
|
|||
<bitset name="#cwrite" extends="#control">
|
||||
<doc>Write to a control register.</doc>
|
||||
<display>
|
||||
{REP}cwrite {SRC}, [{OFFSET} + {BASE}]{PREINCREMENT}, 0x{FLAGS}
|
||||
{REP}{SDS}cwrite {SRC}, [{OFFSET} + {BASE}]{PREINCREMENT}
|
||||
</display>
|
||||
|
||||
<field name="BASE" low="0" high="11" type="#control-base">
|
||||
<param name="PREINCREMENT"/>
|
||||
</field>
|
||||
<field name="SDS" low="12" high="13" type="#sds"/>
|
||||
<field name="SRC" low="16" high="20" type="#src"/>
|
||||
<pattern low="27" high="31">10101</pattern>
|
||||
|
||||
<encode>
|
||||
<map name="SDS">src->sds</map>
|
||||
<map name="SRC">src->src1</map>
|
||||
<map name="OFFSET">src->src2</map>
|
||||
<map name="BASE">src->immed</map>
|
||||
|
|
@ -721,12 +734,13 @@ SOFTWARE.
|
|||
<doc>Write to a SQE register.</doc>
|
||||
<gen min="6"/>
|
||||
<display>
|
||||
{REP}swrite {SRC}, [{OFFSET} + {BASE}]{PREINCREMENT}, 0x{FLAGS}
|
||||
{REP}swrite {SRC}, [{OFFSET} + {BASE}]{PREINCREMENT}
|
||||
</display>
|
||||
|
||||
<field name="BASE" low="0" high="11" type="#sqe-base">
|
||||
<param name="PREINCREMENT"/>
|
||||
</field>
|
||||
<pattern low="12" high="13">00</pattern>
|
||||
<field name="SRC" low="16" high="20" type="#src"/>
|
||||
<pattern pos="15">1</pattern>
|
||||
<pattern low="27" high="31">10101</pattern>
|
||||
|
|
@ -746,10 +760,11 @@ SOFTWARE.
|
|||
restored.
|
||||
</doc>
|
||||
<display>
|
||||
{REP}load {DST}, [{OFFSET} + 0x{IMMED}]{PREINCREMENT}, 0x{FLAGS}
|
||||
{REP}load {DST}, [{OFFSET} + 0x{IMMED}]{PREINCREMENT}
|
||||
</display>
|
||||
|
||||
<field name="IMMED" low="0" high="11" type="hex"/>
|
||||
<pattern low="12" high="13">00</pattern>
|
||||
<pattern pos="15">0</pattern>
|
||||
<field name="DST" low="16" high="20" type="#dst"/>
|
||||
<pattern low="27" high="31">10110</pattern>
|
||||
|
|
@ -762,12 +777,13 @@ SOFTWARE.
|
|||
<bitset name="#cread" extends="#control">
|
||||
<doc>Read from a control register.</doc>
|
||||
<display>
|
||||
{REP}cread {DST}, [{OFFSET} + {BASE}]{PREINCREMENT}, 0x{FLAGS}
|
||||
{REP}cread {DST}, [{OFFSET} + {BASE}]{PREINCREMENT}
|
||||
</display>
|
||||
|
||||
<field name="BASE" low="0" high="11" type="#control-base">
|
||||
<param name="PREINCREMENT"/>
|
||||
</field>
|
||||
<pattern low="12" high="13">00</pattern>
|
||||
<field name="DST" low="16" high="20" type="#dst"/>
|
||||
|
||||
<encode>
|
||||
|
|
@ -793,12 +809,13 @@ SOFTWARE.
|
|||
<doc>Read from a SQE register.</doc>
|
||||
<gen min="6"/>
|
||||
<display>
|
||||
{REP}sread {DST}, [{OFFSET} + {BASE}]{PREINCREMENT}, 0x{FLAGS}
|
||||
{REP}{XREG}sread {DST}, [{OFFSET} + {BASE}]{PREINCREMENT}
|
||||
</display>
|
||||
|
||||
<field name="BASE" low="0" high="11" type="#sqe-base">
|
||||
<param name="PREINCREMENT"/>
|
||||
</field>
|
||||
<pattern low="12" high="13">00</pattern>
|
||||
<field name="DST" low="16" high="20" type="#dst"/>
|
||||
|
||||
<encode>
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@
|
|||
* Emulation for draw-state (ie. CP_SET_DRAW_STATE) related control registers:
|
||||
*/
|
||||
|
||||
EMU_CONTROL_REG(DRAW_STATE_SET);
|
||||
EMU_CONTROL_REG(DRAW_STATE_SET_HDR);
|
||||
EMU_CONTROL_REG(DRAW_STATE_SEL);
|
||||
EMU_CONTROL_REG(DRAW_STATE_ACTIVE_BITMASK);
|
||||
EMU_CONTROL_REG(DRAW_STATE_HDR);
|
||||
|
|
@ -48,28 +48,30 @@ emu_get_draw_state_reg(struct emu *emu, unsigned n)
|
|||
return emu->control_regs.val[n];
|
||||
}
|
||||
|
||||
void
|
||||
emu_set_draw_state_base(struct emu *emu, unsigned n, uint32_t val)
|
||||
{
|
||||
struct emu_draw_state *ds = &emu->draw_state;
|
||||
|
||||
unsigned cur_idx = (emu_get_reg32(emu, &DRAW_STATE_SET_HDR) >> 24) & 0x1f;
|
||||
ds->state[cur_idx].base_lohi[n] = val;
|
||||
}
|
||||
|
||||
void
|
||||
emu_set_draw_state_reg(struct emu *emu, unsigned n, uint32_t val)
|
||||
{
|
||||
struct emu_draw_state *ds = &emu->draw_state;
|
||||
unsigned cur_idx = emu_get_reg32(emu, &DRAW_STATE_SEL);
|
||||
|
||||
if (n == emu_reg_offset(&DRAW_STATE_SET)) {
|
||||
if (ds->write_idx == 0) {
|
||||
cur_idx = (val >> 24) & 0x1f;
|
||||
ds->state[cur_idx].count = val & 0xffff;
|
||||
ds->state[cur_idx].mode_mask = (val >> 20) & 0x7;
|
||||
if (n == emu_reg_offset(&DRAW_STATE_SET_HDR)) {
|
||||
cur_idx = (val >> 24) & 0x1f;
|
||||
ds->state[cur_idx].count = val & 0xffff;
|
||||
ds->state[cur_idx].mode_mask = (val >> 20) & 0x7;
|
||||
|
||||
unsigned active_mask = emu_get_reg32(emu, &DRAW_STATE_ACTIVE_BITMASK);
|
||||
active_mask |= (1 << cur_idx);
|
||||
unsigned active_mask = emu_get_reg32(emu, &DRAW_STATE_ACTIVE_BITMASK);
|
||||
active_mask |= (1 << cur_idx);
|
||||
|
||||
emu_set_reg32(emu, &DRAW_STATE_ACTIVE_BITMASK, active_mask);
|
||||
emu_set_reg32(emu, &DRAW_STATE_SEL, cur_idx);
|
||||
} else {
|
||||
ds->state[cur_idx].base_lohi[ds->write_idx - 1] = val;
|
||||
}
|
||||
|
||||
ds->write_idx = (ds->write_idx + 1) % 3;
|
||||
emu_set_reg32(emu, &DRAW_STATE_ACTIVE_BITMASK, active_mask);
|
||||
} else if (n == emu_reg_offset(&DRAW_STATE_SEL)) {
|
||||
emu_set_reg32(emu, &DRAW_STATE_HDR, ds->state[val].hdr);
|
||||
emu_set_reg64(emu, &DRAW_STATE_BASE, ds->state[val].base);
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@
|
|||
|
||||
EMU_SQE_REG(SP);
|
||||
EMU_SQE_REG(STACK0);
|
||||
EMU_CONTROL_REG(DRAW_STATE_SET_HDR);
|
||||
|
||||
/**
|
||||
* AFUC emulator. Currently only supports a6xx
|
||||
|
|
@ -215,14 +216,24 @@ emu_instr(struct emu *emu, struct afuc_instr *instr)
|
|||
case OPC_CWRITE: {
|
||||
uint32_t src1 = emu_get_gpr_reg(emu, instr->src1);
|
||||
uint32_t src2 = emu_get_gpr_reg(emu, instr->src2);
|
||||
uint32_t reg = src2 + instr->immed;
|
||||
|
||||
if (instr->preincrement) {
|
||||
emu_set_gpr_reg(emu, instr->src2, src2 + instr->immed);
|
||||
} else if (instr->bit && !emu->quiet) {
|
||||
printf("unhandled flags: %x\n", instr->bit);
|
||||
emu_set_gpr_reg(emu, instr->src2, reg);
|
||||
}
|
||||
|
||||
emu_set_control_reg(emu, src2 + instr->immed, src1);
|
||||
emu_set_control_reg(emu, reg, src1);
|
||||
|
||||
for (unsigned i = 0; i < instr->sds; i++) {
|
||||
uint32_t src1 = emu_get_gpr_reg(emu, instr->src1);
|
||||
|
||||
/* TODO: There is likely a DRAW_STATE_SET_BASE register on a6xx, as
|
||||
* there is on a7xx, and we should be writing that instead of setting
|
||||
* the base directly.
|
||||
*/
|
||||
if (reg == emu_reg_offset(&DRAW_STATE_SET_HDR))
|
||||
emu_set_draw_state_base(emu, i, src1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case OPC_CREAD: {
|
||||
|
|
@ -230,8 +241,6 @@ emu_instr(struct emu *emu, struct afuc_instr *instr)
|
|||
|
||||
if (instr->preincrement) {
|
||||
emu_set_gpr_reg(emu, instr->src1, src1 + instr->immed);
|
||||
} else if (instr->bit && !emu->quiet) {
|
||||
printf("unhandled flags: %x\n", instr->bit);
|
||||
}
|
||||
|
||||
emu_set_gpr_reg(emu, instr->dst,
|
||||
|
|
@ -244,8 +253,6 @@ emu_instr(struct emu *emu, struct afuc_instr *instr)
|
|||
|
||||
if (instr->preincrement) {
|
||||
emu_set_gpr_reg(emu, instr->src2, src2 + instr->immed);
|
||||
} else if (instr->bit && !emu->quiet) {
|
||||
printf("unhandled flags: %x\n", instr->bit);
|
||||
}
|
||||
|
||||
emu_set_sqe_reg(emu, src2 + instr->immed, src1);
|
||||
|
|
@ -256,8 +263,6 @@ emu_instr(struct emu *emu, struct afuc_instr *instr)
|
|||
|
||||
if (instr->preincrement) {
|
||||
emu_set_gpr_reg(emu, instr->src1, src1 + instr->immed);
|
||||
} else if (instr->bit && !emu->quiet) {
|
||||
printf("unhandled flags: %x\n", instr->bit);
|
||||
}
|
||||
|
||||
emu_set_gpr_reg(emu, instr->dst,
|
||||
|
|
@ -271,8 +276,6 @@ emu_instr(struct emu *emu, struct afuc_instr *instr)
|
|||
if (instr->preincrement) {
|
||||
uint32_t src1 = emu_get_gpr_reg(emu, instr->src1);
|
||||
emu_set_gpr_reg(emu, instr->src1, src1 + instr->immed);
|
||||
} else if (instr->bit && !emu->quiet) {
|
||||
printf("unhandled flags: %x\n", instr->bit);
|
||||
}
|
||||
|
||||
uint32_t val = emu_mem_read_dword(emu, addr);
|
||||
|
|
@ -288,8 +291,6 @@ emu_instr(struct emu *emu, struct afuc_instr *instr)
|
|||
if (instr->preincrement) {
|
||||
uint32_t src2 = emu_get_gpr_reg(emu, instr->src2);
|
||||
emu_set_gpr_reg(emu, instr->src2, src2 + instr->immed);
|
||||
} else if (instr->bit && !emu->quiet) {
|
||||
printf("unhandled flags: %x\n", instr->bit);
|
||||
}
|
||||
|
||||
uint32_t val = emu_get_gpr_reg(emu, instr->src1);
|
||||
|
|
|
|||
|
|
@ -113,7 +113,6 @@ emu_queue_pop(struct emu_queue *q, uint32_t *val)
|
|||
*/
|
||||
struct emu_draw_state {
|
||||
unsigned prev_draw_state_sel;
|
||||
unsigned write_idx;
|
||||
struct {
|
||||
union {
|
||||
uint32_t hdr;
|
||||
|
|
@ -294,6 +293,7 @@ void emu_set_reg64(struct emu *emu, struct emu_reg *reg, uint64_t val);
|
|||
/* Draw-state control reg emulation: */
|
||||
uint32_t emu_get_draw_state_reg(struct emu *emu, unsigned n);
|
||||
void emu_set_draw_state_reg(struct emu *emu, unsigned n, uint32_t val);
|
||||
void emu_set_draw_state_base(struct emu *emu, unsigned n, uint32_t val);
|
||||
|
||||
/* Helpers: */
|
||||
#define printdelta(fmt, ...) afuc_printc(AFUC_ERR, fmt, ##__VA_ARGS__)
|
||||
|
|
|
|||
|
|
@ -95,6 +95,7 @@ extern YYSTYPE yylval;
|
|||
"<<" return TOKEN(T_LSHIFT);
|
||||
"(rep)" return TOKEN(T_REP);
|
||||
"(xmov"[1-3]")" yylval.num = yytext[5] - '0'; return T_XMOV;
|
||||
"(sds"[1-3]")" yylval.num = yytext[4] - '0'; return T_SDS;
|
||||
|
||||
"," return ',';
|
||||
"[" return '[';
|
||||
|
|
|
|||
|
|
@ -170,6 +170,7 @@ label(const char *str)
|
|||
%token <tok> T_LSHIFT
|
||||
%token <tok> T_REP
|
||||
%token <num> T_XMOV
|
||||
%token <num> T_SDS
|
||||
|
||||
%type <num> reg
|
||||
%type <num> immediate
|
||||
|
|
@ -190,8 +191,8 @@ instr_or_label: instr_r
|
|||
| T_LABEL_DECL { decl_label($1); }
|
||||
|
||||
/* instructions that can optionally have (rep) flag: */
|
||||
instr_r: alu_instr { instr->xmov = 0; }
|
||||
| T_XMOV alu_instr { instr->xmov = $1; }
|
||||
instr_r: alu_instr { instr->xmov = 0; }
|
||||
| T_XMOV alu_instr { instr->xmov = $1; }
|
||||
| load_instr
|
||||
| store_instr
|
||||
|
||||
|
|
@ -255,21 +256,22 @@ alu_instr: alu_2src_instr
|
|||
| alu_clrsetbit_instr
|
||||
| alu_bitfield_instr
|
||||
|
||||
load_op: T_OP_LOAD { new_instr(OPC_LOAD); }
|
||||
| T_OP_CREAD { new_instr(OPC_CREAD); }
|
||||
| T_OP_SREAD { new_instr(OPC_SREAD); }
|
||||
store_op: T_OP_STORE { new_instr(OPC_STORE); }
|
||||
| T_OP_CWRITE { new_instr(OPC_CWRITE); }
|
||||
| T_OP_SWRITE { new_instr(OPC_SWRITE); }
|
||||
load_op: T_OP_LOAD { new_instr(OPC_LOAD); }
|
||||
| T_OP_CREAD { new_instr(OPC_CREAD); }
|
||||
| T_OP_SREAD { new_instr(OPC_SREAD); }
|
||||
store_op: T_OP_STORE { new_instr(OPC_STORE); }
|
||||
| T_OP_CWRITE { new_instr(OPC_CWRITE); instr->sds = 0; }
|
||||
| T_SDS T_OP_CWRITE { new_instr(OPC_CWRITE); instr->sds = $1; }
|
||||
| T_OP_SWRITE { new_instr(OPC_SWRITE); }
|
||||
|
||||
preincrement:
|
||||
| '!' { instr->preincrement = true; }
|
||||
|
||||
load_instr: load_op reg ',' '[' reg '+' immediate ']' preincrement ',' immediate {
|
||||
dst($2); src1($5); immed($7); bit($11);
|
||||
load_instr: load_op reg ',' '[' reg '+' immediate ']' preincrement {
|
||||
dst($2); src1($5); immed($7);
|
||||
}
|
||||
store_instr: store_op reg ',' '[' reg '+' immediate ']' preincrement ',' immediate {
|
||||
src1($2); src2($5); immed($7); bit($11);
|
||||
store_instr: store_op reg ',' '[' reg '+' immediate ']' preincrement {
|
||||
src1($2); src2($5); immed($7);
|
||||
}
|
||||
|
||||
branch_op: T_OP_BRNE { new_instr(OPC_BRNE); }
|
||||
|
|
|
|||
|
|
@ -130,7 +130,14 @@ xsi:schemaLocation="http://nouveau.freedesktop.org/ rules-ng.xsd">
|
|||
</doc>
|
||||
</reg32>
|
||||
<reg32 name="DRAW_STATE_ACTIVE_BITMASK" offset="0x049"/>
|
||||
<reg32 name="DRAW_STATE_SET" offset="0x04a"/>
|
||||
|
||||
<doc>
|
||||
This register is written for each state group entry in
|
||||
CP_SET_DRAW_STATE. The value is copied directly from the packet
|
||||
to these registers so the format is identical to the first word.
|
||||
The draw state base is set via the (sds2) modifier.
|
||||
</doc>
|
||||
<reg32 name="DRAW_STATE_SET_HDR" offset="0x04a"/>
|
||||
|
||||
<doc> Controls whether RB, IB1, or IB2 is executed </doc>
|
||||
<reg32 name="IB_LEVEL" offset="0x054"/>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue