Message ID | 1355615318-28765-5-git-send-email-colin.king@canonical.com |
---|---|
State | Accepted |
Headers | show |
On Sun, Dec 16, 2012 at 7:48 AM, Colin King <colin.king@canonical.com> wrote: > From: Colin Ian King <colin.king@canonical.com> > > Rename fwts_acpi_method.{c,h} to fwts_acpi_object_eval.{c,h}. > This also means renaming the included headers in tests method and > pcc as well as changing the makefile. > > Signed-off-by: Colin Ian King <colin.king@canonical.com> > --- > src/acpi/method/method.c | 2 +- > src/acpi/pcc/pcc.c | 2 +- > src/lib/include/fwts_acpi_method.h | 36 ---- > src/lib/include/fwts_acpi_object_eval.h | 36 ++++ > src/lib/src/Makefile.am | 2 +- > src/lib/src/fwts_acpi_method.c | 295 -------------------------------- > src/lib/src/fwts_acpi_object_eval.c | 295 ++++++++++++++++++++++++++++++++ > 7 files changed, 334 insertions(+), 334 deletions(-) > delete mode 100644 src/lib/include/fwts_acpi_method.h > create mode 100644 src/lib/include/fwts_acpi_object_eval.h > delete mode 100644 src/lib/src/fwts_acpi_method.c > create mode 100644 src/lib/src/fwts_acpi_object_eval.c > > diff --git a/src/acpi/method/method.c b/src/acpi/method/method.c > index 63fcd94..f7df732 100644 > --- a/src/acpi/method/method.c > +++ b/src/acpi/method/method.c > @@ -28,7 +28,7 @@ > > /* acpica headers */ > #include "acpi.h" > -#include "fwts_acpi_method.h" > +#include "fwts_acpi_object_eval.h" > > /* > * ACPI methods + objects used in Linux ACPI driver: > diff --git a/src/acpi/pcc/pcc.c b/src/acpi/pcc/pcc.c > index 6660196..8741e0b 100644 > --- a/src/acpi/pcc/pcc.c > +++ b/src/acpi/pcc/pcc.c > @@ -28,7 +28,7 @@ > > /* acpica headers */ > #include "acpi.h" > -#include "fwts_acpi_method.h" > +#include "fwts_acpi_object_eval.h" > > /* > * This test does some sanity checking on the PCC interface, > diff --git a/src/lib/include/fwts_acpi_method.h b/src/lib/include/fwts_acpi_method.h > deleted file mode 100644 > index 76e3e46..0000000 > --- a/src/lib/include/fwts_acpi_method.h > +++ /dev/null > @@ -1,36 +0,0 @@ > -/* > - * Copyright (C) 2010-2012 Canonical > - * > - * This program is free software; you can redistribute it and/or > - * modify it under the terms of the GNU General Public License > - * as published by the Free Software Foundation; either version 2 > - * of the License, or (at your option) any later version. > - * > - * This program is distributed in the hope that it will be useful, > - * but WITHOUT ANY WARRANTY; without even the implied warranty of > - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > - * GNU General Public License for more details. > - * > - * You should have received a copy of the GNU General Public License > - * along with this program; if not, write to the Free Software > - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. > - * > - */ > - > -#ifndef __FWTS_ACPI_METHOD_H__ > -#define __FWTS_ACPI_METHOD_H__ > - > -#include "fwts.h" > - > -/* acpica headers */ > -#include "acpi.h" > - > -int fwts_acpi_init(fwts_framework *fw); > -int fwts_acpi_deinit(fwts_framework *fw); > -char *fwts_acpi_object_exists(const char *name); > -fwts_list *fwts_acpi_object_get_names(void); > -void fwts_acpi_object_dump(fwts_framework *fw, const ACPI_OBJECT *obj); > -void fwts_acpi_object_evaluate_report_error(fwts_framework *fw, const char *name, const ACPI_STATUS status); > -ACPI_STATUS fwts_acpi_object_evaluate(fwts_framework *fw, char *name, ACPI_OBJECT_LIST *arg_list, ACPI_BUFFER *buf); > - > -#endif > diff --git a/src/lib/include/fwts_acpi_object_eval.h b/src/lib/include/fwts_acpi_object_eval.h > new file mode 100644 > index 0000000..76e3e46 > --- /dev/null > +++ b/src/lib/include/fwts_acpi_object_eval.h > @@ -0,0 +1,36 @@ > +/* > + * Copyright (C) 2010-2012 Canonical > + * > + * This program is free software; you can redistribute it and/or > + * modify it under the terms of the GNU General Public License > + * as published by the Free Software Foundation; either version 2 > + * of the License, or (at your option) any later version. > + * > + * This program is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > + * GNU General Public License for more details. > + * > + * You should have received a copy of the GNU General Public License > + * along with this program; if not, write to the Free Software > + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. > + * > + */ > + > +#ifndef __FWTS_ACPI_METHOD_H__ > +#define __FWTS_ACPI_METHOD_H__ > + > +#include "fwts.h" > + > +/* acpica headers */ > +#include "acpi.h" > + > +int fwts_acpi_init(fwts_framework *fw); > +int fwts_acpi_deinit(fwts_framework *fw); > +char *fwts_acpi_object_exists(const char *name); > +fwts_list *fwts_acpi_object_get_names(void); > +void fwts_acpi_object_dump(fwts_framework *fw, const ACPI_OBJECT *obj); > +void fwts_acpi_object_evaluate_report_error(fwts_framework *fw, const char *name, const ACPI_STATUS status); > +ACPI_STATUS fwts_acpi_object_evaluate(fwts_framework *fw, char *name, ACPI_OBJECT_LIST *arg_list, ACPI_BUFFER *buf); > + > +#endif > diff --git a/src/lib/src/Makefile.am b/src/lib/src/Makefile.am > index 65a2e55..a91d9ab 100644 > --- a/src/lib/src/Makefile.am > +++ b/src/lib/src/Makefile.am > @@ -17,7 +17,7 @@ libfwts_la_LDFLAGS = \ > # > libfwts_la_SOURCES = \ > fwts_ac_adapter.c \ > - fwts_acpi_method.c \ > + fwts_acpi_object_eval.c \ > fwts_acpi_tables.c \ > fwts_acpi.c \ > fwts_acpid.c \ > diff --git a/src/lib/src/fwts_acpi_method.c b/src/lib/src/fwts_acpi_method.c > deleted file mode 100644 > index 8427e4c..0000000 > --- a/src/lib/src/fwts_acpi_method.c > +++ /dev/null > @@ -1,295 +0,0 @@ > -/* > - * Copyright (C) 2010-2012 Canonical > - * > - * This program is free software; you can redistribute it and/or > - * modify it under the terms of the GNU General Public License > - * as published by the Free Software Foundation; either version 2 > - * of the License, or (at your option) any later version. > - * > - * This program is distributed in the hope that it will be useful, > - * but WITHOUT ANY WARRANTY; without even the implied warranty of > - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > - * GNU General Public License for more details. > - * > - * You should have received a copy of the GNU General Public License > - * along with this program; if not, write to the Free Software > - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. > - * > - */ > -#include "fwts.h" > - > -#include <stdio.h> > -#include <stdlib.h> > -#include <string.h> > -#include <unistd.h> > - > -/* acpica headers */ > -#include "acpi.h" > -#include "fwts_acpi_method.h" > - > -typedef struct { > - const ACPI_STATUS status; > - const fwts_log_level level; > - const char *error_type; > - const char *error_text; > -} acpi_eval_error; > - > -static const acpi_eval_error errors[] = { > - /* ACPI_STATUS fwts_log_level error_type error_text */ > - { AE_ERROR, LOG_LEVEL_HIGH, "AEError", "Environment error" }, > - { AE_NO_ACPI_TABLES, LOG_LEVEL_HIGH, "AENoACPITables", "NO ACPI tables" }, > - { AE_NO_NAMESPACE, LOG_LEVEL_HIGH, "AENoNamespace", "No namespace" }, > - { AE_NO_MEMORY, LOG_LEVEL_CRITICAL, "AENoMemory", "Out of memory" }, > - { AE_NOT_FOUND, LOG_LEVEL_CRITICAL, "AENotFound", "Not found" }, > - { AE_NOT_EXIST, LOG_LEVEL_CRITICAL, "AENotExist", "Not exist" }, > - { AE_ALREADY_EXISTS, LOG_LEVEL_HIGH, "AEAlreadyExists", "Already exists" }, > - { AE_TYPE, LOG_LEVEL_CRITICAL, "AETtype", "Type" }, > - { AE_NULL_OBJECT, LOG_LEVEL_CRITICAL, "AENullObject", "Null object" }, > - { AE_NULL_ENTRY, LOG_LEVEL_CRITICAL, "AENullEntry", "Null entry" }, > - { AE_BUFFER_OVERFLOW, LOG_LEVEL_CRITICAL, "AEBufferOverflow", "Buffer overflow" }, > - { AE_STACK_OVERFLOW, LOG_LEVEL_CRITICAL, "AEStackOverflow", "Stack overflow" }, > - { AE_STACK_UNDERFLOW, LOG_LEVEL_CRITICAL, "AEStackUnderflow", "Stack underflow" }, > - { AE_NOT_IMPLEMENTED, LOG_LEVEL_HIGH, "AENotImplemented", "Not implemented" }, > - { AE_SUPPORT, LOG_LEVEL_HIGH, "AESupport", "Support" }, > - { AE_LIMIT, LOG_LEVEL_CRITICAL, "AELimit", "Limit" }, > - { AE_TIME, LOG_LEVEL_HIGH, "AETime", "Timeout" }, > - { AE_ACQUIRE_DEADLOCK, LOG_LEVEL_CRITICAL, "AEAcqDeadlock", "Acquire deadlock" }, > - { AE_RELEASE_DEADLOCK, LOG_LEVEL_CRITICAL, "AERelDeadlock", "Release deadlock" }, > - { AE_NOT_ACQUIRED, LOG_LEVEL_CRITICAL, "AENotAcq", "Not acquired" }, > - { AE_ALREADY_ACQUIRED, LOG_LEVEL_CRITICAL, "AEAlreadyAcq", "Already acquired" }, > - { AE_NO_HARDWARE_RESPONSE, LOG_LEVEL_HIGH, "AENoHWResponse", "No hardware response" }, > - { AE_NO_GLOBAL_LOCK, LOG_LEVEL_HIGH, "AENoGlobalLock", "No global lock" }, > - { AE_ABORT_METHOD, LOG_LEVEL_CRITICAL, "AEAbortMethod", "Abort method" }, > - { AE_SAME_HANDLER, LOG_LEVEL_HIGH, "AESameHandler", "Same handler" }, > - { AE_NO_HANDLER, LOG_LEVEL_CRITICAL, "AENoHandler", "No handler" }, > - { AE_OWNER_ID_LIMIT, LOG_LEVEL_HIGH, "AEOwnerIDLimit", "Owner ID limit" }, > - > - { AE_BAD_PARAMETER, LOG_LEVEL_HIGH, "AEBadParam", "Args: Bad paramater" }, > - { AE_BAD_CHARACTER, LOG_LEVEL_HIGH, "AEBadChar", "Args: Bad character" }, > - { AE_BAD_PATHNAME, LOG_LEVEL_HIGH, "AEBadPathname", "Args: Bad pathname" }, > - { AE_BAD_DATA, LOG_LEVEL_HIGH, "AEBadData", "Args: Bad data" }, > - { AE_BAD_HEX_CONSTANT, LOG_LEVEL_HIGH, "AEBadHexConst", "Args: Bad hex constant" }, > - { AE_BAD_OCTAL_CONSTANT, LOG_LEVEL_HIGH, "AEBadOctConst", "Args: Bad octal constant" }, > - { AE_BAD_DECIMAL_CONSTANT, LOG_LEVEL_HIGH, "AEBadDecConst", "Args: Bad decimal constant" }, > - { AE_MISSING_ARGUMENTS, LOG_LEVEL_CRITICAL, "AEMissingArgs", "Args: Missing arguments" }, > - { AE_BAD_ADDRESS, LOG_LEVEL_CRITICAL, "AEBadAddr", "Args: Bad address" }, > - > - { AE_AML_BAD_OPCODE, LOG_LEVEL_CRITICAL, "AEAMLBadOpCode", "Bad AML opcode" }, > - { AE_AML_NO_OPERAND, LOG_LEVEL_HIGH, "AEAMLNoOperand", "Missing operand" }, > - { AE_AML_OPERAND_TYPE, LOG_LEVEL_HIGH, "AEAMLOperandType", "Incorrect operand type" }, > - { AE_AML_OPERAND_VALUE, LOG_LEVEL_HIGH, "AEAMLOperandValue", "Incorrect operand value" }, > - { AE_AML_UNINITIALIZED_LOCAL, LOG_LEVEL_HIGH, "AEAMLUninitLocal", "Uninitialized local variable" }, > - { AE_AML_UNINITIALIZED_ARG, LOG_LEVEL_HIGH, "AEAMLUninitArg", "Uninitialized argument" }, > - { AE_AML_UNINITIALIZED_ELEMENT, LOG_LEVEL_HIGH, "AEAMLUninitElement", "Uninitialized element" }, > - { AE_AML_NUMERIC_OVERFLOW, LOG_LEVEL_HIGH, "AEAMLNumericOverflow", "Numeric overflow" }, > - { AE_AML_REGION_LIMIT, LOG_LEVEL_CRITICAL, "AEAMLRegionLimit", "Region limit" }, > - { AE_AML_BUFFER_LIMIT, LOG_LEVEL_CRITICAL, "AEAMLBufferLimit", "Buffer limit" }, > - { AE_AML_PACKAGE_LIMIT, LOG_LEVEL_CRITICAL, "AEAMLPackgeLimit", "Package limit" }, > - { AE_AML_DIVIDE_BY_ZERO, LOG_LEVEL_CRITICAL, "AEAMLDivideByZero", "Division by zero" }, > - { AE_AML_NAME_NOT_FOUND, LOG_LEVEL_HIGH, "AEAMLNameNotFound", "Name not found" }, > - { AE_AML_INTERNAL, LOG_LEVEL_HIGH, "AEAMLInternal", "Internal ACPICA execution engine error" }, > - { AE_AML_INVALID_SPACE_ID, LOG_LEVEL_HIGH, "AEAMLInvalidSpaceID", "Invalid space ID error" }, > - { AE_AML_STRING_LIMIT, LOG_LEVEL_HIGH, "AEAMLStringLimit", "String limit" }, > - { AE_AML_NO_RETURN_VALUE, LOG_LEVEL_HIGH, "AEAMLNoReturnValue", "No return value" }, > - { AE_AML_METHOD_LIMIT, LOG_LEVEL_HIGH, "AEAMLMethodLimit", "Method limit" }, > - { AE_AML_NOT_OWNER, LOG_LEVEL_HIGH, "AEAMLNotOwner", "Not owner" }, > - { AE_AML_MUTEX_ORDER, LOG_LEVEL_HIGH, "AEAMLMutexOrder", "Mutex order" }, > - { AE_AML_MUTEX_NOT_ACQUIRED, LOG_LEVEL_HIGH, "AEAMLMutexNotAcq", "Mutux not acquired" }, > - { AE_AML_INVALID_RESOURCE_TYPE, LOG_LEVEL_HIGH, "AEAMLInvResourceType", "Invalid resource type" }, > - { AE_AML_INVALID_INDEX, LOG_LEVEL_HIGH, "AEAMLInvIndex", "Invalid index" }, > - { AE_AML_REGISTER_LIMIT, LOG_LEVEL_HIGH, "AEAMLRegisterLimit", "Register limit" }, > - { AE_AML_NO_WHILE, LOG_LEVEL_CRITICAL, "AEAMLNoWhile", "No while" }, > - { AE_AML_ALIGNMENT, LOG_LEVEL_CRITICAL, "AEAMLAlignment", "Misaligmnent" }, > - { AE_AML_NO_RESOURCE_END_TAG, LOG_LEVEL_HIGH, "AEAMLNoResEndTag", "No resource end tag"}, > - { AE_AML_BAD_RESOURCE_VALUE, LOG_LEVEL_HIGH, "AEAMLBadResValue", "Bad resource value" }, > - { AE_AML_CIRCULAR_REFERENCE, LOG_LEVEL_CRITICAL, "AEAMLCircularRef", "Circular reference" }, > - { AE_AML_BAD_RESOURCE_LENGTH, LOG_LEVEL_HIGH, "AEAMLBadResLength", "Bad resource length" }, > - { AE_AML_ILLEGAL_ADDRESS, LOG_LEVEL_CRITICAL, "AEAMLIllegalAddr", "Illegal address" }, > - /* { AE_AML_INFINITE_LOOP, LOG_LEVEL_HIGH, "AEAMLInfiniteLoop", "Infinite loop" }, */ > - { 0, 0, NULL, NULL } > -}; > - > -static fwts_list *fwts_object_names; > -static bool fwts_acpi_initialized = false; > - > -/* > - * fwts_acpi_init() > - * Initialise ACPIA engine and collect method namespace > - */ > -int fwts_acpi_init(fwts_framework *fw) > -{ > - if (fwts_acpica_init(fw) != FWTS_OK) > - return FWTS_ERROR; > - > - /* Gather all object names */ > - fwts_object_names = fwts_acpica_get_object_names(0); > - fwts_acpi_initialized = true; > - > - return FWTS_OK; > -} > - > -/* > - * fwts_acpi_deinit() > - * Close ACPIA engine and free method namespace > - */ > -int fwts_acpi_deinit(fwts_framework *fw) > -{ > - int ret = FWTS_ERROR; > - > - FWTS_UNUSED(fw); > - > - if (fwts_acpi_initialized) { > - fwts_list_free(fwts_object_names, free); > - fwts_object_names = NULL; > - ret = fwts_acpica_deinit(); > - > - fwts_acpi_initialized = false; > - } > - > - return ret; > -} > - > -/* > - * fwts_acpi_object_get_names() > - * return list of object names > - */ > -fwts_list *fwts_acpi_object_get_names(void) > -{ > - return fwts_object_names; > -} > - > -/* > - * fwts_acpi_object_exists() > - * return first matching name > - */ > -char *fwts_acpi_object_exists(const char *name) > -{ > - size_t name_len = strlen(name); > - fwts_list_link *item; > - > - fwts_list_foreach(item, fwts_object_names) { > - char *method_name = fwts_list_data(char*, item); > - size_t len = strlen(method_name); > - > - if (strncmp(name, method_name + len - name_len, name_len) == 0) > - return method_name; > - } > - return NULL; > -} > - > - > -/* > - * fwts_acpi_object_dump_recursive() > - * dump out an object, minimal form > - */ > -static void fwts_acpi_object_dump_recursive( > - fwts_framework *fw, > - const ACPI_OBJECT *obj, > - const int depth, > - const int index) > -{ > - uint32_t i; > - char index_buf[5]; > - > - if (index > -1) > - snprintf(index_buf, sizeof(index_buf), "%2.2d: ", index); > - else > - index_buf[0] = '\0'; > - > - switch (obj->Type) { > - case ACPI_TYPE_INTEGER: > - fwts_log_info_verbatum(fw, "%*s%sINTEGER: 0x%8.8llx", depth * 2, "", > - index_buf, (unsigned long long)obj->Integer.Value); > - break; > - case ACPI_TYPE_STRING: > - fwts_log_info_verbatum(fw, "%*s%sSTRING: %s", depth * 2, "", > - index_buf, obj->String.Pointer); > - break; > - case ACPI_TYPE_BUFFER: > - fwts_log_info_verbatum(fw, "%*s%sBUFFER: (%d bytes)", depth * 2, "", > - index_buf, obj->Buffer.Length); > - break; > - case ACPI_TYPE_PACKAGE: > - fwts_log_info_verbatum(fw, "%*s%sPackage has %d elements:",depth * 2, "", > - index_buf, obj->Package.Count); > - for (i = 0; i < obj->Package.Count; i++) { > - ACPI_OBJECT *element = &obj->Package.Elements[i]; > - fwts_acpi_object_dump_recursive(fw, element, depth + 1, i); > - } > - break; > - default: > - fwts_log_info_verbatum(fw, "%*s%sUnknown type %d\n", depth * 2, "", > - index_buf, obj->Type); > - break; > - } > -} > - > -/* > - * fwts_method_object_dump() > - * dump out an object, minimal form > - */ > -void fwts_acpi_object_dump(fwts_framework *fw, const ACPI_OBJECT *obj) > -{ > - fwts_acpi_object_dump_recursive(fw, obj, 1, -1); > -} > - > -/* > - * fwts_acpi_object_evaluate_report_error() > - * report any errors found during object evaluation > - */ > -void fwts_acpi_object_evaluate_report_error( > - fwts_framework *fw, > - const char *name, > - const ACPI_STATUS status) > -{ > - int i; > - > - /* Generic cases */ > - for (i=0; errors[i].error_type; i++) { > - if (status == errors[i].status) { > - fwts_failed(fw, errors[i].level, errors[i].error_type, > - "Detected error '%s' when evaluating '%s'.", > - errors[i].error_text, name); > - return; > - } > - } > - > - /* Special cases */ > - switch (status) { > - case AE_OK: > - break; > - case AE_AML_INFINITE_LOOP: > - fwts_warning(fw, "Detected an infinite loop when evaluating method '%s'. ", name); > - fwts_advice(fw, "This may occur because we are emulating the execution " > - "in this test environment and cannot handshake with " > - "the embedded controller or jump to the BIOS via SMIs. " > - "However, the fact that AML code spins forever means that " > - "lockup conditions are not being checked for in the AML bytecode."); > - break; > - /* Unknown?! */ > - default: > - fwts_failed(fw, LOG_LEVEL_MEDIUM, "AMLFailedToEvaluate", "Failed to evaluate '%s', got error code %d.", name, status); > - break; > - } > -} > - > -/* > - * fwts_acpi_object_evaluate() > - * evaluate object, return error status (handle this with > - * fwts_method_evaluate_report_error()). > - * This returns buf which auto allocates any return values > - * which need to be freed post-evalutation using free(). > - */ > -ACPI_STATUS fwts_acpi_object_evaluate(fwts_framework *fw, > - char *name, > - ACPI_OBJECT_LIST *arg_list, > - ACPI_BUFFER *buf) > -{ > - FWTS_UNUSED(fw); > - > - buf->Length = ACPI_ALLOCATE_BUFFER; > - buf->Pointer = NULL; > - > - return AcpiEvaluateObject(NULL, name, arg_list, buf); > -} > - > diff --git a/src/lib/src/fwts_acpi_object_eval.c b/src/lib/src/fwts_acpi_object_eval.c > new file mode 100644 > index 0000000..9883c77 > --- /dev/null > +++ b/src/lib/src/fwts_acpi_object_eval.c > @@ -0,0 +1,295 @@ > +/* > + * Copyright (C) 2010-2012 Canonical > + * > + * This program is free software; you can redistribute it and/or > + * modify it under the terms of the GNU General Public License > + * as published by the Free Software Foundation; either version 2 > + * of the License, or (at your option) any later version. > + * > + * This program is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > + * GNU General Public License for more details. > + * > + * You should have received a copy of the GNU General Public License > + * along with this program; if not, write to the Free Software > + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. > + * > + */ > +#include "fwts.h" > + > +#include <stdio.h> > +#include <stdlib.h> > +#include <string.h> > +#include <unistd.h> > + > +/* acpica headers */ > +#include "acpi.h" > +#include "fwts_acpi_object_eval.h" > + > +typedef struct { > + const ACPI_STATUS status; > + const fwts_log_level level; > + const char *error_type; > + const char *error_text; > +} acpi_eval_error; > + > +static const acpi_eval_error errors[] = { > + /* ACPI_STATUS fwts_log_level error_type error_text */ > + { AE_ERROR, LOG_LEVEL_HIGH, "AEError", "Environment error" }, > + { AE_NO_ACPI_TABLES, LOG_LEVEL_HIGH, "AENoACPITables", "NO ACPI tables" }, > + { AE_NO_NAMESPACE, LOG_LEVEL_HIGH, "AENoNamespace", "No namespace" }, > + { AE_NO_MEMORY, LOG_LEVEL_CRITICAL, "AENoMemory", "Out of memory" }, > + { AE_NOT_FOUND, LOG_LEVEL_CRITICAL, "AENotFound", "Not found" }, > + { AE_NOT_EXIST, LOG_LEVEL_CRITICAL, "AENotExist", "Not exist" }, > + { AE_ALREADY_EXISTS, LOG_LEVEL_HIGH, "AEAlreadyExists", "Already exists" }, > + { AE_TYPE, LOG_LEVEL_CRITICAL, "AETtype", "Type" }, > + { AE_NULL_OBJECT, LOG_LEVEL_CRITICAL, "AENullObject", "Null object" }, > + { AE_NULL_ENTRY, LOG_LEVEL_CRITICAL, "AENullEntry", "Null entry" }, > + { AE_BUFFER_OVERFLOW, LOG_LEVEL_CRITICAL, "AEBufferOverflow", "Buffer overflow" }, > + { AE_STACK_OVERFLOW, LOG_LEVEL_CRITICAL, "AEStackOverflow", "Stack overflow" }, > + { AE_STACK_UNDERFLOW, LOG_LEVEL_CRITICAL, "AEStackUnderflow", "Stack underflow" }, > + { AE_NOT_IMPLEMENTED, LOG_LEVEL_HIGH, "AENotImplemented", "Not implemented" }, > + { AE_SUPPORT, LOG_LEVEL_HIGH, "AESupport", "Support" }, > + { AE_LIMIT, LOG_LEVEL_CRITICAL, "AELimit", "Limit" }, > + { AE_TIME, LOG_LEVEL_HIGH, "AETime", "Timeout" }, > + { AE_ACQUIRE_DEADLOCK, LOG_LEVEL_CRITICAL, "AEAcqDeadlock", "Acquire deadlock" }, > + { AE_RELEASE_DEADLOCK, LOG_LEVEL_CRITICAL, "AERelDeadlock", "Release deadlock" }, > + { AE_NOT_ACQUIRED, LOG_LEVEL_CRITICAL, "AENotAcq", "Not acquired" }, > + { AE_ALREADY_ACQUIRED, LOG_LEVEL_CRITICAL, "AEAlreadyAcq", "Already acquired" }, > + { AE_NO_HARDWARE_RESPONSE, LOG_LEVEL_HIGH, "AENoHWResponse", "No hardware response" }, > + { AE_NO_GLOBAL_LOCK, LOG_LEVEL_HIGH, "AENoGlobalLock", "No global lock" }, > + { AE_ABORT_METHOD, LOG_LEVEL_CRITICAL, "AEAbortMethod", "Abort method" }, > + { AE_SAME_HANDLER, LOG_LEVEL_HIGH, "AESameHandler", "Same handler" }, > + { AE_NO_HANDLER, LOG_LEVEL_CRITICAL, "AENoHandler", "No handler" }, > + { AE_OWNER_ID_LIMIT, LOG_LEVEL_HIGH, "AEOwnerIDLimit", "Owner ID limit" }, > + > + { AE_BAD_PARAMETER, LOG_LEVEL_HIGH, "AEBadParam", "Args: Bad paramater" }, > + { AE_BAD_CHARACTER, LOG_LEVEL_HIGH, "AEBadChar", "Args: Bad character" }, > + { AE_BAD_PATHNAME, LOG_LEVEL_HIGH, "AEBadPathname", "Args: Bad pathname" }, > + { AE_BAD_DATA, LOG_LEVEL_HIGH, "AEBadData", "Args: Bad data" }, > + { AE_BAD_HEX_CONSTANT, LOG_LEVEL_HIGH, "AEBadHexConst", "Args: Bad hex constant" }, > + { AE_BAD_OCTAL_CONSTANT, LOG_LEVEL_HIGH, "AEBadOctConst", "Args: Bad octal constant" }, > + { AE_BAD_DECIMAL_CONSTANT, LOG_LEVEL_HIGH, "AEBadDecConst", "Args: Bad decimal constant" }, > + { AE_MISSING_ARGUMENTS, LOG_LEVEL_CRITICAL, "AEMissingArgs", "Args: Missing arguments" }, > + { AE_BAD_ADDRESS, LOG_LEVEL_CRITICAL, "AEBadAddr", "Args: Bad address" }, > + > + { AE_AML_BAD_OPCODE, LOG_LEVEL_CRITICAL, "AEAMLBadOpCode", "Bad AML opcode" }, > + { AE_AML_NO_OPERAND, LOG_LEVEL_HIGH, "AEAMLNoOperand", "Missing operand" }, > + { AE_AML_OPERAND_TYPE, LOG_LEVEL_HIGH, "AEAMLOperandType", "Incorrect operand type" }, > + { AE_AML_OPERAND_VALUE, LOG_LEVEL_HIGH, "AEAMLOperandValue", "Incorrect operand value" }, > + { AE_AML_UNINITIALIZED_LOCAL, LOG_LEVEL_HIGH, "AEAMLUninitLocal", "Uninitialized local variable" }, > + { AE_AML_UNINITIALIZED_ARG, LOG_LEVEL_HIGH, "AEAMLUninitArg", "Uninitialized argument" }, > + { AE_AML_UNINITIALIZED_ELEMENT, LOG_LEVEL_HIGH, "AEAMLUninitElement", "Uninitialized element" }, > + { AE_AML_NUMERIC_OVERFLOW, LOG_LEVEL_HIGH, "AEAMLNumericOverflow", "Numeric overflow" }, > + { AE_AML_REGION_LIMIT, LOG_LEVEL_CRITICAL, "AEAMLRegionLimit", "Region limit" }, > + { AE_AML_BUFFER_LIMIT, LOG_LEVEL_CRITICAL, "AEAMLBufferLimit", "Buffer limit" }, > + { AE_AML_PACKAGE_LIMIT, LOG_LEVEL_CRITICAL, "AEAMLPackgeLimit", "Package limit" }, > + { AE_AML_DIVIDE_BY_ZERO, LOG_LEVEL_CRITICAL, "AEAMLDivideByZero", "Division by zero" }, > + { AE_AML_NAME_NOT_FOUND, LOG_LEVEL_HIGH, "AEAMLNameNotFound", "Name not found" }, > + { AE_AML_INTERNAL, LOG_LEVEL_HIGH, "AEAMLInternal", "Internal ACPICA execution engine error" }, > + { AE_AML_INVALID_SPACE_ID, LOG_LEVEL_HIGH, "AEAMLInvalidSpaceID", "Invalid space ID error" }, > + { AE_AML_STRING_LIMIT, LOG_LEVEL_HIGH, "AEAMLStringLimit", "String limit" }, > + { AE_AML_NO_RETURN_VALUE, LOG_LEVEL_HIGH, "AEAMLNoReturnValue", "No return value" }, > + { AE_AML_METHOD_LIMIT, LOG_LEVEL_HIGH, "AEAMLMethodLimit", "Method limit" }, > + { AE_AML_NOT_OWNER, LOG_LEVEL_HIGH, "AEAMLNotOwner", "Not owner" }, > + { AE_AML_MUTEX_ORDER, LOG_LEVEL_HIGH, "AEAMLMutexOrder", "Mutex order" }, > + { AE_AML_MUTEX_NOT_ACQUIRED, LOG_LEVEL_HIGH, "AEAMLMutexNotAcq", "Mutux not acquired" }, > + { AE_AML_INVALID_RESOURCE_TYPE, LOG_LEVEL_HIGH, "AEAMLInvResourceType", "Invalid resource type" }, > + { AE_AML_INVALID_INDEX, LOG_LEVEL_HIGH, "AEAMLInvIndex", "Invalid index" }, > + { AE_AML_REGISTER_LIMIT, LOG_LEVEL_HIGH, "AEAMLRegisterLimit", "Register limit" }, > + { AE_AML_NO_WHILE, LOG_LEVEL_CRITICAL, "AEAMLNoWhile", "No while" }, > + { AE_AML_ALIGNMENT, LOG_LEVEL_CRITICAL, "AEAMLAlignment", "Misaligmnent" }, > + { AE_AML_NO_RESOURCE_END_TAG, LOG_LEVEL_HIGH, "AEAMLNoResEndTag", "No resource end tag"}, > + { AE_AML_BAD_RESOURCE_VALUE, LOG_LEVEL_HIGH, "AEAMLBadResValue", "Bad resource value" }, > + { AE_AML_CIRCULAR_REFERENCE, LOG_LEVEL_CRITICAL, "AEAMLCircularRef", "Circular reference" }, > + { AE_AML_BAD_RESOURCE_LENGTH, LOG_LEVEL_HIGH, "AEAMLBadResLength", "Bad resource length" }, > + { AE_AML_ILLEGAL_ADDRESS, LOG_LEVEL_CRITICAL, "AEAMLIllegalAddr", "Illegal address" }, > + /* { AE_AML_INFINITE_LOOP, LOG_LEVEL_HIGH, "AEAMLInfiniteLoop", "Infinite loop" }, */ > + { 0, 0, NULL, NULL } > +}; > + > +static fwts_list *fwts_object_names; > +static bool fwts_acpi_initialized = false; > + > +/* > + * fwts_acpi_init() > + * Initialise ACPIA engine and collect method namespace > + */ > +int fwts_acpi_init(fwts_framework *fw) > +{ > + if (fwts_acpica_init(fw) != FWTS_OK) > + return FWTS_ERROR; > + > + /* Gather all object names */ > + fwts_object_names = fwts_acpica_get_object_names(0); > + fwts_acpi_initialized = true; > + > + return FWTS_OK; > +} > + > +/* > + * fwts_acpi_deinit() > + * Close ACPIA engine and free method namespace > + */ > +int fwts_acpi_deinit(fwts_framework *fw) > +{ > + int ret = FWTS_ERROR; > + > + FWTS_UNUSED(fw); > + > + if (fwts_acpi_initialized) { > + fwts_list_free(fwts_object_names, free); > + fwts_object_names = NULL; > + ret = fwts_acpica_deinit(); > + > + fwts_acpi_initialized = false; > + } > + > + return ret; > +} > + > +/* > + * fwts_acpi_object_get_names() > + * return list of object names > + */ > +fwts_list *fwts_acpi_object_get_names(void) > +{ > + return fwts_object_names; > +} > + > +/* > + * fwts_acpi_object_exists() > + * return first matching name > + */ > +char *fwts_acpi_object_exists(const char *name) > +{ > + size_t name_len = strlen(name); > + fwts_list_link *item; > + > + fwts_list_foreach(item, fwts_object_names) { > + char *method_name = fwts_list_data(char*, item); > + size_t len = strlen(method_name); > + > + if (strncmp(name, method_name + len - name_len, name_len) == 0) > + return method_name; > + } > + return NULL; > +} > + > + > +/* > + * fwts_acpi_object_dump_recursive() > + * dump out an object, minimal form > + */ > +static void fwts_acpi_object_dump_recursive( > + fwts_framework *fw, > + const ACPI_OBJECT *obj, > + const int depth, > + const int index) > +{ > + uint32_t i; > + char index_buf[5]; > + > + if (index > -1) > + snprintf(index_buf, sizeof(index_buf), "%2.2d: ", index); > + else > + index_buf[0] = '\0'; > + > + switch (obj->Type) { > + case ACPI_TYPE_INTEGER: > + fwts_log_info_verbatum(fw, "%*s%sINTEGER: 0x%8.8llx", depth * 2, "", > + index_buf, (unsigned long long)obj->Integer.Value); > + break; > + case ACPI_TYPE_STRING: > + fwts_log_info_verbatum(fw, "%*s%sSTRING: %s", depth * 2, "", > + index_buf, obj->String.Pointer); > + break; > + case ACPI_TYPE_BUFFER: > + fwts_log_info_verbatum(fw, "%*s%sBUFFER: (%d bytes)", depth * 2, "", > + index_buf, obj->Buffer.Length); > + break; > + case ACPI_TYPE_PACKAGE: > + fwts_log_info_verbatum(fw, "%*s%sPackage has %d elements:",depth * 2, "", > + index_buf, obj->Package.Count); > + for (i = 0; i < obj->Package.Count; i++) { > + ACPI_OBJECT *element = &obj->Package.Elements[i]; > + fwts_acpi_object_dump_recursive(fw, element, depth + 1, i); > + } > + break; > + default: > + fwts_log_info_verbatum(fw, "%*s%sUnknown type %d\n", depth * 2, "", > + index_buf, obj->Type); > + break; > + } > +} > + > +/* > + * fwts_method_object_dump() > + * dump out an object, minimal form > + */ > +void fwts_acpi_object_dump(fwts_framework *fw, const ACPI_OBJECT *obj) > +{ > + fwts_acpi_object_dump_recursive(fw, obj, 1, -1); > +} > + > +/* > + * fwts_acpi_object_evaluate_report_error() > + * report any errors found during object evaluation > + */ > +void fwts_acpi_object_evaluate_report_error( > + fwts_framework *fw, > + const char *name, > + const ACPI_STATUS status) > +{ > + int i; > + > + /* Generic cases */ > + for (i=0; errors[i].error_type; i++) { > + if (status == errors[i].status) { > + fwts_failed(fw, errors[i].level, errors[i].error_type, > + "Detected error '%s' when evaluating '%s'.", > + errors[i].error_text, name); > + return; > + } > + } > + > + /* Special cases */ > + switch (status) { > + case AE_OK: > + break; > + case AE_AML_INFINITE_LOOP: > + fwts_warning(fw, "Detected an infinite loop when evaluating method '%s'. ", name); > + fwts_advice(fw, "This may occur because we are emulating the execution " > + "in this test environment and cannot handshake with " > + "the embedded controller or jump to the BIOS via SMIs. " > + "However, the fact that AML code spins forever means that " > + "lockup conditions are not being checked for in the AML bytecode."); > + break; > + /* Unknown?! */ > + default: > + fwts_failed(fw, LOG_LEVEL_MEDIUM, "AMLFailedToEvaluate", "Failed to evaluate '%s', got error code %d.", name, status); > + break; > + } > +} > + > +/* > + * fwts_acpi_object_evaluate() > + * evaluate object, return error status (handle this with > + * fwts_method_evaluate_report_error()). > + * This returns buf which auto allocates any return values > + * which need to be freed post-evalutation using free(). > + */ > +ACPI_STATUS fwts_acpi_object_evaluate(fwts_framework *fw, > + char *name, > + ACPI_OBJECT_LIST *arg_list, > + ACPI_BUFFER *buf) > +{ > + FWTS_UNUSED(fw); > + > + buf->Length = ACPI_ALLOCATE_BUFFER; > + buf->Pointer = NULL; > + > + return AcpiEvaluateObject(NULL, name, arg_list, buf); > +} > + > -- > 1.8.0 > > Acked-by: Keng-Yu Lin <kengyu@canonical.com>
On 12/16/2012 07:48 AM, Colin King wrote: > From: Colin Ian King <colin.king@canonical.com> > > Rename fwts_acpi_method.{c,h} to fwts_acpi_object_eval.{c,h}. > This also means renaming the included headers in tests method and > pcc as well as changing the makefile. > > Signed-off-by: Colin Ian King <colin.king@canonical.com> > --- > src/acpi/method/method.c | 2 +- > src/acpi/pcc/pcc.c | 2 +- > src/lib/include/fwts_acpi_method.h | 36 ---- > src/lib/include/fwts_acpi_object_eval.h | 36 ++++ > src/lib/src/Makefile.am | 2 +- > src/lib/src/fwts_acpi_method.c | 295 -------------------------------- > src/lib/src/fwts_acpi_object_eval.c | 295 ++++++++++++++++++++++++++++++++ > 7 files changed, 334 insertions(+), 334 deletions(-) > delete mode 100644 src/lib/include/fwts_acpi_method.h > create mode 100644 src/lib/include/fwts_acpi_object_eval.h > delete mode 100644 src/lib/src/fwts_acpi_method.c > create mode 100644 src/lib/src/fwts_acpi_object_eval.c > > diff --git a/src/acpi/method/method.c b/src/acpi/method/method.c > index 63fcd94..f7df732 100644 > --- a/src/acpi/method/method.c > +++ b/src/acpi/method/method.c > @@ -28,7 +28,7 @@ > > /* acpica headers */ > #include "acpi.h" > -#include "fwts_acpi_method.h" > +#include "fwts_acpi_object_eval.h" > > /* > * ACPI methods + objects used in Linux ACPI driver: > diff --git a/src/acpi/pcc/pcc.c b/src/acpi/pcc/pcc.c > index 6660196..8741e0b 100644 > --- a/src/acpi/pcc/pcc.c > +++ b/src/acpi/pcc/pcc.c > @@ -28,7 +28,7 @@ > > /* acpica headers */ > #include "acpi.h" > -#include "fwts_acpi_method.h" > +#include "fwts_acpi_object_eval.h" > > /* > * This test does some sanity checking on the PCC interface, > diff --git a/src/lib/include/fwts_acpi_method.h b/src/lib/include/fwts_acpi_method.h > deleted file mode 100644 > index 76e3e46..0000000 > --- a/src/lib/include/fwts_acpi_method.h > +++ /dev/null > @@ -1,36 +0,0 @@ > -/* > - * Copyright (C) 2010-2012 Canonical > - * > - * This program is free software; you can redistribute it and/or > - * modify it under the terms of the GNU General Public License > - * as published by the Free Software Foundation; either version 2 > - * of the License, or (at your option) any later version. > - * > - * This program is distributed in the hope that it will be useful, > - * but WITHOUT ANY WARRANTY; without even the implied warranty of > - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > - * GNU General Public License for more details. > - * > - * You should have received a copy of the GNU General Public License > - * along with this program; if not, write to the Free Software > - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. > - * > - */ > - > -#ifndef __FWTS_ACPI_METHOD_H__ > -#define __FWTS_ACPI_METHOD_H__ > - > -#include "fwts.h" > - > -/* acpica headers */ > -#include "acpi.h" > - > -int fwts_acpi_init(fwts_framework *fw); > -int fwts_acpi_deinit(fwts_framework *fw); > -char *fwts_acpi_object_exists(const char *name); > -fwts_list *fwts_acpi_object_get_names(void); > -void fwts_acpi_object_dump(fwts_framework *fw, const ACPI_OBJECT *obj); > -void fwts_acpi_object_evaluate_report_error(fwts_framework *fw, const char *name, const ACPI_STATUS status); > -ACPI_STATUS fwts_acpi_object_evaluate(fwts_framework *fw, char *name, ACPI_OBJECT_LIST *arg_list, ACPI_BUFFER *buf); > - > -#endif > diff --git a/src/lib/include/fwts_acpi_object_eval.h b/src/lib/include/fwts_acpi_object_eval.h > new file mode 100644 > index 0000000..76e3e46 > --- /dev/null > +++ b/src/lib/include/fwts_acpi_object_eval.h > @@ -0,0 +1,36 @@ > +/* > + * Copyright (C) 2010-2012 Canonical > + * > + * This program is free software; you can redistribute it and/or > + * modify it under the terms of the GNU General Public License > + * as published by the Free Software Foundation; either version 2 > + * of the License, or (at your option) any later version. > + * > + * This program is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > + * GNU General Public License for more details. > + * > + * You should have received a copy of the GNU General Public License > + * along with this program; if not, write to the Free Software > + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. > + * > + */ > + > +#ifndef __FWTS_ACPI_METHOD_H__ > +#define __FWTS_ACPI_METHOD_H__ > + > +#include "fwts.h" > + > +/* acpica headers */ > +#include "acpi.h" > + > +int fwts_acpi_init(fwts_framework *fw); > +int fwts_acpi_deinit(fwts_framework *fw); > +char *fwts_acpi_object_exists(const char *name); > +fwts_list *fwts_acpi_object_get_names(void); > +void fwts_acpi_object_dump(fwts_framework *fw, const ACPI_OBJECT *obj); > +void fwts_acpi_object_evaluate_report_error(fwts_framework *fw, const char *name, const ACPI_STATUS status); > +ACPI_STATUS fwts_acpi_object_evaluate(fwts_framework *fw, char *name, ACPI_OBJECT_LIST *arg_list, ACPI_BUFFER *buf); > + > +#endif > diff --git a/src/lib/src/Makefile.am b/src/lib/src/Makefile.am > index 65a2e55..a91d9ab 100644 > --- a/src/lib/src/Makefile.am > +++ b/src/lib/src/Makefile.am > @@ -17,7 +17,7 @@ libfwts_la_LDFLAGS = \ > # > libfwts_la_SOURCES = \ > fwts_ac_adapter.c \ > - fwts_acpi_method.c \ > + fwts_acpi_object_eval.c \ > fwts_acpi_tables.c \ > fwts_acpi.c \ > fwts_acpid.c \ > diff --git a/src/lib/src/fwts_acpi_method.c b/src/lib/src/fwts_acpi_method.c > deleted file mode 100644 > index 8427e4c..0000000 > --- a/src/lib/src/fwts_acpi_method.c > +++ /dev/null > @@ -1,295 +0,0 @@ > -/* > - * Copyright (C) 2010-2012 Canonical > - * > - * This program is free software; you can redistribute it and/or > - * modify it under the terms of the GNU General Public License > - * as published by the Free Software Foundation; either version 2 > - * of the License, or (at your option) any later version. > - * > - * This program is distributed in the hope that it will be useful, > - * but WITHOUT ANY WARRANTY; without even the implied warranty of > - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > - * GNU General Public License for more details. > - * > - * You should have received a copy of the GNU General Public License > - * along with this program; if not, write to the Free Software > - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. > - * > - */ > -#include "fwts.h" > - > -#include <stdio.h> > -#include <stdlib.h> > -#include <string.h> > -#include <unistd.h> > - > -/* acpica headers */ > -#include "acpi.h" > -#include "fwts_acpi_method.h" > - > -typedef struct { > - const ACPI_STATUS status; > - const fwts_log_level level; > - const char *error_type; > - const char *error_text; > -} acpi_eval_error; > - > -static const acpi_eval_error errors[] = { > - /* ACPI_STATUS fwts_log_level error_type error_text */ > - { AE_ERROR, LOG_LEVEL_HIGH, "AEError", "Environment error" }, > - { AE_NO_ACPI_TABLES, LOG_LEVEL_HIGH, "AENoACPITables", "NO ACPI tables" }, > - { AE_NO_NAMESPACE, LOG_LEVEL_HIGH, "AENoNamespace", "No namespace" }, > - { AE_NO_MEMORY, LOG_LEVEL_CRITICAL, "AENoMemory", "Out of memory" }, > - { AE_NOT_FOUND, LOG_LEVEL_CRITICAL, "AENotFound", "Not found" }, > - { AE_NOT_EXIST, LOG_LEVEL_CRITICAL, "AENotExist", "Not exist" }, > - { AE_ALREADY_EXISTS, LOG_LEVEL_HIGH, "AEAlreadyExists", "Already exists" }, > - { AE_TYPE, LOG_LEVEL_CRITICAL, "AETtype", "Type" }, > - { AE_NULL_OBJECT, LOG_LEVEL_CRITICAL, "AENullObject", "Null object" }, > - { AE_NULL_ENTRY, LOG_LEVEL_CRITICAL, "AENullEntry", "Null entry" }, > - { AE_BUFFER_OVERFLOW, LOG_LEVEL_CRITICAL, "AEBufferOverflow", "Buffer overflow" }, > - { AE_STACK_OVERFLOW, LOG_LEVEL_CRITICAL, "AEStackOverflow", "Stack overflow" }, > - { AE_STACK_UNDERFLOW, LOG_LEVEL_CRITICAL, "AEStackUnderflow", "Stack underflow" }, > - { AE_NOT_IMPLEMENTED, LOG_LEVEL_HIGH, "AENotImplemented", "Not implemented" }, > - { AE_SUPPORT, LOG_LEVEL_HIGH, "AESupport", "Support" }, > - { AE_LIMIT, LOG_LEVEL_CRITICAL, "AELimit", "Limit" }, > - { AE_TIME, LOG_LEVEL_HIGH, "AETime", "Timeout" }, > - { AE_ACQUIRE_DEADLOCK, LOG_LEVEL_CRITICAL, "AEAcqDeadlock", "Acquire deadlock" }, > - { AE_RELEASE_DEADLOCK, LOG_LEVEL_CRITICAL, "AERelDeadlock", "Release deadlock" }, > - { AE_NOT_ACQUIRED, LOG_LEVEL_CRITICAL, "AENotAcq", "Not acquired" }, > - { AE_ALREADY_ACQUIRED, LOG_LEVEL_CRITICAL, "AEAlreadyAcq", "Already acquired" }, > - { AE_NO_HARDWARE_RESPONSE, LOG_LEVEL_HIGH, "AENoHWResponse", "No hardware response" }, > - { AE_NO_GLOBAL_LOCK, LOG_LEVEL_HIGH, "AENoGlobalLock", "No global lock" }, > - { AE_ABORT_METHOD, LOG_LEVEL_CRITICAL, "AEAbortMethod", "Abort method" }, > - { AE_SAME_HANDLER, LOG_LEVEL_HIGH, "AESameHandler", "Same handler" }, > - { AE_NO_HANDLER, LOG_LEVEL_CRITICAL, "AENoHandler", "No handler" }, > - { AE_OWNER_ID_LIMIT, LOG_LEVEL_HIGH, "AEOwnerIDLimit", "Owner ID limit" }, > - > - { AE_BAD_PARAMETER, LOG_LEVEL_HIGH, "AEBadParam", "Args: Bad paramater" }, > - { AE_BAD_CHARACTER, LOG_LEVEL_HIGH, "AEBadChar", "Args: Bad character" }, > - { AE_BAD_PATHNAME, LOG_LEVEL_HIGH, "AEBadPathname", "Args: Bad pathname" }, > - { AE_BAD_DATA, LOG_LEVEL_HIGH, "AEBadData", "Args: Bad data" }, > - { AE_BAD_HEX_CONSTANT, LOG_LEVEL_HIGH, "AEBadHexConst", "Args: Bad hex constant" }, > - { AE_BAD_OCTAL_CONSTANT, LOG_LEVEL_HIGH, "AEBadOctConst", "Args: Bad octal constant" }, > - { AE_BAD_DECIMAL_CONSTANT, LOG_LEVEL_HIGH, "AEBadDecConst", "Args: Bad decimal constant" }, > - { AE_MISSING_ARGUMENTS, LOG_LEVEL_CRITICAL, "AEMissingArgs", "Args: Missing arguments" }, > - { AE_BAD_ADDRESS, LOG_LEVEL_CRITICAL, "AEBadAddr", "Args: Bad address" }, > - > - { AE_AML_BAD_OPCODE, LOG_LEVEL_CRITICAL, "AEAMLBadOpCode", "Bad AML opcode" }, > - { AE_AML_NO_OPERAND, LOG_LEVEL_HIGH, "AEAMLNoOperand", "Missing operand" }, > - { AE_AML_OPERAND_TYPE, LOG_LEVEL_HIGH, "AEAMLOperandType", "Incorrect operand type" }, > - { AE_AML_OPERAND_VALUE, LOG_LEVEL_HIGH, "AEAMLOperandValue", "Incorrect operand value" }, > - { AE_AML_UNINITIALIZED_LOCAL, LOG_LEVEL_HIGH, "AEAMLUninitLocal", "Uninitialized local variable" }, > - { AE_AML_UNINITIALIZED_ARG, LOG_LEVEL_HIGH, "AEAMLUninitArg", "Uninitialized argument" }, > - { AE_AML_UNINITIALIZED_ELEMENT, LOG_LEVEL_HIGH, "AEAMLUninitElement", "Uninitialized element" }, > - { AE_AML_NUMERIC_OVERFLOW, LOG_LEVEL_HIGH, "AEAMLNumericOverflow", "Numeric overflow" }, > - { AE_AML_REGION_LIMIT, LOG_LEVEL_CRITICAL, "AEAMLRegionLimit", "Region limit" }, > - { AE_AML_BUFFER_LIMIT, LOG_LEVEL_CRITICAL, "AEAMLBufferLimit", "Buffer limit" }, > - { AE_AML_PACKAGE_LIMIT, LOG_LEVEL_CRITICAL, "AEAMLPackgeLimit", "Package limit" }, > - { AE_AML_DIVIDE_BY_ZERO, LOG_LEVEL_CRITICAL, "AEAMLDivideByZero", "Division by zero" }, > - { AE_AML_NAME_NOT_FOUND, LOG_LEVEL_HIGH, "AEAMLNameNotFound", "Name not found" }, > - { AE_AML_INTERNAL, LOG_LEVEL_HIGH, "AEAMLInternal", "Internal ACPICA execution engine error" }, > - { AE_AML_INVALID_SPACE_ID, LOG_LEVEL_HIGH, "AEAMLInvalidSpaceID", "Invalid space ID error" }, > - { AE_AML_STRING_LIMIT, LOG_LEVEL_HIGH, "AEAMLStringLimit", "String limit" }, > - { AE_AML_NO_RETURN_VALUE, LOG_LEVEL_HIGH, "AEAMLNoReturnValue", "No return value" }, > - { AE_AML_METHOD_LIMIT, LOG_LEVEL_HIGH, "AEAMLMethodLimit", "Method limit" }, > - { AE_AML_NOT_OWNER, LOG_LEVEL_HIGH, "AEAMLNotOwner", "Not owner" }, > - { AE_AML_MUTEX_ORDER, LOG_LEVEL_HIGH, "AEAMLMutexOrder", "Mutex order" }, > - { AE_AML_MUTEX_NOT_ACQUIRED, LOG_LEVEL_HIGH, "AEAMLMutexNotAcq", "Mutux not acquired" }, > - { AE_AML_INVALID_RESOURCE_TYPE, LOG_LEVEL_HIGH, "AEAMLInvResourceType", "Invalid resource type" }, > - { AE_AML_INVALID_INDEX, LOG_LEVEL_HIGH, "AEAMLInvIndex", "Invalid index" }, > - { AE_AML_REGISTER_LIMIT, LOG_LEVEL_HIGH, "AEAMLRegisterLimit", "Register limit" }, > - { AE_AML_NO_WHILE, LOG_LEVEL_CRITICAL, "AEAMLNoWhile", "No while" }, > - { AE_AML_ALIGNMENT, LOG_LEVEL_CRITICAL, "AEAMLAlignment", "Misaligmnent" }, > - { AE_AML_NO_RESOURCE_END_TAG, LOG_LEVEL_HIGH, "AEAMLNoResEndTag", "No resource end tag"}, > - { AE_AML_BAD_RESOURCE_VALUE, LOG_LEVEL_HIGH, "AEAMLBadResValue", "Bad resource value" }, > - { AE_AML_CIRCULAR_REFERENCE, LOG_LEVEL_CRITICAL, "AEAMLCircularRef", "Circular reference" }, > - { AE_AML_BAD_RESOURCE_LENGTH, LOG_LEVEL_HIGH, "AEAMLBadResLength", "Bad resource length" }, > - { AE_AML_ILLEGAL_ADDRESS, LOG_LEVEL_CRITICAL, "AEAMLIllegalAddr", "Illegal address" }, > - /* { AE_AML_INFINITE_LOOP, LOG_LEVEL_HIGH, "AEAMLInfiniteLoop", "Infinite loop" }, */ > - { 0, 0, NULL, NULL } > -}; > - > -static fwts_list *fwts_object_names; > -static bool fwts_acpi_initialized = false; > - > -/* > - * fwts_acpi_init() > - * Initialise ACPIA engine and collect method namespace > - */ > -int fwts_acpi_init(fwts_framework *fw) > -{ > - if (fwts_acpica_init(fw) != FWTS_OK) > - return FWTS_ERROR; > - > - /* Gather all object names */ > - fwts_object_names = fwts_acpica_get_object_names(0); > - fwts_acpi_initialized = true; > - > - return FWTS_OK; > -} > - > -/* > - * fwts_acpi_deinit() > - * Close ACPIA engine and free method namespace > - */ > -int fwts_acpi_deinit(fwts_framework *fw) > -{ > - int ret = FWTS_ERROR; > - > - FWTS_UNUSED(fw); > - > - if (fwts_acpi_initialized) { > - fwts_list_free(fwts_object_names, free); > - fwts_object_names = NULL; > - ret = fwts_acpica_deinit(); > - > - fwts_acpi_initialized = false; > - } > - > - return ret; > -} > - > -/* > - * fwts_acpi_object_get_names() > - * return list of object names > - */ > -fwts_list *fwts_acpi_object_get_names(void) > -{ > - return fwts_object_names; > -} > - > -/* > - * fwts_acpi_object_exists() > - * return first matching name > - */ > -char *fwts_acpi_object_exists(const char *name) > -{ > - size_t name_len = strlen(name); > - fwts_list_link *item; > - > - fwts_list_foreach(item, fwts_object_names) { > - char *method_name = fwts_list_data(char*, item); > - size_t len = strlen(method_name); > - > - if (strncmp(name, method_name + len - name_len, name_len) == 0) > - return method_name; > - } > - return NULL; > -} > - > - > -/* > - * fwts_acpi_object_dump_recursive() > - * dump out an object, minimal form > - */ > -static void fwts_acpi_object_dump_recursive( > - fwts_framework *fw, > - const ACPI_OBJECT *obj, > - const int depth, > - const int index) > -{ > - uint32_t i; > - char index_buf[5]; > - > - if (index > -1) > - snprintf(index_buf, sizeof(index_buf), "%2.2d: ", index); > - else > - index_buf[0] = '\0'; > - > - switch (obj->Type) { > - case ACPI_TYPE_INTEGER: > - fwts_log_info_verbatum(fw, "%*s%sINTEGER: 0x%8.8llx", depth * 2, "", > - index_buf, (unsigned long long)obj->Integer.Value); > - break; > - case ACPI_TYPE_STRING: > - fwts_log_info_verbatum(fw, "%*s%sSTRING: %s", depth * 2, "", > - index_buf, obj->String.Pointer); > - break; > - case ACPI_TYPE_BUFFER: > - fwts_log_info_verbatum(fw, "%*s%sBUFFER: (%d bytes)", depth * 2, "", > - index_buf, obj->Buffer.Length); > - break; > - case ACPI_TYPE_PACKAGE: > - fwts_log_info_verbatum(fw, "%*s%sPackage has %d elements:",depth * 2, "", > - index_buf, obj->Package.Count); > - for (i = 0; i < obj->Package.Count; i++) { > - ACPI_OBJECT *element = &obj->Package.Elements[i]; > - fwts_acpi_object_dump_recursive(fw, element, depth + 1, i); > - } > - break; > - default: > - fwts_log_info_verbatum(fw, "%*s%sUnknown type %d\n", depth * 2, "", > - index_buf, obj->Type); > - break; > - } > -} > - > -/* > - * fwts_method_object_dump() > - * dump out an object, minimal form > - */ > -void fwts_acpi_object_dump(fwts_framework *fw, const ACPI_OBJECT *obj) > -{ > - fwts_acpi_object_dump_recursive(fw, obj, 1, -1); > -} > - > -/* > - * fwts_acpi_object_evaluate_report_error() > - * report any errors found during object evaluation > - */ > -void fwts_acpi_object_evaluate_report_error( > - fwts_framework *fw, > - const char *name, > - const ACPI_STATUS status) > -{ > - int i; > - > - /* Generic cases */ > - for (i=0; errors[i].error_type; i++) { > - if (status == errors[i].status) { > - fwts_failed(fw, errors[i].level, errors[i].error_type, > - "Detected error '%s' when evaluating '%s'.", > - errors[i].error_text, name); > - return; > - } > - } > - > - /* Special cases */ > - switch (status) { > - case AE_OK: > - break; > - case AE_AML_INFINITE_LOOP: > - fwts_warning(fw, "Detected an infinite loop when evaluating method '%s'. ", name); > - fwts_advice(fw, "This may occur because we are emulating the execution " > - "in this test environment and cannot handshake with " > - "the embedded controller or jump to the BIOS via SMIs. " > - "However, the fact that AML code spins forever means that " > - "lockup conditions are not being checked for in the AML bytecode."); > - break; > - /* Unknown?! */ > - default: > - fwts_failed(fw, LOG_LEVEL_MEDIUM, "AMLFailedToEvaluate", "Failed to evaluate '%s', got error code %d.", name, status); > - break; > - } > -} > - > -/* > - * fwts_acpi_object_evaluate() > - * evaluate object, return error status (handle this with > - * fwts_method_evaluate_report_error()). > - * This returns buf which auto allocates any return values > - * which need to be freed post-evalutation using free(). > - */ > -ACPI_STATUS fwts_acpi_object_evaluate(fwts_framework *fw, > - char *name, > - ACPI_OBJECT_LIST *arg_list, > - ACPI_BUFFER *buf) > -{ > - FWTS_UNUSED(fw); > - > - buf->Length = ACPI_ALLOCATE_BUFFER; > - buf->Pointer = NULL; > - > - return AcpiEvaluateObject(NULL, name, arg_list, buf); > -} > - > diff --git a/src/lib/src/fwts_acpi_object_eval.c b/src/lib/src/fwts_acpi_object_eval.c > new file mode 100644 > index 0000000..9883c77 > --- /dev/null > +++ b/src/lib/src/fwts_acpi_object_eval.c > @@ -0,0 +1,295 @@ > +/* > + * Copyright (C) 2010-2012 Canonical > + * > + * This program is free software; you can redistribute it and/or > + * modify it under the terms of the GNU General Public License > + * as published by the Free Software Foundation; either version 2 > + * of the License, or (at your option) any later version. > + * > + * This program is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > + * GNU General Public License for more details. > + * > + * You should have received a copy of the GNU General Public License > + * along with this program; if not, write to the Free Software > + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. > + * > + */ > +#include "fwts.h" > + > +#include <stdio.h> > +#include <stdlib.h> > +#include <string.h> > +#include <unistd.h> > + > +/* acpica headers */ > +#include "acpi.h" > +#include "fwts_acpi_object_eval.h" > + > +typedef struct { > + const ACPI_STATUS status; > + const fwts_log_level level; > + const char *error_type; > + const char *error_text; > +} acpi_eval_error; > + > +static const acpi_eval_error errors[] = { > + /* ACPI_STATUS fwts_log_level error_type error_text */ > + { AE_ERROR, LOG_LEVEL_HIGH, "AEError", "Environment error" }, > + { AE_NO_ACPI_TABLES, LOG_LEVEL_HIGH, "AENoACPITables", "NO ACPI tables" }, > + { AE_NO_NAMESPACE, LOG_LEVEL_HIGH, "AENoNamespace", "No namespace" }, > + { AE_NO_MEMORY, LOG_LEVEL_CRITICAL, "AENoMemory", "Out of memory" }, > + { AE_NOT_FOUND, LOG_LEVEL_CRITICAL, "AENotFound", "Not found" }, > + { AE_NOT_EXIST, LOG_LEVEL_CRITICAL, "AENotExist", "Not exist" }, > + { AE_ALREADY_EXISTS, LOG_LEVEL_HIGH, "AEAlreadyExists", "Already exists" }, > + { AE_TYPE, LOG_LEVEL_CRITICAL, "AETtype", "Type" }, > + { AE_NULL_OBJECT, LOG_LEVEL_CRITICAL, "AENullObject", "Null object" }, > + { AE_NULL_ENTRY, LOG_LEVEL_CRITICAL, "AENullEntry", "Null entry" }, > + { AE_BUFFER_OVERFLOW, LOG_LEVEL_CRITICAL, "AEBufferOverflow", "Buffer overflow" }, > + { AE_STACK_OVERFLOW, LOG_LEVEL_CRITICAL, "AEStackOverflow", "Stack overflow" }, > + { AE_STACK_UNDERFLOW, LOG_LEVEL_CRITICAL, "AEStackUnderflow", "Stack underflow" }, > + { AE_NOT_IMPLEMENTED, LOG_LEVEL_HIGH, "AENotImplemented", "Not implemented" }, > + { AE_SUPPORT, LOG_LEVEL_HIGH, "AESupport", "Support" }, > + { AE_LIMIT, LOG_LEVEL_CRITICAL, "AELimit", "Limit" }, > + { AE_TIME, LOG_LEVEL_HIGH, "AETime", "Timeout" }, > + { AE_ACQUIRE_DEADLOCK, LOG_LEVEL_CRITICAL, "AEAcqDeadlock", "Acquire deadlock" }, > + { AE_RELEASE_DEADLOCK, LOG_LEVEL_CRITICAL, "AERelDeadlock", "Release deadlock" }, > + { AE_NOT_ACQUIRED, LOG_LEVEL_CRITICAL, "AENotAcq", "Not acquired" }, > + { AE_ALREADY_ACQUIRED, LOG_LEVEL_CRITICAL, "AEAlreadyAcq", "Already acquired" }, > + { AE_NO_HARDWARE_RESPONSE, LOG_LEVEL_HIGH, "AENoHWResponse", "No hardware response" }, > + { AE_NO_GLOBAL_LOCK, LOG_LEVEL_HIGH, "AENoGlobalLock", "No global lock" }, > + { AE_ABORT_METHOD, LOG_LEVEL_CRITICAL, "AEAbortMethod", "Abort method" }, > + { AE_SAME_HANDLER, LOG_LEVEL_HIGH, "AESameHandler", "Same handler" }, > + { AE_NO_HANDLER, LOG_LEVEL_CRITICAL, "AENoHandler", "No handler" }, > + { AE_OWNER_ID_LIMIT, LOG_LEVEL_HIGH, "AEOwnerIDLimit", "Owner ID limit" }, > + > + { AE_BAD_PARAMETER, LOG_LEVEL_HIGH, "AEBadParam", "Args: Bad paramater" }, > + { AE_BAD_CHARACTER, LOG_LEVEL_HIGH, "AEBadChar", "Args: Bad character" }, > + { AE_BAD_PATHNAME, LOG_LEVEL_HIGH, "AEBadPathname", "Args: Bad pathname" }, > + { AE_BAD_DATA, LOG_LEVEL_HIGH, "AEBadData", "Args: Bad data" }, > + { AE_BAD_HEX_CONSTANT, LOG_LEVEL_HIGH, "AEBadHexConst", "Args: Bad hex constant" }, > + { AE_BAD_OCTAL_CONSTANT, LOG_LEVEL_HIGH, "AEBadOctConst", "Args: Bad octal constant" }, > + { AE_BAD_DECIMAL_CONSTANT, LOG_LEVEL_HIGH, "AEBadDecConst", "Args: Bad decimal constant" }, > + { AE_MISSING_ARGUMENTS, LOG_LEVEL_CRITICAL, "AEMissingArgs", "Args: Missing arguments" }, > + { AE_BAD_ADDRESS, LOG_LEVEL_CRITICAL, "AEBadAddr", "Args: Bad address" }, > + > + { AE_AML_BAD_OPCODE, LOG_LEVEL_CRITICAL, "AEAMLBadOpCode", "Bad AML opcode" }, > + { AE_AML_NO_OPERAND, LOG_LEVEL_HIGH, "AEAMLNoOperand", "Missing operand" }, > + { AE_AML_OPERAND_TYPE, LOG_LEVEL_HIGH, "AEAMLOperandType", "Incorrect operand type" }, > + { AE_AML_OPERAND_VALUE, LOG_LEVEL_HIGH, "AEAMLOperandValue", "Incorrect operand value" }, > + { AE_AML_UNINITIALIZED_LOCAL, LOG_LEVEL_HIGH, "AEAMLUninitLocal", "Uninitialized local variable" }, > + { AE_AML_UNINITIALIZED_ARG, LOG_LEVEL_HIGH, "AEAMLUninitArg", "Uninitialized argument" }, > + { AE_AML_UNINITIALIZED_ELEMENT, LOG_LEVEL_HIGH, "AEAMLUninitElement", "Uninitialized element" }, > + { AE_AML_NUMERIC_OVERFLOW, LOG_LEVEL_HIGH, "AEAMLNumericOverflow", "Numeric overflow" }, > + { AE_AML_REGION_LIMIT, LOG_LEVEL_CRITICAL, "AEAMLRegionLimit", "Region limit" }, > + { AE_AML_BUFFER_LIMIT, LOG_LEVEL_CRITICAL, "AEAMLBufferLimit", "Buffer limit" }, > + { AE_AML_PACKAGE_LIMIT, LOG_LEVEL_CRITICAL, "AEAMLPackgeLimit", "Package limit" }, > + { AE_AML_DIVIDE_BY_ZERO, LOG_LEVEL_CRITICAL, "AEAMLDivideByZero", "Division by zero" }, > + { AE_AML_NAME_NOT_FOUND, LOG_LEVEL_HIGH, "AEAMLNameNotFound", "Name not found" }, > + { AE_AML_INTERNAL, LOG_LEVEL_HIGH, "AEAMLInternal", "Internal ACPICA execution engine error" }, > + { AE_AML_INVALID_SPACE_ID, LOG_LEVEL_HIGH, "AEAMLInvalidSpaceID", "Invalid space ID error" }, > + { AE_AML_STRING_LIMIT, LOG_LEVEL_HIGH, "AEAMLStringLimit", "String limit" }, > + { AE_AML_NO_RETURN_VALUE, LOG_LEVEL_HIGH, "AEAMLNoReturnValue", "No return value" }, > + { AE_AML_METHOD_LIMIT, LOG_LEVEL_HIGH, "AEAMLMethodLimit", "Method limit" }, > + { AE_AML_NOT_OWNER, LOG_LEVEL_HIGH, "AEAMLNotOwner", "Not owner" }, > + { AE_AML_MUTEX_ORDER, LOG_LEVEL_HIGH, "AEAMLMutexOrder", "Mutex order" }, > + { AE_AML_MUTEX_NOT_ACQUIRED, LOG_LEVEL_HIGH, "AEAMLMutexNotAcq", "Mutux not acquired" }, > + { AE_AML_INVALID_RESOURCE_TYPE, LOG_LEVEL_HIGH, "AEAMLInvResourceType", "Invalid resource type" }, > + { AE_AML_INVALID_INDEX, LOG_LEVEL_HIGH, "AEAMLInvIndex", "Invalid index" }, > + { AE_AML_REGISTER_LIMIT, LOG_LEVEL_HIGH, "AEAMLRegisterLimit", "Register limit" }, > + { AE_AML_NO_WHILE, LOG_LEVEL_CRITICAL, "AEAMLNoWhile", "No while" }, > + { AE_AML_ALIGNMENT, LOG_LEVEL_CRITICAL, "AEAMLAlignment", "Misaligmnent" }, > + { AE_AML_NO_RESOURCE_END_TAG, LOG_LEVEL_HIGH, "AEAMLNoResEndTag", "No resource end tag"}, > + { AE_AML_BAD_RESOURCE_VALUE, LOG_LEVEL_HIGH, "AEAMLBadResValue", "Bad resource value" }, > + { AE_AML_CIRCULAR_REFERENCE, LOG_LEVEL_CRITICAL, "AEAMLCircularRef", "Circular reference" }, > + { AE_AML_BAD_RESOURCE_LENGTH, LOG_LEVEL_HIGH, "AEAMLBadResLength", "Bad resource length" }, > + { AE_AML_ILLEGAL_ADDRESS, LOG_LEVEL_CRITICAL, "AEAMLIllegalAddr", "Illegal address" }, > + /* { AE_AML_INFINITE_LOOP, LOG_LEVEL_HIGH, "AEAMLInfiniteLoop", "Infinite loop" }, */ > + { 0, 0, NULL, NULL } > +}; > + > +static fwts_list *fwts_object_names; > +static bool fwts_acpi_initialized = false; > + > +/* > + * fwts_acpi_init() > + * Initialise ACPIA engine and collect method namespace > + */ > +int fwts_acpi_init(fwts_framework *fw) > +{ > + if (fwts_acpica_init(fw) != FWTS_OK) > + return FWTS_ERROR; > + > + /* Gather all object names */ > + fwts_object_names = fwts_acpica_get_object_names(0); > + fwts_acpi_initialized = true; > + > + return FWTS_OK; > +} > + > +/* > + * fwts_acpi_deinit() > + * Close ACPIA engine and free method namespace > + */ > +int fwts_acpi_deinit(fwts_framework *fw) > +{ > + int ret = FWTS_ERROR; > + > + FWTS_UNUSED(fw); > + > + if (fwts_acpi_initialized) { > + fwts_list_free(fwts_object_names, free); > + fwts_object_names = NULL; > + ret = fwts_acpica_deinit(); > + > + fwts_acpi_initialized = false; > + } > + > + return ret; > +} > + > +/* > + * fwts_acpi_object_get_names() > + * return list of object names > + */ > +fwts_list *fwts_acpi_object_get_names(void) > +{ > + return fwts_object_names; > +} > + > +/* > + * fwts_acpi_object_exists() > + * return first matching name > + */ > +char *fwts_acpi_object_exists(const char *name) > +{ > + size_t name_len = strlen(name); > + fwts_list_link *item; > + > + fwts_list_foreach(item, fwts_object_names) { > + char *method_name = fwts_list_data(char*, item); > + size_t len = strlen(method_name); > + > + if (strncmp(name, method_name + len - name_len, name_len) == 0) > + return method_name; > + } > + return NULL; > +} > + > + > +/* > + * fwts_acpi_object_dump_recursive() > + * dump out an object, minimal form > + */ > +static void fwts_acpi_object_dump_recursive( > + fwts_framework *fw, > + const ACPI_OBJECT *obj, > + const int depth, > + const int index) > +{ > + uint32_t i; > + char index_buf[5]; > + > + if (index > -1) > + snprintf(index_buf, sizeof(index_buf), "%2.2d: ", index); > + else > + index_buf[0] = '\0'; > + > + switch (obj->Type) { > + case ACPI_TYPE_INTEGER: > + fwts_log_info_verbatum(fw, "%*s%sINTEGER: 0x%8.8llx", depth * 2, "", > + index_buf, (unsigned long long)obj->Integer.Value); > + break; > + case ACPI_TYPE_STRING: > + fwts_log_info_verbatum(fw, "%*s%sSTRING: %s", depth * 2, "", > + index_buf, obj->String.Pointer); > + break; > + case ACPI_TYPE_BUFFER: > + fwts_log_info_verbatum(fw, "%*s%sBUFFER: (%d bytes)", depth * 2, "", > + index_buf, obj->Buffer.Length); > + break; > + case ACPI_TYPE_PACKAGE: > + fwts_log_info_verbatum(fw, "%*s%sPackage has %d elements:",depth * 2, "", > + index_buf, obj->Package.Count); > + for (i = 0; i < obj->Package.Count; i++) { > + ACPI_OBJECT *element = &obj->Package.Elements[i]; > + fwts_acpi_object_dump_recursive(fw, element, depth + 1, i); > + } > + break; > + default: > + fwts_log_info_verbatum(fw, "%*s%sUnknown type %d\n", depth * 2, "", > + index_buf, obj->Type); > + break; > + } > +} > + > +/* > + * fwts_method_object_dump() > + * dump out an object, minimal form > + */ > +void fwts_acpi_object_dump(fwts_framework *fw, const ACPI_OBJECT *obj) > +{ > + fwts_acpi_object_dump_recursive(fw, obj, 1, -1); > +} > + > +/* > + * fwts_acpi_object_evaluate_report_error() > + * report any errors found during object evaluation > + */ > +void fwts_acpi_object_evaluate_report_error( > + fwts_framework *fw, > + const char *name, > + const ACPI_STATUS status) > +{ > + int i; > + > + /* Generic cases */ > + for (i=0; errors[i].error_type; i++) { > + if (status == errors[i].status) { > + fwts_failed(fw, errors[i].level, errors[i].error_type, > + "Detected error '%s' when evaluating '%s'.", > + errors[i].error_text, name); > + return; > + } > + } > + > + /* Special cases */ > + switch (status) { > + case AE_OK: > + break; > + case AE_AML_INFINITE_LOOP: > + fwts_warning(fw, "Detected an infinite loop when evaluating method '%s'. ", name); > + fwts_advice(fw, "This may occur because we are emulating the execution " > + "in this test environment and cannot handshake with " > + "the embedded controller or jump to the BIOS via SMIs. " > + "However, the fact that AML code spins forever means that " > + "lockup conditions are not being checked for in the AML bytecode."); > + break; > + /* Unknown?! */ > + default: > + fwts_failed(fw, LOG_LEVEL_MEDIUM, "AMLFailedToEvaluate", "Failed to evaluate '%s', got error code %d.", name, status); > + break; > + } > +} > + > +/* > + * fwts_acpi_object_evaluate() > + * evaluate object, return error status (handle this with > + * fwts_method_evaluate_report_error()). > + * This returns buf which auto allocates any return values > + * which need to be freed post-evalutation using free(). > + */ > +ACPI_STATUS fwts_acpi_object_evaluate(fwts_framework *fw, > + char *name, > + ACPI_OBJECT_LIST *arg_list, > + ACPI_BUFFER *buf) > +{ > + FWTS_UNUSED(fw); > + > + buf->Length = ACPI_ALLOCATE_BUFFER; > + buf->Pointer = NULL; > + > + return AcpiEvaluateObject(NULL, name, arg_list, buf); > +} > + > Acked-by: Alex Hung <alex.hung@canonical.com>
diff --git a/src/acpi/method/method.c b/src/acpi/method/method.c index 63fcd94..f7df732 100644 --- a/src/acpi/method/method.c +++ b/src/acpi/method/method.c @@ -28,7 +28,7 @@ /* acpica headers */ #include "acpi.h" -#include "fwts_acpi_method.h" +#include "fwts_acpi_object_eval.h" /* * ACPI methods + objects used in Linux ACPI driver: diff --git a/src/acpi/pcc/pcc.c b/src/acpi/pcc/pcc.c index 6660196..8741e0b 100644 --- a/src/acpi/pcc/pcc.c +++ b/src/acpi/pcc/pcc.c @@ -28,7 +28,7 @@ /* acpica headers */ #include "acpi.h" -#include "fwts_acpi_method.h" +#include "fwts_acpi_object_eval.h" /* * This test does some sanity checking on the PCC interface, diff --git a/src/lib/include/fwts_acpi_method.h b/src/lib/include/fwts_acpi_method.h deleted file mode 100644 index 76e3e46..0000000 --- a/src/lib/include/fwts_acpi_method.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (C) 2010-2012 Canonical - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - */ - -#ifndef __FWTS_ACPI_METHOD_H__ -#define __FWTS_ACPI_METHOD_H__ - -#include "fwts.h" - -/* acpica headers */ -#include "acpi.h" - -int fwts_acpi_init(fwts_framework *fw); -int fwts_acpi_deinit(fwts_framework *fw); -char *fwts_acpi_object_exists(const char *name); -fwts_list *fwts_acpi_object_get_names(void); -void fwts_acpi_object_dump(fwts_framework *fw, const ACPI_OBJECT *obj); -void fwts_acpi_object_evaluate_report_error(fwts_framework *fw, const char *name, const ACPI_STATUS status); -ACPI_STATUS fwts_acpi_object_evaluate(fwts_framework *fw, char *name, ACPI_OBJECT_LIST *arg_list, ACPI_BUFFER *buf); - -#endif diff --git a/src/lib/include/fwts_acpi_object_eval.h b/src/lib/include/fwts_acpi_object_eval.h new file mode 100644 index 0000000..76e3e46 --- /dev/null +++ b/src/lib/include/fwts_acpi_object_eval.h @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2010-2012 Canonical + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef __FWTS_ACPI_METHOD_H__ +#define __FWTS_ACPI_METHOD_H__ + +#include "fwts.h" + +/* acpica headers */ +#include "acpi.h" + +int fwts_acpi_init(fwts_framework *fw); +int fwts_acpi_deinit(fwts_framework *fw); +char *fwts_acpi_object_exists(const char *name); +fwts_list *fwts_acpi_object_get_names(void); +void fwts_acpi_object_dump(fwts_framework *fw, const ACPI_OBJECT *obj); +void fwts_acpi_object_evaluate_report_error(fwts_framework *fw, const char *name, const ACPI_STATUS status); +ACPI_STATUS fwts_acpi_object_evaluate(fwts_framework *fw, char *name, ACPI_OBJECT_LIST *arg_list, ACPI_BUFFER *buf); + +#endif diff --git a/src/lib/src/Makefile.am b/src/lib/src/Makefile.am index 65a2e55..a91d9ab 100644 --- a/src/lib/src/Makefile.am +++ b/src/lib/src/Makefile.am @@ -17,7 +17,7 @@ libfwts_la_LDFLAGS = \ # libfwts_la_SOURCES = \ fwts_ac_adapter.c \ - fwts_acpi_method.c \ + fwts_acpi_object_eval.c \ fwts_acpi_tables.c \ fwts_acpi.c \ fwts_acpid.c \ diff --git a/src/lib/src/fwts_acpi_method.c b/src/lib/src/fwts_acpi_method.c deleted file mode 100644 index 8427e4c..0000000 --- a/src/lib/src/fwts_acpi_method.c +++ /dev/null @@ -1,295 +0,0 @@ -/* - * Copyright (C) 2010-2012 Canonical - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - */ -#include "fwts.h" - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> - -/* acpica headers */ -#include "acpi.h" -#include "fwts_acpi_method.h" - -typedef struct { - const ACPI_STATUS status; - const fwts_log_level level; - const char *error_type; - const char *error_text; -} acpi_eval_error; - -static const acpi_eval_error errors[] = { - /* ACPI_STATUS fwts_log_level error_type error_text */ - { AE_ERROR, LOG_LEVEL_HIGH, "AEError", "Environment error" }, - { AE_NO_ACPI_TABLES, LOG_LEVEL_HIGH, "AENoACPITables", "NO ACPI tables" }, - { AE_NO_NAMESPACE, LOG_LEVEL_HIGH, "AENoNamespace", "No namespace" }, - { AE_NO_MEMORY, LOG_LEVEL_CRITICAL, "AENoMemory", "Out of memory" }, - { AE_NOT_FOUND, LOG_LEVEL_CRITICAL, "AENotFound", "Not found" }, - { AE_NOT_EXIST, LOG_LEVEL_CRITICAL, "AENotExist", "Not exist" }, - { AE_ALREADY_EXISTS, LOG_LEVEL_HIGH, "AEAlreadyExists", "Already exists" }, - { AE_TYPE, LOG_LEVEL_CRITICAL, "AETtype", "Type" }, - { AE_NULL_OBJECT, LOG_LEVEL_CRITICAL, "AENullObject", "Null object" }, - { AE_NULL_ENTRY, LOG_LEVEL_CRITICAL, "AENullEntry", "Null entry" }, - { AE_BUFFER_OVERFLOW, LOG_LEVEL_CRITICAL, "AEBufferOverflow", "Buffer overflow" }, - { AE_STACK_OVERFLOW, LOG_LEVEL_CRITICAL, "AEStackOverflow", "Stack overflow" }, - { AE_STACK_UNDERFLOW, LOG_LEVEL_CRITICAL, "AEStackUnderflow", "Stack underflow" }, - { AE_NOT_IMPLEMENTED, LOG_LEVEL_HIGH, "AENotImplemented", "Not implemented" }, - { AE_SUPPORT, LOG_LEVEL_HIGH, "AESupport", "Support" }, - { AE_LIMIT, LOG_LEVEL_CRITICAL, "AELimit", "Limit" }, - { AE_TIME, LOG_LEVEL_HIGH, "AETime", "Timeout" }, - { AE_ACQUIRE_DEADLOCK, LOG_LEVEL_CRITICAL, "AEAcqDeadlock", "Acquire deadlock" }, - { AE_RELEASE_DEADLOCK, LOG_LEVEL_CRITICAL, "AERelDeadlock", "Release deadlock" }, - { AE_NOT_ACQUIRED, LOG_LEVEL_CRITICAL, "AENotAcq", "Not acquired" }, - { AE_ALREADY_ACQUIRED, LOG_LEVEL_CRITICAL, "AEAlreadyAcq", "Already acquired" }, - { AE_NO_HARDWARE_RESPONSE, LOG_LEVEL_HIGH, "AENoHWResponse", "No hardware response" }, - { AE_NO_GLOBAL_LOCK, LOG_LEVEL_HIGH, "AENoGlobalLock", "No global lock" }, - { AE_ABORT_METHOD, LOG_LEVEL_CRITICAL, "AEAbortMethod", "Abort method" }, - { AE_SAME_HANDLER, LOG_LEVEL_HIGH, "AESameHandler", "Same handler" }, - { AE_NO_HANDLER, LOG_LEVEL_CRITICAL, "AENoHandler", "No handler" }, - { AE_OWNER_ID_LIMIT, LOG_LEVEL_HIGH, "AEOwnerIDLimit", "Owner ID limit" }, - - { AE_BAD_PARAMETER, LOG_LEVEL_HIGH, "AEBadParam", "Args: Bad paramater" }, - { AE_BAD_CHARACTER, LOG_LEVEL_HIGH, "AEBadChar", "Args: Bad character" }, - { AE_BAD_PATHNAME, LOG_LEVEL_HIGH, "AEBadPathname", "Args: Bad pathname" }, - { AE_BAD_DATA, LOG_LEVEL_HIGH, "AEBadData", "Args: Bad data" }, - { AE_BAD_HEX_CONSTANT, LOG_LEVEL_HIGH, "AEBadHexConst", "Args: Bad hex constant" }, - { AE_BAD_OCTAL_CONSTANT, LOG_LEVEL_HIGH, "AEBadOctConst", "Args: Bad octal constant" }, - { AE_BAD_DECIMAL_CONSTANT, LOG_LEVEL_HIGH, "AEBadDecConst", "Args: Bad decimal constant" }, - { AE_MISSING_ARGUMENTS, LOG_LEVEL_CRITICAL, "AEMissingArgs", "Args: Missing arguments" }, - { AE_BAD_ADDRESS, LOG_LEVEL_CRITICAL, "AEBadAddr", "Args: Bad address" }, - - { AE_AML_BAD_OPCODE, LOG_LEVEL_CRITICAL, "AEAMLBadOpCode", "Bad AML opcode" }, - { AE_AML_NO_OPERAND, LOG_LEVEL_HIGH, "AEAMLNoOperand", "Missing operand" }, - { AE_AML_OPERAND_TYPE, LOG_LEVEL_HIGH, "AEAMLOperandType", "Incorrect operand type" }, - { AE_AML_OPERAND_VALUE, LOG_LEVEL_HIGH, "AEAMLOperandValue", "Incorrect operand value" }, - { AE_AML_UNINITIALIZED_LOCAL, LOG_LEVEL_HIGH, "AEAMLUninitLocal", "Uninitialized local variable" }, - { AE_AML_UNINITIALIZED_ARG, LOG_LEVEL_HIGH, "AEAMLUninitArg", "Uninitialized argument" }, - { AE_AML_UNINITIALIZED_ELEMENT, LOG_LEVEL_HIGH, "AEAMLUninitElement", "Uninitialized element" }, - { AE_AML_NUMERIC_OVERFLOW, LOG_LEVEL_HIGH, "AEAMLNumericOverflow", "Numeric overflow" }, - { AE_AML_REGION_LIMIT, LOG_LEVEL_CRITICAL, "AEAMLRegionLimit", "Region limit" }, - { AE_AML_BUFFER_LIMIT, LOG_LEVEL_CRITICAL, "AEAMLBufferLimit", "Buffer limit" }, - { AE_AML_PACKAGE_LIMIT, LOG_LEVEL_CRITICAL, "AEAMLPackgeLimit", "Package limit" }, - { AE_AML_DIVIDE_BY_ZERO, LOG_LEVEL_CRITICAL, "AEAMLDivideByZero", "Division by zero" }, - { AE_AML_NAME_NOT_FOUND, LOG_LEVEL_HIGH, "AEAMLNameNotFound", "Name not found" }, - { AE_AML_INTERNAL, LOG_LEVEL_HIGH, "AEAMLInternal", "Internal ACPICA execution engine error" }, - { AE_AML_INVALID_SPACE_ID, LOG_LEVEL_HIGH, "AEAMLInvalidSpaceID", "Invalid space ID error" }, - { AE_AML_STRING_LIMIT, LOG_LEVEL_HIGH, "AEAMLStringLimit", "String limit" }, - { AE_AML_NO_RETURN_VALUE, LOG_LEVEL_HIGH, "AEAMLNoReturnValue", "No return value" }, - { AE_AML_METHOD_LIMIT, LOG_LEVEL_HIGH, "AEAMLMethodLimit", "Method limit" }, - { AE_AML_NOT_OWNER, LOG_LEVEL_HIGH, "AEAMLNotOwner", "Not owner" }, - { AE_AML_MUTEX_ORDER, LOG_LEVEL_HIGH, "AEAMLMutexOrder", "Mutex order" }, - { AE_AML_MUTEX_NOT_ACQUIRED, LOG_LEVEL_HIGH, "AEAMLMutexNotAcq", "Mutux not acquired" }, - { AE_AML_INVALID_RESOURCE_TYPE, LOG_LEVEL_HIGH, "AEAMLInvResourceType", "Invalid resource type" }, - { AE_AML_INVALID_INDEX, LOG_LEVEL_HIGH, "AEAMLInvIndex", "Invalid index" }, - { AE_AML_REGISTER_LIMIT, LOG_LEVEL_HIGH, "AEAMLRegisterLimit", "Register limit" }, - { AE_AML_NO_WHILE, LOG_LEVEL_CRITICAL, "AEAMLNoWhile", "No while" }, - { AE_AML_ALIGNMENT, LOG_LEVEL_CRITICAL, "AEAMLAlignment", "Misaligmnent" }, - { AE_AML_NO_RESOURCE_END_TAG, LOG_LEVEL_HIGH, "AEAMLNoResEndTag", "No resource end tag"}, - { AE_AML_BAD_RESOURCE_VALUE, LOG_LEVEL_HIGH, "AEAMLBadResValue", "Bad resource value" }, - { AE_AML_CIRCULAR_REFERENCE, LOG_LEVEL_CRITICAL, "AEAMLCircularRef", "Circular reference" }, - { AE_AML_BAD_RESOURCE_LENGTH, LOG_LEVEL_HIGH, "AEAMLBadResLength", "Bad resource length" }, - { AE_AML_ILLEGAL_ADDRESS, LOG_LEVEL_CRITICAL, "AEAMLIllegalAddr", "Illegal address" }, - /* { AE_AML_INFINITE_LOOP, LOG_LEVEL_HIGH, "AEAMLInfiniteLoop", "Infinite loop" }, */ - { 0, 0, NULL, NULL } -}; - -static fwts_list *fwts_object_names; -static bool fwts_acpi_initialized = false; - -/* - * fwts_acpi_init() - * Initialise ACPIA engine and collect method namespace - */ -int fwts_acpi_init(fwts_framework *fw) -{ - if (fwts_acpica_init(fw) != FWTS_OK) - return FWTS_ERROR; - - /* Gather all object names */ - fwts_object_names = fwts_acpica_get_object_names(0); - fwts_acpi_initialized = true; - - return FWTS_OK; -} - -/* - * fwts_acpi_deinit() - * Close ACPIA engine and free method namespace - */ -int fwts_acpi_deinit(fwts_framework *fw) -{ - int ret = FWTS_ERROR; - - FWTS_UNUSED(fw); - - if (fwts_acpi_initialized) { - fwts_list_free(fwts_object_names, free); - fwts_object_names = NULL; - ret = fwts_acpica_deinit(); - - fwts_acpi_initialized = false; - } - - return ret; -} - -/* - * fwts_acpi_object_get_names() - * return list of object names - */ -fwts_list *fwts_acpi_object_get_names(void) -{ - return fwts_object_names; -} - -/* - * fwts_acpi_object_exists() - * return first matching name - */ -char *fwts_acpi_object_exists(const char *name) -{ - size_t name_len = strlen(name); - fwts_list_link *item; - - fwts_list_foreach(item, fwts_object_names) { - char *method_name = fwts_list_data(char*, item); - size_t len = strlen(method_name); - - if (strncmp(name, method_name + len - name_len, name_len) == 0) - return method_name; - } - return NULL; -} - - -/* - * fwts_acpi_object_dump_recursive() - * dump out an object, minimal form - */ -static void fwts_acpi_object_dump_recursive( - fwts_framework *fw, - const ACPI_OBJECT *obj, - const int depth, - const int index) -{ - uint32_t i; - char index_buf[5]; - - if (index > -1) - snprintf(index_buf, sizeof(index_buf), "%2.2d: ", index); - else - index_buf[0] = '\0'; - - switch (obj->Type) { - case ACPI_TYPE_INTEGER: - fwts_log_info_verbatum(fw, "%*s%sINTEGER: 0x%8.8llx", depth * 2, "", - index_buf, (unsigned long long)obj->Integer.Value); - break; - case ACPI_TYPE_STRING: - fwts_log_info_verbatum(fw, "%*s%sSTRING: %s", depth * 2, "", - index_buf, obj->String.Pointer); - break; - case ACPI_TYPE_BUFFER: - fwts_log_info_verbatum(fw, "%*s%sBUFFER: (%d bytes)", depth * 2, "", - index_buf, obj->Buffer.Length); - break; - case ACPI_TYPE_PACKAGE: - fwts_log_info_verbatum(fw, "%*s%sPackage has %d elements:",depth * 2, "", - index_buf, obj->Package.Count); - for (i = 0; i < obj->Package.Count; i++) { - ACPI_OBJECT *element = &obj->Package.Elements[i]; - fwts_acpi_object_dump_recursive(fw, element, depth + 1, i); - } - break; - default: - fwts_log_info_verbatum(fw, "%*s%sUnknown type %d\n", depth * 2, "", - index_buf, obj->Type); - break; - } -} - -/* - * fwts_method_object_dump() - * dump out an object, minimal form - */ -void fwts_acpi_object_dump(fwts_framework *fw, const ACPI_OBJECT *obj) -{ - fwts_acpi_object_dump_recursive(fw, obj, 1, -1); -} - -/* - * fwts_acpi_object_evaluate_report_error() - * report any errors found during object evaluation - */ -void fwts_acpi_object_evaluate_report_error( - fwts_framework *fw, - const char *name, - const ACPI_STATUS status) -{ - int i; - - /* Generic cases */ - for (i=0; errors[i].error_type; i++) { - if (status == errors[i].status) { - fwts_failed(fw, errors[i].level, errors[i].error_type, - "Detected error '%s' when evaluating '%s'.", - errors[i].error_text, name); - return; - } - } - - /* Special cases */ - switch (status) { - case AE_OK: - break; - case AE_AML_INFINITE_LOOP: - fwts_warning(fw, "Detected an infinite loop when evaluating method '%s'. ", name); - fwts_advice(fw, "This may occur because we are emulating the execution " - "in this test environment and cannot handshake with " - "the embedded controller or jump to the BIOS via SMIs. " - "However, the fact that AML code spins forever means that " - "lockup conditions are not being checked for in the AML bytecode."); - break; - /* Unknown?! */ - default: - fwts_failed(fw, LOG_LEVEL_MEDIUM, "AMLFailedToEvaluate", "Failed to evaluate '%s', got error code %d.", name, status); - break; - } -} - -/* - * fwts_acpi_object_evaluate() - * evaluate object, return error status (handle this with - * fwts_method_evaluate_report_error()). - * This returns buf which auto allocates any return values - * which need to be freed post-evalutation using free(). - */ -ACPI_STATUS fwts_acpi_object_evaluate(fwts_framework *fw, - char *name, - ACPI_OBJECT_LIST *arg_list, - ACPI_BUFFER *buf) -{ - FWTS_UNUSED(fw); - - buf->Length = ACPI_ALLOCATE_BUFFER; - buf->Pointer = NULL; - - return AcpiEvaluateObject(NULL, name, arg_list, buf); -} - diff --git a/src/lib/src/fwts_acpi_object_eval.c b/src/lib/src/fwts_acpi_object_eval.c new file mode 100644 index 0000000..9883c77 --- /dev/null +++ b/src/lib/src/fwts_acpi_object_eval.c @@ -0,0 +1,295 @@ +/* + * Copyright (C) 2010-2012 Canonical + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ +#include "fwts.h" + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +/* acpica headers */ +#include "acpi.h" +#include "fwts_acpi_object_eval.h" + +typedef struct { + const ACPI_STATUS status; + const fwts_log_level level; + const char *error_type; + const char *error_text; +} acpi_eval_error; + +static const acpi_eval_error errors[] = { + /* ACPI_STATUS fwts_log_level error_type error_text */ + { AE_ERROR, LOG_LEVEL_HIGH, "AEError", "Environment error" }, + { AE_NO_ACPI_TABLES, LOG_LEVEL_HIGH, "AENoACPITables", "NO ACPI tables" }, + { AE_NO_NAMESPACE, LOG_LEVEL_HIGH, "AENoNamespace", "No namespace" }, + { AE_NO_MEMORY, LOG_LEVEL_CRITICAL, "AENoMemory", "Out of memory" }, + { AE_NOT_FOUND, LOG_LEVEL_CRITICAL, "AENotFound", "Not found" }, + { AE_NOT_EXIST, LOG_LEVEL_CRITICAL, "AENotExist", "Not exist" }, + { AE_ALREADY_EXISTS, LOG_LEVEL_HIGH, "AEAlreadyExists", "Already exists" }, + { AE_TYPE, LOG_LEVEL_CRITICAL, "AETtype", "Type" }, + { AE_NULL_OBJECT, LOG_LEVEL_CRITICAL, "AENullObject", "Null object" }, + { AE_NULL_ENTRY, LOG_LEVEL_CRITICAL, "AENullEntry", "Null entry" }, + { AE_BUFFER_OVERFLOW, LOG_LEVEL_CRITICAL, "AEBufferOverflow", "Buffer overflow" }, + { AE_STACK_OVERFLOW, LOG_LEVEL_CRITICAL, "AEStackOverflow", "Stack overflow" }, + { AE_STACK_UNDERFLOW, LOG_LEVEL_CRITICAL, "AEStackUnderflow", "Stack underflow" }, + { AE_NOT_IMPLEMENTED, LOG_LEVEL_HIGH, "AENotImplemented", "Not implemented" }, + { AE_SUPPORT, LOG_LEVEL_HIGH, "AESupport", "Support" }, + { AE_LIMIT, LOG_LEVEL_CRITICAL, "AELimit", "Limit" }, + { AE_TIME, LOG_LEVEL_HIGH, "AETime", "Timeout" }, + { AE_ACQUIRE_DEADLOCK, LOG_LEVEL_CRITICAL, "AEAcqDeadlock", "Acquire deadlock" }, + { AE_RELEASE_DEADLOCK, LOG_LEVEL_CRITICAL, "AERelDeadlock", "Release deadlock" }, + { AE_NOT_ACQUIRED, LOG_LEVEL_CRITICAL, "AENotAcq", "Not acquired" }, + { AE_ALREADY_ACQUIRED, LOG_LEVEL_CRITICAL, "AEAlreadyAcq", "Already acquired" }, + { AE_NO_HARDWARE_RESPONSE, LOG_LEVEL_HIGH, "AENoHWResponse", "No hardware response" }, + { AE_NO_GLOBAL_LOCK, LOG_LEVEL_HIGH, "AENoGlobalLock", "No global lock" }, + { AE_ABORT_METHOD, LOG_LEVEL_CRITICAL, "AEAbortMethod", "Abort method" }, + { AE_SAME_HANDLER, LOG_LEVEL_HIGH, "AESameHandler", "Same handler" }, + { AE_NO_HANDLER, LOG_LEVEL_CRITICAL, "AENoHandler", "No handler" }, + { AE_OWNER_ID_LIMIT, LOG_LEVEL_HIGH, "AEOwnerIDLimit", "Owner ID limit" }, + + { AE_BAD_PARAMETER, LOG_LEVEL_HIGH, "AEBadParam", "Args: Bad paramater" }, + { AE_BAD_CHARACTER, LOG_LEVEL_HIGH, "AEBadChar", "Args: Bad character" }, + { AE_BAD_PATHNAME, LOG_LEVEL_HIGH, "AEBadPathname", "Args: Bad pathname" }, + { AE_BAD_DATA, LOG_LEVEL_HIGH, "AEBadData", "Args: Bad data" }, + { AE_BAD_HEX_CONSTANT, LOG_LEVEL_HIGH, "AEBadHexConst", "Args: Bad hex constant" }, + { AE_BAD_OCTAL_CONSTANT, LOG_LEVEL_HIGH, "AEBadOctConst", "Args: Bad octal constant" }, + { AE_BAD_DECIMAL_CONSTANT, LOG_LEVEL_HIGH, "AEBadDecConst", "Args: Bad decimal constant" }, + { AE_MISSING_ARGUMENTS, LOG_LEVEL_CRITICAL, "AEMissingArgs", "Args: Missing arguments" }, + { AE_BAD_ADDRESS, LOG_LEVEL_CRITICAL, "AEBadAddr", "Args: Bad address" }, + + { AE_AML_BAD_OPCODE, LOG_LEVEL_CRITICAL, "AEAMLBadOpCode", "Bad AML opcode" }, + { AE_AML_NO_OPERAND, LOG_LEVEL_HIGH, "AEAMLNoOperand", "Missing operand" }, + { AE_AML_OPERAND_TYPE, LOG_LEVEL_HIGH, "AEAMLOperandType", "Incorrect operand type" }, + { AE_AML_OPERAND_VALUE, LOG_LEVEL_HIGH, "AEAMLOperandValue", "Incorrect operand value" }, + { AE_AML_UNINITIALIZED_LOCAL, LOG_LEVEL_HIGH, "AEAMLUninitLocal", "Uninitialized local variable" }, + { AE_AML_UNINITIALIZED_ARG, LOG_LEVEL_HIGH, "AEAMLUninitArg", "Uninitialized argument" }, + { AE_AML_UNINITIALIZED_ELEMENT, LOG_LEVEL_HIGH, "AEAMLUninitElement", "Uninitialized element" }, + { AE_AML_NUMERIC_OVERFLOW, LOG_LEVEL_HIGH, "AEAMLNumericOverflow", "Numeric overflow" }, + { AE_AML_REGION_LIMIT, LOG_LEVEL_CRITICAL, "AEAMLRegionLimit", "Region limit" }, + { AE_AML_BUFFER_LIMIT, LOG_LEVEL_CRITICAL, "AEAMLBufferLimit", "Buffer limit" }, + { AE_AML_PACKAGE_LIMIT, LOG_LEVEL_CRITICAL, "AEAMLPackgeLimit", "Package limit" }, + { AE_AML_DIVIDE_BY_ZERO, LOG_LEVEL_CRITICAL, "AEAMLDivideByZero", "Division by zero" }, + { AE_AML_NAME_NOT_FOUND, LOG_LEVEL_HIGH, "AEAMLNameNotFound", "Name not found" }, + { AE_AML_INTERNAL, LOG_LEVEL_HIGH, "AEAMLInternal", "Internal ACPICA execution engine error" }, + { AE_AML_INVALID_SPACE_ID, LOG_LEVEL_HIGH, "AEAMLInvalidSpaceID", "Invalid space ID error" }, + { AE_AML_STRING_LIMIT, LOG_LEVEL_HIGH, "AEAMLStringLimit", "String limit" }, + { AE_AML_NO_RETURN_VALUE, LOG_LEVEL_HIGH, "AEAMLNoReturnValue", "No return value" }, + { AE_AML_METHOD_LIMIT, LOG_LEVEL_HIGH, "AEAMLMethodLimit", "Method limit" }, + { AE_AML_NOT_OWNER, LOG_LEVEL_HIGH, "AEAMLNotOwner", "Not owner" }, + { AE_AML_MUTEX_ORDER, LOG_LEVEL_HIGH, "AEAMLMutexOrder", "Mutex order" }, + { AE_AML_MUTEX_NOT_ACQUIRED, LOG_LEVEL_HIGH, "AEAMLMutexNotAcq", "Mutux not acquired" }, + { AE_AML_INVALID_RESOURCE_TYPE, LOG_LEVEL_HIGH, "AEAMLInvResourceType", "Invalid resource type" }, + { AE_AML_INVALID_INDEX, LOG_LEVEL_HIGH, "AEAMLInvIndex", "Invalid index" }, + { AE_AML_REGISTER_LIMIT, LOG_LEVEL_HIGH, "AEAMLRegisterLimit", "Register limit" }, + { AE_AML_NO_WHILE, LOG_LEVEL_CRITICAL, "AEAMLNoWhile", "No while" }, + { AE_AML_ALIGNMENT, LOG_LEVEL_CRITICAL, "AEAMLAlignment", "Misaligmnent" }, + { AE_AML_NO_RESOURCE_END_TAG, LOG_LEVEL_HIGH, "AEAMLNoResEndTag", "No resource end tag"}, + { AE_AML_BAD_RESOURCE_VALUE, LOG_LEVEL_HIGH, "AEAMLBadResValue", "Bad resource value" }, + { AE_AML_CIRCULAR_REFERENCE, LOG_LEVEL_CRITICAL, "AEAMLCircularRef", "Circular reference" }, + { AE_AML_BAD_RESOURCE_LENGTH, LOG_LEVEL_HIGH, "AEAMLBadResLength", "Bad resource length" }, + { AE_AML_ILLEGAL_ADDRESS, LOG_LEVEL_CRITICAL, "AEAMLIllegalAddr", "Illegal address" }, + /* { AE_AML_INFINITE_LOOP, LOG_LEVEL_HIGH, "AEAMLInfiniteLoop", "Infinite loop" }, */ + { 0, 0, NULL, NULL } +}; + +static fwts_list *fwts_object_names; +static bool fwts_acpi_initialized = false; + +/* + * fwts_acpi_init() + * Initialise ACPIA engine and collect method namespace + */ +int fwts_acpi_init(fwts_framework *fw) +{ + if (fwts_acpica_init(fw) != FWTS_OK) + return FWTS_ERROR; + + /* Gather all object names */ + fwts_object_names = fwts_acpica_get_object_names(0); + fwts_acpi_initialized = true; + + return FWTS_OK; +} + +/* + * fwts_acpi_deinit() + * Close ACPIA engine and free method namespace + */ +int fwts_acpi_deinit(fwts_framework *fw) +{ + int ret = FWTS_ERROR; + + FWTS_UNUSED(fw); + + if (fwts_acpi_initialized) { + fwts_list_free(fwts_object_names, free); + fwts_object_names = NULL; + ret = fwts_acpica_deinit(); + + fwts_acpi_initialized = false; + } + + return ret; +} + +/* + * fwts_acpi_object_get_names() + * return list of object names + */ +fwts_list *fwts_acpi_object_get_names(void) +{ + return fwts_object_names; +} + +/* + * fwts_acpi_object_exists() + * return first matching name + */ +char *fwts_acpi_object_exists(const char *name) +{ + size_t name_len = strlen(name); + fwts_list_link *item; + + fwts_list_foreach(item, fwts_object_names) { + char *method_name = fwts_list_data(char*, item); + size_t len = strlen(method_name); + + if (strncmp(name, method_name + len - name_len, name_len) == 0) + return method_name; + } + return NULL; +} + + +/* + * fwts_acpi_object_dump_recursive() + * dump out an object, minimal form + */ +static void fwts_acpi_object_dump_recursive( + fwts_framework *fw, + const ACPI_OBJECT *obj, + const int depth, + const int index) +{ + uint32_t i; + char index_buf[5]; + + if (index > -1) + snprintf(index_buf, sizeof(index_buf), "%2.2d: ", index); + else + index_buf[0] = '\0'; + + switch (obj->Type) { + case ACPI_TYPE_INTEGER: + fwts_log_info_verbatum(fw, "%*s%sINTEGER: 0x%8.8llx", depth * 2, "", + index_buf, (unsigned long long)obj->Integer.Value); + break; + case ACPI_TYPE_STRING: + fwts_log_info_verbatum(fw, "%*s%sSTRING: %s", depth * 2, "", + index_buf, obj->String.Pointer); + break; + case ACPI_TYPE_BUFFER: + fwts_log_info_verbatum(fw, "%*s%sBUFFER: (%d bytes)", depth * 2, "", + index_buf, obj->Buffer.Length); + break; + case ACPI_TYPE_PACKAGE: + fwts_log_info_verbatum(fw, "%*s%sPackage has %d elements:",depth * 2, "", + index_buf, obj->Package.Count); + for (i = 0; i < obj->Package.Count; i++) { + ACPI_OBJECT *element = &obj->Package.Elements[i]; + fwts_acpi_object_dump_recursive(fw, element, depth + 1, i); + } + break; + default: + fwts_log_info_verbatum(fw, "%*s%sUnknown type %d\n", depth * 2, "", + index_buf, obj->Type); + break; + } +} + +/* + * fwts_method_object_dump() + * dump out an object, minimal form + */ +void fwts_acpi_object_dump(fwts_framework *fw, const ACPI_OBJECT *obj) +{ + fwts_acpi_object_dump_recursive(fw, obj, 1, -1); +} + +/* + * fwts_acpi_object_evaluate_report_error() + * report any errors found during object evaluation + */ +void fwts_acpi_object_evaluate_report_error( + fwts_framework *fw, + const char *name, + const ACPI_STATUS status) +{ + int i; + + /* Generic cases */ + for (i=0; errors[i].error_type; i++) { + if (status == errors[i].status) { + fwts_failed(fw, errors[i].level, errors[i].error_type, + "Detected error '%s' when evaluating '%s'.", + errors[i].error_text, name); + return; + } + } + + /* Special cases */ + switch (status) { + case AE_OK: + break; + case AE_AML_INFINITE_LOOP: + fwts_warning(fw, "Detected an infinite loop when evaluating method '%s'. ", name); + fwts_advice(fw, "This may occur because we are emulating the execution " + "in this test environment and cannot handshake with " + "the embedded controller or jump to the BIOS via SMIs. " + "However, the fact that AML code spins forever means that " + "lockup conditions are not being checked for in the AML bytecode."); + break; + /* Unknown?! */ + default: + fwts_failed(fw, LOG_LEVEL_MEDIUM, "AMLFailedToEvaluate", "Failed to evaluate '%s', got error code %d.", name, status); + break; + } +} + +/* + * fwts_acpi_object_evaluate() + * evaluate object, return error status (handle this with + * fwts_method_evaluate_report_error()). + * This returns buf which auto allocates any return values + * which need to be freed post-evalutation using free(). + */ +ACPI_STATUS fwts_acpi_object_evaluate(fwts_framework *fw, + char *name, + ACPI_OBJECT_LIST *arg_list, + ACPI_BUFFER *buf) +{ + FWTS_UNUSED(fw); + + buf->Length = ACPI_ALLOCATE_BUFFER; + buf->Pointer = NULL; + + return AcpiEvaluateObject(NULL, name, arg_list, buf); +} +