static void acpi_ex_dump_object(union acpi_operand_object *obj_desc, struct acpi_exdump_info *info) { u8 *target; char *name; u8 count; if (!info) { acpi_os_printf ("ExDumpObject: Display not implemented for object type %s\n", acpi_ut_get_object_type_name(obj_desc)); return; } /* First table entry must contain the table length (# of table entries) */ count = info->offset; while (count) { target = ACPI_ADD_PTR(u8, obj_desc, info->offset); name = info->name; switch (info->opcode) { case ACPI_EXD_INIT: break; case ACPI_EXD_TYPE: acpi_ex_out_string("Type", acpi_ut_get_object_type_name (obj_desc)); break; case ACPI_EXD_UINT8: acpi_os_printf("%20s : %2.2X\n", name, *target); break; case ACPI_EXD_UINT16: acpi_os_printf("%20s : %4.4X\n", name, ACPI_GET16(target)); break; case ACPI_EXD_UINT32: acpi_os_printf("%20s : %8.8X\n", name, ACPI_GET32(target)); break; case ACPI_EXD_UINT64: acpi_os_printf("%20s : %8.8X%8.8X\n", "Value", ACPI_FORMAT_UINT64(ACPI_GET64(target))); break; case ACPI_EXD_POINTER: acpi_ex_out_pointer(name, *ACPI_CAST_PTR(void *, target)); break; case ACPI_EXD_ADDRESS: acpi_ex_out_address(name, *ACPI_CAST_PTR (acpi_physical_address, target)); break; case ACPI_EXD_STRING: acpi_ut_print_string(obj_desc->string.pointer, ACPI_UINT8_MAX); acpi_os_printf("\n"); break; case ACPI_EXD_BUFFER: ACPI_DUMP_BUFFER(obj_desc->buffer.pointer, obj_desc->buffer.length); break; case ACPI_EXD_PACKAGE: /* Dump the package contents */ acpi_os_printf("\nPackage Contents:\n"); acpi_ex_dump_package_obj(obj_desc, 0, 0); break; case ACPI_EXD_FIELD: acpi_ex_dump_object(obj_desc, acpi_ex_dump_field_common); break; case ACPI_EXD_REFERENCE: acpi_ex_out_string("Opcode", (acpi_ps_get_opcode_info (obj_desc->reference.opcode))-> name); acpi_ex_dump_reference_obj(obj_desc); break; default: acpi_os_printf("**** Invalid table opcode [%X] ****\n", info->opcode); return; } info++; count--; } }
static void AcpiRsDumpDescriptor ( void *Resource, ACPI_RSDUMP_INFO *Table) { UINT8 *Target = NULL; UINT8 *PreviousTarget; const char *Name; UINT8 Count; /* First table entry must contain the table length (# of table entries) */ Count = Table->Offset; while (Count) { PreviousTarget = Target; Target = ACPI_ADD_PTR (UINT8, Resource, Table->Offset); Name = Table->Name; switch (Table->Opcode) { case ACPI_RSD_TITLE: /* * Optional resource title */ if (Table->Name) { AcpiOsPrintf ("%s Resource\n", Name); } break; /* Strings */ case ACPI_RSD_LITERAL: AcpiRsOutString (Name, ACPI_CAST_PTR (char, Table->Pointer)); break; case ACPI_RSD_STRING: AcpiRsOutString (Name, ACPI_CAST_PTR (char, Target)); break; /* Data items, 8/16/32/64 bit */ case ACPI_RSD_UINT8: if (Table->Pointer) { AcpiRsOutString (Name, Table->Pointer [*Target]); } else { AcpiRsOutInteger8 (Name, ACPI_GET8 (Target)); } break; case ACPI_RSD_UINT16: AcpiRsOutInteger16 (Name, ACPI_GET16 (Target)); break; case ACPI_RSD_UINT32: AcpiRsOutInteger32 (Name, ACPI_GET32 (Target)); break; case ACPI_RSD_UINT64: AcpiRsOutInteger64 (Name, ACPI_GET64 (Target)); break; /* Flags: 1-bit and 2-bit flags supported */ case ACPI_RSD_1BITFLAG: AcpiRsOutString (Name, Table->Pointer [*Target & 0x01]); break; case ACPI_RSD_2BITFLAG: AcpiRsOutString (Name, Table->Pointer [*Target & 0x03]); break; case ACPI_RSD_3BITFLAG: AcpiRsOutString (Name, Table->Pointer [*Target & 0x07]); break; case ACPI_RSD_SHORTLIST: /* * Short byte list (single line output) for DMA and IRQ resources * Note: The list length is obtained from the previous table entry */ if (PreviousTarget) { AcpiRsOutTitle (Name); AcpiRsDumpShortByteList (*PreviousTarget, Target); } break; case ACPI_RSD_SHORTLISTX: /* * Short byte list (single line output) for GPIO vendor data * Note: The list length is obtained from the previous table entry */ if (PreviousTarget) { AcpiRsOutTitle (Name); AcpiRsDumpShortByteList (*PreviousTarget, *(ACPI_CAST_INDIRECT_PTR (UINT8, Target))); } break; case ACPI_RSD_LONGLIST: /* * Long byte list for Vendor resource data * Note: The list length is obtained from the previous table entry */ if (PreviousTarget) { AcpiRsDumpByteList (ACPI_GET16 (PreviousTarget), Target); } break; case ACPI_RSD_DWORDLIST: /* * Dword list for Extended Interrupt resources * Note: The list length is obtained from the previous table entry */ if (PreviousTarget) { AcpiRsDumpDwordList (*PreviousTarget, ACPI_CAST_PTR (UINT32, Target)); } break; case ACPI_RSD_WORDLIST: /* * Word list for GPIO Pin Table * Note: The list length is obtained from the previous table entry */ if (PreviousTarget) { AcpiRsDumpWordList (*PreviousTarget, *(ACPI_CAST_INDIRECT_PTR (UINT16, Target))); } break; case ACPI_RSD_ADDRESS: /* * Common flags for all Address resources */ AcpiRsDumpAddressCommon (ACPI_CAST_PTR ( ACPI_RESOURCE_DATA, Target)); break; case ACPI_RSD_SOURCE: /* * Optional ResourceSource for Address resources */ AcpiRsDumpResourceSource (ACPI_CAST_PTR ( ACPI_RESOURCE_SOURCE, Target)); break; case ACPI_RSD_LABEL: /* * ResourceLabel */ AcpiRsDumpResourceLabel ("Resource Label", ACPI_CAST_PTR ( ACPI_RESOURCE_LABEL, Target)); break; case ACPI_RSD_SOURCE_LABEL: /* * ResourceSourceLabel */ AcpiRsDumpResourceLabel ("Resource Source Label", ACPI_CAST_PTR ( ACPI_RESOURCE_LABEL, Target)); break; default: AcpiOsPrintf ("**** Invalid table opcode [%X] ****\n", Table->Opcode); return; } Table++; Count--; } }
static void acpi_rs_dump_descriptor(void *resource, struct acpi_rsdump_info *table) { u8 *target = NULL; u8 *previous_target; char *name; u8 count; /* First table entry must contain the table length (# of table entries) */ count = table->offset; while (count) { previous_target = target; target = ACPI_ADD_PTR(u8, resource, table->offset); name = table->name; switch (table->opcode) { case ACPI_RSD_TITLE: /* * Optional resource title */ if (table->name) { acpi_os_printf("%s Resource\n", name); } break; /* Strings */ case ACPI_RSD_LITERAL: acpi_rs_out_string(name, ACPI_CAST_PTR(char, table->pointer)); break; case ACPI_RSD_STRING: acpi_rs_out_string(name, ACPI_CAST_PTR(char, target)); break; /* Data items, 8/16/32/64 bit */ case ACPI_RSD_UINT8: if (table->pointer) { acpi_rs_out_string(name, ACPI_CAST_PTR(char, table-> pointer [*target])); } else { acpi_rs_out_integer8(name, ACPI_GET8(target)); } break; case ACPI_RSD_UINT16: acpi_rs_out_integer16(name, ACPI_GET16(target)); break; case ACPI_RSD_UINT32: acpi_rs_out_integer32(name, ACPI_GET32(target)); break; case ACPI_RSD_UINT64: acpi_rs_out_integer64(name, ACPI_GET64(target)); break; /* Flags: 1-bit and 2-bit flags supported */ case ACPI_RSD_1BITFLAG: acpi_rs_out_string(name, ACPI_CAST_PTR(char, table-> pointer[*target & 0x01])); break; case ACPI_RSD_2BITFLAG: acpi_rs_out_string(name, ACPI_CAST_PTR(char, table-> pointer[*target & 0x03])); break; case ACPI_RSD_3BITFLAG: acpi_rs_out_string(name, ACPI_CAST_PTR(char, table-> pointer[*target & 0x07])); break; case ACPI_RSD_SHORTLIST: /* * Short byte list (single line output) for DMA and IRQ resources * Note: The list length is obtained from the previous table entry */ if (previous_target) { acpi_rs_out_title(name); acpi_rs_dump_short_byte_list(*previous_target, target); } break; case ACPI_RSD_SHORTLISTX: /* * Short byte list (single line output) for GPIO vendor data * Note: The list length is obtained from the previous table entry */ if (previous_target) { acpi_rs_out_title(name); acpi_rs_dump_short_byte_list(*previous_target, * (ACPI_CAST_INDIRECT_PTR (u8, target))); } break; case ACPI_RSD_LONGLIST: /* * Long byte list for Vendor resource data * Note: The list length is obtained from the previous table entry */ if (previous_target) { acpi_rs_dump_byte_list(ACPI_GET16 (previous_target), target); } break; case ACPI_RSD_DWORDLIST: /* * Dword list for Extended Interrupt resources * Note: The list length is obtained from the previous table entry */ if (previous_target) { acpi_rs_dump_dword_list(*previous_target, ACPI_CAST_PTR(u32, target)); } break; case ACPI_RSD_WORDLIST: /* * Word list for GPIO Pin Table * Note: The list length is obtained from the previous table entry */ if (previous_target) { acpi_rs_dump_word_list(*previous_target, *(ACPI_CAST_INDIRECT_PTR (u16, target))); } break; case ACPI_RSD_ADDRESS: /* * Common flags for all Address resources */ acpi_rs_dump_address_common(ACPI_CAST_PTR (union acpi_resource_data, target)); break; case ACPI_RSD_SOURCE: /* * Optional resource_source for Address resources */ acpi_rs_dump_resource_source(ACPI_CAST_PTR (struct acpi_resource_source, target)); break; default: acpi_os_printf("**** Invalid table opcode [%X] ****\n", table->opcode); return; }
/******************************************************************************* * * FUNCTION: acpi_ex_system_memory_space_handler * * PARAMETERS: Function - Read or Write operation * Address - Where in the space to read or write * bit_width - Field width in bits (8, 16, or 32) * Value - Pointer to in or out value * handler_context - Pointer to Handler's context * region_context - Pointer to context specific to the * accessed region * * RETURN: Status * * DESCRIPTION: Handler for the System Memory address space (Op Region) * ******************************************************************************/ acpi_status acpi_ex_system_memory_space_handler(u32 function, acpi_physical_address address, u32 bit_width, u64 *value, void *handler_context, void *region_context) { acpi_status status = AE_OK; void *logical_addr_ptr = NULL; struct acpi_mem_space_context *mem_info = region_context; u32 length; acpi_size map_length; acpi_size page_boundary_map_length; #ifdef ACPI_MISALIGNMENT_NOT_SUPPORTED u32 remainder; #endif ACPI_FUNCTION_TRACE(ex_system_memory_space_handler); /* Validate and translate the bit width */ switch (bit_width) { case 8: length = 1; break; case 16: length = 2; break; case 32: length = 4; break; case 64: length = 8; break; default: ACPI_ERROR((AE_INFO, "Invalid SystemMemory width %u", bit_width)); return_ACPI_STATUS(AE_AML_OPERAND_VALUE); } #ifdef ACPI_MISALIGNMENT_NOT_SUPPORTED /* * Hardware does not support non-aligned data transfers, we must verify * the request. */ (void)acpi_ut_short_divide((u64) address, length, NULL, &remainder); if (remainder != 0) { return_ACPI_STATUS(AE_AML_ALIGNMENT); } #endif /* * Does the request fit into the cached memory mapping? * Is 1) Address below the current mapping? OR * 2) Address beyond the current mapping? */ if ((address < mem_info->mapped_physical_address) || (((u64) address + length) > ((u64) mem_info->mapped_physical_address + mem_info->mapped_length))) { /* * The request cannot be resolved by the current memory mapping; * Delete the existing mapping and create a new one. */ if (mem_info->mapped_length) { /* Valid mapping, delete it */ acpi_os_unmap_memory(mem_info->mapped_logical_address, mem_info->mapped_length); } /* * Attempt to map from the requested address to the end of the region. * However, we will never map more than one page, nor will we cross * a page boundary. */ map_length = (acpi_size) ((mem_info->address + mem_info->length) - address); /* * If mapping the entire remaining portion of the region will cross * a page boundary, just map up to the page boundary, do not cross. * On some systems, crossing a page boundary while mapping regions * can cause warnings if the pages have different attributes * due to resource management */ page_boundary_map_length = ACPI_ROUND_UP(address, ACPI_DEFAULT_PAGE_SIZE) - address; if (!page_boundary_map_length) { page_boundary_map_length = ACPI_DEFAULT_PAGE_SIZE; } if (map_length > page_boundary_map_length) { map_length = page_boundary_map_length; } /* Create a new mapping starting at the address given */ mem_info->mapped_logical_address = acpi_os_map_memory((acpi_physical_address) address, map_length); if (!mem_info->mapped_logical_address) { ACPI_ERROR((AE_INFO, "Could not map memory at 0x%8.8X%8.8X, size %u", ACPI_FORMAT_NATIVE_UINT(address), (u32) map_length)); mem_info->mapped_length = 0; return_ACPI_STATUS(AE_NO_MEMORY); } /* Save the physical address and mapping size */ mem_info->mapped_physical_address = address; mem_info->mapped_length = map_length; } /* * Generate a logical pointer corresponding to the address we want to * access */ logical_addr_ptr = mem_info->mapped_logical_address + ((u64) address - (u64) mem_info->mapped_physical_address); ACPI_DEBUG_PRINT((ACPI_DB_INFO, "System-Memory (width %u) R/W %u Address=%8.8X%8.8X\n", bit_width, function, ACPI_FORMAT_NATIVE_UINT(address))); /* * Perform the memory read or write * * Note: For machines that do not support non-aligned transfers, the target * address was checked for alignment above. We do not attempt to break the * transfer up into smaller (byte-size) chunks because the AML specifically * asked for a transfer width that the hardware may require. */ switch (function) { case ACPI_READ: *value = 0; switch (bit_width) { case 8: *value = (u64) ACPI_GET8(logical_addr_ptr); break; case 16: *value = (u64) ACPI_GET16(logical_addr_ptr); break; case 32: *value = (u64) ACPI_GET32(logical_addr_ptr); break; case 64: *value = (u64) ACPI_GET64(logical_addr_ptr); break; default: /* bit_width was already validated */ break; } break; case ACPI_WRITE: switch (bit_width) { case 8: ACPI_SET8(logical_addr_ptr) = (u8) * value; break; case 16: ACPI_SET16(logical_addr_ptr) = (u16) * value; break; case 32: ACPI_SET32(logical_addr_ptr) = (u32) * value; break; case 64: ACPI_SET64(logical_addr_ptr) = (u64) * value; break; default: /* bit_width was already validated */ break; } break; default: status = AE_BAD_PARAMETER; break; } return_ACPI_STATUS(status); }
ACPI_STATUS AcpiExSystemMemorySpaceHandler ( UINT32 Function, ACPI_PHYSICAL_ADDRESS Address, UINT32 BitWidth, UINT64 *Value, void *HandlerContext, void *RegionContext) { ACPI_STATUS Status = AE_OK; void *LogicalAddrPtr = NULL; ACPI_MEM_SPACE_CONTEXT *MemInfo = RegionContext; UINT32 Length; ACPI_SIZE MapLength; ACPI_SIZE PageBoundaryMapLength; #ifdef ACPI_MISALIGNMENT_NOT_SUPPORTED UINT32 Remainder; #endif ACPI_FUNCTION_TRACE (ExSystemMemorySpaceHandler); /* Validate and translate the bit width */ switch (BitWidth) { case 8: Length = 1; break; case 16: Length = 2; break; case 32: Length = 4; break; case 64: Length = 8; break; default: ACPI_ERROR ((AE_INFO, "Invalid SystemMemory width %u", BitWidth)); return_ACPI_STATUS (AE_AML_OPERAND_VALUE); } #ifdef ACPI_MISALIGNMENT_NOT_SUPPORTED /* * Hardware does not support non-aligned data transfers, we must verify * the request. */ (void) AcpiUtShortDivide ((UINT64) Address, Length, NULL, &Remainder); if (Remainder != 0) { return_ACPI_STATUS (AE_AML_ALIGNMENT); } #endif /* * Does the request fit into the cached memory mapping? * Is 1) Address below the current mapping? OR * 2) Address beyond the current mapping? */ if ((Address < MemInfo->MappedPhysicalAddress) || (((UINT64) Address + Length) > ((UINT64) MemInfo->MappedPhysicalAddress + MemInfo->MappedLength))) { /* * The request cannot be resolved by the current memory mapping; * Delete the existing mapping and create a new one. */ if (MemInfo->MappedLength) { /* Valid mapping, delete it */ AcpiOsUnmapMemory (MemInfo->MappedLogicalAddress, MemInfo->MappedLength); } /* * October 2009: Attempt to map from the requested address to the * end of the region. However, we will never map more than one * page, nor will we cross a page boundary. */ MapLength = (ACPI_SIZE) ((MemInfo->Address + MemInfo->Length) - Address); /* * If mapping the entire remaining portion of the region will cross * a page boundary, just map up to the page boundary, do not cross. * On some systems, crossing a page boundary while mapping regions * can cause warnings if the pages have different attributes * due to resource management. * * This has the added benefit of constraining a single mapping to * one page, which is similar to the original code that used a 4k * maximum window. */ PageBoundaryMapLength = (ACPI_SIZE) (ACPI_ROUND_UP (Address, ACPI_DEFAULT_PAGE_SIZE) - Address); if (PageBoundaryMapLength == 0) { PageBoundaryMapLength = ACPI_DEFAULT_PAGE_SIZE; } if (MapLength > PageBoundaryMapLength) { MapLength = PageBoundaryMapLength; } /* Create a new mapping starting at the address given */ MemInfo->MappedLogicalAddress = AcpiOsMapMemory (Address, MapLength); if (!MemInfo->MappedLogicalAddress) { ACPI_ERROR ((AE_INFO, "Could not map memory at 0x%8.8X%8.8X, size %u", ACPI_FORMAT_UINT64 (Address), (UINT32) MapLength)); MemInfo->MappedLength = 0; return_ACPI_STATUS (AE_NO_MEMORY); } /* Save the physical address and mapping size */ MemInfo->MappedPhysicalAddress = Address; MemInfo->MappedLength = MapLength; } /* * Generate a logical pointer corresponding to the address we want to * access */ LogicalAddrPtr = MemInfo->MappedLogicalAddress + ((UINT64) Address - (UINT64) MemInfo->MappedPhysicalAddress); ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "System-Memory (width %u) R/W %u Address=%8.8X%8.8X\n", BitWidth, Function, ACPI_FORMAT_UINT64 (Address))); /* * Perform the memory read or write * * Note: For machines that do not support non-aligned transfers, the target * address was checked for alignment above. We do not attempt to break the * transfer up into smaller (byte-size) chunks because the AML specifically * asked for a transfer width that the hardware may require. */ switch (Function) { case ACPI_READ: *Value = 0; switch (BitWidth) { case 8: *Value = (UINT64) ACPI_GET8 (LogicalAddrPtr); break; case 16: *Value = (UINT64) ACPI_GET16 (LogicalAddrPtr); break; case 32: *Value = (UINT64) ACPI_GET32 (LogicalAddrPtr); break; case 64: *Value = (UINT64) ACPI_GET64 (LogicalAddrPtr); break; default: /* BitWidth was already validated */ break; } break; case ACPI_WRITE: switch (BitWidth) { case 8: ACPI_SET8 (LogicalAddrPtr, *Value); break; case 16: ACPI_SET16 (LogicalAddrPtr, *Value); break; case 32: ACPI_SET32 (LogicalAddrPtr, *Value); break; case 64: ACPI_SET64 (LogicalAddrPtr, *Value); break; default: /* BitWidth was already validated */ break; } break; default: Status = AE_BAD_PARAMETER; break; } return_ACPI_STATUS (Status); }
/******************************************************************************* * * FUNCTION: acpi_ex_system_memory_space_handler * * PARAMETERS: Function - Read or Write operation * Address - Where in the space to read or write * bit_width - Field width in bits (8, 16, or 32) * Value - Pointer to in or out value * handler_context - Pointer to Handler's context * region_context - Pointer to context specific to the * accessed region * * RETURN: Status * * DESCRIPTION: Handler for the System Memory address space (Op Region) * ******************************************************************************/ acpi_status acpi_ex_system_memory_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; void *logical_addr_ptr = NULL; struct acpi_mem_space_context *mem_info = region_context; u32 length; acpi_size window_size; #ifdef ACPI_MISALIGNMENT_NOT_SUPPORTED u32 remainder; #endif ACPI_FUNCTION_TRACE(ex_system_memory_space_handler); /* Validate and translate the bit width */ switch (bit_width) { case 8: length = 1; break; case 16: length = 2; break; case 32: length = 4; break; case 64: length = 8; break; default: ACPI_ERROR((AE_INFO, "Invalid SystemMemory width %d", bit_width)); return_ACPI_STATUS(AE_AML_OPERAND_VALUE); } #ifdef ACPI_MISALIGNMENT_NOT_SUPPORTED /* * Hardware does not support non-aligned data transfers, we must verify * the request. */ (void)acpi_ut_short_divide((acpi_integer) address, length, NULL, &remainder); if (remainder != 0) { return_ACPI_STATUS(AE_AML_ALIGNMENT); } #endif /* * Does the request fit into the cached memory mapping? * Is 1) Address below the current mapping? OR * 2) Address beyond the current mapping? */ if ((address < mem_info->mapped_physical_address) || (((acpi_integer) address + length) > ((acpi_integer) mem_info-> mapped_physical_address + mem_info->mapped_length))) { /* * The request cannot be resolved by the current memory mapping; * Delete the existing mapping and create a new one. */ if (mem_info->mapped_length) { /* Valid mapping, delete it */ acpi_os_unmap_memory(mem_info->mapped_logical_address, mem_info->mapped_length); } /* * Don't attempt to map memory beyond the end of the region, and * constrain the maximum mapping size to something reasonable. */ window_size = (acpi_size) ((mem_info->address + mem_info->length) - address); if (window_size > ACPI_SYSMEM_REGION_WINDOW_SIZE) { window_size = ACPI_SYSMEM_REGION_WINDOW_SIZE; } /* Create a new mapping starting at the address given */ mem_info->mapped_logical_address = acpi_os_map_memory((acpi_native_uint) address, window_size); if (!mem_info->mapped_logical_address) { ACPI_ERROR((AE_INFO, "Could not map memory at %8.8X%8.8X, size %X", ACPI_FORMAT_UINT64(address), (u32) window_size)); mem_info->mapped_length = 0; return_ACPI_STATUS(AE_NO_MEMORY); } /* Save the physical address and mapping size */ mem_info->mapped_physical_address = address; mem_info->mapped_length = window_size; } /* * Generate a logical pointer corresponding to the address we want to * access */ logical_addr_ptr = mem_info->mapped_logical_address + ((acpi_integer) address - (acpi_integer) mem_info->mapped_physical_address); ACPI_DEBUG_PRINT((ACPI_DB_INFO, "System-Memory (width %d) R/W %d Address=%8.8X%8.8X\n", bit_width, function, ACPI_FORMAT_UINT64(address))); /* * Perform the memory read or write * * Note: For machines that do not support non-aligned transfers, the target * address was checked for alignment above. We do not attempt to break the * transfer up into smaller (byte-size) chunks because the AML specifically * asked for a transfer width that the hardware may require. */ switch (function) { case ACPI_READ: *value = 0; switch (bit_width) { case 8: *value = (acpi_integer) ACPI_GET8(logical_addr_ptr); break; case 16: *value = (acpi_integer) ACPI_GET16(logical_addr_ptr); break; case 32: *value = (acpi_integer) ACPI_GET32(logical_addr_ptr); break; case 64: *value = (acpi_integer) ACPI_GET64(logical_addr_ptr); break; default: /* bit_width was already validated */ break; } break; case ACPI_WRITE: switch (bit_width) { case 8: ACPI_SET8(logical_addr_ptr) = (u8) * value; break; case 16: ACPI_SET16(logical_addr_ptr) = (u16) * value; break; case 32: ACPI_SET32(logical_addr_ptr) = (u32) * value; break; case 64: ACPI_SET64(logical_addr_ptr) = (u64) * value; break; default: /* bit_width was already validated */ break; } break; default: status = AE_BAD_PARAMETER; break; } return_ACPI_STATUS(status); }
ACPI_STATUS AcpiExSystemMemorySpaceHandler ( UINT32 Function, ACPI_PHYSICAL_ADDRESS Address, UINT32 BitWidth, ACPI_INTEGER *Value, void *HandlerContext, void *RegionContext) { ACPI_STATUS Status = AE_OK; void *LogicalAddrPtr = NULL; ACPI_MEM_SPACE_CONTEXT *MemInfo = RegionContext; UINT32 Length; ACPI_SIZE WindowSize; #ifdef ACPI_MISALIGNMENT_NOT_SUPPORTED UINT32 Remainder; #endif ACPI_FUNCTION_TRACE (ExSystemMemorySpaceHandler); /* Validate and translate the bit width */ switch (BitWidth) { case 8: Length = 1; break; case 16: Length = 2; break; case 32: Length = 4; break; case 64: Length = 8; break; default: ACPI_ERROR ((AE_INFO, "Invalid SystemMemory width %d", BitWidth)); return_ACPI_STATUS (AE_AML_OPERAND_VALUE); } #ifdef ACPI_MISALIGNMENT_NOT_SUPPORTED /* * Hardware does not support non-aligned data transfers, we must verify * the request. */ (void) AcpiUtShortDivide ((ACPI_INTEGER) Address, Length, NULL, &Remainder); if (Remainder != 0) { return_ACPI_STATUS (AE_AML_ALIGNMENT); } #endif /* * Does the request fit into the cached memory mapping? * Is 1) Address below the current mapping? OR * 2) Address beyond the current mapping? */ if ((Address < MemInfo->MappedPhysicalAddress) || (((ACPI_INTEGER) Address + Length) > ((ACPI_INTEGER) MemInfo->MappedPhysicalAddress + MemInfo->MappedLength))) { /* * The request cannot be resolved by the current memory mapping; * Delete the existing mapping and create a new one. */ if (MemInfo->MappedLength) { /* Valid mapping, delete it */ AcpiOsUnmapMemory (MemInfo->MappedLogicalAddress, MemInfo->MappedLength); } /* * Don't attempt to map memory beyond the end of the region, and * constrain the maximum mapping size to something reasonable. */ WindowSize = (ACPI_SIZE) ((MemInfo->Address + MemInfo->Length) - Address); if (WindowSize > ACPI_SYSMEM_REGION_WINDOW_SIZE) { WindowSize = ACPI_SYSMEM_REGION_WINDOW_SIZE; } /* Create a new mapping starting at the address given */ MemInfo->MappedLogicalAddress = AcpiOsMapMemory ( (ACPI_PHYSICAL_ADDRESS) Address, WindowSize); if (!MemInfo->MappedLogicalAddress) { ACPI_ERROR ((AE_INFO, "Could not map memory at %8.8X%8.8X, size %X", ACPI_FORMAT_NATIVE_UINT (Address), (UINT32) WindowSize)); MemInfo->MappedLength = 0; return_ACPI_STATUS (AE_NO_MEMORY); } /* Save the physical address and mapping size */ MemInfo->MappedPhysicalAddress = Address; MemInfo->MappedLength = WindowSize; } /* * Generate a logical pointer corresponding to the address we want to * access */ LogicalAddrPtr = MemInfo->MappedLogicalAddress + ((ACPI_INTEGER) Address - (ACPI_INTEGER) MemInfo->MappedPhysicalAddress); ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "System-Memory (width %d) R/W %d Address=%8.8X%8.8X\n", BitWidth, Function, ACPI_FORMAT_NATIVE_UINT (Address))); /* * Perform the memory read or write * * Note: For machines that do not support non-aligned transfers, the target * address was checked for alignment above. We do not attempt to break the * transfer up into smaller (byte-size) chunks because the AML specifically * asked for a transfer width that the hardware may require. */ switch (Function) { case ACPI_READ: *Value = 0; switch (BitWidth) { case 8: *Value = (ACPI_INTEGER) ACPI_GET8 (LogicalAddrPtr); break; case 16: *Value = (ACPI_INTEGER) ACPI_GET16 (LogicalAddrPtr); break; case 32: *Value = (ACPI_INTEGER) ACPI_GET32 (LogicalAddrPtr); break; case 64: *Value = (ACPI_INTEGER) ACPI_GET64 (LogicalAddrPtr); break; default: /* BitWidth was already validated */ break; } break; case ACPI_WRITE: switch (BitWidth) { case 8: ACPI_SET8 (LogicalAddrPtr) = (UINT8) *Value; break; case 16: ACPI_SET16 (LogicalAddrPtr) = (UINT16) *Value; break; case 32: ACPI_SET32 ( LogicalAddrPtr) = (UINT32) *Value; break; case 64: ACPI_SET64 (LogicalAddrPtr) = (UINT64) *Value; break; default: /* BitWidth was already validated */ break; } break; default: Status = AE_BAD_PARAMETER; break; } return_ACPI_STATUS (Status); }