xref: /titanic_52/usr/src/uts/intel/io/acpica/events/evrgnini.c (revision 385cc6b4ad1792caef3f84eb61eed3f27085801f)
1ae115bc7Smrj /******************************************************************************
2ae115bc7Smrj  *
3ae115bc7Smrj  * Module Name: evrgnini- ACPI AddressSpace (OpRegion) init
4ae115bc7Smrj  *
5ae115bc7Smrj  *****************************************************************************/
6ae115bc7Smrj 
726f3cdf0SGordon Ross /*
8*385cc6b4SJerry Jelinek  * Copyright (C) 2000 - 2016, Intel Corp.
9ae115bc7Smrj  * All rights reserved.
10ae115bc7Smrj  *
1126f3cdf0SGordon Ross  * Redistribution and use in source and binary forms, with or without
1226f3cdf0SGordon Ross  * modification, are permitted provided that the following conditions
1326f3cdf0SGordon Ross  * are met:
1426f3cdf0SGordon Ross  * 1. Redistributions of source code must retain the above copyright
1526f3cdf0SGordon Ross  *    notice, this list of conditions, and the following disclaimer,
1626f3cdf0SGordon Ross  *    without modification.
1726f3cdf0SGordon Ross  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
1826f3cdf0SGordon Ross  *    substantially similar to the "NO WARRANTY" disclaimer below
1926f3cdf0SGordon Ross  *    ("Disclaimer") and any redistribution must be conditioned upon
2026f3cdf0SGordon Ross  *    including a substantially similar Disclaimer requirement for further
2126f3cdf0SGordon Ross  *    binary redistribution.
2226f3cdf0SGordon Ross  * 3. Neither the names of the above-listed copyright holders nor the names
2326f3cdf0SGordon Ross  *    of any contributors may be used to endorse or promote products derived
2426f3cdf0SGordon Ross  *    from this software without specific prior written permission.
25ae115bc7Smrj  *
2626f3cdf0SGordon Ross  * Alternatively, this software may be distributed under the terms of the
2726f3cdf0SGordon Ross  * GNU General Public License ("GPL") version 2 as published by the Free
2826f3cdf0SGordon Ross  * Software Foundation.
29ae115bc7Smrj  *
3026f3cdf0SGordon Ross  * NO WARRANTY
3126f3cdf0SGordon Ross  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
3226f3cdf0SGordon Ross  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
3326f3cdf0SGordon Ross  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
3426f3cdf0SGordon Ross  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
3526f3cdf0SGordon Ross  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
3626f3cdf0SGordon Ross  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
3726f3cdf0SGordon Ross  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
3826f3cdf0SGordon Ross  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
3926f3cdf0SGordon Ross  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
4026f3cdf0SGordon Ross  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
4126f3cdf0SGordon Ross  * POSSIBILITY OF SUCH DAMAGES.
4226f3cdf0SGordon Ross  */
43ae115bc7Smrj 
44ae115bc7Smrj #include "acpi.h"
45aa2aa9a6SDana Myers #include "accommon.h"
46ae115bc7Smrj #include "acevents.h"
47ae115bc7Smrj #include "acnamesp.h"
48ae115bc7Smrj 
49ae115bc7Smrj #define _COMPONENT          ACPI_EVENTS
50ae115bc7Smrj         ACPI_MODULE_NAME    ("evrgnini")
51ae115bc7Smrj 
52db2bae30SDana Myers /* Local prototypes */
53db2bae30SDana Myers 
54db2bae30SDana Myers static BOOLEAN
55db2bae30SDana Myers AcpiEvIsPciRootBridge (
56db2bae30SDana Myers     ACPI_NAMESPACE_NODE     *Node);
57db2bae30SDana Myers 
58ae115bc7Smrj 
59ae115bc7Smrj /*******************************************************************************
60ae115bc7Smrj  *
61ae115bc7Smrj  * FUNCTION:    AcpiEvSystemMemoryRegionSetup
62ae115bc7Smrj  *
63ae115bc7Smrj  * PARAMETERS:  Handle              - Region we are interested in
64ae115bc7Smrj  *              Function            - Start or stop
65ae115bc7Smrj  *              HandlerContext      - Address space handler context
66ae115bc7Smrj  *              RegionContext       - Region specific context
67ae115bc7Smrj  *
68ae115bc7Smrj  * RETURN:      Status
69ae115bc7Smrj  *
70ae115bc7Smrj  * DESCRIPTION: Setup a SystemMemory operation region
71ae115bc7Smrj  *
72ae115bc7Smrj  ******************************************************************************/
73ae115bc7Smrj 
74ae115bc7Smrj ACPI_STATUS
75ae115bc7Smrj AcpiEvSystemMemoryRegionSetup (
76ae115bc7Smrj     ACPI_HANDLE             Handle,
77ae115bc7Smrj     UINT32                  Function,
78ae115bc7Smrj     void                    *HandlerContext,
79ae115bc7Smrj     void                    **RegionContext)
80ae115bc7Smrj {
81ae115bc7Smrj     ACPI_OPERAND_OBJECT     *RegionDesc = (ACPI_OPERAND_OBJECT *) Handle;
82ae115bc7Smrj     ACPI_MEM_SPACE_CONTEXT  *LocalRegionContext;
83ae115bc7Smrj 
84ae115bc7Smrj 
85ae115bc7Smrj     ACPI_FUNCTION_TRACE (EvSystemMemoryRegionSetup);
86ae115bc7Smrj 
87ae115bc7Smrj 
88ae115bc7Smrj     if (Function == ACPI_REGION_DEACTIVATE)
89ae115bc7Smrj     {
90ae115bc7Smrj         if (*RegionContext)
91ae115bc7Smrj         {
92ae115bc7Smrj             LocalRegionContext = (ACPI_MEM_SPACE_CONTEXT *) *RegionContext;
93ae115bc7Smrj 
94ae115bc7Smrj             /* Delete a cached mapping if present */
95ae115bc7Smrj 
96ae115bc7Smrj             if (LocalRegionContext->MappedLength)
97ae115bc7Smrj             {
98ae115bc7Smrj                 AcpiOsUnmapMemory (LocalRegionContext->MappedLogicalAddress,
99ae115bc7Smrj                     LocalRegionContext->MappedLength);
100ae115bc7Smrj             }
101ae115bc7Smrj             ACPI_FREE (LocalRegionContext);
102ae115bc7Smrj             *RegionContext = NULL;
103ae115bc7Smrj         }
104ae115bc7Smrj         return_ACPI_STATUS (AE_OK);
105ae115bc7Smrj     }
106ae115bc7Smrj 
107ae115bc7Smrj     /* Create a new context */
108ae115bc7Smrj 
109ae115bc7Smrj     LocalRegionContext = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_MEM_SPACE_CONTEXT));
110ae115bc7Smrj     if (!(LocalRegionContext))
111ae115bc7Smrj     {
112ae115bc7Smrj         return_ACPI_STATUS (AE_NO_MEMORY);
113ae115bc7Smrj     }
114ae115bc7Smrj 
115ae115bc7Smrj     /* Save the region length and address for use in the handler */
116ae115bc7Smrj 
117ae115bc7Smrj     LocalRegionContext->Length  = RegionDesc->Region.Length;
118ae115bc7Smrj     LocalRegionContext->Address = RegionDesc->Region.Address;
119ae115bc7Smrj 
120ae115bc7Smrj     *RegionContext = LocalRegionContext;
121ae115bc7Smrj     return_ACPI_STATUS (AE_OK);
122ae115bc7Smrj }
123ae115bc7Smrj 
124ae115bc7Smrj 
125ae115bc7Smrj /*******************************************************************************
126ae115bc7Smrj  *
127ae115bc7Smrj  * FUNCTION:    AcpiEvIoSpaceRegionSetup
128ae115bc7Smrj  *
129ae115bc7Smrj  * PARAMETERS:  Handle              - Region we are interested in
130ae115bc7Smrj  *              Function            - Start or stop
131ae115bc7Smrj  *              HandlerContext      - Address space handler context
132ae115bc7Smrj  *              RegionContext       - Region specific context
133ae115bc7Smrj  *
134ae115bc7Smrj  * RETURN:      Status
135ae115bc7Smrj  *
136ae115bc7Smrj  * DESCRIPTION: Setup a IO operation region
137ae115bc7Smrj  *
138ae115bc7Smrj  ******************************************************************************/
139ae115bc7Smrj 
140ae115bc7Smrj ACPI_STATUS
141ae115bc7Smrj AcpiEvIoSpaceRegionSetup (
142ae115bc7Smrj     ACPI_HANDLE             Handle,
143ae115bc7Smrj     UINT32                  Function,
144ae115bc7Smrj     void                    *HandlerContext,
145ae115bc7Smrj     void                    **RegionContext)
146ae115bc7Smrj {
147ae115bc7Smrj     ACPI_FUNCTION_TRACE (EvIoSpaceRegionSetup);
148ae115bc7Smrj 
149ae115bc7Smrj 
150ae115bc7Smrj     if (Function == ACPI_REGION_DEACTIVATE)
151ae115bc7Smrj     {
152ae115bc7Smrj         *RegionContext = NULL;
153ae115bc7Smrj     }
154ae115bc7Smrj     else
155ae115bc7Smrj     {
156ae115bc7Smrj         *RegionContext = HandlerContext;
157ae115bc7Smrj     }
158ae115bc7Smrj 
159ae115bc7Smrj     return_ACPI_STATUS (AE_OK);
160ae115bc7Smrj }
161ae115bc7Smrj 
162ae115bc7Smrj 
163ae115bc7Smrj /*******************************************************************************
164ae115bc7Smrj  *
165ae115bc7Smrj  * FUNCTION:    AcpiEvPciConfigRegionSetup
166ae115bc7Smrj  *
167ae115bc7Smrj  * PARAMETERS:  Handle              - Region we are interested in
168ae115bc7Smrj  *              Function            - Start or stop
169ae115bc7Smrj  *              HandlerContext      - Address space handler context
170ae115bc7Smrj  *              RegionContext       - Region specific context
171ae115bc7Smrj  *
172ae115bc7Smrj  * RETURN:      Status
173ae115bc7Smrj  *
174ae115bc7Smrj  * DESCRIPTION: Setup a PCI_Config operation region
175ae115bc7Smrj  *
176ae115bc7Smrj  * MUTEX:       Assumes namespace is not locked
177ae115bc7Smrj  *
178ae115bc7Smrj  ******************************************************************************/
179ae115bc7Smrj 
180ae115bc7Smrj ACPI_STATUS
181ae115bc7Smrj AcpiEvPciConfigRegionSetup (
182ae115bc7Smrj     ACPI_HANDLE             Handle,
183ae115bc7Smrj     UINT32                  Function,
184ae115bc7Smrj     void                    *HandlerContext,
185ae115bc7Smrj     void                    **RegionContext)
186ae115bc7Smrj {
187ae115bc7Smrj     ACPI_STATUS             Status = AE_OK;
18826f3cdf0SGordon Ross     UINT64                  PciValue;
189ae115bc7Smrj     ACPI_PCI_ID             *PciId = *RegionContext;
190ae115bc7Smrj     ACPI_OPERAND_OBJECT     *HandlerObj;
191ae115bc7Smrj     ACPI_NAMESPACE_NODE     *ParentNode;
192ae115bc7Smrj     ACPI_NAMESPACE_NODE     *PciRootNode;
193db2bae30SDana Myers     ACPI_NAMESPACE_NODE     *PciDeviceNode;
194ae115bc7Smrj     ACPI_OPERAND_OBJECT     *RegionObj = (ACPI_OPERAND_OBJECT  *) Handle;
195ae115bc7Smrj 
196ae115bc7Smrj 
197ae115bc7Smrj     ACPI_FUNCTION_TRACE (EvPciConfigRegionSetup);
198ae115bc7Smrj 
199ae115bc7Smrj 
200ae115bc7Smrj     HandlerObj = RegionObj->Region.Handler;
201ae115bc7Smrj     if (!HandlerObj)
202ae115bc7Smrj     {
203ae115bc7Smrj         /*
204ae115bc7Smrj          * No installed handler. This shouldn't happen because the dispatch
205ae115bc7Smrj          * routine checks before we get here, but we check again just in case.
206ae115bc7Smrj          */
207ae115bc7Smrj         ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
208ae115bc7Smrj             "Attempting to init a region %p, with no handler\n", RegionObj));
209ae115bc7Smrj         return_ACPI_STATUS (AE_NOT_EXIST);
210ae115bc7Smrj     }
211ae115bc7Smrj 
212ae115bc7Smrj     *RegionContext = NULL;
213ae115bc7Smrj     if (Function == ACPI_REGION_DEACTIVATE)
214ae115bc7Smrj     {
215ae115bc7Smrj         if (PciId)
216ae115bc7Smrj         {
217ae115bc7Smrj             ACPI_FREE (PciId);
218ae115bc7Smrj         }
219ae115bc7Smrj         return_ACPI_STATUS (Status);
220ae115bc7Smrj     }
221ae115bc7Smrj 
22226f3cdf0SGordon Ross     ParentNode = RegionObj->Region.Node->Parent;
223ae115bc7Smrj 
224ae115bc7Smrj     /*
225ae115bc7Smrj      * Get the _SEG and _BBN values from the device upon which the handler
226ae115bc7Smrj      * is installed.
227ae115bc7Smrj      *
228ae115bc7Smrj      * We need to get the _SEG and _BBN objects relative to the PCI BUS device.
229ae115bc7Smrj      * This is the device the handler has been registered to handle.
230ae115bc7Smrj      */
231ae115bc7Smrj 
232ae115bc7Smrj     /*
233ae115bc7Smrj      * If the AddressSpace.Node is still pointing to the root, we need
234ae115bc7Smrj      * to scan upward for a PCI Root bridge and re-associate the OpRegion
235ae115bc7Smrj      * handlers with that device.
236ae115bc7Smrj      */
237ae115bc7Smrj     if (HandlerObj->AddressSpace.Node == AcpiGbl_RootNode)
238ae115bc7Smrj     {
239ae115bc7Smrj         /* Start search from the parent object */
240ae115bc7Smrj 
241ae115bc7Smrj         PciRootNode = ParentNode;
242ae115bc7Smrj         while (PciRootNode != AcpiGbl_RootNode)
243ae115bc7Smrj         {
244db2bae30SDana Myers             /* Get the _HID/_CID in order to detect a RootBridge */
245db2bae30SDana Myers 
246db2bae30SDana Myers             if (AcpiEvIsPciRootBridge (PciRootNode))
247ae115bc7Smrj             {
248ae115bc7Smrj                 /* Install a handler for this PCI root bridge */
249ae115bc7Smrj 
250db2bae30SDana Myers                 Status = AcpiInstallAddressSpaceHandler (
251db2bae30SDana Myers                     (ACPI_HANDLE) PciRootNode,
252ae115bc7Smrj                     ACPI_ADR_SPACE_PCI_CONFIG,
253ae115bc7Smrj                     ACPI_DEFAULT_HANDLER, NULL, NULL);
254ae115bc7Smrj                 if (ACPI_FAILURE (Status))
255ae115bc7Smrj                 {
256ae115bc7Smrj                     if (Status == AE_SAME_HANDLER)
257ae115bc7Smrj                     {
258ae115bc7Smrj                         /*
259aa2aa9a6SDana Myers                          * It is OK if the handler is already installed on the
260aa2aa9a6SDana Myers                          * root bridge. Still need to return a context object
261aa2aa9a6SDana Myers                          * for the new PCI_Config operation region, however.
262ae115bc7Smrj                          */
263ae115bc7Smrj                         Status = AE_OK;
264ae115bc7Smrj                     }
265ae115bc7Smrj                     else
266ae115bc7Smrj                     {
267ae115bc7Smrj                         ACPI_EXCEPTION ((AE_INFO, Status,
268aa2aa9a6SDana Myers                             "Could not install PciConfig handler "
269aa2aa9a6SDana Myers                             "for Root Bridge %4.4s",
270ae115bc7Smrj                             AcpiUtGetNodeName (PciRootNode)));
271ae115bc7Smrj                     }
272ae115bc7Smrj                 }
273ae115bc7Smrj                 break;
274ae115bc7Smrj             }
275ae115bc7Smrj 
27626f3cdf0SGordon Ross             PciRootNode = PciRootNode->Parent;
277ae115bc7Smrj         }
278ae115bc7Smrj 
279ae115bc7Smrj         /* PCI root bridge not found, use namespace root node */
280ae115bc7Smrj     }
281ae115bc7Smrj     else
282ae115bc7Smrj     {
283ae115bc7Smrj         PciRootNode = HandlerObj->AddressSpace.Node;
284ae115bc7Smrj     }
285ae115bc7Smrj 
286ae115bc7Smrj     /*
287ae115bc7Smrj      * If this region is now initialized, we are done.
288ae115bc7Smrj      * (InstallAddressSpaceHandler could have initialized it)
289ae115bc7Smrj      */
290ae115bc7Smrj     if (RegionObj->Region.Flags & AOPOBJ_SETUP_COMPLETE)
291ae115bc7Smrj     {
292ae115bc7Smrj         return_ACPI_STATUS (AE_OK);
293ae115bc7Smrj     }
294ae115bc7Smrj 
295ae115bc7Smrj     /* Region is still not initialized. Create a new context */
296ae115bc7Smrj 
297ae115bc7Smrj     PciId = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_PCI_ID));
298ae115bc7Smrj     if (!PciId)
299ae115bc7Smrj     {
300ae115bc7Smrj         return_ACPI_STATUS (AE_NO_MEMORY);
301ae115bc7Smrj     }
302ae115bc7Smrj 
303ae115bc7Smrj     /*
304aa2aa9a6SDana Myers      * For PCI_Config space access, we need the segment, bus, device and
305aa2aa9a6SDana Myers      * function numbers. Acquire them here.
306db2bae30SDana Myers      *
307db2bae30SDana Myers      * Find the parent device object. (This allows the operation region to be
308db2bae30SDana Myers      * within a subscope under the device, such as a control method.)
309ae115bc7Smrj      */
310db2bae30SDana Myers     PciDeviceNode = RegionObj->Region.Node;
311db2bae30SDana Myers     while (PciDeviceNode && (PciDeviceNode->Type != ACPI_TYPE_DEVICE))
312db2bae30SDana Myers     {
31326f3cdf0SGordon Ross         PciDeviceNode = PciDeviceNode->Parent;
314db2bae30SDana Myers     }
315db2bae30SDana Myers 
316db2bae30SDana Myers     if (!PciDeviceNode)
317db2bae30SDana Myers     {
318db2bae30SDana Myers         ACPI_FREE (PciId);
319db2bae30SDana Myers         return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
320db2bae30SDana Myers     }
321ae115bc7Smrj 
322ae115bc7Smrj     /*
32326f3cdf0SGordon Ross      * Get the PCI device and function numbers from the _ADR object
32426f3cdf0SGordon Ross      * contained in the parent's scope.
325ae115bc7Smrj      */
326aa2aa9a6SDana Myers     Status = AcpiUtEvaluateNumericObject (METHOD_NAME__ADR,
327aa2aa9a6SDana Myers         PciDeviceNode, &PciValue);
328ae115bc7Smrj 
329ae115bc7Smrj     /*
330aa2aa9a6SDana Myers      * The default is zero, and since the allocation above zeroed the data,
331aa2aa9a6SDana Myers      * just do nothing on failure.
332ae115bc7Smrj      */
333ae115bc7Smrj     if (ACPI_SUCCESS (Status))
334ae115bc7Smrj     {
335ae115bc7Smrj         PciId->Device   = ACPI_HIWORD (ACPI_LODWORD (PciValue));
336ae115bc7Smrj         PciId->Function = ACPI_LOWORD (ACPI_LODWORD (PciValue));
337ae115bc7Smrj     }
338ae115bc7Smrj 
339ae115bc7Smrj     /* The PCI segment number comes from the _SEG method */
340ae115bc7Smrj 
341aa2aa9a6SDana Myers     Status = AcpiUtEvaluateNumericObject (METHOD_NAME__SEG,
342aa2aa9a6SDana Myers         PciRootNode, &PciValue);
343ae115bc7Smrj     if (ACPI_SUCCESS (Status))
344ae115bc7Smrj     {
345ae115bc7Smrj         PciId->Segment = ACPI_LOWORD (PciValue);
346ae115bc7Smrj     }
347ae115bc7Smrj 
348ae115bc7Smrj     /* The PCI bus number comes from the _BBN method */
349ae115bc7Smrj 
350aa2aa9a6SDana Myers     Status = AcpiUtEvaluateNumericObject (METHOD_NAME__BBN,
351aa2aa9a6SDana Myers         PciRootNode, &PciValue);
352ae115bc7Smrj     if (ACPI_SUCCESS (Status))
353ae115bc7Smrj     {
354ae115bc7Smrj         PciId->Bus = ACPI_LOWORD (PciValue);
355ae115bc7Smrj     }
356ae115bc7Smrj 
35726f3cdf0SGordon Ross     /* Complete/update the PCI ID for this device */
358ae115bc7Smrj 
35926f3cdf0SGordon Ross     Status = AcpiHwDerivePciId (PciId, PciRootNode, RegionObj->Region.Node);
36026f3cdf0SGordon Ross     if (ACPI_FAILURE (Status))
36126f3cdf0SGordon Ross     {
36226f3cdf0SGordon Ross         ACPI_FREE (PciId);
36326f3cdf0SGordon Ross         return_ACPI_STATUS (Status);
36426f3cdf0SGordon Ross     }
365ae115bc7Smrj 
366ae115bc7Smrj     *RegionContext = PciId;
367ae115bc7Smrj     return_ACPI_STATUS (AE_OK);
368ae115bc7Smrj }
369ae115bc7Smrj 
370ae115bc7Smrj 
371ae115bc7Smrj /*******************************************************************************
372ae115bc7Smrj  *
373db2bae30SDana Myers  * FUNCTION:    AcpiEvIsPciRootBridge
374db2bae30SDana Myers  *
375db2bae30SDana Myers  * PARAMETERS:  Node            - Device node being examined
376db2bae30SDana Myers  *
377db2bae30SDana Myers  * RETURN:      TRUE if device is a PCI/PCI-Express Root Bridge
378db2bae30SDana Myers  *
379db2bae30SDana Myers  * DESCRIPTION: Determine if the input device represents a PCI Root Bridge by
380db2bae30SDana Myers  *              examining the _HID and _CID for the device.
381db2bae30SDana Myers  *
382db2bae30SDana Myers  ******************************************************************************/
383db2bae30SDana Myers 
384db2bae30SDana Myers static BOOLEAN
385db2bae30SDana Myers AcpiEvIsPciRootBridge (
386db2bae30SDana Myers     ACPI_NAMESPACE_NODE     *Node)
387db2bae30SDana Myers {
388db2bae30SDana Myers     ACPI_STATUS             Status;
389*385cc6b4SJerry Jelinek     ACPI_PNP_DEVICE_ID      *Hid;
390*385cc6b4SJerry Jelinek     ACPI_PNP_DEVICE_ID_LIST *Cid;
391db2bae30SDana Myers     UINT32                  i;
39257190917SDana Myers     BOOLEAN                 Match;
393db2bae30SDana Myers 
394db2bae30SDana Myers 
395aa2aa9a6SDana Myers     /* Get the _HID and check for a PCI Root Bridge */
396aa2aa9a6SDana Myers 
397db2bae30SDana Myers     Status = AcpiUtExecute_HID (Node, &Hid);
398db2bae30SDana Myers     if (ACPI_FAILURE (Status))
399db2bae30SDana Myers     {
400db2bae30SDana Myers         return (FALSE);
401db2bae30SDana Myers     }
402db2bae30SDana Myers 
40357190917SDana Myers     Match = AcpiUtIsPciRootBridge (Hid->String);
40457190917SDana Myers     ACPI_FREE (Hid);
40557190917SDana Myers 
40657190917SDana Myers     if (Match)
407db2bae30SDana Myers     {
408db2bae30SDana Myers         return (TRUE);
409db2bae30SDana Myers     }
410db2bae30SDana Myers 
411aa2aa9a6SDana Myers     /* The _HID did not match. Get the _CID and check for a PCI Root Bridge */
412aa2aa9a6SDana Myers 
413db2bae30SDana Myers     Status = AcpiUtExecute_CID (Node, &Cid);
414db2bae30SDana Myers     if (ACPI_FAILURE (Status))
415db2bae30SDana Myers     {
416db2bae30SDana Myers         return (FALSE);
417db2bae30SDana Myers     }
418db2bae30SDana Myers 
419db2bae30SDana Myers     /* Check all _CIDs in the returned list */
420db2bae30SDana Myers 
421db2bae30SDana Myers     for (i = 0; i < Cid->Count; i++)
422db2bae30SDana Myers     {
42357190917SDana Myers         if (AcpiUtIsPciRootBridge (Cid->Ids[i].String))
424db2bae30SDana Myers         {
425db2bae30SDana Myers             ACPI_FREE (Cid);
426db2bae30SDana Myers             return (TRUE);
427db2bae30SDana Myers         }
428db2bae30SDana Myers     }
429db2bae30SDana Myers 
430db2bae30SDana Myers     ACPI_FREE (Cid);
431db2bae30SDana Myers     return (FALSE);
432db2bae30SDana Myers }
433db2bae30SDana Myers 
434db2bae30SDana Myers 
435db2bae30SDana Myers /*******************************************************************************
436db2bae30SDana Myers  *
437ae115bc7Smrj  * FUNCTION:    AcpiEvPciBarRegionSetup
438ae115bc7Smrj  *
439ae115bc7Smrj  * PARAMETERS:  Handle              - Region we are interested in
440ae115bc7Smrj  *              Function            - Start or stop
441ae115bc7Smrj  *              HandlerContext      - Address space handler context
442ae115bc7Smrj  *              RegionContext       - Region specific context
443ae115bc7Smrj  *
444ae115bc7Smrj  * RETURN:      Status
445ae115bc7Smrj  *
446ae115bc7Smrj  * DESCRIPTION: Setup a PciBAR operation region
447ae115bc7Smrj  *
448ae115bc7Smrj  * MUTEX:       Assumes namespace is not locked
449ae115bc7Smrj  *
450ae115bc7Smrj  ******************************************************************************/
451ae115bc7Smrj 
452ae115bc7Smrj ACPI_STATUS
453ae115bc7Smrj AcpiEvPciBarRegionSetup (
454ae115bc7Smrj     ACPI_HANDLE             Handle,
455ae115bc7Smrj     UINT32                  Function,
456ae115bc7Smrj     void                    *HandlerContext,
457ae115bc7Smrj     void                    **RegionContext)
458ae115bc7Smrj {
459ae115bc7Smrj     ACPI_FUNCTION_TRACE (EvPciBarRegionSetup);
460ae115bc7Smrj 
461ae115bc7Smrj 
462ae115bc7Smrj     return_ACPI_STATUS (AE_OK);
463ae115bc7Smrj }
464ae115bc7Smrj 
465ae115bc7Smrj 
466ae115bc7Smrj /*******************************************************************************
467ae115bc7Smrj  *
468ae115bc7Smrj  * FUNCTION:    AcpiEvCmosRegionSetup
469ae115bc7Smrj  *
470ae115bc7Smrj  * PARAMETERS:  Handle              - Region we are interested in
471ae115bc7Smrj  *              Function            - Start or stop
472ae115bc7Smrj  *              HandlerContext      - Address space handler context
473ae115bc7Smrj  *              RegionContext       - Region specific context
474ae115bc7Smrj  *
475ae115bc7Smrj  * RETURN:      Status
476ae115bc7Smrj  *
477ae115bc7Smrj  * DESCRIPTION: Setup a CMOS operation region
478ae115bc7Smrj  *
479ae115bc7Smrj  * MUTEX:       Assumes namespace is not locked
480ae115bc7Smrj  *
481ae115bc7Smrj  ******************************************************************************/
482ae115bc7Smrj 
483ae115bc7Smrj ACPI_STATUS
484ae115bc7Smrj AcpiEvCmosRegionSetup (
485ae115bc7Smrj     ACPI_HANDLE             Handle,
486ae115bc7Smrj     UINT32                  Function,
487ae115bc7Smrj     void                    *HandlerContext,
488ae115bc7Smrj     void                    **RegionContext)
489ae115bc7Smrj {
490ae115bc7Smrj     ACPI_FUNCTION_TRACE (EvCmosRegionSetup);
491ae115bc7Smrj 
492ae115bc7Smrj 
493ae115bc7Smrj     return_ACPI_STATUS (AE_OK);
494ae115bc7Smrj }
495ae115bc7Smrj 
496ae115bc7Smrj 
497ae115bc7Smrj /*******************************************************************************
498ae115bc7Smrj  *
499ae115bc7Smrj  * FUNCTION:    AcpiEvDefaultRegionSetup
500ae115bc7Smrj  *
501ae115bc7Smrj  * PARAMETERS:  Handle              - Region we are interested in
502ae115bc7Smrj  *              Function            - Start or stop
503ae115bc7Smrj  *              HandlerContext      - Address space handler context
504ae115bc7Smrj  *              RegionContext       - Region specific context
505ae115bc7Smrj  *
506ae115bc7Smrj  * RETURN:      Status
507ae115bc7Smrj  *
508ae115bc7Smrj  * DESCRIPTION: Default region initialization
509ae115bc7Smrj  *
510ae115bc7Smrj  ******************************************************************************/
511ae115bc7Smrj 
512ae115bc7Smrj ACPI_STATUS
513ae115bc7Smrj AcpiEvDefaultRegionSetup (
514ae115bc7Smrj     ACPI_HANDLE             Handle,
515ae115bc7Smrj     UINT32                  Function,
516ae115bc7Smrj     void                    *HandlerContext,
517ae115bc7Smrj     void                    **RegionContext)
518ae115bc7Smrj {
519ae115bc7Smrj     ACPI_FUNCTION_TRACE (EvDefaultRegionSetup);
520ae115bc7Smrj 
521ae115bc7Smrj 
522ae115bc7Smrj     if (Function == ACPI_REGION_DEACTIVATE)
523ae115bc7Smrj     {
524ae115bc7Smrj         *RegionContext = NULL;
525ae115bc7Smrj     }
526ae115bc7Smrj     else
527ae115bc7Smrj     {
528ae115bc7Smrj         *RegionContext = HandlerContext;
529ae115bc7Smrj     }
530ae115bc7Smrj 
531ae115bc7Smrj     return_ACPI_STATUS (AE_OK);
532ae115bc7Smrj }
533ae115bc7Smrj 
534ae115bc7Smrj 
535ae115bc7Smrj /*******************************************************************************
536ae115bc7Smrj  *
537ae115bc7Smrj  * FUNCTION:    AcpiEvInitializeRegion
538ae115bc7Smrj  *
539ae115bc7Smrj  * PARAMETERS:  RegionObj       - Region we are initializing
540ae115bc7Smrj  *              AcpiNsLocked    - Is namespace locked?
541ae115bc7Smrj  *
542ae115bc7Smrj  * RETURN:      Status
543ae115bc7Smrj  *
544ae115bc7Smrj  * DESCRIPTION: Initializes the region, finds any _REG methods and saves them
545ae115bc7Smrj  *              for execution at a later time
546ae115bc7Smrj  *
547ae115bc7Smrj  *              Get the appropriate address space handler for a newly
548ae115bc7Smrj  *              created region.
549ae115bc7Smrj  *
550ae115bc7Smrj  *              This also performs address space specific initialization. For
551ae115bc7Smrj  *              example, PCI regions must have an _ADR object that contains
552ae115bc7Smrj  *              a PCI address in the scope of the definition. This address is
553ae115bc7Smrj  *              required to perform an access to PCI config space.
554ae115bc7Smrj  *
555ae115bc7Smrj  * MUTEX:       Interpreter should be unlocked, because we may run the _REG
556ae115bc7Smrj  *              method for this region.
557ae115bc7Smrj  *
558ae115bc7Smrj  ******************************************************************************/
559ae115bc7Smrj 
560ae115bc7Smrj ACPI_STATUS
561ae115bc7Smrj AcpiEvInitializeRegion (
562ae115bc7Smrj     ACPI_OPERAND_OBJECT     *RegionObj,
563ae115bc7Smrj     BOOLEAN                 AcpiNsLocked)
564ae115bc7Smrj {
565ae115bc7Smrj     ACPI_OPERAND_OBJECT     *HandlerObj;
566ae115bc7Smrj     ACPI_OPERAND_OBJECT     *ObjDesc;
567ae115bc7Smrj     ACPI_ADR_SPACE_TYPE     SpaceId;
568ae115bc7Smrj     ACPI_NAMESPACE_NODE     *Node;
569ae115bc7Smrj     ACPI_STATUS             Status;
570ae115bc7Smrj 
571ae115bc7Smrj 
572ae115bc7Smrj     ACPI_FUNCTION_TRACE_U32 (EvInitializeRegion, AcpiNsLocked);
573ae115bc7Smrj 
574ae115bc7Smrj 
575ae115bc7Smrj     if (!RegionObj)
576ae115bc7Smrj     {
577ae115bc7Smrj         return_ACPI_STATUS (AE_BAD_PARAMETER);
578ae115bc7Smrj     }
579ae115bc7Smrj 
580ae115bc7Smrj     if (RegionObj->Common.Flags & AOPOBJ_OBJECT_INITIALIZED)
581ae115bc7Smrj     {
582ae115bc7Smrj         return_ACPI_STATUS (AE_OK);
583ae115bc7Smrj     }
584ae115bc7Smrj 
585*385cc6b4SJerry Jelinek     RegionObj->Common.Flags |= AOPOBJ_OBJECT_INITIALIZED;
586ae115bc7Smrj 
58726f3cdf0SGordon Ross     Node = RegionObj->Region.Node->Parent;
588ae115bc7Smrj     SpaceId = RegionObj->Region.SpaceId;
589ae115bc7Smrj 
590ae115bc7Smrj     /*
591ae115bc7Smrj      * The following loop depends upon the root Node having no parent
592*385cc6b4SJerry Jelinek      * ie: AcpiGbl_RootNode->Parent being set to NULL
593ae115bc7Smrj      */
594ae115bc7Smrj     while (Node)
595ae115bc7Smrj     {
596ae115bc7Smrj         /* Check to see if a handler exists */
597ae115bc7Smrj 
598ae115bc7Smrj         HandlerObj = NULL;
599ae115bc7Smrj         ObjDesc = AcpiNsGetAttachedObject (Node);
600ae115bc7Smrj         if (ObjDesc)
601ae115bc7Smrj         {
602ae115bc7Smrj             /* Can only be a handler if the object exists */
603ae115bc7Smrj 
604ae115bc7Smrj             switch (Node->Type)
605ae115bc7Smrj             {
606ae115bc7Smrj             case ACPI_TYPE_DEVICE:
607ae115bc7Smrj             case ACPI_TYPE_PROCESSOR:
608ae115bc7Smrj             case ACPI_TYPE_THERMAL:
609ae115bc7Smrj 
610*385cc6b4SJerry Jelinek                 HandlerObj = ObjDesc->CommonNotify.Handler;
611ae115bc7Smrj                 break;
612ae115bc7Smrj 
61326f3cdf0SGordon Ross             case ACPI_TYPE_METHOD:
61426f3cdf0SGordon Ross                 /*
61526f3cdf0SGordon Ross                  * If we are executing module level code, the original
61626f3cdf0SGordon Ross                  * Node's object was replaced by this Method object and we
61726f3cdf0SGordon Ross                  * saved the handler in the method object.
61826f3cdf0SGordon Ross                  *
61926f3cdf0SGordon Ross                  * See AcpiNsExecModuleCode
62026f3cdf0SGordon Ross                  */
62126f3cdf0SGordon Ross                 if (ObjDesc->Method.InfoFlags & ACPI_METHOD_MODULE_LEVEL)
62226f3cdf0SGordon Ross                 {
62326f3cdf0SGordon Ross                     HandlerObj = ObjDesc->Method.Dispatch.Handler;
62426f3cdf0SGordon Ross                 }
62526f3cdf0SGordon Ross                 break;
62626f3cdf0SGordon Ross 
627ae115bc7Smrj             default:
628*385cc6b4SJerry Jelinek 
629ae115bc7Smrj                 /* Ignore other objects */
630*385cc6b4SJerry Jelinek 
631ae115bc7Smrj                 break;
632ae115bc7Smrj             }
633ae115bc7Smrj 
634*385cc6b4SJerry Jelinek             HandlerObj = AcpiEvFindRegionHandler (SpaceId, HandlerObj);
635*385cc6b4SJerry Jelinek             if (HandlerObj)
636ae115bc7Smrj             {
637ae115bc7Smrj                 /* Found correct handler */
638ae115bc7Smrj 
639ae115bc7Smrj                 ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
640ae115bc7Smrj                     "Found handler %p for region %p in obj %p\n",
641ae115bc7Smrj                     HandlerObj, RegionObj, ObjDesc));
642ae115bc7Smrj 
643ae115bc7Smrj                 Status = AcpiEvAttachRegion (HandlerObj, RegionObj,
644ae115bc7Smrj                     AcpiNsLocked);
645ae115bc7Smrj 
646ae115bc7Smrj                 /*
647aa2aa9a6SDana Myers                  * Tell all users that this region is usable by
648aa2aa9a6SDana Myers                  * running the _REG method
649ae115bc7Smrj                  */
650ae115bc7Smrj                 if (AcpiNsLocked)
651ae115bc7Smrj                 {
652ae115bc7Smrj                     Status = AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
653ae115bc7Smrj                     if (ACPI_FAILURE (Status))
654ae115bc7Smrj                     {
655ae115bc7Smrj                         return_ACPI_STATUS (Status);
656ae115bc7Smrj                     }
657ae115bc7Smrj                 }
658ae115bc7Smrj 
65926f3cdf0SGordon Ross                 Status = AcpiEvExecuteRegMethod (RegionObj, ACPI_REG_CONNECT);
660ae115bc7Smrj 
661ae115bc7Smrj                 if (AcpiNsLocked)
662ae115bc7Smrj                 {
663ae115bc7Smrj                     Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
664ae115bc7Smrj                     if (ACPI_FAILURE (Status))
665ae115bc7Smrj                     {
666ae115bc7Smrj                         return_ACPI_STATUS (Status);
667ae115bc7Smrj                     }
668ae115bc7Smrj                 }
669ae115bc7Smrj 
670ae115bc7Smrj                 return_ACPI_STATUS (AE_OK);
671ae115bc7Smrj             }
672ae115bc7Smrj         }
673ae115bc7Smrj 
674aa2aa9a6SDana Myers         /* This node does not have the handler we need; Pop up one level */
675aa2aa9a6SDana Myers 
67626f3cdf0SGordon Ross         Node = Node->Parent;
677ae115bc7Smrj     }
678ae115bc7Smrj 
679ae115bc7Smrj     /* If we get here, there is no handler for this region */
680ae115bc7Smrj 
681ae115bc7Smrj     ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
682ae115bc7Smrj         "No handler for RegionType %s(%X) (RegionObj %p)\n",
683ae115bc7Smrj         AcpiUtGetRegionName (SpaceId), SpaceId, RegionObj));
684ae115bc7Smrj 
685ae115bc7Smrj     return_ACPI_STATUS (AE_NOT_EXIST);
686ae115bc7Smrj }
687