static int xrpu_ioctl(dev_t dev, u_long cmd, caddr_t arg, int flag, struct proc *pr) { struct softc *sc = dev->si_drv1; int i, error; if (sc->mode == TIMECOUNTER) { i = dev2pps(dev); if (i < 0 || i >= XRPU_MAX_PPS) return ENODEV; error = pps_ioctl(cmd, arg, &sc->pps[i]); return (error); } if (cmd == XRPU_IOC_TIMECOUNTING) { struct xrpu_timecounting *xt = (struct xrpu_timecounting *)arg; /* Name SHALL be zero terminated */ xt->xt_name[sizeof xt->xt_name - 1] = '\0'; i = strlen(xt->xt_name); sc->tc.tc_name = (char *)malloc(i + 1, M_XRPU, M_WAITOK); strcpy(sc->tc.tc_name, xt->xt_name); sc->tc.tc_frequency = xt->xt_frequency; sc->tc.tc_get_timecount = xrpu_get_timecount; sc->tc.tc_poll_pps = xrpu_poll_pps; sc->tc.tc_priv = sc; sc->tc.tc_counter_mask = xt->xt_mask; sc->trigger = sc->virbase62 + xt->xt_addr_trigger; sc->latch = sc->virbase62 + xt->xt_addr_latch; for (i = 0; i < XRPU_MAX_PPS; i++) { if (xt->xt_pps[i].xt_addr_assert == 0 && xt->xt_pps[i].xt_addr_clear == 0) continue; make_dev(&xrpu_cdevsw, (i+1)<<16, UID_ROOT, GID_WHEEL, 0600, "xpps%d", i); sc->pps[i].ppscap = 0; if (xt->xt_pps[i].xt_addr_assert) { sc->assert[i] = sc->virbase62 + xt->xt_pps[i].xt_addr_assert; sc->pps[i].ppscap |= PPS_CAPTUREASSERT; } if (xt->xt_pps[i].xt_addr_clear) { sc->clear[i] = sc->virbase62 + xt->xt_pps[i].xt_addr_clear; sc->pps[i].ppscap |= PPS_CAPTURECLEAR; } pps_init(&sc->pps[i]); } sc->mode = TIMECOUNTER; init_timecounter(&sc->tc); return (0); } error = ENOTTY; return (error); }
static int piix_probe (device_t dev) { u_int32_t d; switch (pci_get_devid(dev)) { case 0x71138086: d = pci_read_config(dev, 0x4, 2); if (!(d & 1)) return 0; /* IO space not mapped */ d = pci_read_config(dev, 0x40, 4); piix_timecounter_address = (d & 0xffc0) + 8; piix_timecounter.tc_frequency = piix_freq; init_timecounter(&piix_timecounter); return (ENXIO); }; return (ENXIO); }
/* * Start the real-time and statistics clocks. Leave stathz 0 since there * are no other timers available. */ void cpu_initclocks() { if (clockdev == NULL) panic("cpu_initclocks: no clock attached"); tick = 1000000 / hz; /* number of microseconds between interrupts */ tickfix = 1000000 - (hz * tick); if (tickfix) { int ftp; ftp = min(ffs(tickfix), ffs(hz)); tickfix >>= (ftp - 1); tickfixinterval = hz >> (ftp - 1); } /* * Establish the clock interrupt; it's a special case. * * We establish the clock interrupt this late because if * we do it at clock attach time, we may have never been at * spl0() since taking over the system. Some versions of * PALcode save a clock interrupt, which would get delivered * when we spl0() in autoconf.c. If established the clock * interrupt handler earlier, that interrupt would go to * hardclock, which would then fall over because p->p_stats * isn't set at that time. */ last_time = alpha_rpcc(); scaled_ticks_per_cycle = ((u_int64_t)hz << FIX_SHIFT) / cycles_per_sec; max_cycles_per_tick = 2*cycles_per_sec / hz; alpha_timecounter.tc_frequency = cycles_per_sec; init_timecounter(&alpha_timecounter); platform.clockintr = (void (*) __P((void *))) handleclock; /* * Get the clock started. */ CLOCK_INIT(clockdev); }