Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/tools/power/acpi/os_specific/service_layers/osunixxf.c
26292 views
1
// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
2
/******************************************************************************
3
*
4
* Module Name: osunixxf - UNIX OSL interfaces
5
*
6
* Copyright (C) 2000 - 2025, Intel Corp.
7
*
8
*****************************************************************************/
9
10
/*
11
* These interfaces are required in order to compile the ASL compiler and the
12
* various ACPICA tools under Linux or other Unix-like system.
13
*/
14
#include <acpi/acpi.h>
15
#include "accommon.h"
16
#include "amlcode.h"
17
#include "acparser.h"
18
#include "acdebug.h"
19
20
#include <stdio.h>
21
#include <stdlib.h>
22
#include <stdarg.h>
23
#include <unistd.h>
24
#include <sys/time.h>
25
#include <semaphore.h>
26
#include <pthread.h>
27
#include <errno.h>
28
29
#define _COMPONENT ACPI_OS_SERVICES
30
ACPI_MODULE_NAME("osunixxf")
31
32
/* Upcalls to acpi_exec */
33
void
34
ae_table_override(struct acpi_table_header *existing_table,
35
struct acpi_table_header **new_table);
36
37
typedef void *(*PTHREAD_CALLBACK) (void *);
38
39
/* Buffer used by acpi_os_vprintf */
40
41
#define ACPI_VPRINTF_BUFFER_SIZE 512
42
#define _ASCII_NEWLINE '\n'
43
44
/* Terminal support for acpi_exec only */
45
46
#ifdef ACPI_EXEC_APP
47
#include <termios.h>
48
49
struct termios original_term_attributes;
50
int term_attributes_were_set = 0;
51
52
acpi_status acpi_ut_read_line(char *buffer, u32 buffer_length, u32 *bytes_read);
53
54
static void os_enter_line_edit_mode(void);
55
56
static void os_exit_line_edit_mode(void);
57
58
/******************************************************************************
59
*
60
* FUNCTION: os_enter_line_edit_mode, os_exit_line_edit_mode
61
*
62
* PARAMETERS: None
63
*
64
* RETURN: None
65
*
66
* DESCRIPTION: Enter/Exit the raw character input mode for the terminal.
67
*
68
* Interactive line-editing support for the AML debugger. Used with the
69
* common/acgetline module.
70
*
71
* readline() is not used because of non-portability. It is not available
72
* on all systems, and if it is, often the package must be manually installed.
73
*
74
* Therefore, we use the POSIX tcgetattr/tcsetattr and do the minimal line
75
* editing that we need in acpi_os_get_line.
76
*
77
* If the POSIX tcgetattr/tcsetattr interfaces are unavailable, these
78
* calls will also work:
79
* For os_enter_line_edit_mode: system ("stty cbreak -echo")
80
* For os_exit_line_edit_mode: system ("stty cooked echo")
81
*
82
*****************************************************************************/
83
84
static void os_enter_line_edit_mode(void)
85
{
86
struct termios local_term_attributes;
87
88
term_attributes_were_set = 0;
89
90
/* STDIN must be a terminal */
91
92
if (!isatty(STDIN_FILENO)) {
93
return;
94
}
95
96
/* Get and keep the original attributes */
97
98
if (tcgetattr(STDIN_FILENO, &original_term_attributes)) {
99
fprintf(stderr, "Could not get terminal attributes!\n");
100
return;
101
}
102
103
/* Set the new attributes to enable raw character input */
104
105
memcpy(&local_term_attributes, &original_term_attributes,
106
sizeof(struct termios));
107
108
local_term_attributes.c_lflag &= ~(ICANON | ECHO);
109
local_term_attributes.c_cc[VMIN] = 1;
110
local_term_attributes.c_cc[VTIME] = 0;
111
112
if (tcsetattr(STDIN_FILENO, TCSANOW, &local_term_attributes)) {
113
fprintf(stderr, "Could not set terminal attributes!\n");
114
return;
115
}
116
117
term_attributes_were_set = 1;
118
}
119
120
static void os_exit_line_edit_mode(void)
121
{
122
123
if (!term_attributes_were_set) {
124
return;
125
}
126
127
/* Set terminal attributes back to the original values */
128
129
if (tcsetattr(STDIN_FILENO, TCSANOW, &original_term_attributes)) {
130
fprintf(stderr, "Could not restore terminal attributes!\n");
131
}
132
}
133
134
#else
135
136
/* These functions are not needed for other ACPICA utilities */
137
138
#define os_enter_line_edit_mode()
139
#define os_exit_line_edit_mode()
140
#endif
141
142
/******************************************************************************
143
*
144
* FUNCTION: acpi_os_initialize, acpi_os_terminate
145
*
146
* PARAMETERS: None
147
*
148
* RETURN: Status
149
*
150
* DESCRIPTION: Initialize and terminate this module.
151
*
152
*****************************************************************************/
153
154
acpi_status acpi_os_initialize(void)
155
{
156
acpi_status status;
157
158
acpi_gbl_output_file = stdout;
159
160
os_enter_line_edit_mode();
161
162
status = acpi_os_create_lock(&acpi_gbl_print_lock);
163
if (ACPI_FAILURE(status)) {
164
return (status);
165
}
166
167
return (AE_OK);
168
}
169
170
acpi_status acpi_os_terminate(void)
171
{
172
173
os_exit_line_edit_mode();
174
return (AE_OK);
175
}
176
177
#ifndef ACPI_USE_NATIVE_RSDP_POINTER
178
/******************************************************************************
179
*
180
* FUNCTION: acpi_os_get_root_pointer
181
*
182
* PARAMETERS: None
183
*
184
* RETURN: RSDP physical address
185
*
186
* DESCRIPTION: Gets the ACPI root pointer (RSDP)
187
*
188
*****************************************************************************/
189
190
acpi_physical_address acpi_os_get_root_pointer(void)
191
{
192
193
return (0);
194
}
195
#endif
196
197
/******************************************************************************
198
*
199
* FUNCTION: acpi_os_predefined_override
200
*
201
* PARAMETERS: init_val - Initial value of the predefined object
202
* new_val - The new value for the object
203
*
204
* RETURN: Status, pointer to value. Null pointer returned if not
205
* overriding.
206
*
207
* DESCRIPTION: Allow the OS to override predefined names
208
*
209
*****************************************************************************/
210
211
acpi_status
212
acpi_os_predefined_override(const struct acpi_predefined_names *init_val,
213
acpi_string *new_val)
214
{
215
216
if (!init_val || !new_val) {
217
return (AE_BAD_PARAMETER);
218
}
219
220
*new_val = NULL;
221
return (AE_OK);
222
}
223
224
/******************************************************************************
225
*
226
* FUNCTION: acpi_os_table_override
227
*
228
* PARAMETERS: existing_table - Header of current table (probably
229
* firmware)
230
* new_table - Where an entire new table is returned.
231
*
232
* RETURN: Status, pointer to new table. Null pointer returned if no
233
* table is available to override
234
*
235
* DESCRIPTION: Return a different version of a table if one is available
236
*
237
*****************************************************************************/
238
239
acpi_status
240
acpi_os_table_override(struct acpi_table_header *existing_table,
241
struct acpi_table_header **new_table)
242
{
243
244
if (!existing_table || !new_table) {
245
return (AE_BAD_PARAMETER);
246
}
247
248
*new_table = NULL;
249
250
#ifdef ACPI_EXEC_APP
251
252
ae_table_override(existing_table, new_table);
253
return (AE_OK);
254
#else
255
256
return (AE_NO_ACPI_TABLES);
257
#endif
258
}
259
260
/******************************************************************************
261
*
262
* FUNCTION: acpi_os_physical_table_override
263
*
264
* PARAMETERS: existing_table - Header of current table (probably firmware)
265
* new_address - Where new table address is returned
266
* (Physical address)
267
* new_table_length - Where new table length is returned
268
*
269
* RETURN: Status, address/length of new table. Null pointer returned
270
* if no table is available to override.
271
*
272
* DESCRIPTION: Returns AE_SUPPORT, function not used in user space.
273
*
274
*****************************************************************************/
275
276
acpi_status
277
acpi_os_physical_table_override(struct acpi_table_header *existing_table,
278
acpi_physical_address *new_address,
279
u32 *new_table_length)
280
{
281
282
return (AE_SUPPORT);
283
}
284
285
/******************************************************************************
286
*
287
* FUNCTION: acpi_os_enter_sleep
288
*
289
* PARAMETERS: sleep_state - Which sleep state to enter
290
* rega_value - Register A value
291
* regb_value - Register B value
292
*
293
* RETURN: Status
294
*
295
* DESCRIPTION: A hook before writing sleep registers to enter the sleep
296
* state. Return AE_CTRL_TERMINATE to skip further sleep register
297
* writes.
298
*
299
*****************************************************************************/
300
301
acpi_status acpi_os_enter_sleep(u8 sleep_state, u32 rega_value, u32 regb_value)
302
{
303
304
return (AE_OK);
305
}
306
307
/******************************************************************************
308
*
309
* FUNCTION: acpi_os_redirect_output
310
*
311
* PARAMETERS: destination - An open file handle/pointer
312
*
313
* RETURN: None
314
*
315
* DESCRIPTION: Causes redirect of acpi_os_printf and acpi_os_vprintf
316
*
317
*****************************************************************************/
318
319
void acpi_os_redirect_output(void *destination)
320
{
321
322
acpi_gbl_output_file = destination;
323
}
324
325
/******************************************************************************
326
*
327
* FUNCTION: acpi_os_printf
328
*
329
* PARAMETERS: fmt, ... - Standard printf format
330
*
331
* RETURN: None
332
*
333
* DESCRIPTION: Formatted output. Note: very similar to acpi_os_vprintf
334
* (performance), changes should be tracked in both functions.
335
*
336
*****************************************************************************/
337
338
void ACPI_INTERNAL_VAR_XFACE acpi_os_printf(const char *fmt, ...)
339
{
340
va_list args;
341
u8 flags;
342
343
flags = acpi_gbl_db_output_flags;
344
if (flags & ACPI_DB_REDIRECTABLE_OUTPUT) {
345
346
/* Output is directable to either a file (if open) or the console */
347
348
if (acpi_gbl_debug_file) {
349
350
/* Output file is open, send the output there */
351
352
va_start(args, fmt);
353
vfprintf(acpi_gbl_debug_file, fmt, args);
354
va_end(args);
355
} else {
356
/* No redirection, send output to console (once only!) */
357
358
flags |= ACPI_DB_CONSOLE_OUTPUT;
359
}
360
}
361
362
if (flags & ACPI_DB_CONSOLE_OUTPUT) {
363
va_start(args, fmt);
364
vfprintf(acpi_gbl_output_file, fmt, args);
365
va_end(args);
366
}
367
}
368
369
/******************************************************************************
370
*
371
* FUNCTION: acpi_os_vprintf
372
*
373
* PARAMETERS: fmt - Standard printf format
374
* args - Argument list
375
*
376
* RETURN: None
377
*
378
* DESCRIPTION: Formatted output with argument list pointer. Note: very
379
* similar to acpi_os_printf, changes should be tracked in both
380
* functions.
381
*
382
*****************************************************************************/
383
384
void acpi_os_vprintf(const char *fmt, va_list args)
385
{
386
u8 flags;
387
char buffer[ACPI_VPRINTF_BUFFER_SIZE];
388
389
/*
390
* We build the output string in a local buffer because we may be
391
* outputting the buffer twice. Using vfprintf is problematic because
392
* some implementations modify the args pointer/structure during
393
* execution. Thus, we use the local buffer for portability.
394
*
395
* Note: Since this module is intended for use by the various ACPICA
396
* utilities/applications, we can safely declare the buffer on the stack.
397
* Also, This function is used for relatively small error messages only.
398
*/
399
vsnprintf(buffer, ACPI_VPRINTF_BUFFER_SIZE, fmt, args);
400
401
flags = acpi_gbl_db_output_flags;
402
if (flags & ACPI_DB_REDIRECTABLE_OUTPUT) {
403
404
/* Output is directable to either a file (if open) or the console */
405
406
if (acpi_gbl_debug_file) {
407
408
/* Output file is open, send the output there */
409
410
fputs(buffer, acpi_gbl_debug_file);
411
} else {
412
/* No redirection, send output to console (once only!) */
413
414
flags |= ACPI_DB_CONSOLE_OUTPUT;
415
}
416
}
417
418
if (flags & ACPI_DB_CONSOLE_OUTPUT) {
419
fputs(buffer, acpi_gbl_output_file);
420
}
421
}
422
423
#ifndef ACPI_EXEC_APP
424
/******************************************************************************
425
*
426
* FUNCTION: acpi_os_get_line
427
*
428
* PARAMETERS: buffer - Where to return the command line
429
* buffer_length - Maximum length of Buffer
430
* bytes_read - Where the actual byte count is returned
431
*
432
* RETURN: Status and actual bytes read
433
*
434
* DESCRIPTION: Get the next input line from the terminal. NOTE: For the
435
* acpi_exec utility, we use the acgetline module instead to
436
* provide line-editing and history support.
437
*
438
*****************************************************************************/
439
440
acpi_status acpi_os_get_line(char *buffer, u32 buffer_length, u32 *bytes_read)
441
{
442
int input_char;
443
u32 end_of_line;
444
445
/* Standard acpi_os_get_line for all utilities except acpi_exec */
446
447
for (end_of_line = 0;; end_of_line++) {
448
if (end_of_line >= buffer_length) {
449
return (AE_BUFFER_OVERFLOW);
450
}
451
452
if ((input_char = getchar()) == EOF) {
453
return (AE_ERROR);
454
}
455
456
if (!input_char || input_char == _ASCII_NEWLINE) {
457
break;
458
}
459
460
buffer[end_of_line] = (char)input_char;
461
}
462
463
/* Null terminate the buffer */
464
465
buffer[end_of_line] = 0;
466
467
/* Return the number of bytes in the string */
468
469
if (bytes_read) {
470
*bytes_read = end_of_line;
471
}
472
473
return (AE_OK);
474
}
475
#endif
476
477
#ifndef ACPI_USE_NATIVE_MEMORY_MAPPING
478
/******************************************************************************
479
*
480
* FUNCTION: acpi_os_map_memory
481
*
482
* PARAMETERS: where - Physical address of memory to be mapped
483
* length - How much memory to map
484
*
485
* RETURN: Pointer to mapped memory. Null on error.
486
*
487
* DESCRIPTION: Map physical memory into caller's address space
488
*
489
*****************************************************************************/
490
491
void *acpi_os_map_memory(acpi_physical_address where, acpi_size length)
492
{
493
494
return (ACPI_TO_POINTER((acpi_size)where));
495
}
496
497
/******************************************************************************
498
*
499
* FUNCTION: acpi_os_unmap_memory
500
*
501
* PARAMETERS: where - Logical address of memory to be unmapped
502
* length - How much memory to unmap
503
*
504
* RETURN: None.
505
*
506
* DESCRIPTION: Delete a previously created mapping. Where and Length must
507
* correspond to a previous mapping exactly.
508
*
509
*****************************************************************************/
510
511
void acpi_os_unmap_memory(void *where, acpi_size length)
512
{
513
514
return;
515
}
516
#endif
517
518
/******************************************************************************
519
*
520
* FUNCTION: acpi_os_allocate
521
*
522
* PARAMETERS: size - Amount to allocate, in bytes
523
*
524
* RETURN: Pointer to the new allocation. Null on error.
525
*
526
* DESCRIPTION: Allocate memory. Algorithm is dependent on the OS.
527
*
528
*****************************************************************************/
529
530
void *acpi_os_allocate(acpi_size size)
531
{
532
void *mem;
533
534
mem = (void *)malloc((size_t) size);
535
return (mem);
536
}
537
538
#ifdef USE_NATIVE_ALLOCATE_ZEROED
539
/******************************************************************************
540
*
541
* FUNCTION: acpi_os_allocate_zeroed
542
*
543
* PARAMETERS: size - Amount to allocate, in bytes
544
*
545
* RETURN: Pointer to the new allocation. Null on error.
546
*
547
* DESCRIPTION: Allocate and zero memory. Algorithm is dependent on the OS.
548
*
549
*****************************************************************************/
550
551
void *acpi_os_allocate_zeroed(acpi_size size)
552
{
553
void *mem;
554
555
mem = (void *)calloc(1, (size_t) size);
556
return (mem);
557
}
558
#endif
559
560
/******************************************************************************
561
*
562
* FUNCTION: acpi_os_free
563
*
564
* PARAMETERS: mem - Pointer to previously allocated memory
565
*
566
* RETURN: None.
567
*
568
* DESCRIPTION: Free memory allocated via acpi_os_allocate
569
*
570
*****************************************************************************/
571
572
void acpi_os_free(void *mem)
573
{
574
575
free(mem);
576
}
577
578
#ifdef ACPI_SINGLE_THREADED
579
/******************************************************************************
580
*
581
* FUNCTION: Semaphore stub functions
582
*
583
* DESCRIPTION: Stub functions used for single-thread applications that do
584
* not require semaphore synchronization. Full implementations
585
* of these functions appear after the stubs.
586
*
587
*****************************************************************************/
588
589
acpi_status
590
acpi_os_create_semaphore(u32 max_units,
591
u32 initial_units, acpi_handle *out_handle)
592
{
593
*out_handle = (acpi_handle)1;
594
return (AE_OK);
595
}
596
597
acpi_status acpi_os_delete_semaphore(acpi_handle handle)
598
{
599
return (AE_OK);
600
}
601
602
acpi_status acpi_os_wait_semaphore(acpi_handle handle, u32 units, u16 timeout)
603
{
604
return (AE_OK);
605
}
606
607
acpi_status acpi_os_signal_semaphore(acpi_handle handle, u32 units)
608
{
609
return (AE_OK);
610
}
611
612
#else
613
/******************************************************************************
614
*
615
* FUNCTION: acpi_os_create_semaphore
616
*
617
* PARAMETERS: initial_units - Units to be assigned to the new semaphore
618
* out_handle - Where a handle will be returned
619
*
620
* RETURN: Status
621
*
622
* DESCRIPTION: Create an OS semaphore
623
*
624
*****************************************************************************/
625
626
acpi_status
627
acpi_os_create_semaphore(u32 max_units,
628
u32 initial_units, acpi_handle *out_handle)
629
{
630
sem_t *sem;
631
632
if (!out_handle) {
633
return (AE_BAD_PARAMETER);
634
}
635
#ifdef __APPLE__
636
{
637
static int semaphore_count = 0;
638
char semaphore_name[32];
639
640
snprintf(semaphore_name, sizeof(semaphore_name), "acpi_sem_%d",
641
semaphore_count++);
642
printf("%s\n", semaphore_name);
643
sem =
644
sem_open(semaphore_name, O_EXCL | O_CREAT, 0755,
645
initial_units);
646
if (!sem) {
647
return (AE_NO_MEMORY);
648
}
649
sem_unlink(semaphore_name); /* This just deletes the name */
650
}
651
652
#else
653
sem = acpi_os_allocate(sizeof(sem_t));
654
if (!sem) {
655
return (AE_NO_MEMORY);
656
}
657
658
if (sem_init(sem, 0, initial_units) == -1) {
659
acpi_os_free(sem);
660
return (AE_BAD_PARAMETER);
661
}
662
#endif
663
664
*out_handle = (acpi_handle)sem;
665
return (AE_OK);
666
}
667
668
/******************************************************************************
669
*
670
* FUNCTION: acpi_os_delete_semaphore
671
*
672
* PARAMETERS: handle - Handle returned by acpi_os_create_semaphore
673
*
674
* RETURN: Status
675
*
676
* DESCRIPTION: Delete an OS semaphore
677
*
678
*****************************************************************************/
679
680
acpi_status acpi_os_delete_semaphore(acpi_handle handle)
681
{
682
sem_t *sem = (sem_t *) handle;
683
684
if (!sem) {
685
return (AE_BAD_PARAMETER);
686
}
687
#ifdef __APPLE__
688
if (sem_close(sem) == -1) {
689
return (AE_BAD_PARAMETER);
690
}
691
#else
692
if (sem_destroy(sem) == -1) {
693
return (AE_BAD_PARAMETER);
694
}
695
#endif
696
697
return (AE_OK);
698
}
699
700
/******************************************************************************
701
*
702
* FUNCTION: acpi_os_wait_semaphore
703
*
704
* PARAMETERS: handle - Handle returned by acpi_os_create_semaphore
705
* units - How many units to wait for
706
* msec_timeout - How long to wait (milliseconds)
707
*
708
* RETURN: Status
709
*
710
* DESCRIPTION: Wait for units
711
*
712
*****************************************************************************/
713
714
acpi_status
715
acpi_os_wait_semaphore(acpi_handle handle, u32 units, u16 msec_timeout)
716
{
717
acpi_status status = AE_OK;
718
sem_t *sem = (sem_t *) handle;
719
int ret_val;
720
#ifndef ACPI_USE_ALTERNATE_TIMEOUT
721
struct timespec time;
722
#endif
723
724
if (!sem) {
725
return (AE_BAD_PARAMETER);
726
}
727
728
switch (msec_timeout) {
729
/*
730
* No Wait:
731
* --------
732
* A zero timeout value indicates that we shouldn't wait - just
733
* acquire the semaphore if available otherwise return AE_TIME
734
* (a.k.a. 'would block').
735
*/
736
case 0:
737
738
if (sem_trywait(sem) == -1) {
739
status = (AE_TIME);
740
}
741
break;
742
743
/* Wait Indefinitely */
744
745
case ACPI_WAIT_FOREVER:
746
747
while (((ret_val = sem_wait(sem)) == -1) && (errno == EINTR)) {
748
continue; /* Restart if interrupted */
749
}
750
if (ret_val != 0) {
751
status = (AE_TIME);
752
}
753
break;
754
755
/* Wait with msec_timeout */
756
757
default:
758
759
#ifdef ACPI_USE_ALTERNATE_TIMEOUT
760
/*
761
* Alternate timeout mechanism for environments where
762
* sem_timedwait is not available or does not work properly.
763
*/
764
while (msec_timeout) {
765
if (sem_trywait(sem) == 0) {
766
767
/* Got the semaphore */
768
return (AE_OK);
769
}
770
771
if (msec_timeout >= 10) {
772
msec_timeout -= 10;
773
usleep(10 * ACPI_USEC_PER_MSEC); /* ten milliseconds */
774
} else {
775
msec_timeout--;
776
usleep(ACPI_USEC_PER_MSEC); /* one millisecond */
777
}
778
}
779
status = (AE_TIME);
780
#else
781
/*
782
* The interface to sem_timedwait is an absolute time, so we need to
783
* get the current time, then add in the millisecond Timeout value.
784
*/
785
if (clock_gettime(CLOCK_REALTIME, &time) == -1) {
786
perror("clock_gettime");
787
return (AE_TIME);
788
}
789
790
time.tv_sec += (msec_timeout / ACPI_MSEC_PER_SEC);
791
time.tv_nsec +=
792
((msec_timeout % ACPI_MSEC_PER_SEC) * ACPI_NSEC_PER_MSEC);
793
794
/* Handle nanosecond overflow (field must be less than one second) */
795
796
if (time.tv_nsec >= ACPI_NSEC_PER_SEC) {
797
time.tv_sec += (time.tv_nsec / ACPI_NSEC_PER_SEC);
798
time.tv_nsec = (time.tv_nsec % ACPI_NSEC_PER_SEC);
799
}
800
801
while (((ret_val = sem_timedwait(sem, &time)) == -1)
802
&& (errno == EINTR)) {
803
continue; /* Restart if interrupted */
804
805
}
806
807
if (ret_val != 0) {
808
if (errno != ETIMEDOUT) {
809
perror("sem_timedwait");
810
}
811
status = (AE_TIME);
812
}
813
#endif
814
break;
815
}
816
817
return (status);
818
}
819
820
/******************************************************************************
821
*
822
* FUNCTION: acpi_os_signal_semaphore
823
*
824
* PARAMETERS: handle - Handle returned by acpi_os_create_semaphore
825
* units - Number of units to send
826
*
827
* RETURN: Status
828
*
829
* DESCRIPTION: Send units
830
*
831
*****************************************************************************/
832
833
acpi_status acpi_os_signal_semaphore(acpi_handle handle, u32 units)
834
{
835
sem_t *sem = (sem_t *) handle;
836
837
if (!sem) {
838
return (AE_BAD_PARAMETER);
839
}
840
841
if (sem_post(sem) == -1) {
842
return (AE_LIMIT);
843
}
844
845
return (AE_OK);
846
}
847
848
#endif /* ACPI_SINGLE_THREADED */
849
850
/******************************************************************************
851
*
852
* FUNCTION: Spinlock interfaces
853
*
854
* DESCRIPTION: Map these interfaces to semaphore interfaces
855
*
856
*****************************************************************************/
857
858
acpi_status acpi_os_create_lock(acpi_spinlock * out_handle)
859
{
860
861
return (acpi_os_create_semaphore(1, 1, out_handle));
862
}
863
864
void acpi_os_delete_lock(acpi_spinlock handle)
865
{
866
acpi_os_delete_semaphore(handle);
867
}
868
869
acpi_cpu_flags acpi_os_acquire_lock(acpi_handle handle)
870
{
871
acpi_os_wait_semaphore(handle, 1, 0xFFFF);
872
return (0);
873
}
874
875
void acpi_os_release_lock(acpi_spinlock handle, acpi_cpu_flags flags)
876
{
877
acpi_os_signal_semaphore(handle, 1);
878
}
879
880
/******************************************************************************
881
*
882
* FUNCTION: acpi_os_install_interrupt_handler
883
*
884
* PARAMETERS: interrupt_number - Level handler should respond to.
885
* isr - Address of the ACPI interrupt handler
886
* except_ptr - Where status is returned
887
*
888
* RETURN: Handle to the newly installed handler.
889
*
890
* DESCRIPTION: Install an interrupt handler. Used to install the ACPI
891
* OS-independent handler.
892
*
893
*****************************************************************************/
894
895
u32
896
acpi_os_install_interrupt_handler(u32 interrupt_number,
897
acpi_osd_handler service_routine,
898
void *context)
899
{
900
901
return (AE_OK);
902
}
903
904
/******************************************************************************
905
*
906
* FUNCTION: acpi_os_remove_interrupt_handler
907
*
908
* PARAMETERS: handle - Returned when handler was installed
909
*
910
* RETURN: Status
911
*
912
* DESCRIPTION: Uninstalls an interrupt handler.
913
*
914
*****************************************************************************/
915
916
acpi_status
917
acpi_os_remove_interrupt_handler(u32 interrupt_number,
918
acpi_osd_handler service_routine)
919
{
920
921
return (AE_OK);
922
}
923
924
/******************************************************************************
925
*
926
* FUNCTION: acpi_os_stall
927
*
928
* PARAMETERS: microseconds - Time to sleep
929
*
930
* RETURN: Blocks until sleep is completed.
931
*
932
* DESCRIPTION: Sleep at microsecond granularity
933
*
934
*****************************************************************************/
935
936
void acpi_os_stall(u32 microseconds)
937
{
938
939
if (microseconds) {
940
usleep(microseconds);
941
}
942
}
943
944
/******************************************************************************
945
*
946
* FUNCTION: acpi_os_sleep
947
*
948
* PARAMETERS: milliseconds - Time to sleep
949
*
950
* RETURN: Blocks until sleep is completed.
951
*
952
* DESCRIPTION: Sleep at millisecond granularity
953
*
954
*****************************************************************************/
955
956
void acpi_os_sleep(u64 milliseconds)
957
{
958
959
/* Sleep for whole seconds */
960
961
sleep(milliseconds / ACPI_MSEC_PER_SEC);
962
963
/*
964
* Sleep for remaining microseconds.
965
* Arg to usleep() is in usecs and must be less than 1,000,000 (1 second).
966
*/
967
usleep((milliseconds % ACPI_MSEC_PER_SEC) * ACPI_USEC_PER_MSEC);
968
}
969
970
/******************************************************************************
971
*
972
* FUNCTION: acpi_os_get_timer
973
*
974
* PARAMETERS: None
975
*
976
* RETURN: Current time in 100 nanosecond units
977
*
978
* DESCRIPTION: Get the current system time
979
*
980
*****************************************************************************/
981
982
u64 acpi_os_get_timer(void)
983
{
984
struct timeval time;
985
986
/* This timer has sufficient resolution for user-space application code */
987
988
gettimeofday(&time, NULL);
989
990
/* (Seconds * 10^7 = 100ns(10^-7)) + (Microseconds(10^-6) * 10^1 = 100ns) */
991
992
return (((u64)time.tv_sec * ACPI_100NSEC_PER_SEC) +
993
((u64)time.tv_usec * ACPI_100NSEC_PER_USEC));
994
}
995
996
/******************************************************************************
997
*
998
* FUNCTION: acpi_os_read_pci_configuration
999
*
1000
* PARAMETERS: pci_id - Seg/Bus/Dev
1001
* pci_register - Device Register
1002
* value - Buffer where value is placed
1003
* width - Number of bits
1004
*
1005
* RETURN: Status
1006
*
1007
* DESCRIPTION: Read data from PCI configuration space
1008
*
1009
*****************************************************************************/
1010
1011
acpi_status
1012
acpi_os_read_pci_configuration(struct acpi_pci_id *pci_id,
1013
u32 pci_register, u64 *value, u32 width)
1014
{
1015
1016
*value = 0;
1017
return (AE_OK);
1018
}
1019
1020
/******************************************************************************
1021
*
1022
* FUNCTION: acpi_os_write_pci_configuration
1023
*
1024
* PARAMETERS: pci_id - Seg/Bus/Dev
1025
* pci_register - Device Register
1026
* value - Value to be written
1027
* width - Number of bits
1028
*
1029
* RETURN: Status.
1030
*
1031
* DESCRIPTION: Write data to PCI configuration space
1032
*
1033
*****************************************************************************/
1034
1035
acpi_status
1036
acpi_os_write_pci_configuration(struct acpi_pci_id *pci_id,
1037
u32 pci_register, u64 value, u32 width)
1038
{
1039
1040
return (AE_OK);
1041
}
1042
1043
/******************************************************************************
1044
*
1045
* FUNCTION: acpi_os_read_port
1046
*
1047
* PARAMETERS: address - Address of I/O port/register to read
1048
* value - Where value is placed
1049
* width - Number of bits
1050
*
1051
* RETURN: Value read from port
1052
*
1053
* DESCRIPTION: Read data from an I/O port or register
1054
*
1055
*****************************************************************************/
1056
1057
acpi_status acpi_os_read_port(acpi_io_address address, u32 *value, u32 width)
1058
{
1059
1060
switch (width) {
1061
case 8:
1062
1063
*value = 0xFF;
1064
break;
1065
1066
case 16:
1067
1068
*value = 0xFFFF;
1069
break;
1070
1071
case 32:
1072
1073
*value = 0xFFFFFFFF;
1074
break;
1075
1076
default:
1077
1078
return (AE_BAD_PARAMETER);
1079
}
1080
1081
return (AE_OK);
1082
}
1083
1084
/******************************************************************************
1085
*
1086
* FUNCTION: acpi_os_write_port
1087
*
1088
* PARAMETERS: address - Address of I/O port/register to write
1089
* value - Value to write
1090
* width - Number of bits
1091
*
1092
* RETURN: None
1093
*
1094
* DESCRIPTION: Write data to an I/O port or register
1095
*
1096
*****************************************************************************/
1097
1098
acpi_status acpi_os_write_port(acpi_io_address address, u32 value, u32 width)
1099
{
1100
1101
return (AE_OK);
1102
}
1103
1104
/******************************************************************************
1105
*
1106
* FUNCTION: acpi_os_read_memory
1107
*
1108
* PARAMETERS: address - Physical Memory Address to read
1109
* value - Where value is placed
1110
* width - Number of bits (8,16,32, or 64)
1111
*
1112
* RETURN: Value read from physical memory address. Always returned
1113
* as a 64-bit integer, regardless of the read width.
1114
*
1115
* DESCRIPTION: Read data from a physical memory address
1116
*
1117
*****************************************************************************/
1118
1119
acpi_status
1120
acpi_os_read_memory(acpi_physical_address address, u64 *value, u32 width)
1121
{
1122
1123
switch (width) {
1124
case 8:
1125
case 16:
1126
case 32:
1127
case 64:
1128
1129
*value = 0;
1130
break;
1131
1132
default:
1133
1134
return (AE_BAD_PARAMETER);
1135
}
1136
return (AE_OK);
1137
}
1138
1139
/******************************************************************************
1140
*
1141
* FUNCTION: acpi_os_write_memory
1142
*
1143
* PARAMETERS: address - Physical Memory Address to write
1144
* value - Value to write
1145
* width - Number of bits (8,16,32, or 64)
1146
*
1147
* RETURN: None
1148
*
1149
* DESCRIPTION: Write data to a physical memory address
1150
*
1151
*****************************************************************************/
1152
1153
acpi_status
1154
acpi_os_write_memory(acpi_physical_address address, u64 value, u32 width)
1155
{
1156
1157
return (AE_OK);
1158
}
1159
1160
/******************************************************************************
1161
*
1162
* FUNCTION: acpi_os_readable
1163
*
1164
* PARAMETERS: pointer - Area to be verified
1165
* length - Size of area
1166
*
1167
* RETURN: TRUE if readable for entire length
1168
*
1169
* DESCRIPTION: Verify that a pointer is valid for reading
1170
*
1171
*****************************************************************************/
1172
1173
u8 acpi_os_readable(void *pointer, acpi_size length)
1174
{
1175
1176
return (TRUE);
1177
}
1178
1179
/******************************************************************************
1180
*
1181
* FUNCTION: acpi_os_writable
1182
*
1183
* PARAMETERS: pointer - Area to be verified
1184
* length - Size of area
1185
*
1186
* RETURN: TRUE if writable for entire length
1187
*
1188
* DESCRIPTION: Verify that a pointer is valid for writing
1189
*
1190
*****************************************************************************/
1191
1192
u8 acpi_os_writable(void *pointer, acpi_size length)
1193
{
1194
1195
return (TRUE);
1196
}
1197
1198
/******************************************************************************
1199
*
1200
* FUNCTION: acpi_os_signal
1201
*
1202
* PARAMETERS: function - ACPI A signal function code
1203
* info - Pointer to function-dependent structure
1204
*
1205
* RETURN: Status
1206
*
1207
* DESCRIPTION: Miscellaneous functions. Example implementation only.
1208
*
1209
*****************************************************************************/
1210
1211
acpi_status acpi_os_signal(u32 function, void *info)
1212
{
1213
1214
switch (function) {
1215
case ACPI_SIGNAL_FATAL:
1216
1217
break;
1218
1219
case ACPI_SIGNAL_BREAKPOINT:
1220
1221
break;
1222
1223
default:
1224
1225
break;
1226
}
1227
1228
return (AE_OK);
1229
}
1230
1231
/* Optional multi-thread support */
1232
1233
#ifndef ACPI_SINGLE_THREADED
1234
/******************************************************************************
1235
*
1236
* FUNCTION: acpi_os_get_thread_id
1237
*
1238
* PARAMETERS: None
1239
*
1240
* RETURN: Id of the running thread
1241
*
1242
* DESCRIPTION: Get the ID of the current (running) thread
1243
*
1244
*****************************************************************************/
1245
1246
acpi_thread_id acpi_os_get_thread_id(void)
1247
{
1248
pthread_t thread;
1249
1250
thread = pthread_self();
1251
return (ACPI_CAST_PTHREAD_T(thread));
1252
}
1253
1254
/******************************************************************************
1255
*
1256
* FUNCTION: acpi_os_execute
1257
*
1258
* PARAMETERS: type - Type of execution
1259
* function - Address of the function to execute
1260
* context - Passed as a parameter to the function
1261
*
1262
* RETURN: Status.
1263
*
1264
* DESCRIPTION: Execute a new thread
1265
*
1266
*****************************************************************************/
1267
1268
acpi_status
1269
acpi_os_execute(acpi_execute_type type,
1270
acpi_osd_exec_callback function, void *context)
1271
{
1272
pthread_t thread;
1273
int ret;
1274
1275
ret =
1276
pthread_create(&thread, NULL, (PTHREAD_CALLBACK) function, context);
1277
if (ret) {
1278
acpi_os_printf("Create thread failed");
1279
}
1280
return (0);
1281
}
1282
1283
#else /* ACPI_SINGLE_THREADED */
1284
acpi_thread_id acpi_os_get_thread_id(void)
1285
{
1286
return (1);
1287
}
1288
1289
acpi_status
1290
acpi_os_execute(acpi_execute_type type,
1291
acpi_osd_exec_callback function, void *context)
1292
{
1293
1294
function(context);
1295
1296
return (AE_OK);
1297
}
1298
1299
#endif /* ACPI_SINGLE_THREADED */
1300
1301
/******************************************************************************
1302
*
1303
* FUNCTION: acpi_os_wait_events_complete
1304
*
1305
* PARAMETERS: None
1306
*
1307
* RETURN: None
1308
*
1309
* DESCRIPTION: Wait for all asynchronous events to complete. This
1310
* implementation does nothing.
1311
*
1312
*****************************************************************************/
1313
1314
void acpi_os_wait_events_complete(void)
1315
{
1316
return;
1317
}
1318
1319