ACPI_STATUS
AcpiEnterSleepStatePrep (
UINT8 SleepState)
{
ACPI_STATUS Status;
ACPI_OBJECT_LIST ArgList;
ACPI_OBJECT Arg;
ACPI_FUNCTION_TRACE (AcpiEnterSleepStatePrep);
/* _PSW methods could be run here to enable wake-on keyboard, LAN, etc. */
Status = AcpiGetSleepTypeData (SleepState,
&AcpiGbl_SleepTypeA, &AcpiGbl_SleepTypeB);
if (ACPI_FAILURE (Status))
{
return_ACPI_STATUS (Status);
}
/* Execute the _PTS method (Prepare To Sleep) */
ArgList.Count = 1;
ArgList.Pointer = &Arg;
Arg.Type = ACPI_TYPE_INTEGER;
Arg.Integer.Value = SleepState;
Status = AcpiEvaluateObject (NULL, METHOD_NAME__PTS, &ArgList, NULL);
if (ACPI_FAILURE (Status) && Status != AE_NOT_FOUND)
{
return_ACPI_STATUS (Status);
}
/* Setup the argument to the _SST method (System STatus) */
switch (SleepState)
{
case ACPI_STATE_S0:
Arg.Integer.Value = ACPI_SST_WORKING;
break;
case ACPI_STATE_S1:
case ACPI_STATE_S2:
case ACPI_STATE_S3:
Arg.Integer.Value = ACPI_SST_SLEEPING;
break;
case ACPI_STATE_S4:
Arg.Integer.Value = ACPI_SST_SLEEP_CONTEXT;
break;
default:
Arg.Integer.Value = ACPI_SST_INDICATOR_OFF; /* Default is off */
break;
}
/*
* Set the system indicators to show the desired sleep state.
* _SST is an optional method (return no error if not found)
*/
Status = AcpiEvaluateObject (NULL, METHOD_NAME__SST, &ArgList, NULL);
if (ACPI_FAILURE (Status) && Status != AE_NOT_FOUND)
{
ACPI_EXCEPTION ((AE_INFO, Status, "While executing method _SST"));
}
return_ACPI_STATUS (AE_OK);
}
ACPI_STATUS
AcpiDsInitializeObjects (
UINT32 TableIndex,
ACPI_NAMESPACE_NODE *StartNode)
{
ACPI_STATUS Status;
ACPI_INIT_WALK_INFO Info;
ACPI_TABLE_HEADER *Table;
ACPI_OWNER_ID OwnerId;
ACPI_FUNCTION_TRACE (DsInitializeObjects);
Status = AcpiTbGetOwnerId (TableIndex, &OwnerId);
if (ACPI_FAILURE (Status))
{
return_ACPI_STATUS (Status);
}
ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
"**** Starting initialization of namespace objects ****\n"));
ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT, "Parsing all Control Methods:"));
/* Set all init info to zero */
ACPI_MEMSET (&Info, 0, sizeof (ACPI_INIT_WALK_INFO));
Info.OwnerId = OwnerId;
Info.TableIndex = TableIndex;
/* Walk entire namespace from the supplied root */
Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
if (ACPI_FAILURE (Status))
{
return_ACPI_STATUS (Status);
}
/*
* We don't use AcpiWalkNamespace since we do not want to acquire
* the namespace reader lock.
*/
Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, StartNode, ACPI_UINT32_MAX,
ACPI_NS_WALK_UNLOCK, AcpiDsInitOneObject, NULL, &Info, NULL);
if (ACPI_FAILURE (Status))
{
ACPI_EXCEPTION ((AE_INFO, Status, "During WalkNamespace"));
}
(void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
Status = AcpiGetTableByIndex (TableIndex, &Table);
if (ACPI_FAILURE (Status))
{
return_ACPI_STATUS (Status);
}
ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT,
"\nTable [%4.4s](id %4.4X) - %u Objects with %u Devices %u Methods %u Regions\n",
Table->Signature, OwnerId, Info.ObjectCount,
Info.DeviceCount, Info.MethodCount, Info.OpRegionCount));
ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
"%u Methods, %u Regions\n", Info.MethodCount, Info.OpRegionCount));
return_ACPI_STATUS (AE_OK);
}
开发者ID:ornarium,项目名称:freebsd,代码行数:67,代码来源:dsinit.c
示例3: AcpiEvInitializeGpeBlock
ACPI_STATUS
AcpiEvInitializeGpeBlock (
ACPI_GPE_XRUPT_INFO *GpeXruptInfo,
ACPI_GPE_BLOCK_INFO *GpeBlock,
void *Ignored)
{
ACPI_STATUS Status;
ACPI_GPE_EVENT_INFO *GpeEventInfo;
UINT32 GpeEnabledCount;
UINT32 GpeIndex;
UINT32 i;
UINT32 j;
ACPI_FUNCTION_TRACE (EvInitializeGpeBlock);
/*
* Ignore a null GPE block (e.g., if no GPE block 1 exists), and
* any GPE blocks that have been initialized already.
*/
if (!GpeBlock || GpeBlock->Initialized)
{
return_ACPI_STATUS (AE_OK);
}
/*
* Enable all GPEs that have a corresponding method and have the
* ACPI_GPE_CAN_WAKE flag unset. Any other GPEs within this block
* must be enabled via the acpi_enable_gpe() interface.
*/
GpeEnabledCount = 0;
for (i = 0; i < GpeBlock->RegisterCount; i++)
{
for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++)
{
/* Get the info block for this particular GPE */
GpeIndex = (i * ACPI_GPE_REGISTER_WIDTH) + j;
GpeEventInfo = &GpeBlock->EventInfo[GpeIndex];
/*
* Ignore GPEs that have no corresponding _Lxx/_Exx method
* and GPEs that are used to wake the system
*/
if ((ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags) == ACPI_GPE_DISPATCH_NONE) ||
(ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags) == ACPI_GPE_DISPATCH_HANDLER) ||
(ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags) == ACPI_GPE_DISPATCH_RAW_HANDLER) ||
(GpeEventInfo->Flags & ACPI_GPE_CAN_WAKE))
{
continue;
}
Status = AcpiEvAddGpeReference (GpeEventInfo);
if (ACPI_FAILURE (Status))
{
ACPI_EXCEPTION ((AE_INFO, Status,
"Could not enable GPE 0x%02X",
GpeIndex + GpeBlock->BlockBaseNumber));
continue;
}
GpeEnabledCount++;
}
}
if (GpeEnabledCount)
{
ACPI_INFO ((AE_INFO,
"Enabled %u GPEs in block %02X to %02X", GpeEnabledCount,
(UINT32) GpeBlock->BlockBaseNumber,
(UINT32) (GpeBlock->BlockBaseNumber + (GpeBlock->GpeCount - 1))));
}
GpeBlock->Initialized = TRUE;
return_ACPI_STATUS (AE_OK);
}
ACPI_STATUS
AcpiDsGetPredicateValue (
ACPI_WALK_STATE *WalkState,
ACPI_OPERAND_OBJECT *ResultObj)
{
ACPI_STATUS Status = AE_OK;
ACPI_OPERAND_OBJECT *ObjDesc;
ACPI_OPERAND_OBJECT *LocalObjDesc = NULL;
ACPI_FUNCTION_TRACE_PTR (DsGetPredicateValue, WalkState);
WalkState->ControlState->Common.State = 0;
if (ResultObj)
{
Status = AcpiDsResultPop (&ObjDesc, WalkState);
if (ACPI_FAILURE (Status))
{
ACPI_EXCEPTION ((AE_INFO, Status,
"Could not get result from predicate evaluation"));
return_ACPI_STATUS (Status);
}
}
else
{
Status = AcpiDsCreateOperand (WalkState, WalkState->Op, 0);
if (ACPI_FAILURE (Status))
{
return_ACPI_STATUS (Status);
}
Status = AcpiExResolveToValue (&WalkState->Operands [0], WalkState);
if (ACPI_FAILURE (Status))
{
return_ACPI_STATUS (Status);
}
ObjDesc = WalkState->Operands [0];
}
if (!ObjDesc)
{
ACPI_ERROR ((AE_INFO,
"No predicate ObjDesc=%p State=%p",
ObjDesc, WalkState));
return_ACPI_STATUS (AE_AML_NO_OPERAND);
}
/*
* Result of predicate evaluation must be an Integer
* object. Implicitly convert the argument if necessary.
*/
Status = AcpiExConvertToInteger (ObjDesc, &LocalObjDesc, 16);
if (ACPI_FAILURE (Status))
{
goto Cleanup;
}
if (LocalObjDesc->Common.Type != ACPI_TYPE_INTEGER)
{
ACPI_ERROR ((AE_INFO,
"Bad predicate (not an integer) ObjDesc=%p State=%p Type=0x%X",
ObjDesc, WalkState, ObjDesc->Common.Type));
Status = AE_AML_OPERAND_TYPE;
goto Cleanup;
}
/* Truncate the predicate to 32-bits if necessary */
AcpiExTruncateFor32bitTable (LocalObjDesc);
/*
* Save the result of the predicate evaluation on
* the control stack
*/
if (LocalObjDesc->Integer.Value)
{
WalkState->ControlState->Common.Value = TRUE;
}
else
{
/*
* Predicate is FALSE, we will just toss the
* rest of the package
*/
WalkState->ControlState->Common.Value = FALSE;
Status = AE_CTRL_FALSE;
}
/* Predicate can be used for an implicit return value */
(void) AcpiDsDoImplicitReturn (LocalObjDesc, WalkState, TRUE);
Cleanup:
//.........这里部分代码省略.........
/*******************************************************************************
*
* FUNCTION: acpi_ev_gpe_initialize
*
* PARAMETERS: None
*
* RETURN: Status
*
* DESCRIPTION: Initialize the GPE data structures and the FADT GPE 0/1 blocks
*
******************************************************************************/
acpi_status acpi_ev_gpe_initialize(void)
{
u32 register_count0 = 0;
u32 register_count1 = 0;
u32 gpe_number_max = 0;
acpi_status status;
ACPI_FUNCTION_TRACE(ev_gpe_initialize);
status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
/*
* Initialize the GPE Block(s) defined in the FADT
*
* Why the GPE register block lengths are divided by 2: From the ACPI
* Spec, section "General-Purpose Event Registers", we have:
*
* "Each register block contains two registers of equal length
* GPEx_STS and GPEx_EN (where x is 0 or 1). The length of the
* GPE0_STS and GPE0_EN registers is equal to half the GPE0_LEN
* The length of the GPE1_STS and GPE1_EN registers is equal to
* half the GPE1_LEN. If a generic register block is not supported
* then its respective block pointer and block length values in the
* FADT table contain zeros. The GPE0_LEN and GPE1_LEN do not need
* to be the same size."
*/
/*
* Determine the maximum GPE number for this machine.
*
* Note: both GPE0 and GPE1 are optional, and either can exist without
* the other.
*
* If EITHER the register length OR the block address are zero, then that
* particular block is not supported.
*/
if (acpi_gbl_FADT.gpe0_block_length &&
acpi_gbl_FADT.xgpe0_block.address) {
/* GPE block 0 exists (has both length and address > 0) */
register_count0 = (u16)(acpi_gbl_FADT.gpe0_block_length / 2);
gpe_number_max =
(register_count0 * ACPI_GPE_REGISTER_WIDTH) - 1;
/* Install GPE Block 0 */
status = acpi_ev_create_gpe_block(acpi_gbl_fadt_gpe_device,
&acpi_gbl_FADT.xgpe0_block,
register_count0, 0,
acpi_gbl_FADT.sci_interrupt,
&acpi_gbl_gpe_fadt_blocks[0]);
if (ACPI_FAILURE(status)) {
ACPI_EXCEPTION((AE_INFO, status,
"Could not create GPE Block 0"));
}
}
if (acpi_gbl_FADT.gpe1_block_length &&
acpi_gbl_FADT.xgpe1_block.address) {
/* GPE block 1 exists (has both length and address > 0) */
register_count1 = (u16)(acpi_gbl_FADT.gpe1_block_length / 2);
/* Check for GPE0/GPE1 overlap (if both banks exist) */
if ((register_count0) &&
(gpe_number_max >= acpi_gbl_FADT.gpe1_base)) {
ACPI_ERROR((AE_INFO,
"GPE0 block (GPE 0 to %u) overlaps the GPE1 block "
"(GPE %u to %u) - Ignoring GPE1",
gpe_number_max, acpi_gbl_FADT.gpe1_base,
acpi_gbl_FADT.gpe1_base +
((register_count1 *
ACPI_GPE_REGISTER_WIDTH) - 1)));
/* Ignore GPE1 block by setting the register count to zero */
register_count1 = 0;
} else {
/* Install GPE Block 1 */
status =
//.........这里部分代码省略.........
开发者ID:08opt,项目名称:linux,代码行数:101,代码来源:evgpeinit.c
示例7: AcpiEvDetachRegion
void
AcpiEvDetachRegion (
ACPI_OPERAND_OBJECT *RegionObj,
BOOLEAN AcpiNsIsLocked)
{
ACPI_OPERAND_OBJECT *HandlerObj;
ACPI_OPERAND_OBJECT *ObjDesc;
ACPI_OPERAND_OBJECT *StartDesc;
ACPI_OPERAND_OBJECT **LastObjPtr;
ACPI_ADR_SPACE_SETUP RegionSetup;
void **RegionContext;
ACPI_OPERAND_OBJECT *RegionObj2;
ACPI_STATUS Status;
ACPI_FUNCTION_TRACE (EvDetachRegion);
RegionObj2 = AcpiNsGetSecondaryObject (RegionObj);
if (!RegionObj2)
{
return_VOID;
}
RegionContext = &RegionObj2->Extra.RegionContext;
/* Get the address handler from the region object */
HandlerObj = RegionObj->Region.Handler;
if (!HandlerObj)
{
/* This region has no handler, all done */
return_VOID;
}
/* Find this region in the handler's list */
ObjDesc = HandlerObj->AddressSpace.RegionList;
StartDesc = ObjDesc;
LastObjPtr = &HandlerObj->AddressSpace.RegionList;
while (ObjDesc)
{
/* Is this the correct Region? */
if (ObjDesc == RegionObj)
{
ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
"Removing Region %p from address handler %p\n",
RegionObj, HandlerObj));
/* This is it, remove it from the handler's list */
*LastObjPtr = ObjDesc->Region.Next;
ObjDesc->Region.Next = NULL; /* Must clear field */
if (AcpiNsIsLocked)
{
Status = AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
if (ACPI_FAILURE (Status))
{
return_VOID;
}
}
/* Now stop region accesses by executing the _REG method */
Status = AcpiEvExecuteRegMethod (RegionObj, ACPI_REG_DISCONNECT);
if (ACPI_FAILURE (Status))
{
ACPI_EXCEPTION ((AE_INFO, Status, "from region _REG, [%s]",
AcpiUtGetRegionName (RegionObj->Region.SpaceId)));
}
if (AcpiNsIsLocked)
{
Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
if (ACPI_FAILURE (Status))
{
return_VOID;
}
}
/*
* If the region has been activated, call the setup handler with
* the deactivate notification
*/
if (RegionObj->Region.Flags & AOPOBJ_SETUP_COMPLETE)
{
RegionSetup = HandlerObj->AddressSpace.Setup;
Status = RegionSetup (RegionObj, ACPI_REGION_DEACTIVATE,
HandlerObj->AddressSpace.Context, RegionContext);
/*
* RegionContext should have been released by the deactivate
* operation. We don't need access to it anymore here.
*/
if (RegionContext)
{
*RegionContext = NULL;
//.........这里部分代码省略.........
static acpi_status
acpi_ds_init_one_object(acpi_handle obj_handle,
u32 level, void *context, void **return_value)
{
struct acpi_init_walk_info *info =
(struct acpi_init_walk_info *)context;
struct acpi_namespace_node *node =
(struct acpi_namespace_node *)obj_handle;
acpi_object_type type;
acpi_status status;
ACPI_FUNCTION_ENTRY();
/*
* We are only interested in NS nodes owned by the table that
* was just loaded
*/
if (node->owner_id != info->owner_id) {
return (AE_OK);
}
info->object_count++;
/* And even then, we are only interested in a few object types */
type = acpi_ns_get_type(obj_handle);
switch (type) {
case ACPI_TYPE_REGION:
status = acpi_ds_initialize_region(obj_handle);
if (ACPI_FAILURE(status)) {
ACPI_EXCEPTION((AE_INFO, status,
"During Region initialization %p [%4.4s]",
obj_handle,
acpi_ut_get_node_name(obj_handle)));
}
info->op_region_count++;
break;
case ACPI_TYPE_METHOD:
info->method_count++;
break;
case ACPI_TYPE_DEVICE:
info->device_count++;
break;
default:
break;
}
/*
* We ignore errors from above, and always return OK, since
* we don't want to abort the walk on a single error.
*/
return (AE_OK);
}
ACPI_STATUS
AcpiEvPciConfigRegionSetup (
ACPI_HANDLE Handle,
UINT32 Function,
void *HandlerContext,
void **RegionContext)
{
ACPI_STATUS Status = AE_OK;
UINT64 PciValue;
ACPI_PCI_ID *PciId = *RegionContext;
ACPI_OPERAND_OBJECT *HandlerObj;
ACPI_NAMESPACE_NODE *ParentNode;
ACPI_NAMESPACE_NODE *PciRootNode;
ACPI_NAMESPACE_NODE *PciDeviceNode;
ACPI_OPERAND_OBJECT *RegionObj = (ACPI_OPERAND_OBJECT *) Handle;
ACPI_FUNCTION_TRACE (EvPciConfigRegionSetup);
HandlerObj = RegionObj->Region.Handler;
if (!HandlerObj)
{
/*
* No installed handler. This shouldn't happen because the dispatch
* routine checks before we get here, but we check again just in case.
*/
ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
"Attempting to init a region %p, with no handler\n", RegionObj));
return_ACPI_STATUS (AE_NOT_EXIST);
}
*RegionContext = NULL;
if (Function == ACPI_REGION_DEACTIVATE)
{
if (PciId)
{
ACPI_FREE (PciId);
}
return_ACPI_STATUS (Status);
}
ParentNode = RegionObj->Region.Node->Parent;
/*
* Get the _SEG and _BBN values from the device upon which the handler
* is installed.
*
* We need to get the _SEG and _BBN objects relative to the PCI BUS device.
* This is the device the handler has been registered to handle.
*/
/*
* If the AddressSpace.Node is still pointing to the root, we need
* to scan upward for a PCI Root bridge and re-associate the OpRegion
* handlers with that device.
*/
if (HandlerObj->AddressSpace.Node == AcpiGbl_RootNode)
{
/* Start search from the parent object */
PciRootNode = ParentNode;
while (PciRootNode != AcpiGbl_RootNode)
{
/* Get the _HID/_CID in order to detect a RootBridge */
if (AcpiEvIsPciRootBridge (PciRootNode))
{
/* Install a handler for this PCI root bridge */
Status = AcpiInstallAddressSpaceHandler (
(ACPI_HANDLE) PciRootNode,
ACPI_ADR_SPACE_PCI_CONFIG,
ACPI_DEFAULT_HANDLER, NULL, NULL);
if (ACPI_FAILURE (Status))
{
if (Status == AE_SAME_HANDLER)
{
/*
* It is OK if the handler is already installed on the
* root bridge. Still need to return a context object
* for the new PCI_Config operation region, however.
*/
Status = AE_OK;
}
else
{
ACPI_EXCEPTION ((AE_INFO, Status,
"Could not install PciConfig handler "
"for Root Bridge %4.4s",
AcpiUtGetNodeName (PciRootNode)));
}
}
break;
}
PciRootNode = PciRootNode->Parent;
}
/* PCI root bridge not found, use namespace root node */
//.........这里部分代码省略.........
请发表评论