1*adfa13f6Sriastradh /* $NetBSD: OsdSchedule.c,v 1.20 2021/12/31 14:22:26 riastradh Exp $ */
2cf31c67bSkochi
3cf31c67bSkochi /*
4cf31c67bSkochi * Copyright 2001 Wasabi Systems, Inc.
5cf31c67bSkochi * All rights reserved.
6cf31c67bSkochi *
7cf31c67bSkochi * Written by Jason R. Thorpe for Wasabi Systems, Inc.
8cf31c67bSkochi *
9cf31c67bSkochi * Redistribution and use in source and binary forms, with or without
10cf31c67bSkochi * modification, are permitted provided that the following conditions
11cf31c67bSkochi * are met:
12cf31c67bSkochi * 1. Redistributions of source code must retain the above copyright
13cf31c67bSkochi * notice, this list of conditions and the following disclaimer.
14cf31c67bSkochi * 2. Redistributions in binary form must reproduce the above copyright
15cf31c67bSkochi * notice, this list of conditions and the following disclaimer in the
16cf31c67bSkochi * documentation and/or other materials provided with the distribution.
17cf31c67bSkochi * 3. All advertising materials mentioning features or use of this software
18cf31c67bSkochi * must display the following acknowledgement:
19cf31c67bSkochi * This product includes software developed for the NetBSD Project by
20cf31c67bSkochi * Wasabi Systems, Inc.
21cf31c67bSkochi * 4. The name of Wasabi Systems, Inc. may not be used to endorse
22cf31c67bSkochi * or promote products derived from this software without specific prior
23cf31c67bSkochi * written permission.
24cf31c67bSkochi *
25cf31c67bSkochi * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
26cf31c67bSkochi * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
27cf31c67bSkochi * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28cf31c67bSkochi * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC
29cf31c67bSkochi * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30cf31c67bSkochi * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31cf31c67bSkochi * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32cf31c67bSkochi * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33cf31c67bSkochi * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34cf31c67bSkochi * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35cf31c67bSkochi * POSSIBILITY OF SUCH DAMAGE.
36cf31c67bSkochi */
37cf31c67bSkochi
38cf31c67bSkochi /*
39cf31c67bSkochi * OS Services Layer
40cf31c67bSkochi *
41cf31c67bSkochi * 6.3: Scheduling services
42cf31c67bSkochi */
43cf31c67bSkochi
44cf31c67bSkochi #include <sys/cdefs.h>
45*adfa13f6Sriastradh __KERNEL_RCSID(0, "$NetBSD: OsdSchedule.c,v 1.20 2021/12/31 14:22:26 riastradh Exp $");
46cf31c67bSkochi
47cf31c67bSkochi #include <sys/param.h>
48cf31c67bSkochi #include <sys/malloc.h>
49cf31c67bSkochi #include <sys/proc.h>
50cf31c67bSkochi #include <sys/systm.h>
51cf31c67bSkochi #include <sys/kernel.h>
52ef892278Sjmcneill #include <sys/condvar.h>
53ef892278Sjmcneill #include <sys/mutex.h>
54cf31c67bSkochi
55cf31c67bSkochi #include <dev/acpi/acpica.h>
56cf31c67bSkochi
57cf31c67bSkochi #include <dev/acpi/acpi_osd.h>
58cf31c67bSkochi
59cf31c67bSkochi #include <dev/sysmon/sysmon_taskq.h>
60cf31c67bSkochi
610cc9fff2Sjmcneill extern int acpi_suspended;
620cc9fff2Sjmcneill
63cf31c67bSkochi #define _COMPONENT ACPI_OS_SERVICES
64cf31c67bSkochi ACPI_MODULE_NAME("SCHEDULE")
65cf31c67bSkochi
66ef892278Sjmcneill static kcondvar_t acpi_osd_sleep_cv;
67ef892278Sjmcneill static kmutex_t acpi_osd_sleep_mtx;
68ef892278Sjmcneill
69cf31c67bSkochi /*
70cf31c67bSkochi * acpi_osd_sched_init:
71cf31c67bSkochi *
72cf31c67bSkochi * Initialize the APCICA Osd scheduler. Called from AcpiOsInitialize().
73cf31c67bSkochi */
74cf31c67bSkochi void
acpi_osd_sched_init(void)75cf31c67bSkochi acpi_osd_sched_init(void)
76cf31c67bSkochi {
77cf31c67bSkochi sysmon_task_queue_init();
78ef892278Sjmcneill mutex_init(&acpi_osd_sleep_mtx, MUTEX_DEFAULT, IPL_NONE);
79ef892278Sjmcneill cv_init(&acpi_osd_sleep_cv, "acpislp");
80cf31c67bSkochi }
81cf31c67bSkochi
82cf31c67bSkochi /*
83cf31c67bSkochi * AcpiOsGetThreadId:
84cf31c67bSkochi *
85cf31c67bSkochi * Obtain the ID of the currently executing thread.
86cf31c67bSkochi */
874c1d81b2Sjmcneill ACPI_THREAD_ID
AcpiOsGetThreadId(void)88cf31c67bSkochi AcpiOsGetThreadId(void)
89cf31c67bSkochi {
902bf4673fSjmcneill return (ACPI_THREAD_ID)(uintptr_t)curlwp;
91cf31c67bSkochi }
92cf31c67bSkochi
93cf31c67bSkochi /*
94cf31c67bSkochi * AcpiOsQueueForExecution:
95cf31c67bSkochi *
96cf31c67bSkochi * Schedule a procedure for deferred execution.
97cf31c67bSkochi */
98cf31c67bSkochi ACPI_STATUS
AcpiOsExecute(ACPI_EXECUTE_TYPE Type,ACPI_OSD_EXEC_CALLBACK Function,void * Context)994c1d81b2Sjmcneill AcpiOsExecute(ACPI_EXECUTE_TYPE Type, ACPI_OSD_EXEC_CALLBACK Function,
100cf31c67bSkochi void *Context)
101cf31c67bSkochi {
102cf31c67bSkochi int pri;
103cf31c67bSkochi
104*adfa13f6Sriastradh /*
105*adfa13f6Sriastradh * If you raise any priority here make sure to adjust
106*adfa13f6Sriastradh * AcpiOsWaitEventsComplete too.
107*adfa13f6Sriastradh */
1084c1d81b2Sjmcneill switch (Type) {
1094c1d81b2Sjmcneill case OSL_GPE_HANDLER:
1104c1d81b2Sjmcneill pri = 10;
1114c1d81b2Sjmcneill break;
1124c1d81b2Sjmcneill case OSL_GLOBAL_LOCK_HANDLER:
1134c1d81b2Sjmcneill case OSL_EC_POLL_HANDLER:
1144c1d81b2Sjmcneill case OSL_EC_BURST_HANDLER:
1154c1d81b2Sjmcneill pri = 5;
1164c1d81b2Sjmcneill break;
1174c1d81b2Sjmcneill case OSL_NOTIFY_HANDLER:
118cf31c67bSkochi pri = 3;
119cf31c67bSkochi break;
120cf31c67bSkochi default:
121b0fb7abfSjmcneill return AE_BAD_PARAMETER;
122cf31c67bSkochi }
123cf31c67bSkochi
124cf31c67bSkochi switch (sysmon_task_queue_sched(pri, Function, Context)) {
125cf31c67bSkochi case 0:
126b0fb7abfSjmcneill return AE_OK;
127cf31c67bSkochi
128cf31c67bSkochi case ENOMEM:
129b0fb7abfSjmcneill return AE_NO_MEMORY;
130cf31c67bSkochi
131cf31c67bSkochi default:
132b0fb7abfSjmcneill return AE_BAD_PARAMETER;
133cf31c67bSkochi }
134cf31c67bSkochi }
135cf31c67bSkochi
136cf31c67bSkochi /*
137cf31c67bSkochi * AcpiOsSleep:
138cf31c67bSkochi *
139cf31c67bSkochi * Suspend the running task (coarse granularity).
140cf31c67bSkochi */
141cf31c67bSkochi void
AcpiOsSleep(ACPI_INTEGER Milliseconds)142cf31c67bSkochi AcpiOsSleep(ACPI_INTEGER Milliseconds)
143cf31c67bSkochi {
1442731b5ffSjruoho
1450785c6f1Sdrochner if (cold || doing_shutdown || acpi_suspended)
1469f877bc7Sjmcneill DELAY(Milliseconds * 1000);
1479f877bc7Sjmcneill else {
148ef892278Sjmcneill mutex_enter(&acpi_osd_sleep_mtx);
149ef892278Sjmcneill cv_timedwait_sig(&acpi_osd_sleep_cv, &acpi_osd_sleep_mtx,
150ef892278Sjmcneill MAX(mstohz(Milliseconds), 1));
151ef892278Sjmcneill mutex_exit(&acpi_osd_sleep_mtx);
152cf31c67bSkochi }
1539f877bc7Sjmcneill }
154cf31c67bSkochi
155cf31c67bSkochi /*
156cf31c67bSkochi * AcpiOsStall:
157cf31c67bSkochi *
158cf31c67bSkochi * Suspend the running task (fine granularity).
159cf31c67bSkochi */
160cf31c67bSkochi void
AcpiOsStall(UINT32 Microseconds)161cf31c67bSkochi AcpiOsStall(UINT32 Microseconds)
162cf31c67bSkochi {
163cf31c67bSkochi
164cf31c67bSkochi delay(Microseconds);
165cf31c67bSkochi }
166cf31c67bSkochi
167cf31c67bSkochi /*
168dd0320efSjmcneill * AcpiOsGetTimer:
169cf31c67bSkochi *
170cf31c67bSkochi * Get the current system time in 100 nanosecond units
171cf31c67bSkochi */
172cf31c67bSkochi UINT64
AcpiOsGetTimer(void)173cf31c67bSkochi AcpiOsGetTimer(void)
174cf31c67bSkochi {
175732dc837Schristos static UINT64 xt;
176cf31c67bSkochi struct timeval tv;
177cf31c67bSkochi UINT64 t;
178cf31c67bSkochi
179cf31c67bSkochi /* XXX During early boot there is no (decent) timer available yet. */
180732dc837Schristos if (cold) {
181732dc837Schristos return xt += 100;
182732dc837Schristos }
183cf31c67bSkochi
184cf31c67bSkochi microtime(&tv);
185cf31c67bSkochi t = (UINT64)10 * tv.tv_usec;
186cf31c67bSkochi t += (UINT64)10000000 * tv.tv_sec;
187cf31c67bSkochi
188b0fb7abfSjmcneill return t;
189cf31c67bSkochi }
1900a1a7e48Schristos
1910a1a7e48Schristos /*
1920a1a7e48Schristos * AcpiOsWaitEventsComplete:
1930a1a7e48Schristos *
194*adfa13f6Sriastradh * Wait for all asynchronous events to complete.
1950a1a7e48Schristos */
1960a1a7e48Schristos void
AcpiOsWaitEventsComplete(void)1970a1a7e48Schristos AcpiOsWaitEventsComplete(void)
1980a1a7e48Schristos {
199*adfa13f6Sriastradh /* Highest priority used by AcpiOsExecute. */
200*adfa13f6Sriastradh sysmon_task_queue_barrier(10);
2010a1a7e48Schristos }
202