📄 f_amd_sst_arm.s
字号:
; the information on which end has the boot block and its size,
; so we do not need to worry about that.
; - we may be asked to erase one or a set of blocks, but all will
; have the same size.
;
; From tmgmulti.c
; erase takes Reg0=page, Reg1=block_addr, Reg2=count of blocks, Reg3=sizeOfBlocks
;
; Input/Output:
; - In:
; R0=Page of Flash (no meaning for ARM)
; R1=Base of 1st Flash Block to erase
; R2=Count of blocks to do
; R3=Size of blocks (for iterate)
; - Out:R0=status code (0=OK, else error)
; - Scratch: R1, R2
; - Scratch: R6,R7 flash_control
; - Persist: R11 - set with Base of Flash
; ----------------------------------------------------------------------- */
FLASH_erase
; we use sector erase model
mov R0,#FC_ERASE ; start erase mode 0x80
bl flash_control ; send op to Flash
mov R0,#0 ; send nothing for third
bl flash_control ; send AA 55 only
mov R0,#FC_SECTE ; send erase to sector 0x30
STORE R0,[R1] ; do erase of that block
bl wait_status
subs R2,R2,#1 ; count down
addne R1,R1,R3 ; setup for next block if more
bne FLASH_erase ; more to do
mov R0,#0 ; indicate done
b FLASH_break ; Stop routine on breakpoint
; -------------------------------------------------------------------------
; Variant used before writing
; R1=Base of the (we only do one )Flash Block to erase
; Altered R0, (from flash_control R6, R7)
Erase_b4_write
; again we use sector erase model
PUSHX R14
mov R0,#FC_ERASE ; start erase mode 0x80
bl flash_control ; send op to Flash
mov R0,#0 ; send nothing for third
bl flash_control ; send AA 55 only
mov R0,#FC_SECTE ; send erase to sector 0x30
STORE R0,[R1] ; do erase of that block/sector
bl wait_status
POPX R14
RET
;* -----------------------------------------------------------------------
; wait_status utilizes the DQ6 polling algorithm described in
; the flash data book.
; input: R1 == address of flash location
; scratch: R0, R6, R7
wait_status
ldr r0,RETRIES ; get how long we will wait
ldr R8,=0x00000040
wait_loop
ldr R6,[R1] ; read memory once
and R6,R6,R8 ; separate out all but DQ6
ldr R7,[R1] ; read memory again
and R7,R7,R8 ; again separate out DQ6
cmp R6,R7 ; are they the same?
beq ready
subs R0,R0,#1 ;decrement r0 and check again
bne wait_loop
movs R0,#0x03
RET
ready
mov R0,#0
RET
;* -----------------------------------------------------------------------
; FLASH_write - write to a Flash block
; FLASH_write_erase - erase then write
;
; Notes:
; - this writes a buffer into a flash block. The caller is responsible
; for pre-erasing if needed.
; - note: this is writing half-words and not bytes
; - the host knows about block sizes and all, and passes in the needed
; info.
; - if we are writing into a later part of the block, this will be
; handled by the host.
; from tmgmulti:
; write takes Reg0=page, Reg1=block_addr, Reg2=byte_cnt,
; Reg4=offset_write, Reg5=buff_addr,
; Reg8=Page_buff, Reg9=byte_cnt_if_verify
;
; Input/Output:
; - In: R1=Base of Flash Block to write
; R0=Page of Flash (no meaning for ARM)
; R2=Count of bytes to copy
; R4=Offset in block to copy into (from base)
; R5=Address of buffer to copy from
; R8=Page of buffer (no meaning for ARM)
; R9=0 if no verify, else same value as R2 (count)
; - Out:R0=status code (0=OK, else error)
; - Scratch: R6,R7
; - Persist: R11 - set with Base of Flash during init
; ----------------------------------------------------------------------- */
FLASH_write_erase ; Altered R0, (from flash_control R6, R7)
bl Erase_b4_write
FLASH_write
add R4,R4,R1 ; compute address
WRITE_loop
mov R0,#FC_WRITE ; start write mode 0xA0
bl flash_control ; send op to Flash
LOAD R7,[R5],#WIDTH ; load first value from buffer then inc
STORE R7,[R4],#WIDTH ; write value de
bl wait_status ; check status and wait for ok
bne failed_status ; fail if return code (R0) is != 0
subs R2,R2,#WIDTH ; decrement count, more?
bgt WRITE_loop ; yes, continue
mov R0,#0 ; was good
cmp R9,#0 ; want verify?
beq done_write ; no, just quit
mov R2,R9 ; reset count (buff size)
sub R4,R4,R2 ; back up to start of block to verify
sub R5,R5,R2 ; back up to start of buffer to verify
b FLASH_validate ; go on to validate code
done_write
b FLASH_break ; Stop routine on breakpoint
failed_status
mov r0,#3
b FLASH_break ; and go to stop routine
;* -----------------------------------------------------------------------
; FLASH_validate - validate write to a Flash block
;
; Notes:
; - this compares a buffer and a flash block. The caller uses this
; after a write to verify the write worked.
; - the host knows about block sizes and all, and passes in the needed
; info.
;
; Input/Output:
; - In: R1=Base of Flash block to verify
; R0=Page of Flash (no meaning for ARM)
; R2=Count of bytes to verify
; R4=Offset in block to verify from
; R5=Address of buffer to verify against
; R8=Page of buffer (no meaning for ARM)
; - Out:R0=status code (0=OK, else error)
; - Scratch: R6,R7
; ----------------------------------------------------------------------- */
FLASH_validate
mov R6,#0
mov R7,#0
validate_loop
LOAD R7,[R5],#WIDTH ; load value from buffer
LOAD R6,[R4],#WIDTH ; load value from Flash
cmp R6,R7 ; same?
bne bad_validate ; no, failed
subs R2,R2,#WIDTH ; decrement count, more?
bgt validate_loop ; yes, continue
b FLASH_break ; Stop routine on breakpoint
bad_validate
mov R0,#2 ; compare
b FLASH_break ; Stop routine on breakpoint
;* -----------------------------------------------------------------------
; FLASH_break - end of function entry for all Flash routines
;
; Notes:
; - this routine is the Stop routine for the flash code. It runs over
; what should be a break (set by host). If the host messes up, it
; will loop forever allowing the host to halt it.
;
; Input/Output:
; - In: R0=status code to return (0=OK, else error)
; R1=base of Flash block operated on
; ----------------------------------------------------------------------- */
FLASH_break
nop ; place to put breakpoint from host
forever
b forever ; in case host screws up
;************************************************************************/
;* STATIC FUNCTIONS */
;************************************************************************/
;* -----------------------------------------------------------------------
; flash_control - write 3 values to flash to start operation.
;
; Notes:
; - this writes the initialization values to the Flash and
; then the value in R7.
;
; Input/Output:
; - In: R11=Base of Flash (not changed)
; R0=Operation value to write (not changed)
;
; - Out:<none>
; - Scratch: R6,R7
; - Persist: R11 - address to write to either flash base or sector address
; ----------------------------------------------------------------------- */
flash_control
ldr R6,OFFSET1 ; write to OFF1
add R6,R6,R11 ; note arith since >12 bits of off
mov R7,#FC_AT1 ; start of enable ID mode 0xAA
STORE R7,[R6] ; write /half 0xAAAA to Flash
ldr R6,OFFSET2 ; write to OFF2
add R6,R6,R11 ; note arith since >12 bits of off
mov R7,#FC_AT2 ; start of enable ID mode 0x55
STORE R7,[R6] ; write byte/half 0x2fff to Flash
teq R0,#0 ; if R0 is 0 then don't send it
beq out
ldr R6,OFFSET1 ; write to OFF1
add R6,R6,R11 ; note arith since >12 bits of off
STORE R0,[R6] ; write byte/half 0xAAAA to Flash
out
RET
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -