1/******************************************************************************
2 *
3 * Module Name: oswinxf - Windows OSL
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2023, 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 MERCHANTABILITY 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#include "acpi.h"
45#include "accommon.h"
46
47#ifdef WIN32
48#pragma warning(disable:4115)   /* warning C4115: named type definition in parentheses (caused by rpcasync.h> */
49
50#include <windows.h>
51#include <winbase.h>
52
53#elif WIN64
54#include <windowsx.h>
55#endif
56
57#include <stdio.h>
58#include <stdlib.h>
59#include <stdarg.h>
60#include <process.h>
61#include <time.h>
62
63#define _COMPONENT          ACPI_OS_SERVICES
64        ACPI_MODULE_NAME    ("oswinxf")
65
66
67UINT64                      TimerFrequency;
68char                        TableName[ACPI_NAMESEG_SIZE + 1];
69
70#define ACPI_OS_DEBUG_TIMEOUT   30000 /* 30 seconds */
71
72
73/* Upcalls to AcpiExec application */
74
75void
76AeTableOverride (
77    ACPI_TABLE_HEADER       *ExistingTable,
78    ACPI_TABLE_HEADER       **NewTable);
79
80/*
81 * Real semaphores are only used for a multi-threaded application
82 */
83#ifndef ACPI_SINGLE_THREADED
84
85/* Semaphore information structure */
86
87typedef struct acpi_os_semaphore_info
88{
89    UINT16                  MaxUnits;
90    UINT16                  CurrentUnits;
91    void                    *OsHandle;
92
93} ACPI_OS_SEMAPHORE_INFO;
94
95/* Need enough semaphores to run the large aslts suite */
96
97#define ACPI_OS_MAX_SEMAPHORES  256
98
99ACPI_OS_SEMAPHORE_INFO          AcpiGbl_Semaphores[ACPI_OS_MAX_SEMAPHORES];
100
101#endif /* ACPI_SINGLE_THREADED */
102
103/******************************************************************************
104 *
105 * FUNCTION:    AcpiOsTerminate
106 *
107 * PARAMETERS:  None
108 *
109 * RETURN:      Status
110 *
111 * DESCRIPTION: Nothing to do for windows
112 *
113 *****************************************************************************/
114
115ACPI_STATUS
116AcpiOsTerminate (
117    void)
118{
119    return (AE_OK);
120}
121
122
123/******************************************************************************
124 *
125 * FUNCTION:    AcpiOsInitialize
126 *
127 * PARAMETERS:  None
128 *
129 * RETURN:      Status
130 *
131 * DESCRIPTION: Init this OSL
132 *
133 *****************************************************************************/
134
135ACPI_STATUS
136AcpiOsInitialize (
137    void)
138{
139    ACPI_STATUS             Status;
140    LARGE_INTEGER           LocalTimerFrequency;
141
142
143#ifndef ACPI_SINGLE_THREADED
144    /* Clear the semaphore info array */
145
146    memset (AcpiGbl_Semaphores, 0x00, sizeof (AcpiGbl_Semaphores));
147#endif
148
149    AcpiGbl_OutputFile = stdout;
150
151    /* Get the timer frequency for use in AcpiOsGetTimer */
152
153    TimerFrequency = 0;
154    if (QueryPerformanceFrequency (&LocalTimerFrequency))
155    {
156        /* Frequency is in ticks per second */
157
158        TimerFrequency = LocalTimerFrequency.QuadPart;
159    }
160
161    Status = AcpiOsCreateLock (&AcpiGbl_PrintLock);
162    if (ACPI_FAILURE (Status))
163    {
164        return (Status);
165    }
166
167    return (AE_OK);
168}
169
170
171#ifndef ACPI_USE_NATIVE_RSDP_POINTER
172/******************************************************************************
173 *
174 * FUNCTION:    AcpiOsGetRootPointer
175 *
176 * PARAMETERS:  None
177 *
178 * RETURN:      RSDP physical address
179 *
180 * DESCRIPTION: Gets the root pointer (RSDP)
181 *
182 *****************************************************************************/
183
184ACPI_PHYSICAL_ADDRESS
185AcpiOsGetRootPointer (
186    void)
187{
188
189    return (0);
190}
191#endif
192
193
194/******************************************************************************
195 *
196 * FUNCTION:    AcpiOsPredefinedOverride
197 *
198 * PARAMETERS:  InitVal             - Initial value of the predefined object
199 *              NewVal              - The new value for the object
200 *
201 * RETURN:      Status, pointer to value. Null pointer returned if not
202 *              overriding.
203 *
204 * DESCRIPTION: Allow the OS to override predefined names
205 *
206 *****************************************************************************/
207
208ACPI_STATUS
209AcpiOsPredefinedOverride (
210    const ACPI_PREDEFINED_NAMES *InitVal,
211    ACPI_STRING                 *NewVal)
212{
213
214    if (!InitVal || !NewVal)
215    {
216        return (AE_BAD_PARAMETER);
217    }
218
219    *NewVal = NULL;
220    return (AE_OK);
221}
222
223
224/******************************************************************************
225 *
226 * FUNCTION:    AcpiOsTableOverride
227 *
228 * PARAMETERS:  ExistingTable       - Header of current table (probably firmware)
229 *              NewTable            - Where an entire new table is returned.
230 *
231 * RETURN:      Status, pointer to new table. Null pointer returned if no
232 *              table is available to override
233 *
234 * DESCRIPTION: Return a different version of a table if one is available
235 *
236 *****************************************************************************/
237
238ACPI_STATUS
239AcpiOsTableOverride (
240    ACPI_TABLE_HEADER       *ExistingTable,
241    ACPI_TABLE_HEADER       **NewTable)
242{
243
244    if (!ExistingTable || !NewTable)
245    {
246        return (AE_BAD_PARAMETER);
247    }
248
249    *NewTable = NULL;
250
251
252#ifdef ACPI_EXEC_APP
253
254    /* Call back up to AcpiExec */
255
256    AeTableOverride (ExistingTable, NewTable);
257#endif
258
259    return (AE_OK);
260}
261
262
263/******************************************************************************
264 *
265 * FUNCTION:    AcpiOsPhysicalTableOverride
266 *
267 * PARAMETERS:  ExistingTable       - Header of current table (probably firmware)
268 *              NewAddress          - Where new table address is returned
269 *                                    (Physical address)
270 *              NewTableLength      - Where new table length is returned
271 *
272 * RETURN:      Status, address/length of new table. Null pointer returned
273 *              if no table is available to override.
274 *
275 * DESCRIPTION: Returns AE_SUPPORT, function not used in user space.
276 *
277 *****************************************************************************/
278
279ACPI_STATUS
280AcpiOsPhysicalTableOverride (
281    ACPI_TABLE_HEADER       *ExistingTable,
282    ACPI_PHYSICAL_ADDRESS   *NewAddress,
283    UINT32                  *NewTableLength)
284{
285
286    return (AE_SUPPORT);
287}
288
289
290/******************************************************************************
291 *
292 * FUNCTION:    AcpiOsEnterSleep
293 *
294 * PARAMETERS:  SleepState          - Which sleep state to enter
295 *              RegaValue           - Register A value
296 *              RegbValue           - Register B value
297 *
298 * RETURN:      Status
299 *
300 * DESCRIPTION: A hook before writing sleep registers to enter the sleep
301 *              state. Return AE_CTRL_SKIP to skip further sleep register
302 *              writes.
303 *
304 *****************************************************************************/
305
306ACPI_STATUS
307AcpiOsEnterSleep (
308    UINT8                   SleepState,
309    UINT32                  RegaValue,
310    UINT32                  RegbValue)
311{
312
313    return (AE_OK);
314}
315
316
317/******************************************************************************
318 *
319 * FUNCTION:    AcpiOsGetTimer
320 *
321 * PARAMETERS:  None
322 *
323 * RETURN:      Current ticks in 100-nanosecond units
324 *
325 * DESCRIPTION: Get the value of a system timer
326 *
327 ******************************************************************************/
328
329UINT64
330AcpiOsGetTimer (
331    void)
332{
333    LARGE_INTEGER           Timer;
334
335
336    /* Attempt to use hi-granularity timer first */
337
338    if (TimerFrequency &&
339        QueryPerformanceCounter (&Timer))
340    {
341        /* Convert to 100 nanosecond ticks */
342
343        return ((UINT64) ((Timer.QuadPart * (UINT64) ACPI_100NSEC_PER_SEC) /
344            TimerFrequency));
345    }
346
347    /* Fall back to the lo-granularity timer */
348
349    else
350    {
351        /* Convert milliseconds to 100 nanosecond ticks */
352
353        return (GetTickCount64() * ACPI_100NSEC_PER_MSEC);
354    }
355}
356
357
358/******************************************************************************
359 *
360 * FUNCTION:    AcpiOsReadable
361 *
362 * PARAMETERS:  Pointer             - Area to be verified
363 *              Length              - Size of area
364 *
365 * RETURN:      TRUE if readable for entire length
366 *
367 * DESCRIPTION: Verify that a pointer is valid for reading
368 *
369 *****************************************************************************/
370
371BOOLEAN
372AcpiOsReadable (
373    void                    *Pointer,
374    ACPI_SIZE               Length)
375{
376
377    return ((BOOLEAN) !IsBadReadPtr (Pointer, Length));
378}
379
380
381/******************************************************************************
382 *
383 * FUNCTION:    AcpiOsWritable
384 *
385 * PARAMETERS:  Pointer             - Area to be verified
386 *              Length              - Size of area
387 *
388 * RETURN:      TRUE if writable for entire length
389 *
390 * DESCRIPTION: Verify that a pointer is valid for writing
391 *
392 *****************************************************************************/
393
394BOOLEAN
395AcpiOsWritable (
396    void                    *Pointer,
397    ACPI_SIZE               Length)
398{
399
400    return ((BOOLEAN) !IsBadWritePtr (Pointer, Length));
401}
402
403
404/******************************************************************************
405 *
406 * FUNCTION:    AcpiOsRedirectOutput
407 *
408 * PARAMETERS:  Destination         - An open file handle/pointer
409 *
410 * RETURN:      None
411 *
412 * DESCRIPTION: Causes redirect of AcpiOsPrintf and AcpiOsVprintf
413 *
414 *****************************************************************************/
415
416void
417AcpiOsRedirectOutput (
418    void                    *Destination)
419{
420
421    AcpiGbl_OutputFile = Destination;
422}
423
424
425/******************************************************************************
426 *
427 * FUNCTION:    AcpiOsPrintf
428 *
429 * PARAMETERS:  Fmt, ...            - Standard printf format
430 *
431 * RETURN:      None
432 *
433 * DESCRIPTION: Formatted output
434 *
435 *****************************************************************************/
436
437void ACPI_INTERNAL_VAR_XFACE
438AcpiOsPrintf (
439    const char              *Fmt,
440    ...)
441{
442    va_list                 Args;
443    UINT8                   Flags;
444
445
446    Flags = AcpiGbl_DbOutputFlags;
447    if (Flags & ACPI_DB_REDIRECTABLE_OUTPUT)
448    {
449        /* Output is directable to either a file (if open) or the console */
450
451        if (AcpiGbl_DebugFile)
452        {
453            /* Output file is open, send the output there */
454
455            va_start (Args, Fmt);
456            vfprintf (AcpiGbl_DebugFile, Fmt, Args);
457            va_end (Args);
458        }
459        else
460        {
461            /* No redirection, send output to console (once only!) */
462
463            Flags |= ACPI_DB_CONSOLE_OUTPUT;
464        }
465    }
466
467    if (Flags & ACPI_DB_CONSOLE_OUTPUT)
468    {
469        va_start (Args, Fmt);
470        vfprintf (AcpiGbl_OutputFile, Fmt, Args);
471        va_end (Args);
472    }
473
474    return;
475}
476
477
478/******************************************************************************
479 *
480 * FUNCTION:    AcpiOsVprintf
481 *
482 * PARAMETERS:  Fmt                 - Standard printf format
483 *              Args                - Argument list
484 *
485 * RETURN:      None
486 *
487 * DESCRIPTION: Formatted output with argument list pointer
488 *
489 *****************************************************************************/
490
491void
492AcpiOsVprintf (
493    const char              *Fmt,
494    va_list                 Args)
495{
496    INT32                   Count = 0;
497    UINT8                   Flags;
498
499
500    Flags = AcpiGbl_DbOutputFlags;
501    if (Flags & ACPI_DB_REDIRECTABLE_OUTPUT)
502    {
503        /* Output is directable to either a file (if open) or the console */
504
505        if (AcpiGbl_DebugFile)
506        {
507            /* Output file is open, send the output there */
508
509            Count = vfprintf (AcpiGbl_DebugFile, Fmt, Args);
510        }
511        else
512        {
513            /* No redirection, send output to console (once only!) */
514
515            Flags |= ACPI_DB_CONSOLE_OUTPUT;
516        }
517    }
518
519    if (Flags & ACPI_DB_CONSOLE_OUTPUT)
520    {
521        Count = vfprintf (AcpiGbl_OutputFile, Fmt, Args);
522    }
523
524    return;
525}
526
527
528/******************************************************************************
529 *
530 * FUNCTION:    AcpiOsGetLine
531 *
532 * PARAMETERS:  Buffer              - Where to return the command line
533 *              BufferLength        - Maximum length of Buffer
534 *              BytesRead           - Where the actual byte count is returned
535 *
536 * RETURN:      Status and actual bytes read
537 *
538 * DESCRIPTION: Formatted input with argument list pointer
539 *
540 *****************************************************************************/
541
542ACPI_STATUS
543AcpiOsGetLine (
544    char                    *Buffer,
545    UINT32                  BufferLength,
546    UINT32                  *BytesRead)
547{
548    int                     Temp;
549    UINT32                  i;
550
551
552    for (i = 0; ; i++)
553    {
554        if (i >= BufferLength)
555        {
556            return (AE_BUFFER_OVERFLOW);
557        }
558
559        if ((Temp = getchar ()) == EOF)
560        {
561            return (AE_ERROR);
562        }
563
564        if (!Temp || Temp == '\n')
565        {
566            break;
567        }
568
569        Buffer [i] = (char) Temp;
570    }
571
572    /* Null terminate the buffer */
573
574    Buffer [i] = 0;
575
576    /* Return the number of bytes in the string */
577
578    if (BytesRead)
579    {
580        *BytesRead = i;
581    }
582
583    return (AE_OK);
584}
585
586
587#ifndef ACPI_USE_NATIVE_MEMORY_MAPPING
588/******************************************************************************
589 *
590 * FUNCTION:    AcpiOsMapMemory
591 *
592 * PARAMETERS:  Where               - Physical address of memory to be mapped
593 *              Length              - How much memory to map
594 *
595 * RETURN:      Pointer to mapped memory. Null on error.
596 *
597 * DESCRIPTION: Map physical memory into caller's address space
598 *
599 *****************************************************************************/
600
601void *
602AcpiOsMapMemory (
603    ACPI_PHYSICAL_ADDRESS   Where,
604    ACPI_SIZE               Length)
605{
606
607    return (ACPI_TO_POINTER ((ACPI_SIZE) Where));
608}
609
610
611/******************************************************************************
612 *
613 * FUNCTION:    AcpiOsUnmapMemory
614 *
615 * PARAMETERS:  Where               - Logical address of memory to be unmapped
616 *              Length              - How much memory to unmap
617 *
618 * RETURN:      None.
619 *
620 * DESCRIPTION: Delete a previously created mapping. Where and Length must
621 *              correspond to a previous mapping exactly.
622 *
623 *****************************************************************************/
624
625void
626AcpiOsUnmapMemory (
627    void                    *Where,
628    ACPI_SIZE               Length)
629{
630
631    return;
632}
633#endif
634
635
636/******************************************************************************
637 *
638 * FUNCTION:    AcpiOsAllocate
639 *
640 * PARAMETERS:  Size                - Amount to allocate, in bytes
641 *
642 * RETURN:      Pointer to the new allocation. Null on error.
643 *
644 * DESCRIPTION: Allocate memory. Algorithm is dependent on the OS.
645 *
646 *****************************************************************************/
647
648void *
649AcpiOsAllocate (
650    ACPI_SIZE               Size)
651{
652    void                    *Mem;
653
654
655    Mem = (void *) malloc ((size_t) Size);
656    return (Mem);
657}
658
659
660#ifdef USE_NATIVE_ALLOCATE_ZEROED
661/******************************************************************************
662 *
663 * FUNCTION:    AcpiOsAllocateZeroed
664 *
665 * PARAMETERS:  Size                - Amount to allocate, in bytes
666 *
667 * RETURN:      Pointer to the new allocation. Null on error.
668 *
669 * DESCRIPTION: Allocate and zero memory. Algorithm is dependent on the OS.
670 *
671 *****************************************************************************/
672
673void *
674AcpiOsAllocateZeroed (
675    ACPI_SIZE               Size)
676{
677    void                    *Mem;
678
679
680    Mem = (void *) calloc (1, (size_t) Size);
681    return (Mem);
682}
683#endif
684
685
686/******************************************************************************
687 *
688 * FUNCTION:    AcpiOsFree
689 *
690 * PARAMETERS:  Mem                 - Pointer to previously allocated memory
691 *
692 * RETURN:      None.
693 *
694 * DESCRIPTION: Free memory allocated via AcpiOsAllocate
695 *
696 *****************************************************************************/
697
698void
699AcpiOsFree (
700    void                    *Mem)
701{
702
703    free (Mem);
704}
705
706
707#ifdef ACPI_SINGLE_THREADED
708/******************************************************************************
709 *
710 * FUNCTION:    Semaphore stub functions
711 *
712 * DESCRIPTION: Stub functions used for single-thread applications that do
713 *              not require semaphore synchronization. Full implementations
714 *              of these functions appear after the stubs.
715 *
716 *****************************************************************************/
717
718ACPI_STATUS
719AcpiOsCreateSemaphore (
720    UINT32              MaxUnits,
721    UINT32              InitialUnits,
722    ACPI_HANDLE         *OutHandle)
723{
724    *OutHandle = (ACPI_HANDLE) 1;
725    return (AE_OK);
726}
727
728ACPI_STATUS
729AcpiOsDeleteSemaphore (
730    ACPI_HANDLE         Handle)
731{
732    return (AE_OK);
733}
734
735ACPI_STATUS
736AcpiOsWaitSemaphore (
737    ACPI_HANDLE         Handle,
738    UINT32              Units,
739    UINT16              Timeout)
740{
741    return (AE_OK);
742}
743
744ACPI_STATUS
745AcpiOsSignalSemaphore (
746    ACPI_HANDLE         Handle,
747    UINT32              Units)
748{
749    return (AE_OK);
750}
751
752#else
753/******************************************************************************
754 *
755 * FUNCTION:    AcpiOsCreateSemaphore
756 *
757 * PARAMETERS:  MaxUnits            - Maximum units that can be sent
758 *              InitialUnits        - Units to be assigned to the new semaphore
759 *              OutHandle           - Where a handle will be returned
760 *
761 * RETURN:      Status
762 *
763 * DESCRIPTION: Create an OS semaphore
764 *
765 *****************************************************************************/
766
767ACPI_STATUS
768AcpiOsCreateSemaphore (
769    UINT32              MaxUnits,
770    UINT32              InitialUnits,
771    ACPI_SEMAPHORE      *OutHandle)
772{
773    void                *Mutex;
774    UINT32              i;
775
776    ACPI_FUNCTION_NAME (OsCreateSemaphore);
777
778
779    if (MaxUnits == ACPI_UINT32_MAX)
780    {
781        MaxUnits = 255;
782    }
783
784    if (InitialUnits == ACPI_UINT32_MAX)
785    {
786        InitialUnits = MaxUnits;
787    }
788
789    if (InitialUnits > MaxUnits)
790    {
791        return (AE_BAD_PARAMETER);
792    }
793
794    /* Find an empty slot */
795
796    for (i = 0; i < ACPI_OS_MAX_SEMAPHORES; i++)
797    {
798        if (!AcpiGbl_Semaphores[i].OsHandle)
799        {
800            break;
801        }
802    }
803    if (i >= ACPI_OS_MAX_SEMAPHORES)
804    {
805        ACPI_EXCEPTION ((AE_INFO, AE_LIMIT,
806            "Reached max semaphores (%u), could not create",
807            ACPI_OS_MAX_SEMAPHORES));
808        return (AE_LIMIT);
809    }
810
811    /* Create an OS semaphore */
812
813    Mutex = CreateSemaphore (NULL, InitialUnits, MaxUnits, NULL);
814    if (!Mutex)
815    {
816        ACPI_ERROR ((AE_INFO, "Could not create semaphore"));
817        return (AE_NO_MEMORY);
818    }
819
820    AcpiGbl_Semaphores[i].MaxUnits = (UINT16) MaxUnits;
821    AcpiGbl_Semaphores[i].CurrentUnits = (UINT16) InitialUnits;
822    AcpiGbl_Semaphores[i].OsHandle = Mutex;
823
824    ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX,
825        "Handle=%u, Max=%u, Current=%u, OsHandle=%p\n",
826        i, MaxUnits, InitialUnits, Mutex));
827
828    *OutHandle = (void *) i;
829    return (AE_OK);
830}
831
832
833/******************************************************************************
834 *
835 * FUNCTION:    AcpiOsDeleteSemaphore
836 *
837 * PARAMETERS:  Handle              - Handle returned by AcpiOsCreateSemaphore
838 *
839 * RETURN:      Status
840 *
841 * DESCRIPTION: Delete an OS semaphore
842 *
843 *****************************************************************************/
844
845ACPI_STATUS
846AcpiOsDeleteSemaphore (
847    ACPI_SEMAPHORE      Handle)
848{
849    UINT32              Index = (UINT32) Handle;
850
851
852    if ((Index >= ACPI_OS_MAX_SEMAPHORES) ||
853        !AcpiGbl_Semaphores[Index].OsHandle)
854    {
855        return (AE_BAD_PARAMETER);
856    }
857
858    CloseHandle (AcpiGbl_Semaphores[Index].OsHandle);
859    AcpiGbl_Semaphores[Index].OsHandle = NULL;
860    return (AE_OK);
861}
862
863
864/******************************************************************************
865 *
866 * FUNCTION:    AcpiOsWaitSemaphore
867 *
868 * PARAMETERS:  Handle              - Handle returned by AcpiOsCreateSemaphore
869 *              Units               - How many units to wait for
870 *              Timeout             - How long to wait
871 *
872 * RETURN:      Status
873 *
874 * DESCRIPTION: Wait for units
875 *
876 *****************************************************************************/
877
878ACPI_STATUS
879AcpiOsWaitSemaphore (
880    ACPI_SEMAPHORE      Handle,
881    UINT32              Units,
882    UINT16              Timeout)
883{
884    UINT32              Index = (UINT32) Handle;
885    UINT32              WaitStatus;
886    UINT32              OsTimeout = Timeout;
887
888
889    ACPI_FUNCTION_ENTRY ();
890
891
892    if ((Index >= ACPI_OS_MAX_SEMAPHORES) ||
893        !AcpiGbl_Semaphores[Index].OsHandle)
894    {
895        return (AE_BAD_PARAMETER);
896    }
897
898    if (Units > 1)
899    {
900        printf ("WaitSemaphore: Attempt to receive %u units\n", Units);
901        return (AE_NOT_IMPLEMENTED);
902    }
903
904    if (Timeout == ACPI_WAIT_FOREVER)
905    {
906        OsTimeout = INFINITE;
907        if (AcpiGbl_DebugTimeout)
908        {
909            /* The debug timeout will prevent hang conditions */
910
911            OsTimeout = ACPI_OS_DEBUG_TIMEOUT;
912        }
913    }
914    else
915    {
916        /* Add 10ms to account for clock tick granularity */
917
918        OsTimeout += 10;
919    }
920
921    WaitStatus = WaitForSingleObject (
922        AcpiGbl_Semaphores[Index].OsHandle, OsTimeout);
923    if (WaitStatus == WAIT_TIMEOUT)
924    {
925        if (AcpiGbl_DebugTimeout)
926        {
927            ACPI_EXCEPTION ((AE_INFO, AE_TIME,
928                "Debug timeout on semaphore 0x%04X (%ums)\n",
929                Index, ACPI_OS_DEBUG_TIMEOUT));
930        }
931
932        return (AE_TIME);
933    }
934
935    if (AcpiGbl_Semaphores[Index].CurrentUnits == 0)
936    {
937        ACPI_ERROR ((AE_INFO,
938            "%s - No unit received. Timeout 0x%X, OS_Status 0x%X",
939            AcpiUtGetMutexName (Index), Timeout, WaitStatus));
940
941        return (AE_OK);
942    }
943
944    AcpiGbl_Semaphores[Index].CurrentUnits--;
945    return (AE_OK);
946}
947
948
949/******************************************************************************
950 *
951 * FUNCTION:    AcpiOsSignalSemaphore
952 *
953 * PARAMETERS:  Handle              - Handle returned by AcpiOsCreateSemaphore
954 *              Units               - Number of units to send
955 *
956 * RETURN:      Status
957 *
958 * DESCRIPTION: Send units
959 *
960 *****************************************************************************/
961
962ACPI_STATUS
963AcpiOsSignalSemaphore (
964    ACPI_SEMAPHORE      Handle,
965    UINT32              Units)
966{
967    UINT32              Index = (UINT32) Handle;
968
969
970    ACPI_FUNCTION_ENTRY ();
971
972
973    if (Index >= ACPI_OS_MAX_SEMAPHORES)
974    {
975        printf ("SignalSemaphore: Index/Handle out of range: %2.2X\n", Index);
976        return (AE_BAD_PARAMETER);
977    }
978
979    if (!AcpiGbl_Semaphores[Index].OsHandle)
980    {
981        printf ("SignalSemaphore: Null OS handle, Index %2.2X\n", Index);
982        return (AE_BAD_PARAMETER);
983    }
984
985    if (Units > 1)
986    {
987        printf ("SignalSemaphore: Attempt to signal %u units, Index %2.2X\n", Units, Index);
988        return (AE_NOT_IMPLEMENTED);
989    }
990
991    if ((AcpiGbl_Semaphores[Index].CurrentUnits + 1) >
992        AcpiGbl_Semaphores[Index].MaxUnits)
993    {
994        ACPI_ERROR ((AE_INFO,
995            "Oversignalled semaphore[%u]! Current %u Max %u",
996            Index, AcpiGbl_Semaphores[Index].CurrentUnits,
997            AcpiGbl_Semaphores[Index].MaxUnits));
998
999        return (AE_LIMIT);
1000    }
1001
1002    AcpiGbl_Semaphores[Index].CurrentUnits++;
1003    ReleaseSemaphore (AcpiGbl_Semaphores[Index].OsHandle, Units, NULL);
1004
1005    return (AE_OK);
1006}
1007
1008#endif /* ACPI_SINGLE_THREADED */
1009
1010
1011/******************************************************************************
1012 *
1013 * FUNCTION:    Spinlock interfaces
1014 *
1015 * DESCRIPTION: Map these interfaces to semaphore interfaces
1016 *
1017 *****************************************************************************/
1018
1019ACPI_STATUS
1020AcpiOsCreateLock (
1021    ACPI_SPINLOCK           *OutHandle)
1022{
1023    return (AcpiOsCreateSemaphore (1, 1, OutHandle));
1024}
1025
1026void
1027AcpiOsDeleteLock (
1028    ACPI_SPINLOCK           Handle)
1029{
1030    AcpiOsDeleteSemaphore (Handle);
1031}
1032
1033ACPI_CPU_FLAGS
1034AcpiOsAcquireLock (
1035    ACPI_SPINLOCK           Handle)
1036{
1037    AcpiOsWaitSemaphore (Handle, 1, 0xFFFF);
1038    return (0);
1039}
1040
1041void
1042AcpiOsReleaseLock (
1043    ACPI_SPINLOCK           Handle,
1044    ACPI_CPU_FLAGS          Flags)
1045{
1046    AcpiOsSignalSemaphore (Handle, 1);
1047}
1048
1049
1050#if ACPI_FUTURE_IMPLEMENTATION
1051
1052/* Mutex interfaces, just implement with a semaphore */
1053
1054ACPI_STATUS
1055AcpiOsCreateMutex (
1056    ACPI_MUTEX              *OutHandle)
1057{
1058    return (AcpiOsCreateSemaphore (1, 1, OutHandle));
1059}
1060
1061void
1062AcpiOsDeleteMutex (
1063    ACPI_MUTEX              Handle)
1064{
1065    AcpiOsDeleteSemaphore (Handle);
1066}
1067
1068ACPI_STATUS
1069AcpiOsAcquireMutex (
1070    ACPI_MUTEX              Handle,
1071    UINT16                  Timeout)
1072{
1073    AcpiOsWaitSemaphore (Handle, 1, Timeout);
1074    return (0);
1075}
1076
1077void
1078AcpiOsReleaseMutex (
1079    ACPI_MUTEX              Handle)
1080{
1081    AcpiOsSignalSemaphore (Handle, 1);
1082}
1083#endif
1084
1085
1086/******************************************************************************
1087 *
1088 * FUNCTION:    AcpiOsInstallInterruptHandler
1089 *
1090 * PARAMETERS:  InterruptNumber     - Level handler should respond to.
1091 *              ServiceRoutine      - Address of the ACPI interrupt handler
1092 *              Context             - User context
1093 *
1094 * RETURN:      Handle to the newly installed handler.
1095 *
1096 * DESCRIPTION: Install an interrupt handler. Used to install the ACPI
1097 *              OS-independent handler.
1098 *
1099 *****************************************************************************/
1100
1101UINT32
1102AcpiOsInstallInterruptHandler (
1103    UINT32                  InterruptNumber,
1104    ACPI_OSD_HANDLER        ServiceRoutine,
1105    void                    *Context)
1106{
1107
1108    return (AE_OK);
1109}
1110
1111
1112/******************************************************************************
1113 *
1114 * FUNCTION:    AcpiOsRemoveInterruptHandler
1115 *
1116 * PARAMETERS:  Handle              - Returned when handler was installed
1117 *
1118 * RETURN:      Status
1119 *
1120 * DESCRIPTION: Uninstalls an interrupt handler.
1121 *
1122 *****************************************************************************/
1123
1124ACPI_STATUS
1125AcpiOsRemoveInterruptHandler (
1126    UINT32                  InterruptNumber,
1127    ACPI_OSD_HANDLER        ServiceRoutine)
1128{
1129
1130    return (AE_OK);
1131}
1132
1133
1134/******************************************************************************
1135 *
1136 * FUNCTION:    AcpiOsStall
1137 *
1138 * PARAMETERS:  Microseconds        - Time to stall
1139 *
1140 * RETURN:      None. Blocks until stall is completed.
1141 *
1142 * DESCRIPTION: Sleep at microsecond granularity
1143 *
1144 *****************************************************************************/
1145
1146void
1147AcpiOsStall (
1148    UINT32                  Microseconds)
1149{
1150
1151    Sleep ((Microseconds / ACPI_USEC_PER_MSEC) + 1);
1152    return;
1153}
1154
1155
1156/******************************************************************************
1157 *
1158 * FUNCTION:    AcpiOsSleep
1159 *
1160 * PARAMETERS:  Milliseconds        - Time to sleep
1161 *
1162 * RETURN:      None. Blocks until sleep is completed.
1163 *
1164 * DESCRIPTION: Sleep at millisecond granularity
1165 *
1166 *****************************************************************************/
1167
1168void
1169AcpiOsSleep (
1170    UINT64                  Milliseconds)
1171{
1172
1173    /* Add 10ms to account for clock tick granularity */
1174
1175    Sleep (((unsigned long) Milliseconds) + 10);
1176    return;
1177}
1178
1179
1180/******************************************************************************
1181 *
1182 * FUNCTION:    AcpiOsReadPciConfiguration
1183 *
1184 * PARAMETERS:  PciId               - Seg/Bus/Dev
1185 *              Register            - Device Register
1186 *              Value               - Buffer where value is placed
1187 *              Width               - Number of bits
1188 *
1189 * RETURN:      Status
1190 *
1191 * DESCRIPTION: Read data from PCI configuration space
1192 *
1193 *****************************************************************************/
1194
1195ACPI_STATUS
1196AcpiOsReadPciConfiguration (
1197    ACPI_PCI_ID             *PciId,
1198    UINT32                  Register,
1199    UINT64                  *Value,
1200    UINT32                  Width)
1201{
1202
1203    *Value = 0;
1204    return (AE_OK);
1205}
1206
1207
1208/******************************************************************************
1209 *
1210 * FUNCTION:    AcpiOsWritePciConfiguration
1211 *
1212 * PARAMETERS:  PciId               - Seg/Bus/Dev
1213 *              Register            - Device Register
1214 *              Value               - Value to be written
1215 *              Width               - Number of bits
1216 *
1217 * RETURN:      Status
1218 *
1219 * DESCRIPTION: Write data to PCI configuration space
1220 *
1221 *****************************************************************************/
1222
1223ACPI_STATUS
1224AcpiOsWritePciConfiguration (
1225    ACPI_PCI_ID             *PciId,
1226    UINT32                  Register,
1227    UINT64                  Value,
1228    UINT32                  Width)
1229{
1230
1231    return (AE_OK);
1232}
1233
1234
1235/******************************************************************************
1236 *
1237 * FUNCTION:    AcpiOsReadPort
1238 *
1239 * PARAMETERS:  Address             - Address of I/O port/register to read
1240 *              Value               - Where value is placed
1241 *              Width               - Number of bits
1242 *
1243 * RETURN:      Value read from port
1244 *
1245 * DESCRIPTION: Read data from an I/O port or register
1246 *
1247 *****************************************************************************/
1248
1249ACPI_STATUS
1250AcpiOsReadPort (
1251    ACPI_IO_ADDRESS         Address,
1252    UINT32                  *Value,
1253    UINT32                  Width)
1254{
1255    ACPI_FUNCTION_NAME (OsReadPort);
1256
1257
1258    switch (Width)
1259    {
1260    case 8:
1261
1262        *Value = 0xFF;
1263        break;
1264
1265    case 16:
1266
1267        *Value = 0xFFFF;
1268        break;
1269
1270    case 32:
1271
1272        *Value = 0xFFFFFFFF;
1273        break;
1274
1275    default:
1276
1277        ACPI_ERROR ((AE_INFO, "Bad width parameter: %X", Width));
1278        return (AE_BAD_PARAMETER);
1279    }
1280
1281    return (AE_OK);
1282}
1283
1284
1285/******************************************************************************
1286 *
1287 * FUNCTION:    AcpiOsWritePort
1288 *
1289 * PARAMETERS:  Address             - Address of I/O port/register to write
1290 *              Value               - Value to write
1291 *              Width               - Number of bits
1292 *
1293 * RETURN:      None
1294 *
1295 * DESCRIPTION: Write data to an I/O port or register
1296 *
1297 *****************************************************************************/
1298
1299ACPI_STATUS
1300AcpiOsWritePort (
1301    ACPI_IO_ADDRESS         Address,
1302    UINT32                  Value,
1303    UINT32                  Width)
1304{
1305    ACPI_FUNCTION_NAME (OsWritePort);
1306
1307
1308    if ((Width == 8) || (Width == 16) || (Width == 32))
1309    {
1310        return (AE_OK);
1311    }
1312
1313    ACPI_ERROR ((AE_INFO, "Bad width parameter: %X", Width));
1314    return (AE_BAD_PARAMETER);
1315}
1316
1317
1318/******************************************************************************
1319 *
1320 * FUNCTION:    AcpiOsReadMemory
1321 *
1322 * PARAMETERS:  Address             - Physical Memory Address to read
1323 *              Value               - Where value is placed
1324 *              Width               - Number of bits (8,16,32, or 64)
1325 *
1326 * RETURN:      Value read from physical memory address. Always returned
1327 *              as a 64-bit integer, regardless of the read width.
1328 *
1329 * DESCRIPTION: Read data from a physical memory address
1330 *
1331 *****************************************************************************/
1332
1333ACPI_STATUS
1334AcpiOsReadMemory (
1335    ACPI_PHYSICAL_ADDRESS   Address,
1336    UINT64                  *Value,
1337    UINT32                  Width)
1338{
1339
1340    switch (Width)
1341    {
1342    case 8:
1343    case 16:
1344    case 32:
1345    case 64:
1346
1347        *Value = 0;
1348        break;
1349
1350    default:
1351
1352        return (AE_BAD_PARAMETER);
1353        break;
1354    }
1355
1356    return (AE_OK);
1357}
1358
1359
1360/******************************************************************************
1361 *
1362 * FUNCTION:    AcpiOsWriteMemory
1363 *
1364 * PARAMETERS:  Address             - Physical Memory Address to write
1365 *              Value               - Value to write
1366 *              Width               - Number of bits (8,16,32, or 64)
1367 *
1368 * RETURN:      None
1369 *
1370 * DESCRIPTION: Write data to a physical memory address
1371 *
1372 *****************************************************************************/
1373
1374ACPI_STATUS
1375AcpiOsWriteMemory (
1376    ACPI_PHYSICAL_ADDRESS   Address,
1377    UINT64                  Value,
1378    UINT32                  Width)
1379{
1380
1381    return (AE_OK);
1382}
1383
1384
1385/******************************************************************************
1386 *
1387 * FUNCTION:    AcpiOsSignal
1388 *
1389 * PARAMETERS:  Function            - ACPICA signal function code
1390 *              Info                - Pointer to function-dependent structure
1391 *
1392 * RETURN:      Status
1393 *
1394 * DESCRIPTION: Miscellaneous functions. Example implementation only.
1395 *
1396 *****************************************************************************/
1397
1398ACPI_STATUS
1399AcpiOsSignal (
1400    UINT32                  Function,
1401    void                    *Info)
1402{
1403
1404    switch (Function)
1405    {
1406    case ACPI_SIGNAL_FATAL:
1407
1408        break;
1409
1410    case ACPI_SIGNAL_BREAKPOINT:
1411
1412        break;
1413
1414    default:
1415
1416        break;
1417    }
1418
1419    return (AE_OK);
1420}
1421
1422
1423/******************************************************************************
1424 *
1425 * FUNCTION:    Local cache interfaces
1426 *
1427 * DESCRIPTION: Implements cache interfaces via malloc/free for testing
1428 *              purposes only.
1429 *
1430 *****************************************************************************/
1431
1432#ifndef ACPI_USE_LOCAL_CACHE
1433
1434ACPI_STATUS
1435AcpiOsCreateCache (
1436    char                    *CacheName,
1437    UINT16                  ObjectSize,
1438    UINT16                  MaxDepth,
1439    ACPI_CACHE_T            **ReturnCache)
1440{
1441    ACPI_MEMORY_LIST        *NewCache;
1442
1443
1444    NewCache = malloc (sizeof (ACPI_MEMORY_LIST));
1445    if (!NewCache)
1446    {
1447        return (AE_NO_MEMORY);
1448    }
1449
1450    memset (NewCache, 0, sizeof (ACPI_MEMORY_LIST));
1451    NewCache->ListName = CacheName;
1452    NewCache->ObjectSize = ObjectSize;
1453    NewCache->MaxDepth = MaxDepth;
1454
1455    *ReturnCache = (ACPI_CACHE_T) NewCache;
1456    return (AE_OK);
1457}
1458
1459ACPI_STATUS
1460AcpiOsDeleteCache (
1461    ACPI_CACHE_T            *Cache)
1462{
1463    free (Cache);
1464    return (AE_OK);
1465}
1466
1467ACPI_STATUS
1468AcpiOsPurgeCache (
1469    ACPI_CACHE_T            *Cache)
1470{
1471    return (AE_OK);
1472}
1473
1474void *
1475AcpiOsAcquireObject (
1476    ACPI_CACHE_T            *Cache)
1477{
1478    void                    *NewObject;
1479
1480    NewObject = malloc (((ACPI_MEMORY_LIST *) Cache)->ObjectSize);
1481    memset (NewObject, 0, ((ACPI_MEMORY_LIST *) Cache)->ObjectSize);
1482
1483    return (NewObject);
1484}
1485
1486ACPI_STATUS
1487AcpiOsReleaseObject (
1488    ACPI_CACHE_T            *Cache,
1489    void                    *Object)
1490{
1491    free (Object);
1492    return (AE_OK);
1493}
1494
1495#endif /* ACPI_USE_LOCAL_CACHE */
1496
1497
1498/* Optional multi-thread support */
1499
1500#ifndef ACPI_SINGLE_THREADED
1501/******************************************************************************
1502 *
1503 * FUNCTION:    AcpiOsGetThreadId
1504 *
1505 * PARAMETERS:  None
1506 *
1507 * RETURN:      Id of the running thread
1508 *
1509 * DESCRIPTION: Get the Id of the current (running) thread
1510 *
1511 *****************************************************************************/
1512
1513ACPI_THREAD_ID
1514AcpiOsGetThreadId (
1515    void)
1516{
1517    DWORD                   ThreadId;
1518
1519    /* Ensure ID is never 0 */
1520
1521    ThreadId = GetCurrentThreadId ();
1522    return ((ACPI_THREAD_ID) (ThreadId + 1));
1523}
1524
1525
1526/******************************************************************************
1527 *
1528 * FUNCTION:    AcpiOsExecute
1529 *
1530 * PARAMETERS:  Type                - Type of execution
1531 *              Function            - Address of the function to execute
1532 *              Context             - Passed as a parameter to the function
1533 *
1534 * RETURN:      Status
1535 *
1536 * DESCRIPTION: Execute a new thread
1537 *
1538 *****************************************************************************/
1539
1540ACPI_STATUS
1541AcpiOsExecute (
1542    ACPI_EXECUTE_TYPE       Type,
1543    ACPI_OSD_EXEC_CALLBACK  Function,
1544    void                    *Context)
1545{
1546
1547    _beginthread (Function, (unsigned) 0, Context);
1548    return (0);
1549}
1550
1551#else /* ACPI_SINGLE_THREADED */
1552ACPI_THREAD_ID
1553AcpiOsGetThreadId (
1554    void)
1555{
1556    return (1);
1557}
1558
1559ACPI_STATUS
1560AcpiOsExecute (
1561    ACPI_EXECUTE_TYPE       Type,
1562    ACPI_OSD_EXEC_CALLBACK  Function,
1563    void                    *Context)
1564{
1565
1566    Function (Context);
1567    return (AE_OK);
1568}
1569
1570#endif /* ACPI_SINGLE_THREADED */
1571
1572
1573/******************************************************************************
1574 *
1575 * FUNCTION:    AcpiOsWaitEventsComplete
1576 *
1577 * PARAMETERS:  None
1578 *
1579 * RETURN:      None
1580 *
1581 * DESCRIPTION: Wait for all asynchronous events to complete. This
1582 *              implementation does nothing.
1583 *
1584 *****************************************************************************/
1585
1586void
1587AcpiOsWaitEventsComplete (
1588    void)
1589{
1590
1591    return;
1592}
1593