#inc ; program to pack/unpack/check the configuration in the TRAP chip ; by V.Angelov ; The format for single conf. reg. ; Bit 31 is 1 ; Bits 30..17 - address ; Bits 16..0 - data ; The format of a block is ; Bits 31 ; Block 0 start_address(30..15) words(14..7) widthM1(6..2) se(1) astep(0) ; - start_address is 16-bit, but all configuration registers are ; below 0x3FFF ; - words (8 bit) is the number of configuration words, not the number ; of 32-bit data words that follow ; words=0 means end of the data => our end marker is just 0 ! ;- widthM1 (5 bit) 0..31, for 1 to 32 bits ; from 1 to 8 bits: 8 bits ; from 9 to 16 bits: 16 bits ; more than 16 bits : 32 bits ; the more precise number of bits can be used later for extensions ;- se 0|1 is sign extension of the data, only in case of width 8 and 16 ; the sign extension should be used carefully! ; e.g. 5 bit signed, if the configuration register is 5 bit, we can consider the ; register as unsigned and this is safer. ;- astep 0|1 is the increment of the TRAP IO address, normally we need 1 or 2: 0|1 ; This program is better executed by cpu0..2, not 3, because cpu3 can not access DMEM in GIO. ; unpack ; input: in c11 the start address in GIO ; output: in c11 is the number of errors, if cnf_compare is defined #def mask_1F = r8 ; 5 bit mask #def mask_FF = r9 ; 8 bit mask #def mask_1FFFF = r10 ; 17 bit mask #def mask_FFFF = r11 ; 16 bit mask ;#def cnf_compare = 1 ; enable compare & counting errors conf_man_un: mov 0x640, r0 spio r0, CTPCTRL mov 0, r0 spio r0, CTPDINI ; initialization mov 0 , r15 ; the DMEM pointer mov c11, r14 ; the GIO access register with autoincrement mov 0x1F, mask_1F ; prepare the masks needed later mov 0xFF, mask_FF iext 0x1FFFF mov 0x1FFFF, mask_1FFFF iext 0xFFFF mov 0xFFFF, mask_FFFF #ifdef cnf_compare mov 0, r6 ; error counter #endif ; start loop - next block/single conf_man_un_next: jmpr cc_busy, 0 lgio+ 0 ; read the next block/single jmpr cc_busy, 0 lpio GBUSR0, r0 shl -7, r0, r1 ; shift the number of words and mask_FF, r1, r1 ; number of words in r1 jmp cc_zero, conf_man_un_exit ; exit if 0 shl 1, r0, r2 ; check the 31th bit jmp cc_carry conf_man_un_sng ; jump to single shl -2, r0, r2 ; shift the width-1 to the right and mask_1F, r2, r2 ; width-1 in r2 and r0, c1, r3 ; step-1 add r3, c1, r3 ; step in r3 shl -15, r0, r0 ; address, not necessary to mask cmp r2, 16 jmp cc_geu, conf_man_un_32 ; 32 bit case cmp r2, 8 jmp cc_geu, conf_man_un_16 ; 16 bit case ; 8 bit case conf_man_un_8: ; step in r3 ; address in r0 ; number of words in r1 jmpr cc_busy, 0 lgio+ 0 ; read the 4 bytes jmpr cc_busy, 0 lpio GBUSR0, r2 ; data to write ; byte 0 and r2, mask_FF, r4 ; mask the upper 24 bits #ifdef cnf_compare lgio 0, r0 jmpr cc_busy, 0 lpio GBUSR0, r5 ; read data and r5, mask_FF, r5 ; mask the upper 24 bits cmp r5, r4 ; compare jmpr cc_eq, +3 ; skip the error inc and the SGIO! add r6, c1, r6 ; count up the errors #endif sgio r4, r0 ; store to GIO the lower byte add r0, r3, r0 ; increment the write address sub r1, c1, r1 ; decrement the number of words jmp cc_zero, conf_man_un_next ; next block/single ; byte 1 shl -8, r2, r2 ; shift the next 8 bits to the right and r2, mask_FF, r4 ; mask the upper 24 bits jmpr cc_busy, 0 #ifdef cnf_compare lgio 0, r0 jmpr cc_busy, 0 lpio GBUSR0, r5 ; read data and r5, mask_FF, r5 ; mask the upper 24 bits cmp r5, r4 ; compare jmpr cc_eq, +3 ; skip the error inc and the SGIO! add r6, c1, r6 ; count up the errors #endif sgio r4, r0 ; store to GIO the byte add r0, r3, r0 ; increment the write address sub r1, c1, r1 ; decrement the number of words jmp cc_zero, conf_man_un_next ; next block/single ; byte 2 shl -8, r2, r2 ; shift the next 8 bits to the right and r2, mask_FF, r4 ; mask the upper 24 bits jmpr cc_busy, 0 #ifdef cnf_compare lgio 0, r0 jmpr cc_busy, 0 lpio GBUSR0, r5 ; read data and r5, mask_FF, r5 ; mask the upper 24 bits cmp r5, r4 ; compare jmpr cc_eq, +3 ; skip the error inc and the SGIO! add r6, c1, r6 ; count up the errors #endif sgio r4, r0 ; store to GIO the byte add r0, r3, r0 ; increment the write address sub r1, c1, r1 ; decrement the number of words jmp cc_zero, conf_man_un_next ; next block/single ; byte 3 shl -8, r2, r4 ; shift the next 8 bits to the right jmpr cc_busy, 0 #ifdef cnf_compare lgio 0, r0 jmpr cc_busy, 0 lpio GBUSR0, r5 ; read data and r5, mask_FF, r5 ; mask the upper 24 bits cmp r5, r4 ; compare jmpr cc_eq, +3 ; skip the error inc and the SGIO! add r6, c1, r6 ; count up the errors #endif sgio r4, r0 ; store to GIO the byte add r0, r3, r0 ; increment the write address sub r1, c1, r1 ; decrement the number of words jmp cc_nzero, conf_man_un_8 ; next 4 bytes jmp cc_uncond, conf_man_un_next ; next block/single ; 16 bit case conf_man_un_16: ; step in r3 ; address in r0 ; number of words in r1 jmpr cc_busy, 0 lgio+ 0 ; read the 2 x 16 bit words jmpr cc_busy, 0 lpio GBUSR0, r2 ; data to write and r2, mask_FFFF, r4 ; mask the upper 16 bits #ifdef cnf_compare lgio 0, r0 jmpr cc_busy, 0 lpio GBUSR0, r5 ; read data and r5, mask_FFFF, r5 ; mask the upper 16 bits cmp r5, r4 ; compare jmpr cc_eq, +3 ; skip the error inc and the SGIO! add r6, c1, r6 ; count up the errors #endif sgio r4, r0 ; store to GIO the lower 16 bits add r0, r3, r0 ; increment the write address sub r1, c1, r1 ; decrement the number of words jmp cc_zero, conf_man_un_next ; next block/single shl -16, r2, r4 ; shift the upper 16 bits to the right jmpr cc_busy, 0 #ifdef cnf_compare lgio 0, r0 jmpr cc_busy, 0 lpio GBUSR0, r5 ; read data and r5, mask_FFFF, r5 ; mask the upper 16 bits cmp r5, r4 ; compare jmpr cc_eq, +3 ; skip the error inc and the SGIO! add r6, c1, r6 ; count up the errors #endif sgio r4, r0 ; store to GIO the upper 16 bits add r0, r3, r0 ; increment the write address sub r1, c1, r1 ; decrement the number of words jmp cc_nzero, conf_man_un_16 ; next 2 x 16 bit words jmp cc_uncond, conf_man_un_next ; 32 bit case conf_man_un_32: ; step in r3 ; address in r0 ; number of words in r1 jmpr cc_busy, 0 lgio+ 0 ; read the 32 bit word jmpr cc_busy, 0 lpio GBUSR0, r2 ; data to write #ifdef cnf_compare lgio 0, r0 jmpr cc_busy, 0 lpio GBUSR0, r5 ; read data cmp r5, r2 ; compare jmpr cc_eq, +3 ; skip the error inc and the SGIO! add r6, c1, r6 ; count up the errors #endif sgio r2, r0 ; store to GIO add r0, r3, r0 ; increment the write address sub r1, c1, r1 ; decrement the number of words jmp cc_nzero, conf_man_un_32 ; next 32 bit word jmp cc_uncond, conf_man_un_next ; next block/single ; single case conf_man_un_sng: and r0, mask_1FFFF, r1 ; data in r1 shl -11, r2, r0 ; r2[31..18] contains the address shl -7, r0, r0 ; address in r0 #ifdef cnf_compare lgio 0, r0 jmpr cc_busy, 0 lpio GBUSR0, r5 ; read data and r5, mask_1FFFF, r5 ; data in r1 cmp r5, r1 ; compare jmp cc_eq, conf_man_un_next ; skip the error inc and the SGIO! add r6, c1, r6 ; count up the errors #endif sgio r1, r0 ; sra+ r1 ; debugging ; nop ; sra+ r0 jmp cc_uncond, conf_man_un_next conf_man_un_exit: #ifdef cnf_compare sgio r6, 0xC03 ; c11 of CPU0 in GIO #endif lpio CTPDOUT, r6 ; the number of CPU clocks jmpr cc_busy, 0 sgio r6, 0xC02 ; c10 of CPU0 in GIO mov cmd_lp, r0 jmpr cc_busy, 0 sgio r0, SMCMD ; go to low power, will be changed later jmpr cc_busy, 0 jmpr cc_uncond, 0 nop