1*5d9d9091SRichard Lowe/* 2*5d9d9091SRichard Lowe * CDDL HEADER START 3*5d9d9091SRichard Lowe * 4*5d9d9091SRichard Lowe * The contents of this file are subject to the terms of the 5*5d9d9091SRichard Lowe * Common Development and Distribution License, Version 1.0 only 6*5d9d9091SRichard Lowe * (the "License"). You may not use this file except in compliance 7*5d9d9091SRichard Lowe * with the License. 8*5d9d9091SRichard Lowe * 9*5d9d9091SRichard Lowe * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*5d9d9091SRichard Lowe * or http://www.opensolaris.org/os/licensing. 11*5d9d9091SRichard Lowe * See the License for the specific language governing permissions 12*5d9d9091SRichard Lowe * and limitations under the License. 13*5d9d9091SRichard Lowe * 14*5d9d9091SRichard Lowe * When distributing Covered Code, include this CDDL HEADER in each 15*5d9d9091SRichard Lowe * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*5d9d9091SRichard Lowe * If applicable, add the following below this CDDL HEADER, with the 17*5d9d9091SRichard Lowe * fields enclosed by brackets "[]" replaced with your own identifying 18*5d9d9091SRichard Lowe * information: Portions Copyright [yyyy] [name of copyright owner] 19*5d9d9091SRichard Lowe * 20*5d9d9091SRichard Lowe * CDDL HEADER END 21*5d9d9091SRichard Lowe */ 22*5d9d9091SRichard Lowe/* 23*5d9d9091SRichard Lowe * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 24*5d9d9091SRichard Lowe * Use is subject to license terms. 25*5d9d9091SRichard Lowe */ 26*5d9d9091SRichard Lowe 27*5d9d9091SRichard Lowe#include <sys/param.h> 28*5d9d9091SRichard Lowe#include <sys/errno.h> 29*5d9d9091SRichard Lowe#include <sys/asm_linkage.h> 30*5d9d9091SRichard Lowe#include <sys/vtrace.h> 31*5d9d9091SRichard Lowe#include <sys/machthread.h> 32*5d9d9091SRichard Lowe#include <sys/clock.h> 33*5d9d9091SRichard Lowe#include <sys/asi.h> 34*5d9d9091SRichard Lowe#include <sys/fsr.h> 35*5d9d9091SRichard Lowe#include <sys/privregs.h> 36*5d9d9091SRichard Lowe 37*5d9d9091SRichard Lowe#include "assym.h" 38*5d9d9091SRichard Lowe 39*5d9d9091SRichard Lowe#define FP_USED 1 40*5d9d9091SRichard Lowe#define LOFAULT_SET 2 41*5d9d9091SRichard Lowe 42*5d9d9091SRichard Lowe/* 43*5d9d9091SRichard Lowe * Error barrier: 44*5d9d9091SRichard Lowe * We use membar sync to establish an error barrier for 45*5d9d9091SRichard Lowe * deferred errors. Membar syncs are added before any update 46*5d9d9091SRichard Lowe * to t_lofault to ensure that deferred errors from earlier 47*5d9d9091SRichard Lowe * accesses will not be reported after the membar. This error 48*5d9d9091SRichard Lowe * isolation is important when we try to recover from async 49*5d9d9091SRichard Lowe * errors which tries to distinguish kernel accesses to user 50*5d9d9091SRichard Lowe * data. 51*5d9d9091SRichard Lowe */ 52*5d9d9091SRichard Lowe 53*5d9d9091SRichard Lowe/* 54*5d9d9091SRichard Lowe * Zero a block of storage. 55*5d9d9091SRichard Lowe * 56*5d9d9091SRichard Lowe * uzero is used by the kernel to zero a block in user address space. 57*5d9d9091SRichard Lowe */ 58*5d9d9091SRichard Lowe 59*5d9d9091SRichard Lowe ENTRY(uzero) 60*5d9d9091SRichard Lowe ! 61*5d9d9091SRichard Lowe ! Set a new lo_fault handler only if we came in with one 62*5d9d9091SRichard Lowe ! already specified. 63*5d9d9091SRichard Lowe ! 64*5d9d9091SRichard Lowe wr %g0, ASI_USER, %asi 65*5d9d9091SRichard Lowe ldn [THREAD_REG + T_LOFAULT], %o5 66*5d9d9091SRichard Lowe tst %o5 67*5d9d9091SRichard Lowe bz,pt %ncc, .do_zero 68*5d9d9091SRichard Lowe sethi %hi(.zeroerr), %o2 69*5d9d9091SRichard Lowe or %o2, %lo(.zeroerr), %o2 70*5d9d9091SRichard Lowe membar #Sync 71*5d9d9091SRichard Lowe ba,pt %ncc, .do_zero 72*5d9d9091SRichard Lowe stn %o2, [THREAD_REG + T_LOFAULT] 73*5d9d9091SRichard Lowe 74*5d9d9091SRichard Lowe ENTRY(kzero) 75*5d9d9091SRichard Lowe ! 76*5d9d9091SRichard Lowe ! Always set a lo_fault handler 77*5d9d9091SRichard Lowe ! 78*5d9d9091SRichard Lowe wr %g0, ASI_P, %asi 79*5d9d9091SRichard Lowe ldn [THREAD_REG + T_LOFAULT], %o5 80*5d9d9091SRichard Lowe sethi %hi(.zeroerr), %o2 81*5d9d9091SRichard Lowe or %o5, LOFAULT_SET, %o5 82*5d9d9091SRichard Lowe or %o2, %lo(.zeroerr), %o2 83*5d9d9091SRichard Lowe membar #Sync 84*5d9d9091SRichard Lowe ba,pt %ncc, .do_zero 85*5d9d9091SRichard Lowe stn %o2, [THREAD_REG + T_LOFAULT] 86*5d9d9091SRichard Lowe 87*5d9d9091SRichard Lowe/* 88*5d9d9091SRichard Lowe * We got here because of a fault during kzero or if 89*5d9d9091SRichard Lowe * uzero or bzero was called with t_lofault non-zero. 90*5d9d9091SRichard Lowe * Otherwise we've already run screaming from the room. 91*5d9d9091SRichard Lowe * Errno value is in %g1. Note that we're here iff 92*5d9d9091SRichard Lowe * we did set t_lofault. 93*5d9d9091SRichard Lowe */ 94*5d9d9091SRichard Lowe.zeroerr: 95*5d9d9091SRichard Lowe ! 96*5d9d9091SRichard Lowe ! Undo asi register setting. Just set it to be the 97*5d9d9091SRichard Lowe ! kernel default without checking. 98*5d9d9091SRichard Lowe ! 99*5d9d9091SRichard Lowe wr %g0, ASI_P, %asi 100*5d9d9091SRichard Lowe ! 101*5d9d9091SRichard Lowe ! If saved t_lofault has FP_USED set, clear the %fprs register 102*5d9d9091SRichard Lowe ! 103*5d9d9091SRichard Lowe btst FP_USED, %o5 104*5d9d9091SRichard Lowe bz,pt %ncc, 1f ! skip if not used 105*5d9d9091SRichard Lowe nop 106*5d9d9091SRichard Lowe membar #Sync 107*5d9d9091SRichard Lowe wr %g0, %g0, %fprs ! clear fprs 108*5d9d9091SRichard Lowe andn %o5, FP_USED, %o5 ! turn off flag bit 109*5d9d9091SRichard Lowe ! 110*5d9d9091SRichard Lowe ! We did set t_lofault. It may well have been zero coming in. 111*5d9d9091SRichard Lowe ! 112*5d9d9091SRichard Lowe1: 113*5d9d9091SRichard Lowe tst %o5 114*5d9d9091SRichard Lowe membar #Sync 115*5d9d9091SRichard Lowe bne,pn %ncc, 3f 116*5d9d9091SRichard Lowe andncc %o5, LOFAULT_SET, %o5 117*5d9d9091SRichard Lowe2: 118*5d9d9091SRichard Lowe ! 119*5d9d9091SRichard Lowe ! Old handler was zero. Just return the error. 120*5d9d9091SRichard Lowe ! 121*5d9d9091SRichard Lowe retl ! return 122*5d9d9091SRichard Lowe mov %g1, %o0 ! error code from %g1 123*5d9d9091SRichard Lowe3: 124*5d9d9091SRichard Lowe ! 125*5d9d9091SRichard Lowe ! We're here because %o5 was non-zero. It was non-zero 126*5d9d9091SRichard Lowe ! because either LOFAULT_SET was present, a previous fault 127*5d9d9091SRichard Lowe ! handler was present or both. In all cases we need to reset 128*5d9d9091SRichard Lowe ! T_LOFAULT to the value of %o5 after clearing LOFAULT_SET 129*5d9d9091SRichard Lowe ! before we either simply return the error or we invoke the 130*5d9d9091SRichard Lowe ! previously specified handler. 131*5d9d9091SRichard Lowe ! 132*5d9d9091SRichard Lowe be %ncc, 2b 133*5d9d9091SRichard Lowe stn %o5, [THREAD_REG + T_LOFAULT] 134*5d9d9091SRichard Lowe jmp %o5 ! goto real handler 135*5d9d9091SRichard Lowe nop 136*5d9d9091SRichard Lowe SET_SIZE(kzero) 137*5d9d9091SRichard Lowe SET_SIZE(uzero) 138*5d9d9091SRichard Lowe 139*5d9d9091SRichard Lowe/* 140*5d9d9091SRichard Lowe * Zero a block of storage. 141*5d9d9091SRichard Lowe */ 142*5d9d9091SRichard Lowe 143*5d9d9091SRichard Lowe ENTRY(bzero) 144*5d9d9091SRichard Lowe wr %g0, ASI_P, %asi 145*5d9d9091SRichard Lowe 146*5d9d9091SRichard Lowe ldn [THREAD_REG + T_LOFAULT], %o5 ! save old vector 147*5d9d9091SRichard Lowe tst %o5 148*5d9d9091SRichard Lowe bz,pt %ncc, .do_zero 149*5d9d9091SRichard Lowe sethi %hi(.zeroerr), %o2 150*5d9d9091SRichard Lowe or %o2, %lo(.zeroerr), %o2 151*5d9d9091SRichard Lowe membar #Sync ! sync error barrier 152*5d9d9091SRichard Lowe stn %o2, [THREAD_REG + T_LOFAULT] ! install new vector 153*5d9d9091SRichard Lowe 154*5d9d9091SRichard Lowe.do_zero: 155*5d9d9091SRichard Lowe cmp %o1, 15 ! check for small counts 156*5d9d9091SRichard Lowe blu,pn %ncc, .byteclr ! just clear bytes 157*5d9d9091SRichard Lowe nop 158*5d9d9091SRichard Lowe 159*5d9d9091SRichard Lowe cmp %o1, 192 ! check for large counts 160*5d9d9091SRichard Lowe blu %ncc, .bzero_small 161*5d9d9091SRichard Lowe nop 162*5d9d9091SRichard Lowe 163*5d9d9091SRichard Lowe sethi %hi(use_hw_bzero), %o2 164*5d9d9091SRichard Lowe ld [%o2 + %lo(use_hw_bzero)], %o2 165*5d9d9091SRichard Lowe tst %o2 166*5d9d9091SRichard Lowe bz %icc, .bzero_small 167*5d9d9091SRichard Lowe nop 168*5d9d9091SRichard Lowe 169*5d9d9091SRichard Lowe rd %fprs, %o2 ! check for unused fp 170*5d9d9091SRichard Lowe btst FPRS_FEF, %o2 171*5d9d9091SRichard Lowe bnz %icc, .bzero_small 172*5d9d9091SRichard Lowe nop 173*5d9d9091SRichard Lowe 174*5d9d9091SRichard Lowe ldn [THREAD_REG + T_LWP], %o2 175*5d9d9091SRichard Lowe tst %o2 176*5d9d9091SRichard Lowe bz,pn %ncc, .bzero_small 177*5d9d9091SRichard Lowe nop 178*5d9d9091SRichard Lowe 179*5d9d9091SRichard Lowe ! Check for block alignment 180*5d9d9091SRichard Lowe btst (64-1), %o0 181*5d9d9091SRichard Lowe bz %icc, .bzl_block 182*5d9d9091SRichard Lowe nop 183*5d9d9091SRichard Lowe 184*5d9d9091SRichard Lowe ! Check for double-word alignment 185*5d9d9091SRichard Lowe btst (8-1), %o0 186*5d9d9091SRichard Lowe bz %icc, .bzl_dword 187*5d9d9091SRichard Lowe nop 188*5d9d9091SRichard Lowe 189*5d9d9091SRichard Lowe ! Check for word alignment 190*5d9d9091SRichard Lowe btst (4-1), %o0 191*5d9d9091SRichard Lowe bz %icc, .bzl_word 192*5d9d9091SRichard Lowe nop 193*5d9d9091SRichard Lowe 194*5d9d9091SRichard Lowe ! Clear bytes until word aligned 195*5d9d9091SRichard Lowe.bzl_byte: 196*5d9d9091SRichard Lowe stba %g0, [%o0]%asi 197*5d9d9091SRichard Lowe add %o0, 1, %o0 198*5d9d9091SRichard Lowe btst (4-1), %o0 199*5d9d9091SRichard Lowe bnz %icc, .bzl_byte 200*5d9d9091SRichard Lowe sub %o1, 1, %o1 201*5d9d9091SRichard Lowe 202*5d9d9091SRichard Lowe ! Check for dword-aligned 203*5d9d9091SRichard Lowe btst (8-1), %o0 204*5d9d9091SRichard Lowe bz %icc, .bzl_dword 205*5d9d9091SRichard Lowe nop 206*5d9d9091SRichard Lowe 207*5d9d9091SRichard Lowe ! Clear words until double-word aligned 208*5d9d9091SRichard Lowe.bzl_word: 209*5d9d9091SRichard Lowe sta %g0, [%o0]%asi 210*5d9d9091SRichard Lowe add %o0, 4, %o0 211*5d9d9091SRichard Lowe btst (8-1), %o0 212*5d9d9091SRichard Lowe bnz %icc, .bzl_word 213*5d9d9091SRichard Lowe sub %o1, 4, %o1 214*5d9d9091SRichard Lowe 215*5d9d9091SRichard Lowe.bzl_dword: 216*5d9d9091SRichard Lowe ! Clear dwords until block aligned 217*5d9d9091SRichard Lowe stxa %g0, [%o0]%asi 218*5d9d9091SRichard Lowe add %o0, 8, %o0 219*5d9d9091SRichard Lowe btst (64-1), %o0 220*5d9d9091SRichard Lowe bnz %icc, .bzl_dword 221*5d9d9091SRichard Lowe sub %o1, 8, %o1 222*5d9d9091SRichard Lowe 223*5d9d9091SRichard Lowe.bzl_block: 224*5d9d9091SRichard Lowe membar #StoreStore|#StoreLoad|#LoadStore 225*5d9d9091SRichard Lowe wr %g0, FPRS_FEF, %fprs 226*5d9d9091SRichard Lowe 227*5d9d9091SRichard Lowe ! Set the lower bit in the saved t_lofault to indicate 228*5d9d9091SRichard Lowe ! that we need to clear the %fprs register on the way 229*5d9d9091SRichard Lowe ! out 230*5d9d9091SRichard Lowe or %o5, FP_USED, %o5 231*5d9d9091SRichard Lowe 232*5d9d9091SRichard Lowe ! Clear block 233*5d9d9091SRichard Lowe fzero %d0 234*5d9d9091SRichard Lowe fzero %d2 235*5d9d9091SRichard Lowe fzero %d4 236*5d9d9091SRichard Lowe fzero %d6 237*5d9d9091SRichard Lowe fzero %d8 238*5d9d9091SRichard Lowe fzero %d10 239*5d9d9091SRichard Lowe fzero %d12 240*5d9d9091SRichard Lowe fzero %d14 241*5d9d9091SRichard Lowe rd %asi, %o3 242*5d9d9091SRichard Lowe wr %g0, ASI_BLK_P, %asi 243*5d9d9091SRichard Lowe cmp %o3, ASI_P 244*5d9d9091SRichard Lowe bne,a %icc, 1f 245*5d9d9091SRichard Lowe wr %g0, ASI_BLK_AIUS, %asi 246*5d9d9091SRichard Lowe1: 247*5d9d9091SRichard Lowe mov 256, %o3 248*5d9d9091SRichard Lowe ba,pt %ncc, .bzl_doblock 249*5d9d9091SRichard Lowe nop 250*5d9d9091SRichard Lowe 251*5d9d9091SRichard Lowe.bzl_blkstart: 252*5d9d9091SRichard Lowe ! stda %d0, [%o0+192]%asi ! in dly slot of branch that got us here 253*5d9d9091SRichard Lowe stda %d0, [%o0+128]%asi 254*5d9d9091SRichard Lowe stda %d0, [%o0+64]%asi 255*5d9d9091SRichard Lowe stda %d0, [%o0]%asi 256*5d9d9091SRichard Lowe.bzl_zinst: 257*5d9d9091SRichard Lowe add %o0, %o3, %o0 258*5d9d9091SRichard Lowe sub %o1, %o3, %o1 259*5d9d9091SRichard Lowe.bzl_doblock: 260*5d9d9091SRichard Lowe cmp %o1, 256 261*5d9d9091SRichard Lowe bgeu,a %ncc, .bzl_blkstart 262*5d9d9091SRichard Lowe stda %d0, [%o0+192]%asi 263*5d9d9091SRichard Lowe 264*5d9d9091SRichard Lowe cmp %o1, 64 265*5d9d9091SRichard Lowe blu %ncc, .bzl_finish 266*5d9d9091SRichard Lowe 267*5d9d9091SRichard Lowe andn %o1, (64-1), %o3 268*5d9d9091SRichard Lowe srl %o3, 4, %o2 ! using blocks, 1 instr / 16 words 269*5d9d9091SRichard Lowe set .bzl_zinst, %o4 270*5d9d9091SRichard Lowe sub %o4, %o2, %o4 271*5d9d9091SRichard Lowe jmp %o4 272*5d9d9091SRichard Lowe nop 273*5d9d9091SRichard Lowe 274*5d9d9091SRichard Lowe.bzl_finish: 275*5d9d9091SRichard Lowe membar #StoreLoad|#StoreStore 276*5d9d9091SRichard Lowe wr %g0, %g0, %fprs 277*5d9d9091SRichard Lowe andn %o5, FP_USED, %o5 278*5d9d9091SRichard Lowe 279*5d9d9091SRichard Lowe rd %asi, %o4 280*5d9d9091SRichard Lowe wr %g0, ASI_P, %asi 281*5d9d9091SRichard Lowe cmp %o4, ASI_BLK_P 282*5d9d9091SRichard Lowe bne,a %icc, 1f 283*5d9d9091SRichard Lowe wr %g0, ASI_USER, %asi 284*5d9d9091SRichard Lowe1: 285*5d9d9091SRichard Lowe 286*5d9d9091SRichard Lowe.bzlf_dword: 287*5d9d9091SRichard Lowe ! double words 288*5d9d9091SRichard Lowe cmp %o1, 8 289*5d9d9091SRichard Lowe blu %ncc, .bzlf_word 290*5d9d9091SRichard Lowe nop 291*5d9d9091SRichard Lowe stxa %g0, [%o0]%asi 292*5d9d9091SRichard Lowe add %o0, 8, %o0 293*5d9d9091SRichard Lowe sub %o1, 8, %o1 294*5d9d9091SRichard Lowe ba,pt %ncc, .bzlf_dword 295*5d9d9091SRichard Lowe nop 296*5d9d9091SRichard Lowe 297*5d9d9091SRichard Lowe.bzlf_word: 298*5d9d9091SRichard Lowe ! words 299*5d9d9091SRichard Lowe cmp %o1, 4 300*5d9d9091SRichard Lowe blu %ncc, .bzlf_byte 301*5d9d9091SRichard Lowe nop 302*5d9d9091SRichard Lowe sta %g0, [%o0]%asi 303*5d9d9091SRichard Lowe add %o0, 4, %o0 304*5d9d9091SRichard Lowe sub %o1, 4, %o1 305*5d9d9091SRichard Lowe ba,pt %ncc, .bzlf_word 306*5d9d9091SRichard Lowe nop 307*5d9d9091SRichard Lowe 308*5d9d9091SRichard Lowe1: 309*5d9d9091SRichard Lowe add %o0, 1, %o0 ! increment address 310*5d9d9091SRichard Lowe.bzlf_byte: 311*5d9d9091SRichard Lowe subcc %o1, 1, %o1 ! decrement count 312*5d9d9091SRichard Lowe bgeu,a %ncc, 1b 313*5d9d9091SRichard Lowe stba %g0, [%o0]%asi ! zero a byte 314*5d9d9091SRichard Lowe 315*5d9d9091SRichard Lowe ! 316*5d9d9091SRichard Lowe ! If we used the FP registers, that bit was turned 317*5d9d9091SRichard Lowe ! off after we were finished. We're just concerned with 318*5d9d9091SRichard Lowe ! whether t_lofault was set when we came in. We end up 319*5d9d9091SRichard Lowe ! here from either kzero() or bzero(). kzero() *always* 320*5d9d9091SRichard Lowe ! sets a lofault handler. It ors LOFAULT_SET into %o5 321*5d9d9091SRichard Lowe ! to indicate it has done this even if the value of %o5 322*5d9d9091SRichard Lowe ! is otherwise zero. bzero() sets a lofault handler *only* 323*5d9d9091SRichard Lowe ! if one was previously set. Accordingly we need to examine 324*5d9d9091SRichard Lowe ! %o5 and if it is non-zero be sure to clear LOFAULT_SET 325*5d9d9091SRichard Lowe ! before resetting the error handler. 326*5d9d9091SRichard Lowe ! 327*5d9d9091SRichard Lowe tst %o5 328*5d9d9091SRichard Lowe bz,pt %ncc, 1f 329*5d9d9091SRichard Lowe andn %o5, LOFAULT_SET, %o5 330*5d9d9091SRichard Lowe membar #Sync ! sync error barrier 331*5d9d9091SRichard Lowe stn %o5, [THREAD_REG + T_LOFAULT] ! restore old t_lofault 332*5d9d9091SRichard Lowe1: 333*5d9d9091SRichard Lowe retl 334*5d9d9091SRichard Lowe clr %o0 ! return (0) 335*5d9d9091SRichard Lowe 336*5d9d9091SRichard Lowe.bzero_small: 337*5d9d9091SRichard Lowe 338*5d9d9091SRichard Lowe ! 339*5d9d9091SRichard Lowe ! Check for word alignment. 340*5d9d9091SRichard Lowe ! 341*5d9d9091SRichard Lowe btst 3, %o0 342*5d9d9091SRichard Lowe bz .bzero_probe 343*5d9d9091SRichard Lowe mov 0x100, %o3 ! constant size of main loop 344*5d9d9091SRichard Lowe ! 345*5d9d9091SRichard Lowe ! 346*5d9d9091SRichard Lowe ! clear bytes until word aligned 347*5d9d9091SRichard Lowe ! 348*5d9d9091SRichard Lowe1: stba %g0,[%o0]%asi 349*5d9d9091SRichard Lowe add %o0, 1, %o0 350*5d9d9091SRichard Lowe btst 3, %o0 351*5d9d9091SRichard Lowe bnz 1b 352*5d9d9091SRichard Lowe sub %o1, 1, %o1 353*5d9d9091SRichard Lowe.bzero_probe: 354*5d9d9091SRichard Lowe 355*5d9d9091SRichard Lowe ! 356*5d9d9091SRichard Lowe ! if needed move a word to become double-word aligned. 357*5d9d9091SRichard Lowe ! 358*5d9d9091SRichard Lowe btst 7, %o0 ! is double aligned? 359*5d9d9091SRichard Lowe bz %icc, .bzero_nobuf 360*5d9d9091SRichard Lowe nop 361*5d9d9091SRichard Lowe sta %g0, [%o0]%asi ! clr to double boundry 362*5d9d9091SRichard Lowe sub %o1, 4, %o1 363*5d9d9091SRichard Lowe ba,pt %ncc, .bzero_nobuf 364*5d9d9091SRichard Lowe add %o0, 4, %o0 365*5d9d9091SRichard Lowe 366*5d9d9091SRichard Lowe !stxa %g0, [%o0+0xf8]%asi 367*5d9d9091SRichard Lowe.bzero_blk: 368*5d9d9091SRichard Lowe stxa %g0, [%o0+0xf0]%asi 369*5d9d9091SRichard Lowe stxa %g0, [%o0+0xe8]%asi 370*5d9d9091SRichard Lowe stxa %g0, [%o0+0xe0]%asi 371*5d9d9091SRichard Lowe stxa %g0, [%o0+0xd8]%asi 372*5d9d9091SRichard Lowe stxa %g0, [%o0+0xd0]%asi 373*5d9d9091SRichard Lowe stxa %g0, [%o0+0xc8]%asi 374*5d9d9091SRichard Lowe stxa %g0, [%o0+0xc0]%asi 375*5d9d9091SRichard Lowe stxa %g0, [%o0+0xb8]%asi 376*5d9d9091SRichard Lowe stxa %g0, [%o0+0xb0]%asi 377*5d9d9091SRichard Lowe stxa %g0, [%o0+0xa8]%asi 378*5d9d9091SRichard Lowe stxa %g0, [%o0+0xa0]%asi 379*5d9d9091SRichard Lowe stxa %g0, [%o0+0x98]%asi 380*5d9d9091SRichard Lowe stxa %g0, [%o0+0x90]%asi 381*5d9d9091SRichard Lowe stxa %g0, [%o0+0x88]%asi 382*5d9d9091SRichard Lowe stxa %g0, [%o0+0x80]%asi 383*5d9d9091SRichard Lowe stxa %g0, [%o0+0x78]%asi 384*5d9d9091SRichard Lowe stxa %g0, [%o0+0x70]%asi 385*5d9d9091SRichard Lowe stxa %g0, [%o0+0x68]%asi 386*5d9d9091SRichard Lowe stxa %g0, [%o0+0x60]%asi 387*5d9d9091SRichard Lowe stxa %g0, [%o0+0x58]%asi 388*5d9d9091SRichard Lowe stxa %g0, [%o0+0x50]%asi 389*5d9d9091SRichard Lowe stxa %g0, [%o0+0x48]%asi 390*5d9d9091SRichard Lowe stxa %g0, [%o0+0x40]%asi 391*5d9d9091SRichard Lowe stxa %g0, [%o0+0x38]%asi 392*5d9d9091SRichard Lowe stxa %g0, [%o0+0x30]%asi 393*5d9d9091SRichard Lowe stxa %g0, [%o0+0x28]%asi 394*5d9d9091SRichard Lowe stxa %g0, [%o0+0x20]%asi 395*5d9d9091SRichard Lowe stxa %g0, [%o0+0x18]%asi 396*5d9d9091SRichard Lowe stxa %g0, [%o0+0x10]%asi 397*5d9d9091SRichard Lowe stxa %g0, [%o0+0x08]%asi 398*5d9d9091SRichard Lowe stxa %g0, [%o0]%asi 399*5d9d9091SRichard Lowe.zinst: 400*5d9d9091SRichard Lowe add %o0, %o3, %o0 ! increment source address 401*5d9d9091SRichard Lowe sub %o1, %o3, %o1 ! decrement count 402*5d9d9091SRichard Lowe.bzero_nobuf: 403*5d9d9091SRichard Lowe cmp %o1, 0x100 ! can we do whole chunk? 404*5d9d9091SRichard Lowe bgeu,a %ncc, .bzero_blk 405*5d9d9091SRichard Lowe stxa %g0, [%o0+0xf8]%asi ! do first double of chunk 406*5d9d9091SRichard Lowe 407*5d9d9091SRichard Lowe cmp %o1, 7 ! can we zero any more double words 408*5d9d9091SRichard Lowe bleu %ncc, .byteclr ! too small go zero bytes 409*5d9d9091SRichard Lowe 410*5d9d9091SRichard Lowe andn %o1, 7, %o3 ! %o3 bytes left, double-word aligned 411*5d9d9091SRichard Lowe srl %o3, 1, %o2 ! using doubles, need 1 instr / 2 words 412*5d9d9091SRichard Lowe set .zinst, %o4 ! address of clr instructions 413*5d9d9091SRichard Lowe sub %o4, %o2, %o4 ! jmp address relative to instr 414*5d9d9091SRichard Lowe jmp %o4 415*5d9d9091SRichard Lowe nop 416*5d9d9091SRichard Lowe ! 417*5d9d9091SRichard Lowe ! do leftover bytes 418*5d9d9091SRichard Lowe ! 419*5d9d9091SRichard Lowe3: 420*5d9d9091SRichard Lowe add %o0, 1, %o0 ! increment address 421*5d9d9091SRichard Lowe.byteclr: 422*5d9d9091SRichard Lowe subcc %o1, 1, %o1 ! decrement count 423*5d9d9091SRichard Lowe bgeu,a %ncc, 3b 424*5d9d9091SRichard Lowe stba %g0, [%o0]%asi ! zero a byte 425*5d9d9091SRichard Lowe 426*5d9d9091SRichard Lowe.bzero_finished: 427*5d9d9091SRichard Lowe ! 428*5d9d9091SRichard Lowe ! We're just concerned with whether t_lofault was set 429*5d9d9091SRichard Lowe ! when we came in. We end up here from either kzero() 430*5d9d9091SRichard Lowe ! or bzero(). kzero() *always* sets a lofault handler. 431*5d9d9091SRichard Lowe ! It ors LOFAULT_SET into %o5 to indicate it has done 432*5d9d9091SRichard Lowe ! this even if the value of %o5 is otherwise zero. 433*5d9d9091SRichard Lowe ! bzero() sets a lofault handler *only* if one was 434*5d9d9091SRichard Lowe ! previously set. Accordingly we need to examine 435*5d9d9091SRichard Lowe ! %o5 and if it is non-zero be sure to clear LOFAULT_SET 436*5d9d9091SRichard Lowe ! before resetting the error handler. 437*5d9d9091SRichard Lowe ! 438*5d9d9091SRichard Lowe tst %o5 439*5d9d9091SRichard Lowe bz %ncc, 1f 440*5d9d9091SRichard Lowe andn %o5, LOFAULT_SET, %o5 441*5d9d9091SRichard Lowe membar #Sync ! sync error barrier 442*5d9d9091SRichard Lowe stn %o5, [THREAD_REG + T_LOFAULT] ! restore old t_lofault 443*5d9d9091SRichard Lowe1: 444*5d9d9091SRichard Lowe retl 445*5d9d9091SRichard Lowe clr %o0 ! return (0) 446*5d9d9091SRichard Lowe 447*5d9d9091SRichard Lowe SET_SIZE(bzero) 448