📄 vbainit.c
字号:
um->um_addr, um->um_addr2); /* Map csr space(s) */ /* Map csr1 address space if present */ if(um->um_addr) { if ( (map_addr = vme_map_csr(um->um_addr, udp->ud_addr1_size, udp->ud_addr1_atype, udp, um, vhp)) == 0){ continue; } } /* Map csr2 address space if present */ if(um->um_addr2) { if( (map_addr2 = vme_map_csr(um->um_addr2, udp->ud_addr2_size, udp->ud_addr2_atype, udp, um, vhp)) == 0) { continue; } } i = (*udp->ud_probe)(um->um_ctlr, map_addr, map_addr2); if (i == 0) continue; um->um_vbanum = vhp->vbanum; um->um_adpt = vhp->adptnum; config_fillin(um); printf(" csr 0x%x", um->um_addr); config_vme(udp->ud_addr1_atype); if(map_addr2) { printf(" csr2 0x%x", um->um_addr2); config_vme(udp->ud_addr2_atype); } printf(" vec 0x%x", um->um_ivnum); printf(" priority %d\n", um->um_bus_priority); um->um_alive = 1; um->um_vbahd = vhp; um->um_addr = (caddr_t)map_addr; um->um_addr2 = (caddr_t)map_addr2; um->um_physaddr = (caddr_t)svtophy(map_addr); udp->ud_minfo[um->um_ctlr] = um; switch(vbatype) { case VBA_3VIA: intr_dispatch = (int (**)())_3VIA_VEC_ADDR(vhp, vec); Cprintf("probevba: intr_dispatch = 0x%x\n", intr_dispatch); for (ivec = um->um_intr; *ivec; ivec++) { *intr_dispatch = *ivec; intr_dispatch++; } um->um_priority = splm[SPLBIO]; break; case VBA_XBIA: for (ivec = um->um_intr; *ivec; ivec++) { vecaddr = (int (**)())SCB_VME_VEC_ADDR(vhp->vbavec_page, vec); *vecaddr = scbentry(*ivec, SCB_ISTACK); Cprintf("probevba: vecaddr = 0x%x, *vecaddr = 0x%x\n", vecaddr, *vecaddr); vec++; } switch(um->um_bus_priority) { case 1: case 2: um->um_priority = splm[SPLBIO]; break; case 3: case 4: um->um_priority = splm[SPLBIO]; break; case 5: case 6: um->um_priority = splm[SPLBIO]; break; case 7: um->um_priority = splm[SPLBIO]; break; default: break; } break; } for (ui = ubdinit; ui->ui_driver; ui++) { if (ui->ui_driver != udp || ui->ui_alive || ui->ui_ctlr != um->um_ctlr && ui->ui_ctlr != '?'|| ui->ui_adpt != vhp->vbanum || ui->ui_vbanum == '?') continue; Cprintf("probevba: Found matching ui entry\n"); savectlr = ui->ui_ctlr; ui->ui_ctlr = um->um_ctlr; if ((*udp->ud_slave)(ui, map_addr, map_addr2)) { ui->ui_alive = 1; ui->ui_ctlr = um->um_ctlr; ui->ui_vbanum = vhp->vbanum; ui->ui_adpt = vhp->adptnum; ui->ui_vbahd = vhp; ui->ui_addr = (caddr_t)map_addr; ui->ui_addr2 = (caddr_t)map_addr2; ui->ui_physaddr = (caddr_t)svtophy(map_addr); if (ui->ui_dk && dkn < DK_NDRIVE) ui->ui_dk = dkn++; else ui->ui_dk = -1; ui->ui_mi = um; /* ui_type comes from driver */ udp->ud_dinfo[ui->ui_unit] = ui; printf("%s%d at %s%d slave %d\n", ui->ui_devname, ui->ui_unit, udp->ud_mname, um->um_ctlr, ui->ui_slave); if(udp->ud_attach) (*udp->ud_attach)(ui); } else ui->ui_ctlr = savectlr; } } /* * Now look for non-controller devices */ for (ui = ubdinit; udp = ui->ui_driver; ui++) { if((ui->ui_alive) || (ui->ui_adpt != vhp->vbanum) || (ui->ui_slave != -1) || (ui->ui_vbanum == '?')) continue; for(p_adpt = &config_adpt[0]; p_adpt->p_name; p_adpt++) { if(strcmp("vba", p_adpt->p_name)==0 && (char *)udp == p_adpt->c_name && (p_adpt->c_type == 'D') && p_adpt->c_num == ui->ui_unit) break; } if (p_adpt->p_name == 0) continue; Cprintf("probevba: Non-controller - name = %s\n", ui->ui_devname); map_addr = 0; map_addr2 = 0; vec = ui->ui_ivnum; if((vec < 0x40) || (vec > 0xFF)) { printf("%s%d not configured: Invalid vector 0x%x\n", ui->ui_devname, ui->ui_unit, vec); continue; } /* Map csr space(s) */ /* Map csr1 address space if present */ if(ui->ui_addr) { if ( (map_addr = vme_map_csr(ui->ui_addr, udp->ud_addr1_size, udp->ud_addr1_atype, udp, ui, vhp)) == 0) { continue; } } /* Map csr2 address space if present */ if(ui->ui_addr2) { if ( (map_addr2 = vme_map_csr(ui->ui_addr2, udp->ud_addr2_size, udp->ud_addr2_atype, udp, ui, vhp)) == 0) { continue; } } i = (*udp->ud_probe)(ui->ui_unit, map_addr, map_addr2); if (i == 0) continue; ui->ui_vbanum = vhp->vbanum; ui->ui_adpt = vhp->adptnum; config_fillin(ui); printf(" csr 0x%x", ui->ui_addr); config_vme(udp->ud_addr1_atype); if(map_addr2){ printf(" csr2 0x%x", ui->ui_addr2); config_vme(udp->ud_addr2_atype); } printf(" vec 0x%x", ui->ui_ivnum); printf(" priority %d\n", ui->ui_bus_priority); ui->ui_vbahd = vhp; switch(vbatype) { case VBA_3VIA: intr_dispatch = (int (**)())_3VIA_VEC_ADDR(vhp, vec); Cprintf("probevba: intr_dispatch = 0x%x\n", intr_dispatch); for (ivec = ui->ui_intr; *ivec; ivec++) { *intr_dispatch = *ivec; intr_dispatch++; } ui->ui_priority = splm[SPLBIO]; break; case VBA_XBIA: for (ivec = ui->ui_intr; *ivec; ivec++) { vecaddr = (int (**)())SCB_VME_VEC_ADDR(vhp->vbavec_page, vec); *vecaddr = scbentry(*ivec, SCB_ISTACK); Cprintf("probevba: vecaddr = 0x%x, *vecaddr = 0x%x\n", vecaddr, *vecaddr); vec++; } switch(ui->ui_bus_priority) { case 1: case 2: ui->ui_priority = splm[SPLBIO]; break; case 3: case 4: ui->ui_priority = splm[SPLBIO]; break; case 5: case 6: ui->ui_priority = splm[SPLBIO]; break; case 7: ui->ui_priority = splm[SPLBIO]; break; default: break; } break; } ui->ui_alive = 1; ui->ui_addr = (caddr_t)map_addr; ui->ui_addr2 = (caddr_t)map_addr2; ui->ui_physaddr = (caddr_t)svtophy(map_addr); ui->ui_dk = -1; /* ui_type comes from driver */ udp->ud_dinfo[ui->ui_unit] = ui; if(udp->ud_attach) (*udp->ud_attach)(ui); } vecvme++; return(1);}u_longvme_map_csr(addr, size, atype, udp, um, vhp) u_long addr;u_long size;u_long atype;struct uba_driver *udp;struct uba_ctlr *um;struct vba_hd *vhp;{register int reg, treg, nmr, nmr16, atype_size, byte_swap;register u_int offset, reg_shift;register u_long map_addr, taddr, vcar, pio;volatile u_int *via_pmr_ptr;volatile u_int *pmr_ptr;int i, pmrinit = 0, inval = 0; Cprintf("vme_map_csr: addr = 0x%x, size = 0x%x, atype = 0x%x\n", addr, size, atype); switch(atype & VME_ASPACE_MASK) { case VME_A16: if( (addr + size - 1) > 0xFFFF ) inval++; break; case VME_A24: if(((addr & VME_A24_VALID) == 0) || ((addr + size - 1) > 0xFFFFFF)) inval++; break; case VME_A32: if((addr & VME_A32_VALID) == 0) inval++; break; } if(inval) { printf("%s%d not configured: csr out of range\n", um->um_ctlrname, um->um_ctlr); return(0); } /* Reserve space consumed by device registers */ if (rmget(vhp->vba_map[atype & VME_ASPACE_MASK], size, addr) == 0) { printf("%s%d not configured: Overlapping csr space\n", um->um_ctlrname, um->um_ctlr); return(0); } switch(vhp->vba_type) { case VBA_3VIA: offset = (u_int)addr & XVIA_PIO_OFFSET; reg_shift = XVIA_PIO_REGSHFT; nmr = (((int)size + offset + (vhp->nbyte_piopmr - 1) ) >> XVIA_PIO_REGSHFT); break; case VBA_XBIA: offset = (u_int)addr & XVME_PIO_OFFSET; reg_shift = XVIB_PIO_REGSHFT; nmr = (((int)size + offset + (vhp->nbyte_piopmr - 1) ) >> XVME_PIO_SHIFT); Cprintf("vme_map_csr: vhp->pio_map = 0x%x\n", vhp->pio_map); Cprintf("vme_map_csr: vhp->nbyte_piopmr = 0x%x\n", vhp->nbyte_piopmr); break; } atype_size = (atype & VME_ASIZE_MASK) >> VME_ASIZE_SHIFT; byte_swap = (atype & VME_BS_MASK) >> VME_BS_SHIFT; reg = rmalloc(vhp->pio_map, nmr); if (reg == 0) { printf("%s%d not configured: Insufficient mapping resources\n", um->um_ctlrname, um->um_ctlr); return(0); } reg--; treg = reg; taddr = addr; switch(vhp->vba_type) { case VBA_3VIA: if( (atype & VME_ASPACE_MASK) == VME_A32) pio = (XVIA_PIO_A32 << XVIA_PIO_AS_SHIFT); else if ( (atype & VME_ASPACE_MASK) == VME_A16 ) pio = (XVIA_PIO_A16 << XVIA_PIO_AS_SHIFT); else pio = (XVIA_PIO_A24 << XVIA_PIO_AS_SHIFT); pio |= ( (atype_size + 1) << XVIA_PIO_DL_SHIFT) | (byte_swap << XVIA_PIO_BS_SHIFT) | (XVIA_PIO_SPROG << XVIA_PIO_FC_SHIFT) | XVIA_PIO_VALID; via_pmr_ptr = (u_int *)(Xviaregs.pio_pmr) + reg; Cprintf("vme_map_csr: via_pmr_ptr = 0x%x, nmr = %d\n", via_pmr_ptr, nmr); while (nmr-- != 0) { *(int *)via_pmr_ptr++ = pio | ((u_int)taddr & XVIA_PIO_MASK); (u_int)taddr += vhp->nbyte_piopmr; } WBFLUSH; break; case VBA_XBIA: if( (atype & VME_ASPACE_MASK) == VME_A24) vcar = XVIB_PIO_A24; else if( (atype & VME_ASPACE_MASK) == VME_A32) vcar = XVIB_PIO_A32; else vcar = XVIB_PIO_A16; vcar |= ( (atype_size + 1) << XVIB_PIO_DL_SHIFT ); while (nmr-- != 0) { XVIB_STORE_PMR(treg, ((u_int)taddr & XVIB_PIO_MASK) | vcar); (u_int)taddr += vhp->nbyte_piopmr; treg++; } break; }/* Create system virtual address of VME address space */ map_addr = offset; map_addr |= (reg << reg_shift); map_addr += (u_long)vhp->pio_base; Cprintf("vme_map_csr: map_addr = 0x%x\n", map_addr); return(map_addr);}intvme_unmap_csr(vhp, addr, size)struct vba_hd *vhp;u_long addr;int size;{ int reg, reg_shift, nmr, offset, i, s; volatile u_int *via_pmr_ptr; switch(vhp->vba_type) { case VBA_3VIA: offset = (u_int)addr & XVIA_PIO_OFFSET; reg_shift = XVIA_PIO_REGSHFT; nmr = (((int)size + offset + (vhp->nbyte_piopmr - 1) ) >> XVIA_PIO_REGSHFT); break; case VBA_XBIA: offset = (u_int)addr & XVME_PIO_OFFSET; reg_shift = XVIB_PIO_REGSHFT; nmr = (((int)size + offset + (vhp->nbyte_piopmr - 1) ) >> XVIB_PIO_REGSHFT); break; } reg = addr - (u_long)vhp->pio_base; reg = reg >> reg_shift; switch(vhp->vba_type) { case VBA_3VIA: via_pmr_ptr = (u_int *)(Xviaregs.pio_pmr) + reg; for (i = 0; i < nmr; i++) { *(int *)via_pmr_ptr++ = 0; } s = spl6(); rmfree(vhp->pio_map, (long)nmr, (long)reg); splx(s); break; case VBA_XBIA: break; }}/* Allocate the address space resource maps. These maps control *//* the I/O section of VME address space. This area will contain *//* device registers and onboard memory. It will also be used *//* for device to device DMA. *//* The A32 map will map the second 2GB of VME address space *//* The A24 map will map the second 8MB of VME address space *//* The A16 map will map the first 64KB of VME address space */intvme_init_maps(vhp)struct vba_hd *vhp;{ int i; for(i = 0; i < VME_NMAPS; i++) { KM_ALLOC(vhp->vba_map[i], struct map *, VBAMSIZ*sizeof(struct map), KM_RMAP, KM_CLEAR|KM_NOWAIT); if(vhp->vba_map[i] == (struct map *)NULL) return(0); } /* Only allocate A32 and A24 DMA maps as we do not support A16 DMA */ KM_ALLOC(vhp->dma_map[VME_A32], struct map *, VME_DMASIZ*sizeof(struct map), KM_RMAP, KM_CLEAR|KM_NOWAIT); if(vhp->dma_map[VME_A32] == (struct map *)NULL) return(0); KM_ALLOC(vhp->dma_map[VME_A24], struct map *, VME_DMASIZ*sizeof(struct map), KM_RMAP, KM_CLEAR|KM_NOWAIT); if(vhp->dma_map[VME_A24] == (struct map *)NULL) return(0); KM_ALLOC(vhp->pio_map, struct map *, VME_PIOSIZ*sizeof(struct map), KM_RMAP, KM_CLEAR|KM_NOWAIT); if(vhp->pio_map == (struct map *)NULL) return(0); rminit(vhp->vba_map[VME_A32], 0x80000000, 0x80000000, "vme A32 map",VBAMSIZ); rminit(vhp->vba_map[VME_A24], 0x800000, 0x800000, "vme A24 map",VBAMSIZ); rminit(vhp->vba_map[VME_A16], 0x10000, 0x1, "vme A16 map",VBAMSIZ); /* Allocate the DMA PMR space resource maps */ /* These maps are used for allocating the DMA Page Map Registers */ /* which reside on the host adapter modules. Each register maps */ /* one page. Since the address spaces overlap, some space must be */ /* removed from the A32 and A24 maps to account for the A24 and A16 */ /* spaces respectively. */ if(vhp->n32dmapmr) rminit(vhp->dma_map[VME_A32], vhp->n32dmapmr, 1, "vme A32 DMA PMR map",VME_DMASIZ); if(vhp->n24dmapmr) rminit(vhp->dma_map[VME_A24], vhp->n24dmapmr, 1, "vme A24 DMA PMR map",VME_DMASIZ); /* Reserve DMA registers that can't be used because of address */ /* space overlap */ rmget(vhp->dma_map[VME_A24], 0x10000/vhp->nbyte_dmapmr, 0x1); /* A16 space */ rmget(vhp->dma_map[VME_A32], 0x1000000/vhp->nbyte_dmapmr, 0x1); /* A24 space */ /* Allocate PIO PMR resource map */ /* This map controls the Page Map Registers used to access */ /* VME space from system space. The amount of memory that */ /* each register maps is adapter-dependent. */ rminit(vhp->pio_map, vhp->npiopmr, 1, "pio pmr map",VME_PIOSIZ); /* Reserve 3VIA PIO registers which are used for * PROM/register space. Add one to account for map * starting at 1. */ if ( vhp->vba_type == VBA_3VIA ) rmget(vhp->pio_map, 128, 1); return(1);}config_vme(atype)int atype;{ int aspace, dsize; aspace = atype & VME_ASPACE_MASK; dsize = (atype & VME_ASIZE_MASK) >> VME_ASIZE_SHIFT; printf(" %s", vme_spaces[dsize][aspace]);}u_longvba_get_vmeaddr(vhp, addr)struct vba_hd *vhp;u_long addr;{ u_long vmeaddr; u_long reg, reg_shift, nmr, offset; volatile u_int *via_pmr_ptr; switch(vhp->vba_type) { case VBA_3VIA: offset = addr & XVIA_PIO_OFFSET; reg_shift = XVIA_PIO_REGSHFT; reg = addr - (u_long)vhp->pio_base; reg = reg >> reg_shift; via_pmr_ptr = (u_int *)(Xviaregs.pio_pmr) + reg; vmeaddr = *(int *)via_pmr_ptr & XVIA_PIO_MASK; vmeaddr |= offset; break; case VBA_XBIA: reg = addr - (u_long)vhp->pio_base; reg = reg >> reg_shift; offset = (u_int)addr & XVME_PIO_OFFSET; reg_shift = XVIB_PIO_REGSHFT; XVIB_READ_PMR(reg, vmeaddr); vmeaddr |= offset; break; } return(vmeaddr);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -