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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [drivers/] [acpi/] [tables/] [tbrsdt.c] - Blame information for rev 1275

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/******************************************************************************
2
 *
3
 * Module Name: tbrsdt - ACPI RSDT table utilities
4
 *
5
 *****************************************************************************/
6
 
7
/*
8
 * Copyright (C) 2000 - 2004, R. Byron Moore
9
 * All rights reserved.
10
 *
11
 * Redistribution and use in source and binary forms, with or without
12
 * modification, are permitted provided that the following conditions
13
 * are met:
14
 * 1. Redistributions of source code must retain the above copyright
15
 *    notice, this list of conditions, and the following disclaimer,
16
 *    without modification.
17
 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18
 *    substantially similar to the "NO WARRANTY" disclaimer below
19
 *    ("Disclaimer") and any redistribution must be conditioned upon
20
 *    including a substantially similar Disclaimer requirement for further
21
 *    binary redistribution.
22
 * 3. Neither the names of the above-listed copyright holders nor the names
23
 *    of any contributors may be used to endorse or promote products derived
24
 *    from this software without specific prior written permission.
25
 *
26
 * Alternatively, this software may be distributed under the terms of the
27
 * GNU General Public License ("GPL") version 2 as published by the Free
28
 * Software Foundation.
29
 *
30
 * NO WARRANTY
31
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35
 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41
 * POSSIBILITY OF SUCH DAMAGES.
42
 */
43
 
44
 
45
#include <acpi/acpi.h>
46
#include <acpi/actables.h>
47
 
48
 
49
#define _COMPONENT          ACPI_TABLES
50
         ACPI_MODULE_NAME    ("tbrsdt")
51
 
52
 
53
/*******************************************************************************
54
 *
55
 * FUNCTION:    acpi_tb_verify_rsdp
56
 *
57
 * PARAMETERS:  Address         - RSDP (Pointer to RSDT)
58
 *
59
 * RETURN:      Status
60
 *
61
 * DESCRIPTION: Load and validate the RSDP (ptr) and RSDT (table)
62
 *
63
 ******************************************************************************/
64
 
65
acpi_status
66
acpi_tb_verify_rsdp (
67
        struct acpi_pointer             *address)
68
{
69
        struct acpi_table_desc          table_info;
70
        acpi_status                     status;
71
        struct rsdp_descriptor          *rsdp;
72
 
73
 
74
        ACPI_FUNCTION_TRACE ("tb_verify_rsdp");
75
 
76
 
77
        switch (address->pointer_type) {
78
        case ACPI_LOGICAL_POINTER:
79
 
80
                rsdp = address->pointer.logical;
81
                break;
82
 
83
        case ACPI_PHYSICAL_POINTER:
84
                /*
85
                 * Obtain access to the RSDP structure
86
                 */
87
                status = acpi_os_map_memory (address->pointer.physical, sizeof (struct rsdp_descriptor),
88
                                  (void *) &rsdp);
89
                if (ACPI_FAILURE (status)) {
90
                        return_ACPI_STATUS (status);
91
                }
92
                break;
93
 
94
        default:
95
                return_ACPI_STATUS (AE_BAD_PARAMETER);
96
        }
97
 
98
        /*
99
         *  The signature and checksum must both be correct
100
         */
101
        if (ACPI_STRNCMP ((char *) rsdp, RSDP_SIG, sizeof (RSDP_SIG)-1) != 0) {
102
                /* Nope, BAD Signature */
103
 
104
                status = AE_BAD_SIGNATURE;
105
                goto cleanup;
106
        }
107
 
108
        /* Check the standard checksum */
109
 
110
        if (acpi_tb_checksum (rsdp, ACPI_RSDP_CHECKSUM_LENGTH) != 0) {
111
                status = AE_BAD_CHECKSUM;
112
                goto cleanup;
113
        }
114
 
115
        /* Check extended checksum if table version >= 2 */
116
 
117
        if (rsdp->revision >= 2) {
118
                if (acpi_tb_checksum (rsdp, ACPI_RSDP_XCHECKSUM_LENGTH) != 0) {
119
                        status = AE_BAD_CHECKSUM;
120
                        goto cleanup;
121
                }
122
        }
123
 
124
        /* The RSDP supplied is OK */
125
 
126
        table_info.pointer     = ACPI_CAST_PTR (struct acpi_table_header, rsdp);
127
        table_info.length      = sizeof (struct rsdp_descriptor);
128
        table_info.allocation  = ACPI_MEM_MAPPED;
129
 
130
        /* Save the table pointers and allocation info */
131
 
132
        status = acpi_tb_init_table_descriptor (ACPI_TABLE_RSDP, &table_info);
133
        if (ACPI_FAILURE (status)) {
134
                goto cleanup;
135
        }
136
 
137
        /* Save the RSDP in a global for easy access */
138
 
139
        acpi_gbl_RSDP = ACPI_CAST_PTR (struct rsdp_descriptor, table_info.pointer);
140
        return_ACPI_STATUS (status);
141
 
142
 
143
        /* Error exit */
144
cleanup:
145
 
146
        if (acpi_gbl_table_flags & ACPI_PHYSICAL_POINTER) {
147
                acpi_os_unmap_memory (rsdp, sizeof (struct rsdp_descriptor));
148
        }
149
        return_ACPI_STATUS (status);
150
}
151
 
152
 
153
/*******************************************************************************
154
 *
155
 * FUNCTION:    acpi_tb_get_rsdt_address
156
 *
157
 * PARAMETERS:  None
158
 *
159
 * RETURN:      RSDT physical address
160
 *
161
 * DESCRIPTION: Extract the address of the RSDT or XSDT, depending on the
162
 *              version of the RSDP
163
 *
164
 ******************************************************************************/
165
 
166
void
167
acpi_tb_get_rsdt_address (
168
        struct acpi_pointer             *out_address)
169
{
170
 
171
        ACPI_FUNCTION_ENTRY ();
172
 
173
 
174
        out_address->pointer_type = acpi_gbl_table_flags | ACPI_LOGICAL_ADDRESSING;
175
 
176
        /*
177
         * For RSDP revision 0 or 1, we use the RSDT.
178
         * For RSDP revision 2 (and above), we use the XSDT
179
         */
180
        if (acpi_gbl_RSDP->revision < 2) {
181
                out_address->pointer.value = acpi_gbl_RSDP->rsdt_physical_address;
182
        }
183
        else {
184
                out_address->pointer.value = acpi_gbl_RSDP->xsdt_physical_address;
185
        }
186
}
187
 
188
 
189
/*******************************************************************************
190
 *
191
 * FUNCTION:    acpi_tb_validate_rsdt
192
 *
193
 * PARAMETERS:  table_ptr       - Addressable pointer to the RSDT.
194
 *
195
 * RETURN:      Status
196
 *
197
 * DESCRIPTION: Validate signature for the RSDT or XSDT
198
 *
199
 ******************************************************************************/
200
 
201
acpi_status
202
acpi_tb_validate_rsdt (
203
        struct acpi_table_header        *table_ptr)
204
{
205
        int                             no_match;
206
 
207
 
208
        ACPI_FUNCTION_NAME ("tb_validate_rsdt");
209
 
210
 
211
        /*
212
         * For RSDP revision 0 or 1, we use the RSDT.
213
         * For RSDP revision 2 and above, we use the XSDT
214
         */
215
        if (acpi_gbl_RSDP->revision < 2) {
216
                no_match = ACPI_STRNCMP ((char *) table_ptr, RSDT_SIG,
217
                                  sizeof (RSDT_SIG) -1);
218
        }
219
        else {
220
                no_match = ACPI_STRNCMP ((char *) table_ptr, XSDT_SIG,
221
                                  sizeof (XSDT_SIG) -1);
222
        }
223
 
224
        if (no_match) {
225
                /* Invalid RSDT or XSDT signature */
226
 
227
                ACPI_REPORT_ERROR (("Invalid signature where RSDP indicates RSDT/XSDT should be located\n"));
228
 
229
                ACPI_DUMP_BUFFER (acpi_gbl_RSDP, 20);
230
 
231
                ACPI_DEBUG_PRINT_RAW ((ACPI_DB_ERROR,
232
                        "RSDT/XSDT signature at %X (%p) is invalid\n",
233
                        acpi_gbl_RSDP->rsdt_physical_address,
234
                        (void *) (acpi_native_uint) acpi_gbl_RSDP->rsdt_physical_address));
235
 
236
                if (acpi_gbl_RSDP->revision < 2) {
237
                        ACPI_REPORT_ERROR (("Looking for RSDT (RSDP->Rev < 2)\n"))
238
                }
239
                else {
240
                        ACPI_REPORT_ERROR (("Looking for XSDT (RSDP->Rev >= 2)\n"))
241
                }
242
 
243
                ACPI_DUMP_BUFFER ((char *) table_ptr, 48);
244
 
245
                return (AE_BAD_SIGNATURE);
246
        }
247
 
248
        return (AE_OK);
249
}
250
 
251
 
252
/*******************************************************************************
253
 *
254
 * FUNCTION:    acpi_tb_get_table_rsdt
255
 *
256
 * PARAMETERS:  None
257
 *
258
 * RETURN:      Status
259
 *
260
 * DESCRIPTION: Load and validate the RSDP (ptr) and RSDT (table)
261
 *
262
 ******************************************************************************/
263
 
264
acpi_status
265
acpi_tb_get_table_rsdt (
266
        void)
267
{
268
        struct acpi_table_desc          table_info;
269
        acpi_status                     status;
270
        struct acpi_pointer             address;
271
 
272
 
273
        ACPI_FUNCTION_TRACE ("tb_get_table_rsdt");
274
 
275
 
276
        /* Get the RSDT/XSDT via the RSDP */
277
 
278
        acpi_tb_get_rsdt_address (&address);
279
 
280
        status = acpi_tb_get_table (&address, &table_info);
281
        if (ACPI_FAILURE (status)) {
282
                ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not get the RSDT/XSDT, %s\n",
283
                        acpi_format_exception (status)));
284
                return_ACPI_STATUS (status);
285
        }
286
 
287
        ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
288
                "RSDP located at %p, points to RSDT physical=%8.8X%8.8X \n",
289
                acpi_gbl_RSDP,
290
                ACPI_FORMAT_UINT64 (address.pointer.value)));
291
 
292
        /* Check the RSDT or XSDT signature */
293
 
294
        status = acpi_tb_validate_rsdt (table_info.pointer);
295
        if (ACPI_FAILURE (status)) {
296
                return_ACPI_STATUS (status);
297
        }
298
 
299
        /* Get the number of tables defined in the RSDT or XSDT */
300
 
301
        acpi_gbl_rsdt_table_count = acpi_tb_get_table_count (acpi_gbl_RSDP, table_info.pointer);
302
 
303
        /* Convert and/or copy to an XSDT structure */
304
 
305
        status = acpi_tb_convert_to_xsdt (&table_info);
306
        if (ACPI_FAILURE (status)) {
307
                return_ACPI_STATUS (status);
308
        }
309
 
310
        /* Save the table pointers and allocation info */
311
 
312
        status = acpi_tb_init_table_descriptor (ACPI_TABLE_XSDT, &table_info);
313
        if (ACPI_FAILURE (status)) {
314
                return_ACPI_STATUS (status);
315
        }
316
 
317
        acpi_gbl_XSDT = ACPI_CAST_PTR (XSDT_DESCRIPTOR, table_info.pointer);
318
 
319
        ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "XSDT located at %p\n", acpi_gbl_XSDT));
320
        return_ACPI_STATUS (status);
321
}
322
 
323
 

powered by: WebSVN 2.1.0

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