Annotation of sys/arch/solbourne/solbourne/prom_machdep.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: prom_machdep.c,v 1.1 2005/04/19 21:30:18 miod Exp $ */
2: /*
3: * Copyright (c) 2005, Miodrag Vallat
4: *
5: * Redistribution and use in source and binary forms, with or without
6: * modification, are permitted provided that the following conditions
7: * are met:
8: * 1. Redistributions of source code must retain the above copyright
9: * notice, this list of conditions and the following disclaimer.
10: * 2. Redistributions in binary form must reproduce the above copyright
11: * notice, this list of conditions and the following disclaimer in the
12: * documentation and/or other materials provided with the distribution.
13: *
14: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
15: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17: * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
18: * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19: * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
20: * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
22: * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
23: * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24: * POSSIBILITY OF SUCH DAMAGE.
25: */
26:
27: /*
28: * Routines to hide the Solbourne PROM specifics.
29: */
30:
31: #include <sys/param.h>
32: #include <sys/systm.h>
33:
34: #include <machine/autoconf.h>
35: #include <machine/bsd_openprom.h> /* romboot() prototype */
36: #include <machine/idt.h>
37: #include <machine/kap.h>
38: #include <machine/prom.h>
39:
40: #include <uvm/uvm_extern.h>
41:
42: #include <sparc/sparc/asm.h>
43:
44: int sysmodel;
45:
46: void myetheraddr(u_char *);
47: void prom_map(void);
48: void prom_unmap(void);
49:
50: extern void tlb_flush_all(void);
51:
52: /*
53: * Lookup a variable in the environment strings.
54: */
55: const char *
56: prom_getenv(const char *var)
57: {
58: u_int i;
59: const char *eq, *env;
60: size_t len;
61: extern char **prom_environ;
62:
63: len = strlen(var);
64:
65: for (i = 0; (env = prom_environ[i]) != NULL; i++) {
66: eq = strchr(env, '=');
67: #ifdef DIAGNOSTIC
68: if (eq == NULL)
69: continue; /* can't happen */
70: #endif
71: if (eq - env != len)
72: continue;
73:
74: if (strncasecmp(var, env, len) == 0) {
75: return (eq + 1);
76: }
77: }
78:
79: return (NULL);
80: }
81:
82: void
83: myetheraddr(u_char *cp)
84: {
85: const char *enetaddr;
86: int i;
87:
88: enetaddr = prom_getenv(ENV_ETHERADDR);
89: if (enetaddr == NULL) {
90: cp[0] = cp[1] = cp[2] = cp[3] = cp[4] = cp[5] = 0xff;
91: } else {
92: for (i = 0; i < 6; i++) {
93: cp[i] = 0;
94: for (;;) {
95: if (*enetaddr >= '0' && *enetaddr <= '9')
96: cp[i] = cp[i] * 0x10 +
97: (*enetaddr - '0');
98: else if (*enetaddr >= 'A' && *enetaddr <= 'F')
99: cp[i] = cp[i] * 0x10 +
100: (*enetaddr + 10 - 'A');
101: else if (*enetaddr >= 'a' && *enetaddr <= 'f')
102: cp[i] = cp[i] * 0x10 +
103: (*enetaddr + 10 - 'a');
104: else
105: break;
106:
107: enetaddr++;
108: }
109: if (*enetaddr++ != ':')
110: break;
111: }
112: /* fill remaining digits if necessary */
113: while (i++ < 6)
114: cp[i] = 0;
115: }
116: }
117:
118: /*
119: * Set up PROM-friendly mappings
120: */
121:
122: void
123: prom_map(void)
124: {
125: sta(0, ASI_PTW0, PTW0_DEFAULT);
126: tlb_flush_all();
127: }
128:
129: void
130: prom_unmap(void)
131: {
132: sta(0, ASI_PTW0, 0);
133: tlb_flush_all();
134: }
135:
136: /*
137: * Prom property access
138: *
139: * Note that if we are passed addresses in the fd va window, we need to
140: * temporarily copy these pointers to a ``safe'' address (in this case,
141: * a global variable, thus in the f0 or f1 window).
142: */
143:
144: int
145: getprop(int node, char *name, void *buf, int bufsiz)
146: {
147: struct prom_node *n = (struct prom_node *)node;
148: struct prom_prop *p;
149: char *propname, *eq;
150: int len, proplen;
151:
152: len = strlen(name);
153:
154: #ifdef DIAGNOSTIC
155: if (node == 0)
156: #if 0
157: node = findroot();
158: #else
159: panic("getprop(%s) invoked on invalid node", name);
160: #endif
161: #endif
162:
163: for (p = (struct prom_prop *)n->pn_props; p != NULL; p = p->pp_next) {
164: propname = p->pp_data;
165: eq = strchr(propname, '=');
166: #ifdef DIAGNOSTIC
167: if (eq == NULL)
168: continue; /* can't happen */
169: #endif
170: if (eq - propname != len)
171: continue;
172:
173: if (strncmp(name, propname, len) == 0) {
174: proplen = p->pp_size;
175: if (proplen > bufsiz) {
176: printf("node %p property %s length %d > %d",
177: node, name, proplen, bufsiz);
178: #ifdef DEBUG
179: panic("getprop");
180: #else
181: return (0);
182: #endif
183: } else
184: bcopy(eq + 1, buf, proplen);
185: break;
186: }
187: }
188:
189: if (p == NULL)
190: proplen = -1;
191:
192: return (proplen);
193: }
194:
195: int
196: getproplen(int node, char *name)
197: {
198: struct prom_node *n = (struct prom_node *)node;
199: struct prom_prop *p;
200: char *propname, *eq;
201: int len, proplen;
202:
203: #ifdef DIAGNOSTIC
204: if (node == 0)
205: panic("getproplen(%s) invoked on invalid node", name);
206: #endif
207:
208: len = strlen(name);
209:
210: for (p = (struct prom_prop *)n->pn_props; p != NULL; p = p->pp_next) {
211: propname = p->pp_data;
212: eq = strchr(propname, '=');
213: #ifdef DIAGNOSTIC
214: if (eq == NULL)
215: continue; /* can't happen */
216: #endif
217: if (eq - propname != len)
218: continue;
219:
220: if (strncmp(name, propname, len) == 0) {
221: proplen = p->pp_size;
222: break;
223: }
224: }
225:
226: if (p == NULL)
227: proplen = -1;
228:
229: return (proplen);
230: }
231:
232: int
233: firstchild(int node)
234: {
235: return ((struct prom_node *)node)->pn_child;
236: }
237:
238: int
239: nextsibling(int node)
240: {
241: if (node == 0)
242: return (findroot());
243: else
244: return (((struct prom_node *)node)->pn_sibling);
245: }
246:
247: int
248: findroot()
249: {
250: struct sb_prom *sp;
251:
252: sp = (struct sb_prom *)PROM_DATA_VA;
253: if (sp->sp_interface >= PROM_INTERFACE)
254: return (sp->sp_rootnode);
255:
256: panic("findroot: PROM communication interface is too old (%d)",
257: sp->sp_interface);
258: /* NOTREACHED */
259: }
260:
261: /*
262: * Shutdown and reboot interface
263: */
264:
265: void
266: romhalt()
267: {
268: struct sb_prom *sp;
269:
270: sp = (struct sb_prom *)PROM_DATA_VA;
271: if (sp->sp_interface >= PROM_INTERFACE) {
272: prom_map();
273: (*sp->sp_interp)("reset " PROM_RESET_HALT);
274: prom_unmap();
275: }
276:
277: panic("PROM exit failed");
278: }
279:
280: void
281: romboot(char *str)
282: {
283: char command[256];
284: struct sb_prom *sp;
285:
286: if (*str != '\0') {
287: strlcpy(command, "boot ", sizeof command);
288: strlcat(command, str, sizeof command);
289: } else {
290: strlcpy(command, "reset ", sizeof command);
291: strlcat(command, PROM_RESET_WARM, sizeof command);
292: }
293:
294: sp = (struct sb_prom *)PROM_DATA_VA;
295: if (sp->sp_interface >= PROM_INTERFACE) {
296: prom_map();
297: (*sp->sp_interp)(command);
298: prom_unmap();
299: }
300:
301: panic("PROM boot failed");
302: }
CVSweb