2 /******************************************************************************
4 * Module Name: exregion - ACPI default OpRegion (address space) handlers
6 *****************************************************************************/
9 * Copyright (C) 2000 - 2011, Intel Corp.
10 * All rights reserved.
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions, and the following disclaimer,
17 * without modification.
18 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
19 * substantially similar to the "NO WARRANTY" disclaimer below
20 * ("Disclaimer") and any redistribution must be conditioned upon
21 * including a substantially similar Disclaimer requirement for further
22 * binary redistribution.
23 * 3. Neither the names of the above-listed copyright holders nor the names
24 * of any contributors may be used to endorse or promote products derived
25 * from this software without specific prior written permission.
27 * Alternatively, this software may be distributed under the terms of the
28 * GNU General Public License ("GPL") version 2 as published by the Free
29 * Software Foundation.
32 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
33 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
34 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
35 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
36 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
40 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
41 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42 * POSSIBILITY OF SUCH DAMAGES.
46 #define __EXREGION_C__
48 #include <contrib/dev/acpica/include/acpi.h>
49 #include <contrib/dev/acpica/include/accommon.h>
50 #include <contrib/dev/acpica/include/acinterp.h>
53 #define _COMPONENT ACPI_EXECUTER
54 ACPI_MODULE_NAME ("exregion")
57 /*******************************************************************************
59 * FUNCTION: AcpiExSystemMemorySpaceHandler
61 * PARAMETERS: Function - Read or Write operation
62 * Address - Where in the space to read or write
63 * BitWidth - Field width in bits (8, 16, or 32)
64 * Value - Pointer to in or out value
65 * HandlerContext - Pointer to Handler's context
66 * RegionContext - Pointer to context specific to the
71 * DESCRIPTION: Handler for the System Memory address space (Op Region)
73 ******************************************************************************/
76 AcpiExSystemMemorySpaceHandler (
78 ACPI_PHYSICAL_ADDRESS Address,
84 ACPI_STATUS Status = AE_OK;
85 void *LogicalAddrPtr = NULL;
86 ACPI_MEM_SPACE_CONTEXT *MemInfo = RegionContext;
89 ACPI_SIZE PageBoundaryMapLength;
90 #ifdef ACPI_MISALIGNMENT_NOT_SUPPORTED
95 ACPI_FUNCTION_TRACE (ExSystemMemorySpaceHandler);
98 /* Validate and translate the bit width */
119 ACPI_ERROR ((AE_INFO, "Invalid SystemMemory width %u",
121 return_ACPI_STATUS (AE_AML_OPERAND_VALUE);
124 #ifdef ACPI_MISALIGNMENT_NOT_SUPPORTED
126 * Hardware does not support non-aligned data transfers, we must verify
129 (void) AcpiUtShortDivide ((UINT64) Address, Length, NULL, &Remainder);
132 return_ACPI_STATUS (AE_AML_ALIGNMENT);
137 * Does the request fit into the cached memory mapping?
138 * Is 1) Address below the current mapping? OR
139 * 2) Address beyond the current mapping?
141 if ((Address < MemInfo->MappedPhysicalAddress) ||
142 (((UINT64) Address + Length) >
144 MemInfo->MappedPhysicalAddress + MemInfo->MappedLength)))
147 * The request cannot be resolved by the current memory mapping;
148 * Delete the existing mapping and create a new one.
150 if (MemInfo->MappedLength)
152 /* Valid mapping, delete it */
154 AcpiOsUnmapMemory (MemInfo->MappedLogicalAddress,
155 MemInfo->MappedLength);
159 * October 2009: Attempt to map from the requested address to the
160 * end of the region. However, we will never map more than one
161 * page, nor will we cross a page boundary.
163 MapLength = (ACPI_SIZE)
164 ((MemInfo->Address + MemInfo->Length) - Address);
167 * If mapping the entire remaining portion of the region will cross
168 * a page boundary, just map up to the page boundary, do not cross.
169 * On some systems, crossing a page boundary while mapping regions
170 * can cause warnings if the pages have different attributes
171 * due to resource management.
173 * This has the added benefit of constraining a single mapping to
174 * one page, which is similar to the original code that used a 4k
177 PageBoundaryMapLength =
178 ACPI_ROUND_UP (Address, ACPI_DEFAULT_PAGE_SIZE) - Address;
179 if (PageBoundaryMapLength == 0)
181 PageBoundaryMapLength = ACPI_DEFAULT_PAGE_SIZE;
184 if (MapLength > PageBoundaryMapLength)
186 MapLength = PageBoundaryMapLength;
189 /* Create a new mapping starting at the address given */
191 MemInfo->MappedLogicalAddress = AcpiOsMapMemory (
192 (ACPI_PHYSICAL_ADDRESS) Address, MapLength);
193 if (!MemInfo->MappedLogicalAddress)
195 ACPI_ERROR ((AE_INFO,
196 "Could not map memory at 0x%8.8X%8.8X, size %u",
197 ACPI_FORMAT_NATIVE_UINT (Address), (UINT32) MapLength));
198 MemInfo->MappedLength = 0;
199 return_ACPI_STATUS (AE_NO_MEMORY);
202 /* Save the physical address and mapping size */
204 MemInfo->MappedPhysicalAddress = Address;
205 MemInfo->MappedLength = MapLength;
209 * Generate a logical pointer corresponding to the address we want to
212 LogicalAddrPtr = MemInfo->MappedLogicalAddress +
213 ((UINT64) Address - (UINT64) MemInfo->MappedPhysicalAddress);
215 ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
216 "System-Memory (width %u) R/W %u Address=%8.8X%8.8X\n",
217 BitWidth, Function, ACPI_FORMAT_NATIVE_UINT (Address)));
220 * Perform the memory read or write
222 * Note: For machines that do not support non-aligned transfers, the target
223 * address was checked for alignment above. We do not attempt to break the
224 * transfer up into smaller (byte-size) chunks because the AML specifically
225 * asked for a transfer width that the hardware may require.
235 *Value = (UINT64) ACPI_GET8 (LogicalAddrPtr);
239 *Value = (UINT64) ACPI_GET16 (LogicalAddrPtr);
243 *Value = (UINT64) ACPI_GET32 (LogicalAddrPtr);
247 *Value = (UINT64) ACPI_GET64 (LogicalAddrPtr);
251 /* BitWidth was already validated */
261 ACPI_SET8 (LogicalAddrPtr) = (UINT8) *Value;
265 ACPI_SET16 (LogicalAddrPtr) = (UINT16) *Value;
269 ACPI_SET32 ( LogicalAddrPtr) = (UINT32) *Value;
273 ACPI_SET64 (LogicalAddrPtr) = (UINT64) *Value;
277 /* BitWidth was already validated */
283 Status = AE_BAD_PARAMETER;
287 return_ACPI_STATUS (Status);
291 /*******************************************************************************
293 * FUNCTION: AcpiExSystemIoSpaceHandler
295 * PARAMETERS: Function - Read or Write operation
296 * Address - Where in the space to read or write
297 * BitWidth - Field width in bits (8, 16, or 32)
298 * Value - Pointer to in or out value
299 * HandlerContext - Pointer to Handler's context
300 * RegionContext - Pointer to context specific to the
305 * DESCRIPTION: Handler for the System IO address space (Op Region)
307 ******************************************************************************/
310 AcpiExSystemIoSpaceHandler (
312 ACPI_PHYSICAL_ADDRESS Address,
315 void *HandlerContext,
318 ACPI_STATUS Status = AE_OK;
322 ACPI_FUNCTION_TRACE (ExSystemIoSpaceHandler);
325 ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
326 "System-IO (width %u) R/W %u Address=%8.8X%8.8X\n",
327 BitWidth, Function, ACPI_FORMAT_NATIVE_UINT (Address)));
329 /* Decode the function parameter */
335 Status = AcpiHwReadPort ((ACPI_IO_ADDRESS) Address,
342 Status = AcpiHwWritePort ((ACPI_IO_ADDRESS) Address,
343 (UINT32) *Value, BitWidth);
347 Status = AE_BAD_PARAMETER;
351 return_ACPI_STATUS (Status);
355 /*******************************************************************************
357 * FUNCTION: AcpiExPciConfigSpaceHandler
359 * PARAMETERS: Function - Read or Write operation
360 * Address - Where in the space to read or write
361 * BitWidth - Field width in bits (8, 16, or 32)
362 * Value - Pointer to in or out value
363 * HandlerContext - Pointer to Handler's context
364 * RegionContext - Pointer to context specific to the
369 * DESCRIPTION: Handler for the PCI Config address space (Op Region)
371 ******************************************************************************/
374 AcpiExPciConfigSpaceHandler (
376 ACPI_PHYSICAL_ADDRESS Address,
379 void *HandlerContext,
382 ACPI_STATUS Status = AE_OK;
387 ACPI_FUNCTION_TRACE (ExPciConfigSpaceHandler);
391 * The arguments to AcpiOs(Read|Write)PciConfiguration are:
393 * PciSegment is the PCI bus segment range 0-31
394 * PciBus is the PCI bus number range 0-255
395 * PciDevice is the PCI device number range 0-31
396 * PciFunction is the PCI device function number
397 * PciRegister is the Config space register range 0-255 bytes
399 * Value - input value for write, output address for read
402 PciId = (ACPI_PCI_ID *) RegionContext;
403 PciRegister = (UINT16) (UINT32) Address;
405 ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
406 "Pci-Config %u (%u) Seg(%04x) Bus(%04x) Dev(%04x) Func(%04x) Reg(%04x)\n",
407 Function, BitWidth, PciId->Segment, PciId->Bus, PciId->Device,
408 PciId->Function, PciRegister));
415 Status = AcpiOsReadPciConfiguration (PciId, PciRegister,
421 Status = AcpiOsWritePciConfiguration (PciId, PciRegister,
427 Status = AE_BAD_PARAMETER;
431 return_ACPI_STATUS (Status);
435 /*******************************************************************************
437 * FUNCTION: AcpiExCmosSpaceHandler
439 * PARAMETERS: Function - Read or Write operation
440 * Address - Where in the space to read or write
441 * BitWidth - Field width in bits (8, 16, or 32)
442 * Value - Pointer to in or out value
443 * HandlerContext - Pointer to Handler's context
444 * RegionContext - Pointer to context specific to the
449 * DESCRIPTION: Handler for the CMOS address space (Op Region)
451 ******************************************************************************/
454 AcpiExCmosSpaceHandler (
456 ACPI_PHYSICAL_ADDRESS Address,
459 void *HandlerContext,
462 ACPI_STATUS Status = AE_OK;
465 ACPI_FUNCTION_TRACE (ExCmosSpaceHandler);
468 return_ACPI_STATUS (Status);
472 /*******************************************************************************
474 * FUNCTION: AcpiExPciBarSpaceHandler
476 * PARAMETERS: Function - Read or Write operation
477 * Address - Where in the space to read or write
478 * BitWidth - Field width in bits (8, 16, or 32)
479 * Value - Pointer to in or out value
480 * HandlerContext - Pointer to Handler's context
481 * RegionContext - Pointer to context specific to the
486 * DESCRIPTION: Handler for the PCI BarTarget address space (Op Region)
488 ******************************************************************************/
491 AcpiExPciBarSpaceHandler (
493 ACPI_PHYSICAL_ADDRESS Address,
496 void *HandlerContext,
499 ACPI_STATUS Status = AE_OK;
502 ACPI_FUNCTION_TRACE (ExPciBarSpaceHandler);
505 return_ACPI_STATUS (Status);
509 /*******************************************************************************
511 * FUNCTION: AcpiExDataTableSpaceHandler
513 * PARAMETERS: Function - Read or Write operation
514 * Address - Where in the space to read or write
515 * BitWidth - Field width in bits (8, 16, or 32)
516 * Value - Pointer to in or out value
517 * HandlerContext - Pointer to Handler's context
518 * RegionContext - Pointer to context specific to the
523 * DESCRIPTION: Handler for the Data Table address space (Op Region)
525 ******************************************************************************/
528 AcpiExDataTableSpaceHandler (
530 ACPI_PHYSICAL_ADDRESS Address,
533 void *HandlerContext,
536 ACPI_FUNCTION_TRACE (ExDataTableSpaceHandler);
540 * Perform the memory read or write. The BitWidth was already
547 ACPI_MEMCPY (ACPI_CAST_PTR (char, Value), ACPI_PHYSADDR_TO_PTR (Address),
548 ACPI_DIV_8 (BitWidth));
553 ACPI_MEMCPY (ACPI_PHYSADDR_TO_PTR (Address), ACPI_CAST_PTR (char, Value),
554 ACPI_DIV_8 (BitWidth));
559 return_ACPI_STATUS (AE_BAD_PARAMETER);
562 return_ACPI_STATUS (AE_OK);