1/*
2 * Some or all of this work - Copyright (c) 2006 - 2016, 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/*
30 * UnLoad ASL operator functionality
31 */
32
33/*
34 * This sub-test is intended to comprehensively verify
35 * the Unload ASL operator functionality.
36 *
37 * Performs a run-time unload of a Definition Block that was
38 * loaded using a Load (and LoadTable) term.
39 *
40 * The overall functionality of the Unload Objects is indirectly
41 * verified by other Table management tests as far as Unload is
42 * needed to perform cleanup and check effectiveness of Load and
43 * LoadTable operators.
44 *
45 *    17.5.126   Unload (Unload Definition Block)
46 *    Syntax
47 * Unload (Handle)
48 *
49 * On testing the following issues should be covered (actually in the tests
50 * of loading except for the exceptional conditions ones):
51 *
52 * - successful execution of the Unload operator for the specified DDBHandle
53 *   obtained through loading of a SSDT from a proper location,
54 *
55 * - successful execution of the Unload operator for the specified DDBHandle
56 *   obtained through LoadTable operator,
57 *
58 * - the Handle parameter of the Unload can be specified as Named Object,
59 *   LocalX, ArgX, Derefof (to Index or RefOf reference), and Method call,
60 *
61 * - all namespace objects created as a result of the corresponding Load
62 *   operation are removed from the namespace,
63 *
64 * - unloading a number of different SSDTs,
65 *
66 * - Load/UnLoad processing can be done with the same table many times,
67 *
68 * - exceptional conditions caused by inappropriate data:
69 *   = the parameter of the UnLoad operator is not of DDBHandle type,
70 *   = execute UnLoad operator with the same DDBHandle repeatedly,
71 *   = the operand of UnLoad operator is absent.
72 *
73 * Can not be tested following issues:
74 * - unloading a SSDT to be a synchronous operation ("the control methods
75 *   defined in the Definition Block are not executed during load time")
76 */
77
78Name(z175, 175)
79
80Device(DTM1) {
81
82	// Different Sources to specify DDBHandle for UnLoad.
83	// Most of them (Named Object, LocalX, ArgX, Derefof)
84	// are checked in load.asl
85
86	// DDBHandle returned by Method call
87	Method(tst0, 1, Serialized)
88	{
89		Name(HI0, 0)
90
91		Method(m000) {Return (HI0)}
92
93		Concatenate(arg0, "-tst0", arg0)
94
95		Store(\DTM0.BUF0, \DTM0.RFU0)
96
97		if (CondRefof(\SSS0, Local0)) {
98			err(arg0, z175, 0x000, 0, 0, "\\SSS0", 1)
99			return
100		}
101
102		// Modify Revision field of SSDT
103		Store(Add(\DTM0.CREV, 1), \DTM0.CREV)
104
105		// Recalculate and save CheckSum
106		Store(\DTM0.RFU0, Local0)
107		Store(Add(\DTM0.SUM, \DTM0.CHSM(Local0, SizeOf (Local0))), \DTM0.SUM)
108
109		if (CH03(arg0, z175, 0x001, 0, 0)) {
110			return
111		}
112
113		Load(\DTM0.RFU0, HI0)
114
115		if (CH03(arg0, z175, 0x002, 0, 0)) {
116			return
117		}
118
119		Store("Table Loaded", Debug)
120
121		if (y260) {
122			Store(ObjectType(HI0), Local1)
123			if (LNotEqual(Local1, c017)) { // DDB Handle
124				err(arg0, z175, 0x003, 0, 0, Local1, c017)
125			}
126		}
127
128		// Check the new Object appears
129
130		if (CondRefof(\SSS0, Local0)) {
131		} else {
132			err(arg0, z175, 0x004, 0, 0, "\\SSS0", 0)
133		}
134
135		Store(ObjectType(Local0), Local1)
136		if (LNotEqual(Local1, c010)) { // Method
137			err(arg0, z175, 0x005, 0, 0, Local1, c010)
138		} else {
139			Store(\SSS0(), Local0)
140			if (CH03(arg0, z175, 0x006, "\\SSS0", 1)) {
141				return
142			}
143			if (LNotEqual("\\SSS0", Local0)) {
144				err(arg0, z175, 0x007, 0, 0, Local0, "\\SSS0")
145			}
146		}
147
148		// UnLoad operator execution
149		UnLoad(m000())
150
151		if (CH03(arg0, z175, 0x008, 0, 0)) {
152			return
153		}
154
155		Store("Table Unloaded", Debug)
156
157		if (CondRefof(\SSS0, Local0)) {
158			err(arg0, z175, 0x009, 0, 0, "\\SSS0", 1)
159		}
160		return
161	}
162
163	// All namespace objects created as a result of the corresponding
164	// Load operation are absent in the namespace after UnLoad
165	Method(tst1, 1, Serialized)
166	{
167		Name(DDB0, 0)
168		Name(DDB1, 0)
169
170		Method(m000, 4)
171		{
172			Concatenate(arg0, "-m000.", arg0)
173			Concatenate(arg0, arg1, arg0)
174
175			Store(ObjectType(arg2), Local0)
176			if (LNotEqual(arg3, Local0)) {
177				err(arg0, z175, 0x010, 0, 0, Local0, arg3)
178				return (1)
179			}
180
181			return (0)
182		}
183
184		Method(m001, 1)
185		{
186			Concatenate(arg0, "-m001", arg0)
187
188			// Integer
189			if (CondRefof(\AUXD.INT0, Local0)) {
190				err(arg0, z175, 0x011, 0, 0, "\\AUXD.INT0", 1)
191				return (1)
192			}
193
194			// String
195			if (CondRefof(\AUXD.STR0, Local0)) {
196				err(arg0, z175, 0x012, 0, 0, "\\AUXD.STR0", 1)
197				return (1)
198			}
199
200			// Buffer
201			if (CondRefof(\AUXD.BUF0, Local0)) {
202				err(arg0, z175, 0x013, 0, 0, "\\AUXD.BUF0", 1)
203				return (1)
204			}
205
206			// Package
207			if (CondRefof(\AUXD.PAC0, Local0)) {
208				err(arg0, z175, 0x014, 0, 0, "\\AUXD.PAC0", 1)
209				return (1)
210			}
211
212			// Field Unit
213			if (CondRefof(\AUXD.FLU0, Local0)) {
214				err(arg0, z175, 0x015, 0, 0, "\\AUXD.FLU0", 1)
215				return (1)
216			}
217
218			// Device
219			if (CondRefof(\AUXD.DEV0, Local0)) {
220				err(arg0, z175, 0x016, 0, 0, "\\AUXD.DEV0", 1)
221				return (1)
222			}
223
224			// Event
225			if (CondRefof(\AUXD.EVE0, Local0)) {
226				err(arg0, z175, 0x017, 0, 0, "\\AUXD.EVE0", 1)
227				return (1)
228			}
229
230			// Method
231			if (CondRefof(\AUXD.MMM0, Local0)) {
232				err(arg0, z175, 0x018, 0, 0, "\\AUXD.MMM0", 1)
233				return (1)
234			}
235
236			// Mutex
237			if (CondRefof(\AUXD.MTX0, Local0)) {
238				err(arg0, z175, 0x019, 0, 0, "\\AUXD.MTX0", 1)
239				return (1)
240			}
241
242			// OpRegion
243			if (CondRefof(\AUXD.OPR0, Local0)) {
244				err(arg0, z175, 0x01a, 0, 0, "\\AUXD.OPR0", 1)
245				return (1)
246			}
247
248			// Power Resource
249			if (CondRefof(\AUXD.PWR0, Local0)) {
250				err(arg0, z175, 0x01b, 0, 0, "\\AUXD.PWR0", 1)
251				return (1)
252			}
253
254			// Processor
255			if (CondRefof(\AUXD.CPU0, Local0)) {
256				err(arg0, z175, 0x01c, 0, 0, "\\AUXD.CPU0", 1)
257				return (1)
258			}
259
260			// Thermal Zone
261			if (CondRefof(\AUXD.TZN0, Local0)) {
262				err(arg0, z175, 0x01d, 0, 0, "\\AUXD.TZN0", 1)
263				return (1)
264			}
265
266			// Buffer Field
267			if (CondRefof(\AUXD.BFL0, Local0)) {
268				err(arg0, z175, 0x01e, 0, 0, "\\AUXD.BFL0", 1)
269				return (1)
270			}
271
272			return (0)
273		}
274
275		Concatenate(arg0, "-tst1", arg0)
276
277		// Check absence of the auxiliary table Objects before Load
278		if (m001(Concatenate(arg0, ".before"))) {
279			return (1)
280		}
281
282		// Load auxiliary table
283		Store(\DTM0.BUF3, \DTM0.RFU3)
284		Load(\DTM0.RFU3, DDB0)
285
286		if (CH03(arg0, z175, 0x01f, 0, 0)) {
287			return (1)
288		}
289
290		// Integer
291		if (CondRefof(\AUXD.INT0, Local0)) {
292			m000(arg0, "int", Local0, c009)
293		} else {
294			err(arg0, z175, 0x021, 0, 0, "\\AUXD.INT0", 0)
295		}
296
297		// String
298		if (CondRefof(\AUXD.STR0, Local0)) {
299			m000(arg0, "str", Local0, c00a)
300		} else {
301			err(arg0, z175, 0x022, 0, 0, "\\AUXD.STR0", 0)
302		}
303
304		// Buffer
305		if (CondRefof(\AUXD.BUF0, Local0)) {
306			m000(arg0, "buf", Local0, c00b)
307		} else {
308			err(arg0, z175, 0x023, 0, 0, "\\AUXD.BUF0", 0)
309		}
310
311		// Package
312		if (y286) {
313			if (CondRefof(\AUXD.PAC0, Local0)) {
314				m000(arg0, "pac", Local0, c00c)
315			} else {
316				err(arg0, z175, 0x024, 0, 0, "\\AUXD.PAC0", 0)
317			}
318		}
319
320		// Field Unit
321		if (CondRefof(\AUXD.FLU0, Local0)) {
322			m000(arg0, "flu", Local0, c00d)
323		} else {
324			err(arg0, z175, 0x025, 0, 0, "\\AUXD.FLU0", 0)
325		}
326
327		// Device
328		if (CondRefof(\AUXD.DEV0, Local0)) {
329			m000(arg0, "dev", Local0, c00e)
330		} else {
331			err(arg0, z175, 0x026, 0, 0, "\\AUXD.DEV0", 0)
332		}
333
334		// Event
335		if (CondRefof(\AUXD.EVE0, Local0)) {
336			m000(arg0, "evt", Local0, c00f)
337		} else {
338			err(arg0, z175, 0x027, 0, 0, "\\AUXD.EVE0", 0)
339		}
340
341		// Method
342		if (CondRefof(\AUXD.MMM0, Local0)) {
343			m000(arg0, "met", Local0, c010)
344		} else {
345			err(arg0, z175, 0x028, 0, 0, "\\AUXD.MMM0", 0)
346		}
347
348		// Mutex
349		if (CondRefof(\AUXD.MTX0, Local0)) {
350			m000(arg0, "mtx", Local0, c011)
351		} else {
352			err(arg0, z175, 0x029, 0, 0, "\\AUXD.MTX0", 0)
353		}
354
355		// OpRegion
356		if (CondRefof(\AUXD.OPR0, Local0)) {
357			m000(arg0, "opr", Local0, c012)
358		} else {
359			err(arg0, z175, 0x02a, 0, 0, "\\AUXD.OPR0", 0)
360		}
361
362		// Power Resource
363		if (CondRefof(\AUXD.PWR0, Local0)) {
364			m000(arg0, "pwr", Local0, c013)
365		} else {
366			err(arg0, z175, 0x02b, 0, 0, "\\AUXD.PWR0", 0)
367		}
368
369		// Processor
370		if (CondRefof(\AUXD.CPU0, Local0)) {
371			m000(arg0, "cpu", Local0, c014)
372		} else {
373			err(arg0, z175, 0x02c, 0, 0, "\\AUXD.CPU0", 0)
374		}
375
376		// Thermal Zone
377		if (CondRefof(\AUXD.TZN0, Local0)) {
378			m000(arg0, "cpu", Local0, c015)
379		} else {
380			err(arg0, z175, 0x02d, 0, 0, "\\AUXD.TZN0", 0)
381		}
382
383		// Buffer Field
384		if (CondRefof(\AUXD.BFL0, Local0)) {
385			m000(arg0, "bfl", Local0, c016)
386		} else {
387			err(arg0, z175, 0x02e, 0, 0, "\\AUXD.BFL0", 0)
388		}
389
390		UnLoad(DDB0)
391
392		CH03(arg0, z175, 0x02f, 0, 0)
393
394		// Check absence of the auxiliary table Objects after UnLoad
395		if (m001(Concatenate(arg0, ".after"))) {
396			return (1)
397		}
398
399		return (0)
400	}
401
402	// Load/UnLoad processing can be done with the same table many times
403	Method(tst2, 1)
404	{
405		Concatenate(arg0, "tst2.", arg0)
406
407		Store(5, Local0)
408
409		while (Local0) {
410			if (tst1(Concatenate(arg0, Mid("0123456789", Local0, 1)))) {
411				return (1)
412			}
413			Decrement(Local0)
414		}
415
416		return (0)
417	}
418
419	// Exceptions when the parameter of the UnLoad operator
420	// is not of DDBHandle type
421	Method(tst3, 1, Serialized)
422	{
423		Name(DDB0, 0)
424		Name(DDB1, 0)
425
426		Method(m000, 4)
427		{
428			Concatenate(arg0, "-m000.", arg0)
429			Concatenate(arg0, arg1, arg0)
430
431			Store(ObjectType(arg2), Local0)
432			if (LNotEqual(arg3, Local0)) {
433				err(arg0, z175, 0x031, 0, 0, Local0, arg3)
434				return (1)
435			}
436
437			UnLoad(Derefof(arg2))
438			CH04(arg0, 0, 47, z175, 0x032, 0, 0)	// AE_AML_OPERAND_TYPE
439
440			return (0)
441		}
442
443		Concatenate(arg0, "-tst3", arg0)
444
445		// Load auxiliary table
446		Store(\DTM0.BUF3, \DTM0.RFU3)
447		Load(\DTM0.RFU3, DDB0)
448
449		if (CH03(arg0, z175, 0x033, 0, 0)) {
450			return (1)
451		}
452
453		// Uninitialized
454		if (0) {
455			Store(0, Local1)
456		}
457		Store(ObjectType(Local1), Local0)
458		if (LNotEqual(c008, Local0)) {
459			err(arg0, z175, 0x034, 0, 0, Local0, c008)
460		} else {
461			UnLoad(Local1)
462			if (SLCK) {
463				CH04(arg0, 0, 47, z175, 0x035, 0, 0) // AE_AML_OPERAND_TYPE
464			} else {
465				CH04(arg0, 0, 49, z175, 0x035, 0, 0) // AE_AML_UNINITIALIZED_LOCAL
466			}
467		}
468
469		// Integer
470		m000(arg0, "int", Refof(\AUXD.INT0), c009)
471
472		// String
473		m000(arg0, "str", Refof(\AUXD.STR0), c00a)
474
475		// Buffer
476		m000(arg0, "buf", Refof(\AUXD.BUF0), c00b)
477
478		// Package
479
480		if (y286) {
481			m000(arg0, "pac", Refof(\AUXD.PAC0), c00c)
482		}
483
484		Store(ObjectType(\AUXD.PAC0), Local0)
485		if (LNotEqual(c00c, Local0)) {
486			err(arg0, z175, 0x036, 0, 0, Local0, c00c)
487		} else {
488			UnLoad(\AUXD.PAC0)
489			CH04(arg0, 0, 47, z175, 0x037, 0, 0) // AE_AML_OPERAND_TYPE
490		}
491
492		// Field Unit
493		m000(arg0, "flu", Refof(\AUXD.FLU0), c00d)
494
495		// Device
496		Store(ObjectType(\AUXD.DEV0), Local0)
497		if (LNotEqual(c00e, Local0)) {
498			err(arg0, z175, 0x038, 0, 0, Local0, c00e)
499		} else {
500			UnLoad(\AUXD.DEV0)
501			CH04(arg0, 0, 47, z175, 0x039, 0, 0) // AE_AML_OPERAND_TYPE
502		}
503
504		// Event
505		m000(arg0, "evt", Refof(\AUXD.EVE0), c00f)
506
507		// Method
508		m000(arg0, "met", Refof(\AUXD.MMM0), c010)
509
510		// Mutex
511		m000(arg0, "mtx", Refof(\AUXD.MTX0), c011)
512
513		// OpRegion
514		m000(arg0, "opr", Refof(\AUXD.OPR0), c012)
515
516		// Power Resource
517		m000(arg0, "pwr", Refof(\AUXD.PWR0), c013)
518
519		// Processor
520		m000(arg0, "cpu", Refof(\AUXD.CPU0), c014)
521
522		// Thermal Zone
523		Store(ObjectType(\AUXD.TZN0), Local0)
524		if (LNotEqual(c015, Local0)) {
525			err(arg0, z175, 0x03a, 0, 0, Local0, c015)
526		} else {
527			UnLoad(\AUXD.TZN0)
528			CH04(arg0, 0, 47, z175, 0x03b, 0, 0) // AE_AML_OPERAND_TYPE
529		}
530
531		// Buffer Field
532		m000(arg0, "bfl", Refof(\AUXD.BFL0), c016)
533
534		UnLoad(DDB0)
535
536		CH03(arg0, z175, 0x03c, 0, 0)
537
538		return (0)
539	}
540
541	// Exceptions when UnLoad is executed with the same DDBHandle repeatedly
542	Method(tst4, 1, Serialized)
543	{
544		Name(DDB0, 0)
545		Name(DDB1, 0)
546
547		Concatenate(arg0, "-tst4", arg0)
548
549		// Load auxiliary table
550		Store(\DTM0.BUF3, \DTM0.RFU3)
551		Load(\DTM0.RFU3, DDB0)
552
553		if (CH03(arg0, z175, 0x03d, 0, 0)) {
554			return (1)
555		}
556
557		// First Unload
558		UnLoad(DDB0)
559
560		if (CH03(arg0, z175, 0x03e, 0, 0)) {
561			return (1)
562		}
563
564		Store(5, Local0)
565		while (Local0) {
566
567			// Any next
568			UnLoad(DDB0)
569
570			CH04(arg0, 0, 28, z175, 0x03f, 5, Local0) // AE_BAD_PARAMETER
571
572			Decrement(Local0)
573		}
574
575		// Second DDBHandle
576		Store(\DTM0.BUF3, \DTM0.RFU3)
577		Load(\DTM0.RFU3, DDB1)
578
579		if (CH03(arg0, z175, 0x040, 0, 0)) {
580			return (1)
581		}
582
583		Store(5, Local0)
584		while (Local0) {
585
586			// Any next
587			UnLoad(DDB0)
588
589			CH04(arg0, 0, 28, z175, 0x041, 5, Local0) // AE_BAD_PARAMETER
590
591			Decrement(Local0)
592		}
593
594		UnLoad(DDB1)
595
596		if (CH03(arg0, z175, 0x042, 0, 0)) {
597			return (1)
598		}
599
600		return (0)
601	}
602
603	// Exceptions when the operand of UnLoad operator is absent
604	Method(tst5, 1, Serialized)
605	{
606		Name(DDB0, 0)
607
608		Method(m000) {Return (0) }
609		Method(m001) {Return (DDB0)}
610
611		Concatenate(arg0, "-tst5", arg0)
612
613		// Load auxiliary table
614		Store(\DTM0.BUF3, \DTM0.RFU3)
615		Load(\DTM0.RFU3, DDB0)
616
617		if (CH03(arg0, z175, 0x043, 0, 0)) {
618			return (1)
619		}
620
621		// Device
622		UnLoad(Derefof(Refof(\AUXD.DEV0)))
623		CH04(arg0, 0, 62, z175, 0x044, 0, 0) // AE_AML_NO_RETURN_VALUE
624
625		// Thermal Zone
626		UnLoad(Derefof(Refof(\AUXD.TZN0)))
627		CH04(arg0, 0, 62, z175, 0x045, 0, 0) // AE_AML_NO_RETURN_VALUE
628
629		// Method execution
630		CopyObject(m000, m001)
631		UnLoad(m001())
632
633		if (SLCK) {
634			CH04(arg0, 0, 47, z175, 0x046, 0, 0) // AE_AML_OPERAND_TYPE
635		} else {
636			CH04(arg0, 0, 47, z175, 0x047, 0, 0) // AE_AML_OPERAND_TYPE
637		}
638
639		UnLoad(DDB0)
640
641		if (CH03(arg0, z175, 0x048, 0, 0)) {
642			return (1)
643		}
644
645		return (0)
646	}
647}
648
649Method(TUL0,, Serialized)
650{
651	Name(ts, "TUL0")
652
653	CH03(ts, z175, 0x200, 0, 0)
654
655	// Different Sources to specify DDBHandle for UnLoad.
656	// Most of them (Named Object, LocalX, ArgX, Derefof)
657	// are checked in load.asl
658	// DDBHandle returned by Method call
659	SRMT("TUL0.tst0")
660	\DTM1.tst0(ts)
661
662	CH03(ts, z175, 0x201, 0, 0)
663
664	// All namespace objects created as a result of the corresponding
665	// Load operation are absent in the namespace after UnLoad
666	SRMT("TUL0.tst1")
667	\DTM1.tst1(ts)
668
669	CH03(ts, z175, 0x202, 0, 0)
670
671	// Load/UnLoad processing can be done with the same table many times
672	SRMT("TUL0.tst2")
673	\DTM1.tst2(ts)
674
675	CH03(ts, z175, 0x203, 0, 0)
676}
677
678// Exceptional conditions
679Method(TUL1,, Serialized)
680{
681	Name(ts, "TUL1")
682
683	// Exceptions when the parameter of the UnLoad operator
684	// is not of DDBHandle type
685	SRMT("TUL1.tst3")
686	\DTM1.tst3(ts)
687
688	// Exceptions when UnLoad is executed with the same DDBHandle repeatedly
689	SRMT("TUL1.tst4")
690	if (y292) {
691		\DTM1.tst4(ts)
692	} else {
693		BLCK()
694	}
695
696	// Exceptions when the operand of UnLoad operator is absent
697	SRMT("TUL1.tst5")
698	\DTM1.tst5(ts)
699}
700