These changes are the raw update to linux-4.4.6-rt14. Kernel sources
[kvmfornfv.git] / kernel / drivers / acpi / acpica / exdebug.c
index e67d0ac..de92458 100644 (file)
 
 #include <acpi/acpi.h>
 #include "accommon.h"
+#include "acnamesp.h"
 #include "acinterp.h"
+#include "acparser.h"
 
 #define _COMPONENT          ACPI_EXECUTER
 ACPI_MODULE_NAME("exdebug")
 
+static union acpi_operand_object *acpi_gbl_trace_method_object = NULL;
+
+/* Local prototypes */
+
+#ifdef ACPI_DEBUG_OUTPUT
+static const char *acpi_ex_get_trace_event_name(acpi_trace_event_type type);
+#endif
+
 #ifndef ACPI_NO_ERROR_MESSAGES
 /*******************************************************************************
  *
@@ -70,12 +80,15 @@ ACPI_MODULE_NAME("exdebug")
  * enabled if necessary.
  *
  ******************************************************************************/
+
 void
 acpi_ex_do_debug_object(union acpi_operand_object *source_desc,
                        u32 level, u32 index)
 {
        u32 i;
        u32 timer;
+       union acpi_operand_object *object_desc;
+       u32 value;
 
        ACPI_FUNCTION_TRACE_PTR(ex_do_debug_object, source_desc);
 
@@ -254,8 +267,44 @@ acpi_ex_do_debug_object(union acpi_operand_object *source_desc,
                                                         object)->object,
                                                        level + 4, 0);
                        } else {
-                               acpi_ex_do_debug_object(source_desc->reference.
-                                                       object, level + 4, 0);
+                               object_desc = source_desc->reference.object;
+                               value = source_desc->reference.value;
+
+                               switch (object_desc->common.type) {
+                               case ACPI_TYPE_BUFFER:
+
+                                       acpi_os_printf("Buffer[%u] = 0x%2.2X\n",
+                                                      value,
+                                                      *source_desc->reference.
+                                                      index_pointer);
+                                       break;
+
+                               case ACPI_TYPE_STRING:
+
+                                       acpi_os_printf
+                                           ("String[%u] = \"%c\" (0x%2.2X)\n",
+                                            value,
+                                            *source_desc->reference.
+                                            index_pointer,
+                                            *source_desc->reference.
+                                            index_pointer);
+                                       break;
+
+                               case ACPI_TYPE_PACKAGE:
+
+                                       acpi_os_printf("Package[%u] = ", value);
+                                       acpi_ex_do_debug_object(*source_desc->
+                                                               reference.where,
+                                                               level + 4, 0);
+                                       break;
+
+                               default:
+
+                                       acpi_os_printf
+                                           ("Unknown Reference object type %X\n",
+                                            object_desc->common.type);
+                                       break;
+                               }
                        }
                }
                break;
@@ -270,3 +319,316 @@ acpi_ex_do_debug_object(union acpi_operand_object *source_desc,
        return_VOID;
 }
 #endif
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ex_interpreter_trace_enabled
+ *
+ * PARAMETERS:  name                - Whether method name should be matched,
+ *                                    this should be checked before starting
+ *                                    the tracer
+ *
+ * RETURN:      TRUE if interpreter trace is enabled.
+ *
+ * DESCRIPTION: Check whether interpreter trace is enabled
+ *
+ ******************************************************************************/
+
+static u8 acpi_ex_interpreter_trace_enabled(char *name)
+{
+
+       /* Check if tracing is enabled */
+
+       if (!(acpi_gbl_trace_flags & ACPI_TRACE_ENABLED)) {
+               return (FALSE);
+       }
+
+       /*
+        * Check if tracing is filtered:
+        *
+        * 1. If the tracer is started, acpi_gbl_trace_method_object should have
+        *    been filled by the trace starter
+        * 2. If the tracer is not started, acpi_gbl_trace_method_name should be
+        *    matched if it is specified
+        * 3. If the tracer is oneshot style, acpi_gbl_trace_method_name should
+        *    not be cleared by the trace stopper during the first match
+        */
+       if (acpi_gbl_trace_method_object) {
+               return (TRUE);
+       }
+       if (name &&
+           (acpi_gbl_trace_method_name &&
+            strcmp(acpi_gbl_trace_method_name, name))) {
+               return (FALSE);
+       }
+       if ((acpi_gbl_trace_flags & ACPI_TRACE_ONESHOT) &&
+           !acpi_gbl_trace_method_name) {
+               return (FALSE);
+       }
+
+       return (TRUE);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ex_get_trace_event_name
+ *
+ * PARAMETERS:  type            - Trace event type
+ *
+ * RETURN:      Trace event name.
+ *
+ * DESCRIPTION: Used to obtain the full trace event name.
+ *
+ ******************************************************************************/
+
+#ifdef ACPI_DEBUG_OUTPUT
+
+static const char *acpi_ex_get_trace_event_name(acpi_trace_event_type type)
+{
+       switch (type) {
+       case ACPI_TRACE_AML_METHOD:
+
+               return "Method";
+
+       case ACPI_TRACE_AML_OPCODE:
+
+               return "Opcode";
+
+       case ACPI_TRACE_AML_REGION:
+
+               return "Region";
+
+       default:
+
+               return "";
+       }
+}
+
+#endif
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ex_trace_point
+ *
+ * PARAMETERS:  type                - Trace event type
+ *              begin               - TRUE if before execution
+ *              aml                 - Executed AML address
+ *              pathname            - Object path
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Internal interpreter execution trace.
+ *
+ ******************************************************************************/
+
+void
+acpi_ex_trace_point(acpi_trace_event_type type,
+                   u8 begin, u8 *aml, char *pathname)
+{
+
+       ACPI_FUNCTION_NAME(ex_trace_point);
+
+       if (pathname) {
+               ACPI_DEBUG_PRINT((ACPI_DB_TRACE_POINT,
+                                 "%s %s [0x%p:%s] execution.\n",
+                                 acpi_ex_get_trace_event_name(type),
+                                 begin ? "Begin" : "End", aml, pathname));
+       } else {
+               ACPI_DEBUG_PRINT((ACPI_DB_TRACE_POINT,
+                                 "%s %s [0x%p] execution.\n",
+                                 acpi_ex_get_trace_event_name(type),
+                                 begin ? "Begin" : "End", aml));
+       }
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ex_start_trace_method
+ *
+ * PARAMETERS:  method_node         - Node of the method
+ *              obj_desc            - The method object
+ *              walk_state          - current state, NULL if not yet executing
+ *                                    a method.
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Start control method execution trace
+ *
+ ******************************************************************************/
+
+void
+acpi_ex_start_trace_method(struct acpi_namespace_node *method_node,
+                          union acpi_operand_object *obj_desc,
+                          struct acpi_walk_state *walk_state)
+{
+       acpi_status status;
+       char *pathname = NULL;
+       u8 enabled = FALSE;
+
+       ACPI_FUNCTION_NAME(ex_start_trace_method);
+
+       if (method_node) {
+               pathname = acpi_ns_get_normalized_pathname(method_node, TRUE);
+       }
+
+       status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
+       if (ACPI_FAILURE(status)) {
+               goto exit;
+       }
+
+       enabled = acpi_ex_interpreter_trace_enabled(pathname);
+       if (enabled && !acpi_gbl_trace_method_object) {
+               acpi_gbl_trace_method_object = obj_desc;
+               acpi_gbl_original_dbg_level = acpi_dbg_level;
+               acpi_gbl_original_dbg_layer = acpi_dbg_layer;
+               acpi_dbg_level = ACPI_TRACE_LEVEL_ALL;
+               acpi_dbg_layer = ACPI_TRACE_LAYER_ALL;
+
+               if (acpi_gbl_trace_dbg_level) {
+                       acpi_dbg_level = acpi_gbl_trace_dbg_level;
+               }
+               if (acpi_gbl_trace_dbg_layer) {
+                       acpi_dbg_layer = acpi_gbl_trace_dbg_layer;
+               }
+       }
+       (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
+
+exit:
+       if (enabled) {
+               ACPI_TRACE_POINT(ACPI_TRACE_AML_METHOD, TRUE,
+                                obj_desc ? obj_desc->method.aml_start : NULL,
+                                pathname);
+       }
+       if (pathname) {
+               ACPI_FREE(pathname);
+       }
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ex_stop_trace_method
+ *
+ * PARAMETERS:  method_node         - Node of the method
+ *              obj_desc            - The method object
+ *              walk_state          - current state, NULL if not yet executing
+ *                                    a method.
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Stop control method execution trace
+ *
+ ******************************************************************************/
+
+void
+acpi_ex_stop_trace_method(struct acpi_namespace_node *method_node,
+                         union acpi_operand_object *obj_desc,
+                         struct acpi_walk_state *walk_state)
+{
+       acpi_status status;
+       char *pathname = NULL;
+       u8 enabled;
+
+       ACPI_FUNCTION_NAME(ex_stop_trace_method);
+
+       if (method_node) {
+               pathname = acpi_ns_get_normalized_pathname(method_node, TRUE);
+       }
+
+       status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
+       if (ACPI_FAILURE(status)) {
+               goto exit_path;
+       }
+
+       enabled = acpi_ex_interpreter_trace_enabled(NULL);
+
+       (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
+
+       if (enabled) {
+               ACPI_TRACE_POINT(ACPI_TRACE_AML_METHOD, FALSE,
+                                obj_desc ? obj_desc->method.aml_start : NULL,
+                                pathname);
+       }
+
+       status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
+       if (ACPI_FAILURE(status)) {
+               goto exit_path;
+       }
+
+       /* Check whether the tracer should be stopped */
+
+       if (acpi_gbl_trace_method_object == obj_desc) {
+
+               /* Disable further tracing if type is one-shot */
+
+               if (acpi_gbl_trace_flags & ACPI_TRACE_ONESHOT) {
+                       acpi_gbl_trace_method_name = NULL;
+               }
+
+               acpi_dbg_level = acpi_gbl_original_dbg_level;
+               acpi_dbg_layer = acpi_gbl_original_dbg_layer;
+               acpi_gbl_trace_method_object = NULL;
+       }
+
+       (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
+
+exit_path:
+       if (pathname) {
+               ACPI_FREE(pathname);
+       }
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ex_start_trace_opcode
+ *
+ * PARAMETERS:  op                  - The parser opcode object
+ *              walk_state          - current state, NULL if not yet executing
+ *                                    a method.
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Start opcode execution trace
+ *
+ ******************************************************************************/
+
+void
+acpi_ex_start_trace_opcode(union acpi_parse_object *op,
+                          struct acpi_walk_state *walk_state)
+{
+
+       ACPI_FUNCTION_NAME(ex_start_trace_opcode);
+
+       if (acpi_ex_interpreter_trace_enabled(NULL) &&
+           (acpi_gbl_trace_flags & ACPI_TRACE_OPCODE)) {
+               ACPI_TRACE_POINT(ACPI_TRACE_AML_OPCODE, TRUE,
+                                op->common.aml, op->common.aml_op_name);
+       }
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ex_stop_trace_opcode
+ *
+ * PARAMETERS:  op                  - The parser opcode object
+ *              walk_state          - current state, NULL if not yet executing
+ *                                    a method.
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Stop opcode execution trace
+ *
+ ******************************************************************************/
+
+void
+acpi_ex_stop_trace_opcode(union acpi_parse_object *op,
+                         struct acpi_walk_state *walk_state)
+{
+
+       ACPI_FUNCTION_NAME(ex_stop_trace_opcode);
+
+       if (acpi_ex_interpreter_trace_enabled(NULL) &&
+           (acpi_gbl_trace_flags & ACPI_TRACE_OPCODE)) {
+               ACPI_TRACE_POINT(ACPI_TRACE_AML_OPCODE, FALSE,
+                                op->common.aml, op->common.aml_op_name);
+       }
+}