| .. | .. |
|---|
| 3 | 3 | * |
|---|
| 4 | 4 | * Module Name: exregion - ACPI default op_region (address space) handlers |
|---|
| 5 | 5 | * |
|---|
| 6 | | - * Copyright (C) 2000 - 2018, Intel Corp. |
|---|
| 6 | + * Copyright (C) 2000 - 2020, Intel Corp. |
|---|
| 7 | 7 | * |
|---|
| 8 | 8 | *****************************************************************************/ |
|---|
| 9 | 9 | |
|---|
| .. | .. |
|---|
| 41 | 41 | acpi_status status = AE_OK; |
|---|
| 42 | 42 | void *logical_addr_ptr = NULL; |
|---|
| 43 | 43 | struct acpi_mem_space_context *mem_info = region_context; |
|---|
| 44 | + struct acpi_mem_mapping *mm = mem_info->cur_mm; |
|---|
| 44 | 45 | u32 length; |
|---|
| 45 | 46 | acpi_size map_length; |
|---|
| 46 | 47 | acpi_size page_boundary_map_length; |
|---|
| .. | .. |
|---|
| 96 | 97 | * Is 1) Address below the current mapping? OR |
|---|
| 97 | 98 | * 2) Address beyond the current mapping? |
|---|
| 98 | 99 | */ |
|---|
| 99 | | - if ((address < mem_info->mapped_physical_address) || |
|---|
| 100 | | - (((u64) address + length) > ((u64) |
|---|
| 101 | | - mem_info->mapped_physical_address + |
|---|
| 102 | | - mem_info->mapped_length))) { |
|---|
| 100 | + if (!mm || (address < mm->physical_address) || |
|---|
| 101 | + ((u64) address + length > (u64) mm->physical_address + mm->length)) { |
|---|
| 103 | 102 | /* |
|---|
| 104 | | - * The request cannot be resolved by the current memory mapping; |
|---|
| 105 | | - * Delete the existing mapping and create a new one. |
|---|
| 103 | + * The request cannot be resolved by the current memory mapping. |
|---|
| 104 | + * |
|---|
| 105 | + * Look for an existing saved mapping covering the address range |
|---|
| 106 | + * at hand. If found, save it as the current one and carry out |
|---|
| 107 | + * the access. |
|---|
| 106 | 108 | */ |
|---|
| 107 | | - if (mem_info->mapped_length) { |
|---|
| 109 | + for (mm = mem_info->first_mm; mm; mm = mm->next_mm) { |
|---|
| 110 | + if (mm == mem_info->cur_mm) |
|---|
| 111 | + continue; |
|---|
| 108 | 112 | |
|---|
| 109 | | - /* Valid mapping, delete it */ |
|---|
| 113 | + if (address < mm->physical_address) |
|---|
| 114 | + continue; |
|---|
| 110 | 115 | |
|---|
| 111 | | - acpi_os_unmap_memory(mem_info->mapped_logical_address, |
|---|
| 112 | | - mem_info->mapped_length); |
|---|
| 116 | + if ((u64) address + length > |
|---|
| 117 | + (u64) mm->physical_address + mm->length) |
|---|
| 118 | + continue; |
|---|
| 119 | + |
|---|
| 120 | + mem_info->cur_mm = mm; |
|---|
| 121 | + goto access; |
|---|
| 122 | + } |
|---|
| 123 | + |
|---|
| 124 | + /* Create a new mappings list entry */ |
|---|
| 125 | + mm = ACPI_ALLOCATE_ZEROED(sizeof(*mm)); |
|---|
| 126 | + if (!mm) { |
|---|
| 127 | + ACPI_ERROR((AE_INFO, |
|---|
| 128 | + "Unable to save memory mapping at 0x%8.8X%8.8X, size %u", |
|---|
| 129 | + ACPI_FORMAT_UINT64(address), length)); |
|---|
| 130 | + return_ACPI_STATUS(AE_NO_MEMORY); |
|---|
| 113 | 131 | } |
|---|
| 114 | 132 | |
|---|
| 115 | 133 | /* |
|---|
| .. | .. |
|---|
| 143 | 161 | |
|---|
| 144 | 162 | /* Create a new mapping starting at the address given */ |
|---|
| 145 | 163 | |
|---|
| 146 | | - mem_info->mapped_logical_address = |
|---|
| 147 | | - acpi_os_map_memory(address, map_length); |
|---|
| 148 | | - if (!mem_info->mapped_logical_address) { |
|---|
| 164 | + logical_addr_ptr = acpi_os_map_memory(address, map_length); |
|---|
| 165 | + if (!logical_addr_ptr) { |
|---|
| 149 | 166 | ACPI_ERROR((AE_INFO, |
|---|
| 150 | 167 | "Could not map memory at 0x%8.8X%8.8X, size %u", |
|---|
| 151 | 168 | ACPI_FORMAT_UINT64(address), |
|---|
| 152 | 169 | (u32)map_length)); |
|---|
| 153 | | - mem_info->mapped_length = 0; |
|---|
| 170 | + ACPI_FREE(mm); |
|---|
| 154 | 171 | return_ACPI_STATUS(AE_NO_MEMORY); |
|---|
| 155 | 172 | } |
|---|
| 156 | 173 | |
|---|
| 157 | 174 | /* Save the physical address and mapping size */ |
|---|
| 158 | 175 | |
|---|
| 159 | | - mem_info->mapped_physical_address = address; |
|---|
| 160 | | - mem_info->mapped_length = map_length; |
|---|
| 176 | + mm->logical_address = logical_addr_ptr; |
|---|
| 177 | + mm->physical_address = address; |
|---|
| 178 | + mm->length = map_length; |
|---|
| 179 | + |
|---|
| 180 | + /* |
|---|
| 181 | + * Add the new entry to the mappigs list and save it as the |
|---|
| 182 | + * current mapping. |
|---|
| 183 | + */ |
|---|
| 184 | + mm->next_mm = mem_info->first_mm; |
|---|
| 185 | + mem_info->first_mm = mm; |
|---|
| 186 | + |
|---|
| 187 | + mem_info->cur_mm = mm; |
|---|
| 161 | 188 | } |
|---|
| 162 | 189 | |
|---|
| 190 | +access: |
|---|
| 163 | 191 | /* |
|---|
| 164 | 192 | * Generate a logical pointer corresponding to the address we want to |
|---|
| 165 | 193 | * access |
|---|
| 166 | 194 | */ |
|---|
| 167 | | - logical_addr_ptr = mem_info->mapped_logical_address + |
|---|
| 168 | | - ((u64) address - (u64) mem_info->mapped_physical_address); |
|---|
| 195 | + logical_addr_ptr = mm->logical_address + |
|---|
| 196 | + ((u64) address - (u64) mm->physical_address); |
|---|
| 169 | 197 | |
|---|
| 170 | 198 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
|---|
| 171 | 199 | "System-Memory (width %u) R/W %u Address=%8.8X%8.8X\n", |
|---|
| .. | .. |
|---|
| 311 | 339 | return_ACPI_STATUS(status); |
|---|
| 312 | 340 | } |
|---|
| 313 | 341 | |
|---|
| 342 | +#ifdef ACPI_PCI_CONFIGURED |
|---|
| 314 | 343 | /******************************************************************************* |
|---|
| 315 | 344 | * |
|---|
| 316 | 345 | * FUNCTION: acpi_ex_pci_config_space_handler |
|---|
| .. | .. |
|---|
| 387 | 416 | |
|---|
| 388 | 417 | return_ACPI_STATUS(status); |
|---|
| 389 | 418 | } |
|---|
| 419 | +#endif |
|---|
| 390 | 420 | |
|---|
| 391 | 421 | /******************************************************************************* |
|---|
| 392 | 422 | * |
|---|
| .. | .. |
|---|
| 420 | 450 | return_ACPI_STATUS(status); |
|---|
| 421 | 451 | } |
|---|
| 422 | 452 | |
|---|
| 453 | +#ifdef ACPI_PCI_CONFIGURED |
|---|
| 423 | 454 | /******************************************************************************* |
|---|
| 424 | 455 | * |
|---|
| 425 | 456 | * FUNCTION: acpi_ex_pci_bar_space_handler |
|---|
| .. | .. |
|---|
| 451 | 482 | |
|---|
| 452 | 483 | return_ACPI_STATUS(status); |
|---|
| 453 | 484 | } |
|---|
| 485 | +#endif |
|---|
| 454 | 486 | |
|---|
| 455 | 487 | /******************************************************************************* |
|---|
| 456 | 488 | * |
|---|