📄 pcibr.c
字号:
printk("\n\tBase Register Info\n"); printk("\t\tReg#\tBase\t\tSize\t\tSpace\n"); for(win = 0 ; win < 6 ; win++) printk("\t\t%d\t0x%lx\t%s0x%lx\t%s%s\n", win, pcibr_info->f_window[win].w_base, pcibr_info->f_window[win].w_base >= 0x100000 ? "": "\t", pcibr_info->f_window[win].w_size, pcibr_info->f_window[win].w_size >= 0x100000 ? "": "\t", pci_space_name[pcibr_info->f_window[win].w_space]); printk("\t\t7\t0x%x\t%s0x%x\t%sROM\n", pcibr_info->f_rbase, pcibr_info->f_rbase > 0x100000 ? "" : "\t", pcibr_info->f_rsize, pcibr_info->f_rsize > 0x100000 ? "" : "\t"); printk("\n\tInterrupt Bit Map\n"); printk("\t\tPCI Int#\tBridge Pin#\n"); for (win = 0 ; win < 4; win++) printk("\t\tINT%c\t\t%d\n",win+'A',pcibr_info->f_ibit[win]); printk("\n");}voidpcibr_slot_info_print(pcibr_soft_t pcibr_soft, pciio_slot_t slot, int verbose){ pcibr_soft_slot_t pss; char slot_conn_name[MAXDEVNAME]; int func; bridge_t *bridge = pcibr_soft->bs_base; bridgereg_t b_resp; reg_p b_respp; int dev; bridgereg_t b_int_device; bridgereg_t b_int_host; bridgereg_t b_int_enable; int pin = 0; int int_bits = 0; pss = &pcibr_soft->bs_slot[slot]; printk("\nPCI INFRASTRUCTURAL INFO FOR SLOT %d\n\n", slot); if (verbose) { printk("\tHost Present ? %s ", pss->has_host ? "yes" : "no"); printk("\tHost Slot : %d\n",pss->host_slot);#ifdef SUPPORT_PRINTING_V_FORMAT sprintf(slot_conn_name, "%v", pss->slot_conn);#endif printk("\tSlot Conn : %s\n",slot_conn_name); printk("\t#Functions : %d\n",pss->bss_ninfo); } for (func = 0; func < pss->bss_ninfo; func++) pcibr_slot_func_info_print(pss->bss_infos,func, verbose); printk("\tDevio[Space:%s,Base:0x%lx,Shadow:0x%x]\n", pci_space_name[pss->bss_devio.bssd_space], pss->bss_devio.bssd_base, pss->bss_device); if (verbose) { printk("\tUsage counts : pmu %d d32 %d d64 %d\n", pss->bss_pmu_uctr,pss->bss_d32_uctr,pss->bss_d64_uctr); printk("\tDirect Trans Info : d64_base 0x%x d64_flags 0x%x" "d32_base 0x%x d32_flags 0x%x\n", (unsigned int)pss->bss_d64_base, pss->bss_d64_flags, (unsigned int)pss->bss_d32_base, pss->bss_d32_flags); printk("\tExt ATEs active ? %s", pss->bss_ext_ates_active ? "yes" : "no"); printk(" Command register : 0x%p ", pss->bss_cmd_pointer); printk(" Shadow command val : 0x%x\n", pss->bss_cmd_shadow); } printk("\tSoft RRB Info[Valid %d+%d, Reserved %d]\n", pcibr_soft->bs_rrb_valid[slot], pcibr_soft->bs_rrb_valid[slot + PCIBR_RRB_SLOT_VIRTUAL], pcibr_soft->bs_rrb_res[slot]); if (slot & 1) b_respp = &bridge->b_odd_resp; else b_respp = &bridge->b_even_resp; b_resp = *b_respp; printk("\n\tBridge RRB Info\n"); printk("\t\tRRB#\tVirtual\n"); for (dev = 0; dev < 8; dev++) { if ((b_resp & BRIDGE_RRB_EN) && (b_resp & BRIDGE_RRB_PDEV) == (slot >> 1)) printk( "\t\t%d\t%s\n", dev, (b_resp & BRIDGE_RRB_VDEV) ? "yes" : "no"); b_resp >>= 4; } b_int_device = bridge->b_int_device; b_int_enable = bridge->b_int_enable; printk("\n\tBridge Interrupt Info\n" "\t\tInt_device 0x%x\n\t\tInt_enable 0x%x " "\n\t\tEnabled pin#s for this slot: ", b_int_device, b_int_enable); while (b_int_device) { if (((b_int_device & 7) == slot) && (b_int_enable & (1 << pin))) { int_bits |= (1 << pin); printk("%d ", pin); } pin++; b_int_device >>= 3; } if (!int_bits) printk("NONE "); b_int_host = bridge->b_int_addr[slot].addr; printk("\n\t\tInt_host_addr 0x%x\n", b_int_host); }int verbose = 0;/* * pcibr_slot_inquiry * Print information about the pci slot maintained by the infrastructure. * Current information displayed * 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 * In verbose mode following additional info is displayed * 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_inquiry(devfs_handle_t pcibr_vhdl, pciio_slot_t slot){ pcibr_soft_t pcibr_soft = pcibr_soft_get(pcibr_vhdl); /* 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); /* Print information for the requested pci slot */ if (slot != PCIIO_SLOT_NONE) { pcibr_slot_info_print(pcibr_soft,slot,verbose); return(0); } /* Print information for all the slots */ for (slot = 0; slot < 8; slot++) pcibr_slot_info_print(pcibr_soft, slot,verbose); return(0);}/*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 colin pcibr_soft_t pcibr_soft = pcibr_soft_get(pcibr_vhdl);#endif int error = 0; hwgraph_vertex_unref(pcibr_vhdl); switch (cmd) {#ifdef colin 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; }#endif /* colin */ 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: { pciio_slot_t slot; if (!cap_able(CAP_DEVICE_MGT)) { error = EPERM; break; } slot = (pciio_slot_t)(uint64_t)arg; error = pcibr_slot_shutdown(pcibr_vhdl,slot); break; } case PCIBR_SLOT_INQUIRY: { pciio_slot_t slot; if (!cap_able(CAP_DEVICE_MGT)) { error = EPERM; break; } slot = (pciio_slot_t)(uint64_t)arg; error = pcibr_slot_inquiry(pcibr_vhdl,slot); break; } 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 */}#ifdef IRIX/* 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#endif /* IRIX *//* * 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. */#ifndef BRINGUPLOCAL 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; if (is_xbridge(bridge)) return 0; /* 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; /* See if value was written */ if (bridge->b_ext_ate_ram[ATE_NUM_ENTRIES(i) - 1] == ATE_PROBE_VALUE) largest_working_size = i; } bridge->b_int_enable = old_enable; bridge->b_wid_tflush; /* wait until Bridge PIO complete */ /* * ensure that we write and read without any interruption. * The read following the write is required for the Bridge war */ s = splhi();#ifdef colin bridge->b_wid_control = (bridge->b_wid_control & ~BRIDGE_CTRL_SSRAM_SIZE_MASK) | BRIDGE_CTRL_SSRAM_SIZE(largest_working_size);#endif bridge->b_wid_control; /* inval addr bug war */ splx(s); num_entries = ATE_NUM_ENTRIES(largest_working_size);#if PCIBR_ATE_DEBUG if (num_entries) printk("bridge at 0x%x: clearing %d external ATEs\n", bridge, num_entries); else printk("bridge at 0x%x: no externa9422l ATE RAM found\n", bridge);#endif /* Initialize external mapping entries */ for (entry = 0; entry < num_entries; entry++) bridge->b_ext_ate_ram[entry] = 0; return (num_entries);}#endif /* !BRINGUP *//* * Allocate "count" contiguous Bridge Address Translation Entries * on the specified bridge to be used for PCI to XTALK mappings. * Indices in rm map range from 1..num_entries. Indicies returned
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -