Merge ../linux-2.6/
[linux-2.6] / drivers / acpi / executer / exregion.c
1
2 /******************************************************************************
3  *
4  * Module Name: exregion - ACPI default op_region (address space) handlers
5  *
6  *****************************************************************************/
7
8 /*
9  * Copyright (C) 2000 - 2005, R. Byron Moore
10  * All rights reserved.
11  *
12  * Redistribution and use in source and binary forms, with or without
13  * modification, are permitted provided that the following conditions
14  * are met:
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.
26  *
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.
30  *
31  * NO WARRANTY
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.
43  */
44
45
46 #include <acpi/acpi.h>
47 #include <acpi/acinterp.h>
48
49
50 #define _COMPONENT          ACPI_EXECUTER
51          ACPI_MODULE_NAME    ("exregion")
52
53
54 /*******************************************************************************
55  *
56  * FUNCTION:    acpi_ex_system_memory_space_handler
57  *
58  * PARAMETERS:  Function            - Read or Write operation
59  *              Address             - Where in the space to read or write
60  *              bit_width           - Field width in bits (8, 16, or 32)
61  *              Value               - Pointer to in or out value
62  *              handler_context     - Pointer to Handler's context
63  *              region_context      - Pointer to context specific to the
64  *                                    accessed region
65  *
66  * RETURN:      Status
67  *
68  * DESCRIPTION: Handler for the System Memory address space (Op Region)
69  *
70  ******************************************************************************/
71
72 acpi_status
73 acpi_ex_system_memory_space_handler (
74         u32                             function,
75         acpi_physical_address           address,
76         u32                             bit_width,
77         acpi_integer                    *value,
78         void                            *handler_context,
79         void                            *region_context)
80 {
81         acpi_status                     status = AE_OK;
82         void                            *logical_addr_ptr = NULL;
83         struct acpi_mem_space_context   *mem_info = region_context;
84         u32                             length;
85         acpi_size                       window_size;
86 #ifndef ACPI_MISALIGNED_TRANSFERS
87         u32                             remainder;
88 #endif
89
90         ACPI_FUNCTION_TRACE ("ex_system_memory_space_handler");
91
92
93         /* Validate and translate the bit width */
94
95         switch (bit_width) {
96         case 8:
97                 length = 1;
98                 break;
99
100         case 16:
101                 length = 2;
102                 break;
103
104         case 32:
105                 length = 4;
106                 break;
107
108         case 64:
109                 length = 8;
110                 break;
111
112         default:
113                 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Invalid system_memory width %d\n",
114                         bit_width));
115                 return_ACPI_STATUS (AE_AML_OPERAND_VALUE);
116         }
117
118 #ifndef ACPI_MISALIGNED_TRANSFERS
119         /*
120          * Hardware does not support non-aligned data transfers, we must verify
121          * the request.
122          */
123         (void) acpi_ut_short_divide ((acpi_integer) address, length, NULL, &remainder);
124         if (remainder != 0) {
125                 return_ACPI_STATUS (AE_AML_ALIGNMENT);
126         }
127 #endif
128
129         /*
130          * Does the request fit into the cached memory mapping?
131          * Is 1) Address below the current mapping? OR
132          *    2) Address beyond the current mapping?
133          */
134         if ((address < mem_info->mapped_physical_address) ||
135                 (((acpi_integer) address + length) >
136                         ((acpi_integer)
137                         mem_info->mapped_physical_address + mem_info->mapped_length))) {
138                 /*
139                  * The request cannot be resolved by the current memory mapping;
140                  * Delete the existing mapping and create a new one.
141                  */
142                 if (mem_info->mapped_length) {
143                         /* Valid mapping, delete it */
144
145                         acpi_os_unmap_memory (mem_info->mapped_logical_address,
146                                            mem_info->mapped_length);
147                 }
148
149                 /*
150                  * Don't attempt to map memory beyond the end of the region, and
151                  * constrain the maximum mapping size to something reasonable.
152                  */
153                 window_size = (acpi_size)
154                         ((mem_info->address + mem_info->length) - address);
155
156                 if (window_size > ACPI_SYSMEM_REGION_WINDOW_SIZE) {
157                         window_size = ACPI_SYSMEM_REGION_WINDOW_SIZE;
158                 }
159
160                 /* Create a new mapping starting at the address given */
161
162                 status = acpi_os_map_memory (address, window_size,
163                                   (void **) &mem_info->mapped_logical_address);
164                 if (ACPI_FAILURE (status)) {
165                         ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
166                                 "Could not map memory at %8.8X%8.8X, size %X\n",
167                                 ACPI_FORMAT_UINT64 (address), (u32) window_size));
168                         mem_info->mapped_length = 0;
169                         return_ACPI_STATUS (status);
170                 }
171
172                 /* Save the physical address and mapping size */
173
174                 mem_info->mapped_physical_address = address;
175                 mem_info->mapped_length = window_size;
176         }
177
178         /*
179          * Generate a logical pointer corresponding to the address we want to
180          * access
181          */
182         logical_addr_ptr = mem_info->mapped_logical_address +
183                            ((acpi_integer) address -
184                                           (acpi_integer) mem_info->mapped_physical_address);
185
186         ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
187                         "system_memory %d (%d width) Address=%8.8X%8.8X\n",
188                         function, bit_width,
189                         ACPI_FORMAT_UINT64 (address)));
190
191    /*
192         * Perform the memory read or write
193         *
194         * Note: For machines that do not support non-aligned transfers, the target
195         * address was checked for alignment above.  We do not attempt to break the
196         * transfer up into smaller (byte-size) chunks because the AML specifically
197         * asked for a transfer width that the hardware may require.
198         */
199         switch (function) {
200         case ACPI_READ:
201
202                 *value = 0;
203                 switch (bit_width) {
204                 case 8:
205                         *value = (acpi_integer) *((u8 *) logical_addr_ptr);
206                         break;
207
208                 case 16:
209                         *value = (acpi_integer) *((u16 *) logical_addr_ptr);
210                         break;
211
212                 case 32:
213                         *value = (acpi_integer) *((u32 *) logical_addr_ptr);
214                         break;
215
216 #if ACPI_MACHINE_WIDTH != 16
217                 case 64:
218                         *value = (acpi_integer) *((u64 *) logical_addr_ptr);
219                         break;
220 #endif
221                 default:
222                         /* bit_width was already validated */
223                         break;
224                 }
225                 break;
226
227         case ACPI_WRITE:
228
229                 switch (bit_width) {
230                 case 8:
231                         *(u8 *) logical_addr_ptr = (u8) *value;
232                         break;
233
234                 case 16:
235                         *(u16 *) logical_addr_ptr = (u16) *value;
236                         break;
237
238                 case 32:
239                         *(u32 *) logical_addr_ptr = (u32) *value;
240                         break;
241
242 #if ACPI_MACHINE_WIDTH != 16
243                 case 64:
244                         *(u64 *) logical_addr_ptr = (u64) *value;
245                         break;
246 #endif
247
248                 default:
249                         /* bit_width was already validated */
250                         break;
251                 }
252                 break;
253
254         default:
255                 status = AE_BAD_PARAMETER;
256                 break;
257         }
258
259         return_ACPI_STATUS (status);
260 }
261
262
263 /*******************************************************************************
264  *
265  * FUNCTION:    acpi_ex_system_io_space_handler
266  *
267  * PARAMETERS:  Function            - Read or Write operation
268  *              Address             - Where in the space to read or write
269  *              bit_width           - Field width in bits (8, 16, or 32)
270  *              Value               - Pointer to in or out value
271  *              handler_context     - Pointer to Handler's context
272  *              region_context      - Pointer to context specific to the
273  *                                    accessed region
274  *
275  * RETURN:      Status
276  *
277  * DESCRIPTION: Handler for the System IO address space (Op Region)
278  *
279  ******************************************************************************/
280
281 acpi_status
282 acpi_ex_system_io_space_handler (
283         u32                             function,
284         acpi_physical_address           address,
285         u32                             bit_width,
286         acpi_integer                    *value,
287         void                            *handler_context,
288         void                            *region_context)
289 {
290         acpi_status                     status = AE_OK;
291         u32                             value32;
292
293
294         ACPI_FUNCTION_TRACE ("ex_system_io_space_handler");
295
296
297         ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
298                         "system_iO %d (%d width) Address=%8.8X%8.8X\n", function, bit_width,
299                         ACPI_FORMAT_UINT64 (address)));
300
301         /* Decode the function parameter */
302
303         switch (function) {
304         case ACPI_READ:
305
306                 status = acpi_os_read_port ((acpi_io_address) address,
307                                  &value32, bit_width);
308                 *value = value32;
309                 break;
310
311         case ACPI_WRITE:
312
313                 status = acpi_os_write_port ((acpi_io_address) address,
314                                  (u32) *value, bit_width);
315                 break;
316
317         default:
318                 status = AE_BAD_PARAMETER;
319                 break;
320         }
321
322         return_ACPI_STATUS (status);
323 }
324
325
326 /*******************************************************************************
327  *
328  * FUNCTION:    acpi_ex_pci_config_space_handler
329  *
330  * PARAMETERS:  Function            - Read or Write operation
331  *              Address             - Where in the space to read or write
332  *              bit_width           - Field width in bits (8, 16, or 32)
333  *              Value               - Pointer to in or out value
334  *              handler_context     - Pointer to Handler's context
335  *              region_context      - Pointer to context specific to the
336  *                                    accessed region
337  *
338  * RETURN:      Status
339  *
340  * DESCRIPTION: Handler for the PCI Config address space (Op Region)
341  *
342  ******************************************************************************/
343
344 acpi_status
345 acpi_ex_pci_config_space_handler (
346         u32                             function,
347         acpi_physical_address           address,
348         u32                             bit_width,
349         acpi_integer                    *value,
350         void                            *handler_context,
351         void                            *region_context)
352 {
353         acpi_status                     status = AE_OK;
354         struct acpi_pci_id              *pci_id;
355         u16                             pci_register;
356
357
358         ACPI_FUNCTION_TRACE ("ex_pci_config_space_handler");
359
360
361         /*
362          *  The arguments to acpi_os(Read|Write)pci_configuration are:
363          *
364          *  pci_segment is the PCI bus segment range 0-31
365          *  pci_bus     is the PCI bus number range 0-255
366          *  pci_device  is the PCI device number range 0-31
367          *  pci_function is the PCI device function number
368          *  pci_register is the Config space register range 0-255 bytes
369          *
370          *  Value - input value for write, output address for read
371          *
372          */
373         pci_id      = (struct acpi_pci_id *) region_context;
374         pci_register = (u16) (u32) address;
375
376         ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
377                 "pci_config %d (%d) Seg(%04x) Bus(%04x) Dev(%04x) Func(%04x) Reg(%04x)\n",
378                 function, bit_width, pci_id->segment, pci_id->bus, pci_id->device,
379                 pci_id->function, pci_register));
380
381         switch (function) {
382         case ACPI_READ:
383
384                 *value = 0;
385                 status = acpi_os_read_pci_configuration (pci_id, pci_register,
386                                  value, bit_width);
387                 break;
388
389         case ACPI_WRITE:
390
391                 status = acpi_os_write_pci_configuration (pci_id, pci_register,
392                                  *value, bit_width);
393                 break;
394
395         default:
396
397                 status = AE_BAD_PARAMETER;
398                 break;
399         }
400
401         return_ACPI_STATUS (status);
402 }
403
404
405 /*******************************************************************************
406  *
407  * FUNCTION:    acpi_ex_cmos_space_handler
408  *
409  * PARAMETERS:  Function            - Read or Write operation
410  *              Address             - Where in the space to read or write
411  *              bit_width           - Field width in bits (8, 16, or 32)
412  *              Value               - Pointer to in or out value
413  *              handler_context     - Pointer to Handler's context
414  *              region_context      - Pointer to context specific to the
415  *                                    accessed region
416  *
417  * RETURN:      Status
418  *
419  * DESCRIPTION: Handler for the CMOS address space (Op Region)
420  *
421  ******************************************************************************/
422
423 acpi_status
424 acpi_ex_cmos_space_handler (
425         u32                             function,
426         acpi_physical_address           address,
427         u32                             bit_width,
428         acpi_integer                    *value,
429         void                            *handler_context,
430         void                            *region_context)
431 {
432         acpi_status                     status = AE_OK;
433
434
435         ACPI_FUNCTION_TRACE ("ex_cmos_space_handler");
436
437
438         return_ACPI_STATUS (status);
439 }
440
441
442 /*******************************************************************************
443  *
444  * FUNCTION:    acpi_ex_pci_bar_space_handler
445  *
446  * PARAMETERS:  Function            - Read or Write operation
447  *              Address             - Where in the space to read or write
448  *              bit_width           - Field width in bits (8, 16, or 32)
449  *              Value               - Pointer to in or out value
450  *              handler_context     - Pointer to Handler's context
451  *              region_context      - Pointer to context specific to the
452  *                                    accessed region
453  *
454  * RETURN:      Status
455  *
456  * DESCRIPTION: Handler for the PCI bar_target address space (Op Region)
457  *
458  ******************************************************************************/
459
460 acpi_status
461 acpi_ex_pci_bar_space_handler (
462         u32                             function,
463         acpi_physical_address           address,
464         u32                             bit_width,
465         acpi_integer                    *value,
466         void                            *handler_context,
467         void                            *region_context)
468 {
469         acpi_status                     status = AE_OK;
470
471
472         ACPI_FUNCTION_TRACE ("ex_pci_bar_space_handler");
473
474
475         return_ACPI_STATUS (status);
476 }
477
478
479 /*******************************************************************************
480  *
481  * FUNCTION:    acpi_ex_data_table_space_handler
482  *
483  * PARAMETERS:  Function            - Read or Write operation
484  *              Address             - Where in the space to read or write
485  *              bit_width           - Field width in bits (8, 16, or 32)
486  *              Value               - Pointer to in or out value
487  *              handler_context     - Pointer to Handler's context
488  *              region_context      - Pointer to context specific to the
489  *                                    accessed region
490  *
491  * RETURN:      Status
492  *
493  * DESCRIPTION: Handler for the Data Table address space (Op Region)
494  *
495  ******************************************************************************/
496
497 acpi_status
498 acpi_ex_data_table_space_handler (
499         u32                             function,
500         acpi_physical_address           address,
501         u32                             bit_width,
502         acpi_integer                    *value,
503         void                            *handler_context,
504         void                            *region_context)
505 {
506         acpi_status                     status = AE_OK;
507         u32                             byte_width = ACPI_DIV_8 (bit_width);
508         u32                             i;
509         char                            *logical_addr_ptr;
510
511
512         ACPI_FUNCTION_TRACE ("ex_data_table_space_handler");
513
514
515         logical_addr_ptr = ACPI_PHYSADDR_TO_PTR (address);
516
517         /* Perform the memory read or write */
518
519         switch (function) {
520         case ACPI_READ:
521
522                 for (i = 0; i < byte_width; i++) {
523                         ((char *) value) [i] = logical_addr_ptr[i];
524                 }
525                 break;
526
527         case ACPI_WRITE:
528         default:
529
530                 return_ACPI_STATUS (AE_SUPPORT);
531         }
532
533         return_ACPI_STATUS (status);
534 }
535
536