summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/alpha/alpha/trap.c13
-rw-r--r--sys/alpha/include/cpu.h2
-rw-r--r--sys/alpha/include/globals.h1
-rw-r--r--sys/amd64/amd64/apic_vector.S55
-rw-r--r--sys/amd64/amd64/cpu_switch.S1
-rw-r--r--sys/amd64/amd64/genassym.c1
-rw-r--r--sys/amd64/amd64/machdep.c9
-rw-r--r--sys/amd64/amd64/mp_machdep.c9
-rw-r--r--sys/amd64/amd64/mptable.c9
-rw-r--r--sys/amd64/amd64/swtch.s1
-rw-r--r--sys/amd64/amd64/trap.c12
-rw-r--r--sys/amd64/amd64/tsc.c157
-rw-r--r--sys/amd64/include/cpu.h15
-rw-r--r--sys/amd64/include/mptable.h9
-rw-r--r--sys/amd64/include/mutex.h1
-rw-r--r--sys/amd64/include/pcpu.h1
-rw-r--r--sys/amd64/isa/atpic_vector.S48
-rw-r--r--sys/amd64/isa/clock.c157
-rw-r--r--sys/amd64/isa/icu_vector.S48
-rw-r--r--sys/amd64/isa/icu_vector.s48
-rw-r--r--sys/i386/i386/apic_vector.s55
-rw-r--r--sys/i386/i386/genassym.c1
-rw-r--r--sys/i386/i386/globals.s6
-rw-r--r--sys/i386/i386/machdep.c9
-rw-r--r--sys/i386/i386/mp_machdep.c9
-rw-r--r--sys/i386/i386/mptable.c9
-rw-r--r--sys/i386/i386/swtch.s1
-rw-r--r--sys/i386/i386/trap.c12
-rw-r--r--sys/i386/i386/tsc.c157
-rw-r--r--sys/i386/include/asnames.h1
-rw-r--r--sys/i386/include/cpu.h15
-rw-r--r--sys/i386/include/globaldata.h1
-rw-r--r--sys/i386/include/globals.h2
-rw-r--r--sys/i386/include/lock.h15
-rw-r--r--sys/i386/include/mptable.h9
-rw-r--r--sys/i386/include/mutex.h1
-rw-r--r--sys/i386/include/pcpu.h1
-rw-r--r--sys/i386/include/smptests.h2
-rw-r--r--sys/i386/isa/apic_vector.s55
-rw-r--r--sys/i386/isa/atpic_vector.s48
-rw-r--r--sys/i386/isa/clock.c157
-rw-r--r--sys/i386/isa/icu_vector.s48
-rw-r--r--sys/isa/atrtc.c157
-rw-r--r--sys/kern/kern_clock.c42
-rw-r--r--sys/kern/kern_synch.c14
-rw-r--r--sys/kern/subr_smp.c9
-rw-r--r--sys/kern/subr_trap.c12
-rw-r--r--sys/powerpc/include/globals.h1
-rw-r--r--sys/sys/proc.h4
49 files changed, 466 insertions, 984 deletions
diff --git a/sys/alpha/alpha/trap.c b/sys/alpha/alpha/trap.c
index 3e773d3..79019bd 100644
--- a/sys/alpha/alpha/trap.c
+++ b/sys/alpha/alpha/trap.c
@@ -784,6 +784,11 @@ ast(framep)
sticks = p->p_sticks;
p->p_md.md_tf = framep;
+ /*
+ * XXX - is this still correct? What about a clock interrupt
+ * that runs hardclock() and triggers a delayed SIGVTALRM or
+ * SIGPROF?
+ */
if ((framep->tf_regs[FRAME_PS] & ALPHA_PSL_USERMODE) == 0)
panic("ast and not user");
@@ -795,6 +800,14 @@ ast(framep)
addupc_task(p, p->p_stats->p_prof.pr_addr,
p->p_stats->p_prof.pr_ticks);
}
+ if (p->p_flag & P_ALRMPEND) {
+ p->p_flag &= ~P_ALRMPEND;
+ psignal(p, SIGVTALRM);
+ }
+ if (p->p_flag & P_PROFPEND) {
+ p->p_flag &= ~P_PROFPEND;
+ psignal(p, SIGPROF);
+ }
userret(p, framep->tf_regs[FRAME_PC], sticks, 1);
diff --git a/sys/alpha/include/cpu.h b/sys/alpha/include/cpu.h
index cd60cc6..a45b4d1 100644
--- a/sys/alpha/include/cpu.h
+++ b/sys/alpha/include/cpu.h
@@ -62,8 +62,6 @@ struct clockframe {
};
#define CLKF_USERMODE(framep) \
(((framep)->cf_tf.tf_regs[FRAME_PS] & ALPHA_PSL_USERMODE) != 0)
-#define CLKF_BASEPRI(framep) \
- (((framep)->cf_tf.tf_regs[FRAME_PS] & ALPHA_PSL_IPL_MASK) == 0)
#define CLKF_PC(framep) ((framep)->cf_tf.tf_regs[FRAME_PC])
#define CLKF_INTR(framep) (PCPU_GET(intr_nesting_level) >= 2)
diff --git a/sys/alpha/include/globals.h b/sys/alpha/include/globals.h
index 303efdf..f85a67c 100644
--- a/sys/alpha/include/globals.h
+++ b/sys/alpha/include/globals.h
@@ -56,7 +56,6 @@ register struct globaldata *globalp __asm__("$8");
#define switchtime PCPU_GET(switchtime)
#define switchticks PCPU_GET(switchticks)
#define cpuid PCPU_GET(cpuno)
-#define prevproc PCPU_GET(curproc) /* XXX - until ithreads */
#endif /* _KERNEL */
diff --git a/sys/amd64/amd64/apic_vector.S b/sys/amd64/amd64/apic_vector.S
index 11d9797..1f80224 100644
--- a/sys/amd64/amd64/apic_vector.S
+++ b/sys/amd64/amd64/apic_vector.S
@@ -15,6 +15,23 @@
/* make an index into the IO APIC from the IRQ# */
#define REDTBL_IDX(irq_num) (0x10 + ((irq_num) * 2))
+/*
+ *
+ */
+#define PUSH_FRAME \
+ pushl $0 ; /* dummy error code */ \
+ pushl $0 ; /* dummy trap type */ \
+ pushal ; \
+ pushl %ds ; /* save data and extra segments ... */ \
+ pushl %es ; \
+ pushl %fs
+
+#define POP_FRAME \
+ popl %fs ; \
+ popl %es ; \
+ popl %ds ; \
+ popal ; \
+ addl $4+4,%esp
/*
* Macros for interrupt entry, call to handler, and exit.
@@ -24,18 +41,14 @@
.text ; \
SUPERALIGN_TEXT ; \
IDTVEC(vec_name) ; \
- pushl %eax ; /* save only call-used registers */ \
- pushl %ecx ; \
- pushl %edx ; \
- pushl %ds ; \
- MAYBE_PUSHL_ES ; \
- pushl %fs ; \
+ PUSH_FRAME ; \
movl $KDSEL,%eax ; \
mov %ax,%ds ; \
- MAYBE_MOVW_AX_ES ; \
+ mov %ax,%es ; \
movl $KPSEL,%eax ; \
mov %ax,%fs ; \
- FAKE_MCOUNT((5+ACTUALLY_PUSHED)*4(%esp)) ; \
+ FAKE_MCOUNT(13*4(%esp)) ; \
+ incb _intr_nesting_level ; \
pushl _intr_unit + (irq_num) * 4 ; \
call *_intr_handler + (irq_num) * 4 ; /* do the work ASAP */ \
addl $4, %esp ; \
@@ -46,31 +59,7 @@ IDTVEC(vec_name) ; \
lock ; \
incl (%eax) ; \
MEXITCOUNT ; \
- popl %fs ; \
- MAYBE_POPL_ES ; \
- popl %ds ; \
- popl %edx ; \
- popl %ecx ; \
- popl %eax ; \
- iret
-
-/*
- *
- */
-#define PUSH_FRAME \
- pushl $0 ; /* dummy error code */ \
- pushl $0 ; /* dummy trap type */ \
- pushal ; \
- pushl %ds ; /* save data and extra segments ... */ \
- pushl %es ; \
- pushl %fs
-
-#define POP_FRAME \
- popl %fs ; \
- popl %es ; \
- popl %ds ; \
- popal ; \
- addl $4+4,%esp
+ jmp doreti_next
#define IOAPICADDR(irq_num) CNAME(int_to_apicintpin) + 16 * (irq_num) + 8
#define REDIRIDX(irq_num) CNAME(int_to_apicintpin) + 16 * (irq_num) + 12
diff --git a/sys/amd64/amd64/cpu_switch.S b/sys/amd64/amd64/cpu_switch.S
index ac71f0c..32dbe56 100644
--- a/sys/amd64/amd64/cpu_switch.S
+++ b/sys/amd64/amd64/cpu_switch.S
@@ -82,7 +82,6 @@ ENTRY(cpu_switch)
/* switch to new process. first, save context as needed */
movl _curproc,%ecx
- movl %ecx,_prevproc
/* if no process to save, don't bother */
testl %ecx,%ecx
diff --git a/sys/amd64/amd64/genassym.c b/sys/amd64/amd64/genassym.c
index 78c6075..0566dd7 100644
--- a/sys/amd64/amd64/genassym.c
+++ b/sys/amd64/amd64/genassym.c
@@ -173,7 +173,6 @@ ASSYM(BI_ESYMTAB, offsetof(struct bootinfo, bi_esymtab));
ASSYM(BI_KERNEND, offsetof(struct bootinfo, bi_kernend));
ASSYM(GD_SIZEOF, sizeof(struct globaldata));
ASSYM(GD_CURPROC, offsetof(struct globaldata, gd_curproc));
-ASSYM(GD_PREVPROC, offsetof(struct globaldata, gd_prevproc));
ASSYM(GD_NPXPROC, offsetof(struct globaldata, gd_npxproc));
ASSYM(GD_IDLEPROC, offsetof(struct globaldata, gd_idleproc));
ASSYM(GD_CURPCB, offsetof(struct globaldata, gd_curpcb));
diff --git a/sys/amd64/amd64/machdep.c b/sys/amd64/amd64/machdep.c
index 355a0a9..7055010 100644
--- a/sys/amd64/amd64/machdep.c
+++ b/sys/amd64/amd64/machdep.c
@@ -1883,7 +1883,6 @@ init386(first)
/* setup curproc so that mutexes work */
PCPU_SET(curproc, &proc0);
- PCPU_SET(prevproc, &proc0);
/* make ldt memory segments */
/*
@@ -1945,6 +1944,11 @@ init386(first)
lidt(&r_idt);
/*
+ * We need this mutex before the console probe.
+ */
+ mtx_init(&clock_lock, "clk interrupt lock", MTX_SPIN);
+
+ /*
* Initialize the console before we print anything out.
*/
cninit();
@@ -1955,8 +1959,7 @@ init386(first)
#endif
/*
- * Giant is used early for at least debugger traps, unexpected traps,
- * and vm86bios initialization.
+ * Giant is used early for at least debugger traps and unexpected traps.
*/
mtx_init(&Giant, "Giant", MTX_DEF);
diff --git a/sys/amd64/amd64/mp_machdep.c b/sys/amd64/amd64/mp_machdep.c
index ea9aee8..5ef95b3 100644
--- a/sys/amd64/amd64/mp_machdep.c
+++ b/sys/amd64/amd64/mp_machdep.c
@@ -1900,11 +1900,6 @@ struct simplelock mcount_lock;
struct simplelock com_lock;
#endif /* USE_COMLOCK */
-#ifdef USE_CLOCKLOCK
-/* lock regions around the clock hardware */
-struct simplelock clock_lock;
-#endif /* USE_CLOCKLOCK */
-
/* lock around the MP rendezvous */
static struct simplelock smp_rv_lock;
@@ -1930,9 +1925,6 @@ init_locks(void)
#ifdef USE_COMLOCK
s_lock_init((struct simplelock*)&com_lock);
#endif /* USE_COMLOCK */
-#ifdef USE_CLOCKLOCK
- s_lock_init((struct simplelock*)&clock_lock);
-#endif /* USE_CLOCKLOCK */
s_lock_init(&ap_boot_lock);
}
@@ -2425,7 +2417,6 @@ ap_init(void)
* something unique to lock with.
*/
PCPU_SET(curproc,idleproc);
- PCPU_SET(prevproc,idleproc);
microuptime(&switchtime);
switchticks = ticks;
diff --git a/sys/amd64/amd64/mptable.c b/sys/amd64/amd64/mptable.c
index ea9aee8..5ef95b3 100644
--- a/sys/amd64/amd64/mptable.c
+++ b/sys/amd64/amd64/mptable.c
@@ -1900,11 +1900,6 @@ struct simplelock mcount_lock;
struct simplelock com_lock;
#endif /* USE_COMLOCK */
-#ifdef USE_CLOCKLOCK
-/* lock regions around the clock hardware */
-struct simplelock clock_lock;
-#endif /* USE_CLOCKLOCK */
-
/* lock around the MP rendezvous */
static struct simplelock smp_rv_lock;
@@ -1930,9 +1925,6 @@ init_locks(void)
#ifdef USE_COMLOCK
s_lock_init((struct simplelock*)&com_lock);
#endif /* USE_COMLOCK */
-#ifdef USE_CLOCKLOCK
- s_lock_init((struct simplelock*)&clock_lock);
-#endif /* USE_CLOCKLOCK */
s_lock_init(&ap_boot_lock);
}
@@ -2425,7 +2417,6 @@ ap_init(void)
* something unique to lock with.
*/
PCPU_SET(curproc,idleproc);
- PCPU_SET(prevproc,idleproc);
microuptime(&switchtime);
switchticks = ticks;
diff --git a/sys/amd64/amd64/swtch.s b/sys/amd64/amd64/swtch.s
index ac71f0c..32dbe56 100644
--- a/sys/amd64/amd64/swtch.s
+++ b/sys/amd64/amd64/swtch.s
@@ -82,7 +82,6 @@ ENTRY(cpu_switch)
/* switch to new process. first, save context as needed */
movl _curproc,%ecx
- movl %ecx,_prevproc
/* if no process to save, don't bother */
testl %ecx,%ecx
diff --git a/sys/amd64/amd64/trap.c b/sys/amd64/amd64/trap.c
index 1cbfcfa..b9ebb60 100644
--- a/sys/amd64/amd64/trap.c
+++ b/sys/amd64/amd64/trap.c
@@ -1244,6 +1244,18 @@ ast(frame)
addupc_task(p, p->p_stats->p_prof.pr_addr,
p->p_stats->p_prof.pr_ticks);
}
+ if (p->p_flag & P_ALRMPEND) {
+ if (!mtx_owned(&Giant))
+ mtx_enter(&Giant, MTX_DEF);
+ p->p_flag &= ~P_ALRMPEND;
+ psignal(p, SIGVTALRM);
+ }
+ if (p->p_flag & P_PROFPEND) {
+ if (!mtx_owned(&Giant))
+ mtx_enter(&Giant, MTX_DEF);
+ p->p_flag &= ~P_PROFPEND;
+ psignal(p, SIGPROF);
+ }
if (userret(p, &frame, sticks, mtx_owned(&Giant)) != 0)
mtx_exit(&Giant, MTX_DEF);
}
diff --git a/sys/amd64/amd64/tsc.c b/sys/amd64/amd64/tsc.c
index 0e630d9..a164288 100644
--- a/sys/amd64/amd64/tsc.c
+++ b/sys/amd64/amd64/tsc.c
@@ -72,6 +72,7 @@
#include <machine/ipl.h>
#include <machine/limits.h>
#include <machine/md_var.h>
+#include <machine/mutex.h>
#include <machine/psl.h>
#ifdef APIC_IO
#include <machine/segments.h>
@@ -139,6 +140,7 @@ int timer0_max_count;
u_int tsc_freq;
int tsc_is_broken;
int wall_cmos_clock; /* wall CMOS clock assumed if != 0 */
+struct mtx clock_lock;
static int beeping = 0;
static const u_char daysinmonth[] = {31,28,31,30,31,30,31,31,30,31,30,31};
@@ -198,12 +200,9 @@ SYSCTL_OPAQUE(_debug, OID_AUTO, i8254_timecounter, CTLFLAG_RD,
static void
clkintr(struct clockframe frame)
{
- int intrsave;
if (timecounter->tc_get_timecount == i8254_get_timecount) {
- intrsave = save_intr();
- disable_intr();
- CLOCK_LOCK();
+ mtx_enter(&clock_lock, MTX_SPIN);
if (i8254_ticked)
i8254_ticked = 0;
else {
@@ -211,8 +210,7 @@ clkintr(struct clockframe frame)
i8254_lastcount = 0;
}
clkintr_pending = 0;
- CLOCK_UNLOCK();
- restore_intr(intrsave);
+ mtx_exit(&clock_lock, MTX_SPIN);
}
timer_func(&frame);
switch (timer0_state) {
@@ -231,17 +229,14 @@ clkintr(struct clockframe frame)
break;
case ACQUIRE_PENDING:
- intrsave = save_intr();
- disable_intr();
- CLOCK_LOCK();
+ mtx_enter(&clock_lock, MTX_SPIN);
i8254_offset = i8254_get_timecount(NULL);
i8254_lastcount = 0;
timer0_max_count = TIMER_DIV(new_rate);
outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT);
outb(TIMER_CNTR0, timer0_max_count & 0xff);
outb(TIMER_CNTR0, timer0_max_count >> 8);
- CLOCK_UNLOCK();
- restore_intr(intrsave);
+ mtx_exit(&clock_lock, MTX_SPIN);
timer_func = new_function;
timer0_state = ACQUIRED;
setdelayed();
@@ -250,9 +245,7 @@ clkintr(struct clockframe frame)
case RELEASE_PENDING:
if ((timer0_prescaler_count += timer0_max_count)
>= hardclock_max_count) {
- intrsave = save_intr();
- disable_intr();
- CLOCK_LOCK();
+ mtx_enter(&clock_lock, MTX_SPIN);
i8254_offset = i8254_get_timecount(NULL);
i8254_lastcount = 0;
timer0_max_count = hardclock_max_count;
@@ -260,8 +253,7 @@ clkintr(struct clockframe frame)
TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT);
outb(TIMER_CNTR0, timer0_max_count & 0xff);
outb(TIMER_CNTR0, timer0_max_count >> 8);
- CLOCK_UNLOCK();
- restore_intr(intrsave);
+ mtx_exit(&clock_lock, MTX_SPIN);
timer0_prescaler_count = 0;
timer_func = hardclock;
timer0_state = RELEASED;
@@ -408,11 +400,9 @@ DB_SHOW_COMMAND(rtc, rtc)
static int
getit(void)
{
- int high, low, intrsave;
+ int high, low;
- intrsave = save_intr();
- disable_intr();
- CLOCK_LOCK();
+ mtx_enter(&clock_lock, MTX_SPIN);
/* Select timer0 and latch counter value. */
outb(TIMER_MODE, TIMER_SEL0 | TIMER_LATCH);
@@ -420,8 +410,7 @@ getit(void)
low = inb(TIMER_CNTR0);
high = inb(TIMER_CNTR0);
- CLOCK_UNLOCK();
- restore_intr(intrsave);
+ mtx_exit(&clock_lock, MTX_SPIN);
return ((high << 8) | low);
}
@@ -527,7 +516,6 @@ sysbeepstop(void *chan)
int
sysbeep(int pitch, int period)
{
- int intrsave;
int x = splclock();
if (acquire_timer2(TIMER_SQWAVE|TIMER_16BIT))
@@ -536,13 +524,10 @@ sysbeep(int pitch, int period)
splx(x);
return (-1); /* XXX Should be EBUSY, but nobody cares anyway. */
}
- intrsave = save_intr();
- disable_intr();
- CLOCK_LOCK();
+ mtx_enter(&clock_lock, MTX_SPIN);
outb(TIMER_CNTR2, pitch);
outb(TIMER_CNTR2, (pitch>>8));
- CLOCK_UNLOCK();
- restore_intr(intrsave);
+ mtx_exit(&clock_lock, MTX_SPIN);
if (!beeping) {
/* enable counter2 output to speaker */
outb(IO_PPI, inb(IO_PPI) | 3);
@@ -691,12 +676,9 @@ fail:
static void
set_timer_freq(u_int freq, int intr_freq)
{
- int intrsave;
int new_timer0_max_count;
- intrsave = save_intr();
- disable_intr();
- CLOCK_LOCK();
+ mtx_enter(&clock_lock, MTX_SPIN);
timer_freq = freq;
new_timer0_max_count = hardclock_max_count = TIMER_DIV(intr_freq);
if (new_timer0_max_count != timer0_max_count) {
@@ -705,8 +687,7 @@ set_timer_freq(u_int freq, int intr_freq)
outb(TIMER_CNTR0, timer0_max_count & 0xff);
outb(TIMER_CNTR0, timer0_max_count >> 8);
}
- CLOCK_UNLOCK();
- restore_intr(intrsave);
+ mtx_exit(&clock_lock, MTX_SPIN);
}
/*
@@ -720,16 +701,12 @@ set_timer_freq(u_int freq, int intr_freq)
void
i8254_restore(void)
{
- int intrsave;
- intrsave = save_intr();
- disable_intr();
- CLOCK_LOCK();
+ mtx_enter(&clock_lock, MTX_SPIN);
outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT);
outb(TIMER_CNTR0, timer0_max_count & 0xff);
outb(TIMER_CNTR0, timer0_max_count >> 8);
- CLOCK_UNLOCK();
- restore_intr(intrsave);
+ mtx_exit(&clock_lock, MTX_SPIN);
}
/*
@@ -989,8 +966,8 @@ cpu_initclocks()
{
int diag;
#ifdef APIC_IO
- int apic_8254_trial, num_8254_ticks;
- struct intrec *clkdesc, *rtcdesc;
+ int apic_8254_trial;
+ struct intrec *clkdesc;
#endif /* APIC_IO */
if (statclock_disable) {
@@ -1023,6 +1000,11 @@ cpu_initclocks()
} else
panic("APIC_IO: Cannot route 8254 interrupt to CPU");
}
+
+ clkdesc = inthand_add("clk", apic_8254_intr, (driver_intr_t *)clkintr,
+ NULL, PI_REALTIME, INTR_FAST);
+ INTREN(1 << apic_8254_intr);
+
#else /* APIC_IO */
/*
@@ -1030,9 +1012,8 @@ cpu_initclocks()
* couldn't find anything suitable in the BSD/OS code (grog,
* 19 July 2000).
*/
- /* Setup the PIC clk handler. The APIC handler is setup later */
inthand_add("clk", 0, (driver_intr_t *)clkintr, NULL, PI_REALTIME,
- INTR_EXCL);
+ INTR_FAST);
INTREN(IRQ0);
#endif /* APIC_IO */
@@ -1042,18 +1023,8 @@ cpu_initclocks()
writertc(RTC_STATUSB, RTCSB_24HR);
/* Don't bother enabling the statistics clock. */
- if (statclock_disable) {
-#ifdef APIC_IO
- /*
- * XXX - if statclock is disabled, don't attempt the APIC
- * trial. Not sure this is sane for APIC_IO.
- */
- inthand_add("clk", apic_8254_intr, (driver_intr_t *)clkintr,
- NULL, PI_REALTIME, INTR_EXCL);
- INTREN(1 << apic_8254_intr);
-#endif /* APIC_IO */
+ if (statclock_disable)
return;
- }
diag = rtcin(RTC_DIAG);
if (diag != 0)
printf("RTC BIOS diagnostic error %b\n", diag, RTCDG_BITS);
@@ -1061,44 +1032,34 @@ cpu_initclocks()
#ifdef APIC_IO
if (isa_apic_irq(8) != 8)
panic("APIC RTC != 8");
+#endif /* APIC_IO */
- if (apic_8254_trial) {
- /*
- * XXX - We use fast interrupts for clk and rtc long enough to
- * perform the APIC probe and then revert to exclusive
- * interrupts.
- */
- clkdesc = inthand_add("clk", apic_8254_intr,
- (driver_intr_t *)clkintr, NULL, PI_REALTIME, INTR_FAST);
- INTREN(1 << apic_8254_intr);
+ inthand_add("rtc", 8, (driver_intr_t *)rtcintr, NULL, PI_REALTIME,
+ INTR_FAST);
- rtcdesc = inthand_add("rtc", 8, (driver_intr_t *)rtcintr, NULL,
- PI_REALTIME, INTR_FAST); /* XXX */
- INTREN(APIC_IRQ8);
- writertc(RTC_STATUSB, rtc_statusb);
+#ifdef APIC_IO
+ INTREN(APIC_IRQ8);
+#else
+ INTREN(IRQ8);
+#endif /* APIC_IO */
+
+ writertc(RTC_STATUSB, rtc_statusb);
+
+#ifdef APIC_IO
+ if (apic_8254_trial) {
printf("APIC_IO: Testing 8254 interrupt delivery\n");
while (read_intr_count(8) < 6)
; /* nothing */
- num_8254_ticks = read_intr_count(apic_8254_intr);
-
- /* disable and remove our fake handlers */
- INTRDIS(1 << apic_8254_intr);
- inthand_remove(clkdesc);
-
- writertc(RTC_STATUSA, rtc_statusa);
- writertc(RTC_STATUSB, RTCSB_24HR);
-
- INTRDIS(APIC_IRQ8);
- inthand_remove(rtcdesc);
-
- if (num_8254_ticks < 3) {
+ if (read_intr_count(apic_8254_intr) < 3) {
/*
* The MP table is broken.
* The 8254 was not connected to the specified pin
* on the IO APIC.
* Workaround: Limited variant of mixed mode.
*/
+ INTRDIS(1 << apic_8254_intr);
+ inthand_remove(clkdesc);
printf("APIC_IO: Broken MP table detected: "
"8254 is not connected to "
"IOAPIC #%d intpin %d\n",
@@ -1117,27 +1078,13 @@ cpu_initclocks()
}
apic_8254_intr = apic_irq(0, 0);
setup_8254_mixed_mode();
+ inthand_add("clk", apic_8254_intr,
+ (driver_intr_t *)clkintr, NULL,
+ PI_REALTIME, INTR_FAST);
+ INTREN(1 << apic_8254_intr);
}
}
-
- /* Finally, setup the real clock handlers */
- inthand_add("clk", apic_8254_intr, (driver_intr_t *)clkintr, NULL,
- PI_REALTIME, INTR_EXCL);
- INTREN(1 << apic_8254_intr);
-#endif
-
- inthand_add("rtc", 8, (driver_intr_t *)rtcintr, NULL, PI_REALTIME,
- INTR_EXCL);
-#ifdef APIC_IO
- INTREN(APIC_IRQ8);
-#else
- INTREN(IRQ8);
-#endif
-
- writertc(RTC_STATUSB, rtc_statusb);
-
-#ifdef APIC_IO
if (apic_int_type(0, 0) != 3 ||
int_to_apicintpin[apic_8254_intr].ioapic != 0 ||
int_to_apicintpin[apic_8254_intr].int_pin != 0)
@@ -1242,12 +1189,11 @@ static unsigned
i8254_get_timecount(struct timecounter *tc)
{
u_int count;
- int intrsave;
u_int high, low;
+ u_int eflags;
- intrsave = save_intr();
- disable_intr();
- CLOCK_LOCK();
+ eflags = read_eflags();
+ mtx_enter(&clock_lock, MTX_SPIN);
/* Select timer0 and latch counter value. */
outb(TIMER_MODE, TIMER_SEL0 | TIMER_LATCH);
@@ -1257,7 +1203,7 @@ i8254_get_timecount(struct timecounter *tc)
count = timer0_max_count - ((high << 8) | low);
if (count < i8254_lastcount ||
(!i8254_ticked && (clkintr_pending ||
- ((count < 20 || (!(intrsave & PSL_I) && count < timer0_max_count / 2u)) &&
+ ((count < 20 || (!(eflags & PSL_I) && count < timer0_max_count / 2u)) &&
#ifdef APIC_IO
#define lapic_irr1 ((volatile u_int *)&lapic)[0x210 / 4] /* XXX XXX */
/* XXX this assumes that apic_8254_intr is < 24. */
@@ -1271,8 +1217,7 @@ i8254_get_timecount(struct timecounter *tc)
}
i8254_lastcount = count;
count += i8254_offset;
- CLOCK_UNLOCK();
- restore_intr(intrsave);
+ mtx_exit(&clock_lock, MTX_SPIN);
return (count);
}
diff --git a/sys/amd64/include/cpu.h b/sys/amd64/include/cpu.h
index 18822b8..d35b940 100644
--- a/sys/amd64/include/cpu.h
+++ b/sys/amd64/include/cpu.h
@@ -62,21 +62,6 @@
((ISPL((framep)->cf_cs) == SEL_UPL) || (framep->cf_eflags & PSL_VM))
#define CLKF_INTR(framep) (intr_nesting_level >= 2)
-#if 0
-/*
- * XXX splsoftclock() is very broken and barely worth fixing. It doesn't
- * turn off the clock bit in imen or in the icu. (This is not a serious
- * problem at 100 Hz but it is serious at 16000 Hz for pcaudio. softclock()
- * can take more than 62.5 usec so clock interrupts are lost.) It doesn't
- * check for pending interrupts being unmasked. clkintr() and Xintr0()
- * assume that the ipl is high when hardclock() returns. Our SWI_CLOCK
- * handling is efficient enough that little is gained by calling
- * softclock() directly.
- */
-#define CLKF_BASEPRI(framep) ((framep)->cf_ppl == 0)
-#else
-#define CLKF_BASEPRI(framep) (0)
-#endif
#define CLKF_PC(framep) ((framep)->cf_eip)
/*
diff --git a/sys/amd64/include/mptable.h b/sys/amd64/include/mptable.h
index ea9aee8..5ef95b3 100644
--- a/sys/amd64/include/mptable.h
+++ b/sys/amd64/include/mptable.h
@@ -1900,11 +1900,6 @@ struct simplelock mcount_lock;
struct simplelock com_lock;
#endif /* USE_COMLOCK */
-#ifdef USE_CLOCKLOCK
-/* lock regions around the clock hardware */
-struct simplelock clock_lock;
-#endif /* USE_CLOCKLOCK */
-
/* lock around the MP rendezvous */
static struct simplelock smp_rv_lock;
@@ -1930,9 +1925,6 @@ init_locks(void)
#ifdef USE_COMLOCK
s_lock_init((struct simplelock*)&com_lock);
#endif /* USE_COMLOCK */
-#ifdef USE_CLOCKLOCK
- s_lock_init((struct simplelock*)&clock_lock);
-#endif /* USE_CLOCKLOCK */
s_lock_init(&ap_boot_lock);
}
@@ -2425,7 +2417,6 @@ ap_init(void)
* something unique to lock with.
*/
PCPU_SET(curproc,idleproc);
- PCPU_SET(prevproc,idleproc);
microuptime(&switchtime);
switchticks = ticks;
diff --git a/sys/amd64/include/mutex.h b/sys/amd64/include/mutex.h
index ca518d9..881cbfa 100644
--- a/sys/amd64/include/mutex.h
+++ b/sys/amd64/include/mutex.h
@@ -146,6 +146,7 @@ void _mtx_exit(struct mtx *mtxp, int type, const char *file, int line);
/* Global locks */
extern struct mtx sched_lock;
extern struct mtx Giant;
+extern struct mtx clock_lock;
/*
* Used to replace return with an exit Giant and return.
diff --git a/sys/amd64/include/pcpu.h b/sys/amd64/include/pcpu.h
index ace3602..2788499 100644
--- a/sys/amd64/include/pcpu.h
+++ b/sys/amd64/include/pcpu.h
@@ -55,7 +55,6 @@
struct globaldata {
struct privatespace *gd_prvspace; /* self-reference */
struct proc *gd_curproc;
- struct proc *gd_prevproc;
struct proc *gd_npxproc;
struct pcb *gd_curpcb;
struct proc *gd_idleproc;
diff --git a/sys/amd64/isa/atpic_vector.S b/sys/amd64/isa/atpic_vector.S
index 0a89492..7644c03 100644
--- a/sys/amd64/isa/atpic_vector.S
+++ b/sys/amd64/isa/atpic_vector.S
@@ -49,17 +49,18 @@
.text ; \
SUPERALIGN_TEXT ; \
IDTVEC(vec_name) ; \
- pushl %eax ; /* save only call-used registers */ \
- pushl %ecx ; \
- pushl %edx ; \
+ pushl $0 ; /* dummy error code */ \
+ pushl $0 ; /* dummy trap type */ \
+ pushal ; \
pushl %ds ; \
+ pushl %es ; \
pushl %fs ; \
- MAYBE_PUSHL_ES ; \
mov $KDSEL,%ax ; \
mov %ax,%ds ; \
+ mov %ax,%es ; \
mov %ax,%fs ; \
- MAYBE_MOVW_AX_ES ; \
- FAKE_MCOUNT((4+ACTUALLY_PUSHED)*4(%esp)) ; \
+ FAKE_MCOUNT((12+ACTUALLY_PUSHED)*4(%esp)) ; \
+ incb _intr_nesting_level ; \
pushl _intr_unit + (irq_num) * 4 ; \
call *_intr_handler + (irq_num) * 4 ; /* do the work ASAP */ \
enable_icus ; /* (re)enable ASAP (helps edge trigger?) */ \
@@ -67,19 +68,8 @@ IDTVEC(vec_name) ; \
incl _cnt+V_INTR ; /* book-keeping can wait */ \
movl _intr_countp + (irq_num) * 4,%eax ; \
incl (%eax) ; \
-/* movl _cpl,%eax ; // are we unmasking pending SWIs? / \
- notl %eax ; \
- andl _spending,$SWI_MASK ; \
- jne 2f ; // yes, maybe handle them */ \
-1: ; \
MEXITCOUNT ; \
- MAYBE_POPL_ES ; \
- popl %fs ; \
- popl %ds ; \
- popl %edx ; \
- popl %ecx ; \
- popl %eax ; \
- iret ; \
+ jmp doreti_next
#if 0
; \
@@ -141,7 +131,7 @@ IDTVEC(vec_name) ; \
movb %al,_imen + IRQ_BYTE(irq_num) ; \
outb %al,$icu+ICU_IMR_OFFSET ; \
enable_icus ; \
- incb _intr_nesting_level ; /* XXX do we need this? */ \
+ incb _intr_nesting_level ; \
__CONCAT(Xresume,irq_num): ; \
FAKE_MCOUNT(13*4(%esp)) ; /* XXX late to avoid double count */ \
pushl $irq_num; /* pass the IRQ */ \
@@ -153,26 +143,6 @@ __CONCAT(Xresume,irq_num): ; \
/* _doreti, but it's probably better to use less cache. */ \
jmp doreti_next /* and catch up inside doreti */
-/*
- * Reenable the interrupt mask after completing an interrupt. Called
- * from ithd_loop. There are two separate functions, one for each
- * ICU.
- */
- .globl setimask0, setimask1
-setimask0:
- cli
- movb _imen,%al
- outb %al,$IO_ICU1 + ICU_IMR_OFFSET
- sti
- ret
-
-setimask1:
- cli
- movb _imen + 1,%al
- outb %al,$IO_ICU2 + ICU_IMR_OFFSET
- sti
- ret
-
MCOUNT_LABEL(bintr)
FAST_INTR(0,fastintr0, ENABLE_ICU1)
FAST_INTR(1,fastintr1, ENABLE_ICU1)
diff --git a/sys/amd64/isa/clock.c b/sys/amd64/isa/clock.c
index 0e630d9..a164288 100644
--- a/sys/amd64/isa/clock.c
+++ b/sys/amd64/isa/clock.c
@@ -72,6 +72,7 @@
#include <machine/ipl.h>
#include <machine/limits.h>
#include <machine/md_var.h>
+#include <machine/mutex.h>
#include <machine/psl.h>
#ifdef APIC_IO
#include <machine/segments.h>
@@ -139,6 +140,7 @@ int timer0_max_count;
u_int tsc_freq;
int tsc_is_broken;
int wall_cmos_clock; /* wall CMOS clock assumed if != 0 */
+struct mtx clock_lock;
static int beeping = 0;
static const u_char daysinmonth[] = {31,28,31,30,31,30,31,31,30,31,30,31};
@@ -198,12 +200,9 @@ SYSCTL_OPAQUE(_debug, OID_AUTO, i8254_timecounter, CTLFLAG_RD,
static void
clkintr(struct clockframe frame)
{
- int intrsave;
if (timecounter->tc_get_timecount == i8254_get_timecount) {
- intrsave = save_intr();
- disable_intr();
- CLOCK_LOCK();
+ mtx_enter(&clock_lock, MTX_SPIN);
if (i8254_ticked)
i8254_ticked = 0;
else {
@@ -211,8 +210,7 @@ clkintr(struct clockframe frame)
i8254_lastcount = 0;
}
clkintr_pending = 0;
- CLOCK_UNLOCK();
- restore_intr(intrsave);
+ mtx_exit(&clock_lock, MTX_SPIN);
}
timer_func(&frame);
switch (timer0_state) {
@@ -231,17 +229,14 @@ clkintr(struct clockframe frame)
break;
case ACQUIRE_PENDING:
- intrsave = save_intr();
- disable_intr();
- CLOCK_LOCK();
+ mtx_enter(&clock_lock, MTX_SPIN);
i8254_offset = i8254_get_timecount(NULL);
i8254_lastcount = 0;
timer0_max_count = TIMER_DIV(new_rate);
outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT);
outb(TIMER_CNTR0, timer0_max_count & 0xff);
outb(TIMER_CNTR0, timer0_max_count >> 8);
- CLOCK_UNLOCK();
- restore_intr(intrsave);
+ mtx_exit(&clock_lock, MTX_SPIN);
timer_func = new_function;
timer0_state = ACQUIRED;
setdelayed();
@@ -250,9 +245,7 @@ clkintr(struct clockframe frame)
case RELEASE_PENDING:
if ((timer0_prescaler_count += timer0_max_count)
>= hardclock_max_count) {
- intrsave = save_intr();
- disable_intr();
- CLOCK_LOCK();
+ mtx_enter(&clock_lock, MTX_SPIN);
i8254_offset = i8254_get_timecount(NULL);
i8254_lastcount = 0;
timer0_max_count = hardclock_max_count;
@@ -260,8 +253,7 @@ clkintr(struct clockframe frame)
TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT);
outb(TIMER_CNTR0, timer0_max_count & 0xff);
outb(TIMER_CNTR0, timer0_max_count >> 8);
- CLOCK_UNLOCK();
- restore_intr(intrsave);
+ mtx_exit(&clock_lock, MTX_SPIN);
timer0_prescaler_count = 0;
timer_func = hardclock;
timer0_state = RELEASED;
@@ -408,11 +400,9 @@ DB_SHOW_COMMAND(rtc, rtc)
static int
getit(void)
{
- int high, low, intrsave;
+ int high, low;
- intrsave = save_intr();
- disable_intr();
- CLOCK_LOCK();
+ mtx_enter(&clock_lock, MTX_SPIN);
/* Select timer0 and latch counter value. */
outb(TIMER_MODE, TIMER_SEL0 | TIMER_LATCH);
@@ -420,8 +410,7 @@ getit(void)
low = inb(TIMER_CNTR0);
high = inb(TIMER_CNTR0);
- CLOCK_UNLOCK();
- restore_intr(intrsave);
+ mtx_exit(&clock_lock, MTX_SPIN);
return ((high << 8) | low);
}
@@ -527,7 +516,6 @@ sysbeepstop(void *chan)
int
sysbeep(int pitch, int period)
{
- int intrsave;
int x = splclock();
if (acquire_timer2(TIMER_SQWAVE|TIMER_16BIT))
@@ -536,13 +524,10 @@ sysbeep(int pitch, int period)
splx(x);
return (-1); /* XXX Should be EBUSY, but nobody cares anyway. */
}
- intrsave = save_intr();
- disable_intr();
- CLOCK_LOCK();
+ mtx_enter(&clock_lock, MTX_SPIN);
outb(TIMER_CNTR2, pitch);
outb(TIMER_CNTR2, (pitch>>8));
- CLOCK_UNLOCK();
- restore_intr(intrsave);
+ mtx_exit(&clock_lock, MTX_SPIN);
if (!beeping) {
/* enable counter2 output to speaker */
outb(IO_PPI, inb(IO_PPI) | 3);
@@ -691,12 +676,9 @@ fail:
static void
set_timer_freq(u_int freq, int intr_freq)
{
- int intrsave;
int new_timer0_max_count;
- intrsave = save_intr();
- disable_intr();
- CLOCK_LOCK();
+ mtx_enter(&clock_lock, MTX_SPIN);
timer_freq = freq;
new_timer0_max_count = hardclock_max_count = TIMER_DIV(intr_freq);
if (new_timer0_max_count != timer0_max_count) {
@@ -705,8 +687,7 @@ set_timer_freq(u_int freq, int intr_freq)
outb(TIMER_CNTR0, timer0_max_count & 0xff);
outb(TIMER_CNTR0, timer0_max_count >> 8);
}
- CLOCK_UNLOCK();
- restore_intr(intrsave);
+ mtx_exit(&clock_lock, MTX_SPIN);
}
/*
@@ -720,16 +701,12 @@ set_timer_freq(u_int freq, int intr_freq)
void
i8254_restore(void)
{
- int intrsave;
- intrsave = save_intr();
- disable_intr();
- CLOCK_LOCK();
+ mtx_enter(&clock_lock, MTX_SPIN);
outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT);
outb(TIMER_CNTR0, timer0_max_count & 0xff);
outb(TIMER_CNTR0, timer0_max_count >> 8);
- CLOCK_UNLOCK();
- restore_intr(intrsave);
+ mtx_exit(&clock_lock, MTX_SPIN);
}
/*
@@ -989,8 +966,8 @@ cpu_initclocks()
{
int diag;
#ifdef APIC_IO
- int apic_8254_trial, num_8254_ticks;
- struct intrec *clkdesc, *rtcdesc;
+ int apic_8254_trial;
+ struct intrec *clkdesc;
#endif /* APIC_IO */
if (statclock_disable) {
@@ -1023,6 +1000,11 @@ cpu_initclocks()
} else
panic("APIC_IO: Cannot route 8254 interrupt to CPU");
}
+
+ clkdesc = inthand_add("clk", apic_8254_intr, (driver_intr_t *)clkintr,
+ NULL, PI_REALTIME, INTR_FAST);
+ INTREN(1 << apic_8254_intr);
+
#else /* APIC_IO */
/*
@@ -1030,9 +1012,8 @@ cpu_initclocks()
* couldn't find anything suitable in the BSD/OS code (grog,
* 19 July 2000).
*/
- /* Setup the PIC clk handler. The APIC handler is setup later */
inthand_add("clk", 0, (driver_intr_t *)clkintr, NULL, PI_REALTIME,
- INTR_EXCL);
+ INTR_FAST);
INTREN(IRQ0);
#endif /* APIC_IO */
@@ -1042,18 +1023,8 @@ cpu_initclocks()
writertc(RTC_STATUSB, RTCSB_24HR);
/* Don't bother enabling the statistics clock. */
- if (statclock_disable) {
-#ifdef APIC_IO
- /*
- * XXX - if statclock is disabled, don't attempt the APIC
- * trial. Not sure this is sane for APIC_IO.
- */
- inthand_add("clk", apic_8254_intr, (driver_intr_t *)clkintr,
- NULL, PI_REALTIME, INTR_EXCL);
- INTREN(1 << apic_8254_intr);
-#endif /* APIC_IO */
+ if (statclock_disable)
return;
- }
diag = rtcin(RTC_DIAG);
if (diag != 0)
printf("RTC BIOS diagnostic error %b\n", diag, RTCDG_BITS);
@@ -1061,44 +1032,34 @@ cpu_initclocks()
#ifdef APIC_IO
if (isa_apic_irq(8) != 8)
panic("APIC RTC != 8");
+#endif /* APIC_IO */
- if (apic_8254_trial) {
- /*
- * XXX - We use fast interrupts for clk and rtc long enough to
- * perform the APIC probe and then revert to exclusive
- * interrupts.
- */
- clkdesc = inthand_add("clk", apic_8254_intr,
- (driver_intr_t *)clkintr, NULL, PI_REALTIME, INTR_FAST);
- INTREN(1 << apic_8254_intr);
+ inthand_add("rtc", 8, (driver_intr_t *)rtcintr, NULL, PI_REALTIME,
+ INTR_FAST);
- rtcdesc = inthand_add("rtc", 8, (driver_intr_t *)rtcintr, NULL,
- PI_REALTIME, INTR_FAST); /* XXX */
- INTREN(APIC_IRQ8);
- writertc(RTC_STATUSB, rtc_statusb);
+#ifdef APIC_IO
+ INTREN(APIC_IRQ8);
+#else
+ INTREN(IRQ8);
+#endif /* APIC_IO */
+
+ writertc(RTC_STATUSB, rtc_statusb);
+
+#ifdef APIC_IO
+ if (apic_8254_trial) {
printf("APIC_IO: Testing 8254 interrupt delivery\n");
while (read_intr_count(8) < 6)
; /* nothing */
- num_8254_ticks = read_intr_count(apic_8254_intr);
-
- /* disable and remove our fake handlers */
- INTRDIS(1 << apic_8254_intr);
- inthand_remove(clkdesc);
-
- writertc(RTC_STATUSA, rtc_statusa);
- writertc(RTC_STATUSB, RTCSB_24HR);
-
- INTRDIS(APIC_IRQ8);
- inthand_remove(rtcdesc);
-
- if (num_8254_ticks < 3) {
+ if (read_intr_count(apic_8254_intr) < 3) {
/*
* The MP table is broken.
* The 8254 was not connected to the specified pin
* on the IO APIC.
* Workaround: Limited variant of mixed mode.
*/
+ INTRDIS(1 << apic_8254_intr);
+ inthand_remove(clkdesc);
printf("APIC_IO: Broken MP table detected: "
"8254 is not connected to "
"IOAPIC #%d intpin %d\n",
@@ -1117,27 +1078,13 @@ cpu_initclocks()
}
apic_8254_intr = apic_irq(0, 0);
setup_8254_mixed_mode();
+ inthand_add("clk", apic_8254_intr,
+ (driver_intr_t *)clkintr, NULL,
+ PI_REALTIME, INTR_FAST);
+ INTREN(1 << apic_8254_intr);
}
}
-
- /* Finally, setup the real clock handlers */
- inthand_add("clk", apic_8254_intr, (driver_intr_t *)clkintr, NULL,
- PI_REALTIME, INTR_EXCL);
- INTREN(1 << apic_8254_intr);
-#endif
-
- inthand_add("rtc", 8, (driver_intr_t *)rtcintr, NULL, PI_REALTIME,
- INTR_EXCL);
-#ifdef APIC_IO
- INTREN(APIC_IRQ8);
-#else
- INTREN(IRQ8);
-#endif
-
- writertc(RTC_STATUSB, rtc_statusb);
-
-#ifdef APIC_IO
if (apic_int_type(0, 0) != 3 ||
int_to_apicintpin[apic_8254_intr].ioapic != 0 ||
int_to_apicintpin[apic_8254_intr].int_pin != 0)
@@ -1242,12 +1189,11 @@ static unsigned
i8254_get_timecount(struct timecounter *tc)
{
u_int count;
- int intrsave;
u_int high, low;
+ u_int eflags;
- intrsave = save_intr();
- disable_intr();
- CLOCK_LOCK();
+ eflags = read_eflags();
+ mtx_enter(&clock_lock, MTX_SPIN);
/* Select timer0 and latch counter value. */
outb(TIMER_MODE, TIMER_SEL0 | TIMER_LATCH);
@@ -1257,7 +1203,7 @@ i8254_get_timecount(struct timecounter *tc)
count = timer0_max_count - ((high << 8) | low);
if (count < i8254_lastcount ||
(!i8254_ticked && (clkintr_pending ||
- ((count < 20 || (!(intrsave & PSL_I) && count < timer0_max_count / 2u)) &&
+ ((count < 20 || (!(eflags & PSL_I) && count < timer0_max_count / 2u)) &&
#ifdef APIC_IO
#define lapic_irr1 ((volatile u_int *)&lapic)[0x210 / 4] /* XXX XXX */
/* XXX this assumes that apic_8254_intr is < 24. */
@@ -1271,8 +1217,7 @@ i8254_get_timecount(struct timecounter *tc)
}
i8254_lastcount = count;
count += i8254_offset;
- CLOCK_UNLOCK();
- restore_intr(intrsave);
+ mtx_exit(&clock_lock, MTX_SPIN);
return (count);
}
diff --git a/sys/amd64/isa/icu_vector.S b/sys/amd64/isa/icu_vector.S
index 0a89492..7644c03 100644
--- a/sys/amd64/isa/icu_vector.S
+++ b/sys/amd64/isa/icu_vector.S
@@ -49,17 +49,18 @@
.text ; \
SUPERALIGN_TEXT ; \
IDTVEC(vec_name) ; \
- pushl %eax ; /* save only call-used registers */ \
- pushl %ecx ; \
- pushl %edx ; \
+ pushl $0 ; /* dummy error code */ \
+ pushl $0 ; /* dummy trap type */ \
+ pushal ; \
pushl %ds ; \
+ pushl %es ; \
pushl %fs ; \
- MAYBE_PUSHL_ES ; \
mov $KDSEL,%ax ; \
mov %ax,%ds ; \
+ mov %ax,%es ; \
mov %ax,%fs ; \
- MAYBE_MOVW_AX_ES ; \
- FAKE_MCOUNT((4+ACTUALLY_PUSHED)*4(%esp)) ; \
+ FAKE_MCOUNT((12+ACTUALLY_PUSHED)*4(%esp)) ; \
+ incb _intr_nesting_level ; \
pushl _intr_unit + (irq_num) * 4 ; \
call *_intr_handler + (irq_num) * 4 ; /* do the work ASAP */ \
enable_icus ; /* (re)enable ASAP (helps edge trigger?) */ \
@@ -67,19 +68,8 @@ IDTVEC(vec_name) ; \
incl _cnt+V_INTR ; /* book-keeping can wait */ \
movl _intr_countp + (irq_num) * 4,%eax ; \
incl (%eax) ; \
-/* movl _cpl,%eax ; // are we unmasking pending SWIs? / \
- notl %eax ; \
- andl _spending,$SWI_MASK ; \
- jne 2f ; // yes, maybe handle them */ \
-1: ; \
MEXITCOUNT ; \
- MAYBE_POPL_ES ; \
- popl %fs ; \
- popl %ds ; \
- popl %edx ; \
- popl %ecx ; \
- popl %eax ; \
- iret ; \
+ jmp doreti_next
#if 0
; \
@@ -141,7 +131,7 @@ IDTVEC(vec_name) ; \
movb %al,_imen + IRQ_BYTE(irq_num) ; \
outb %al,$icu+ICU_IMR_OFFSET ; \
enable_icus ; \
- incb _intr_nesting_level ; /* XXX do we need this? */ \
+ incb _intr_nesting_level ; \
__CONCAT(Xresume,irq_num): ; \
FAKE_MCOUNT(13*4(%esp)) ; /* XXX late to avoid double count */ \
pushl $irq_num; /* pass the IRQ */ \
@@ -153,26 +143,6 @@ __CONCAT(Xresume,irq_num): ; \
/* _doreti, but it's probably better to use less cache. */ \
jmp doreti_next /* and catch up inside doreti */
-/*
- * Reenable the interrupt mask after completing an interrupt. Called
- * from ithd_loop. There are two separate functions, one for each
- * ICU.
- */
- .globl setimask0, setimask1
-setimask0:
- cli
- movb _imen,%al
- outb %al,$IO_ICU1 + ICU_IMR_OFFSET
- sti
- ret
-
-setimask1:
- cli
- movb _imen + 1,%al
- outb %al,$IO_ICU2 + ICU_IMR_OFFSET
- sti
- ret
-
MCOUNT_LABEL(bintr)
FAST_INTR(0,fastintr0, ENABLE_ICU1)
FAST_INTR(1,fastintr1, ENABLE_ICU1)
diff --git a/sys/amd64/isa/icu_vector.s b/sys/amd64/isa/icu_vector.s
index 0a89492..7644c03 100644
--- a/sys/amd64/isa/icu_vector.s
+++ b/sys/amd64/isa/icu_vector.s
@@ -49,17 +49,18 @@
.text ; \
SUPERALIGN_TEXT ; \
IDTVEC(vec_name) ; \
- pushl %eax ; /* save only call-used registers */ \
- pushl %ecx ; \
- pushl %edx ; \
+ pushl $0 ; /* dummy error code */ \
+ pushl $0 ; /* dummy trap type */ \
+ pushal ; \
pushl %ds ; \
+ pushl %es ; \
pushl %fs ; \
- MAYBE_PUSHL_ES ; \
mov $KDSEL,%ax ; \
mov %ax,%ds ; \
+ mov %ax,%es ; \
mov %ax,%fs ; \
- MAYBE_MOVW_AX_ES ; \
- FAKE_MCOUNT((4+ACTUALLY_PUSHED)*4(%esp)) ; \
+ FAKE_MCOUNT((12+ACTUALLY_PUSHED)*4(%esp)) ; \
+ incb _intr_nesting_level ; \
pushl _intr_unit + (irq_num) * 4 ; \
call *_intr_handler + (irq_num) * 4 ; /* do the work ASAP */ \
enable_icus ; /* (re)enable ASAP (helps edge trigger?) */ \
@@ -67,19 +68,8 @@ IDTVEC(vec_name) ; \
incl _cnt+V_INTR ; /* book-keeping can wait */ \
movl _intr_countp + (irq_num) * 4,%eax ; \
incl (%eax) ; \
-/* movl _cpl,%eax ; // are we unmasking pending SWIs? / \
- notl %eax ; \
- andl _spending,$SWI_MASK ; \
- jne 2f ; // yes, maybe handle them */ \
-1: ; \
MEXITCOUNT ; \
- MAYBE_POPL_ES ; \
- popl %fs ; \
- popl %ds ; \
- popl %edx ; \
- popl %ecx ; \
- popl %eax ; \
- iret ; \
+ jmp doreti_next
#if 0
; \
@@ -141,7 +131,7 @@ IDTVEC(vec_name) ; \
movb %al,_imen + IRQ_BYTE(irq_num) ; \
outb %al,$icu+ICU_IMR_OFFSET ; \
enable_icus ; \
- incb _intr_nesting_level ; /* XXX do we need this? */ \
+ incb _intr_nesting_level ; \
__CONCAT(Xresume,irq_num): ; \
FAKE_MCOUNT(13*4(%esp)) ; /* XXX late to avoid double count */ \
pushl $irq_num; /* pass the IRQ */ \
@@ -153,26 +143,6 @@ __CONCAT(Xresume,irq_num): ; \
/* _doreti, but it's probably better to use less cache. */ \
jmp doreti_next /* and catch up inside doreti */
-/*
- * Reenable the interrupt mask after completing an interrupt. Called
- * from ithd_loop. There are two separate functions, one for each
- * ICU.
- */
- .globl setimask0, setimask1
-setimask0:
- cli
- movb _imen,%al
- outb %al,$IO_ICU1 + ICU_IMR_OFFSET
- sti
- ret
-
-setimask1:
- cli
- movb _imen + 1,%al
- outb %al,$IO_ICU2 + ICU_IMR_OFFSET
- sti
- ret
-
MCOUNT_LABEL(bintr)
FAST_INTR(0,fastintr0, ENABLE_ICU1)
FAST_INTR(1,fastintr1, ENABLE_ICU1)
diff --git a/sys/i386/i386/apic_vector.s b/sys/i386/i386/apic_vector.s
index 11d9797..1f80224 100644
--- a/sys/i386/i386/apic_vector.s
+++ b/sys/i386/i386/apic_vector.s
@@ -15,6 +15,23 @@
/* make an index into the IO APIC from the IRQ# */
#define REDTBL_IDX(irq_num) (0x10 + ((irq_num) * 2))
+/*
+ *
+ */
+#define PUSH_FRAME \
+ pushl $0 ; /* dummy error code */ \
+ pushl $0 ; /* dummy trap type */ \
+ pushal ; \
+ pushl %ds ; /* save data and extra segments ... */ \
+ pushl %es ; \
+ pushl %fs
+
+#define POP_FRAME \
+ popl %fs ; \
+ popl %es ; \
+ popl %ds ; \
+ popal ; \
+ addl $4+4,%esp
/*
* Macros for interrupt entry, call to handler, and exit.
@@ -24,18 +41,14 @@
.text ; \
SUPERALIGN_TEXT ; \
IDTVEC(vec_name) ; \
- pushl %eax ; /* save only call-used registers */ \
- pushl %ecx ; \
- pushl %edx ; \
- pushl %ds ; \
- MAYBE_PUSHL_ES ; \
- pushl %fs ; \
+ PUSH_FRAME ; \
movl $KDSEL,%eax ; \
mov %ax,%ds ; \
- MAYBE_MOVW_AX_ES ; \
+ mov %ax,%es ; \
movl $KPSEL,%eax ; \
mov %ax,%fs ; \
- FAKE_MCOUNT((5+ACTUALLY_PUSHED)*4(%esp)) ; \
+ FAKE_MCOUNT(13*4(%esp)) ; \
+ incb _intr_nesting_level ; \
pushl _intr_unit + (irq_num) * 4 ; \
call *_intr_handler + (irq_num) * 4 ; /* do the work ASAP */ \
addl $4, %esp ; \
@@ -46,31 +59,7 @@ IDTVEC(vec_name) ; \
lock ; \
incl (%eax) ; \
MEXITCOUNT ; \
- popl %fs ; \
- MAYBE_POPL_ES ; \
- popl %ds ; \
- popl %edx ; \
- popl %ecx ; \
- popl %eax ; \
- iret
-
-/*
- *
- */
-#define PUSH_FRAME \
- pushl $0 ; /* dummy error code */ \
- pushl $0 ; /* dummy trap type */ \
- pushal ; \
- pushl %ds ; /* save data and extra segments ... */ \
- pushl %es ; \
- pushl %fs
-
-#define POP_FRAME \
- popl %fs ; \
- popl %es ; \
- popl %ds ; \
- popal ; \
- addl $4+4,%esp
+ jmp doreti_next
#define IOAPICADDR(irq_num) CNAME(int_to_apicintpin) + 16 * (irq_num) + 8
#define REDIRIDX(irq_num) CNAME(int_to_apicintpin) + 16 * (irq_num) + 12
diff --git a/sys/i386/i386/genassym.c b/sys/i386/i386/genassym.c
index 78c6075..0566dd7 100644
--- a/sys/i386/i386/genassym.c
+++ b/sys/i386/i386/genassym.c
@@ -173,7 +173,6 @@ ASSYM(BI_ESYMTAB, offsetof(struct bootinfo, bi_esymtab));
ASSYM(BI_KERNEND, offsetof(struct bootinfo, bi_kernend));
ASSYM(GD_SIZEOF, sizeof(struct globaldata));
ASSYM(GD_CURPROC, offsetof(struct globaldata, gd_curproc));
-ASSYM(GD_PREVPROC, offsetof(struct globaldata, gd_prevproc));
ASSYM(GD_NPXPROC, offsetof(struct globaldata, gd_npxproc));
ASSYM(GD_IDLEPROC, offsetof(struct globaldata, gd_idleproc));
ASSYM(GD_CURPCB, offsetof(struct globaldata, gd_curpcb));
diff --git a/sys/i386/i386/globals.s b/sys/i386/i386/globals.s
index f318142..aaa6f81 100644
--- a/sys/i386/i386/globals.s
+++ b/sys/i386/i386/globals.s
@@ -61,11 +61,10 @@ globaldata:
#else
.set globaldata,0
#endif
- .globl gd_curproc, gd_prevproc, gd_curpcb, gd_npxproc, gd_idleproc
+ .globl gd_curproc, gd_curpcb, gd_npxproc, gd_idleproc
.globl gd_astpending, gd_common_tss, gd_switchtime, gd_switchticks
.globl gd_intr_nesting_level
.set gd_curproc,globaldata + GD_CURPROC
- .set gd_prevproc,globaldata + GD_PREVPROC
.set gd_astpending,globaldata + GD_ASTPENDING
.set gd_curpcb,globaldata + GD_CURPCB
.set gd_npxproc,globaldata + GD_NPXPROC
@@ -96,11 +95,10 @@ globaldata:
#endif
#ifndef SMP
- .globl _curproc, _prevproc, _curpcb, _npxproc, _idleproc,
+ .globl _curproc, _curpcb, _npxproc, _idleproc,
.globl _astpending, _common_tss, _switchtime, _switchticks
.global _intr_nesting_level
.set _curproc,globaldata + GD_CURPROC
- .set _prevproc,globaldata + GD_PREVPROC
.set _astpending,globaldata + GD_ASTPENDING
.set _curpcb,globaldata + GD_CURPCB
.set _npxproc,globaldata + GD_NPXPROC
diff --git a/sys/i386/i386/machdep.c b/sys/i386/i386/machdep.c
index 355a0a9..7055010 100644
--- a/sys/i386/i386/machdep.c
+++ b/sys/i386/i386/machdep.c
@@ -1883,7 +1883,6 @@ init386(first)
/* setup curproc so that mutexes work */
PCPU_SET(curproc, &proc0);
- PCPU_SET(prevproc, &proc0);
/* make ldt memory segments */
/*
@@ -1945,6 +1944,11 @@ init386(first)
lidt(&r_idt);
/*
+ * We need this mutex before the console probe.
+ */
+ mtx_init(&clock_lock, "clk interrupt lock", MTX_SPIN);
+
+ /*
* Initialize the console before we print anything out.
*/
cninit();
@@ -1955,8 +1959,7 @@ init386(first)
#endif
/*
- * Giant is used early for at least debugger traps, unexpected traps,
- * and vm86bios initialization.
+ * Giant is used early for at least debugger traps and unexpected traps.
*/
mtx_init(&Giant, "Giant", MTX_DEF);
diff --git a/sys/i386/i386/mp_machdep.c b/sys/i386/i386/mp_machdep.c
index ea9aee8..5ef95b3 100644
--- a/sys/i386/i386/mp_machdep.c
+++ b/sys/i386/i386/mp_machdep.c
@@ -1900,11 +1900,6 @@ struct simplelock mcount_lock;
struct simplelock com_lock;
#endif /* USE_COMLOCK */
-#ifdef USE_CLOCKLOCK
-/* lock regions around the clock hardware */
-struct simplelock clock_lock;
-#endif /* USE_CLOCKLOCK */
-
/* lock around the MP rendezvous */
static struct simplelock smp_rv_lock;
@@ -1930,9 +1925,6 @@ init_locks(void)
#ifdef USE_COMLOCK
s_lock_init((struct simplelock*)&com_lock);
#endif /* USE_COMLOCK */
-#ifdef USE_CLOCKLOCK
- s_lock_init((struct simplelock*)&clock_lock);
-#endif /* USE_CLOCKLOCK */
s_lock_init(&ap_boot_lock);
}
@@ -2425,7 +2417,6 @@ ap_init(void)
* something unique to lock with.
*/
PCPU_SET(curproc,idleproc);
- PCPU_SET(prevproc,idleproc);
microuptime(&switchtime);
switchticks = ticks;
diff --git a/sys/i386/i386/mptable.c b/sys/i386/i386/mptable.c
index ea9aee8..5ef95b3 100644
--- a/sys/i386/i386/mptable.c
+++ b/sys/i386/i386/mptable.c
@@ -1900,11 +1900,6 @@ struct simplelock mcount_lock;
struct simplelock com_lock;
#endif /* USE_COMLOCK */
-#ifdef USE_CLOCKLOCK
-/* lock regions around the clock hardware */
-struct simplelock clock_lock;
-#endif /* USE_CLOCKLOCK */
-
/* lock around the MP rendezvous */
static struct simplelock smp_rv_lock;
@@ -1930,9 +1925,6 @@ init_locks(void)
#ifdef USE_COMLOCK
s_lock_init((struct simplelock*)&com_lock);
#endif /* USE_COMLOCK */
-#ifdef USE_CLOCKLOCK
- s_lock_init((struct simplelock*)&clock_lock);
-#endif /* USE_CLOCKLOCK */
s_lock_init(&ap_boot_lock);
}
@@ -2425,7 +2417,6 @@ ap_init(void)
* something unique to lock with.
*/
PCPU_SET(curproc,idleproc);
- PCPU_SET(prevproc,idleproc);
microuptime(&switchtime);
switchticks = ticks;
diff --git a/sys/i386/i386/swtch.s b/sys/i386/i386/swtch.s
index ac71f0c..32dbe56 100644
--- a/sys/i386/i386/swtch.s
+++ b/sys/i386/i386/swtch.s
@@ -82,7 +82,6 @@ ENTRY(cpu_switch)
/* switch to new process. first, save context as needed */
movl _curproc,%ecx
- movl %ecx,_prevproc
/* if no process to save, don't bother */
testl %ecx,%ecx
diff --git a/sys/i386/i386/trap.c b/sys/i386/i386/trap.c
index 1cbfcfa..b9ebb60 100644
--- a/sys/i386/i386/trap.c
+++ b/sys/i386/i386/trap.c
@@ -1244,6 +1244,18 @@ ast(frame)
addupc_task(p, p->p_stats->p_prof.pr_addr,
p->p_stats->p_prof.pr_ticks);
}
+ if (p->p_flag & P_ALRMPEND) {
+ if (!mtx_owned(&Giant))
+ mtx_enter(&Giant, MTX_DEF);
+ p->p_flag &= ~P_ALRMPEND;
+ psignal(p, SIGVTALRM);
+ }
+ if (p->p_flag & P_PROFPEND) {
+ if (!mtx_owned(&Giant))
+ mtx_enter(&Giant, MTX_DEF);
+ p->p_flag &= ~P_PROFPEND;
+ psignal(p, SIGPROF);
+ }
if (userret(p, &frame, sticks, mtx_owned(&Giant)) != 0)
mtx_exit(&Giant, MTX_DEF);
}
diff --git a/sys/i386/i386/tsc.c b/sys/i386/i386/tsc.c
index 0e630d9..a164288 100644
--- a/sys/i386/i386/tsc.c
+++ b/sys/i386/i386/tsc.c
@@ -72,6 +72,7 @@
#include <machine/ipl.h>
#include <machine/limits.h>
#include <machine/md_var.h>
+#include <machine/mutex.h>
#include <machine/psl.h>
#ifdef APIC_IO
#include <machine/segments.h>
@@ -139,6 +140,7 @@ int timer0_max_count;
u_int tsc_freq;
int tsc_is_broken;
int wall_cmos_clock; /* wall CMOS clock assumed if != 0 */
+struct mtx clock_lock;
static int beeping = 0;
static const u_char daysinmonth[] = {31,28,31,30,31,30,31,31,30,31,30,31};
@@ -198,12 +200,9 @@ SYSCTL_OPAQUE(_debug, OID_AUTO, i8254_timecounter, CTLFLAG_RD,
static void
clkintr(struct clockframe frame)
{
- int intrsave;
if (timecounter->tc_get_timecount == i8254_get_timecount) {
- intrsave = save_intr();
- disable_intr();
- CLOCK_LOCK();
+ mtx_enter(&clock_lock, MTX_SPIN);
if (i8254_ticked)
i8254_ticked = 0;
else {
@@ -211,8 +210,7 @@ clkintr(struct clockframe frame)
i8254_lastcount = 0;
}
clkintr_pending = 0;
- CLOCK_UNLOCK();
- restore_intr(intrsave);
+ mtx_exit(&clock_lock, MTX_SPIN);
}
timer_func(&frame);
switch (timer0_state) {
@@ -231,17 +229,14 @@ clkintr(struct clockframe frame)
break;
case ACQUIRE_PENDING:
- intrsave = save_intr();
- disable_intr();
- CLOCK_LOCK();
+ mtx_enter(&clock_lock, MTX_SPIN);
i8254_offset = i8254_get_timecount(NULL);
i8254_lastcount = 0;
timer0_max_count = TIMER_DIV(new_rate);
outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT);
outb(TIMER_CNTR0, timer0_max_count & 0xff);
outb(TIMER_CNTR0, timer0_max_count >> 8);
- CLOCK_UNLOCK();
- restore_intr(intrsave);
+ mtx_exit(&clock_lock, MTX_SPIN);
timer_func = new_function;
timer0_state = ACQUIRED;
setdelayed();
@@ -250,9 +245,7 @@ clkintr(struct clockframe frame)
case RELEASE_PENDING:
if ((timer0_prescaler_count += timer0_max_count)
>= hardclock_max_count) {
- intrsave = save_intr();
- disable_intr();
- CLOCK_LOCK();
+ mtx_enter(&clock_lock, MTX_SPIN);
i8254_offset = i8254_get_timecount(NULL);
i8254_lastcount = 0;
timer0_max_count = hardclock_max_count;
@@ -260,8 +253,7 @@ clkintr(struct clockframe frame)
TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT);
outb(TIMER_CNTR0, timer0_max_count & 0xff);
outb(TIMER_CNTR0, timer0_max_count >> 8);
- CLOCK_UNLOCK();
- restore_intr(intrsave);
+ mtx_exit(&clock_lock, MTX_SPIN);
timer0_prescaler_count = 0;
timer_func = hardclock;
timer0_state = RELEASED;
@@ -408,11 +400,9 @@ DB_SHOW_COMMAND(rtc, rtc)
static int
getit(void)
{
- int high, low, intrsave;
+ int high, low;
- intrsave = save_intr();
- disable_intr();
- CLOCK_LOCK();
+ mtx_enter(&clock_lock, MTX_SPIN);
/* Select timer0 and latch counter value. */
outb(TIMER_MODE, TIMER_SEL0 | TIMER_LATCH);
@@ -420,8 +410,7 @@ getit(void)
low = inb(TIMER_CNTR0);
high = inb(TIMER_CNTR0);
- CLOCK_UNLOCK();
- restore_intr(intrsave);
+ mtx_exit(&clock_lock, MTX_SPIN);
return ((high << 8) | low);
}
@@ -527,7 +516,6 @@ sysbeepstop(void *chan)
int
sysbeep(int pitch, int period)
{
- int intrsave;
int x = splclock();
if (acquire_timer2(TIMER_SQWAVE|TIMER_16BIT))
@@ -536,13 +524,10 @@ sysbeep(int pitch, int period)
splx(x);
return (-1); /* XXX Should be EBUSY, but nobody cares anyway. */
}
- intrsave = save_intr();
- disable_intr();
- CLOCK_LOCK();
+ mtx_enter(&clock_lock, MTX_SPIN);
outb(TIMER_CNTR2, pitch);
outb(TIMER_CNTR2, (pitch>>8));
- CLOCK_UNLOCK();
- restore_intr(intrsave);
+ mtx_exit(&clock_lock, MTX_SPIN);
if (!beeping) {
/* enable counter2 output to speaker */
outb(IO_PPI, inb(IO_PPI) | 3);
@@ -691,12 +676,9 @@ fail:
static void
set_timer_freq(u_int freq, int intr_freq)
{
- int intrsave;
int new_timer0_max_count;
- intrsave = save_intr();
- disable_intr();
- CLOCK_LOCK();
+ mtx_enter(&clock_lock, MTX_SPIN);
timer_freq = freq;
new_timer0_max_count = hardclock_max_count = TIMER_DIV(intr_freq);
if (new_timer0_max_count != timer0_max_count) {
@@ -705,8 +687,7 @@ set_timer_freq(u_int freq, int intr_freq)
outb(TIMER_CNTR0, timer0_max_count & 0xff);
outb(TIMER_CNTR0, timer0_max_count >> 8);
}
- CLOCK_UNLOCK();
- restore_intr(intrsave);
+ mtx_exit(&clock_lock, MTX_SPIN);
}
/*
@@ -720,16 +701,12 @@ set_timer_freq(u_int freq, int intr_freq)
void
i8254_restore(void)
{
- int intrsave;
- intrsave = save_intr();
- disable_intr();
- CLOCK_LOCK();
+ mtx_enter(&clock_lock, MTX_SPIN);
outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT);
outb(TIMER_CNTR0, timer0_max_count & 0xff);
outb(TIMER_CNTR0, timer0_max_count >> 8);
- CLOCK_UNLOCK();
- restore_intr(intrsave);
+ mtx_exit(&clock_lock, MTX_SPIN);
}
/*
@@ -989,8 +966,8 @@ cpu_initclocks()
{
int diag;
#ifdef APIC_IO
- int apic_8254_trial, num_8254_ticks;
- struct intrec *clkdesc, *rtcdesc;
+ int apic_8254_trial;
+ struct intrec *clkdesc;
#endif /* APIC_IO */
if (statclock_disable) {
@@ -1023,6 +1000,11 @@ cpu_initclocks()
} else
panic("APIC_IO: Cannot route 8254 interrupt to CPU");
}
+
+ clkdesc = inthand_add("clk", apic_8254_intr, (driver_intr_t *)clkintr,
+ NULL, PI_REALTIME, INTR_FAST);
+ INTREN(1 << apic_8254_intr);
+
#else /* APIC_IO */
/*
@@ -1030,9 +1012,8 @@ cpu_initclocks()
* couldn't find anything suitable in the BSD/OS code (grog,
* 19 July 2000).
*/
- /* Setup the PIC clk handler. The APIC handler is setup later */
inthand_add("clk", 0, (driver_intr_t *)clkintr, NULL, PI_REALTIME,
- INTR_EXCL);
+ INTR_FAST);
INTREN(IRQ0);
#endif /* APIC_IO */
@@ -1042,18 +1023,8 @@ cpu_initclocks()
writertc(RTC_STATUSB, RTCSB_24HR);
/* Don't bother enabling the statistics clock. */
- if (statclock_disable) {
-#ifdef APIC_IO
- /*
- * XXX - if statclock is disabled, don't attempt the APIC
- * trial. Not sure this is sane for APIC_IO.
- */
- inthand_add("clk", apic_8254_intr, (driver_intr_t *)clkintr,
- NULL, PI_REALTIME, INTR_EXCL);
- INTREN(1 << apic_8254_intr);
-#endif /* APIC_IO */
+ if (statclock_disable)
return;
- }
diag = rtcin(RTC_DIAG);
if (diag != 0)
printf("RTC BIOS diagnostic error %b\n", diag, RTCDG_BITS);
@@ -1061,44 +1032,34 @@ cpu_initclocks()
#ifdef APIC_IO
if (isa_apic_irq(8) != 8)
panic("APIC RTC != 8");
+#endif /* APIC_IO */
- if (apic_8254_trial) {
- /*
- * XXX - We use fast interrupts for clk and rtc long enough to
- * perform the APIC probe and then revert to exclusive
- * interrupts.
- */
- clkdesc = inthand_add("clk", apic_8254_intr,
- (driver_intr_t *)clkintr, NULL, PI_REALTIME, INTR_FAST);
- INTREN(1 << apic_8254_intr);
+ inthand_add("rtc", 8, (driver_intr_t *)rtcintr, NULL, PI_REALTIME,
+ INTR_FAST);
- rtcdesc = inthand_add("rtc", 8, (driver_intr_t *)rtcintr, NULL,
- PI_REALTIME, INTR_FAST); /* XXX */
- INTREN(APIC_IRQ8);
- writertc(RTC_STATUSB, rtc_statusb);
+#ifdef APIC_IO
+ INTREN(APIC_IRQ8);
+#else
+ INTREN(IRQ8);
+#endif /* APIC_IO */
+
+ writertc(RTC_STATUSB, rtc_statusb);
+
+#ifdef APIC_IO
+ if (apic_8254_trial) {
printf("APIC_IO: Testing 8254 interrupt delivery\n");
while (read_intr_count(8) < 6)
; /* nothing */
- num_8254_ticks = read_intr_count(apic_8254_intr);
-
- /* disable and remove our fake handlers */
- INTRDIS(1 << apic_8254_intr);
- inthand_remove(clkdesc);
-
- writertc(RTC_STATUSA, rtc_statusa);
- writertc(RTC_STATUSB, RTCSB_24HR);
-
- INTRDIS(APIC_IRQ8);
- inthand_remove(rtcdesc);
-
- if (num_8254_ticks < 3) {
+ if (read_intr_count(apic_8254_intr) < 3) {
/*
* The MP table is broken.
* The 8254 was not connected to the specified pin
* on the IO APIC.
* Workaround: Limited variant of mixed mode.
*/
+ INTRDIS(1 << apic_8254_intr);
+ inthand_remove(clkdesc);
printf("APIC_IO: Broken MP table detected: "
"8254 is not connected to "
"IOAPIC #%d intpin %d\n",
@@ -1117,27 +1078,13 @@ cpu_initclocks()
}
apic_8254_intr = apic_irq(0, 0);
setup_8254_mixed_mode();
+ inthand_add("clk", apic_8254_intr,
+ (driver_intr_t *)clkintr, NULL,
+ PI_REALTIME, INTR_FAST);
+ INTREN(1 << apic_8254_intr);
}
}
-
- /* Finally, setup the real clock handlers */
- inthand_add("clk", apic_8254_intr, (driver_intr_t *)clkintr, NULL,
- PI_REALTIME, INTR_EXCL);
- INTREN(1 << apic_8254_intr);
-#endif
-
- inthand_add("rtc", 8, (driver_intr_t *)rtcintr, NULL, PI_REALTIME,
- INTR_EXCL);
-#ifdef APIC_IO
- INTREN(APIC_IRQ8);
-#else
- INTREN(IRQ8);
-#endif
-
- writertc(RTC_STATUSB, rtc_statusb);
-
-#ifdef APIC_IO
if (apic_int_type(0, 0) != 3 ||
int_to_apicintpin[apic_8254_intr].ioapic != 0 ||
int_to_apicintpin[apic_8254_intr].int_pin != 0)
@@ -1242,12 +1189,11 @@ static unsigned
i8254_get_timecount(struct timecounter *tc)
{
u_int count;
- int intrsave;
u_int high, low;
+ u_int eflags;
- intrsave = save_intr();
- disable_intr();
- CLOCK_LOCK();
+ eflags = read_eflags();
+ mtx_enter(&clock_lock, MTX_SPIN);
/* Select timer0 and latch counter value. */
outb(TIMER_MODE, TIMER_SEL0 | TIMER_LATCH);
@@ -1257,7 +1203,7 @@ i8254_get_timecount(struct timecounter *tc)
count = timer0_max_count - ((high << 8) | low);
if (count < i8254_lastcount ||
(!i8254_ticked && (clkintr_pending ||
- ((count < 20 || (!(intrsave & PSL_I) && count < timer0_max_count / 2u)) &&
+ ((count < 20 || (!(eflags & PSL_I) && count < timer0_max_count / 2u)) &&
#ifdef APIC_IO
#define lapic_irr1 ((volatile u_int *)&lapic)[0x210 / 4] /* XXX XXX */
/* XXX this assumes that apic_8254_intr is < 24. */
@@ -1271,8 +1217,7 @@ i8254_get_timecount(struct timecounter *tc)
}
i8254_lastcount = count;
count += i8254_offset;
- CLOCK_UNLOCK();
- restore_intr(intrsave);
+ mtx_exit(&clock_lock, MTX_SPIN);
return (count);
}
diff --git a/sys/i386/include/asnames.h b/sys/i386/include/asnames.h
index fe5d6ca..b99b9af 100644
--- a/sys/i386/include/asnames.h
+++ b/sys/i386/include/asnames.h
@@ -342,7 +342,6 @@
#define _cpu_lockid FS(cpu_lockid)
#define _curpcb FS(curpcb)
#define _curproc FS(curproc)
-#define _prevproc FS(prevproc)
#define _idleproc FS(idleproc)
#define _astpending FS(astpending)
#define _currentldt FS(currentldt)
diff --git a/sys/i386/include/cpu.h b/sys/i386/include/cpu.h
index 18822b8..d35b940 100644
--- a/sys/i386/include/cpu.h
+++ b/sys/i386/include/cpu.h
@@ -62,21 +62,6 @@
((ISPL((framep)->cf_cs) == SEL_UPL) || (framep->cf_eflags & PSL_VM))
#define CLKF_INTR(framep) (intr_nesting_level >= 2)
-#if 0
-/*
- * XXX splsoftclock() is very broken and barely worth fixing. It doesn't
- * turn off the clock bit in imen or in the icu. (This is not a serious
- * problem at 100 Hz but it is serious at 16000 Hz for pcaudio. softclock()
- * can take more than 62.5 usec so clock interrupts are lost.) It doesn't
- * check for pending interrupts being unmasked. clkintr() and Xintr0()
- * assume that the ipl is high when hardclock() returns. Our SWI_CLOCK
- * handling is efficient enough that little is gained by calling
- * softclock() directly.
- */
-#define CLKF_BASEPRI(framep) ((framep)->cf_ppl == 0)
-#else
-#define CLKF_BASEPRI(framep) (0)
-#endif
#define CLKF_PC(framep) ((framep)->cf_eip)
/*
diff --git a/sys/i386/include/globaldata.h b/sys/i386/include/globaldata.h
index ace3602..2788499 100644
--- a/sys/i386/include/globaldata.h
+++ b/sys/i386/include/globaldata.h
@@ -55,7 +55,6 @@
struct globaldata {
struct privatespace *gd_prvspace; /* self-reference */
struct proc *gd_curproc;
- struct proc *gd_prevproc;
struct proc *gd_npxproc;
struct pcb *gd_curpcb;
struct proc *gd_idleproc;
diff --git a/sys/i386/include/globals.h b/sys/i386/include/globals.h
index 71bbbd5..d18c0ac 100644
--- a/sys/i386/include/globals.h
+++ b/sys/i386/include/globals.h
@@ -90,7 +90,6 @@ _global_globaldata(void)
* portability between UP and SMP kernels.
*/
#define curproc GLOBAL_RVALUE_NV(curproc, struct proc *)
-#define prevproc GLOBAL_RVALUE_NV(prevproc, struct proc *)
#define curpcb GLOBAL_RVALUE_NV(curpcb, struct pcb *)
#define npxproc GLOBAL_RVALUE_NV(npxproc, struct proc *)
#define idleproc GLOBAL_RVALUE_NV(idleproc, struct proc *)
@@ -126,7 +125,6 @@ _global_globaldata(void)
#endif /*UP kernel*/
GLOBAL_FUNC(curproc)
-GLOBAL_FUNC(prevproc)
GLOBAL_FUNC(astpending)
GLOBAL_FUNC(curpcb)
GLOBAL_FUNC(npxproc)
diff --git a/sys/i386/include/lock.h b/sys/i386/include/lock.h
index 7871606..aa527ef 100644
--- a/sys/i386/include/lock.h
+++ b/sys/i386/include/lock.h
@@ -74,24 +74,10 @@
#define COM_UNLOCK()
#endif /* USE_COMLOCK */
-/*
- * Clock hardware/struct lock.
- * XXX pcaudio and friends still need this lock installed.
- */
-#ifdef USE_CLOCKLOCK
-#define CLOCK_LOCK() s_lock(&clock_lock)
-#define CLOCK_UNLOCK() s_unlock(&clock_lock)
-#else
-#define CLOCK_LOCK()
-#define CLOCK_UNLOCK()
-#endif /* USE_CLOCKLOCK */
-
#else /* SMP */
#define COM_LOCK()
#define COM_UNLOCK()
-#define CLOCK_LOCK()
-#define CLOCK_UNLOCK()
#endif /* SMP */
@@ -124,7 +110,6 @@ extern struct simplelock imen_lock;
extern struct simplelock cpl_lock;
extern struct simplelock fast_intr_lock;
extern struct simplelock intr_lock;
-extern struct simplelock clock_lock;
extern struct simplelock com_lock;
extern struct simplelock mpintr_lock;
extern struct simplelock mcount_lock;
diff --git a/sys/i386/include/mptable.h b/sys/i386/include/mptable.h
index ea9aee8..5ef95b3 100644
--- a/sys/i386/include/mptable.h
+++ b/sys/i386/include/mptable.h
@@ -1900,11 +1900,6 @@ struct simplelock mcount_lock;
struct simplelock com_lock;
#endif /* USE_COMLOCK */
-#ifdef USE_CLOCKLOCK
-/* lock regions around the clock hardware */
-struct simplelock clock_lock;
-#endif /* USE_CLOCKLOCK */
-
/* lock around the MP rendezvous */
static struct simplelock smp_rv_lock;
@@ -1930,9 +1925,6 @@ init_locks(void)
#ifdef USE_COMLOCK
s_lock_init((struct simplelock*)&com_lock);
#endif /* USE_COMLOCK */
-#ifdef USE_CLOCKLOCK
- s_lock_init((struct simplelock*)&clock_lock);
-#endif /* USE_CLOCKLOCK */
s_lock_init(&ap_boot_lock);
}
@@ -2425,7 +2417,6 @@ ap_init(void)
* something unique to lock with.
*/
PCPU_SET(curproc,idleproc);
- PCPU_SET(prevproc,idleproc);
microuptime(&switchtime);
switchticks = ticks;
diff --git a/sys/i386/include/mutex.h b/sys/i386/include/mutex.h
index ca518d9..881cbfa 100644
--- a/sys/i386/include/mutex.h
+++ b/sys/i386/include/mutex.h
@@ -146,6 +146,7 @@ void _mtx_exit(struct mtx *mtxp, int type, const char *file, int line);
/* Global locks */
extern struct mtx sched_lock;
extern struct mtx Giant;
+extern struct mtx clock_lock;
/*
* Used to replace return with an exit Giant and return.
diff --git a/sys/i386/include/pcpu.h b/sys/i386/include/pcpu.h
index ace3602..2788499 100644
--- a/sys/i386/include/pcpu.h
+++ b/sys/i386/include/pcpu.h
@@ -55,7 +55,6 @@
struct globaldata {
struct privatespace *gd_prvspace; /* self-reference */
struct proc *gd_curproc;
- struct proc *gd_prevproc;
struct proc *gd_npxproc;
struct pcb *gd_curpcb;
struct proc *gd_idleproc;
diff --git a/sys/i386/include/smptests.h b/sys/i386/include/smptests.h
index 304e990..239f849 100644
--- a/sys/i386/include/smptests.h
+++ b/sys/i386/include/smptests.h
@@ -87,14 +87,12 @@
* protected via cli/sti in the UP kernel.
*
* COMLOCK protects the sio/cy drivers.
- * CLOCKLOCK protects clock hardware and data
* known to be incomplete:
* joystick lkm
* ?
*/
#ifdef PUSHDOWN_LEVEL_1
#define USE_COMLOCK
-#define USE_CLOCKLOCK
#endif
diff --git a/sys/i386/isa/apic_vector.s b/sys/i386/isa/apic_vector.s
index 11d9797..1f80224 100644
--- a/sys/i386/isa/apic_vector.s
+++ b/sys/i386/isa/apic_vector.s
@@ -15,6 +15,23 @@
/* make an index into the IO APIC from the IRQ# */
#define REDTBL_IDX(irq_num) (0x10 + ((irq_num) * 2))
+/*
+ *
+ */
+#define PUSH_FRAME \
+ pushl $0 ; /* dummy error code */ \
+ pushl $0 ; /* dummy trap type */ \
+ pushal ; \
+ pushl %ds ; /* save data and extra segments ... */ \
+ pushl %es ; \
+ pushl %fs
+
+#define POP_FRAME \
+ popl %fs ; \
+ popl %es ; \
+ popl %ds ; \
+ popal ; \
+ addl $4+4,%esp
/*
* Macros for interrupt entry, call to handler, and exit.
@@ -24,18 +41,14 @@
.text ; \
SUPERALIGN_TEXT ; \
IDTVEC(vec_name) ; \
- pushl %eax ; /* save only call-used registers */ \
- pushl %ecx ; \
- pushl %edx ; \
- pushl %ds ; \
- MAYBE_PUSHL_ES ; \
- pushl %fs ; \
+ PUSH_FRAME ; \
movl $KDSEL,%eax ; \
mov %ax,%ds ; \
- MAYBE_MOVW_AX_ES ; \
+ mov %ax,%es ; \
movl $KPSEL,%eax ; \
mov %ax,%fs ; \
- FAKE_MCOUNT((5+ACTUALLY_PUSHED)*4(%esp)) ; \
+ FAKE_MCOUNT(13*4(%esp)) ; \
+ incb _intr_nesting_level ; \
pushl _intr_unit + (irq_num) * 4 ; \
call *_intr_handler + (irq_num) * 4 ; /* do the work ASAP */ \
addl $4, %esp ; \
@@ -46,31 +59,7 @@ IDTVEC(vec_name) ; \
lock ; \
incl (%eax) ; \
MEXITCOUNT ; \
- popl %fs ; \
- MAYBE_POPL_ES ; \
- popl %ds ; \
- popl %edx ; \
- popl %ecx ; \
- popl %eax ; \
- iret
-
-/*
- *
- */
-#define PUSH_FRAME \
- pushl $0 ; /* dummy error code */ \
- pushl $0 ; /* dummy trap type */ \
- pushal ; \
- pushl %ds ; /* save data and extra segments ... */ \
- pushl %es ; \
- pushl %fs
-
-#define POP_FRAME \
- popl %fs ; \
- popl %es ; \
- popl %ds ; \
- popal ; \
- addl $4+4,%esp
+ jmp doreti_next
#define IOAPICADDR(irq_num) CNAME(int_to_apicintpin) + 16 * (irq_num) + 8
#define REDIRIDX(irq_num) CNAME(int_to_apicintpin) + 16 * (irq_num) + 12
diff --git a/sys/i386/isa/atpic_vector.s b/sys/i386/isa/atpic_vector.s
index 0a89492..7644c03 100644
--- a/sys/i386/isa/atpic_vector.s
+++ b/sys/i386/isa/atpic_vector.s
@@ -49,17 +49,18 @@
.text ; \
SUPERALIGN_TEXT ; \
IDTVEC(vec_name) ; \
- pushl %eax ; /* save only call-used registers */ \
- pushl %ecx ; \
- pushl %edx ; \
+ pushl $0 ; /* dummy error code */ \
+ pushl $0 ; /* dummy trap type */ \
+ pushal ; \
pushl %ds ; \
+ pushl %es ; \
pushl %fs ; \
- MAYBE_PUSHL_ES ; \
mov $KDSEL,%ax ; \
mov %ax,%ds ; \
+ mov %ax,%es ; \
mov %ax,%fs ; \
- MAYBE_MOVW_AX_ES ; \
- FAKE_MCOUNT((4+ACTUALLY_PUSHED)*4(%esp)) ; \
+ FAKE_MCOUNT((12+ACTUALLY_PUSHED)*4(%esp)) ; \
+ incb _intr_nesting_level ; \
pushl _intr_unit + (irq_num) * 4 ; \
call *_intr_handler + (irq_num) * 4 ; /* do the work ASAP */ \
enable_icus ; /* (re)enable ASAP (helps edge trigger?) */ \
@@ -67,19 +68,8 @@ IDTVEC(vec_name) ; \
incl _cnt+V_INTR ; /* book-keeping can wait */ \
movl _intr_countp + (irq_num) * 4,%eax ; \
incl (%eax) ; \
-/* movl _cpl,%eax ; // are we unmasking pending SWIs? / \
- notl %eax ; \
- andl _spending,$SWI_MASK ; \
- jne 2f ; // yes, maybe handle them */ \
-1: ; \
MEXITCOUNT ; \
- MAYBE_POPL_ES ; \
- popl %fs ; \
- popl %ds ; \
- popl %edx ; \
- popl %ecx ; \
- popl %eax ; \
- iret ; \
+ jmp doreti_next
#if 0
; \
@@ -141,7 +131,7 @@ IDTVEC(vec_name) ; \
movb %al,_imen + IRQ_BYTE(irq_num) ; \
outb %al,$icu+ICU_IMR_OFFSET ; \
enable_icus ; \
- incb _intr_nesting_level ; /* XXX do we need this? */ \
+ incb _intr_nesting_level ; \
__CONCAT(Xresume,irq_num): ; \
FAKE_MCOUNT(13*4(%esp)) ; /* XXX late to avoid double count */ \
pushl $irq_num; /* pass the IRQ */ \
@@ -153,26 +143,6 @@ __CONCAT(Xresume,irq_num): ; \
/* _doreti, but it's probably better to use less cache. */ \
jmp doreti_next /* and catch up inside doreti */
-/*
- * Reenable the interrupt mask after completing an interrupt. Called
- * from ithd_loop. There are two separate functions, one for each
- * ICU.
- */
- .globl setimask0, setimask1
-setimask0:
- cli
- movb _imen,%al
- outb %al,$IO_ICU1 + ICU_IMR_OFFSET
- sti
- ret
-
-setimask1:
- cli
- movb _imen + 1,%al
- outb %al,$IO_ICU2 + ICU_IMR_OFFSET
- sti
- ret
-
MCOUNT_LABEL(bintr)
FAST_INTR(0,fastintr0, ENABLE_ICU1)
FAST_INTR(1,fastintr1, ENABLE_ICU1)
diff --git a/sys/i386/isa/clock.c b/sys/i386/isa/clock.c
index 0e630d9..a164288 100644
--- a/sys/i386/isa/clock.c
+++ b/sys/i386/isa/clock.c
@@ -72,6 +72,7 @@
#include <machine/ipl.h>
#include <machine/limits.h>
#include <machine/md_var.h>
+#include <machine/mutex.h>
#include <machine/psl.h>
#ifdef APIC_IO
#include <machine/segments.h>
@@ -139,6 +140,7 @@ int timer0_max_count;
u_int tsc_freq;
int tsc_is_broken;
int wall_cmos_clock; /* wall CMOS clock assumed if != 0 */
+struct mtx clock_lock;
static int beeping = 0;
static const u_char daysinmonth[] = {31,28,31,30,31,30,31,31,30,31,30,31};
@@ -198,12 +200,9 @@ SYSCTL_OPAQUE(_debug, OID_AUTO, i8254_timecounter, CTLFLAG_RD,
static void
clkintr(struct clockframe frame)
{
- int intrsave;
if (timecounter->tc_get_timecount == i8254_get_timecount) {
- intrsave = save_intr();
- disable_intr();
- CLOCK_LOCK();
+ mtx_enter(&clock_lock, MTX_SPIN);
if (i8254_ticked)
i8254_ticked = 0;
else {
@@ -211,8 +210,7 @@ clkintr(struct clockframe frame)
i8254_lastcount = 0;
}
clkintr_pending = 0;
- CLOCK_UNLOCK();
- restore_intr(intrsave);
+ mtx_exit(&clock_lock, MTX_SPIN);
}
timer_func(&frame);
switch (timer0_state) {
@@ -231,17 +229,14 @@ clkintr(struct clockframe frame)
break;
case ACQUIRE_PENDING:
- intrsave = save_intr();
- disable_intr();
- CLOCK_LOCK();
+ mtx_enter(&clock_lock, MTX_SPIN);
i8254_offset = i8254_get_timecount(NULL);
i8254_lastcount = 0;
timer0_max_count = TIMER_DIV(new_rate);
outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT);
outb(TIMER_CNTR0, timer0_max_count & 0xff);
outb(TIMER_CNTR0, timer0_max_count >> 8);
- CLOCK_UNLOCK();
- restore_intr(intrsave);
+ mtx_exit(&clock_lock, MTX_SPIN);
timer_func = new_function;
timer0_state = ACQUIRED;
setdelayed();
@@ -250,9 +245,7 @@ clkintr(struct clockframe frame)
case RELEASE_PENDING:
if ((timer0_prescaler_count += timer0_max_count)
>= hardclock_max_count) {
- intrsave = save_intr();
- disable_intr();
- CLOCK_LOCK();
+ mtx_enter(&clock_lock, MTX_SPIN);
i8254_offset = i8254_get_timecount(NULL);
i8254_lastcount = 0;
timer0_max_count = hardclock_max_count;
@@ -260,8 +253,7 @@ clkintr(struct clockframe frame)
TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT);
outb(TIMER_CNTR0, timer0_max_count & 0xff);
outb(TIMER_CNTR0, timer0_max_count >> 8);
- CLOCK_UNLOCK();
- restore_intr(intrsave);
+ mtx_exit(&clock_lock, MTX_SPIN);
timer0_prescaler_count = 0;
timer_func = hardclock;
timer0_state = RELEASED;
@@ -408,11 +400,9 @@ DB_SHOW_COMMAND(rtc, rtc)
static int
getit(void)
{
- int high, low, intrsave;
+ int high, low;
- intrsave = save_intr();
- disable_intr();
- CLOCK_LOCK();
+ mtx_enter(&clock_lock, MTX_SPIN);
/* Select timer0 and latch counter value. */
outb(TIMER_MODE, TIMER_SEL0 | TIMER_LATCH);
@@ -420,8 +410,7 @@ getit(void)
low = inb(TIMER_CNTR0);
high = inb(TIMER_CNTR0);
- CLOCK_UNLOCK();
- restore_intr(intrsave);
+ mtx_exit(&clock_lock, MTX_SPIN);
return ((high << 8) | low);
}
@@ -527,7 +516,6 @@ sysbeepstop(void *chan)
int
sysbeep(int pitch, int period)
{
- int intrsave;
int x = splclock();
if (acquire_timer2(TIMER_SQWAVE|TIMER_16BIT))
@@ -536,13 +524,10 @@ sysbeep(int pitch, int period)
splx(x);
return (-1); /* XXX Should be EBUSY, but nobody cares anyway. */
}
- intrsave = save_intr();
- disable_intr();
- CLOCK_LOCK();
+ mtx_enter(&clock_lock, MTX_SPIN);
outb(TIMER_CNTR2, pitch);
outb(TIMER_CNTR2, (pitch>>8));
- CLOCK_UNLOCK();
- restore_intr(intrsave);
+ mtx_exit(&clock_lock, MTX_SPIN);
if (!beeping) {
/* enable counter2 output to speaker */
outb(IO_PPI, inb(IO_PPI) | 3);
@@ -691,12 +676,9 @@ fail:
static void
set_timer_freq(u_int freq, int intr_freq)
{
- int intrsave;
int new_timer0_max_count;
- intrsave = save_intr();
- disable_intr();
- CLOCK_LOCK();
+ mtx_enter(&clock_lock, MTX_SPIN);
timer_freq = freq;
new_timer0_max_count = hardclock_max_count = TIMER_DIV(intr_freq);
if (new_timer0_max_count != timer0_max_count) {
@@ -705,8 +687,7 @@ set_timer_freq(u_int freq, int intr_freq)
outb(TIMER_CNTR0, timer0_max_count & 0xff);
outb(TIMER_CNTR0, timer0_max_count >> 8);
}
- CLOCK_UNLOCK();
- restore_intr(intrsave);
+ mtx_exit(&clock_lock, MTX_SPIN);
}
/*
@@ -720,16 +701,12 @@ set_timer_freq(u_int freq, int intr_freq)
void
i8254_restore(void)
{
- int intrsave;
- intrsave = save_intr();
- disable_intr();
- CLOCK_LOCK();
+ mtx_enter(&clock_lock, MTX_SPIN);
outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT);
outb(TIMER_CNTR0, timer0_max_count & 0xff);
outb(TIMER_CNTR0, timer0_max_count >> 8);
- CLOCK_UNLOCK();
- restore_intr(intrsave);
+ mtx_exit(&clock_lock, MTX_SPIN);
}
/*
@@ -989,8 +966,8 @@ cpu_initclocks()
{
int diag;
#ifdef APIC_IO
- int apic_8254_trial, num_8254_ticks;
- struct intrec *clkdesc, *rtcdesc;
+ int apic_8254_trial;
+ struct intrec *clkdesc;
#endif /* APIC_IO */
if (statclock_disable) {
@@ -1023,6 +1000,11 @@ cpu_initclocks()
} else
panic("APIC_IO: Cannot route 8254 interrupt to CPU");
}
+
+ clkdesc = inthand_add("clk", apic_8254_intr, (driver_intr_t *)clkintr,
+ NULL, PI_REALTIME, INTR_FAST);
+ INTREN(1 << apic_8254_intr);
+
#else /* APIC_IO */
/*
@@ -1030,9 +1012,8 @@ cpu_initclocks()
* couldn't find anything suitable in the BSD/OS code (grog,
* 19 July 2000).
*/
- /* Setup the PIC clk handler. The APIC handler is setup later */
inthand_add("clk", 0, (driver_intr_t *)clkintr, NULL, PI_REALTIME,
- INTR_EXCL);
+ INTR_FAST);
INTREN(IRQ0);
#endif /* APIC_IO */
@@ -1042,18 +1023,8 @@ cpu_initclocks()
writertc(RTC_STATUSB, RTCSB_24HR);
/* Don't bother enabling the statistics clock. */
- if (statclock_disable) {
-#ifdef APIC_IO
- /*
- * XXX - if statclock is disabled, don't attempt the APIC
- * trial. Not sure this is sane for APIC_IO.
- */
- inthand_add("clk", apic_8254_intr, (driver_intr_t *)clkintr,
- NULL, PI_REALTIME, INTR_EXCL);
- INTREN(1 << apic_8254_intr);
-#endif /* APIC_IO */
+ if (statclock_disable)
return;
- }
diag = rtcin(RTC_DIAG);
if (diag != 0)
printf("RTC BIOS diagnostic error %b\n", diag, RTCDG_BITS);
@@ -1061,44 +1032,34 @@ cpu_initclocks()
#ifdef APIC_IO
if (isa_apic_irq(8) != 8)
panic("APIC RTC != 8");
+#endif /* APIC_IO */
- if (apic_8254_trial) {
- /*
- * XXX - We use fast interrupts for clk and rtc long enough to
- * perform the APIC probe and then revert to exclusive
- * interrupts.
- */
- clkdesc = inthand_add("clk", apic_8254_intr,
- (driver_intr_t *)clkintr, NULL, PI_REALTIME, INTR_FAST);
- INTREN(1 << apic_8254_intr);
+ inthand_add("rtc", 8, (driver_intr_t *)rtcintr, NULL, PI_REALTIME,
+ INTR_FAST);
- rtcdesc = inthand_add("rtc", 8, (driver_intr_t *)rtcintr, NULL,
- PI_REALTIME, INTR_FAST); /* XXX */
- INTREN(APIC_IRQ8);
- writertc(RTC_STATUSB, rtc_statusb);
+#ifdef APIC_IO
+ INTREN(APIC_IRQ8);
+#else
+ INTREN(IRQ8);
+#endif /* APIC_IO */
+
+ writertc(RTC_STATUSB, rtc_statusb);
+
+#ifdef APIC_IO
+ if (apic_8254_trial) {
printf("APIC_IO: Testing 8254 interrupt delivery\n");
while (read_intr_count(8) < 6)
; /* nothing */
- num_8254_ticks = read_intr_count(apic_8254_intr);
-
- /* disable and remove our fake handlers */
- INTRDIS(1 << apic_8254_intr);
- inthand_remove(clkdesc);
-
- writertc(RTC_STATUSA, rtc_statusa);
- writertc(RTC_STATUSB, RTCSB_24HR);
-
- INTRDIS(APIC_IRQ8);
- inthand_remove(rtcdesc);
-
- if (num_8254_ticks < 3) {
+ if (read_intr_count(apic_8254_intr) < 3) {
/*
* The MP table is broken.
* The 8254 was not connected to the specified pin
* on the IO APIC.
* Workaround: Limited variant of mixed mode.
*/
+ INTRDIS(1 << apic_8254_intr);
+ inthand_remove(clkdesc);
printf("APIC_IO: Broken MP table detected: "
"8254 is not connected to "
"IOAPIC #%d intpin %d\n",
@@ -1117,27 +1078,13 @@ cpu_initclocks()
}
apic_8254_intr = apic_irq(0, 0);
setup_8254_mixed_mode();
+ inthand_add("clk", apic_8254_intr,
+ (driver_intr_t *)clkintr, NULL,
+ PI_REALTIME, INTR_FAST);
+ INTREN(1 << apic_8254_intr);
}
}
-
- /* Finally, setup the real clock handlers */
- inthand_add("clk", apic_8254_intr, (driver_intr_t *)clkintr, NULL,
- PI_REALTIME, INTR_EXCL);
- INTREN(1 << apic_8254_intr);
-#endif
-
- inthand_add("rtc", 8, (driver_intr_t *)rtcintr, NULL, PI_REALTIME,
- INTR_EXCL);
-#ifdef APIC_IO
- INTREN(APIC_IRQ8);
-#else
- INTREN(IRQ8);
-#endif
-
- writertc(RTC_STATUSB, rtc_statusb);
-
-#ifdef APIC_IO
if (apic_int_type(0, 0) != 3 ||
int_to_apicintpin[apic_8254_intr].ioapic != 0 ||
int_to_apicintpin[apic_8254_intr].int_pin != 0)
@@ -1242,12 +1189,11 @@ static unsigned
i8254_get_timecount(struct timecounter *tc)
{
u_int count;
- int intrsave;
u_int high, low;
+ u_int eflags;
- intrsave = save_intr();
- disable_intr();
- CLOCK_LOCK();
+ eflags = read_eflags();
+ mtx_enter(&clock_lock, MTX_SPIN);
/* Select timer0 and latch counter value. */
outb(TIMER_MODE, TIMER_SEL0 | TIMER_LATCH);
@@ -1257,7 +1203,7 @@ i8254_get_timecount(struct timecounter *tc)
count = timer0_max_count - ((high << 8) | low);
if (count < i8254_lastcount ||
(!i8254_ticked && (clkintr_pending ||
- ((count < 20 || (!(intrsave & PSL_I) && count < timer0_max_count / 2u)) &&
+ ((count < 20 || (!(eflags & PSL_I) && count < timer0_max_count / 2u)) &&
#ifdef APIC_IO
#define lapic_irr1 ((volatile u_int *)&lapic)[0x210 / 4] /* XXX XXX */
/* XXX this assumes that apic_8254_intr is < 24. */
@@ -1271,8 +1217,7 @@ i8254_get_timecount(struct timecounter *tc)
}
i8254_lastcount = count;
count += i8254_offset;
- CLOCK_UNLOCK();
- restore_intr(intrsave);
+ mtx_exit(&clock_lock, MTX_SPIN);
return (count);
}
diff --git a/sys/i386/isa/icu_vector.s b/sys/i386/isa/icu_vector.s
index 0a89492..7644c03 100644
--- a/sys/i386/isa/icu_vector.s
+++ b/sys/i386/isa/icu_vector.s
@@ -49,17 +49,18 @@
.text ; \
SUPERALIGN_TEXT ; \
IDTVEC(vec_name) ; \
- pushl %eax ; /* save only call-used registers */ \
- pushl %ecx ; \
- pushl %edx ; \
+ pushl $0 ; /* dummy error code */ \
+ pushl $0 ; /* dummy trap type */ \
+ pushal ; \
pushl %ds ; \
+ pushl %es ; \
pushl %fs ; \
- MAYBE_PUSHL_ES ; \
mov $KDSEL,%ax ; \
mov %ax,%ds ; \
+ mov %ax,%es ; \
mov %ax,%fs ; \
- MAYBE_MOVW_AX_ES ; \
- FAKE_MCOUNT((4+ACTUALLY_PUSHED)*4(%esp)) ; \
+ FAKE_MCOUNT((12+ACTUALLY_PUSHED)*4(%esp)) ; \
+ incb _intr_nesting_level ; \
pushl _intr_unit + (irq_num) * 4 ; \
call *_intr_handler + (irq_num) * 4 ; /* do the work ASAP */ \
enable_icus ; /* (re)enable ASAP (helps edge trigger?) */ \
@@ -67,19 +68,8 @@ IDTVEC(vec_name) ; \
incl _cnt+V_INTR ; /* book-keeping can wait */ \
movl _intr_countp + (irq_num) * 4,%eax ; \
incl (%eax) ; \
-/* movl _cpl,%eax ; // are we unmasking pending SWIs? / \
- notl %eax ; \
- andl _spending,$SWI_MASK ; \
- jne 2f ; // yes, maybe handle them */ \
-1: ; \
MEXITCOUNT ; \
- MAYBE_POPL_ES ; \
- popl %fs ; \
- popl %ds ; \
- popl %edx ; \
- popl %ecx ; \
- popl %eax ; \
- iret ; \
+ jmp doreti_next
#if 0
; \
@@ -141,7 +131,7 @@ IDTVEC(vec_name) ; \
movb %al,_imen + IRQ_BYTE(irq_num) ; \
outb %al,$icu+ICU_IMR_OFFSET ; \
enable_icus ; \
- incb _intr_nesting_level ; /* XXX do we need this? */ \
+ incb _intr_nesting_level ; \
__CONCAT(Xresume,irq_num): ; \
FAKE_MCOUNT(13*4(%esp)) ; /* XXX late to avoid double count */ \
pushl $irq_num; /* pass the IRQ */ \
@@ -153,26 +143,6 @@ __CONCAT(Xresume,irq_num): ; \
/* _doreti, but it's probably better to use less cache. */ \
jmp doreti_next /* and catch up inside doreti */
-/*
- * Reenable the interrupt mask after completing an interrupt. Called
- * from ithd_loop. There are two separate functions, one for each
- * ICU.
- */
- .globl setimask0, setimask1
-setimask0:
- cli
- movb _imen,%al
- outb %al,$IO_ICU1 + ICU_IMR_OFFSET
- sti
- ret
-
-setimask1:
- cli
- movb _imen + 1,%al
- outb %al,$IO_ICU2 + ICU_IMR_OFFSET
- sti
- ret
-
MCOUNT_LABEL(bintr)
FAST_INTR(0,fastintr0, ENABLE_ICU1)
FAST_INTR(1,fastintr1, ENABLE_ICU1)
diff --git a/sys/isa/atrtc.c b/sys/isa/atrtc.c
index 0e630d9..a164288 100644
--- a/sys/isa/atrtc.c
+++ b/sys/isa/atrtc.c
@@ -72,6 +72,7 @@
#include <machine/ipl.h>
#include <machine/limits.h>
#include <machine/md_var.h>
+#include <machine/mutex.h>
#include <machine/psl.h>
#ifdef APIC_IO
#include <machine/segments.h>
@@ -139,6 +140,7 @@ int timer0_max_count;
u_int tsc_freq;
int tsc_is_broken;
int wall_cmos_clock; /* wall CMOS clock assumed if != 0 */
+struct mtx clock_lock;
static int beeping = 0;
static const u_char daysinmonth[] = {31,28,31,30,31,30,31,31,30,31,30,31};
@@ -198,12 +200,9 @@ SYSCTL_OPAQUE(_debug, OID_AUTO, i8254_timecounter, CTLFLAG_RD,
static void
clkintr(struct clockframe frame)
{
- int intrsave;
if (timecounter->tc_get_timecount == i8254_get_timecount) {
- intrsave = save_intr();
- disable_intr();
- CLOCK_LOCK();
+ mtx_enter(&clock_lock, MTX_SPIN);
if (i8254_ticked)
i8254_ticked = 0;
else {
@@ -211,8 +210,7 @@ clkintr(struct clockframe frame)
i8254_lastcount = 0;
}
clkintr_pending = 0;
- CLOCK_UNLOCK();
- restore_intr(intrsave);
+ mtx_exit(&clock_lock, MTX_SPIN);
}
timer_func(&frame);
switch (timer0_state) {
@@ -231,17 +229,14 @@ clkintr(struct clockframe frame)
break;
case ACQUIRE_PENDING:
- intrsave = save_intr();
- disable_intr();
- CLOCK_LOCK();
+ mtx_enter(&clock_lock, MTX_SPIN);
i8254_offset = i8254_get_timecount(NULL);
i8254_lastcount = 0;
timer0_max_count = TIMER_DIV(new_rate);
outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT);
outb(TIMER_CNTR0, timer0_max_count & 0xff);
outb(TIMER_CNTR0, timer0_max_count >> 8);
- CLOCK_UNLOCK();
- restore_intr(intrsave);
+ mtx_exit(&clock_lock, MTX_SPIN);
timer_func = new_function;
timer0_state = ACQUIRED;
setdelayed();
@@ -250,9 +245,7 @@ clkintr(struct clockframe frame)
case RELEASE_PENDING:
if ((timer0_prescaler_count += timer0_max_count)
>= hardclock_max_count) {
- intrsave = save_intr();
- disable_intr();
- CLOCK_LOCK();
+ mtx_enter(&clock_lock, MTX_SPIN);
i8254_offset = i8254_get_timecount(NULL);
i8254_lastcount = 0;
timer0_max_count = hardclock_max_count;
@@ -260,8 +253,7 @@ clkintr(struct clockframe frame)
TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT);
outb(TIMER_CNTR0, timer0_max_count & 0xff);
outb(TIMER_CNTR0, timer0_max_count >> 8);
- CLOCK_UNLOCK();
- restore_intr(intrsave);
+ mtx_exit(&clock_lock, MTX_SPIN);
timer0_prescaler_count = 0;
timer_func = hardclock;
timer0_state = RELEASED;
@@ -408,11 +400,9 @@ DB_SHOW_COMMAND(rtc, rtc)
static int
getit(void)
{
- int high, low, intrsave;
+ int high, low;
- intrsave = save_intr();
- disable_intr();
- CLOCK_LOCK();
+ mtx_enter(&clock_lock, MTX_SPIN);
/* Select timer0 and latch counter value. */
outb(TIMER_MODE, TIMER_SEL0 | TIMER_LATCH);
@@ -420,8 +410,7 @@ getit(void)
low = inb(TIMER_CNTR0);
high = inb(TIMER_CNTR0);
- CLOCK_UNLOCK();
- restore_intr(intrsave);
+ mtx_exit(&clock_lock, MTX_SPIN);
return ((high << 8) | low);
}
@@ -527,7 +516,6 @@ sysbeepstop(void *chan)
int
sysbeep(int pitch, int period)
{
- int intrsave;
int x = splclock();
if (acquire_timer2(TIMER_SQWAVE|TIMER_16BIT))
@@ -536,13 +524,10 @@ sysbeep(int pitch, int period)
splx(x);
return (-1); /* XXX Should be EBUSY, but nobody cares anyway. */
}
- intrsave = save_intr();
- disable_intr();
- CLOCK_LOCK();
+ mtx_enter(&clock_lock, MTX_SPIN);
outb(TIMER_CNTR2, pitch);
outb(TIMER_CNTR2, (pitch>>8));
- CLOCK_UNLOCK();
- restore_intr(intrsave);
+ mtx_exit(&clock_lock, MTX_SPIN);
if (!beeping) {
/* enable counter2 output to speaker */
outb(IO_PPI, inb(IO_PPI) | 3);
@@ -691,12 +676,9 @@ fail:
static void
set_timer_freq(u_int freq, int intr_freq)
{
- int intrsave;
int new_timer0_max_count;
- intrsave = save_intr();
- disable_intr();
- CLOCK_LOCK();
+ mtx_enter(&clock_lock, MTX_SPIN);
timer_freq = freq;
new_timer0_max_count = hardclock_max_count = TIMER_DIV(intr_freq);
if (new_timer0_max_count != timer0_max_count) {
@@ -705,8 +687,7 @@ set_timer_freq(u_int freq, int intr_freq)
outb(TIMER_CNTR0, timer0_max_count & 0xff);
outb(TIMER_CNTR0, timer0_max_count >> 8);
}
- CLOCK_UNLOCK();
- restore_intr(intrsave);
+ mtx_exit(&clock_lock, MTX_SPIN);
}
/*
@@ -720,16 +701,12 @@ set_timer_freq(u_int freq, int intr_freq)
void
i8254_restore(void)
{
- int intrsave;
- intrsave = save_intr();
- disable_intr();
- CLOCK_LOCK();
+ mtx_enter(&clock_lock, MTX_SPIN);
outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT);
outb(TIMER_CNTR0, timer0_max_count & 0xff);
outb(TIMER_CNTR0, timer0_max_count >> 8);
- CLOCK_UNLOCK();
- restore_intr(intrsave);
+ mtx_exit(&clock_lock, MTX_SPIN);
}
/*
@@ -989,8 +966,8 @@ cpu_initclocks()
{
int diag;
#ifdef APIC_IO
- int apic_8254_trial, num_8254_ticks;
- struct intrec *clkdesc, *rtcdesc;
+ int apic_8254_trial;
+ struct intrec *clkdesc;
#endif /* APIC_IO */
if (statclock_disable) {
@@ -1023,6 +1000,11 @@ cpu_initclocks()
} else
panic("APIC_IO: Cannot route 8254 interrupt to CPU");
}
+
+ clkdesc = inthand_add("clk", apic_8254_intr, (driver_intr_t *)clkintr,
+ NULL, PI_REALTIME, INTR_FAST);
+ INTREN(1 << apic_8254_intr);
+
#else /* APIC_IO */
/*
@@ -1030,9 +1012,8 @@ cpu_initclocks()
* couldn't find anything suitable in the BSD/OS code (grog,
* 19 July 2000).
*/
- /* Setup the PIC clk handler. The APIC handler is setup later */
inthand_add("clk", 0, (driver_intr_t *)clkintr, NULL, PI_REALTIME,
- INTR_EXCL);
+ INTR_FAST);
INTREN(IRQ0);
#endif /* APIC_IO */
@@ -1042,18 +1023,8 @@ cpu_initclocks()
writertc(RTC_STATUSB, RTCSB_24HR);
/* Don't bother enabling the statistics clock. */
- if (statclock_disable) {
-#ifdef APIC_IO
- /*
- * XXX - if statclock is disabled, don't attempt the APIC
- * trial. Not sure this is sane for APIC_IO.
- */
- inthand_add("clk", apic_8254_intr, (driver_intr_t *)clkintr,
- NULL, PI_REALTIME, INTR_EXCL);
- INTREN(1 << apic_8254_intr);
-#endif /* APIC_IO */
+ if (statclock_disable)
return;
- }
diag = rtcin(RTC_DIAG);
if (diag != 0)
printf("RTC BIOS diagnostic error %b\n", diag, RTCDG_BITS);
@@ -1061,44 +1032,34 @@ cpu_initclocks()
#ifdef APIC_IO
if (isa_apic_irq(8) != 8)
panic("APIC RTC != 8");
+#endif /* APIC_IO */
- if (apic_8254_trial) {
- /*
- * XXX - We use fast interrupts for clk and rtc long enough to
- * perform the APIC probe and then revert to exclusive
- * interrupts.
- */
- clkdesc = inthand_add("clk", apic_8254_intr,
- (driver_intr_t *)clkintr, NULL, PI_REALTIME, INTR_FAST);
- INTREN(1 << apic_8254_intr);
+ inthand_add("rtc", 8, (driver_intr_t *)rtcintr, NULL, PI_REALTIME,
+ INTR_FAST);
- rtcdesc = inthand_add("rtc", 8, (driver_intr_t *)rtcintr, NULL,
- PI_REALTIME, INTR_FAST); /* XXX */
- INTREN(APIC_IRQ8);
- writertc(RTC_STATUSB, rtc_statusb);
+#ifdef APIC_IO
+ INTREN(APIC_IRQ8);
+#else
+ INTREN(IRQ8);
+#endif /* APIC_IO */
+
+ writertc(RTC_STATUSB, rtc_statusb);
+
+#ifdef APIC_IO
+ if (apic_8254_trial) {
printf("APIC_IO: Testing 8254 interrupt delivery\n");
while (read_intr_count(8) < 6)
; /* nothing */
- num_8254_ticks = read_intr_count(apic_8254_intr);
-
- /* disable and remove our fake handlers */
- INTRDIS(1 << apic_8254_intr);
- inthand_remove(clkdesc);
-
- writertc(RTC_STATUSA, rtc_statusa);
- writertc(RTC_STATUSB, RTCSB_24HR);
-
- INTRDIS(APIC_IRQ8);
- inthand_remove(rtcdesc);
-
- if (num_8254_ticks < 3) {
+ if (read_intr_count(apic_8254_intr) < 3) {
/*
* The MP table is broken.
* The 8254 was not connected to the specified pin
* on the IO APIC.
* Workaround: Limited variant of mixed mode.
*/
+ INTRDIS(1 << apic_8254_intr);
+ inthand_remove(clkdesc);
printf("APIC_IO: Broken MP table detected: "
"8254 is not connected to "
"IOAPIC #%d intpin %d\n",
@@ -1117,27 +1078,13 @@ cpu_initclocks()
}
apic_8254_intr = apic_irq(0, 0);
setup_8254_mixed_mode();
+ inthand_add("clk", apic_8254_intr,
+ (driver_intr_t *)clkintr, NULL,
+ PI_REALTIME, INTR_FAST);
+ INTREN(1 << apic_8254_intr);
}
}
-
- /* Finally, setup the real clock handlers */
- inthand_add("clk", apic_8254_intr, (driver_intr_t *)clkintr, NULL,
- PI_REALTIME, INTR_EXCL);
- INTREN(1 << apic_8254_intr);
-#endif
-
- inthand_add("rtc", 8, (driver_intr_t *)rtcintr, NULL, PI_REALTIME,
- INTR_EXCL);
-#ifdef APIC_IO
- INTREN(APIC_IRQ8);
-#else
- INTREN(IRQ8);
-#endif
-
- writertc(RTC_STATUSB, rtc_statusb);
-
-#ifdef APIC_IO
if (apic_int_type(0, 0) != 3 ||
int_to_apicintpin[apic_8254_intr].ioapic != 0 ||
int_to_apicintpin[apic_8254_intr].int_pin != 0)
@@ -1242,12 +1189,11 @@ static unsigned
i8254_get_timecount(struct timecounter *tc)
{
u_int count;
- int intrsave;
u_int high, low;
+ u_int eflags;
- intrsave = save_intr();
- disable_intr();
- CLOCK_LOCK();
+ eflags = read_eflags();
+ mtx_enter(&clock_lock, MTX_SPIN);
/* Select timer0 and latch counter value. */
outb(TIMER_MODE, TIMER_SEL0 | TIMER_LATCH);
@@ -1257,7 +1203,7 @@ i8254_get_timecount(struct timecounter *tc)
count = timer0_max_count - ((high << 8) | low);
if (count < i8254_lastcount ||
(!i8254_ticked && (clkintr_pending ||
- ((count < 20 || (!(intrsave & PSL_I) && count < timer0_max_count / 2u)) &&
+ ((count < 20 || (!(eflags & PSL_I) && count < timer0_max_count / 2u)) &&
#ifdef APIC_IO
#define lapic_irr1 ((volatile u_int *)&lapic)[0x210 / 4] /* XXX XXX */
/* XXX this assumes that apic_8254_intr is < 24. */
@@ -1271,8 +1217,7 @@ i8254_get_timecount(struct timecounter *tc)
}
i8254_lastcount = count;
count += i8254_offset;
- CLOCK_UNLOCK();
- restore_intr(intrsave);
+ mtx_exit(&clock_lock, MTX_SPIN);
return (count);
}
diff --git a/sys/kern/kern_clock.c b/sys/kern/kern_clock.c
index bc6bf06..6b3153f 100644
--- a/sys/kern/kern_clock.c
+++ b/sys/kern/kern_clock.c
@@ -58,7 +58,9 @@
#include <sys/sysctl.h>
#include <machine/cpu.h>
+#include <machine/ipl.h>
#include <machine/limits.h>
+#include <machine/mutex.h>
#include <machine/smp.h>
#ifdef GPROF
@@ -161,11 +163,15 @@ hardclock(frame)
pstats = p->p_stats;
if (CLKF_USERMODE(frame) &&
timevalisset(&pstats->p_timer[ITIMER_VIRTUAL].it_value) &&
- itimerdecr(&pstats->p_timer[ITIMER_VIRTUAL], tick) == 0)
- psignal(p, SIGVTALRM);
+ itimerdecr(&pstats->p_timer[ITIMER_VIRTUAL], tick) == 0) {
+ p->p_flag |= P_ALRMPEND;
+ aston();
+ }
if (timevalisset(&pstats->p_timer[ITIMER_PROF].it_value) &&
- itimerdecr(&pstats->p_timer[ITIMER_PROF], tick) == 0)
- psignal(p, SIGPROF);
+ itimerdecr(&pstats->p_timer[ITIMER_PROF], tick) == 0) {
+ p->p_flag |= P_PROFPEND;
+ aston();
+ }
}
#if defined(SMP) && defined(BETTER_CLOCK)
@@ -186,15 +192,7 @@ hardclock(frame)
* relatively high clock interrupt priority any longer than necessary.
*/
if (TAILQ_FIRST(&callwheel[ticks & callwheelmask]) != NULL) {
- if (CLKF_BASEPRI(frame)) {
- /*
- * Save the overhead of a software interrupt;
- * it will happen as soon as we return, so do it now.
- */
- (void)splsoftclock();
- softclock();
- } else
- setsoftclock();
+ setsoftclock();
} else if (softticks + 1 == ticks)
++softticks;
}
@@ -321,20 +319,24 @@ statclock(frame)
struct rusage *ru;
struct vmspace *vm;
+ mtx_enter(&sched_lock, MTX_SPIN);
+
if (CLKF_USERMODE(frame)) {
/*
* Came from user mode; CPU was in user state.
* If this process is being profiled, record the tick.
*/
- p = prevproc;
+ p = curproc;
if (p->p_flag & P_PROFIL)
addupc_intr(p, CLKF_PC(frame), 1);
#if defined(SMP) && defined(BETTER_CLOCK)
if (stathz != 0)
forward_statclock(pscnt);
#endif
- if (--pscnt > 0)
+ if (--pscnt > 0) {
+ mtx_exit(&sched_lock, MTX_SPIN);
return;
+ }
/*
* Charge the time as appropriate.
*/
@@ -361,8 +363,10 @@ statclock(frame)
if (stathz != 0)
forward_statclock(pscnt);
#endif
- if (--pscnt > 0)
+ if (--pscnt > 0) {
+ mtx_exit(&sched_lock, MTX_SPIN);
return;
+ }
/*
* Came from kernel mode, so we were:
* - handling an interrupt,
@@ -375,8 +379,8 @@ statclock(frame)
* so that we know how much of its real time was spent
* in ``non-process'' (i.e., interrupt) work.
*/
- p = prevproc;
- if (p->p_ithd) {
+ p = curproc;
+ if ((p->p_ithd != NULL) || CLKF_INTR(frame)) {
p->p_iticks++;
cp_time[CP_INTR]++;
} else {
@@ -402,6 +406,8 @@ statclock(frame)
if (ru->ru_maxrss < rss)
ru->ru_maxrss = rss;
}
+
+ mtx_exit(&sched_lock, MTX_SPIN);
}
/*
diff --git a/sys/kern/kern_synch.c b/sys/kern/kern_synch.c
index eeddeb6..3031334 100644
--- a/sys/kern/kern_synch.c
+++ b/sys/kern/kern_synch.c
@@ -289,6 +289,7 @@ schedcpu(arg)
if (p->p_stat == SWAIT)
continue;
*/
+ mtx_enter(&sched_lock, MTX_SPIN);
p->p_swtime++;
if (p->p_stat == SSLEEP || p->p_stat == SSTOP)
p->p_slptime++;
@@ -297,13 +298,15 @@ schedcpu(arg)
* If the process has slept the entire second,
* stop recalculating its priority until it wakes up.
*/
- if (p->p_slptime > 1)
+ if (p->p_slptime > 1) {
+ mtx_exit(&sched_lock, MTX_SPIN);
continue;
+ }
+
/*
* prevent state changes and protect run queue
*/
s = splhigh();
- mtx_enter(&sched_lock, MTX_SPIN);
/*
* p_pctcpu is only for ps.
@@ -451,9 +454,6 @@ msleep(ident, mtx, priority, wmesg, timo)
* in case this is the idle process and already asleep.
*/
mtx_exit(&sched_lock, MTX_SPIN);
-#if 0
- splx(safepri);
-#endif
splx(s);
return (0);
}
@@ -994,7 +994,6 @@ setrunnable(p)
p->p_stat = SRUN;
if (p->p_flag & P_INMEM)
setrunqueue(p);
- mtx_exit(&sched_lock, MTX_SPIN);
splx(s);
if (p->p_slptime > 1)
updatepri(p);
@@ -1005,6 +1004,7 @@ setrunnable(p)
}
else
maybe_resched(p);
+ mtx_exit(&sched_lock, MTX_SPIN);
}
/*
@@ -1018,6 +1018,7 @@ resetpriority(p)
{
register unsigned int newpriority;
+ mtx_enter(&sched_lock, MTX_SPIN);
if (p->p_rtprio.type == RTP_PRIO_NORMAL) {
newpriority = PUSER + p->p_estcpu / INVERSE_ESTCPU_WEIGHT +
NICE_WEIGHT * (p->p_nice - PRIO_MIN);
@@ -1025,6 +1026,7 @@ resetpriority(p)
p->p_usrpri = newpriority;
}
maybe_resched(p);
+ mtx_exit(&sched_lock, MTX_SPIN);
}
/* ARGSUSED */
diff --git a/sys/kern/subr_smp.c b/sys/kern/subr_smp.c
index ea9aee8..5ef95b3 100644
--- a/sys/kern/subr_smp.c
+++ b/sys/kern/subr_smp.c
@@ -1900,11 +1900,6 @@ struct simplelock mcount_lock;
struct simplelock com_lock;
#endif /* USE_COMLOCK */
-#ifdef USE_CLOCKLOCK
-/* lock regions around the clock hardware */
-struct simplelock clock_lock;
-#endif /* USE_CLOCKLOCK */
-
/* lock around the MP rendezvous */
static struct simplelock smp_rv_lock;
@@ -1930,9 +1925,6 @@ init_locks(void)
#ifdef USE_COMLOCK
s_lock_init((struct simplelock*)&com_lock);
#endif /* USE_COMLOCK */
-#ifdef USE_CLOCKLOCK
- s_lock_init((struct simplelock*)&clock_lock);
-#endif /* USE_CLOCKLOCK */
s_lock_init(&ap_boot_lock);
}
@@ -2425,7 +2417,6 @@ ap_init(void)
* something unique to lock with.
*/
PCPU_SET(curproc,idleproc);
- PCPU_SET(prevproc,idleproc);
microuptime(&switchtime);
switchticks = ticks;
diff --git a/sys/kern/subr_trap.c b/sys/kern/subr_trap.c
index 1cbfcfa..b9ebb60 100644
--- a/sys/kern/subr_trap.c
+++ b/sys/kern/subr_trap.c
@@ -1244,6 +1244,18 @@ ast(frame)
addupc_task(p, p->p_stats->p_prof.pr_addr,
p->p_stats->p_prof.pr_ticks);
}
+ if (p->p_flag & P_ALRMPEND) {
+ if (!mtx_owned(&Giant))
+ mtx_enter(&Giant, MTX_DEF);
+ p->p_flag &= ~P_ALRMPEND;
+ psignal(p, SIGVTALRM);
+ }
+ if (p->p_flag & P_PROFPEND) {
+ if (!mtx_owned(&Giant))
+ mtx_enter(&Giant, MTX_DEF);
+ p->p_flag &= ~P_PROFPEND;
+ psignal(p, SIGPROF);
+ }
if (userret(p, &frame, sticks, mtx_owned(&Giant)) != 0)
mtx_exit(&Giant, MTX_DEF);
}
diff --git a/sys/powerpc/include/globals.h b/sys/powerpc/include/globals.h
index 303efdf..f85a67c 100644
--- a/sys/powerpc/include/globals.h
+++ b/sys/powerpc/include/globals.h
@@ -56,7 +56,6 @@ register struct globaldata *globalp __asm__("$8");
#define switchtime PCPU_GET(switchtime)
#define switchticks PCPU_GET(switchticks)
#define cpuid PCPU_GET(cpuno)
-#define prevproc PCPU_GET(curproc) /* XXX - until ithreads */
#endif /* _KERNEL */
diff --git a/sys/sys/proc.h b/sys/sys/proc.h
index 1f75150..3a14e34 100644
--- a/sys/sys/proc.h
+++ b/sys/sys/proc.h
@@ -273,6 +273,7 @@ struct proc {
#define P_ADVLOCK 0x00001 /* Process may hold a POSIX advisory lock. */
#define P_CONTROLT 0x00002 /* Has a controlling terminal. */
#define P_INMEM 0x00004 /* Loaded into memory. */
+#define P_NOLOAD 0x00008 /* Ignore during load avg calculations. */
#define P_PPWAIT 0x00010 /* Parent is waiting for child to exec/exit. */
#define P_PROFIL 0x00020 /* Has started profiling. */
#define P_SELECT 0x00040 /* Selecting; wakeup/waiting danger. */
@@ -284,7 +285,8 @@ struct proc {
#define P_WAITED 0x01000 /* Debugging process has waited for child. */
#define P_WEXIT 0x02000 /* Working on exiting. */
#define P_EXEC 0x04000 /* Process called exec. */
-#define P_NOLOAD 0x08000 /* Ignore during load avg calculations. */
+#define P_ALRMPEND 0x08000 /* Pending SIGVTALRM needs to be posted. */
+#define P_PROFPEND 0x08000 /* Pending SIGPROF needs to be posted. */
/* Should probably be changed into a hold count. */
/* was P_NOSWAP 0x08000 was: Do not swap upages; p->p_hold */
OpenPOWER on IntegriCloud