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