![]() |
|
|||
0001 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 0002 /****************************************************************************** 0003 * 0004 * Module Name: osunixxf - UNIX OSL interfaces 0005 * 0006 * Copyright (C) 2000 - 2022, Intel Corp. 0007 * 0008 *****************************************************************************/ 0009 0010 /* 0011 * These interfaces are required in order to compile the ASL compiler and the 0012 * various ACPICA tools under Linux or other Unix-like system. 0013 */ 0014 #include <acpi/acpi.h> 0015 #include "accommon.h" 0016 #include "amlcode.h" 0017 #include "acparser.h" 0018 #include "acdebug.h" 0019 0020 #include <stdio.h> 0021 #include <stdlib.h> 0022 #include <stdarg.h> 0023 #include <unistd.h> 0024 #include <sys/time.h> 0025 #include <semaphore.h> 0026 #include <pthread.h> 0027 #include <errno.h> 0028 0029 #define _COMPONENT ACPI_OS_SERVICES 0030 ACPI_MODULE_NAME("osunixxf") 0031 0032 /* Upcalls to acpi_exec */ 0033 void 0034 ae_table_override(struct acpi_table_header *existing_table, 0035 struct acpi_table_header **new_table); 0036 0037 typedef void *(*PTHREAD_CALLBACK) (void *); 0038 0039 /* Buffer used by acpi_os_vprintf */ 0040 0041 #define ACPI_VPRINTF_BUFFER_SIZE 512 0042 #define _ASCII_NEWLINE '\n' 0043 0044 /* Terminal support for acpi_exec only */ 0045 0046 #ifdef ACPI_EXEC_APP 0047 #include <termios.h> 0048 0049 struct termios original_term_attributes; 0050 int term_attributes_were_set = 0; 0051 0052 acpi_status acpi_ut_read_line(char *buffer, u32 buffer_length, u32 *bytes_read); 0053 0054 static void os_enter_line_edit_mode(void); 0055 0056 static void os_exit_line_edit_mode(void); 0057 0058 /****************************************************************************** 0059 * 0060 * FUNCTION: os_enter_line_edit_mode, os_exit_line_edit_mode 0061 * 0062 * PARAMETERS: None 0063 * 0064 * RETURN: None 0065 * 0066 * DESCRIPTION: Enter/Exit the raw character input mode for the terminal. 0067 * 0068 * Interactive line-editing support for the AML debugger. Used with the 0069 * common/acgetline module. 0070 * 0071 * readline() is not used because of non-portability. It is not available 0072 * on all systems, and if it is, often the package must be manually installed. 0073 * 0074 * Therefore, we use the POSIX tcgetattr/tcsetattr and do the minimal line 0075 * editing that we need in acpi_os_get_line. 0076 * 0077 * If the POSIX tcgetattr/tcsetattr interfaces are unavailable, these 0078 * calls will also work: 0079 * For os_enter_line_edit_mode: system ("stty cbreak -echo") 0080 * For os_exit_line_edit_mode: system ("stty cooked echo") 0081 * 0082 *****************************************************************************/ 0083 0084 static void os_enter_line_edit_mode(void) 0085 { 0086 struct termios local_term_attributes; 0087 0088 term_attributes_were_set = 0; 0089 0090 /* STDIN must be a terminal */ 0091 0092 if (!isatty(STDIN_FILENO)) { 0093 return; 0094 } 0095 0096 /* Get and keep the original attributes */ 0097 0098 if (tcgetattr(STDIN_FILENO, &original_term_attributes)) { 0099 fprintf(stderr, "Could not get terminal attributes!\n"); 0100 return; 0101 } 0102 0103 /* Set the new attributes to enable raw character input */ 0104 0105 memcpy(&local_term_attributes, &original_term_attributes, 0106 sizeof(struct termios)); 0107 0108 local_term_attributes.c_lflag &= ~(ICANON | ECHO); 0109 local_term_attributes.c_cc[VMIN] = 1; 0110 local_term_attributes.c_cc[VTIME] = 0; 0111 0112 if (tcsetattr(STDIN_FILENO, TCSANOW, &local_term_attributes)) { 0113 fprintf(stderr, "Could not set terminal attributes!\n"); 0114 return; 0115 } 0116 0117 term_attributes_were_set = 1; 0118 } 0119 0120 static void os_exit_line_edit_mode(void) 0121 { 0122 0123 if (!term_attributes_were_set) { 0124 return; 0125 } 0126 0127 /* Set terminal attributes back to the original values */ 0128 0129 if (tcsetattr(STDIN_FILENO, TCSANOW, &original_term_attributes)) { 0130 fprintf(stderr, "Could not restore terminal attributes!\n"); 0131 } 0132 } 0133 0134 #else 0135 0136 /* These functions are not needed for other ACPICA utilities */ 0137 0138 #define os_enter_line_edit_mode() 0139 #define os_exit_line_edit_mode() 0140 #endif 0141 0142 /****************************************************************************** 0143 * 0144 * FUNCTION: acpi_os_initialize, acpi_os_terminate 0145 * 0146 * PARAMETERS: None 0147 * 0148 * RETURN: Status 0149 * 0150 * DESCRIPTION: Initialize and terminate this module. 0151 * 0152 *****************************************************************************/ 0153 0154 acpi_status acpi_os_initialize(void) 0155 { 0156 acpi_status status; 0157 0158 acpi_gbl_output_file = stdout; 0159 0160 os_enter_line_edit_mode(); 0161 0162 status = acpi_os_create_lock(&acpi_gbl_print_lock); 0163 if (ACPI_FAILURE(status)) { 0164 return (status); 0165 } 0166 0167 return (AE_OK); 0168 } 0169 0170 acpi_status acpi_os_terminate(void) 0171 { 0172 0173 os_exit_line_edit_mode(); 0174 return (AE_OK); 0175 } 0176 0177 #ifndef ACPI_USE_NATIVE_RSDP_POINTER 0178 /****************************************************************************** 0179 * 0180 * FUNCTION: acpi_os_get_root_pointer 0181 * 0182 * PARAMETERS: None 0183 * 0184 * RETURN: RSDP physical address 0185 * 0186 * DESCRIPTION: Gets the ACPI root pointer (RSDP) 0187 * 0188 *****************************************************************************/ 0189 0190 acpi_physical_address acpi_os_get_root_pointer(void) 0191 { 0192 0193 return (0); 0194 } 0195 #endif 0196 0197 /****************************************************************************** 0198 * 0199 * FUNCTION: acpi_os_predefined_override 0200 * 0201 * PARAMETERS: init_val - Initial value of the predefined object 0202 * new_val - The new value for the object 0203 * 0204 * RETURN: Status, pointer to value. Null pointer returned if not 0205 * overriding. 0206 * 0207 * DESCRIPTION: Allow the OS to override predefined names 0208 * 0209 *****************************************************************************/ 0210 0211 acpi_status 0212 acpi_os_predefined_override(const struct acpi_predefined_names *init_val, 0213 acpi_string *new_val) 0214 { 0215 0216 if (!init_val || !new_val) { 0217 return (AE_BAD_PARAMETER); 0218 } 0219 0220 *new_val = NULL; 0221 return (AE_OK); 0222 } 0223 0224 /****************************************************************************** 0225 * 0226 * FUNCTION: acpi_os_table_override 0227 * 0228 * PARAMETERS: existing_table - Header of current table (probably 0229 * firmware) 0230 * new_table - Where an entire new table is returned. 0231 * 0232 * RETURN: Status, pointer to new table. Null pointer returned if no 0233 * table is available to override 0234 * 0235 * DESCRIPTION: Return a different version of a table if one is available 0236 * 0237 *****************************************************************************/ 0238 0239 acpi_status 0240 acpi_os_table_override(struct acpi_table_header *existing_table, 0241 struct acpi_table_header **new_table) 0242 { 0243 0244 if (!existing_table || !new_table) { 0245 return (AE_BAD_PARAMETER); 0246 } 0247 0248 *new_table = NULL; 0249 0250 #ifdef ACPI_EXEC_APP 0251 0252 ae_table_override(existing_table, new_table); 0253 return (AE_OK); 0254 #else 0255 0256 return (AE_NO_ACPI_TABLES); 0257 #endif 0258 } 0259 0260 /****************************************************************************** 0261 * 0262 * FUNCTION: acpi_os_physical_table_override 0263 * 0264 * PARAMETERS: existing_table - Header of current table (probably firmware) 0265 * new_address - Where new table address is returned 0266 * (Physical address) 0267 * new_table_length - Where new table length is returned 0268 * 0269 * RETURN: Status, address/length of new table. Null pointer returned 0270 * if no table is available to override. 0271 * 0272 * DESCRIPTION: Returns AE_SUPPORT, function not used in user space. 0273 * 0274 *****************************************************************************/ 0275 0276 acpi_status 0277 acpi_os_physical_table_override(struct acpi_table_header *existing_table, 0278 acpi_physical_address *new_address, 0279 u32 *new_table_length) 0280 { 0281 0282 return (AE_SUPPORT); 0283 } 0284 0285 /****************************************************************************** 0286 * 0287 * FUNCTION: acpi_os_enter_sleep 0288 * 0289 * PARAMETERS: sleep_state - Which sleep state to enter 0290 * rega_value - Register A value 0291 * regb_value - Register B value 0292 * 0293 * RETURN: Status 0294 * 0295 * DESCRIPTION: A hook before writing sleep registers to enter the sleep 0296 * state. Return AE_CTRL_TERMINATE to skip further sleep register 0297 * writes. 0298 * 0299 *****************************************************************************/ 0300 0301 acpi_status acpi_os_enter_sleep(u8 sleep_state, u32 rega_value, u32 regb_value) 0302 { 0303 0304 return (AE_OK); 0305 } 0306 0307 /****************************************************************************** 0308 * 0309 * FUNCTION: acpi_os_redirect_output 0310 * 0311 * PARAMETERS: destination - An open file handle/pointer 0312 * 0313 * RETURN: None 0314 * 0315 * DESCRIPTION: Causes redirect of acpi_os_printf and acpi_os_vprintf 0316 * 0317 *****************************************************************************/ 0318 0319 void acpi_os_redirect_output(void *destination) 0320 { 0321 0322 acpi_gbl_output_file = destination; 0323 } 0324 0325 /****************************************************************************** 0326 * 0327 * FUNCTION: acpi_os_printf 0328 * 0329 * PARAMETERS: fmt, ... - Standard printf format 0330 * 0331 * RETURN: None 0332 * 0333 * DESCRIPTION: Formatted output. Note: very similar to acpi_os_vprintf 0334 * (performance), changes should be tracked in both functions. 0335 * 0336 *****************************************************************************/ 0337 0338 void ACPI_INTERNAL_VAR_XFACE acpi_os_printf(const char *fmt, ...) 0339 { 0340 va_list args; 0341 u8 flags; 0342 0343 flags = acpi_gbl_db_output_flags; 0344 if (flags & ACPI_DB_REDIRECTABLE_OUTPUT) { 0345 0346 /* Output is directable to either a file (if open) or the console */ 0347 0348 if (acpi_gbl_debug_file) { 0349 0350 /* Output file is open, send the output there */ 0351 0352 va_start(args, fmt); 0353 vfprintf(acpi_gbl_debug_file, fmt, args); 0354 va_end(args); 0355 } else { 0356 /* No redirection, send output to console (once only!) */ 0357 0358 flags |= ACPI_DB_CONSOLE_OUTPUT; 0359 } 0360 } 0361 0362 if (flags & ACPI_DB_CONSOLE_OUTPUT) { 0363 va_start(args, fmt); 0364 vfprintf(acpi_gbl_output_file, fmt, args); 0365 va_end(args); 0366 } 0367 } 0368 0369 /****************************************************************************** 0370 * 0371 * FUNCTION: acpi_os_vprintf 0372 * 0373 * PARAMETERS: fmt - Standard printf format 0374 * args - Argument list 0375 * 0376 * RETURN: None 0377 * 0378 * DESCRIPTION: Formatted output with argument list pointer. Note: very 0379 * similar to acpi_os_printf, changes should be tracked in both 0380 * functions. 0381 * 0382 *****************************************************************************/ 0383 0384 void acpi_os_vprintf(const char *fmt, va_list args) 0385 { 0386 u8 flags; 0387 char buffer[ACPI_VPRINTF_BUFFER_SIZE]; 0388 0389 /* 0390 * We build the output string in a local buffer because we may be 0391 * outputting the buffer twice. Using vfprintf is problematic because 0392 * some implementations modify the args pointer/structure during 0393 * execution. Thus, we use the local buffer for portability. 0394 * 0395 * Note: Since this module is intended for use by the various ACPICA 0396 * utilities/applications, we can safely declare the buffer on the stack. 0397 * Also, This function is used for relatively small error messages only. 0398 */ 0399 vsnprintf(buffer, ACPI_VPRINTF_BUFFER_SIZE, fmt, args); 0400 0401 flags = acpi_gbl_db_output_flags; 0402 if (flags & ACPI_DB_REDIRECTABLE_OUTPUT) { 0403 0404 /* Output is directable to either a file (if open) or the console */ 0405 0406 if (acpi_gbl_debug_file) { 0407 0408 /* Output file is open, send the output there */ 0409 0410 fputs(buffer, acpi_gbl_debug_file); 0411 } else { 0412 /* No redirection, send output to console (once only!) */ 0413 0414 flags |= ACPI_DB_CONSOLE_OUTPUT; 0415 } 0416 } 0417 0418 if (flags & ACPI_DB_CONSOLE_OUTPUT) { 0419 fputs(buffer, acpi_gbl_output_file); 0420 } 0421 } 0422 0423 #ifndef ACPI_EXEC_APP 0424 /****************************************************************************** 0425 * 0426 * FUNCTION: acpi_os_get_line 0427 * 0428 * PARAMETERS: buffer - Where to return the command line 0429 * buffer_length - Maximum length of Buffer 0430 * bytes_read - Where the actual byte count is returned 0431 * 0432 * RETURN: Status and actual bytes read 0433 * 0434 * DESCRIPTION: Get the next input line from the terminal. NOTE: For the 0435 * acpi_exec utility, we use the acgetline module instead to 0436 * provide line-editing and history support. 0437 * 0438 *****************************************************************************/ 0439 0440 acpi_status acpi_os_get_line(char *buffer, u32 buffer_length, u32 *bytes_read) 0441 { 0442 int input_char; 0443 u32 end_of_line; 0444 0445 /* Standard acpi_os_get_line for all utilities except acpi_exec */ 0446 0447 for (end_of_line = 0;; end_of_line++) { 0448 if (end_of_line >= buffer_length) { 0449 return (AE_BUFFER_OVERFLOW); 0450 } 0451 0452 if ((input_char = getchar()) == EOF) { 0453 return (AE_ERROR); 0454 } 0455 0456 if (!input_char || input_char == _ASCII_NEWLINE) { 0457 break; 0458 } 0459 0460 buffer[end_of_line] = (char)input_char; 0461 } 0462 0463 /* Null terminate the buffer */ 0464 0465 buffer[end_of_line] = 0; 0466 0467 /* Return the number of bytes in the string */ 0468 0469 if (bytes_read) { 0470 *bytes_read = end_of_line; 0471 } 0472 0473 return (AE_OK); 0474 } 0475 #endif 0476 0477 #ifndef ACPI_USE_NATIVE_MEMORY_MAPPING 0478 /****************************************************************************** 0479 * 0480 * FUNCTION: acpi_os_map_memory 0481 * 0482 * PARAMETERS: where - Physical address of memory to be mapped 0483 * length - How much memory to map 0484 * 0485 * RETURN: Pointer to mapped memory. Null on error. 0486 * 0487 * DESCRIPTION: Map physical memory into caller's address space 0488 * 0489 *****************************************************************************/ 0490 0491 void *acpi_os_map_memory(acpi_physical_address where, acpi_size length) 0492 { 0493 0494 return (ACPI_TO_POINTER((acpi_size)where)); 0495 } 0496 0497 /****************************************************************************** 0498 * 0499 * FUNCTION: acpi_os_unmap_memory 0500 * 0501 * PARAMETERS: where - Logical address of memory to be unmapped 0502 * length - How much memory to unmap 0503 * 0504 * RETURN: None. 0505 * 0506 * DESCRIPTION: Delete a previously created mapping. Where and Length must 0507 * correspond to a previous mapping exactly. 0508 * 0509 *****************************************************************************/ 0510 0511 void acpi_os_unmap_memory(void *where, acpi_size length) 0512 { 0513 0514 return; 0515 } 0516 #endif 0517 0518 /****************************************************************************** 0519 * 0520 * FUNCTION: acpi_os_allocate 0521 * 0522 * PARAMETERS: size - Amount to allocate, in bytes 0523 * 0524 * RETURN: Pointer to the new allocation. Null on error. 0525 * 0526 * DESCRIPTION: Allocate memory. Algorithm is dependent on the OS. 0527 * 0528 *****************************************************************************/ 0529 0530 void *acpi_os_allocate(acpi_size size) 0531 { 0532 void *mem; 0533 0534 mem = (void *)malloc((size_t) size); 0535 return (mem); 0536 } 0537 0538 #ifdef USE_NATIVE_ALLOCATE_ZEROED 0539 /****************************************************************************** 0540 * 0541 * FUNCTION: acpi_os_allocate_zeroed 0542 * 0543 * PARAMETERS: size - Amount to allocate, in bytes 0544 * 0545 * RETURN: Pointer to the new allocation. Null on error. 0546 * 0547 * DESCRIPTION: Allocate and zero memory. Algorithm is dependent on the OS. 0548 * 0549 *****************************************************************************/ 0550 0551 void *acpi_os_allocate_zeroed(acpi_size size) 0552 { 0553 void *mem; 0554 0555 mem = (void *)calloc(1, (size_t) size); 0556 return (mem); 0557 } 0558 #endif 0559 0560 /****************************************************************************** 0561 * 0562 * FUNCTION: acpi_os_free 0563 * 0564 * PARAMETERS: mem - Pointer to previously allocated memory 0565 * 0566 * RETURN: None. 0567 * 0568 * DESCRIPTION: Free memory allocated via acpi_os_allocate 0569 * 0570 *****************************************************************************/ 0571 0572 void acpi_os_free(void *mem) 0573 { 0574 0575 free(mem); 0576 } 0577 0578 #ifdef ACPI_SINGLE_THREADED 0579 /****************************************************************************** 0580 * 0581 * FUNCTION: Semaphore stub functions 0582 * 0583 * DESCRIPTION: Stub functions used for single-thread applications that do 0584 * not require semaphore synchronization. Full implementations 0585 * of these functions appear after the stubs. 0586 * 0587 *****************************************************************************/ 0588 0589 acpi_status 0590 acpi_os_create_semaphore(u32 max_units, 0591 u32 initial_units, acpi_handle *out_handle) 0592 { 0593 *out_handle = (acpi_handle)1; 0594 return (AE_OK); 0595 } 0596 0597 acpi_status acpi_os_delete_semaphore(acpi_handle handle) 0598 { 0599 return (AE_OK); 0600 } 0601 0602 acpi_status acpi_os_wait_semaphore(acpi_handle handle, u32 units, u16 timeout) 0603 { 0604 return (AE_OK); 0605 } 0606 0607 acpi_status acpi_os_signal_semaphore(acpi_handle handle, u32 units) 0608 { 0609 return (AE_OK); 0610 } 0611 0612 #else 0613 /****************************************************************************** 0614 * 0615 * FUNCTION: acpi_os_create_semaphore 0616 * 0617 * PARAMETERS: initial_units - Units to be assigned to the new semaphore 0618 * out_handle - Where a handle will be returned 0619 * 0620 * RETURN: Status 0621 * 0622 * DESCRIPTION: Create an OS semaphore 0623 * 0624 *****************************************************************************/ 0625 0626 acpi_status 0627 acpi_os_create_semaphore(u32 max_units, 0628 u32 initial_units, acpi_handle *out_handle) 0629 { 0630 sem_t *sem; 0631 0632 if (!out_handle) { 0633 return (AE_BAD_PARAMETER); 0634 } 0635 #ifdef __APPLE__ 0636 { 0637 static int semaphore_count = 0; 0638 char semaphore_name[32]; 0639 0640 snprintf(semaphore_name, sizeof(semaphore_name), "acpi_sem_%d", 0641 semaphore_count++); 0642 printf("%s\n", semaphore_name); 0643 sem = 0644 sem_open(semaphore_name, O_EXCL | O_CREAT, 0755, 0645 initial_units); 0646 if (!sem) { 0647 return (AE_NO_MEMORY); 0648 } 0649 sem_unlink(semaphore_name); /* This just deletes the name */ 0650 } 0651 0652 #else 0653 sem = acpi_os_allocate(sizeof(sem_t)); 0654 if (!sem) { 0655 return (AE_NO_MEMORY); 0656 } 0657 0658 if (sem_init(sem, 0, initial_units) == -1) { 0659 acpi_os_free(sem); 0660 return (AE_BAD_PARAMETER); 0661 } 0662 #endif 0663 0664 *out_handle = (acpi_handle)sem; 0665 return (AE_OK); 0666 } 0667 0668 /****************************************************************************** 0669 * 0670 * FUNCTION: acpi_os_delete_semaphore 0671 * 0672 * PARAMETERS: handle - Handle returned by acpi_os_create_semaphore 0673 * 0674 * RETURN: Status 0675 * 0676 * DESCRIPTION: Delete an OS semaphore 0677 * 0678 *****************************************************************************/ 0679 0680 acpi_status acpi_os_delete_semaphore(acpi_handle handle) 0681 { 0682 sem_t *sem = (sem_t *) handle; 0683 0684 if (!sem) { 0685 return (AE_BAD_PARAMETER); 0686 } 0687 #ifdef __APPLE__ 0688 if (sem_close(sem) == -1) { 0689 return (AE_BAD_PARAMETER); 0690 } 0691 #else 0692 if (sem_destroy(sem) == -1) { 0693 return (AE_BAD_PARAMETER); 0694 } 0695 #endif 0696 0697 return (AE_OK); 0698 } 0699 0700 /****************************************************************************** 0701 * 0702 * FUNCTION: acpi_os_wait_semaphore 0703 * 0704 * PARAMETERS: handle - Handle returned by acpi_os_create_semaphore 0705 * units - How many units to wait for 0706 * msec_timeout - How long to wait (milliseconds) 0707 * 0708 * RETURN: Status 0709 * 0710 * DESCRIPTION: Wait for units 0711 * 0712 *****************************************************************************/ 0713 0714 acpi_status 0715 acpi_os_wait_semaphore(acpi_handle handle, u32 units, u16 msec_timeout) 0716 { 0717 acpi_status status = AE_OK; 0718 sem_t *sem = (sem_t *) handle; 0719 int ret_val; 0720 #ifndef ACPI_USE_ALTERNATE_TIMEOUT 0721 struct timespec time; 0722 #endif 0723 0724 if (!sem) { 0725 return (AE_BAD_PARAMETER); 0726 } 0727 0728 switch (msec_timeout) { 0729 /* 0730 * No Wait: 0731 * -------- 0732 * A zero timeout value indicates that we shouldn't wait - just 0733 * acquire the semaphore if available otherwise return AE_TIME 0734 * (a.k.a. 'would block'). 0735 */ 0736 case 0: 0737 0738 if (sem_trywait(sem) == -1) { 0739 status = (AE_TIME); 0740 } 0741 break; 0742 0743 /* Wait Indefinitely */ 0744 0745 case ACPI_WAIT_FOREVER: 0746 0747 while (((ret_val = sem_wait(sem)) == -1) && (errno == EINTR)) { 0748 continue; /* Restart if interrupted */ 0749 } 0750 if (ret_val != 0) { 0751 status = (AE_TIME); 0752 } 0753 break; 0754 0755 /* Wait with msec_timeout */ 0756 0757 default: 0758 0759 #ifdef ACPI_USE_ALTERNATE_TIMEOUT 0760 /* 0761 * Alternate timeout mechanism for environments where 0762 * sem_timedwait is not available or does not work properly. 0763 */ 0764 while (msec_timeout) { 0765 if (sem_trywait(sem) == 0) { 0766 0767 /* Got the semaphore */ 0768 return (AE_OK); 0769 } 0770 0771 if (msec_timeout >= 10) { 0772 msec_timeout -= 10; 0773 usleep(10 * ACPI_USEC_PER_MSEC); /* ten milliseconds */ 0774 } else { 0775 msec_timeout--; 0776 usleep(ACPI_USEC_PER_MSEC); /* one millisecond */ 0777 } 0778 } 0779 status = (AE_TIME); 0780 #else 0781 /* 0782 * The interface to sem_timedwait is an absolute time, so we need to 0783 * get the current time, then add in the millisecond Timeout value. 0784 */ 0785 if (clock_gettime(CLOCK_REALTIME, &time) == -1) { 0786 perror("clock_gettime"); 0787 return (AE_TIME); 0788 } 0789 0790 time.tv_sec += (msec_timeout / ACPI_MSEC_PER_SEC); 0791 time.tv_nsec += 0792 ((msec_timeout % ACPI_MSEC_PER_SEC) * ACPI_NSEC_PER_MSEC); 0793 0794 /* Handle nanosecond overflow (field must be less than one second) */ 0795 0796 if (time.tv_nsec >= ACPI_NSEC_PER_SEC) { 0797 time.tv_sec += (time.tv_nsec / ACPI_NSEC_PER_SEC); 0798 time.tv_nsec = (time.tv_nsec % ACPI_NSEC_PER_SEC); 0799 } 0800 0801 while (((ret_val = sem_timedwait(sem, &time)) == -1) 0802 && (errno == EINTR)) { 0803 continue; /* Restart if interrupted */ 0804 0805 } 0806 0807 if (ret_val != 0) { 0808 if (errno != ETIMEDOUT) { 0809 perror("sem_timedwait"); 0810 } 0811 status = (AE_TIME); 0812 } 0813 #endif 0814 break; 0815 } 0816 0817 return (status); 0818 } 0819 0820 /****************************************************************************** 0821 * 0822 * FUNCTION: acpi_os_signal_semaphore 0823 * 0824 * PARAMETERS: handle - Handle returned by acpi_os_create_semaphore 0825 * units - Number of units to send 0826 * 0827 * RETURN: Status 0828 * 0829 * DESCRIPTION: Send units 0830 * 0831 *****************************************************************************/ 0832 0833 acpi_status acpi_os_signal_semaphore(acpi_handle handle, u32 units) 0834 { 0835 sem_t *sem = (sem_t *) handle; 0836 0837 if (!sem) { 0838 return (AE_BAD_PARAMETER); 0839 } 0840 0841 if (sem_post(sem) == -1) { 0842 return (AE_LIMIT); 0843 } 0844 0845 return (AE_OK); 0846 } 0847 0848 #endif /* ACPI_SINGLE_THREADED */ 0849 0850 /****************************************************************************** 0851 * 0852 * FUNCTION: Spinlock interfaces 0853 * 0854 * DESCRIPTION: Map these interfaces to semaphore interfaces 0855 * 0856 *****************************************************************************/ 0857 0858 acpi_status acpi_os_create_lock(acpi_spinlock * out_handle) 0859 { 0860 0861 return (acpi_os_create_semaphore(1, 1, out_handle)); 0862 } 0863 0864 void acpi_os_delete_lock(acpi_spinlock handle) 0865 { 0866 acpi_os_delete_semaphore(handle); 0867 } 0868 0869 acpi_cpu_flags acpi_os_acquire_lock(acpi_handle handle) 0870 { 0871 acpi_os_wait_semaphore(handle, 1, 0xFFFF); 0872 return (0); 0873 } 0874 0875 void acpi_os_release_lock(acpi_spinlock handle, acpi_cpu_flags flags) 0876 { 0877 acpi_os_signal_semaphore(handle, 1); 0878 } 0879 0880 /****************************************************************************** 0881 * 0882 * FUNCTION: acpi_os_install_interrupt_handler 0883 * 0884 * PARAMETERS: interrupt_number - Level handler should respond to. 0885 * isr - Address of the ACPI interrupt handler 0886 * except_ptr - Where status is returned 0887 * 0888 * RETURN: Handle to the newly installed handler. 0889 * 0890 * DESCRIPTION: Install an interrupt handler. Used to install the ACPI 0891 * OS-independent handler. 0892 * 0893 *****************************************************************************/ 0894 0895 u32 0896 acpi_os_install_interrupt_handler(u32 interrupt_number, 0897 acpi_osd_handler service_routine, 0898 void *context) 0899 { 0900 0901 return (AE_OK); 0902 } 0903 0904 /****************************************************************************** 0905 * 0906 * FUNCTION: acpi_os_remove_interrupt_handler 0907 * 0908 * PARAMETERS: handle - Returned when handler was installed 0909 * 0910 * RETURN: Status 0911 * 0912 * DESCRIPTION: Uninstalls an interrupt handler. 0913 * 0914 *****************************************************************************/ 0915 0916 acpi_status 0917 acpi_os_remove_interrupt_handler(u32 interrupt_number, 0918 acpi_osd_handler service_routine) 0919 { 0920 0921 return (AE_OK); 0922 } 0923 0924 /****************************************************************************** 0925 * 0926 * FUNCTION: acpi_os_stall 0927 * 0928 * PARAMETERS: microseconds - Time to sleep 0929 * 0930 * RETURN: Blocks until sleep is completed. 0931 * 0932 * DESCRIPTION: Sleep at microsecond granularity 0933 * 0934 *****************************************************************************/ 0935 0936 void acpi_os_stall(u32 microseconds) 0937 { 0938 0939 if (microseconds) { 0940 usleep(microseconds); 0941 } 0942 } 0943 0944 /****************************************************************************** 0945 * 0946 * FUNCTION: acpi_os_sleep 0947 * 0948 * PARAMETERS: milliseconds - Time to sleep 0949 * 0950 * RETURN: Blocks until sleep is completed. 0951 * 0952 * DESCRIPTION: Sleep at millisecond granularity 0953 * 0954 *****************************************************************************/ 0955 0956 void acpi_os_sleep(u64 milliseconds) 0957 { 0958 0959 /* Sleep for whole seconds */ 0960 0961 sleep(milliseconds / ACPI_MSEC_PER_SEC); 0962 0963 /* 0964 * Sleep for remaining microseconds. 0965 * Arg to usleep() is in usecs and must be less than 1,000,000 (1 second). 0966 */ 0967 usleep((milliseconds % ACPI_MSEC_PER_SEC) * ACPI_USEC_PER_MSEC); 0968 } 0969 0970 /****************************************************************************** 0971 * 0972 * FUNCTION: acpi_os_get_timer 0973 * 0974 * PARAMETERS: None 0975 * 0976 * RETURN: Current time in 100 nanosecond units 0977 * 0978 * DESCRIPTION: Get the current system time 0979 * 0980 *****************************************************************************/ 0981 0982 u64 acpi_os_get_timer(void) 0983 { 0984 struct timeval time; 0985 0986 /* This timer has sufficient resolution for user-space application code */ 0987 0988 gettimeofday(&time, NULL); 0989 0990 /* (Seconds * 10^7 = 100ns(10^-7)) + (Microseconds(10^-6) * 10^1 = 100ns) */ 0991 0992 return (((u64)time.tv_sec * ACPI_100NSEC_PER_SEC) + 0993 ((u64)time.tv_usec * ACPI_100NSEC_PER_USEC)); 0994 } 0995 0996 /****************************************************************************** 0997 * 0998 * FUNCTION: acpi_os_read_pci_configuration 0999 * 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 }
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.1.0 LXR engine. The LXR team |
![]() ![]() |