aboutsummaryrefslogtreecommitdiff
path: root/libflash/ecc.c
diff options
context:
space:
mode:
authorJeremy Kerr <jk@ozlabs.org>2015-02-23 16:44:16 +0800
committerStewart Smith <stewart@linux.vnet.ibm.com>2015-11-13 13:51:18 +1100
commit66680887735352de0f737b4f823d8e45d3993795 (patch)
tree9fad1bb58af82e6a440370fcc4469d46d3274b16 /libflash/ecc.c
parent66625890a23fa3bf0d5dcaa3432e01dcbe54bc63 (diff)
downloadskiboot-66680887735352de0f737b4f823d8e45d3993795.zip
skiboot-66680887735352de0f737b4f823d8e45d3993795.tar.gz
skiboot-66680887735352de0f737b4f823d8e45d3993795.tar.bz2
libflash: Provide an internal parity implementation, to remove libgcc dependency
In commit 8f5b8616, we introduced a dependency on libgcc, for the __builtin_parityl() function in commit 6cfaa3ba. However, if we're building with a biarch compiler, we may not have a libgcc available. This commit removes the __builtin_parityl() call, and replaces with the equivalent instructions, and removes the dependency on libgcc. Although this is untested, I have confirmed that the __builtin_parityl() functions emits the same instructions (on power7 and power8, with gcc-4.9) as we're using in the parity() function. Signed-off-by: Jeremy Kerr <jk@ozlabs.org> [stewart@linux.vnet.ibm.com: only use inline asm for skiboot build] Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
Diffstat (limited to 'libflash/ecc.c')
-rw-r--r--libflash/ecc.c18
1 files changed, 17 insertions, 1 deletions
diff --git a/libflash/ecc.c b/libflash/ecc.c
index 05c0e14..9cd6ad2 100644
--- a/libflash/ecc.c
+++ b/libflash/ecc.c
@@ -108,6 +108,22 @@ static enum eccbitfields syndromematrix[] = {
UE, UE, UE, UE, 4, UE, UE, UE, UE, UE, UE, UE, UE, UE, UE, UE,
};
+static uint8_t parity(uint64_t data)
+{
+#ifdef __SKIBOOT__
+ uint8_t p;
+
+ asm volatile(
+ "popcntb %1,%0\n"
+ "prtyd %1,%1\n"
+ : "=r"(p) : "r"(data));
+
+ return p;
+#else
+ return __builtin_parityl(data);
+#endif
+}
+
/**
* Create the ECC field corresponding to a 8-byte data field
*
@@ -120,7 +136,7 @@ static uint8_t eccgenerate(uint64_t data)
uint8_t result = 0;
for (i = 0; i < 8; i++)
- result |= __builtin_parityl(eccmatrix[i] & data) << i;
+ result |= parity(eccmatrix[i] & data) << i;
return result;
}