Branch data Line data Source code
1 : : // SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later 2 : : /* 3 : : * This is based on the hostboot ecc code 4 : : * 5 : : * Copyright 2013-2018 IBM Corp. 6 : : */ 7 : : 8 : : #ifndef __ECC_H 9 : : #define __ECC_H 10 : : 11 : : #include <stdint.h> 12 : : #include <ccan/endian/endian.h> 13 : : 14 : : struct ecc64 { 15 : : beint64_t data; 16 : : uint8_t ecc; 17 : : } __attribute__((__packed__)); 18 : : 19 : : extern int memcpy_from_ecc(beint64_t *dst, struct ecc64 *src, uint64_t len); 20 : : extern int memcpy_from_ecc_unaligned(beint64_t *dst, struct ecc64 *src, uint64_t len, 21 : : uint8_t alignment); 22 : : 23 : : extern int memcpy_to_ecc(struct ecc64 *dst, const beint64_t *src, uint64_t len); 24 : : extern int memcpy_to_ecc_unaligned(struct ecc64 *dst, const beint64_t *src, uint64_t len, 25 : : uint8_t alignment); 26 : : 27 : : /* 28 : : * Calculate the size of a buffer if ECC is added 29 : : * 30 : : * We add 1 byte of ecc for every 8 bytes of data. So we need to round up to 8 31 : : * bytes length and then add 1/8 32 : : */ 33 : : #ifndef ALIGN_UP 34 : : #define ALIGN_UP(_v, _a) (((_v) + (_a) - 1) & ~((_a) - 1)) 35 : : #endif 36 : : 37 : : #define BYTES_PER_ECC 8 38 : : 39 : 119 : static inline uint64_t ecc_size(uint64_t len) 40 : : { 41 : 119 : return ALIGN_UP(len, BYTES_PER_ECC) >> 3; 42 : : } 43 : : 44 : 119 : static inline uint64_t ecc_buffer_size(uint64_t len) 45 : : { 46 : 119 : return ALIGN_UP(len, BYTES_PER_ECC) + ecc_size(len); 47 : : } 48 : : 49 : : static inline int ecc_buffer_size_check(uint64_t len) 50 : : { 51 : : return len % (BYTES_PER_ECC + 1); 52 : : } 53 : : 54 : 0 : static inline uint64_t ecc_buffer_size_minus_ecc(uint64_t len) 55 : : { 56 : 0 : return len * BYTES_PER_ECC / (BYTES_PER_ECC + 1); 57 : : } 58 : : 59 : 123 : static inline uint64_t ecc_buffer_align(uint64_t start, uint64_t pos) 60 : : { 61 : 123 : return pos - ((pos - start) % (BYTES_PER_ECC + 1)); 62 : : } 63 : : 64 : : #endif