1 /* $OpenBSD: mp_setperf.c,v 1.6 2014/09/12 09:52:45 kettenis Exp $ */
2 /*
3 * Copyright (c) 2007 Gordon Willem Klok <gwk@openbsd.org>
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18 #include <sys/param.h>
19 #include <sys/systm.h>
20 #include <sys/sysctl.h>
21 #include <sys/mutex.h>
22
23 #include <machine/cpu.h>
24 #include <machine/intr.h>
25
26 struct mutex setperf_mp_mutex = MUTEX_INITIALIZER(IPL_HIGH);
27
28 /* underlying setperf mechanism e.g. k8_powernow_setperf() */
29 void (*ul_setperf)(int);
30
31 /* protected by setperf_mp_mutex */
32 volatile int mp_perflevel;
33
34 void mp_setperf(int);
35
36 void
mp_setperf(int level)37 mp_setperf(int level)
38 {
39 mtx_enter(&setperf_mp_mutex);
40 mp_perflevel = level;
41
42 ul_setperf(mp_perflevel);
43 i386_broadcast_ipi(I386_IPI_SETPERF);
44 mtx_leave(&setperf_mp_mutex);
45 }
46
47 void
i386_setperf_ipi(struct cpu_info * ci)48 i386_setperf_ipi(struct cpu_info *ci)
49 {
50 ul_setperf(mp_perflevel);
51 }
52
53 void
mp_setperf_init(void)54 mp_setperf_init(void)
55 {
56 if (!cpu_setperf)
57 return;
58
59 ul_setperf = cpu_setperf;
60 cpu_setperf = mp_setperf;
61 mtx_init(&setperf_mp_mutex, IPL_HIGH);
62 }
63