/* Copyright 2013-2014 IBM Corp.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * 	http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
 * implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/* This is based on the hostboot ecc code */

#include <stdint.h>
#include <inttypes.h>
#include <string.h>

#include <ccan/endian/endian.h>

#include "libflash.h"
#include "ecc.h"

/* Bit field identifiers for syndrome calculations. */
enum eccbitfields
{
        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
        /* 0-63 Correctable bit in byte */
};

/*
 * Matrix used for ECC calculation.
 *
 *  Each row of this is the set of data word bits that are used for
 *  the calculation of the corresponding ECC bit.  The parity of the
 *  bitset is the value of the ECC bit.
 *
 *  ie. ECC[n] = eccMatrix[n] & data
 *
 *  Note: To make the math easier (and less shifts in resulting code),
 *        row0 = ECC7.  HW numbering is MSB, order here is LSB.
 *
 *  These values come from the HW design of the ECC algorithm.
 */
static uint64_t eccmatrix[] = {
        0x0000e8423c0f99ffull,
        0x00e8423c0f99ff00ull,
        0xe8423c0f99ff0000ull,
        0x423c0f99ff0000e8ull,
        0x3c0f99ff0000e842ull,
        0x0f99ff0000e8423cull,
        0x99ff0000e8423c0full,
        0xff0000e8423c0f99ull
};

/**
 * Syndrome calculation matrix.
 *
 *  Maps syndrome to flipped bit.
 *
 *  To perform ECC correction, this matrix is a look-up of the bit
 *  that is bad based on the binary difference of the good and bad
 *  ECC.  This difference is called the "syndrome".
 *
 *  When a particular bit is on in the data, it cause a column from
 *  eccMatrix being XOR'd into the ECC field.  This column is the
 *  "effect" of each bit.  If a bit is flipped in the data then its
 *  "effect" is missing from the ECC.  You can calculate ECC on unknown
 *  quality data and compare the ECC field between the calculated
 *  value and the stored value.  If the difference is zero, then the
 *  data is clean.  If the difference is non-zero, you look up the
 *  difference in the syndrome table to identify the "effect" that
 *  is missing, which is the bit that is flipped.
 *
 *  Notice that ECC bit flips are recorded by a single "effect"
 *  bit (ie. 0x1, 0x2, 0x4, 0x8 ...) and double bit flips are identified
 *  by the UE status in the table.
 *
 *  Bits are in MSB order.
 */
static enum eccbitfields syndromematrix[] = {
        GD, E7, E6, UE, E5, UE, UE, 47, E4, UE, UE, 37, UE, 35, 39, UE,
        E3, UE, UE, 48, UE, 30, 29, UE, UE, 57, 27, UE, 31, UE, UE, UE,
        E2, UE, UE, 17, UE, 18, 40, UE, UE, 58, 22, UE, 21, UE, UE, UE,
        UE, 16, 49, UE, 19, UE, UE, UE, 23, UE, UE, UE, UE, 20, UE, UE,
        E1, UE, UE, 51, UE, 46,  9, UE, UE, 34, 10, UE, 32, UE, UE, 36,
        UE, 62, 50, UE, 14, UE, UE, UE, 13, UE, UE, UE, UE, UE, UE, UE,
        UE, 61,  8, UE, 41, UE, UE, UE, 11, UE, UE, UE, UE, UE, UE, UE,
        15, UE, UE, UE, UE, UE, UE, UE, UE, UE, 12, UE, UE, UE, UE, UE,
        E0, UE, UE, 55, UE, 45, 43, UE, UE, 56, 38, UE,  1, UE, UE, UE,
        UE, 25, 26, UE,  2, UE, UE, UE, 24, UE, UE, UE, UE, UE, 28, UE,
        UE, 59, 54, UE, 42, UE, UE, 44,  6, UE, UE, UE, UE, UE, UE, UE,
         5, UE, UE, UE, UE, UE, UE, UE, UE, UE, UE, UE, UE, UE, UE, UE,
        UE, 63, 53, UE,  0, UE, UE, UE, 33, UE, UE, UE, UE, UE, UE, UE,
         3, UE, UE, 52, UE, UE, UE, UE, UE, UE, UE, UE, UE, UE, UE, UE,
         7, UE, UE, UE, UE, UE, UE, UE, UE, 60, UE, UE, UE, UE, UE, UE,
        UE, UE, UE, UE,  4, UE, UE, UE, UE, UE, UE, UE, UE, UE, UE, UE,
};

/**
 * Create the ECC field corresponding to a 8-byte data field
 *
 *  @data:	The 8 byte data to generate ECC for.
 *  @return:	The 1 byte ECC corresponding to the data.
 */
static uint8_t eccgenerate(uint64_t data)
{
	int i;
	uint8_t result = 0;

	for (i = 0; i < 8; i++)
		result |= __builtin_parityll(eccmatrix[i] & data) << i;

	return result;
}

/**
 * Verify the data and ECC match or indicate how they are wrong.
 *
 * @data:	The data to check ECC on.
 * @ecc:	The [supposed] ECC for the data.
 *
 * @return:	eccBitfield or 0-64.
 *
 * @retval GD - Indicates the data is good (matches ECC).
 * @retval UE - Indicates the data is uncorrectable.
 * @retval all others - Indication of which bit is incorrect.
 */
static enum eccbitfields eccverify(uint64_t data, uint8_t ecc)
{
	return syndromematrix[eccgenerate(data) ^ ecc];
}

/* IBM bit ordering */
static inline uint64_t eccflipbit(uint64_t data, uint8_t bit)
{
	if (bit > 63)
		return data;

	return data ^ (1ul << (63 - bit));
}

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

	data = src->data;
	ecc = src->ecc;

	badbit = eccverify(be64_to_cpu(data), ecc);
	if (badbit == UE) {
		FL_ERR("ECC: uncorrectable error: %016lx %02x\n",
				(long unsigned int)be64_to_cpu(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));

	return 0;
}

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

static struct ecc64 *inc_ecc64_by(struct ecc64 *p, uint64_t i)
{
	return (struct ecc64 *)(((char *)p) + i);
}

static uint64_t whole_ecc_bytes(uint64_t i)
{
	return i & ~(BYTES_PER_ECC - 1);
}

static uint64_t whole_ecc_structs(uint64_t i)
{
	return whole_ecc_bytes(i) >> 3;
}

/**
 * Copy data from an input buffer with ECC to an output buffer without ECC.
 * Correct it along the way and check for errors.
 *
 * @dst:	destination buffer without ECC
 * @src:	source buffer with ECC
 * @len:	number of bytes of data to copy (without ecc).
 *                   Must be 8 byte aligned.
 *
 * @return:	Success or error
 *
 * @retval: 0 - success
 * @retfal: other - fail
 */
int memcpy_from_ecc(uint64_t *dst, struct ecc64 *src, uint64_t len)
{
	uint32_t i;

	if (len & 0x7) {
		/* TODO: we could probably handle this */
		FL_ERR("ECC data length must be 8 byte aligned length:%" PRIx64  "\n",
		       len);
		return -1;
	}

	/* Handle in chunks of 8 bytes, so adjust the length */
	len >>= 3;

	for (i = 0; i < len; i++) {
		int rc;
		rc = eccbyte(dst, src + i);
		if (rc)
			return rc;
		dst++;
	}
	return 0;
}

/**
 * Copy data from an input buffer with ECC to an output buffer without ECC.
 * Correct it along the way and check for errors.
 *
 * Unlike memcmp_from_ecc() which requires that the first byte into
 * dst be the first byte in src (which must also be aligned to a
 * struct ecc64 struct boundary) this function can cope with the first
 * byte in dst not being the first byte in src.
 *
 * Note: src MUST still be aligned to a struct ecc64 otherwise ECC
 * calculations are impossible.
 *
 * The alignment parameter species the number of bytes present at the
 * start of src that should be skipped and not written to dst. Once
 * again, these bytes must be in src otherwise the ECC cannot be
 * checked.
 *
 * len also doesn't have any value limitation for this function. Of
 * course src must contain an exact multiple of struct ecc64 otherwise
 * ECC calculation cannot be performed but this function won't copy
 * the entirety of the last src data word if len is not mutiple of 8
 *
 * @dst:		destination buffer without ECC
 * @src:		source buffer with ECC
 * @len:		number of bytes of data to copy (without ecc).
 * @alignment:	number of leading bytes in src which shouldn't be
 * 				copied to dst
 * @return:	Success or error
 *
 * @retval: 0 - success
 * @retfal: other - fail
 */
int memcpy_from_ecc_unaligned(uint64_t *dst, struct ecc64 *src,
		uint64_t len, uint8_t alignment)
{
	char data[BYTES_PER_ECC];
	uint8_t bytes_wanted;
	int rc;

	if (alignment > 8)
		return -1;

	bytes_wanted = BYTES_PER_ECC - alignment;

	/*
	 * Only actually do the first calculation if an alignment is
	 * required - otherwise jump straight to memcpy_from_ecc()
	 */
	if (alignment) {
		rc = eccbyte((uint64_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);
		len -= bytes_wanted;
	}

	if (len >= BYTES_PER_ECC) {
		rc = memcpy_from_ecc(dst, src, whole_ecc_bytes(len));
		if (rc)
			return rc;

		/*
		 * It helps to let the compiler to the pointer arithmetic
		 * here, (dst and src are different types)
		 */
		dst += whole_ecc_structs(len);
		src += whole_ecc_structs(len);
		len -= whole_ecc_bytes(len);
	}

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

		memcpy(dst, data, len);
	}

	return 0;
}

/**
 * Copy data from an input buffer without ECC to an output buffer with ECC.
 *
 * @dst:	destination buffer with ECC
 * @src:	source buffer without ECC
 * @len:	number of bytes of data to copy (without ecc, length of src).
 *       Note: dst must be big enough to hold ecc bytes as well.
 *                   Must be 8 byte aligned.
 *
 * @return:	success or failure
 *
 * @retval: 0 - success
 * @retfal: other - fail
 */
int memcpy_to_ecc(struct ecc64 *dst, const uint64_t *src, uint64_t len)
{
	struct ecc64 ecc_word;
	uint64_t i;

	if (len & 0x7) {
		/* TODO: we could probably handle this */
		FL_ERR("Data to add ECC bytes to must be 8 byte aligned length: %"
		       PRIx64 "\n", len);
		return -1;
	}

	/* Handle in chunks of 8 bytes, so adjust the length */
	len >>= 3;

	for (i = 0; i < len; i++) {
		ecc_word.ecc = eccgenerate(be64_to_cpu(*(src + i)));
		ecc_word.data = *(src + i);

		*(dst + i) = ecc_word;
	}

	return 0;
}

/**
 * Copy data from an input buffer without ECC to an output buffer with ECC.
 *
 * Unlike memcmp_to_ecc() which requires that the first byte in src be
 * the first byte of a struct ecc64 structure this function does not
 * have this requirement.
 *
 * Like memcpy_to_ecc_unaligned() the alignment parameter specfies the
 * number of bytes in the first src word that are missing and would be
 * required to form a struct ecc64 structure.
 *
 * It must be noted here that extra work IN THE CALLER must be done
 * if your data is unaligned. In order to peform ECC calculations
 * whatever portions of the ecc words are missing in src must be in
 * dst.
 *
 * For example, if there is an alignment value of 1 then this means
 * there is 1 byte (of the total of 8 bytes) missing in src which is
 * needed to calculate the first ECC byte. Therefore the first byte of
 * dst MUST CONTAIN IT!
 *
 * The same problem exists for the end of the buffer where src may not
 * end exactly aligned, if this is the case dst must contain the
 * required bytes to calculate the last ECC byte - they should be in
 * dst where they would normally be found if src did contain those
 * bytes.
 *
 * @dst:		destination buffer with ECC
 * @src:		source buffer without ECC
 * @len:		number of bytes of data to copy (without ecc, length of src).
 * @alignment:	The number of bytes 'missing' from the start of src to
 * 				be struct ecc64 aligned
 *
 *       Note: dst must be big enough to hold ecc bytes as well.
 *                   Must be 8 byte aligned.
 *
 * @return:	success or failure
 *
 * @retval: 0 - success
 * @retfal: other - fail
 */

int memcpy_to_ecc_unaligned(struct ecc64 *dst, const uint64_t *src,
		uint64_t len, uint8_t alignment)
{
	struct ecc64 ecc_word;
	uint8_t bytes_wanted;
	int rc;

	bytes_wanted = BYTES_PER_ECC - alignment;

	/*
	 * Only actually do the first calculation if an alignment is
	 * required - otherwise jump straight to memcpy_to_ecc()
	 */
	if (alignment) {
		ecc_word.data = dst->data;
		memcpy(inc_uint64_by(&ecc_word.data, alignment), src, bytes_wanted);

		ecc_word.ecc = eccgenerate(be64_to_cpu(ecc_word.data));
		memcpy(dst, inc_ecc64_by(&ecc_word, alignment),
				sizeof(struct ecc64) - alignment);

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

	if (len >= BYTES_PER_ECC) {
		rc = memcpy_to_ecc(dst, src, whole_ecc_bytes(len));
		if (rc)
			return rc;

		/*
		 * It helps to let the compiler to the pointer arithmetic
		 * here, (dst and src are different types)
		 */
		dst += whole_ecc_structs(len);
		src += whole_ecc_structs(len);
		len -= whole_ecc_bytes(len);
	}

	if (len) {
		bytes_wanted = BYTES_PER_ECC - len;

		ecc_word.data = *src;
		memcpy(inc_uint64_by(&ecc_word.data, len), inc_ecc64_by(dst, len),
				bytes_wanted);
		ecc_word.ecc = eccgenerate(be64_to_cpu(ecc_word.data));

		*dst = ecc_word;
	}

	return 0;
}
