xref: /onnv-gate/usr/src/lib/cfgadm_plugins/ac/common/mema_test.c (revision 2305:7954d746a1b5)
1*2305Sstevel /*
2*2305Sstevel  * CDDL HEADER START
3*2305Sstevel  *
4*2305Sstevel  * The contents of this file are subject to the terms of the
5*2305Sstevel  * Common Development and Distribution License, Version 1.0 only
6*2305Sstevel  * (the "License").  You may not use this file except in compliance
7*2305Sstevel  * with the License.
8*2305Sstevel  *
9*2305Sstevel  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*2305Sstevel  * or http://www.opensolaris.org/os/licensing.
11*2305Sstevel  * See the License for the specific language governing permissions
12*2305Sstevel  * and limitations under the License.
13*2305Sstevel  *
14*2305Sstevel  * When distributing Covered Code, include this CDDL HEADER in each
15*2305Sstevel  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*2305Sstevel  * If applicable, add the following below this CDDL HEADER, with the
17*2305Sstevel  * fields enclosed by brackets "[]" replaced with your own identifying
18*2305Sstevel  * information: Portions Copyright [yyyy] [name of copyright owner]
19*2305Sstevel  *
20*2305Sstevel  * CDDL HEADER END
21*2305Sstevel  */
22*2305Sstevel /*
23*2305Sstevel  * Copyright (c) 1996-1998, 2001 by Sun Microsystems, Inc.
24*2305Sstevel  * All rights reserved.
25*2305Sstevel  */
26*2305Sstevel 
27*2305Sstevel #pragma ident	"%Z%%M%	%I%	%E% SMI"
28*2305Sstevel 
29*2305Sstevel #include <stddef.h>
30*2305Sstevel #include <stdio.h>
31*2305Sstevel #include <sys/param.h>
32*2305Sstevel #include <config_admin.h>
33*2305Sstevel #include <memory.h>
34*2305Sstevel #include <sys/types.h>
35*2305Sstevel #include <time.h>
36*2305Sstevel #include "mema_test.h"
37*2305Sstevel 
38*2305Sstevel typedef u_longlong_t pbuf_t;
39*2305Sstevel 
40*2305Sstevel /*
41*2305Sstevel  * Test for stuck-at fault and transitional faults
42*2305Sstevel  *   Algorithm:
43*2305Sstevel  *         for i = 0 to npages
44*2305Sstevel  *              write(0x55)
45*2305Sstevel  *         for npages to 0
46*2305Sstevel  *              read_compare(0x55)
47*2305Sstevel  *              write(0xaa)
48*2305Sstevel  *         for 0 to number of pages
49*2305Sstevel  *              read_compare(0xaa)
50*2305Sstevel  *              write(0x55)
51*2305Sstevel  *              read_compare(0x55)
52*2305Sstevel  *
53*2305Sstevel  * stuck-at fault is detected because each cell have a 1 and a 0 is read
54*2305Sstevel  * transitional fault is detected because after each 0 to 1 and 1 to 0
55*2305Sstevel  * transition the value is check to be sure that the cell is not frozen.
56*2305Sstevel  */
57*2305Sstevel 
58*2305Sstevel /*
59*2305Sstevel  * The following strings are subject of stderr output and
60*2305Sstevel  * gettext() is not used for them.
61*2305Sstevel  */
62*2305Sstevel static const char err_sum[] = "total error %u\n";
63*2305Sstevel static const char nts_msg[] = "Normal test started\n";
64*2305Sstevel static const char ntf_msg[] = "Normal test finished\n";
65*2305Sstevel static const char qts_msg[] = "Quick test started\n";
66*2305Sstevel static const char qtf_msg[] = "Quick test finished\n";
67*2305Sstevel static const char ets_msg[] = "Extended test started\n";
68*2305Sstevel static const char etf_msg[] = "Extended test finished\n";
69*2305Sstevel static const char m1_msg[] = "    March 1, ";
70*2305Sstevel static const char m2_msg[] = "    March 2, ";
71*2305Sstevel static const char m3_msg[] = "    March 3, ";
72*2305Sstevel static const char m4_msg[] = "    March 4, ";
73*2305Sstevel static const char wr_msg[] = "write. ";
74*2305Sstevel static const char rd_cmp_msg[] = "read/compare. ";
75*2305Sstevel static const char rpt_rd_cmp_msg[] = "repeated read/compare. ";
76*2305Sstevel static const char ml_rd_cmp_msg[] = "mixed line read/compare. ";
77*2305Sstevel static const char ln_rd_cmp_msg[] = "line read/compare. ";
78*2305Sstevel static const char report_msg[] = "%s%s%d%% complete.\n";
79*2305Sstevel static const char pg_header_msg[] = "    Errors at page address: 0x%x.\n";
80*2305Sstevel static const char rd_err_msg[] = "    Error reading page at address: 0x%x.\n";
81*2305Sstevel static const char wr_err_msg[] = "    Error writing page at address: 0x%x.\n";
82*2305Sstevel static const
83*2305Sstevel char mem_err_msg[] = "      Offset: 0x%x, data written/read: 0x%2x/0x%2x.\n";
84*2305Sstevel 
85*2305Sstevel /*
86*2305Sstevel  * Macros do deal with test conditions.
87*2305Sstevel  */
88*2305Sstevel #define	TEST_END(END_MSG) \
89*2305Sstevel 			if ((handle->max_errors != 0) &&\
90*2305Sstevel 				(handle->max_errors == total_errors)) {\
91*2305Sstevel 				mtest_message(handle, (END_MSG));\
92*2305Sstevel 				error_summary(handle, total_errors);\
93*2305Sstevel 				SET_CONDITION(handle, cond);\
94*2305Sstevel 				return (MTEST_DONE);\
95*2305Sstevel 			}
96*2305Sstevel 
97*2305Sstevel static void
error_summary(mtest_handle_t handle,uint_t total_errors)98*2305Sstevel error_summary(mtest_handle_t handle, uint_t total_errors)
99*2305Sstevel {
100*2305Sstevel 	char msgbuf[100];
101*2305Sstevel 
102*2305Sstevel 	(void) sprintf(msgbuf, err_sum, total_errors);
103*2305Sstevel 	mtest_message(handle, msgbuf);
104*2305Sstevel }
105*2305Sstevel 
106*2305Sstevel 
107*2305Sstevel static void
error_print(char * writebuf,char * readbuf,mtest_handle_t handle,long pageno,uint_t * total_errorsp)108*2305Sstevel error_print(char *writebuf, char *readbuf, mtest_handle_t handle, long pageno,
109*2305Sstevel 	uint_t *total_errorsp)
110*2305Sstevel {
111*2305Sstevel 	char msgbuf[100];
112*2305Sstevel 	size_t offset;
113*2305Sstevel 
114*2305Sstevel 	(void) sprintf(msgbuf, pg_header_msg, PAGE_SIZE(handle) * pageno);
115*2305Sstevel 	mtest_message(handle, msgbuf);
116*2305Sstevel 
117*2305Sstevel 	for (offset = 0; offset < PAGE_SIZE(handle); offset++) {
118*2305Sstevel 		if ((handle->max_errors != 0) &&
119*2305Sstevel 		    (readbuf[offset] != writebuf[offset]) &&
120*2305Sstevel 		    (handle->max_errors == *total_errorsp))
121*2305Sstevel 			return;
122*2305Sstevel 		else {
123*2305Sstevel 			(*total_errorsp)++;
124*2305Sstevel 			(void) sprintf(msgbuf, mem_err_msg, offset,
125*2305Sstevel 			    writebuf[offset], readbuf[offset]);
126*2305Sstevel 			mtest_message(handle, msgbuf);
127*2305Sstevel 		}
128*2305Sstevel 	}
129*2305Sstevel }
130*2305Sstevel 
131*2305Sstevel int
memory_test_normal(mtest_handle_t handle)132*2305Sstevel memory_test_normal(
133*2305Sstevel 	mtest_handle_t handle)
134*2305Sstevel {
135*2305Sstevel 	pbuf_t *patternbuf1;
136*2305Sstevel 	pbuf_t *patternbuf2;
137*2305Sstevel 	pbuf_t *readbuf;
138*2305Sstevel 	long npages, pageno;
139*2305Sstevel 	struct mtest_error errbuf;
140*2305Sstevel 	uint_t total_errors;
141*2305Sstevel 	cfga_cond_t cond;
142*2305Sstevel 	time_t time_rep;
143*2305Sstevel 	char msgbuf[100];
144*2305Sstevel 
145*2305Sstevel 	patternbuf1 = (pbuf_t *)mtest_allocate_page_buf(handle);
146*2305Sstevel 	patternbuf2 = (pbuf_t *)mtest_allocate_page_buf(handle);
147*2305Sstevel 	readbuf = (pbuf_t *)mtest_allocate_page_buf(handle);
148*2305Sstevel 	if (patternbuf1 == NULL || patternbuf2 == NULL || readbuf == NULL) {
149*2305Sstevel 		return (MTEST_LIB_ERROR);
150*2305Sstevel 	}
151*2305Sstevel 
152*2305Sstevel 	mtest_message(handle, nts_msg);
153*2305Sstevel 	npages = BANK_SIZE(handle) / PAGE_SIZE(handle);
154*2305Sstevel 
155*2305Sstevel 	total_errors = 0;
156*2305Sstevel 	cond = CFGA_COND_OK;
157*2305Sstevel 
158*2305Sstevel 	(void) memset((void *)patternbuf1, 0x55, PAGE_SIZE(handle));
159*2305Sstevel 	(void) memset((void *)patternbuf2, 0xaa, PAGE_SIZE(handle));
160*2305Sstevel 
161*2305Sstevel 	time_rep = time(NULL) + REPORT_SEC;
162*2305Sstevel 
163*2305Sstevel 	for (pageno = 0; pageno < npages; pageno++) {
164*2305Sstevel 		if (mtest_write(handle, (void *)patternbuf1, pageno, 0, 0)
165*2305Sstevel 		    == -1) {
166*2305Sstevel 			(void) sprintf(msgbuf, wr_err_msg, pageno);
167*2305Sstevel 			mtest_message(handle, msgbuf);
168*2305Sstevel 			return (MTEST_DEV_ERROR);
169*2305Sstevel 		}
170*2305Sstevel 		if ((time(NULL) >= time_rep) || (pageno == npages - 1) ||
171*2305Sstevel 		    (pageno == 0)) {
172*2305Sstevel 			(void) sprintf(msgbuf, report_msg, m1_msg, wr_msg,
173*2305Sstevel 			    ((pageno + 1) * 100) / npages);
174*2305Sstevel 			mtest_message(handle, msgbuf);
175*2305Sstevel 			time_rep = time(NULL) + REPORT_SEC;
176*2305Sstevel 		}
177*2305Sstevel 	}
178*2305Sstevel 	for (pageno = npages-1; pageno >= 0; pageno--) {
179*2305Sstevel 		if (mtest_read(handle, (void *)readbuf, pageno, 0, 0, &errbuf)
180*2305Sstevel 		    == -1) {
181*2305Sstevel 			(void) sprintf(msgbuf, rd_err_msg, pageno);
182*2305Sstevel 			mtest_message(handle, msgbuf);
183*2305Sstevel 			return (MTEST_DEV_ERROR);
184*2305Sstevel 		}
185*2305Sstevel 		if (errbuf.error_type != MTEST_ERR_NONE) {
186*2305Sstevel 			if (errbuf.error_type == MTEST_ERR_CE &&
187*2305Sstevel 			    cond != CFGA_COND_FAILED)
188*2305Sstevel 				cond = CFGA_COND_FAILING;
189*2305Sstevel 			else
190*2305Sstevel 				cond = CFGA_COND_FAILED;
191*2305Sstevel 			total_errors++;
192*2305Sstevel 			/*
193*2305Sstevel 			 * Keep going if max errors is 0 or limit not
194*2305Sstevel 			 * reached.
195*2305Sstevel 			 */
196*2305Sstevel 			TEST_END(ntf_msg);
197*2305Sstevel 		}
198*2305Sstevel 		if (memcmp((void *)patternbuf1, (void *)readbuf,
199*2305Sstevel 		    PAGE_SIZE(handle)) != 0) {
200*2305Sstevel 			cond = CFGA_COND_FAILED;
201*2305Sstevel 			error_print((void *)patternbuf1, (void *)readbuf,
202*2305Sstevel 			    handle, pageno, &total_errors);
203*2305Sstevel 			TEST_END(ntf_msg);
204*2305Sstevel 		}
205*2305Sstevel 		if (mtest_write(handle, (void *)patternbuf2, pageno, 0, 0)
206*2305Sstevel 		    == -1) {
207*2305Sstevel 			(void) sprintf(msgbuf, wr_err_msg, pageno);
208*2305Sstevel 			mtest_message(handle, msgbuf);
209*2305Sstevel 			return (MTEST_DEV_ERROR);
210*2305Sstevel 		}
211*2305Sstevel 		if ((time(NULL) >= time_rep) || (pageno == npages - 1) ||
212*2305Sstevel 		    (pageno == 0)) {
213*2305Sstevel 			(void) sprintf(msgbuf, report_msg, m1_msg, rd_cmp_msg,
214*2305Sstevel 			    ((npages - pageno) * 100) / npages);
215*2305Sstevel 			mtest_message(handle, msgbuf);
216*2305Sstevel 			time_rep = time(NULL) + REPORT_SEC;
217*2305Sstevel 		}
218*2305Sstevel 	}
219*2305Sstevel 	/* March 2 (repeated) */
220*2305Sstevel 	for (pageno = 0; pageno < npages; pageno++) {
221*2305Sstevel 		if (mtest_read(handle, (void *)readbuf, pageno, 0, 0, &errbuf)
222*2305Sstevel 		    == -1) {
223*2305Sstevel 			(void) sprintf(msgbuf, rd_err_msg, pageno);
224*2305Sstevel 			mtest_message(handle, msgbuf);
225*2305Sstevel 			return (MTEST_DEV_ERROR);
226*2305Sstevel 		}
227*2305Sstevel 		if (errbuf.error_type != MTEST_ERR_NONE) {
228*2305Sstevel 			if (errbuf.error_type == MTEST_ERR_CE &&
229*2305Sstevel 			    cond != CFGA_COND_FAILED)
230*2305Sstevel 				cond = CFGA_COND_FAILING;
231*2305Sstevel 			else
232*2305Sstevel 				cond = CFGA_COND_FAILED;
233*2305Sstevel 			total_errors++;
234*2305Sstevel 			TEST_END(ntf_msg);
235*2305Sstevel 		}
236*2305Sstevel 		if (memcmp((void *)patternbuf2, (void *)readbuf,
237*2305Sstevel 		    PAGE_SIZE(handle)) != 0) {
238*2305Sstevel 			cond = CFGA_COND_FAILED;
239*2305Sstevel 			error_print((void *)patternbuf2, (void *)readbuf,
240*2305Sstevel 			    handle, pageno, &total_errors);
241*2305Sstevel 			TEST_END(ntf_msg);
242*2305Sstevel 		}
243*2305Sstevel 		if (mtest_write(handle, (void *)patternbuf1, pageno, 0, 0)
244*2305Sstevel 		    == -1) {
245*2305Sstevel 			(void) sprintf(msgbuf, wr_err_msg, pageno);
246*2305Sstevel 			mtest_message(handle, msgbuf);
247*2305Sstevel 			return (MTEST_DEV_ERROR);
248*2305Sstevel 		}
249*2305Sstevel 		if (mtest_read(handle, (void *)readbuf, pageno, 0, 0, &errbuf)
250*2305Sstevel 		    == -1) {
251*2305Sstevel 			(void) sprintf(msgbuf, rd_err_msg, pageno);
252*2305Sstevel 			mtest_message(handle, msgbuf);
253*2305Sstevel 			return (MTEST_DEV_ERROR);
254*2305Sstevel 		}
255*2305Sstevel 		if (errbuf.error_type != MTEST_ERR_NONE) {
256*2305Sstevel 			if (errbuf.error_type == MTEST_ERR_CE &&
257*2305Sstevel 			    cond != CFGA_COND_FAILED)
258*2305Sstevel 				cond = CFGA_COND_FAILING;
259*2305Sstevel 			else
260*2305Sstevel 				cond = CFGA_COND_FAILED;
261*2305Sstevel 			total_errors++;
262*2305Sstevel 			TEST_END(ntf_msg);
263*2305Sstevel 		}
264*2305Sstevel 		if (memcmp((void *)patternbuf1, (void *)readbuf,
265*2305Sstevel 		    PAGE_SIZE(handle)) != 0) {
266*2305Sstevel 			cond = CFGA_COND_FAILED;
267*2305Sstevel 			error_print((void *)patternbuf1, (void *)readbuf,
268*2305Sstevel 			    handle, pageno, &total_errors);
269*2305Sstevel 			TEST_END(ntf_msg);
270*2305Sstevel 		}
271*2305Sstevel 		if ((time(NULL) >= time_rep) || (pageno == npages - 1) ||
272*2305Sstevel 		    (pageno == 0)) {
273*2305Sstevel 			(void) sprintf(msgbuf, report_msg, m2_msg,
274*2305Sstevel 			    rpt_rd_cmp_msg, ((pageno + 1) * 100) / npages);
275*2305Sstevel 			mtest_message(handle, msgbuf);
276*2305Sstevel 			time_rep = time(NULL) + REPORT_SEC;
277*2305Sstevel 		}
278*2305Sstevel 	}
279*2305Sstevel 	mtest_message(handle, ntf_msg);
280*2305Sstevel 	error_summary(handle, total_errors);
281*2305Sstevel 	SET_CONDITION(handle, cond);
282*2305Sstevel 	return (MTEST_DONE);
283*2305Sstevel }
284*2305Sstevel 
285*2305Sstevel /* this test look only for stuck-at fault */
286*2305Sstevel int
memory_test_quick(mtest_handle_t handle)287*2305Sstevel memory_test_quick(
288*2305Sstevel 	mtest_handle_t handle)
289*2305Sstevel {
290*2305Sstevel 	pbuf_t *patternbuf1;
291*2305Sstevel 	pbuf_t *patternbuf2;
292*2305Sstevel 	pbuf_t *readbuf;
293*2305Sstevel 	long npages, pageno;
294*2305Sstevel 	struct mtest_error errbuf;
295*2305Sstevel 	uint_t total_errors;
296*2305Sstevel 	cfga_cond_t cond;
297*2305Sstevel 	time_t time_rep;
298*2305Sstevel 	char msgbuf[100];
299*2305Sstevel 
300*2305Sstevel 	patternbuf1 = (pbuf_t *)mtest_allocate_page_buf(handle);
301*2305Sstevel 	patternbuf2 = (pbuf_t *)mtest_allocate_page_buf(handle);
302*2305Sstevel 	readbuf = (pbuf_t *)mtest_allocate_page_buf(handle);
303*2305Sstevel 	if (patternbuf1 == NULL || patternbuf2 == NULL || readbuf == NULL) {
304*2305Sstevel 		return (MTEST_LIB_ERROR);
305*2305Sstevel 	}
306*2305Sstevel 
307*2305Sstevel 	mtest_message(handle, qts_msg);
308*2305Sstevel 	npages = BANK_SIZE(handle) / PAGE_SIZE(handle);
309*2305Sstevel 
310*2305Sstevel 	total_errors = 0;
311*2305Sstevel 	cond = CFGA_COND_OK;
312*2305Sstevel 
313*2305Sstevel 	(void) memset((void *)patternbuf1, 0x55, PAGE_SIZE(handle));
314*2305Sstevel 	(void) memset((void *)patternbuf2, 0xaa, PAGE_SIZE(handle));
315*2305Sstevel 
316*2305Sstevel 	time_rep = time(NULL) + REPORT_SEC;
317*2305Sstevel 
318*2305Sstevel 	for (pageno = 0; pageno < npages; pageno++) {
319*2305Sstevel 		if (mtest_write(handle, (void *)patternbuf1, pageno, 0, 0)
320*2305Sstevel 		    == -1) {
321*2305Sstevel 			(void) sprintf(msgbuf, wr_err_msg, pageno);
322*2305Sstevel 			mtest_message(handle, msgbuf);
323*2305Sstevel 			return (MTEST_DEV_ERROR);
324*2305Sstevel 		}
325*2305Sstevel 		if ((time(NULL) >= time_rep) || (pageno == npages - 1) ||
326*2305Sstevel 		    (pageno == 0)) {
327*2305Sstevel 			(void) sprintf(msgbuf, report_msg, m1_msg, wr_msg,
328*2305Sstevel 			    ((pageno + 1) * 100) / npages);
329*2305Sstevel 			mtest_message(handle, msgbuf);
330*2305Sstevel 			time_rep = time(NULL) + REPORT_SEC;
331*2305Sstevel 		}
332*2305Sstevel 	}
333*2305Sstevel 
334*2305Sstevel 	for (pageno = npages-1; pageno >= 0; pageno--) {
335*2305Sstevel 		if (mtest_read(handle, (void *)readbuf, pageno, 0, 0, &errbuf)
336*2305Sstevel 		    == -1) {
337*2305Sstevel 			(void) sprintf(msgbuf, rd_err_msg, pageno);
338*2305Sstevel 			mtest_message(handle, msgbuf);
339*2305Sstevel 			return (MTEST_DEV_ERROR);
340*2305Sstevel 		}
341*2305Sstevel 		if (errbuf.error_type != MTEST_ERR_NONE) {
342*2305Sstevel 			if (errbuf.error_type == MTEST_ERR_CE &&
343*2305Sstevel 			    cond != CFGA_COND_FAILED)
344*2305Sstevel 				cond = CFGA_COND_FAILING;
345*2305Sstevel 			else
346*2305Sstevel 				cond = CFGA_COND_FAILED;
347*2305Sstevel 			total_errors++;
348*2305Sstevel 			/*
349*2305Sstevel 			 * Keep going if max errors is 0 or limit not
350*2305Sstevel 			 * reached.
351*2305Sstevel 			 */
352*2305Sstevel 			TEST_END(qtf_msg);
353*2305Sstevel 		}
354*2305Sstevel 		if (memcmp((void *)patternbuf1, (void *)readbuf,
355*2305Sstevel 		    PAGE_SIZE(handle)) != 0) {
356*2305Sstevel 			cond = CFGA_COND_FAILED;
357*2305Sstevel 			error_print((void *)patternbuf1, (void *)readbuf,
358*2305Sstevel 			    handle, pageno, &total_errors);
359*2305Sstevel 			TEST_END(qtf_msg);
360*2305Sstevel 		}
361*2305Sstevel 		if (mtest_write(handle, (void *)patternbuf2, pageno, 0, 0)
362*2305Sstevel 		    == -1) {
363*2305Sstevel 			(void) sprintf(msgbuf, wr_err_msg, pageno);
364*2305Sstevel 			mtest_message(handle, msgbuf);
365*2305Sstevel 			return (MTEST_DEV_ERROR);
366*2305Sstevel 		}
367*2305Sstevel 		if ((time(NULL) >= time_rep) || (pageno == npages - 1) ||
368*2305Sstevel 		    (pageno == 0)) {
369*2305Sstevel 			(void) sprintf(msgbuf, report_msg, m1_msg, rd_cmp_msg,
370*2305Sstevel 			    ((npages - pageno) * 100) / npages);
371*2305Sstevel 			mtest_message(handle, msgbuf);
372*2305Sstevel 			time_rep = time(NULL) + REPORT_SEC;
373*2305Sstevel 		}
374*2305Sstevel 	}
375*2305Sstevel 	/* March 2 */
376*2305Sstevel 	for (pageno = 0; pageno < npages; pageno++) {
377*2305Sstevel 		if (mtest_read(handle, (void *)readbuf, pageno, 0, 0, &errbuf)
378*2305Sstevel 		    == -1) {
379*2305Sstevel 			(void) sprintf(msgbuf, rd_err_msg, pageno);
380*2305Sstevel 			mtest_message(handle, msgbuf);
381*2305Sstevel 			return (MTEST_DEV_ERROR);
382*2305Sstevel 		}
383*2305Sstevel 		if (errbuf.error_type != MTEST_ERR_NONE) {
384*2305Sstevel 			if (errbuf.error_type == MTEST_ERR_CE &&
385*2305Sstevel 			    cond != CFGA_COND_FAILED)
386*2305Sstevel 				cond = CFGA_COND_FAILING;
387*2305Sstevel 			else
388*2305Sstevel 				cond = CFGA_COND_FAILED;
389*2305Sstevel 			total_errors++;
390*2305Sstevel 			TEST_END(qtf_msg);
391*2305Sstevel 		}
392*2305Sstevel 		if (memcmp((void *)patternbuf2, (void *)readbuf,
393*2305Sstevel 		    PAGE_SIZE(handle)) != 0) {
394*2305Sstevel 			cond = CFGA_COND_FAILED;
395*2305Sstevel 			error_print((void *)patternbuf2, (void *)readbuf,
396*2305Sstevel 			    handle, pageno, &total_errors);
397*2305Sstevel 			TEST_END(qtf_msg);
398*2305Sstevel 		}
399*2305Sstevel 		if ((time(NULL) >= time_rep) || (pageno == npages - 1) ||
400*2305Sstevel 		    (pageno == 0)) {
401*2305Sstevel 			(void) sprintf(msgbuf, report_msg, m2_msg, rd_cmp_msg,
402*2305Sstevel 			    ((pageno + 1) * 100) / npages);
403*2305Sstevel 			mtest_message(handle, msgbuf);
404*2305Sstevel 			time_rep = time(NULL) + REPORT_SEC;
405*2305Sstevel 		}
406*2305Sstevel 	}
407*2305Sstevel 	mtest_message(handle, qtf_msg);
408*2305Sstevel 	error_summary(handle, total_errors);
409*2305Sstevel 	SET_CONDITION(handle, cond);
410*2305Sstevel 	return (MTEST_DONE);
411*2305Sstevel }
412*2305Sstevel 
413*2305Sstevel 
414*2305Sstevel /* look for stuck-at, transition, coupling fault: inversion, idempotent */
415*2305Sstevel int
memory_test_extended(mtest_handle_t handle)416*2305Sstevel memory_test_extended(
417*2305Sstevel 	mtest_handle_t handle)
418*2305Sstevel {
419*2305Sstevel 	pbuf_t *patternbuf0, *patternbuf1;
420*2305Sstevel 	pbuf_t *readbuf0, *readbuf1, *readbuf2;
421*2305Sstevel 	long npages, pageno;
422*2305Sstevel 	long line;
423*2305Sstevel 	struct mtest_error errbuf;
424*2305Sstevel 	uint_t total_errors;
425*2305Sstevel 	cfga_cond_t cond;
426*2305Sstevel 	time_t time_rep;
427*2305Sstevel 	char msgbuf[100];
428*2305Sstevel 
429*2305Sstevel 	patternbuf0 = (pbuf_t *)mtest_allocate_page_buf(handle);
430*2305Sstevel 	patternbuf1 = (pbuf_t *)mtest_allocate_page_buf(handle);
431*2305Sstevel 	readbuf0 = (pbuf_t *)mtest_allocate_page_buf(handle);
432*2305Sstevel 	readbuf1 = (pbuf_t *)mtest_allocate_page_buf(handle);
433*2305Sstevel 	readbuf2 = (pbuf_t *)mtest_allocate_page_buf(handle);
434*2305Sstevel 	if (patternbuf0 == NULL || patternbuf1 == NULL ||
435*2305Sstevel 	    readbuf0 == NULL || readbuf1 == NULL || readbuf2 == NULL) {
436*2305Sstevel 		return (MTEST_LIB_ERROR);
437*2305Sstevel 	}
438*2305Sstevel 
439*2305Sstevel 	mtest_message(handle, ets_msg);
440*2305Sstevel 	npages = BANK_SIZE(handle) / PAGE_SIZE(handle);
441*2305Sstevel 
442*2305Sstevel 	total_errors = 0;
443*2305Sstevel 	cond = CFGA_COND_OK;
444*2305Sstevel 
445*2305Sstevel 	(void) memset((void *)patternbuf0, 0x55, PAGE_SIZE(handle));
446*2305Sstevel 	(void) memset((void *)patternbuf1, 0xaa, PAGE_SIZE(handle));
447*2305Sstevel 
448*2305Sstevel 	time_rep = time(NULL) + REPORT_SEC;
449*2305Sstevel 
450*2305Sstevel 	for (pageno = 0; pageno < npages; pageno++) {
451*2305Sstevel 		if (mtest_write(handle, (void *)patternbuf0, pageno, 0, 0)
452*2305Sstevel 		    == -1) {
453*2305Sstevel 			(void) sprintf(msgbuf, wr_err_msg, pageno);
454*2305Sstevel 			mtest_message(handle, msgbuf);
455*2305Sstevel 			return (MTEST_DEV_ERROR);
456*2305Sstevel 		}
457*2305Sstevel 		if ((time(NULL) >= time_rep) || (pageno == npages - 1) ||
458*2305Sstevel 		    (pageno == 0)) {
459*2305Sstevel 			(void) sprintf(msgbuf, report_msg, m1_msg, wr_msg,
460*2305Sstevel 			    ((pageno + 1) * 100) / npages);
461*2305Sstevel 			mtest_message(handle, msgbuf);
462*2305Sstevel 			time_rep = time(NULL) + REPORT_SEC;
463*2305Sstevel 		}
464*2305Sstevel 	}
465*2305Sstevel 
466*2305Sstevel 	/*
467*2305Sstevel 	 * Line tests take 5-9 time longer and the reprting interval
468*2305Sstevel 	 * should be extended 3-5 times.
469*2305Sstevel 	 */
470*2305Sstevel 
471*2305Sstevel 	/* March 1 */
472*2305Sstevel 	for (pageno = npages-1; pageno >= 0; pageno--) {
473*2305Sstevel 		for (line = (LINES_PER_PAGE(handle) - 1); line >= 0; line--) {
474*2305Sstevel 			if (mtest_read(handle, (void *)readbuf0, pageno,
475*2305Sstevel 			    line, 1, &errbuf) == -1) {
476*2305Sstevel 				(void) sprintf(msgbuf, rd_err_msg, pageno);
477*2305Sstevel 				mtest_message(handle, msgbuf);
478*2305Sstevel 				return (MTEST_DEV_ERROR);
479*2305Sstevel 			}
480*2305Sstevel 			if (errbuf.error_type != MTEST_ERR_NONE) {
481*2305Sstevel 				if (errbuf.error_type == MTEST_ERR_CE &&
482*2305Sstevel 				    cond != CFGA_COND_FAILED)
483*2305Sstevel 					cond = CFGA_COND_FAILING;
484*2305Sstevel 				else
485*2305Sstevel 					cond = CFGA_COND_FAILED;
486*2305Sstevel 				total_errors++;
487*2305Sstevel 				/*
488*2305Sstevel 				 * Keep going if max errors is 0 or limit not
489*2305Sstevel 				 * reached.
490*2305Sstevel 				 */
491*2305Sstevel 				TEST_END(ntf_msg);
492*2305Sstevel 			}
493*2305Sstevel 			if (mtest_write(handle, (void*)patternbuf1, pageno,
494*2305Sstevel 			    line, 1) == -1) {
495*2305Sstevel 				(void) sprintf(msgbuf, wr_err_msg, pageno);
496*2305Sstevel 				mtest_message(handle, msgbuf);
497*2305Sstevel 				return (MTEST_DEV_ERROR);
498*2305Sstevel 			}
499*2305Sstevel 			if (mtest_read(handle, (void *)readbuf1, pageno,
500*2305Sstevel 			    line, 1, &errbuf) == -1) {
501*2305Sstevel 				(void) sprintf(msgbuf, rd_err_msg, pageno);
502*2305Sstevel 				mtest_message(handle, msgbuf);
503*2305Sstevel 				return (MTEST_DEV_ERROR);
504*2305Sstevel 			}
505*2305Sstevel 			if (errbuf.error_type != MTEST_ERR_NONE) {
506*2305Sstevel 				if (errbuf.error_type == MTEST_ERR_CE &&
507*2305Sstevel 				    cond != CFGA_COND_FAILED)
508*2305Sstevel 					cond = CFGA_COND_FAILING;
509*2305Sstevel 				else
510*2305Sstevel 					cond = CFGA_COND_FAILED;
511*2305Sstevel 				total_errors++;
512*2305Sstevel 				TEST_END(ntf_msg);
513*2305Sstevel 			}
514*2305Sstevel 			if (mtest_write(handle, (void*)patternbuf0, pageno,
515*2305Sstevel 			    line, 1) == -1) {
516*2305Sstevel 				(void) sprintf(msgbuf, wr_err_msg, pageno);
517*2305Sstevel 				mtest_message(handle, msgbuf);
518*2305Sstevel 				return (MTEST_DEV_ERROR);
519*2305Sstevel 			}
520*2305Sstevel 			if (mtest_read(handle, (void *)readbuf2, pageno,
521*2305Sstevel 			    line, 1, &errbuf) == -1) {
522*2305Sstevel 				(void) sprintf(msgbuf, rd_err_msg, pageno);
523*2305Sstevel 				mtest_message(handle, msgbuf);
524*2305Sstevel 				return (MTEST_DEV_ERROR);
525*2305Sstevel 			}
526*2305Sstevel 			if (errbuf.error_type != MTEST_ERR_NONE) {
527*2305Sstevel 				if (errbuf.error_type == MTEST_ERR_CE &&
528*2305Sstevel 				    cond != CFGA_COND_FAILED)
529*2305Sstevel 					cond = CFGA_COND_FAILING;
530*2305Sstevel 				else
531*2305Sstevel 					cond = CFGA_COND_FAILED;
532*2305Sstevel 				total_errors++;
533*2305Sstevel 				TEST_END(ntf_msg);
534*2305Sstevel 			}
535*2305Sstevel 			if (mtest_write(handle, (void*)patternbuf1, pageno,
536*2305Sstevel 			    line, 1) == -1) {
537*2305Sstevel 				(void) sprintf(msgbuf, wr_err_msg, pageno);
538*2305Sstevel 				return (MTEST_DEV_ERROR);
539*2305Sstevel 			}
540*2305Sstevel 		}	/* line */
541*2305Sstevel 		if (memcmp((void *)patternbuf0, (void *)readbuf0,
542*2305Sstevel 		    PAGE_SIZE(handle)) != 0) {
543*2305Sstevel 			cond = CFGA_COND_FAILED;
544*2305Sstevel 			error_print((void *)patternbuf0, (void *)readbuf0,
545*2305Sstevel 			    handle, pageno, &total_errors);
546*2305Sstevel 			TEST_END(ntf_msg);
547*2305Sstevel 		}
548*2305Sstevel 		if (memcmp((void *)patternbuf1, (void *)readbuf1,
549*2305Sstevel 			PAGE_SIZE(handle)) != 0) {
550*2305Sstevel 			cond = CFGA_COND_FAILED;
551*2305Sstevel 			error_print((void *)patternbuf1, (void *)readbuf1,
552*2305Sstevel 			    handle, pageno, &total_errors);
553*2305Sstevel 			TEST_END(ntf_msg);
554*2305Sstevel 		}
555*2305Sstevel 		if (memcmp((void *)patternbuf0, (void *)readbuf2,
556*2305Sstevel 			PAGE_SIZE(handle)) != 0) {
557*2305Sstevel 			cond = CFGA_COND_FAILED;
558*2305Sstevel 			error_print((void *)patternbuf0, (void *)readbuf2,
559*2305Sstevel 			    handle, pageno, &total_errors);
560*2305Sstevel 			TEST_END(ntf_msg);
561*2305Sstevel 		}
562*2305Sstevel 		if ((time(NULL) >= time_rep) || (pageno == npages - 1) ||
563*2305Sstevel 		    (pageno == 0)) {
564*2305Sstevel 			(void) sprintf(msgbuf, report_msg, m1_msg,
565*2305Sstevel 			    ml_rd_cmp_msg, ((npages - pageno) * 100) / npages);
566*2305Sstevel 			mtest_message(handle, msgbuf);
567*2305Sstevel 			time_rep = time(NULL) + REPORT_SEC * 3;
568*2305Sstevel 		}
569*2305Sstevel 	}	/* page */
570*2305Sstevel 
571*2305Sstevel 	/* March 2 */
572*2305Sstevel 	for (pageno = npages-1; pageno >= 0; pageno--) {
573*2305Sstevel 		for (line = (LINES_PER_PAGE(handle) - 1); line >= 0; line--) {
574*2305Sstevel 			if (mtest_read(handle, (void *)readbuf0, pageno,
575*2305Sstevel 			    line, 1, &errbuf) == -1) {
576*2305Sstevel 				(void) sprintf(msgbuf, rd_err_msg, pageno);
577*2305Sstevel 				mtest_message(handle, msgbuf);
578*2305Sstevel 				return (MTEST_DEV_ERROR);
579*2305Sstevel 			}
580*2305Sstevel 			if (errbuf.error_type != MTEST_ERR_NONE) {
581*2305Sstevel 				if (errbuf.error_type == MTEST_ERR_CE &&
582*2305Sstevel 				    cond != CFGA_COND_FAILED)
583*2305Sstevel 					cond = CFGA_COND_FAILING;
584*2305Sstevel 				else
585*2305Sstevel 					cond = CFGA_COND_FAILED;
586*2305Sstevel 				total_errors++;
587*2305Sstevel 				/*
588*2305Sstevel 				 * Keep going if max errors is 0 or limit not
589*2305Sstevel 				 * reached.
590*2305Sstevel 				 */
591*2305Sstevel 				TEST_END(ntf_msg);
592*2305Sstevel 			}
593*2305Sstevel 			if (mtest_write(handle, (void*)patternbuf0, pageno,
594*2305Sstevel 			    line, 1) == -1) {
595*2305Sstevel 				(void) sprintf(msgbuf, wr_err_msg, pageno);
596*2305Sstevel 				mtest_message(handle, msgbuf);
597*2305Sstevel 				return (MTEST_DEV_ERROR);
598*2305Sstevel 			}
599*2305Sstevel 			if (mtest_write(handle, (void*)patternbuf1, pageno,
600*2305Sstevel 			    line, 1) == -1) {
601*2305Sstevel 				(void) sprintf(msgbuf, wr_err_msg, pageno);
602*2305Sstevel 				mtest_message(handle, msgbuf);
603*2305Sstevel 				return (MTEST_DEV_ERROR);
604*2305Sstevel 			}
605*2305Sstevel 		}
606*2305Sstevel 		if (memcmp((void *)patternbuf1, (void *)readbuf0,
607*2305Sstevel 			PAGE_SIZE(handle)) != 0) {
608*2305Sstevel 			cond = CFGA_COND_FAILED;
609*2305Sstevel 			total_errors++;
610*2305Sstevel 		}
611*2305Sstevel 		if ((time(NULL) >= time_rep) || (pageno == npages - 1) ||
612*2305Sstevel 		    (pageno == 0)) {
613*2305Sstevel 			(void) sprintf(msgbuf, report_msg, m2_msg,
614*2305Sstevel 			    ln_rd_cmp_msg, ((npages - pageno) * 100) / npages);
615*2305Sstevel 			mtest_message(handle, msgbuf);
616*2305Sstevel 			time_rep = time(NULL) + REPORT_SEC * 3;
617*2305Sstevel 		}
618*2305Sstevel 	}	/* page */
619*2305Sstevel 
620*2305Sstevel 	/* March 3 */
621*2305Sstevel 	for (pageno = 0; pageno < npages; pageno++) {
622*2305Sstevel 		for (line = 0; line < LINES_PER_PAGE(handle); line++) {
623*2305Sstevel 			if (mtest_read(handle, (void *)readbuf0, pageno,
624*2305Sstevel 			    line, 1, &errbuf) == -1) {
625*2305Sstevel 				(void) sprintf(msgbuf, rd_err_msg, pageno);
626*2305Sstevel 				mtest_message(handle, msgbuf);
627*2305Sstevel 				return (MTEST_DEV_ERROR);
628*2305Sstevel 			}
629*2305Sstevel 			if (errbuf.error_type != MTEST_ERR_NONE) {
630*2305Sstevel 				if (errbuf.error_type == MTEST_ERR_CE &&
631*2305Sstevel 				    cond != CFGA_COND_FAILED)
632*2305Sstevel 					cond = CFGA_COND_FAILING;
633*2305Sstevel 				else
634*2305Sstevel 					cond = CFGA_COND_FAILED;
635*2305Sstevel 				total_errors++;
636*2305Sstevel 				TEST_END(ntf_msg);
637*2305Sstevel 			}
638*2305Sstevel 			if (mtest_write(handle, (void*)patternbuf0, pageno,
639*2305Sstevel 			    line, 1) == -1) {
640*2305Sstevel 				(void) sprintf(msgbuf, wr_err_msg, pageno);
641*2305Sstevel 				mtest_message(handle, msgbuf);
642*2305Sstevel 				return (MTEST_DEV_ERROR);
643*2305Sstevel 			}
644*2305Sstevel 			if (mtest_write(handle, (void*)patternbuf1, pageno,
645*2305Sstevel 			    line, 1) == -1) {
646*2305Sstevel 				(void) sprintf(msgbuf, wr_err_msg, pageno);
647*2305Sstevel 				mtest_message(handle, msgbuf);
648*2305Sstevel 				return (MTEST_DEV_ERROR);
649*2305Sstevel 			}
650*2305Sstevel 			if (mtest_write(handle, (void*)patternbuf0, pageno,
651*2305Sstevel 			    line, 1) == -1) {
652*2305Sstevel 				(void) sprintf(msgbuf, wr_err_msg, pageno);
653*2305Sstevel 				mtest_message(handle, msgbuf);
654*2305Sstevel 				return (MTEST_DEV_ERROR);
655*2305Sstevel 			}
656*2305Sstevel 		}
657*2305Sstevel 		if (memcmp((void *)patternbuf1, (void *)readbuf0,
658*2305Sstevel 			PAGE_SIZE(handle)) != 0) {
659*2305Sstevel 			cond = CFGA_COND_FAILED;
660*2305Sstevel 			error_print((void *)patternbuf1, (void *)readbuf0,
661*2305Sstevel 			    handle, pageno, &total_errors);
662*2305Sstevel 			TEST_END(ntf_msg);
663*2305Sstevel 		}
664*2305Sstevel 		if ((time(NULL) >= time_rep) || (pageno == npages - 1) ||
665*2305Sstevel 		    (pageno == 0)) {
666*2305Sstevel 			(void) sprintf(msgbuf, report_msg, m3_msg,
667*2305Sstevel 			    ml_rd_cmp_msg, ((pageno + 1) * 100) / npages);
668*2305Sstevel 			mtest_message(handle, msgbuf);
669*2305Sstevel 			time_rep = time(NULL) + REPORT_SEC * 3;
670*2305Sstevel 		}
671*2305Sstevel 	}	/* page */
672*2305Sstevel 
673*2305Sstevel 	/* March 4 */
674*2305Sstevel 	for (pageno = 0; pageno < npages; pageno++) {
675*2305Sstevel 		for (line = 0; line < LINES_PER_PAGE(handle); line++) {
676*2305Sstevel 			if (mtest_read(handle, (void *)readbuf0, pageno,
677*2305Sstevel 			    line, 1, &errbuf) == -1) {
678*2305Sstevel 				(void) sprintf(msgbuf, rd_err_msg, pageno);
679*2305Sstevel 				mtest_message(handle, msgbuf);
680*2305Sstevel 				return (MTEST_DEV_ERROR);
681*2305Sstevel 			}
682*2305Sstevel 			if (errbuf.error_type != MTEST_ERR_NONE) {
683*2305Sstevel 				if (errbuf.error_type == MTEST_ERR_CE &&
684*2305Sstevel 				    cond != CFGA_COND_FAILED)
685*2305Sstevel 					cond = CFGA_COND_FAILING;
686*2305Sstevel 				else
687*2305Sstevel 					cond = CFGA_COND_FAILED;
688*2305Sstevel 				total_errors++;
689*2305Sstevel 				TEST_END(ntf_msg);
690*2305Sstevel 			}
691*2305Sstevel 			if (mtest_write(handle, (void*)patternbuf1, pageno,
692*2305Sstevel 			    line, 1) == -1) {
693*2305Sstevel 				(void) sprintf(msgbuf, wr_err_msg, pageno);
694*2305Sstevel 				mtest_message(handle, msgbuf);
695*2305Sstevel 				return (MTEST_DEV_ERROR);
696*2305Sstevel 			}
697*2305Sstevel 			if (mtest_write(handle, (void*)patternbuf0, pageno,
698*2305Sstevel 			    line, 1) == -1) {
699*2305Sstevel 				(void) sprintf(msgbuf, wr_err_msg, pageno);
700*2305Sstevel 				mtest_message(handle, msgbuf);
701*2305Sstevel 				return (MTEST_DEV_ERROR);
702*2305Sstevel 			}
703*2305Sstevel 		}
704*2305Sstevel 		if (memcmp((void *)patternbuf0, (void *)readbuf0,
705*2305Sstevel 			PAGE_SIZE(handle)) != 0) {
706*2305Sstevel 			cond = CFGA_COND_FAILED;
707*2305Sstevel 			error_print((void *)patternbuf0, (void *)readbuf0,
708*2305Sstevel 			    handle, pageno, &total_errors);
709*2305Sstevel 			TEST_END(ntf_msg);
710*2305Sstevel 		}
711*2305Sstevel 		if ((time(NULL) >= time_rep) || (pageno == npages - 1) ||
712*2305Sstevel 		    (pageno == 0)) {
713*2305Sstevel 			(void) sprintf(msgbuf, report_msg, m4_msg,
714*2305Sstevel 			    ln_rd_cmp_msg, ((pageno + 1) * 100) / npages);
715*2305Sstevel 			mtest_message(handle, msgbuf);
716*2305Sstevel 			time_rep = time(NULL) + REPORT_SEC * 3;
717*2305Sstevel 		}
718*2305Sstevel 	}	/* page */
719*2305Sstevel 	mtest_message(handle, etf_msg);
720*2305Sstevel 	error_summary(handle, total_errors);
721*2305Sstevel 	SET_CONDITION(handle, cond);
722*2305Sstevel 	return (MTEST_DONE);
723*2305Sstevel }
724