Home | History | Annotate | Line # | Download | only in arm32
cpu.c revision 1.9.2.4
      1  1.9.2.4  nathanw /*	$NetBSD: cpu.c,v 1.9.2.4 2002/04/01 07:39:07 nathanw Exp $	*/
      2  1.9.2.2  nathanw 
      3  1.9.2.2  nathanw /*
      4  1.9.2.2  nathanw  * Copyright (c) 1995 Mark Brinicombe.
      5  1.9.2.2  nathanw  * Copyright (c) 1995 Brini.
      6  1.9.2.2  nathanw  * All rights reserved.
      7  1.9.2.2  nathanw  *
      8  1.9.2.2  nathanw  * Redistribution and use in source and binary forms, with or without
      9  1.9.2.2  nathanw  * modification, are permitted provided that the following conditions
     10  1.9.2.2  nathanw  * are met:
     11  1.9.2.2  nathanw  * 1. Redistributions of source code must retain the above copyright
     12  1.9.2.2  nathanw  *    notice, this list of conditions and the following disclaimer.
     13  1.9.2.2  nathanw  * 2. Redistributions in binary form must reproduce the above copyright
     14  1.9.2.2  nathanw  *    notice, this list of conditions and the following disclaimer in the
     15  1.9.2.2  nathanw  *    documentation and/or other materials provided with the distribution.
     16  1.9.2.2  nathanw  * 3. All advertising materials mentioning features or use of this software
     17  1.9.2.2  nathanw  *    must display the following acknowledgement:
     18  1.9.2.2  nathanw  *	This product includes software developed by Brini.
     19  1.9.2.2  nathanw  * 4. The name of the company nor the name of the author may be used to
     20  1.9.2.2  nathanw  *    endorse or promote products derived from this software without specific
     21  1.9.2.2  nathanw  *    prior written permission.
     22  1.9.2.2  nathanw  *
     23  1.9.2.2  nathanw  * THIS SOFTWARE IS PROVIDED BY BRINI ``AS IS'' AND ANY EXPRESS OR IMPLIED
     24  1.9.2.2  nathanw  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
     25  1.9.2.2  nathanw  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     26  1.9.2.2  nathanw  * IN NO EVENT SHALL BRINI OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
     27  1.9.2.2  nathanw  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
     28  1.9.2.2  nathanw  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
     29  1.9.2.2  nathanw  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     30  1.9.2.2  nathanw  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     31  1.9.2.2  nathanw  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     32  1.9.2.2  nathanw  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     33  1.9.2.2  nathanw  * SUCH DAMAGE.
     34  1.9.2.2  nathanw  *
     35  1.9.2.2  nathanw  * RiscBSD kernel project
     36  1.9.2.2  nathanw  *
     37  1.9.2.2  nathanw  * cpu.c
     38  1.9.2.2  nathanw  *
     39  1.9.2.2  nathanw  * Probing and configuration for the master cpu
     40  1.9.2.2  nathanw  *
     41  1.9.2.2  nathanw  * Created      : 10/10/95
     42  1.9.2.2  nathanw  */
     43  1.9.2.2  nathanw 
     44  1.9.2.2  nathanw #include "opt_armfpe.h"
     45  1.9.2.2  nathanw #include "opt_cputypes.h"
     46  1.9.2.2  nathanw 
     47  1.9.2.2  nathanw #include <sys/param.h>
     48  1.9.2.4  nathanw 
     49  1.9.2.4  nathanw __KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.9.2.4 2002/04/01 07:39:07 nathanw Exp $");
     50  1.9.2.4  nathanw 
     51  1.9.2.2  nathanw #include <sys/systm.h>
     52  1.9.2.2  nathanw #include <sys/malloc.h>
     53  1.9.2.2  nathanw #include <sys/device.h>
     54  1.9.2.2  nathanw #include <sys/proc.h>
     55  1.9.2.2  nathanw #include <uvm/uvm_extern.h>
     56  1.9.2.2  nathanw #include <machine/conf.h>
     57  1.9.2.2  nathanw #include <machine/cpu.h>
     58  1.9.2.2  nathanw #include <arm/undefined.h>
     59  1.9.2.2  nathanw 
     60  1.9.2.2  nathanw #ifdef ARMFPE
     61  1.9.2.2  nathanw #include <machine/bootconfig.h> /* For boot args */
     62  1.9.2.2  nathanw #include <arm/fpe-arm/armfpe.h>
     63  1.9.2.2  nathanw #endif
     64  1.9.2.2  nathanw 
     65  1.9.2.4  nathanw char cpu_model[256];
     66  1.9.2.2  nathanw 
     67  1.9.2.2  nathanw /* Prototypes */
     68  1.9.2.4  nathanw void identify_arm_cpu(struct device *dv, struct cpu_info *);
     69  1.9.2.2  nathanw 
     70  1.9.2.2  nathanw /*
     71  1.9.2.4  nathanw  * Identify the master (boot) CPU
     72  1.9.2.2  nathanw  */
     73  1.9.2.2  nathanw 
     74  1.9.2.2  nathanw void
     75  1.9.2.3  nathanw cpu_attach(struct device *dv)
     76  1.9.2.2  nathanw {
     77  1.9.2.4  nathanw 	int usearmfpe;
     78  1.9.2.3  nathanw 
     79  1.9.2.4  nathanw 	usearmfpe = 1;	/* when compiled in, its enabled by default */
     80  1.9.2.2  nathanw 
     81  1.9.2.4  nathanw 	curcpu()->ci_dev = dv;
     82  1.9.2.2  nathanw 
     83  1.9.2.4  nathanw 	evcnt_attach_dynamic(&curcpu()->ci_arm700bugcount, EVCNT_TYPE_MISC,
     84  1.9.2.4  nathanw 	    NULL, dv->dv_xname, "arm700swibug");
     85  1.9.2.4  nathanw 
     86  1.9.2.2  nathanw 	/* Get the cpu ID from coprocessor 15 */
     87  1.9.2.2  nathanw 
     88  1.9.2.4  nathanw 	curcpu()->ci_cpuid = cpu_id();
     89  1.9.2.4  nathanw 	curcpu()->ci_cputype = curcpu()->ci_cpuid & CPU_ID_CPU_MASK;
     90  1.9.2.4  nathanw 	curcpu()->ci_cpurev = curcpu()->ci_cpuid & CPU_ID_REVISION_MASK;
     91  1.9.2.2  nathanw 
     92  1.9.2.4  nathanw 	identify_arm_cpu(dv, curcpu());
     93  1.9.2.2  nathanw 
     94  1.9.2.4  nathanw 	if (curcpu()->ci_cputype == CPU_ID_SA110 && curcpu()->ci_cpurev < 3) {
     95  1.9.2.2  nathanw 		printf("%s: SA-110 with bugged STM^ instruction\n",
     96  1.9.2.2  nathanw 		       dv->dv_xname);
     97  1.9.2.2  nathanw 	}
     98  1.9.2.2  nathanw 
     99  1.9.2.2  nathanw #ifdef CPU_ARM8
    100  1.9.2.4  nathanw 	if ((curcpu()->ci_cpuid & CPU_ID_CPU_MASK) == CPU_ID_ARM810) {
    101  1.9.2.2  nathanw 		int clock = arm8_clock_config(0, 0);
    102  1.9.2.2  nathanw 		char *fclk;
    103  1.9.2.2  nathanw 		printf("%s: ARM810 cp15=%02x", dv->dv_xname, clock);
    104  1.9.2.2  nathanw 		printf(" clock:%s", (clock & 1) ? " dynamic" : "");
    105  1.9.2.2  nathanw 		printf("%s", (clock & 2) ? " sync" : "");
    106  1.9.2.2  nathanw 		switch ((clock >> 2) & 3) {
    107  1.9.2.3  nathanw 		case 0:
    108  1.9.2.2  nathanw 			fclk = "bus clock";
    109  1.9.2.2  nathanw 			break;
    110  1.9.2.3  nathanw 		case 1:
    111  1.9.2.2  nathanw 			fclk = "ref clock";
    112  1.9.2.2  nathanw 			break;
    113  1.9.2.3  nathanw 		case 3:
    114  1.9.2.2  nathanw 			fclk = "pll";
    115  1.9.2.2  nathanw 			break;
    116  1.9.2.3  nathanw 		default:
    117  1.9.2.2  nathanw 			fclk = "illegal";
    118  1.9.2.2  nathanw 			break;
    119  1.9.2.2  nathanw 		}
    120  1.9.2.2  nathanw 		printf(" fclk source=%s\n", fclk);
    121  1.9.2.2  nathanw  	}
    122  1.9.2.2  nathanw #endif
    123  1.9.2.2  nathanw 
    124  1.9.2.4  nathanw #ifdef ARMFPE
    125  1.9.2.2  nathanw 	/*
    126  1.9.2.2  nathanw 	 * Ok now we test for an FPA
    127  1.9.2.2  nathanw 	 * At this point no floating point emulator has been installed.
    128  1.9.2.2  nathanw 	 * This means any FP instruction will cause undefined exception.
    129  1.9.2.2  nathanw 	 * We install a temporay coproc 1 handler which will modify
    130  1.9.2.2  nathanw 	 * undefined_test if it is called.
    131  1.9.2.2  nathanw 	 * We then try to read the FP status register. If undefined_test
    132  1.9.2.2  nathanw 	 * has been decremented then the instruction was not handled by
    133  1.9.2.2  nathanw 	 * an FPA so we know the FPA is missing. If undefined_test is
    134  1.9.2.2  nathanw 	 * still 1 then we know the instruction was handled by an FPA.
    135  1.9.2.2  nathanw 	 * We then remove our test handler and look at the
    136  1.9.2.2  nathanw 	 * FP status register for identification.
    137  1.9.2.2  nathanw 	 */
    138  1.9.2.2  nathanw 
    139  1.9.2.4  nathanw 	/*
    140  1.9.2.4  nathanw 	 * Ok if ARMFPE is defined and the boot options request the
    141  1.9.2.4  nathanw 	 * ARM FPE then it will be installed as the FPE.
    142  1.9.2.4  nathanw 	 * This is just while I work on integrating the new FPE.
    143  1.9.2.4  nathanw 	 * It means the new FPE gets installed if compiled int (ARMFPE
    144  1.9.2.4  nathanw 	 * defined) and also gives me a on/off option when I boot in
    145  1.9.2.4  nathanw 	 * case the new FPE is causing panics.
    146  1.9.2.4  nathanw 	 */
    147  1.9.2.2  nathanw 
    148  1.9.2.2  nathanw 
    149  1.9.2.4  nathanw 	if (boot_args)
    150  1.9.2.4  nathanw 		get_bootconf_option(boot_args, "armfpe",
    151  1.9.2.4  nathanw 		    BOOTOPT_TYPE_BOOLEAN, &usearmfpe);
    152  1.9.2.4  nathanw 	if (usearmfpe)
    153  1.9.2.4  nathanw 		initialise_arm_fpe();
    154  1.9.2.2  nathanw #endif
    155  1.9.2.2  nathanw }
    156  1.9.2.2  nathanw 
    157  1.9.2.4  nathanw enum cpu_class {
    158  1.9.2.4  nathanw 	CPU_CLASS_NONE,
    159  1.9.2.4  nathanw 	CPU_CLASS_ARM2,
    160  1.9.2.4  nathanw 	CPU_CLASS_ARM2AS,
    161  1.9.2.4  nathanw 	CPU_CLASS_ARM3,
    162  1.9.2.4  nathanw 	CPU_CLASS_ARM6,
    163  1.9.2.4  nathanw 	CPU_CLASS_ARM7,
    164  1.9.2.4  nathanw 	CPU_CLASS_ARM7TDMI,
    165  1.9.2.4  nathanw 	CPU_CLASS_ARM8,
    166  1.9.2.4  nathanw 	CPU_CLASS_ARM9TDMI,
    167  1.9.2.4  nathanw 	CPU_CLASS_ARM9ES,
    168  1.9.2.4  nathanw 	CPU_CLASS_SA1,
    169  1.9.2.4  nathanw 	CPU_CLASS_XSCALE,
    170  1.9.2.4  nathanw 	CPU_CLASS_ARM10E
    171  1.9.2.4  nathanw };
    172  1.9.2.4  nathanw 
    173  1.9.2.3  nathanw static const char *generic_steppings[16] = {
    174  1.9.2.3  nathanw 	"rev 0",	"rev 1",	"rev 2",	"rev 3",
    175  1.9.2.3  nathanw 	"rev 4",	"rev 5",	"rev 6",	"rev 7",
    176  1.9.2.3  nathanw 	"rev 8",	"rev 9",	"rev 10",	"rev 11",
    177  1.9.2.3  nathanw 	"rev 12",	"rev 13",	"rev 14",	"rev 15",
    178  1.9.2.3  nathanw };
    179  1.9.2.3  nathanw 
    180  1.9.2.3  nathanw static const char *sa110_steppings[16] = {
    181  1.9.2.3  nathanw 	"rev 0",	"step J",	"step K",	"step S",
    182  1.9.2.3  nathanw 	"step T",	"rev 5",	"rev 6",	"rev 7",
    183  1.9.2.3  nathanw 	"rev 8",	"rev 9",	"rev 10",	"rev 11",
    184  1.9.2.3  nathanw 	"rev 12",	"rev 13",	"rev 14",	"rev 15",
    185  1.9.2.3  nathanw };
    186  1.9.2.3  nathanw 
    187  1.9.2.3  nathanw static const char *sa1100_steppings[16] = {
    188  1.9.2.3  nathanw 	"rev 0",	"step B",	"step C",	"rev 3",
    189  1.9.2.3  nathanw 	"rev 4",	"rev 5",	"rev 6",	"rev 7",
    190  1.9.2.3  nathanw 	"step D",	"step E",	"rev 10"	"step G",
    191  1.9.2.3  nathanw 	"rev 12",	"rev 13",	"rev 14",	"rev 15",
    192  1.9.2.3  nathanw };
    193  1.9.2.3  nathanw 
    194  1.9.2.3  nathanw static const char *sa1110_steppings[16] = {
    195  1.9.2.3  nathanw 	"step A-0",	"rev 1",	"rev 2",	"rev 3",
    196  1.9.2.3  nathanw 	"step B-0",	"step B-1",	"step B-2",	"step B-3",
    197  1.9.2.3  nathanw 	"step B-4",	"step B-5",	"rev 10",	"rev 11",
    198  1.9.2.3  nathanw 	"rev 12",	"rev 13",	"rev 14",	"rev 15",
    199  1.9.2.3  nathanw };
    200  1.9.2.3  nathanw 
    201  1.9.2.4  nathanw static const char *xscale_steppings[16] = {
    202  1.9.2.3  nathanw 	"step A-0",	"step A-1",	"step B-0",	"step C-0",
    203  1.9.2.3  nathanw 	"rev 4",	"rev 5",	"rev 6",	"rev 7",
    204  1.9.2.3  nathanw 	"rev 8",	"rev 9",	"rev 10",	"rev 11",
    205  1.9.2.3  nathanw 	"rev 12",	"rev 13",	"rev 14",	"rev 15",
    206  1.9.2.3  nathanw };
    207  1.9.2.3  nathanw 
    208  1.9.2.2  nathanw struct cpuidtab {
    209  1.9.2.2  nathanw 	u_int32_t	cpuid;
    210  1.9.2.2  nathanw 	enum		cpu_class cpu_class;
    211  1.9.2.2  nathanw 	const char	*cpu_name;
    212  1.9.2.3  nathanw 	const char	**cpu_steppings;
    213  1.9.2.2  nathanw };
    214  1.9.2.2  nathanw 
    215  1.9.2.2  nathanw const struct cpuidtab cpuids[] = {
    216  1.9.2.3  nathanw 	{ CPU_ID_ARM2,		CPU_CLASS_ARM2,		"ARM2",
    217  1.9.2.3  nathanw 	  generic_steppings },
    218  1.9.2.3  nathanw 	{ CPU_ID_ARM250,	CPU_CLASS_ARM2AS,	"ARM250",
    219  1.9.2.3  nathanw 	  generic_steppings },
    220  1.9.2.3  nathanw 
    221  1.9.2.3  nathanw 	{ CPU_ID_ARM3,		CPU_CLASS_ARM3,		"ARM3",
    222  1.9.2.3  nathanw 	  generic_steppings },
    223  1.9.2.3  nathanw 
    224  1.9.2.3  nathanw 	{ CPU_ID_ARM600,	CPU_CLASS_ARM6,		"ARM600",
    225  1.9.2.3  nathanw 	  generic_steppings },
    226  1.9.2.3  nathanw 	{ CPU_ID_ARM610,	CPU_CLASS_ARM6,		"ARM610",
    227  1.9.2.3  nathanw 	  generic_steppings },
    228  1.9.2.3  nathanw 	{ CPU_ID_ARM620,	CPU_CLASS_ARM6,		"ARM620",
    229  1.9.2.3  nathanw 	  generic_steppings },
    230  1.9.2.3  nathanw 
    231  1.9.2.3  nathanw 	{ CPU_ID_ARM700,	CPU_CLASS_ARM7,		"ARM700",
    232  1.9.2.3  nathanw 	  generic_steppings },
    233  1.9.2.3  nathanw 	{ CPU_ID_ARM710,	CPU_CLASS_ARM7,		"ARM710",
    234  1.9.2.3  nathanw 	  generic_steppings },
    235  1.9.2.3  nathanw 	{ CPU_ID_ARM7500,	CPU_CLASS_ARM7,		"ARM7500",
    236  1.9.2.3  nathanw 	  generic_steppings },
    237  1.9.2.3  nathanw 	{ CPU_ID_ARM710A,	CPU_CLASS_ARM7,		"ARM710a",
    238  1.9.2.3  nathanw 	  generic_steppings },
    239  1.9.2.3  nathanw 	{ CPU_ID_ARM7500FE,	CPU_CLASS_ARM7,		"ARM7500FE",
    240  1.9.2.3  nathanw 	  generic_steppings },
    241  1.9.2.3  nathanw 	{ CPU_ID_ARM710T,	CPU_CLASS_ARM7TDMI,	"ARM710T",
    242  1.9.2.3  nathanw 	  generic_steppings },
    243  1.9.2.3  nathanw 	{ CPU_ID_ARM720T,	CPU_CLASS_ARM7TDMI,	"ARM720T",
    244  1.9.2.3  nathanw 	  generic_steppings },
    245  1.9.2.3  nathanw 	{ CPU_ID_ARM740T8K,	CPU_CLASS_ARM7TDMI, "ARM740T (8 KB cache)",
    246  1.9.2.3  nathanw 	  generic_steppings },
    247  1.9.2.3  nathanw 	{ CPU_ID_ARM740T4K,	CPU_CLASS_ARM7TDMI, "ARM740T (4 KB cache)",
    248  1.9.2.3  nathanw 	  generic_steppings },
    249  1.9.2.3  nathanw 
    250  1.9.2.3  nathanw 	{ CPU_ID_ARM810,	CPU_CLASS_ARM8,		"ARM810",
    251  1.9.2.3  nathanw 	  generic_steppings },
    252  1.9.2.3  nathanw 
    253  1.9.2.3  nathanw 	{ CPU_ID_ARM920T,	CPU_CLASS_ARM9TDMI,	"ARM920T",
    254  1.9.2.3  nathanw 	  generic_steppings },
    255  1.9.2.3  nathanw 	{ CPU_ID_ARM922T,	CPU_CLASS_ARM9TDMI,	"ARM922T",
    256  1.9.2.3  nathanw 	  generic_steppings },
    257  1.9.2.3  nathanw 	{ CPU_ID_ARM940T,	CPU_CLASS_ARM9TDMI,	"ARM940T",
    258  1.9.2.3  nathanw 	  generic_steppings },
    259  1.9.2.3  nathanw 	{ CPU_ID_ARM946ES,	CPU_CLASS_ARM9ES,	"ARM946E-S",
    260  1.9.2.3  nathanw 	  generic_steppings },
    261  1.9.2.3  nathanw 	{ CPU_ID_ARM966ES,	CPU_CLASS_ARM9ES,	"ARM966E-S",
    262  1.9.2.3  nathanw 	  generic_steppings },
    263  1.9.2.3  nathanw 	{ CPU_ID_ARM966ESR1,	CPU_CLASS_ARM9ES,	"ARM966E-S",
    264  1.9.2.3  nathanw 	  generic_steppings },
    265  1.9.2.3  nathanw 
    266  1.9.2.3  nathanw 	{ CPU_ID_SA110,		CPU_CLASS_SA1,		"SA-110",
    267  1.9.2.3  nathanw 	  sa110_steppings },
    268  1.9.2.3  nathanw 	{ CPU_ID_SA1100,	CPU_CLASS_SA1,		"SA-1100",
    269  1.9.2.3  nathanw 	  sa1100_steppings },
    270  1.9.2.3  nathanw 	{ CPU_ID_SA1110,	CPU_CLASS_SA1,		"SA-1110",
    271  1.9.2.3  nathanw 	  sa1110_steppings },
    272  1.9.2.3  nathanw 
    273  1.9.2.4  nathanw 	{ CPU_ID_80200,		CPU_CLASS_XSCALE,	"i80200",
    274  1.9.2.4  nathanw 	  xscale_steppings },
    275  1.9.2.4  nathanw 
    276  1.9.2.4  nathanw 	{ CPU_ID_80321,		CPU_CLASS_XSCALE,	"i80321",
    277  1.9.2.4  nathanw 	  xscale_steppings },
    278  1.9.2.4  nathanw 
    279  1.9.2.4  nathanw 	{ CPU_ID_ARM1022ES,	CPU_CLASS_ARM10E,	"ARM1022ES",
    280  1.9.2.4  nathanw 	  generic_steppings },
    281  1.9.2.3  nathanw 
    282  1.9.2.3  nathanw 	{ 0, CPU_CLASS_NONE, NULL, NULL }
    283  1.9.2.2  nathanw };
    284  1.9.2.2  nathanw 
    285  1.9.2.2  nathanw struct cpu_classtab {
    286  1.9.2.2  nathanw 	const char	*class_name;
    287  1.9.2.2  nathanw 	const char	*class_option;
    288  1.9.2.2  nathanw };
    289  1.9.2.2  nathanw 
    290  1.9.2.2  nathanw const struct cpu_classtab cpu_classes[] = {
    291  1.9.2.2  nathanw 	{ "unknown",	NULL },			/* CPU_CLASS_NONE */
    292  1.9.2.2  nathanw 	{ "ARM2",	"CPU_ARM2" },		/* CPU_CLASS_ARM2 */
    293  1.9.2.2  nathanw 	{ "ARM2as",	"CPU_ARM250" },		/* CPU_CLASS_ARM2AS */
    294  1.9.2.2  nathanw 	{ "ARM3",	"CPU_ARM3" },		/* CPU_CLASS_ARM3 */
    295  1.9.2.2  nathanw 	{ "ARM6",	"CPU_ARM6" },		/* CPU_CLASS_ARM6 */
    296  1.9.2.2  nathanw 	{ "ARM7",	"CPU_ARM7" },		/* CPU_CLASS_ARM7 */
    297  1.9.2.2  nathanw 	{ "ARM7TDMI",	"CPU_ARM7TDMI" },	/* CPU_CLASS_ARM7TDMI */
    298  1.9.2.2  nathanw 	{ "ARM8",	"CPU_ARM8" },		/* CPU_CLASS_ARM8 */
    299  1.9.2.2  nathanw 	{ "ARM9TDMI",	NULL },			/* CPU_CLASS_ARM9TDMI */
    300  1.9.2.2  nathanw 	{ "ARM9E-S",	NULL },			/* CPU_CLASS_ARM9ES */
    301  1.9.2.2  nathanw 	{ "SA-1",	"CPU_SA110" },		/* CPU_CLASS_SA1 */
    302  1.9.2.4  nathanw 	{ "XScale",	"CPU_XSCALE_..." },	/* CPU_CLASS_XSCALE */
    303  1.9.2.4  nathanw 	{ "ARM10E",	NULL },			/* CPU_CLASS_ARM10E */
    304  1.9.2.2  nathanw };
    305  1.9.2.2  nathanw 
    306  1.9.2.2  nathanw /*
    307  1.9.2.2  nathanw  * Report the type of the specifed arm processor. This uses the generic and
    308  1.9.2.2  nathanw  * arm specific information in the cpu structure to identify the processor.
    309  1.9.2.2  nathanw  * The remaining fields in the cpu structure are filled in appropriately.
    310  1.9.2.2  nathanw  */
    311  1.9.2.2  nathanw 
    312  1.9.2.2  nathanw static const char *wtnames[] = {
    313  1.9.2.2  nathanw 	"write-through",
    314  1.9.2.2  nathanw 	"write-back",
    315  1.9.2.2  nathanw 	"write-back",
    316  1.9.2.2  nathanw 	"**unknown 3**",
    317  1.9.2.2  nathanw 	"**unknown 4**",
    318  1.9.2.2  nathanw 	"write-back-locking",		/* XXX XScale-specific? */
    319  1.9.2.2  nathanw 	"write-back-locking-A",
    320  1.9.2.2  nathanw 	"write-back-locking-B",
    321  1.9.2.2  nathanw 	"**unknown 8**",
    322  1.9.2.2  nathanw 	"**unknown 9**",
    323  1.9.2.2  nathanw 	"**unknown 10**",
    324  1.9.2.2  nathanw 	"**unknown 11**",
    325  1.9.2.2  nathanw 	"**unknown 12**",
    326  1.9.2.2  nathanw 	"**unknown 13**",
    327  1.9.2.2  nathanw 	"**unknown 14**",
    328  1.9.2.2  nathanw 	"**unknown 15**",
    329  1.9.2.2  nathanw };
    330  1.9.2.2  nathanw 
    331  1.9.2.2  nathanw void
    332  1.9.2.4  nathanw identify_arm_cpu(struct device *dv, struct cpu_info *ci)
    333  1.9.2.2  nathanw {
    334  1.9.2.2  nathanw 	u_int cpuid;
    335  1.9.2.4  nathanw 	enum cpu_class cpu_class;
    336  1.9.2.2  nathanw 	int i;
    337  1.9.2.2  nathanw 
    338  1.9.2.4  nathanw 	cpuid = ci->ci_cpuid;
    339  1.9.2.2  nathanw 
    340  1.9.2.2  nathanw 	if (cpuid == 0) {
    341  1.9.2.2  nathanw 		printf("Processor failed probe - no CPU ID\n");
    342  1.9.2.2  nathanw 		return;
    343  1.9.2.2  nathanw 	}
    344  1.9.2.2  nathanw 
    345  1.9.2.2  nathanw 	for (i = 0; cpuids[i].cpuid != 0; i++)
    346  1.9.2.2  nathanw 		if (cpuids[i].cpuid == (cpuid & CPU_ID_CPU_MASK)) {
    347  1.9.2.4  nathanw 			cpu_class = cpuids[i].cpu_class;
    348  1.9.2.4  nathanw 			sprintf(cpu_model, "%s %s (%s core)",
    349  1.9.2.3  nathanw 			    cpuids[i].cpu_name,
    350  1.9.2.3  nathanw 			    cpuids[i].cpu_steppings[cpuid &
    351  1.9.2.3  nathanw 						    CPU_ID_REVISION_MASK],
    352  1.9.2.4  nathanw 			    cpu_classes[cpu_class].class_name);
    353  1.9.2.2  nathanw 			break;
    354  1.9.2.2  nathanw 		}
    355  1.9.2.2  nathanw 
    356  1.9.2.2  nathanw 	if (cpuids[i].cpuid == 0)
    357  1.9.2.4  nathanw 		sprintf(cpu_model, "unknown CPU (ID = 0x%x)", cpuid);
    358  1.9.2.2  nathanw 
    359  1.9.2.4  nathanw 	printf(": %s\n", cpu_model);
    360  1.9.2.4  nathanw 
    361  1.9.2.4  nathanw 	printf("%s:", dv->dv_xname);
    362  1.9.2.4  nathanw 
    363  1.9.2.4  nathanw 	switch (cpu_class) {
    364  1.9.2.2  nathanw 	case CPU_CLASS_ARM6:
    365  1.9.2.2  nathanw 	case CPU_CLASS_ARM7:
    366  1.9.2.2  nathanw 	case CPU_CLASS_ARM7TDMI:
    367  1.9.2.2  nathanw 	case CPU_CLASS_ARM8:
    368  1.9.2.4  nathanw 		if ((ci->ci_ctrl & CPU_CONTROL_IDC_ENABLE) == 0)
    369  1.9.2.4  nathanw 			printf(" IDC disabled");
    370  1.9.2.2  nathanw 		else
    371  1.9.2.4  nathanw 			printf(" IDC enabled");
    372  1.9.2.2  nathanw 		break;
    373  1.9.2.2  nathanw 	case CPU_CLASS_ARM9TDMI:
    374  1.9.2.2  nathanw 	case CPU_CLASS_SA1:
    375  1.9.2.2  nathanw 	case CPU_CLASS_XSCALE:
    376  1.9.2.4  nathanw 		if ((ci->ci_ctrl & CPU_CONTROL_DC_ENABLE) == 0)
    377  1.9.2.4  nathanw 			printf(" DC disabled");
    378  1.9.2.2  nathanw 		else
    379  1.9.2.4  nathanw 			printf(" DC enabled");
    380  1.9.2.4  nathanw 		if ((ci->ci_ctrl & CPU_CONTROL_IC_ENABLE) == 0)
    381  1.9.2.4  nathanw 			printf(" IC disabled");
    382  1.9.2.2  nathanw 		else
    383  1.9.2.4  nathanw 			printf(" IC enabled");
    384  1.9.2.4  nathanw 		break;
    385  1.9.2.4  nathanw 	default:
    386  1.9.2.2  nathanw 		break;
    387  1.9.2.2  nathanw 	}
    388  1.9.2.4  nathanw 	if ((ci->ci_ctrl & CPU_CONTROL_WBUF_ENABLE) == 0)
    389  1.9.2.4  nathanw 		printf(" WB disabled");
    390  1.9.2.2  nathanw 	else
    391  1.9.2.4  nathanw 		printf(" WB enabled");
    392  1.9.2.2  nathanw 
    393  1.9.2.4  nathanw 	if (ci->ci_ctrl & CPU_CONTROL_LABT_ENABLE)
    394  1.9.2.4  nathanw 		printf(" LABT");
    395  1.9.2.2  nathanw 	else
    396  1.9.2.4  nathanw 		printf(" EABT");
    397  1.9.2.2  nathanw 
    398  1.9.2.4  nathanw 	if (ci->ci_ctrl & CPU_CONTROL_BPRD_ENABLE)
    399  1.9.2.4  nathanw 		printf(" branch prediction enabled");
    400  1.9.2.2  nathanw 
    401  1.9.2.4  nathanw 	printf("\n");
    402  1.9.2.2  nathanw 
    403  1.9.2.2  nathanw 	/* Print cache info. */
    404  1.9.2.2  nathanw 	if (arm_picache_line_size == 0 && arm_pdcache_line_size == 0)
    405  1.9.2.2  nathanw 		goto skip_pcache;
    406  1.9.2.2  nathanw 
    407  1.9.2.2  nathanw 	if (arm_pcache_unified) {
    408  1.9.2.2  nathanw 		printf("%s: %dKB/%dB %d-way %s unified cache\n",
    409  1.9.2.2  nathanw 		    dv->dv_xname, arm_pdcache_size / 1024,
    410  1.9.2.2  nathanw 		    arm_pdcache_line_size, arm_pdcache_ways,
    411  1.9.2.2  nathanw 		    wtnames[arm_pcache_type]);
    412  1.9.2.2  nathanw 	} else {
    413  1.9.2.2  nathanw 		printf("%s: %dKB/%dB %d-way Instruction cache\n",
    414  1.9.2.2  nathanw 		    dv->dv_xname, arm_picache_size / 1024,
    415  1.9.2.2  nathanw 		    arm_picache_line_size, arm_picache_ways);
    416  1.9.2.2  nathanw 		printf("%s: %dKB/%dB %d-way %s Data cache\n",
    417  1.9.2.2  nathanw 		    dv->dv_xname, arm_pdcache_size / 1024,
    418  1.9.2.2  nathanw 		    arm_pdcache_line_size, arm_pdcache_ways,
    419  1.9.2.2  nathanw 		    wtnames[arm_pcache_type]);
    420  1.9.2.2  nathanw 	}
    421  1.9.2.2  nathanw 
    422  1.9.2.2  nathanw  skip_pcache:
    423  1.9.2.2  nathanw 
    424  1.9.2.4  nathanw 	switch (cpu_class) {
    425  1.9.2.2  nathanw #ifdef CPU_ARM2
    426  1.9.2.2  nathanw 	case CPU_CLASS_ARM2:
    427  1.9.2.2  nathanw #endif
    428  1.9.2.2  nathanw #ifdef CPU_ARM250
    429  1.9.2.2  nathanw 	case CPU_CLASS_ARM2AS:
    430  1.9.2.2  nathanw #endif
    431  1.9.2.2  nathanw #ifdef CPU_ARM3
    432  1.9.2.2  nathanw 	case CPU_CLASS_ARM3:
    433  1.9.2.2  nathanw #endif
    434  1.9.2.2  nathanw #ifdef CPU_ARM6
    435  1.9.2.2  nathanw 	case CPU_CLASS_ARM6:
    436  1.9.2.2  nathanw #endif
    437  1.9.2.2  nathanw #ifdef CPU_ARM7
    438  1.9.2.2  nathanw 	case CPU_CLASS_ARM7:
    439  1.9.2.2  nathanw #endif
    440  1.9.2.2  nathanw #ifdef CPU_ARM7TDMI
    441  1.9.2.2  nathanw 	case CPU_CLASS_ARM7TDMI:
    442  1.9.2.2  nathanw #endif
    443  1.9.2.2  nathanw #ifdef CPU_ARM8
    444  1.9.2.2  nathanw 	case CPU_CLASS_ARM8:
    445  1.9.2.2  nathanw #endif
    446  1.9.2.2  nathanw #ifdef CPU_ARM9
    447  1.9.2.2  nathanw 	case CPU_CLASS_ARM9TDMI:
    448  1.9.2.2  nathanw #endif
    449  1.9.2.2  nathanw #ifdef CPU_SA110
    450  1.9.2.2  nathanw 	case CPU_CLASS_SA1:
    451  1.9.2.2  nathanw #endif
    452  1.9.2.4  nathanw #if defined(CPU_XSCALE_80200) || defined(CPU_XSCALE_80321)
    453  1.9.2.2  nathanw 	case CPU_CLASS_XSCALE:
    454  1.9.2.2  nathanw #endif
    455  1.9.2.2  nathanw 		break;
    456  1.9.2.2  nathanw 	default:
    457  1.9.2.4  nathanw 		if (cpu_classes[cpu_class].class_option != NULL)
    458  1.9.2.2  nathanw 			printf("%s: %s does not fully support this CPU."
    459  1.9.2.2  nathanw 			       "\n", dv->dv_xname, ostype);
    460  1.9.2.2  nathanw 		else {
    461  1.9.2.2  nathanw 			printf("%s: This kernel does not fully support "
    462  1.9.2.2  nathanw 			       "this CPU.\n", dv->dv_xname);
    463  1.9.2.2  nathanw 			printf("%s: Recompile with \"options %s\" to "
    464  1.9.2.2  nathanw 			       "correct this.\n", dv->dv_xname,
    465  1.9.2.4  nathanw 			       cpu_classes[cpu_class].class_option);
    466  1.9.2.2  nathanw 		}
    467  1.9.2.2  nathanw 		break;
    468  1.9.2.2  nathanw 	}
    469  1.9.2.2  nathanw 
    470  1.9.2.2  nathanw }
    471  1.9.2.2  nathanw 
    472  1.9.2.2  nathanw /* End of cpu.c */
    473