1
2
3
4
5
6
7
8
9
10#include <acpi/acpi.h>
11#include "accommon.h"
12#include "acevents.h"
13#include "acnamesp.h"
14#include "acinterp.h"
15
16#define _COMPONENT ACPI_EVENTS
17ACPI_MODULE_NAME("evrgnini")
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33acpi_status
34acpi_ev_system_memory_region_setup(acpi_handle handle,
35 u32 function,
36 void *handler_context, void **region_context)
37{
38 union acpi_operand_object *region_desc =
39 (union acpi_operand_object *)handle;
40 struct acpi_mem_space_context *local_region_context;
41 struct acpi_mem_mapping *mm;
42
43 ACPI_FUNCTION_TRACE(ev_system_memory_region_setup);
44
45 if (function == ACPI_REGION_DEACTIVATE) {
46 if (*region_context) {
47 local_region_context =
48 (struct acpi_mem_space_context *)*region_context;
49
50
51
52 while (local_region_context->first_mm) {
53 mm = local_region_context->first_mm;
54 local_region_context->first_mm = mm->next_mm;
55 acpi_os_unmap_memory(mm->logical_address,
56 mm->length);
57 ACPI_FREE(mm);
58 }
59 ACPI_FREE(local_region_context);
60 *region_context = NULL;
61 }
62 return_ACPI_STATUS(AE_OK);
63 }
64
65
66
67 local_region_context =
68 ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_mem_space_context));
69 if (!(local_region_context)) {
70 return_ACPI_STATUS(AE_NO_MEMORY);
71 }
72
73
74
75 local_region_context->length = region_desc->region.length;
76 local_region_context->address = region_desc->region.address;
77
78 *region_context = local_region_context;
79 return_ACPI_STATUS(AE_OK);
80}
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97acpi_status
98acpi_ev_io_space_region_setup(acpi_handle handle,
99 u32 function,
100 void *handler_context, void **region_context)
101{
102 ACPI_FUNCTION_TRACE(ev_io_space_region_setup);
103
104 if (function == ACPI_REGION_DEACTIVATE) {
105 *region_context = NULL;
106 } else {
107 *region_context = handler_context;
108 }
109
110 return_ACPI_STATUS(AE_OK);
111}
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130acpi_status
131acpi_ev_pci_config_region_setup(acpi_handle handle,
132 u32 function,
133 void *handler_context, void **region_context)
134{
135 acpi_status status = AE_OK;
136 u64 pci_value;
137 struct acpi_pci_id *pci_id = *region_context;
138 union acpi_operand_object *handler_obj;
139 struct acpi_namespace_node *parent_node;
140 struct acpi_namespace_node *pci_root_node;
141 struct acpi_namespace_node *pci_device_node;
142 union acpi_operand_object *region_obj =
143 (union acpi_operand_object *)handle;
144
145 ACPI_FUNCTION_TRACE(ev_pci_config_region_setup);
146
147 handler_obj = region_obj->region.handler;
148 if (!handler_obj) {
149
150
151
152
153 ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
154 "Attempting to init a region %p, with no handler\n",
155 region_obj));
156 return_ACPI_STATUS(AE_NOT_EXIST);
157 }
158
159 *region_context = NULL;
160 if (function == ACPI_REGION_DEACTIVATE) {
161 if (pci_id) {
162 ACPI_FREE(pci_id);
163 }
164 return_ACPI_STATUS(status);
165 }
166
167 parent_node = region_obj->region.node->parent;
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182 if (handler_obj->address_space.node == acpi_gbl_root_node) {
183
184
185
186 pci_root_node = parent_node;
187 while (pci_root_node != acpi_gbl_root_node) {
188
189
190
191 if (acpi_ev_is_pci_root_bridge(pci_root_node)) {
192
193
194
195 status = acpi_install_address_space_handler((acpi_handle)pci_root_node, ACPI_ADR_SPACE_PCI_CONFIG, ACPI_DEFAULT_HANDLER, NULL, NULL);
196 if (ACPI_FAILURE(status)) {
197 if (status == AE_SAME_HANDLER) {
198
199
200
201
202
203 } else {
204 ACPI_EXCEPTION((AE_INFO, status,
205 "Could not install PciConfig handler "
206 "for Root Bridge %4.4s",
207 acpi_ut_get_node_name
208 (pci_root_node)));
209 }
210 }
211 break;
212 }
213
214 pci_root_node = pci_root_node->parent;
215 }
216
217
218 } else {
219 pci_root_node = handler_obj->address_space.node;
220 }
221
222
223
224
225
226 if (region_obj->region.flags & AOPOBJ_SETUP_COMPLETE) {
227 return_ACPI_STATUS(AE_OK);
228 }
229
230
231
232 pci_id = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_pci_id));
233 if (!pci_id) {
234 return_ACPI_STATUS(AE_NO_MEMORY);
235 }
236
237
238
239
240
241
242
243
244 pci_device_node = region_obj->region.node;
245 while (pci_device_node && (pci_device_node->type != ACPI_TYPE_DEVICE)) {
246 pci_device_node = pci_device_node->parent;
247 }
248
249 if (!pci_device_node) {
250 ACPI_FREE(pci_id);
251 return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
252 }
253
254
255
256
257
258 status = acpi_ut_evaluate_numeric_object(METHOD_NAME__ADR,
259 pci_device_node, &pci_value);
260
261
262
263
264
265 if (ACPI_SUCCESS(status)) {
266 pci_id->device = ACPI_HIWORD(ACPI_LODWORD(pci_value));
267 pci_id->function = ACPI_LOWORD(ACPI_LODWORD(pci_value));
268 }
269
270
271
272 status = acpi_ut_evaluate_numeric_object(METHOD_NAME__SEG,
273 pci_root_node, &pci_value);
274 if (ACPI_SUCCESS(status)) {
275 pci_id->segment = ACPI_LOWORD(pci_value);
276 }
277
278
279
280 status = acpi_ut_evaluate_numeric_object(METHOD_NAME__BBN,
281 pci_root_node, &pci_value);
282 if (ACPI_SUCCESS(status)) {
283 pci_id->bus = ACPI_LOWORD(pci_value);
284 }
285
286
287
288 status =
289 acpi_hw_derive_pci_id(pci_id, pci_root_node,
290 region_obj->region.node);
291 if (ACPI_FAILURE(status)) {
292 ACPI_FREE(pci_id);
293 return_ACPI_STATUS(status);
294 }
295
296 *region_context = pci_id;
297 return_ACPI_STATUS(AE_OK);
298}
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313u8 acpi_ev_is_pci_root_bridge(struct acpi_namespace_node *node)
314{
315 acpi_status status;
316 struct acpi_pnp_device_id *hid;
317 struct acpi_pnp_device_id_list *cid;
318 u32 i;
319 u8 match;
320
321
322
323 status = acpi_ut_execute_HID(node, &hid);
324 if (ACPI_FAILURE(status)) {
325 return (FALSE);
326 }
327
328 match = acpi_ut_is_pci_root_bridge(hid->string);
329 ACPI_FREE(hid);
330
331 if (match) {
332 return (TRUE);
333 }
334
335
336
337 status = acpi_ut_execute_CID(node, &cid);
338 if (ACPI_FAILURE(status)) {
339 return (FALSE);
340 }
341
342
343
344 for (i = 0; i < cid->count; i++) {
345 if (acpi_ut_is_pci_root_bridge(cid->ids[i].string)) {
346 ACPI_FREE(cid);
347 return (TRUE);
348 }
349 }
350
351 ACPI_FREE(cid);
352 return (FALSE);
353}
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372acpi_status
373acpi_ev_pci_bar_region_setup(acpi_handle handle,
374 u32 function,
375 void *handler_context, void **region_context)
376{
377 ACPI_FUNCTION_TRACE(ev_pci_bar_region_setup);
378
379 return_ACPI_STATUS(AE_OK);
380}
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399acpi_status
400acpi_ev_cmos_region_setup(acpi_handle handle,
401 u32 function,
402 void *handler_context, void **region_context)
403{
404 ACPI_FUNCTION_TRACE(ev_cmos_region_setup);
405
406 return_ACPI_STATUS(AE_OK);
407}
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424acpi_status
425acpi_ev_default_region_setup(acpi_handle handle,
426 u32 function,
427 void *handler_context, void **region_context)
428{
429 ACPI_FUNCTION_TRACE(ev_default_region_setup);
430
431 if (function == ACPI_REGION_DEACTIVATE) {
432 *region_context = NULL;
433 } else {
434 *region_context = handler_context;
435 }
436
437 return_ACPI_STATUS(AE_OK);
438}
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476acpi_status acpi_ev_initialize_region(union acpi_operand_object *region_obj)
477{
478 union acpi_operand_object *handler_obj;
479 union acpi_operand_object *obj_desc;
480 acpi_adr_space_type space_id;
481 struct acpi_namespace_node *node;
482
483 ACPI_FUNCTION_TRACE(ev_initialize_region);
484
485 if (!region_obj) {
486 return_ACPI_STATUS(AE_BAD_PARAMETER);
487 }
488
489 if (region_obj->common.flags & AOPOBJ_OBJECT_INITIALIZED) {
490 return_ACPI_STATUS(AE_OK);
491 }
492
493 region_obj->common.flags |= AOPOBJ_OBJECT_INITIALIZED;
494
495 node = region_obj->region.node->parent;
496 space_id = region_obj->region.space_id;
497
498
499
500
501
502 while (node) {
503
504
505
506 handler_obj = NULL;
507 obj_desc = acpi_ns_get_attached_object(node);
508 if (obj_desc) {
509
510
511
512 switch (node->type) {
513 case ACPI_TYPE_DEVICE:
514 case ACPI_TYPE_PROCESSOR:
515 case ACPI_TYPE_THERMAL:
516
517 handler_obj = obj_desc->common_notify.handler;
518 break;
519
520 default:
521
522
523
524 break;
525 }
526
527 handler_obj =
528 acpi_ev_find_region_handler(space_id, handler_obj);
529 if (handler_obj) {
530
531
532
533 ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
534 "Found handler %p for region %p in obj %p\n",
535 handler_obj, region_obj,
536 obj_desc));
537
538 (void)acpi_ev_attach_region(handler_obj,
539 region_obj, FALSE);
540
541
542
543
544
545 acpi_ex_exit_interpreter();
546 (void)acpi_ev_execute_reg_method(region_obj,
547 ACPI_REG_CONNECT);
548 acpi_ex_enter_interpreter();
549 return_ACPI_STATUS(AE_OK);
550 }
551 }
552
553
554
555 node = node->parent;
556 }
557
558
559
560
561
562
563 ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
564 "No handler for RegionType %s(%X) (RegionObj %p)\n",
565 acpi_ut_get_region_name(space_id), space_id,
566 region_obj));
567
568 return_ACPI_STATUS(AE_OK);
569}
570