예제 #1
0
static void
uart_pps_process(struct uart_softc *sc, int ser_sig)
{
	sbintime_t now;
	int is_assert, pps_sig;

	/* Which signal is configured as PPS?  Early out if none. */
	switch(sc->sc_pps_mode & UART_PPS_SIGNAL_MASK) {
	case UART_PPS_CTS:
		pps_sig = SER_CTS;
		break;
	case UART_PPS_DCD:
		pps_sig = SER_DCD;
		break;
	default:
		return;
	}

	/* Early out if there is no change in the signal configured as PPS. */
	if ((ser_sig & SER_DELTA(pps_sig)) == 0)
		return;

	/*
	 * In narrow-pulse mode we need to synthesize both capture and clear
	 * events from a single "delta occurred" indication from the uart
	 * hardware because the pulse width is too narrow to reliably detect
	 * both edges.  However, when the pulse width is close to our interrupt
	 * processing latency we might intermittantly catch both edges.  To
	 * guard against generating spurious events when that happens, we use a
	 * separate timer to ensure at least half a second elapses before we
	 * generate another event.
	 */
	pps_capture(&sc->sc_pps);
	if (sc->sc_pps_mode & UART_PPS_NARROW_PULSE) {
		now = getsbinuptime();
		if (now > sc->sc_pps_captime + 500 * SBT_1MS) {
			sc->sc_pps_captime = now;
			pps_event(&sc->sc_pps, PPS_CAPTUREASSERT);
			pps_event(&sc->sc_pps, PPS_CAPTURECLEAR);
		}
	} else  {
		is_assert = ser_sig & pps_sig;
		if (sc->sc_pps_mode & UART_PPS_INVERT_PULSE)
			is_assert = !is_assert;
		pps_event(&sc->sc_pps, is_assert ? PPS_CAPTUREASSERT :
		    PPS_CAPTURECLEAR);
	}
}
예제 #2
0
파일: fortuna.c 프로젝트: fengsi/freebsd
/* The argument buf points to a whole number of blocks. */
void
random_fortuna_read(uint8_t *buf, u_int bytecount)
{
#ifdef _KERNEL
	sbintime_t thistime;
#endif
	struct randomdev_hash context;
	uint8_t s[NPOOLS*KEYSIZE], temp[KEYSIZE];
	int i;
	u_int seedlength;

	/* We must be locked for all this as plenty of state gets messed with */
	mtx_lock(&random_reseed_mtx);

	/* if buf == NULL and bytecount == 0 then this is the pre-read. */
	/* if buf == NULL and bytecount != 0 then this is the post-read; ignore. */
	if (buf == NULL) {
		if (bytecount == 0) {
			if (fortuna_state.pool[0].length >= fortuna_state.minpoolsize
#ifdef _KERNEL
			/* F&S - Use 'getsbinuptime()' to prevent reseed-spamming. */
		    	&& ((thistime = getsbinuptime()) - fortuna_state.lasttime > hz/10)
#endif
		    	) {
#ifdef _KERNEL
				fortuna_state.lasttime = thistime;
#endif

				seedlength = 0U;
				/* F&S - ReseedCNT = ReseedCNT + 1 */
				fortuna_state.reseedcount++;
				/* s = \epsilon by default */
				for (i = 0; i < NPOOLS; i++) {
					/* F&S - if Divides(ReseedCnt, 2^i) ... */
					if ((fortuna_state.reseedcount % (1 << i)) == 0U) {
						seedlength += KEYSIZE;
						/* F&S - temp = (P_i) */
						randomdev_hash_finish(&fortuna_state.pool[i].hash, temp);
						/* F&S - P_i = \epsilon */
						randomdev_hash_init(&fortuna_state.pool[i].hash);
						fortuna_state.pool[i].length = 0U;
						/* F&S - s = s|H(temp) */
						randomdev_hash_init(&context);
						randomdev_hash_iterate(&context, temp, KEYSIZE);
						randomdev_hash_finish(&context, s + i*KEYSIZE);
					}
					else
						break;
				}
#ifdef RANDOM_DEBUG
				printf("random: active reseed: reseedcount [%d] ", fortuna_state.reseedcount);
				for (i = 0; i < NPOOLS; i++)
					printf(" %d", fortuna_state.pool[i].length);
				printf("\n");
#endif
				/* F&S */
				reseed(s, seedlength);

				/* Clean up */
				memset(s, 0, seedlength);
				seedlength = 0U;
				memset(temp, 0, sizeof(temp));
				memset(&context, 0, sizeof(context));
			}
		}
	}
	/* if buf != NULL do a regular read. */
	else
		random_fortuna_genrandom(buf, bytecount);

	mtx_unlock(&random_reseed_mtx);
}