Annotation of sys/arch/alpha/stand/netboot/if_prom.c, Revision 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