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     * Service routines of common use
30     */
31    Name (Z153, 0x99)
32    /*
33     * Fill the buffer with the same value
34     *
35     * arg0 - buffer
36     * arg1 - the length of buffer
37     * arg2 - the value
38     */
39    Method (M200, 3, Serialized)
40    {
41        Name (LPN0, 0x00)
42        Name (LPC0, 0x00)
43        LPN0 = Arg1
44        LPC0 = 0x00
45        While (LPN0)
46        {
47            /* For not a Control thread only */
48
49            If ((LPC0 != 0x00))
50            {
51                Arg0 [LPC0] = Arg2
52            }
53
54            LPN0--
55            LPC0++
56        }
57    }
58
59    /*
60     * Fill the region of buffer with the same value
61     *
62     * arg0 - buffer
63     * arg1 - the length of buffer
64     * arg2 - the value
65     *
66     * arg3 - start index
67     * arg4 - the length of region to be filled
68     *        0 - everywhere from index to the end of buffer
69     * arg5 - if non-zero than fill the ground value arg6 into the buffer
70     *        everywhere outside the specified region
71     * arg6 - the value of ground
72     */
73    Method (M210, 7, Serialized)
74    {
75        Name (LPN0, 0x00)
76        Name (LPC0, 0x00)
77        Name (SZ01, 0x00)
78        Name (IX02, 0x00)
79        If ((Arg3 >= Arg1))
80        {
81            ERR ("m210", Z153, __LINE__, 0x00, 0x00, Arg3, Arg1)
82            Return (Zero)
83        }
84
85        /* Sizes of fields */
86
87        If (Arg4)
88        {
89            SZ01 = Arg4
90        }
91        Else
92        {
93            SZ01 = (Arg1 - Arg3)
94        }
95
96        IX02 = (Arg3 + SZ01) /* \M210.SZ01 */
97        If ((IX02 > Arg1))
98        {
99            ERR ("m210", Z153, __LINE__, 0x00, 0x00, IX02, Arg1)
100            Debug = Arg1
101            Debug = Arg3
102            Debug = Arg4
103            Debug = Arg5
104            Return (Zero)
105        }
106
107        If (Arg5)
108        {
109            LPN0 = Arg1
110            LPC0 = 0x00
111        }
112        Else
113        {
114            LPN0 = SZ01 /* \M210.SZ01 */
115            LPC0 = Arg3
116        }
117
118        While (LPN0)
119        {
120            If (((LPC0 < Arg3) || (LPC0 >= IX02)))
121            {
122                Local0 = Arg6
123            }
124            Else
125            {
126                Local0 = Arg2
127            }
128
129            Arg0 [LPC0] = Local0
130            LPN0--
131            LPC0++
132        }
133    }
134
135    /*
136     * Report message of thread
137     * (adds index of thread and reports the message)
138     *
139     * arg0 - Index of current thread
140     * arg1 - s-flag of verbal mode
141     * arg2 - string
142     */
143    Method (M201, 3, NotSerialized)
144    {
145        If (Arg1)
146        {
147            Concatenate ("THREAD ", Arg0, Local0)
148            Concatenate (Local0, ": ", Local1)
149            Concatenate (Local1, Arg2, Local0)
150            Debug = Local0
151        }
152    }
153
154    /*
155     * Report the message conditionally according to the relevant
156     * flag of verbal mode.
157     *
158     * arg0 - Index of current thread
159     * arg1 - mc-flag of verbal mode
160     * arg2 - if do printing actually (or only return flag)
161     * arg3 - message - object to be sent to Debug
162     */
163    Method (M202, 4, Serialized)
164    {
165        Local0 = 0x00
166        Switch (Arg1)
167        {
168            Case (0x01)
169            {
170                /* allow only for Control Thread to report */
171
172                If (!Arg0)
173                {
174                    Local0 = 0x01
175                }
176            }
177            Case (0x02)
178            {
179                /* allow only for Worker Threads to report */
180
181                If (Arg0)
182                {
183                    Local0 = 0x01
184                }
185            }
186            Case (0x03)
187            {
188                /* allow for all threads to report */
189
190                Local0 = 0x01
191            }
192
193        }
194
195        If ((Local0 && Arg2))
196        {
197            Debug = Arg3
198        }
199
200        Return (Local0)
201    }
202
203    /*
204     * Report start of test
205     *
206     * arg0 - name of test
207     * arg1 - number of threads
208     * arg2 - ID of current thread
209     * arg3 - Index of current thread
210     */
211    Method (M204, 4, NotSerialized)
212    {
213        If (M202 (Arg3, VB01, 0x00, 0x00))
214        {
215            Concatenate ("Test ", Arg0, Local0)
216            Concatenate (Local0, " started", Local1)
217            Concatenate (Local1, ", threads num ", Local0)
218            Concatenate (Local0, Arg1, Local1)
219            Concatenate (Local1, ", ID of thread ", Local0)
220            Concatenate (Local0, Arg2, Local1)
221            Concatenate (Local1, ", Index of thread ", Local0)
222            Concatenate (Local0, Arg3, Local1)
223            Debug = Local1
224        }
225    }
226
227    /*
228     * Fulfill and report Sleep
229     *
230     * arg0 - Index of current thread
231     * arg1 - number of milliseconds to sleep
232     */
233    Method (M206, 2, NotSerialized)
234    {
235        M201 (Arg0, VB03, "Sleep")
236        /* Increment statistics of Sleep */
237
238        If ((VB04 && CTL0))
239        {
240            M212 (RefOf (P104), Arg0)
241        }
242
243        Sleep (Arg1)
244    }
245
246    /*
247     * Fulfill and report Stall
248     *
249     * arg0 - Index of current thread
250     * arg1 - number of MicroSeconds to Stall
251     */
252    Method (M207, 2, NotSerialized)
253    {
254        M201 (Arg0, VB03, "Stall")
255        Stall (Arg1)
256    }
257
258    /*
259     * Put the value into i-th element of the buffer
260     *
261     * arg0 - buffer
262     * arg1 - index
263     * arg2 - the value
264     */
265    Method (M208, 3, NotSerialized)
266    {
267        Arg0 [Arg1] = Arg2
268    }
269
270    /*
271     * Set up a sleeping mode
272     *
273     * arg0 - opcode of sleeping mode
274     */
275    Method (M209, 0, Serialized)
276    {
277        /* Milliseconds to sleep for non-zero slm0 */
278
279        Switch (0x00)
280        {
281            Case (0x00)
282            {
283                I100 = 0x0A
284                I101 = 0x0A
285                I102 = 0x0A
286                I103 = 0x0A
287                I104 = 0x0A
288                I105 = 0x0A
289                I106 = 0x0A
290                I107 = 0x0A
291                I108 = 0x0A
292            }
293            Default
294            {
295                I100 = 0x32
296                I101 = 0x64
297                I102 = 0xC8
298                I103 = 0x0190
299                I104 = 0x01F4
300                I105 = 0x4B
301                I106 = 0x96
302                I107 = 0xFA
303                I108 = 0x012C
304            }
305
306        }
307    }
308
309    /*
310     * Fill specified elements of buffer with the same value
311     *
312     * arg0 - buffer
313     * arg1 - the length of buffer
314     * arg2 - the value
315     * arg3 - specificator of elements:
316     *        Integer - all elements of arg0
317     *        Buffer  - for non-zero elements of arg3 only
318     */
319    Method (M20A, 4, Serialized)
320    {
321        Name (LPN0, 0x00)
322        Name (LPC0, 0x00)
323        Name (SLCT, 0x00)
324        Name (RUN0, 0x00)
325        Local0 = ObjectType (Arg3)
326        If ((Local0 != C009))
327        {
328            SLCT = 0x01
329        }
330
331        LPN0 = Arg1
332        LPC0 = 0x00
333        While (LPN0)
334        {
335            RUN0 = 0x01
336            If (SLCT)
337            {
338                RUN0 = DerefOf (Arg3 [LPC0])
339            }
340
341            If (RUN0)
342            {
343                Arg0 [LPC0] = Arg2
344            }
345
346            LPN0--
347            LPC0++
348        }
349    }
350
351    /*
352     * Print out all the auxiliary buffers
353     *
354     * arg0 - Index of current thread
355     * arg1 - message
356     */
357    Method (M20B, 2, NotSerialized)
358    {
359        Concatenate ("Print out the auxiliary buffers (bs00,bs01,bs02) <", Arg1, Local0)
360        Concatenate (Local0, ">", Local1)
361        M201 (Arg0, 0x01, Local1)
362        M201 (Arg0, 0x01, BS00)
363        M201 (Arg0, 0x01, BS01)
364        M201 (Arg0, 0x01, BS02)
365        M201 (Arg0, 0x01, BS03)
366    }
367
368    /*
369     * Return numbers of threads Buffer
370     *
371     * arg0 - number of threads (total)
372     * arg1 - number of threads (threads actually in work, not extra idle ones)
373     */
374    Method (M20D, 2, Serialized)
375    {
376        Name (NTH0, Buffer (0x02){})
377        NTH0 [0x00] = Arg0
378        NTH0 [0x01] = Arg1
379        Return (NTH0) /* \M20D.NTH0 */
380    }
381
382    /*
383     * Prepare the exceptional conditions flags buffer
384     *
385     * arg0 - number of threads
386     * arg1 - Exceptional conditions flags (buffer/Integer)
387     */
388    Method (M20E, 2, Serialized)
389    {
390        Name (LPN0, 0x00)
391        Name (LPC0, 0x00)
392        Local0 = ObjectType (Arg1)
393        If ((Local0 != C009))
394        {
395            /* Not Integer */
396
397            Return (Arg1)
398        }
399
400        Name (B000, Buffer (Arg0){})
401        LPN0 = Arg0
402        LPC0 = 0x00
403        While (LPN0)
404        {
405            /* Flag of exceptional condition */
406
407            B000 [LPC0] = Arg1
408            LPN0--
409            LPC0++
410        }
411
412        Return (B000) /* \M20E.B000 */
413    }
414
415    /*
416     * Initialize the exceptional conditions flags (p204 & FLG0)
417     * (initialize expectation of exceptions).
418     *
419     * arg0 - number of threads
420     * arg1 - exceptional conditions flags (buffer/Integer)
421     * arg2 - non-zero means to check absence of exception
422     *        before and after each operation additionally
423     *        to the checking (if any) specified per-operation.
424     */
425    Method (M20F, 3, Serialized)
426    {
427        Name (LPN0, 0x00)
428        Name (LPC0, 0x00)
429        Name (SLCT, 0x00)
430        Name (EX00, 0x00)
431        Local0 = ObjectType (Arg1)
432        If ((Local0 == C009))
433        {
434            /* Integer */
435
436            EX00 = Arg1
437        }
438        Else
439        {
440            /* Buffer/Package */
441
442            SLCT = 0x01
443        }
444
445        LPN0 = Arg0
446        LPC0 = 0x00
447        While (LPN0)
448        {
449            If (SLCT)
450            {
451                /* Flag of exceptional condition */
452
453                EX00 = DerefOf (Arg1 [LPC0])
454            }
455
456            P204 [LPC0] = EX00 /* \M20F.EX00 */
457            LPN0--
458            LPC0++
459        }
460
461        FLG0 = Arg2
462    }
463
464    /*
465     * Initialize the TimeOutValue mapping buffer
466     *
467     * arg0 - number of threads (total)
468     * arg1 - number of threads (threads actually in work)
469     * arg2 - (buffer/Integer) of TimeOutValue
470     */
471    Method (M214, 3, Serialized)
472    {
473        Name (LPN0, 0x00)
474        Name (LPC0, 0x00)
475        Name (SLCT, 0x00)
476        Name (TOPC, 0x00)
477        Local0 = ObjectType (Arg2)
478        If ((Local0 == C009))
479        {
480            /* Integer */
481
482            TOPC = Arg2
483        }
484        Else
485        {
486            /* Buffer/Package */
487
488            SLCT = 0x01
489        }
490
491        LPN0 = Arg1
492        LPC0 = 0x00
493        While (LPN0)
494        {
495            If (SLCT)
496            {
497                TOPC = DerefOf (Arg2 [LPC0])
498            }
499
500            P205 [LPC0] = TOPC /* \M214.TOPC */
501            LPN0--
502            LPC0++
503        }
504    }
505
506    /*
507     * Reset TimeOutValue and exceptional conditions flags to default
508     *
509     * arg0 - number of threads (total)
510     */
511    Method (M215, 1, NotSerialized)
512    {
513        M20F (Arg0, 0x00, 0x00)       /* Reset the exceptional conditions flags */
514        M214 (Arg0, Arg0, TOVF) /* Set TimeOutValue to default */
515    }
516
517    /*
518     * Report statistics
519     *
520     * arg0 - number of threads
521     */
522    Method (M211, 1, Serialized)
523    {
524        Name (LPN0, 0x00)
525        Name (LPC0, 0x00)
526        /* global data not initialized */
527
528        If (!GLDI)
529        {
530            Return (Zero)
531        }
532
533        Debug = "================ Per-thread statistics: ================"
534        Local0 = "Errors   scale   : "
535        Local1 = "          number : "
536        Local2 = "Warnings   scale : "
537        Local3 = "          number : "
538        Local4 = "Sleep     number : "
539        Local5 = "Acquire   number : "
540        Local6 = "Release   number : "
541        LPN0 = Arg0
542        LPC0 = 0x00
543        While (LPN0)
544        {
545            Local7 = DerefOf (P100 [LPC0])
546            Concatenate (Local0, Local7, Local0)
547            If ((LPN0 != 0x01))
548            {
549                Concatenate (Local0, ", ", Local0)
550            }
551
552            Local7 = DerefOf (P101 [LPC0])
553            Concatenate (Local1, Local7, Local1)
554            If ((LPN0 != 0x01))
555            {
556                Concatenate (Local1, ", ", Local1)
557            }
558
559            Local7 = DerefOf (P102 [LPC0])
560            Concatenate (Local2, Local7, Local2)
561            If ((LPN0 != 0x01))
562            {
563                Concatenate (Local2, ", ", Local2)
564            }
565
566            Local7 = DerefOf (P103 [LPC0])
567            Concatenate (Local3, Local7, Local3)
568            If ((LPN0 != 0x01))
569            {
570                Concatenate (Local3, ", ", Local3)
571            }
572
573            Local7 = DerefOf (P104 [LPC0])
574            Concatenate (Local4, Local7, Local4)
575            If ((LPN0 != 0x01))
576            {
577                Concatenate (Local4, ", ", Local4)
578            }
579
580            Local7 = DerefOf (P105 [LPC0])
581            Concatenate (Local5, Local7, Local5)
582            If ((LPN0 != 0x01))
583            {
584                Concatenate (Local5, ", ", Local5)
585            }
586
587            Local7 = DerefOf (P106 [LPC0])
588            Concatenate (Local6, Local7, Local6)
589            If ((LPN0 != 0x01))
590            {
591                Concatenate (Local6, ", ", Local6)
592            }
593
594            LPN0--
595            LPC0++
596        }
597
598        Debug = Local0
599        Debug = Local1
600        Debug = Local2
601        Debug = Local3
602        Debug = Local4
603        Debug = Local5
604        Debug = Local6
605        Concatenate ("Exceptions total : ", EX10, Debug)
606        Debug = "========================================================"
607    }
608
609    /*
610     * Increment element of Package
611     *
612     * arg0 - RefOf of Package
613     * arg1 - index of element
614     */
615    Method (M212, 2, NotSerialized)
616    {
617        Local0 = DerefOf (DerefOf (Arg0) [Arg1])
618        Local0++
619        DerefOf (Arg0) [Arg1] = Local0
620    }
621
622    /*
623     * Return the number of threads to be the number of threads actually in work
624     * (including Control thread).
625     * Should be not less than 3.
626     *
627     * Note: to be provided that arg0 is not less than the test needs
628     *       to perform effective checking according to its scenario.
629     *
630     * arg0 - number of threads (total)
631     * arg1 - maximal number of threads according to scenario of test (including Control thread)
632     * arg2 - if non-zero, then the number of treads to be actually in work in reduced mode (including Control thread)
633     */
634    Method (M213, 3, Serialized)
635    {
636        Name (NUM, 0x00)
637        NUM = Arg0
638        If (Arg1)
639        {
640            NUM = Arg1
641        }
642
643        If (REDM)
644        {
645            If (Arg2)
646            {
647                NUM = Arg2
648            }
649        }
650
651        If ((Arg0 < NUM))
652        {
653            NUM = Arg0
654        }
655
656        Return (NUM) /* \M213.NUM_ */
657    }
658