Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/drivers/acpi/acpica/evrgnini.c
15111 views
1
/******************************************************************************
2
*
3
* Module Name: evrgnini- ACPI address_space (op_region) init
4
*
5
*****************************************************************************/
6
7
/*
8
* Copyright (C) 2000 - 2011, 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/acpi.h>
45
#include "accommon.h"
46
#include "acevents.h"
47
#include "acnamesp.h"
48
49
#define _COMPONENT ACPI_EVENTS
50
ACPI_MODULE_NAME("evrgnini")
51
52
/* Local prototypes */
53
static u8 acpi_ev_is_pci_root_bridge(struct acpi_namespace_node *node);
54
55
/*******************************************************************************
56
*
57
* FUNCTION: acpi_ev_system_memory_region_setup
58
*
59
* PARAMETERS: Handle - Region we are interested in
60
* Function - Start or stop
61
* handler_context - Address space handler context
62
* region_context - Region specific context
63
*
64
* RETURN: Status
65
*
66
* DESCRIPTION: Setup a system_memory operation region
67
*
68
******************************************************************************/
69
70
acpi_status
71
acpi_ev_system_memory_region_setup(acpi_handle handle,
72
u32 function,
73
void *handler_context, void **region_context)
74
{
75
union acpi_operand_object *region_desc =
76
(union acpi_operand_object *)handle;
77
struct acpi_mem_space_context *local_region_context;
78
79
ACPI_FUNCTION_TRACE(ev_system_memory_region_setup);
80
81
if (function == ACPI_REGION_DEACTIVATE) {
82
if (*region_context) {
83
local_region_context =
84
(struct acpi_mem_space_context *)*region_context;
85
86
/* Delete a cached mapping if present */
87
88
if (local_region_context->mapped_length) {
89
acpi_os_unmap_memory(local_region_context->
90
mapped_logical_address,
91
local_region_context->
92
mapped_length);
93
}
94
ACPI_FREE(local_region_context);
95
*region_context = NULL;
96
}
97
return_ACPI_STATUS(AE_OK);
98
}
99
100
/* Create a new context */
101
102
local_region_context =
103
ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_mem_space_context));
104
if (!(local_region_context)) {
105
return_ACPI_STATUS(AE_NO_MEMORY);
106
}
107
108
/* Save the region length and address for use in the handler */
109
110
local_region_context->length = region_desc->region.length;
111
local_region_context->address = region_desc->region.address;
112
113
*region_context = local_region_context;
114
return_ACPI_STATUS(AE_OK);
115
}
116
117
/*******************************************************************************
118
*
119
* FUNCTION: acpi_ev_io_space_region_setup
120
*
121
* PARAMETERS: Handle - Region we are interested in
122
* Function - Start or stop
123
* handler_context - Address space handler context
124
* region_context - Region specific context
125
*
126
* RETURN: Status
127
*
128
* DESCRIPTION: Setup a IO operation region
129
*
130
******************************************************************************/
131
132
acpi_status
133
acpi_ev_io_space_region_setup(acpi_handle handle,
134
u32 function,
135
void *handler_context, void **region_context)
136
{
137
ACPI_FUNCTION_TRACE(ev_io_space_region_setup);
138
139
if (function == ACPI_REGION_DEACTIVATE) {
140
*region_context = NULL;
141
} else {
142
*region_context = handler_context;
143
}
144
145
return_ACPI_STATUS(AE_OK);
146
}
147
148
/*******************************************************************************
149
*
150
* FUNCTION: acpi_ev_pci_config_region_setup
151
*
152
* PARAMETERS: Handle - Region we are interested in
153
* Function - Start or stop
154
* handler_context - Address space handler context
155
* region_context - Region specific context
156
*
157
* RETURN: Status
158
*
159
* DESCRIPTION: Setup a PCI_Config operation region
160
*
161
* MUTEX: Assumes namespace is not locked
162
*
163
******************************************************************************/
164
165
acpi_status
166
acpi_ev_pci_config_region_setup(acpi_handle handle,
167
u32 function,
168
void *handler_context, void **region_context)
169
{
170
acpi_status status = AE_OK;
171
u64 pci_value;
172
struct acpi_pci_id *pci_id = *region_context;
173
union acpi_operand_object *handler_obj;
174
struct acpi_namespace_node *parent_node;
175
struct acpi_namespace_node *pci_root_node;
176
struct acpi_namespace_node *pci_device_node;
177
union acpi_operand_object *region_obj =
178
(union acpi_operand_object *)handle;
179
180
ACPI_FUNCTION_TRACE(ev_pci_config_region_setup);
181
182
handler_obj = region_obj->region.handler;
183
if (!handler_obj) {
184
/*
185
* No installed handler. This shouldn't happen because the dispatch
186
* routine checks before we get here, but we check again just in case.
187
*/
188
ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
189
"Attempting to init a region %p, with no handler\n",
190
region_obj));
191
return_ACPI_STATUS(AE_NOT_EXIST);
192
}
193
194
*region_context = NULL;
195
if (function == ACPI_REGION_DEACTIVATE) {
196
if (pci_id) {
197
ACPI_FREE(pci_id);
198
}
199
return_ACPI_STATUS(status);
200
}
201
202
parent_node = region_obj->region.node->parent;
203
204
/*
205
* Get the _SEG and _BBN values from the device upon which the handler
206
* is installed.
207
*
208
* We need to get the _SEG and _BBN objects relative to the PCI BUS device.
209
* This is the device the handler has been registered to handle.
210
*/
211
212
/*
213
* If the address_space.Node is still pointing to the root, we need
214
* to scan upward for a PCI Root bridge and re-associate the op_region
215
* handlers with that device.
216
*/
217
if (handler_obj->address_space.node == acpi_gbl_root_node) {
218
219
/* Start search from the parent object */
220
221
pci_root_node = parent_node;
222
while (pci_root_node != acpi_gbl_root_node) {
223
224
/* Get the _HID/_CID in order to detect a root_bridge */
225
226
if (acpi_ev_is_pci_root_bridge(pci_root_node)) {
227
228
/* Install a handler for this PCI root bridge */
229
230
status =
231
acpi_install_address_space_handler((acpi_handle) pci_root_node, ACPI_ADR_SPACE_PCI_CONFIG, ACPI_DEFAULT_HANDLER, NULL, NULL);
232
if (ACPI_FAILURE(status)) {
233
if (status == AE_SAME_HANDLER) {
234
/*
235
* It is OK if the handler is already installed on the
236
* root bridge. Still need to return a context object
237
* for the new PCI_Config operation region, however.
238
*/
239
status = AE_OK;
240
} else {
241
ACPI_EXCEPTION((AE_INFO, status,
242
"Could not install PciConfig handler "
243
"for Root Bridge %4.4s",
244
acpi_ut_get_node_name
245
(pci_root_node)));
246
}
247
}
248
break;
249
}
250
251
pci_root_node = pci_root_node->parent;
252
}
253
254
/* PCI root bridge not found, use namespace root node */
255
} else {
256
pci_root_node = handler_obj->address_space.node;
257
}
258
259
/*
260
* If this region is now initialized, we are done.
261
* (install_address_space_handler could have initialized it)
262
*/
263
if (region_obj->region.flags & AOPOBJ_SETUP_COMPLETE) {
264
return_ACPI_STATUS(AE_OK);
265
}
266
267
/* Region is still not initialized. Create a new context */
268
269
pci_id = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_pci_id));
270
if (!pci_id) {
271
return_ACPI_STATUS(AE_NO_MEMORY);
272
}
273
274
/*
275
* For PCI_Config space access, we need the segment, bus, device and
276
* function numbers. Acquire them here.
277
*
278
* Find the parent device object. (This allows the operation region to be
279
* within a subscope under the device, such as a control method.)
280
*/
281
pci_device_node = region_obj->region.node;
282
while (pci_device_node && (pci_device_node->type != ACPI_TYPE_DEVICE)) {
283
pci_device_node = pci_device_node->parent;
284
}
285
286
if (!pci_device_node) {
287
ACPI_FREE(pci_id);
288
return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
289
}
290
291
/*
292
* Get the PCI device and function numbers from the _ADR object
293
* contained in the parent's scope.
294
*/
295
status = acpi_ut_evaluate_numeric_object(METHOD_NAME__ADR,
296
pci_device_node, &pci_value);
297
298
/*
299
* The default is zero, and since the allocation above zeroed the data,
300
* just do nothing on failure.
301
*/
302
if (ACPI_SUCCESS(status)) {
303
pci_id->device = ACPI_HIWORD(ACPI_LODWORD(pci_value));
304
pci_id->function = ACPI_LOWORD(ACPI_LODWORD(pci_value));
305
}
306
307
/* The PCI segment number comes from the _SEG method */
308
309
status = acpi_ut_evaluate_numeric_object(METHOD_NAME__SEG,
310
pci_root_node, &pci_value);
311
if (ACPI_SUCCESS(status)) {
312
pci_id->segment = ACPI_LOWORD(pci_value);
313
}
314
315
/* The PCI bus number comes from the _BBN method */
316
317
status = acpi_ut_evaluate_numeric_object(METHOD_NAME__BBN,
318
pci_root_node, &pci_value);
319
if (ACPI_SUCCESS(status)) {
320
pci_id->bus = ACPI_LOWORD(pci_value);
321
}
322
323
/* Complete/update the PCI ID for this device */
324
325
status =
326
acpi_hw_derive_pci_id(pci_id, pci_root_node,
327
region_obj->region.node);
328
if (ACPI_FAILURE(status)) {
329
ACPI_FREE(pci_id);
330
return_ACPI_STATUS(status);
331
}
332
333
*region_context = pci_id;
334
return_ACPI_STATUS(AE_OK);
335
}
336
337
/*******************************************************************************
338
*
339
* FUNCTION: acpi_ev_is_pci_root_bridge
340
*
341
* PARAMETERS: Node - Device node being examined
342
*
343
* RETURN: TRUE if device is a PCI/PCI-Express Root Bridge
344
*
345
* DESCRIPTION: Determine if the input device represents a PCI Root Bridge by
346
* examining the _HID and _CID for the device.
347
*
348
******************************************************************************/
349
350
static u8 acpi_ev_is_pci_root_bridge(struct acpi_namespace_node *node)
351
{
352
acpi_status status;
353
struct acpica_device_id *hid;
354
struct acpica_device_id_list *cid;
355
u32 i;
356
u8 match;
357
358
/* Get the _HID and check for a PCI Root Bridge */
359
360
status = acpi_ut_execute_HID(node, &hid);
361
if (ACPI_FAILURE(status)) {
362
return (FALSE);
363
}
364
365
match = acpi_ut_is_pci_root_bridge(hid->string);
366
ACPI_FREE(hid);
367
368
if (match) {
369
return (TRUE);
370
}
371
372
/* The _HID did not match. Get the _CID and check for a PCI Root Bridge */
373
374
status = acpi_ut_execute_CID(node, &cid);
375
if (ACPI_FAILURE(status)) {
376
return (FALSE);
377
}
378
379
/* Check all _CIDs in the returned list */
380
381
for (i = 0; i < cid->count; i++) {
382
if (acpi_ut_is_pci_root_bridge(cid->ids[i].string)) {
383
ACPI_FREE(cid);
384
return (TRUE);
385
}
386
}
387
388
ACPI_FREE(cid);
389
return (FALSE);
390
}
391
392
/*******************************************************************************
393
*
394
* FUNCTION: acpi_ev_pci_bar_region_setup
395
*
396
* PARAMETERS: Handle - Region we are interested in
397
* Function - Start or stop
398
* handler_context - Address space handler context
399
* region_context - Region specific context
400
*
401
* RETURN: Status
402
*
403
* DESCRIPTION: Setup a pci_bAR operation region
404
*
405
* MUTEX: Assumes namespace is not locked
406
*
407
******************************************************************************/
408
409
acpi_status
410
acpi_ev_pci_bar_region_setup(acpi_handle handle,
411
u32 function,
412
void *handler_context, void **region_context)
413
{
414
ACPI_FUNCTION_TRACE(ev_pci_bar_region_setup);
415
416
return_ACPI_STATUS(AE_OK);
417
}
418
419
/*******************************************************************************
420
*
421
* FUNCTION: acpi_ev_cmos_region_setup
422
*
423
* PARAMETERS: Handle - Region we are interested in
424
* Function - Start or stop
425
* handler_context - Address space handler context
426
* region_context - Region specific context
427
*
428
* RETURN: Status
429
*
430
* DESCRIPTION: Setup a CMOS operation region
431
*
432
* MUTEX: Assumes namespace is not locked
433
*
434
******************************************************************************/
435
436
acpi_status
437
acpi_ev_cmos_region_setup(acpi_handle handle,
438
u32 function,
439
void *handler_context, void **region_context)
440
{
441
ACPI_FUNCTION_TRACE(ev_cmos_region_setup);
442
443
return_ACPI_STATUS(AE_OK);
444
}
445
446
/*******************************************************************************
447
*
448
* FUNCTION: acpi_ev_default_region_setup
449
*
450
* PARAMETERS: Handle - Region we are interested in
451
* Function - Start or stop
452
* handler_context - Address space handler context
453
* region_context - Region specific context
454
*
455
* RETURN: Status
456
*
457
* DESCRIPTION: Default region initialization
458
*
459
******************************************************************************/
460
461
acpi_status
462
acpi_ev_default_region_setup(acpi_handle handle,
463
u32 function,
464
void *handler_context, void **region_context)
465
{
466
ACPI_FUNCTION_TRACE(ev_default_region_setup);
467
468
if (function == ACPI_REGION_DEACTIVATE) {
469
*region_context = NULL;
470
} else {
471
*region_context = handler_context;
472
}
473
474
return_ACPI_STATUS(AE_OK);
475
}
476
477
/*******************************************************************************
478
*
479
* FUNCTION: acpi_ev_initialize_region
480
*
481
* PARAMETERS: region_obj - Region we are initializing
482
* acpi_ns_locked - Is namespace locked?
483
*
484
* RETURN: Status
485
*
486
* DESCRIPTION: Initializes the region, finds any _REG methods and saves them
487
* for execution at a later time
488
*
489
* Get the appropriate address space handler for a newly
490
* created region.
491
*
492
* This also performs address space specific initialization. For
493
* example, PCI regions must have an _ADR object that contains
494
* a PCI address in the scope of the definition. This address is
495
* required to perform an access to PCI config space.
496
*
497
* MUTEX: Interpreter should be unlocked, because we may run the _REG
498
* method for this region.
499
*
500
******************************************************************************/
501
502
acpi_status
503
acpi_ev_initialize_region(union acpi_operand_object *region_obj,
504
u8 acpi_ns_locked)
505
{
506
union acpi_operand_object *handler_obj;
507
union acpi_operand_object *obj_desc;
508
acpi_adr_space_type space_id;
509
struct acpi_namespace_node *node;
510
acpi_status status;
511
struct acpi_namespace_node *method_node;
512
acpi_name *reg_name_ptr = (acpi_name *) METHOD_NAME__REG;
513
union acpi_operand_object *region_obj2;
514
515
ACPI_FUNCTION_TRACE_U32(ev_initialize_region, acpi_ns_locked);
516
517
if (!region_obj) {
518
return_ACPI_STATUS(AE_BAD_PARAMETER);
519
}
520
521
if (region_obj->common.flags & AOPOBJ_OBJECT_INITIALIZED) {
522
return_ACPI_STATUS(AE_OK);
523
}
524
525
region_obj2 = acpi_ns_get_secondary_object(region_obj);
526
if (!region_obj2) {
527
return_ACPI_STATUS(AE_NOT_EXIST);
528
}
529
530
node = region_obj->region.node->parent;
531
space_id = region_obj->region.space_id;
532
533
/* Setup defaults */
534
535
region_obj->region.handler = NULL;
536
region_obj2->extra.method_REG = NULL;
537
region_obj->common.flags &= ~(AOPOBJ_SETUP_COMPLETE);
538
region_obj->common.flags |= AOPOBJ_OBJECT_INITIALIZED;
539
540
/* Find any "_REG" method associated with this region definition */
541
542
status =
543
acpi_ns_search_one_scope(*reg_name_ptr, node, ACPI_TYPE_METHOD,
544
&method_node);
545
if (ACPI_SUCCESS(status)) {
546
/*
547
* The _REG method is optional and there can be only one per region
548
* definition. This will be executed when the handler is attached
549
* or removed
550
*/
551
region_obj2->extra.method_REG = method_node;
552
}
553
554
/*
555
* The following loop depends upon the root Node having no parent
556
* ie: acpi_gbl_root_node->parent_entry being set to NULL
557
*/
558
while (node) {
559
560
/* Check to see if a handler exists */
561
562
handler_obj = NULL;
563
obj_desc = acpi_ns_get_attached_object(node);
564
if (obj_desc) {
565
566
/* Can only be a handler if the object exists */
567
568
switch (node->type) {
569
case ACPI_TYPE_DEVICE:
570
571
handler_obj = obj_desc->device.handler;
572
break;
573
574
case ACPI_TYPE_PROCESSOR:
575
576
handler_obj = obj_desc->processor.handler;
577
break;
578
579
case ACPI_TYPE_THERMAL:
580
581
handler_obj = obj_desc->thermal_zone.handler;
582
break;
583
584
case ACPI_TYPE_METHOD:
585
/*
586
* If we are executing module level code, the original
587
* Node's object was replaced by this Method object and we
588
* saved the handler in the method object.
589
*
590
* See acpi_ns_exec_module_code
591
*/
592
if (obj_desc->method.
593
info_flags & ACPI_METHOD_MODULE_LEVEL) {
594
handler_obj =
595
obj_desc->method.dispatch.handler;
596
}
597
break;
598
599
default:
600
/* Ignore other objects */
601
break;
602
}
603
604
while (handler_obj) {
605
606
/* Is this handler of the correct type? */
607
608
if (handler_obj->address_space.space_id ==
609
space_id) {
610
611
/* Found correct handler */
612
613
ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
614
"Found handler %p for region %p in obj %p\n",
615
handler_obj,
616
region_obj,
617
obj_desc));
618
619
status =
620
acpi_ev_attach_region(handler_obj,
621
region_obj,
622
acpi_ns_locked);
623
624
/*
625
* Tell all users that this region is usable by
626
* running the _REG method
627
*/
628
if (acpi_ns_locked) {
629
status =
630
acpi_ut_release_mutex
631
(ACPI_MTX_NAMESPACE);
632
if (ACPI_FAILURE(status)) {
633
return_ACPI_STATUS
634
(status);
635
}
636
}
637
638
status =
639
acpi_ev_execute_reg_method
640
(region_obj, ACPI_REG_CONNECT);
641
642
if (acpi_ns_locked) {
643
status =
644
acpi_ut_acquire_mutex
645
(ACPI_MTX_NAMESPACE);
646
if (ACPI_FAILURE(status)) {
647
return_ACPI_STATUS
648
(status);
649
}
650
}
651
652
return_ACPI_STATUS(AE_OK);
653
}
654
655
/* Try next handler in the list */
656
657
handler_obj = handler_obj->address_space.next;
658
}
659
}
660
661
/* This node does not have the handler we need; Pop up one level */
662
663
node = node->parent;
664
}
665
666
/* If we get here, there is no handler for this region */
667
668
ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
669
"No handler for RegionType %s(%X) (RegionObj %p)\n",
670
acpi_ut_get_region_name(space_id), space_id,
671
region_obj));
672
673
return_ACPI_STATUS(AE_NOT_EXIST);
674
}
675
676