exfldio.c 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017
  1. /******************************************************************************
  2. *
  3. * Module Name: exfldio - Aml Field I/O
  4. *
  5. *****************************************************************************/
  6. /*
  7. * Copyright (C) 2000 - 2012, Intel Corp.
  8. * All rights reserved.
  9. *
  10. * Redistribution and use in source and binary forms, with or without
  11. * modification, are permitted provided that the following conditions
  12. * are met:
  13. * 1. Redistributions of source code must retain the above copyright
  14. * notice, this list of conditions, and the following disclaimer,
  15. * without modification.
  16. * 2. Redistributions in binary form must reproduce at minimum a disclaimer
  17. * substantially similar to the "NO WARRANTY" disclaimer below
  18. * ("Disclaimer") and any redistribution must be conditioned upon
  19. * including a substantially similar Disclaimer requirement for further
  20. * binary redistribution.
  21. * 3. Neither the names of the above-listed copyright holders nor the names
  22. * of any contributors may be used to endorse or promote products derived
  23. * from this software without specific prior written permission.
  24. *
  25. * Alternatively, this software may be distributed under the terms of the
  26. * GNU General Public License ("GPL") version 2 as published by the Free
  27. * Software Foundation.
  28. *
  29. * NO WARRANTY
  30. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  31. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  32. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
  33. * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  34. * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  35. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  36. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  37. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  38. * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
  39. * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  40. * POSSIBILITY OF SUCH DAMAGES.
  41. */
  42. #include <acpi/acpi.h>
  43. #include "accommon.h"
  44. #include "acinterp.h"
  45. #include "amlcode.h"
  46. #include "acevents.h"
  47. #include "acdispat.h"
  48. #define _COMPONENT ACPI_EXECUTER
  49. ACPI_MODULE_NAME("exfldio")
  50. /* Local prototypes */
  51. static acpi_status
  52. acpi_ex_field_datum_io(union acpi_operand_object *obj_desc,
  53. u32 field_datum_byte_offset,
  54. u64 *value, u32 read_write);
  55. static u8
  56. acpi_ex_register_overflow(union acpi_operand_object *obj_desc, u64 value);
  57. static acpi_status
  58. acpi_ex_setup_region(union acpi_operand_object *obj_desc,
  59. u32 field_datum_byte_offset);
  60. /*******************************************************************************
  61. *
  62. * FUNCTION: acpi_ex_setup_region
  63. *
  64. * PARAMETERS: obj_desc - Field to be read or written
  65. * field_datum_byte_offset - Byte offset of this datum within the
  66. * parent field
  67. *
  68. * RETURN: Status
  69. *
  70. * DESCRIPTION: Common processing for acpi_ex_extract_from_field and
  71. * acpi_ex_insert_into_field. Initialize the Region if necessary and
  72. * validate the request.
  73. *
  74. ******************************************************************************/
  75. static acpi_status
  76. acpi_ex_setup_region(union acpi_operand_object *obj_desc,
  77. u32 field_datum_byte_offset)
  78. {
  79. acpi_status status = AE_OK;
  80. union acpi_operand_object *rgn_desc;
  81. u8 space_id;
  82. ACPI_FUNCTION_TRACE_U32(ex_setup_region, field_datum_byte_offset);
  83. rgn_desc = obj_desc->common_field.region_obj;
  84. /* We must have a valid region */
  85. if (rgn_desc->common.type != ACPI_TYPE_REGION) {
  86. ACPI_ERROR((AE_INFO, "Needed Region, found type 0x%X (%s)",
  87. rgn_desc->common.type,
  88. acpi_ut_get_object_type_name(rgn_desc)));
  89. return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
  90. }
  91. space_id = rgn_desc->region.space_id;
  92. /* Validate the Space ID */
  93. if (!acpi_is_valid_space_id(space_id)) {
  94. ACPI_ERROR((AE_INFO,
  95. "Invalid/unknown Address Space ID: 0x%2.2X",
  96. space_id));
  97. return_ACPI_STATUS(AE_AML_INVALID_SPACE_ID);
  98. }
  99. /*
  100. * If the Region Address and Length have not been previously evaluated,
  101. * evaluate them now and save the results.
  102. */
  103. if (!(rgn_desc->common.flags & AOPOBJ_DATA_VALID)) {
  104. status = acpi_ds_get_region_arguments(rgn_desc);
  105. if (ACPI_FAILURE(status)) {
  106. return_ACPI_STATUS(status);
  107. }
  108. }
  109. /* Exit if Address/Length have been disallowed by the host OS */
  110. if (rgn_desc->common.flags & AOPOBJ_INVALID) {
  111. return_ACPI_STATUS(AE_AML_ILLEGAL_ADDRESS);
  112. }
  113. /*
  114. * Exit now for SMBus, GSBus or IPMI address space, it has a non-linear
  115. * address space and the request cannot be directly validated
  116. */
  117. if (space_id == ACPI_ADR_SPACE_SMBUS ||
  118. space_id == ACPI_ADR_SPACE_GSBUS ||
  119. space_id == ACPI_ADR_SPACE_IPMI) {
  120. /* SMBus or IPMI has a non-linear address space */
  121. return_ACPI_STATUS(AE_OK);
  122. }
  123. #ifdef ACPI_UNDER_DEVELOPMENT
  124. /*
  125. * If the Field access is any_acc, we can now compute the optimal
  126. * access (because we know know the length of the parent region)
  127. */
  128. if (!(obj_desc->common.flags & AOPOBJ_DATA_VALID)) {
  129. if (ACPI_FAILURE(status)) {
  130. return_ACPI_STATUS(status);
  131. }
  132. }
  133. #endif
  134. /*
  135. * Validate the request. The entire request from the byte offset for a
  136. * length of one field datum (access width) must fit within the region.
  137. * (Region length is specified in bytes)
  138. */
  139. if (rgn_desc->region.length <
  140. (obj_desc->common_field.base_byte_offset + field_datum_byte_offset +
  141. obj_desc->common_field.access_byte_width)) {
  142. if (acpi_gbl_enable_interpreter_slack) {
  143. /*
  144. * Slack mode only: We will go ahead and allow access to this
  145. * field if it is within the region length rounded up to the next
  146. * access width boundary. acpi_size cast for 64-bit compile.
  147. */
  148. if (ACPI_ROUND_UP(rgn_desc->region.length,
  149. obj_desc->common_field.
  150. access_byte_width) >=
  151. ((acpi_size) obj_desc->common_field.
  152. base_byte_offset +
  153. obj_desc->common_field.access_byte_width +
  154. field_datum_byte_offset)) {
  155. return_ACPI_STATUS(AE_OK);
  156. }
  157. }
  158. if (rgn_desc->region.length <
  159. obj_desc->common_field.access_byte_width) {
  160. /*
  161. * This is the case where the access_type (acc_word, etc.) is wider
  162. * than the region itself. For example, a region of length one
  163. * byte, and a field with Dword access specified.
  164. */
  165. ACPI_ERROR((AE_INFO,
  166. "Field [%4.4s] access width (%u bytes) too large for region [%4.4s] (length %u)",
  167. acpi_ut_get_node_name(obj_desc->
  168. common_field.node),
  169. obj_desc->common_field.access_byte_width,
  170. acpi_ut_get_node_name(rgn_desc->region.
  171. node),
  172. rgn_desc->region.length));
  173. }
  174. /*
  175. * Offset rounded up to next multiple of field width
  176. * exceeds region length, indicate an error
  177. */
  178. ACPI_ERROR((AE_INFO,
  179. "Field [%4.4s] Base+Offset+Width %u+%u+%u is beyond end of region [%4.4s] (length %u)",
  180. acpi_ut_get_node_name(obj_desc->common_field.node),
  181. obj_desc->common_field.base_byte_offset,
  182. field_datum_byte_offset,
  183. obj_desc->common_field.access_byte_width,
  184. acpi_ut_get_node_name(rgn_desc->region.node),
  185. rgn_desc->region.length));
  186. return_ACPI_STATUS(AE_AML_REGION_LIMIT);
  187. }
  188. return_ACPI_STATUS(AE_OK);
  189. }
  190. /*******************************************************************************
  191. *
  192. * FUNCTION: acpi_ex_access_region
  193. *
  194. * PARAMETERS: obj_desc - Field to be read
  195. * field_datum_byte_offset - Byte offset of this datum within the
  196. * parent field
  197. * Value - Where to store value (must at least
  198. * 64 bits)
  199. * Function - Read or Write flag plus other region-
  200. * dependent flags
  201. *
  202. * RETURN: Status
  203. *
  204. * DESCRIPTION: Read or Write a single field datum to an Operation Region.
  205. *
  206. ******************************************************************************/
  207. acpi_status
  208. acpi_ex_access_region(union acpi_operand_object *obj_desc,
  209. u32 field_datum_byte_offset, u64 *value, u32 function)
  210. {
  211. acpi_status status;
  212. union acpi_operand_object *rgn_desc;
  213. u32 region_offset;
  214. ACPI_FUNCTION_TRACE(ex_access_region);
  215. /*
  216. * Ensure that the region operands are fully evaluated and verify
  217. * the validity of the request
  218. */
  219. status = acpi_ex_setup_region(obj_desc, field_datum_byte_offset);
  220. if (ACPI_FAILURE(status)) {
  221. return_ACPI_STATUS(status);
  222. }
  223. /*
  224. * The physical address of this field datum is:
  225. *
  226. * 1) The base of the region, plus
  227. * 2) The base offset of the field, plus
  228. * 3) The current offset into the field
  229. */
  230. rgn_desc = obj_desc->common_field.region_obj;
  231. region_offset =
  232. obj_desc->common_field.base_byte_offset + field_datum_byte_offset;
  233. if ((function & ACPI_IO_MASK) == ACPI_READ) {
  234. ACPI_DEBUG_PRINT((ACPI_DB_BFIELD, "[READ]"));
  235. } else {
  236. ACPI_DEBUG_PRINT((ACPI_DB_BFIELD, "[WRITE]"));
  237. }
  238. ACPI_DEBUG_PRINT_RAW((ACPI_DB_BFIELD,
  239. " Region [%s:%X], Width %X, ByteBase %X, Offset %X at %p\n",
  240. acpi_ut_get_region_name(rgn_desc->region.
  241. space_id),
  242. rgn_desc->region.space_id,
  243. obj_desc->common_field.access_byte_width,
  244. obj_desc->common_field.base_byte_offset,
  245. field_datum_byte_offset, ACPI_CAST_PTR(void,
  246. (rgn_desc->
  247. region.
  248. address +
  249. region_offset))));
  250. /* Invoke the appropriate address_space/op_region handler */
  251. status = acpi_ev_address_space_dispatch(rgn_desc, obj_desc,
  252. function, region_offset,
  253. ACPI_MUL_8(obj_desc->
  254. common_field.
  255. access_byte_width),
  256. value);
  257. if (ACPI_FAILURE(status)) {
  258. if (status == AE_NOT_IMPLEMENTED) {
  259. ACPI_ERROR((AE_INFO,
  260. "Region %s (ID=%u) not implemented",
  261. acpi_ut_get_region_name(rgn_desc->region.
  262. space_id),
  263. rgn_desc->region.space_id));
  264. } else if (status == AE_NOT_EXIST) {
  265. ACPI_ERROR((AE_INFO,
  266. "Region %s (ID=%u) has no handler",
  267. acpi_ut_get_region_name(rgn_desc->region.
  268. space_id),
  269. rgn_desc->region.space_id));
  270. }
  271. }
  272. return_ACPI_STATUS(status);
  273. }
  274. /*******************************************************************************
  275. *
  276. * FUNCTION: acpi_ex_register_overflow
  277. *
  278. * PARAMETERS: obj_desc - Register(Field) to be written
  279. * Value - Value to be stored
  280. *
  281. * RETURN: TRUE if value overflows the field, FALSE otherwise
  282. *
  283. * DESCRIPTION: Check if a value is out of range of the field being written.
  284. * Used to check if the values written to Index and Bank registers
  285. * are out of range. Normally, the value is simply truncated
  286. * to fit the field, but this case is most likely a serious
  287. * coding error in the ASL.
  288. *
  289. ******************************************************************************/
  290. static u8
  291. acpi_ex_register_overflow(union acpi_operand_object *obj_desc, u64 value)
  292. {
  293. ACPI_FUNCTION_NAME(ex_register_overflow);
  294. if (obj_desc->common_field.bit_length >= ACPI_INTEGER_BIT_SIZE) {
  295. /*
  296. * The field is large enough to hold the maximum integer, so we can
  297. * never overflow it.
  298. */
  299. return (FALSE);
  300. }
  301. if (value >= ((u64) 1 << obj_desc->common_field.bit_length)) {
  302. /*
  303. * The Value is larger than the maximum value that can fit into
  304. * the register.
  305. */
  306. ACPI_ERROR((AE_INFO,
  307. "Index value 0x%8.8X%8.8X overflows field width 0x%X",
  308. ACPI_FORMAT_UINT64(value),
  309. obj_desc->common_field.bit_length));
  310. return (TRUE);
  311. }
  312. /* The Value will fit into the field with no truncation */
  313. return (FALSE);
  314. }
  315. /*******************************************************************************
  316. *
  317. * FUNCTION: acpi_ex_field_datum_io
  318. *
  319. * PARAMETERS: obj_desc - Field to be read
  320. * field_datum_byte_offset - Byte offset of this datum within the
  321. * parent field
  322. * Value - Where to store value (must be 64 bits)
  323. * read_write - Read or Write flag
  324. *
  325. * RETURN: Status
  326. *
  327. * DESCRIPTION: Read or Write a single datum of a field. The field_type is
  328. * demultiplexed here to handle the different types of fields
  329. * (buffer_field, region_field, index_field, bank_field)
  330. *
  331. ******************************************************************************/
  332. static acpi_status
  333. acpi_ex_field_datum_io(union acpi_operand_object *obj_desc,
  334. u32 field_datum_byte_offset, u64 *value, u32 read_write)
  335. {
  336. acpi_status status;
  337. u64 local_value;
  338. ACPI_FUNCTION_TRACE_U32(ex_field_datum_io, field_datum_byte_offset);
  339. if (read_write == ACPI_READ) {
  340. if (!value) {
  341. local_value = 0;
  342. /* To support reads without saving return value */
  343. value = &local_value;
  344. }
  345. /* Clear the entire return buffer first, [Very Important!] */
  346. *value = 0;
  347. }
  348. /*
  349. * The four types of fields are:
  350. *
  351. * buffer_field - Read/write from/to a Buffer
  352. * region_field - Read/write from/to a Operation Region.
  353. * bank_field - Write to a Bank Register, then read/write from/to an
  354. * operation_region
  355. * index_field - Write to an Index Register, then read/write from/to a
  356. * Data Register
  357. */
  358. switch (obj_desc->common.type) {
  359. case ACPI_TYPE_BUFFER_FIELD:
  360. /*
  361. * If the buffer_field arguments have not been previously evaluated,
  362. * evaluate them now and save the results.
  363. */
  364. if (!(obj_desc->common.flags & AOPOBJ_DATA_VALID)) {
  365. status = acpi_ds_get_buffer_field_arguments(obj_desc);
  366. if (ACPI_FAILURE(status)) {
  367. return_ACPI_STATUS(status);
  368. }
  369. }
  370. if (read_write == ACPI_READ) {
  371. /*
  372. * Copy the data from the source buffer.
  373. * Length is the field width in bytes.
  374. */
  375. ACPI_MEMCPY(value,
  376. (obj_desc->buffer_field.buffer_obj)->buffer.
  377. pointer +
  378. obj_desc->buffer_field.base_byte_offset +
  379. field_datum_byte_offset,
  380. obj_desc->common_field.access_byte_width);
  381. } else {
  382. /*
  383. * Copy the data to the target buffer.
  384. * Length is the field width in bytes.
  385. */
  386. ACPI_MEMCPY((obj_desc->buffer_field.buffer_obj)->buffer.
  387. pointer +
  388. obj_desc->buffer_field.base_byte_offset +
  389. field_datum_byte_offset, value,
  390. obj_desc->common_field.access_byte_width);
  391. }
  392. status = AE_OK;
  393. break;
  394. case ACPI_TYPE_LOCAL_BANK_FIELD:
  395. /*
  396. * Ensure that the bank_value is not beyond the capacity of
  397. * the register
  398. */
  399. if (acpi_ex_register_overflow(obj_desc->bank_field.bank_obj,
  400. (u64) obj_desc->bank_field.
  401. value)) {
  402. return_ACPI_STATUS(AE_AML_REGISTER_LIMIT);
  403. }
  404. /*
  405. * For bank_fields, we must write the bank_value to the bank_register
  406. * (itself a region_field) before we can access the data.
  407. */
  408. status =
  409. acpi_ex_insert_into_field(obj_desc->bank_field.bank_obj,
  410. &obj_desc->bank_field.value,
  411. sizeof(obj_desc->bank_field.
  412. value));
  413. if (ACPI_FAILURE(status)) {
  414. return_ACPI_STATUS(status);
  415. }
  416. /*
  417. * Now that the Bank has been selected, fall through to the
  418. * region_field case and write the datum to the Operation Region
  419. */
  420. /*lint -fallthrough */
  421. case ACPI_TYPE_LOCAL_REGION_FIELD:
  422. /*
  423. * For simple region_fields, we just directly access the owning
  424. * Operation Region.
  425. */
  426. status =
  427. acpi_ex_access_region(obj_desc, field_datum_byte_offset,
  428. value, read_write);
  429. break;
  430. case ACPI_TYPE_LOCAL_INDEX_FIELD:
  431. /*
  432. * Ensure that the index_value is not beyond the capacity of
  433. * the register
  434. */
  435. if (acpi_ex_register_overflow(obj_desc->index_field.index_obj,
  436. (u64) obj_desc->index_field.
  437. value)) {
  438. return_ACPI_STATUS(AE_AML_REGISTER_LIMIT);
  439. }
  440. /* Write the index value to the index_register (itself a region_field) */
  441. field_datum_byte_offset += obj_desc->index_field.value;
  442. ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
  443. "Write to Index Register: Value %8.8X\n",
  444. field_datum_byte_offset));
  445. status =
  446. acpi_ex_insert_into_field(obj_desc->index_field.index_obj,
  447. &field_datum_byte_offset,
  448. sizeof(field_datum_byte_offset));
  449. if (ACPI_FAILURE(status)) {
  450. return_ACPI_STATUS(status);
  451. }
  452. if (read_write == ACPI_READ) {
  453. /* Read the datum from the data_register */
  454. ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
  455. "Read from Data Register\n"));
  456. status =
  457. acpi_ex_extract_from_field(obj_desc->index_field.
  458. data_obj, value,
  459. sizeof(u64));
  460. } else {
  461. /* Write the datum to the data_register */
  462. ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
  463. "Write to Data Register: Value %8.8X%8.8X\n",
  464. ACPI_FORMAT_UINT64(*value)));
  465. status =
  466. acpi_ex_insert_into_field(obj_desc->index_field.
  467. data_obj, value,
  468. sizeof(u64));
  469. }
  470. break;
  471. default:
  472. ACPI_ERROR((AE_INFO, "Wrong object type in field I/O %u",
  473. obj_desc->common.type));
  474. status = AE_AML_INTERNAL;
  475. break;
  476. }
  477. if (ACPI_SUCCESS(status)) {
  478. if (read_write == ACPI_READ) {
  479. ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
  480. "Value Read %8.8X%8.8X, Width %u\n",
  481. ACPI_FORMAT_UINT64(*value),
  482. obj_desc->common_field.
  483. access_byte_width));
  484. } else {
  485. ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
  486. "Value Written %8.8X%8.8X, Width %u\n",
  487. ACPI_FORMAT_UINT64(*value),
  488. obj_desc->common_field.
  489. access_byte_width));
  490. }
  491. }
  492. return_ACPI_STATUS(status);
  493. }
  494. /*******************************************************************************
  495. *
  496. * FUNCTION: acpi_ex_write_with_update_rule
  497. *
  498. * PARAMETERS: obj_desc - Field to be written
  499. * Mask - bitmask within field datum
  500. * field_value - Value to write
  501. * field_datum_byte_offset - Offset of datum within field
  502. *
  503. * RETURN: Status
  504. *
  505. * DESCRIPTION: Apply the field update rule to a field write
  506. *
  507. ******************************************************************************/
  508. acpi_status
  509. acpi_ex_write_with_update_rule(union acpi_operand_object *obj_desc,
  510. u64 mask,
  511. u64 field_value, u32 field_datum_byte_offset)
  512. {
  513. acpi_status status = AE_OK;
  514. u64 merged_value;
  515. u64 current_value;
  516. ACPI_FUNCTION_TRACE_U32(ex_write_with_update_rule, mask);
  517. /* Start with the new bits */
  518. merged_value = field_value;
  519. /* If the mask is all ones, we don't need to worry about the update rule */
  520. if (mask != ACPI_UINT64_MAX) {
  521. /* Decode the update rule */
  522. switch (obj_desc->common_field.
  523. field_flags & AML_FIELD_UPDATE_RULE_MASK) {
  524. case AML_FIELD_UPDATE_PRESERVE:
  525. /*
  526. * Check if update rule needs to be applied (not if mask is all
  527. * ones) The left shift drops the bits we want to ignore.
  528. */
  529. if ((~mask << (ACPI_MUL_8(sizeof(mask)) -
  530. ACPI_MUL_8(obj_desc->common_field.
  531. access_byte_width))) != 0) {
  532. /*
  533. * Read the current contents of the byte/word/dword containing
  534. * the field, and merge with the new field value.
  535. */
  536. status =
  537. acpi_ex_field_datum_io(obj_desc,
  538. field_datum_byte_offset,
  539. &current_value,
  540. ACPI_READ);
  541. if (ACPI_FAILURE(status)) {
  542. return_ACPI_STATUS(status);
  543. }
  544. merged_value |= (current_value & ~mask);
  545. }
  546. break;
  547. case AML_FIELD_UPDATE_WRITE_AS_ONES:
  548. /* Set positions outside the field to all ones */
  549. merged_value |= ~mask;
  550. break;
  551. case AML_FIELD_UPDATE_WRITE_AS_ZEROS:
  552. /* Set positions outside the field to all zeros */
  553. merged_value &= mask;
  554. break;
  555. default:
  556. ACPI_ERROR((AE_INFO,
  557. "Unknown UpdateRule value: 0x%X",
  558. (obj_desc->common_field.
  559. field_flags &
  560. AML_FIELD_UPDATE_RULE_MASK)));
  561. return_ACPI_STATUS(AE_AML_OPERAND_VALUE);
  562. }
  563. }
  564. ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
  565. "Mask %8.8X%8.8X, DatumOffset %X, Width %X, Value %8.8X%8.8X, MergedValue %8.8X%8.8X\n",
  566. ACPI_FORMAT_UINT64(mask),
  567. field_datum_byte_offset,
  568. obj_desc->common_field.access_byte_width,
  569. ACPI_FORMAT_UINT64(field_value),
  570. ACPI_FORMAT_UINT64(merged_value)));
  571. /* Write the merged value */
  572. status = acpi_ex_field_datum_io(obj_desc, field_datum_byte_offset,
  573. &merged_value, ACPI_WRITE);
  574. return_ACPI_STATUS(status);
  575. }
  576. /*******************************************************************************
  577. *
  578. * FUNCTION: acpi_ex_extract_from_field
  579. *
  580. * PARAMETERS: obj_desc - Field to be read
  581. * Buffer - Where to store the field data
  582. * buffer_length - Length of Buffer
  583. *
  584. * RETURN: Status
  585. *
  586. * DESCRIPTION: Retrieve the current value of the given field
  587. *
  588. ******************************************************************************/
  589. acpi_status
  590. acpi_ex_extract_from_field(union acpi_operand_object *obj_desc,
  591. void *buffer, u32 buffer_length)
  592. {
  593. acpi_status status;
  594. u64 raw_datum;
  595. u64 merged_datum;
  596. u32 field_offset = 0;
  597. u32 buffer_offset = 0;
  598. u32 buffer_tail_bits;
  599. u32 datum_count;
  600. u32 field_datum_count;
  601. u32 access_bit_width;
  602. u32 i;
  603. ACPI_FUNCTION_TRACE(ex_extract_from_field);
  604. /* Validate target buffer and clear it */
  605. if (buffer_length <
  606. ACPI_ROUND_BITS_UP_TO_BYTES(obj_desc->common_field.bit_length)) {
  607. ACPI_ERROR((AE_INFO,
  608. "Field size %u (bits) is too large for buffer (%u)",
  609. obj_desc->common_field.bit_length, buffer_length));
  610. return_ACPI_STATUS(AE_BUFFER_OVERFLOW);
  611. }
  612. ACPI_MEMSET(buffer, 0, buffer_length);
  613. access_bit_width = ACPI_MUL_8(obj_desc->common_field.access_byte_width);
  614. /* Handle the simple case here */
  615. if ((obj_desc->common_field.start_field_bit_offset == 0) &&
  616. (obj_desc->common_field.bit_length == access_bit_width)) {
  617. if (buffer_length >= sizeof(u64)) {
  618. status =
  619. acpi_ex_field_datum_io(obj_desc, 0, buffer,
  620. ACPI_READ);
  621. } else {
  622. /* Use raw_datum (u64) to handle buffers < 64 bits */
  623. status =
  624. acpi_ex_field_datum_io(obj_desc, 0, &raw_datum,
  625. ACPI_READ);
  626. ACPI_MEMCPY(buffer, &raw_datum, buffer_length);
  627. }
  628. return_ACPI_STATUS(status);
  629. }
  630. /* TBD: Move to common setup code */
  631. /* Field algorithm is limited to sizeof(u64), truncate if needed */
  632. if (obj_desc->common_field.access_byte_width > sizeof(u64)) {
  633. obj_desc->common_field.access_byte_width = sizeof(u64);
  634. access_bit_width = sizeof(u64) * 8;
  635. }
  636. /* Compute the number of datums (access width data items) */
  637. datum_count =
  638. ACPI_ROUND_UP_TO(obj_desc->common_field.bit_length,
  639. access_bit_width);
  640. field_datum_count = ACPI_ROUND_UP_TO(obj_desc->common_field.bit_length +
  641. obj_desc->common_field.
  642. start_field_bit_offset,
  643. access_bit_width);
  644. /* Priming read from the field */
  645. status =
  646. acpi_ex_field_datum_io(obj_desc, field_offset, &raw_datum,
  647. ACPI_READ);
  648. if (ACPI_FAILURE(status)) {
  649. return_ACPI_STATUS(status);
  650. }
  651. merged_datum =
  652. raw_datum >> obj_desc->common_field.start_field_bit_offset;
  653. /* Read the rest of the field */
  654. for (i = 1; i < field_datum_count; i++) {
  655. /* Get next input datum from the field */
  656. field_offset += obj_desc->common_field.access_byte_width;
  657. status = acpi_ex_field_datum_io(obj_desc, field_offset,
  658. &raw_datum, ACPI_READ);
  659. if (ACPI_FAILURE(status)) {
  660. return_ACPI_STATUS(status);
  661. }
  662. /*
  663. * Merge with previous datum if necessary.
  664. *
  665. * Note: Before the shift, check if the shift value will be larger than
  666. * the integer size. If so, there is no need to perform the operation.
  667. * This avoids the differences in behavior between different compilers
  668. * concerning shift values larger than the target data width.
  669. */
  670. if (access_bit_width -
  671. obj_desc->common_field.start_field_bit_offset <
  672. ACPI_INTEGER_BIT_SIZE) {
  673. merged_datum |=
  674. raw_datum << (access_bit_width -
  675. obj_desc->common_field.
  676. start_field_bit_offset);
  677. }
  678. if (i == datum_count) {
  679. break;
  680. }
  681. /* Write merged datum to target buffer */
  682. ACPI_MEMCPY(((char *)buffer) + buffer_offset, &merged_datum,
  683. ACPI_MIN(obj_desc->common_field.access_byte_width,
  684. buffer_length - buffer_offset));
  685. buffer_offset += obj_desc->common_field.access_byte_width;
  686. merged_datum =
  687. raw_datum >> obj_desc->common_field.start_field_bit_offset;
  688. }
  689. /* Mask off any extra bits in the last datum */
  690. buffer_tail_bits = obj_desc->common_field.bit_length % access_bit_width;
  691. if (buffer_tail_bits) {
  692. merged_datum &= ACPI_MASK_BITS_ABOVE(buffer_tail_bits);
  693. }
  694. /* Write the last datum to the buffer */
  695. ACPI_MEMCPY(((char *)buffer) + buffer_offset, &merged_datum,
  696. ACPI_MIN(obj_desc->common_field.access_byte_width,
  697. buffer_length - buffer_offset));
  698. return_ACPI_STATUS(AE_OK);
  699. }
  700. /*******************************************************************************
  701. *
  702. * FUNCTION: acpi_ex_insert_into_field
  703. *
  704. * PARAMETERS: obj_desc - Field to be written
  705. * Buffer - Data to be written
  706. * buffer_length - Length of Buffer
  707. *
  708. * RETURN: Status
  709. *
  710. * DESCRIPTION: Store the Buffer contents into the given field
  711. *
  712. ******************************************************************************/
  713. acpi_status
  714. acpi_ex_insert_into_field(union acpi_operand_object *obj_desc,
  715. void *buffer, u32 buffer_length)
  716. {
  717. void *new_buffer;
  718. acpi_status status;
  719. u64 mask;
  720. u64 width_mask;
  721. u64 merged_datum;
  722. u64 raw_datum = 0;
  723. u32 field_offset = 0;
  724. u32 buffer_offset = 0;
  725. u32 buffer_tail_bits;
  726. u32 datum_count;
  727. u32 field_datum_count;
  728. u32 access_bit_width;
  729. u32 required_length;
  730. u32 i;
  731. ACPI_FUNCTION_TRACE(ex_insert_into_field);
  732. /* Validate input buffer */
  733. new_buffer = NULL;
  734. required_length =
  735. ACPI_ROUND_BITS_UP_TO_BYTES(obj_desc->common_field.bit_length);
  736. /*
  737. * We must have a buffer that is at least as long as the field
  738. * we are writing to. This is because individual fields are
  739. * indivisible and partial writes are not supported -- as per
  740. * the ACPI specification.
  741. */
  742. if (buffer_length < required_length) {
  743. /* We need to create a new buffer */
  744. new_buffer = ACPI_ALLOCATE_ZEROED(required_length);
  745. if (!new_buffer) {
  746. return_ACPI_STATUS(AE_NO_MEMORY);
  747. }
  748. /*
  749. * Copy the original data to the new buffer, starting
  750. * at Byte zero. All unused (upper) bytes of the
  751. * buffer will be 0.
  752. */
  753. ACPI_MEMCPY((char *)new_buffer, (char *)buffer, buffer_length);
  754. buffer = new_buffer;
  755. buffer_length = required_length;
  756. }
  757. /* TBD: Move to common setup code */
  758. /* Algo is limited to sizeof(u64), so cut the access_byte_width */
  759. if (obj_desc->common_field.access_byte_width > sizeof(u64)) {
  760. obj_desc->common_field.access_byte_width = sizeof(u64);
  761. }
  762. access_bit_width = ACPI_MUL_8(obj_desc->common_field.access_byte_width);
  763. /*
  764. * Create the bitmasks used for bit insertion.
  765. * Note: This if/else is used to bypass compiler differences with the
  766. * shift operator
  767. */
  768. if (access_bit_width == ACPI_INTEGER_BIT_SIZE) {
  769. width_mask = ACPI_UINT64_MAX;
  770. } else {
  771. width_mask = ACPI_MASK_BITS_ABOVE(access_bit_width);
  772. }
  773. mask = width_mask &
  774. ACPI_MASK_BITS_BELOW(obj_desc->common_field.start_field_bit_offset);
  775. /* Compute the number of datums (access width data items) */
  776. datum_count = ACPI_ROUND_UP_TO(obj_desc->common_field.bit_length,
  777. access_bit_width);
  778. field_datum_count = ACPI_ROUND_UP_TO(obj_desc->common_field.bit_length +
  779. obj_desc->common_field.
  780. start_field_bit_offset,
  781. access_bit_width);
  782. /* Get initial Datum from the input buffer */
  783. ACPI_MEMCPY(&raw_datum, buffer,
  784. ACPI_MIN(obj_desc->common_field.access_byte_width,
  785. buffer_length - buffer_offset));
  786. merged_datum =
  787. raw_datum << obj_desc->common_field.start_field_bit_offset;
  788. /* Write the entire field */
  789. for (i = 1; i < field_datum_count; i++) {
  790. /* Write merged datum to the target field */
  791. merged_datum &= mask;
  792. status = acpi_ex_write_with_update_rule(obj_desc, mask,
  793. merged_datum,
  794. field_offset);
  795. if (ACPI_FAILURE(status)) {
  796. goto exit;
  797. }
  798. field_offset += obj_desc->common_field.access_byte_width;
  799. /*
  800. * Start new output datum by merging with previous input datum
  801. * if necessary.
  802. *
  803. * Note: Before the shift, check if the shift value will be larger than
  804. * the integer size. If so, there is no need to perform the operation.
  805. * This avoids the differences in behavior between different compilers
  806. * concerning shift values larger than the target data width.
  807. */
  808. if ((access_bit_width -
  809. obj_desc->common_field.start_field_bit_offset) <
  810. ACPI_INTEGER_BIT_SIZE) {
  811. merged_datum =
  812. raw_datum >> (access_bit_width -
  813. obj_desc->common_field.
  814. start_field_bit_offset);
  815. } else {
  816. merged_datum = 0;
  817. }
  818. mask = width_mask;
  819. if (i == datum_count) {
  820. break;
  821. }
  822. /* Get the next input datum from the buffer */
  823. buffer_offset += obj_desc->common_field.access_byte_width;
  824. ACPI_MEMCPY(&raw_datum, ((char *)buffer) + buffer_offset,
  825. ACPI_MIN(obj_desc->common_field.access_byte_width,
  826. buffer_length - buffer_offset));
  827. merged_datum |=
  828. raw_datum << obj_desc->common_field.start_field_bit_offset;
  829. }
  830. /* Mask off any extra bits in the last datum */
  831. buffer_tail_bits = (obj_desc->common_field.bit_length +
  832. obj_desc->common_field.start_field_bit_offset) %
  833. access_bit_width;
  834. if (buffer_tail_bits) {
  835. mask &= ACPI_MASK_BITS_ABOVE(buffer_tail_bits);
  836. }
  837. /* Write the last datum to the field */
  838. merged_datum &= mask;
  839. status = acpi_ex_write_with_update_rule(obj_desc,
  840. mask, merged_datum,
  841. field_offset);
  842. exit:
  843. /* Free temporary buffer if we used one */
  844. if (new_buffer) {
  845. ACPI_FREE(new_buffer);
  846. }
  847. return_ACPI_STATUS(status);
  848. }