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 - 2023, 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
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.