1 /* $NetBSD: idprom.c,v 1.12 2005/12/11 12:19:27 christos Exp $ */ 2 3 /*- 4 * Copyright (c) 1996 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 * 3. All advertising materials mentioning features or use of this software 19 * must display the following acknowledgement: 20 * This product includes software developed by the NetBSD 21 * Foundation, Inc. and its contributors. 22 * 4. Neither the name of The NetBSD Foundation nor the names of its 23 * contributors may be used to endorse or promote products derived 24 * from this software without specific prior written permission. 25 * 26 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 27 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 28 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 29 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 30 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 36 * POSSIBILITY OF SUCH DAMAGE. 37 */ 38 39 /* 40 * Machine ID PROM - system type and serial number 41 */ 42 43 #include <sys/cdefs.h> 44 __KERNEL_RCSID(0, "$NetBSD: idprom.c,v 1.12 2005/12/11 12:19:27 christos Exp $"); 45 46 #include <sys/param.h> 47 #include <sys/systm.h> 48 #include <sys/device.h> 49 #include <sys/kernel.h> 50 51 #include <machine/autoconf.h> 52 #include <machine/idprom.h> 53 54 #include <sun3/sun3/machdep.h> 55 #ifdef _SUN3_ 56 #include <sun3/sun3/control.h> 57 #elif _SUN3X_ 58 #include <sun3/sun3x/obio.h> 59 #endif 60 61 /* 62 * This structure is what this driver is all about. 63 * It is copied from the device early in startup. 64 */ 65 struct idprom identity_prom; 66 67 static int idprom_cksum(u_char *); 68 static void idprom_get(u_char *); 69 static int idprom_hostid(void); 70 71 /* 72 * Copy the IDPROM contents, 73 * verify the checksum, 74 * set the hostid... 75 */ 76 void 77 idprom_init(void) 78 { 79 80 idprom_get((u_char *)&identity_prom); 81 if (idprom_cksum((u_char *) &identity_prom)) 82 printf("idprom: bad checksum\n"); 83 if (identity_prom.idp_format < 1) 84 printf("idprom: bad version\n"); 85 86 cpu_machine_id = identity_prom.idp_machtype; 87 hostid = idprom_hostid(); 88 } 89 90 static int 91 idprom_cksum(u_char *p) 92 { 93 int len, x; 94 95 len = IDPROM_CKSUM_SIZE; 96 x = 0; /* xor of data */ 97 do x ^= *p++; 98 while (--len > 0); 99 return (x); 100 } 101 102 static int 103 idprom_hostid(void) 104 { 105 struct idprom *idp; 106 union { 107 long l; 108 char c[4]; 109 } hid; 110 111 /* 112 * Construct the hostid from the idprom contents. 113 * This appears to be the way SunOS does it. 114 */ 115 idp = &identity_prom; 116 hid.c[0] = idp->idp_machtype; 117 hid.c[1] = idp->idp_serialnum[0]; 118 hid.c[2] = idp->idp_serialnum[1]; 119 hid.c[3] = idp->idp_serialnum[2]; 120 return (hid.l); 121 } 122 123 void 124 idprom_etheraddr(u_char *eaddrp) 125 { 126 127 memcpy(eaddrp, identity_prom.idp_etheraddr, 6); 128 } 129 130 /* 131 * Machine specific stuff follows. 132 */ 133 134 #ifdef _SUN3_ 135 #error "not yet merged" 136 #endif /* SUN3 */ 137 #ifdef _SUN3X_ 138 /* 139 * On the Sun3X, this is called early during startup, 140 * but after trap table setup so peek_byte() works. 141 * Called by machdep.c:identifycpu() 142 */ 143 static void 144 idprom_get(u_char *dst) 145 { 146 u_char *src; 147 caddr_t va; 148 int len; 149 150 /* First, probe for a separate IDPROM (3/470). */ 151 va = obio_find_mapping(OBIO_IDPROM1, IDPROM_SIZE); 152 if (peek_byte(va) == -1) { 153 /* IDPROM is in the EEPROM */ 154 va = obio_find_mapping(OBIO_IDPROM2, IDPROM_SIZE); 155 } 156 157 /* Copy the IDPROM contents and do the checksum. */ 158 src = (u_char *) va; 159 len = IDPROM_SIZE; 160 do { 161 *dst++ = *src++; 162 } while (--len > 0); 163 } 164 165 #endif /* SUN3X */ 166