17c478bd9Sstevel@tonic-gate/* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 57c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 67c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 77c478bd9Sstevel@tonic-gate * with the License. 87c478bd9Sstevel@tonic-gate * 97c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 107c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 117c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 127c478bd9Sstevel@tonic-gate * and limitations under the License. 137c478bd9Sstevel@tonic-gate * 147c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 157c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 167c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 177c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 187c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 197c478bd9Sstevel@tonic-gate * 207c478bd9Sstevel@tonic-gate * CDDL HEADER END 217c478bd9Sstevel@tonic-gate */ 227c478bd9Sstevel@tonic-gate/* 237c478bd9Sstevel@tonic-gate * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 247c478bd9Sstevel@tonic-gate * Use is subject to license terms. 257c478bd9Sstevel@tonic-gate */ 267c478bd9Sstevel@tonic-gate 277c478bd9Sstevel@tonic-gate#include <sys/param.h> 287c478bd9Sstevel@tonic-gate#include <sys/errno.h> 297c478bd9Sstevel@tonic-gate#include <sys/asm_linkage.h> 307c478bd9Sstevel@tonic-gate#include <sys/vtrace.h> 317c478bd9Sstevel@tonic-gate#include <sys/machthread.h> 327c478bd9Sstevel@tonic-gate#include <sys/clock.h> 337c478bd9Sstevel@tonic-gate#include <sys/asi.h> 347c478bd9Sstevel@tonic-gate#include <sys/fsr.h> 357c478bd9Sstevel@tonic-gate#include <sys/privregs.h> 367c478bd9Sstevel@tonic-gate 377c478bd9Sstevel@tonic-gate#include "assym.h" 387c478bd9Sstevel@tonic-gate 397c478bd9Sstevel@tonic-gate#define FP_USED 1 407c478bd9Sstevel@tonic-gate#define LOFAULT_SET 2 417c478bd9Sstevel@tonic-gate 427c478bd9Sstevel@tonic-gate/* 437c478bd9Sstevel@tonic-gate * Error barrier: 447c478bd9Sstevel@tonic-gate * We use membar sync to establish an error barrier for 457c478bd9Sstevel@tonic-gate * deferred errors. Membar syncs are added before any update 467c478bd9Sstevel@tonic-gate * to t_lofault to ensure that deferred errors from earlier 477c478bd9Sstevel@tonic-gate * accesses will not be reported after the membar. This error 487c478bd9Sstevel@tonic-gate * isolation is important when we try to recover from async 497c478bd9Sstevel@tonic-gate * errors which tries to distinguish kernel accesses to user 507c478bd9Sstevel@tonic-gate * data. 517c478bd9Sstevel@tonic-gate */ 527c478bd9Sstevel@tonic-gate 537c478bd9Sstevel@tonic-gate/* 547c478bd9Sstevel@tonic-gate * Zero a block of storage. 557c478bd9Sstevel@tonic-gate * 567c478bd9Sstevel@tonic-gate * uzero is used by the kernel to zero a block in user address space. 577c478bd9Sstevel@tonic-gate */ 587c478bd9Sstevel@tonic-gate 597c478bd9Sstevel@tonic-gate ENTRY(uzero) 607c478bd9Sstevel@tonic-gate ! 617c478bd9Sstevel@tonic-gate ! Set a new lo_fault handler only if we came in with one 627c478bd9Sstevel@tonic-gate ! already specified. 637c478bd9Sstevel@tonic-gate ! 647c478bd9Sstevel@tonic-gate wr %g0, ASI_USER, %asi 657c478bd9Sstevel@tonic-gate ldn [THREAD_REG + T_LOFAULT], %o5 667c478bd9Sstevel@tonic-gate tst %o5 677c478bd9Sstevel@tonic-gate bz,pt %ncc, .do_zero 687c478bd9Sstevel@tonic-gate sethi %hi(.zeroerr), %o2 697c478bd9Sstevel@tonic-gate or %o2, %lo(.zeroerr), %o2 707c478bd9Sstevel@tonic-gate membar #Sync 717c478bd9Sstevel@tonic-gate ba,pt %ncc, .do_zero 727c478bd9Sstevel@tonic-gate stn %o2, [THREAD_REG + T_LOFAULT] 737c478bd9Sstevel@tonic-gate 747c478bd9Sstevel@tonic-gate ENTRY(kzero) 757c478bd9Sstevel@tonic-gate ! 767c478bd9Sstevel@tonic-gate ! Always set a lo_fault handler 777c478bd9Sstevel@tonic-gate ! 787c478bd9Sstevel@tonic-gate wr %g0, ASI_P, %asi 797c478bd9Sstevel@tonic-gate ldn [THREAD_REG + T_LOFAULT], %o5 807c478bd9Sstevel@tonic-gate sethi %hi(.zeroerr), %o2 817c478bd9Sstevel@tonic-gate or %o5, LOFAULT_SET, %o5 827c478bd9Sstevel@tonic-gate or %o2, %lo(.zeroerr), %o2 837c478bd9Sstevel@tonic-gate membar #Sync 847c478bd9Sstevel@tonic-gate ba,pt %ncc, .do_zero 857c478bd9Sstevel@tonic-gate stn %o2, [THREAD_REG + T_LOFAULT] 867c478bd9Sstevel@tonic-gate 877c478bd9Sstevel@tonic-gate/* 887c478bd9Sstevel@tonic-gate * We got here because of a fault during kzero or if 897c478bd9Sstevel@tonic-gate * uzero or bzero was called with t_lofault non-zero. 907c478bd9Sstevel@tonic-gate * Otherwise we've already run screaming from the room. 917c478bd9Sstevel@tonic-gate * Errno value is in %g1. Note that we're here iff 927c478bd9Sstevel@tonic-gate * we did set t_lofault. 937c478bd9Sstevel@tonic-gate */ 947c478bd9Sstevel@tonic-gate.zeroerr: 957c478bd9Sstevel@tonic-gate ! 967c478bd9Sstevel@tonic-gate ! Undo asi register setting. Just set it to be the 977c478bd9Sstevel@tonic-gate ! kernel default without checking. 987c478bd9Sstevel@tonic-gate ! 997c478bd9Sstevel@tonic-gate wr %g0, ASI_P, %asi 1007c478bd9Sstevel@tonic-gate ! 1017c478bd9Sstevel@tonic-gate ! If saved t_lofault has FP_USED set, clear the %fprs register 1027c478bd9Sstevel@tonic-gate ! 1037c478bd9Sstevel@tonic-gate btst FP_USED, %o5 1047c478bd9Sstevel@tonic-gate bz,pt %ncc, 1f ! skip if not used 1057c478bd9Sstevel@tonic-gate nop 1067c478bd9Sstevel@tonic-gate membar #Sync 1077c478bd9Sstevel@tonic-gate wr %g0, %g0, %fprs ! clear fprs 1087c478bd9Sstevel@tonic-gate andn %o5, FP_USED, %o5 ! turn off flag bit 1097c478bd9Sstevel@tonic-gate ! 1107c478bd9Sstevel@tonic-gate ! We did set t_lofault. It may well have been zero coming in. 1117c478bd9Sstevel@tonic-gate ! 1127c478bd9Sstevel@tonic-gate1: 1137c478bd9Sstevel@tonic-gate tst %o5 1147c478bd9Sstevel@tonic-gate membar #Sync 115*55fea89dSDan Cross bne,pn %ncc, 3f 1167c478bd9Sstevel@tonic-gate andncc %o5, LOFAULT_SET, %o5 1177c478bd9Sstevel@tonic-gate2: 1187c478bd9Sstevel@tonic-gate ! 1197c478bd9Sstevel@tonic-gate ! Old handler was zero. Just return the error. 1207c478bd9Sstevel@tonic-gate ! 1217c478bd9Sstevel@tonic-gate retl ! return 1227c478bd9Sstevel@tonic-gate mov %g1, %o0 ! error code from %g1 1237c478bd9Sstevel@tonic-gate3: 1247c478bd9Sstevel@tonic-gate ! 1257c478bd9Sstevel@tonic-gate ! We're here because %o5 was non-zero. It was non-zero 1267c478bd9Sstevel@tonic-gate ! because either LOFAULT_SET was present, a previous fault 1277c478bd9Sstevel@tonic-gate ! handler was present or both. In all cases we need to reset 1287c478bd9Sstevel@tonic-gate ! T_LOFAULT to the value of %o5 after clearing LOFAULT_SET 1297c478bd9Sstevel@tonic-gate ! before we either simply return the error or we invoke the 1307c478bd9Sstevel@tonic-gate ! previously specified handler. 1317c478bd9Sstevel@tonic-gate ! 1327c478bd9Sstevel@tonic-gate be %ncc, 2b 1337c478bd9Sstevel@tonic-gate stn %o5, [THREAD_REG + T_LOFAULT] 1347c478bd9Sstevel@tonic-gate jmp %o5 ! goto real handler 1357c478bd9Sstevel@tonic-gate nop 1367c478bd9Sstevel@tonic-gate SET_SIZE(kzero) 1377c478bd9Sstevel@tonic-gate SET_SIZE(uzero) 1387c478bd9Sstevel@tonic-gate 1397c478bd9Sstevel@tonic-gate/* 1407c478bd9Sstevel@tonic-gate * Zero a block of storage. 1417c478bd9Sstevel@tonic-gate */ 1427c478bd9Sstevel@tonic-gate 1437c478bd9Sstevel@tonic-gate ENTRY(bzero) 1447c478bd9Sstevel@tonic-gate wr %g0, ASI_P, %asi 1457c478bd9Sstevel@tonic-gate 1467c478bd9Sstevel@tonic-gate ldn [THREAD_REG + T_LOFAULT], %o5 ! save old vector 1477c478bd9Sstevel@tonic-gate tst %o5 1487c478bd9Sstevel@tonic-gate bz,pt %ncc, .do_zero 1497c478bd9Sstevel@tonic-gate sethi %hi(.zeroerr), %o2 1507c478bd9Sstevel@tonic-gate or %o2, %lo(.zeroerr), %o2 1517c478bd9Sstevel@tonic-gate membar #Sync ! sync error barrier 1527c478bd9Sstevel@tonic-gate stn %o2, [THREAD_REG + T_LOFAULT] ! install new vector 1537c478bd9Sstevel@tonic-gate 1547c478bd9Sstevel@tonic-gate.do_zero: 1557c478bd9Sstevel@tonic-gate cmp %o1, 15 ! check for small counts 1567c478bd9Sstevel@tonic-gate blu,pn %ncc, .byteclr ! just clear bytes 1577c478bd9Sstevel@tonic-gate nop 1587c478bd9Sstevel@tonic-gate 1597c478bd9Sstevel@tonic-gate cmp %o1, 192 ! check for large counts 1607c478bd9Sstevel@tonic-gate blu %ncc, .bzero_small 1617c478bd9Sstevel@tonic-gate nop 1627c478bd9Sstevel@tonic-gate 1637c478bd9Sstevel@tonic-gate sethi %hi(use_hw_bzero), %o2 1647c478bd9Sstevel@tonic-gate ld [%o2 + %lo(use_hw_bzero)], %o2 1657c478bd9Sstevel@tonic-gate tst %o2 1667c478bd9Sstevel@tonic-gate bz %icc, .bzero_small 1677c478bd9Sstevel@tonic-gate nop 1687c478bd9Sstevel@tonic-gate 1697c478bd9Sstevel@tonic-gate rd %fprs, %o2 ! check for unused fp 1707c478bd9Sstevel@tonic-gate btst FPRS_FEF, %o2 1717c478bd9Sstevel@tonic-gate bnz %icc, .bzero_small 1727c478bd9Sstevel@tonic-gate nop 1737c478bd9Sstevel@tonic-gate 1747c478bd9Sstevel@tonic-gate ldn [THREAD_REG + T_LWP], %o2 1757c478bd9Sstevel@tonic-gate tst %o2 1767c478bd9Sstevel@tonic-gate bz,pn %ncc, .bzero_small 1777c478bd9Sstevel@tonic-gate nop 1787c478bd9Sstevel@tonic-gate 1797c478bd9Sstevel@tonic-gate ! Check for block alignment 1807c478bd9Sstevel@tonic-gate btst (64-1), %o0 1817c478bd9Sstevel@tonic-gate bz %icc, .bzl_block 1827c478bd9Sstevel@tonic-gate nop 1837c478bd9Sstevel@tonic-gate 1847c478bd9Sstevel@tonic-gate ! Check for double-word alignment 1857c478bd9Sstevel@tonic-gate btst (8-1), %o0 1867c478bd9Sstevel@tonic-gate bz %icc, .bzl_dword 1877c478bd9Sstevel@tonic-gate nop 1887c478bd9Sstevel@tonic-gate 1897c478bd9Sstevel@tonic-gate ! Check for word alignment 1907c478bd9Sstevel@tonic-gate btst (4-1), %o0 1917c478bd9Sstevel@tonic-gate bz %icc, .bzl_word 1927c478bd9Sstevel@tonic-gate nop 1937c478bd9Sstevel@tonic-gate 1947c478bd9Sstevel@tonic-gate ! Clear bytes until word aligned 1957c478bd9Sstevel@tonic-gate.bzl_byte: 1967c478bd9Sstevel@tonic-gate stba %g0, [%o0]%asi 1977c478bd9Sstevel@tonic-gate add %o0, 1, %o0 1987c478bd9Sstevel@tonic-gate btst (4-1), %o0 1997c478bd9Sstevel@tonic-gate bnz %icc, .bzl_byte 2007c478bd9Sstevel@tonic-gate sub %o1, 1, %o1 2017c478bd9Sstevel@tonic-gate 2027c478bd9Sstevel@tonic-gate ! Check for dword-aligned 2037c478bd9Sstevel@tonic-gate btst (8-1), %o0 2047c478bd9Sstevel@tonic-gate bz %icc, .bzl_dword 2057c478bd9Sstevel@tonic-gate nop 206*55fea89dSDan Cross 2077c478bd9Sstevel@tonic-gate ! Clear words until double-word aligned 2087c478bd9Sstevel@tonic-gate.bzl_word: 2097c478bd9Sstevel@tonic-gate sta %g0, [%o0]%asi 2107c478bd9Sstevel@tonic-gate add %o0, 4, %o0 2117c478bd9Sstevel@tonic-gate btst (8-1), %o0 2127c478bd9Sstevel@tonic-gate bnz %icc, .bzl_word 2137c478bd9Sstevel@tonic-gate sub %o1, 4, %o1 2147c478bd9Sstevel@tonic-gate 2157c478bd9Sstevel@tonic-gate.bzl_dword: 2167c478bd9Sstevel@tonic-gate ! Clear dwords until block aligned 2177c478bd9Sstevel@tonic-gate stxa %g0, [%o0]%asi 2187c478bd9Sstevel@tonic-gate add %o0, 8, %o0 2197c478bd9Sstevel@tonic-gate btst (64-1), %o0 2207c478bd9Sstevel@tonic-gate bnz %icc, .bzl_dword 2217c478bd9Sstevel@tonic-gate sub %o1, 8, %o1 2227c478bd9Sstevel@tonic-gate 2237c478bd9Sstevel@tonic-gate.bzl_block: 2247c478bd9Sstevel@tonic-gate membar #StoreStore|#StoreLoad|#LoadStore 2257c478bd9Sstevel@tonic-gate wr %g0, FPRS_FEF, %fprs 2267c478bd9Sstevel@tonic-gate 2277c478bd9Sstevel@tonic-gate ! Set the lower bit in the saved t_lofault to indicate 2287c478bd9Sstevel@tonic-gate ! that we need to clear the %fprs register on the way 2297c478bd9Sstevel@tonic-gate ! out 2307c478bd9Sstevel@tonic-gate or %o5, FP_USED, %o5 2317c478bd9Sstevel@tonic-gate 2327c478bd9Sstevel@tonic-gate ! Clear block 2337c478bd9Sstevel@tonic-gate fzero %d0 2347c478bd9Sstevel@tonic-gate fzero %d2 2357c478bd9Sstevel@tonic-gate fzero %d4 2367c478bd9Sstevel@tonic-gate fzero %d6 2377c478bd9Sstevel@tonic-gate fzero %d8 2387c478bd9Sstevel@tonic-gate fzero %d10 2397c478bd9Sstevel@tonic-gate fzero %d12 2407c478bd9Sstevel@tonic-gate fzero %d14 2417c478bd9Sstevel@tonic-gate rd %asi, %o3 2427c478bd9Sstevel@tonic-gate wr %g0, ASI_BLK_P, %asi 2437c478bd9Sstevel@tonic-gate cmp %o3, ASI_P 2447c478bd9Sstevel@tonic-gate bne,a %icc, 1f 2457c478bd9Sstevel@tonic-gate wr %g0, ASI_BLK_AIUS, %asi 246*55fea89dSDan Cross1: 2477c478bd9Sstevel@tonic-gate mov 256, %o3 2487c478bd9Sstevel@tonic-gate ba,pt %ncc, .bzl_doblock 2497c478bd9Sstevel@tonic-gate nop 2507c478bd9Sstevel@tonic-gate 251*55fea89dSDan Cross.bzl_blkstart: 2527c478bd9Sstevel@tonic-gate ! stda %d0, [%o0+192]%asi ! in dly slot of branch that got us here 2537c478bd9Sstevel@tonic-gate stda %d0, [%o0+128]%asi 2547c478bd9Sstevel@tonic-gate stda %d0, [%o0+64]%asi 2557c478bd9Sstevel@tonic-gate stda %d0, [%o0]%asi 2567c478bd9Sstevel@tonic-gate.bzl_zinst: 2577c478bd9Sstevel@tonic-gate add %o0, %o3, %o0 2587c478bd9Sstevel@tonic-gate sub %o1, %o3, %o1 2597c478bd9Sstevel@tonic-gate.bzl_doblock: 2607c478bd9Sstevel@tonic-gate cmp %o1, 256 2617c478bd9Sstevel@tonic-gate bgeu,a %ncc, .bzl_blkstart 2627c478bd9Sstevel@tonic-gate stda %d0, [%o0+192]%asi 2637c478bd9Sstevel@tonic-gate 2647c478bd9Sstevel@tonic-gate cmp %o1, 64 2657c478bd9Sstevel@tonic-gate blu %ncc, .bzl_finish 266*55fea89dSDan Cross 2677c478bd9Sstevel@tonic-gate andn %o1, (64-1), %o3 2687c478bd9Sstevel@tonic-gate srl %o3, 4, %o2 ! using blocks, 1 instr / 16 words 2697c478bd9Sstevel@tonic-gate set .bzl_zinst, %o4 2707c478bd9Sstevel@tonic-gate sub %o4, %o2, %o4 2717c478bd9Sstevel@tonic-gate jmp %o4 2727c478bd9Sstevel@tonic-gate nop 2737c478bd9Sstevel@tonic-gate 2747c478bd9Sstevel@tonic-gate.bzl_finish: 2757c478bd9Sstevel@tonic-gate membar #StoreLoad|#StoreStore 2767c478bd9Sstevel@tonic-gate wr %g0, %g0, %fprs 2777c478bd9Sstevel@tonic-gate andn %o5, FP_USED, %o5 2787c478bd9Sstevel@tonic-gate 2797c478bd9Sstevel@tonic-gate rd %asi, %o4 2807c478bd9Sstevel@tonic-gate wr %g0, ASI_P, %asi 2817c478bd9Sstevel@tonic-gate cmp %o4, ASI_BLK_P 2827c478bd9Sstevel@tonic-gate bne,a %icc, 1f 2837c478bd9Sstevel@tonic-gate wr %g0, ASI_USER, %asi 2847c478bd9Sstevel@tonic-gate1: 2857c478bd9Sstevel@tonic-gate 2867c478bd9Sstevel@tonic-gate.bzlf_dword: 2877c478bd9Sstevel@tonic-gate ! double words 2887c478bd9Sstevel@tonic-gate cmp %o1, 8 2897c478bd9Sstevel@tonic-gate blu %ncc, .bzlf_word 2907c478bd9Sstevel@tonic-gate nop 2917c478bd9Sstevel@tonic-gate stxa %g0, [%o0]%asi 2927c478bd9Sstevel@tonic-gate add %o0, 8, %o0 2937c478bd9Sstevel@tonic-gate sub %o1, 8, %o1 2947c478bd9Sstevel@tonic-gate ba,pt %ncc, .bzlf_dword 2957c478bd9Sstevel@tonic-gate nop 2967c478bd9Sstevel@tonic-gate 2977c478bd9Sstevel@tonic-gate.bzlf_word: 2987c478bd9Sstevel@tonic-gate ! words 2997c478bd9Sstevel@tonic-gate cmp %o1, 4 3007c478bd9Sstevel@tonic-gate blu %ncc, .bzlf_byte 3017c478bd9Sstevel@tonic-gate nop 3027c478bd9Sstevel@tonic-gate sta %g0, [%o0]%asi 3037c478bd9Sstevel@tonic-gate add %o0, 4, %o0 3047c478bd9Sstevel@tonic-gate sub %o1, 4, %o1 3057c478bd9Sstevel@tonic-gate ba,pt %ncc, .bzlf_word 3067c478bd9Sstevel@tonic-gate nop 3077c478bd9Sstevel@tonic-gate 3087c478bd9Sstevel@tonic-gate1: 3097c478bd9Sstevel@tonic-gate add %o0, 1, %o0 ! increment address 3107c478bd9Sstevel@tonic-gate.bzlf_byte: 3117c478bd9Sstevel@tonic-gate subcc %o1, 1, %o1 ! decrement count 3127c478bd9Sstevel@tonic-gate bgeu,a %ncc, 1b 3137c478bd9Sstevel@tonic-gate stba %g0, [%o0]%asi ! zero a byte 3147c478bd9Sstevel@tonic-gate 3157c478bd9Sstevel@tonic-gate ! 3167c478bd9Sstevel@tonic-gate ! If we used the FP registers, that bit was turned 3177c478bd9Sstevel@tonic-gate ! off after we were finished. We're just concerned with 3187c478bd9Sstevel@tonic-gate ! whether t_lofault was set when we came in. We end up 3197c478bd9Sstevel@tonic-gate ! here from either kzero() or bzero(). kzero() *always* 320*55fea89dSDan Cross ! sets a lofault handler. It ors LOFAULT_SET into %o5 3217c478bd9Sstevel@tonic-gate ! to indicate it has done this even if the value of %o5 3227c478bd9Sstevel@tonic-gate ! is otherwise zero. bzero() sets a lofault handler *only* 3237c478bd9Sstevel@tonic-gate ! if one was previously set. Accordingly we need to examine 3247c478bd9Sstevel@tonic-gate ! %o5 and if it is non-zero be sure to clear LOFAULT_SET 3257c478bd9Sstevel@tonic-gate ! before resetting the error handler. 3267c478bd9Sstevel@tonic-gate ! 3277c478bd9Sstevel@tonic-gate tst %o5 328*55fea89dSDan Cross bz,pt %ncc, 1f 3297c478bd9Sstevel@tonic-gate andn %o5, LOFAULT_SET, %o5 3307c478bd9Sstevel@tonic-gate membar #Sync ! sync error barrier 3317c478bd9Sstevel@tonic-gate stn %o5, [THREAD_REG + T_LOFAULT] ! restore old t_lofault 3327c478bd9Sstevel@tonic-gate1: 3337c478bd9Sstevel@tonic-gate retl 3347c478bd9Sstevel@tonic-gate clr %o0 ! return (0) 3357c478bd9Sstevel@tonic-gate 3367c478bd9Sstevel@tonic-gate.bzero_small: 3377c478bd9Sstevel@tonic-gate 3387c478bd9Sstevel@tonic-gate ! 3397c478bd9Sstevel@tonic-gate ! Check for word alignment. 3407c478bd9Sstevel@tonic-gate ! 3417c478bd9Sstevel@tonic-gate btst 3, %o0 3427c478bd9Sstevel@tonic-gate bz .bzero_probe 3437c478bd9Sstevel@tonic-gate mov 0x100, %o3 ! constant size of main loop 3447c478bd9Sstevel@tonic-gate ! 3457c478bd9Sstevel@tonic-gate ! 3467c478bd9Sstevel@tonic-gate ! clear bytes until word aligned 3477c478bd9Sstevel@tonic-gate ! 3487c478bd9Sstevel@tonic-gate1: stba %g0,[%o0]%asi 3497c478bd9Sstevel@tonic-gate add %o0, 1, %o0 3507c478bd9Sstevel@tonic-gate btst 3, %o0 3517c478bd9Sstevel@tonic-gate bnz 1b 3527c478bd9Sstevel@tonic-gate sub %o1, 1, %o1 3537c478bd9Sstevel@tonic-gate.bzero_probe: 3547c478bd9Sstevel@tonic-gate 3557c478bd9Sstevel@tonic-gate ! 3567c478bd9Sstevel@tonic-gate ! if needed move a word to become double-word aligned. 3577c478bd9Sstevel@tonic-gate ! 3587c478bd9Sstevel@tonic-gate btst 7, %o0 ! is double aligned? 3597c478bd9Sstevel@tonic-gate bz %icc, .bzero_nobuf 3607c478bd9Sstevel@tonic-gate nop 3617c478bd9Sstevel@tonic-gate sta %g0, [%o0]%asi ! clr to double boundry 3627c478bd9Sstevel@tonic-gate sub %o1, 4, %o1 3637c478bd9Sstevel@tonic-gate ba,pt %ncc, .bzero_nobuf 3647c478bd9Sstevel@tonic-gate add %o0, 4, %o0 3657c478bd9Sstevel@tonic-gate 3667c478bd9Sstevel@tonic-gate !stxa %g0, [%o0+0xf8]%asi 3677c478bd9Sstevel@tonic-gate.bzero_blk: 3687c478bd9Sstevel@tonic-gate stxa %g0, [%o0+0xf0]%asi 3697c478bd9Sstevel@tonic-gate stxa %g0, [%o0+0xe8]%asi 3707c478bd9Sstevel@tonic-gate stxa %g0, [%o0+0xe0]%asi 3717c478bd9Sstevel@tonic-gate stxa %g0, [%o0+0xd8]%asi 3727c478bd9Sstevel@tonic-gate stxa %g0, [%o0+0xd0]%asi 3737c478bd9Sstevel@tonic-gate stxa %g0, [%o0+0xc8]%asi 3747c478bd9Sstevel@tonic-gate stxa %g0, [%o0+0xc0]%asi 3757c478bd9Sstevel@tonic-gate stxa %g0, [%o0+0xb8]%asi 3767c478bd9Sstevel@tonic-gate stxa %g0, [%o0+0xb0]%asi 3777c478bd9Sstevel@tonic-gate stxa %g0, [%o0+0xa8]%asi 3787c478bd9Sstevel@tonic-gate stxa %g0, [%o0+0xa0]%asi 3797c478bd9Sstevel@tonic-gate stxa %g0, [%o0+0x98]%asi 3807c478bd9Sstevel@tonic-gate stxa %g0, [%o0+0x90]%asi 3817c478bd9Sstevel@tonic-gate stxa %g0, [%o0+0x88]%asi 3827c478bd9Sstevel@tonic-gate stxa %g0, [%o0+0x80]%asi 3837c478bd9Sstevel@tonic-gate stxa %g0, [%o0+0x78]%asi 3847c478bd9Sstevel@tonic-gate stxa %g0, [%o0+0x70]%asi 3857c478bd9Sstevel@tonic-gate stxa %g0, [%o0+0x68]%asi 3867c478bd9Sstevel@tonic-gate stxa %g0, [%o0+0x60]%asi 3877c478bd9Sstevel@tonic-gate stxa %g0, [%o0+0x58]%asi 3887c478bd9Sstevel@tonic-gate stxa %g0, [%o0+0x50]%asi 3897c478bd9Sstevel@tonic-gate stxa %g0, [%o0+0x48]%asi 3907c478bd9Sstevel@tonic-gate stxa %g0, [%o0+0x40]%asi 3917c478bd9Sstevel@tonic-gate stxa %g0, [%o0+0x38]%asi 3927c478bd9Sstevel@tonic-gate stxa %g0, [%o0+0x30]%asi 3937c478bd9Sstevel@tonic-gate stxa %g0, [%o0+0x28]%asi 3947c478bd9Sstevel@tonic-gate stxa %g0, [%o0+0x20]%asi 3957c478bd9Sstevel@tonic-gate stxa %g0, [%o0+0x18]%asi 3967c478bd9Sstevel@tonic-gate stxa %g0, [%o0+0x10]%asi 3977c478bd9Sstevel@tonic-gate stxa %g0, [%o0+0x08]%asi 3987c478bd9Sstevel@tonic-gate stxa %g0, [%o0]%asi 3997c478bd9Sstevel@tonic-gate.zinst: 4007c478bd9Sstevel@tonic-gate add %o0, %o3, %o0 ! increment source address 4017c478bd9Sstevel@tonic-gate sub %o1, %o3, %o1 ! decrement count 4027c478bd9Sstevel@tonic-gate.bzero_nobuf: 4037c478bd9Sstevel@tonic-gate cmp %o1, 0x100 ! can we do whole chunk? 4047c478bd9Sstevel@tonic-gate bgeu,a %ncc, .bzero_blk 4057c478bd9Sstevel@tonic-gate stxa %g0, [%o0+0xf8]%asi ! do first double of chunk 4067c478bd9Sstevel@tonic-gate 4077c478bd9Sstevel@tonic-gate cmp %o1, 7 ! can we zero any more double words 4087c478bd9Sstevel@tonic-gate bleu %ncc, .byteclr ! too small go zero bytes 4097c478bd9Sstevel@tonic-gate 4107c478bd9Sstevel@tonic-gate andn %o1, 7, %o3 ! %o3 bytes left, double-word aligned 4117c478bd9Sstevel@tonic-gate srl %o3, 1, %o2 ! using doubles, need 1 instr / 2 words 4127c478bd9Sstevel@tonic-gate set .zinst, %o4 ! address of clr instructions 4137c478bd9Sstevel@tonic-gate sub %o4, %o2, %o4 ! jmp address relative to instr 4147c478bd9Sstevel@tonic-gate jmp %o4 4157c478bd9Sstevel@tonic-gate nop 4167c478bd9Sstevel@tonic-gate ! 4177c478bd9Sstevel@tonic-gate ! do leftover bytes 4187c478bd9Sstevel@tonic-gate ! 4197c478bd9Sstevel@tonic-gate3: 4207c478bd9Sstevel@tonic-gate add %o0, 1, %o0 ! increment address 4217c478bd9Sstevel@tonic-gate.byteclr: 4227c478bd9Sstevel@tonic-gate subcc %o1, 1, %o1 ! decrement count 4237c478bd9Sstevel@tonic-gate bgeu,a %ncc, 3b 4247c478bd9Sstevel@tonic-gate stba %g0, [%o0]%asi ! zero a byte 4257c478bd9Sstevel@tonic-gate 4267c478bd9Sstevel@tonic-gate.bzero_finished: 4277c478bd9Sstevel@tonic-gate ! 4287c478bd9Sstevel@tonic-gate ! We're just concerned with whether t_lofault was set 4297c478bd9Sstevel@tonic-gate ! when we came in. We end up here from either kzero() 4307c478bd9Sstevel@tonic-gate ! or bzero(). kzero() *always* sets a lofault handler. 4317c478bd9Sstevel@tonic-gate ! It ors LOFAULT_SET into %o5 to indicate it has done 4327c478bd9Sstevel@tonic-gate ! this even if the value of %o5 is otherwise zero. 4337c478bd9Sstevel@tonic-gate ! bzero() sets a lofault handler *only* if one was 4347c478bd9Sstevel@tonic-gate ! previously set. Accordingly we need to examine 4357c478bd9Sstevel@tonic-gate ! %o5 and if it is non-zero be sure to clear LOFAULT_SET 4367c478bd9Sstevel@tonic-gate ! before resetting the error handler. 4377c478bd9Sstevel@tonic-gate ! 4387c478bd9Sstevel@tonic-gate tst %o5 4397c478bd9Sstevel@tonic-gate bz %ncc, 1f 4407c478bd9Sstevel@tonic-gate andn %o5, LOFAULT_SET, %o5 4417c478bd9Sstevel@tonic-gate membar #Sync ! sync error barrier 4427c478bd9Sstevel@tonic-gate stn %o5, [THREAD_REG + T_LOFAULT] ! restore old t_lofault 4437c478bd9Sstevel@tonic-gate1: 4447c478bd9Sstevel@tonic-gate retl 4457c478bd9Sstevel@tonic-gate clr %o0 ! return (0) 4467c478bd9Sstevel@tonic-gate 4477c478bd9Sstevel@tonic-gate SET_SIZE(bzero) 448