mblog.c
来自「Linux Kernel 2.6.9 for OMAP1710」· C语言 代码 · 共 385 行
C
385 行
/* * linux/arch/arm/mach-omap/dsp/mblog.c * * OMAP DSP driver Mailbox log module * * Copyright (C) 2003,2004 Nokia Corporation * * Written by Toshihiro Kobayashi <toshihiro.kobayashi@nokia.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; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: mblog.c * $Revision: 3.0.1 * $Date: 2004/10/04 * */#include <linux/module.h>#include <linux/sched.h>#include <linux/proc_fs.h>#include <linux/init.h>#include <asm/irq.h>#include <asm/arch/dsp.h>#include "dsp.h"#define CMD_L_TYPE_NULL 0#define CMD_L_TYPE_TID 1#define CMD_L_TYPE_SUBCMD 2struct cmdinfo { char *name; char cmd_l_type;};static const struct cmdinfo cif_null = { "Unknown", CMD_L_TYPE_NULL }, cif_wdsnd = { "WDSND", CMD_L_TYPE_TID }, cif_wdreq = { "WDREQ", CMD_L_TYPE_TID }, cif_bksnd = { "BKSND", CMD_L_TYPE_TID }, cif_bkreq = { "BKREQ", CMD_L_TYPE_TID }, cif_bkyld = { "BKYLD", CMD_L_TYPE_NULL }, cif_bksndp = { "BKSNDP", CMD_L_TYPE_TID }, cif_bkreqp = { "BKREQP", CMD_L_TYPE_TID }, cif_tctl = { "TCTL", CMD_L_TYPE_TID }, cif_mmap = { "MMAP", CMD_L_TYPE_TID }, cif_wdt = { "WDT", CMD_L_TYPE_NULL }, cif_runlevel = { "RUNLEVEL", CMD_L_TYPE_SUBCMD }, cif_pm = { "PM", CMD_L_TYPE_SUBCMD }, cif_tcfg = { "TCFG", CMD_L_TYPE_TID }, cif_tadd = { "TADD", CMD_L_TYPE_TID }, cif_tdel = { "TDEL", CMD_L_TYPE_TID }, cif_tstop = { "TSTOP", CMD_L_TYPE_TID }, cif_dspcfg = { "DSPCFG", CMD_L_TYPE_SUBCMD }, cif_regrw = { "REGRW", CMD_L_TYPE_SUBCMD }, cif_getvar = { "GETVAR", CMD_L_TYPE_SUBCMD }, cif_setvar = { "SETVAR", CMD_L_TYPE_SUBCMD }, cif_err = { "ERR", CMD_L_TYPE_SUBCMD }, cif_dbg = { "DBG", CMD_L_TYPE_NULL };static const struct cmdinfo *cmdinfo[128] = {/*00*/ &cif_null, &cif_null, &cif_null, &cif_null, &cif_null, &cif_null, &cif_null, &cif_null, &cif_null, &cif_null, &cif_null, &cif_null, &cif_null, &cif_null, &cif_null, &cif_null,/*10*/ &cif_wdsnd, &cif_wdreq, &cif_null, &cif_null, &cif_null, &cif_null, &cif_null, &cif_null, &cif_null, &cif_null, &cif_null, &cif_null, &cif_null, &cif_null, &cif_null, &cif_null,/*20*/ &cif_bksnd, &cif_bkreq, &cif_null, &cif_bkyld, &cif_bksndp, &cif_bkreqp, &cif_null, &cif_null, &cif_null, &cif_null, &cif_null, &cif_null, &cif_null, &cif_null, &cif_null, &cif_null,/*30*/ &cif_tctl, &cif_null, &cif_null, &cif_null, &cif_null, &cif_null, &cif_null, &cif_null, &cif_null, &cif_null, &cif_null, &cif_null, &cif_null, &cif_null, &cif_null, &cif_null,/*40*/ &cif_mmap, &cif_null, &cif_null, &cif_null, &cif_null, &cif_null, &cif_null, &cif_null, &cif_null, &cif_null, &cif_null, &cif_null, &cif_null, &cif_null, &cif_null, &cif_null,/*50*/ &cif_wdt, &cif_runlevel, &cif_pm, &cif_null, &cif_null, &cif_null, &cif_null, &cif_null, &cif_null, &cif_null, &cif_null, &cif_null, &cif_null, &cif_null, &cif_null, &cif_null,/*60*/ &cif_tcfg, &cif_null, &cif_tadd, &cif_tdel, &cif_null, &cif_tstop, &cif_null, &cif_null, &cif_null, &cif_null, &cif_null, &cif_null, &cif_null, &cif_null, &cif_null, &cif_null,/*70*/ &cif_dspcfg, &cif_null, &cif_regrw, &cif_null, &cif_getvar, &cif_setvar, &cif_null, &cif_null, &cif_err, &cif_dbg, &cif_null, &cif_null, &cif_null, &cif_null, &cif_null, &cif_null};/* * */char *cmd_name(unsigned char cmd_h){ return cmdinfo[cmd_h]->name;}#define RLCMD(nm) OMAP_DSP_MBCMD_RUNLEVEL_##nm#define PMCMD(nm) OMAP_DSP_MBCMD_PM_##nm#define CFGCMD(nm) OMAP_DSP_MBCMD_DSPCFG_##nm#define REGCMD(nm) OMAP_DSP_MBCMD_REGRW_##nm#define VICMD(nm) OMAP_DSP_MBCMD_VARID_##nm#define EID(nm) OMAP_DSP_EID_##nmchar *subcmd_name(unsigned char cmd_h, unsigned char cmd_l){ char *s; switch (cmd_h) { case MBCMD(RUNLEVEL): s = (cmd_l == RLCMD(USER)) ? "USER": (cmd_l == RLCMD(SUPER)) ? "SUPER": (cmd_l == RLCMD(RECOVERY)) ? "RECOVERY": NULL; break; case MBCMD(PM): s = (cmd_l == PMCMD(DISABLE)) ? "DISABLE": (cmd_l == PMCMD(ENABLE)) ? "ENABLE": NULL; break; case MBCMD(DSPCFG): { unsigned char cfgc = cmd_l & 0x7f; s = (cfgc == CFGCMD(REQ)) ? "REQ": (cfgc == CFGCMD(SYSADRH)) ? "SYSADRH": (cfgc == CFGCMD(SYSADRL)) ? "SYSADRL": (cfgc == CFGCMD(PROTREV)) ? "PROTREV": NULL; break; } case MBCMD(REGRW): s = (cmd_l == REGCMD(MEMR)) ? "MEMR": (cmd_l == REGCMD(MEMW)) ? "MEMW": (cmd_l == REGCMD(IOR)) ? "IOR": (cmd_l == REGCMD(IOW)) ? "IOW": (cmd_l == REGCMD(DATA)) ? "DATA": NULL; break; case MBCMD(GETVAR): case MBCMD(SETVAR): s = (cmd_l == VICMD(ICRMASK)) ? "ICRMASK": NULL; break; case MBCMD(ERR): s = (cmd_l == EID(BADTID)) ? "BADTID": (cmd_l == EID(BADTCN)) ? "BADTCN": (cmd_l == EID(BADBID)) ? "BADBID": (cmd_l == EID(BADCNT)) ? "BADCNT": (cmd_l == EID(NOTLOCKED)) ? "NOTLOCKED": (cmd_l == EID(STVBUF)) ? "STVBUF": (cmd_l == EID(BADADR)) ? "BADADR": (cmd_l == EID(BADTCTL)) ? "BADTCTL": (cmd_l == EID(BADPARAM)) ? "BADPARAM": (cmd_l == EID(FATAL)) ? "FATAL": (cmd_l == EID(NOMEM)) ? "NOMEM": (cmd_l == EID(NORES)) ? "NORES": (cmd_l == EID(IPBFULL)) ? "IPBFULL": (cmd_l == EID(TASKNOTRDY)) ? "TASKNOTRDY": (cmd_l == EID(TASKBSY)) ? "TASKBSY": (cmd_l == EID(TASKERR)) ? "TASKERR": (cmd_l == EID(BADCFGTYP)) ? "BADCFGTYP": (cmd_l == EID(DEBUG)) ? "DEBUG": (cmd_l == EID(BADSEQ)) ? "BADSEQ": (cmd_l == EID(BADCMD)) ? "BADCMD": NULL; break; default: s = NULL; } return s;}#ifdef CONFIG_OMAP_DSP_MBLOG#define MBLOG_DEPTH 256struct mblogent { unsigned long jiffies; unsigned short cmd; unsigned short data; char dir;};static struct { int wp; unsigned long cnt, cnt_ad, cnt_da; struct mblogent ent[MBLOG_DEPTH];} mblog = { .wp = 0, .cnt = 0, .cnt_ad = 0, .cnt_da = 0,};void omap_dsp_mblog_add(unsigned short cmd, unsigned short data, char dir){ struct mblogent *ent; disable_irq(INT_D2A_MB1); ent = &mblog.ent[mblog.wp]; ent->jiffies = jiffies; ent->cmd = cmd; ent->data = data; ent->dir = dir; if (mblog.cnt < 0xffffffff) mblog.cnt++; switch (dir) { case MBLOG_DIR_AD: if (mblog.cnt_ad < 0xffffffff) mblog.cnt_ad++; break; case MBLOG_DIR_DA: if (mblog.cnt_da < 0xffffffff) mblog.cnt_da++; break; } if (++mblog.wp == MBLOG_DEPTH) mblog.wp = 0; enable_irq(INT_D2A_MB1);}#ifdef CONFIG_PROC_FSstatic int omap_dsp_proc_mblog_read(char *page, char **start, off_t off, int count, int *eof, void *data){ char *out; int len; int wp; int i; disable_irq(INT_D2A_MB1); wp = mblog.wp; out = page; out += sprintf(out, "log count:%ld / ARM->DSP:%ld, DSP->ARM:%ld\n", mblog.cnt, mblog.cnt_ad, mblog.cnt_da); if (mblog.cnt == 0) goto done; out += sprintf(out, " ARM->DSP ARM<-DSP\n"); out += sprintf(out, "jiffies cmd data cmd data\n"); i = (mblog.cnt >= MBLOG_DEPTH) ? wp : 0; do { struct mblogent *ent = &mblog.ent[i]; unsigned char seq = mb_sqbit(ent->cmd); unsigned char cmd_h = mb_cmd_h(ent->cmd); unsigned char cmd_l = mb_cmd_l(ent->cmd); const struct cmdinfo *ci = cmdinfo[cmd_h]; out += sprintf(out, (ent->dir == MBLOG_DIR_AD)? "%08lx %04x %04x seq=%d": "%08lx %04x %04x seq=%d", ent->jiffies, ent->cmd, ent->data, seq); switch (ci->cmd_l_type) { case CMD_L_TYPE_SUBCMD: { char *subname; subname = subcmd_name(cmd_h, cmd_l); out += sprintf(out, " %s:%s\n", ci->name, subname ? subname : "Unknown"); break; } case CMD_L_TYPE_TID: out += sprintf(out, " %s:task %d\n", ci->name, cmd_l); break; case CMD_L_TYPE_NULL: out += sprintf(out, " %s\n", ci->name); break; } if (++i == MBLOG_DEPTH) i = 0; } while (i != wp);done: enable_irq(INT_D2A_MB1); len = out - page; len -= off; if (len < count) { *eof = 1; if (len <= 0) return 0; } else { len = count; } *start = page + off; return len;}void __init omap_dsp_create_mblog_proc(void){ struct proc_dir_entry *ent; ent = create_proc_read_entry("mblog", 0, procdir_dsp, omap_dsp_proc_mblog_read, NULL); if (ent == NULL) { printk(KERN_ERR "omapdsp: failed to register proc device: mblog\n"); }}void omap_dsp_remove_mblog_proc(void){ remove_proc_entry("mblog", procdir_dsp);}#endif /* CONFIG_PROC_FS */#endif /* CONFIG_OMAP_DSP_MBLOG */#ifdef CONFIG_OMAP_DSP_MBCMD_VERBOSEvoid omap_dsp_mblog_printcmd(unsigned short cmd, unsigned short data, char dir){ unsigned char seq = mb_sqbit(cmd); unsigned char cmd_h = mb_cmd_h(cmd); unsigned char cmd_l = mb_cmd_l(cmd); const struct cmdinfo *ci = cmdinfo[cmd_h]; char *dir_str; char *subname; dir_str = (dir == MBLOG_DIR_AD) ? "sending" : "receiving"; switch (ci->cmd_l_type) { case CMD_L_TYPE_SUBCMD: if ((subname = subcmd_name(cmd_h, cmd_l)) == NULL) subname = "Unknown"; printk(KERN_DEBUG "mailbox: %s seq=%d, cmd=0x%04x(%s:%s), data=0x%04x\n", dir_str, seq, cmd, ci->name, subname, data); break; case CMD_L_TYPE_TID: printk(KERN_DEBUG "mailbox: %s seq=%d, cmd=0x%04x(%s:task %d), data=0x%04x\n", dir_str, seq, cmd, ci->name, cmd_l, data); break; case CMD_L_TYPE_NULL: printk(KERN_DEBUG "mailbox: %s seq=%d, cmd=0x%04x(%s), data=0x%04x\n", dir_str, seq, cmd, ci->name, data); break; }}#endif /* CONFIG_OMAP_DSP_MBCMD_VERBOSE */void __init omap_dsp_mblog_init(void){#ifdef CONFIG_OMAP_DSP_MBLOG#ifdef CONFIG_PROC_FS omap_dsp_create_mblog_proc();#endif#endif}void omap_dsp_mblog_exit(void){#ifdef CONFIG_OMAP_DSP_MBLOG#ifdef CONFIG_PROC_FS omap_dsp_remove_mblog_proc();#endif#endif}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?