28035 Boot ROM Checksum

Hi,

I need to verify the Boot Rom checksum described in TMS320x2803x Piccolo Boot ROM Reference Guide chapter 4.1 (http://www.ti.com/lit/ug/sprugo0a/sprugo0a.pdf).

The documentation states that:

"Taking a 64-bit summation of all addresses within the ROM, except for the checksum locations, generates this checksum."

Does anybody know how to do that? 

I tried the following code which does not work:

#define ROM_ADDR 0x3FE000
#define ROM_CHKS 0x3FFFBC
#define ROM_SIZE 0x2000

typedef unsigned long long Uint64;

Uint16 ROMChecksumOk()
{
Uint16 i, *pword;
Uint64 sum, *psum;

pword = (Uint16*)ROM_ADDR;

sum = 0;
for (i = 0; i < (ROM_CHKS - ROM_ADDR); i++)
{
sum += pword[i];
}
for (i += 4; i < ROM_SIZE; i++)
{
sum += pword[i];
}
psum = (Uint64*)ROM_CHKS;
return sum == *psum;
}

  • I'm trying to do the exact same thing, but just summing from 0x3FE000 to 0x3FFFBB (up to the checksum).

    I cannot get the checksum to match the one in ROM.

    The value I get summing the range above is 0x0000,0000,0DC6,8AD1

    The 64bit checksum value in ROM for the 28031 Rev 0 part that I am using is 0x0000,093D,455C,FE90 .

    The strange thing is, the one in ROM is bigger the maximum possible value; =0x2000 locations * 0xFFFF = 0x1FFF,E000.

  • In reply to jason wiseman:

    C code snippet for the test I am doing:


    #define ROM_CKSM ((const unsigned long long *)(0x3FFFBC)) /*first checksum loc, long,long=bf,be,bd,bc*/
    #define ROM_BOT   ((const unsigned int *)(0x3FE000)) /*smaller number */

    unsigned int *temp_uint_pntr;

    unsigned long long BootROMChecksum,BootROMChecksum_expected;

    temp_uint_pntr=(unsigned int *)ROM_BOT;

    BootROMChecksum=0LL;

    BootROMChecksum_expected=*ROM_CKSM; /* reads as: 0x0000,093D,455C,FE90 same for reading mem location ; this is not possible 8192*65535 = 0x1FFF,E000*/

    while(temp_uint_pntr<(unsigned int *)ROM_CKSM) { BootROMChecksum+=(unsigned long long)*temp_uint_pntr++;  } 

    if(BootROMChecksum!=*ROM_CKSM) /* 0x000000000DC6,8AD1 */
    { /* do something */

    }

  • In reply to jason wiseman:


    All,

    attached file has the checksum algorithm we used, the bootROM sources should've had that function in the ROM sources but they didn't because the function itself was never ROM'd. Most of the devices use this algorithm unless otherwise mentioned so in the device TRM.

    7585.checksum.c


    Best Regards

    santosh

  • In reply to Santosh Athuru:

    Great. Thanks for the quick response.

    Best Regards

    Anders

  • In reply to Anders P. Nielsen:

    Did you get it to work?

    I have not had any success yet using this code. 

    There might be something missing in my code since I do not have checksum.h.

    I made the following assumptions;

    ui16 = unsigned int

    ui32 = unsigned long

    Also, this line confuses me:

    checksum.lowHalfLSW += *currentVal ^ ((unsigned long)currentVal & 0x0000FFFF);

    Should there be a * in the ((unsigned long)currentVal & 0x0000FFFF above , or are we using the address of the pointer in the checksum??

  • In reply to jason wiseman:

    Jason,

    you don't need checksum.h except for ui16 and ui32, below are the typedefs.

    typedef int              i16;
    typedef long             i32;
    typedef unsigned int      ui16;
    typedef unsigned long     ui32;

    jason wiseman

    ui16 = unsigned int

    ui32 = unsigned long

    yes, we include lower 16 bits of address in the checksum. currentVal is 32 bit variable storing the address - initialized by the line "      currentVal = memblock[i].firstAddr;"

    Note that the while computing checksum we avoid the locations which store the checksum in ROM, this is done by hard initializing the memblock structure.  After computing the checksum it is compared against the checksum result stored in ROM itself.

    Let us know if you have any questions. All the information needed is included within the file itself though.

    Best Regards

    Santosh



  • In reply to jason wiseman:

    Yes the code works. I have replaced the ui types with Uint16, Uint32 etc which are used in the examples and changed main into a function that returns Uint16.

    The following code computes the return value.

    pword = (Uint16 *)CHECKSUM_ADDR;
    if ((pword[0] == (Uint16)checksum.lowHalfLSW) &&
    (pword[1] == (Uint16)checksum.lowHalfMSW) &&
    (pword[2] == (Uint16)checksum.highHalfLSW) &&
    (pword[3] == (Uint16)checksum.highHalfMSW))
    return 1;
    else
    return 0;

    Note that I have renamed currentVal to pword and removed lastVal which is only used in one place.

  • In reply to Anders P. Nielsen:

    Thanks,

    My only problem was the initialization of the memblock structure. I dont have a cinit in my system, so I changed memblock to a const.

    Everything works great now.

    I think the documentation for the bootloader needs to be changed. The actual checksum is quite a bit different than described in the document (sum all values in ROM as 64bit except the checksum itself).

    regards,

    Jason