Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 | /* $Id$ * * 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. * * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved. */ #include <linux/types.h> #include <linux/config.h> #include <linux/slab.h> #include <linux/bootmem.h> #include <asm/sn/sgi.h> #include <asm/sn/io.h> #include <asm/sn/iograph.h> #include <asm/sn/invent.h> #include <asm/sn/hcl.h> #include <asm/sn/labelcl.h> #include <asm/sn/sn_private.h> #include <asm/sn/klconfig.h> #include <asm/sn/sn_cpuid.h> #include <asm/sn/snconfig.h> extern int numcpus; extern char arg_maxnodes[]; extern cpuid_t master_procid; #if defined(CONFIG_IA64_SGI_SN1) extern synergy_da_t *Synergy_da_indr[]; #endif extern int hasmetarouter; int maxcpus; cpumask_t boot_cpumask; hubreg_t region_mask = 0; extern xwidgetnum_t hub_widget_id(nasid_t); extern int valid_icache_reasons; /* Reasons to flush the icache */ extern int valid_dcache_reasons; /* Reasons to flush the dcache */ extern u_char miniroot; extern volatile int need_utlbmiss_patch; extern void iograph_early_init(void); nasid_t master_nasid = INVALID_NASID; /* * mlreset(int slave) * very early machine reset - at this point NO interrupts have been * enabled; nor is memory, tlb, p0, etc setup. * * slave is zero when mlreset is called for the master processor and * is nonzero thereafter. */ void mlreset(int slave) { if (!slave) { /* * We are the master cpu and node. */ master_nasid = get_nasid(); set_master_bridge_base(); /* We're the master processor */ master_procid = smp_processor_id(); master_nasid = cpuid_to_nasid(master_procid); /* * master_nasid we get back better be same as one from * get_nasid() */ ASSERT_ALWAYS(master_nasid == get_nasid()); /* early initialization of iograph */ iograph_early_init(); /* Initialize Hub Pseudodriver Management */ hubdev_init(); } else { /* slave != 0 */ /* * This code is performed ONLY by slave processors. */ } } /* XXX - Move the meat of this to intr.c ? */ /* * Set up the platform-dependent fields in the nodepda. */ void init_platform_nodepda(nodepda_t *npda, cnodeid_t node) { hubinfo_t hubinfo; #ifdef CONFIG_IA64_SGI_SN1 int sn; #endif extern void router_map_init(nodepda_t *); extern void router_queue_init(nodepda_t *,cnodeid_t); extern void intr_init_vecblk(nodepda_t *, cnodeid_t, int); /* Allocate per-node platform-dependent data */ hubinfo = (hubinfo_t)alloc_bootmem_node(NODE_DATA(node), sizeof(struct hubinfo_s)); npda->pdinfo = (void *)hubinfo; hubinfo->h_nodepda = npda; hubinfo->h_cnodeid = node; hubinfo->h_nasid = COMPACT_TO_NASID_NODEID(node); spin_lock_init(&hubinfo->h_crblock); hubinfo->h_widgetid = hub_widget_id(hubinfo->h_nasid); npda->xbow_peer = INVALID_NASID; /* * Initialize the linked list of * router info pointers to the dependent routers */ npda->npda_rip_first = NULL; /* * npda_rip_last always points to the place * where the next element is to be inserted * into the list */ npda->npda_rip_last = &npda->npda_rip_first; npda->module_id = INVALID_MODULE; #ifdef CONFIG_IA64_SGI_SN1 /* * Initialize the interrupts. * On sn2, this is done at pci init time, * because sn2 needs the cpus checked in * when it initializes interrupts. This is * so we don't see all the nodes as headless. */ for (sn=0; sn<NUM_SUBNODES; sn++) { intr_init_vecblk(npda, node, sn); } #endif /* CONFIG_IA64_SGI_SN1 */ mutex_init_locked(&npda->xbow_sema); /* init it locked? */ #ifdef LATER /* Setup the (module,slot) --> nic mapping for all the routers * in the system. This is useful during error handling when * there is no shared memory. */ router_map_init(npda); /* Allocate memory for the per-node router traversal queue */ router_queue_init(npda,node); npda->sbe_info = alloc_bootmem_node(NODE_DATA(node), sizeof (sbe_info_t)); ASSERT(npda->sbe_info); #endif /* LATER */ } /* XXX - Move the interrupt stuff to intr.c ? */ /* * Set up the platform-dependent fields in the processor pda. * Must be done _after_ init_platform_nodepda(). * If we need a lock here, something else is wrong! */ void init_platform_pda(cpuid_t cpu) { #if defined(CONFIG_IA64_SGI_SN1) hub_intmasks_t *intmasks; int i, subnode; cnodeid_t cnode; synergy_da_t *sda; int which_synergy; cnode = cpuid_to_cnodeid(cpu); which_synergy = cpuid_to_synergy(cpu); sda = Synergy_da_indr[(cnode * 2) + which_synergy]; intmasks = &sda->s_intmasks; /* Clear INT_PEND0 masks. */ for (i = 0; i < N_INTPEND0_MASKS; i++) intmasks->intpend0_masks[i] = 0; /* Set up pointer to the vector block in the nodepda. */ /* (Cant use SUBNODEPDA - not working yet) */ subnode = cpuid_to_subnode(cpu); intmasks->dispatch0 = &NODEPDA(cnode)->snpda[cpuid_to_subnode(cpu)].intr_dispatch0; intmasks->dispatch1 = &NODEPDA(cnode)->snpda[cpuid_to_subnode(cpu)].intr_dispatch1; if (intmasks->dispatch0 != &SUBNODEPDA(cnode, subnode)->intr_dispatch0 || intmasks->dispatch1 != &SUBNODEPDA(cnode, subnode)->intr_dispatch1) panic("xxx"); intmasks->dispatch0 = &SUBNODEPDA(cnode, subnode)->intr_dispatch0; intmasks->dispatch1 = &SUBNODEPDA(cnode, subnode)->intr_dispatch1; /* Clear INT_PEND1 masks. */ for (i = 0; i < N_INTPEND1_MASKS; i++) intmasks->intpend1_masks[i] = 0; #endif /* CONFIG_IA64_SGI_SN1 */ } void update_node_information(cnodeid_t cnodeid) { nodepda_t *npda = NODEPDA(cnodeid); nodepda_router_info_t *npda_rip; /* Go through the list of router info * structures and copy some frequently * accessed info from the info hanging * off the corresponding router vertices */ npda_rip = npda->npda_rip_first; while(npda_rip) { if (npda_rip->router_infop) { npda_rip->router_portmask = npda_rip->router_infop->ri_portmask; npda_rip->router_slot = npda_rip->router_infop->ri_slotnum; } else { /* No router, no ports. */ npda_rip->router_portmask = 0; } npda_rip = npda_rip->router_next; } } |