Commit 6e8a3ff6ed ("docs/specs/tpm: reST-ify TPM documentation")
converted docs/specs/tpm.txt to docs/specs/tpm.rst.
We still have several references to the old file, so let's fix them
with the following command:
  sed -i s/tpm.txt/tpm.rst/ $(git grep -l docs/specs/tpm.txt)
Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Message-Id: <20210517151702.109066-5-sgarzare@redhat.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
		
	
			
		
			
				
	
	
		
			460 lines
		
	
	
		
			18 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			460 lines
		
	
	
		
			18 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/* Support for generating ACPI TPM tables
 | 
						|
 *
 | 
						|
 * Copyright (C) 2018 IBM, Corp.
 | 
						|
 * Copyright (C) 2018 Red Hat Inc
 | 
						|
 *
 | 
						|
 * This program is free software; you can redistribute it and/or modify
 | 
						|
 * it under the terms of the GNU General Public License as published by
 | 
						|
 * the Free Software Foundation; either version 2 of the License, or
 | 
						|
 * (at your option) any later version.
 | 
						|
 | 
						|
 * This program is distributed in the hope that it will be useful,
 | 
						|
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
						|
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
						|
 * GNU General Public License for more details.
 | 
						|
 | 
						|
 * You should have received a copy of the GNU General Public License along
 | 
						|
 * with this program; if not, see <http://www.gnu.org/licenses/>.
 | 
						|
 */
 | 
						|
#include "qemu/osdep.h"
 | 
						|
#include "qapi/error.h"
 | 
						|
#include "hw/acpi/tpm.h"
 | 
						|
 | 
						|
void tpm_build_ppi_acpi(TPMIf *tpm, Aml *dev)
 | 
						|
{
 | 
						|
    Aml *method, *field, *ifctx, *ifctx2, *ifctx3, *func_mask,
 | 
						|
        *not_implemented, *pak, *tpm2, *tpm3, *pprm, *pprq, *zero, *one;
 | 
						|
 | 
						|
    if (!object_property_get_bool(OBJECT(tpm), "ppi", &error_abort)) {
 | 
						|
        return;
 | 
						|
    }
 | 
						|
 | 
						|
    zero = aml_int(0);
 | 
						|
    one = aml_int(1);
 | 
						|
    func_mask = aml_int(TPM_PPI_FUNC_MASK);
 | 
						|
    not_implemented = aml_int(TPM_PPI_FUNC_NOT_IMPLEMENTED);
 | 
						|
 | 
						|
    /*
 | 
						|
     * TPP2 is for the registers that ACPI code used to pass
 | 
						|
     * the PPI code and parameter (PPRQ, PPRM) to the firmware.
 | 
						|
     */
 | 
						|
    aml_append(dev,
 | 
						|
               aml_operation_region("TPP2", AML_SYSTEM_MEMORY,
 | 
						|
                                    aml_int(TPM_PPI_ADDR_BASE + 0x100),
 | 
						|
                                    0x5A));
 | 
						|
    field = aml_field("TPP2", AML_ANY_ACC, AML_NOLOCK, AML_PRESERVE);
 | 
						|
    aml_append(field, aml_named_field("PPIN", 8));
 | 
						|
    aml_append(field, aml_named_field("PPIP", 32));
 | 
						|
    aml_append(field, aml_named_field("PPRP", 32));
 | 
						|
    aml_append(field, aml_named_field("PPRQ", 32));
 | 
						|
    aml_append(field, aml_named_field("PPRM", 32));
 | 
						|
    aml_append(field, aml_named_field("LPPR", 32));
 | 
						|
    aml_append(dev, field);
 | 
						|
    pprq = aml_name("PPRQ");
 | 
						|
    pprm = aml_name("PPRM");
 | 
						|
 | 
						|
    aml_append(dev,
 | 
						|
               aml_operation_region(
 | 
						|
                   "TPP3", AML_SYSTEM_MEMORY,
 | 
						|
                   aml_int(TPM_PPI_ADDR_BASE +
 | 
						|
                           0x15a /* movv, docs/specs/tpm.rst */),
 | 
						|
                           0x1));
 | 
						|
    field = aml_field("TPP3", AML_BYTE_ACC, AML_NOLOCK, AML_PRESERVE);
 | 
						|
    aml_append(field, aml_named_field("MOVV", 8));
 | 
						|
    aml_append(dev, field);
 | 
						|
 | 
						|
    /*
 | 
						|
     * DerefOf in Windows is broken with SYSTEM_MEMORY.  Use a dynamic
 | 
						|
     * operation region inside of a method for getting FUNC[op].
 | 
						|
     */
 | 
						|
    method = aml_method("TPFN", 1, AML_SERIALIZED);
 | 
						|
    {
 | 
						|
        Aml *op = aml_arg(0);
 | 
						|
        ifctx = aml_if(aml_lgreater_equal(op, aml_int(0x100)));
 | 
						|
        {
 | 
						|
            aml_append(ifctx, aml_return(zero));
 | 
						|
        }
 | 
						|
        aml_append(method, ifctx);
 | 
						|
 | 
						|
        aml_append(method,
 | 
						|
            aml_operation_region("TPP1", AML_SYSTEM_MEMORY,
 | 
						|
                aml_add(aml_int(TPM_PPI_ADDR_BASE), op, NULL), 0x1));
 | 
						|
        field = aml_field("TPP1", AML_BYTE_ACC, AML_NOLOCK, AML_PRESERVE);
 | 
						|
        aml_append(field, aml_named_field("TPPF", 8));
 | 
						|
        aml_append(method, field);
 | 
						|
        aml_append(method, aml_return(aml_name("TPPF")));
 | 
						|
    }
 | 
						|
    aml_append(dev, method);
 | 
						|
 | 
						|
    /*
 | 
						|
     * Use global TPM2 & TPM3 variables to workaround Windows ACPI bug
 | 
						|
     * when returning packages.
 | 
						|
     */
 | 
						|
    pak = aml_package(2);
 | 
						|
    aml_append(pak, zero);
 | 
						|
    aml_append(pak, zero);
 | 
						|
    aml_append(dev, aml_name_decl("TPM2", pak));
 | 
						|
    tpm2 = aml_name("TPM2");
 | 
						|
 | 
						|
    pak = aml_package(3);
 | 
						|
    aml_append(pak, zero);
 | 
						|
    aml_append(pak, zero);
 | 
						|
    aml_append(pak, zero);
 | 
						|
    aml_append(dev, aml_name_decl("TPM3", pak));
 | 
						|
    tpm3 = aml_name("TPM3");
 | 
						|
 | 
						|
    method = aml_method("_DSM", 4, AML_SERIALIZED);
 | 
						|
    {
 | 
						|
        uint8_t zerobyte[1] = { 0 };
 | 
						|
        Aml *function, *arguments, *rev, *op, *op_arg, *op_flags, *uuid;
 | 
						|
 | 
						|
        uuid = aml_arg(0);
 | 
						|
        rev = aml_arg(1);
 | 
						|
        function = aml_arg(2);
 | 
						|
        arguments = aml_arg(3);
 | 
						|
        op = aml_local(0);
 | 
						|
        op_flags = aml_local(1);
 | 
						|
 | 
						|
        /* Physical Presence Interface */
 | 
						|
        ifctx = aml_if(
 | 
						|
            aml_equal(uuid,
 | 
						|
                      aml_touuid("3DDDFAA6-361B-4EB4-A424-8D10089D1653")));
 | 
						|
        {
 | 
						|
            /* standard DSM query function */
 | 
						|
            ifctx2 = aml_if(aml_equal(function, zero));
 | 
						|
            {
 | 
						|
                uint8_t byte_list[2] = { 0xff, 0x01 }; /* functions 1-8 */
 | 
						|
 | 
						|
                aml_append(ifctx2,
 | 
						|
                           aml_return(aml_buffer(sizeof(byte_list),
 | 
						|
                                                 byte_list)));
 | 
						|
            }
 | 
						|
            aml_append(ifctx, ifctx2);
 | 
						|
 | 
						|
            /*
 | 
						|
             * PPI 1.0: 2.1.1 Get Physical Presence Interface Version
 | 
						|
             *
 | 
						|
             * Arg 2 (Integer): Function Index = 1
 | 
						|
             * Arg 3 (Package): Arguments = Empty Package
 | 
						|
             * Returns: Type: String
 | 
						|
             */
 | 
						|
            ifctx2 = aml_if(aml_equal(function, one));
 | 
						|
            {
 | 
						|
                aml_append(ifctx2, aml_return(aml_string("1.3")));
 | 
						|
            }
 | 
						|
            aml_append(ifctx, ifctx2);
 | 
						|
 | 
						|
            /*
 | 
						|
             * PPI 1.0: 2.1.3 Submit TPM Operation Request to Pre-OS Environment
 | 
						|
             *
 | 
						|
             * Arg 2 (Integer): Function Index = 2
 | 
						|
             * Arg 3 (Package): Arguments = Package: Type: Integer
 | 
						|
             *                              Operation Value of the Request
 | 
						|
             * Returns: Type: Integer
 | 
						|
             *          0: Success
 | 
						|
             *          1: Operation Value of the Request Not Supported
 | 
						|
             *          2: General Failure
 | 
						|
             */
 | 
						|
            ifctx2 = aml_if(aml_equal(function, aml_int(2)));
 | 
						|
            {
 | 
						|
                /* get opcode */
 | 
						|
                aml_append(ifctx2,
 | 
						|
                           aml_store(aml_derefof(aml_index(arguments,
 | 
						|
                                                           zero)), op));
 | 
						|
 | 
						|
                /* get opcode flags */
 | 
						|
                aml_append(ifctx2,
 | 
						|
                           aml_store(aml_call1("TPFN", op), op_flags));
 | 
						|
 | 
						|
                /* if func[opcode] & TPM_PPI_FUNC_NOT_IMPLEMENTED */
 | 
						|
                ifctx3 = aml_if(
 | 
						|
                    aml_equal(
 | 
						|
                        aml_and(op_flags, func_mask, NULL),
 | 
						|
                        not_implemented));
 | 
						|
                {
 | 
						|
                    /* 1: Operation Value of the Request Not Supported */
 | 
						|
                    aml_append(ifctx3, aml_return(one));
 | 
						|
                }
 | 
						|
                aml_append(ifctx2, ifctx3);
 | 
						|
 | 
						|
                aml_append(ifctx2, aml_store(op, pprq));
 | 
						|
                aml_append(ifctx2, aml_store(zero, pprm));
 | 
						|
                /* 0: success */
 | 
						|
                aml_append(ifctx2, aml_return(zero));
 | 
						|
            }
 | 
						|
            aml_append(ifctx, ifctx2);
 | 
						|
 | 
						|
            /*
 | 
						|
             * PPI 1.0: 2.1.4 Get Pending TPM Operation Requested By the OS
 | 
						|
             *
 | 
						|
             * Arg 2 (Integer): Function Index = 3
 | 
						|
             * Arg 3 (Package): Arguments = Empty Package
 | 
						|
             * Returns: Type: Package of Integers
 | 
						|
             *          Integer 1: Function Return code
 | 
						|
             *                     0: Success
 | 
						|
             *                     1: General Failure
 | 
						|
             *          Integer 2: Pending operation requested by the OS
 | 
						|
             *                     0: None
 | 
						|
             *                    >0: Operation Value of the Pending Request
 | 
						|
             *          Integer 3: Optional argument to pending operation
 | 
						|
             *                     requested by the OS
 | 
						|
             *                     0: None
 | 
						|
             *                    >0: Argument Value of the Pending Request
 | 
						|
             */
 | 
						|
            ifctx2 = aml_if(aml_equal(function, aml_int(3)));
 | 
						|
            {
 | 
						|
                /*
 | 
						|
                 * Revision ID of 1, no integer parameter beyond
 | 
						|
                 * parameter two are expected
 | 
						|
                 */
 | 
						|
                ifctx3 = aml_if(aml_equal(rev, one));
 | 
						|
                {
 | 
						|
                    /* TPM2[1] = PPRQ */
 | 
						|
                    aml_append(ifctx3,
 | 
						|
                               aml_store(pprq, aml_index(tpm2, one)));
 | 
						|
                    aml_append(ifctx3, aml_return(tpm2));
 | 
						|
                }
 | 
						|
                aml_append(ifctx2, ifctx3);
 | 
						|
 | 
						|
                /*
 | 
						|
                 * A return value of {0, 23, 1} indicates that
 | 
						|
                 * operation 23 with argument 1 is pending.
 | 
						|
                 */
 | 
						|
                ifctx3 = aml_if(aml_equal(rev, aml_int(2)));
 | 
						|
                {
 | 
						|
                    /* TPM3[1] = PPRQ */
 | 
						|
                    aml_append(ifctx3,
 | 
						|
                               aml_store(pprq, aml_index(tpm3, one)));
 | 
						|
                    /* TPM3[2] = PPRM */
 | 
						|
                    aml_append(ifctx3,
 | 
						|
                               aml_store(pprm, aml_index(tpm3, aml_int(2))));
 | 
						|
                    aml_append(ifctx3, aml_return(tpm3));
 | 
						|
                }
 | 
						|
                aml_append(ifctx2, ifctx3);
 | 
						|
            }
 | 
						|
            aml_append(ifctx, ifctx2);
 | 
						|
 | 
						|
            /*
 | 
						|
             * PPI 1.0: 2.1.5 Get Platform-Specific Action to Transition to
 | 
						|
             *     Pre-OS Environment
 | 
						|
             *
 | 
						|
             * Arg 2 (Integer): Function Index = 4
 | 
						|
             * Arg 3 (Package): Arguments = Empty Package
 | 
						|
             * Returns: Type: Integer
 | 
						|
             *          0: None
 | 
						|
             *          1: Shutdown
 | 
						|
             *          2: Reboot
 | 
						|
             *          3: OS Vendor-specific
 | 
						|
             */
 | 
						|
            ifctx2 = aml_if(aml_equal(function, aml_int(4)));
 | 
						|
            {
 | 
						|
                /* reboot */
 | 
						|
                aml_append(ifctx2, aml_return(aml_int(2)));
 | 
						|
            }
 | 
						|
            aml_append(ifctx, ifctx2);
 | 
						|
 | 
						|
            /*
 | 
						|
             * PPI 1.0: 2.1.6 Return TPM Operation Response to OS Environment
 | 
						|
             *
 | 
						|
             * Arg 2 (Integer): Function Index = 5
 | 
						|
             * Arg 3 (Package): Arguments = Empty Package
 | 
						|
             * Returns: Type: Package of Integer
 | 
						|
             *          Integer 1: Function Return code
 | 
						|
             *                     0: Success
 | 
						|
             *                     1: General Failure
 | 
						|
             *          Integer 2: Most recent operation request
 | 
						|
             *                     0: None
 | 
						|
             *                    >0: Operation Value of the most recent request
 | 
						|
             *          Integer 3: Response to the most recent operation request
 | 
						|
             *                     0: Success
 | 
						|
             *                     0x00000001..0x00000FFF: Corresponding TPM
 | 
						|
             *                                             error code
 | 
						|
             *                     0xFFFFFFF0: User Abort or timeout of dialog
 | 
						|
             *                     0xFFFFFFF1: firmware Failure
 | 
						|
             */
 | 
						|
            ifctx2 = aml_if(aml_equal(function, aml_int(5)));
 | 
						|
            {
 | 
						|
                /* TPM3[1] = LPPR */
 | 
						|
                aml_append(ifctx2,
 | 
						|
                           aml_store(aml_name("LPPR"),
 | 
						|
                                     aml_index(tpm3, one)));
 | 
						|
                /* TPM3[2] = PPRP */
 | 
						|
                aml_append(ifctx2,
 | 
						|
                           aml_store(aml_name("PPRP"),
 | 
						|
                                     aml_index(tpm3, aml_int(2))));
 | 
						|
                aml_append(ifctx2, aml_return(tpm3));
 | 
						|
            }
 | 
						|
            aml_append(ifctx, ifctx2);
 | 
						|
 | 
						|
            /*
 | 
						|
             * PPI 1.0: 2.1.7 Submit preferred user language
 | 
						|
             *
 | 
						|
             * Arg 2 (Integer): Function Index = 6
 | 
						|
             * Arg 3 (Package): Arguments = String Package
 | 
						|
             *                  Preferred language code
 | 
						|
             * Returns: Type: Integer
 | 
						|
             * Function Return Code
 | 
						|
             *          3: Not implemented
 | 
						|
             */
 | 
						|
            ifctx2 = aml_if(aml_equal(function, aml_int(6)));
 | 
						|
            {
 | 
						|
                /* 3 = not implemented */
 | 
						|
                aml_append(ifctx2, aml_return(aml_int(3)));
 | 
						|
            }
 | 
						|
            aml_append(ifctx, ifctx2);
 | 
						|
 | 
						|
            /*
 | 
						|
             * PPI 1.1: 2.1.7 Submit TPM Operation Request to
 | 
						|
             *     Pre-OS Environment 2
 | 
						|
             *
 | 
						|
             * Arg 2 (Integer): Function Index = 7
 | 
						|
             * Arg 3 (Package): Arguments = Package: Type: Integer
 | 
						|
             *                  Integer 1: Operation Value of the Request
 | 
						|
             *                  Integer 2: Argument for Operation (optional)
 | 
						|
             * Returns: Type: Integer
 | 
						|
             *          0: Success
 | 
						|
             *          1: Not Implemented
 | 
						|
             *          2: General Failure
 | 
						|
             *          3: Operation blocked by current firmware settings
 | 
						|
             */
 | 
						|
            ifctx2 = aml_if(aml_equal(function, aml_int(7)));
 | 
						|
            {
 | 
						|
                /* get opcode */
 | 
						|
                aml_append(ifctx2, aml_store(aml_derefof(aml_index(arguments,
 | 
						|
                                                                   zero)),
 | 
						|
                                             op));
 | 
						|
 | 
						|
                /* get opcode flags */
 | 
						|
                aml_append(ifctx2, aml_store(aml_call1("TPFN", op),
 | 
						|
                                             op_flags));
 | 
						|
                /* if func[opcode] & TPM_PPI_FUNC_NOT_IMPLEMENTED */
 | 
						|
                ifctx3 = aml_if(
 | 
						|
                    aml_equal(
 | 
						|
                        aml_and(op_flags, func_mask, NULL),
 | 
						|
                        not_implemented));
 | 
						|
                {
 | 
						|
                    /* 1: not implemented */
 | 
						|
                    aml_append(ifctx3, aml_return(one));
 | 
						|
                }
 | 
						|
                aml_append(ifctx2, ifctx3);
 | 
						|
 | 
						|
                /* if func[opcode] & TPM_PPI_FUNC_BLOCKED */
 | 
						|
                ifctx3 = aml_if(
 | 
						|
                    aml_equal(
 | 
						|
                        aml_and(op_flags, func_mask, NULL),
 | 
						|
                        aml_int(TPM_PPI_FUNC_BLOCKED)));
 | 
						|
                {
 | 
						|
                    /* 3: blocked by firmware */
 | 
						|
                    aml_append(ifctx3, aml_return(aml_int(3)));
 | 
						|
                }
 | 
						|
                aml_append(ifctx2, ifctx3);
 | 
						|
 | 
						|
                /* revision to integer */
 | 
						|
                ifctx3 = aml_if(aml_equal(rev, one));
 | 
						|
                {
 | 
						|
                    /* revision 1 */
 | 
						|
                    /* PPRQ = op */
 | 
						|
                    aml_append(ifctx3, aml_store(op, pprq));
 | 
						|
                    /* no argument, PPRM = 0 */
 | 
						|
                    aml_append(ifctx3, aml_store(zero, pprm));
 | 
						|
                }
 | 
						|
                aml_append(ifctx2, ifctx3);
 | 
						|
 | 
						|
                ifctx3 = aml_if(aml_equal(rev, aml_int(2)));
 | 
						|
                {
 | 
						|
                    /* revision 2 */
 | 
						|
                    /* PPRQ = op */
 | 
						|
                    op_arg = aml_derefof(aml_index(arguments, one));
 | 
						|
                    aml_append(ifctx3, aml_store(op, pprq));
 | 
						|
                    /* PPRM = arg3[1] */
 | 
						|
                    aml_append(ifctx3, aml_store(op_arg, pprm));
 | 
						|
                }
 | 
						|
                aml_append(ifctx2, ifctx3);
 | 
						|
                /* 0: success */
 | 
						|
                aml_append(ifctx2, aml_return(zero));
 | 
						|
            }
 | 
						|
            aml_append(ifctx, ifctx2);
 | 
						|
 | 
						|
            /*
 | 
						|
             * PPI 1.1: 2.1.8 Get User Confirmation Status for Operation
 | 
						|
             *
 | 
						|
             * Arg 2 (Integer): Function Index = 8
 | 
						|
             * Arg 3 (Package): Arguments = Package: Type: Integer
 | 
						|
             *                  Operation Value that may need user confirmation
 | 
						|
             * Returns: Type: Integer
 | 
						|
             *          0: Not implemented
 | 
						|
             *          1: Firmware only
 | 
						|
             *          2: Blocked for OS by firmware configuration
 | 
						|
             *          3: Allowed and physically present user required
 | 
						|
             *          4: Allowed and physically present user not required
 | 
						|
             */
 | 
						|
            ifctx2 = aml_if(aml_equal(function, aml_int(8)));
 | 
						|
            {
 | 
						|
                /* get opcode */
 | 
						|
                aml_append(ifctx2,
 | 
						|
                           aml_store(aml_derefof(aml_index(arguments,
 | 
						|
                                                           zero)),
 | 
						|
                                     op));
 | 
						|
 | 
						|
                /* get opcode flags */
 | 
						|
                aml_append(ifctx2, aml_store(aml_call1("TPFN", op),
 | 
						|
                                             op_flags));
 | 
						|
                /* return confirmation status code */
 | 
						|
                aml_append(ifctx2,
 | 
						|
                           aml_return(
 | 
						|
                               aml_and(op_flags, func_mask, NULL)));
 | 
						|
            }
 | 
						|
            aml_append(ifctx, ifctx2);
 | 
						|
 | 
						|
            aml_append(ifctx, aml_return(aml_buffer(1, zerobyte)));
 | 
						|
        }
 | 
						|
        aml_append(method, ifctx);
 | 
						|
 | 
						|
        /*
 | 
						|
         * "TCG Platform Reset Attack Mitigation Specification 1.00",
 | 
						|
         * Chapter 6 "ACPI _DSM Function"
 | 
						|
         */
 | 
						|
        ifctx = aml_if(
 | 
						|
            aml_equal(uuid,
 | 
						|
                      aml_touuid("376054ED-CC13-4675-901C-4756D7F2D45D")));
 | 
						|
        {
 | 
						|
            /* standard DSM query function */
 | 
						|
            ifctx2 = aml_if(aml_equal(function, zero));
 | 
						|
            {
 | 
						|
                uint8_t byte_list[1] = { 0x03 }; /* functions 1-2 supported */
 | 
						|
 | 
						|
                aml_append(ifctx2,
 | 
						|
                           aml_return(aml_buffer(sizeof(byte_list),
 | 
						|
                                                 byte_list)));
 | 
						|
            }
 | 
						|
            aml_append(ifctx, ifctx2);
 | 
						|
 | 
						|
            /*
 | 
						|
             * TCG Platform Reset Attack Mitigation Specification 1.0 Ch.6
 | 
						|
             *
 | 
						|
             * Arg 2 (Integer): Function Index = 1
 | 
						|
             * Arg 3 (Package): Arguments = Package: Type: Integer
 | 
						|
             *                  Operation Value of the Request
 | 
						|
             * Returns: Type: Integer
 | 
						|
             *          0: Success
 | 
						|
             *          1: General Failure
 | 
						|
             */
 | 
						|
            ifctx2 = aml_if(aml_equal(function, one));
 | 
						|
            {
 | 
						|
                aml_append(ifctx2,
 | 
						|
                           aml_store(aml_derefof(aml_index(arguments, zero)),
 | 
						|
                                     op));
 | 
						|
                {
 | 
						|
                    aml_append(ifctx2, aml_store(op, aml_name("MOVV")));
 | 
						|
 | 
						|
                    /* 0: success */
 | 
						|
                    aml_append(ifctx2, aml_return(zero));
 | 
						|
                }
 | 
						|
            }
 | 
						|
            aml_append(ifctx, ifctx2);
 | 
						|
        }
 | 
						|
        aml_append(method, ifctx);
 | 
						|
    }
 | 
						|
    aml_append(dev, method);
 | 
						|
}
 |