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

📄 ml_sn_intr.c

📁 上传linux-jx2410的源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
    }    /* XXX - This will have to change to deal with various SN errors. */    panic( "exception on IDLE stack "	    "ep:0x%x epc:0x%x cause:0x%w32x sp:0x%x badvaddr:0x%x",	    ep, epc, cause, sp, getbadvaddr());    /* NOTREACHED */}/* * earlynofault - handle very early global faults - usually just while *      sizing memory * Returns: 1 if should do nofault *          0 if not *//* ARGSUSED */intearlynofault(eframe_t *ep, uint code){	switch(code) {	case EXC_DBE:		return(1);	default:		return(0);	}}/* ARGSUSED */static voidcpuintr(void *arg1, void *arg2){#if RTE	static int rte_intrdebug = 1;#endif	/*	 * Frame Scheduler	 */	LOG_TSTAMP_EVENT(RTMON_INTR, TSTAMP_EV_CPUINTR, NULL, NULL,			 NULL, NULL);	/*	 * Hardware clears the IO interrupts, but we need to clear software-	 * generated interrupts.	 */	LOCAL_HUB_CLR_INTR(CPU_ACTION_A + cputolocalslice(cpuid()));#if 0	/* XXX - Handle error interrupts. */	if (error_intr_reason)		error_intr();#endif /* 0 */	/*	 * If we're headed for panicspin and it is due to a NMI, save the	 * eframe in the NMI area	 */	if (private.p_va_panicspin && nmied) {		caddr_t	nmi_save_area;		nmi_save_area = (caddr_t) (TO_UNCAC(TO_NODE(			cputonasid(cpuid()), IP27_NMI_EFRAME_OFFSET)) + 			cputoslice(cpuid()) * IP27_NMI_EFRAME_SIZE);		bcopy((caddr_t) arg2, nmi_save_area, sizeof(eframe_t));	}	doacvec();#if RTE	if (private.p_flags & PDAF_ISOLATED && !rte_intrdebug)		goto end_cpuintr;#endif	doactions();#if RTEend_cpuintr:#endif	LOG_TSTAMP_EVENT(RTMON_INTR, TSTAMP_EV_INTREXIT, TSTAMP_EV_CPUINTR, NULL, NULL, NULL);}voidinstall_cpuintr(cpuid_t cpu){	int		intr_bit = CPU_ACTION_A + cputolocalslice(cpu);	if (intr_connect_level(cpu, intr_bit, INTPEND0_MAXMASK,				(intr_func_t) cpuintr, NULL, NULL))		panic("install_cpuintr: Can't connect interrupt.");}#endif /* BRINGUP */#ifdef DEBUG_INTR_TSTAMP/* We allocate an array, but only use element number 64.  This guarantees that * the entry is in a cacheline by itself. */#define DINTR_CNTIDX	32#define DINTR_TSTAMP1	48#define	DINTR_TSTAMP2	64volatile long long dintr_tstamp_cnt[128];int dintr_debug_output=0;extern void idbg_tstamp_debug(void);#ifdef SPLDEBUGextern void idbg_splx_log(int);#endif#if DEBUG_INTR_TSTAMP_DEBUGint dintr_enter_symmon=1000;	/* 1000 microseconds is 1 millisecond */#endif#ifndef BRINGUP/* ARGSUSED */static voidcpulatintr(void *arg){	/*	 * Hardware only clears IO interrupts so we have to clear our level	 * here.	 */	LOCAL_HUB_CLR_INTR(CPU_INTRLAT_A + cputolocalslice(cpuid()));#if DEBUG_INTR_TSTAMP_DEBUG	dintr_tstamp_cnt[DINTR_TSTAMP2] =  GET_LOCAL_RTC;	if ((dintr_tstamp_cnt[DINTR_TSTAMP2] - dintr_tstamp_cnt[DINTR_TSTAMP1])	    > dintr_enter_symmon) {#ifdef SPLDEBUG		extern int spldebug_log_off;		spldebug_log_off = 1;#endif /* SPLDEBUG */		debug("ring");#ifdef SPLDEBUG		spldebug_log_off = 0;#endif /* SPLDEBUG */	}#endif	dintr_tstamp_cnt[DINTR_CNTIDX]++;	return;}static int install_cpulat_first=0;voidinstall_cpulatintr(cpuid_t cpu){	int		intr_bit;	devfs_handle_t	cpuv = cpuid_to_vertex(cpu);	intr_bit = CPU_INTRLAT_A + cputolocalslice(cpu);	if (intr_bit != intr_reserve_level(cpu, intr_bit, II_THREADED,					   cpuv, "intrlat"))		panic( "install_cpulatintr: Can't reserve interrupt.");	if (intr_connect_level(cpu, intr_bit, INTPEND0_MAXMASK,				cpulatintr, NULL, NULL))		panic( "install_cpulatintr: Can't connect interrupt.");	if (!install_cpulat_first) {		install_cpulat_first++;		idbg_addfunc("tstamp_debug", (void (*)())idbg_tstamp_debug);#if defined(SPLDEBUG) || defined(SPLDEBUG_CPU_EVENTS)		idbg_addfunc("splx_log", (void (*)())idbg_splx_log);#endif /* SPLDEBUG || SPLDEBUG_CPU_EVENTS */	}}#endif /* BRINGUP */#endif /* DEBUG_INTR_TSTAMP */#ifndef BRINGUP/* ARGSUSED */static voiddbgintr(void *arg){	/*	 * Hardware only clears IO interrupts so we have to clear our level	 * here.	 */	LOCAL_HUB_CLR_INTR(N_INTPEND_BITS + DEBUG_INTR_A + cputolocalslice(cpuid()));	debug("zing");	return;}voidinstall_dbgintr(cpuid_t cpu){	int		intr_bit;	devfs_handle_t	cpuv = cpuid_to_vertex(cpu);	intr_bit = N_INTPEND_BITS + DEBUG_INTR_A + cputolocalslice(cpu);	if (intr_bit != intr_reserve_level(cpu, intr_bit, 1, cpuv, "DEBUG"))		panic("install_dbgintr: Can't reserve interrupt. "			" intr_bit %d" ,intr_bit);	if (intr_connect_level(cpu, intr_bit, INTPEND1_MAXMASK,				dbgintr, NULL, NULL))		panic("install_dbgintr: Can't connect interrupt.");#ifdef DEBUG_INTR_TSTAMP	/* Set up my interrupt latency test interrupt */	install_cpulatintr(cpu);#endif}/* ARGSUSED */static voidtlbintr(void *arg){	extern void tlbflush_rand(void);	/*	 * Hardware only clears IO interrupts so we have to clear our level	 * here.	 */	LOCAL_HUB_CLR_INTR(N_INTPEND_BITS + TLB_INTR_A + cputolocalslice(cpuid()));	tlbflush_rand();	return;}voidinstall_tlbintr(cpuid_t cpu){	int		intr_bit;	devfs_handle_t	cpuv = cpuid_to_vertex(cpu);	intr_bit = N_INTPEND_BITS + TLB_INTR_A + cputolocalslice(cpu);	if (intr_bit != intr_reserve_level(cpu, intr_bit, 1, cpuv, "DEBUG"))		panic("install_tlbintr: Can't reserve interrupt. "			" intr_bit %d" ,intr_bit);	if (intr_connect_level(cpu, intr_bit, INTPEND1_MAXMASK,				tlbintr, NULL, NULL))		panic("install_tlbintr: Can't connect interrupt.");}/* * Send an interrupt to all nodes.  Don't panic if we get an error. * Returns 1 if any exceptions occurred. */intprotected_broadcast(hubreg_t intrbit){	nodepda_t *npdap = private.p_nodepda;	int byte, bit, sn;	int error = 0;	extern int _wbadaddr_val(volatile void *, int, volatile int *);	/* Send rather than clear an interrupt. */	intrbit |= 0x100;		for (byte = 0; byte < NASID_MASK_BYTES; byte++) {		for (bit = 0; bit < 8; bit++) {			if (npdap->nasid_mask[byte] & (1 << bit)) {				nasid_t nasid = byte * 8 + bit;				for (sn=0; sn<NUM_SUBNODES; sn++) {					error += _wbadaddr_val(REMOTE_HUB_PI_ADDR(nasid,					      sn, PI_INT_PEND_MOD),					      sizeof(hubreg_t),					      (volatile int *)&intrbit);				}			}		}	}	return error;}/* * Poll the interrupt register to see if another cpu has asked us * to drop into the debugger (without lowering spl). */voidchkdebug(void){	if (LOCAL_HUB_L(PI_INT_PEND1) & (1L << (DEBUG_INTR_A + cputolocalslice(cpuid()))))		dbgintr((void *)NULL);}/* * Install special graphics interrupt. */voidinstall_gfxintr(cpuid_t cpu, ilvl_t swlevel, intr_func_t intr_func, void *intr_arg){	int intr_bit = GFX_INTR_A + cputolocalslice(cpu);	if (intr_connect_level(cpu, intr_bit, swlevel,				intr_func, intr_arg, NULL))		panic("install_gfxintr: Can't connect interrupt.");}/* * Install page migration interrupt handler. */voidhub_migrintr_init(cnodeid_t cnode){	cpuid_t cpu = cnodetocpu(cnode);	int intr_bit = INT_PEND0_BASELVL + PG_MIG_INTR;	if (numnodes == 1){		/* 		 * No migration with just one node..		 */		return;	}		if (cpu != -1) {		if (intr_connect_level(cpu, intr_bit, 0,			       (intr_func_t) migr_intr_handler, 0, (intr_func_t) migr_intr_prologue_handler))			panic( "hub_migrintr_init: Can't connect interrupt.");	}}/* * Cause all CPUs to stop by sending them each a DEBUG interrupt. * Parameter is actually a (cpumask_t *). */voiddebug_stop_all_cpus(void *stoplist){	int cpu;	ulong level;	for (cpu=0; cpu<maxcpus; cpu++) {		if (cpu == cpuid())			continue;		if (!cpu_enabled(cpu))		        continue;		/* "-1" is the old style parameter OR could be the new style		 * if no-one is currently stopped.  We only stop the		 * requested cpus, the others are already stopped (probably		 * at a breakpoint).		 */		if (((cpumask_t *)stoplist != (cpumask_t *)-1LL) &&		    (!CPUMASK_TSTB(*(cpumask_t*)stoplist, cpu)))			continue;		/*		 * CPU lslice A gets level DEBUG_INTR_A		 * CPU lslice B gets level DEBUG_INTR_B		 */		level = DEBUG_INTR_A + LOCALCPU(get_cpu_slice(cpu));		/*		 * Convert the compact hub number to the NASID to get the		 * correct part of the address space.  Then set the interrupt		 * bit associated with the CPU we want to send the interrupt		 * to.		 */		REMOTE_CPU_SEND_INTR(cpu, N_INTPEND_BITS + level);	}}#endif /* BRINGUP */struct hardwired_intr_s {	signed char level;	int flags;	char *name;} const hardwired_intr[] = {	{ INT_PEND0_BASELVL + RESERVED_INTR,	0,	"Reserved" },	{ INT_PEND0_BASELVL + GFX_INTR_A,	0, 	"Gfx A" },	{ INT_PEND0_BASELVL + GFX_INTR_B,	0, 	"Gfx B" },	{ INT_PEND0_BASELVL + PG_MIG_INTR,	II_THREADED, "Migration" },	{ INT_PEND0_BASELVL + UART_INTR,	II_THREADED, "Bedrock/L1" },	{ INT_PEND0_BASELVL + CC_PEND_A,	0,	"Crosscall A" },	{ INT_PEND0_BASELVL + CC_PEND_B,	0,	"Crosscall B" },	{ INT_PEND1_BASELVL + CLK_ERR_INTR,	II_ERRORINT, "Clock Error" },	{ INT_PEND1_BASELVL + COR_ERR_INTR_A,	II_ERRORINT, "Correctable Error A" },	{ INT_PEND1_BASELVL + COR_ERR_INTR_B,	II_ERRORINT, "Correctable Error B" },	{ INT_PEND1_BASELVL + MD_COR_ERR_INTR,	II_ERRORINT, "MD Correct. Error" },	{ INT_PEND1_BASELVL + NI_ERROR_INTR,	II_ERRORINT, "NI Error" },	{ INT_PEND1_BASELVL + NI_BRDCAST_ERR_A,	II_ERRORINT, "Remote NI Error"},	{ INT_PEND1_BASELVL + NI_BRDCAST_ERR_B,	II_ERRORINT, "Remote NI Error"},	{ INT_PEND1_BASELVL + MSC_PANIC_INTR,	II_ERRORINT, "MSC Panic" },	{ INT_PEND1_BASELVL + LLP_PFAIL_INTR_A,	II_ERRORINT, "LLP Pfail WAR" },	{ INT_PEND1_BASELVL + LLP_PFAIL_INTR_B,	II_ERRORINT, "LLP Pfail WAR" },	{ INT_PEND1_BASELVL + NACK_INT_A,	0, "CPU A Nack count == NACK_CMP" },	{ INT_PEND1_BASELVL + NACK_INT_B,	0, "CPU B Nack count == NACK_CMP" },	{ INT_PEND1_BASELVL + LB_ERROR,		0, "Local Block Error" },	{ INT_PEND1_BASELVL + XB_ERROR,		0, "Local XBar Error" },	{ -1, 0, (char *)NULL},};/* * Reserve all of the hardwired interrupt levels so they're not used as * general purpose bits later. */voidintr_reserve_hardwired(cnodeid_t cnode){	cpuid_t cpu;	int level;	int i;	char subnode_done[NUM_SUBNODES];	// cpu = cnodetocpu(cnode);	for (cpu = 0; cpu < smp_num_cpus; cpu++) {		if (cpuid_to_cnodeid(cpu) == cnode) {			break;		}	}	if (cpu == smp_num_cpus) cpu = CPU_NONE;	if (cpu == CPU_NONE) {		printk("Node %d has no CPUs", cnode);		return;	}	for (i=0; i<NUM_SUBNODES; i++)		subnode_done[i] = 0;	for (; cpu<smp_num_cpus && cpu_enabled(cpu) && cpuid_to_cnodeid(cpu) == cnode; cpu++) {		int which_subnode = cpuid_to_subnode(cpu);		if (subnode_done[which_subnode])			continue;		subnode_done[which_subnode] = 1;		for (i = 0; hardwired_intr[i].level != -1; i++) {			level = hardwired_intr[i].level;			if (level != intr_reserve_level(cpu, level,						hardwired_intr[i].flags,						(devfs_handle_t) NULL,						hardwired_intr[i].name))				panic("intr_reserve_hardwired: Can't reserve level %d.", level);		}	}}/* * Check and clear interrupts. *//*ARGSUSED*/static voidintr_clear_bits(nasid_t nasid, volatile hubreg_t *pend, int base_level,		char *name){	volatile hubreg_t bits;	int i;	/* Check pending interrupts */	if ((bits = HUB_L(pend)) != 0) {		for (i = 0; i < N_INTPEND_BITS; i++) {			if (bits & (1 << i)) {#ifdef INTRDEBUG				PRINT_WARNING("Nasid %d interrupt bit %d set in %s",					nasid, i, name);#endif				LOCAL_HUB_CLR_INTR(base_level + i);			}		}	}}/* * Clear out our interrupt registers. */voidintr_clear_all(nasid_t nasid){	int	sn;	for(sn=0; sn<NUM_SUBNODES; sn++) {		REMOTE_HUB_PI_S(nasid, sn, PI_INT_MASK0_A, 0);		REMOTE_HUB_PI_S(nasid, sn, PI_INT_MASK0_B, 0);		REMOTE_HUB_PI_S(nasid, sn, PI_INT_MASK1_A, 0);		REMOTE_HUB_PI_S(nasid, sn, PI_INT_MASK1_B, 0);			intr_clear_bits(nasid, REMOTE_HUB_PI_ADDR(nasid, sn, PI_INT_PEND0),				INT_PEND0_BASELVL, "INT_PEND0");		intr_clear_bits(nasid, REMOTE_HUB_PI_ADDR(nasid, sn, PI_INT_PEND1),				INT_PEND1_BASELVL, "INT_PEND1");	}}/*  * Dump information about a particular interrupt vector. */static voiddump_vector(intr_info_t *info, intr_vector_t *vector, int bit, hubreg_t ip,		hubreg_t ima, hubreg_t imb, void (*pf)(char *, ...)){	hubreg_t value = 1LL << bit;	pf("  Bit %02d: %s: func 0x%x arg 0x%x prefunc 0x%x\n",		bit, info->ii_name,		vector->iv_func, vector->iv_arg, vector->iv_prefunc);	pf("   vertex 0x%x %s%s",		info->ii_owner_dev,		((info->ii_flags) & II_RESERVE) ? "R" : "U",		((info->ii_flags) & II_INUSE) ? "C" : "-");	pf("%s%s%s%s",		ip & value ? "P" : "-",		ima & value ? "A" : "-",		imb & value ? "B" : "-",		((info->ii_flags) & II_ERRORINT) ? "E" : "-");	pf("\n");}/* * Dump information about interrupt vector assignment. */voidintr_dumpvec(cnodeid_t cnode, void (*pf)(char *, ...)){	nodepda_t *npda;	int ip, sn, bit;	intr_vecblk_t *dispatch;	hubreg_t ipr, ima, imb;	nasid_t nasid;	if ((cnode < 0) || (cnode >= numnodes)) {		pf("intr_dumpvec: cnodeid out of range: %d\n", cnode);		return ;	}	nasid = COMPACT_TO_NASID_NODEID(cnode);	if (nasid == INVALID_NASID) {		pf("intr_dumpvec: Bad cnodeid: %d\n", cnode);		return ;	}			npda = NODEPDA(cnode);	for (sn = 0; sn < NUM_SUBNODES; sn++) {		for (ip = 0; ip < 2; ip++) {			dispatch = ip ? &(SNPDA(npda,sn)->intr_dispatch1) : &(SNPDA(npda,sn)->intr_dispatch0);			ipr = REMOTE_HUB_PI_L(nasid, sn, ip ? PI_INT_PEND1 : PI_INT_PEND0);			ima = REMOTE_HUB_PI_L(nasid, sn, ip ? PI_INT_MASK1_A : PI_INT_MASK0_A);			imb = REMOTE_HUB_PI_L(nasid, sn, ip ? PI_INT_MASK1_B : PI_INT_MASK0_B);				pf("Node %d INT_PEND%d:\n", cnode, ip);				if (dispatch->ithreads_enabled)				pf(" Ithreads enabled\n");			else				pf(" Ithreads disabled\n");			pf(" vector_count = %d, vector_state = %d\n",				dispatch->vector_count,				dispatch->vector_state);			pf(" CPU A count %d, CPU B count %d\n", 		   	dispatch->cpu_count[0], 		   	dispatch->cpu_count[1]);			pf(" &vector_lock = 0x%x\n",				&(dispatch->vector_lock));			for (bit = 0; bit < N_INTPEND_BITS; bit++) {				if ((dispatch->info[bit].ii_flags & II_RESERVE) ||			    	(ipr & (1L << bit))) {					dump_vector(&(dispatch->info[bit]),					    	&(dispatch->vectors[bit]),					    	bit, ipr, ima, imb, pf);				}			}			pf("\n");		}	}}

⌨️ 快捷键说明

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