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