Jeremy Kerr | 459b0ea | 2015-05-04 15:49:08 +0800 | [diff] [blame] | 1 | From de70ad43ccee4dd51e9d38325c7713f590323a47 Mon Sep 17 00:00:00 2001 |
| 2 | From: Jeremy Kerr <jk@ozlabs.org> |
| 3 | Date: Mon, 23 Feb 2015 16:43:53 +0800 |
| 4 | Subject: [PATCH] libflash: Provide an internal parity implementation, to |
| 5 | remove libgcc dependency |
| 6 | |
| 7 | In commit 8f5b8616, we introduced a dependency on libgcc, for the |
| 8 | __builtin_parityl() function in commit 6cfaa3ba. |
| 9 | |
| 10 | However, if we're building with a biarch compiler, we may not have a |
| 11 | libgcc available. |
| 12 | |
| 13 | This commit removes the __builtin_parityl() call, and replaces with the |
| 14 | equivalent instructions, and removes the dependency on libgcc. |
| 15 | |
| 16 | Although this is untested, I have confirmed that the __builtin_parityl() |
| 17 | functions emits the same instructions (on power7 and power8, with |
| 18 | gcc-4.9) as we're using in the parity() function. |
| 19 | |
| 20 | Signed-off-by: Jeremy Kerr <jk@ozlabs.org> |
| 21 | --- |
| 22 | Makefile.main | 5 ++--- |
| 23 | libflash/ecc.c | 14 +++++++++++++- |
| 24 | 2 files changed, 15 insertions(+), 4 deletions(-) |
| 25 | |
| 26 | diff --git a/Makefile.main b/Makefile.main |
| 27 | index 665baf4..b5376fc 100644 |
| 28 | --- a/Makefile.main |
| 29 | +++ b/Makefile.main |
| 30 | @@ -120,7 +120,6 @@ OBJS += $(LIBPORE) |
| 31 | endif |
| 32 | OBJS += $(LIBC) $(CCAN) $(DEVSRC_OBJ) |
| 33 | OBJS_NO_VER = $(OBJS) |
| 34 | -EXTRA_LIBS = -Wl,-lgcc |
| 35 | ALL_OBJS = $(OBJS) version.o |
| 36 | |
| 37 | ALL_OBJS_1 = $(ALL_OBJS) asm/dummy_map.o |
| 38 | @@ -130,12 +129,12 @@ $(TARGET).lid: $(TARGET).elf |
| 39 | $(call Q,OBJCOPY, $(OBJCOPY) -O binary -S $^ $@, $@) |
| 40 | |
| 41 | $(TARGET).tmp.elf: $(ALL_OBJS_1) $(TARGET).lds $(KERNEL) |
| 42 | - $(call Q,LD, $(CC) $(LDFLAGS) -T $(TARGET).lds $(ALL_OBJS_1) $(EXTRA_LIBS) -o $@, $@) |
| 43 | + $(call Q,LD, $(CC) $(LDFLAGS) -T $(TARGET).lds $(ALL_OBJS_1) -o $@, $@) |
| 44 | |
| 45 | asm/real_map.o : $(TARGET).tmp.map |
| 46 | |
| 47 | $(TARGET).elf: $(ALL_OBJS_2) $(TARGET).lds $(KERNEL) |
| 48 | - $(call Q,LD, $(CC) $(LDFLAGS) -T $(TARGET).lds $(ALL_OBJS_2) $(EXTRA_LIBS) -o $@, $@) |
| 49 | + $(call Q,LD, $(CC) $(LDFLAGS) -T $(TARGET).lds $(ALL_OBJS_2) -o $@, $@) |
| 50 | |
| 51 | $(SUBDIRS): |
| 52 | $(call Q,MKDIR,mkdir $@, $@) |
| 53 | diff --git a/libflash/ecc.c b/libflash/ecc.c |
| 54 | index 9293743..3d94594 100644 |
| 55 | --- a/libflash/ecc.c |
| 56 | +++ b/libflash/ecc.c |
| 57 | @@ -88,6 +88,18 @@ static uint8_t syndromematrix[] = { |
| 58 | UE, UE, UE, UE, 4, UE, UE, UE, UE, UE, UE, UE, UE, UE, UE, UE, |
| 59 | }; |
| 60 | |
| 61 | +static uint8_t parity(uint64_t data) |
| 62 | +{ |
| 63 | + uint8_t p; |
| 64 | + |
| 65 | + asm volatile( |
| 66 | + "popcntb %1,%0\n" |
| 67 | + "prtyd %1,%1\n" |
| 68 | + : "=r"(p) : "r"(data)); |
| 69 | + |
| 70 | + return p; |
| 71 | +} |
| 72 | + |
| 73 | /** |
| 74 | * Create the ECC field corresponding to a 8-byte data field |
| 75 | * |
| 76 | @@ -100,7 +112,7 @@ static uint8_t eccgenerate(uint64_t data) |
| 77 | uint8_t result = 0; |
| 78 | |
| 79 | for (i = 0; i < 8; i++) |
| 80 | - result |= __builtin_parityl(eccmatrix[i] & data) << i; |
| 81 | + result |= parity(eccmatrix[i] & data) << i; |
| 82 | |
| 83 | return result; |
| 84 | } |
| 85 | -- |
| 86 | 1.9.1 |
| 87 | |