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 2005 Sun Microsystems, Inc. All rights reserved.
24*2305Sstevel * Use is subject to license terms.
25*2305Sstevel */
26*2305Sstevel
27*2305Sstevel #pragma ident "%Z%%M% %I% %E% SMI"
28*2305Sstevel
29*2305Sstevel #include <stddef.h>
30*2305Sstevel #include <stdlib.h>
31*2305Sstevel #include <unistd.h>
32*2305Sstevel #include <ctype.h>
33*2305Sstevel #include <fcntl.h>
34*2305Sstevel #include <signal.h>
35*2305Sstevel #include <string.h>
36*2305Sstevel #include <locale.h>
37*2305Sstevel #include <errno.h>
38*2305Sstevel #include <assert.h>
39*2305Sstevel #include <sys/dditypes.h>
40*2305Sstevel #include <sys/param.h>
41*2305Sstevel #include <sys/obpdefs.h>
42*2305Sstevel #include <sys/fhc.h>
43*2305Sstevel #include <sys/sysctrl.h>
44*2305Sstevel #include <sys/ac.h>
45*2305Sstevel #include <sys/spitregs.h>
46*2305Sstevel #include <config_admin.h>
47*2305Sstevel #include "mema_util.h"
48*2305Sstevel #include "mema_test.h"
49*2305Sstevel #include "mema_prom.h"
50*2305Sstevel
51*2305Sstevel #ifdef DEBUG
52*2305Sstevel #define DBG (void) printf
53*2305Sstevel #define DBG1 (void) printf
54*2305Sstevel #define DBG3 (void) printf
55*2305Sstevel #define DBG4 (void) printf
56*2305Sstevel #else
57*2305Sstevel #define DBG(a, b)
58*2305Sstevel #define DBG1(a)
59*2305Sstevel #define DBG3(a, b, c)
60*2305Sstevel #define DBG4(a, b, c, d)
61*2305Sstevel #endif
62*2305Sstevel
63*2305Sstevel #ifndef P_DER_UE
64*2305Sstevel /*
65*2305Sstevel * <sys/spitregs.h> has these defines inside 'ifdef _KERNEL' at the
66*2305Sstevel * time of writing. Re-define here if that is still the case.
67*2305Sstevel */
68*2305Sstevel
69*2305Sstevel #define P_DER_UE 0x00000000000000200ULL /* UE has occurred */
70*2305Sstevel #define P_DER_CE 0x00000000000000100ULL /* CE has occurred */
71*2305Sstevel #define P_DER_E_SYND 0x000000000000000FFULL /* SYND<7:0>: ECC syndrome */
72*2305Sstevel #endif /* ! P_DER_UE */
73*2305Sstevel
74*2305Sstevel #define DEV_DEBUG
75*2305Sstevel #ifdef DEV_DEBUG
76*2305Sstevel #include <stdio.h>
77*2305Sstevel #include <stdlib.h>
78*2305Sstevel
79*2305Sstevel static FILE *debug_fp;
80*2305Sstevel static int debugging(void);
81*2305Sstevel static void dump_ioctl(int, void *);
82*2305Sstevel static void dump_ioctl_res(int, void *, int, int);
83*2305Sstevel #else /* DEV_DEBUG */
84*2305Sstevel #define dump_ioctl(CMD, ARG)
85*2305Sstevel #define dump_ioctl_res(CMD, ARG, RET, ERRNO)
86*2305Sstevel #endif /* DEV_DEBUG */
87*2305Sstevel
88*2305Sstevel typedef struct {
89*2305Sstevel uint_t board;
90*2305Sstevel uint_t bank;
91*2305Sstevel } mema_bank_t;
92*2305Sstevel
93*2305Sstevel static char *mema_opts[] = {
94*2305Sstevel #define OPT_BOOT_DISABLE 0
95*2305Sstevel "disable-at-boot",
96*2305Sstevel #define OPT_BOOT_ENABLE 1
97*2305Sstevel "enable-at-boot",
98*2305Sstevel #define OPT_TIMEOUT 2
99*2305Sstevel "timeout",
100*2305Sstevel NULL
101*2305Sstevel };
102*2305Sstevel
103*2305Sstevel #define OPT_NEEDS_VALUE(O) ((O) == OPT_TIMEOUT)
104*2305Sstevel
105*2305Sstevel #define MAX_OPT_LENGTH (sizeof ("disable-at-boot"))
106*2305Sstevel
107*2305Sstevel /*
108*2305Sstevel * For each function there is an array of opt_control structures giving
109*2305Sstevel * the valid options. The array is terminated by an element with the
110*2305Sstevel * subopt field set to -1. The group field is used to identify
111*2305Sstevel * mutually exclusive options, with zero meaning no grouping.
112*2305Sstevel */
113*2305Sstevel struct opt_control {
114*2305Sstevel int subopt;
115*2305Sstevel int group;
116*2305Sstevel };
117*2305Sstevel
118*2305Sstevel /*
119*2305Sstevel * Returned set of options.
120*2305Sstevel * If the option takes a value, it will be set in 'val'
121*2305Sstevel * if the corresponding bit is set in 'bits' is set,
122*2305Sstevel * otherwise the pointer in 'val' is undefined.
123*2305Sstevel */
124*2305Sstevel #define OPT_VAL_ARRAY_SIZE 32 /* # bits in 'bits' */
125*2305Sstevel typedef struct {
126*2305Sstevel unsigned int bits;
127*2305Sstevel char *val[OPT_VAL_ARRAY_SIZE];
128*2305Sstevel } option_set_t;
129*2305Sstevel
130*2305Sstevel #define OPTSET_INIT(S) ((S).bits = 0)
131*2305Sstevel #define _OPT_TO_BIT(O) (1 << (O))
132*2305Sstevel #define OPTSET_SET_VAL(S, O, V) ((S).bits |= _OPT_TO_BIT(O), \
133*2305Sstevel (S).val[(O)] = (V))
134*2305Sstevel #define OPTSET_TEST(S, O) (((S).bits & _OPT_TO_BIT(O)) != 0)
135*2305Sstevel #define OPTSET_VAL(S, O) ((S).val[(O)])
136*2305Sstevel #define OPTSET_IS_EMPTY(S) ((S).bits == 0)
137*2305Sstevel
138*2305Sstevel static option_set_t process_options(const char *, struct opt_control *,
139*2305Sstevel int *, char **);
140*2305Sstevel
141*2305Sstevel static struct opt_control add_opts[] = {
142*2305Sstevel {OPT_BOOT_ENABLE, 1},
143*2305Sstevel {OPT_BOOT_DISABLE, 1},
144*2305Sstevel {-1, 0}
145*2305Sstevel };
146*2305Sstevel
147*2305Sstevel static struct opt_control del_opts[] = {
148*2305Sstevel {OPT_BOOT_ENABLE, 1},
149*2305Sstevel {OPT_BOOT_DISABLE, 1},
150*2305Sstevel {OPT_TIMEOUT, 2},
151*2305Sstevel {-1, 0}
152*2305Sstevel };
153*2305Sstevel
154*2305Sstevel static struct opt_control stat_opts[] = {
155*2305Sstevel {OPT_BOOT_ENABLE, 1},
156*2305Sstevel {OPT_BOOT_DISABLE, 1},
157*2305Sstevel {-1, 0}
158*2305Sstevel };
159*2305Sstevel
160*2305Sstevel #if !defined(TEXT_DOMAIN)
161*2305Sstevel #define TEXT_DOMAIN "SYS_TEST"
162*2305Sstevel #endif
163*2305Sstevel
164*2305Sstevel static const char still_testing[] = "bank %s being tested by process %d";
165*2305Sstevel static const char no_value[] = "sub-option \"%s\" does not take a value";
166*2305Sstevel static const char missing_value[] = "sub-option \"%s\" needs a value";
167*2305Sstevel static const char conflict_opt[] = "sub-option \"%s\" conflicts with \"%s\"";
168*2305Sstevel static const char unk_subopt[] = "sub-option \"%s\" unknown\n"
169*2305Sstevel "choose from: %s";
170*2305Sstevel static const char not_valid[] =
171*2305Sstevel "sub-option \"%s\" not valid for this operation\n"
172*2305Sstevel "choose from: %s";
173*2305Sstevel static const char timeout_notnum[] =
174*2305Sstevel "timeout value not a positive integer \"%s\"";
175*2305Sstevel static const char calloc_fail[] = "memory allocation failed (%d*%d bytes)";
176*2305Sstevel static const char unk_test[] = "test \"%s\" unknown\n"
177*2305Sstevel "choose from: %s";
178*2305Sstevel static const char dup_test[] = "more than one test type specified (\"%s\")";
179*2305Sstevel static const char dup_num[] = "option specified more than once (\"%s\")";
180*2305Sstevel static const char no_num[] = "invalid number specified for max_errors(\"%s\")";
181*2305Sstevel static const char mtest_rw_error[] = "memory test read/write error";
182*2305Sstevel static const char mtest_lib_error[] = "memory test library error";
183*2305Sstevel static const char dlist_invalid[] = "invalid disabled-memory-list";
184*2305Sstevel static const char dlist_write_failed[] = "disabled-memory-list write failed";
185*2305Sstevel static const char mtest_unknown_error[] = "unknown memory test error";
186*2305Sstevel static const char ap_invalid[] = "invalid attachment point: %s";
187*2305Sstevel static const char trans_illegal[] = "illegal transition";
188*2305Sstevel static const char open_failed[] = "open failed: %s: %s";
189*2305Sstevel static const char mema_help[] = "\nAc specific options:\n";
190*2305Sstevel static const char disable_opts[] = "\t-o disable-at-boot\n";
191*2305Sstevel static const char enable_opts[] = "\t-o enable-at-boot\n";
192*2305Sstevel static const char timeout_opts[] = "\t-o timeout=# (seconds)\n";
193*2305Sstevel static const char test_opts[] =
194*2305Sstevel "\t-o {quick, normal, extended},[max_errors=#] -t ap_id [ap_id...]\n";
195*2305Sstevel static const char private_funcs[] = "\t-x relocate-test ap_id [ap_id...]\n";
196*2305Sstevel static const char add_is_disabled[] = "memory is disabled at boot";
197*2305Sstevel static const char add_willbe_disabled[] =
198*2305Sstevel "memory will be disabled at boot";
199*2305Sstevel static const char add_disab_err[] = "cannot get memory disabled status";
200*2305Sstevel static const char pfunc_unknown[] = "private function \"%s\" unknown";
201*2305Sstevel
202*2305Sstevel
203*2305Sstevel #define mema_eid(a, b) (((a) << 8) + (b))
204*2305Sstevel #define mema_str(i) mema_strs[(i)]
205*2305Sstevel
206*2305Sstevel #define AC_BK_BUSY 0
207*2305Sstevel #define AC_BK_ID 1
208*2305Sstevel #define AC_BD_ID 2
209*2305Sstevel #define AC_BD_TYPE 3
210*2305Sstevel #define AC_BD_STATE 4
211*2305Sstevel #define AC_MEM_TEST_ID 5
212*2305Sstevel #define AC_MEM_TEST_PAR 6
213*2305Sstevel #define AC_MEM_PERM 7
214*2305Sstevel #define AC_KPM_CANCELLED 8
215*2305Sstevel #define AC_KPM_REFUSED 9
216*2305Sstevel #define AC_KPM_SPAN 10
217*2305Sstevel #define AC_KPM_DUP 11
218*2305Sstevel #define AC_KPM_FAULT 12
219*2305Sstevel #define AC_KPM_RESOURCE 13
220*2305Sstevel #define AC_KPM_NOTSUP 14
221*2305Sstevel #define AC_KPM_NOHANDLES 15
222*2305Sstevel #define AC_KPM_NONRELOC 16
223*2305Sstevel #define AC_KPM_HANDLE 17
224*2305Sstevel #define AC_KPM_BUSY 18
225*2305Sstevel #define AC_KPM_NOTVIABLE 19
226*2305Sstevel #define AC_KPM_SEQUENCE 20
227*2305Sstevel #define AC_KPM_NOWORK 21
228*2305Sstevel #define AC_KPM_NOTFINISHED 22
229*2305Sstevel #define AC_KPM_NOTRUNNING 23
230*2305Sstevel #define AC_VMEM 24
231*2305Sstevel #define CMD_MEM_STAT 25
232*2305Sstevel #define CMD_MEM_ADD 26
233*2305Sstevel #define CMD_MEM_DEL 27
234*2305Sstevel #define CMD_MEM_TEST_START 28
235*2305Sstevel #define CMD_MEM_TEST_STOP 29
236*2305Sstevel #define AC_UNKNOWN 30
237*2305Sstevel #define AC_INTR 31
238*2305Sstevel #define AC_TIMEOUT 32
239*2305Sstevel #define CMD_MEM_RELOCTEST 33
240*2305Sstevel #define AC_DEINTLV 34
241*2305Sstevel
242*2305Sstevel static char *
243*2305Sstevel mema_strs[] = {
244*2305Sstevel "memory bank busy",
245*2305Sstevel "invalid memory bank",
246*2305Sstevel "invalid board id",
247*2305Sstevel "invalid board type",
248*2305Sstevel "invalid board state",
249*2305Sstevel "invalid memory test id",
250*2305Sstevel "invalid memory test parameter(s)",
251*2305Sstevel "no write permission",
252*2305Sstevel "memory operation cancelled",
253*2305Sstevel "memory operation refused",
254*2305Sstevel "memory already in use (add)",
255*2305Sstevel "memory span duplicate (delete)",
256*2305Sstevel "memory access test failed (add)",
257*2305Sstevel "some resource was not available",
258*2305Sstevel "operation not supported",
259*2305Sstevel "cannot allocate any more handles",
260*2305Sstevel "non-relocatable pages in span",
261*2305Sstevel "bad handle supplied",
262*2305Sstevel "memory in span is being deleted",
263*2305Sstevel "VM viability test failed",
264*2305Sstevel "function called out of sequence",
265*2305Sstevel "no memory to delete",
266*2305Sstevel "delete processing not finished",
267*2305Sstevel "delete processing not running",
268*2305Sstevel "insufficient virtual memory",
269*2305Sstevel "memory stat failed: %s",
270*2305Sstevel "memory add failed: %s",
271*2305Sstevel "memory delete failed: %s",
272*2305Sstevel "memory test start failed: %s",
273*2305Sstevel "memory test stop failed: %s",
274*2305Sstevel "unknown error",
275*2305Sstevel "memory delete killed",
276*2305Sstevel "memory delete timeout",
277*2305Sstevel "memory relocate-test failed: %s",
278*2305Sstevel "memory cannot be de-interleaved"
279*2305Sstevel };
280*2305Sstevel
281*2305Sstevel /*
282*2305Sstevel * AC_MEM_PERM, EBADF, AC_ERR_MEM_PERM
283*2305Sstevel * AC_BK_BUSY, EBUSY, AC_ERR_MEM_BK
284*2305Sstevel * AC_KPM_CANCELLED, EINTR, AC_ERR_KPM_CANCELLED
285*2305Sstevel * AC_KPM_REFUSED, EINTR, AC_ERR_KPM_REFUSED
286*2305Sstevel * AC_BK_ID, EINVAL, AC_ERR_MEM_BK
287*2305Sstevel * AC_BD_ID, EINVAL, AC_ERR_BD
288*2305Sstevel * AC_BD_TYPE, EINVAL, AC_ERR_BD_TYPE
289*2305Sstevel * AC_BD_STATE, EINVAL, AC_ERR_BD_STATE
290*2305Sstevel * AC_MEM_TEST_ID, EINVAL, AC_ERR_MEM_TEST
291*2305Sstevel * AC_MEM_TEST_PAR, EINVAL, AC_ERR_MEM_TEST_PAR
292*2305Sstevel * AC_KPM_SPAN, EINVAL, AC_ERR_KPM_SPAN
293*2305Sstevel * AC_KPM_DUP, EINVAL, AC_ERR_KPM_DUP?
294*2305Sstevel * AC_KPM_FAULT, EINVAL, AC_ERR_KPM_FAULT
295*2305Sstevel * AC_KPM_RESOURCE, EINVAL, AC_ERR_KPM_RESOURCE
296*2305Sstevel * AC_KPM_NOTSUP, EINVAL, AC_ERR_KPM_NOTSUP
297*2305Sstevel * AC_KPM_NOHANDLES, EINVAL, AC_ERR_KPM_NOHANDLES
298*2305Sstevel * AC_KPM_NONRELOC, EINVAL, AC_ERR_KPM_NONRELOC
299*2305Sstevel * AC_KPM_HANDLE, EINVAL, AC_ERR_KPM_HANDLE
300*2305Sstevel * AC_KPM_BUSY, EINVAL, AC_ERR_KPM_BUSY
301*2305Sstevel * AC_KPM_NOTVIABLE, EINVAL, AC_ERR_KPM_NOTVIABLE
302*2305Sstevel * AC_KPM_SEQUENCE, EINVAL, AC_ERR_KPM_SEQUENCE
303*2305Sstevel * AC_KPM_NOWORK, EINVAL, AC_ERR_KPM_NOWORK
304*2305Sstevel * AC_KPM_NOTFINISHED, EINVAL, AC_ERR_KPM_NOTFINISHED
305*2305Sstevel * AC_KPM_NOTRUNNING, EINVAL, AC_ERR_KPM_NOTRUNNING
306*2305Sstevel * AC_VMEM, ENOMEM, AC_ERR_VMEM
307*2305Sstevel * AC_INTR, EINTR, AC_ERR_INTR
308*2305Sstevel * AC_TIMEOUT, EINTR, AC_ERR_TIMEOUT
309*2305Sstevel * AC_DEINTLV, EINVAL, AC_ERR_MEM_DEINTLV
310*2305Sstevel */
311*2305Sstevel static int
mema_sid(int err,int acerr)312*2305Sstevel mema_sid(int err, int acerr)
313*2305Sstevel {
314*2305Sstevel if (acerr == AC_ERR_DEFAULT)
315*2305Sstevel return (AC_UNKNOWN);
316*2305Sstevel
317*2305Sstevel switch (mema_eid(err, acerr)) {
318*2305Sstevel case mema_eid(EBADF, AC_ERR_MEM_PERM):
319*2305Sstevel return (AC_MEM_PERM);
320*2305Sstevel case mema_eid(EBUSY, AC_ERR_MEM_BK):
321*2305Sstevel return (AC_BK_BUSY);
322*2305Sstevel case mema_eid(EINTR, AC_ERR_KPM_CANCELLED):
323*2305Sstevel return (AC_KPM_CANCELLED);
324*2305Sstevel case mema_eid(EINTR, AC_ERR_KPM_REFUSED):
325*2305Sstevel return (AC_KPM_REFUSED);
326*2305Sstevel case mema_eid(EINVAL, AC_ERR_MEM_BK):
327*2305Sstevel return (AC_BK_ID);
328*2305Sstevel case mema_eid(EINVAL, AC_ERR_BD):
329*2305Sstevel return (AC_BD_ID);
330*2305Sstevel case mema_eid(EINVAL, AC_ERR_BD_TYPE):
331*2305Sstevel return (AC_BD_TYPE);
332*2305Sstevel case mema_eid(EINVAL, AC_ERR_BD_STATE):
333*2305Sstevel return (AC_BD_STATE);
334*2305Sstevel case mema_eid(EINVAL, AC_ERR_MEM_TEST):
335*2305Sstevel return (AC_MEM_TEST_ID);
336*2305Sstevel case mema_eid(EINVAL, AC_ERR_MEM_TEST_PAR):
337*2305Sstevel return (AC_MEM_TEST_PAR);
338*2305Sstevel case mema_eid(EINVAL, AC_ERR_KPM_SPAN):
339*2305Sstevel return (AC_KPM_SPAN);
340*2305Sstevel case mema_eid(EINVAL, AC_ERR_KPM_DUP):
341*2305Sstevel return (AC_KPM_DUP);
342*2305Sstevel case mema_eid(EINVAL, AC_ERR_KPM_FAULT):
343*2305Sstevel return (AC_KPM_FAULT);
344*2305Sstevel case mema_eid(EINVAL, AC_ERR_KPM_RESOURCE):
345*2305Sstevel return (AC_KPM_RESOURCE);
346*2305Sstevel case mema_eid(EINVAL, AC_ERR_KPM_NOTSUP):
347*2305Sstevel return (AC_KPM_NOTSUP);
348*2305Sstevel case mema_eid(EINVAL, AC_ERR_KPM_NOHANDLES):
349*2305Sstevel return (AC_KPM_NOHANDLES);
350*2305Sstevel case mema_eid(EINVAL, AC_ERR_KPM_NONRELOC):
351*2305Sstevel return (AC_KPM_NONRELOC);
352*2305Sstevel case mema_eid(EINVAL, AC_ERR_KPM_HANDLE):
353*2305Sstevel return (AC_KPM_HANDLE);
354*2305Sstevel case mema_eid(EINVAL, AC_ERR_KPM_BUSY):
355*2305Sstevel return (AC_KPM_BUSY);
356*2305Sstevel case mema_eid(EINVAL, AC_ERR_KPM_NOTVIABLE):
357*2305Sstevel return (AC_KPM_NOTVIABLE);
358*2305Sstevel case mema_eid(EINVAL, AC_ERR_KPM_SEQUENCE):
359*2305Sstevel return (AC_KPM_SEQUENCE);
360*2305Sstevel case mema_eid(EINVAL, AC_ERR_KPM_NOWORK):
361*2305Sstevel return (AC_KPM_NOWORK);
362*2305Sstevel case mema_eid(EINVAL, AC_ERR_KPM_NOTFINISHED):
363*2305Sstevel return (AC_KPM_NOTFINISHED);
364*2305Sstevel case mema_eid(EINVAL, AC_ERR_KPM_NOTRUNNING):
365*2305Sstevel return (AC_KPM_NOTRUNNING);
366*2305Sstevel case mema_eid(ENOMEM, AC_ERR_VMEM):
367*2305Sstevel return (AC_VMEM);
368*2305Sstevel case mema_eid(EINTR, AC_ERR_INTR):
369*2305Sstevel return (AC_INTR);
370*2305Sstevel case mema_eid(EINTR, AC_ERR_TIMEOUT):
371*2305Sstevel return (AC_TIMEOUT);
372*2305Sstevel case mema_eid(EINVAL, AC_ERR_MEM_DEINTLV):
373*2305Sstevel return (AC_DEINTLV);
374*2305Sstevel default:
375*2305Sstevel break;
376*2305Sstevel }
377*2305Sstevel
378*2305Sstevel return (AC_UNKNOWN);
379*2305Sstevel }
380*2305Sstevel
381*2305Sstevel static void
mema_err(ac_cfga_cmd_t * ac,int ret_errno,char ** errstring,int cmd)382*2305Sstevel mema_err(ac_cfga_cmd_t *ac, int ret_errno, char **errstring, int cmd)
383*2305Sstevel {
384*2305Sstevel char *cname = mema_str(cmd);
385*2305Sstevel char *syserr;
386*2305Sstevel char syserr_num[20];
387*2305Sstevel
388*2305Sstevel if (ac) {
389*2305Sstevel syserr = mema_str(mema_sid(ret_errno, ac->errtype));
390*2305Sstevel syserr = dgettext(TEXT_DOMAIN, syserr);
391*2305Sstevel } else {
392*2305Sstevel syserr = strerror(ret_errno);
393*2305Sstevel /* strerror() does its own gettext(). */
394*2305Sstevel if (syserr == NULL) {
395*2305Sstevel (void) sprintf(syserr_num, "errno=%d", errno);
396*2305Sstevel syserr = syserr_num;
397*2305Sstevel }
398*2305Sstevel }
399*2305Sstevel
400*2305Sstevel __fmt_errstring(errstring, strlen(syserr),
401*2305Sstevel dgettext(TEXT_DOMAIN, cname), syserr);
402*2305Sstevel }
403*2305Sstevel
404*2305Sstevel static void
mema_cmd_init(ac_cfga_cmd_t * ac,void * cmd,char * outputstr,int force)405*2305Sstevel mema_cmd_init(ac_cfga_cmd_t *ac, void *cmd, char *outputstr, int force)
406*2305Sstevel {
407*2305Sstevel (void) memset((void *)ac, 0, sizeof (*ac));
408*2305Sstevel
409*2305Sstevel ac->errtype = AC_ERR_DEFAULT;
410*2305Sstevel ac->private = cmd;
411*2305Sstevel ac->force = force;
412*2305Sstevel ac->outputstr = outputstr;
413*2305Sstevel
414*2305Sstevel (void) memset((void *)outputstr, 0, AC_OUTPUT_LEN);
415*2305Sstevel }
416*2305Sstevel
417*2305Sstevel static int
ap_bk_idx(const char * ap_id)418*2305Sstevel ap_bk_idx(const char *ap_id)
419*2305Sstevel {
420*2305Sstevel int id;
421*2305Sstevel char *s;
422*2305Sstevel static char *bank = "bank";
423*2305Sstevel
424*2305Sstevel DBG("ap_bk_idx(%s)\n", ap_id);
425*2305Sstevel
426*2305Sstevel if ((s = strstr(ap_id, bank)) == NULL)
427*2305Sstevel return (-1);
428*2305Sstevel else {
429*2305Sstevel int n;
430*2305Sstevel
431*2305Sstevel s += strlen(bank);
432*2305Sstevel n = strlen(s);
433*2305Sstevel
434*2305Sstevel DBG3("ap_bk_idx: s=%s, n=%d\n", s, n);
435*2305Sstevel
436*2305Sstevel if ((n != 1) || !isdigit(s[0]))
437*2305Sstevel return (-1);
438*2305Sstevel }
439*2305Sstevel
440*2305Sstevel id = atoi(s);
441*2305Sstevel
442*2305Sstevel if (id < 0 || id > 1)
443*2305Sstevel return (-1);
444*2305Sstevel
445*2305Sstevel DBG3("ap_bk_idx(%s)=%d\n", s, id);
446*2305Sstevel
447*2305Sstevel return (id);
448*2305Sstevel }
449*2305Sstevel
450*2305Sstevel static cfga_err_t
ap_stat(const char * bank_spec,int * fdp,mema_bank_t * bkp,ac_stat_t * stp,char ** errstring)451*2305Sstevel ap_stat(
452*2305Sstevel const char *bank_spec,
453*2305Sstevel int *fdp,
454*2305Sstevel mema_bank_t *bkp,
455*2305Sstevel ac_stat_t *stp,
456*2305Sstevel char **errstring)
457*2305Sstevel {
458*2305Sstevel int fd;
459*2305Sstevel int ret, ret_errno;
460*2305Sstevel int bank;
461*2305Sstevel mema_bank_t bk;
462*2305Sstevel ac_stat_t stat;
463*2305Sstevel ac_cfga_cmd_t cmd;
464*2305Sstevel char outputstr[AC_OUTPUT_LEN];
465*2305Sstevel
466*2305Sstevel if ((bank = ap_bk_idx(bank_spec)) == -1) {
467*2305Sstevel __fmt_errstring(errstring, strlen(bank_spec),
468*2305Sstevel dgettext(TEXT_DOMAIN, ap_invalid), bank_spec);
469*2305Sstevel return (CFGA_ERROR);
470*2305Sstevel }
471*2305Sstevel
472*2305Sstevel bk.bank = bank;
473*2305Sstevel
474*2305Sstevel if ((fd = open(bank_spec, ((fdp != NULL) ? O_RDWR : O_RDONLY), 0)) ==
475*2305Sstevel -1) {
476*2305Sstevel char *syserr;
477*2305Sstevel char syserr_num[20];
478*2305Sstevel
479*2305Sstevel syserr = strerror(errno);
480*2305Sstevel if (syserr == NULL) {
481*2305Sstevel (void) sprintf(syserr_num, "errno=%d", errno);
482*2305Sstevel syserr = syserr_num;
483*2305Sstevel }
484*2305Sstevel __fmt_errstring(errstring, strlen(syserr) +
485*2305Sstevel strlen(bank_spec),
486*2305Sstevel dgettext(TEXT_DOMAIN, open_failed), bank_spec, syserr);
487*2305Sstevel return (CFGA_ERROR);
488*2305Sstevel }
489*2305Sstevel
490*2305Sstevel mema_cmd_init(&cmd, &stat, outputstr, 0);
491*2305Sstevel dump_ioctl(AC_MEM_STAT, NULL);
492*2305Sstevel ret = ioctl(fd, AC_MEM_STAT, &cmd);
493*2305Sstevel ret_errno = errno;
494*2305Sstevel dump_ioctl_res(AC_MEM_STAT, &stat, ret, ret_errno);
495*2305Sstevel
496*2305Sstevel if (ret == -1) {
497*2305Sstevel mema_err(&cmd, ret_errno, errstring, CMD_MEM_STAT);
498*2305Sstevel (void) close(fd);
499*2305Sstevel return (CFGA_ERROR);
500*2305Sstevel }
501*2305Sstevel
502*2305Sstevel if (fdp)
503*2305Sstevel *fdp = fd;
504*2305Sstevel else
505*2305Sstevel (void) close(fd);
506*2305Sstevel
507*2305Sstevel if (stp)
508*2305Sstevel *stp = stat;
509*2305Sstevel
510*2305Sstevel if (bkp) {
511*2305Sstevel bkp->bank = bk.bank;
512*2305Sstevel bkp->board = stat.board;
513*2305Sstevel }
514*2305Sstevel
515*2305Sstevel return (CFGA_OK);
516*2305Sstevel }
517*2305Sstevel
518*2305Sstevel static void
set_disabled_bits(mema_disabled_t * dp,int value)519*2305Sstevel set_disabled_bits(mema_disabled_t *dp, int value)
520*2305Sstevel {
521*2305Sstevel if (value == 0)
522*2305Sstevel *dp &= ~PROM_MEMORY_DISABLED;
523*2305Sstevel else
524*2305Sstevel *dp |= PROM_MEMORY_DISABLED;
525*2305Sstevel }
526*2305Sstevel
527*2305Sstevel static void
set_present_bits(mema_disabled_t * dp,ac_stat_t * asp)528*2305Sstevel set_present_bits(mema_disabled_t *dp, ac_stat_t *asp)
529*2305Sstevel {
530*2305Sstevel if (asp->ostate == SYSC_CFGA_OSTATE_CONFIGURED)
531*2305Sstevel *dp |= PROM_MEMORY_PRESENT;
532*2305Sstevel else
533*2305Sstevel *dp &= ~PROM_MEMORY_DISABLED;
534*2305Sstevel }
535*2305Sstevel
536*2305Sstevel static cfga_err_t
prom_do_options(option_set_t do_option,int board,ac_stat_t * asp,char ** errstring)537*2305Sstevel prom_do_options(
538*2305Sstevel option_set_t do_option,
539*2305Sstevel int board,
540*2305Sstevel ac_stat_t *asp,
541*2305Sstevel char **errstring)
542*2305Sstevel {
543*2305Sstevel cfga_err_t ret;
544*2305Sstevel mema_disabled_t disab;
545*2305Sstevel
546*2305Sstevel if (!prom_read_disabled_list(&disab, board))
547*2305Sstevel return (CFGA_ERROR);
548*2305Sstevel
549*2305Sstevel set_present_bits(&disab, asp);
550*2305Sstevel
551*2305Sstevel ret = CFGA_OK;
552*2305Sstevel
553*2305Sstevel if (OPTSET_TEST(do_option, OPT_BOOT_ENABLE)) {
554*2305Sstevel set_disabled_bits(&disab, 0);
555*2305Sstevel if (!prom_viable_disabled_list(&disab)) {
556*2305Sstevel __fmt_errstring(errstring, 0,
557*2305Sstevel dgettext(TEXT_DOMAIN, dlist_invalid));
558*2305Sstevel ret = CFGA_ERROR;
559*2305Sstevel } else if (!prom_write_disabled_list(&disab, board)) {
560*2305Sstevel __fmt_errstring(errstring, 0,
561*2305Sstevel dgettext(TEXT_DOMAIN, dlist_write_failed));
562*2305Sstevel ret = CFGA_ERROR;
563*2305Sstevel }
564*2305Sstevel } else if (OPTSET_TEST(do_option, OPT_BOOT_DISABLE)) {
565*2305Sstevel set_disabled_bits(&disab, 1);
566*2305Sstevel if (!prom_viable_disabled_list(&disab)) {
567*2305Sstevel __fmt_errstring(errstring, 0,
568*2305Sstevel dgettext(TEXT_DOMAIN, dlist_invalid));
569*2305Sstevel ret = CFGA_ERROR;
570*2305Sstevel } else if (!prom_write_disabled_list(&disab, board)) {
571*2305Sstevel __fmt_errstring(errstring, 0,
572*2305Sstevel dgettext(TEXT_DOMAIN, dlist_write_failed));
573*2305Sstevel ret = CFGA_ERROR;
574*2305Sstevel }
575*2305Sstevel }
576*2305Sstevel
577*2305Sstevel return (ret);
578*2305Sstevel }
579*2305Sstevel
580*2305Sstevel static cfga_err_t
mema_add(const char * bank_spec,const char * options,char ** errstring,int force)581*2305Sstevel mema_add(
582*2305Sstevel const char *bank_spec,
583*2305Sstevel const char *options,
584*2305Sstevel char **errstring,
585*2305Sstevel int force)
586*2305Sstevel {
587*2305Sstevel mema_bank_t bk;
588*2305Sstevel int fd, ret, ret_errno;
589*2305Sstevel option_set_t do_option;
590*2305Sstevel ac_cfga_cmd_t cmd;
591*2305Sstevel ac_stat_t stat;
592*2305Sstevel char outputstr[AC_OUTPUT_LEN];
593*2305Sstevel
594*2305Sstevel ret = 0;
595*2305Sstevel do_option = process_options(options, add_opts, &ret, errstring);
596*2305Sstevel if (ret != 0) {
597*2305Sstevel return (ret);
598*2305Sstevel }
599*2305Sstevel
600*2305Sstevel ret = ap_stat(bank_spec, &fd, &bk, &stat, errstring);
601*2305Sstevel if (ret != CFGA_OK)
602*2305Sstevel return (ret);
603*2305Sstevel
604*2305Sstevel
605*2305Sstevel if (stat.rstate != SYSC_CFGA_RSTATE_CONNECTED ||
606*2305Sstevel stat.ostate != SYSC_CFGA_OSTATE_UNCONFIGURED) {
607*2305Sstevel __fmt_errstring(errstring, 0,
608*2305Sstevel dgettext(TEXT_DOMAIN, trans_illegal));
609*2305Sstevel (void) close(fd);
610*2305Sstevel return (CFGA_ERROR);
611*2305Sstevel }
612*2305Sstevel
613*2305Sstevel if (!force) {
614*2305Sstevel mema_disabled_t disab;
615*2305Sstevel
616*2305Sstevel if (prom_read_disabled_list(&disab, bk.board)) {
617*2305Sstevel if (disab != 0 &&
618*2305Sstevel !OPTSET_TEST(do_option, OPT_BOOT_ENABLE)) {
619*2305Sstevel __fmt_errstring(errstring, 0,
620*2305Sstevel dgettext(TEXT_DOMAIN, add_is_disabled));
621*2305Sstevel (void) close(fd);
622*2305Sstevel return (CFGA_ERROR);
623*2305Sstevel }
624*2305Sstevel if (disab == 0 &&
625*2305Sstevel OPTSET_TEST(do_option, OPT_BOOT_DISABLE)) {
626*2305Sstevel __fmt_errstring(errstring, 0,
627*2305Sstevel dgettext(TEXT_DOMAIN, add_willbe_disabled));
628*2305Sstevel (void) close(fd);
629*2305Sstevel return (CFGA_ERROR);
630*2305Sstevel }
631*2305Sstevel } else {
632*2305Sstevel __fmt_errstring(errstring, 0,
633*2305Sstevel dgettext(TEXT_DOMAIN, add_disab_err));
634*2305Sstevel (void) close(fd);
635*2305Sstevel return (CFGA_ERROR);
636*2305Sstevel }
637*2305Sstevel }
638*2305Sstevel
639*2305Sstevel mema_cmd_init(&cmd, NULL, outputstr, force);
640*2305Sstevel dump_ioctl(AC_MEM_CONFIGURE, NULL);
641*2305Sstevel ret = ioctl(fd, AC_MEM_CONFIGURE, &cmd);
642*2305Sstevel ret_errno = errno;
643*2305Sstevel dump_ioctl_res(AC_MEM_CONFIGURE, NULL, ret, ret_errno);
644*2305Sstevel (void) close(fd);
645*2305Sstevel
646*2305Sstevel if (ret == -1) {
647*2305Sstevel mema_err(&cmd, ret_errno, errstring, CMD_MEM_ADD);
648*2305Sstevel return (CFGA_ERROR);
649*2305Sstevel }
650*2305Sstevel
651*2305Sstevel ret = prom_do_options(do_option, bk.board, &stat, errstring);
652*2305Sstevel
653*2305Sstevel return (ret);
654*2305Sstevel }
655*2305Sstevel
656*2305Sstevel static cfga_err_t
mema_delete(const char * bank_spec,const char * options,char ** errstring,int force)657*2305Sstevel mema_delete(
658*2305Sstevel const char *bank_spec,
659*2305Sstevel const char *options,
660*2305Sstevel char **errstring,
661*2305Sstevel int force)
662*2305Sstevel {
663*2305Sstevel mema_bank_t bk;
664*2305Sstevel int fd, ret, ret_errno;
665*2305Sstevel option_set_t do_option;
666*2305Sstevel ac_cfga_cmd_t cmd;
667*2305Sstevel ac_stat_t stat;
668*2305Sstevel char outputstr[AC_OUTPUT_LEN];
669*2305Sstevel int timeout_secs = -1; /* Init to 'use default'. */
670*2305Sstevel
671*2305Sstevel ret = 0;
672*2305Sstevel do_option = process_options(options, del_opts, &ret, errstring);
673*2305Sstevel if (ret != 0) {
674*2305Sstevel return (ret);
675*2305Sstevel }
676*2305Sstevel
677*2305Sstevel if (OPTSET_TEST(do_option, OPT_TIMEOUT)) {
678*2305Sstevel char *to_val;
679*2305Sstevel char *ep;
680*2305Sstevel
681*2305Sstevel to_val = OPTSET_VAL(do_option, OPT_TIMEOUT);
682*2305Sstevel timeout_secs = (int)strtol(to_val, &ep, 10);
683*2305Sstevel if (*ep != '\0' || ep == to_val || timeout_secs < 0) {
684*2305Sstevel __fmt_errstring(errstring, strlen(to_val),
685*2305Sstevel dgettext(TEXT_DOMAIN, timeout_notnum), to_val);
686*2305Sstevel return (CFGA_ERROR);
687*2305Sstevel }
688*2305Sstevel }
689*2305Sstevel
690*2305Sstevel ret = ap_stat(bank_spec, &fd, &bk, &stat, errstring);
691*2305Sstevel if (ret != CFGA_OK)
692*2305Sstevel return (ret);
693*2305Sstevel
694*2305Sstevel if (stat.rstate != SYSC_CFGA_RSTATE_CONNECTED ||
695*2305Sstevel stat.ostate != SYSC_CFGA_OSTATE_CONFIGURED) {
696*2305Sstevel __fmt_errstring(errstring, 0,
697*2305Sstevel dgettext(TEXT_DOMAIN, trans_illegal));
698*2305Sstevel (void) close(fd);
699*2305Sstevel return (CFGA_ERROR);
700*2305Sstevel }
701*2305Sstevel
702*2305Sstevel mema_cmd_init(&cmd, NULL, outputstr, force);
703*2305Sstevel cmd.arg = timeout_secs;
704*2305Sstevel dump_ioctl(AC_MEM_UNCONFIGURE, NULL);
705*2305Sstevel ret = ioctl(fd, AC_MEM_UNCONFIGURE, &cmd);
706*2305Sstevel ret_errno = errno;
707*2305Sstevel dump_ioctl_res(AC_MEM_UNCONFIGURE, NULL, ret, ret_errno);
708*2305Sstevel (void) close(fd);
709*2305Sstevel
710*2305Sstevel if (ret == -1) {
711*2305Sstevel mema_err(&cmd, ret_errno, errstring, CMD_MEM_DEL);
712*2305Sstevel return (CFGA_ERROR);
713*2305Sstevel }
714*2305Sstevel
715*2305Sstevel ret = prom_do_options(do_option, bk.board, &stat, errstring);
716*2305Sstevel
717*2305Sstevel return (ret);
718*2305Sstevel }
719*2305Sstevel
720*2305Sstevel /*ARGSUSED*/
721*2305Sstevel cfga_err_t
cfga_change_state(cfga_cmd_t state_change_cmd,const char * ap_id,const char * options,struct cfga_confirm * confp,struct cfga_msg * msgp,char ** errstring,cfga_flags_t flags)722*2305Sstevel cfga_change_state(
723*2305Sstevel cfga_cmd_t state_change_cmd,
724*2305Sstevel const char *ap_id,
725*2305Sstevel const char *options,
726*2305Sstevel struct cfga_confirm *confp,
727*2305Sstevel struct cfga_msg *msgp,
728*2305Sstevel char **errstring,
729*2305Sstevel cfga_flags_t flags)
730*2305Sstevel {
731*2305Sstevel int force;
732*2305Sstevel cfga_err_t rc;
733*2305Sstevel
734*2305Sstevel if (errstring != NULL)
735*2305Sstevel *errstring = NULL;
736*2305Sstevel
737*2305Sstevel force = flags & CFGA_FLAG_FORCE;
738*2305Sstevel
739*2305Sstevel switch (state_change_cmd) {
740*2305Sstevel case CFGA_CMD_CONFIGURE:
741*2305Sstevel rc = mema_add(ap_id, options, errstring, force);
742*2305Sstevel break;
743*2305Sstevel
744*2305Sstevel case CFGA_CMD_UNCONFIGURE:
745*2305Sstevel rc = mema_delete(ap_id, options, errstring, force);
746*2305Sstevel break;
747*2305Sstevel
748*2305Sstevel default:
749*2305Sstevel rc = CFGA_OPNOTSUPP;
750*2305Sstevel break;
751*2305Sstevel }
752*2305Sstevel
753*2305Sstevel return (rc);
754*2305Sstevel }
755*2305Sstevel
756*2305Sstevel /*ARGSUSED*/
757*2305Sstevel cfga_err_t
cfga_private_func(const char * function,const char * ap_id,const char * options,struct cfga_confirm * confp,struct cfga_msg * msgp,char ** errstring,cfga_flags_t flags)758*2305Sstevel cfga_private_func(
759*2305Sstevel const char *function,
760*2305Sstevel const char *ap_id,
761*2305Sstevel const char *options,
762*2305Sstevel struct cfga_confirm *confp,
763*2305Sstevel struct cfga_msg *msgp,
764*2305Sstevel char **errstring,
765*2305Sstevel cfga_flags_t flags)
766*2305Sstevel {
767*2305Sstevel mema_bank_t bk;
768*2305Sstevel ac_stat_t stat;
769*2305Sstevel int fd, ret, ret_errno;
770*2305Sstevel ac_cfga_cmd_t cmd;
771*2305Sstevel char outputstr[AC_OUTPUT_LEN];
772*2305Sstevel
773*2305Sstevel if (errstring != NULL)
774*2305Sstevel *errstring = NULL;
775*2305Sstevel
776*2305Sstevel ret = ap_stat(ap_id, &fd, &bk, &stat, errstring);
777*2305Sstevel if (ret != CFGA_OK)
778*2305Sstevel return (ret);
779*2305Sstevel
780*2305Sstevel if (strcmp(function, "relocate-test") == 0) {
781*2305Sstevel struct ac_memx_relocate_stats rstat;
782*2305Sstevel
783*2305Sstevel mema_cmd_init(&cmd, NULL, outputstr,
784*2305Sstevel (flags & CFGA_FLAG_FORCE));
785*2305Sstevel cmd.arg = AC_MEMX_RELOCATE_ALL;
786*2305Sstevel cmd.private = &rstat;
787*2305Sstevel (void) memset((void *)&rstat, 0, sizeof (rstat));
788*2305Sstevel dump_ioctl(AC_MEM_EXERCISE, &cmd);
789*2305Sstevel ret = ioctl(fd, AC_MEM_EXERCISE, &cmd);
790*2305Sstevel ret_errno = errno;
791*2305Sstevel dump_ioctl_res(AC_MEM_EXERCISE, &cmd, ret, ret_errno);
792*2305Sstevel (void) close(fd);
793*2305Sstevel
794*2305Sstevel if (ret == -1) {
795*2305Sstevel mema_err(&cmd, ret_errno, errstring, CMD_MEM_RELOCTEST);
796*2305Sstevel return (CFGA_ERROR);
797*2305Sstevel }
798*2305Sstevel return (CFGA_OK);
799*2305Sstevel }
800*2305Sstevel
801*2305Sstevel __fmt_errstring(errstring, strlen(function),
802*2305Sstevel dgettext(TEXT_DOMAIN, pfunc_unknown), function);
803*2305Sstevel
804*2305Sstevel return (CFGA_ERROR);
805*2305Sstevel }
806*2305Sstevel
807*2305Sstevel static int
mtest_run(int fd,int test_fun,mema_bank_t * abkp,struct cfga_msg * msgp,char ** errstring,ulong_t max_errors)808*2305Sstevel mtest_run(
809*2305Sstevel int fd,
810*2305Sstevel int test_fun,
811*2305Sstevel mema_bank_t *abkp,
812*2305Sstevel struct cfga_msg *msgp,
813*2305Sstevel char **errstring,
814*2305Sstevel ulong_t max_errors)
815*2305Sstevel {
816*2305Sstevel ac_mem_test_start_t test_start;
817*2305Sstevel ac_mem_test_stop_t test_stop;
818*2305Sstevel struct mtest_handle handle;
819*2305Sstevel int ret, ret_errno;
820*2305Sstevel int res;
821*2305Sstevel ac_cfga_cmd_t cmd;
822*2305Sstevel char outputstr[AC_OUTPUT_LEN];
823*2305Sstevel
824*2305Sstevel (void) memset((void *)&test_start, 0, sizeof (test_start));
825*2305Sstevel mema_cmd_init(&cmd, &test_start, outputstr, 0);
826*2305Sstevel dump_ioctl(AC_MEM_TEST_START, &test_start);
827*2305Sstevel ret = ioctl(fd, AC_MEM_TEST_START, &cmd);
828*2305Sstevel ret_errno = errno;
829*2305Sstevel dump_ioctl_res(AC_MEM_TEST_START, &test_start, ret, ret_errno);
830*2305Sstevel
831*2305Sstevel if (ret == -1) {
832*2305Sstevel if (ret_errno == ENOTSUP) {
833*2305Sstevel mema_err(&cmd, ret_errno, errstring,
834*2305Sstevel CMD_MEM_TEST_START);
835*2305Sstevel return (CFGA_OPNOTSUPP);
836*2305Sstevel }
837*2305Sstevel if (ret_errno == EBUSY && test_start.tester_pid > 0) {
838*2305Sstevel /*
839*2305Sstevel * Bank appears to be being tested. Check that
840*2305Sstevel * process 'tester_pid' is still running.
841*2305Sstevel */
842*2305Sstevel if (kill(test_start.tester_pid, 0) != -1 ||
843*2305Sstevel errno != ESRCH) {
844*2305Sstevel cfga_ap_log_id_t bname;
845*2305Sstevel
846*2305Sstevel /* Process still exists. */
847*2305Sstevel (void) sprintf(bname, "board %d bank%d",
848*2305Sstevel abkp->board, abkp->bank);
849*2305Sstevel __fmt_errstring(errstring, strlen(bname),
850*2305Sstevel dgettext(TEXT_DOMAIN, still_testing),
851*2305Sstevel bname, test_start.tester_pid);
852*2305Sstevel return (CFGA_ERROR);
853*2305Sstevel }
854*2305Sstevel /*
855*2305Sstevel * Do a test stop and re-try the start.
856*2305Sstevel */
857*2305Sstevel (void) memset((void *)&test_stop, 0,
858*2305Sstevel sizeof (test_stop));
859*2305Sstevel test_stop.handle = test_start.handle;
860*2305Sstevel test_stop.condition = SYSC_CFGA_COND_UNKNOWN;
861*2305Sstevel mema_cmd_init(&cmd, &test_stop, outputstr, 0);
862*2305Sstevel dump_ioctl(AC_MEM_TEST_STOP, &test_stop);
863*2305Sstevel ret = ioctl(fd, AC_MEM_TEST_STOP, &cmd);
864*2305Sstevel ret_errno = errno;
865*2305Sstevel dump_ioctl_res(AC_MEM_TEST_STOP, &test_stop,
866*2305Sstevel ret, ret_errno);
867*2305Sstevel /*
868*2305Sstevel * Ignore test stop error processing and re-try the
869*2305Sstevel * start. The error return will be derived from the
870*2305Sstevel * result of start.
871*2305Sstevel */
872*2305Sstevel (void) memset((void *)&test_start, 0,
873*2305Sstevel sizeof (test_start));
874*2305Sstevel mema_cmd_init(&cmd, &test_start, outputstr, 0);
875*2305Sstevel dump_ioctl(AC_MEM_TEST_START, &test_start);
876*2305Sstevel ret = ioctl(fd, AC_MEM_TEST_START, &cmd);
877*2305Sstevel ret_errno = errno;
878*2305Sstevel dump_ioctl_res(AC_MEM_TEST_START, &test_start,
879*2305Sstevel ret, ret_errno);
880*2305Sstevel }
881*2305Sstevel /* Test return code again to cover the case of a re-try. */
882*2305Sstevel if (ret == -1) {
883*2305Sstevel mema_err(&cmd, ret_errno, errstring,
884*2305Sstevel CMD_MEM_TEST_START);
885*2305Sstevel return (CFGA_ERROR);
886*2305Sstevel }
887*2305Sstevel }
888*2305Sstevel (void) memset((void *)&handle, 0, sizeof (handle));
889*2305Sstevel handle.fd = fd;
890*2305Sstevel handle.drvhandle = (void *)&test_start;
891*2305Sstevel handle.msgp = msgp;
892*2305Sstevel handle.bank_size = test_start.bank_size;
893*2305Sstevel handle.page_size = test_start.page_size;
894*2305Sstevel handle.line_size = test_start.line_size;
895*2305Sstevel handle.lines_per_page = test_start.page_size / test_start.line_size;
896*2305Sstevel handle.condition = CFGA_COND_UNKNOWN;
897*2305Sstevel handle.max_errors = max_errors;
898*2305Sstevel
899*2305Sstevel res = (*mtest_table[test_fun].test_func)(&handle);
900*2305Sstevel
901*2305Sstevel mtest_deallocate_buf_all(&handle);
902*2305Sstevel
903*2305Sstevel /*
904*2305Sstevel * Convert memory test code to MEMA_ code.
905*2305Sstevel */
906*2305Sstevel switch (res) {
907*2305Sstevel case MTEST_DONE:
908*2305Sstevel res = CFGA_OK;
909*2305Sstevel break;
910*2305Sstevel case MTEST_LIB_ERROR:
911*2305Sstevel __fmt_errstring(errstring, 0, dgettext(TEXT_DOMAIN,
912*2305Sstevel mtest_lib_error));
913*2305Sstevel res = CFGA_ERROR;
914*2305Sstevel break;
915*2305Sstevel case MTEST_DEV_ERROR:
916*2305Sstevel __fmt_errstring(errstring, 0, dgettext(TEXT_DOMAIN,
917*2305Sstevel mtest_rw_error));
918*2305Sstevel res = CFGA_ERROR;
919*2305Sstevel break;
920*2305Sstevel default:
921*2305Sstevel __fmt_errstring(errstring, 0, dgettext(TEXT_DOMAIN,
922*2305Sstevel mtest_unknown_error));
923*2305Sstevel res = CFGA_ERROR;
924*2305Sstevel assert(0);
925*2305Sstevel break;
926*2305Sstevel }
927*2305Sstevel
928*2305Sstevel (void) memset((void *)&test_stop, 0, sizeof (test_stop));
929*2305Sstevel test_stop.handle = test_start.handle;
930*2305Sstevel switch (handle.condition) {
931*2305Sstevel case CFGA_COND_OK:
932*2305Sstevel test_stop.condition = SYSC_CFGA_COND_OK;
933*2305Sstevel break;
934*2305Sstevel case CFGA_COND_FAILING:
935*2305Sstevel test_stop.condition = SYSC_CFGA_COND_FAILING;
936*2305Sstevel break;
937*2305Sstevel case CFGA_COND_FAILED:
938*2305Sstevel test_stop.condition = SYSC_CFGA_COND_FAILED;
939*2305Sstevel break;
940*2305Sstevel case CFGA_COND_UNKNOWN:
941*2305Sstevel test_stop.condition = SYSC_CFGA_COND_UNKNOWN;
942*2305Sstevel break;
943*2305Sstevel default:
944*2305Sstevel test_stop.condition = SYSC_CFGA_COND_UNKNOWN;
945*2305Sstevel assert(0);
946*2305Sstevel break;
947*2305Sstevel }
948*2305Sstevel
949*2305Sstevel mema_cmd_init(&cmd, &test_stop, outputstr, 0);
950*2305Sstevel dump_ioctl(AC_MEM_TEST_STOP, &test_stop);
951*2305Sstevel ret = ioctl(fd, AC_MEM_TEST_STOP, &cmd);
952*2305Sstevel ret_errno = errno;
953*2305Sstevel dump_ioctl_res(AC_MEM_TEST_STOP, &test_stop, ret, ret_errno);
954*2305Sstevel if (ret == -1) {
955*2305Sstevel mema_err(&cmd, ret_errno, errstring,
956*2305Sstevel CMD_MEM_TEST_STOP);
957*2305Sstevel return (CFGA_ERROR);
958*2305Sstevel }
959*2305Sstevel return (res);
960*2305Sstevel }
961*2305Sstevel
962*2305Sstevel #define DRVHANDLE(H) (((ac_mem_test_start_t *)(H)->drvhandle)->handle)
963*2305Sstevel
964*2305Sstevel int
mtest_write(mtest_handle_t handle,void * page_buf,u_longlong_t page_no,uint_t line_offset,uint_t line_count)965*2305Sstevel mtest_write(
966*2305Sstevel mtest_handle_t handle,
967*2305Sstevel void *page_buf,
968*2305Sstevel u_longlong_t page_no,
969*2305Sstevel uint_t line_offset,
970*2305Sstevel uint_t line_count)
971*2305Sstevel {
972*2305Sstevel ac_mem_test_write_t test_write;
973*2305Sstevel int fd, ret, ret_errno;
974*2305Sstevel ac_cfga_cmd_t cmd;
975*2305Sstevel char outputstr[AC_OUTPUT_LEN];
976*2305Sstevel
977*2305Sstevel (void) memset((void *)&test_write, 0, sizeof (test_write));
978*2305Sstevel fd = handle->fd;
979*2305Sstevel test_write.handle = DRVHANDLE(handle);
980*2305Sstevel test_write.page_buf = page_buf;
981*2305Sstevel test_write.address.page_num = page_no;
982*2305Sstevel test_write.address.line_offset = line_offset;
983*2305Sstevel if (line_count == 0)
984*2305Sstevel test_write.address.line_count = handle->lines_per_page;
985*2305Sstevel else
986*2305Sstevel test_write.address.line_count = line_count;
987*2305Sstevel
988*2305Sstevel mema_cmd_init(&cmd, &test_write, outputstr, 0);
989*2305Sstevel dump_ioctl(AC_MEM_TEST_WRITE, &test_write);
990*2305Sstevel ret = ioctl(fd, AC_MEM_TEST_WRITE, &cmd);
991*2305Sstevel ret_errno = errno;
992*2305Sstevel dump_ioctl_res(AC_MEM_TEST_WRITE, &test_write, ret, ret_errno);
993*2305Sstevel
994*2305Sstevel if (ret == -1)
995*2305Sstevel return (-1);
996*2305Sstevel return (0);
997*2305Sstevel }
998*2305Sstevel
999*2305Sstevel int
mtest_read(mtest_handle_t handle,void * page_buf,u_longlong_t page_no,uint_t line_offset,uint_t line_count,struct mtest_error * errp)1000*2305Sstevel mtest_read(
1001*2305Sstevel mtest_handle_t handle,
1002*2305Sstevel void *page_buf,
1003*2305Sstevel u_longlong_t page_no,
1004*2305Sstevel uint_t line_offset,
1005*2305Sstevel uint_t line_count,
1006*2305Sstevel struct mtest_error *errp)
1007*2305Sstevel {
1008*2305Sstevel ac_mem_test_read_t test_read;
1009*2305Sstevel sunfire_processor_error_regs_t errbuf;
1010*2305Sstevel int fd, ret, ret_errno;
1011*2305Sstevel ac_cfga_cmd_t cmd;
1012*2305Sstevel char outputstr[AC_OUTPUT_LEN];
1013*2305Sstevel
1014*2305Sstevel (void) memset((void *)&test_read, 0, sizeof (test_read));
1015*2305Sstevel (void) memset((void *)&errbuf, 0, sizeof (errbuf));
1016*2305Sstevel fd = handle->fd;
1017*2305Sstevel test_read.handle = DRVHANDLE(handle);
1018*2305Sstevel test_read.page_buf = page_buf;
1019*2305Sstevel test_read.address.page_num = page_no;
1020*2305Sstevel test_read.address.line_offset = line_offset;
1021*2305Sstevel test_read.error_buf = &errbuf;
1022*2305Sstevel if (line_count == 0)
1023*2305Sstevel test_read.address.line_count = handle->lines_per_page;
1024*2305Sstevel else
1025*2305Sstevel test_read.address.line_count = line_count;
1026*2305Sstevel
1027*2305Sstevel mema_cmd_init(&cmd, &test_read, outputstr, 0);
1028*2305Sstevel dump_ioctl(AC_MEM_TEST_READ, &test_read);
1029*2305Sstevel ret = ioctl(fd, AC_MEM_TEST_READ, &cmd);
1030*2305Sstevel ret_errno = errno;
1031*2305Sstevel dump_ioctl_res(AC_MEM_TEST_READ, &test_read, ret, ret_errno);
1032*2305Sstevel
1033*2305Sstevel if (ret == -1) {
1034*2305Sstevel if (ret_errno == EIO) {
1035*2305Sstevel /*
1036*2305Sstevel * Special case indicating CE or UE.
1037*2305Sstevel */
1038*2305Sstevel if (((errbuf.udbh_error_reg | errbuf.udbl_error_reg) &
1039*2305Sstevel P_DER_UE) != 0)
1040*2305Sstevel errp->error_type = MTEST_ERR_UE;
1041*2305Sstevel else
1042*2305Sstevel errp->error_type = MTEST_ERR_CE;
1043*2305Sstevel } else {
1044*2305Sstevel return (-1);
1045*2305Sstevel }
1046*2305Sstevel } else {
1047*2305Sstevel errp->error_type = MTEST_ERR_NONE;
1048*2305Sstevel }
1049*2305Sstevel return (0);
1050*2305Sstevel }
1051*2305Sstevel
1052*2305Sstevel static char *
subopt_help_str(char * opts[])1053*2305Sstevel subopt_help_str(char *opts[])
1054*2305Sstevel {
1055*2305Sstevel char *str;
1056*2305Sstevel const char *sep;
1057*2305Sstevel int len;
1058*2305Sstevel int i, n;
1059*2305Sstevel static const char help_sep[] = ", ";
1060*2305Sstevel static const char help_nil[] = "???";
1061*2305Sstevel
1062*2305Sstevel len = 0;
1063*2305Sstevel n = 0;
1064*2305Sstevel for (i = 0; opts[i] != NULL; i++) {
1065*2305Sstevel n++;
1066*2305Sstevel len += strlen(opts[i]);
1067*2305Sstevel }
1068*2305Sstevel if (n == 0)
1069*2305Sstevel return (strdup(help_nil));
1070*2305Sstevel len += (n - 1) * strlen(help_sep);
1071*2305Sstevel len++;
1072*2305Sstevel str = (char *)malloc(len);
1073*2305Sstevel if (str == NULL)
1074*2305Sstevel return (NULL);
1075*2305Sstevel *str = '\0';
1076*2305Sstevel sep = "";
1077*2305Sstevel for (i = 0; opts[i] != NULL; i++) {
1078*2305Sstevel (void) strcat(str, sep);
1079*2305Sstevel (void) strcat(str, opts[i]);
1080*2305Sstevel sep = help_sep;
1081*2305Sstevel }
1082*2305Sstevel return (str);
1083*2305Sstevel }
1084*2305Sstevel
1085*2305Sstevel /*ARGSUSED*/
1086*2305Sstevel cfga_err_t
cfga_test(const char * ap_id,const char * options,struct cfga_msg * msgp,char ** errstring,cfga_flags_t flags)1087*2305Sstevel cfga_test(
1088*2305Sstevel const char *ap_id,
1089*2305Sstevel const char *options,
1090*2305Sstevel struct cfga_msg *msgp,
1091*2305Sstevel char **errstring,
1092*2305Sstevel cfga_flags_t flags)
1093*2305Sstevel {
1094*2305Sstevel mema_bank_t bk;
1095*2305Sstevel ac_stat_t stat;
1096*2305Sstevel int test_fun = -1;
1097*2305Sstevel int fd, ret;
1098*2305Sstevel int maxerr_idx;
1099*2305Sstevel long max_errors = -1;
1100*2305Sstevel char *ret_p;
1101*2305Sstevel
1102*2305Sstevel if (errstring != NULL)
1103*2305Sstevel *errstring = NULL;
1104*2305Sstevel
1105*2305Sstevel /*
1106*2305Sstevel * Decode test level and max error number.
1107*2305Sstevel */
1108*2305Sstevel if (options != NULL && *options != '\0') {
1109*2305Sstevel char **opts;
1110*2305Sstevel char *value;
1111*2305Sstevel char *cp, *free_cp;
1112*2305Sstevel int subopt;
1113*2305Sstevel
1114*2305Sstevel /* getsubopt() modifies the input string, so copy it. */
1115*2305Sstevel cp = strdup(options);
1116*2305Sstevel if (cp == NULL) {
1117*2305Sstevel return (CFGA_LIB_ERROR);
1118*2305Sstevel }
1119*2305Sstevel free_cp = cp;
1120*2305Sstevel opts = mtest_build_opts(&maxerr_idx);
1121*2305Sstevel if (opts == NULL) {
1122*2305Sstevel free((void *)free_cp);
1123*2305Sstevel return (CFGA_LIB_ERROR);
1124*2305Sstevel }
1125*2305Sstevel
1126*2305Sstevel while (*cp != '\0') {
1127*2305Sstevel subopt = getsubopt(&cp, opts, &value);
1128*2305Sstevel if (subopt == -1) {
1129*2305Sstevel char *hlp;
1130*2305Sstevel
1131*2305Sstevel hlp = subopt_help_str(opts);
1132*2305Sstevel if (hlp != NULL) {
1133*2305Sstevel __fmt_errstring(errstring,
1134*2305Sstevel strlen(value) + strlen(hlp),
1135*2305Sstevel dgettext(TEXT_DOMAIN, unk_test),
1136*2305Sstevel value, hlp);
1137*2305Sstevel free((void *)hlp);
1138*2305Sstevel } else {
1139*2305Sstevel __fmt_errstring(errstring, 20,
1140*2305Sstevel dgettext(TEXT_DOMAIN, calloc_fail),
1141*2305Sstevel strlen(options) + 1, 1);
1142*2305Sstevel }
1143*2305Sstevel /* Free after printing value. */
1144*2305Sstevel free((void *)free_cp);
1145*2305Sstevel return (CFGA_ERROR);
1146*2305Sstevel }
1147*2305Sstevel
1148*2305Sstevel if (test_fun != -1 && subopt != test_fun &&
1149*2305Sstevel subopt != maxerr_idx) {
1150*2305Sstevel __fmt_errstring(errstring,
1151*2305Sstevel strlen(opts[subopt]),
1152*2305Sstevel dgettext(TEXT_DOMAIN, dup_test),
1153*2305Sstevel opts[subopt]);
1154*2305Sstevel free((void *)free_cp);
1155*2305Sstevel return (CFGA_ERROR);
1156*2305Sstevel }
1157*2305Sstevel
1158*2305Sstevel if (subopt < maxerr_idx)
1159*2305Sstevel test_fun = subopt;
1160*2305Sstevel else {
1161*2305Sstevel
1162*2305Sstevel if (max_errors != -1 && subopt == maxerr_idx) {
1163*2305Sstevel __fmt_errstring(errstring,
1164*2305Sstevel strlen(opts[subopt]),
1165*2305Sstevel dgettext(TEXT_DOMAIN, dup_num),
1166*2305Sstevel opts[subopt]);
1167*2305Sstevel free((void *)free_cp);
1168*2305Sstevel return (CFGA_ERROR);
1169*2305Sstevel }
1170*2305Sstevel
1171*2305Sstevel if (value == NULL) {
1172*2305Sstevel __fmt_errstring(errstring,
1173*2305Sstevel 0,
1174*2305Sstevel dgettext(TEXT_DOMAIN, no_num),
1175*2305Sstevel "");
1176*2305Sstevel free((void *)free_cp);
1177*2305Sstevel return (CFGA_ERROR);
1178*2305Sstevel }
1179*2305Sstevel
1180*2305Sstevel max_errors = strtol(value, &ret_p, 10);
1181*2305Sstevel if ((ret_p == value) || (*ret_p != '\0') ||
1182*2305Sstevel (max_errors < 0)) {
1183*2305Sstevel __fmt_errstring(errstring,
1184*2305Sstevel strlen(value),
1185*2305Sstevel dgettext(TEXT_DOMAIN, no_num),
1186*2305Sstevel value);
1187*2305Sstevel free((void *)free_cp);
1188*2305Sstevel return (CFGA_ERROR);
1189*2305Sstevel }
1190*2305Sstevel }
1191*2305Sstevel }
1192*2305Sstevel free((void *)free_cp);
1193*2305Sstevel }
1194*2305Sstevel
1195*2305Sstevel if (test_fun == -1)
1196*2305Sstevel test_fun = MTEST_DEFAULT_TEST;
1197*2305Sstevel if (max_errors == -1)
1198*2305Sstevel max_errors = MAX_ERRORS;
1199*2305Sstevel
1200*2305Sstevel ret = ap_stat(ap_id, &fd, &bk, &stat, errstring);
1201*2305Sstevel if (ret != CFGA_OK)
1202*2305Sstevel return (ret);
1203*2305Sstevel
1204*2305Sstevel if (stat.rstate != SYSC_CFGA_RSTATE_CONNECTED ||
1205*2305Sstevel stat.ostate != SYSC_CFGA_OSTATE_UNCONFIGURED) {
1206*2305Sstevel __fmt_errstring(errstring, 0,
1207*2305Sstevel dgettext(TEXT_DOMAIN, trans_illegal));
1208*2305Sstevel (void) close(fd);
1209*2305Sstevel return (CFGA_ERROR);
1210*2305Sstevel }
1211*2305Sstevel
1212*2305Sstevel ret = mtest_run(fd, test_fun, &bk,
1213*2305Sstevel ((flags & CFGA_FLAG_VERBOSE) != 0) ? msgp : NULL, errstring,
1214*2305Sstevel (ulong_t)max_errors);
1215*2305Sstevel
1216*2305Sstevel (void) close(fd);
1217*2305Sstevel
1218*2305Sstevel return (ret);
1219*2305Sstevel }
1220*2305Sstevel
1221*2305Sstevel static cfga_stat_t
rstate_cvt(sysc_cfga_rstate_t rs)1222*2305Sstevel rstate_cvt(sysc_cfga_rstate_t rs)
1223*2305Sstevel {
1224*2305Sstevel cfga_stat_t cs;
1225*2305Sstevel
1226*2305Sstevel switch (rs) {
1227*2305Sstevel case SYSC_CFGA_RSTATE_EMPTY:
1228*2305Sstevel cs = CFGA_STAT_EMPTY;
1229*2305Sstevel break;
1230*2305Sstevel case SYSC_CFGA_RSTATE_DISCONNECTED:
1231*2305Sstevel cs = CFGA_STAT_DISCONNECTED;
1232*2305Sstevel break;
1233*2305Sstevel case SYSC_CFGA_RSTATE_CONNECTED:
1234*2305Sstevel cs = CFGA_STAT_CONNECTED;
1235*2305Sstevel break;
1236*2305Sstevel default:
1237*2305Sstevel cs = CFGA_STAT_NONE;
1238*2305Sstevel break;
1239*2305Sstevel }
1240*2305Sstevel
1241*2305Sstevel return (cs);
1242*2305Sstevel }
1243*2305Sstevel
1244*2305Sstevel static cfga_stat_t
ostate_cvt(sysc_cfga_ostate_t os)1245*2305Sstevel ostate_cvt(sysc_cfga_ostate_t os)
1246*2305Sstevel {
1247*2305Sstevel cfga_stat_t cs;
1248*2305Sstevel
1249*2305Sstevel switch (os) {
1250*2305Sstevel case SYSC_CFGA_OSTATE_UNCONFIGURED:
1251*2305Sstevel cs = CFGA_STAT_UNCONFIGURED;
1252*2305Sstevel break;
1253*2305Sstevel case SYSC_CFGA_OSTATE_CONFIGURED:
1254*2305Sstevel cs = CFGA_STAT_CONFIGURED;
1255*2305Sstevel break;
1256*2305Sstevel default:
1257*2305Sstevel cs = CFGA_STAT_NONE;
1258*2305Sstevel break;
1259*2305Sstevel }
1260*2305Sstevel
1261*2305Sstevel return (cs);
1262*2305Sstevel }
1263*2305Sstevel
1264*2305Sstevel static cfga_cond_t
cond_cvt(sysc_cfga_cond_t sc)1265*2305Sstevel cond_cvt(sysc_cfga_cond_t sc)
1266*2305Sstevel {
1267*2305Sstevel cfga_cond_t cc;
1268*2305Sstevel
1269*2305Sstevel switch (sc) {
1270*2305Sstevel case SYSC_CFGA_COND_OK:
1271*2305Sstevel cc = CFGA_COND_OK;
1272*2305Sstevel break;
1273*2305Sstevel case SYSC_CFGA_COND_FAILING:
1274*2305Sstevel cc = CFGA_COND_FAILING;
1275*2305Sstevel break;
1276*2305Sstevel case SYSC_CFGA_COND_FAILED:
1277*2305Sstevel cc = CFGA_COND_FAILED;
1278*2305Sstevel break;
1279*2305Sstevel case SYSC_CFGA_COND_UNUSABLE:
1280*2305Sstevel cc = CFGA_COND_UNUSABLE;
1281*2305Sstevel break;
1282*2305Sstevel case SYSC_CFGA_COND_UNKNOWN:
1283*2305Sstevel default:
1284*2305Sstevel cc = CFGA_COND_UNKNOWN;
1285*2305Sstevel break;
1286*2305Sstevel }
1287*2305Sstevel
1288*2305Sstevel return (cc);
1289*2305Sstevel }
1290*2305Sstevel
1291*2305Sstevel static void
info_set(ac_stat_t * asp,mema_bank_t * bkp,cfga_info_t info)1292*2305Sstevel info_set(ac_stat_t *asp, mema_bank_t *bkp, cfga_info_t info)
1293*2305Sstevel {
1294*2305Sstevel mema_disabled_t disab;
1295*2305Sstevel uint_t board;
1296*2305Sstevel uint_t n;
1297*2305Sstevel u_longlong_t decode;
1298*2305Sstevel uint_t intlv;
1299*2305Sstevel char *f;
1300*2305Sstevel char *end;
1301*2305Sstevel
1302*2305Sstevel end = &info[sizeof (cfga_info_t)];
1303*2305Sstevel *info = NULL;
1304*2305Sstevel
1305*2305Sstevel board = bkp->board;
1306*2305Sstevel
1307*2305Sstevel /* Print the board number in a way that matches the sysctrl AP. */
1308*2305Sstevel info += snprintf(info, end - info, "slot%d", board);
1309*2305Sstevel
1310*2305Sstevel if (asp->real_size == 0) {
1311*2305Sstevel info += snprintf(info, end - info, " empty");
1312*2305Sstevel return;
1313*2305Sstevel }
1314*2305Sstevel
1315*2305Sstevel if ((n = asp->real_size) >= 1024) {
1316*2305Sstevel n /= 1024;
1317*2305Sstevel f = "Gb";
1318*2305Sstevel } else
1319*2305Sstevel f = "Mb";
1320*2305Sstevel info += snprintf(info, end - info, " %d%s", n, f);
1321*2305Sstevel
1322*2305Sstevel if (asp->rstate == SYSC_CFGA_RSTATE_CONNECTED &&
1323*2305Sstevel asp->ostate == SYSC_CFGA_OSTATE_CONFIGURED &&
1324*2305Sstevel asp->use_size != asp->real_size) {
1325*2305Sstevel if ((n = asp->use_size) >= 1024) {
1326*2305Sstevel n /= 1024;
1327*2305Sstevel f = "Gb";
1328*2305Sstevel } else
1329*2305Sstevel f = "Mb";
1330*2305Sstevel info += snprintf(info, end - info, " (%d%s used)", n, f);
1331*2305Sstevel }
1332*2305Sstevel
1333*2305Sstevel if (bkp->bank == 0)
1334*2305Sstevel decode = asp->ac_decode0;
1335*2305Sstevel else
1336*2305Sstevel decode = asp->ac_decode1;
1337*2305Sstevel
1338*2305Sstevel info += snprintf(info, end - info, " base 0x%llx",
1339*2305Sstevel GRP_REALBASE(decode));
1340*2305Sstevel
1341*2305Sstevel if (bkp->bank == 0)
1342*2305Sstevel intlv = INTLV0(asp->ac_memctl);
1343*2305Sstevel else
1344*2305Sstevel intlv = INTLV1(asp->ac_memctl);
1345*2305Sstevel
1346*2305Sstevel if (intlv != 1)
1347*2305Sstevel info += snprintf(info, end - info, " interleaved %u-way",
1348*2305Sstevel intlv);
1349*2305Sstevel
1350*2305Sstevel if (prom_read_disabled_list(&disab, board)) {
1351*2305Sstevel if (disab != 0) {
1352*2305Sstevel info += snprintf(info, end - info, " disabled at boot");
1353*2305Sstevel }
1354*2305Sstevel
1355*2305Sstevel }
1356*2305Sstevel
1357*2305Sstevel if (asp->rstate == SYSC_CFGA_RSTATE_CONNECTED &&
1358*2305Sstevel asp->ostate == SYSC_CFGA_OSTATE_CONFIGURED &&
1359*2305Sstevel asp->nonrelocatable)
1360*2305Sstevel info += snprintf(info, end - info, " permanent");
1361*2305Sstevel }
1362*2305Sstevel
1363*2305Sstevel static void
mema_cvt(ac_stat_t * ac,mema_bank_t * bkp,cfga_stat_data_t * cs)1364*2305Sstevel mema_cvt(ac_stat_t *ac, mema_bank_t *bkp, cfga_stat_data_t *cs)
1365*2305Sstevel {
1366*2305Sstevel (void) strcpy(cs->ap_type, "memory");
1367*2305Sstevel cs->ap_r_state = rstate_cvt(ac->rstate);
1368*2305Sstevel cs->ap_o_state = ostate_cvt(ac->ostate);
1369*2305Sstevel cs->ap_cond = cond_cvt(ac->condition);
1370*2305Sstevel cs->ap_busy = (cfga_busy_t)ac->busy;
1371*2305Sstevel cs->ap_status_time = ac->status_time;
1372*2305Sstevel info_set(ac, bkp, cs->ap_info);
1373*2305Sstevel cs->ap_log_id[0] = NULL;
1374*2305Sstevel cs->ap_phys_id[0] = NULL;
1375*2305Sstevel }
1376*2305Sstevel
1377*2305Sstevel /*ARGSUSED*/
1378*2305Sstevel cfga_err_t
cfga_stat(const char * ap_id,struct cfga_stat_data * cs,const char * options,char ** errstring)1379*2305Sstevel cfga_stat(
1380*2305Sstevel const char *ap_id,
1381*2305Sstevel struct cfga_stat_data *cs,
1382*2305Sstevel const char *options,
1383*2305Sstevel char **errstring)
1384*2305Sstevel {
1385*2305Sstevel int ret;
1386*2305Sstevel mema_bank_t bk;
1387*2305Sstevel ac_stat_t stat;
1388*2305Sstevel option_set_t do_option;
1389*2305Sstevel
1390*2305Sstevel if (errstring != NULL)
1391*2305Sstevel *errstring = NULL;
1392*2305Sstevel
1393*2305Sstevel ret = 0;
1394*2305Sstevel do_option = process_options(options, stat_opts, &ret, errstring);
1395*2305Sstevel if (ret != 0)
1396*2305Sstevel return (ret);
1397*2305Sstevel
1398*2305Sstevel ret = ap_stat(ap_id, NULL, &bk, &stat, errstring);
1399*2305Sstevel if (ret != CFGA_OK)
1400*2305Sstevel return (ret);
1401*2305Sstevel
1402*2305Sstevel mema_cvt(&stat, &bk, cs);
1403*2305Sstevel
1404*2305Sstevel ret = prom_do_options(do_option, bk.board, &stat, errstring);
1405*2305Sstevel
1406*2305Sstevel return (ret);
1407*2305Sstevel }
1408*2305Sstevel
1409*2305Sstevel /*ARGSUSED*/
1410*2305Sstevel cfga_err_t
cfga_list(const char * ap_id,cfga_stat_data_t ** ap_list,int * nlist,const char * options,char ** errstring)1411*2305Sstevel cfga_list(
1412*2305Sstevel const char *ap_id,
1413*2305Sstevel cfga_stat_data_t **ap_list,
1414*2305Sstevel int *nlist,
1415*2305Sstevel const char *options,
1416*2305Sstevel char **errstring)
1417*2305Sstevel {
1418*2305Sstevel if (errstring != NULL)
1419*2305Sstevel *errstring = NULL;
1420*2305Sstevel
1421*2305Sstevel return (CFGA_NOTSUPP);
1422*2305Sstevel }
1423*2305Sstevel
1424*2305Sstevel /*
1425*2305Sstevel * cfga_ap_id_cmp -- use default_ap_id_cmp() in libcfgadm
1426*2305Sstevel */
1427*2305Sstevel
1428*2305Sstevel /*ARGSUSED*/
1429*2305Sstevel cfga_err_t
cfga_help(struct cfga_msg * msgp,const char * options,cfga_flags_t flags)1430*2305Sstevel cfga_help(struct cfga_msg *msgp, const char *options, cfga_flags_t flags)
1431*2305Sstevel {
1432*2305Sstevel
1433*2305Sstevel
1434*2305Sstevel (*msgp->message_routine)(msgp->appdata_ptr, mema_help);
1435*2305Sstevel (*msgp->message_routine)(msgp->appdata_ptr, disable_opts);
1436*2305Sstevel (*msgp->message_routine)(msgp->appdata_ptr, enable_opts);
1437*2305Sstevel (*msgp->message_routine)(msgp->appdata_ptr, timeout_opts);
1438*2305Sstevel (*msgp->message_routine)(msgp->appdata_ptr, test_opts);
1439*2305Sstevel (*msgp->message_routine)(msgp->appdata_ptr, private_funcs);
1440*2305Sstevel
1441*2305Sstevel return (CFGA_OK);
1442*2305Sstevel }
1443*2305Sstevel
1444*2305Sstevel #if 0
1445*2305Sstevel static ac_mem_version_t
1446*2305Sstevel get_version(int fd)
1447*2305Sstevel {
1448*2305Sstevel ac_mem_version_t ver;
1449*2305Sstevel int ret, ret_errno;
1450*2305Sstevel
1451*2305Sstevel ver = 0;
1452*2305Sstevel dump_ioctl(AC_MEM_ADMIN_VER, &ver);
1453*2305Sstevel ret = ioctl(fd, AC_MEM_ADMIN_VER, &ver);
1454*2305Sstevel ret_errno = errno;
1455*2305Sstevel dump_ioctl_res(AC_MEM_ADMIN_VER, &ver, ret, ret_errno);
1456*2305Sstevel return (ver);
1457*2305Sstevel }
1458*2305Sstevel #endif
1459*2305Sstevel
1460*2305Sstevel static char *
opt_help_str(struct opt_control * opts)1461*2305Sstevel opt_help_str(struct opt_control *opts)
1462*2305Sstevel {
1463*2305Sstevel char *str;
1464*2305Sstevel const char *sep;
1465*2305Sstevel int len;
1466*2305Sstevel int i, n;
1467*2305Sstevel static const char help_sep[] = ", ";
1468*2305Sstevel static const char help_nil[] = "???";
1469*2305Sstevel
1470*2305Sstevel len = 0;
1471*2305Sstevel n = 0;
1472*2305Sstevel for (i = 0; opts[i].subopt != -1; i++) {
1473*2305Sstevel n++;
1474*2305Sstevel len += strlen(mema_opts[opts[i].subopt]);
1475*2305Sstevel }
1476*2305Sstevel if (n == 0)
1477*2305Sstevel return (strdup(help_nil));
1478*2305Sstevel len += (n - 1) * strlen(help_sep);
1479*2305Sstevel len++;
1480*2305Sstevel str = (char *)malloc(len);
1481*2305Sstevel if (str == NULL)
1482*2305Sstevel return (NULL);
1483*2305Sstevel *str = '\0';
1484*2305Sstevel sep = "";
1485*2305Sstevel for (i = 0; opts[i].subopt != -1; i++) {
1486*2305Sstevel (void) strcat(str, sep);
1487*2305Sstevel (void) strcat(str, mema_opts[opts[i].subopt]);
1488*2305Sstevel sep = help_sep;
1489*2305Sstevel }
1490*2305Sstevel return (str);
1491*2305Sstevel }
1492*2305Sstevel
1493*2305Sstevel static option_set_t
process_options(const char * options,struct opt_control * opts,int * retp,char ** errstring)1494*2305Sstevel process_options(
1495*2305Sstevel const char *options,
1496*2305Sstevel struct opt_control *opts,
1497*2305Sstevel int *retp,
1498*2305Sstevel char **errstring)
1499*2305Sstevel {
1500*2305Sstevel option_set_t opt_set;
1501*2305Sstevel char *optcopy, *optcopy_alloc;
1502*2305Sstevel char *value;
1503*2305Sstevel int subopt;
1504*2305Sstevel int subopt_err;
1505*2305Sstevel int i;
1506*2305Sstevel int group;
1507*2305Sstevel int need_value;
1508*2305Sstevel
1509*2305Sstevel OPTSET_INIT(opt_set);
1510*2305Sstevel
1511*2305Sstevel if (options == NULL || *options == '\0') {
1512*2305Sstevel return (opt_set);
1513*2305Sstevel }
1514*2305Sstevel
1515*2305Sstevel optcopy = optcopy_alloc = strdup(options);
1516*2305Sstevel if (optcopy_alloc == NULL) {
1517*2305Sstevel __fmt_errstring(errstring, 20,
1518*2305Sstevel dgettext(TEXT_DOMAIN, calloc_fail), strlen(options) + 1, 1);
1519*2305Sstevel *retp = CFGA_LIB_ERROR;
1520*2305Sstevel return (opt_set);
1521*2305Sstevel }
1522*2305Sstevel
1523*2305Sstevel subopt_err = 0;
1524*2305Sstevel while (*optcopy != '\0' && subopt_err == 0) {
1525*2305Sstevel subopt = getsubopt(&optcopy, mema_opts, &value);
1526*2305Sstevel if (subopt == -1) {
1527*2305Sstevel char *hlp;
1528*2305Sstevel
1529*2305Sstevel hlp = opt_help_str(opts);
1530*2305Sstevel __fmt_errstring(errstring, strlen(value) + strlen(hlp),
1531*2305Sstevel dgettext(TEXT_DOMAIN, unk_subopt), value, hlp);
1532*2305Sstevel free((void *)hlp);
1533*2305Sstevel subopt_err = 1;
1534*2305Sstevel break;
1535*2305Sstevel }
1536*2305Sstevel for (i = 0; opts[i].subopt != -1; i++) {
1537*2305Sstevel if (opts[i].subopt == subopt) {
1538*2305Sstevel group = opts[i].group;
1539*2305Sstevel break;
1540*2305Sstevel }
1541*2305Sstevel }
1542*2305Sstevel if (opts[i].subopt == -1) {
1543*2305Sstevel char *hlp;
1544*2305Sstevel
1545*2305Sstevel hlp = opt_help_str(opts);
1546*2305Sstevel __fmt_errstring(errstring,
1547*2305Sstevel MAX_OPT_LENGTH + strlen(hlp),
1548*2305Sstevel dgettext(TEXT_DOMAIN, not_valid),
1549*2305Sstevel mema_opts[subopt], hlp);
1550*2305Sstevel free((void *)hlp);
1551*2305Sstevel subopt_err = 1;
1552*2305Sstevel break;
1553*2305Sstevel }
1554*2305Sstevel need_value = OPT_NEEDS_VALUE(subopt);
1555*2305Sstevel if (!need_value && value != NULL) {
1556*2305Sstevel __fmt_errstring(errstring, MAX_OPT_LENGTH,
1557*2305Sstevel dgettext(TEXT_DOMAIN, no_value),
1558*2305Sstevel mema_opts[subopt]);
1559*2305Sstevel subopt_err = 1;
1560*2305Sstevel break;
1561*2305Sstevel }
1562*2305Sstevel if (need_value && value == NULL) {
1563*2305Sstevel __fmt_errstring(errstring, MAX_OPT_LENGTH,
1564*2305Sstevel dgettext(TEXT_DOMAIN, missing_value),
1565*2305Sstevel mema_opts[subopt]);
1566*2305Sstevel subopt_err = 1;
1567*2305Sstevel break;
1568*2305Sstevel }
1569*2305Sstevel if (OPTSET_TEST(opt_set, subopt)) {
1570*2305Sstevel /* Ignore repeated options. */
1571*2305Sstevel continue;
1572*2305Sstevel }
1573*2305Sstevel if (group != 0 && !OPTSET_IS_EMPTY(opt_set)) {
1574*2305Sstevel for (i = 0; opts[i].subopt != -1; i++) {
1575*2305Sstevel if (i == subopt)
1576*2305Sstevel continue;
1577*2305Sstevel if (opts[i].group == group &&
1578*2305Sstevel OPTSET_TEST(opt_set, opts[i].subopt))
1579*2305Sstevel break;
1580*2305Sstevel }
1581*2305Sstevel if (opts[i].subopt != -1) {
1582*2305Sstevel __fmt_errstring(errstring, MAX_OPT_LENGTH * 2,
1583*2305Sstevel dgettext(TEXT_DOMAIN, conflict_opt),
1584*2305Sstevel mema_opts[subopt],
1585*2305Sstevel mema_opts[opts[i].subopt]);
1586*2305Sstevel subopt_err = 1;
1587*2305Sstevel break;
1588*2305Sstevel }
1589*2305Sstevel }
1590*2305Sstevel OPTSET_SET_VAL(opt_set, subopt, value);
1591*2305Sstevel }
1592*2305Sstevel free((void *)optcopy_alloc);
1593*2305Sstevel if (subopt_err) {
1594*2305Sstevel *retp = CFGA_ERROR;
1595*2305Sstevel }
1596*2305Sstevel
1597*2305Sstevel return (opt_set);
1598*2305Sstevel }
1599*2305Sstevel
1600*2305Sstevel #ifdef DEV_DEBUG
1601*2305Sstevel
1602*2305Sstevel static int
debugging(void)1603*2305Sstevel debugging(void)
1604*2305Sstevel {
1605*2305Sstevel char *ep;
1606*2305Sstevel static int inited;
1607*2305Sstevel
1608*2305Sstevel if (inited)
1609*2305Sstevel return (debug_fp != NULL);
1610*2305Sstevel inited = 1;
1611*2305Sstevel
1612*2305Sstevel if ((ep = getenv("MEMADM_DEBUG")) == NULL) {
1613*2305Sstevel return (0);
1614*2305Sstevel }
1615*2305Sstevel if (*ep == '\0')
1616*2305Sstevel debug_fp = stderr;
1617*2305Sstevel else {
1618*2305Sstevel if ((debug_fp = fopen(ep, "a")) == NULL)
1619*2305Sstevel return (0);
1620*2305Sstevel }
1621*2305Sstevel (void) fprintf(debug_fp, "\nDebug started, pid=%d\n", (int)getpid());
1622*2305Sstevel return (1);
1623*2305Sstevel }
1624*2305Sstevel
1625*2305Sstevel static void
dump_ioctl(int cmd,void * arg)1626*2305Sstevel dump_ioctl(
1627*2305Sstevel int cmd,
1628*2305Sstevel void *arg)
1629*2305Sstevel {
1630*2305Sstevel if (!debugging())
1631*2305Sstevel return;
1632*2305Sstevel
1633*2305Sstevel switch (cmd) {
1634*2305Sstevel case AC_MEM_CONFIGURE:
1635*2305Sstevel (void) fprintf(debug_fp, "IOCTL: AC_MEM_CONFIGURE\n");
1636*2305Sstevel break;
1637*2305Sstevel
1638*2305Sstevel case AC_MEM_UNCONFIGURE:
1639*2305Sstevel (void) fprintf(debug_fp, "IOCTL: AC_MEM_UNCONFIGURE\n");
1640*2305Sstevel break;
1641*2305Sstevel
1642*2305Sstevel case AC_MEM_TEST_START:
1643*2305Sstevel (void) fprintf(debug_fp, "IOCTL: AC_MEM_TEST_START\n");
1644*2305Sstevel break;
1645*2305Sstevel
1646*2305Sstevel case AC_MEM_TEST_STOP: {
1647*2305Sstevel ac_mem_test_stop_t *tstop;
1648*2305Sstevel
1649*2305Sstevel tstop = (ac_mem_test_stop_t *)arg;
1650*2305Sstevel (void) fprintf(debug_fp, "IOCTL: AC_MEM_TEST_STOP handle=%#x "
1651*2305Sstevel "condition=%d\n", tstop->handle, tstop->condition);
1652*2305Sstevel }
1653*2305Sstevel break;
1654*2305Sstevel case AC_MEM_TEST_READ: {
1655*2305Sstevel ac_mem_test_read_t *tread;
1656*2305Sstevel
1657*2305Sstevel tread = (ac_mem_test_read_t *)arg;
1658*2305Sstevel (void) fprintf(debug_fp, "IOCTL: AC_MEM_TEST_READ handle=%#x "
1659*2305Sstevel "buf=%#p page=%#llx off=%#x count=%#x\n",
1660*2305Sstevel tread->handle, tread->page_buf,
1661*2305Sstevel tread->address.page_num,
1662*2305Sstevel tread->address.line_offset, tread->address.line_count);
1663*2305Sstevel }
1664*2305Sstevel break;
1665*2305Sstevel case AC_MEM_TEST_WRITE: {
1666*2305Sstevel ac_mem_test_write_t *twrite;
1667*2305Sstevel
1668*2305Sstevel twrite = (ac_mem_test_write_t *)arg;
1669*2305Sstevel (void) fprintf(debug_fp, "IOCTL: AC_MEM_TEST_WRITE handle=%#x "
1670*2305Sstevel "buf=%#p page=%#llx off=%#x count=%#x\n",
1671*2305Sstevel twrite->handle, twrite->page_buf,
1672*2305Sstevel twrite->address.page_num,
1673*2305Sstevel twrite->address.line_offset, twrite->address.line_count);
1674*2305Sstevel }
1675*2305Sstevel break;
1676*2305Sstevel case AC_MEM_ADMIN_VER:
1677*2305Sstevel (void) fprintf(debug_fp, "IOCTL: AC_MEM_ADMIN_VER:\n");
1678*2305Sstevel break;
1679*2305Sstevel case AC_MEM_STAT:
1680*2305Sstevel (void) fprintf(debug_fp, "IOCTL: AC_MEM_STAT\n");
1681*2305Sstevel break;
1682*2305Sstevel case AC_MEM_EXERCISE: {
1683*2305Sstevel ac_cfga_cmd_t *cmdp;
1684*2305Sstevel
1685*2305Sstevel cmdp = arg;
1686*2305Sstevel (void) fprintf(debug_fp, "IOCTL: AC_MEM_EXERCISE arg=%d\n",
1687*2305Sstevel cmdp->arg);
1688*2305Sstevel break;
1689*2305Sstevel }
1690*2305Sstevel default:
1691*2305Sstevel (void) fprintf(debug_fp, "IOCTL: unknown (%#x)\n", cmd);
1692*2305Sstevel break;
1693*2305Sstevel }
1694*2305Sstevel (void) fflush(debug_fp);
1695*2305Sstevel }
1696*2305Sstevel
1697*2305Sstevel static void
dump_ioctl_res(int cmd,void * arg,int ret,int ret_errno)1698*2305Sstevel dump_ioctl_res(
1699*2305Sstevel int cmd,
1700*2305Sstevel void *arg,
1701*2305Sstevel int ret,
1702*2305Sstevel int ret_errno)
1703*2305Sstevel {
1704*2305Sstevel if (!debugging())
1705*2305Sstevel return;
1706*2305Sstevel
1707*2305Sstevel if (ret == -1) {
1708*2305Sstevel (void) fprintf(debug_fp, "IOCTL failed, \"%s\" (errno=%d)\n",
1709*2305Sstevel strerror(ret_errno), ret_errno);
1710*2305Sstevel (void) fflush(debug_fp);
1711*2305Sstevel return;
1712*2305Sstevel } else {
1713*2305Sstevel (void) fprintf(debug_fp, "IOCTL succeeded, ret=%d\n", ret);
1714*2305Sstevel }
1715*2305Sstevel
1716*2305Sstevel switch (cmd) {
1717*2305Sstevel case AC_MEM_CONFIGURE:
1718*2305Sstevel case AC_MEM_UNCONFIGURE:
1719*2305Sstevel break;
1720*2305Sstevel case AC_MEM_TEST_START: {
1721*2305Sstevel ac_mem_test_start_t *tstart;
1722*2305Sstevel
1723*2305Sstevel tstart = (ac_mem_test_start_t *)arg;
1724*2305Sstevel (void) fprintf(debug_fp, " handle=%#x tester_pid=%d "
1725*2305Sstevel "prev_condition=%d bank_size=%#llx "
1726*2305Sstevel "page_size=%#x line_size=%#x afar_base=%#llx\n",
1727*2305Sstevel tstart->handle, (int)tstart->tester_pid,
1728*2305Sstevel tstart->prev_condition,
1729*2305Sstevel tstart->bank_size, tstart->page_size,
1730*2305Sstevel tstart->line_size, tstart->afar_base);
1731*2305Sstevel }
1732*2305Sstevel break;
1733*2305Sstevel case AC_MEM_TEST_STOP:
1734*2305Sstevel break;
1735*2305Sstevel case AC_MEM_TEST_READ: {
1736*2305Sstevel ac_mem_test_read_t *tread;
1737*2305Sstevel sunfire_processor_error_regs_t *err;
1738*2305Sstevel
1739*2305Sstevel tread = (ac_mem_test_read_t *)arg;
1740*2305Sstevel err = tread->error_buf;
1741*2305Sstevel if (ret_errno == EIO) {
1742*2305Sstevel (void) fprintf(debug_fp, "module_id=%#llx afsr=%#llx "
1743*2305Sstevel "afar=%#llx udbh_error_reg=%#llx "
1744*2305Sstevel "udbl_error_reg=%#llx\n",
1745*2305Sstevel (longlong_t)err->module_id, (longlong_t)err->afsr,
1746*2305Sstevel (longlong_t)err->afar,
1747*2305Sstevel (longlong_t)err->udbh_error_reg,
1748*2305Sstevel (longlong_t)err->udbl_error_reg);
1749*2305Sstevel } else {
1750*2305Sstevel (void) fprintf(debug_fp, "\n");
1751*2305Sstevel }
1752*2305Sstevel }
1753*2305Sstevel break;
1754*2305Sstevel case AC_MEM_TEST_WRITE:
1755*2305Sstevel break;
1756*2305Sstevel case AC_MEM_ADMIN_VER: {
1757*2305Sstevel ac_mem_version_t *ver;
1758*2305Sstevel
1759*2305Sstevel ver = (ac_mem_version_t *)arg;
1760*2305Sstevel (void) fprintf(debug_fp, " version %d\n", *ver);
1761*2305Sstevel }
1762*2305Sstevel break;
1763*2305Sstevel case AC_MEM_STAT: {
1764*2305Sstevel ac_stat_t *tstat;
1765*2305Sstevel
1766*2305Sstevel tstat = (ac_stat_t *)arg;
1767*2305Sstevel (void) fprintf(debug_fp, " rstate=%u ostate=%u "
1768*2305Sstevel "condition=%u status_time=%#lx board=%u\n",
1769*2305Sstevel (uint_t)tstat->rstate, (uint_t)tstat->ostate,
1770*2305Sstevel (uint_t)tstat->condition, (ulong_t)tstat->status_time,
1771*2305Sstevel tstat->board);
1772*2305Sstevel (void) fprintf(debug_fp, " real_size=%u use_size=%u "
1773*2305Sstevel "busy=%u\n",
1774*2305Sstevel tstat->real_size, tstat->use_size, tstat->busy);
1775*2305Sstevel (void) fprintf(debug_fp, " page_size=%#x "
1776*2305Sstevel "phys_pages=%#llx managed=%#llx nonrelocatable=%#llx\n",
1777*2305Sstevel tstat->page_size, (longlong_t)tstat->phys_pages,
1778*2305Sstevel (longlong_t)tstat->managed,
1779*2305Sstevel (longlong_t)tstat->nonrelocatable);
1780*2305Sstevel (void) fprintf(debug_fp, " memctl=%#llx "
1781*2305Sstevel "decode0=%#llx decode1=%#llx\n",
1782*2305Sstevel (longlong_t)tstat->ac_memctl, (longlong_t)tstat->ac_decode0,
1783*2305Sstevel (longlong_t)tstat->ac_decode1);
1784*2305Sstevel }
1785*2305Sstevel break;
1786*2305Sstevel case AC_MEM_EXERCISE: {
1787*2305Sstevel ac_cfga_cmd_t *cmdp;
1788*2305Sstevel
1789*2305Sstevel cmdp = arg;
1790*2305Sstevel switch (cmdp->arg) {
1791*2305Sstevel case AC_MEMX_RELOCATE_ALL: {
1792*2305Sstevel struct ac_memx_relocate_stats *stp;
1793*2305Sstevel
1794*2305Sstevel if ((stp = cmdp->private) != NULL) {
1795*2305Sstevel (void) fprintf(debug_fp, " base=%u npgs=%u"
1796*2305Sstevel " nopaget=%u nolock=%u isfree=%u reloc=%u"
1797*2305Sstevel " noreloc=%u\n",
1798*2305Sstevel stp->base, stp->npgs, stp->nopaget,
1799*2305Sstevel stp->nolock, stp->isfree, stp->reloc,
1800*2305Sstevel stp->noreloc);
1801*2305Sstevel }
1802*2305Sstevel break;
1803*2305Sstevel }
1804*2305Sstevel default:
1805*2305Sstevel break;
1806*2305Sstevel }
1807*2305Sstevel break;
1808*2305Sstevel }
1809*2305Sstevel default:
1810*2305Sstevel break;
1811*2305Sstevel }
1812*2305Sstevel (void) fflush(debug_fp);
1813*2305Sstevel }
1814*2305Sstevel #endif /* DEV_DEBUG */
1815