xref: /onnv-gate/usr/src/cmd/fps/fptest/cheetah_sdc.c (revision 7186:e728311aafb0)
16429Svs195195 /*
26429Svs195195  * CDDL HEADER START
36429Svs195195  *
46429Svs195195  * The contents of this file are subject to the terms of the
56429Svs195195  * Common Development and Distribution License (the "License").
66429Svs195195  * You may not use this file except in compliance with the License.
76429Svs195195  *
86429Svs195195  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
96429Svs195195  * or http://www.opensolaris.org/os/licensing.
106429Svs195195  * See the License for the specific language governing permissions
116429Svs195195  * and limitations under the License.
126429Svs195195  *
136429Svs195195  * When distributing Covered Code, include this CDDL HEADER in each
146429Svs195195  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
156429Svs195195  * If applicable, add the following below this CDDL HEADER, with the
166429Svs195195  * fields enclosed by brackets "[]" replaced with your own identifying
176429Svs195195  * information: Portions Copyright [yyyy] [name of copyright owner]
186429Svs195195  *
196429Svs195195  * CDDL HEADER END
206429Svs195195  */
216429Svs195195 
226429Svs195195 /*
236491Sia112686  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
246429Svs195195  * Use is subject to license terms.
256429Svs195195  */
266429Svs195195 
276429Svs195195 #pragma ident	"%Z%%M%	%I%	%E% SMI"
286429Svs195195 
296429Svs195195 #include <stdio.h>
306429Svs195195 #include <unistd.h>
316429Svs195195 #include <fps_ereport.h>
326429Svs195195 
336429Svs195195 extern void	iflush(void);
346429Svs195195 extern int	g1(unsigned long, unsigned long *, unsigned long *);
356429Svs195195 extern int	g2(unsigned long, unsigned long *, unsigned long *);
366429Svs195195 extern int	g3(unsigned long, unsigned long *, unsigned long *);
376429Svs195195 extern int	g4(unsigned long, unsigned long *, unsigned long *);
386429Svs195195 extern int	l0(unsigned long, unsigned long *, unsigned long *);
396429Svs195195 extern int	l1(unsigned long, unsigned long *, unsigned long *);
406429Svs195195 extern int	l2(unsigned long, unsigned long *, unsigned long *);
416429Svs195195 extern int	l3(unsigned long, unsigned long *, unsigned long *);
426429Svs195195 extern int	l4(unsigned long, unsigned long *, unsigned long *);
436429Svs195195 extern int	l5(unsigned long, unsigned long *, unsigned long *);
446429Svs195195 extern int	l6(unsigned long, unsigned long *, unsigned long *);
456429Svs195195 extern int	l7(unsigned long, unsigned long *, unsigned long *);
466429Svs195195 extern int	o0(unsigned long, unsigned long *, unsigned long *);
476429Svs195195 extern int	o1(unsigned long, unsigned long *, unsigned long *);
486429Svs195195 extern int	o2(unsigned long, unsigned long *, unsigned long *);
496429Svs195195 extern int	o3(unsigned long, unsigned long *, unsigned long *);
506429Svs195195 extern int	o4(unsigned long, unsigned long *, unsigned long *);
516429Svs195195 extern int	o5(unsigned long, unsigned long *, unsigned long *);
526429Svs195195 extern int	o7(unsigned long, unsigned long *, unsigned long *);
536429Svs195195 
546429Svs195195 typedef struct {
556429Svs195195 	char	*reg;
566429Svs195195 	int	(*test_func) (unsigned long, unsigned long *,\
576429Svs195195 		unsigned long *);
586429Svs195195 }reg_info;
596429Svs195195 
606429Svs195195 /* Registers to be tested and the functions to be used for it. */
616429Svs195195 static
626429Svs195195 reg_info	reg_func[] =
636429Svs195195 {
646429Svs195195 	{"g1", g1},
656429Svs195195 	{"g2", g2},
666429Svs195195 	{"g3", g3},
676429Svs195195 	{"g4", g4},
686429Svs195195 	{"l0", l0},
696429Svs195195 	{"l1", l1},
706429Svs195195 	{"l2", l2},
716429Svs195195 	{"l3", l3},
726429Svs195195 	{"l4", l4},
736429Svs195195 	{"l5", l5},
746429Svs195195 	{"l6", l6},
756429Svs195195 	{"l7", l7},
766429Svs195195 	{"o0", o0},
776429Svs195195 	{"o1", o1},
786429Svs195195 	{"o2", o2},
796429Svs195195 	{"o3", o3},
806429Svs195195 	{"o4", o4},
816429Svs195195 	{"o5", o5},
826429Svs195195 	/* %o6 is not tested as it is the %sp */
836429Svs195195 	{"o7", o7}
846429Svs195195 };
856429Svs195195 
866429Svs195195 #define	N_REGS (sizeof (reg_func)/sizeof (*reg_func))
876429Svs195195 
886429Svs195195 /*
896429Svs195195  * cheetah_sdc_test(int limit, int unit, struct fps_test_ereport *report)
906429Svs195195  * tests for silent data corruption first unearthed in a 750 Mhz Cheetah
916429Svs195195  * (Toshiba). Returns if successful or not. If an error, relevant data
926429Svs195195  * is stored in report. The test calls an assembly routine with
936429Svs195195  * different target registers but essentially the same code sequence
946429Svs195195  */
956429Svs195195 int
cheetah_sdc_test(int limit,struct fps_test_ereport * report)966429Svs195195 cheetah_sdc_test(int limit, struct fps_test_ereport *report)
976429Svs195195 {
986429Svs195195 	char err_data[MAX_INFO_SIZE];
996429Svs195195 	int iter;
1006429Svs195195 	int regs;
1016429Svs195195 	int rval;
1026429Svs195195 	uint64_t expect;
1036429Svs195195 	uint64_t observe;
1046429Svs195195 	unsigned long tmp1 = 0;
1056429Svs195195 	unsigned long tmp2 = 0;
1066429Svs195195 
1076429Svs195195 	unsigned long pattern = 0xDEADDEADDEADDEAD;
1086429Svs195195 
1096429Svs195195 	for (regs = 0; regs < N_REGS; regs++) {
1106429Svs195195 		for (iter = 0; iter < limit; iter++) {
1116429Svs195195 			iflush();
1126429Svs195195 			rval = reg_func[regs].test_func(pattern, &tmp1, &tmp2);
1136429Svs195195 
1146429Svs195195 			if (rval != 0) {
115*7186Skk158166 				(void) snprintf(err_data, sizeof (err_data),
1166429Svs195195 				    "Test:%d, reg:%s", iter,
1176429Svs195195 				    reg_func[regs].reg);
1186429Svs195195 				expect = (uint64_t)0;
1196429Svs195195 				observe = (uint64_t)rval;
1206429Svs195195 				setup_fps_test_struct(IS_EREPORT_INFO,
1216429Svs195195 				    report,	6357, &observe,
1226429Svs195195 				    &expect, 1, 1, err_data);
1236429Svs195195 
1246429Svs195195 				return (-1);
1256429Svs195195 			}
1266429Svs195195 		}
1276429Svs195195 	}
1286429Svs195195 
1296429Svs195195 	return (0);
1306429Svs195195 }
131