diff options
-rw-r--r-- | arch/arm64/include/asm/bitops.h | 53 | ||||
-rw-r--r-- | arch/arm64/include/asm/syscall.h | 101 | ||||
-rw-r--r-- | arch/arm64/kernel/arm64ksyms.c | 46 | ||||
-rw-r--r-- | arch/arm64/lib/Makefile | 4 | ||||
-rw-r--r-- | arch/arm64/lib/bitops.c | 25 | ||||
-rw-r--r-- | arch/arm64/lib/clear_page.S | 39 | ||||
-rw-r--r-- | arch/arm64/lib/copy_page.S | 46 | ||||
-rw-r--r-- | arch/arm64/lib/delay.c | 55 |
8 files changed, 369 insertions, 0 deletions
diff --git a/arch/arm64/include/asm/bitops.h b/arch/arm64/include/asm/bitops.h new file mode 100644 index 000000000000..5e693073b030 --- /dev/null +++ b/arch/arm64/include/asm/bitops.h | |||
@@ -0,0 +1,53 @@ | |||
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 */ | ||
diff --git a/arch/arm64/include/asm/syscall.h b/arch/arm64/include/asm/syscall.h new file mode 100644 index 000000000000..89c047f9a971 --- /dev/null +++ b/arch/arm64/include/asm/syscall.h | |||
@@ -0,0 +1,101 @@ | |||
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, ®s->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(®s->regs[i], args, n * sizeof(args[0])); | ||
99 | } | ||
100 | |||
101 | #endif /* __ASM_SYSCALL_H */ | ||
diff --git a/arch/arm64/kernel/arm64ksyms.c b/arch/arm64/kernel/arm64ksyms.c new file mode 100644 index 000000000000..cef3925eaf60 --- /dev/null +++ b/arch/arm64/kernel/arm64ksyms.c | |||
@@ -0,0 +1,46 @@ | |||
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); | ||
diff --git a/arch/arm64/lib/Makefile b/arch/arm64/lib/Makefile new file mode 100644 index 000000000000..2fb7f6092aae --- /dev/null +++ b/arch/arm64/lib/Makefile | |||
@@ -0,0 +1,4 @@ | |||
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 | ||
diff --git a/arch/arm64/lib/bitops.c b/arch/arm64/lib/bitops.c new file mode 100644 index 000000000000..aa4965e60acc --- /dev/null +++ b/arch/arm64/lib/bitops.c | |||
@@ -0,0 +1,25 @@ | |||
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 | ||
diff --git a/arch/arm64/lib/clear_page.S b/arch/arm64/lib/clear_page.S new file mode 100644 index 000000000000..ef08e905e35b --- /dev/null +++ b/arch/arm64/lib/clear_page.S | |||
@@ -0,0 +1,39 @@ | |||
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) | ||
diff --git a/arch/arm64/lib/copy_page.S b/arch/arm64/lib/copy_page.S new file mode 100644 index 000000000000..512b9a7b980e --- /dev/null +++ b/arch/arm64/lib/copy_page.S | |||
@@ -0,0 +1,46 @@ | |||
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) | ||
diff --git a/arch/arm64/lib/delay.c b/arch/arm64/lib/delay.c new file mode 100644 index 000000000000..dad4ec9bbfd1 --- /dev/null +++ b/arch/arm64/lib/delay.c | |||
@@ -0,0 +1,55 @@ | |||
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); | ||