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