Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. /******************************************************************************
  2.  *
  3.  * Module Name: evrgnini- ACPI AddressSpace (OpRegion) init
  4.  *
  5.  *****************************************************************************/
  6.  
  7. /******************************************************************************
  8.  *
  9.  * 1. Copyright Notice
  10.  *
  11.  * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp.
  12.  * All rights reserved.
  13.  *
  14.  * 2. License
  15.  *
  16.  * 2.1. This is your license from Intel Corp. under its intellectual property
  17.  * rights.  You may have additional license terms from the party that provided
  18.  * you this software, covering your right to use that party's intellectual
  19.  * property rights.
  20.  *
  21.  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
  22.  * copy of the source code appearing in this file ("Covered Code") an
  23.  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
  24.  * base code distributed originally by Intel ("Original Intel Code") to copy,
  25.  * make derivatives, distribute, use and display any portion of the Covered
  26.  * Code in any form, with the right to sublicense such rights; and
  27.  *
  28.  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
  29.  * license (with the right to sublicense), under only those claims of Intel
  30.  * patents that are infringed by the Original Intel Code, to make, use, sell,
  31.  * offer to sell, and import the Covered Code and derivative works thereof
  32.  * solely to the minimum extent necessary to exercise the above copyright
  33.  * license, and in no event shall the patent license extend to any additions
  34.  * to or modifications of the Original Intel Code.  No other license or right
  35.  * is granted directly or by implication, estoppel or otherwise;
  36.  *
  37.  * The above copyright and patent license is granted only if the following
  38.  * conditions are met:
  39.  *
  40.  * 3. Conditions
  41.  *
  42.  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
  43.  * Redistribution of source code of any substantial portion of the Covered
  44.  * Code or modification with rights to further distribute source must include
  45.  * the above Copyright Notice, the above License, this list of Conditions,
  46.  * and the following Disclaimer and Export Compliance provision.  In addition,
  47.  * Licensee must cause all Covered Code to which Licensee contributes to
  48.  * contain a file documenting the changes Licensee made to create that Covered
  49.  * Code and the date of any change.  Licensee must include in that file the
  50.  * documentation of any changes made by any predecessor Licensee.  Licensee
  51.  * must include a prominent statement that the modification is derived,
  52.  * directly or indirectly, from Original Intel Code.
  53.  *
  54.  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
  55.  * Redistribution of source code of any substantial portion of the Covered
  56.  * Code or modification without rights to further distribute source must
  57.  * include the following Disclaimer and Export Compliance provision in the
  58.  * documentation and/or other materials provided with distribution.  In
  59.  * addition, Licensee may not authorize further sublicense of source of any
  60.  * portion of the Covered Code, and must include terms to the effect that the
  61.  * license from Licensee to its licensee is limited to the intellectual
  62.  * property embodied in the software Licensee provides to its licensee, and
  63.  * not to intellectual property embodied in modifications its licensee may
  64.  * make.
  65.  *
  66.  * 3.3. Redistribution of Executable. Redistribution in executable form of any
  67.  * substantial portion of the Covered Code or modification must reproduce the
  68.  * above Copyright Notice, and the following Disclaimer and Export Compliance
  69.  * provision in the documentation and/or other materials provided with the
  70.  * distribution.
  71.  *
  72.  * 3.4. Intel retains all right, title, and interest in and to the Original
  73.  * Intel Code.
  74.  *
  75.  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
  76.  * Intel shall be used in advertising or otherwise to promote the sale, use or
  77.  * other dealings in products derived from or relating to the Covered Code
  78.  * without prior written authorization from Intel.
  79.  *
  80.  * 4. Disclaimer and Export Compliance
  81.  *
  82.  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
  83.  * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
  84.  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
  85.  * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
  86.  * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
  87.  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
  88.  * PARTICULAR PURPOSE.
  89.  *
  90.  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
  91.  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
  92.  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
  93.  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
  94.  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
  95.  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
  96.  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
  97.  * LIMITED REMEDY.
  98.  *
  99.  * 4.3. Licensee shall not export, either directly or indirectly, any of this
  100.  * software or system incorporating such software without first obtaining any
  101.  * required license or other approval from the U. S. Department of Commerce or
  102.  * any other agency or department of the United States Government.  In the
  103.  * event Licensee exports any such software from the United States or
  104.  * re-exports any such software from a foreign destination, Licensee shall
  105.  * ensure that the distribution and export/re-export of the software is in
  106.  * compliance with all laws, regulations, orders, or other restrictions of the
  107.  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
  108.  * any of its subsidiaries will export/re-export any technical data, process,
  109.  * software, or service, directly or indirectly, to any country for which the
  110.  * United States government or any agency thereof requires an export license,
  111.  * other governmental approval, or letter of assurance, without first obtaining
  112.  * such license, approval or letter.
  113.  *
  114.  *****************************************************************************/
  115.  
  116.  
  117. #define __EVRGNINI_C__
  118.  
  119. #include "acpi.h"
  120. #include "accommon.h"
  121. #include "acevents.h"
  122. #include "acnamesp.h"
  123.  
  124. #define _COMPONENT          ACPI_EVENTS
  125.         ACPI_MODULE_NAME    ("evrgnini")
  126.  
  127. /* Local prototypes */
  128.  
  129. static BOOLEAN
  130. AcpiEvIsPciRootBridge (
  131.     ACPI_NAMESPACE_NODE     *Node);
  132.  
  133.  
  134. /*******************************************************************************
  135.  *
  136.  * FUNCTION:    AcpiEvSystemMemoryRegionSetup
  137.  *
  138.  * PARAMETERS:  Handle              - Region we are interested in
  139.  *              Function            - Start or stop
  140.  *              HandlerContext      - Address space handler context
  141.  *              RegionContext       - Region specific context
  142.  *
  143.  * RETURN:      Status
  144.  *
  145.  * DESCRIPTION: Setup a SystemMemory operation region
  146.  *
  147.  ******************************************************************************/
  148.  
  149. ACPI_STATUS
  150. AcpiEvSystemMemoryRegionSetup (
  151.     ACPI_HANDLE             Handle,
  152.     UINT32                  Function,
  153.     void                    *HandlerContext,
  154.     void                    **RegionContext)
  155. {
  156.     ACPI_OPERAND_OBJECT     *RegionDesc = (ACPI_OPERAND_OBJECT *) Handle;
  157.     ACPI_MEM_SPACE_CONTEXT  *LocalRegionContext;
  158.  
  159.  
  160.     ACPI_FUNCTION_TRACE (EvSystemMemoryRegionSetup);
  161.  
  162.  
  163.     if (Function == ACPI_REGION_DEACTIVATE)
  164.     {
  165.         if (*RegionContext)
  166.         {
  167.             LocalRegionContext = (ACPI_MEM_SPACE_CONTEXT *) *RegionContext;
  168.  
  169.             /* Delete a cached mapping if present */
  170.  
  171.             if (LocalRegionContext->MappedLength)
  172.             {
  173.                 AcpiOsUnmapMemory (LocalRegionContext->MappedLogicalAddress,
  174.                     LocalRegionContext->MappedLength);
  175.             }
  176.             ACPI_FREE (LocalRegionContext);
  177.             *RegionContext = NULL;
  178.         }
  179.         return_ACPI_STATUS (AE_OK);
  180.     }
  181.  
  182.     /* Create a new context */
  183.  
  184.     LocalRegionContext = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_MEM_SPACE_CONTEXT));
  185.     if (!(LocalRegionContext))
  186.     {
  187.         return_ACPI_STATUS (AE_NO_MEMORY);
  188.     }
  189.  
  190.     /* Save the region length and address for use in the handler */
  191.  
  192.     LocalRegionContext->Length  = RegionDesc->Region.Length;
  193.     LocalRegionContext->Address = RegionDesc->Region.Address;
  194.  
  195.     *RegionContext = LocalRegionContext;
  196.     return_ACPI_STATUS (AE_OK);
  197. }
  198.  
  199.  
  200. /*******************************************************************************
  201.  *
  202.  * FUNCTION:    AcpiEvIoSpaceRegionSetup
  203.  *
  204.  * PARAMETERS:  Handle              - Region we are interested in
  205.  *              Function            - Start or stop
  206.  *              HandlerContext      - Address space handler context
  207.  *              RegionContext       - Region specific context
  208.  *
  209.  * RETURN:      Status
  210.  *
  211.  * DESCRIPTION: Setup a IO operation region
  212.  *
  213.  ******************************************************************************/
  214.  
  215. ACPI_STATUS
  216. AcpiEvIoSpaceRegionSetup (
  217.     ACPI_HANDLE             Handle,
  218.     UINT32                  Function,
  219.     void                    *HandlerContext,
  220.     void                    **RegionContext)
  221. {
  222.     ACPI_FUNCTION_TRACE (EvIoSpaceRegionSetup);
  223.  
  224.  
  225.     if (Function == ACPI_REGION_DEACTIVATE)
  226.     {
  227.         *RegionContext = NULL;
  228.     }
  229.     else
  230.     {
  231.         *RegionContext = HandlerContext;
  232.     }
  233.  
  234.     return_ACPI_STATUS (AE_OK);
  235. }
  236.  
  237.  
  238. /*******************************************************************************
  239.  *
  240.  * FUNCTION:    AcpiEvPciConfigRegionSetup
  241.  *
  242.  * PARAMETERS:  Handle              - Region we are interested in
  243.  *              Function            - Start or stop
  244.  *              HandlerContext      - Address space handler context
  245.  *              RegionContext       - Region specific context
  246.  *
  247.  * RETURN:      Status
  248.  *
  249.  * DESCRIPTION: Setup a PCI_Config operation region
  250.  *
  251.  * MUTEX:       Assumes namespace is not locked
  252.  *
  253.  ******************************************************************************/
  254.  
  255. ACPI_STATUS
  256. AcpiEvPciConfigRegionSetup (
  257.     ACPI_HANDLE             Handle,
  258.     UINT32                  Function,
  259.     void                    *HandlerContext,
  260.     void                    **RegionContext)
  261. {
  262.     ACPI_STATUS             Status = AE_OK;
  263.     UINT64                  PciValue;
  264.     ACPI_PCI_ID             *PciId = *RegionContext;
  265.     ACPI_OPERAND_OBJECT     *HandlerObj;
  266.     ACPI_NAMESPACE_NODE     *ParentNode;
  267.     ACPI_NAMESPACE_NODE     *PciRootNode;
  268.     ACPI_NAMESPACE_NODE     *PciDeviceNode;
  269.     ACPI_OPERAND_OBJECT     *RegionObj = (ACPI_OPERAND_OBJECT  *) Handle;
  270.  
  271.  
  272.     ACPI_FUNCTION_TRACE (EvPciConfigRegionSetup);
  273.  
  274.  
  275.     HandlerObj = RegionObj->Region.Handler;
  276.     if (!HandlerObj)
  277.     {
  278.         /*
  279.          * No installed handler. This shouldn't happen because the dispatch
  280.          * routine checks before we get here, but we check again just in case.
  281.          */
  282.         ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
  283.             "Attempting to init a region %p, with no handler\n", RegionObj));
  284.         return_ACPI_STATUS (AE_NOT_EXIST);
  285.     }
  286.  
  287.     *RegionContext = NULL;
  288.     if (Function == ACPI_REGION_DEACTIVATE)
  289.     {
  290.         if (PciId)
  291.         {
  292.             ACPI_FREE (PciId);
  293.         }
  294.         return_ACPI_STATUS (Status);
  295.     }
  296.  
  297.     ParentNode = RegionObj->Region.Node->Parent;
  298.  
  299.     /*
  300.      * Get the _SEG and _BBN values from the device upon which the handler
  301.      * is installed.
  302.      *
  303.      * We need to get the _SEG and _BBN objects relative to the PCI BUS device.
  304.      * This is the device the handler has been registered to handle.
  305.      */
  306.  
  307.     /*
  308.      * If the AddressSpace.Node is still pointing to the root, we need
  309.      * to scan upward for a PCI Root bridge and re-associate the OpRegion
  310.      * handlers with that device.
  311.      */
  312.     if (HandlerObj->AddressSpace.Node == AcpiGbl_RootNode)
  313.     {
  314.         /* Start search from the parent object */
  315.  
  316.         PciRootNode = ParentNode;
  317.         while (PciRootNode != AcpiGbl_RootNode)
  318.         {
  319.             /* Get the _HID/_CID in order to detect a RootBridge */
  320.  
  321.             if (AcpiEvIsPciRootBridge (PciRootNode))
  322.             {
  323.                 /* Install a handler for this PCI root bridge */
  324.  
  325.                 Status = AcpiInstallAddressSpaceHandler (
  326.                             (ACPI_HANDLE) PciRootNode,
  327.                             ACPI_ADR_SPACE_PCI_CONFIG,
  328.                             ACPI_DEFAULT_HANDLER, NULL, NULL);
  329.                 if (ACPI_FAILURE (Status))
  330.                 {
  331.                     if (Status == AE_SAME_HANDLER)
  332.                     {
  333.                         /*
  334.                          * It is OK if the handler is already installed on the
  335.                          * root bridge. Still need to return a context object
  336.                          * for the new PCI_Config operation region, however.
  337.                          */
  338.                         Status = AE_OK;
  339.                     }
  340.                     else
  341.                     {
  342.                         ACPI_EXCEPTION ((AE_INFO, Status,
  343.                             "Could not install PciConfig handler "
  344.                             "for Root Bridge %4.4s",
  345.                             AcpiUtGetNodeName (PciRootNode)));
  346.                     }
  347.                 }
  348.                 break;
  349.             }
  350.  
  351.             PciRootNode = PciRootNode->Parent;
  352.         }
  353.  
  354.         /* PCI root bridge not found, use namespace root node */
  355.     }
  356.     else
  357.     {
  358.         PciRootNode = HandlerObj->AddressSpace.Node;
  359.     }
  360.  
  361.     /*
  362.      * If this region is now initialized, we are done.
  363.      * (InstallAddressSpaceHandler could have initialized it)
  364.      */
  365.     if (RegionObj->Region.Flags & AOPOBJ_SETUP_COMPLETE)
  366.     {
  367.         return_ACPI_STATUS (AE_OK);
  368.     }
  369.  
  370.     /* Region is still not initialized. Create a new context */
  371.  
  372.     PciId = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_PCI_ID));
  373.     if (!PciId)
  374.     {
  375.         return_ACPI_STATUS (AE_NO_MEMORY);
  376.     }
  377.  
  378.     /*
  379.      * For PCI_Config space access, we need the segment, bus, device and
  380.      * function numbers. Acquire them here.
  381.      *
  382.      * Find the parent device object. (This allows the operation region to be
  383.      * within a subscope under the device, such as a control method.)
  384.      */
  385.     PciDeviceNode = RegionObj->Region.Node;
  386.     while (PciDeviceNode && (PciDeviceNode->Type != ACPI_TYPE_DEVICE))
  387.     {
  388.         PciDeviceNode = PciDeviceNode->Parent;
  389.     }
  390.  
  391.     if (!PciDeviceNode)
  392.     {
  393.         ACPI_FREE (PciId);
  394.         return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
  395.     }
  396.  
  397.     /*
  398.      * Get the PCI device and function numbers from the _ADR object contained
  399.      * in the parent's scope.
  400.      */
  401.     Status = AcpiUtEvaluateNumericObject (METHOD_NAME__ADR,
  402.                 PciDeviceNode, &PciValue);
  403.  
  404.     /*
  405.      * The default is zero, and since the allocation above zeroed the data,
  406.      * just do nothing on failure.
  407.      */
  408.     if (ACPI_SUCCESS (Status))
  409.     {
  410.         PciId->Device   = ACPI_HIWORD (ACPI_LODWORD (PciValue));
  411.         PciId->Function = ACPI_LOWORD (ACPI_LODWORD (PciValue));
  412.     }
  413.  
  414.     /* The PCI segment number comes from the _SEG method */
  415.  
  416.     Status = AcpiUtEvaluateNumericObject (METHOD_NAME__SEG,
  417.                 PciRootNode, &PciValue);
  418.     if (ACPI_SUCCESS (Status))
  419.     {
  420.         PciId->Segment = ACPI_LOWORD (PciValue);
  421.     }
  422.  
  423.     /* The PCI bus number comes from the _BBN method */
  424.  
  425.     Status = AcpiUtEvaluateNumericObject (METHOD_NAME__BBN,
  426.                 PciRootNode, &PciValue);
  427.     if (ACPI_SUCCESS (Status))
  428.     {
  429.         PciId->Bus = ACPI_LOWORD (PciValue);
  430.     }
  431.  
  432.     /* Complete this device's PciId */
  433.  
  434.     AcpiOsDerivePciId (PciRootNode, RegionObj->Region.Node, &PciId);
  435.  
  436.     *RegionContext = PciId;
  437.     return_ACPI_STATUS (AE_OK);
  438. }
  439.  
  440.  
  441. /*******************************************************************************
  442.  *
  443.  * FUNCTION:    AcpiEvIsPciRootBridge
  444.  *
  445.  * PARAMETERS:  Node            - Device node being examined
  446.  *
  447.  * RETURN:      TRUE if device is a PCI/PCI-Express Root Bridge
  448.  *
  449.  * DESCRIPTION: Determine if the input device represents a PCI Root Bridge by
  450.  *              examining the _HID and _CID for the device.
  451.  *
  452.  ******************************************************************************/
  453.  
  454. static BOOLEAN
  455. AcpiEvIsPciRootBridge (
  456.     ACPI_NAMESPACE_NODE     *Node)
  457. {
  458.     ACPI_STATUS             Status;
  459.     ACPI_DEVICE_ID          *Hid;
  460.     ACPI_DEVICE_ID_LIST     *Cid;
  461.     UINT32                  i;
  462.     BOOLEAN                 Match;
  463.  
  464.  
  465.     /* Get the _HID and check for a PCI Root Bridge */
  466.  
  467.     Status = AcpiUtExecute_HID (Node, &Hid);
  468.     if (ACPI_FAILURE (Status))
  469.     {
  470.         return (FALSE);
  471.     }
  472.  
  473.     Match = AcpiUtIsPciRootBridge (Hid->String);
  474.     ACPI_FREE (Hid);
  475.  
  476.     if (Match)
  477.     {
  478.         return (TRUE);
  479.     }
  480.  
  481.     /* The _HID did not match. Get the _CID and check for a PCI Root Bridge */
  482.  
  483.     Status = AcpiUtExecute_CID (Node, &Cid);
  484.     if (ACPI_FAILURE (Status))
  485.     {
  486.         return (FALSE);
  487.     }
  488.  
  489.     /* Check all _CIDs in the returned list */
  490.  
  491.     for (i = 0; i < Cid->Count; i++)
  492.     {
  493.         if (AcpiUtIsPciRootBridge (Cid->Ids[i].String))
  494.         {
  495.             ACPI_FREE (Cid);
  496.             return (TRUE);
  497.         }
  498.     }
  499.  
  500.     ACPI_FREE (Cid);
  501.     return (FALSE);
  502. }
  503.  
  504.  
  505. /*******************************************************************************
  506.  *
  507.  * FUNCTION:    AcpiEvPciBarRegionSetup
  508.  *
  509.  * PARAMETERS:  Handle              - Region we are interested in
  510.  *              Function            - Start or stop
  511.  *              HandlerContext      - Address space handler context
  512.  *              RegionContext       - Region specific context
  513.  *
  514.  * RETURN:      Status
  515.  *
  516.  * DESCRIPTION: Setup a PciBAR operation region
  517.  *
  518.  * MUTEX:       Assumes namespace is not locked
  519.  *
  520.  ******************************************************************************/
  521.  
  522. ACPI_STATUS
  523. AcpiEvPciBarRegionSetup (
  524.     ACPI_HANDLE             Handle,
  525.     UINT32                  Function,
  526.     void                    *HandlerContext,
  527.     void                    **RegionContext)
  528. {
  529.     ACPI_FUNCTION_TRACE (EvPciBarRegionSetup);
  530.  
  531.  
  532.     return_ACPI_STATUS (AE_OK);
  533. }
  534.  
  535.  
  536. /*******************************************************************************
  537.  *
  538.  * FUNCTION:    AcpiEvCmosRegionSetup
  539.  *
  540.  * PARAMETERS:  Handle              - Region we are interested in
  541.  *              Function            - Start or stop
  542.  *              HandlerContext      - Address space handler context
  543.  *              RegionContext       - Region specific context
  544.  *
  545.  * RETURN:      Status
  546.  *
  547.  * DESCRIPTION: Setup a CMOS operation region
  548.  *
  549.  * MUTEX:       Assumes namespace is not locked
  550.  *
  551.  ******************************************************************************/
  552.  
  553. ACPI_STATUS
  554. AcpiEvCmosRegionSetup (
  555.     ACPI_HANDLE             Handle,
  556.     UINT32                  Function,
  557.     void                    *HandlerContext,
  558.     void                    **RegionContext)
  559. {
  560.     ACPI_FUNCTION_TRACE (EvCmosRegionSetup);
  561.  
  562.  
  563.     return_ACPI_STATUS (AE_OK);
  564. }
  565.  
  566.  
  567. /*******************************************************************************
  568.  *
  569.  * FUNCTION:    AcpiEvDefaultRegionSetup
  570.  *
  571.  * PARAMETERS:  Handle              - Region we are interested in
  572.  *              Function            - Start or stop
  573.  *              HandlerContext      - Address space handler context
  574.  *              RegionContext       - Region specific context
  575.  *
  576.  * RETURN:      Status
  577.  *
  578.  * DESCRIPTION: Default region initialization
  579.  *
  580.  ******************************************************************************/
  581.  
  582. ACPI_STATUS
  583. AcpiEvDefaultRegionSetup (
  584.     ACPI_HANDLE             Handle,
  585.     UINT32                  Function,
  586.     void                    *HandlerContext,
  587.     void                    **RegionContext)
  588. {
  589.     ACPI_FUNCTION_TRACE (EvDefaultRegionSetup);
  590.  
  591.  
  592.     if (Function == ACPI_REGION_DEACTIVATE)
  593.     {
  594.         *RegionContext = NULL;
  595.     }
  596.     else
  597.     {
  598.         *RegionContext = HandlerContext;
  599.     }
  600.  
  601.     return_ACPI_STATUS (AE_OK);
  602. }
  603.  
  604.  
  605. /*******************************************************************************
  606.  *
  607.  * FUNCTION:    AcpiEvInitializeRegion
  608.  *
  609.  * PARAMETERS:  RegionObj       - Region we are initializing
  610.  *              AcpiNsLocked    - Is namespace locked?
  611.  *
  612.  * RETURN:      Status
  613.  *
  614.  * DESCRIPTION: Initializes the region, finds any _REG methods and saves them
  615.  *              for execution at a later time
  616.  *
  617.  *              Get the appropriate address space handler for a newly
  618.  *              created region.
  619.  *
  620.  *              This also performs address space specific initialization. For
  621.  *              example, PCI regions must have an _ADR object that contains
  622.  *              a PCI address in the scope of the definition. This address is
  623.  *              required to perform an access to PCI config space.
  624.  *
  625.  * MUTEX:       Interpreter should be unlocked, because we may run the _REG
  626.  *              method for this region.
  627.  *
  628.  ******************************************************************************/
  629.  
  630. ACPI_STATUS
  631. AcpiEvInitializeRegion (
  632.     ACPI_OPERAND_OBJECT     *RegionObj,
  633.     BOOLEAN                 AcpiNsLocked)
  634. {
  635.     ACPI_OPERAND_OBJECT     *HandlerObj;
  636.     ACPI_OPERAND_OBJECT     *ObjDesc;
  637.     ACPI_ADR_SPACE_TYPE     SpaceId;
  638.     ACPI_NAMESPACE_NODE     *Node;
  639.     ACPI_STATUS             Status;
  640.     ACPI_NAMESPACE_NODE     *MethodNode;
  641.     ACPI_NAME               *RegNamePtr = (ACPI_NAME *) METHOD_NAME__REG;
  642.     ACPI_OPERAND_OBJECT     *RegionObj2;
  643.  
  644.  
  645.     ACPI_FUNCTION_TRACE_U32 (EvInitializeRegion, AcpiNsLocked);
  646.  
  647.  
  648.     if (!RegionObj)
  649.     {
  650.         return_ACPI_STATUS (AE_BAD_PARAMETER);
  651.     }
  652.  
  653.     if (RegionObj->Common.Flags & AOPOBJ_OBJECT_INITIALIZED)
  654.     {
  655.         return_ACPI_STATUS (AE_OK);
  656.     }
  657.  
  658.     RegionObj2 = AcpiNsGetSecondaryObject (RegionObj);
  659.     if (!RegionObj2)
  660.     {
  661.         return_ACPI_STATUS (AE_NOT_EXIST);
  662.     }
  663.  
  664.     Node = RegionObj->Region.Node->Parent;
  665.     SpaceId = RegionObj->Region.SpaceId;
  666.  
  667.     /* Setup defaults */
  668.  
  669.     RegionObj->Region.Handler = NULL;
  670.     RegionObj2->Extra.Method_REG = NULL;
  671.     RegionObj->Common.Flags &= ~(AOPOBJ_SETUP_COMPLETE);
  672.     RegionObj->Common.Flags |= AOPOBJ_OBJECT_INITIALIZED;
  673.  
  674.     /* Find any "_REG" method associated with this region definition */
  675.  
  676.     Status = AcpiNsSearchOneScope (
  677.                 *RegNamePtr, Node, ACPI_TYPE_METHOD, &MethodNode);
  678.     if (ACPI_SUCCESS (Status))
  679.     {
  680.         /*
  681.          * The _REG method is optional and there can be only one per region
  682.          * definition. This will be executed when the handler is attached
  683.          * or removed
  684.          */
  685.         RegionObj2->Extra.Method_REG = MethodNode;
  686.     }
  687.  
  688.     /*
  689.      * The following loop depends upon the root Node having no parent
  690.      * ie: AcpiGbl_RootNode->ParentEntry being set to NULL
  691.      */
  692.     while (Node)
  693.     {
  694.         /* Check to see if a handler exists */
  695.  
  696.         HandlerObj = NULL;
  697.         ObjDesc = AcpiNsGetAttachedObject (Node);
  698.         if (ObjDesc)
  699.         {
  700.             /* Can only be a handler if the object exists */
  701.  
  702.             switch (Node->Type)
  703.             {
  704.             case ACPI_TYPE_DEVICE:
  705.  
  706.                 HandlerObj = ObjDesc->Device.Handler;
  707.                 break;
  708.  
  709.             case ACPI_TYPE_PROCESSOR:
  710.  
  711.                 HandlerObj = ObjDesc->Processor.Handler;
  712.                 break;
  713.  
  714.             case ACPI_TYPE_THERMAL:
  715.  
  716.                 HandlerObj = ObjDesc->ThermalZone.Handler;
  717.                 break;
  718.  
  719.             case ACPI_TYPE_METHOD:
  720.                 /*
  721.                  * If we are executing module level code, the original
  722.                  * Node's object was replaced by this Method object and we
  723.                  * saved the handler in the method object.
  724.                  *
  725.                  * See AcpiNsExecModuleCode
  726.                  */
  727.                 if (ObjDesc->Method.Flags & AOPOBJ_MODULE_LEVEL)
  728.                 {
  729.                     HandlerObj = ObjDesc->Method.Extra.Handler;
  730.                 }
  731.                 break;
  732.  
  733.             default:
  734.                 /* Ignore other objects */
  735.                 break;
  736.             }
  737.  
  738.             while (HandlerObj)
  739.             {
  740.                 /* Is this handler of the correct type? */
  741.  
  742.                 if (HandlerObj->AddressSpace.SpaceId == SpaceId)
  743.                 {
  744.                     /* Found correct handler */
  745.  
  746.                     ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
  747.                         "Found handler %p for region %p in obj %p\n",
  748.                         HandlerObj, RegionObj, ObjDesc));
  749.  
  750.                     Status = AcpiEvAttachRegion (HandlerObj, RegionObj,
  751.                                 AcpiNsLocked);
  752.  
  753.                     /*
  754.                      * Tell all users that this region is usable by
  755.                      * running the _REG method
  756.                      */
  757.                     if (AcpiNsLocked)
  758.                     {
  759.                         Status = AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
  760.                         if (ACPI_FAILURE (Status))
  761.                         {
  762.                             return_ACPI_STATUS (Status);
  763.                         }
  764.                     }
  765.  
  766.                     Status = AcpiEvExecuteRegMethod (RegionObj, 1);
  767.  
  768.                     if (AcpiNsLocked)
  769.                     {
  770.                         Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
  771.                         if (ACPI_FAILURE (Status))
  772.                         {
  773.                             return_ACPI_STATUS (Status);
  774.                         }
  775.                     }
  776.  
  777.                     return_ACPI_STATUS (AE_OK);
  778.                 }
  779.  
  780.                 /* Try next handler in the list */
  781.  
  782.                 HandlerObj = HandlerObj->AddressSpace.Next;
  783.             }
  784.         }
  785.  
  786.         /* This node does not have the handler we need; Pop up one level */
  787.  
  788.         Node = Node->Parent;
  789.     }
  790.  
  791.     /* If we get here, there is no handler for this region */
  792.  
  793.     ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
  794.         "No handler for RegionType %s(%X) (RegionObj %p)\n",
  795.         AcpiUtGetRegionName (SpaceId), SpaceId, RegionObj));
  796.  
  797.     return_ACPI_STATUS (AE_NOT_EXIST);
  798. }
  799.  
  800.