1 /* $OpenBSD: cpu.c,v 1.8 2000/08/15 20:38:24 mickey Exp $ */ 2 3 /* 4 * Copyright (c) 1998,1999 Michael Shalayeff 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 Michael Shalayeff. 18 * 4. The name of the author may not be used to endorse or promote products 19 * derived from this software without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF MIND, 27 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33 #include <sys/param.h> 34 #include <sys/systm.h> 35 #include <sys/device.h> 36 #include <sys/reboot.h> 37 38 #include <machine/cpufunc.h> 39 #include <machine/pdc.h> 40 #include <machine/iomod.h> 41 #include <machine/autoconf.h> 42 43 #include <hppa/dev/cpudevs.h> 44 45 struct cpu_softc { 46 struct device sc_dev; 47 48 hppa_hpa_t sc_hpa; 49 void *sc_ih; 50 }; 51 52 int cpumatch __P((struct device *, void *, void *)); 53 void cpuattach __P((struct device *, struct device *, void *)); 54 55 struct cfattach cpu_ca = { 56 sizeof(struct cpu_softc), cpumatch, cpuattach 57 }; 58 59 struct cfdriver cpu_cd = { 60 NULL, "cpu", DV_DULL 61 }; 62 63 int 64 cpumatch(parent, cfdata, aux) 65 struct device *parent; 66 void *cfdata; 67 void *aux; 68 { 69 struct confargs *ca = aux; 70 struct cfdata *cf = cfdata; 71 72 /* there will be only one for now XXX */ 73 /* probe any 1.0, 1.1 or 2.0 */ 74 if (cf->cf_unit > 0 || 75 ca->ca_type.iodc_type != HPPA_TYPE_NPROC || 76 ca->ca_type.iodc_sv_model != HPPA_NPROC_HPPA) 77 return 0; 78 79 return 1; 80 } 81 82 void 83 cpuattach(parent, self, aux) 84 struct device *parent; 85 struct device *self; 86 void *aux; 87 { 88 /* machdep.c */ 89 extern struct pdc_cache pdc_cache; 90 extern struct pdc_btlb pdc_btlb; 91 extern u_int cpu_ticksnum, cpu_ticksdenom; 92 93 struct pdc_model pdc_model PDC_ALIGNMENT; 94 struct pdc_cpuid pdc_cpuid PDC_ALIGNMENT; 95 u_int pdc_cversion[32] PDC_ALIGNMENT; 96 register struct cpu_softc *sc = (struct cpu_softc *)self; 97 register struct confargs *ca = aux; 98 const char *p = NULL; 99 u_int mhz = 100 * cpu_ticksnum / cpu_ticksdenom; 100 int err; 101 102 bzero (&pdc_cpuid, sizeof(pdc_cpuid)); 103 if (pdc_call((iodcio_t)pdc, 0, PDC_MODEL, PDC_MODEL_CPUID, 104 &pdc_cpuid, sc->sc_dev.dv_unit, 0, 0, 0) >= 0) { 105 106 /* patch for old 8200 */ 107 if (pdc_cpuid.version == HPPA_CPU_PCXUP && 108 pdc_cpuid.revision > 0x0d) 109 pdc_cpuid.version = HPPA_CPU_PCXUP1; 110 111 p = hppa_mod_info(HPPA_TYPE_CPU, pdc_cpuid.version); 112 } 113 /* otherwise try to guess on component version numbers */ 114 else if (pdc_call((iodcio_t)pdc, 0, PDC_MODEL, PDC_MODEL_COMP, 115 &pdc_cversion, sc->sc_dev.dv_unit) >= 0) { 116 /* XXX p = hppa_mod_info(HPPA_TYPE_CPU,pdc_cversion[0]); */ 117 } 118 119 printf (": %s rev %d, ", p? p : cpu_typename, (*cpu_desidhash)()); 120 121 if ((err = pdc_call((iodcio_t)pdc, 0, PDC_MODEL, PDC_MODEL_INFO, 122 &pdc_model)) < 0) { 123 #ifdef DEBUG 124 printf("WARNING: PDC_MODEL failed (%d)\n", err); 125 #endif 126 } else { 127 static const char lvls[4][4] = { "0", "1", "1.5", "2" }; 128 129 printf("lev %s, cat %c, ", 130 lvls[pdc_model.pa_lvl], "AB"[pdc_model.mc]); 131 } 132 133 printf ("%d", mhz / 100); 134 if (mhz % 100 > 9) 135 printf(".%02d", mhz % 100); 136 137 printf(" MHz clk\n%s: %s", self->dv_xname, 138 pdc_model.sh? "shadows, ": ""); 139 140 if (pdc_cache.dc_conf.cc_sh) 141 printf("%uK cache", pdc_cache.dc_size / 1024); 142 else 143 printf("%uK/%uK D/I caches", 144 pdc_cache.dc_size / 1024, 145 pdc_cache.ic_size / 1024); 146 if (pdc_cache.dt_conf.tc_sh) 147 printf(", %u shared TLB", pdc_cache.dt_size); 148 else 149 printf(", %u/%u D/I TLBs", 150 pdc_cache.dt_size, pdc_cache.it_size); 151 152 if (pdc_btlb.finfo.num_c) 153 printf(", %u shared BTLB", pdc_btlb.finfo.num_c); 154 else { 155 printf(", %u/%u D/I BTLBs", 156 pdc_btlb.finfo.num_i, 157 pdc_btlb.finfo.num_d); 158 } 159 160 printf("\n"); 161 162 /* sanity against luser amongst config editors */ 163 if (ca->ca_irq == 31) { 164 sc->sc_ih = cpu_intr_establish(IPL_CLOCK, ca->ca_irq, 165 clock_intr, NULL /*trapframe*/, 166 &sc->sc_dev); 167 } else { 168 printf ("%s: bad irq number %d\n", sc->sc_dev.dv_xname, 169 ca->ca_irq); 170 } 171 } 172