Print this page
update to acpica-unix2-20140114
update to acpica-unix2-20131218
acpica-unix2-20130823
PANKOVs restructure
@@ -3,11 +3,11 @@
* Module Name: dsfield - Dispatcher field routines
*
*****************************************************************************/
/*
- * Copyright (C) 2000 - 2011, Intel Corp.
+ * Copyright (C) 2000 - 2014, Intel Corp.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -55,19 +55,94 @@
#define _COMPONENT ACPI_DISPATCHER
ACPI_MODULE_NAME ("dsfield")
/* Local prototypes */
+#ifdef ACPI_ASL_COMPILER
+#include "acdisasm.h"
+
static ACPI_STATUS
+AcpiDsCreateExternalRegion (
+ ACPI_STATUS LookupStatus,
+ ACPI_PARSE_OBJECT *Op,
+ char *Path,
+ ACPI_WALK_STATE *WalkState,
+ ACPI_NAMESPACE_NODE **Node);
+#endif
+
+static ACPI_STATUS
AcpiDsGetFieldNames (
ACPI_CREATE_FIELD_INFO *Info,
ACPI_WALK_STATE *WalkState,
ACPI_PARSE_OBJECT *Arg);
+#ifdef ACPI_ASL_COMPILER
/*******************************************************************************
*
+ * FUNCTION: AcpiDsCreateExternalRegion (iASL Disassembler only)
+ *
+ * PARAMETERS: LookupStatus - Status from NsLookup operation
+ * Op - Op containing the Field definition and args
+ * Path - Pathname of the region
+ * ` WalkState - Current method state
+ * Node - Where the new region node is returned
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Add region to the external list if NOT_FOUND. Create a new
+ * region node/object.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiDsCreateExternalRegion (
+ ACPI_STATUS LookupStatus,
+ ACPI_PARSE_OBJECT *Op,
+ char *Path,
+ ACPI_WALK_STATE *WalkState,
+ ACPI_NAMESPACE_NODE **Node)
+{
+ ACPI_STATUS Status;
+ ACPI_OPERAND_OBJECT *ObjDesc;
+
+
+ if (LookupStatus != AE_NOT_FOUND)
+ {
+ return (LookupStatus);
+ }
+
+ /*
+ * Table disassembly:
+ * OperationRegion not found. Generate an External for it, and
+ * insert the name into the namespace.
+ */
+ AcpiDmAddOpToExternalList (Op, Path, ACPI_TYPE_REGION, 0, 0);
+ Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ACPI_TYPE_REGION,
+ ACPI_IMODE_LOAD_PASS1, ACPI_NS_SEARCH_PARENT, WalkState, Node);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ /* Must create and install a region object for the new node */
+
+ ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_REGION);
+ if (!ObjDesc)
+ {
+ return (AE_NO_MEMORY);
+ }
+
+ ObjDesc->Region.Node = *Node;
+ Status = AcpiNsAttachObject (*Node, ObjDesc, ACPI_TYPE_REGION);
+ return (Status);
+}
+#endif
+
+
+/*******************************************************************************
+ *
* FUNCTION: AcpiDsCreateBufferField
*
* PARAMETERS: Op - Current parse op (CreateXXField)
* WalkState - Current state
*
@@ -75,12 +150,12 @@
*
* DESCRIPTION: Execute the CreateField operators:
* CreateBitFieldOp,
* CreateByteFieldOp,
* CreateWordFieldOp,
- * CreateDWordFieldOp,
- * CreateQWordFieldOp,
+ * CreateDwordFieldOp,
+ * CreateQwordFieldOp,
* CreateFieldOp (all of which define a field in a buffer)
*
******************************************************************************/
ACPI_STATUS
@@ -241,10 +316,11 @@
ACPI_WALK_STATE *WalkState,
ACPI_PARSE_OBJECT *Arg)
{
ACPI_STATUS Status;
UINT64 Position;
+ ACPI_PARSE_OBJECT *Child;
ACPI_FUNCTION_TRACE_PTR (DsGetFieldNames, Info);
@@ -255,14 +331,15 @@
/* Process all elements in the field list (of parse nodes) */
while (Arg)
{
/*
- * Three types of field elements are handled:
- * 1) Offset - specifies a bit offset
- * 2) AccessAs - changes the access mode
- * 3) Name - Enters a new named field into the namespace
+ * Four types of field elements are handled:
+ * 1) Name - Enters a new named field into the namespace
+ * 2) Offset - specifies a bit offset
+ * 3) AccessAs - changes the access mode/attributes
+ * 4) Connection - Associate a resource template with the field
*/
switch (Arg->Common.AmlOpcode)
{
case AML_INT_RESERVEDFIELD_OP:
@@ -277,29 +354,72 @@
}
Info->FieldBitPosition = (UINT32) Position;
break;
-
case AML_INT_ACCESSFIELD_OP:
-
+ case AML_INT_EXTACCESSFIELD_OP:
/*
- * Get a new AccessType and AccessAttribute -- to be used for all
- * field units that follow, until field end or another AccessAs
- * keyword.
+ * Get new AccessType, AccessAttribute, and AccessLength fields
+ * -- to be used for all field units that follow, until the
+ * end-of-field or another AccessAs keyword is encountered.
+ * NOTE. These three bytes are encoded in the integer value
+ * of the parseop for convenience.
*
* In FieldFlags, preserve the flag bits other than the
- * ACCESS_TYPE bits
+ * ACCESS_TYPE bits.
*/
+
+ /* AccessType (ByteAcc, WordAcc, etc.) */
+
Info->FieldFlags = (UINT8)
((Info->FieldFlags & ~(AML_FIELD_ACCESS_TYPE_MASK)) |
- ((UINT8) ((UINT32) Arg->Common.Value.Integer >> 8)));
+ ((UINT8) ((UINT32) (Arg->Common.Value.Integer & 0x07))));
- Info->Attribute = (UINT8) (Arg->Common.Value.Integer);
+ /* AccessAttribute (AttribQuick, AttribByte, etc.) */
+
+ Info->Attribute = (UINT8) ((Arg->Common.Value.Integer >> 8) & 0xFF);
+
+ /* AccessLength (for serial/buffer protocols) */
+
+ Info->AccessLength = (UINT8) ((Arg->Common.Value.Integer >> 16) & 0xFF);
break;
+ case AML_INT_CONNECTION_OP:
+ /*
+ * Clear any previous connection. New connection is used for all
+ * fields that follow, similar to AccessAs
+ */
+ Info->ResourceBuffer = NULL;
+ Info->ConnectionNode = NULL;
+ /*
+ * A Connection() is either an actual resource descriptor (buffer)
+ * or a named reference to a resource template
+ */
+ Child = Arg->Common.Value.Arg;
+ if (Child->Common.AmlOpcode == AML_INT_BYTELIST_OP)
+ {
+ Info->ResourceBuffer = Child->Named.Data;
+ Info->ResourceLength = (UINT16) Child->Named.Value.Integer;
+ }
+ else
+ {
+ /* Lookup the Connection() namepath, it should already exist */
+
+ Status = AcpiNsLookup (WalkState->ScopeInfo,
+ Child->Common.Value.Name, ACPI_TYPE_ANY,
+ ACPI_IMODE_EXECUTE, ACPI_NS_DONT_OPEN_SCOPE,
+ WalkState, &Info->ConnectionNode);
+ if (ACPI_FAILURE (Status))
+ {
+ ACPI_ERROR_NAMESPACE (Child->Common.Value.Name, Status);
+ return_ACPI_STATUS (Status);
+ }
+ }
+ break;
+
case AML_INT_NAMEDFIELD_OP:
/* Lookup the name, it should already exist */
Status = AcpiNsLookup (WalkState->ScopeInfo,
@@ -346,11 +466,10 @@
}
Info->FieldBitPosition += Info->FieldBitLength;
break;
-
default:
ACPI_ERROR ((AE_INFO,
"Invalid opcode in field list: 0x%X", Arg->Common.AmlOpcode));
return_ACPI_STATUS (AE_AML_BAD_OPCODE);
@@ -392,22 +511,29 @@
/* First arg is the name of the parent OpRegion (must already exist) */
Arg = Op->Common.Value.Arg;
+
if (!RegionNode)
{
Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Common.Value.Name,
ACPI_TYPE_REGION, ACPI_IMODE_EXECUTE,
ACPI_NS_SEARCH_PARENT, WalkState, &RegionNode);
+#ifdef ACPI_ASL_COMPILER
+ Status = AcpiDsCreateExternalRegion (Status, Arg,
+ Arg->Common.Value.Name, WalkState, &RegionNode);
+#endif
if (ACPI_FAILURE (Status))
{
ACPI_ERROR_NAMESPACE (Arg->Common.Value.Name, Status);
return_ACPI_STATUS (Status);
}
}
+ ACPI_MEMSET (&Info, 0, sizeof (ACPI_CREATE_FIELD_INFO));
+
/* Second arg is the field flags */
Arg = Arg->Common.Next;
Info.FieldFlags = (UINT8) Arg->Common.Value.Integer;
Info.Attribute = 0;
@@ -416,11 +542,10 @@
Info.FieldType = ACPI_TYPE_LOCAL_REGION_FIELD;
Info.RegionNode = RegionNode;
Status = AcpiDsGetFieldNames (&Info, WalkState, Arg->Common.Next);
-
return_ACPI_STATUS (Status);
}
/*******************************************************************************
@@ -472,25 +597,29 @@
* list of field elements.
*/
switch (WalkState->Opcode)
{
case AML_FIELD_OP:
+
Arg = AcpiPsGetArg (Op, 2);
Type = ACPI_TYPE_LOCAL_REGION_FIELD;
break;
case AML_BANK_FIELD_OP:
+
Arg = AcpiPsGetArg (Op, 4);
Type = ACPI_TYPE_LOCAL_BANK_FIELD;
break;
case AML_INDEX_FIELD_OP:
+
Arg = AcpiPsGetArg (Op, 3);
Type = ACPI_TYPE_LOCAL_INDEX_FIELD;
break;
default:
+
return_ACPI_STATUS (AE_BAD_PARAMETER);
}
/* Creating new namespace node(s), should not already exist */
@@ -512,12 +641,12 @@
* Note: FieldList can be of zero length. In this case, Arg will be NULL.
*/
while (Arg)
{
/*
- * Ignore OFFSET and ACCESSAS terms here; we are only interested in the
- * field names in order to enter them into the namespace.
+ * Ignore OFFSET/ACCESSAS/CONNECTION terms here; we are only interested
+ * in the field names in order to enter them into the namespace.
*/
if (Arg->Common.AmlOpcode == AML_INT_NAMEDFIELD_OP)
{
Status = AcpiNsLookup (WalkState->ScopeInfo,
(char *) &Arg->Named.Name, Type, ACPI_IMODE_LOAD_PASS1,
@@ -581,10 +710,14 @@
if (!RegionNode)
{
Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Common.Value.Name,
ACPI_TYPE_REGION, ACPI_IMODE_EXECUTE,
ACPI_NS_SEARCH_PARENT, WalkState, &RegionNode);
+#ifdef ACPI_ASL_COMPILER
+ Status = AcpiDsCreateExternalRegion (Status, Arg,
+ Arg->Common.Value.Name, WalkState, &RegionNode);
+#endif
if (ACPI_FAILURE (Status))
{
ACPI_ERROR_NAMESPACE (Arg->Common.Value.Name, Status);
return_ACPI_STATUS (Status);
}
@@ -695,10 +828,7 @@
Info.FieldType = ACPI_TYPE_LOCAL_INDEX_FIELD;
Info.RegionNode = RegionNode;
Status = AcpiDsGetFieldNames (&Info, WalkState, Arg->Common.Next);
-
return_ACPI_STATUS (Status);
}
-
-