/**************************************************************************** **************************************************************************** Calculate a check sum with target code : INPUT : OUTPUT : RETURN error code ****************************************************************************/ #define WORKSPACE 0xF0008000L /* internal RAM */ #define TARGET_READY 1 #define TARGET_RUNNING 2 static const BDI_InitTypeT initLite5200[] = { {BDI_INIT_PPC_WSPR, 8001 , 2000 }, // Additional memory access delay {BDI_INIT_PPC_WMSR, 0x00000000, 0x00001042}, // MSR: ME,RI {BDI_INIT_PPC_WM32, 0x80000000, 0x0000F000}, // MBAR: internal registers at 0xf0000000 {BDI_INIT_PPC_WM32, 0xF0000004, 0x0000FF00}, // CS0 start = 0xff000000 {BDI_INIT_PPC_WM32, 0xF0000008, 0x0000FFFF}, // CS0 stop = 0xffffffff {BDI_INIT_PPC_WM32, 0xF0000054, 0x00010001}, // CSE: enable CS0, disable CSBOOT {BDI_INIT_PPC_WM32, 0xF0000300, 0x00047800}, // BOOT ctrl }; /* !!! Warning: count is number of 32-bit values !!! !!! Warning: dest has to be 32-bit alligned !!! UINT32 CalcSum(UINT32 count, volatile UINT32* dest) { UINT32 sum; sum = 0; while (count--) { sum += *dest++; } return sum; } */ static BYTE TA_Sum[] = { 0x7c,0x60,0x1b,0x78, /* mr r0,r3 */ 0x2c,0x00,0x00,0x00, /* cmpwi r0,0 */ 0x39,0x60,0x00,0x00, /* li r11,0 */ 0x38,0x63,0xff,0xff, /* addi r3,r3,-1 */ 0x41,0x82,0x00,0x20, /* beq b4c */ 0x7c,0x60,0x1b,0x78, /* mr r0,r3 */ 0x81,0x24,0x00,0x00, /* lwz r9,0(r4) */ 0x2c,0x00,0x00,0x00, /* cmpwi r0,0 */ 0x38,0x84,0x00,0x04, /* addi r4,r4,4 */ 0x7d,0x6b,0x4a,0x14, /* add r11,r11,r9 */ 0x38,0x63,0xff,0xff, /* addi r3,r3,-1 */ 0x40,0x82,0xff,0xe8, /* bne b30 */ 0x7d,0x63,0x5b,0x78, /* mr r3,r11 */ /* enter debug mode via TRAP instruction */ 0x7c,0x00,0x04,0xac, /* sync */ 0x7F,0xE0,0x00,0x08, /* trap */ 0x60,0x00,0x00,0x00, /* nop */ 0x60,0x00,0x00,0x00, /* nop */ 0x60,0x00,0x00,0x00, /* nop */ 0x48,0x00,0x00,0x00, /* b $pc */ /* alternate way to enter debug mode */ 0x7c,0x00,0x04,0xac, /* sync */ 0x38,0x00,0x24,0x40, /* li r0,9280 */ 0x7c,0x00,0x01,0x24, /* mtmsr r0 */ 0x60,0x00,0x00,0x00, /* nop */ 0x60,0x00,0x00,0x00, /* nop */ 0x60,0x00,0x00,0x00, /* nop */ 0x48,0x00,0x00,0x00, /* b $pc */ }; /* #define POLYNOMIAL 0x04c11db7L UINT32 crc32(UINT32 count, volatile UINT8* dest, UINT32* table) { UINT32 crc, i, j; for (i = 0; i < 256; i++ ) { crc = (i << 24 ); for ( j = 0; j < 8; j++ ) { if (crc & 0x80000000L ) crc = ( crc << 1 ) ^ POLYNOMIAL; else crc = ( crc << 1 ); } table[i] = crc; } crc = 0xffffffff; while (count--) { i = ((crc >> 24) ^ *dest++ ) & 0xff; crc = (crc << 8 ) ^ table[i]; } return crc ^ 0xffffffff; } */ static BYTE TA_CRC32[] = { 0x7c,0x68,0x1b,0x78, /* mr r8,r3 */ 0x38,0xe8,0xff,0xff, /* addi r7,r8,-1 */ 0x39,0x60,0x00,0x00, /* li r11,0 */ 0x38,0x00,0x00,0x08, /* li r0,8 */ 0x7c,0x09,0x03,0xa6, /* mtctr r0 */ 0x39,0x2b,0x00,0x01, /* addi r9,r11,1 */ 0x55,0x63,0xc0,0x0e, /* rlwinm r3,r11,24,0,7 */ 0x55,0x6a,0x10,0x3a, /* rlwinm r10,r11,2,0,29 */ 0x2c,0x03,0x00,0x00, /* cmpwi r3,0 */ 0x40,0x80,0x00,0x14, /* bge c54 */ 0x54,0x60,0x08,0x3c, /* rlwinm r0,r3,1,0,30 */ 0x6c,0x00,0x04,0xc1, /* xoris r0,r0,1217 */ 0x68,0x03,0x1d,0xb7, /* xori r3,r0,7607 */ 0x48,0x00,0x00,0x08, /* b c58 */ 0x54,0x63,0x08,0x3c, /* rlwinm r3,r3,1,0,30 */ 0x42,0x00,0xff,0xe4, /* bdnz c3c */ 0x7d,0x2b,0x4b,0x78, /* mr r11,r9 */ 0x28,0x0b,0x00,0xff, /* cmplwi r11,255 */ 0x7c,0x6a,0x29,0x2e, /* stwx r3,r10,r5 */ 0x40,0x81,0xff,0xc0, /* ble c28 */ 0x7d,0x00,0x43,0x78, /* mr r0,r8 */ 0x2c,0x00,0x00,0x00, /* cmpwi r0,0 */ 0x7c,0xe8,0x3b,0x78, /* mr r8,r7 */ 0x38,0x60,0xff,0xff, /* li r3,-1 */ 0x41,0x82,0x00,0x34, /* beq cb0 */ 0x89,0x24,0x00,0x00, /* lbz r9,0(r4) */ 0x54,0x60,0x46,0x3e, /* rlwinm r0,r3,8,24,31 */ 0x7c,0x0b,0x4a,0x78, /* xor r11,r0,r9 */ 0x7d,0x09,0x43,0x78, /* mr r9,r8 */ 0x55,0x6b,0x10,0x3a, /* rlwinm r11,r11,2,0,29 */ 0x7d,0x4b,0x28,0x2e, /* lwzx r10,r11,r5 */ 0x2c,0x09,0x00,0x00, /* cmpwi r9,0 */ 0x54,0x60,0x40,0x2e, /* rlwinm r0,r3,8,0,23 */ 0x7c,0x03,0x52,0x78, /* xor r3,r0,r10 */ 0x38,0x84,0x00,0x01, /* addi r4,r4,1 */ 0x39,0x08,0xff,0xff, /* addi r8,r8,-1 */ 0x40,0x82,0xff,0xd4, /* bne c80 */ 0x7c,0x63,0x18,0xf8, /* not r3,r3 */ /* enter debug mode via TRAP instruction */ 0x7c,0x00,0x04,0xac, /* sync */ 0x7F,0xE0,0x00,0x08, /* trap */ 0x60,0x00,0x00,0x00, /* nop */ 0x60,0x00,0x00,0x00, /* nop */ 0x60,0x00,0x00,0x00, /* nop */ 0x48,0x00,0x00,0x00, /* b $pc */ /* alternate way to enter debug mode */ 0x7c,0x00,0x04,0xac, /* sync */ 0x38,0x00,0x24,0x40, /* li r0,9280 */ 0x7c,0x00,0x01,0x24, /* mtmsr r0 */ 0x60,0x00,0x00,0x00, /* nop */ 0x60,0x00,0x00,0x00, /* nop */ 0x60,0x00,0x00,0x00, /* nop */ 0x48,0x00,0x00,0x00, /* b $pc */ }; static int CalcChecksum(void) { int result; int timeout; DWORD errorAddr; DWORD sum; WORD state; DWORD timeStamp; WORD infoCount; DWORD infoValue[10]; int errorCode; static const BDI_RegTypeT regSum = {BDI_RT_PPC_GPR, 3}; static const BDI_RegTypeT regType[] = { { BDI_RT_PPC_GPR, 3 }, { BDI_RT_PPC_GPR, 4 }, { BDI_RT_PPC_GPR, 5 }, { BDI_RT_PPC_IAR, 0 } }; static const DWORD regCalc[] = { 0x00800000L, /* count */ 0xFF800000L, /* address */ WORKSPACE + 0x400, /* CRC table */ WORKSPACE, /* PC */ }; /* reset and init target */ result = BDI_TargetStartup(0, 10L << 8 | 0, /* MPC5200, 16 MHz JTAG clock */ sizeof initLite5200 / sizeof initLite5200[0], initLite5200); /* load checksum code */ result = BDI_LoadBlock(WORKSPACE, sizeof TA_CRC32, TA_CRC32, &errorAddr); /* calculate sum */ result = BDI_RegisterSet(sizeof regType / sizeof regType[0], regType, regCalc); result = BDI_TargetStart(); timeout = 1000; do { Sleep(100); result = BDI_StateGet(&state, &errorCode, &timeStamp, &infoCount, infoValue); } while ((state == TARGET_RUNNING) && (--timeout > 0)); if (state == TARGET_READY) { result = BDI_RegisterGet(1, ®Sum, &sum); } /* if */ else { return -1; } /* else */ printf("Checksum is 0x%08lx\n", sum); return result; } /* CalcChecksum */