Skip to content

Commit

Permalink
libflash: ecc endian conversions
Browse files Browse the repository at this point in the history
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
Signed-off-by: Oliver O'Halloran <oohall@gmail.com>
  • Loading branch information
npiggin authored and oohal committed Dec 16, 2019
1 parent f27d32f commit 8d9d63b
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 20 deletions.
36 changes: 20 additions & 16 deletions libflash/ecc.c
Expand Up @@ -142,30 +142,34 @@ static inline uint64_t eccflipbit(uint64_t data, uint8_t bit)
return data ^ (1ul << (63 - bit));
}

static int eccbyte(uint64_t *dst, struct ecc64 *src)
static int eccbyte(beint64_t *dst, struct ecc64 *src)
{
uint8_t ecc, badbit;
uint64_t data;

data = src->data;
data = be64_to_cpu(src->data);
ecc = src->ecc;

badbit = eccverify(be64_to_cpu(data), ecc);
badbit = eccverify(data, ecc);
if (badbit == UE) {
FL_ERR("ECC: uncorrectable error: %016lx %02x\n",
(long unsigned int)be64_to_cpu(data), ecc);
FL_ERR("ECC: uncorrectable error: %016llx %02x\n", (unsigned long long int)data, ecc);
return badbit;
}
*dst = data;
if (badbit <= UE)
FL_INF("ECC: correctable error: %i\n", badbit);
if (badbit < 64)
*dst = (uint64_t)be64_to_cpu(eccflipbit(be64_to_cpu(data),
badbit));
*dst = cpu_to_be64(eccflipbit(data, badbit));
else
*dst = cpu_to_be64(data);

return 0;
}

static beint64_t *inc_beint64_by(const void *p, uint64_t i)
{
return (beint64_t *)(((char *)p) + i);
}

static uint64_t *inc_uint64_by(const void *p, uint64_t i)
{
return (uint64_t *)(((char *)p) + i);
Expand Down Expand Up @@ -200,7 +204,7 @@ static uint64_t whole_ecc_structs(uint64_t i)
* @retval: 0 - success
* @retfal: other - fail
*/
int memcpy_from_ecc(uint64_t *dst, struct ecc64 *src, uint64_t len)
int memcpy_from_ecc(beint64_t *dst, struct ecc64 *src, uint64_t len)
{
uint32_t i;

Expand Down Expand Up @@ -256,7 +260,7 @@ int memcpy_from_ecc(uint64_t *dst, struct ecc64 *src, uint64_t len)
* @retval: 0 - success
* @retfal: other - fail
*/
int memcpy_from_ecc_unaligned(uint64_t *dst, struct ecc64 *src,
int memcpy_from_ecc_unaligned(beint64_t *dst, struct ecc64 *src,
uint64_t len, uint8_t alignment)
{
char data[BYTES_PER_ECC];
Expand All @@ -273,14 +277,14 @@ int memcpy_from_ecc_unaligned(uint64_t *dst, struct ecc64 *src,
* required - otherwise jump straight to memcpy_from_ecc()
*/
if (alignment) {
rc = eccbyte((uint64_t *)data, src);
rc = eccbyte((beint64_t *)data, src);
if (rc)
return rc;

memcpy(dst, &data[alignment], bytes_wanted);

src = inc_ecc64_by(src, sizeof(struct ecc64));
dst = inc_uint64_by(dst, bytes_wanted);
dst = inc_beint64_by(dst, bytes_wanted);
len -= bytes_wanted;
}

Expand All @@ -299,7 +303,7 @@ int memcpy_from_ecc_unaligned(uint64_t *dst, struct ecc64 *src,
}

if (len) {
rc = eccbyte((uint64_t *)data, src);
rc = eccbyte((beint64_t *)data, src);
if (rc)
return rc;

Expand All @@ -323,7 +327,7 @@ int memcpy_from_ecc_unaligned(uint64_t *dst, struct ecc64 *src,
* @retval: 0 - success
* @retfal: other - fail
*/
int memcpy_to_ecc(struct ecc64 *dst, const uint64_t *src, uint64_t len)
int memcpy_to_ecc(struct ecc64 *dst, const beint64_t *src, uint64_t len)
{
struct ecc64 ecc_word;
uint64_t i;
Expand Down Expand Up @@ -390,7 +394,7 @@ int memcpy_to_ecc(struct ecc64 *dst, const uint64_t *src, uint64_t len)
* @retfal: other - fail
*/

int memcpy_to_ecc_unaligned(struct ecc64 *dst, const uint64_t *src,
int memcpy_to_ecc_unaligned(struct ecc64 *dst, const beint64_t *src,
uint64_t len, uint8_t alignment)
{
struct ecc64 ecc_word;
Expand All @@ -412,7 +416,7 @@ int memcpy_to_ecc_unaligned(struct ecc64 *dst, const uint64_t *src,
sizeof(struct ecc64) - alignment);

dst = inc_ecc64_by(dst, sizeof(struct ecc64) - alignment);
src = inc_uint64_by(src, bytes_wanted);
src = inc_beint64_by(src, bytes_wanted);
len -= bytes_wanted;
}

Expand Down
8 changes: 4 additions & 4 deletions libflash/ecc.h
Expand Up @@ -16,12 +16,12 @@ struct ecc64 {
uint8_t ecc;
} __attribute__((__packed__));

extern int memcpy_from_ecc(uint64_t *dst, struct ecc64 *src, uint64_t len);
extern int memcpy_from_ecc_unaligned(uint64_t *dst, struct ecc64 *src, uint64_t len,
extern int memcpy_from_ecc(beint64_t *dst, struct ecc64 *src, uint64_t len);
extern int memcpy_from_ecc_unaligned(beint64_t *dst, struct ecc64 *src, uint64_t len,
uint8_t alignment);

extern int memcpy_to_ecc(struct ecc64 *dst, const uint64_t *src, uint64_t len);
extern int memcpy_to_ecc_unaligned(struct ecc64 *dst, const uint64_t *src, uint64_t len,
extern int memcpy_to_ecc(struct ecc64 *dst, const beint64_t *src, uint64_t len);
extern int memcpy_to_ecc_unaligned(struct ecc64 *dst, const beint64_t *src, uint64_t len,
uint8_t alignment);

/*
Expand Down

0 comments on commit 8d9d63b

Please sign in to comment.