acpica.c revision f2be51489e45daeb2c91d227fa1691c74cc3ea97
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
* Solaris x86 ACPI CA services
*/
#pragma ident "%Z%%M% %I% %E% SMI"
/*
*
*/
"ACPI interpreter %I%",
};
static struct modlinkage modlinkage = {
MODREV_1, /* MODREV_1 manual */
(void *)&modlmisc, /* module linkage */
NULL, /* list terminator */
};
/*
* Local data
*/
static kmutex_t acpica_module_lock;
/*
* State of acpica subsystem
* After successful initialization, will be ACPICA_INITIALIZED
*/
/*
* Following are set by acpica_process_user_options()
*
* acpica_enable = FALSE prevents initialization of ACPI CA
* completely
*
* acpi_init_level determines level of ACPI CA functionality
* enabled in acpica_init()
*/
int acpica_enable;
/*
* Non-zero enables lax behavior with respect to some
* common ACPI BIOS issues; see ACPI CA documentation
* Setting this to zero causes ACPI CA to enforce strict
* compliance with ACPI specification
*/
int acpica_enable_interpreter_slack = 1;
/*
* For non-DEBUG builds, set the ACPI CA debug level to 0
* Field-patchable for diagnostic use.
*/
#ifdef DEBUG
int acpica_muzzle_debug_output = 0;
#else
int acpica_muzzle_debug_output = 1;
#endif
int
_init(void)
{
int status;
}
}
return (error);
}
int
{
}
int
_fini(void)
{
/*
* acpica module is never unloaded at run-time; there's always
* a PSM depending on it, at the very least
*/
return (EBUSY);
}
/*
* Install acpica-provided address-space handlers
*/
static int
{
/*
* Install ACPI CA default handlers
*/
" system memory");
}
" system I/O");
}
" PCI Config");
}
return (rv);
}
/*
* Find the BIOS date, and return TRUE if supplied
* date is same or later than the BIOS date, or FALSE
* if the BIOS date can't be fetched for any reason
*/
static int
{
char *datep;
/* If firmware has no bios, skip the check */
return (TRUE);
/*
* PC BIOSes contain a string in the form of
* where mm, dd and yy are all ASCII digits.
* We map the string, pluck out the values,
* and accept all BIOSes from 1 Jan 1999 on
* as valid.
*/
return (FALSE);
/* year */
/* month */
/* day */
/* non-digit chars in BIOS date */
return (FALSE);
}
/*
* Adjust for 2-digit year; note to grand-children:
* need a new scheme before 2080 rolls around
*/
1900 : 2000;
return (FALSE);
return (TRUE);
if (bios_month < mm)
return (FALSE);
else if (bios_month > mm)
return (TRUE);
return (FALSE);
return (TRUE);
}
/*
* Check for Metropolis systems with BIOSes older than 10/12/04
* return TRUE if BIOS requires legacy mode, FALSE otherwise
*/
static int
{
/* get the FADT */
return (FALSE);
/* compare OEM Table ID to "SUNmetro" - no match, return false */
return (FALSE);
/* On a Metro - return FALSE if later than 10/12/04 */
}
/*
* Process acpi-user-options property if present
*/
static void
{
static int processed = 0;
int acpi_user_options;
char *acpi_prop;
/*
* return if acpi-user-options has already been processed
*/
if (processed)
return;
else
processed = 1;
/* converts acpi-user-options from type string to int, if any */
long data;
int ret;
if (ret == 0) {
"acpi-user-options");
"acpi-user-options", data);
}
}
/*
* fetch the optional options property
*/
"acpi-user-options", 0);
/*
* Note that 'off' has precedence over 'on'
* Also note - all cases of ACPI_OUSER_MASK
* provided here, no default: case is present
*/
switch (acpi_user_options & ACPI_OUSER_MASK) {
case ACPI_OUSER_DFLT:
break;
case ACPI_OUSER_ON:
break;
case ACPI_OUSER_OFF:
case ACPI_OUSER_OFF | ACPI_OUSER_ON:
break;
}
/*
* special test here; may be generalized in the
* future - test for a machines that are known to
* work only in legacy mode, and set OUSER_LEGACY if
* we're on one
*/
if (acpica_metro_old_bios())
/*
* If legacy mode is specified, set initialization
* options to avoid entering ACPI mode and hooking SCI
* - basically try to act like legacy acpi_intp
*/
if ((acpi_user_options & ACPI_OUSER_LEGACY) != 0)
/*
* modify default ACPI CA debug output level for non-DEBUG builds
*/
AcpiDbgLevel = 0;
}
/*
* Initialize the CA subsystem if it hasn't been done already
*/
int
{
/*
* Make sure user options are processed,
* then fail to initialize if ACPI CA has been
* disabled
*/
if (!acpica_enable)
return (AE_ERROR);
if (acpica_init_state == ACPICA_NOT_INITIALIZED) {
goto error;
}
goto error;
}
goto error;
}
goto error;
}
/*
* Initialize EC
*/
if (acpica_init_state != ACPICA_INITIALIZED) {
" ACPI services");
}
} else
/*
* Set acpi-status to 13 if acpica has been initialized successfully.
* This indicates that acpica is up and running. This variable name
* and value were chosen in order to remain compatible with acpi_intp.
*/
ACPI_BOOT_BOOTCONF) : 0);
return (status);
}
/*
* SCI handling
*/
{
/*
* Make sure user options are processed,
* then return error if ACPI CA has been
* disabled or system is not running in ACPI
* and won't need/understand SCI
*/
return (AE_ERROR);
/*
* according to Intel ACPI developers, SCI
* unless otherwise directed by overrides.
*/
/* get the SCI from the FADT */
return (AE_ERROR);
/* search for ISOs that modify it */
/* if we don't find a MADT, that's OK; no ISOs then */
return (AE_OK);
}
case APIC_XRUPT_OVERRIDE:
}
break;
}
/* advance to next entry */
}
/*
* One more check; if ISO said "conform", revert to default
*/
return (AE_OK);
}