X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=arch%2Fmips%2Fsgi-ip27%2Fip27-init.c;h=9094baf31d0e8c8d7b4c6d40ccc3ce1fbea4a96c;hb=refs%2Fheads%2Fvserver;hp=b8ee02cd02331cd1a767f806b165964a1aca1dbf;hpb=5273a3df6485dc2ad6aa7ddd441b9a21970f003b;p=linux-2.6.git diff --git a/arch/mips/sgi-ip27/ip27-init.c b/arch/mips/sgi-ip27/ip27-init.c index b8ee02cd0..9094baf31 100644 --- a/arch/mips/sgi-ip27/ip27-init.c +++ b/arch/mips/sgi-ip27/ip27-init.c @@ -6,12 +6,11 @@ * Copyright (C) 2000 - 2001 by Kanoj Sarcar (kanoj@sgi.com) * Copyright (C) 2000 - 2001 by Silicon Graphics, Inc. */ -#include #include #include #include -#include /* for numnodes */ #include +#include #include #include #include @@ -40,93 +39,28 @@ #define CPU_NONE (cpuid_t)-1 static DECLARE_BITMAP(hub_init_mask, MAX_COMPACT_NODES); -static hubreg_t region_mask; -static int fine_mode; -static int router_distance; nasid_t master_nasid = INVALID_NASID; cnodeid_t nasid_to_compact_node[MAX_NASIDS]; nasid_t compact_to_nasid_node[MAX_COMPACT_NODES]; cnodeid_t cpuid_to_compact_node[MAXCPUS]; -char node_distances[MAX_COMPACT_NODES][MAX_COMPACT_NODES]; -static hubreg_t get_region(cnodeid_t cnode) -{ - if (fine_mode) - return COMPACT_TO_NASID_NODEID(cnode) >> NASID_TO_FINEREG_SHFT; - else - return COMPACT_TO_NASID_NODEID(cnode) >> NASID_TO_COARSEREG_SHFT; -} - -static void gen_region_mask(hubreg_t *region_mask, int maxnodes) -{ - cnodeid_t cnode; - - (*region_mask) = 0; - for (cnode = 0; cnode < maxnodes; cnode++) { - (*region_mask) |= 1ULL << get_region(cnode); - } -} - -static int is_fine_dirmode(void) -{ - return (((LOCAL_HUB_L(NI_STATUS_REV_ID) & NSRI_REGIONSIZE_MASK) - >> NSRI_REGIONSIZE_SHFT) & REGIONSIZE_FINE); -} +EXPORT_SYMBOL(nasid_to_compact_node); extern void pcibr_setup(cnodeid_t); -static __init void per_slice_init(cnodeid_t cnode, int slice) -{ - struct slice_data *si = hub_data[cnode]->slice + slice; - int cpu = smp_processor_id(); - int i; - - for (i = 0; i < LEVELS_PER_SLICE; i++) - si->level_to_irq[i] = -1; - /* - * Some interrupts are reserved by hardware or by software convention. - * Mark these as reserved right away so they won't be used accidently - * later. - */ - for (i = 0; i <= BASE_PCI_IRQ; i++) { - __set_bit(i, si->irq_alloc_mask); - LOCAL_HUB_S(PI_INT_PEND_MOD, i); - } - - __set_bit(IP_PEND0_6_63, si->irq_alloc_mask); - LOCAL_HUB_S(PI_INT_PEND_MOD, IP_PEND0_6_63); - - for (i = NI_BRDCAST_ERR_A; i <= MSC_PANIC_INTR; i++) { - __set_bit(i, si->irq_alloc_mask + 1); - LOCAL_HUB_S(PI_INT_PEND_MOD, i); - } - - LOCAL_HUB_L(PI_INT_PEND0); - - /* - * We use this so we can find the local hub's data as fast as only - * possible. - */ - cpu_data[cpu].data = si; -} - extern void xtalk_probe_node(cnodeid_t nid); -void __init per_hub_init(cnodeid_t cnode) +static void __init per_hub_init(cnodeid_t cnode) { - struct hub_data *hub = HUB_DATA(cnode); + struct hub_data *hub = hub_data(cnode); nasid_t nasid = COMPACT_TO_NASID_NODEID(cnode); - int slice = LOCAL_HUB_L(PI_CPU_NUM); + int i; cpu_set(smp_processor_id(), hub->h_cpus); - if (!test_and_set_bit(slice, &hub->slice_map)) - per_slice_init(cnode, slice); - if (test_and_set_bit(cnode, hub_init_mask)) return; - /* * Set CRB timeout at 5ms, (< PI timeout of 10ms) */ @@ -142,274 +76,87 @@ void __init per_hub_init(cnodeid_t cnode) * copy over the caliased exception handlers. */ if (get_compact_nodeid() == cnode) { - extern char except_vec0, except_vec1_r10k; extern char except_vec2_generic, except_vec3_generic; + extern void build_tlb_refill_handler(void); - memcpy((void *)(KSEG0 + 0x100), &except_vec2_generic, 0x80); - memcpy((void *)(KSEG0 + 0x180), &except_vec3_generic, 0x80); - memcpy((void *)KSEG0, &except_vec0, 0x80); - memcpy((void *)KSEG0 + 0x080, &except_vec1_r10k, 0x80); - memcpy((void *)(KSEG0 + 0x100), (void *) KSEG0, 0x80); - memcpy((void *)(KSEG0 + 0x180), &except_vec3_generic, 0x100); + memcpy((void *)(CKSEG0 + 0x100), &except_vec2_generic, 0x80); + memcpy((void *)(CKSEG0 + 0x180), &except_vec3_generic, 0x80); + build_tlb_refill_handler(); + memcpy((void *)(CKSEG0 + 0x100), (void *) CKSEG0, 0x80); + memcpy((void *)(CKSEG0 + 0x180), &except_vec3_generic, 0x100); __flush_cache_all(); } #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); -} - -/* - * Map the physical node id to a virtual node id (virtual node ids are contiguous). - */ -cnodeid_t get_compact_nodeid(void) -{ - return NASID_TO_COMPACT_NODEID(get_nasid()); -} - -#define rou_rflag rou_flags - -static void router_recurse(klrou_t *router_a, klrou_t *router_b, int depth) -{ - klrou_t *router; - lboard_t *brd; - int port; - - if (router_a->rou_rflag == 1) - return; + /* + * Some interrupts are reserved by hardware or by software convention. + * Mark these as reserved right away so they won't be used accidently + * later. + */ + for (i = 0; i <= BASE_PCI_IRQ; i++) { + __set_bit(i, hub->irq_alloc_mask); + LOCAL_HUB_CLR_INTR(INT_PEND0_BASELVL + i); + } - if (depth >= router_distance) - return; + __set_bit(IP_PEND0_6_63, hub->irq_alloc_mask); + LOCAL_HUB_S(PI_INT_PEND_MOD, IP_PEND0_6_63); - router_a->rou_rflag = 1; - - for (port = 1; port <= MAX_ROUTER_PORTS; port++) { - if (router_a->rou_port[port].port_nasid == INVALID_NASID) - continue; - - brd = (lboard_t *)NODE_OFFSET_TO_K0( - router_a->rou_port[port].port_nasid, - router_a->rou_port[port].port_offset); - - if (brd->brd_type == KLTYPE_ROUTER) { - router = (klrou_t *)NODE_OFFSET_TO_K0(NASID_GET(brd), brd->brd_compts[0]); - if (router == router_b) { - if (depth < router_distance) - router_distance = depth; - } - else - router_recurse(router, router_b, depth + 1); - } + for (i = NI_BRDCAST_ERR_A; i <= MSC_PANIC_INTR; i++) { + __set_bit(i, hub->irq_alloc_mask); + LOCAL_HUB_CLR_INTR(INT_PEND1_BASELVL + i); } - - router_a->rou_rflag = 0; } -int node_distance(nasid_t nasid_a, nasid_t nasid_b) +void __init per_cpu_init(void) { - klrou_t *router, *router_a = NULL, *router_b = NULL; - lboard_t *brd, *dest_brd; - cnodeid_t cnode; - nasid_t nasid; - int port; - - /* Figure out which routers nodes in question are connected to */ - for (cnode = 0; cnode < numnodes; cnode++) { - nasid = COMPACT_TO_NASID_NODEID(cnode); - - if (nasid == -1) continue; - - brd = find_lboard_class((lboard_t *)KL_CONFIG_INFO(nasid), - KLTYPE_ROUTER); - - if (!brd) - continue; - - do { - if (brd->brd_flags & DUPLICATE_BOARD) - continue; - - router = (klrou_t *)NODE_OFFSET_TO_K0(NASID_GET(brd), brd->brd_compts[0]); - router->rou_rflag = 0; - - for (port = 1; port <= MAX_ROUTER_PORTS; port++) { - if (router->rou_port[port].port_nasid == INVALID_NASID) - continue; - - dest_brd = (lboard_t *)NODE_OFFSET_TO_K0( - router->rou_port[port].port_nasid, - router->rou_port[port].port_offset); + int cpu = smp_processor_id(); + int slice = LOCAL_HUB_L(PI_CPU_NUM); + cnodeid_t cnode = get_compact_nodeid(); + struct hub_data *hub = hub_data(cnode); + struct slice_data *si = hub->slice + slice; + int i; - if (dest_brd->brd_type == KLTYPE_IP27) { - if (dest_brd->brd_nasid == nasid_a) - router_a = router; - if (dest_brd->brd_nasid == nasid_b) - router_b = router; - } - } + if (test_and_set_bit(slice, &hub->slice_map)) + return; - } while ((brd = find_lboard_class(KLCF_NEXT(brd), KLTYPE_ROUTER))); - } + clear_c0_status(ST0_IM); - if (router_a == NULL) { - printk("node_distance: router_a NULL\n"); - return -1; - } - if (router_b == NULL) { - printk("node_distance: router_b NULL\n"); - return -1; - } + per_hub_init(cnode); - if (nasid_a == nasid_b) - return 0; + for (i = 0; i < LEVELS_PER_SLICE; i++) + si->level_to_irq[i] = -1; - if (router_a == router_b) - return 1; + /* + * We use this so we can find the local hub's data as fast as only + * possible. + */ + cpu_data[cpu].data = si; - router_distance = 100; - router_recurse(router_a, router_b, 2); + cpu_time_init(); + install_ipi(); - return router_distance; -} + /* Install our NMI handler if symmon hasn't installed one. */ + install_cpu_nmi_handler(cputoslice(cpu)); -static void init_topology_matrix(void) -{ - nasid_t nasid, nasid2; - cnodeid_t row, col; - - for (row = 0; row < MAX_COMPACT_NODES; row++) - for (col = 0; col < MAX_COMPACT_NODES; col++) - node_distances[row][col] = -1; - - for (row = 0; row < numnodes; row++) { - nasid = COMPACT_TO_NASID_NODEID(row); - for (col = 0; col < numnodes; col++) { - nasid2 = COMPACT_TO_NASID_NODEID(col); - node_distances[row][col] = node_distance(nasid, nasid2); - } - } + set_c0_status(SRB_DEV0 | SRB_DEV1); } -static void dump_topology(void) +/* + * get_nasid() returns the physical node id number of the caller. + */ +nasid_t +get_nasid(void) { - nasid_t nasid; - cnodeid_t cnode; - lboard_t *brd, *dest_brd; - int port; - int router_num = 0; - klrou_t *router; - cnodeid_t row, col; - - printk("************** Topology ********************\n"); - - printk(" "); - for (col = 0; col < numnodes; col++) - printk("%02d ", col); - printk("\n"); - for (row = 0; row < numnodes; row++) { - printk("%02d ", row); - for (col = 0; col < numnodes; col++) - printk("%2d ", node_distances[row][col]); - printk("\n"); - } - - for (cnode = 0; cnode < numnodes; cnode++) { - nasid = COMPACT_TO_NASID_NODEID(cnode); - - if (nasid == -1) continue; - - brd = find_lboard_class((lboard_t *)KL_CONFIG_INFO(nasid), - KLTYPE_ROUTER); - - if (!brd) - continue; - - do { - if (brd->brd_flags & DUPLICATE_BOARD) - continue; - printk("Router %d:", router_num); - router_num++; - - router = (klrou_t *)NODE_OFFSET_TO_K0(NASID_GET(brd), brd->brd_compts[0]); - - for (port = 1; port <= MAX_ROUTER_PORTS; port++) { - if (router->rou_port[port].port_nasid == INVALID_NASID) - continue; - - dest_brd = (lboard_t *)NODE_OFFSET_TO_K0( - router->rou_port[port].port_nasid, - router->rou_port[port].port_offset); - - if (dest_brd->brd_type == KLTYPE_IP27) - printk(" %d", dest_brd->brd_nasid); - if (dest_brd->brd_type == KLTYPE_ROUTER) - printk(" r"); - } - printk("\n"); - - } while ( (brd = find_lboard_class(KLCF_NEXT(brd), KLTYPE_ROUTER)) ); - } + return (nasid_t)((LOCAL_HUB_L(NI_STATUS_REV_ID) & NSRI_NODEID_MASK) + >> NSRI_NODEID_SHFT); } -void mlreset(void) +/* + * Map the physical node id to a virtual node id (virtual node ids are contiguous). + */ +cnodeid_t get_compact_nodeid(void) { - int i; - - master_nasid = get_nasid(); - fine_mode = is_fine_dirmode(); - - /* - * Probe for all CPUs - this creates the cpumask and sets up the - * mapping tables. We need to do this as early as possible. - */ -#ifdef CONFIG_SMP - cpu_node_probe(); -#endif - - init_topology_matrix(); - dump_topology(); - - gen_region_mask(®ion_mask, numnodes); - - setup_replication_mask(numnodes); - - /* - * Set all nodes' calias sizes to 8k - */ - for (i = 0; i < numnodes; i++) { - nasid_t nasid; - - nasid = COMPACT_TO_NASID_NODEID(i); - - /* - * Always have node 0 in the region mask, otherwise - * CALIAS accesses get exceptions since the hub - * thinks it is a node 0 address. - */ - REMOTE_HUB_S(nasid, PI_REGION_PRESENT, (region_mask | 1)); -#ifdef CONFIG_REPLICATE_EXHANDLERS - REMOTE_HUB_S(nasid, PI_CALIAS_SIZE, PI_CALIAS_SIZE_8K); -#else - REMOTE_HUB_S(nasid, PI_CALIAS_SIZE, PI_CALIAS_SIZE_0); -#endif - -#ifdef LATER - /* - * Set up all hubs to have a big window pointing at - * widget 0. Memory mode, widget 0, offset 0 - */ - REMOTE_HUB_S(nasid, IIO_ITTE(SWIN0_BIGWIN), - ((HUB_PIO_MAP_TO_MEM << IIO_ITTE_IOSP_SHIFT) | - (0 << IIO_ITTE_WIDGET_SHIFT))); -#endif - } + return NASID_TO_COMPACT_NODEID(get_nasid()); } /* Extracted from the IOC3 meta driver. FIXME. */ @@ -444,25 +191,11 @@ static inline void ioc3_eth_init(void) ioc3->eier = 0; } -void __init per_cpu_init(void) -{ - cnodeid_t cnode = get_compact_nodeid(); - int cpu = smp_processor_id(); - - clear_c0_status(ST0_IM); - per_hub_init(cnode); - cpu_time_init(); - install_ipi(); - /* Install our NMI handler if symmon hasn't installed one. */ - install_cpu_nmi_handler(cputoslice(cpu)); - set_c0_status(SRB_DEV0 | SRB_DEV1); -} - extern void ip27_setup_console(void); extern void ip27_time_init(void); extern void ip27_reboot_setup(void); -static int __init ip27_setup(void) +void __init plat_mem_setup(void) { hubreg_t p, e, n_mode; nasid_t nid; @@ -494,7 +227,7 @@ static int __init ip27_setup(void) */ 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 +#ifdef CONFIG_SGI_SN_N_MODE if (!n_mode) panic("Kernel compiled for M mode."); #else @@ -509,8 +242,4 @@ static int __init ip27_setup(void) set_io_port_base(IO_BASE); board_time_init = ip27_time_init; - - return 0; } - -early_initcall(ip27_setup);