cse: add simple crc32 function to calculate the v2.5 header checksum

Add simple crc32 function to calculate the checksum for v2.5 headers.
Implementation is very simple using shift register as we don't require
speed. Calculate the v2.5 header checksum with crc-32/iso-hdlc
parameters.

Signed-off-by: Jaska Uimonen <jaska.uimonen@linux.intel.com>
Signed-off-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
This commit is contained in:
Jaska Uimonen 2020-10-26 10:51:17 +00:00 committed by Liam Girdwood
parent 48ba01ec45
commit 8478c03483
2 changed files with 84 additions and 0 deletions

View File

@ -6,6 +6,7 @@
// Keyon Jie <yang.jie@linux.intel.com>
#include <stdio.h>
#include <stdbool.h>
#include <rimage/rimage.h>
#include <rimage/cse.h>
#include <rimage/manifest.h>
@ -34,3 +35,74 @@ void ri_cse_create(struct image *image)
}
cse_hdr->checksum = 0x100 - csum;
}
static uint32_t crc32(uint8_t *input, int size, uint32_t poly, uint32_t init,
bool rev_in, bool rev_out, uint32_t xor_out)
{
uint32_t crc = init;
uint32_t t32;
uint8_t val;
uint8_t t8;
int i;
int j;
for (i = 0; i < size; i++) {
val = input[i];
if (rev_in) {
t8 = 0;
for (j = 0; j < 8; j++) {
if (val & (1 << j))
t8 |= (uint8_t)(1 << (7 - j));
}
val = t8;
}
crc ^= (uint32_t)(val << 24);
for (j = 0; j < 8; j++) {
if (crc & 0x80000000)
crc = (uint32_t)((crc << 1) ^ poly);
else
crc <<= 1;
}
}
if (rev_out) {
t32 = 0;
for (i = 0; i < 32; i++) {
if (crc & (1 << i))
t32 |= (uint32_t)(1 << (31 - i));
}
crc = t32;
}
return crc ^ xor_out;
}
void ri_cse_create_v2_5(struct image *image)
{
struct CsePartitionDirHeader_v2_5 *cse_hdr = image->fw_image;
struct sof_man_adsp_meta_file_ext_v2_5 *meta = image->fw_image +
MAN_META_EXT_OFFSET_V2_5;
struct CsePartitionDirEntry *cse_entry =
image->fw_image + sizeof(*cse_hdr);
uint8_t *val = image->fw_image;
int size;
fprintf(stdout, " cse: completing CSE V2.5 manifest\n");
cse_entry[2].length = meta->comp_desc[0].limit_offset -
MAN_DESC_OFFSET_V1_8;
/*
* calculate checksum using crc-32/iso-hdlc
*
* polynomial: 0x04c11db7
* initial value: 0xffffffff
* reverse input: true
* reverse output: true
* xor output: 0xffffffff
*/
size = (sizeof(*cse_hdr) + (sizeof(*cse_entry) * MAN_CSE_PARTS));
cse_hdr->checksum = crc32(val, size, 0x04c11db7, 0xffffffff, true, true, 0xffffffff);
fprintf(stdout, " cse: cse checksum %x\n", cse_hdr->checksum);
}

View File

@ -22,6 +22,17 @@ struct CsePartitionDirHeader {
uint8_t partition_name[4];
} __attribute__((packed));
struct CsePartitionDirHeader_v2_5 {
uint32_t header_marker;
uint32_t nb_entries;
uint8_t header_version;
uint8_t entry_version;
uint8_t header_length;
uint8_t not_used; /* set to zero - old checksum */
uint8_t partition_name[4];
uint32_t checksum; /* crc32 checksum */
} __attribute__((packed));
struct CsePartitionDirEntry {
uint8_t entry_name[12];
uint32_t offset;
@ -30,5 +41,6 @@ struct CsePartitionDirEntry {
} __attribute__((packed));
void ri_cse_create(struct image *image);
void ri_cse_create_v2_5(struct image *image);
#endif