blob: 27ab7e362a598acf037f324d907444c83d6d8f0f [file] [log] [blame]
/******************************************************************************
*
* Module Name: aeregion - Operation region support for acpiexec
*
*****************************************************************************/
/*
* Copyright (C) 2000 - 2016, Intel Corp.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions, and the following disclaimer,
* without modification.
* 2. Redistributions in binary form must reproduce at minimum a disclaimer
* substantially similar to the "NO WARRANTY" disclaimer below
* ("Disclaimer") and any redistribution must be conditioned upon
* including a substantially similar Disclaimer requirement for further
* binary redistribution.
* 3. Neither the names of the above-listed copyright holders nor the names
* of any contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* Alternatively, this software may be distributed under the terms of the
* GNU General Public License ("GPL") version 2 as published by the Free
* Software Foundation.
*
* NO WARRANTY
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES.
*/
#include "aecommon.h"
#define _COMPONENT ACPI_TOOLS
ACPI_MODULE_NAME ("aeregion")
/* Local prototypes */
static ACPI_STATUS
AeRegionInit (
ACPI_HANDLE RegionHandle,
UINT32 Function,
void *HandlerContext,
void **RegionContext);
static ACPI_STATUS
AeInstallEcHandler (
ACPI_HANDLE ObjHandle,
UINT32 Level,
void *Context,
void **ReturnValue);
static ACPI_STATUS
AeInstallPciHandler (
ACPI_HANDLE ObjHandle,
UINT32 Level,
void *Context,
void **ReturnValue);
static AE_DEBUG_REGIONS AeRegions;
BOOLEAN AcpiGbl_DisplayRegionAccess = FALSE;
ACPI_CONNECTION_INFO AeMyContext;
/*
* We will override some of the default region handlers, especially
* the SystemMemory handler, which must be implemented locally.
* These handlers are installed "early" - before any _REG methods
* are executed - since they are special in the sense that the ACPI spec
* declares that they must "always be available". Cannot override the
* DataTable region handler either -- needed for test execution.
*
* NOTE: The local region handler will simulate access to these address
* spaces by creating a memory buffer behind each operation region.
*/
static ACPI_ADR_SPACE_TYPE DefaultSpaceIdList[] =
{
ACPI_ADR_SPACE_SYSTEM_MEMORY,
ACPI_ADR_SPACE_SYSTEM_IO,
ACPI_ADR_SPACE_PCI_CONFIG,
ACPI_ADR_SPACE_EC
};
/*
* We will install handlers for some of the various address space IDs.
* Test one user-defined address space (used by aslts).
*/
#define ACPI_ADR_SPACE_USER_DEFINED1 0x80
#define ACPI_ADR_SPACE_USER_DEFINED2 0xE4
static ACPI_ADR_SPACE_TYPE SpaceIdList[] =
{
ACPI_ADR_SPACE_SMBUS,
ACPI_ADR_SPACE_CMOS,
ACPI_ADR_SPACE_PCI_BAR_TARGET,
ACPI_ADR_SPACE_IPMI,
ACPI_ADR_SPACE_GPIO,
ACPI_ADR_SPACE_GSBUS,
ACPI_ADR_SPACE_FIXED_HARDWARE,
ACPI_ADR_SPACE_USER_DEFINED1,
ACPI_ADR_SPACE_USER_DEFINED2
};
/******************************************************************************
*
* FUNCTION: AeRegionInit
*
* PARAMETERS: Region init handler
*
* RETURN: Status
*
* DESCRIPTION: Opregion init function.
*
*****************************************************************************/
static ACPI_STATUS
AeRegionInit (
ACPI_HANDLE RegionHandle,
UINT32 Function,
void *HandlerContext,
void **RegionContext)
{
if (Function == ACPI_REGION_DEACTIVATE)
{
*RegionContext = NULL;
}
else
{
*RegionContext = RegionHandle;
}
return (AE_OK);
}
/******************************************************************************
*
* FUNCTION: AeOverrideRegionHandlers
*
* PARAMETERS: None
*
* RETURN: None
*
* DESCRIPTION: Override the default region handlers for memory, i/o, and
* pci_config. Also install a handler for EC. This is part of
* the "install early handlers" functionality.
*
*****************************************************************************/
void
AeOverrideRegionHandlers (
void)
{
UINT32 i;
ACPI_STATUS Status;
/*
* Install handlers that will override the default handlers for some of
* the space IDs.
*/
for (i = 0; i < ACPI_ARRAY_LENGTH (DefaultSpaceIdList); i++)
{
/* Install handler at the root object */
Status = AcpiInstallAddressSpaceHandler (ACPI_ROOT_OBJECT,
DefaultSpaceIdList[i], AeRegionHandler,
AeRegionInit, &AeMyContext);
if (ACPI_FAILURE (Status))
{
ACPI_EXCEPTION ((AE_INFO, Status,
"Could not install an OpRegion handler for %s space(%u)",
AcpiUtGetRegionName ((UINT8) DefaultSpaceIdList[i]),
DefaultSpaceIdList[i]));
}
}
}
/******************************************************************************
*
* FUNCTION: AeInstallRegionHandlers
*
* PARAMETERS: None
*
* RETURN: None
*
* DESCRIPTION: Install handlers for the address spaces other than memory,
* i/o, and pci_config.
*
*****************************************************************************/
void
AeInstallRegionHandlers (
void)
{
UINT32 i;
ACPI_STATUS Status;
/*
* Install handlers for some of the "device driver" address spaces
* such as SMBus, etc.
*/
for (i = 0; i < ACPI_ARRAY_LENGTH (SpaceIdList); i++)
{
/* Install handler at the root object */
Status = AcpiInstallAddressSpaceHandler (ACPI_ROOT_OBJECT,
SpaceIdList[i], AeRegionHandler,
AeRegionInit, &AeMyContext);
if (ACPI_FAILURE (Status))
{
ACPI_EXCEPTION ((AE_INFO, Status,
"Could not install an OpRegion handler for %s space(%u)",
AcpiUtGetRegionName((UINT8) SpaceIdList[i]), SpaceIdList[i]));
return;
}
}
}
/*******************************************************************************
*
* FUNCTION: AeInstallDeviceHandlers,
* AeInstallEcHandler,
* AeInstallPciHandler
*
* PARAMETERS: ACPI_WALK_NAMESPACE callback
*
* RETURN: Status
*
* DESCRIPTION: Walk entire namespace, install a handler for every EC
* and PCI device found.
*
******************************************************************************/
static ACPI_STATUS
AeInstallEcHandler (
ACPI_HANDLE ObjHandle,
UINT32 Level,
void *Context,
void **ReturnValue)
{
ACPI_STATUS Status;
/* Install the handler for this EC device */
Status = AcpiInstallAddressSpaceHandler (ObjHandle, ACPI_ADR_SPACE_EC,
AeRegionHandler, AeRegionInit, &AeMyContext);
if (ACPI_FAILURE (Status))
{
ACPI_EXCEPTION ((AE_INFO, Status,
"Could not install an OpRegion handler for EC device (%p)",
ObjHandle));
}
return (Status);
}
static ACPI_STATUS
AeInstallPciHandler (
ACPI_HANDLE ObjHandle,
UINT32 Level,
void *Context,
void **ReturnValue)
{
ACPI_STATUS Status;
/* Install memory and I/O handlers for the PCI device */
Status = AcpiInstallAddressSpaceHandler (ObjHandle, ACPI_ADR_SPACE_SYSTEM_IO,
AeRegionHandler, AeRegionInit, &AeMyContext);
if (ACPI_FAILURE (Status))
{
ACPI_EXCEPTION ((AE_INFO, Status,
"Could not install an OpRegion handler for PCI device (%p)",
ObjHandle));
}
Status = AcpiInstallAddressSpaceHandler (ObjHandle, ACPI_ADR_SPACE_SYSTEM_MEMORY,
AeRegionHandler, AeRegionInit, &AeMyContext);
if (ACPI_FAILURE (Status))
{
ACPI_EXCEPTION ((AE_INFO, Status,
"Could not install an OpRegion handler for PCI device (%p)",
ObjHandle));
}
return (AE_CTRL_TERMINATE);
}
ACPI_STATUS
AeInstallDeviceHandlers (
void)
{
/* Find all Embedded Controller devices */
AcpiGetDevices ("PNP0C09", AeInstallEcHandler, NULL, NULL);
/* Install a PCI handler */
AcpiGetDevices ("PNP0A08", AeInstallPciHandler, NULL, NULL);
return (AE_OK);
}
/******************************************************************************
*
* FUNCTION: AeRegionHandler
*
* PARAMETERS: Standard region handler parameters
*
* RETURN: Status
*
* DESCRIPTION: Test handler - Handles some dummy regions via memory that can
* be manipulated in Ring 3. Simulates actual reads and writes.
*
*****************************************************************************/
ACPI_STATUS
AeRegionHandler (
UINT32 Function,
ACPI_PHYSICAL_ADDRESS Address,
UINT32 BitWidth,
UINT64 *Value,
void *HandlerContext,
void *RegionContext)
{
ACPI_OPERAND_OBJECT *RegionObject = ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, RegionContext);
UINT8 *Buffer = ACPI_CAST_PTR (UINT8, Value);
UINT8 *OldBuffer;
UINT8 *NewBuffer;
ACPI_PHYSICAL_ADDRESS BaseAddress;
ACPI_PHYSICAL_ADDRESS BaseAddressEnd;
ACPI_PHYSICAL_ADDRESS RegionAddress;
ACPI_PHYSICAL_ADDRESS RegionAddressEnd;
ACPI_SIZE Length;
BOOLEAN BufferExists;
BOOLEAN BufferResize;
AE_REGION *RegionElement;
void *BufferValue;
ACPI_STATUS Status;
UINT32 ByteWidth;
UINT32 RegionLength;
UINT32 i;
UINT8 SpaceId;
ACPI_CONNECTION_INFO *MyContext;
UINT32 Value1;
UINT32 Value2;
ACPI_RESOURCE *Resource;
ACPI_FUNCTION_NAME (AeRegionHandler);
/*
* If the object is not a region, simply return
*/
if (RegionObject->Region.Type != ACPI_TYPE_REGION)
{
return (AE_OK);
}
/* Check that we actually got back our context parameter */
if (HandlerContext != &AeMyContext)
{
printf ("Region handler received incorrect context %p, should be %p\n",
HandlerContext, &AeMyContext);
}
MyContext = ACPI_CAST_PTR (ACPI_CONNECTION_INFO, HandlerContext);
/*
* Find the region's address space and length before searching
* the linked list.
*/
BaseAddress = RegionObject->Region.Address;
Length = (ACPI_SIZE) RegionObject->Region.Length;
SpaceId = RegionObject->Region.SpaceId;
ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
"Operation Region request on %s at 0x%X\n",
AcpiUtGetRegionName (RegionObject->Region.SpaceId),
(UINT32) Address));
/*
* Region support can be disabled with the -do option.
* We use this to support dynamically loaded tables where we pass a valid
* address to the AML.
*/
if (AcpiGbl_DbOpt_NoRegionSupport)
{
BufferValue = ACPI_TO_POINTER (Address);
ByteWidth = (BitWidth / 8);
if (BitWidth % 8)
{
ByteWidth += 1;
}
goto DoFunction;
}
switch (SpaceId)
{
case ACPI_ADR_SPACE_SYSTEM_IO:
/*
* For I/O space, exercise the port validation
* Note: ReadPort currently always returns all ones, length=BitLength
*/
switch (Function & ACPI_IO_MASK)
{
case ACPI_READ:
if (BitWidth == 64)
{
/* Split the 64-bit request into two 32-bit requests */
Status = AcpiHwReadPort (Address, &Value1, 32);
ACPI_CHECK_OK (AcpiHwReadPort, Status);
Status = AcpiHwReadPort (Address+4, &Value2, 32);
ACPI_CHECK_OK (AcpiHwReadPort, Status);
*Value = Value1 | ((UINT64) Value2 << 32);
}
else
{
Status = AcpiHwReadPort (Address, &Value1, BitWidth);
ACPI_CHECK_OK (AcpiHwReadPort, Status);
*Value = (UINT64) Value1;
}
break;
case ACPI_WRITE:
if (BitWidth == 64)
{
/* Split the 64-bit request into two 32-bit requests */
Status = AcpiHwWritePort (Address, ACPI_LODWORD (*Value), 32);
ACPI_CHECK_OK (AcpiHwWritePort, Status);
Status = AcpiHwWritePort (Address+4, ACPI_HIDWORD (*Value), 32);
ACPI_CHECK_OK (AcpiHwWritePort, Status);
}
else
{
Status = AcpiHwWritePort (Address, (UINT32) *Value, BitWidth);
ACPI_CHECK_OK (AcpiHwWritePort, Status);
}
break;
default:
Status = AE_BAD_PARAMETER;
break;
}
if (ACPI_FAILURE (Status))
{
return (Status);
}
/* Now go ahead and simulate the hardware */
break;
/*
* SMBus and GenericSerialBus support the various bidirectional
* protocols.
*/
case ACPI_ADR_SPACE_SMBUS:
case ACPI_ADR_SPACE_GSBUS: /* ACPI 5.0 */
Length = 0;
switch (Function & ACPI_IO_MASK)
{
case ACPI_READ:
switch (Function >> 16)
{
case AML_FIELD_ATTRIB_QUICK:
Length = 0;
break;
case AML_FIELD_ATTRIB_SEND_RCV:
case AML_FIELD_ATTRIB_BYTE:
Length = 1;
break;
case AML_FIELD_ATTRIB_WORD:
case AML_FIELD_ATTRIB_WORD_CALL:
Length = 2;
break;
case AML_FIELD_ATTRIB_BLOCK:
case AML_FIELD_ATTRIB_BLOCK_CALL:
Length = 32;
break;
case AML_FIELD_ATTRIB_MULTIBYTE:
case AML_FIELD_ATTRIB_RAW_BYTES:
case AML_FIELD_ATTRIB_RAW_PROCESS:
Length = MyContext->AccessLength;
break;
default:
break;
}
break;
case ACPI_WRITE:
switch (Function >> 16)
{
case AML_FIELD_ATTRIB_QUICK:
case AML_FIELD_ATTRIB_SEND_RCV:
case AML_FIELD_ATTRIB_BYTE:
case AML_FIELD_ATTRIB_WORD:
case AML_FIELD_ATTRIB_BLOCK:
Length = 0;
break;
case AML_FIELD_ATTRIB_WORD_CALL:
Length = 2;
break;
case AML_FIELD_ATTRIB_BLOCK_CALL:
Length = 32;
break;
case AML_FIELD_ATTRIB_MULTIBYTE:
case AML_FIELD_ATTRIB_RAW_BYTES:
case AML_FIELD_ATTRIB_RAW_PROCESS:
Length = MyContext->AccessLength;
break;
default:
break;
}
break;
default:
break;
}
if (AcpiGbl_DisplayRegionAccess)
{
AcpiOsPrintf ("AcpiExec: %s "
"%s: Attr %X Addr %.4X BaseAddr %.4X Len %.2X Width %X BufLen %X",
AcpiUtGetRegionName (SpaceId),
(Function & ACPI_IO_MASK) ? "Write" : "Read ",
(UINT32) (Function >> 16),
(UINT32) Address, (UINT32) BaseAddress,
Length, BitWidth, Buffer[1]);
/* GenericSerialBus has a Connection() parameter */
if (SpaceId == ACPI_ADR_SPACE_GSBUS)
{
Status = AcpiBufferToResource (MyContext->Connection,
MyContext->Length, &Resource);
AcpiOsPrintf (" [AccLen %.2X Conn %p]",
MyContext->AccessLength, MyContext->Connection);
}
AcpiOsPrintf ("\n");
}
/* Setup the return buffer. Note: ASLTS depends on these fill values */
for (i = 0; i < Length; i++)
{
Buffer[i+2] = (UINT8) (0xA0 + i);
}
Buffer[0] = 0x7A;
Buffer[1] = (UINT8) Length;
return (AE_OK);
case ACPI_ADR_SPACE_IPMI: /* ACPI 4.0 */
if (AcpiGbl_DisplayRegionAccess)
{
AcpiOsPrintf ("AcpiExec: IPMI "
"%s: Attr %X Addr %.4X BaseAddr %.4X Len %.2X Width %X BufLen %X\n",
(Function & ACPI_IO_MASK) ? "Write" : "Read ",
(UINT32) (Function >> 16), (UINT32) Address, (UINT32) BaseAddress,
Length, BitWidth, Buffer[1]);
}
/*
* Regardless of a READ or WRITE, this handler is passed a 66-byte
* buffer in which to return the IPMI status/length/data.
*
* Return some example data to show use of the bidirectional buffer
*/
Buffer[0] = 0; /* Status byte */
Buffer[1] = 64; /* Return buffer data length */
Buffer[2] = 0; /* Completion code */
Buffer[3] = 0; /* Reserved */
/*
* Fill the 66-byte buffer with the return data.
* Note: ASLTS depends on these fill values.
*/
for (i = 4; i < 66; i++)
{
Buffer[i] = (UINT8) (i);
}
return (AE_OK);
/*
* GPIO has some special semantics:
* 1) Address is the pin number index into the Connection() pin list
* 2) BitWidth is the actual number of bits (pins) defined by the field
*/
case ACPI_ADR_SPACE_GPIO: /* ACPI 5.0 */
if (AcpiGbl_DisplayRegionAccess)
{
AcpiOsPrintf ("AcpiExec: GPIO "
"%s: Addr %.4X Width %X Conn %p\n",
(Function & ACPI_IO_MASK) ? "Write" : "Read ",
(UINT32) Address, BitWidth, MyContext->Connection);
}
return (AE_OK);
default:
break;
}
/*
* Search through the linked list for this region's buffer
*/
BufferExists = FALSE;
BufferResize = FALSE;
RegionElement = AeRegions.RegionList;
if (AeRegions.NumberOfRegions)
{
BaseAddressEnd = BaseAddress + Length - 1;
while (!BufferExists && RegionElement)
{
RegionAddress = RegionElement->Address;
RegionAddressEnd = RegionElement->Address + RegionElement->Length - 1;
RegionLength = RegionElement->Length;
/*
* Overlapping Region Support
*
* While searching through the region buffer list, determine if an
* overlap exists between the requested buffer space and the current
* RegionElement space. If there is an overlap then replace the old
* buffer with a new buffer of increased size before continuing to
* do the read or write
*/
if (RegionElement->SpaceId != SpaceId ||
BaseAddressEnd < RegionAddress ||
BaseAddress > RegionAddressEnd)
{
/*
* Requested buffer is outside of the current RegionElement
* bounds
*/
RegionElement = RegionElement->NextRegion;
}
else
{
/*
* Some amount of buffer space sharing exists. There are 4 cases
* to consider:
*
* 1. Right overlap
* 2. Left overlap
* 3. Left and right overlap
* 4. Fully contained - no resizing required
*/
BufferExists = TRUE;
if ((BaseAddress >= RegionAddress) &&
(BaseAddress <= RegionAddressEnd) &&
(BaseAddressEnd > RegionAddressEnd))
{
/* Right overlap */
RegionElement->Length = (UINT32) (BaseAddress -
RegionAddress + Length);
BufferResize = TRUE;
}
else if ((BaseAddressEnd >= RegionAddress) &&
(BaseAddressEnd <= RegionAddressEnd) &&
(BaseAddress < RegionAddress))
{
/* Left overlap */
RegionElement->Address = BaseAddress;
RegionElement->Length = (UINT32) (RegionAddress -
BaseAddress + RegionElement->Length);
BufferResize = TRUE;
}
else if ((BaseAddress < RegionAddress) &&
(BaseAddressEnd > RegionAddressEnd))
{
/* Left and right overlap */
RegionElement->Address = BaseAddress;
RegionElement->Length = Length;
BufferResize = TRUE;
}
/*
* only remaining case is fully contained for which we don't
* need to do anything
*/
if (BufferResize)
{
NewBuffer = AcpiOsAllocate (RegionElement->Length);
if (!NewBuffer)
{
return (AE_NO_MEMORY);
}
OldBuffer = RegionElement->Buffer;
RegionElement->Buffer = NewBuffer;
NewBuffer = NULL;
/* Initialize the region with the default fill value */
memset (RegionElement->Buffer,
AcpiGbl_RegionFillValue, RegionElement->Length);
/*
* Get BufferValue to point (within the new buffer) to the
* base address of the old buffer
*/
BufferValue = (UINT8 *) RegionElement->Buffer +
(UINT64) RegionAddress -
(UINT64) RegionElement->Address;
/*
* Copy the old buffer to its same location within the new
* buffer
*/
memcpy (BufferValue, OldBuffer, RegionLength);
AcpiOsFree (OldBuffer);
}
}
}
}
/*
* If the Region buffer does not exist, create it now
*/
if (!BufferExists)
{
/* Do the memory allocations first */
RegionElement = AcpiOsAllocate (sizeof (AE_REGION));
if (!RegionElement)
{
return (AE_NO_MEMORY);
}
RegionElement->Buffer = AcpiOsAllocate (Length);
if (!RegionElement->Buffer)
{
AcpiOsFree (RegionElement);
return (AE_NO_MEMORY);
}
/* Initialize the region with the default fill value */
memset (RegionElement->Buffer, AcpiGbl_RegionFillValue, Length);
RegionElement->Address = BaseAddress;
RegionElement->Length = Length;
RegionElement->SpaceId = SpaceId;
RegionElement->NextRegion = NULL;
/*
* Increment the number of regions and put this one
* at the head of the list as it will probably get accessed
* more often anyway.
*/
AeRegions.NumberOfRegions += 1;
if (AeRegions.RegionList)
{
RegionElement->NextRegion = AeRegions.RegionList;
}
AeRegions.RegionList = RegionElement;
}
/* Calculate the size of the memory copy */
ByteWidth = (BitWidth / 8);
if (BitWidth % 8)
{
ByteWidth += 1;
}
/*
* The buffer exists and is pointed to by RegionElement.
* We now need to verify the request is valid and perform the operation.
*
* NOTE: RegionElement->Length is in bytes, therefore it we compare against
* ByteWidth (see above)
*/
if ((RegionObject->Region.SpaceId != ACPI_ADR_SPACE_GPIO) &&
((UINT64) Address + ByteWidth) >
((UINT64)(RegionElement->Address) + RegionElement->Length))
{
ACPI_WARNING ((AE_INFO,
"Request on [%4.4s] is beyond region limit "
"Req-0x%X+0x%X, Base=0x%X, Len-0x%X",
(RegionObject->Region.Node)->Name.Ascii, (UINT32) Address,
ByteWidth, (UINT32)(RegionElement->Address),
RegionElement->Length));
return (AE_AML_REGION_LIMIT);
}
/*
* Get BufferValue to point to the "address" in the buffer
*/
BufferValue = ((UINT8 *) RegionElement->Buffer +
((UINT64) Address - (UINT64) RegionElement->Address));
DoFunction:
/*
* Perform a read or write to the buffer space
*/
switch (Function)
{
case ACPI_READ:
/*
* Set the pointer Value to whatever is in the buffer
*/
memcpy (Value, BufferValue, ByteWidth);
break;
case ACPI_WRITE:
/*
* Write the contents of Value to the buffer
*/
memcpy (BufferValue, Value, ByteWidth);
break;
default:
return (AE_BAD_PARAMETER);
}
if (AcpiGbl_DisplayRegionAccess)
{
switch (SpaceId)
{
case ACPI_ADR_SPACE_SYSTEM_MEMORY:
AcpiOsPrintf ("AcpiExec: SystemMemory "
"%s: Val %.8X Addr %.4X Width %X [REGION: BaseAddr %.4X Len %.2X]\n",
(Function & ACPI_IO_MASK) ? "Write" : "Read ",
(UINT32) *Value, (UINT32) Address, BitWidth, (UINT32) BaseAddress, Length);
break;
case ACPI_ADR_SPACE_GPIO: /* ACPI 5.0 */
/* This space is required to always be ByteAcc */
Status = AcpiBufferToResource (MyContext->Connection,
MyContext->Length, &Resource);
AcpiOsPrintf ("AcpiExec: GeneralPurposeIo "
"%s: Val %.8X Addr %.4X BaseAddr %.4X Len %.2X Width %X AccLen %.2X Conn %p\n",
(Function & ACPI_IO_MASK) ? "Write" : "Read ", (UINT32) *Value,
(UINT32) Address, (UINT32) BaseAddress, Length, BitWidth,
MyContext->AccessLength, MyContext->Connection);
break;
default:
break;
}
}
return (AE_OK);
}