18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * User memory copy functions for kernel
48c2ecf20Sopenharmony_ci *
58c2ecf20Sopenharmony_ci * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved.
68c2ecf20Sopenharmony_ci */
78c2ecf20Sopenharmony_ci
88c2ecf20Sopenharmony_ci/*
98c2ecf20Sopenharmony_ci * The right way to do this involves valignb
108c2ecf20Sopenharmony_ci * The easy way to do this is only speed up src/dest similar alignment.
118c2ecf20Sopenharmony_ci */
128c2ecf20Sopenharmony_ci
138c2ecf20Sopenharmony_ci/*
148c2ecf20Sopenharmony_ci * Copy to/from user are the same, except that for packets with a load and
158c2ecf20Sopenharmony_ci * a store, I don't know how to tell which kind of exception we got.
168c2ecf20Sopenharmony_ci * Therefore, we duplicate the function, and handle faulting addresses
178c2ecf20Sopenharmony_ci * differently for each function
188c2ecf20Sopenharmony_ci */
198c2ecf20Sopenharmony_ci
208c2ecf20Sopenharmony_ci/*
218c2ecf20Sopenharmony_ci * copy from user: loads can fault
228c2ecf20Sopenharmony_ci */
238c2ecf20Sopenharmony_ci#define src_sav r13
248c2ecf20Sopenharmony_ci#define dst_sav r12
258c2ecf20Sopenharmony_ci#define src_dst_sav r13:12
268c2ecf20Sopenharmony_ci#define d_dbuf r15:14
278c2ecf20Sopenharmony_ci#define w_dbuf r15
288c2ecf20Sopenharmony_ci
298c2ecf20Sopenharmony_ci#define dst r0
308c2ecf20Sopenharmony_ci#define src r1
318c2ecf20Sopenharmony_ci#define bytes r2
328c2ecf20Sopenharmony_ci#define loopcount r5
338c2ecf20Sopenharmony_ci
348c2ecf20Sopenharmony_ci#define FUNCNAME raw_copy_from_user
358c2ecf20Sopenharmony_ci#include "copy_user_template.S"
368c2ecf20Sopenharmony_ci
378c2ecf20Sopenharmony_ci	/* LOAD FAULTS from COPY_FROM_USER */
388c2ecf20Sopenharmony_ci
398c2ecf20Sopenharmony_ci	/* Alignment loop.  r2 has been updated. Return it. */
408c2ecf20Sopenharmony_ci	.falign
418c2ecf20Sopenharmony_ci1009:
428c2ecf20Sopenharmony_ci2009:
438c2ecf20Sopenharmony_ci4009:
448c2ecf20Sopenharmony_ci	{
458c2ecf20Sopenharmony_ci		r0 = r2
468c2ecf20Sopenharmony_ci		jumpr r31
478c2ecf20Sopenharmony_ci	}
488c2ecf20Sopenharmony_ci	/* Normal copy loops. Do epilog. Use src-src_sav to compute distance */
498c2ecf20Sopenharmony_ci	/* X - (A - B) == X + B - A */
508c2ecf20Sopenharmony_ci	.falign
518c2ecf20Sopenharmony_ci8089:
528c2ecf20Sopenharmony_ci	{
538c2ecf20Sopenharmony_ci		memd(dst) = d_dbuf
548c2ecf20Sopenharmony_ci		r2 += sub(src_sav,src)
558c2ecf20Sopenharmony_ci	}
568c2ecf20Sopenharmony_ci	{
578c2ecf20Sopenharmony_ci		r0 = r2
588c2ecf20Sopenharmony_ci		jumpr r31
598c2ecf20Sopenharmony_ci	}
608c2ecf20Sopenharmony_ci	.falign
618c2ecf20Sopenharmony_ci4089:
628c2ecf20Sopenharmony_ci	{
638c2ecf20Sopenharmony_ci		memw(dst) = w_dbuf
648c2ecf20Sopenharmony_ci		r2 += sub(src_sav,src)
658c2ecf20Sopenharmony_ci	}
668c2ecf20Sopenharmony_ci	{
678c2ecf20Sopenharmony_ci		r0 = r2
688c2ecf20Sopenharmony_ci		jumpr r31
698c2ecf20Sopenharmony_ci	}
708c2ecf20Sopenharmony_ci	.falign
718c2ecf20Sopenharmony_ci2089:
728c2ecf20Sopenharmony_ci	{
738c2ecf20Sopenharmony_ci		memh(dst) = w_dbuf
748c2ecf20Sopenharmony_ci		r2 += sub(src_sav,src)
758c2ecf20Sopenharmony_ci	}
768c2ecf20Sopenharmony_ci	{
778c2ecf20Sopenharmony_ci		r0 = r2
788c2ecf20Sopenharmony_ci		jumpr r31
798c2ecf20Sopenharmony_ci	}
808c2ecf20Sopenharmony_ci	.falign
818c2ecf20Sopenharmony_ci1089:
828c2ecf20Sopenharmony_ci	{
838c2ecf20Sopenharmony_ci		memb(dst) = w_dbuf
848c2ecf20Sopenharmony_ci		r2 += sub(src_sav,src)
858c2ecf20Sopenharmony_ci	}
868c2ecf20Sopenharmony_ci	{
878c2ecf20Sopenharmony_ci		r0 = r2
888c2ecf20Sopenharmony_ci		jumpr r31
898c2ecf20Sopenharmony_ci	}
908c2ecf20Sopenharmony_ci
918c2ecf20Sopenharmony_ci	/* COPY FROM USER: only loads can fail */
928c2ecf20Sopenharmony_ci
938c2ecf20Sopenharmony_ci	.section __ex_table,"a"
948c2ecf20Sopenharmony_ci	.long 1000b,1009b
958c2ecf20Sopenharmony_ci	.long 2000b,2009b
968c2ecf20Sopenharmony_ci	.long 4000b,4009b
978c2ecf20Sopenharmony_ci	.long 8080b,8089b
988c2ecf20Sopenharmony_ci	.long 4080b,4089b
998c2ecf20Sopenharmony_ci	.long 2080b,2089b
1008c2ecf20Sopenharmony_ci	.long 1080b,1089b
1018c2ecf20Sopenharmony_ci	.previous
102