Esempio n. 1
0
static void __init scan_for_ionodes(void)
{
	int nasid = 0;
	lboard_t *brd;

	/* Setup ionodes with memory */
	for (nasid = 0; nasid < MAX_PHYSNODE_ID; nasid += 2) {
		char *klgraph_header;
		cnodeid_t cnodeid;

		if (physical_node_map[nasid] == -1)
			continue;

		cnodeid = -1;
		klgraph_header = __va(ia64_sn_get_klconfig_addr(nasid));
		if (!klgraph_header) {
			if (IS_RUNNING_ON_SIMULATOR())
				continue;
			BUG();	/* All nodes must have klconfig tables! */
		}
		cnodeid = nasid_to_cnodeid(nasid);
		root_lboard[cnodeid] = (lboard_t *)
		    NODE_OFFSET_TO_LBOARD((nasid),
					  ((kl_config_hdr_t
					    *) (klgraph_header))->
					  ch_board_info);
	}

	/* Scan headless/memless IO Nodes. */
	for (nasid = 0; nasid < MAX_PHYSNODE_ID; nasid += 2) {
		/* if there's no nasid, don't try to read the klconfig on the node */
		if (physical_node_map[nasid] == -1)
			continue;
		brd = find_lboard_any((lboard_t *)
				      root_lboard[nasid_to_cnodeid(nasid)],
				      KLTYPE_SNIA);
		if (brd) {
			brd = KLCF_NEXT_ANY(brd);	/* Skip this node's lboard */
			if (!brd)
				continue;
		}

		brd = find_lboard_any(brd, KLTYPE_SNIA);

		while (brd) {
			pda->cnodeid_to_nasid_table[numionodes] =
			    brd->brd_nasid;
			physical_node_map[brd->brd_nasid] = numionodes;
			root_lboard[numionodes] = brd;
			numionodes++;
			brd = KLCF_NEXT_ANY(brd);
			if (!brd)
				break;

			brd = find_lboard_any(brd, KLTYPE_SNIA);
		}
	}

	/* Scan for TIO nodes. */
	for (nasid = 0; nasid < MAX_PHYSNODE_ID; nasid += 2) {
		/* if there's no nasid, don't try to read the klconfig on the node */
		if (physical_node_map[nasid] == -1)
			continue;
		brd = find_lboard_any((lboard_t *)
				      root_lboard[nasid_to_cnodeid(nasid)],
				      KLTYPE_TIO);
		while (brd) {
			pda->cnodeid_to_nasid_table[numionodes] =
			    brd->brd_nasid;
			physical_node_map[brd->brd_nasid] = numionodes;
			root_lboard[numionodes] = brd;
			numionodes++;
			brd = KLCF_NEXT_ANY(brd);
			if (!brd)
				break;

			brd = find_lboard_any(brd, KLTYPE_TIO);
		}
	}

}
Esempio n. 2
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);
	}
}
Esempio n. 3
0
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;
				}
			}
		}
	}
}
Esempio n. 4
0
static 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_cnodeid(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_nasid( (lboard_t *)KL_CONFIG_INFO(nasid),
				nasid, KLCLASS_IOBRICK);
		if (!board && NODEPDA(cnode)->xbow_peer != INVALID_NASID) {
		    	board = find_lboard_class_nasid(
				(lboard_t *)KL_CONFIG_INFO( NODEPDA(cnode)->xbow_peer),
					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_any((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_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 : "?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);

		(void)xwidget_register(&hwid, widgetv, widgetnum,
				       hubv, hub_widgetid);

		io_module = iomoduleid_get(nasid);
		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));
			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);

			to = hwgraph_path_to_vertex(pathname);
			ASSERT_ALWAYS(to);
			rc = hwgraph_edge_add(from, to,
				EDGE_LBL_INTERCONNECT);
			if (rc != -EEXIST && rc != GRAPH_SUCCESS) {
				printk("%s: Unable to establish link"
					" for xbmon.", pathname);
			}
		}

	}
}