exresop.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:13k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /******************************************************************************
  2.  *
  3.  * Module Name: exresop - AML Interpreter operand/object resolution
  4.  *              $Revision: 41 $
  5.  *
  6.  *****************************************************************************/
  7. /*
  8.  *  Copyright (C) 2000, 2001 R. Byron Moore
  9.  *
  10.  *  This program is free software; you can redistribute it and/or modify
  11.  *  it under the terms of the GNU General Public License as published by
  12.  *  the Free Software Foundation; either version 2 of the License, or
  13.  *  (at your option) any later version.
  14.  *
  15.  *  This program is distributed in the hope that it will be useful,
  16.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  17.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18.  *  GNU General Public License for more details.
  19.  *
  20.  *  You should have received a copy of the GNU General Public License
  21.  *  along with this program; if not, write to the Free Software
  22.  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  23.  */
  24. #include "acpi.h"
  25. #include "amlcode.h"
  26. #include "acparser.h"
  27. #include "acdispat.h"
  28. #include "acinterp.h"
  29. #include "acnamesp.h"
  30. #include "actables.h"
  31. #include "acevents.h"
  32. #define _COMPONENT          ACPI_EXECUTER
  33.  MODULE_NAME         ("exresop")
  34. /*******************************************************************************
  35.  *
  36.  * FUNCTION:    Acpi_ex_check_object_type
  37.  *
  38.  * PARAMETERS:  Type_needed         Object type needed
  39.  *              This_type           Actual object type
  40.  *              Object              Object pointer
  41.  *
  42.  * RETURN:      Status
  43.  *
  44.  * DESCRIPTION: Check required type against actual type
  45.  *
  46.  ******************************************************************************/
  47. acpi_status
  48. acpi_ex_check_object_type (
  49. acpi_object_type        type_needed,
  50. acpi_object_type        this_type,
  51. void                    *object)
  52. {
  53. PROC_NAME ("Ex_check_object_type");
  54. if (type_needed == ACPI_TYPE_ANY) {
  55. /* All types OK, so we don't perform any typechecks */
  56. return (AE_OK);
  57. }
  58. if (type_needed != this_type) {
  59. ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
  60. "Needed [%s], found [%s] %pn",
  61. acpi_ut_get_type_name (type_needed),
  62. acpi_ut_get_type_name (this_type), object));
  63. return (AE_AML_OPERAND_TYPE);
  64. }
  65. return (AE_OK);
  66. }
  67. /*******************************************************************************
  68.  *
  69.  * FUNCTION:    Acpi_ex_resolve_operands
  70.  *
  71.  * PARAMETERS:  Opcode              Opcode being interpreted
  72.  *              Stack_ptr           Top of operand stack
  73.  *
  74.  * RETURN:      Status
  75.  *
  76.  * DESCRIPTION: Convert stack entries to required types
  77.  *
  78.  *      Each nibble in Arg_types represents one required operand
  79.  *      and indicates the required Type:
  80.  *
  81.  *      The corresponding stack entry will be converted to the
  82.  *      required type if possible, else return an exception
  83.  *
  84.  ******************************************************************************/
  85. acpi_status
  86. acpi_ex_resolve_operands (
  87. u16                     opcode,
  88. acpi_operand_object     **stack_ptr,
  89. acpi_walk_state         *walk_state)
  90. {
  91. acpi_operand_object     *obj_desc;
  92. acpi_status             status = AE_OK;
  93. u8                      object_type;
  94. void                    *temp_node;
  95. u32                     arg_types;
  96. const acpi_opcode_info  *op_info;
  97. u32                     this_arg_type;
  98. acpi_object_type        type_needed;
  99. FUNCTION_TRACE_U32 ("Ex_resolve_operands", opcode);
  100. op_info = acpi_ps_get_opcode_info (opcode);
  101. if (op_info->class == AML_CLASS_UNKNOWN) {
  102. return_ACPI_STATUS (AE_AML_BAD_OPCODE);
  103. }
  104. arg_types = op_info->runtime_args;
  105. if (arg_types == ARGI_INVALID_OPCODE) {
  106. ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Internal - %X is not a valid AML opcoden",
  107. opcode));
  108. return_ACPI_STATUS (AE_AML_INTERNAL);
  109. }
  110. ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Opcode %X Operand_types=%X n",
  111. opcode, arg_types));
  112. /*
  113.  * Normal exit is with (Arg_types == 0) at end of argument list.
  114.  * Function will return an exception from within the loop upon
  115.  * finding an entry which is not (or cannot be converted
  116.  * to) the required type; if stack underflows; or upon
  117.  * finding a NULL stack entry (which should not happen).
  118.  */
  119. while (GET_CURRENT_ARG_TYPE (arg_types)) {
  120. if (!stack_ptr || !*stack_ptr) {
  121. ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Internal - null stack entry at %pn",
  122. stack_ptr));
  123. return_ACPI_STATUS (AE_AML_INTERNAL);
  124. }
  125. /* Extract useful items */
  126. obj_desc = *stack_ptr;
  127. /* Decode the descriptor type */
  128. if (VALID_DESCRIPTOR_TYPE (obj_desc, ACPI_DESC_TYPE_NAMED)) {
  129. /* Node */
  130. object_type = ((acpi_namespace_node *) obj_desc)->type;
  131. }
  132. else if (VALID_DESCRIPTOR_TYPE (obj_desc, ACPI_DESC_TYPE_INTERNAL)) {
  133. /* ACPI internal object */
  134. object_type = obj_desc->common.type;
  135. /* Check for bad acpi_object_type */
  136. if (!acpi_ex_validate_object_type (object_type)) {
  137. ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Bad operand object type [%X]n",
  138. object_type));
  139. return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
  140. }
  141. if (object_type == (u8) INTERNAL_TYPE_REFERENCE) {
  142. /*
  143.  * Decode the Reference
  144.  */
  145. op_info = acpi_ps_get_opcode_info (opcode);
  146. if (op_info->class == AML_CLASS_UNKNOWN) {
  147. return_ACPI_STATUS (AE_AML_BAD_OPCODE);
  148. }
  149. switch (obj_desc->reference.opcode) {
  150. case AML_ZERO_OP:
  151. case AML_ONE_OP:
  152. case AML_ONES_OP:
  153. case AML_DEBUG_OP:
  154. case AML_NAME_OP:
  155. case AML_INDEX_OP:
  156. case AML_ARG_OP:
  157. case AML_LOCAL_OP:
  158. case AML_REVISION_OP:
  159. DEBUG_ONLY_MEMBERS (ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
  160. "Reference Opcode: %sn", op_info->name)));
  161. break;
  162. default:
  163. ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
  164. "Reference Opcode: Unknown [%02x]n",
  165. obj_desc->reference.opcode));
  166. return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
  167. break;
  168. }
  169. }
  170. }
  171. else {
  172. /* Invalid descriptor */
  173. ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
  174. "Bad descriptor type %X in Obj %pn",
  175. obj_desc->common.data_type, obj_desc));
  176. return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
  177. }
  178. /*
  179.  * Get one argument type, point to the next
  180.  */
  181. this_arg_type = GET_CURRENT_ARG_TYPE (arg_types);
  182. INCREMENT_ARG_LIST (arg_types);
  183. /*
  184.  * Handle cases where the object does not need to be
  185.  * resolved to a value
  186.  */
  187. switch (this_arg_type) {
  188. case ARGI_REFERENCE:            /* References */
  189. case ARGI_INTEGER_REF:
  190. case ARGI_OBJECT_REF:
  191. case ARGI_DEVICE_REF:
  192. case ARGI_TARGETREF:            /* TBD: must implement implicit conversion rules before store */
  193. case ARGI_FIXED_TARGET:         /* No implicit conversion before store to target */
  194. case ARGI_SIMPLE_TARGET:        /* Name, Local, or Arg - no implicit conversion */
  195. /* Need an operand of type INTERNAL_TYPE_REFERENCE */
  196. if (VALID_DESCRIPTOR_TYPE (obj_desc, ACPI_DESC_TYPE_NAMED))            /* direct name ptr OK as-is */ {
  197. goto next_operand;
  198. }
  199. status = acpi_ex_check_object_type (INTERNAL_TYPE_REFERENCE,
  200.   object_type, obj_desc);
  201. if (ACPI_FAILURE (status)) {
  202. return_ACPI_STATUS (status);
  203. }
  204. if (AML_NAME_OP == obj_desc->reference.opcode) {
  205. /*
  206.  * Convert an indirect name ptr to direct name ptr and put
  207.  * it on the stack
  208.  */
  209. temp_node = obj_desc->reference.object;
  210. acpi_ut_remove_reference (obj_desc);
  211. (*stack_ptr) = temp_node;
  212. }
  213. goto next_operand;
  214. break;
  215. case ARGI_ANYTYPE:
  216. /*
  217.  * We don't want to resolve Index_op reference objects during
  218.  * a store because this would be an implicit De_ref_of operation.
  219.  * Instead, we just want to store the reference object.
  220.  * -- All others must be resolved below.
  221.  */
  222. if ((opcode == AML_STORE_OP) &&
  223. ((*stack_ptr)->common.type == INTERNAL_TYPE_REFERENCE) &&
  224. ((*stack_ptr)->reference.opcode == AML_INDEX_OP)) {
  225. goto next_operand;
  226. }
  227. break;
  228. }
  229. /*
  230.  * Resolve this object to a value
  231.  */
  232. status = acpi_ex_resolve_to_value (stack_ptr, walk_state);
  233. if (ACPI_FAILURE (status)) {
  234. return_ACPI_STATUS (status);
  235. }
  236. /*
  237.  * Check the resulting object (value) type
  238.  */
  239. switch (this_arg_type) {
  240. /*
  241.  * For the simple cases, only one type of resolved object
  242.  * is allowed
  243.  */
  244. case ARGI_MUTEX:
  245. /* Need an operand of type ACPI_TYPE_MUTEX */
  246. type_needed = ACPI_TYPE_MUTEX;
  247. break;
  248. case ARGI_EVENT:
  249. /* Need an operand of type ACPI_TYPE_EVENT */
  250. type_needed = ACPI_TYPE_EVENT;
  251. break;
  252. case ARGI_REGION:
  253. /* Need an operand of type ACPI_TYPE_REGION */
  254. type_needed = ACPI_TYPE_REGION;
  255. break;
  256. case ARGI_IF:   /* If */
  257. /* Need an operand of type INTERNAL_TYPE_IF */
  258. type_needed = INTERNAL_TYPE_IF;
  259. break;
  260. case ARGI_PACKAGE:   /* Package */
  261. /* Need an operand of type ACPI_TYPE_PACKAGE */
  262. type_needed = ACPI_TYPE_PACKAGE;
  263. break;
  264. case ARGI_ANYTYPE:
  265. /* Any operand type will do */
  266. type_needed = ACPI_TYPE_ANY;
  267. break;
  268. /*
  269.  * The more complex cases allow multiple resolved object types
  270.  */
  271. case ARGI_INTEGER:   /* Number */
  272. /*
  273.  * Need an operand of type ACPI_TYPE_INTEGER,
  274.  * But we can implicitly convert from a STRING or BUFFER
  275.  */
  276. status = acpi_ex_convert_to_integer (*stack_ptr, stack_ptr, walk_state);
  277. if (ACPI_FAILURE (status)) {
  278. if (status == AE_TYPE) {
  279. ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
  280. "Needed [Integer/String/Buffer], found [%s] %pn",
  281. acpi_ut_get_type_name ((*stack_ptr)->common.type), *stack_ptr));
  282. return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
  283. }
  284. return_ACPI_STATUS (status);
  285. }
  286. goto next_operand;
  287. break;
  288. case ARGI_BUFFER:
  289. /*
  290.  * Need an operand of type ACPI_TYPE_BUFFER,
  291.  * But we can implicitly convert from a STRING or INTEGER
  292.  */
  293. status = acpi_ex_convert_to_buffer (*stack_ptr, stack_ptr, walk_state);
  294. if (ACPI_FAILURE (status)) {
  295. if (status == AE_TYPE) {
  296. ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
  297. "Needed [Integer/String/Buffer], found [%s] %pn",
  298. acpi_ut_get_type_name ((*stack_ptr)->common.type), *stack_ptr));
  299. return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
  300. }
  301. return_ACPI_STATUS (status);
  302. }
  303. goto next_operand;
  304. break;
  305. case ARGI_STRING:
  306. /*
  307.  * Need an operand of type ACPI_TYPE_STRING,
  308.  * But we can implicitly convert from a BUFFER or INTEGER
  309.  */
  310. status = acpi_ex_convert_to_string (*stack_ptr, stack_ptr, 16, ACPI_UINT32_MAX, walk_state);
  311. if (ACPI_FAILURE (status)) {
  312. if (status == AE_TYPE) {
  313. ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
  314. "Needed [Integer/String/Buffer], found [%s] %pn",
  315. acpi_ut_get_type_name ((*stack_ptr)->common.type), *stack_ptr));
  316. return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
  317. }
  318. return_ACPI_STATUS (status);
  319. }
  320. goto next_operand;
  321. break;
  322. case ARGI_COMPUTEDATA:
  323. /* Need an operand of type INTEGER, STRING or BUFFER */
  324. if ((ACPI_TYPE_INTEGER != (*stack_ptr)->common.type) &&
  325. (ACPI_TYPE_STRING != (*stack_ptr)->common.type) &&
  326. (ACPI_TYPE_BUFFER != (*stack_ptr)->common.type)) {
  327. ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
  328. "Needed [Integer/String/Buffer], found [%s] %pn",
  329. acpi_ut_get_type_name ((*stack_ptr)->common.type), *stack_ptr));
  330. return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
  331. }
  332. goto next_operand;
  333. break;
  334. case ARGI_DATAOBJECT:
  335. /*
  336.  * ARGI_DATAOBJECT is only used by the Size_of operator.
  337.  *
  338.  * The ACPI specification allows Size_of to return the size of
  339.  *  a Buffer, String or Package.  However, the MS ACPI.SYS AML
  340.  *  Interpreter also allows an Node reference to return without
  341.  *  error with a size of 4.
  342.  */
  343. /* Need a buffer, string, package or Node reference */
  344. if (((*stack_ptr)->common.type != ACPI_TYPE_BUFFER) &&
  345. ((*stack_ptr)->common.type != ACPI_TYPE_STRING) &&
  346. ((*stack_ptr)->common.type != ACPI_TYPE_PACKAGE) &&
  347. ((*stack_ptr)->common.type != INTERNAL_TYPE_REFERENCE)) {
  348. ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
  349. "Needed [Buf/Str/Pkg/Ref], found [%s] %pn",
  350. acpi_ut_get_type_name ((*stack_ptr)->common.type), *stack_ptr));
  351. return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
  352. }
  353. /*
  354.  * If this is a reference, only allow a reference to an Node.
  355.  */
  356. if ((*stack_ptr)->common.type == INTERNAL_TYPE_REFERENCE) {
  357. if (!(*stack_ptr)->reference.node) {
  358. ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
  359. "Needed [Node Reference], found [%p]n",
  360. *stack_ptr));
  361. return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
  362. }
  363. }
  364. goto next_operand;
  365. break;
  366. case ARGI_COMPLEXOBJ:
  367. /* Need a buffer or package or (ACPI 2.0) String */
  368. if (((*stack_ptr)->common.type != ACPI_TYPE_BUFFER) &&
  369. ((*stack_ptr)->common.type != ACPI_TYPE_STRING) &&
  370. ((*stack_ptr)->common.type != ACPI_TYPE_PACKAGE)) {
  371. ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
  372. "Needed [Buf/Pkg], found [%s] %pn",
  373. acpi_ut_get_type_name ((*stack_ptr)->common.type), *stack_ptr));
  374. return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
  375. }
  376. goto next_operand;
  377. break;
  378. default:
  379. /* Unknown type */
  380. ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
  381. "Internal - Unknown ARGI type %Xn",
  382. this_arg_type));
  383. return_ACPI_STATUS (AE_BAD_PARAMETER);
  384. }
  385. /*
  386.  * Make sure that the original object was resolved to the
  387.  * required object type (Simple cases only).
  388.  */
  389. status = acpi_ex_check_object_type (type_needed,
  390.   (*stack_ptr)->common.type, *stack_ptr);
  391. if (ACPI_FAILURE (status)) {
  392. return_ACPI_STATUS (status);
  393. }
  394. next_operand:
  395. /*
  396.  * If more operands needed, decrement Stack_ptr to point
  397.  * to next operand on stack
  398.  */
  399. if (GET_CURRENT_ARG_TYPE (arg_types)) {
  400. stack_ptr--;
  401. }
  402. }   /* while (*Types) */
  403. return_ACPI_STATUS (status);
  404. }