没什么好多说的,需要注意延迟槽喝判断指令跳转,紧跟的代码最好用nop间隔,否则会有副作用。。。
byte_rdwr:
# we use byte rdwr operation for hook operation , format like "DDR_REG_RDWR_B ( 0x0 ) TAILING 0x0"
#ifdef CONFIG_BYTE_RDWR_HOOK
# uart0 cycle 15021518[11:0] byte0~3, LCDL base 150215e8, add 0x40
# uart1 cycle 15023518[11:0] byte0~3, LCDL base 150235e8, add 0x40
lui t0,0xb502
ori t6,t0,0x3518 #rslr
ori t7,t0,0x35E8 #DQSDG
ori t9,t0,0x34A4 #T/4
ori k0,t0,0x3090 #gs
ori k1,t0,0x3084 #120 or 240
and a1,a1,0x1
beq a1,0x1,hook_start
nop
ori t6,t0,0x1518 #rslr
ori t7,t0,0x15E8 #DQSDG
ori t9,t0,0x14A4 #T/4
ori k0,t0,0x1090 #gs
ori k1,t0,0x1084 #120 or 240
hook_start:
lui v1,0x0 # v1 loop i = 0
lui t8,0xfff # t8 save the min
lw t0,(t6) # t0 = cycle
lw t1,(k1) # judgement for 120 or 240
and t1,t1,0x1 #[0]
li k1,0x4 #default 240, 4bytes b)
beqz t1,min_rlsr #If it is '1', it means it is two byte mode. It can only need to work on byte0 and byte1.
nop # 这里不加的话,k1即便已经赋值为4,还是会在跳转时变成 2
li k1,0x2 #is 120, 2bytes
min_rlsr:
mul a2,v1,0x3 # 0x3
nop
srl t1,t0,a2 # >> i*3
and t1,t1,0x7 #&3 bits
bgeu t1,t8,min_rlsr_iadd # >=
nop
move t8,t1
min_rlsr_iadd:
add v1,v1,0x1
blt v1,k1,min_rlsr
nop
lui v1,0x0 #loop i = 0
diff_rslr:
mul a2,v1,0x3
nop
srl t1,t0,a2 # >> i*3
and t1,t1,0x7 #&0xff
sub t1,t1,t8 # t1 = cycle - min
blez t1,diff_iadd #<=0
nop
mul a2,v1,0x40 #offset = 0x40*index
nop
add a2,t7,a2 # a2 addr = base + offset
lw a1,(a2) # a1 = DQSDG
and t2,a1,0xff #&0xff , t2 = DQSDG[7:0]
lw a3,(t9) #load T/4
and a3,a3,0xff #a3=T/4
sll a3,a3,0x2 # T
mul t1,t1,a3 #(T/4)*(rslrN-min{rlsr3:0})
nop
add t2,t2,t1
and a1,a1,0xffffff00
or a1,a1,t2
sw a1,(a2)
diff_iadd:
add v1,v1,0x1
blt v1,k1,diff_rslr
nop
lw t0,(k0)
and t0,t0,0xfffffffe
sw t0,(k0)
b loop
nop