cpu.c revision 110388
1/*-
2 * Copyright (c) 2001 Matt Thomas.
3 * Copyright (c) 2001 Tsubai Masanari.
4 * Copyright (c) 1998, 1999, 2001 Internet Research Institute, Inc.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 *    notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 *    notice, this list of conditions and the following disclaimer in the
14 *    documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 *    must display the following acknowledgement:
17 *	This product includes software developed by
18 *	Internet Research Institute, Inc.
19 * 4. The name of the author may not be used to endorse or promote products
20 *    derived from this software without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */
33/*
34 * Copyright (C) 2003 Benno Rice.
35 * All rights reserved.
36 *
37 * Redistribution and use in source and binary forms, with or without
38 * modification, are permitted provided that the following conditions
39 * are met:
40 * 1. Redistributions of source code must retain the above copyright
41 *    notice, this list of conditions and the following disclaimer.
42 * 2. Redistributions in binary form must reproduce the above copyright
43 *    notice, this list of conditions and the following disclaimer in the
44 *    documentation and/or other materials provided with the distribution.
45 *
46 * THIS SOFTWARE IS PROVIDED BY Benno Rice ``AS IS'' AND ANY EXPRESS OR
47 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
48 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
49 * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
50 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
51 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
52 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
53 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
54 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
55 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
56 *
57 * from $NetBSD: cpu_subr.c,v 1.1 2003/02/03 17:10:09 matt Exp $
58 * $FreeBSD: head/sys/powerpc/powerpc/cpu.c 110388 2003-02-05 12:33:49Z benno $
59 */
60
61#include <sys/param.h>
62#include <sys/systm.h>
63#include <sys/bus.h>
64#include <sys/conf.h>
65#include <sys/kernel.h>
66
67#include <machine/bus.h>
68#include <machine/hid.h>
69#include <machine/md_var.h>
70#include <machine/spr.h>
71
72struct cputab {
73	const char	*name;
74	uint16_t	version;
75	uint16_t	revfmt;
76};
77#define	REVFMT_MAJMIN	1	/* %u.%u */
78#define	REVFMT_HEX	2	/* 0x%04x */
79#define	REVFMT_DEC	3	/* %u */
80static const struct cputab models[] = {
81        { "Motorola PowerPC 601",	MPC601,		REVFMT_DEC },
82        { "Motorola PowerPC 602",	MPC602,		REVFMT_DEC },
83        { "Motorola PowerPC 603",	MPC603,		REVFMT_MAJMIN },
84        { "Motorola PowerPC 603e",	MPC603e,	REVFMT_MAJMIN },
85        { "Motorola PowerPC 603ev",	MPC603ev,	REVFMT_MAJMIN },
86        { "Motorola PowerPC 604",	MPC604,		REVFMT_MAJMIN },
87        { "Motorola PowerPC 604ev",	MPC604ev,	REVFMT_MAJMIN },
88        { "Motorola PowerPC 620",	MPC620,		REVFMT_HEX },
89        { "Motorola PowerPC 750",	MPC750,		REVFMT_MAJMIN },
90        { "IBM PowerPC 750FX",		IBM750FX,	REVFMT_MAJMIN },
91        { "Motorola PowerPC 7400",	MPC7400,	REVFMT_MAJMIN },
92        { "Motorola PowerPC 7410",	MPC7410,	REVFMT_MAJMIN },
93        { "Motorola PowerPC 7450",	MPC7450,	REVFMT_MAJMIN },
94        { "Motorola PowerPC 7455",	MPC7455,	REVFMT_MAJMIN },
95        { "Motorola PowerPC 8240",	MPC8240,	REVFMT_MAJMIN },
96        { "Unknown PowerPC CPU",	0,		REVFMT_HEX }
97};
98
99static register_t	l2cr_config = 0;
100
101static void	cpu_print_speed(void);
102static void	cpu_config_l2cr(u_int, uint16_t);
103
104void
105cpu_setup(u_int cpuid)
106{
107	u_int		pvr, maj, min, hid0;
108	uint16_t	vers, rev, revfmt;
109	const struct	cputab *cp;
110	const char	*name;
111	char		*bitmask;
112
113	pvr = mfpvr();
114	vers = pvr >> 16;
115	rev = pvr;
116	switch (vers) {
117	case MPC7410:
118		min = (pvr >> 0) & 0xff;
119		maj = min <= 4 ? 1 : 2;
120		break;
121	default:
122		maj = (pvr >>  8) & 0xf;
123		min = (pvr >>  0) & 0xf;
124	}
125
126	for (cp = models; cp->name[0] != '\0'; cp++) {
127		if (cp->version == vers)
128			break;
129	}
130
131	revfmt = cp->revfmt;
132	name = cp->name;
133	if (rev == MPC750 && pvr == 15) {
134		name = "Motorola MPC755";
135		revfmt = REVFMT_HEX;
136	}
137
138	printf("cpu%d: %s revision ", cpuid, name);
139
140	switch (revfmt) {
141	case REVFMT_MAJMIN:
142		printf("%u.%u", maj, min);
143		break;
144	case REVFMT_HEX:
145		printf("0x%04x", rev);
146		break;
147	case REVFMT_DEC:
148		printf("%u", rev);
149		break;
150	}
151
152	hid0 = mfspr(SPR_HID0);
153
154	/*
155	 * Configure power-saving mode.
156	 */
157	switch (vers) {
158	case MPC603:
159	case MPC603e:
160	case MPC603ev:
161	case MPC604ev:
162	case MPC750:
163	case IBM750FX:
164	case MPC7400:
165	case MPC7410:
166	case MPC8240:
167	case MPC8245:
168		/* Select DOZE mode. */
169		hid0 &= ~(HID0_DOZE | HID0_NAP | HID0_SLEEP);
170		hid0 |= HID0_DOZE | HID0_DPM;
171#ifdef notyet
172		powersave = 1;
173#endif
174		break;
175
176	case MPC7455:
177	case MPC7450:
178		/* Disable BTIC on 7450 Rev 2.0 or earlier */
179		if ((pvr >> 16) == MPC7450 && (pvr & 0xFFFF) <= 0x0200)
180			hid0 &= ~HID0_BTIC;
181		/* Select NAP mode. */
182		hid0 &= ~(HID0_DOZE | HID0_NAP | HID0_SLEEP);
183		hid0 |= HID0_NAP | HID0_DPM;
184#ifdef notyet
185		powersave = 0;		/* but don't use it */
186#endif
187		break;
188
189	default:
190		/* No power-saving mode is available. */ ;
191	}
192
193	switch (vers) {
194	case IBM750FX:
195	case MPC750:
196		hid0 &= ~HID0_DBP;		/* XXX correct? */
197		hid0 |= HID0_EMCP | HID0_BTIC | HID0_SGE | HID0_BHT;
198		break;
199
200	case MPC7400:
201	case MPC7410:
202		hid0 &= ~HID0_SPD;
203		hid0 |= HID0_EMCP | HID0_BTIC | HID0_SGE | HID0_BHT;
204		hid0 |= HID0_EIEC;
205		break;
206	}
207
208	mtspr(SPR_HID0, hid0);
209
210	switch (vers) {
211	case MPC7450:
212	case MPC7455:
213		bitmask = HID0_7450_BITMASK;
214		break;
215	default:
216		bitmask = HID0_BITMASK;
217		break;
218	}
219
220	switch (vers) {
221	case MPC750:
222	case IBM750FX:
223	case MPC7400:
224	case MPC7410:
225	case MPC7450:
226	case MPC7455:
227		cpu_print_speed();
228		printf("\n");
229		cpu_config_l2cr(cpuid, vers);
230		break;
231
232	default:
233		printf("\n");
234		break;
235	}
236
237	printf("cpu%d: HID0 %b\n", cpuid, hid0, bitmask);
238}
239
240void
241cpu_print_speed(void)
242{
243	uint64_t	cps;
244
245	mtspr(SPR_MMCR0, SPR_MMCR0_FC);
246	mtspr(SPR_PMC1, 0);
247	mtspr(SPR_MMCR0, SPR_MMCR0_PMC1SEL(PMCN_CYCLES));
248	delay(100000);
249	cps = (mfspr(SPR_PMC1) * 10) + 4999;
250	printf(", %lld.%02lld MHz", cps / 1000000, (cps / 10000) % 100);
251}
252
253void
254cpu_config_l2cr(u_int cpuid, uint16_t vers)
255{
256	u_int l2cr, x, msr;
257
258	l2cr = mfspr(SPR_L2CR);
259
260	/*
261	 * For MP systems, the firmware may only configure the L2 cache
262	 * on the first CPU.  In this case, assume that the other CPUs
263	 * should use the same value for L2CR.
264	 */
265	if ((l2cr & L2CR_L2E) != 0 && l2cr_config == 0) {
266		l2cr_config = l2cr;
267	}
268
269	/*
270	 * Configure L2 cache if not enabled.
271	 */
272	if ((l2cr & L2CR_L2E) == 0 && l2cr_config != 0) {
273		l2cr = l2cr_config;
274
275		/* Disable interrupts and set the cache config bits. */
276		msr = mfmsr();
277		mtmsr(msr & ~PSL_EE);
278#ifdef ALTIVEC
279		if (cpu_altivec)
280			__asm __volatile("dssall");
281#endif
282		__asm __volatile("sync");
283		mtspr(SPR_L2CR, l2cr & ~L2CR_L2E);
284		__asm __volatile("sync");
285
286		/* Wait for L2 clock to be stable (640 L2 clocks). */
287		delay(100);
288
289		/* Invalidate all L2 contents. */
290		mtspr(SPR_L2CR, l2cr | L2CR_L2I);
291		do {
292			x = mfspr(SPR_L2CR);
293		} while (x & L2CR_L2IP);
294
295		/* Enable L2 cache. */
296		l2cr |= L2CR_L2E;
297		mtspr(SPR_L2CR, l2cr);
298		mtmsr(msr);
299	}
300
301	if (!bootverbose)
302		return;
303
304	printf("cpu%d: ", cpuid);
305
306	if (l2cr & L2CR_L2E) {
307		if (vers == MPC7450 || vers == MPC7455) {
308			u_int l3cr;
309
310			printf("256KB L2 cache");
311
312			l3cr = mfspr(SPR_L3CR);
313			if (l3cr & L3CR_L3E)
314				printf(", %cMB L3 backside cache",
315				   l3cr & L3CR_L3SIZ ? '2' : '1');
316			printf("\n");
317			return;
318		}
319		if (vers == IBM750FX) {
320			printf("512KB L2 cache\n");
321			return;
322		}
323		switch (l2cr & L2CR_L2SIZ) {
324		case L2SIZ_256K:
325			printf("256KB");
326			break;
327		case L2SIZ_512K:
328			printf("512KB");
329			break;
330		case L2SIZ_1M:
331			printf("1MB");
332			break;
333		default:
334			printf("unknown size");
335		}
336		if (l2cr & L2CR_L2WT) {
337			printf(" write-through");
338		} else {
339			printf(" write-back");
340		}
341		switch (l2cr & L2CR_L2RAM) {
342		case L2RAM_FLOWTHRU_BURST:
343			printf(" flow-through synchronous burst SRAM");
344			break;
345		case L2RAM_PIPELINE_BURST:
346			printf(" pipelined synchronous burst SRAM");
347			break;
348		case L2RAM_PIPELINE_LATE:
349			printf(" pipelined synchronous late-write SRAM");
350			break;
351		default:
352			printf(" unknown type");
353		}
354
355		if (l2cr & L2CR_L2PE)
356			printf(" with parity");
357		printf(" backside cache");
358	} else
359		printf("L2 cache not enabled");
360
361	printf("\n");
362}
363