xref: /original-bsd/sys/sparc/sparc/cpu.c (revision 21eed380)
1 /*
2  * Copyright (c) 1992 The Regents of the University of California.
3  * All rights reserved.
4  *
5  * This software was developed by the Computer Systems Engineering group
6  * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
7  * contributed to Berkeley.
8  *
9  * All advertising materials mentioning features or use of this software
10  * must display the following acknowledgement:
11  *	This product includes software developed by the University of
12  *	California, Lawrence Berkeley Laboratory.
13  *
14  * %sccs.include.redist.c%
15  *
16  *	@(#)cpu.c	7.5 (Berkeley) 04/27/93
17  *
18  * from: $Header: cpu.c,v 1.11 93/04/27 14:34:42 torek Exp $ (LBL)
19  */
20 
21 #include <sys/param.h>
22 #include <sys/device.h>
23 
24 #include <machine/autoconf.h>
25 #include <machine/cpu.h>
26 #include <machine/reg.h>
27 
28 #include <sparc/sparc/cache.h>
29 
30 /* This is declared here so that you must include a CPU for the cache code. */
31 struct cacheinfo cacheinfo;
32 
33 /* the following are used externally (sysctl_hw) */
34 char	machine[] = "sparc";
35 char	cpu_model[80];
36 int	cpuspeed;		/* XXX */
37 
38 static char *psrtoname();
39 static char *fsrtoname();
40 
41 /*
42  * Attach the CPU.
43  * Discover interesting goop about the virtual address cache.
44  */
45 static void
46 cpu_attach(parent, dev, aux)
47 	struct device *parent;
48 	struct device *dev;
49 	void *aux;
50 {
51 	register int node, clk, i, l;
52 	register u_int psr, fver;
53 	register char *fpuname;
54 	struct fpstate fpstate;
55 
56 	/*
57 	 * Get the FSR and clear any exceptions.  If we do not unload
58 	 * the queue here and it is left over from a previous crash, we
59 	 * will panic in the first loadfpstate(), due to a sequence error,
60 	 * so we need to dump the whole state anyway.
61 	 *
62 	 * If there is no FPU, trap.c will advance over all the stores,
63 	 * so we initialize fs_fsr here.
64 	 */
65 	fpstate.fs_fsr = 7 << FSR_VER_SHIFT;	/* 7 is reserved for "none" */
66 	savefpstate(&fpstate);
67 	fver = (fpstate.fs_fsr >> FSR_VER_SHIFT) & (FSR_VER >> FSR_VER_SHIFT);
68 	psr = getpsr();
69 	if (fver != 7) {
70 		foundfpu = 1;
71 		fpuname = fsrtoname(psr, fver);
72 	} else
73 		fpuname = "no";
74 
75 	/* tell them what we have */
76 	node = ((struct romaux *)aux)->ra_node;
77 	clk = getpropint(node, "clock-frequency", 0);
78 	sprintf(cpu_model, "%s (%s @ %s MHz, %s FPU)",
79 	    getpropstring(node, "name"), psrtoname(psr),
80 	    clockfreq(clk), fpuname);
81 	printf(": %s\n", cpu_model);
82 	cpuspeed = clk / 1000000;	/* XXX */
83 
84 	/*
85 	 * Fill in the cache info.  Note, vac-hwflush is spelled
86 	 * with an underscore on 4/75s.
87 	 */
88 	cacheinfo.c_totalsize = getpropint(node, "vac-size", 65536);
89 	cacheinfo.c_hwflush = getpropint(node, "vac_hwflush", 0) |
90 	    getpropint(node, "vac-hwflush", 0);
91 	cacheinfo.c_linesize = l = getpropint(node, "vac-linesize", 16);
92 	for (i = 0; (1 << i) < l; i++)
93 		/* void */;
94 	if ((1 << i) != l)
95 		panic("bad cache line size %d", l);
96 	cacheinfo.c_l2linesize = i;
97 
98 	vactype = VAC_WRITETHROUGH;	/* ??? */
99 }
100 
101 struct cfdriver cpucd =
102     { NULL, "cpu", matchbyname, cpu_attach, DV_CPU, sizeof(struct device) };
103 
104 static char *
105 psrtoname(psr)
106 	register u_int psr;
107 {
108 	int impl = psr >> 28, vers = (psr >> 24) & 15;
109 
110 	switch (impl) {
111 
112 	case 0:
113 		if (vers == 0)
114 			return ("MB86900/1A or L64801");
115 		break;
116 
117 	case 1:
118 		if (vers < 2)
119 			return ("CY7C601 or L64811");
120 		if (vers == 3)
121 			return ("CY7C611");
122 		break;
123 
124 	case 2:
125 		if (vers == 0)
126 			return ("B5010");
127 		break;
128 
129 	case 5:
130 		if (vers == 0)
131 			return ("MN10501");
132 		break;
133 	}
134 	return ("???");
135 }
136 
137 static char *
138 fsrtoname(psr, fver)
139 	register u_int psr, fver;
140 {
141 
142 	switch (psr >> 28) {
143 
144 	case 0:
145 		switch (fver) {
146 		case 0:
147 			return ("MB86910 or WTL1164/5");
148 		case 1:
149 			return ("MB86911 or WTL1164/5");
150 		case 2:
151 			return ("L64802 or ACT8847");
152 		case 3:
153 			return ("WTL3170/2");
154 		case 4:
155 			return ("L64804");
156 		}
157 		break;
158 
159 	case 1:
160 		switch (fver) {
161 		case 0:
162 			return ("L64812 or ACT8847");
163 		case 1:
164 			return ("L64814");
165 		case 2:
166 			return ("TMS390C602A");
167 		case 3:
168 			return ("WTL3171");
169 		}
170 		break;
171 
172 	case 2:
173 		if (fver == 0)
174 			return ("B5010 or B5110/20 or B5210");
175 		break;
176 
177 	case 5:
178 		if (fver == 0)
179 			return ("MN10501");
180 	}
181 	return ("???");
182 }
183