FreeBSD/sys/kern/kern_clocksource.c
/*
 * Configure and start event timers (BSP part).
 */
Configure and start event timers (BSP part).
Configure and start event timers ( BSP part ) .
void
cpu_initclocks_bsp(void)
{
	struct pcpu_state *state;
	int base, div, cpu;
	mtx_init(&et_hw_mtx, "et_hw_mtx", NULL, MTX_SPIN);
	CPU_FOREACH(cpu) {
		state = DPCPU_ID_PTR(cpu, timerstate);
		mtx_init(&state->et_hw_mtx, "et_hw_mtx", NULL, MTX_SPIN);
		state->nextcall = SBT_MAX;
		state->nextcallopt = SBT_MAX;
	}
	periodic = want_periodic;
	if (timername[0])
		timer = et_find(timername, 0, 0);
	if (timer == NULL && periodic) {
		timer = et_find(NULL,
		    ET_FLAGS_PERIODIC, ET_FLAGS_PERIODIC);
	}
	if (timer == NULL) {
		timer = et_find(NULL,
		    ET_FLAGS_ONESHOT, ET_FLAGS_ONESHOT);
	}
	if (timer == NULL && !periodic) {
		timer = et_find(NULL,
		    ET_FLAGS_PERIODIC, ET_FLAGS_PERIODIC);
	}
	if (timer == NULL)
		panic("No usable event timer found!");
	et_init(timer, timercb, NULL, NULL);
	if (periodic && (timer->et_flags & ET_FLAGS_PERIODIC) == 0)
		periodic = 0;
	else if (!periodic && (timer->et_flags & ET_FLAGS_ONESHOT) == 0)
		periodic = 1;
	if (timer->et_flags & ET_FLAGS_C3STOP)
		cpu_disable_c3_sleep++;
	if (singlemul <= 0 || singlemul > 20) {
		if (hz >= 1500 || (hz % 128) == 0)
			singlemul = 1;
		else if (hz >= 750)
			singlemul = 2;
		else
			singlemul = 4;
	}
	if (periodic) {
		base = round_freq(timer, hz * singlemul);
		singlemul = max((base + hz / 2) / hz, 1);
		hz = (base + singlemul / 2) / singlemul;
		if (base <= 128)
			stathz = base;
		else {
			div = base / 128;
			if (div >= singlemul && (div % singlemul) == 0)
				div++;
			stathz = base / div;
		}
		profhz = stathz;
		while ((profhz + stathz) <= 128 * 64)
			profhz += stathz;
		profhz = round_freq(timer, profhz);
	} else {
		hz = round_freq(timer, hz);
		stathz = round_freq(timer, 127);
		profhz = round_freq(timer, stathz * 64);
	}
	tick = 1000000 / hz;
	tick_sbt = SBT_1S / hz;
	tick_bt = sbttobt(tick_sbt);
	statperiod = SBT_1S / stathz;
	profperiod = SBT_1S / profhz;
	ET_LOCK();
	configtimer(1);
	ET_UNLOCK();
}
void cpu_initclocks_bsp ( void ) { struct pcpu_state * state ; int base , div , cpu ; mtx_init ( & et_hw_mtx , " " , NULL , MTX_SPIN ) ; CPU_FOREACH ( cpu ) { state = DPCPU_ID_PTR ( cpu , timerstate ) ; mtx_init ( & state -> et_hw_mtx , " " , NULL , MTX_SPIN ) ; state -> nextcall = SBT_MAX ; state -> nextcallopt = SBT_MAX ; } periodic = want_periodic ; if ( timername [ 0 ] ) timer = et_find ( timername , 0 , 0 ) ; if ( timer == NULL && periodic ) { timer = et_find ( NULL , ET_FLAGS_PERIODIC , ET_FLAGS_PERIODIC ) ; } if ( timer == NULL ) { timer = et_find ( NULL , ET_FLAGS_ONESHOT , ET_FLAGS_ONESHOT ) ; } if ( timer == NULL && ! periodic ) { timer = et_find ( NULL , ET_FLAGS_PERIODIC , ET_FLAGS_PERIODIC ) ; } if ( timer == NULL ) panic ( " " ) ; et_init ( timer , timercb , NULL , NULL ) ; if ( periodic && ( timer -> et_flags & ET_FLAGS_PERIODIC ) == 0 ) periodic = 0 ; else if ( ! periodic && ( timer -> et_flags & ET_FLAGS_ONESHOT ) == 0 ) periodic = 1 ; if ( timer -> et_flags & ET_FLAGS_C3STOP ) cpu_disable_c3_sleep ++ ; if ( singlemul <= 0 || singlemul > 20 ) { if ( hz >= 1500 || ( hz % 128 ) == 0 ) singlemul = 1 ; else if ( hz >= 750 ) singlemul = 2 ; else singlemul = 4 ; } if ( periodic ) { base = round_freq ( timer , hz * singlemul ) ; singlemul = max ( ( base + hz / 2 ) / hz , 1 ) ; hz = ( base + singlemul / 2 ) / singlemul ; if ( base <= 128 ) stathz = base ; else { div = base / 128 ; if ( div >= singlemul && ( div % singlemul ) == 0 ) div ++ ; stathz = base / div ; } profhz = stathz ; while ( ( profhz + stathz ) <= 128 * 64 ) profhz += stathz ; profhz = round_freq ( timer , profhz ) ; } else { hz = round_freq ( timer , hz ) ; stathz = round_freq ( timer , 127 ) ; profhz = round_freq ( timer , stathz * 64 ) ; } tick = 1000000 / hz ; tick_sbt = SBT_1S / hz ; tick_bt = sbttobt ( tick_sbt ) ; statperiod = SBT_1S / stathz ; profperiod = SBT_1S / profhz ; ET_LOCK ( ) ; configtimer ( 1 ) ; ET_UNLOCK ( ) ; }
Configure and start event timers (BSP part).
Configure and start event timers ( BSP part ) .
/* Grab requested timer or the best of present. */ /* Adapt to timer capabilities. */ /*
	 * We honor the requested 'hz' value.
	 * We want to run stathz in the neighborhood of 128hz.
	 * We would like profhz to run as often as possible.
	 */