summaryrefslogtreecommitdiffstats
path: root/sys/i386/isa/npx.c
diff options
context:
space:
mode:
authorpeter <peter@FreeBSD.org>1997-04-26 11:46:25 +0000
committerpeter <peter@FreeBSD.org>1997-04-26 11:46:25 +0000
commit6323aa10bffe459912ba8b2f8592c7ac4ffd8705 (patch)
treebf48960e09e26f0de373de093c89322724bbdd64 /sys/i386/isa/npx.c
parent96efe480c0c091aecb2f359675c74aca30f36a4a (diff)
downloadFreeBSD-src-6323aa10bffe459912ba8b2f8592c7ac4ffd8705.zip
FreeBSD-src-6323aa10bffe459912ba8b2f8592c7ac4ffd8705.tar.gz
Man the liferafts! Here comes the long awaited SMP -> -current merge!
There are various options documented in i386/conf/LINT, there is more to come over the next few days. The kernel should run pretty much "as before" without the options to activate SMP mode. There are a handful of known "loose ends" that need to be fixed, but have been put off since the SMP kernel is in a moderately good condition at the moment. This commit is the result of the tinkering and testing over the last 14 months by many people. A special thanks to Steve Passe for implementing the APIC code!
Diffstat (limited to 'sys/i386/isa/npx.c')
-rw-r--r--sys/i386/isa/npx.c75
1 files changed, 72 insertions, 3 deletions
diff --git a/sys/i386/isa/npx.c b/sys/i386/isa/npx.c
index 6e3f5c7..402b1ce 100644
--- a/sys/i386/isa/npx.c
+++ b/sys/i386/isa/npx.c
@@ -32,7 +32,7 @@
* SUCH DAMAGE.
*
* from: @(#)npx.c 7.2 (Berkeley) 5/12/91
- * $Id: npx.c,v 1.40 1997/03/24 11:23:58 bde Exp $
+ * $Id: npx.c,v 1.41 1997/04/22 06:55:38 jdp Exp $
*/
#include "npx.h"
@@ -40,6 +40,7 @@
#include "opt_cpu.h"
#include "opt_math_emulate.h"
+#include "opt_smp.h"
#include <sys/param.h>
#include <sys/systm.h>
@@ -60,6 +61,10 @@
#include <machine/trap.h>
#include <machine/clock.h>
#include <machine/specialreg.h>
+#if defined(APIC_IO)
+#include <machine/apic.h>
+#include <machine/mpapic.h>
+#endif /* APIC_IO */
#include <i386/isa/icu.h>
#include <i386/isa/isa_device.h>
@@ -133,7 +138,12 @@ SYSCTL_INT(_hw,HW_FLOATINGPT, floatingpoint,
"Floatingpoint instructions executed in hardware");
static u_int npx0_imask = SWI_CLOCK_MASK;
+#ifdef SMP
+#define npxproc (SMPnpxproc[cpunumber()])
+struct proc *SMPnpxproc[NCPU];
+#else
struct proc *npxproc;
+#endif
static bool_t npx_ex16;
static bool_t npx_exists;
@@ -148,8 +158,28 @@ static volatile u_int npx_traps_while_probing;
* interrupts. We'll still need a special exception 16 handler. The busy
* latch stuff in probeintr() can be moved to npxprobe().
*/
-
inthand_t probeintr;
+
+#if defined(APIC_IO)
+
+asm
+("
+ .text
+ .p2align 2,0x90
+" __XSTRING(CNAME(probeintr)) ":
+ ss
+ incl " __XSTRING(CNAME(npx_intrs_while_probing)) "
+ pushl %eax
+ movl " __XSTRING(CNAME(apic_base)) ",%eax # EOI to local APIC
+ movl $0,0xb0(,%eax,1) # movl $0, APIC_EOI(%eax)
+ movb $0,%al
+ outb %al,$0xf0 # clear BUSY# latch
+ popl %eax
+ iret
+");
+
+#else
+
asm
("
.text
@@ -167,6 +197,8 @@ asm
iret
");
+#endif /* APIC_IO */
+
inthand_t probetrap;
asm
("
@@ -191,8 +223,12 @@ npxprobe(dvp)
{
int result;
u_long save_eflags;
+#if defined(APIC_IO)
+ u_int save_apic_mask;
+#else
u_char save_icu1_mask;
u_char save_icu2_mask;
+#endif /* APIC_IO */
struct gate_descriptor save_idt_npxintr;
struct gate_descriptor save_idt_npxtrap;
/*
@@ -205,20 +241,32 @@ npxprobe(dvp)
npx_intrno = NRSVIDT + ffs(dvp->id_irq) - 1;
save_eflags = read_eflags();
disable_intr();
+#if defined(APIC_IO)
+ save_apic_mask = INTRGET();
+#else
save_icu1_mask = inb(IO_ICU1 + 1);
save_icu2_mask = inb(IO_ICU2 + 1);
+#endif /* APIC_IO */
save_idt_npxintr = idt[npx_intrno];
save_idt_npxtrap = idt[16];
+#if defined(APIC_IO)
+ INTRSET( ~dvp->id_irq );
+#else
outb(IO_ICU1 + 1, ~(IRQ_SLAVE | dvp->id_irq));
outb(IO_ICU2 + 1, ~(dvp->id_irq >> 8));
+#endif /* APIC_IO */
setidt(16, probetrap, SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
setidt(npx_intrno, probeintr, SDT_SYS386IGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
npx_idt_probeintr = idt[npx_intrno];
enable_intr();
result = npxprobe1(dvp);
disable_intr();
+#if defined(APIC_IO)
+ INTRSET( save_apic_mask );
+#else
outb(IO_ICU1 + 1, save_icu1_mask);
outb(IO_ICU2 + 1, save_icu2_mask);
+#endif /* APIC_IO */
idt[npx_intrno] = save_idt_npxintr;
idt[16] = save_idt_npxtrap;
write_eflags(save_eflags);
@@ -364,7 +412,8 @@ npxattach(dvp)
}
npxinit(__INITIAL_NPXCW__);
-#ifdef I586_CPU
+#if defined(I586_CPU) && !defined(SMP)
+ /* FPU not working under SMP yet */
if (cpu_class == CPUCLASS_586 && npx_ex16) {
if (!(dvp->id_flags & NPX_DISABLE_I586_OPTIMIZED_BCOPY)) {
bcopy_vector = i586_bcopy;
@@ -576,18 +625,32 @@ void
npxsave(addr)
struct save87 *addr;
{
+#if defined(APIC_IO)
+ u_int apic_mask;
+ u_int old_apic_mask;
+#else
u_char icu1_mask;
u_char icu2_mask;
u_char old_icu1_mask;
u_char old_icu2_mask;
+#endif /* APIC_IO */
struct gate_descriptor save_idt_npxintr;
disable_intr();
+#if defined(APIC_IO)
+ old_apic_mask = INTRGET();
+#else
old_icu1_mask = inb(IO_ICU1 + 1);
old_icu2_mask = inb(IO_ICU2 + 1);
+#endif /* APIC_IO */
save_idt_npxintr = idt[npx_intrno];
+#if defined(APIC_IO)
+ /** FIXME: try clrIoApicMaskBit( npx0_imask ); */
+ INTRSET( old_apic_mask & ~(npx0_imask & 0xffff) );
+#else
outb(IO_ICU1 + 1, old_icu1_mask & ~(IRQ_SLAVE | npx0_imask));
outb(IO_ICU2 + 1, old_icu2_mask & ~(npx0_imask >> 8));
+#endif /* APIC_IO */
idt[npx_intrno] = npx_idt_probeintr;
enable_intr();
stop_emulating();
@@ -596,6 +659,11 @@ npxsave(addr)
start_emulating();
npxproc = NULL;
disable_intr();
+#if defined(APIC_IO)
+ apic_mask = INTRGET(); /* masks may have changed */
+ INTRSET( (apic_mask & ~(npx0_imask & 0xffff)) |
+ (old_apic_mask & (npx0_imask & 0xffff)));
+#else
icu1_mask = inb(IO_ICU1 + 1); /* masks may have changed */
icu2_mask = inb(IO_ICU2 + 1);
outb(IO_ICU1 + 1,
@@ -603,6 +671,7 @@ npxsave(addr)
outb(IO_ICU2 + 1,
(icu2_mask & ~(npx0_imask >> 8))
| (old_icu2_mask & (npx0_imask >> 8)));
+#endif /* APIC_IO */
idt[npx_intrno] = save_idt_npxintr;
enable_intr(); /* back to usual state */
}
OpenPOWER on IntegriCloud