4
4
#include "error.h"
5
5
#include "../string.h"
6
6
7
- #ifdef CONFIG_ACPI
7
+ #include <linux/efi.h>
8
+ #include <asm/efi.h>
8
9
9
10
/*
10
11
* Max length of 64-bit hex address string is 19, prefix "0x" + 16 hex
@@ -29,4 +30,80 @@ static acpi_physical_address get_acpi_rsdp(void)
29
30
#endif
30
31
return addr ;
31
32
}
32
- #endif /* CONFIG_ACPI */
33
+
34
+ /* Search EFI system tables for RSDP. */
35
+ static acpi_physical_address efi_get_rsdp_addr (void )
36
+ {
37
+ acpi_physical_address rsdp_addr = 0 ;
38
+
39
+ #ifdef CONFIG_EFI
40
+ efi_system_table_t * systab ;
41
+ struct efi_info * ei ;
42
+ bool efi_64 ;
43
+ int size , i ;
44
+ char * sig ;
45
+
46
+ ei = & boot_params -> efi_info ;
47
+ sig = (char * )& ei -> efi_loader_signature ;
48
+
49
+ if (!strncmp (sig , EFI64_LOADER_SIGNATURE , 4 )) {
50
+ efi_64 = true;
51
+ } else if (!strncmp (sig , EFI32_LOADER_SIGNATURE , 4 )) {
52
+ efi_64 = false;
53
+ } else {
54
+ debug_putstr ("Wrong EFI loader signature.\n" );
55
+ return 0 ;
56
+ }
57
+
58
+ /* Get systab from boot params. */
59
+ #ifdef CONFIG_X86_64
60
+ systab = (efi_system_table_t * )(ei -> efi_systab | ((__u64 )ei -> efi_systab_hi <<32 ));
61
+ #else
62
+ if (ei -> efi_systab_hi || ei -> efi_memmap_hi ) {
63
+ debug_putstr ("Error getting RSDP address: EFI system table located above 4GB.\n" );
64
+ return 0 ;
65
+ }
66
+ systab = (efi_system_table_t * )ei -> efi_systab ;
67
+ #endif
68
+ if (!systab )
69
+ error ("EFI system table not found." );
70
+
71
+ /*
72
+ * Get EFI tables from systab.
73
+ */
74
+ size = efi_64 ? sizeof (efi_config_table_64_t ) :
75
+ sizeof (efi_config_table_32_t );
76
+
77
+ for (i = 0 ; i < systab -> nr_tables ; i ++ ) {
78
+ acpi_physical_address table ;
79
+ void * config_tables ;
80
+ efi_guid_t guid ;
81
+
82
+ config_tables = (void * )(systab -> tables + size * i );
83
+ if (efi_64 ) {
84
+ efi_config_table_64_t * tmp_table ;
85
+
86
+ tmp_table = config_tables ;
87
+ guid = tmp_table -> guid ;
88
+ table = tmp_table -> table ;
89
+
90
+ if (!IS_ENABLED (CONFIG_X86_64 ) && table >> 32 ) {
91
+ debug_putstr ("Error getting RSDP address: EFI config table located above 4GB.\n" );
92
+ return 0 ;
93
+ }
94
+ } else {
95
+ efi_config_table_32_t * tmp_table ;
96
+
97
+ tmp_table = config_tables ;
98
+ guid = tmp_table -> guid ;
99
+ table = tmp_table -> table ;
100
+ }
101
+
102
+ if (!(efi_guidcmp (guid , ACPI_TABLE_GUID )))
103
+ rsdp_addr = table ;
104
+ else if (!(efi_guidcmp (guid , ACPI_20_TABLE_GUID )))
105
+ return table ;
106
+ }
107
+ #endif
108
+ return rsdp_addr ;
109
+ }
0 commit comments