# HG changeset patch # User Space Falcon # Date 1430626301 0 # Node ID cbc49d533b7daadae6afdac1f47742a029d584ab # Parent d32dff865575e2f9e148b1efca4e9a841d9b6283 gsm-fw: new implementation of bzero() and some specialized bcopy variants diff -r d32dff865575 -r cbc49d533b7d gsm-fw/Makefile --- 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 $@ diff -r d32dff865575 -r cbc49d533b7d gsm-fw/cfgmagic/processconf.sh --- 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 diff -r d32dff865575 -r cbc49d533b7d gsm-fw/finlink/Makefile --- 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) diff -r d32dff865575 -r cbc49d533b7d gsm-fw/finlink/ld-script.src --- 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); diff -r d32dff865575 -r cbc49d533b7d gsm-fw/libiram/Makefile --- /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 diff -r d32dff865575 -r cbc49d533b7d gsm-fw/libiram/bcopy_chunk32.S --- /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 diff -r d32dff865575 -r cbc49d533b7d gsm-fw/libiram/bcopy_words.S --- /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 diff -r d32dff865575 -r cbc49d533b7d gsm-fw/libiram/bzero.S --- /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