diff options
Diffstat (limited to 'clib/ecc.h')
-rw-r--r-- | clib/ecc.h | 217 |
1 files changed, 217 insertions, 0 deletions
diff --git a/clib/ecc.h b/clib/ecc.h new file mode 100644 index 0000000..c6f67f7 --- /dev/null +++ b/clib/ecc.h @@ -0,0 +1,217 @@ +/* + * Copyright (c) International Business Machines Corp., 2014 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/*! + * @file ecc.h + * @brief FSP-2 & P8 ECC functions + * @details These functions are used to insert and remove FSP-2 & P8 ECC + * bytes. 8-bits of ECC is inserted every 8 bytes of data such as: + * XXxxXXxxXXxxXXxxYY (where XXxx is 4 nibbles of data and YY is + * 2 nibbles of ECC) + * @author Shaun Wetzstein <shaun@us.ibm.com> + * @date 2011 + */ + +#ifndef __ECC_H__ +#define __ECC_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <stdint.h> +/** Status for the ECC removal function. */ +enum ecc_status + { + CLEAN=0, //< No ECC Error was detected. + CORRECTED=1, //< ECC error detected and corrected. + UNCORRECTABLE=2 //< ECC error detected and uncorrectable. + }; +typedef enum ecc_status ecc_status_t; + +enum ecc_bitfields + { + GD = 0xff, //< Good, ECC matches. + UE = 0xfe, //< Uncorrectable. + E0 = 71, //< Error in ECC bit 0 + E1 = 70, //< Error in ECC bit 1 + E2 = 69, //< Error in ECC bit 2 + E3 = 68, //< Error in ECC bit 3 + E4 = 67, //< Error in ECC bit 4 + E5 = 66, //< Error in ECC bit 5 + E6 = 65, //< Error in ECC bit 6 + E7 = 64 //< Error in ECC bit 7 + }; + +/*! + * @brief Compute the 8-bit ECC (SFC) value given an array of 8 + * unsigned char data values + * @param data [in] Input data + * @return 8-bit SFC ECC value + */ + extern uint8_t sfc_ecc(uint8_t __data[8]); + +/*! + * @brief Copy bytes from the source buffer to the destination buffer while + * computing and injecting an 8-bit SFC ECC value for every 8-bytes + * of source buffer read + * @param __dst [in] Destination buffer + * @param __dst_sz [in] Destination buffer size (in bytes) which must be large + * enough to store both the data and the ECC bytes + * @param __src [in] Source buffer + * @param __src_sz [in] Source buffer size (in bytes) which must be a multiple + * of 8 bytes + * @return -1 if an error occurs, number of bytes copied (including ECC bytes) + * otherwise. + * EINVAL if __src_sz is 0 or not a multiple of 8 bytes + * ENOBUFS if __dst_sz is not large enough to store the ECC bytes + * + */ + extern ssize_t sfc_ecc_inject(void *__restrict __dst, size_t __dst_sz, + const void *__restrict __src, + size_t __src_sz) +/*! @cond */ + __nonnull((1, 3)) /*! @endcond */ ; + +/*! + * @brief Copy bytes from the source buffer to the destination buffer while + * computing and removing an 8-bit SFC ECC value for every 9-bytes + * of source buffer read + * @param __dst [in] Destination buffer + * @param __dst_sz [in] Destination buffer size (in bytes) which must be large + * enough to store the data (after ECC removal) + * @param __src [in] Source buffer + * @param __src_sz [in] Source buffer size (in bytes) which must be a multiple + * 9 bytes + * @return -1 if an error occurs, number of bytes copied (excluding ECC bytes) + * otherwise. if an ECC mismatch error occurs the function returns + * immediately and the return code indicates the number of bytes processed + * prior to the ECC error. + * EINVAL if __src_sz is 0 or not a multiple of 9 bytes + * ENOBUFS if __dst_sz is not large enough to store the ECC bytes + */ + extern ssize_t sfc_ecc_remove(void *__restrict __dst, size_t __dst_sz, + const void *__restrict __src, + size_t __src_sz) +/*! @cond */ + __nonnull((1, 3)) /*! @endcond */ ; + +/*! + * @brief Hexdump the contents of a memory buffer to an output stream. + * This is a buck-standard hexdump except it issolates the ECC value + * in a separate column for easy debug. + * @param __out [in] Output stream + * @param __addr [in] Starting put to display (in bytes) + * @param __buf [in] Data buffer + * @param __buf_sz [in] Data buffer size (in bytes) + * @return -1 if an error occurs, number of bytes copied (excluding ECC bytes) + * otherwise. if an ECC mismatch error occurs the function highlights the + * the corrupted data with red ANSI. + */ + extern void sfc_ecc_dump(FILE * __out, uint32_t __addr, + void *__restrict __buf, size_t __buf_sz) +/*! @cond */ + __nonnull((1, 3)) /*! @endcond */ ; + +/*! + * @brief Copy bytes from the source buffer to the destination buffer while + * computing and injecting an 8-bit P8 ECC value for every 8-bytes + * of source buffer read + * @param __dst [in] Destination buffer + * @param __dst_sz [in] Destination buffer size (in bytes) which must be large + * enough to store both the data and the ECC bytes + * @param __src [in] Source buffer + * @param __src_sz [in] Source buffer size (in bytes) which must be a multiple + * of 8 bytes + * @return -1 if an error occurs, number of bytes copied (including ECC bytes) + * otherwise. + * EINVAL if __src_sz is 0 or not a multiple of 8 bytes + * ENOBUFS if __dst_sz is not large enough to store the ECC bytes + * + */ + extern ssize_t p8_ecc_inject(void *__restrict __dst, size_t __dst_sz, + const void *__restrict __src, + size_t __src_sz) +/*! @cond */ + __nonnull((1, 3)) /*! @endcond */ ; + +/*! + * @brief Copy bytes from the source buffer to the destination buffer while + * computing and removing an 8-bit P8 ECC value for every 9-bytes + * of source buffer read + * @param __dst [in] Destination buffer + * @param __dst_sz [in] Destination buffer size (in bytes) which must be large + * enough to store the data (after ECC removal) + * @param __src [in] Source buffer + * @param __src_sz [in] Source buffer size (in bytes) which must be a multiple + * 9 bytes + * @return 0 - CLEAN for success + * 1 - CORRECTED error - _src [in] buffer changed + * 2 - UNCORRECTABLE error. + */ + extern ecc_status_t p8_ecc_remove(void *__restrict __dst, size_t __dst_sz, + void *__restrict __src, + size_t __src_sz) + +/*! @cond */ + __nonnull((1, 3)) /*! @endcond */ ; + +/*! + * @brief Copy bytes from the source buffer to the destination buffer while + * computing and removing an 8-bit P8 ECC value for every 9-bytes + * of source buffer read + * @param __dst [in] Destination buffer + * @param __dst_sz [in] Destination buffer size (in bytes) which must be large + * enough to store the data (after ECC removal) + * @param __src [in] Source buffer + * @param __src_sz [in] Source buffer size (in bytes) which must be a multiple + * 9 bytes + * @return -1 if an error occurs, number of bytes copied (excluding ECC bytes) + * otherwise. if an ECC mismatch error occurs the function returns + * immediately and the return code indicates zero number of bytes + * processed + * EINVAL if __src_sz is 0 or not a multiple of 9 bytes + * ENOBUFS if __dst_sz is not large enough to store the ECC bytes + */ + extern ssize_t p8_ecc_remove_size(void *__restrict __dst, size_t __dst_sz, + void *__restrict __src, size_t __src_sz) + +/*! @cond */ + __nonnull((1, 3)) /*! @endcond */ ; + +/*! + * @brief Hexdump the contents of a memory buffer to an output stream. + * This is a buck-standard hexdump except it issolates the P8 ECC + * value in a separate column for easy debug. + * @param __out [in] Output stream + * @param __addr [in] Starting put to display (in bytes) + * @param __buf [in] Data buffer + * @param __buf_sz [in] Data buffer size (in bytes) + * @return -1 if an error occurs, number of bytes copied (excluding ECC bytes) + * otherwise. if an ECC mismatch error occurs the function highlights the + * the corrupted data with red ANSI. + */ + extern void p8_ecc_dump(FILE * __out, uint32_t __addr, + void *__restrict __buf, size_t __buf_sz) +/*! @cond */ + __nonnull((1, 3)) /*! @endcond */ ; + +#ifdef __cplusplus +} +#endif +#endif /* __ECC_H__ */ |