1179260Sjb/*- 2179260Sjb * Copyright 2006-2008 John Birrell <jb@FreeBSD.org> 3179260Sjb * 4179260Sjb * Redistribution and use in source and binary forms, with or without 5179260Sjb * modification, are permitted provided that the following conditions 6179260Sjb * are met: 7179260Sjb * 1. Redistributions of source code must retain the above copyright 8179260Sjb * notice, this list of conditions and the following disclaimer. 9179260Sjb * 2. Redistributions in binary form must reproduce the above copyright 10179260Sjb * notice, this list of conditions and the following disclaimer in the 11179260Sjb * documentation and/or other materials provided with the distribution. 12179260Sjb * 13179260Sjb * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND 14179260Sjb * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15179260Sjb * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 16179260Sjb * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE 17179260Sjb * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18179260Sjb * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 19179260Sjb * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 20179260Sjb * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21179260Sjb * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22179260Sjb * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 23179260Sjb * SUCH DAMAGE. 24179260Sjb * 25179260Sjb * $FreeBSD$ 26179260Sjb * 27179260Sjb */ 28179260Sjb 29179260Sjbstatic void enable(cyb_arg_t); 30179260Sjbstatic void disable(cyb_arg_t); 31179260Sjbstatic void reprogram(cyb_arg_t, hrtime_t); 32179260Sjbstatic void xcall(cyb_arg_t, cpu_t *, cyc_func_t, void *); 33221990Savgstatic void cyclic_clock(struct trapframe *frame); 34179260Sjb 35179260Sjbstatic cyc_backend_t be = { 36179260Sjb NULL, /* cyb_configure */ 37179260Sjb NULL, /* cyb_unconfigure */ 38179260Sjb enable, 39179260Sjb disable, 40179260Sjb reprogram, 41179260Sjb xcall, 42179260Sjb NULL /* cyb_arg_t cyb_arg */ 43179260Sjb}; 44179260Sjb 45179260Sjbstatic void 46179260Sjbcyclic_ap_start(void *dummy) 47179260Sjb{ 48179260Sjb /* Initialise the rest of the CPUs. */ 49221990Savg cyclic_clock_func = cyclic_clock; 50179260Sjb cyclic_mp_init(); 51179260Sjb} 52179260Sjb 53179260SjbSYSINIT(cyclic_ap_start, SI_SUB_SMP, SI_ORDER_ANY, cyclic_ap_start, NULL); 54179260Sjb 55179260Sjb/* 56179260Sjb * Machine dependent cyclic subsystem initialisation. 57179260Sjb */ 58179260Sjbstatic void 59179260Sjbcyclic_machdep_init(void) 60179260Sjb{ 61179260Sjb /* Register the cyclic backend. */ 62179260Sjb cyclic_init(&be); 63179260Sjb} 64179260Sjb 65179260Sjbstatic void 66179260Sjbcyclic_machdep_uninit(void) 67179260Sjb{ 68179260Sjb /* De-register the cyclic backend. */ 69179260Sjb cyclic_uninit(); 70179260Sjb} 71179260Sjb 72179260Sjb/* 73179260Sjb * This function is the one registered by the machine dependent 74179260Sjb * initialiser as the callback for high speed timer events. 75179260Sjb */ 76179260Sjbstatic void 77179260Sjbcyclic_clock(struct trapframe *frame) 78179260Sjb{ 79179260Sjb cpu_t *c = &solaris_cpu[curcpu]; 80179260Sjb 81221990Savg if (c->cpu_cyclic != NULL) { 82179260Sjb if (TRAPF_USERMODE(frame)) { 83179260Sjb c->cpu_profile_pc = 0; 84179260Sjb c->cpu_profile_upc = TRAPF_PC(frame); 85179260Sjb } else { 86179260Sjb c->cpu_profile_pc = TRAPF_PC(frame); 87179260Sjb c->cpu_profile_upc = 0; 88179260Sjb } 89179260Sjb 90179260Sjb c->cpu_intr_actv = 1; 91179260Sjb 92179260Sjb /* Fire any timers that are due. */ 93179260Sjb cyclic_fire(c); 94179260Sjb 95179260Sjb c->cpu_intr_actv = 0; 96179260Sjb } 97179260Sjb} 98179260Sjb 99221990Savgstatic void 100221990Savgenable(cyb_arg_t arg __unused) 101179260Sjb{ 102221990Savg 103179260Sjb} 104179260Sjb 105221990Savgstatic void 106221990Savgdisable(cyb_arg_t arg __unused) 107179260Sjb{ 108221990Savg 109179260Sjb} 110179260Sjb 111221990Savgstatic void 112221990Savgreprogram(cyb_arg_t arg __unused, hrtime_t exp) 113179260Sjb{ 114221990Savg struct bintime bt; 115221990Savg struct timespec ts; 116221990Savg 117221990Savg ts.tv_sec = exp / 1000000000; 118221990Savg ts.tv_nsec = exp % 1000000000; 119221990Savg timespec2bintime(&ts, &bt); 120221990Savg clocksource_cyc_set(&bt); 121179260Sjb} 122179260Sjb 123221990Savgstatic void xcall(cyb_arg_t arg __unused, cpu_t *c, cyc_func_t func, 124221990Savg void *param) 125179260Sjb{ 126222813Sattilio cpuset_t cpus; 127216252Savg 128222813Sattilio CPU_SETOF(c->cpuid, &cpus); 129222813Sattilio smp_rendezvous_cpus(cpus, 130216505Savg smp_no_rendevous_barrier, func, smp_no_rendevous_barrier, param); 131179260Sjb} 132