162306a36Sopenharmony_ci// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 262306a36Sopenharmony_ci/****************************************************************************** 362306a36Sopenharmony_ci * 462306a36Sopenharmony_ci * Module Name: exregion - ACPI default op_region (address space) handlers 562306a36Sopenharmony_ci * 662306a36Sopenharmony_ci * Copyright (C) 2000 - 2023, Intel Corp. 762306a36Sopenharmony_ci * 862306a36Sopenharmony_ci *****************************************************************************/ 962306a36Sopenharmony_ci 1062306a36Sopenharmony_ci#include <acpi/acpi.h> 1162306a36Sopenharmony_ci#include "accommon.h" 1262306a36Sopenharmony_ci#include "acinterp.h" 1362306a36Sopenharmony_ci 1462306a36Sopenharmony_ci#define _COMPONENT ACPI_EXECUTER 1562306a36Sopenharmony_ciACPI_MODULE_NAME("exregion") 1662306a36Sopenharmony_ci 1762306a36Sopenharmony_ci/******************************************************************************* 1862306a36Sopenharmony_ci * 1962306a36Sopenharmony_ci * FUNCTION: acpi_ex_system_memory_space_handler 2062306a36Sopenharmony_ci * 2162306a36Sopenharmony_ci * PARAMETERS: function - Read or Write operation 2262306a36Sopenharmony_ci * address - Where in the space to read or write 2362306a36Sopenharmony_ci * bit_width - Field width in bits (8, 16, or 32) 2462306a36Sopenharmony_ci * value - Pointer to in or out value 2562306a36Sopenharmony_ci * handler_context - Pointer to Handler's context 2662306a36Sopenharmony_ci * region_context - Pointer to context specific to the 2762306a36Sopenharmony_ci * accessed region 2862306a36Sopenharmony_ci * 2962306a36Sopenharmony_ci * RETURN: Status 3062306a36Sopenharmony_ci * 3162306a36Sopenharmony_ci * DESCRIPTION: Handler for the System Memory address space (Op Region) 3262306a36Sopenharmony_ci * 3362306a36Sopenharmony_ci ******************************************************************************/ 3462306a36Sopenharmony_ciacpi_status 3562306a36Sopenharmony_ciacpi_ex_system_memory_space_handler(u32 function, 3662306a36Sopenharmony_ci acpi_physical_address address, 3762306a36Sopenharmony_ci u32 bit_width, 3862306a36Sopenharmony_ci u64 *value, 3962306a36Sopenharmony_ci void *handler_context, void *region_context) 4062306a36Sopenharmony_ci{ 4162306a36Sopenharmony_ci acpi_status status = AE_OK; 4262306a36Sopenharmony_ci void *logical_addr_ptr = NULL; 4362306a36Sopenharmony_ci struct acpi_mem_space_context *mem_info = region_context; 4462306a36Sopenharmony_ci struct acpi_mem_mapping *mm = mem_info->cur_mm; 4562306a36Sopenharmony_ci u32 length; 4662306a36Sopenharmony_ci acpi_size map_length; 4762306a36Sopenharmony_ci acpi_size page_boundary_map_length; 4862306a36Sopenharmony_ci#ifdef ACPI_MISALIGNMENT_NOT_SUPPORTED 4962306a36Sopenharmony_ci u32 remainder; 5062306a36Sopenharmony_ci#endif 5162306a36Sopenharmony_ci 5262306a36Sopenharmony_ci ACPI_FUNCTION_TRACE(ex_system_memory_space_handler); 5362306a36Sopenharmony_ci 5462306a36Sopenharmony_ci /* Validate and translate the bit width */ 5562306a36Sopenharmony_ci 5662306a36Sopenharmony_ci switch (bit_width) { 5762306a36Sopenharmony_ci case 8: 5862306a36Sopenharmony_ci 5962306a36Sopenharmony_ci length = 1; 6062306a36Sopenharmony_ci break; 6162306a36Sopenharmony_ci 6262306a36Sopenharmony_ci case 16: 6362306a36Sopenharmony_ci 6462306a36Sopenharmony_ci length = 2; 6562306a36Sopenharmony_ci break; 6662306a36Sopenharmony_ci 6762306a36Sopenharmony_ci case 32: 6862306a36Sopenharmony_ci 6962306a36Sopenharmony_ci length = 4; 7062306a36Sopenharmony_ci break; 7162306a36Sopenharmony_ci 7262306a36Sopenharmony_ci case 64: 7362306a36Sopenharmony_ci 7462306a36Sopenharmony_ci length = 8; 7562306a36Sopenharmony_ci break; 7662306a36Sopenharmony_ci 7762306a36Sopenharmony_ci default: 7862306a36Sopenharmony_ci 7962306a36Sopenharmony_ci ACPI_ERROR((AE_INFO, "Invalid SystemMemory width %u", 8062306a36Sopenharmony_ci bit_width)); 8162306a36Sopenharmony_ci return_ACPI_STATUS(AE_AML_OPERAND_VALUE); 8262306a36Sopenharmony_ci } 8362306a36Sopenharmony_ci 8462306a36Sopenharmony_ci#ifdef ACPI_MISALIGNMENT_NOT_SUPPORTED 8562306a36Sopenharmony_ci /* 8662306a36Sopenharmony_ci * Hardware does not support non-aligned data transfers, we must verify 8762306a36Sopenharmony_ci * the request. 8862306a36Sopenharmony_ci */ 8962306a36Sopenharmony_ci (void)acpi_ut_short_divide((u64) address, length, NULL, &remainder); 9062306a36Sopenharmony_ci if (remainder != 0) { 9162306a36Sopenharmony_ci return_ACPI_STATUS(AE_AML_ALIGNMENT); 9262306a36Sopenharmony_ci } 9362306a36Sopenharmony_ci#endif 9462306a36Sopenharmony_ci 9562306a36Sopenharmony_ci /* 9662306a36Sopenharmony_ci * Does the request fit into the cached memory mapping? 9762306a36Sopenharmony_ci * Is 1) Address below the current mapping? OR 9862306a36Sopenharmony_ci * 2) Address beyond the current mapping? 9962306a36Sopenharmony_ci */ 10062306a36Sopenharmony_ci if (!mm || (address < mm->physical_address) || 10162306a36Sopenharmony_ci ((u64) address + length > (u64) mm->physical_address + mm->length)) { 10262306a36Sopenharmony_ci /* 10362306a36Sopenharmony_ci * The request cannot be resolved by the current memory mapping. 10462306a36Sopenharmony_ci * 10562306a36Sopenharmony_ci * Look for an existing saved mapping covering the address range 10662306a36Sopenharmony_ci * at hand. If found, save it as the current one and carry out 10762306a36Sopenharmony_ci * the access. 10862306a36Sopenharmony_ci */ 10962306a36Sopenharmony_ci for (mm = mem_info->first_mm; mm; mm = mm->next_mm) { 11062306a36Sopenharmony_ci if (mm == mem_info->cur_mm) 11162306a36Sopenharmony_ci continue; 11262306a36Sopenharmony_ci 11362306a36Sopenharmony_ci if (address < mm->physical_address) 11462306a36Sopenharmony_ci continue; 11562306a36Sopenharmony_ci 11662306a36Sopenharmony_ci if ((u64) address + length > 11762306a36Sopenharmony_ci (u64) mm->physical_address + mm->length) 11862306a36Sopenharmony_ci continue; 11962306a36Sopenharmony_ci 12062306a36Sopenharmony_ci mem_info->cur_mm = mm; 12162306a36Sopenharmony_ci goto access; 12262306a36Sopenharmony_ci } 12362306a36Sopenharmony_ci 12462306a36Sopenharmony_ci /* Create a new mappings list entry */ 12562306a36Sopenharmony_ci mm = ACPI_ALLOCATE_ZEROED(sizeof(*mm)); 12662306a36Sopenharmony_ci if (!mm) { 12762306a36Sopenharmony_ci ACPI_ERROR((AE_INFO, 12862306a36Sopenharmony_ci "Unable to save memory mapping at 0x%8.8X%8.8X, size %u", 12962306a36Sopenharmony_ci ACPI_FORMAT_UINT64(address), length)); 13062306a36Sopenharmony_ci return_ACPI_STATUS(AE_NO_MEMORY); 13162306a36Sopenharmony_ci } 13262306a36Sopenharmony_ci 13362306a36Sopenharmony_ci /* 13462306a36Sopenharmony_ci * October 2009: Attempt to map from the requested address to the 13562306a36Sopenharmony_ci * end of the region. However, we will never map more than one 13662306a36Sopenharmony_ci * page, nor will we cross a page boundary. 13762306a36Sopenharmony_ci */ 13862306a36Sopenharmony_ci map_length = (acpi_size) 13962306a36Sopenharmony_ci ((mem_info->address + mem_info->length) - address); 14062306a36Sopenharmony_ci 14162306a36Sopenharmony_ci /* 14262306a36Sopenharmony_ci * If mapping the entire remaining portion of the region will cross 14362306a36Sopenharmony_ci * a page boundary, just map up to the page boundary, do not cross. 14462306a36Sopenharmony_ci * On some systems, crossing a page boundary while mapping regions 14562306a36Sopenharmony_ci * can cause warnings if the pages have different attributes 14662306a36Sopenharmony_ci * due to resource management. 14762306a36Sopenharmony_ci * 14862306a36Sopenharmony_ci * This has the added benefit of constraining a single mapping to 14962306a36Sopenharmony_ci * one page, which is similar to the original code that used a 4k 15062306a36Sopenharmony_ci * maximum window. 15162306a36Sopenharmony_ci */ 15262306a36Sopenharmony_ci page_boundary_map_length = (acpi_size) 15362306a36Sopenharmony_ci (ACPI_ROUND_UP(address, ACPI_DEFAULT_PAGE_SIZE) - address); 15462306a36Sopenharmony_ci if (page_boundary_map_length == 0) { 15562306a36Sopenharmony_ci page_boundary_map_length = ACPI_DEFAULT_PAGE_SIZE; 15662306a36Sopenharmony_ci } 15762306a36Sopenharmony_ci 15862306a36Sopenharmony_ci if (map_length > page_boundary_map_length) { 15962306a36Sopenharmony_ci map_length = page_boundary_map_length; 16062306a36Sopenharmony_ci } 16162306a36Sopenharmony_ci 16262306a36Sopenharmony_ci /* Create a new mapping starting at the address given */ 16362306a36Sopenharmony_ci 16462306a36Sopenharmony_ci logical_addr_ptr = acpi_os_map_memory(address, map_length); 16562306a36Sopenharmony_ci if (!logical_addr_ptr) { 16662306a36Sopenharmony_ci ACPI_ERROR((AE_INFO, 16762306a36Sopenharmony_ci "Could not map memory at 0x%8.8X%8.8X, size %u", 16862306a36Sopenharmony_ci ACPI_FORMAT_UINT64(address), 16962306a36Sopenharmony_ci (u32)map_length)); 17062306a36Sopenharmony_ci ACPI_FREE(mm); 17162306a36Sopenharmony_ci return_ACPI_STATUS(AE_NO_MEMORY); 17262306a36Sopenharmony_ci } 17362306a36Sopenharmony_ci 17462306a36Sopenharmony_ci /* Save the physical address and mapping size */ 17562306a36Sopenharmony_ci 17662306a36Sopenharmony_ci mm->logical_address = logical_addr_ptr; 17762306a36Sopenharmony_ci mm->physical_address = address; 17862306a36Sopenharmony_ci mm->length = map_length; 17962306a36Sopenharmony_ci 18062306a36Sopenharmony_ci /* 18162306a36Sopenharmony_ci * Add the new entry to the mappigs list and save it as the 18262306a36Sopenharmony_ci * current mapping. 18362306a36Sopenharmony_ci */ 18462306a36Sopenharmony_ci mm->next_mm = mem_info->first_mm; 18562306a36Sopenharmony_ci mem_info->first_mm = mm; 18662306a36Sopenharmony_ci 18762306a36Sopenharmony_ci mem_info->cur_mm = mm; 18862306a36Sopenharmony_ci } 18962306a36Sopenharmony_ci 19062306a36Sopenharmony_ciaccess: 19162306a36Sopenharmony_ci /* 19262306a36Sopenharmony_ci * Generate a logical pointer corresponding to the address we want to 19362306a36Sopenharmony_ci * access 19462306a36Sopenharmony_ci */ 19562306a36Sopenharmony_ci logical_addr_ptr = mm->logical_address + 19662306a36Sopenharmony_ci ((u64) address - (u64) mm->physical_address); 19762306a36Sopenharmony_ci 19862306a36Sopenharmony_ci ACPI_DEBUG_PRINT((ACPI_DB_INFO, 19962306a36Sopenharmony_ci "System-Memory (width %u) R/W %u Address=%8.8X%8.8X\n", 20062306a36Sopenharmony_ci bit_width, function, ACPI_FORMAT_UINT64(address))); 20162306a36Sopenharmony_ci 20262306a36Sopenharmony_ci /* 20362306a36Sopenharmony_ci * Perform the memory read or write 20462306a36Sopenharmony_ci * 20562306a36Sopenharmony_ci * Note: For machines that do not support non-aligned transfers, the target 20662306a36Sopenharmony_ci * address was checked for alignment above. We do not attempt to break the 20762306a36Sopenharmony_ci * transfer up into smaller (byte-size) chunks because the AML specifically 20862306a36Sopenharmony_ci * asked for a transfer width that the hardware may require. 20962306a36Sopenharmony_ci */ 21062306a36Sopenharmony_ci switch (function) { 21162306a36Sopenharmony_ci case ACPI_READ: 21262306a36Sopenharmony_ci 21362306a36Sopenharmony_ci *value = 0; 21462306a36Sopenharmony_ci switch (bit_width) { 21562306a36Sopenharmony_ci case 8: 21662306a36Sopenharmony_ci 21762306a36Sopenharmony_ci *value = (u64)ACPI_GET8(logical_addr_ptr); 21862306a36Sopenharmony_ci break; 21962306a36Sopenharmony_ci 22062306a36Sopenharmony_ci case 16: 22162306a36Sopenharmony_ci 22262306a36Sopenharmony_ci *value = (u64)ACPI_GET16(logical_addr_ptr); 22362306a36Sopenharmony_ci break; 22462306a36Sopenharmony_ci 22562306a36Sopenharmony_ci case 32: 22662306a36Sopenharmony_ci 22762306a36Sopenharmony_ci *value = (u64)ACPI_GET32(logical_addr_ptr); 22862306a36Sopenharmony_ci break; 22962306a36Sopenharmony_ci 23062306a36Sopenharmony_ci case 64: 23162306a36Sopenharmony_ci 23262306a36Sopenharmony_ci *value = (u64)ACPI_GET64(logical_addr_ptr); 23362306a36Sopenharmony_ci break; 23462306a36Sopenharmony_ci 23562306a36Sopenharmony_ci default: 23662306a36Sopenharmony_ci 23762306a36Sopenharmony_ci /* bit_width was already validated */ 23862306a36Sopenharmony_ci 23962306a36Sopenharmony_ci break; 24062306a36Sopenharmony_ci } 24162306a36Sopenharmony_ci break; 24262306a36Sopenharmony_ci 24362306a36Sopenharmony_ci case ACPI_WRITE: 24462306a36Sopenharmony_ci 24562306a36Sopenharmony_ci switch (bit_width) { 24662306a36Sopenharmony_ci case 8: 24762306a36Sopenharmony_ci 24862306a36Sopenharmony_ci ACPI_SET8(logical_addr_ptr, *value); 24962306a36Sopenharmony_ci break; 25062306a36Sopenharmony_ci 25162306a36Sopenharmony_ci case 16: 25262306a36Sopenharmony_ci 25362306a36Sopenharmony_ci ACPI_SET16(logical_addr_ptr, *value); 25462306a36Sopenharmony_ci break; 25562306a36Sopenharmony_ci 25662306a36Sopenharmony_ci case 32: 25762306a36Sopenharmony_ci 25862306a36Sopenharmony_ci ACPI_SET32(logical_addr_ptr, *value); 25962306a36Sopenharmony_ci break; 26062306a36Sopenharmony_ci 26162306a36Sopenharmony_ci case 64: 26262306a36Sopenharmony_ci 26362306a36Sopenharmony_ci ACPI_SET64(logical_addr_ptr, *value); 26462306a36Sopenharmony_ci break; 26562306a36Sopenharmony_ci 26662306a36Sopenharmony_ci default: 26762306a36Sopenharmony_ci 26862306a36Sopenharmony_ci /* bit_width was already validated */ 26962306a36Sopenharmony_ci 27062306a36Sopenharmony_ci break; 27162306a36Sopenharmony_ci } 27262306a36Sopenharmony_ci break; 27362306a36Sopenharmony_ci 27462306a36Sopenharmony_ci default: 27562306a36Sopenharmony_ci 27662306a36Sopenharmony_ci status = AE_BAD_PARAMETER; 27762306a36Sopenharmony_ci break; 27862306a36Sopenharmony_ci } 27962306a36Sopenharmony_ci 28062306a36Sopenharmony_ci return_ACPI_STATUS(status); 28162306a36Sopenharmony_ci} 28262306a36Sopenharmony_ci 28362306a36Sopenharmony_ci/******************************************************************************* 28462306a36Sopenharmony_ci * 28562306a36Sopenharmony_ci * FUNCTION: acpi_ex_system_io_space_handler 28662306a36Sopenharmony_ci * 28762306a36Sopenharmony_ci * PARAMETERS: function - Read or Write operation 28862306a36Sopenharmony_ci * address - Where in the space to read or write 28962306a36Sopenharmony_ci * bit_width - Field width in bits (8, 16, or 32) 29062306a36Sopenharmony_ci * value - Pointer to in or out value 29162306a36Sopenharmony_ci * handler_context - Pointer to Handler's context 29262306a36Sopenharmony_ci * region_context - Pointer to context specific to the 29362306a36Sopenharmony_ci * accessed region 29462306a36Sopenharmony_ci * 29562306a36Sopenharmony_ci * RETURN: Status 29662306a36Sopenharmony_ci * 29762306a36Sopenharmony_ci * DESCRIPTION: Handler for the System IO address space (Op Region) 29862306a36Sopenharmony_ci * 29962306a36Sopenharmony_ci ******************************************************************************/ 30062306a36Sopenharmony_ci 30162306a36Sopenharmony_ciacpi_status 30262306a36Sopenharmony_ciacpi_ex_system_io_space_handler(u32 function, 30362306a36Sopenharmony_ci acpi_physical_address address, 30462306a36Sopenharmony_ci u32 bit_width, 30562306a36Sopenharmony_ci u64 *value, 30662306a36Sopenharmony_ci void *handler_context, void *region_context) 30762306a36Sopenharmony_ci{ 30862306a36Sopenharmony_ci acpi_status status = AE_OK; 30962306a36Sopenharmony_ci u32 value32; 31062306a36Sopenharmony_ci 31162306a36Sopenharmony_ci ACPI_FUNCTION_TRACE(ex_system_io_space_handler); 31262306a36Sopenharmony_ci 31362306a36Sopenharmony_ci ACPI_DEBUG_PRINT((ACPI_DB_INFO, 31462306a36Sopenharmony_ci "System-IO (width %u) R/W %u Address=%8.8X%8.8X\n", 31562306a36Sopenharmony_ci bit_width, function, ACPI_FORMAT_UINT64(address))); 31662306a36Sopenharmony_ci 31762306a36Sopenharmony_ci /* Decode the function parameter */ 31862306a36Sopenharmony_ci 31962306a36Sopenharmony_ci switch (function) { 32062306a36Sopenharmony_ci case ACPI_READ: 32162306a36Sopenharmony_ci 32262306a36Sopenharmony_ci status = acpi_hw_read_port((acpi_io_address)address, 32362306a36Sopenharmony_ci &value32, bit_width); 32462306a36Sopenharmony_ci *value = value32; 32562306a36Sopenharmony_ci break; 32662306a36Sopenharmony_ci 32762306a36Sopenharmony_ci case ACPI_WRITE: 32862306a36Sopenharmony_ci 32962306a36Sopenharmony_ci status = acpi_hw_write_port((acpi_io_address)address, 33062306a36Sopenharmony_ci (u32)*value, bit_width); 33162306a36Sopenharmony_ci break; 33262306a36Sopenharmony_ci 33362306a36Sopenharmony_ci default: 33462306a36Sopenharmony_ci 33562306a36Sopenharmony_ci status = AE_BAD_PARAMETER; 33662306a36Sopenharmony_ci break; 33762306a36Sopenharmony_ci } 33862306a36Sopenharmony_ci 33962306a36Sopenharmony_ci return_ACPI_STATUS(status); 34062306a36Sopenharmony_ci} 34162306a36Sopenharmony_ci 34262306a36Sopenharmony_ci#ifdef ACPI_PCI_CONFIGURED 34362306a36Sopenharmony_ci/******************************************************************************* 34462306a36Sopenharmony_ci * 34562306a36Sopenharmony_ci * FUNCTION: acpi_ex_pci_config_space_handler 34662306a36Sopenharmony_ci * 34762306a36Sopenharmony_ci * PARAMETERS: function - Read or Write operation 34862306a36Sopenharmony_ci * address - Where in the space to read or write 34962306a36Sopenharmony_ci * bit_width - Field width in bits (8, 16, or 32) 35062306a36Sopenharmony_ci * value - Pointer to in or out value 35162306a36Sopenharmony_ci * handler_context - Pointer to Handler's context 35262306a36Sopenharmony_ci * region_context - Pointer to context specific to the 35362306a36Sopenharmony_ci * accessed region 35462306a36Sopenharmony_ci * 35562306a36Sopenharmony_ci * RETURN: Status 35662306a36Sopenharmony_ci * 35762306a36Sopenharmony_ci * DESCRIPTION: Handler for the PCI Config address space (Op Region) 35862306a36Sopenharmony_ci * 35962306a36Sopenharmony_ci ******************************************************************************/ 36062306a36Sopenharmony_ci 36162306a36Sopenharmony_ciacpi_status 36262306a36Sopenharmony_ciacpi_ex_pci_config_space_handler(u32 function, 36362306a36Sopenharmony_ci acpi_physical_address address, 36462306a36Sopenharmony_ci u32 bit_width, 36562306a36Sopenharmony_ci u64 *value, 36662306a36Sopenharmony_ci void *handler_context, void *region_context) 36762306a36Sopenharmony_ci{ 36862306a36Sopenharmony_ci acpi_status status = AE_OK; 36962306a36Sopenharmony_ci struct acpi_pci_id *pci_id; 37062306a36Sopenharmony_ci u16 pci_register; 37162306a36Sopenharmony_ci 37262306a36Sopenharmony_ci ACPI_FUNCTION_TRACE(ex_pci_config_space_handler); 37362306a36Sopenharmony_ci 37462306a36Sopenharmony_ci /* 37562306a36Sopenharmony_ci * The arguments to acpi_os(Read|Write)pci_configuration are: 37662306a36Sopenharmony_ci * 37762306a36Sopenharmony_ci * pci_segment is the PCI bus segment range 0-31 37862306a36Sopenharmony_ci * pci_bus is the PCI bus number range 0-255 37962306a36Sopenharmony_ci * pci_device is the PCI device number range 0-31 38062306a36Sopenharmony_ci * pci_function is the PCI device function number 38162306a36Sopenharmony_ci * pci_register is the Config space register range 0-255 bytes 38262306a36Sopenharmony_ci * 38362306a36Sopenharmony_ci * value - input value for write, output address for read 38462306a36Sopenharmony_ci * 38562306a36Sopenharmony_ci */ 38662306a36Sopenharmony_ci pci_id = (struct acpi_pci_id *)region_context; 38762306a36Sopenharmony_ci pci_register = (u16) (u32) address; 38862306a36Sopenharmony_ci 38962306a36Sopenharmony_ci ACPI_DEBUG_PRINT((ACPI_DB_INFO, 39062306a36Sopenharmony_ci "Pci-Config %u (%u) Seg(%04x) Bus(%04x) " 39162306a36Sopenharmony_ci "Dev(%04x) Func(%04x) Reg(%04x)\n", 39262306a36Sopenharmony_ci function, bit_width, pci_id->segment, pci_id->bus, 39362306a36Sopenharmony_ci pci_id->device, pci_id->function, pci_register)); 39462306a36Sopenharmony_ci 39562306a36Sopenharmony_ci switch (function) { 39662306a36Sopenharmony_ci case ACPI_READ: 39762306a36Sopenharmony_ci 39862306a36Sopenharmony_ci *value = 0; 39962306a36Sopenharmony_ci status = 40062306a36Sopenharmony_ci acpi_os_read_pci_configuration(pci_id, pci_register, value, 40162306a36Sopenharmony_ci bit_width); 40262306a36Sopenharmony_ci break; 40362306a36Sopenharmony_ci 40462306a36Sopenharmony_ci case ACPI_WRITE: 40562306a36Sopenharmony_ci 40662306a36Sopenharmony_ci status = 40762306a36Sopenharmony_ci acpi_os_write_pci_configuration(pci_id, pci_register, 40862306a36Sopenharmony_ci *value, bit_width); 40962306a36Sopenharmony_ci break; 41062306a36Sopenharmony_ci 41162306a36Sopenharmony_ci default: 41262306a36Sopenharmony_ci 41362306a36Sopenharmony_ci status = AE_BAD_PARAMETER; 41462306a36Sopenharmony_ci break; 41562306a36Sopenharmony_ci } 41662306a36Sopenharmony_ci 41762306a36Sopenharmony_ci return_ACPI_STATUS(status); 41862306a36Sopenharmony_ci} 41962306a36Sopenharmony_ci#endif 42062306a36Sopenharmony_ci 42162306a36Sopenharmony_ci/******************************************************************************* 42262306a36Sopenharmony_ci * 42362306a36Sopenharmony_ci * FUNCTION: acpi_ex_cmos_space_handler 42462306a36Sopenharmony_ci * 42562306a36Sopenharmony_ci * PARAMETERS: function - Read or Write operation 42662306a36Sopenharmony_ci * address - Where in the space to read or write 42762306a36Sopenharmony_ci * bit_width - Field width in bits (8, 16, or 32) 42862306a36Sopenharmony_ci * value - Pointer to in or out value 42962306a36Sopenharmony_ci * handler_context - Pointer to Handler's context 43062306a36Sopenharmony_ci * region_context - Pointer to context specific to the 43162306a36Sopenharmony_ci * accessed region 43262306a36Sopenharmony_ci * 43362306a36Sopenharmony_ci * RETURN: Status 43462306a36Sopenharmony_ci * 43562306a36Sopenharmony_ci * DESCRIPTION: Handler for the CMOS address space (Op Region) 43662306a36Sopenharmony_ci * 43762306a36Sopenharmony_ci ******************************************************************************/ 43862306a36Sopenharmony_ci 43962306a36Sopenharmony_ciacpi_status 44062306a36Sopenharmony_ciacpi_ex_cmos_space_handler(u32 function, 44162306a36Sopenharmony_ci acpi_physical_address address, 44262306a36Sopenharmony_ci u32 bit_width, 44362306a36Sopenharmony_ci u64 *value, 44462306a36Sopenharmony_ci void *handler_context, void *region_context) 44562306a36Sopenharmony_ci{ 44662306a36Sopenharmony_ci acpi_status status = AE_OK; 44762306a36Sopenharmony_ci 44862306a36Sopenharmony_ci ACPI_FUNCTION_TRACE(ex_cmos_space_handler); 44962306a36Sopenharmony_ci 45062306a36Sopenharmony_ci return_ACPI_STATUS(status); 45162306a36Sopenharmony_ci} 45262306a36Sopenharmony_ci 45362306a36Sopenharmony_ci#ifdef ACPI_PCI_CONFIGURED 45462306a36Sopenharmony_ci/******************************************************************************* 45562306a36Sopenharmony_ci * 45662306a36Sopenharmony_ci * FUNCTION: acpi_ex_pci_bar_space_handler 45762306a36Sopenharmony_ci * 45862306a36Sopenharmony_ci * PARAMETERS: function - Read or Write operation 45962306a36Sopenharmony_ci * address - Where in the space to read or write 46062306a36Sopenharmony_ci * bit_width - Field width in bits (8, 16, or 32) 46162306a36Sopenharmony_ci * value - Pointer to in or out value 46262306a36Sopenharmony_ci * handler_context - Pointer to Handler's context 46362306a36Sopenharmony_ci * region_context - Pointer to context specific to the 46462306a36Sopenharmony_ci * accessed region 46562306a36Sopenharmony_ci * 46662306a36Sopenharmony_ci * RETURN: Status 46762306a36Sopenharmony_ci * 46862306a36Sopenharmony_ci * DESCRIPTION: Handler for the PCI bar_target address space (Op Region) 46962306a36Sopenharmony_ci * 47062306a36Sopenharmony_ci ******************************************************************************/ 47162306a36Sopenharmony_ci 47262306a36Sopenharmony_ciacpi_status 47362306a36Sopenharmony_ciacpi_ex_pci_bar_space_handler(u32 function, 47462306a36Sopenharmony_ci acpi_physical_address address, 47562306a36Sopenharmony_ci u32 bit_width, 47662306a36Sopenharmony_ci u64 *value, 47762306a36Sopenharmony_ci void *handler_context, void *region_context) 47862306a36Sopenharmony_ci{ 47962306a36Sopenharmony_ci acpi_status status = AE_OK; 48062306a36Sopenharmony_ci 48162306a36Sopenharmony_ci ACPI_FUNCTION_TRACE(ex_pci_bar_space_handler); 48262306a36Sopenharmony_ci 48362306a36Sopenharmony_ci return_ACPI_STATUS(status); 48462306a36Sopenharmony_ci} 48562306a36Sopenharmony_ci#endif 48662306a36Sopenharmony_ci 48762306a36Sopenharmony_ci/******************************************************************************* 48862306a36Sopenharmony_ci * 48962306a36Sopenharmony_ci * FUNCTION: acpi_ex_data_table_space_handler 49062306a36Sopenharmony_ci * 49162306a36Sopenharmony_ci * PARAMETERS: function - Read or Write operation 49262306a36Sopenharmony_ci * address - Where in the space to read or write 49362306a36Sopenharmony_ci * bit_width - Field width in bits (8, 16, or 32) 49462306a36Sopenharmony_ci * value - Pointer to in or out value 49562306a36Sopenharmony_ci * handler_context - Pointer to Handler's context 49662306a36Sopenharmony_ci * region_context - Pointer to context specific to the 49762306a36Sopenharmony_ci * accessed region 49862306a36Sopenharmony_ci * 49962306a36Sopenharmony_ci * RETURN: Status 50062306a36Sopenharmony_ci * 50162306a36Sopenharmony_ci * DESCRIPTION: Handler for the Data Table address space (Op Region) 50262306a36Sopenharmony_ci * 50362306a36Sopenharmony_ci ******************************************************************************/ 50462306a36Sopenharmony_ci 50562306a36Sopenharmony_ciacpi_status 50662306a36Sopenharmony_ciacpi_ex_data_table_space_handler(u32 function, 50762306a36Sopenharmony_ci acpi_physical_address address, 50862306a36Sopenharmony_ci u32 bit_width, 50962306a36Sopenharmony_ci u64 *value, 51062306a36Sopenharmony_ci void *handler_context, void *region_context) 51162306a36Sopenharmony_ci{ 51262306a36Sopenharmony_ci struct acpi_data_table_mapping *mapping; 51362306a36Sopenharmony_ci char *pointer; 51462306a36Sopenharmony_ci 51562306a36Sopenharmony_ci ACPI_FUNCTION_TRACE(ex_data_table_space_handler); 51662306a36Sopenharmony_ci 51762306a36Sopenharmony_ci mapping = (struct acpi_data_table_mapping *) region_context; 51862306a36Sopenharmony_ci pointer = ACPI_CAST_PTR(char, mapping->pointer) + 51962306a36Sopenharmony_ci (address - ACPI_PTR_TO_PHYSADDR(mapping->pointer)); 52062306a36Sopenharmony_ci 52162306a36Sopenharmony_ci /* 52262306a36Sopenharmony_ci * Perform the memory read or write. The bit_width was already 52362306a36Sopenharmony_ci * validated. 52462306a36Sopenharmony_ci */ 52562306a36Sopenharmony_ci switch (function) { 52662306a36Sopenharmony_ci case ACPI_READ: 52762306a36Sopenharmony_ci 52862306a36Sopenharmony_ci memcpy(ACPI_CAST_PTR(char, value), pointer, 52962306a36Sopenharmony_ci ACPI_DIV_8(bit_width)); 53062306a36Sopenharmony_ci break; 53162306a36Sopenharmony_ci 53262306a36Sopenharmony_ci case ACPI_WRITE: 53362306a36Sopenharmony_ci 53462306a36Sopenharmony_ci memcpy(pointer, ACPI_CAST_PTR(char, value), 53562306a36Sopenharmony_ci ACPI_DIV_8(bit_width)); 53662306a36Sopenharmony_ci break; 53762306a36Sopenharmony_ci 53862306a36Sopenharmony_ci default: 53962306a36Sopenharmony_ci 54062306a36Sopenharmony_ci return_ACPI_STATUS(AE_BAD_PARAMETER); 54162306a36Sopenharmony_ci } 54262306a36Sopenharmony_ci 54362306a36Sopenharmony_ci return_ACPI_STATUS(AE_OK); 54462306a36Sopenharmony_ci} 545