.title  "Flash bootup utility for 6211 dsk"
        .option D,T
        .length 102
        .width  140
     

PAGE_SIZE	  .equ    0x80	    ;flash page size in byte
BOOT_SIZE     .equ    0x800       ;bootup code size in byte
FLASH_START   .equ    0x90000000  ;flash start address
BOOT_START    .equ    0x00000000  ;L2 sram start address

CODE_SIZE     .equ    0xF800      ;application code size in byte
CODE_START    .equ    0x800       ;application code start address

FLASH_REG1    .equ    0x90005555  ;address of the flash control reg 1
FLASH_REG2    .equ    0x90002AAA  ;address of the flash control reg 2
FLASH_KEY1    .equ    0xAA
FLASH_KEY2    .equ    0x55
FLASH_KEY3    .equ    0xA0
IO_PORT       .equ    0x90080000  ;address of I/O port, only top byte has valid data 
EMIF_GCR 	  .equ    0x01800000  ;EMIF global control     
EMIF_CE1      .equ    0x01800004  ;address of EMIF CE1 control reg. 
EMIF_CE0      .equ    0x01800008  ;EMIF CE0control          
EMIF_SDCTRL   .equ    0x01800018  ;EMIF SDRAM control     
EMIF_SDRP     .equ    0x0180001c  ;EMIF SDRM refresh period 
EMIF_CE1_8    .equ    0xffffff03  ;
EMIF_CE1_32   .equ    0xffffff23  ;
EMIF_CE0_V    .equ    0xffffff33  ;EMIF CE0control   ;0x30
EMIF_SDCTRL_V .equ    0x07117000  ;EMIF SDRAM control ;0x73380000    



 .sect ".boot_load" 
 .global _boot
 .global _flash_prog
 .global _wait

 .ref _c_int00
 
_boot:
            mvkl  EMIF_GCR,A4    ;EMIF_GCR address ->A4
      ||    mvkl  0x3300,B4      

            mvkh  EMIF_GCR,A4
      ||    mvkh  0x3300,B4  
                            
            stw   B4,*A4                

            mvkl  EMIF_CE0,A4       ;EMIF_CE0 address ->A4
      ||    mvkl  EMIF_CE0_V,B4     ;

            mvkh  EMIF_CE0,A4
      ||    mvkh  EMIF_CE0_V,B4
      
            stw   B4,*A4                
      ||    mvkl  EMIF_SDCTRL,A4    ;EMIF_SDCTRL address ->A4
      ||    mvkl  EMIF_SDCTRL_V,B4     ;

            mvkh  EMIF_SDCTRL,A4
      ||    mvkh  EMIF_SDCTRL_V,B4     
      
            stw   B4,*A4                
      ||    mvkl  EMIF_SDRP,A4      ;EMIF_SDRP address ->A4
      ||    mvkl  0x61a,B4    ;

            mvkh  EMIF_SDRP,A4
      ||    mvkh  0x61a,B4
            
            stw   B4,*A4
 


            mvkl  BOOT_START+1024,A4 ;ram start address ->A4
      ||    mvkl  FLASH_START+1024,B4 ;flash start address ->B4

            mvkh  BOOT_START+1024,A4
      ||    mvkh  FLASH_START+1024,B4   
       

            zero  A1
_boot_loop1:
            ldb   *B4++,B5
            mvkl  BOOT_SIZE-1024,B6 ;B6 = BOOT_SIZE -1024

            add   1,A1,A1          ;A1+=1,inc outer counter
      ||    mvkh  BOOT_SIZE-1024,B6
       
            cmplt A1,B6,B0
            nop   
            stb   B5,*A4++
      [B0]  b     _boot_loop1
            nop   5

            mvkl  CODE_START,A4 ;apps code start address ->A4
            mvkh  CODE_START,A4
            zero  A1
 
_boot_loop2:
            ldb   *B4++,B5
            mvkl  CODE_SIZE-4,B6 ;B6 = BOOT_SIZE -1024

            add   1,A1,A1          ;A1+=1,inc outer counter
      ||    mvkh  CODE_SIZE-4,B6
       
            cmplt  A1,B6,B0
            nop    
            stb   B5,*A4++
      [B0]  b     _boot_loop2
            nop   5
        
            mvkl .S2 _c_int00, B0
            mvkh .S2 _c_int00, B0
            B    .S2 B0
            nop   5
; 
; end of the bootup routine

_flash_prog:
      	mvk   0x100,B0
      ||    mvk   1,A1 
      
       	mvc	B0,CSR         ;CSR = 0x100

            mvc   A1,IER         ;IER = 1
       
            mvk   -1,B0
      ||    mvk   0,A1           ;couter = 0

            mvc   B0,ICR         ;ICR = 0xffff
      ||    mvk   0,A0           ;checksum =0
            mvkl  EMIF_GCR,A4    ;EMIF_GCR address ->A4
      ||    mvkl  0x3300,B4      

            mvkh  EMIF_GCR,A4
      ||    mvkh  0x3300,B4  
                            
            stw   B4,*A4                
      ||    mvkl  EMIF_CE1,A4       ;EMIF_CE1 address ->A4
      ||    mvkl  EMIF_CE1_32,B4     ;

            mvkh  EMIF_CE1,A4
      ||    mvkh  EMIF_CE1_32,B4   
      
            stw   B4,*A4                
      ||    mvkl  EMIF_CE0,A4       ;EMIF_CE0 address ->A4
      ||    mvkl  EMIF_CE0_V,B4     ;

            mvkh  EMIF_CE0,A4
      ||    mvkh  EMIF_CE0_V,B4
      
            stw   B4,*A4                
      ||    mvkl  EMIF_SDCTRL,A4    ;EMIF_SDCTRL address ->A4
      ||    mvkl  EMIF_SDCTRL_V,B4     ;

            mvkh  EMIF_SDCTRL,A4
      ||    mvkh  EMIF_SDCTRL_V,B4     
      
            stw   B4,*A4                
      ||    mvkl  EMIF_SDRP,A4      ;EMIF_SDRP address ->A4
      ||    mvkl  0x61a,B4    ;

            mvkh  EMIF_SDRP,A4
      ||    mvkh  0x61a,B4
            
            stw   B4,*A4
      ||    mvkl  IO_PORT,B4        ;I/O port address ->B4
      ||    mvkl  0x07000000,A4
               
            mvkh  IO_PORT,B4        ;I/O port address ->B4
      ||    mvkh  0x07000000,A4

            nop   9
            stw   A4,*B4            ;turn off all three LEDs 
            nop   9

            mvkl  EMIF_CE1,A4       ;EMIF_CE1 address ->A4
      ||    mvkl  EMIF_CE1_8,B4     ;flash start address ->B4

            mvkh  EMIF_CE1,A4
      ||    mvkh  EMIF_CE1_8,B4

            stw   B4,*A4
      ||    mvkl  BOOT_START,A4      ;ram start address ->A4
      ||    mvkl  BOOT_SIZE,B0

            mvkh  BOOT_START,A4
      ||    mvkh  BOOT_SIZE,B0    
      
            mvk   0xff,B6

_prog_checksum_loop1:
            ldb   *A4++,B4
            mvk   1,B1
            sub   B0,B1,B0
            nop   2  
            and   B4,B6,B4
            add   A0,B4,A0         ;update checksum and save in A0
      [B0]  b     _prog_checksum_loop1
            nop   5

            mvkl  CODE_START,A4      ;ram start address ->A4
      ||    mvkl  CODE_SIZE-4,B0

            mvkh  CODE_START,A4
      ||    mvkh  CODE_SIZE-4,B0

_prog_checksum_loop2:
            ldb   *A4++,B4
            mvk   1,B1
            sub   B0,B1,B0
            nop   2 
            and   B4,B6,B4
            add   A0,B4,A0         ;update checksum and save in A0
      [B0]  b     _prog_checksum_loop2
            nop   5

;            stw   A0,*A4
            
            mvkl  BOOT_START,A4
      ||    mvkl  FLASH_START,B4    ;flash start address ->B4

            mvkh  BOOT_START,A4
      ||    mvkh  FLASH_START,B4

            mvk   PAGE_SIZE,A6
      ||    mvkl  BOOT_SIZE,B2

            mvkh  BOOT_SIZE,B2
      ||    zero  A1

_flash_prog_loop1:
            b     _flash_page_prog
            mvkl  _flash_prog_branch1,B3
            mvkh  _flash_prog_branch1,B3
            add   A6,A1,A1
            cmplt A1,B2,B0
            nop
_flash_prog_branch1:
      [B0]  b     _flash_prog_loop1   
            nop   5   

            
            mvkl  CODE_START,A4
      ||    mvkl  CODE_SIZE,B2

            mvkh  CODE_START,A4
      ||    mvkh  CODE_SIZE,B2
      
            zero  A1

_flash_prog_loop2:
            b     _flash_page_prog
            mvkl  _flash_prog_branch2,B3
            mvkh  _flash_prog_branch2,B3
            add   A6,A1,A1
            cmplt A1,B2,B0
            nop
_flash_prog_branch2:
      [B0]  b     _flash_prog_loop2   
            nop   5   

     
             
;Read back flash and calculate the checksum
            mvk   0,A1              ;A1 = 0, clear checksum
      ||    mvkl  FLASH_START,B4    ;flash start address ->B4
           
            mvk   0,A2              ;A2 = 0, clear counter  
      ||    mvkh  FLASH_START,B4  
      
            mvk   0xff,B6 

_checksum_cal:
            ldb   *B4++,B5
            add   1,A2,A2
            mvkl  BOOT_SIZE+CODE_SIZE-4,B1    ;
            mvkh  BOOT_SIZE+CODE_SIZE-4,B1    ;
            cmplt A2,B1,B0  
            and   B5,B6,B5
            add   A1,B5,A1
      [B0]  b     _checksum_cal
            nop   5

            cmpeq A1,A0,A1
      [A1]  b     _flash_prog_success
            nop   5
            b     _flash_prog_fail
            nop   5
 
 
;******************************************************************************
;* FUNCTION NAME: _flash_page_prog                                            *
;*                                                                            *
;*   Regs Modified     : A3,A4,A6,B1,B4,B5,B6                                 *
;******************************************************************************
_flash_page_prog:
  
           MVKL    .S2     0x90005555,B6     ;  

           MVK     .S1     -86,A3            ; 
||         MVKH    .S2     0x90005555,B6     ;  

           STB     .D2T1   A3,*B6  
           nop             9          ;  
           MVKL    .S2     0x90002aaa,B5     ;  

           MVK     .S1     85,A3             ;  
||         MVKH    .S2     0x90002aaa,B5     ;  

           STB     .D2T1   A3,*B5   
           nop             9         ;  
	
           MVKL    .S1     0x90005555,A3     ;  

           MVK     .S2     -96,B5            ;  
||         MVKH    .S1     0x90005555,A3     ;  

           STB     .D1T2   B5,*A3            ;    
           nop             9
           
	
           ZERO    .L2     B5                ;  
          
;** --------------------------------------------------------------------------*
FLASH_PAGE_PROG_LOOP:               
           LDB             *A4++,B6          ; 
           ADD             1,B5,B5
           NOP             4
           STB     .D2T2   B6,*B4++          ;   
           nop             9
           CMPLT   .L2x    B5,A6,B1          ; 
   [ B1]   B       .S1     FLASH_PAGE_PROG_LOOP ; 
           NOP             5
            
;** --------------------------------------------------------------------------*
FLASH_PAGE_PROG_WAIT:    
	       LDB     .D1T1   *-A4(1),A3          ;  
||         LDB             *-B4(1),B5
           NOP             4
           CMPEQ   .L2X    A3,B5,B1          ; 
   [!B1]   B       .S1     FLASH_PAGE_PROG_WAIT                ; 
           NOP             5
           B       .S2     B3                ; 
           NOP             5
          
;******************************************************************************
;* FUNCTION NAME: _flash_prog_success                                         *
;******************************************************************************
_flash_prog_success:
            mvkl  EMIF_CE1,A4       ;EMIF_CE1 address ->A4
      ||    mvkl  EMIF_CE1_32,B4     ;

            mvkh  EMIF_CE1,A4
      ||    mvkh  EMIF_CE1_32,B4

            mvkl  IO_PORT,B1        ;I/O port address ->B1
      ||    mvkh  0x00000000,A1
	||    stw   B4,*A4
               
            mvkh  IO_PORT,B1        ;I/O port address ->B1
      ||    mvkh  0x07000000,A2
            
            mvk   1,B2
_flash_prog_suc_loop:
            mvkl   500000,B0
            mvkh   500000,B0
_flash_prog_suc_loop1:
       [B0] sub   B0,B2,B0
            stw   A2,*B1
       [B0] b     _flash_prog_suc_loop1
            nop   5
 
            mvkl   500000,B0
            mvkh   500000,B0
  
_flash_prog_suc_loop2:  
       [B0] sub   B0,B2,B0
            stw   A1,*B1
       [B0] b     _flash_prog_suc_loop2
            nop   5

            b     _flash_prog_suc_loop
	      nop   5

;******************************************************************************
;* FUNCTION NAME: _flash_prog_fail                                            *
;******************************************************************************
_flash_prog_fail:
            mvkl  EMIF_CE1,A4       ;EMIF_CE1 address ->A4
      ||    mvkl  EMIF_CE1_32,B4     ;

            mvkh  EMIF_CE1,A4
      ||    mvkh  EMIF_CE1_32,B4

            mvkl  IO_PORT,B1        ;I/O port address ->B1
      ||    mvkh  0x00000000,A1
	||    stw   B4,*A4
               
            mvkh  IO_PORT,B1        ;I/O port address ->B1
            stw   A1,*B1
_flash_prog_fail_loop:
            b     _flash_prog_fail_loop
	      nop   5

_wait:
        mv  a4,b0
_w1
        [b0]sub b0,1,b0
        [b0]b   _w1
        nop 5
        b   b3
        nop 5