OsdSchedule.c revision 1.19
11.19Schristos/*	$NetBSD: OsdSchedule.c,v 1.19 2017/11/12 02:59:55 christos Exp $	*/
21.1Skochi
31.1Skochi/*
41.1Skochi * Copyright 2001 Wasabi Systems, Inc.
51.1Skochi * All rights reserved.
61.1Skochi *
71.1Skochi * Written by Jason R. Thorpe for Wasabi Systems, Inc.
81.1Skochi *
91.1Skochi * Redistribution and use in source and binary forms, with or without
101.1Skochi * modification, are permitted provided that the following conditions
111.1Skochi * are met:
121.1Skochi * 1. Redistributions of source code must retain the above copyright
131.1Skochi *    notice, this list of conditions and the following disclaimer.
141.1Skochi * 2. Redistributions in binary form must reproduce the above copyright
151.1Skochi *    notice, this list of conditions and the following disclaimer in the
161.1Skochi *    documentation and/or other materials provided with the distribution.
171.1Skochi * 3. All advertising materials mentioning features or use of this software
181.1Skochi *    must display the following acknowledgement:
191.1Skochi *	This product includes software developed for the NetBSD Project by
201.1Skochi *	Wasabi Systems, Inc.
211.1Skochi * 4. The name of Wasabi Systems, Inc. may not be used to endorse
221.1Skochi *    or promote products derived from this software without specific prior
231.1Skochi *    written permission.
241.1Skochi *
251.1Skochi * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
261.1Skochi * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
271.1Skochi * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
281.1Skochi * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL WASABI SYSTEMS, INC
291.1Skochi * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
301.1Skochi * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
311.1Skochi * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
321.1Skochi * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
331.1Skochi * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
341.1Skochi * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
351.1Skochi * POSSIBILITY OF SUCH DAMAGE.
361.1Skochi */
371.1Skochi
381.1Skochi/*
391.1Skochi * OS Services Layer
401.1Skochi *
411.1Skochi * 6.3: Scheduling services
421.1Skochi */
431.1Skochi
441.1Skochi#include <sys/cdefs.h>
451.19Schristos__KERNEL_RCSID(0, "$NetBSD: OsdSchedule.c,v 1.19 2017/11/12 02:59:55 christos Exp $");
461.1Skochi
471.1Skochi#include <sys/param.h>
481.1Skochi#include <sys/malloc.h>
491.1Skochi#include <sys/proc.h>
501.1Skochi#include <sys/systm.h>
511.1Skochi#include <sys/kernel.h>
521.5Sjmcneill#include <sys/condvar.h>
531.5Sjmcneill#include <sys/mutex.h>
541.1Skochi
551.1Skochi#include <dev/acpi/acpica.h>
561.1Skochi
571.1Skochi#include <dev/acpi/acpi_osd.h>
581.1Skochi
591.1Skochi#include <dev/sysmon/sysmon_taskq.h>
601.1Skochi
611.9Sjmcneillextern int acpi_suspended;
621.9Sjmcneill
631.1Skochi#define	_COMPONENT	ACPI_OS_SERVICES
641.1SkochiACPI_MODULE_NAME("SCHEDULE")
651.1Skochi
661.5Sjmcneillstatic kcondvar_t	acpi_osd_sleep_cv;
671.5Sjmcneillstatic kmutex_t		acpi_osd_sleep_mtx;
681.5Sjmcneill
691.1Skochi/*
701.1Skochi * acpi_osd_sched_init:
711.1Skochi *
721.1Skochi *	Initialize the APCICA Osd scheduler.  Called from AcpiOsInitialize().
731.1Skochi */
741.1Skochivoid
751.1Skochiacpi_osd_sched_init(void)
761.1Skochi{
771.1Skochi	sysmon_task_queue_init();
781.5Sjmcneill	mutex_init(&acpi_osd_sleep_mtx, MUTEX_DEFAULT, IPL_NONE);
791.5Sjmcneill	cv_init(&acpi_osd_sleep_cv, "acpislp");
801.1Skochi}
811.1Skochi
821.1Skochi/*
831.1Skochi * AcpiOsGetThreadId:
841.1Skochi *
851.1Skochi *	Obtain the ID of the currently executing thread.
861.1Skochi */
871.2SjmcneillACPI_THREAD_ID
881.1SkochiAcpiOsGetThreadId(void)
891.1Skochi{
901.16Sjmcneill	return (ACPI_THREAD_ID)(uintptr_t)curlwp;
911.1Skochi}
921.1Skochi
931.1Skochi/*
941.1Skochi * AcpiOsQueueForExecution:
951.1Skochi *
961.1Skochi *	Schedule a procedure for deferred execution.
971.1Skochi */
981.1SkochiACPI_STATUS
991.2SjmcneillAcpiOsExecute(ACPI_EXECUTE_TYPE Type, ACPI_OSD_EXEC_CALLBACK Function,
1001.1Skochi    void *Context)
1011.1Skochi{
1021.1Skochi	int pri;
1031.1Skochi
1041.2Sjmcneill	switch (Type) {
1051.2Sjmcneill	case OSL_GPE_HANDLER:
1061.2Sjmcneill		pri = 10;
1071.1Skochi		break;
1081.2Sjmcneill	case OSL_GLOBAL_LOCK_HANDLER:
1091.2Sjmcneill	case OSL_EC_POLL_HANDLER:
1101.2Sjmcneill	case OSL_EC_BURST_HANDLER:
1111.2Sjmcneill		pri = 5;
1121.1Skochi		break;
1131.2Sjmcneill	case OSL_NOTIFY_HANDLER:
1141.2Sjmcneill		pri = 3;
1151.1Skochi		break;
1161.1Skochi	default:
1171.11Sjmcneill		return AE_BAD_PARAMETER;
1181.1Skochi	}
1191.1Skochi
1201.1Skochi	switch (sysmon_task_queue_sched(pri, Function, Context)) {
1211.1Skochi	case 0:
1221.11Sjmcneill		return AE_OK;
1231.1Skochi
1241.1Skochi	case ENOMEM:
1251.11Sjmcneill		return AE_NO_MEMORY;
1261.1Skochi
1271.1Skochi	default:
1281.11Sjmcneill		return AE_BAD_PARAMETER;
1291.1Skochi	}
1301.1Skochi}
1311.1Skochi
1321.1Skochi/*
1331.1Skochi * AcpiOsSleep:
1341.1Skochi *
1351.1Skochi *	Suspend the running task (coarse granularity).
1361.1Skochi */
1371.1Skochivoid
1381.1SkochiAcpiOsSleep(ACPI_INTEGER Milliseconds)
1391.1Skochi{
1401.13Sjruoho
1411.10Sdrochner	if (cold || doing_shutdown || acpi_suspended)
1421.8Sjmcneill		DELAY(Milliseconds * 1000);
1431.8Sjmcneill	else {
1441.8Sjmcneill		mutex_enter(&acpi_osd_sleep_mtx);
1451.8Sjmcneill		cv_timedwait_sig(&acpi_osd_sleep_cv, &acpi_osd_sleep_mtx,
1461.8Sjmcneill		    MAX(mstohz(Milliseconds), 1));
1471.8Sjmcneill		mutex_exit(&acpi_osd_sleep_mtx);
1481.8Sjmcneill	}
1491.1Skochi}
1501.1Skochi
1511.1Skochi/*
1521.1Skochi * AcpiOsStall:
1531.1Skochi *
1541.1Skochi *	Suspend the running task (fine granularity).
1551.1Skochi */
1561.1Skochivoid
1571.1SkochiAcpiOsStall(UINT32 Microseconds)
1581.1Skochi{
1591.1Skochi
1601.1Skochi	delay(Microseconds);
1611.1Skochi}
1621.1Skochi
1631.1Skochi/*
1641.4Sjmcneill * AcpiOsGetTimer:
1651.1Skochi *
1661.1Skochi *	Get the current system time in 100 nanosecond units
1671.1Skochi */
1681.1SkochiUINT64
1691.1SkochiAcpiOsGetTimer(void)
1701.1Skochi{
1711.19Schristos	static UINT64 xt;
1721.1Skochi	struct timeval tv;
1731.1Skochi	UINT64 t;
1741.1Skochi
1751.1Skochi	/* XXX During early boot there is no (decent) timer available yet. */
1761.19Schristos	if (cold) {
1771.19Schristos		return xt += 100;
1781.19Schristos	}
1791.1Skochi
1801.1Skochi	microtime(&tv);
1811.1Skochi	t = (UINT64)10 * tv.tv_usec;
1821.1Skochi	t += (UINT64)10000000 * tv.tv_sec;
1831.1Skochi
1841.11Sjmcneill	return t;
1851.1Skochi}
1861.17Schristos
1871.17Schristos/*
1881.17Schristos *
1891.17Schristos * AcpiOsWaitEventsComplete:
1901.17Schristos *
1911.17Schristos * 	Wait for all asynchronous events to complete. This implementation
1921.17Schristos *	does nothing.
1931.17Schristos */
1941.17Schristosvoid
1951.17SchristosAcpiOsWaitEventsComplete(void)
1961.17Schristos{
1971.17Schristos	return;
1981.17Schristos}
199