1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376
|
/** @file
AML grammar definitions.
Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved. <BR>
Copyright (c) 2019 - 2021, Arm Limited. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#ifndef AML_H_
#define AML_H_
#include <AmlDefines.h>
#include <AmlInclude.h>
#include <IndustryStandard/AcpiAml.h>
#if !defined (MDEPKG_NDEBUG)
#define AML_OPCODE_DEF(str, OpCode) str, OpCode
#else
#define AML_OPCODE_DEF(str, OpCode) OpCode
#endif // MDEPKG_NDEBUG
/** AML types.
In the AML bytestream, data is represented using one of the following types.
These types are used in the parsing logic to know what kind of data is
expected next in the bytestream. This allows to parse data according
to the AML_PARSE_FORMAT type.
E.g.: A string will not be parsed in the same way as a UINT8.
These are internal types.
*/
typedef enum EAmlParseFormat {
EAmlNone = 0, ///< No data expected.
EAmlUInt8, ///< One byte value evaluated as a UINT8.
EAmlUInt16, ///< Two byte value evaluated as a UINT16.
EAmlUInt32, ///< Four byte value evaluated as a UINT32.
EAmlUInt64, ///< Eight byte value evaluated as a UINT64.
EAmlObject, ///< AML object, starting with an OpCode/SubOpCode
/// couple, potentially followed by package length.
/// EAmlName is a subtype of an EAmlObject.
/// Indeed, an EAmlName can also be evaluated as
/// an EAmlObject in the parsing.
EAmlName, ///< Name corresponding to the NameString keyword
/// in the ACPI specification. E.g.: "\_SB_.DEV0"
EAmlString, ///< NULL terminated string.
EAmlFieldPkgLen, ///< A field package length (PkgLen). A data node of this
/// type can only be found in a field list, in a
/// NamedField statement. The PkgLen is otherwise
/// part of the object node structure.
EAmlParseFormatMax ///< Max enum.
} AML_PARSE_FORMAT;
/** AML attributes
To add some more information to the byte encoding, it is possible to add
these attributes.
*/
typedef UINT32 AML_OP_ATTRIBUTE;
/** A PkgLength is expected between the OpCode/SubOpCode couple and the first
fixed argument of the object.
*/
#define AML_HAS_PKG_LENGTH 0x00001U
/** The object's OpCode is actually a character. Encodings with this attribute
don't describe objects. The dual/multi name prefix have this attribute,
indicating the start of a longer NameString.
*/
#define AML_IS_NAME_CHAR 0x00002U
/** A variable list of arguments is following the last fixed argument. Each
argument is evaluated as an EAmlObject.
*/
#define AML_HAS_CHILD_OBJ 0x00004U
/** This is a sub-type of a variable list of arguments. It can only be
found in buffer objects. A ByteList is either a list of
bytes or a list of resource data elements. Resource data elements
have specific opcodes.
*/
#define AML_HAS_BYTE_LIST 0x00008U
/** This is a sub-type of a variable list of arguments. It can only be
found in Fields, IndexFields and BankFields.
A FieldList is made of FieldElements. FieldElements have specific opcodes.
*/
#define AML_HAS_FIELD_LIST 0x00010U
/** This object node is a field element. Its opcode is to be fetched from
the field encoding table.
*/
#define AML_IS_FIELD_ELEMENT 0x00020U
/** The object has a name and which is part of the AML namespace. The name
can be found in the fixed argument list at the NameIndex.
*/
#define AML_IN_NAMESPACE 0x10000U
/** Some OpCodes have been created in this library. They are called
pseudo opcodes and must stay internal to this library.
*/
#define AML_IS_PSEUDO_OPCODE 0x20000U
/** Encoding of an AML object.
Every AML object has a specific encoding. This encoding information
is used to parse AML objects. A table of AML_BYTE_ENCODING entries
allows to parse an AML bytestream.
This structure is also used to describe field objects.
Cf. ACPI 6.3 specification, s20.2.
*/
typedef struct _AML_BYTE_ENCODING {
// Enable this field for debug.
#if !defined (MDEPKG_NDEBUG)
/// String field allowing to print the AML object.
CONST CHAR8 *Str;
#endif // MDEPKG_NDEBUG
/// OpCode of the AML object.
UINT8 OpCode;
/// SubOpCode of the AML object.
/// The SubOpcode field has a valid value when the OpCode is 0x5B,
/// otherwise this field must be zero.
/// For field objects, the SubOpCode is not used.
UINT8 SubOpCode;
/// Number of fixed arguments for the AML statement represented
/// by the OpCode & SubOpcode.
/// Maximum is 6 for AML objects.
/// Maximum is 3 for field objects.
EAML_PARSE_INDEX MaxIndex;
/// If the encoding has the AML_IN_NAMESPACE attribute (cf Attribute
/// field below), indicate where to find the name in the fixed list
/// of arguments.
EAML_PARSE_INDEX NameIndex;
/// Type of each fixed argument.
AML_PARSE_FORMAT Format[EAmlParseIndexMax];
/// Additional information on the AML object.
AML_OP_ATTRIBUTE Attribute;
} AML_BYTE_ENCODING;
/** Get the AML_BYTE_ENCODING entry in the AML encoding table.
Note: For Pseudo OpCodes this function returns NULL.
@param [in] Buffer Pointer to an OpCode/SubOpCode couple.
If *Buffer = 0x5b (extended OpCode),
Buffer must be at least two bytes long.
@return The corresponding AML_BYTE_ENCODING entry.
NULL if not found.
**/
CONST
AML_BYTE_ENCODING *
EFIAPI
AmlGetByteEncoding (
IN CONST UINT8 *Buffer
);
/** Get the AML_BYTE_ENCODING entry in the AML encoding table
by providing an OpCode/SubOpCode couple.
@param [in] OpCode OpCode.
@param [in] SubOpCode SubOpCode.
@return The corresponding AML_BYTE_ENCODING entry.
NULL if not found.
**/
CONST
AML_BYTE_ENCODING *
EFIAPI
AmlGetByteEncodingByOpCode (
IN UINT8 OpCode,
IN UINT8 SubOpCode
);
/** Get the AML_BYTE_ENCODING entry in the field encoding table.
Note: For Pseudo OpCodes this function returns NULL.
@param [in] Buffer Pointer to a field OpCode.
No SubOpCode is expected.
@return The corresponding AML_BYTE_ENCODING entry
in the field encoding table.
NULL if not found.
**/
CONST
AML_BYTE_ENCODING *
EFIAPI
AmlGetFieldEncoding (
IN CONST UINT8 *Buffer
);
/** Get the AML_BYTE_ENCODING entry in the field encoding table
by providing an OpCode/SubOpCode couple.
@param [in] OpCode OpCode.
@param [in] SubOpCode SubOpCode.
@return The corresponding AML_BYTE_ENCODING entry
in the field encoding table.
NULL if not found.
**/
CONST
AML_BYTE_ENCODING *
EFIAPI
AmlGetFieldEncodingByOpCode (
IN UINT8 OpCode,
IN UINT8 SubOpCode
);
// Enable this function for debug.
#if !defined (MDEPKG_NDEBUG)
/** Look for an OpCode/SubOpCode couple in the AML grammar,
and return a corresponding string.
@param [in] OpCode The OpCode.
@param [in] SubOpCode The SubOpCode.
@return A string describing the OpCode/SubOpCode couple.
NULL if not found.
**/
CONST
CHAR8 *
AmlGetOpCodeStr (
IN UINT8 OpCode,
IN UINT8 SubOpCode
);
/** Look for an OpCode/SubOpCode couple in the AML field element grammar,
and return a corresponding string.
@param [in] OpCode The OpCode.
@param [in] SubOpCode The SubOpCode. Must be zero.
@return A string describing the OpCode/SubOpCode couple.
NULL if not found.
**/
CONST
CHAR8 *
AmlGetFieldOpCodeStr (
IN UINT8 OpCode,
IN UINT8 SubOpCode
);
#endif // MDEPKG_NDEBUG
/** Check whether the OpCode/SubOpcode couple is a valid entry
in the AML grammar encoding table.
@param [in] OpCode OpCode to check.
@param [in] SubOpCode SubOpCode to check.
@retval TRUE The OpCode/SubOpCode couple is valid.
@retval FALSE Otherwise.
**/
BOOLEAN
EFIAPI
AmlIsOpCodeValid (
IN UINT8 OpCode,
IN UINT8 SubOpCode
);
/** Convert an AML_PARSE_FORMAT to its corresponding EAML_NODE_DATA_TYPE.
@param [in] AmlType Input AML Type.
@return The corresponding EAML_NODE_DATA_TYPE.
EAmlNodeDataTypeNone if not found.
**/
EAML_NODE_DATA_TYPE
EFIAPI
AmlTypeToNodeDataType (
IN AML_PARSE_FORMAT AmlType
);
/** Get the package length from the buffer.
@param [in] Buffer AML buffer.
@param [out] PkgLength The interpreted PkgLen value.
Length cannot exceed 2^28.
@return The number of bytes to represent the package length.
0 if an issue occurred.
**/
UINT32
EFIAPI
AmlGetPkgLength (
IN CONST UINT8 *Buffer,
OUT UINT32 *PkgLength
);
/** Convert the Length to the AML PkgLen encoding,
then and write it in the Buffer.
@param [in] Length Length to convert.
Length cannot exceed 2^28.
@param [out] Buffer Write the result in this Buffer.
@return The number of bytes used to write the Length.
**/
UINT8
EFIAPI
AmlSetPkgLength (
IN UINT32 Length,
OUT UINT8 *Buffer
);
/** Compute the number of bytes required to write a package length.
@param [in] Length The length to convert in the AML package length
encoding style.
Length cannot exceed 2^28.
@return The number of bytes required to write the Length.
**/
UINT8
EFIAPI
AmlComputePkgLengthWidth (
IN UINT32 Length
);
/** Given a length, compute the value of a PkgLen.
In AML, some object have a PkgLen, telling the size of the AML object.
It can be encoded in 1 to 4 bytes. The bytes used to encode the PkgLen is
itself counted in the PkgLen value.
This means that if an AML object sees its size increment/decrement,
the number of bytes used to encode the PkgLen value can itself
increment/decrement.
For instance, the AML encoding of a DeviceOp is:
DefDevice := DeviceOp PkgLength NameString TermList
If:
- sizeof (NameString) = 4 (the name is "DEV0" for instance);
- sizeof (TermList) = (2^6-6)
then the PkgLen is encoded on 1 byte. Indeed, its value is:
sizeof (PkgLen) + sizeof (NameString) + sizeof (TermList) =
sizeof (PkgLen) + 4 + (2^6-6)
So:
PkgLen = sizeof (PkgLen) + (2^6-2)
The input arguments Length and PkgLen represent, for the DefDevice:
DefDevice := DeviceOp PkgLength NameString TermList
|------Length-----|
|--------*PgkLength---------|
@param [in] Length The length to encode as a PkgLen.
Length cannot exceed 2^28 - 4 (4 bytes for the
PkgLen encoding).
The size of the PkgLen encoding bytes should not be
counted in this length value.
@param [out] PkgLen If success, contains the value of the PkgLen,
ready to encode in the PkgLen format.
This value takes into account the size of PkgLen
encoding.
@retval EFI_SUCCESS The function completed successfully.
@retval EFI_INVALID_PARAMETER Invalid parameter.
**/
EFI_STATUS
EFIAPI
AmlComputePkgLength (
IN UINT32 Length,
OUT UINT32 *PkgLen
);
#endif // AML_H_
|