1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44#include <acpi/acpi.h>
45#include "accommon.h"
46#include "acnamesp.h"
47#include "actables.h"
48#include "acevents.h"
49
50#define _COMPONENT ACPI_TABLES
51ACPI_MODULE_NAME("tbdata")
52
53
54static acpi_status
55acpi_tb_check_duplication(struct acpi_table_desc *table_desc, u32 *table_index);
56
57static u8
58acpi_tb_compare_tables(struct acpi_table_desc *table_desc, u32 table_index);
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74static u8
75acpi_tb_compare_tables(struct acpi_table_desc *table_desc, u32 table_index)
76{
77 acpi_status status = AE_OK;
78 u8 is_identical;
79 struct acpi_table_header *table;
80 u32 table_length;
81 u8 table_flags;
82
83 status =
84 acpi_tb_acquire_table(&acpi_gbl_root_table_list.tables[table_index],
85 &table, &table_length, &table_flags);
86 if (ACPI_FAILURE(status)) {
87 return (FALSE);
88 }
89
90
91
92
93
94 is_identical = (u8)((table_desc->length != table_length ||
95 memcmp(table_desc->pointer, table, table_length)) ?
96 FALSE : TRUE);
97
98
99
100 acpi_tb_release_table(table, table_length, table_flags);
101 return (is_identical);
102}
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119void
120acpi_tb_init_table_descriptor(struct acpi_table_desc *table_desc,
121 acpi_physical_address address,
122 u8 flags, struct acpi_table_header *table)
123{
124
125
126
127
128
129 memset(table_desc, 0, sizeof(struct acpi_table_desc));
130 table_desc->address = address;
131 table_desc->length = table->length;
132 table_desc->flags = flags;
133 ACPI_MOVE_32_TO_32(table_desc->signature.ascii, table->signature);
134}
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152acpi_status
153acpi_tb_acquire_table(struct acpi_table_desc *table_desc,
154 struct acpi_table_header **table_ptr,
155 u32 *table_length, u8 *table_flags)
156{
157 struct acpi_table_header *table = NULL;
158
159 switch (table_desc->flags & ACPI_TABLE_ORIGIN_MASK) {
160 case ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL:
161
162 table =
163 acpi_os_map_memory(table_desc->address, table_desc->length);
164 break;
165
166 case ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL:
167 case ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL:
168
169 table = ACPI_CAST_PTR(struct acpi_table_header,
170 ACPI_PHYSADDR_TO_PTR(table_desc->
171 address));
172 break;
173
174 default:
175
176 break;
177 }
178
179
180
181 if (!table) {
182 return (AE_NO_MEMORY);
183 }
184
185
186
187 *table_ptr = table;
188 *table_length = table_desc->length;
189 *table_flags = table_desc->flags;
190 return (AE_OK);
191}
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207void
208acpi_tb_release_table(struct acpi_table_header *table,
209 u32 table_length, u8 table_flags)
210{
211
212 switch (table_flags & ACPI_TABLE_ORIGIN_MASK) {
213 case ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL:
214
215 acpi_os_unmap_memory(table, table_length);
216 break;
217
218 case ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL:
219 case ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL:
220 default:
221
222 break;
223 }
224}
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243acpi_status
244acpi_tb_acquire_temp_table(struct acpi_table_desc *table_desc,
245 acpi_physical_address address, u8 flags)
246{
247 struct acpi_table_header *table_header;
248
249 switch (flags & ACPI_TABLE_ORIGIN_MASK) {
250 case ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL:
251
252
253
254 table_header =
255 acpi_os_map_memory(address,
256 sizeof(struct acpi_table_header));
257 if (!table_header) {
258 return (AE_NO_MEMORY);
259 }
260
261 acpi_tb_init_table_descriptor(table_desc, address, flags,
262 table_header);
263 acpi_os_unmap_memory(table_header,
264 sizeof(struct acpi_table_header));
265 return (AE_OK);
266
267 case ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL:
268 case ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL:
269
270 table_header = ACPI_CAST_PTR(struct acpi_table_header,
271 ACPI_PHYSADDR_TO_PTR(address));
272 if (!table_header) {
273 return (AE_NO_MEMORY);
274 }
275
276 acpi_tb_init_table_descriptor(table_desc, address, flags,
277 table_header);
278 return (AE_OK);
279
280 default:
281
282 break;
283 }
284
285
286
287 return (AE_NO_MEMORY);
288}
289
290
291
292
293
294
295
296
297
298
299
300
301
302void acpi_tb_release_temp_table(struct acpi_table_desc *table_desc)
303{
304
305
306
307
308
309
310 acpi_tb_invalidate_table(table_desc);
311}
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326acpi_status acpi_tb_validate_table(struct acpi_table_desc *table_desc)
327{
328 acpi_status status = AE_OK;
329
330 ACPI_FUNCTION_TRACE(tb_validate_table);
331
332
333
334 if (!table_desc->pointer) {
335 status = acpi_tb_acquire_table(table_desc, &table_desc->pointer,
336 &table_desc->length,
337 &table_desc->flags);
338 if (!table_desc->pointer) {
339 status = AE_NO_MEMORY;
340 }
341 }
342
343 return_ACPI_STATUS(status);
344}
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359void acpi_tb_invalidate_table(struct acpi_table_desc *table_desc)
360{
361
362 ACPI_FUNCTION_TRACE(tb_invalidate_table);
363
364
365
366 if (!table_desc->pointer) {
367 return_VOID;
368 }
369
370 acpi_tb_release_table(table_desc->pointer, table_desc->length,
371 table_desc->flags);
372 table_desc->pointer = NULL;
373
374 return_VOID;
375}
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390acpi_status acpi_tb_validate_temp_table(struct acpi_table_desc *table_desc)
391{
392
393 if (!table_desc->pointer && !acpi_gbl_enable_table_validation) {
394
395
396
397
398
399
400
401
402
403 table_desc->length = sizeof(struct acpi_table_header);
404 }
405
406 return (acpi_tb_validate_table(table_desc));
407}
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425static acpi_status
426acpi_tb_check_duplication(struct acpi_table_desc *table_desc, u32 *table_index)
427{
428 u32 i;
429
430 ACPI_FUNCTION_TRACE(tb_check_duplication);
431
432
433
434 for (i = 0; i < acpi_gbl_root_table_list.current_table_count; ++i) {
435
436
437
438 if (!
439 (acpi_gbl_root_table_list.tables[i].
440 flags & ACPI_TABLE_IS_VERIFIED)) {
441 continue;
442 }
443
444
445
446
447
448 if (!acpi_tb_compare_tables(table_desc, i)) {
449 continue;
450 }
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466 if (acpi_gbl_root_table_list.tables[i].flags &
467 ACPI_TABLE_IS_LOADED) {
468
469
470
471 return_ACPI_STATUS(AE_ALREADY_EXISTS);
472 } else {
473 *table_index = i;
474 return_ACPI_STATUS(AE_CTRL_TERMINATE);
475 }
476 }
477
478
479
480 return_ACPI_STATUS(AE_OK);
481}
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500acpi_status
501acpi_tb_verify_temp_table(struct acpi_table_desc *table_desc,
502 char *signature, u32 *table_index)
503{
504 acpi_status status = AE_OK;
505
506 ACPI_FUNCTION_TRACE(tb_verify_temp_table);
507
508
509
510 status = acpi_tb_validate_temp_table(table_desc);
511 if (ACPI_FAILURE(status)) {
512 return_ACPI_STATUS(AE_NO_MEMORY);
513 }
514
515
516
517 if (signature && !ACPI_COMPARE_NAME(&table_desc->signature, signature)) {
518 ACPI_BIOS_ERROR((AE_INFO,
519 "Invalid signature 0x%X for ACPI table, expected [%s]",
520 table_desc->signature.integer, signature));
521 status = AE_BAD_SIGNATURE;
522 goto invalidate_and_exit;
523 }
524
525 if (acpi_gbl_enable_table_validation) {
526
527
528
529 status =
530 acpi_tb_verify_checksum(table_desc->pointer,
531 table_desc->length);
532 if (ACPI_FAILURE(status)) {
533 ACPI_EXCEPTION((AE_INFO, AE_NO_MEMORY,
534 "%4.4s 0x%8.8X%8.8X"
535 " Attempted table install failed",
536 acpi_ut_valid_nameseg(table_desc->
537 signature.
538 ascii) ?
539 table_desc->signature.ascii : "????",
540 ACPI_FORMAT_UINT64(table_desc->
541 address)));
542
543 goto invalidate_and_exit;
544 }
545
546
547
548 if (table_index) {
549 status =
550 acpi_tb_check_duplication(table_desc, table_index);
551 if (ACPI_FAILURE(status)) {
552 if (status != AE_CTRL_TERMINATE) {
553 ACPI_EXCEPTION((AE_INFO, AE_NO_MEMORY,
554 "%4.4s 0x%8.8X%8.8X"
555 " Table is duplicated",
556 acpi_ut_valid_nameseg
557 (table_desc->signature.
558 ascii) ? table_desc->
559 signature.
560 ascii : "????",
561 ACPI_FORMAT_UINT64
562 (table_desc->address)));
563 }
564
565 goto invalidate_and_exit;
566 }
567 }
568
569 table_desc->flags |= ACPI_TABLE_IS_VERIFIED;
570 }
571
572 return_ACPI_STATUS(status);
573
574invalidate_and_exit:
575 acpi_tb_invalidate_table(table_desc);
576 return_ACPI_STATUS(status);
577}
578
579
580
581
582
583
584
585
586
587
588
589
590
591acpi_status acpi_tb_resize_root_table_list(void)
592{
593 struct acpi_table_desc *tables;
594 u32 table_count;
595 u32 current_table_count, max_table_count;
596 u32 i;
597
598 ACPI_FUNCTION_TRACE(tb_resize_root_table_list);
599
600
601
602 if (!(acpi_gbl_root_table_list.flags & ACPI_ROOT_ALLOW_RESIZE)) {
603 ACPI_ERROR((AE_INFO,
604 "Resize of Root Table Array is not allowed"));
605 return_ACPI_STATUS(AE_SUPPORT);
606 }
607
608
609
610 if (acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) {
611 table_count = acpi_gbl_root_table_list.max_table_count;
612 } else {
613 table_count = acpi_gbl_root_table_list.current_table_count;
614 }
615
616 max_table_count = table_count + ACPI_ROOT_TABLE_SIZE_INCREMENT;
617 tables = ACPI_ALLOCATE_ZEROED(((acpi_size)max_table_count) *
618 sizeof(struct acpi_table_desc));
619 if (!tables) {
620 ACPI_ERROR((AE_INFO,
621 "Could not allocate new root table array"));
622 return_ACPI_STATUS(AE_NO_MEMORY);
623 }
624
625
626
627 current_table_count = 0;
628 if (acpi_gbl_root_table_list.tables) {
629 for (i = 0; i < table_count; i++) {
630 if (acpi_gbl_root_table_list.tables[i].address) {
631 memcpy(tables + current_table_count,
632 acpi_gbl_root_table_list.tables + i,
633 sizeof(struct acpi_table_desc));
634 current_table_count++;
635 }
636 }
637
638 if (acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) {
639 ACPI_FREE(acpi_gbl_root_table_list.tables);
640 }
641 }
642
643 acpi_gbl_root_table_list.tables = tables;
644 acpi_gbl_root_table_list.max_table_count = max_table_count;
645 acpi_gbl_root_table_list.current_table_count = current_table_count;
646 acpi_gbl_root_table_list.flags |= ACPI_ROOT_ORIGIN_ALLOCATED;
647
648 return_ACPI_STATUS(AE_OK);
649}
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664acpi_status
665acpi_tb_get_next_table_descriptor(u32 *table_index,
666 struct acpi_table_desc **table_desc)
667{
668 acpi_status status;
669 u32 i;
670
671
672
673 if (acpi_gbl_root_table_list.current_table_count >=
674 acpi_gbl_root_table_list.max_table_count) {
675 status = acpi_tb_resize_root_table_list();
676 if (ACPI_FAILURE(status)) {
677 return (status);
678 }
679 }
680
681 i = acpi_gbl_root_table_list.current_table_count;
682 acpi_gbl_root_table_list.current_table_count++;
683
684 if (table_index) {
685 *table_index = i;
686 }
687 if (table_desc) {
688 *table_desc = &acpi_gbl_root_table_list.tables[i];
689 }
690
691 return (AE_OK);
692}
693
694
695
696
697
698
699
700
701
702
703
704
705
706void acpi_tb_terminate(void)
707{
708 u32 i;
709
710 ACPI_FUNCTION_TRACE(tb_terminate);
711
712 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
713
714
715
716 for (i = 0; i < acpi_gbl_root_table_list.current_table_count; i++) {
717 acpi_tb_uninstall_table(&acpi_gbl_root_table_list.tables[i]);
718 }
719
720
721
722
723
724 if (acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) {
725 ACPI_FREE(acpi_gbl_root_table_list.tables);
726 }
727
728 acpi_gbl_root_table_list.tables = NULL;
729 acpi_gbl_root_table_list.flags = 0;
730 acpi_gbl_root_table_list.current_table_count = 0;
731
732 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "ACPI Tables freed\n"));
733
734 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
735 return_VOID;
736}
737
738
739
740
741
742
743
744
745
746
747
748
749
750acpi_status acpi_tb_delete_namespace_by_owner(u32 table_index)
751{
752 acpi_owner_id owner_id;
753 acpi_status status;
754
755 ACPI_FUNCTION_TRACE(tb_delete_namespace_by_owner);
756
757 status = acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
758 if (ACPI_FAILURE(status)) {
759 return_ACPI_STATUS(status);
760 }
761
762 if (table_index >= acpi_gbl_root_table_list.current_table_count) {
763
764
765
766 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
767 return_ACPI_STATUS(AE_NOT_EXIST);
768 }
769
770
771
772 owner_id = acpi_gbl_root_table_list.tables[table_index].owner_id;
773 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
774
775
776
777
778
779
780
781
782 status = acpi_ut_acquire_write_lock(&acpi_gbl_namespace_rw_lock);
783 if (ACPI_FAILURE(status)) {
784 return_ACPI_STATUS(status);
785 }
786 acpi_ns_delete_namespace_by_owner(owner_id);
787 acpi_ut_release_write_lock(&acpi_gbl_namespace_rw_lock);
788 return_ACPI_STATUS(status);
789}
790
791
792
793
794
795
796
797
798
799
800
801
802
803acpi_status acpi_tb_allocate_owner_id(u32 table_index)
804{
805 acpi_status status = AE_BAD_PARAMETER;
806
807 ACPI_FUNCTION_TRACE(tb_allocate_owner_id);
808
809 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
810 if (table_index < acpi_gbl_root_table_list.current_table_count) {
811 status =
812 acpi_ut_allocate_owner_id(&
813 (acpi_gbl_root_table_list.
814 tables[table_index].owner_id));
815 }
816
817 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
818 return_ACPI_STATUS(status);
819}
820
821
822
823
824
825
826
827
828
829
830
831
832
833acpi_status acpi_tb_release_owner_id(u32 table_index)
834{
835 acpi_status status = AE_BAD_PARAMETER;
836
837 ACPI_FUNCTION_TRACE(tb_release_owner_id);
838
839 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
840 if (table_index < acpi_gbl_root_table_list.current_table_count) {
841 acpi_ut_release_owner_id(&
842 (acpi_gbl_root_table_list.
843 tables[table_index].owner_id));
844 status = AE_OK;
845 }
846
847 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
848 return_ACPI_STATUS(status);
849}
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864acpi_status acpi_tb_get_owner_id(u32 table_index, acpi_owner_id *owner_id)
865{
866 acpi_status status = AE_BAD_PARAMETER;
867
868 ACPI_FUNCTION_TRACE(tb_get_owner_id);
869
870 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
871 if (table_index < acpi_gbl_root_table_list.current_table_count) {
872 *owner_id =
873 acpi_gbl_root_table_list.tables[table_index].owner_id;
874 status = AE_OK;
875 }
876
877 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
878 return_ACPI_STATUS(status);
879}
880
881
882
883
884
885
886
887
888
889
890
891u8 acpi_tb_is_table_loaded(u32 table_index)
892{
893 u8 is_loaded = FALSE;
894
895 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
896 if (table_index < acpi_gbl_root_table_list.current_table_count) {
897 is_loaded = (u8)
898 (acpi_gbl_root_table_list.tables[table_index].flags &
899 ACPI_TABLE_IS_LOADED);
900 }
901
902 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
903 return (is_loaded);
904}
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919void acpi_tb_set_table_loaded_flag(u32 table_index, u8 is_loaded)
920{
921
922 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
923 if (table_index < acpi_gbl_root_table_list.current_table_count) {
924 if (is_loaded) {
925 acpi_gbl_root_table_list.tables[table_index].flags |=
926 ACPI_TABLE_IS_LOADED;
927 } else {
928 acpi_gbl_root_table_list.tables[table_index].flags &=
929 ~ACPI_TABLE_IS_LOADED;
930 }
931 }
932
933 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
934}
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949acpi_status
950acpi_tb_load_table(u32 table_index, struct acpi_namespace_node *parent_node)
951{
952 struct acpi_table_header *table;
953 acpi_status status;
954 acpi_owner_id owner_id;
955
956 ACPI_FUNCTION_TRACE(tb_load_table);
957
958
959
960
961
962 status = acpi_get_table_by_index(table_index, &table);
963 if (ACPI_FAILURE(status)) {
964 return_ACPI_STATUS(status);
965 }
966
967 status = acpi_ns_load_table(table_index, parent_node);
968
969
970
971 if (!acpi_gbl_parse_table_as_term_list
972 && acpi_gbl_group_module_level_code) {
973 acpi_ns_exec_module_code_list();
974 }
975
976
977
978
979
980
981 status = acpi_tb_get_owner_id(table_index, &owner_id);
982 if (ACPI_SUCCESS(status)) {
983 acpi_ev_update_gpes(owner_id);
984 }
985
986
987
988 acpi_tb_notify_table(ACPI_TABLE_EVENT_LOAD, table);
989 return_ACPI_STATUS(status);
990}
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007acpi_status
1008acpi_tb_install_and_load_table(acpi_physical_address address,
1009 u8 flags, u8 override, u32 *table_index)
1010{
1011 acpi_status status;
1012 u32 i;
1013
1014 ACPI_FUNCTION_TRACE(tb_install_and_load_table);
1015
1016
1017
1018 status = acpi_tb_install_standard_table(address, flags, TRUE,
1019 override, &i);
1020 if (ACPI_FAILURE(status)) {
1021 goto exit;
1022 }
1023
1024 status = acpi_tb_load_table(i, acpi_gbl_root_node);
1025
1026exit:
1027 *table_index = i;
1028 return_ACPI_STATUS(status);
1029}
1030
1031ACPI_EXPORT_SYMBOL(acpi_tb_install_and_load_table)
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045acpi_status acpi_tb_unload_table(u32 table_index)
1046{
1047 acpi_status status = AE_OK;
1048 struct acpi_table_header *table;
1049
1050 ACPI_FUNCTION_TRACE(tb_unload_table);
1051
1052
1053
1054 if (!acpi_tb_is_table_loaded(table_index)) {
1055 return_ACPI_STATUS(AE_NOT_EXIST);
1056 }
1057
1058
1059
1060 status = acpi_get_table_by_index(table_index, &table);
1061 if (ACPI_SUCCESS(status)) {
1062 acpi_tb_notify_table(ACPI_TABLE_EVENT_UNLOAD, table);
1063 }
1064
1065
1066
1067 status = acpi_tb_delete_namespace_by_owner(table_index);
1068 if (ACPI_FAILURE(status)) {
1069 return_ACPI_STATUS(status);
1070 }
1071
1072 (void)acpi_tb_release_owner_id(table_index);
1073 acpi_tb_set_table_loaded_flag(table_index, FALSE);
1074 return_ACPI_STATUS(status);
1075}
1076
1077ACPI_EXPORT_SYMBOL(acpi_tb_unload_table)
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092void acpi_tb_notify_table(u32 event, void *table)
1093{
1094
1095
1096 if (acpi_gbl_table_handler) {
1097 (void)acpi_gbl_table_handler(event, table,
1098 acpi_gbl_table_handler_context);
1099 }
1100}
1101