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

📄 ip27-nmi.c

📁 linux 内核源代码
💻 C
字号:
#include <linux/kallsyms.h>#include <linux/kernel.h>#include <linux/mmzone.h>#include <linux/nodemask.h>#include <linux/spinlock.h>#include <linux/smp.h>#include <asm/atomic.h>#include <asm/sn/types.h>#include <asm/sn/addrs.h>#include <asm/sn/nmi.h>#include <asm/sn/arch.h>#include <asm/sn/sn0/hub.h>#if 0#define NODE_NUM_CPUS(n)	CNODE_NUM_CPUS(n)#else#define NODE_NUM_CPUS(n)	CPUS_PER_NODE#endif#define CNODEID_NONE (cnodeid_t)-1#define enter_panic_mode()	spin_lock(&nmi_lock)typedef unsigned long machreg_t;DEFINE_SPINLOCK(nmi_lock);/* * Lets see what else we need to do here. Set up sp, gp? */void nmi_dump(void){	void cont_nmi_dump(void);	cont_nmi_dump();}void install_cpu_nmi_handler(int slice){	nmi_t *nmi_addr;	nmi_addr = (nmi_t *)NMI_ADDR(get_nasid(), slice);	if (nmi_addr->call_addr)		return;	nmi_addr->magic = NMI_MAGIC;	nmi_addr->call_addr = (void *)nmi_dump;	nmi_addr->call_addr_c =		(void *)(~((unsigned long)(nmi_addr->call_addr)));	nmi_addr->call_parm = 0;}/* * Copy the cpu registers which have been saved in the IP27prom format * into the eframe format for the node under consideration. */void nmi_cpu_eframe_save(nasid_t nasid, int slice){	struct reg_struct *nr;	int 		i;	/* Get the pointer to the current cpu's register set. */	nr = (struct reg_struct *)		(TO_UNCAC(TO_NODE(nasid, IP27_NMI_KREGS_OFFSET)) +		slice * IP27_NMI_KREGS_CPU_SIZE);	printk("NMI nasid %d: slice %d\n", nasid, slice);	/*	 * Saved main processor registers	 */	for (i = 0; i < 32; ) {		if ((i % 4) == 0)			printk("$%2d   :", i);		printk(" %016lx", nr->gpr[i]);		i++;		if ((i % 4) == 0)			printk("\n");	}	printk("Hi    : (value lost)\n");	printk("Lo    : (value lost)\n");	/*	 * Saved cp0 registers	 */	printk("epc   : %016lx ", nr->epc);	print_symbol("%s ", nr->epc);	printk("%s\n", print_tainted());	printk("ErrEPC: %016lx ", nr->error_epc);	print_symbol("%s\n", nr->error_epc);	printk("ra    : %016lx ", nr->gpr[31]);	print_symbol("%s\n", nr->gpr[31]);	printk("Status: %08lx         ", nr->sr);	if (nr->sr & ST0_KX)		printk("KX ");	if (nr->sr & ST0_SX)		printk("SX 	");	if (nr->sr & ST0_UX)		printk("UX ");	switch (nr->sr & ST0_KSU) {	case KSU_USER:		printk("USER ");		break;	case KSU_SUPERVISOR:		printk("SUPERVISOR ");		break;	case KSU_KERNEL:		printk("KERNEL ");		break;	default:		printk("BAD_MODE ");		break;	}	if (nr->sr & ST0_ERL)		printk("ERL ");	if (nr->sr & ST0_EXL)		printk("EXL ");	if (nr->sr & ST0_IE)		printk("IE ");	printk("\n");	printk("Cause : %08lx\n", nr->cause);	printk("PrId  : %08x\n", read_c0_prid());	printk("BadVA : %016lx\n", nr->badva);	printk("CErr  : %016lx\n", nr->cache_err);	printk("NMI_SR: %016lx\n", nr->nmi_sr);	printk("\n");}void nmi_dump_hub_irq(nasid_t nasid, int slice){	hubreg_t mask0, mask1, pend0, pend1;	if (slice == 0) {				/* Slice A */		mask0 = REMOTE_HUB_L(nasid, PI_INT_MASK0_A);		mask1 = REMOTE_HUB_L(nasid, PI_INT_MASK1_A);	} else {					/* Slice B */		mask0 = REMOTE_HUB_L(nasid, PI_INT_MASK0_B);		mask1 = REMOTE_HUB_L(nasid, PI_INT_MASK1_B);	}	pend0 = REMOTE_HUB_L(nasid, PI_INT_PEND0);	pend1 = REMOTE_HUB_L(nasid, PI_INT_PEND1);	printk("PI_INT_MASK0: %16lx PI_INT_MASK1: %16lx\n", mask0, mask1);	printk("PI_INT_PEND0: %16lx PI_INT_PEND1: %16lx\n", pend0, pend1);	printk("\n\n");}/* * Copy the cpu registers which have been saved in the IP27prom format * into the eframe format for the node under consideration. */void nmi_node_eframe_save(cnodeid_t  cnode){	nasid_t nasid;	int slice;	/* Make sure that we have a valid node */	if (cnode == CNODEID_NONE)		return;	nasid = COMPACT_TO_NASID_NODEID(cnode);	if (nasid == INVALID_NASID)		return;	/* Save the registers into eframe for each cpu */	for (slice = 0; slice < NODE_NUM_CPUS(slice); slice++) {		nmi_cpu_eframe_save(nasid, slice);		nmi_dump_hub_irq(nasid, slice);	}}/* * Save the nmi cpu registers for all cpus in the system. */voidnmi_eframes_save(void){	cnodeid_t	cnode;	for_each_online_node(cnode)		nmi_node_eframe_save(cnode);}voidcont_nmi_dump(void){#ifndef REAL_NMI_SIGNAL	static atomic_t nmied_cpus = ATOMIC_INIT(0);	atomic_inc(&nmied_cpus);#endif	/*	 * Use enter_panic_mode to allow only 1 cpu to proceed	 */	enter_panic_mode();#ifdef REAL_NMI_SIGNAL	/*	 * Wait up to 15 seconds for the other cpus to respond to the NMI.	 * If a cpu has not responded after 10 sec, send it 1 additional NMI.	 * This is for 2 reasons:	 *	- sometimes a MMSC fail to NMI all cpus.	 *	- on 512p SN0 system, the MMSC will only send NMIs to	 *	  half the cpus. Unfortunately, we don't know which cpus may be	 *	  NMIed - it depends on how the site chooses to configure.	 *	 * Note: it has been measure that it takes the MMSC up to 2.3 secs to	 * send NMIs to all cpus on a 256p system.	 */	for (i=0; i < 1500; i++) {		for_each_online_node(node)			if (NODEPDA(node)->dump_count == 0)				break;		if (node == MAX_NUMNODES)			break;		if (i == 1000) {			for_each_online_node(node)				if (NODEPDA(node)->dump_count == 0) {					cpu = node_to_first_cpu(node);					for (n=0; n < CNODE_NUM_CPUS(node); cpu++, n++) {						CPUMASK_SETB(nmied_cpus, cpu);						/*						 * cputonasid, cputoslice						 * needs kernel cpuid						 */						SEND_NMI((cputonasid(cpu)), (cputoslice(cpu)));					}				}		}		udelay(10000);	}#else	while (atomic_read(&nmied_cpus) != num_online_cpus());#endif	/*	 * Save the nmi cpu registers for all cpu in the eframe format.	 */	nmi_eframes_save();	LOCAL_HUB_S(NI_PORT_RESET, NPR_PORTRESET | NPR_LOCALRESET);}

⌨️ 快捷键说明

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