diff options
author | peter <peter@FreeBSD.org> | 1997-04-26 11:46:25 +0000 |
---|---|---|
committer | peter <peter@FreeBSD.org> | 1997-04-26 11:46:25 +0000 |
commit | 6323aa10bffe459912ba8b2f8592c7ac4ffd8705 (patch) | |
tree | bf48960e09e26f0de373de093c89322724bbdd64 /sys/amd64/isa/npx.c | |
parent | 96efe480c0c091aecb2f359675c74aca30f36a4a (diff) | |
download | FreeBSD-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/amd64/isa/npx.c')
-rw-r--r-- | sys/amd64/isa/npx.c | 75 |
1 files changed, 72 insertions, 3 deletions
diff --git a/sys/amd64/isa/npx.c b/sys/amd64/isa/npx.c index 6e3f5c7..402b1ce 100644 --- a/sys/amd64/isa/npx.c +++ b/sys/amd64/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 */ } |