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

📄 pcibr.c

📁 广州斯道2410普及版II的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
    if(is_sys_critical_vertex(pcibr_info->f_vertex)) {        funcp->resp_f_status |= FUNC_IS_SYS_CRITICAL;    }    funcp->resp_f_bus = pcibr_info->f_bus;    funcp->resp_f_slot = pcibr_info->f_slot;    funcp->resp_f_func = pcibr_info->f_func;#ifdef SUPPORT_PRINTING_V_FORMAT    sprintf(funcp->resp_f_master_name, "%v", pcibr_info->f_master);#else    sprintf(funcp->resp_f_master_name, "%x", pcibr_info->f_master);#endif    funcp->resp_f_pops = pcibr_info->f_pops;    funcp->resp_f_efunc = pcibr_info->f_efunc;    funcp->resp_f_einfo = pcibr_info->f_einfo;    funcp->resp_f_vendor = pcibr_info->f_vendor;    funcp->resp_f_device = pcibr_info->f_device;    for(win = 0 ; win < 6 ; win++) {        funcp->resp_f_window[win].resp_w_base =                                  pcibr_info->f_window[win].w_base;        funcp->resp_f_window[win].resp_w_size =                                  pcibr_info->f_window[win].w_size;        sprintf(funcp->resp_f_window[win].resp_w_space,                "%s",                pci_space_name[pcibr_info->f_window[win].w_space]);    }    funcp->resp_f_rbase = pcibr_info->f_rbase;    funcp->resp_f_rsize = pcibr_info->f_rsize;    for (win = 0 ; win < 4; win++) {        funcp->resp_f_ibit[win] = pcibr_info->f_ibit[win];    }    funcp->resp_f_att_det_error = pcibr_info->f_att_det_error;}intpcibr_slot_info_return(pcibr_soft_t             pcibr_soft,                       pciio_slot_t             slot,                       pcibr_slot_info_resp_t   respp){    pcibr_soft_slot_t            pss;    int                          func;    bridge_t                    *bridge = pcibr_soft->bs_base;    reg_p                        b_respp;    pcibr_slot_info_resp_t       slotp;    pcibr_slot_func_info_resp_t  funcp;    slotp = kmem_zalloc(sizeof(*slotp), KM_SLEEP);    if (slotp == NULL) {        return(ENOMEM);    }    pss = &pcibr_soft->bs_slot[slot];        printk("\nPCI INFRASTRUCTURAL INFO FOR SLOT %d\n\n", slot);    slotp->resp_has_host = pss->has_host;    slotp->resp_host_slot = pss->host_slot;#ifdef SUPPORT_PRINTING_V_FORMAT    sprintf(slotp->resp_slot_conn_name, "%v", pss->slot_conn);#else    sprintf(slotp->resp_slot_conn_name, "%x", pss->slot_conn);#endif    slotp->resp_slot_status = pss->slot_status;    slotp->resp_l1_bus_num = io_path_map_widget(pcibr_soft->bs_vhdl);    if (is_sys_critical_vertex(pss->slot_conn)) {        slotp->resp_slot_status |= SLOT_IS_SYS_CRITICAL;    }    slotp->resp_bss_ninfo = pss->bss_ninfo;    for (func = 0; func < pss->bss_ninfo; func++) {        funcp = &(slotp->resp_func[func]);        pcibr_slot_func_info_return(pss->bss_infos, func, funcp);    }    sprintf(slotp->resp_bss_devio_bssd_space, "%s",            pci_space_name[pss->bss_devio.bssd_space]);    slotp->resp_bss_devio_bssd_base = pss->bss_devio.bssd_base;    slotp->resp_bss_device = pss->bss_device;    slotp->resp_bss_pmu_uctr = pss->bss_pmu_uctr;    slotp->resp_bss_d32_uctr = pss->bss_d32_uctr;    slotp->resp_bss_d64_uctr = pss->bss_d64_uctr;    slotp->resp_bss_d64_base = pss->bss_d64_base;    slotp->resp_bss_d64_flags = pss->bss_d64_flags;    slotp->resp_bss_d32_base = pss->bss_d32_base;    slotp->resp_bss_d32_flags = pss->bss_d32_flags;    slotp->resp_bss_ext_ates_active = atomic_read(&pss->bss_ext_ates_active);    slotp->resp_bss_cmd_pointer = pss->bss_cmd_pointer;    slotp->resp_bss_cmd_shadow = pss->bss_cmd_shadow;    slotp->resp_bs_rrb_valid = pcibr_soft->bs_rrb_valid[slot];    slotp->resp_bs_rrb_valid_v = pcibr_soft->bs_rrb_valid[slot +                                                      PCIBR_RRB_SLOT_VIRTUAL];    slotp->resp_bs_rrb_res = pcibr_soft->bs_rrb_res[slot];    if (slot & 1) {        b_respp = &bridge->b_odd_resp;    } else {        b_respp = &bridge->b_even_resp;    }    slotp->resp_b_resp = *b_respp;    slotp->resp_b_int_device = bridge->b_int_device;    slotp->resp_b_int_enable = bridge->b_int_enable;    slotp->resp_b_int_host = bridge->b_int_addr[slot].addr;    if (COPYOUT(slotp, respp, sizeof(*respp))) {        return(EFAULT);    }    kmem_free(slotp, sizeof(*slotp));    return(0);}/* * pcibr_slot_query *	Return information about the PCI slot maintained by the infrastructure. *	Information is requested in the request structure. * *      Information returned in the response structure: *		Slot hwgraph name *		Vendor/Device info *		Base register info *		Interrupt mapping from device pins to the bridge pins *		Devio register *		Software RRB info *		RRB register info *		Host/Gues info *		PCI Bus #,slot #, function # *		Slot provider hwgraph name *		Provider Functions *		Error handler *		DMA mapping usage counters *		DMA direct translation info *		External SSRAM workaround info */intpcibr_slot_query(devfs_handle_t pcibr_vhdl, pcibr_slot_info_req_t reqp){    pcibr_soft_t            pcibr_soft = pcibr_soft_get(pcibr_vhdl);    pciio_slot_t            slot = reqp->req_slot;    pciio_slot_t            tmp_slot;    pcibr_slot_info_resp_t  respp = (pcibr_slot_info_resp_t) reqp->req_respp;    int                     size = reqp->req_size;    int                     error;    /* Make sure that we are dealing with a bridge device vertex */    if (!pcibr_soft) {        return(EINVAL);    }    /* Make sure that we have a valid PCI slot number or PCIIO_SLOT_NONE */    if ((!PCIBR_VALID_SLOT(slot)) && (slot != PCIIO_SLOT_NONE)) {        return(EINVAL);    }#ifdef LATER    /* Do not allow a query of a slot in a shoehorn */    if(nic_vertex_info_match(pcibr_soft->bs_conn, XTALK_PCI_PART_NUM)) {       return(EPERM);    }#endif    /* Return information for the requested PCI slot */    if (slot != PCIIO_SLOT_NONE) {        if (size < sizeof(*respp)) {            return(EINVAL);        }        /* Acquire read access to the slot */        mrlock(pcibr_soft->bs_slot[slot].slot_lock, MR_ACCESS, PZERO);        error = pcibr_slot_info_return(pcibr_soft, slot, respp);        /* Release the slot lock */        mrunlock(pcibr_soft->bs_slot[slot].slot_lock);        return(error);    }    /* Return information for all the slots */    for (tmp_slot = 0; tmp_slot < 8; tmp_slot++) {        if (size < sizeof(*respp)) {            return(EINVAL);        }        /* Acquire read access to the slot */        mrlock(pcibr_soft->bs_slot[tmp_slot].slot_lock, MR_ACCESS, PZERO);        error = pcibr_slot_info_return(pcibr_soft, tmp_slot, respp);        /* Release the slot lock */        mrunlock(pcibr_soft->bs_slot[tmp_slot].slot_lock);        if (error) {            return(error);        }        ++respp;        size -= sizeof(*respp);    }    return(error);}#endif	/* LATER *//*ARGSUSED */intpcibr_ioctl(devfs_handle_t dev,	    int cmd,	    void *arg,	    int flag,	    struct cred *cr,	    int *rvalp){    devfs_handle_t            pcibr_vhdl = hwgraph_connectpt_get((devfs_handle_t)dev);#ifdef LATER    pcibr_soft_t            pcibr_soft = pcibr_soft_get(pcibr_vhdl);#endif    int                     error = 0;    hwgraph_vertex_unref(pcibr_vhdl);    switch (cmd) {#ifdef LATER    case GIOCSETBW:	{	    grio_ioctl_info_t       info;	    pciio_slot_t            slot = 0;	    if (!cap_able((uint64_t)CAP_DEVICE_MGT)) {		error = EPERM;		break;	    }	    if (COPYIN(arg, &info, sizeof(grio_ioctl_info_t))) {		error = EFAULT;		break;	    }#ifdef GRIO_DEBUG	    printk("pcibr:: prev_vhdl: %d reqbw: %lld\n",		    info.prev_vhdl, info.reqbw);#endif				/* GRIO_DEBUG */	    if ((slot = pcibr_device_slot_get(info.prev_vhdl)) ==		PCIIO_SLOT_NONE) {		error = EIO;		break;	    }	    if (info.reqbw)		pcibr_priority_bits_set(pcibr_soft, slot, PCI_PRIO_HIGH);	    break;	}    case GIOCRELEASEBW:	{	    grio_ioctl_info_t       info;	    pciio_slot_t            slot = 0;	    if (!cap_able(CAP_DEVICE_MGT)) {		error = EPERM;		break;	    }	    if (COPYIN(arg, &info, sizeof(grio_ioctl_info_t))) {		error = EFAULT;		break;	    }#ifdef GRIO_DEBUG	    printk("pcibr:: prev_vhdl: %d reqbw: %lld\n",		    info.prev_vhdl, info.reqbw);#endif				/* GRIO_DEBUG */	    if ((slot = pcibr_device_slot_get(info.prev_vhdl)) ==		PCIIO_SLOT_NONE) {		error = EIO;		break;	    }	    if (info.reqbw)		pcibr_priority_bits_set(pcibr_soft, slot, PCI_PRIO_LOW);	    break;	}    case PCIBR_SLOT_POWERUP:	{	    pciio_slot_t	slot;	    if (!cap_able(CAP_DEVICE_MGT)) {		error = EPERM;		break;	    }	    slot = (pciio_slot_t)(uint64_t)arg;	    error = pcibr_slot_powerup(pcibr_vhdl,slot);	    break;	}    case PCIBR_SLOT_SHUTDOWN:	    if (!cap_able(CAP_DEVICE_MGT)) {		error = EPERM;		break;	    }	    slot = (pciio_slot_t)(uint64_t)arg;	    error = pcibr_slot_powerup(pcibr_vhdl,slot);	    break;	}    case PCIBR_SLOT_QUERY:	{	    struct pcibr_slot_info_req_s        req;	    if (!cap_able(CAP_DEVICE_MGT)) {		error = EPERM;		break;	    }            if (COPYIN(arg, &req, sizeof(req))) {                error = EFAULT;                break;            }            error = pcibr_slot_query(pcibr_vhdl, &req);	    break;	}#endif	/* LATER */    default:	break;    }    return error;}voidpcibr_freeblock_sub(iopaddr_t *free_basep,		    iopaddr_t *free_lastp,		    iopaddr_t base,		    size_t size){    iopaddr_t               free_base = *free_basep;    iopaddr_t               free_last = *free_lastp;    iopaddr_t               last = base + size - 1;    if ((last < free_base) || (base > free_last));	/* free block outside arena */    else if ((base <= free_base) && (last >= free_last))	/* free block contains entire arena */	*free_basep = *free_lastp = 0;    else if (base <= free_base)	/* free block is head of arena */	*free_basep = last + 1;    else if (last >= free_last)	/* free block is tail of arena */	*free_lastp = base - 1;    /*     * We are left with two regions: the free area     * in the arena "below" the block, and the free     * area in the arena "above" the block. Keep     * the one that is bigger.     */    else if ((base - free_base) > (free_last - last))	*free_lastp = base - 1;		/* keep lower chunk */    else	*free_basep = last + 1;		/* keep upper chunk */}/* Convert from ssram_bits in control register to number of SSRAM entries */#define ATE_NUM_ENTRIES(n) _ate_info[n]/* Possible choices for number of ATE entries in Bridge's SSRAM */LOCAL int               _ate_info[] ={    0,					/* 0 entries */    8 * 1024,				/* 8K entries */    16 * 1024,				/* 16K entries */    64 * 1024				/* 64K entries */};#define ATE_NUM_SIZES (sizeof(_ate_info) / sizeof(int))#define ATE_PROBE_VALUE 0x0123456789abcdefULL/* * Determine the size of this bridge's external mapping SSRAM, and set * the control register appropriately to reflect this size, and initialize * the external SSRAM. */LOCAL intpcibr_init_ext_ate_ram(bridge_t *bridge){    int                     largest_working_size = 0;    int                     num_entries, entry;    int                     i, j;    bridgereg_t             old_enable, new_enable;    int                     s;    /* Probe SSRAM to determine its size. */    old_enable = bridge->b_int_enable;    new_enable = old_enable & ~BRIDGE_IMR_PCI_MST_TIMEOUT;    bridge->b_int_enable = new_enable;    for (i = 1; i < ATE_NUM_SIZES; i++) {	/* Try writing a value */	bridge->b_ext_ate_ram[ATE_NUM_ENTRIES(i) - 1] = ATE_PROBE_VALUE;	/* Guard against wrap */	for (j = 1; j < i; j++)	    bridge->b_ext_ate_ram[ATE_NUM_ENTRIES(j) - 1] = 0;	/* Se

⌨️ 快捷键说明

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