/* * Some or all of this work - Copyright (c) 2006 - 2017, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * Neither the name of Intel Corporation nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * Access to mutexes routines */ Name (Z149, 0x95) /* * Opcodes of initialization of set of mutexes * * c300 - usual * c301 - one mutex of Index equal to ((Index of current thread) - 1) */ Name (C300, 0x00) Name (C301, 0x01) /* * Flags corresponding to Mutexes */ Name (FL00, Package (MAX0) { Package (MAX1){}, Package (MAX1){}, Package (MAX1){}, Package (MAX1){}, Package (MAX1){}, Package (MAX1){}, Package (MAX1){}, Package (MAX1){}, Package (MAX1){}, Package (MAX1){}, Package (MAX1){}, Package (MAX1){}, Package (MAX1){}, Package (MAX1){}, Package (MAX1){}, Package (MAX1){} }) /* * Counters (current) corresponding to Mutexes * (how many times the relevant mutex has been * successfully Acquired (may be repeatedly) * (by the same thread)) * * - incremented on Acquire * - decremented on Release */ Name (FL01, Package (MAX0) { Package (MAX1){}, Package (MAX1){}, Package (MAX1){}, Package (MAX1){}, Package (MAX1){}, Package (MAX1){}, Package (MAX1){}, Package (MAX1){}, Package (MAX1){}, Package (MAX1){}, Package (MAX1){}, Package (MAX1){}, Package (MAX1){}, Package (MAX1){}, Package (MAX1){}, Package (MAX1){} }) /* * Counters corresponding to Mutexes * * how many times the mutex has successfully Acquired * by different threads. * * - incremented on Acquire * - reset to zero by the Control thread */ Name (CNT0, Package (MAX0) { Package (MAX1){}, Package (MAX1){}, Package (MAX1){}, Package (MAX1){}, Package (MAX1){}, Package (MAX1){}, Package (MAX1){}, Package (MAX1){}, Package (MAX1){}, Package (MAX1){}, Package (MAX1){}, Package (MAX1){}, Package (MAX1){}, Package (MAX1){}, Package (MAX1){}, Package (MAX1){} }) /* * Acquire mutex * * arg0 - ID of current thread * arg1 - Index of thread * arg2 - Level of mutex * arg3 - Index of mutex * arg4 - opcode of exception to be generated or zero * arg5 - opcode of TimeOutValue (see comment to ma00) * arg6 - if fall into sleep */ Method (M310, 7, Serialized) { Local0 = M21E ("Acquire mutex, ", Arg2, Arg3) M201 (Arg1, VB03, Local0) /* Increment statistics of Acquire */ If (VB04) { M212 (RefOf (P105), Arg1) } If ((Arg4 == EX0D)) { /* FAIL expected */ Local6 = 0x00 } Else { Local6 = Arg4 } Local7 = 0x01 /* Init with FAIL */ Switch (Arg2) { Case (0x00) { Local7 = MA00 (Arg3, Local6, Arg5) } Case (0x01) { Local7 = MA01 (Arg3, Local6, Arg5) } Case (0x02) { Local7 = MA02 (Arg3, Local6, Arg5) } Case (0x03) { Local7 = MA03 (Arg3, Local6, Arg5) } Case (0x04) { Local7 = MA04 (Arg3, Local6, Arg5) } Case (0x05) { Local7 = MA05 (Arg3, Local6, Arg5) } Case (0x06) { Local7 = MA06 (Arg3, Local6, Arg5) } Case (0x07) { Local7 = MA07 (Arg3, Local6, Arg5) } Case (0x08) { Local7 = MA08 (Arg3, Local6, Arg5) } Case (0x09) { Local7 = MA09 (Arg3, Local6, Arg5) } Case (0x0A) { Local7 = MA0A (Arg3, Local6, Arg5) } Case (0x0B) { Local7 = MA0B (Arg3, Local6, Arg5) } Case (0x0C) { Local7 = MA0C (Arg3, Local6, Arg5) } Case (0x0D) { Local7 = MA0D (Arg3, Local6, Arg5) } Case (0x0E) { Local7 = MA0E (Arg3, Local6, Arg5) } Case (0x0F) { Local7 = MA0F (Arg3, Local6, Arg5) } } If ((Arg4 == EX0D)) { /* FAIL expected */ If (Local7) { M201 (Arg1, VB03, "Acquire returned non-zero, it was expected") } Else { M201 (Arg1, VB03, "Error 9: Acquire returned zero but FAIL expected!") SE00 (Arg1, ER09, "Error er09") } Return (Local7) } ElseIf (Arg4) { Return (0x01) } ElseIf (Local7) { M201 (Arg1, VB03, "Error 0: Acquire returned non-zero!") SE00 (Arg1, ER00, "Error er00") Return (0x01) } Else { /* * Increment counter (cnt0) and set up flag (fl00) * corresponding to mutex. Report error in case the * flag is non-zero. */ Local7 = M21E ("Incrementing count of mutex, ", Arg2, Arg3) Concatenate (Local7, " and set up its flag", Local1) M201 (Arg1, VB03, Local1) M331 (Arg1, Arg2, Arg3) If (Arg6) { M201 (Arg1, VB03, "Fall into sleep") If (SLM0) { Divide (Arg1, 0x05, Local1) Local2 = 0x64 Switch (Local1) { Case (0x00) { Local2 = I100 /* \I100 */ } Case (0x01) { Local2 = I101 /* \I101 */ } Case (0x02) { Local2 = I102 /* \I102 */ } Case (0x03) { Local2 = I103 /* \I103 */ } Case (0x04) { Local2 = I104 /* \I104 */ } Case (0x05) { Local2 = I105 /* \I105 */ } Case (0x06) { Local2 = I106 /* \I106 */ } Case (0x07) { Local2 = I107 /* \I107 */ } Case (0x08) { Local2 = I108 /* \I108 */ } } M206 (Arg1, Local2) } Else { M206 (Arg1, SL01) } } } Return (0x00) } /* * Release mutex * * arg0 - ID of current thread * arg1 - Index of thread * arg2 - Level of mutex * arg3 - Index of mutex * arg4 - opcode of exception to be generated or zero * arg5 - if fall into sleep */ Method (M311, 6, Serialized) { Local0 = M21E ("Release mutex, ", Arg2, Arg3) M201 (Arg1, VB03, Local0) /* Increment statistics of Release */ If (VB04) { M212 (RefOf (P106), Arg1) } /* * Check up and reset flag (fl00) corresponding to this Mutex * (check that it was not changed by other threads while this * one was sleeping). */ If (!Arg4) { M332 (Arg1, Arg2, Arg3) } Switch (Arg2) { Case (0x00) { MA10 (Arg3) } Case (0x01) { MA11 (Arg3) } Case (0x02) { MA12 (Arg3) } Case (0x03) { MA13 (Arg3) } Case (0x04) { MA14 (Arg3) } Case (0x05) { MA15 (Arg3) } Case (0x06) { MA16 (Arg3) } Case (0x07) { MA17 (Arg3) } Case (0x08) { MA18 (Arg3) } Case (0x09) { MA19 (Arg3) } Case (0x0A) { MA1A (Arg3) } Case (0x0B) { MA1B (Arg3) } Case (0x0C) { MA1C (Arg3) } Case (0x0D) { MA1D (Arg3) } Case (0x0E) { MA1E (Arg3) } Case (0x0F) { MA1F (Arg3) } } If (Arg5) { M206 (Arg1, SL01) } } /* * Reset all counters (cnt0) and flags (fl00) * corresponding to all Mutexes. */ Method (M330, 0, Serialized) { Name (LPN0, 0x00) Name (LPC0, 0x00) Name (LPN1, 0x00) Name (LPC1, 0x00) LPN0 = MAX0 /* \MAX0 */ LPC0 = 0x00 While (LPN0) { LPN1 = MAX1 /* \MAX1 */ LPC1 = 0x00 While (LPN1) { DerefOf (CNT0 [LPC0]) [LPC1] = 0x00 DerefOf (FL00 [LPC0]) [LPC1] = 0x00 LPN1-- LPC1++ } LPN0-- LPC0++ } } /* * For Acquire * * Increment counter (cnt0) and set up flag (fl00) * corresponding to the mutex of arg1-Level and * arg2-Index. Report error in case the flag is non-zero. * * arg0 - Index of thread * arg1 - Level of mutex * arg2 - Index of mutex */ Method (M331, 3, NotSerialized) { /* Local1 - the value of flag (index of thread owning the mutex) */ Local0 = DerefOf (FL00 [Arg1]) Local1 = DerefOf (Local0 [Arg2]) If (Local1) { If ((Local1 == Arg0)) { Local7 = M21E ("Mutex ", Arg1, Arg2) Concatenate (Local7, " is already owned by thr ", Local7) Concatenate (Local7, Arg0, Local7) WRN0 (Arg0, WN00, Local7) } Else { SE00 (Arg0, ER01, "Error er01") } } /* Set up flag */ DerefOf (FL00 [Arg1]) [Arg2] = Arg0 /* Increment counter cnt0 (owning by all threads) */ Local0 = DerefOf (CNT0 [Arg1]) Local1 = DerefOf (Local0 [Arg2]) Local1++ DerefOf (CNT0 [Arg1]) [Arg2] = Local1 /* Increment counter fl01 (owning by one thread) */ Local0 = DerefOf (FL01 [Arg1]) Local1 = DerefOf (Local0 [Arg2]) Local1++ DerefOf (FL01 [Arg1]) [Arg2] = Local1 } /* * For Release * * Check up and reset flag (fl00) corresponding to this Mutex * (check that it was not changed by other threads while this * one was sleeping). * * arg0 - Index of thread * arg1 - Level of mutex * arg2 - Index of mutex */ Method (M332, 3, NotSerialized) { /* Local1 - the value of flag (index of thread owning the mutex) */ Local0 = DerefOf (FL00 [Arg1]) Local1 = DerefOf (Local0 [Arg2]) If ((Local1 != Arg0)) { SE00 (Arg0, ER02, "Error er02") } Else { /* Reset flag */ /* Local1 - counter of owning the mutex by the same thread */ Local0 = DerefOf (FL01 [Arg1]) Local1 = DerefOf (Local0 [Arg2]) If ((Local1 == 0x00)) { SE00 (Arg0, ER08, "Error er08") } Else { Local1-- If ((Local1 == 0x00)) { /* * May be greater than one when owning mutex by the * same thread several times (allowed for ACPI mutex). */ DerefOf (FL00 [Arg1]) [Arg2] = 0x00 } DerefOf (FL01 [Arg1]) [Arg2] = Local1 } } } /* * Check up the value of counter corresponding to this Mutex * * arg0 - Level of mutex * arg1 - Index of mutex * arg2 - expected value of counter */ Method (M333, 3, NotSerialized) { Local0 = DerefOf (CNT0 [Arg0]) Local1 = DerefOf (Local0 [Arg1]) If ((Local1 != Arg2)) { ERR ("m333", Z149, 0x01EC, 0x00, 0x00, Local1, Arg2) Debug = Arg0 Debug = Arg1 } } /* * Specify the per-thread set of mutexes to deal with in operation * * arg0 - number of threads (threads actually in work) * arg1 - opcode of initialization * arg2 - Level of mutex (initial) * arg3 - Number of levels of mutexes * arg4 - Index of mutex (inside the level) * arg5 - Number of mutexes of the same level */ Method (M334, 6, Serialized) { Name (LPN0, 0x00) Name (LPC0, 0x00) LPN0 = Arg0 LPC0 = 0x00 While (LPN0) { /* For not a Control thread only */ If ((LPC0 != 0x00)) { Switch (Arg1) { Case (0x01) { /* c301 */ /* * One mutex of Index equal to * ((Index of current thread) - 1) */ P200 [LPC0] = Arg2 P201 [LPC0] = Arg3 Local0 = (LPC0 - 0x01) P202 [LPC0] = Local0 P203 [LPC0] = 0x01 } /* c300 */ Default { P200 [LPC0] = Arg2 P201 [LPC0] = Arg3 P202 [LPC0] = Arg4 P203 [LPC0] = Arg5 } } /* Switch() */ } /* if() */ LPN0-- LPC0++ } } /* * Control thread initiates slaves to Acquire * specified set of mutexes - on each specified * level - one mutex of Index which is equal to * ((Index of thread) - 1). * * When all slaves complete that operation checks up * the state of execution of operation provided by * slaves. * * arg0 - number of threads (total) * arg1 - number of threads (threads actually in work) * * ====== as for m334: * arg2 - Level of mutex (initial) * arg3 - Number of levels of mutexes * * arg4 - expected value of counter * arg5 - exceptional conditions flags (buffer/Integer) */ Method (M337, 6, Serialized) { Name (LPN0, 0x00) Name (LPC0, 0x00) /* Acquire specified set of mutexes */ /* Set up per-thread set of mutexes */ M334 (Arg1, C301, Arg2, Arg3, 0x00, 0x00) /* Init the exceptional conditions flags */ M215 (Arg0) /* Reset TimeOutValue and exceptional condition flags */ M20F (Arg1, Arg5, 0x00) /* c106 for all first arg1 threads */ M210 (BS00, Arg0, C106, 0x00, Arg1, 0x01, C102) /* cmd: Acquire specified set of mutexes */ M114 (Arg0) /* run */ /* Wait for all Slave threads */ M103 (Arg0) /* Check up the values of counters of all Mutexs */ LPN0 = Arg3 LPC0 = Arg2 While (LPN0) { M333 (LPC0, 0x00, Arg4) LPN0-- LPC0++ } } /* * Control thread initiates slaves to Release * specified set of mutexes - on each specified * level - one mutex of Index which is equal to * ((Index of thread) - 1). * * Control thread initiates slaves to Release * specified set of mutexes. * * arg0 - number of threads (total) * arg1 - number of threads (threads actually in work) * * ====== as for m334: * arg2 - Level of mutex (initial) * arg3 - Number of levels of mutexes */ Method (M338, 4, NotSerialized) { /* Set up per-thread set of mutexes */ M334 (Arg1, C301, Arg2, Arg3, 0x00, 0x00) /* c107 for all first arg1 threads */ M210 (BS00, Arg0, C107, 0x00, Arg1, 0x01, C102) /* cmd: Release specified set of mutexes */ M114 (Arg0) /* run */ /* Wait for all Slave threads */ M103 (Arg0) } /* * Control thread checks that the specified set of slave threads * hang on the specified operations or completed the operations. * * See m10e for args: * arg0 - number of threads * arg1 - buffer */ Method (M33D, 2, NotSerialized) { Local0 = M10F (Arg0, Arg1) If ((Local0 & 0x01)) { ERR ("m33d", Z149, 0x0280, 0x00, 0x00, Local0, 0x00) } If ((Local0 & 0x02)) { ERR ("m33d", Z149, 0x0283, 0x00, 0x00, Local0, 0x00) } } /* * Run command for the specified set of slaves * * arg0 - number of threads * arg1 - specificator of elements (see m20a) * arg2 - command */ Method (M33E, 3, NotSerialized) { M20A (BS00, Arg0, Arg2, Arg1) /* cmd */ M114 (Arg0) /* Wait for Slave threads */ M103 (Arg0) } /* * Control thread initiates commands for slaves to be fulfilled. * After commands execution checks the statuses of all threads. * * It should be one of the following: * - thread completed the specified command * - thread hangs (on the specified command) * - all other idle threads completed the 'idle-command' * (for all those threads not enumerated in either 'Expected * completion statuses' or 'Expected hang statuses' lists). * * Note: because of the restricted number of ACPI arguments available, * the input data are combined. * * arg0 - numbers of threads (buffer/Integer). * Integer: * number of threads both total and 'actually in work' * Buffer (elements of buffer): * 0-th element - number of threads (total) * 1-th element - number of threads (threads actually in work, not extra idle ones) * * arg1 - Commands (buffer/Integer). * * buffer/Integer, per-thread commands to be fulfilled * Integer: * 0 - undefined * non-zero - the same command for all slave threads * Buffer (elements of buffer): * 0 - undefined * non-zero - command for the relevant slave thread * * arg2 - Exceptional conditions flags (buffer/Integer) * * buffer/Integer, per-thread flags of exceptional conditions * Integer: * - non-zero means that we generate the same * exceptional condition for all slave threads * Buffer (elements of buffer): * 0 - exception is not expected * non-zero - means that we generate exceptional condition * for the relevant thread * * The particular value (X0) of the exceptional condition flag * corresponding to the particular thread means the following: * * 0: do nothing * non-zero: * * 1) before to run operation: * * check absence of any exception occured on this thread * * 2) after the operation is completed depending on X0: * * EX0E (particular undefined opcode of exception): * * check that no any exception occured on this thread * * otherwise: * * check that exception with opcode equal to X0 * has occured on this thread * * arg3 - Levels of mutexes (buffer/Integer). * * buffer/Integer, per-thread levels of mutexes * Integer: * - the same level of mutex for all slave threads * (number of levels is 1) * Buffer (elements of buffer): * Pairs: * - start level of mutex for the relevant thread * - number of levels * * arg4 - Indexes of mutexes (buffer/Integer). * * buffer/Integer, per-thread indexes of mutexes * Integer: * - the same index of mutex for all slave threads * (number of mutexes of the same level is 1) * Buffer (elements of buffer): * Pairs: * - start index of mutex for the relevant thread * - number of mutexes of the same level * * arg5 - Expected completion statuses (the same semantics as Commands) (buffer/Integer). * * buffer/Integer, per-thread commands to check for completion * Integer: * 0 - do nothing * non-zero - the same command for all slave threads * Buffer (elements of buffer): * 0 - do nothing * non-zero - command for the relevant slave thread * * arg6 - Expected hang statuses (the same semantics as Commands) (buffer/Integer). * * buffer/Integer, per-thread commands to check for hang * Integer: * 0 - do nothing * non-zero - the same command for all slave threads * Buffer (elements of buffer): * 0 - do nothing * non-zero - command for the relevant slave thread * * Note: non-zero 0-th element of the buffer means the * number of hanging threads expected to wake up * after some command of arg1 will be executed. */ Method (M33F, 7, Serialized) { Name (NTH0, 0x00) /* total */ Name (NTH1, 0x00) /* actually in work */ Name (HAS1, 0x00) /* has non-zero exception expectations */ /* Check params */ Local0 = M344 (Arg5, Arg6) If (Local0) { ERR ("m33f: incorrect parameters", Z149, 0x030D, 0x00, 0x00, Arg5, Arg6) Debug = Local0 Return (Zero) } /* Parse number of threads */ If ((ObjectType (Arg0) == C009)) { NTH0 = Arg0 NTH1 = Arg0 } Else { NTH0 = DerefOf (Arg0 [0x00]) NTH1 = DerefOf (Arg0 [0x01]) } /* 1) Command execution */ /* * Prepare buffers of per-thread commands and arguments * * Resulting data: bs00, p200, p201, p202, p203, p204 * * Note: not specified elements of buffers are not touched. */ HAS1 = M340 (NTH1, Arg1, Arg2, Arg3, Arg4) /* Allow slaves to execute their commands */ M114 (NTH0) /* 2) Check status of execution of commands */ /* Calculate the per-thread expectations of completion statuses */ Local0 = M342 (NTH0, NTH1, Arg5) /* Calculate the per-thread expectations of hang statuses */ Local1 = M342 (NTH0, NTH1, Arg6) /* Calculate the idle-threads mapping buffer */ Local2 = M343 (NTH0, NTH1, Local0, Local1) /* * So, each thread is represented in one and only one of sets: * * Local0 - expectations of completion * Local1 - expectations of hang * Local2 - idle */ /* Wait for all Slave threads and check their statuses */ M110 (NTH0, Local0, Local1, Local2) /* Reset exception expectation */ M336 (NTH0, HAS1) } /* * Prepare buffers of per-thread commands and arguments * * Resulting data: bs00, p200, p201, p202, p203 * * Note: don't touch not specified elements of buffer. * * arg0 - number of threads (threads actually in work) * arg1 - Commands (see m33f) * arg2 - Exceptional conditions flags (see m33f) * arg3 - Levels of mutexes (see m33f) * arg4 - Indexes of mutexes (see m33f) */ Method (M340, 5, Serialized) { Name (HAS0, 0x00) Name (HAS1, 0x00) /* has non-zero exception expectations */ Name (LPN0, 0x00) Name (LPC0, 0x00) Name (SLCT, 0x00) Name (CMD0, 0x00) Name (B000, Buffer (Arg0){}) Name (B200, Buffer (Arg0){}) Name (B201, Buffer (Arg0){}) Name (B202, Buffer (Arg0){}) Name (B203, Buffer (Arg0){}) Local0 = ObjectType (Arg1) If ((Local0 == C009)) { /* Integer */ CMD0 = Arg1 If (!CMD0) { Return (Zero) } } Else { /* Buffer/Package */ SLCT = 0x01 } LPN0 = Arg0 LPC0 = 0x00 While (LPN0) { /* For not a Control thread only */ If ((LPC0 != 0x00)) { If (SLCT) { CMD0 = DerefOf (Arg1 [LPC0]) } If (CMD0) { HAS0 = 0x01 B000 [LPC0] = CMD0 /* \M340.CMD0 */ /* Prepare arguments of command */ Local0 = M341 (CMD0, LPC0, Arg3, Arg4) If ((ObjectType (Local0) == C00C)) { Local1 = DerefOf (Local0 [0x00]) B200 [LPC0] = Local1 Local1 = DerefOf (Local0 [0x01]) B201 [LPC0] = Local1 Local1 = DerefOf (Local0 [0x02]) B202 [LPC0] = Local1 Local1 = DerefOf (Local0 [0x03]) B203 [LPC0] = Local1 } } } LPN0-- LPC0++ } /* Prepare the exceptional conditions flags buffer */ Local1 = M20E (Arg0, Arg2) /* * Prepare all the commands and arguments and then re-write * them into the target buffers looks there useful for debugging. */ If (HAS0) { LPN0 = Arg0 LPC0 = 0x00 While (LPN0) { CMD0 = DerefOf (B000 [LPC0]) If (CMD0) { BS00 [LPC0] = CMD0 /* \M340.CMD0 */ Local0 = DerefOf (B200 [LPC0]) P200 [LPC0] = Local0 Local0 = DerefOf (B201 [LPC0]) P201 [LPC0] = Local0 Local0 = DerefOf (B202 [LPC0]) P202 [LPC0] = Local0 Local0 = DerefOf (B203 [LPC0]) P203 [LPC0] = Local0 Local0 = DerefOf (Local1 [LPC0]) If (Local0) { HAS1 = 0x01 } P204 [LPC0] = Local0 P205 [LPC0] = TOVF /* \TOVF */ } LPN0-- LPC0++ } } Return (HAS1) /* \M340.HAS1 */ } /* * Prepare arguments of command * * arg0 - command * arg1 - index of thread * arg2 - Levels of mutexes (see m33f) * arg3 - Indexes of mutexes (see m33f) * * Return (no free ArgX to pass references to target Packages there, * so using Return): * - Package with elements to be filled * into p200, p201, p202, p203. * - Integer if no arguments. */ Method (M341, 4, Serialized) { Name (HAS0, 0x00) Name (P000, Package (0x04) { 0x00, 0x00, 0x00, 0x00 }) Name (I000, 0x00) Name (I001, 0x00) Name (I002, 0x00) Name (I003, 0x00) Switch (Arg0) { Case (Package (0x03) { 0xF6, 0xF7, 0xF3 } ) { /* 0xf6, c106 - Acquire specified set of mutexes */ /* 0xf7, c107 - Release specified set of mutexes */ /* 0xf3, c103 - Acquire/Sleep/Release */ /* * To calculate: * * i000 - starting level of mutex * i001 - number of levels * i002 - starting index of mutex (of the same level) * i003 - number of mutexes (of the same level) */ /* Levels */ Local0 = ObjectType (Arg2) If ((Local0 == C009)) { /* Integer */ I000 = Arg2 I001 = 0x01 } Else { /* Buffer/Package */ Local0 = (Arg1 * 0x02) I000 = DerefOf (Arg2 [Local0]) Local0++ I001 = DerefOf (Arg2 [Local0]) } /* Indexes */ Local0 = ObjectType (Arg3) If ((Local0 == C009)) { /* Integer */ I002 = Arg3 I003 = 0x01 } Else { /* Buffer/Package */ Local0 = (Arg1 * 0x02) I002 = DerefOf (Arg3 [Local0]) Local0++ I003 = DerefOf (Arg3 [Local0]) } HAS0 = 0x01 } Default { ERR ("m341: unexpected command:", Z149, 0x0403, 0x00, 0x00, 0x00, Arg0) } } If (HAS0) { P000 [0x00] = I000 /* \M341.I000 */ P000 [0x01] = I001 /* \M341.I001 */ P000 [0x02] = I002 /* \M341.I002 */ P000 [0x03] = I003 /* \M341.I003 */ Return (P000) /* \M341.P000 */ } Return (0x00) } /* * Prepare the per-thread status expectations mapping buffer * * arg0 - number of threads (total) * arg1 - number of threads (threads actually in work) * arg2 - Expected completion/hang statuses (see m33f) * * Return: * * Buffer (elements of buffer): * 0 - nothing to do for the relevant thread * non-zero - element of buffer means the last command * specified for the relevant thread. */ Method (M342, 3, Serialized) { Name (LPN0, 0x00) Name (LPC0, 0x00) Name (SLCT, 0x00) Name (CMD0, 0x00) Name (B000, Buffer (Arg0){}) Local0 = ObjectType (Arg2) If ((Local0 == C009)) { /* Integer */ CMD0 = Arg2 If (!CMD0) { Return (B000) /* \M342.B000 */ } } Else { /* Buffer/Package */ SLCT = 0x01 } LPN0 = Arg1 LPC0 = 0x00 While (LPN0) { If (SLCT) { CMD0 = DerefOf (Arg2 [LPC0]) } If (CMD0) { B000 [LPC0] = CMD0 /* \M342.CMD0 */ } LPN0-- LPC0++ } Return (B000) /* \M342.B000 */ } /* * Prepare the idle-threads mapping buffer * * arg0 - number of threads (total) * arg1 - number of threads (threads actually in work, not extra idle ones) * arg2 - Buffer, expected completion statuses (see m33f) * arg3 - Buffer, Expected hang statuses (see m33f) * * Return: * * Buffer (elements of buffer): * 0 - the relevant thread is non-idle * non-zero - the relevant thread is idle */ Method (M343, 4, Serialized) { Name (ERR0, 0x00) Name (IDLE, 0x00) Name (LPN0, 0x00) Name (LPC0, 0x00) Name (B000, Buffer (Arg0){}) LPN0 = Arg0 LPC0 = 0x00 While (LPN0) { IDLE = 0x00 If ((LPC0 >= Arg1)) { IDLE = 0x01 } Else { Local0 = DerefOf (Arg2 [LPC0]) Local1 = DerefOf (Arg3 [LPC0]) If ((Local0 && Local1)) { /* Expects both completion and hang simultaneously */ ERR0 = 0x01 } ElseIf ((!Local0 && !Local1)) { IDLE = 0x01 } } B000 [LPC0] = IDLE /* \M343.IDLE */ LPN0-- LPC0++ } If (ERR0) { ERR ("m333", Z149, 0x0477, 0x00, 0x00, 0x00, 0x00) } Return (B000) /* \M343.B000 */ } /* * Check pair of parameters * * arg0 - Expected completion statuses (see m33f). * arg1 - Expected hang statuses (see m33f). */ Method (M344, 2, Serialized) { Name (INT0, 0x00) Name (INT1, 0x00) Name (ALL0, 0x00) Name (ALL1, 0x00) If ((ObjectType (Arg0) == C009)) { INT0 = 0x01 If (Arg0) { ALL0 = 0x01 } } If ((ObjectType (Arg1) == C009)) { INT1 = 0x01 If (Arg1) { ALL1 = 0x01 } } If ((ALL0 || ALL1)) { If ((INT0 && INT0)) { If ((ALL0 && ALL1)) { Return (0x01) } } Else { Return (0x02) } } Return (0x00) } /* * Reset exception expectation * * arg0 - number of threads (total) * arg1 - non-zero -- has non-zero exception expectations */ Method (M336, 2, NotSerialized) { /* Add statistics of exceptions (total) */ EX10 += EXC0 /* \EXC0 */ If (Arg1) { If (!EXC0) { /* Expected exceptions but have none */ ERR ("m333", Z149, 0x04B3, 0x00, 0x00, EXC0, 0x00) } } ElseIf (EXC0) { /* Unexpected exceptions */ ERR ("m333", Z149, 0x04B8, 0x00, 0x00, EXC0, 0x00) } /*Reset EXC0 (the current number of exceptions handled) */ CH0A () M215 (Arg0) /* Reset TimeOutValue and exceptional condition flags */ } /* Init fl01 */ Method (M339, 0, Serialized) { Name (LPN0, 0x00) Name (LPC0, 0x00) Name (LPN1, 0x00) Name (LPC1, 0x00) LPN0 = MAX0 /* \MAX0 */ LPC0 = 0x00 While (LPN0) { LPN1 = MAX1 /* \MAX1 */ LPC1 = 0x00 While (LPN1) { DerefOf (FL01 [LPC0]) [LPC1] = 0x00 LPN1-- LPC1++ } LPN0-- LPC0++ } }