summaryrefslogtreecommitdiffstats
path: root/arch/unicore32/lib
diff options
context:
space:
mode:
authorGuanXuetao <gxt@mprc.pku.edu.cn>2011-01-15 18:23:09 +0800
committerGuanXuetao <gxt@mprc.pku.edu.cn>2011-03-17 09:19:13 +0800
commit96cf5185a95e0b304596fe19edcf8dfcd5c10699 (patch)
treeaebdf44fdfa8841577171df18cb1b0745b54d64e /arch/unicore32/lib
parent77c93b2f2388b974253af4149aa025b4751f92ad (diff)
unicore32 additional architecture files: low-level lib: misc
This patch implements the rest low-level libraries. Signed-off-by: Guan Xuetao <gxt@mprc.pku.edu.cn> Acked-by: Arnd Bergmann <arnd@arndb.de>
Diffstat (limited to 'arch/unicore32/lib')
-rw-r--r--arch/unicore32/lib/Makefile27
-rw-r--r--arch/unicore32/lib/delay.S51
-rw-r--r--arch/unicore32/lib/findbit.S98
3 files changed, 176 insertions, 0 deletions
diff --git a/arch/unicore32/lib/Makefile b/arch/unicore32/lib/Makefile
new file mode 100644
index 00000000000..87229a558b3
--- /dev/null
+++ b/arch/unicore32/lib/Makefile
@@ -0,0 +1,27 @@
+#
+# linux/arch/unicore32/lib/Makefile
+#
+# Copyright (C) 2001-2010 GUAN Xue-tao
+#
+
+lib-y := backtrace.o delay.o findbit.o
+lib-y += strncpy_from_user.o strnlen_user.o
+lib-y += clear_user.o copy_page.o
+lib-y += copy_from_user.o copy_to_user.o
+
+GNU_LIBC_A := $(shell $(CC) $(KBUILD_CFLAGS) -print-file-name=libc.a)
+GNU_LIBC_A_OBJS := memchr.o memcpy.o memmove.o memset.o
+GNU_LIBC_A_OBJS += strchr.o strrchr.o
+GNU_LIBC_A_OBJS += rawmemchr.o # needed by strrchr.o
+
+GNU_LIBGCC_A := $(shell $(CC) $(KBUILD_CFLAGS) -print-file-name=libgcc.a)
+GNU_LIBGCC_A_OBJS := _ashldi3.o _ashrdi3.o _lshrdi3.o
+GNU_LIBGCC_A_OBJS += _divsi3.o _modsi3.o _ucmpdi2.o _umodsi3.o _udivsi3.o
+
+lib-y += $(GNU_LIBC_A_OBJS) $(GNU_LIBGCC_A_OBJS)
+
+$(addprefix $(obj)/, $(GNU_LIBC_A_OBJS)):
+ $(Q)$(AR) p $(GNU_LIBC_A) $(notdir $@) > $@
+
+$(addprefix $(obj)/, $(GNU_LIBGCC_A_OBJS)):
+ $(Q)$(AR) p $(GNU_LIBGCC_A) $(notdir $@) > $@
diff --git a/arch/unicore32/lib/delay.S b/arch/unicore32/lib/delay.S
new file mode 100644
index 00000000000..24664c009e7
--- /dev/null
+++ b/arch/unicore32/lib/delay.S
@@ -0,0 +1,51 @@
+/*
+ * linux/arch/unicore32/lib/delay.S
+ *
+ * Code specific to PKUnity SoC and UniCore ISA
+ *
+ * Copyright (C) 2001-2010 GUAN Xue-tao
+ *
+ * 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.
+ */
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include <asm/param.h>
+ .text
+
+.LC0: .word loops_per_jiffy
+.LC1: .word (2199023*HZ)>>11
+
+/*
+ * r0 <= 2000
+ * lpj <= 0x01ffffff (max. 3355 bogomips)
+ * HZ <= 1000
+ */
+
+ENTRY(__udelay)
+ ldw r2, .LC1
+ mul r0, r2, r0
+ENTRY(__const_udelay) @ 0 <= r0 <= 0x7fffff06
+ ldw r2, .LC0
+ ldw r2, [r2] @ max = 0x01ffffff
+ mov r0, r0 >> #14 @ max = 0x0001ffff
+ mov r2, r2 >> #10 @ max = 0x00007fff
+ mul r0, r2, r0 @ max = 2^32-1
+ mov.a r0, r0 >> #6
+ cmoveq pc, lr
+
+/*
+ * loops = r0 * HZ * loops_per_jiffy / 1000000
+ *
+ * Oh, if only we had a cycle counter...
+ */
+
+@ Delay routine
+ENTRY(__delay)
+ sub.a r0, r0, #2
+ bua __delay
+ mov pc, lr
+ENDPROC(__udelay)
+ENDPROC(__const_udelay)
+ENDPROC(__delay)
diff --git a/arch/unicore32/lib/findbit.S b/arch/unicore32/lib/findbit.S
new file mode 100644
index 00000000000..c360ce905d8
--- /dev/null
+++ b/arch/unicore32/lib/findbit.S
@@ -0,0 +1,98 @@
+/*
+ * linux/arch/unicore32/lib/findbit.S
+ *
+ * Code specific to PKUnity SoC and UniCore ISA
+ *
+ * Copyright (C) 2001-2010 GUAN Xue-tao
+ *
+ * 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.
+ */
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+ .text
+
+/*
+ * Purpose : Find a 'zero' bit
+ * Prototype: int find_first_zero_bit(void *addr, unsigned int maxbit);
+ */
+__uc32_find_first_zero_bit:
+ cxor.a r1, #0
+ beq 3f
+ mov r2, #0
+1: ldb r3, [r0+], r2 >> #3
+ xor.a r3, r3, #0xff @ invert bits
+ bne .L_found @ any now set - found zero bit
+ add r2, r2, #8 @ next bit pointer
+2: csub.a r2, r1 @ any more?
+ bub 1b
+3: mov r0, r1 @ no free bits
+ mov pc, lr
+
+/*
+ * Purpose : Find next 'zero' bit
+ * Prototype: int find_next_zero_bit
+ * (void *addr, unsigned int maxbit, int offset)
+ */
+ENTRY(__uc32_find_next_zero_bit)
+ cxor.a r1, #0
+ beq 3b
+ and.a ip, r2, #7
+ beq 1b @ If new byte, goto old routine
+ ldb r3, [r0+], r2 >> #3
+ xor r3, r3, #0xff @ now looking for a 1 bit
+ mov.a r3, r3 >> ip @ shift off unused bits
+ bne .L_found
+ or r2, r2, #7 @ if zero, then no bits here
+ add r2, r2, #1 @ align bit pointer
+ b 2b @ loop for next bit
+ENDPROC(__uc32_find_next_zero_bit)
+
+/*
+ * Purpose : Find a 'one' bit
+ * Prototype: int find_first_bit
+ * (const unsigned long *addr, unsigned int maxbit);
+ */
+__uc32_find_first_bit:
+ cxor.a r1, #0
+ beq 3f
+ mov r2, #0
+1: ldb r3, [r0+], r2 >> #3
+ mov.a r3, r3
+ bne .L_found @ any now set - found zero bit
+ add r2, r2, #8 @ next bit pointer
+2: csub.a r2, r1 @ any more?
+ bub 1b
+3: mov r0, r1 @ no free bits
+ mov pc, lr
+
+/*
+ * Purpose : Find next 'one' bit
+ * Prototype: int find_next_zero_bit
+ * (void *addr, unsigned int maxbit, int offset)
+ */
+ENTRY(__uc32_find_next_bit)
+ cxor.a r1, #0
+ beq 3b
+ and.a ip, r2, #7
+ beq 1b @ If new byte, goto old routine
+ ldb r3, [r0+], r2 >> #3
+ mov.a r3, r3 >> ip @ shift off unused bits
+ bne .L_found
+ or r2, r2, #7 @ if zero, then no bits here
+ add r2, r2, #1 @ align bit pointer
+ b 2b @ loop for next bit
+ENDPROC(__uc32_find_next_bit)
+
+/*
+ * One or more bits in the LSB of r3 are assumed to be set.
+ */
+.L_found:
+ rsub r1, r3, #0
+ and r3, r3, r1
+ cntlz r3, r3
+ rsub r3, r3, #31
+ add r0, r2, r3
+ mov pc, lr
+