Skip to content

Commit

Permalink
imxrt-flash: support for calulating CRC32 of selected region
Browse files Browse the repository at this point in the history
CRC32 can be calulated for selected region of flash memory or raw partition.
To calculate automatically CRC32 of whole memory/partition set addr and
len to 0.

JIRA: NIL-574
  • Loading branch information
ziemleszcz committed May 14, 2024
1 parent 0956bdc commit 202e123
Show file tree
Hide file tree
Showing 2 changed files with 154 additions and 21 deletions.
141 changes: 123 additions & 18 deletions storage/imxrt-flash/flashsrv.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@
#define IMXRT_FLASH_PRIO 3
#endif

#define CRC32_BUFSZ 1024

/* clang-format off */
enum { flashsrv_memory_inactive = 0, flashsrv_memory_active = 0xff };
/* clang-format on */
Expand Down Expand Up @@ -166,6 +168,54 @@ static int flashsrv_chipErase(uint8_t fID)
}


static uint32_t flashsrv_crc32Update(uint32_t crc32, const uint8_t *data, size_t len)
{
unsigned int i;

while (len--) {
crc32 ^= *data++;
for (i = 0; i < 8; i++) {
crc32 = (crc32 >> 1) ^ ((crc32 & 1) ? 0xedb88320 : 0);
}
}

return crc32;
}


static int flashsrv_calcCrc32(uint8_t fID, size_t offset, size_t len, uint32_t *crc32)
{
flashsrv_memory_t *mem;
uint8_t buf[CRC32_BUFSZ];
uint32_t tmp;
unsigned int i;

Check warning on line 191 in storage/imxrt-flash/flashsrv.c

View workflow job for this annotation

GitHub Actions / call-ci / build (armv7m7-imxrt106x-evk)

unused variable 'i' [-Wunused-variable]

Check warning on line 191 in storage/imxrt-flash/flashsrv.c

View workflow job for this annotation

GitHub Actions / call-ci / build (armv7m7-imxrt117x-evk)

unused variable 'i' [-Wunused-variable]
int res;

res = flashsrv_getFlashMemory(fID, &mem);
if (res < 0) {
return res;
}

tmp = 0xffffffff;

while (len > 0) {
res = flash_directRead(&mem->ctx, offset, buf, len < sizeof(buf) ? len : sizeof(buf));
if (res < 0) {
return res;
}

tmp = flashsrv_crc32Update(tmp, buf, res);

offset += res;
len -= res;
}

*crc32 = ~tmp;

return EOK;
}


/* Callbacks to meterfs - wrappers for basic flash functions */

static ssize_t flashsrv_fsWritef0(struct _meterfs_devCtx_t *devCtx, off_t offs, const void *buff, size_t bufflen)
Expand Down Expand Up @@ -219,6 +269,7 @@ static int flashsrv_fsEraseSectorf1(struct _meterfs_devCtx_t *devCtx, off_t offs
static void flashsrv_devCtl(flashsrv_memory_t *memory, msg_t *msg)
{
uint8_t fID;
uint32_t crc32;
flash_i_devctl_t *idevctl = (flash_i_devctl_t *)msg->i.raw;
flash_o_devctl_t *odevctl = (flash_o_devctl_t *)msg->o.raw;

Expand Down Expand Up @@ -249,12 +300,12 @@ static void flashsrv_devCtl(flashsrv_memory_t *memory, msg_t *msg)
break;

case flashsrv_devctl_eraseSector:
TRACE("imxrt-flashsrv: flashsrv_devctl_eraseSector - addr: %u, id: %u, port: %u.", idevctl->addr, msg->oid.id, msg->oid.port);
if (idevctl->addr >= memory->ctx.properties.size) {
TRACE("imxrt-flashsrv: flashsrv_devctl_eraseSector - addr: %u, id: %u, port: %u.", idevctl->erase.addr, msg->oid.id, msg->oid.port);
if (idevctl->erase.addr >= memory->ctx.properties.size) {
msg->o.err = -EINVAL;
break;
}
flashsrv_eraseSector(memory->fOid.id, idevctl->addr);
flashsrv_eraseSector(memory->fOid.id, idevctl->erase.addr);
msg->o.err = EOK;
break;

Expand All @@ -266,26 +317,43 @@ static void flashsrv_devCtl(flashsrv_memory_t *memory, msg_t *msg)

case flashsrv_devctl_directWrite:
TRACE("imxrt-flashsrv: flashsrv_devctl_directWrite, addr: %u, size: %u, id: %u, port: %u.",
idevctl->addr, msg->i.size, msg->oid.id, msg->oid.port);
idevctl->write.addr, msg->i.size, msg->oid.id, msg->oid.port);

if (idevctl->addr >= memory->ctx.properties.size) {
if (idevctl->write.addr >= memory->ctx.properties.size) {
msg->o.err = -EINVAL;
break;
}

msg->o.err = flashsrv_directWrite(memory->fOid.id, idevctl->addr, msg->i.data, msg->i.size);
msg->o.err = flashsrv_directWrite(memory->fOid.id, idevctl->write.addr, msg->i.data, msg->i.size);
break;

case flashsrv_devctl_directRead:
TRACE("imxrt-flashsrv: flashsrv_devctl_directRead, addr: %u, size: %u, id: %u, port: %u.",
idevctl->addr, msg->o.size, msg->oid.id, msg->oid.port);
idevctl->read.addr, msg->o.size, msg->oid.id, msg->oid.port);

if (idevctl->read.addr >= memory->ctx.properties.size) {
msg->o.err = -EINVAL;
break;
}

msg->o.err = flashsrv_directRead(memory->fOid.id, idevctl->read.addr, msg->o.data, msg->o.size);
break;

if (idevctl->addr >= memory->ctx.properties.size) {
case flashsrv_devctl_calcCrc32:
TRACE("imxrt-flashsrv: flashsrv_devctl_calcCrc32, addr: %u, len: %u, id: %u, port: %u.",
idevctl->crc32.addr, idevctl->crc32.len, msg->oid.id, msg->oid.port);

if (idevctl->crc32.addr == 0 && idevctl->crc32.len == 0) {
/* calculate CRC for whole flash */
idevctl->crc32.len = memory->ctx.properties.size;
}
else if ((idevctl->crc32.addr + idevctl->crc32.len) > memory->ctx.properties.size) {
msg->o.err = -EINVAL;
break;
}

msg->o.err = flashsrv_directRead(memory->fOid.id, idevctl->addr, msg->o.data, msg->o.size);
msg->o.err = flashsrv_calcCrc32(memory->fOid.id, idevctl->crc32.addr, idevctl->crc32.len, &crc32);
odevctl->crc32 = crc32;
break;

default:
Expand All @@ -300,6 +368,7 @@ static void flashsrv_rawCtl(flashsrv_memory_t *memory, msg_t *msg)
int i;
uint32_t sNb;
uint8_t partID;
uint32_t crc32;
flash_i_devctl_t *idevctl = (flash_i_devctl_t *)msg->i.raw;
flash_o_devctl_t *odevctl = (flash_o_devctl_t *)msg->o.raw;

Expand Down Expand Up @@ -336,14 +405,14 @@ static void flashsrv_rawCtl(flashsrv_memory_t *memory, msg_t *msg)

case flashsrv_devctl_eraseSector:
TRACE("imxrt-flashsrv: flashsrv_devctl_eraseSector - addr: %u, id: %u, port: %u.",
idevctl->addr + memory->parts[partID].pHeader->offset, partID, msg->oid.port);
idevctl->erase.addr + memory->parts[partID].pHeader->offset, partID, msg->oid.port);

if (idevctl->addr >= memory->parts[msg->oid.id].pHeader->size) {
if (idevctl->erase.addr >= memory->parts[msg->oid.id].pHeader->size) {
msg->o.err = -EINVAL;
break;
}

flashsrv_eraseSector(memory->fOid.id, memory->parts[partID].pHeader->offset + idevctl->addr);
flashsrv_eraseSector(memory->fOid.id, memory->parts[partID].pHeader->offset + idevctl->erase.addr);
msg->o.err = EOK;
break;

Expand All @@ -360,26 +429,43 @@ static void flashsrv_rawCtl(flashsrv_memory_t *memory, msg_t *msg)

case flashsrv_devctl_directWrite:
TRACE("imxrt-flashsrv: flashsrv_devctl_directWrite, addr: %u, size: %u, id: %u, port: %u.",
idevctl->addr + memory->parts[partID].pHeader->offset, msg->i.size, msg->oid.id, msg->oid.port);
idevctl->write.addr + memory->parts[partID].pHeader->offset, msg->i.size, msg->oid.id, msg->oid.port);

if (idevctl->addr >= memory->parts[msg->oid.id].pHeader->size) {
if (idevctl->write.addr >= memory->parts[msg->oid.id].pHeader->size) {
msg->o.err = -EINVAL;
break;
}

msg->o.err = flashsrv_directWrite(memory->fOid.id, memory->parts[partID].pHeader->offset + idevctl->addr, msg->i.data, msg->i.size);
msg->o.err = flashsrv_directWrite(memory->fOid.id, memory->parts[partID].pHeader->offset + idevctl->write.addr, msg->i.data, msg->i.size);
break;

case flashsrv_devctl_directRead:
TRACE("imxrt-flashsrv: flashsrv_devctl_directRead, addr: %u, size: %u, id: %u, port: %u.",
idevctl->addr + memory->parts[partID].pHeader->offset, msg->o.size, msg->oid.id, msg->oid.port);
idevctl->read.addr + memory->parts[partID].pHeader->offset, msg->o.size, msg->oid.id, msg->oid.port);

if (idevctl->addr >= memory->parts[msg->oid.id].pHeader->size) {
if (idevctl->read.addr >= memory->parts[msg->oid.id].pHeader->size) {
msg->o.err = -EINVAL;
break;
}

msg->o.err = flashsrv_directRead(memory->fOid.id, memory->parts[partID].pHeader->offset + idevctl->addr, msg->o.data, msg->o.size);
msg->o.err = flashsrv_directRead(memory->fOid.id, memory->parts[partID].pHeader->offset + idevctl->read.addr, msg->o.data, msg->o.size);
break;

case flashsrv_devctl_calcCrc32:
TRACE("imxrt-flashsrv: flashsrv_devctl_calcCrc32, addr: %u, len: %u, id: %u, port: %u.",
idevctl->crc32.addr, idevctl->crc32.len, msg->oid.id, msg->oid.port);

if (idevctl->crc32.addr == 0 && idevctl->crc32.len == 0) {
/* calculate CRC for whole partition */
idevctl->crc32.len = memory->parts[partID].pHeader->size;
}
else if ((idevctl->crc32.addr + idevctl->crc32.len) > memory->parts[partID].pHeader->size) {
msg->o.err = -EINVAL;
break;
}

msg->o.err = flashsrv_calcCrc32(memory->fOid.id, memory->parts[partID].pHeader->offset + idevctl->crc32.addr, idevctl->crc32.len, &crc32);
odevctl->crc32 = crc32;
break;

default:
Expand Down Expand Up @@ -914,6 +1000,24 @@ static int flashsrv_getProperties(uint8_t fID, flashsrv_properties_t *p)
}


static int flashsrv_safeCalcCrc32(uint8_t fID, size_t offset, size_t len, uint32_t *crc32)
{
ssize_t ret;
flashsrv_memory_t *mem;

ret = flashsrv_getFlashMemory(fID, &mem);
if (ret < 0) {
return ret;
}

mutexLock(mem->lock);
ret = flashsrv_calcCrc32(fID, offset, len, crc32);
mutexUnlock(mem->lock);

return ret;
}


static ssize_t flashsrv_safeDirectWrite(uint8_t fID, size_t offset, const void *data, size_t size)
{
ssize_t ret;
Expand Down Expand Up @@ -977,6 +1081,7 @@ static int flashsrv_customInit(void)
flashsrv_common.ops.write = flashsrv_safeDirectWrite;
flashsrv_common.ops.eraseSector = flashsrv_safeSectorErase;
flashsrv_common.ops.getProperties = flashsrv_getProperties;
flashsrv_common.ops.calcCrc32 = flashsrv_safeCalcCrc32;

return flashsrv_customIntInit(&flashsrv_common.ops);
}
Expand Down
34 changes: 31 additions & 3 deletions storage/imxrt-flash/imxrt-flashsrv.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,38 @@
/* clang-format off */

enum { flashsrv_devctl_properties = 0, flashsrv_devctl_sync, flashsrv_devctl_eraseSector,
flashsrv_devctl_erasePartition, flashsrv_devctl_directWrite, flashsrv_devctl_directRead };
flashsrv_devctl_erasePartition, flashsrv_devctl_directWrite, flashsrv_devctl_directRead,
flashsrv_devctl_calcCrc32 };

/* clang-format on */


typedef struct {
int type;
uint32_t addr;

union {
/* eraseSector */
struct {
uint32_t addr;
} erase;

/* directWrite */
struct {
uint32_t addr;
} write;

/* directRead */
struct {
uint32_t addr;
} read;

/* calcCrc32 */
struct {
/* set addr & len to 0 for full range */
uint32_t addr;
uint32_t len;
} crc32;
};
} __attribute__((packed)) flash_i_devctl_t;


Expand All @@ -42,7 +66,10 @@ typedef struct {


typedef struct {
flashsrv_properties_t properties;
union {
flashsrv_properties_t properties;
uint32_t crc32;
};
} __attribute__((packed)) flash_o_devctl_t;


Expand All @@ -60,6 +87,7 @@ typedef struct {
ssize_t (*write)(uint8_t fID, size_t offset, const void *data, size_t size);
int (*eraseSector)(uint8_t fID, uint32_t offs);
int (*getProperties)(uint8_t fID, flashsrv_properties_t *p);
int (*calcCrc32)(uint8_t fID, size_t offset, size_t len, uint32_t *crc32);
} flashsrv_partitionOps_t;


Expand Down

0 comments on commit 202e123

Please sign in to comment.