1 /* $NetBSD: cpu.c,v 1.4 2002/03/06 08:02:12 simonb Exp $ */ 2 3 /* 4 * Copyright 2000, 2001 5 * Broadcom Corporation. All rights reserved. 6 * 7 * This software is furnished under license and may be used and copied only 8 * in accordance with the following terms and conditions. Subject to these 9 * conditions, you may download, copy, install, use, modify and distribute 10 * modified or unmodified copies of this software in source and/or binary 11 * form. No title or ownership is transferred hereby. 12 * 13 * 1) Any source code used, modified or distributed must reproduce and 14 * retain this copyright notice and list of conditions as they appear in 15 * the source file. 16 * 17 * 2) No right is granted to use any trade name, trademark, or logo of 18 * Broadcom Corporation. Neither the "Broadcom Corporation" name nor any 19 * trademark or logo of Broadcom Corporation may be used to endorse or 20 * promote products derived from this software without the prior written 21 * permission of Broadcom Corporation. 22 * 23 * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR IMPLIED 24 * WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED WARRANTIES OF 25 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR 26 * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL BROADCOM BE LIABLE 27 * FOR ANY DAMAGES WHATSOEVER, AND IN PARTICULAR, BROADCOM SHALL NOT BE 28 * LIABLE FOR DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 29 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 30 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 31 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 32 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 33 * OR OTHERWISE), EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34 */ 35 36 #include <sys/param.h> 37 #include <sys/device.h> 38 #include <sys/kernel.h> 39 #include <sys/systm.h> 40 41 #include <mips/locore.h> 42 #include <mips/cache.h> 43 44 #include <machine/cpu.h> 45 46 #include <mips/sibyte/include/zbbusvar.h> 47 #include <mips/sibyte/include/sb1250_regs.h> 48 #include <mips/sibyte/include/sb1250_scd.h> 49 #include <mips/sibyte/dev/sbscdvar.h> 50 51 #define READ_REG(rp) (mips3_ld((uint64_t *)(rp))) 52 53 static int cpu_match(struct device *, struct cfdata *, void *); 54 static void cpu_attach(struct device *, struct device *, void *); 55 56 struct cfattach cpu_ca = { 57 sizeof(struct device), cpu_match, cpu_attach 58 }; 59 60 static int 61 cpu_match(struct device *parent, struct cfdata *match, void *aux) 62 { 63 struct zbbus_attach_args *zap = aux; 64 65 if (zap->za_locs.za_type != ZBBUS_ENTTYPE_CPU) 66 return (0); 67 68 return 1; 69 } 70 71 static void 72 cpu_attach(struct device *parent, struct device *self, void *aux) 73 { 74 int plldiv; 75 uint32_t config; 76 77 /* XXX this code must run on the target cpu */ 78 config = mips3_cp0_config_read(); 79 config &= ~MIPS3_CONFIG_K0_MASK; 80 config |= 0x05; /* XXX. cacheable coherent */ 81 mips3_cp0_config_write(config); 82 83 /* 84 * Flush all of the caches, so that any lines marked non-coherent will 85 * be flushed. Don't need to worry about L2; it's always 86 * coherent (XXX???). 87 */ 88 mips_icache_sync_all(); 89 mips_dcache_wbinv_all(); 90 91 /* Determine CPU frequency */ 92 93 /* XXX: We should determine the CPU frequency from a time source 94 * not coupled with the CPU crystal, like the RTC. Unfortunately 95 * we don't attach that yet... 96 */ 97 plldiv = G_SYS_PLL_DIV(READ_REG(MIPS_PHYS_TO_KSEG1(A_SCD_SYSTEM_CFG))); 98 if (plldiv == 0) { 99 printf("PLL_DIV of zero found, assuming 6 (300MHz)\n"); 100 plldiv = 6; 101 102 printf("%s", self->dv_xname); 103 } 104 105 curcpu()->ci_cpu_freq = 50000000 * plldiv; 106 /* Compute the delay divisor. */ 107 curcpu()->ci_divisor_delay = curcpu()->ci_cpu_freq / 1000000; 108 /* Compute clock cycles per hz */ 109 curcpu()->ci_cycles_per_hz = curcpu()->ci_cpu_freq / hz; 110 111 /* 112 * To implement a more accurate microtime using the CP0 COUNT 113 * register we need to divide that register by the number of 114 * cycles per MHz. But... 115 * 116 * DIV and DIVU are expensive on MIPS (eg 75 clocks on the 117 * R4000). MULT and MULTU are only 12 clocks on the same CPU. 118 * On the SB1 these appear to be 40-72 clocks for DIV/DIVU and 3 119 * clocks for MUL/MULTU. 120 * 121 * The strategy we use to to calculate the reciprical of cycles 122 * per MHz, scaled by 1<<32. Then we can simply issue a MULTU 123 * and pluck of the HI register and have the results of the 124 * division. 125 */ 126 curcpu()->ci_divisor_recip = 127 0x100000000ULL / curcpu()->ci_divisor_delay; 128 129 printf(": %lu.%02luMHz (hz cycles = %lu, delay divisor = %lu)\n", 130 curcpu()->ci_cpu_freq / 1000000, 131 (curcpu()->ci_cpu_freq % 1000000) / 10000, 132 curcpu()->ci_cycles_per_hz, curcpu()->ci_divisor_delay); 133 134 printf("%s: ", self->dv_xname); 135 cpu_identify(); 136 137 /* make sure processor is available for use */ 138 /* XXXCGD */ 139 } 140