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