Пример #1
0
pcireg_t
ttwoga_conf_read(void *cpv, pcitag_t tag, int offset)
{
	struct ttwoga_config *tcp = cpv;
	pcireg_t *datap, data;
	int b, d, f, ba;
	paddr_t addr;
	uint64_t old_hae3;

	if ((unsigned int)offset >= PCI_CONF_SIZE)
		return (pcireg_t) -1;

	pci_decompose_tag(&tcp->tc_pc, tag, &b, &d, &f);

	addr = b ? tag : ttwoga_make_type0addr(d, f);
	if (addr == (paddr_t)-1)
		return ((pcireg_t) -1);

	TTWOGA_CONF_LOCK();

	alpha_mb();
	old_hae3 = T2GA(tcp, T2_HAE0_3) & ~HAE0_3_PCA;
	T2GA(tcp, T2_HAE0_3) =
	    old_hae3 | ((b ? 1UL : 0UL) << HAE0_3_PCA_SHIFT);
	alpha_mb();
	alpha_mb();

	datap =
	    (pcireg_t *)ALPHA_PHYS_TO_K0SEG(tcp->tc_sysmap->tsmap_conf_base |
	    addr << 5UL |		/* address shift */
	    (offset & ~0x03) << 5UL |	/* address shift */
	    0x3 << 3UL);		/* 4-byte, size shift */
	data = (pcireg_t)-1;
	if (!(ba = badaddr(datap, sizeof *datap)))
		data = *datap;

	alpha_mb();
	T2GA(tcp, T2_HAE0_3) = old_hae3;
	alpha_mb();
	alpha_mb();

	alpha_pal_draina();
	alpha_mb();
	alpha_mb();

	TTWOGA_CONF_UNLOCK();

#if 0
	printf("ttwoga_conf_read: tag 0x%lx, reg 0x%x -> 0x%x @ %p%s\n",
	    tag, offset, data, datap, ba ? " (badaddr)" : "");
#endif

	return (data);
}
Пример #2
0
void
ttwoga_conf_write(void *cpv, pcitag_t tag, int offset, pcireg_t data)
{
	struct ttwoga_config *tcp = cpv;
	pcireg_t *datap;
	int b, d, f;
	paddr_t addr;
	uint64_t old_hae3;

	if ((unsigned int)offset >= PCI_CONF_SIZE)
		return;

	pci_decompose_tag(&tcp->tc_pc, tag, &b, &d, &f);

	addr = b ? tag : ttwoga_make_type0addr(d, f);
	if (addr == (paddr_t)-1)
		return;

	TTWOGA_CONF_LOCK();

	alpha_mb();
	old_hae3 = T2GA(tcp, T2_HAE0_3) & ~HAE0_3_PCA;
	T2GA(tcp, T2_HAE0_3) =
	    old_hae3 | ((b ? 1UL : 0UL) << HAE0_3_PCA_SHIFT);
	alpha_mb();
	alpha_mb();

	datap =
	    (pcireg_t *)ALPHA_PHYS_TO_K0SEG(tcp->tc_sysmap->tsmap_conf_base |
	    addr << 5UL |		/* address shift */
	    (offset & ~0x03) << 5UL |	/* address shift */
	    0x3 << 3UL);		/* 4-byte, size shift */

	alpha_mb();
	*datap = data;
	alpha_mb();
	alpha_mb();

	alpha_mb();
	T2GA(tcp, T2_HAE0_3) = old_hae3;
	alpha_mb();
	alpha_mb();

	TTWOGA_CONF_UNLOCK();

#if 0
	printf("ttwoga_conf_write: tag 0x%lx, reg 0x%x -> 0x%x @ %p\n",
	    tag, offset, data, datap);
#endif
}
Пример #3
0
void
ttwoga_dma_init(struct ttwoga_config *tcp)
{
	bus_dma_tag_t t;

	/*
	 * Initialize the DMA tag used for direct-mapped DMA.
	 */
	t = &tcp->tc_dmat_direct;
	t->_cookie = tcp;
	t->_wbase = TTWOGA_DIRECT_MAPPED_BASE;
	t->_wsize = TTWOGA_DIRECT_MAPPED_SIZE;
	t->_next_window = NULL;
	t->_boundary = 0;
	t->_sgmap = NULL;
	t->_get_tag = ttwoga_dma_get_tag;
	t->_dmamap_create = _bus_dmamap_create;
	t->_dmamap_destroy = _bus_dmamap_destroy;
	t->_dmamap_load = _bus_dmamap_load_direct;
	t->_dmamap_load_mbuf = _bus_dmamap_load_mbuf_direct;
	t->_dmamap_load_uio = _bus_dmamap_load_uio_direct;
	t->_dmamap_load_raw = _bus_dmamap_load_raw_direct;
	t->_dmamap_unload = _bus_dmamap_unload;
	t->_dmamap_sync = _bus_dmamap_sync;

	t->_dmamem_alloc = _bus_dmamem_alloc;
	t->_dmamem_free = _bus_dmamem_free;
	t->_dmamem_map = _bus_dmamem_map;
	t->_dmamem_unmap = _bus_dmamem_unmap;
	t->_dmamem_mmap = _bus_dmamem_mmap;

	/*
	 * Initialize the DMA tag used for sgmap-mapped DMA.
	 */
	t = &tcp->tc_dmat_sgmap;
	t->_cookie = tcp;
	t->_wbase = TTWOGA_SGMAP_MAPPED_BASE;
	t->_wsize = TTWOGA_SGMAP_MAPPED_SIZE;
	t->_next_window = NULL;
	t->_boundary = 0;
	t->_sgmap = &tcp->tc_sgmap;
	t->_pfthresh = TTWOGA_SGMAP_PFTHRESH;
	t->_get_tag = ttwoga_dma_get_tag;
	t->_dmamap_create = alpha_sgmap_dmamap_create;
	t->_dmamap_destroy = alpha_sgmap_dmamap_destroy;
	t->_dmamap_load = ttwoga_bus_dmamap_load_sgmap;
	t->_dmamap_load_mbuf = ttwoga_bus_dmamap_load_mbuf_sgmap;
	t->_dmamap_load_uio = ttwoga_bus_dmamap_load_uio_sgmap;
	t->_dmamap_load_raw = ttwoga_bus_dmamap_load_raw_sgmap;
	t->_dmamap_unload = ttwoga_bus_dmamap_unload_sgmap;
	t->_dmamap_sync = _bus_dmamap_sync;

	t->_dmamem_alloc = _bus_dmamem_alloc;
	t->_dmamem_free = _bus_dmamem_free;
	t->_dmamem_map = _bus_dmamem_map;
	t->_dmamem_unmap = _bus_dmamem_unmap;
	t->_dmamem_mmap = _bus_dmamem_mmap;

	/*
	 * Disable the SGMAP TLB, and flush it.  We reenable it if
	 * we have a Sable or a Gamma with T3 or T4; Gamma with T2
	 * has a TLB bug apparently severe enough to require disabling
	 * it.
	 */
	alpha_mb();
	T2GA(tcp, T2_IOCSR) &= ~IOCSR_ETLB;
	alpha_mb();
	alpha_mb();	/* MAGIC */

	TTWOGA_TLB_INVALIDATE(tcp);

	/*
	 * XXX We might want to make sure our DMA windows don't
	 * XXX overlap with PCI memory space!
	 */

	/*
	 * Set up window 1 as a 1G direct-mapped window
	 * starting at 1G.
	 */
	T2GA(tcp, T2_WBASE1) = 0;
	alpha_mb();

	T2GA(tcp, T2_WMASK1) = (TTWOGA_DIRECT_MAPPED_SIZE - 1) & WMASKx_PWM;
	alpha_mb();

	T2GA(tcp, T2_TBASE1) = 0;
	alpha_mb();

	T2GA(tcp, T2_WBASE1) = TTWOGA_DIRECT_MAPPED_BASE |
	    ((TTWOGA_DIRECT_MAPPED_BASE + (TTWOGA_DIRECT_MAPPED_SIZE - 1)) >>
	     WBASEx_PWxA_SHIFT) | WBASEx_PWE;
	alpha_mb();

	/*
	 * Initialize the SGMAP.
	 */
	alpha_sgmap_init(t, &tcp->tc_sgmap, "ttwoga_sgmap",
	    TTWOGA_SGMAP_MAPPED_BASE, 0, TTWOGA_SGMAP_MAPPED_SIZE,
	    sizeof(u_int64_t), NULL, 0);

	/*
	 * Set up window 2 as an 8MB SGMAP-mapped window
	 * starting at 8MB.
	 */
#ifdef DIAGNOSTIC
	if ((TTWOGA_SGMAP_MAPPED_BASE & WBASEx_PWSA) !=
	    TTWOGA_SGMAP_MAPPED_BASE)
		panic("ttwoga_dma_init: SGMAP base inconsistency");
#endif
	T2GA(tcp, T2_WBASE2) = 0;
	alpha_mb();

	T2GA(tcp, T2_WMASK2) = (TTWOGA_SGMAP_MAPPED_SIZE - 1) & WMASKx_PWM;
	alpha_mb();

	T2GA(tcp, T2_TBASE2) = tcp->tc_sgmap.aps_ptpa >> 1;
	alpha_mb();

	T2GA(tcp, T2_WBASE2) = TTWOGA_SGMAP_MAPPED_BASE |
	    ((TTWOGA_SGMAP_MAPPED_BASE + (TTWOGA_SGMAP_MAPPED_SIZE - 1)) >>
	     WBASEx_PWxA_SHIFT) | WBASEx_SGE | WBASEx_PWE;
	alpha_mb();

	/*
	 * Enable SGMAP TLB on Sable or Gamma with T3 or T4; see above.
	 */
	if (alpha_implver() == ALPHA_IMPLVER_EV4 ||
	    tcp->tc_rev >= TRN_T3) {
		alpha_mb();
		T2GA(tcp, T2_IOCSR) |= IOCSR_ETLB;
		alpha_mb();
		alpha_mb();	/* MAGIC */
		tcp->tc_use_tlb = 1;
	}

	/* XXX XXX BEGIN XXX XXX */
	{							/* XXX */
		extern paddr_t alpha_XXX_dmamap_or;		/* XXX */
		alpha_XXX_dmamap_or = TTWOGA_DIRECT_MAPPED_BASE;/* XXX */
	}							/* XXX */
	/* XXX XXX END XXX XXX */
}