⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 debug.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 5 页
字号:
#include "platform.h"#include "pc.h"#include "di_defs.h"#include "debug_if.h"#include "divasync.h"#include "kst_ifc.h"#include "maintidi.h"#include "man_defs.h"/*  LOCALS  */#define DBG_MAGIC (0x47114711L)static void DI_register (void *arg);static void DI_deregister (pDbgHandle hDbg);static void DI_format (int do_lock, word id, int type, char *format, va_list argument_list);static void DI_format_locked   (word id, int type, char *format, va_list argument_list);static void DI_format_old (word id, char *format, va_list ap) { }static void DiProcessEventLog (unsigned short id, unsigned long msgID, va_list ap) { }static void single_p (byte * P, word * PLength, byte Id);static void diva_maint_xdi_cb (ENTITY* e);static word SuperTraceCreateReadReq (byte* P, const char* path);static int diva_mnt_cmp_nmbr (const char* nmbr);static void diva_free_dma_descriptor (IDI_CALL request, int nr);static int diva_get_dma_descriptor (IDI_CALL request, dword *dma_magic);void diva_mnt_internal_dprintf (dword drv_id, dword type, char* p, ...);static dword MaxDumpSize = 256 ;static dword MaxXlogSize = 2 + 128 ;static char  TraceFilter[DIVA_MAX_SELECTIVE_FILTER_LENGTH+1];static int TraceFilterIdent   = -1;static int TraceFilterChannel = -1;typedef struct _diva_maint_client {  dword       sec;  dword       usec;  pDbgHandle  hDbg;  char        drvName[128];  dword       dbgMask;  dword       last_dbgMask;  IDI_CALL    request;  _DbgHandle_ Dbg;  int         logical;  int         channels;  diva_strace_library_interface_t* pIdiLib;  BUFFERS     XData;  char        xbuffer[2048+512];  byte*       pmem;  int         request_pending;  int         dma_handle;} diva_maint_client_t;static diva_maint_client_t clients[MAX_DESCRIPTORS];static void diva_change_management_debug_mask (diva_maint_client_t* pC, dword old_mask);static void diva_maint_error (void* user_context,                              diva_strace_library_interface_t* hLib,                              int Adapter,                              int error,                              const char* file,                              int line);static void diva_maint_state_change_notify (void* user_context,                                            diva_strace_library_interface_t* hLib,                                            int Adapter,                                            diva_trace_line_state_t* channel,                                            int notify_subject);static void diva_maint_trace_notify (void* user_context,                                     diva_strace_library_interface_t* hLib,                                     int Adapter,                                     void* xlog_buffer,                                     int length);typedef struct MSG_QUEUE {	dword	Size;		/* total size of queue (constant)	*/	byte	*Base;		/* lowest address (constant)		*/	byte	*High;		/* Base + Size (constant)		*/	byte	*Head;		/* first message in queue (if any)	*/	byte	*Tail;		/* first free position			*/	byte	*Wrap;		/* current wraparound position 		*/	dword	Count;		/* current no of bytes in queue		*/} MSG_QUEUE;typedef struct MSG_HEAD {	volatile dword	Size;		/* size of data following MSG_HEAD	*/#define	MSG_INCOMPLETE	0x8000	/* ored to Size until queueCompleteMsg 	*/} MSG_HEAD;#define queueCompleteMsg(p) do{ ((MSG_HEAD *)p - 1)->Size &= ~MSG_INCOMPLETE; }while(0)#define queueCount(q)	((q)->Count)#define MSG_NEED(size) \	( (sizeof(MSG_HEAD) + size + sizeof(dword) - 1) & ~(sizeof(dword) - 1) )static void queueInit (MSG_QUEUE *Q, byte *Buffer, dword sizeBuffer) {	Q->Size = sizeBuffer;	Q->Base = Q->Head = Q->Tail = Buffer;	Q->High = Buffer + sizeBuffer;	Q->Wrap = NULL;	Q->Count= 0;}static byte *queueAllocMsg (MSG_QUEUE *Q, word size) {	/* Allocate 'size' bytes at tail of queue which will be filled later   * directly with callers own message header info and/or message.   * An 'alloced' message is marked incomplete by oring the 'Size' field   * with MSG_INCOMPLETE.   * This must be reset via queueCompleteMsg() after the message is filled.   * As long as a message is marked incomplete queuePeekMsg() will return   * a 'queue empty' condition when it reaches such a message.  */	MSG_HEAD *Msg;	word need = MSG_NEED(size);	if (Q->Tail == Q->Head) {		if (Q->Wrap || need > Q->Size) {			return NULL; /* full */		}		goto alloc; /* empty */	}		if (Q->Tail > Q->Head) {		if (Q->Tail + need <= Q->High) goto alloc; /* append */		if (Q->Base + need > Q->Head) {			return NULL; /* too much */		}		/* wraparound the queue (but not the message) */		Q->Wrap = Q->Tail;		Q->Tail = Q->Base;		goto alloc;	}	if (Q->Tail + need > Q->Head) {		return NULL; /* too much */	}alloc:	Msg = (MSG_HEAD *)Q->Tail;	Msg->Size = size | MSG_INCOMPLETE;	Q->Tail	 += need;	Q->Count += size;	return ((byte*)(Msg + 1));}static void queueFreeMsg (MSG_QUEUE *Q) {/* Free the message at head of queue */	word size = ((MSG_HEAD *)Q->Head)->Size & ~MSG_INCOMPLETE;	Q->Head  += MSG_NEED(size);	Q->Count -= size;	if (Q->Wrap) {		if (Q->Head >= Q->Wrap) {			Q->Head = Q->Base;			Q->Wrap = NULL;		}	} else if (Q->Head >= Q->Tail) {		Q->Head = Q->Tail = Q->Base;	}}static byte *queuePeekMsg (MSG_QUEUE *Q, word *size) {	/* Show the first valid message in queue BUT DON'T free the message.   * After looking on the message contents it can be freed queueFreeMsg()   * or simply remain in message queue.  */	MSG_HEAD *Msg = (MSG_HEAD *)Q->Head;	if (((byte *)Msg == Q->Tail && !Q->Wrap) ||	    (Msg->Size & MSG_INCOMPLETE)) {		return NULL;	} else {		*size = Msg->Size;		return ((byte *)(Msg + 1));	}}/*  Message queue header  */static MSG_QUEUE*          dbg_queue;static byte*               dbg_base;static int                 external_dbg_queue;static diva_os_spin_lock_t dbg_q_lock;static diva_os_spin_lock_t dbg_adapter_lock;static int                 dbg_q_busy;static volatile dword      dbg_sequence;static dword               start_sec;static dword               start_usec;/*	INTERFACE:    Initialize run time queue structures.    base:    base of the message queue    length:  length of the message queue    do_init: perfor queue reset    return:  zero on success, -1 on error  */int diva_maint_init (byte* base, unsigned long length, int do_init) {  if (dbg_queue || (!base) || (length < (4096*4))) {    return (-1);  }  TraceFilter[0]     =  0;  TraceFilterIdent   = -1;  TraceFilterChannel = -1;  dbg_base = base;  diva_os_get_time (&start_sec, &start_usec);  *(dword*)base  = (dword)DBG_MAGIC; /* Store Magic */  base   += sizeof(dword);  length -= sizeof(dword);  *(dword*)base = 2048; /* Extension Field Length */  base   += sizeof(dword);  length -= sizeof(dword);  strcpy (base, "KERNEL MODE BUFFER\n");  base   += 2048;  length -= 2048;  *(dword*)base = 0; /* Terminate extension */  base   += sizeof(dword);  length -= sizeof(dword);  *(void**)base  =  (void*)(base+sizeof(void*)); /* Store Base  */  base   += sizeof(void*);  length -= sizeof(void*);  dbg_queue = (MSG_QUEUE*)base;  queueInit (dbg_queue, base + sizeof(MSG_QUEUE), length - sizeof(MSG_QUEUE) - 512);  external_dbg_queue = 0;  if (!do_init) {    external_dbg_queue = 1; /* memory was located on the external device */  }	if (diva_os_initialize_spin_lock (&dbg_q_lock, "dbg_init")) {    dbg_queue = NULL;    dbg_base = NULL;    external_dbg_queue = 0;		return (-1);  }	if (diva_os_initialize_spin_lock (&dbg_adapter_lock, "dbg_init")) {    diva_os_destroy_spin_lock(&dbg_q_lock, "dbg_init");    dbg_queue = NULL;    dbg_base = NULL;    external_dbg_queue = 0;		return (-1);  }  return (0);}/*  INTERFACE:    Finit at unload time    return address of internal queue or zero if queue    was external  */void* diva_maint_finit (void) {  void* ret = (void*)dbg_base;  int i;  dbg_queue = NULL;  dbg_base  = NULL;  if (ret) {    diva_os_destroy_spin_lock(&dbg_q_lock, "dbg_finit");    diva_os_destroy_spin_lock(&dbg_adapter_lock, "dbg_finit");  }  if (external_dbg_queue) {    ret = NULL;  }  external_dbg_queue = 0;  for (i = 1; i < (sizeof(clients)/sizeof(clients[0])); i++) {    if (clients[i].pmem) {      diva_os_free (0, clients[i].pmem);    }  }  return (ret);}/*  INTERFACE:    Return amount of messages in debug queue  */dword diva_dbg_q_length (void) {	return (dbg_queue ? queueCount(dbg_queue)	: 0);}/*  INTERFACE:    Lock message queue and return the pointer to the first    entry.  */diva_dbg_entry_head_t* diva_maint_get_message (word* size,                                               diva_os_spin_lock_magic_t* old_irql) {  diva_dbg_entry_head_t*     pmsg = NULL;  diva_os_enter_spin_lock (&dbg_q_lock, old_irql, "read");  if (dbg_q_busy) {    diva_os_leave_spin_lock (&dbg_q_lock, old_irql, "read_busy");    return NULL;  }  dbg_q_busy = 1;  if (!(pmsg = (diva_dbg_entry_head_t*)queuePeekMsg (dbg_queue, size))) {    dbg_q_busy = 0;    diva_os_leave_spin_lock (&dbg_q_lock, old_irql, "read_empty");  }  return (pmsg);}/*  INTERFACE:    acknowledge last message and unlock queue  */void diva_maint_ack_message (int do_release,                             diva_os_spin_lock_magic_t* old_irql) {	if (!dbg_q_busy) {		return;	}	if (do_release) {		queueFreeMsg (dbg_queue);	}	dbg_q_busy = 0;  diva_os_leave_spin_lock (&dbg_q_lock, old_irql, "read_ack");}/*  INTERFACE:    PRT COMP function used to register    with MAINT adapter or log in compatibility    mode in case older driver version is connected too  */void diva_maint_prtComp (char *format, ...) {  void    *hDbg;  va_list ap;  if (!format)    return;  va_start(ap, format);  /*    register to new log driver functions   */  if ((format[0] == 0) && ((unsigned char)format[1] == 255)) {    hDbg = va_arg(ap, void *); /* ptr to DbgHandle */    DI_register (hDbg);  }  va_end (ap);}static void DI_register (void *arg) {  diva_os_spin_lock_magic_t old_irql;  dword sec, usec;  pDbgHandle  	hDbg ;  int id, free_id = -1, best_id = 0;    diva_os_get_time (&sec, &usec);	hDbg = (pDbgHandle)arg ;  /*    Check for bad args, specially for the old obsolete debug handle    */  if ((hDbg == NULL) ||      ((hDbg->id == 0) && (((_OldDbgHandle_ *)hDbg)->id == -1)) ||      (hDbg->Registered != 0)) {		return ;  }  diva_os_enter_spin_lock (&dbg_q_lock, &old_irql, "register");  for (id = 1; id < (sizeof(clients)/sizeof(clients[0])); id++) {    if (clients[id].hDbg == hDbg) {      /*        driver already registered        */      diva_os_leave_spin_lock (&dbg_q_lock, &old_irql, "register");      return;    }    if (clients[id].hDbg) { /* slot is busy */      continue;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -