1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 #include <stdio.h> 30 #include <stdlib.h> 31 #include <fp.h> 32 #include <fps_ereport.h> 33 34 #pragma align 64(datain1, datain2, dataout) 35 36 int cbbcopy(struct fps_test_ereport *report); 37 static void asi_bcopy_f0(uint32_t *out, uint32_t *in); 38 static void asi_bcopy_f16(uint32_t *out, uint32_t *in); 39 static void ax_bcopy(uint32_t *out, uint32_t *in); 40 41 static uint32_t dataout[64]; 42 43 static uint32_t datain1[64] = { 44 0x55555500, 0x55555501, 0xaaaaaa02, 0xaaaaaa03, 45 0x55555504, 0x55555505, 0xaaaaaa06, 0xaaaaaa07, 46 0x55555508, 0x55555509, 0xaaaaaa0a, 0xaaaaaa0b, 47 0x5555550c, 0x5555550d, 0xaaaaaa0e, 0xaaaaaa0f, 48 0x55555510, 0x55555511, 0xaaaaaa12, 0xaaaaaa13, 49 0x55555514, 0x55555515, 0xaaaaaa16, 0xaaaaaa17, 50 0x55555518, 0x55555519, 0xaaaaaa1a, 0xaaaaaa1b, 51 0x5555551c, 0x5555551d, 0xaaaaaa1e, 0xaaaaaa1f, 52 0x55555520, 0x55555521, 0xaaaaaa22, 0xaaaaaa23, 53 0x55555524, 0x55555525, 0xaaaaaa26, 0xaaaaaa27, 54 0x55555528, 0x55555529, 0xaaaaaa2a, 0xaaaaaa2b, 55 0x5555552c, 0x5555552d, 0xaaaaaa2e, 0xaaaaaa2f, 56 0x55555530, 0x55555531, 0xaaaaaa32, 0xaaaaaa33, 57 0x55555534, 0x55555535, 0xaaaaaa36, 0xaaaaaa37, 58 0x55555538, 0x55555539, 0xaaaaaa3a, 0xaaaaaa3b, 59 0x5555553c, 0x5555553d, 0xaaaaaa3e, 0xaaaaaa3f 60 }; 61 62 static uint32_t datain2[64] = { 63 0xaaaaaaff, 0xaaaaaafe, 0x555555fd, 0x555555fc, 64 0xaaaaaafb, 0xaaaaaafa, 0x555555f9, 0x555555f8, 65 0xaaaaaaf7, 0xaaaaaaf6, 0x555555f5, 0x555555f4, 66 0xaaaaaaf3, 0xaaaaaaf2, 0x555555f1, 0x555555f0, 67 0xaaaaaaef, 0xaaaaaaee, 0x555555ed, 0x555555ec, 68 0xaaaaaaeb, 0xaaaaaaea, 0x555555e9, 0x555555e8, 69 0xaaaaaae7, 0xaaaaaae6, 0x555555e5, 0x555555e4, 70 0xaaaaaae3, 0xaaaaaae2, 0x555555e1, 0x555555e0, 71 0xaaaaaadf, 0xaaaaaade, 0x555555dd, 0x555555dc, 72 0xaaaaaadb, 0xaaaaaada, 0x555555d9, 0x555555d8, 73 0xaaaaaad7, 0xaaaaaad6, 0x555555d5, 0x555555d4, 74 0xaaaaaad3, 0xaaaaaad2, 0x555555d1, 0x555555d0, 75 0xaaaaaacf, 0xaaaaaace, 0x555555cd, 0x555555cc, 76 0xaaaaaacb, 0xaaaaaaca, 0x555555c9, 0x555555c8, 77 0xaaaaaac7, 0xaaaaaac6, 0x555555c5, 0x555555c4, 78 0xaaaaaac3, 0xaaaaaac2, 0x555555c1, 0x555555c0 79 }; 80 81 /* 82 * cbbcopy(int unit, struct fps_test_ereport *report) 83 * exercises block load and store path thru floating point 84 * registers. Returns whether load/store was successful. 85 * If an error, all relevant data is stored in report. 86 * Purpose: FRF integraty check thru both block ld/st and P$ 87 * ax/ms pipe for health check online check utility. The utility is intented 88 * to detect simple stuck at fault not timing related faults. 89 */ 90 int 91 cbbcopy(struct fps_test_ereport *report) 92 { 93 int i; 94 uint64_t expect; 95 uint64_t observe; 96 97 ax_bcopy(dataout, datain1); 98 asi_bcopy_f0(dataout, dataout); 99 100 for (i = 0; i < 64; i++) { 101 if (dataout[i] != datain1[i]) { 102 expect = (uint64_t)datain1[i]; 103 observe = (uint64_t)dataout[i]; 104 setup_fps_test_struct(NO_EREPORT_INFO, report, 105 6337, &observe, &expect, 1, 1); 106 107 return (FPU_FOROFFLINE); 108 } 109 } 110 111 ax_bcopy(dataout, datain2); 112 asi_bcopy_f16(dataout, dataout); 113 114 for (i = 0; i < 64; i++) { 115 if (dataout[i] != datain2[i]) { 116 expect = (uint64_t)datain2[i]; 117 observe = (uint64_t)dataout[i]; 118 setup_fps_test_struct(NO_EREPORT_INFO, report, 119 6338, &observe, &expect, 1, 1); 120 121 return (FPU_FOROFFLINE); 122 } 123 } 124 125 return (FPU_OK); 126 } 127 128 /* 129 * asi_bcopy_f0(uint32_t *out, uint32_t *in) 130 * does the assembly load/store of in to out 131 */ 132 /* ARGSUSED */ 133 static void 134 asi_bcopy_f0(uint32_t *out, uint32_t *in) 135 { 136 asm("ldda [%i1]0xf8,%f0"); 137 asm("membar #Sync"); 138 asm("stda %f0,[%i0]0xf0"); 139 asm("membar #Sync"); 140 } 141 142 /* 143 * asi_bcopy_f16(uint32_t *out, uint32_t *in) 144 * does the assembly load/store of in to out 145 */ 146 /* ARGSUSED */ 147 static void 148 asi_bcopy_f16(uint32_t *out, uint32_t *in) 149 { 150 asm("ldda [%i1]0xf0,%f16"); 151 asm("membar #Sync"); 152 asm("stda %f16,[%i0]0xf8"); 153 asm("membar #Sync"); 154 } 155 156 /* 157 * ax_bcopy(uint32_t *out, uint32_t *in) 158 * does the assembly load/store of in to out 159 */ 160 /* ARGSUSED */ 161 static void 162 ax_bcopy(uint32_t *out, uint32_t *in) 163 { 164 asm("prefetch [%i1],21"); 165 asm("prefetch [%i1+0x40],21"); 166 asm("ldd [%i1],%f16"); 167 asm("ldd [%i1+8],%f18"); 168 asm("ldd [%i1+0x10],%f20"); 169 asm("ldd [%i1+0x18],%f22"); 170 asm("ldd [%i1+0x20],%f24"); 171 asm("ldd [%i1+0x28],%f26"); 172 asm("ldd [%i1+0x30],%f28"); 173 asm("ldd [%i1+0x38],%f30"); 174 asm("ldd [%i1+0x40],%f32"); 175 176 asm("prefetch [%i1+0x80],21"); 177 asm("ldd [%i1+0x48],%f34"); 178 asm("ldd [%i1+0x50],%f36"); 179 asm("ldd [%i1+0x58],%f38"); 180 asm("ldd [%i1+0x60],%f40"); 181 asm("ldd [%i1+0x68],%f42"); 182 asm("ldd [%i1+0x70],%f44"); 183 asm("ldd [%i1+0x78],%f46"); 184 185 asm("prefetch [%i1+0xc0],21"); 186 asm("ldd [%i1+0x80],%f0"); 187 asm("ldd [%i1+0x88],%f2"); 188 asm("ldd [%i1+0x90],%f4"); 189 asm("ldd [%i1+0x98],%f6"); 190 asm("ldd [%i1+0xa0],%f8"); 191 asm("ldd [%i1+0xa8],%f10"); 192 asm("ldd [%i1+0xb0],%f12"); 193 asm("ldd [%i1+0xb8],%f14"); 194 195 asm("ldd [%i1+0xc0],%f48"); 196 asm("ldd [%i1+0xc8],%f50"); 197 asm("ldd [%i1+0xd0],%f52"); 198 asm("ldd [%i1+0xd8],%f54"); 199 asm("ldd [%i1+0xe0],%f56"); 200 asm("ldd [%i1+0xe8],%f58"); 201 asm("ldd [%i1+0xf0],%f60"); 202 asm("ldd [%i1+0xf8],%f62"); 203 204 asm("membar #Sync"); 205 asm("stda %f16,[%i0]0xf8"); 206 asm("add %i0,0x40,%i0"); 207 asm("stda %f32,[%i0]0xf0"); 208 asm("add %i0,0x40,%i0"); 209 asm("stda %f0,[%i0]0xf0"); 210 asm("add %i0,0x40,%i0"); 211 asm("stda %f48,[%i0]0xf0"); 212 asm("membar #Sync"); 213 } 214