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