ACPI_STATUS DtCompilePadding ( UINT32 Length, DT_SUBTABLE **RetSubtable) { DT_SUBTABLE *Subtable; /* UINT8 *Buffer; */ char *String; Subtable = UtSubtableCacheCalloc (); if (Length > 0) { String = UtLocalCacheCalloc (Length); Subtable->Buffer = ACPI_CAST_PTR (UINT8, String); } Subtable->Length = Length; Subtable->TotalLength = Length; /* Buffer = Subtable->Buffer; */ *RetSubtable = Subtable; return (AE_OK); }
void DtCreateSubtable ( UINT8 *Buffer, UINT32 Length, DT_SUBTABLE **RetSubtable) { DT_SUBTABLE *Subtable; char *String; Subtable = UtSubtableCacheCalloc (); /* Create a new buffer for the subtable data */ String = UtStringCacheCalloc (Length); Subtable->Buffer = ACPI_CAST_PTR (UINT8, String); memcpy (Subtable->Buffer, Buffer, Length); Subtable->Length = Length; Subtable->TotalLength = Length; *RetSubtable = Subtable; }
ACPI_STATUS DtCompileTable ( DT_FIELD **Field, ACPI_DMTABLE_INFO *Info, DT_SUBTABLE **RetSubtable, BOOLEAN Required) { DT_FIELD *LocalField; UINT32 Length; DT_SUBTABLE *Subtable; DT_SUBTABLE *InlineSubtable; UINT32 FieldLength = 0; UINT8 FieldType; UINT8 *Buffer; UINT8 *FlagBuffer = NULL; UINT32 CurrentFlagByteOffset = 0; ACPI_STATUS Status; if (!Field || !*Field) { return (AE_BAD_PARAMETER); } /* Ignore optional subtable if name does not match */ if ((Info->Flags & DT_OPTIONAL) && ACPI_STRCMP ((*Field)->Name, Info->Name)) { *RetSubtable = NULL; return (AE_OK); } Length = DtGetSubtableLength (*Field, Info); if (Length == ASL_EOF) { return (AE_ERROR); } Subtable = UtSubtableCacheCalloc (); if (Length > 0) { Subtable->Buffer = ACPI_CAST_PTR (UINT8, UtStringCacheCalloc (Length)); } Subtable->Length = Length; Subtable->TotalLength = Length; Buffer = Subtable->Buffer; LocalField = *Field; /* * Main loop walks the info table for this ACPI table or subtable */ for (; Info->Name; Info++) { if (Info->Opcode == ACPI_DMT_EXTRA_TEXT) { continue; } if (!LocalField) { sprintf (MsgBuffer, "Found NULL field - Field name \"%s\" needed", Info->Name); DtFatal (ASL_MSG_COMPILER_INTERNAL, NULL, MsgBuffer); Status = AE_BAD_DATA; goto Error; } /* Maintain table offsets */ LocalField->TableOffset = Gbl_CurrentTableOffset; FieldLength = DtGetFieldLength (LocalField, Info); Gbl_CurrentTableOffset += FieldLength; FieldType = DtGetFieldType (Info); Gbl_InputFieldCount++; switch (FieldType) { case DT_FIELD_TYPE_FLAGS_INTEGER: /* * Start of the definition of a flags field. * This master flags integer starts at value zero, in preparation * to compile and insert the flag fields from the individual bits */ LocalField = LocalField->Next; *Field = LocalField; FlagBuffer = Buffer; CurrentFlagByteOffset = Info->Offset; break; case DT_FIELD_TYPE_FLAG: /* Individual Flag field, can be multiple bits */ if (FlagBuffer) { /* * We must increment the FlagBuffer when we have crossed * into the next flags byte within the flags field * of type DT_FIELD_TYPE_FLAGS_INTEGER. */ FlagBuffer += (Info->Offset - CurrentFlagByteOffset); CurrentFlagByteOffset = Info->Offset; DtCompileFlag (FlagBuffer, LocalField, Info); } else { /* TBD - this is an internal error */ } LocalField = LocalField->Next; *Field = LocalField; break; case DT_FIELD_TYPE_INLINE_SUBTABLE: /* * Recursion (one level max): compile GAS (Generic Address) * or Notify in-line subtable */ *Field = LocalField; if (Info->Opcode == ACPI_DMT_GAS) { Status = DtCompileTable (Field, AcpiDmTableInfoGas, &InlineSubtable, TRUE); } else { Status = DtCompileTable (Field, AcpiDmTableInfoHestNotify, &InlineSubtable, TRUE); } if (ACPI_FAILURE (Status)) { goto Error; } DtSetSubtableLength (InlineSubtable); ACPI_MEMCPY (Buffer, InlineSubtable->Buffer, FieldLength); LocalField = *Field; break; case DT_FIELD_TYPE_LABEL: DtWriteFieldToListing (Buffer, LocalField, 0); LocalField = LocalField->Next; break; default: /* Normal case for most field types (Integer, String, etc.) */ DtCompileOneField (Buffer, LocalField, FieldLength, FieldType, Info->Flags); DtWriteFieldToListing (Buffer, LocalField, FieldLength); LocalField = LocalField->Next; if (Info->Flags & DT_LENGTH) { /* Field is an Integer that will contain a subtable length */ Subtable->LengthField = Buffer; Subtable->SizeOfLengthField = FieldLength; } break; } Buffer += FieldLength; } *Field = LocalField; *RetSubtable = Subtable; return (AE_OK); Error: ACPI_FREE (Subtable->Buffer); ACPI_FREE (Subtable); return (Status); }