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); }
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 }
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 */ }