OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [drivers/] [acpi/] [executer/] [exregion.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
 
2
/******************************************************************************
3
 *
4
 * Module Name: exregion - ACPI default op_region (address space) handlers
5
 *
6
 *****************************************************************************/
7
 
8
/*
9
 * Copyright (C) 2000 - 2004, 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
 
119
#ifndef ACPI_MISALIGNED_TRANSFERS
120
        /*
121
         * Hardware does not support non-aligned data transfers, we must verify
122
         * the request.
123
         */
124
        (void) acpi_ut_short_divide ((acpi_integer *) &address, length, NULL, &remainder);
125
        if (remainder != 0) {
126
                return_ACPI_STATUS (AE_AML_ALIGNMENT);
127
        }
128
#endif
129
 
130
        /*
131
         * Does the request fit into the cached memory mapping?
132
         * Is 1) Address below the current mapping? OR
133
         *    2) Address beyond the current mapping?
134
         */
135
        if ((address < mem_info->mapped_physical_address) ||
136
                (((acpi_integer) address + length) >
137
                        ((acpi_integer) 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) ((mem_info->address + mem_info->length) - address);
154
                if (window_size > ACPI_SYSMEM_REGION_WINDOW_SIZE) {
155
                        window_size = ACPI_SYSMEM_REGION_WINDOW_SIZE;
156
                }
157
 
158
                /* Create a new mapping starting at the address given */
159
 
160
                status = acpi_os_map_memory (address, window_size,
161
                                  (void **) &mem_info->mapped_logical_address);
162
                if (ACPI_FAILURE (status)) {
163
                        ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not map memory at %8.8X%8.8X, size %X\n",
164
                                        ACPI_FORMAT_UINT64 (address), (u32) window_size));
165
                        mem_info->mapped_length = 0;
166
                        return_ACPI_STATUS (status);
167
                }
168
 
169
                /* Save the physical address and mapping size */
170
 
171
                mem_info->mapped_physical_address = address;
172
                mem_info->mapped_length = window_size;
173
        }
174
 
175
        /*
176
         * Generate a logical pointer corresponding to the address we want to
177
         * access
178
         */
179
        logical_addr_ptr = mem_info->mapped_logical_address +
180
                          ((acpi_integer) address - (acpi_integer) mem_info->mapped_physical_address);
181
 
182
        ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
183
                        "system_memory %d (%d width) Address=%8.8X%8.8X\n", function, bit_width,
184
                        ACPI_FORMAT_UINT64 (address)));
185
 
186
   /*
187
        * Perform the memory read or write
188
        *
189
        * Note: For machines that do not support non-aligned transfers, the target
190
        * address was checked for alignment above.  We do not attempt to break the
191
        * transfer up into smaller (byte-size) chunks because the AML specifically
192
        * asked for a transfer width that the hardware may require.
193
        */
194
        switch (function) {
195
        case ACPI_READ:
196
 
197
                *value = 0;
198
                switch (bit_width) {
199
                case 8:
200
                        *value = (acpi_integer) *((u8 *) logical_addr_ptr);
201
                        break;
202
 
203
                case 16:
204
                        *value = (acpi_integer) *((u16 *) logical_addr_ptr);
205
                        break;
206
 
207
                case 32:
208
                        *value = (acpi_integer) *((u32 *) logical_addr_ptr);
209
                        break;
210
 
211
#if ACPI_MACHINE_WIDTH != 16
212
                case 64:
213
                        *value = (acpi_integer) *((u64 *) logical_addr_ptr);
214
                        break;
215
#endif
216
                default:
217
                        /* bit_width was already validated */
218
                        break;
219
                }
220
                break;
221
 
222
        case ACPI_WRITE:
223
 
224
                switch (bit_width) {
225
                case 8:
226
                        *(u8 *) logical_addr_ptr = (u8) *value;
227
                        break;
228
 
229
                case 16:
230
                        *(u16 *) logical_addr_ptr = (u16) *value;
231
                        break;
232
 
233
                case 32:
234
                        *(u32 *) logical_addr_ptr = (u32) *value;
235
                        break;
236
 
237
#if ACPI_MACHINE_WIDTH != 16
238
                case 64:
239
                        *(u64 *) logical_addr_ptr = (u64) *value;
240
                        break;
241
#endif
242
 
243
                default:
244
                        /* bit_width was already validated */
245
                        break;
246
                }
247
                break;
248
 
249
        default:
250
                status = AE_BAD_PARAMETER;
251
                break;
252
        }
253
 
254
        return_ACPI_STATUS (status);
255
}
256
 
257
 
258
/*******************************************************************************
259
 *
260
 * FUNCTION:    acpi_ex_system_io_space_handler
261
 *
262
 * PARAMETERS:  Function            - Read or Write operation
263
 *              Address             - Where in the space to read or write
264
 *              bit_width           - Field width in bits (8, 16, or 32)
265
 *              Value               - Pointer to in or out value
266
 *              handler_context     - Pointer to Handler's context
267
 *              region_context      - Pointer to context specific to the
268
 *                                    accessed region
269
 *
270
 * RETURN:      Status
271
 *
272
 * DESCRIPTION: Handler for the System IO address space (Op Region)
273
 *
274
 ******************************************************************************/
275
 
276
acpi_status
277
acpi_ex_system_io_space_handler (
278
        u32                             function,
279
        acpi_physical_address           address,
280
        u32                             bit_width,
281
        acpi_integer                    *value,
282
        void                            *handler_context,
283
        void                            *region_context)
284
{
285
        acpi_status                     status = AE_OK;
286
        u32                             value32;
287
 
288
 
289
        ACPI_FUNCTION_TRACE ("ex_system_io_space_handler");
290
 
291
 
292
        ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
293
                        "system_iO %d (%d width) Address=%8.8X%8.8X\n", function, bit_width,
294
                        ACPI_FORMAT_UINT64 (address)));
295
 
296
        /* Decode the function parameter */
297
 
298
        switch (function) {
299
        case ACPI_READ:
300
 
301
                status = acpi_os_read_port ((acpi_io_address) address, &value32, bit_width);
302
                *value = value32;
303
                break;
304
 
305
        case ACPI_WRITE:
306
 
307
                status = acpi_os_write_port ((acpi_io_address) address, (u32) *value, bit_width);
308
                break;
309
 
310
        default:
311
                status = AE_BAD_PARAMETER;
312
                break;
313
        }
314
 
315
        return_ACPI_STATUS (status);
316
}
317
 
318
 
319
/*******************************************************************************
320
 *
321
 * FUNCTION:    acpi_ex_pci_config_space_handler
322
 *
323
 * PARAMETERS:  Function            - Read or Write operation
324
 *              Address             - Where in the space to read or write
325
 *              bit_width           - Field width in bits (8, 16, or 32)
326
 *              Value               - Pointer to in or out value
327
 *              handler_context     - Pointer to Handler's context
328
 *              region_context      - Pointer to context specific to the
329
 *                                    accessed region
330
 *
331
 * RETURN:      Status
332
 *
333
 * DESCRIPTION: Handler for the PCI Config address space (Op Region)
334
 *
335
 ******************************************************************************/
336
 
337
acpi_status
338
acpi_ex_pci_config_space_handler (
339
        u32                             function,
340
        acpi_physical_address           address,
341
        u32                             bit_width,
342
        acpi_integer                    *value,
343
        void                            *handler_context,
344
        void                            *region_context)
345
{
346
        acpi_status                     status = AE_OK;
347
        struct acpi_pci_id              *pci_id;
348
        u16                             pci_register;
349
 
350
 
351
        ACPI_FUNCTION_TRACE ("ex_pci_config_space_handler");
352
 
353
 
354
        /*
355
         *  The arguments to acpi_os(Read|Write)pci_configuration are:
356
         *
357
         *  pci_segment is the PCI bus segment range 0-31
358
         *  pci_bus     is the PCI bus number range 0-255
359
         *  pci_device  is the PCI device number range 0-31
360
         *  pci_function is the PCI device function number
361
         *  pci_register is the Config space register range 0-255 bytes
362
         *
363
         *  Value - input value for write, output address for read
364
         *
365
         */
366
        pci_id      = (struct acpi_pci_id *) region_context;
367
        pci_register = (u16) (u32) address;
368
 
369
        ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
370
                "pci_config %d (%d) Seg(%04x) Bus(%04x) Dev(%04x) Func(%04x) Reg(%04x)\n",
371
                function, bit_width, pci_id->segment, pci_id->bus, pci_id->device,
372
                pci_id->function, pci_register));
373
 
374
        switch (function) {
375
        case ACPI_READ:
376
 
377
                *value = 0;
378
                status = acpi_os_read_pci_configuration (pci_id, pci_register, value, bit_width);
379
                break;
380
 
381
        case ACPI_WRITE:
382
 
383
                status = acpi_os_write_pci_configuration (pci_id, pci_register, *value, bit_width);
384
                break;
385
 
386
        default:
387
 
388
                status = AE_BAD_PARAMETER;
389
                break;
390
        }
391
 
392
        return_ACPI_STATUS (status);
393
}
394
 
395
 
396
/*******************************************************************************
397
 *
398
 * FUNCTION:    acpi_ex_cmos_space_handler
399
 *
400
 * PARAMETERS:  Function            - Read or Write operation
401
 *              Address             - Where in the space to read or write
402
 *              bit_width           - Field width in bits (8, 16, or 32)
403
 *              Value               - Pointer to in or out value
404
 *              handler_context     - Pointer to Handler's context
405
 *              region_context      - Pointer to context specific to the
406
 *                                    accessed region
407
 *
408
 * RETURN:      Status
409
 *
410
 * DESCRIPTION: Handler for the CMOS address space (Op Region)
411
 *
412
 ******************************************************************************/
413
 
414
acpi_status
415
acpi_ex_cmos_space_handler (
416
        u32                             function,
417
        acpi_physical_address           address,
418
        u32                             bit_width,
419
        acpi_integer                    *value,
420
        void                            *handler_context,
421
        void                            *region_context)
422
{
423
        acpi_status                     status = AE_OK;
424
 
425
 
426
        ACPI_FUNCTION_TRACE ("ex_cmos_space_handler");
427
 
428
 
429
        return_ACPI_STATUS (status);
430
}
431
 
432
 
433
/*******************************************************************************
434
 *
435
 * FUNCTION:    acpi_ex_pci_bar_space_handler
436
 *
437
 * PARAMETERS:  Function            - Read or Write operation
438
 *              Address             - Where in the space to read or write
439
 *              bit_width           - Field width in bits (8, 16, or 32)
440
 *              Value               - Pointer to in or out value
441
 *              handler_context     - Pointer to Handler's context
442
 *              region_context      - Pointer to context specific to the
443
 *                                    accessed region
444
 *
445
 * RETURN:      Status
446
 *
447
 * DESCRIPTION: Handler for the PCI bar_target address space (Op Region)
448
 *
449
 ******************************************************************************/
450
 
451
acpi_status
452
acpi_ex_pci_bar_space_handler (
453
        u32                             function,
454
        acpi_physical_address           address,
455
        u32                             bit_width,
456
        acpi_integer                    *value,
457
        void                            *handler_context,
458
        void                            *region_context)
459
{
460
        acpi_status                     status = AE_OK;
461
 
462
 
463
        ACPI_FUNCTION_TRACE ("ex_pci_bar_space_handler");
464
 
465
 
466
        return_ACPI_STATUS (status);
467
}
468
 
469
 
470
/*******************************************************************************
471
 *
472
 * FUNCTION:    acpi_ex_data_table_space_handler
473
 *
474
 * PARAMETERS:  Function            - Read or Write operation
475
 *              Address             - Where in the space to read or write
476
 *              bit_width           - Field width in bits (8, 16, or 32)
477
 *              Value               - Pointer to in or out value
478
 *              handler_context     - Pointer to Handler's context
479
 *              region_context      - Pointer to context specific to the
480
 *                                    accessed region
481
 *
482
 * RETURN:      Status
483
 *
484
 * DESCRIPTION: Handler for the Data Table address space (Op Region)
485
 *
486
 ******************************************************************************/
487
 
488
acpi_status
489
acpi_ex_data_table_space_handler (
490
        u32                             function,
491
        acpi_physical_address           address,
492
        u32                             bit_width,
493
        acpi_integer                    *value,
494
        void                            *handler_context,
495
        void                            *region_context)
496
{
497
        acpi_status                     status = AE_OK;
498
        u32                             byte_width = ACPI_DIV_8 (bit_width);
499
        u32                             i;
500
        char                            *logical_addr_ptr;
501
 
502
 
503
        ACPI_FUNCTION_TRACE ("ex_data_table_space_handler");
504
 
505
 
506
        logical_addr_ptr = ACPI_PHYSADDR_TO_PTR (address);
507
 
508
 
509
   /* Perform the memory read or write */
510
 
511
        switch (function) {
512
        case ACPI_READ:
513
 
514
                for (i = 0; i < byte_width; i++) {
515
                        ((char *) value) [i] = logical_addr_ptr[i];
516
                }
517
                break;
518
 
519
        case ACPI_WRITE:
520
        default:
521
 
522
                return_ACPI_STATUS (AE_SUPPORT);
523
        }
524
 
525
        return_ACPI_STATUS (status);
526
}
527
 
528
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.