📄 pcibr.c
字号:
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 + -