SPRAC71B February 2019 – October 2023
A copy table has the following format:
typedef struct
{
uint16 rec_size;
uint16 num_recs;
COPY_RECORD recs[num_recs];
} COPY_TABLE;
rec_size is a 16-bit unsigned integer that specifies the size in 16-bit units of each copy record in the table.
num_recs is a 16-bit unsigned integer that specifies the number of copy records in the table.
The remainder of the table consists of a vector of copy records, each of which has the following format:
typedef struct
{
uint32 load_addr; /* 32-bit storage for data or code pointer */
uint32 run_addr; /* 32-bit storage for data or code pointer */
uint32 size;
} COPY_RECORD;
The load_addr field is the address of the source data in offline storage.
The run_addr field is the destination address to which the data will be copied.
The size field is overloaded:
The rest of the source data is format-specific. The copy-in routine reads the first 16 bits of the source data to determine its format/index, uses that value to index into the handler table, and invokes the handler to finish decompressing and copying the data.
The handler table has the following format:
The copy-in routine references the table via special linker-defined symbols as shown. The assignment of handler indexes is not fixed; the linker reassigns indices for each application depending on what decompression routines are needed for that application. The handler table is generated into the .cinit section of the executable file.
The run-time support library in the TI toolchain contains handler functions for all the supported compression formats. The first argument to the handler function is the address pointing to the 16 bits after the 16-bit index. The second argument is the destination address.
Reference Implementation of Copy-In Function provides a reference implementation of the copy_in function:
typedef void (*handler_fptr)(const unsigned char *src, unsigned char *dst);
extern int __TI_Handler_Table_Base;
void copy_in(COPY_TABLE *tp)
{
unsigned short i;
for (i = 0; i < tp->num_recs; i++)
{
COPY_RECORD crp = tp->recs[i];
const unsigned char *ld_addr = (const unsigned char *)crp.load_addr;
unsigned char *rn_addr = (unsigned char *)crp.run_addr;
if (crp.size) // not compressed, just copy the data.
memcpy(rn_addr, ld_addr, crp.size);
else // invoke decompression routine
{
unsigned char index = *ld_addr++;
handler_fptr hndl = ((handler_fptr *)(__TI_Handler_Table_Base))[index];
(*hndl)(ld_addr, rn_addr);
}
}
}