Index: src/sys/amd64/isa/clock.c =================================================================== RCS file: /home/ncvs/src/sys/amd64/isa/clock.c,v retrieving revision 1.221.2.1 diff -u -r1.221.2.1 clock.c --- src/sys/amd64/isa/clock.c 18 Jul 2005 19:52:04 -0000 1.221.2.1 +++ src/sys/amd64/isa/clock.c 21 Nov 2006 16:06:10 -0000 @@ -215,6 +215,8 @@ { while (rtcin(RTC_INTR) & RTCIR_PERIOD) { + if (using_lapic_timer) + continue; if (profprocs != 0) { if (--pscnt == 0) pscnt = psdiv; @@ -751,6 +753,37 @@ i8254_simple_get_timecount; i8254_timecounter.tc_counter_mask = 0xffff; set_timer_freq(timer_freq, hz); + if (using_lapic_timer == 1) { + if (hz > 8192) + panic("RTC: Cannot drive %u Hz", hz); + + rtc_statusa = 0; + + if (hz > 4096) + rtc_statusa |= RTCSA_8192; + else if (hz > 2048) + rtc_statusa |= RTCSA_4096; + else if (hz > 1024) + rtc_statusa |= RTCSA_2048; + else if (hz > 512) + rtc_statusa |= RTCSA_1024; + else if (hz > 256) + rtc_statusa |= RTCSA_512; + else if (hz > 128) + rtc_statusa |= RTCSA_256; + else if (hz > 64) + rtc_statusa |= RTCSA_128; + else if (hz > 32) + rtc_statusa |= RTCSA_64; + else + rtc_statusa |= RTCSA_32; + + if (bootverbose) + printf("RTC: Driving APIC timer at %u Hz\n", + 1U << (16 - rtc_statusa)); + + rtc_statusa |= RTCSA_DIVIDER; + } } /* Initialize RTC. */ @@ -763,14 +796,19 @@ * kernel clocks, then setup the RTC to periodically interrupt to * drive statclock() and profclock(). */ - if (!statclock_disable && !using_lapic_timer) { + if ((!statclock_disable && !using_lapic_timer) || + using_lapic_timer == 1) { diag = rtcin(RTC_DIAG); if (diag != 0) printf("RTC BIOS diagnostic error %b\n", diag, RTCDG_BITS); - /* Setting stathz to nonzero early helps avoid races. */ - stathz = RTC_NOPROFRATE; - profhz = RTC_PROFRATE; + if (!using_lapic_timer) { + /* + * Setting stathz to nonzero early helps avoid races. + */ + stathz = RTC_NOPROFRATE; + profhz = RTC_PROFRATE; + } /* Enable periodic interrupts from the RTC. */ rtc_statusb |= RTCSB_PINTR; Index: src/sys/amd64/amd64/local_apic.c =================================================================== RCS file: /home/ncvs/src/sys/amd64/amd64/local_apic.c,v retrieving revision 1.17.2.10 diff -u -r1.17.2.10 local_apic.c --- src/sys/amd64/amd64/local_apic.c 30 Oct 2006 18:03:02 -0000 1.17.2.10 +++ src/sys/amd64/amd64/local_apic.c 22 Nov 2006 03:20:21 -0000 @@ -338,6 +338,7 @@ lapic_setup_clock(void) { u_long value; + int i; /* Can't drive the timer without a local APIC. */ if (lapic == NULL) @@ -368,7 +369,9 @@ * both of the other timers with similarly small but relatively * prime divisors. */ - lapic_timer_hz = hz * LAPIC_TIMER_HZ_DIVIDER; + lapic_timer_hz = hz; + if (!(getenv_int("hw.apic.idle_cpu", &i) && i != 0)) + lapic_timer_hz *= LAPIC_TIMER_HZ_DIVIDER; stathz = lapic_timer_hz / LAPIC_TIMER_STATHZ_DIVIDER; profhz = lapic_timer_hz / LAPIC_TIMER_PROFHZ_DIVIDER; lapic_timer_period = value / lapic_timer_hz; @@ -379,7 +382,7 @@ */ lapic_timer_periodic(lapic_timer_period); lapic_timer_enable_intr(); - return (1); + return (lapic_timer_hz / hz); } void Index: src/sys/i386/isa/clock.c =================================================================== RCS file: /home/ncvs/src/sys/i386/isa/clock.c,v retrieving revision 1.222.2.2 diff -u -r1.222.2.2 clock.c --- src/sys/i386/isa/clock.c 22 Aug 2006 16:52:42 -0000 1.222.2.2 +++ src/sys/i386/isa/clock.c 21 Nov 2006 16:03:55 -0000 @@ -234,6 +234,8 @@ { while (rtcin(RTC_INTR) & RTCIR_PERIOD) { + if (using_lapic_timer) + continue; if (profprocs != 0) { if (--pscnt == 0) pscnt = psdiv; @@ -815,6 +817,37 @@ i8254_simple_get_timecount; i8254_timecounter.tc_counter_mask = 0xffff; set_timer_freq(timer_freq, hz); + if (using_lapic_timer == 1) { + if (hz > 8192) + panic("RTC: Cannot drive %u Hz", hz); + + rtc_statusa = 0; + + if (hz > 4096) + rtc_statusa |= RTCSA_8192; + else if (hz > 2048) + rtc_statusa |= RTCSA_4096; + else if (hz > 1024) + rtc_statusa |= RTCSA_2048; + else if (hz > 512) + rtc_statusa |= RTCSA_1024; + else if (hz > 256) + rtc_statusa |= RTCSA_512; + else if (hz > 128) + rtc_statusa |= RTCSA_256; + else if (hz > 64) + rtc_statusa |= RTCSA_128; + else if (hz > 32) + rtc_statusa |= RTCSA_64; + else + rtc_statusa |= RTCSA_32; + + if (bootverbose) + printf("RTC: Driving APIC timer at %u Hz\n", + 1U << (16 - rtc_statusa)); + + rtc_statusa |= RTCSA_DIVIDER; + } } /* Initialize RTC. */ @@ -827,14 +860,19 @@ * kernel clocks, then setup the RTC to periodically interrupt to * drive statclock() and profclock(). */ - if (!statclock_disable && !using_lapic_timer) { + if ((!statclock_disable && !using_lapic_timer) || + using_lapic_timer == 1) { diag = rtcin(RTC_DIAG); if (diag != 0) printf("RTC BIOS diagnostic error %b\n", diag, RTCDG_BITS); - /* Setting stathz to nonzero early helps avoid races. */ - stathz = RTC_NOPROFRATE; - profhz = RTC_PROFRATE; + if (!using_lapic_timer) { + /* + * Setting stathz to nonzero early helps avoid races. + */ + stathz = RTC_NOPROFRATE; + profhz = RTC_PROFRATE; + } /* Enable periodic interrupts from the RTC. */ rtc_statusb |= RTCSB_PINTR; Index: src/sys/i386/i386/local_apic.c =================================================================== RCS file: /home/ncvs/src/sys/i386/i386/local_apic.c,v retrieving revision 1.17.2.10 diff -u -r1.17.2.10 local_apic.c --- src/sys/i386/i386/local_apic.c 30 Oct 2006 18:03:03 -0000 1.17.2.10 +++ src/sys/i386/i386/local_apic.c 22 Nov 2006 03:20:21 -0000 @@ -339,6 +339,7 @@ lapic_setup_clock(void) { u_long value; + int i; /* Can't drive the timer without a local APIC. */ if (lapic == NULL) @@ -369,7 +370,9 @@ * both of the other timers with similarly small but relatively * prime divisors. */ - lapic_timer_hz = hz * LAPIC_TIMER_HZ_DIVIDER; + lapic_timer_hz = hz; + if (!(getenv_int("hw.apic.idle_cpu", &i) && i != 0)) + lapic_timer_hz *= LAPIC_TIMER_HZ_DIVIDER; stathz = lapic_timer_hz / LAPIC_TIMER_STATHZ_DIVIDER; profhz = lapic_timer_hz / LAPIC_TIMER_PROFHZ_DIVIDER; lapic_timer_period = value / lapic_timer_hz; @@ -380,7 +383,7 @@ */ lapic_timer_periodic(lapic_timer_period); lapic_timer_enable_intr(); - return (1); + return (lapic_timer_hz / hz); } void