18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Optimized xor_block operation for RAID4/5 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Copyright IBM Corp. 2016 68c2ecf20Sopenharmony_ci * Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com> 78c2ecf20Sopenharmony_ci */ 88c2ecf20Sopenharmony_ci 98c2ecf20Sopenharmony_ci#include <linux/types.h> 108c2ecf20Sopenharmony_ci#include <linux/export.h> 118c2ecf20Sopenharmony_ci#include <linux/raid/xor.h> 128c2ecf20Sopenharmony_ci#include <asm/xor.h> 138c2ecf20Sopenharmony_ci 148c2ecf20Sopenharmony_cistatic void xor_xc_2(unsigned long bytes, unsigned long *p1, unsigned long *p2) 158c2ecf20Sopenharmony_ci{ 168c2ecf20Sopenharmony_ci asm volatile( 178c2ecf20Sopenharmony_ci " larl 1,2f\n" 188c2ecf20Sopenharmony_ci " aghi %0,-1\n" 198c2ecf20Sopenharmony_ci " jm 3f\n" 208c2ecf20Sopenharmony_ci " srlg 0,%0,8\n" 218c2ecf20Sopenharmony_ci " ltgr 0,0\n" 228c2ecf20Sopenharmony_ci " jz 1f\n" 238c2ecf20Sopenharmony_ci "0: xc 0(256,%1),0(%2)\n" 248c2ecf20Sopenharmony_ci " la %1,256(%1)\n" 258c2ecf20Sopenharmony_ci " la %2,256(%2)\n" 268c2ecf20Sopenharmony_ci " brctg 0,0b\n" 278c2ecf20Sopenharmony_ci "1: ex %0,0(1)\n" 288c2ecf20Sopenharmony_ci " j 3f\n" 298c2ecf20Sopenharmony_ci "2: xc 0(1,%1),0(%2)\n" 308c2ecf20Sopenharmony_ci "3:\n" 318c2ecf20Sopenharmony_ci : : "d" (bytes), "a" (p1), "a" (p2) 328c2ecf20Sopenharmony_ci : "0", "1", "cc", "memory"); 338c2ecf20Sopenharmony_ci} 348c2ecf20Sopenharmony_ci 358c2ecf20Sopenharmony_cistatic void xor_xc_3(unsigned long bytes, unsigned long *p1, unsigned long *p2, 368c2ecf20Sopenharmony_ci unsigned long *p3) 378c2ecf20Sopenharmony_ci{ 388c2ecf20Sopenharmony_ci asm volatile( 398c2ecf20Sopenharmony_ci " larl 1,2f\n" 408c2ecf20Sopenharmony_ci " aghi %0,-1\n" 418c2ecf20Sopenharmony_ci " jm 3f\n" 428c2ecf20Sopenharmony_ci " srlg 0,%0,8\n" 438c2ecf20Sopenharmony_ci " ltgr 0,0\n" 448c2ecf20Sopenharmony_ci " jz 1f\n" 458c2ecf20Sopenharmony_ci "0: xc 0(256,%1),0(%2)\n" 468c2ecf20Sopenharmony_ci " xc 0(256,%1),0(%3)\n" 478c2ecf20Sopenharmony_ci " la %1,256(%1)\n" 488c2ecf20Sopenharmony_ci " la %2,256(%2)\n" 498c2ecf20Sopenharmony_ci " la %3,256(%3)\n" 508c2ecf20Sopenharmony_ci " brctg 0,0b\n" 518c2ecf20Sopenharmony_ci "1: ex %0,0(1)\n" 528c2ecf20Sopenharmony_ci " ex %0,6(1)\n" 538c2ecf20Sopenharmony_ci " j 3f\n" 548c2ecf20Sopenharmony_ci "2: xc 0(1,%1),0(%2)\n" 558c2ecf20Sopenharmony_ci " xc 0(1,%1),0(%3)\n" 568c2ecf20Sopenharmony_ci "3:\n" 578c2ecf20Sopenharmony_ci : "+d" (bytes), "+a" (p1), "+a" (p2), "+a" (p3) 588c2ecf20Sopenharmony_ci : : "0", "1", "cc", "memory"); 598c2ecf20Sopenharmony_ci} 608c2ecf20Sopenharmony_ci 618c2ecf20Sopenharmony_cistatic void xor_xc_4(unsigned long bytes, unsigned long *p1, unsigned long *p2, 628c2ecf20Sopenharmony_ci unsigned long *p3, unsigned long *p4) 638c2ecf20Sopenharmony_ci{ 648c2ecf20Sopenharmony_ci asm volatile( 658c2ecf20Sopenharmony_ci " larl 1,2f\n" 668c2ecf20Sopenharmony_ci " aghi %0,-1\n" 678c2ecf20Sopenharmony_ci " jm 3f\n" 688c2ecf20Sopenharmony_ci " srlg 0,%0,8\n" 698c2ecf20Sopenharmony_ci " ltgr 0,0\n" 708c2ecf20Sopenharmony_ci " jz 1f\n" 718c2ecf20Sopenharmony_ci "0: xc 0(256,%1),0(%2)\n" 728c2ecf20Sopenharmony_ci " xc 0(256,%1),0(%3)\n" 738c2ecf20Sopenharmony_ci " xc 0(256,%1),0(%4)\n" 748c2ecf20Sopenharmony_ci " la %1,256(%1)\n" 758c2ecf20Sopenharmony_ci " la %2,256(%2)\n" 768c2ecf20Sopenharmony_ci " la %3,256(%3)\n" 778c2ecf20Sopenharmony_ci " la %4,256(%4)\n" 788c2ecf20Sopenharmony_ci " brctg 0,0b\n" 798c2ecf20Sopenharmony_ci "1: ex %0,0(1)\n" 808c2ecf20Sopenharmony_ci " ex %0,6(1)\n" 818c2ecf20Sopenharmony_ci " ex %0,12(1)\n" 828c2ecf20Sopenharmony_ci " j 3f\n" 838c2ecf20Sopenharmony_ci "2: xc 0(1,%1),0(%2)\n" 848c2ecf20Sopenharmony_ci " xc 0(1,%1),0(%3)\n" 858c2ecf20Sopenharmony_ci " xc 0(1,%1),0(%4)\n" 868c2ecf20Sopenharmony_ci "3:\n" 878c2ecf20Sopenharmony_ci : "+d" (bytes), "+a" (p1), "+a" (p2), "+a" (p3), "+a" (p4) 888c2ecf20Sopenharmony_ci : : "0", "1", "cc", "memory"); 898c2ecf20Sopenharmony_ci} 908c2ecf20Sopenharmony_ci 918c2ecf20Sopenharmony_cistatic void xor_xc_5(unsigned long bytes, unsigned long *p1, unsigned long *p2, 928c2ecf20Sopenharmony_ci unsigned long *p3, unsigned long *p4, unsigned long *p5) 938c2ecf20Sopenharmony_ci{ 948c2ecf20Sopenharmony_ci /* Get around a gcc oddity */ 958c2ecf20Sopenharmony_ci register unsigned long *reg7 asm ("7") = p5; 968c2ecf20Sopenharmony_ci 978c2ecf20Sopenharmony_ci asm volatile( 988c2ecf20Sopenharmony_ci " larl 1,2f\n" 998c2ecf20Sopenharmony_ci " aghi %0,-1\n" 1008c2ecf20Sopenharmony_ci " jm 3f\n" 1018c2ecf20Sopenharmony_ci " srlg 0,%0,8\n" 1028c2ecf20Sopenharmony_ci " ltgr 0,0\n" 1038c2ecf20Sopenharmony_ci " jz 1f\n" 1048c2ecf20Sopenharmony_ci "0: xc 0(256,%1),0(%2)\n" 1058c2ecf20Sopenharmony_ci " xc 0(256,%1),0(%3)\n" 1068c2ecf20Sopenharmony_ci " xc 0(256,%1),0(%4)\n" 1078c2ecf20Sopenharmony_ci " xc 0(256,%1),0(%5)\n" 1088c2ecf20Sopenharmony_ci " la %1,256(%1)\n" 1098c2ecf20Sopenharmony_ci " la %2,256(%2)\n" 1108c2ecf20Sopenharmony_ci " la %3,256(%3)\n" 1118c2ecf20Sopenharmony_ci " la %4,256(%4)\n" 1128c2ecf20Sopenharmony_ci " la %5,256(%5)\n" 1138c2ecf20Sopenharmony_ci " brctg 0,0b\n" 1148c2ecf20Sopenharmony_ci "1: ex %0,0(1)\n" 1158c2ecf20Sopenharmony_ci " ex %0,6(1)\n" 1168c2ecf20Sopenharmony_ci " ex %0,12(1)\n" 1178c2ecf20Sopenharmony_ci " ex %0,18(1)\n" 1188c2ecf20Sopenharmony_ci " j 3f\n" 1198c2ecf20Sopenharmony_ci "2: xc 0(1,%1),0(%2)\n" 1208c2ecf20Sopenharmony_ci " xc 0(1,%1),0(%3)\n" 1218c2ecf20Sopenharmony_ci " xc 0(1,%1),0(%4)\n" 1228c2ecf20Sopenharmony_ci " xc 0(1,%1),0(%5)\n" 1238c2ecf20Sopenharmony_ci "3:\n" 1248c2ecf20Sopenharmony_ci : "+d" (bytes), "+a" (p1), "+a" (p2), "+a" (p3), "+a" (p4), 1258c2ecf20Sopenharmony_ci "+a" (reg7) 1268c2ecf20Sopenharmony_ci : : "0", "1", "cc", "memory"); 1278c2ecf20Sopenharmony_ci} 1288c2ecf20Sopenharmony_ci 1298c2ecf20Sopenharmony_cistruct xor_block_template xor_block_xc = { 1308c2ecf20Sopenharmony_ci .name = "xc", 1318c2ecf20Sopenharmony_ci .do_2 = xor_xc_2, 1328c2ecf20Sopenharmony_ci .do_3 = xor_xc_3, 1338c2ecf20Sopenharmony_ci .do_4 = xor_xc_4, 1348c2ecf20Sopenharmony_ci .do_5 = xor_xc_5, 1358c2ecf20Sopenharmony_ci}; 1368c2ecf20Sopenharmony_ciEXPORT_SYMBOL(xor_block_xc); 137