Annotation of sys/arch/mvmeppc/dev/cpu.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: cpu.c,v 1.8 2004/11/18 16:10:28 miod Exp $ */
2:
3: /*
4: * Copyright (c) 1997 Per Fogelstrom
5: * Copyright (c) 1997 RTMX Inc
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 under OpenBSD for RTMX Inc
18: * North Carolina, USA, by Per Fogelstrom, Opsycon AB, Sweden.
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
23: * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
24: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25: * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
26: * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32: * SUCH DAMAGE.
33: *
34: */
35:
36: #include <sys/param.h>
37: #include <sys/systm.h>
38: #include <sys/proc.h>
39: #include <sys/user.h>
40: #include <sys/device.h>
41:
42: #include <machine/autoconf.h>
43:
44: /* only valid on 603(e,ev) and G3, G4 */
45: #define HID0_DOZE (1 << (31-8))
46: #define HID0_NAP (1 << (31-9))
47: #define HID0_SLEEP (1 << (31-10))
48: #define HID0_DPM (1 << (31-11))
49: #define HID0_SGE (1 << (31-24))
50: #define HID0_BTIC (1 << (31-26))
51: #define HID0_LRSTK (1 << (31-27))
52: #define HID0_FOLD (1 << (31-28))
53: #define HID0_BHT (1 << (31-29))
54:
55: char cpu_model[80];
56: char machine[] = MACHINE; /* cpu architecture */
57:
58: /* Definition of the driver for autoconfig. */
59: int cpumatch(struct device *, void *, void *);
60: void cpuattach(struct device *, struct device *, void *);
61:
62: struct cfattach cpu_ca = {
63: sizeof(struct device), cpumatch, cpuattach
64: };
65:
66: struct cfdriver cpu_cd = {
67: NULL, "cpu", DV_DULL
68: };
69:
70: void config_l2cr(int cpu);
71:
72: int
73: cpumatch(parent, cfdata, aux)
74: struct device *parent;
75: void *cfdata;
76: void *aux;
77: {
78: struct confargs *ca = aux;
79:
80: /* make sure that we're looking for a CPU. */
81: if (strcmp(ca->ca_name, cpu_cd.cd_name) != 0)
82: return (0);
83:
84: return (1);
85: }
86:
87: void
88: cpuattach(struct device *parent, struct device *dev, void *aux)
89: {
90: unsigned int cpu, pvr, hid0;
91:
92: pvr = ppc_mfpvr();
93: cpu = pvr >> 16;
94: switch (cpu) {
95: case PPC_CPU_MPC601:
96: snprintf(cpu_model, sizeof(cpu_model), "601");
97: break;
98: case PPC_CPU_MPC603:
99: snprintf(cpu_model, sizeof(cpu_model), "603");
100: break;
101: case PPC_CPU_MPC604:
102: snprintf(cpu_model, sizeof(cpu_model), "604");
103: break;
104: case PPC_CPU_MPC603e:
105: snprintf(cpu_model, sizeof(cpu_model), "603e");
106: break;
107: case PPC_CPU_MPC603ev:
108: snprintf(cpu_model, sizeof(cpu_model), "603ev");
109: break;
110: case PPC_CPU_MPC750:
111: snprintf(cpu_model, sizeof(cpu_model), "750");
112: break;
113: case PPC_CPU_MPC604ev:
114: snprintf(cpu_model, sizeof(cpu_model), "604ev");
115: break;
116: case PPC_CPU_MPC7400:
117: snprintf(cpu_model, sizeof(cpu_model), "7400");
118: break;
119: case PPC_CPU_IBM750FX:
120: snprintf(cpu_model, sizeof(cpu_model), "750FX");
121: break;
122: case PPC_CPU_MPC7410:
123: snprintf(cpu_model, sizeof(cpu_model), "7410");
124: break;
125: case PPC_CPU_MPC7450:
126: if ((pvr & 0xf) < 3)
127: snprintf(cpu_model, sizeof(cpu_model), "7450");
128: else
129: snprintf(cpu_model, sizeof(cpu_model), "7451");
130: break;
131: case PPC_CPU_MPC7455:
132: snprintf(cpu_model, sizeof(cpu_model), "7455");
133: break;
134: default:
135: snprintf(cpu_model, sizeof(cpu_model), "Version %x", cpu);
136: break;
137: }
138: snprintf(cpu_model + strlen(cpu_model),
139: sizeof(cpu_model) - strlen(cpu_model),
140: " (Revision %x)", pvr & 0xffff);
141: printf(": %s", cpu_model);
142:
143: /* power savings mode */
144: hid0 = ppc_mfhid0();
145: switch (cpu) {
146: case PPC_CPU_MPC603:
147: case PPC_CPU_MPC603e:
148: case PPC_CPU_MPC750:
149: case PPC_CPU_MPC7400:
150: case PPC_CPU_IBM750FX:
151: case PPC_CPU_MPC7410:
152: /* select DOZE mode */
153: hid0 &= ~(HID0_NAP | HID0_SLEEP);
154: hid0 |= HID0_DOZE | HID0_DPM;
155: break;
156: case PPC_CPU_MPC7450:
157: case PPC_CPU_MPC7455:
158: /* select NAP mode */
159: hid0 &= ~(HID0_DOZE | HID0_SLEEP);
160: hid0 |= HID0_NAP | HID0_DPM;
161: /* try some other flags */
162: hid0 |= HID0_SGE | HID0_BTIC;
163: hid0 |= HID0_LRSTK | HID0_FOLD | HID0_BHT;
164: /* Disable BTIC on 7450 Rev 2.0 or earlier */
165: if (cpu == PPC_CPU_MPC7450 && (pvr & 0xffff) < 0x0200)
166: hid0 &= ~HID0_BTIC;
167: break;
168: }
169: ppc_mthid0(hid0);
170:
171: /* if processor is G3 or G4, configure l2 cache */
172: if (cpu == PPC_CPU_MPC750 || cpu == PPC_CPU_MPC7400 ||
173: cpu == PPC_CPU_IBM750FX || cpu == PPC_CPU_MPC7410 ||
174: cpu == PPC_CPU_MPC7450 || cpu == PPC_CPU_MPC7455) {
175: config_l2cr(cpu);
176: }
177: printf("\n");
178: }
179:
180: /* L2CR bit definitions */
181: #define L2CR_L2E 0x80000000 /* 0: L2 enable */
182: #define L2CR_L2PE 0x40000000 /* 1: L2 data parity enable */
183: #define L2CR_L2SIZ 0x30000000 /* 2-3: L2 size */
184: #define L2SIZ_RESERVED 0x00000000
185: #define L2SIZ_256K 0x10000000
186: #define L2SIZ_512K 0x20000000
187: #define L2SIZ_1M 0x30000000
188: #define L2CR_L2CLK 0x0e000000 /* 4-6: L2 clock ratio */
189: #define L2CLK_DIS 0x00000000 /* disable L2 clock */
190: #define L2CLK_10 0x02000000 /* core clock / 1 */
191: #define L2CLK_15 0x04000000 /* / 1.5 */
192: #define L2CLK_20 0x08000000 /* / 2 */
193: #define L2CLK_25 0x0a000000 /* / 2.5 */
194: #define L2CLK_30 0x0c000000 /* / 3 */
195: #define L2CR_L2RAM 0x01800000 /* 7-8: L2 RAM type */
196: #define L2RAM_FLOWTHRU_BURST 0x00000000
197: #define L2RAM_PIPELINE_BURST 0x01000000
198: #define L2RAM_PIPELINE_LATE 0x01800000
199: #define L2CR_L2DO 0x00400000 /* 9: L2 data-only.
200: Setting this bit disables instruction
201: caching. */
202: #define L2CR_L2I 0x00200000 /* 10: L2 global invalidate. */
203: #define L2CR_L2CTL 0x00100000 /* 11: L2 RAM control (ZZ enable).
204: Enables automatic operation of the
205: L2ZZ (low-power mode) signal. */
206: #define L2CR_L2WT 0x00080000 /* 12: L2 write-through. */
207: #define L2CR_L2TS 0x00040000 /* 13: L2 test support. */
208: #define L2CR_L2OH 0x00030000 /* 14-15: L2 output hold. */
209: #define L2CR_L2SL 0x00008000 /* 16: L2 DLL slow. */
210: #define L2CR_L2DF 0x00004000 /* 17: L2 differential clock. */
211: #define L2CR_L2BYP 0x00002000 /* 18: L2 DLL bypass. */
212: #define L2CR_L2IP 0x00000001 /* 31: L2 global invalidate in progress
213: (read only). */
214: #ifdef L2CR_CONFIG
215: u_int l2cr_config = L2CR_CONFIG;
216: #else
217: u_int l2cr_config = 0;
218: #endif
219:
220: /* L3CR bit definitions */
221: #define L3CR_L3E 0x80000000 /* 0: L3 enable */
222: #define L3CR_L3SIZ 0x10000000 /* 3: L3 size (0=1MB, 1=2MB) */
223:
224: void
225: config_l2cr(int cpu)
226: {
227: u_int l2cr, x;
228:
229: l2cr = ppc_mfl2cr();
230:
231: /*
232: * Configure L2 cache if not enabled.
233: */
234: if ((l2cr & L2CR_L2E) == 0 && l2cr_config != 0) {
235: l2cr = l2cr_config;
236: ppc_mtl2cr(l2cr);
237:
238: /* Wait for L2 clock to be stable (640 L2 clocks). */
239: delay(100);
240:
241: /* Invalidate all L2 contents. */
242: l2cr |= L2CR_L2I;
243: ppc_mtl2cr(l2cr);
244: do {
245: x = ppc_mfl2cr();
246: } while (x & L2CR_L2IP);
247:
248: /* Enable L2 cache. */
249: l2cr &= ~L2CR_L2I;
250: l2cr |= L2CR_L2E;
251: ppc_mtl2cr(l2cr);
252: }
253:
254: if (l2cr & L2CR_L2E) {
255: if (cpu == PPC_CPU_MPC7450 || cpu == PPC_CPU_MPC7455) {
256: u_int l3cr;
257:
258: printf(": 256KB L2 cache");
259:
260: l3cr = ppc_mfl3cr();
261: if (l3cr & L3CR_L3E)
262: printf(", %cMB L3 cache",
263: l3cr & L3CR_L3SIZ ? '2' : '1');
264: } else if (cpu == PPC_CPU_IBM750FX)
265: printf(": 512KB L2 cache");
266: else {
267: switch (l2cr & L2CR_L2SIZ) {
268: case L2SIZ_256K:
269: printf(": 256KB");
270: break;
271: case L2SIZ_512K:
272: printf(": 512KB");
273: break;
274: case L2SIZ_1M:
275: printf(": 1MB");
276: break;
277: default:
278: printf(": unknown size");
279: }
280: printf(" backside cache");
281: }
282: #if 0
283: switch (l2cr & L2CR_L2RAM) {
284: case L2RAM_FLOWTHRU_BURST:
285: printf(" Flow-through synchronous burst SRAM");
286: break;
287: case L2RAM_PIPELINE_BURST:
288: printf(" Pipelined synchronous burst SRAM");
289: break;
290: case L2RAM_PIPELINE_LATE:
291: printf(" Pipelined synchronous late-write SRAM");
292: break;
293: default:
294: printf(" unknown type");
295: }
296:
297: if (l2cr & L2CR_L2PE)
298: printf(" with parity");
299: #endif
300: } else
301: printf(": L2 cache not enabled");
302: }
CVSweb