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); }
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); }
/** * 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; }
/** * 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; }
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); }
/** * 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; }
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); }
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); }
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); }
void AcpiUtInitStackPtrTrace ( void) { UINT32 CurrentSp; AcpiGbl_EntryStackPointer = ACPI_PTR_DIFF (&CurrentSp, NULL); }
void acpi_ut_init_stack_ptr_trace ( void) { u32 current_sp; acpi_gbl_entry_stack_pointer = ACPI_PTR_DIFF (¤t_sp, NULL); }
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); }
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); }
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); }
void acpi_ut_track_stack_ptr(void) { acpi_size current_sp; current_sp = ACPI_PTR_DIFF(¤t_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; } }
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; } }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }