^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Optimized xor_block operation for RAID4/5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright IBM Corp. 2016
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/export.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/raid/xor.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <asm/xor.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) static void xor_xc_2(unsigned long bytes, unsigned long *p1, unsigned long *p2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) asm volatile(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) " larl 1,2f\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) " aghi %0,-1\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) " jm 3f\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) " srlg 0,%0,8\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) " ltgr 0,0\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) " jz 1f\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) "0: xc 0(256,%1),0(%2)\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) " la %1,256(%1)\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) " la %2,256(%2)\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) " brctg 0,0b\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) "1: ex %0,0(1)\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) " j 3f\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) "2: xc 0(1,%1),0(%2)\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) "3:\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) : : "d" (bytes), "a" (p1), "a" (p2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) : "0", "1", "cc", "memory");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) static void xor_xc_3(unsigned long bytes, unsigned long *p1, unsigned long *p2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) unsigned long *p3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) asm volatile(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) " larl 1,2f\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) " aghi %0,-1\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) " jm 3f\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) " srlg 0,%0,8\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) " ltgr 0,0\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) " jz 1f\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) "0: xc 0(256,%1),0(%2)\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) " xc 0(256,%1),0(%3)\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) " la %1,256(%1)\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) " la %2,256(%2)\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) " la %3,256(%3)\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) " brctg 0,0b\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) "1: ex %0,0(1)\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) " ex %0,6(1)\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) " j 3f\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) "2: xc 0(1,%1),0(%2)\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) " xc 0(1,%1),0(%3)\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) "3:\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) : "+d" (bytes), "+a" (p1), "+a" (p2), "+a" (p3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) : : "0", "1", "cc", "memory");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) static void xor_xc_4(unsigned long bytes, unsigned long *p1, unsigned long *p2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) unsigned long *p3, unsigned long *p4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) asm volatile(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) " larl 1,2f\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) " aghi %0,-1\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) " jm 3f\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) " srlg 0,%0,8\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) " ltgr 0,0\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) " jz 1f\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) "0: xc 0(256,%1),0(%2)\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) " xc 0(256,%1),0(%3)\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) " xc 0(256,%1),0(%4)\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) " la %1,256(%1)\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) " la %2,256(%2)\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) " la %3,256(%3)\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) " la %4,256(%4)\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) " brctg 0,0b\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) "1: ex %0,0(1)\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) " ex %0,6(1)\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) " ex %0,12(1)\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) " j 3f\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) "2: xc 0(1,%1),0(%2)\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) " xc 0(1,%1),0(%3)\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) " xc 0(1,%1),0(%4)\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) "3:\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) : "+d" (bytes), "+a" (p1), "+a" (p2), "+a" (p3), "+a" (p4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) : : "0", "1", "cc", "memory");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) static void xor_xc_5(unsigned long bytes, unsigned long *p1, unsigned long *p2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) unsigned long *p3, unsigned long *p4, unsigned long *p5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) /* Get around a gcc oddity */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) register unsigned long *reg7 asm ("7") = p5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) asm volatile(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) " larl 1,2f\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) " aghi %0,-1\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) " jm 3f\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) " srlg 0,%0,8\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) " ltgr 0,0\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) " jz 1f\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) "0: xc 0(256,%1),0(%2)\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) " xc 0(256,%1),0(%3)\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) " xc 0(256,%1),0(%4)\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) " xc 0(256,%1),0(%5)\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) " la %1,256(%1)\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) " la %2,256(%2)\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) " la %3,256(%3)\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) " la %4,256(%4)\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) " la %5,256(%5)\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) " brctg 0,0b\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) "1: ex %0,0(1)\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) " ex %0,6(1)\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) " ex %0,12(1)\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) " ex %0,18(1)\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) " j 3f\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) "2: xc 0(1,%1),0(%2)\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) " xc 0(1,%1),0(%3)\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) " xc 0(1,%1),0(%4)\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) " xc 0(1,%1),0(%5)\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) "3:\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) : "+d" (bytes), "+a" (p1), "+a" (p2), "+a" (p3), "+a" (p4),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) "+a" (reg7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) : : "0", "1", "cc", "memory");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) struct xor_block_template xor_block_xc = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) .name = "xc",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) .do_2 = xor_xc_2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) .do_3 = xor_xc_3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) .do_4 = xor_xc_4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) .do_5 = xor_xc_5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) EXPORT_SYMBOL(xor_block_xc);