| From de70ad43ccee4dd51e9d38325c7713f590323a47 Mon Sep 17 00:00:00 2001 |
| From: Jeremy Kerr <jk@ozlabs.org> |
| Date: Mon, 23 Feb 2015 16:43:53 +0800 |
| Subject: [PATCH] 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> |
| --- |
| Makefile.main | 5 ++--- |
| libflash/ecc.c | 14 +++++++++++++- |
| 2 files changed, 15 insertions(+), 4 deletions(-) |
| |
| diff --git a/Makefile.main b/Makefile.main |
| index 665baf4..b5376fc 100644 |
| --- a/Makefile.main |
| +++ b/Makefile.main |
| @@ -120,7 +120,6 @@ OBJS += $(LIBPORE) |
| endif |
| OBJS += $(LIBC) $(CCAN) $(DEVSRC_OBJ) |
| OBJS_NO_VER = $(OBJS) |
| -EXTRA_LIBS = -Wl,-lgcc |
| ALL_OBJS = $(OBJS) version.o |
| |
| ALL_OBJS_1 = $(ALL_OBJS) asm/dummy_map.o |
| @@ -130,12 +129,12 @@ $(TARGET).lid: $(TARGET).elf |
| $(call Q,OBJCOPY, $(OBJCOPY) -O binary -S $^ $@, $@) |
| |
| $(TARGET).tmp.elf: $(ALL_OBJS_1) $(TARGET).lds $(KERNEL) |
| - $(call Q,LD, $(CC) $(LDFLAGS) -T $(TARGET).lds $(ALL_OBJS_1) $(EXTRA_LIBS) -o $@, $@) |
| + $(call Q,LD, $(CC) $(LDFLAGS) -T $(TARGET).lds $(ALL_OBJS_1) -o $@, $@) |
| |
| asm/real_map.o : $(TARGET).tmp.map |
| |
| $(TARGET).elf: $(ALL_OBJS_2) $(TARGET).lds $(KERNEL) |
| - $(call Q,LD, $(CC) $(LDFLAGS) -T $(TARGET).lds $(ALL_OBJS_2) $(EXTRA_LIBS) -o $@, $@) |
| + $(call Q,LD, $(CC) $(LDFLAGS) -T $(TARGET).lds $(ALL_OBJS_2) -o $@, $@) |
| |
| $(SUBDIRS): |
| $(call Q,MKDIR,mkdir $@, $@) |
| diff --git a/libflash/ecc.c b/libflash/ecc.c |
| index 9293743..3d94594 100644 |
| --- a/libflash/ecc.c |
| +++ b/libflash/ecc.c |
| @@ -88,6 +88,18 @@ static uint8_t syndromematrix[] = { |
| UE, UE, UE, UE, 4, UE, UE, UE, UE, UE, UE, UE, UE, UE, UE, UE, |
| }; |
| |
| +static uint8_t parity(uint64_t data) |
| +{ |
| + uint8_t p; |
| + |
| + asm volatile( |
| + "popcntb %1,%0\n" |
| + "prtyd %1,%1\n" |
| + : "=r"(p) : "r"(data)); |
| + |
| + return p; |
| +} |
| + |
| /** |
| * Create the ECC field corresponding to a 8-byte data field |
| * |
| @@ -100,7 +112,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; |
| } |
| -- |
| 1.9.1 |
| |