Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
exfldio.c
Go to the documentation of this file.
1 /******************************************************************************
2  *
3  * Module Name: exfldio - Aml Field I/O
4  *
5  *****************************************************************************/
6 
7 /*
8  * Copyright (C) 2000 - 2012, 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/acpi.h>
45 #include "accommon.h"
46 #include "acinterp.h"
47 #include "amlcode.h"
48 #include "acevents.h"
49 #include "acdispat.h"
50 
51 #define _COMPONENT ACPI_EXECUTER
52 ACPI_MODULE_NAME("exfldio")
53 
54 /* Local prototypes */
55 static acpi_status
56 acpi_ex_field_datum_io(union acpi_operand_object *obj_desc,
57  u32 field_datum_byte_offset,
58  u64 *value, u32 read_write);
59 
60 static u8
61 acpi_ex_register_overflow(union acpi_operand_object *obj_desc, u64 value);
62 
63 static acpi_status
64 acpi_ex_setup_region(union acpi_operand_object *obj_desc,
65  u32 field_datum_byte_offset);
66 
67 /*******************************************************************************
68  *
69  * FUNCTION: acpi_ex_setup_region
70  *
71  * PARAMETERS: obj_desc - Field to be read or written
72  * field_datum_byte_offset - Byte offset of this datum within the
73  * parent field
74  *
75  * RETURN: Status
76  *
77  * DESCRIPTION: Common processing for acpi_ex_extract_from_field and
78  * acpi_ex_insert_into_field. Initialize the Region if necessary and
79  * validate the request.
80  *
81  ******************************************************************************/
82 
83 static acpi_status
84 acpi_ex_setup_region(union acpi_operand_object *obj_desc,
85  u32 field_datum_byte_offset)
86 {
88  union acpi_operand_object *rgn_desc;
89  u8 space_id;
90 
91  ACPI_FUNCTION_TRACE_U32(ex_setup_region, field_datum_byte_offset);
92 
93  rgn_desc = obj_desc->common_field.region_obj;
94 
95  /* We must have a valid region */
96 
97  if (rgn_desc->common.type != ACPI_TYPE_REGION) {
98  ACPI_ERROR((AE_INFO, "Needed Region, found type 0x%X (%s)",
99  rgn_desc->common.type,
100  acpi_ut_get_object_type_name(rgn_desc)));
101 
103  }
104 
105  space_id = rgn_desc->region.space_id;
106 
107  /* Validate the Space ID */
108 
109  if (!acpi_is_valid_space_id(space_id)) {
111  "Invalid/unknown Address Space ID: 0x%2.2X",
112  space_id));
114  }
115 
116  /*
117  * If the Region Address and Length have not been previously evaluated,
118  * evaluate them now and save the results.
119  */
120  if (!(rgn_desc->common.flags & AOPOBJ_DATA_VALID)) {
121  status = acpi_ds_get_region_arguments(rgn_desc);
122  if (ACPI_FAILURE(status)) {
123  return_ACPI_STATUS(status);
124  }
125  }
126 
127  /* Exit if Address/Length have been disallowed by the host OS */
128 
129  if (rgn_desc->common.flags & AOPOBJ_INVALID) {
131  }
132 
133  /*
134  * Exit now for SMBus, GSBus or IPMI address space, it has a non-linear
135  * address space and the request cannot be directly validated
136  */
137  if (space_id == ACPI_ADR_SPACE_SMBUS ||
138  space_id == ACPI_ADR_SPACE_GSBUS ||
139  space_id == ACPI_ADR_SPACE_IPMI) {
140 
141  /* SMBus or IPMI has a non-linear address space */
142 
144  }
145 #ifdef ACPI_UNDER_DEVELOPMENT
146  /*
147  * If the Field access is any_acc, we can now compute the optimal
148  * access (because we know know the length of the parent region)
149  */
150  if (!(obj_desc->common.flags & AOPOBJ_DATA_VALID)) {
151  if (ACPI_FAILURE(status)) {
152  return_ACPI_STATUS(status);
153  }
154  }
155 #endif
156 
157  /*
158  * Validate the request. The entire request from the byte offset for a
159  * length of one field datum (access width) must fit within the region.
160  * (Region length is specified in bytes)
161  */
162  if (rgn_desc->region.length <
163  (obj_desc->common_field.base_byte_offset + field_datum_byte_offset +
164  obj_desc->common_field.access_byte_width)) {
166  /*
167  * Slack mode only: We will go ahead and allow access to this
168  * field if it is within the region length rounded up to the next
169  * access width boundary. acpi_size cast for 64-bit compile.
170  */
171  if (ACPI_ROUND_UP(rgn_desc->region.length,
172  obj_desc->common_field.
173  access_byte_width) >=
174  ((acpi_size) obj_desc->common_field.
175  base_byte_offset +
176  obj_desc->common_field.access_byte_width +
177  field_datum_byte_offset)) {
179  }
180  }
181 
182  if (rgn_desc->region.length <
183  obj_desc->common_field.access_byte_width) {
184  /*
185  * This is the case where the access_type (acc_word, etc.) is wider
186  * than the region itself. For example, a region of length one
187  * byte, and a field with Dword access specified.
188  */
190  "Field [%4.4s] access width (%u bytes) too large for region [%4.4s] (length %u)",
191  acpi_ut_get_node_name(obj_desc->
192  common_field.node),
193  obj_desc->common_field.access_byte_width,
194  acpi_ut_get_node_name(rgn_desc->region.
195  node),
196  rgn_desc->region.length));
197  }
198 
199  /*
200  * Offset rounded up to next multiple of field width
201  * exceeds region length, indicate an error
202  */
204  "Field [%4.4s] Base+Offset+Width %u+%u+%u is beyond end of region [%4.4s] (length %u)",
205  acpi_ut_get_node_name(obj_desc->common_field.node),
206  obj_desc->common_field.base_byte_offset,
207  field_datum_byte_offset,
208  obj_desc->common_field.access_byte_width,
209  acpi_ut_get_node_name(rgn_desc->region.node),
210  rgn_desc->region.length));
211 
213  }
214 
216 }
217 
218 /*******************************************************************************
219  *
220  * FUNCTION: acpi_ex_access_region
221  *
222  * PARAMETERS: obj_desc - Field to be read
223  * field_datum_byte_offset - Byte offset of this datum within the
224  * parent field
225  * value - Where to store value (must at least
226  * 64 bits)
227  * function - Read or Write flag plus other region-
228  * dependent flags
229  *
230  * RETURN: Status
231  *
232  * DESCRIPTION: Read or Write a single field datum to an Operation Region.
233  *
234  ******************************************************************************/
235 
238  u32 field_datum_byte_offset, u64 *value, u32 function)
239 {
241  union acpi_operand_object *rgn_desc;
242  u32 region_offset;
243 
244  ACPI_FUNCTION_TRACE(ex_access_region);
245 
246  /*
247  * Ensure that the region operands are fully evaluated and verify
248  * the validity of the request
249  */
250  status = acpi_ex_setup_region(obj_desc, field_datum_byte_offset);
251  if (ACPI_FAILURE(status)) {
252  return_ACPI_STATUS(status);
253  }
254 
255  /*
256  * The physical address of this field datum is:
257  *
258  * 1) The base of the region, plus
259  * 2) The base offset of the field, plus
260  * 3) The current offset into the field
261  */
262  rgn_desc = obj_desc->common_field.region_obj;
263  region_offset =
264  obj_desc->common_field.base_byte_offset + field_datum_byte_offset;
265 
266  if ((function & ACPI_IO_MASK) == ACPI_READ) {
267  ACPI_DEBUG_PRINT((ACPI_DB_BFIELD, "[READ]"));
268  } else {
269  ACPI_DEBUG_PRINT((ACPI_DB_BFIELD, "[WRITE]"));
270  }
271 
273  " Region [%s:%X], Width %X, ByteBase %X, Offset %X at %p\n",
275  space_id),
276  rgn_desc->region.space_id,
277  obj_desc->common_field.access_byte_width,
278  obj_desc->common_field.base_byte_offset,
279  field_datum_byte_offset, ACPI_CAST_PTR(void,
280  (rgn_desc->
281  region.
282  address +
283  region_offset))));
284 
285  /* Invoke the appropriate address_space/op_region handler */
286 
287  status = acpi_ev_address_space_dispatch(rgn_desc, obj_desc,
288  function, region_offset,
289  ACPI_MUL_8(obj_desc->
290  common_field.
291  access_byte_width),
292  value);
293 
294  if (ACPI_FAILURE(status)) {
295  if (status == AE_NOT_IMPLEMENTED) {
297  "Region %s (ID=%u) not implemented",
299  space_id),
300  rgn_desc->region.space_id));
301  } else if (status == AE_NOT_EXIST) {
303  "Region %s (ID=%u) has no handler",
305  space_id),
306  rgn_desc->region.space_id));
307  }
308  }
309 
310  return_ACPI_STATUS(status);
311 }
312 
313 /*******************************************************************************
314  *
315  * FUNCTION: acpi_ex_register_overflow
316  *
317  * PARAMETERS: obj_desc - Register(Field) to be written
318  * value - Value to be stored
319  *
320  * RETURN: TRUE if value overflows the field, FALSE otherwise
321  *
322  * DESCRIPTION: Check if a value is out of range of the field being written.
323  * Used to check if the values written to Index and Bank registers
324  * are out of range. Normally, the value is simply truncated
325  * to fit the field, but this case is most likely a serious
326  * coding error in the ASL.
327  *
328  ******************************************************************************/
329 
330 static u8
331 acpi_ex_register_overflow(union acpi_operand_object *obj_desc, u64 value)
332 {
333  ACPI_FUNCTION_NAME(ex_register_overflow);
334 
335  if (obj_desc->common_field.bit_length >= ACPI_INTEGER_BIT_SIZE) {
336  /*
337  * The field is large enough to hold the maximum integer, so we can
338  * never overflow it.
339  */
340  return (FALSE);
341  }
342 
343  if (value >= ((u64) 1 << obj_desc->common_field.bit_length)) {
344  /*
345  * The Value is larger than the maximum value that can fit into
346  * the register.
347  */
349  "Index value 0x%8.8X%8.8X overflows field width 0x%X",
350  ACPI_FORMAT_UINT64(value),
351  obj_desc->common_field.bit_length));
352 
353  return (TRUE);
354  }
355 
356  /* The Value will fit into the field with no truncation */
357 
358  return (FALSE);
359 }
360 
361 /*******************************************************************************
362  *
363  * FUNCTION: acpi_ex_field_datum_io
364  *
365  * PARAMETERS: obj_desc - Field to be read
366  * field_datum_byte_offset - Byte offset of this datum within the
367  * parent field
368  * value - Where to store value (must be 64 bits)
369  * read_write - Read or Write flag
370  *
371  * RETURN: Status
372  *
373  * DESCRIPTION: Read or Write a single datum of a field. The field_type is
374  * demultiplexed here to handle the different types of fields
375  * (buffer_field, region_field, index_field, bank_field)
376  *
377  ******************************************************************************/
378 
379 static acpi_status
380 acpi_ex_field_datum_io(union acpi_operand_object *obj_desc,
381  u32 field_datum_byte_offset, u64 *value, u32 read_write)
382 {
384  u64 local_value;
385 
386  ACPI_FUNCTION_TRACE_U32(ex_field_datum_io, field_datum_byte_offset);
387 
388  if (read_write == ACPI_READ) {
389  if (!value) {
390  local_value = 0;
391 
392  /* To support reads without saving return value */
393  value = &local_value;
394  }
395 
396  /* Clear the entire return buffer first, [Very Important!] */
397 
398  *value = 0;
399  }
400 
401  /*
402  * The four types of fields are:
403  *
404  * buffer_field - Read/write from/to a Buffer
405  * region_field - Read/write from/to a Operation Region.
406  * bank_field - Write to a Bank Register, then read/write from/to an
407  * operation_region
408  * index_field - Write to an Index Register, then read/write from/to a
409  * Data Register
410  */
411  switch (obj_desc->common.type) {
413  /*
414  * If the buffer_field arguments have not been previously evaluated,
415  * evaluate them now and save the results.
416  */
417  if (!(obj_desc->common.flags & AOPOBJ_DATA_VALID)) {
418  status = acpi_ds_get_buffer_field_arguments(obj_desc);
419  if (ACPI_FAILURE(status)) {
420  return_ACPI_STATUS(status);
421  }
422  }
423 
424  if (read_write == ACPI_READ) {
425  /*
426  * Copy the data from the source buffer.
427  * Length is the field width in bytes.
428  */
429  ACPI_MEMCPY(value,
430  (obj_desc->buffer_field.buffer_obj)->buffer.
431  pointer +
432  obj_desc->buffer_field.base_byte_offset +
433  field_datum_byte_offset,
434  obj_desc->common_field.access_byte_width);
435  } else {
436  /*
437  * Copy the data to the target buffer.
438  * Length is the field width in bytes.
439  */
440  ACPI_MEMCPY((obj_desc->buffer_field.buffer_obj)->buffer.
441  pointer +
442  obj_desc->buffer_field.base_byte_offset +
443  field_datum_byte_offset, value,
444  obj_desc->common_field.access_byte_width);
445  }
446 
447  status = AE_OK;
448  break;
449 
451 
452  /*
453  * Ensure that the bank_value is not beyond the capacity of
454  * the register
455  */
456  if (acpi_ex_register_overflow(obj_desc->bank_field.bank_obj,
457  (u64) obj_desc->bank_field.
458  value)) {
460  }
461 
462  /*
463  * For bank_fields, we must write the bank_value to the bank_register
464  * (itself a region_field) before we can access the data.
465  */
466  status =
467  acpi_ex_insert_into_field(obj_desc->bank_field.bank_obj,
468  &obj_desc->bank_field.value,
469  sizeof(obj_desc->bank_field.
470  value));
471  if (ACPI_FAILURE(status)) {
472  return_ACPI_STATUS(status);
473  }
474 
475  /*
476  * Now that the Bank has been selected, fall through to the
477  * region_field case and write the datum to the Operation Region
478  */
479 
480  /*lint -fallthrough */
481 
483  /*
484  * For simple region_fields, we just directly access the owning
485  * Operation Region.
486  */
487  status =
488  acpi_ex_access_region(obj_desc, field_datum_byte_offset,
489  value, read_write);
490  break;
491 
493 
494  /*
495  * Ensure that the index_value is not beyond the capacity of
496  * the register
497  */
498  if (acpi_ex_register_overflow(obj_desc->index_field.index_obj,
499  (u64) obj_desc->index_field.
500  value)) {
502  }
503 
504  /* Write the index value to the index_register (itself a region_field) */
505 
506  field_datum_byte_offset += obj_desc->index_field.value;
507 
509  "Write to Index Register: Value %8.8X\n",
510  field_datum_byte_offset));
511 
512  status =
513  acpi_ex_insert_into_field(obj_desc->index_field.index_obj,
514  &field_datum_byte_offset,
515  sizeof(field_datum_byte_offset));
516  if (ACPI_FAILURE(status)) {
517  return_ACPI_STATUS(status);
518  }
519 
520  if (read_write == ACPI_READ) {
521 
522  /* Read the datum from the data_register */
523 
525  "Read from Data Register\n"));
526 
527  status =
529  data_obj, value,
530  sizeof(u64));
531  } else {
532  /* Write the datum to the data_register */
533 
535  "Write to Data Register: Value %8.8X%8.8X\n",
536  ACPI_FORMAT_UINT64(*value)));
537 
538  status =
540  data_obj, value,
541  sizeof(u64));
542  }
543  break;
544 
545  default:
546 
547  ACPI_ERROR((AE_INFO, "Wrong object type in field I/O %u",
548  obj_desc->common.type));
549  status = AE_AML_INTERNAL;
550  break;
551  }
552 
553  if (ACPI_SUCCESS(status)) {
554  if (read_write == ACPI_READ) {
556  "Value Read %8.8X%8.8X, Width %u\n",
557  ACPI_FORMAT_UINT64(*value),
558  obj_desc->common_field.
559  access_byte_width));
560  } else {
562  "Value Written %8.8X%8.8X, Width %u\n",
563  ACPI_FORMAT_UINT64(*value),
564  obj_desc->common_field.
565  access_byte_width));
566  }
567  }
568 
569  return_ACPI_STATUS(status);
570 }
571 
572 /*******************************************************************************
573  *
574  * FUNCTION: acpi_ex_write_with_update_rule
575  *
576  * PARAMETERS: obj_desc - Field to be written
577  * mask - bitmask within field datum
578  * field_value - Value to write
579  * field_datum_byte_offset - Offset of datum within field
580  *
581  * RETURN: Status
582  *
583  * DESCRIPTION: Apply the field update rule to a field write
584  *
585  ******************************************************************************/
586 
589  u64 mask,
590  u64 field_value, u32 field_datum_byte_offset)
591 {
592  acpi_status status = AE_OK;
593  u64 merged_value;
594  u64 current_value;
595 
596  ACPI_FUNCTION_TRACE_U32(ex_write_with_update_rule, mask);
597 
598  /* Start with the new bits */
599 
600  merged_value = field_value;
601 
602  /* If the mask is all ones, we don't need to worry about the update rule */
603 
604  if (mask != ACPI_UINT64_MAX) {
605 
606  /* Decode the update rule */
607 
608  switch (obj_desc->common_field.
609  field_flags & AML_FIELD_UPDATE_RULE_MASK) {
611  /*
612  * Check if update rule needs to be applied (not if mask is all
613  * ones) The left shift drops the bits we want to ignore.
614  */
615  if ((~mask << (ACPI_MUL_8(sizeof(mask)) -
616  ACPI_MUL_8(obj_desc->common_field.
617  access_byte_width))) != 0) {
618  /*
619  * Read the current contents of the byte/word/dword containing
620  * the field, and merge with the new field value.
621  */
622  status =
623  acpi_ex_field_datum_io(obj_desc,
624  field_datum_byte_offset,
625  &current_value,
626  ACPI_READ);
627  if (ACPI_FAILURE(status)) {
628  return_ACPI_STATUS(status);
629  }
630 
631  merged_value |= (current_value & ~mask);
632  }
633  break;
634 
636 
637  /* Set positions outside the field to all ones */
638 
639  merged_value |= ~mask;
640  break;
641 
643 
644  /* Set positions outside the field to all zeros */
645 
646  merged_value &= mask;
647  break;
648 
649  default:
650 
652  "Unknown UpdateRule value: 0x%X",
653  (obj_desc->common_field.
654  field_flags &
655  AML_FIELD_UPDATE_RULE_MASK)));
657  }
658  }
659 
661  "Mask %8.8X%8.8X, DatumOffset %X, Width %X, Value %8.8X%8.8X, MergedValue %8.8X%8.8X\n",
662  ACPI_FORMAT_UINT64(mask),
663  field_datum_byte_offset,
664  obj_desc->common_field.access_byte_width,
665  ACPI_FORMAT_UINT64(field_value),
666  ACPI_FORMAT_UINT64(merged_value)));
667 
668  /* Write the merged value */
669 
670  status = acpi_ex_field_datum_io(obj_desc, field_datum_byte_offset,
671  &merged_value, ACPI_WRITE);
672 
673  return_ACPI_STATUS(status);
674 }
675 
676 /*******************************************************************************
677  *
678  * FUNCTION: acpi_ex_extract_from_field
679  *
680  * PARAMETERS: obj_desc - Field to be read
681  * buffer - Where to store the field data
682  * buffer_length - Length of Buffer
683  *
684  * RETURN: Status
685  *
686  * DESCRIPTION: Retrieve the current value of the given field
687  *
688  ******************************************************************************/
689 
692  void *buffer, u32 buffer_length)
693 {
695  u64 raw_datum;
696  u64 merged_datum;
697  u32 field_offset = 0;
698  u32 buffer_offset = 0;
699  u32 buffer_tail_bits;
700  u32 datum_count;
701  u32 field_datum_count;
702  u32 access_bit_width;
703  u32 i;
704 
705  ACPI_FUNCTION_TRACE(ex_extract_from_field);
706 
707  /* Validate target buffer and clear it */
708 
709  if (buffer_length <
710  ACPI_ROUND_BITS_UP_TO_BYTES(obj_desc->common_field.bit_length)) {
712  "Field size %u (bits) is too large for buffer (%u)",
713  obj_desc->common_field.bit_length, buffer_length));
714 
716  }
717 
718  ACPI_MEMSET(buffer, 0, buffer_length);
719  access_bit_width = ACPI_MUL_8(obj_desc->common_field.access_byte_width);
720 
721  /* Handle the simple case here */
722 
723  if ((obj_desc->common_field.start_field_bit_offset == 0) &&
724  (obj_desc->common_field.bit_length == access_bit_width)) {
725  status = acpi_ex_field_datum_io(obj_desc, 0, buffer, ACPI_READ);
726  return_ACPI_STATUS(status);
727  }
728 
729 /* TBD: Move to common setup code */
730 
731  /* Field algorithm is limited to sizeof(u64), truncate if needed */
732 
733  if (obj_desc->common_field.access_byte_width > sizeof(u64)) {
734  obj_desc->common_field.access_byte_width = sizeof(u64);
735  access_bit_width = sizeof(u64) * 8;
736  }
737 
738  /* Compute the number of datums (access width data items) */
739 
740  datum_count =
741  ACPI_ROUND_UP_TO(obj_desc->common_field.bit_length,
742  access_bit_width);
743 
744  field_datum_count = ACPI_ROUND_UP_TO(obj_desc->common_field.bit_length +
745  obj_desc->common_field.
746  start_field_bit_offset,
747  access_bit_width);
748 
749  /* Priming read from the field */
750 
751  status =
752  acpi_ex_field_datum_io(obj_desc, field_offset, &raw_datum,
753  ACPI_READ);
754  if (ACPI_FAILURE(status)) {
755  return_ACPI_STATUS(status);
756  }
757  merged_datum =
758  raw_datum >> obj_desc->common_field.start_field_bit_offset;
759 
760  /* Read the rest of the field */
761 
762  for (i = 1; i < field_datum_count; i++) {
763 
764  /* Get next input datum from the field */
765 
766  field_offset += obj_desc->common_field.access_byte_width;
767  status = acpi_ex_field_datum_io(obj_desc, field_offset,
768  &raw_datum, ACPI_READ);
769  if (ACPI_FAILURE(status)) {
770  return_ACPI_STATUS(status);
771  }
772 
773  /*
774  * Merge with previous datum if necessary.
775  *
776  * Note: Before the shift, check if the shift value will be larger than
777  * the integer size. If so, there is no need to perform the operation.
778  * This avoids the differences in behavior between different compilers
779  * concerning shift values larger than the target data width.
780  */
781  if (access_bit_width -
782  obj_desc->common_field.start_field_bit_offset <
784  merged_datum |=
785  raw_datum << (access_bit_width -
786  obj_desc->common_field.
787  start_field_bit_offset);
788  }
789 
790  if (i == datum_count) {
791  break;
792  }
793 
794  /* Write merged datum to target buffer */
795 
796  ACPI_MEMCPY(((char *)buffer) + buffer_offset, &merged_datum,
797  ACPI_MIN(obj_desc->common_field.access_byte_width,
798  buffer_length - buffer_offset));
799 
800  buffer_offset += obj_desc->common_field.access_byte_width;
801  merged_datum =
802  raw_datum >> obj_desc->common_field.start_field_bit_offset;
803  }
804 
805  /* Mask off any extra bits in the last datum */
806 
807  buffer_tail_bits = obj_desc->common_field.bit_length % access_bit_width;
808  if (buffer_tail_bits) {
809  merged_datum &= ACPI_MASK_BITS_ABOVE(buffer_tail_bits);
810  }
811 
812  /* Write the last datum to the buffer */
813 
814  ACPI_MEMCPY(((char *)buffer) + buffer_offset, &merged_datum,
815  ACPI_MIN(obj_desc->common_field.access_byte_width,
816  buffer_length - buffer_offset));
817 
819 }
820 
821 /*******************************************************************************
822  *
823  * FUNCTION: acpi_ex_insert_into_field
824  *
825  * PARAMETERS: obj_desc - Field to be written
826  * buffer - Data to be written
827  * buffer_length - Length of Buffer
828  *
829  * RETURN: Status
830  *
831  * DESCRIPTION: Store the Buffer contents into the given field
832  *
833  ******************************************************************************/
834 
837  void *buffer, u32 buffer_length)
838 {
839  void *new_buffer;
841  u64 mask;
842  u64 width_mask;
843  u64 merged_datum;
844  u64 raw_datum = 0;
845  u32 field_offset = 0;
846  u32 buffer_offset = 0;
847  u32 buffer_tail_bits;
848  u32 datum_count;
849  u32 field_datum_count;
850  u32 access_bit_width;
851  u32 required_length;
852  u32 i;
853 
854  ACPI_FUNCTION_TRACE(ex_insert_into_field);
855 
856  /* Validate input buffer */
857 
858  new_buffer = NULL;
859  required_length =
860  ACPI_ROUND_BITS_UP_TO_BYTES(obj_desc->common_field.bit_length);
861  /*
862  * We must have a buffer that is at least as long as the field
863  * we are writing to. This is because individual fields are
864  * indivisible and partial writes are not supported -- as per
865  * the ACPI specification.
866  */
867  if (buffer_length < required_length) {
868 
869  /* We need to create a new buffer */
870 
871  new_buffer = ACPI_ALLOCATE_ZEROED(required_length);
872  if (!new_buffer) {
874  }
875 
876  /*
877  * Copy the original data to the new buffer, starting
878  * at Byte zero. All unused (upper) bytes of the
879  * buffer will be 0.
880  */
881  ACPI_MEMCPY((char *)new_buffer, (char *)buffer, buffer_length);
882  buffer = new_buffer;
883  buffer_length = required_length;
884  }
885 
886 /* TBD: Move to common setup code */
887 
888  /* Algo is limited to sizeof(u64), so cut the access_byte_width */
889  if (obj_desc->common_field.access_byte_width > sizeof(u64)) {
890  obj_desc->common_field.access_byte_width = sizeof(u64);
891  }
892 
893  access_bit_width = ACPI_MUL_8(obj_desc->common_field.access_byte_width);
894 
895  /*
896  * Create the bitmasks used for bit insertion.
897  * Note: This if/else is used to bypass compiler differences with the
898  * shift operator
899  */
900  if (access_bit_width == ACPI_INTEGER_BIT_SIZE) {
901  width_mask = ACPI_UINT64_MAX;
902  } else {
903  width_mask = ACPI_MASK_BITS_ABOVE(access_bit_width);
904  }
905 
906  mask = width_mask &
907  ACPI_MASK_BITS_BELOW(obj_desc->common_field.start_field_bit_offset);
908 
909  /* Compute the number of datums (access width data items) */
910 
911  datum_count = ACPI_ROUND_UP_TO(obj_desc->common_field.bit_length,
912  access_bit_width);
913 
914  field_datum_count = ACPI_ROUND_UP_TO(obj_desc->common_field.bit_length +
915  obj_desc->common_field.
916  start_field_bit_offset,
917  access_bit_width);
918 
919  /* Get initial Datum from the input buffer */
920 
921  ACPI_MEMCPY(&raw_datum, buffer,
922  ACPI_MIN(obj_desc->common_field.access_byte_width,
923  buffer_length - buffer_offset));
924 
925  merged_datum =
926  raw_datum << obj_desc->common_field.start_field_bit_offset;
927 
928  /* Write the entire field */
929 
930  for (i = 1; i < field_datum_count; i++) {
931 
932  /* Write merged datum to the target field */
933 
934  merged_datum &= mask;
935  status = acpi_ex_write_with_update_rule(obj_desc, mask,
936  merged_datum,
937  field_offset);
938  if (ACPI_FAILURE(status)) {
939  goto exit;
940  }
941 
942  field_offset += obj_desc->common_field.access_byte_width;
943 
944  /*
945  * Start new output datum by merging with previous input datum
946  * if necessary.
947  *
948  * Note: Before the shift, check if the shift value will be larger than
949  * the integer size. If so, there is no need to perform the operation.
950  * This avoids the differences in behavior between different compilers
951  * concerning shift values larger than the target data width.
952  */
953  if ((access_bit_width -
954  obj_desc->common_field.start_field_bit_offset) <
956  merged_datum =
957  raw_datum >> (access_bit_width -
958  obj_desc->common_field.
959  start_field_bit_offset);
960  } else {
961  merged_datum = 0;
962  }
963 
964  mask = width_mask;
965 
966  if (i == datum_count) {
967  break;
968  }
969 
970  /* Get the next input datum from the buffer */
971 
972  buffer_offset += obj_desc->common_field.access_byte_width;
973  ACPI_MEMCPY(&raw_datum, ((char *)buffer) + buffer_offset,
974  ACPI_MIN(obj_desc->common_field.access_byte_width,
975  buffer_length - buffer_offset));
976 
977  merged_datum |=
978  raw_datum << obj_desc->common_field.start_field_bit_offset;
979  }
980 
981  /* Mask off any extra bits in the last datum */
982 
983  buffer_tail_bits = (obj_desc->common_field.bit_length +
984  obj_desc->common_field.start_field_bit_offset) %
985  access_bit_width;
986  if (buffer_tail_bits) {
987  mask &= ACPI_MASK_BITS_ABOVE(buffer_tail_bits);
988  }
989 
990  /* Write the last datum to the field */
991 
992  merged_datum &= mask;
993  status = acpi_ex_write_with_update_rule(obj_desc,
994  mask, merged_datum,
995  field_offset);
996 
997  exit:
998  /* Free temporary buffer if we used one */
999 
1000  if (new_buffer) {
1001  ACPI_FREE(new_buffer);
1002  }
1003  return_ACPI_STATUS(status);
1004 }