18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * User memory copying routines for the Hexagon Kernel
48c2ecf20Sopenharmony_ci *
58c2ecf20Sopenharmony_ci * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved.
68c2ecf20Sopenharmony_ci */
78c2ecf20Sopenharmony_ci
88c2ecf20Sopenharmony_ci/* The right way to do this involves valignb
98c2ecf20Sopenharmony_ci * The easy way to do this is only speed up src/dest similar alignment.
108c2ecf20Sopenharmony_ci */
118c2ecf20Sopenharmony_ci
128c2ecf20Sopenharmony_ci/*
138c2ecf20Sopenharmony_ci * Copy to/from user are the same, except that for packets with a load and
148c2ecf20Sopenharmony_ci * a store, I don't know how to tell which kind of exception we got.
158c2ecf20Sopenharmony_ci * Therefore, we duplicate the function, and handle faulting addresses
168c2ecf20Sopenharmony_ci * differently for each function
178c2ecf20Sopenharmony_ci */
188c2ecf20Sopenharmony_ci
198c2ecf20Sopenharmony_ci/*
208c2ecf20Sopenharmony_ci * copy to user: stores can fault
218c2ecf20Sopenharmony_ci */
228c2ecf20Sopenharmony_ci#define src_sav r13
238c2ecf20Sopenharmony_ci#define dst_sav r12
248c2ecf20Sopenharmony_ci#define src_dst_sav r13:12
258c2ecf20Sopenharmony_ci#define d_dbuf r15:14
268c2ecf20Sopenharmony_ci#define w_dbuf r15
278c2ecf20Sopenharmony_ci
288c2ecf20Sopenharmony_ci#define dst r0
298c2ecf20Sopenharmony_ci#define src r1
308c2ecf20Sopenharmony_ci#define bytes r2
318c2ecf20Sopenharmony_ci#define loopcount r5
328c2ecf20Sopenharmony_ci
338c2ecf20Sopenharmony_ci#define FUNCNAME raw_copy_to_user
348c2ecf20Sopenharmony_ci#include "copy_user_template.S"
358c2ecf20Sopenharmony_ci
368c2ecf20Sopenharmony_ci	/* STORE FAULTS from COPY_TO_USER */
378c2ecf20Sopenharmony_ci	.falign
388c2ecf20Sopenharmony_ci1109:
398c2ecf20Sopenharmony_ci2109:
408c2ecf20Sopenharmony_ci4109:
418c2ecf20Sopenharmony_ci	/* Alignment loop.  r2 has been updated.  Return it. */
428c2ecf20Sopenharmony_ci	{
438c2ecf20Sopenharmony_ci		r0 = r2
448c2ecf20Sopenharmony_ci		jumpr r31
458c2ecf20Sopenharmony_ci	}
468c2ecf20Sopenharmony_ci	/* Normal copy loops.  Use dst-dst_sav to compute distance */
478c2ecf20Sopenharmony_ci	/* dst holds best write, no need to unwind any loops */
488c2ecf20Sopenharmony_ci	/* X - (A - B) == X + B - A */
498c2ecf20Sopenharmony_ci	.falign
508c2ecf20Sopenharmony_ci8189:
518c2ecf20Sopenharmony_ci8199:
528c2ecf20Sopenharmony_ci4189:
538c2ecf20Sopenharmony_ci4199:
548c2ecf20Sopenharmony_ci2189:
558c2ecf20Sopenharmony_ci2199:
568c2ecf20Sopenharmony_ci1189:
578c2ecf20Sopenharmony_ci1199:
588c2ecf20Sopenharmony_ci	{
598c2ecf20Sopenharmony_ci		r2 += sub(dst_sav,dst)
608c2ecf20Sopenharmony_ci	}
618c2ecf20Sopenharmony_ci	{
628c2ecf20Sopenharmony_ci		r0 = r2
638c2ecf20Sopenharmony_ci		jumpr r31
648c2ecf20Sopenharmony_ci	}
658c2ecf20Sopenharmony_ci
668c2ecf20Sopenharmony_ci	/* COPY TO USER: only stores can fail */
678c2ecf20Sopenharmony_ci	.section __ex_table,"a"
688c2ecf20Sopenharmony_ci	.long 1100b,1109b
698c2ecf20Sopenharmony_ci	.long 2100b,2109b
708c2ecf20Sopenharmony_ci	.long 4100b,4109b
718c2ecf20Sopenharmony_ci	.long 8180b,8189b
728c2ecf20Sopenharmony_ci	.long 8190b,8199b
738c2ecf20Sopenharmony_ci	.long 4180b,4189b
748c2ecf20Sopenharmony_ci	.long 4190b,4199b
758c2ecf20Sopenharmony_ci	.long 2180b,2189b
768c2ecf20Sopenharmony_ci	.long 2190b,2199b
778c2ecf20Sopenharmony_ci	.long 1180b,1189b
788c2ecf20Sopenharmony_ci	.long 1190b,1199b
798c2ecf20Sopenharmony_ci	.previous
80