| 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 |  |