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