18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * Copyright (C) 2012 ARM Ltd.
48c2ecf20Sopenharmony_ci */
58c2ecf20Sopenharmony_ci
68c2ecf20Sopenharmony_ci#include <linux/linkage.h>
78c2ecf20Sopenharmony_ci
88c2ecf20Sopenharmony_ci#include <asm/asm-uaccess.h>
98c2ecf20Sopenharmony_ci#include <asm/assembler.h>
108c2ecf20Sopenharmony_ci#include <asm/cache.h>
118c2ecf20Sopenharmony_ci
128c2ecf20Sopenharmony_ci/*
138c2ecf20Sopenharmony_ci * Copy to user space from a kernel buffer (alignment handled by the hardware)
148c2ecf20Sopenharmony_ci *
158c2ecf20Sopenharmony_ci * Parameters:
168c2ecf20Sopenharmony_ci *	x0 - to
178c2ecf20Sopenharmony_ci *	x1 - from
188c2ecf20Sopenharmony_ci *	x2 - n
198c2ecf20Sopenharmony_ci * Returns:
208c2ecf20Sopenharmony_ci *	x0 - bytes not copied
218c2ecf20Sopenharmony_ci */
228c2ecf20Sopenharmony_ci	.macro ldrb1 reg, ptr, val
238c2ecf20Sopenharmony_ci	ldrb  \reg, [\ptr], \val
248c2ecf20Sopenharmony_ci	.endm
258c2ecf20Sopenharmony_ci
268c2ecf20Sopenharmony_ci	.macro strb1 reg, ptr, val
278c2ecf20Sopenharmony_ci	uao_user_alternative 9998f, strb, sttrb, \reg, \ptr, \val
288c2ecf20Sopenharmony_ci	.endm
298c2ecf20Sopenharmony_ci
308c2ecf20Sopenharmony_ci	.macro ldrh1 reg, ptr, val
318c2ecf20Sopenharmony_ci	ldrh  \reg, [\ptr], \val
328c2ecf20Sopenharmony_ci	.endm
338c2ecf20Sopenharmony_ci
348c2ecf20Sopenharmony_ci	.macro strh1 reg, ptr, val
358c2ecf20Sopenharmony_ci	uao_user_alternative 9997f, strh, sttrh, \reg, \ptr, \val
368c2ecf20Sopenharmony_ci	.endm
378c2ecf20Sopenharmony_ci
388c2ecf20Sopenharmony_ci	.macro ldr1 reg, ptr, val
398c2ecf20Sopenharmony_ci	ldr \reg, [\ptr], \val
408c2ecf20Sopenharmony_ci	.endm
418c2ecf20Sopenharmony_ci
428c2ecf20Sopenharmony_ci	.macro str1 reg, ptr, val
438c2ecf20Sopenharmony_ci	uao_user_alternative 9997f, str, sttr, \reg, \ptr, \val
448c2ecf20Sopenharmony_ci	.endm
458c2ecf20Sopenharmony_ci
468c2ecf20Sopenharmony_ci	.macro ldp1 reg1, reg2, ptr, val
478c2ecf20Sopenharmony_ci	ldp \reg1, \reg2, [\ptr], \val
488c2ecf20Sopenharmony_ci	.endm
498c2ecf20Sopenharmony_ci
508c2ecf20Sopenharmony_ci	.macro stp1 reg1, reg2, ptr, val
518c2ecf20Sopenharmony_ci	uao_stp 9997f, \reg1, \reg2, \ptr, \val
528c2ecf20Sopenharmony_ci	.endm
538c2ecf20Sopenharmony_ci
548c2ecf20Sopenharmony_ciend	.req	x5
558c2ecf20Sopenharmony_cisrcin	.req	x15
568c2ecf20Sopenharmony_ciSYM_FUNC_START(__arch_copy_to_user)
578c2ecf20Sopenharmony_ci	add	end, x0, x2
588c2ecf20Sopenharmony_ci	mov	srcin, x1
598c2ecf20Sopenharmony_ci#include "copy_template.S"
608c2ecf20Sopenharmony_ci	mov	x0, #0
618c2ecf20Sopenharmony_ci	ret
628c2ecf20Sopenharmony_ciSYM_FUNC_END(__arch_copy_to_user)
638c2ecf20Sopenharmony_ciEXPORT_SYMBOL(__arch_copy_to_user)
648c2ecf20Sopenharmony_ci
658c2ecf20Sopenharmony_ci	.section .fixup,"ax"
668c2ecf20Sopenharmony_ci	.align	2
678c2ecf20Sopenharmony_ci9997:	cmp	dst, dstin
688c2ecf20Sopenharmony_ci	b.ne	9998f
698c2ecf20Sopenharmony_ci	// Before being absolutely sure we couldn't copy anything, try harder
708c2ecf20Sopenharmony_ci	ldrb	tmp1w, [srcin]
718c2ecf20Sopenharmony_ciUSER(9998f, sttrb tmp1w, [dst])
728c2ecf20Sopenharmony_ci	add	dst, dst, #1
738c2ecf20Sopenharmony_ci9998:	sub	x0, end, dst			// bytes not copied
748c2ecf20Sopenharmony_ci	ret
758c2ecf20Sopenharmony_ci	.previous
76