1 | /****************************************************************************** |
2 | * |
3 | * Module Name: nsarguments - Validation of args for ACPI predefined methods |
4 | * |
5 | *****************************************************************************/ |
6 | |
7 | /* |
8 | * Copyright (C) 2000 - 2016, 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 MERCHANTIBILITY 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 | #include "acnamesp.h" |
47 | #include "acpredef.h" |
48 | |
49 | |
50 | #define _COMPONENT ACPI_NAMESPACE |
51 | ACPI_MODULE_NAME ("nsarguments" ) |
52 | |
53 | |
54 | /******************************************************************************* |
55 | * |
56 | * FUNCTION: AcpiNsCheckArgumentTypes |
57 | * |
58 | * PARAMETERS: Info - Method execution information block |
59 | * |
60 | * RETURN: None |
61 | * |
62 | * DESCRIPTION: Check the incoming argument count and all argument types |
63 | * against the argument type list for a predefined name. |
64 | * |
65 | ******************************************************************************/ |
66 | |
67 | void |
68 | AcpiNsCheckArgumentTypes ( |
69 | ACPI_EVALUATE_INFO *Info) |
70 | { |
71 | UINT16 ArgTypeList; |
72 | UINT8 ArgCount; |
73 | UINT8 ArgType; |
74 | UINT8 UserArgType; |
75 | UINT32 i; |
76 | |
77 | |
78 | /* If not a predefined name, cannot typecheck args */ |
79 | |
80 | if (!Info->Predefined) |
81 | { |
82 | return; |
83 | } |
84 | |
85 | ArgTypeList = Info->Predefined->Info.ArgumentList; |
86 | ArgCount = METHOD_GET_ARG_COUNT (ArgTypeList); |
87 | |
88 | /* Typecheck all arguments */ |
89 | |
90 | for (i = 0; ((i < ArgCount) && (i < Info->ParamCount)); i++) |
91 | { |
92 | ArgType = METHOD_GET_NEXT_TYPE (ArgTypeList); |
93 | UserArgType = Info->Parameters[i]->Common.Type; |
94 | |
95 | if (UserArgType != ArgType) |
96 | { |
97 | ACPI_WARN_PREDEFINED ((AE_INFO, Info->FullPathname, ACPI_WARN_ALWAYS, |
98 | "Argument #%u type mismatch - " |
99 | "Found [%s], ACPI requires [%s]" , (i + 1), |
100 | AcpiUtGetTypeName (UserArgType), |
101 | AcpiUtGetTypeName (ArgType))); |
102 | } |
103 | } |
104 | } |
105 | |
106 | |
107 | /******************************************************************************* |
108 | * |
109 | * FUNCTION: AcpiNsCheckAcpiCompliance |
110 | * |
111 | * PARAMETERS: Pathname - Full pathname to the node (for error msgs) |
112 | * Node - Namespace node for the method/object |
113 | * Predefined - Pointer to entry in predefined name table |
114 | * |
115 | * RETURN: None |
116 | * |
117 | * DESCRIPTION: Check that the declared parameter count (in ASL/AML) for a |
118 | * predefined name is what is expected (matches what is defined in |
119 | * the ACPI specification for this predefined name.) |
120 | * |
121 | ******************************************************************************/ |
122 | |
123 | void |
124 | AcpiNsCheckAcpiCompliance ( |
125 | char *Pathname, |
126 | ACPI_NAMESPACE_NODE *Node, |
127 | const ACPI_PREDEFINED_INFO *Predefined) |
128 | { |
129 | UINT32 AmlParamCount; |
130 | UINT32 RequiredParamCount; |
131 | |
132 | |
133 | if (!Predefined) |
134 | { |
135 | return; |
136 | } |
137 | |
138 | /* Get the ACPI-required arg count from the predefined info table */ |
139 | |
140 | RequiredParamCount = |
141 | METHOD_GET_ARG_COUNT (Predefined->Info.ArgumentList); |
142 | |
143 | /* |
144 | * If this object is not a control method, we can check if the ACPI |
145 | * spec requires that it be a method. |
146 | */ |
147 | if (Node->Type != ACPI_TYPE_METHOD) |
148 | { |
149 | if (RequiredParamCount > 0) |
150 | { |
151 | /* Object requires args, must be implemented as a method */ |
152 | |
153 | ACPI_BIOS_ERROR_PREDEFINED ((AE_INFO, Pathname, ACPI_WARN_ALWAYS, |
154 | "Object (%s) must be a control method with %u arguments" , |
155 | AcpiUtGetTypeName (Node->Type), RequiredParamCount)); |
156 | } |
157 | else if (!RequiredParamCount && !Predefined->Info.ExpectedBtypes) |
158 | { |
159 | /* Object requires no args and no return value, must be a method */ |
160 | |
161 | ACPI_BIOS_ERROR_PREDEFINED ((AE_INFO, Pathname, ACPI_WARN_ALWAYS, |
162 | "Object (%s) must be a control method " |
163 | "with no arguments and no return value" , |
164 | AcpiUtGetTypeName (Node->Type))); |
165 | } |
166 | |
167 | return; |
168 | } |
169 | |
170 | /* |
171 | * This is a control method. |
172 | * Check that the ASL/AML-defined parameter count for this method |
173 | * matches the ACPI-required parameter count |
174 | * |
175 | * Some methods are allowed to have a "minimum" number of args (_SCP) |
176 | * because their definition in ACPI has changed over time. |
177 | * |
178 | * Note: These are BIOS errors in the declaration of the object |
179 | */ |
180 | AmlParamCount = Node->Object->Method.ParamCount; |
181 | |
182 | if (AmlParamCount < RequiredParamCount) |
183 | { |
184 | ACPI_BIOS_ERROR_PREDEFINED ((AE_INFO, Pathname, ACPI_WARN_ALWAYS, |
185 | "Insufficient arguments - " |
186 | "ASL declared %u, ACPI requires %u" , |
187 | AmlParamCount, RequiredParamCount)); |
188 | } |
189 | else if ((AmlParamCount > RequiredParamCount) && |
190 | !(Predefined->Info.ArgumentList & ARG_COUNT_IS_MINIMUM)) |
191 | { |
192 | ACPI_BIOS_ERROR_PREDEFINED ((AE_INFO, Pathname, ACPI_WARN_ALWAYS, |
193 | "Excess arguments - " |
194 | "ASL declared %u, ACPI requires %u" , |
195 | AmlParamCount, RequiredParamCount)); |
196 | } |
197 | } |
198 | |
199 | |
200 | /******************************************************************************* |
201 | * |
202 | * FUNCTION: AcpiNsCheckArgumentCount |
203 | * |
204 | * PARAMETERS: Pathname - Full pathname to the node (for error msgs) |
205 | * Node - Namespace node for the method/object |
206 | * UserParamCount - Number of args passed in by the caller |
207 | * Predefined - Pointer to entry in predefined name table |
208 | * |
209 | * RETURN: None |
210 | * |
211 | * DESCRIPTION: Check that incoming argument count matches the declared |
212 | * parameter count (in the ASL/AML) for an object. |
213 | * |
214 | ******************************************************************************/ |
215 | |
216 | void |
217 | AcpiNsCheckArgumentCount ( |
218 | char *Pathname, |
219 | ACPI_NAMESPACE_NODE *Node, |
220 | UINT32 UserParamCount, |
221 | const ACPI_PREDEFINED_INFO *Predefined) |
222 | { |
223 | UINT32 AmlParamCount; |
224 | UINT32 RequiredParamCount; |
225 | |
226 | |
227 | if (!Predefined) |
228 | { |
229 | /* |
230 | * Not a predefined name. Check the incoming user argument count |
231 | * against the count that is specified in the method/object. |
232 | */ |
233 | if (Node->Type != ACPI_TYPE_METHOD) |
234 | { |
235 | if (UserParamCount) |
236 | { |
237 | ACPI_INFO_PREDEFINED ((AE_INFO, Pathname, ACPI_WARN_ALWAYS, |
238 | "%u arguments were passed to a non-method ACPI object (%s)" , |
239 | UserParamCount, AcpiUtGetTypeName (Node->Type))); |
240 | } |
241 | |
242 | return; |
243 | } |
244 | |
245 | /* |
246 | * This is a control method. Check the parameter count. |
247 | * We can only check the incoming argument count against the |
248 | * argument count declared for the method in the ASL/AML. |
249 | * |
250 | * Emit a message if too few or too many arguments have been passed |
251 | * by the caller. |
252 | * |
253 | * Note: Too many arguments will not cause the method to |
254 | * fail. However, the method will fail if there are too few |
255 | * arguments and the method attempts to use one of the missing ones. |
256 | */ |
257 | AmlParamCount = Node->Object->Method.ParamCount; |
258 | |
259 | if (UserParamCount < AmlParamCount) |
260 | { |
261 | ACPI_WARN_PREDEFINED ((AE_INFO, Pathname, ACPI_WARN_ALWAYS, |
262 | "Insufficient arguments - " |
263 | "Caller passed %u, method requires %u" , |
264 | UserParamCount, AmlParamCount)); |
265 | } |
266 | else if (UserParamCount > AmlParamCount) |
267 | { |
268 | ACPI_INFO_PREDEFINED ((AE_INFO, Pathname, ACPI_WARN_ALWAYS, |
269 | "Excess arguments - " |
270 | "Caller passed %u, method requires %u" , |
271 | UserParamCount, AmlParamCount)); |
272 | } |
273 | |
274 | return; |
275 | } |
276 | |
277 | /* |
278 | * This is a predefined name. Validate the user-supplied parameter |
279 | * count against the ACPI specification. We don't validate against |
280 | * the method itself because what is important here is that the |
281 | * caller is in conformance with the spec. (The arg count for the |
282 | * method was checked against the ACPI spec earlier.) |
283 | * |
284 | * Some methods are allowed to have a "minimum" number of args (_SCP) |
285 | * because their definition in ACPI has changed over time. |
286 | */ |
287 | RequiredParamCount = |
288 | METHOD_GET_ARG_COUNT (Predefined->Info.ArgumentList); |
289 | |
290 | if (UserParamCount < RequiredParamCount) |
291 | { |
292 | ACPI_WARN_PREDEFINED ((AE_INFO, Pathname, ACPI_WARN_ALWAYS, |
293 | "Insufficient arguments - " |
294 | "Caller passed %u, ACPI requires %u" , |
295 | UserParamCount, RequiredParamCount)); |
296 | } |
297 | else if ((UserParamCount > RequiredParamCount) && |
298 | !(Predefined->Info.ArgumentList & ARG_COUNT_IS_MINIMUM)) |
299 | { |
300 | ACPI_INFO_PREDEFINED ((AE_INFO, Pathname, ACPI_WARN_ALWAYS, |
301 | "Excess arguments - " |
302 | "Caller passed %u, ACPI requires %u" , |
303 | UserParamCount, RequiredParamCount)); |
304 | } |
305 | } |
306 | |