0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <acpi/acpi.h>
0011 #include "accommon.h"
0012 #include "actables.h"
0013
0014 #define _COMPONENT ACPI_TABLES
0015 ACPI_MODULE_NAME("tbxfroot")
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028 u32 acpi_tb_get_rsdp_length(struct acpi_table_rsdp *rsdp)
0029 {
0030
0031 if (!ACPI_VALIDATE_RSDP_SIG(rsdp->signature)) {
0032
0033
0034
0035 return (0);
0036 }
0037
0038
0039
0040 if (rsdp->revision >= 2) {
0041 return (rsdp->length);
0042 } else {
0043 return (ACPI_RSDP_CHECKSUM_LENGTH);
0044 }
0045 }
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059 acpi_status acpi_tb_validate_rsdp(struct acpi_table_rsdp *rsdp)
0060 {
0061
0062
0063
0064
0065
0066
0067
0068 if (!ACPI_VALIDATE_RSDP_SIG(rsdp->signature)) {
0069
0070
0071
0072 return (AE_BAD_SIGNATURE);
0073 }
0074
0075
0076
0077 if (acpi_tb_checksum((u8 *) rsdp, ACPI_RSDP_CHECKSUM_LENGTH) != 0) {
0078 return (AE_BAD_CHECKSUM);
0079 }
0080
0081
0082
0083 if ((rsdp->revision >= 2) &&
0084 (acpi_tb_checksum((u8 *) rsdp, ACPI_RSDP_XCHECKSUM_LENGTH) != 0)) {
0085 return (AE_BAD_CHECKSUM);
0086 }
0087
0088 return (AE_OK);
0089 }
0090
0091
0092
0093
0094
0095
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106
0107
0108
0109
0110
0111 acpi_status ACPI_INIT_FUNCTION
0112 acpi_find_root_pointer(acpi_physical_address *table_address)
0113 {
0114 u8 *table_ptr;
0115 u8 *mem_rover;
0116 u32 physical_address;
0117
0118 ACPI_FUNCTION_TRACE(acpi_find_root_pointer);
0119
0120
0121
0122 table_ptr = acpi_os_map_memory((acpi_physical_address)
0123 ACPI_EBDA_PTR_LOCATION,
0124 ACPI_EBDA_PTR_LENGTH);
0125 if (!table_ptr) {
0126 ACPI_ERROR((AE_INFO,
0127 "Could not map memory at 0x%8.8X for length %u",
0128 ACPI_EBDA_PTR_LOCATION, ACPI_EBDA_PTR_LENGTH));
0129
0130 return_ACPI_STATUS(AE_NO_MEMORY);
0131 }
0132
0133 ACPI_MOVE_16_TO_32(&physical_address, table_ptr);
0134
0135
0136
0137 physical_address <<= 4;
0138 acpi_os_unmap_memory(table_ptr, ACPI_EBDA_PTR_LENGTH);
0139
0140
0141
0142 if (physical_address > 0x400) {
0143
0144
0145
0146
0147 table_ptr = acpi_os_map_memory((acpi_physical_address)
0148 physical_address,
0149 ACPI_EBDA_WINDOW_SIZE);
0150 if (!table_ptr) {
0151 ACPI_ERROR((AE_INFO,
0152 "Could not map memory at 0x%8.8X for length %u",
0153 physical_address, ACPI_EBDA_WINDOW_SIZE));
0154
0155 return_ACPI_STATUS(AE_NO_MEMORY);
0156 }
0157
0158 mem_rover =
0159 acpi_tb_scan_memory_for_rsdp(table_ptr,
0160 ACPI_EBDA_WINDOW_SIZE);
0161 acpi_os_unmap_memory(table_ptr, ACPI_EBDA_WINDOW_SIZE);
0162
0163 if (mem_rover) {
0164
0165
0166
0167 physical_address +=
0168 (u32) ACPI_PTR_DIFF(mem_rover, table_ptr);
0169
0170 *table_address =
0171 (acpi_physical_address)physical_address;
0172 return_ACPI_STATUS(AE_OK);
0173 }
0174 }
0175
0176
0177
0178
0179 table_ptr = acpi_os_map_memory((acpi_physical_address)
0180 ACPI_HI_RSDP_WINDOW_BASE,
0181 ACPI_HI_RSDP_WINDOW_SIZE);
0182
0183 if (!table_ptr) {
0184 ACPI_ERROR((AE_INFO,
0185 "Could not map memory at 0x%8.8X for length %u",
0186 ACPI_HI_RSDP_WINDOW_BASE,
0187 ACPI_HI_RSDP_WINDOW_SIZE));
0188
0189 return_ACPI_STATUS(AE_NO_MEMORY);
0190 }
0191
0192 mem_rover =
0193 acpi_tb_scan_memory_for_rsdp(table_ptr, ACPI_HI_RSDP_WINDOW_SIZE);
0194 acpi_os_unmap_memory(table_ptr, ACPI_HI_RSDP_WINDOW_SIZE);
0195
0196 if (mem_rover) {
0197
0198
0199
0200 physical_address = (u32)
0201 (ACPI_HI_RSDP_WINDOW_BASE +
0202 ACPI_PTR_DIFF(mem_rover, table_ptr));
0203
0204 *table_address = (acpi_physical_address)physical_address;
0205 return_ACPI_STATUS(AE_OK);
0206 }
0207
0208
0209
0210 ACPI_BIOS_ERROR((AE_INFO, "A valid RSDP was not found"));
0211 return_ACPI_STATUS(AE_NOT_FOUND);
0212 }
0213
0214 ACPI_EXPORT_SYMBOL_INIT(acpi_find_root_pointer)
0215
0216
0217
0218
0219
0220
0221
0222
0223
0224
0225
0226
0227
0228 u8 *acpi_tb_scan_memory_for_rsdp(u8 *start_address, u32 length)
0229 {
0230 acpi_status status;
0231 u8 *mem_rover;
0232 u8 *end_address;
0233
0234 ACPI_FUNCTION_TRACE(tb_scan_memory_for_rsdp);
0235
0236 end_address = start_address + length;
0237
0238
0239
0240 for (mem_rover = start_address; mem_rover < end_address;
0241 mem_rover += ACPI_RSDP_SCAN_STEP) {
0242
0243
0244
0245 status =
0246 acpi_tb_validate_rsdp(ACPI_CAST_PTR
0247 (struct acpi_table_rsdp, mem_rover));
0248 if (ACPI_SUCCESS(status)) {
0249
0250
0251
0252 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
0253 "RSDP located at physical address %p\n",
0254 mem_rover));
0255 return_PTR(mem_rover);
0256 }
0257
0258
0259 }
0260
0261
0262
0263 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
0264 "Searched entire block from %p, valid RSDP was not found\n",
0265 start_address));
0266 return_PTR(NULL);
0267 }