FreeBSD/sys/contrib/dev/acpica/compiler/aslprepkg.c
/*******************************************************************************
 *
 * FUNCTION:    ApCheckPackage
 *
 * PARAMETERS:  ParentOp            - Parser op for the package
 *              Predefined          - Pointer to package-specific info for
 *                                    the method
 *
 * RETURN:      None
 *
 * DESCRIPTION: Top-level validation for predefined name return package
 *              objects.
 *
 ******************************************************************************/
ApCheckPackage
PARAMETERS:  ParentOp            - Parser op for the package
Predefined          - Pointer to package-specific info for
the method

None

Top-level validation for predefined name return package
objects.
ApCheckPackage PARAMETERS : ParentOp - Parser op for the package Predefined - Pointer to package - specific info for the method None Top - level validation for predefined name return package objects .
void
ApCheckPackage (
    ACPI_PARSE_OBJECT           *ParentOp,
    const ACPI_PREDEFINED_INFO  *Predefined)
{
    ACPI_PARSE_OBJECT           *Op;
    const ACPI_PREDEFINED_INFO  *Package;
    ACPI_STATUS                 Status;
    UINT32                      ExpectedCount;
    UINT32                      Count;
    UINT32                      i;
    Package = Predefined + 1;
    Op = ParentOp->Asl.Child;
    Count = (UINT32) Op->Asl.Value.Integer;
    if (!Count)
    {
        switch (Package->RetInfo.Type)
        {
        case ACPI_PTYPE1_FIXED:
        case ACPI_PTYPE1_OPTION:
        case ACPI_PTYPE2_PKG_COUNT:
        case ACPI_PTYPE2_REV_FIXED:
            ApZeroLengthPackage (Predefined->Info.Name, ParentOp);
            break;
        case ACPI_PTYPE1_VAR:
        case ACPI_PTYPE2:
        case ACPI_PTYPE2_COUNT:
        case ACPI_PTYPE2_FIXED:
        case ACPI_PTYPE2_MIN:
        case ACPI_PTYPE2_FIX_VAR:
        case ACPI_PTYPE2_VAR_VAR:
        default:
            break;
        }
        return;
    }
    Op = Op->Asl.Next;
    switch (Package->RetInfo.Type)
    {
    case ACPI_PTYPE_CUSTOM:
        ApCustomPackage (ParentOp, Predefined);
        break;
    case ACPI_PTYPE1_FIXED:
        ExpectedCount = Package->RetInfo.Count1 + Package->RetInfo.Count2;
        if (Count < ExpectedCount)
        {
            goto PackageTooSmall;
        }
        else if (Count > ExpectedCount)
        {
            ApPackageTooLarge (Predefined->Info.Name, ParentOp,
                Count, ExpectedCount);
        }
        ApCheckPackageElements (Predefined->Info.Name, Op,
            Package->RetInfo.ObjectType1, Package->RetInfo.Count1,
            Package->RetInfo.ObjectType2, Package->RetInfo.Count2);
        break;
    case ACPI_PTYPE1_VAR:
        for (i = 0; i < Count; i++)
        {
            ApCheckObjectType (Predefined->Info.Name, Op,
                Package->RetInfo.ObjectType1, i);
            Op = Op->Asl.Next;
        }
        break;
    case ACPI_PTYPE1_OPTION:
        ExpectedCount = Package->RetInfo3.Count;
        if (Count < ExpectedCount)
        {
            goto PackageTooSmall;
        }
        for (i = 0; i < Count; i++)
        {
            if (i < Package->RetInfo3.Count)
            {
                ApCheckObjectType (Predefined->Info.Name, Op,
                    Package->RetInfo3.ObjectType[i], i);
            }
            else
            {
                ApCheckObjectType (Predefined->Info.Name, Op,
                    Package->RetInfo3.TailObjectType, i);
            }
            Op = Op->Asl.Next;
        }
        break;
    case ACPI_PTYPE2_REV_FIXED:
        ApCheckObjectType (Predefined->Info.Name, Op,
            ACPI_RTYPE_INTEGER, 0);
        Op = Op->Asl.Next;
        Count--;
        ApCheckPackageList (Predefined->Info.Name, Op,
            Package, 1, Count);
        break;
    case ACPI_PTYPE2_PKG_COUNT:
        Status = ApCheckObjectType (Predefined->Info.Name, Op,
            ACPI_RTYPE_INTEGER, 0);
        if (ACPI_SUCCESS (Status))
        {
            ExpectedCount = (UINT32) Op->Asl.Value.Integer;
            if (ExpectedCount >= Count)
            {
                goto PackageTooSmall;
            }
            Count = ExpectedCount;
        }
        Op = Op->Asl.Next;
        ApCheckPackageList (Predefined->Info.Name, Op,
            Package, 1, Count);
        break;
    case ACPI_PTYPE2_UUID_PAIR:
        if (Count & 1)
        {
            sprintf (MsgBuffer, "%4.4s: Package length, %d, must be even.",
                Predefined->Info.Name, Count);
            AslError (ASL_ERROR, ASL_MSG_RESERVED_PACKAGE_LENGTH,
                ParentOp->Asl.Child, MsgBuffer);
        }
        for (i = 0; i < Count; ++i)
        {
            if (i & 1)
            {
                ApCheckObjectType (Predefined->Info.Name, Op,
                    Package->RetInfo.ObjectType2, i);
            }
            else
            {
                ApCheckObjectType (Predefined->Info.Name, Op,
                    Package->RetInfo.ObjectType1, i);
            }
            Op = Op->Asl.Next;
        }
        break;
    case ACPI_PTYPE2_VAR_VAR:
        ExpectedCount = Package->RetInfo4.Count1 + 1;
        if (Count < ExpectedCount)
        {
            goto PackageTooSmall;
        }
        for (i = 0; i < Package->RetInfo4.Count1; ++i)
        {
            Status = ApCheckObjectType (Predefined->Info.Name, Op,
                Package->RetInfo4.ObjectType1, i);
            Op = Op->Asl.Next;
        }
        ApCheckPackageList (Predefined->Info.Name, Op,
            Package, Package->RetInfo4.Count1, Count);
        break;
    case ACPI_PTYPE2:
    case ACPI_PTYPE2_FIXED:
    case ACPI_PTYPE2_MIN:
    case ACPI_PTYPE2_COUNT:
    case ACPI_PTYPE2_FIX_VAR:
        ApCheckPackageList (Predefined->Info.Name, Op,
            Package, 0, Count);
        break;
    default:
        return;
    }
    return;
PackageTooSmall:
    ApPackageTooSmall (Predefined->Info.Name, ParentOp,
        Count, ExpectedCount);
}
void ApCheckPackage ( ACPI_PARSE_OBJECT * ParentOp , const ACPI_PREDEFINED_INFO * Predefined ) { ACPI_PARSE_OBJECT * Op ; const ACPI_PREDEFINED_INFO * Package ; ACPI_STATUS Status ; UINT32 ExpectedCount ; UINT32 Count ; UINT32 i ; Package = Predefined + 1 ; Op = ParentOp -> Asl . Child ; Count = ( UINT32 ) Op -> Asl . Value . Integer ; if ( ! Count ) { switch ( Package -> RetInfo . Type ) { case ACPI_PTYPE1_FIXED : case ACPI_PTYPE1_OPTION : case ACPI_PTYPE2_PKG_COUNT : case ACPI_PTYPE2_REV_FIXED : ApZeroLengthPackage ( Predefined -> Info . Name , ParentOp ) ; break ; case ACPI_PTYPE1_VAR : case ACPI_PTYPE2 : case ACPI_PTYPE2_COUNT : case ACPI_PTYPE2_FIXED : case ACPI_PTYPE2_MIN : case ACPI_PTYPE2_FIX_VAR : case ACPI_PTYPE2_VAR_VAR : default : break ; } return ; } Op = Op -> Asl . Next ; switch ( Package -> RetInfo . Type ) { case ACPI_PTYPE_CUSTOM : ApCustomPackage ( ParentOp , Predefined ) ; break ; case ACPI_PTYPE1_FIXED : ExpectedCount = Package -> RetInfo . Count1 + Package -> RetInfo . Count2 ; if ( Count < ExpectedCount ) { goto PackageTooSmall ; } else if ( Count > ExpectedCount ) { ApPackageTooLarge ( Predefined -> Info . Name , ParentOp , Count , ExpectedCount ) ; } ApCheckPackageElements ( Predefined -> Info . Name , Op , Package -> RetInfo . ObjectType1 , Package -> RetInfo . Count1 , Package -> RetInfo . ObjectType2 , Package -> RetInfo . Count2 ) ; break ; case ACPI_PTYPE1_VAR : for ( i = 0 ; i < Count ; i ++ ) { ApCheckObjectType ( Predefined -> Info . Name , Op , Package -> RetInfo . ObjectType1 , i ) ; Op = Op -> Asl . Next ; } break ; case ACPI_PTYPE1_OPTION : ExpectedCount = Package -> RetInfo3 . Count ; if ( Count < ExpectedCount ) { goto PackageTooSmall ; } for ( i = 0 ; i < Count ; i ++ ) { if ( i < Package -> RetInfo3 . Count ) { ApCheckObjectType ( Predefined -> Info . Name , Op , Package -> RetInfo3 . ObjectType [ i ] , i ) ; } else { ApCheckObjectType ( Predefined -> Info . Name , Op , Package -> RetInfo3 . TailObjectType , i ) ; } Op = Op -> Asl . Next ; } break ; case ACPI_PTYPE2_REV_FIXED : ApCheckObjectType ( Predefined -> Info . Name , Op , ACPI_RTYPE_INTEGER , 0 ) ; Op = Op -> Asl . Next ; Count -- ; ApCheckPackageList ( Predefined -> Info . Name , Op , Package , 1 , Count ) ; break ; case ACPI_PTYPE2_PKG_COUNT : Status = ApCheckObjectType ( Predefined -> Info . Name , Op , ACPI_RTYPE_INTEGER , 0 ) ; if ( ACPI_SUCCESS ( Status ) ) { ExpectedCount = ( UINT32 ) Op -> Asl . Value . Integer ; if ( ExpectedCount >= Count ) { goto PackageTooSmall ; } Count = ExpectedCount ; } Op = Op -> Asl . Next ; ApCheckPackageList ( Predefined -> Info . Name , Op , Package , 1 , Count ) ; break ; case ACPI_PTYPE2_UUID_PAIR : if ( Count & 1 ) { sprintf ( MsgBuffer , " " , Predefined -> Info . Name , Count ) ; AslError ( ASL_ERROR , ASL_MSG_RESERVED_PACKAGE_LENGTH , ParentOp -> Asl . Child , MsgBuffer ) ; } for ( i = 0 ; i < Count ; ++ i ) { if ( i & 1 ) { ApCheckObjectType ( Predefined -> Info . Name , Op , Package -> RetInfo . ObjectType2 , i ) ; } else { ApCheckObjectType ( Predefined -> Info . Name , Op , Package -> RetInfo . ObjectType1 , i ) ; } Op = Op -> Asl . Next ; } break ; case ACPI_PTYPE2_VAR_VAR : ExpectedCount = Package -> RetInfo4 . Count1 + 1 ; if ( Count < ExpectedCount ) { goto PackageTooSmall ; } for ( i = 0 ; i < Package -> RetInfo4 . Count1 ; ++ i ) { Status = ApCheckObjectType ( Predefined -> Info . Name , Op , Package -> RetInfo4 . ObjectType1 , i ) ; Op = Op -> Asl . Next ; } ApCheckPackageList ( Predefined -> Info . Name , Op , Package , Package -> RetInfo4 . Count1 , Count ) ; break ; case ACPI_PTYPE2 : case ACPI_PTYPE2_FIXED : case ACPI_PTYPE2_MIN : case ACPI_PTYPE2_COUNT : case ACPI_PTYPE2_FIX_VAR : ApCheckPackageList ( Predefined -> Info . Name , Op , Package , 0 , Count ) ; break ; default : return ; } return ; PackageTooSmall : ApPackageTooSmall ( Predefined -> Info . Name , ParentOp , Count , ExpectedCount ) ; }
FUNCTION:    ApCheckPackage
 PARAMETERS:  ParentOp            - Parser op for the package
              Predefined          - Pointer to package-specific info for
                                    the method
FUNCTION : ApCheckPackage PARAMETERS : ParentOp - Parser op for the package Predefined - Pointer to package - specific info for the method
/* The package info for this name is in the next table entry */ /* First child is the package length */ /*
     * Many of the variable-length top-level packages are allowed to simply
     * have zero elements. This allows the BIOS to tell the host that even
     * though the predefined name/method exists, the feature is not supported.
     * Other package types require one or more elements. In any case, there
     * is no need to continue validation.
     */ /* Get the first element of the package */ /* Decode the package type */ /*
         * The package count is fixed and there are no subpackages
         *
         * If package is too small, exit.
         * If package is larger than expected, issue warning but continue
         */ /* Validate all elements of the package */ /*
         * The package count is variable, there are no subpackages,
         * and all elements must be of the same type
         */ /*
         * The package count is variable, there are no subpackages.
         * There are a fixed number of required elements, and a variable
         * number of optional elements.
         *
         * Check if package is at least as large as the minimum required
         */ /* Variable number of sub-objects */ /* These are the required package elements (0, 1, or 2) */ /* These are the optional package elements */ /* First element is the (Integer) revision */ /* Examine the subpackages */ /* First element is the (Integer) count of subpackages to follow */ /* We must have an integer count from above (otherwise, use Count) */ /*
             * Count cannot be larger than the parent package length, but
             * allow it to be smaller. The >= accounts for the Integer above.
             */ /* Examine the subpackages */ /* The package contains a variable list of UUID Buffer/Package pairs */ /* The length of the package must be even */ /* Validate the alternating types */ /* Check for minimum size (ints at beginning + 1 subpackage) */ /* Check the non-package elements at beginning of main package */ /* Examine the variable-length list of subpackages */ /*
         * These types all return a single Package that consists of a
         * variable number of subpackages.
         */ /* Examine the subpackages */