diff options
author | msmith <msmith@FreeBSD.org> | 2001-05-29 19:56:18 +0000 |
---|---|---|
committer | msmith <msmith@FreeBSD.org> | 2001-05-29 19:56:18 +0000 |
commit | adc622bc2d7f44144b00414f40341c94f96be143 (patch) | |
tree | 9b3c03c9374939fdaa96ac0078b3c6b59a1f00c5 | |
parent | aa7ec52010ab8c57de054cdb411a36092f3378ee (diff) | |
download | FreeBSD-src-adc622bc2d7f44144b00414f40341c94f96be143.zip FreeBSD-src-adc622bc2d7f44144b00414f40341c94f96be143.tar.gz |
Merge FreeBSD-specific changes with the ACPI CA 20010518 release.
-rw-r--r-- | sys/contrib/dev/acpica/acconfig.h | 11 | ||||
-rw-r--r-- | sys/contrib/dev/acpica/acfreebsd.h | 29 | ||||
-rw-r--r-- | sys/contrib/dev/acpica/acgcc.h | 3 | ||||
-rw-r--r-- | sys/contrib/dev/acpica/acpixf.h | 46 | ||||
-rw-r--r-- | sys/contrib/dev/acpica/exfldio.c | 1064 | ||||
-rw-r--r-- | sys/contrib/dev/acpica/psparse.c | 137 |
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); |