void AcpiTbUninstallTable ( ACPI_TABLE_DESC *TableDesc) { ACPI_FUNCTION_TRACE (TbUninstallTable); /* Table must be installed */ if (!TableDesc->Address) { return_VOID; } AcpiTbInvalidateTable (TableDesc); if ((TableDesc->Flags & ACPI_TABLE_ORIGIN_MASK) == ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL) { ACPI_FREE (ACPI_PHYSADDR_TO_PTR (TableDesc->Address)); } TableDesc->Address = ACPI_PTR_TO_PHYSADDR (NULL); return_VOID; }
ACPI_STATUS AcpiTbAcquireTempTable ( ACPI_TABLE_DESC *TableDesc, ACPI_PHYSICAL_ADDRESS Address, UINT8 Flags) { ACPI_TABLE_HEADER *TableHeader; switch (Flags & ACPI_TABLE_ORIGIN_MASK) { case ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL: /* Get the length of the full table from the header */ TableHeader = AcpiOsMapMemory (Address, sizeof (ACPI_TABLE_HEADER)); if (!TableHeader) { return (AE_NO_MEMORY); } AcpiTbInitTableDescriptor (TableDesc, Address, Flags, TableHeader); AcpiOsUnmapMemory (TableHeader, sizeof (ACPI_TABLE_HEADER)); return (AE_OK); case ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL: case ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL: TableHeader = ACPI_CAST_PTR (ACPI_TABLE_HEADER, ACPI_PHYSADDR_TO_PTR (Address)); if (!TableHeader) { return (AE_NO_MEMORY); } AcpiTbInitTableDescriptor (TableDesc, Address, Flags, TableHeader); return (AE_OK); default: break; } /* Table is not valid yet */ return (AE_NO_MEMORY); }
ACPI_STATUS AcpiTbAcquireTable ( ACPI_TABLE_DESC *TableDesc, ACPI_TABLE_HEADER **TablePtr, UINT32 *TableLength, UINT8 *TableFlags) { ACPI_TABLE_HEADER *Table = NULL; switch (TableDesc->Flags & ACPI_TABLE_ORIGIN_MASK) { case ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL: Table = AcpiOsMapMemory (TableDesc->Address, TableDesc->Length); break; case ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL: case ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL: Table = ACPI_CAST_PTR (ACPI_TABLE_HEADER, ACPI_PHYSADDR_TO_PTR (TableDesc->Address)); break; default: break; } /* Table is not valid yet */ if (!Table) { return (AE_NO_MEMORY); } /* Fill the return values */ *TablePtr = Table; *TableLength = TableDesc->Length; *TableFlags = TableDesc->Flags; return (AE_OK); }
acpi_status acpi_tb_acquire_table(struct acpi_table_desc *table_desc, struct acpi_table_header **table_ptr, u32 *table_length, u8 *table_flags) { struct acpi_table_header *table = NULL; switch (table_desc->flags & ACPI_TABLE_ORIGIN_MASK) { case ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL: table = acpi_os_map_memory(table_desc->address, table_desc->length); break; case ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL: case ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL: table = ACPI_CAST_PTR(struct acpi_table_header, ACPI_PHYSADDR_TO_PTR(table_desc-> address)); break; default: break; } /* Table is not valid yet */ if (!table) { return (AE_NO_MEMORY); } /* Fill the return values */ *table_ptr = table; *table_length = table_desc->length; *table_flags = table_desc->flags; return (AE_OK); }
acpi_status acpi_ex_data_table_space_handler ( u32 function, acpi_physical_address address, u32 bit_width, acpi_integer *value, void *handler_context, void *region_context) { acpi_status status = AE_OK; u32 byte_width = ACPI_DIV_8 (bit_width); u32 i; char *logical_addr_ptr; ACPI_FUNCTION_TRACE ("ex_data_table_space_handler"); logical_addr_ptr = ACPI_PHYSADDR_TO_PTR (address); /* Perform the memory read or write */ switch (function) { case ACPI_READ: for (i = 0; i < byte_width; i++) { ((char *) value) [i] = logical_addr_ptr[i]; } break; case ACPI_WRITE: default: return_ACPI_STATUS (AE_SUPPORT); } return_ACPI_STATUS (status); }
acpi_status acpi_tb_find_rsdp ( struct acpi_table_desc *table_info, u32 flags) { u8 *table_ptr; u8 *mem_rover; u64 phys_addr; acpi_status status = AE_OK; ACPI_FUNCTION_TRACE ("tb_find_rsdp"); /* * Scan supports either 1) Logical addressing or 2) Physical addressing */ if ((flags & ACPI_MEMORY_MODE) == ACPI_LOGICAL_ADDRESSING) { /* * 1) Search EBDA (low memory) paragraphs */ status = acpi_os_map_memory ((u64) ACPI_LO_RSDP_WINDOW_BASE, ACPI_LO_RSDP_WINDOW_SIZE, (void *) &table_ptr); if (ACPI_FAILURE (status)) { ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not map memory at %X for length %X\n", ACPI_LO_RSDP_WINDOW_BASE, ACPI_LO_RSDP_WINDOW_SIZE)); return_ACPI_STATUS (status); } mem_rover = acpi_tb_scan_memory_for_rsdp (table_ptr, ACPI_LO_RSDP_WINDOW_SIZE); acpi_os_unmap_memory (table_ptr, ACPI_LO_RSDP_WINDOW_SIZE); if (mem_rover) { /* Found it, return the physical address */ phys_addr = ACPI_LO_RSDP_WINDOW_BASE; phys_addr += ACPI_PTR_DIFF (mem_rover,table_ptr); table_info->physical_address = phys_addr; return_ACPI_STATUS (AE_OK); } /* * 2) Search upper memory: 16-byte boundaries in E0000h-F0000h */ status = acpi_os_map_memory ((u64) ACPI_HI_RSDP_WINDOW_BASE, ACPI_HI_RSDP_WINDOW_SIZE, (void *) &table_ptr); if (ACPI_FAILURE (status)) { ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not map memory at %X for length %X\n", ACPI_HI_RSDP_WINDOW_BASE, ACPI_HI_RSDP_WINDOW_SIZE)); return_ACPI_STATUS (status); } mem_rover = acpi_tb_scan_memory_for_rsdp (table_ptr, ACPI_HI_RSDP_WINDOW_SIZE); acpi_os_unmap_memory (table_ptr, ACPI_HI_RSDP_WINDOW_SIZE); if (mem_rover) { /* Found it, return the physical address */ phys_addr = ACPI_HI_RSDP_WINDOW_BASE; phys_addr += ACPI_PTR_DIFF (mem_rover, table_ptr); table_info->physical_address = phys_addr; return_ACPI_STATUS (AE_OK); } } /* * Physical addressing */ else { /* * 1) Search EBDA (low memory) paragraphs */ mem_rover = acpi_tb_scan_memory_for_rsdp (ACPI_PHYSADDR_TO_PTR (ACPI_LO_RSDP_WINDOW_BASE), ACPI_LO_RSDP_WINDOW_SIZE); if (mem_rover) { /* Found it, return the physical address */ table_info->physical_address = ACPI_TO_INTEGER (mem_rover); return_ACPI_STATUS (AE_OK); } /* * 2) Search upper memory: 16-byte boundaries in E0000h-F0000h */ mem_rover = acpi_tb_scan_memory_for_rsdp (ACPI_PHYSADDR_TO_PTR (ACPI_HI_RSDP_WINDOW_BASE), ACPI_HI_RSDP_WINDOW_SIZE); if (mem_rover) { /* Found it, return the physical address */ table_info->physical_address = ACPI_TO_INTEGER (mem_rover); return_ACPI_STATUS (AE_OK); } } /* RSDP signature was not found */ return_ACPI_STATUS (AE_NOT_FOUND); }
ACPI_STATUS AcpiTbFindRsdp ( ACPI_TABLE_DESC *TableInfo, UINT32 Flags) { UINT8 *TablePtr; UINT8 *MemRover; UINT64 PhysAddr; ACPI_STATUS Status = AE_OK; ACPI_FUNCTION_TRACE ("TbFindRsdp"); /* * Scan supports either 1) Logical addressing or 2) Physical addressing */ if ((Flags & ACPI_MEMORY_MODE) == ACPI_LOGICAL_ADDRESSING) { /* * 1) Search EBDA (low memory) paragraphs */ Status = AcpiOsMapMemory ((UINT64) ACPI_LO_RSDP_WINDOW_BASE, ACPI_LO_RSDP_WINDOW_SIZE, (void **) &TablePtr); if (ACPI_FAILURE (Status)) { ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not map memory at %X for length %X\n", ACPI_LO_RSDP_WINDOW_BASE, ACPI_LO_RSDP_WINDOW_SIZE)); return_ACPI_STATUS (Status); } MemRover = AcpiTbScanMemoryForRsdp (TablePtr, ACPI_LO_RSDP_WINDOW_SIZE); AcpiOsUnmapMemory (TablePtr, ACPI_LO_RSDP_WINDOW_SIZE); if (MemRover) { /* Found it, return the physical address */ PhysAddr = ACPI_LO_RSDP_WINDOW_BASE; PhysAddr += ACPI_PTR_DIFF (MemRover,TablePtr); TableInfo->PhysicalAddress = PhysAddr; return_ACPI_STATUS (AE_OK); } /* * 2) Search upper memory: 16-byte boundaries in E0000h-F0000h */ Status = AcpiOsMapMemory ((UINT64) ACPI_HI_RSDP_WINDOW_BASE, ACPI_HI_RSDP_WINDOW_SIZE, (void **) &TablePtr); if (ACPI_FAILURE (Status)) { ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not map memory at %X for length %X\n", ACPI_HI_RSDP_WINDOW_BASE, ACPI_HI_RSDP_WINDOW_SIZE)); return_ACPI_STATUS (Status); } MemRover = AcpiTbScanMemoryForRsdp (TablePtr, ACPI_HI_RSDP_WINDOW_SIZE); AcpiOsUnmapMemory (TablePtr, ACPI_HI_RSDP_WINDOW_SIZE); if (MemRover) { /* Found it, return the physical address */ PhysAddr = ACPI_HI_RSDP_WINDOW_BASE; PhysAddr += ACPI_PTR_DIFF (MemRover, TablePtr); TableInfo->PhysicalAddress = PhysAddr; return_ACPI_STATUS (AE_OK); } } /* * Physical addressing */ else { /* * 1) Search EBDA (low memory) paragraphs */ MemRover = AcpiTbScanMemoryForRsdp (ACPI_PHYSADDR_TO_PTR (ACPI_LO_RSDP_WINDOW_BASE), ACPI_LO_RSDP_WINDOW_SIZE); if (MemRover) { /* Found it, return the physical address */ TableInfo->PhysicalAddress = ACPI_TO_INTEGER (MemRover); return_ACPI_STATUS (AE_OK); } /* * 2) Search upper memory: 16-byte boundaries in E0000h-F0000h */ MemRover = AcpiTbScanMemoryForRsdp (ACPI_PHYSADDR_TO_PTR (ACPI_HI_RSDP_WINDOW_BASE), ACPI_HI_RSDP_WINDOW_SIZE); if (MemRover) { /* Found it, return the physical address */ TableInfo->PhysicalAddress = ACPI_TO_INTEGER (MemRover); return_ACPI_STATUS (AE_OK); } } /* RSDP signature was not found */ return_ACPI_STATUS (AE_NOT_FOUND); }
static acpi_status acpi_tb_find_rsdp(struct acpi_table_desc *table_info, u32 flags) { u8 *table_ptr; u8 *mem_rover; u32 physical_address; acpi_status status; ACPI_FUNCTION_TRACE("tb_find_rsdp"); /* * Scan supports either logical addressing or physical addressing */ if ((flags & ACPI_MEMORY_MODE) == ACPI_LOGICAL_ADDRESSING) { /* 1a) Get the location of the Extended BIOS Data Area (EBDA) */ status = acpi_os_map_memory((acpi_physical_address) ACPI_EBDA_PTR_LOCATION, ACPI_EBDA_PTR_LENGTH, (void *)&table_ptr); if (ACPI_FAILURE(status)) { ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Could not map memory at %8.8X for length %X\n", ACPI_EBDA_PTR_LOCATION, ACPI_EBDA_PTR_LENGTH)); return_ACPI_STATUS(status); } ACPI_MOVE_16_TO_32(&physical_address, table_ptr); /* Convert segment part to physical address */ physical_address <<= 4; acpi_os_unmap_memory(table_ptr, ACPI_EBDA_PTR_LENGTH); /* EBDA present? */ if (physical_address > 0x400) { /* * 1b) Search EBDA paragraphs (EBDa is required to be a * minimum of 1_k length) */ status = acpi_os_map_memory((acpi_physical_address) physical_address, ACPI_EBDA_WINDOW_SIZE, (void *)&table_ptr); if (ACPI_FAILURE(status)) { ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Could not map memory at %8.8X for length %X\n", physical_address, ACPI_EBDA_WINDOW_SIZE)); return_ACPI_STATUS(status); } mem_rover = acpi_tb_scan_memory_for_rsdp(table_ptr, ACPI_EBDA_WINDOW_SIZE); acpi_os_unmap_memory(table_ptr, ACPI_EBDA_WINDOW_SIZE); if (mem_rover) { /* Return the physical address */ physical_address += ACPI_PTR_DIFF(mem_rover, table_ptr); table_info->physical_address = (acpi_physical_address) physical_address; return_ACPI_STATUS(AE_OK); } } /* * 2) Search upper memory: 16-byte boundaries in E0000h-FFFFFh */ status = acpi_os_map_memory((acpi_physical_address) ACPI_HI_RSDP_WINDOW_BASE, ACPI_HI_RSDP_WINDOW_SIZE, (void *)&table_ptr); if (ACPI_FAILURE(status)) { ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Could not map memory at %8.8X for length %X\n", ACPI_HI_RSDP_WINDOW_BASE, ACPI_HI_RSDP_WINDOW_SIZE)); return_ACPI_STATUS(status); } mem_rover = acpi_tb_scan_memory_for_rsdp(table_ptr, ACPI_HI_RSDP_WINDOW_SIZE); acpi_os_unmap_memory(table_ptr, ACPI_HI_RSDP_WINDOW_SIZE); if (mem_rover) { /* Return the physical address */ physical_address = ACPI_HI_RSDP_WINDOW_BASE + ACPI_PTR_DIFF(mem_rover, table_ptr); table_info->physical_address = (acpi_physical_address) physical_address; return_ACPI_STATUS(AE_OK); } } /* * Physical addressing */ else { /* 1a) Get the location of the EBDA */ ACPI_MOVE_16_TO_32(&physical_address, ACPI_EBDA_PTR_LOCATION); physical_address <<= 4; /* Convert segment to physical address */ /* EBDA present? */ if (physical_address > 0x400) { /* * 1b) Search EBDA paragraphs (EBDa is required to be a minimum of * 1_k length) */ mem_rover = acpi_tb_scan_memory_for_rsdp(ACPI_PHYSADDR_TO_PTR (physical_address), ACPI_EBDA_WINDOW_SIZE); if (mem_rover) { /* Return the physical address */ table_info->physical_address = ACPI_TO_INTEGER(mem_rover); return_ACPI_STATUS(AE_OK); } } /* 2) Search upper memory: 16-byte boundaries in E0000h-FFFFFh */ mem_rover = acpi_tb_scan_memory_for_rsdp(ACPI_PHYSADDR_TO_PTR (ACPI_HI_RSDP_WINDOW_BASE), ACPI_HI_RSDP_WINDOW_SIZE); if (mem_rover) { /* Found it, return the physical address */ table_info->physical_address = ACPI_TO_INTEGER(mem_rover); return_ACPI_STATUS(AE_OK); } } /* A valid RSDP was not found */ ACPI_REPORT_ERROR(("No valid RSDP was found\n")); return_ACPI_STATUS(AE_NOT_FOUND); }
struct acpi_table_header *acpi_tb_table_override(struct acpi_table_header *table_header, struct acpi_table_desc *table_desc) { acpi_status status; struct acpi_table_header *new_table = NULL; acpi_physical_address new_address = 0; u32 new_table_length = 0; u8 new_flags; char *override_type; /* (1) Attempt logical override (returns a logical address) */ status = acpi_os_table_override(table_header, &new_table); if (ACPI_SUCCESS(status) && new_table) { new_address = ACPI_PTR_TO_PHYSADDR(new_table); new_table_length = new_table->length; new_flags = ACPI_TABLE_ORIGIN_OVERRIDE; override_type = "Logical"; goto finish_override; } /* (2) Attempt physical override (returns a physical address) */ status = acpi_os_physical_table_override(table_header, &new_address, &new_table_length); if (ACPI_SUCCESS(status) && new_address && new_table_length) { /* Map the entire new table */ new_table = acpi_os_map_memory(new_address, new_table_length); if (!new_table) { ACPI_EXCEPTION((AE_INFO, AE_NO_MEMORY, "%4.4s %p Attempted physical table override failed", table_header->signature, ACPI_PHYSADDR_TO_PTR(table_desc->address))); return (NULL); } override_type = "Physical"; new_flags = ACPI_TABLE_ORIGIN_MAPPED; goto finish_override; } return (NULL); /* There was no override */ finish_override: ACPI_INFO((AE_INFO, "%4.4s %p %s table override, new table: %p", table_header->signature, ACPI_PHYSADDR_TO_PTR(table_desc->address), override_type, new_table)); /* We can now unmap/delete the original table (if fully mapped) */ acpi_tb_delete_table(table_desc); /* Setup descriptor for the new table */ table_desc->address = new_address; table_desc->pointer = new_table; table_desc->length = new_table_length; table_desc->flags = new_flags; return (new_table); }
void *AcpiOsMapMemory(ACPI_PHYSICAL_ADDRESS Where, ACPI_SIZE Length) { PRINTD("AcpiOsMapMemory() called"); return ACPI_PHYSADDR_TO_PTR(Where); }