/* $Id: ip27-setup.c,v 1.7 2000/03/07 15:45:29 ralf Exp $ * * 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 Ralf Baechle (ralf@gnu.org) * Copyright (C) 1999 Silcon Graphics, Inc. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* Check against user dumbness. */ #ifdef CONFIG_VT #error CONFIG_VT not allowed for IP27. #endif /* * get_nasid() returns the physical node id number of the caller. */ nasid_t get_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 } static void __init pcibr_setup(void) { bridge_t *bridge = (bridge_t *) 0x9200000008000000; /* * 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; bridge->b_wid_tflush; /* wait until Bridge PIO complete */ } void __init ip27_setup(void) { nasid_t nid; hubreg_t p, e; /* * hub_rtc init and cpu clock intr enabled for later calibrate_delay. */ per_cpu_init(); 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(); /* set some bridge registers */ pcibr_setup(); }