/******************************************************************************
 *
 * Module Name: aeregion - Handler for operation regions
 *
 *****************************************************************************/

/*
 * Copyright (C) 2000 - 2023, 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 MERCHANTABILITY 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")


static AE_DEBUG_REGIONS     AeRegions;


/******************************************************************************
 *
 * 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;
    UINT32                  Length;
    UINT8                   DataLength;
    UINT8                   *DataBuffer;
    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;
    char                    Uuid[ACPI_PRM_INPUT_BUFFER_SIZE + 1];


    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)
    {
        AcpiOsPrintf (
            "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 = RegionObject->Region.Length;
    SpaceId = RegionObject->Region.SpaceId;

    ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
        "Operation Region request on %s at 0x%X, BitWidth 0x%X, RegionLength 0x%X\n",
        AcpiUtGetRegionName (RegionObject->Region.SpaceId),
        (UINT32) Address, BitWidth, (UINT32) Length));

    /*
     * 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 */

        Status = AcpiExGetProtocolBufferLength ((Function >> 16), &Length);
        if (ACPI_FAILURE (Status))
        {
            AcpiOsPrintf ("AcpiExec: Invalid SMbus/GSbus protocol ID: 0x%X\n",
                (Function >> 16));
            return (Status);
        }

        /* Adjust for fixed SMBus buffer size */

        if ((SpaceId == ACPI_ADR_SPACE_SMBUS) &&
            (Length > ACPI_SMBUS_DATA_SIZE))
        {
            Length = ACPI_SMBUS_DATA_SIZE; /* SMBus buffer is fixed-length */
        }

        if (AcpiGbl_DisplayRegionAccess)
        {
            AcpiOsPrintf ("AcpiExec: %s "
                "%s: Attr %X Addr %.4X BaseAddr %.4X Length %.2X BitWidth %X BufLen %X\n",
                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) && MyContext)
            {
                Status = AcpiBufferToResource (MyContext->Connection,
                    MyContext->Length, &Resource);
                if (ACPI_SUCCESS (Status))
                {
                    ACPI_FREE (Resource);
                }

                AcpiOsPrintf (" [AccessLength %.2X Connection %p]",
                    MyContext->AccessLength, MyContext->Connection);
            }

            AcpiOsPrintf ("\n");
        }

        DataBuffer = &Buffer[2];
        DataLength = (UINT8) Length;

        /* Setup the return buffer. Note: ASLTS depends on these fill values */

        if (Length == ACPI_MAX_GSBUS_DATA_SIZE)
        {
            DataLength = 0x20; /* For ASLTS only */
        }

        for (i = 0; i < Length; i++)
        {
            DataBuffer[i] = (UINT8) (0xA0 + i);
        }

        Buffer[0] = 0;                  /* Return Status, OK */
        Buffer[1] = DataLength;         /* Length of valid data */
        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] = ACPI_IPMI_DATA_SIZE;    /* 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 < ACPI_IPMI_BUFFER_SIZE; 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: Address %.4X Length %X BitWidth %X Conn %p\n",
                (Function & ACPI_IO_MASK) ? "Write" : "Read ",
                (UINT32) Address, Length, BitWidth, MyContext->Connection);
        }

        /* Now perform the "normal" SystemMemory handling, for AcpiExec only */
        break;

    /*
     * PCC operation region will write the entire subspace's data and expect
     * a response from the hardware. For acpiexec, we'll fill the buffer with
     * default values. Note: ASLTS will depend on these values.
     */
    case ACPI_ADR_SPACE_PLATFORM_COMM: /* ACPI 6.3 */

        if (AcpiGbl_DisplayRegionAccess)
        {
            AcpiOsPrintf ("AcpiExec: PCC Write : Addr %.4X Width %X\n",
                (UINT32) Address, BitWidth);
        }
        for (i = 0; i < Length; ++i)
        {
            Buffer[i] = (UINT8) i;
        }
        return (AE_OK);

    case ACPI_ADR_SPACE_PLATFORM_RT:

        AcpiOsPrintf ("Acpiexec: PRM %s invoked\n",
            (Function & ACPI_IO_MASK) ? "Write" : "Read ");

        if ((Function & ACPI_IO_MASK) == ACPI_WRITE)
        {
            AcpiUtConvertUuidToString((char *) Buffer + 10, Uuid);
            AcpiOsPrintf ("Mode: %u GUID: %s\n", Buffer[0], Uuid);
        }

        /* Unpack the input buffer and print the contents for debug */

        break;

    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 BitWidth %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_GSBUS:

            AcpiOsPrintf ("AcpiExec: GenericSerialBus\n");
            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: %.8X Addr %.4X BaseAddr %.4X Length %.2X "
                "BitWidth %X AccLen %.2X Conn %p\n",
                (Function & ACPI_IO_MASK) ? "Write" : "Read ", (UINT32) *Value,
                (UINT32) Address, (UINT32) BaseAddress, Length, BitWidth,
                MyContext->AccessLength, MyContext->Connection);
            if (ACPI_SUCCESS (Status))
            {
                ACPI_FREE (Resource);
            }
            break;

        default:

            AcpiOsPrintf ("AcpiExec: Region access on SpaceId %2.2X\n", SpaceId);
            break;
        }
    }

    return (AE_OK);
}
