1228f09b3SNathan Whitehorn /*-
2*4d846d26SWarner Losh * SPDX-License-Identifier: BSD-4-Clause AND BSD-2-Clause
371e3c308SPedro F. Giffuni *
4228f09b3SNathan Whitehorn * Copyright (C) 1995, 1996 Wolfgang Solfrank.
5228f09b3SNathan Whitehorn * Copyright (C) 1995, 1996 TooLs GmbH.
6228f09b3SNathan Whitehorn * All rights reserved.
7228f09b3SNathan Whitehorn *
8228f09b3SNathan Whitehorn * Redistribution and use in source and binary forms, with or without
9228f09b3SNathan Whitehorn * modification, are permitted provided that the following conditions
10228f09b3SNathan Whitehorn * are met:
11228f09b3SNathan Whitehorn * 1. Redistributions of source code must retain the above copyright
12228f09b3SNathan Whitehorn * notice, this list of conditions and the following disclaimer.
13228f09b3SNathan Whitehorn * 2. Redistributions in binary form must reproduce the above copyright
14228f09b3SNathan Whitehorn * notice, this list of conditions and the following disclaimer in the
15228f09b3SNathan Whitehorn * documentation and/or other materials provided with the distribution.
16228f09b3SNathan Whitehorn * 3. All advertising materials mentioning features or use of this software
17228f09b3SNathan Whitehorn * must display the following acknowledgement:
18228f09b3SNathan Whitehorn * This product includes software developed by TooLs GmbH.
19228f09b3SNathan Whitehorn * 4. The name of TooLs GmbH may not be used to endorse or promote products
20228f09b3SNathan Whitehorn * derived from this software without specific prior written permission.
21228f09b3SNathan Whitehorn *
22228f09b3SNathan Whitehorn * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
23228f09b3SNathan Whitehorn * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24228f09b3SNathan Whitehorn * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25228f09b3SNathan Whitehorn * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26228f09b3SNathan Whitehorn * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
27228f09b3SNathan Whitehorn * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
28228f09b3SNathan Whitehorn * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
29228f09b3SNathan Whitehorn * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
30228f09b3SNathan Whitehorn * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
31228f09b3SNathan Whitehorn * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32228f09b3SNathan Whitehorn *
33228f09b3SNathan Whitehorn * $NetBSD: clock.c,v 1.9 2000/01/19 02:52:19 msaitoh Exp $
34228f09b3SNathan Whitehorn */
35228f09b3SNathan Whitehorn /*
36228f09b3SNathan Whitehorn * Copyright (C) 2001 Benno Rice.
37228f09b3SNathan Whitehorn * All rights reserved.
38228f09b3SNathan Whitehorn *
39228f09b3SNathan Whitehorn * Redistribution and use in source and binary forms, with or without
40228f09b3SNathan Whitehorn * modification, are permitted provided that the following conditions
41228f09b3SNathan Whitehorn * are met:
42228f09b3SNathan Whitehorn * 1. Redistributions of source code must retain the above copyright
43228f09b3SNathan Whitehorn * notice, this list of conditions and the following disclaimer.
44228f09b3SNathan Whitehorn * 2. Redistributions in binary form must reproduce the above copyright
45228f09b3SNathan Whitehorn * notice, this list of conditions and the following disclaimer in the
46228f09b3SNathan Whitehorn * documentation and/or other materials provided with the distribution.
47228f09b3SNathan Whitehorn *
48228f09b3SNathan Whitehorn * THIS SOFTWARE IS PROVIDED BY Benno Rice ``AS IS'' AND ANY EXPRESS OR
49228f09b3SNathan Whitehorn * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
50228f09b3SNathan Whitehorn * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
51228f09b3SNathan Whitehorn * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
52228f09b3SNathan Whitehorn * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
53228f09b3SNathan Whitehorn * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
54228f09b3SNathan Whitehorn * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
55228f09b3SNathan Whitehorn * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
56228f09b3SNathan Whitehorn * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
57228f09b3SNathan Whitehorn * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
58228f09b3SNathan Whitehorn */
59228f09b3SNathan Whitehorn
60228f09b3SNathan Whitehorn #include <sys/param.h>
61228f09b3SNathan Whitehorn #include <sys/systm.h>
62228f09b3SNathan Whitehorn #include <sys/kernel.h>
63228f09b3SNathan Whitehorn #include <sys/bus.h>
64228f09b3SNathan Whitehorn #include <sys/interrupt.h>
65228f09b3SNathan Whitehorn #include <sys/pcpu.h>
66228f09b3SNathan Whitehorn #include <sys/sysctl.h>
67228f09b3SNathan Whitehorn #include <sys/timeet.h>
68228f09b3SNathan Whitehorn #include <sys/timetc.h>
69328b5f25SBrandon Bergren #include <sys/vdso.h>
70228f09b3SNathan Whitehorn
71228f09b3SNathan Whitehorn #include <dev/ofw/openfirm.h>
72228f09b3SNathan Whitehorn
73228f09b3SNathan Whitehorn #include <machine/clock.h>
74228f09b3SNathan Whitehorn #include <machine/cpu.h>
75228f09b3SNathan Whitehorn #include <machine/intr_machdep.h>
76228f09b3SNathan Whitehorn #include <machine/md_var.h>
77228f09b3SNathan Whitehorn #include <machine/smp.h>
78228f09b3SNathan Whitehorn
79228f09b3SNathan Whitehorn /*
80228f09b3SNathan Whitehorn * Initially we assume a processor with a bus frequency of 12.5 MHz.
81228f09b3SNathan Whitehorn */
82228f09b3SNathan Whitehorn static int initialized = 0;
83f32ebdc8SWojciech Macek static uint64_t ps_per_tick = 80000;
84228f09b3SNathan Whitehorn static u_long ticks_per_sec = 12500000;
85228f09b3SNathan Whitehorn static u_long *decr_counts[MAXCPU];
86228f09b3SNathan Whitehorn
87228f09b3SNathan Whitehorn static int decr_et_start(struct eventtimer *et,
88228f09b3SNathan Whitehorn sbintime_t first, sbintime_t period);
89228f09b3SNathan Whitehorn static int decr_et_stop(struct eventtimer *et);
90228f09b3SNathan Whitehorn static timecounter_get_t decr_get_timecount;
91328b5f25SBrandon Bergren static uint32_t decr_vdso_timehands(struct vdso_timehands *vdso_th,
92328b5f25SBrandon Bergren struct timecounter *tc);
93328b5f25SBrandon Bergren #ifdef COMPAT_FREEBSD32
94328b5f25SBrandon Bergren static uint32_t decr_vdso_timehands32(struct vdso_timehands32 *vdso_th32,
95328b5f25SBrandon Bergren struct timecounter *tc);
96328b5f25SBrandon Bergren #endif
97228f09b3SNathan Whitehorn
98228f09b3SNathan Whitehorn struct decr_state {
99228f09b3SNathan Whitehorn int mode; /* 0 - off, 1 - periodic, 2 - one-shot. */
100228f09b3SNathan Whitehorn int32_t div; /* Periodic divisor. */
101228f09b3SNathan Whitehorn };
1022bf95012SAndrew Turner DPCPU_DEFINE_STATIC(struct decr_state, decr_state);
103228f09b3SNathan Whitehorn
104228f09b3SNathan Whitehorn static struct eventtimer decr_et;
105228f09b3SNathan Whitehorn static struct timecounter decr_tc = {
106328b5f25SBrandon Bergren .tc_get_timecount = decr_get_timecount,
107328b5f25SBrandon Bergren .tc_counter_mask = ~0u,
108328b5f25SBrandon Bergren .tc_name = "timebase",
109328b5f25SBrandon Bergren .tc_quality = 1000,
110328b5f25SBrandon Bergren .tc_fill_vdso_timehands = decr_vdso_timehands,
111328b5f25SBrandon Bergren #ifdef COMPAT_FREEBSD32
112328b5f25SBrandon Bergren .tc_fill_vdso_timehands32 = decr_vdso_timehands32,
113328b5f25SBrandon Bergren #endif
114228f09b3SNathan Whitehorn };
115228f09b3SNathan Whitehorn
116228f09b3SNathan Whitehorn /*
117228f09b3SNathan Whitehorn * Decrementer interrupt handler.
118228f09b3SNathan Whitehorn */
119228f09b3SNathan Whitehorn void
decr_intr(struct trapframe * frame)120228f09b3SNathan Whitehorn decr_intr(struct trapframe *frame)
121228f09b3SNathan Whitehorn {
122228f09b3SNathan Whitehorn struct decr_state *s = DPCPU_PTR(decr_state);
123228f09b3SNathan Whitehorn int nticks = 0;
124228f09b3SNathan Whitehorn int32_t val;
125228f09b3SNathan Whitehorn
126228f09b3SNathan Whitehorn if (!initialized)
127228f09b3SNathan Whitehorn return;
128228f09b3SNathan Whitehorn
129228f09b3SNathan Whitehorn (*decr_counts[curcpu])++;
130228f09b3SNathan Whitehorn
131228f09b3SNathan Whitehorn #ifdef BOOKE
132228f09b3SNathan Whitehorn /*
133228f09b3SNathan Whitehorn * Interrupt handler must reset DIS to avoid getting another
134228f09b3SNathan Whitehorn * interrupt once EE is enabled.
135228f09b3SNathan Whitehorn */
136228f09b3SNathan Whitehorn mtspr(SPR_TSR, TSR_DIS);
137228f09b3SNathan Whitehorn #endif
138228f09b3SNathan Whitehorn
139228f09b3SNathan Whitehorn if (s->mode == 1) {
140228f09b3SNathan Whitehorn /*
141228f09b3SNathan Whitehorn * Based on the actual time delay since the last decrementer
142228f09b3SNathan Whitehorn * reload, we arrange for earlier interrupt next time.
143228f09b3SNathan Whitehorn */
144228f09b3SNathan Whitehorn __asm ("mfdec %0" : "=r"(val));
145228f09b3SNathan Whitehorn while (val < 0) {
146228f09b3SNathan Whitehorn val += s->div;
147228f09b3SNathan Whitehorn nticks++;
148228f09b3SNathan Whitehorn }
149228f09b3SNathan Whitehorn mtdec(val);
150228f09b3SNathan Whitehorn } else if (s->mode == 2) {
151228f09b3SNathan Whitehorn nticks = 1;
152228f09b3SNathan Whitehorn decr_et_stop(NULL);
1538a92c52aSNathan Whitehorn } else if (s->mode == 0) {
1548a92c52aSNathan Whitehorn /* Potemkin timer ran out without an event. Just reset it. */
1558a92c52aSNathan Whitehorn decr_et_stop(NULL);
156228f09b3SNathan Whitehorn }
157228f09b3SNathan Whitehorn
158228f09b3SNathan Whitehorn while (nticks-- > 0) {
159228f09b3SNathan Whitehorn if (decr_et.et_active)
160228f09b3SNathan Whitehorn decr_et.et_event_cb(&decr_et, decr_et.et_arg);
161228f09b3SNathan Whitehorn }
162228f09b3SNathan Whitehorn }
163228f09b3SNathan Whitehorn
164228f09b3SNathan Whitehorn void
cpu_initclocks(void)165228f09b3SNathan Whitehorn cpu_initclocks(void)
166228f09b3SNathan Whitehorn {
167228f09b3SNathan Whitehorn
168228f09b3SNathan Whitehorn decr_tc_init();
169228f09b3SNathan Whitehorn cpu_initclocks_bsp();
170228f09b3SNathan Whitehorn }
171228f09b3SNathan Whitehorn
172228f09b3SNathan Whitehorn /*
173228f09b3SNathan Whitehorn * BSP early initialization.
174228f09b3SNathan Whitehorn */
175228f09b3SNathan Whitehorn void
decr_init(void)176228f09b3SNathan Whitehorn decr_init(void)
177228f09b3SNathan Whitehorn {
178228f09b3SNathan Whitehorn struct cpuref cpu;
179228f09b3SNathan Whitehorn char buf[32];
180228f09b3SNathan Whitehorn
181228f09b3SNathan Whitehorn /*
18272c775daSNathan Whitehorn * Check the BSP's timebase frequency. Sometimes we can't find the BSP,
18372c775daSNathan Whitehorn * so fall back to the first CPU in this case.
184228f09b3SNathan Whitehorn */
185228f09b3SNathan Whitehorn if (platform_smp_get_bsp(&cpu) != 0)
186228f09b3SNathan Whitehorn platform_smp_first_cpu(&cpu);
187228f09b3SNathan Whitehorn ticks_per_sec = platform_timebase_freq(&cpu);
188f32ebdc8SWojciech Macek ps_per_tick = 1000000000000 / ticks_per_sec;
189228f09b3SNathan Whitehorn
1908701571dSMitchell Horne set_cputicker(mftb, ticks_per_sec, false);
191228f09b3SNathan Whitehorn snprintf(buf, sizeof(buf), "cpu%d:decrementer", curcpu);
192228f09b3SNathan Whitehorn intrcnt_add(buf, &decr_counts[curcpu]);
193228f09b3SNathan Whitehorn decr_et_stop(NULL);
194228f09b3SNathan Whitehorn initialized = 1;
195228f09b3SNathan Whitehorn }
196228f09b3SNathan Whitehorn
197228f09b3SNathan Whitehorn #ifdef SMP
198228f09b3SNathan Whitehorn /*
199228f09b3SNathan Whitehorn * AP early initialization.
200228f09b3SNathan Whitehorn */
201228f09b3SNathan Whitehorn void
decr_ap_init(void)202228f09b3SNathan Whitehorn decr_ap_init(void)
203228f09b3SNathan Whitehorn {
204228f09b3SNathan Whitehorn char buf[32];
205228f09b3SNathan Whitehorn
206228f09b3SNathan Whitehorn snprintf(buf, sizeof(buf), "cpu%d:decrementer", curcpu);
207228f09b3SNathan Whitehorn intrcnt_add(buf, &decr_counts[curcpu]);
208228f09b3SNathan Whitehorn decr_et_stop(NULL);
209228f09b3SNathan Whitehorn }
210228f09b3SNathan Whitehorn #endif
211228f09b3SNathan Whitehorn
212228f09b3SNathan Whitehorn /*
213228f09b3SNathan Whitehorn * Final initialization.
214228f09b3SNathan Whitehorn */
215228f09b3SNathan Whitehorn void
decr_tc_init(void)216228f09b3SNathan Whitehorn decr_tc_init(void)
217228f09b3SNathan Whitehorn {
218228f09b3SNathan Whitehorn
219228f09b3SNathan Whitehorn decr_tc.tc_frequency = ticks_per_sec;
220228f09b3SNathan Whitehorn tc_init(&decr_tc);
221228f09b3SNathan Whitehorn decr_et.et_name = "decrementer";
222228f09b3SNathan Whitehorn decr_et.et_flags = ET_FLAGS_PERIODIC | ET_FLAGS_ONESHOT |
223228f09b3SNathan Whitehorn ET_FLAGS_PERCPU;
224228f09b3SNathan Whitehorn decr_et.et_quality = 1000;
225228f09b3SNathan Whitehorn decr_et.et_frequency = ticks_per_sec;
226228f09b3SNathan Whitehorn decr_et.et_min_period = (0x00000002LLU << 32) / ticks_per_sec;
227228f09b3SNathan Whitehorn decr_et.et_max_period = (0x7fffffffLLU << 32) / ticks_per_sec;
228228f09b3SNathan Whitehorn decr_et.et_start = decr_et_start;
229228f09b3SNathan Whitehorn decr_et.et_stop = decr_et_stop;
230228f09b3SNathan Whitehorn decr_et.et_priv = NULL;
231228f09b3SNathan Whitehorn et_register(&decr_et);
232228f09b3SNathan Whitehorn }
233228f09b3SNathan Whitehorn
234328b5f25SBrandon Bergren uint32_t
decr_vdso_timehands(struct vdso_timehands * vdso_th,struct timecounter * tc)235328b5f25SBrandon Bergren decr_vdso_timehands(struct vdso_timehands *vdso_th, struct timecounter *tc)
236328b5f25SBrandon Bergren {
237328b5f25SBrandon Bergren vdso_th->th_algo = VDSO_TH_ALGO_PPC_TB;
238328b5f25SBrandon Bergren bzero(vdso_th->th_res, sizeof(vdso_th->th_res));
239328b5f25SBrandon Bergren return (initialized == 1);
240328b5f25SBrandon Bergren }
241328b5f25SBrandon Bergren
242328b5f25SBrandon Bergren #ifdef COMPAT_FREEBSD32
243328b5f25SBrandon Bergren uint32_t
decr_vdso_timehands32(struct vdso_timehands32 * vdso_th32,struct timecounter * tc)244328b5f25SBrandon Bergren decr_vdso_timehands32(struct vdso_timehands32 *vdso_th32,
245328b5f25SBrandon Bergren struct timecounter *tc)
246328b5f25SBrandon Bergren {
247328b5f25SBrandon Bergren vdso_th32->th_algo = VDSO_TH_ALGO_PPC_TB;
248328b5f25SBrandon Bergren bzero(vdso_th32->th_res, sizeof(vdso_th32->th_res));
249328b5f25SBrandon Bergren return (initialized == 1);
250328b5f25SBrandon Bergren }
251328b5f25SBrandon Bergren #endif
252328b5f25SBrandon Bergren
253228f09b3SNathan Whitehorn /*
254228f09b3SNathan Whitehorn * Event timer start method.
255228f09b3SNathan Whitehorn */
256228f09b3SNathan Whitehorn static int
decr_et_start(struct eventtimer * et,sbintime_t first,sbintime_t period)257228f09b3SNathan Whitehorn decr_et_start(struct eventtimer *et, sbintime_t first, sbintime_t period)
258228f09b3SNathan Whitehorn {
259228f09b3SNathan Whitehorn struct decr_state *s = DPCPU_PTR(decr_state);
260228f09b3SNathan Whitehorn uint32_t fdiv;
261228f09b3SNathan Whitehorn #ifdef BOOKE
262228f09b3SNathan Whitehorn uint32_t tcr;
263228f09b3SNathan Whitehorn #endif
264228f09b3SNathan Whitehorn
265228f09b3SNathan Whitehorn if (period != 0) {
266228f09b3SNathan Whitehorn s->mode = 1;
267228f09b3SNathan Whitehorn s->div = (decr_et.et_frequency * period) >> 32;
268228f09b3SNathan Whitehorn } else {
269228f09b3SNathan Whitehorn s->mode = 2;
270228f09b3SNathan Whitehorn s->div = 0;
271228f09b3SNathan Whitehorn }
272228f09b3SNathan Whitehorn if (first != 0)
273228f09b3SNathan Whitehorn fdiv = (decr_et.et_frequency * first) >> 32;
274228f09b3SNathan Whitehorn else
275228f09b3SNathan Whitehorn fdiv = s->div;
276228f09b3SNathan Whitehorn
277228f09b3SNathan Whitehorn #ifdef BOOKE
278228f09b3SNathan Whitehorn tcr = mfspr(SPR_TCR);
279228f09b3SNathan Whitehorn tcr |= TCR_DIE;
280228f09b3SNathan Whitehorn if (s->mode == 1) {
281228f09b3SNathan Whitehorn mtspr(SPR_DECAR, s->div);
282228f09b3SNathan Whitehorn tcr |= TCR_ARE;
283228f09b3SNathan Whitehorn } else
284228f09b3SNathan Whitehorn tcr &= ~TCR_ARE;
285228f09b3SNathan Whitehorn mtdec(fdiv);
286228f09b3SNathan Whitehorn mtspr(SPR_TCR, tcr);
287228f09b3SNathan Whitehorn #else
288228f09b3SNathan Whitehorn mtdec(fdiv);
289228f09b3SNathan Whitehorn #endif
290228f09b3SNathan Whitehorn
291228f09b3SNathan Whitehorn return (0);
292228f09b3SNathan Whitehorn }
293228f09b3SNathan Whitehorn
294228f09b3SNathan Whitehorn /*
295228f09b3SNathan Whitehorn * Event timer stop method.
296228f09b3SNathan Whitehorn */
297228f09b3SNathan Whitehorn static int
decr_et_stop(struct eventtimer * et)298228f09b3SNathan Whitehorn decr_et_stop(struct eventtimer *et)
299228f09b3SNathan Whitehorn {
300228f09b3SNathan Whitehorn struct decr_state *s = DPCPU_PTR(decr_state);
301228f09b3SNathan Whitehorn #ifdef BOOKE
302228f09b3SNathan Whitehorn uint32_t tcr;
303228f09b3SNathan Whitehorn #endif
304228f09b3SNathan Whitehorn
305228f09b3SNathan Whitehorn s->mode = 0;
306228f09b3SNathan Whitehorn s->div = 0x7fffffff;
307228f09b3SNathan Whitehorn #ifdef BOOKE
308228f09b3SNathan Whitehorn tcr = mfspr(SPR_TCR);
309228f09b3SNathan Whitehorn tcr &= ~(TCR_DIE | TCR_ARE);
310228f09b3SNathan Whitehorn mtspr(SPR_TCR, tcr);
311228f09b3SNathan Whitehorn #else
312228f09b3SNathan Whitehorn mtdec(s->div);
313228f09b3SNathan Whitehorn #endif
314228f09b3SNathan Whitehorn return (0);
315228f09b3SNathan Whitehorn }
316228f09b3SNathan Whitehorn
317228f09b3SNathan Whitehorn /*
318228f09b3SNathan Whitehorn * Timecounter get method.
319228f09b3SNathan Whitehorn */
320228f09b3SNathan Whitehorn static unsigned
decr_get_timecount(struct timecounter * tc)321228f09b3SNathan Whitehorn decr_get_timecount(struct timecounter *tc)
322228f09b3SNathan Whitehorn {
323228f09b3SNathan Whitehorn return (mftb());
324228f09b3SNathan Whitehorn }
325228f09b3SNathan Whitehorn
326228f09b3SNathan Whitehorn /*
327228f09b3SNathan Whitehorn * Wait for about n microseconds (at least!).
328228f09b3SNathan Whitehorn */
329228f09b3SNathan Whitehorn void
DELAY(int n)330228f09b3SNathan Whitehorn DELAY(int n)
331228f09b3SNathan Whitehorn {
33277eb50c7SJustin Hibbits volatile u_quad_t tb;
33377eb50c7SJustin Hibbits u_quad_t ttb;
334228f09b3SNathan Whitehorn
335d5d7606cSColin Percival TSENTER();
336228f09b3SNathan Whitehorn tb = mftb();
337f32ebdc8SWojciech Macek ttb = tb + howmany((uint64_t)n * 1000000, ps_per_tick);
33877eb50c7SJustin Hibbits nop_prio_vlow();
339228f09b3SNathan Whitehorn while (tb < ttb)
340228f09b3SNathan Whitehorn tb = mftb();
34177eb50c7SJustin Hibbits nop_prio_medium();
342d5d7606cSColin Percival TSEXIT();
343228f09b3SNathan Whitehorn }
344