diff options
Diffstat (limited to 'drivers/acpi/acpica/psloop.c')
| -rw-r--r-- | drivers/acpi/acpica/psloop.c | 61 | 
1 files changed, 47 insertions, 14 deletions
diff --git a/drivers/acpi/acpica/psloop.c b/drivers/acpi/acpica/psloop.c index 799162c1b6d..5607805aab2 100644 --- a/drivers/acpi/acpica/psloop.c +++ b/drivers/acpi/acpica/psloop.c @@ -133,18 +133,46 @@ static acpi_status acpi_ps_get_aml_opcode(struct acpi_walk_state *walk_state)  	case AML_CLASS_UNKNOWN: -		/* The opcode is unrecognized. Just skip unknown opcodes */ +		/* The opcode is unrecognized. Complain and skip unknown opcodes */ -		ACPI_ERROR((AE_INFO, -			    "Found unknown opcode 0x%X at AML address %p offset 0x%X, ignoring", -			    walk_state->opcode, walk_state->parser_state.aml, -			    walk_state->aml_offset)); +		if (walk_state->pass_number == 2) { +			ACPI_ERROR((AE_INFO, +				    "Unknown opcode 0x%.2X at table offset 0x%.4X, ignoring", +				    walk_state->opcode, +				    (u32)(walk_state->aml_offset + +					  sizeof(struct acpi_table_header)))); -		ACPI_DUMP_BUFFER(walk_state->parser_state.aml, 128); +			ACPI_DUMP_BUFFER(walk_state->parser_state.aml - 16, 48); -		/* Assume one-byte bad opcode */ +#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)(walk_state->aml_offset + +				   sizeof(struct acpi_table_header))); + +			/* Dump the context surrounding the invalid opcode */ + +			acpi_ut_dump_buffer(((u8 *)walk_state->parser_state. +					     aml - 16), 48, DB_BYTE_DISPLAY, +					    walk_state->aml_offset + +					    sizeof(struct acpi_table_header) - +					    16); +			acpi_os_printf(" */\n"); +#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: @@ -519,11 +547,18 @@ acpi_ps_get_arguments(struct acpi_walk_state *walk_state,  					if ((op_info->class ==  					     AML_CLASS_EXECUTE) && (!arg)) {  						ACPI_WARNING((AE_INFO, -							      "Detected an unsupported executable opcode " -							      "at module-level: [0x%.4X] at table offset 0x%.4X", -							      op->common.aml_opcode, -							      (u32)((aml_op_start - walk_state->parser_state.aml_start) -								+ sizeof(struct acpi_table_header)))); +							      "Unsupported module-level executable opcode " +							      "0x%.2X at table offset 0x%.4X", +							      op->common. +							      aml_opcode, +							      (u32) +							      (ACPI_PTR_DIFF +							       (aml_op_start, +								walk_state-> +								parser_state. +								aml_start) + +							       sizeof(struct +								      acpi_table_header))));  					}  				}  				break; @@ -843,8 +878,6 @@ acpi_ps_complete_op(struct acpi_walk_state *walk_state,  		*op = NULL;  	} -	ACPI_PREEMPTION_POINT(); -  	return_ACPI_STATUS(AE_OK);  }  |