diff options
author | Len Brown <len.brown@intel.com> | 2005-08-04 18:09:09 -0400 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2005-08-04 18:09:09 -0400 |
commit | 5d2a22079c825669d91a3a200332f1053b4b61b0 (patch) | |
tree | 2e6e88bbcc3e17535fdf3103540b246b3658e20b /drivers/acpi/tables | |
parent | 1c5ad84516ae7ea4ec868436a910a6bd8d20215a (diff) | |
parent | bd6dbdf3c7b9784fbf5d8500e427a954e27a976a (diff) |
/home/lenb/src/to-akpm branch 'acpi-2.6.12'
Diffstat (limited to 'drivers/acpi/tables')
-rw-r--r-- | drivers/acpi/tables/tbconvrt.c | 8 | ||||
-rw-r--r-- | drivers/acpi/tables/tbinstal.c | 34 | ||||
-rw-r--r-- | drivers/acpi/tables/tbrsdt.c | 59 | ||||
-rw-r--r-- | drivers/acpi/tables/tbutils.c | 67 | ||||
-rw-r--r-- | drivers/acpi/tables/tbxface.c | 17 | ||||
-rw-r--r-- | drivers/acpi/tables/tbxfroot.c | 120 |
6 files changed, 202 insertions, 103 deletions
diff --git a/drivers/acpi/tables/tbconvrt.c b/drivers/acpi/tables/tbconvrt.c index 92e0c31539be..d4ff71f5fe5d 100644 --- a/drivers/acpi/tables/tbconvrt.c +++ b/drivers/acpi/tables/tbconvrt.c | |||
@@ -97,7 +97,9 @@ acpi_tb_get_table_count ( | |||
97 | ACPI_FUNCTION_ENTRY (); | 97 | ACPI_FUNCTION_ENTRY (); |
98 | 98 | ||
99 | 99 | ||
100 | if (RSDP->revision < 2) { | 100 | /* RSDT pointers are 32 bits, XSDT pointers are 64 bits */ |
101 | |||
102 | if (acpi_gbl_root_table_type == ACPI_TABLE_TYPE_RSDT) { | ||
101 | pointer_size = sizeof (u32); | 103 | pointer_size = sizeof (u32); |
102 | } | 104 | } |
103 | else { | 105 | else { |
@@ -158,7 +160,9 @@ acpi_tb_convert_to_xsdt ( | |||
158 | /* Copy the table pointers */ | 160 | /* Copy the table pointers */ |
159 | 161 | ||
160 | for (i = 0; i < acpi_gbl_rsdt_table_count; i++) { | 162 | for (i = 0; i < acpi_gbl_rsdt_table_count; i++) { |
161 | if (acpi_gbl_RSDP->revision < 2) { | 163 | /* RSDT pointers are 32 bits, XSDT pointers are 64 bits */ |
164 | |||
165 | if (acpi_gbl_root_table_type == ACPI_TABLE_TYPE_RSDT) { | ||
162 | ACPI_STORE_ADDRESS (new_table->table_offset_entry[i], | 166 | ACPI_STORE_ADDRESS (new_table->table_offset_entry[i], |
163 | (ACPI_CAST_PTR (struct rsdt_descriptor_rev1, | 167 | (ACPI_CAST_PTR (struct rsdt_descriptor_rev1, |
164 | table_info->pointer))->table_offset_entry[i]); | 168 | table_info->pointer))->table_offset_entry[i]); |
diff --git a/drivers/acpi/tables/tbinstal.c b/drivers/acpi/tables/tbinstal.c index 629b64c8193d..698799901f55 100644 --- a/drivers/acpi/tables/tbinstal.c +++ b/drivers/acpi/tables/tbinstal.c | |||
@@ -124,9 +124,7 @@ acpi_tb_match_signature ( | |||
124 | * | 124 | * |
125 | * RETURN: Status | 125 | * RETURN: Status |
126 | * | 126 | * |
127 | * DESCRIPTION: Load and validate all tables other than the RSDT. The RSDT must | 127 | * DESCRIPTION: Install the table into the global data structures. |
128 | * already be loaded and validated. | ||
129 | * Install the table into the global data structs. | ||
130 | * | 128 | * |
131 | ******************************************************************************/ | 129 | ******************************************************************************/ |
132 | 130 | ||
@@ -136,6 +134,7 @@ acpi_tb_install_table ( | |||
136 | { | 134 | { |
137 | acpi_status status; | 135 | acpi_status status; |
138 | 136 | ||
137 | |||
139 | ACPI_FUNCTION_TRACE ("tb_install_table"); | 138 | ACPI_FUNCTION_TRACE ("tb_install_table"); |
140 | 139 | ||
141 | 140 | ||
@@ -143,22 +142,33 @@ acpi_tb_install_table ( | |||
143 | 142 | ||
144 | status = acpi_ut_acquire_mutex (ACPI_MTX_TABLES); | 143 | status = acpi_ut_acquire_mutex (ACPI_MTX_TABLES); |
145 | if (ACPI_FAILURE (status)) { | 144 | if (ACPI_FAILURE (status)) { |
146 | ACPI_REPORT_ERROR (("Could not acquire table mutex for [%4.4s], %s\n", | 145 | ACPI_REPORT_ERROR (("Could not acquire table mutex, %s\n", |
147 | table_info->pointer->signature, acpi_format_exception (status))); | 146 | acpi_format_exception (status))); |
148 | return_ACPI_STATUS (status); | 147 | return_ACPI_STATUS (status); |
149 | } | 148 | } |
150 | 149 | ||
150 | /* | ||
151 | * Ignore a table that is already installed. For example, some BIOS | ||
152 | * ASL code will repeatedly attempt to load the same SSDT. | ||
153 | */ | ||
154 | status = acpi_tb_is_table_installed (table_info); | ||
155 | if (ACPI_FAILURE (status)) { | ||
156 | goto unlock_and_exit; | ||
157 | } | ||
158 | |||
151 | /* Install the table into the global data structure */ | 159 | /* Install the table into the global data structure */ |
152 | 160 | ||
153 | status = acpi_tb_init_table_descriptor (table_info->type, table_info); | 161 | status = acpi_tb_init_table_descriptor (table_info->type, table_info); |
154 | if (ACPI_FAILURE (status)) { | 162 | if (ACPI_FAILURE (status)) { |
155 | ACPI_REPORT_ERROR (("Could not install ACPI table [%4.4s], %s\n", | 163 | ACPI_REPORT_ERROR (("Could not install table [%4.4s], %s\n", |
156 | table_info->pointer->signature, acpi_format_exception (status))); | 164 | table_info->pointer->signature, acpi_format_exception (status))); |
157 | } | 165 | } |
158 | 166 | ||
159 | ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "%s located at %p\n", | 167 | ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "%s located at %p\n", |
160 | acpi_gbl_table_data[table_info->type].name, table_info->pointer)); | 168 | acpi_gbl_table_data[table_info->type].name, table_info->pointer)); |
161 | 169 | ||
170 | |||
171 | unlock_and_exit: | ||
162 | (void) acpi_ut_release_mutex (ACPI_MTX_TABLES); | 172 | (void) acpi_ut_release_mutex (ACPI_MTX_TABLES); |
163 | return_ACPI_STATUS (status); | 173 | return_ACPI_STATUS (status); |
164 | } | 174 | } |
@@ -251,6 +261,7 @@ acpi_tb_init_table_descriptor ( | |||
251 | { | 261 | { |
252 | struct acpi_table_list *list_head; | 262 | struct acpi_table_list *list_head; |
253 | struct acpi_table_desc *table_desc; | 263 | struct acpi_table_desc *table_desc; |
264 | acpi_status status; | ||
254 | 265 | ||
255 | 266 | ||
256 | ACPI_FUNCTION_TRACE_U32 ("tb_init_table_descriptor", table_type); | 267 | ACPI_FUNCTION_TRACE_U32 ("tb_init_table_descriptor", table_type); |
@@ -263,6 +274,13 @@ acpi_tb_init_table_descriptor ( | |||
263 | return_ACPI_STATUS (AE_NO_MEMORY); | 274 | return_ACPI_STATUS (AE_NO_MEMORY); |
264 | } | 275 | } |
265 | 276 | ||
277 | /* Get a new owner ID for the table */ | ||
278 | |||
279 | status = acpi_ut_allocate_owner_id (&table_desc->owner_id); | ||
280 | if (ACPI_FAILURE (status)) { | ||
281 | return_ACPI_STATUS (status); | ||
282 | } | ||
283 | |||
266 | /* Install the table into the global data structure */ | 284 | /* Install the table into the global data structure */ |
267 | 285 | ||
268 | list_head = &acpi_gbl_table_lists[table_type]; | 286 | list_head = &acpi_gbl_table_lists[table_type]; |
@@ -325,8 +343,6 @@ acpi_tb_init_table_descriptor ( | |||
325 | table_desc->aml_start = (u8 *) (table_desc->pointer + 1), | 343 | table_desc->aml_start = (u8 *) (table_desc->pointer + 1), |
326 | table_desc->aml_length = (u32) (table_desc->length - | 344 | table_desc->aml_length = (u32) (table_desc->length - |
327 | (u32) sizeof (struct acpi_table_header)); | 345 | (u32) sizeof (struct acpi_table_header)); |
328 | table_desc->table_id = acpi_ut_allocate_owner_id ( | ||
329 | ACPI_OWNER_TYPE_TABLE); | ||
330 | table_desc->loaded_into_namespace = FALSE; | 346 | table_desc->loaded_into_namespace = FALSE; |
331 | 347 | ||
332 | /* | 348 | /* |
@@ -339,7 +355,7 @@ acpi_tb_init_table_descriptor ( | |||
339 | 355 | ||
340 | /* Return Data */ | 356 | /* Return Data */ |
341 | 357 | ||
342 | table_info->table_id = table_desc->table_id; | 358 | table_info->owner_id = table_desc->owner_id; |
343 | table_info->installed_desc = table_desc; | 359 | table_info->installed_desc = table_desc; |
344 | 360 | ||
345 | return_ACPI_STATUS (AE_OK); | 361 | return_ACPI_STATUS (AE_OK); |
diff --git a/drivers/acpi/tables/tbrsdt.c b/drivers/acpi/tables/tbrsdt.c index b7ffe39c3626..069d498465d0 100644 --- a/drivers/acpi/tables/tbrsdt.c +++ b/drivers/acpi/tables/tbrsdt.c | |||
@@ -96,32 +96,13 @@ acpi_tb_verify_rsdp ( | |||
96 | return_ACPI_STATUS (AE_BAD_PARAMETER); | 96 | return_ACPI_STATUS (AE_BAD_PARAMETER); |
97 | } | 97 | } |
98 | 98 | ||
99 | /* | 99 | /* Verify RSDP signature and checksum */ |
100 | * The signature and checksum must both be correct | ||
101 | */ | ||
102 | if (ACPI_STRNCMP ((char *) rsdp, RSDP_SIG, sizeof (RSDP_SIG)-1) != 0) { | ||
103 | /* Nope, BAD Signature */ | ||
104 | |||
105 | status = AE_BAD_SIGNATURE; | ||
106 | goto cleanup; | ||
107 | } | ||
108 | |||
109 | /* Check the standard checksum */ | ||
110 | 100 | ||
111 | if (acpi_tb_checksum (rsdp, ACPI_RSDP_CHECKSUM_LENGTH) != 0) { | 101 | status = acpi_tb_validate_rsdp (rsdp); |
112 | status = AE_BAD_CHECKSUM; | 102 | if (ACPI_FAILURE (status)) { |
113 | goto cleanup; | 103 | goto cleanup; |
114 | } | 104 | } |
115 | 105 | ||
116 | /* Check extended checksum if table version >= 2 */ | ||
117 | |||
118 | if (rsdp->revision >= 2) { | ||
119 | if (acpi_tb_checksum (rsdp, ACPI_RSDP_XCHECKSUM_LENGTH) != 0) { | ||
120 | status = AE_BAD_CHECKSUM; | ||
121 | goto cleanup; | ||
122 | } | ||
123 | } | ||
124 | |||
125 | /* The RSDP supplied is OK */ | 106 | /* The RSDP supplied is OK */ |
126 | 107 | ||
127 | table_info.pointer = ACPI_CAST_PTR (struct acpi_table_header, rsdp); | 108 | table_info.pointer = ACPI_CAST_PTR (struct acpi_table_header, rsdp); |
@@ -159,8 +140,8 @@ cleanup: | |||
159 | * | 140 | * |
160 | * RETURN: None, Address | 141 | * RETURN: None, Address |
161 | * | 142 | * |
162 | * DESCRIPTION: Extract the address of the RSDT or XSDT, depending on the | 143 | * DESCRIPTION: Extract the address of either the RSDT or XSDT, depending on the |
163 | * version of the RSDP | 144 | * version of the RSDP and whether the XSDT pointer is valid |
164 | * | 145 | * |
165 | ******************************************************************************/ | 146 | ******************************************************************************/ |
166 | 147 | ||
@@ -174,16 +155,19 @@ acpi_tb_get_rsdt_address ( | |||
174 | 155 | ||
175 | out_address->pointer_type = acpi_gbl_table_flags | ACPI_LOGICAL_ADDRESSING; | 156 | out_address->pointer_type = acpi_gbl_table_flags | ACPI_LOGICAL_ADDRESSING; |
176 | 157 | ||
177 | /* | 158 | /* Use XSDT if it is present */ |
178 | * For RSDP revision 0 or 1, we use the RSDT. | 159 | |
179 | * For RSDP revision 2 (and above), we use the XSDT | 160 | if ((acpi_gbl_RSDP->revision >= 2) && |
180 | */ | 161 | acpi_gbl_RSDP->xsdt_physical_address) { |
181 | if (acpi_gbl_RSDP->revision < 2) { | ||
182 | out_address->pointer.value = acpi_gbl_RSDP->rsdt_physical_address; | ||
183 | } | ||
184 | else { | ||
185 | out_address->pointer.value = | 162 | out_address->pointer.value = |
186 | acpi_gbl_RSDP->xsdt_physical_address; | 163 | acpi_gbl_RSDP->xsdt_physical_address; |
164 | acpi_gbl_root_table_type = ACPI_TABLE_TYPE_XSDT; | ||
165 | } | ||
166 | else { | ||
167 | /* No XSDT, use the RSDT */ | ||
168 | |||
169 | out_address->pointer.value = acpi_gbl_RSDP->rsdt_physical_address; | ||
170 | acpi_gbl_root_table_type = ACPI_TABLE_TYPE_RSDT; | ||
187 | } | 171 | } |
188 | } | 172 | } |
189 | 173 | ||
@@ -211,10 +195,9 @@ acpi_tb_validate_rsdt ( | |||
211 | 195 | ||
212 | 196 | ||
213 | /* | 197 | /* |
214 | * For RSDP revision 0 or 1, we use the RSDT. | 198 | * Search for appropriate signature, RSDT or XSDT |
215 | * For RSDP revision 2 and above, we use the XSDT | ||
216 | */ | 199 | */ |
217 | if (acpi_gbl_RSDP->revision < 2) { | 200 | if (acpi_gbl_root_table_type == ACPI_TABLE_TYPE_RSDT) { |
218 | no_match = ACPI_STRNCMP ((char *) table_ptr, RSDT_SIG, | 201 | no_match = ACPI_STRNCMP ((char *) table_ptr, RSDT_SIG, |
219 | sizeof (RSDT_SIG) -1); | 202 | sizeof (RSDT_SIG) -1); |
220 | } | 203 | } |
@@ -236,11 +219,11 @@ acpi_tb_validate_rsdt ( | |||
236 | acpi_gbl_RSDP->rsdt_physical_address, | 219 | acpi_gbl_RSDP->rsdt_physical_address, |
237 | (void *) (acpi_native_uint) acpi_gbl_RSDP->rsdt_physical_address)); | 220 | (void *) (acpi_native_uint) acpi_gbl_RSDP->rsdt_physical_address)); |
238 | 221 | ||
239 | if (acpi_gbl_RSDP->revision < 2) { | 222 | if (acpi_gbl_root_table_type == ACPI_TABLE_TYPE_RSDT) { |
240 | ACPI_REPORT_ERROR (("Looking for RSDT (RSDP->Rev < 2)\n")) | 223 | ACPI_REPORT_ERROR (("Looking for RSDT\n")) |
241 | } | 224 | } |
242 | else { | 225 | else { |
243 | ACPI_REPORT_ERROR (("Looking for XSDT (RSDP->Rev >= 2)\n")) | 226 | ACPI_REPORT_ERROR (("Looking for XSDT\n")) |
244 | } | 227 | } |
245 | 228 | ||
246 | ACPI_DUMP_BUFFER ((char *) table_ptr, 48); | 229 | ACPI_DUMP_BUFFER ((char *) table_ptr, 48); |
diff --git a/drivers/acpi/tables/tbutils.c b/drivers/acpi/tables/tbutils.c index e69d01d443d2..6fc1e36e6042 100644 --- a/drivers/acpi/tables/tbutils.c +++ b/drivers/acpi/tables/tbutils.c | |||
@@ -61,6 +61,67 @@ acpi_tb_handle_to_object ( | |||
61 | 61 | ||
62 | /******************************************************************************* | 62 | /******************************************************************************* |
63 | * | 63 | * |
64 | * FUNCTION: acpi_tb_is_table_installed | ||
65 | * | ||
66 | * PARAMETERS: new_table_desc - Descriptor for new table being installed | ||
67 | * | ||
68 | * RETURN: Status - AE_ALREADY_EXISTS if the table is already installed | ||
69 | * | ||
70 | * DESCRIPTION: Determine if an ACPI table is already installed | ||
71 | * | ||
72 | * MUTEX: Table data structures should be locked | ||
73 | * | ||
74 | ******************************************************************************/ | ||
75 | |||
76 | acpi_status | ||
77 | acpi_tb_is_table_installed ( | ||
78 | struct acpi_table_desc *new_table_desc) | ||
79 | { | ||
80 | struct acpi_table_desc *table_desc; | ||
81 | |||
82 | |||
83 | ACPI_FUNCTION_TRACE ("tb_is_table_installed"); | ||
84 | |||
85 | |||
86 | /* Get the list descriptor and first table descriptor */ | ||
87 | |||
88 | table_desc = acpi_gbl_table_lists[new_table_desc->type].next; | ||
89 | |||
90 | /* Examine all installed tables of this type */ | ||
91 | |||
92 | while (table_desc) { | ||
93 | /* Compare Revision and oem_table_id */ | ||
94 | |||
95 | if ((table_desc->loaded_into_namespace) && | ||
96 | (table_desc->pointer->revision == | ||
97 | new_table_desc->pointer->revision) && | ||
98 | (!ACPI_MEMCMP (table_desc->pointer->oem_table_id, | ||
99 | new_table_desc->pointer->oem_table_id, 8))) { | ||
100 | /* This table is already installed */ | ||
101 | |||
102 | ACPI_DEBUG_PRINT ((ACPI_DB_TABLES, | ||
103 | "Table [%4.4s] already installed: Rev %X oem_table_id [%8.8s]\n", | ||
104 | new_table_desc->pointer->signature, | ||
105 | new_table_desc->pointer->revision, | ||
106 | new_table_desc->pointer->oem_table_id)); | ||
107 | |||
108 | new_table_desc->owner_id = table_desc->owner_id; | ||
109 | new_table_desc->installed_desc = table_desc; | ||
110 | |||
111 | return_ACPI_STATUS (AE_ALREADY_EXISTS); | ||
112 | } | ||
113 | |||
114 | /* Get next table on the list */ | ||
115 | |||
116 | table_desc = table_desc->next; | ||
117 | } | ||
118 | |||
119 | return_ACPI_STATUS (AE_OK); | ||
120 | } | ||
121 | |||
122 | |||
123 | /******************************************************************************* | ||
124 | * | ||
64 | * FUNCTION: acpi_tb_validate_table_header | 125 | * FUNCTION: acpi_tb_validate_table_header |
65 | * | 126 | * |
66 | * PARAMETERS: table_header - Logical pointer to the table | 127 | * PARAMETERS: table_header - Logical pointer to the table |
@@ -157,7 +218,7 @@ acpi_tb_verify_table_checksum ( | |||
157 | 218 | ||
158 | /* Compute the checksum on the table */ | 219 | /* Compute the checksum on the table */ |
159 | 220 | ||
160 | checksum = acpi_tb_checksum (table_header, table_header->length); | 221 | checksum = acpi_tb_generate_checksum (table_header, table_header->length); |
161 | 222 | ||
162 | /* Return the appropriate exception */ | 223 | /* Return the appropriate exception */ |
163 | 224 | ||
@@ -175,7 +236,7 @@ acpi_tb_verify_table_checksum ( | |||
175 | 236 | ||
176 | /******************************************************************************* | 237 | /******************************************************************************* |
177 | * | 238 | * |
178 | * FUNCTION: acpi_tb_checksum | 239 | * FUNCTION: acpi_tb_generate_checksum |
179 | * | 240 | * |
180 | * PARAMETERS: Buffer - Buffer to checksum | 241 | * PARAMETERS: Buffer - Buffer to checksum |
181 | * Length - Size of the buffer | 242 | * Length - Size of the buffer |
@@ -187,7 +248,7 @@ acpi_tb_verify_table_checksum ( | |||
187 | ******************************************************************************/ | 248 | ******************************************************************************/ |
188 | 249 | ||
189 | u8 | 250 | u8 |
190 | acpi_tb_checksum ( | 251 | acpi_tb_generate_checksum ( |
191 | void *buffer, | 252 | void *buffer, |
192 | u32 length) | 253 | u32 length) |
193 | { | 254 | { |
diff --git a/drivers/acpi/tables/tbxface.c b/drivers/acpi/tables/tbxface.c index 0c0b9085dbeb..e18a05d1b9b3 100644 --- a/drivers/acpi/tables/tbxface.c +++ b/drivers/acpi/tables/tbxface.c | |||
@@ -182,10 +182,23 @@ acpi_load_table ( | |||
182 | return_ACPI_STATUS (status); | 182 | return_ACPI_STATUS (status); |
183 | } | 183 | } |
184 | 184 | ||
185 | /* Check signature for a valid table type */ | ||
186 | |||
187 | status = acpi_tb_recognize_table (&table_info, ACPI_TABLE_ALL); | ||
188 | if (ACPI_FAILURE (status)) { | ||
189 | return_ACPI_STATUS (status); | ||
190 | } | ||
191 | |||
185 | /* Install the new table into the local data structures */ | 192 | /* Install the new table into the local data structures */ |
186 | 193 | ||
187 | status = acpi_tb_install_table (&table_info); | 194 | status = acpi_tb_install_table (&table_info); |
188 | if (ACPI_FAILURE (status)) { | 195 | if (ACPI_FAILURE (status)) { |
196 | if (status == AE_ALREADY_EXISTS) { | ||
197 | /* Table already exists, no error */ | ||
198 | |||
199 | status = AE_OK; | ||
200 | } | ||
201 | |||
189 | /* Free table allocated by acpi_tb_get_table_body */ | 202 | /* Free table allocated by acpi_tb_get_table_body */ |
190 | 203 | ||
191 | acpi_tb_delete_single_table (&table_info); | 204 | acpi_tb_delete_single_table (&table_info); |
@@ -260,8 +273,8 @@ acpi_unload_table ( | |||
260 | * "Scope" operator. Thus, we need to track ownership by an ID, not | 273 | * "Scope" operator. Thus, we need to track ownership by an ID, not |
261 | * simply a position within the hierarchy | 274 | * simply a position within the hierarchy |
262 | */ | 275 | */ |
263 | acpi_ns_delete_namespace_by_owner (table_desc->table_id); | 276 | acpi_ns_delete_namespace_by_owner (table_desc->owner_id); |
264 | 277 | acpi_ut_release_owner_id (&table_desc->owner_id); | |
265 | table_desc = table_desc->next; | 278 | table_desc = table_desc->next; |
266 | } | 279 | } |
267 | 280 | ||
diff --git a/drivers/acpi/tables/tbxfroot.c b/drivers/acpi/tables/tbxfroot.c index dc3c3f6a9f62..87dccdda9ae2 100644 --- a/drivers/acpi/tables/tbxfroot.c +++ b/drivers/acpi/tables/tbxfroot.c | |||
@@ -65,6 +65,51 @@ acpi_tb_scan_memory_for_rsdp ( | |||
65 | 65 | ||
66 | /******************************************************************************* | 66 | /******************************************************************************* |
67 | * | 67 | * |
68 | * FUNCTION: acpi_tb_validate_rsdp | ||
69 | * | ||
70 | * PARAMETERS: Rsdp - Pointer to unvalidated RSDP | ||
71 | * | ||
72 | * RETURN: Status | ||
73 | * | ||
74 | * DESCRIPTION: Validate the RSDP (ptr) | ||
75 | * | ||
76 | ******************************************************************************/ | ||
77 | |||
78 | acpi_status | ||
79 | acpi_tb_validate_rsdp ( | ||
80 | struct rsdp_descriptor *rsdp) | ||
81 | { | ||
82 | ACPI_FUNCTION_ENTRY (); | ||
83 | |||
84 | |||
85 | /* | ||
86 | * The signature and checksum must both be correct | ||
87 | */ | ||
88 | if (ACPI_STRNCMP ((char *) rsdp, RSDP_SIG, sizeof (RSDP_SIG)-1) != 0) { | ||
89 | /* Nope, BAD Signature */ | ||
90 | |||
91 | return (AE_BAD_SIGNATURE); | ||
92 | } | ||
93 | |||
94 | /* Check the standard checksum */ | ||
95 | |||
96 | if (acpi_tb_generate_checksum (rsdp, ACPI_RSDP_CHECKSUM_LENGTH) != 0) { | ||
97 | return (AE_BAD_CHECKSUM); | ||
98 | } | ||
99 | |||
100 | /* Check extended checksum if table version >= 2 */ | ||
101 | |||
102 | if ((rsdp->revision >= 2) && | ||
103 | (acpi_tb_generate_checksum (rsdp, ACPI_RSDP_XCHECKSUM_LENGTH) != 0)) { | ||
104 | return (AE_BAD_CHECKSUM); | ||
105 | } | ||
106 | |||
107 | return (AE_OK); | ||
108 | } | ||
109 | |||
110 | |||
111 | /******************************************************************************* | ||
112 | * | ||
68 | * FUNCTION: acpi_tb_find_table | 113 | * FUNCTION: acpi_tb_find_table |
69 | * | 114 | * |
70 | * PARAMETERS: Signature - String with ACPI table signature | 115 | * PARAMETERS: Signature - String with ACPI table signature |
@@ -218,19 +263,11 @@ acpi_get_firmware_table ( | |||
218 | acpi_gbl_RSDP = address.pointer.logical; | 263 | acpi_gbl_RSDP = address.pointer.logical; |
219 | } | 264 | } |
220 | 265 | ||
221 | /* The signature and checksum must both be correct */ | 266 | /* The RDSP signature and checksum must both be correct */ |
222 | |||
223 | if (ACPI_STRNCMP ((char *) acpi_gbl_RSDP, RSDP_SIG, | ||
224 | sizeof (RSDP_SIG)-1) != 0) { | ||
225 | /* Nope, BAD Signature */ | ||
226 | |||
227 | return_ACPI_STATUS (AE_BAD_SIGNATURE); | ||
228 | } | ||
229 | |||
230 | if (acpi_tb_checksum (acpi_gbl_RSDP, ACPI_RSDP_CHECKSUM_LENGTH) != 0) { | ||
231 | /* Nope, BAD Checksum */ | ||
232 | 267 | ||
233 | return_ACPI_STATUS (AE_BAD_CHECKSUM); | 268 | status = acpi_tb_validate_rsdp (acpi_gbl_RSDP); |
269 | if (ACPI_FAILURE (status)) { | ||
270 | return_ACPI_STATUS (status); | ||
234 | } | 271 | } |
235 | } | 272 | } |
236 | 273 | ||
@@ -287,9 +324,11 @@ acpi_get_firmware_table ( | |||
287 | * requested table | 324 | * requested table |
288 | */ | 325 | */ |
289 | for (i = 0, j = 0; i < table_count; i++) { | 326 | for (i = 0, j = 0; i < table_count; i++) { |
290 | /* Get the next table pointer, handle RSDT vs. XSDT */ | 327 | /* |
291 | 328 | * Get the next table pointer, handle RSDT vs. XSDT | |
292 | if (acpi_gbl_RSDP->revision < 2) { | 329 | * RSDT pointers are 32 bits, XSDT pointers are 64 bits |
330 | */ | ||
331 | if (acpi_gbl_root_table_type == ACPI_TABLE_TYPE_RSDT) { | ||
293 | address.pointer.value = (ACPI_CAST_PTR ( | 332 | address.pointer.value = (ACPI_CAST_PTR ( |
294 | RSDT_DESCRIPTOR, rsdt_info->pointer))->table_offset_entry[i]; | 333 | RSDT_DESCRIPTOR, rsdt_info->pointer))->table_offset_entry[i]; |
295 | } | 334 | } |
@@ -331,8 +370,10 @@ acpi_get_firmware_table ( | |||
331 | 370 | ||
332 | 371 | ||
333 | cleanup: | 372 | cleanup: |
334 | acpi_os_unmap_memory (rsdt_info->pointer, | 373 | if (rsdt_info->pointer) { |
335 | (acpi_size) rsdt_info->pointer->length); | 374 | acpi_os_unmap_memory (rsdt_info->pointer, |
375 | (acpi_size) rsdt_info->pointer->length); | ||
376 | } | ||
336 | ACPI_MEM_FREE (rsdt_info); | 377 | ACPI_MEM_FREE (rsdt_info); |
337 | 378 | ||
338 | if (header) { | 379 | if (header) { |
@@ -410,9 +451,9 @@ acpi_tb_scan_memory_for_rsdp ( | |||
410 | u8 *start_address, | 451 | u8 *start_address, |
411 | u32 length) | 452 | u32 length) |
412 | { | 453 | { |
454 | acpi_status status; | ||
413 | u8 *mem_rover; | 455 | u8 *mem_rover; |
414 | u8 *end_address; | 456 | u8 *end_address; |
415 | u8 checksum; | ||
416 | 457 | ||
417 | 458 | ||
418 | ACPI_FUNCTION_TRACE ("tb_scan_memory_for_rsdp"); | 459 | ACPI_FUNCTION_TRACE ("tb_scan_memory_for_rsdp"); |
@@ -424,45 +465,25 @@ acpi_tb_scan_memory_for_rsdp ( | |||
424 | 465 | ||
425 | for (mem_rover = start_address; mem_rover < end_address; | 466 | for (mem_rover = start_address; mem_rover < end_address; |
426 | mem_rover += ACPI_RSDP_SCAN_STEP) { | 467 | mem_rover += ACPI_RSDP_SCAN_STEP) { |
427 | /* The signature and checksum must both be correct */ | 468 | /* The RSDP signature and checksum must both be correct */ |
428 | |||
429 | if (ACPI_STRNCMP ((char *) mem_rover, | ||
430 | RSDP_SIG, sizeof (RSDP_SIG) - 1) != 0) { | ||
431 | /* No signature match, keep looking */ | ||
432 | |||
433 | continue; | ||
434 | } | ||
435 | |||
436 | /* Signature matches, check the appropriate checksum */ | ||
437 | |||
438 | if ((ACPI_CAST_PTR (struct rsdp_descriptor, mem_rover))->revision < 2) { | ||
439 | /* ACPI version 1.0 */ | ||
440 | 469 | ||
441 | checksum = acpi_tb_checksum (mem_rover, ACPI_RSDP_CHECKSUM_LENGTH); | 470 | status = acpi_tb_validate_rsdp (ACPI_CAST_PTR (struct rsdp_descriptor, mem_rover)); |
442 | } | 471 | if (ACPI_SUCCESS (status)) { |
443 | else { | 472 | /* Sig and checksum valid, we have found a real RSDP */ |
444 | /* Post ACPI 1.0, use extended_checksum */ | ||
445 | |||
446 | checksum = acpi_tb_checksum (mem_rover, ACPI_RSDP_XCHECKSUM_LENGTH); | ||
447 | } | ||
448 | |||
449 | if (checksum == 0) { | ||
450 | /* Checksum valid, we have found a valid RSDP */ | ||
451 | 473 | ||
452 | ACPI_DEBUG_PRINT ((ACPI_DB_INFO, | 474 | ACPI_DEBUG_PRINT ((ACPI_DB_INFO, |
453 | "RSDP located at physical address %p\n", mem_rover)); | 475 | "RSDP located at physical address %p\n", mem_rover)); |
454 | return_PTR (mem_rover); | 476 | return_PTR (mem_rover); |
455 | } | 477 | } |
456 | 478 | ||
457 | ACPI_DEBUG_PRINT ((ACPI_DB_INFO, | 479 | /* No sig match or bad checksum, keep searching */ |
458 | "Found an RSDP at physical address %p, but it has a bad checksum\n", | ||
459 | mem_rover)); | ||
460 | } | 480 | } |
461 | 481 | ||
462 | /* Searched entire block, no RSDP was found */ | 482 | /* Searched entire block, no RSDP was found */ |
463 | 483 | ||
464 | ACPI_DEBUG_PRINT ((ACPI_DB_INFO, | 484 | ACPI_DEBUG_PRINT ((ACPI_DB_INFO, |
465 | "Searched entire block, no valid RSDP was found.\n")); | 485 | "Searched entire block from %p, valid RSDP was not found\n", |
486 | start_address)); | ||
466 | return_PTR (NULL); | 487 | return_PTR (NULL); |
467 | } | 488 | } |
468 | 489 | ||
@@ -550,7 +571,7 @@ acpi_tb_find_rsdp ( | |||
550 | acpi_os_unmap_memory (table_ptr, ACPI_EBDA_WINDOW_SIZE); | 571 | acpi_os_unmap_memory (table_ptr, ACPI_EBDA_WINDOW_SIZE); |
551 | 572 | ||
552 | if (mem_rover) { | 573 | if (mem_rover) { |
553 | /* Found it, return the physical address */ | 574 | /* Return the physical address */ |
554 | 575 | ||
555 | physical_address += ACPI_PTR_DIFF (mem_rover, table_ptr); | 576 | physical_address += ACPI_PTR_DIFF (mem_rover, table_ptr); |
556 | 577 | ||
@@ -579,7 +600,7 @@ acpi_tb_find_rsdp ( | |||
579 | acpi_os_unmap_memory (table_ptr, ACPI_HI_RSDP_WINDOW_SIZE); | 600 | acpi_os_unmap_memory (table_ptr, ACPI_HI_RSDP_WINDOW_SIZE); |
580 | 601 | ||
581 | if (mem_rover) { | 602 | if (mem_rover) { |
582 | /* Found it, return the physical address */ | 603 | /* Return the physical address */ |
583 | 604 | ||
584 | physical_address = | 605 | physical_address = |
585 | ACPI_HI_RSDP_WINDOW_BASE + ACPI_PTR_DIFF (mem_rover, table_ptr); | 606 | ACPI_HI_RSDP_WINDOW_BASE + ACPI_PTR_DIFF (mem_rover, table_ptr); |
@@ -610,7 +631,7 @@ acpi_tb_find_rsdp ( | |||
610 | ACPI_PHYSADDR_TO_PTR (physical_address), | 631 | ACPI_PHYSADDR_TO_PTR (physical_address), |
611 | ACPI_EBDA_WINDOW_SIZE); | 632 | ACPI_EBDA_WINDOW_SIZE); |
612 | if (mem_rover) { | 633 | if (mem_rover) { |
613 | /* Found it, return the physical address */ | 634 | /* Return the physical address */ |
614 | 635 | ||
615 | table_info->physical_address = ACPI_TO_INTEGER (mem_rover); | 636 | table_info->physical_address = ACPI_TO_INTEGER (mem_rover); |
616 | return_ACPI_STATUS (AE_OK); | 637 | return_ACPI_STATUS (AE_OK); |
@@ -630,8 +651,9 @@ acpi_tb_find_rsdp ( | |||
630 | } | 651 | } |
631 | } | 652 | } |
632 | 653 | ||
633 | /* RSDP signature was not found */ | 654 | /* A valid RSDP was not found */ |
634 | 655 | ||
656 | ACPI_REPORT_ERROR (("No valid RSDP was found\n")); | ||
635 | return_ACPI_STATUS (AE_NOT_FOUND); | 657 | return_ACPI_STATUS (AE_NOT_FOUND); |
636 | } | 658 | } |
637 | 659 | ||