Ejemplo n.º 1
0
vertex_hdl_t
pciio_device_info_register(
		vertex_hdl_t connectpt,		/* vertex at center of bus */
		pciio_info_t pciio_info)	/* details about the connectpt */
{
    char		name[32];
    vertex_hdl_t	pconn;
    int device_master_set(vertex_hdl_t, vertex_hdl_t);

    pciio_slot_func_to_name(name,
			    pciio_info->c_slot,
			    pciio_info->c_func);

    if (GRAPH_SUCCESS !=
	hwgraph_path_add(connectpt, name, &pconn))
	return pconn;

    pciio_info->c_vertex = pconn;
    pciio_info_set(pconn, pciio_info);
#ifdef DEBUG_PCIIO
    {
	int pos;
	char dname[256];
	pos = devfs_generate_path(pconn, dname, 256);
	printk("%s : pconn path= %s \n", __FUNCTION__, &dname[pos]);
    }
#endif /* DEBUG_PCIIO */

    /*
     * create link to our pci provider
     */

    device_master_set(pconn, pciio_info->c_master);
    return pconn;
}
Ejemplo n.º 2
0
void
mark_nodevertex_as_node(devfs_handle_t vhdl, cnodeid_t cnodeid)
{
	if (cnodeid == CNODEID_NONE)
		return;

	cnodeid_to_vertex(cnodeid) = vhdl;
	labelcl_info_add_LBL(vhdl, INFO_LBL_CNODEID, INFO_DESC_EXPORT, 
		(arbitrary_info_t)cnodeid);

	{
		char cnodeid_buffer[10];

		if (hwgraph_all_cnodes == GRAPH_VERTEX_NONE) {
			(void)hwgraph_path_add( hwgraph_root,
						EDGE_LBL_NODENUM,
						&hwgraph_all_cnodes);
		}

		sprintf(cnodeid_buffer, "%d", cnodeid);
		(void)hwgraph_edge_add( hwgraph_all_cnodes,
					vhdl,
					cnodeid_buffer);
	}
}
Ejemplo n.º 3
0
/* ARGSUSED */
static void __init
klhwg_add_cpu(vertex_hdl_t node_vertex, cnodeid_t cnode, klcpu_t *cpu)
{
        vertex_hdl_t my_cpu, cpu_dir;
        char name[120];
        cpuid_t cpu_id;
	nasid_t nasid;

	nasid = cnodeid_to_nasid(cnode);
        cpu_id = nasid_slice_to_cpuid(nasid, cpu->cpu_info.physid);

        snprintf(name, 120, "%s/%d/%c",
                EDGE_LBL_CPUBUS,
                0,
                'a' + cpu->cpu_info.physid);

        (void) hwgraph_path_add(node_vertex, name, &my_cpu);

	HWGRAPH_DEBUG(__FILE__, __FUNCTION__,__LINE__, my_cpu, NULL, "Created path for active cpu slice.\n");

	mark_cpuvertex_as_cpu(my_cpu, cpu_id);
        device_master_set(my_cpu, node_vertex);

        /* Add an alias under the node's CPU directory */
        if (hwgraph_edge_get(node_vertex, EDGE_LBL_CPU, &cpu_dir) == GRAPH_SUCCESS) {
                snprintf(name, 120, "%c", 'a' + cpu->cpu_info.physid);
                (void) hwgraph_edge_add(cpu_dir, my_cpu, name);
		HWGRAPH_DEBUG(__FILE__, __FUNCTION__,__LINE__, cpu_dir, my_cpu, "Created % from vhdl1 to vhdl2.\n", name);
        }
}
Ejemplo n.º 4
0
void __init
klhwg_add_all_modules(vertex_hdl_t hwgraph_root)
{
	cmoduleid_t	cm;
	char		name[128];
	vertex_hdl_t	vhdl;
	vertex_hdl_t  module_vhdl;
	int		rc;
	char		buffer[16];

	/* Add devices under each module */

	for (cm = 0; cm < nummodules; cm++) {
		/* Use module as module vertex fastinfo */

		memset(buffer, 0, 16);
		format_module_id(buffer, sn_modules[cm]->id, MODULE_FORMAT_BRIEF);
		sprintf(name, EDGE_LBL_MODULE "/%s", buffer);

		rc = hwgraph_path_add(hwgraph_root, name, &module_vhdl);
		ASSERT(rc == GRAPH_SUCCESS);
		rc = rc;
		HWGRAPH_DEBUG(__FILE__, __FUNCTION__, __LINE__, module_vhdl, NULL, "Created module path.\n");

		hwgraph_fastinfo_set(module_vhdl, (arbitrary_info_t) sn_modules[cm]);

		/* Add system controller */
		sprintf(name,
			EDGE_LBL_MODULE "/%s/" EDGE_LBL_L1,
			buffer);

		rc = hwgraph_path_add(hwgraph_root, name, &vhdl);
		ASSERT_ALWAYS(rc == GRAPH_SUCCESS); 
		rc = rc;
		HWGRAPH_DEBUG(__FILE__, __FUNCTION__, __LINE__, vhdl, NULL, "Created L1 path.\n");

		hwgraph_info_add_LBL(vhdl, INFO_LBL_ELSC,
				     (arbitrary_info_t)1);

	}
}
Ejemplo n.º 5
0
void
pcibr_hints_subdevs(devfs_handle_t xconn_vhdl,
		    pciio_slot_t slot,
		    uint64_t subdevs)
{
    arbitrary_info_t        ainfo = 0;
    char                    sdname[16];
    devfs_handle_t            pconn_vhdl = GRAPH_VERTEX_NONE;

    sprintf(sdname, "pci/%d", slot);
    (void) hwgraph_path_add(xconn_vhdl, sdname, &pconn_vhdl);
    if (pconn_vhdl == GRAPH_VERTEX_NONE) {
#if DEBUG
	printk("pcibr_hints_subdevs: hwgraph_path_create failed at\n"
		"\t%p (seeking %s)\n", xconn_vhdl, sdname);
#endif
	return;
    }
    hwgraph_info_get_LBL(pconn_vhdl, INFO_LBL_SUBDEVS, &ainfo);
    if (ainfo == 0) {
	uint64_t                *subdevp;

	NEW(subdevp);
	if (!subdevp) {
#if DEBUG
	    printk("pcibr_hints_subdevs: subdev ptr alloc failed at\n"
		    "\t%p\n", pconn_vhdl);
#endif
	    return;
	}
	*subdevp = subdevs;
	hwgraph_info_add_LBL(pconn_vhdl, INFO_LBL_SUBDEVS, (arbitrary_info_t) subdevp);
	hwgraph_info_get_LBL(pconn_vhdl, INFO_LBL_SUBDEVS, &ainfo);
	if (ainfo == (arbitrary_info_t) subdevp)
	    return;
	DEL(subdevp);
	if (ainfo == (arbitrary_info_t) NULL) {
#if DEBUG
	    printk("pcibr_hints_subdevs: null subdevs ptr at\n"
		    "\t%p\n", pconn_vhdl);
#endif
	    return;
	}
#if DEBUG
	printk("pcibr_subdevs_get: dup subdev add_LBL at\n"
		"\t%p\n", pconn_vhdl);
#endif
    }
    *(uint64_t *) ainfo = subdevs;
}
Ejemplo n.º 6
0
devfs_handle_t
pciio_device_info_register(
    devfs_handle_t connectpt,		/* vertex at center of bus */
    pciio_info_t pciio_info)	/* details about the connectpt */
{
    char		name[32];
    devfs_handle_t	pconn;

    pciio_slot_func_to_name(name,
                            pciio_info->c_slot,
                            pciio_info->c_func);

    if (GRAPH_SUCCESS !=
            hwgraph_path_add(connectpt, name, &pconn))
        return pconn;

    pciio_info->c_vertex = pconn;
    pciio_info_set(pconn, pciio_info);
#ifdef BRINGUP
    {
        int pos;
        char dname[256];
        pos = devfs_generate_path(pconn, dname, 256);
#ifdef DEBUG_PCIIO
        printk("%s : pconn path= %s \n", __FUNCTION__, &dname[pos]);
#endif
    }
#endif /* BRINGUP */

    /*
     * create link to our pci provider
     */

    device_master_set(pconn, pciio_info->c_master);

#if USRPCI
    /*
     * Call into usrpci provider to let it initialize for
     * the given slot.
     */
    if (pciio_info->c_slot != PCIIO_SLOT_NONE)
        usrpci_device_register(pconn, pciio_info->c_master, pciio_info->c_slot);
#endif

    return pconn;
}
Ejemplo n.º 7
0
/* 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)) );
	}

}
Ejemplo n.º 8
0
void
pcibr_hints_subdevs(devfs_handle_t xconn_vhdl,
		    pciio_slot_t slot,
		    uint64_t subdevs)
{
    arbitrary_info_t        ainfo = 0;
    char                    sdname[16];
    devfs_handle_t            pconn_vhdl = GRAPH_VERTEX_NONE;

    sprintf(sdname, "%s/%d", EDGE_LBL_PCI, slot);
    (void) hwgraph_path_add(xconn_vhdl, sdname, &pconn_vhdl);
    if (pconn_vhdl == GRAPH_VERTEX_NONE) {
	PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_HINTS, xconn_vhdl,
		    "pcibr_hints_subdevs: hwgraph_path_create failed\n"));
	return;
    }
    hwgraph_info_get_LBL(pconn_vhdl, INFO_LBL_SUBDEVS, &ainfo);
    if (ainfo == 0) {
	uint64_t                *subdevp;

	NEW(subdevp);
	if (!subdevp) {
	    PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_HINTS, xconn_vhdl,
			"pcibr_hints_subdevs: subdev ptr alloc failed\n"));
	    return;
	}
	*subdevp = subdevs;
	hwgraph_info_add_LBL(pconn_vhdl, INFO_LBL_SUBDEVS, (arbitrary_info_t) subdevp);
	hwgraph_info_get_LBL(pconn_vhdl, INFO_LBL_SUBDEVS, &ainfo);
	if (ainfo == (arbitrary_info_t) subdevp)
	    return;
	DEL(subdevp);
	if (ainfo == (arbitrary_info_t) NULL) {
	    PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_HINTS, xconn_vhdl,
			"pcibr_hints_subdevs: null subdevs ptr\n"));
	    return;
	}
	PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_HINTS, xconn_vhdl,
		    "pcibr_subdevs_get: dup subdev add_LBL\n"));
    }
    *(uint64_t *) ainfo = subdevs;
}
Ejemplo n.º 9
0
/* ARGSUSED */
static void __init
klhwg_add_disabled_cpu(vertex_hdl_t node_vertex, cnodeid_t cnode, klcpu_t *cpu, slotid_t slot)
{
        vertex_hdl_t my_cpu;
        char name[120];
        cpuid_t cpu_id;
	nasid_t nasid;

	nasid = cnodeid_to_nasid(cnode);
        cpu_id = nasid_slice_to_cpuid(nasid, cpu->cpu_info.physid);
        if(cpu_id != -1){
		snprintf(name, 120, "%s/%s/%c", EDGE_LBL_DISABLED, EDGE_LBL_CPU, 'a' + cpu->cpu_info.physid);
		(void) hwgraph_path_add(node_vertex, name, &my_cpu);

		HWGRAPH_DEBUG(__FILE__, __FUNCTION__,__LINE__, my_cpu, NULL, "Created path for disabled cpu slice.\n");

		mark_cpuvertex_as_cpu(my_cpu, cpu_id);
		device_master_set(my_cpu, node_vertex);
		return;
        }
}
Ejemplo n.º 10
0
/* ARGSUSED */
static void __init
klhwg_add_hub(vertex_hdl_t node_vertex, klhub_t *hub, cnodeid_t cnode)
{
	vertex_hdl_t myhubv;
	vertex_hdl_t hub_mon;
	int rc;
	extern struct file_operations shub_mon_fops;

	hwgraph_path_add(node_vertex, EDGE_LBL_HUB, &myhubv);

	HWGRAPH_DEBUG(__FILE__, __FUNCTION__,__LINE__, myhubv, NULL, "Created path for hub vertex for Shub node.\n");

	rc = device_master_set(myhubv, node_vertex);
	if (rc) {
		printk("klhwg_add_hub: Unable to create hub vertex.\n");
		return;
	}
	hub_mon = hwgraph_register(myhubv, EDGE_LBL_PERFMON,
		0, 0, 0, 0,
		S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, 0, 0,
		&shub_mon_fops, (void *)(long)cnode);
}
Ejemplo n.º 11
0
void
mark_cpuvertex_as_cpu(devfs_handle_t vhdl, cpuid_t cpuid)
{
	if (cpuid == CPU_NONE)
		return;

	(void)labelcl_info_add_LBL(vhdl, INFO_LBL_CPUID, INFO_DESC_EXPORT,
			(arbitrary_info_t)cpuid);
	{
		char cpuid_buffer[10];

		if (hwgraph_all_cpuids == GRAPH_VERTEX_NONE) {
			(void)hwgraph_path_add( hwgraph_root,
						EDGE_LBL_CPUNUM,
						&hwgraph_all_cpuids);
		}

		sprintf(cpuid_buffer, "%ld", cpuid);
		(void)hwgraph_edge_add( hwgraph_all_cpuids,
							vhdl,
							cpuid_buffer);
	}
}
Ejemplo n.º 12
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
	}
}
Ejemplo n.º 13
0
/*
 * 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;
}
Ejemplo n.º 14
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;
				}
			}
		}
	}
}
Ejemplo n.º 15
0
/*
 * PIC has two buses under a single widget.  pic_attach() calls pic_attach2()
 * to attach each of those buses.
 */
int
pic_attach(vertex_hdl_t conn_v)
{
	int		rc;
	void	*bridge0, *bridge1 = (void *)0;
	vertex_hdl_t	pcibr_vhdl0, pcibr_vhdl1 = (vertex_hdl_t)0;
	pcibr_soft_t	bus0_soft, bus1_soft = (pcibr_soft_t)0;
	vertex_hdl_t  conn_v0, conn_v1, peer_conn_v;
	int		bricktype;
	int		iobrick_type_get_nasid(nasid_t nasid);

	PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_ATTACH, conn_v, "pic_attach()\n"));

	bridge0 = pcibr_bridge_ptr_get(conn_v, 0);
	bridge1 = pcibr_bridge_ptr_get(conn_v, 1);

	PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_ATTACH, conn_v,
		    "pic_attach: bridge0=0x%lx, bridge1=0x%lx\n", 
		    bridge0, bridge1));

	conn_v0 = conn_v1 = conn_v;

	/* If dual-ported then split the two PIC buses across both Cbricks */
	peer_conn_v = pic_bus1_redist(NASID_GET(bridge0), conn_v);
	if (peer_conn_v)
		conn_v1 = peer_conn_v;

	/*
	 * Create the vertex for the PCI buses, which we
	 * will also use to hold the pcibr_soft and
	 * which will be the "master" vertex for all the
	 * pciio connection points we will hang off it.
	 * This needs to happen before we call nic_bridge_vertex_info
	 * as we are some of the *_vmc functions need access to the edges.
	 *
	 * Opening this vertex will provide access to
	 * the Bridge registers themselves.
	 */
	bricktype = iobrick_type_get_nasid(NASID_GET(bridge0));
	if ( bricktype == MODULE_CGBRICK ) {
		rc = hwgraph_path_add(conn_v0, EDGE_LBL_AGP_0, &pcibr_vhdl0);
		ASSERT(rc == GRAPH_SUCCESS);
		rc = hwgraph_path_add(conn_v1, EDGE_LBL_AGP_1, &pcibr_vhdl1);
		ASSERT(rc == GRAPH_SUCCESS);
	} else {
		rc = hwgraph_path_add(conn_v0, EDGE_LBL_PCIX_0, &pcibr_vhdl0);
		ASSERT(rc == GRAPH_SUCCESS);
		rc = hwgraph_path_add(conn_v1, EDGE_LBL_PCIX_1, &pcibr_vhdl1);
		ASSERT(rc == GRAPH_SUCCESS);
	}

	PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_ATTACH, conn_v,
		    "pic_attach: pcibr_vhdl0=0x%lx, pcibr_vhdl1=0x%lx\n",
		    pcibr_vhdl0, pcibr_vhdl1));

	/* register pci provider array */
	pciio_provider_register(pcibr_vhdl0, &pci_pic_provider);
	pciio_provider_register(pcibr_vhdl1, &pci_pic_provider);

	pciio_provider_startup(pcibr_vhdl0);
	pciio_provider_startup(pcibr_vhdl1);

	pic_attach2(conn_v0, bridge0, pcibr_vhdl0, 0, &bus0_soft);
	pic_attach2(conn_v1, bridge1, pcibr_vhdl1, 1, &bus1_soft);

	{
	    /* If we're dual-ported finish duplicating the peer info structure.
	     * The error handler and arg are done in pic_attach2().
	     */
	    xwidget_info_t info0, info1;
		if (conn_v0 != conn_v1) {	/* dual ported */
			info0 = xwidget_info_get(conn_v0);
			info1 = xwidget_info_get(conn_v1);
			if (info1->w_efunc == (error_handler_f *)NULL)
				info1->w_efunc = info0->w_efunc;
			if (info1->w_einfo == (error_handler_arg_t)0)
				info1->w_einfo = bus1_soft;
		}
	}

	/* save a pointer to the PIC's other bus's soft struct */
        bus0_soft->bs_peers_soft = bus1_soft;
        bus1_soft->bs_peers_soft = bus0_soft;

	PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_ATTACH, conn_v,
		    "pic_attach: bus0_soft=0x%lx, bus1_soft=0x%lx\n",
		    bus0_soft, bus1_soft));

	return 0;
}
Ejemplo n.º 16
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);
	}
}
Ejemplo n.º 17
0
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;
		}
	}
}
Ejemplo n.º 18
0
/*
 * init_hcl() - Boot time initialization.  Ensure that it is called 
 *	after devfs has been initialized.
 *
 * For now this routine is being called out of devfs/base.c.  Actually 
 * Not a bad place to be ..
 *
 */
int __init init_hcl(void)
{
	extern void string_table_init(struct string_table *);
	extern struct string_table label_string_table;
	extern int init_ifconfig_net(void);
	extern int init_ioconfig_bus(void);
	int status = 0;
	int rv = 0;

	if (IS_RUNNING_ON_SIMULATOR()) {
		extern u64 klgraph_addr[];
		klgraph_addr[0] = 0xe000003000030000;
	}

	/*
	 * Create the hwgraph_root on devfs.
	 */
	rv = hwgraph_path_add(NULL, EDGE_LBL_HW, &hwgraph_root);
	if (rv)
		printk ("WARNING: init_hcl: Failed to create hwgraph_root. Error = %d.\n", rv);

	status = devfs_set_flags (hwgraph_root, DEVFS_FL_HIDE);

	/*
	 * Create the hcl driver to support inventory entry manipulations.
	 * By default, it is expected that devfs is mounted on /dev.
	 *
	 */
	hcl_handle = hwgraph_register(hwgraph_root, ".hcl",
			0, DEVFS_FL_AUTO_DEVNUM,
			0, 0,
			S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, 0, 0,
			&hcl_fops, NULL);

	if (hcl_handle == NULL) {
		panic("HCL: Unable to create HCL Driver in init_hcl().\n");
		return(0);
	}

	/*
	 * Initialize the HCL string table.
	 */
	string_table_init(&label_string_table);

	/*
	 * Create the directory that links Linux bus numbers to our Xwidget.
	 */
	rv = hwgraph_path_add(hwgraph_root, EDGE_LBL_LINUX_BUS, &linux_busnum);
	if (linux_busnum == NULL) {
		panic("HCL: Unable to create %s\n", EDGE_LBL_LINUX_BUS);
		return(0);
	}

	pci_bus_cvlink_init();

	/*
	 * Initialize the ifconfgi_net driver that does network devices 
	 * Persistent Naming.
	 */
	init_ifconfig_net();
	init_ioconfig_bus();

	return(0);

}
Ejemplo n.º 19
0
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
	}
Ejemplo n.º 20
0
/*
 * Initialize all I/O on the specified node.
 */
static void
io_init_node(cnodeid_t cnodeid)
{
	/*REFERENCED*/
	vertex_hdl_t hubv, switchv, widgetv;
	struct xwidget_hwid_s hwid;
	hubinfo_t hubinfo;
	int is_xswitch;
	nodepda_t	*npdap;
	struct semaphore *peer_sema = 0;
	uint32_t	widget_partnum;
	cpuid_t	c = 0;

	npdap = NODEPDA(cnodeid);

	/*
	 * Get the "top" vertex for this node's hardware
	 * graph; it will carry the per-hub hub-specific
	 * data, and act as the crosstalk provider master.
	 * It's canonical path is probably something of the
	 * form /hw/module/%M/slot/%d/node
	 */
	hubv = cnodeid_to_vertex(cnodeid);
	DBG("io_init_node: Initialize IO for cnode %d hubv(node) 0x%p npdap 0x%p\n", cnodeid, hubv, npdap);

	ASSERT(hubv != GRAPH_VERTEX_NONE);

	/*
	 * Read mfg info on this hub
	 */

	/* 
	 * If nothing connected to this hub's xtalk port, we're done.
	 */
	early_probe_for_widget(hubv, &hwid);
	if (hwid.part_num == XWIDGET_PART_NUM_NONE) {
#ifdef PROBE_TEST
		if ((cnodeid == 1) || (cnodeid == 2)) {
			int index;

			for (index = 0; index < 600; index++)
				DBG("Interfering with device probing!!!\n");
		}
#endif
		/* io_init_done takes cpu cookie as 2nd argument 
		 * to do a restorenoderun for the setnoderun done 
		 * at the start of this thread 
		 */
		
		DBG("**** io_init_node: Node's 0x%p hub widget has XWIDGET_PART_NUM_NONE ****\n", hubv);
		return;
		/* NOTREACHED */
	}

	/* 
	 * attach our hub_provider information to hubv,
	 * so we can use it as a crosstalk provider "master"
	 * vertex.
	 */
	xtalk_provider_register(hubv, &hub_provider);
	xtalk_provider_startup(hubv);

	/*
	 * Create a vertex to represent the crosstalk bus
	 * attached to this hub, and a vertex to be used
	 * as the connect point for whatever is out there
	 * on the other side of our crosstalk connection.
	 *
	 * Crosstalk Switch drivers "climb up" from their
	 * connection point to try and take over the switch
	 * point.
	 *
	 * Of course, the edges and verticies may already
	 * exist, in which case our net effect is just to
	 * associate the "xtalk_" driver with the connection
	 * point for the device.
	 */

	(void)hwgraph_path_add(hubv, EDGE_LBL_XTALK, &switchv);

	DBG("io_init_node: Created 'xtalk' entry to '../node/' xtalk vertex 0x%p\n", switchv);

	ASSERT(switchv != GRAPH_VERTEX_NONE);

	(void)hwgraph_edge_add(hubv, switchv, EDGE_LBL_IO);

	DBG("io_init_node: Created symlink 'io' from ../node/io to ../node/xtalk \n");

	/*
	 * We need to find the widget id and update the basew_id field
	 * accordingly. In particular, SN00 has direct connected bridge,
	 * and hence widget id is Not 0.
	 */

	widget_partnum = (((*(volatile int32_t *)(NODE_SWIN_BASE(COMPACT_TO_NASID_NODEID(cnodeid), 0) + WIDGET_ID))) & WIDGET_PART_NUM) >> WIDGET_PART_NUM_SHFT;

	if (widget_partnum == BRIDGE_WIDGET_PART_NUM ||
				widget_partnum == XBRIDGE_WIDGET_PART_NUM){
		npdap->basew_id = (((*(volatile int32_t *)(NODE_SWIN_BASE(COMPACT_TO_NASID_NODEID(cnodeid), 0) + BRIDGE_WID_CONTROL))) & WIDGET_WIDGET_ID);

		DBG("io_init_node: Found XBRIDGE widget_partnum= 0x%x\n", widget_partnum);

	} else if ((widget_partnum == XBOW_WIDGET_PART_NUM) ||
			(widget_partnum == XXBOW_WIDGET_PART_NUM) ||
			(widget_partnum == PXBOW_WIDGET_PART_NUM) ) {
		/* 
		 * Xbow control register does not have the widget ID field.
		 * So, hard code the widget ID to be zero.
		 */
		DBG("io_init_node: Found XBOW widget_partnum= 0x%x\n", widget_partnum);
		npdap->basew_id = 0;

	} else {
		npdap->basew_id = (((*(volatile int32_t *)(NODE_SWIN_BASE(COMPACT_TO_NASID_NODEID(cnodeid), 0) + BRIDGE_WID_CONTROL))) & WIDGET_WIDGET_ID);

		panic(" ****io_init_node: Unknown Widget Part Number 0x%x Widget ID 0x%x attached to Hubv 0x%p ****\n", widget_partnum, npdap->basew_id, (void *)hubv);

		/*NOTREACHED*/
	}
	{
		char widname[10];
		sprintf(widname, "%x", npdap->basew_id);
		(void)hwgraph_path_add(switchv, widname, &widgetv);
		DBG("io_init_node: Created '%s' to '..node/xtalk/' vertex 0x%p\n", widname, widgetv);
		ASSERT(widgetv != GRAPH_VERTEX_NONE);
	}
	
	nodepda->basew_xc = widgetv;

	is_xswitch = xwidget_hwid_is_xswitch(&hwid);

	/* 
	 * Try to become the master of the widget.  If this is an xswitch
	 * with multiple hubs connected, only one will succeed.  Mastership
	 * of an xswitch is used only when touching registers on that xswitch.
	 * The slave xwidgets connected to the xswitch can be owned by various
	 * masters.
	 */
	if (device_master_set(widgetv, hubv) == 0) {

		/* Only one hub (thread) per Crosstalk device or switch makes
		 * it to here.
		 */

		/* 
		 * Initialize whatever xwidget is hanging off our hub.
		 * Whatever it is, it's accessible through widgetnum 0.
		 */
		hubinfo_get(hubv, &hubinfo);

		(void)xwidget_register(&hwid, widgetv, npdap->basew_id, hubv, hubinfo->h_widgetid);

		if (!is_xswitch) {
			/* io_init_done takes cpu cookie as 2nd argument 
			 * to do a restorenoderun for the setnoderun done 
			 * at the start of this thread 
			 */
			io_init_done(cnodeid,c);
			/* NOTREACHED */
		}

		/* 
		 * Special handling for Crosstalk Switches (e.g. xbow).
		 * We need to do things in roughly the following order:
		 *	1) Initialize xswitch hardware (done above)
		 *	2) Determine which hubs are available to be widget masters
		 *	3) Discover which links are active from the xswitch
		 *	4) Assign xwidgets hanging off the xswitch to hubs
		 *	5) Initialize all xwidgets on the xswitch
		 */

		DBG("call volunteer_for_widgets\n");

		volunteer_for_widgets(switchv, hubv);

		/* If there's someone else on this crossbow, recognize him */
		if (npdap->xbow_peer != INVALID_NASID) {
			nodepda_t *peer_npdap = NODEPDA(NASID_TO_COMPACT_NODEID(npdap->xbow_peer));
			peer_sema = &peer_npdap->xbow_sema;
			DBG("call volunteer_for_widgets again\n");
			volunteer_for_widgets(switchv, peer_npdap->node_vertex);
		}

		assign_widgets_to_volunteers(switchv, hubv);

		/* Signal that we're done */
		if (peer_sema) {
			up(peer_sema);
		}
		
	}
	else {
	    /* Wait 'til master is done assigning widgets. */
	    down(&npdap->xbow_sema);
	}

#ifdef PROBE_TEST
	if ((cnodeid == 1) || (cnodeid == 2)) {
		int index;

		for (index = 0; index < 500; index++)
			DBG("Interfering with device probing!!!\n");
	}
#endif
	/* Now both nodes can safely inititialize widgets */
	io_init_xswitch_widgets(switchv, cnodeid);
	io_link_xswitch_widgets(switchv, cnodeid);

	/* io_init_done takes cpu cookie as 2nd argument 
	 * to do a restorenoderun for the setnoderun done 
	 * at the start of this thread 
	 */
	io_init_done(cnodeid,c);

	DBG("\nio_init_node: DONE INITIALIZED ALL I/O FOR CNODEID %d\n\n", cnodeid);
}
Ejemplo n.º 21
0
int
pic_attach(vertex_hdl_t conn_v)
{
    int		rc;
    bridge_t	*bridge0, *bridge1 = (bridge_t *)0;
    vertex_hdl_t	pcibr_vhdl0, pcibr_vhdl1 = (vertex_hdl_t)0;
    pcibr_soft_t	bus0_soft, bus1_soft = (pcibr_soft_t)0;
    vertex_hdl_t  conn_v0, conn_v1, peer_conn_v;

    PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_ATTACH, conn_v, "pic_attach()\n"));

    bridge0 = (bridge_t *) xtalk_piotrans_addr(conn_v, NULL,
              0, sizeof(bridge_t), 0);
    bridge1 = (bridge_t *)((char *)bridge0 + PIC_BUS1_OFFSET);

    PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_ATTACH, conn_v,
                        "pic_attach: bridge0=0x%x, bridge1=0x%x\n",
                        bridge0, bridge1));

    conn_v0 = conn_v1 = conn_v;

    /* If dual-ported then split the two PIC buses across both Cbricks */
    if ((peer_conn_v = (pic_bus1_redist(NASID_GET(bridge0), conn_v))))
        conn_v1 = peer_conn_v;

    /*
     * Create the vertex for the PCI buses, which we
     * will also use to hold the pcibr_soft and
     * which will be the "master" vertex for all the
     * pciio connection points we will hang off it.
     * This needs to happen before we call nic_bridge_vertex_info
     * as we are some of the *_vmc functions need access to the edges.
     *
     * Opening this vertex will provide access to
     * the Bridge registers themselves.
     */
    /* FIXME: what should the hwgraph path look like ? */
    rc = hwgraph_path_add(conn_v0, EDGE_LBL_PCIX_0, &pcibr_vhdl0);
    ASSERT(rc == GRAPH_SUCCESS);
    rc = hwgraph_path_add(conn_v1, EDGE_LBL_PCIX_1, &pcibr_vhdl1);
    ASSERT(rc == GRAPH_SUCCESS);

    PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_ATTACH, conn_v,
                        "pic_attach: pcibr_vhdl0=%v, pcibr_vhdl1=%v\n",
                        pcibr_vhdl0, pcibr_vhdl1));

    /* register pci provider array */
    pciio_provider_register(pcibr_vhdl0, &pci_pic_provider);
    pciio_provider_register(pcibr_vhdl1, &pci_pic_provider);

    pciio_provider_startup(pcibr_vhdl0);
    pciio_provider_startup(pcibr_vhdl1);

    pcibr_attach2(conn_v0, bridge0, pcibr_vhdl0, 0, &bus0_soft);
    pcibr_attach2(conn_v1, bridge1, pcibr_vhdl1, 1, &bus1_soft);

    /* save a pointer to the PIC's other bus's soft struct */
    bus0_soft->bs_peers_soft = bus1_soft;
    bus1_soft->bs_peers_soft = bus0_soft;

    PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_ATTACH, conn_v,
                        "pic_attach: bus0_soft=0x%x, bus1_soft=0x%x\n",
                        bus0_soft, bus1_soft));

    return 0;
}