xref: /netbsd/sys/arch/sun2/sun2/idprom.c (revision ce099b40)
1*ce099b40Smartin /*	$NetBSD: idprom.c,v 1.7 2008/04/28 20:23:37 martin Exp $	*/
2ec984a04Sfredette 
3ec984a04Sfredette /*-
4ec984a04Sfredette  * Copyright (c) 1996 The NetBSD Foundation, Inc.
5ec984a04Sfredette  * All rights reserved.
6ec984a04Sfredette  *
7ec984a04Sfredette  * This code is derived from software contributed to The NetBSD Foundation
8ec984a04Sfredette  * by Adam Glass, Gordon W. Ross, and Matthew Fredette.
9ec984a04Sfredette  *
10ec984a04Sfredette  * Redistribution and use in source and binary forms, with or without
11ec984a04Sfredette  * modification, are permitted provided that the following conditions
12ec984a04Sfredette  * are met:
13ec984a04Sfredette  * 1. Redistributions of source code must retain the above copyright
14ec984a04Sfredette  *    notice, this list of conditions and the following disclaimer.
15ec984a04Sfredette  * 2. Redistributions in binary form must reproduce the above copyright
16ec984a04Sfredette  *    notice, this list of conditions and the following disclaimer in the
17ec984a04Sfredette  *    documentation and/or other materials provided with the distribution.
18ec984a04Sfredette  *
19ec984a04Sfredette  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20ec984a04Sfredette  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21ec984a04Sfredette  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22ec984a04Sfredette  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23ec984a04Sfredette  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24ec984a04Sfredette  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25ec984a04Sfredette  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26ec984a04Sfredette  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27ec984a04Sfredette  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28ec984a04Sfredette  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29ec984a04Sfredette  * POSSIBILITY OF SUCH DAMAGE.
30ec984a04Sfredette  */
31ec984a04Sfredette 
32ec984a04Sfredette /*
33ec984a04Sfredette  * Machine ID PROM - system type and serial number
34ec984a04Sfredette  */
35ec984a04Sfredette 
36ed517291Slukem #include <sys/cdefs.h>
37*ce099b40Smartin __KERNEL_RCSID(0, "$NetBSD: idprom.c,v 1.7 2008/04/28 20:23:37 martin Exp $");
38ed517291Slukem 
39ec984a04Sfredette #include <sys/param.h>
40ec984a04Sfredette #include <sys/systm.h>
41ec984a04Sfredette #include <sys/device.h>
42ec984a04Sfredette #include <sys/kernel.h>
43ec984a04Sfredette 
4443e759e5Sthorpej #include <uvm/uvm_extern.h>
4543e759e5Sthorpej 
46ec984a04Sfredette #include <machine/autoconf.h>
47ec984a04Sfredette #include <machine/idprom.h>
48ec984a04Sfredette 
49ec984a04Sfredette #include <sun2/sun2/machdep.h>
50ec984a04Sfredette #include <sun2/sun2/control.h>
51ec984a04Sfredette 
52ec984a04Sfredette /*
53ec984a04Sfredette  * This structure is what this driver is all about.
54ec984a04Sfredette  * It is copied from the device early in startup.
55ec984a04Sfredette  */
56ec984a04Sfredette struct idprom identity_prom;
57ec984a04Sfredette 
5810b1a7beSchs static int idprom_cksum(u_char *);
5910b1a7beSchs static void idprom_get(u_char *);
6010b1a7beSchs static int idprom_hostid(void);
61ec984a04Sfredette 
62ec984a04Sfredette /*
63ec984a04Sfredette  * Copy the IDPROM contents,
64ec984a04Sfredette  * verify the checksum,
65ec984a04Sfredette  * set the hostid...
66ec984a04Sfredette  */
67ec984a04Sfredette void
idprom_init(void)6810b1a7beSchs idprom_init(void)
69ec984a04Sfredette {
70ec984a04Sfredette 
71ec984a04Sfredette 	idprom_get((u_char *)&identity_prom);
72ec984a04Sfredette 	if (idprom_cksum((u_char *) &identity_prom))
73ec984a04Sfredette 		printf("idprom: bad checksum\n");
74ec984a04Sfredette 	if (identity_prom.idp_format < 1)
75ec984a04Sfredette 		printf("idprom: bad version\n");
76ec984a04Sfredette 
77ec984a04Sfredette 	cpu_machine_id = identity_prom.idp_machtype;
78ec984a04Sfredette 	hostid = idprom_hostid();
79ec984a04Sfredette }
80ec984a04Sfredette 
81ec984a04Sfredette static int
idprom_cksum(u_char * p)8210b1a7beSchs idprom_cksum(u_char *p)
83ec984a04Sfredette {
84ec984a04Sfredette 	int len, x;
85ec984a04Sfredette 
86ec984a04Sfredette 	len = IDPROM_CKSUM_SIZE;
87ec984a04Sfredette 	x = 0;	/* xor of data */
88ec984a04Sfredette 	do x ^= *p++;
89ec984a04Sfredette 	while (--len > 0);
90ec984a04Sfredette 	return (x);
91ec984a04Sfredette }
92ec984a04Sfredette 
93ec984a04Sfredette static int
idprom_hostid(void)9410b1a7beSchs idprom_hostid(void)
95ec984a04Sfredette {
96ec984a04Sfredette 	struct idprom *idp;
97ec984a04Sfredette 	union {
98ec984a04Sfredette 		long l;
99ec984a04Sfredette 		char c[4];
100ec984a04Sfredette 	} hid;
101ec984a04Sfredette 
102ec984a04Sfredette 	/*
103ec984a04Sfredette 	 * Construct the hostid from the idprom contents.
104ec984a04Sfredette 	 * This appears to be the way SunOS does it.
105ec984a04Sfredette 	 */
106ec984a04Sfredette 	idp = &identity_prom;
107ec984a04Sfredette 	hid.c[0] = idp->idp_machtype;
108ec984a04Sfredette 	hid.c[1] = idp->idp_serialnum[0];
109ec984a04Sfredette 	hid.c[2] = idp->idp_serialnum[1];
110ec984a04Sfredette 	hid.c[3] = idp->idp_serialnum[2];
111ec984a04Sfredette 	return (hid.l);
112ec984a04Sfredette }
113ec984a04Sfredette 
114ec984a04Sfredette void
idprom_etheraddr(u_char * eaddrp)11510b1a7beSchs idprom_etheraddr(u_char *eaddrp)
116ec984a04Sfredette {
117ec984a04Sfredette 
118bbb634caSfredette 	memcpy(eaddrp, identity_prom.idp_etheraddr, 6);
119ec984a04Sfredette }
120ec984a04Sfredette 
121ec984a04Sfredette /*
122ec984a04Sfredette  * Machine specific stuff follows.
123ec984a04Sfredette  */
124ec984a04Sfredette 
125ec984a04Sfredette /*
126ec984a04Sfredette  * Copy the IDPROM to memory.
127ec984a04Sfredette  *
128ec984a04Sfredette  * On the Sun2, this is called very early,
129ec984a04Sfredette  * because we need the cputype.
130ec984a04Sfredette  */
131ec984a04Sfredette static void
idprom_get(u_char * dst)13210b1a7beSchs idprom_get(u_char *dst)
133ec984a04Sfredette {
134bbb634caSfredette 	vaddr_t src;	/* control space address */
135ec984a04Sfredette 	int len, x;
136ec984a04Sfredette 
137ec984a04Sfredette 	src = IDPROM_BASE;
138ec984a04Sfredette 	len = IDPROM_SIZE;
139ec984a04Sfredette 	do {
140ec984a04Sfredette 		x = get_control_byte(src);
14143e759e5Sthorpej 		src += PAGE_SIZE;
142ec984a04Sfredette 		*dst++ = x;
143ec984a04Sfredette 	} while (--len > 0);
144ec984a04Sfredette }
145ec984a04Sfredette 
146