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

📄 vbainit.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 2 页
字号:
			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 + -