Пример #1
0
ACPI_STATUS
AcpiExConcatTemplate (
    ACPI_OPERAND_OBJECT     *ObjDesc1,
    ACPI_OPERAND_OBJECT     *ObjDesc2,
    ACPI_OPERAND_OBJECT     **ActualReturnDesc,
    ACPI_WALK_STATE         *WalkState)
{
    ACPI_OPERAND_OBJECT     *ReturnDesc;
    UINT8                   *NewBuf;
    UINT8                   *EndTag1;
    UINT8                   *EndTag2;
    ACPI_SIZE               Length1;
    ACPI_SIZE               Length2;


    ACPI_FUNCTION_TRACE ("ExConcatTemplate");


    /* Find the EndTags in each resource template */

    EndTag1 = AcpiUtGetResourceEndTag (ObjDesc1);
    EndTag2 = AcpiUtGetResourceEndTag (ObjDesc2);
    if (!EndTag1 || !EndTag2)
    {
        return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
    }

    /* Compute the length of each part */

    Length1 = ACPI_PTR_DIFF (EndTag1, ObjDesc1->Buffer.Pointer);
    Length2 = ACPI_PTR_DIFF (EndTag2, ObjDesc2->Buffer.Pointer) +
                             2; /* Size of END_TAG */

    /* Create a new buffer object for the result */

    ReturnDesc = AcpiUtCreateBufferObject (Length1 + Length2);
    if (!ReturnDesc)
    {
        return_ACPI_STATUS (AE_NO_MEMORY);
    }

    /* Copy the templates to the new descriptor */

    NewBuf = ReturnDesc->Buffer.Pointer;
    ACPI_MEMCPY (NewBuf, ObjDesc1->Buffer.Pointer, Length1);
    ACPI_MEMCPY (NewBuf + Length1, ObjDesc2->Buffer.Pointer, Length2);

    /* Compute the new checksum */

    NewBuf[ReturnDesc->Buffer.Length - 1] =
            AcpiUtGenerateChecksum (ReturnDesc->Buffer.Pointer,
                                   (ReturnDesc->Buffer.Length - 1));

    /* Return the completed template descriptor */

    *ActualReturnDesc = ReturnDesc;
    return_ACPI_STATUS (AE_OK);
}
Пример #2
0
acpi_status
acpi_ex_concat_template (
	union acpi_operand_object       *obj_desc1,
	union acpi_operand_object       *obj_desc2,
	union acpi_operand_object       **actual_return_desc,
	struct acpi_walk_state          *walk_state)
{
	union acpi_operand_object       *return_desc;
	u8                              *new_buf;
	u8                              *end_tag1;
	u8                              *end_tag2;
	acpi_size                       length1;
	acpi_size                       length2;


	ACPI_FUNCTION_TRACE ("ex_concat_template");


	/* Find the end_tags in each resource template */

	end_tag1 = acpi_ut_get_resource_end_tag (obj_desc1);
	end_tag2 = acpi_ut_get_resource_end_tag (obj_desc2);
	if (!end_tag1 || !end_tag2) {
		return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
	}

	/* Compute the length of each part */

	length1 = ACPI_PTR_DIFF (end_tag1, obj_desc1->buffer.pointer);
	length2 = ACPI_PTR_DIFF (end_tag2, obj_desc2->buffer.pointer) +
			  2; /* Size of END_TAG */

	/* Create a new buffer object for the result */

	return_desc = acpi_ut_create_buffer_object (length1 + length2);
	if (!return_desc) {
		return_ACPI_STATUS (AE_NO_MEMORY);
	}

	/* Copy the templates to the new descriptor */

	new_buf = return_desc->buffer.pointer;
	ACPI_MEMCPY (new_buf, obj_desc1->buffer.pointer, length1);
	ACPI_MEMCPY (new_buf + length1, obj_desc2->buffer.pointer, length2);

	/* Compute the new checksum */

	new_buf[return_desc->buffer.length - 1] =
			acpi_ut_generate_checksum (return_desc->buffer.pointer,
					   (return_desc->buffer.length - 1));

	/* Return the completed template descriptor */

	*actual_return_desc = return_desc;
	return_ACPI_STATUS (AE_OK);
}
Пример #3
0
/**
 * acpi_pptt_leaf_node() - Given a processor node, determine if its a leaf
 * @table_hdr: Pointer to the head of the PPTT table
 * @node: passed node is checked to see if its a leaf
 *
 * Determine if the *node parameter is a leaf node by iterating the
 * PPTT table, looking for nodes which reference it.
 *
 * Return: 0 if we find a node referencing the passed node (or table error),
 * or 1 if we don't.
 */
static int acpi_pptt_leaf_node(struct acpi_table_header *table_hdr,
			       struct acpi_pptt_processor *node)
{
	struct acpi_subtable_header *entry;
	unsigned long table_end;
	u32 node_entry;
	struct acpi_pptt_processor *cpu_node;
	u32 proc_sz;

	if (table_hdr->revision > 1)
		return (node->flags & ACPI_PPTT_ACPI_LEAF_NODE);

	table_end = (unsigned long)table_hdr + table_hdr->length;
	node_entry = ACPI_PTR_DIFF(node, table_hdr);
	entry = ACPI_ADD_PTR(struct acpi_subtable_header, table_hdr,
			     sizeof(struct acpi_table_pptt));
	proc_sz = sizeof(struct acpi_pptt_processor *);

	while ((unsigned long)entry + proc_sz < table_end) {
		cpu_node = (struct acpi_pptt_processor *)entry;
		if (entry->type == ACPI_PPTT_TYPE_PROCESSOR &&
		    cpu_node->parent == node_entry)
			return 0;
		if (entry->length == 0)
			return 0;
		entry = ACPI_ADD_PTR(struct acpi_subtable_header, entry,
				     entry->length);

	}
	return 1;
}
Пример #4
0
/**
 * topology_get_acpi_cpu_tag() - Find a unique topology value for a feature
 * @table: Pointer to the head of the PPTT table
 * @cpu: Kernel logical CPU number
 * @level: A level that terminates the search
 * @flag: A flag which terminates the search
 *
 * Get a unique value given a CPU, and a topology level, that can be
 * matched to determine which cpus share common topological features
 * at that level.
 *
 * Return: Unique value, or -ENOENT if unable to locate CPU
 */
static int topology_get_acpi_cpu_tag(struct acpi_table_header *table,
				     unsigned int cpu, int level, int flag)
{
	struct acpi_pptt_processor *cpu_node;
	u32 acpi_cpu_id = get_acpi_id_for_cpu(cpu);

	cpu_node = acpi_find_processor_node(table, acpi_cpu_id);
	if (cpu_node) {
		cpu_node = acpi_find_processor_package_id(table, cpu_node,
							  level, flag);
		/*
		 * As per specification if the processor structure represents
		 * an actual processor, then ACPI processor ID must be valid.
		 * For processor containers ACPI_PPTT_ACPI_PROCESSOR_ID_VALID
		 * should be set if the UID is valid
		 */
		if (level == 0 ||
		    cpu_node->flags & ACPI_PPTT_ACPI_PROCESSOR_ID_VALID)
			return cpu_node->acpi_processor_id;
		return ACPI_PTR_DIFF(cpu_node, table);
	}
	pr_warn_once("PPTT table found, but unable to locate core %d (%d)\n",
		    cpu, acpi_cpu_id);
	return -ENOENT;
}
Пример #5
0
void
AcpiDbSetMethodBreakpoint (
    char                    *Location,
    ACPI_WALK_STATE         *WalkState,
    ACPI_PARSE_OBJECT       *Op)
{
    UINT32                  Address;
    UINT32                  AmlOffset;


    if (!Op)
    {
        AcpiOsPrintf ("There is no method currently executing\n");
        return;
    }

    /* Get and verify the breakpoint address */

    Address = strtoul (Location, NULL, 16);
    AmlOffset = (UINT32) ACPI_PTR_DIFF (Op->Common.Aml,
                    WalkState->ParserState.AmlStart);
    if (Address <= AmlOffset)
    {
        AcpiOsPrintf ("Breakpoint %X is beyond current address %X\n",
            Address, AmlOffset);
    }

    /* Save breakpoint in current walk */

    WalkState->UserBreakpoint = Address;
    AcpiOsPrintf ("Breakpoint set at AML offset %X\n", Address);
}
Пример #6
0
/**
 * find_acpi_cpu_cache_topology() - Determine a unique cache topology value
 * @cpu: Kernel logical CPU number
 * @level: The cache level for which we would like a unique ID
 *
 * Determine a unique ID for each unified cache in the system
 *
 * Return: -ENOENT if the PPTT doesn't exist, or the CPU cannot be found.
 * Otherwise returns a value which represents a unique topological feature.
 */
int find_acpi_cpu_cache_topology(unsigned int cpu, int level)
{
	struct acpi_table_header *table;
	struct acpi_pptt_cache *found_cache;
	acpi_status status;
	u32 acpi_cpu_id = get_acpi_id_for_cpu(cpu);
	struct acpi_pptt_processor *cpu_node = NULL;
	int ret = -1;

	status = acpi_get_table(ACPI_SIG_PPTT, 0, &table);
	if (ACPI_FAILURE(status)) {
		acpi_pptt_warn_missing();
		return -ENOENT;
	}

	found_cache = acpi_find_cache_node(table, acpi_cpu_id,
					   CACHE_TYPE_UNIFIED,
					   level,
					   &cpu_node);
	if (found_cache)
		ret = ACPI_PTR_DIFF(cpu_node, table);

	acpi_put_table(table);

	return ret;
}
Пример #7
0
ACPI_STATUS
AcpiRsVendorStream (
    ACPI_RESOURCE           *LinkedList,
    UINT8                   **OutputBuffer,
    ACPI_SIZE               *BytesConsumed)
{
    UINT8                   *Buffer = *OutputBuffer;
    UINT16                  Temp16 = 0;
    UINT8                   Temp8 = 0;
    UINT8                   Index;


    ACPI_FUNCTION_TRACE ("RsVendorStream");


    /*
     * Dereference the length to find if this is a large or small item.
     */
    if(LinkedList->Data.VendorSpecific.Length > 7)
    {
        /*
         * Large Item, Set the descriptor field and length bytes
         */
        *Buffer = 0x84;
        Buffer += 1;

        Temp16 = (UINT16) LinkedList->Data.VendorSpecific.Length;

        ACPI_MOVE_UNALIGNED16_TO_16 (Buffer, &Temp16);
        Buffer += 2;
    }
    else
    {
        /*
         * Small Item, Set the descriptor field
         */
        Temp8 = 0x70;
        Temp8 |= (UINT8) LinkedList->Data.VendorSpecific.Length;

        *Buffer = Temp8;
        Buffer += 1;
    }

    /*
     * Loop through all of the Vendor Specific fields
     */
    for (Index = 0; Index < LinkedList->Data.VendorSpecific.Length; Index++)
    {
        Temp8 = LinkedList->Data.VendorSpecific.Reserved[Index];

        *Buffer = Temp8;
        Buffer += 1;
    }

    /*
     * Return the number of bytes consumed in this operation
     */
    *BytesConsumed = ACPI_PTR_DIFF (Buffer, *OutputBuffer);
    return_ACPI_STATUS (AE_OK);
}
Пример #8
0
ACPI_STATUS
AcpiRsEndTagStream (
    ACPI_RESOURCE           *LinkedList,
    UINT8                   **OutputBuffer,
    ACPI_SIZE               *BytesConsumed)
{
    UINT8                   *Buffer = *OutputBuffer;
    UINT8                   Temp8 = 0;


    ACPI_FUNCTION_TRACE ("RsEndTagStream");


    /*
     * The descriptor field is static
     */
    *Buffer = 0x79;
    Buffer += 1;

    /*
     * Set the Checksum - zero means that the resource data is treated as if
     * the checksum operation succeeded (ACPI Spec 1.0b Section 6.4.2.8)
     */
    Temp8 = 0;

    *Buffer = Temp8;
    Buffer += 1;

    /*
     * Return the number of bytes consumed in this operation
     */
    *BytesConsumed = ACPI_PTR_DIFF (Buffer, *OutputBuffer);
    return_ACPI_STATUS (AE_OK);
}
Пример #9
0
static ACPI_STATUS
AcpiPsGetAmlOpcode (
    ACPI_WALK_STATE         *WalkState)
{

    ACPI_FUNCTION_TRACE_PTR (PsGetAmlOpcode, WalkState);


    WalkState->AmlOffset = (UINT32) ACPI_PTR_DIFF (WalkState->ParserState.Aml,
                                WalkState->ParserState.AmlStart);
    WalkState->Opcode = AcpiPsPeekOpcode (&(WalkState->ParserState));

    /*
     * First cut to determine what we have found:
     * 1) A valid AML opcode
     * 2) A name string
     * 3) An unknown/invalid opcode
     */
    WalkState->OpInfo = AcpiPsGetOpcodeInfo (WalkState->Opcode);

    switch (WalkState->OpInfo->Class)
    {
    case AML_CLASS_ASCII:
    case AML_CLASS_PREFIX:
        /*
         * Starts with a valid prefix or ASCII char, this is a name
         * string. Convert the bare name string to a namepath.
         */
        WalkState->Opcode = AML_INT_NAMEPATH_OP;
        WalkState->ArgTypes = ARGP_NAMESTRING;
        break;

    case AML_CLASS_UNKNOWN:

        /* The opcode is unrecognized. Just skip unknown opcodes */

        ACPI_ERROR ((AE_INFO,
             "Found unknown opcode 0x%X at AML address %p offset 0x%X, ignoring",
              WalkState->Opcode, WalkState->ParserState.Aml, WalkState->AmlOffset));

        ACPI_DUMP_BUFFER (WalkState->ParserState.Aml, 128);

        /* Assume one-byte bad opcode */

        WalkState->ParserState.Aml++;
        return_ACPI_STATUS (AE_CTRL_PARSE_CONTINUE);

    default:

        /* Found opcode info, this is a normal opcode */

        WalkState->ParserState.Aml += AcpiPsGetOpcodeSize (WalkState->Opcode);
        WalkState->ArgTypes = WalkState->OpInfo->ParseArgs;
        break;
    }

    return_ACPI_STATUS (AE_OK);
}
Пример #10
0
void
AcpiUtInitStackPtrTrace (
    void)
{
    UINT32                  CurrentSp;


    AcpiGbl_EntryStackPointer = ACPI_PTR_DIFF (&CurrentSp, NULL);
}
Пример #11
0
void
acpi_ut_init_stack_ptr_trace (
	void)
{
	u32                         current_sp;


	acpi_gbl_entry_stack_pointer = ACPI_PTR_DIFF (&current_sp, NULL);
}
Пример #12
0
ACPI_STATUS
AcpiDsMethodError (
    ACPI_STATUS             Status,
    ACPI_WALK_STATE         *WalkState)
{
    UINT32                  AmlOffset;


    ACPI_FUNCTION_ENTRY ();


    /* Ignore AE_OK and control exception codes */

    if (ACPI_SUCCESS (Status) ||
        (Status & AE_CODE_CONTROL))
    {
        return (Status);
    }

    /* Invoke the global exception handler */

    if (AcpiGbl_ExceptionHandler)
    {
        /* Exit the interpreter, allow handler to execute methods */

        AcpiExExitInterpreter ();

        /*
         * Handler can map the exception code to anything it wants, including
         * AE_OK, in which case the executing method will not be aborted.
         */
        AmlOffset = (UINT32) ACPI_PTR_DIFF (WalkState->Aml,
            WalkState->ParserState.AmlStart);

        Status = AcpiGbl_ExceptionHandler (Status,
            WalkState->MethodNode ?
                WalkState->MethodNode->Name.Integer : 0,
            WalkState->Opcode, AmlOffset, NULL);
        AcpiExEnterInterpreter ();
    }

    AcpiDsClearImplicitReturn (WalkState);

    if (ACPI_FAILURE (Status))
    {
        AcpiDsDumpMethodStack (Status, WalkState, WalkState->Op);

        /* Display method locals/args if debugger is present */

#ifdef ACPI_DEBUGGER
        AcpiDbDumpMethodInfo (Status, WalkState);
#endif
    }

    return (Status);
}
Пример #13
0
acpi_status
acpi_ds_method_error(acpi_status status, struct acpi_walk_state *walk_state)
{
	u32 aml_offset;
	acpi_name name = 0;

	ACPI_FUNCTION_ENTRY();

	/* Ignore AE_OK and control exception codes */

	if (ACPI_SUCCESS(status) || (status & AE_CODE_CONTROL)) {
		return (status);
	}

	/* Invoke the global exception handler */

	if (acpi_gbl_exception_handler) {

		/* Exit the interpreter, allow handler to execute methods */

		acpi_ex_exit_interpreter();

		/*
		 * Handler can map the exception code to anything it wants, including
		 * AE_OK, in which case the executing method will not be aborted.
		 */
		aml_offset = (u32)ACPI_PTR_DIFF(walk_state->aml,
						walk_state->parser_state.
						aml_start);

		if (walk_state->method_node) {
			name = walk_state->method_node->name.integer;
		} else if (walk_state->deferred_node) {
			name = walk_state->deferred_node->name.integer;
		}

		status = acpi_gbl_exception_handler(status, name,
						    walk_state->opcode,
						    aml_offset, NULL);
		acpi_ex_enter_interpreter();
	}

	acpi_ds_clear_implicit_return(walk_state);

	if (ACPI_FAILURE(status)) {
		acpi_ds_dump_method_stack(status, walk_state, walk_state->op);

		/* Display method locals/args if debugger is present */

#ifdef ACPI_DEBUGGER
		acpi_db_dump_method_info(status, walk_state);
#endif
	}

	return (status);
}
Пример #14
0
acpi_status
acpi_rs_fixed_memory32_stream (
	struct acpi_resource            *linked_list,
	u8                              **output_buffer,
	acpi_size                       *bytes_consumed)
{
	u8                              *buffer = *output_buffer;
	u16                             temp16 = 0;
	u8                              temp8 = 0;


	ACPI_FUNCTION_TRACE ("rs_fixed_memory32_stream");


	/*
	 * The descriptor field is static
	 */
	*buffer = 0x86;
	buffer += 1;

	/*
	 * The length field is static
	 */
	temp16 = 0x09;

	ACPI_MOVE_16_TO_16 (buffer, &temp16);
	buffer += 2;

	/*
	 * Set the Information Byte
	 */
	temp8 = (u8) (linked_list->data.fixed_memory32.read_write_attribute & 0x01);
	*buffer = temp8;
	buffer += 1;

	/*
	 * Set the Range base address
	 */
	ACPI_MOVE_32_TO_32 (buffer,
			 &linked_list->data.fixed_memory32.range_base_address);
	buffer += 4;

	/*
	 * Set the range length
	 */
	ACPI_MOVE_32_TO_32 (buffer,
			 &linked_list->data.fixed_memory32.range_length);
	buffer += 4;

	/*
	 * Return the number of bytes consumed in this operation
	 */
	*bytes_consumed = ACPI_PTR_DIFF (buffer, *output_buffer);
	return_ACPI_STATUS (AE_OK);
}
Пример #15
0
void acpi_ut_track_stack_ptr(void)
{
    acpi_size current_sp;

    current_sp = ACPI_PTR_DIFF(&current_sp, NULL);

    if (current_sp < acpi_gbl_lowest_stack_pointer) {
        acpi_gbl_lowest_stack_pointer = current_sp;
    }

    if (acpi_gbl_nesting_level > acpi_gbl_deepest_nesting) {
        acpi_gbl_deepest_nesting = acpi_gbl_nesting_level;
    }
}
Пример #16
0
void
AcpiUtTrackStackPtr (
    void)
{
    ACPI_SIZE               CurrentSp;


    CurrentSp = ACPI_PTR_DIFF (&CurrentSp, NULL);

    if (CurrentSp < AcpiGbl_LowestStackPointer)
    {
        AcpiGbl_LowestStackPointer = CurrentSp;
    }

    if (AcpiGbl_NestingLevel > AcpiGbl_DeepestNesting)
    {
        AcpiGbl_DeepestNesting = AcpiGbl_NestingLevel;
    }
}
Пример #17
0
static char *
AcpiUtFormatNumber (
    char                    *String,
    char                    *End,
    UINT64                  Number,
    UINT8                   Base,
    INT32                   Width,
    INT32                   Precision,
    UINT8                   Type)
{
    char                    *Pos;
    char                    Sign;
    char                    Zero;
    BOOLEAN                 NeedPrefix;
    BOOLEAN                 Upper;
    INT32                   i;
    char                    ReversedString[66];


    /* Parameter validation */

    if (Base < 2 || Base > 16)
    {
        return (NULL);
    }

    if (Type & ACPI_FORMAT_LEFT)
    {
        Type &= ~ACPI_FORMAT_ZERO;
    }

    NeedPrefix = ((Type & ACPI_FORMAT_PREFIX) && Base != 10) ? TRUE : FALSE;
    Upper = (Type & ACPI_FORMAT_UPPER) ? TRUE : FALSE;
    Zero = (Type & ACPI_FORMAT_ZERO) ? '0' : ' ';

    /* Calculate size according to sign and prefix */

    Sign = '\0';
    if (Type & ACPI_FORMAT_SIGN)
    {
        if ((INT64) Number < 0)
        {
            Sign = '-';
            Number = - (INT64) Number;
            Width--;
        }
        else if (Type & ACPI_FORMAT_SIGN_PLUS)
        {
            Sign = '+';
            Width--;
        }
        else if (Type & ACPI_FORMAT_SIGN_PLUS_SPACE)
        {
            Sign = ' ';
            Width--;
        }
    }
    if (NeedPrefix)
    {
        Width--;
        if (Base == 16)
        {
            Width--;
        }
    }

    /* Generate full string in reverse order */

    Pos = AcpiUtPutNumber (ReversedString, Number, Base, Upper);
    i = ACPI_PTR_DIFF (Pos, ReversedString);

    /* Printing 100 using %2d gives "100", not "00" */

    if (i > Precision)
    {
        Precision = i;
    }

    Width -= Precision;

    /* Output the string */

    if (!(Type & (ACPI_FORMAT_ZERO | ACPI_FORMAT_LEFT)))
    {
        while (--Width >= 0)
        {
            String = AcpiUtBoundStringOutput (String, End, ' ');
        }
    }
    if (Sign)
    {
        String = AcpiUtBoundStringOutput (String, End, Sign);
    }
    if (NeedPrefix)
    {
        String = AcpiUtBoundStringOutput (String, End, '0');
        if (Base == 16)
        {
            String = AcpiUtBoundStringOutput (String, End,
                        Upper ? 'X' : 'x');
        }
    }
    if (!(Type & ACPI_FORMAT_LEFT))
    {
        while (--Width >= 0)
        {
            String = AcpiUtBoundStringOutput (String, End, Zero);
        }
    }

    while (i <= --Precision)
    {
        String = AcpiUtBoundStringOutput (String, End, '0');
    }
    while (--i >= 0)
    {
        String = AcpiUtBoundStringOutput (String, End,
                    ReversedString[i]);
    }
    while (--Width >= 0)
    {
        String = AcpiUtBoundStringOutput (String, End, ' ');
    }

    return (String);
}
Пример #18
0
ACPI_STATUS
AeBuildLocalTables (
    ACPI_NEW_TABLE_DESC     *ListHead)
{
    UINT32                  TableCount = 1;
    ACPI_PHYSICAL_ADDRESS   DsdtAddress = 0;
    UINT32                  XsdtSize;
    ACPI_NEW_TABLE_DESC     *NextTable;
    UINT32                  NextIndex;
    ACPI_TABLE_FADT         *ExternalFadt = NULL;


    /*
     * Update the table count. For the DSDT, it is not put into the XSDT.
     * For the FADT, this table is already accounted for since we usually
     * install a local FADT.
     */
    NextTable = ListHead;
    while (NextTable)
    {
        if (!ACPI_COMPARE_NAME (NextTable->Table->Signature, ACPI_SIG_DSDT) &&
            !ACPI_COMPARE_NAME (NextTable->Table->Signature, ACPI_SIG_FADT))
        {
            TableCount++;
        }

        NextTable = NextTable->Next;
    }

    XsdtSize = (((TableCount + 1) * sizeof (UINT64)) +
        sizeof (ACPI_TABLE_HEADER));
    if (AcpiGbl_LoadTestTables)
    {
        XsdtSize += BASE_XSDT_SIZE;
    }

    /* Build an XSDT */

    LocalXSDT = AcpiOsAllocate (XsdtSize);
    if (!LocalXSDT)
    {
        return (AE_NO_MEMORY);
    }

    memset (LocalXSDT, 0, XsdtSize);
    LocalXSDT->TableOffsetEntry[0] = ACPI_PTR_TO_PHYSADDR (&LocalFADT);
    NextIndex = 1;

    /*
     * Install the user tables. The DSDT must be installed in the FADT.
     * All other tables are installed directly into the XSDT.
     */
    NextTable = ListHead;
    while (NextTable)
    {
        /*
         * Incoming DSDT or FADT are special cases. All other tables are
         * just immediately installed into the XSDT.
         */
        if (ACPI_COMPARE_NAME (NextTable->Table->Signature, ACPI_SIG_DSDT))
        {
            if (DsdtAddress)
            {
                printf ("Already found a DSDT, only one allowed\n");
                return (AE_ALREADY_EXISTS);
            }

            /* The incoming user table is a DSDT */

            DsdtAddress = ACPI_PTR_TO_PHYSADDR (NextTable->Table);
            DsdtToInstallOverride = NextTable->Table;
        }
        else if (ACPI_COMPARE_NAME (NextTable->Table->Signature, ACPI_SIG_FADT))
        {
            ExternalFadt = ACPI_CAST_PTR (ACPI_TABLE_FADT, NextTable->Table);
            LocalXSDT->TableOffsetEntry[0] = ACPI_PTR_TO_PHYSADDR (NextTable->Table);
        }
        else
        {
            /* Install the table in the XSDT */

            LocalXSDT->TableOffsetEntry[NextIndex] =
                ACPI_PTR_TO_PHYSADDR (NextTable->Table);
            NextIndex++;
        }

        NextTable = NextTable->Next;
    }

    /* Install the optional extra local tables */

    if (AcpiGbl_LoadTestTables)
    {
        LocalXSDT->TableOffsetEntry[NextIndex++] = ACPI_PTR_TO_PHYSADDR (&LocalTEST);
        LocalXSDT->TableOffsetEntry[NextIndex++] = ACPI_PTR_TO_PHYSADDR (&LocalBADTABLE);

        /* Install two SSDTs to test multiple table support */

        LocalXSDT->TableOffsetEntry[NextIndex++] = ACPI_PTR_TO_PHYSADDR (&Ssdt1Code);
        LocalXSDT->TableOffsetEntry[NextIndex++] = ACPI_PTR_TO_PHYSADDR (&Ssdt2Code);

        /* Install the OEM1 table to test LoadTable */

        LocalXSDT->TableOffsetEntry[NextIndex++] = ACPI_PTR_TO_PHYSADDR (&Oem1Code);

        /* Install the OEMx table to test LoadTable */

        LocalXSDT->TableOffsetEntry[NextIndex++] = ACPI_PTR_TO_PHYSADDR (&OemxCode);

         /* Install the ECDT table to test _REG */

        LocalXSDT->TableOffsetEntry[NextIndex++] = ACPI_PTR_TO_PHYSADDR (&EcdtCode);

        /* Install two UEFIs to test multiple table support */

        LocalXSDT->TableOffsetEntry[NextIndex++] = ACPI_PTR_TO_PHYSADDR (&Uefi1Code);
        LocalXSDT->TableOffsetEntry[NextIndex++] = ACPI_PTR_TO_PHYSADDR (&Uefi2Code);
    }

    /* Build an RSDP. Contains a valid XSDT only, no RSDT */

    memset (&LocalRSDP, 0, sizeof (ACPI_TABLE_RSDP));
    ACPI_MAKE_RSDP_SIG (LocalRSDP.Signature);
    memcpy (LocalRSDP.OemId, "Intel", 6);

    LocalRSDP.Revision = 2;
    LocalRSDP.XsdtPhysicalAddress = ACPI_PTR_TO_PHYSADDR (LocalXSDT);
    LocalRSDP.Length = sizeof (ACPI_TABLE_RSDP);

    /* Set checksums for both XSDT and RSDP */

    AeInitializeTableHeader ((void *) LocalXSDT, ACPI_SIG_XSDT, XsdtSize);

    LocalRSDP.Checksum = 0;
    LocalRSDP.Checksum = (UINT8) -AcpiTbChecksum (
        (void *) &LocalRSDP, ACPI_RSDP_CHECKSUM_LENGTH);

    if (!DsdtAddress)
    {
        /* Use the local DSDT because incoming table(s) are all SSDT(s) */

        DsdtAddress = ACPI_PTR_TO_PHYSADDR (LocalDsdtCode);
        DsdtToInstallOverride = ACPI_CAST_PTR (ACPI_TABLE_HEADER, LocalDsdtCode);
    }

    /*
     * Build an FADT. There are three options for the FADT:
     * 1) Incoming external FADT specified on the command line
     * 2) A "hardware reduced" local FADT
     * 3) A fully featured local FADT
     */
    memset (&LocalFADT, 0, sizeof (ACPI_TABLE_FADT));

    if (ExternalFadt)
    {
        /*
         * Use the external FADT, but we must update the DSDT/FACS
         * addresses as well as the checksum
         */
        ExternalFadt->Dsdt = (UINT32) DsdtAddress;
        if (!AcpiGbl_ReducedHardware)
        {
            ExternalFadt->Facs = ACPI_PTR_TO_PHYSADDR (&LocalFACS);
        }

        /*
         * If there room in the FADT for the XDsdt and XFacs 64-bit
         * pointers, use them.
         */
        if (ExternalFadt->Header.Length > ACPI_PTR_DIFF (
            &ExternalFadt->XDsdt, ExternalFadt))
        {
            ExternalFadt->Dsdt = 0;
            ExternalFadt->Facs = 0;

            ExternalFadt->XDsdt = DsdtAddress;
            if (!AcpiGbl_ReducedHardware)
            {
                ExternalFadt->XFacs = ACPI_PTR_TO_PHYSADDR (&LocalFACS);
            }
        }

        /* Complete the external FADT with the checksum */

        ExternalFadt->Header.Checksum = 0;
        ExternalFadt->Header.Checksum = (UINT8) -AcpiTbChecksum (
            (void *) ExternalFadt, ExternalFadt->Header.Length);
    }
    else if (AcpiGbl_UseHwReducedFadt)
    {
        memcpy (&LocalFADT, HwReducedFadtCode, ACPI_FADT_V5_SIZE);
        LocalFADT.Dsdt = 0;
        LocalFADT.XDsdt = DsdtAddress;
    }
    else
    {
        /*
         * Build a local FADT so we can test the hardware/event init
         */
        LocalFADT.Header.Revision = 5;

        /* Setup FADT header and DSDT/FACS addresses */

        LocalFADT.Dsdt = 0;
        LocalFADT.Facs = 0;

        LocalFADT.XDsdt = DsdtAddress;
        LocalFADT.XFacs = ACPI_PTR_TO_PHYSADDR (&LocalFACS);

        /* Miscellaneous FADT fields */

        LocalFADT.Gpe0BlockLength = 0x08;
        LocalFADT.Gpe0Block = 0x00001234;

        LocalFADT.Gpe1BlockLength = 0x80;
        LocalFADT.Gpe1Block = 0x00005678;
        LocalFADT.Gpe1Base = 100;

        LocalFADT.Pm1EventLength = 4;
        LocalFADT.Pm1aEventBlock = 0x00001aaa;
        LocalFADT.Pm1bEventBlock = 0x00001bbb;

        LocalFADT.Pm1ControlLength = 2;
        LocalFADT.Pm1aControlBlock = 0xB0;

        LocalFADT.PmTimerLength = 4;
        LocalFADT.PmTimerBlock = 0xA0;

        LocalFADT.Pm2ControlBlock = 0xC0;
        LocalFADT.Pm2ControlLength = 1;

        /* Setup one example X-64 GAS field */

        LocalFADT.XPm1bEventBlock.SpaceId = ACPI_ADR_SPACE_SYSTEM_IO;
        LocalFADT.XPm1bEventBlock.Address = LocalFADT.Pm1bEventBlock;
        LocalFADT.XPm1bEventBlock.BitWidth = (UINT8)
            ACPI_MUL_8 (LocalFADT.Pm1EventLength);
    }

    AeInitializeTableHeader ((void *) &LocalFADT,
        ACPI_SIG_FADT, sizeof (ACPI_TABLE_FADT));

    /* Build a FACS */

    memset (&LocalFACS, 0, sizeof (ACPI_TABLE_FACS));
    ACPI_MOVE_NAME (LocalFACS.Signature, ACPI_SIG_FACS);

    LocalFACS.Length = sizeof (ACPI_TABLE_FACS);
    LocalFACS.GlobalLock = 0x11AA0011;

    /* Build the optional local tables */

    if (AcpiGbl_LoadTestTables)
    {
        /*
         * Build a fake table [TEST] so that we make sure that the
         * ACPICA core ignores it
         */
        memset (&LocalTEST, 0, sizeof (ACPI_TABLE_HEADER));
        ACPI_MOVE_NAME (LocalTEST.Signature, "TEST");

        LocalTEST.Revision = 1;
        LocalTEST.Length = sizeof (ACPI_TABLE_HEADER);

        LocalTEST.Checksum = 0;
        LocalTEST.Checksum = (UINT8) -AcpiTbChecksum (
            (void *) &LocalTEST, LocalTEST.Length);

        /*
         * Build a fake table with a bad signature [BAD!] so that we make
         * sure that the ACPICA core ignores it
         */
        memset (&LocalBADTABLE, 0, sizeof (ACPI_TABLE_HEADER));
        ACPI_MOVE_NAME (LocalBADTABLE.Signature, "BAD!");

        LocalBADTABLE.Revision = 1;
        LocalBADTABLE.Length = sizeof (ACPI_TABLE_HEADER);

        LocalBADTABLE.Checksum = 0;
        LocalBADTABLE.Checksum = (UINT8) -AcpiTbChecksum (
            (void *) &LocalBADTABLE, LocalBADTABLE.Length);
    }

    return (AE_OK);
}
Пример #19
0
ACPI_STATUS
AcpiExConcatTemplate (
    ACPI_OPERAND_OBJECT     *Operand0,
    ACPI_OPERAND_OBJECT     *Operand1,
    ACPI_OPERAND_OBJECT     **ActualReturnDesc,
    ACPI_WALK_STATE         *WalkState)
{
    ACPI_STATUS             Status;
    ACPI_OPERAND_OBJECT     *ReturnDesc;
    UINT8                   *NewBuf;
    UINT8                   *EndTag;
    ACPI_SIZE               Length0;
    ACPI_SIZE               Length1;
    ACPI_SIZE               NewLength;


    ACPI_FUNCTION_TRACE (ExConcatTemplate);


    /*
     * Find the EndTag descriptor in each resource template.
     * Note1: returned pointers point TO the EndTag, not past it.
     * Note2: zero-length buffers are allowed; treated like one EndTag
     */

    /* Get the length of the first resource template */

    Status = AcpiUtGetResourceEndTag (Operand0, &EndTag);
    if (ACPI_FAILURE (Status))
    {
        return_ACPI_STATUS (Status);
    }

    Length0 = ACPI_PTR_DIFF (EndTag, Operand0->Buffer.Pointer);

    /* Get the length of the second resource template */

    Status = AcpiUtGetResourceEndTag (Operand1, &EndTag);
    if (ACPI_FAILURE (Status))
    {
        return_ACPI_STATUS (Status);
    }

    Length1 = ACPI_PTR_DIFF (EndTag, Operand1->Buffer.Pointer);

    /* Combine both lengths, minimum size will be 2 for EndTag */

    NewLength = Length0 + Length1 + sizeof (AML_RESOURCE_END_TAG);

    /* Create a new buffer object for the result (with one EndTag) */

    ReturnDesc = AcpiUtCreateBufferObject (NewLength);
    if (!ReturnDesc)
    {
        return_ACPI_STATUS (AE_NO_MEMORY);
    }

    /*
     * Copy the templates to the new buffer, 0 first, then 1 follows. One
     * EndTag descriptor is copied from Operand1.
     */
    NewBuf = ReturnDesc->Buffer.Pointer;
    memcpy (NewBuf, Operand0->Buffer.Pointer, Length0);
    memcpy (NewBuf + Length0, Operand1->Buffer.Pointer, Length1);

    /* Insert EndTag and set the checksum to zero, means "ignore checksum" */

    NewBuf[NewLength - 1] = 0;
    NewBuf[NewLength - 2] = ACPI_RESOURCE_NAME_END_TAG | 1;

    /* Return the completed resource template */

    *ActualReturnDesc = ReturnDesc;
    return_ACPI_STATUS (AE_OK);
}
Пример #20
0
ACPI_STATUS
AcpiDbDisplayStatistics (
    char                    *TypeArg)
{
    UINT32                  i;
    UINT32                  Temp;


    if (!TypeArg)
    {
        AcpiOsPrintf ("The following subcommands are available:\n    ALLOCATIONS, OBJECTS, MEMORY, MISC, SIZES, TABLES\n");
        return (AE_OK);
    }

    AcpiUtStrupr (TypeArg);
    Temp = AcpiDbMatchArgument (TypeArg, AcpiDbStatTypes);
    if (Temp == (UINT32) -1)
    {
        AcpiOsPrintf ("Invalid or unsupported argument\n");
        return (AE_OK);
    }


    switch (Temp)
    {
    case CMD_STAT_ALLOCATIONS:

#ifdef ACPI_DBG_TRACK_ALLOCATIONS
        AcpiUtDumpAllocationInfo ();
#endif
        break;

    case CMD_STAT_TABLES:

        AcpiOsPrintf ("ACPI Table Information (not implemented):\n\n");
        break;

    case CMD_STAT_OBJECTS:

        AcpiDbCountNamespaceObjects ();

        AcpiOsPrintf ("\nObjects defined in the current namespace:\n\n");

        AcpiOsPrintf ("%16.16s %10.10s %10.10s\n",
            "ACPI_TYPE", "NODES", "OBJECTS");

        for (i = 0; i < ACPI_TYPE_NS_NODE_MAX; i++)
        {
            AcpiOsPrintf ("%16.16s % 10ld% 10ld\n", AcpiUtGetTypeName (i),
                AcpiGbl_NodeTypeCount [i], AcpiGbl_ObjTypeCount [i]);
        }
        AcpiOsPrintf ("%16.16s % 10ld% 10ld\n", "Misc/Unknown",
            AcpiGbl_NodeTypeCountMisc, AcpiGbl_ObjTypeCountMisc);

        AcpiOsPrintf ("%16.16s % 10ld% 10ld\n", "TOTALS:",
            AcpiGbl_NumNodes, AcpiGbl_NumObjects);
        break;

    case CMD_STAT_MEMORY:

#ifdef ACPI_DBG_TRACK_ALLOCATIONS
        AcpiOsPrintf ("\n----Object Statistics (all in hex)---------\n");

        AcpiDbListInfo (AcpiGbl_GlobalList);
        AcpiDbListInfo (AcpiGbl_NsNodeList);
#endif

#ifdef ACPI_USE_LOCAL_CACHE
        AcpiOsPrintf ("\n----Cache Statistics (all in hex)---------\n");
        AcpiDbListInfo (AcpiGbl_OperandCache);
        AcpiDbListInfo (AcpiGbl_PsNodeCache);
        AcpiDbListInfo (AcpiGbl_PsNodeExtCache);
        AcpiDbListInfo (AcpiGbl_StateCache);
#endif

        break;

    case CMD_STAT_MISC:

        AcpiOsPrintf ("\nMiscellaneous Statistics:\n\n");
        AcpiOsPrintf ("Calls to AcpiPsFind:..  ........% 7ld\n",
            AcpiGbl_PsFindCount);
        AcpiOsPrintf ("Calls to AcpiNsLookup:..........% 7ld\n",
            AcpiGbl_NsLookupCount);

        AcpiOsPrintf ("\n");

        AcpiOsPrintf ("Mutex usage:\n\n");
        for (i = 0; i < ACPI_NUM_MUTEX; i++)
        {
            AcpiOsPrintf ("%-28s:       % 7ld\n",
                AcpiUtGetMutexName (i), AcpiGbl_MutexInfo[i].UseCount);
        }
        break;


    case CMD_STAT_SIZES:

        AcpiOsPrintf ("\nInternal object sizes:\n\n");

        AcpiOsPrintf ("Common           %3d\n", sizeof (ACPI_OBJECT_COMMON));
        AcpiOsPrintf ("Number           %3d\n", sizeof (ACPI_OBJECT_INTEGER));
        AcpiOsPrintf ("String           %3d\n", sizeof (ACPI_OBJECT_STRING));
        AcpiOsPrintf ("Buffer           %3d\n", sizeof (ACPI_OBJECT_BUFFER));
        AcpiOsPrintf ("Package          %3d\n", sizeof (ACPI_OBJECT_PACKAGE));
        AcpiOsPrintf ("BufferField      %3d\n", sizeof (ACPI_OBJECT_BUFFER_FIELD));
        AcpiOsPrintf ("Device           %3d\n", sizeof (ACPI_OBJECT_DEVICE));
        AcpiOsPrintf ("Event            %3d\n", sizeof (ACPI_OBJECT_EVENT));
        AcpiOsPrintf ("Method           %3d\n", sizeof (ACPI_OBJECT_METHOD));
        AcpiOsPrintf ("Mutex            %3d\n", sizeof (ACPI_OBJECT_MUTEX));
        AcpiOsPrintf ("Region           %3d\n", sizeof (ACPI_OBJECT_REGION));
        AcpiOsPrintf ("PowerResource    %3d\n", sizeof (ACPI_OBJECT_POWER_RESOURCE));
        AcpiOsPrintf ("Processor        %3d\n", sizeof (ACPI_OBJECT_PROCESSOR));
        AcpiOsPrintf ("ThermalZone      %3d\n", sizeof (ACPI_OBJECT_THERMAL_ZONE));
        AcpiOsPrintf ("RegionField      %3d\n", sizeof (ACPI_OBJECT_REGION_FIELD));
        AcpiOsPrintf ("BankField        %3d\n", sizeof (ACPI_OBJECT_BANK_FIELD));
        AcpiOsPrintf ("IndexField       %3d\n", sizeof (ACPI_OBJECT_INDEX_FIELD));
        AcpiOsPrintf ("Reference        %3d\n", sizeof (ACPI_OBJECT_REFERENCE));
        AcpiOsPrintf ("Notify           %3d\n", sizeof (ACPI_OBJECT_NOTIFY_HANDLER));
        AcpiOsPrintf ("AddressSpace     %3d\n", sizeof (ACPI_OBJECT_ADDR_HANDLER));
        AcpiOsPrintf ("Extra            %3d\n", sizeof (ACPI_OBJECT_EXTRA));
        AcpiOsPrintf ("Data             %3d\n", sizeof (ACPI_OBJECT_DATA));

        AcpiOsPrintf ("\n");

        AcpiOsPrintf ("ParseObject      %3d\n", sizeof (ACPI_PARSE_OBJ_COMMON));
        AcpiOsPrintf ("ParseObjectNamed %3d\n", sizeof (ACPI_PARSE_OBJ_NAMED));
        AcpiOsPrintf ("ParseObjectAsl   %3d\n", sizeof (ACPI_PARSE_OBJ_ASL));
        AcpiOsPrintf ("OperandObject    %3d\n", sizeof (ACPI_OPERAND_OBJECT));
        AcpiOsPrintf ("NamespaceNode    %3d\n", sizeof (ACPI_NAMESPACE_NODE));
        AcpiOsPrintf ("AcpiObject       %3d\n", sizeof (ACPI_OBJECT));

        break;


    case CMD_STAT_STACK:
#if defined(ACPI_DEBUG_OUTPUT)

        Temp = (UINT32) ACPI_PTR_DIFF (AcpiGbl_EntryStackPointer, AcpiGbl_LowestStackPointer);

        AcpiOsPrintf ("\nSubsystem Stack Usage:\n\n");
        AcpiOsPrintf ("Entry Stack Pointer          %p\n", AcpiGbl_EntryStackPointer);
        AcpiOsPrintf ("Lowest Stack Pointer         %p\n", AcpiGbl_LowestStackPointer);
        AcpiOsPrintf ("Stack Use                    %X (%u)\n", Temp, Temp);
        AcpiOsPrintf ("Deepest Procedure Nesting    %u\n", AcpiGbl_DeepestNesting);
#endif
        break;

    default:
        break;
    }

    AcpiOsPrintf ("\n");
    return (AE_OK);
}
Пример #21
0
static char *acpi_ut_format_number(char *string,
                                   char *end,
                                   u64 number,
                                   u8 base, s32 width, s32 precision, u8 type)
{
    char *pos;
    char sign;
    char zero;
    u8 need_prefix;
    u8 upper;
    s32 i;
    char reversed_string[66];

    /* Parameter validation */

    if (base < 2 || base > 16) {
        return (NULL);
    }

    if (type & ACPI_FORMAT_LEFT) {
        type &= ~ACPI_FORMAT_ZERO;
    }

    need_prefix = ((type & ACPI_FORMAT_PREFIX)
                   && base != 10) ? TRUE : FALSE;
    upper = (type & ACPI_FORMAT_UPPER) ? TRUE : FALSE;
    zero = (type & ACPI_FORMAT_ZERO) ? '0' : ' ';

    /* Calculate size according to sign and prefix */

    sign = '\0';
    if (type & ACPI_FORMAT_SIGN) {
        if ((s64) number < 0) {
            sign = '-';
            number = -(s64) number;
            width--;
        } else if (type & ACPI_FORMAT_SIGN_PLUS) {
            sign = '+';
            width--;
        } else if (type & ACPI_FORMAT_SIGN_PLUS_SPACE) {
            sign = ' ';
            width--;
        }
    }
    if (need_prefix) {
        width--;
        if (base == 16) {
            width--;
        }
    }

    /* Generate full string in reverse order */

    pos = acpi_ut_put_number(reversed_string, number, base, upper);
    i = ACPI_PTR_DIFF(pos, reversed_string);

    /* Printing 100 using %2d gives "100", not "00" */

    if (i > precision) {
        precision = i;
    }

    width -= precision;

    /* Output the string */

    if (!(type & (ACPI_FORMAT_ZERO | ACPI_FORMAT_LEFT))) {
        while (--width >= 0) {
            string = acpi_ut_bound_string_output(string, end, ' ');
        }
    }
    if (sign) {
        string = acpi_ut_bound_string_output(string, end, sign);
    }
    if (need_prefix) {
        string = acpi_ut_bound_string_output(string, end, '0');
        if (base == 16) {
            string = acpi_ut_bound_string_output(string, end,
                                                 upper ? 'X' : 'x');
        }
    }
    if (!(type & ACPI_FORMAT_LEFT)) {
        while (--width >= 0) {
            string = acpi_ut_bound_string_output(string, end, zero);
        }
    }

    while (i <= --precision) {
        string = acpi_ut_bound_string_output(string, end, '0');
    }
    while (--i >= 0) {
        string = acpi_ut_bound_string_output(string, end,
                                             reversed_string[i]);
    }
    while (--width >= 0) {
        string = acpi_ut_bound_string_output(string, end, ' ');
    }

    return (string);
}
Пример #22
0
static ACPI_STATUS
AcpiPsGetArguments (
    ACPI_WALK_STATE         *WalkState,
    UINT8                   *AmlOpStart,
    ACPI_PARSE_OBJECT       *Op)
{
    ACPI_STATUS             Status = AE_OK;
    ACPI_PARSE_OBJECT       *Arg = NULL;
    const ACPI_OPCODE_INFO  *OpInfo;


    ACPI_FUNCTION_TRACE_PTR (PsGetArguments, WalkState);


    switch (Op->Common.AmlOpcode)
    {
    case AML_BYTE_OP:       /* AML_BYTEDATA_ARG */
    case AML_WORD_OP:       /* AML_WORDDATA_ARG */
    case AML_DWORD_OP:      /* AML_DWORDATA_ARG */
    case AML_QWORD_OP:      /* AML_QWORDATA_ARG */
    case AML_STRING_OP:     /* AML_ASCIICHARLIST_ARG */

        /* Fill in constant or string argument directly */

        AcpiPsGetNextSimpleArg (&(WalkState->ParserState),
            GET_CURRENT_ARG_TYPE (WalkState->ArgTypes), Op);
        break;

    case AML_INT_NAMEPATH_OP:   /* AML_NAMESTRING_ARG */

        Status = AcpiPsGetNextNamepath (WalkState, &(WalkState->ParserState), Op, 1);
        if (ACPI_FAILURE (Status))
        {
            return_ACPI_STATUS (Status);
        }

        WalkState->ArgTypes = 0;
        break;

    default:
        /*
         * Op is not a constant or string, append each argument to the Op
         */
        while (GET_CURRENT_ARG_TYPE (WalkState->ArgTypes) && !WalkState->ArgCount)
        {
            WalkState->AmlOffset = (UINT32) ACPI_PTR_DIFF (WalkState->ParserState.Aml,
                WalkState->ParserState.AmlStart);

            Status = AcpiPsGetNextArg (WalkState, &(WalkState->ParserState),
                        GET_CURRENT_ARG_TYPE (WalkState->ArgTypes), &Arg);
            if (ACPI_FAILURE (Status))
            {
                return_ACPI_STATUS (Status);
            }

            if (Arg)
            {
                Arg->Common.AmlOffset = WalkState->AmlOffset;
                AcpiPsAppendArg (Op, Arg);
            }

            INCREMENT_ARG_LIST (WalkState->ArgTypes);
        }


        /*
         * Handle executable code at "module-level". This refers to
         * executable opcodes that appear outside of any control method.
         */
        if ((WalkState->PassNumber <= ACPI_IMODE_LOAD_PASS2) &&
            ((WalkState->ParseFlags & ACPI_PARSE_DISASSEMBLE) == 0))
        {
            /*
             * We want to skip If/Else/While constructs during Pass1 because we
             * want to actually conditionally execute the code during Pass2.
             *
             * Except for disassembly, where we always want to walk the
             * If/Else/While packages
             */
            switch (Op->Common.AmlOpcode)
            {
            case AML_IF_OP:
            case AML_ELSE_OP:
            case AML_WHILE_OP:

                /*
                 * Currently supported module-level opcodes are:
                 * IF/ELSE/WHILE. These appear to be the most common,
                 * and easiest to support since they open an AML
                 * package.
                 */
                if (WalkState->PassNumber == ACPI_IMODE_LOAD_PASS1)
                {
                    AcpiPsLinkModuleCode (Op->Common.Parent, AmlOpStart,
                        (UINT32) (WalkState->ParserState.PkgEnd - AmlOpStart),
                        WalkState->OwnerId);
                }

                ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
                    "Pass1: Skipping an If/Else/While body\n"));

                /* Skip body of if/else/while in pass 1 */

                WalkState->ParserState.Aml = WalkState->ParserState.PkgEnd;
                WalkState->ArgCount = 0;
                break;

            default:
                /*
                 * Check for an unsupported executable opcode at module
                 * level. We must be in PASS1, the parent must be a SCOPE,
                 * The opcode class must be EXECUTE, and the opcode must
                 * not be an argument to another opcode.
                 */
                if ((WalkState->PassNumber == ACPI_IMODE_LOAD_PASS1) &&
                    (Op->Common.Parent->Common.AmlOpcode == AML_SCOPE_OP))
                {
                    OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
                    if ((OpInfo->Class == AML_CLASS_EXECUTE) &&
                        (!Arg))
                    {
                        ACPI_WARNING ((AE_INFO,
                            "Unsupported module-level executable opcode "
                            "0x%.2X at table offset 0x%.4X",
                            Op->Common.AmlOpcode,
                            (UINT32) (ACPI_PTR_DIFF (AmlOpStart,
                                WalkState->ParserState.AmlStart) +
                                sizeof (ACPI_TABLE_HEADER))));
                    }
                }
                break;
            }
        }

        /* Special processing for certain opcodes */

        switch (Op->Common.AmlOpcode)
        {
        case AML_METHOD_OP:
            /*
             * Skip parsing of control method because we don't have enough
             * info in the first pass to parse it correctly.
             *
             * Save the length and address of the body
             */
            Op->Named.Data = WalkState->ParserState.Aml;
            Op->Named.Length = (UINT32)
                (WalkState->ParserState.PkgEnd - WalkState->ParserState.Aml);

            /* Skip body of method */

            WalkState->ParserState.Aml = WalkState->ParserState.PkgEnd;
            WalkState->ArgCount = 0;
            break;

        case AML_BUFFER_OP:
        case AML_PACKAGE_OP:
        case AML_VAR_PACKAGE_OP:

            if ((Op->Common.Parent) &&
                (Op->Common.Parent->Common.AmlOpcode == AML_NAME_OP) &&
                (WalkState->PassNumber <= ACPI_IMODE_LOAD_PASS2))
            {
                /*
                 * Skip parsing of Buffers and Packages because we don't have
                 * enough info in the first pass to parse them correctly.
                 */
                Op->Named.Data = AmlOpStart;
                Op->Named.Length = (UINT32)
                    (WalkState->ParserState.PkgEnd - AmlOpStart);

                /* Skip body */

                WalkState->ParserState.Aml = WalkState->ParserState.PkgEnd;
                WalkState->ArgCount = 0;
            }
            break;

        case AML_WHILE_OP:

            if (WalkState->ControlState)
            {
                WalkState->ControlState->Control.PackageEnd =
                    WalkState->ParserState.PkgEnd;
            }
            break;

        default:

            /* No action for all other opcodes */
            break;
        }

        break;
    }

    return_ACPI_STATUS (AE_OK);
}
Пример #23
0
static ACPI_STATUS
AcpiPsGetAmlOpcode (
    ACPI_WALK_STATE         *WalkState)
{

    ACPI_FUNCTION_TRACE_PTR (PsGetAmlOpcode, WalkState);


    WalkState->AmlOffset = (UINT32) ACPI_PTR_DIFF (WalkState->ParserState.Aml,
                                WalkState->ParserState.AmlStart);
    WalkState->Opcode = AcpiPsPeekOpcode (&(WalkState->ParserState));

    /*
     * First cut to determine what we have found:
     * 1) A valid AML opcode
     * 2) A name string
     * 3) An unknown/invalid opcode
     */
    WalkState->OpInfo = AcpiPsGetOpcodeInfo (WalkState->Opcode);

    switch (WalkState->OpInfo->Class)
    {
    case AML_CLASS_ASCII:
    case AML_CLASS_PREFIX:
        /*
         * Starts with a valid prefix or ASCII char, this is a name
         * string. Convert the bare name string to a namepath.
         */
        WalkState->Opcode = AML_INT_NAMEPATH_OP;
        WalkState->ArgTypes = ARGP_NAMESTRING;
        break;

    case AML_CLASS_UNKNOWN:

        /* The opcode is unrecognized. Complain and skip unknown opcodes */

        if (WalkState->PassNumber == 2)
        {
            ACPI_ERROR ((AE_INFO,
                "Unknown opcode 0x%.2X at table offset 0x%.4X, ignoring",
                WalkState->Opcode,
                (UINT32) (WalkState->AmlOffset + sizeof (ACPI_TABLE_HEADER))));

            ACPI_DUMP_BUFFER ((WalkState->ParserState.Aml - 16), 48);

#ifdef ACPI_ASL_COMPILER
            /*
             * This is executed for the disassembler only. Output goes
             * to the disassembled ASL output file.
             */
            AcpiOsPrintf (
                "/*\nError: Unknown opcode 0x%.2X at table offset 0x%.4X, context:\n",
                WalkState->Opcode,
                (UINT32) (WalkState->AmlOffset + sizeof (ACPI_TABLE_HEADER)));

            /* Dump the context surrounding the invalid opcode */

            AcpiUtDumpBuffer (((UINT8 *) WalkState->ParserState.Aml - 16),
                48, DB_BYTE_DISPLAY,
                (WalkState->AmlOffset + sizeof (ACPI_TABLE_HEADER) - 16));
            AcpiOsPrintf (" */\n");
#endif
        }

        /* Increment past one-byte or two-byte opcode */

        WalkState->ParserState.Aml++;
        if (WalkState->Opcode > 0xFF) /* Can only happen if first byte is 0x5B */
        {
            WalkState->ParserState.Aml++;
        }

        return_ACPI_STATUS (AE_CTRL_PARSE_CONTINUE);

    default:

        /* Found opcode info, this is a normal opcode */

        WalkState->ParserState.Aml += AcpiPsGetOpcodeSize (WalkState->Opcode);
        WalkState->ArgTypes = WalkState->OpInfo->ParseArgs;
        break;
    }

    return_ACPI_STATUS (AE_OK);
}
Пример #24
0
acpi_status
acpi_ex_concat_template(union acpi_operand_object *operand0,
			union acpi_operand_object *operand1,
			union acpi_operand_object **actual_return_desc,
			struct acpi_walk_state *walk_state)
{
	acpi_status status;
	union acpi_operand_object *return_desc;
	u8 *new_buf;
	u8 *end_tag;
	acpi_size length0;
	acpi_size length1;
	acpi_size new_length;

	ACPI_FUNCTION_TRACE(ex_concat_template);

	/*
	 * Find the end_tag descriptor in each resource template.
	 * Note1: returned pointers point TO the end_tag, not past it.
	 * Note2: zero-length buffers are allowed; treated like one end_tag
	 */

	/* Get the length of the first resource template */

	status = acpi_ut_get_resource_end_tag(operand0, &end_tag);
	if (ACPI_FAILURE(status)) {
		return_ACPI_STATUS(status);
	}

	length0 = ACPI_PTR_DIFF(end_tag, operand0->buffer.pointer);

	/* Get the length of the second resource template */

	status = acpi_ut_get_resource_end_tag(operand1, &end_tag);
	if (ACPI_FAILURE(status)) {
		return_ACPI_STATUS(status);
	}

	length1 = ACPI_PTR_DIFF(end_tag, operand1->buffer.pointer);

	/* Combine both lengths, minimum size will be 2 for end_tag */

	new_length = length0 + length1 + sizeof(struct aml_resource_end_tag);

	/* Create a new buffer object for the result (with one end_tag) */

	return_desc = acpi_ut_create_buffer_object(new_length);
	if (!return_desc) {
		return_ACPI_STATUS(AE_NO_MEMORY);
	}

	/*
	 * Copy the templates to the new buffer, 0 first, then 1 follows. One
	 * end_tag descriptor is copied from Operand1.
	 */
	new_buf = return_desc->buffer.pointer;
	memcpy(new_buf, operand0->buffer.pointer, length0);
	memcpy(new_buf + length0, operand1->buffer.pointer, length1);

	/* Insert end_tag and set the checksum to zero, means "ignore checksum" */

	new_buf[new_length - 1] = 0;
	new_buf[new_length - 2] = ACPI_RESOURCE_NAME_END_TAG | 1;

	/* Return the completed resource template */

	*actual_return_desc = return_desc;
	return_ACPI_STATUS(AE_OK);
}
Пример #25
0
static ACPI_STATUS
DtParseLine (
    char                    *LineBuffer,
    UINT32                  Line,
    UINT32                  Offset)
{
    char                    *Start;
    char                    *End;
    char                    *TmpName;
    char                    *TmpValue;
    char                    *Name;
    char                    *Value;
    char                    *Colon;
    UINT32                  Length;
    DT_FIELD                *Field;
    UINT32                  Column;
    UINT32                  NameColumn;
    BOOLEAN                 IsNullString = FALSE;


    if (!LineBuffer)
    {
        return (AE_OK);
    }

    /* All lines after "Raw Table Data" are ingored */

    if (strstr (LineBuffer, ACPI_RAW_TABLE_DATA_HEADER))
    {
        return (AE_NOT_FOUND);
    }

    Colon = strchr (LineBuffer, ':');
    if (!Colon)
    {
        return (AE_OK);
    }

    Start = LineBuffer;
    End = Colon;

    while (Start < Colon)
    {
        if (*Start == ' ')
        {
            Start++;
            continue;
        }

        /* Found left bracket, go to the right bracket */

        if (*Start == '[')
        {
            while (Start < Colon && *Start != ']')
            {
                Start++;
            }

            if (Start == Colon)
            {
                break;
            }

            Start++;
            continue;
        }

        break;
    }

    /*
     * There are two column values. One for the field name,
     * and one for the field value.
     */
    Column = ACPI_PTR_DIFF (Colon, LineBuffer) + 3;
    NameColumn = ACPI_PTR_DIFF (Start, LineBuffer) + 1;

    Length = ACPI_PTR_DIFF (End, Start);

    TmpName = UtLocalCalloc (Length + 1);
    ACPI_STRNCPY (TmpName, Start, Length);
    Name = DtTrim (TmpName);
    ACPI_FREE (TmpName);

    Start = End = (Colon + 1);
    while (*End)
    {
        /* Found left quotation, go to the right quotation and break */

        if (*End == '"')
        {
            End++;

            /* Check for an explicit null string */

            if (*End == '"')
            {
                IsNullString = TRUE;
            }
            while (*End && (*End != '"'))
            {
                End++;
            }

            End++;
            break;
        }

        /*
         * Special "comment" fields at line end, ignore them.
         * Note: normal slash-slash and slash-asterisk comments are
         * stripped already by the DtGetNextLine parser.
         *
         * TBD: Perhaps DtGetNextLine should parse the following type
         * of comments also.
         */
        if (*End == '[')
        {
            End--;
            break;
        }
        End++;
    }

    Length = ACPI_PTR_DIFF (End, Start);
    TmpValue = UtLocalCalloc (Length + 1);

    ACPI_STRNCPY (TmpValue, Start, Length);
    Value = DtTrim (TmpValue);
    ACPI_FREE (TmpValue);

    /* Create a new field object only if we have a valid value field */

    if ((Value && *Value) || IsNullString)
    {
        Field = UtLocalCalloc (sizeof (DT_FIELD));
        Field->Name = Name;
        Field->Value = Value;
        Field->Line = Line;
        Field->ByteOffset = Offset;
        Field->NameColumn = NameColumn;
        Field->Column = Column;

        DtLinkField (Field);
    }
    else /* Ignore this field, it has no valid data */
    {
        ACPI_FREE (Name);
        ACPI_FREE (Value);
    }

    return (AE_OK);
}
Пример #26
0
static char *
DtTrim (
    char                    *String)
{
    char                    *Start;
    char                    *End;
    char                    *ReturnString;
    ACPI_SIZE               Length;


    /* Skip lines that start with a space */

    if (!ACPI_STRCMP (String, " "))
    {
        ReturnString = UtLocalCalloc (1);
        return (ReturnString);
    }

    /* Setup pointers to start and end of input string */

    Start = String;
    End = String + ACPI_STRLEN (String) - 1;

    /* Find first non-whitespace character */

    while ((Start <= End) && ((*Start == ' ') || (*Start == '\t')))
    {
        Start++;
    }

    /* Find last non-space character */

    while (End >= Start)
    {
        if (*End == '\r' || *End == '\n')
        {
            End--;
            continue;
        }

        if (*End != ' ')
        {
            break;
        }

        End--;
    }

    /* Remove any quotes around the string */

    if (*Start == '\"')
    {
        Start++;
    }
    if (*End == '\"')
    {
        End--;
    }

    /* Create the trimmed return string */

    Length = ACPI_PTR_DIFF (End, Start) + 1;
    ReturnString = UtLocalCalloc (Length + 1);
    if (ACPI_STRLEN (Start))
    {
        ACPI_STRNCPY (ReturnString, Start, Length);
    }

    ReturnString[Length] = 0;
    return (ReturnString);
}
Пример #27
0
ACPI_STATUS
AeBuildLocalTables (
    UINT32                  TableCount,
    AE_TABLE_DESC           *TableList)
{
    ACPI_PHYSICAL_ADDRESS   DsdtAddress = 0;
    UINT32                  XsdtSize;
    AE_TABLE_DESC           *NextTable;
    UINT32                  NextIndex;
    ACPI_TABLE_FADT         *ExternalFadt = NULL;


    /*
     * Update the table count. For DSDT, it is not put into the XSDT. For
     * FADT, this is already accounted for since we usually install a
     * local FADT.
     */
    NextTable = TableList;
    while (NextTable)
    {
        if (ACPI_COMPARE_NAME (NextTable->Table->Signature, ACPI_SIG_DSDT) ||
            ACPI_COMPARE_NAME (NextTable->Table->Signature, ACPI_SIG_FADT))
        {
            TableCount--;
        }
        NextTable = NextTable->Next;
    }

    XsdtSize = BASE_XSDT_SIZE + (TableCount * sizeof (UINT64));

    /* Build an XSDT */

    LocalXSDT = AcpiOsAllocate (XsdtSize);
    if (!LocalXSDT)
    {
        return (AE_NO_MEMORY);
    }

    ACPI_MEMSET (LocalXSDT, 0, XsdtSize);
    ACPI_MOVE_NAME (LocalXSDT->Header.Signature, ACPI_SIG_XSDT);
    LocalXSDT->Header.Length = XsdtSize;
    LocalXSDT->Header.Revision = 1;

    LocalXSDT->TableOffsetEntry[0] = ACPI_PTR_TO_PHYSADDR (&LocalFADT);

    /*
     * Install the user tables. The DSDT must be installed in the FADT.
     * All other tables are installed directly into the XSDT.
     */
    NextIndex = BASE_XSDT_TABLES;
    NextTable = TableList;
    while (NextTable)
    {
        /*
         * Incoming DSDT or FADT are special cases. All other tables are
         * just immediately installed into the XSDT.
         */
        if (ACPI_COMPARE_NAME (NextTable->Table->Signature, ACPI_SIG_DSDT))
        {
            if (DsdtAddress)
            {
                printf ("Already found a DSDT, only one allowed\n");
                return (AE_ALREADY_EXISTS);
            }

            /* The incoming user table is a DSDT */

            DsdtAddress = ACPI_PTR_TO_PHYSADDR (NextTable->Table);
        }
        else if (ACPI_COMPARE_NAME (NextTable->Table->Signature, ACPI_SIG_FADT))
        {
            ExternalFadt = ACPI_CAST_PTR (ACPI_TABLE_FADT, NextTable->Table);
            LocalXSDT->TableOffsetEntry[2] = ACPI_PTR_TO_PHYSADDR (NextTable->Table);
        }
        else
        {
            /* Install the table in the XSDT */

            LocalXSDT->TableOffsetEntry[NextIndex] = ACPI_PTR_TO_PHYSADDR (NextTable->Table);
            NextIndex++;
        }

        NextTable = NextTable->Next;
    }

    /* Build an RSDP */

    ACPI_MEMSET (&LocalRSDP, 0, sizeof (ACPI_TABLE_RSDP));
    ACPI_MAKE_RSDP_SIG (LocalRSDP.Signature);
    ACPI_MEMCPY (LocalRSDP.OemId, "I_TEST", 6);
    LocalRSDP.Revision = 2;
    LocalRSDP.XsdtPhysicalAddress = ACPI_PTR_TO_PHYSADDR (LocalXSDT);
    LocalRSDP.Length = sizeof (ACPI_TABLE_XSDT);

    /* Set checksums for both XSDT and RSDP */

    LocalXSDT->Header.Checksum = (UINT8) -AcpiTbChecksum (
        (void *) LocalXSDT, LocalXSDT->Header.Length);
    LocalRSDP.Checksum = (UINT8) -AcpiTbChecksum (
        (void *) &LocalRSDP, ACPI_RSDP_CHECKSUM_LENGTH);

    if (!DsdtAddress)
    {
        return (AE_SUPPORT);
    }

    if (ExternalFadt)
    {
        /*
         * Use the external FADT, but we must update the DSDT/FACS addresses
         * as well as the checksum
         */
        ExternalFadt->Dsdt = DsdtAddress;
        ExternalFadt->Facs = ACPI_PTR_TO_PHYSADDR (&LocalFACS);

        if (ExternalFadt->Header.Length > ACPI_PTR_DIFF (&ExternalFadt->XDsdt, ExternalFadt))
        {
            ExternalFadt->XDsdt = DsdtAddress;
            ExternalFadt->XFacs = ACPI_PTR_TO_PHYSADDR (&LocalFACS);
        }
        /* Complete the FADT with the checksum */

        ExternalFadt->Header.Checksum = 0;
        ExternalFadt->Header.Checksum = (UINT8) -AcpiTbChecksum (
            (void *) ExternalFadt, ExternalFadt->Header.Length);
    }
    else
    {
        /*
         * Build a local FADT so we can test the hardware/event init
         */
        ACPI_MEMSET (&LocalFADT, 0, sizeof (ACPI_TABLE_FADT));
        ACPI_MOVE_NAME (LocalFADT.Header.Signature, ACPI_SIG_FADT);

        /* Setup FADT header and DSDT/FACS addresses */

        LocalFADT.Dsdt = 0;
        LocalFADT.Facs = 0;

        LocalFADT.XDsdt = DsdtAddress;
        LocalFADT.XFacs = ACPI_PTR_TO_PHYSADDR (&LocalFACS);

        LocalFADT.Header.Revision = 3;
        LocalFADT.Header.Length = sizeof (ACPI_TABLE_FADT);

        /* Miscellaneous FADT fields */

        LocalFADT.Gpe0BlockLength = 16;
        LocalFADT.Gpe0Block = 0x00001234;

        LocalFADT.Gpe1BlockLength = 6;
        LocalFADT.Gpe1Block = 0x00005678;
        LocalFADT.Gpe1Base = 96;

        LocalFADT.Pm1EventLength = 4;
        LocalFADT.Pm1aEventBlock = 0x00001aaa;
        LocalFADT.Pm1bEventBlock = 0x00001bbb;

        LocalFADT.Pm1ControlLength = 2;
        LocalFADT.Pm1aControlBlock = 0xB0;

        LocalFADT.PmTimerLength = 4;
        LocalFADT.PmTimerBlock = 0xA0;

        LocalFADT.Pm2ControlBlock = 0xC0;
        LocalFADT.Pm2ControlLength = 1;

        /* Setup one example X-64 field */

        LocalFADT.XPm1bEventBlock.SpaceId = ACPI_ADR_SPACE_SYSTEM_IO;
        LocalFADT.XPm1bEventBlock.Address = LocalFADT.Pm1bEventBlock;
        LocalFADT.XPm1bEventBlock.BitWidth = (UINT8) ACPI_MUL_8 (LocalFADT.Pm1EventLength);

        /* Complete the FADT with the checksum */

        LocalFADT.Header.Checksum = 0;
        LocalFADT.Header.Checksum = (UINT8) -AcpiTbChecksum (
            (void *) &LocalFADT, LocalFADT.Header.Length);
    }

    /* Build a FACS */

    ACPI_MEMSET (&LocalFACS, 0, sizeof (ACPI_TABLE_FACS));
    ACPI_MOVE_NAME (LocalFACS.Signature, ACPI_SIG_FACS);

    LocalFACS.Length = sizeof (ACPI_TABLE_FACS);
    LocalFACS.GlobalLock = 0x11AA0011;

    return (AE_OK);
}
Пример #28
0
acpi_status acpi_find_root_pointer(acpi_size *table_address)
{
	u8 *table_ptr;
	u8 *mem_rover;
	u32 physical_address;

	ACPI_FUNCTION_TRACE(acpi_find_root_pointer);

	/* 1a) Get the location of the Extended BIOS Data Area (EBDA) */

	table_ptr = acpi_os_map_memory((acpi_physical_address)
				       ACPI_EBDA_PTR_LOCATION,
				       ACPI_EBDA_PTR_LENGTH);
	if (!table_ptr) {
		ACPI_ERROR((AE_INFO,
			    "Could not map memory at 0x%8.8X for length %u",
			    ACPI_EBDA_PTR_LOCATION, ACPI_EBDA_PTR_LENGTH));

		return_ACPI_STATUS(AE_NO_MEMORY);
	}

	ACPI_MOVE_16_TO_32(&physical_address, table_ptr);

	/* Convert segment part to physical address */

	physical_address <<= 4;
	acpi_os_unmap_memory(table_ptr, ACPI_EBDA_PTR_LENGTH);

	/* EBDA present? */

	if (physical_address > 0x400) {
		/*
		 * 1b) Search EBDA paragraphs (EBDA is required to be a
		 *     minimum of 1K length)
		 */
		table_ptr = acpi_os_map_memory((acpi_physical_address)
					       physical_address,
					       ACPI_EBDA_WINDOW_SIZE);
		if (!table_ptr) {
			ACPI_ERROR((AE_INFO,
				    "Could not map memory at 0x%8.8X for length %u",
				    physical_address, ACPI_EBDA_WINDOW_SIZE));

			return_ACPI_STATUS(AE_NO_MEMORY);
		}

		mem_rover =
		    acpi_tb_scan_memory_for_rsdp(table_ptr,
						 ACPI_EBDA_WINDOW_SIZE);
		acpi_os_unmap_memory(table_ptr, ACPI_EBDA_WINDOW_SIZE);

		if (mem_rover) {

			/* Return the physical address */

			physical_address +=
			    (u32) ACPI_PTR_DIFF(mem_rover, table_ptr);

			*table_address = physical_address;
			return_ACPI_STATUS(AE_OK);
		}
	}

	/*
	 * 2) Search upper memory: 16-byte boundaries in E0000h-FFFFFh
	 */
	table_ptr = acpi_os_map_memory((acpi_physical_address)
				       ACPI_HI_RSDP_WINDOW_BASE,
				       ACPI_HI_RSDP_WINDOW_SIZE);

	if (!table_ptr) {
		ACPI_ERROR((AE_INFO,
			    "Could not map memory at 0x%8.8X for length %u",
			    ACPI_HI_RSDP_WINDOW_BASE,
			    ACPI_HI_RSDP_WINDOW_SIZE));

		return_ACPI_STATUS(AE_NO_MEMORY);
	}

	mem_rover =
	    acpi_tb_scan_memory_for_rsdp(table_ptr, ACPI_HI_RSDP_WINDOW_SIZE);
	acpi_os_unmap_memory(table_ptr, ACPI_HI_RSDP_WINDOW_SIZE);

	if (mem_rover) {

		/* Return the physical address */

		physical_address = (u32)
		    (ACPI_HI_RSDP_WINDOW_BASE +
		     ACPI_PTR_DIFF(mem_rover, table_ptr));

		*table_address = physical_address;
		return_ACPI_STATUS(AE_OK);
	}

	/* A valid RSDP was not found */

	ACPI_BIOS_ERROR((AE_INFO, "A valid RSDP was not found"));
	return_ACPI_STATUS(AE_NOT_FOUND);
}
Пример #29
0
static ACPI_STATUS
AcpiDmDescendingOp (
    ACPI_PARSE_OBJECT       *Op,
    UINT32                  Level,
    void                    *Context)
{
    ACPI_OP_WALK_INFO       *Info = Context;
    const ACPI_OPCODE_INFO  *OpInfo;
    UINT32                  Name;
    ACPI_PARSE_OBJECT       *NextOp;
    UINT32                  AmlOffset;


    OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);

    /* Listing support to dump the AML code after the ASL statement */

    if (AcpiGbl_DmOpt_Listing)
    {
        /* We only care about these classes of objects */

        if ((OpInfo->Class == AML_CLASS_NAMED_OBJECT) ||
            (OpInfo->Class == AML_CLASS_CONTROL) ||
            (OpInfo->Class == AML_CLASS_CREATE) ||
            ((OpInfo->Class == AML_CLASS_EXECUTE) && (!Op->Common.Next)))
        {
            if (AcpiGbl_DmOpt_Listing && Info->PreviousAml)
            {
                /* Dump the AML byte code for the previous Op */

                if (Op->Common.Aml > Info->PreviousAml)
                {
                    AcpiOsPrintf ("\n");
                    AcpiUtDumpBuffer (
                        (Info->StartAml + Info->AmlOffset),
                        (Op->Common.Aml - Info->PreviousAml),
                        DB_BYTE_DISPLAY,
                        Info->AmlOffset);
                    AcpiOsPrintf ("\n");
                }

                Info->AmlOffset = (Op->Common.Aml - Info->StartAml);
            }

            Info->PreviousAml = Op->Common.Aml;
        }
    }

    if (Op->Common.DisasmFlags & ACPI_PARSEOP_IGNORE)
    {
        /* Ignore this op -- it was handled elsewhere */

        return (AE_CTRL_DEPTH);
    }

    /* Level 0 is at the Definition Block level */

    if (Level == 0)
    {
        /* In verbose mode, print the AML offset, opcode and depth count */

        if (Info->WalkState)
        {
            AmlOffset = (UINT32) ACPI_PTR_DIFF (Op->Common.Aml,
                Info->WalkState->ParserState.AmlStart);
            if (AcpiGbl_DmOpt_Verbose)
            {
                AcpiOsPrintf (DB_FULL_OP_INFO,
                    (Info->WalkState->MethodNode ?
                        Info->WalkState->MethodNode->Name.Ascii : "   "),
                    AmlOffset, (UINT32) Op->Common.AmlOpcode);
            }
        }

        if (Op->Common.AmlOpcode == AML_SCOPE_OP)
        {
            /* This is the beginning of the Definition Block */

            AcpiOsPrintf ("{\n");

            /* Emit all External() declarations here */

            AcpiDmEmitExternals ();
            return (AE_OK);
        }
    }
    else if ((AcpiDmBlockType (Op->Common.Parent) & BLOCK_BRACE) &&
         (!(Op->Common.DisasmFlags & ACPI_PARSEOP_PARAMLIST)) &&
         (Op->Common.AmlOpcode != AML_INT_BYTELIST_OP))
    {
            /*
             * This is a first-level element of a term list,
             * indent a new line
             */
            switch (Op->Common.AmlOpcode)
            {
            case AML_NOOP_OP:
                /*
                 * Optionally just ignore this opcode. Some tables use
                 * NoOp opcodes for "padding" out packages that the BIOS
                 * changes dynamically. This can leave hundreds or
                 * thousands of NoOp opcodes that if disassembled,
                 * cannot be compiled because they are syntactically
                 * incorrect.
                 */
                if (AcpiGbl_IgnoreNoopOperator)
                {
                    Op->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
                    return (AE_OK);
                }

                /* Fallthrough */

            default:

                AcpiDmIndent (Level);
                break;
            }

            Info->LastLevel = Level;
            Info->Count = 0;
    }

    /*
     * This is an inexpensive mechanism to try and keep lines from getting
     * too long. When the limit is hit, start a new line at the previous
     * indent plus one. A better but more expensive mechanism would be to
     * keep track of the current column.
     */
    Info->Count++;
    if (Info->Count /* +Info->LastLevel */ > 12)
    {
        Info->Count = 0;
        AcpiOsPrintf ("\n");
        AcpiDmIndent (Info->LastLevel + 1);
    }

    /* If ASL+ is enabled, check for a C-style operator */

    if (AcpiDmCheckForSymbolicOpcode (Op, Info))
    {
        return (AE_OK);
    }

    /* Print the opcode name */

    AcpiDmDisassembleOneOp (NULL, Info, Op);

    if ((Op->Common.DisasmOpcode == ACPI_DASM_LNOT_PREFIX) ||
        (Op->Common.AmlOpcode == AML_INT_CONNECTION_OP))
    {
        return (AE_OK);
    }

    if ((Op->Common.AmlOpcode == AML_NAME_OP) ||
        (Op->Common.AmlOpcode == AML_RETURN_OP))
    {
        Info->Level--;
    }

    /* Start the opcode argument list if necessary */

    if ((OpInfo->Flags & AML_HAS_ARGS) ||
        (Op->Common.AmlOpcode == AML_EVENT_OP))
    {
        /* This opcode has an argument list */

        if (AcpiDmBlockType (Op) & BLOCK_PAREN)
        {
            AcpiOsPrintf (" (");
        }

        /* If this is a named opcode, print the associated name value */

        if (OpInfo->Flags & AML_NAMED)
        {
            switch (Op->Common.AmlOpcode)
            {
            case AML_ALIAS_OP:

                NextOp = AcpiPsGetDepthNext (NULL, Op);
                NextOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
                AcpiDmNamestring (NextOp->Common.Value.Name);
                AcpiOsPrintf (", ");

                /*lint -fallthrough */

            default:

                Name = AcpiPsGetName (Op);
                if (Op->Named.Path)
                {
                    AcpiDmNamestring ((char *) Op->Named.Path);
                }
                else
                {
                    AcpiDmDumpName (Name);
                }

                if (Op->Common.AmlOpcode != AML_INT_NAMEDFIELD_OP)
                {
                    if (AcpiGbl_DmOpt_Verbose)
                    {
                        (void) AcpiPsDisplayObjectPathname (NULL, Op);
                    }
                }
                break;
            }

            switch (Op->Common.AmlOpcode)
            {
            case AML_METHOD_OP:

                AcpiDmMethodFlags (Op);
                AcpiOsPrintf (")");

                /* Emit description comment for Method() with a predefined ACPI name */

                AcpiDmPredefinedDescription (Op);
                break;

            case AML_NAME_OP:

                /* Check for _HID and related EISAID() */

                AcpiDmCheckForHardwareId (Op);
                AcpiOsPrintf (", ");
                break;

            case AML_REGION_OP:

                AcpiDmRegionFlags (Op);
                break;

            case AML_POWER_RES_OP:

                /* Mark the next two Ops as part of the parameter list */

                AcpiOsPrintf (", ");
                NextOp = AcpiPsGetDepthNext (NULL, Op);
                NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST;

                NextOp = NextOp->Common.Next;
                NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST;
                return (AE_OK);

            case AML_PROCESSOR_OP:

                /* Mark the next three Ops as part of the parameter list */

                AcpiOsPrintf (", ");
                NextOp = AcpiPsGetDepthNext (NULL, Op);
                NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST;

                NextOp = NextOp->Common.Next;
                NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST;

                NextOp = NextOp->Common.Next;
                NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST;
                return (AE_OK);

            case AML_MUTEX_OP:
            case AML_DATA_REGION_OP:

                AcpiOsPrintf (", ");
                return (AE_OK);

            case AML_EVENT_OP:
            case AML_ALIAS_OP:

                return (AE_OK);

            case AML_SCOPE_OP:
            case AML_DEVICE_OP:
            case AML_THERMAL_ZONE_OP:

                AcpiOsPrintf (")");
                break;

            default:

                AcpiOsPrintf ("*** Unhandled named opcode %X\n",
                    Op->Common.AmlOpcode);
                break;
            }
        }

        else switch (Op->Common.AmlOpcode)
        {
        case AML_FIELD_OP:
        case AML_BANK_FIELD_OP:
        case AML_INDEX_FIELD_OP:

            Info->BitOffset = 0;

            /* Name of the parent OperationRegion */

            NextOp = AcpiPsGetDepthNext (NULL, Op);
            AcpiDmNamestring (NextOp->Common.Value.Name);
            AcpiOsPrintf (", ");
            NextOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;

            switch (Op->Common.AmlOpcode)
            {
            case AML_BANK_FIELD_OP:

                /* Namestring - Bank Name */

                NextOp = AcpiPsGetDepthNext (NULL, NextOp);
                AcpiDmNamestring (NextOp->Common.Value.Name);
                NextOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
                AcpiOsPrintf (", ");

                /*
                 * Bank Value. This is a TermArg in the middle of the parameter
                 * list, must handle it here.
                 *
                 * Disassemble the TermArg parse tree. ACPI_PARSEOP_PARAMLIST
                 * eliminates newline in the output.
                 */
                NextOp = NextOp->Common.Next;

                Info->Flags = ACPI_PARSEOP_PARAMLIST;
                AcpiDmWalkParseTree (NextOp, AcpiDmDescendingOp,
                    AcpiDmAscendingOp, Info);
                Info->Flags = 0;
                Info->Level = Level;

                NextOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
                AcpiOsPrintf (", ");
                break;

            case AML_INDEX_FIELD_OP:

                /* Namestring - Data Name */

                NextOp = AcpiPsGetDepthNext (NULL, NextOp);
                AcpiDmNamestring (NextOp->Common.Value.Name);
                AcpiOsPrintf (", ");
                NextOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
                break;

            default:

                break;
            }

            AcpiDmFieldFlags (NextOp);
            break;

        case AML_BUFFER_OP:

            /* The next op is the size parameter */

            NextOp = AcpiPsGetDepthNext (NULL, Op);
            if (!NextOp)
            {
                /* Single-step support */

                return (AE_OK);
            }

            if (Op->Common.DisasmOpcode == ACPI_DASM_RESOURCE)
            {
                /*
                 * We have a resource list. Don't need to output
                 * the buffer size Op. Open up a new block
                 */
                NextOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
                NextOp = NextOp->Common.Next;
                AcpiOsPrintf (")");

                /* Emit description comment for Name() with a predefined ACPI name */

                AcpiDmPredefinedDescription (Op->Asl.Parent);

                AcpiOsPrintf ("\n");
                AcpiDmIndent (Info->Level);
                AcpiOsPrintf ("{\n");
                return (AE_OK);
            }

            /* Normal Buffer, mark size as in the parameter list */

            NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST;
            return (AE_OK);

        case AML_VAR_PACKAGE_OP:
        case AML_IF_OP:
        case AML_WHILE_OP:

            /* The next op is the size or predicate parameter */

            NextOp = AcpiPsGetDepthNext (NULL, Op);
            if (NextOp)
            {
                NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST;
            }
            return (AE_OK);

        case AML_PACKAGE_OP:

            /* The next op is the size parameter */

            NextOp = AcpiPsGetDepthNext (NULL, Op);
            if (NextOp)
            {
                NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST;
            }
            return (AE_OK);

        case AML_MATCH_OP:

            AcpiDmMatchOp (Op);
            break;

        default:

            break;
        }

        if (AcpiDmBlockType (Op) & BLOCK_BRACE)
        {
            AcpiOsPrintf ("\n");
            AcpiDmIndent (Level);
            AcpiOsPrintf ("{\n");
        }
    }

    return (AE_OK);
}
Пример #30
0
static acpi_status acpi_ps_get_aml_opcode(struct acpi_walk_state *walk_state)
{
	u32 aml_offset;

	ACPI_FUNCTION_TRACE_PTR(ps_get_aml_opcode, walk_state);

	walk_state->aml = walk_state->parser_state.aml;
	walk_state->opcode = acpi_ps_peek_opcode(&(walk_state->parser_state));

	/*
	 * First cut to determine what we have found:
	 * 1) A valid AML opcode
	 * 2) A name string
	 * 3) An unknown/invalid opcode
	 */
	walk_state->op_info = acpi_ps_get_opcode_info(walk_state->opcode);

	switch (walk_state->op_info->class) {
	case AML_CLASS_ASCII:
	case AML_CLASS_PREFIX:
		/*
		 * Starts with a valid prefix or ASCII char, this is a name
		 * string. Convert the bare name string to a namepath.
		 */
		walk_state->opcode = AML_INT_NAMEPATH_OP;
		walk_state->arg_types = ARGP_NAMESTRING;
		break;

	case AML_CLASS_UNKNOWN:

		/* The opcode is unrecognized. Complain and skip unknown opcodes */

		if (walk_state->pass_number == 2) {
			aml_offset = (u32)ACPI_PTR_DIFF(walk_state->aml,
							walk_state->
							parser_state.aml_start);

			ACPI_ERROR((AE_INFO,
				    "Unknown opcode 0x%.2X at table offset 0x%.4X, ignoring",
				    walk_state->opcode,
				    (u32)(aml_offset +
					  sizeof(struct acpi_table_header))));

			ACPI_DUMP_BUFFER((walk_state->parser_state.aml - 16),
					 48);

#ifdef ACPI_ASL_COMPILER
			/*
			 * This is executed for the disassembler only. Output goes
			 * to the disassembled ASL output file.
			 */
			acpi_os_printf
			    ("/*\nError: Unknown opcode 0x%.2X at table offset 0x%.4X, context:\n",
			     walk_state->opcode,
			     (u32)(aml_offset +
				   sizeof(struct acpi_table_header)));

			ACPI_ERROR((AE_INFO,
				    "Aborting disassembly, AML byte code is corrupt"));

			/* Dump the context surrounding the invalid opcode */

			acpi_ut_dump_buffer(((u8 *)walk_state->parser_state.
					     aml - 16), 48, DB_BYTE_DISPLAY,
					    (aml_offset +
					     sizeof(struct acpi_table_header) -
					     16));
			acpi_os_printf(" */\n");

			/*
			 * Just abort the disassembly, cannot continue because the
			 * parser is essentially lost. The disassembler can then
			 * randomly fail because an ill-constructed parse tree
			 * can result.
			 */
			return_ACPI_STATUS(AE_AML_BAD_OPCODE);
#endif
		}

		/* Increment past one-byte or two-byte opcode */

		walk_state->parser_state.aml++;
		if (walk_state->opcode > 0xFF) {	/* Can only happen if first byte is 0x5B */
			walk_state->parser_state.aml++;
		}

		return_ACPI_STATUS(AE_CTRL_PARSE_CONTINUE);

	default:

		/* Found opcode info, this is a normal opcode */

		walk_state->parser_state.aml +=
		    acpi_ps_get_opcode_size(walk_state->opcode);
		walk_state->arg_types = walk_state->op_info->parse_args;
		break;
	}

	return_ACPI_STATUS(AE_OK);
}