Skip to contentSkip to conversation

ACPICA: 20150930 Release

PATCH In review Lv Zheng 5 participants 73 messages Oct 19, 2015 – Dec 25, 2015 1 message not in the archive

Subsystems (3)
lore
Share & tools
lore

A message that is not in the archive (sent off-list or not yet received): 8c1016ca8a570ba7c7a1c9f0f88d73cd83cea490

Lv Zheng

author
#1 lore raw

v2 cover ACPICA: 20150930 Release

The 20150930 ACPICA kernel-resident subsystem updates are linuxized based on the linux-pm/linux-next branch.

The patchset has passed the following build/boot tests. Build tests are performed as follows:
1. i386 + allyes
2. i386 + allno
3. i386 + default + ACPI_DEBUGGER=y
4. i386 + default + ACPI_DEBUGGER=n + ACPI_DEBUG=y
5. i386 + default + ACPI_DEBUG=n + ACPI=y
6. i386 + default + ACPI=n
7. x86_64 + allyes
8. x86_64 + allno
9. x86_64 + default + ACPI_DEBUGGER=y
10.x86_64 + default + ACPI_DEBUGGER=n + ACPI_DEBUG=y 11.x86_64 + default + ACPI_DEBUG=n + ACPI=y
12.x86_64 + default + ACPI=n
Boot tests are performed as follows:
1. i386 + default + ACPI_DEBUGGER=y
2. x86_64 + default + ACPI_DEBUGGER=y
Where:
1. i386: machine named as "Dell Inspiron Mini 1010"
2. x86_64: machine named as "HP Compaq 8200 Elite SFF PC"
3. default: kernel configuration with following items enabled:
All hardware drivers related to the machines of i386/x86_64 All "drivers/acpi" configurations
All "drivers/platform" drivers
All other drivers that link the APIs provided by ACPICA subsystem

The divergences checking result:
Before applying (20150818 Release):
517 lines
After applying (20150930 Release):
517 lines

Note there are still 2 ACPICA debugger patches not released during this release cycle, so the debugger IO driver is not released in this cycle. In this series the ACPICA debugger core is compile time enabled as all ACPICA debugger files can be built with ACPI_DEBUGGER=y, but not runtime enabled as there is no invocations calling ACPICA debugger APIs and its required OSls are just stubs. The embedded debugger invocation acpi_db_single_step() is also stubbed via debugger thread ID support.

Bob Moore (8):
ACPICA: Remove unnecessary conditional compilation.
ACPICA: iASL: Add symbolic operator support for Index() operator.
ACPICA: Update exception code for "file not found" error
ACPICA: Debugger: Update mutexes used for multithreaded debugger
ACPICA: Update NFIT table to rename a flags field
ACPICA: Improve typechecking, both compile-time and runtime
ACPICA: iASL: General cleanup of the file suffix #defines
ACPICA: Update version to 20150930

Lv Zheng (6):
ACPICA: Linuxize: Export debugger files to Linux
ACPICA: Debugger: Fix "quit/exit" command by cleaning up user
commands termination logic
ACPICA: Debugger: Fix "terminate" command by cleaning up subsystem
shutdown logic
ACPICA: Debugger: Add thread ID support so that single step mode can
only apply to the debugger thread
ACPI: Enable build of AML interpreter debugger
ACPICA: Debugger: Fix dead lock issue ocurred in single stepping mode

 drivers/acpi/Kconfig                      |    9 +
 drivers/acpi/acpica/Makefile              |   18 +-
 drivers/acpi/acpica/acapps.h              |    2 +-
 drivers/acpi/acpica/acdebug.h             |    6 +
 drivers/acpi/acpica/acglobal.h            |    7 +-
 drivers/acpi/acpica/acinterp.h            |    2 -
 drivers/acpi/acpica/aclocal.h             |   22 +-
 drivers/acpi/acpica/acnamesp.h            |    4 -
 drivers/acpi/acpica/acopcode.h            |    4 +-
 drivers/acpi/acpica/acparser.h            |    4 -
 drivers/acpi/acpica/acutils.h             |    2 -
 drivers/acpi/acpica/amlcode.h             |   11 +-
 drivers/acpi/acpica/dbcmds.c              | 1187 +++++++++++++++++++++++++++
 drivers/acpi/acpica/dbconvert.c           |  484 +++++++++++
 drivers/acpi/acpica/dbdisply.c            | 1108 +++++++++++++++++++++++++
 drivers/acpi/acpica/dbexec.c              |  764 +++++++++++++++++
 drivers/acpi/acpica/dbfileio.c            |  256 ++++++
 drivers/acpi/acpica/dbhistry.c            |  239 ++++++
 drivers/acpi/acpica/dbinput.c             | 1267 +++++++++++++++++++++++++++++
 drivers/acpi/acpica/dbmethod.c            |  369 +++++++++
 drivers/acpi/acpica/dbnames.c             |  947 +++++++++++++++++++++
 drivers/acpi/acpica/dbobject.c            |  533 ++++++++++++
 drivers/acpi/acpica/dbstats.c             |  546 +++++++++++++
 drivers/acpi/acpica/dbtest.c              | 1057 ++++++++++++++++++++++++
 drivers/acpi/acpica/dbutils.c             |  457 +++++++++++
 drivers/acpi/acpica/dbxface.c             |  513 ++++++++++++
 drivers/acpi/acpica/evxface.c             |    2 +-
 drivers/acpi/acpica/exconvrt.c            |    1 +
 drivers/acpi/acpica/exresolv.c            |    1 -
 drivers/acpi/acpica/exresop.c             |    2 +
 drivers/acpi/acpica/exstore.c             |  120 ++-
 drivers/acpi/acpica/exstoren.c            |    5 +-
 drivers/acpi/acpica/nsdump.c              |    6 -
 drivers/acpi/acpica/nspredef.c            |    2 +-
 drivers/acpi/acpica/pstree.c              |    2 -
 drivers/acpi/acpica/psutils.c             |    2 -
 drivers/acpi/acpica/rsdump.c              |    3 -
 drivers/acpi/acpica/rsutils.c             |    2 -
 drivers/acpi/acpica/rsxface.c             |    4 +-
 drivers/acpi/acpica/utdecode.c            |   21 +-
 drivers/acpi/acpica/utfileio.c            |    6 +
 drivers/acpi/acpica/utinit.c              |   15 +-
 drivers/acpi/acpica/utmutex.c             |   21 +
 drivers/acpi/acpica/utxface.c             |   19 +-
 drivers/acpi/nfit.c                       |    6 +-
 drivers/acpi/nfit.h                       |    2 +-
 drivers/acpi/osl.c                        |   11 +-
 include/acpi/acexcep.h                    |    7 +-
 include/acpi/acpiosxf.h                   |    3 +-
 include/acpi/acpixf.h                     |   14 +-
 include/acpi/actbl1.h                     |    2 +-
 include/acpi/platform/acenv.h             |    8 +-
 include/acpi/platform/aclinux.h           |    7 +-
 include/acpi/platform/aclinuxex.h         |    5 +
 tools/power/acpi/tools/acpidump/apfiles.c |    2 +-
 55 files changed, 9982 insertions(+), 137 deletions(-)
 create mode 100644 drivers/acpi/acpica/dbcmds.c
 create mode 100644 drivers/acpi/acpica/dbconvert.c
 create mode 100644 drivers/acpi/acpica/dbdisply.c
 create mode 100644 drivers/acpi/acpica/dbexec.c
 create mode 100644 drivers/acpi/acpica/dbfileio.c
 create mode 100644 drivers/acpi/acpica/dbhistry.c
 create mode 100644 drivers/acpi/acpica/dbinput.c
 create mode 100644 drivers/acpi/acpica/dbmethod.c
 create mode 100644 drivers/acpi/acpica/dbnames.c
 create mode 100644 drivers/acpi/acpica/dbobject.c
 create mode 100644 drivers/acpi/acpica/dbstats.c
 create mode 100644 drivers/acpi/acpica/dbtest.c
 create mode 100644 drivers/acpi/acpica/dbutils.c
 create mode 100644 drivers/acpi/acpica/dbxface.c
Signature · 1 line
1.7.10
author
#2 lore raw

PATCH v2 1/14 ACPICA: Remove unnecessary conditional compilation.

From: Bob Moore <[email protected]>

ACPICA commit eea1f0e561893b6d6417913b2d224082fe3a0a5e

Remove use of ACPI_DEBUGGER and ACPI_DISASSEMBLER where these defines are used around entire modules.

Note: This type of code also causes problems with IDEs.

---
 drivers/acpi/acpica/Makefile  |    2 +-
 drivers/acpi/acpica/acdebug.h |    6 ++++++
 drivers/acpi/acpica/rsdump.c  |    3 ---
 include/acpi/platform/acenv.h |    2 +-
 4 files changed, 8 insertions(+), 5 deletions(-)
drivers/acpi/acpica/Makefile +1 -1
index fedcc16..ac78d76 100644
@@ -123,7 +123,6 @@ acpi-y +=		\
 	rsaddr.o	\
 	rscalc.o	\
 	rscreate.o	\
-	rsdump.o	\
 	rsdumpinfo.o	\
 	rsinfo.o	\
 	rsio.o		\
@@ -179,6 +178,7 @@ acpi-y +=		\
 	utxfmutex.o
 
 acpi-$(ACPI_FUTURE_USAGE) +=	\
+	rsdump.o		\
 	utcache.o		\
 	utfileio.o		\
 	utprint.o		\
drivers/acpi/acpica/acdebug.h +6 -0
index eb2e926..c928ba4 100644
@@ -44,6 +44,12 @@
 #ifndef __ACDEBUG_H__
 #define __ACDEBUG_H__
 
+/* The debugger is used in conjunction with the disassembler most of time */
+
+#ifdef ACPI_DISASSEMBLER
+#include "acdisasm.h"
+#endif
+
 #define ACPI_DEBUG_BUFFER_SIZE  0x4000	/* 16K buffer for return objects */
 
 struct acpi_db_command_info {
drivers/acpi/acpica/rsdump.c +0 -3
index c428bb3..2a09288 100644
@@ -51,7 +51,6 @@ ACPI_MODULE_NAME("rsdump")
 /*
  * All functions in this module are used by the AML Debugger only
  */
-#if defined(ACPI_DEBUGGER)
 /* Local prototypes */
 static void acpi_rs_out_string(char *title, char *value);
 
@@ -565,5 +564,3 @@ static void acpi_rs_dump_word_list(u16 length, u16 *data)
 		acpi_os_printf("%25s%2.2X : %4.4X\n", "Word", i, data[i]);
 	}
 }
-
-#endif
include/acpi/platform/acenv.h +1 -1
index ec00e2b..15ef08c 100644
@@ -142,7 +142,7 @@
 
 #ifdef ACPI_LIBRARY
 #define ACPI_USE_LOCAL_CACHE
-#define ACPI_FUTURE_USAGE
+#define ACPI_FULL_DEBUG
 #endif
 
 /* Common for all ACPICA applications */
Signature · 1 line
1.7.10
author
#3 lore raw

PATCH v2 2/14 ACPICA: iASL: Add symbolic operator support for Index() operator.

In reply to Lv Zheng

From: Bob Moore <[email protected]>

ACPICA commit fbe67c46830f10c839941f8512cac5bddcb86bd3

Index (XXXX, 2) is now supported by XXXX [2]

This patch doesn't affect Linux kernel.

---
 drivers/acpi/acpica/aclocal.h |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/acpi/acpica/aclocal.h +1 -1
index 6f70826..8a66fef 100644
@@ -848,7 +848,7 @@ struct acpi_parse_state {
 #define ACPI_PARSEOP_PARAMLIST          0x02
 #define ACPI_PARSEOP_EMPTY_TERMLIST     0x04
 #define ACPI_PARSEOP_PREDEF_CHECKED     0x08
-#define ACPI_PARSEOP_SPECIAL            0x10
+#define ACPI_PARSEOP_CLOSING_PAREN      0x10
 #define ACPI_PARSEOP_COMPOUND           0x20
 #define ACPI_PARSEOP_ASSIGNMENT         0x40
 
Signature · 1 line
1.7.10
author
#4 lore raw

PATCH v2 3/14 ACPICA: Update exception code for "file not found" error

In reply to Lv Zheng

From: Bob Moore <[email protected]>

ACPICA commit ac1564c26d239348ef13455f61d5616f3961ff43

Used by the ACPICA applications.

This patch is a bit broken due to non-portable <errno.h> inclusion as on some platforms, there is no such a header file for their lib-c exports. Fortunately, Linux doesn't compile utfileio.c for either the kernel space ACPICA core (drivers/acpi/acpica) or the userspace ACPICA tools (tools/power/acpi) for now, so it's safe to leave this patch as it is.

---
 drivers/acpi/acpica/utfileio.c |    6 ++++++
 1 file changed, 6 insertions(+)
drivers/acpi/acpica/utfileio.c +6 -0
index 75a94f5..d435b7b 100644
@@ -45,6 +45,7 @@
 #include "accommon.h"
 #include "actables.h"
 #include "acapps.h"
+#include "errno.h"
 
 #ifdef ACPI_ASL_COMPILER
 #include "aslcompiler.h"
@@ -301,6 +302,11 @@ acpi_ut_read_table_from_file(char *filename, struct acpi_table_header ** table)
 	file = fopen(filename, "rb");
 	if (!file) {
 		perror("Could not open input file");
+
+		if (errno == ENOENT) {
+			return (AE_NOT_EXIST);
+		}
+
 		return (status);
 	}
 
Signature · 1 line
1.7.10
author
#5 lore raw

PATCH v2 4/14 ACPICA: Debugger: Update mutexes used for multithreaded debugger

In reply to Lv Zheng

From: Bob Moore <[email protected]>

ACPICA commit 6b2701f619040e803313363f516b200e362a9100

Make these mutex objects independent of the deadlock detection mechanism. This mechanism caused failures with the multithread debugger.

This patch doesn't affect Linux kernel as debugger is currently not fully functioning in the Linux kernel. And the further debugger cleanups will take care of handling debugger command signalling correctly instead of using such kind of mutexes. So it is safe to leave this patch as it is.

---
 drivers/acpi/acpica/acglobal.h |    3 +++
 drivers/acpi/acpica/aclocal.h  |    4 +---
 drivers/acpi/acpica/utdecode.c |    2 --
 drivers/acpi/acpica/utmutex.c  |   21 +++++++++++++++++++++
 include/acpi/platform/acenv.h  |    6 +++---
 5 files changed, 28 insertions(+), 8 deletions(-)
drivers/acpi/acpica/acglobal.h +3 -0
index 09f37b5..593de41 100644
@@ -357,6 +357,9 @@ ACPI_GLOBAL(u16, acpi_gbl_node_type_count_misc);
 ACPI_GLOBAL(u32, acpi_gbl_num_nodes);
 ACPI_GLOBAL(u32, acpi_gbl_num_objects);
 
+ACPI_GLOBAL(acpi_mutex, acpi_gbl_db_command_ready);
+ACPI_GLOBAL(acpi_mutex, acpi_gbl_db_command_complete);
+
 #endif				/* ACPI_DEBUGGER */
 
 /*****************************************************************************
drivers/acpi/acpica/aclocal.h +1 -3
index 8a66fef..918f70d 100644
@@ -83,10 +83,8 @@ union acpi_parse_object;
 #define ACPI_MTX_EVENTS                 3	/* Data for ACPI events */
 #define ACPI_MTX_CACHES                 4	/* Internal caches, general purposes */
 #define ACPI_MTX_MEMORY                 5	/* Debug memory tracking lists */
-#define ACPI_MTX_DEBUG_CMD_COMPLETE     6	/* AML debugger */
-#define ACPI_MTX_DEBUG_CMD_READY        7	/* AML debugger */
 
-#define ACPI_MAX_MUTEX                  7
+#define ACPI_MAX_MUTEX                  5
 #define ACPI_NUM_MUTEX                  ACPI_MAX_MUTEX+1
 
 /* Lock structure for reader/writer interfaces */
drivers/acpi/acpica/utdecode.c +0 -2
index 988e23b..d452a78 100644
@@ -407,8 +407,6 @@ static char *acpi_gbl_mutex_names[ACPI_NUM_MUTEX] = {
 	"ACPI_MTX_Events",
 	"ACPI_MTX_Caches",
 	"ACPI_MTX_Memory",
-	"ACPI_MTX_CommandComplete",
-	"ACPI_MTX_CommandReady"
 };
 
 char *acpi_ut_get_mutex_name(u32 mutex_id)
drivers/acpi/acpica/utmutex.c +21 -0
index 37b8b58..ce406e3 100644
@@ -108,6 +108,21 @@ acpi_status acpi_ut_mutex_initialize(void)
 	/* Create the reader/writer lock for namespace access */
 
 	status = acpi_ut_create_rw_lock(&acpi_gbl_namespace_rw_lock);
+	if (ACPI_FAILURE(status)) {
+		return_ACPI_STATUS(status);
+	}
+#ifdef ACPI_DEBUGGER
+
+	/* Debugger Support */
+
+	status = acpi_os_create_mutex(&acpi_gbl_db_command_ready);
+	if (ACPI_FAILURE(status)) {
+		return_ACPI_STATUS(status);
+	}
+
+	status = acpi_os_create_mutex(&acpi_gbl_db_command_complete);
+#endif
+
 	return_ACPI_STATUS(status);
 }
 
@@ -147,6 +162,12 @@ void acpi_ut_mutex_terminate(void)
 	/* Delete the reader/writer lock */
 
 	acpi_ut_delete_rw_lock(&acpi_gbl_namespace_rw_lock);
+
+#ifdef ACPI_DEBUGGER
+	acpi_os_delete_mutex(acpi_gbl_db_command_ready);
+	acpi_os_delete_mutex(acpi_gbl_db_command_complete);
+#endif
+
 	return_VOID;
 }
 
include/acpi/platform/acenv.h +3 -3
index 15ef08c..056f245 100644
@@ -304,11 +304,11 @@
  * multi-threaded if ACPI_APPLICATION is not set.
  */
 #ifndef DEBUGGER_THREADING
-#ifdef ACPI_APPLICATION
-#define DEBUGGER_THREADING          DEBUGGER_SINGLE_THREADED
+#if !defined (ACPI_APPLICATION) || defined (ACPI_EXEC_APP)
+#define DEBUGGER_THREADING          DEBUGGER_MULTI_THREADED
 
 #else
-#define DEBUGGER_THREADING          DEBUGGER_MULTI_THREADED
+#define DEBUGGER_THREADING          DEBUGGER_SINGLE_THREADED
 #endif
 #endif				/* !DEBUGGER_THREADING */
 
Signature · 1 line
1.7.10
author
#6 lore raw

PATCH v2 5/14 ACPICA: Update NFIT table to rename a flags field

In reply to Lv Zheng

From: Bob Moore <[email protected]>

ACPICA commit 534deab97fb416a13bfede15c538e2c9eac9384a

Updated one of the memory subtable flags to clarify.

---
 drivers/acpi/nfit.c   |    6 +++---
 drivers/acpi/nfit.h   |    2 +-
 include/acpi/actbl1.h |    2 +-
 3 files changed, 5 insertions(+), 5 deletions(-)
drivers/acpi/nfit.c +3 -3
index c1b8d03..bc18aa2 100644
@@ -706,7 +706,7 @@ static ssize_t flags_show(struct device *dev,
 		flags & ACPI_NFIT_MEM_SAVE_FAILED ? "save_fail " : "",
 		flags & ACPI_NFIT_MEM_RESTORE_FAILED ? "restore_fail " : "",
 		flags & ACPI_NFIT_MEM_FLUSH_FAILED ? "flush_fail " : "",
-		flags & ACPI_NFIT_MEM_ARMED ? "not_armed " : "",
+		flags & ACPI_NFIT_MEM_NOT_ARMED ? "not_armed " : "",
 		flags & ACPI_NFIT_MEM_HEALTH_OBSERVED ? "smart_event " : "");
 }
 static DEVICE_ATTR_RO(flags);
@@ -815,7 +815,7 @@ static int acpi_nfit_register_dimms(struct acpi_nfit_desc *acpi_desc)
 			flags |= NDD_ALIASING;
 
 		mem_flags = __to_nfit_memdev(nfit_mem)->flags;
-		if (mem_flags & ACPI_NFIT_MEM_ARMED)
+		if (mem_flags & ACPI_NFIT_MEM_NOT_ARMED)
 			flags |= NDD_UNARMED;
 
 		rc = acpi_nfit_add_dimm(acpi_desc, nfit_mem, device_handle);
@@ -839,7 +839,7 @@ static int acpi_nfit_register_dimms(struct acpi_nfit_desc *acpi_desc)
 		  mem_flags & ACPI_NFIT_MEM_SAVE_FAILED ? " save_fail" : "",
 		  mem_flags & ACPI_NFIT_MEM_RESTORE_FAILED ? " restore_fail":"",
 		  mem_flags & ACPI_NFIT_MEM_FLUSH_FAILED ? " flush_fail" : "",
-		  mem_flags & ACPI_NFIT_MEM_ARMED ? " not_armed" : "");
+		  mem_flags & ACPI_NFIT_MEM_NOT_ARMED ? " not_armed" : "");
 
 	}
 
drivers/acpi/nfit.h +1 -1
index 7e74015..329a1eb 100644
@@ -24,7 +24,7 @@
 #define UUID_NFIT_DIMM "4309ac30-0d11-11e4-9191-0800200c9a66"
 #define ACPI_NFIT_MEM_FAILED_MASK (ACPI_NFIT_MEM_SAVE_FAILED \
 		| ACPI_NFIT_MEM_RESTORE_FAILED | ACPI_NFIT_MEM_FLUSH_FAILED \
-		| ACPI_NFIT_MEM_ARMED)
+		| ACPI_NFIT_MEM_NOT_ARMED)
 
 enum nfit_uuids {
 	NFIT_SPA_VOLATILE,
include/acpi/actbl1.h +1 -1
index fcd5709..1bb979e 100644
@@ -1012,7 +1012,7 @@ struct acpi_nfit_memory_map {
 #define ACPI_NFIT_MEM_SAVE_FAILED       (1)	/* 00: Last SAVE to Memory Device failed */
 #define ACPI_NFIT_MEM_RESTORE_FAILED    (1<<1)	/* 01: Last RESTORE from Memory Device failed */
 #define ACPI_NFIT_MEM_FLUSH_FAILED      (1<<2)	/* 02: Platform flush failed */
-#define ACPI_NFIT_MEM_ARMED             (1<<3)	/* 03: Memory Device observed to be not armed */
+#define ACPI_NFIT_MEM_NOT_ARMED         (1<<3)	/* 03: Memory Device is not armed */
 #define ACPI_NFIT_MEM_HEALTH_OBSERVED   (1<<4)	/* 04: Memory Device observed SMART/health events */
 #define ACPI_NFIT_MEM_HEALTH_ENABLED    (1<<5)	/* 05: SMART/health events enabled */
 
Signature · 1 line
1.7.10
author
#7 lore raw

PATCH v2 6/14 ACPICA: Improve typechecking, both compile-time and runtime

In reply to Lv Zheng

From: Bob Moore <[email protected]>

ACPICA commit 8d0f96e2a11a4ceabb2cae4b41e0ce1f4d3786b9

Adds much stricter typechecking in the iASL compiler, and also adds some additional checking in the interpreter.

---
 drivers/acpi/acpica/aclocal.h  |    8 ++-
 drivers/acpi/acpica/acopcode.h |    4 +-
 drivers/acpi/acpica/amlcode.h  |   11 ++--
 drivers/acpi/acpica/exconvrt.c |    1 +
 drivers/acpi/acpica/exresolv.c |    1 -
 drivers/acpi/acpica/exresop.c  |    2 +
 drivers/acpi/acpica/exstore.c  |  120 ++++++++++++++++++++++++++++++----------
 drivers/acpi/acpica/exstoren.c |    5 +-
 drivers/acpi/acpica/nspredef.c |    2 +-
 drivers/acpi/acpica/utdecode.c |   19 ++++++-
 include/acpi/acexcep.h         |    7 ++-
 11 files changed, 134 insertions(+), 46 deletions(-)
drivers/acpi/acpica/aclocal.h +6 -2
index 918f70d..4e41b43 100644
@@ -285,13 +285,17 @@ acpi_status(*acpi_internal_method) (struct acpi_walk_state * walk_state);
 #define ACPI_BTYPE_BUFFER_FIELD         0x00002000
 #define ACPI_BTYPE_DDB_HANDLE           0x00004000
 #define ACPI_BTYPE_DEBUG_OBJECT         0x00008000
-#define ACPI_BTYPE_REFERENCE            0x00010000
+#define ACPI_BTYPE_REFERENCE_OBJECT     0x00010000	/* From Index(), ref_of(), etc (type6_opcodes) */
 #define ACPI_BTYPE_RESOURCE             0x00020000
+#define ACPI_BTYPE_NAMED_REFERENCE      0x00040000	/* Generic unresolved Name or Namepath */
 
 #define ACPI_BTYPE_COMPUTE_DATA         (ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING | ACPI_BTYPE_BUFFER)
 
 #define ACPI_BTYPE_DATA                 (ACPI_BTYPE_COMPUTE_DATA  | ACPI_BTYPE_PACKAGE)
-#define ACPI_BTYPE_DATA_REFERENCE       (ACPI_BTYPE_DATA | ACPI_BTYPE_REFERENCE | ACPI_BTYPE_DDB_HANDLE)
+
+	/* Used by Copy, de_ref_of, Store, Printf, Fprintf */
+
+#define ACPI_BTYPE_DATA_REFERENCE       (ACPI_BTYPE_DATA | ACPI_BTYPE_REFERENCE_OBJECT | ACPI_BTYPE_DDB_HANDLE)
 #define ACPI_BTYPE_DEVICE_OBJECTS       (ACPI_BTYPE_DEVICE | ACPI_BTYPE_THERMAL | ACPI_BTYPE_PROCESSOR)
 #define ACPI_BTYPE_OBJECTS_AND_REFS     0x0001FFFF	/* ARG or LOCAL */
 #define ACPI_BTYPE_ALL_OBJECTS          0x0000FFFF
drivers/acpi/acpica/acopcode.h +2 -2
index fd85ad0..f9acf92 100644
@@ -211,7 +211,7 @@
 #define ARGI_ARG4                       ARG_NONE
 #define ARGI_ARG5                       ARG_NONE
 #define ARGI_ARG6                       ARG_NONE
-#define ARGI_BANK_FIELD_OP              ARGI_INVALID_OPCODE
+#define ARGI_BANK_FIELD_OP              ARGI_LIST1 (ARGI_INTEGER)
 #define ARGI_BIT_AND_OP                 ARGI_LIST3 (ARGI_INTEGER,    ARGI_INTEGER,       ARGI_TARGETREF)
 #define ARGI_BIT_NAND_OP                ARGI_LIST3 (ARGI_INTEGER,    ARGI_INTEGER,       ARGI_TARGETREF)
 #define ARGI_BIT_NOR_OP                 ARGI_LIST3 (ARGI_INTEGER,    ARGI_INTEGER,       ARGI_TARGETREF)
@@ -307,7 +307,7 @@
 #define ARGI_SLEEP_OP                   ARGI_LIST1 (ARGI_INTEGER)
 #define ARGI_STALL_OP                   ARGI_LIST1 (ARGI_INTEGER)
 #define ARGI_STATICSTRING_OP            ARGI_INVALID_OPCODE
-#define ARGI_STORE_OP                   ARGI_LIST2 (ARGI_DATAREFOBJ, ARGI_TARGETREF)
+#define ARGI_STORE_OP                   ARGI_LIST2 (ARGI_DATAREFOBJ, ARGI_STORE_TARGET)
 #define ARGI_STRING_OP                  ARGI_INVALID_OPCODE
 #define ARGI_SUBTRACT_OP                ARGI_LIST3 (ARGI_INTEGER,    ARGI_INTEGER,       ARGI_TARGETREF)
 #define ARGI_THERMAL_ZONE_OP            ARGI_INVALID_OPCODE
drivers/acpi/acpica/amlcode.h +6 -5
index be9fd00..883f20c 100644
@@ -277,14 +277,15 @@
 #define ARGI_TARGETREF              0x0F	/* Target, subject to implicit conversion */
 #define ARGI_FIXED_TARGET           0x10	/* Target, no implicit conversion */
 #define ARGI_SIMPLE_TARGET          0x11	/* Name, Local, Arg -- no implicit conversion */
+#define ARGI_STORE_TARGET           0x12	/* Target for store is TARGETREF + package objects */
 
 /* Multiple/complex types */
 
-#define ARGI_DATAOBJECT             0x12	/* Buffer, String, package or reference to a node - Used only by size_of operator */
-#define ARGI_COMPLEXOBJ             0x13	/* Buffer, String, or package (Used by INDEX op only) */
-#define ARGI_REF_OR_STRING          0x14	/* Reference or String (Used by DEREFOF op only) */
-#define ARGI_REGION_OR_BUFFER       0x15	/* Used by LOAD op only */
-#define ARGI_DATAREFOBJ             0x16
+#define ARGI_DATAOBJECT             0x13	/* Buffer, String, package or reference to a node - Used only by size_of operator */
+#define ARGI_COMPLEXOBJ             0x14	/* Buffer, String, or package (Used by INDEX op only) */
+#define ARGI_REF_OR_STRING          0x15	/* Reference or String (Used by DEREFOF op only) */
+#define ARGI_REGION_OR_BUFFER       0x16	/* Used by LOAD op only */
+#define ARGI_DATAREFOBJ             0x17
 
 /* Note: types above can expand to 0x1F maximum */
 
drivers/acpi/acpica/exconvrt.c +1 -0
index 075d654..1e4c5b6 100644
@@ -618,6 +618,7 @@ acpi_ex_convert_to_target_type(acpi_object_type destination_type,
 		break;
 
 	case ARGI_TARGETREF:
+	case ARGI_STORE_TARGET:
 
 		switch (destination_type) {
 		case ACPI_TYPE_INTEGER:
drivers/acpi/acpica/exresolv.c +0 -1
index 7b10912..a1afe1a 100644
@@ -209,7 +209,6 @@ acpi_ex_resolve_object_to_value(union acpi_operand_object **stack_ptr,
 					 * (i.e., dereference the package index)
 					 * Delete the ref object, increment the returned object
 					 */
-					acpi_ut_remove_reference(stack_desc);
 					acpi_ut_add_reference(obj_desc);
 					*stack_ptr = obj_desc;
 				} else {
drivers/acpi/acpica/exresop.c +2 -0
index d2964af..424442d 100644
@@ -307,6 +307,8 @@ acpi_ex_resolve_operands(u16 opcode,
 		case ARGI_TARGETREF:	/* Allows implicit conversion rules before store */
 		case ARGI_FIXED_TARGET:	/* No implicit conversion before store to target */
 		case ARGI_SIMPLE_TARGET:	/* Name, Local, or arg - no implicit conversion  */
+		case ARGI_STORE_TARGET:
+
 			/*
 			 * Need an operand of type ACPI_TYPE_LOCAL_REFERENCE
 			 * A Namespace Node is OK as-is
drivers/acpi/acpica/exstore.c +91 -29

186 lines not on this page · raw message

drivers/acpi/acpica/exstoren.c +3 -2
index 3101607..d1841de 100644
@@ -122,9 +122,10 @@ acpi_ex_resolve_object(union acpi_operand_object **source_desc_ptr,
 			/* Conversion successful but still not a valid type */
 
 			ACPI_ERROR((AE_INFO,
-				    "Cannot assign type %s to %s (must be type Int/Str/Buf)",
+				    "Cannot assign type [%s] to [%s] (must be type Int/Str/Buf)",
 				    acpi_ut_get_object_type_name(source_desc),
 				    acpi_ut_get_type_name(target_type)));
+
 			status = AE_AML_OPERAND_TYPE;
 		}
 		break;
@@ -275,7 +276,7 @@ acpi_ex_store_object_to_object(union acpi_operand_object *source_desc,
 		/*
 		 * All other types come here.
 		 */
-		ACPI_WARNING((AE_INFO, "Store into type %s not implemented",
+		ACPI_WARNING((AE_INFO, "Store into type [%s] not implemented",
 			      acpi_ut_get_object_type_name(dest_desc)));
 
 		status = AE_NOT_IMPLEMENTED;
drivers/acpi/acpica/nspredef.c +1 -1
index 0eb5431..0c20980 100644
@@ -226,7 +226,7 @@ acpi_ns_check_object_type(struct acpi_evaluate_info *info,
 {
 	union acpi_operand_object *return_object = *return_object_ptr;
 	acpi_status status = AE_OK;
-	char type_buffer[48];	/* Room for 5 types */
+	char type_buffer[96];	/* Room for 10 types */
 
 	/* A Namespace node should not get here, but make sure */
 
drivers/acpi/acpica/utdecode.c +17 -2
index d452a78..ecaaaff 100644
@@ -232,12 +232,27 @@ char *acpi_ut_get_type_name(acpi_object_type type)
 
 char *acpi_ut_get_object_type_name(union acpi_operand_object *obj_desc)
 {
+	ACPI_FUNCTION_TRACE(ut_get_object_type_name);
 
 	if (!obj_desc) {
-		return ("[NULL Object Descriptor]");
+		ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Null Object Descriptor\n"));
+		return_PTR("[NULL Object Descriptor]");
 	}
 
-	return (acpi_ut_get_type_name(obj_desc->common.type));
+	/* These descriptor types share a common area */
+
+	if ((ACPI_GET_DESCRIPTOR_TYPE(obj_desc) != ACPI_DESC_TYPE_OPERAND) &&
+	    (ACPI_GET_DESCRIPTOR_TYPE(obj_desc) != ACPI_DESC_TYPE_NAMED)) {
+		ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
+				  "Invalid object descriptor type: 0x%2.2X [%s] (%p)\n",
+				  ACPI_GET_DESCRIPTOR_TYPE(obj_desc),
+				  acpi_ut_get_descriptor_name(obj_desc),
+				  obj_desc));
+
+		return_PTR("Invalid object");
+	}
+
+	return_PTR(acpi_ut_get_type_name(obj_desc->common.type));
 }
 
 /*******************************************************************************
include/acpi/acexcep.h +5 -2
index 9f20eb4a..204f581 100644
@@ -193,8 +193,9 @@ struct acpi_exception_info {
 #define AE_AML_ILLEGAL_ADDRESS          EXCEP_AML (0x0020)
 #define AE_AML_INFINITE_LOOP            EXCEP_AML (0x0021)
 #define AE_AML_UNINITIALIZED_NODE       EXCEP_AML (0x0022)
+#define AE_AML_TARGET_TYPE              EXCEP_AML (0x0023)
 
-#define AE_CODE_AML_MAX                 0x0022
+#define AE_CODE_AML_MAX                 0x0023
 
 /*
  * Internal exceptions used for control
@@ -358,7 +359,9 @@ static const struct acpi_exception_info acpi_gbl_exception_names_aml[] = {
 	EXCEP_TXT("AE_AML_INFINITE_LOOP",
 		  "An apparent infinite AML While loop, method was aborted"),
 	EXCEP_TXT("AE_AML_UNINITIALIZED_NODE",
-		  "A namespace node is uninitialized or unresolved")
+		  "A namespace node is uninitialized or unresolved"),
+	EXCEP_TXT("AE_AML_TARGET_TYPE",
+		  "A target operand of an incorrect type was encountered")
 };
 
 static const struct acpi_exception_info acpi_gbl_exception_names_ctrl[] = {
Signature · 1 line
1.7.10
author
#8 lore raw

PATCH v2 7/14 ACPICA: iASL: General cleanup of the file suffix #defines

In reply to Lv Zheng

From: Bob Moore <[email protected]>

ACPICA commit bed456ed2976bdaafdef406b982fdf6c539befc0

Removed some extraneous defines, reordered others.

---
 drivers/acpi/acpica/acapps.h              |    2 +-
 tools/power/acpi/tools/acpidump/apfiles.c |    2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)
drivers/acpi/acpica/acapps.h +1 -1
index e9f0833..e4cc48f 100644
@@ -88,7 +88,7 @@
 	acpi_os_printf (" %-18s%s\n", name, description);
 
 #define FILE_SUFFIX_DISASSEMBLY     "dsl"
-#define ACPI_TABLE_FILE_SUFFIX      ".dat"
+#define FILE_SUFFIX_BINARY_TABLE    ".dat"	/* Needs the dot */
 
 /*
  * getopt
tools/power/acpi/tools/acpidump/apfiles.c +1 -1
index a37f970..a1c62de 100644
@@ -150,7 +150,7 @@ int ap_write_to_binary_file(struct acpi_table_header *table, u32 instance)
 		strcat(filename, instance_str);
 	}
 
-	strcat(filename, ACPI_TABLE_FILE_SUFFIX);
+	strcat(filename, FILE_SUFFIX_BINARY_TABLE);
 
 	if (gbl_verbose_mode) {
 		acpi_log_error
Signature · 1 line
1.7.10
author
#9 lore raw

PATCH v2 8/14 ACPICA: Linuxize: Export debugger files to Linux

In reply to Lv Zheng

ACPICA commit bc2d3daa4bd429611451f28800def9fea55e63de

This patch exports debugger files to Linux.

---
 drivers/acpi/acpica/dbcmds.c    | 1187 ++++++++++++++++++++++++++++++++++++
 drivers/acpi/acpica/dbconvert.c |  484 +++++++++++++++
 drivers/acpi/acpica/dbdisply.c  | 1108 ++++++++++++++++++++++++++++++++++
 drivers/acpi/acpica/dbexec.c    |  753 +++++++++++++++++++++++
 drivers/acpi/acpica/dbfileio.c  |  256 ++++++++
 drivers/acpi/acpica/dbhistry.c  |  239 ++++++++
 drivers/acpi/acpica/dbinput.c   | 1274 +++++++++++++++++++++++++++++++++++++++
 drivers/acpi/acpica/dbmethod.c  |  369 ++++++++++++
 drivers/acpi/acpica/dbnames.c   |  947 +++++++++++++++++++++++++++++
 drivers/acpi/acpica/dbobject.c  |  533 ++++++++++++++++
 drivers/acpi/acpica/dbstats.c   |  546 +++++++++++++++++
 drivers/acpi/acpica/dbtest.c    | 1057 ++++++++++++++++++++++++++++++++
 drivers/acpi/acpica/dbutils.c   |  457 ++++++++++++++
 drivers/acpi/acpica/dbxface.c   |  467 ++++++++++++++
 14 files changed, 9677 insertions(+)
 create mode 100644 drivers/acpi/acpica/dbcmds.c
 create mode 100644 drivers/acpi/acpica/dbconvert.c
 create mode 100644 drivers/acpi/acpica/dbdisply.c
 create mode 100644 drivers/acpi/acpica/dbexec.c
 create mode 100644 drivers/acpi/acpica/dbfileio.c
 create mode 100644 drivers/acpi/acpica/dbhistry.c
 create mode 100644 drivers/acpi/acpica/dbinput.c
 create mode 100644 drivers/acpi/acpica/dbmethod.c
 create mode 100644 drivers/acpi/acpica/dbnames.c
 create mode 100644 drivers/acpi/acpica/dbobject.c
 create mode 100644 drivers/acpi/acpica/dbstats.c
 create mode 100644 drivers/acpi/acpica/dbtest.c
 create mode 100644 drivers/acpi/acpica/dbutils.c
 create mode 100644 drivers/acpi/acpica/dbxface.c
drivers/acpi/acpica/dbcmds.c new file +1187 -0
new file mode 100644
index 0000000..30414b3
@@ -0,0 +1,1187 @@
+/*******************************************************************************
+ *
+ * Module Name: dbcmds - Miscellaneous debug commands and output routines
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, Intel Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+#include <acpi/acpi.h>
+#include "accommon.h"
+#include "acevents.h"
+#include "acdebug.h"
+#include "acnamesp.h"
+#include "acresrc.h"
+#include "actables.h"
+
+#define _COMPONENT          ACPI_CA_DEBUGGER
+ACPI_MODULE_NAME("dbcmds")
+
+/* Local prototypes */
+static void
+acpi_dm_compare_aml_resources(u8 *aml1_buffer,
+			      acpi_rsdesc_size aml1_buffer_length,
+			      u8 *aml2_buffer,
+			      acpi_rsdesc_size aml2_buffer_length);
+
+static acpi_status
+acpi_dm_test_resource_conversion(struct acpi_namespace_node *node, char *name);
+
+static acpi_status
+acpi_db_resource_callback(struct acpi_resource *resource, void *context);
+
+static acpi_status
+acpi_db_device_resources(acpi_handle obj_handle,
+			 u32 nesting_level, void *context, void **return_value);
+
+static void acpi_db_do_one_sleep_state(u8 sleep_state);
+
+static char *acpi_db_trace_method_name = NULL;
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_convert_to_node
+ *
+ * PARAMETERS:  in_string           - String to convert
+ *
+ * RETURN:      Pointer to a NS node
+ *
+ * DESCRIPTION: Convert a string to a valid NS pointer. Handles numeric or
+ *              alphanumeric strings.
+ *
+ ******************************************************************************/
+
+struct acpi_namespace_node *acpi_db_convert_to_node(char *in_string)
+{
+	struct acpi_namespace_node *node;
+	acpi_size address;
+
+	if ((*in_string >= 0x30) && (*in_string <= 0x39)) {
+
+		/* Numeric argument, convert */
+
+		address = strtoul(in_string, NULL, 16);
+		node = ACPI_TO_POINTER(address);
+		if (!acpi_os_readable(node, sizeof(struct acpi_namespace_node))) {
+			acpi_os_printf("Address %p is invalid", node);
+			return (NULL);
+		}
+
+		/* Make sure pointer is valid NS node */
+
+		if (ACPI_GET_DESCRIPTOR_TYPE(node) != ACPI_DESC_TYPE_NAMED) {
+			acpi_os_printf
+			    ("Address %p is not a valid namespace node [%s]\n",
+			     node, acpi_ut_get_descriptor_name(node));
+			return (NULL);
+		}
+	} else {
+		/*
+		 * Alpha argument: The parameter is a name string that must be
+		 * resolved to a Namespace object.
+		 */
+		node = acpi_db_local_ns_lookup(in_string);
+		if (!node) {
+			acpi_os_printf
+			    ("Could not find [%s] in namespace, defaulting to root node\n",
+			     in_string);
+			node = acpi_gbl_root_node;
+		}
+	}
+
+	return (node);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_sleep
+ *
+ * PARAMETERS:  object_arg          - Desired sleep state (0-5). NULL means
+ *                                    invoke all possible sleep states.
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Simulate sleep/wake sequences
+ *
+ ******************************************************************************/
+
+acpi_status acpi_db_sleep(char *object_arg)
+{
+	u8 sleep_state;
+	u32 i;
+
+	ACPI_FUNCTION_TRACE(acpi_db_sleep);
+
+	/* Null input (no arguments) means to invoke all sleep states */
+
+	if (!object_arg) {
+		acpi_os_printf("Invoking all possible sleep states, 0-%d\n",
+			       ACPI_S_STATES_MAX);
+
+		for (i = 0; i <= ACPI_S_STATES_MAX; i++) {
+			acpi_db_do_one_sleep_state((u8)i);
+		}
+
+		return_ACPI_STATUS(AE_OK);
+	}
+
+	/* Convert argument to binary and invoke the sleep state */
+
+	sleep_state = (u8)strtoul(object_arg, NULL, 0);
+	acpi_db_do_one_sleep_state(sleep_state);
+	return_ACPI_STATUS(AE_OK);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_do_one_sleep_state
+ *
+ * PARAMETERS:  sleep_state         - Desired sleep state (0-5)
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Simulate a sleep/wake sequence
+ *
+ ******************************************************************************/
+
+static void acpi_db_do_one_sleep_state(u8 sleep_state)
+{
+	acpi_status status;
+	u8 sleep_type_a;
+	u8 sleep_type_b;
+
+	/* Validate parameter */
+
+	if (sleep_state > ACPI_S_STATES_MAX) {
+		acpi_os_printf("Sleep state %d out of range (%d max)\n",
+			       sleep_state, ACPI_S_STATES_MAX);
+		return;
+	}
+
+	acpi_os_printf("\n---- Invoking sleep state S%d (%s):\n",
+		       sleep_state, acpi_gbl_sleep_state_names[sleep_state]);
+
+	/* Get the values for the sleep type registers (for display only) */
+
+	status =
+	    acpi_get_sleep_type_data(sleep_state, &sleep_type_a, &sleep_type_b);
+	if (ACPI_FAILURE(status)) {
+		acpi_os_printf("Could not evaluate [%s] method, %s\n",
+			       acpi_gbl_sleep_state_names[sleep_state],
+			       acpi_format_exception(status));
+		return;
+	}
+
+	acpi_os_printf
+	    ("Register values for sleep state S%d: Sleep-A: %.2X, Sleep-B: %.2X\n",
+	     sleep_state, sleep_type_a, sleep_type_b);
+
+	/* Invoke the various sleep/wake interfaces */
+
+	acpi_os_printf("**** Sleep: Prepare to sleep (S%d) ****\n",
+		       sleep_state);
+	status = acpi_enter_sleep_state_prep(sleep_state);
+	if (ACPI_FAILURE(status)) {
+		goto error_exit;
+	}
+
+	acpi_os_printf("**** Sleep: Going to sleep (S%d) ****\n", sleep_state);
+	status = acpi_enter_sleep_state(sleep_state);
+	if (ACPI_FAILURE(status)) {
+		goto error_exit;
+	}
+
+	acpi_os_printf("**** Wake: Prepare to return from sleep (S%d) ****\n",
+		       sleep_state);
+	status = acpi_leave_sleep_state_prep(sleep_state);
+	if (ACPI_FAILURE(status)) {
+		goto error_exit;
+	}
+
+	acpi_os_printf("**** Wake: Return from sleep (S%d) ****\n",
+		       sleep_state);
+	status = acpi_leave_sleep_state(sleep_state);
+	if (ACPI_FAILURE(status)) {
+		goto error_exit;
+	}
+
+	return;
+
+error_exit:
+	ACPI_EXCEPTION((AE_INFO, status, "During invocation of sleep state S%d",
+			sleep_state));
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_display_locks
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Display information about internal mutexes.
+ *
+ ******************************************************************************/
+
+void acpi_db_display_locks(void)
+{
+	u32 i;
+
+	for (i = 0; i < ACPI_MAX_MUTEX; i++) {
+		acpi_os_printf("%26s : %s\n", acpi_ut_get_mutex_name(i),
+			       acpi_gbl_mutex_info[i].thread_id ==
+			       ACPI_MUTEX_NOT_ACQUIRED ? "Locked" : "Unlocked");
+	}
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_display_table_info
+ *
+ * PARAMETERS:  table_arg           - Name of table to be displayed
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Display information about loaded tables. Current
+ *              implementation displays all loaded tables.
+ *
+ ******************************************************************************/
+
+void acpi_db_display_table_info(char *table_arg)
+{
+	u32 i;
+	struct acpi_table_desc *table_desc;
+	acpi_status status;
+
+	/* Header */
+
+	acpi_os_printf("Idx ID  Status Type                    "
+		       "TableHeader (Sig, Address, Length, Misc)\n");
+
+	/* Walk the entire root table list */
+
+	for (i = 0; i < acpi_gbl_root_table_list.current_table_count; i++) {
+		table_desc = &acpi_gbl_root_table_list.tables[i];
+
+		/* Index and Table ID */
+
+		acpi_os_printf("%3u %.2u ", i, table_desc->owner_id);
+
+		/* Decode the table flags */
+
+		if (!(table_desc->flags & ACPI_TABLE_IS_LOADED)) {
+			acpi_os_printf("NotLoaded ");
+		} else {
+			acpi_os_printf(" Loaded ");
+		}
+
+		switch (table_desc->flags & ACPI_TABLE_ORIGIN_MASK) {
+		case ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL:
+
+			acpi_os_printf("External/virtual ");
+			break;
+
+		case ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL:
+
+			acpi_os_printf("Internal/physical ");
+			break;
+
+		case ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL:
+
+			acpi_os_printf("Internal/virtual ");
+			break;
+
+		default:
+
+			acpi_os_printf("INVALID TYPE    ");
+			break;
+		}
+
+		/* Make sure that the table is mapped */
+
+		status = acpi_tb_validate_table(table_desc);
+		if (ACPI_FAILURE(status)) {
+			return;
+		}
+
+		/* Dump the table header */
+
+		if (table_desc->pointer) {
+			acpi_tb_print_table_header(table_desc->address,
+						   table_desc->pointer);
+		} else {
+			/* If the pointer is null, the table has been unloaded */
+
+			ACPI_INFO((AE_INFO, "%4.4s - Table has been unloaded",
+				   table_desc->signature.ascii));
+		}
+	}
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_unload_acpi_table
+ *
+ * PARAMETERS:  object_name         - Namespace pathname for an object that
+ *                                    is owned by the table to be unloaded
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Unload an ACPI table, via any namespace node that is owned
+ *              by the table.
+ *
+ ******************************************************************************/
+
+void acpi_db_unload_acpi_table(char *object_name)
+{
+	struct acpi_namespace_node *node;
+	acpi_status status;
+
+	/* Translate name to an Named object */
+
+	node = acpi_db_convert_to_node(object_name);
+	if (!node) {
+		return;
+	}
+
+	status = acpi_unload_parent_table(ACPI_CAST_PTR(acpi_handle, node));
+	if (ACPI_SUCCESS(status)) {
+		acpi_os_printf("Parent of [%s] (%p) unloaded and uninstalled\n",
+			       object_name, node);
+	} else {
+		acpi_os_printf("%s, while unloading parent table of [%s]\n",
+			       acpi_format_exception(status), object_name);
+	}
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_send_notify
+ *
+ * PARAMETERS:  name                - Name of ACPI object where to send notify
+ *              value               - Value of the notify to send.
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Send an ACPI notification. The value specified is sent to the
+ *              named object as an ACPI notify.
+ *
+ ******************************************************************************/
+
+void acpi_db_send_notify(char *name, u32 value)
+{
+	struct acpi_namespace_node *node;
+	acpi_status status;
+
+	/* Translate name to an Named object */
+
+	node = acpi_db_convert_to_node(name);
+	if (!node) {
+		return;
+	}
+
+	/* Dispatch the notify if legal */
+
+	if (acpi_ev_is_notify_object(node)) {
+		status = acpi_ev_queue_notify_request(node, value);
+		if (ACPI_FAILURE(status)) {
+			acpi_os_printf("Could not queue notify\n");
+		}
+	} else {
+		acpi_os_printf("Named object [%4.4s] Type %s, "
+			       "must be Device/Thermal/Processor type\n",
+			       acpi_ut_get_node_name(node),
+			       acpi_ut_get_type_name(node->type));
+	}
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_display_interfaces
+ *
+ * PARAMETERS:  action_arg          - Null, "install", or "remove"
+ *              interface_name_arg  - Name for install/remove options
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Display or modify the global _OSI interface list
+ *
+ ******************************************************************************/
+
+void acpi_db_display_interfaces(char *action_arg, char *interface_name_arg)
+{
+	struct acpi_interface_info *next_interface;
+	char *sub_string;
+	acpi_status status;
+
+	/* If no arguments, just display current interface list */
+
+	if (!action_arg) {
+		(void)acpi_os_acquire_mutex(acpi_gbl_osi_mutex,
+					    ACPI_WAIT_FOREVER);
+
+		next_interface = acpi_gbl_supported_interfaces;
+		while (next_interface) {
+			if (!(next_interface->flags & ACPI_OSI_INVALID)) {
+				acpi_os_printf("%s\n", next_interface->name);
+			}
+
+			next_interface = next_interface->next;
+		}
+
+		acpi_os_release_mutex(acpi_gbl_osi_mutex);
+		return;
+	}
+
+	/* If action_arg exists, so must interface_name_arg */
+
+	if (!interface_name_arg) {
+		acpi_os_printf("Missing Interface Name argument\n");
+		return;
+	}
+
+	/* Uppercase the action for match below */
+
+	acpi_ut_strupr(action_arg);
+
+	/* install - install an interface */
+
+	sub_string = strstr("INSTALL", action_arg);
+	if (sub_string) {
+		status = acpi_install_interface(interface_name_arg);
+		if (ACPI_FAILURE(status)) {
+			acpi_os_printf("%s, while installing \"%s\"\n",
+				       acpi_format_exception(status),
+				       interface_name_arg);
+		}
+		return;
+	}
+
+	/* remove - remove an interface */
+
+	sub_string = strstr("REMOVE", action_arg);
+	if (sub_string) {
+		status = acpi_remove_interface(interface_name_arg);
+		if (ACPI_FAILURE(status)) {
+			acpi_os_printf("%s, while removing \"%s\"\n",
+				       acpi_format_exception(status),
+				       interface_name_arg);
+		}
+		return;
+	}
+
+	/* Invalid action_arg */
+
+	acpi_os_printf("Invalid action argument: %s\n", action_arg);
+	return;
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_display_template
+ *
+ * PARAMETERS:  buffer_arg          - Buffer name or address
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Dump a buffer that contains a resource template
+ *
+ ******************************************************************************/
+
+void acpi_db_display_template(char *buffer_arg)
+{
+	struct acpi_namespace_node *node;
+	acpi_status status;
+	struct acpi_buffer return_buffer;
+
+	/* Translate buffer_arg to an Named object */
+
+	node = acpi_db_convert_to_node(buffer_arg);
+	if (!node || (node == acpi_gbl_root_node)) {
+		acpi_os_printf("Invalid argument: %s\n", buffer_arg);
+		return;
+	}
+
+	/* We must have a buffer object */
+
+	if (node->type != ACPI_TYPE_BUFFER) {
+		acpi_os_printf
+		    ("Not a Buffer object, cannot be a template: %s\n",
+		     buffer_arg);
+		return;
+	}
+
+	return_buffer.length = ACPI_DEBUG_BUFFER_SIZE;
+	return_buffer.pointer = acpi_gbl_db_buffer;
+
+	/* Attempt to convert the raw buffer to a resource list */
+
+	status = acpi_rs_create_resource_list(node->object, &return_buffer);
+
+	acpi_db_set_output_destination(ACPI_DB_REDIRECTABLE_OUTPUT);
+	acpi_dbg_level |= ACPI_LV_RESOURCES;
+
+	if (ACPI_FAILURE(status)) {
+		acpi_os_printf
+		    ("Could not convert Buffer to a resource list: %s, %s\n",
+		     buffer_arg, acpi_format_exception(status));
+		goto dump_buffer;
+	}
+
+	/* Now we can dump the resource list */
+
+	acpi_rs_dump_resource_list(ACPI_CAST_PTR(struct acpi_resource,
+						 return_buffer.pointer));
+
+dump_buffer:
+	acpi_os_printf("\nRaw data buffer:\n");
+	acpi_ut_debug_dump_buffer((u8 *)node->object->buffer.pointer,
+				  node->object->buffer.length,
+				  DB_BYTE_DISPLAY, ACPI_UINT32_MAX);
+
+	acpi_db_set_output_destination(ACPI_DB_CONSOLE_OUTPUT);
+	return;
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_dm_compare_aml_resources
+ *
+ * PARAMETERS:  aml1_buffer         - Contains first resource list
+ *              aml1_buffer_length  - Length of first resource list
+ *              aml2_buffer         - Contains second resource list
+ *              aml2_buffer_length  - Length of second resource list
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Compare two AML resource lists, descriptor by descriptor (in
+ *              order to isolate a miscompare to an individual resource)
+ *
+ ******************************************************************************/
+
+static void
+acpi_dm_compare_aml_resources(u8 *aml1_buffer,
+			      acpi_rsdesc_size aml1_buffer_length,
+			      u8 *aml2_buffer,
+			      acpi_rsdesc_size aml2_buffer_length)
+{
+	u8 *aml1;
+	u8 *aml2;
+	u8 *aml1_end;
+	u8 *aml2_end;
+	acpi_rsdesc_size aml1_length;
+	acpi_rsdesc_size aml2_length;
+	acpi_rsdesc_size offset = 0;
+	u8 resource_type;
+	u32 count = 0;
+	u32 i;
+
+	/* Compare overall buffer sizes (may be different due to size rounding) */
+
+	if (aml1_buffer_length != aml2_buffer_length) {
+		acpi_os_printf("**** Buffer length mismatch in converted "
+			       "AML: Original %X, New %X ****\n",
+			       aml1_buffer_length, aml2_buffer_length);
+	}
+
+	aml1 = aml1_buffer;
+	aml2 = aml2_buffer;
+	aml1_end = aml1_buffer + aml1_buffer_length;
+	aml2_end = aml2_buffer + aml2_buffer_length;
+
+	/* Walk the descriptor lists, comparing each descriptor */
+
+	while ((aml1 < aml1_end) && (aml2 < aml2_end)) {
+
+		/* Get the lengths of each descriptor */
+
+		aml1_length = acpi_ut_get_descriptor_length(aml1);
+		aml2_length = acpi_ut_get_descriptor_length(aml2);
+		resource_type = acpi_ut_get_resource_type(aml1);
+
+		/* Check for descriptor length match */
+
+		if (aml1_length != aml2_length) {
+			acpi_os_printf
+			    ("**** Length mismatch in descriptor [%.2X] type %2.2X, "
+			     "Offset %8.8X Len1 %X, Len2 %X ****\n", count,
+			     resource_type, offset, aml1_length, aml2_length);
+		}
+
+		/* Check for descriptor byte match */
+
+		else if (memcmp(aml1, aml2, aml1_length)) {
+			acpi_os_printf
+			    ("**** Data mismatch in descriptor [%.2X] type %2.2X, "
+			     "Offset %8.8X ****\n", count, resource_type,
+			     offset);
+
+			for (i = 0; i < aml1_length; i++) {
+				if (aml1[i] != aml2[i]) {
+					acpi_os_printf
+					    ("Mismatch at byte offset %.2X: is %2.2X, "
+					     "should be %2.2X\n", i, aml2[i],
+					     aml1[i]);
+				}
+			}
+		}
+
+		/* Exit on end_tag descriptor */
+
+		if (resource_type == ACPI_RESOURCE_NAME_END_TAG) {
+			return;
+		}
+
+		/* Point to next descriptor in each buffer */
+
+		count++;
+		offset += aml1_length;
+		aml1 += aml1_length;
+		aml2 += aml2_length;
+	}
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_dm_test_resource_conversion
+ *
+ * PARAMETERS:  node                - Parent device node
+ *              name                - resource method name (_CRS)
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Compare the original AML with a conversion of the AML to
+ *              internal resource list, then back to AML.
+ *
+ ******************************************************************************/
+
+static acpi_status
+acpi_dm_test_resource_conversion(struct acpi_namespace_node *node, char *name)
+{
+	acpi_status status;
+	struct acpi_buffer return_buffer;
+	struct acpi_buffer resource_buffer;
+	struct acpi_buffer new_aml;
+	union acpi_object *original_aml;
+
+	acpi_os_printf("Resource Conversion Comparison:\n");
+
+	new_aml.length = ACPI_ALLOCATE_LOCAL_BUFFER;
+	return_buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
+	resource_buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
+
+	/* Get the original _CRS AML resource template */
+
+	status = acpi_evaluate_object(node, name, NULL, &return_buffer);
+	if (ACPI_FAILURE(status)) {
+		acpi_os_printf("Could not obtain %s: %s\n",
+			       name, acpi_format_exception(status));
+		return (status);
+	}
+
+	/* Get the AML resource template, converted to internal resource structs */
+
+	status = acpi_get_current_resources(node, &resource_buffer);
+	if (ACPI_FAILURE(status)) {
+		acpi_os_printf("AcpiGetCurrentResources failed: %s\n",
+			       acpi_format_exception(status));
+		goto exit1;
+	}
+
+	/* Convert internal resource list to external AML resource template */
+
+	status = acpi_rs_create_aml_resources(&resource_buffer, &new_aml);
+	if (ACPI_FAILURE(status)) {
+		acpi_os_printf("AcpiRsCreateAmlResources failed: %s\n",
+			       acpi_format_exception(status));
+		goto exit2;
+	}
+
+	/* Compare original AML to the newly created AML resource list */
+
+	original_aml = return_buffer.pointer;
+
+	acpi_dm_compare_aml_resources(original_aml->buffer.pointer,
+				      (acpi_rsdesc_size) original_aml->buffer.
+				      length, new_aml.pointer,
+				      (acpi_rsdesc_size) new_aml.length);
+
+	/* Cleanup and exit */
+
+	ACPI_FREE(new_aml.pointer);
+exit2:
+	ACPI_FREE(resource_buffer.pointer);
+exit1:
+	ACPI_FREE(return_buffer.pointer);
+	return (status);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_resource_callback
+ *
+ * PARAMETERS:  acpi_walk_resource_callback
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Simple callback to exercise acpi_walk_resources and
+ *              acpi_walk_resource_buffer.
+ *
+ ******************************************************************************/
+
+static acpi_status
+acpi_db_resource_callback(struct acpi_resource *resource, void *context)
+{
+
+	return (AE_OK);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_device_resources
+ *
+ * PARAMETERS:  acpi_walk_callback
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Display the _PRT/_CRS/_PRS resources for a device object.
+ *
+ ******************************************************************************/
+
+static acpi_status
+acpi_db_device_resources(acpi_handle obj_handle,
+			 u32 nesting_level, void *context, void **return_value)
+{
+	struct acpi_namespace_node *node;
+	struct acpi_namespace_node *prt_node = NULL;
+	struct acpi_namespace_node *crs_node = NULL;
+	struct acpi_namespace_node *prs_node = NULL;
+	struct acpi_namespace_node *aei_node = NULL;
+	char *parent_path;
+	struct acpi_buffer return_buffer;
+	acpi_status status;
+
+	node = ACPI_CAST_PTR(struct acpi_namespace_node, obj_handle);
+	parent_path = acpi_ns_get_external_pathname(node);
+	if (!parent_path) {
+		return (AE_NO_MEMORY);
+	}
+
+	/* Get handles to the resource methods for this device */
+
+	(void)acpi_get_handle(node, METHOD_NAME__PRT,
+			      ACPI_CAST_PTR(acpi_handle, &prt_node));
+	(void)acpi_get_handle(node, METHOD_NAME__CRS,
+			      ACPI_CAST_PTR(acpi_handle, &crs_node));
+	(void)acpi_get_handle(node, METHOD_NAME__PRS,
+			      ACPI_CAST_PTR(acpi_handle, &prs_node));
+	(void)acpi_get_handle(node, METHOD_NAME__AEI,
+			      ACPI_CAST_PTR(acpi_handle, &aei_node));
+
+	if (!prt_node && !crs_node && !prs_node && !aei_node) {
+		goto cleanup;	/* Nothing to do */
+	}
+
+	acpi_os_printf("\nDevice: %s\n", parent_path);
+
+	/* Prepare for a return object of arbitrary size */
+
+	return_buffer.pointer = acpi_gbl_db_buffer;
+	return_buffer.length = ACPI_DEBUG_BUFFER_SIZE;
+
+	/* _PRT */
+
+	if (prt_node) {
+		acpi_os_printf("Evaluating _PRT\n");
+
+		status =
+		    acpi_evaluate_object(prt_node, NULL, NULL, &return_buffer);
+		if (ACPI_FAILURE(status)) {
+			acpi_os_printf("Could not evaluate _PRT: %s\n",
+				       acpi_format_exception(status));
+			goto get_crs;
+		}
+
+		return_buffer.pointer = acpi_gbl_db_buffer;
+		return_buffer.length = ACPI_DEBUG_BUFFER_SIZE;
+
+		status = acpi_get_irq_routing_table(node, &return_buffer);
+		if (ACPI_FAILURE(status)) {
+			acpi_os_printf("GetIrqRoutingTable failed: %s\n",
+				       acpi_format_exception(status));
+			goto get_crs;
+		}
+
+		acpi_rs_dump_irq_list(ACPI_CAST_PTR(u8, acpi_gbl_db_buffer));
+	}
+
+	/* _CRS */
+
+get_crs:
+	if (crs_node) {
+		acpi_os_printf("Evaluating _CRS\n");
+
+		return_buffer.pointer = acpi_gbl_db_buffer;
+		return_buffer.length = ACPI_DEBUG_BUFFER_SIZE;
+
+		status =
+		    acpi_evaluate_object(crs_node, NULL, NULL, &return_buffer);
+		if (ACPI_FAILURE(status)) {
+			acpi_os_printf("Could not evaluate _CRS: %s\n",
+				       acpi_format_exception(status));
+			goto get_prs;
+		}
+
+		/* This code exercises the acpi_walk_resources interface */
+
+		status = acpi_walk_resources(node, METHOD_NAME__CRS,
+					     acpi_db_resource_callback, NULL);
+		if (ACPI_FAILURE(status)) {
+			acpi_os_printf("AcpiWalkResources failed: %s\n",
+				       acpi_format_exception(status));
+			goto get_prs;
+		}
+
+		/* Get the _CRS resource list (test ALLOCATE buffer) */
+
+		return_buffer.pointer = NULL;
+		return_buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
+
+		status = acpi_get_current_resources(node, &return_buffer);
+		if (ACPI_FAILURE(status)) {
+			acpi_os_printf("AcpiGetCurrentResources failed: %s\n",
+				       acpi_format_exception(status));
+			goto get_prs;
+		}
+
+		/* This code exercises the acpi_walk_resource_buffer interface */
+
+		status = acpi_walk_resource_buffer(&return_buffer,
+						   acpi_db_resource_callback,
+						   NULL);
+		if (ACPI_FAILURE(status)) {
+			acpi_os_printf("AcpiWalkResourceBuffer failed: %s\n",
+				       acpi_format_exception(status));
+			goto end_crs;
+		}
+
+		/* Dump the _CRS resource list */
+
+		acpi_rs_dump_resource_list(ACPI_CAST_PTR(struct acpi_resource,
+							 return_buffer.
+							 pointer));
+
+		/*
+		 * Perform comparison of original AML to newly created AML. This
+		 * tests both the AML->Resource conversion and the Resource->AML
+		 * conversion.
+		 */
+		(void)acpi_dm_test_resource_conversion(node, METHOD_NAME__CRS);
+
+		/* Execute _SRS with the resource list */
+
+		acpi_os_printf("Evaluating _SRS\n");
+
+		status = acpi_set_current_resources(node, &return_buffer);
+		if (ACPI_FAILURE(status)) {
+			acpi_os_printf("AcpiSetCurrentResources failed: %s\n",
+				       acpi_format_exception(status));
+			goto end_crs;
+		}
+
+end_crs:
+		ACPI_FREE(return_buffer.pointer);
+	}
+
+	/* _PRS */
+
+get_prs:
+	if (prs_node) {
+		acpi_os_printf("Evaluating _PRS\n");
+
+		return_buffer.pointer = acpi_gbl_db_buffer;
+		return_buffer.length = ACPI_DEBUG_BUFFER_SIZE;
+
+		status =
+		    acpi_evaluate_object(prs_node, NULL, NULL, &return_buffer);
+		if (ACPI_FAILURE(status)) {
+			acpi_os_printf("Could not evaluate _PRS: %s\n",
+				       acpi_format_exception(status));
+			goto get_aei;
+		}
+
+		return_buffer.pointer = acpi_gbl_db_buffer;
+		return_buffer.length = ACPI_DEBUG_BUFFER_SIZE;
+
+		status = acpi_get_possible_resources(node, &return_buffer);
+		if (ACPI_FAILURE(status)) {
+			acpi_os_printf("AcpiGetPossibleResources failed: %s\n",
+				       acpi_format_exception(status));
+			goto get_aei;
+		}
+
+		acpi_rs_dump_resource_list(ACPI_CAST_PTR
+					   (struct acpi_resource,
+					    acpi_gbl_db_buffer));
+	}
+
+	/* _AEI */
+
+get_aei:
+	if (aei_node) {
+		acpi_os_printf("Evaluating _AEI\n");
+
+		return_buffer.pointer = acpi_gbl_db_buffer;
+		return_buffer.length = ACPI_DEBUG_BUFFER_SIZE;
+
+		status =
+		    acpi_evaluate_object(aei_node, NULL, NULL, &return_buffer);
+		if (ACPI_FAILURE(status)) {
+			acpi_os_printf("Could not evaluate _AEI: %s\n",
+				       acpi_format_exception(status));
+			goto cleanup;
+		}
+
+		return_buffer.pointer = acpi_gbl_db_buffer;
+		return_buffer.length = ACPI_DEBUG_BUFFER_SIZE;
+
+		status = acpi_get_event_resources(node, &return_buffer);
+		if (ACPI_FAILURE(status)) {
+			acpi_os_printf("AcpiGetEventResources failed: %s\n",
+				       acpi_format_exception(status));
+			goto cleanup;
+		}
+
+		acpi_rs_dump_resource_list(ACPI_CAST_PTR
+					   (struct acpi_resource,
+					    acpi_gbl_db_buffer));
+	}
+
+cleanup:
+	ACPI_FREE(parent_path);
+	return (AE_OK);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_display_resources
+ *
+ * PARAMETERS:  object_arg          - String object name or object pointer.
+ *                                    NULL or "*" means "display resources for
+ *                                    all devices"
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Display the resource objects associated with a device.
+ *
+ ******************************************************************************/
+
+void acpi_db_display_resources(char *object_arg)
+{
+	struct acpi_namespace_node *node;
+
+	acpi_db_set_output_destination(ACPI_DB_REDIRECTABLE_OUTPUT);
+	acpi_dbg_level |= ACPI_LV_RESOURCES;
+
+	/* Asterisk means "display resources for all devices" */
+
+	if (!object_arg || (!strcmp(object_arg, "*"))) {
+		(void)acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
+					  ACPI_UINT32_MAX,
+					  acpi_db_device_resources, NULL, NULL,
+					  NULL);
+	} else {
+		/* Convert string to object pointer */
+
+		node = acpi_db_convert_to_node(object_arg);
+		if (node) {
+			if (node->type != ACPI_TYPE_DEVICE) {
+				acpi_os_printf
+				    ("%4.4s: Name is not a device object (%s)\n",
+				     node->name.ascii,
+				     acpi_ut_get_type_name(node->type));
+			} else {
+				(void)acpi_db_device_resources(node, 0, NULL,
+							       NULL);
+			}
+		}
+	}
+
+	acpi_db_set_output_destination(ACPI_DB_CONSOLE_OUTPUT);
+}
+
+#if (!ACPI_REDUCED_HARDWARE)
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_generate_gpe
+ *
+ * PARAMETERS:  gpe_arg             - Raw GPE number, ascii string
+ *              block_arg           - GPE block number, ascii string
+ *                                    0 or 1 for FADT GPE blocks
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Simulate firing of a GPE
+ *
+ ******************************************************************************/
+
+void acpi_db_generate_gpe(char *gpe_arg, char *block_arg)
+{
+	u32 block_number = 0;
+	u32 gpe_number;
+	struct acpi_gpe_event_info *gpe_event_info;
+
+	gpe_number = strtoul(gpe_arg, NULL, 0);
+
+	/*
+	 * If no block arg, or block arg == 0 or 1, use the FADT-defined
+	 * GPE blocks.
+	 */
+	if (block_arg) {
+		block_number = strtoul(block_arg, NULL, 0);
+		if (block_number == 1) {
+			block_number = 0;
+		}
+	}
+
+	gpe_event_info =
+	    acpi_ev_get_gpe_event_info(ACPI_TO_POINTER(block_number),
+				       gpe_number);
+	if (!gpe_event_info) {
+		acpi_os_printf("Invalid GPE\n");
+		return;
+	}
+
+	(void)acpi_ev_gpe_dispatch(NULL, gpe_event_info, gpe_number);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_generate_sci
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Simulate an SCI -- just call the SCI dispatch.
+ *
+ ******************************************************************************/
+
+void acpi_db_generate_sci(void)
+{
+	acpi_ev_sci_dispatch();
+}
+
+#endif				/* !ACPI_REDUCED_HARDWARE */
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_db_trace
+ *
+ * PARAMETERS:  enable_arg          - ENABLE/AML to enable tracer
+ *                                    DISABLE to disable tracer
+ *              method_arg          - Method to trace
+ *              once_arg            - Whether trace once
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Control method tracing facility
+ *
+ ******************************************************************************/
+
+void acpi_db_trace(char *enable_arg, char *method_arg, char *once_arg)
+{
+	u32 debug_level = 0;
+	u32 debug_layer = 0;
+	u32 flags = 0;
+
+	if (enable_arg) {
+		acpi_ut_strupr(enable_arg);
+	}
+
+	if (once_arg) {
+		acpi_ut_strupr(once_arg);
+	}
+
+	if (method_arg) {
+		if (acpi_db_trace_method_name) {
+			ACPI_FREE(acpi_db_trace_method_name);
+			acpi_db_trace_method_name = NULL;
+		}
+
+		acpi_db_trace_method_name =
+		    ACPI_ALLOCATE(strlen(method_arg) + 1);
+		if (!acpi_db_trace_method_name) {
+			acpi_os_printf("Failed to allocate method name (%s)\n",
+				       method_arg);
+			return;
+		}
+
+		strcpy(acpi_db_trace_method_name, method_arg);
+	}
+
+	if (!strcmp(enable_arg, "ENABLE") ||
+	    !strcmp(enable_arg, "METHOD") || !strcmp(enable_arg, "OPCODE")) {
+		if (!strcmp(enable_arg, "ENABLE")) {
+
+			/* Inherit current console settings */
+
+			debug_level = acpi_gbl_db_console_debug_level;
+			debug_layer = acpi_dbg_layer;
+		} else {
+			/* Restrict console output to trace points only */
+
+			debug_level = ACPI_LV_TRACE_POINT;
+			debug_layer = ACPI_EXECUTER;
+		}
+
+		flags = ACPI_TRACE_ENABLED;
+
+		if (!strcmp(enable_arg, "OPCODE")) {
+			flags |= ACPI_TRACE_OPCODE;
+		}
+
+		if (once_arg && !strcmp(once_arg, "ONCE")) {
+			flags |= ACPI_TRACE_ONESHOT;
+		}
+	}
+
+	(void)acpi_debug_trace(acpi_db_trace_method_name,
+			       debug_level, debug_layer, flags);
+}
drivers/acpi/acpica/dbconvert.c new file +484 -0

484 lines not on this page · raw message

drivers/acpi/acpica/dbdisply.c new file +1108 -0

1,108 lines not on this page · raw message

drivers/acpi/acpica/dbexec.c new file +753 -0

221 lines not on this page · raw message

drivers/acpi/acpica/dbfileio.c new file +256 -0

256 lines not on this page · raw message

drivers/acpi/acpica/dbhistry.c new file +239 -0

239 lines not on this page · raw message

drivers/acpi/acpica/dbinput.c new file +1274 -0

1,274 lines not on this page · raw message

drivers/acpi/acpica/dbmethod.c new file +369 -0

369 lines not on this page · raw message

drivers/acpi/acpica/dbnames.c new file +947 -0

947 lines not on this page · raw message

drivers/acpi/acpica/dbobject.c new file +533 -0

533 lines not on this page · raw message

drivers/acpi/acpica/dbstats.c new file +546 -0

546 lines not on this page · raw message

drivers/acpi/acpica/dbtest.c new file +1057 -0

1,057 lines not on this page · raw message

drivers/acpi/acpica/dbutils.c new file +457 -0

457 lines not on this page · raw message

drivers/acpi/acpica/dbxface.c new file +467 -0

467 lines not on this page · raw message

The rest of this diff is not shown. View the raw message.

Signature · 1 line
1.7.10

Part of the diff is not shown here. View the raw message.

author
#10 lore raw

PATCH v2 9/14 ACPICA: Debugger: Fix "quit/exit" command by cleaning up user commands termination logic

In reply to Lv Zheng

ACPICA commit 0dd68e16274cd38224aa4781eddc57dc2cbaa108

The quit/exit commands shouldn't invoke acpi_terminate_debugger() and acpi_terminate() right in the user command loop, because when the debugger exits, the kernel ACPI subsystem shouldn't be terminated (acpi_terminate()) and the debugger should only be terminated by its users (acpi_terminate_debugger()) rather than being terminated itself. Leaving such invocations causes kernel panic when the debugger is shipped in the Linux kernel.

This patch fixes this issue. Lv Zheng.

---
 drivers/acpi/acpica/acglobal.h |    3 ++-
 drivers/acpi/acpica/dbinput.c  |   16 ++++------------
 drivers/acpi/acpica/dbxface.c  |   20 ++++++++++++++++++++
 drivers/acpi/acpica/utinit.c   |    2 --
 drivers/acpi/acpica/utxface.c  |    4 ----
 5 files changed, 26 insertions(+), 19 deletions(-)
drivers/acpi/acpica/acglobal.h +2 -1
index 593de41..d82249c 100644
@@ -324,7 +324,6 @@ ACPI_GLOBAL(struct acpi_external_file *, acpi_gbl_external_file_list);
 
 #ifdef ACPI_DEBUGGER
 
-ACPI_INIT_GLOBAL(u8, acpi_gbl_db_terminate_threads, FALSE);
 ACPI_INIT_GLOBAL(u8, acpi_gbl_abort_method, FALSE);
 ACPI_INIT_GLOBAL(u8, acpi_gbl_method_executing, FALSE);
 
@@ -336,6 +335,8 @@ ACPI_GLOBAL(char *, acpi_gbl_db_filename);
 ACPI_GLOBAL(u32, acpi_gbl_db_debug_level);
 ACPI_GLOBAL(u32, acpi_gbl_db_console_debug_level);
 ACPI_GLOBAL(struct acpi_namespace_node *, acpi_gbl_db_scope_node);
+ACPI_GLOBAL(u8, acpi_gbl_db_terminate_loop);
+ACPI_GLOBAL(u8, acpi_gbl_db_threads_terminated);
 
 ACPI_GLOBAL(char *, acpi_gbl_db_args[ACPI_DEBUGGER_MAX_ARGS]);
 ACPI_GLOBAL(acpi_object_type, acpi_gbl_db_arg_types[ACPI_DEBUGGER_MAX_ARGS]);
drivers/acpi/acpica/dbinput.c +4 -12
index 7f1b6ec..f8cddd6 100644
@@ -694,7 +694,7 @@ acpi_db_command_dispatch(char *input_buffer,
 
 	/* If acpi_terminate has been called, terminate this thread */
 
-	if (acpi_gbl_db_terminate_threads) {
+	if (acpi_gbl_db_terminate_loop) {
 		return (AE_CTRL_TERMINATE);
 	}
 
@@ -1116,7 +1116,7 @@ acpi_db_command_dispatch(char *input_buffer,
 #ifdef ACPI_APPLICATION
 		acpi_db_close_debug_file();
 #endif
-		acpi_gbl_db_terminate_threads = TRUE;
+		acpi_gbl_db_terminate_loop = TRUE;
 		return (AE_CTRL_TERMINATE);
 
 	case CMD_NOT_FOUND:
@@ -1166,6 +1166,7 @@ void ACPI_SYSTEM_XFACE acpi_db_execute_thread(void *context)
 
 		acpi_os_release_mutex(acpi_gbl_db_command_complete);
 	}
+	acpi_gbl_db_threads_terminated = TRUE;
 }
 
 /*******************************************************************************
@@ -1212,7 +1213,7 @@ acpi_status acpi_db_user_commands(char prompt, union acpi_parse_object *op)
 
 	/* TBD: [Restructure] Need a separate command line buffer for step mode */
 
-	while (!acpi_gbl_db_terminate_threads) {
+	while (!acpi_gbl_db_terminate_loop) {
 
 		/* Force output to console until a command is entered */
 
@@ -1261,14 +1262,5 @@ acpi_status acpi_db_user_commands(char prompt, union acpi_parse_object *op)
 		}
 	}
 
-	/* Shut down the debugger */
-
-	acpi_terminate_debugger();
-
-	/*
-	 * Only this thread (the original thread) should actually terminate the
-	 * subsystem, because all the semaphores are deleted during termination
-	 */
-	status = acpi_terminate();
 	return (status);
 }
drivers/acpi/acpica/dbxface.c +20 -0
index 26023bd..bef5f4e 100644
@@ -401,6 +401,10 @@ acpi_status acpi_initialize_debugger(void)
 	acpi_gbl_db_scope_buf[1] = 0;
 	acpi_gbl_db_scope_node = acpi_gbl_root_node;
 
+	/* Initialize user commands loop */
+
+	acpi_gbl_db_terminate_loop = FALSE;
+
 	/*
 	 * If configured for multi-thread support, the debug executor runs in
 	 * a separate thread so that the front end can be in another address
@@ -426,11 +430,13 @@ acpi_status acpi_initialize_debugger(void)
 
 		/* Create the debug execution thread to execute commands */
 
+		acpi_gbl_db_threads_terminated = FALSE;
 		status = acpi_os_execute(OSL_DEBUGGER_THREAD,
 					 acpi_db_execute_thread, NULL);
 		if (ACPI_FAILURE(status)) {
 			ACPI_EXCEPTION((AE_INFO, status,
 					"Could not start debugger thread"));
+			acpi_gbl_db_threads_terminated = TRUE;
 			return_ACPI_STATUS(status);
 		}
 	}
@@ -454,6 +460,20 @@ ACPI_EXPORT_SYMBOL(acpi_initialize_debugger)
 void acpi_terminate_debugger(void)
 {
 
+	/* Terminate the AML Debugger */
+
+	acpi_gbl_db_terminate_loop = TRUE;
+
+	if (acpi_gbl_debugger_configuration & DEBUGGER_MULTI_THREADED) {
+		acpi_os_release_mutex(acpi_gbl_db_command_ready);
+
+		/* Wait the AML Debugger threads */
+
+		while (!acpi_gbl_db_threads_terminated) {
+			acpi_os_sleep(100);
+		}
+	}
+
 	if (acpi_gbl_db_buffer) {
 		acpi_os_free(acpi_gbl_db_buffer);
 		acpi_gbl_db_buffer = NULL;
drivers/acpi/acpica/utinit.c +0 -2
index 28ab3a1..d8699df 100644
@@ -241,8 +241,6 @@ acpi_status acpi_ut_init_globals(void)
 	acpi_gbl_disable_mem_tracking = FALSE;
 #endif
 
-	ACPI_DEBUGGER_EXEC(acpi_gbl_db_terminate_threads = FALSE);
-
 	return_ACPI_STATUS(AE_OK);
 }
 
drivers/acpi/acpica/utxface.c +0 -4
index 4f33281..f183daf 100644
@@ -80,10 +80,6 @@ acpi_status __init acpi_terminate(void)
 	acpi_gbl_startup_flags = 0;
 	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Shutting down ACPI Subsystem\n"));
 
-	/* Terminate the AML Debugger if present */
-
-	ACPI_DEBUGGER_EXEC(acpi_gbl_db_terminate_threads = TRUE);
-
 	/* Shutdown and free all resources */
 
 	acpi_ut_subsystem_shutdown();
Signature · 1 line
1.7.10
#11 lore raw

Re: [PATCH v2 09/14] ACPICA: Debugger: Fix "quit/exit" command by cleaning up user commands termination logic

Quoted 10 lines · Lv Zheng

ACPICA commit 0dd68e16274cd38224aa4781eddc57dc2cbaa108

The quit/exit commands shouldn't invoke acpi_terminate_debugger() and acpi_terminate() right in the user command loop, because when the debugger exits, the kernel ACPI subsystem shouldn't be terminated (acpi_terminate()) and the debugger should only be terminated by its users (acpi_terminate_debugger()) rather than being terminated itself. Leaving such invocations causes kernel panic when the debugger is shipped in the Linux kernel.

Quoted 5 lines

This patch fixes this issue. Lv Zheng.

This patch does not apply for me on top of the current mainline.

What tree is it applicable to?

Thanks,
Rafael

author
#12 lore raw

RE: [PATCH v2 09/14] ACPICA: Debugger: Fix "quit/exit" command by cleaning up user commands termination logic

I was using linux-pm.git/linux-next base which I downloaded a week ago.
Maybe the conflict was caused by the fast-path ACPICA table fix merged after my downloading. Let me check again.

Thanks and best regards
-Lv

Quoted 26 lines

From: Rafael J. Wysocki [mailto:[email protected]]
Sent: Tuesday, October 20, 2015 5:04 AM

Quoted 10 lines · Lv Zheng

ACPICA commit 0dd68e16274cd38224aa4781eddc57dc2cbaa108

The quit/exit commands shouldn't invoke acpi_terminate_debugger() and acpi_terminate() right in the user command loop, because when the debugger exits, the kernel ACPI subsystem shouldn't be terminated (acpi_terminate()) and the debugger should only be terminated by its users (acpi_terminate_debugger()) rather than being terminated itself. Leaving such invocations causes kernel panic when the debugger is shipped in the Linux kernel.

Quoted 5 lines

This patch fixes this issue. Lv Zheng.

This patch does not apply for me on top of the current mainline.

What tree is it applicable to?

Thanks,
Rafael

author
#13 lore raw

RE: [PATCH v2 09/14] ACPICA: Debugger: Fix "quit/exit" command by cleaning up user commands termination logic

It looks patch 08 is not listed on the https://patchwork.kernel.org/project/linux-acpi/list/.
I just re-sent it, hope it could reach the mailing list this time.
I'll also send it in attachment style via private route to you.

Thanks and best regards
-Lv

Quoted 40 lines

From: [email protected] [mailto:[email protected]] On Behalf Of Zheng, Lv
Sent: Tuesday, October 20, 2015 10:04 AM

I was using linux-pm.git/linux-next base which I downloaded a week ago.
Maybe the conflict was caused by the fast-path ACPICA table fix merged after my downloading. Let me check again.

Thanks and best regards
-Lv

Quoted 20 lines

From: Rafael J. Wysocki [mailto:[email protected]]
Sent: Tuesday, October 20, 2015 5:04 AM

Quoted 10 lines · Lv Zheng

ACPICA commit 0dd68e16274cd38224aa4781eddc57dc2cbaa108

The quit/exit commands shouldn't invoke acpi_terminate_debugger() and acpi_terminate() right in the user command loop, because when the debugger exits, the kernel ACPI subsystem shouldn't be terminated (acpi_terminate()) and the debugger should only be terminated by its users (acpi_terminate_debugger()) rather than being terminated itself. Leaving such invocations causes kernel panic when the debugger is shipped in the Linux kernel.

Quoted 5 lines

This patch fixes this issue. Lv Zheng.

Quoted 6 lines

This patch does not apply for me on top of the current mainline.

What tree is it applicable to?

Thanks,
Rafael

N�����r��y���b�X��ǧv�^�)޺{.n�+����{�i�b�{ay�ʇڙ�,j ��f���h���z��w���

���j:+v���w�j�m���� ����zZ+�����ݢj"��!�i

author
#14 lore raw

PATCH v2 10/14 ACPICA: Debugger: Fix "terminate" command by cleaning up subsystem shutdown logic

In reply to Lv Zheng

ACPICA commit 7e823714911480be47e310fb1b3590d289b9fd99

Segmentation fault can be seen for executing the "terminate" command. This is because acpi_ut_subsystem_shutdown() is errnously called multiple times.

This patch cleans up acpi_ut_subsystem_shutdown() logics to fix this issue. Lv Zheng.

---
 drivers/acpi/acpica/dbinput.c |    3 ++-
 drivers/acpi/acpica/utinit.c  |   13 +++++++++++++
 drivers/acpi/acpica/utxface.c |   13 -------------
 3 files changed, 15 insertions(+), 14 deletions(-)
drivers/acpi/acpica/dbinput.c +2 -1
index f8cddd6..0480254 100644
@@ -1074,6 +1074,7 @@ acpi_db_command_dispatch(char *input_buffer,
 		 * re-creating the semaphores!
 		 */
 
+		acpi_gbl_db_terminate_loop = TRUE;
 		/*  acpi_initialize (NULL); */
 		break;
 
@@ -1151,7 +1152,7 @@ void ACPI_SYSTEM_XFACE acpi_db_execute_thread(void *context)
 	acpi_status status = AE_OK;
 	acpi_status Mstatus;
 
-	while (status != AE_CTRL_TERMINATE) {
+	while (status != AE_CTRL_TERMINATE && !acpi_gbl_db_terminate_loop) {
 		acpi_gbl_method_executing = FALSE;
 		acpi_gbl_step_to_next_call = FALSE;
 
drivers/acpi/acpica/utinit.c +13 -0
index d8699df..ccd0745 100644
@@ -282,6 +282,19 @@ void acpi_ut_subsystem_shutdown(void)
 {
 	ACPI_FUNCTION_TRACE(ut_subsystem_shutdown);
 
+	/* Just exit if subsystem is already shutdown */
+
+	if (acpi_gbl_shutdown) {
+		ACPI_ERROR((AE_INFO, "ACPI Subsystem is already terminated"));
+		return_VOID;
+	}
+
+	/* Subsystem appears active, go ahead and shut it down */
+
+	acpi_gbl_shutdown = TRUE;
+	acpi_gbl_startup_flags = 0;
+	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Shutting down ACPI Subsystem\n"));
+
 #ifndef ACPI_ASL_COMPILER
 
 	/* Close the acpi_event Handling */
drivers/acpi/acpica/utxface.c +0 -13
index f183daf..a6b0eb0 100644
@@ -67,19 +67,6 @@ acpi_status __init acpi_terminate(void)
 
 	ACPI_FUNCTION_TRACE(acpi_terminate);
 
-	/* Just exit if subsystem is already shutdown */
-
-	if (acpi_gbl_shutdown) {
-		ACPI_ERROR((AE_INFO, "ACPI Subsystem is already terminated"));
-		return_ACPI_STATUS(AE_OK);
-	}
-
-	/* Subsystem appears active, go ahead and shut it down */
-
-	acpi_gbl_shutdown = TRUE;
-	acpi_gbl_startup_flags = 0;
-	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Shutting down ACPI Subsystem\n"));
-
 	/* Shutdown and free all resources */
 
 	acpi_ut_subsystem_shutdown();
Signature · 1 line
1.7.10
author
#15 lore raw

PATCH v2 11/14 ACPICA: Debugger: Add thread ID support so that single step mode can only apply to the debugger thread

In reply to Lv Zheng

When the debugger is running in the kernel mode, acpi_db_single_step() may also be invoked by the kernel runtime code path but the single stepping command prompt may be erronously logged as the kernel logs and runtime code path cannot proceed.

This patch fixes this issue by adding acpi_gbl_db_thread_id for the debugger thread and preventing acpi_db_single_step() to be invoked from other threads.

It is not suitable to add acpi_thread_id parameter for acpi_os_execute() as the function may be implemented as work queue on some hosts. So it is better to let the hosts invoke acpi_set_debugger_thread_id(). Currently acpiexec is not configured as DEBUGGER_MULTI_THREADED, but we can do this. When we do this, it is better to invoke acpi_set_debugger_thread_id() in acpi_os_execute() when the execution type is OSL_DEBUGGER_MAIN_THREAD. The support should look like:
create_thread(&tid);
if (type == OSL_DEBUGGER_MAIN_THREAD)

      acpi_set_debugger_thread_id(tid);

resume_thread(tid);
Similarly, semop() may be used for pthread implementation. But this patch simply skips debugger thread ID check for application instead of introducing such complications as there is no need to skip acpi_db_single_step() for an application debugger - acpiexec.

Note that the debugger thread ID can also be used by acpi_os_printf() to filter out debugger output. Lv Zheng.

---
 drivers/acpi/acpica/acglobal.h |    1 +
 drivers/acpi/acpica/aclocal.h  |    8 ++++++++
 drivers/acpi/acpica/dbexec.c   |    3 ++-
 drivers/acpi/acpica/dbxface.c  |   28 +++++++++++++++++++++++++++-
 include/acpi/acpiosxf.h        |    3 ++-
 include/acpi/acpixf.h          |    2 ++
 6 files changed, 42 insertions(+), 3 deletions(-)
drivers/acpi/acpica/acglobal.h +1 -0
index d82249c..fdef15f 100644
@@ -326,6 +326,7 @@ ACPI_GLOBAL(struct acpi_external_file *, acpi_gbl_external_file_list);
 
 ACPI_INIT_GLOBAL(u8, acpi_gbl_abort_method, FALSE);
 ACPI_INIT_GLOBAL(u8, acpi_gbl_method_executing, FALSE);
+ACPI_INIT_GLOBAL(acpi_thread_id, acpi_gbl_db_thread_id, ACPI_INVALID_THREAD_ID);
 
 ACPI_GLOBAL(u8, acpi_gbl_db_opt_no_ini_methods);
 ACPI_GLOBAL(u8, acpi_gbl_db_opt_no_region_support);
drivers/acpi/acpica/aclocal.h +8 -0
index 4e41b43..e1dd784 100644
@@ -109,6 +109,14 @@ struct acpi_rw_lock {
 
 #define ACPI_MUTEX_NOT_ACQUIRED         (acpi_thread_id) 0
 
+/* This Thread ID means an invalid thread ID */
+
+#ifdef ACPI_OS_INVALID_THREAD_ID
+#define ACPI_INVALID_THREAD_ID          ACPI_OS_INVALID_THREAD_ID
+#else
+#define ACPI_INVALID_THREAD_ID          ((acpi_thread_id) 0xFFFFFFFF)
+#endif
+
 /* Table for the global mutexes */
 
 struct acpi_mutex_info {
drivers/acpi/acpica/dbexec.c +2 -1
index 8eef298..258e615 100644
@@ -725,7 +725,8 @@ acpi_db_create_execution_threads(char *num_threads_arg,
 
 	for (i = 0; i < (num_threads); i++) {
 		status =
-		    acpi_os_execute(OSL_DEBUGGER_THREAD, acpi_db_method_thread,
+		    acpi_os_execute(OSL_DEBUGGER_EXEC_THREAD,
+				    acpi_db_method_thread,
 				    &acpi_gbl_db_method_info);
 		if (ACPI_FAILURE(status)) {
 			break;
drivers/acpi/acpica/dbxface.c +27 -1
index bef5f4e..342298a 100644
@@ -164,6 +164,12 @@ acpi_db_single_step(struct acpi_walk_state * walk_state,
 
 	ACPI_FUNCTION_ENTRY();
 
+#ifndef ACPI_APPLICATION
+	if (acpi_gbl_db_thread_id != acpi_os_get_thread_id()) {
+		return (AE_OK);
+	}
+#endif
+
 	/* Check the abort flag */
 
 	if (acpi_gbl_abort_method) {
@@ -431,7 +437,7 @@ acpi_status acpi_initialize_debugger(void)
 		/* Create the debug execution thread to execute commands */
 
 		acpi_gbl_db_threads_terminated = FALSE;
-		status = acpi_os_execute(OSL_DEBUGGER_THREAD,
+		status = acpi_os_execute(OSL_DEBUGGER_MAIN_THREAD,
 					 acpi_db_execute_thread, NULL);
 		if (ACPI_FAILURE(status)) {
 			ACPI_EXCEPTION((AE_INFO, status,
@@ -439,6 +445,8 @@ acpi_status acpi_initialize_debugger(void)
 			acpi_gbl_db_threads_terminated = TRUE;
 			return_ACPI_STATUS(status);
 		}
+	} else {
+		acpi_gbl_db_thread_id = acpi_os_get_thread_id();
 	}
 
 	return_ACPI_STATUS(AE_OK);
@@ -485,3 +493,21 @@ void acpi_terminate_debugger(void)
 }
 
 ACPI_EXPORT_SYMBOL(acpi_terminate_debugger)
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_set_debugger_thread_id
+ *
+ * PARAMETERS:  thread_id       - Debugger thread ID
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Set debugger thread ID
+ *
+ ******************************************************************************/
+void acpi_set_debugger_thread_id(acpi_thread_id thread_id)
+{
+	acpi_gbl_db_thread_id = thread_id;
+}
+
+ACPI_EXPORT_SYMBOL(acpi_set_debugger_thread_id)
include/acpi/acpiosxf.h +2 -1
index a54ad1c..fbc2baf 100644
@@ -55,7 +55,8 @@ typedef enum {
 	OSL_GLOBAL_LOCK_HANDLER,
 	OSL_NOTIFY_HANDLER,
 	OSL_GPE_HANDLER,
-	OSL_DEBUGGER_THREAD,
+	OSL_DEBUGGER_MAIN_THREAD,
+	OSL_DEBUGGER_EXEC_THREAD,
 	OSL_EC_POLL_HANDLER,
 	OSL_EC_BURST_HANDLER
 } acpi_execute_type;
include/acpi/acpixf.h +2 -0
index c33eeab..f837adf 100644
@@ -939,4 +939,6 @@ ACPI_EXTERNAL_RETURN_STATUS(acpi_status
 					       void **data,
 					       void (*callback)(void *)))
 
+void acpi_set_debugger_thread_id(acpi_thread_id thread_id);
+
 #endif				/* __ACXFACE_H__ */
Signature · 1 line
1.7.10
author
#16 lore raw

PATCH v2 12/14 ACPI: Enable build of AML interpreter debugger

In reply to Lv Zheng

This patch enables ACPICA debugger files using a configurable CONFIG_ACPI_DEBUGGER configuration item. Those debugger related code that was originally masked as ACPI_FUTURE_USAGE now gets unmasked.

Necessary OSL stubs are also added in this patch:
1. acpi_os_readable(): This should be arch specific in Linux, while this patch doesn't introduce real implementation and a complex mechanism to allow architecture specific acpi_os_readable() to be implemented to validate the address. It may be done by future commits.
2. acpi_os_get_line(): This is used to obtain debugger command input. This patch only introduces a simple KDB concept example in it and the example should be co-working with the code implemented in acpi_os_printf(). Since this KDB example won't be compiled unless ENABLE_DEBUGGER is defined and it seems Linux has already stopped to use ENABLE_DEBUGGER, thus do not expect it can work properly.

This patch also cleans up all other ACPI_FUTURE_USAGE surroundings accordingly.
1. Since linkage error can be automatically detected, declaration in the headers needn't be surrounded by ACPI_FUTURE_USAGE.
So only the following separate exported fuction bodies are masked by this macro (other exported fucntions may have already been masked at entire module level via drivers/acpi/acpica/Makefile):
acpi_install_exception_handler()
acpi_subsystem_status()
acpi_get_system_info()
acpi_get_statistics() acpi_install_initialization_handler()
2. Since strip can automatically zap the no-user functions, functions that are not marked with ACPI_EXPORT_SYMBOL() needn't get surrounded by ACPI_FUTURE_USAGE.
So the following function which is not used by Linux kernel now won't get surrounded by this macro:

     acpi_ps_get_name()
---
 drivers/acpi/Kconfig              |    9 +++++++++
 drivers/acpi/acpica/Makefile      |   18 +++++++++++++++++-
 drivers/acpi/acpica/acinterp.h    |    2 --
 drivers/acpi/acpica/acnamesp.h    |    4 ----
 drivers/acpi/acpica/acparser.h    |    4 ----
 drivers/acpi/acpica/acutils.h     |    2 --
 drivers/acpi/acpica/evxface.c     |    2 +-
 drivers/acpi/acpica/nsdump.c      |    6 ------
 drivers/acpi/acpica/pstree.c      |    2 --
 drivers/acpi/acpica/psutils.c     |    2 --
 drivers/acpi/acpica/rsutils.c     |    2 --
 drivers/acpi/acpica/rsxface.c     |    4 ++--
 drivers/acpi/acpica/utxface.c     |    2 +-
 drivers/acpi/osl.c                |   11 +++--------
 include/acpi/acpixf.h             |   10 ----------
 include/acpi/platform/aclinux.h   |    7 +++++--
 include/acpi/platform/aclinuxex.h |    5 +++++
 17 files changed, 43 insertions(+), 49 deletions(-)
drivers/acpi/Kconfig +9 -0
index 5d1015c..706c2e9 100644
@@ -57,6 +57,15 @@ config ACPI_SYSTEM_POWER_STATES_SUPPORT
 config ACPI_CCA_REQUIRED
 	bool
 
+config ACPI_DEBUGGER
+	bool "In-kernel debugger (EXPERIMENTAL)"
+	select ACPI_DEBUG
+	help
+	  Enable in-kernel debugging facilities: statistics, internal
+	  object dump, single step control method execution.
+	  This is still under development, currently enabling this only
+	  results in the compilation of the ACPICA debugger files.
+
 config ACPI_SLEEP
 	bool
 	depends on SUSPEND || HIBERNATION
drivers/acpi/acpica/Makefile +17 -1
index ac78d76..885936f 100644
@@ -177,8 +177,24 @@ acpi-y +=		\
 	utxferror.o	\
 	utxfmutex.o
 
-acpi-$(ACPI_FUTURE_USAGE) +=	\
+acpi-$(CONFIG_ACPI_DEBUGGER) +=	\
+	dbcmds.o		\
+	dbconvert.o		\
+	dbdisply.o		\
+	dbexec.o		\
+	dbhistry.o		\
+	dbinput.o		\
+	dbmethod.o		\
+	dbnames.o		\
+	dbobject.o		\
+	dbstats.o		\
+	dbutils.o		\
+	dbxface.o		\
 	rsdump.o		\
+
+acpi-$(ACPI_FUTURE_USAGE) +=	\
+	dbfileio.o		\
+	dbtest.o		\
 	utcache.o		\
 	utfileio.o		\
 	utprint.o		\
drivers/acpi/acpica/acinterp.h +0 -2
index e820ed8..e9e936e 100644
@@ -397,12 +397,10 @@ void
 acpi_ex_dump_operands(union acpi_operand_object **operands,
 		      const char *opcode_name, u32 num_opcodes);
 
-#ifdef	ACPI_FUTURE_USAGE
 void
 acpi_ex_dump_object_descriptor(union acpi_operand_object *object, u32 flags);
 
 void acpi_ex_dump_namespace_node(struct acpi_namespace_node *node, u32 flags);
-#endif				/* ACPI_FUTURE_USAGE */
 
 /*
  * exnames - AML namestring support
drivers/acpi/acpica/acnamesp.h +0 -4
index ea0d907..5d261c9 100644
@@ -193,9 +193,7 @@ acpi_ns_convert_to_resource(union acpi_operand_object *original_object,
 /*
  * nsdump - Namespace dump/print utilities
  */
-#ifdef	ACPI_FUTURE_USAGE
 void acpi_ns_dump_tables(acpi_handle search_base, u32 max_depth);
-#endif				/* ACPI_FUTURE_USAGE */
 
 void acpi_ns_dump_entry(acpi_handle handle, u32 debug_level);
 
@@ -208,7 +206,6 @@ acpi_status
 acpi_ns_dump_one_object(acpi_handle obj_handle,
 			u32 level, void *context, void **return_value);
 
-#ifdef	ACPI_FUTURE_USAGE
 void
 acpi_ns_dump_objects(acpi_object_type type,
 		     u8 display_type,
@@ -220,7 +217,6 @@ acpi_ns_dump_object_paths(acpi_object_type type,
 			  u8 display_type,
 			  u32 max_depth,
 			  acpi_owner_id owner_id, acpi_handle start_handle);
-#endif				/* ACPI_FUTURE_USAGE */
 
 /*
  * nseval - Namespace evaluation functions
drivers/acpi/acpica/acparser.h +0 -4
index 6021ccf..8fc8c7c 100644
@@ -194,10 +194,8 @@ union acpi_parse_object *acpi_ps_find(union acpi_parse_object *scope,
 
 union acpi_parse_object *acpi_ps_get_arg(union acpi_parse_object *op, u32 argn);
 
-#ifdef	ACPI_FUTURE_USAGE
 union acpi_parse_object *acpi_ps_get_depth_next(union acpi_parse_object *origin,
 						union acpi_parse_object *op);
-#endif				/* ACPI_FUTURE_USAGE */
 
 /*
  * pswalk - parse tree walk routines
@@ -235,9 +233,7 @@ void acpi_ps_free_op(union acpi_parse_object *op);
 
 u8 acpi_ps_is_leading_char(u32 c);
 
-#ifdef	ACPI_FUTURE_USAGE
 u32 acpi_ps_get_name(union acpi_parse_object *op);
-#endif				/* ACPI_FUTURE_USAGE */
 
 void acpi_ps_set_name(union acpi_parse_object *op, u32 name);
 
drivers/acpi/acpica/acutils.h +0 -2
index fb2aa50..8b8fef6 100644
@@ -635,9 +635,7 @@ void
 acpi_ut_free_and_track(void *address,
 		       u32 component, const char *module, u32 line);
 
-#ifdef	ACPI_FUTURE_USAGE
 void acpi_ut_dump_allocation_info(void);
-#endif				/* ACPI_FUTURE_USAGE */
 
 void acpi_ut_dump_allocations(u32 component, const char *module);
 
drivers/acpi/acpica/evxface.c +1 -1
index 81f2d9e..07d22bf 100644
@@ -405,7 +405,7 @@ cleanup:
 }
 
 ACPI_EXPORT_SYMBOL(acpi_install_exception_handler)
-#endif				/*  ACPI_FUTURE_USAGE  */
+#endif
 
 #if (!ACPI_REDUCED_HARDWARE)
 /*******************************************************************************
drivers/acpi/acpica/nsdump.c +0 -6
index 0f1daba..37aa5c4 100644
@@ -60,7 +60,6 @@ acpi_ns_dump_one_device(acpi_handle obj_handle,
 
 #if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER)
 
-#ifdef	ACPI_FUTURE_USAGE
 static acpi_status
 acpi_ns_dump_one_object_path(acpi_handle obj_handle,
 			     u32 level, void *context, void **return_value);
@@ -68,7 +67,6 @@ acpi_ns_dump_one_object_path(acpi_handle obj_handle,
 static acpi_status
 acpi_ns_get_max_depth(acpi_handle obj_handle,
 		      u32 level, void *context, void **return_value);
-#endif				/* ACPI_FUTURE_USAGE */
 
 /*******************************************************************************
  *
@@ -625,7 +623,6 @@ cleanup:
 	return (AE_OK);
 }
 
-#ifdef ACPI_FUTURE_USAGE
 /*******************************************************************************
  *
  * FUNCTION:    acpi_ns_dump_objects
@@ -680,9 +677,7 @@ acpi_ns_dump_objects(acpi_object_type type,
 
 	(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
 }
-#endif				/* ACPI_FUTURE_USAGE */
 
-#ifdef	ACPI_FUTURE_USAGE
 /*******************************************************************************
  *
  * FUNCTION:    acpi_ns_dump_one_object_path, acpi_ns_get_max_depth
@@ -810,7 +805,6 @@ acpi_ns_dump_object_paths(acpi_object_type type,
 
 	(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
 }
-#endif				/* ACPI_FUTURE_USAGE */
 
 /*******************************************************************************
  *
drivers/acpi/acpica/pstree.c +0 -2
index 89984f3..cf2f2fa 100644
@@ -183,7 +183,6 @@ acpi_ps_append_arg(union acpi_parse_object *op, union acpi_parse_object *arg)
 	}
 }
 
-#ifdef ACPI_FUTURE_USAGE
 /*******************************************************************************
  *
  * FUNCTION:    acpi_ps_get_depth_next
@@ -317,4 +316,3 @@ union acpi_parse_object *acpi_ps_get_child(union acpi_parse_object *op)
 	return (child);
 }
 #endif
-#endif				/*  ACPI_FUTURE_USAGE  */
drivers/acpi/acpica/psutils.c +0 -2
index 183cc1e..71d2877 100644
@@ -205,7 +205,6 @@ u8 acpi_ps_is_leading_char(u32 c)
 /*
  * Get op's name (4-byte name segment) or 0 if unnamed
  */
-#ifdef ACPI_FUTURE_USAGE
 u32 acpi_ps_get_name(union acpi_parse_object * op)
 {
 
@@ -219,7 +218,6 @@ u32 acpi_ps_get_name(union acpi_parse_object * op)
 
 	return (op->named.name);
 }
-#endif				/*  ACPI_FUTURE_USAGE  */
 
 /*
  * Set op's name
drivers/acpi/acpica/rsutils.c +0 -2
index 52b024d..9486992 100644
@@ -564,7 +564,6 @@ acpi_rs_get_crs_method_data(struct acpi_namespace_node *node,
  *
  ******************************************************************************/
 
-#ifdef ACPI_FUTURE_USAGE
 acpi_status
 acpi_rs_get_prs_method_data(struct acpi_namespace_node *node,
 			    struct acpi_buffer *ret_buffer)
@@ -596,7 +595,6 @@ acpi_rs_get_prs_method_data(struct acpi_namespace_node *node,
 	acpi_ut_remove_reference(obj_desc);
 	return_ACPI_STATUS(status);
 }
-#endif				/*  ACPI_FUTURE_USAGE  */
 
 /*******************************************************************************
  *
drivers/acpi/acpica/rsxface.c +2 -2
index de51f83..1e8cd57 100644
@@ -220,7 +220,7 @@ acpi_get_current_resources(acpi_handle device_handle,
 }
 
 ACPI_EXPORT_SYMBOL(acpi_get_current_resources)
-#ifdef ACPI_FUTURE_USAGE
+
 /*******************************************************************************
  *
  * FUNCTION:    acpi_get_possible_resources
@@ -262,7 +262,7 @@ acpi_get_possible_resources(acpi_handle device_handle,
 }
 
 ACPI_EXPORT_SYMBOL(acpi_get_possible_resources)
-#endif				/*  ACPI_FUTURE_USAGE  */
+
 /*******************************************************************************
  *
  * FUNCTION:    acpi_set_current_resources
drivers/acpi/acpica/utxface.c +1 -1
index a6b0eb0..f9c8f9c 100644
@@ -253,7 +253,7 @@ acpi_install_initialization_handler(acpi_init_handler handler, u32 function)
 }
 
 ACPI_EXPORT_SYMBOL(acpi_install_initialization_handler)
-#endif				/*  ACPI_FUTURE_USAGE  */
+#endif
 
 /*****************************************************************************
  *
drivers/acpi/osl.c +3 -8
index 739a4a6..3272915 100644
@@ -66,8 +66,6 @@ struct acpi_os_dpc {
 /* stuff for debugger support */
 int acpi_in_debugger;
 EXPORT_SYMBOL(acpi_in_debugger);
-
-extern char line_buf[80];
 #endif				/*ENABLE_DEBUGGER */
 
 static int (*__acpi_os_prepare_sleep)(u8 sleep_state, u32 pm1a_ctrl,
@@ -1345,15 +1343,13 @@ acpi_status acpi_os_signal_semaphore(acpi_handle handle, u32 units)
 	return AE_OK;
 }
 
-#ifdef ACPI_FUTURE_USAGE
-u32 acpi_os_get_line(char *buffer)
+acpi_status acpi_os_get_line(char *buffer, u32 buffer_length, u32 *bytes_read)
 {
-
 #ifdef ENABLE_DEBUGGER
 	if (acpi_in_debugger) {
 		u32 chars;
 
-		kdb_read(buffer, sizeof(line_buf));
+		kdb_read(buffer, buffer_length);
 
 		/* remove the CR kdb includes */
 		chars = strlen(buffer) - 1;
@@ -1361,9 +1357,8 @@ u32 acpi_os_get_line(char *buffer)
 	}
 #endif
 
-	return 0;
+	return AE_OK;
 }
-#endif				/*  ACPI_FUTURE_USAGE  */
 
 acpi_status acpi_os_signal(u32 function, void *info)
 {
include/acpi/acpixf.h +0 -10
index f837adf..ded9fa3 100644
@@ -393,15 +393,11 @@ ACPI_EXTERNAL_RETURN_STATUS(acpi_status __init acpi_terminate(void))
  */
 ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status acpi_enable(void))
 ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status acpi_disable(void))
-#ifdef ACPI_FUTURE_USAGE
 ACPI_EXTERNAL_RETURN_STATUS(acpi_status acpi_subsystem_status(void))
-#endif
 
-#ifdef ACPI_FUTURE_USAGE
 ACPI_EXTERNAL_RETURN_STATUS(acpi_status
 			    acpi_get_system_info(struct acpi_buffer
 						 *ret_buffer))
-#endif
 ACPI_EXTERNAL_RETURN_STATUS(acpi_status
 			     acpi_get_statistics(struct acpi_statistics *stats))
 ACPI_EXTERNAL_RETURN_PTR(const char
@@ -625,11 +621,9 @@ ACPI_EXTERNAL_RETURN_STATUS(acpi_status
 							       space_id,
 							       acpi_adr_space_handler
 							       handler))
-#ifdef ACPI_FUTURE_USAGE
 ACPI_EXTERNAL_RETURN_STATUS(acpi_status
 			     acpi_install_exception_handler
 			     (acpi_exception_handler handler))
-#endif
 ACPI_EXTERNAL_RETURN_STATUS(acpi_status
 			     acpi_install_interface_handler
 			     (acpi_interface_handler handler))
@@ -750,12 +744,10 @@ ACPI_EXTERNAL_RETURN_STATUS(acpi_status
 			     acpi_get_current_resources(acpi_handle device,
 							struct acpi_buffer
 							*ret_buffer))
-#ifdef ACPI_FUTURE_USAGE
 ACPI_EXTERNAL_RETURN_STATUS(acpi_status
 			     acpi_get_possible_resources(acpi_handle device,
 							 struct acpi_buffer
 							 *ret_buffer))
-#endif
 ACPI_EXTERNAL_RETURN_STATUS(acpi_status
 			     acpi_get_event_resources(acpi_handle device_handle,
 						      struct acpi_buffer
@@ -844,7 +836,6 @@ ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status
 /*
  * ACPI Timer interfaces
  */
-#ifdef ACPI_FUTURE_USAGE
 ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status
 				acpi_get_timer_resolution(u32 *resolution))
 ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status acpi_get_timer(u32 *ticks))
@@ -853,7 +844,6 @@ ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status
 				acpi_get_timer_duration(u32 start_ticks,
 							u32 end_ticks,
 							u32 *time_elapsed))
-#endif				/* ACPI_FUTURE_USAGE */
 
 /*
  * Error/Warning output
include/acpi/platform/aclinux.h +5 -2
index 74ba46c..323e5da 100644
@@ -63,12 +63,16 @@
 
 #define ACPI_USE_SYSTEM_INTTYPES
 
-/* Compile for reduced hardware mode only with this kernel config */
+/* Kernel specific ACPICA configuration */
 
 #ifdef CONFIG_ACPI_REDUCED_HARDWARE_ONLY
 #define ACPI_REDUCED_HARDWARE 1
 #endif
 
+#ifdef CONFIG_ACPI_DEBUGGER
+#define ACPI_DEBUGGER
+#endif
+
 #include <linux/string.h>
 #include <linux/kernel.h>
 #include <linux/ctype.h>
@@ -151,7 +155,6 @@
  * OSL interfaces used by utilities
  */
 #define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_redirect_output
-#define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_get_line
 #define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_get_table_by_name
 #define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_get_table_by_index
 #define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_get_table_by_address
include/acpi/platform/aclinuxex.h +5 -0
index acedc3f..fd6d70f 100644
@@ -124,6 +124,11 @@ static inline acpi_thread_id acpi_os_get_thread_id(void)
 		lock ? AE_OK : AE_NO_MEMORY; \
 	})
 
+static inline u8 acpi_os_readable(void *pointer, acpi_size length)
+{
+	return TRUE;
+}
+
 /*
  * OSL interfaces added by Linux
  */
Signature · 1 line
1.7.10
author
#17 lore raw

PATCH v2 13/14 ACPICA: Debugger: Fix dead lock issue ocurred in single stepping mode

In reply to Lv Zheng

ACPICA commit 35273add90da19cd8790fdb5735f52e3c9861684

When single step execution is not ended, executing another control methods leads to dead locks around interpreter lock/namespace lock/method serialization lock. So we should only allow one execution from the debugger at same time. Lv Zheng.

---
 drivers/acpi/acpica/dbexec.c |   10 ++++++++++
 1 file changed, 10 insertions(+)
drivers/acpi/acpica/dbexec.c +10 -0
index 258e615..d713e2d 100644
@@ -370,7 +370,17 @@ acpi_db_execute(char *name, char **args, acpi_object_type * types, u32 flags)
 #ifdef ACPI_DEBUG_OUTPUT
 	u32 previous_allocations;
 	u32 allocations;
+#endif
 
+	/*
+	 * Allow one execution to be performed by debugger or single step
+	 * execution will be dead locked by the interpreter mutexes.
+	 */
+	if (acpi_gbl_method_executing) {
+		acpi_os_printf("Only one debugger execution is allowed.\n");
+		return;
+	}
+#ifdef ACPI_DEBUG_OUTPUT
 	/* Memory allocation tracking */
 
 	previous_allocations = acpi_db_get_outstanding_allocations();
Signature · 1 line
1.7.10
author
#18 lore raw

PATCH v2 14/14 ACPICA: Update version to 20150930

In reply to Lv Zheng

From: Bob Moore <[email protected]>

ACPICA commit e9c75ca267262326e80d49a290e8387a5963e2d2

Version 20150930.

---
 include/acpi/acpixf.h |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
include/acpi/acpixf.h +1 -1
index ded9fa3..3aaaa86 100644
@@ -46,7 +46,7 @@
 
 /* Current ACPICA subsystem version in YYYYMMDD format */
 
-#define ACPI_CA_VERSION                 0x20150818
+#define ACPI_CA_VERSION                 0x20150930
 
 #include <acpi/acconfig.h>
 #include <acpi/actypes.h>
Signature · 1 line
1.7.10
author
#19 lore raw

v2 cover ACPICA / debugger: Add in-kernel AML debugger support

In reply to a message not in the archive

This patchset enables ACPICA debugger for Linux kernel and implements a userspace utility to access it.

A. Build the AML debugger
In order to build the kernel support of AML debugger, the following kconfig items should be enabled:
CONFIG_ACPI_DEBUG=y
CONFIG_ACPI_DEBUGGER=y
CONFIG_DEBUG_FS=y
CONFIG_ACPI_DEBUGGER_USER=m
The userspace tool can be found at tools/power/acpi/tools/acpidbg. To build this utility, staying in tools folder and type "make acpi".

B. Load the AML debugger during runtime
In order to use the in-kernel AML debugger, the following command should be executed using root user:

 # modprobe acpi_dbg
 # mount -t debugfs none /sys/kernel/debug
 # acpidbg

C. Batch mode
In order to support scripts, the userspace utility also supports single command batch mode:

 # acpidbg -b "help"
 # acpidbg -b "tables"
 # acpidbg -b "find _LID"
 # acpidbg -b "execute \_SB.LID0._LID"
You can find the documentation about the ACPICA debugger commands in:
 https://acpica.org/sites/acpica/files/acpica-reference_17.pdf
 (The latest document can be found at https://acpica.org/documentation)
And refer to the chapter - ACPICA debugger reference to obtain the full
description of the debugger commands. Note that not all commands are
supported by an in-kernel AML debugger.

D. Unload the AML debugger during runtime
After terminating all acpidbg instances, the following command can be executed to remove the AML debugger from kernel:

 # rmmod acpi_dbg

The following tasks are not completed:
1. .flush() support in the kernel debugger IO driver.
2. multi-commands batch mode.
3. upstream the userspace acpidbg to the ACPICA upstream.

Colin Ian King (1):
ACPICA: Debugger: Remove unnecessary status check

Lv Zheng (4):
ACPICA: Debugger: Convert some mechanisms to OSPM specific ACPI / debugger: Add IO interface to access debugger functionalities tools/power/acpi: Add userspace AML interface support ACPI / debugger: Add module support for ACPI debugger

 drivers/acpi/Kconfig                     |   13 +-
 drivers/acpi/Makefile                    |    1 +
 drivers/acpi/acpi_dbg.c                  |  818 ++++++++++++++++++++++++++++++
 drivers/acpi/acpica/acdebug.h            |    2 +-
 drivers/acpi/acpica/acglobal.h           |    5 -
 drivers/acpi/acpica/dbinput.c            |  100 +---
 drivers/acpi/acpica/dbxface.c            |   63 +--
 drivers/acpi/acpica/utmutex.c            |   17 -
 drivers/acpi/bus.c                       |    1 +
 drivers/acpi/osl.c                       |  250 ++++++++-
 include/acpi/acpiosxf.h                  |   18 +-
 include/acpi/acpixf.h                    |   11 +
 include/acpi/platform/aclinux.h          |    2 +
 include/acpi/platform/aclinuxex.h        |    9 +
 include/linux/acpi.h                     |   71 +++
 tools/power/acpi/Makefile                |   16 +-
 tools/power/acpi/tools/acpidbg/Makefile  |   27 +
 tools/power/acpi/tools/acpidbg/acpidbg.c |  438 ++++++++++++++++
 18 files changed, 1699 insertions(+), 163 deletions(-)
 create mode 100644 drivers/acpi/acpi_dbg.c
 create mode 100644 tools/power/acpi/tools/acpidbg/Makefile
 create mode 100644 tools/power/acpi/tools/acpidbg/acpidbg.c
Signature · 1 line
1.7.10
author
#20 lore raw

RFC PATCH v2 1/5 ACPICA: Debugger: Remove unnecessary status check

From: Colin Ian King <[email protected]>

ACPICA commit f9d5c6c9a25e9f5ac05458bfcd8b381e21bb2ba5

ACPICA BZ 1205. Colin Ian King.

---
 drivers/acpi/acpica/dbinput.c |    3 ---
 1 file changed, 3 deletions(-)
drivers/acpi/acpica/dbinput.c +0 -3
index 0480254..fe93f67 100644
@@ -1246,9 +1246,6 @@ acpi_status acpi_db_user_commands(char prompt, union acpi_parse_object *op)
 			 * and wait for the command to complete.
 			 */
 			acpi_os_release_mutex(acpi_gbl_db_command_ready);
-			if (ACPI_FAILURE(status)) {
-				return (status);
-			}
 
 			status =
 			    acpi_os_acquire_mutex(acpi_gbl_db_command_complete,
Signature · 1 line
1.7.10
author
#21 lore raw

RFC PATCH v2 2/5 ACPICA: Debugger: Convert some mechanisms to OSPM specific

In reply to Lv Zheng

The following mechanisms are OSPM specific:
1. Redirect output destination to console: no file redirection will be needed by an in-kernel debugger, there is even no file can be accessed when the debugger is running in the kernel mode.
2. Output command prompts: programs other than acpiexec can have different prompt characters and the prompt characters may be implemented as a special character sequence to form a char device IO protocol.
3. Command ready/complete handshake: OSPM debugger may wait more conditions to implement OSPM specific semantics (for example, FIFO full/empty conditions for O_NONBLOCK or IO open/close conditions).
Leaving such OSPM specific stuffs in the ACPICA debugger core blocks Linux debugger IO driver implementation.

Several new OSL APIs are provided by this patch:
1. acpi_os_initialize_command_signals: initialize command handshake mechanism or any other OSPM specific stuffs.
2. acpi_os_terminate_command_signals: reversal of acpi_os_initialize_command_signals.
3. acpi_os_wait_command_ready: putting debugger task into wait state when a command is not ready. OSPMs can terminate command loop by returning AE_CTRL_TERMINATE from this API. Normally, wait_event() or wait_for_multiple_object() may be used to implement this API.
4. acpi_os_notify_command_complete: putting user task into running state when a command has been completed. OSPMs can terminate command loop by returning AE_CTRL_TERMINATE from this API. Normally, wake_up() or set_event() may be used to implement this API.
This patch also converts current command signaling implementation into a generic debugger layer (osgendbg.c) to be used by the existing OSPMs or acpiexec, in return, Linux can have chance to implement its own command handshake mechanism. This patch also implements acpiexec batch mode in a multi-threading mode comaptible style as a demo (this can be confirmed by configuring acpiexec into DEBUGGER_MULTI_THREADED mode where the batch mode is still working). Lv Zheng.

Note that the OSPM specific command handshake mechanism is required by Linux kernel because:
1. Linux kernel trends to use wait queue to synchronize two threads, using mutexes to achieve that will cause false "dead lock" warnings.
2. The command handshake mechanism implemented by ACPICA is implemented in this way because of a design issue in debugger IO streaming. Debugger IO outputs are simply cached using a giant buffer, this should be tuned by Linux in the future.

---
 drivers/acpi/acpica/acdebug.h     |    2 +-
 drivers/acpi/acpica/acglobal.h    |    5 --
 drivers/acpi/acpica/dbinput.c     |   97 ++++++++-----------------------------
 drivers/acpi/acpica/dbxface.c     |   63 +++++++-----------------
 drivers/acpi/acpica/utmutex.c     |   17 -------
 include/acpi/acpiosxf.h           |   18 ++++++-
 include/acpi/acpixf.h             |   11 +++++
 include/acpi/platform/aclinux.h   |    4 ++
 include/acpi/platform/aclinuxex.h |   19 ++++++++
 9 files changed, 89 insertions(+), 147 deletions(-)
drivers/acpi/acpica/acdebug.h +1 -1
index c928ba4..86474d8 100644
@@ -257,7 +257,7 @@ acpi_db_command_dispatch(char *input_buffer,
 
 void ACPI_SYSTEM_XFACE acpi_db_execute_thread(void *context);
 
-acpi_status acpi_db_user_commands(char prompt, union acpi_parse_object *op);
+acpi_status acpi_db_user_commands(void);
 
 char *acpi_db_get_next_token(char *string,
 			     char **next, acpi_object_type * return_type);
drivers/acpi/acpica/acglobal.h +0 -5
index faa9760..3977134 100644
@@ -326,7 +326,6 @@ ACPI_GLOBAL(struct acpi_external_file *, acpi_gbl_external_file_list);
 #ifdef ACPI_DEBUGGER
 
 ACPI_INIT_GLOBAL(u8, acpi_gbl_abort_method, FALSE);
-ACPI_INIT_GLOBAL(u8, acpi_gbl_method_executing, FALSE);
 ACPI_INIT_GLOBAL(acpi_thread_id, acpi_gbl_db_thread_id, ACPI_INVALID_THREAD_ID);
 
 ACPI_GLOBAL(u8, acpi_gbl_db_opt_no_ini_methods);
@@ -345,7 +344,6 @@ ACPI_GLOBAL(acpi_object_type, acpi_gbl_db_arg_types[ACPI_DEBUGGER_MAX_ARGS]);
 
 /* These buffers should all be the same size */
 
-ACPI_GLOBAL(char, acpi_gbl_db_line_buf[ACPI_DB_LINE_BUFFER_SIZE]);
 ACPI_GLOBAL(char, acpi_gbl_db_parsed_buf[ACPI_DB_LINE_BUFFER_SIZE]);
 ACPI_GLOBAL(char, acpi_gbl_db_scope_buf[ACPI_DB_LINE_BUFFER_SIZE]);
 ACPI_GLOBAL(char, acpi_gbl_db_debug_filename[ACPI_DB_LINE_BUFFER_SIZE]);
@@ -360,9 +358,6 @@ ACPI_GLOBAL(u16, acpi_gbl_node_type_count_misc);
 ACPI_GLOBAL(u32, acpi_gbl_num_nodes);
 ACPI_GLOBAL(u32, acpi_gbl_num_objects);
 
-ACPI_GLOBAL(acpi_mutex, acpi_gbl_db_command_ready);
-ACPI_GLOBAL(acpi_mutex, acpi_gbl_db_command_complete);
-
 #endif				/* ACPI_DEBUGGER */
 
 /*****************************************************************************
drivers/acpi/acpica/dbinput.c +19 -78

138 lines not on this page · raw message

drivers/acpi/acpica/dbxface.c +18 -45

98 lines not on this page · raw message

drivers/acpi/acpica/utmutex.c +0 -17
index ce406e3..ea0c207 100644
@@ -111,17 +111,6 @@ acpi_status acpi_ut_mutex_initialize(void)
 	if (ACPI_FAILURE(status)) {
 		return_ACPI_STATUS(status);
 	}
-#ifdef ACPI_DEBUGGER
-
-	/* Debugger Support */
-
-	status = acpi_os_create_mutex(&acpi_gbl_db_command_ready);
-	if (ACPI_FAILURE(status)) {
-		return_ACPI_STATUS(status);
-	}
-
-	status = acpi_os_create_mutex(&acpi_gbl_db_command_complete);
-#endif
 
 	return_ACPI_STATUS(status);
 }
@@ -162,12 +151,6 @@ void acpi_ut_mutex_terminate(void)
 	/* Delete the reader/writer lock */
 
 	acpi_ut_delete_rw_lock(&acpi_gbl_namespace_rw_lock);
-
-#ifdef ACPI_DEBUGGER
-	acpi_os_delete_mutex(acpi_gbl_db_command_ready);
-	acpi_os_delete_mutex(acpi_gbl_db_command_complete);
-#endif
-
 	return_VOID;
 }
 
include/acpi/acpiosxf.h +17 -1
index fbc2baf..0d824a2 100644
@@ -349,12 +349,28 @@ void acpi_os_redirect_output(void *destination);
 #endif
 
 /*
- * Debug input
+ * Debug IO
  */
 #ifndef ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_get_line
 acpi_status acpi_os_get_line(char *buffer, u32 buffer_length, u32 *bytes_read);
 #endif
 
+#ifndef ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_initialize_command_signals
+acpi_status acpi_os_initialize_command_signals(void);
+#endif
+
+#ifndef ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_terminate_command_signals
+void acpi_os_terminate_command_signals(void);
+#endif
+
+#ifndef ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_wait_command_ready
+acpi_status acpi_os_wait_command_ready(void);
+#endif
+
+#ifndef ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_notify_command_complete
+acpi_status acpi_os_notify_command_complete(void);
+#endif
+
 /*
  * Obtain ACPI table(s)
  */
include/acpi/acpixf.h +11 -0
index 3aaaa86..95ebae3 100644
@@ -264,6 +264,15 @@ ACPI_INIT_GLOBAL(u32, acpi_dbg_level, ACPI_DEBUG_DEFAULT);
 ACPI_INIT_GLOBAL(u32, acpi_dbg_layer, 0);
 
 /*
+ * Debugger command handshake globals. Host OSes need to access these
+ * variables to implement their own command handshake mechanism.
+ */
+#ifdef ACPI_DEBUGGER
+ACPI_INIT_GLOBAL(u8, acpi_gbl_method_executing, FALSE);
+ACPI_GLOBAL(char, acpi_gbl_db_line_buf[ACPI_DB_LINE_BUFFER_SIZE]);
+#endif
+
+/*
  * Other miscellaneous globals
  */
 ACPI_GLOBAL(struct acpi_table_fadt, acpi_gbl_FADT);
@@ -929,6 +938,8 @@ ACPI_EXTERNAL_RETURN_STATUS(acpi_status
 					       void **data,
 					       void (*callback)(void *)))
 
+void acpi_run_debugger(char *batch_buffer);
+
 void acpi_set_debugger_thread_id(acpi_thread_id thread_id);
 
 #endif				/* __ACXFACE_H__ */
include/acpi/platform/aclinux.h +4 -0
index 323e5da..69dbae6 100644
@@ -150,6 +150,10 @@
  */
 #define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_readable
 #define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_writable
+#define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_initialize_command_signals
+#define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_terminate_command_signals
+#define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_wait_command_ready
+#define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_notify_command_complete
 
 /*
  * OSL interfaces used by utilities
include/acpi/platform/aclinuxex.h +19 -0
index fd6d70f..673fdf4 100644
@@ -129,6 +129,25 @@ static inline u8 acpi_os_readable(void *pointer, acpi_size length)
 	return TRUE;
 }
 
+static inline acpi_status acpi_os_initialize_command_signals(void)
+{
+	return AE_OK;
+}
+
+static inline void acpi_os_terminate_command_signals(void)
+{
+}
+
+static inline acpi_status acpi_os_wait_command_ready(void)
+{
+	return AE_ERROR;
+}
+
+static inline acpi_status acpi_os_notify_command_complete(void)
+{
+	return AE_ERROR;
+}
+
 /*
  * OSL interfaces added by Linux
  */
Signature · 1 line
1.7.10
author
#22 lore raw

RFC PATCH v2 3/5 ACPI / debugger: Add IO interface to access debugger functionalities

In reply to Lv Zheng

This patch adds /sys/kernel/debug/acpi/acpidbg, which can be used by userspace programs to access ACPICA debugger functionalities.

Known issue:
1. IO flush support
acpi_os_notify_command_complete() and acpi_os_wait_command_ready() can be used by acpi_dbg module to implement .flush() filesystem operation. While this patch doesn't go that far. It then becomes userspace tool's duty now to flush old commands before executing new batch mode commands.

---
 drivers/acpi/Kconfig              |    2 +-
 drivers/acpi/Makefile             |    1 +
 drivers/acpi/acpi_dbg.c           |  792 +++++++++++++++++++++++++++++++++++++
 drivers/acpi/bus.c                |    2 +
 drivers/acpi/osl.c                |   55 ++-
 include/acpi/platform/aclinux.h   |    2 -
 include/acpi/platform/aclinuxex.h |   10 -
 include/linux/acpi_dbg.h          |   52 +++
 8 files changed, 899 insertions(+), 17 deletions(-)
 create mode 100644 drivers/acpi/acpi_dbg.c
 create mode 100644 include/linux/acpi_dbg.h
drivers/acpi/Kconfig +1 -1
index 25dbb76..2b89fd7 100644
@@ -58,7 +58,7 @@ config ACPI_CCA_REQUIRED
 	bool
 
 config ACPI_DEBUGGER
-	bool "In-kernel debugger (EXPERIMENTAL)"
+	bool "In-kernel debugger"
 	select ACPI_DEBUG
 	help
 	  Enable in-kernel debugging facilities: statistics, internal
drivers/acpi/Makefile +1 -0
index 675eaf3..102b5e6 100644
@@ -50,6 +50,7 @@ acpi-y				+= sysfs.o
 acpi-y				+= property.o
 acpi-$(CONFIG_X86)		+= acpi_cmos_rtc.o
 acpi-$(CONFIG_DEBUG_FS)		+= debugfs.o
+acpi-$(CONFIG_ACPI_DEBUGGER)	+= acpi_dbg.o
 acpi-$(CONFIG_ACPI_NUMA)	+= numa.o
 acpi-$(CONFIG_ACPI_PROCFS_POWER) += cm_sbs.o
 acpi-y				+= acpi_lpat.o
drivers/acpi/acpi_dbg.c new file +792 -0

792 lines not on this page · raw message

drivers/acpi/bus.c +2 -0
index a212cef..06fbba9 100644
@@ -37,6 +37,7 @@
 #include <acpi/apei.h>
 #include <linux/dmi.h>
 #include <linux/suspend.h>
+#include <linux/acpi_dbg.h>
 
 #include "internal.h"
 
@@ -1094,6 +1095,7 @@ static int __init acpi_init(void)
 	acpi_debugfs_init();
 	acpi_sleep_proc_init();
 	acpi_wakeup_device_init();
+	acpi_aml_init();
 	return 0;
 }
 
drivers/acpi/osl.c +51 -4

105 lines not on this page · raw message

include/acpi/platform/aclinux.h +0 -2
index 69dbae6..e21857d 100644
@@ -152,8 +152,6 @@
 #define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_writable
 #define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_initialize_command_signals
 #define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_terminate_command_signals
-#define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_wait_command_ready
-#define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_notify_command_complete
 
 /*
  * OSL interfaces used by utilities
include/acpi/platform/aclinuxex.h +0 -10
index 673fdf4..ceea026 100644
@@ -138,16 +138,6 @@ static inline void acpi_os_terminate_command_signals(void)
 {
 }
 
-static inline acpi_status acpi_os_wait_command_ready(void)
-{
-	return AE_ERROR;
-}
-
-static inline acpi_status acpi_os_notify_command_complete(void)
-{
-	return AE_ERROR;
-}
-
 /*
  * OSL interfaces added by Linux
  */
include/linux/acpi_dbg.h new file +52 -0

52 lines not on this page · raw message

Signature · 1 line
1.7.10
author
#23 lore raw

RFC PATCH v2 4/5 tools/power/acpi: Add userspace AML interface support

In reply to Lv Zheng

This patch adds a userspace tool to access Linux kernel AML debugger interface.

Tow modes are supported by this tool:
1. Interactive: Users are able to launch a debugging shell to talk with in-kernel AML debugger.
Note that it's user duty to ensure kernel runtime integrity by using this debugging tool:
A. Some control methods evaluated by the users may result in kernel
panics if those control methods shouldn't be evaluated by the OSPMs according to the current BIOS/OS configurations.
B. Currently if a single stepping evaluation couldn't run to an end,
then the synchronization primitives acquired by the evaluation may block normal OSPM control method evaluations.
2. Batch: Users are able to execute debugger commands in a script. Note that in addition to the above duties, it's user duty to ensure script runtime integrity by using this debugging tool in this mode:
C. Currently only those commands that are not used for single stepping
are suitable to be used in this mode.
D. If the execution of the command may cause a failure that could result
in an endless kernel execution, the execution of the script may also get blocked.
To exit the utility, currently "exit/quit" commands are recommended, but ctrl-C" can also be used.

---
 tools/power/acpi/Makefile                |   16 +-
 tools/power/acpi/tools/acpidbg/Makefile  |   27 ++
 tools/power/acpi/tools/acpidbg/acpidbg.c |  438 ++++++++++++++++++++++++++++++
 3 files changed, 473 insertions(+), 8 deletions(-)
 create mode 100644 tools/power/acpi/tools/acpidbg/Makefile
 create mode 100644 tools/power/acpi/tools/acpidbg/acpidbg.c
tools/power/acpi/Makefile +8 -8
index e882c83..a8bf908 100644
@@ -10,18 +10,18 @@
 
 include ../../scripts/Makefile.include
 
-all: acpidump ec
-clean: acpidump_clean ec_clean
-install: acpidump_install ec_install
-uninstall: acpidump_uninstall ec_uninstall
+all: acpidbg acpidump ec
+clean: acpidbg_clean acpidump_clean ec_clean
+install: acpidbg_install acpidump_install ec_install
+uninstall: acpidbg_uninstall acpidump_uninstall ec_uninstall
 
-acpidump ec: FORCE
+acpidbg acpidump ec: FORCE
 	$(call descend,tools/$@,all)
-acpidump_clean ec_clean:
+acpidbg_clean acpidump_clean ec_clean:
 	$(call descend,tools/$(@:_clean=),clean)
-acpidump_install ec_install:
+acpidbg_install acpidump_install ec_install:
 	$(call descend,tools/$(@:_install=),install)
-acpidump_uninstall ec_uninstall:
+acpidbg_uninstall acpidump_uninstall ec_uninstall:
 	$(call descend,tools/$(@:_uninstall=),uninstall)
 
 .PHONY: FORCE
tools/power/acpi/tools/acpidbg/Makefile new file +27 -0
new file mode 100644
index 0000000..352df4b
@@ -0,0 +1,27 @@
+# tools/power/acpi/tools/acpidbg/Makefile - ACPI tool Makefile
+#
+# Copyright (c) 2015, Intel Corporation
+#   Author: Lv Zheng <[email protected]>
+#
+# 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; version 2
+# of the License.
+
+include ../../Makefile.config
+
+TOOL = acpidbg
+vpath %.c \
+	../../../../../drivers/acpi/acpica\
+	../../common\
+	../../os_specific/service_layers\
+	.
+CFLAGS += -DACPI_APPLICATION -DACPI_SINGLE_THREAD -DACPI_DEBUGGER\
+	-I.\
+	-I../../../../../drivers/acpi/acpica\
+	-I../../../../../include
+LDFLAGS += -lpthread
+TOOL_OBJS = \
+	acpidbg.o
+
+include ../../Makefile.rules
tools/power/acpi/tools/acpidbg/acpidbg.c new file +438 -0

438 lines not on this page · raw message

Signature · 1 line
1.7.10
author
#24 lore raw

RFC PATCH v2 5/5 ACPI / debugger: Add module support for ACPI debugger

In reply to Lv Zheng

This patch converts AML debugger into a loadable module.

Note that, it implements driver unloading at the level dependent on the module reference count. Which means if ACPI debugger is being used by a userspace program, "rmmod acpi_dbg" should result in failure.

---
 drivers/acpi/Kconfig     |   11 +++
 drivers/acpi/Makefile    |    2 +-
 drivers/acpi/acpi_dbg.c  |   80 ++++++++++++------
 drivers/acpi/bus.c       |    3 +-
 drivers/acpi/osl.c       |  207 ++++++++++++++++++++++++++++++++++++++++++++--
 include/linux/acpi.h     |   71 ++++++++++++++++
 include/linux/acpi_dbg.h |   52 ------------
 7 files changed, 338 insertions(+), 88 deletions(-)
 delete mode 100644 include/linux/acpi_dbg.h
drivers/acpi/Kconfig +11 -0
index 2b89fd7..c4d4a05 100644
@@ -66,6 +66,17 @@ config ACPI_DEBUGGER
 	  This is still under development, currently enabling this only
 	  results in the compilation of the ACPICA debugger files.
 
+if ACPI_DEBUGGER
+
+config ACPI_DEBUGGER_USER
+	tristate "Userspace debugger accessiblity"
+	depends on DEBUG_FS
+	help
+	  Export /sys/kernel/debug/acpi/acpidbg for userspace utilities
+	  to access the debugger functionalities.
+
+endif
+
 config ACPI_SLEEP
 	bool
 	depends on SUSPEND || HIBERNATION
drivers/acpi/Makefile +1 -1
index 102b5e6..c6f236f 100644
@@ -50,7 +50,6 @@ acpi-y				+= sysfs.o
 acpi-y				+= property.o
 acpi-$(CONFIG_X86)		+= acpi_cmos_rtc.o
 acpi-$(CONFIG_DEBUG_FS)		+= debugfs.o
-acpi-$(CONFIG_ACPI_DEBUGGER)	+= acpi_dbg.o
 acpi-$(CONFIG_ACPI_NUMA)	+= numa.o
 acpi-$(CONFIG_ACPI_PROCFS_POWER) += cm_sbs.o
 acpi-y				+= acpi_lpat.o
@@ -80,6 +79,7 @@ obj-$(CONFIG_ACPI_EC_DEBUGFS)	+= ec_sys.o
 obj-$(CONFIG_ACPI_CUSTOM_METHOD)+= custom_method.o
 obj-$(CONFIG_ACPI_BGRT)		+= bgrt.o
 obj-$(CONFIG_ACPI_CPPC_LIB)	+= cppc_acpi.o
+obj-$(CONFIG_ACPI_DEBUGGER_USER) += acpi_dbg.o
 
 # processor has its own "processor." module_param namespace
 processor-y			:= processor_driver.o
drivers/acpi/acpi_dbg.c +53 -27

156 lines not on this page · raw message

drivers/acpi/bus.c +1 -2
index 06fbba9..1a40111 100644
@@ -37,7 +37,6 @@
 #include <acpi/apei.h>
 #include <linux/dmi.h>
 #include <linux/suspend.h>
-#include <linux/acpi_dbg.h>
 
 #include "internal.h"
 
@@ -1095,7 +1094,7 @@ static int __init acpi_init(void)
 	acpi_debugfs_init();
 	acpi_sleep_proc_init();
 	acpi_wakeup_device_init();
-	acpi_aml_init();
+	acpi_debugger_init();
 	return 0;
 }
 
drivers/acpi/osl.c +201 -6

260 lines not on this page · raw message

include/linux/acpi.h +71 -0

83 lines not on this page · raw message

include/linux/acpi_dbg.h deleted +0 -52

52 lines not on this page · raw message

Signature · 1 line
1.7.10
author
#25 lore raw

v2 cover ACPICA / debugger: Add in-kernel AML debugger support

In reply to Lv Zheng

This patchset enables ACPICA debugger for Linux kernel and implements a userspace utility to access it.

A. Build the AML debugger
In order to build the kernel support of AML debugger, the following kconfig items should be enabled:
CONFIG_ACPI_DEBUG=y
CONFIG_ACPI_DEBUGGER=y
CONFIG_DEBUG_FS=y
CONFIG_ACPI_DEBUGGER_USER=m
The userspace tool can be found at tools/power/acpi/tools/acpidbg. To build this utility, staying in tools folder and type "make acpi".

B. Load the AML debugger during runtime
In order to use the in-kernel AML debugger, the following command should be executed using root user:

 # modprobe acpi_dbg
 # mount -t debugfs none /sys/kernel/debug
 # acpidbg

C. Batch mode
In order to support scripts, the userspace utility also supports single command batch mode:

 # acpidbg -b "help"
 # acpidbg -b "tables"
 # acpidbg -b "find _LID"
 # acpidbg -b "execute \_SB.LID0._LID"
You can find the documentation about the ACPICA debugger commands in:
 https://acpica.org/sites/acpica/files/acpica-reference_17.pdf
 (The latest document can be found at https://acpica.org/documentation)
And refer to the chapter - ACPICA debugger reference to obtain the full
description of the debugger commands. Note that not all commands are
supported by an in-kernel AML debugger.

D. Unload the AML debugger during runtime
After terminating all acpidbg instances, the following command can be executed to remove the AML debugger from kernel:

 # rmmod acpi_dbg

The following tasks are not completed:
1. .flush() support in the kernel debugger IO driver.
2. multi-commands batch mode.

v2:
1. Fix a help message issue for the userspace acpidbg utility (this is a typo fix).
2. Fix a batch mode issue by adding "\n" to the prompt sequence (this was lost due to too many rebase cycles).
3. Fix kconfig dependency for an intermediate patch (this is only useful in case the latter patches are reverted).
4. Add more accurate runtime debugger stub mechanism and remove old ACPI_DEBUGGER_EXEC() stub mechanism.
5. Add x86 acpi_os_readable() support.

Chen Yu (1):
ACPI / x86: introduce acpi_os_readable() support

Colin Ian King (1):
ACPICA: Debugger: Remove unnecessary status check

Lv Zheng (5):
ACPICA: Debugger: Convert some mechanisms to OSPM specific
ACPICA: Debugger: Fix runtime stub issues of ACPI_DEBUGGER_EXEC using
different stub mechanism
ACPI / debugger: Add IO interface to access debugger functionalities tools/power/acpi: Add userspace AML interface support
ACPI / debugger: Add module support for ACPI debugger

 arch/x86/Kconfig                         |    1 +
 arch/x86/include/asm/acenv.h             |    1 +
 arch/x86/kernel/acpi/boot.c              |   14 +
 drivers/acpi/Kconfig                     |   16 +-
 drivers/acpi/Makefile                    |    1 +
 drivers/acpi/acpi_dbg.c                  |  818 ++++++++++++++++++++++++++++++
 drivers/acpi/acpica/acdebug.h            |   36 +-
 drivers/acpi/acpica/acglobal.h           |    5 -
 drivers/acpi/acpica/acmacros.h           |   11 -
 drivers/acpi/acpica/dbdisply.c           |   12 +
 drivers/acpi/acpica/dbinput.c            |  100 +---
 drivers/acpi/acpica/dbxface.c            |   93 ++--
 drivers/acpi/acpica/dscontrol.c          |   10 +-
 drivers/acpi/acpica/dsutils.c            |   16 +-
 drivers/acpi/acpica/dswexec.c            |   16 +-
 drivers/acpi/acpica/utmutex.c            |   17 -
 drivers/acpi/bus.c                       |    1 +
 drivers/acpi/osl.c                       |  262 +++++++++-
 include/acpi/acpiosxf.h                  |   18 +-
 include/acpi/acpixf.h                    |   34 ++
 include/acpi/platform/aclinux.h          |    3 +-
 include/acpi/platform/aclinuxex.h        |    8 +-
 include/linux/acpi.h                     |   71 +++
 tools/power/acpi/Makefile                |   16 +-
 tools/power/acpi/tools/acpidbg/Makefile  |   27 +
 tools/power/acpi/tools/acpidbg/acpidbg.c |  438 ++++++++++++++++
 26 files changed, 1833 insertions(+), 212 deletions(-)
 create mode 100644 drivers/acpi/acpi_dbg.c
 create mode 100644 tools/power/acpi/tools/acpidbg/Makefile
 create mode 100644 tools/power/acpi/tools/acpidbg/acpidbg.c
Signature · 1 line
1.7.10
author
#26 lore raw

PATCH v2 1/7 ACPICA: Debugger: Remove unnecessary status check

From: Colin Ian King <[email protected]>

ACPICA commit f9d5c6c9a25e9f5ac05458bfcd8b381e21bb2ba5

ACPICA BZ 1205. Colin Ian King.

---
 drivers/acpi/acpica/dbinput.c |    3 ---
 1 file changed, 3 deletions(-)
drivers/acpi/acpica/dbinput.c +0 -3
index 0480254..fe93f67 100644
@@ -1246,9 +1246,6 @@ acpi_status acpi_db_user_commands(char prompt, union acpi_parse_object *op)
 			 * and wait for the command to complete.
 			 */
 			acpi_os_release_mutex(acpi_gbl_db_command_ready);
-			if (ACPI_FAILURE(status)) {
-				return (status);
-			}
 
 			status =
 			    acpi_os_acquire_mutex(acpi_gbl_db_command_complete,
Signature · 1 line
1.7.10
author
#27 lore raw

PATCH v2 2/7 ACPICA: Debugger: Convert some mechanisms to OSPM specific

In reply to Lv Zheng

The following mechanisms are OSPM specific:
1. Redirect output destination to console: no file redirection will be needed by an in-kernel debugger, there is even no file can be accessed when the debugger is running in the kernel mode.
2. Output command prompts: programs other than acpiexec can have different prompt characters and the prompt characters may be implemented as a special character sequence to form a char device IO protocol.
3. Command ready/complete handshake: OSPM debugger may wait more conditions to implement OSPM specific semantics (for example, FIFO full/empty conditions for O_NONBLOCK or IO open/close conditions).
Leaving such OSPM specific stuffs in the ACPICA debugger core blocks Linux debugger IO driver implementation.

Several new OSL APIs are provided by this patch:
1. acpi_os_initialize_command_signals: initialize command handshake mechanism or any other OSPM specific stuffs.
2. acpi_os_terminate_command_signals: reversal of acpi_os_initialize_command_signals.
3. acpi_os_wait_command_ready: putting debugger task into wait state when a command is not ready. OSPMs can terminate command loop by returning AE_CTRL_TERMINATE from this API. Normally, wait_event() or wait_for_multiple_object() may be used to implement this API.
4. acpi_os_notify_command_complete: putting user task into running state when a command has been completed. OSPMs can terminate command loop by returning AE_CTRL_TERMINATE from this API. Normally, wake_up() or set_event() may be used to implement this API.
This patch also converts current command signaling implementation into a generic debugger layer (osgendbg.c) to be used by the existing OSPMs or acpiexec, in return, Linux can have chance to implement its own command handshake mechanism. This patch also implements acpiexec batch mode in a multi-threading mode comaptible style as a demo (this can be confirmed by configuring acpiexec into DEBUGGER_MULTI_THREADED mode where the batch mode is still working). Lv Zheng.

Note that the OSPM specific command handshake mechanism is required by Linux kernel because:
1. Linux kernel trends to use wait queue to synchronize two threads, using mutexes to achieve that will cause false "dead lock" warnings.
2. The command handshake mechanism implemented by ACPICA is implemented in this way because of a design issue in debugger IO streaming. Debugger IO outputs are simply cached using a giant buffer, this should be tuned by Linux in the future.

---
 drivers/acpi/acpica/acdebug.h     |    2 +-
 drivers/acpi/acpica/acglobal.h    |    5 --
 drivers/acpi/acpica/dbinput.c     |   97 ++++++++-----------------------------
 drivers/acpi/acpica/dbxface.c     |   63 +++++++-----------------
 drivers/acpi/acpica/utmutex.c     |   17 -------
 include/acpi/acpiosxf.h           |   18 ++++++-
 include/acpi/acpixf.h             |   11 +++++
 include/acpi/platform/aclinux.h   |    4 ++
 include/acpi/platform/aclinuxex.h |   19 ++++++++
 9 files changed, 89 insertions(+), 147 deletions(-)
drivers/acpi/acpica/acdebug.h +1 -1
index c928ba4..86474d8 100644
@@ -257,7 +257,7 @@ acpi_db_command_dispatch(char *input_buffer,
 
 void ACPI_SYSTEM_XFACE acpi_db_execute_thread(void *context);
 
-acpi_status acpi_db_user_commands(char prompt, union acpi_parse_object *op);
+acpi_status acpi_db_user_commands(void);
 
 char *acpi_db_get_next_token(char *string,
 			     char **next, acpi_object_type * return_type);
drivers/acpi/acpica/acglobal.h +0 -5
index faa9760..3977134 100644
@@ -326,7 +326,6 @@ ACPI_GLOBAL(struct acpi_external_file *, acpi_gbl_external_file_list);
 #ifdef ACPI_DEBUGGER
 
 ACPI_INIT_GLOBAL(u8, acpi_gbl_abort_method, FALSE);
-ACPI_INIT_GLOBAL(u8, acpi_gbl_method_executing, FALSE);
 ACPI_INIT_GLOBAL(acpi_thread_id, acpi_gbl_db_thread_id, ACPI_INVALID_THREAD_ID);
 
 ACPI_GLOBAL(u8, acpi_gbl_db_opt_no_ini_methods);
@@ -345,7 +344,6 @@ ACPI_GLOBAL(acpi_object_type, acpi_gbl_db_arg_types[ACPI_DEBUGGER_MAX_ARGS]);
 
 /* These buffers should all be the same size */
 
-ACPI_GLOBAL(char, acpi_gbl_db_line_buf[ACPI_DB_LINE_BUFFER_SIZE]);
 ACPI_GLOBAL(char, acpi_gbl_db_parsed_buf[ACPI_DB_LINE_BUFFER_SIZE]);
 ACPI_GLOBAL(char, acpi_gbl_db_scope_buf[ACPI_DB_LINE_BUFFER_SIZE]);
 ACPI_GLOBAL(char, acpi_gbl_db_debug_filename[ACPI_DB_LINE_BUFFER_SIZE]);
@@ -360,9 +358,6 @@ ACPI_GLOBAL(u16, acpi_gbl_node_type_count_misc);
 ACPI_GLOBAL(u32, acpi_gbl_num_nodes);
 ACPI_GLOBAL(u32, acpi_gbl_num_objects);
 
-ACPI_GLOBAL(acpi_mutex, acpi_gbl_db_command_ready);
-ACPI_GLOBAL(acpi_mutex, acpi_gbl_db_command_complete);
-
 #endif				/* ACPI_DEBUGGER */
 
 /*****************************************************************************
drivers/acpi/acpica/dbinput.c +19 -78

138 lines not on this page · raw message

drivers/acpi/acpica/dbxface.c +18 -45

98 lines not on this page · raw message

drivers/acpi/acpica/utmutex.c +0 -17
index ce406e3..ea0c207 100644
@@ -111,17 +111,6 @@ acpi_status acpi_ut_mutex_initialize(void)
 	if (ACPI_FAILURE(status)) {
 		return_ACPI_STATUS(status);
 	}
-#ifdef ACPI_DEBUGGER
-
-	/* Debugger Support */
-
-	status = acpi_os_create_mutex(&acpi_gbl_db_command_ready);
-	if (ACPI_FAILURE(status)) {
-		return_ACPI_STATUS(status);
-	}
-
-	status = acpi_os_create_mutex(&acpi_gbl_db_command_complete);
-#endif
 
 	return_ACPI_STATUS(status);
 }
@@ -162,12 +151,6 @@ void acpi_ut_mutex_terminate(void)
 	/* Delete the reader/writer lock */
 
 	acpi_ut_delete_rw_lock(&acpi_gbl_namespace_rw_lock);
-
-#ifdef ACPI_DEBUGGER
-	acpi_os_delete_mutex(acpi_gbl_db_command_ready);
-	acpi_os_delete_mutex(acpi_gbl_db_command_complete);
-#endif
-
 	return_VOID;
 }
 
include/acpi/acpiosxf.h +17 -1
index fbc2baf..0d824a2 100644
@@ -349,12 +349,28 @@ void acpi_os_redirect_output(void *destination);
 #endif
 
 /*
- * Debug input
+ * Debug IO
  */
 #ifndef ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_get_line
 acpi_status acpi_os_get_line(char *buffer, u32 buffer_length, u32 *bytes_read);
 #endif
 
+#ifndef ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_initialize_command_signals
+acpi_status acpi_os_initialize_command_signals(void);
+#endif
+
+#ifndef ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_terminate_command_signals
+void acpi_os_terminate_command_signals(void);
+#endif
+
+#ifndef ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_wait_command_ready
+acpi_status acpi_os_wait_command_ready(void);
+#endif
+
+#ifndef ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_notify_command_complete
+acpi_status acpi_os_notify_command_complete(void);
+#endif
+
 /*
  * Obtain ACPI table(s)
  */
include/acpi/acpixf.h +11 -0
index 3aaaa86..95ebae3 100644
@@ -264,6 +264,15 @@ ACPI_INIT_GLOBAL(u32, acpi_dbg_level, ACPI_DEBUG_DEFAULT);
 ACPI_INIT_GLOBAL(u32, acpi_dbg_layer, 0);
 
 /*
+ * Debugger command handshake globals. Host OSes need to access these
+ * variables to implement their own command handshake mechanism.
+ */
+#ifdef ACPI_DEBUGGER
+ACPI_INIT_GLOBAL(u8, acpi_gbl_method_executing, FALSE);
+ACPI_GLOBAL(char, acpi_gbl_db_line_buf[ACPI_DB_LINE_BUFFER_SIZE]);
+#endif
+
+/*
  * Other miscellaneous globals
  */
 ACPI_GLOBAL(struct acpi_table_fadt, acpi_gbl_FADT);
@@ -929,6 +938,8 @@ ACPI_EXTERNAL_RETURN_STATUS(acpi_status
 					       void **data,
 					       void (*callback)(void *)))
 
+void acpi_run_debugger(char *batch_buffer);
+
 void acpi_set_debugger_thread_id(acpi_thread_id thread_id);
 
 #endif				/* __ACXFACE_H__ */
include/acpi/platform/aclinux.h +4 -0
index 323e5da..69dbae6 100644
@@ -150,6 +150,10 @@
  */
 #define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_readable
 #define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_writable
+#define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_initialize_command_signals
+#define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_terminate_command_signals
+#define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_wait_command_ready
+#define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_notify_command_complete
 
 /*
  * OSL interfaces used by utilities
include/acpi/platform/aclinuxex.h +19 -0
index fd6d70f..673fdf4 100644
@@ -129,6 +129,25 @@ static inline u8 acpi_os_readable(void *pointer, acpi_size length)
 	return TRUE;
 }
 
+static inline acpi_status acpi_os_initialize_command_signals(void)
+{
+	return AE_OK;
+}
+
+static inline void acpi_os_terminate_command_signals(void)
+{
+}
+
+static inline acpi_status acpi_os_wait_command_ready(void)
+{
+	return AE_ERROR;
+}
+
+static inline acpi_status acpi_os_notify_command_complete(void)
+{
+	return AE_ERROR;
+}
+
 /*
  * OSL interfaces added by Linux
  */
Signature · 1 line
1.7.10
author
#28 lore raw

PATCH v2 3/7 ACPICA: Debugger: Fix runtime stub issues of ACPI_DEBUGGER_EXEC using different stub mechanism

In reply to Lv Zheng

The ACPI_DEBUGGER_EXEC is a problem now when the debugger code is compiled but runtime disabled. They actually will get executed in this situation. Although such executions are harmless if we can correctly make acpi_db_single_step() a runtime stub, users may still do not want to see the debugger print messages logged into OSPMs' kernel logs when a debugger driver is not loaded to enable the debugger during runtime.

This patch fixes this issue by introducing new stub mechanism instead of ACPI_DEBUGGER_EXEC. Lv Zheng.

---
 drivers/acpi/acpica/acdebug.h   |   34 ++++++++++++++++++++++++----------
 drivers/acpi/acpica/acmacros.h  |   11 -----------
 drivers/acpi/acpica/dbdisply.c  |   12 ++++++++++++
 drivers/acpi/acpica/dbxface.c   |   30 ++++++++++++++++++++++++++++++
 drivers/acpi/acpica/dscontrol.c |   10 ++--------
 drivers/acpi/acpica/dsutils.c   |   16 ++++++++--------
 drivers/acpi/acpica/dswexec.c   |   16 +++++++---------
 include/acpi/acpixf.h           |   23 +++++++++++++++++++++++
 8 files changed, 106 insertions(+), 46 deletions(-)
drivers/acpi/acpica/acdebug.h +24 -10
index 86474d8..dcaa15d 100644
@@ -80,9 +80,15 @@ struct acpi_db_execute_walk {
 /*
  * dbxface - external debugger interfaces
  */
-acpi_status
-acpi_db_single_step(struct acpi_walk_state *walk_state,
-		    union acpi_parse_object *op, u32 op_type);
+ACPI_DBR_DEPENDENT_RETURN_OK(acpi_status
+			     acpi_db_single_step(struct acpi_walk_state
+						 *walk_state,
+						 union acpi_parse_object *op,
+						 u32 op_type))
+ ACPI_DBR_DEPENDENT_RETURN_VOID(void
+				acpi_db_signal_break_point(struct
+							   acpi_walk_state
+							   *walk_state))
 
 /*
  * dbcmds - debug commands and output routines
@@ -182,11 +188,15 @@ void acpi_db_display_method_info(union acpi_parse_object *op);
 
 void acpi_db_decode_and_display_object(char *target, char *output_type);
 
-void
-acpi_db_display_result_object(union acpi_operand_object *obj_desc,
-			      struct acpi_walk_state *walk_state);
+ACPI_DBR_DEPENDENT_RETURN_VOID(void
+			       acpi_db_display_result_object(union
+							     acpi_operand_object
+							     *obj_desc,
+							     struct
+							     acpi_walk_state
+							     *walk_state))
 
-acpi_status acpi_db_display_all_methods(char *display_count_arg);
+ acpi_status acpi_db_display_all_methods(char *display_count_arg);
 
 void acpi_db_display_arguments(void);
 
@@ -198,9 +208,13 @@ void acpi_db_display_calling_tree(void);
 
 void acpi_db_display_object_type(char *object_arg);
 
-void
-acpi_db_display_argument_object(union acpi_operand_object *obj_desc,
-				struct acpi_walk_state *walk_state);
+ACPI_DBR_DEPENDENT_RETURN_VOID(void
+			       acpi_db_display_argument_object(union
+							       acpi_operand_object
+							       *obj_desc,
+							       struct
+							       acpi_walk_state
+							       *walk_state))
 
 /*
  * dbexec - debugger control method execution
drivers/acpi/acpica/acmacros.h +0 -11
index e85366c..bad5bca 100644
@@ -401,17 +401,6 @@
 #endif
 
 /*
- * Some code only gets executed when the debugger is built in.
- * Note that this is entirely independent of whether the
- * DEBUG_PRINT stuff (set by ACPI_DEBUG_OUTPUT) is on, or not.
- */
-#ifdef ACPI_DEBUGGER
-#define ACPI_DEBUGGER_EXEC(a)           a
-#else
-#define ACPI_DEBUGGER_EXEC(a)
-#endif
-
-/*
  * Macros used for ACPICA utilities only
  */
 
drivers/acpi/acpica/dbdisply.c +12 -0
index 672977e..c42ce8a 100644
@@ -679,6 +679,12 @@ acpi_db_display_result_object(union acpi_operand_object *obj_desc,
 			      struct acpi_walk_state *walk_state)
 {
 
+#ifndef ACPI_APPLICATION
+	if (acpi_gbl_db_thread_id != acpi_os_get_thread_id()) {
+		return;
+	}
+#endif
+
 	/* Only display if single stepping */
 
 	if (!acpi_gbl_cm_single_step) {
@@ -708,6 +714,12 @@ acpi_db_display_argument_object(union acpi_operand_object *obj_desc,
 				struct acpi_walk_state *walk_state)
 {
 
+#ifndef ACPI_APPLICATION
+	if (acpi_gbl_db_thread_id != acpi_os_get_thread_id()) {
+		return;
+	}
+#endif
+
 	if (!acpi_gbl_cm_single_step) {
 		return;
 	}
drivers/acpi/acpica/dbxface.c +30 -0
index d95e91f..d7ff58e 100644
@@ -119,6 +119,36 @@ error_exit:
 
 /*******************************************************************************
  *
+ * FUNCTION:    acpi_db_signal_break_point
+ *
+ * PARAMETERS:  walk_state      - Current walk
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Called for AML_BREAK_POINT_OP
+ *
+ ******************************************************************************/
+
+void acpi_db_signal_break_point(struct acpi_walk_state *walk_state)
+{
+
+#ifndef ACPI_APPLICATION
+	if (acpi_gbl_db_thread_id != acpi_os_get_thread_id()) {
+		return;
+	}
+#endif
+
+	/*
+	 * Set the single-step flag. This will cause the debugger (if present)
+	 * to break to the console within the AML debugger at the start of the
+	 * next AML instruction.
+	 */
+	acpi_gbl_cm_single_step = TRUE;
+	acpi_os_printf("**break** Executed AML BreakPoint opcode\n");
+}
+
+/*******************************************************************************
+ *
  * FUNCTION:    acpi_db_single_step
  *
  * PARAMETERS:  walk_state      - Current walk
drivers/acpi/acpica/dscontrol.c +2 -8
index 435fc16..06a6f7f 100644
@@ -47,6 +47,7 @@
 #include "amlcode.h"
 #include "acdispat.h"
 #include "acinterp.h"
+#include "acdebug.h"
 
 #define _COMPONENT          ACPI_DISPATCHER
 ACPI_MODULE_NAME("dscontrol")
@@ -348,14 +349,7 @@ acpi_ds_exec_end_control_op(struct acpi_walk_state * walk_state,
 
 	case AML_BREAK_POINT_OP:
 
-		/*
-		 * Set the single-step flag. This will cause the debugger (if present)
-		 * to break to the console within the AML debugger at the start of the
-		 * next AML instruction.
-		 */
-		ACPI_DEBUGGER_EXEC(acpi_gbl_cm_single_step = TRUE);
-		ACPI_DEBUGGER_EXEC(acpi_os_printf
-				   ("**break** Executed AML BreakPoint opcode\n"));
+		acpi_db_signal_break_point(walk_state);
 
 		/* Call to the OSL in case OS wants a piece of the action */
 
drivers/acpi/acpica/dsutils.c +8 -8
index ebc577b..e4293a8 100644
@@ -605,8 +605,8 @@ acpi_ds_create_operand(struct acpi_walk_state *walk_state,
 		if (ACPI_FAILURE(status)) {
 			return_ACPI_STATUS(status);
 		}
-		ACPI_DEBUGGER_EXEC(acpi_db_display_argument_object
-				   (obj_desc, walk_state));
+
+		acpi_db_display_argument_object(obj_desc, walk_state);
 	} else {
 		/* Check for null name case */
 
@@ -638,10 +638,11 @@ acpi_ds_create_operand(struct acpi_walk_state *walk_state,
 			ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
 					  "Argument previously created, already stacked\n"));
 
-			ACPI_DEBUGGER_EXEC(acpi_db_display_argument_object
-					   (walk_state->
-					    operands[walk_state->num_operands -
-						     1], walk_state));
+			acpi_db_display_argument_object(walk_state->
+							operands[walk_state->
+								 num_operands -
+								 1],
+							walk_state);
 
 			/*
 			 * Use value that was already previously returned
@@ -685,8 +686,7 @@ acpi_ds_create_operand(struct acpi_walk_state *walk_state,
 			return_ACPI_STATUS(status);
 		}
 
-		ACPI_DEBUGGER_EXEC(acpi_db_display_argument_object
-				   (obj_desc, walk_state));
+		acpi_db_display_argument_object(obj_desc, walk_state);
 	}
 
 	return_ACPI_STATUS(AE_OK);
drivers/acpi/acpica/dswexec.c +7 -9
index df54d46..9cc5761 100644
@@ -178,8 +178,7 @@ cleanup:
 
 	/* Break to debugger to display result */
 
-	ACPI_DEBUGGER_EXEC(acpi_db_display_result_object
-			   (local_obj_desc, walk_state));
+	acpi_db_display_result_object(local_obj_desc, walk_state);
 
 	/*
 	 * Delete the predicate result object (we know that
@@ -386,11 +385,10 @@ acpi_status acpi_ds_exec_end_op(struct acpi_walk_state *walk_state)
 
 	/* Call debugger for single step support (DEBUG build only) */
 
-	ACPI_DEBUGGER_EXEC(status =
-			   acpi_db_single_step(walk_state, op, op_class));
-	ACPI_DEBUGGER_EXEC(if (ACPI_FAILURE(status)) {
-			   return_ACPI_STATUS(status);}
-	) ;
+	status = acpi_db_single_step(walk_state, op, op_class);
+	if (ACPI_FAILURE(status)) {
+		return_ACPI_STATUS(status);
+	}
 
 	/* Decode the Opcode Class */
 
@@ -728,8 +726,8 @@ cleanup:
 
 		/* Break to debugger to display result */
 
-		ACPI_DEBUGGER_EXEC(acpi_db_display_result_object
-				   (walk_state->result_obj, walk_state));
+		acpi_db_display_result_object(walk_state->result_obj,
+					      walk_state);
 
 		/*
 		 * Delete the result op if and only if:
include/acpi/acpixf.h +23 -0
index 95ebae3..5dfab9c 100644
@@ -375,6 +375,29 @@ ACPI_GLOBAL(u8, acpi_gbl_system_awake_and_running);
 
 #endif				/* ACPI_APPLICATION */
 
+/*
+ * Debugger prototypes
+ *
+ * All interfaces used by debugger will be configured
+ * out of the ACPICA build unless the ACPI_DEBUGGER
+ * flag is defined.
+ */
+#ifdef ACPI_DEBUGGER
+#define ACPI_DBR_DEPENDENT_RETURN_OK(prototype) \
+	ACPI_EXTERNAL_RETURN_OK(prototype)
+
+#define ACPI_DBR_DEPENDENT_RETURN_VOID(prototype) \
+	ACPI_EXTERNAL_RETURN_VOID(prototype)
+
+#else
+#define ACPI_DBR_DEPENDENT_RETURN_OK(prototype) \
+	static ACPI_INLINE prototype {return(AE_OK);}
+
+#define ACPI_DBR_DEPENDENT_RETURN_VOID(prototype) \
+	static ACPI_INLINE prototype {return;}
+
+#endif				/* ACPI_DEBUGGER */
+
 /*****************************************************************************
  *
  * ACPICA public interface prototypes
Signature · 1 line
1.7.10
author
#29 lore raw

PATCH v2 4/7 ACPI / debugger: Add IO interface to access debugger functionalities

In reply to Lv Zheng

This patch adds /sys/kernel/debug/acpi/acpidbg, which can be used by userspace programs to access ACPICA debugger functionalities.

Known issue:
1. IO flush support
acpi_os_notify_command_complete() and acpi_os_wait_command_ready() can be used by acpi_dbg module to implement .flush() filesystem operation. While this patch doesn't go that far. It then becomes userspace tool's duty now to flush old commands before executing new batch mode commands.

---
 drivers/acpi/Kconfig              |    3 +-
 drivers/acpi/Makefile             |    1 +
 drivers/acpi/acpi_dbg.c           |  792 +++++++++++++++++++++++++++++++++++++
 drivers/acpi/bus.c                |    2 +
 drivers/acpi/osl.c                |   55 ++-
 include/acpi/platform/aclinux.h   |    2 -
 include/acpi/platform/aclinuxex.h |   10 -
 include/linux/acpi_dbg.h          |   52 +++
 8 files changed, 900 insertions(+), 17 deletions(-)
 create mode 100644 drivers/acpi/acpi_dbg.c
 create mode 100644 include/linux/acpi_dbg.h
drivers/acpi/Kconfig +2 -1
index 25dbb76..4de3517 100644
@@ -58,8 +58,9 @@ config ACPI_CCA_REQUIRED
 	bool
 
 config ACPI_DEBUGGER
-	bool "In-kernel debugger (EXPERIMENTAL)"
+	bool "In-kernel debugger"
 	select ACPI_DEBUG
+	depends on DEBUG_FS
 	help
 	  Enable in-kernel debugging facilities: statistics, internal
 	  object dump, single step control method execution.
drivers/acpi/Makefile +1 -0
index 675eaf3..102b5e6 100644
@@ -50,6 +50,7 @@ acpi-y				+= sysfs.o
 acpi-y				+= property.o
 acpi-$(CONFIG_X86)		+= acpi_cmos_rtc.o
 acpi-$(CONFIG_DEBUG_FS)		+= debugfs.o
+acpi-$(CONFIG_ACPI_DEBUGGER)	+= acpi_dbg.o
 acpi-$(CONFIG_ACPI_NUMA)	+= numa.o
 acpi-$(CONFIG_ACPI_PROCFS_POWER) += cm_sbs.o
 acpi-y				+= acpi_lpat.o
drivers/acpi/acpi_dbg.c new file +792 -0

792 lines not on this page · raw message

drivers/acpi/bus.c +2 -0
index a212cef..06fbba9 100644
@@ -37,6 +37,7 @@
 #include <acpi/apei.h>
 #include <linux/dmi.h>
 #include <linux/suspend.h>
+#include <linux/acpi_dbg.h>
 
 #include "internal.h"
 
@@ -1094,6 +1095,7 @@ static int __init acpi_init(void)
 	acpi_debugfs_init();
 	acpi_sleep_proc_init();
 	acpi_wakeup_device_init();
+	acpi_aml_init();
 	return 0;
 }
 
drivers/acpi/osl.c +51 -4

105 lines not on this page · raw message

include/acpi/platform/aclinux.h +0 -2
index 69dbae6..e21857d 100644
@@ -152,8 +152,6 @@
 #define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_writable
 #define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_initialize_command_signals
 #define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_terminate_command_signals
-#define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_wait_command_ready
-#define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_notify_command_complete
 
 /*
  * OSL interfaces used by utilities
include/acpi/platform/aclinuxex.h +0 -10
index 673fdf4..ceea026 100644
@@ -138,16 +138,6 @@ static inline void acpi_os_terminate_command_signals(void)
 {
 }
 
-static inline acpi_status acpi_os_wait_command_ready(void)
-{
-	return AE_ERROR;
-}
-
-static inline acpi_status acpi_os_notify_command_complete(void)
-{
-	return AE_ERROR;
-}
-
 /*
  * OSL interfaces added by Linux
  */
include/linux/acpi_dbg.h new file +52 -0

52 lines not on this page · raw message

Signature · 1 line
1.7.10
author
#30 lore raw

PATCH v2 5/7 ACPI / x86: introduce acpi_os_readable() support

In reply to Lv Zheng

From: Chen Yu <[email protected]>

This patch implements acpi_os_readable(). The function is used by ACPI AML debugger to validate user specified pointers for the dumpable AML operand objects.

---
 arch/x86/Kconfig                  |    1 +
 arch/x86/include/asm/acenv.h      |    1 +
 arch/x86/kernel/acpi/boot.c       |   14 ++++++++++++++
 drivers/acpi/Kconfig              |    3 +++
 drivers/acpi/osl.c                |   12 ++++++++++++
 include/acpi/platform/aclinux.h   |    1 -
 include/acpi/platform/aclinuxex.h |    5 -----
 7 files changed, 31 insertions(+), 6 deletions(-)
arch/x86/Kconfig +1 -0
index 96d058a..25585ee 100644
@@ -19,6 +19,7 @@ config X86
 	def_bool y
 	select ACPI_LEGACY_TABLES_LOOKUP	if ACPI
 	select ACPI_SYSTEM_POWER_STATES_SUPPORT	if ACPI
+	select ACPI_MEMORY_ACCESS_CHECK_SUPPORT	if ACPI
 	select ANON_INODES
 	select ARCH_CLOCKSOURCE_DATA
 	select ARCH_DISCARD_MEMBLOCK
arch/x86/include/asm/acenv.h +1 -0
index 1b010a8..a2a2849 100644
@@ -20,6 +20,7 @@
 
 int __acpi_acquire_global_lock(unsigned int *lock);
 int __acpi_release_global_lock(unsigned int *lock);
+bool __acpi_memory_readable(void *pointer, size_t length);
 
 #define ACPI_ACQUIRE_GLOBAL_LOCK(facs, Acq) \
 	((Acq) = __acpi_acquire_global_lock(&facs->global_lock))
arch/x86/kernel/acpi/boot.c +14 -0
index e759076..3e03fde 100644
@@ -1699,6 +1699,20 @@ int __acpi_release_global_lock(unsigned int *lock)
 	return old & 0x1;
 }
 
+bool __acpi_memory_readable(void *pointer, size_t length)
+{
+	unsigned long start_pfn, end_pfn;
+
+	start_pfn = page_to_pfn(virt_to_page(pointer));
+	end_pfn = page_to_pfn(virt_to_page(pointer + length));
+	/*
+	 * Since the acpi address is allocated by kmalloc, we only
+	 * need to consider the direct-mapping virtual address,
+	 * rather than the kmap/vmalloc/ioremap address.
+	 */
+	return pfn_range_is_mapped(start_pfn, end_pfn) ? true : false;
+}
+
 void __init arch_reserve_mem_area(acpi_physical_address addr, size_t size)
 {
 	e820_add_region(addr, size, E820_ACPI);
drivers/acpi/Kconfig +3 -0
index 4de3517..e67b1b5 100644
@@ -57,6 +57,9 @@ config ACPI_SYSTEM_POWER_STATES_SUPPORT
 config ACPI_CCA_REQUIRED
 	bool
 
+config ACPI_MEMORY_ACCESS_CHECK_SUPPORT
+	bool
+
 config ACPI_DEBUGGER
 	bool "In-kernel debugger"
 	select ACPI_DEBUG
drivers/acpi/osl.c +12 -0
index 2de8f66..bc3da95 100644
@@ -1387,6 +1387,18 @@ acpi_status acpi_os_get_line(char *buffer, u32 buffer_length, u32 *bytes_read)
 	return AE_OK;
 }
 
+#ifdef CONFIG_ACPI_MEMORY_ACCESS_CHECK_SUPPORT
+u8 acpi_os_readable(void *pointer, acpi_size length)
+{
+	return __acpi_memory_readable(pointer, length);
+}
+#else
+u8 acpi_os_readable(void *pointer, acpi_size length)
+{
+	return true;
+}
+#endif
+
 acpi_status acpi_os_wait_command_ready(void)
 {
 	int ret;
include/acpi/platform/aclinux.h +0 -1
index e21857d..b3c493e 100644
@@ -148,7 +148,6 @@
 /*
  * OSL interfaces used by debugger/disassembler
  */
-#define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_readable
 #define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_writable
 #define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_initialize_command_signals
 #define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_terminate_command_signals
include/acpi/platform/aclinuxex.h +0 -5
index ceea026..94bead6 100644
@@ -124,11 +124,6 @@ static inline acpi_thread_id acpi_os_get_thread_id(void)
 		lock ? AE_OK : AE_NO_MEMORY; \
 	})
 
-static inline u8 acpi_os_readable(void *pointer, acpi_size length)
-{
-	return TRUE;
-}
-
 static inline acpi_status acpi_os_initialize_command_signals(void)
 {
 	return AE_OK;
Signature · 1 line
1.7.10
#31 lore raw

RE: [PATCH v2 5/7] ACPI / x86: introduce acpi_os_readable() support

Hi, Lv
Sorry for my late feedback on the patch, one minor nit below:

Quoted 17 lines

-----Original Message-----
From: Zheng, Lv
Sent: Tuesday, November 10, 2015 4:22 PM
To: Wysocki, Rafael J; Brown, Len
Cc: Zheng, Lv; Lv Zheng; [email protected]; linux- [email protected]; Chen, Yu C
Subject: [PATCH v2 5/7] ACPI / x86: introduce acpi_os_readable() support

From: Chen Yu <[email protected]>

This patch implements acpi_os_readable(). The function is used by ACPI AML debugger to validate user specified pointers for the dumpable AML operand objects.

---

arch/x86/kernel/acpi/boot.c int __acpi_release_global_lock(unsigned int *lock) · line 1705

Quoted 3 lines
arch/x86/kernel/acpi/boot.c +3 -0
+bool __acpi_memory_readable(void *pointer, size_t length) {
+	unsigned long start_pfn, end_pfn;
+

We should only check the low memory, otherwise the highmem address might bring unexpected behavior in this function, I think we should add:

	if (pointer  >= PAGE_OFFSET)
		return false;

arch/x86/kernel/acpi/boot.c int __acpi_release_global_lock(unsigned int *lock) · line 1707

Quoted 2 lines
arch/x86/kernel/acpi/boot.c +2 -0
+	start_pfn = page_to_pfn(virt_to_page(pointer));
+	end_pfn = page_to_pfn(virt_to_page(pointer + length));

Convert pointer to char* first?
end_pfn = page_to_pfn(virt_to_page((char*)pointer + length));

arch/x86/kernel/acpi/boot.c int __acpi_release_global_lock(unsigned int *lock) · line 1715

Quoted 7 lines
arch/x86/kernel/acpi/boot.c +7 -0
+	/*
+	 * Since the acpi address is allocated by kmalloc, we only
+	 * need to consider the direct-mapping virtual address,
+	 * rather than the kmap/vmalloc/ioremap address.
+	 */
+	return pfn_range_is_mapped(start_pfn, end_pfn) ? true : false; }
+

Thanks!

Best Regards,
Yu

#32 lore raw

RE: [PATCH v2 5/7] ACPI / x86: introduce acpi_os_readable() support

Quoted 35 lines

-----Original Message-----
From: Chen, Yu C
Sent: Tuesday, November 10, 2015 5:43 PM
To: Zheng, Lv
Cc: Lv Zheng; [email protected]; [email protected]; Wysocki, Rafael J; Brown, Len
Subject: RE: [PATCH v2 5/7] ACPI / x86: introduce acpi_os_readable() support

Hi, Lv
Sorry for my late feedback on the patch, one minor nit below:

Quoted 18 lines

-----Original Message-----
From: Zheng, Lv
Sent: Tuesday, November 10, 2015 4:22 PM
To: Wysocki, Rafael J; Brown, Len
Cc: Zheng, Lv; Lv Zheng; [email protected]; linux- [email protected]; Chen, Yu C
Subject: [PATCH v2 5/7] ACPI / x86: introduce acpi_os_readable() support

From: Chen Yu <[email protected]>

This patch implements acpi_os_readable(). The function is used by ACPI AML debugger to validate user specified pointers for the dumpable AML operand objects.

---

arch/x86/kernel/acpi/boot.c int __acpi_release_global_lock(unsigned int *lock) · line 1705

Quoted 3 lines
arch/x86/kernel/acpi/boot.c +3 -0
+bool __acpi_memory_readable(void *pointer, size_t length) {
+	unsigned long start_pfn, end_pfn;
+

We should only check the low memory, otherwise the highmem address might bring unexpected behavior in this function, I think we should add:

Quoted 2 lines
	if (pointer  >= PAGE_OFFSET)
		return false;

Should be :

	If (pointer < PAGE_OFFSET && pointer >= high_memory)
		return false;
Quoted 16 lines

arch/x86/kernel/acpi/boot.c int __acpi_release_global_lock(unsigned int *lock) · line 1707

Quoted 2 lines
arch/x86/kernel/acpi/boot.c +2 -0
+	start_pfn = page_to_pfn(virt_to_page(pointer));
+	end_pfn = page_to_pfn(virt_to_page(pointer + length));

Convert pointer to char* first?
end_pfn = page_to_pfn(virt_to_page((char*)pointer + length));

arch/x86/kernel/acpi/boot.c int __acpi_release_global_lock(unsigned int *lock) · line 1715

Quoted 7 lines
arch/x86/kernel/acpi/boot.c +7 -0
+	/*
+	 * Since the acpi address is allocated by kmalloc, we only
+	 * need to consider the direct-mapping virtual address,
+	 * rather than the kmap/vmalloc/ioremap address.
+	 */
+	return pfn_range_is_mapped(start_pfn, end_pfn) ? true : false; }
+

Thanks!

Best Regards,
Yu

#33 lore raw

Re: [PATCH v2 5/7] ACPI / x86: introduce acpi_os_readable() support

In reply to Chen, Yu C
Quoted 7 lines · Yu C

Hi, Lv
Sorry for my late feedback on the patch, one minor nit below:

arch/x86/kernel/acpi/boot.c int __acpi_release_global_lock(unsigned int *lock) · line 1707

Quoted 2 lines
arch/x86/kernel/acpi/boot.c +2 -0
+     start_pfn = page_to_pfn(virt_to_page(pointer));
+     end_pfn = page_to_pfn(virt_to_page(pointer + length));

Convert pointer to char* first?
end_pfn = page_to_pfn(virt_to_page((char*)pointer + length));

Why do you need that?
void * + size_t = char * + size_t

Signature · 2 lines
With Best Regards,
Andy Shevchenko
#34 lore raw

RE: [PATCH v2 5/7] ACPI / x86: introduce acpi_os_readable() support

Hi, Shevchenko,
Thanks for you review

Quoted 12 lines

-----Original Message-----
From: Andy Shevchenko [mailto:[email protected]]
Sent: Tuesday, November 10, 2015 9:04 PM
To: Chen, Yu C
Cc: Zheng, Lv; Lv Zheng; [email protected]; linux- [email protected]; Wysocki, Rafael J; Brown, Len
Subject: Re: [PATCH v2 5/7] ACPI / x86: introduce acpi_os_readable() support

Quoted 2 lines · Yu C

Hi, Lv
Sorry for my late feedback on the patch, one minor nit below:

Quoted 8 lines
Quoted 4 lines

arch/x86/kernel/acpi/boot.c int __acpi_release_global_lock(unsigned int *lock) · line 1707

Quoted 2 lines
arch/x86/kernel/acpi/boot.c +2 -0
+     start_pfn = page_to_pfn(virt_to_page(pointer));
+     end_pfn = page_to_pfn(virt_to_page(pointer + length));

Convert pointer to char* first?
end_pfn = page_to_pfn(virt_to_page((char*)pointer + length));

Why do you need that?
void * + size_t = char * + size_t

Hum, I was under impression it was a pointer, so I converted it to char* for safety, but it seems a wrong impression,and I've just tested it on gcc, it is OK without char*.

Quoted 3 lines

--
With Best Regards,
Andy Shevchenko

author
#35 lore raw

RE: [PATCH v2 5/7] ACPI / x86: introduce acpi_os_readable() support

In reply to Chen, Yu C

Hi, Yu

Quoted 23 lines

From: Chen, Yu C
Sent: Tuesday, November 10, 2015 5:43 PM

Hi, Lv
Sorry for my late feedback on the patch, one minor nit below:

Quoted 12 lines

From: Zheng, Lv
Sent: Tuesday, November 10, 2015 4:22 PM

From: Chen Yu <[email protected]>

This patch implements acpi_os_readable(). The function is used by ACPI AML debugger to validate user specified pointers for the dumpable AML operand objects.

---

arch/x86/kernel/acpi/boot.c int __acpi_release_global_lock(unsigned int *lock) · line 1705

Quoted 3 lines
arch/x86/kernel/acpi/boot.c +3 -0
+bool __acpi_memory_readable(void *pointer, size_t length) {
+	unsigned long start_pfn, end_pfn;
+

We should only check the low memory, otherwise the highmem address might bring unexpected behavior in this function, I think we should add:

Quoted 2 lines
	if (pointer  >= PAGE_OFFSET)
		return false;

I think pfn_range_is_mapped() can ensure this.
If you want to add some sanity checks, IMO, virt_addr_valid() could be better.

Quoted 4 lines

arch/x86/kernel/acpi/boot.c int __acpi_release_global_lock(unsigned int *lock) · line 1707

Quoted 2 lines
arch/x86/kernel/acpi/boot.c +2 -0
+	start_pfn = page_to_pfn(virt_to_page(pointer));
+	end_pfn = page_to_pfn(virt_to_page(pointer + length));

Convert pointer to char* first?
end_pfn = page_to_pfn(virt_to_page((char*)pointer + length));

Either a compiler supports such a conversion or a compiler ends up fatal error by complaining unknown sizeof(void *). So there is no need to do this here as the build test has passed.

Thanks and best regards
-Lv

Quoted 12 lines

arch/x86/kernel/acpi/boot.c int __acpi_release_global_lock(unsigned int *lock) · line 1715

Quoted 8 lines
arch/x86/kernel/acpi/boot.c +7 -0
+	/*
+	 * Since the acpi address is allocated by kmalloc, we only
+	 * need to consider the direct-mapping virtual address,
+	 * rather than the kmap/vmalloc/ioremap address.
+	 */
+	return pfn_range_is_mapped(start_pfn, end_pfn) ? true : false; }
+

Thanks!

Best Regards,
Yu

#36 lore raw

RE: [PATCH v2 5/7] ACPI / x86: introduce acpi_os_readable() support

Hi,

Quoted 36 lines

-----Original Message-----
From: Zheng, Lv
Sent: Wednesday, November 11, 2015 1:07 PM
To: Chen, Yu C
Cc: Lv Zheng; [email protected]; [email protected]; Wysocki, Rafael J; Brown, Len
Subject: RE: [PATCH v2 5/7] ACPI / x86: introduce acpi_os_readable() support

Hi, Yu

Quoted 23 lines

From: Chen, Yu C
Sent: Tuesday, November 10, 2015 5:43 PM

Hi, Lv
Sorry for my late feedback on the patch, one minor nit below:

Quoted 12 lines

From: Zheng, Lv
Sent: Tuesday, November 10, 2015 4:22 PM

From: Chen Yu <[email protected]>

This patch implements acpi_os_readable(). The function is used by ACPI AML debugger to validate user specified pointers for the dumpable AML operand objects.

---

arch/x86/kernel/acpi/boot.c int __acpi_release_global_lock(unsigned int *lock) · line 1705

Quoted 3 lines
arch/x86/kernel/acpi/boot.c +3 -0
+bool __acpi_memory_readable(void *pointer, size_t length) {
+	unsigned long start_pfn, end_pfn;
+

We should only check the low memory, otherwise the highmem address might bring unexpected behavior in this function, I think we should add:

Quoted 2 lines
	if (pointer  >= PAGE_OFFSET)
		return false;
Quoted 1 line

I think pfn_range_is_mapped() can ensure this.

virt_to_page might return an invalid page struct if pointer is not a valid kernel address.

Quoted 2 lines

If you want to add some sanity checks, IMO, virt_addr_valid() could be better.

Yes, virt_addr_valid is better.

Quoted 10 lines
Quoted 5 lines

arch/x86/kernel/acpi/boot.c int __acpi_release_global_lock(unsigned int *lock) · line 1707

Quoted 3 lines
arch/x86/kernel/acpi/boot.c +2 -0
+	start_pfn = page_to_pfn(virt_to_page(pointer));
+	end_pfn = page_to_pfn(virt_to_page(pointer + length));

Convert pointer to char* first?
end_pfn = page_to_pfn(virt_to_page((char*)pointer + length));

Either a compiler supports such a conversion or a compiler ends up fatal error by complaining unknown sizeof(void *).
So there is no need to do this here as the build test has passed.

OK, got it, thanks.

Quoted 15 lines

Thanks and best regards
-Lv

Quoted 12 lines

arch/x86/kernel/acpi/boot.c int __acpi_release_global_lock(unsigned int *lock) · line 1715

Quoted 8 lines
arch/x86/kernel/acpi/boot.c +7 -0
+	/*
+	 * Since the acpi address is allocated by kmalloc, we only
+	 * need to consider the direct-mapping virtual address,
+	 * rather than the kmap/vmalloc/ioremap address.
+	 */
+	return pfn_range_is_mapped(start_pfn, end_pfn) ? true : false; }
+

Thanks!

Best Regards,
Yu

author
#37 lore raw

RE: [PATCH v2 5/7] ACPI / x86: introduce acpi_os_readable() support

In reply to Zheng, Lv

Hi, Yu

Quoted 31 lines

From: Zheng, Lv
Sent: Wednesday, November 11, 2015 1:07 PM

Hi, Yu

Quoted 23 lines

From: Chen, Yu C
Sent: Tuesday, November 10, 2015 5:43 PM

Hi, Lv
Sorry for my late feedback on the patch, one minor nit below:

Quoted 12 lines

From: Zheng, Lv
Sent: Tuesday, November 10, 2015 4:22 PM

From: Chen Yu <[email protected]>

This patch implements acpi_os_readable(). The function is used by ACPI AML debugger to validate user specified pointers for the dumpable AML operand objects.

---

arch/x86/kernel/acpi/boot.c int __acpi_release_global_lock(unsigned int *lock) · line 1705

Quoted 3 lines
arch/x86/kernel/acpi/boot.c +3 -0
+bool __acpi_memory_readable(void *pointer, size_t length) {
+	unsigned long start_pfn, end_pfn;
+

We should only check the low memory, otherwise the highmem address might bring unexpected behavior in this function, I think we should add:

Quoted 2 lines
	if (pointer  >= PAGE_OFFSET)
		return false;
Quoted 2 lines

I think pfn_range_is_mapped() can ensure this.
If you want to add some sanity checks, IMO, virt_addr_valid() could be better.

I confirmed that pfn_range_is_mapped() doesn't cover this for us.
We need such a check or enhance this in pfn_range_is_mapped().
I'll remove this patch from this patchset and re-send the rest of the patches in this patchset as v3. For acpi_os_readable() support, I'll create a separate RFC patchset with different approaches included.

Thanks and best regards
-Lv

Quoted 24 lines
Quoted 5 lines

arch/x86/kernel/acpi/boot.c int __acpi_release_global_lock(unsigned int *lock) · line 1707

Quoted 3 lines
arch/x86/kernel/acpi/boot.c +2 -0
+	start_pfn = page_to_pfn(virt_to_page(pointer));
+	end_pfn = page_to_pfn(virt_to_page(pointer + length));

Convert pointer to char* first?
end_pfn = page_to_pfn(virt_to_page((char*)pointer + length));

Either a compiler supports such a conversion or a compiler ends up fatal error by complaining unknown sizeof(void *). So there is no need to do this here as the build test has passed.

Thanks and best regards
-Lv

Quoted 12 lines

arch/x86/kernel/acpi/boot.c int __acpi_release_global_lock(unsigned int *lock) · line 1715

Quoted 8 lines
arch/x86/kernel/acpi/boot.c +7 -0
+	/*
+	 * Since the acpi address is allocated by kmalloc, we only
+	 * need to consider the direct-mapping virtual address,
+	 * rather than the kmap/vmalloc/ioremap address.
+	 */
+	return pfn_range_is_mapped(start_pfn, end_pfn) ? true : false; }
+

Thanks!

Best Regards,
Yu

author
#38 lore raw

PATCH v2 6/7 tools/power/acpi: Add userspace AML interface support

In reply to Lv Zheng

This patch adds a userspace tool to access Linux kernel AML debugger interface.

Tow modes are supported by this tool:
1. Interactive: Users are able to launch a debugging shell to talk with in-kernel AML debugger.
Note that it's user duty to ensure kernel runtime integrity by using this debugging tool:
A. Some control methods evaluated by the users may result in kernel
panics if those control methods shouldn't be evaluated by the OSPMs according to the current BIOS/OS configurations.
B. Currently if a single stepping evaluation couldn't run to an end,
then the synchronization primitives acquired by the evaluation may block normal OSPM control method evaluations.
2. Batch: Users are able to execute debugger commands in a script. Note that in addition to the above duties, it's user duty to ensure script runtime integrity by using this debugging tool in this mode:
C. Currently only those commands that are not used for single stepping
are suitable to be used in this mode.
D. If the execution of the command may cause a failure that could result
in an endless kernel execution, the execution of the script may also get blocked.
To exit the utility, currently "exit/quit" commands are recommended, but ctrl-C" can also be used.

---
 tools/power/acpi/Makefile                |   16 +-
 tools/power/acpi/tools/acpidbg/Makefile  |   27 ++
 tools/power/acpi/tools/acpidbg/acpidbg.c |  438 ++++++++++++++++++++++++++++++
 3 files changed, 473 insertions(+), 8 deletions(-)
 create mode 100644 tools/power/acpi/tools/acpidbg/Makefile
 create mode 100644 tools/power/acpi/tools/acpidbg/acpidbg.c
tools/power/acpi/Makefile +8 -8
index e882c83..a8bf908 100644
@@ -10,18 +10,18 @@
 
 include ../../scripts/Makefile.include
 
-all: acpidump ec
-clean: acpidump_clean ec_clean
-install: acpidump_install ec_install
-uninstall: acpidump_uninstall ec_uninstall
+all: acpidbg acpidump ec
+clean: acpidbg_clean acpidump_clean ec_clean
+install: acpidbg_install acpidump_install ec_install
+uninstall: acpidbg_uninstall acpidump_uninstall ec_uninstall
 
-acpidump ec: FORCE
+acpidbg acpidump ec: FORCE
 	$(call descend,tools/$@,all)
-acpidump_clean ec_clean:
+acpidbg_clean acpidump_clean ec_clean:
 	$(call descend,tools/$(@:_clean=),clean)
-acpidump_install ec_install:
+acpidbg_install acpidump_install ec_install:
 	$(call descend,tools/$(@:_install=),install)
-acpidump_uninstall ec_uninstall:
+acpidbg_uninstall acpidump_uninstall ec_uninstall:
 	$(call descend,tools/$(@:_uninstall=),uninstall)
 
 .PHONY: FORCE
tools/power/acpi/tools/acpidbg/Makefile new file +27 -0
new file mode 100644
index 0000000..352df4b
@@ -0,0 +1,27 @@
+# tools/power/acpi/tools/acpidbg/Makefile - ACPI tool Makefile
+#
+# Copyright (c) 2015, Intel Corporation
+#   Author: Lv Zheng <[email protected]>
+#
+# 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; version 2
+# of the License.
+
+include ../../Makefile.config
+
+TOOL = acpidbg
+vpath %.c \
+	../../../../../drivers/acpi/acpica\
+	../../common\
+	../../os_specific/service_layers\
+	.
+CFLAGS += -DACPI_APPLICATION -DACPI_SINGLE_THREAD -DACPI_DEBUGGER\
+	-I.\
+	-I../../../../../drivers/acpi/acpica\
+	-I../../../../../include
+LDFLAGS += -lpthread
+TOOL_OBJS = \
+	acpidbg.o
+
+include ../../Makefile.rules
tools/power/acpi/tools/acpidbg/acpidbg.c new file +438 -0

438 lines not on this page · raw message

Signature · 1 line
1.7.10
author
#39 lore raw

PATCH v2 7/7 ACPI / debugger: Add module support for ACPI debugger

In reply to Lv Zheng

This patch converts AML debugger into a loadable module.

Note that, it implements driver unloading at the level dependent on the module reference count. Which means if ACPI debugger is being used by a userspace program, "rmmod acpi_dbg" should result in failure.

---
 drivers/acpi/Kconfig     |   12 ++-
 drivers/acpi/Makefile    |    2 +-
 drivers/acpi/acpi_dbg.c  |   80 ++++++++++++------
 drivers/acpi/bus.c       |    3 +-
 drivers/acpi/osl.c       |  207 ++++++++++++++++++++++++++++++++++++++++++++--
 include/linux/acpi.h     |   71 ++++++++++++++++
 include/linux/acpi_dbg.h |   52 ------------
 7 files changed, 338 insertions(+), 89 deletions(-)
 delete mode 100644 include/linux/acpi_dbg.h
drivers/acpi/Kconfig +11 -1
index e67b1b5..73b45f9 100644
@@ -63,13 +63,23 @@ config ACPI_MEMORY_ACCESS_CHECK_SUPPORT
 config ACPI_DEBUGGER
 	bool "In-kernel debugger"
 	select ACPI_DEBUG
-	depends on DEBUG_FS
 	help
 	  Enable in-kernel debugging facilities: statistics, internal
 	  object dump, single step control method execution.
 	  This is still under development, currently enabling this only
 	  results in the compilation of the ACPICA debugger files.
 
+if ACPI_DEBUGGER
+
+config ACPI_DEBUGGER_USER
+	tristate "Userspace debugger accessiblity"
+	depends on DEBUG_FS
+	help
+	  Export /sys/kernel/debug/acpi/acpidbg for userspace utilities
+	  to access the debugger functionalities.
+
+endif
+
 config ACPI_SLEEP
 	bool
 	depends on SUSPEND || HIBERNATION
drivers/acpi/Makefile +1 -1
index 102b5e6..c6f236f 100644
@@ -50,7 +50,6 @@ acpi-y				+= sysfs.o
 acpi-y				+= property.o
 acpi-$(CONFIG_X86)		+= acpi_cmos_rtc.o
 acpi-$(CONFIG_DEBUG_FS)		+= debugfs.o
-acpi-$(CONFIG_ACPI_DEBUGGER)	+= acpi_dbg.o
 acpi-$(CONFIG_ACPI_NUMA)	+= numa.o
 acpi-$(CONFIG_ACPI_PROCFS_POWER) += cm_sbs.o
 acpi-y				+= acpi_lpat.o
@@ -80,6 +79,7 @@ obj-$(CONFIG_ACPI_EC_DEBUGFS)	+= ec_sys.o
 obj-$(CONFIG_ACPI_CUSTOM_METHOD)+= custom_method.o
 obj-$(CONFIG_ACPI_BGRT)		+= bgrt.o
 obj-$(CONFIG_ACPI_CPPC_LIB)	+= cppc_acpi.o
+obj-$(CONFIG_ACPI_DEBUGGER_USER) += acpi_dbg.o
 
 # processor has its own "processor." module_param namespace
 processor-y			:= processor_driver.o
drivers/acpi/acpi_dbg.c +53 -27

156 lines not on this page · raw message

drivers/acpi/bus.c +1 -2
index 06fbba9..1a40111 100644
@@ -37,7 +37,6 @@
 #include <acpi/apei.h>
 #include <linux/dmi.h>
 #include <linux/suspend.h>
-#include <linux/acpi_dbg.h>
 
 #include "internal.h"
 
@@ -1095,7 +1094,7 @@ static int __init acpi_init(void)
 	acpi_debugfs_init();
 	acpi_sleep_proc_init();
 	acpi_wakeup_device_init();
-	acpi_aml_init();
+	acpi_debugger_init();
 	return 0;
 }
 
drivers/acpi/osl.c +201 -6

261 lines not on this page · raw message

include/linux/acpi.h +71 -0

83 lines not on this page · raw message

include/linux/acpi_dbg.h deleted +0 -52

52 lines not on this page · raw message

Signature · 1 line
1.7.10
author
#40 lore raw

v3 cover ACPICA / debugger: Add in-kernel AML debugger support

In reply to Lv Zheng

This patchset enables ACPICA debugger for Linux kernel and implements a userspace utility to access it.

A. Build the AML debugger
In order to build the kernel support of AML debugger, the following kconfig items should be enabled:
CONFIG_ACPI_DEBUG=y
CONFIG_ACPI_DEBUGGER=y
CONFIG_DEBUG_FS=y
CONFIG_ACPI_DEBUGGER_USER=m
The userspace tool can be found at tools/power/acpi/tools/acpidbg. To build this utility, staying in tools folder and type "make acpi".

B. Load the AML debugger during runtime
In order to use the in-kernel AML debugger, the following command should be executed using root user:

 # modprobe acpi_dbg
 # mount -t debugfs none /sys/kernel/debug
 # acpidbg

C. Batch mode
In order to support scripts, the userspace utility also supports single command batch mode:

 # acpidbg -b "help"
 # acpidbg -b "tables"
 # acpidbg -b "find _LID"
 # acpidbg -b "execute \_SB.LID0._LID"
You can find the documentation about the ACPICA debugger commands in:
 https://acpica.org/sites/acpica/files/acpica-reference_17.pdf
 (The latest document can be found at https://acpica.org/documentation)
And refer to the chapter - ACPICA debugger reference to obtain the full
description of the debugger commands. Note that not all commands are
supported by an in-kernel AML debugger.

D. Unload the AML debugger during runtime
After terminating all acpidbg instances, the following command can be executed to remove the AML debugger from kernel:

 # rmmod acpi_dbg

The following tasks are not completed:
1. .flush() support in the kernel debugger IO driver.
2. multi-commands batch mode.

v2:
1. Fix a help message issue for the userspace acpidbg utility (this is a typo fix).
2. Fix a batch mode issue by adding "\n" to the prompt sequence (this was lost due to too many rebase cycles).
3. Fix kconfig dependency for an intermediate patch (this is only useful in case the latter patches are reverted).
4. Add more accurate runtime debugger stub mechanism and remove old ACPI_DEBUGGER_EXEC() stub mechanism.
5. Add x86 acpi_os_readable() support.

v3:
1. Remove acpi_os_readable() support from this patchset. It's sent separately.
2. Delete some deprecated comments.

Colin Ian King (1):
ACPICA: Debugger: Remove unnecessary status check

Lv Zheng (5):
ACPICA: Debugger: Convert some mechanisms to OSPM specific
ACPICA: Debugger: Fix runtime stub issues of ACPI_DEBUGGER_EXEC using
different stub mechanism
ACPI / debugger: Add IO interface to access debugger functionalities tools/power/acpi: Add userspace AML interface support
ACPI / debugger: Add module support for ACPI debugger

 drivers/acpi/Kconfig                     |   13 +-
 drivers/acpi/Makefile                    |    1 +
 drivers/acpi/acpi_dbg.c                  |  805 ++++++++++++++++++++++++++++++
 drivers/acpi/acpica/acdebug.h            |   36 +-
 drivers/acpi/acpica/acglobal.h           |    5 -
 drivers/acpi/acpica/acmacros.h           |   11 -
 drivers/acpi/acpica/dbdisply.c           |   12 +
 drivers/acpi/acpica/dbinput.c            |  100 +---
 drivers/acpi/acpica/dbxface.c            |   93 ++--
 drivers/acpi/acpica/dscontrol.c          |   10 +-
 drivers/acpi/acpica/dsutils.c            |   16 +-
 drivers/acpi/acpica/dswexec.c            |   16 +-
 drivers/acpi/acpica/utmutex.c            |   17 -
 drivers/acpi/bus.c                       |    1 +
 drivers/acpi/osl.c                       |  250 +++++++++-
 include/acpi/acpiosxf.h                  |   18 +-
 include/acpi/acpixf.h                    |   34 ++
 include/acpi/platform/aclinux.h          |    2 +
 include/acpi/platform/aclinuxex.h        |    9 +
 include/linux/acpi.h                     |   71 +++
 tools/power/acpi/Makefile                |   16 +-
 tools/power/acpi/tools/acpidbg/Makefile  |   27 +
 tools/power/acpi/tools/acpidbg/acpidbg.c |  438 ++++++++++++++++
 23 files changed, 1792 insertions(+), 209 deletions(-)
 create mode 100644 drivers/acpi/acpi_dbg.c
 create mode 100644 tools/power/acpi/tools/acpidbg/Makefile
 create mode 100644 tools/power/acpi/tools/acpidbg/acpidbg.c
Signature · 1 line
1.7.10
author
#41 lore raw

PATCH v3 1/6 ACPICA: Debugger: Remove unnecessary status check

From: Colin Ian King <[email protected]>

ACPICA commit f9d5c6c9a25e9f5ac05458bfcd8b381e21bb2ba5

ACPICA BZ 1205. Colin Ian King.

---
 drivers/acpi/acpica/dbinput.c |    3 ---
 1 file changed, 3 deletions(-)
drivers/acpi/acpica/dbinput.c +0 -3
index 0480254..fe93f67 100644
@@ -1246,9 +1246,6 @@ acpi_status acpi_db_user_commands(char prompt, union acpi_parse_object *op)
 			 * and wait for the command to complete.
 			 */
 			acpi_os_release_mutex(acpi_gbl_db_command_ready);
-			if (ACPI_FAILURE(status)) {
-				return (status);
-			}
 
 			status =
 			    acpi_os_acquire_mutex(acpi_gbl_db_command_complete,
Signature · 1 line
1.7.10
author
#42 lore raw

PATCH v3 2/6 ACPICA: Debugger: Convert some mechanisms to OSPM specific

In reply to Lv Zheng

The following mechanisms are OSPM specific:
1. Redirect output destination to console: no file redirection will be needed by an in-kernel debugger, there is even no file can be accessed when the debugger is running in the kernel mode.
2. Output command prompts: programs other than acpiexec can have different prompt characters and the prompt characters may be implemented as a special character sequence to form a char device IO protocol.
3. Command ready/complete handshake: OSPM debugger may wait more conditions to implement OSPM specific semantics (for example, FIFO full/empty conditions for O_NONBLOCK or IO open/close conditions).
Leaving such OSPM specific stuffs in the ACPICA debugger core blocks Linux debugger IO driver implementation.

Several new OSL APIs are provided by this patch:
1. acpi_os_initialize_command_signals: initialize command handshake mechanism or any other OSPM specific stuffs.
2. acpi_os_terminate_command_signals: reversal of acpi_os_initialize_command_signals.
3. acpi_os_wait_command_ready: putting debugger task into wait state when a command is not ready. OSPMs can terminate command loop by returning AE_CTRL_TERMINATE from this API. Normally, wait_event() or wait_for_multiple_object() may be used to implement this API.
4. acpi_os_notify_command_complete: putting user task into running state when a command has been completed. OSPMs can terminate command loop by returning AE_CTRL_TERMINATE from this API. Normally, wake_up() or set_event() may be used to implement this API.
This patch also converts current command signaling implementation into a generic debugger layer (osgendbg.c) to be used by the existing OSPMs or acpiexec, in return, Linux can have chance to implement its own command handshake mechanism. This patch also implements acpiexec batch mode in a multi-threading mode comaptible style as a demo (this can be confirmed by configuring acpiexec into DEBUGGER_MULTI_THREADED mode where the batch mode is still working). Lv Zheng.

Note that the OSPM specific command handshake mechanism is required by Linux kernel because:
1. Linux kernel trends to use wait queue to synchronize two threads, using mutexes to achieve that will cause false "dead lock" warnings.
2. The command handshake mechanism implemented by ACPICA is implemented in this way because of a design issue in debugger IO streaming. Debugger IO outputs are simply cached using a giant buffer, this should be tuned by Linux in the future.

---
 drivers/acpi/acpica/acdebug.h     |    2 +-
 drivers/acpi/acpica/acglobal.h    |    5 --
 drivers/acpi/acpica/dbinput.c     |   97 ++++++++-----------------------------
 drivers/acpi/acpica/dbxface.c     |   63 +++++++-----------------
 drivers/acpi/acpica/utmutex.c     |   17 -------
 include/acpi/acpiosxf.h           |   18 ++++++-
 include/acpi/acpixf.h             |   11 +++++
 include/acpi/platform/aclinux.h   |    4 ++
 include/acpi/platform/aclinuxex.h |   19 ++++++++
 9 files changed, 89 insertions(+), 147 deletions(-)
drivers/acpi/acpica/acdebug.h +1 -1
index c928ba4..86474d8 100644
@@ -257,7 +257,7 @@ acpi_db_command_dispatch(char *input_buffer,
 
 void ACPI_SYSTEM_XFACE acpi_db_execute_thread(void *context);
 
-acpi_status acpi_db_user_commands(char prompt, union acpi_parse_object *op);
+acpi_status acpi_db_user_commands(void);
 
 char *acpi_db_get_next_token(char *string,
 			     char **next, acpi_object_type * return_type);
drivers/acpi/acpica/acglobal.h +0 -5
index faa9760..3977134 100644
@@ -326,7 +326,6 @@ ACPI_GLOBAL(struct acpi_external_file *, acpi_gbl_external_file_list);
 #ifdef ACPI_DEBUGGER
 
 ACPI_INIT_GLOBAL(u8, acpi_gbl_abort_method, FALSE);
-ACPI_INIT_GLOBAL(u8, acpi_gbl_method_executing, FALSE);
 ACPI_INIT_GLOBAL(acpi_thread_id, acpi_gbl_db_thread_id, ACPI_INVALID_THREAD_ID);
 
 ACPI_GLOBAL(u8, acpi_gbl_db_opt_no_ini_methods);
@@ -345,7 +344,6 @@ ACPI_GLOBAL(acpi_object_type, acpi_gbl_db_arg_types[ACPI_DEBUGGER_MAX_ARGS]);
 
 /* These buffers should all be the same size */
 
-ACPI_GLOBAL(char, acpi_gbl_db_line_buf[ACPI_DB_LINE_BUFFER_SIZE]);
 ACPI_GLOBAL(char, acpi_gbl_db_parsed_buf[ACPI_DB_LINE_BUFFER_SIZE]);
 ACPI_GLOBAL(char, acpi_gbl_db_scope_buf[ACPI_DB_LINE_BUFFER_SIZE]);
 ACPI_GLOBAL(char, acpi_gbl_db_debug_filename[ACPI_DB_LINE_BUFFER_SIZE]);
@@ -360,9 +358,6 @@ ACPI_GLOBAL(u16, acpi_gbl_node_type_count_misc);
 ACPI_GLOBAL(u32, acpi_gbl_num_nodes);
 ACPI_GLOBAL(u32, acpi_gbl_num_objects);
 
-ACPI_GLOBAL(acpi_mutex, acpi_gbl_db_command_ready);
-ACPI_GLOBAL(acpi_mutex, acpi_gbl_db_command_complete);
-
 #endif				/* ACPI_DEBUGGER */
 
 /*****************************************************************************
drivers/acpi/acpica/dbinput.c +19 -78

138 lines not on this page · raw message

drivers/acpi/acpica/dbxface.c +18 -45

98 lines not on this page · raw message

drivers/acpi/acpica/utmutex.c +0 -17
index ce406e3..ea0c207 100644
@@ -111,17 +111,6 @@ acpi_status acpi_ut_mutex_initialize(void)
 	if (ACPI_FAILURE(status)) {
 		return_ACPI_STATUS(status);
 	}
-#ifdef ACPI_DEBUGGER
-
-	/* Debugger Support */
-
-	status = acpi_os_create_mutex(&acpi_gbl_db_command_ready);
-	if (ACPI_FAILURE(status)) {
-		return_ACPI_STATUS(status);
-	}
-
-	status = acpi_os_create_mutex(&acpi_gbl_db_command_complete);
-#endif
 
 	return_ACPI_STATUS(status);
 }
@@ -162,12 +151,6 @@ void acpi_ut_mutex_terminate(void)
 	/* Delete the reader/writer lock */
 
 	acpi_ut_delete_rw_lock(&acpi_gbl_namespace_rw_lock);
-
-#ifdef ACPI_DEBUGGER
-	acpi_os_delete_mutex(acpi_gbl_db_command_ready);
-	acpi_os_delete_mutex(acpi_gbl_db_command_complete);
-#endif
-
 	return_VOID;
 }
 
include/acpi/acpiosxf.h +17 -1
index fbc2baf..0d824a2 100644
@@ -349,12 +349,28 @@ void acpi_os_redirect_output(void *destination);
 #endif
 
 /*
- * Debug input
+ * Debug IO
  */
 #ifndef ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_get_line
 acpi_status acpi_os_get_line(char *buffer, u32 buffer_length, u32 *bytes_read);
 #endif
 
+#ifndef ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_initialize_command_signals
+acpi_status acpi_os_initialize_command_signals(void);
+#endif
+
+#ifndef ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_terminate_command_signals
+void acpi_os_terminate_command_signals(void);
+#endif
+
+#ifndef ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_wait_command_ready
+acpi_status acpi_os_wait_command_ready(void);
+#endif
+
+#ifndef ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_notify_command_complete
+acpi_status acpi_os_notify_command_complete(void);
+#endif
+
 /*
  * Obtain ACPI table(s)
  */
include/acpi/acpixf.h +11 -0
index 3aaaa86..95ebae3 100644
@@ -264,6 +264,15 @@ ACPI_INIT_GLOBAL(u32, acpi_dbg_level, ACPI_DEBUG_DEFAULT);
 ACPI_INIT_GLOBAL(u32, acpi_dbg_layer, 0);
 
 /*
+ * Debugger command handshake globals. Host OSes need to access these
+ * variables to implement their own command handshake mechanism.
+ */
+#ifdef ACPI_DEBUGGER
+ACPI_INIT_GLOBAL(u8, acpi_gbl_method_executing, FALSE);
+ACPI_GLOBAL(char, acpi_gbl_db_line_buf[ACPI_DB_LINE_BUFFER_SIZE]);
+#endif
+
+/*
  * Other miscellaneous globals
  */
 ACPI_GLOBAL(struct acpi_table_fadt, acpi_gbl_FADT);
@@ -929,6 +938,8 @@ ACPI_EXTERNAL_RETURN_STATUS(acpi_status
 					       void **data,
 					       void (*callback)(void *)))
 
+void acpi_run_debugger(char *batch_buffer);
+
 void acpi_set_debugger_thread_id(acpi_thread_id thread_id);
 
 #endif				/* __ACXFACE_H__ */
include/acpi/platform/aclinux.h +4 -0
index 323e5da..69dbae6 100644
@@ -150,6 +150,10 @@
  */
 #define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_readable
 #define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_writable
+#define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_initialize_command_signals
+#define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_terminate_command_signals
+#define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_wait_command_ready
+#define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_notify_command_complete
 
 /*
  * OSL interfaces used by utilities
include/acpi/platform/aclinuxex.h +19 -0
index fd6d70f..673fdf4 100644
@@ -129,6 +129,25 @@ static inline u8 acpi_os_readable(void *pointer, acpi_size length)
 	return TRUE;
 }
 
+static inline acpi_status acpi_os_initialize_command_signals(void)
+{
+	return AE_OK;
+}
+
+static inline void acpi_os_terminate_command_signals(void)
+{
+}
+
+static inline acpi_status acpi_os_wait_command_ready(void)
+{
+	return AE_ERROR;
+}
+
+static inline acpi_status acpi_os_notify_command_complete(void)
+{
+	return AE_ERROR;
+}
+
 /*
  * OSL interfaces added by Linux
  */
Signature · 1 line
1.7.10
author
#43 lore raw

PATCH v3 3/6 ACPICA: Debugger: Fix runtime stub issues of ACPI_DEBUGGER_EXEC using different stub mechanism

In reply to Lv Zheng

The ACPI_DEBUGGER_EXEC is a problem now when the debugger code is compiled but runtime disabled. They actually will get executed in this situation. Although such executions are harmless if we can correctly make acpi_db_single_step() a runtime stub, users may still do not want to see the debugger print messages logged into OSPMs' kernel logs when a debugger driver is not loaded to enable the debugger during runtime.

This patch fixes this issue by introducing new stub mechanism instead of ACPI_DEBUGGER_EXEC. Lv Zheng.

---
 drivers/acpi/acpica/acdebug.h   |   34 ++++++++++++++++++++++++----------
 drivers/acpi/acpica/acmacros.h  |   11 -----------
 drivers/acpi/acpica/dbdisply.c  |   12 ++++++++++++
 drivers/acpi/acpica/dbxface.c   |   30 ++++++++++++++++++++++++++++++
 drivers/acpi/acpica/dscontrol.c |   10 ++--------
 drivers/acpi/acpica/dsutils.c   |   16 ++++++++--------
 drivers/acpi/acpica/dswexec.c   |   16 +++++++---------
 include/acpi/acpixf.h           |   23 +++++++++++++++++++++++
 8 files changed, 106 insertions(+), 46 deletions(-)
drivers/acpi/acpica/acdebug.h +24 -10
index 86474d8..dcaa15d 100644
@@ -80,9 +80,15 @@ struct acpi_db_execute_walk {
 /*
  * dbxface - external debugger interfaces
  */
-acpi_status
-acpi_db_single_step(struct acpi_walk_state *walk_state,
-		    union acpi_parse_object *op, u32 op_type);
+ACPI_DBR_DEPENDENT_RETURN_OK(acpi_status
+			     acpi_db_single_step(struct acpi_walk_state
+						 *walk_state,
+						 union acpi_parse_object *op,
+						 u32 op_type))
+ ACPI_DBR_DEPENDENT_RETURN_VOID(void
+				acpi_db_signal_break_point(struct
+							   acpi_walk_state
+							   *walk_state))
 
 /*
  * dbcmds - debug commands and output routines
@@ -182,11 +188,15 @@ void acpi_db_display_method_info(union acpi_parse_object *op);
 
 void acpi_db_decode_and_display_object(char *target, char *output_type);
 
-void
-acpi_db_display_result_object(union acpi_operand_object *obj_desc,
-			      struct acpi_walk_state *walk_state);
+ACPI_DBR_DEPENDENT_RETURN_VOID(void
+			       acpi_db_display_result_object(union
+							     acpi_operand_object
+							     *obj_desc,
+							     struct
+							     acpi_walk_state
+							     *walk_state))
 
-acpi_status acpi_db_display_all_methods(char *display_count_arg);
+ acpi_status acpi_db_display_all_methods(char *display_count_arg);
 
 void acpi_db_display_arguments(void);
 
@@ -198,9 +208,13 @@ void acpi_db_display_calling_tree(void);
 
 void acpi_db_display_object_type(char *object_arg);
 
-void
-acpi_db_display_argument_object(union acpi_operand_object *obj_desc,
-				struct acpi_walk_state *walk_state);
+ACPI_DBR_DEPENDENT_RETURN_VOID(void
+			       acpi_db_display_argument_object(union
+							       acpi_operand_object
+							       *obj_desc,
+							       struct
+							       acpi_walk_state
+							       *walk_state))
 
 /*
  * dbexec - debugger control method execution
drivers/acpi/acpica/acmacros.h +0 -11
index e85366c..bad5bca 100644
@@ -401,17 +401,6 @@
 #endif
 
 /*
- * Some code only gets executed when the debugger is built in.
- * Note that this is entirely independent of whether the
- * DEBUG_PRINT stuff (set by ACPI_DEBUG_OUTPUT) is on, or not.
- */
-#ifdef ACPI_DEBUGGER
-#define ACPI_DEBUGGER_EXEC(a)           a
-#else
-#define ACPI_DEBUGGER_EXEC(a)
-#endif
-
-/*
  * Macros used for ACPICA utilities only
  */
 
drivers/acpi/acpica/dbdisply.c +12 -0
index 672977e..c42ce8a 100644
@@ -679,6 +679,12 @@ acpi_db_display_result_object(union acpi_operand_object *obj_desc,
 			      struct acpi_walk_state *walk_state)
 {
 
+#ifndef ACPI_APPLICATION
+	if (acpi_gbl_db_thread_id != acpi_os_get_thread_id()) {
+		return;
+	}
+#endif
+
 	/* Only display if single stepping */
 
 	if (!acpi_gbl_cm_single_step) {
@@ -708,6 +714,12 @@ acpi_db_display_argument_object(union acpi_operand_object *obj_desc,
 				struct acpi_walk_state *walk_state)
 {
 
+#ifndef ACPI_APPLICATION
+	if (acpi_gbl_db_thread_id != acpi_os_get_thread_id()) {
+		return;
+	}
+#endif
+
 	if (!acpi_gbl_cm_single_step) {
 		return;
 	}
drivers/acpi/acpica/dbxface.c +30 -0
index d95e91f..d7ff58e 100644
@@ -119,6 +119,36 @@ error_exit:
 
 /*******************************************************************************
  *
+ * FUNCTION:    acpi_db_signal_break_point
+ *
+ * PARAMETERS:  walk_state      - Current walk
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Called for AML_BREAK_POINT_OP
+ *
+ ******************************************************************************/
+
+void acpi_db_signal_break_point(struct acpi_walk_state *walk_state)
+{
+
+#ifndef ACPI_APPLICATION
+	if (acpi_gbl_db_thread_id != acpi_os_get_thread_id()) {
+		return;
+	}
+#endif
+
+	/*
+	 * Set the single-step flag. This will cause the debugger (if present)
+	 * to break to the console within the AML debugger at the start of the
+	 * next AML instruction.
+	 */
+	acpi_gbl_cm_single_step = TRUE;
+	acpi_os_printf("**break** Executed AML BreakPoint opcode\n");
+}
+
+/*******************************************************************************
+ *
  * FUNCTION:    acpi_db_single_step
  *
  * PARAMETERS:  walk_state      - Current walk
drivers/acpi/acpica/dscontrol.c +2 -8
index 435fc16..06a6f7f 100644
@@ -47,6 +47,7 @@
 #include "amlcode.h"
 #include "acdispat.h"
 #include "acinterp.h"
+#include "acdebug.h"
 
 #define _COMPONENT          ACPI_DISPATCHER
 ACPI_MODULE_NAME("dscontrol")
@@ -348,14 +349,7 @@ acpi_ds_exec_end_control_op(struct acpi_walk_state * walk_state,
 
 	case AML_BREAK_POINT_OP:
 
-		/*
-		 * Set the single-step flag. This will cause the debugger (if present)
-		 * to break to the console within the AML debugger at the start of the
-		 * next AML instruction.
-		 */
-		ACPI_DEBUGGER_EXEC(acpi_gbl_cm_single_step = TRUE);
-		ACPI_DEBUGGER_EXEC(acpi_os_printf
-				   ("**break** Executed AML BreakPoint opcode\n"));
+		acpi_db_signal_break_point(walk_state);
 
 		/* Call to the OSL in case OS wants a piece of the action */
 
drivers/acpi/acpica/dsutils.c +8 -8
index ebc577b..e4293a8 100644
@@ -605,8 +605,8 @@ acpi_ds_create_operand(struct acpi_walk_state *walk_state,
 		if (ACPI_FAILURE(status)) {
 			return_ACPI_STATUS(status);
 		}
-		ACPI_DEBUGGER_EXEC(acpi_db_display_argument_object
-				   (obj_desc, walk_state));
+
+		acpi_db_display_argument_object(obj_desc, walk_state);
 	} else {
 		/* Check for null name case */
 
@@ -638,10 +638,11 @@ acpi_ds_create_operand(struct acpi_walk_state *walk_state,
 			ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
 					  "Argument previously created, already stacked\n"));
 
-			ACPI_DEBUGGER_EXEC(acpi_db_display_argument_object
-					   (walk_state->
-					    operands[walk_state->num_operands -
-						     1], walk_state));
+			acpi_db_display_argument_object(walk_state->
+							operands[walk_state->
+								 num_operands -
+								 1],
+							walk_state);
 
 			/*
 			 * Use value that was already previously returned
@@ -685,8 +686,7 @@ acpi_ds_create_operand(struct acpi_walk_state *walk_state,
 			return_ACPI_STATUS(status);
 		}
 
-		ACPI_DEBUGGER_EXEC(acpi_db_display_argument_object
-				   (obj_desc, walk_state));
+		acpi_db_display_argument_object(obj_desc, walk_state);
 	}
 
 	return_ACPI_STATUS(AE_OK);
drivers/acpi/acpica/dswexec.c +7 -9
index df54d46..9cc5761 100644
@@ -178,8 +178,7 @@ cleanup:
 
 	/* Break to debugger to display result */
 
-	ACPI_DEBUGGER_EXEC(acpi_db_display_result_object
-			   (local_obj_desc, walk_state));
+	acpi_db_display_result_object(local_obj_desc, walk_state);
 
 	/*
 	 * Delete the predicate result object (we know that
@@ -386,11 +385,10 @@ acpi_status acpi_ds_exec_end_op(struct acpi_walk_state *walk_state)
 
 	/* Call debugger for single step support (DEBUG build only) */
 
-	ACPI_DEBUGGER_EXEC(status =
-			   acpi_db_single_step(walk_state, op, op_class));
-	ACPI_DEBUGGER_EXEC(if (ACPI_FAILURE(status)) {
-			   return_ACPI_STATUS(status);}
-	) ;
+	status = acpi_db_single_step(walk_state, op, op_class);
+	if (ACPI_FAILURE(status)) {
+		return_ACPI_STATUS(status);
+	}
 
 	/* Decode the Opcode Class */
 
@@ -728,8 +726,8 @@ cleanup:
 
 		/* Break to debugger to display result */
 
-		ACPI_DEBUGGER_EXEC(acpi_db_display_result_object
-				   (walk_state->result_obj, walk_state));
+		acpi_db_display_result_object(walk_state->result_obj,
+					      walk_state);
 
 		/*
 		 * Delete the result op if and only if:
include/acpi/acpixf.h +23 -0
index 95ebae3..5dfab9c 100644
@@ -375,6 +375,29 @@ ACPI_GLOBAL(u8, acpi_gbl_system_awake_and_running);
 
 #endif				/* ACPI_APPLICATION */
 
+/*
+ * Debugger prototypes
+ *
+ * All interfaces used by debugger will be configured
+ * out of the ACPICA build unless the ACPI_DEBUGGER
+ * flag is defined.
+ */
+#ifdef ACPI_DEBUGGER
+#define ACPI_DBR_DEPENDENT_RETURN_OK(prototype) \
+	ACPI_EXTERNAL_RETURN_OK(prototype)
+
+#define ACPI_DBR_DEPENDENT_RETURN_VOID(prototype) \
+	ACPI_EXTERNAL_RETURN_VOID(prototype)
+
+#else
+#define ACPI_DBR_DEPENDENT_RETURN_OK(prototype) \
+	static ACPI_INLINE prototype {return(AE_OK);}
+
+#define ACPI_DBR_DEPENDENT_RETURN_VOID(prototype) \
+	static ACPI_INLINE prototype {return;}
+
+#endif				/* ACPI_DEBUGGER */
+
 /*****************************************************************************
  *
  * ACPICA public interface prototypes
Signature · 1 line
1.7.10
author
#44 lore raw

PATCH v3 4/6 ACPI / debugger: Add IO interface to access debugger functionalities

In reply to Lv Zheng

This patch adds /sys/kernel/debug/acpi/acpidbg, which can be used by userspace programs to access ACPICA debugger functionalities.

Known issue:
1. IO flush support
acpi_os_notify_command_complete() and acpi_os_wait_command_ready() can be used by acpi_dbg module to implement .flush() filesystem operation. While this patch doesn't go that far. It then becomes userspace tool's duty now to flush old commands before executing new batch mode commands.

---
 drivers/acpi/Kconfig              |    3 +-
 drivers/acpi/Makefile             |    1 +
 drivers/acpi/acpi_dbg.c           |  779 +++++++++++++++++++++++++++++++++++++
 drivers/acpi/bus.c                |    2 +
 drivers/acpi/osl.c                |   55 ++-
 include/acpi/platform/aclinux.h   |    2 -
 include/acpi/platform/aclinuxex.h |   10 -
 include/linux/acpi_dbg.h          |   52 +++
 8 files changed, 887 insertions(+), 17 deletions(-)
 create mode 100644 drivers/acpi/acpi_dbg.c
 create mode 100644 include/linux/acpi_dbg.h
drivers/acpi/Kconfig +2 -1
index 25dbb76..4de3517 100644
@@ -58,8 +58,9 @@ config ACPI_CCA_REQUIRED
 	bool
 
 config ACPI_DEBUGGER
-	bool "In-kernel debugger (EXPERIMENTAL)"
+	bool "In-kernel debugger"
 	select ACPI_DEBUG
+	depends on DEBUG_FS
 	help
 	  Enable in-kernel debugging facilities: statistics, internal
 	  object dump, single step control method execution.
drivers/acpi/Makefile +1 -0
index 675eaf3..102b5e6 100644
@@ -50,6 +50,7 @@ acpi-y				+= sysfs.o
 acpi-y				+= property.o
 acpi-$(CONFIG_X86)		+= acpi_cmos_rtc.o
 acpi-$(CONFIG_DEBUG_FS)		+= debugfs.o
+acpi-$(CONFIG_ACPI_DEBUGGER)	+= acpi_dbg.o
 acpi-$(CONFIG_ACPI_NUMA)	+= numa.o
 acpi-$(CONFIG_ACPI_PROCFS_POWER) += cm_sbs.o
 acpi-y				+= acpi_lpat.o
drivers/acpi/acpi_dbg.c new file +779 -0

779 lines not on this page · raw message

drivers/acpi/bus.c +2 -0
index a212cef..06fbba9 100644
@@ -37,6 +37,7 @@
 #include <acpi/apei.h>
 #include <linux/dmi.h>
 #include <linux/suspend.h>
+#include <linux/acpi_dbg.h>
 
 #include "internal.h"
 
@@ -1094,6 +1095,7 @@ static int __init acpi_init(void)
 	acpi_debugfs_init();
 	acpi_sleep_proc_init();
 	acpi_wakeup_device_init();
+	acpi_aml_init();
 	return 0;
 }
 
drivers/acpi/osl.c +51 -4

105 lines not on this page · raw message

include/acpi/platform/aclinux.h +0 -2
index 69dbae6..e21857d 100644
@@ -152,8 +152,6 @@
 #define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_writable
 #define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_initialize_command_signals
 #define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_terminate_command_signals
-#define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_wait_command_ready
-#define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_notify_command_complete
 
 /*
  * OSL interfaces used by utilities
include/acpi/platform/aclinuxex.h +0 -10
index 673fdf4..ceea026 100644
@@ -138,16 +138,6 @@ static inline void acpi_os_terminate_command_signals(void)
 {
 }
 
-static inline acpi_status acpi_os_wait_command_ready(void)
-{
-	return AE_ERROR;
-}
-
-static inline acpi_status acpi_os_notify_command_complete(void)
-{
-	return AE_ERROR;
-}
-
 /*
  * OSL interfaces added by Linux
  */
include/linux/acpi_dbg.h new file +52 -0

52 lines not on this page · raw message

Signature · 1 line
1.7.10
author
#45 lore raw

PATCH v3 5/6 tools/power/acpi: Add userspace AML interface support

In reply to Lv Zheng

This patch adds a userspace tool to access Linux kernel AML debugger interface.

Tow modes are supported by this tool:
1. Interactive: Users are able to launch a debugging shell to talk with in-kernel AML debugger.
Note that it's user duty to ensure kernel runtime integrity by using this debugging tool:
A. Some control methods evaluated by the users may result in kernel
panics if those control methods shouldn't be evaluated by the OSPMs according to the current BIOS/OS configurations.
B. Currently if a single stepping evaluation couldn't run to an end,
then the synchronization primitives acquired by the evaluation may block normal OSPM control method evaluations.
2. Batch: Users are able to execute debugger commands in a script. Note that in addition to the above duties, it's user duty to ensure script runtime integrity by using this debugging tool in this mode:
C. Currently only those commands that are not used for single stepping
are suitable to be used in this mode.
D. If the execution of the command may cause a failure that could result
in an endless kernel execution, the execution of the script may also get blocked.
To exit the utility, currently "exit/quit" commands are recommended, but ctrl-C" can also be used.

---
 tools/power/acpi/Makefile                |   16 +-
 tools/power/acpi/tools/acpidbg/Makefile  |   27 ++
 tools/power/acpi/tools/acpidbg/acpidbg.c |  438 ++++++++++++++++++++++++++++++
 3 files changed, 473 insertions(+), 8 deletions(-)
 create mode 100644 tools/power/acpi/tools/acpidbg/Makefile
 create mode 100644 tools/power/acpi/tools/acpidbg/acpidbg.c
tools/power/acpi/Makefile +8 -8
index e882c83..a8bf908 100644
@@ -10,18 +10,18 @@
 
 include ../../scripts/Makefile.include
 
-all: acpidump ec
-clean: acpidump_clean ec_clean
-install: acpidump_install ec_install
-uninstall: acpidump_uninstall ec_uninstall
+all: acpidbg acpidump ec
+clean: acpidbg_clean acpidump_clean ec_clean
+install: acpidbg_install acpidump_install ec_install
+uninstall: acpidbg_uninstall acpidump_uninstall ec_uninstall
 
-acpidump ec: FORCE
+acpidbg acpidump ec: FORCE
 	$(call descend,tools/$@,all)
-acpidump_clean ec_clean:
+acpidbg_clean acpidump_clean ec_clean:
 	$(call descend,tools/$(@:_clean=),clean)
-acpidump_install ec_install:
+acpidbg_install acpidump_install ec_install:
 	$(call descend,tools/$(@:_install=),install)
-acpidump_uninstall ec_uninstall:
+acpidbg_uninstall acpidump_uninstall ec_uninstall:
 	$(call descend,tools/$(@:_uninstall=),uninstall)
 
 .PHONY: FORCE
tools/power/acpi/tools/acpidbg/Makefile new file +27 -0
new file mode 100644
index 0000000..352df4b
@@ -0,0 +1,27 @@
+# tools/power/acpi/tools/acpidbg/Makefile - ACPI tool Makefile
+#
+# Copyright (c) 2015, Intel Corporation
+#   Author: Lv Zheng <[email protected]>
+#
+# 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; version 2
+# of the License.
+
+include ../../Makefile.config
+
+TOOL = acpidbg
+vpath %.c \
+	../../../../../drivers/acpi/acpica\
+	../../common\
+	../../os_specific/service_layers\
+	.
+CFLAGS += -DACPI_APPLICATION -DACPI_SINGLE_THREAD -DACPI_DEBUGGER\
+	-I.\
+	-I../../../../../drivers/acpi/acpica\
+	-I../../../../../include
+LDFLAGS += -lpthread
+TOOL_OBJS = \
+	acpidbg.o
+
+include ../../Makefile.rules
tools/power/acpi/tools/acpidbg/acpidbg.c new file +438 -0

438 lines not on this page · raw message

Signature · 1 line
1.7.10
author
#46 lore raw

PATCH v3 6/6 ACPI / debugger: Add module support for ACPI debugger

In reply to Lv Zheng

This patch converts AML debugger into a loadable module.

Note that, it implements driver unloading at the level dependent on the module reference count. Which means if ACPI debugger is being used by a userspace program, "rmmod acpi_dbg" should result in failure.

---
 drivers/acpi/Kconfig     |   12 ++-
 drivers/acpi/Makefile    |    2 +-
 drivers/acpi/acpi_dbg.c  |   80 ++++++++++++------
 drivers/acpi/bus.c       |    3 +-
 drivers/acpi/osl.c       |  207 ++++++++++++++++++++++++++++++++++++++++++++--
 include/linux/acpi.h     |   71 ++++++++++++++++
 include/linux/acpi_dbg.h |   52 ------------
 7 files changed, 338 insertions(+), 89 deletions(-)
 delete mode 100644 include/linux/acpi_dbg.h
drivers/acpi/Kconfig +11 -1
index 4de3517..c4d4a05 100644
@@ -60,13 +60,23 @@ config ACPI_CCA_REQUIRED
 config ACPI_DEBUGGER
 	bool "In-kernel debugger"
 	select ACPI_DEBUG
-	depends on DEBUG_FS
 	help
 	  Enable in-kernel debugging facilities: statistics, internal
 	  object dump, single step control method execution.
 	  This is still under development, currently enabling this only
 	  results in the compilation of the ACPICA debugger files.
 
+if ACPI_DEBUGGER
+
+config ACPI_DEBUGGER_USER
+	tristate "Userspace debugger accessiblity"
+	depends on DEBUG_FS
+	help
+	  Export /sys/kernel/debug/acpi/acpidbg for userspace utilities
+	  to access the debugger functionalities.
+
+endif
+
 config ACPI_SLEEP
 	bool
 	depends on SUSPEND || HIBERNATION
drivers/acpi/Makefile +1 -1
index 102b5e6..c6f236f 100644
@@ -50,7 +50,6 @@ acpi-y				+= sysfs.o
 acpi-y				+= property.o
 acpi-$(CONFIG_X86)		+= acpi_cmos_rtc.o
 acpi-$(CONFIG_DEBUG_FS)		+= debugfs.o
-acpi-$(CONFIG_ACPI_DEBUGGER)	+= acpi_dbg.o
 acpi-$(CONFIG_ACPI_NUMA)	+= numa.o
 acpi-$(CONFIG_ACPI_PROCFS_POWER) += cm_sbs.o
 acpi-y				+= acpi_lpat.o
@@ -80,6 +79,7 @@ obj-$(CONFIG_ACPI_EC_DEBUGFS)	+= ec_sys.o
 obj-$(CONFIG_ACPI_CUSTOM_METHOD)+= custom_method.o
 obj-$(CONFIG_ACPI_BGRT)		+= bgrt.o
 obj-$(CONFIG_ACPI_CPPC_LIB)	+= cppc_acpi.o
+obj-$(CONFIG_ACPI_DEBUGGER_USER) += acpi_dbg.o
 
 # processor has its own "processor." module_param namespace
 processor-y			:= processor_driver.o
drivers/acpi/acpi_dbg.c +53 -27

156 lines not on this page · raw message

drivers/acpi/bus.c +1 -2
index 06fbba9..1a40111 100644
@@ -37,7 +37,6 @@
 #include <acpi/apei.h>
 #include <linux/dmi.h>
 #include <linux/suspend.h>
-#include <linux/acpi_dbg.h>
 
 #include "internal.h"
 
@@ -1095,7 +1094,7 @@ static int __init acpi_init(void)
 	acpi_debugfs_init();
 	acpi_sleep_proc_init();
 	acpi_wakeup_device_init();
-	acpi_aml_init();
+	acpi_debugger_init();
 	return 0;
 }
 
drivers/acpi/osl.c +201 -6

260 lines not on this page · raw message

include/linux/acpi.h +71 -0

83 lines not on this page · raw message

include/linux/acpi_dbg.h deleted +0 -52

52 lines not on this page · raw message

Signature · 1 line
1.7.10
author
#47 lore raw

PATCH v3 1/1 ACPI / x86: introduce acpi_os_readable() support

In reply to Lv Zheng

From: Chen Yu <[email protected]>

This patch implements acpi_os_readable(). The function is used by ACPICA AML debugger to validate user specified pointers for dumping the memory as ACPICA descriptor objects.

---
 arch/x86/Kconfig                  |    1 +
 arch/x86/include/asm/acenv.h      |    1 +
 arch/x86/kernel/acpi/boot.c       |   44 +++++++++++++++++++++++++++++++++++++
 drivers/acpi/Kconfig              |    3 +++
 drivers/acpi/osl.c                |   12 ++++++++++
 include/acpi/platform/aclinux.h   |    1 -
 include/acpi/platform/aclinuxex.h |    5 -----
 7 files changed, 61 insertions(+), 6 deletions(-)
arch/x86/Kconfig +1 -0
index 96d058a..25585ee 100644
@@ -19,6 +19,7 @@ config X86
 	def_bool y
 	select ACPI_LEGACY_TABLES_LOOKUP	if ACPI
 	select ACPI_SYSTEM_POWER_STATES_SUPPORT	if ACPI
+	select ACPI_MEMORY_ACCESS_CHECK_SUPPORT	if ACPI
 	select ANON_INODES
 	select ARCH_CLOCKSOURCE_DATA
 	select ARCH_DISCARD_MEMBLOCK
arch/x86/include/asm/acenv.h +1 -0
index 1b010a8..a2a2849 100644
@@ -20,6 +20,7 @@
 
 int __acpi_acquire_global_lock(unsigned int *lock);
 int __acpi_release_global_lock(unsigned int *lock);
+bool __acpi_memory_readable(void *pointer, size_t length);
 
 #define ACPI_ACQUIRE_GLOBAL_LOCK(facs, Acq) \
 	((Acq) = __acpi_acquire_global_lock(&facs->global_lock))
arch/x86/kernel/acpi/boot.c +44 -0

50 lines not on this page · raw message

drivers/acpi/Kconfig +3 -0
index c4d4a05..73b45f9 100644
@@ -57,6 +57,9 @@ config ACPI_SYSTEM_POWER_STATES_SUPPORT
 config ACPI_CCA_REQUIRED
 	bool
 
+config ACPI_MEMORY_ACCESS_CHECK_SUPPORT
+	bool
+
 config ACPI_DEBUGGER
 	bool "In-kernel debugger"
 	select ACPI_DEBUG
drivers/acpi/osl.c +12 -0
index ce5ac00..edec035 100644
@@ -1582,6 +1582,18 @@ acpi_status acpi_os_get_line(char *buffer, u32 buffer_length, u32 *bytes_read)
 }
 EXPORT_SYMBOL(acpi_os_get_line);
 
+#ifdef CONFIG_ACPI_MEMORY_ACCESS_CHECK_SUPPORT
+u8 acpi_os_readable(void *pointer, acpi_size length)
+{
+	return __acpi_memory_readable(pointer, length) ? TRUE : FALSE;
+}
+#else
+u8 acpi_os_readable(void *pointer, acpi_size length)
+{
+	return TRUE;
+}
+#endif
+
 acpi_status acpi_os_wait_command_ready(void)
 {
 	int ret;
include/acpi/platform/aclinux.h +0 -1
index e21857d..b3c493e 100644
@@ -148,7 +148,6 @@
 /*
  * OSL interfaces used by debugger/disassembler
  */
-#define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_readable
 #define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_writable
 #define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_initialize_command_signals
 #define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_terminate_command_signals
include/acpi/platform/aclinuxex.h +0 -5
index ceea026..94bead6 100644
@@ -124,11 +124,6 @@ static inline acpi_thread_id acpi_os_get_thread_id(void)
 		lock ? AE_OK : AE_NO_MEMORY; \
 	})
 
-static inline u8 acpi_os_readable(void *pointer, acpi_size length)
-{
-	return TRUE;
-}
-
 static inline acpi_status acpi_os_initialize_command_signals(void)
 {
 	return AE_OK;
Signature · 1 line
1.7.10
author
#48 lore raw

v4 cover ACPICA / debugger: Add in-kernel AML debugger support

In reply to Lv Zheng

This patchset enables ACPICA debugger for Linux kernel and implements a userspace utility to access it.

A. Build the AML debugger
In order to build the kernel support of AML debugger, the following kconfig items should be enabled:
CONFIG_ACPI_DEBUG=y
CONFIG_ACPI_DEBUGGER=y
CONFIG_DEBUG_FS=y
CONFIG_ACPI_DEBUGGER_USER=m
The userspace tool can be found at tools/power/acpi/tools/acpidbg. To build this utility, staying in tools folder and type "make acpi".

B. Load the AML debugger during runtime
In order to use the in-kernel AML debugger, the following command should be executed using root user:

 # modprobe acpi_dbg
 # mount -t debugfs none /sys/kernel/debug
 # acpidbg

C. Batch mode
In order to support scripts, the userspace utility also supports single command batch mode:

 # acpidbg -b "help"
 # acpidbg -b "tables"
 # acpidbg -b "find _LID"
 # acpidbg -b "execute \_SB.LID0._LID"
You can find the documentation about the ACPICA debugger commands in:
 https://acpica.org/sites/acpica/files/acpica-reference_17.pdf
 (The latest document can be found at https://acpica.org/documentation)
And refer to the chapter - ACPICA debugger reference to obtain the full
description of the debugger commands. Note that not all commands are
supported by an in-kernel AML debugger.

D. Unload the AML debugger during runtime
After terminating all acpidbg instances, the following command can be executed to remove the AML debugger from kernel:

 # rmmod acpi_dbg

The following tasks are not completed:
1. .flush() support in the kernel debugger IO driver.
2. multi-commands batch mode.

v2:
1. Fix a help message issue for the userspace acpidbg utility (this is a typo fix).
2. Fix a batch mode issue by adding "\n" to the prompt sequence (this was lost due to too many rebase cycles).
3. Fix kconfig dependency for an intermediate patch (this is only useful in case the latter patches are reverted).
4. Add more accurate runtime debugger stub mechanism and remove old ACPI_DEBUGGER_EXEC() stub mechanism.
5. Add x86 acpi_os_readable() support.

v3:
1. Remove acpi_os_readable() support from this patchset. It's sent separately.
2. Delete some deprecated comments.

v4:
1. Rebase patch 4/6 because of Kconfig changes.
2. Include acpi_os_readable() back as no objections, also test result is positive.

Chen Yu (1):
ACPI / x86: introduce acpi_os_readable() support

Colin Ian King (1):
ACPICA: Debugger: Remove unnecessary status check

Lv Zheng (5):
ACPICA: Debugger: Convert some mechanisms to OSPM specific
ACPICA: Debugger: Fix runtime stub issues of ACPI_DEBUGGER_EXEC using
different stub mechanism
ACPI / debugger: Add IO interface to access debugger functionalities tools/power/acpi: Add userspace AML interface support
ACPI / debugger: Add module support for ACPI debugger

 arch/x86/Kconfig                         |    1 +
 arch/x86/include/asm/acenv.h             |    1 +
 arch/x86/kernel/acpi/boot.c              |   44 ++
 drivers/acpi/Kconfig                     |   20 +-
 drivers/acpi/Makefile                    |    1 +
 drivers/acpi/acpi_dbg.c                  |  805 ++++++++++++++++++++++++++++++
 drivers/acpi/acpica/acdebug.h            |   36 +-
 drivers/acpi/acpica/acglobal.h           |    5 -
 drivers/acpi/acpica/acmacros.h           |   11 -
 drivers/acpi/acpica/dbdisply.c           |   12 +
 drivers/acpi/acpica/dbinput.c            |  100 +---
 drivers/acpi/acpica/dbxface.c            |   93 ++--
 drivers/acpi/acpica/dscontrol.c          |   10 +-
 drivers/acpi/acpica/dsutils.c            |   16 +-
 drivers/acpi/acpica/dswexec.c            |   16 +-
 drivers/acpi/acpica/utmutex.c            |   17 -
 drivers/acpi/bus.c                       |    1 +
 drivers/acpi/osl.c                       |  262 +++++++++-
 include/acpi/acpiosxf.h                  |   18 +-
 include/acpi/acpixf.h                    |   34 ++
 include/acpi/platform/aclinux.h          |    3 +-
 include/acpi/platform/aclinuxex.h        |    8 +-
 include/linux/acpi.h                     |   71 +++
 tools/power/acpi/Makefile                |   16 +-
 tools/power/acpi/tools/acpidbg/Makefile  |   27 +
 tools/power/acpi/tools/acpidbg/acpidbg.c |  438 ++++++++++++++++
 26 files changed, 1852 insertions(+), 214 deletions(-)
 create mode 100644 drivers/acpi/acpi_dbg.c
 create mode 100644 tools/power/acpi/tools/acpidbg/Makefile
 create mode 100644 tools/power/acpi/tools/acpidbg/acpidbg.c
Signature · 1 line
1.7.10
author
#49 lore raw

PATCH v4 1/7 ACPICA: Debugger: Remove unnecessary status check

From: Colin Ian King <[email protected]>

ACPICA commit f9d5c6c9a25e9f5ac05458bfcd8b381e21bb2ba5

ACPICA BZ 1205. Colin Ian King.

---
 drivers/acpi/acpica/dbinput.c |    3 ---
 1 file changed, 3 deletions(-)
drivers/acpi/acpica/dbinput.c +0 -3
index 0480254..fe93f67 100644
@@ -1246,9 +1246,6 @@ acpi_status acpi_db_user_commands(char prompt, union acpi_parse_object *op)
 			 * and wait for the command to complete.
 			 */
 			acpi_os_release_mutex(acpi_gbl_db_command_ready);
-			if (ACPI_FAILURE(status)) {
-				return (status);
-			}
 
 			status =
 			    acpi_os_acquire_mutex(acpi_gbl_db_command_complete,
Signature · 1 line
1.7.10
author
#50 lore raw

PATCH v4 2/7 ACPICA: Debugger: Convert some mechanisms to OSPM specific

In reply to Lv Zheng

The following mechanisms are OSPM specific:
1. Redirect output destination to console: no file redirection will be needed by an in-kernel debugger, there is even no file can be accessed when the debugger is running in the kernel mode.
2. Output command prompts: programs other than acpiexec can have different prompt characters and the prompt characters may be implemented as a special character sequence to form a char device IO protocol.
3. Command ready/complete handshake: OSPM debugger may wait more conditions to implement OSPM specific semantics (for example, FIFO full/empty conditions for O_NONBLOCK or IO open/close conditions).
Leaving such OSPM specific stuffs in the ACPICA debugger core blocks Linux debugger IO driver implementation.

Several new OSL APIs are provided by this patch:
1. acpi_os_initialize_command_signals: initialize command handshake mechanism or any other OSPM specific stuffs.
2. acpi_os_terminate_command_signals: reversal of acpi_os_initialize_command_signals.
3. acpi_os_wait_command_ready: putting debugger task into wait state when a command is not ready. OSPMs can terminate command loop by returning AE_CTRL_TERMINATE from this API. Normally, wait_event() or wait_for_multiple_object() may be used to implement this API.
4. acpi_os_notify_command_complete: putting user task into running state when a command has been completed. OSPMs can terminate command loop by returning AE_CTRL_TERMINATE from this API. Normally, wake_up() or set_event() may be used to implement this API.
This patch also converts current command signaling implementation into a generic debugger layer (osgendbg.c) to be used by the existing OSPMs or acpiexec, in return, Linux can have chance to implement its own command handshake mechanism. This patch also implements acpiexec batch mode in a multi-threading mode comaptible style as a demo (this can be confirmed by configuring acpiexec into DEBUGGER_MULTI_THREADED mode where the batch mode is still working). Lv Zheng.

Note that the OSPM specific command handshake mechanism is required by Linux kernel because:
1. Linux kernel trends to use wait queue to synchronize two threads, using mutexes to achieve that will cause false "dead lock" warnings.
2. The command handshake mechanism implemented by ACPICA is implemented in this way because of a design issue in debugger IO streaming. Debugger IO outputs are simply cached using a giant buffer, this should be tuned by Linux in the future.

---
 drivers/acpi/acpica/acdebug.h     |    2 +-
 drivers/acpi/acpica/acglobal.h    |    5 --
 drivers/acpi/acpica/dbinput.c     |   97 ++++++++-----------------------------
 drivers/acpi/acpica/dbxface.c     |   63 +++++++-----------------
 drivers/acpi/acpica/utmutex.c     |   17 -------
 include/acpi/acpiosxf.h           |   18 ++++++-
 include/acpi/acpixf.h             |   11 +++++
 include/acpi/platform/aclinux.h   |    4 ++
 include/acpi/platform/aclinuxex.h |   19 ++++++++
 9 files changed, 89 insertions(+), 147 deletions(-)
drivers/acpi/acpica/acdebug.h +1 -1
index c928ba4..86474d8 100644
@@ -257,7 +257,7 @@ acpi_db_command_dispatch(char *input_buffer,
 
 void ACPI_SYSTEM_XFACE acpi_db_execute_thread(void *context);
 
-acpi_status acpi_db_user_commands(char prompt, union acpi_parse_object *op);
+acpi_status acpi_db_user_commands(void);
 
 char *acpi_db_get_next_token(char *string,
 			     char **next, acpi_object_type * return_type);
drivers/acpi/acpica/acglobal.h +0 -5
index faa9760..3977134 100644
@@ -326,7 +326,6 @@ ACPI_GLOBAL(struct acpi_external_file *, acpi_gbl_external_file_list);
 #ifdef ACPI_DEBUGGER
 
 ACPI_INIT_GLOBAL(u8, acpi_gbl_abort_method, FALSE);
-ACPI_INIT_GLOBAL(u8, acpi_gbl_method_executing, FALSE);
 ACPI_INIT_GLOBAL(acpi_thread_id, acpi_gbl_db_thread_id, ACPI_INVALID_THREAD_ID);
 
 ACPI_GLOBAL(u8, acpi_gbl_db_opt_no_ini_methods);
@@ -345,7 +344,6 @@ ACPI_GLOBAL(acpi_object_type, acpi_gbl_db_arg_types[ACPI_DEBUGGER_MAX_ARGS]);
 
 /* These buffers should all be the same size */
 
-ACPI_GLOBAL(char, acpi_gbl_db_line_buf[ACPI_DB_LINE_BUFFER_SIZE]);
 ACPI_GLOBAL(char, acpi_gbl_db_parsed_buf[ACPI_DB_LINE_BUFFER_SIZE]);
 ACPI_GLOBAL(char, acpi_gbl_db_scope_buf[ACPI_DB_LINE_BUFFER_SIZE]);
 ACPI_GLOBAL(char, acpi_gbl_db_debug_filename[ACPI_DB_LINE_BUFFER_SIZE]);
@@ -360,9 +358,6 @@ ACPI_GLOBAL(u16, acpi_gbl_node_type_count_misc);
 ACPI_GLOBAL(u32, acpi_gbl_num_nodes);
 ACPI_GLOBAL(u32, acpi_gbl_num_objects);
 
-ACPI_GLOBAL(acpi_mutex, acpi_gbl_db_command_ready);
-ACPI_GLOBAL(acpi_mutex, acpi_gbl_db_command_complete);
-
 #endif				/* ACPI_DEBUGGER */
 
 /*****************************************************************************
drivers/acpi/acpica/dbinput.c +19 -78

138 lines not on this page · raw message

drivers/acpi/acpica/dbxface.c +18 -45

98 lines not on this page · raw message

drivers/acpi/acpica/utmutex.c +0 -17
index ce406e3..ea0c207 100644
@@ -111,17 +111,6 @@ acpi_status acpi_ut_mutex_initialize(void)
 	if (ACPI_FAILURE(status)) {
 		return_ACPI_STATUS(status);
 	}
-#ifdef ACPI_DEBUGGER
-
-	/* Debugger Support */
-
-	status = acpi_os_create_mutex(&acpi_gbl_db_command_ready);
-	if (ACPI_FAILURE(status)) {
-		return_ACPI_STATUS(status);
-	}
-
-	status = acpi_os_create_mutex(&acpi_gbl_db_command_complete);
-#endif
 
 	return_ACPI_STATUS(status);
 }
@@ -162,12 +151,6 @@ void acpi_ut_mutex_terminate(void)
 	/* Delete the reader/writer lock */
 
 	acpi_ut_delete_rw_lock(&acpi_gbl_namespace_rw_lock);
-
-#ifdef ACPI_DEBUGGER
-	acpi_os_delete_mutex(acpi_gbl_db_command_ready);
-	acpi_os_delete_mutex(acpi_gbl_db_command_complete);
-#endif
-
 	return_VOID;
 }
 
include/acpi/acpiosxf.h +17 -1
index fbc2baf..0d824a2 100644
@@ -349,12 +349,28 @@ void acpi_os_redirect_output(void *destination);
 #endif
 
 /*
- * Debug input
+ * Debug IO
  */
 #ifndef ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_get_line
 acpi_status acpi_os_get_line(char *buffer, u32 buffer_length, u32 *bytes_read);
 #endif
 
+#ifndef ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_initialize_command_signals
+acpi_status acpi_os_initialize_command_signals(void);
+#endif
+
+#ifndef ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_terminate_command_signals
+void acpi_os_terminate_command_signals(void);
+#endif
+
+#ifndef ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_wait_command_ready
+acpi_status acpi_os_wait_command_ready(void);
+#endif
+
+#ifndef ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_notify_command_complete
+acpi_status acpi_os_notify_command_complete(void);
+#endif
+
 /*
  * Obtain ACPI table(s)
  */
include/acpi/acpixf.h +11 -0
index 3aaaa86..95ebae3 100644
@@ -264,6 +264,15 @@ ACPI_INIT_GLOBAL(u32, acpi_dbg_level, ACPI_DEBUG_DEFAULT);
 ACPI_INIT_GLOBAL(u32, acpi_dbg_layer, 0);
 
 /*
+ * Debugger command handshake globals. Host OSes need to access these
+ * variables to implement their own command handshake mechanism.
+ */
+#ifdef ACPI_DEBUGGER
+ACPI_INIT_GLOBAL(u8, acpi_gbl_method_executing, FALSE);
+ACPI_GLOBAL(char, acpi_gbl_db_line_buf[ACPI_DB_LINE_BUFFER_SIZE]);
+#endif
+
+/*
  * Other miscellaneous globals
  */
 ACPI_GLOBAL(struct acpi_table_fadt, acpi_gbl_FADT);
@@ -929,6 +938,8 @@ ACPI_EXTERNAL_RETURN_STATUS(acpi_status
 					       void **data,
 					       void (*callback)(void *)))
 
+void acpi_run_debugger(char *batch_buffer);
+
 void acpi_set_debugger_thread_id(acpi_thread_id thread_id);
 
 #endif				/* __ACXFACE_H__ */
include/acpi/platform/aclinux.h +4 -0
index 323e5da..69dbae6 100644
@@ -150,6 +150,10 @@
  */
 #define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_readable
 #define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_writable
+#define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_initialize_command_signals
+#define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_terminate_command_signals
+#define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_wait_command_ready
+#define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_notify_command_complete
 
 /*
  * OSL interfaces used by utilities
include/acpi/platform/aclinuxex.h +19 -0
index fd6d70f..673fdf4 100644
@@ -129,6 +129,25 @@ static inline u8 acpi_os_readable(void *pointer, acpi_size length)
 	return TRUE;
 }
 
+static inline acpi_status acpi_os_initialize_command_signals(void)
+{
+	return AE_OK;
+}
+
+static inline void acpi_os_terminate_command_signals(void)
+{
+}
+
+static inline acpi_status acpi_os_wait_command_ready(void)
+{
+	return AE_ERROR;
+}
+
+static inline acpi_status acpi_os_notify_command_complete(void)
+{
+	return AE_ERROR;
+}
+
 /*
  * OSL interfaces added by Linux
  */
Signature · 1 line
1.7.10
author
#51 lore raw

PATCH v4 3/7 ACPICA: Debugger: Fix runtime stub issues of ACPI_DEBUGGER_EXEC using different stub mechanism

In reply to Lv Zheng

ACPICA commit 11522d6b894054fc4d62dd4f9863ec151296b386

The ACPI_DEBUGGER_EXEC is a problem now when the debugger code is compiled but runtime disabled. They actually will get executed in this situation. Although such executions are harmless if we can correctly make acpi_db_single_step() a runtime stub, users may still do not want to see the debugger print messages logged into OSPMs' kernel logs when a debugger driver is not loaded to enable the debugger during runtime.

This patch fixes this issue by introducing new stub mechanism instead of ACPI_DEBUGGER_EXEC. Lv Zheng.

---
 drivers/acpi/acpica/acdebug.h   |   34 ++++++++++++++++++++++++----------
 drivers/acpi/acpica/acmacros.h  |   11 -----------
 drivers/acpi/acpica/dbdisply.c  |   12 ++++++++++++
 drivers/acpi/acpica/dbxface.c   |   30 ++++++++++++++++++++++++++++++
 drivers/acpi/acpica/dscontrol.c |   10 ++--------
 drivers/acpi/acpica/dsutils.c   |   16 ++++++++--------
 drivers/acpi/acpica/dswexec.c   |   16 +++++++---------
 include/acpi/acpixf.h           |   23 +++++++++++++++++++++++
 8 files changed, 106 insertions(+), 46 deletions(-)
drivers/acpi/acpica/acdebug.h +24 -10
index 86474d8..dcaa15d 100644
@@ -80,9 +80,15 @@ struct acpi_db_execute_walk {
 /*
  * dbxface - external debugger interfaces
  */
-acpi_status
-acpi_db_single_step(struct acpi_walk_state *walk_state,
-		    union acpi_parse_object *op, u32 op_type);
+ACPI_DBR_DEPENDENT_RETURN_OK(acpi_status
+			     acpi_db_single_step(struct acpi_walk_state
+						 *walk_state,
+						 union acpi_parse_object *op,
+						 u32 op_type))
+ ACPI_DBR_DEPENDENT_RETURN_VOID(void
+				acpi_db_signal_break_point(struct
+							   acpi_walk_state
+							   *walk_state))
 
 /*
  * dbcmds - debug commands and output routines
@@ -182,11 +188,15 @@ void acpi_db_display_method_info(union acpi_parse_object *op);
 
 void acpi_db_decode_and_display_object(char *target, char *output_type);
 
-void
-acpi_db_display_result_object(union acpi_operand_object *obj_desc,
-			      struct acpi_walk_state *walk_state);
+ACPI_DBR_DEPENDENT_RETURN_VOID(void
+			       acpi_db_display_result_object(union
+							     acpi_operand_object
+							     *obj_desc,
+							     struct
+							     acpi_walk_state
+							     *walk_state))
 
-acpi_status acpi_db_display_all_methods(char *display_count_arg);
+ acpi_status acpi_db_display_all_methods(char *display_count_arg);
 
 void acpi_db_display_arguments(void);
 
@@ -198,9 +208,13 @@ void acpi_db_display_calling_tree(void);
 
 void acpi_db_display_object_type(char *object_arg);
 
-void
-acpi_db_display_argument_object(union acpi_operand_object *obj_desc,
-				struct acpi_walk_state *walk_state);
+ACPI_DBR_DEPENDENT_RETURN_VOID(void
+			       acpi_db_display_argument_object(union
+							       acpi_operand_object
+							       *obj_desc,
+							       struct
+							       acpi_walk_state
+							       *walk_state))
 
 /*
  * dbexec - debugger control method execution
drivers/acpi/acpica/acmacros.h +0 -11
index e85366c..bad5bca 100644
@@ -401,17 +401,6 @@
 #endif
 
 /*
- * Some code only gets executed when the debugger is built in.
- * Note that this is entirely independent of whether the
- * DEBUG_PRINT stuff (set by ACPI_DEBUG_OUTPUT) is on, or not.
- */
-#ifdef ACPI_DEBUGGER
-#define ACPI_DEBUGGER_EXEC(a)           a
-#else
-#define ACPI_DEBUGGER_EXEC(a)
-#endif
-
-/*
  * Macros used for ACPICA utilities only
  */
 
drivers/acpi/acpica/dbdisply.c +12 -0
index 672977e..c42ce8a 100644
@@ -679,6 +679,12 @@ acpi_db_display_result_object(union acpi_operand_object *obj_desc,
 			      struct acpi_walk_state *walk_state)
 {
 
+#ifndef ACPI_APPLICATION
+	if (acpi_gbl_db_thread_id != acpi_os_get_thread_id()) {
+		return;
+	}
+#endif
+
 	/* Only display if single stepping */
 
 	if (!acpi_gbl_cm_single_step) {
@@ -708,6 +714,12 @@ acpi_db_display_argument_object(union acpi_operand_object *obj_desc,
 				struct acpi_walk_state *walk_state)
 {
 
+#ifndef ACPI_APPLICATION
+	if (acpi_gbl_db_thread_id != acpi_os_get_thread_id()) {
+		return;
+	}
+#endif
+
 	if (!acpi_gbl_cm_single_step) {
 		return;
 	}
drivers/acpi/acpica/dbxface.c +30 -0
index d95e91f..d7ff58e 100644
@@ -119,6 +119,36 @@ error_exit:
 
 /*******************************************************************************
  *
+ * FUNCTION:    acpi_db_signal_break_point
+ *
+ * PARAMETERS:  walk_state      - Current walk
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Called for AML_BREAK_POINT_OP
+ *
+ ******************************************************************************/
+
+void acpi_db_signal_break_point(struct acpi_walk_state *walk_state)
+{
+
+#ifndef ACPI_APPLICATION
+	if (acpi_gbl_db_thread_id != acpi_os_get_thread_id()) {
+		return;
+	}
+#endif
+
+	/*
+	 * Set the single-step flag. This will cause the debugger (if present)
+	 * to break to the console within the AML debugger at the start of the
+	 * next AML instruction.
+	 */
+	acpi_gbl_cm_single_step = TRUE;
+	acpi_os_printf("**break** Executed AML BreakPoint opcode\n");
+}
+
+/*******************************************************************************
+ *
  * FUNCTION:    acpi_db_single_step
  *
  * PARAMETERS:  walk_state      - Current walk
drivers/acpi/acpica/dscontrol.c +2 -8
index 435fc16..06a6f7f 100644
@@ -47,6 +47,7 @@
 #include "amlcode.h"
 #include "acdispat.h"
 #include "acinterp.h"
+#include "acdebug.h"
 
 #define _COMPONENT          ACPI_DISPATCHER
 ACPI_MODULE_NAME("dscontrol")
@@ -348,14 +349,7 @@ acpi_ds_exec_end_control_op(struct acpi_walk_state * walk_state,
 
 	case AML_BREAK_POINT_OP:
 
-		/*
-		 * Set the single-step flag. This will cause the debugger (if present)
-		 * to break to the console within the AML debugger at the start of the
-		 * next AML instruction.
-		 */
-		ACPI_DEBUGGER_EXEC(acpi_gbl_cm_single_step = TRUE);
-		ACPI_DEBUGGER_EXEC(acpi_os_printf
-				   ("**break** Executed AML BreakPoint opcode\n"));
+		acpi_db_signal_break_point(walk_state);
 
 		/* Call to the OSL in case OS wants a piece of the action */
 
drivers/acpi/acpica/dsutils.c +8 -8
index ebc577b..e4293a8 100644
@@ -605,8 +605,8 @@ acpi_ds_create_operand(struct acpi_walk_state *walk_state,
 		if (ACPI_FAILURE(status)) {
 			return_ACPI_STATUS(status);
 		}
-		ACPI_DEBUGGER_EXEC(acpi_db_display_argument_object
-				   (obj_desc, walk_state));
+
+		acpi_db_display_argument_object(obj_desc, walk_state);
 	} else {
 		/* Check for null name case */
 
@@ -638,10 +638,11 @@ acpi_ds_create_operand(struct acpi_walk_state *walk_state,
 			ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
 					  "Argument previously created, already stacked\n"));
 
-			ACPI_DEBUGGER_EXEC(acpi_db_display_argument_object
-					   (walk_state->
-					    operands[walk_state->num_operands -
-						     1], walk_state));
+			acpi_db_display_argument_object(walk_state->
+							operands[walk_state->
+								 num_operands -
+								 1],
+							walk_state);
 
 			/*
 			 * Use value that was already previously returned
@@ -685,8 +686,7 @@ acpi_ds_create_operand(struct acpi_walk_state *walk_state,
 			return_ACPI_STATUS(status);
 		}
 
-		ACPI_DEBUGGER_EXEC(acpi_db_display_argument_object
-				   (obj_desc, walk_state));
+		acpi_db_display_argument_object(obj_desc, walk_state);
 	}
 
 	return_ACPI_STATUS(AE_OK);
drivers/acpi/acpica/dswexec.c +7 -9
index df54d46..9cc5761 100644
@@ -178,8 +178,7 @@ cleanup:
 
 	/* Break to debugger to display result */
 
-	ACPI_DEBUGGER_EXEC(acpi_db_display_result_object
-			   (local_obj_desc, walk_state));
+	acpi_db_display_result_object(local_obj_desc, walk_state);
 
 	/*
 	 * Delete the predicate result object (we know that
@@ -386,11 +385,10 @@ acpi_status acpi_ds_exec_end_op(struct acpi_walk_state *walk_state)
 
 	/* Call debugger for single step support (DEBUG build only) */
 
-	ACPI_DEBUGGER_EXEC(status =
-			   acpi_db_single_step(walk_state, op, op_class));
-	ACPI_DEBUGGER_EXEC(if (ACPI_FAILURE(status)) {
-			   return_ACPI_STATUS(status);}
-	) ;
+	status = acpi_db_single_step(walk_state, op, op_class);
+	if (ACPI_FAILURE(status)) {
+		return_ACPI_STATUS(status);
+	}
 
 	/* Decode the Opcode Class */
 
@@ -728,8 +726,8 @@ cleanup:
 
 		/* Break to debugger to display result */
 
-		ACPI_DEBUGGER_EXEC(acpi_db_display_result_object
-				   (walk_state->result_obj, walk_state));
+		acpi_db_display_result_object(walk_state->result_obj,
+					      walk_state);
 
 		/*
 		 * Delete the result op if and only if:
include/acpi/acpixf.h +23 -0
index 95ebae3..5dfab9c 100644
@@ -375,6 +375,29 @@ ACPI_GLOBAL(u8, acpi_gbl_system_awake_and_running);
 
 #endif				/* ACPI_APPLICATION */
 
+/*
+ * Debugger prototypes
+ *
+ * All interfaces used by debugger will be configured
+ * out of the ACPICA build unless the ACPI_DEBUGGER
+ * flag is defined.
+ */
+#ifdef ACPI_DEBUGGER
+#define ACPI_DBR_DEPENDENT_RETURN_OK(prototype) \
+	ACPI_EXTERNAL_RETURN_OK(prototype)
+
+#define ACPI_DBR_DEPENDENT_RETURN_VOID(prototype) \
+	ACPI_EXTERNAL_RETURN_VOID(prototype)
+
+#else
+#define ACPI_DBR_DEPENDENT_RETURN_OK(prototype) \
+	static ACPI_INLINE prototype {return(AE_OK);}
+
+#define ACPI_DBR_DEPENDENT_RETURN_VOID(prototype) \
+	static ACPI_INLINE prototype {return;}
+
+#endif				/* ACPI_DEBUGGER */
+
 /*****************************************************************************
  *
  * ACPICA public interface prototypes
Signature · 1 line
1.7.10
author
#52 lore raw

PATCH v4 4/7 ACPI / debugger: Add IO interface to access debugger functionalities

In reply to Lv Zheng

This patch adds /sys/kernel/debug/acpi/acpidbg, which can be used by userspace programs to access ACPICA debugger functionalities.

Known issue:
1. IO flush support
acpi_os_notify_command_complete() and acpi_os_wait_command_ready() can be used by acpi_dbg module to implement .flush() filesystem operation. While this patch doesn't go that far. It then becomes userspace tool's duty now to flush old commands before executing new batch mode commands.

---
 drivers/acpi/Kconfig              |    3 +-
 drivers/acpi/Makefile             |    1 +
 drivers/acpi/acpi_dbg.c           |  779 +++++++++++++++++++++++++++++++++++++
 drivers/acpi/bus.c                |    2 +
 drivers/acpi/osl.c                |   55 ++-
 include/acpi/platform/aclinux.h   |    2 -
 include/acpi/platform/aclinuxex.h |   10 -
 include/linux/acpi_dbg.h          |   52 +++
 8 files changed, 887 insertions(+), 17 deletions(-)
 create mode 100644 drivers/acpi/acpi_dbg.c
 create mode 100644 include/linux/acpi_dbg.h
drivers/acpi/Kconfig +2 -1
index 5eef4cb..2a7e6d4 100644
@@ -58,8 +58,9 @@ config ACPI_CCA_REQUIRED
 	bool
 
 config ACPI_DEBUGGER
-	bool "AML debugger interface (EXPERIMENTAL)"
+	bool "AML debugger interface"
 	select ACPI_DEBUG
+	depends on DEBUG_FS
 	help
 	  Enable in-kernel debugging of AML facilities: statistics, internal
 	  object dump, single step control method execution.
drivers/acpi/Makefile +1 -0
index 675eaf3..102b5e6 100644
@@ -50,6 +50,7 @@ acpi-y				+= sysfs.o
 acpi-y				+= property.o
 acpi-$(CONFIG_X86)		+= acpi_cmos_rtc.o
 acpi-$(CONFIG_DEBUG_FS)		+= debugfs.o
+acpi-$(CONFIG_ACPI_DEBUGGER)	+= acpi_dbg.o
 acpi-$(CONFIG_ACPI_NUMA)	+= numa.o
 acpi-$(CONFIG_ACPI_PROCFS_POWER) += cm_sbs.o
 acpi-y				+= acpi_lpat.o
drivers/acpi/acpi_dbg.c new file +779 -0

779 lines not on this page · raw message

drivers/acpi/bus.c +2 -0
index a212cef..06fbba9 100644
@@ -37,6 +37,7 @@
 #include <acpi/apei.h>
 #include <linux/dmi.h>
 #include <linux/suspend.h>
+#include <linux/acpi_dbg.h>
 
 #include "internal.h"
 
@@ -1094,6 +1095,7 @@ static int __init acpi_init(void)
 	acpi_debugfs_init();
 	acpi_sleep_proc_init();
 	acpi_wakeup_device_init();
+	acpi_aml_init();
 	return 0;
 }
 
drivers/acpi/osl.c +51 -4

105 lines not on this page · raw message

include/acpi/platform/aclinux.h +0 -2
index 69dbae6..e21857d 100644
@@ -152,8 +152,6 @@
 #define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_writable
 #define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_initialize_command_signals
 #define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_terminate_command_signals
-#define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_wait_command_ready
-#define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_notify_command_complete
 
 /*
  * OSL interfaces used by utilities
include/acpi/platform/aclinuxex.h +0 -10
index 673fdf4..ceea026 100644
@@ -138,16 +138,6 @@ static inline void acpi_os_terminate_command_signals(void)
 {
 }
 
-static inline acpi_status acpi_os_wait_command_ready(void)
-{
-	return AE_ERROR;
-}
-
-static inline acpi_status acpi_os_notify_command_complete(void)
-{
-	return AE_ERROR;
-}
-
 /*
  * OSL interfaces added by Linux
  */
include/linux/acpi_dbg.h new file +52 -0

52 lines not on this page · raw message

Signature · 1 line
1.7.10
#53 lore raw

Re: [PATCH v4 4/7] ACPI / debugger: Add IO interface to access debugger functionalities

Quoted 2 lines · Lv Zheng

This patch adds /sys/kernel/debug/acpi/acpidbg, which can be used by userspace programs to access ACPICA debugger functionalities.

What's this one generated against? My Kconfig contains:

config ACPI_DEBUGGER
bool "In-kernel debugger (EXPERIMENTAL)"
select ACPI_DEBUG

which isn't quite the same as what you generated this against. I'm starting with 4.4-rc3.

--Andy

#54 lore raw

Re: [PATCH v4 4/7] ACPI / debugger: Add IO interface to access debugger functionalities

Quoted 4 lines · Andy Lutomirski
Quoted 2 lines · Lv Zheng

This patch adds /sys/kernel/debug/acpi/acpidbg, which can be used by userspace programs to access ACPICA debugger functionalities.

Quoted 8 lines

What's this one generated against? My Kconfig contains:

config ACPI_DEBUGGER
bool "In-kernel debugger (EXPERIMENTAL)"
select ACPI_DEBUG

which isn't quite the same as what you generated this against. I'm starting with 4.4-rc3.

Probably on top of linux-next (or my linux-next branch).

There's a fix commit against Kconfig in my tree which is going to be pushed for 4.4-rc4 tomorrow.

Thanks,
Rafael

author
#55 lore raw

PATCH v4 5/7 tools/power/acpi: Add userspace AML interface support

In reply to Lv Zheng

This patch adds a userspace tool to access Linux kernel AML debugger interface.

Tow modes are supported by this tool:
1. Interactive: Users are able to launch a debugging shell to talk with in-kernel AML debugger.
Note that it's user duty to ensure kernel runtime integrity by using this debugging tool:
A. Some control methods evaluated by the users may result in kernel
panics if those control methods shouldn't be evaluated by the OSPMs according to the current BIOS/OS configurations.
B. Currently if a single stepping evaluation couldn't run to an end,
then the synchronization primitives acquired by the evaluation may block normal OSPM control method evaluations.
2. Batch: Users are able to execute debugger commands in a script. Note that in addition to the above duties, it's user duty to ensure script runtime integrity by using this debugging tool in this mode:
C. Currently only those commands that are not used for single stepping
are suitable to be used in this mode.
D. If the execution of the command may cause a failure that could result
in an endless kernel execution, the execution of the script may also get blocked.
To exit the utility, currently "exit/quit" commands are recommended, but ctrl-C" can also be used.

---
 tools/power/acpi/Makefile                |   16 +-
 tools/power/acpi/tools/acpidbg/Makefile  |   27 ++
 tools/power/acpi/tools/acpidbg/acpidbg.c |  438 ++++++++++++++++++++++++++++++
 3 files changed, 473 insertions(+), 8 deletions(-)
 create mode 100644 tools/power/acpi/tools/acpidbg/Makefile
 create mode 100644 tools/power/acpi/tools/acpidbg/acpidbg.c
tools/power/acpi/Makefile +8 -8
index e882c83..a8bf908 100644
@@ -10,18 +10,18 @@
 
 include ../../scripts/Makefile.include
 
-all: acpidump ec
-clean: acpidump_clean ec_clean
-install: acpidump_install ec_install
-uninstall: acpidump_uninstall ec_uninstall
+all: acpidbg acpidump ec
+clean: acpidbg_clean acpidump_clean ec_clean
+install: acpidbg_install acpidump_install ec_install
+uninstall: acpidbg_uninstall acpidump_uninstall ec_uninstall
 
-acpidump ec: FORCE
+acpidbg acpidump ec: FORCE
 	$(call descend,tools/$@,all)
-acpidump_clean ec_clean:
+acpidbg_clean acpidump_clean ec_clean:
 	$(call descend,tools/$(@:_clean=),clean)
-acpidump_install ec_install:
+acpidbg_install acpidump_install ec_install:
 	$(call descend,tools/$(@:_install=),install)
-acpidump_uninstall ec_uninstall:
+acpidbg_uninstall acpidump_uninstall ec_uninstall:
 	$(call descend,tools/$(@:_uninstall=),uninstall)
 
 .PHONY: FORCE
tools/power/acpi/tools/acpidbg/Makefile new file +27 -0
new file mode 100644
index 0000000..352df4b
@@ -0,0 +1,27 @@
+# tools/power/acpi/tools/acpidbg/Makefile - ACPI tool Makefile
+#
+# Copyright (c) 2015, Intel Corporation
+#   Author: Lv Zheng <[email protected]>
+#
+# 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; version 2
+# of the License.
+
+include ../../Makefile.config
+
+TOOL = acpidbg
+vpath %.c \
+	../../../../../drivers/acpi/acpica\
+	../../common\
+	../../os_specific/service_layers\
+	.
+CFLAGS += -DACPI_APPLICATION -DACPI_SINGLE_THREAD -DACPI_DEBUGGER\
+	-I.\
+	-I../../../../../drivers/acpi/acpica\
+	-I../../../../../include
+LDFLAGS += -lpthread
+TOOL_OBJS = \
+	acpidbg.o
+
+include ../../Makefile.rules
tools/power/acpi/tools/acpidbg/acpidbg.c new file +438 -0

438 lines not on this page · raw message

Signature · 1 line
1.7.10
author
#56 lore raw

PATCH v4 6/7 ACPI / debugger: Add module support for ACPI debugger

In reply to Lv Zheng

This patch converts AML debugger into a loadable module.

Note that, it implements driver unloading at the level dependent on the module reference count. Which means if ACPI debugger is being used by a userspace program, "rmmod acpi_dbg" should result in failure.

---
 drivers/acpi/Kconfig     |   16 +++-
 drivers/acpi/Makefile    |    2 +-
 drivers/acpi/acpi_dbg.c  |   80 ++++++++++++------
 drivers/acpi/bus.c       |    3 +-
 drivers/acpi/osl.c       |  207 ++++++++++++++++++++++++++++++++++++++++++++--
 include/linux/acpi.h     |   71 ++++++++++++++++
 include/linux/acpi_dbg.h |   52 ------------
 7 files changed, 340 insertions(+), 91 deletions(-)
 delete mode 100644 include/linux/acpi_dbg.h
drivers/acpi/Kconfig +13 -3
index 2a7e6d4..82b96ee 100644
@@ -60,13 +60,23 @@ config ACPI_CCA_REQUIRED
 config ACPI_DEBUGGER
 	bool "AML debugger interface"
 	select ACPI_DEBUG
-	depends on DEBUG_FS
 	help
-	  Enable in-kernel debugging of AML facilities: statistics, internal
-	  object dump, single step control method execution.
+	  Enable in-kernel debugging of AML facilities: statistics,
+	  internal object dump, single step control method execution.
 	  This is still under development, currently enabling this only
 	  results in the compilation of the ACPICA debugger files.
 
+if ACPI_DEBUGGER
+
+config ACPI_DEBUGGER_USER
+	tristate "Userspace debugger accessiblity"
+	depends on DEBUG_FS
+	help
+	  Export /sys/kernel/debug/acpi/acpidbg for userspace utilities
+	  to access the debugger functionalities.
+
+endif
+
 config ACPI_SLEEP
 	bool
 	depends on SUSPEND || HIBERNATION
drivers/acpi/Makefile +1 -1
index 102b5e6..c6f236f 100644
@@ -50,7 +50,6 @@ acpi-y				+= sysfs.o
 acpi-y				+= property.o
 acpi-$(CONFIG_X86)		+= acpi_cmos_rtc.o
 acpi-$(CONFIG_DEBUG_FS)		+= debugfs.o
-acpi-$(CONFIG_ACPI_DEBUGGER)	+= acpi_dbg.o
 acpi-$(CONFIG_ACPI_NUMA)	+= numa.o
 acpi-$(CONFIG_ACPI_PROCFS_POWER) += cm_sbs.o
 acpi-y				+= acpi_lpat.o
@@ -80,6 +79,7 @@ obj-$(CONFIG_ACPI_EC_DEBUGFS)	+= ec_sys.o
 obj-$(CONFIG_ACPI_CUSTOM_METHOD)+= custom_method.o
 obj-$(CONFIG_ACPI_BGRT)		+= bgrt.o
 obj-$(CONFIG_ACPI_CPPC_LIB)	+= cppc_acpi.o
+obj-$(CONFIG_ACPI_DEBUGGER_USER) += acpi_dbg.o
 
 # processor has its own "processor." module_param namespace
 processor-y			:= processor_driver.o
drivers/acpi/acpi_dbg.c +53 -27

156 lines not on this page · raw message

drivers/acpi/bus.c +1 -2
index 06fbba9..1a40111 100644
@@ -37,7 +37,6 @@
 #include <acpi/apei.h>
 #include <linux/dmi.h>
 #include <linux/suspend.h>
-#include <linux/acpi_dbg.h>
 
 #include "internal.h"
 
@@ -1095,7 +1094,7 @@ static int __init acpi_init(void)
 	acpi_debugfs_init();
 	acpi_sleep_proc_init();
 	acpi_wakeup_device_init();
-	acpi_aml_init();
+	acpi_debugger_init();
 	return 0;
 }
 
drivers/acpi/osl.c +201 -6

260 lines not on this page · raw message

include/linux/acpi.h +71 -0

83 lines not on this page · raw message

include/linux/acpi_dbg.h deleted +0 -52

52 lines not on this page · raw message

Signature · 1 line
1.7.10
author
#57 lore raw

PATCH v4 7/7 ACPI / x86: introduce acpi_os_readable() support

In reply to Lv Zheng

From: Chen Yu <[email protected]>

This patch implements acpi_os_readable(). The function is used by ACPICA AML debugger to validate user specified pointers for dumping the memory as ACPICA descriptor objects.

---
 arch/x86/Kconfig                  |    1 +
 arch/x86/include/asm/acenv.h      |    1 +
 arch/x86/kernel/acpi/boot.c       |   44 +++++++++++++++++++++++++++++++++++++
 drivers/acpi/Kconfig              |    3 +++
 drivers/acpi/osl.c                |   12 ++++++++++
 include/acpi/platform/aclinux.h   |    1 -
 include/acpi/platform/aclinuxex.h |    5 -----
 7 files changed, 61 insertions(+), 6 deletions(-)
arch/x86/Kconfig +1 -0
index db3622f..6593b6a 100644
@@ -19,6 +19,7 @@ config X86
 	def_bool y
 	select ACPI_LEGACY_TABLES_LOOKUP	if ACPI
 	select ACPI_SYSTEM_POWER_STATES_SUPPORT	if ACPI
+	select ACPI_MEMORY_ACCESS_CHECK_SUPPORT	if ACPI
 	select ANON_INODES
 	select ARCH_CLOCKSOURCE_DATA
 	select ARCH_DISCARD_MEMBLOCK
arch/x86/include/asm/acenv.h +1 -0
index 1b010a8..a2a2849 100644
@@ -20,6 +20,7 @@
 
 int __acpi_acquire_global_lock(unsigned int *lock);
 int __acpi_release_global_lock(unsigned int *lock);
+bool __acpi_memory_readable(void *pointer, size_t length);
 
 #define ACPI_ACQUIRE_GLOBAL_LOCK(facs, Acq) \
 	((Acq) = __acpi_acquire_global_lock(&facs->global_lock))
arch/x86/kernel/acpi/boot.c +44 -0

50 lines not on this page · raw message

drivers/acpi/Kconfig +3 -0
index 82b96ee..9422133 100644
@@ -57,6 +57,9 @@ config ACPI_SYSTEM_POWER_STATES_SUPPORT
 config ACPI_CCA_REQUIRED
 	bool
 
+config ACPI_MEMORY_ACCESS_CHECK_SUPPORT
+	bool
+
 config ACPI_DEBUGGER
 	bool "AML debugger interface"
 	select ACPI_DEBUG
drivers/acpi/osl.c +12 -0
index bb66093..14a3beb 100644
@@ -1585,6 +1585,18 @@ acpi_status acpi_os_get_line(char *buffer, u32 buffer_length, u32 *bytes_read)
 }
 EXPORT_SYMBOL(acpi_os_get_line);
 
+#ifdef CONFIG_ACPI_MEMORY_ACCESS_CHECK_SUPPORT
+u8 acpi_os_readable(void *pointer, acpi_size length)
+{
+	return __acpi_memory_readable(pointer, length) ? TRUE : FALSE;
+}
+#else
+u8 acpi_os_readable(void *pointer, acpi_size length)
+{
+	return TRUE;
+}
+#endif
+
 acpi_status acpi_os_wait_command_ready(void)
 {
 	int ret;
include/acpi/platform/aclinux.h +0 -1
index e21857d..b3c493e 100644
@@ -148,7 +148,6 @@
 /*
  * OSL interfaces used by debugger/disassembler
  */
-#define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_readable
 #define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_writable
 #define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_initialize_command_signals
 #define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_terminate_command_signals
include/acpi/platform/aclinuxex.h +0 -5
index ceea026..94bead6 100644
@@ -124,11 +124,6 @@ static inline acpi_thread_id acpi_os_get_thread_id(void)
 		lock ? AE_OK : AE_NO_MEMORY; \
 	})
 
-static inline u8 acpi_os_readable(void *pointer, acpi_size length)
-{
-	return TRUE;
-}
-
 static inline acpi_status acpi_os_initialize_command_signals(void)
 {
 	return AE_OK;
Signature · 1 line
1.7.10
#58 lore raw

Re: [PATCH v4 7/7] ACPI / x86: introduce acpi_os_readable() support

Quoted 9 lines · Lv Zheng

From: Chen Yu <[email protected]>

This patch implements acpi_os_readable(). The function is used by ACPICA AML debugger to validate user specified pointers for dumping the memory as ACPICA descriptor objects.

This has to be resent with CCs to the x86 maintainers.

Thanks,
Rafael

#59 lore raw

Re: [PATCH v4 7/7] ACPI / x86: introduce acpi_os_readable() support

In reply to Lv Zheng
Quoted 48 lines · Lv Zheng

From: Chen Yu <[email protected]>

This patch implements acpi_os_readable(). The function is used by ACPICA AML debugger to validate user specified pointers for dumping the memory as ACPICA descriptor objects.

---
 arch/x86/Kconfig                  |    1 +
 arch/x86/include/asm/acenv.h      |    1 +
 arch/x86/kernel/acpi/boot.c       |   44 +++++++++++++++++++++++++++++++++++++
 drivers/acpi/Kconfig              |    3 +++
 drivers/acpi/osl.c                |   12 ++++++++++
 include/acpi/platform/aclinux.h   |    1 -
 include/acpi/platform/aclinuxex.h |    5 -----
 7 files changed, 61 insertions(+), 6 deletions(-)
arch/x86/Kconfig +1 -0
index db3622f..6593b6a 100644
@@ -19,6 +19,7 @@ config X86
        def_bool y
        select ACPI_LEGACY_TABLES_LOOKUP        if ACPI
        select ACPI_SYSTEM_POWER_STATES_SUPPORT if ACPI
+       select ACPI_MEMORY_ACCESS_CHECK_SUPPORT if ACPI
        select ANON_INODES
        select ARCH_CLOCKSOURCE_DATA
        select ARCH_DISCARD_MEMBLOCK
arch/x86/include/asm/acenv.h +1 -0
index 1b010a8..a2a2849 100644
@@ -20,6 +20,7 @@
 
 int __acpi_acquire_global_lock(unsigned int *lock);
 int __acpi_release_global_lock(unsigned int *lock);
+bool __acpi_memory_readable(void *pointer, size_t length);
 
 #define ACPI_ACQUIRE_GLOBAL_LOCK(facs, Acq) \
        ((Acq) = __acpi_acquire_global_lock(&facs->global_lock))
arch/x86/kernel/acpi/boot.c +0 -0
index e759076..4a5e22e 100644

arch/x86/kernel/acpi/boot.c int __acpi_release_global_lock(unsigned int *lock) · line 1705

Quoted 7 lines
arch/x86/kernel/acpi/boot.c +4 -0
@@ -1699,6 +1699,50 @@ int __acpi_release_global_lock(unsigned int *lock)
        return old & 0x1;
 }
 
+bool __acpi_memory_readable(void *pointer, size_t length)
+{
+       unsigned long obj_start, obj_end;
+       unsigned long start_pfn, end_pfn;

What does "readable" mean in this context?

--Andy

#60 lore raw

RE: [PATCH v4 7/7] ACPI / x86: introduce acpi_os_readable() support

Hi, Andy

Quoted 15 lines

-----Original Message-----
From: Andy Lutomirski [mailto:[email protected]]
Sent: Tuesday, December 15, 2015 7:28 AM
To: Zheng, Lv
Cc: Wysocki, Rafael J; Brown, Len; Andy Lutomirski; Lv Zheng; linux- [email protected]; Linux ACPI; Chen, Yu C
Subject: Re: [PATCH v4 7/7] ACPI / x86: introduce acpi_os_readable() support

Quoted 6 lines · Lv Zheng

From: Chen Yu <[email protected]>

This patch implements acpi_os_readable(). The function is used by ACPICA AML debugger to validate user specified pointers for dumping the memory as ACPICA descriptor objects.

[cut]

Quoted 6 lines

arch/x86/kernel/acpi/boot.c int __acpi_release_global_lock(unsigned int *lock) · line 1705

Quoted 4 lines
arch/x86/kernel/acpi/boot.c +3 -0
+bool __acpi_memory_readable(void *pointer, size_t length) {
+       unsigned long obj_start, obj_end;
+       unsigned long start_pfn, end_pfn;

What does "readable" mean in this context?

'readable' means : the address provided by the user, is a dynamically allocated virtual address - because the acpi address space are allocated by 'kmalloc', acpi debugger must check if this address is a valid 'kmalloc' address before accessing it.

This function does the sanity check that, the vitual address is a:
1. dynamically allocated address (beyond PAGE_OFFSET , but lower
than high_memory, VMALLOC_START, eg)
2. besides, the physical address must be direct-mapped(so it would not be a hole).

Thanks,
yu

author
#61 lore raw

RE: [PATCH v4 7/7] ACPI / x86: introduce acpi_os_readable() support

Hi,

Quoted 8 lines

From: Chen, Yu C
Sent: Tuesday, December 15, 2015 2:13 PM

Hi, Andy

Quoted 3 lines

From: Andy Lutomirski [mailto:[email protected]]
Sent: Tuesday, December 15, 2015 7:28 AM

Quoted 14 lines
Quoted 7 lines · Lv Zheng
Quoted 6 lines

From: Chen Yu <[email protected]>

This patch implements acpi_os_readable(). The function is used by ACPICA AML debugger to validate user specified pointers for dumping the memory as ACPICA descriptor objects.

[cut]

Quoted 6 lines

arch/x86/kernel/acpi/boot.c int __acpi_release_global_lock(unsigned int *lock) · line 1705

Quoted 4 lines
arch/x86/kernel/acpi/boot.c +3 -0
+bool __acpi_memory_readable(void *pointer, size_t length) {
+       unsigned long obj_start, obj_end;
+       unsigned long start_pfn, end_pfn;

What does "readable" mean in this context?

[Lv Zheng]
The function is used by ACPICA "dump" command.
It accepts an arbitrary address, and tries to dump the memory block specified by the address as an acpi_object. You can try: "help dump" in the interactive mode to confirm.
While acpi_object is actually all created by kmalloc.
So we just check if the specified memory block belongs to the kernel heap.
The readable/writeable is not so meaningful here as the kernel heap should always be both readable and writeable.

We do a lot of checks in this function in order to allow it to:
1. return true if "pointer" belongs to kernel heap when "length" is 0;
2. return false if "pointer" doesn't belong to kernel heap when "length" is 0;
3. return true if "pointer ~ pointer+length-1" belongs to a kernel heap range;
4. return false if "pointer ~ pointer+length-1" doesn't belong to any kernel heap range.

These checks are weak, but can help to avoid panics if users specify wrong pointers for the "dump" command.

Quoted 11 lines

'readable' means : the address provided by the user, is a dynamically allocated virtual address - because the acpi address space are allocated by 'kmalloc', acpi debugger must check if this address is a valid 'kmalloc' address before accessing it.

This function does the sanity check that, the vitual address is a:
1. dynamically allocated address (beyond PAGE_OFFSET , but lower
than high_memory, VMALLOC_START, eg)
2. besides, the physical address must be direct-mapped(so it would not be a hole).

[Lv Zheng]
There is a special case (possibly hackish) on x86_64. x86_64 kernel maps kernel image twice.
One is called as high map and the other is called as low map.

Since we use __pa() to convert a virtual address,
If the virtual address belongs to the high map range, __pa() which takes care of converting high map addresses actually returns a physical address where there should also be low map mappings ready for it. Thus the converted PFN from the result of __pa() will be treated as valid.

But this doesn't mean there is a high map for this virtual address.
x86_64 kernel drops several pages from high map in cleanup_highmap().
So accessing a virtual address that belongs to the holes whose page mappings have been dropped in this function could still result in panic due to no mappings. By enforcing this check, we can avoid such a case.
Actually no acpi_object's virtual address will belong to high map range.

Thanks and best regards
-Lv

author
#62 lore raw

RE: [PATCH v4 7/7] ACPI / x86: introduce acpi_os_readable() support

In reply to Chen, Yu C

Hi, Andy and Yu

Quoted 26 lines

From: Zheng, Lv
Sent: Tuesday, December 15, 2015 4:52 PM

Hi,

Quoted 21 lines

From: Chen, Yu C
Sent: Tuesday, December 15, 2015 2:13 PM

Hi, Andy

Quoted 10 lines

From: Andy Lutomirski [mailto:[email protected]]
Sent: Tuesday, December 15, 2015 7:28 AM

Quoted 6 lines · Lv Zheng

From: Chen Yu <[email protected]>

This patch implements acpi_os_readable(). The function is used by ACPICA AML debugger to validate user specified pointers for dumping the memory as ACPICA descriptor objects.

[cut]

Quoted 5 lines
Quoted 4 lines
arch/x86/kernel/acpi/boot.c +3 -0
+bool __acpi_memory_readable(void *pointer, size_t length) {
+       unsigned long obj_start, obj_end;
+       unsigned long start_pfn, end_pfn;
Quoted 8 lines
Quoted 1 line
Quoted 1 line

What does "readable" mean in this context?

[Lv Zheng]
The function is used by ACPICA "dump" command.
It accepts an arbitrary address, and tries to dump the memory block specified by the address as an acpi_object.
You can try: "help dump" in the interactive mode to confirm. While acpi_object is actually all created by kmalloc.

[Lv Zheng]
This statement might be wrong, Let me Cc Bob to confirm.

Hi, Bob

Do we have statically allocated acpi_objects?
If we have, we need to change this patch to allow high map .data/.bss segments addresses to pass this check.

Thanks and best regards
-Lv

Quoted 46 lines

So we just check if the specified memory block belongs to the kernel heap. The readable/writeable is not so meaningful here as the kernel heap should always be both readable and writeable.

We do a lot of checks in this function in order to allow it to:
1. return true if "pointer" belongs to kernel heap when "length" is 0;
2. return false if "pointer" doesn't belong to kernel heap when "length" is 0;
3. return true if "pointer ~ pointer+length-1" belongs to a kernel heap range;
4. return false if "pointer ~ pointer+length-1" doesn't belong to any kernel heap range.

These checks are weak, but can help to avoid panics if users specify wrong pointers for the "dump" command.

Quoted 11 lines

'readable' means : the address provided by the user, is a dynamically allocated virtual address - because the acpi address space are allocated by 'kmalloc', acpi debugger must check if this address is a valid 'kmalloc' address before accessing it.

This function does the sanity check that, the vitual address is a:
1. dynamically allocated address (beyond PAGE_OFFSET , but lower
than high_memory, VMALLOC_START, eg)
2. besides, the physical address must be direct-mapped(so it would not be a hole).

[Lv Zheng]
There is a special case (possibly hackish) on x86_64. x86_64 kernel maps kernel image twice.
One is called as high map and the other is called as low map.

Since we use __pa() to convert a virtual address,
If the virtual address belongs to the high map range, __pa() which takes care of converting high map addresses actually returns a physical address where there should also be low map mappings ready for it.
Thus the converted PFN from the result of __pa() will be treated as valid.

But this doesn't mean there is a high map for this virtual address. x86_64 kernel drops several pages from high map in cleanup_highmap(). So accessing a virtual address that belongs to the holes whose page mappings have been dropped in this function could still result in panic due to no mappings. By enforcing this check, we can avoid such a case.
Actually no acpi_object's virtual address will belong to high map range.

Thanks and best regards
-Lv

#63 lore raw

Re: [PATCH v4 7/7] ACPI / x86: introduce acpi_os_readable() support

Quoted 36 lines · Lv

Hi, Andy and Yu

Quoted 26 lines

From: Zheng, Lv
Sent: Tuesday, December 15, 2015 4:52 PM

Hi,

Quoted 21 lines

From: Chen, Yu C
Sent: Tuesday, December 15, 2015 2:13 PM

Hi, Andy

Quoted 10 lines

From: Andy Lutomirski [mailto:[email protected]]
Sent: Tuesday, December 15, 2015 7:28 AM

Quoted 6 lines · Lv Zheng

From: Chen Yu <[email protected]>

This patch implements acpi_os_readable(). The function is used by ACPICA AML debugger to validate user specified pointers for dumping the memory as ACPICA descriptor objects.

[cut]

Quoted 5 lines
Quoted 4 lines
arch/x86/kernel/acpi/boot.c +3 -0
+bool __acpi_memory_readable(void *pointer, size_t length) {
+       unsigned long obj_start, obj_end;
+       unsigned long start_pfn, end_pfn;
Quoted 8 lines
Quoted 1 line
Quoted 1 line

What does "readable" mean in this context?

[Lv Zheng]
The function is used by ACPICA "dump" command.
It accepts an arbitrary address, and tries to dump the memory block specified by the address as an acpi_object.
You can try: "help dump" in the interactive mode to confirm. While acpi_object is actually all created by kmalloc.

Quoted 8 lines

[Lv Zheng]
This statement might be wrong, Let me Cc Bob to confirm.

Hi, Bob

Do we have statically allocated acpi_objects?
If we have, we need to change this patch to allow high map .data/.bss segments addresses to pass this check.

I think that hpa or Borislav [cc'd] could address the memory map details better than I could. However, this functionality seems strange.

Are these physical addresses or virtual addresses that are being dumped? In either case, ISTM that using something iike page_is_ram might be a lot simpler.

--Andy

Quoted 49 lines

Thanks and best regards
-Lv

Quoted 46 lines

So we just check if the specified memory block belongs to the kernel heap. The readable/writeable is not so meaningful here as the kernel heap should always be both readable and writeable.

We do a lot of checks in this function in order to allow it to:
1. return true if "pointer" belongs to kernel heap when "length" is 0;
2. return false if "pointer" doesn't belong to kernel heap when "length" is 0;
3. return true if "pointer ~ pointer+length-1" belongs to a kernel heap range;
4. return false if "pointer ~ pointer+length-1" doesn't belong to any kernel heap range.

These checks are weak, but can help to avoid panics if users specify wrong pointers for the "dump" command.

Quoted 11 lines

'readable' means : the address provided by the user, is a dynamically allocated virtual address - because the acpi address space are allocated by 'kmalloc', acpi debugger must check if this address is a valid 'kmalloc' address before accessing it.

This function does the sanity check that, the vitual address is a:
1. dynamically allocated address (beyond PAGE_OFFSET , but lower
than high_memory, VMALLOC_START, eg)
2. besides, the physical address must be direct-mapped(so it would not be a hole).

[Lv Zheng]
There is a special case (possibly hackish) on x86_64. x86_64 kernel maps kernel image twice.
One is called as high map and the other is called as low map.

Since we use __pa() to convert a virtual address,
If the virtual address belongs to the high map range, __pa() which takes care of converting high map addresses actually returns a physical address where there should also be low map mappings ready for it.
Thus the converted PFN from the result of __pa() will be treated as valid.

But this doesn't mean there is a high map for this virtual address. x86_64 kernel drops several pages from high map in cleanup_highmap(). So accessing a virtual address that belongs to the holes whose page mappings have been dropped in this function could still result in panic due to no mappings. By enforcing this check, we can avoid such a case.
Actually no acpi_object's virtual address will belong to high map range.

Thanks and best regards
-Lv

Signature · 2 lines
Andy Lutomirski
AMA Capital Management, LLC
#64 lore raw

RE: [PATCH v4 7/7] ACPI / x86: introduce acpi_os_readable() support

Hi Andy,
thanks for your review,

Quoted 9 lines

-----Original Message-----
From: Andy Lutomirski [mailto:[email protected]]
Sent: Friday, December 18, 2015 1:00 AM
To: Zheng, Lv
Cc: Chen, Yu C; Moore, Robert; Wysocki, Rafael J; Brown, Len; Andy Lutomirski; Lv Zheng; [email protected]; Linux ACPI; H. Peter Anvin; Borislav Petkov
Subject: Re: [PATCH v4 7/7] ACPI / x86: introduce acpi_os_readable() support

[cut]

Quoted 5 lines

I think that hpa or Borislav [cc'd] could address the memory map details better than I could. However, this functionality seems strange.

Are these physical addresses or virtual addresses that are being dumped?

[Yu] They are virtual addresses to be dumped.

Quoted 2 lines

In either case, ISTM that using something iike page_is_ram might be a lot simpler.

[Yu] if i understand correctly, this API is used to check if the address is a valid 'kmalloc' style address, but not 'kmap' or 'vmalloc' address, and page_is_ram might treat the latter as valid address?

thanks,
Yu

#65 lore raw

Re: [PATCH v4 7/7] ACPI / x86: introduce acpi_os_readable() support

Quoted 17 lines · Yu C

Hi Andy,
thanks for your review,

Quoted 9 lines

-----Original Message-----
From: Andy Lutomirski [mailto:[email protected]]
Sent: Friday, December 18, 2015 1:00 AM
To: Zheng, Lv
Cc: Chen, Yu C; Moore, Robert; Wysocki, Rafael J; Brown, Len; Andy Lutomirski; Lv Zheng; [email protected]; Linux ACPI; H. Peter Anvin; Borislav Petkov
Subject: Re: [PATCH v4 7/7] ACPI / x86: introduce acpi_os_readable() support

[cut]

Quoted 4 lines

I think that hpa or Borislav [cc'd] could address the memory map details better than I could. However, this functionality seems strange.

Quoted 8 lines
Quoted 1 line

Are these physical addresses or virtual addresses that are being dumped?

[Yu] They are virtual addresses to be dumped.

Quoted 2 lines

In either case, ISTM that using something iike page_is_ram might be a lot simpler.

[Yu] if i understand correctly, this API is used to check if the address is a valid 'kmalloc' style address, but not 'kmap' or 'vmalloc' address, and page_is_ram might treat the latter as valid address?

I'm a bit puzzled as to why this matters, but I have no fundamental objection to doing it that way.

What's the use case, though? That is, what goes wrong if the function just always returns false?

--Andy

Quoted 2 lines

thanks,
Yu

Signature · 2 lines
Andy Lutomirski
AMA Capital Management, LLC
author
#66 lore raw

RE: [PATCH v4 7/7] ACPI / x86: introduce acpi_os_readable() support

Hi, Andy

Quoted 26 lines

From: [email protected] [mailto:linux-acpi- [email protected]] On Behalf Of Andy Lutomirski
Sent: Wednesday, December 23, 2015 6:49 AM
Subject: Re: [PATCH v4 7/7] ACPI / x86: introduce acpi_os_readable() support

Quoted 11 lines · Yu C

Hi Andy,
thanks for your review,

Quoted 8 lines

-----Original Message-----
From: Andy Lutomirski [mailto:[email protected]]
Sent: Friday, December 18, 2015 1:00 AM
To: Zheng, Lv
Cc: Chen, Yu C; Moore, Robert; Wysocki, Rafael J; Brown, Len; Andy Lutomirski; Lv Zheng; [email protected]; Linux ACPI; H. Peter Anvin; Borislav Petkov
Subject: Re: [PATCH v4 7/7] ACPI / x86: introduce acpi_os_readable()

support

Quoted 8 lines
Quoted 1 line

[cut]

Quoted 5 lines

I think that hpa or Borislav [cc'd] could address the memory map details better than I could. However, this functionality seems strange.

Are these physical addresses or virtual addresses that are being dumped?

[Yu] They are virtual addresses to be dumped.

Quoted 8 lines
Quoted 6 lines
Quoted 2 lines

In either case, ISTM that using something iike page_is_ram might be a lot simpler.

[Yu] if i understand correctly, this API is used to check if the address is a valid 'kmalloc' style address, but not 'kmap' or 'vmalloc' address, and page_is_ram might treat the latter as valid address?

I'm a bit puzzled as to why this matters, but I have no fundamental objection to doing it that way.

[Lv Zheng]
IMO, using page_is_ram() or something similar, the problem is what we need to solve in the current approach still need to be solved:
1. How can we convert a virtual address into a "struct page"?
There is no kernel API to convert any virtual address into struct page.
Even there is such a kernel API to convert kmap/vmalloc addresses, we still couldn't use it.
Because if we want to validate kmap/vmaloc pages, we need 2 APIs rather than 1 API while ACPICA only provides 1 API for this purpose. The 2 APIs should be get/put style to ping the page mappings as the mappings other than the direct mappings will not be stationary in the kernel address space. Fortunately we needn't take care of the mappings other than the direct mappings (reasons are in the 2nd comment).
So we still need to use the direct mapping APIs here.
2. How can we ensure the page is a direct mapping page?
I think Yu should confirm if there is such a common kernel API.
If there is such an API, we should use it so that we can remove the arch specific stuffs.

Quoted 1 line

What's the use case, though?

[Lv Zheng]
Fortunately, currently ACPICA only uses this API to validate if a namespace node, an operand object or a parser object is readable. See drivers/acpi/acpica/dbdisplay.c and drivers/acpi/acpica/dbcmds.c.

Quoted 1 line

That is, what goes wrong if the function just always returns false?

[Lv Zheng]
1. If it always returns false, then many ACPICA debugger internal object conversion/dump functionalities won't be functioning. For example, you can try to type “dump \_SB" in acpidbg shell and it will return an error:
"Invalid named object at address xxxxxxxxxxxxxxxx"
2. While if this function always returns true (current linux-pm/linux-next merged stuffs), we can see such a result:

      Object (ffffxxxxxxxxxxxx) Pathname: \_SB
          Name : _SB_
          Type : 06 [Device]
          ...

3. But if it always returns true, then there will be another problem:
User can type an invalid address, for example, "dump 0xFFFFFFFFFFFFFFFF".
And ACPICA debugger will try to access this invalid virtual address and finally result in a panic. So we need to implement acpi_os_readable() to harden the check.

[Lv Zheng]
Let me say more about this patch.
Currently this patch looks wrong.
Though, most of the acpi_object(s) are kmalloced in the kernel heap, as far as I know, at least the namespace root is a statically allocated object in ACPICA. Maybe "One"/"Ones"/"Zero" operands are all statically allocated objects.

So we need to modify this function to return true for the addresses that belong to .data/.bss sections for x86_64 kernels. You can confirm this by typing "dump \" in the acpidbg shell, it now returns:
"Invalid named object at address ffffffff8xxxxxxx".
We'll update it and send it after testing.

Thanks and best regards
-Lv

#67 lore raw

Re: [PATCH v4 7/7] ACPI / x86: introduce acpi_os_readable() support

Quoted 55 lines · Lv

Hi, Andy

Quoted 26 lines

From: [email protected] [mailto:linux-acpi- [email protected]] On Behalf Of Andy Lutomirski
Sent: Wednesday, December 23, 2015 6:49 AM
Subject: Re: [PATCH v4 7/7] ACPI / x86: introduce acpi_os_readable() support

Quoted 11 lines · Yu C

Hi Andy,
thanks for your review,

Quoted 8 lines

-----Original Message-----
From: Andy Lutomirski [mailto:[email protected]]
Sent: Friday, December 18, 2015 1:00 AM
To: Zheng, Lv
Cc: Chen, Yu C; Moore, Robert; Wysocki, Rafael J; Brown, Len; Andy Lutomirski; Lv Zheng; [email protected]; Linux ACPI; H. Peter Anvin; Borislav Petkov
Subject: Re: [PATCH v4 7/7] ACPI / x86: introduce acpi_os_readable()

support

Quoted 8 lines
Quoted 1 line

[cut]

Quoted 5 lines

I think that hpa or Borislav [cc'd] could address the memory map details better than I could. However, this functionality seems strange.

Are these physical addresses or virtual addresses that are being dumped?

[Yu] They are virtual addresses to be dumped.

Quoted 8 lines
Quoted 6 lines
Quoted 2 lines

In either case, ISTM that using something iike page_is_ram might be a lot simpler.

[Yu] if i understand correctly, this API is used to check if the address is a valid 'kmalloc' style address, but not 'kmap' or 'vmalloc' address, and page_is_ram might treat the latter as valid address?

I'm a bit puzzled as to why this matters, but I have no fundamental objection to doing it that way.

[Lv Zheng]
IMO, using page_is_ram() or something similar, the problem is what we need to solve in the current approach still need to be solved:
1. How can we convert a virtual address into a "struct page"?
There is no kernel API to convert any virtual address into struct page.
Even there is such a kernel API to convert kmap/vmalloc addresses, we still couldn't use it.
Because if we want to validate kmap/vmaloc pages, we need 2 APIs rather than 1 API while ACPICA only provides 1 API for this purpose. The 2 APIs should be get/put style to ping the page mappings as the mappings other than the direct mappings will not be stationary in the kernel address space. Fortunately we needn't take care of the mappings other than the direct mappings (reasons are in the 2nd comment).
So we still need to use the direct mapping APIs here.
2. How can we ensure the page is a direct mapping page?
I think Yu should confirm if there is such a common kernel API.
If there is such an API, we should use it so that we can remove the arch specific stuffs.

Quoted 1 line

What's the use case, though?

[Lv Zheng]
Fortunately, currently ACPICA only uses this API to validate if a namespace node, an operand object or a parser object is readable. See drivers/acpi/acpica/dbdisplay.c and drivers/acpi/acpica/dbcmds.c.

Quoted 1 line

That is, what goes wrong if the function just always returns false?

Quoted 9 lines

[Lv Zheng]
1. If it always returns false, then many ACPICA debugger internal object conversion/dump functionalities won't be functioning. For example, you can try to type “dump \_SB" in acpidbg shell and it will return an error:
"Invalid named object at address xxxxxxxxxxxxxxxx"
2. While if this function always returns true (current linux-pm/linux-next merged stuffs), we can see such a result:

      Object (ffffxxxxxxxxxxxx) Pathname: \_SB
          Name : _SB_
          Type : 06 [Device]

It seems a bit unfortunate to me that the ACPICA debugger lets userspace choose what address to dump rather than dumping by pathname, but given that constraint, I guess this function is needed.

Can you do something like checking virt_addr_valid and then using virt_to_pfn and page_is_ram? If that's not enough (e.g. if it doesn't work for vmalloc addresses and you need those), you could try to do something like slow_virt_to_phys, but you'd need to do some extra checks to avoid the BUG in the function.

--Andy

#68 lore raw

RE: [PATCH v4 7/7] ACPI / x86: introduce acpi_os_readable() support

Hi,Andy

Quoted 10 lines

-----Original Message-----
From: Andy Lutomirski [mailto:[email protected]]
Sent: Thursday, December 24, 2015 9:40 AM
To: Zheng, Lv
Cc: Chen, Yu C; Moore, Robert; Wysocki, Rafael J; Brown, Len; Andy Lutomirski; Lv Zheng; [email protected]; Linux ACPI; H. Peter Anvin; Borislav Petkov
Subject: Re: [PATCH v4 7/7] ACPI / x86: introduce acpi_os_readable() support

On Tue, Dec 22, 2015 at 7:25 PM, Zheng, Lv <[email protected]> wrote:

[cut]

Quoted 11 lines

It seems a bit unfortunate to me that the ACPICA debugger lets userspace choose what address to dump rather than dumping by pathname, but given that constraint, I guess this function is needed.

Can you do something like checking virt_addr_valid and then using virt_to_pfn and page_is_ram? If that's not enough (e.g. if it doesn't work for vmalloc addresses and you need those), you could try to do something like slow_virt_to_phys, but you'd need to do some extra checks to avoid the BUG in the function.

[Yu] This is a good method, firstly virt_addr_valid can exclude the vaddr of vmalloc/kmap , then slow_virt_to_phys can check if this vaddr has a valid pte physical address, but I guess we need another non-BUG_on version of slow_virt_to_phys, I'll try to test with your suggestion, thanks!
Yu

#69 lore raw

RE: [PATCH v4 7/7] ACPI / x86: introduce acpi_os_readable() support

In reply to Andy Lutomirski

(resend for messy code)
Hi, Andy

Quoted 96 lines

-----Original Message-----
From: Andy Lutomirski [mailto:[email protected]]
Sent: Thursday, December 24, 2015 9:40 AM
To: Zheng, Lv
Cc: Chen, Yu C; Moore, Robert; Wysocki, Rafael J; Brown, Len; Andy Lutomirski; Lv Zheng; [email protected]; Linux ACPI; H. Peter Anvin; Borislav Petkov
Subject: Re: [PATCH v4 7/7] ACPI / x86: introduce acpi_os_readable() support

Quoted 9 lines · Lv

Hi, Andy

Quoted 7 lines

From: [email protected] [mailto:linux-acpi- [email protected]] On Behalf Of Andy Lutomirski
Sent: Wednesday, December 23, 2015 6:49 AM
Subject: Re: [PATCH v4 7/7] ACPI / x86: introduce acpi_os_readable() support

On Mon, Dec 21, 2015 at 5:03 PM, Chen, Yu C <[email protected]>

Quoted 12 lines · wrote:
Quoted 12 lines
Quoted 12 lines

Hi Andy,
thanks for your review,

Quoted 9 lines

-----Original Message-----
From: Andy Lutomirski [mailto:[email protected]]
Sent: Friday, December 18, 2015 1:00 AM
To: Zheng, Lv
Cc: Chen, Yu C; Moore, Robert; Wysocki, Rafael J; Brown, Len; Andy Lutomirski; Lv Zheng; [email protected]; Linux ACPI; H. Peter Anvin; Borislav Petkov
Subject: Re: [PATCH v4 7/7] ACPI / x86: introduce acpi_os_readable()

Quoted 8 lines
Quoted 8 lines

support

Quoted 7 lines
Quoted 1 line

[cut]

Quoted 5 lines

I think that hpa or Borislav [cc'd] could address the memory map details better than I could. However, this functionality seems strange.

Are these physical addresses or virtual addresses that are being

dumped?

Quoted 6 lines
Quoted 6 lines
Quoted 6 lines

[Yu] They are virtual addresses to be dumped.

Quoted 2 lines

In either case, ISTM that using something iike page_is_ram might be a lot simpler.

[Yu] if i understand correctly, this API is used to check if the address is a valid 'kmalloc' style address, but not 'kmap' or 'vmalloc' address, and page_is_ram might treat the latter as valid

address?

Quoted 3 lines
Quoted 3 lines
Quoted 1 line

I'm a bit puzzled as to why this matters, but I have no fundamental

objection to doing it that way.

Quoted 2 lines

[Lv Zheng]
IMO, using page_is_ram() or something similar, the problem is what we

need to solve in the current approach still need to be solved:

Quoted 3 lines

1. How can we convert a virtual address into a "struct page"? There is no kernel API to convert any virtual address into struct page. Even there is such a kernel API to convert kmap/vmalloc addresses, we

still couldn't use it.

Quoted 1 line

Because if we want to validate kmap/vmaloc pages, we need 2 APIs

rather than 1 API while ACPICA only provides 1 API for this purpose.

Quoted 1 line

The 2 APIs should be get/put style to ping the page mappings as the

mappings other than the direct mappings will not be stationary in the kernel address space.

Quoted 1 line

Fortunately we needn't take care of the mappings other than the direct

mappings (reasons are in the 2nd comment).

Quoted 4 lines

So we still need to use the direct mapping APIs here.
2. How can we ensure the page is a direct mapping page?
I think Yu should confirm if there is such a common kernel API. If there is such an API, we should use it so that we can remove the arch

specific stuffs.

Quoted 4 lines
Quoted 2 lines

What's the use case, though?

[Lv Zheng]
Fortunately, currently ACPICA only uses this API to validate if a namespace

node, an operand object or a parser object is readable.

Quoted 5 lines

See drivers/acpi/acpica/dbdisplay.c and drivers/acpi/acpica/dbcmds.c.

Quoted 1 line

That is, what goes wrong if the function just always returns false?

[Lv Zheng]
1. If it always returns false, then many ACPICA debugger internal object

conversion/dump functionalities won't be functioning.

Quoted 1 line

For example, you can try to type “dump \_SB" in acpidbg shell and it will

return an error:

Quoted 2 lines

"Invalid named object at address xxxxxxxxxxxxxxxx"
2. While if this function always returns true (current linux-pm/linux-next

merged stuffs), we can see such a result:

Quoted 4 lines
      Object (ffffxxxxxxxxxxxx) Pathname: \_SB
          Name : _SB_
          Type : 06 [Device]

It seems a bit unfortunate to me that the ACPICA debugger lets userspace choose what address to dump rather than dumping by pathname, but given that constraint, I guess this function is needed.

Quoted 6 lines

Can you do something like checking virt_addr_valid and then using virt_to_pfn and page_is_ram? If that's not enough (e.g. if it doesn't work for vmalloc addresses and you need those), you could try to do something like slow_virt_to_phys, but you'd need to do some extra checks to avoid the BUG in the function.

[Yu] This is a good method, firstly virt_addr_valid can exclude the vaddr of vmalloc/kmap , then slow_virt_to_phys can check if this vaddr has a valid pte physical address, but I guess we need another non-BUG_on version of slow_virt_to_phys,
I'll try to test with your suggestion, thanks!
Yu

#70 lore raw

Re: [PATCH v4 0/7] ACPICA / debugger: Add in-kernel AML debugger support

In reply to Lv Zheng
Quoted 69 lines · Lv Zheng

This patchset enables ACPICA debugger for Linux kernel and implements a userspace utility to access it.

A. Build the AML debugger
In order to build the kernel support of AML debugger, the following kconfig items should be enabled:
CONFIG_ACPI_DEBUG=y
CONFIG_ACPI_DEBUGGER=y
CONFIG_DEBUG_FS=y
CONFIG_ACPI_DEBUGGER_USER=m
The userspace tool can be found at tools/power/acpi/tools/acpidbg. To build this utility, staying in tools folder and type "make acpi".

B. Load the AML debugger during runtime
In order to use the in-kernel AML debugger, the following command should be executed using root user:

 # modprobe acpi_dbg
 # mount -t debugfs none /sys/kernel/debug
 # acpidbg

C. Batch mode
In order to support scripts, the userspace utility also supports single command batch mode:

 # acpidbg -b "help"
 # acpidbg -b "tables"
 # acpidbg -b "find _LID"
 # acpidbg -b "execute \_SB.LID0._LID"
You can find the documentation about the ACPICA debugger commands in:
 https://acpica.org/sites/acpica/files/acpica-reference_17.pdf
 (The latest document can be found at https://acpica.org/documentation)
And refer to the chapter - ACPICA debugger reference to obtain the full
description of the debugger commands. Note that not all commands are
supported by an in-kernel AML debugger.

D. Unload the AML debugger during runtime
After terminating all acpidbg instances, the following command can be executed to remove the AML debugger from kernel:

 # rmmod acpi_dbg

The following tasks are not completed:
1. .flush() support in the kernel debugger IO driver.
2. multi-commands batch mode.

v2:
1. Fix a help message issue for the userspace acpidbg utility (this is a typo fix).
2. Fix a batch mode issue by adding "\n" to the prompt sequence (this was lost due to too many rebase cycles).
3. Fix kconfig dependency for an intermediate patch (this is only useful in case the latter patches are reverted).
4. Add more accurate runtime debugger stub mechanism and remove old ACPI_DEBUGGER_EXEC() stub mechanism.
5. Add x86 acpi_os_readable() support.

v3:
1. Remove acpi_os_readable() support from this patchset. It's sent separately.
2. Delete some deprecated comments.

v4:
1. Rebase patch 4/6 because of Kconfig changes.
2. Include acpi_os_readable() back as no objections, also test result is positive.

Chen Yu (1):
ACPI / x86: introduce acpi_os_readable() support

Colin Ian King (1):
ACPICA: Debugger: Remove unnecessary status check

Quoted 7 lines

Lv Zheng (5):
ACPICA: Debugger: Convert some mechanisms to OSPM specific
ACPICA: Debugger: Fix runtime stub issues of ACPI_DEBUGGER_EXEC using
different stub mechanism
ACPI / debugger: Add IO interface to access debugger functionalities tools/power/acpi: Add userspace AML interface support
ACPI / debugger: Add module support for ACPI debugger

OK, I'm queuing up [1-6/7] for 4.5.

The [7/7] needs at least to be looked at by the x86 maintainers.

Thanks,
Rafael

author
#71 lore raw

RE: [PATCH v4 0/7] ACPICA / debugger: Add in-kernel AML debugger support

Hi, Rafael

Quoted 82 lines

From: Rafael J. Wysocki [mailto:[email protected]]
Sent: Tuesday, December 15, 2015 7:45 AM

Quoted 13 lines · Lv Zheng

This patchset enables ACPICA debugger for Linux kernel and implements a userspace utility to access it.

A. Build the AML debugger
In order to build the kernel support of AML debugger, the following kconfig items should be enabled:
CONFIG_ACPI_DEBUG=y
CONFIG_ACPI_DEBUGGER=y
CONFIG_DEBUG_FS=y
CONFIG_ACPI_DEBUGGER_USER=m
The userspace tool can be found at tools/power/acpi/tools/acpidbg. To build this utility, staying in tools folder and type "make acpi".

Quoted 2 lines

B. Load the AML debugger during runtime
In order to use the in-kernel AML debugger, the following command should

be

Quoted 54 lines

executed using root user:

 # modprobe acpi_dbg
 # mount -t debugfs none /sys/kernel/debug
 # acpidbg

C. Batch mode
In order to support scripts, the userspace utility also supports single command batch mode:

 # acpidbg -b "help"
 # acpidbg -b "tables"
 # acpidbg -b "find _LID"
 # acpidbg -b "execute \_SB.LID0._LID"
You can find the documentation about the ACPICA debugger commands in:
 https://acpica.org/sites/acpica/files/acpica-reference_17.pdf
 (The latest document can be found at https://acpica.org/documentation)
And refer to the chapter - ACPICA debugger reference to obtain the full
description of the debugger commands. Note that not all commands are
supported by an in-kernel AML debugger.

D. Unload the AML debugger during runtime
After terminating all acpidbg instances, the following command can be executed to remove the AML debugger from kernel:

 # rmmod acpi_dbg

The following tasks are not completed:
1. .flush() support in the kernel debugger IO driver.
2. multi-commands batch mode.

v2:
1. Fix a help message issue for the userspace acpidbg utility (this is a typo fix).
2. Fix a batch mode issue by adding "\n" to the prompt sequence (this was lost due to too many rebase cycles).
3. Fix kconfig dependency for an intermediate patch (this is only useful in case the latter patches are reverted).
4. Add more accurate runtime debugger stub mechanism and remove old ACPI_DEBUGGER_EXEC() stub mechanism.
5. Add x86 acpi_os_readable() support.

v3:
1. Remove acpi_os_readable() support from this patchset. It's sent separately.
2. Delete some deprecated comments.

v4:
1. Rebase patch 4/6 because of Kconfig changes.
2. Include acpi_os_readable() back as no objections, also test result is positive.

Chen Yu (1):
ACPI / x86: introduce acpi_os_readable() support

Colin Ian King (1):
ACPICA: Debugger: Remove unnecessary status check

Quoted 7 lines

Lv Zheng (5):
ACPICA: Debugger: Convert some mechanisms to OSPM specific
ACPICA: Debugger: Fix runtime stub issues of ACPI_DEBUGGER_EXEC using
different stub mechanism
ACPI / debugger: Add IO interface to access debugger functionalities tools/power/acpi: Add userspace AML interface support
ACPI / debugger: Add module support for ACPI debugger

Quoted 1 line

OK, I'm queuing up [1-6/7] for 4.5.

[Lv Zheng]
Thanks!

Quoted 2 lines

The [7/7] needs at least to be looked at by the x86 maintainers.

[Lv Zheng]
OK, we'll re-send this patch to both x86/acpi mailing list with an additional test patch included to make it clearer.

Thanks and best regards
-Lv

author
#72 lore raw

PATCH 1/1 ACPI / debugger: Fix an issue a flag is modified without locking

In reply to Lv Zheng

There is one line of code, executed out of locking due to rebase mistakes. This patch fixes this issue.

---
 drivers/acpi/acpi_dbg.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/acpi/acpi_dbg.c +1 -1
index 381beb2..fa18bd0 100644
@@ -516,10 +516,10 @@ static int acpi_aml_open(struct inode *inode, struct file *file)
 			ret = -EINVAL;
 			goto err_lock;
 		}
-		acpi_aml_io.flags |= ACPI_AML_OPENED;
 		pr_debug("Debugger thread initialized.\n");
 
 		mutex_lock(&acpi_aml_io.lock);
+		acpi_aml_io.flags |= ACPI_AML_OPENED;
 		acpi_aml_io.out_crc.head = acpi_aml_io.out_crc.tail = 0;
 		acpi_aml_io.in_crc.head = acpi_aml_io.in_crc.tail = 0;
 		pr_debug("Debugger interface opened.\n");
Signature · 1 line
1.7.10
author
#73 lore raw

PATCH 1/1 ACPI / debugger: Fix a redundant mutex unlock issue in acpi_aml_open()

In reply to Lv Zheng

Fix a double mutex_unlock() issue where acpi_initialize_debugger() is called with the mutex already unlocked.

---
 drivers/acpi/acpi_dbg.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/acpi/acpi_dbg.c +2 -1
index fa18bd0..9c31b08 100644
@@ -514,7 +514,7 @@ static int acpi_aml_open(struct inode *inode, struct file *file)
 		if (ACPI_FAILURE(status)) {
 			pr_err("Failed to initialize debugger.\n");
 			ret = -EINVAL;
-			goto err_lock;
+			goto err_exit;
 		}
 		pr_debug("Debugger thread initialized.\n");
 
@@ -531,6 +531,7 @@ err_lock:
 			acpi_aml_active_reader = NULL;
 	}
 	mutex_unlock(&acpi_aml_io.lock);
+err_exit:
 	return ret;
 }
 
Signature · 1 line
1.7.10