identcpu.c revision 266341
1/*	$NetBSD: cpu.c,v 1.55 2004/02/13 11:36:10 wiz Exp $	*/
2
3/*-
4 * Copyright (c) 1995 Mark Brinicombe.
5 * Copyright (c) 1995 Brini.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 *    notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 *    notice, this list of conditions and the following disclaimer in the
15 *    documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 *    must display the following acknowledgement:
18 *	This product includes software developed by Brini.
19 * 4. The name of the company nor the name of the author may be used to
20 *    endorse or promote products derived from this software without specific
21 *    prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY BRINI ``AS IS'' AND ANY EXPRESS OR IMPLIED
24 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
25 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26 * IN NO EVENT SHALL BRINI OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
27 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
28 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
29 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
34 *
35 * RiscBSD kernel project
36 *
37 * cpu.c
38 *
39 * Probing and configuration for the master CPU
40 *
41 * Created      : 10/10/95
42 */
43
44#include <sys/cdefs.h>
45__FBSDID("$FreeBSD: stable/10/sys/arm/arm/identcpu.c 266341 2014-05-17 19:37:04Z ian $");
46#include <sys/systm.h>
47#include <sys/param.h>
48#include <sys/malloc.h>
49#include <sys/time.h>
50#include <sys/proc.h>
51#include <sys/conf.h>
52#include <sys/kernel.h>
53#include <sys/sysctl.h>
54#include <machine/cpu.h>
55#include <machine/endian.h>
56
57#include <machine/cpuconf.h>
58#include <machine/md_var.h>
59
60char machine[] = "arm";
61
62SYSCTL_STRING(_hw, HW_MACHINE, machine, CTLFLAG_RD,
63	machine, 0, "Machine class");
64
65static const char * const generic_steppings[16] = {
66	"rev 0",	"rev 1",	"rev 2",	"rev 3",
67	"rev 4",	"rev 5",	"rev 6",	"rev 7",
68	"rev 8",	"rev 9",	"rev 10",	"rev 11",
69	"rev 12",	"rev 13",	"rev 14",	"rev 15",
70};
71
72static const char * const xscale_steppings[16] = {
73	"step A-0",	"step A-1",	"step B-0",	"step C-0",
74	"step D-0",	"rev 5",	"rev 6",	"rev 7",
75	"rev 8",	"rev 9",	"rev 10",	"rev 11",
76	"rev 12",	"rev 13",	"rev 14",	"rev 15",
77};
78
79static const char * const i80219_steppings[16] = {
80	"step A-0",	"rev 1",	"rev 2",	"rev 3",
81	"rev 4",	"rev 5",	"rev 6",	"rev 7",
82	"rev 8",	"rev 9",	"rev 10",	"rev 11",
83	"rev 12",	"rev 13",	"rev 14",	"rev 15",
84};
85
86static const char * const i80321_steppings[16] = {
87	"step A-0",	"step B-0",	"rev 2",	"rev 3",
88	"rev 4",	"rev 5",	"rev 6",	"rev 7",
89	"rev 8",	"rev 9",	"rev 10",	"rev 11",
90	"rev 12",	"rev 13",	"rev 14",	"rev 15",
91};
92
93static const char * const i81342_steppings[16] = {
94	"step A-0",	"rev 1",	"rev 2",	"rev 3",
95	"rev 4",	"rev 5",	"rev 6",	"rev 7",
96	"rev 8",	"rev 9",	"rev 10",	"rev 11",
97	"rev 12",	"rev 13",	"rev 14",	"rev 15",
98};
99
100/* Steppings for PXA2[15]0 */
101static const char * const pxa2x0_steppings[16] = {
102	"step A-0",	"step A-1",	"step B-0",	"step B-1",
103	"step B-2",	"step C-0",	"rev 6",	"rev 7",
104	"rev 8",	"rev 9",	"rev 10",	"rev 11",
105	"rev 12",	"rev 13",	"rev 14",	"rev 15",
106};
107
108/* Steppings for PXA255/26x.
109 * rev 5: PXA26x B0, rev 6: PXA255 A0
110 */
111static const char * const pxa255_steppings[16] = {
112	"rev 0",	"rev 1",	"rev 2",	"step A-0",
113	"rev 4",	"step B-0",	"step A-0",	"rev 7",
114	"rev 8",	"rev 9",	"rev 10",	"rev 11",
115	"rev 12",	"rev 13",	"rev 14",	"rev 15",
116};
117
118/* Stepping for PXA27x */
119static const char * const pxa27x_steppings[16] = {
120	"step A-0",	"step A-1",	"step B-0",	"step B-1",
121	"step C-0",	"rev 5",	"rev 6",	"rev 7",
122	"rev 8",	"rev 9",	"rev 10",	"rev 11",
123	"rev 12",	"rev 13",	"rev 14",	"rev 15",
124};
125
126static const char * const ixp425_steppings[16] = {
127	"step 0 (A0)",	"rev 1 (ARMv5TE)", "rev 2",	"rev 3",
128	"rev 4",	"rev 5",	"rev 6",	"rev 7",
129	"rev 8",	"rev 9",	"rev 10",	"rev 11",
130	"rev 12",	"rev 13",	"rev 14",	"rev 15",
131};
132
133struct cpuidtab {
134	u_int32_t	cpuid;
135	enum		cpu_class cpu_class;
136	const char	*cpu_name;
137	const char * const *cpu_steppings;
138};
139
140const struct cpuidtab cpuids[] = {
141	{ CPU_ID_ARM920T,	CPU_CLASS_ARM9TDMI,	"ARM920T",
142	  generic_steppings },
143	{ CPU_ID_ARM920T_ALT,	CPU_CLASS_ARM9TDMI,	"ARM920T",
144	  generic_steppings },
145	{ CPU_ID_ARM922T,	CPU_CLASS_ARM9TDMI,	"ARM922T",
146	  generic_steppings },
147	{ CPU_ID_ARM926EJS,	CPU_CLASS_ARM9EJS,	"ARM926EJ-S",
148	  generic_steppings },
149	{ CPU_ID_ARM940T,	CPU_CLASS_ARM9TDMI,	"ARM940T",
150	  generic_steppings },
151	{ CPU_ID_ARM946ES,	CPU_CLASS_ARM9ES,	"ARM946E-S",
152	  generic_steppings },
153	{ CPU_ID_ARM966ES,	CPU_CLASS_ARM9ES,	"ARM966E-S",
154	  generic_steppings },
155	{ CPU_ID_ARM966ESR1,	CPU_CLASS_ARM9ES,	"ARM966E-S",
156	  generic_steppings },
157	{ CPU_ID_FA526,		CPU_CLASS_ARM9TDMI,	"FA526",
158	  generic_steppings },
159	{ CPU_ID_FA626TE,	CPU_CLASS_ARM9ES,	"FA626TE",
160	  generic_steppings },
161
162	{ CPU_ID_TI925T,	CPU_CLASS_ARM9TDMI,	"TI ARM925T",
163	  generic_steppings },
164
165	{ CPU_ID_ARM1020E,	CPU_CLASS_ARM10E,	"ARM1020E",
166	  generic_steppings },
167	{ CPU_ID_ARM1022ES,	CPU_CLASS_ARM10E,	"ARM1022E-S",
168	  generic_steppings },
169	{ CPU_ID_ARM1026EJS,	CPU_CLASS_ARM10EJ,	"ARM1026EJ-S",
170	  generic_steppings },
171
172	{ CPU_ID_CORTEXA7,	CPU_CLASS_CORTEXA,	"Cortex A7",
173	  generic_steppings },
174	{ CPU_ID_CORTEXA8R1,	CPU_CLASS_CORTEXA,	"Cortex A8-r1",
175	  generic_steppings },
176	{ CPU_ID_CORTEXA8R2,	CPU_CLASS_CORTEXA,	"Cortex A8-r2",
177	  generic_steppings },
178	{ CPU_ID_CORTEXA8R3,	CPU_CLASS_CORTEXA,	"Cortex A8-r3",
179	  generic_steppings },
180	{ CPU_ID_CORTEXA9R1,	CPU_CLASS_CORTEXA,	"Cortex A9-r1",
181	  generic_steppings },
182	{ CPU_ID_CORTEXA9R2,	CPU_CLASS_CORTEXA,	"Cortex A9-r2",
183	  generic_steppings },
184	{ CPU_ID_CORTEXA9R3,	CPU_CLASS_CORTEXA,	"Cortex A9-r3",
185	  generic_steppings },
186	{ CPU_ID_CORTEXA15R0,	CPU_CLASS_CORTEXA,	"Cortex A15-r0",
187	  generic_steppings },
188	{ CPU_ID_CORTEXA15R1,	CPU_CLASS_CORTEXA,	"Cortex A15-r1",
189	  generic_steppings },
190	{ CPU_ID_CORTEXA15R2,	CPU_CLASS_CORTEXA,	"Cortex A15-r2",
191	  generic_steppings },
192	{ CPU_ID_CORTEXA15R3,	CPU_CLASS_CORTEXA,	"Cortex A15-r3",
193	  generic_steppings },
194	{ CPU_ID_KRAIT,		CPU_CLASS_KRAIT,	"Krait",
195	  generic_steppings },
196
197	{ CPU_ID_80200,		CPU_CLASS_XSCALE,	"i80200",
198	  xscale_steppings },
199
200	{ CPU_ID_80321_400,	CPU_CLASS_XSCALE,	"i80321 400MHz",
201	  i80321_steppings },
202	{ CPU_ID_80321_600,	CPU_CLASS_XSCALE,	"i80321 600MHz",
203	  i80321_steppings },
204	{ CPU_ID_80321_400_B0,	CPU_CLASS_XSCALE,	"i80321 400MHz",
205	  i80321_steppings },
206	{ CPU_ID_80321_600_B0,	CPU_CLASS_XSCALE,	"i80321 600MHz",
207	  i80321_steppings },
208
209	{ CPU_ID_81342,		CPU_CLASS_XSCALE,	"i81342",
210	  i81342_steppings },
211
212	{ CPU_ID_80219_400,	CPU_CLASS_XSCALE,	"i80219 400MHz",
213	  i80219_steppings },
214	{ CPU_ID_80219_600,	CPU_CLASS_XSCALE,	"i80219 600MHz",
215	  i80219_steppings },
216
217	{ CPU_ID_PXA27X,	CPU_CLASS_XSCALE,	"PXA27x",
218	  pxa27x_steppings },
219	{ CPU_ID_PXA250A,	CPU_CLASS_XSCALE,	"PXA250",
220	  pxa2x0_steppings },
221	{ CPU_ID_PXA210A,	CPU_CLASS_XSCALE,	"PXA210",
222	  pxa2x0_steppings },
223	{ CPU_ID_PXA250B,	CPU_CLASS_XSCALE,	"PXA250",
224	  pxa2x0_steppings },
225	{ CPU_ID_PXA210B,	CPU_CLASS_XSCALE,	"PXA210",
226	  pxa2x0_steppings },
227	{ CPU_ID_PXA250C, 	CPU_CLASS_XSCALE,	"PXA255",
228	  pxa255_steppings },
229	{ CPU_ID_PXA210C, 	CPU_CLASS_XSCALE,	"PXA210",
230	  pxa2x0_steppings },
231
232	{ CPU_ID_IXP425_533,	CPU_CLASS_XSCALE,	"IXP425 533MHz",
233	  ixp425_steppings },
234	{ CPU_ID_IXP425_400,	CPU_CLASS_XSCALE,	"IXP425 400MHz",
235	  ixp425_steppings },
236	{ CPU_ID_IXP425_266,	CPU_CLASS_XSCALE,	"IXP425 266MHz",
237	  ixp425_steppings },
238
239	/* XXX ixp435 steppings? */
240	{ CPU_ID_IXP435,	CPU_CLASS_XSCALE,	"IXP435",
241	  ixp425_steppings },
242
243	{ CPU_ID_ARM1136JS,	CPU_CLASS_ARM11J,	"ARM1136J-S",
244	  generic_steppings },
245	{ CPU_ID_ARM1136JSR1,	CPU_CLASS_ARM11J,	"ARM1136J-S R1",
246	  generic_steppings },
247	{ CPU_ID_ARM1176JZS,	CPU_CLASS_ARM11J,	"ARM1176JZ-S",
248	  generic_steppings },
249
250	{ CPU_ID_MV88FR131,	CPU_CLASS_MARVELL,	"Feroceon 88FR131",
251	  generic_steppings },
252
253	{ CPU_ID_MV88FR571_VD,	CPU_CLASS_MARVELL,	"Feroceon 88FR571-VD",
254	  generic_steppings },
255	{ CPU_ID_MV88SV581X_V7,	CPU_CLASS_MARVELL,	"Sheeva 88SV581x",
256	  generic_steppings },
257	{ CPU_ID_ARM_88SV581X_V7, CPU_CLASS_MARVELL,	"Sheeva 88SV581x",
258	  generic_steppings },
259	{ CPU_ID_MV88SV584X_V7,	CPU_CLASS_MARVELL,	"Sheeva 88SV584x",
260	  generic_steppings },
261
262	{ 0, CPU_CLASS_NONE, NULL, NULL }
263};
264
265struct cpu_classtab {
266	const char	*class_name;
267	const char	*class_option;
268};
269
270const struct cpu_classtab cpu_classes[] = {
271	{ "unknown",	NULL },			/* CPU_CLASS_NONE */
272	{ "ARM9TDMI",	"CPU_ARM9TDMI" },	/* CPU_CLASS_ARM9TDMI */
273	{ "ARM9E-S",	"CPU_ARM9E" },		/* CPU_CLASS_ARM9ES */
274	{ "ARM9EJ-S",	"CPU_ARM9E" },		/* CPU_CLASS_ARM9EJS */
275	{ "ARM10E",	"CPU_ARM10" },		/* CPU_CLASS_ARM10E */
276	{ "ARM10EJ",	"CPU_ARM10" },		/* CPU_CLASS_ARM10EJ */
277	{ "Cortex-A",	"CPU_CORTEXA" },	/* CPU_CLASS_CORTEXA */
278	{ "Krait",	"CPU_KRAIT" },		/* CPU_CLASS_KRAIT */
279	{ "XScale",	"CPU_XSCALE_..." },	/* CPU_CLASS_XSCALE */
280	{ "ARM11J",	"CPU_ARM11" },		/* CPU_CLASS_ARM11J */
281	{ "Marvell",	"CPU_MARVELL" },	/* CPU_CLASS_MARVELL */
282};
283
284/*
285 * Report the type of the specified arm processor. This uses the generic and
286 * arm specific information in the cpu structure to identify the processor.
287 * The remaining fields in the cpu structure are filled in appropriately.
288 */
289
290static const char * const wtnames[] = {
291	"write-through",
292	"write-back",
293	"write-back",
294	"**unknown 3**",
295	"**unknown 4**",
296	"write-back-locking",		/* XXX XScale-specific? */
297	"write-back-locking-A",
298	"write-back-locking-B",
299	"**unknown 8**",
300	"**unknown 9**",
301	"**unknown 10**",
302	"**unknown 11**",
303	"**unknown 12**",
304	"**unknown 13**",
305	"write-back-locking-C",
306	"**unknown 15**",
307};
308
309static void
310print_enadis(int enadis, char *s)
311{
312
313	printf(" %s %sabled", s, (enadis == 0) ? "dis" : "en");
314}
315
316extern int ctrl;
317enum cpu_class cpu_class = CPU_CLASS_NONE;
318
319u_int cpu_pfr(int num)
320{
321	u_int feat;
322
323	switch (num) {
324	case 0:
325		__asm __volatile("mrc p15, 0, %0, c0, c1, 0"
326		    : "=r" (feat));
327		break;
328	case 1:
329		__asm __volatile("mrc p15, 0, %0, c0, c1, 1"
330		    : "=r" (feat));
331		break;
332	default:
333		panic("Processor Feature Register %d not implemented", num);
334		break;
335	}
336
337	return (feat);
338}
339
340static
341void identify_armv7(void)
342{
343	u_int feature;
344
345	printf("Supported features:");
346	/* Get Processor Feature Register 0 */
347	feature = cpu_pfr(0);
348
349	if (feature & ARM_PFR0_ARM_ISA_MASK)
350		printf(" ARM_ISA");
351
352	if (feature & ARM_PFR0_THUMB2)
353		printf(" THUMB2");
354	else if (feature & ARM_PFR0_THUMB)
355		printf(" THUMB");
356
357	if (feature & ARM_PFR0_JAZELLE_MASK)
358		printf(" JAZELLE");
359
360	if (feature & ARM_PFR0_THUMBEE_MASK)
361		printf(" THUMBEE");
362
363
364	/* Get Processor Feature Register 1 */
365	feature = cpu_pfr(1);
366
367	if (feature & ARM_PFR1_ARMV4_MASK)
368		printf(" ARMv4");
369
370	if (feature & ARM_PFR1_SEC_EXT_MASK)
371		printf(" Security_Ext");
372
373	if (feature & ARM_PFR1_MICROCTRL_MASK)
374		printf(" M_profile");
375
376	printf("\n");
377}
378
379void
380identify_arm_cpu(void)
381{
382	u_int cpuid, reg, size, sets, ways;
383	u_int8_t type, linesize;
384	int i;
385
386	cpuid = cpu_id();
387
388	if (cpuid == 0) {
389		printf("Processor failed probe - no CPU ID\n");
390		return;
391	}
392
393	for (i = 0; cpuids[i].cpuid != 0; i++)
394		if (cpuids[i].cpuid == (cpuid & CPU_ID_CPU_MASK)) {
395			cpu_class = cpuids[i].cpu_class;
396			printf("CPU: %s %s (%s core)\n",
397			    cpuids[i].cpu_name,
398			    cpuids[i].cpu_steppings[cpuid &
399			    CPU_ID_REVISION_MASK],
400			    cpu_classes[cpu_class].class_name);
401			break;
402		}
403	if (cpuids[i].cpuid == 0)
404		printf("unknown CPU (ID = 0x%x)\n", cpuid);
405
406	printf(" ");
407
408	if ((cpuid & CPU_ID_ARCH_MASK) == CPU_ID_CPUID_SCHEME) {
409		identify_armv7();
410	} else {
411		if (ctrl & CPU_CONTROL_BEND_ENABLE)
412			printf(" Big-endian");
413		else
414			printf(" Little-endian");
415
416		switch (cpu_class) {
417		case CPU_CLASS_ARM9TDMI:
418		case CPU_CLASS_ARM9ES:
419		case CPU_CLASS_ARM9EJS:
420		case CPU_CLASS_ARM10E:
421		case CPU_CLASS_ARM10EJ:
422		case CPU_CLASS_XSCALE:
423		case CPU_CLASS_ARM11J:
424		case CPU_CLASS_MARVELL:
425			print_enadis(ctrl & CPU_CONTROL_DC_ENABLE, "DC");
426			print_enadis(ctrl & CPU_CONTROL_IC_ENABLE, "IC");
427#ifdef CPU_XSCALE_81342
428			print_enadis(ctrl & CPU_CONTROL_L2_ENABLE, "L2");
429#endif
430#if defined(SOC_MV_KIRKWOOD) || defined(SOC_MV_DISCOVERY)
431			i = sheeva_control_ext(0, 0);
432			print_enadis(i & MV_WA_ENABLE, "WA");
433			print_enadis(i & MV_DC_STREAM_ENABLE, "DC streaming");
434			printf("\n ");
435			print_enadis((i & MV_BTB_DISABLE) == 0, "BTB");
436			print_enadis(i & MV_L2_ENABLE, "L2");
437			print_enadis((i & MV_L2_PREFETCH_DISABLE) == 0,
438			    "L2 prefetch");
439			printf("\n ");
440#endif
441			break;
442		default:
443			break;
444		}
445	}
446
447	print_enadis(ctrl & CPU_CONTROL_WBUF_ENABLE, "WB");
448	if (ctrl & CPU_CONTROL_LABT_ENABLE)
449		printf(" LABT");
450	else
451		printf(" EABT");
452
453	print_enadis(ctrl & CPU_CONTROL_BPRD_ENABLE, "branch prediction");
454	printf("\n");
455
456	if (arm_cache_level) {
457		printf("LoUU:%d LoC:%d LoUIS:%d \n", CPU_CLIDR_LOUU(arm_cache_level) + 1,
458		    arm_cache_loc, CPU_CLIDR_LOUIS(arm_cache_level) + 1);
459		i = 0;
460		while (((type = CPU_CLIDR_CTYPE(arm_cache_level, i)) != 0) && i < 7) {
461			printf("Cache level %d: \n", i + 1);
462			if (type == CACHE_DCACHE || type == CACHE_UNI_CACHE ||
463			    type == CACHE_SEP_CACHE) {
464				reg = arm_cache_type[2 * i];
465				ways = CPUV7_CT_xSIZE_ASSOC(reg) + 1;
466				sets = CPUV7_CT_xSIZE_SET(reg) + 1;
467				linesize = 1 << (CPUV7_CT_xSIZE_LEN(reg) + 4);
468				size = (ways * sets * linesize) / 1024;
469
470				if (type == CACHE_UNI_CACHE)
471					printf(" %dKB/%dB %d-way unified cache", size, linesize,ways);
472				else
473					printf(" %dKB/%dB %d-way data cache", size, linesize, ways);
474				if (reg & CPUV7_CT_CTYPE_WT)
475					printf(" WT");
476				if (reg & CPUV7_CT_CTYPE_WB)
477					printf(" WB");
478				if (reg & CPUV7_CT_CTYPE_RA)
479					printf(" Read-Alloc");
480				if (reg & CPUV7_CT_CTYPE_WA)
481					printf(" Write-Alloc");
482				printf("\n");
483			}
484
485			if (type == CACHE_ICACHE || type == CACHE_SEP_CACHE) {
486				reg = arm_cache_type[(2 * i) + 1];
487
488				ways = CPUV7_CT_xSIZE_ASSOC(reg) + 1;
489				sets = CPUV7_CT_xSIZE_SET(reg) + 1;
490				linesize = 1 << (CPUV7_CT_xSIZE_LEN(reg) + 4);
491				size = (ways * sets * linesize) / 1024;
492
493				printf(" %dKB/%dB %d-way instruction cache", size, linesize, ways);
494				if (reg & CPUV7_CT_CTYPE_WT)
495					printf(" WT");
496				if (reg & CPUV7_CT_CTYPE_WB)
497					printf(" WB");
498				if (reg & CPUV7_CT_CTYPE_RA)
499					printf(" Read-Alloc");
500				if (reg & CPUV7_CT_CTYPE_WA)
501					printf(" Write-Alloc");
502				printf("\n");
503			}
504			i++;
505		}
506	} else {
507		/* Print cache info. */
508		if (arm_picache_line_size == 0 && arm_pdcache_line_size == 0)
509			return;
510
511		if (arm_pcache_unified) {
512			printf("  %dKB/%dB %d-way %s unified cache\n",
513			    arm_pdcache_size / 1024,
514			    arm_pdcache_line_size, arm_pdcache_ways,
515			    wtnames[arm_pcache_type]);
516		} else {
517			printf("  %dKB/%dB %d-way instruction cache\n",
518			    arm_picache_size / 1024,
519			    arm_picache_line_size, arm_picache_ways);
520			printf("  %dKB/%dB %d-way %s data cache\n",
521			    arm_pdcache_size / 1024,
522			    arm_pdcache_line_size, arm_pdcache_ways,
523			    wtnames[arm_pcache_type]);
524		}
525	}
526}
527