1/*
2 * Copyright (c) 2017, Google Inc. All rights reserved
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining
5 * a copy of this software and associated documentation files
6 * (the "Software"), to deal in the Software without restriction,
7 * including without limitation the rights to use, copy, modify, merge,
8 * publish, distribute, sublicense, and/or sell copies of the Software,
9 * and to permit persons to whom the Software is furnished to do so,
10 * subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be
13 * included in all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 */
23
24#include <asm.h>
25#include <arch/asm_macros.h>
26#include <err.h>
27
28/* status_t arch_copy_to_user(user_addr_t udest, const void *ksrc, size_t len) */
29FUNCTION(arch_copy_to_user)
30	cbz	x2, .Larch_copy_to_user_done
31.Larch_copy_to_user_loop:
32	ldrb	w9, [x1], #1
33
34	set_fault_handler	.Larch_copy_to_user_fault
35	sttrb	w9, [x0]
36
37	add	x0, x0, #1
38	subs	x2, x2, #1
39	b.hi	.Larch_copy_to_user_loop
40.Larch_copy_to_user_done:
41	mov	x0, #0
42	ret
43
44/* status_t arch_copy_from_user(void *kdest, user_addr_t usrc, size_t len) */
45FUNCTION(arch_copy_from_user)
46	cbz	x2, .Larch_copy_from_user_done
47.Larch_copy_from_user_loop:
48	set_fault_handler	.Larch_copy_from_user_fault
49	ldtrb	w9, [x1]
50
51	add	x1, x1, #1
52	strb	w9, [x0], #1
53	subs	x2, x2, #1
54	b.hi	.Larch_copy_from_user_loop
55.Larch_copy_from_user_done:
56	mov	x0, #0
57	ret
58
59/* ssize_t arch_strlcpy_from_user(char *kdst, user_addr_t usrc, size_t len) */
60FUNCTION(arch_strlcpy_from_user)
61	mov	x10, x1
62.Larch_strlcpy_from_user_loop:
63	set_fault_handler	.Larch_strlcpy_from_user_fault
64	ldtrb	w9, [x1]
65
66	cmp	w9, #0
67	cinc	x1, x1, ne
68
69	cbz	x2, .Larch_strlcpy_from_user_dst_full
70	subs	x2, x2, #1
71	csel	w11, w9, wzr, hi
72	strb	w11, [x0], #1
73.Larch_strlcpy_from_user_dst_full:
74	cbnz	w9, .Larch_strlcpy_from_user_loop
75
76	sub	x0, x1, x10
77	ret
78
79.Larch_strlcpy_from_user_fault:
80	cbz	x2, .Larch_copy_to_user_fault
81.Larch_copy_from_user_fault:
82	strb	wzr, [x0], #1
83	subs	x2, x2, #1
84	b.hi	.Larch_copy_from_user_fault
85.Larch_copy_to_user_fault:
86	mov	x0, #ERR_FAULT
87	ret
88