Home | History | Annotate | Line # | Download | only in libsa
idprom.c revision 1.4.78.1
      1 /*	$NetBSD: idprom.c,v 1.4.78.1 2008/05/16 02:23:23 yamt Exp $	*/
      2 
      3 /*-
      4  * Copyright (c) 1998 The NetBSD Foundation, Inc.
      5  * All rights reserved.
      6  *
      7  * This code is derived from software contributed to The NetBSD Foundation
      8  * by Adam Glass and Gordon W. Ross.
      9  *
     10  * Redistribution and use in source and binary forms, with or without
     11  * modification, are permitted provided that the following conditions
     12  * are met:
     13  * 1. Redistributions of source code must retain the above copyright
     14  *    notice, this list of conditions and the following disclaimer.
     15  * 2. Redistributions in binary form must reproduce the above copyright
     16  *    notice, this list of conditions and the following disclaimer in the
     17  *    documentation and/or other materials provided with the distribution.
     18  *
     19  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     21  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     23  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     29  * POSSIBILITY OF SUCH DAMAGE.
     30  */
     31 
     32 /*
     33  * Machine ID PROM - system type and serial number
     34  */
     35 
     36 #include <sys/types.h>
     37 #include <machine/idprom.h>
     38 #include <machine/mon.h>
     39 
     40 #include "libsa.h"
     41 
     42 /*
     43  * This driver provides a soft copy of the IDPROM.
     44  * It is copied from the device early in startup.
     45  * Allow these to be patched (helps with poor old
     46  * Sun3/80 boxes with dead NVRAM).
     47  */
     48 u_char cpu_machine_id = 0;
     49 struct idprom identity_prom = { 0 };
     50 
     51 int idprom_cksum(u_char *);
     52 void idprom_init2(void);
     53 void idprom_init3(void);
     54 void idprom_init3x(void);
     55 
     56 int
     57 idprom_cksum(u_char *p)
     58 {
     59 	int len, x;
     60 
     61 	len = IDPROM_CKSUM_SIZE;
     62 	x = 0;	/* xor of data */
     63 	do x ^= *p++;
     64 	while (--len > 0);
     65 	return (x);
     66 }
     67 
     68 /* Copy the ethernet address into the passed space. */
     69 void
     70 idprom_etheraddr(u_char *eaddrp)
     71 {
     72 
     73 	idprom_init();
     74 	memcpy(eaddrp, identity_prom.idp_etheraddr, 6);
     75 }
     76 
     77 /* Fetch a copy of the idprom. */
     78 void
     79 idprom_init(void)
     80 {
     81 
     82 	if (identity_prom.idp_format == 1)
     83 		return;
     84 
     85 	/* Copy the IDPROM contents and do the checksum. */
     86 	if (_is3x)
     87 		idprom_init3x();
     88 	else if (_is2)
     89 		idprom_init2();
     90 	else
     91 		idprom_init3();
     92 
     93 	if (identity_prom.idp_format != 1)
     94 		panic("idprom: bad version");
     95 	cpu_machine_id = identity_prom.idp_machtype;
     96 }
     97 
     98 /*
     99  * Sun2 version:
    100  * Just copy it from control space.
    101  */
    102 void
    103 idprom_init2(void)
    104 {
    105 
    106 	/* Copy the IDPROM contents and do the checksum. */
    107 	sun2_getidprom((u_char *) &identity_prom);
    108 	if (idprom_cksum((u_char *) &identity_prom))
    109 		printf("idprom: bad checksum\n");
    110 }
    111 
    112 /*
    113  * Sun3 version:
    114  * Just copy it from control space.
    115  */
    116 void
    117 idprom_init3(void)
    118 {
    119 
    120 	/* Copy the IDPROM contents and do the checksum. */
    121 	sun3_getidprom((u_char *) &identity_prom);
    122 	if (idprom_cksum((u_char *) &identity_prom))
    123 		printf("idprom: bad checksum\n");
    124 }
    125 
    126 /*
    127  * Sun3X version:
    128  * Rather than do all the map-in/probe work to find the idprom,
    129  * we can cheat!  We _know_ the monitor already made a copy of
    130  * the IDPROM in its data page.  All we have to do is find it.
    131  *
    132  * Yeah, this is sorta gross...  Only used on old PROMs that
    133  * do not have a sif_macaddr function (rev < 3.0).  The area
    134  * to search was determined from some "insider" info. about
    135  * the layout of the PROM data area.
    136  */
    137 void
    138 idprom_init3x(void)
    139 {
    140 	u_char *p;
    141 
    142 	printf("idprom: Sun3X search for soft copy...\n");
    143 
    144 	for (p = (u_char *)(SUN3X_MONDATA + 0x0400);
    145 	     p < (u_char *)(SUN3X_MONDATA + 0x1c00); p++)
    146 	{
    147 		/* first check for some constants */
    148 		if (p[0] != 0x01) /* format */
    149 			continue;
    150 		if (p[2] != 0x08) /* ether[0] */
    151 			continue;
    152 		if (p[3] != 0x00) /* ether[1] */
    153 			continue;
    154 		if (p[4] != 0x20) /* ether[2] */
    155 			continue;
    156 		if ((p[1] & 0xfc) != IDM_ARCH_SUN3X)
    157 			continue;
    158 		/* Looks plausible.  Try the checksum. */
    159 		if (idprom_cksum(p) == 0)
    160 			goto found;
    161 	}
    162 	panic("idprom: not found in monitor data");
    163 
    164 found:
    165 	printf("idprom: copy found at 0x%x\n", (int)p);
    166 	memcpy(&identity_prom, p, sizeof(struct idprom));
    167 }
    168