Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
raspberrypi-kernel
提交
b17629db
R
raspberrypi-kernel
项目概览
openeuler
/
raspberrypi-kernel
通知
13
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
raspberrypi-kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
b17629db
编写于
9年前
作者:
R
Rafael J. Wysocki
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'acpi-debug' into acpica
上级
74bf8efb
59adb398
无相关合并请求
变更
23
隐藏空白更改
内联
并排
Showing
23 changed file
with
1793 addition
and
211 deletion
+1793
-211
drivers/acpi/Kconfig
drivers/acpi/Kconfig
+14
-3
drivers/acpi/Makefile
drivers/acpi/Makefile
+1
-0
drivers/acpi/acpi_dbg.c
drivers/acpi/acpi_dbg.c
+804
-0
drivers/acpi/acpica/acdebug.h
drivers/acpi/acpica/acdebug.h
+25
-11
drivers/acpi/acpica/acglobal.h
drivers/acpi/acpica/acglobal.h
+0
-5
drivers/acpi/acpica/acmacros.h
drivers/acpi/acpica/acmacros.h
+0
-11
drivers/acpi/acpica/dbdisply.c
drivers/acpi/acpica/dbdisply.c
+12
-0
drivers/acpi/acpica/dbinput.c
drivers/acpi/acpica/dbinput.c
+19
-81
drivers/acpi/acpica/dbxface.c
drivers/acpi/acpica/dbxface.c
+48
-45
drivers/acpi/acpica/dscontrol.c
drivers/acpi/acpica/dscontrol.c
+2
-8
drivers/acpi/acpica/dsutils.c
drivers/acpi/acpica/dsutils.c
+8
-8
drivers/acpi/acpica/dswexec.c
drivers/acpi/acpica/dswexec.c
+7
-9
drivers/acpi/acpica/utmutex.c
drivers/acpi/acpica/utmutex.c
+0
-17
drivers/acpi/bus.c
drivers/acpi/bus.c
+1
-0
drivers/acpi/osl.c
drivers/acpi/osl.c
+246
-4
include/acpi/acpiosxf.h
include/acpi/acpiosxf.h
+17
-1
include/acpi/acpixf.h
include/acpi/acpixf.h
+34
-0
include/acpi/platform/aclinux.h
include/acpi/platform/aclinux.h
+2
-0
include/acpi/platform/aclinuxex.h
include/acpi/platform/aclinuxex.h
+9
-0
include/linux/acpi.h
include/linux/acpi.h
+71
-0
tools/power/acpi/Makefile
tools/power/acpi/Makefile
+8
-8
tools/power/acpi/tools/acpidbg/Makefile
tools/power/acpi/tools/acpidbg/Makefile
+27
-0
tools/power/acpi/tools/acpidbg/acpidbg.c
tools/power/acpi/tools/acpidbg/acpidbg.c
+438
-0
未找到文件。
drivers/acpi/Kconfig
浏览文件 @
b17629db
...
...
@@ -58,14 +58,25 @@ config ACPI_CCA_REQUIRED
bool
config ACPI_DEBUGGER
bool "AML debugger interface
(EXPERIMENTAL)
"
bool "AML debugger interface"
select ACPI_DEBUG
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
...
...
This diff is collapsed.
Click to expand it.
drivers/acpi/Makefile
浏览文件 @
b17629db
...
...
@@ -79,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
...
...
This diff is collapsed.
Click to expand it.
drivers/acpi/acpi_dbg.c
0 → 100644
浏览文件 @
b17629db
/*
* ACPI AML interfacing support
*
* Copyright (C) 2015, Intel Corporation
* Authors: Lv Zheng <lv.zheng@intel.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
/* #define DEBUG */
#define pr_fmt(fmt) "ACPI : AML: " fmt
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/wait.h>
#include <linux/poll.h>
#include <linux/sched.h>
#include <linux/kthread.h>
#include <linux/proc_fs.h>
#include <linux/debugfs.h>
#include <linux/circ_buf.h>
#include <linux/acpi.h>
#include "internal.h"
#define ACPI_AML_BUF_ALIGN (sizeof (acpi_size))
#define ACPI_AML_BUF_SIZE PAGE_SIZE
#define circ_count(circ) \
(CIRC_CNT((circ)->head, (circ)->tail, ACPI_AML_BUF_SIZE))
#define circ_count_to_end(circ) \
(CIRC_CNT_TO_END((circ)->head, (circ)->tail, ACPI_AML_BUF_SIZE))
#define circ_space(circ) \
(CIRC_SPACE((circ)->head, (circ)->tail, ACPI_AML_BUF_SIZE))
#define circ_space_to_end(circ) \
(CIRC_SPACE_TO_END((circ)->head, (circ)->tail, ACPI_AML_BUF_SIZE))
#define ACPI_AML_OPENED 0x0001
#define ACPI_AML_CLOSED 0x0002
#define ACPI_AML_IN_USER 0x0004
/* user space is writing cmd */
#define ACPI_AML_IN_KERN 0x0008
/* kernel space is reading cmd */
#define ACPI_AML_OUT_USER 0x0010
/* user space is reading log */
#define ACPI_AML_OUT_KERN 0x0020
/* kernel space is writing log */
#define ACPI_AML_USER (ACPI_AML_IN_USER | ACPI_AML_OUT_USER)
#define ACPI_AML_KERN (ACPI_AML_IN_KERN | ACPI_AML_OUT_KERN)
#define ACPI_AML_BUSY (ACPI_AML_USER | ACPI_AML_KERN)
#define ACPI_AML_OPEN (ACPI_AML_OPENED | ACPI_AML_CLOSED)
struct
acpi_aml_io
{
wait_queue_head_t
wait
;
unsigned
long
flags
;
unsigned
long
users
;
struct
mutex
lock
;
struct
task_struct
*
thread
;
char
out_buf
[
ACPI_AML_BUF_SIZE
]
__aligned
(
ACPI_AML_BUF_ALIGN
);
struct
circ_buf
out_crc
;
char
in_buf
[
ACPI_AML_BUF_SIZE
]
__aligned
(
ACPI_AML_BUF_ALIGN
);
struct
circ_buf
in_crc
;
acpi_osd_exec_callback
function
;
void
*
context
;
unsigned
long
usages
;
};
static
struct
acpi_aml_io
acpi_aml_io
;
static
bool
acpi_aml_initialized
;
static
struct
file
*
acpi_aml_active_reader
;
static
struct
dentry
*
acpi_aml_dentry
;
static
inline
bool
__acpi_aml_running
(
void
)
{
return
acpi_aml_io
.
thread
?
true
:
false
;
}
static
inline
bool
__acpi_aml_access_ok
(
unsigned
long
flag
)
{
/*
* The debugger interface is in opened state (OPENED && !CLOSED),
* then it is allowed to access the debugger buffers from either
* user space or the kernel space.
* In addition, for the kernel space, only the debugger thread
* (thread ID matched) is allowed to access.
*/
if
(
!
(
acpi_aml_io
.
flags
&
ACPI_AML_OPENED
)
||
(
acpi_aml_io
.
flags
&
ACPI_AML_CLOSED
)
||
!
__acpi_aml_running
())
return
false
;
if
((
flag
&
ACPI_AML_KERN
)
&&
current
!=
acpi_aml_io
.
thread
)
return
false
;
return
true
;
}
static
inline
bool
__acpi_aml_readable
(
struct
circ_buf
*
circ
,
unsigned
long
flag
)
{
/*
* Another read is not in progress and there is data in buffer
* available for read.
*/
if
(
!
(
acpi_aml_io
.
flags
&
flag
)
&&
circ_count
(
circ
))
return
true
;
return
false
;
}
static
inline
bool
__acpi_aml_writable
(
struct
circ_buf
*
circ
,
unsigned
long
flag
)
{
/*
* Another write is not in progress and there is buffer space
* available for write.
*/
if
(
!
(
acpi_aml_io
.
flags
&
flag
)
&&
circ_space
(
circ
))
return
true
;
return
false
;
}
static
inline
bool
__acpi_aml_busy
(
void
)
{
if
(
acpi_aml_io
.
flags
&
ACPI_AML_BUSY
)
return
true
;
return
false
;
}
static
inline
bool
__acpi_aml_opened
(
void
)
{
if
(
acpi_aml_io
.
flags
&
ACPI_AML_OPEN
)
return
true
;
return
false
;
}
static
inline
bool
__acpi_aml_used
(
void
)
{
return
acpi_aml_io
.
usages
?
true
:
false
;
}
static
inline
bool
acpi_aml_running
(
void
)
{
bool
ret
;
mutex_lock
(
&
acpi_aml_io
.
lock
);
ret
=
__acpi_aml_running
();
mutex_unlock
(
&
acpi_aml_io
.
lock
);
return
ret
;
}
static
bool
acpi_aml_busy
(
void
)
{
bool
ret
;
mutex_lock
(
&
acpi_aml_io
.
lock
);
ret
=
__acpi_aml_busy
();
mutex_unlock
(
&
acpi_aml_io
.
lock
);
return
ret
;
}
static
bool
acpi_aml_used
(
void
)
{
bool
ret
;
/*
* The usage count is prepared to avoid race conditions between the
* starts and the stops of the debugger thread.
*/
mutex_lock
(
&
acpi_aml_io
.
lock
);
ret
=
__acpi_aml_used
();
mutex_unlock
(
&
acpi_aml_io
.
lock
);
return
ret
;
}
static
bool
acpi_aml_kern_readable
(
void
)
{
bool
ret
;
mutex_lock
(
&
acpi_aml_io
.
lock
);
ret
=
!
__acpi_aml_access_ok
(
ACPI_AML_IN_KERN
)
||
__acpi_aml_readable
(
&
acpi_aml_io
.
in_crc
,
ACPI_AML_IN_KERN
);
mutex_unlock
(
&
acpi_aml_io
.
lock
);
return
ret
;
}
static
bool
acpi_aml_kern_writable
(
void
)
{
bool
ret
;
mutex_lock
(
&
acpi_aml_io
.
lock
);
ret
=
!
__acpi_aml_access_ok
(
ACPI_AML_OUT_KERN
)
||
__acpi_aml_writable
(
&
acpi_aml_io
.
out_crc
,
ACPI_AML_OUT_KERN
);
mutex_unlock
(
&
acpi_aml_io
.
lock
);
return
ret
;
}
static
bool
acpi_aml_user_readable
(
void
)
{
bool
ret
;
mutex_lock
(
&
acpi_aml_io
.
lock
);
ret
=
!
__acpi_aml_access_ok
(
ACPI_AML_OUT_USER
)
||
__acpi_aml_readable
(
&
acpi_aml_io
.
out_crc
,
ACPI_AML_OUT_USER
);
mutex_unlock
(
&
acpi_aml_io
.
lock
);
return
ret
;
}
static
bool
acpi_aml_user_writable
(
void
)
{
bool
ret
;
mutex_lock
(
&
acpi_aml_io
.
lock
);
ret
=
!
__acpi_aml_access_ok
(
ACPI_AML_IN_USER
)
||
__acpi_aml_writable
(
&
acpi_aml_io
.
in_crc
,
ACPI_AML_IN_USER
);
mutex_unlock
(
&
acpi_aml_io
.
lock
);
return
ret
;
}
static
int
acpi_aml_lock_write
(
struct
circ_buf
*
circ
,
unsigned
long
flag
)
{
int
ret
=
0
;
mutex_lock
(
&
acpi_aml_io
.
lock
);
if
(
!
__acpi_aml_access_ok
(
flag
))
{
ret
=
-
EFAULT
;
goto
out
;
}
if
(
!
__acpi_aml_writable
(
circ
,
flag
))
{
ret
=
-
EAGAIN
;
goto
out
;
}
acpi_aml_io
.
flags
|=
flag
;
out:
mutex_unlock
(
&
acpi_aml_io
.
lock
);
return
ret
;
}
static
int
acpi_aml_lock_read
(
struct
circ_buf
*
circ
,
unsigned
long
flag
)
{
int
ret
=
0
;
mutex_lock
(
&
acpi_aml_io
.
lock
);
if
(
!
__acpi_aml_access_ok
(
flag
))
{
ret
=
-
EFAULT
;
goto
out
;
}
if
(
!
__acpi_aml_readable
(
circ
,
flag
))
{
ret
=
-
EAGAIN
;
goto
out
;
}
acpi_aml_io
.
flags
|=
flag
;
out:
mutex_unlock
(
&
acpi_aml_io
.
lock
);
return
ret
;
}
static
void
acpi_aml_unlock_fifo
(
unsigned
long
flag
,
bool
wakeup
)
{
mutex_lock
(
&
acpi_aml_io
.
lock
);
acpi_aml_io
.
flags
&=
~
flag
;
if
(
wakeup
)
wake_up_interruptible
(
&
acpi_aml_io
.
wait
);
mutex_unlock
(
&
acpi_aml_io
.
lock
);
}
static
int
acpi_aml_write_kern
(
const
char
*
buf
,
int
len
)
{
int
ret
;
struct
circ_buf
*
crc
=
&
acpi_aml_io
.
out_crc
;
int
n
;
char
*
p
;
ret
=
acpi_aml_lock_write
(
crc
,
ACPI_AML_OUT_KERN
);
if
(
IS_ERR_VALUE
(
ret
))
return
ret
;
/* sync tail before inserting logs */
smp_mb
();
p
=
&
crc
->
buf
[
crc
->
head
];
n
=
min
(
len
,
circ_space_to_end
(
crc
));
memcpy
(
p
,
buf
,
n
);
/* sync head after inserting logs */
smp_wmb
();
crc
->
head
=
(
crc
->
head
+
n
)
&
(
ACPI_AML_BUF_SIZE
-
1
);
acpi_aml_unlock_fifo
(
ACPI_AML_OUT_KERN
,
true
);
return
n
;
}
static
int
acpi_aml_readb_kern
(
void
)
{
int
ret
;
struct
circ_buf
*
crc
=
&
acpi_aml_io
.
in_crc
;
char
*
p
;
ret
=
acpi_aml_lock_read
(
crc
,
ACPI_AML_IN_KERN
);
if
(
IS_ERR_VALUE
(
ret
))
return
ret
;
/* sync head before removing cmds */
smp_rmb
();
p
=
&
crc
->
buf
[
crc
->
tail
];
ret
=
(
int
)
*
p
;
/* sync tail before inserting cmds */
smp_mb
();
crc
->
tail
=
(
crc
->
tail
+
1
)
&
(
ACPI_AML_BUF_SIZE
-
1
);
acpi_aml_unlock_fifo
(
ACPI_AML_IN_KERN
,
true
);
return
ret
;
}
/*
* acpi_aml_write_log() - Capture debugger output
* @msg: the debugger output
*
* This function should be used to implement acpi_os_printf() to filter out
* the debugger output and store the output into the debugger interface
* buffer. Return the size of stored logs or errno.
*/
static
ssize_t
acpi_aml_write_log
(
const
char
*
msg
)
{
int
ret
=
0
;
int
count
=
0
,
size
=
0
;
if
(
!
acpi_aml_initialized
)
return
-
ENODEV
;
if
(
msg
)
count
=
strlen
(
msg
);
while
(
count
>
0
)
{
again:
ret
=
acpi_aml_write_kern
(
msg
+
size
,
count
);
if
(
ret
==
-
EAGAIN
)
{
ret
=
wait_event_interruptible
(
acpi_aml_io
.
wait
,
acpi_aml_kern_writable
());
/*
* We need to retry when the condition
* becomes true.
*/
if
(
ret
==
0
)
goto
again
;
break
;
}
if
(
IS_ERR_VALUE
(
ret
))
break
;
size
+=
ret
;
count
-=
ret
;
}
return
size
>
0
?
size
:
ret
;
}
/*
* acpi_aml_read_cmd() - Capture debugger input
* @msg: the debugger input
* @size: the size of the debugger input
*
* This function should be used to implement acpi_os_get_line() to capture
* the debugger input commands and store the input commands into the
* debugger interface buffer. Return the size of stored commands or errno.
*/
static
ssize_t
acpi_aml_read_cmd
(
char
*
msg
,
size_t
count
)
{
int
ret
=
0
;
int
size
=
0
;
/*
* This is ensured by the running fact of the debugger thread
* unless a bug is introduced.
*/
BUG_ON
(
!
acpi_aml_initialized
);
while
(
count
>
0
)
{
again:
/*
* Check each input byte to find the end of the command.
*/
ret
=
acpi_aml_readb_kern
();
if
(
ret
==
-
EAGAIN
)
{
ret
=
wait_event_interruptible
(
acpi_aml_io
.
wait
,
acpi_aml_kern_readable
());
/*
* We need to retry when the condition becomes
* true.
*/
if
(
ret
==
0
)
goto
again
;
}
if
(
IS_ERR_VALUE
(
ret
))
break
;
*
(
msg
+
size
)
=
(
char
)
ret
;
size
++
;
count
--
;
if
(
ret
==
'\n'
)
{
/*
* acpi_os_get_line() requires a zero terminated command
* string.
*/
*
(
msg
+
size
-
1
)
=
'\0'
;
break
;
}
}
return
size
>
0
?
size
:
ret
;
}
static
int
acpi_aml_thread
(
void
*
unsed
)
{
acpi_osd_exec_callback
function
=
NULL
;
void
*
context
;
mutex_lock
(
&
acpi_aml_io
.
lock
);
if
(
acpi_aml_io
.
function
)
{
acpi_aml_io
.
usages
++
;
function
=
acpi_aml_io
.
function
;
context
=
acpi_aml_io
.
context
;
}
mutex_unlock
(
&
acpi_aml_io
.
lock
);
if
(
function
)
function
(
context
);
mutex_lock
(
&
acpi_aml_io
.
lock
);
acpi_aml_io
.
usages
--
;
if
(
!
__acpi_aml_used
())
{
acpi_aml_io
.
thread
=
NULL
;
wake_up
(
&
acpi_aml_io
.
wait
);
}
mutex_unlock
(
&
acpi_aml_io
.
lock
);
return
0
;
}
/*
* acpi_aml_create_thread() - Create AML debugger thread
* @function: the debugger thread callback
* @context: the context to be passed to the debugger thread
*
* This function should be used to implement acpi_os_execute() which is
* used by the ACPICA debugger to create the debugger thread.
*/
static
int
acpi_aml_create_thread
(
acpi_osd_exec_callback
function
,
void
*
context
)
{
struct
task_struct
*
t
;
mutex_lock
(
&
acpi_aml_io
.
lock
);
acpi_aml_io
.
function
=
function
;
acpi_aml_io
.
context
=
context
;
mutex_unlock
(
&
acpi_aml_io
.
lock
);
t
=
kthread_create
(
acpi_aml_thread
,
NULL
,
"aml"
);
if
(
IS_ERR
(
t
))
{
pr_err
(
"Failed to create AML debugger thread.
\n
"
);
return
PTR_ERR
(
t
);
}
mutex_lock
(
&
acpi_aml_io
.
lock
);
acpi_aml_io
.
thread
=
t
;
acpi_set_debugger_thread_id
((
acpi_thread_id
)(
unsigned
long
)
t
);
wake_up_process
(
t
);
mutex_unlock
(
&
acpi_aml_io
.
lock
);
return
0
;
}
static
int
acpi_aml_wait_command_ready
(
bool
single_step
,
char
*
buffer
,
size_t
length
)
{
acpi_status
status
;
if
(
single_step
)
acpi_os_printf
(
"
\n
%1c "
,
ACPI_DEBUGGER_EXECUTE_PROMPT
);
else
acpi_os_printf
(
"
\n
%1c "
,
ACPI_DEBUGGER_COMMAND_PROMPT
);
status
=
acpi_os_get_line
(
buffer
,
length
,
NULL
);
if
(
ACPI_FAILURE
(
status
))
return
-
EINVAL
;
return
0
;
}
static
int
acpi_aml_notify_command_complete
(
void
)
{
return
0
;
}
static
int
acpi_aml_open
(
struct
inode
*
inode
,
struct
file
*
file
)
{
int
ret
=
0
;
acpi_status
status
;
mutex_lock
(
&
acpi_aml_io
.
lock
);
/*
* The debugger interface is being closed, no new user is allowed
* during this period.
*/
if
(
acpi_aml_io
.
flags
&
ACPI_AML_CLOSED
)
{
ret
=
-
EBUSY
;
goto
err_lock
;
}
if
((
file
->
f_flags
&
O_ACCMODE
)
!=
O_WRONLY
)
{
/*
* Only one reader is allowed to initiate the debugger
* thread.
*/
if
(
acpi_aml_active_reader
)
{
ret
=
-
EBUSY
;
goto
err_lock
;
}
else
{
pr_debug
(
"Opening debugger reader.
\n
"
);
acpi_aml_active_reader
=
file
;
}
}
else
{
/*
* No writer is allowed unless the debugger thread is
* ready.
*/
if
(
!
(
acpi_aml_io
.
flags
&
ACPI_AML_OPENED
))
{
ret
=
-
ENODEV
;
goto
err_lock
;
}
}
if
(
acpi_aml_active_reader
==
file
)
{
pr_debug
(
"Opening debugger interface.
\n
"
);
mutex_unlock
(
&
acpi_aml_io
.
lock
);
pr_debug
(
"Initializing debugger thread.
\n
"
);
status
=
acpi_initialize_debugger
();
if
(
ACPI_FAILURE
(
status
))
{
pr_err
(
"Failed to initialize debugger.
\n
"
);
ret
=
-
EINVAL
;
goto
err_exit
;
}
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
"
);
}
acpi_aml_io
.
users
++
;
err_lock:
if
(
IS_ERR_VALUE
(
ret
))
{
if
(
acpi_aml_active_reader
==
file
)
acpi_aml_active_reader
=
NULL
;
}
mutex_unlock
(
&
acpi_aml_io
.
lock
);
err_exit:
return
ret
;
}
static
int
acpi_aml_release
(
struct
inode
*
inode
,
struct
file
*
file
)
{
mutex_lock
(
&
acpi_aml_io
.
lock
);
acpi_aml_io
.
users
--
;
if
(
file
==
acpi_aml_active_reader
)
{
pr_debug
(
"Closing debugger reader.
\n
"
);
acpi_aml_active_reader
=
NULL
;
pr_debug
(
"Closing debugger interface.
\n
"
);
acpi_aml_io
.
flags
|=
ACPI_AML_CLOSED
;
/*
* Wake up all user space/kernel space blocked
* readers/writers.
*/
wake_up_interruptible
(
&
acpi_aml_io
.
wait
);
mutex_unlock
(
&
acpi_aml_io
.
lock
);
/*
* Wait all user space/kernel space readers/writers to
* stop so that ACPICA command loop of the debugger thread
* should fail all its command line reads after this point.
*/
wait_event
(
acpi_aml_io
.
wait
,
!
acpi_aml_busy
());
/*
* Then we try to terminate the debugger thread if it is
* not terminated.
*/
pr_debug
(
"Terminating debugger thread.
\n
"
);
acpi_terminate_debugger
();
wait_event
(
acpi_aml_io
.
wait
,
!
acpi_aml_used
());
pr_debug
(
"Debugger thread terminated.
\n
"
);
mutex_lock
(
&
acpi_aml_io
.
lock
);
acpi_aml_io
.
flags
&=
~
ACPI_AML_OPENED
;
}
if
(
acpi_aml_io
.
users
==
0
)
{
pr_debug
(
"Debugger interface closed.
\n
"
);
acpi_aml_io
.
flags
&=
~
ACPI_AML_CLOSED
;
}
mutex_unlock
(
&
acpi_aml_io
.
lock
);
return
0
;
}
static
int
acpi_aml_read_user
(
char
__user
*
buf
,
int
len
)
{
int
ret
;
struct
circ_buf
*
crc
=
&
acpi_aml_io
.
out_crc
;
int
n
;
char
*
p
;
ret
=
acpi_aml_lock_read
(
crc
,
ACPI_AML_OUT_USER
);
if
(
IS_ERR_VALUE
(
ret
))
return
ret
;
/* sync head before removing logs */
smp_rmb
();
p
=
&
crc
->
buf
[
crc
->
tail
];
n
=
min
(
len
,
circ_count_to_end
(
crc
));
if
(
copy_to_user
(
buf
,
p
,
n
))
{
ret
=
-
EFAULT
;
goto
out
;
}
/* sync tail after removing logs */
smp_mb
();
crc
->
tail
=
(
crc
->
tail
+
n
)
&
(
ACPI_AML_BUF_SIZE
-
1
);
ret
=
n
;
out:
acpi_aml_unlock_fifo
(
ACPI_AML_OUT_USER
,
!
IS_ERR_VALUE
(
ret
));
return
ret
;
}
static
ssize_t
acpi_aml_read
(
struct
file
*
file
,
char
__user
*
buf
,
size_t
count
,
loff_t
*
ppos
)
{
int
ret
=
0
;
int
size
=
0
;
if
(
!
count
)
return
0
;
if
(
!
access_ok
(
VERIFY_WRITE
,
buf
,
count
))
return
-
EFAULT
;
while
(
count
>
0
)
{
again:
ret
=
acpi_aml_read_user
(
buf
+
size
,
count
);
if
(
ret
==
-
EAGAIN
)
{
if
(
file
->
f_flags
&
O_NONBLOCK
)
break
;
else
{
ret
=
wait_event_interruptible
(
acpi_aml_io
.
wait
,
acpi_aml_user_readable
());
/*
* We need to retry when the condition
* becomes true.
*/
if
(
ret
==
0
)
goto
again
;
}
}
if
(
IS_ERR_VALUE
(
ret
))
{
if
(
!
acpi_aml_running
())
ret
=
0
;
break
;
}
if
(
ret
)
{
size
+=
ret
;
count
-=
ret
;
*
ppos
+=
ret
;
break
;
}
}
return
size
>
0
?
size
:
ret
;
}
static
int
acpi_aml_write_user
(
const
char
__user
*
buf
,
int
len
)
{
int
ret
;
struct
circ_buf
*
crc
=
&
acpi_aml_io
.
in_crc
;
int
n
;
char
*
p
;
ret
=
acpi_aml_lock_write
(
crc
,
ACPI_AML_IN_USER
);
if
(
IS_ERR_VALUE
(
ret
))
return
ret
;
/* sync tail before inserting cmds */
smp_mb
();
p
=
&
crc
->
buf
[
crc
->
head
];
n
=
min
(
len
,
circ_space_to_end
(
crc
));
if
(
copy_from_user
(
p
,
buf
,
n
))
{
ret
=
-
EFAULT
;
goto
out
;
}
/* sync head after inserting cmds */
smp_wmb
();
crc
->
head
=
(
crc
->
head
+
n
)
&
(
ACPI_AML_BUF_SIZE
-
1
);
ret
=
n
;
out:
acpi_aml_unlock_fifo
(
ACPI_AML_IN_USER
,
!
IS_ERR_VALUE
(
ret
));
return
n
;
}
static
ssize_t
acpi_aml_write
(
struct
file
*
file
,
const
char
__user
*
buf
,
size_t
count
,
loff_t
*
ppos
)
{
int
ret
=
0
;
int
size
=
0
;
if
(
!
count
)
return
0
;
if
(
!
access_ok
(
VERIFY_READ
,
buf
,
count
))
return
-
EFAULT
;
while
(
count
>
0
)
{
again:
ret
=
acpi_aml_write_user
(
buf
+
size
,
count
);
if
(
ret
==
-
EAGAIN
)
{
if
(
file
->
f_flags
&
O_NONBLOCK
)
break
;
else
{
ret
=
wait_event_interruptible
(
acpi_aml_io
.
wait
,
acpi_aml_user_writable
());
/*
* We need to retry when the condition
* becomes true.
*/
if
(
ret
==
0
)
goto
again
;
}
}
if
(
IS_ERR_VALUE
(
ret
))
{
if
(
!
acpi_aml_running
())
ret
=
0
;
break
;
}
if
(
ret
)
{
size
+=
ret
;
count
-=
ret
;
*
ppos
+=
ret
;
}
}
return
size
>
0
?
size
:
ret
;
}
static
unsigned
int
acpi_aml_poll
(
struct
file
*
file
,
poll_table
*
wait
)
{
int
masks
=
0
;
poll_wait
(
file
,
&
acpi_aml_io
.
wait
,
wait
);
if
(
acpi_aml_user_readable
())
masks
|=
POLLIN
|
POLLRDNORM
;
if
(
acpi_aml_user_writable
())
masks
|=
POLLOUT
|
POLLWRNORM
;
return
masks
;
}
static
const
struct
file_operations
acpi_aml_operations
=
{
.
read
=
acpi_aml_read
,
.
write
=
acpi_aml_write
,
.
poll
=
acpi_aml_poll
,
.
open
=
acpi_aml_open
,
.
release
=
acpi_aml_release
,
.
llseek
=
generic_file_llseek
,
};
static
const
struct
acpi_debugger_ops
acpi_aml_debugger
=
{
.
create_thread
=
acpi_aml_create_thread
,
.
read_cmd
=
acpi_aml_read_cmd
,
.
write_log
=
acpi_aml_write_log
,
.
wait_command_ready
=
acpi_aml_wait_command_ready
,
.
notify_command_complete
=
acpi_aml_notify_command_complete
,
};
int
__init
acpi_aml_init
(
void
)
{
int
ret
=
0
;
if
(
!
acpi_debugfs_dir
)
{
ret
=
-
ENOENT
;
goto
err_exit
;
}
/* Initialize AML IO interface */
mutex_init
(
&
acpi_aml_io
.
lock
);
init_waitqueue_head
(
&
acpi_aml_io
.
wait
);
acpi_aml_io
.
out_crc
.
buf
=
acpi_aml_io
.
out_buf
;
acpi_aml_io
.
in_crc
.
buf
=
acpi_aml_io
.
in_buf
;
acpi_aml_dentry
=
debugfs_create_file
(
"acpidbg"
,
S_IFREG
|
S_IRUGO
|
S_IWUSR
,
acpi_debugfs_dir
,
NULL
,
&
acpi_aml_operations
);
if
(
acpi_aml_dentry
==
NULL
)
{
ret
=
-
ENODEV
;
goto
err_exit
;
}
ret
=
acpi_register_debugger
(
THIS_MODULE
,
&
acpi_aml_debugger
);
if
(
ret
)
goto
err_fs
;
acpi_aml_initialized
=
true
;
err_fs:
if
(
ret
)
{
debugfs_remove
(
acpi_aml_dentry
);
acpi_aml_dentry
=
NULL
;
}
err_exit:
return
ret
;
}
void
__exit
acpi_aml_exit
(
void
)
{
if
(
acpi_aml_initialized
)
{
acpi_unregister_debugger
(
&
acpi_aml_debugger
);
if
(
acpi_aml_dentry
)
{
debugfs_remove
(
acpi_aml_dentry
);
acpi_aml_dentry
=
NULL
;
}
acpi_aml_initialized
=
false
;
}
}
module_init
(
acpi_aml_init
);
module_exit
(
acpi_aml_exit
);
MODULE_AUTHOR
(
"Lv Zheng"
);
MODULE_DESCRIPTION
(
"ACPI debugger userspace IO driver"
);
MODULE_LICENSE
(
"GPL"
);
This diff is collapsed.
Click to expand it.
drivers/acpi/acpica/acdebug.h
浏览文件 @
b17629db
...
...
@@ -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
...
...
@@ -257,7 +271,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
);
...
...
This diff is collapsed.
Click to expand it.
drivers/acpi/acpica/acglobal.h
浏览文件 @
b17629db
...
...
@@ -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 */
/*****************************************************************************
...
...
This diff is collapsed.
Click to expand it.
drivers/acpi/acpica/acmacros.h
浏览文件 @
b17629db
...
...
@@ -400,17 +400,6 @@
#define ACPI_HW_OPTIONAL_FUNCTION(addr) NULL
#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
*/
...
...
This diff is collapsed.
Click to expand it.
drivers/acpi/acpica/dbdisply.c
浏览文件 @
b17629db
...
...
@@ -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
;
}
...
...
This diff is collapsed.
Click to expand it.
drivers/acpi/acpica/dbinput.c
浏览文件 @
b17629db
...
...
@@ -53,8 +53,6 @@ static u32 acpi_db_get_line(char *input_buffer);
static
u32
acpi_db_match_command
(
char
*
user_command
);
static
void
acpi_db_single_thread
(
void
);
static
void
acpi_db_display_command_info
(
char
*
command
,
u8
display_all
);
static
void
acpi_db_display_help
(
char
*
command
);
...
...
@@ -1149,55 +1147,16 @@ acpi_db_command_dispatch(char *input_buffer,
void
ACPI_SYSTEM_XFACE
acpi_db_execute_thread
(
void
*
context
)
{
acpi_status
status
=
AE_OK
;
acpi_status
Mstatus
;
while
(
status
!=
AE_CTRL_TERMINATE
&&
!
acpi_gbl_db_terminate_loop
)
{
acpi_gbl_method_executing
=
FALSE
;
acpi_gbl_step_to_next_call
=
FALSE
;
Mstatus
=
acpi_os_acquire_mutex
(
acpi_gbl_db_command_ready
,
ACPI_WAIT_FOREVER
);
if
(
ACPI_FAILURE
(
Mstatus
))
{
return
;
}
status
=
acpi_db_command_dispatch
(
acpi_gbl_db_line_buf
,
NULL
,
NULL
);
acpi_os_release_mutex
(
acpi_gbl_db_command_complete
);
}
(
void
)
acpi_db_user_commands
();
acpi_gbl_db_threads_terminated
=
TRUE
;
}
/*******************************************************************************
*
* FUNCTION: acpi_db_single_thread
*
* PARAMETERS: None
*
* RETURN: None
*
* DESCRIPTION: Debugger execute thread. Waits for a command line, then
* simply dispatches it.
*
******************************************************************************/
static
void
acpi_db_single_thread
(
void
)
{
acpi_gbl_method_executing
=
FALSE
;
acpi_gbl_step_to_next_call
=
FALSE
;
(
void
)
acpi_db_command_dispatch
(
acpi_gbl_db_line_buf
,
NULL
,
NULL
);
}
/*******************************************************************************
*
* FUNCTION: acpi_db_user_commands
*
* PARAMETERS: prompt - User prompt (depends on mode)
* op - Current executing parse op
* PARAMETERS: None
*
* RETURN: None
*
...
...
@@ -1206,7 +1165,7 @@ static void acpi_db_single_thread(void)
*
******************************************************************************/
acpi_status
acpi_db_user_commands
(
char
prompt
,
union
acpi_parse_object
*
op
)
acpi_status
acpi_db_user_commands
(
void
)
{
acpi_status
status
=
AE_OK
;
...
...
@@ -1216,52 +1175,31 @@ acpi_status acpi_db_user_commands(char prompt, union acpi_parse_object *op)
while
(
!
acpi_gbl_db_terminate_loop
)
{
/* Force output to console until a command is entered */
acpi_db_set_output_destination
(
ACPI_DB_CONSOLE_OUTPUT
);
/* Different prompt if method is executing */
if
(
!
acpi_gbl_method_executing
)
{
acpi_os_printf
(
"%1c "
,
ACPI_DEBUGGER_COMMAND_PROMPT
);
}
else
{
acpi_os_printf
(
"%1c "
,
ACPI_DEBUGGER_EXECUTE_PROMPT
);
}
/* Get the user input line */
/* Wait the readiness of the command */
status
=
acpi_os_get_line
(
acpi_gbl_db_line_buf
,
ACPI_DB_LINE_BUFFER_SIZE
,
NULL
);
status
=
acpi_os_wait_command_ready
();
if
(
ACPI_FAILURE
(
status
))
{
ACPI_EXCEPTION
((
AE_INFO
,
status
,
"While parsing command line"
));
return
(
status
);
break
;
}
/*
Check for single or multithreaded debug
*/
/*
Just call to the command line interpreter
*/
if
(
acpi_gbl_debugger_configuration
&
DEBUGGER_MULTI_THREADED
)
{
/*
* Signal the debug thread that we have a command to execute,
* and wait for the command to complete.
*/
acpi_os_release_mutex
(
acpi_gbl_db_command_ready
);
if
(
ACPI_FAILURE
(
status
))
{
return
(
status
);
}
acpi_gbl_method_executing
=
FALSE
;
acpi_gbl_step_to_next_call
=
FALSE
;
status
=
acpi_os_acquire_mutex
(
acpi_gbl_db_command_complete
,
ACPI_WAIT_FOREVER
);
if
(
ACPI_FAILURE
(
status
))
{
return
(
status
);
}
}
else
{
/* Just call to the command line interpreter */
(
void
)
acpi_db_command_dispatch
(
acpi_gbl_db_line_buf
,
NULL
,
NULL
);
/* Notify the completion of the command */
acpi_db_single_thread
();
status
=
acpi_os_notify_command_complete
();
if
(
ACPI_FAILURE
(
status
))
{
break
;
}
}
if
(
ACPI_FAILURE
(
status
)
&&
status
!=
AE_CTRL_TERMINATE
)
{
ACPI_EXCEPTION
((
AE_INFO
,
status
,
"While parsing command line"
));
}
return
(
status
);
}
This diff is collapsed.
Click to expand it.
drivers/acpi/acpica/dbxface.c
浏览文件 @
b17629db
...
...
@@ -85,46 +85,21 @@ acpi_db_start_command(struct acpi_walk_state *walk_state,
acpi_gbl_method_executing
=
TRUE
;
status
=
AE_CTRL_TRUE
;
while
(
status
==
AE_CTRL_TRUE
)
{
if
(
acpi_gbl_debugger_configuration
==
DEBUGGER_MULTI_THREADED
)
{
/* Handshake with the front-end that gets user command lines */
acpi_os_release_mutex
(
acpi_gbl_db_command_complete
);
status
=
acpi_os_acquire_mutex
(
acpi_gbl_db_command_ready
,
ACPI_WAIT_FOREVER
);
if
(
ACPI_FAILURE
(
status
))
{
return
(
status
);
}
}
else
{
/* Single threaded, we must get a command line ourselves */
/* Force output to console until a command is entered */
acpi_db_set_output_destination
(
ACPI_DB_CONSOLE_OUTPUT
);
while
(
status
==
AE_CTRL_TRUE
)
{
/* Different prompt if method is executing
*/
/* Notify the completion of the command
*/
if
(
!
acpi_gbl_method_executing
)
{
acpi_os_printf
(
"%1c "
,
ACPI_DEBUGGER_COMMAND_PROMPT
);
}
else
{
acpi_os_printf
(
"%1c "
,
ACPI_DEBUGGER_EXECUTE_PROMPT
);
}
status
=
acpi_os_notify_command_complete
();
if
(
ACPI_FAILURE
(
status
))
{
goto
error_exit
;
}
/* Get the user input line
*/
/* Wait the readiness of the command
*/
status
=
acpi_os_get_line
(
acpi_gbl_db_line_buf
,
ACPI_DB_LINE_BUFFER_SIZE
,
NULL
);
if
(
ACPI_FAILURE
(
status
))
{
ACPI_EXCEPTION
((
AE_INFO
,
status
,
"While parsing command line"
));
return
(
status
);
}
status
=
acpi_os_wait_command_ready
();
if
(
ACPI_FAILURE
(
status
))
{
goto
error_exit
;
}
status
=
...
...
@@ -134,9 +109,44 @@ acpi_db_start_command(struct acpi_walk_state *walk_state,
/* acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); */
error_exit:
if
(
ACPI_FAILURE
(
status
)
&&
status
!=
AE_CTRL_TERMINATE
)
{
ACPI_EXCEPTION
((
AE_INFO
,
status
,
"While parsing/handling command line"
));
}
return
(
status
);
}
/*******************************************************************************
*
* 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
...
...
@@ -420,15 +430,7 @@ acpi_status acpi_initialize_debugger(void)
/* These were created with one unit, grab it */
status
=
acpi_os_acquire_mutex
(
acpi_gbl_db_command_complete
,
ACPI_WAIT_FOREVER
);
if
(
ACPI_FAILURE
(
status
))
{
acpi_os_printf
(
"Could not get debugger mutex
\n
"
);
return_ACPI_STATUS
(
status
);
}
status
=
acpi_os_acquire_mutex
(
acpi_gbl_db_command_ready
,
ACPI_WAIT_FOREVER
);
status
=
acpi_os_initialize_command_signals
();
if
(
ACPI_FAILURE
(
status
))
{
acpi_os_printf
(
"Could not get debugger mutex
\n
"
);
return_ACPI_STATUS
(
status
);
...
...
@@ -473,13 +475,14 @@ void acpi_terminate_debugger(void)
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
);
}
acpi_os_terminate_command_signals
();
}
if
(
acpi_gbl_db_buffer
)
{
...
...
This diff is collapsed.
Click to expand it.
drivers/acpi/acpica/dscontrol.c
浏览文件 @
b17629db
...
...
@@ -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 */
...
...
This diff is collapsed.
Click to expand it.
drivers/acpi/acpica/dsutils.c
浏览文件 @
b17629db
...
...
@@ -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
);
...
...
This diff is collapsed.
Click to expand it.
drivers/acpi/acpica/dswexec.c
浏览文件 @
b17629db
...
...
@@ -178,8 +178,7 @@ acpi_ds_get_predicate_value(struct acpi_walk_state *walk_state,
/* 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 @@ acpi_status acpi_ds_exec_end_op(struct acpi_walk_state *walk_state)
/* 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:
...
...
This diff is collapsed.
Click to expand it.
drivers/acpi/acpica/utmutex.c
浏览文件 @
b17629db
...
...
@@ -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
;
}
...
...
This diff is collapsed.
Click to expand it.
drivers/acpi/bus.c
浏览文件 @
b17629db
...
...
@@ -1094,6 +1094,7 @@ static int __init acpi_init(void)
acpi_debugfs_init
();
acpi_sleep_proc_init
();
acpi_wakeup_device_init
();
acpi_debugger_init
();
return
0
;
}
...
...
This diff is collapsed.
Click to expand it.
drivers/acpi/osl.c
浏览文件 @
b17629db
...
...
@@ -220,6 +220,7 @@ void acpi_os_printf(const char *fmt, ...)
acpi_os_vprintf
(
fmt
,
args
);
va_end
(
args
);
}
EXPORT_SYMBOL
(
acpi_os_printf
);
void
acpi_os_vprintf
(
const
char
*
fmt
,
va_list
args
)
{
...
...
@@ -234,7 +235,8 @@ void acpi_os_vprintf(const char *fmt, va_list args)
printk
(
KERN_CONT
"%s"
,
buffer
);
}
#else
printk
(
KERN_CONT
"%s"
,
buffer
);
if
(
acpi_debugger_write_log
(
buffer
)
<
0
)
printk
(
KERN_CONT
"%s"
,
buffer
);
#endif
}
...
...
@@ -1101,6 +1103,200 @@ static void acpi_os_execute_deferred(struct work_struct *work)
kfree
(
dpc
);
}
#ifdef CONFIG_ACPI_DEBUGGER
static
struct
acpi_debugger
acpi_debugger
;
static
bool
acpi_debugger_initialized
;
int
acpi_register_debugger
(
struct
module
*
owner
,
const
struct
acpi_debugger_ops
*
ops
)
{
int
ret
=
0
;
mutex_lock
(
&
acpi_debugger
.
lock
);
if
(
acpi_debugger
.
ops
)
{
ret
=
-
EBUSY
;
goto
err_lock
;
}
acpi_debugger
.
owner
=
owner
;
acpi_debugger
.
ops
=
ops
;
err_lock:
mutex_unlock
(
&
acpi_debugger
.
lock
);
return
ret
;
}
EXPORT_SYMBOL
(
acpi_register_debugger
);
void
acpi_unregister_debugger
(
const
struct
acpi_debugger_ops
*
ops
)
{
mutex_lock
(
&
acpi_debugger
.
lock
);
if
(
ops
==
acpi_debugger
.
ops
)
{
acpi_debugger
.
ops
=
NULL
;
acpi_debugger
.
owner
=
NULL
;
}
mutex_unlock
(
&
acpi_debugger
.
lock
);
}
EXPORT_SYMBOL
(
acpi_unregister_debugger
);
int
acpi_debugger_create_thread
(
acpi_osd_exec_callback
function
,
void
*
context
)
{
int
ret
;
int
(
*
func
)(
acpi_osd_exec_callback
,
void
*
);
struct
module
*
owner
;
if
(
!
acpi_debugger_initialized
)
return
-
ENODEV
;
mutex_lock
(
&
acpi_debugger
.
lock
);
if
(
!
acpi_debugger
.
ops
)
{
ret
=
-
ENODEV
;
goto
err_lock
;
}
if
(
!
try_module_get
(
acpi_debugger
.
owner
))
{
ret
=
-
ENODEV
;
goto
err_lock
;
}
func
=
acpi_debugger
.
ops
->
create_thread
;
owner
=
acpi_debugger
.
owner
;
mutex_unlock
(
&
acpi_debugger
.
lock
);
ret
=
func
(
function
,
context
);
mutex_lock
(
&
acpi_debugger
.
lock
);
module_put
(
owner
);
err_lock:
mutex_unlock
(
&
acpi_debugger
.
lock
);
return
ret
;
}
ssize_t
acpi_debugger_write_log
(
const
char
*
msg
)
{
ssize_t
ret
;
ssize_t
(
*
func
)(
const
char
*
);
struct
module
*
owner
;
if
(
!
acpi_debugger_initialized
)
return
-
ENODEV
;
mutex_lock
(
&
acpi_debugger
.
lock
);
if
(
!
acpi_debugger
.
ops
)
{
ret
=
-
ENODEV
;
goto
err_lock
;
}
if
(
!
try_module_get
(
acpi_debugger
.
owner
))
{
ret
=
-
ENODEV
;
goto
err_lock
;
}
func
=
acpi_debugger
.
ops
->
write_log
;
owner
=
acpi_debugger
.
owner
;
mutex_unlock
(
&
acpi_debugger
.
lock
);
ret
=
func
(
msg
);
mutex_lock
(
&
acpi_debugger
.
lock
);
module_put
(
owner
);
err_lock:
mutex_unlock
(
&
acpi_debugger
.
lock
);
return
ret
;
}
ssize_t
acpi_debugger_read_cmd
(
char
*
buffer
,
size_t
buffer_length
)
{
ssize_t
ret
;
ssize_t
(
*
func
)(
char
*
,
size_t
);
struct
module
*
owner
;
if
(
!
acpi_debugger_initialized
)
return
-
ENODEV
;
mutex_lock
(
&
acpi_debugger
.
lock
);
if
(
!
acpi_debugger
.
ops
)
{
ret
=
-
ENODEV
;
goto
err_lock
;
}
if
(
!
try_module_get
(
acpi_debugger
.
owner
))
{
ret
=
-
ENODEV
;
goto
err_lock
;
}
func
=
acpi_debugger
.
ops
->
read_cmd
;
owner
=
acpi_debugger
.
owner
;
mutex_unlock
(
&
acpi_debugger
.
lock
);
ret
=
func
(
buffer
,
buffer_length
);
mutex_lock
(
&
acpi_debugger
.
lock
);
module_put
(
owner
);
err_lock:
mutex_unlock
(
&
acpi_debugger
.
lock
);
return
ret
;
}
int
acpi_debugger_wait_command_ready
(
void
)
{
int
ret
;
int
(
*
func
)(
bool
,
char
*
,
size_t
);
struct
module
*
owner
;
if
(
!
acpi_debugger_initialized
)
return
-
ENODEV
;
mutex_lock
(
&
acpi_debugger
.
lock
);
if
(
!
acpi_debugger
.
ops
)
{
ret
=
-
ENODEV
;
goto
err_lock
;
}
if
(
!
try_module_get
(
acpi_debugger
.
owner
))
{
ret
=
-
ENODEV
;
goto
err_lock
;
}
func
=
acpi_debugger
.
ops
->
wait_command_ready
;
owner
=
acpi_debugger
.
owner
;
mutex_unlock
(
&
acpi_debugger
.
lock
);
ret
=
func
(
acpi_gbl_method_executing
,
acpi_gbl_db_line_buf
,
ACPI_DB_LINE_BUFFER_SIZE
);
mutex_lock
(
&
acpi_debugger
.
lock
);
module_put
(
owner
);
err_lock:
mutex_unlock
(
&
acpi_debugger
.
lock
);
return
ret
;
}
int
acpi_debugger_notify_command_complete
(
void
)
{
int
ret
;
int
(
*
func
)(
void
);
struct
module
*
owner
;
if
(
!
acpi_debugger_initialized
)
return
-
ENODEV
;
mutex_lock
(
&
acpi_debugger
.
lock
);
if
(
!
acpi_debugger
.
ops
)
{
ret
=
-
ENODEV
;
goto
err_lock
;
}
if
(
!
try_module_get
(
acpi_debugger
.
owner
))
{
ret
=
-
ENODEV
;
goto
err_lock
;
}
func
=
acpi_debugger
.
ops
->
notify_command_complete
;
owner
=
acpi_debugger
.
owner
;
mutex_unlock
(
&
acpi_debugger
.
lock
);
ret
=
func
();
mutex_lock
(
&
acpi_debugger
.
lock
);
module_put
(
owner
);
err_lock:
mutex_unlock
(
&
acpi_debugger
.
lock
);
return
ret
;
}
int
__init
acpi_debugger_init
(
void
)
{
mutex_init
(
&
acpi_debugger
.
lock
);
acpi_debugger_initialized
=
true
;
return
0
;
}
#endif
/*******************************************************************************
*
* FUNCTION: acpi_os_execute
...
...
@@ -1127,6 +1323,15 @@ acpi_status acpi_os_execute(acpi_execute_type type,
"Scheduling function [%p(%p)] for deferred execution.
\n
"
,
function
,
context
));
if
(
type
==
OSL_DEBUGGER_MAIN_THREAD
)
{
ret
=
acpi_debugger_create_thread
(
function
,
context
);
if
(
ret
)
{
pr_err
(
"Call to kthread_create() failed.
\n
"
);
status
=
AE_ERROR
;
}
goto
out_thread
;
}
/*
* Allocate/initialize DPC structure. Note that this memory will be
* freed by the callee. The kernel handles the work_struct list in a
...
...
@@ -1151,11 +1356,17 @@ acpi_status acpi_os_execute(acpi_execute_type type,
if
(
type
==
OSL_NOTIFY_HANDLER
)
{
queue
=
kacpi_notify_wq
;
INIT_WORK
(
&
dpc
->
work
,
acpi_os_execute_deferred
);
}
else
{
}
else
if
(
type
==
OSL_GPE_HANDLER
)
{
queue
=
kacpid_wq
;
INIT_WORK
(
&
dpc
->
work
,
acpi_os_execute_deferred
);
}
else
{
pr_err
(
"Unsupported os_execute type %d.
\n
"
,
type
);
status
=
AE_ERROR
;
}
if
(
ACPI_FAILURE
(
status
))
goto
err_workqueue
;
/*
* On some machines, a software-initiated SMI causes corruption unless
* the SMI runs on CPU 0. An SMI can be initiated by any AML, but
...
...
@@ -1164,13 +1375,15 @@ acpi_status acpi_os_execute(acpi_execute_type type,
* queueing on CPU 0.
*/
ret
=
queue_work_on
(
0
,
queue
,
&
dpc
->
work
);
if
(
!
ret
)
{
printk
(
KERN_ERR
PREFIX
"Call to queue_work() failed.
\n
"
);
status
=
AE_ERROR
;
kfree
(
dpc
);
}
err_workqueue:
if
(
ACPI_FAILURE
(
status
))
kfree
(
dpc
);
out_thread:
return
status
;
}
EXPORT_SYMBOL
(
acpi_os_execute
);
...
...
@@ -1358,10 +1571,39 @@ acpi_status acpi_os_get_line(char *buffer, u32 buffer_length, u32 *bytes_read)
chars
=
strlen
(
buffer
)
-
1
;
buffer
[
chars
]
=
'\0'
;
}
#else
int
ret
;
ret
=
acpi_debugger_read_cmd
(
buffer
,
buffer_length
);
if
(
ret
<
0
)
return
AE_ERROR
;
if
(
bytes_read
)
*
bytes_read
=
ret
;
#endif
return
AE_OK
;
}
EXPORT_SYMBOL
(
acpi_os_get_line
);
acpi_status
acpi_os_wait_command_ready
(
void
)
{
int
ret
;
ret
=
acpi_debugger_wait_command_ready
();
if
(
ret
<
0
)
return
AE_ERROR
;
return
AE_OK
;
}
acpi_status
acpi_os_notify_command_complete
(
void
)
{
int
ret
;
ret
=
acpi_debugger_notify_command_complete
();
if
(
ret
<
0
)
return
AE_ERROR
;
return
AE_OK
;
}
acpi_status
acpi_os_signal
(
u32
function
,
void
*
info
)
{
...
...
This diff is collapsed.
Click to expand it.
include/acpi/acpiosxf.h
浏览文件 @
b17629db
...
...
@@ -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)
*/
...
...
This diff is collapsed.
Click to expand it.
include/acpi/acpixf.h
浏览文件 @
b17629db
...
...
@@ -263,6 +263,15 @@ ACPI_INIT_GLOBAL(u32, acpi_gbl_trace_dbg_layer, ACPI_TRACE_LAYER_DEFAULT);
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
*/
...
...
@@ -366,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
...
...
@@ -929,6 +961,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__ */
This diff is collapsed.
Click to expand it.
include/acpi/platform/aclinux.h
浏览文件 @
b17629db
...
...
@@ -150,6 +150,8 @@
*/
#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
/*
* OSL interfaces used by utilities
...
...
This diff is collapsed.
Click to expand it.
include/acpi/platform/aclinuxex.h
浏览文件 @
b17629db
...
...
@@ -129,6 +129,15 @@ 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
)
{
}
/*
* OSL interfaces added by Linux
*/
...
...
This diff is collapsed.
Click to expand it.
include/linux/acpi.h
浏览文件 @
b17629db
...
...
@@ -37,6 +37,8 @@
#include <linux/list.h>
#include <linux/mod_devicetable.h>
#include <linux/dynamic_debug.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <acpi/acpi_bus.h>
#include <acpi/acpi_drivers.h>
...
...
@@ -119,6 +121,75 @@ typedef int (*acpi_tbl_table_handler)(struct acpi_table_header *table);
typedef
int
(
*
acpi_tbl_entry_handler
)(
struct
acpi_subtable_header
*
header
,
const
unsigned
long
end
);
/* Debugger support */
struct
acpi_debugger_ops
{
int
(
*
create_thread
)(
acpi_osd_exec_callback
function
,
void
*
context
);
ssize_t
(
*
write_log
)(
const
char
*
msg
);
ssize_t
(
*
read_cmd
)(
char
*
buffer
,
size_t
length
);
int
(
*
wait_command_ready
)(
bool
single_step
,
char
*
buffer
,
size_t
length
);
int
(
*
notify_command_complete
)(
void
);
};
struct
acpi_debugger
{
const
struct
acpi_debugger_ops
*
ops
;
struct
module
*
owner
;
struct
mutex
lock
;
};
#ifdef CONFIG_ACPI_DEBUGGER
int
__init
acpi_debugger_init
(
void
);
int
acpi_register_debugger
(
struct
module
*
owner
,
const
struct
acpi_debugger_ops
*
ops
);
void
acpi_unregister_debugger
(
const
struct
acpi_debugger_ops
*
ops
);
int
acpi_debugger_create_thread
(
acpi_osd_exec_callback
function
,
void
*
context
);
ssize_t
acpi_debugger_write_log
(
const
char
*
msg
);
ssize_t
acpi_debugger_read_cmd
(
char
*
buffer
,
size_t
buffer_length
);
int
acpi_debugger_wait_command_ready
(
void
);
int
acpi_debugger_notify_command_complete
(
void
);
#else
static
inline
int
acpi_debugger_init
(
void
)
{
return
-
ENODEV
;
}
static
inline
int
acpi_register_debugger
(
struct
module
*
owner
,
const
struct
acpi_debugger_ops
*
ops
)
{
return
-
ENODEV
;
}
static
inline
void
acpi_unregister_debugger
(
const
struct
acpi_debugger_ops
*
ops
)
{
}
static
inline
int
acpi_debugger_create_thread
(
acpi_osd_exec_callback
function
,
void
*
context
)
{
return
-
ENODEV
;
}
static
inline
int
acpi_debugger_write_log
(
const
char
*
msg
)
{
return
-
ENODEV
;
}
static
inline
int
acpi_debugger_read_cmd
(
char
*
buffer
,
u32
buffer_length
)
{
return
-
ENODEV
;
}
static
inline
int
acpi_debugger_wait_command_ready
(
void
)
{
return
-
ENODEV
;
}
static
inline
int
acpi_debugger_notify_command_complete
(
void
)
{
return
-
ENODEV
;
}
#endif
#ifdef CONFIG_ACPI_INITRD_TABLE_OVERRIDE
void
acpi_initrd_override
(
void
*
data
,
size_t
size
);
#else
...
...
This diff is collapsed.
Click to expand it.
tools/power/acpi/Makefile
浏览文件 @
b17629db
...
...
@@ -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
:
acpid
bg acpid
ump ec
clean
:
acpid
bg_clean acpid
ump_clean ec_clean
install
:
acpid
bg_install acpid
ump_install ec_install
uninstall
:
acpid
bg_uninstall acpid
ump_uninstall ec_uninstall
acpidump ec
:
FORCE
acpid
bg acpid
ump ec
:
FORCE
$(
call
descend,tools/
$@
,all
)
acpidump_clean ec_clean
:
acpid
bg_clean acpid
ump_clean ec_clean
:
$(
call
descend,tools/
$
(
@:_clean
=
)
,clean
)
acpidump_install ec_install
:
acpid
bg_install acpid
ump_install ec_install
:
$(
call
descend,tools/
$
(
@:_install
=
)
,install
)
acpidump_uninstall ec_uninstall
:
acpid
bg_uninstall acpid
ump_uninstall ec_uninstall
:
$(
call
descend,tools/
$
(
@:_uninstall
=
)
,uninstall
)
.PHONY
:
FORCE
This diff is collapsed.
Click to expand it.
tools/power/acpi/tools/acpidbg/Makefile
0 → 100644
浏览文件 @
b17629db
# tools/power/acpi/tools/acpidbg/Makefile - ACPI tool Makefile
#
# Copyright (c) 2015, Intel Corporation
# Author: Lv Zheng <lv.zheng@intel.com>
#
# 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
This diff is collapsed.
Click to expand it.
tools/power/acpi/tools/acpidbg/acpidbg.c
0 → 100644
浏览文件 @
b17629db
/*
* ACPI AML interfacing userspace utility
*
* Copyright (C) 2015, Intel Corporation
* Authors: Lv Zheng <lv.zheng@intel.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <acpi/acpi.h>
/* Headers not included by include/acpi/platform/aclinux.h */
#include <stdbool.h>
#include <fcntl.h>
#include <assert.h>
#include <linux/circ_buf.h>
#define ACPI_AML_FILE "/sys/kernel/debug/acpi/acpidbg"
#define ACPI_AML_SEC_TICK 1
#define ACPI_AML_USEC_PEEK 200
#define ACPI_AML_BUF_SIZE 4096
#define ACPI_AML_BATCH_WRITE_CMD 0x00
/* Write command to kernel */
#define ACPI_AML_BATCH_READ_LOG 0x01
/* Read log from kernel */
#define ACPI_AML_BATCH_WRITE_LOG 0x02
/* Write log to console */
#define ACPI_AML_LOG_START 0x00
#define ACPI_AML_PROMPT_START 0x01
#define ACPI_AML_PROMPT_STOP 0x02
#define ACPI_AML_LOG_STOP 0x03
#define ACPI_AML_PROMPT_ROLL 0x04
#define ACPI_AML_INTERACTIVE 0x00
#define ACPI_AML_BATCH 0x01
#define circ_count(circ) \
(CIRC_CNT((circ)->head, (circ)->tail, ACPI_AML_BUF_SIZE))
#define circ_count_to_end(circ) \
(CIRC_CNT_TO_END((circ)->head, (circ)->tail, ACPI_AML_BUF_SIZE))
#define circ_space(circ) \
(CIRC_SPACE((circ)->head, (circ)->tail, ACPI_AML_BUF_SIZE))
#define circ_space_to_end(circ) \
(CIRC_SPACE_TO_END((circ)->head, (circ)->tail, ACPI_AML_BUF_SIZE))
#define acpi_aml_cmd_count() circ_count(&acpi_aml_cmd_crc)
#define acpi_aml_log_count() circ_count(&acpi_aml_log_crc)
#define acpi_aml_cmd_space() circ_space(&acpi_aml_cmd_crc)
#define acpi_aml_log_space() circ_space(&acpi_aml_log_crc)
#define ACPI_AML_DO(_fd, _op, _buf, _ret) \
do { \
_ret = acpi_aml_##_op(_fd, &acpi_aml_##_buf##_crc); \
if (_ret == 0) { \
fprintf(stderr, \
"%s %s pipe closed.\n", #_buf, #_op); \
return; \
} \
} while (0)
#define ACPI_AML_BATCH_DO(_fd, _op, _buf, _ret) \
do { \
_ret = acpi_aml_##_op##_batch_##_buf(_fd, \
&acpi_aml_##_buf##_crc); \
if (_ret == 0) \
return; \
} while (0)
static
char
acpi_aml_cmd_buf
[
ACPI_AML_BUF_SIZE
];
static
char
acpi_aml_log_buf
[
ACPI_AML_BUF_SIZE
];
static
struct
circ_buf
acpi_aml_cmd_crc
=
{
.
buf
=
acpi_aml_cmd_buf
,
.
head
=
0
,
.
tail
=
0
,
};
static
struct
circ_buf
acpi_aml_log_crc
=
{
.
buf
=
acpi_aml_log_buf
,
.
head
=
0
,
.
tail
=
0
,
};
static
const
char
*
acpi_aml_file_path
=
ACPI_AML_FILE
;
static
unsigned
long
acpi_aml_mode
=
ACPI_AML_INTERACTIVE
;
static
bool
acpi_aml_exit
;
static
bool
acpi_aml_batch_drain
;
static
unsigned
long
acpi_aml_batch_state
;
static
char
acpi_aml_batch_prompt
;
static
char
acpi_aml_batch_roll
;
static
unsigned
long
acpi_aml_log_state
;
static
char
*
acpi_aml_batch_cmd
=
NULL
;
static
char
*
acpi_aml_batch_pos
=
NULL
;
static
int
acpi_aml_set_fl
(
int
fd
,
int
flags
)
{
int
ret
;
ret
=
fcntl
(
fd
,
F_GETFL
,
0
);
if
(
ret
<
0
)
{
perror
(
"fcntl(F_GETFL)"
);
return
ret
;
}
flags
|=
ret
;
ret
=
fcntl
(
fd
,
F_SETFL
,
flags
);
if
(
ret
<
0
)
{
perror
(
"fcntl(F_SETFL)"
);
return
ret
;
}
return
ret
;
}
static
int
acpi_aml_set_fd
(
int
fd
,
int
maxfd
,
fd_set
*
set
)
{
if
(
fd
>
maxfd
)
maxfd
=
fd
;
FD_SET
(
fd
,
set
);
return
maxfd
;
}
static
int
acpi_aml_read
(
int
fd
,
struct
circ_buf
*
crc
)
{
char
*
p
;
int
len
;
p
=
&
crc
->
buf
[
crc
->
head
];
len
=
circ_space_to_end
(
crc
);
len
=
read
(
fd
,
p
,
len
);
if
(
len
<
0
)
perror
(
"read"
);
else
if
(
len
>
0
)
crc
->
head
=
(
crc
->
head
+
len
)
&
(
ACPI_AML_BUF_SIZE
-
1
);
return
len
;
}
static
int
acpi_aml_read_batch_cmd
(
int
unused
,
struct
circ_buf
*
crc
)
{
char
*
p
;
int
len
;
int
remained
=
strlen
(
acpi_aml_batch_pos
);
p
=
&
crc
->
buf
[
crc
->
head
];
len
=
circ_space_to_end
(
crc
);
if
(
len
>
remained
)
{
memcpy
(
p
,
acpi_aml_batch_pos
,
remained
);
acpi_aml_batch_pos
+=
remained
;
len
=
remained
;
}
else
{
memcpy
(
p
,
acpi_aml_batch_pos
,
len
);
acpi_aml_batch_pos
+=
len
;
}
if
(
len
>
0
)
crc
->
head
=
(
crc
->
head
+
len
)
&
(
ACPI_AML_BUF_SIZE
-
1
);
return
len
;
}
static
int
acpi_aml_read_batch_log
(
int
fd
,
struct
circ_buf
*
crc
)
{
char
*
p
;
int
len
;
int
ret
=
0
;
p
=
&
crc
->
buf
[
crc
->
head
];
len
=
circ_space_to_end
(
crc
);
while
(
ret
<
len
&&
acpi_aml_log_state
!=
ACPI_AML_LOG_STOP
)
{
if
(
acpi_aml_log_state
==
ACPI_AML_PROMPT_ROLL
)
{
*
p
=
acpi_aml_batch_roll
;
len
=
1
;
crc
->
head
=
(
crc
->
head
+
1
)
&
(
ACPI_AML_BUF_SIZE
-
1
);
ret
+=
1
;
acpi_aml_log_state
=
ACPI_AML_LOG_START
;
}
else
{
len
=
read
(
fd
,
p
,
1
);
if
(
len
<=
0
)
{
if
(
len
<
0
)
perror
(
"read"
);
ret
=
len
;
break
;
}
}
switch
(
acpi_aml_log_state
)
{
case
ACPI_AML_LOG_START
:
if
(
*
p
==
'\n'
)
acpi_aml_log_state
=
ACPI_AML_PROMPT_START
;
crc
->
head
=
(
crc
->
head
+
1
)
&
(
ACPI_AML_BUF_SIZE
-
1
);
ret
+=
1
;
break
;
case
ACPI_AML_PROMPT_START
:
if
(
*
p
==
ACPI_DEBUGGER_COMMAND_PROMPT
||
*
p
==
ACPI_DEBUGGER_EXECUTE_PROMPT
)
{
acpi_aml_batch_prompt
=
*
p
;
acpi_aml_log_state
=
ACPI_AML_PROMPT_STOP
;
}
else
{
if
(
*
p
!=
'\n'
)
acpi_aml_log_state
=
ACPI_AML_LOG_START
;
crc
->
head
=
(
crc
->
head
+
1
)
&
(
ACPI_AML_BUF_SIZE
-
1
);
ret
+=
1
;
}
break
;
case
ACPI_AML_PROMPT_STOP
:
if
(
*
p
==
' '
)
{
acpi_aml_log_state
=
ACPI_AML_LOG_STOP
;
acpi_aml_exit
=
true
;
}
else
{
/* Roll back */
acpi_aml_log_state
=
ACPI_AML_PROMPT_ROLL
;
acpi_aml_batch_roll
=
*
p
;
*
p
=
acpi_aml_batch_prompt
;
crc
->
head
=
(
crc
->
head
+
1
)
&
(
ACPI_AML_BUF_SIZE
-
1
);
ret
+=
1
;
}
break
;
default:
assert
(
0
);
break
;
}
}
return
ret
;
}
static
int
acpi_aml_write
(
int
fd
,
struct
circ_buf
*
crc
)
{
char
*
p
;
int
len
;
p
=
&
crc
->
buf
[
crc
->
tail
];
len
=
circ_count_to_end
(
crc
);
len
=
write
(
fd
,
p
,
len
);
if
(
len
<
0
)
perror
(
"write"
);
else
if
(
len
>
0
)
crc
->
tail
=
(
crc
->
tail
+
len
)
&
(
ACPI_AML_BUF_SIZE
-
1
);
return
len
;
}
static
int
acpi_aml_write_batch_log
(
int
fd
,
struct
circ_buf
*
crc
)
{
char
*
p
;
int
len
;
p
=
&
crc
->
buf
[
crc
->
tail
];
len
=
circ_count_to_end
(
crc
);
if
(
!
acpi_aml_batch_drain
)
{
len
=
write
(
fd
,
p
,
len
);
if
(
len
<
0
)
perror
(
"write"
);
}
if
(
len
>
0
)
crc
->
tail
=
(
crc
->
tail
+
len
)
&
(
ACPI_AML_BUF_SIZE
-
1
);
return
len
;
}
static
int
acpi_aml_write_batch_cmd
(
int
fd
,
struct
circ_buf
*
crc
)
{
int
len
;
len
=
acpi_aml_write
(
fd
,
crc
);
if
(
circ_count_to_end
(
crc
)
==
0
)
acpi_aml_batch_state
=
ACPI_AML_BATCH_READ_LOG
;
return
len
;
}
static
void
acpi_aml_loop
(
int
fd
)
{
fd_set
rfds
;
fd_set
wfds
;
struct
timeval
tv
;
int
ret
;
int
maxfd
=
0
;
if
(
acpi_aml_mode
==
ACPI_AML_BATCH
)
{
acpi_aml_log_state
=
ACPI_AML_LOG_START
;
acpi_aml_batch_pos
=
acpi_aml_batch_cmd
;
if
(
acpi_aml_batch_drain
)
acpi_aml_batch_state
=
ACPI_AML_BATCH_READ_LOG
;
else
acpi_aml_batch_state
=
ACPI_AML_BATCH_WRITE_CMD
;
}
acpi_aml_exit
=
false
;
while
(
!
acpi_aml_exit
)
{
tv
.
tv_sec
=
ACPI_AML_SEC_TICK
;
tv
.
tv_usec
=
0
;
FD_ZERO
(
&
rfds
);
FD_ZERO
(
&
wfds
);
if
(
acpi_aml_cmd_space
())
{
if
(
acpi_aml_mode
==
ACPI_AML_INTERACTIVE
)
maxfd
=
acpi_aml_set_fd
(
STDIN_FILENO
,
maxfd
,
&
rfds
);
else
if
(
strlen
(
acpi_aml_batch_pos
)
&&
acpi_aml_batch_state
==
ACPI_AML_BATCH_WRITE_CMD
)
ACPI_AML_BATCH_DO
(
STDIN_FILENO
,
read
,
cmd
,
ret
);
}
if
(
acpi_aml_cmd_count
()
&&
(
acpi_aml_mode
==
ACPI_AML_INTERACTIVE
||
acpi_aml_batch_state
==
ACPI_AML_BATCH_WRITE_CMD
))
maxfd
=
acpi_aml_set_fd
(
fd
,
maxfd
,
&
wfds
);
if
(
acpi_aml_log_space
()
&&
(
acpi_aml_mode
==
ACPI_AML_INTERACTIVE
||
acpi_aml_batch_state
==
ACPI_AML_BATCH_READ_LOG
))
maxfd
=
acpi_aml_set_fd
(
fd
,
maxfd
,
&
rfds
);
if
(
acpi_aml_log_count
())
maxfd
=
acpi_aml_set_fd
(
STDOUT_FILENO
,
maxfd
,
&
wfds
);
ret
=
select
(
maxfd
+
1
,
&
rfds
,
&
wfds
,
NULL
,
&
tv
);
if
(
ret
<
0
)
{
perror
(
"select"
);
break
;
}
if
(
ret
>
0
)
{
if
(
FD_ISSET
(
STDIN_FILENO
,
&
rfds
))
ACPI_AML_DO
(
STDIN_FILENO
,
read
,
cmd
,
ret
);
if
(
FD_ISSET
(
fd
,
&
wfds
))
{
if
(
acpi_aml_mode
==
ACPI_AML_BATCH
)
ACPI_AML_BATCH_DO
(
fd
,
write
,
cmd
,
ret
);
else
ACPI_AML_DO
(
fd
,
write
,
cmd
,
ret
);
}
if
(
FD_ISSET
(
fd
,
&
rfds
))
{
if
(
acpi_aml_mode
==
ACPI_AML_BATCH
)
ACPI_AML_BATCH_DO
(
fd
,
read
,
log
,
ret
);
else
ACPI_AML_DO
(
fd
,
read
,
log
,
ret
);
}
if
(
FD_ISSET
(
STDOUT_FILENO
,
&
wfds
))
{
if
(
acpi_aml_mode
==
ACPI_AML_BATCH
)
ACPI_AML_BATCH_DO
(
STDOUT_FILENO
,
write
,
log
,
ret
);
else
ACPI_AML_DO
(
STDOUT_FILENO
,
write
,
log
,
ret
);
}
}
}
}
static
bool
acpi_aml_readable
(
int
fd
)
{
fd_set
rfds
;
struct
timeval
tv
;
int
ret
;
int
maxfd
=
0
;
tv
.
tv_sec
=
0
;
tv
.
tv_usec
=
ACPI_AML_USEC_PEEK
;
FD_ZERO
(
&
rfds
);
maxfd
=
acpi_aml_set_fd
(
fd
,
maxfd
,
&
rfds
);
ret
=
select
(
maxfd
+
1
,
&
rfds
,
NULL
,
NULL
,
&
tv
);
if
(
ret
<
0
)
perror
(
"select"
);
if
(
ret
>
0
&&
FD_ISSET
(
fd
,
&
rfds
))
return
true
;
return
false
;
}
/*
* This is a userspace IO flush implementation, replying on the prompt
* characters and can be turned into a flush() call after kernel implements
* .flush() filesystem operation.
*/
static
void
acpi_aml_flush
(
int
fd
)
{
while
(
acpi_aml_readable
(
fd
))
{
acpi_aml_batch_drain
=
true
;
acpi_aml_loop
(
fd
);
acpi_aml_batch_drain
=
false
;
}
}
void
usage
(
FILE
*
file
,
char
*
progname
)
{
fprintf
(
file
,
"usage: %s [-b cmd] [-f file] [-h]
\n
"
,
progname
);
fprintf
(
file
,
"
\n
Options:
\n
"
);
fprintf
(
file
,
" -b Specify command to be executed in batch mode
\n
"
);
fprintf
(
file
,
" -f Specify interface file other than"
);
fprintf
(
file
,
" /sys/kernel/debug/acpi/acpidbg
\n
"
);
fprintf
(
file
,
" -h Print this help message
\n
"
);
}
int
main
(
int
argc
,
char
**
argv
)
{
int
fd
=
0
;
int
ch
;
int
len
;
int
ret
=
EXIT_SUCCESS
;
while
((
ch
=
getopt
(
argc
,
argv
,
"b:f:h"
))
!=
-
1
)
{
switch
(
ch
)
{
case
'b'
:
if
(
acpi_aml_batch_cmd
)
{
fprintf
(
stderr
,
"Already specify %s
\n
"
,
acpi_aml_batch_cmd
);
ret
=
EXIT_FAILURE
;
goto
exit
;
}
len
=
strlen
(
optarg
);
acpi_aml_batch_cmd
=
calloc
(
len
+
2
,
1
);
if
(
!
acpi_aml_batch_cmd
)
{
perror
(
"calloc"
);
ret
=
EXIT_FAILURE
;
goto
exit
;
}
memcpy
(
acpi_aml_batch_cmd
,
optarg
,
len
);
acpi_aml_batch_cmd
[
len
]
=
'\n'
;
acpi_aml_mode
=
ACPI_AML_BATCH
;
break
;
case
'f'
:
acpi_aml_file_path
=
optarg
;
break
;
case
'h'
:
usage
(
stdout
,
argv
[
0
]);
goto
exit
;
break
;
case
'?'
:
default:
usage
(
stderr
,
argv
[
0
]);
ret
=
EXIT_FAILURE
;
goto
exit
;
break
;
}
}
fd
=
open
(
acpi_aml_file_path
,
O_RDWR
|
O_NONBLOCK
);
if
(
fd
<
0
)
{
perror
(
"open"
);
ret
=
EXIT_FAILURE
;
goto
exit
;
}
acpi_aml_set_fl
(
STDIN_FILENO
,
O_NONBLOCK
);
acpi_aml_set_fl
(
STDOUT_FILENO
,
O_NONBLOCK
);
if
(
acpi_aml_mode
==
ACPI_AML_BATCH
)
acpi_aml_flush
(
fd
);
acpi_aml_loop
(
fd
);
exit:
if
(
fd
<
0
)
close
(
fd
);
if
(
acpi_aml_batch_cmd
)
free
(
acpi_aml_batch_cmd
);
return
ret
;
}
This diff is collapsed.
Click to expand it.
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录
反馈
建议
客服
返回
顶部