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