exprep.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599
  1. // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
  2. /******************************************************************************
  3. *
  4. * Module Name: exprep - ACPI AML field prep utilities
  5. *
  6. * Copyright (C) 2000 - 2022, Intel Corp.
  7. *
  8. *****************************************************************************/
  9. #include <acpi/acpi.h>
  10. #include "accommon.h"
  11. #include "acinterp.h"
  12. #include "amlcode.h"
  13. #include "acnamesp.h"
  14. #include "acdispat.h"
  15. #define _COMPONENT ACPI_EXECUTER
  16. ACPI_MODULE_NAME("exprep")
  17. /* Local prototypes */
  18. static u32
  19. acpi_ex_decode_field_access(union acpi_operand_object *obj_desc,
  20. u8 field_flags, u32 * return_byte_alignment);
  21. #ifdef ACPI_UNDER_DEVELOPMENT
  22. static u32
  23. acpi_ex_generate_access(u32 field_bit_offset,
  24. u32 field_bit_length, u32 region_length);
  25. /*******************************************************************************
  26. *
  27. * FUNCTION: acpi_ex_generate_access
  28. *
  29. * PARAMETERS: field_bit_offset - Start of field within parent region/buffer
  30. * field_bit_length - Length of field in bits
  31. * region_length - Length of parent in bytes
  32. *
  33. * RETURN: Field granularity (8, 16, 32 or 64) and
  34. * byte_alignment (1, 2, 3, or 4)
  35. *
  36. * DESCRIPTION: Generate an optimal access width for fields defined with the
  37. * any_acc keyword.
  38. *
  39. * NOTE: Need to have the region_length in order to check for boundary
  40. * conditions (end-of-region). However, the region_length is a deferred
  41. * operation. Therefore, to complete this implementation, the generation
  42. * of this access width must be deferred until the region length has
  43. * been evaluated.
  44. *
  45. ******************************************************************************/
  46. static u32
  47. acpi_ex_generate_access(u32 field_bit_offset,
  48. u32 field_bit_length, u32 region_length)
  49. {
  50. u32 field_byte_length;
  51. u32 field_byte_offset;
  52. u32 field_byte_end_offset;
  53. u32 access_byte_width;
  54. u32 field_start_offset;
  55. u32 field_end_offset;
  56. u32 minimum_access_width = 0xFFFFFFFF;
  57. u32 minimum_accesses = 0xFFFFFFFF;
  58. u32 accesses;
  59. ACPI_FUNCTION_TRACE(ex_generate_access);
  60. /* Round Field start offset and length to "minimal" byte boundaries */
  61. field_byte_offset = ACPI_DIV_8(ACPI_ROUND_DOWN(field_bit_offset, 8));
  62. field_byte_end_offset =
  63. ACPI_DIV_8(ACPI_ROUND_UP(field_bit_length + field_bit_offset, 8));
  64. field_byte_length = field_byte_end_offset - field_byte_offset;
  65. ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
  66. "Bit length %u, Bit offset %u\n",
  67. field_bit_length, field_bit_offset));
  68. ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
  69. "Byte Length %u, Byte Offset %u, End Offset %u\n",
  70. field_byte_length, field_byte_offset,
  71. field_byte_end_offset));
  72. /*
  73. * Iterative search for the maximum access width that is both aligned
  74. * and does not go beyond the end of the region
  75. *
  76. * Start at byte_acc and work upwards to qword_acc max. (1,2,4,8 bytes)
  77. */
  78. for (access_byte_width = 1; access_byte_width <= 8;
  79. access_byte_width <<= 1) {
  80. /*
  81. * 1) Round end offset up to next access boundary and make sure that
  82. * this does not go beyond the end of the parent region.
  83. * 2) When the Access width is greater than the field_byte_length, we
  84. * are done. (This does not optimize for the perfectly aligned
  85. * case yet).
  86. */
  87. if (ACPI_ROUND_UP(field_byte_end_offset, access_byte_width) <=
  88. region_length) {
  89. field_start_offset =
  90. ACPI_ROUND_DOWN(field_byte_offset,
  91. access_byte_width) /
  92. access_byte_width;
  93. field_end_offset =
  94. ACPI_ROUND_UP((field_byte_length +
  95. field_byte_offset),
  96. access_byte_width) /
  97. access_byte_width;
  98. accesses = field_end_offset - field_start_offset;
  99. ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
  100. "AccessWidth %u end is within region\n",
  101. access_byte_width));
  102. ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
  103. "Field Start %u, Field End %u -- requires %u accesses\n",
  104. field_start_offset, field_end_offset,
  105. accesses));
  106. /* Single access is optimal */
  107. if (accesses <= 1) {
  108. ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
  109. "Entire field can be accessed "
  110. "with one operation of size %u\n",
  111. access_byte_width));
  112. return_VALUE(access_byte_width);
  113. }
  114. /*
  115. * Fits in the region, but requires more than one read/write.
  116. * try the next wider access on next iteration
  117. */
  118. if (accesses < minimum_accesses) {
  119. minimum_accesses = accesses;
  120. minimum_access_width = access_byte_width;
  121. }
  122. } else {
  123. ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
  124. "AccessWidth %u end is NOT within region\n",
  125. access_byte_width));
  126. if (access_byte_width == 1) {
  127. ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
  128. "Field goes beyond end-of-region!\n"));
  129. /* Field does not fit in the region at all */
  130. return_VALUE(0);
  131. }
  132. /*
  133. * This width goes beyond the end-of-region, back off to
  134. * previous access
  135. */
  136. ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
  137. "Backing off to previous optimal access width of %u\n",
  138. minimum_access_width));
  139. return_VALUE(minimum_access_width);
  140. }
  141. }
  142. /*
  143. * Could not read/write field with one operation,
  144. * just use max access width
  145. */
  146. ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
  147. "Cannot access field in one operation, using width 8\n"));
  148. return_VALUE(8);
  149. }
  150. #endif /* ACPI_UNDER_DEVELOPMENT */
  151. /*******************************************************************************
  152. *
  153. * FUNCTION: acpi_ex_decode_field_access
  154. *
  155. * PARAMETERS: obj_desc - Field object
  156. * field_flags - Encoded fieldflags (contains access bits)
  157. * return_byte_alignment - Where the byte alignment is returned
  158. *
  159. * RETURN: Field granularity (8, 16, 32 or 64) and
  160. * byte_alignment (1, 2, 3, or 4)
  161. *
  162. * DESCRIPTION: Decode the access_type bits of a field definition.
  163. *
  164. ******************************************************************************/
  165. static u32
  166. acpi_ex_decode_field_access(union acpi_operand_object *obj_desc,
  167. u8 field_flags, u32 * return_byte_alignment)
  168. {
  169. u32 access;
  170. u32 byte_alignment;
  171. u32 bit_length;
  172. ACPI_FUNCTION_TRACE(ex_decode_field_access);
  173. access = (field_flags & AML_FIELD_ACCESS_TYPE_MASK);
  174. switch (access) {
  175. case AML_FIELD_ACCESS_ANY:
  176. #ifdef ACPI_UNDER_DEVELOPMENT
  177. byte_alignment =
  178. acpi_ex_generate_access(obj_desc->common_field.
  179. start_field_bit_offset,
  180. obj_desc->common_field.bit_length,
  181. 0xFFFFFFFF
  182. /* Temp until we pass region_length as parameter */
  183. );
  184. bit_length = byte_alignment * 8;
  185. #endif
  186. byte_alignment = 1;
  187. bit_length = 8;
  188. break;
  189. case AML_FIELD_ACCESS_BYTE:
  190. case AML_FIELD_ACCESS_BUFFER: /* ACPI 2.0 (SMBus Buffer) */
  191. byte_alignment = 1;
  192. bit_length = 8;
  193. break;
  194. case AML_FIELD_ACCESS_WORD:
  195. byte_alignment = 2;
  196. bit_length = 16;
  197. break;
  198. case AML_FIELD_ACCESS_DWORD:
  199. byte_alignment = 4;
  200. bit_length = 32;
  201. break;
  202. case AML_FIELD_ACCESS_QWORD: /* ACPI 2.0 */
  203. byte_alignment = 8;
  204. bit_length = 64;
  205. break;
  206. default:
  207. /* Invalid field access type */
  208. ACPI_ERROR((AE_INFO, "Unknown field access type 0x%X", access));
  209. return_UINT32(0);
  210. }
  211. if (obj_desc->common.type == ACPI_TYPE_BUFFER_FIELD) {
  212. /*
  213. * buffer_field access can be on any byte boundary, so the
  214. * byte_alignment is always 1 byte -- regardless of any byte_alignment
  215. * implied by the field access type.
  216. */
  217. byte_alignment = 1;
  218. }
  219. *return_byte_alignment = byte_alignment;
  220. return_UINT32(bit_length);
  221. }
  222. /*******************************************************************************
  223. *
  224. * FUNCTION: acpi_ex_prep_common_field_object
  225. *
  226. * PARAMETERS: obj_desc - The field object
  227. * field_flags - Access, lock_rule, and update_rule.
  228. * The format of a field_flag is described
  229. * in the ACPI specification
  230. * field_attribute - Special attributes (not used)
  231. * field_bit_position - Field start position
  232. * field_bit_length - Field length in number of bits
  233. *
  234. * RETURN: Status
  235. *
  236. * DESCRIPTION: Initialize the areas of the field object that are common
  237. * to the various types of fields. Note: This is very "sensitive"
  238. * code because we are solving the general case for field
  239. * alignment.
  240. *
  241. ******************************************************************************/
  242. acpi_status
  243. acpi_ex_prep_common_field_object(union acpi_operand_object *obj_desc,
  244. u8 field_flags,
  245. u8 field_attribute,
  246. u32 field_bit_position, u32 field_bit_length)
  247. {
  248. u32 access_bit_width;
  249. u32 byte_alignment;
  250. u32 nearest_byte_address;
  251. ACPI_FUNCTION_TRACE(ex_prep_common_field_object);
  252. /*
  253. * Note: the structure being initialized is the
  254. * ACPI_COMMON_FIELD_INFO; No structure fields outside of the common
  255. * area are initialized by this procedure.
  256. */
  257. obj_desc->common_field.field_flags = field_flags;
  258. obj_desc->common_field.attribute = field_attribute;
  259. obj_desc->common_field.bit_length = field_bit_length;
  260. /*
  261. * Decode the access type so we can compute offsets. The access type gives
  262. * two pieces of information - the width of each field access and the
  263. * necessary byte_alignment (address granularity) of the access.
  264. *
  265. * For any_acc, the access_bit_width is the largest width that is both
  266. * necessary and possible in an attempt to access the whole field in one
  267. * I/O operation. However, for any_acc, the byte_alignment is always one
  268. * byte.
  269. *
  270. * For all Buffer Fields, the byte_alignment is always one byte.
  271. *
  272. * For all other access types (Byte, Word, Dword, Qword), the Bitwidth is
  273. * the same (equivalent) as the byte_alignment.
  274. */
  275. access_bit_width =
  276. acpi_ex_decode_field_access(obj_desc, field_flags, &byte_alignment);
  277. if (!access_bit_width) {
  278. return_ACPI_STATUS(AE_AML_OPERAND_VALUE);
  279. }
  280. /* Setup width (access granularity) fields (values are: 1, 2, 4, 8) */
  281. obj_desc->common_field.access_byte_width = (u8)
  282. ACPI_DIV_8(access_bit_width);
  283. /*
  284. * base_byte_offset is the address of the start of the field within the
  285. * region. It is the byte address of the first *datum* (field-width data
  286. * unit) of the field. (i.e., the first datum that contains at least the
  287. * first *bit* of the field.)
  288. *
  289. * Note: byte_alignment is always either equal to the access_bit_width or 8
  290. * (Byte access), and it defines the addressing granularity of the parent
  291. * region or buffer.
  292. */
  293. nearest_byte_address =
  294. ACPI_ROUND_BITS_DOWN_TO_BYTES(field_bit_position);
  295. obj_desc->common_field.base_byte_offset = (u32)
  296. ACPI_ROUND_DOWN(nearest_byte_address, byte_alignment);
  297. /*
  298. * start_field_bit_offset is the offset of the first bit of the field within
  299. * a field datum.
  300. */
  301. obj_desc->common_field.start_field_bit_offset = (u8)
  302. (field_bit_position -
  303. ACPI_MUL_8(obj_desc->common_field.base_byte_offset));
  304. return_ACPI_STATUS(AE_OK);
  305. }
  306. /*******************************************************************************
  307. *
  308. * FUNCTION: acpi_ex_prep_field_value
  309. *
  310. * PARAMETERS: info - Contains all field creation info
  311. *
  312. * RETURN: Status
  313. *
  314. * DESCRIPTION: Construct an object of type union acpi_operand_object with a
  315. * subtype of def_field and connect it to the parent Node.
  316. *
  317. ******************************************************************************/
  318. acpi_status acpi_ex_prep_field_value(struct acpi_create_field_info *info)
  319. {
  320. union acpi_operand_object *obj_desc;
  321. union acpi_operand_object *second_desc = NULL;
  322. acpi_status status;
  323. u32 access_byte_width;
  324. u32 type;
  325. ACPI_FUNCTION_TRACE(ex_prep_field_value);
  326. /* Parameter validation */
  327. if (info->field_type != ACPI_TYPE_LOCAL_INDEX_FIELD) {
  328. if (!info->region_node) {
  329. ACPI_ERROR((AE_INFO, "Null RegionNode"));
  330. return_ACPI_STATUS(AE_AML_NO_OPERAND);
  331. }
  332. type = acpi_ns_get_type(info->region_node);
  333. if (type != ACPI_TYPE_REGION) {
  334. ACPI_ERROR((AE_INFO,
  335. "Needed Region, found type 0x%X (%s)", type,
  336. acpi_ut_get_type_name(type)));
  337. return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
  338. }
  339. }
  340. /* Allocate a new field object */
  341. obj_desc = acpi_ut_create_internal_object(info->field_type);
  342. if (!obj_desc) {
  343. return_ACPI_STATUS(AE_NO_MEMORY);
  344. }
  345. /* Initialize areas of the object that are common to all fields */
  346. obj_desc->common_field.node = info->field_node;
  347. status = acpi_ex_prep_common_field_object(obj_desc,
  348. info->field_flags,
  349. info->attribute,
  350. info->field_bit_position,
  351. info->field_bit_length);
  352. if (ACPI_FAILURE(status)) {
  353. acpi_ut_delete_object_desc(obj_desc);
  354. return_ACPI_STATUS(status);
  355. }
  356. /* Initialize areas of the object that are specific to the field type */
  357. switch (info->field_type) {
  358. case ACPI_TYPE_LOCAL_REGION_FIELD:
  359. obj_desc->field.region_obj =
  360. acpi_ns_get_attached_object(info->region_node);
  361. /* Fields specific to generic_serial_bus fields */
  362. obj_desc->field.access_length = info->access_length;
  363. if (info->connection_node) {
  364. second_desc = info->connection_node->object;
  365. if (!(second_desc->common.flags & AOPOBJ_DATA_VALID)) {
  366. status =
  367. acpi_ds_get_buffer_arguments(second_desc);
  368. if (ACPI_FAILURE(status)) {
  369. acpi_ut_delete_object_desc(obj_desc);
  370. return_ACPI_STATUS(status);
  371. }
  372. }
  373. obj_desc->field.resource_buffer =
  374. second_desc->buffer.pointer;
  375. obj_desc->field.resource_length =
  376. (u16)second_desc->buffer.length;
  377. } else if (info->resource_buffer) {
  378. obj_desc->field.resource_buffer = info->resource_buffer;
  379. obj_desc->field.resource_length = info->resource_length;
  380. }
  381. obj_desc->field.pin_number_index = info->pin_number_index;
  382. /* Allow full data read from EC address space */
  383. if ((obj_desc->field.region_obj->region.space_id ==
  384. ACPI_ADR_SPACE_EC)
  385. && (obj_desc->common_field.bit_length > 8)) {
  386. access_byte_width =
  387. ACPI_ROUND_BITS_UP_TO_BYTES(obj_desc->common_field.
  388. bit_length);
  389. /* Maximum byte width supported is 255 */
  390. if (access_byte_width < 256) {
  391. obj_desc->common_field.access_byte_width =
  392. (u8)access_byte_width;
  393. }
  394. }
  395. ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
  396. "RegionField: BitOff %X, Off %X, Gran %X, Region %p\n",
  397. obj_desc->field.start_field_bit_offset,
  398. obj_desc->field.base_byte_offset,
  399. obj_desc->field.access_byte_width,
  400. obj_desc->field.region_obj));
  401. break;
  402. case ACPI_TYPE_LOCAL_BANK_FIELD:
  403. obj_desc->bank_field.value = info->bank_value;
  404. obj_desc->bank_field.region_obj =
  405. acpi_ns_get_attached_object(info->region_node);
  406. obj_desc->bank_field.bank_obj =
  407. acpi_ns_get_attached_object(info->register_node);
  408. /* An additional reference for the attached objects */
  409. acpi_ut_add_reference(obj_desc->bank_field.region_obj);
  410. acpi_ut_add_reference(obj_desc->bank_field.bank_obj);
  411. ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
  412. "Bank Field: BitOff %X, Off %X, Gran %X, Region %p, BankReg %p\n",
  413. obj_desc->bank_field.start_field_bit_offset,
  414. obj_desc->bank_field.base_byte_offset,
  415. obj_desc->field.access_byte_width,
  416. obj_desc->bank_field.region_obj,
  417. obj_desc->bank_field.bank_obj));
  418. /*
  419. * Remember location in AML stream of the field unit
  420. * opcode and operands -- since the bank_value
  421. * operands must be evaluated.
  422. */
  423. second_desc = obj_desc->common.next_object;
  424. second_desc->extra.aml_start =
  425. ACPI_CAST_PTR(union acpi_parse_object,
  426. info->data_register_node)->named.data;
  427. second_desc->extra.aml_length =
  428. ACPI_CAST_PTR(union acpi_parse_object,
  429. info->data_register_node)->named.length;
  430. break;
  431. case ACPI_TYPE_LOCAL_INDEX_FIELD:
  432. /* Get the Index and Data registers */
  433. obj_desc->index_field.index_obj =
  434. acpi_ns_get_attached_object(info->register_node);
  435. obj_desc->index_field.data_obj =
  436. acpi_ns_get_attached_object(info->data_register_node);
  437. if (!obj_desc->index_field.data_obj
  438. || !obj_desc->index_field.index_obj) {
  439. ACPI_ERROR((AE_INFO,
  440. "Null Index Object during field prep"));
  441. acpi_ut_delete_object_desc(obj_desc);
  442. return_ACPI_STATUS(AE_AML_INTERNAL);
  443. }
  444. /* An additional reference for the attached objects */
  445. acpi_ut_add_reference(obj_desc->index_field.data_obj);
  446. acpi_ut_add_reference(obj_desc->index_field.index_obj);
  447. /*
  448. * April 2006: Changed to match MS behavior
  449. *
  450. * The value written to the Index register is the byte offset of the
  451. * target field in units of the granularity of the index_field
  452. *
  453. * Previously, the value was calculated as an index in terms of the
  454. * width of the Data register, as below:
  455. *
  456. * obj_desc->index_field.Value = (u32)
  457. * (Info->field_bit_position / ACPI_MUL_8 (
  458. * obj_desc->Field.access_byte_width));
  459. *
  460. * February 2006: Tried value as a byte offset:
  461. * obj_desc->index_field.Value = (u32)
  462. * ACPI_DIV_8 (Info->field_bit_position);
  463. */
  464. obj_desc->index_field.value =
  465. (u32) ACPI_ROUND_DOWN(ACPI_DIV_8(info->field_bit_position),
  466. obj_desc->index_field.
  467. access_byte_width);
  468. ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
  469. "IndexField: BitOff %X, Off %X, Value %X, "
  470. "Gran %X, Index %p, Data %p\n",
  471. obj_desc->index_field.start_field_bit_offset,
  472. obj_desc->index_field.base_byte_offset,
  473. obj_desc->index_field.value,
  474. obj_desc->field.access_byte_width,
  475. obj_desc->index_field.index_obj,
  476. obj_desc->index_field.data_obj));
  477. break;
  478. default:
  479. /* No other types should get here */
  480. break;
  481. }
  482. /*
  483. * Store the constructed descriptor (obj_desc) into the parent Node,
  484. * preserving the current type of that named_obj.
  485. */
  486. status =
  487. acpi_ns_attach_object(info->field_node, obj_desc,
  488. acpi_ns_get_type(info->field_node));
  489. ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
  490. "Set NamedObj %p [%4.4s], ObjDesc %p\n",
  491. info->field_node,
  492. acpi_ut_get_node_name(info->field_node), obj_desc));
  493. /* Remove local reference to the object */
  494. acpi_ut_remove_reference(obj_desc);
  495. return_ACPI_STATUS(status);
  496. }