xref: /original-bsd/sys/sparc/sparc/cpu.c (revision 3705696b)
1 /*
2  * Copyright (c) 1992, 1993
3  *	The Regents of the University of California.  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	8.1 (Berkeley) 06/11/93
17  *
18  * from: $Header: cpu.c,v 1.12 93/05/03 09:47:57 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 
37 static char *psrtoname();
38 static char *fsrtoname();
39 
40 /*
41  * Attach the CPU.
42  * Discover interesting goop about the virtual address cache.
43  */
44 static void
45 cpu_attach(parent, dev, aux)
46 	struct device *parent;
47 	struct device *dev;
48 	void *aux;
49 {
50 	register int node, clk, i, l;
51 	register u_int psr, fver;
52 	register char *fpuname;
53 	struct fpstate fpstate;
54 
55 	/*
56 	 * Get the FSR and clear any exceptions.  If we do not unload
57 	 * the queue here and it is left over from a previous crash, we
58 	 * will panic in the first loadfpstate(), due to a sequence error,
59 	 * so we need to dump the whole state anyway.
60 	 *
61 	 * If there is no FPU, trap.c will advance over all the stores,
62 	 * so we initialize fs_fsr here.
63 	 */
64 	fpstate.fs_fsr = 7 << FSR_VER_SHIFT;	/* 7 is reserved for "none" */
65 	savefpstate(&fpstate);
66 	fver = (fpstate.fs_fsr >> FSR_VER_SHIFT) & (FSR_VER >> FSR_VER_SHIFT);
67 	psr = getpsr();
68 	if (fver != 7) {
69 		foundfpu = 1;
70 		fpuname = fsrtoname(psr, fver);
71 	} else
72 		fpuname = "no";
73 
74 	/* tell them what we have */
75 	node = ((struct romaux *)aux)->ra_node;
76 	clk = getpropint(node, "clock-frequency", 0);
77 	sprintf(cpu_model, "%s (%s @ %s MHz, %s FPU)",
78 	    getpropstring(node, "name"), psrtoname(psr),
79 	    clockfreq(clk), fpuname);
80 	printf(": %s\n", cpu_model);
81 
82 	/*
83 	 * Fill in the cache info.  Note, vac-hwflush is spelled
84 	 * with an underscore on 4/75s.
85 	 */
86 	cacheinfo.c_totalsize = getpropint(node, "vac-size", 65536);
87 	cacheinfo.c_hwflush = getpropint(node, "vac_hwflush", 0) |
88 	    getpropint(node, "vac-hwflush", 0);
89 	cacheinfo.c_linesize = l = getpropint(node, "vac-linesize", 16);
90 	for (i = 0; (1 << i) < l; i++)
91 		/* void */;
92 	if ((1 << i) != l)
93 		panic("bad cache line size %d", l);
94 	cacheinfo.c_l2linesize = i;
95 
96 	vactype = VAC_WRITETHROUGH;	/* ??? */
97 }
98 
99 struct cfdriver cpucd =
100     { NULL, "cpu", matchbyname, cpu_attach, DV_CPU, sizeof(struct device) };
101 
102 static char *
103 psrtoname(psr)
104 	register u_int psr;
105 {
106 	int impl = psr >> 28, vers = (psr >> 24) & 15;
107 
108 	switch (impl) {
109 
110 	case 0:
111 		if (vers == 0)
112 			return ("MB86900/1A or L64801");
113 		break;
114 
115 	case 1:
116 		if (vers < 2)
117 			return ("CY7C601 or L64811");
118 		if (vers == 3)
119 			return ("CY7C611");
120 		break;
121 
122 	case 2:
123 		if (vers == 0)
124 			return ("B5010");
125 		break;
126 
127 	case 5:
128 		if (vers == 0)
129 			return ("MN10501");
130 		break;
131 	}
132 	return ("???");
133 }
134 
135 static char *
136 fsrtoname(psr, fver)
137 	register u_int psr, fver;
138 {
139 
140 	switch (psr >> 28) {
141 
142 	case 0:
143 		switch (fver) {
144 		case 0:
145 			return ("MB86910 or WTL1164/5");
146 		case 1:
147 			return ("MB86911 or WTL1164/5");
148 		case 2:
149 			return ("L64802 or ACT8847");
150 		case 3:
151 			return ("WTL3170/2");
152 		case 4:
153 			return ("L64804");
154 		}
155 		break;
156 
157 	case 1:
158 		switch (fver) {
159 		case 0:
160 			return ("L64812 or ACT8847");
161 		case 1:
162 			return ("L64814");
163 		case 2:
164 			return ("TMS390C602A");
165 		case 3:
166 			return ("WTL3171");
167 		}
168 		break;
169 
170 	case 2:
171 		if (fver == 0)
172 			return ("B5010 or B5110/20 or B5210");
173 		break;
174 
175 	case 5:
176 		if (fver == 0)
177 			return ("MN10501");
178 	}
179 	return ("???");
180 }
181