summaryrefslogtreecommitdiffstats
path: root/sys/contrib
diff options
context:
space:
mode:
authormsmith <msmith@FreeBSD.org>2001-05-29 19:56:18 +0000
committermsmith <msmith@FreeBSD.org>2001-05-29 19:56:18 +0000
commitadc622bc2d7f44144b00414f40341c94f96be143 (patch)
tree9b3c03c9374939fdaa96ac0078b3c6b59a1f00c5 /sys/contrib
parentaa7ec52010ab8c57de054cdb411a36092f3378ee (diff)
downloadFreeBSD-src-adc622bc2d7f44144b00414f40341c94f96be143.zip
FreeBSD-src-adc622bc2d7f44144b00414f40341c94f96be143.tar.gz
Merge FreeBSD-specific changes with the ACPI CA 20010518 release.
Diffstat (limited to 'sys/contrib')
-rw-r--r--sys/contrib/dev/acpica/acconfig.h11
-rw-r--r--sys/contrib/dev/acpica/acfreebsd.h29
-rw-r--r--sys/contrib/dev/acpica/acgcc.h3
-rw-r--r--sys/contrib/dev/acpica/acpixf.h46
-rw-r--r--sys/contrib/dev/acpica/exfldio.c1064
-rw-r--r--sys/contrib/dev/acpica/psparse.c137
6 files changed, 756 insertions, 534 deletions
diff --git a/sys/contrib/dev/acpica/acconfig.h b/sys/contrib/dev/acpica/acconfig.h
index 0721500..4a1e275 100644
--- a/sys/contrib/dev/acpica/acconfig.h
+++ b/sys/contrib/dev/acpica/acconfig.h
@@ -1,7 +1,7 @@
/******************************************************************************
*
* Name: acconfig.h - Global configuration constants
- * $Revision: 55 $
+ * $Revision: 64 $
*
*****************************************************************************/
@@ -144,7 +144,7 @@
/* Version string */
-#define ACPI_CA_VERSION 0x20010208
+#define ACPI_CA_VERSION 0x20010518
/* Maximum objects in the various object caches */
@@ -180,7 +180,7 @@
/*
* Debugger threading model
* Use single threaded if the entire subsystem is contained in an application
- * Use multiple threaded when the the subsystem is running in the kernel.
+ * Use multiple threaded when the subsystem is running in the kernel.
*
* By default the model is single threaded if ACPI_APPLICATION is set,
* multi-threaded if ACPI_APPLICATION is not set.
@@ -240,6 +240,11 @@
#define HI_RSDP_WINDOW_SIZE 0x20000
#define RSDP_SCAN_STEP 16
+/* Maximum SpaceIds for Operation Regions */
+
+#define ACPI_MAX_ADDRESS_SPACE 255
+#define ACPI_NUM_ADDRESS_SPACES 256
+
#endif /* _ACCONFIG_H */
diff --git a/sys/contrib/dev/acpica/acfreebsd.h b/sys/contrib/dev/acpica/acfreebsd.h
index 2d42e83..d8ad905 100644
--- a/sys/contrib/dev/acpica/acfreebsd.h
+++ b/sys/contrib/dev/acpica/acfreebsd.h
@@ -1,7 +1,7 @@
/******************************************************************************
*
* Name: acfreebsd.h - OS specific defines, etc.
- * $Revision: 4 $
+ * $Revision: 6 $
*
*****************************************************************************/
@@ -128,7 +128,7 @@
#include "acgcc.h"
#ifdef _KERNEL
-#include "opt_acpi.h" /* collect build-time options here */
+#include "opt_acpi.h"
#include <sys/ctype.h>
#include <sys/param.h>
@@ -144,7 +144,7 @@
#ifdef DEBUGGER_THREADING
#undef DEBUGGER_THREADING
#endif /* DEBUGGER_THREADING */
-#define DEBUGGER_THREADING 0 /* integrated with DDB */
+#define DEBUGGER_THREADING 0 /* integrated with DDB */
#include "opt_ddb.h"
#ifdef DDB
#define ENABLE_DEBUGGER
@@ -156,6 +156,9 @@
/* Not building kernel code, so use libc */
#define ACPI_USE_STANDARD_HEADERS
+#define __cli()
+#define __sti()
+
#endif /* _KERNEL */
/* Always use FreeBSD code over our local versions */
@@ -167,8 +170,8 @@ strupr(char *str)
{
char *c = str;
while(*c) {
- *c = toupper(*c);
- c++;
+ *c = toupper(*c);
+ c++;
}
return(str);
}
@@ -182,14 +185,14 @@ strstr(char *s, char *find)
size_t len;
if ((c = *find++) != 0) {
- len = strlen(find);
- do {
- do {
- if ((sc = *s++) == 0)
- return (NULL);
- } while (sc != c);
- } while (strncmp(s, find, len) != 0);
- s--;
+ len = strlen(find);
+ do {
+ do {
+ if ((sc = *s++) == 0)
+ return (NULL);
+ } while (sc != c);
+ } while (strncmp(s, find, len) != 0);
+ s--;
}
return ((char *)s);
}
diff --git a/sys/contrib/dev/acpica/acgcc.h b/sys/contrib/dev/acpica/acgcc.h
index e486315..435277d 100644
--- a/sys/contrib/dev/acpica/acgcc.h
+++ b/sys/contrib/dev/acpica/acgcc.h
@@ -1,7 +1,7 @@
/******************************************************************************
*
* Name: acgcc.h - GCC specific defines, etc.
- * $Revision: 5 $
+ * $Revision: 6 $
*
*****************************************************************************/
@@ -118,7 +118,6 @@
#define __ACGCC_H__
-
#ifdef __ia64__
#define _IA64
diff --git a/sys/contrib/dev/acpica/acpixf.h b/sys/contrib/dev/acpica/acpixf.h
index 5dd9c30..e314c5b 100644
--- a/sys/contrib/dev/acpica/acpixf.h
+++ b/sys/contrib/dev/acpica/acpixf.h
@@ -121,6 +121,7 @@
#include "actypes.h"
#include "actbl.h"
+
/*
* Global interfaces
*/
@@ -156,6 +157,23 @@ AcpiFormatException (
/*
+ * ACPI Memory manager
+ */
+
+void *
+AcpiAllocate (
+ UINT32 Size);
+
+void *
+AcpiCallocate (
+ UINT32 Size);
+
+void
+AcpiFree (
+ void *Address);
+
+
+/*
* ACPI table manipulation interfaces
*/
@@ -197,14 +215,14 @@ AcpiWalkNamespace (
ACPI_OBJECT_TYPE Type,
ACPI_HANDLE StartObject,
UINT32 MaxDepth,
- WALK_CALLBACK UserFunction,
+ ACPI_WALK_CALLBACK UserFunction,
void *Context,
void * *ReturnValue);
ACPI_STATUS
AcpiGetDevices (
NATIVE_CHAR *HID,
- WALK_CALLBACK UserFunction,
+ ACPI_WALK_CALLBACK UserFunction,
void *Context,
void **ReturnValue);
@@ -256,52 +274,52 @@ AcpiGetParent (
/*
- * AcpiEvent handler interfaces
+ * Event handler interfaces
*/
ACPI_STATUS
AcpiInstallFixedEventHandler (
UINT32 AcpiEvent,
- FIXED_EVENT_HANDLER Handler,
+ ACPI_EVENT_HANDLER Handler,
void *Context);
ACPI_STATUS
AcpiRemoveFixedEventHandler (
UINT32 AcpiEvent,
- FIXED_EVENT_HANDLER Handler);
+ ACPI_EVENT_HANDLER Handler);
ACPI_STATUS
AcpiInstallNotifyHandler (
ACPI_HANDLE Device,
UINT32 HandlerType,
- NOTIFY_HANDLER Handler,
+ ACPI_NOTIFY_HANDLER Handler,
void *Context);
ACPI_STATUS
AcpiRemoveNotifyHandler (
ACPI_HANDLE Device,
UINT32 HandlerType,
- NOTIFY_HANDLER Handler);
+ ACPI_NOTIFY_HANDLER Handler);
ACPI_STATUS
AcpiInstallAddressSpaceHandler (
ACPI_HANDLE Device,
- ACPI_ADDRESS_SPACE_TYPE SpaceId,
- ADDRESS_SPACE_HANDLER Handler,
- ADDRESS_SPACE_SETUP Setup,
+ ACPI_ADR_SPACE_TYPE SpaceId,
+ ACPI_ADR_SPACE_HANDLER Handler,
+ ACPI_ADR_SPACE_SETUP Setup,
void *Context);
ACPI_STATUS
AcpiRemoveAddressSpaceHandler (
ACPI_HANDLE Device,
- ACPI_ADDRESS_SPACE_TYPE SpaceId,
- ADDRESS_SPACE_HANDLER Handler);
+ ACPI_ADR_SPACE_TYPE SpaceId,
+ ACPI_ADR_SPACE_HANDLER Handler);
ACPI_STATUS
AcpiInstallGpeHandler (
UINT32 GpeNumber,
UINT32 Type,
- GPE_HANDLER Handler,
+ ACPI_GPE_HANDLER Handler,
void *Context);
ACPI_STATUS
@@ -315,7 +333,7 @@ AcpiReleaseGlobalLock (
ACPI_STATUS
AcpiRemoveGpeHandler (
UINT32 GpeNumber,
- GPE_HANDLER Handler);
+ ACPI_GPE_HANDLER Handler);
ACPI_STATUS
AcpiEnableEvent (
diff --git a/sys/contrib/dev/acpica/exfldio.c b/sys/contrib/dev/acpica/exfldio.c
index 24c9a2a..96f3227 100644
--- a/sys/contrib/dev/acpica/exfldio.c
+++ b/sys/contrib/dev/acpica/exfldio.c
@@ -1,7 +1,7 @@
/******************************************************************************
*
- * Module Name: amfldio - Aml Field I/O
- * $Revision: 39 $
+ * Module Name: exfldio - Aml Field I/O
+ * $Revision: 57 $
*
*****************************************************************************/
@@ -115,7 +115,7 @@
*****************************************************************************/
-#define __AMFLDIO_C__
+#define __EXFLDIO_C__
#include "acpi.h"
#include "acinterp.h"
@@ -123,116 +123,324 @@
#include "acnamesp.h"
#include "achware.h"
#include "acevents.h"
+#include "acdispat.h"
-#define _COMPONENT INTERPRETER
- MODULE_NAME ("amfldio")
+#define _COMPONENT ACPI_EXECUTER
+ MODULE_NAME ("exfldio")
/*******************************************************************************
*
- * FUNCTION: AcpiAmlReadFieldData
+ * FUNCTION: AcpiExSetupField
*
- * PARAMETERS: *ObjDesc - Field to be read
- * *Value - Where to store value
- * FieldBitWidth - Field Width in bits (8, 16, or 32)
+ * PARAMETERS: *ObjDesc - Field to be read or written
+ * FieldDatumByteOffset - Current offset into the field
*
* RETURN: Status
*
- * DESCRIPTION: Retrieve the value of the given field
+ * DESCRIPTION: Common processing for AcpiExExtractFromField and
+ * AcpiExInsertIntoField
*
******************************************************************************/
ACPI_STATUS
-AcpiAmlReadFieldData (
+AcpiExSetupField (
ACPI_OPERAND_OBJECT *ObjDesc,
- UINT32 FieldByteOffset,
- UINT32 FieldBitWidth,
- UINT32 *Value)
+ UINT32 FieldDatumByteOffset)
{
- ACPI_STATUS Status;
- ACPI_OPERAND_OBJECT *RgnDesc = NULL;
- ACPI_PHYSICAL_ADDRESS Address;
- UINT32 LocalValue = 0;
- UINT32 FieldByteWidth;
+ ACPI_STATUS Status = AE_OK;
+ ACPI_OPERAND_OBJECT *RgnDesc;
- FUNCTION_TRACE ("AmlReadFieldData");
+ FUNCTION_TRACE ("ExSetupField");
- /* ObjDesc is validated by callers */
+ /* Parameter validation */
- if (ObjDesc)
+ RgnDesc = ObjDesc->CommonField.RegionObj;
+ if (!ObjDesc || !RgnDesc)
{
- RgnDesc = ObjDesc->Field.Container;
+ DEBUG_PRINTP (ACPI_ERROR, ("Internal error - null handle\n"));
+ return_ACPI_STATUS (AE_AML_NO_OPERAND);
}
+ if (ACPI_TYPE_REGION != RgnDesc->Common.Type)
+ {
+ DEBUG_PRINTP (ACPI_ERROR, ("Needed Region, found type %x %s\n",
+ RgnDesc->Common.Type, AcpiUtGetTypeName (RgnDesc->Common.Type)));
+ return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
+ }
- FieldByteWidth = DIV_8 (FieldBitWidth);
- Status = AcpiAmlSetupField (ObjDesc, RgnDesc, FieldBitWidth);
- if (ACPI_FAILURE (Status))
+
+ /*
+ * If the Region Address and Length have not been previously evaluated,
+ * evaluate them now and save the results.
+ */
+ if (!(RgnDesc->Region.Flags & AOPOBJ_DATA_VALID))
{
- return_ACPI_STATUS (Status);
+
+ Status = AcpiDsGetRegionArguments (RgnDesc);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
}
- /* SetupField validated RgnDesc and FieldBitWidth */
+
+ /*
+ * Validate the request. The entire request from the byte offset for a
+ * length of one field datum (access width) must fit within the region.
+ * (Region length is specified in bytes)
+ */
+ if (RgnDesc->Region.Length < (ObjDesc->CommonField.BaseByteOffset +
+ FieldDatumByteOffset +
+ ObjDesc->CommonField.AccessByteWidth))
+ {
+ if (RgnDesc->Region.Length < ObjDesc->CommonField.AccessByteWidth)
+ {
+ /*
+ * This is the case where the AccessType (AccWord, etc.) is wider
+ * than the region itself. For example, a region of length one
+ * byte, and a field with Dword access specified.
+ */
+ DEBUG_PRINTP (ACPI_ERROR,
+ ("Field access width (%d bytes) too large for region size (%X)\n",
+ ObjDesc->CommonField.AccessByteWidth, RgnDesc->Region.Length));
+ }
+
+ /*
+ * Offset rounded up to next multiple of field width
+ * exceeds region length, indicate an error
+ */
+ DEBUG_PRINTP (ACPI_ERROR,
+ ("Field base+offset+width %X+%X+%X exceeds region size (%X bytes) field=%p region=%p\n",
+ ObjDesc->CommonField.BaseByteOffset, FieldDatumByteOffset,
+ ObjDesc->CommonField.AccessByteWidth,
+ RgnDesc->Region.Length, ObjDesc, RgnDesc));
+
+ return_ACPI_STATUS (AE_AML_REGION_LIMIT);
+ }
+
+ return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiExReadFieldDatum
+ *
+ * PARAMETERS: *ObjDesc - Field to be read
+ * *Value - Where to store value (must be 32 bits)
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Retrieve the value of the given field
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiExReadFieldDatum (
+ ACPI_OPERAND_OBJECT *ObjDesc,
+ UINT32 FieldDatumByteOffset,
+ UINT32 *Value)
+{
+ ACPI_STATUS Status;
+ ACPI_OPERAND_OBJECT *RgnDesc;
+ ACPI_PHYSICAL_ADDRESS Address;
+ UINT32 LocalValue;
+
+
+ FUNCTION_TRACE_U32 ("ExReadFieldDatum", FieldDatumByteOffset);
+
if (!Value)
{
+ LocalValue = 0;
Value = &LocalValue; /* support reads without saving value */
}
+ /* Clear the entire return buffer first, [Very Important!] */
+
+ *Value = 0;
+
/*
- * Set offset to next multiple of field width,
- * add region base address and offset within the field
+ * BufferFields - Read from a Buffer
+ * Other Fields - Read from a Operation Region.
*/
- Address = RgnDesc->Region.Address +
- (ObjDesc->Field.Offset * FieldByteWidth) +
- FieldByteOffset;
+ switch (ObjDesc->Common.Type)
+ {
+ case ACPI_TYPE_BUFFER_FIELD:
+
+ /*
+ * For BufferFields, we only need to copy the data from the
+ * source buffer. Length is the field width in bytes.
+ */
+ MEMCPY (Value, (ObjDesc->BufferField.BufferObj)->Buffer.Pointer
+ + ObjDesc->BufferField.BaseByteOffset + FieldDatumByteOffset,
+ ObjDesc->CommonField.AccessByteWidth);
+ Status = AE_OK;
+ break;
+
+
+ case INTERNAL_TYPE_REGION_FIELD:
+ case INTERNAL_TYPE_BANK_FIELD:
- DEBUG_PRINT (TRACE_OPREGION,
- ("AmlReadFieldData: Region %s(%X) at %08lx width %X\n",
- AcpiCmGetRegionName (RgnDesc->Region.SpaceId),
- RgnDesc->Region.SpaceId, Address,
- FieldBitWidth));
+ /*
+ * For other fields, we need to go through an Operation Region
+ * (Only types that will get here are RegionFields and BankFields)
+ */
+ Status = AcpiExSetupField (ObjDesc, FieldDatumByteOffset);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
- /* Invoke the appropriate AddressSpace/OpRegion handler */
+ /*
+ * The physical address of this field datum is:
+ *
+ * 1) The base of the region, plus
+ * 2) The base offset of the field, plus
+ * 3) The current offset into the field
+ */
+ RgnDesc = ObjDesc->CommonField.RegionObj;
+ Address = RgnDesc->Region.Address + ObjDesc->CommonField.BaseByteOffset +
+ FieldDatumByteOffset;
- Status = AcpiEvAddressSpaceDispatch (RgnDesc, ADDRESS_SPACE_READ,
- Address, FieldBitWidth, Value);
+ DEBUG_PRINTP (TRACE_BFIELD, ("Region %s(%X) width %X base:off %X:%X at %08lX\n",
+ AcpiUtGetRegionName (RgnDesc->Region.SpaceId),
+ RgnDesc->Region.SpaceId, ObjDesc->CommonField.AccessBitWidth,
+ ObjDesc->CommonField.BaseByteOffset, FieldDatumByteOffset,
+ Address));
- if (Status == AE_NOT_IMPLEMENTED)
- {
- DEBUG_PRINT (ACPI_ERROR,
- ("AmlReadFieldData: **** Region %s(%X) not implemented\n",
- AcpiCmGetRegionName (RgnDesc->Region.SpaceId),
- RgnDesc->Region.SpaceId));
+
+ /* Invoke the appropriate AddressSpace/OpRegion handler */
+
+ Status = AcpiEvAddressSpaceDispatch (RgnDesc, ACPI_READ_ADR_SPACE,
+ Address, ObjDesc->CommonField.AccessBitWidth, Value);
+ if (Status == AE_NOT_IMPLEMENTED)
+ {
+ DEBUG_PRINTP (ACPI_ERROR, ("Region %s(%X) not implemented\n",
+ AcpiUtGetRegionName (RgnDesc->Region.SpaceId),
+ RgnDesc->Region.SpaceId));
+ }
+
+ else if (Status == AE_NOT_EXIST)
+ {
+ DEBUG_PRINTP (ACPI_ERROR, ("Region %s(%X) has no handler\n",
+ AcpiUtGetRegionName (RgnDesc->Region.SpaceId),
+ RgnDesc->Region.SpaceId));
+ }
+ break;
+
+
+ default:
+
+ DEBUG_PRINTP (ACPI_ERROR, ("%p, wrong source type - %s\n",
+ ObjDesc, AcpiUtGetTypeName (ObjDesc->Common.Type)));
+ Status = AE_AML_INTERNAL;
+ break;
}
- else if (Status == AE_NOT_EXIST)
+
+ DEBUG_PRINTP (TRACE_BFIELD, ("Returned value=%08lX \n", *Value));
+
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiExGetBufferDatum
+ *
+ * PARAMETERS: MergedDatum - Value to store
+ * Buffer - Receiving buffer
+ * ByteGranularity - 1/2/4 Granularity of the field
+ * (aka Datum Size)
+ * Offset - Datum offset into the buffer
+ *
+ * RETURN: none
+ *
+ * DESCRIPTION: Store the merged datum to the buffer according to the
+ * byte granularity
+ *
+ ******************************************************************************/
+
+static void
+AcpiExGetBufferDatum(
+ UINT32 *Datum,
+ void *Buffer,
+ UINT32 ByteGranularity,
+ UINT32 Offset)
+{
+
+ switch (ByteGranularity)
{
- DEBUG_PRINT (ACPI_ERROR,
- ("AmlReadFieldData: **** Region %s(%X) has no handler\n",
- AcpiCmGetRegionName (RgnDesc->Region.SpaceId),
- RgnDesc->Region.SpaceId));
+ case ACPI_FIELD_BYTE_GRANULARITY:
+ *Datum = ((UINT8 *) Buffer) [Offset];
+ break;
+
+ case ACPI_FIELD_WORD_GRANULARITY:
+ MOVE_UNALIGNED16_TO_32 (Datum, &(((UINT16 *) Buffer) [Offset]));
+ break;
+
+ case ACPI_FIELD_DWORD_GRANULARITY:
+ MOVE_UNALIGNED32_TO_32 (Datum, &(((UINT32 *) Buffer) [Offset]));
+ break;
}
+}
- DEBUG_PRINT (TRACE_OPREGION,
- ("AmlReadField: Returned value=%08lx \n", *Value));
- return_ACPI_STATUS (Status);
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiExSetBufferDatum
+ *
+ * PARAMETERS: MergedDatum - Value to store
+ * Buffer - Receiving buffer
+ * ByteGranularity - 1/2/4 Granularity of the field
+ * (aka Datum Size)
+ * Offset - Datum offset into the buffer
+ *
+ * RETURN: none
+ *
+ * DESCRIPTION: Store the merged datum to the buffer according to the
+ * byte granularity
+ *
+ ******************************************************************************/
+
+static void
+AcpiExSetBufferDatum (
+ UINT32 MergedDatum,
+ void *Buffer,
+ UINT32 ByteGranularity,
+ UINT32 Offset)
+{
+
+ switch (ByteGranularity)
+ {
+ case ACPI_FIELD_BYTE_GRANULARITY:
+ ((UINT8 *) Buffer) [Offset] = (UINT8) MergedDatum;
+ break;
+
+ case ACPI_FIELD_WORD_GRANULARITY:
+ MOVE_UNALIGNED16_TO_16 (&(((UINT16 *) Buffer)[Offset]), &MergedDatum);
+ break;
+
+ case ACPI_FIELD_DWORD_GRANULARITY:
+ MOVE_UNALIGNED32_TO_32 (&(((UINT32 *) Buffer)[Offset]), &MergedDatum);
+ break;
+ }
}
/*******************************************************************************
*
- * FUNCTION: AcpiAmlReadField
+ * FUNCTION: AcpiExExtractFromField
*
* PARAMETERS: *ObjDesc - Field to be read
* *Value - Where to store value
- * FieldBitWidth - Field Width in bits (8, 16, or 32)
*
* RETURN: Status
*
@@ -241,218 +449,186 @@ AcpiAmlReadFieldData (
******************************************************************************/
ACPI_STATUS
-AcpiAmlReadField (
+AcpiExExtractFromField (
ACPI_OPERAND_OBJECT *ObjDesc,
void *Buffer,
- UINT32 BufferLength,
- UINT32 ByteLength,
- UINT32 DatumLength,
- UINT32 BitGranularity,
- UINT32 ByteGranularity)
+ UINT32 BufferLength)
{
ACPI_STATUS Status;
- UINT32 ThisFieldByteOffset;
- UINT32 ThisFieldDatumOffset;
+ UINT32 FieldDatumByteOffset;
+ UINT32 DatumOffset;
UINT32 PreviousRawDatum;
UINT32 ThisRawDatum = 0;
- UINT32 ValidFieldBits;
- UINT32 Mask;
UINT32 MergedDatum = 0;
+ UINT32 ByteFieldLength;
+ UINT32 DatumCount;
+
+ FUNCTION_TRACE ("ExExtractFromField");
+
+
+ /*
+ * The field must fit within the caller's buffer
+ */
+ ByteFieldLength = ROUND_BITS_UP_TO_BYTES (ObjDesc->CommonField.BitLength);
+ if (ByteFieldLength > BufferLength)
+ {
+ DEBUG_PRINTP (ACPI_INFO, ("Field size %X (bytes) too large for buffer (%X)\n",
+ ByteFieldLength, BufferLength));
+
+ return_ACPI_STATUS (AE_BUFFER_OVERFLOW);
+ }
+
+ /* Convert field byte count to datum count, round up if necessary */
+
+ DatumCount = ROUND_UP_TO (ByteFieldLength, ObjDesc->CommonField.AccessByteWidth);
+
+ DEBUG_PRINT (ACPI_INFO,
+ ("ByteLen=%x, DatumLen=%x, BitGran=%x, ByteGran=%x\n",
+ ByteFieldLength, DatumCount, ObjDesc->CommonField.AccessBitWidth,
+ ObjDesc->CommonField.AccessByteWidth));
- FUNCTION_TRACE ("AmlReadField");
/*
* Clear the caller's buffer (the whole buffer length as given)
* This is very important, especially in the cases where a byte is read,
* but the buffer is really a UINT32 (4 bytes).
*/
-
MEMSET (Buffer, 0, BufferLength);
/* Read the first raw datum to prime the loop */
- ThisFieldByteOffset = 0;
- ThisFieldDatumOffset= 0;
+ FieldDatumByteOffset = 0;
+ DatumOffset= 0;
- Status = AcpiAmlReadFieldData (ObjDesc, ThisFieldByteOffset, BitGranularity,
- &PreviousRawDatum);
+ Status = AcpiExReadFieldDatum (ObjDesc, FieldDatumByteOffset, &PreviousRawDatum);
if (ACPI_FAILURE (Status))
{
- goto Cleanup;
+ return_ACPI_STATUS (Status);
}
+
/* We might actually be done if the request fits in one datum */
- if ((DatumLength == 1) &&
- ((ObjDesc->Field.BitOffset + ObjDesc->FieldUnit.Length) <=
- (UINT16) BitGranularity))
+ if ((DatumCount == 1) &&
+ (ObjDesc->CommonField.AccessFlags & AFIELD_SINGLE_DATUM))
{
- MergedDatum = PreviousRawDatum;
+ /* 1) Shift the valid data bits down to start at bit 0 */
+
+ MergedDatum = (PreviousRawDatum >> ObjDesc->CommonField.StartFieldBitOffset);
- MergedDatum = (MergedDatum >> ObjDesc->Field.BitOffset);
+ /* 2) Mask off any upper unused bits (bits not part of the field) */
- ValidFieldBits = ObjDesc->FieldUnit.Length % BitGranularity;
- if (ValidFieldBits)
+ if (ObjDesc->CommonField.EndBufferValidBits)
{
- Mask = (((UINT32) 1 << ValidFieldBits) - (UINT32) 1);
- MergedDatum &= Mask;
+ MergedDatum &= MASK_BITS_ABOVE (ObjDesc->CommonField.EndBufferValidBits);
}
+ /* Store the datum to the caller buffer */
- /*
- * Place the MergedDatum into the proper format and return buffer
- * field
- */
-
- switch (ByteGranularity)
- {
- case 1:
- ((UINT8 *) Buffer) [ThisFieldDatumOffset] = (UINT8) MergedDatum;
- break;
+ AcpiExSetBufferDatum (MergedDatum, Buffer, ObjDesc->CommonField.AccessByteWidth,
+ DatumOffset);
- case 2:
- MOVE_UNALIGNED16_TO_16 (&(((UINT16 *) Buffer)[ThisFieldDatumOffset]), &MergedDatum);
- break;
+ return_ACPI_STATUS (AE_OK);
+ }
- case 4:
- MOVE_UNALIGNED32_TO_32 (&(((UINT32 *) Buffer)[ThisFieldDatumOffset]), &MergedDatum);
- break;
- }
- ThisFieldByteOffset = 1;
- ThisFieldDatumOffset = 1;
- }
+ /* We need to get more raw data to complete one or more field data */
- else
+ while (DatumOffset < DatumCount)
{
- /* We need to get more raw data to complete one or more field data */
+ FieldDatumByteOffset += ObjDesc->CommonField.AccessByteWidth;
- while (ThisFieldDatumOffset < DatumLength)
+ /*
+ * If the field is aligned on a byte boundary, we don't want
+ * to perform a final read, since this would potentially read
+ * past the end of the region.
+ *
+ * TBD: [Investigate] It may make more sense to just split the aligned
+ * and non-aligned cases since the aligned case is so very simple,
+ */
+ if ((ObjDesc->CommonField.StartFieldBitOffset != 0) ||
+ ((ObjDesc->CommonField.StartFieldBitOffset == 0) &&
+ (DatumOffset < (DatumCount -1))))
{
/*
- * If the field is aligned on a byte boundary, we don't want
- * to perform a final read, since this would potentially read
- * past the end of the region.
- *
- * TBD: [Investigate] It may make more sense to just split the aligned
- * and non-aligned cases since the aligned case is so very simple,
+ * Get the next raw datum, it contains some or all bits
+ * of the current field datum
*/
- if ((ObjDesc->Field.BitOffset != 0) ||
- ((ObjDesc->Field.BitOffset == 0) &&
- (ThisFieldDatumOffset < (DatumLength -1))))
+ Status = AcpiExReadFieldDatum (ObjDesc, FieldDatumByteOffset, &ThisRawDatum);
+ if (ACPI_FAILURE (Status))
{
- /*
- * Get the next raw datum, it contains some or all bits
- * of the current field datum
- */
-
- Status = AcpiAmlReadFieldData (ObjDesc,
- ThisFieldByteOffset + ByteGranularity,
- BitGranularity, &ThisRawDatum);
- if (ACPI_FAILURE (Status))
- {
- goto Cleanup;
- }
-
- /* Before merging the data, make sure the unused bits are clear */
-
- switch (ByteGranularity)
- {
- case 1:
- ThisRawDatum &= 0x000000FF;
- PreviousRawDatum &= 0x000000FF;
- break;
-
- case 2:
- ThisRawDatum &= 0x0000FFFF;
- PreviousRawDatum &= 0x0000FFFF;
- break;
- }
+ return_ACPI_STATUS (Status);
}
+ }
+ /*
+ * Create the (possibly) merged datum to be stored to the caller buffer
+ */
+ if (ObjDesc->CommonField.StartFieldBitOffset == 0)
+ {
+ /* Field is not skewed and we can just copy the datum */
- /*
- * Put together bits of the two raw data to make a complete
- * field datum
- */
-
-
- if (ObjDesc->Field.BitOffset != 0)
- {
- MergedDatum =
- (PreviousRawDatum >> ObjDesc->Field.BitOffset) |
- (ThisRawDatum << (BitGranularity - ObjDesc->Field.BitOffset));
- }
-
- else
- {
- MergedDatum = PreviousRawDatum;
- }
+ MergedDatum = PreviousRawDatum;
+ }
+ else
+ {
/*
- * Prepare the merged datum for storing into the caller's
- * buffer. It is possible to have a 32-bit buffer
- * (ByteGranularity == 4), but a ObjDesc->Field.Length
- * of 8 or 16, meaning that the upper bytes of merged data
- * are undesired. This section fixes that.
+ * Put together the appropriate bits of the two raw data to make a
+ * single complete field datum
+ *
+ * 1) Normalize the first datum down to bit 0
*/
- switch (ObjDesc->Field.Length)
- {
- case 8:
- MergedDatum &= 0x000000FF;
- break;
+ MergedDatum = (PreviousRawDatum >> ObjDesc->CommonField.StartFieldBitOffset);
- case 16:
- MergedDatum &= 0x0000FFFF;
- break;
- }
+ /* 2) Insert the second datum "above" the first datum */
- /*
- * Now store the datum in the caller's buffer, according to
- * the data type
- */
- switch (ByteGranularity)
+ MergedDatum |= (ThisRawDatum << ObjDesc->CommonField.DatumValidBits);
+
+ if ((DatumOffset >= (DatumCount -1)))
{
- case 1:
- ((UINT8 *) Buffer) [ThisFieldDatumOffset] = (UINT8) MergedDatum;
- break;
-
- case 2:
- MOVE_UNALIGNED16_TO_16 (&(((UINT16 *) Buffer) [ThisFieldDatumOffset]), &MergedDatum);
- break;
-
- case 4:
- MOVE_UNALIGNED32_TO_32 (&(((UINT32 *) Buffer) [ThisFieldDatumOffset]), &MergedDatum);
- break;
+ /*
+ * This is the last iteration of the loop. We need to clear
+ * any unused bits (bits that are not part of this field) that
+ * came from the last raw datum before we store the final
+ * merged datum into the caller buffer.
+ */
+ if (ObjDesc->CommonField.EndBufferValidBits)
+ {
+ MergedDatum &=
+ MASK_BITS_ABOVE (ObjDesc->CommonField.EndBufferValidBits);
+ }
}
+ }
- /*
- * Save the most recent datum since it contains bits of
- * the *next* field datum
- */
-
- PreviousRawDatum = ThisRawDatum;
- ThisFieldByteOffset += ByteGranularity;
- ThisFieldDatumOffset++;
+ /*
+ * Store the merged field datum in the caller's buffer, according to
+ * the granularity of the field (size of each datum).
+ */
+ AcpiExSetBufferDatum (MergedDatum, Buffer, ObjDesc->CommonField.AccessByteWidth,
+ DatumOffset);
- } /* while */
+ /*
+ * Save the raw datum that was just acquired since it may contain bits
+ * of the *next* field datum. Update offsets
+ */
+ PreviousRawDatum = ThisRawDatum;
+ DatumOffset++;
}
-Cleanup:
- return_ACPI_STATUS (Status);
+ return_ACPI_STATUS (AE_OK);
}
/*******************************************************************************
*
- * FUNCTION: AcpiAmlWriteFieldData
+ * FUNCTION: AcpiExWriteFieldDatum
*
* PARAMETERS: *ObjDesc - Field to be set
* Value - Value to store
- * FieldBitWidth - Field Width in bits (8, 16, or 32)
*
* RETURN: Status
*
@@ -461,400 +637,418 @@ Cleanup:
******************************************************************************/
static ACPI_STATUS
-AcpiAmlWriteFieldData (
+AcpiExWriteFieldDatum (
ACPI_OPERAND_OBJECT *ObjDesc,
- UINT32 FieldByteOffset,
- UINT32 FieldBitWidth,
+ UINT32 FieldDatumByteOffset,
UINT32 Value)
{
ACPI_STATUS Status = AE_OK;
ACPI_OPERAND_OBJECT *RgnDesc = NULL;
ACPI_PHYSICAL_ADDRESS Address;
- UINT32 FieldByteWidth;
- FUNCTION_TRACE ("AmlWriteFieldData");
+ FUNCTION_TRACE_U32 ("ExWriteFieldDatum", FieldDatumByteOffset);
- /* ObjDesc is validated by callers */
- if (ObjDesc)
+ /*
+ * BufferFields - Read from a Buffer
+ * Other Fields - Read from a Operation Region.
+ */
+ switch (ObjDesc->Common.Type)
{
- RgnDesc = ObjDesc->Field.Container;
- }
+ case ACPI_TYPE_BUFFER_FIELD:
- FieldByteWidth = DIV_8 (FieldBitWidth);
- Status = AcpiAmlSetupField (ObjDesc, RgnDesc, FieldBitWidth);
- if (ACPI_FAILURE (Status))
- {
- return_ACPI_STATUS (Status);
- }
+ /*
+ * For BufferFields, we only need to copy the data to the
+ * target buffer. Length is the field width in bytes.
+ */
+ MEMCPY ((ObjDesc->BufferField.BufferObj)->Buffer.Pointer
+ + ObjDesc->BufferField.BaseByteOffset + FieldDatumByteOffset,
+ &Value, ObjDesc->CommonField.AccessByteWidth);
+ Status = AE_OK;
+ break;
- /*
- * Set offset to next multiple of field width,
- * add region base address and offset within the field
- */
- Address = RgnDesc->Region.Address +
- (ObjDesc->Field.Offset * FieldByteWidth) +
- FieldByteOffset;
+ case INTERNAL_TYPE_REGION_FIELD:
+ case INTERNAL_TYPE_BANK_FIELD:
- DEBUG_PRINT (TRACE_OPREGION,
- ("AmlWriteField: Store %lx in Region %s(%X) at %p width %X\n",
- Value, AcpiCmGetRegionName (RgnDesc->Region.SpaceId),
- RgnDesc->Region.SpaceId, Address,
- FieldBitWidth));
+ /*
+ * For other fields, we need to go through an Operation Region
+ * (Only types that will get here are RegionFields and BankFields)
+ */
+ Status = AcpiExSetupField (ObjDesc, FieldDatumByteOffset);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
- /* Invoke the appropriate AddressSpace/OpRegion handler */
+ /*
+ * The physical address of this field datum is:
+ *
+ * 1) The base of the region, plus
+ * 2) The base offset of the field, plus
+ * 3) The current offset into the field
+ */
+ RgnDesc = ObjDesc->CommonField.RegionObj;
+ Address = RgnDesc->Region.Address +
+ ObjDesc->CommonField.BaseByteOffset +
+ FieldDatumByteOffset;
- Status = AcpiEvAddressSpaceDispatch (RgnDesc, ADDRESS_SPACE_WRITE,
- Address, FieldBitWidth, &Value);
+ DEBUG_PRINTP (TRACE_BFIELD,
+ ("Store %X in Region %s(%X) at %p width %X\n",
+ Value, AcpiUtGetRegionName (RgnDesc->Region.SpaceId),
+ RgnDesc->Region.SpaceId, Address, ObjDesc->CommonField.AccessBitWidth));
- if (Status == AE_NOT_IMPLEMENTED)
- {
- DEBUG_PRINT (ACPI_ERROR,
- ("AmlWriteField: **** Region type %s(%X) not implemented\n",
- AcpiCmGetRegionName (RgnDesc->Region.SpaceId),
- RgnDesc->Region.SpaceId));
- }
+ /* Invoke the appropriate AddressSpace/OpRegion handler */
- else if (Status == AE_NOT_EXIST)
- {
- DEBUG_PRINT (ACPI_ERROR,
- ("AmlWriteField: **** Region type %s(%X) does not have a handler\n",
- AcpiCmGetRegionName (RgnDesc->Region.SpaceId),
- RgnDesc->Region.SpaceId));
+ Status = AcpiEvAddressSpaceDispatch (RgnDesc, ACPI_WRITE_ADR_SPACE,
+ Address, ObjDesc->CommonField.AccessBitWidth, &Value);
+
+ if (Status == AE_NOT_IMPLEMENTED)
+ {
+ DEBUG_PRINTP (ACPI_ERROR,
+ ("**** Region type %s(%X) not implemented\n",
+ AcpiUtGetRegionName (RgnDesc->Region.SpaceId),
+ RgnDesc->Region.SpaceId));
+ }
+
+ else if (Status == AE_NOT_EXIST)
+ {
+ DEBUG_PRINTP (ACPI_ERROR,
+ ("**** Region type %s(%X) does not have a handler\n",
+ AcpiUtGetRegionName (RgnDesc->Region.SpaceId),
+ RgnDesc->Region.SpaceId));
+ }
+
+ break;
+
+
+ default:
+
+ DEBUG_PRINTP (ACPI_ERROR, ("%p, wrong source type - %s\n",
+ ObjDesc, AcpiUtGetTypeName (ObjDesc->Common.Type)));
+ Status = AE_AML_INTERNAL;
+ break;
}
+
+ DEBUG_PRINTP (TRACE_BFIELD, ("Value written=%08lX \n", Value));
return_ACPI_STATUS (Status);
}
-/*****************************************************************************
+/*******************************************************************************
*
- * FUNCTION: AcpiAmlWriteFieldDataWithUpdateRule
+ * FUNCTION: AcpiExWriteFieldDatumWithUpdateRule
*
* PARAMETERS: *ObjDesc - Field to be set
* Value - Value to store
- * FieldBitWidth - Field Width in bits (8, 16, or 32)
*
* RETURN: Status
*
* DESCRIPTION: Apply the field update rule to a field write
*
- ****************************************************************************/
+ ******************************************************************************/
static ACPI_STATUS
-AcpiAmlWriteFieldDataWithUpdateRule (
+AcpiExWriteFieldDatumWithUpdateRule (
ACPI_OPERAND_OBJECT *ObjDesc,
UINT32 Mask,
UINT32 FieldValue,
- UINT32 ThisFieldByteOffset,
- UINT32 BitGranularity)
+ UINT32 FieldDatumByteOffset)
{
ACPI_STATUS Status = AE_OK;
UINT32 MergedValue;
UINT32 CurrentValue;
+ FUNCTION_TRACE ("ExWriteFieldDatumWithUpdateRule");
+
+
/* Start with the new bits */
MergedValue = FieldValue;
+ /* If the mask is all ones, we don't need to worry about the update rule */
- /* Decode the update rule */
-
- switch (ObjDesc->Field.UpdateRule)
+ if (Mask != ACPI_UINT32_MAX)
{
+ /* Decode the update rule */
- case UPDATE_PRESERVE:
+ switch (ObjDesc->CommonField.UpdateRule)
+ {
- /* Check if update rule needs to be applied (not if mask is all ones) */
+ case UPDATE_PRESERVE:
- /* The left shift drops the bits we want to ignore. */
- if ((~Mask << (sizeof(Mask)*8 - BitGranularity)) != 0)
- {
- /*
- * Read the current contents of the byte/word/dword containing
- * the field, and merge with the new field value.
+ /*
+ * Check if update rule needs to be applied (not if mask is all
+ * ones) The left shift drops the bits we want to ignore.
*/
- Status = AcpiAmlReadFieldData (ObjDesc, ThisFieldByteOffset,
- BitGranularity, &CurrentValue);
- MergedValue |= (CurrentValue & ~Mask);
- }
- break;
+ if ((~Mask << (sizeof (Mask) * 8 -
+ ObjDesc->CommonField.AccessBitWidth)) != 0)
+ {
+ /*
+ * Read the current contents of the byte/word/dword containing
+ * the field, and merge with the new field value.
+ */
+ Status = AcpiExReadFieldDatum (ObjDesc, FieldDatumByteOffset,
+ &CurrentValue);
+ MergedValue |= (CurrentValue & ~Mask);
+ }
+ break;
- case UPDATE_WRITE_AS_ONES:
+ case UPDATE_WRITE_AS_ONES:
- /* Set positions outside the field to all ones */
+ /* Set positions outside the field to all ones */
- MergedValue |= ~Mask;
- break;
+ MergedValue |= ~Mask;
+ break;
- case UPDATE_WRITE_AS_ZEROS:
+ case UPDATE_WRITE_AS_ZEROS:
- /* Set positions outside the field to all zeros */
+ /* Set positions outside the field to all zeros */
- MergedValue &= Mask;
- break;
+ MergedValue &= Mask;
+ break;
- default:
- DEBUG_PRINT (ACPI_ERROR,
- ("WriteFieldDataWithUpdateRule: Unknown UpdateRule setting: %x\n",
- ObjDesc->Field.UpdateRule));
- Status = AE_AML_OPERAND_VALUE;
+ default:
+ DEBUG_PRINT (ACPI_ERROR,
+ ("WriteWithUpdateRule: Unknown UpdateRule setting: %x\n",
+ ObjDesc->CommonField.UpdateRule));
+ return_ACPI_STATUS (AE_AML_OPERAND_VALUE);
+ break;
+ }
}
/* Write the merged value */
- if (ACPI_SUCCESS (Status))
- {
- Status = AcpiAmlWriteFieldData (ObjDesc, ThisFieldByteOffset,
- BitGranularity, MergedValue);
- }
+ Status = AcpiExWriteFieldDatum (ObjDesc, FieldDatumByteOffset,
+ MergedValue);
+
+ DEBUG_PRINTP (TRACE_BFIELD, ("Mask %X DatumOffset %X Value %X, MergedValue %X\n",
+ Mask, FieldDatumByteOffset, FieldValue, MergedValue));
- return (Status);
+ return_ACPI_STATUS (Status);
}
-/*****************************************************************************
+/*******************************************************************************
*
- * FUNCTION: AcpiAmlWriteField
+ * FUNCTION: AcpiExInsertIntoField
*
* PARAMETERS: *ObjDesc - Field to be set
- * Value - Value to store
- * FieldBitWidth - Field Width in bits (8, 16, or 32)
+ * Buffer - Value to store
*
* RETURN: Status
*
* DESCRIPTION: Store the value into the given field
*
- ****************************************************************************/
+ ******************************************************************************/
ACPI_STATUS
-AcpiAmlWriteField (
+AcpiExInsertIntoField (
ACPI_OPERAND_OBJECT *ObjDesc,
void *Buffer,
- UINT32 BufferLength,
- UINT32 ByteLength,
- UINT32 DatumLength,
- UINT32 BitGranularity,
- UINT32 ByteGranularity)
+ UINT32 BufferLength)
{
ACPI_STATUS Status;
- UINT32 ThisFieldByteOffset;
- UINT32 ThisFieldDatumOffset;
+ UINT32 FieldDatumByteOffset;
+ UINT32 DatumOffset;
UINT32 Mask;
UINT32 MergedDatum;
UINT32 PreviousRawDatum;
UINT32 ThisRawDatum;
- UINT32 FieldValue;
- UINT32 ValidFieldBits;
+ UINT32 ByteFieldLength;
+ UINT32 DatumCount;
- FUNCTION_TRACE ("AmlWriteField");
+ FUNCTION_TRACE ("ExInsertIntoField");
/*
- * Break the request into up to three parts:
- * non-aligned part at start, aligned part in middle, non-aligned part
- * at end --- Just like an I/O request ---
+ * Incoming buffer must be at least as long as the field, we do not
+ * allow "partial" field writes. We do not care if the buffer is
+ * larger than the field, this typically happens when an integer is
+ * written to a field that is actually smaller than an integer.
*/
+ ByteFieldLength = ROUND_BITS_UP_TO_BYTES (ObjDesc->CommonField.BitLength);
+ if (BufferLength < ByteFieldLength)
+ {
+ DEBUG_PRINTP (ACPI_INFO, ("Buffer length %X too small for field %X\n",
+ BufferLength, ByteFieldLength));
- ThisFieldByteOffset = 0;
- ThisFieldDatumOffset= 0;
+ /* TBD: Need a better error code */
- /* Get a datum */
+ return_ACPI_STATUS (AE_BUFFER_OVERFLOW);
+ }
- switch (ByteGranularity)
- {
- case 1:
- PreviousRawDatum = ((UINT8 *) Buffer) [ThisFieldDatumOffset];
- break;
+ /* Convert byte count to datum count, round up if necessary */
- case 2:
- MOVE_UNALIGNED16_TO_32 (&PreviousRawDatum, &(((UINT16 *) Buffer) [ThisFieldDatumOffset]));
- break;
+ DatumCount = ROUND_UP_TO (ByteFieldLength, ObjDesc->CommonField.AccessByteWidth);
- case 4:
- MOVE_UNALIGNED32_TO_32 (&PreviousRawDatum, &(((UINT32 *) Buffer) [ThisFieldDatumOffset]));
- break;
+ DEBUG_PRINT (ACPI_INFO,
+ ("ByteLen=%x, DatumLen=%x, BitGran=%x, ByteGran=%x\n",
+ ByteFieldLength, DatumCount, ObjDesc->CommonField.AccessBitWidth,
+ ObjDesc->CommonField.AccessByteWidth));
- default:
- DEBUG_PRINT (ACPI_ERROR, ("AmlWriteField: Invalid granularity: %x\n",
- ByteGranularity));
- Status = AE_AML_OPERAND_VALUE;
- goto Cleanup;
- }
+ /*
+ * Break the request into up to three parts (similar to an I/O request):
+ * 1) non-aligned part at start
+ * 2) aligned part in middle
+ * 3) non-aligned part at the end
+ */
+ FieldDatumByteOffset = 0;
+ DatumOffset= 0;
+
+ /* Get a single datum from the caller's buffer */
+
+ AcpiExGetBufferDatum (&PreviousRawDatum, Buffer,
+ ObjDesc->CommonField.AccessByteWidth, DatumOffset);
/*
+ * Part1:
* Write a partial field datum if field does not begin on a datum boundary
+ * Note: The code in this section also handles the aligned case
*
* Construct Mask with 1 bits where the field is, 0 bits elsewhere
+ * (Only the bottom 5 bits of BitLength are valid for a shift operation)
*
- * 1) Bits above the field
+ * Mask off bits that are "below" the field (if any)
*/
+ Mask = MASK_BITS_BELOW (ObjDesc->CommonField.StartFieldBitOffset);
- Mask = (((UINT32)(-1)) << (UINT32)ObjDesc->Field.BitOffset);
-
- /* 2) Only the bottom 5 bits are valid for a shift operation. */
+ /* If the field fits in one datum, may need to mask upper bits */
- if ((ObjDesc->Field.BitOffset + ObjDesc->FieldUnit.Length) < 32)
+ if ((ObjDesc->CommonField.AccessFlags & AFIELD_SINGLE_DATUM) &&
+ ObjDesc->CommonField.EndFieldValidBits)
{
- /* Bits above the field */
+ /* There are bits above the field, mask them off also */
- Mask &= (~(((UINT32)(-1)) << ((UINT32)ObjDesc->Field.BitOffset +
- (UINT32)ObjDesc->FieldUnit.Length)));
+ Mask &= MASK_BITS_ABOVE (ObjDesc->CommonField.EndFieldValidBits);
}
- /* 3) Shift and mask the value into the field position */
+ /* Shift and mask the value into the field position */
+
+ MergedDatum = (PreviousRawDatum << ObjDesc->CommonField.StartFieldBitOffset);
+ MergedDatum &= Mask;
- FieldValue = (PreviousRawDatum << ObjDesc->Field.BitOffset) & Mask;
+ /* Apply the update rule (if necessary) and write the datum to the field */
- Status = AcpiAmlWriteFieldDataWithUpdateRule (ObjDesc, Mask, FieldValue,
- ThisFieldByteOffset,
- BitGranularity);
+ Status = AcpiExWriteFieldDatumWithUpdateRule (ObjDesc, Mask, MergedDatum,
+ FieldDatumByteOffset);
if (ACPI_FAILURE (Status))
{
- goto Cleanup;
+ return_ACPI_STATUS (Status);
}
+ /* If the entire field fits within one datum, we are done. */
- /* If the field fits within one datum, we are done. */
-
- if ((DatumLength == 1) &&
- ((ObjDesc->Field.BitOffset + ObjDesc->FieldUnit.Length) <=
- (UINT16) BitGranularity))
+ if ((DatumCount == 1) &&
+ (ObjDesc->CommonField.AccessFlags & AFIELD_SINGLE_DATUM))
{
- goto Cleanup;
+ return_ACPI_STATUS (AE_OK);
}
/*
+ * Part2:
+ * Write the aligned data.
+ *
* We don't need to worry about the update rule for these data, because
- * all of the bits are part of the field.
+ * all of the bits in each datum are part of the field.
*
- * Can't write the last datum, however, because it might contain bits that
- * are not part of the field -- the update rule must be applied.
+ * The last datum must be special cased because it might contain bits
+ * that are not part of the field -- therefore the "update rule" must be
+ * applied in Part3 below.
*/
-
- while (ThisFieldDatumOffset < (DatumLength - 1))
+ while (DatumOffset < DatumCount)
{
- ThisFieldDatumOffset++;
-
- /* Get the next raw datum, it contains bits of the current field datum... */
-
- switch (ByteGranularity)
- {
- case 1:
- ThisRawDatum = ((UINT8 *) Buffer) [ThisFieldDatumOffset];
- break;
-
- case 2:
- MOVE_UNALIGNED16_TO_32 (&ThisRawDatum, &(((UINT16 *) Buffer) [ThisFieldDatumOffset]));
- break;
-
- case 4:
- MOVE_UNALIGNED32_TO_32 (&ThisRawDatum, &(((UINT32 *) Buffer) [ThisFieldDatumOffset]));
- break;
+ DatumOffset++;
+ FieldDatumByteOffset += ObjDesc->CommonField.AccessByteWidth;
- default:
- DEBUG_PRINT (ACPI_ERROR, ("AmlWriteField: Invalid Byte Granularity: %x\n",
- ByteGranularity));
- Status = AE_AML_OPERAND_VALUE;
- goto Cleanup;
- }
-
- /*
- * Put together bits of the two raw data to make a complete field
- * datum
+ /*
+ * Get the next raw buffer datum. It may contain bits of the previous
+ * field datum
*/
+ AcpiExGetBufferDatum (&ThisRawDatum, Buffer,
+ ObjDesc->CommonField.AccessByteWidth, DatumOffset);
+
+ /* Create the field datum based on the field alignment */
- if (ObjDesc->Field.BitOffset != 0)
+ if (ObjDesc->CommonField.StartFieldBitOffset != 0)
{
- MergedDatum =
- (PreviousRawDatum >> (BitGranularity - ObjDesc->Field.BitOffset)) |
- (ThisRawDatum << ObjDesc->Field.BitOffset);
+ /*
+ * Put together appropriate bits of the two raw buffer data to make
+ * a single complete field datum
+ */
+ MergedDatum =
+ (PreviousRawDatum >> ObjDesc->CommonField.DatumValidBits) |
+ (ThisRawDatum << ObjDesc->CommonField.StartFieldBitOffset);
}
else
{
- MergedDatum = ThisRawDatum;
- }
-
- /* Now write the completed datum */
-
+ /* Field began aligned on datum boundary */
- Status = AcpiAmlWriteFieldData (ObjDesc,
- ThisFieldByteOffset + ByteGranularity,
- BitGranularity, MergedDatum);
- if (ACPI_FAILURE (Status))
- {
- goto Cleanup;
+ MergedDatum = ThisRawDatum;
}
/*
- * Save the most recent datum since it contains bits of
- * the *next* field datum
+ * Special handling for the last datum if the field does NOT end on
+ * a datum boundary. Update Rule must be applied to the bits outside
+ * the field.
*/
+ if ((DatumOffset == DatumCount) &&
+ ObjDesc->CommonField.EndFieldValidBits)
+ {
+ /*
+ * Part3:
+ * This is the last datum and the field does not end on a datum boundary.
+ * Build the partial datum and write with the update rule.
+ */
- PreviousRawDatum = ThisRawDatum;
-
- ThisFieldByteOffset += ByteGranularity;
+ /* Mask off the unused bits above (after) the end-of-field */
- } /* while */
+ Mask = MASK_BITS_ABOVE (ObjDesc->CommonField.EndFieldValidBits);
+ MergedDatum &= Mask;
+ /* Write the last datum with the update rule */
- /* Write a partial field datum if field does not end on a datum boundary */
+ Status = AcpiExWriteFieldDatumWithUpdateRule (ObjDesc, Mask,
+ MergedDatum, FieldDatumByteOffset);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+ }
- if ((ObjDesc->FieldUnit.Length + ObjDesc->FieldUnit.BitOffset) %
- BitGranularity)
- {
- switch (ByteGranularity)
+ else
{
- case 1:
- ThisRawDatum = ((UINT8 *) Buffer) [ThisFieldDatumOffset];
- break;
-
- case 2:
- MOVE_UNALIGNED16_TO_32 (&ThisRawDatum, &(((UINT16 *) Buffer) [ThisFieldDatumOffset]));
- break;
+ /* Normal case -- write the completed datum */
- case 4:
- MOVE_UNALIGNED32_TO_32 (&ThisRawDatum, &(((UINT32 *) Buffer) [ThisFieldDatumOffset]));
- break;
+ Status = AcpiExWriteFieldDatum (ObjDesc,
+ FieldDatumByteOffset, MergedDatum);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
}
- /* Construct Mask with 1 bits where the field is, 0 bits elsewhere */
-
- ValidFieldBits = ((ObjDesc->FieldUnit.Length % BitGranularity) +
- ObjDesc->Field.BitOffset);
-
- Mask = (((UINT32) 1 << ValidFieldBits) - (UINT32) 1);
-
- /* Shift and mask the value into the field position */
-
- FieldValue = (PreviousRawDatum >>
- (BitGranularity - ObjDesc->Field.BitOffset)) & Mask;
-
- Status = AcpiAmlWriteFieldDataWithUpdateRule (ObjDesc, Mask, FieldValue,
- ThisFieldByteOffset + ByteGranularity,
- BitGranularity);
- if (ACPI_FAILURE (Status))
- {
- goto Cleanup;
- }
+ /*
+ * Save the most recent datum since it may contain bits of the *next*
+ * field datum. Update current byte offset.
+ */
+ PreviousRawDatum = ThisRawDatum;
}
-Cleanup:
-
return_ACPI_STATUS (Status);
}
diff --git a/sys/contrib/dev/acpica/psparse.c b/sys/contrib/dev/acpica/psparse.c
index 1d44bd8..3f4548d 100644
--- a/sys/contrib/dev/acpica/psparse.c
+++ b/sys/contrib/dev/acpica/psparse.c
@@ -1,7 +1,7 @@
/******************************************************************************
*
* Module Name: psparse - Parser top level AML parse routines
- * $Revision: 74 $
+ * $Revision: 85 $
*
*****************************************************************************/
@@ -130,8 +130,9 @@
#include "amlcode.h"
#include "acnamesp.h"
#include "acdebug.h"
+#include "acinterp.h"
-#define _COMPONENT PARSER
+#define _COMPONENT ACPI_PARSER
MODULE_NAME ("psparse")
@@ -203,9 +204,9 @@ AcpiPsPeekOpcode (
*
* if (Opcode == AML_EXTOP
* || (Opcode == AML_LNOT
- * && (GET8 (AcpiAml) == AML_LEQUAL
- * || GET8 (AcpiAml) == AML_LGREATER
- * || GET8 (AcpiAml) == AML_LLESS)))
+ * && (GET8 (Aml) == AML_LEQUAL
+ * || GET8 (Aml) == AML_LGREATER
+ * || GET8 (Aml) == AML_LLESS)))
*
* extended Opcode, !=, <=, or >=
*/
@@ -228,8 +229,8 @@ AcpiPsPeekOpcode (
*
* FUNCTION: AcpiPsCreateState
*
- * PARAMETERS: AcpiAml - AcpiAml code pointer
- * AcpiAmlSize - Length of AML code
+ * PARAMETERS: Aml - Aml code pointer
+ * AmlSize - Length of AML code
*
* RETURN: A new parser state object
*
@@ -248,10 +249,10 @@ AcpiPsCreateState (
FUNCTION_TRACE ("PsCreateState");
- ParserState = AcpiCmCallocate (sizeof (ACPI_PARSE_STATE));
+ ParserState = AcpiUtCallocate (sizeof (ACPI_PARSE_STATE));
if (!ParserState)
{
- return_VALUE (NULL);
+ return_PTR (NULL);
}
ParserState->Aml = Aml;
@@ -362,7 +363,7 @@ AcpiPsCompleteThisOp (
(OpcodeClass != OPTYPE_LOCAL_VARIABLE) &&
(OpcodeClass != OPTYPE_METHOD_ARGUMENT) &&
(OpcodeClass != OPTYPE_DATA_TERM) &&
- (Op->Opcode != AML_NAMEPATH_OP))
+ (Op->Opcode != AML_INT_NAMEPATH_OP))
{
/* Make sure that we only delete this subtree */
@@ -387,15 +388,15 @@ AcpiPsCompleteThisOp (
* op must be replace by a placeholder return op
*/
- if ((Op->Parent->Opcode == AML_REGION_OP) ||
- (Op->Parent->Opcode == AML_CREATE_FIELD_OP) ||
- (Op->Parent->Opcode == AML_BIT_FIELD_OP) ||
- (Op->Parent->Opcode == AML_BYTE_FIELD_OP) ||
- (Op->Parent->Opcode == AML_WORD_FIELD_OP) ||
- (Op->Parent->Opcode == AML_DWORD_FIELD_OP) ||
- (Op->Parent->Opcode == AML_QWORD_FIELD_OP))
+ if ((Op->Parent->Opcode == AML_REGION_OP) ||
+ (Op->Parent->Opcode == AML_CREATE_FIELD_OP) ||
+ (Op->Parent->Opcode == AML_CREATE_BIT_FIELD_OP) ||
+ (Op->Parent->Opcode == AML_CREATE_BYTE_FIELD_OP) ||
+ (Op->Parent->Opcode == AML_CREATE_WORD_FIELD_OP) ||
+ (Op->Parent->Opcode == AML_CREATE_DWORD_FIELD_OP) ||
+ (Op->Parent->Opcode == AML_CREATE_QWORD_FIELD_OP))
{
- ReplacementOp = AcpiPsAllocOp (AML_RETURN_VALUE_OP);
+ ReplacementOp = AcpiPsAllocOp (AML_INT_RETURN_VALUE_OP);
if (!ReplacementOp)
{
return_VALUE (FALSE);
@@ -405,7 +406,7 @@ AcpiPsCompleteThisOp (
break;
default:
- ReplacementOp = AcpiPsAllocOp (AML_RETURN_VALUE_OP);
+ ReplacementOp = AcpiPsAllocOp (AML_INT_RETURN_VALUE_OP);
if (!ReplacementOp)
{
return_VALUE (FALSE);
@@ -621,7 +622,7 @@ AcpiPsParseLoop (
ACPI_PARSE2_OBJECT *DeferredOp;
UINT32 ArgCount; /* push for fixed or var args */
UINT32 ArgTypes = 0;
- ACPI_PTRDIFF AmlOffset;
+ UINT32 AmlOffset;
UINT16 Opcode;
ACPI_PARSE_OBJECT PreOp;
ACPI_PARSE_STATE *ParserState;
@@ -663,14 +664,13 @@ AcpiPsParseLoop (
{
if (Status == AE_AML_NO_RETURN_VALUE)
{
- DEBUG_PRINT (ACPI_ERROR,
- ("PsParseLoop: Invoked method did not return a value, %s\n",
- AcpiCmFormatException (Status)));
+ DEBUG_PRINTP (ACPI_ERROR,
+ ("Invoked method did not return a value, %s\n",
+ AcpiUtFormatException (Status)));
}
- DEBUG_PRINT (ACPI_ERROR,
- ("PsParseLoop: GetPredicate Failed, %s\n",
- AcpiCmFormatException (Status)));
+ DEBUG_PRINTP (ACPI_ERROR, ("GetPredicate Failed, %s\n",
+ AcpiUtFormatException (Status)));
return_ACPI_STATUS (Status);
}
@@ -678,7 +678,7 @@ AcpiPsParseLoop (
}
AcpiPsPopScope (ParserState, &Op, &ArgTypes, &ArgCount);
- DEBUG_PRINT (TRACE_PARSE, ("ParseLoop: Popped scope, Op=%p\n", Op));
+ DEBUG_PRINTP (TRACE_PARSE, ("Popped scope, Op=%p\n", Op));
}
else if (WalkState->PrevOp)
@@ -729,7 +729,7 @@ AcpiPsParseLoop (
* string. Convert the bare name string to a namepath.
*/
- Opcode = AML_NAMEPATH_OP;
+ Opcode = AML_INT_NAMEPATH_OP;
ArgTypes = ARGP_NAMESTRING;
break;
@@ -737,8 +737,8 @@ AcpiPsParseLoop (
/* The opcode is unrecognized. Just skip unknown opcodes */
- DEBUG_PRINT (ACPI_ERROR,
- ("ParseLoop: Found unknown opcode %lX at AML offset %X, ignoring\n",
+ DEBUG_PRINTP (ACPI_ERROR,
+ ("Found unknown opcode %lX at AML offset %X, ignoring\n",
Opcode, AmlOffset));
DUMP_BUFFER (ParserState->Aml, 128);
@@ -835,11 +835,12 @@ AcpiPsParseLoop (
}
- if ((Op->Opcode == AML_CREATE_FIELD_OP) ||
- (Op->Opcode == AML_BIT_FIELD_OP) ||
- (Op->Opcode == AML_BYTE_FIELD_OP) ||
- (Op->Opcode == AML_WORD_FIELD_OP) ||
- (Op->Opcode == AML_DWORD_FIELD_OP))
+ if ((Op->Opcode == AML_CREATE_FIELD_OP) ||
+ (Op->Opcode == AML_CREATE_BIT_FIELD_OP) ||
+ (Op->Opcode == AML_CREATE_BYTE_FIELD_OP) ||
+ (Op->Opcode == AML_CREATE_WORD_FIELD_OP) ||
+ (Op->Opcode == AML_CREATE_DWORD_FIELD_OP) ||
+ (Op->Opcode == AML_CREATE_QWORD_FIELD_OP))
{
/*
* Backup to beginning of CreateXXXfield declaration
@@ -878,8 +879,8 @@ AcpiPsParseLoop (
if (OpInfo)
{
- DEBUG_PRINT (TRACE_PARSE,
- ("ParseLoop: Op=%p Opcode=%4.4lX Aml %p Oft=%5.5lX\n",
+ DEBUG_PRINTP (TRACE_PARSE,
+ ("Op=%p Opcode=%4.4lX Aml %p Oft=%5.5lX\n",
Op, Op->Opcode, ParserState->Aml, Op->AmlOffset));
}
}
@@ -907,7 +908,7 @@ AcpiPsParseLoop (
GET_CURRENT_ARG_TYPE (ArgTypes), Op);
break;
- case AML_NAMEPATH_OP: /* AML_NAMESTRING_ARG */
+ case AML_INT_NAMEPATH_OP: /* AML_NAMESTRING_ARG */
AcpiPsGetNextNamepath (ParserState, Op, &ArgCount, 1);
ArgTypes = 0;
@@ -948,8 +949,8 @@ AcpiPsParseLoop (
*/
DeferredOp->Data = ParserState->Aml;
- DeferredOp->Length = ParserState->PkgEnd -
- ParserState->Aml;
+ DeferredOp->Length = (UINT32) (ParserState->PkgEnd -
+ ParserState->Aml);
/*
* Skip body of method. For OpRegions, we must continue
@@ -994,18 +995,18 @@ AcpiPsParseLoop (
* know the length.
*/
- DeferredOp->Length = ParserState->Aml -
- DeferredOp->Data;
+ DeferredOp->Length = (UINT32) (ParserState->Aml -
+ DeferredOp->Data);
}
}
}
- if ((Op->Opcode == AML_CREATE_FIELD_OP) ||
- (Op->Opcode == AML_BIT_FIELD_OP) ||
- (Op->Opcode == AML_BYTE_FIELD_OP) ||
- (Op->Opcode == AML_WORD_FIELD_OP) ||
- (Op->Opcode == AML_DWORD_FIELD_OP) ||
- (Op->Opcode == AML_QWORD_FIELD_OP))
+ if ((Op->Opcode == AML_CREATE_FIELD_OP) ||
+ (Op->Opcode == AML_CREATE_BIT_FIELD_OP) ||
+ (Op->Opcode == AML_CREATE_BYTE_FIELD_OP) ||
+ (Op->Opcode == AML_CREATE_WORD_FIELD_OP) ||
+ (Op->Opcode == AML_CREATE_DWORD_FIELD_OP) ||
+ (Op->Opcode == AML_CREATE_QWORD_FIELD_OP))
{
/*
* Backup to beginning of CreateXXXfield declaration (1 for
@@ -1014,7 +1015,8 @@ AcpiPsParseLoop (
* BodyLength is unknown until we parse the body
*/
DeferredOp = (ACPI_PARSE2_OBJECT *) Op;
- DeferredOp->Length = ParserState->Aml - DeferredOp->Data;
+ DeferredOp->Length = (UINT32) (ParserState->Aml -
+ DeferredOp->Data);
}
/* This op complete, notify the dispatcher */
@@ -1118,7 +1120,7 @@ CloseThisOp:
if (AcpiPsHasCompletedScope (ParserState))
{
AcpiPsPopScope (ParserState, &Op, &ArgTypes, &ArgCount);
- DEBUG_PRINT (TRACE_PARSE, ("ParseLoop: Popped scope, Op=%p\n", Op));
+ DEBUG_PRINTP (TRACE_PARSE, ("Popped scope, Op=%p\n", Op));
}
else
@@ -1149,7 +1151,7 @@ CloseThisOp:
* sequential closing braces). We want to terminate each one cleanly.
*/
- DEBUG_PRINT (TRACE_PARSE, ("PsParseLoop: Package complete at Op %p\n", Op));
+ DEBUG_PRINTP (TRACE_PARSE, ("Package complete at Op %p\n", Op));
do
{
if (Op)
@@ -1241,8 +1243,7 @@ AcpiPsParseAml (
FUNCTION_TRACE ("PsParseAml");
- DEBUG_PRINT (TRACE_PARSE,
- ("PsParseAml: Entered with Scope=%p Aml=%p size=%lX\n",
+ DEBUG_PRINTP (TRACE_PARSE, ("Entered with Scope=%p Aml=%p size=%lX\n",
StartScope, Aml, AmlSize));
@@ -1264,8 +1265,11 @@ AcpiPsParseAml (
/* Create and initialize a new walk list */
WalkList.WalkState = NULL;
+ WalkList.AcquiredMutexList.Prev = NULL;
+ WalkList.AcquiredMutexList.Next = NULL;
- WalkState = AcpiDsCreateWalkState (TABLE_ID_DSDT, ParserState->StartOp, MthDesc, &WalkList);
+ WalkState = AcpiDsCreateWalkState (TABLE_ID_DSDT, ParserState->StartOp,
+ MthDesc, &WalkList);
if (!WalkState)
{
Status = AE_NO_MEMORY;
@@ -1331,8 +1335,7 @@ AcpiPsParseAml (
* handles nested control method invocations without recursion.
*/
- DEBUG_PRINT (TRACE_PARSE, ("PsParseAml: State=%p\n",
- WalkState));
+ DEBUG_PRINTP (TRACE_PARSE, ("State=%p\n", WalkState));
while (WalkState)
{
@@ -1341,9 +1344,8 @@ AcpiPsParseAml (
Status = AcpiPsParseLoop (WalkState);
}
- DEBUG_PRINT (TRACE_PARSE,
- ("PsParseAml: Completed one call to walk loop, State=%p\n",
- WalkState));
+ DEBUG_PRINTP (TRACE_PARSE,
+ ("Completed one call to walk loop, State=%p\n", WalkState));
if (Status == AE_CTRL_TRANSFER)
{
@@ -1381,12 +1383,11 @@ AcpiPsParseAml (
if (CallerReturnDesc && ReturnDesc)
{
- EffectiveReturnDesc = ReturnDesc;
- AcpiCmAddReference (EffectiveReturnDesc);
+ EffectiveReturnDesc = ReturnDesc;
+ AcpiUtAddReference (EffectiveReturnDesc);
}
- DEBUG_PRINT (TRACE_PARSE,
- ("PsParseAml: ReturnValue=%p, State=%p\n",
+ DEBUG_PRINTP (TRACE_PARSE, ("ReturnValue=%p, State=%p\n",
WalkState->ReturnDesc, WalkState));
/* Reset the current scope to the beginning of scope stack */
@@ -1406,7 +1407,7 @@ AcpiPsParseAml (
/* Delete this walk state and all linked control states */
AcpiPsCleanupScope (WalkState->ParserState);
- AcpiCmFree (WalkState->ParserState);
+ AcpiUtFree (WalkState->ParserState);
AcpiDsDeleteWalkState (WalkState);
/* Check if we have restarted a preempted walk */
@@ -1440,7 +1441,7 @@ AcpiPsParseAml (
if (ReturnDesc == NULL && EffectiveReturnDesc != NULL)
{
- AcpiCmRemoveReference (ReturnDesc);
+ AcpiUtRemoveReference (ReturnDesc);
ReturnDesc = EffectiveReturnDesc;
}
*CallerReturnDesc = ReturnDesc; /* NULL if no return value */
@@ -1450,13 +1451,14 @@ AcpiPsParseAml (
{
/* Caller doesn't want it, must delete it */
- AcpiCmRemoveReference (ReturnDesc);
+ AcpiUtRemoveReference (ReturnDesc);
}
}
/* Normal exit */
+ AcpiExReleaseAllMutexes ((ACPI_OPERAND_OBJECT *) &WalkList.AcquiredMutexList);
AcpiGbl_CurrentWalkList = PrevWalkList;
return_ACPI_STATUS (Status);
@@ -1467,8 +1469,9 @@ Cleanup:
AcpiDsDeleteWalkState (WalkState);
AcpiPsCleanupScope (ParserState);
- AcpiCmFree (ParserState);
+ AcpiUtFree (ParserState);
+ AcpiExReleaseAllMutexes ((ACPI_OPERAND_OBJECT *)&WalkList.AcquiredMutexList);
AcpiGbl_CurrentWalkList = PrevWalkList;
return_ACPI_STATUS (Status);
OpenPOWER on IntegriCloud