12874c5fdSThomas Gleixner/* SPDX-License-Identifier: GPL-2.0-or-later */ 2224cd129SJonas Bonn/* 3224cd129SJonas Bonn * OpenRISC string.S 4224cd129SJonas Bonn * 5224cd129SJonas Bonn * Linux architectural port borrowing liberally from similar works of 6224cd129SJonas Bonn * others. All original copyrights apply as per the original source 7224cd129SJonas Bonn * declaration. 8224cd129SJonas Bonn * 9224cd129SJonas Bonn * Modifications for the OpenRISC architecture: 10224cd129SJonas Bonn * Copyright (C) 2003 Matjaz Breskvar <phoenix@bsemi.com> 11224cd129SJonas Bonn * Copyright (C) 2010-2011 Jonas Bonn <jonas@southpole.se> 12224cd129SJonas Bonn */ 13224cd129SJonas Bonn 14224cd129SJonas Bonn#include <linux/linkage.h> 15224cd129SJonas Bonn#include <asm/errno.h> 16224cd129SJonas Bonn 17224cd129SJonas Bonn /* 18224cd129SJonas Bonn * this can be optimized by doing gcc inline assemlby with 19224cd129SJonas Bonn * proper constraints (no need to save args registers...) 20224cd129SJonas Bonn * 21224cd129SJonas Bonn */ 22224cd129SJonas Bonn 23224cd129SJonas Bonn 24224cd129SJonas Bonn/* 25224cd129SJonas Bonn * 26224cd129SJonas Bonn * int __copy_tofrom_user(void *to, const void *from, unsigned long size); 27224cd129SJonas Bonn * 28224cd129SJonas Bonn * NOTE: it returns number of bytes NOT copied !!! 29224cd129SJonas Bonn * 30224cd129SJonas Bonn */ 31224cd129SJonas Bonn .global __copy_tofrom_user 32224cd129SJonas Bonn__copy_tofrom_user: 33224cd129SJonas Bonn l.addi r1,r1,-12 34224cd129SJonas Bonn l.sw 0(r1),r6 35224cd129SJonas Bonn l.sw 4(r1),r4 36224cd129SJonas Bonn l.sw 8(r1),r3 37224cd129SJonas Bonn 38224cd129SJonas Bonn l.addi r11,r5,0 39224cd129SJonas Bonn2: l.sfeq r11,r0 40224cd129SJonas Bonn l.bf 1f 41224cd129SJonas Bonn l.addi r11,r11,-1 42224cd129SJonas Bonn8: l.lbz r6,0(r4) 43224cd129SJonas Bonn9: l.sb 0(r3),r6 44224cd129SJonas Bonn l.addi r3,r3,1 45224cd129SJonas Bonn l.j 2b 46224cd129SJonas Bonn l.addi r4,r4,1 47224cd129SJonas Bonn1: 48224cd129SJonas Bonn l.addi r11,r11,1 // r11 holds the return value 49224cd129SJonas Bonn 50224cd129SJonas Bonn l.lwz r6,0(r1) 51224cd129SJonas Bonn l.lwz r4,4(r1) 52224cd129SJonas Bonn l.lwz r3,8(r1) 53224cd129SJonas Bonn l.jr r9 54224cd129SJonas Bonn l.addi r1,r1,12 55224cd129SJonas Bonn 56224cd129SJonas Bonn .section .fixup, "ax" 57224cd129SJonas Bonn99: 58224cd129SJonas Bonn l.j 1b 59224cd129SJonas Bonn l.nop 60224cd129SJonas Bonn .previous 61224cd129SJonas Bonn 62224cd129SJonas Bonn .section __ex_table, "a" 63224cd129SJonas Bonn .long 8b, 99b // read fault 64224cd129SJonas Bonn .long 9b, 99b // write fault 65224cd129SJonas Bonn .previous 66224cd129SJonas Bonn 67224cd129SJonas Bonn/* 68224cd129SJonas Bonn * unsigned long clear_user(void *addr, unsigned long size) ; 69224cd129SJonas Bonn * 70224cd129SJonas Bonn * NOTE: it returns number of bytes NOT cleared !!! 71224cd129SJonas Bonn */ 72224cd129SJonas Bonn .global __clear_user 73224cd129SJonas Bonn__clear_user: 74224cd129SJonas Bonn l.addi r1,r1,-8 75224cd129SJonas Bonn l.sw 0(r1),r4 76224cd129SJonas Bonn l.sw 4(r1),r3 77224cd129SJonas Bonn 78224cd129SJonas Bonn2: l.sfeq r4,r0 79224cd129SJonas Bonn l.bf 1f 80224cd129SJonas Bonn l.addi r4,r4,-1 81224cd129SJonas Bonn9: l.sb 0(r3),r0 82224cd129SJonas Bonn l.j 2b 83224cd129SJonas Bonn l.addi r3,r3,1 84224cd129SJonas Bonn 85224cd129SJonas Bonn1: 86224cd129SJonas Bonn l.addi r11,r4,1 87224cd129SJonas Bonn 88224cd129SJonas Bonn l.lwz r4,0(r1) 89224cd129SJonas Bonn l.lwz r3,4(r1) 90224cd129SJonas Bonn l.jr r9 91224cd129SJonas Bonn l.addi r1,r1,8 92224cd129SJonas Bonn 93224cd129SJonas Bonn .section .fixup, "ax" 94224cd129SJonas Bonn99: 95224cd129SJonas Bonn l.j 1b 96224cd129SJonas Bonn l.nop 97224cd129SJonas Bonn .previous 98224cd129SJonas Bonn 99224cd129SJonas Bonn .section __ex_table, "a" 100224cd129SJonas Bonn .long 9b, 99b // write fault 101224cd129SJonas Bonn .previous 102