/* * cpu_initclocks: * * Initialize the clock and get them going. */ void cpu_initclocks(void) { u_int oldirqstate; #if 0 if (hz < 50 || COUNTS_PER_SEC % hz) { printf("Cannot get %d Hz clock; using 100 Hz\n", hz); hz = 100; } #endif /* * We only have one timer available; stathz and profhz are * always left as 0 (the upper-layer clock code deals with * this situation). */ if (stathz != 0) printf("Cannot get %d Hz statclock\n", stathz); stathz = 0; if (profhz != 0) printf("Cannot get %d Hz profclock\n", profhz); profhz = 0; /* Report the clock frequency. */ aprint_normal("clock: hz=%d stathz=%d profhz=%d\n", hz, stathz, profhz); oldirqstate = disable_interrupts(I32_bit); /* Hook up the clock interrupt handler. */ clock_ih = becc_intr_establish(ICU_TIMERA, IPL_CLOCK, clockhandler, NULL); if (clock_ih == NULL) panic("cpu_initclocks: unable to register timer interrupt"); /* Set up the new clock parameters. */ /* Stop timer, clear interrupt */ BECC_CSR_WRITE(BECC_TSCRA, TSCRx_TIF); counts_per_hz = COUNTS_PER_SEC / hz; /* Set the timer preload value. */ BECC_CSR_WRITE(BECC_TPRA, counts_per_hz - 1); /* ...and start it in motion. */ BECC_CSR_WRITE(BECC_TSCRA, TSCRx_TE | TSCRx_CM); #ifdef __HAVE_FAST_SOFTINTS /* register soft interrupt handler as well */ becc_intr_establish(ICU_SOFT, IPL_SOFTCLOCK, becc_softint, NULL); #endif restore_interrupts(oldirqstate); tc_init(&becc_timecounter); }
static int becc_pci_conf_cleanup(struct becc_softc *sc) { uint32_t reg; int err=0; BECC_CSR_WRITE(BECC_POCR, 0); reg = becc_pcicore_read(sc, PCI_COMMAND_STATUS_REG); if (reg & 0xf9000000) { DPRINTF((" ** pci status error: %08x (%08x) **\n", reg, reg & 0xf9000000)); err = 1; becc_pcicore_write(sc, PCI_COMMAND_STATUS_REG, reg & 0xf900ffff); reg = becc_pcicore_read(sc, PCI_COMMAND_STATUS_REG); DPRINTF((" ** pci status after clearing: %08x (%08x) **\n", reg, reg & 0xf9000000)); } reg = BECC_CSR_READ(BECC_PMISR); if (reg & 0x000f000d) { DPRINTF((" ** pci master isr: %08x (%08x) **\n", reg, reg & 0x000f000d)); err = 1; BECC_CSR_WRITE(BECC_PMISR, reg & 0x000f000d); reg = BECC_CSR_READ(BECC_PMISR); DPRINTF((" ** pci master isr after clearing: %08x (%08x) **\n", reg, reg & 0x000f000d)); } reg = BECC_CSR_READ(BECC_PSISR); if (reg & 0x000f0210) { DPRINTF((" ** pci slave isr: %08x (%08x) **\n", reg, reg & 0x000f0210)); err = 1; BECC_CSR_WRITE(BECC_PSISR, reg & 0x000f0210); reg = BECC_CSR_READ(BECC_PSISR); DPRINTF((" ** pci slave isr after clearing: %08x (%08x) **\n", reg, reg & 0x000f0210)); } return err; }
/* * becc_calibrate_delay: * * Calibrate the delay loop. */ void becc_calibrate_delay(void) { /* * Just use hz=100 for now -- we'll adjust it, if necessary, * in cpu_initclocks(). */ counts_per_hz = COUNTS_PER_SEC / 100; /* Stop both timers, clear interrupts. */ BECC_CSR_WRITE(BECC_TSCRA, TSCRx_TIF); BECC_CSR_WRITE(BECC_TSCRB, TSCRx_TIF); /* Set the timer preload value. */ BECC_CSR_WRITE(BECC_TPRA, counts_per_hz - 1); /* Start the timer. */ BECC_CSR_WRITE(BECC_TSCRA, TSCRx_TE | TSCRx_CM); }
/* * clockhandler: * * Handle the hardclock interrupt. */ int clockhandler(void *arg) { struct clockframe *frame = arg; /* ACK the interrupt. */ BECC_CSR_WRITE(BECC_TSCRA, TSCRx_TE | TSCRx_CM | TSCRx_TIF); hardclock(frame); atomic_add_32(&becc_base, counts_per_hz); if (becc_hardclock_hook != NULL) (*becc_hardclock_hook)(); return (1); }
pcireg_t becc_pci_conf_read(void *v, pcitag_t tag, int offset) { struct becc_softc *sc = v; struct pciconf_state ps; vaddr_t va; pcireg_t rv; u_int s; if (becc_pci_conf_setup(sc, tag, offset, &ps)) return ((pcireg_t) -1); /* * Skip device 0 (the BECC itself). We don't want it * to appear as part of the PCI device space. */ if (ps.ps_b == 0 && ps.ps_d == 0) return ((pcireg_t) -1); PCI_CONF_LOCK(s); va = sc->sc_pci_cfg_base + ps.ps_offset; BECC_CSR_WRITE(BECC_POCR, ps.ps_type); if (badaddr_read((void *) va, sizeof(rv), &rv)) { /* XXX Check master/target abort? */ #if 0 printf("conf_read: %d/%d/%d bad address\n", ps.ps_b, ps.ps_d, ps.ps_f); #endif rv = (pcireg_t) -1; } if (becc_pci_conf_cleanup(sc)) rv = (pcireg_t) -1; PCI_CONF_UNLOCK(s); return (rv); }
void becc_pci_conf_write(void *v, pcitag_t tag, int offset, pcireg_t val) { struct becc_softc *sc = v; struct pciconf_state ps; vaddr_t va; u_int s; if (becc_pci_conf_setup(sc, tag, offset, &ps)) return; PCI_CONF_LOCK(s); BECC_CSR_WRITE(BECC_POCR, ps.ps_type); va = sc->sc_pci_cfg_base + ps.ps_offset; *(volatile pcireg_t *)va = val; becc_pci_conf_cleanup(sc); PCI_CONF_UNLOCK(s); }