Ported ACPI CA (from the nice guys at Intel) to ReactOS (ACPI bus driver).
[reactos.git] / reactos / drivers / bus / acpi / utils / cmxface.c
1 /******************************************************************************
2 *
3 * Module Name: cmxface - External interfaces for "global" ACPI functions
4 * $Revision: 1.1 $
5 *
6 *****************************************************************************/
7
8 /*
9 * Copyright (C) 2000, 2001 R. Byron Moore
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 */
25
26
27 #include "acpi.h"
28 #include "acevents.h"
29 #include "achware.h"
30 #include "acnamesp.h"
31 #include "acinterp.h"
32 #include "amlcode.h"
33 #include "acdebug.h"
34
35
36 #define _COMPONENT ACPI_UTILITIES
37 MODULE_NAME ("cmxface")
38
39
40 /*******************************************************************************
41 *
42 * FUNCTION: Acpi_initialize_subsystem
43 *
44 * PARAMETERS: None
45 *
46 * RETURN: Status
47 *
48 * DESCRIPTION: Initializes all global variables. This is the first function
49 * called, so any early initialization belongs here.
50 *
51 ******************************************************************************/
52
53 ACPI_STATUS
54 acpi_initialize_subsystem (
55 void)
56 {
57 ACPI_STATUS status;
58
59
60 /* Initialize all globals used by the subsystem */
61
62 acpi_cm_init_globals ();
63
64 /* Initialize the OS-Dependent layer */
65
66 status = acpi_os_initialize ();
67 if (ACPI_FAILURE (status)) {
68 REPORT_ERROR (("OSD failed to initialize, %s\n",
69 acpi_cm_format_exception (status)));
70 return (status);
71 }
72
73 /* Create the default mutex objects */
74
75 status = acpi_cm_mutex_initialize ();
76 if (ACPI_FAILURE (status)) {
77 REPORT_ERROR (("Global mutex creation failure, %s\n",
78 acpi_cm_format_exception (status)));
79 return (status);
80 }
81
82 /*
83 * Initialize the namespace manager and
84 * the root of the namespace tree
85 */
86
87 status = acpi_ns_root_initialize ();
88 if (ACPI_FAILURE (status)) {
89 REPORT_ERROR (("Namespace initialization failure, %s\n",
90 acpi_cm_format_exception (status)));
91 return (status);
92 }
93
94
95 /* If configured, initialize the AML debugger */
96
97 DEBUGGER_EXEC (acpi_db_initialize ());
98
99 return (status);
100 }
101
102
103 /*******************************************************************************
104 *
105 * FUNCTION: Acpi_enable_subsystem
106 *
107 * PARAMETERS: Flags - Init/enable Options
108 *
109 * RETURN: Status
110 *
111 * DESCRIPTION: Completes the subsystem initialization including hardware.
112 * Puts system into ACPI mode if it isn't already.
113 *
114 ******************************************************************************/
115
116 ACPI_STATUS
117 acpi_enable_subsystem (
118 u32 flags)
119 {
120 ACPI_STATUS status = AE_OK;
121
122
123 /* Sanity check the FADT for valid values */
124
125 status = acpi_cm_validate_fadt ();
126 if (ACPI_FAILURE (status)) {
127 return (status);
128 }
129
130 /*
131 * Install the default Op_region handlers. These are
132 * installed unless other handlers have already been
133 * installed via the Install_address_space_handler interface
134 */
135
136 if (!(flags & ACPI_NO_ADDRESS_SPACE_INIT)) {
137 status = acpi_ev_install_default_address_space_handlers ();
138 if (ACPI_FAILURE (status)) {
139 return (status);
140 }
141 }
142
143 /*
144 * We must initialize the hardware before we can enable ACPI.
145 */
146
147 if (!(flags & ACPI_NO_HARDWARE_INIT)) {
148 status = acpi_hw_initialize ();
149 if (ACPI_FAILURE (status)) {
150 return (status);
151 }
152 }
153
154 /*
155 * Enable ACPI on this platform
156 */
157
158 if (!(flags & ACPI_NO_ACPI_ENABLE)) {
159 status = acpi_enable ();
160 if (ACPI_FAILURE (status)) {
161 return (status);
162 }
163 }
164
165 /*
166 * Note:
167 * We must have the hardware AND events initialized before we can execute
168 * ANY control methods SAFELY. Any control method can require ACPI hardware
169 * support, so the hardware MUST be initialized before execution!
170 */
171
172 if (!(flags & ACPI_NO_EVENT_INIT)) {
173 status = acpi_ev_initialize ();
174 if (ACPI_FAILURE (status)) {
175 return (status);
176 }
177 }
178
179
180 /*
181 * Initialize all device objects in the namespace
182 * This runs the _STA and _INI methods.
183 */
184
185 if (!(flags & ACPI_NO_DEVICE_INIT)) {
186 status = acpi_ns_initialize_devices ();
187 if (ACPI_FAILURE (status)) {
188 return (status);
189 }
190 }
191
192
193 /*
194 * Initialize the objects that remain uninitialized. This
195 * runs the executable AML that is part of the declaration of Op_regions
196 * and Fields.
197 */
198
199 if (!(flags & ACPI_NO_OBJECT_INIT)) {
200 status = acpi_ns_initialize_objects ();
201 if (ACPI_FAILURE (status)) {
202 return (status);
203 }
204 }
205
206
207 return (status);
208 }
209
210
211 /*******************************************************************************
212 *
213 * FUNCTION: Acpi_terminate
214 *
215 * PARAMETERS: None
216 *
217 * RETURN: Status
218 *
219 * DESCRIPTION: Shutdown the ACPI subsystem. Release all resources.
220 *
221 ******************************************************************************/
222
223 ACPI_STATUS
224 acpi_terminate (void)
225 {
226
227 /* Terminate the AML Debuger if present */
228
229 DEBUGGER_EXEC(acpi_gbl_db_terminate_threads = TRUE);
230
231 /* TBD: [Investigate] This is no longer needed?*/
232 /* Acpi_cm_release_mutex (ACPI_MTX_DEBUG_CMD_READY); */
233
234
235 /* Shutdown and free all resources */
236
237 acpi_cm_subsystem_shutdown ();
238
239
240 /* Free the mutex objects */
241
242 acpi_cm_mutex_terminate ();
243
244
245 /* Now we can shutdown the OS-dependent layer */
246
247 acpi_os_terminate ();
248
249 return (AE_OK);
250 }
251
252
253 /******************************************************************************
254 *
255 * FUNCTION: Acpi_get_system_info
256 *
257 * PARAMETERS: Out_buffer - a pointer to a buffer to receive the
258 * resources for the device
259 * Buffer_length - the number of bytes available in the buffer
260 *
261 * RETURN: Status - the status of the call
262 *
263 * DESCRIPTION: This function is called to get information about the current
264 * state of the ACPI subsystem. It will return system information
265 * in the Out_buffer.
266 *
267 * If the function fails an appropriate status will be returned
268 * and the value of Out_buffer is undefined.
269 *
270 ******************************************************************************/
271
272 ACPI_STATUS
273 acpi_get_system_info (
274 ACPI_BUFFER *out_buffer)
275 {
276 ACPI_SYSTEM_INFO *info_ptr;
277 u32 i;
278
279
280 /*
281 * Must have a valid buffer
282 */
283 if ((!out_buffer) ||
284 (!out_buffer->pointer)) {
285 return (AE_BAD_PARAMETER);
286 }
287
288 if (out_buffer->length < sizeof (ACPI_SYSTEM_INFO)) {
289 /*
290 * Caller's buffer is too small
291 */
292 out_buffer->length = sizeof (ACPI_SYSTEM_INFO);
293
294 return (AE_BUFFER_OVERFLOW);
295 }
296
297
298 /*
299 * Set return length and get data
300 */
301 out_buffer->length = sizeof (ACPI_SYSTEM_INFO);
302 info_ptr = (ACPI_SYSTEM_INFO *) out_buffer->pointer;
303
304 info_ptr->acpi_ca_version = ACPI_CA_VERSION;
305
306 /* System flags (ACPI capabilities) */
307
308 info_ptr->flags = acpi_gbl_system_flags;
309
310 /* Timer resolution - 24 or 32 bits */
311 if (!acpi_gbl_FADT) {
312 info_ptr->timer_resolution = 0;
313 }
314 else if (acpi_gbl_FADT->tmr_val_ext == 0) {
315 info_ptr->timer_resolution = 24;
316 }
317 else {
318 info_ptr->timer_resolution = 32;
319 }
320
321 /* Clear the reserved fields */
322
323 info_ptr->reserved1 = 0;
324 info_ptr->reserved2 = 0;
325
326 /* Current debug levels */
327
328 info_ptr->debug_layer = acpi_dbg_layer;
329 info_ptr->debug_level = acpi_dbg_level;
330
331 /* Current status of the ACPI tables, per table type */
332
333 info_ptr->num_table_types = NUM_ACPI_TABLES;
334 for (i = 0; i < NUM_ACPI_TABLES; i++) {
335 info_ptr->table_info[i].count = acpi_gbl_acpi_tables[i].count;
336 }
337
338 return (AE_OK);
339 }
340
341
342 /******************************************************************************
343 *
344 * FUNCTION: Acpi_format_exception
345 *
346 * PARAMETERS: Out_buffer - a pointer to a buffer to receive the
347 * exception name
348 *
349 * RETURN: Status - the status of the call
350 *
351 * DESCRIPTION: This function translates an ACPI exception into an ASCII string.
352 *
353 ******************************************************************************/
354
355 ACPI_STATUS
356 acpi_format_exception (
357 ACPI_STATUS exception,
358 ACPI_BUFFER *out_buffer)
359 {
360 u32 length;
361 NATIVE_CHAR *formatted_exception;
362
363
364 /*
365 * Must have a valid buffer
366 */
367 if ((!out_buffer) ||
368 (!out_buffer->pointer)) {
369 return (AE_BAD_PARAMETER);
370 }
371
372
373 /* Convert the exception code (Handles bad exception codes) */
374
375 formatted_exception = acpi_cm_format_exception (exception);
376
377 /*
378 * Get length of string and check if it will fit in caller's buffer
379 */
380
381 length = STRLEN (formatted_exception);
382 if (out_buffer->length < length) {
383 out_buffer->length = length;
384 return (AE_BUFFER_OVERFLOW);
385 }
386
387
388 /* Copy the string, all done */
389
390 STRCPY (out_buffer->pointer, formatted_exception);
391
392 return (AE_OK);
393 }
394
395
396 /*****************************************************************************
397 *
398 * FUNCTION: Acpi_allocate
399 *
400 * PARAMETERS: Size - Size of the allocation
401 *
402 * RETURN: Address of the allocated memory on success, NULL on failure.
403 *
404 * DESCRIPTION: The subsystem's equivalent of malloc.
405 * External front-end to the Cm* memory manager
406 *
407 ****************************************************************************/
408
409 void *
410 acpi_allocate (
411 u32 size)
412 {
413
414 return (acpi_cm_allocate (size));
415 }
416
417
418 /*****************************************************************************
419 *
420 * FUNCTION: Acpi_callocate
421 *
422 * PARAMETERS: Size - Size of the allocation
423 *
424 * RETURN: Address of the allocated memory on success, NULL on failure.
425 *
426 * DESCRIPTION: The subsystem's equivalent of calloc.
427 * External front-end to the Cm* memory manager
428 *
429 ****************************************************************************/
430
431 void *
432 acpi_callocate (
433 u32 size)
434 {
435
436 return (acpi_cm_callocate (size));
437 }
438
439
440 /*****************************************************************************
441 *
442 * FUNCTION: Acpi_free
443 *
444 * PARAMETERS: Address - Address of the memory to deallocate
445 *
446 * RETURN: None
447 *
448 * DESCRIPTION: Frees the memory at Address
449 * External front-end to the Cm* memory manager
450 *
451 ****************************************************************************/
452
453 void
454 acpi_free (
455 void *address)
456 {
457
458 acpi_cm_free (address);
459 }