xref: /OK3568_Linux_fs/kernel/drivers/acpi/acpica/exregion.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
2*4882a593Smuzhiyun /******************************************************************************
3*4882a593Smuzhiyun  *
4*4882a593Smuzhiyun  * Module Name: exregion - ACPI default op_region (address space) handlers
5*4882a593Smuzhiyun  *
6*4882a593Smuzhiyun  * Copyright (C) 2000 - 2020, Intel Corp.
7*4882a593Smuzhiyun  *
8*4882a593Smuzhiyun  *****************************************************************************/
9*4882a593Smuzhiyun 
10*4882a593Smuzhiyun #include <acpi/acpi.h>
11*4882a593Smuzhiyun #include "accommon.h"
12*4882a593Smuzhiyun #include "acinterp.h"
13*4882a593Smuzhiyun 
14*4882a593Smuzhiyun #define _COMPONENT          ACPI_EXECUTER
15*4882a593Smuzhiyun ACPI_MODULE_NAME("exregion")
16*4882a593Smuzhiyun 
17*4882a593Smuzhiyun /*******************************************************************************
18*4882a593Smuzhiyun  *
19*4882a593Smuzhiyun  * FUNCTION:    acpi_ex_system_memory_space_handler
20*4882a593Smuzhiyun  *
21*4882a593Smuzhiyun  * PARAMETERS:  function            - Read or Write operation
22*4882a593Smuzhiyun  *              address             - Where in the space to read or write
23*4882a593Smuzhiyun  *              bit_width           - Field width in bits (8, 16, or 32)
24*4882a593Smuzhiyun  *              value               - Pointer to in or out value
25*4882a593Smuzhiyun  *              handler_context     - Pointer to Handler's context
26*4882a593Smuzhiyun  *              region_context      - Pointer to context specific to the
27*4882a593Smuzhiyun  *                                    accessed region
28*4882a593Smuzhiyun  *
29*4882a593Smuzhiyun  * RETURN:      Status
30*4882a593Smuzhiyun  *
31*4882a593Smuzhiyun  * DESCRIPTION: Handler for the System Memory address space (Op Region)
32*4882a593Smuzhiyun  *
33*4882a593Smuzhiyun  ******************************************************************************/
34*4882a593Smuzhiyun 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)35*4882a593Smuzhiyun acpi_ex_system_memory_space_handler(u32 function,
36*4882a593Smuzhiyun 				    acpi_physical_address address,
37*4882a593Smuzhiyun 				    u32 bit_width,
38*4882a593Smuzhiyun 				    u64 *value,
39*4882a593Smuzhiyun 				    void *handler_context, void *region_context)
40*4882a593Smuzhiyun {
41*4882a593Smuzhiyun 	acpi_status status = AE_OK;
42*4882a593Smuzhiyun 	void *logical_addr_ptr = NULL;
43*4882a593Smuzhiyun 	struct acpi_mem_space_context *mem_info = region_context;
44*4882a593Smuzhiyun 	struct acpi_mem_mapping *mm = mem_info->cur_mm;
45*4882a593Smuzhiyun 	u32 length;
46*4882a593Smuzhiyun 	acpi_size map_length;
47*4882a593Smuzhiyun 	acpi_size page_boundary_map_length;
48*4882a593Smuzhiyun #ifdef ACPI_MISALIGNMENT_NOT_SUPPORTED
49*4882a593Smuzhiyun 	u32 remainder;
50*4882a593Smuzhiyun #endif
51*4882a593Smuzhiyun 
52*4882a593Smuzhiyun 	ACPI_FUNCTION_TRACE(ex_system_memory_space_handler);
53*4882a593Smuzhiyun 
54*4882a593Smuzhiyun 	/* Validate and translate the bit width */
55*4882a593Smuzhiyun 
56*4882a593Smuzhiyun 	switch (bit_width) {
57*4882a593Smuzhiyun 	case 8:
58*4882a593Smuzhiyun 
59*4882a593Smuzhiyun 		length = 1;
60*4882a593Smuzhiyun 		break;
61*4882a593Smuzhiyun 
62*4882a593Smuzhiyun 	case 16:
63*4882a593Smuzhiyun 
64*4882a593Smuzhiyun 		length = 2;
65*4882a593Smuzhiyun 		break;
66*4882a593Smuzhiyun 
67*4882a593Smuzhiyun 	case 32:
68*4882a593Smuzhiyun 
69*4882a593Smuzhiyun 		length = 4;
70*4882a593Smuzhiyun 		break;
71*4882a593Smuzhiyun 
72*4882a593Smuzhiyun 	case 64:
73*4882a593Smuzhiyun 
74*4882a593Smuzhiyun 		length = 8;
75*4882a593Smuzhiyun 		break;
76*4882a593Smuzhiyun 
77*4882a593Smuzhiyun 	default:
78*4882a593Smuzhiyun 
79*4882a593Smuzhiyun 		ACPI_ERROR((AE_INFO, "Invalid SystemMemory width %u",
80*4882a593Smuzhiyun 			    bit_width));
81*4882a593Smuzhiyun 		return_ACPI_STATUS(AE_AML_OPERAND_VALUE);
82*4882a593Smuzhiyun 	}
83*4882a593Smuzhiyun 
84*4882a593Smuzhiyun #ifdef ACPI_MISALIGNMENT_NOT_SUPPORTED
85*4882a593Smuzhiyun 	/*
86*4882a593Smuzhiyun 	 * Hardware does not support non-aligned data transfers, we must verify
87*4882a593Smuzhiyun 	 * the request.
88*4882a593Smuzhiyun 	 */
89*4882a593Smuzhiyun 	(void)acpi_ut_short_divide((u64) address, length, NULL, &remainder);
90*4882a593Smuzhiyun 	if (remainder != 0) {
91*4882a593Smuzhiyun 		return_ACPI_STATUS(AE_AML_ALIGNMENT);
92*4882a593Smuzhiyun 	}
93*4882a593Smuzhiyun #endif
94*4882a593Smuzhiyun 
95*4882a593Smuzhiyun 	/*
96*4882a593Smuzhiyun 	 * Does the request fit into the cached memory mapping?
97*4882a593Smuzhiyun 	 * Is 1) Address below the current mapping? OR
98*4882a593Smuzhiyun 	 *    2) Address beyond the current mapping?
99*4882a593Smuzhiyun 	 */
100*4882a593Smuzhiyun 	if (!mm || (address < mm->physical_address) ||
101*4882a593Smuzhiyun 	    ((u64) address + length > (u64) mm->physical_address + mm->length)) {
102*4882a593Smuzhiyun 		/*
103*4882a593Smuzhiyun 		 * The request cannot be resolved by the current memory mapping.
104*4882a593Smuzhiyun 		 *
105*4882a593Smuzhiyun 		 * Look for an existing saved mapping covering the address range
106*4882a593Smuzhiyun 		 * at hand.  If found, save it as the current one and carry out
107*4882a593Smuzhiyun 		 * the access.
108*4882a593Smuzhiyun 		 */
109*4882a593Smuzhiyun 		for (mm = mem_info->first_mm; mm; mm = mm->next_mm) {
110*4882a593Smuzhiyun 			if (mm == mem_info->cur_mm)
111*4882a593Smuzhiyun 				continue;
112*4882a593Smuzhiyun 
113*4882a593Smuzhiyun 			if (address < mm->physical_address)
114*4882a593Smuzhiyun 				continue;
115*4882a593Smuzhiyun 
116*4882a593Smuzhiyun 			if ((u64) address + length >
117*4882a593Smuzhiyun 					(u64) mm->physical_address + mm->length)
118*4882a593Smuzhiyun 				continue;
119*4882a593Smuzhiyun 
120*4882a593Smuzhiyun 			mem_info->cur_mm = mm;
121*4882a593Smuzhiyun 			goto access;
122*4882a593Smuzhiyun 		}
123*4882a593Smuzhiyun 
124*4882a593Smuzhiyun 		/* Create a new mappings list entry */
125*4882a593Smuzhiyun 		mm = ACPI_ALLOCATE_ZEROED(sizeof(*mm));
126*4882a593Smuzhiyun 		if (!mm) {
127*4882a593Smuzhiyun 			ACPI_ERROR((AE_INFO,
128*4882a593Smuzhiyun 				    "Unable to save memory mapping at 0x%8.8X%8.8X, size %u",
129*4882a593Smuzhiyun 				    ACPI_FORMAT_UINT64(address), length));
130*4882a593Smuzhiyun 			return_ACPI_STATUS(AE_NO_MEMORY);
131*4882a593Smuzhiyun 		}
132*4882a593Smuzhiyun 
133*4882a593Smuzhiyun 		/*
134*4882a593Smuzhiyun 		 * October 2009: Attempt to map from the requested address to the
135*4882a593Smuzhiyun 		 * end of the region. However, we will never map more than one
136*4882a593Smuzhiyun 		 * page, nor will we cross a page boundary.
137*4882a593Smuzhiyun 		 */
138*4882a593Smuzhiyun 		map_length = (acpi_size)
139*4882a593Smuzhiyun 		    ((mem_info->address + mem_info->length) - address);
140*4882a593Smuzhiyun 
141*4882a593Smuzhiyun 		/*
142*4882a593Smuzhiyun 		 * If mapping the entire remaining portion of the region will cross
143*4882a593Smuzhiyun 		 * a page boundary, just map up to the page boundary, do not cross.
144*4882a593Smuzhiyun 		 * On some systems, crossing a page boundary while mapping regions
145*4882a593Smuzhiyun 		 * can cause warnings if the pages have different attributes
146*4882a593Smuzhiyun 		 * due to resource management.
147*4882a593Smuzhiyun 		 *
148*4882a593Smuzhiyun 		 * This has the added benefit of constraining a single mapping to
149*4882a593Smuzhiyun 		 * one page, which is similar to the original code that used a 4k
150*4882a593Smuzhiyun 		 * maximum window.
151*4882a593Smuzhiyun 		 */
152*4882a593Smuzhiyun 		page_boundary_map_length = (acpi_size)
153*4882a593Smuzhiyun 		    (ACPI_ROUND_UP(address, ACPI_DEFAULT_PAGE_SIZE) - address);
154*4882a593Smuzhiyun 		if (page_boundary_map_length == 0) {
155*4882a593Smuzhiyun 			page_boundary_map_length = ACPI_DEFAULT_PAGE_SIZE;
156*4882a593Smuzhiyun 		}
157*4882a593Smuzhiyun 
158*4882a593Smuzhiyun 		if (map_length > page_boundary_map_length) {
159*4882a593Smuzhiyun 			map_length = page_boundary_map_length;
160*4882a593Smuzhiyun 		}
161*4882a593Smuzhiyun 
162*4882a593Smuzhiyun 		/* Create a new mapping starting at the address given */
163*4882a593Smuzhiyun 
164*4882a593Smuzhiyun 		logical_addr_ptr = acpi_os_map_memory(address, map_length);
165*4882a593Smuzhiyun 		if (!logical_addr_ptr) {
166*4882a593Smuzhiyun 			ACPI_ERROR((AE_INFO,
167*4882a593Smuzhiyun 				    "Could not map memory at 0x%8.8X%8.8X, size %u",
168*4882a593Smuzhiyun 				    ACPI_FORMAT_UINT64(address),
169*4882a593Smuzhiyun 				    (u32)map_length));
170*4882a593Smuzhiyun 			ACPI_FREE(mm);
171*4882a593Smuzhiyun 			return_ACPI_STATUS(AE_NO_MEMORY);
172*4882a593Smuzhiyun 		}
173*4882a593Smuzhiyun 
174*4882a593Smuzhiyun 		/* Save the physical address and mapping size */
175*4882a593Smuzhiyun 
176*4882a593Smuzhiyun 		mm->logical_address = logical_addr_ptr;
177*4882a593Smuzhiyun 		mm->physical_address = address;
178*4882a593Smuzhiyun 		mm->length = map_length;
179*4882a593Smuzhiyun 
180*4882a593Smuzhiyun 		/*
181*4882a593Smuzhiyun 		 * Add the new entry to the mappigs list and save it as the
182*4882a593Smuzhiyun 		 * current mapping.
183*4882a593Smuzhiyun 		 */
184*4882a593Smuzhiyun 		mm->next_mm = mem_info->first_mm;
185*4882a593Smuzhiyun 		mem_info->first_mm = mm;
186*4882a593Smuzhiyun 
187*4882a593Smuzhiyun 		mem_info->cur_mm = mm;
188*4882a593Smuzhiyun 	}
189*4882a593Smuzhiyun 
190*4882a593Smuzhiyun access:
191*4882a593Smuzhiyun 	/*
192*4882a593Smuzhiyun 	 * Generate a logical pointer corresponding to the address we want to
193*4882a593Smuzhiyun 	 * access
194*4882a593Smuzhiyun 	 */
195*4882a593Smuzhiyun 	logical_addr_ptr = mm->logical_address +
196*4882a593Smuzhiyun 		((u64) address - (u64) mm->physical_address);
197*4882a593Smuzhiyun 
198*4882a593Smuzhiyun 	ACPI_DEBUG_PRINT((ACPI_DB_INFO,
199*4882a593Smuzhiyun 			  "System-Memory (width %u) R/W %u Address=%8.8X%8.8X\n",
200*4882a593Smuzhiyun 			  bit_width, function, ACPI_FORMAT_UINT64(address)));
201*4882a593Smuzhiyun 
202*4882a593Smuzhiyun 	/*
203*4882a593Smuzhiyun 	 * Perform the memory read or write
204*4882a593Smuzhiyun 	 *
205*4882a593Smuzhiyun 	 * Note: For machines that do not support non-aligned transfers, the target
206*4882a593Smuzhiyun 	 * address was checked for alignment above. We do not attempt to break the
207*4882a593Smuzhiyun 	 * transfer up into smaller (byte-size) chunks because the AML specifically
208*4882a593Smuzhiyun 	 * asked for a transfer width that the hardware may require.
209*4882a593Smuzhiyun 	 */
210*4882a593Smuzhiyun 	switch (function) {
211*4882a593Smuzhiyun 	case ACPI_READ:
212*4882a593Smuzhiyun 
213*4882a593Smuzhiyun 		*value = 0;
214*4882a593Smuzhiyun 		switch (bit_width) {
215*4882a593Smuzhiyun 		case 8:
216*4882a593Smuzhiyun 
217*4882a593Smuzhiyun 			*value = (u64)ACPI_GET8(logical_addr_ptr);
218*4882a593Smuzhiyun 			break;
219*4882a593Smuzhiyun 
220*4882a593Smuzhiyun 		case 16:
221*4882a593Smuzhiyun 
222*4882a593Smuzhiyun 			*value = (u64)ACPI_GET16(logical_addr_ptr);
223*4882a593Smuzhiyun 			break;
224*4882a593Smuzhiyun 
225*4882a593Smuzhiyun 		case 32:
226*4882a593Smuzhiyun 
227*4882a593Smuzhiyun 			*value = (u64)ACPI_GET32(logical_addr_ptr);
228*4882a593Smuzhiyun 			break;
229*4882a593Smuzhiyun 
230*4882a593Smuzhiyun 		case 64:
231*4882a593Smuzhiyun 
232*4882a593Smuzhiyun 			*value = (u64)ACPI_GET64(logical_addr_ptr);
233*4882a593Smuzhiyun 			break;
234*4882a593Smuzhiyun 
235*4882a593Smuzhiyun 		default:
236*4882a593Smuzhiyun 
237*4882a593Smuzhiyun 			/* bit_width was already validated */
238*4882a593Smuzhiyun 
239*4882a593Smuzhiyun 			break;
240*4882a593Smuzhiyun 		}
241*4882a593Smuzhiyun 		break;
242*4882a593Smuzhiyun 
243*4882a593Smuzhiyun 	case ACPI_WRITE:
244*4882a593Smuzhiyun 
245*4882a593Smuzhiyun 		switch (bit_width) {
246*4882a593Smuzhiyun 		case 8:
247*4882a593Smuzhiyun 
248*4882a593Smuzhiyun 			ACPI_SET8(logical_addr_ptr, *value);
249*4882a593Smuzhiyun 			break;
250*4882a593Smuzhiyun 
251*4882a593Smuzhiyun 		case 16:
252*4882a593Smuzhiyun 
253*4882a593Smuzhiyun 			ACPI_SET16(logical_addr_ptr, *value);
254*4882a593Smuzhiyun 			break;
255*4882a593Smuzhiyun 
256*4882a593Smuzhiyun 		case 32:
257*4882a593Smuzhiyun 
258*4882a593Smuzhiyun 			ACPI_SET32(logical_addr_ptr, *value);
259*4882a593Smuzhiyun 			break;
260*4882a593Smuzhiyun 
261*4882a593Smuzhiyun 		case 64:
262*4882a593Smuzhiyun 
263*4882a593Smuzhiyun 			ACPI_SET64(logical_addr_ptr, *value);
264*4882a593Smuzhiyun 			break;
265*4882a593Smuzhiyun 
266*4882a593Smuzhiyun 		default:
267*4882a593Smuzhiyun 
268*4882a593Smuzhiyun 			/* bit_width was already validated */
269*4882a593Smuzhiyun 
270*4882a593Smuzhiyun 			break;
271*4882a593Smuzhiyun 		}
272*4882a593Smuzhiyun 		break;
273*4882a593Smuzhiyun 
274*4882a593Smuzhiyun 	default:
275*4882a593Smuzhiyun 
276*4882a593Smuzhiyun 		status = AE_BAD_PARAMETER;
277*4882a593Smuzhiyun 		break;
278*4882a593Smuzhiyun 	}
279*4882a593Smuzhiyun 
280*4882a593Smuzhiyun 	return_ACPI_STATUS(status);
281*4882a593Smuzhiyun }
282*4882a593Smuzhiyun 
283*4882a593Smuzhiyun /*******************************************************************************
284*4882a593Smuzhiyun  *
285*4882a593Smuzhiyun  * FUNCTION:    acpi_ex_system_io_space_handler
286*4882a593Smuzhiyun  *
287*4882a593Smuzhiyun  * PARAMETERS:  function            - Read or Write operation
288*4882a593Smuzhiyun  *              address             - Where in the space to read or write
289*4882a593Smuzhiyun  *              bit_width           - Field width in bits (8, 16, or 32)
290*4882a593Smuzhiyun  *              value               - Pointer to in or out value
291*4882a593Smuzhiyun  *              handler_context     - Pointer to Handler's context
292*4882a593Smuzhiyun  *              region_context      - Pointer to context specific to the
293*4882a593Smuzhiyun  *                                    accessed region
294*4882a593Smuzhiyun  *
295*4882a593Smuzhiyun  * RETURN:      Status
296*4882a593Smuzhiyun  *
297*4882a593Smuzhiyun  * DESCRIPTION: Handler for the System IO address space (Op Region)
298*4882a593Smuzhiyun  *
299*4882a593Smuzhiyun  ******************************************************************************/
300*4882a593Smuzhiyun 
301*4882a593Smuzhiyun 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)302*4882a593Smuzhiyun acpi_ex_system_io_space_handler(u32 function,
303*4882a593Smuzhiyun 				acpi_physical_address address,
304*4882a593Smuzhiyun 				u32 bit_width,
305*4882a593Smuzhiyun 				u64 *value,
306*4882a593Smuzhiyun 				void *handler_context, void *region_context)
307*4882a593Smuzhiyun {
308*4882a593Smuzhiyun 	acpi_status status = AE_OK;
309*4882a593Smuzhiyun 	u32 value32;
310*4882a593Smuzhiyun 
311*4882a593Smuzhiyun 	ACPI_FUNCTION_TRACE(ex_system_io_space_handler);
312*4882a593Smuzhiyun 
313*4882a593Smuzhiyun 	ACPI_DEBUG_PRINT((ACPI_DB_INFO,
314*4882a593Smuzhiyun 			  "System-IO (width %u) R/W %u Address=%8.8X%8.8X\n",
315*4882a593Smuzhiyun 			  bit_width, function, ACPI_FORMAT_UINT64(address)));
316*4882a593Smuzhiyun 
317*4882a593Smuzhiyun 	/* Decode the function parameter */
318*4882a593Smuzhiyun 
319*4882a593Smuzhiyun 	switch (function) {
320*4882a593Smuzhiyun 	case ACPI_READ:
321*4882a593Smuzhiyun 
322*4882a593Smuzhiyun 		status = acpi_hw_read_port((acpi_io_address)address,
323*4882a593Smuzhiyun 					   &value32, bit_width);
324*4882a593Smuzhiyun 		*value = value32;
325*4882a593Smuzhiyun 		break;
326*4882a593Smuzhiyun 
327*4882a593Smuzhiyun 	case ACPI_WRITE:
328*4882a593Smuzhiyun 
329*4882a593Smuzhiyun 		status = acpi_hw_write_port((acpi_io_address)address,
330*4882a593Smuzhiyun 					    (u32)*value, bit_width);
331*4882a593Smuzhiyun 		break;
332*4882a593Smuzhiyun 
333*4882a593Smuzhiyun 	default:
334*4882a593Smuzhiyun 
335*4882a593Smuzhiyun 		status = AE_BAD_PARAMETER;
336*4882a593Smuzhiyun 		break;
337*4882a593Smuzhiyun 	}
338*4882a593Smuzhiyun 
339*4882a593Smuzhiyun 	return_ACPI_STATUS(status);
340*4882a593Smuzhiyun }
341*4882a593Smuzhiyun 
342*4882a593Smuzhiyun #ifdef ACPI_PCI_CONFIGURED
343*4882a593Smuzhiyun /*******************************************************************************
344*4882a593Smuzhiyun  *
345*4882a593Smuzhiyun  * FUNCTION:    acpi_ex_pci_config_space_handler
346*4882a593Smuzhiyun  *
347*4882a593Smuzhiyun  * PARAMETERS:  function            - Read or Write operation
348*4882a593Smuzhiyun  *              address             - Where in the space to read or write
349*4882a593Smuzhiyun  *              bit_width           - Field width in bits (8, 16, or 32)
350*4882a593Smuzhiyun  *              value               - Pointer to in or out value
351*4882a593Smuzhiyun  *              handler_context     - Pointer to Handler's context
352*4882a593Smuzhiyun  *              region_context      - Pointer to context specific to the
353*4882a593Smuzhiyun  *                                    accessed region
354*4882a593Smuzhiyun  *
355*4882a593Smuzhiyun  * RETURN:      Status
356*4882a593Smuzhiyun  *
357*4882a593Smuzhiyun  * DESCRIPTION: Handler for the PCI Config address space (Op Region)
358*4882a593Smuzhiyun  *
359*4882a593Smuzhiyun  ******************************************************************************/
360*4882a593Smuzhiyun 
361*4882a593Smuzhiyun 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)362*4882a593Smuzhiyun acpi_ex_pci_config_space_handler(u32 function,
363*4882a593Smuzhiyun 				 acpi_physical_address address,
364*4882a593Smuzhiyun 				 u32 bit_width,
365*4882a593Smuzhiyun 				 u64 *value,
366*4882a593Smuzhiyun 				 void *handler_context, void *region_context)
367*4882a593Smuzhiyun {
368*4882a593Smuzhiyun 	acpi_status status = AE_OK;
369*4882a593Smuzhiyun 	struct acpi_pci_id *pci_id;
370*4882a593Smuzhiyun 	u16 pci_register;
371*4882a593Smuzhiyun 
372*4882a593Smuzhiyun 	ACPI_FUNCTION_TRACE(ex_pci_config_space_handler);
373*4882a593Smuzhiyun 
374*4882a593Smuzhiyun 	/*
375*4882a593Smuzhiyun 	 *  The arguments to acpi_os(Read|Write)pci_configuration are:
376*4882a593Smuzhiyun 	 *
377*4882a593Smuzhiyun 	 *  pci_segment is the PCI bus segment range 0-31
378*4882a593Smuzhiyun 	 *  pci_bus     is the PCI bus number range 0-255
379*4882a593Smuzhiyun 	 *  pci_device  is the PCI device number range 0-31
380*4882a593Smuzhiyun 	 *  pci_function is the PCI device function number
381*4882a593Smuzhiyun 	 *  pci_register is the Config space register range 0-255 bytes
382*4882a593Smuzhiyun 	 *
383*4882a593Smuzhiyun 	 *  value - input value for write, output address for read
384*4882a593Smuzhiyun 	 *
385*4882a593Smuzhiyun 	 */
386*4882a593Smuzhiyun 	pci_id = (struct acpi_pci_id *)region_context;
387*4882a593Smuzhiyun 	pci_register = (u16) (u32) address;
388*4882a593Smuzhiyun 
389*4882a593Smuzhiyun 	ACPI_DEBUG_PRINT((ACPI_DB_INFO,
390*4882a593Smuzhiyun 			  "Pci-Config %u (%u) Seg(%04x) Bus(%04x) "
391*4882a593Smuzhiyun 			  "Dev(%04x) Func(%04x) Reg(%04x)\n",
392*4882a593Smuzhiyun 			  function, bit_width, pci_id->segment, pci_id->bus,
393*4882a593Smuzhiyun 			  pci_id->device, pci_id->function, pci_register));
394*4882a593Smuzhiyun 
395*4882a593Smuzhiyun 	switch (function) {
396*4882a593Smuzhiyun 	case ACPI_READ:
397*4882a593Smuzhiyun 
398*4882a593Smuzhiyun 		*value = 0;
399*4882a593Smuzhiyun 		status =
400*4882a593Smuzhiyun 		    acpi_os_read_pci_configuration(pci_id, pci_register, value,
401*4882a593Smuzhiyun 						   bit_width);
402*4882a593Smuzhiyun 		break;
403*4882a593Smuzhiyun 
404*4882a593Smuzhiyun 	case ACPI_WRITE:
405*4882a593Smuzhiyun 
406*4882a593Smuzhiyun 		status =
407*4882a593Smuzhiyun 		    acpi_os_write_pci_configuration(pci_id, pci_register,
408*4882a593Smuzhiyun 						    *value, bit_width);
409*4882a593Smuzhiyun 		break;
410*4882a593Smuzhiyun 
411*4882a593Smuzhiyun 	default:
412*4882a593Smuzhiyun 
413*4882a593Smuzhiyun 		status = AE_BAD_PARAMETER;
414*4882a593Smuzhiyun 		break;
415*4882a593Smuzhiyun 	}
416*4882a593Smuzhiyun 
417*4882a593Smuzhiyun 	return_ACPI_STATUS(status);
418*4882a593Smuzhiyun }
419*4882a593Smuzhiyun #endif
420*4882a593Smuzhiyun 
421*4882a593Smuzhiyun /*******************************************************************************
422*4882a593Smuzhiyun  *
423*4882a593Smuzhiyun  * FUNCTION:    acpi_ex_cmos_space_handler
424*4882a593Smuzhiyun  *
425*4882a593Smuzhiyun  * PARAMETERS:  function            - Read or Write operation
426*4882a593Smuzhiyun  *              address             - Where in the space to read or write
427*4882a593Smuzhiyun  *              bit_width           - Field width in bits (8, 16, or 32)
428*4882a593Smuzhiyun  *              value               - Pointer to in or out value
429*4882a593Smuzhiyun  *              handler_context     - Pointer to Handler's context
430*4882a593Smuzhiyun  *              region_context      - Pointer to context specific to the
431*4882a593Smuzhiyun  *                                    accessed region
432*4882a593Smuzhiyun  *
433*4882a593Smuzhiyun  * RETURN:      Status
434*4882a593Smuzhiyun  *
435*4882a593Smuzhiyun  * DESCRIPTION: Handler for the CMOS address space (Op Region)
436*4882a593Smuzhiyun  *
437*4882a593Smuzhiyun  ******************************************************************************/
438*4882a593Smuzhiyun 
439*4882a593Smuzhiyun acpi_status
acpi_ex_cmos_space_handler(u32 function,acpi_physical_address address,u32 bit_width,u64 * value,void * handler_context,void * region_context)440*4882a593Smuzhiyun acpi_ex_cmos_space_handler(u32 function,
441*4882a593Smuzhiyun 			   acpi_physical_address address,
442*4882a593Smuzhiyun 			   u32 bit_width,
443*4882a593Smuzhiyun 			   u64 *value,
444*4882a593Smuzhiyun 			   void *handler_context, void *region_context)
445*4882a593Smuzhiyun {
446*4882a593Smuzhiyun 	acpi_status status = AE_OK;
447*4882a593Smuzhiyun 
448*4882a593Smuzhiyun 	ACPI_FUNCTION_TRACE(ex_cmos_space_handler);
449*4882a593Smuzhiyun 
450*4882a593Smuzhiyun 	return_ACPI_STATUS(status);
451*4882a593Smuzhiyun }
452*4882a593Smuzhiyun 
453*4882a593Smuzhiyun #ifdef ACPI_PCI_CONFIGURED
454*4882a593Smuzhiyun /*******************************************************************************
455*4882a593Smuzhiyun  *
456*4882a593Smuzhiyun  * FUNCTION:    acpi_ex_pci_bar_space_handler
457*4882a593Smuzhiyun  *
458*4882a593Smuzhiyun  * PARAMETERS:  function            - Read or Write operation
459*4882a593Smuzhiyun  *              address             - Where in the space to read or write
460*4882a593Smuzhiyun  *              bit_width           - Field width in bits (8, 16, or 32)
461*4882a593Smuzhiyun  *              value               - Pointer to in or out value
462*4882a593Smuzhiyun  *              handler_context     - Pointer to Handler's context
463*4882a593Smuzhiyun  *              region_context      - Pointer to context specific to the
464*4882a593Smuzhiyun  *                                    accessed region
465*4882a593Smuzhiyun  *
466*4882a593Smuzhiyun  * RETURN:      Status
467*4882a593Smuzhiyun  *
468*4882a593Smuzhiyun  * DESCRIPTION: Handler for the PCI bar_target address space (Op Region)
469*4882a593Smuzhiyun  *
470*4882a593Smuzhiyun  ******************************************************************************/
471*4882a593Smuzhiyun 
472*4882a593Smuzhiyun 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)473*4882a593Smuzhiyun acpi_ex_pci_bar_space_handler(u32 function,
474*4882a593Smuzhiyun 			      acpi_physical_address address,
475*4882a593Smuzhiyun 			      u32 bit_width,
476*4882a593Smuzhiyun 			      u64 *value,
477*4882a593Smuzhiyun 			      void *handler_context, void *region_context)
478*4882a593Smuzhiyun {
479*4882a593Smuzhiyun 	acpi_status status = AE_OK;
480*4882a593Smuzhiyun 
481*4882a593Smuzhiyun 	ACPI_FUNCTION_TRACE(ex_pci_bar_space_handler);
482*4882a593Smuzhiyun 
483*4882a593Smuzhiyun 	return_ACPI_STATUS(status);
484*4882a593Smuzhiyun }
485*4882a593Smuzhiyun #endif
486*4882a593Smuzhiyun 
487*4882a593Smuzhiyun /*******************************************************************************
488*4882a593Smuzhiyun  *
489*4882a593Smuzhiyun  * FUNCTION:    acpi_ex_data_table_space_handler
490*4882a593Smuzhiyun  *
491*4882a593Smuzhiyun  * PARAMETERS:  function            - Read or Write operation
492*4882a593Smuzhiyun  *              address             - Where in the space to read or write
493*4882a593Smuzhiyun  *              bit_width           - Field width in bits (8, 16, or 32)
494*4882a593Smuzhiyun  *              value               - Pointer to in or out value
495*4882a593Smuzhiyun  *              handler_context     - Pointer to Handler's context
496*4882a593Smuzhiyun  *              region_context      - Pointer to context specific to the
497*4882a593Smuzhiyun  *                                    accessed region
498*4882a593Smuzhiyun  *
499*4882a593Smuzhiyun  * RETURN:      Status
500*4882a593Smuzhiyun  *
501*4882a593Smuzhiyun  * DESCRIPTION: Handler for the Data Table address space (Op Region)
502*4882a593Smuzhiyun  *
503*4882a593Smuzhiyun  ******************************************************************************/
504*4882a593Smuzhiyun 
505*4882a593Smuzhiyun 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)506*4882a593Smuzhiyun acpi_ex_data_table_space_handler(u32 function,
507*4882a593Smuzhiyun 				 acpi_physical_address address,
508*4882a593Smuzhiyun 				 u32 bit_width,
509*4882a593Smuzhiyun 				 u64 *value,
510*4882a593Smuzhiyun 				 void *handler_context, void *region_context)
511*4882a593Smuzhiyun {
512*4882a593Smuzhiyun 	ACPI_FUNCTION_TRACE(ex_data_table_space_handler);
513*4882a593Smuzhiyun 
514*4882a593Smuzhiyun 	/*
515*4882a593Smuzhiyun 	 * Perform the memory read or write. The bit_width was already
516*4882a593Smuzhiyun 	 * validated.
517*4882a593Smuzhiyun 	 */
518*4882a593Smuzhiyun 	switch (function) {
519*4882a593Smuzhiyun 	case ACPI_READ:
520*4882a593Smuzhiyun 
521*4882a593Smuzhiyun 		memcpy(ACPI_CAST_PTR(char, value),
522*4882a593Smuzhiyun 		       ACPI_PHYSADDR_TO_PTR(address), ACPI_DIV_8(bit_width));
523*4882a593Smuzhiyun 		break;
524*4882a593Smuzhiyun 
525*4882a593Smuzhiyun 	case ACPI_WRITE:
526*4882a593Smuzhiyun 
527*4882a593Smuzhiyun 		memcpy(ACPI_PHYSADDR_TO_PTR(address),
528*4882a593Smuzhiyun 		       ACPI_CAST_PTR(char, value), ACPI_DIV_8(bit_width));
529*4882a593Smuzhiyun 		break;
530*4882a593Smuzhiyun 
531*4882a593Smuzhiyun 	default:
532*4882a593Smuzhiyun 
533*4882a593Smuzhiyun 		return_ACPI_STATUS(AE_BAD_PARAMETER);
534*4882a593Smuzhiyun 	}
535*4882a593Smuzhiyun 
536*4882a593Smuzhiyun 	return_ACPI_STATUS(AE_OK);
537*4882a593Smuzhiyun }
538