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

📄 ip27-setup.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
字号:
/* * This file is subject to the terms and conditions of the GNU General Public * License.  See the file "COPYING" in the main directory of this archive * for more details. * * SGI IP27 specific setup. * * Copyright (C) 1999, 2000 Ralf Baechle (ralf@gnu.org) * Copyright (C) 1999, 2000 Silcon Graphics, Inc. */#include <linux/config.h>#include <linux/init.h>#include <linux/kernel.h>#include <linux/spinlock.h>#include <linux/sched.h>#include <linux/smp.h>#include <asm/sn/types.h>#include <asm/sn/sn0/addrs.h>#include <asm/sn/sn0/hubni.h>#include <asm/sn/sn0/hubio.h>#include <asm/sn/klconfig.h>#include <asm/sn/ioc3.h>#include <asm/mipsregs.h>#include <asm/sn/arch.h>#include <asm/sn/sn_private.h>#include <asm/pci/bridge.h>#include <asm/paccess.h>#include <asm/sn/sn0/ip27.h>/* Check against user dumbness.  */#ifdef CONFIG_VT#error CONFIG_VT not allowed for IP27.#endif#undef DEBUG_SETUP#ifdef DEBUG_SETUP#define DBG(x...) printk(x)#else#define DBG(x...)#endif/* * get_nasid() returns the physical node id number of the caller. */nasid_tget_nasid(void){	return (nasid_t)((LOCAL_HUB_L(NI_STATUS_REV_ID) & NSRI_NODEID_MASK)	                 >> NSRI_NODEID_SHFT);}/* Extracted from the IOC3 meta driver.  FIXME.  */static inline void ioc3_sio_init(void){	struct ioc3 *ioc3;	nasid_t nid;        long loops;	nid = get_nasid();	ioc3 = (struct ioc3 *) KL_CONFIG_CH_CONS_INFO(nid)->memory_base;	ioc3->sscr_a = 0;			/* PIO mode for uarta.  */	ioc3->sscr_b = 0;			/* PIO mode for uartb.  */	ioc3->sio_iec = ~0;	ioc3->sio_ies = (SIO_IR_SA_INT | SIO_IR_SB_INT);	loops=1000000; while(loops--);	ioc3->sregs.uarta.iu_fcr = 0;	ioc3->sregs.uartb.iu_fcr = 0;	loops=1000000; while(loops--);}static inline void ioc3_eth_init(void){	struct ioc3 *ioc3;	nasid_t nid;	nid = get_nasid();	ioc3 = (struct ioc3 *) KL_CONFIG_CH_CONS_INFO(nid)->memory_base;	ioc3->eier = 0;}/* Try to catch kernel missconfigurations and give user an indication what   option to select.  */static void __init verify_mode(void){	int n_mode;	n_mode = LOCAL_HUB_L(NI_STATUS_REV_ID) & NSRI_MORENODES_MASK;	printk("Machine is in %c mode.\n", n_mode ? 'N' : 'M');#ifdef CONFIG_SGI_SN0_N_MODE	if (!n_mode)		panic("Kernel compiled for M mode.");#else	if (n_mode)		panic("Kernel compiled for N mode.");#endif}#define XBOW_WIDGET_PART_NUM    0x0#define XXBOW_WIDGET_PART_NUM   0xd000          /* Xbridge */#define BASE_XBOW_PORT  	8     /* Lowest external port */unsigned int bus_to_cpu[256];unsigned long bus_to_baddr[256];void __init pcibr_setup(cnodeid_t nid){	int 			i, start, num;	unsigned long		masterwid;	bridge_t 		*bridge; 	volatile u64 		hubreg;	nasid_t	 		nasid, masternasid;	xwidget_part_num_t	partnum;	widgetreg_t 		widget_id;	static spinlock_t	pcibr_setup_lock = SPIN_LOCK_UNLOCKED;	/*	 * If the master is doing this for headless node, nothing to do.	 * This is because currently we require at least one of the hubs	 * (master hub) connected to the xbow to have at least one enabled 	 * cpu to receive intrs. Else we need an array bus_to_intrnasid[] 	 * that bridge_startup() needs to use to target intrs. All dma is	 * routed thru the widget of the master hub. The master hub wid	 * is selectable by WIDGET_A below.	 */	if (nid != get_compact_nodeid())		return;	/*	 * find what's on our local node	 */	spin_lock(&pcibr_setup_lock);	start = num_bridges;		/* Remember where we start from */	nasid = COMPACT_TO_NASID_NODEID(nid);	hubreg = REMOTE_HUB_L(nasid, IIO_LLP_CSR);	if (hubreg & IIO_LLP_CSR_IS_UP) {		/* link is up */		widget_id = *(volatile widgetreg_t *)                        (RAW_NODE_SWIN_BASE(nasid, 0x0) + WIDGET_ID);		partnum = XWIDGET_PART_NUM(widget_id);		printk("Cpu %d, Nasid 0x%x, pcibr_setup(): found partnum= 0x%x",					smp_processor_id(), nasid, partnum);		if (partnum == BRIDGE_WIDGET_PART_NUM) {			/*			 * found direct connected bridge so must be Origin200			 */			printk("...is bridge\n");			num_bridges = 1;        		bus_to_wid[0] = 0x8;			bus_to_nid[0] = 0;			masterwid = 0xa;			bus_to_baddr[0] = 0xa100000000000000UL;		} else if (partnum == XBOW_WIDGET_PART_NUM) {			lboard_t *brd;			klxbow_t *xbow_p;			/*			 * found xbow, so may have multiple bridges			 * need to probe xbow			 */			printk("...is xbow\n");			if ((brd = find_lboard((lboard_t *)KL_CONFIG_INFO(nasid),                                   KLTYPE_MIDPLANE8)) == NULL)				printk("argh\n");			else				printk("brd = 0x%lx\n", (unsigned long) brd);			if ((xbow_p = (klxbow_t *)			     find_component(brd, NULL, KLSTRUCT_XBOW)) == NULL)				printk("argh\n");			else {			   /*			    * Okay, here's a xbow. Lets arbitrate and find			    * out if we should initialize it. Set enabled 			    * hub connected at highest or lowest widget as 			    * master.			    */#ifdef WIDGET_A			   i = HUB_WIDGET_ID_MAX + 1;			   do {				i--;			   } while ((!XBOW_PORT_TYPE_HUB(xbow_p, i)) ||					(!XBOW_PORT_IS_ENABLED(xbow_p, i)));#else			   i = HUB_WIDGET_ID_MIN - 1;			   do {				i++;			   } while ((!XBOW_PORT_TYPE_HUB(xbow_p, i)) ||					(!XBOW_PORT_IS_ENABLED(xbow_p, i)));#endif			   masterwid = i;			   masternasid = XBOW_PORT_NASID(xbow_p, i);			   if (nasid == masternasid)			   for (i=HUB_WIDGET_ID_MIN; i<=HUB_WIDGET_ID_MAX; i++) {				if (!XBOW_PORT_IS_ENABLED(xbow_p, i))					continue;				if (XBOW_PORT_TYPE_IO(xbow_p, i)) {				   widget_id = *(volatile widgetreg_t *)                        		   (RAW_NODE_SWIN_BASE(nasid, i) + WIDGET_ID);				   partnum = XWIDGET_PART_NUM(widget_id);				   if (partnum == BRIDGE_WIDGET_PART_NUM) {					printk("widget 0x%x is a bridge\n", i);					bus_to_wid[num_bridges] = i;					bus_to_nid[num_bridges] = nasid;					bus_to_baddr[num_bridges] = ((masterwid << 60) | (1UL << 56));	/* Barrier set */					num_bridges++;				   }				}			   }			}		} else if (partnum == XXBOW_WIDGET_PART_NUM) {			/*			 * found xbridge, assume ibrick for now 			 */			printk("...is xbridge\n");        		bus_to_wid[0] = 0xb;        		bus_to_wid[1] = 0xe;        		bus_to_wid[2] = 0xf;        		bus_to_nid[0] = 0;        		bus_to_nid[1] = 0;        		bus_to_nid[2] = 0;			bus_to_baddr[0] = 0xa100000000000000UL;			bus_to_baddr[1] = 0xa100000000000000UL;			bus_to_baddr[2] = 0xa100000000000000UL;			masterwid = 0xa;			num_bridges = 3;		}	}	num = num_bridges - start;	spin_unlock(&pcibr_setup_lock);	/*         * set bridge registers         */	for (i = start; i < (start + num); i++) {		DBG("pcibr_setup: bus= %d  bus_to_wid[%2d]= %d  bus_to_nid[%2d]= %d\n",                        i, i, bus_to_wid[i], i, bus_to_nid[i]);		bus_to_cpu[i] = smp_processor_id();		/*		 * point to this bridge		 */		bridge = (bridge_t *) NODE_SWIN_BASE(bus_to_nid[i],bus_to_wid[i]);		/*	 	 * Clear all pending interrupts.	 	 */		bridge->b_int_rst_stat = (BRIDGE_IRR_ALL_CLR);		/*	 	 * Until otherwise set up, assume all interrupts are from slot 0	 	 */		bridge->b_int_device = (u32) 0x0;		/*	 	 * swap pio's to pci mem and io space (big windows)	 	 */		bridge->b_wid_control |= BRIDGE_CTRL_IO_SWAP;		bridge->b_wid_control |= BRIDGE_CTRL_MEM_SWAP;		/*		 * Hmm...  IRIX sets additional bits in the address which 		 * are documented as reserved in the bridge docs.		 */		bridge->b_int_mode = 0x0;		/* Don't clear ints */		bridge->b_wid_int_upper = 0x8000 | (masterwid << 16);		bridge->b_wid_int_lower = 0x01800090;	/* PI_INT_PEND_MOD off*/		bridge->b_dir_map = (masterwid << 20);	/* DMA */		bridge->b_int_enable = 0;		bridge->b_wid_tflush;     /* wait until Bridge PIO complete */	}}extern void ip27_setup_console(void);void __init ip27_setup(void){	nasid_t nid;	hubreg_t p, e;	ip27_setup_console();	num_bridges = 0;	/*	 * hub_rtc init and cpu clock intr enabled for later calibrate_delay.	 */	DBG("ip27_setup(): Entered.\n");	nid = get_nasid();	printk("IP27: Running on node %d.\n", nid);	p = LOCAL_HUB_L(PI_CPU_PRESENT_A) & 1;	e = LOCAL_HUB_L(PI_CPU_ENABLE_A) & 1;	printk("Node %d has %s primary CPU%s.\n", nid,	       p ? "a" : "no",	       e ? ", CPU is running" : "");	p = LOCAL_HUB_L(PI_CPU_PRESENT_B) & 1;	e = LOCAL_HUB_L(PI_CPU_ENABLE_B) & 1;	printk("Node %d has %s secondary CPU%s.\n", nid,	       p ? "a" : "no",	       e ? ", CPU is running" : "");	verify_mode();	ioc3_sio_init();	ioc3_eth_init();	per_cpu_init();}

⌨️ 快捷键说明

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