⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xbow.c

📁 microwindows移植到S3C44B0的源码
💻 C
📖 第 1 页 / 共 3 页
字号:
{    return 0;}/*ARGSUSED */intxbow_close(devfs_handle_t dev, int oflag, int otyp, cred_t *crp){    return 0;}/*ARGSUSED */intxbow_map(devfs_handle_t dev, vhandl_t *vt, off_t off, size_t len, uint prot){    devfs_handle_t            vhdl = dev_to_vhdl(dev);    xbow_soft_t             soft = xbow_soft_get(vhdl);    int                     error;    ASSERT(soft);    len = ctob(btoc(len));    /* XXX- this ignores the offset!!! */    error = v_mapphys(vt, (void *) soft->base, len);    return error;}/*ARGSUSED */intxbow_unmap(devfs_handle_t dev, vhandl_t *vt){    return 0;}/* This contains special-case code for grio. There are plans to make * this general sometime in the future, but till then this should * be good enough. */xwidgetnum_txbow_widget_num_get(devfs_handle_t dev){	devfs_handle_t	tdev;	char		devname[MAXDEVNAME];	xwidget_info_t	xwidget_info;	int		i;	vertex_to_name(dev, devname, MAXDEVNAME);	/* If this is a pci controller vertex, traverse up using	 * the ".." links to get to the widget.	 */	if (strstr(devname, EDGE_LBL_PCI) &&			strstr(devname, EDGE_LBL_CONTROLLER)) {		tdev = dev;		for (i=0; i< 2; i++) {			if (hwgraph_edge_get(tdev,				HWGRAPH_EDGELBL_DOTDOT, &tdev) !=					GRAPH_SUCCESS)				return XWIDGET_NONE;		}		if ((xwidget_info = xwidget_info_chk(tdev)) != NULL) {			return (xwidget_info_id_get(xwidget_info));		} else {			return XWIDGET_NONE;		}	}	return XWIDGET_NONE;}intxbow_ioctl(devfs_handle_t dev,	   int cmd,	   void *arg,	   int flag,	   struct cred *cr,	   int *rvalp){    devfs_handle_t            vhdl;    int                     error = 0;#if defined (DEBUG)    int                     rc;    devfs_handle_t            conn;    struct xwidget_info_s  *xwidget_info;    xbow_soft_t             xbow_soft;#endif    *rvalp = 0;    vhdl = dev_to_vhdl(dev);#if defined (DEBUG)    xbow_soft = xbow_soft_get(vhdl);    conn = xbow_soft->conn;    xwidget_info = xwidget_info_get(conn);    ASSERT_ALWAYS(xwidget_info != NULL);    rc = xwidget_hwid_is_xswitch(&xwidget_info->w_hwid);    ASSERT_ALWAYS(rc != 0);#endif    switch (cmd) {#ifdef LATER    case XBOWIOC_PERF_ENABLE:    case XBOWIOC_PERF_DISABLE:	{	    struct xbow_perfarg_t   xbow_perf_en;	    if (!_CAP_CRABLE(cr, CAP_DEVICE_MGT)) {		error = EPERM;		break;	    }	    if ((flag & FWRITE) == 0) {		error = EBADF;		break;	    }	    if (COPYIN(arg, &xbow_perf_en, sizeof(xbow_perf_en))) {		error = EFAULT;		break;	    }	    if (error = xbow_enable_perf_counter(vhdl,						 xbow_perf_en.link,						 (cmd == XBOWIOC_PERF_DISABLE) ? 0 : xbow_perf_en.mode,						 xbow_perf_en.counter)) {		error = EINVAL;		break;	    }	    break;	}#endif#ifdef LATER    case XBOWIOC_PERF_GET:	{	    xbow_perf_link_t       *xbow_perf_cnt;	    if ((flag & FREAD) == 0) {		error = EBADF;		break;	    }	    xbow_perf_cnt = xbow_get_perf_counters(vhdl);	    ASSERT_ALWAYS(xbow_perf_cnt != NULL);	    if (COPYOUT((void *) xbow_perf_cnt, (void *) arg,			MAX_XBOW_PORTS * sizeof(xbow_perf_link_t))) {		error = EFAULT;		break;	    }	    break;	}#endif    case XBOWIOC_LLP_ERROR_ENABLE:	if ((error = xbow_enable_llp_monitor(vhdl)) != 0)	    error = EINVAL;	break;    case XBOWIOC_LLP_ERROR_DISABLE:	if ((error = xbow_disable_llp_monitor(vhdl)) != 0)	    error = EINVAL;	break;#ifdef LATER    case XBOWIOC_LLP_ERROR_GET:	{	    xbow_link_status_t     *xbow_llp_status;	    if ((flag & FREAD) == 0) {		error = EBADF;		break;	    }	    xbow_llp_status = xbow_get_llp_status(vhdl);	    ASSERT_ALWAYS(xbow_llp_status != NULL);	    if (COPYOUT((void *) xbow_llp_status, (void *) arg,			MAX_XBOW_PORTS * sizeof(xbow_link_status_t))) {		error = EFAULT;		break;	    }	    break;	}#endif#ifdef LATER    case GIOCSETBW:	{	    grio_ioctl_info_t info;	    xwidgetnum_t src_widgetnum, dest_widgetnum;	    if (COPYIN(arg, &info, sizeof(grio_ioctl_info_t))) {		error = EFAULT;		break;	    }#ifdef GRIO_DEBUG	    printf("xbow:: prev_vhdl: %d next_vhdl: %d reqbw: %lld\n",			info.prev_vhdl, info.next_vhdl, info.reqbw);#endif /* GRIO_DEBUG */	    src_widgetnum = xbow_widget_num_get(info.prev_vhdl);	    dest_widgetnum = xbow_widget_num_get(info.next_vhdl);	    /* Bandwidth allocation is bi-directional. Since bandwidth	     * reservations have already been done at an earlier stage,	     * we cannot fail here for lack of bandwidth.	     */	    xbow_prio_bw_alloc(dev, src_widgetnum, dest_widgetnum,			0, info.reqbw);	    xbow_prio_bw_alloc(dev, dest_widgetnum, src_widgetnum,			0, info.reqbw);	    break;	}    case GIOCRELEASEBW:	{	    grio_ioctl_info_t info;	    xwidgetnum_t src_widgetnum, dest_widgetnum;	    if (!cap_able(CAP_DEVICE_MGT)) {		error = EPERM;		break;	    }	    if (COPYIN(arg, &info, sizeof(grio_ioctl_info_t))) {		error = EFAULT;		break;	    }#ifdef GRIO_DEBUG	    printf("xbow:: prev_vhdl: %d next_vhdl: %d reqbw: %lld\n",			info.prev_vhdl, info.next_vhdl, info.reqbw);#endif /* GRIO_DEBUG */	    src_widgetnum = xbow_widget_num_get(info.prev_vhdl);	    dest_widgetnum = xbow_widget_num_get(info.next_vhdl);	    /* Bandwidth reservation is bi-directional. Hence, remove	     * bandwidth reservations for both directions.	     */	    xbow_prio_bw_alloc(dev, src_widgetnum, dest_widgetnum,			info.reqbw, (-1 * info.reqbw));	    xbow_prio_bw_alloc(dev, dest_widgetnum, src_widgetnum,			info.reqbw, (-1 * info.reqbw));	    break;	}#endif    default:	break;    }    return error;}/* * xbow_widget_present: See if a device is present * on the specified port of this crossbow. */intxbow_widget_present(xbow_t * xbow, int port){	if ( IS_RUNNING_ON_SIMULATOR() ) {		if ( (port == 14) || (port == 15) ) {			return 1;		}		else {			return 0;		}	}	else {		return xbow->xb_link(port).link_aux_status & XB_AUX_STAT_PRESENT;	}}static intxbow_link_alive(xbow_t * xbow, int port){    xbwX_stat_t             xbow_linkstat;    xbow_linkstat.linkstatus = xbow->xb_link(port).link_status;    return (xbow_linkstat.link_alive);}/* * xbow_widget_lookup *      Lookup the edges connected to the xbow specified, and *      retrieve the handle corresponding to the widgetnum *      specified. *      If not found, return 0. */devfs_handle_txbow_widget_lookup(devfs_handle_t vhdl,		   int widgetnum){    xswitch_info_t          xswitch_info;    devfs_handle_t            conn;    xswitch_info = xswitch_info_get(vhdl);    conn = xswitch_info_vhdl_get(xswitch_info, widgetnum);    return conn;}/* * xbow_setwidint: called when xtalk * is establishing or migrating our * interrupt service. */#ifdef LATERstatic voidxbow_setwidint(xtalk_intr_t intr){    xwidgetnum_t            targ = xtalk_intr_target_get(intr);    iopaddr_t               addr = xtalk_intr_addr_get(intr);    xtalk_intr_vector_t     vect = xtalk_intr_vector_get(intr);    xbow_t                 *xbow = (xbow_t *) xtalk_intr_sfarg_get(intr);    xbow_intr_preset((void *) xbow, 0, targ, addr, vect);}#endif	/* LATER *//* * xbow_intr_preset: called during mlreset time * if the platform specific code needs to route * an xbow interrupt before the xtalk infrastructure * is available for use. * * Also called from xbow_setwidint, so we don't * replicate the guts of the routine. * * XXX- probably should be renamed xbow_wid_intr_set or * something to reduce confusion. *//*ARGSUSED3 */voidxbow_intr_preset(void *which_widget,		 int which_widget_intr,		 xwidgetnum_t targ,		 iopaddr_t addr,		 xtalk_intr_vector_t vect){    xbow_t                 *xbow = (xbow_t *) which_widget;    xbow->xb_wid_int_upper = ((0xFF000000 & (vect << 24)) |			      (0x000F0000 & (targ << 16)) |			      XTALK_ADDR_TO_UPPER(addr));    xbow->xb_wid_int_lower = XTALK_ADDR_TO_LOWER(addr);}#define	XEM_ADD_STR(s)		printk("%s", (s))#define	XEM_ADD_NVAR(n,v)	printk("\t%20s: 0x%x\n", (n), (v))#define	XEM_ADD_VAR(v)		XEM_ADD_NVAR(#v,(v))#define XEM_ADD_IOEF(n) 	if (IOERROR_FIELDVALID(ioe,n))		    \				    XEM_ADD_NVAR("ioe." #n,		    \						 IOERROR_GETVALUE(ioe,n))#ifdef LATERstatic voidxem_add_ioe(ioerror_t *ioe){    XEM_ADD_IOEF(errortype);    XEM_ADD_IOEF(widgetnum);    XEM_ADD_IOEF(widgetdev);    XEM_ADD_IOEF(srccpu);    XEM_ADD_IOEF(srcnode);    XEM_ADD_IOEF(errnode);    XEM_ADD_IOEF(sysioaddr);    XEM_ADD_IOEF(xtalkaddr);    XEM_ADD_IOEF(busspace);    XEM_ADD_IOEF(busaddr);    XEM_ADD_IOEF(vaddr);    XEM_ADD_IOEF(memaddr);    XEM_ADD_IOEF(epc);    XEM_ADD_IOEF(ef);}#define XEM_ADD_IOE()	(xem_add_ioe(ioe))#endif	/* LATER */int                     xbow_xmit_retry_errors = 0;intxbow_xmit_retry_error(xbow_soft_t soft,		      int port){    xswitch_info_t          info;    devfs_handle_t            vhdl;    widget_cfg_t           *wid;    widgetreg_t             id;    int                     part;    int                     mfgr;    wid = soft->wpio[port - BASE_XBOW_PORT];    if (wid == NULL) {	/* If we can't track down a PIO	 * pointer to our widget yet,	 * leave our caller knowing that	 * we are interested in this	 * interrupt if it occurs in	 * the future.	 */	info = xswitch_info_get(soft->busv);	if (!info)	    return 1;	vhdl = xswitch_info_vhdl_get(info, port);	if (vhdl == GRAPH_VERTEX_NONE)	    return 1;	wid = (widget_cfg_t *) xtalk_piotrans_addr	    (vhdl, 0, 0, sizeof *wid, 0);	if (!wid)	    return 1;	soft->wpio[port - BASE_XBOW_PORT] = wid;    }    id = wid->w_id;    part = XWIDGET_PART_NUM(id);    mfgr = XWIDGET_MFG_NUM(id);    /* If this thing is not a Bridge,     * do not activate the WAR, and     * tell our caller we do not need     * to be called again.     */    if ((part != BRIDGE_WIDGET_PART_NUM) ||	(mfgr != BRIDGE_WIDGET_MFGR_NUM)) {		/* FIXME: add Xbridge to the WAR.		 * Shouldn't hurt anything.  Later need to		 * check if we can remove this.                 */    		if ((part != XBRIDGE_WIDGET_PART_NUM) ||		    (mfgr != XBRIDGE_WIDGET_MFGR_NUM))			return 0;    }    /* count how many times we     * have picked up after     * LLP Transmit problems.     */    xbow_xmit_retry_errors++;    /* rewrite the control register

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -