clock.c revision 209639
1127915Skientzle/*- 2265420Simp * Copyright (C) 1995, 1996 Wolfgang Solfrank. 3127915Skientzle * Copyright (C) 1995, 1996 TooLs GmbH. 4319186Sngie * All rights reserved. 5228797Smm * 6127915Skientzle * Redistribution and use in source and binary forms, with or without 7368984Smm * modification, are permitted provided that the following conditions 8368984Smm * are met: 9228797Smm * 1. Redistributions of source code must retain the above copyright 10291620Sbdrewery * notice, this list of conditions and the following disclaimer. 11203559Skientzle * 2. Redistributions in binary form must reproduce the above copyright 12203559Skientzle * notice, this list of conditions and the following disclaimer in the 13248616Smm * documentation and/or other materials provided with the distribution. 14203559Skientzle * 3. All advertising materials mentioning features or use of this software 15203559Skientzle * must display the following acknowledgement: 16203559Skientzle * This product includes software developed by TooLs GmbH. 17203559Skientzle * 4. The name of TooLs GmbH may not be used to endorse or promote products 18224153Smm * derived from this software without specific prior written permission. 19291620Sbdrewery * 20224153Smm * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR 21299529Smm * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 22299529Smm * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 23224153Smm * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24275042Sbapt * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 25224566Smm * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 26232153Smm * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 27232153Smm * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 28232153Smm * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 29232153Smm * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30175051Skientzle * 31319186Sngie * $NetBSD: clock.c,v 1.9 2000/01/19 02:52:19 msaitoh Exp $ 32291620Sbdrewery */ 33291620Sbdrewery/* 34137616Sru * Copyright (C) 2001 Benno Rice. 35128446Skientzle * All rights reserved. 36128446Skientzle * 37289195Sngie * Redistribution and use in source and binary forms, with or without 38289195Sngie * modification, are permitted provided that the following conditions 39289195Sngie * are met: 40175051Skientzle * 1. Redistributions of source code must retain the above copyright 41127915Skientzle * notice, this list of conditions and the following disclaimer. 42 * 2. Redistributions in binary form must reproduce the above copyright 43 * notice, this list of conditions and the following disclaimer in the 44 * documentation and/or other materials provided with the distribution. 45 * 46 * THIS SOFTWARE IS PROVIDED BY Benno Rice ``AS IS'' AND ANY EXPRESS OR 47 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 48 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 49 * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 50 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 51 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 52 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 53 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 54 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 55 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 56 */ 57 58#include <sys/cdefs.h> 59__FBSDID("$FreeBSD: head/sys/powerpc/aim/clock.c 209639 2010-07-02 02:17:39Z marcel $"); 60 61#include <sys/param.h> 62#include <sys/systm.h> 63#include <sys/kernel.h> 64#include <sys/bus.h> 65#include <sys/interrupt.h> 66#include <sys/pcpu.h> 67#include <sys/sysctl.h> 68#include <sys/timetc.h> 69 70#include <dev/ofw/openfirm.h> 71 72#include <machine/clock.h> 73#include <machine/cpu.h> 74#include <machine/md_var.h> 75#include <machine/smp.h> 76 77/* 78 * Initially we assume a processor with a bus frequency of 12.5 MHz. 79 */ 80u_long ns_per_tick = 80; 81static u_long ticks_per_sec = 12500000; 82static long ticks_per_intr; 83 84static timecounter_get_t decr_get_timecount; 85 86static struct timecounter decr_timecounter = { 87 decr_get_timecount, /* get_timecount */ 88 0, /* no poll_pps */ 89 ~0u, /* counter_mask */ 90 0, /* frequency */ 91 "decrementer" /* name */ 92}; 93 94void 95decr_intr(struct trapframe *frame) 96{ 97 int32_t tick, nticks; 98 99 /* 100 * Check whether we are initialized. 101 */ 102 if (!ticks_per_intr) 103 return; 104 105 /* 106 * Based on the actual time delay since the last decrementer reload, 107 * we arrange for earlier interrupt next time. 108 */ 109 __asm ("mfdec %0" : "=r"(tick)); 110 for (nticks = 0; tick < 0; nticks++) 111 tick += ticks_per_intr; 112 mtdec(tick); 113 114 while (nticks-- > 0) { 115 if (PCPU_GET(cpuid) == 0) 116 hardclock(TRAPF_USERMODE(frame), TRAPF_PC(frame)); 117 else 118 hardclock_cpu(TRAPF_USERMODE(frame)); 119 120 statclock(TRAPF_USERMODE(frame)); 121 if (profprocs != 0) 122 profclock(TRAPF_USERMODE(frame), TRAPF_PC(frame)); 123 } 124} 125 126void 127decr_init(void) 128{ 129 struct cpuref cpu; 130 register_t msr; 131 132 /* 133 * Check the BSP's timebase frequency. Sometimes we can't find the BSP, so fall 134 * back to the first CPU in this case. 135 */ 136 137 if (platform_smp_get_bsp(&cpu) != 0) 138 platform_smp_first_cpu(&cpu); 139 140 ticks_per_sec = platform_timebase_freq(&cpu); 141 142 msr = mfmsr(); 143 mtmsr(msr & ~PSL_EE); 144 145 ns_per_tick = 1000000000 / ticks_per_sec; 146 ticks_per_intr = ticks_per_sec / hz; 147 mtdec(ticks_per_intr); 148 149 set_cputicker(mftb, ticks_per_sec, 0); 150 151 mtmsr(msr); 152} 153 154#ifdef SMP 155void 156decr_ap_init(void) 157{ 158 159} 160#endif 161 162void 163decr_tc_init(void) 164{ 165 decr_timecounter.tc_frequency = ticks_per_sec; 166 tc_init(&decr_timecounter); 167} 168 169static unsigned 170decr_get_timecount(struct timecounter *tc) 171{ 172 register_t tb; 173 174 __asm __volatile("mftb %0" : "=r"(tb)); 175 return (tb); 176} 177 178/* 179 * Wait for about n microseconds (at least!). 180 */ 181void 182DELAY(int n) 183{ 184 u_quad_t tb, ttb; 185 186 tb = mftb(); 187 ttb = tb + (n * 1000 + ns_per_tick - 1) / ns_per_tick; 188 while (tb < ttb) 189 tb = mftb(); 190} 191 192/* 193 * Nothing to do. 194 */ 195void 196cpu_startprofclock(void) 197{ 198 199 /* Do nothing */ 200} 201 202void 203cpu_stopprofclock(void) 204{ 205} 206