1    /*
2     * Some or all of this work - Copyright (c) 2006 - 2021, Intel Corp.
3     * All rights reserved.
4     *
5     * Redistribution and use in source and binary forms, with or without modification,
6     * are permitted provided that the following conditions are met:
7     *
8     * Redistributions of source code must retain the above copyright notice,
9     * this list of conditions and the following disclaimer.
10     * Redistributions in binary form must reproduce the above copyright notice,
11     * this list of conditions and the following disclaimer in the documentation
12     * and/or other materials provided with the distribution.
13     * Neither the name of Intel Corporation nor the names of its contributors
14     * may be used to endorse or promote products derived from this software
15     * without specific prior written permission.
16     *
17     * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18     * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19     * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20     * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21     * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22     * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23     * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24     * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
25     * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
26     * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27     */
28    /*
29     * Bug 248:
30     *
31     * SUMMARY: Incorrect ReferenceCount on Switch operation
32     */
33    Method (M02D, 0, NotSerialized)
34    {
35        /*
36         * NoOp -
37         * all them are for tracking only - to simplify debugging
38         */
39        Method (M003, 1, Serialized)
40        {
41            Noop
42            Switch (ToInteger (Arg0))
43            {
44                Case (0x00)
45                {
46                    Debug = "m003"
47                }
48
49            }
50
51            Noop
52        }
53
54        Method (M004, 1, NotSerialized)
55        {
56            Noop
57            If (Arg0)
58            {
59                Debug = "m004"
60            }
61
62            Noop
63        }
64
65        Method (M1A8, 2, NotSerialized)
66        {
67            If (Arg1)
68            {
69                M003 (Arg0)
70            }
71            Else
72            {
73                M004 (Arg0)
74            }
75        }
76
77        Method (M1A9, 0, Serialized)
78        {
79            Name (SW00, 0x01)
80            Name (HG00, 0x00) /* if non-zero - the test hangs */
81            Name (P91E, Package (0x01)
82            {
83                0xABCD0000
84            })
85            If (0x01)
86            {
87                Local0 = Local1 = P91E [0x00]
88            }
89            Else
90            {
91                Local0 = 0xABCD0000
92                Local1 = 0xABCD0001
93            }
94
95            If ((DerefOf (Local0) != 0xABCD0000))
96            {
97                ERR (__METHOD__, ZFFF, __LINE__, 0x00, 0x00, DerefOf (Local0), 0xABCD0000)
98            }
99
100            Debug = "============== sit 0 (Local0):"
101            M1A8 (Local0, SW00)
102            /*
103             * At this point, after returning from m1a8
104             * for the non-zero sw00, the object attached
105             * to Local0 has been deleted. It is the essence
106             * of the bug.
107             */
108            If (HG00)
109            {
110                /*
111                 * To show visually the consequences of the anomaly
112                 * run this code. It causes hang.
113                 */
114                Debug = "============== sit 1 (Local1):"
115                M1A8 (Local1, SW00)
116                Debug = "============== sit 2:"
117                Local7 = ObjectType (Local0)
118                Debug = Local7
119                Local7 = ObjectType (Local1)
120                Debug = Local7
121                Debug = Local0
122                Debug = Local1
123            }
124
125            Debug = "============== before checking:"
126            If ((DerefOf (Local0) != 0xABCD0000))
127            {
128                ERR (__METHOD__, ZFFF, __LINE__, 0x00, 0x00, DerefOf (Local0), 0xABCD0000)
129            }
130
131            Debug = "============== end of test"
132        }
133
134        Method (MM00, 0, NotSerialized)
135        {
136            M1A9 ()
137        }
138
139        CH03 (__METHOD__, 0x00, __LINE__, 0x00, 0x00)
140        MM00 ()
141        /* Check opcode of the last exception */
142
143        CH04 (__METHOD__, 0x02, 0x2F, 0x00, __LINE__, 0x00, 0x00) /* AE_AML_OPERAND_TYPE */
144    }
145
146    /*
147     * It is Functional:Reference:ref07.asl:Method(m1d5)
148     */
149    Method (M03D, 0, Serialized)
150    {
151        Name (I001, 0x00)
152        Name (P000, Package (0x02)
153        {
154            0x77,
155            0x88
156        })
157        Name (SW00, 0x01)
158        Name (HG00, 0x01) /* if non-zero - the test hangs */
159        Name (HG01, 0x01) /* if non-zero - the test hangs */
160        Name (HG02, 0x01) /* if non-zero - the test hangs */
161        CH03 (__METHOD__, 0x00, __LINE__, 0x00, 0x00)
162        CopyObject (Local0 = P000 [0x01], I001) /* \M03D.I001 */
163        CH03 (__METHOD__, 0x00, __LINE__, 0x00, 0x00)
164        /* Type of i001 should be already IRef here, */
165        /* so, don't expect exception. */
166        I001 = Local0 = P000 [0x00]
167        CH03 (__METHOD__, 0x00, __LINE__, 0x00, 0x00)
168        Local7 = (Local0 + 0x01)
169        If (Y248)
170        {
171            HG00 = 0x01
172            HG01 = 0x01
173            HG02 = 0x01
174        }
175
176        /*
177         * To show visually the consequences of the anomaly
178         * run one of code below. They cause hang.
179         */
180        If (HG00)
181        {
182            /* Infinite loop of printing */
183
184            Local1 = 0x00
185            Debug = Local0
186        }
187
188        If (HG01)
189        {
190            /* Infinite loop of printing */
191
192            Debug = Local0
193            Debug = Local0
194        }
195
196        If (HG02)
197        {
198            Local1 = 0x00
199            Debug = "============== sit 2:"
200            Local7 = ObjectType (Local0)
201            Debug = Local7
202        }
203
204        CH04 (__METHOD__, 0x00, 0xFF, 0x00, __LINE__, 0x00, 0x00)
205        Local7 = (I001 + 0x01)
206        CH04 (__METHOD__, 0x00, 0xFF, 0x00, __LINE__, 0x00, 0x00)
207        /*
208         * Looks identical to b248: "Incorrect ReferenceCount on Switch operation"
209         * (though there is no Switch operation)
210         *
211         * Reference count of Local0 is mistakenly zeroed there too.
212         *
213         * [ACPI Debug]  String: [0x0F] "<-------- 0000>"
214         * [ACPI Debug]  Reference: [Debug]
215         * [ACPI Debug]  String: [0x0F] "<-------- 1111>"
216         *
217         * [ACPI Debug]  String: [0x0F] "<-------- 0000>"
218         * [ACPI Debug]  [ACPI Debug]  String: [0x0F] "<-------- 1111>"
219         */
220        Debug = "<-------- 0000>"
221        Debug = Local0
222        Debug = "<-------- 1111>"
223    }
224