Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

arm64: Miscellaneous library functions

This patch adds udelay, memory and bit operations together with the
ksyms exports.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Will Deacon <will.deacon@arm.com>
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
Acked-by: Tony Lindgren <tony@atomide.com>
Acked-by: Nicolas Pitre <nico@linaro.org>
Acked-by: Olof Johansson <olof@lixom.net>
Acked-by: Santosh Shilimkar <santosh.shilimkar@ti.com>

authored by

Marc Zyngier and committed by
Catalin Marinas
f27bb139 03089688

+369
+53
arch/arm64/include/asm/bitops.h
··· 1 + /* 2 + * Copyright (C) 2012 ARM Ltd. 3 + * 4 + * This program is free software; you can redistribute it and/or modify 5 + * it under the terms of the GNU General Public License version 2 as 6 + * published by the Free Software Foundation. 7 + * 8 + * This program is distributed in the hope that it will be useful, 9 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 + * GNU General Public License for more details. 12 + * 13 + * You should have received a copy of the GNU General Public License 14 + * along with this program. If not, see <http://www.gnu.org/licenses/>. 15 + */ 16 + #ifndef __ASM_BITOPS_H 17 + #define __ASM_BITOPS_H 18 + 19 + #include <linux/compiler.h> 20 + 21 + #include <asm/barrier.h> 22 + 23 + /* 24 + * clear_bit may not imply a memory barrier 25 + */ 26 + #ifndef smp_mb__before_clear_bit 27 + #define smp_mb__before_clear_bit() smp_mb() 28 + #define smp_mb__after_clear_bit() smp_mb() 29 + #endif 30 + 31 + #ifndef _LINUX_BITOPS_H 32 + #error only <linux/bitops.h> can be included directly 33 + #endif 34 + 35 + #include <asm-generic/bitops/builtin-__ffs.h> 36 + #include <asm-generic/bitops/builtin-ffs.h> 37 + #include <asm-generic/bitops/builtin-__fls.h> 38 + #include <asm-generic/bitops/builtin-fls.h> 39 + 40 + #include <asm-generic/bitops/ffz.h> 41 + #include <asm-generic/bitops/fls64.h> 42 + #include <asm-generic/bitops/find.h> 43 + 44 + #include <asm-generic/bitops/sched.h> 45 + #include <asm-generic/bitops/hweight.h> 46 + #include <asm-generic/bitops/lock.h> 47 + 48 + #include <asm-generic/bitops/atomic.h> 49 + #include <asm-generic/bitops/non-atomic.h> 50 + #include <asm-generic/bitops/le.h> 51 + #include <asm-generic/bitops/ext2-atomic.h> 52 + 53 + #endif /* __ASM_BITOPS_H */
+101
arch/arm64/include/asm/syscall.h
··· 1 + /* 2 + * Copyright (C) 2012 ARM Ltd. 3 + * 4 + * This program is free software; you can redistribute it and/or modify 5 + * it under the terms of the GNU General Public License version 2 as 6 + * published by the Free Software Foundation. 7 + * 8 + * This program is distributed in the hope that it will be useful, 9 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 + * GNU General Public License for more details. 12 + * 13 + * You should have received a copy of the GNU General Public License 14 + * along with this program. If not, see <http://www.gnu.org/licenses/>. 15 + */ 16 + #ifndef __ASM_SYSCALL_H 17 + #define __ASM_SYSCALL_H 18 + 19 + #include <linux/err.h> 20 + 21 + 22 + static inline int syscall_get_nr(struct task_struct *task, 23 + struct pt_regs *regs) 24 + { 25 + return regs->syscallno; 26 + } 27 + 28 + static inline void syscall_rollback(struct task_struct *task, 29 + struct pt_regs *regs) 30 + { 31 + regs->regs[0] = regs->orig_x0; 32 + } 33 + 34 + 35 + static inline long syscall_get_error(struct task_struct *task, 36 + struct pt_regs *regs) 37 + { 38 + unsigned long error = regs->regs[0]; 39 + return IS_ERR_VALUE(error) ? error : 0; 40 + } 41 + 42 + static inline long syscall_get_return_value(struct task_struct *task, 43 + struct pt_regs *regs) 44 + { 45 + return regs->regs[0]; 46 + } 47 + 48 + static inline void syscall_set_return_value(struct task_struct *task, 49 + struct pt_regs *regs, 50 + int error, long val) 51 + { 52 + regs->regs[0] = (long) error ? error : val; 53 + } 54 + 55 + #define SYSCALL_MAX_ARGS 6 56 + 57 + static inline void syscall_get_arguments(struct task_struct *task, 58 + struct pt_regs *regs, 59 + unsigned int i, unsigned int n, 60 + unsigned long *args) 61 + { 62 + if (i + n > SYSCALL_MAX_ARGS) { 63 + unsigned long *args_bad = args + SYSCALL_MAX_ARGS - i; 64 + unsigned int n_bad = n + i - SYSCALL_MAX_ARGS; 65 + pr_warning("%s called with max args %d, handling only %d\n", 66 + __func__, i + n, SYSCALL_MAX_ARGS); 67 + memset(args_bad, 0, n_bad * sizeof(args[0])); 68 + } 69 + 70 + if (i == 0) { 71 + args[0] = regs->orig_x0; 72 + args++; 73 + i++; 74 + n--; 75 + } 76 + 77 + memcpy(args, &regs->regs[i], n * sizeof(args[0])); 78 + } 79 + 80 + static inline void syscall_set_arguments(struct task_struct *task, 81 + struct pt_regs *regs, 82 + unsigned int i, unsigned int n, 83 + const unsigned long *args) 84 + { 85 + if (i + n > SYSCALL_MAX_ARGS) { 86 + pr_warning("%s called with max args %d, handling only %d\n", 87 + __func__, i + n, SYSCALL_MAX_ARGS); 88 + n = SYSCALL_MAX_ARGS - i; 89 + } 90 + 91 + if (i == 0) { 92 + regs->orig_x0 = args[0]; 93 + args++; 94 + i++; 95 + n--; 96 + } 97 + 98 + memcpy(&regs->regs[i], args, n * sizeof(args[0])); 99 + } 100 + 101 + #endif /* __ASM_SYSCALL_H */
+46
arch/arm64/kernel/arm64ksyms.c
··· 1 + /* 2 + * Based on arch/arm/kernel/armksyms.c 3 + * 4 + * Copyright (C) 2000 Russell King 5 + * Copyright (C) 2012 ARM Ltd. 6 + * 7 + * This program is free software; you can redistribute it and/or modify 8 + * it under the terms of the GNU General Public License version 2 as 9 + * published by the Free Software Foundation. 10 + * 11 + * This program is distributed in the hope that it will be useful, 12 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 + * GNU General Public License for more details. 15 + * 16 + * You should have received a copy of the GNU General Public License 17 + * along with this program. If not, see <http://www.gnu.org/licenses/>. 18 + */ 19 + 20 + #include <linux/export.h> 21 + #include <linux/sched.h> 22 + #include <linux/string.h> 23 + #include <linux/cryptohash.h> 24 + #include <linux/delay.h> 25 + #include <linux/in6.h> 26 + #include <linux/syscalls.h> 27 + #include <linux/uaccess.h> 28 + #include <linux/io.h> 29 + 30 + #include <asm/checksum.h> 31 + 32 + /* user mem (segment) */ 33 + EXPORT_SYMBOL(__strnlen_user); 34 + EXPORT_SYMBOL(__strncpy_from_user); 35 + 36 + EXPORT_SYMBOL(copy_page); 37 + 38 + EXPORT_SYMBOL(__copy_from_user); 39 + EXPORT_SYMBOL(__copy_to_user); 40 + EXPORT_SYMBOL(__clear_user); 41 + 42 + /* bitops */ 43 + EXPORT_SYMBOL(__atomic_hash); 44 + 45 + /* physical memory */ 46 + EXPORT_SYMBOL(memstart_addr);
+4
arch/arm64/lib/Makefile
··· 1 + lib-y := bitops.o delay.o \ 2 + strncpy_from_user.o strnlen_user.o clear_user.o \ 3 + copy_from_user.o copy_to_user.o copy_in_user.o \ 4 + copy_page.o clear_page.o
+25
arch/arm64/lib/bitops.c
··· 1 + /* 2 + * Copyright (C) 2012 ARM Limited 3 + * 4 + * This program is free software; you can redistribute it and/or modify 5 + * it under the terms of the GNU General Public License version 2 as 6 + * published by the Free Software Foundation. 7 + * 8 + * This program is distributed in the hope that it will be useful, 9 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 + * GNU General Public License for more details. 12 + * 13 + * You should have received a copy of the GNU General Public License 14 + * along with this program. If not, see <http://www.gnu.org/licenses/>. 15 + */ 16 + 17 + #include <linux/kernel.h> 18 + #include <linux/spinlock.h> 19 + #include <linux/atomic.h> 20 + 21 + #ifdef CONFIG_SMP 22 + arch_spinlock_t __atomic_hash[ATOMIC_HASH_SIZE] __lock_aligned = { 23 + [0 ... (ATOMIC_HASH_SIZE-1)] = __ARCH_SPIN_LOCK_UNLOCKED 24 + }; 25 + #endif
+39
arch/arm64/lib/clear_page.S
··· 1 + /* 2 + * Copyright (C) 2012 ARM Ltd. 3 + * 4 + * This program is free software; you can redistribute it and/or modify 5 + * it under the terms of the GNU General Public License version 2 as 6 + * published by the Free Software Foundation. 7 + * 8 + * This program is distributed in the hope that it will be useful, 9 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 + * GNU General Public License for more details. 12 + * 13 + * You should have received a copy of the GNU General Public License 14 + * along with this program. If not, see <http://www.gnu.org/licenses/>. 15 + */ 16 + 17 + #include <linux/linkage.h> 18 + #include <linux/const.h> 19 + #include <asm/assembler.h> 20 + #include <asm/page.h> 21 + 22 + /* 23 + * Clear page @dest 24 + * 25 + * Parameters: 26 + * x0 - dest 27 + */ 28 + ENTRY(clear_page) 29 + mrs x1, dczid_el0 30 + and w1, w1, #0xf 31 + mov x2, #4 32 + lsl x1, x2, x1 33 + 34 + 1: dc zva, x0 35 + add x0, x0, x1 36 + tst x0, #(PAGE_SIZE - 1) 37 + b.ne 1b 38 + ret 39 + ENDPROC(clear_page)
+46
arch/arm64/lib/copy_page.S
··· 1 + /* 2 + * Copyright (C) 2012 ARM Ltd. 3 + * 4 + * This program is free software; you can redistribute it and/or modify 5 + * it under the terms of the GNU General Public License version 2 as 6 + * published by the Free Software Foundation. 7 + * 8 + * This program is distributed in the hope that it will be useful, 9 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 + * GNU General Public License for more details. 12 + * 13 + * You should have received a copy of the GNU General Public License 14 + * along with this program. If not, see <http://www.gnu.org/licenses/>. 15 + */ 16 + 17 + #include <linux/linkage.h> 18 + #include <linux/const.h> 19 + #include <asm/assembler.h> 20 + #include <asm/page.h> 21 + 22 + /* 23 + * Copy a page from src to dest (both are page aligned) 24 + * 25 + * Parameters: 26 + * x0 - dest 27 + * x1 - src 28 + */ 29 + ENTRY(copy_page) 30 + /* Assume cache line size is 64 bytes. */ 31 + prfm pldl1strm, [x1, #64] 32 + 1: ldp x2, x3, [x1] 33 + ldp x4, x5, [x1, #16] 34 + ldp x6, x7, [x1, #32] 35 + ldp x8, x9, [x1, #48] 36 + add x1, x1, #64 37 + prfm pldl1strm, [x1, #64] 38 + stnp x2, x3, [x0] 39 + stnp x4, x5, [x0, #16] 40 + stnp x6, x7, [x0, #32] 41 + stnp x8, x9, [x0, #48] 42 + add x0, x0, #64 43 + tst x1, #(PAGE_SIZE - 1) 44 + b.ne 1b 45 + ret 46 + ENDPROC(copy_page)
+55
arch/arm64/lib/delay.c
··· 1 + /* 2 + * Delay loops based on the OpenRISC implementation. 3 + * 4 + * Copyright (C) 2012 ARM Limited 5 + * 6 + * This program is free software; you can redistribute it and/or modify 7 + * it under the terms of the GNU General Public License version 2 as 8 + * published by the Free Software Foundation. 9 + * 10 + * This program is distributed in the hope that it will be useful, 11 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 + * GNU General Public License for more details. 14 + * 15 + * You should have received a copy of the GNU General Public License 16 + * along with this program. If not, see <http://www.gnu.org/licenses/>. 17 + * 18 + * Author: Will Deacon <will.deacon@arm.com> 19 + */ 20 + 21 + #include <linux/delay.h> 22 + #include <linux/init.h> 23 + #include <linux/kernel.h> 24 + #include <linux/module.h> 25 + #include <linux/timex.h> 26 + 27 + void __delay(unsigned long cycles) 28 + { 29 + cycles_t start = get_cycles(); 30 + 31 + while ((get_cycles() - start) < cycles) 32 + cpu_relax(); 33 + } 34 + EXPORT_SYMBOL(__delay); 35 + 36 + inline void __const_udelay(unsigned long xloops) 37 + { 38 + unsigned long loops; 39 + 40 + loops = xloops * loops_per_jiffy * HZ; 41 + __delay(loops >> 32); 42 + } 43 + EXPORT_SYMBOL(__const_udelay); 44 + 45 + void __udelay(unsigned long usecs) 46 + { 47 + __const_udelay(usecs * 0x10C7UL); /* 2**32 / 1000000 (rounded up) */ 48 + } 49 + EXPORT_SYMBOL(__udelay); 50 + 51 + void __ndelay(unsigned long nsecs) 52 + { 53 + __const_udelay(nsecs * 0x5UL); /* 2**32 / 1000000000 (rounded up) */ 54 + } 55 + EXPORT_SYMBOL(__ndelay);