xref: /openbmc/linux/drivers/acpi/acpica/exregion.c (revision 57904291176fa16a981cefca5cbe1a0b50196792)
195857638SErik Schmauss // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
295b482a8SLen Brown /******************************************************************************
395b482a8SLen Brown  *
495b482a8SLen Brown  * Module Name: exregion - ACPI default op_region (address space) handlers
595b482a8SLen Brown  *
6612c2932SBob Moore  * Copyright (C) 2000 - 2023, Intel Corp.
795b482a8SLen Brown  *
895857638SErik Schmauss  *****************************************************************************/
995b482a8SLen Brown 
1095b482a8SLen Brown #include <acpi/acpi.h>
11e2f7a777SLen Brown #include "accommon.h"
12e2f7a777SLen Brown #include "acinterp.h"
1395b482a8SLen Brown 
1495b482a8SLen Brown #define _COMPONENT          ACPI_EXECUTER
1595b482a8SLen Brown ACPI_MODULE_NAME("exregion")
1695b482a8SLen Brown 
1795b482a8SLen Brown /*******************************************************************************
1895b482a8SLen Brown  *
1995b482a8SLen Brown  * FUNCTION:    acpi_ex_system_memory_space_handler
2095b482a8SLen Brown  *
21ba494beeSBob Moore  * PARAMETERS:  function            - Read or Write operation
22ba494beeSBob Moore  *              address             - Where in the space to read or write
2395b482a8SLen Brown  *              bit_width           - Field width in bits (8, 16, or 32)
24ba494beeSBob Moore  *              value               - Pointer to in or out value
2595b482a8SLen Brown  *              handler_context     - Pointer to Handler's context
2695b482a8SLen Brown  *              region_context      - Pointer to context specific to the
2795b482a8SLen Brown  *                                    accessed region
2895b482a8SLen Brown  *
2995b482a8SLen Brown  * RETURN:      Status
3095b482a8SLen Brown  *
3195b482a8SLen Brown  * DESCRIPTION: Handler for the System Memory address space (Op Region)
3295b482a8SLen Brown  *
3395b482a8SLen Brown  ******************************************************************************/
3495b482a8SLen Brown 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)3595b482a8SLen Brown acpi_ex_system_memory_space_handler(u32 function,
3695b482a8SLen Brown 				    acpi_physical_address address,
3795b482a8SLen Brown 				    u32 bit_width,
385df7e6cbSBob Moore 				    u64 *value,
3995b482a8SLen Brown 				    void *handler_context, void *region_context)
4095b482a8SLen Brown {
4195b482a8SLen Brown 	acpi_status status = AE_OK;
4295b482a8SLen Brown 	void *logical_addr_ptr = NULL;
4395b482a8SLen Brown 	struct acpi_mem_space_context *mem_info = region_context;
44b8fcd0e5SRafael J. Wysocki 	struct acpi_mem_mapping *mm = mem_info->cur_mm;
4595b482a8SLen Brown 	u32 length;
46d410ee51SBob Moore 	acpi_size map_length;
4795b482a8SLen Brown #ifdef ACPI_MISALIGNMENT_NOT_SUPPORTED
4895b482a8SLen Brown 	u32 remainder;
4995b482a8SLen Brown #endif
5095b482a8SLen Brown 
5195b482a8SLen Brown 	ACPI_FUNCTION_TRACE(ex_system_memory_space_handler);
5295b482a8SLen Brown 
5395b482a8SLen Brown 	/* Validate and translate the bit width */
5495b482a8SLen Brown 
5595b482a8SLen Brown 	switch (bit_width) {
5695b482a8SLen Brown 	case 8:
571d1ea1b7SChao Guan 
5895b482a8SLen Brown 		length = 1;
5995b482a8SLen Brown 		break;
6095b482a8SLen Brown 
6195b482a8SLen Brown 	case 16:
621d1ea1b7SChao Guan 
6395b482a8SLen Brown 		length = 2;
6495b482a8SLen Brown 		break;
6595b482a8SLen Brown 
6695b482a8SLen Brown 	case 32:
671d1ea1b7SChao Guan 
6895b482a8SLen Brown 		length = 4;
6995b482a8SLen Brown 		break;
7095b482a8SLen Brown 
7195b482a8SLen Brown 	case 64:
721d1ea1b7SChao Guan 
7395b482a8SLen Brown 		length = 8;
7495b482a8SLen Brown 		break;
7595b482a8SLen Brown 
7695b482a8SLen Brown 	default:
771d1ea1b7SChao Guan 
78f6a22b0bSBob Moore 		ACPI_ERROR((AE_INFO, "Invalid SystemMemory width %u",
7995b482a8SLen Brown 			    bit_width));
8095b482a8SLen Brown 		return_ACPI_STATUS(AE_AML_OPERAND_VALUE);
8195b482a8SLen Brown 	}
8295b482a8SLen Brown 
8395b482a8SLen Brown #ifdef ACPI_MISALIGNMENT_NOT_SUPPORTED
8495b482a8SLen Brown 	/*
8595b482a8SLen Brown 	 * Hardware does not support non-aligned data transfers, we must verify
8695b482a8SLen Brown 	 * the request.
8795b482a8SLen Brown 	 */
885df7e6cbSBob Moore 	(void)acpi_ut_short_divide((u64) address, length, NULL, &remainder);
8995b482a8SLen Brown 	if (remainder != 0) {
9095b482a8SLen Brown 		return_ACPI_STATUS(AE_AML_ALIGNMENT);
9195b482a8SLen Brown 	}
9295b482a8SLen Brown #endif
9395b482a8SLen Brown 
9495b482a8SLen Brown 	/*
9595b482a8SLen Brown 	 * Does the request fit into the cached memory mapping?
9695b482a8SLen Brown 	 * Is 1) Address below the current mapping? OR
9795b482a8SLen Brown 	 *    2) Address beyond the current mapping?
9895b482a8SLen Brown 	 */
99b8fcd0e5SRafael J. Wysocki 	if (!mm || (address < mm->physical_address) ||
100b8fcd0e5SRafael J. Wysocki 	    ((u64) address + length > (u64) mm->physical_address + mm->length)) {
10195b482a8SLen Brown 		/*
102b8fcd0e5SRafael J. Wysocki 		 * The request cannot be resolved by the current memory mapping.
103b8fcd0e5SRafael J. Wysocki 		 *
104b8fcd0e5SRafael J. Wysocki 		 * Look for an existing saved mapping covering the address range
105b8fcd0e5SRafael J. Wysocki 		 * at hand.  If found, save it as the current one and carry out
106b8fcd0e5SRafael J. Wysocki 		 * the access.
10795b482a8SLen Brown 		 */
108b8fcd0e5SRafael J. Wysocki 		for (mm = mem_info->first_mm; mm; mm = mm->next_mm) {
109b8fcd0e5SRafael J. Wysocki 			if (mm == mem_info->cur_mm)
110b8fcd0e5SRafael J. Wysocki 				continue;
11195b482a8SLen Brown 
112b8fcd0e5SRafael J. Wysocki 			if (address < mm->physical_address)
113b8fcd0e5SRafael J. Wysocki 				continue;
11495b482a8SLen Brown 
115b8fcd0e5SRafael J. Wysocki 			if ((u64) address + length >
116b8fcd0e5SRafael J. Wysocki 					(u64) mm->physical_address + mm->length)
117b8fcd0e5SRafael J. Wysocki 				continue;
118b8fcd0e5SRafael J. Wysocki 
119b8fcd0e5SRafael J. Wysocki 			mem_info->cur_mm = mm;
120b8fcd0e5SRafael J. Wysocki 			goto access;
121b8fcd0e5SRafael J. Wysocki 		}
122b8fcd0e5SRafael J. Wysocki 
123b8fcd0e5SRafael J. Wysocki 		/* Create a new mappings list entry */
124b8fcd0e5SRafael J. Wysocki 		mm = ACPI_ALLOCATE_ZEROED(sizeof(*mm));
125b8fcd0e5SRafael J. Wysocki 		if (!mm) {
126b8fcd0e5SRafael J. Wysocki 			ACPI_ERROR((AE_INFO,
127b8fcd0e5SRafael J. Wysocki 				    "Unable to save memory mapping at 0x%8.8X%8.8X, size %u",
128b8fcd0e5SRafael J. Wysocki 				    ACPI_FORMAT_UINT64(address), length));
129b8fcd0e5SRafael J. Wysocki 			return_ACPI_STATUS(AE_NO_MEMORY);
13095b482a8SLen Brown 		}
13195b482a8SLen Brown 
13295b482a8SLen Brown 		/*
13375c8044fSLv Zheng 		 * October 2009: Attempt to map from the requested address to the
13475c8044fSLv Zheng 		 * end of the region. However, we will never map more than one
13575c8044fSLv Zheng 		 * page, nor will we cross a page boundary.
13695b482a8SLen Brown 		 */
137d410ee51SBob Moore 		map_length = (acpi_size)
13895b482a8SLen Brown 		    ((mem_info->address + mem_info->length) - address);
13995b482a8SLen Brown 
140*434c6b92SRaju Rangoju 		if (map_length > ACPI_DEFAULT_PAGE_SIZE)
141*434c6b92SRaju Rangoju 			map_length = ACPI_DEFAULT_PAGE_SIZE;
14295b482a8SLen Brown 
14395b482a8SLen Brown 		/* Create a new mapping starting at the address given */
14495b482a8SLen Brown 
145b8fcd0e5SRafael J. Wysocki 		logical_addr_ptr = acpi_os_map_memory(address, map_length);
146b8fcd0e5SRafael J. Wysocki 		if (!logical_addr_ptr) {
14795b482a8SLen Brown 			ACPI_ERROR((AE_INFO,
148f6a22b0bSBob Moore 				    "Could not map memory at 0x%8.8X%8.8X, size %u",
1491d0a0b2fSLv Zheng 				    ACPI_FORMAT_UINT64(address),
150d410ee51SBob Moore 				    (u32)map_length));
151b8fcd0e5SRafael J. Wysocki 			ACPI_FREE(mm);
15295b482a8SLen Brown 			return_ACPI_STATUS(AE_NO_MEMORY);
15395b482a8SLen Brown 		}
15495b482a8SLen Brown 
15595b482a8SLen Brown 		/* Save the physical address and mapping size */
15695b482a8SLen Brown 
157b8fcd0e5SRafael J. Wysocki 		mm->logical_address = logical_addr_ptr;
158b8fcd0e5SRafael J. Wysocki 		mm->physical_address = address;
159b8fcd0e5SRafael J. Wysocki 		mm->length = map_length;
160b8fcd0e5SRafael J. Wysocki 
161b8fcd0e5SRafael J. Wysocki 		/*
162b8fcd0e5SRafael J. Wysocki 		 * Add the new entry to the mappigs list and save it as the
163b8fcd0e5SRafael J. Wysocki 		 * current mapping.
164b8fcd0e5SRafael J. Wysocki 		 */
165b8fcd0e5SRafael J. Wysocki 		mm->next_mm = mem_info->first_mm;
166b8fcd0e5SRafael J. Wysocki 		mem_info->first_mm = mm;
167b8fcd0e5SRafael J. Wysocki 
168b8fcd0e5SRafael J. Wysocki 		mem_info->cur_mm = mm;
16995b482a8SLen Brown 	}
17095b482a8SLen Brown 
171b8fcd0e5SRafael J. Wysocki access:
17295b482a8SLen Brown 	/*
17395b482a8SLen Brown 	 * Generate a logical pointer corresponding to the address we want to
17495b482a8SLen Brown 	 * access
17595b482a8SLen Brown 	 */
176b8fcd0e5SRafael J. Wysocki 	logical_addr_ptr = mm->logical_address +
177b8fcd0e5SRafael J. Wysocki 		((u64) address - (u64) mm->physical_address);
17895b482a8SLen Brown 
17995b482a8SLen Brown 	ACPI_DEBUG_PRINT((ACPI_DB_INFO,
180b27d6597SBob Moore 			  "System-Memory (width %u) R/W %u Address=%8.8X%8.8X\n",
1811d0a0b2fSLv Zheng 			  bit_width, function, ACPI_FORMAT_UINT64(address)));
18295b482a8SLen Brown 
18395b482a8SLen Brown 	/*
18495b482a8SLen Brown 	 * Perform the memory read or write
18595b482a8SLen Brown 	 *
18695b482a8SLen Brown 	 * Note: For machines that do not support non-aligned transfers, the target
18795b482a8SLen Brown 	 * address was checked for alignment above. We do not attempt to break the
18895b482a8SLen Brown 	 * transfer up into smaller (byte-size) chunks because the AML specifically
18995b482a8SLen Brown 	 * asked for a transfer width that the hardware may require.
19095b482a8SLen Brown 	 */
19195b482a8SLen Brown 	switch (function) {
19295b482a8SLen Brown 	case ACPI_READ:
19395b482a8SLen Brown 
19495b482a8SLen Brown 		*value = 0;
19595b482a8SLen Brown 		switch (bit_width) {
19695b482a8SLen Brown 		case 8:
1971d1ea1b7SChao Guan 
1985df7e6cbSBob Moore 			*value = (u64)ACPI_GET8(logical_addr_ptr);
19995b482a8SLen Brown 			break;
20095b482a8SLen Brown 
20195b482a8SLen Brown 		case 16:
2021d1ea1b7SChao Guan 
2035df7e6cbSBob Moore 			*value = (u64)ACPI_GET16(logical_addr_ptr);
20495b482a8SLen Brown 			break;
20595b482a8SLen Brown 
20695b482a8SLen Brown 		case 32:
2071d1ea1b7SChao Guan 
2085df7e6cbSBob Moore 			*value = (u64)ACPI_GET32(logical_addr_ptr);
20995b482a8SLen Brown 			break;
21095b482a8SLen Brown 
21195b482a8SLen Brown 		case 64:
2121d1ea1b7SChao Guan 
2135df7e6cbSBob Moore 			*value = (u64)ACPI_GET64(logical_addr_ptr);
21495b482a8SLen Brown 			break;
21595b482a8SLen Brown 
21695b482a8SLen Brown 		default:
2171d1ea1b7SChao Guan 
21895b482a8SLen Brown 			/* bit_width was already validated */
2191d1ea1b7SChao Guan 
22095b482a8SLen Brown 			break;
22195b482a8SLen Brown 		}
22295b482a8SLen Brown 		break;
22395b482a8SLen Brown 
22495b482a8SLen Brown 	case ACPI_WRITE:
22595b482a8SLen Brown 
22695b482a8SLen Brown 		switch (bit_width) {
22795b482a8SLen Brown 		case 8:
2281d1ea1b7SChao Guan 
22957bf6aefSLv Zheng 			ACPI_SET8(logical_addr_ptr, *value);
23095b482a8SLen Brown 			break;
23195b482a8SLen Brown 
23295b482a8SLen Brown 		case 16:
2331d1ea1b7SChao Guan 
23457bf6aefSLv Zheng 			ACPI_SET16(logical_addr_ptr, *value);
23595b482a8SLen Brown 			break;
23695b482a8SLen Brown 
23795b482a8SLen Brown 		case 32:
2381d1ea1b7SChao Guan 
23957bf6aefSLv Zheng 			ACPI_SET32(logical_addr_ptr, *value);
24095b482a8SLen Brown 			break;
24195b482a8SLen Brown 
24295b482a8SLen Brown 		case 64:
2431d1ea1b7SChao Guan 
24457bf6aefSLv Zheng 			ACPI_SET64(logical_addr_ptr, *value);
24595b482a8SLen Brown 			break;
24695b482a8SLen Brown 
24795b482a8SLen Brown 		default:
2481d1ea1b7SChao Guan 
24995b482a8SLen Brown 			/* bit_width was already validated */
2501d1ea1b7SChao Guan 
25195b482a8SLen Brown 			break;
25295b482a8SLen Brown 		}
25395b482a8SLen Brown 		break;
25495b482a8SLen Brown 
25595b482a8SLen Brown 	default:
2561d1ea1b7SChao Guan 
25795b482a8SLen Brown 		status = AE_BAD_PARAMETER;
25895b482a8SLen Brown 		break;
25995b482a8SLen Brown 	}
26095b482a8SLen Brown 
26195b482a8SLen Brown 	return_ACPI_STATUS(status);
26295b482a8SLen Brown }
26395b482a8SLen Brown 
26495b482a8SLen Brown /*******************************************************************************
26595b482a8SLen Brown  *
26695b482a8SLen Brown  * FUNCTION:    acpi_ex_system_io_space_handler
26795b482a8SLen Brown  *
268ba494beeSBob Moore  * PARAMETERS:  function            - Read or Write operation
269ba494beeSBob Moore  *              address             - Where in the space to read or write
27095b482a8SLen Brown  *              bit_width           - Field width in bits (8, 16, or 32)
271ba494beeSBob Moore  *              value               - Pointer to in or out value
27295b482a8SLen Brown  *              handler_context     - Pointer to Handler's context
27395b482a8SLen Brown  *              region_context      - Pointer to context specific to the
27495b482a8SLen Brown  *                                    accessed region
27595b482a8SLen Brown  *
27695b482a8SLen Brown  * RETURN:      Status
27795b482a8SLen Brown  *
27895b482a8SLen Brown  * DESCRIPTION: Handler for the System IO address space (Op Region)
27995b482a8SLen Brown  *
28095b482a8SLen Brown  ******************************************************************************/
28195b482a8SLen Brown 
28295b482a8SLen Brown acpi_status
acpi_ex_system_io_space_handler(u32 function,acpi_physical_address address,u32 bit_width,u64 * value,void * handler_context,void * region_context)28395b482a8SLen Brown acpi_ex_system_io_space_handler(u32 function,
28495b482a8SLen Brown 				acpi_physical_address address,
28595b482a8SLen Brown 				u32 bit_width,
2865df7e6cbSBob Moore 				u64 *value,
28795b482a8SLen Brown 				void *handler_context, void *region_context)
28895b482a8SLen Brown {
28995b482a8SLen Brown 	acpi_status status = AE_OK;
29095b482a8SLen Brown 	u32 value32;
29195b482a8SLen Brown 
29295b482a8SLen Brown 	ACPI_FUNCTION_TRACE(ex_system_io_space_handler);
29395b482a8SLen Brown 
29495b482a8SLen Brown 	ACPI_DEBUG_PRINT((ACPI_DB_INFO,
295b27d6597SBob Moore 			  "System-IO (width %u) R/W %u Address=%8.8X%8.8X\n",
2961d0a0b2fSLv Zheng 			  bit_width, function, ACPI_FORMAT_UINT64(address)));
29795b482a8SLen Brown 
29895b482a8SLen Brown 	/* Decode the function parameter */
29995b482a8SLen Brown 
30095b482a8SLen Brown 	switch (function) {
30195b482a8SLen Brown 	case ACPI_READ:
30295b482a8SLen Brown 
3037f071903SBob Moore 		status = acpi_hw_read_port((acpi_io_address)address,
30495b482a8SLen Brown 					   &value32, bit_width);
30595b482a8SLen Brown 		*value = value32;
30695b482a8SLen Brown 		break;
30795b482a8SLen Brown 
30895b482a8SLen Brown 	case ACPI_WRITE:
30995b482a8SLen Brown 
3107f071903SBob Moore 		status = acpi_hw_write_port((acpi_io_address)address,
31195b482a8SLen Brown 					    (u32)*value, bit_width);
31295b482a8SLen Brown 		break;
31395b482a8SLen Brown 
31495b482a8SLen Brown 	default:
3151d1ea1b7SChao Guan 
31695b482a8SLen Brown 		status = AE_BAD_PARAMETER;
31795b482a8SLen Brown 		break;
31895b482a8SLen Brown 	}
31995b482a8SLen Brown 
32095b482a8SLen Brown 	return_ACPI_STATUS(status);
32195b482a8SLen Brown }
32295b482a8SLen Brown 
323bd23fac3SSinan Kaya #ifdef ACPI_PCI_CONFIGURED
32495b482a8SLen Brown /*******************************************************************************
32595b482a8SLen Brown  *
32695b482a8SLen Brown  * FUNCTION:    acpi_ex_pci_config_space_handler
32795b482a8SLen Brown  *
328ba494beeSBob Moore  * PARAMETERS:  function            - Read or Write operation
329ba494beeSBob Moore  *              address             - Where in the space to read or write
33095b482a8SLen Brown  *              bit_width           - Field width in bits (8, 16, or 32)
331ba494beeSBob Moore  *              value               - Pointer to in or out value
33295b482a8SLen Brown  *              handler_context     - Pointer to Handler's context
33395b482a8SLen Brown  *              region_context      - Pointer to context specific to the
33495b482a8SLen Brown  *                                    accessed region
33595b482a8SLen Brown  *
33695b482a8SLen Brown  * RETURN:      Status
33795b482a8SLen Brown  *
33895b482a8SLen Brown  * DESCRIPTION: Handler for the PCI Config address space (Op Region)
33995b482a8SLen Brown  *
34095b482a8SLen Brown  ******************************************************************************/
34195b482a8SLen Brown 
34295b482a8SLen Brown acpi_status
acpi_ex_pci_config_space_handler(u32 function,acpi_physical_address address,u32 bit_width,u64 * value,void * handler_context,void * region_context)34395b482a8SLen Brown acpi_ex_pci_config_space_handler(u32 function,
34495b482a8SLen Brown 				 acpi_physical_address address,
34595b482a8SLen Brown 				 u32 bit_width,
3465df7e6cbSBob Moore 				 u64 *value,
34795b482a8SLen Brown 				 void *handler_context, void *region_context)
34895b482a8SLen Brown {
34995b482a8SLen Brown 	acpi_status status = AE_OK;
35095b482a8SLen Brown 	struct acpi_pci_id *pci_id;
35195b482a8SLen Brown 	u16 pci_register;
35295b482a8SLen Brown 
35395b482a8SLen Brown 	ACPI_FUNCTION_TRACE(ex_pci_config_space_handler);
35495b482a8SLen Brown 
35595b482a8SLen Brown 	/*
35695b482a8SLen Brown 	 *  The arguments to acpi_os(Read|Write)pci_configuration are:
35795b482a8SLen Brown 	 *
35895b482a8SLen Brown 	 *  pci_segment is the PCI bus segment range 0-31
35995b482a8SLen Brown 	 *  pci_bus     is the PCI bus number range 0-255
36095b482a8SLen Brown 	 *  pci_device  is the PCI device number range 0-31
36195b482a8SLen Brown 	 *  pci_function is the PCI device function number
36295b482a8SLen Brown 	 *  pci_register is the Config space register range 0-255 bytes
36395b482a8SLen Brown 	 *
364ba494beeSBob Moore 	 *  value - input value for write, output address for read
36595b482a8SLen Brown 	 *
36695b482a8SLen Brown 	 */
36795b482a8SLen Brown 	pci_id = (struct acpi_pci_id *)region_context;
36895b482a8SLen Brown 	pci_register = (u16) (u32) address;
36995b482a8SLen Brown 
37095b482a8SLen Brown 	ACPI_DEBUG_PRINT((ACPI_DB_INFO,
3711fad8738SBob Moore 			  "Pci-Config %u (%u) Seg(%04x) Bus(%04x) "
3721fad8738SBob Moore 			  "Dev(%04x) Func(%04x) Reg(%04x)\n",
37395b482a8SLen Brown 			  function, bit_width, pci_id->segment, pci_id->bus,
37495b482a8SLen Brown 			  pci_id->device, pci_id->function, pci_register));
37595b482a8SLen Brown 
37695b482a8SLen Brown 	switch (function) {
37795b482a8SLen Brown 	case ACPI_READ:
37895b482a8SLen Brown 
379bb42cc22SLv Zheng 		*value = 0;
3801fad8738SBob Moore 		status =
3811fad8738SBob Moore 		    acpi_os_read_pci_configuration(pci_id, pci_register, value,
3821fad8738SBob Moore 						   bit_width);
38395b482a8SLen Brown 		break;
38495b482a8SLen Brown 
38595b482a8SLen Brown 	case ACPI_WRITE:
38695b482a8SLen Brown 
3871fad8738SBob Moore 		status =
3881fad8738SBob Moore 		    acpi_os_write_pci_configuration(pci_id, pci_register,
38995b482a8SLen Brown 						    *value, bit_width);
39095b482a8SLen Brown 		break;
39195b482a8SLen Brown 
39295b482a8SLen Brown 	default:
39395b482a8SLen Brown 
39495b482a8SLen Brown 		status = AE_BAD_PARAMETER;
39595b482a8SLen Brown 		break;
39695b482a8SLen Brown 	}
39795b482a8SLen Brown 
39895b482a8SLen Brown 	return_ACPI_STATUS(status);
39995b482a8SLen Brown }
400bd23fac3SSinan Kaya #endif
40195b482a8SLen Brown 
40295b482a8SLen Brown /*******************************************************************************
40395b482a8SLen Brown  *
40495b482a8SLen Brown  * FUNCTION:    acpi_ex_cmos_space_handler
40595b482a8SLen Brown  *
406ba494beeSBob Moore  * PARAMETERS:  function            - Read or Write operation
407ba494beeSBob Moore  *              address             - Where in the space to read or write
40895b482a8SLen Brown  *              bit_width           - Field width in bits (8, 16, or 32)
409ba494beeSBob Moore  *              value               - Pointer to in or out value
41095b482a8SLen Brown  *              handler_context     - Pointer to Handler's context
41195b482a8SLen Brown  *              region_context      - Pointer to context specific to the
41295b482a8SLen Brown  *                                    accessed region
41395b482a8SLen Brown  *
41495b482a8SLen Brown  * RETURN:      Status
41595b482a8SLen Brown  *
41695b482a8SLen Brown  * DESCRIPTION: Handler for the CMOS address space (Op Region)
41795b482a8SLen Brown  *
41895b482a8SLen Brown  ******************************************************************************/
41995b482a8SLen Brown 
42095b482a8SLen Brown acpi_status
acpi_ex_cmos_space_handler(u32 function,acpi_physical_address address,u32 bit_width,u64 * value,void * handler_context,void * region_context)42195b482a8SLen Brown acpi_ex_cmos_space_handler(u32 function,
42295b482a8SLen Brown 			   acpi_physical_address address,
42395b482a8SLen Brown 			   u32 bit_width,
4245df7e6cbSBob Moore 			   u64 *value,
42595b482a8SLen Brown 			   void *handler_context, void *region_context)
42695b482a8SLen Brown {
42795b482a8SLen Brown 	acpi_status status = AE_OK;
42895b482a8SLen Brown 
42995b482a8SLen Brown 	ACPI_FUNCTION_TRACE(ex_cmos_space_handler);
43095b482a8SLen Brown 
43195b482a8SLen Brown 	return_ACPI_STATUS(status);
43295b482a8SLen Brown }
43395b482a8SLen Brown 
434bd23fac3SSinan Kaya #ifdef ACPI_PCI_CONFIGURED
43595b482a8SLen Brown /*******************************************************************************
43695b482a8SLen Brown  *
43795b482a8SLen Brown  * FUNCTION:    acpi_ex_pci_bar_space_handler
43895b482a8SLen Brown  *
439ba494beeSBob Moore  * PARAMETERS:  function            - Read or Write operation
440ba494beeSBob Moore  *              address             - Where in the space to read or write
44195b482a8SLen Brown  *              bit_width           - Field width in bits (8, 16, or 32)
442ba494beeSBob Moore  *              value               - Pointer to in or out value
44395b482a8SLen Brown  *              handler_context     - Pointer to Handler's context
44495b482a8SLen Brown  *              region_context      - Pointer to context specific to the
44595b482a8SLen Brown  *                                    accessed region
44695b482a8SLen Brown  *
44795b482a8SLen Brown  * RETURN:      Status
44895b482a8SLen Brown  *
44995b482a8SLen Brown  * DESCRIPTION: Handler for the PCI bar_target address space (Op Region)
45095b482a8SLen Brown  *
45195b482a8SLen Brown  ******************************************************************************/
45295b482a8SLen Brown 
45395b482a8SLen Brown acpi_status
acpi_ex_pci_bar_space_handler(u32 function,acpi_physical_address address,u32 bit_width,u64 * value,void * handler_context,void * region_context)45495b482a8SLen Brown acpi_ex_pci_bar_space_handler(u32 function,
45595b482a8SLen Brown 			      acpi_physical_address address,
45695b482a8SLen Brown 			      u32 bit_width,
4575df7e6cbSBob Moore 			      u64 *value,
45895b482a8SLen Brown 			      void *handler_context, void *region_context)
45995b482a8SLen Brown {
46095b482a8SLen Brown 	acpi_status status = AE_OK;
46195b482a8SLen Brown 
46295b482a8SLen Brown 	ACPI_FUNCTION_TRACE(ex_pci_bar_space_handler);
46395b482a8SLen Brown 
46495b482a8SLen Brown 	return_ACPI_STATUS(status);
46595b482a8SLen Brown }
466bd23fac3SSinan Kaya #endif
46795b482a8SLen Brown 
46895b482a8SLen Brown /*******************************************************************************
46995b482a8SLen Brown  *
47095b482a8SLen Brown  * FUNCTION:    acpi_ex_data_table_space_handler
47195b482a8SLen Brown  *
472ba494beeSBob Moore  * PARAMETERS:  function            - Read or Write operation
473ba494beeSBob Moore  *              address             - Where in the space to read or write
47495b482a8SLen Brown  *              bit_width           - Field width in bits (8, 16, or 32)
475ba494beeSBob Moore  *              value               - Pointer to in or out value
47695b482a8SLen Brown  *              handler_context     - Pointer to Handler's context
47795b482a8SLen Brown  *              region_context      - Pointer to context specific to the
47895b482a8SLen Brown  *                                    accessed region
47995b482a8SLen Brown  *
48095b482a8SLen Brown  * RETURN:      Status
48195b482a8SLen Brown  *
48295b482a8SLen Brown  * DESCRIPTION: Handler for the Data Table address space (Op Region)
48395b482a8SLen Brown  *
48495b482a8SLen Brown  ******************************************************************************/
48595b482a8SLen Brown 
48695b482a8SLen Brown acpi_status
acpi_ex_data_table_space_handler(u32 function,acpi_physical_address address,u32 bit_width,u64 * value,void * handler_context,void * region_context)48795b482a8SLen Brown acpi_ex_data_table_space_handler(u32 function,
48895b482a8SLen Brown 				 acpi_physical_address address,
48995b482a8SLen Brown 				 u32 bit_width,
4905df7e6cbSBob Moore 				 u64 *value,
49195b482a8SLen Brown 				 void *handler_context, void *region_context)
49295b482a8SLen Brown {
4939737ff46SPedro Falcato 	struct acpi_data_table_mapping *mapping;
494ca25f92bSJessica Clarke 	char *pointer;
495ca25f92bSJessica Clarke 
49695b482a8SLen Brown 	ACPI_FUNCTION_TRACE(ex_data_table_space_handler);
49795b482a8SLen Brown 
4989737ff46SPedro Falcato 	mapping = (struct acpi_data_table_mapping *) region_context;
499ca25f92bSJessica Clarke 	pointer = ACPI_CAST_PTR(char, mapping->pointer) +
500ca25f92bSJessica Clarke 	    (address - ACPI_PTR_TO_PHYSADDR(mapping->pointer));
501ca25f92bSJessica Clarke 
502c1637e9cSBob Moore 	/*
503c1637e9cSBob Moore 	 * Perform the memory read or write. The bit_width was already
504c1637e9cSBob Moore 	 * validated.
505c1637e9cSBob Moore 	 */
50695b482a8SLen Brown 	switch (function) {
50795b482a8SLen Brown 	case ACPI_READ:
50895b482a8SLen Brown 
509ca25f92bSJessica Clarke 		memcpy(ACPI_CAST_PTR(char, value), pointer,
510ca25f92bSJessica Clarke 		       ACPI_DIV_8(bit_width));
51195b482a8SLen Brown 		break;
51295b482a8SLen Brown 
51395b482a8SLen Brown 	case ACPI_WRITE:
514c1637e9cSBob Moore 
515ca25f92bSJessica Clarke 		memcpy(pointer, ACPI_CAST_PTR(char, value),
516ca25f92bSJessica Clarke 		       ACPI_DIV_8(bit_width));
517c1637e9cSBob Moore 		break;
518c1637e9cSBob Moore 
51995b482a8SLen Brown 	default:
52095b482a8SLen Brown 
521c1637e9cSBob Moore 		return_ACPI_STATUS(AE_BAD_PARAMETER);
52295b482a8SLen Brown 	}
52395b482a8SLen Brown 
52495b482a8SLen Brown 	return_ACPI_STATUS(AE_OK);
52595b482a8SLen Brown }
526