1 /* $NetBSD: idprom.c,v 1.15 2008/04/28 20:23:38 martin 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 * 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/cdefs.h> 37 __KERNEL_RCSID(0, "$NetBSD: idprom.c,v 1.15 2008/04/28 20:23:38 martin Exp $"); 38 39 #include <sys/param.h> 40 #include <sys/systm.h> 41 #include <sys/device.h> 42 #include <sys/kernel.h> 43 44 #include <uvm/uvm_extern.h> 45 46 #include <machine/autoconf.h> 47 #include <machine/idprom.h> 48 49 #include <sun3/sun3/machdep.h> 50 #ifdef _SUN3_ 51 #include <sun3/sun3/control.h> 52 #elif _SUN3X_ 53 #include <sun3/sun3x/obio.h> 54 #endif 55 56 /* 57 * This structure is what this driver is all about. 58 * It is copied from the device early in startup. 59 */ 60 struct idprom identity_prom; 61 62 static int idprom_cksum(u_char *); 63 static void idprom_get(u_char *); 64 static int idprom_hostid(void); 65 66 /* 67 * Copy the IDPROM contents, 68 * verify the checksum, 69 * set the hostid... 70 */ 71 void 72 idprom_init(void) 73 { 74 75 idprom_get((u_char *)&identity_prom); 76 if (idprom_cksum((u_char *) &identity_prom)) 77 printf("idprom: bad checksum\n"); 78 if (identity_prom.idp_format < 1) 79 printf("idprom: bad version\n"); 80 81 cpu_machine_id = identity_prom.idp_machtype; 82 hostid = idprom_hostid(); 83 } 84 85 static int 86 idprom_cksum(u_char *p) 87 { 88 int len, x; 89 90 len = IDPROM_CKSUM_SIZE; 91 x = 0; /* xor of data */ 92 do x ^= *p++; 93 while (--len > 0); 94 return (x); 95 } 96 97 static int 98 idprom_hostid(void) 99 { 100 struct idprom *idp; 101 union { 102 long l; 103 char c[4]; 104 } hid; 105 106 /* 107 * Construct the hostid from the idprom contents. 108 * This appears to be the way SunOS does it. 109 */ 110 idp = &identity_prom; 111 hid.c[0] = idp->idp_machtype; 112 hid.c[1] = idp->idp_serialnum[0]; 113 hid.c[2] = idp->idp_serialnum[1]; 114 hid.c[3] = idp->idp_serialnum[2]; 115 return (hid.l); 116 } 117 118 void 119 idprom_etheraddr(u_char *eaddrp) 120 { 121 122 memcpy(eaddrp, identity_prom.idp_etheraddr, 6); 123 } 124 125 /* 126 * Machine specific stuff follows. 127 */ 128 129 #ifdef _SUN3_ 130 #error "not yet merged" 131 #endif /* SUN3 */ 132 #ifdef _SUN3X_ 133 /* 134 * On the Sun3X, this is called early during startup, 135 * but after trap table setup so peek_byte() works. 136 * Called by machdep.c:identifycpu() 137 */ 138 static void 139 idprom_get(u_char *dst) 140 { 141 u_char *src; 142 vaddr_t va; 143 int len; 144 145 /* First, probe for a separate IDPROM (3/470). */ 146 find_prom_map(OBIO_IDPROM1, PMAP_OBIO, IDPROM_SIZE, &va); 147 if (peek_byte((void *)va) == -1) { 148 /* IDPROM is in the EEPROM */ 149 find_prom_map(OBIO_IDPROM2, PMAP_OBIO, IDPROM_SIZE, &va); 150 } 151 152 /* Copy the IDPROM contents and do the checksum. */ 153 src = (void *)va; 154 len = IDPROM_SIZE; 155 do { 156 *dst++ = *src++; 157 } while (--len > 0); 158 } 159 160 #endif /* SUN3X */ 161