changeset 860:cbc49d533b7d

gsm-fw: new implementation of bzero() and some specialized bcopy variants
author Space Falcon <falcon@ivan.Harhan.ORG>
date Sun, 03 May 2015 04:11:41 +0000
parents d32dff865575
children 6ffebb8cec78
files gsm-fw/Makefile gsm-fw/cfgmagic/processconf.sh gsm-fw/finlink/Makefile gsm-fw/finlink/ld-script.src gsm-fw/libiram/Makefile gsm-fw/libiram/bcopy_chunk32.S gsm-fw/libiram/bcopy_words.S gsm-fw/libiram/bzero.S
diffstat 8 files changed, 128 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/gsm-fw/Makefile	Sat May 02 08:21:21 2015 +0000
+++ b/gsm-fw/Makefile	Sun May 03 04:11:41 2015 +0000
@@ -1,5 +1,5 @@
 SUBDIR=	L1 bsp ccd comlib finlink g23m-aci g23m-glue g23m-gsm gpf include \
-	nucleus riviera serial services sprintf sysglue
+	libiram nucleus riviera serial services sprintf sysglue
 
 default:	config.stamp
 	${MAKE} ${MFLAGS} -f Makefile.build $@
--- a/gsm-fw/cfgmagic/processconf.sh	Sat May 02 08:21:21 2015 +0000
+++ b/gsm-fw/cfgmagic/processconf.sh	Sun May 03 04:11:41 2015 +0000
@@ -103,7 +103,7 @@
 # The list of build components: we have some invariants that are always
 # included, and some others that are included depending on the configuration.
 
-BUILD_COMPONENTS="bsp nucleus riviera serial services sprintf sysglue"
+BUILD_COMPONENTS="bsp libiram nucleus riviera serial services sprintf sysglue"
 
 if [ "$CONFIG_INCLUDE_GPF" = 1 ]
 then
--- a/gsm-fw/finlink/Makefile	Sat May 02 08:21:21 2015 +0000
+++ b/gsm-fw/finlink/Makefile	Sun May 03 04:11:41 2015 +0000
@@ -13,7 +13,8 @@
 sinclude ../include/config.mk
 
 BASE_LIBS=	../riviera/librv.a ../nucleus/libplus.xip.a \
-		../nucleus/libplus.iram.a ../sprintf/libsprintf.a
+		../nucleus/libplus.iram.a ../sprintf/libsprintf.a \
+		../libiram/libiram.a
 LIB_DEPEND=	${BASE_LIBS}
 
 ifeq (${CONFIG_INCLUDE_PS},1)
--- a/gsm-fw/finlink/ld-script.src	Sat May 02 08:21:21 2015 +0000
+++ b/gsm-fw/finlink/ld-script.src	Sun May 03 04:11:41 2015 +0000
@@ -78,6 +78,7 @@
 		iramcode.o(.text*)
 		*libplus.iram.a:(.text*)
 		*libgpf.iram.a:(.text*)
+		*libiram.a:(.text*)
 		*libc.a:(.text*)
 		*libgcc.a:(.text*)
 	} > IRAM Put_in_flash
@@ -114,6 +115,7 @@
 		iramcode.o(.bss* COMMON)
 		*libplus.iram.a:(.bss* COMMON)
 		*libgpf.iram.a:(.bss* COMMON)
+		*libiram.a:(.bss* COMMON)
 		*libc.a:(.bss* COMMON)
 		*libgcc.a:(.bss* COMMON)
 		. = ALIGN(4);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gsm-fw/libiram/Makefile	Sun May 03 04:11:41 2015 +0000
@@ -0,0 +1,16 @@
+CC=	arm-elf-gcc
+CFLAGS=	-O2 -fno-builtin -mthumb-interwork
+ASFLAGS=-mthumb-interwork
+AR=	arm-elf-ar
+RANLIB=	arm-elf-ranlib
+
+OBJS=	bcopy_chunk32.o bcopy_words.o bzero.o
+
+all:	libiram.a
+
+libiram.a:	${OBJS}
+	${AR} cru $@ ${OBJS}
+	${RANLIB} $@
+
+clean:
+	rm -f *.[oa] *errs
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gsm-fw/libiram/bcopy_chunk32.S	Sun May 03 04:11:41 2015 +0000
@@ -0,0 +1,27 @@
+/*
+ * bcopy_32byte_chunks() takes the same arguments as BSD bcopy(),
+ * but works on large chunks, specifically:
+ *
+ * - both addresses must be 32-bit word-aligned;
+ * - the count must be a non-zero multiple of 32 bytes;
+ * - the source and destination memory regions must not overlap.
+ *
+ * Arguments:
+ *
+ * R0: source address (word-aligned)
+ * R1: destination address (ditto)
+ * R2: byte count (must be a multiple of 32)
+ */
+
+	.text
+	.code	32
+
+	.globl	bcopy_32byte_chunks
+bcopy_32byte_chunks:
+	stmfd	sp!, {r4-r9}
+1:	ldmia	r0!, {r3-r9,r12}
+	stmia	r1!, {r3-r9,r12}
+	subs	r2, r2, #0x20
+	bhi	1b
+	ldmfd	sp!, {r4-r9}
+	bx	lr
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gsm-fw/libiram/bcopy_words.S	Sun May 03 04:11:41 2015 +0000
@@ -0,0 +1,23 @@
+/*
+ * bcopy_aligned_words() takes the same arguments as BSD bcopy(),
+ * but requires both addresses and the count to be 32-bit word-aligned,
+ * and assumes that the source and destination memory regions
+ * do not overlap.  Furthermore, the count is expected to be non-zero.
+ *
+ * Arguments:
+ *
+ * R0: source address (word-aligned)
+ * R1: destination address (ditto)
+ * R2: byte count (must be a multiple of 4)
+ */
+
+	.text
+	.code	32
+
+	.globl	bcopy_aligned_words
+bcopy_aligned_words:
+1:	ldr	r3, [r0], #4
+	str	r3, [r1], #4
+	subs	r2, r2, #4
+	bhi	1b
+	bx	lr
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gsm-fw/libiram/bzero.S	Sun May 03 04:11:41 2015 +0000
@@ -0,0 +1,56 @@
+/*
+ * This ARM implementation of bzero() has been derived from:
+ *
+ *  linux/arch/arm/lib/memzero.S
+ *
+ *  Copyright (C) 1995-2000 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+	.text
+	.code	32
+	.globl	bzero
+
+/*
+ * Align the pointer in r0.  r3 contains the number of bytes that we are
+ * mis-aligned by, and r1 is the number of bytes.  If r1 < 4, then we
+ * don't bother; we use byte stores instead.
+ */
+1:	subs	r1, r1, #4		@ 1 do we have enough
+	blt	5f			@ 1 bytes to align with?
+	cmp	r3, #2			@ 1
+	strltb	r2, [r0], #1		@ 1
+	strleb	r2, [r0], #1		@ 1
+	strb	r2, [r0], #1		@ 1
+	add	r1, r1, r3		@ 1 (r1 = r1 - (4 - r3))
+/*
+ * The pointer is now aligned and the length is adjusted.  Try doing the
+ * bzero again.
+ */
+
+bzero:
+	mov	r2, #0			@ 1
+	ands	r3, r0, #3		@ 1 unaligned?
+	bne	1b			@ 1
+/*
+ * r3 = 0, and we know that the pointer in r0 is aligned to a word boundary.
+ */
+3:	subs	r1, r1, #4
+	strge	r2, [r0], #4
+	bgt	3b			@ 1
+	bxeq	lr			@ 1/2 quick exit
+/*
+ * No need to correct the count; we're only testing bits from now on
+ *
+ * When we get here, we've got less than 4 bytes to zero.  We
+ * may have an unaligned pointer as well.
+ */
+5:	tst	r1, #2			@ 1 2 bytes or more?
+	strneb	r2, [r0], #1		@ 1
+	strneb	r2, [r0], #1		@ 1
+	tst	r1, #1			@ 1 a byte left over
+	strneb	r2, [r0], #1		@ 1
+	bx	lr			@ 1