4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright (c) 1996-1998 by Sun Microsystems, Inc.
24 * All rights reserved.
27 #pragma ident "%Z%%M% %I% %E% SMI"
36 #include <sys/param.h>
37 #include <sys/obpdefs.h>
40 #include <sys/sysctrl.h>
41 #include <sys/openpromio.h>
42 #include "mema_prom.h"
43 #include <config_admin.h>
47 * PROM access routines to get and set disabled lists
48 * Based on code in the usr/src/cmd/eeprom directory.
50 #define PROMDEV "/dev/openprom"
52 * 128 is the size of the largest (currently) property name
53 * 8192 - MAXPROPSIZE - sizeof (int) is the size of the largest
54 * (currently) property value, viz. nvramrc.
55 * the sizeof(u_int) is from struct openpromio
58 #define MAXPROPSIZE 128
59 #define MAXNAMESIZE MAXPROPSIZE
60 #define MAXVALSIZE (8192 - MAXPROPSIZE - sizeof (u_int))
61 #define BUFSIZE (MAXPROPSIZE + MAXVALSIZE + sizeof (u_int))
64 struct openpromio opp
;
66 #define PROP_MEMORY_LIST "disabled-memory-list"
68 static int prom_read_one(mema_disabled_t
*, int, int, char *, u_int
);
69 static int prom_write_one(mema_disabled_t
*, int, int, char *, u_int
);
72 prom_read_disabled_list(mema_disabled_t
*dp
, int bd
)
77 (void) memset(dp
, 0, sizeof (*dp
));
78 prom_fd
= open(PROMDEV
, O_RDONLY
);
82 ret
= prom_read_one(dp
, bd
, prom_fd
,
83 PROP_MEMORY_LIST
, PROM_MEMORY_DISABLED
);
84 (void) close(prom_fd
);
89 prom_write_disabled_list(mema_disabled_t
*dp
, int bd
)
94 prom_fd
= open(PROMDEV
, O_RDWR
);
98 ret
= prom_write_one(dp
, bd
, prom_fd
,
99 PROP_MEMORY_LIST
, PROM_MEMORY_DISABLED
);
100 (void) close(prom_fd
);
113 struct openpromio
*opp
= &oppbuf
.opp
;
116 (void) memset(&oppbuf
, 0, sizeof (oppbuf
));
117 (void) strncpy(opp
->oprom_array
, var
, MAXNAMESIZE
);
118 opp
->oprom_size
= MAXVALSIZE
;
119 if (ioctl(prom_fd
, OPROMGETOPT
, opp
) == -1) {
122 if (opp
->oprom_size
== 0) {
123 /* Not a failure - just not set to anything */
130 for (cp
= opp
->oprom_array
; *cp
!= '\0'; cp
++) {
150 board
= *cp
- 'a' + 10;
158 board
= *cp
- 'A' + 10;
161 /* Ignore bad characters. */
162 /* TODO: maybe should set ret to 0? */
182 struct openpromio
*in_opp
= &in_oppbuf
.opp
;
184 struct openpromio
*opp
= &oppbuf
.opp
;
188 /* Setup output buffer. */
189 (void) memset(&oppbuf
, 0, sizeof (oppbuf
));
190 (void) strncpy(opp
->oprom_array
, var
, MAXNAMESIZE
);
191 opp
->oprom_size
= strlen(var
) + 1;
192 cp
= opp
->oprom_array
+ opp
->oprom_size
;
195 * First read the existing list, filtering out 'bd' if 'bit'
198 (void) memset(&in_oppbuf
, 0, sizeof (in_oppbuf
));
199 (void) strncpy(in_opp
->oprom_array
, var
, MAXNAMESIZE
);
200 in_opp
->oprom_size
= MAXVALSIZE
;
201 if (ioctl(prom_fd
, OPROMGETOPT
, in_opp
) != -1 &&
202 in_opp
->oprom_size
!= 0) {
206 for (icp
= in_opp
->oprom_array
; *icp
!= '\0'; icp
++) {
208 case '0': case '1': case '2': case '3':
209 case '4': case '5': case '6': case '7':
213 case 'a': case 'b': case 'c':
214 case 'd': case 'e': case 'f':
215 board
= *icp
- 'a' + 10;
217 case 'A': case 'B': case 'C':
218 case 'D': case 'E': case 'F':
219 board
= *icp
- 'A' + 10;
222 /* Ignore bad characters. */
225 /* If enabling this board ... */
226 if (board
== bd
&& (*dp
& bit
) == 0)
228 *cp
++ = "0123456789abcdef"[board
];
233 if ((*dp
& bit
) != 0) {
234 *cp
++ = "0123456789abcdef"[bd
];
237 if (ioctl(prom_fd
, OPROMSETOPT
, opp
) == -1) {
247 * The PROM only has board-level disable of memory. If two banks are present
248 * on the board, both are either enabled or disabled at boot.
249 * The caller of this routine must set the PROM_MEMORY_PRESENT bits
250 * before calling this function.
255 prom_viable_disabled_list(mema_disabled_t
*dp
)
260 for (board
= 0; board
< MAX_BOARDS
; board
++) {
261 if ((dp
->bank_A
[board
] & PROM_MEMORY_PRESENT
) != 0 &&
262 (dp
->bank_B
[board
] & PROM_MEMORY_PRESENT
) != 0 &&
263 (dp
->bank_A
[board
] & PROM_MEMORY_DISABLED
) !=
264 (dp
->bank_B
[board
] & PROM_MEMORY_DISABLED
)) {