void AcpiTbCreateLocalFadt ( ACPI_TABLE_HEADER *Table, UINT32 Length) { /* * Check if the FADT is larger than the largest table that we expect * (the ACPI 2.0/3.0 version). If so, truncate the table, and issue * a warning. */ if (Length > sizeof (ACPI_TABLE_FADT)) { ACPI_WARNING ((AE_INFO, "FADT (revision %u) is longer than ACPI 2.0 version, truncating length 0x%X to 0x%X", Table->Revision, Length, sizeof (ACPI_TABLE_FADT))); } /* Clear the entire local FADT */ ACPI_MEMSET (&AcpiGbl_FADT, 0, sizeof (ACPI_TABLE_FADT)); /* Copy the original FADT, up to sizeof (ACPI_TABLE_FADT) */ ACPI_MEMCPY (&AcpiGbl_FADT, Table, ACPI_MIN (Length, sizeof (ACPI_TABLE_FADT))); /* * 1) Convert the local copy of the FADT to the common internal format * 2) Validate some of the important values within the FADT */ AcpiTbConvertFadt (); AcpiTbValidateFadt (); }
void __init acpi_tb_create_local_fadt(struct acpi_table_header *table, u32 length) { /* * Check if the FADT is larger than the largest table that we expect * (the ACPI 2.0/3.0 version). If so, truncate the table, and issue * a warning. */ if (length > sizeof(struct acpi_table_fadt)) { ACPI_WARNING((AE_INFO, "FADT (revision %u) is longer than ACPI 2.0 version, truncating length 0x%X to 0x%zX", table->revision, (unsigned)length, sizeof(struct acpi_table_fadt))); } /* Clear the entire local FADT */ ACPI_MEMSET(&acpi_gbl_FADT, 0, sizeof(struct acpi_table_fadt)); /* Copy the original FADT, up to sizeof (struct acpi_table_fadt) */ ACPI_MEMCPY(&acpi_gbl_FADT, table, ACPI_MIN(length, sizeof(struct acpi_table_fadt))); /* * 1) Convert the local copy of the FADT to the common internal format * 2) Validate some of the important values within the FADT */ acpi_tb_convert_fadt(); acpi_tb_validate_fadt(); }
void acpi_tb_create_local_fadt(struct acpi_table_header *table, u32 length) { if (length > sizeof(struct acpi_table_fadt)) { ACPI_WARNING((AE_INFO, "FADT (revision %u) is longer than ACPI 2.0 version, " "truncating length 0x%X to 0x%X", table->revision, length, (u32)sizeof(struct acpi_table_fadt))); } ACPI_MEMSET(&acpi_gbl_FADT, 0, sizeof(struct acpi_table_fadt)); ACPI_MEMCPY(&acpi_gbl_FADT, table, ACPI_MIN(length, sizeof(struct acpi_table_fadt))); acpi_tb_convert_fadt(); acpi_tb_validate_fadt(); acpi_tb_setup_fadt_registers(); }
void AcpiTbCreateLocalFadt ( ACPI_TABLE_HEADER *Table, UINT32 Length) { /* * Check if the FADT is larger than what we know about (ACPI 2.0 version). * Truncate the table, but make some noise. */ if (Length > sizeof (ACPI_TABLE_FADT)) { ACPI_WARNING ((AE_INFO, "FADT (revision %u) is longer than ACPI 2.0 version, truncating length 0x%X to 0x%zX", Table->Revision, Length, sizeof (ACPI_TABLE_FADT))); } /* Copy the entire FADT locally. Zero first for TbConvertFadt */ ACPI_MEMSET (&AcpiGbl_FADT, 0, sizeof (ACPI_TABLE_FADT)); ACPI_MEMCPY (&AcpiGbl_FADT, Table, ACPI_MIN (Length, sizeof (ACPI_TABLE_FADT))); /* * 1) Convert the local copy of the FADT to the common internal format * 2) Validate some of the important values within the FADT */ AcpiTbConvertFadt (); AcpiTbValidateFadt (); }
void AcpiTbCreateLocalFadt ( ACPI_TABLE_HEADER *Table, UINT32 Length) { /* * Check if the FADT is larger than the largest table that we expect * (the ACPI 5.0 version). If so, truncate the table, and issue * a warning. */ if (Length > sizeof (ACPI_TABLE_FADT)) { ACPI_BIOS_WARNING ((AE_INFO, "FADT (revision %u) is longer than ACPI 5.0 version, " "truncating length %u to %u", Table->Revision, Length, (UINT32) sizeof (ACPI_TABLE_FADT))); } /* Clear the entire local FADT */ ACPI_MEMSET (&AcpiGbl_FADT, 0, sizeof (ACPI_TABLE_FADT)); /* Copy the original FADT, up to sizeof (ACPI_TABLE_FADT) */ ACPI_MEMCPY (&AcpiGbl_FADT, Table, ACPI_MIN (Length, sizeof (ACPI_TABLE_FADT))); /* Take a copy of the Hardware Reduced flag */ AcpiGbl_ReducedHardware = FALSE; if (AcpiGbl_FADT.Flags & ACPI_FADT_HW_REDUCED) { AcpiGbl_ReducedHardware = TRUE; } /* Convert the local copy of the FADT to the common internal format */ AcpiTbConvertFadt (); /* Validate FADT values now, before we make any changes */ AcpiTbValidateFadt (); /* Initialize the global ACPI register structures */ AcpiTbSetupFadtRegisters (); }
u8 acpi_ut_safe_strncat(char *dest, acpi_size dest_size, char *source, acpi_size max_transfer_length) { acpi_size actual_transfer_length; actual_transfer_length = ACPI_MIN(max_transfer_length, strlen(source)); if ((strlen(dest) + actual_transfer_length) >= dest_size) { return (TRUE); } strncat(dest, source, max_transfer_length); return (FALSE); }
void AcpiTbCreateLocalFadt ( ACPI_TABLE_HEADER *Table, UINT32 Length) { /* * Check if the FADT is larger than the largest table that we expect * (typically the current ACPI specification version). If so, truncate * the table, and issue a warning. */ if (Length > sizeof (ACPI_TABLE_FADT)) { ACPI_BIOS_WARNING ((AE_INFO, "FADT (revision %u) is longer than %s length, " "truncating length %u to %u", Table->Revision, ACPI_FADT_CONFORMANCE, Length, (UINT32) sizeof (ACPI_TABLE_FADT))); } /* Clear the entire local FADT */ memset (&AcpiGbl_FADT, 0, sizeof (ACPI_TABLE_FADT)); /* Copy the original FADT, up to sizeof (ACPI_TABLE_FADT) */ memcpy (&AcpiGbl_FADT, Table, ACPI_MIN (Length, sizeof (ACPI_TABLE_FADT))); /* Take a copy of the Hardware Reduced flag */ AcpiGbl_ReducedHardware = FALSE; if (AcpiGbl_FADT.Flags & ACPI_FADT_HW_REDUCED) { AcpiGbl_ReducedHardware = TRUE; } /* Convert the local copy of the FADT to the common internal format */ AcpiTbConvertFadt (); /* Initialize the global ACPI register structures */ AcpiTbSetupFadtRegisters (); }
void acpi_tb_create_local_fadt(struct acpi_table_header *table, u32 length) { /* * Check if the FADT is larger than the largest table that we expect * (the ACPI 5.0 version). If so, truncate the table, and issue * a warning. */ /* 기본 테이블 크기보다 크면 2.0 이상이면 경고 출력 */ if (length > sizeof(struct acpi_table_fadt)) { ACPI_BIOS_WARNING((AE_INFO, "FADT (revision %u) is longer than ACPI 5.0 version, " "truncating length %u to %u", table->revision, length, (u32)sizeof(struct acpi_table_fadt))); } /* Clear the entire local FADT */ /* acpi_gbl_FADT 테이블 초기화 */ ACPI_MEMSET(&acpi_gbl_FADT, 0, sizeof(struct acpi_table_fadt)); /* Copy the original FADT, up to sizeof (struct acpi_table_fadt) */ /* acpi_gbl_FADT에 기본 테이블 크기만큼 복사 */ ACPI_MEMCPY(&acpi_gbl_FADT, table, ACPI_MIN(length, sizeof(struct acpi_table_fadt))); /* Take a copy of the Hardware Reduced flag */ acpi_gbl_reduced_hardware = FALSE; if (acpi_gbl_FADT.flags & ACPI_FADT_HW_REDUCED) { acpi_gbl_reduced_hardware = TRUE; } /* Convert the local copy of the FADT to the common internal format */ acpi_tb_convert_fadt(); /* Validate FADT values now, before we make any changes */ acpi_tb_validate_fadt(); /* Initialize the global ACPI register structures */ acpi_tb_setup_fadt_registers(); }
BOOLEAN AcpiUtSafeStrncat ( char *Dest, ACPI_SIZE DestSize, char *Source, ACPI_SIZE MaxTransferLength) { ACPI_SIZE ActualTransferLength; ActualTransferLength = ACPI_MIN (MaxTransferLength, ACPI_STRLEN (Source)); if ((ACPI_STRLEN (Dest) + ActualTransferLength) >= DestSize) { return (TRUE); } ACPI_STRNCAT (Dest, Source, MaxTransferLength); return (FALSE); }
void acpi_tb_create_local_fadt(struct acpi_table_header *table, u32 length) { /* * Check if the FADT is larger than the largest table that we expect * (typically the current ACPI specification version). If so, truncate * the table, and issue a warning. */ if (length > sizeof(struct acpi_table_fadt)) { ACPI_BIOS_WARNING((AE_INFO, "FADT (revision %u) is longer than %s length, " "truncating length %u to %u", table->revision, ACPI_FADT_CONFORMANCE, length, (u32)sizeof(struct acpi_table_fadt))); } /* Clear the entire local FADT */ memset(&acpi_gbl_FADT, 0, sizeof(struct acpi_table_fadt)); /* Copy the original FADT, up to sizeof (struct acpi_table_fadt) */ memcpy(&acpi_gbl_FADT, table, ACPI_MIN(length, sizeof(struct acpi_table_fadt))); /* Take a copy of the Hardware Reduced flag */ acpi_gbl_reduced_hardware = FALSE; if (acpi_gbl_FADT.flags & ACPI_FADT_HW_REDUCED) { acpi_gbl_reduced_hardware = TRUE; } /* Convert the local copy of the FADT to the common internal format */ acpi_tb_convert_fadt(); /* Initialize the global ACPI register structures */ acpi_tb_setup_fadt_registers(); }
void __init acpi_tb_create_local_fadt(struct acpi_table_header *table, u32 length) { /* * Check if the FADT is larger than the largest table that we expect * (the ACPI 5.0 version). If so, truncate the table, and issue * a warning. */ if (length > sizeof(struct acpi_table_fadt)) { ACPI_WARNING((AE_INFO, "FADT (revision %u) is longer than ACPI 5.0 version," " truncating length %u to %zu", table->revision, (unsigned)length, sizeof(struct acpi_table_fadt))); } /* Clear the entire local FADT */ ACPI_MEMSET(&acpi_gbl_FADT, 0, sizeof(struct acpi_table_fadt)); /* Copy the original FADT, up to sizeof (struct acpi_table_fadt) */ ACPI_MEMCPY(&acpi_gbl_FADT, table, ACPI_MIN(length, sizeof(struct acpi_table_fadt))); /* Take a copy of the Hardware Reduced flag */ acpi_gbl_reduced_hardware = FALSE; if (acpi_gbl_FADT.flags & ACPI_FADT_HW_REDUCED) { acpi_gbl_reduced_hardware = TRUE; } /* * 1) Convert the local copy of the FADT to the common internal format * 2) Validate some of the important values within the FADT */ acpi_tb_convert_fadt(); acpi_tb_validate_fadt(); }
void acpi_tb_create_local_fadt(struct acpi_table_header *table, u32 length) { /* * Check if the FADT is larger than the largest table that we expect * (the ACPI 2.0/3.0 version). If so, truncate the table, and issue * a warning. */ if (length > sizeof(struct acpi_table_fadt)) { ACPI_WARNING((AE_INFO, "FADT (revision %u) is longer than ACPI 2.0 version, " "truncating length %u to %u", table->revision, length, (u32)sizeof(struct acpi_table_fadt))); } /* Clear the entire local FADT */ ACPI_MEMSET(&acpi_gbl_FADT, 0, sizeof(struct acpi_table_fadt)); /* Copy the original FADT, up to sizeof (struct acpi_table_fadt) */ ACPI_MEMCPY(&acpi_gbl_FADT, table, ACPI_MIN(length, sizeof(struct acpi_table_fadt))); /* Convert the local copy of the FADT to the common internal format */ acpi_tb_convert_fadt(); /* Validate FADT values now, before we make any changes */ acpi_tb_validate_fadt(); /* Initialize the global ACPI register structures */ acpi_tb_setup_fadt_registers(); }
ACPI_STATUS AcpiExInsertIntoField ( ACPI_OPERAND_OBJECT *ObjDesc, void *Buffer, UINT32 BufferLength) { void *NewBuffer; ACPI_STATUS Status; UINT64 Mask; UINT64 WidthMask; UINT64 MergedDatum; UINT64 RawDatum = 0; UINT32 FieldOffset = 0; UINT32 BufferOffset = 0; UINT32 BufferTailBits; UINT32 DatumCount; UINT32 FieldDatumCount; UINT32 AccessBitWidth; UINT32 RequiredLength; UINT32 i; ACPI_FUNCTION_TRACE (ExInsertIntoField); /* Validate input buffer */ NewBuffer = NULL; RequiredLength = ACPI_ROUND_BITS_UP_TO_BYTES ( ObjDesc->CommonField.BitLength); /* * We must have a buffer that is at least as long as the field * we are writing to. This is because individual fields are * indivisible and partial writes are not supported -- as per * the ACPI specification. */ if (BufferLength < RequiredLength) { /* We need to create a new buffer */ NewBuffer = ACPI_ALLOCATE_ZEROED (RequiredLength); if (!NewBuffer) { return_ACPI_STATUS (AE_NO_MEMORY); } /* * Copy the original data to the new buffer, starting * at Byte zero. All unused (upper) bytes of the * buffer will be 0. */ memcpy ((char *) NewBuffer, (char *) Buffer, BufferLength); Buffer = NewBuffer; BufferLength = RequiredLength; } /* TBD: Move to common setup code */ /* Algo is limited to sizeof(UINT64), so cut the AccessByteWidth */ if (ObjDesc->CommonField.AccessByteWidth > sizeof (UINT64)) { ObjDesc->CommonField.AccessByteWidth = sizeof (UINT64); } AccessBitWidth = ACPI_MUL_8 (ObjDesc->CommonField.AccessByteWidth); /* * Create the bitmasks used for bit insertion. * Note: This if/else is used to bypass compiler differences with the * shift operator */ if (AccessBitWidth == ACPI_INTEGER_BIT_SIZE) { WidthMask = ACPI_UINT64_MAX; } else { WidthMask = ACPI_MASK_BITS_ABOVE (AccessBitWidth); } Mask = WidthMask & ACPI_MASK_BITS_BELOW (ObjDesc->CommonField.StartFieldBitOffset); /* Compute the number of datums (access width data items) */ DatumCount = ACPI_ROUND_UP_TO (ObjDesc->CommonField.BitLength, AccessBitWidth); FieldDatumCount = ACPI_ROUND_UP_TO (ObjDesc->CommonField.BitLength + ObjDesc->CommonField.StartFieldBitOffset, AccessBitWidth); /* Get initial Datum from the input buffer */ memcpy (&RawDatum, Buffer, ACPI_MIN(ObjDesc->CommonField.AccessByteWidth, BufferLength - BufferOffset)); MergedDatum = RawDatum << ObjDesc->CommonField.StartFieldBitOffset; /* Write the entire field */ for (i = 1; i < FieldDatumCount; i++) { /* Write merged datum to the target field */ MergedDatum &= Mask; Status = AcpiExWriteWithUpdateRule (ObjDesc, Mask, MergedDatum, FieldOffset); if (ACPI_FAILURE (Status)) { goto Exit; } FieldOffset += ObjDesc->CommonField.AccessByteWidth; /* * Start new output datum by merging with previous input datum * if necessary. * * Note: Before the shift, check if the shift value will be larger than * the integer size. If so, there is no need to perform the operation. * This avoids the differences in behavior between different compilers * concerning shift values larger than the target data width. */ if ((AccessBitWidth - ObjDesc->CommonField.StartFieldBitOffset) < ACPI_INTEGER_BIT_SIZE) { MergedDatum = RawDatum >> (AccessBitWidth - ObjDesc->CommonField.StartFieldBitOffset); } else {
ACPI_STATUS AcpiExExtractFromField ( ACPI_OPERAND_OBJECT *ObjDesc, void *Buffer, UINT32 BufferLength) { ACPI_STATUS Status; UINT64 RawDatum; UINT64 MergedDatum; UINT32 FieldOffset = 0; UINT32 BufferOffset = 0; UINT32 BufferTailBits; UINT32 DatumCount; UINT32 FieldDatumCount; UINT32 AccessBitWidth; UINT32 i; ACPI_FUNCTION_TRACE (ExExtractFromField); /* Validate target buffer and clear it */ if (BufferLength < ACPI_ROUND_BITS_UP_TO_BYTES (ObjDesc->CommonField.BitLength)) { ACPI_ERROR ((AE_INFO, "Field size %u (bits) is too large for buffer (%u)", ObjDesc->CommonField.BitLength, BufferLength)); return_ACPI_STATUS (AE_BUFFER_OVERFLOW); } memset (Buffer, 0, BufferLength); AccessBitWidth = ACPI_MUL_8 (ObjDesc->CommonField.AccessByteWidth); /* Handle the simple case here */ if ((ObjDesc->CommonField.StartFieldBitOffset == 0) && (ObjDesc->CommonField.BitLength == AccessBitWidth)) { if (BufferLength >= sizeof (UINT64)) { Status = AcpiExFieldDatumIo (ObjDesc, 0, Buffer, ACPI_READ); } else { /* Use RawDatum (UINT64) to handle buffers < 64 bits */ Status = AcpiExFieldDatumIo (ObjDesc, 0, &RawDatum, ACPI_READ); memcpy (Buffer, &RawDatum, BufferLength); } return_ACPI_STATUS (Status); } /* TBD: Move to common setup code */ /* Field algorithm is limited to sizeof(UINT64), truncate if needed */ if (ObjDesc->CommonField.AccessByteWidth > sizeof (UINT64)) { ObjDesc->CommonField.AccessByteWidth = sizeof (UINT64); AccessBitWidth = sizeof (UINT64) * 8; } /* Compute the number of datums (access width data items) */ DatumCount = ACPI_ROUND_UP_TO ( ObjDesc->CommonField.BitLength, AccessBitWidth); FieldDatumCount = ACPI_ROUND_UP_TO ( ObjDesc->CommonField.BitLength + ObjDesc->CommonField.StartFieldBitOffset, AccessBitWidth); /* Priming read from the field */ Status = AcpiExFieldDatumIo (ObjDesc, FieldOffset, &RawDatum, ACPI_READ); if (ACPI_FAILURE (Status)) { return_ACPI_STATUS (Status); } MergedDatum = RawDatum >> ObjDesc->CommonField.StartFieldBitOffset; /* Read the rest of the field */ for (i = 1; i < FieldDatumCount; i++) { /* Get next input datum from the field */ FieldOffset += ObjDesc->CommonField.AccessByteWidth; Status = AcpiExFieldDatumIo (ObjDesc, FieldOffset, &RawDatum, ACPI_READ); if (ACPI_FAILURE (Status)) { return_ACPI_STATUS (Status); } /* * Merge with previous datum if necessary. * * Note: Before the shift, check if the shift value will be larger than * the integer size. If so, there is no need to perform the operation. * This avoids the differences in behavior between different compilers * concerning shift values larger than the target data width. */ if (AccessBitWidth - ObjDesc->CommonField.StartFieldBitOffset < ACPI_INTEGER_BIT_SIZE) { MergedDatum |= RawDatum << (AccessBitWidth - ObjDesc->CommonField.StartFieldBitOffset); } if (i == DatumCount) { break; } /* Write merged datum to target buffer */ memcpy (((char *) Buffer) + BufferOffset, &MergedDatum, ACPI_MIN(ObjDesc->CommonField.AccessByteWidth, BufferLength - BufferOffset)); BufferOffset += ObjDesc->CommonField.AccessByteWidth; MergedDatum = RawDatum >> ObjDesc->CommonField.StartFieldBitOffset; } /* Mask off any extra bits in the last datum */ BufferTailBits = ObjDesc->CommonField.BitLength % AccessBitWidth; if (BufferTailBits) { MergedDatum &= ACPI_MASK_BITS_ABOVE (BufferTailBits); } /* Write the last datum to the buffer */ memcpy (((char *) Buffer) + BufferOffset, &MergedDatum, ACPI_MIN(ObjDesc->CommonField.AccessByteWidth, BufferLength - BufferOffset)); return_ACPI_STATUS (AE_OK); }
acpi_status acpi_ex_insert_into_field(union acpi_operand_object *obj_desc, void *buffer, u32 buffer_length) { void *new_buffer; acpi_status status; u64 mask; u64 width_mask; u64 merged_datum; u64 raw_datum = 0; u32 field_offset = 0; u32 buffer_offset = 0; u32 buffer_tail_bits; u32 datum_count; u32 field_datum_count; u32 access_bit_width; u32 required_length; u32 i; ACPI_FUNCTION_TRACE(ex_insert_into_field); /* Validate input buffer */ new_buffer = NULL; required_length = ACPI_ROUND_BITS_UP_TO_BYTES(obj_desc->common_field.bit_length); /* * We must have a buffer that is at least as long as the field * we are writing to. This is because individual fields are * indivisible and partial writes are not supported -- as per * the ACPI specification. */ if (buffer_length < required_length) { /* We need to create a new buffer */ new_buffer = ACPI_ALLOCATE_ZEROED(required_length); if (!new_buffer) { return_ACPI_STATUS(AE_NO_MEMORY); } /* * Copy the original data to the new buffer, starting * at Byte zero. All unused (upper) bytes of the * buffer will be 0. */ ACPI_MEMCPY((char *)new_buffer, (char *)buffer, buffer_length); buffer = new_buffer; buffer_length = required_length; } /* TBD: Move to common setup code */ /* Algo is limited to sizeof(u64), so cut the access_byte_width */ if (obj_desc->common_field.access_byte_width > sizeof(u64)) { obj_desc->common_field.access_byte_width = sizeof(u64); } access_bit_width = ACPI_MUL_8(obj_desc->common_field.access_byte_width); /* * Create the bitmasks used for bit insertion. * Note: This if/else is used to bypass compiler differences with the * shift operator */ if (access_bit_width == ACPI_INTEGER_BIT_SIZE) { width_mask = ACPI_UINT64_MAX; } else { width_mask = ACPI_MASK_BITS_ABOVE(access_bit_width); } mask = width_mask & ACPI_MASK_BITS_BELOW(obj_desc->common_field.start_field_bit_offset); /* Compute the number of datums (access width data items) */ datum_count = ACPI_ROUND_UP_TO(obj_desc->common_field.bit_length, access_bit_width); field_datum_count = ACPI_ROUND_UP_TO(obj_desc->common_field.bit_length + obj_desc->common_field. start_field_bit_offset, access_bit_width); /* Get initial Datum from the input buffer */ ACPI_MEMCPY(&raw_datum, buffer, ACPI_MIN(obj_desc->common_field.access_byte_width, buffer_length - buffer_offset)); merged_datum = raw_datum << obj_desc->common_field.start_field_bit_offset; /* Write the entire field */ for (i = 1; i < field_datum_count; i++) { /* Write merged datum to the target field */ merged_datum &= mask; status = acpi_ex_write_with_update_rule(obj_desc, mask, merged_datum, field_offset); if (ACPI_FAILURE(status)) { goto exit; } field_offset += obj_desc->common_field.access_byte_width; /* * Start new output datum by merging with previous input datum * if necessary. * * Note: Before the shift, check if the shift value will be larger than * the integer size. If so, there is no need to perform the operation. * This avoids the differences in behavior between different compilers * concerning shift values larger than the target data width. */ if ((access_bit_width - obj_desc->common_field.start_field_bit_offset) < ACPI_INTEGER_BIT_SIZE) { merged_datum = raw_datum >> (access_bit_width - obj_desc->common_field. start_field_bit_offset); } else {
acpi_status acpi_ex_extract_from_field(union acpi_operand_object *obj_desc, void *buffer, u32 buffer_length) { acpi_status status; u64 raw_datum; u64 merged_datum; u32 field_offset = 0; u32 buffer_offset = 0; u32 buffer_tail_bits; u32 datum_count; u32 field_datum_count; u32 access_bit_width; u32 i; ACPI_FUNCTION_TRACE(ex_extract_from_field); /* Validate target buffer and clear it */ if (buffer_length < ACPI_ROUND_BITS_UP_TO_BYTES(obj_desc->common_field.bit_length)) { ACPI_ERROR((AE_INFO, "Field size %u (bits) is too large for buffer (%u)", obj_desc->common_field.bit_length, buffer_length)); return_ACPI_STATUS(AE_BUFFER_OVERFLOW); } ACPI_MEMSET(buffer, 0, buffer_length); access_bit_width = ACPI_MUL_8(obj_desc->common_field.access_byte_width); /* Handle the simple case here */ if ((obj_desc->common_field.start_field_bit_offset == 0) && (obj_desc->common_field.bit_length == access_bit_width)) { status = acpi_ex_field_datum_io(obj_desc, 0, buffer, ACPI_READ); return_ACPI_STATUS(status); } /* TBD: Move to common setup code */ /* Field algorithm is limited to sizeof(u64), truncate if needed */ if (obj_desc->common_field.access_byte_width > sizeof(u64)) { obj_desc->common_field.access_byte_width = sizeof(u64); access_bit_width = sizeof(u64) * 8; } /* Compute the number of datums (access width data items) */ datum_count = ACPI_ROUND_UP_TO(obj_desc->common_field.bit_length, access_bit_width); field_datum_count = ACPI_ROUND_UP_TO(obj_desc->common_field.bit_length + obj_desc->common_field. start_field_bit_offset, access_bit_width); /* Priming read from the field */ status = acpi_ex_field_datum_io(obj_desc, field_offset, &raw_datum, ACPI_READ); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } merged_datum = raw_datum >> obj_desc->common_field.start_field_bit_offset; /* Read the rest of the field */ for (i = 1; i < field_datum_count; i++) { /* Get next input datum from the field */ field_offset += obj_desc->common_field.access_byte_width; status = acpi_ex_field_datum_io(obj_desc, field_offset, &raw_datum, ACPI_READ); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } /* * Merge with previous datum if necessary. * * Note: Before the shift, check if the shift value will be larger than * the integer size. If so, there is no need to perform the operation. * This avoids the differences in behavior between different compilers * concerning shift values larger than the target data width. */ if (access_bit_width - obj_desc->common_field.start_field_bit_offset < ACPI_INTEGER_BIT_SIZE) { merged_datum |= raw_datum << (access_bit_width - obj_desc->common_field. start_field_bit_offset); } if (i == datum_count) { break; } /* Write merged datum to target buffer */ ACPI_MEMCPY(((char *)buffer) + buffer_offset, &merged_datum, ACPI_MIN(obj_desc->common_field.access_byte_width, buffer_length - buffer_offset)); buffer_offset += obj_desc->common_field.access_byte_width; merged_datum = raw_datum >> obj_desc->common_field.start_field_bit_offset; } /* Mask off any extra bits in the last datum */ buffer_tail_bits = obj_desc->common_field.bit_length % access_bit_width; if (buffer_tail_bits) { merged_datum &= ACPI_MASK_BITS_ABOVE(buffer_tail_bits); } /* Write the last datum to the buffer */ ACPI_MEMCPY(((char *)buffer) + buffer_offset, &merged_datum, ACPI_MIN(obj_desc->common_field.access_byte_width, buffer_length - buffer_offset)); return_ACPI_STATUS(AE_OK); }
acpi_status acpi_ex_insert_into_field ( union acpi_operand_object *obj_desc, void *buffer, u32 buffer_length) { acpi_status status; acpi_integer mask; acpi_integer merged_datum; acpi_integer raw_datum = 0; u32 field_offset = 0; u32 buffer_offset = 0; u32 buffer_tail_bits; u32 datum_count; u32 field_datum_count; u32 i; ACPI_FUNCTION_TRACE ("ex_insert_into_field"); /* Validate input buffer */ if (buffer_length < ACPI_ROUND_BITS_UP_TO_BYTES ( obj_desc->common_field.bit_length)) { ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Field size %X (bits) is too large for buffer (%X)\n", obj_desc->common_field.bit_length, buffer_length)); return_ACPI_STATUS (AE_BUFFER_OVERFLOW); } /* Compute the number of datums (access width data items) */ mask = ACPI_MASK_BITS_BELOW (obj_desc->common_field.start_field_bit_offset); datum_count = ACPI_ROUND_UP_TO (obj_desc->common_field.bit_length, obj_desc->common_field.access_bit_width); field_datum_count = ACPI_ROUND_UP_TO (obj_desc->common_field.bit_length + obj_desc->common_field.start_field_bit_offset, obj_desc->common_field.access_bit_width); /* Get initial Datum from the input buffer */ ACPI_MEMCPY (&raw_datum, buffer, ACPI_MIN(obj_desc->common_field.access_byte_width, buffer_length - buffer_offset)); merged_datum = raw_datum << obj_desc->common_field.start_field_bit_offset; /* Write the entire field */ for (i = 1; i < field_datum_count; i++) { /* Write merged datum to the target field */ merged_datum &= mask; status = acpi_ex_write_with_update_rule (obj_desc, mask, merged_datum, field_offset); if (ACPI_FAILURE (status)) { return_ACPI_STATUS (status); } /* Start new output datum by merging with previous input datum */ field_offset += obj_desc->common_field.access_byte_width; merged_datum = raw_datum >> (obj_desc->common_field.access_bit_width - obj_desc->common_field.start_field_bit_offset); mask = ACPI_INTEGER_MAX; if (i == datum_count) { break; } /* Get the next input datum from the buffer */ buffer_offset += obj_desc->common_field.access_byte_width; ACPI_MEMCPY (&raw_datum, ((char *) buffer) + buffer_offset, ACPI_MIN(obj_desc->common_field.access_byte_width, buffer_length - buffer_offset)); merged_datum |= raw_datum << obj_desc->common_field.start_field_bit_offset; } /* Mask off any extra bits in the last datum */ buffer_tail_bits = (obj_desc->common_field.bit_length + obj_desc->common_field.start_field_bit_offset) % obj_desc->common_field.access_bit_width; if (buffer_tail_bits) { mask &= ACPI_MASK_BITS_ABOVE (buffer_tail_bits); } /* Write the last datum to the field */ merged_datum &= mask; status = acpi_ex_write_with_update_rule (obj_desc, mask, merged_datum, field_offset); return_ACPI_STATUS (status); }
acpi_status acpi_ex_extract_from_field ( union acpi_operand_object *obj_desc, void *buffer, u32 buffer_length) { acpi_status status; acpi_integer raw_datum; acpi_integer merged_datum; u32 field_offset = 0; u32 buffer_offset = 0; u32 buffer_tail_bits; u32 datum_count; u32 field_datum_count; u32 i; ACPI_FUNCTION_TRACE ("ex_extract_from_field"); /* Validate target buffer and clear it */ if (buffer_length < ACPI_ROUND_BITS_UP_TO_BYTES ( obj_desc->common_field.bit_length)) { ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Field size %X (bits) is too large for buffer (%X)\n", obj_desc->common_field.bit_length, buffer_length)); return_ACPI_STATUS (AE_BUFFER_OVERFLOW); } ACPI_MEMSET (buffer, 0, buffer_length); /* Compute the number of datums (access width data items) */ datum_count = ACPI_ROUND_UP_TO ( obj_desc->common_field.bit_length, obj_desc->common_field.access_bit_width); field_datum_count = ACPI_ROUND_UP_TO ( obj_desc->common_field.bit_length + obj_desc->common_field.start_field_bit_offset, obj_desc->common_field.access_bit_width); /* Priming read from the field */ status = acpi_ex_field_datum_io (obj_desc, field_offset, &raw_datum, ACPI_READ); if (ACPI_FAILURE (status)) { return_ACPI_STATUS (status); } merged_datum = raw_datum >> obj_desc->common_field.start_field_bit_offset; /* Read the rest of the field */ for (i = 1; i < field_datum_count; i++) { /* Get next input datum from the field */ field_offset += obj_desc->common_field.access_byte_width; status = acpi_ex_field_datum_io (obj_desc, field_offset, &raw_datum, ACPI_READ); if (ACPI_FAILURE (status)) { return_ACPI_STATUS (status); } /* Merge with previous datum if necessary */ merged_datum |= raw_datum << (obj_desc->common_field.access_bit_width - obj_desc->common_field.start_field_bit_offset); if (i == datum_count) { break; } /* Write merged datum to target buffer */ ACPI_MEMCPY (((char *) buffer) + buffer_offset, &merged_datum, ACPI_MIN(obj_desc->common_field.access_byte_width, buffer_length - buffer_offset)); buffer_offset += obj_desc->common_field.access_byte_width; merged_datum = raw_datum >> obj_desc->common_field.start_field_bit_offset; } /* Mask off any extra bits in the last datum */ buffer_tail_bits = obj_desc->common_field.bit_length % obj_desc->common_field.access_bit_width; if (buffer_tail_bits) { merged_datum &= ACPI_MASK_BITS_ABOVE (buffer_tail_bits); } /* Write the last datum to the buffer */ ACPI_MEMCPY (((char *) buffer) + buffer_offset, &merged_datum, ACPI_MIN(obj_desc->common_field.access_byte_width, buffer_length - buffer_offset)); return_ACPI_STATUS (AE_OK); }
acpi_status acpi_ex_insert_into_field(union acpi_operand_object *obj_desc, void *buffer, u32 buffer_length) { acpi_status status; acpi_integer mask; acpi_integer width_mask; acpi_integer merged_datum; acpi_integer raw_datum = 0; u32 field_offset = 0; u32 buffer_offset = 0; u32 buffer_tail_bits; u32 datum_count; u32 field_datum_count; u32 i; ACPI_FUNCTION_TRACE(ex_insert_into_field); /* Validate input buffer */ if (buffer_length < ACPI_ROUND_BITS_UP_TO_BYTES(obj_desc->common_field.bit_length)) { ACPI_ERROR((AE_INFO, "Field size %X (bits) is too large for buffer (%X)", obj_desc->common_field.bit_length, buffer_length)); return_ACPI_STATUS(AE_BUFFER_OVERFLOW); } /* * Create the bitmasks used for bit insertion. * Note: This if/else is used to bypass compiler differences with the * shift operator */ if (obj_desc->common_field.access_bit_width == ACPI_INTEGER_BIT_SIZE) { width_mask = ACPI_INTEGER_MAX; } else { width_mask = ACPI_MASK_BITS_ABOVE(obj_desc->common_field. access_bit_width); } mask = width_mask & ACPI_MASK_BITS_BELOW(obj_desc->common_field.start_field_bit_offset); /* Compute the number of datums (access width data items) */ datum_count = ACPI_ROUND_UP_TO(obj_desc->common_field.bit_length, obj_desc->common_field.access_bit_width); field_datum_count = ACPI_ROUND_UP_TO(obj_desc->common_field.bit_length + obj_desc->common_field. start_field_bit_offset, obj_desc->common_field. access_bit_width); /* Get initial Datum from the input buffer */ ACPI_MEMCPY(&raw_datum, buffer, ACPI_MIN(obj_desc->common_field.access_byte_width, buffer_length - buffer_offset)); merged_datum = raw_datum << obj_desc->common_field.start_field_bit_offset; /* Write the entire field */ for (i = 1; i < field_datum_count; i++) { /* Write merged datum to the target field */ merged_datum &= mask; status = acpi_ex_write_with_update_rule(obj_desc, mask, merged_datum, field_offset); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } field_offset += obj_desc->common_field.access_byte_width; /* * Start new output datum by merging with previous input datum * if necessary. * * Note: Before the shift, check if the shift value will be larger than * the integer size. If so, there is no need to perform the operation. * This avoids the differences in behavior between different compilers * concerning shift values larger than the target data width. */ if ((obj_desc->common_field.access_bit_width - obj_desc->common_field.start_field_bit_offset) < ACPI_INTEGER_BIT_SIZE) { merged_datum = raw_datum >> (obj_desc->common_field. access_bit_width - obj_desc->common_field. start_field_bit_offset); } else {