/* * For each PCI bridge connected to the xswitch, add a link from the * board's klconfig info to the bridge's hwgraph vertex. This lets * the FRU analyzer find the bridge without traversing the hardware * graph and risking hangs. */ static void io_link_xswitch_widgets(devfs_handle_t xswitchv, cnodeid_t cnodeid) { xwidgetnum_t widgetnum; char pathname[128]; devfs_handle_t vhdl; nasid_t nasid, peer_nasid; lboard_t *board; /* And its connected hub's nasids */ nasid = COMPACT_TO_NASID_NODEID(cnodeid); peer_nasid = NODEPDA(cnodeid)->xbow_peer; /* * Look for paths matching "<widgetnum>/pci" under xswitchv. * For every widget, init. its lboard's hwgraph link. If the * board has a PCI bridge, point the link to it. */ for (widgetnum = HUB_WIDGET_ID_MIN; widgetnum <= HUB_WIDGET_ID_MAX; widgetnum++) { sprintf(pathname, "%d", widgetnum); if (hwgraph_traverse(xswitchv, pathname, &vhdl) != GRAPH_SUCCESS) continue; board = find_lboard_module((lboard_t *)KL_CONFIG_INFO(nasid), NODEPDA(cnodeid)->module_id); if (board == NULL && peer_nasid != INVALID_NASID) { /* * Try to find the board on our peer */ board = find_lboard_module( (lboard_t *)KL_CONFIG_INFO(peer_nasid), NODEPDA(cnodeid)->module_id); } if (board == NULL) { #if defined(SUPPORT_PRINTING_V_FORMAT) printk(KERN_WARNING "Could not find PROM info for vertex %v, " "FRU analyzer may fail", vhdl); #else printk(KERN_WARNING "Could not find PROM info for vertex 0x%p, " "FRU analyzer may fail", (void *)vhdl); #endif return; } sprintf(pathname, "%d/"EDGE_LBL_PCI, widgetnum); if (hwgraph_traverse(xswitchv, pathname, &vhdl) == GRAPH_SUCCESS) board->brd_graph_link = vhdl; else board->brd_graph_link = GRAPH_VERTEX_NONE; } }
/* * Early iograph initialization. Called by master CPU in mlreset(). * Useful for including iograph.o in kernel.o. */ void iograph_early_init(void) { /* * Need new way to get this information .. */ cnodeid_t cnode; nasid_t nasid; lboard_t *board; /* * Init. the board-to-hwgraph link early, so FRU analyzer * doesn't trip on leftover values if we panic early on. */ for(cnode = 0; cnode < numnodes; cnode++) { nasid = COMPACT_TO_NASID_NODEID(cnode); board = (lboard_t *)KL_CONFIG_INFO(nasid); DBG("iograph_early_init: Found board 0x%p\n", board); /* Check out all the board info stored on a node */ while(board) { board->brd_graph_link = GRAPH_VERTEX_NONE; board = KLCF_NEXT(board); DBG("iograph_early_init: Found board 0x%p\n", board); } } hubio_init(); }
static int do_cpumask(cnodeid_t cnode, nasid_t nasid, int highest) { static int tot_cpus_found = 0; lboard_t *brd; klcpu_t *acpu; int cpus_found = 0; cpuid_t cpuid; brd = find_lboard((lboard_t *)KL_CONFIG_INFO(nasid), KLTYPE_IP27); do { acpu = (klcpu_t *)find_first_component(brd, KLSTRUCT_CPU); while (acpu) { cpuid = acpu->cpu_info.virtid; /* cnode is not valid for completely disabled brds */ if (get_actual_nasid(brd) == brd->brd_nasid) cpuid_to_compact_node[cpuid] = cnode; if (cpuid > highest) highest = cpuid; /* Only let it join in if it's marked enabled */ if ((acpu->cpu_info.flags & KLINFO_ENABLE) && (tot_cpus_found != NR_CPUS)) { <<<<<<< HEAD set_cpu_possible(cpuid, true); ======= <<<<<<< HEAD set_cpu_possible(cpuid, true); ======= cpu_set(cpuid, cpu_possible_map); >>>>>>> 58a75b6a81be54a8b491263ca1af243e9d8617b9 >>>>>>> ae1773bb70f3d7cf73324ce8fba787e01d8fa9f2
static pfn_t slot_psize_compute(cnodeid_t node, int slot) { nasid_t nasid; lboard_t *brd; klmembnk_t *banks; unsigned long size; nasid = COMPACT_TO_NASID_NODEID(node); /* Find the node board */ brd = find_lboard((lboard_t *)KL_CONFIG_INFO(nasid), KLTYPE_IP27); if (!brd) return 0; /* Get the memory bank structure */ banks = (klmembnk_t *)find_first_component(brd, KLSTRUCT_MEMBNK); if (!banks) return 0; /* Size in _Megabytes_ */ size = (unsigned long)banks->membnk_bnksz[slot/4]; /* hack for 128 dimm banks */ if (size <= 128) { if (slot%4 == 0) { size <<= 20; /* size in bytes */ return(size >> PAGE_SHIFT); } else { return 0;
static void __init klhwg_connect_routers(vertex_hdl_t hwgraph_root) { nasid_t nasid; cnodeid_t cnode; lboard_t *brd; for (cnode = 0; cnode < numnodes; cnode++) { nasid = cnodeid_to_nasid(cnode); brd = find_lboard_class_any((lboard_t *)KL_CONFIG_INFO(nasid), KLTYPE_ROUTER); if (!brd) continue; do { nasid = cnodeid_to_nasid(cnode); klhwg_connect_one_router(hwgraph_root, brd, cnode, nasid); /* Find the rest of the routers stored on this node. */ } while ( (brd = find_lboard_class_any(KLCF_NEXT_ANY(brd), KLTYPE_ROUTER)) ); } }
void io_module_init(void) { cnodeid_t node; lboard_t *board; nasid_t nasid; int nserial; module_t *m; DPRINTF("*******module_init\n"); nserial = 0; for (node = 0; node < numnodes; node++) { nasid = COMPACT_TO_NASID_NODEID(node); board = find_lboard((lboard_t *) KL_CONFIG_INFO(nasid), KLTYPE_IP27); ASSERT(board); m = module_add_node(board->brd_module, node); if (! m->snum_valid && module_probe_snum(m, nasid)) nserial++; } DPRINTF("********found total of %d serial numbers in the system\n", nserial); if (nserial == 0) PRINT_WARNING("io_module_init: No serial number found.\n"); }
static int __cpuinit xbow_probe(nasid_t nasid) { lboard_t *brd; klxbow_t *xbow_p; unsigned masterwid, i; printk("is xbow\n"); /* * found xbow, so may have multiple bridges * need to probe xbow */ brd = find_lboard((lboard_t *)KL_CONFIG_INFO(nasid), KLTYPE_MIDPLANE8); if (!brd) return -ENODEV; xbow_p = (klxbow_t *)find_component(brd, NULL, KLSTRUCT_XBOW); if (!xbow_p) return -ENODEV; /* * 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; if (nasid != XBOW_PORT_NASID(xbow_p, i)) return 1; for (i = HUB_WIDGET_ID_MIN; i <= HUB_WIDGET_ID_MAX; i++) { if (XBOW_PORT_IS_ENABLED(xbow_p, i) && XBOW_PORT_TYPE_IO(xbow_p, i)) probe_one_port(nasid, i, masterwid); } return 0; }
int module_probe_snum(module_t *m, nasid_t nasid) { lboard_t *board; klmod_serial_num_t *comp; board = find_lboard((lboard_t *) KL_CONFIG_INFO(nasid), KLTYPE_MIDPLANE8); if (! board || KL_CONFIG_DUPLICATE_BOARD(board)) return 0; comp = GET_SNUM_COMP(board); if (comp) { #if LDEBUG int i; printf("********found module with id %x and string", m->id); for (i = 0; i < MAX_SERIAL_NUM_SIZE; i++) printf(" %x ", comp->snum.snum_str[i]); printf("\n"); /* Fudged string is not ASCII */ #endif if (comp->snum.snum_str[0] != '\0') { bcopy(comp->snum.snum_str, m->snum.snum_str, MAX_SERIAL_NUM_SIZE); m->snum_valid = 1; } } if (m->snum_valid) return 1; else { #ifndef CONFIG_IA64_SGI_IO cmn_err(CE_WARN | CE_MAINTENANCE, "Invalid serial number for module %d, " "possible missing or invalid NIC.", m->id); #else printk("Invalid serial number for module %d, " "possible missing or invalid NIC.", m->id); #endif return 0; } }
klcpu_t * nasid_slice_to_cpuinfo(nasid_t nasid, int slice) { lboard_t *brd; klcpu_t *acpu; if (!(brd = find_lboard((lboard_t *)KL_CONFIG_INFO(nasid), KLTYPE_IP27))) return (klcpu_t *)NULL; if (!(acpu = (klcpu_t *)find_first_component(brd, KLSTRUCT_CPU))) return (klcpu_t *)NULL; do { if ((acpu->cpu_info.physid) == slice) return acpu; } while ((acpu = (klcpu_t *)find_component(brd, (klinfo_t *)acpu, KLSTRUCT_CPU))); return (klcpu_t *)NULL; }
/* ARGSUSED */ static void __init klhwg_add_all_routers(vertex_hdl_t hwgraph_root) { nasid_t nasid; cnodeid_t cnode; lboard_t *brd; vertex_hdl_t node_vertex; char path_buffer[100]; int rv; for (cnode = 0; cnode < numnodes; cnode++) { nasid = cnodeid_to_nasid(cnode); brd = find_lboard_class_any((lboard_t *)KL_CONFIG_INFO(nasid), KLTYPE_ROUTER); if (!brd) /* No routers stored in this node's memory */ continue; do { ASSERT(brd); /* Don't add duplicate boards. */ if (brd->brd_flags & DUPLICATE_BOARD) continue; /* Generate a hardware graph path for this board. */ board_to_path(brd, path_buffer); /* Add the router */ rv = hwgraph_path_add(hwgraph_root, path_buffer, &node_vertex); if (rv != GRAPH_SUCCESS) { printk("Router vertex creation " "failed. Path == %s", path_buffer); return; } HWGRAPH_DEBUG(__FILE__, __FUNCTION__, __LINE__, node_vertex, NULL, "Created router path.\n"); /* Find the rest of the routers stored on this node. */ } while ( (brd = find_lboard_class_any(KLCF_NEXT_ANY(brd), KLTYPE_ROUTER)) ); } }
void __init cpu_time_init(void) { lboard_t *board; klcpu_t *cpu; int cpuid; /* Don't use ARCS. ARCS is fragile. Klconfig is simple and sane. */ board = find_lboard(KL_CONFIG_INFO(get_nasid()), KLTYPE_IP27); if (!board) panic("Can't find board info for myself."); cpuid = LOCAL_HUB_L(PI_CPU_NUM) ? IP27_CPU0_INDEX : IP27_CPU1_INDEX; cpu = (klcpu_t *) KLCF_COMP(board, cpuid); if (!cpu) panic("No information about myself?"); printk("CPU %d clock is %dMHz.\n", smp_processor_id(), cpu->cpu_speed); set_c0_status(SRB_TIMOCLK); }
static int do_cpumask(cnodeid_t cnode, nasid_t nasid, int highest) { static int tot_cpus_found = 0; lboard_t *brd; klcpu_t *acpu; int cpus_found = 0; cpuid_t cpuid; brd = find_lboard((lboard_t *)KL_CONFIG_INFO(nasid), KLTYPE_IP27); do { acpu = (klcpu_t *)find_first_component(brd, KLSTRUCT_CPU); while (acpu) { cpuid = acpu->cpu_info.virtid; /* cnode is not valid for completely disabled brds */ if (get_actual_nasid(brd) == brd->brd_nasid) cpuid_to_compact_node[cpuid] = cnode; if (cpuid > highest) highest = cpuid; /* Only let it join in if it's marked enabled */ if ((acpu->cpu_info.flags & KLINFO_ENABLE) && (tot_cpus_found != NR_CPUS)) { cpu_set(cpuid, phys_cpu_present_map); alloc_cpupda(cpuid, tot_cpus_found); cpus_found++; tot_cpus_found++; } acpu = (klcpu_t *)find_component(brd, (klinfo_t *)acpu, KLSTRUCT_CPU); } brd = KLCF_NEXT(brd); if (!brd) break; brd = find_lboard(brd, KLTYPE_IP27); } while (brd); return highest; }
static void __init klhwg_add_xbow(cnodeid_t cnode, nasid_t nasid) { lboard_t *brd; klxbow_t *xbow_p; nasid_t hub_nasid; cnodeid_t hub_cnode; int widgetnum; vertex_hdl_t xbow_v, hubv; /*REFERENCED*/ graph_error_t err; if (!(brd = find_lboard_nasid((lboard_t *)KL_CONFIG_INFO(nasid), nasid, KLTYPE_IOBRICK_XBOW))) return; if (KL_CONFIG_DUPLICATE_BOARD(brd)) return; if ((xbow_p = (klxbow_t *)find_component(brd, NULL, KLSTRUCT_XBOW)) == NULL) return; for (widgetnum = HUB_WIDGET_ID_MIN; widgetnum <= HUB_WIDGET_ID_MAX; widgetnum++) { if (!XBOW_PORT_TYPE_HUB(xbow_p, widgetnum)) continue; hub_nasid = XBOW_PORT_NASID(xbow_p, widgetnum); if (hub_nasid == INVALID_NASID) { printk(KERN_WARNING "hub widget %d, skipping xbow graph\n", widgetnum); continue; } hub_cnode = nasid_to_cnodeid(hub_nasid); if (hub_cnode == INVALID_CNODEID) { continue; } hubv = cnodeid_to_vertex(hub_cnode); err = hwgraph_path_add(hubv, EDGE_LBL_XTALK, &xbow_v); if (err != GRAPH_SUCCESS) { if (err == GRAPH_DUP) printk(KERN_WARNING "klhwg_add_xbow: Check for " "working routers and router links!"); printk("klhwg_add_xbow: Failed to add " "edge: vertex 0x%p to vertex 0x%p," "error %d\n", (void *)hubv, (void *)xbow_v, err); return; } HWGRAPH_DEBUG(__FILE__, __FUNCTION__, __LINE__, xbow_v, NULL, "Created path for xtalk.\n"); xswitch_vertex_init(xbow_v); NODEPDA(hub_cnode)->xbow_vhdl = xbow_v; /* * XXX - This won't work is we ever hook up two hubs * by crosstown through a crossbow. */ if (hub_nasid != nasid) { NODEPDA(hub_cnode)->xbow_peer = nasid; NODEPDA(nasid_to_cnodeid(nasid))->xbow_peer = hub_nasid; } } }
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 */ } }
void io_xswitch_widget_init(vertex_hdl_t xswitchv, vertex_hdl_t hubv, xwidgetnum_t widgetnum) { xswitch_info_t xswitch_info; xwidgetnum_t hub_widgetid; vertex_hdl_t widgetv; cnodeid_t cnode; widgetreg_t widget_id; nasid_t nasid, peer_nasid; struct xwidget_hwid_s hwid; hubinfo_t hubinfo; /*REFERENCED*/ int rc; char pathname[128]; lboard_t *board = NULL; char buffer[16]; char bt; moduleid_t io_module; slotid_t get_widget_slotnum(int xbow, int widget); DBG("\nio_xswitch_widget_init: hubv 0x%p, xswitchv 0x%p, widgetnum 0x%x\n", hubv, xswitchv, widgetnum); /* * Verify that xswitchv is indeed an attached xswitch. */ xswitch_info = xswitch_info_get(xswitchv); ASSERT(xswitch_info != NULL); hubinfo_get(hubv, &hubinfo); nasid = hubinfo->h_nasid; cnode = NASID_TO_COMPACT_NODEID(nasid); hub_widgetid = hubinfo->h_widgetid; /* * Check that the widget is an io widget and is enabled * on this nasid or the `peer' nasid. The peer nasid * is the other hub/bedrock connected to the xbow. */ peer_nasid = NODEPDA(cnode)->xbow_peer; if (peer_nasid == INVALID_NASID) /* If I don't have a peer, use myself. */ peer_nasid = nasid; if (!xbow_port_io_enabled(nasid, widgetnum) && !xbow_port_io_enabled(peer_nasid, widgetnum)) { return; } if (xswitch_info_link_ok(xswitch_info, widgetnum)) { char name[4]; lboard_t dummy; /* * If the current hub is not supposed to be the master * for this widgetnum, then skip this widget. */ if (xswitch_info_master_assignment_get(xswitch_info, widgetnum) != hubv) { return; } board = find_lboard_class( (lboard_t *)KL_CONFIG_INFO(nasid), KLCLASS_IOBRICK); if (!board && NODEPDA(cnode)->xbow_peer != INVALID_NASID) { board = find_lboard_class( (lboard_t *)KL_CONFIG_INFO( NODEPDA(cnode)->xbow_peer), KLCLASS_IOBRICK); } if (board) { DBG("io_xswitch_widget_init: Found KLTYPE_IOBRICK Board 0x%p brd_type 0x%x\n", board, board->brd_type); } else { DBG("io_xswitch_widget_init: FIXME did not find IOBOARD\n"); board = &dummy; } /* Copy over the nodes' geoid info */ { lboard_t *brd; brd = find_lboard((lboard_t *)KL_CONFIG_INFO(nasid), KLTYPE_SNIA); if ( brd != (lboard_t *)0 ) { board->brd_geoid = brd->brd_geoid; } } /* * Make sure we really want to say xbrick, pbrick, * etc. rather than XIO, graphics, etc. */ memset(buffer, 0, 16); format_module_id(buffer, geo_module(board->brd_geoid), MODULE_FORMAT_BRIEF); sprintf(pathname, EDGE_LBL_MODULE "/%s/" EDGE_LBL_SLAB "/%d" "/%s" "/%s/%d", buffer, geo_slab(board->brd_geoid), (board->brd_type == KLTYPE_IBRICK) ? EDGE_LBL_IBRICK : (board->brd_type == KLTYPE_PBRICK) ? EDGE_LBL_PBRICK : (board->brd_type == KLTYPE_PXBRICK) ? EDGE_LBL_PXBRICK : (board->brd_type == KLTYPE_IXBRICK) ? EDGE_LBL_IXBRICK : (board->brd_type == KLTYPE_CGBRICK) ? EDGE_LBL_CGBRICK : (board->brd_type == KLTYPE_OPUSBRICK) ? EDGE_LBL_OPUSBRICK : (board->brd_type == KLTYPE_XBRICK) ? EDGE_LBL_XBRICK : "?brick", EDGE_LBL_XTALK, widgetnum); DBG("io_xswitch_widget_init: path= %s\n", pathname); rc = hwgraph_path_add(hwgraph_root, pathname, &widgetv); ASSERT(rc == GRAPH_SUCCESS); /* This is needed to let the user programs to map the * module,slot numbers to the corresponding widget numbers * on the crossbow. */ device_master_set(hwgraph_connectpt_get(widgetv), hubv); sprintf(name, "%d", widgetnum); DBG("io_xswitch_widget_init: FIXME hwgraph_edge_add %s xswitchv 0x%p, widgetv 0x%p\n", name, xswitchv, widgetv); rc = hwgraph_edge_add(xswitchv, widgetv, name); /* * crosstalk switch code tracks which * widget is attached to each link. */ xswitch_info_vhdl_set(xswitch_info, widgetnum, widgetv); /* * Peek at the widget to get its crosstalk part and * mfgr numbers, then present it to the generic xtalk * bus provider to have its driver attach routine * called (or not). */ widget_id = XWIDGET_ID_READ(nasid, widgetnum); hwid.part_num = XWIDGET_PART_NUM(widget_id); hwid.rev_num = XWIDGET_REV_NUM(widget_id); hwid.mfg_num = XWIDGET_MFG_NUM(widget_id); /* Store some inventory information about * the xwidget in the hardware graph. */ xwidget_inventory_add(widgetv,board,hwid); (void)xwidget_register(&hwid, widgetv, widgetnum, hubv, hub_widgetid); ia64_sn_sysctl_iobrick_module_get(nasid, &io_module); if (io_module >= 0) { char buffer[16]; vertex_hdl_t to, from; char *brick_name; extern char *iobrick_L1bricktype_to_name(int type); memset(buffer, 0, 16); format_module_id(buffer, geo_module(board->brd_geoid), MODULE_FORMAT_BRIEF); if ( isupper(MODULE_GET_BTCHAR(io_module)) ) { bt = tolower(MODULE_GET_BTCHAR(io_module)); } else { bt = MODULE_GET_BTCHAR(io_module); } brick_name = iobrick_L1bricktype_to_name(bt); /* Add a helper vertex so xbow monitoring * can identify the brick type. It's simply * an edge from the widget 0 vertex to the * brick vertex. */ sprintf(pathname, EDGE_LBL_HW "/" EDGE_LBL_MODULE "/%s/" EDGE_LBL_SLAB "/%d/" EDGE_LBL_NODE "/" EDGE_LBL_XTALK "/" "0", buffer, geo_slab(board->brd_geoid)); DBG("io_xswitch_widget_init: FROM path '%s'\n", pathname); from = hwgraph_path_to_vertex(pathname); ASSERT_ALWAYS(from); sprintf(pathname, EDGE_LBL_HW "/" EDGE_LBL_MODULE "/%s/" EDGE_LBL_SLAB "/%d/" "%s", buffer, geo_slab(board->brd_geoid), brick_name); DBG("io_xswitch_widget_init: TO path '%s'\n", pathname); to = hwgraph_path_to_vertex(pathname); ASSERT_ALWAYS(to); rc = hwgraph_edge_add(from, to, EDGE_LBL_INTERCONNECT); if (rc == -EEXIST) goto link_done; if (rc != GRAPH_SUCCESS) { printk("%s: Unable to establish link" " for xbmon.", pathname); } link_done: } #ifdef SN0_USE_BTE bte_bpush_war(cnode, (void *)board); #endif } }
void io_xswitch_widget_init(devfs_handle_t xswitchv, devfs_handle_t hubv, xwidgetnum_t widgetnum, async_attach_t aa) { xswitch_info_t xswitch_info; xwidgetnum_t hub_widgetid; devfs_handle_t widgetv; cnodeid_t cnode; widgetreg_t widget_id; nasid_t nasid, peer_nasid; struct xwidget_hwid_s hwid; hubinfo_t hubinfo; /*REFERENCED*/ int rc; char pathname[128]; char new_name[64]; moduleid_t module; slotid_t slot; lboard_t *board = NULL; char buffer[16]; slotid_t get_widget_slotnum(int xbow, int widget); DBG("\nio_xswitch_widget_init: hubv 0x%p, xswitchv 0x%p, widgetnum 0x%x\n", hubv, xswitchv, widgetnum); /* * Verify that xswitchv is indeed an attached xswitch. */ xswitch_info = xswitch_info_get(xswitchv); ASSERT(xswitch_info != NULL); hubinfo_get(hubv, &hubinfo); nasid = hubinfo->h_nasid; cnode = NASID_TO_COMPACT_NODEID(nasid); hub_widgetid = hubinfo->h_widgetid; /* * Check that the widget is an io widget and is enabled * on this nasid or the `peer' nasid. The peer nasid * is the other hub/bedrock connected to the xbow. */ peer_nasid = NODEPDA(cnode)->xbow_peer; if (peer_nasid == INVALID_NASID) /* If I don't have a peer, use myself. */ peer_nasid = nasid; if (!xbow_port_io_enabled(nasid, widgetnum) && !xbow_port_io_enabled(peer_nasid, widgetnum)) { return; } if (xswitch_info_link_ok(xswitch_info, widgetnum)) { char name[4]; /* * If the current hub is not supposed to be the master * for this widgetnum, then skip this widget. */ if (xswitch_info_master_assignment_get(xswitch_info, widgetnum) != hubv) { return; } module = NODEPDA(cnode)->module_id; #ifdef XBRIDGE_REGS_SIM /* hardwire for now...could do this with something like: * xbow_soft_t soft = hwgraph_fastinfo_get(vhdl); * xbow_t xbow = soft->base; * xbowreg_t xwidget_id = xbow->xb_wid_id; * but I don't feel like figuring out vhdl right now.. * and I know for a fact the answer is 0x2d000049 */ DBG("io_xswitch_widget_init: XBRIDGE_REGS_SIM FIXME: reading xwidget id: hardwired to xbridge (0x2d000049).\n"); DBG("XWIDGET_PART_NUM(0x2d000049)= 0x%x\n", XWIDGET_PART_NUM(0x2d000049)); if (XWIDGET_PART_NUM(0x2d000049)==XXBOW_WIDGET_PART_NUM) #else if (nasid_has_xbridge(nasid)) #endif /* XBRIDGE_REGS_SIM */ { board = find_lboard_module_class( (lboard_t *)KL_CONFIG_INFO(nasid), module, KLTYPE_IOBRICK); DBG("io_xswitch_widget_init: Board 0x%p\n", board); { lboard_t dummy; if (board) { DBG("io_xswitch_widget_init: Found KLTYPE_IOBRICK Board 0x%p brd_type 0x%x\n", board, board->brd_type); } else { DBG("io_xswitch_widget_init: FIXME did not find IOBOARD\n"); board = &dummy; } } /* * Make sure we really want to say xbrick, pbrick, * etc. rather than XIO, graphics, etc. */ #ifdef SUPPORT_PRINTING_M_FORMAT sprintf(pathname, EDGE_LBL_MODULE "/%M/" "%cbrick" "/%s/%d", NODEPDA(cnode)->module_id, #else memset(buffer, 0, 16); format_module_id(buffer, NODEPDA(cnode)->module_id, MODULE_FORMAT_BRIEF); sprintf(pathname, EDGE_LBL_MODULE "/%s/" "%cbrick" "/%s/%d", buffer, #endif (board->brd_type == KLTYPE_IBRICK) ? 'I' : (board->brd_type == KLTYPE_PBRICK) ? 'P' : (board->brd_type == KLTYPE_XBRICK) ? 'X' : '?', EDGE_LBL_XTALK, widgetnum); } DBG("io_xswitch_widget_init: path= %s\n", pathname); rc = hwgraph_path_add(hwgraph_root, pathname, &widgetv); ASSERT(rc == GRAPH_SUCCESS); /* This is needed to let the user programs to map the * module,slot numbers to the corresponding widget numbers * on the crossbow. */ rc = device_master_set(hwgraph_connectpt_get(widgetv), hubv); /* If we are looking at the global master io6 * then add information about the version of * the io6prom as a part of "detailed inventory" * information. */ if (is_master_baseio(nasid, NODEPDA(cnode)->module_id, get_widget_slotnum(0,widgetnum))) { extern void klhwg_baseio_inventory_add(devfs_handle_t, cnodeid_t); module = NODEPDA(cnode)->module_id; #ifdef XBRIDGE_REGS_SIM DBG("io_xswitch_widget_init: XBRIDGE_REGS_SIM FIXME: reading xwidget id: hardwired to xbridge (0x2d000049).\n"); if (XWIDGET_PART_NUM(0x2d000049)==XXBOW_WIDGET_PART_NUM) #else if (nasid_has_xbridge(nasid)) #endif /* XBRIDGE_REGS_SIM */ { board = find_lboard_module( (lboard_t *)KL_CONFIG_INFO(nasid), module); /* * Change iobrick to correct i/o brick */ #ifdef SUPPORT_PRINTING_M_FORMAT sprintf(pathname, EDGE_LBL_MODULE "/%M/" #else sprintf(pathname, EDGE_LBL_MODULE "/%x/" #endif "iobrick" "/%s/%d", NODEPDA(cnode)->module_id, EDGE_LBL_XTALK, widgetnum); } else { slot = get_widget_slotnum(0, widgetnum); board = get_board_name(nasid, module, slot, new_name); /* * Create the vertex for the widget, * using the decimal * widgetnum as the name of the primary edge. */ #ifdef SUPPORT_PRINTING_M_FORMAT sprintf(pathname, EDGE_LBL_MODULE "/%M/" EDGE_LBL_SLOT "/%s", NODEPDA(cnode)->module_id, new_name); #else memset(buffer, 0, 16); format_module_id(buffer, NODEPDA(cnode)->module_id, MODULE_FORMAT_BRIEF); sprintf(pathname, EDGE_LBL_MODULE "/%s/" EDGE_LBL_SLOT "/%s", buffer, new_name); #endif } rc = hwgraph_path_add(hwgraph_root, pathname, &widgetv); DBG("io_xswitch_widget_init: (2) path= %s\n", pathname); /* * This is a weird ass code needed for error injection * purposes. */ rc = device_master_set(hwgraph_connectpt_get(widgetv), hubv); klhwg_baseio_inventory_add(widgetv,cnode); } sprintf(name, "%d", widgetnum); DBG("io_xswitch_widget_init: FIXME hwgraph_edge_add %s xswitchv 0x%p, widgetv 0x%p\n", name, xswitchv, widgetv); rc = hwgraph_edge_add(xswitchv, widgetv, name); /* * crosstalk switch code tracks which * widget is attached to each link. */ xswitch_info_vhdl_set(xswitch_info, widgetnum, widgetv); /* * Peek at the widget to get its crosstalk part and * mfgr numbers, then present it to the generic xtalk * bus provider to have its driver attach routine * called (or not). */ #ifdef XBRIDGE_REGS_SIM widget_id = 0x2d000049; DBG("io_xswitch_widget_init: XBRIDGE_REGS_SIM FIXME: id hardwired to widget_id\n"); #else widget_id = XWIDGET_ID_READ(nasid, widgetnum); #endif /* XBRIDGE_REGS_SIM */ hwid.part_num = XWIDGET_PART_NUM(widget_id); hwid.rev_num = XWIDGET_REV_NUM(widget_id); hwid.mfg_num = XWIDGET_MFG_NUM(widget_id); /* Store some inventory information about * the xwidget in the hardware graph. */ xwidget_inventory_add(widgetv,board,hwid); (void)xwidget_register(&hwid, widgetv, widgetnum, hubv, hub_widgetid, aa); #ifdef SN0_USE_BTE bte_bpush_war(cnode, (void *)board); #endif }
static void __init klhwg_connect_hubs(vertex_hdl_t hwgraph_root) { nasid_t nasid; cnodeid_t cnode; lboard_t *brd; klhub_t *hub; lboard_t *dest_brd; vertex_hdl_t hub_hndl; vertex_hdl_t dest_hndl; char path_buffer[50]; char dest_path[50]; graph_error_t rc; int port; for (cnode = 0; cnode < numionodes; cnode++) { nasid = cnodeid_to_nasid(cnode); brd = find_lboard_any((lboard_t *)KL_CONFIG_INFO(nasid), KLTYPE_SNIA); hub = (klhub_t *)find_first_component(brd, KLSTRUCT_HUB); ASSERT(hub); for (port = 1; port <= MAX_NI_PORTS; port++) { if (hub->hub_port[port].port_nasid == INVALID_NASID) { continue; /* Port not active */ } if (nasid_to_cnodeid(hub->hub_port[port].port_nasid) == INVALID_CNODEID) continue; /* Generate a hardware graph path for this board. */ board_to_path(brd, path_buffer); rc = hwgraph_traverse(hwgraph_root, path_buffer, &hub_hndl); if (rc != GRAPH_SUCCESS) printk(KERN_WARNING "Can't find hub: %s", path_buffer); dest_brd = (lboard_t *)NODE_OFFSET_TO_K0( hub->hub_port[port].port_nasid, hub->hub_port[port].port_offset); /* Generate a hardware graph path for this board. */ board_to_path(dest_brd, dest_path); rc = hwgraph_traverse(hwgraph_root, dest_path, &dest_hndl); if (rc != GRAPH_SUCCESS) { if (KL_CONFIG_DUPLICATE_BOARD(dest_brd)) continue; printk("Can't find board: %s", dest_path); return; } else { char buf[1024]; rc = hwgraph_path_add(hub_hndl, EDGE_LBL_INTERCONNECT, &hub_hndl); HWGRAPH_DEBUG(__FILE__, __FUNCTION__, __LINE__, hub_hndl, NULL, "Created link path.\n"); sprintf(buf,"%s/%s",path_buffer,EDGE_LBL_INTERCONNECT); rc = hwgraph_traverse(hwgraph_root, buf, &hub_hndl); sprintf(buf,"%d",port); rc = hwgraph_edge_add(hub_hndl, dest_hndl, buf); HWGRAPH_DEBUG(__FILE__, __FUNCTION__, __LINE__, hub_hndl, dest_hndl, "Created edge %s from vhdl1 to vhdl2.\n", buf); if (rc != GRAPH_SUCCESS) { printk("Can't create edge: %s/%s to vertex 0x%p, error 0x%x\n", path_buffer, dest_path, (void *)dest_hndl, rc); return; } } } } }
/* ARGSUSED */ static void __init klhwg_add_node(vertex_hdl_t hwgraph_root, cnodeid_t cnode) { nasid_t nasid; lboard_t *brd; klhub_t *hub; vertex_hdl_t node_vertex = NULL; char path_buffer[100]; int rv; char *s; int board_disabled = 0; klcpu_t *cpu; vertex_hdl_t cpu_dir; nasid = cnodeid_to_nasid(cnode); brd = find_lboard_any((lboard_t *)KL_CONFIG_INFO(nasid), KLTYPE_SNIA); ASSERT(brd); /* Generate a hardware graph path for this board. */ board_to_path(brd, path_buffer); rv = hwgraph_path_add(hwgraph_root, path_buffer, &node_vertex); if (rv != GRAPH_SUCCESS) { printk("Node vertex creation failed. Path == %s", path_buffer); return; } HWGRAPH_DEBUG(__FILE__, __FUNCTION__, __LINE__, node_vertex, NULL, "Created path for SHUB node.\n"); hub = (klhub_t *)find_first_component(brd, KLSTRUCT_HUB); ASSERT(hub); if(hub->hub_info.flags & KLINFO_ENABLE) board_disabled = 0; else board_disabled = 1; if(!board_disabled) { mark_nodevertex_as_node(node_vertex, cnode); s = dev_to_name(node_vertex, path_buffer, sizeof(path_buffer)); NODEPDA(cnode)->hwg_node_name = kmalloc(strlen(s) + 1, GFP_KERNEL); if (NODEPDA(cnode)->hwg_node_name <= 0) { printk("%s: no memory\n", __FUNCTION__); return; } strcpy(NODEPDA(cnode)->hwg_node_name, s); hubinfo_set(node_vertex, NODEPDA(cnode)->pdinfo); NODEPDA(cnode)->slotdesc = brd->brd_slot; NODEPDA(cnode)->geoid = brd->brd_geoid; NODEPDA(cnode)->module = module_lookup(geo_module(brd->brd_geoid)); klhwg_add_hub(node_vertex, hub, cnode); } /* * If there's at least 1 CPU, add a "cpu" directory to represent * the collection of all CPUs attached to this node. */ cpu = (klcpu_t *)find_first_component(brd, KLSTRUCT_CPU); if (cpu) { graph_error_t rv; rv = hwgraph_path_add(node_vertex, EDGE_LBL_CPU, &cpu_dir); if (rv != GRAPH_SUCCESS) { printk("klhwg_add_node: Cannot create CPU directory\n"); return; } HWGRAPH_DEBUG(__FILE__, __FUNCTION__, __LINE__, cpu_dir, NULL, "Created cpu directiry on SHUB node.\n"); } while (cpu) { cpuid_t cpu_id; cpu_id = nasid_slice_to_cpuid(nasid,cpu->cpu_info.physid); if (cpu_online(cpu_id)) klhwg_add_cpu(node_vertex, cnode, cpu); else klhwg_add_disabled_cpu(node_vertex, cnode, cpu, brd->brd_slot); cpu = (klcpu_t *) find_component(brd, (klinfo_t *)cpu, KLSTRUCT_CPU); } }
int module_probe_snum(module_t *m, nasid_t nasid) { lboard_t *board; klmod_serial_num_t *comp; char * bcopy(const char * src, char * dest, int count); char serial_number[16]; /* * record brick serial number */ board = find_lboard((lboard_t *) KL_CONFIG_INFO(nasid), KLTYPE_SNIA); if (! board || KL_CONFIG_DUPLICATE_BOARD(board)) { #if LDEBUG printf ("module_probe_snum: no IP35 board found!\n"); #endif return 0; } board_serial_number_get( board, serial_number ); if( serial_number[0] != '\0' ) { encode_str_serial( serial_number, m->snum.snum_str ); m->snum_valid = 1; } #if LDEBUG else { printf("module_probe_snum: brick serial number is null!\n"); } printf("module_probe_snum: brick serial number == %s\n", serial_number); #endif /* DEBUG */ board = find_lboard((lboard_t *) KL_CONFIG_INFO(nasid), KLTYPE_IOBRICK_XBOW); if (! board || KL_CONFIG_DUPLICATE_BOARD(board)) return 0; comp = GET_SNUM_COMP(board); if (comp) { #if LDEBUG int i; printf("********found module with id %x and string", m->id); for (i = 0; i < MAX_SERIAL_NUM_SIZE; i++) printf(" %x ", comp->snum.snum_str[i]); printf("\n"); /* Fudged string is not ASCII */ #endif if (comp->snum.snum_str[0] != '\0') { bcopy(comp->snum.snum_str, m->sys_snum, MAX_SERIAL_NUM_SIZE); m->sys_snum_valid = 1; } } if (m->sys_snum_valid) return 1; else { DPRINTF("Invalid serial number for module %d, " "possible missing or invalid NIC.", m->id); return 0; } }