18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 28c2ecf20Sopenharmony_ci/* GENbzero.S: Generic sparc64 memset/clear_user. 38c2ecf20Sopenharmony_ci * 48c2ecf20Sopenharmony_ci * Copyright (C) 2007 David S. Miller (davem@davemloft.net) 58c2ecf20Sopenharmony_ci */ 68c2ecf20Sopenharmony_ci#include <asm/asi.h> 78c2ecf20Sopenharmony_ci 88c2ecf20Sopenharmony_ci#define EX_ST(x,y) \ 98c2ecf20Sopenharmony_ci98: x,y; \ 108c2ecf20Sopenharmony_ci .section __ex_table,"a";\ 118c2ecf20Sopenharmony_ci .align 4; \ 128c2ecf20Sopenharmony_ci .word 98b, __retl_o1_asi;\ 138c2ecf20Sopenharmony_ci .text; \ 148c2ecf20Sopenharmony_ci .align 4; 158c2ecf20Sopenharmony_ci 168c2ecf20Sopenharmony_ci .align 32 178c2ecf20Sopenharmony_ci .text 188c2ecf20Sopenharmony_ci 198c2ecf20Sopenharmony_ci .globl GENmemset 208c2ecf20Sopenharmony_ci .type GENmemset, #function 218c2ecf20Sopenharmony_ciGENmemset: /* %o0=buf, %o1=pat, %o2=len */ 228c2ecf20Sopenharmony_ci and %o1, 0xff, %o3 238c2ecf20Sopenharmony_ci mov %o2, %o1 248c2ecf20Sopenharmony_ci sllx %o3, 8, %g1 258c2ecf20Sopenharmony_ci or %g1, %o3, %o2 268c2ecf20Sopenharmony_ci sllx %o2, 16, %g1 278c2ecf20Sopenharmony_ci or %g1, %o2, %o2 288c2ecf20Sopenharmony_ci sllx %o2, 32, %g1 298c2ecf20Sopenharmony_ci ba,pt %xcc, 1f 308c2ecf20Sopenharmony_ci or %g1, %o2, %o2 318c2ecf20Sopenharmony_ci 328c2ecf20Sopenharmony_ci .globl GENbzero 338c2ecf20Sopenharmony_ci .type GENbzero, #function 348c2ecf20Sopenharmony_ciGENbzero: 358c2ecf20Sopenharmony_ci clr %o2 368c2ecf20Sopenharmony_ci1: brz,pn %o1, GENbzero_return 378c2ecf20Sopenharmony_ci mov %o0, %o3 388c2ecf20Sopenharmony_ci 398c2ecf20Sopenharmony_ci /* %o5: saved %asi, restored at GENbzero_done 408c2ecf20Sopenharmony_ci * %o4: store %asi to use 418c2ecf20Sopenharmony_ci */ 428c2ecf20Sopenharmony_ci rd %asi, %o5 438c2ecf20Sopenharmony_ci mov ASI_P, %o4 448c2ecf20Sopenharmony_ci wr %o4, 0x0, %asi 458c2ecf20Sopenharmony_ci 468c2ecf20Sopenharmony_ciGENbzero_from_clear_user: 478c2ecf20Sopenharmony_ci cmp %o1, 15 488c2ecf20Sopenharmony_ci bl,pn %icc, GENbzero_tiny 498c2ecf20Sopenharmony_ci andcc %o0, 0x7, %g1 508c2ecf20Sopenharmony_ci be,pt %xcc, 2f 518c2ecf20Sopenharmony_ci mov 8, %g2 528c2ecf20Sopenharmony_ci sub %g2, %g1, %g1 538c2ecf20Sopenharmony_ci sub %o1, %g1, %o1 548c2ecf20Sopenharmony_ci1: EX_ST(stba %o2, [%o0 + 0x00] %asi) 558c2ecf20Sopenharmony_ci subcc %g1, 1, %g1 568c2ecf20Sopenharmony_ci bne,pt %xcc, 1b 578c2ecf20Sopenharmony_ci add %o0, 1, %o0 588c2ecf20Sopenharmony_ci2: cmp %o1, 128 598c2ecf20Sopenharmony_ci bl,pn %icc, GENbzero_medium 608c2ecf20Sopenharmony_ci andcc %o0, (64 - 1), %g1 618c2ecf20Sopenharmony_ci be,pt %xcc, GENbzero_pre_loop 628c2ecf20Sopenharmony_ci mov 64, %g2 638c2ecf20Sopenharmony_ci sub %g2, %g1, %g1 648c2ecf20Sopenharmony_ci sub %o1, %g1, %o1 658c2ecf20Sopenharmony_ci1: EX_ST(stxa %o2, [%o0 + 0x00] %asi) 668c2ecf20Sopenharmony_ci subcc %g1, 8, %g1 678c2ecf20Sopenharmony_ci bne,pt %xcc, 1b 688c2ecf20Sopenharmony_ci add %o0, 8, %o0 698c2ecf20Sopenharmony_ci 708c2ecf20Sopenharmony_ciGENbzero_pre_loop: 718c2ecf20Sopenharmony_ci andn %o1, (64 - 1), %g1 728c2ecf20Sopenharmony_ci sub %o1, %g1, %o1 738c2ecf20Sopenharmony_ciGENbzero_loop: 748c2ecf20Sopenharmony_ci EX_ST(stxa %o2, [%o0 + 0x00] %asi) 758c2ecf20Sopenharmony_ci EX_ST(stxa %o2, [%o0 + 0x08] %asi) 768c2ecf20Sopenharmony_ci EX_ST(stxa %o2, [%o0 + 0x10] %asi) 778c2ecf20Sopenharmony_ci EX_ST(stxa %o2, [%o0 + 0x18] %asi) 788c2ecf20Sopenharmony_ci EX_ST(stxa %o2, [%o0 + 0x20] %asi) 798c2ecf20Sopenharmony_ci EX_ST(stxa %o2, [%o0 + 0x28] %asi) 808c2ecf20Sopenharmony_ci EX_ST(stxa %o2, [%o0 + 0x30] %asi) 818c2ecf20Sopenharmony_ci EX_ST(stxa %o2, [%o0 + 0x38] %asi) 828c2ecf20Sopenharmony_ci subcc %g1, 64, %g1 838c2ecf20Sopenharmony_ci bne,pt %xcc, GENbzero_loop 848c2ecf20Sopenharmony_ci add %o0, 64, %o0 858c2ecf20Sopenharmony_ci 868c2ecf20Sopenharmony_ci membar #Sync 878c2ecf20Sopenharmony_ci wr %o4, 0x0, %asi 888c2ecf20Sopenharmony_ci brz,pn %o1, GENbzero_done 898c2ecf20Sopenharmony_ciGENbzero_medium: 908c2ecf20Sopenharmony_ci andncc %o1, 0x7, %g1 918c2ecf20Sopenharmony_ci be,pn %xcc, 2f 928c2ecf20Sopenharmony_ci sub %o1, %g1, %o1 938c2ecf20Sopenharmony_ci1: EX_ST(stxa %o2, [%o0 + 0x00] %asi) 948c2ecf20Sopenharmony_ci subcc %g1, 8, %g1 958c2ecf20Sopenharmony_ci bne,pt %xcc, 1b 968c2ecf20Sopenharmony_ci add %o0, 8, %o0 978c2ecf20Sopenharmony_ci2: brz,pt %o1, GENbzero_done 988c2ecf20Sopenharmony_ci nop 998c2ecf20Sopenharmony_ci 1008c2ecf20Sopenharmony_ciGENbzero_tiny: 1018c2ecf20Sopenharmony_ci1: EX_ST(stba %o2, [%o0 + 0x00] %asi) 1028c2ecf20Sopenharmony_ci subcc %o1, 1, %o1 1038c2ecf20Sopenharmony_ci bne,pt %icc, 1b 1048c2ecf20Sopenharmony_ci add %o0, 1, %o0 1058c2ecf20Sopenharmony_ci 1068c2ecf20Sopenharmony_ci /* fallthrough */ 1078c2ecf20Sopenharmony_ci 1088c2ecf20Sopenharmony_ciGENbzero_done: 1098c2ecf20Sopenharmony_ci wr %o5, 0x0, %asi 1108c2ecf20Sopenharmony_ci 1118c2ecf20Sopenharmony_ciGENbzero_return: 1128c2ecf20Sopenharmony_ci retl 1138c2ecf20Sopenharmony_ci mov %o3, %o0 1148c2ecf20Sopenharmony_ci .size GENbzero, .-GENbzero 1158c2ecf20Sopenharmony_ci .size GENmemset, .-GENmemset 1168c2ecf20Sopenharmony_ci 1178c2ecf20Sopenharmony_ci .globl GENclear_user 1188c2ecf20Sopenharmony_ci .type GENclear_user, #function 1198c2ecf20Sopenharmony_ciGENclear_user: /* %o0=buf, %o1=len */ 1208c2ecf20Sopenharmony_ci rd %asi, %o5 1218c2ecf20Sopenharmony_ci brz,pn %o1, GENbzero_done 1228c2ecf20Sopenharmony_ci clr %o3 1238c2ecf20Sopenharmony_ci cmp %o5, ASI_AIUS 1248c2ecf20Sopenharmony_ci bne,pn %icc, GENbzero 1258c2ecf20Sopenharmony_ci clr %o2 1268c2ecf20Sopenharmony_ci ba,pt %xcc, GENbzero_from_clear_user 1278c2ecf20Sopenharmony_ci mov ASI_AIUS, %o4 1288c2ecf20Sopenharmony_ci .size GENclear_user, .-GENclear_user 1298c2ecf20Sopenharmony_ci 1308c2ecf20Sopenharmony_ci#define BRANCH_ALWAYS 0x10680000 1318c2ecf20Sopenharmony_ci#define NOP 0x01000000 1328c2ecf20Sopenharmony_ci#define GEN_DO_PATCH(OLD, NEW) \ 1338c2ecf20Sopenharmony_ci sethi %hi(NEW), %g1; \ 1348c2ecf20Sopenharmony_ci or %g1, %lo(NEW), %g1; \ 1358c2ecf20Sopenharmony_ci sethi %hi(OLD), %g2; \ 1368c2ecf20Sopenharmony_ci or %g2, %lo(OLD), %g2; \ 1378c2ecf20Sopenharmony_ci sub %g1, %g2, %g1; \ 1388c2ecf20Sopenharmony_ci sethi %hi(BRANCH_ALWAYS), %g3; \ 1398c2ecf20Sopenharmony_ci sll %g1, 11, %g1; \ 1408c2ecf20Sopenharmony_ci srl %g1, 11 + 2, %g1; \ 1418c2ecf20Sopenharmony_ci or %g3, %lo(BRANCH_ALWAYS), %g3; \ 1428c2ecf20Sopenharmony_ci or %g3, %g1, %g3; \ 1438c2ecf20Sopenharmony_ci stw %g3, [%g2]; \ 1448c2ecf20Sopenharmony_ci sethi %hi(NOP), %g3; \ 1458c2ecf20Sopenharmony_ci or %g3, %lo(NOP), %g3; \ 1468c2ecf20Sopenharmony_ci stw %g3, [%g2 + 0x4]; \ 1478c2ecf20Sopenharmony_ci flush %g2; 1488c2ecf20Sopenharmony_ci 1498c2ecf20Sopenharmony_ci .globl generic_patch_bzero 1508c2ecf20Sopenharmony_ci .type generic_patch_bzero,#function 1518c2ecf20Sopenharmony_cigeneric_patch_bzero: 1528c2ecf20Sopenharmony_ci GEN_DO_PATCH(memset, GENmemset) 1538c2ecf20Sopenharmony_ci GEN_DO_PATCH(__bzero, GENbzero) 1548c2ecf20Sopenharmony_ci GEN_DO_PATCH(__clear_user, GENclear_user) 1558c2ecf20Sopenharmony_ci retl 1568c2ecf20Sopenharmony_ci nop 1578c2ecf20Sopenharmony_ci .size generic_patch_bzero,.-generic_patch_bzero 158