static int sn_hwperf_geoid_to_cnode(char *location) { int cnode; geoid_t geoid; moduleid_t module_id; int rack, bay, slot, slab; int this_rack, this_bay, this_slot, this_slab; if (sn_hwperf_location_to_bpos(location, &rack, &bay, &slot, &slab)) return -1; for (cnode = 0; cnode < numionodes; cnode++) { geoid = cnodeid_get_geoid(cnode); module_id = geo_module(geoid); this_rack = MODULE_GET_RACK(module_id); this_bay = MODULE_GET_BPOS(module_id); this_slot = geo_slot(geoid); this_slab = geo_slab(geoid); if (rack == this_rack && bay == this_bay && slot == this_slot && slab == this_slab) { break; } } return cnode < numionodes ? cnode : -1; }
int geo_cmp(geoid_t g0, geoid_t g1) { int rv; /* Compare the common fields */ rv = MODULE_CMP(geo_module(g0), geo_module(g1)); if (rv != 0) return rv; rv = geo_slab(g0) - geo_slab(g1); if (rv != 0) return rv; /* Within a slab, sort by type */ rv = geo_type(g0) - geo_type(g1); if (rv != 0) return rv; switch(geo_type(g0)) { case GEO_TYPE_CPU: rv = g0.cpu.slice - g1.cpu.slice; break; case GEO_TYPE_IOCARD: rv = g0.pcicard.bus - g1.pcicard.bus; if (rv) break; rv = SLOTNUM_GETSLOT(g0.pcicard.slot) - SLOTNUM_GETSLOT(g1.pcicard.slot); break; case GEO_TYPE_MEM: rv = g0.mem.membus - g1.mem.membus; if (rv) break; rv = g0.mem.memslot - g1.mem.memslot; break; default: rv = 0; } return rv; }
static int tiocx_btchar_get(int nasid) { moduleid_t module_id; geoid_t geoid; int cnodeid; cnodeid = nasid_to_cnodeid(nasid); geoid = cnodeid_get_geoid(cnodeid); module_id = geo_module(geoid); return MODULE_GET_BTCHAR(module_id); }
/* Add inventory information to the widget vertex * Right now (module,slot,revision) is being * added as inventory information. */ static void xwidget_inventory_add(vertex_hdl_t widgetv, lboard_t *board, struct xwidget_hwid_s hwid) { if (!board) return; /* Donot add inventory information for the baseio * on a speedo with an xbox. It has already been * taken care of in SN00_vmc. * Speedo with xbox's baseio comes in at slot io1 (widget 9) */ device_inventory_add(widgetv,INV_IOBD,board->brd_type, geo_module(board->brd_geoid), SLOTNUM_GETSLOT(board->brd_slot), hwid.rev_num); }
module_t *module_add_node(geoid_t geoid, cnodeid_t cnodeid) { module_t *m; int i; char buffer[16]; moduleid_t moduleid; memset(buffer, 0, 16); moduleid = geo_module(geoid); format_module_id(buffer, moduleid, MODULE_FORMAT_BRIEF); DPRINTF("module_add_node: moduleid=%s node=%d\n", buffer, cnodeid); if ((m = module_lookup(moduleid)) == 0) { m = kmalloc(sizeof (module_t), GFP_KERNEL); memset(m, 0 , sizeof(module_t)); ASSERT_ALWAYS(m); m->id = moduleid; spin_lock_init(&m->lock); mutex_init_locked(&m->thdcnt); /* Insert in sorted order by module number */ for (i = nummodules; i > 0 && modules[i - 1]->id > moduleid; i--) modules[i] = modules[i - 1]; modules[i] = m; nummodules++; } m->nodes[m->nodecnt] = cnodeid; m->geoid[m->nodecnt] = geoid; m->nodecnt++; DPRINTF("module_add_node: module %s now has %d nodes\n", buffer, m->nodecnt); return m; }
/* * scdrv_init * * Called at boot time to initialize the system controller communication * facility. */ int __init scdrv_init(void) { geoid_t geoid; cnodeid_t cnode; char devname[32]; char *devnamep; struct sysctl_data_s *scd; void *salbuf; dev_t first_dev, dev; nasid_t event_nasid = ia64_sn_get_console_nasid(); if (alloc_chrdev_region(&first_dev, 0, numionodes, SYSCTL_BASENAME) < 0) { printk("%s: failed to register SN system controller device\n", __FUNCTION__); return -ENODEV; } snsc_class = class_create(THIS_MODULE, SYSCTL_BASENAME); for (cnode = 0; cnode < numionodes; cnode++) { geoid = cnodeid_get_geoid(cnode); devnamep = devname; format_module_id(devnamep, geo_module(geoid), MODULE_FORMAT_BRIEF); devnamep = devname + strlen(devname); sprintf(devnamep, "#%d", geo_slab(geoid)); /* allocate sysctl device data */ scd = kmalloc(sizeof (struct sysctl_data_s), GFP_KERNEL); if (!scd) { printk("%s: failed to allocate device info" "for %s/%s\n", __FUNCTION__, SYSCTL_BASENAME, devname); continue; } memset(scd, 0, sizeof (struct sysctl_data_s)); /* initialize sysctl device data fields */ scd->scd_nasid = cnodeid_to_nasid(cnode); if (!(salbuf = kmalloc(SCDRV_BUFSZ, GFP_KERNEL))) { printk("%s: failed to allocate driver buffer" "(%s%s)\n", __FUNCTION__, SYSCTL_BASENAME, devname); kfree(scd); continue; } if (ia64_sn_irtr_init(scd->scd_nasid, salbuf, SCDRV_BUFSZ) < 0) { printk ("%s: failed to initialize SAL for" " system controller communication" " (%s/%s): outdated PROM?\n", __FUNCTION__, SYSCTL_BASENAME, devname); kfree(scd); kfree(salbuf); continue; } dev = first_dev + cnode; cdev_init(&scd->scd_cdev, &scdrv_fops); if (cdev_add(&scd->scd_cdev, dev, 1)) { printk("%s: failed to register system" " controller device (%s%s)\n", __FUNCTION__, SYSCTL_BASENAME, devname); kfree(scd); kfree(salbuf); continue; } class_device_create(snsc_class, dev, NULL, "%s", devname); ia64_sn_irtr_intr_enable(scd->scd_nasid, 0 /*ignored */ , SAL_IROUTER_INTR_RECV); /* on the console nasid, prepare to receive * system controller environmental events */ if(scd->scd_nasid == event_nasid) { scdrv_event_init(scd); } } return 0; }
/* 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); } }
/* * scdrv_init * * Called at boot time to initialize the system controller communication * facility. */ int __init scdrv_init(void) { geoid_t geoid; cmoduleid_t cmod; int i; char devname[32]; char *devnamep; module_t *m; struct sysctl_data_s *scd; void *salbuf; struct class_simple *snsc_class; dev_t first_dev, dev; if (alloc_chrdev_region(&first_dev, 0, (MAX_SLABS*nummodules), SYSCTL_BASENAME) < 0) { printk("%s: failed to register SN system controller device\n", __FUNCTION__); return -ENODEV; } snsc_class = class_simple_create(THIS_MODULE, SYSCTL_BASENAME); for (cmod = 0; cmod < nummodules; cmod++) { m = sn_modules[cmod]; for (i = 0; i <= MAX_SLABS; i++) { if (m->nodes[i] == -1) { /* node is not alive in module */ continue; } geoid = m->geoid[i]; devnamep = devname; format_module_id(devnamep, geo_module(geoid), MODULE_FORMAT_BRIEF); devnamep = devname + strlen(devname); sprintf(devnamep, "#%d", geo_slab(geoid)); /* allocate sysctl device data */ scd = kmalloc(sizeof (struct sysctl_data_s), GFP_KERNEL); if (!scd) { printk("%s: failed to allocate device info" "for %s/%s\n", __FUNCTION__, SYSCTL_BASENAME, devname); continue; } memset(scd, 0, sizeof (struct sysctl_data_s)); /* initialize sysctl device data fields */ scd->scd_nasid = cnodeid_to_nasid(m->nodes[i]); if (!(salbuf = kmalloc(SCDRV_BUFSZ, GFP_KERNEL))) { printk("%s: failed to allocate driver buffer" "(%s%s)\n", __FUNCTION__, SYSCTL_BASENAME, devname); kfree(scd); continue; } if (ia64_sn_irtr_init(scd->scd_nasid, salbuf, SCDRV_BUFSZ) < 0) { printk ("%s: failed to initialize SAL for" " system controller communication" " (%s/%s): outdated PROM?\n", __FUNCTION__, SYSCTL_BASENAME, devname); kfree(scd); kfree(salbuf); continue; } dev = first_dev + m->nodes[i]; cdev_init(&scd->scd_cdev, &scdrv_fops); if (cdev_add(&scd->scd_cdev, dev, 1)) { printk("%s: failed to register system" " controller device (%s%s)\n", __FUNCTION__, SYSCTL_BASENAME, devname); kfree(scd); kfree(salbuf); continue; } class_simple_device_add(snsc_class, dev, NULL, "%s", devname); ia64_sn_irtr_intr_enable(scd->scd_nasid, 0 /*ignored */ , SAL_IROUTER_INTR_RECV); } } return 0; }
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 } }
/* * If this PIC is attached to two Cbricks ("dual-ported") then * attach each bus to opposite Cbricks. * * If successful, return a new vertex suitable for attaching the PIC bus. * If not successful, return zero and both buses will attach to the * vertex passed into pic_attach(). */ static vertex_hdl_t pic_bus1_redist(nasid_t nasid, vertex_hdl_t conn_v) { cnodeid_t cnode = nasid_to_cnodeid(nasid); cnodeid_t xbow_peer = -1; char pathname[256], peer_path[256], tmpbuf[256]; char *p; int rc; vertex_hdl_t peer_conn_v, hubv; int pos; slabid_t slab; if (NODEPDA(cnode)->xbow_peer >= 0) { /* if dual-ported */ /* create a path for this widget on the peer Cbrick */ /* pcibr widget hw/module/001c11/slab/0/Pbrick/xtalk/12 */ /* sprintf(pathname, "%v", conn_v); */ xbow_peer = nasid_to_cnodeid(NODEPDA(cnode)->xbow_peer); pos = hwgfs_generate_path(conn_v, tmpbuf, 256); strcpy(pathname, &tmpbuf[pos]); p = pathname + strlen("hw/module/001c01/slab/0/"); memset(tmpbuf, 0, 16); format_module_id(tmpbuf, geo_module((NODEPDA(xbow_peer))->geoid), MODULE_FORMAT_BRIEF); slab = geo_slab((NODEPDA(xbow_peer))->geoid); sprintf(peer_path, "module/%s/slab/%d/%s", tmpbuf, (int)slab, p); /* Look for vertex for this widget on the peer Cbrick. * Expect GRAPH_NOT_FOUND. */ rc = hwgraph_traverse(hwgraph_root, peer_path, &peer_conn_v); if (GRAPH_SUCCESS == rc) printk("pic_attach: found unexpected vertex: 0x%lx\n", (uint64_t)peer_conn_v); else if (GRAPH_NOT_FOUND != rc) { printk("pic_attach: hwgraph_traverse unexpectedly" " returned 0x%x\n", rc); } else { /* try to add the widget vertex to the peer Cbrick */ rc = hwgraph_path_add(hwgraph_root, peer_path, &peer_conn_v); if (GRAPH_SUCCESS != rc) printk("pic_attach: hwgraph_path_add" " failed with 0x%x\n", rc); else { PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_ATTACH, conn_v, "pic_bus1_redist: added vertex %v\n", peer_conn_v)); /* Now hang appropiate stuff off of the new * vertex. We bail out if we cannot add something. * In that case, we don't remove the newly added * vertex but that should be safe and we don't * really expect the additions to fail anyway. */ if (!pic_bus1_widget_info_dup(conn_v, peer_conn_v, xbow_peer, peer_path)) return 0; hubv = cnodeid_to_vertex(xbow_peer); ASSERT(hubv != GRAPH_VERTEX_NONE); device_master_set(peer_conn_v, hubv); xtalk_provider_register(hubv, &hub_provider); xtalk_provider_startup(hubv); return peer_conn_v; } } } return 0; }