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

📄 smp.c

📁 Linux下的类似softice的调试工具
💻 C
字号:
/****************************************************************************** * * Copyright (c) 2003 Gerhard W. Gruber * * PROJECT: pICE * $Source: /cvsroot/pice/pice/module/smp.c,v $ * $Revision: 1.3 $ * $Date: 2004/02/17 23:07:37 $ * $Author: lightweave $ * $Name:  $ * * $Log: smp.c,v $ * Revision 1.3  2004/02/17 23:07:37  lightweave * * Improved the DEBUG facillity and replaced the configuration handler with a * new code which now can read MS Windows INI style files. See CHANGES.txt for * more details. * Also added a macro which prevents compiling for kernels before 2.4.19. * * Revision 1.2  2003/06/18 22:00:22  lightweave * DEBUG and DEBUG_SERIAL added * * *****************************************************************************/static char *ident = "$Header: /cvsroot/pice/pice/module/smp.c,v 1.3 2004/02/17 23:07:37 lightweave Exp $";/*++Copyright (c) 1998-2001 Klaus P. GerlicherModule Name:    smp.cAbstract:    symmetric multi processor stuffEnvironment:    LINUX 2.2.X    Kernel mode onlyAuthor:     Klaus P. GerlicherRevision History:    22-Oct-2001:	createdCopyright notice:  This file may be distributed under the terms of the GNU Public License.--*/////////////////////////////////////////////////////// INCLUDES////#include "remods.h"#include <asm/io.h>#include <asm/smp.h>#include "precomp.h"#ifdef CONFIG_SMPstatic volatile ULONG ulWait[PICE_MAX_CPUS] = {0,};// something we want a CPU to do while idleingstatic volatile ULONG ulCmdForThisCPU[PICE_MAX_CPUS] = {0,};struct task_struct *current_for_cpu[PICE_MAX_CPUS] = {0,};EXCEPTION_FRAME *frame_for_cpu[PICE_MAX_CPUS];CPUID_S cpuid_for_cpu[PICE_MAX_CPUS];// this only shows that CPUs are spinning volatile ULONG ulSpinCount[PICE_MAX_CPUS] = {0,};PUCHAR pLocalApic = NULL;void GetCpuId(void);#endif // CONFIG_SMP#if LINUX_VERSION_CODE < 0x020400  // kernels below 2.4.0 don't export thisstatic int (*pice_smp_call_function)(void (*function)(void*),void* info,int retry,int wait);#endif // LINUX_VERSION_CODE < 0x020400	 //************************************************************************* // ProcessorsIdleLoop() // //************************************************************************* void ProcessorsIdleLoop(EXCEPTION_FRAME* pFrame){#ifdef CONFIG_SMP	ULONG ulLocalFlags;	ULONG this = current->processor;	ENTER_FUNC();	save_flags(ulLocalFlags);	cli();	ulSpinCount[this] = 0;	// loop until ulWait goes high	// we could let the other processor do any work we want here, maybe implement that someday	while(!ulWait[this])	{ 		//DPRINT(PICE_DEBUG, DBT_SMP, DBL_INFO, "LoopProcessorsLoop(): spinning...\n");		// increment spin counter, we can see this incrementing in shell with "CPU" command		ulSpinCount[this]++;		switch(ulCmdForThisCPU[this])		{			case SMP_CPU_GET_CPU_INFO:				DPRINT(PICE_DEBUG, DBT_SMP, DBL_INFO, "SMP_CPU_GET_CPU_INFO on CPU #%u\n",this);				current_for_cpu[this] = current;				frame_for_cpu[this] = pFrame;				GetCpuId();				ulCmdForThisCPU[this] = SMP_CPU_DONE;				DPRINT(PICE_DEBUG, DBT_SMP, DBL_INFO, "after SMP_CPU_GET_CPU_INFO on CPU #%u\n",this);				break;			case SMP_CPU_DONE:			default:				break;		}	}	// well, who knows what for	FlushCacheAndTLB();    restore_flags(ulLocalFlags);	LEAVE_FUNC();#endif}//************************************************************************* // CallOtherCPU() // //************************************************************************* void CallOtherCPU(ULONG ulCmd){#ifdef CONFIG_SMP	ULONG i;	ENTER_FUNC();	DPRINT(PICE_DEBUG, DBT_SMP, DBL_INFO, "sending other processors cmd %x\n", ulCmd);	// tell other CPUs to provide stuff	for(i = 0; i < smp_num_cpus; i++)	{	   if(i != current->processor)	   {	      ulCmdForThisCPU[i] = ulCmd;	   }	}	DPRINT(PICE_DEBUG, DBT_SMP, DBL_INFO, "waiting for other processors\n");	// wait for data	for(i = 0; i < smp_num_cpus; i++)	{	   if(i != current->processor)	   {	     while(ulCmdForThisCPU[i] != SMP_CPU_DONE)	       __asm__ __volatile__("nop");	   }	}	LEAVE_FUNC();#endif // CONFIG_SMP}//************************************************************************* // LoopProcessorLoop() // //************************************************************************* #ifdef CONFIG_SMPstatic void LoopProcessorLoop(void* info){  void Debugger2ndProcessor(void);  Debugger2ndProcessor();}#endif // CONFIG_SMP//************************************************************************* // LoopProcessors() // //************************************************************************* void LoopProcessors(void){#ifdef CONFIG_SMP	ULONG i;	ENTER_FUNC();	// tell others to loop	for(i = 0; i < smp_num_cpus; i++)	{	   // loop variable	   ulWait[i] = 0;	}	// call other CPUs, retry until ready and don't wait to finish	// as all others will spin until return conditions are met#if LINUX_VERSION_CODE < 0x020400  	DPRINT(PICE_DEBUG, DBT_SMP, DBL_INFO, "pice_smp_call_function = %.8X\n",pice_smp_call_function);	if(pice_smp_call_function)		(*pice_smp_call_function)(LoopProcessorLoop, NULL, 1, 0);#else // LINUX_VERSION_CODE < 0x020400			smp_call_function(LoopProcessorLoop, NULL, 1, 0);#endif // LINUX_VERSION_CODE < 0x020400	 	LEAVE_FUNC();#endif // CONFIG_SMP}//************************************************************************* // UnloopProcessors() // //************************************************************************* void UnloopProcessors(void){#ifdef CONFIG_SMP	ULONG i;	// tell others to unloop	for(i=0;i<smp_num_cpus;i++)		ulWait[i] = 1;#endif // CONFIG_SMP}//************************************************************************* // GetProcessor() // //************************************************************************* ULONG GetProcessor(void){  return smp_processor_id();}//************************************************************************* // FlushCacheAndTLBAllCpus() // //************************************************************************* #ifdef CONFIG_SMPstatic void CallFlushCacheAndTLB(void* info){  FlushCacheAndTLB();}#endif // CONFIG_SMP//************************************************************************* // FlushCacheAndTLBAllCpus() // //************************************************************************* void FlushCacheAndTLBAllCpus(void){	ENTER_FUNC();	// call other CPUs, retry until ready and wait#if LINUX_VERSION_CODE < 0x020400  	DPRINT(PICE_DEBUG, DBT_SMP, DBL_INFO, "pice_smp_call_function = %.8X\n",pice_smp_call_function);	if(pice_smp_call_function)		(*pice_smp_call_function)(CallFlushCacheAndTLB, NULL, 1, 0);#else // LINUX_VERSION_CODE < 0x020400			smp_call_function(CallFlushCacheAndTLB, NULL, 1, 0);#endif // LINUX_VERSION_CODE < 0x020400	 	FlushCacheAndTLB();	LEAVE_FUNC();}//************************************************************************* // CallDisableHWBreakpoints() // //************************************************************************* static void CallDisableHWBreakpoints(void* info){    // disable HW breakpoints	__asm__ __volatile__(	   "xorl %%eax,%%eax\n"	   "mov %%eax,%%dr6\n"	   "mov %%eax,%%dr7\n"	   "mov %%dr0,%%eax\n"	   "mov %%dr1,%%eax\n"	   "mov %%dr2,%%eax\n"	   "mov %%dr3,%%eax\n"	:::"eax"		); }//************************************************************************* // DisableHWBreakpointsAllCpus() // //************************************************************************* void DisableHWBreakpointsAllCpus(void){	ENTER_FUNC();	// call other CPUs, retry until ready and wait#if LINUX_VERSION_CODE < 0x020400  	DPRINT(PICE_DEBUG, DBT_SMP, DBL_INFO, "pice_smp_call_function = %.8X\n",pice_smp_call_function);	if(pice_smp_call_function)		(*pice_smp_call_function)(CallDisableHWBreakpoints, NULL, 1, 0);#else // LINUX_VERSION_CODE < 0x020400			smp_call_function(CallDisableHWBreakpoints, NULL, 1, 0);#endif // LINUX_VERSION_CODE < 0x020400	 	CallDisableHWBreakpoints(NULL);	LEAVE_FUNC();}//************************************************************************* // GetCpuId() // //************************************************************************* void GetCpuId(void){#ifdef CONFIG_SMP	PULONG p;	ULONG junk;	p = (PULONG)&cpuid_for_cpu[current->processor].vendor;	memset(cpuid_for_cpu[current->processor].vendor,0,12);	cpuid_for_cpu[current->processor].vendor[12] = 0;	cpuid(0x00000000,&cpuid_for_cpu[current->processor].max_cpuid,&p[0],&p[2],&p[1]);	cpuid(0x00000001,(PULONG)&cpuid_for_cpu[current->processor].signature,&junk,&junk,&junk);	p = (PULONG)&cpuid_for_cpu[current->processor].cpu_name;	memset(cpuid_for_cpu[current->processor].cpu_name,0,48);	cpuid_for_cpu[current->processor].cpu_name[48] = 0;	if(cpuid_for_cpu[current->processor].max_cpuid < 0x80000004)		return;	cpuid(0x80000002,&p[0],&p[1],&p[2],&p[3]);	cpuid(0x80000003,&p[4],&p[5],&p[6],&p[7]);	cpuid(0x80000004,&p[8],&p[9],&p[10],&p[11]);#endif // CONFIG_SMP}//************************************************************************* // InitSmp() // //************************************************************************* void InitSmp(void){	 ENTER_FUNC();#ifdef CONFIG_SMP#if LINUX_VERSION_CODE < 0x020400  	// try to find SMP smp_call_function     ScanSystemMap("smp_call_function",(PULONG)&pice_smp_call_function);	DPRINT(PICE_DEBUG, DBT_SMP, DBL_INFO, "smp_call_function @ %.8X\n",pice_smp_call_function);#endif // LINUX_VERSION_CODE < 0x020400	 	pLocalApic = ioremap(0xFFE00000,PAGE_SIZE);#endif // CONFIG_SMP   	LEAVE_FUNC();}//************************************************************************* // ExitSmp() // //************************************************************************* void ExitSmp(void){#ifdef CONFIG_SMP	if(pLocalApic)		iounmap(pLocalApic);#endif // CONFIG_SMP}

⌨️ 快捷键说明

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