ip27-setup.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:8k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  * This file is subject to the terms and conditions of the GNU General Public
  3.  * License.  See the file "COPYING" in the main directory of this archive
  4.  * for more details.
  5.  *
  6.  * SGI IP27 specific setup.
  7.  *
  8.  * Copyright (C) 1999, 2000 Ralf Baechle (ralf@gnu.org)
  9.  * Copyright (C) 1999, 2000 Silcon Graphics, Inc.
  10.  */
  11. #include <linux/config.h>
  12. #include <linux/init.h>
  13. #include <linux/kernel.h>
  14. #include <linux/spinlock.h>
  15. #include <linux/sched.h>
  16. #include <linux/smp.h>
  17. #include <asm/io.h>
  18. #include <asm/sn/types.h>
  19. #include <asm/sn/sn0/addrs.h>
  20. #include <asm/sn/sn0/hubni.h>
  21. #include <asm/sn/sn0/hubio.h>
  22. #include <asm/sn/klconfig.h>
  23. #include <asm/sn/ioc3.h>
  24. #include <asm/mipsregs.h>
  25. #include <asm/sn/arch.h>
  26. #include <asm/sn/sn_private.h>
  27. #include <asm/pci/bridge.h>
  28. #include <asm/paccess.h>
  29. #include <asm/sn/sn0/ip27.h>
  30. /* Check against user dumbness.  */
  31. #ifdef CONFIG_VT
  32. #error CONFIG_VT not allowed for IP27.
  33. #endif
  34. #undef DEBUG_SETUP
  35. #ifdef DEBUG_SETUP
  36. #define DBG(x...) printk(x)
  37. #else
  38. #define DBG(x...)
  39. #endif
  40. unsigned long mips_io_port_base = IO_BASE;
  41. /*
  42.  * get_nasid() returns the physical node id number of the caller.
  43.  */
  44. nasid_t
  45. get_nasid(void)
  46. {
  47. return (nasid_t)((LOCAL_HUB_L(NI_STATUS_REV_ID) & NSRI_NODEID_MASK)
  48.                  >> NSRI_NODEID_SHFT);
  49. }
  50. /* Extracted from the IOC3 meta driver.  FIXME.  */
  51. static inline void ioc3_sio_init(void)
  52. {
  53. struct ioc3 *ioc3;
  54. nasid_t nid;
  55.         long loops;
  56. nid = get_nasid();
  57. ioc3 = (struct ioc3 *) KL_CONFIG_CH_CONS_INFO(nid)->memory_base;
  58. ioc3->sscr_a = 0; /* PIO mode for uarta.  */
  59. ioc3->sscr_b = 0; /* PIO mode for uartb.  */
  60. ioc3->sio_iec = ~0;
  61. ioc3->sio_ies = (SIO_IR_SA_INT | SIO_IR_SB_INT);
  62. loops=1000000; while(loops--);
  63. ioc3->sregs.uarta.iu_fcr = 0;
  64. ioc3->sregs.uartb.iu_fcr = 0;
  65. loops=1000000; while(loops--);
  66. }
  67. static inline void ioc3_eth_init(void)
  68. {
  69. struct ioc3 *ioc3;
  70. nasid_t nid;
  71. nid = get_nasid();
  72. ioc3 = (struct ioc3 *) KL_CONFIG_CH_CONS_INFO(nid)->memory_base;
  73. ioc3->eier = 0;
  74. }
  75. /* Try to catch kernel missconfigurations and give user an indication what
  76.    option to select.  */
  77. static void __init verify_mode(void)
  78. {
  79. int n_mode;
  80. n_mode = LOCAL_HUB_L(NI_STATUS_REV_ID) & NSRI_MORENODES_MASK;
  81. printk("Machine is in %c mode.n", n_mode ? 'N' : 'M');
  82. #ifdef CONFIG_SGI_SN0_N_MODE
  83. if (!n_mode)
  84. panic("Kernel compiled for M mode.");
  85. #else
  86. if (n_mode)
  87. panic("Kernel compiled for N mode.");
  88. #endif
  89. }
  90. #define XBOW_WIDGET_PART_NUM    0x0
  91. #define XXBOW_WIDGET_PART_NUM   0xd000          /* Xbridge */
  92. #define BASE_XBOW_PORT   8     /* Lowest external port */
  93. unsigned int bus_to_cpu[256];
  94. unsigned long bus_to_baddr[256];
  95. void __init pcibr_setup(cnodeid_t nid)
  96. {
  97. int  i, start, num;
  98. unsigned long masterwid;
  99. bridge_t  *bridge; 
  100. volatile u64  hubreg;
  101. nasid_t   nasid, masternasid;
  102. xwidget_part_num_t partnum;
  103. widgetreg_t  widget_id;
  104. static spinlock_t pcibr_setup_lock = SPIN_LOCK_UNLOCKED;
  105. /*
  106.  * If the master is doing this for headless node, nothing to do.
  107.  * This is because currently we require at least one of the hubs
  108.  * (master hub) connected to the xbow to have at least one enabled 
  109.  * cpu to receive intrs. Else we need an array bus_to_intrnasid[] 
  110.  * that bridge_startup() needs to use to target intrs. All dma is
  111.  * routed thru the widget of the master hub. The master hub wid
  112.  * is selectable by WIDGET_A below.
  113.  */
  114. if (nid != get_compact_nodeid())
  115. return;
  116. /*
  117.  * find what's on our local node
  118.  */
  119. spin_lock(&pcibr_setup_lock);
  120. start = num_bridges; /* Remember where we start from */
  121. nasid = COMPACT_TO_NASID_NODEID(nid);
  122. hubreg = REMOTE_HUB_L(nasid, IIO_LLP_CSR);
  123. if (hubreg & IIO_LLP_CSR_IS_UP) {
  124. /* link is up */
  125. widget_id = *(volatile widgetreg_t *)
  126.                         (RAW_NODE_SWIN_BASE(nasid, 0x0) + WIDGET_ID);
  127. partnum = XWIDGET_PART_NUM(widget_id);
  128. printk("Cpu %d, Nasid 0x%x, pcibr_setup(): found partnum= 0x%x",
  129. smp_processor_id(), nasid, partnum);
  130. if (partnum == BRIDGE_WIDGET_PART_NUM) {
  131. /*
  132.  * found direct connected bridge so must be Origin200
  133.  */
  134. printk("...is bridgen");
  135. num_bridges = 1;
  136.          bus_to_wid[0] = 0x8;
  137. bus_to_nid[0] = 0;
  138. masterwid = 0xa;
  139. bus_to_baddr[0] = 0xa100000000000000UL;
  140. } else if (partnum == XBOW_WIDGET_PART_NUM) {
  141. lboard_t *brd;
  142. klxbow_t *xbow_p;
  143. /*
  144.  * found xbow, so may have multiple bridges
  145.  * need to probe xbow
  146.  */
  147. printk("...is xbown");
  148. if ((brd = find_lboard((lboard_t *)KL_CONFIG_INFO(nasid),
  149.                                    KLTYPE_MIDPLANE8)) == NULL)
  150. printk("arghn");
  151. else
  152. printk("brd = 0x%lxn", (unsigned long) brd);
  153. if ((xbow_p = (klxbow_t *)
  154.      find_component(brd, NULL, KLSTRUCT_XBOW)) == NULL)
  155. printk("arghn");
  156. else {
  157.    /*
  158.     * Okay, here's a xbow. Lets arbitrate and find
  159.     * out if we should initialize it. Set enabled 
  160.     * hub connected at highest or lowest widget as 
  161.     * master.
  162.     */
  163. #ifdef WIDGET_A
  164.    i = HUB_WIDGET_ID_MAX + 1;
  165.    do {
  166. i--;
  167.    } while ((!XBOW_PORT_TYPE_HUB(xbow_p, i)) ||
  168. (!XBOW_PORT_IS_ENABLED(xbow_p, i)));
  169. #else
  170.    i = HUB_WIDGET_ID_MIN - 1;
  171.    do {
  172. i++;
  173.    } while ((!XBOW_PORT_TYPE_HUB(xbow_p, i)) ||
  174. (!XBOW_PORT_IS_ENABLED(xbow_p, i)));
  175. #endif
  176.    masterwid = i;
  177.    masternasid = XBOW_PORT_NASID(xbow_p, i);
  178.    if (nasid == masternasid)
  179.    for (i=HUB_WIDGET_ID_MIN; i<=HUB_WIDGET_ID_MAX; i++) {
  180. if (!XBOW_PORT_IS_ENABLED(xbow_p, i))
  181. continue;
  182. if (XBOW_PORT_TYPE_IO(xbow_p, i)) {
  183.    widget_id = *(volatile widgetreg_t *)
  184.                             (RAW_NODE_SWIN_BASE(nasid, i) + WIDGET_ID);
  185.    partnum = XWIDGET_PART_NUM(widget_id);
  186.    if (partnum == BRIDGE_WIDGET_PART_NUM) {
  187. printk("widget 0x%x is a bridgen", i);
  188. bus_to_wid[num_bridges] = i;
  189. bus_to_nid[num_bridges] = nasid;
  190. bus_to_baddr[num_bridges] = ((masterwid << 60) | (1UL << 56)); /* Barrier set */
  191. num_bridges++;
  192.    }
  193. }
  194.    }
  195. }
  196. } else if (partnum == XXBOW_WIDGET_PART_NUM) {
  197. /*
  198.  * found xbridge, assume ibrick for now 
  199.  */
  200. printk("...is xbridgen");
  201.          bus_to_wid[0] = 0xb;
  202.          bus_to_wid[1] = 0xe;
  203.          bus_to_wid[2] = 0xf;
  204.          bus_to_nid[0] = 0;
  205.          bus_to_nid[1] = 0;
  206.          bus_to_nid[2] = 0;
  207. bus_to_baddr[0] = 0xa100000000000000UL;
  208. bus_to_baddr[1] = 0xa100000000000000UL;
  209. bus_to_baddr[2] = 0xa100000000000000UL;
  210. masterwid = 0xa;
  211. num_bridges = 3;
  212. }
  213. }
  214. num = num_bridges - start;
  215. spin_unlock(&pcibr_setup_lock);
  216. /*
  217.          * set bridge registers
  218.          */
  219. for (i = start; i < (start + num); i++) {
  220. DBG("pcibr_setup: bus= %d  bus_to_wid[%2d]= %d  bus_to_nid[%2d]= %dn",
  221.                         i, i, bus_to_wid[i], i, bus_to_nid[i]);
  222. bus_to_cpu[i] = smp_processor_id();
  223. /*
  224.  * point to this bridge
  225.  */
  226. bridge = (bridge_t *) NODE_SWIN_BASE(bus_to_nid[i],bus_to_wid[i]);
  227. /*
  228.    * Clear all pending interrupts.
  229.    */
  230. bridge->b_int_rst_stat = (BRIDGE_IRR_ALL_CLR);
  231. /*
  232.    * Until otherwise set up, assume all interrupts are from slot 0
  233.    */
  234. bridge->b_int_device = (u32) 0x0;
  235. /*
  236.    * swap pio's to pci mem and io space (big windows)
  237.    */
  238. bridge->b_wid_control |= BRIDGE_CTRL_IO_SWAP;
  239. bridge->b_wid_control |= BRIDGE_CTRL_MEM_SWAP;
  240. /*
  241.  * Hmm...  IRIX sets additional bits in the address which 
  242.  * are documented as reserved in the bridge docs.
  243.  */
  244. bridge->b_int_mode = 0x0; /* Don't clear ints */
  245. bridge->b_wid_int_upper = 0x8000 | (masterwid << 16);
  246. bridge->b_wid_int_lower = 0x01800090; /* PI_INT_PEND_MOD off*/
  247. bridge->b_dir_map = (masterwid << 20); /* DMA */
  248. bridge->b_int_enable = 0;
  249. bridge->b_wid_tflush;     /* wait until Bridge PIO complete */
  250. }
  251. }
  252. extern void ip27_setup_console(void);
  253. void __init ip27_setup(void)
  254. {
  255. nasid_t nid;
  256. hubreg_t p, e;
  257. ip27_setup_console();
  258. num_bridges = 0;
  259. /*
  260.  * hub_rtc init and cpu clock intr enabled for later calibrate_delay.
  261.  */
  262. DBG("ip27_setup(): Entered.n");
  263. nid = get_nasid();
  264. printk("IP27: Running on node %d.n", nid);
  265. p = LOCAL_HUB_L(PI_CPU_PRESENT_A) & 1;
  266. e = LOCAL_HUB_L(PI_CPU_ENABLE_A) & 1;
  267. printk("Node %d has %s primary CPU%s.n", nid,
  268.        p ? "a" : "no",
  269.        e ? ", CPU is running" : "");
  270. p = LOCAL_HUB_L(PI_CPU_PRESENT_B) & 1;
  271. e = LOCAL_HUB_L(PI_CPU_ENABLE_B) & 1;
  272. printk("Node %d has %s secondary CPU%s.n", nid,
  273.        p ? "a" : "no",
  274.        e ? ", CPU is running" : "");
  275. verify_mode();
  276. ioc3_sio_init();
  277. ioc3_eth_init();
  278. per_cpu_init();
  279. }