Annotation of sys/arch/alpha/stand/netboot/if_prom.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: if_prom.c,v 1.3 1997/05/05 06:02:01 millert Exp $ */
2: /* $NetBSD: if_prom.c,v 1.9 1997/04/06 08:41:26 cgd Exp $ */
3:
4: /*
5: * Copyright (c) 1997 Christopher G. Demetriou. All rights reserved.
6: * Copyright (c) 1993 Adam Glass. All rights reserved.
7: *
8: * Redistribution and use in source and binary forms, with or without
9: * modification, are permitted provided that the following conditions
10: * are met:
11: * 1. Redistributions of source code must retain the above copyright
12: * notice, this list of conditions and the following disclaimer.
13: * 2. Redistributions in binary form must reproduce the above copyright
14: * notice, this list of conditions and the following disclaimer in the
15: * documentation and/or other materials provided with the distribution.
16: * 3. All advertising materials mentioning features or use of this software
17: * must display the following acknowledgement:
18: * This product includes software developed by Adam Glass.
19: * 4. The name of the Author may not be used to endorse or promote products
20: * derived from this software without specific prior written permission.
21: *
22: * THIS SOFTWARE IS PROVIDED BY Adam Glass ``AS IS'' AND
23: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32: * SUCH DAMAGE.
33: */
34:
35: #include <sys/param.h>
36: #include <sys/types.h>
37:
38: #include <netinet/in.h>
39: #include <netinet/in_systm.h>
40:
41: #include <include/rpb.h>
42: #include <include/prom.h>
43:
44: #include <lib/libkern/libkern.h>
45: #include <lib/libsa/netif.h>
46: #include <lib/libsa/stand.h>
47:
48: #include "stand/bbinfo.h"
49:
50: int prom_probe();
51: int prom_match();
52: void prom_init();
53: int prom_get();
54: int prom_put();
55: void prom_end();
56:
57: extern struct netif_stats prom_stats[];
58:
59: struct netif_dif prom_ifs[] = {
60: /* dif_unit dif_nsel dif_stats dif_private */
61: { 0, 1, &prom_stats[0], 0, },
62: };
63:
64: struct netif_stats prom_stats[NENTS(prom_ifs)];
65:
66: struct netbbinfo netbbinfo = {
67: 0xfeedbabedeadbeef, /* magic number */
68: 0, /* set */
69: 0, 0, 0, 0, 0, 0, /* ether address */
70: 0, /* force */
71: { 0, }, /* pad2 */
72: 0, /* cksum */
73: 0xfeedbeefdeadbabe, /* magic number */
74: };
75:
76: struct netif_driver prom_netif_driver = {
77: "prom", /* netif_bname */
78: prom_match, /* netif_match */
79: prom_probe, /* netif_probe */
80: prom_init, /* netif_init */
81: prom_get, /* netif_get */
82: prom_put, /* netif_put */
83: prom_end, /* netif_end */
84: prom_ifs, /* netif_ifs */
85: NENTS(prom_ifs) /* netif_nifs */
86: };
87:
88: int netfd, broken_firmware;
89:
90: int
91: prom_match(nif, machdep_hint)
92: struct netif *nif;
93: void *machdep_hint;
94: {
95:
96: return (1);
97: }
98:
99: int
100: prom_probe(nif, machdep_hint)
101: struct netif *nif;
102: void *machdep_hint;
103: {
104:
105: return 0;
106: }
107:
108: int
109: prom_put(desc, pkt, len)
110: struct iodesc *desc;
111: void *pkt;
112: int len;
113: {
114:
115: prom_write(netfd, len, pkt, 0);
116:
117: return len;
118: }
119:
120:
121: int
122: prom_get(desc, pkt, len, timeout)
123: struct iodesc *desc;
124: void *pkt;
125: int len;
126: time_t timeout;
127: {
128: prom_return_t ret;
129: time_t t;
130: int cc;
131: char hate[2000];
132:
133: t = getsecs();
134: cc = 0;
135: while (((getsecs() - t) < timeout) && !cc) {
136: if (broken_firmware)
137: ret.bits = prom_read(netfd, 0, hate, 0);
138: else
139: ret.bits = prom_read(netfd, sizeof hate, hate, 0);
140: if (ret.u.status == 0)
141: cc = ret.u.retval;
142: }
143: if (broken_firmware)
144: cc = min(cc, len);
145: else
146: cc = len;
147: bcopy(hate, pkt, cc);
148:
149: return cc;
150: }
151:
152: extern char *strchr();
153:
154: void
155: prom_init(desc, machdep_hint)
156: struct iodesc *desc;
157: void *machdep_hint;
158: {
159: prom_return_t ret;
160: char devname[64];
161: int devlen, i, netbbinfovalid;
162: char *enet_addr;
163: u_int64_t *qp, csum;
164:
165: broken_firmware = 0;
166:
167: csum = 0;
168: for (i = 0, qp = (u_int64_t *)&netbbinfo;
169: i < (sizeof netbbinfo / sizeof (u_int64_t)); i++, qp++)
170: csum += *qp;
171: netbbinfovalid = (csum == 0);
172: if (netbbinfovalid)
173: netbbinfovalid = netbbinfo.set;
174:
175: #if 0
176: printf("netbbinfo ");
177: if (!netbbinfovalid)
178: printf("invalid\n");
179: else
180: printf("valid: force = %d, ea = %s\n", netbbinfo.force,
181: ether_sprintf(netbbinfo.ether_addr));
182: #endif
183:
184: ret.bits = prom_getenv(PROM_E_BOOTED_DEV, devname, sizeof(devname));
185: devlen = ret.u.retval;
186:
187: /* Ethernet address is the 9th component of the booted_dev string. */
188: enet_addr = devname;
189: for (i = 0; i < 8; i++) {
190: enet_addr = strchr(enet_addr, ' ');
191: if (enet_addr == NULL) {
192: printf("boot: boot device name does not contain ethernet address.\n");
193: goto punt;
194: }
195: enet_addr++;
196: }
197: if (enet_addr != NULL) {
198: int hv, lv;
199:
200: #define dval(c) (((c) >= '0' && (c) <= '9') ? ((c) - '0') : \
201: (((c) >= 'A' && (c) <= 'F') ? (10 + (c) - 'A') : \
202: (((c) >= 'a' && (c) <= 'f') ? (10 + (c) - 'a') : -1)))
203:
204: for (i = 0; i < 6; i++) {
205: hv = dval(*enet_addr); enet_addr++;
206: lv = dval(*enet_addr); enet_addr++;
207: enet_addr++;
208:
209: if (hv == -1 || lv == -1) {
210: printf("boot: boot device name contains bogus ethernet address.\n");
211: goto punt;
212: }
213:
214: desc->myea[i] = (hv << 4) | lv;
215: }
216: #undef dval
217: }
218:
219: if (netbbinfovalid && netbbinfo.force) {
220: printf("boot: using hard-coded ethernet address (forced).\n");
221: bcopy(netbbinfo.ether_addr, desc->myea, sizeof desc->myea);
222: }
223:
224: gotit:
225: printf("boot: ethernet address: %s\n", ether_sprintf(desc->myea));
226:
227: ret.bits = prom_open(devname, devlen + 1);
228: if (ret.u.status) {
229: printf("prom_init: open failed: %d\n", ret.u.status);
230: goto reallypunt;
231: }
232: netfd = ret.u.retval;
233: return;
234:
235: punt:
236: broken_firmware = 1;
237: if (netbbinfovalid) {
238: printf("boot: using hard-coded ethernet address.\n");
239: bcopy(netbbinfo.ether_addr, desc->myea, sizeof desc->myea);
240: goto gotit;
241: }
242:
243: reallypunt:
244: printf("\n");
245: printf("Boot device name was: \"%s\"\n", devname);
246: printf("\n");
247: printf("Your firmware may be too old to network-boot OpenBSD/Alpha,\n");
248: printf("or you might have to hard-code an ethernet address into\n");
249: printf("your network boot block with setnetbootinfo(8).\n");
250: halt();
251: }
252:
253: void
254: prom_end(nif)
255: struct netif *nif;
256: {
257:
258: prom_close(netfd);
259: }
CVSweb