1 /* $NetBSD: idprom.c,v 1.8 2020/06/20 18:44:17 riastradh 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 #include <lib/libsa/stand.h> 40 41 #include "libsa.h" 42 43 /* 44 * This driver provides a soft copy of the IDPROM. 45 * It is copied from the device early in startup. 46 * Allow these to be patched (helps with poor old 47 * Sun3/80 boxes with dead NVRAM). 48 */ 49 u_char cpu_machine_id = 0; 50 struct idprom identity_prom = { 0 }; 51 52 static int idprom_cksum(u_char *); 53 static void idprom_init2(void); 54 static void idprom_init3(void); 55 static void idprom_init3x(void); 56 57 static int 58 idprom_cksum(u_char *p) 59 { 60 int len, x; 61 62 len = IDPROM_CKSUM_SIZE; 63 x = 0; /* xor of data */ 64 do x ^= *p++; 65 while (--len > 0); 66 return (x); 67 } 68 69 /* Copy the ethernet address into the passed space. */ 70 void 71 idprom_etheraddr(u_char *eaddrp) 72 { 73 74 idprom_init(); 75 memcpy(eaddrp, identity_prom.idp_etheraddr, 6); 76 } 77 78 /* Fetch a copy of the idprom. */ 79 void 80 idprom_init(void) 81 { 82 83 if (identity_prom.idp_format == 1) 84 return; 85 86 /* Copy the IDPROM contents and do the checksum. */ 87 if (_is3x) 88 idprom_init3x(); 89 else if (_is2) 90 idprom_init2(); 91 else 92 idprom_init3(); 93 94 if (identity_prom.idp_format != 1) 95 panic("idprom: bad version"); 96 cpu_machine_id = identity_prom.idp_machtype; 97 } 98 99 /* 100 * Sun2 version: 101 * Just copy it from control space. 102 */ 103 static void 104 idprom_init2(void) 105 { 106 107 /* Copy the IDPROM contents and do the checksum. */ 108 sun2_getidprom((u_char *) &identity_prom); 109 if (idprom_cksum((u_char *) &identity_prom)) 110 printf("idprom: bad checksum\n"); 111 } 112 113 /* 114 * Sun3 version: 115 * Just copy it from control space. 116 */ 117 static void 118 idprom_init3(void) 119 { 120 121 /* Copy the IDPROM contents and do the checksum. */ 122 sun3_getidprom((u_char *) &identity_prom); 123 if (idprom_cksum((u_char *) &identity_prom)) 124 printf("idprom: bad checksum\n"); 125 } 126 127 /* 128 * Sun3X version: 129 * Rather than do all the map-in/probe work to find the idprom, 130 * we can cheat! We _know_ the monitor already made a copy of 131 * the IDPROM in its data page. All we have to do is find it. 132 * 133 * Yeah, this is sorta gross... Only used on old PROMs that 134 * do not have a sif_macaddr function (rev < 3.0). The area 135 * to search was determined from some "insider" info. about 136 * the layout of the PROM data area. 137 */ 138 static void 139 idprom_init3x(void) 140 { 141 u_char *p; 142 143 printf("idprom: Sun3X search for soft copy...\n"); 144 145 for (p = (u_char *)(SUN3X_MONDATA + 0x0400); 146 p < (u_char *)(SUN3X_MONDATA + 0x1c00); p++) 147 { 148 /* first check for some constants */ 149 if (p[0] != 0x01) /* format */ 150 continue; 151 if (p[2] != 0x08) /* ether[0] */ 152 continue; 153 if (p[3] != 0x00) /* ether[1] */ 154 continue; 155 if (p[4] != 0x20) /* ether[2] */ 156 continue; 157 if ((p[1] & 0xfc) != IDM_ARCH_SUN3X) 158 continue; 159 /* Looks plausible. Try the checksum. */ 160 if (idprom_cksum(p) == 0) 161 goto found; 162 } 163 panic("idprom: not found in monitor data"); 164 165 found: 166 printf("idprom: copy found at 0x%x\n", (int)p); 167 memcpy(&identity_prom, p, sizeof(struct idprom)); 168 } 169