1318 lines · c
1// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.02/******************************************************************************3 *4 * Module Name: osunixxf - UNIX OSL interfaces5 *6 * Copyright (C) 2000 - 2023, Intel Corp.7 *8 *****************************************************************************/9 10/*11 * These interfaces are required in order to compile the ASL compiler and the12 * 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_SERVICES30ACPI_MODULE_NAME("osunixxf")31 32/* Upcalls to acpi_exec */33void34ae_table_override(struct acpi_table_header *existing_table,35 struct acpi_table_header **new_table);36 37typedef void *(*PTHREAD_CALLBACK) (void *);38 39/* Buffer used by acpi_os_vprintf */40 41#define ACPI_VPRINTF_BUFFER_SIZE 51242#define _ASCII_NEWLINE '\n'43 44/* Terminal support for acpi_exec only */45 46#ifdef ACPI_EXEC_APP47#include <termios.h>48 49struct termios original_term_attributes;50int term_attributes_were_set = 0;51 52acpi_status acpi_ut_read_line(char *buffer, u32 buffer_length, u32 *bytes_read);53 54static void os_enter_line_edit_mode(void);55 56static void os_exit_line_edit_mode(void);57 58/******************************************************************************59 *60 * FUNCTION: os_enter_line_edit_mode, os_exit_line_edit_mode61 *62 * PARAMETERS: None63 *64 * RETURN: None65 *66 * DESCRIPTION: Enter/Exit the raw character input mode for the terminal.67 *68 * Interactive line-editing support for the AML debugger. Used with the69 * common/acgetline module.70 *71 * readline() is not used because of non-portability. It is not available72 * 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 line75 * editing that we need in acpi_os_get_line.76 *77 * If the POSIX tcgetattr/tcsetattr interfaces are unavailable, these78 * 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 84static 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 120static 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#else135 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#endif141 142/******************************************************************************143 *144 * FUNCTION: acpi_os_initialize, acpi_os_terminate145 *146 * PARAMETERS: None147 *148 * RETURN: Status149 *150 * DESCRIPTION: Initialize and terminate this module.151 *152 *****************************************************************************/153 154acpi_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 170acpi_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_POINTER178/******************************************************************************179 *180 * FUNCTION: acpi_os_get_root_pointer181 *182 * PARAMETERS: None183 *184 * RETURN: RSDP physical address185 *186 * DESCRIPTION: Gets the ACPI root pointer (RSDP)187 *188 *****************************************************************************/189 190acpi_physical_address acpi_os_get_root_pointer(void)191{192 193 return (0);194}195#endif196 197/******************************************************************************198 *199 * FUNCTION: acpi_os_predefined_override200 *201 * PARAMETERS: init_val - Initial value of the predefined object202 * new_val - The new value for the object203 *204 * RETURN: Status, pointer to value. Null pointer returned if not205 * overriding.206 *207 * DESCRIPTION: Allow the OS to override predefined names208 *209 *****************************************************************************/210 211acpi_status212acpi_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_override227 *228 * PARAMETERS: existing_table - Header of current table (probably229 * firmware)230 * new_table - Where an entire new table is returned.231 *232 * RETURN: Status, pointer to new table. Null pointer returned if no233 * table is available to override234 *235 * DESCRIPTION: Return a different version of a table if one is available236 *237 *****************************************************************************/238 239acpi_status240acpi_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_APP251 252 ae_table_override(existing_table, new_table);253 return (AE_OK);254#else255 256 return (AE_NO_ACPI_TABLES);257#endif258}259 260/******************************************************************************261 *262 * FUNCTION: acpi_os_physical_table_override263 *264 * PARAMETERS: existing_table - Header of current table (probably firmware)265 * new_address - Where new table address is returned266 * (Physical address)267 * new_table_length - Where new table length is returned268 *269 * RETURN: Status, address/length of new table. Null pointer returned270 * if no table is available to override.271 *272 * DESCRIPTION: Returns AE_SUPPORT, function not used in user space.273 *274 *****************************************************************************/275 276acpi_status277acpi_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_sleep288 *289 * PARAMETERS: sleep_state - Which sleep state to enter290 * rega_value - Register A value291 * regb_value - Register B value292 *293 * RETURN: Status294 *295 * DESCRIPTION: A hook before writing sleep registers to enter the sleep296 * state. Return AE_CTRL_TERMINATE to skip further sleep register297 * writes.298 *299 *****************************************************************************/300 301acpi_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_output310 *311 * PARAMETERS: destination - An open file handle/pointer312 *313 * RETURN: None314 *315 * DESCRIPTION: Causes redirect of acpi_os_printf and acpi_os_vprintf316 *317 *****************************************************************************/318 319void acpi_os_redirect_output(void *destination)320{321 322 acpi_gbl_output_file = destination;323}324 325/******************************************************************************326 *327 * FUNCTION: acpi_os_printf328 *329 * PARAMETERS: fmt, ... - Standard printf format330 *331 * RETURN: None332 *333 * DESCRIPTION: Formatted output. Note: very similar to acpi_os_vprintf334 * (performance), changes should be tracked in both functions.335 *336 *****************************************************************************/337 338void 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_vprintf372 *373 * PARAMETERS: fmt - Standard printf format374 * args - Argument list375 *376 * RETURN: None377 *378 * DESCRIPTION: Formatted output with argument list pointer. Note: very379 * similar to acpi_os_printf, changes should be tracked in both380 * functions.381 *382 *****************************************************************************/383 384void 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 be391 * outputting the buffer twice. Using vfprintf is problematic because392 * some implementations modify the args pointer/structure during393 * execution. Thus, we use the local buffer for portability.394 *395 * Note: Since this module is intended for use by the various ACPICA396 * 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_APP424/******************************************************************************425 *426 * FUNCTION: acpi_os_get_line427 *428 * PARAMETERS: buffer - Where to return the command line429 * buffer_length - Maximum length of Buffer430 * bytes_read - Where the actual byte count is returned431 *432 * RETURN: Status and actual bytes read433 *434 * DESCRIPTION: Get the next input line from the terminal. NOTE: For the435 * acpi_exec utility, we use the acgetline module instead to436 * provide line-editing and history support.437 *438 *****************************************************************************/439 440acpi_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#endif476 477#ifndef ACPI_USE_NATIVE_MEMORY_MAPPING478/******************************************************************************479 *480 * FUNCTION: acpi_os_map_memory481 *482 * PARAMETERS: where - Physical address of memory to be mapped483 * length - How much memory to map484 *485 * RETURN: Pointer to mapped memory. Null on error.486 *487 * DESCRIPTION: Map physical memory into caller's address space488 *489 *****************************************************************************/490 491void *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_memory500 *501 * PARAMETERS: where - Logical address of memory to be unmapped502 * length - How much memory to unmap503 *504 * RETURN: None.505 *506 * DESCRIPTION: Delete a previously created mapping. Where and Length must507 * correspond to a previous mapping exactly.508 *509 *****************************************************************************/510 511void acpi_os_unmap_memory(void *where, acpi_size length)512{513 514 return;515}516#endif517 518/******************************************************************************519 *520 * FUNCTION: acpi_os_allocate521 *522 * PARAMETERS: size - Amount to allocate, in bytes523 *524 * RETURN: Pointer to the new allocation. Null on error.525 *526 * DESCRIPTION: Allocate memory. Algorithm is dependent on the OS.527 *528 *****************************************************************************/529 530void *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_ZEROED539/******************************************************************************540 *541 * FUNCTION: acpi_os_allocate_zeroed542 *543 * PARAMETERS: size - Amount to allocate, in bytes544 *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 551void *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#endif559 560/******************************************************************************561 *562 * FUNCTION: acpi_os_free563 *564 * PARAMETERS: mem - Pointer to previously allocated memory565 *566 * RETURN: None.567 *568 * DESCRIPTION: Free memory allocated via acpi_os_allocate569 *570 *****************************************************************************/571 572void acpi_os_free(void *mem)573{574 575 free(mem);576}577 578#ifdef ACPI_SINGLE_THREADED579/******************************************************************************580 *581 * FUNCTION: Semaphore stub functions582 *583 * DESCRIPTION: Stub functions used for single-thread applications that do584 * not require semaphore synchronization. Full implementations585 * of these functions appear after the stubs.586 *587 *****************************************************************************/588 589acpi_status590acpi_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 597acpi_status acpi_os_delete_semaphore(acpi_handle handle)598{599 return (AE_OK);600}601 602acpi_status acpi_os_wait_semaphore(acpi_handle handle, u32 units, u16 timeout)603{604 return (AE_OK);605}606 607acpi_status acpi_os_signal_semaphore(acpi_handle handle, u32 units)608{609 return (AE_OK);610}611 612#else613/******************************************************************************614 *615 * FUNCTION: acpi_os_create_semaphore616 *617 * PARAMETERS: initial_units - Units to be assigned to the new semaphore618 * out_handle - Where a handle will be returned619 *620 * RETURN: Status621 *622 * DESCRIPTION: Create an OS semaphore623 *624 *****************************************************************************/625 626acpi_status627acpi_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#else653 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#endif663 664 *out_handle = (acpi_handle)sem;665 return (AE_OK);666}667 668/******************************************************************************669 *670 * FUNCTION: acpi_os_delete_semaphore671 *672 * PARAMETERS: handle - Handle returned by acpi_os_create_semaphore673 *674 * RETURN: Status675 *676 * DESCRIPTION: Delete an OS semaphore677 *678 *****************************************************************************/679 680acpi_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#else692 if (sem_destroy(sem) == -1) {693 return (AE_BAD_PARAMETER);694 }695#endif696 697 return (AE_OK);698}699 700/******************************************************************************701 *702 * FUNCTION: acpi_os_wait_semaphore703 *704 * PARAMETERS: handle - Handle returned by acpi_os_create_semaphore705 * units - How many units to wait for706 * msec_timeout - How long to wait (milliseconds)707 *708 * RETURN: Status709 *710 * DESCRIPTION: Wait for units711 *712 *****************************************************************************/713 714acpi_status715acpi_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_TIMEOUT721 struct timespec time;722#endif723 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 - just733 * acquire the semaphore if available otherwise return AE_TIME734 * (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_TIMEOUT760 /*761 * Alternate timeout mechanism for environments where762 * 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#else781 /*782 * The interface to sem_timedwait is an absolute time, so we need to783 * 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#endif814 break;815 }816 817 return (status);818}819 820/******************************************************************************821 *822 * FUNCTION: acpi_os_signal_semaphore823 *824 * PARAMETERS: handle - Handle returned by acpi_os_create_semaphore825 * units - Number of units to send826 *827 * RETURN: Status828 *829 * DESCRIPTION: Send units830 *831 *****************************************************************************/832 833acpi_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 interfaces853 *854 * DESCRIPTION: Map these interfaces to semaphore interfaces855 *856 *****************************************************************************/857 858acpi_status acpi_os_create_lock(acpi_spinlock * out_handle)859{860 861 return (acpi_os_create_semaphore(1, 1, out_handle));862}863 864void acpi_os_delete_lock(acpi_spinlock handle)865{866 acpi_os_delete_semaphore(handle);867}868 869acpi_cpu_flags acpi_os_acquire_lock(acpi_handle handle)870{871 acpi_os_wait_semaphore(handle, 1, 0xFFFF);872 return (0);873}874 875void 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_handler883 *884 * PARAMETERS: interrupt_number - Level handler should respond to.885 * isr - Address of the ACPI interrupt handler886 * except_ptr - Where status is returned887 *888 * RETURN: Handle to the newly installed handler.889 *890 * DESCRIPTION: Install an interrupt handler. Used to install the ACPI891 * OS-independent handler.892 *893 *****************************************************************************/894 895u32896acpi_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_handler907 *908 * PARAMETERS: handle - Returned when handler was installed909 *910 * RETURN: Status911 *912 * DESCRIPTION: Uninstalls an interrupt handler.913 *914 *****************************************************************************/915 916acpi_status917acpi_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_stall927 *928 * PARAMETERS: microseconds - Time to sleep929 *930 * RETURN: Blocks until sleep is completed.931 *932 * DESCRIPTION: Sleep at microsecond granularity933 *934 *****************************************************************************/935 936void acpi_os_stall(u32 microseconds)937{938 939 if (microseconds) {940 usleep(microseconds);941 }942}943 944/******************************************************************************945 *946 * FUNCTION: acpi_os_sleep947 *948 * PARAMETERS: milliseconds - Time to sleep949 *950 * RETURN: Blocks until sleep is completed.951 *952 * DESCRIPTION: Sleep at millisecond granularity953 *954 *****************************************************************************/955 956void 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_timer973 *974 * PARAMETERS: None975 *976 * RETURN: Current time in 100 nanosecond units977 *978 * DESCRIPTION: Get the current system time979 *980 *****************************************************************************/981 982u64 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_configuration999 *1000 * PARAMETERS: pci_id - Seg/Bus/Dev1001 * pci_register - Device Register1002 * value - Buffer where value is placed1003 * width - Number of bits1004 *1005 * RETURN: Status1006 *1007 * DESCRIPTION: Read data from PCI configuration space1008 *1009 *****************************************************************************/1010 1011acpi_status1012acpi_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_configuration1023 *1024 * PARAMETERS: pci_id - Seg/Bus/Dev1025 * pci_register - Device Register1026 * value - Value to be written1027 * width - Number of bits1028 *1029 * RETURN: Status.1030 *1031 * DESCRIPTION: Write data to PCI configuration space1032 *1033 *****************************************************************************/1034 1035acpi_status1036acpi_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_port1046 *1047 * PARAMETERS: address - Address of I/O port/register to read1048 * value - Where value is placed1049 * width - Number of bits1050 *1051 * RETURN: Value read from port1052 *1053 * DESCRIPTION: Read data from an I/O port or register1054 *1055 *****************************************************************************/1056 1057acpi_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_port1087 *1088 * PARAMETERS: address - Address of I/O port/register to write1089 * value - Value to write1090 * width - Number of bits1091 *1092 * RETURN: None1093 *1094 * DESCRIPTION: Write data to an I/O port or register1095 *1096 *****************************************************************************/1097 1098acpi_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_memory1107 *1108 * PARAMETERS: address - Physical Memory Address to read1109 * value - Where value is placed1110 * width - Number of bits (8,16,32, or 64)1111 *1112 * RETURN: Value read from physical memory address. Always returned1113 * as a 64-bit integer, regardless of the read width.1114 *1115 * DESCRIPTION: Read data from a physical memory address1116 *1117 *****************************************************************************/1118 1119acpi_status1120acpi_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_memory1142 *1143 * PARAMETERS: address - Physical Memory Address to write1144 * value - Value to write1145 * width - Number of bits (8,16,32, or 64)1146 *1147 * RETURN: None1148 *1149 * DESCRIPTION: Write data to a physical memory address1150 *1151 *****************************************************************************/1152 1153acpi_status1154acpi_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_readable1163 *1164 * PARAMETERS: pointer - Area to be verified1165 * length - Size of area1166 *1167 * RETURN: TRUE if readable for entire length1168 *1169 * DESCRIPTION: Verify that a pointer is valid for reading1170 *1171 *****************************************************************************/1172 1173u8 acpi_os_readable(void *pointer, acpi_size length)1174{1175 1176 return (TRUE);1177}1178 1179/******************************************************************************1180 *1181 * FUNCTION: acpi_os_writable1182 *1183 * PARAMETERS: pointer - Area to be verified1184 * length - Size of area1185 *1186 * RETURN: TRUE if writable for entire length1187 *1188 * DESCRIPTION: Verify that a pointer is valid for writing1189 *1190 *****************************************************************************/1191 1192u8 acpi_os_writable(void *pointer, acpi_size length)1193{1194 1195 return (TRUE);1196}1197 1198/******************************************************************************1199 *1200 * FUNCTION: acpi_os_signal1201 *1202 * PARAMETERS: function - ACPI A signal function code1203 * info - Pointer to function-dependent structure1204 *1205 * RETURN: Status1206 *1207 * DESCRIPTION: Miscellaneous functions. Example implementation only.1208 *1209 *****************************************************************************/1210 1211acpi_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_THREADED1234/******************************************************************************1235 *1236 * FUNCTION: acpi_os_get_thread_id1237 *1238 * PARAMETERS: None1239 *1240 * RETURN: Id of the running thread1241 *1242 * DESCRIPTION: Get the ID of the current (running) thread1243 *1244 *****************************************************************************/1245 1246acpi_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_execute1257 *1258 * PARAMETERS: type - Type of execution1259 * function - Address of the function to execute1260 * context - Passed as a parameter to the function1261 *1262 * RETURN: Status.1263 *1264 * DESCRIPTION: Execute a new thread1265 *1266 *****************************************************************************/1267 1268acpi_status1269acpi_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 */1284acpi_thread_id acpi_os_get_thread_id(void)1285{1286 return (1);1287}1288 1289acpi_status1290acpi_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_complete1304 *1305 * PARAMETERS: None1306 *1307 * RETURN: None1308 *1309 * DESCRIPTION: Wait for all asynchronous events to complete. This1310 * implementation does nothing.1311 *1312 *****************************************************************************/1313 1314void acpi_os_wait_events_complete(void)1315{1316 return;1317}1318