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