/* * gtmpsc_common_putc - polled console putc */ STATIC void gtmpsc_common_putc_wait_complete(struct gtmpsc_softc *sc, int ix) { gtmpsc_polltx_t *vtxp = &sc->sc_poll_sdmapage->tx[ix]; uint32_t csr; int wdog_interval = 0; bus_dmamap_sync(sc->sc_dmat, sc->sc_txdma_map, ix * sizeof(gtmpsc_polltx_t), sizeof(sdma_desc_t), BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); csr = vtxp->txdesc.sdma_csr; while (csr & SDMA_CSR_TX_OWN) { bus_dmamap_sync(sc->sc_dmat, sc->sc_txdma_map, ix * sizeof(gtmpsc_polltx_t), sizeof(sdma_desc_t), BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); DELAY(40); if (wdog_interval++ % 32) gt_watchdog_service(); bus_dmamap_sync(sc->sc_dmat, sc->sc_txdma_map, ix * sizeof(gtmpsc_polltx_t), sizeof(sdma_desc_t), BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); csr = vtxp->txdesc.sdma_csr; } if (csr & SDMA_CSR_TX_ES) aprint_error_dev(sc->sc_dev, "TX error, txdesc(%d) csr 0x%x\n", ix, csr); bus_dmamap_sync(sc->sc_dmat, sc->sc_txdma_map, ix * sizeof(gtmpsc_polltx_t) + sizeof(sdma_desc_t), sizeof(vtxp->txbuf), BUS_DMASYNC_POSTWRITE); }
void gt_watchdog_init(struct gt_softc *gt) { u_int32_t r; unsigned int omsr; omsr = extintr_disable(); printf("%s: watchdog", gt->gt_dev.dv_xname); /* * handle case where firmware started watchdog */ r = gt_read(gt, GT_WDOG_Config); printf(" status %#x,%#x:", r, gt_read(gt, GT_WDOG_Value)); if ((r & 0x80000000) != 0) { gt_watchdog_sc = gt; /* enabled */ gt_watchdog_state = 1; printf(" firmware-enabled\n"); gt_watchdog_service(); return; } else { printf(" firmware-disabled\n"); } extintr_restore(omsr); }
void gtpci_attach(struct device *parent, struct device *self, void *aux) { struct pcibus_attach_args pba; struct gt_attach_args * const ga = aux; struct gt_softc * const gt = device_private(parent); struct gtpci_softc * const gtp = device_private(self); struct gtpci_chipset * const gtpc = >p->gtpci_gtpc; struct pci_chipset * const pc = >pc->gtpc_pc; const int busno = ga->ga_unit; uint32_t data; GT_PCIFOUND(gt, ga); pc->pc_funcs = >pci_functions; pc->pc_parent = self; gtpc->gtpc_busno = busno; gtpc->gtpc_cfgaddr = PCI_CONFIG_ADDR(busno); gtpc->gtpc_cfgdata = PCI_CONFIG_DATA(busno); gtpc->gtpc_syncreg = PCI_SYNC_REG(busno); gtpc->gtpc_gt_memt = ga->ga_memt; gtpc->gtpc_gt_memh = ga->ga_memh; /* * Let's find out where we are located. */ data = gtpci_read(gtpc, PCI_P2P_CONFIGURATION(gtpc->gtpc_busno)); gtpc->gtpc_self = gtpci_make_tag(>pc->gtpc_pc, PCI_P2PCFG_BusNum_GET(data), PCI_P2PCFG_DevNum_GET(data), 0); switch (busno) { case 0: gtpc->gtpc_io_bs = gt->gt_pci0_iot; gtpc->gtpc_mem_bs = gt->gt_pci0_memt; gtpc->gtpc_host = gt->gt_pci0_host; break; case 1: gtpc->gtpc_io_bs = gt->gt_pci1_iot; gtpc->gtpc_mem_bs = gt->gt_pci1_memt; gtpc->gtpc_host = gt->gt_pci1_host; break; default: break; } /* * If no bus_spaces exist, then it's been disabled. */ if (gtpc->gtpc_io_bs == NULL && gtpc->gtpc_mem_bs == NULL) { aprint_normal(": disabled\n"); return; } aprint_normal("\n"); /* * clear any pre-existing error interrupt(s) * clear latched pci error registers * establish ISRs for PCI errors * enable PCI error interrupts */ gtpci_write(gtpc, PCI_ERROR_MASK(gtpc->gtpc_busno), 0); gtpci_write(gtpc, PCI_ERROR_CAUSE(gtpc->gtpc_busno), 0); (void)gtpci_read(gtpc, PCI_ERROR_DATA_LOW(gtpc->gtpc_busno)); (void)gtpci_read(gtpc, PCI_ERROR_DATA_HIGH(gtpc->gtpc_busno)); (void)gtpci_read(gtpc, PCI_ERROR_COMMAND(gtpc->gtpc_busno)); (void)gtpci_read(gtpc, PCI_ERROR_ADDRESS_HIGH(gtpc->gtpc_busno)); (void)gtpci_read(gtpc, PCI_ERROR_ADDRESS_LOW(gtpc->gtpc_busno)); if (gtpc->gtpc_host) { intr_establish(pci_irqs[gtpc->gtpc_busno][0], IST_LEVEL, IPL_VM, gtpci_error_intr, pc); intr_establish(pci_irqs[gtpc->gtpc_busno][1], IST_LEVEL, IPL_VM, gtpci_error_intr, pc); intr_establish(pci_irqs[gtpc->gtpc_busno][2], IST_LEVEL, IPL_VM, gtpci_error_intr, pc); aprint_normal_dev(pc->pc_parent, "%s%d error interrupts at irqs %s, %s, %s\n", "pci", busno, intr_string(pci_irqs[gtpc->gtpc_busno][0]), intr_string(pci_irqs[gtpc->gtpc_busno][1]), intr_string(pci_irqs[gtpc->gtpc_busno][2])); gtpci_write(gtpc, PCI_ERROR_MASK(gtpc->gtpc_busno), PCI_SERRMSK_ALL_ERRS); } /* * Fill in the pci_bus_attach_args */ pba.pba_pc = pc; pba.pba_bus = 0; pba.pba_iot = gtpc->gtpc_io_bs; pba.pba_memt = gtpc->gtpc_mem_bs; pba.pba_dmat = gt->gt_dmat; pba.pba_flags = 0; if (pba.pba_iot != NULL) pba.pba_flags |= PCI_FLAGS_IO_ENABLED; if (pba.pba_memt != NULL) pba.pba_flags |= PCI_FLAGS_MEM_ENABLED; data = gtpci_read(gtpc, PCI_COMMAND(gtpc->gtpc_busno)); if (data & PCI_CMD_MRdMul) pba.pba_flags |= PCI_FLAGS_MRM_OKAY; if (data & PCI_CMD_MRdLine) pba.pba_flags |= PCI_FLAGS_MRL_OKAY; pba.pba_flags |= PCI_FLAGS_MWI_OKAY; gt_watchdog_service(); /* * Configure the pci bus. */ config_found_ia(self, "pcibus", &pba, gtpci_cfprint); gt_watchdog_service(); }
/* * gtmpsc_common_getc - polled console read * * We copy data from the DMA buffers into a buffer in the softc * to reduce descriptor ownership turnaround time * MPSC can crater if it wraps descriptor rings, * which is asynchronous and throttled only by line speed. */ STATIC int gtmpsc_common_getc(struct gtmpsc_softc *sc) { gtmpsc_pollrx_t *vrxp; uint32_t csr; int ix, ch, wdog_interval = 0; if (!cold) mutex_spin_enter(&sc->sc_lock); ix = sc->sc_rcvdrx; vrxp = &sc->sc_poll_sdmapage->rx[ix]; while (sc->sc_rcvcnt == 0) { /* Wait receive */ bus_dmamap_sync(sc->sc_dmat, sc->sc_rxdma_map, ix * sizeof(gtmpsc_pollrx_t), sizeof(sdma_desc_t), BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); csr = vrxp->rxdesc.sdma_csr; if (csr & SDMA_CSR_RX_OWN) { GT_MPSC_WRITE(sc, GTMPSC_CHRN(2), GTMPSC_CHR2_EH | GTMPSC_CHR2_CRD); if (wdog_interval++ % 32) gt_watchdog_service(); bus_dmamap_sync(sc->sc_dmat, sc->sc_rxdma_map, ix * sizeof(gtmpsc_pollrx_t), sizeof(sdma_desc_t), BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); DELAY(50); continue; } if (csr & SDMA_CSR_RX_ES) aprint_error_dev(sc->sc_dev, "RX error, rxdesc csr 0x%x\n", csr); bus_dmamap_sync(sc->sc_dmat, sc->sc_rxdma_map, ix * sizeof(gtmpsc_pollrx_t) + sizeof(sdma_desc_t), sizeof(vrxp->rxbuf), BUS_DMASYNC_POSTREAD); vrxp->rxdesc.sdma_cnt &= SDMA_RX_CNT_BCNT_MASK; sc->sc_rcvcnt = vrxp->rxdesc.sdma_cnt; sc->sc_roffset = 0; sc->sc_rcvdrx = (ix + 1) % GTMPSC_NRXDESC; if (sc->sc_rcvcnt == 0) { /* cleanup this descriptor, and return to DMA */ CLEANUP_AND_RETURN_RXDMA(sc, sc->sc_rcvrx); sc->sc_rcvrx = sc->sc_rcvdrx; } ix = sc->sc_rcvdrx; vrxp = &sc->sc_poll_sdmapage->rx[ix]; } ch = vrxp->rxbuf[sc->sc_roffset++]; sc->sc_rcvcnt--; if (sc->sc_roffset == vrxp->rxdesc.sdma_cnt) { /* cleanup this descriptor, and return to DMA */ CLEANUP_AND_RETURN_RXDMA(sc, ix); sc->sc_rcvrx = (ix + 1) % GTMPSC_NRXDESC; } gt_watchdog_service(); if (!cold) mutex_spin_exit(&sc->sc_lock); return ch; }
void gt_attach_common(struct gt_softc *gt) { uint32_t cpucfg, cpumode, cpumstr; #ifdef DEBUG uint32_t loaddr, hiaddr; #endif gtfound = 1; cpumode = gt_read(gt, GT_CPU_Mode); aprint_normal(": id %d", GT_CPUMode_MultiGTID_GET(cpumode)); if (cpumode & GT_CPUMode_MultiGT) aprint_normal (" (multi)"); switch (GT_CPUMode_CPUType_GET(cpumode)) { case 4: aprint_normal(", 60x bus"); break; case 5: aprint_normal(", MPX bus"); break; default: aprint_normal(", %#x(?) bus", GT_CPUMode_CPUType_GET(cpumode)); break; } cpumstr = gt_read(gt, GT_CPU_Master_Ctl); cpumstr &= ~(GT_CPUMstrCtl_CleanBlock|GT_CPUMstrCtl_FlushBlock); #if 0 cpumstr |= GT_CPUMstrCtl_CleanBlock|GT_CPUMstrCtl_FlushBlock; #endif gt_write(gt, GT_CPU_Master_Ctl, cpumstr); switch (cpumstr & (GT_CPUMstrCtl_CleanBlock|GT_CPUMstrCtl_FlushBlock)) { case 0: break; case GT_CPUMstrCtl_CleanBlock: aprint_normal(", snoop=clean"); break; case GT_CPUMstrCtl_FlushBlock: aprint_normal(", snoop=flush"); break; case GT_CPUMstrCtl_CleanBlock|GT_CPUMstrCtl_FlushBlock: aprint_normal(", snoop=clean&flush"); break; } aprint_normal(" wdog=%#x,%#x\n", gt_read(gt, GT_WDOG_Config), gt_read(gt, GT_WDOG_Value)); #if DEBUG loaddr = GT_LowAddr_GET(gt_read(gt, GT_SCS0_Low_Decode)); hiaddr = GT_HighAddr_GET(gt_read(gt, GT_SCS0_High_Decode)); aprint_normal("%s: scs[0]=%#10x-%#10x\n", gt->gt_dev.dv_xname, loaddr, hiaddr); loaddr = GT_LowAddr_GET(gt_read(gt, GT_SCS1_Low_Decode)); hiaddr = GT_HighAddr_GET(gt_read(gt, GT_SCS1_High_Decode)); aprint_normal("%s: scs[1]=%#10x-%#10x\n", gt->gt_dev.dv_xname, loaddr, hiaddr); loaddr = GT_LowAddr_GET(gt_read(gt, GT_SCS2_Low_Decode)); hiaddr = GT_HighAddr_GET(gt_read(gt, GT_SCS2_High_Decode)); aprint_normal("%s: scs[2]=%#10x-%#10x\n", gt->gt_dev.dv_xname, loaddr, hiaddr); loaddr = GT_LowAddr_GET(gt_read(gt, GT_SCS3_Low_Decode)); hiaddr = GT_HighAddr_GET(gt_read(gt, GT_SCS3_High_Decode)); aprint_normal("%s: scs[3]=%#10x-%#10x\n", gt->gt_dev.dv_xname, loaddr, hiaddr); loaddr = GT_LowAddr_GET(gt_read(gt, GT_CS0_Low_Decode)); hiaddr = GT_HighAddr_GET(gt_read(gt, GT_CS0_High_Decode)); aprint_normal("%s: cs[0]=%#10x-%#10x\n", gt->gt_dev.dv_xname, loaddr, hiaddr); loaddr = GT_LowAddr_GET(gt_read(gt, GT_CS1_Low_Decode)); hiaddr = GT_HighAddr_GET(gt_read(gt, GT_CS1_High_Decode)); aprint_normal("%s: cs[1]=%#10x-%#10x\n", gt->gt_dev.dv_xname, loaddr, hiaddr); loaddr = GT_LowAddr_GET(gt_read(gt, GT_CS2_Low_Decode)); hiaddr = GT_HighAddr_GET(gt_read(gt, GT_CS2_High_Decode)); aprint_normal("%s: cs[2]=%#10x-%#10x\n", gt->gt_dev.dv_xname, loaddr, hiaddr); loaddr = GT_LowAddr_GET(gt_read(gt, GT_CS3_Low_Decode)); hiaddr = GT_HighAddr_GET(gt_read(gt, GT_CS3_High_Decode)); aprint_normal("%s: cs[3]=%#10x-%#10x\n", gt->gt_dev.dv_xname, loaddr, hiaddr); loaddr = GT_LowAddr_GET(gt_read(gt, GT_BootCS_Low_Decode)); hiaddr = GT_HighAddr_GET(gt_read(gt, GT_BootCS_High_Decode)); aprint_normal("%s: bootcs=%#10x-%#10x\n", gt->gt_dev.dv_xname, loaddr, hiaddr); loaddr = GT_LowAddr_GET(gt_read(gt, GT_PCI0_IO_Low_Decode)); hiaddr = GT_HighAddr_GET(gt_read(gt, GT_PCI0_IO_High_Decode)); aprint_normal("%s: pci0io=%#10x-%#10x ", gt->gt_dev.dv_xname, loaddr, hiaddr); loaddr = gt_read(gt, GT_PCI0_IO_Remap); aprint_normal("remap=%#010x\n", loaddr); loaddr = GT_LowAddr_GET(gt_read(gt, GT_PCI0_Mem0_Low_Decode)); hiaddr = GT_HighAddr_GET(gt_read(gt, GT_PCI0_Mem0_High_Decode)); aprint_normal("%s: pci0mem[0]=%#10x-%#10x ", gt->gt_dev.dv_xname, loaddr, hiaddr); loaddr = gt_read(gt, GT_PCI0_Mem0_Remap_Low); hiaddr = gt_read(gt, GT_PCI0_Mem0_Remap_High); aprint_normal("remap=%#010x.%#010x\n", hiaddr, loaddr); loaddr = GT_LowAddr_GET(gt_read(gt, GT_PCI0_Mem1_Low_Decode)); hiaddr = GT_HighAddr_GET(gt_read(gt, GT_PCI0_Mem1_High_Decode)); aprint_normal("%s: pci0mem[1]=%#10x-%#10x ", gt->gt_dev.dv_xname, loaddr, hiaddr); loaddr = gt_read(gt, GT_PCI0_Mem1_Remap_Low); hiaddr = gt_read(gt, GT_PCI0_Mem1_Remap_High); aprint_normal("remap=%#010x.%#010x\n", hiaddr, loaddr); loaddr = GT_LowAddr_GET(gt_read(gt, GT_PCI0_Mem2_Low_Decode)); hiaddr = GT_HighAddr_GET(gt_read(gt, GT_PCI0_Mem2_High_Decode)); aprint_normal("%s: pci0mem[2]=%#10x-%#10x ", gt->gt_dev.dv_xname, loaddr, hiaddr); loaddr = gt_read(gt, GT_PCI0_Mem2_Remap_Low); hiaddr = gt_read(gt, GT_PCI0_Mem2_Remap_High); aprint_normal("remap=%#010x.%#010x\n", hiaddr, loaddr); loaddr = GT_LowAddr_GET(gt_read(gt, GT_PCI0_Mem3_Low_Decode)); hiaddr = GT_HighAddr_GET(gt_read(gt, GT_PCI0_Mem3_High_Decode)); aprint_normal("%s: pci0mem[3]=%#10x-%#10x ", gt->gt_dev.dv_xname, loaddr, hiaddr); loaddr = gt_read(gt, GT_PCI0_Mem3_Remap_Low); hiaddr = gt_read(gt, GT_PCI0_Mem3_Remap_High); aprint_normal("remap=%#010x.%#010x\n", hiaddr, loaddr); loaddr = GT_LowAddr_GET(gt_read(gt, GT_PCI1_IO_Low_Decode)); hiaddr = GT_HighAddr_GET(gt_read(gt, GT_PCI1_IO_High_Decode)); aprint_normal("%s: pci1io=%#10x-%#10x ", gt->gt_dev.dv_xname, loaddr, hiaddr); loaddr = gt_read(gt, GT_PCI1_IO_Remap); aprint_normal("remap=%#010x\n", loaddr); loaddr = GT_LowAddr_GET(gt_read(gt, GT_PCI1_Mem0_Low_Decode)); hiaddr = GT_HighAddr_GET(gt_read(gt, GT_PCI1_Mem0_High_Decode)); aprint_normal("%s: pci1mem[0]=%#10x-%#10x ", gt->gt_dev.dv_xname, loaddr, hiaddr); loaddr = gt_read(gt, GT_PCI1_Mem0_Remap_Low); hiaddr = gt_read(gt, GT_PCI1_Mem0_Remap_High); aprint_normal("remap=%#010x.%#010x\n", hiaddr, loaddr); loaddr = GT_LowAddr_GET(gt_read(gt, GT_PCI1_Mem1_Low_Decode)); hiaddr = GT_HighAddr_GET(gt_read(gt, GT_PCI1_Mem1_High_Decode)); aprint_normal("%s: pci1mem[1]=%#10x-%#10x ", gt->gt_dev.dv_xname, loaddr, hiaddr); loaddr = gt_read(gt, GT_PCI1_Mem1_Remap_Low); hiaddr = gt_read(gt, GT_PCI1_Mem1_Remap_High); aprint_normal("remap=%#010x.%#010x\n", hiaddr, loaddr); loaddr = GT_LowAddr_GET(gt_read(gt, GT_PCI1_Mem2_Low_Decode)); hiaddr = GT_HighAddr_GET(gt_read(gt, GT_PCI1_Mem2_High_Decode)); aprint_normal("%s: pci1mem[2]=%#10x-%#10x ", gt->gt_dev.dv_xname, loaddr, hiaddr); loaddr = gt_read(gt, GT_PCI1_Mem2_Remap_Low); hiaddr = gt_read(gt, GT_PCI1_Mem2_Remap_High); aprint_normal("remap=%#010x.%#010x\n", hiaddr, loaddr); loaddr = GT_LowAddr_GET(gt_read(gt, GT_PCI1_Mem3_Low_Decode)); hiaddr = GT_HighAddr_GET(gt_read(gt, GT_PCI1_Mem3_High_Decode)); aprint_normal("%s: pci1mem[3]=%#10x-%#10x ", gt->gt_dev.dv_xname, loaddr, hiaddr); loaddr = gt_read(gt, GT_PCI1_Mem3_Remap_Low); hiaddr = gt_read(gt, GT_PCI1_Mem3_Remap_High); aprint_normal("remap=%#010x.%#010x\n", hiaddr, loaddr); loaddr = GT_LowAddr_GET(gt_read(gt, GT_Internal_Decode)); aprint_normal("%s: internal=%#10x-%#10x\n", gt->gt_dev.dv_xname, loaddr, loaddr+256*1024); loaddr = GT_LowAddr_GET(gt_read(gt, GT_CPU0_Low_Decode)); hiaddr = GT_HighAddr_GET(gt_read(gt, GT_CPU0_High_Decode)); aprint_normal("%s: cpu0=%#10x-%#10x\n", gt->gt_dev.dv_xname, loaddr, hiaddr); loaddr = GT_LowAddr_GET(gt_read(gt, GT_CPU1_Low_Decode)); hiaddr = GT_HighAddr_GET(gt_read(gt, GT_CPU1_High_Decode)); aprint_normal("%s: cpu1=%#10x-%#10x", gt->gt_dev.dv_xname, loaddr, hiaddr); #endif aprint_normal("%s:", gt->gt_dev.dv_xname); cpucfg = gt_read(gt, GT_CPU_Cfg); cpucfg |= GT_CPUCfg_ConfSBDis; /* per errata #46 */ cpucfg |= GT_CPUCfg_AACKDelay; /* per restriction #18 */ gt_write(gt, GT_CPU_Cfg, cpucfg); if (cpucfg & GT_CPUCfg_Pipeline) aprint_normal(" pipeline"); if (cpucfg & GT_CPUCfg_AACKDelay) aprint_normal(" aack-delay"); if (cpucfg & GT_CPUCfg_RdOOO) aprint_normal(" read-ooo"); if (cpucfg & GT_CPUCfg_IOSBDis) aprint_normal(" io-sb-dis"); if (cpucfg & GT_CPUCfg_ConfSBDis) aprint_normal(" conf-sb-dis"); if (cpucfg & GT_CPUCfg_ClkSync) aprint_normal(" clk-sync"); aprint_normal("\n"); gt_init_hostid(gt); gt_watchdog_init(gt); gt_init_interrupt(gt); #ifdef GT_ECC gt_ecc_intr_enb(gt); #endif gt_comm_intr_enb(gt); gt_devbus_intr_enb(gt); gt_watchdog_disable(); config_search(gt_cfsearch, >->gt_dev, NULL); gt_watchdog_service(); gt_watchdog_enable(); }