/* $NetBSD: idprom.c,v 1.6 2009/01/12 07:00:59 tsutsui Exp $ */ /*- * Copyright (c) 1998 The NetBSD Foundation, Inc. * All rights reserved. * * This code is derived from software contributed to The NetBSD Foundation * by Adam Glass and Gordon W. Ross. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ /* * Machine ID PROM - system type and serial number */ #include #include #include #include #include "libsa.h" /* * This driver provides a soft copy of the IDPROM. * It is copied from the device early in startup. * Allow these to be patched (helps with poor old * Sun3/80 boxes with dead NVRAM). */ u_char cpu_machine_id = 0; struct idprom identity_prom = { 0 }; int idprom_cksum(u_char *); void idprom_init2(void); void idprom_init3(void); void idprom_init3x(void); int idprom_cksum(u_char *p) { int len, x; len = IDPROM_CKSUM_SIZE; x = 0; /* xor of data */ do x ^= *p++; while (--len > 0); return (x); } /* Copy the ethernet address into the passed space. */ void idprom_etheraddr(u_char *eaddrp) { idprom_init(); memcpy(eaddrp, identity_prom.idp_etheraddr, 6); } /* Fetch a copy of the idprom. */ void idprom_init(void) { if (identity_prom.idp_format == 1) return; /* Copy the IDPROM contents and do the checksum. */ if (_is3x) idprom_init3x(); else if (_is2) idprom_init2(); else idprom_init3(); if (identity_prom.idp_format != 1) panic("idprom: bad version"); cpu_machine_id = identity_prom.idp_machtype; } /* * Sun2 version: * Just copy it from control space. */ void idprom_init2(void) { /* Copy the IDPROM contents and do the checksum. */ sun2_getidprom((u_char *) &identity_prom); if (idprom_cksum((u_char *) &identity_prom)) printf("idprom: bad checksum\n"); } /* * Sun3 version: * Just copy it from control space. */ void idprom_init3(void) { /* Copy the IDPROM contents and do the checksum. */ sun3_getidprom((u_char *) &identity_prom); if (idprom_cksum((u_char *) &identity_prom)) printf("idprom: bad checksum\n"); } /* * Sun3X version: * Rather than do all the map-in/probe work to find the idprom, * we can cheat! We _know_ the monitor already made a copy of * the IDPROM in its data page. All we have to do is find it. * * Yeah, this is sorta gross... Only used on old PROMs that * do not have a sif_macaddr function (rev < 3.0). The area * to search was determined from some "insider" info. about * the layout of the PROM data area. */ void idprom_init3x(void) { u_char *p; printf("idprom: Sun3X search for soft copy...\n"); for (p = (u_char *)(SUN3X_MONDATA + 0x0400); p < (u_char *)(SUN3X_MONDATA + 0x1c00); p++) { /* first check for some constants */ if (p[0] != 0x01) /* format */ continue; if (p[2] != 0x08) /* ether[0] */ continue; if (p[3] != 0x00) /* ether[1] */ continue; if (p[4] != 0x20) /* ether[2] */ continue; if ((p[1] & 0xfc) != IDM_ARCH_SUN3X) continue; /* Looks plausible. Try the checksum. */ if (idprom_cksum(p) == 0) goto found; } panic("idprom: not found in monitor data"); found: printf("idprom: copy found at 0x%x\n", (int)p); memcpy(&identity_prom, p, sizeof(struct idprom)); }