summaryrefslogtreecommitdiffstats
path: root/sys/i386/include
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2005-02-08 20:25:07 +0000
committerjhb <jhb@FreeBSD.org>2005-02-08 20:25:07 +0000
commitad1ee10f6d12f8bbdd826c263511342a4a45857a (patch)
tree0d346c70694552278e41eaff461d9a620e55ac7e /sys/i386/include
parent1d264321faae4f3aba6b42846e735baa1dab10f3 (diff)
downloadFreeBSD-src-ad1ee10f6d12f8bbdd826c263511342a4a45857a.zip
FreeBSD-src-ad1ee10f6d12f8bbdd826c263511342a4a45857a.tar.gz
Use the local APIC timer to drive the various kernel clocks on SMP machines
rather than forwarding interrupts from the clock devices around using IPIs: - Add an IDT vector that pushes a clock frame and calls lapic_handle_timer(). - Add functions to program the local APIC timer including setting the divisor, and setting up the timer to either down a periodic countdown or one-shot countdown. - Add a lapic_setup_clock() function that the BSP calls from cpu_init_clocks() to setup the local APIC timer if it is going to be used. The setup uses a one-shot countdown to calibrate the timer. We then program the timer on each CPU to fire at a frequency of hz * 3. stathz is defined as freq / 23 (hz * 3 / 23), and profhz is defined as freq / 2 (hz * 3 / 2). This gives the clocks relatively prime divisors while keeping a low LCM for the frequency of the clock interrupts. Thanks to Peter Jeremy for suggesting this approach. - Remove the hardclock and statclock forwarding code including the two associated IPIs. The bitmap IPI handler has now effectively degenerated to just IPI_AST. - When the local APIC timer is used we don't turn the RTC on at all, but we still enable interrupts on the ISA timer 0 (i8254) for timecounting purposes.
Diffstat (limited to 'sys/i386/include')
-rw-r--r--sys/i386/include/apicvar.h8
-rw-r--r--sys/i386/include/smp.h2
2 files changed, 4 insertions, 6 deletions
diff --git a/sys/i386/include/apicvar.h b/sys/i386/include/apicvar.h
index a0f06ba..d4af36b 100644
--- a/sys/i386/include/apicvar.h
+++ b/sys/i386/include/apicvar.h
@@ -122,9 +122,7 @@
/* IPIs handled by IPI_BITMAPED_VECTOR (XXX ups is there a better place?) */
#define IPI_AST 0 /* Generate software trap. */
-#define IPI_HARDCLOCK 1 /* Inter-CPU clock handling. */
-#define IPI_STATCLOCK 2
-#define IPI_BITMAP_LAST IPI_STATCLOCK
+#define IPI_BITMAP_LAST IPI_AST
#define IPI_IS_BITMAPED(x) ((x) <= IPI_BITMAP_LAST)
#define IPI_STOP (APIC_IPI_INTS + 6) /* Stop CPU until restarted. */
@@ -171,7 +169,7 @@ struct apic_enumerator {
inthand_t
IDTVEC(apic_isr1), IDTVEC(apic_isr2), IDTVEC(apic_isr3),
IDTVEC(apic_isr4), IDTVEC(apic_isr5), IDTVEC(apic_isr6),
- IDTVEC(apic_isr7), IDTVEC(spuriousint);
+ IDTVEC(apic_isr7), IDTVEC(spuriousint), IDTVEC(timerint);
u_int apic_irq_to_idt(u_int irq);
u_int apic_idt_to_irq(u_int vector);
@@ -202,6 +200,7 @@ void lapic_ipi_raw(register_t icrlo, u_int dest);
void lapic_ipi_vectored(u_int vector, int dest);
int lapic_ipi_wait(int delay);
void lapic_handle_intr(struct intrframe frame);
+void lapic_handle_timer(struct clockframe frame);
void lapic_set_logical_id(u_int apic_id, u_int cluster, u_int cluster_id);
int lapic_set_lvt_mask(u_int apic_id, u_int lvt, u_char masked);
int lapic_set_lvt_mode(u_int apic_id, u_int lvt, u_int32_t mode);
@@ -211,6 +210,7 @@ int lapic_set_lvt_triggermode(u_int apic_id, u_int lvt,
enum intr_trigger trigger);
void lapic_set_tpr(u_int vector);
void lapic_setup(void);
+int lapic_setup_clock(void);
#endif /* !LOCORE */
#endif /* _MACHINE_APICVAR_H_ */
diff --git a/sys/i386/include/smp.h b/sys/i386/include/smp.h
index 6bad810a..7837120 100644
--- a/sys/i386/include/smp.h
+++ b/sys/i386/include/smp.h
@@ -67,8 +67,6 @@ void ipi_selected(u_int cpus, u_int ipi);
void ipi_all(u_int ipi);
void ipi_all_but_self(u_int ipi);
void ipi_self(u_int ipi);
-void forward_statclock(void);
-void forward_hardclock(void);
void ipi_bitmap_handler(struct clockframe frame);
u_int mp_bootaddress(u_int);
int mp_grab_cpu_hlt(void);
OpenPOWER on IntegriCloud