diff options
73 files changed, 1579 insertions, 1731 deletions
diff --git a/sys/amd64/amd64/apic_vector.S b/sys/amd64/amd64/apic_vector.S index 0817521..fa7edb0 100644 --- a/sys/amd64/amd64/apic_vector.S +++ b/sys/amd64/amd64/apic_vector.S @@ -1,6 +1,6 @@ /* * from: vector.s, 386BSD 0.1 unknown origin - * $Id: apic_vector.s,v 1.1 1997/05/26 17:58:26 fsmp Exp $ + * $Id: apic_vector.s,v 1.2 1997/05/31 08:59:51 peter Exp $ */ @@ -11,19 +11,19 @@ #define REDTBL_IDX(irq_num) (0x10 + ((irq_num) * 2)) /* - * 'lazy masking' code submitted by: Bruce Evans <bde@zeta.org.au> + * 'lazy masking' code suggested by Bruce Evans <bde@zeta.org.au> */ #define MAYBE_MASK_IRQ(irq_num) \ testl $IRQ_BIT(irq_num),iactive ; /* lazy masking */ \ je 1f ; /* NOT currently active */ \ orl $IRQ_BIT(irq_num),_imen ; /* set the mask bit */ \ - movl _io_apic_base,%ecx ; /* io apic addr */ \ + movl _ioapic,%ecx ; /* ioapic[0]addr */ \ movl $REDTBL_IDX(irq_num),(%ecx) ; /* write the index */ \ movl IOAPIC_WINDOW(%ecx),%eax ; /* current value */ \ orl $IOART_INTMASK,%eax ; /* set the mask */ \ movl %eax,IOAPIC_WINDOW(%ecx) ; /* new value */ \ - movl _apic_base, %eax ; \ - movl $0, APIC_EOI(%eax) ; \ + movl $lapic_eoi, %eax ; \ + movl $0, (%eax) ; \ orl $IRQ_BIT(irq_num), _ipending ; \ REL_MPLOCK ; /* SMP release global lock */ \ popl %es ; \ @@ -43,7 +43,7 @@ testl $IRQ_BIT(irq_num),_imen ; \ je 2f ; \ andl $~IRQ_BIT(irq_num),_imen ; /* clear mask bit */ \ - movl _io_apic_base,%ecx ; /* io apic addr */ \ + movl _ioapic,%ecx ; /* ioapic[0]addr */ \ movl $REDTBL_IDX(irq_num),(%ecx) ; /* write the index */ \ movl IOAPIC_WINDOW(%ecx),%eax ; /* current value */ \ andl $~IOART_INTMASK,%eax ; /* clear the mask */ \ @@ -72,8 +72,8 @@ IDTVEC(vec_name) ; \ GET_MPLOCK ; /* SMP Spin lock */ \ pushl _intr_unit + (irq_num) * 4 ; \ call *_intr_handler + (irq_num) * 4 ; /* do the work ASAP */ \ - movl _apic_base, %eax ; \ - movl $0, APIC_EOI(%eax) ; \ + movl $lapic_eoi, %eax ; \ + movl $0, (%eax) ; \ addl $4,%esp ; \ incl _cnt+V_INTR ; /* book-keeping can wait */ \ movl _intr_countp + (irq_num) * 4,%eax ; \ @@ -132,8 +132,8 @@ IDTVEC(vec_name) ; \ movl %ax,%es ; \ GET_MPLOCK ; /* SMP Spin lock */ \ MAYBE_MASK_IRQ(irq_num) ; \ - movl _apic_base, %eax ; \ - movl $0, APIC_EOI(%eax) ; \ + movl $lapic_eoi, %eax ; \ + movl $0, (%eax) ; \ movl _cpl,%eax ; \ testl $IRQ_BIT(irq_num), %eax ; \ jne 3f ; \ @@ -172,10 +172,9 @@ _Xinvltlb: pushl %eax movl %cr3, %eax /* invalidate the TLB */ movl %eax, %cr3 + movl $lapic_eoi, %eax ss /* stack segment, avoid %ds load */ - movl _apic_base, %eax - ss - movl $0, APIC_EOI(%eax) /* End Of Interrupt to APIC */ + movl $0, (%eax) /* End Of Interrupt to APIC */ popl %eax iret diff --git a/sys/amd64/amd64/cpu_switch.S b/sys/amd64/amd64/cpu_switch.S index 923d694..eacef02 100644 --- a/sys/amd64/amd64/cpu_switch.S +++ b/sys/amd64/amd64/cpu_switch.S @@ -33,22 +33,21 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: swtch.s,v 1.51 1997/05/31 09:27:29 peter Exp $ + * $Id: swtch.s,v 1.52 1997/06/07 04:36:10 bde Exp $ */ #include "npx.h" #include "opt_user_ldt.h" -#include "opt_smp_privpages.h" #include <sys/rtprio.h> #include <machine/asmacros.h> #include <machine/ipl.h> -#include <machine/smpasm.h> #include <machine/smptests.h> /** TEST_LOPRIO */ -#if defined(SMP) && defined(SMP_PRIVPAGES) +#if defined(SMP) #include <machine/pmap.h> +#include <machine/apic.h> #endif #include "assym.s" @@ -250,7 +249,7 @@ _idle: #ifdef SMP movl _smp_active, %eax cmpl $0, %eax - jnz badsw + jnz badsw3 #endif /* SMP */ xorl %ebp,%ebp movl $HIDENAME(tmpstk),%esp @@ -258,12 +257,7 @@ _idle: movl %ecx,%cr3 /* update common_tss.tss_esp0 pointer */ -#ifdef SMP - GETCPUID(%eax) - movl _SMPcommon_tss_ptr(,%eax,4), %eax -#else movl $_common_tss, %eax -#endif movl %esp, TSS_ESP0(%eax) #ifdef TSS_IS_CACHED /* example only */ @@ -315,7 +309,7 @@ ENTRY(default_halt) ENTRY(cpu_switch) /* switch to new process. first, save context as needed */ - GETCURPROC(%ecx) + movl _curproc,%ecx /* if no process to save, don't bother */ testl %ecx,%ecx @@ -342,16 +336,15 @@ ENTRY(cpu_switch) #ifdef SMP movl _mp_lock, %eax cmpl $0xffffffff, %eax /* is it free? */ - je badsw /* yes, bad medicine! */ + je badsw4 /* yes, bad medicine! */ andl $0x00ffffff, %eax /* clear CPU portion */ movl %eax,PCB_MPNEST(%ecx) /* store it */ #endif /* SMP */ #if NNPX > 0 /* have we used fp, and need a save? */ - GETCURPROC(%eax) - GETNPXPROC(%ebx) - cmp %eax,%ebx + movl _curproc,%eax + cmpl %eax,_npxproc jne 1f addl $PCB_SAVEFPU,%ecx /* h/w bugs make saving complicated */ pushl %ecx @@ -362,7 +355,7 @@ ENTRY(cpu_switch) movb $1,_intr_nesting_level /* charge Intr, not Sys/Idle */ - SETCURPROC($0, %edi) + movl $0,_curproc /* out of process */ /* save is done, now choose a new process or idle */ sw1: @@ -451,16 +444,16 @@ swtch_com: #ifdef DIAGNOSTIC cmpl %eax,P_WCHAN(%ecx) - jne badsw + jne badsw1 cmpb $SRUN,P_STAT(%ecx) - jne badsw + jne badsw2 #endif movl %eax,P_BACK(%ecx) /* isolate process to run */ movl P_ADDR(%ecx),%edx movl PCB_CR3(%edx),%ebx -#if defined(SMP) && defined(SMP_PRIVPAGES) +#if defined(SMP) /* Grab the private PT pointer from the outgoing process's PTD */ movl $_PTD,%esi movl 4*MPPTDI(%esi), %eax /* fetch cpu's prv pt */ @@ -469,7 +462,7 @@ swtch_com: /* switch address space */ movl %ebx,%cr3 -#if defined(SMP) && defined(SMP_PRIVPAGES) +#if defined(SMP) /* Copy the private PT to the new process's PTD */ /* XXX yuck, the _PTD changes when we switch, so we have to * reload %cr3 after changing the address space. @@ -477,7 +470,6 @@ swtch_com: * location of the per-process PTD in the PCB or something quick. * Dereferencing proc->vm_map->pmap->p_pdir[] is painful in asm. */ - movl $_PTD,%esi movl %eax, 4*MPPTDI(%esi) /* restore cpu's prv page */ /* XXX: we have just changed the page tables.. reload.. */ @@ -499,12 +491,7 @@ swtch_com: #endif /* update common_tss.tss_esp0 pointer */ -#ifdef SMP - GETCPUID(%eax) - movl _SMPcommon_tss_ptr(,%eax,4), %eax -#else movl $_common_tss, %eax -#endif movl %edx, %ebx /* pcb */ addl $(UPAGES * PAGE_SIZE), %ebx movl %ebx, TSS_ESP0(%eax) @@ -527,25 +514,22 @@ swtch_com: movl %eax,(%esp) #ifdef SMP - GETCPUID(%eax) + movl _cpuid,%eax movb %al, P_ONCPU(%ecx) #endif - SETCURPCB(%edx, %eax) - SETCURPROC(%ecx, %eax) + movl %edx,_curpcb + movl %ecx,_curproc /* into next process */ movb $0,_intr_nesting_level #ifdef SMP - movl _apic_base, %eax /* base addr of LOCAL APIC */ #if defined(TEST_LOPRIO) - pushl %edx - movl APIC_TPR(%eax), %edx /* get TPR register contents */ - andl $~0xff, %edx /* clear the prio field */ - movl %edx, APIC_TPR(%eax) /* now hold loprio for INTs */ - popl %edx + /* Set us to prefer to get irq's from the apic since we have the lock */ + movl lapic_tpr, %eax /* get TPR register contents */ + andl $0xffffff00, %eax /* clear the prio field */ + movl %eax, lapic_tpr /* now hold loprio for INTs */ #endif /* TEST_LOPRIO */ - movl APIC_ID(%eax), %eax /* APIC ID register */ - andl $APIC_ID_MASK, %eax /* extract ID portion */ - orl PCB_MPNEST(%edx), %eax /* add count from PROC */ + movl _cpu_lockid,%eax + orl PCB_MPNEST(%edx), %eax /* add next count from PROC */ movl %eax, _mp_lock /* load the mp_lock */ #endif /* SMP */ @@ -579,11 +563,33 @@ CROSSJUMPTARGET(idqr) CROSSJUMPTARGET(nortqr) CROSSJUMPTARGET(sw1a) -badsw: - pushl $sw0 +#ifdef DIAGNOSTIC +badsw1: + pushl $sw0_1 + call _panic + +sw0_1: .asciz "cpu_switch: has wchan" + +badsw2: + pushl $sw0_2 + call _panic + +sw0_2: .asciz "cpu_switch: not SRUN" +#endif + +#ifdef SMP +badsw3: + pushl $sw0_3 call _panic -sw0: .asciz "cpu_switch" +sw0_3: .asciz "cpu_switch: went idle with smp_active" + +badsw4: + pushl $sw0_4 + call _panic + +sw0_4: .asciz "cpu_switch: do not have lock" +#endif /* * savectx(pcb) @@ -618,7 +624,7 @@ ENTRY(savectx) * have to handle h/w bugs for reloading. We used to lose the * parent's npx state for forks by forgetting to reload. */ - GETNPXPROC(%eax) + movl _npxproc,%eax testl %eax,%eax je 1f diff --git a/sys/amd64/amd64/exception.S b/sys/amd64/amd64/exception.S index 054e086..22ddf7f 100644 --- a/sys/amd64/amd64/exception.S +++ b/sys/amd64/amd64/exception.S @@ -30,7 +30,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: exception.s,v 1.28 1997/05/29 05:11:09 peter Exp $ + * $Id: exception.s,v 1.29 1997/05/31 09:27:28 peter Exp $ */ #include "npx.h" /* NNPX */ @@ -44,7 +44,7 @@ #include <sys/cdefs.h> /* CPP macros */ #ifdef SMP -#include <machine/smpasm.h> /* this includes <machine/apic.h> */ +#include <machine/apic.h> /* for apic_vector.s */ #define GET_MPLOCK call _get_mplock #define REL_MPLOCK call _rel_mplock #define MP_INSTR_LOCK lock @@ -270,13 +270,7 @@ ENTRY(fork_trampoline) movl $SWI_AST_MASK,_cpl call _splz -#ifdef SMP - GETCPUID(%eax) - leal _SMPruntime(,%eax,8), %eax - pushl %eax -#else pushl $_runtime -#endif /* SMP */ call _microtime popl %eax diff --git a/sys/amd64/amd64/exception.s b/sys/amd64/amd64/exception.s index 054e086..22ddf7f 100644 --- a/sys/amd64/amd64/exception.s +++ b/sys/amd64/amd64/exception.s @@ -30,7 +30,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: exception.s,v 1.28 1997/05/29 05:11:09 peter Exp $ + * $Id: exception.s,v 1.29 1997/05/31 09:27:28 peter Exp $ */ #include "npx.h" /* NNPX */ @@ -44,7 +44,7 @@ #include <sys/cdefs.h> /* CPP macros */ #ifdef SMP -#include <machine/smpasm.h> /* this includes <machine/apic.h> */ +#include <machine/apic.h> /* for apic_vector.s */ #define GET_MPLOCK call _get_mplock #define REL_MPLOCK call _rel_mplock #define MP_INSTR_LOCK lock @@ -270,13 +270,7 @@ ENTRY(fork_trampoline) movl $SWI_AST_MASK,_cpl call _splz -#ifdef SMP - GETCPUID(%eax) - leal _SMPruntime(,%eax,8), %eax - pushl %eax -#else pushl $_runtime -#endif /* SMP */ call _microtime popl %eax diff --git a/sys/amd64/amd64/fpu.c b/sys/amd64/amd64/fpu.c index aca74fa..14487c95 100644 --- a/sys/amd64/amd64/fpu.c +++ b/sys/amd64/amd64/fpu.c @@ -32,7 +32,7 @@ * SUCH DAMAGE. * * from: @(#)npx.c 7.2 (Berkeley) 5/12/91 - * $Id: npx.c,v 1.44 1997/05/31 09:27:31 peter Exp $ + * $Id: npx.c,v 1.45 1997/06/02 08:19:05 dfr Exp $ */ #include "npx.h" @@ -63,6 +63,7 @@ #include <machine/clock.h> #include <machine/specialreg.h> #if defined(APIC_IO) +#include <machine/smp.h> #include <machine/apic.h> #include <machine/mpapic.h> #endif /* APIC_IO */ @@ -140,10 +141,8 @@ 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 + +#ifndef SMP /* XXX per-cpu on smp */ struct proc *npxproc; #endif @@ -172,8 +171,8 @@ asm 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) + movl $lapic_eoi,%eax # EOI to local APIC + movl $0,(%eax) # movl $0, APIC_EOI(%eax) movb $0,%al outb %al,$0xf0 # clear BUSY# latch popl %eax diff --git a/sys/amd64/amd64/locore.S b/sys/amd64/amd64/locore.S index b35cac7..44ddcbb 100644 --- a/sys/amd64/amd64/locore.S +++ b/sys/amd64/amd64/locore.S @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * from: @(#)locore.s 7.3 (Berkeley) 5/13/91 - * $Id: locore.s,v 1.87 1997/05/15 19:12:56 tegge Exp $ + * $Id: locore.s,v 1.88 1997/05/29 05:11:09 peter Exp $ * * originally from: locore.s, by William F. Jolitz * @@ -47,8 +47,7 @@ #include "opt_cpu.h" #include "opt_ddb.h" #include "opt_userconfig.h" -#include "opt_smp_privpages.h" -#include "opt_serial.h" +#include "opt_smp.h" #include <sys/errno.h> #include <sys/syscall.h> @@ -60,9 +59,9 @@ #include <machine/pmap.h> #include <machine/specialreg.h> -#if defined(SMP) && defined(SMP_PRIVPAGES) +#ifdef SMP #include <machine/apic.h> -#endif /* SMP && PRIVPAGES */ +#endif /* SMP */ #include "assym.s" @@ -92,6 +91,31 @@ .set _APTD,_APTmap + (APTDPTDI * PAGE_SIZE) .set _APTDpde,_PTD + (APTDPTDI * PDESIZE) +#ifdef SMP + .globl _SMP_prvstart + .set _SMP_prvstart,(MPPTDI << PDRSHIFT) + + .globl _SMP_prvpage,_SMP_prvpt,_lapic,_SMP_ioapic + .set _SMP_prvpage,_SMP_prvstart + .set _SMP_prvpt,_SMP_prvstart + PAGE_SIZE + .set _lapic,_SMP_prvstart + (2 * PAGE_SIZE) + .set _SMP_ioapic,_SMP_prvstart + (16 * PAGE_SIZE) + + .globl _cpuid,_curproc,_curpcb,_npxproc,_runtime,_cpu_lockid + .globl _common_tss + .set _cpuid,_SMP_prvpage+0 + .set _curproc,_SMP_prvpage+4 + .set _curpcb,_SMP_prvpage+8 + .set _npxproc,_SMP_prvpage+12 + .set _runtime,_SMP_prvpage+16 /* 8 bytes struct timeval */ + .set _cpu_lockid,_SMP_prvpage+24 + .set _common_tss,_SMP_prvpage+28 /* 104 bytes long, next = 132 */ + +/* Fetch the .set's for the local apic */ +#include "i386/i386/mp_apicdefs.s" + +#endif + /* * Globals */ @@ -117,18 +141,21 @@ _bootinfo: .space BOOTINFO_SIZE /* bootinfo that we can handle */ _KERNend: .long 0 /* phys addr end of kernel (just after bss) */ physfree: .long 0 /* phys addr of next free page */ -#if defined(SMP) && defined(SMP_PRIVPAGES) +#ifdef SMP cpu0pp: .long 0 /* phys addr cpu0 private pg */ cpu0pt: .long 0 /* phys addr cpu0 private pt */ .globl _cpu0prvpage,_cpu0prvpt _cpu0prvpage: .long 0 /* relocated version */ _cpu0prvpt: .long 0 /* relocated version */ -#endif /* SMP && PRIVPAGES */ +#endif /* SMP */ .globl _IdlePTD _IdlePTD: .long 0 /* phys addr of kernel PTD */ +#ifdef SMP + .globl _KPTphys +#endif _KPTphys: .long 0 /* phys addr of kernel page tables */ .globl _proc0paddr @@ -769,7 +796,7 @@ over_symalloc: addl $KERNBASE, %esi movl %esi, R(_proc0paddr) -#if defined(SMP) && defined(SMP_PRIVPAGES) +#ifdef SMP /* Allocate cpu0's private data page */ ALLOCPAGES(1) movl %esi,R(cpu0pp) @@ -781,7 +808,7 @@ over_symalloc: movl %esi,R(cpu0pt) addl $KERNBASE, %esi movl %esi, R(_cpu0prvpt) /* relocated to KVM space */ -#endif /* SMP && SMP_PRIVPAGES */ +#endif /* SMP */ /* Map read-only from zero to the end of the kernel text section */ xorl %eax, %eax @@ -830,41 +857,35 @@ map_read_write: movl $ISA_HOLE_LENGTH>>PAGE_SHIFT, %ecx fillkptphys($PG_RW) -#if defined(SMP) && defined(SMP_PRIVPAGES) -/* Map cpu0's private page into global KVM */ +#ifdef SMP +/* Map cpu0's private page into global kmem (4K @ cpu0prvpage) */ movl R(cpu0pp), %eax movl $1, %ecx fillkptphys($PG_RW) -/* Map cpu0's private page table into global KVM */ +/* Map cpu0's private page table into global kmem FWIW */ movl R(cpu0pt), %eax movl $1, %ecx fillkptphys($PG_RW) -/* Map the private page into the private page table (4K @ 0xff80000) */ +/* Map the private page into the private page table into private space */ movl R(cpu0pp), %eax movl $0, %ebx /* pte offset = 0 */ movl $1, %ecx /* one private page coming right up */ fillkpt(R(cpu0pt), $PG_RW) -/* Map the default Local APIC address (4K @ 0xff801000) */ - movl $DEFAULT_APIC_BASE, %eax /* XXX just testing.. */ +/* Map the page table page into private space */ + movl R(cpu0pt), %eax movl $1, %ebx /* pte offset = 1 */ - movl $1, %ecx /* Bing! Local APIC appears */ - fillkpt(R(cpu0pt), $PG_RW|PG_N) - -/* Map the default IO APIC address (4K @ 0xff802000) */ - movl $DEFAULT_IO_APIC_BASE, %eax /* XXX just testing.. */ - movl $2, %ebx /* pte offset = 2 */ - movl $1, %ecx /* Bing! Local APIC appears */ - fillkpt(R(cpu0pt), $PG_RW|PG_N) + movl $1, %ecx /* one private pt coming right up */ + fillkpt(R(cpu0pt), $PG_RW) -/* ... and put the page table in the pde. */ +/* ... and put the page table table in the pde. */ movl R(cpu0pt), %eax movl $MPPTDI, %ebx movl $1, %ecx fillkpt(R(_IdlePTD), $PG_RW) -#endif /* SMP && SMP_PRIVPAGES */ +#endif /* SMP */ /* install a pde for temporary double map of bottom of VA */ movl R(_KPTphys), %eax diff --git a/sys/amd64/amd64/locore.s b/sys/amd64/amd64/locore.s index b35cac7..44ddcbb 100644 --- a/sys/amd64/amd64/locore.s +++ b/sys/amd64/amd64/locore.s @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * from: @(#)locore.s 7.3 (Berkeley) 5/13/91 - * $Id: locore.s,v 1.87 1997/05/15 19:12:56 tegge Exp $ + * $Id: locore.s,v 1.88 1997/05/29 05:11:09 peter Exp $ * * originally from: locore.s, by William F. Jolitz * @@ -47,8 +47,7 @@ #include "opt_cpu.h" #include "opt_ddb.h" #include "opt_userconfig.h" -#include "opt_smp_privpages.h" -#include "opt_serial.h" +#include "opt_smp.h" #include <sys/errno.h> #include <sys/syscall.h> @@ -60,9 +59,9 @@ #include <machine/pmap.h> #include <machine/specialreg.h> -#if defined(SMP) && defined(SMP_PRIVPAGES) +#ifdef SMP #include <machine/apic.h> -#endif /* SMP && PRIVPAGES */ +#endif /* SMP */ #include "assym.s" @@ -92,6 +91,31 @@ .set _APTD,_APTmap + (APTDPTDI * PAGE_SIZE) .set _APTDpde,_PTD + (APTDPTDI * PDESIZE) +#ifdef SMP + .globl _SMP_prvstart + .set _SMP_prvstart,(MPPTDI << PDRSHIFT) + + .globl _SMP_prvpage,_SMP_prvpt,_lapic,_SMP_ioapic + .set _SMP_prvpage,_SMP_prvstart + .set _SMP_prvpt,_SMP_prvstart + PAGE_SIZE + .set _lapic,_SMP_prvstart + (2 * PAGE_SIZE) + .set _SMP_ioapic,_SMP_prvstart + (16 * PAGE_SIZE) + + .globl _cpuid,_curproc,_curpcb,_npxproc,_runtime,_cpu_lockid + .globl _common_tss + .set _cpuid,_SMP_prvpage+0 + .set _curproc,_SMP_prvpage+4 + .set _curpcb,_SMP_prvpage+8 + .set _npxproc,_SMP_prvpage+12 + .set _runtime,_SMP_prvpage+16 /* 8 bytes struct timeval */ + .set _cpu_lockid,_SMP_prvpage+24 + .set _common_tss,_SMP_prvpage+28 /* 104 bytes long, next = 132 */ + +/* Fetch the .set's for the local apic */ +#include "i386/i386/mp_apicdefs.s" + +#endif + /* * Globals */ @@ -117,18 +141,21 @@ _bootinfo: .space BOOTINFO_SIZE /* bootinfo that we can handle */ _KERNend: .long 0 /* phys addr end of kernel (just after bss) */ physfree: .long 0 /* phys addr of next free page */ -#if defined(SMP) && defined(SMP_PRIVPAGES) +#ifdef SMP cpu0pp: .long 0 /* phys addr cpu0 private pg */ cpu0pt: .long 0 /* phys addr cpu0 private pt */ .globl _cpu0prvpage,_cpu0prvpt _cpu0prvpage: .long 0 /* relocated version */ _cpu0prvpt: .long 0 /* relocated version */ -#endif /* SMP && PRIVPAGES */ +#endif /* SMP */ .globl _IdlePTD _IdlePTD: .long 0 /* phys addr of kernel PTD */ +#ifdef SMP + .globl _KPTphys +#endif _KPTphys: .long 0 /* phys addr of kernel page tables */ .globl _proc0paddr @@ -769,7 +796,7 @@ over_symalloc: addl $KERNBASE, %esi movl %esi, R(_proc0paddr) -#if defined(SMP) && defined(SMP_PRIVPAGES) +#ifdef SMP /* Allocate cpu0's private data page */ ALLOCPAGES(1) movl %esi,R(cpu0pp) @@ -781,7 +808,7 @@ over_symalloc: movl %esi,R(cpu0pt) addl $KERNBASE, %esi movl %esi, R(_cpu0prvpt) /* relocated to KVM space */ -#endif /* SMP && SMP_PRIVPAGES */ +#endif /* SMP */ /* Map read-only from zero to the end of the kernel text section */ xorl %eax, %eax @@ -830,41 +857,35 @@ map_read_write: movl $ISA_HOLE_LENGTH>>PAGE_SHIFT, %ecx fillkptphys($PG_RW) -#if defined(SMP) && defined(SMP_PRIVPAGES) -/* Map cpu0's private page into global KVM */ +#ifdef SMP +/* Map cpu0's private page into global kmem (4K @ cpu0prvpage) */ movl R(cpu0pp), %eax movl $1, %ecx fillkptphys($PG_RW) -/* Map cpu0's private page table into global KVM */ +/* Map cpu0's private page table into global kmem FWIW */ movl R(cpu0pt), %eax movl $1, %ecx fillkptphys($PG_RW) -/* Map the private page into the private page table (4K @ 0xff80000) */ +/* Map the private page into the private page table into private space */ movl R(cpu0pp), %eax movl $0, %ebx /* pte offset = 0 */ movl $1, %ecx /* one private page coming right up */ fillkpt(R(cpu0pt), $PG_RW) -/* Map the default Local APIC address (4K @ 0xff801000) */ - movl $DEFAULT_APIC_BASE, %eax /* XXX just testing.. */ +/* Map the page table page into private space */ + movl R(cpu0pt), %eax movl $1, %ebx /* pte offset = 1 */ - movl $1, %ecx /* Bing! Local APIC appears */ - fillkpt(R(cpu0pt), $PG_RW|PG_N) - -/* Map the default IO APIC address (4K @ 0xff802000) */ - movl $DEFAULT_IO_APIC_BASE, %eax /* XXX just testing.. */ - movl $2, %ebx /* pte offset = 2 */ - movl $1, %ecx /* Bing! Local APIC appears */ - fillkpt(R(cpu0pt), $PG_RW|PG_N) + movl $1, %ecx /* one private pt coming right up */ + fillkpt(R(cpu0pt), $PG_RW) -/* ... and put the page table in the pde. */ +/* ... and put the page table table in the pde. */ movl R(cpu0pt), %eax movl $MPPTDI, %ebx movl $1, %ecx fillkpt(R(_IdlePTD), $PG_RW) -#endif /* SMP && SMP_PRIVPAGES */ +#endif /* SMP */ /* install a pde for temporary double map of bottom of VA */ movl R(_KPTphys), %eax diff --git a/sys/amd64/amd64/machdep.c b/sys/amd64/amd64/machdep.c index 19838a2..4456e42 100644 --- a/sys/amd64/amd64/machdep.c +++ b/sys/amd64/amd64/machdep.c @@ -35,7 +35,7 @@ * SUCH DAMAGE. * * from: @(#)machdep.c 7.4 (Berkeley) 6/3/91 - * $Id: machdep.c,v 1.249 1997/06/15 02:24:06 wollman Exp $ + * $Id: machdep.c,v 1.250 1997/06/22 15:47:07 peter Exp $ */ #include "apm.h" @@ -218,12 +218,6 @@ cpu_startup(dummy) * Good {morning,afternoon,evening,night}. */ printf(version); -#ifdef SMP -#if defined(LATE_START) - mp_start(); /* fire up the APs and APICs */ -#endif /* LATE_START */ - mp_announce(); -#endif /* SMP */ earlysetcpuclass(); startrtclock(); printcpuinfo(); @@ -402,6 +396,14 @@ again: printf("avail memory = %d (%dK bytes)\n", ptoa(cnt.v_free_count), ptoa(cnt.v_free_count) / 1024); +#ifdef SMP + /* + * OK, enough kmem_alloc/malloc state should be up, lets get on with it! + */ + mp_start(); /* fire up the APs and APICs */ + mp_announce(); +#endif /* SMP */ + /* * Set up buffers, so they can be used to read disk labels. */ @@ -787,8 +789,7 @@ struct region_descriptor r_gdt, r_idt; #endif #ifdef SMP -struct i386tss SMPcommon_tss[NCPU]; /* One tss per cpu */ -struct i386tss *SMPcommon_tss_ptr[NCPU]; /* for the benefit of asmp code */ +extern struct i386tss common_tss; /* One tss per cpu */ #else struct i386tss common_tss; #endif @@ -865,11 +866,7 @@ struct soft_segment_descriptor gdt_segs[ 0 /* limit granularity (byte/page units)*/ }, /* GPROC0_SEL 6 Proc 0 Tss Descriptor */ { -#ifdef SMP - (int) &SMPcommon_tss[0],/* segment base address */ -#else (int) &common_tss, /* segment base address */ -#endif sizeof(struct i386tss)-1,/* length - all address space */ SDT_SYS386TSS, /* segment type */ 0, /* segment descriptor priority level */ @@ -1055,12 +1052,11 @@ init386(first) #ifdef SMP /* - * Oh puke! + * Spin these up now. init_secondary() grabs them. We could use + * #for(x,y,z) / #endfor cpp directives if they existed. */ for (x = 0; x < NCPU; x++) { - SMPcommon_tss_ptr[x] = &SMPcommon_tss[x]; gdt_segs[NGDT + x] = gdt_segs[GPROC0_SEL]; - gdt_segs[NGDT + x].ssd_base = (int) SMPcommon_tss_ptr[x]; ssdtosd(&gdt_segs[NGDT + x], &gdt[NGDT + x].sd); } #endif @@ -1254,6 +1250,11 @@ init386(first) Maxmem = idp->id_msize / 4; #endif +#ifdef SMP + /* look for the MP hardware - needed for apic addresses */ + mp_probe(); +#endif + /* call pmap initialization to make new kernel address space */ pmap_bootstrap (first, 0); @@ -1383,40 +1384,18 @@ init386(first) avail_end + off, VM_PROT_ALL, TRUE); msgbufmapped = 1; -#ifdef SMP - /* look for the MP hardware */ - mp_probe(); - - /* make the initial tss so cpu can get interrupt stack on syscall! */ - for(x = 0; x < NCPU; x++) { - SMPcommon_tss[x].tss_esp0 = (int) proc0.p_addr + UPAGES*PAGE_SIZE; - SMPcommon_tss[x].tss_ss0 = GSEL(GDATA_SEL, SEL_KPL) ; - SMPcommon_tss[x].tss_ioopt = (sizeof SMPcommon_tss[x]) << 16; - } -#if 0 - /** XXX FIXME: - * We can't access the LOCAL APIC till mp_enable() runs. Since - * this is run by the BSP, cpunumber() should always equal 0 anyway. - */ - gsel_tss = GSEL(NGDT + cpunumber(), SEL_KPL); -#else - gsel_tss = GSEL(NGDT /** + 0 */, SEL_KPL); -#endif /** 0 */ - ltr(gsel_tss); -#else /* make an initial tss so cpu can get interrupt stack on syscall! */ common_tss.tss_esp0 = (int) proc0.p_addr + UPAGES*PAGE_SIZE; common_tss.tss_ss0 = GSEL(GDATA_SEL, SEL_KPL) ; common_tss.tss_ioopt = (sizeof common_tss) << 16; gsel_tss = GSEL(GPROC0_SEL, SEL_KPL); ltr(gsel_tss); -#endif /* SMP */ dblfault_tss.tss_esp = dblfault_tss.tss_esp0 = dblfault_tss.tss_esp1 = dblfault_tss.tss_esp2 = (int) &dblfault_stack[sizeof(dblfault_stack)]; dblfault_tss.tss_ss = dblfault_tss.tss_ss0 = dblfault_tss.tss_ss1 = dblfault_tss.tss_ss2 = GSEL(GDATA_SEL, SEL_KPL); - dblfault_tss.tss_cr3 = IdlePTD; + dblfault_tss.tss_cr3 = (int)IdlePTD; dblfault_tss.tss_eip = (int) dblfault_handler; dblfault_tss.tss_eflags = PSL_KERNEL; dblfault_tss.tss_ds = dblfault_tss.tss_es = dblfault_tss.tss_fs = @@ -1450,14 +1429,8 @@ init386(first) /* setup proc 0's pcb */ proc0.p_addr->u_pcb.pcb_flags = 0; - proc0.p_addr->u_pcb.pcb_cr3 = IdlePTD; + proc0.p_addr->u_pcb.pcb_cr3 = (int)IdlePTD; proc0.p_addr->u_pcb.pcb_mpnest = 1; - -#ifdef SMP -#if !defined(LATE_START) - mp_start(); /* fire up the APs and APICs */ -#endif /* LATE_START */ -#endif /* SMP */ } int diff --git a/sys/amd64/amd64/mp_machdep.c b/sys/amd64/amd64/mp_machdep.c index a27cf86..c817925 100644 --- a/sys/amd64/amd64/mp_machdep.c +++ b/sys/amd64/amd64/mp_machdep.c @@ -22,11 +22,10 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: mp_machdep.c,v 1.16 1997/05/29 05:58:41 fsmp Exp $ + * $Id: mp_machdep.c,v 1.17 1997/06/02 10:44:08 dfr Exp $ */ #include "opt_smp.h" -#include "opt_serial.h" #include <sys/param.h> /* for KERNBASE */ #include <sys/types.h> @@ -38,18 +37,21 @@ #include <vm/vm_param.h> /* for KERNBASE */ #include <vm/pmap.h> /* for KERNBASE */ #include <machine/pmap.h> /* for KERNBASE */ +#include <vm/vm_kern.h> +#include <vm/vm_extern.h> #include <machine/smp.h> #include <machine/apic.h> #include <machine/mpapic.h> #include <machine/cpufunc.h> #include <machine/segments.h> -#include <machine/smptests.h> /** TEST_DEFAULT_CONFIG, LATE_START */ +#include <machine/smptests.h> /** TEST_DEFAULT_CONFIG */ +#include <machine/tss.h> #include <i386/i386/cons.h> /* cngetc() */ #if defined(APIC_IO) -#include <i386/include/md_var.h> /* setidt() */ +#include <machine/md_var.h> /* setidt() */ #include <i386/isa/icu.h> /* Xinvltlb() */ #include <i386/isa/intr_machdep.h> /* Xinvltlb() */ #endif /* APIC_IO */ @@ -186,11 +188,6 @@ typedef struct BASETABLE_ENTRY { /** FIXME: what system files declare these??? */ extern struct region_descriptor r_gdt, r_idt; -/* global data */ -struct proc *SMPcurproc[NCPU]; -struct pcb *SMPcurpcb[NCPU]; -struct timeval SMPruntime[NCPU]; - int mp_ncpus; /* # of CPUs, including BSP */ int mp_naps; /* # of Applications processors */ int mp_nbusses; /* # of busses */ @@ -210,6 +207,15 @@ int cpu_num_to_apic_id[NAPICID]; int io_num_to_apic_id[NAPICID]; int apic_id_to_logical[NAPICID]; +/* Boot of AP uses this PTD */ +u_int *bootPTD; + +/* Hotwire a 0->4MB V==P mapping */ +extern pt_entry_t KPTphys; + +/* virtual address of per-cpu common_tss */ +extern struct i386tss common_tss; + /* * look for MP compliant motherboard. */ @@ -283,11 +289,6 @@ found: /* please forgive the 'goto'! */ if (mptable_pass1()) panic("you must reconfigure your kernel"); -#if defined(LATE_START) - /* create pages for (address common) cpu APIC and each IO APIC */ - pmap_bootstrap_apics(); -#endif /* LATE_START */ - /* flag fact that we are running multiple processors */ mp_capable = 1; return 1; @@ -305,9 +306,6 @@ mp_start(void) mp_enable(boot_address); else panic("MP hardware not found!"); - - /* finish pmap initialization - turn off V==P mapping at zero */ - pmap_bootstrap2(); } @@ -321,23 +319,25 @@ mp_announce(void) printf("FreeBSD/SMP: Multiprocessor motherboard\n"); printf(" cpu0 (BSP): apic id: %d", CPU_TO_ID(0)); - printf(", version: 0x%08x\n", cpu_apic_versions[0]); + printf(", version: 0x%08x", cpu_apic_versions[0]); + printf(", at 0x%08x\n", cpu_apic_address); for (x = 1; x <= mp_naps; ++x) { printf(" cpu%d (AP): apic id: %d", x, CPU_TO_ID(x)); - printf(", version: 0x%08x\n", cpu_apic_versions[x]); + printf(", version: 0x%08x", cpu_apic_versions[x]); + printf(", at 0x%08x\n", cpu_apic_address); } #if defined(APIC_IO) for (x = 0; x < mp_napics; ++x) { printf(" io%d (APIC): apic id: %d", x, IO_TO_ID(x)); - printf(", version: 0x%08x\n", io_apic_versions[x]); + printf(", version: 0x%08x", io_apic_versions[x]); + printf(", at 0x%08x\n", io_apic_address[x]); } #else printf(" Warning: APIC I/O disabled\n"); #endif /* APIC_IO */ } - /* * AP cpu's call this to sync up protected mode. */ @@ -352,12 +352,18 @@ init_secondary(void) lidt(&r_idt); lldt(_default_ldt); - slot = NGDT + cpunumber(); + slot = NGDT + cpuid; gsel_tss = GSEL(slot, SEL_KPL); gdt[slot].sd.sd_type = SDT_SYS386TSS; + common_tss.tss_esp0 = 0; /* not used until after switch */ + common_tss.tss_ss0 = GSEL(GDATA_SEL, SEL_KPL); + common_tss.tss_ioopt = (sizeof common_tss) << 16; ltr(gsel_tss); load_cr0(0x8005003b); /* XXX! */ + + PTD[0] = 0; + invltlb(); } @@ -375,9 +381,9 @@ configure_local_apic(void) outb(0x23, byte); /* disconnect 8259s/NMI */ } /* mask the LVT1 */ - temp = lapic__lvt_lint0; + temp = lapic.lvt_lint0; temp |= APIC_LVT_M; - lapic__lvt_lint0 = temp; + lapic.lvt_lint0 = temp; } #endif /* APIC_IO */ @@ -398,13 +404,15 @@ mp_enable(u_int boot_addr) u_int ux; #endif /* APIC_IO */ - /* examine the MP table for needed info */ + /* Turn on 4MB of V == P addressing so we can get to MP table */ + *(int *)PTD = PG_V | PG_RW | ((u_long)KPTphys & PG_FRAME); + invltlb(); + + /* examine the MP table for needed info, uses physical addresses */ x = mptable_pass2(); -#if !defined(LATE_START) - /* create pages for (address common) cpu APIC and each IO APIC */ - pmap_bootstrap_apics(); -#endif /* LATE_START */ + *(int *)PTD = 0; + invltlb(); /* can't process default configs till the CPU APIC is pmapped */ if (x) @@ -832,7 +840,7 @@ fix_mp_table(void) for (x = 0; x < mp_nbusses; ++x) { if (bus_data[x].bus_type != PCI) continue; - if (bus_data[x].bus_id >= num_pci_bus ) + if (bus_data[x].bus_id >= num_pci_bus) panic("bad PCI bus numbering"); } } @@ -1258,7 +1266,7 @@ default_mp_table(int type) } #endif /* 0 */ - boot_cpu_id = (lapic__id & APIC_ID_MASK) >> 24; + boot_cpu_id = (lapic.id & APIC_ID_MASK) >> 24; ap_cpu_id = (boot_cpu_id == 0) ? 1 : 0; /* BSP */ @@ -1351,9 +1359,12 @@ default_mp_table(int type) static int start_all_aps(u_int boot_addr) { - int x; + int x, i; u_char mpbiosreason; u_long mpbioswarmvec; + pd_entry_t newptd; + pt_entry_t newpt; + int *newpp; /** * NOTE: this needs further thought: @@ -1362,7 +1373,7 @@ start_all_aps(u_int boot_addr) * * get the initial mp_lock with a count of 1 for the BSP */ - mp_lock = (lapic__id & APIC_ID_MASK) + 1; + mp_lock = (lapic.id & APIC_ID_MASK) + 1; /* initialize BSP's local APIC */ apic_initialize(1); @@ -1370,6 +1381,7 @@ start_all_aps(u_int boot_addr) /* install the AP 1st level boot code */ install_ap_tramp(boot_addr); + /* save the current value of the warm-start vector */ mpbioswarmvec = *((u_long *) WARMBOOT_OFF); outb(CMOS_REG, BIOS_RESET); @@ -1378,6 +1390,58 @@ start_all_aps(u_int boot_addr) /* start each AP */ for (x = 1; x <= mp_naps; ++x) { + /* HACK HACK HACK !!! */ + + /* alloc new page table directory */ + newptd = (pd_entry_t)(kmem_alloc(kernel_map, PAGE_SIZE)); + + /* clone currently active one (ie: IdlePTD) */ + bcopy(PTD, newptd, PAGE_SIZE); /* inc prv page pde */ + + /* set up 0 -> 4MB P==V mapping for AP boot */ + newptd[0] = PG_V | PG_RW | ((u_long)KPTphys & PG_FRAME); + + /* store PTD for this AP */ + bootPTD = (pd_entry_t)vtophys(newptd); + + /* alloc new page table page */ + newpt = (pt_entry_t)(kmem_alloc(kernel_map, PAGE_SIZE)); + + /* set the new PTD's private page to point there */ + newptd[MPPTDI] = PG_V | PG_RW | vtophys(newpt); + + /* install self referential entry */ + newptd[PTDPTDI] = PG_V | PG_RW | vtophys(newptd); + + /* get a new private data page */ + newpp = (int *)kmem_alloc(kernel_map, PAGE_SIZE); + + /* wire it into the private page table page */ + newpt[0] = PG_V | PG_RW | vtophys(newpp); + + /* wire the ptp into itself for access */ + newpt[1] = PG_V | PG_RW | vtophys(newpt); + + /* and the local apic */ + newpt[2] = SMP_prvpt[2]; + + /* and the IO apic mapping[s] */ + for (i = 16; i < 32; i++) + newpt[i] = SMP_prvpt[i]; + + /* prime data page for it to use */ + newpp[0] = x; /* cpuid */ + newpp[1] = 0; /* curproc */ + newpp[2] = 0; /* curpcb */ + newpp[3] = 0; /* npxproc */ + newpp[4] = 0; /* runtime.tv_sec */ + newpp[5] = 0; /* runtime.tv_usec */ + newpp[6] = x << 24; /* cpu_lockid */ + + /* XXX NOTE: ABANDON bootPTD for now!!!! */ + + /* END REVOLTING HACKERY */ + /* setup a vector to our boot code */ *((volatile u_short *) WARMBOOT_OFF) = WARMBOOT_TARGET; *((volatile u_short *) WARMBOOT_SEG) = (boot_addr >> 4); @@ -1401,7 +1465,7 @@ start_all_aps(u_int boot_addr) } /* fill in our (BSP) APIC version */ - cpu_apic_versions[0] = lapic__version; + cpu_apic_versions[0] = lapic.version; /* restore the warmstart vector */ *(u_long *) WARMBOOT_OFF = mpbioswarmvec; @@ -1503,24 +1567,24 @@ start_ap(int logical_cpu, u_int boot_addr) */ /* setup the address for the target AP */ - icr_hi = lapic__icr_hi & ~APIC_ID_MASK; + icr_hi = lapic.icr_hi & ~APIC_ID_MASK; icr_hi |= (physical_cpu << 24); - lapic__icr_hi = icr_hi; + lapic.icr_hi = icr_hi; /* do an INIT IPI: assert RESET */ - icr_lo = lapic__icr_lo & 0xfff00000; - lapic__icr_lo = icr_lo | 0x0000c500; + icr_lo = lapic.icr_lo & 0xfff00000; + lapic.icr_lo = icr_lo | 0x0000c500; /* wait for pending status end */ - while (lapic__icr_lo & APIC_DELSTAT_MASK) + while (lapic.icr_lo & APIC_DELSTAT_MASK) /* spin */ ; /* do an INIT IPI: deassert RESET */ - lapic__icr_lo = icr_lo | 0x00008500; + lapic.icr_lo = icr_lo | 0x00008500; /* wait for pending status end */ u_sleep(10000); /* wait ~10mS */ - while (lapic__icr_lo & APIC_DELSTAT_MASK) + while (lapic.icr_lo & APIC_DELSTAT_MASK) /* spin */ ; /* @@ -1533,8 +1597,8 @@ start_ap(int logical_cpu, u_int boot_addr) */ /* do a STARTUP IPI */ - lapic__icr_lo = icr_lo | 0x00000600 | vector; - while (lapic__icr_lo & APIC_DELSTAT_MASK) + lapic.icr_lo = icr_lo | 0x00000600 | vector; + while (lapic.icr_lo & APIC_DELSTAT_MASK) /* spin */ ; u_sleep(200); /* wait ~200uS */ @@ -1545,8 +1609,8 @@ start_ap(int logical_cpu, u_int boot_addr) * recognized after hardware RESET or INIT IPI. */ - lapic__icr_lo = icr_lo | 0x00000600 | vector; - while (lapic__icr_lo & APIC_DELSTAT_MASK) + lapic.icr_lo = icr_lo | 0x00000600 | vector; + while (lapic.icr_lo & APIC_DELSTAT_MASK) /* spin */ ; u_sleep(200); /* wait ~200uS */ diff --git a/sys/amd64/amd64/mpboot.S b/sys/amd64/amd64/mpboot.S index e43b250..f47f49f 100644 --- a/sys/amd64/amd64/mpboot.S +++ b/sys/amd64/amd64/mpboot.S @@ -31,7 +31,7 @@ * mpboot.s: FreeBSD machine support for the Intel MP Spec * multiprocessor systems. * - * $Id: mpboot.s,v 1.18 1997/04/25 03:11:27 fsmp Exp $ + * $Id: mpboot.s,v 1.1 1997/04/26 11:45:17 peter Exp $ */ @@ -76,7 +76,7 @@ NON_GPROF_ENTRY(MPentry) CHECKPOINT(0x36, 3) movl $mp_stk-KERNBASE,%esp /* mp boot stack end loc. */ /* Now enable paging mode */ - movl _IdlePTD-KERNBASE, %eax + movl _bootPTD-KERNBASE, %eax movl %eax,%cr3 movl %cr0,%eax orl $CR0_PE|CR0_PG,%eax /* enable paging */ @@ -96,13 +96,12 @@ mp_begin: /* now running relocated at KERNBASE */ CHECKPOINT(0x38, 5) /* disable the APIC, just to be SURE */ - movl _apic_base, %esi - movl APIC_SVR(%esi), %eax /* get spurious vector reg. */ + movl lapic_svr, %eax /* get spurious vector reg. */ andl $~APIC_SVR_SWEN, %eax /* clear software enable bit */ - movl %eax, APIC_SVR(%esi) + movl %eax, lapic_svr /* signal our startup to the BSP */ - movl APIC_VER(%esi), %eax /* our version reg contents */ + movl lapic_ver, %eax /* our version reg contents */ movl %eax, _cpu_apic_versions /* into [ 0 ] */ incl _mp_ncpus /* signal BSP */ diff --git a/sys/amd64/amd64/mptable.c b/sys/amd64/amd64/mptable.c index a27cf86..c817925 100644 --- a/sys/amd64/amd64/mptable.c +++ b/sys/amd64/amd64/mptable.c @@ -22,11 +22,10 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: mp_machdep.c,v 1.16 1997/05/29 05:58:41 fsmp Exp $ + * $Id: mp_machdep.c,v 1.17 1997/06/02 10:44:08 dfr Exp $ */ #include "opt_smp.h" -#include "opt_serial.h" #include <sys/param.h> /* for KERNBASE */ #include <sys/types.h> @@ -38,18 +37,21 @@ #include <vm/vm_param.h> /* for KERNBASE */ #include <vm/pmap.h> /* for KERNBASE */ #include <machine/pmap.h> /* for KERNBASE */ +#include <vm/vm_kern.h> +#include <vm/vm_extern.h> #include <machine/smp.h> #include <machine/apic.h> #include <machine/mpapic.h> #include <machine/cpufunc.h> #include <machine/segments.h> -#include <machine/smptests.h> /** TEST_DEFAULT_CONFIG, LATE_START */ +#include <machine/smptests.h> /** TEST_DEFAULT_CONFIG */ +#include <machine/tss.h> #include <i386/i386/cons.h> /* cngetc() */ #if defined(APIC_IO) -#include <i386/include/md_var.h> /* setidt() */ +#include <machine/md_var.h> /* setidt() */ #include <i386/isa/icu.h> /* Xinvltlb() */ #include <i386/isa/intr_machdep.h> /* Xinvltlb() */ #endif /* APIC_IO */ @@ -186,11 +188,6 @@ typedef struct BASETABLE_ENTRY { /** FIXME: what system files declare these??? */ extern struct region_descriptor r_gdt, r_idt; -/* global data */ -struct proc *SMPcurproc[NCPU]; -struct pcb *SMPcurpcb[NCPU]; -struct timeval SMPruntime[NCPU]; - int mp_ncpus; /* # of CPUs, including BSP */ int mp_naps; /* # of Applications processors */ int mp_nbusses; /* # of busses */ @@ -210,6 +207,15 @@ int cpu_num_to_apic_id[NAPICID]; int io_num_to_apic_id[NAPICID]; int apic_id_to_logical[NAPICID]; +/* Boot of AP uses this PTD */ +u_int *bootPTD; + +/* Hotwire a 0->4MB V==P mapping */ +extern pt_entry_t KPTphys; + +/* virtual address of per-cpu common_tss */ +extern struct i386tss common_tss; + /* * look for MP compliant motherboard. */ @@ -283,11 +289,6 @@ found: /* please forgive the 'goto'! */ if (mptable_pass1()) panic("you must reconfigure your kernel"); -#if defined(LATE_START) - /* create pages for (address common) cpu APIC and each IO APIC */ - pmap_bootstrap_apics(); -#endif /* LATE_START */ - /* flag fact that we are running multiple processors */ mp_capable = 1; return 1; @@ -305,9 +306,6 @@ mp_start(void) mp_enable(boot_address); else panic("MP hardware not found!"); - - /* finish pmap initialization - turn off V==P mapping at zero */ - pmap_bootstrap2(); } @@ -321,23 +319,25 @@ mp_announce(void) printf("FreeBSD/SMP: Multiprocessor motherboard\n"); printf(" cpu0 (BSP): apic id: %d", CPU_TO_ID(0)); - printf(", version: 0x%08x\n", cpu_apic_versions[0]); + printf(", version: 0x%08x", cpu_apic_versions[0]); + printf(", at 0x%08x\n", cpu_apic_address); for (x = 1; x <= mp_naps; ++x) { printf(" cpu%d (AP): apic id: %d", x, CPU_TO_ID(x)); - printf(", version: 0x%08x\n", cpu_apic_versions[x]); + printf(", version: 0x%08x", cpu_apic_versions[x]); + printf(", at 0x%08x\n", cpu_apic_address); } #if defined(APIC_IO) for (x = 0; x < mp_napics; ++x) { printf(" io%d (APIC): apic id: %d", x, IO_TO_ID(x)); - printf(", version: 0x%08x\n", io_apic_versions[x]); + printf(", version: 0x%08x", io_apic_versions[x]); + printf(", at 0x%08x\n", io_apic_address[x]); } #else printf(" Warning: APIC I/O disabled\n"); #endif /* APIC_IO */ } - /* * AP cpu's call this to sync up protected mode. */ @@ -352,12 +352,18 @@ init_secondary(void) lidt(&r_idt); lldt(_default_ldt); - slot = NGDT + cpunumber(); + slot = NGDT + cpuid; gsel_tss = GSEL(slot, SEL_KPL); gdt[slot].sd.sd_type = SDT_SYS386TSS; + common_tss.tss_esp0 = 0; /* not used until after switch */ + common_tss.tss_ss0 = GSEL(GDATA_SEL, SEL_KPL); + common_tss.tss_ioopt = (sizeof common_tss) << 16; ltr(gsel_tss); load_cr0(0x8005003b); /* XXX! */ + + PTD[0] = 0; + invltlb(); } @@ -375,9 +381,9 @@ configure_local_apic(void) outb(0x23, byte); /* disconnect 8259s/NMI */ } /* mask the LVT1 */ - temp = lapic__lvt_lint0; + temp = lapic.lvt_lint0; temp |= APIC_LVT_M; - lapic__lvt_lint0 = temp; + lapic.lvt_lint0 = temp; } #endif /* APIC_IO */ @@ -398,13 +404,15 @@ mp_enable(u_int boot_addr) u_int ux; #endif /* APIC_IO */ - /* examine the MP table for needed info */ + /* Turn on 4MB of V == P addressing so we can get to MP table */ + *(int *)PTD = PG_V | PG_RW | ((u_long)KPTphys & PG_FRAME); + invltlb(); + + /* examine the MP table for needed info, uses physical addresses */ x = mptable_pass2(); -#if !defined(LATE_START) - /* create pages for (address common) cpu APIC and each IO APIC */ - pmap_bootstrap_apics(); -#endif /* LATE_START */ + *(int *)PTD = 0; + invltlb(); /* can't process default configs till the CPU APIC is pmapped */ if (x) @@ -832,7 +840,7 @@ fix_mp_table(void) for (x = 0; x < mp_nbusses; ++x) { if (bus_data[x].bus_type != PCI) continue; - if (bus_data[x].bus_id >= num_pci_bus ) + if (bus_data[x].bus_id >= num_pci_bus) panic("bad PCI bus numbering"); } } @@ -1258,7 +1266,7 @@ default_mp_table(int type) } #endif /* 0 */ - boot_cpu_id = (lapic__id & APIC_ID_MASK) >> 24; + boot_cpu_id = (lapic.id & APIC_ID_MASK) >> 24; ap_cpu_id = (boot_cpu_id == 0) ? 1 : 0; /* BSP */ @@ -1351,9 +1359,12 @@ default_mp_table(int type) static int start_all_aps(u_int boot_addr) { - int x; + int x, i; u_char mpbiosreason; u_long mpbioswarmvec; + pd_entry_t newptd; + pt_entry_t newpt; + int *newpp; /** * NOTE: this needs further thought: @@ -1362,7 +1373,7 @@ start_all_aps(u_int boot_addr) * * get the initial mp_lock with a count of 1 for the BSP */ - mp_lock = (lapic__id & APIC_ID_MASK) + 1; + mp_lock = (lapic.id & APIC_ID_MASK) + 1; /* initialize BSP's local APIC */ apic_initialize(1); @@ -1370,6 +1381,7 @@ start_all_aps(u_int boot_addr) /* install the AP 1st level boot code */ install_ap_tramp(boot_addr); + /* save the current value of the warm-start vector */ mpbioswarmvec = *((u_long *) WARMBOOT_OFF); outb(CMOS_REG, BIOS_RESET); @@ -1378,6 +1390,58 @@ start_all_aps(u_int boot_addr) /* start each AP */ for (x = 1; x <= mp_naps; ++x) { + /* HACK HACK HACK !!! */ + + /* alloc new page table directory */ + newptd = (pd_entry_t)(kmem_alloc(kernel_map, PAGE_SIZE)); + + /* clone currently active one (ie: IdlePTD) */ + bcopy(PTD, newptd, PAGE_SIZE); /* inc prv page pde */ + + /* set up 0 -> 4MB P==V mapping for AP boot */ + newptd[0] = PG_V | PG_RW | ((u_long)KPTphys & PG_FRAME); + + /* store PTD for this AP */ + bootPTD = (pd_entry_t)vtophys(newptd); + + /* alloc new page table page */ + newpt = (pt_entry_t)(kmem_alloc(kernel_map, PAGE_SIZE)); + + /* set the new PTD's private page to point there */ + newptd[MPPTDI] = PG_V | PG_RW | vtophys(newpt); + + /* install self referential entry */ + newptd[PTDPTDI] = PG_V | PG_RW | vtophys(newptd); + + /* get a new private data page */ + newpp = (int *)kmem_alloc(kernel_map, PAGE_SIZE); + + /* wire it into the private page table page */ + newpt[0] = PG_V | PG_RW | vtophys(newpp); + + /* wire the ptp into itself for access */ + newpt[1] = PG_V | PG_RW | vtophys(newpt); + + /* and the local apic */ + newpt[2] = SMP_prvpt[2]; + + /* and the IO apic mapping[s] */ + for (i = 16; i < 32; i++) + newpt[i] = SMP_prvpt[i]; + + /* prime data page for it to use */ + newpp[0] = x; /* cpuid */ + newpp[1] = 0; /* curproc */ + newpp[2] = 0; /* curpcb */ + newpp[3] = 0; /* npxproc */ + newpp[4] = 0; /* runtime.tv_sec */ + newpp[5] = 0; /* runtime.tv_usec */ + newpp[6] = x << 24; /* cpu_lockid */ + + /* XXX NOTE: ABANDON bootPTD for now!!!! */ + + /* END REVOLTING HACKERY */ + /* setup a vector to our boot code */ *((volatile u_short *) WARMBOOT_OFF) = WARMBOOT_TARGET; *((volatile u_short *) WARMBOOT_SEG) = (boot_addr >> 4); @@ -1401,7 +1465,7 @@ start_all_aps(u_int boot_addr) } /* fill in our (BSP) APIC version */ - cpu_apic_versions[0] = lapic__version; + cpu_apic_versions[0] = lapic.version; /* restore the warmstart vector */ *(u_long *) WARMBOOT_OFF = mpbioswarmvec; @@ -1503,24 +1567,24 @@ start_ap(int logical_cpu, u_int boot_addr) */ /* setup the address for the target AP */ - icr_hi = lapic__icr_hi & ~APIC_ID_MASK; + icr_hi = lapic.icr_hi & ~APIC_ID_MASK; icr_hi |= (physical_cpu << 24); - lapic__icr_hi = icr_hi; + lapic.icr_hi = icr_hi; /* do an INIT IPI: assert RESET */ - icr_lo = lapic__icr_lo & 0xfff00000; - lapic__icr_lo = icr_lo | 0x0000c500; + icr_lo = lapic.icr_lo & 0xfff00000; + lapic.icr_lo = icr_lo | 0x0000c500; /* wait for pending status end */ - while (lapic__icr_lo & APIC_DELSTAT_MASK) + while (lapic.icr_lo & APIC_DELSTAT_MASK) /* spin */ ; /* do an INIT IPI: deassert RESET */ - lapic__icr_lo = icr_lo | 0x00008500; + lapic.icr_lo = icr_lo | 0x00008500; /* wait for pending status end */ u_sleep(10000); /* wait ~10mS */ - while (lapic__icr_lo & APIC_DELSTAT_MASK) + while (lapic.icr_lo & APIC_DELSTAT_MASK) /* spin */ ; /* @@ -1533,8 +1597,8 @@ start_ap(int logical_cpu, u_int boot_addr) */ /* do a STARTUP IPI */ - lapic__icr_lo = icr_lo | 0x00000600 | vector; - while (lapic__icr_lo & APIC_DELSTAT_MASK) + lapic.icr_lo = icr_lo | 0x00000600 | vector; + while (lapic.icr_lo & APIC_DELSTAT_MASK) /* spin */ ; u_sleep(200); /* wait ~200uS */ @@ -1545,8 +1609,8 @@ start_ap(int logical_cpu, u_int boot_addr) * recognized after hardware RESET or INIT IPI. */ - lapic__icr_lo = icr_lo | 0x00000600 | vector; - while (lapic__icr_lo & APIC_DELSTAT_MASK) + lapic.icr_lo = icr_lo | 0x00000600 | vector; + while (lapic.icr_lo & APIC_DELSTAT_MASK) /* spin */ ; u_sleep(200); /* wait ~200uS */ diff --git a/sys/amd64/amd64/pmap.c b/sys/amd64/amd64/pmap.c index 32b8b55..c95c509 100644 --- a/sys/amd64/amd64/pmap.c +++ b/sys/amd64/amd64/pmap.c @@ -39,7 +39,7 @@ * SUCH DAMAGE. * * from: @(#)pmap.c 7.7 (Berkeley) 5/12/91 - * $Id: pmap.c,v 1.143 1997/04/27 12:11:43 peter Exp $ + * $Id: pmap.c,v 1.145 1997/05/29 05:58:41 fsmp Exp $ */ /* @@ -187,14 +187,6 @@ static caddr_t CADDR2; static pt_entry_t *msgbufmap; struct msgbuf *msgbufp=0; -#if defined(SMP) || defined(APIC_IO) -static pt_entry_t *apic_map; -#endif /* SMP || APIC_IO */ - -#if defined(APIC_IO) -static pt_entry_t *io_apic_map; -#endif /* APIC_IO */ - pt_entry_t *PMAP1 = 0; unsigned *PADDR1 = 0; @@ -266,6 +258,7 @@ pmap_bootstrap(firstaddr, loadaddr) { vm_offset_t va; pt_entry_t *pte; + int i, j; avail_start = firstaddr; @@ -292,7 +285,7 @@ pmap_bootstrap(firstaddr, loadaddr) */ kernel_pmap = &kernel_pmap_store; - kernel_pmap->pm_pdir = (pd_entry_t *) (KERNBASE + IdlePTD); + kernel_pmap->pm_pdir = (pd_entry_t *) (KERNBASE + (u_int)IdlePTD); kernel_pmap->pm_count = 1; #if PMAP_PVLIST @@ -310,26 +303,6 @@ pmap_bootstrap(firstaddr, loadaddr) va = virtual_avail; pte = (pt_entry_t *) pmap_pte(kernel_pmap, va); -#if defined(SMP) || defined(APIC_IO) - /* - * apic_map is the pt for where the local (CPU) apic is mapped in. - */ - SYSMAP(unsigned int *, apic_map, apic_base, 1) -#if 1 /** XXX APIC_STRUCT */ - lapic = (lapic_t*)apic_base; -#endif /** XXX APIC_STRUCT */ -#endif /* SMP || APIC_IO */ - -#if defined(APIC_IO) - /* - * io_apic_map is the pt for where the I/O apic is mapped in. - */ - SYSMAP(unsigned int *, io_apic_map, io_apic_base, 1) -#if 1 /** XXX APIC_STRUCT */ - ioapic = (ioapic_t*)io_apic_base; -#endif /** XXX APIC_STRUCT */ -#endif /* APIC_IO */ - /* * CMAP1/CMAP2 are used for zeroing and copying pages. */ @@ -357,8 +330,37 @@ pmap_bootstrap(firstaddr, loadaddr) virtual_avail = va; *(int *) CMAP1 = *(int *) CMAP2 = 0; -#if !defined(SMP) *(int *) PTD = 0; + +#ifdef SMP + if (cpu_apic_address == 0) + panic("pmap_bootstrap: no local apic!"); + + /* 0 = private page */ + /* 1 = page table page */ + /* 2 = local apic */ + /* 16-31 = io apics */ + SMP_prvpt[2] = PG_V | PG_RW | ((u_long)cpu_apic_address & PG_FRAME); + + for (i = 0; i < mp_napics; i++) { + for (j = 0; j < 16; j++) { + /* same page frame as a previous IO apic? */ + if (((u_long)SMP_prvpt[j + 16] & PG_FRAME) == + ((u_long)io_apic_address[0] & PG_FRAME)) { + ioapic[i] = (ioapic_t *)&SMP_ioapic[j * PAGE_SIZE]; + break; + } + /* use this slot if available */ + if (((u_long)SMP_prvpt[j + 16] & PG_FRAME) == 0) { + SMP_prvpt[j + 16] = PG_V | PG_RW | + ((u_long)io_apic_address[i] & PG_FRAME); + ioapic[i] = (ioapic_t *)&SMP_ioapic[j * PAGE_SIZE]; + break; + } + } + if (j == 16) + panic("no space to map IO apic %d!", i); + } #endif invltlb(); @@ -371,39 +373,6 @@ pmap_bootstrap(firstaddr, loadaddr) pgeflag = 0; } -#if defined(SMP) || defined(APIC_IO) -void -pmap_bootstrap_apics() -{ - if (cpu_apic_address == 0) { - printf("pmap: BSP APIC address NOT found!\n"); - panic("pmap_bootstrap_apics: no apic"); - } - - *(int*)apic_map = PG_V | PG_RW | ((u_long)cpu_apic_address & PG_FRAME); - -#if defined(APIC_IO) -#if defined(MULTIPLE_IOAPICS) -#error MULTIPLE_IOAPICSXXX -#else - *(int*)io_apic_map = PG_V | PG_RW - | ((u_long)io_apic_address[0] & PG_FRAME); -#endif /* MULTIPLE_IOAPICS */ -#endif /* APIC_IO */ - - invltlb(); -} -#endif /* SMP || APIC_IO */ - -#ifdef SMP -void -pmap_bootstrap2() -{ - *(int *) PTD = 0; - invltlb(); -} -#endif - /* * Initialize the pmap module. * Called by vm_init, to initialize any structures that the pmap @@ -1062,6 +1031,7 @@ retry: bzero(pmap->pm_pdir, PAGE_SIZE); /* wire in kernel global address entries */ + /* XXX copies current process, does not fill in MPPTDI */ bcopy(PTD + KPTDI, pmap->pm_pdir + KPTDI, nkpt * PTESIZE); /* install self-referential address mapping entry */ @@ -1116,6 +1086,9 @@ pmap_release_free_page(pmap, p) */ if (p->pindex == PTDPTDI) { bzero(pde + KPTDI, nkpt * PTESIZE); +#ifdef SMP + pde[MPPTDI] = 0; +#endif pde[APTDPTDI] = 0; pmap_kremove((vm_offset_t) pmap->pm_pdir); } diff --git a/sys/amd64/amd64/support.S b/sys/amd64/amd64/support.S index b87370b..be18df8 100644 --- a/sys/amd64/amd64/support.S +++ b/sys/amd64/amd64/support.S @@ -30,7 +30,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: support.s,v 1.52 1997/04/26 11:45:21 peter Exp $ + * $Id: support.s,v 1.53 1997/05/29 05:11:10 peter Exp $ */ #include "npx.h" @@ -40,7 +40,6 @@ #include <machine/cputypes.h> #include <machine/pmap.h> #include <machine/specialreg.h> -#include <machine/smpasm.h> #include "assym.s" @@ -195,7 +194,7 @@ do0: ret #endif -#if defined(I586_CPU) && NNPX > 0 && !defined(SMP) +#if defined(I586_CPU) && NNPX > 0 ENTRY(i586_bzero) movl 4(%esp),%edx movl 8(%esp),%ecx @@ -438,7 +437,7 @@ ENTRY(generic_bcopy) cld ret -#if defined(I586_CPU) && NNPX > 0 && !defined(SMP) +#if defined(I586_CPU) && NNPX > 0 ENTRY(i586_bcopy) pushl %esi pushl %edi @@ -623,7 +622,7 @@ ENTRY(copyout) jmp *_copyout_vector ENTRY(generic_copyout) - GETCURPCB(%eax) + movl _curpcb,%eax movl $copyout_fault,PCB_ONFAULT(%eax) pushl %esi pushl %edi @@ -716,7 +715,7 @@ ENTRY(generic_copyout) 3: movl %ebx,%ecx -#if defined(I586_CPU) && NNPX > 0 && !defined(SMP) +#if defined(I586_CPU) && NNPX > 0 ALIGN_TEXT slow_copyout: #endif @@ -734,7 +733,7 @@ done_copyout: popl %edi popl %esi xorl %eax,%eax - GETCURPCB(%edx) + movl _curpcb,%edx movl %eax,PCB_ONFAULT(%edx) ret @@ -743,12 +742,12 @@ copyout_fault: popl %ebx popl %edi popl %esi - GETCURPCB(%edx) + movl _curpcb,%edx movl $0,PCB_ONFAULT(%edx) movl $EFAULT,%eax ret -#if defined(I586_CPU) && NNPX > 0 && !defined(SMP) +#if defined(I586_CPU) && NNPX > 0 ENTRY(i586_copyout) /* * Duplicated from generic_copyout. Could be done a bit better. @@ -808,7 +807,7 @@ ENTRY(copyin) jmp *_copyin_vector ENTRY(generic_copyin) - GETCURPCB(%eax) + movl _curpcb,%eax movl $copyin_fault,PCB_ONFAULT(%eax) pushl %esi pushl %edi @@ -825,7 +824,7 @@ ENTRY(generic_copyin) cmpl $VM_MAXUSER_ADDRESS,%edx ja copyin_fault -#if defined(I586_CPU) && NNPX > 0 && !defined(SMP) +#if defined(I586_CPU) && NNPX > 0 ALIGN_TEXT slow_copyin: #endif @@ -839,14 +838,14 @@ slow_copyin: rep movsb -#if defined(I586_CPU) && NNPX > 0 && !defined(SMP) +#if defined(I586_CPU) && NNPX > 0 ALIGN_TEXT done_copyin: #endif popl %edi popl %esi xorl %eax,%eax - GETCURPCB(%edx) + movl _curpcb,%edx movl %eax,PCB_ONFAULT(%edx) ret @@ -854,12 +853,12 @@ done_copyin: copyin_fault: popl %edi popl %esi - GETCURPCB(%edx) + movl _curpcb,%edx movl $0,PCB_ONFAULT(%edx) movl $EFAULT,%eax ret -#if defined(I586_CPU) && NNPX > 0 && !defined(SMP) +#if defined(I586_CPU) && NNPX > 0 ENTRY(i586_copyin) /* * Duplicated from generic_copyin. Could be done a bit better. @@ -894,7 +893,7 @@ ENTRY(i586_copyin) jmp done_copyin #endif /* I586_CPU && NNPX > 0 */ -#if defined(I586_CPU) && NNPX > 0 && !defined(SMP) +#if defined(I586_CPU) && NNPX > 0 /* fastmove(src, dst, len) src in %esi dst in %edi @@ -1086,7 +1085,7 @@ fastmove_tail_fault: * fu{byte,sword,word} : fetch a byte (sword, word) from user memory */ ENTRY(fuword) - GETCURPCB(%ecx) + movl _curpcb,%ecx movl $fusufault,PCB_ONFAULT(%ecx) movl 4(%esp),%edx /* from */ @@ -1109,7 +1108,7 @@ ENTRY(fuswintr) ret ENTRY(fusword) - GETCURPCB(%ecx) + movl _curpcb,%ecx movl $fusufault,PCB_ONFAULT(%ecx) movl 4(%esp),%edx @@ -1121,7 +1120,7 @@ ENTRY(fusword) ret ENTRY(fubyte) - GETCURPCB(%ecx) + movl _curpcb,%ecx movl $fusufault,PCB_ONFAULT(%ecx) movl 4(%esp),%edx @@ -1134,7 +1133,7 @@ ENTRY(fubyte) ALIGN_TEXT fusufault: - GETCURPCB(%ecx) + movl _curpcb,%ecx xorl %eax,%eax movl %eax,PCB_ONFAULT(%ecx) decl %eax @@ -1144,7 +1143,7 @@ fusufault: * su{byte,sword,word}: write a byte (word, longword) to user memory */ ENTRY(suword) - GETCURPCB(%ecx) + movl _curpcb,%ecx movl $fusufault,PCB_ONFAULT(%ecx) movl 4(%esp),%edx @@ -1188,12 +1187,12 @@ ENTRY(suword) movl 8(%esp),%eax movl %eax,(%edx) xorl %eax,%eax - GETCURPCB(%ecx) + movl _curpcb,%ecx movl %eax,PCB_ONFAULT(%ecx) ret ENTRY(susword) - GETCURPCB(%ecx) + movl _curpcb,%ecx movl $fusufault,PCB_ONFAULT(%ecx) movl 4(%esp),%edx @@ -1237,13 +1236,13 @@ ENTRY(susword) movw 8(%esp),%ax movw %ax,(%edx) xorl %eax,%eax - GETCURPCB(%ecx) /* restore trashed register */ + movl _curpcb,%ecx /* restore trashed register */ movl %eax,PCB_ONFAULT(%ecx) ret ALTENTRY(suibyte) ENTRY(subyte) - GETCURPCB(%ecx) + movl _curpcb,%ecx movl $fusufault,PCB_ONFAULT(%ecx) movl 4(%esp),%edx @@ -1286,7 +1285,7 @@ ENTRY(subyte) movb 8(%esp),%al movb %al,(%edx) xorl %eax,%eax - GETCURPCB(%ecx) /* restore trashed register */ + movl _curpcb,%ecx /* restore trashed register */ movl %eax,PCB_ONFAULT(%ecx) ret @@ -1300,7 +1299,7 @@ ENTRY(subyte) ENTRY(copyinstr) pushl %esi pushl %edi - GETCURPCB(%ecx) + movl _curpcb,%ecx movl $cpystrflt,PCB_ONFAULT(%ecx) movl 12(%esp),%esi /* %esi = from */ @@ -1348,7 +1347,7 @@ cpystrflt: cpystrflt_x: /* set *lencopied and return %eax */ - GETCURPCB(%ecx) + movl _curpcb,%ecx movl $0,PCB_ONFAULT(%ecx) movl 20(%esp),%ecx subl %edx,%ecx diff --git a/sys/amd64/amd64/support.s b/sys/amd64/amd64/support.s index b87370b..be18df8 100644 --- a/sys/amd64/amd64/support.s +++ b/sys/amd64/amd64/support.s @@ -30,7 +30,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: support.s,v 1.52 1997/04/26 11:45:21 peter Exp $ + * $Id: support.s,v 1.53 1997/05/29 05:11:10 peter Exp $ */ #include "npx.h" @@ -40,7 +40,6 @@ #include <machine/cputypes.h> #include <machine/pmap.h> #include <machine/specialreg.h> -#include <machine/smpasm.h> #include "assym.s" @@ -195,7 +194,7 @@ do0: ret #endif -#if defined(I586_CPU) && NNPX > 0 && !defined(SMP) +#if defined(I586_CPU) && NNPX > 0 ENTRY(i586_bzero) movl 4(%esp),%edx movl 8(%esp),%ecx @@ -438,7 +437,7 @@ ENTRY(generic_bcopy) cld ret -#if defined(I586_CPU) && NNPX > 0 && !defined(SMP) +#if defined(I586_CPU) && NNPX > 0 ENTRY(i586_bcopy) pushl %esi pushl %edi @@ -623,7 +622,7 @@ ENTRY(copyout) jmp *_copyout_vector ENTRY(generic_copyout) - GETCURPCB(%eax) + movl _curpcb,%eax movl $copyout_fault,PCB_ONFAULT(%eax) pushl %esi pushl %edi @@ -716,7 +715,7 @@ ENTRY(generic_copyout) 3: movl %ebx,%ecx -#if defined(I586_CPU) && NNPX > 0 && !defined(SMP) +#if defined(I586_CPU) && NNPX > 0 ALIGN_TEXT slow_copyout: #endif @@ -734,7 +733,7 @@ done_copyout: popl %edi popl %esi xorl %eax,%eax - GETCURPCB(%edx) + movl _curpcb,%edx movl %eax,PCB_ONFAULT(%edx) ret @@ -743,12 +742,12 @@ copyout_fault: popl %ebx popl %edi popl %esi - GETCURPCB(%edx) + movl _curpcb,%edx movl $0,PCB_ONFAULT(%edx) movl $EFAULT,%eax ret -#if defined(I586_CPU) && NNPX > 0 && !defined(SMP) +#if defined(I586_CPU) && NNPX > 0 ENTRY(i586_copyout) /* * Duplicated from generic_copyout. Could be done a bit better. @@ -808,7 +807,7 @@ ENTRY(copyin) jmp *_copyin_vector ENTRY(generic_copyin) - GETCURPCB(%eax) + movl _curpcb,%eax movl $copyin_fault,PCB_ONFAULT(%eax) pushl %esi pushl %edi @@ -825,7 +824,7 @@ ENTRY(generic_copyin) cmpl $VM_MAXUSER_ADDRESS,%edx ja copyin_fault -#if defined(I586_CPU) && NNPX > 0 && !defined(SMP) +#if defined(I586_CPU) && NNPX > 0 ALIGN_TEXT slow_copyin: #endif @@ -839,14 +838,14 @@ slow_copyin: rep movsb -#if defined(I586_CPU) && NNPX > 0 && !defined(SMP) +#if defined(I586_CPU) && NNPX > 0 ALIGN_TEXT done_copyin: #endif popl %edi popl %esi xorl %eax,%eax - GETCURPCB(%edx) + movl _curpcb,%edx movl %eax,PCB_ONFAULT(%edx) ret @@ -854,12 +853,12 @@ done_copyin: copyin_fault: popl %edi popl %esi - GETCURPCB(%edx) + movl _curpcb,%edx movl $0,PCB_ONFAULT(%edx) movl $EFAULT,%eax ret -#if defined(I586_CPU) && NNPX > 0 && !defined(SMP) +#if defined(I586_CPU) && NNPX > 0 ENTRY(i586_copyin) /* * Duplicated from generic_copyin. Could be done a bit better. @@ -894,7 +893,7 @@ ENTRY(i586_copyin) jmp done_copyin #endif /* I586_CPU && NNPX > 0 */ -#if defined(I586_CPU) && NNPX > 0 && !defined(SMP) +#if defined(I586_CPU) && NNPX > 0 /* fastmove(src, dst, len) src in %esi dst in %edi @@ -1086,7 +1085,7 @@ fastmove_tail_fault: * fu{byte,sword,word} : fetch a byte (sword, word) from user memory */ ENTRY(fuword) - GETCURPCB(%ecx) + movl _curpcb,%ecx movl $fusufault,PCB_ONFAULT(%ecx) movl 4(%esp),%edx /* from */ @@ -1109,7 +1108,7 @@ ENTRY(fuswintr) ret ENTRY(fusword) - GETCURPCB(%ecx) + movl _curpcb,%ecx movl $fusufault,PCB_ONFAULT(%ecx) movl 4(%esp),%edx @@ -1121,7 +1120,7 @@ ENTRY(fusword) ret ENTRY(fubyte) - GETCURPCB(%ecx) + movl _curpcb,%ecx movl $fusufault,PCB_ONFAULT(%ecx) movl 4(%esp),%edx @@ -1134,7 +1133,7 @@ ENTRY(fubyte) ALIGN_TEXT fusufault: - GETCURPCB(%ecx) + movl _curpcb,%ecx xorl %eax,%eax movl %eax,PCB_ONFAULT(%ecx) decl %eax @@ -1144,7 +1143,7 @@ fusufault: * su{byte,sword,word}: write a byte (word, longword) to user memory */ ENTRY(suword) - GETCURPCB(%ecx) + movl _curpcb,%ecx movl $fusufault,PCB_ONFAULT(%ecx) movl 4(%esp),%edx @@ -1188,12 +1187,12 @@ ENTRY(suword) movl 8(%esp),%eax movl %eax,(%edx) xorl %eax,%eax - GETCURPCB(%ecx) + movl _curpcb,%ecx movl %eax,PCB_ONFAULT(%ecx) ret ENTRY(susword) - GETCURPCB(%ecx) + movl _curpcb,%ecx movl $fusufault,PCB_ONFAULT(%ecx) movl 4(%esp),%edx @@ -1237,13 +1236,13 @@ ENTRY(susword) movw 8(%esp),%ax movw %ax,(%edx) xorl %eax,%eax - GETCURPCB(%ecx) /* restore trashed register */ + movl _curpcb,%ecx /* restore trashed register */ movl %eax,PCB_ONFAULT(%ecx) ret ALTENTRY(suibyte) ENTRY(subyte) - GETCURPCB(%ecx) + movl _curpcb,%ecx movl $fusufault,PCB_ONFAULT(%ecx) movl 4(%esp),%edx @@ -1286,7 +1285,7 @@ ENTRY(subyte) movb 8(%esp),%al movb %al,(%edx) xorl %eax,%eax - GETCURPCB(%ecx) /* restore trashed register */ + movl _curpcb,%ecx /* restore trashed register */ movl %eax,PCB_ONFAULT(%ecx) ret @@ -1300,7 +1299,7 @@ ENTRY(subyte) ENTRY(copyinstr) pushl %esi pushl %edi - GETCURPCB(%ecx) + movl _curpcb,%ecx movl $cpystrflt,PCB_ONFAULT(%ecx) movl 12(%esp),%esi /* %esi = from */ @@ -1348,7 +1347,7 @@ cpystrflt: cpystrflt_x: /* set *lencopied and return %eax */ - GETCURPCB(%ecx) + movl _curpcb,%ecx movl $0,PCB_ONFAULT(%ecx) movl 20(%esp),%ecx subl %edx,%ecx diff --git a/sys/amd64/amd64/swtch.s b/sys/amd64/amd64/swtch.s index 923d694..eacef02 100644 --- a/sys/amd64/amd64/swtch.s +++ b/sys/amd64/amd64/swtch.s @@ -33,22 +33,21 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: swtch.s,v 1.51 1997/05/31 09:27:29 peter Exp $ + * $Id: swtch.s,v 1.52 1997/06/07 04:36:10 bde Exp $ */ #include "npx.h" #include "opt_user_ldt.h" -#include "opt_smp_privpages.h" #include <sys/rtprio.h> #include <machine/asmacros.h> #include <machine/ipl.h> -#include <machine/smpasm.h> #include <machine/smptests.h> /** TEST_LOPRIO */ -#if defined(SMP) && defined(SMP_PRIVPAGES) +#if defined(SMP) #include <machine/pmap.h> +#include <machine/apic.h> #endif #include "assym.s" @@ -250,7 +249,7 @@ _idle: #ifdef SMP movl _smp_active, %eax cmpl $0, %eax - jnz badsw + jnz badsw3 #endif /* SMP */ xorl %ebp,%ebp movl $HIDENAME(tmpstk),%esp @@ -258,12 +257,7 @@ _idle: movl %ecx,%cr3 /* update common_tss.tss_esp0 pointer */ -#ifdef SMP - GETCPUID(%eax) - movl _SMPcommon_tss_ptr(,%eax,4), %eax -#else movl $_common_tss, %eax -#endif movl %esp, TSS_ESP0(%eax) #ifdef TSS_IS_CACHED /* example only */ @@ -315,7 +309,7 @@ ENTRY(default_halt) ENTRY(cpu_switch) /* switch to new process. first, save context as needed */ - GETCURPROC(%ecx) + movl _curproc,%ecx /* if no process to save, don't bother */ testl %ecx,%ecx @@ -342,16 +336,15 @@ ENTRY(cpu_switch) #ifdef SMP movl _mp_lock, %eax cmpl $0xffffffff, %eax /* is it free? */ - je badsw /* yes, bad medicine! */ + je badsw4 /* yes, bad medicine! */ andl $0x00ffffff, %eax /* clear CPU portion */ movl %eax,PCB_MPNEST(%ecx) /* store it */ #endif /* SMP */ #if NNPX > 0 /* have we used fp, and need a save? */ - GETCURPROC(%eax) - GETNPXPROC(%ebx) - cmp %eax,%ebx + movl _curproc,%eax + cmpl %eax,_npxproc jne 1f addl $PCB_SAVEFPU,%ecx /* h/w bugs make saving complicated */ pushl %ecx @@ -362,7 +355,7 @@ ENTRY(cpu_switch) movb $1,_intr_nesting_level /* charge Intr, not Sys/Idle */ - SETCURPROC($0, %edi) + movl $0,_curproc /* out of process */ /* save is done, now choose a new process or idle */ sw1: @@ -451,16 +444,16 @@ swtch_com: #ifdef DIAGNOSTIC cmpl %eax,P_WCHAN(%ecx) - jne badsw + jne badsw1 cmpb $SRUN,P_STAT(%ecx) - jne badsw + jne badsw2 #endif movl %eax,P_BACK(%ecx) /* isolate process to run */ movl P_ADDR(%ecx),%edx movl PCB_CR3(%edx),%ebx -#if defined(SMP) && defined(SMP_PRIVPAGES) +#if defined(SMP) /* Grab the private PT pointer from the outgoing process's PTD */ movl $_PTD,%esi movl 4*MPPTDI(%esi), %eax /* fetch cpu's prv pt */ @@ -469,7 +462,7 @@ swtch_com: /* switch address space */ movl %ebx,%cr3 -#if defined(SMP) && defined(SMP_PRIVPAGES) +#if defined(SMP) /* Copy the private PT to the new process's PTD */ /* XXX yuck, the _PTD changes when we switch, so we have to * reload %cr3 after changing the address space. @@ -477,7 +470,6 @@ swtch_com: * location of the per-process PTD in the PCB or something quick. * Dereferencing proc->vm_map->pmap->p_pdir[] is painful in asm. */ - movl $_PTD,%esi movl %eax, 4*MPPTDI(%esi) /* restore cpu's prv page */ /* XXX: we have just changed the page tables.. reload.. */ @@ -499,12 +491,7 @@ swtch_com: #endif /* update common_tss.tss_esp0 pointer */ -#ifdef SMP - GETCPUID(%eax) - movl _SMPcommon_tss_ptr(,%eax,4), %eax -#else movl $_common_tss, %eax -#endif movl %edx, %ebx /* pcb */ addl $(UPAGES * PAGE_SIZE), %ebx movl %ebx, TSS_ESP0(%eax) @@ -527,25 +514,22 @@ swtch_com: movl %eax,(%esp) #ifdef SMP - GETCPUID(%eax) + movl _cpuid,%eax movb %al, P_ONCPU(%ecx) #endif - SETCURPCB(%edx, %eax) - SETCURPROC(%ecx, %eax) + movl %edx,_curpcb + movl %ecx,_curproc /* into next process */ movb $0,_intr_nesting_level #ifdef SMP - movl _apic_base, %eax /* base addr of LOCAL APIC */ #if defined(TEST_LOPRIO) - pushl %edx - movl APIC_TPR(%eax), %edx /* get TPR register contents */ - andl $~0xff, %edx /* clear the prio field */ - movl %edx, APIC_TPR(%eax) /* now hold loprio for INTs */ - popl %edx + /* Set us to prefer to get irq's from the apic since we have the lock */ + movl lapic_tpr, %eax /* get TPR register contents */ + andl $0xffffff00, %eax /* clear the prio field */ + movl %eax, lapic_tpr /* now hold loprio for INTs */ #endif /* TEST_LOPRIO */ - movl APIC_ID(%eax), %eax /* APIC ID register */ - andl $APIC_ID_MASK, %eax /* extract ID portion */ - orl PCB_MPNEST(%edx), %eax /* add count from PROC */ + movl _cpu_lockid,%eax + orl PCB_MPNEST(%edx), %eax /* add next count from PROC */ movl %eax, _mp_lock /* load the mp_lock */ #endif /* SMP */ @@ -579,11 +563,33 @@ CROSSJUMPTARGET(idqr) CROSSJUMPTARGET(nortqr) CROSSJUMPTARGET(sw1a) -badsw: - pushl $sw0 +#ifdef DIAGNOSTIC +badsw1: + pushl $sw0_1 + call _panic + +sw0_1: .asciz "cpu_switch: has wchan" + +badsw2: + pushl $sw0_2 + call _panic + +sw0_2: .asciz "cpu_switch: not SRUN" +#endif + +#ifdef SMP +badsw3: + pushl $sw0_3 call _panic -sw0: .asciz "cpu_switch" +sw0_3: .asciz "cpu_switch: went idle with smp_active" + +badsw4: + pushl $sw0_4 + call _panic + +sw0_4: .asciz "cpu_switch: do not have lock" +#endif /* * savectx(pcb) @@ -618,7 +624,7 @@ ENTRY(savectx) * have to handle h/w bugs for reloading. We used to lose the * parent's npx state for forks by forgetting to reload. */ - GETNPXPROC(%eax) + movl _npxproc,%eax testl %eax,%eax je 1f diff --git a/sys/amd64/amd64/trap.c b/sys/amd64/amd64/trap.c index 89dd34f..8914a5b 100644 --- a/sys/amd64/amd64/trap.c +++ b/sys/amd64/amd64/trap.c @@ -35,7 +35,7 @@ * SUCH DAMAGE. * * from: @(#)trap.c 7.4 (Berkeley) 5/13/91 - * $Id: trap.c,v 1.98 1997/06/02 08:19:03 dfr Exp $ + * $Id: trap.c,v 1.99 1997/06/07 04:36:10 bde Exp $ */ /* @@ -87,11 +87,7 @@ #include "isa.h" #include "npx.h" -#ifdef SMP -extern struct i386tss *SMPcommon_tss_ptr[]; -#else extern struct i386tss common_tss; -#endif int (*pmath_emulate) __P((struct trapframe *)); @@ -704,7 +700,7 @@ trap_fatal(frame) type, trap_msg[type], ISPL(frame->tf_cs) == SEL_UPL ? "user" : "kernel"); #ifdef SMP - printf("cpunumber = %d\n", cpunumber()); + printf("cpuid = %d\n", cpuid); #endif if (type == T_PAGEFLT) { printf("fault virtual address = 0x%x\n", eva); @@ -790,19 +786,12 @@ trap_fatal(frame) void dblfault_handler() { -#ifdef SMP - int x = cpunumber(); -#endif - printf("\nFatal double fault:\n"); -#ifdef SMP - printf("eip = 0x%x\n", SMPcommon_tss_ptr[x]->tss_eip); - printf("esp = 0x%x\n", SMPcommon_tss_ptr[x]->tss_esp); - printf("ebp = 0x%x\n", SMPcommon_tss_ptr[x]->tss_ebp); -#else printf("eip = 0x%x\n", common_tss.tss_eip); printf("esp = 0x%x\n", common_tss.tss_esp); printf("ebp = 0x%x\n", common_tss.tss_ebp); +#ifdef SMP + printf("cpuid = %d\n", cpuid); #endif panic("double fault"); } diff --git a/sys/amd64/amd64/vm_machdep.c b/sys/amd64/amd64/vm_machdep.c index 6f1a4b6..5ad743d 100644 --- a/sys/amd64/amd64/vm_machdep.c +++ b/sys/amd64/amd64/vm_machdep.c @@ -38,7 +38,7 @@ * * from: @(#)vm_machdep.c 7.3 (Berkeley) 5/13/91 * Utah $Hdr: vm_machdep.c 1.16.1.1 89/06/23$ - * $Id: vm_machdep.c,v 1.79 1997/04/16 12:11:37 kato Exp $ + * $Id: vm_machdep.c,v 1.80 1997/05/07 20:19:18 peter Exp $ */ #include "npx.h" @@ -78,13 +78,6 @@ #include <i386/isa/isa.h> #endif -#ifdef SMP -extern struct proc *SMPnpxproc[]; -#define npxproc (SMPnpxproc[cpunumber()]) -#else -extern struct proc *npxproc; -#endif - #ifdef BOUNCE_BUFFERS static vm_offset_t vm_bounce_kva __P((int size, int waitok)); diff --git a/sys/amd64/include/apicreg.h b/sys/amd64/include/apicreg.h index 1d92faf..8e7f2a8 100644 --- a/sys/amd64/include/apicreg.h +++ b/sys/amd64/include/apicreg.h @@ -22,7 +22,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: apic.h,v 1.1 1997/05/28 19:43:45 smp Exp smp $ + * $Id: apic.h,v 1.3 1997/05/29 05:57:43 fsmp Exp $ */ #ifndef _MACHINE_APIC_H_ @@ -223,76 +223,6 @@ typedef struct IOAPIC ioapic_t; /* default physical locations of LOCAL (CPU) APICs */ #define DEFAULT_APIC_BASE 0xfee00000 -# if defined(LOCORE) - -#define APIC_ID 0x020 -#define APIC_VER 0x030 -#define APIC_TPR 0x080 -#define APIC_APR 0x090 -#define APIC_PPR 0x0a0 -#define APIC_EOI 0x0b0 -#define APIC_RR 0x0c0 -#define APIC_LDR 0x0d0 -#define APIC_DFR 0x0e0 -#define APIC_SVR 0x0f0 -#define APIC_ISR 0x100 -#define APIC_ISR0 0x100 -#define APIC_ISR1 0x110 -#define APIC_ISR2 0x120 -#define APIC_TMR 0x180 -#define APIC_IRR 0x200 -#define APIC_IRR0 0x200 -#define APIC_IRR1 0x210 -#define APIC_IRR2 0x220 -#define APIC_ESR 0x280 -#define APIC_ICR_LOW 0x300 -#define APIC_ICR_HI 0x310 -#define APIC_LVTT 0x320 -#define APIC_LVT1 0x350 -#define APIC_LVT2 0x360 -#define APIC_LVT3 0x370 -#define APIC_TICR 0x380 -#define APIC_TCCR 0x390 -#define APIC_TDCR 0x3e0 - -# else /* !LOCORE */ - -#if 0 /** XXX APIC_STRUCT */ -/* offsets in apic_base[] */ -#define APIC_ID (0x020/4) -#define APIC_VER (0x030/4) -#define APIC_TPR (0x080/4) -#define APIC_APR (0x090/4) -#define APIC_PPR (0x0a0/4) -#define APIC_EOI (0x0b0/4) -#define APIC_RR (0x0c0/4) -#define APIC_LDR (0x0d0/4) -#define APIC_DFR (0x0e0/4) -#define APIC_SVR (0x0f0/4) -#define APIC_ISR (0x100/4) -#define APIC_ISR0 (0x100/4) -#define APIC_ISR1 (0x110/4) -#define APIC_ISR2 (0x120/4) -#define APIC_TMR (0x180/4) -#define APIC_IRR (0x200/4) -#define APIC_IRR0 (0x200/4) -#define APIC_IRR1 (0x210/4) -#define APIC_IRR2 (0x220/4) -#define APIC_ESR (0x280/4) -#define APIC_ICR_LOW (0x300/4) -#define APIC_ICR_HI (0x310/4) -#define APIC_LVTT (0x320/4) -#define APIC_LVT1 (0x350/4) -#define APIC_LVT2 (0x360/4) -#define APIC_LVT3 (0x370/4) -#define APIC_TICR (0x380/4) -#define APIC_TCCR (0x390/4) -#define APIC_TDCR (0x3e0/4) -#endif /** XXX APIC_STRUCT */ - -# endif /* LOCORE */ - - /* fields in VER */ #define APIC_VER_VERSION 0x000000ff #define APIC_VER_MAXLVT 0x00ff0000 @@ -501,45 +431,4 @@ typedef struct IOAPIC ioapic_t; #define IOART_INTVEC 0x000000ff /* R/W: INTerrupt vector field */ -/** - * XXX FIXME: temproary defines till we get private pages... - */ -#if 1 /** XXX APIC_STRUCT */ - -/* XXX when automatically mapped to a virtual page */ -#define lapic__id lapic->id -#define lapic__version lapic->version -#define lapic__eoi lapic->eoi -#define lapic__irr1 lapic->irr1 -#define lapic__lvt_lint0 lapic->lvt_lint0 -#define lapic__lvt_lint1 lapic->lvt_lint1 -#define lapic__tpr lapic->tpr -#define lapic__svr lapic->svr -#define lapic__icr_lo lapic->icr_lo -#define lapic__icr_hi lapic->icr_hi -#define lapic__dcr_timer lapic->dcr_timer -#define lapic__lvt_timer lapic->lvt_timer -#define lapic__icr_timer lapic->icr_timer -#define lapic__ccr_timer lapic->ccr_timer - -#else - -/* XXX when mapped to a known virtual address */ -#define lapic__id lapic.id -#define lapic__version lapic.version -#define lapic__eoi lapic.eoi -#define lapic__irr1 lapic.irr1 -#define lapic__lvt_lint0 lapic.lvt_lint0 -#define lapic__lvt_lint1 lapic.lvt_lint1 -#define lapic__tpr lapic.tpr -#define lapic__svr lapic.svr -#define lapic__icr_lo lapic.icr_lo -#define lapic__icr_hi lapic.icr_hi -#define lapic__dcr_timer lapic.dcr_timer -#define lapic__lvt_timer lapic.lvt_timer -#define lapic__icr_timer lapic.icr_timer -#define lapic__ccr_timer lapic.ccr_timer - -#endif /** XXX APIC_STRUCT */ - #endif /* _MACHINE_APIC_H_ */ diff --git a/sys/amd64/include/fpu.h b/sys/amd64/include/fpu.h index 33c6a23..719142d 100644 --- a/sys/amd64/include/fpu.h +++ b/sys/amd64/include/fpu.h @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * from: @(#)npx.h 5.3 (Berkeley) 1/18/91 - * $Id$ + * $Id: npx.h,v 1.12 1997/02/22 09:34:52 peter Exp $ */ /* @@ -140,6 +140,8 @@ struct save87 { struct proc; +extern struct proc *npxproc; + int npxdna __P((void)); void npxexit __P((struct proc *p)); void npxinit __P((int control)); diff --git a/sys/amd64/include/mptable.h b/sys/amd64/include/mptable.h index a27cf86..c817925 100644 --- a/sys/amd64/include/mptable.h +++ b/sys/amd64/include/mptable.h @@ -22,11 +22,10 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: mp_machdep.c,v 1.16 1997/05/29 05:58:41 fsmp Exp $ + * $Id: mp_machdep.c,v 1.17 1997/06/02 10:44:08 dfr Exp $ */ #include "opt_smp.h" -#include "opt_serial.h" #include <sys/param.h> /* for KERNBASE */ #include <sys/types.h> @@ -38,18 +37,21 @@ #include <vm/vm_param.h> /* for KERNBASE */ #include <vm/pmap.h> /* for KERNBASE */ #include <machine/pmap.h> /* for KERNBASE */ +#include <vm/vm_kern.h> +#include <vm/vm_extern.h> #include <machine/smp.h> #include <machine/apic.h> #include <machine/mpapic.h> #include <machine/cpufunc.h> #include <machine/segments.h> -#include <machine/smptests.h> /** TEST_DEFAULT_CONFIG, LATE_START */ +#include <machine/smptests.h> /** TEST_DEFAULT_CONFIG */ +#include <machine/tss.h> #include <i386/i386/cons.h> /* cngetc() */ #if defined(APIC_IO) -#include <i386/include/md_var.h> /* setidt() */ +#include <machine/md_var.h> /* setidt() */ #include <i386/isa/icu.h> /* Xinvltlb() */ #include <i386/isa/intr_machdep.h> /* Xinvltlb() */ #endif /* APIC_IO */ @@ -186,11 +188,6 @@ typedef struct BASETABLE_ENTRY { /** FIXME: what system files declare these??? */ extern struct region_descriptor r_gdt, r_idt; -/* global data */ -struct proc *SMPcurproc[NCPU]; -struct pcb *SMPcurpcb[NCPU]; -struct timeval SMPruntime[NCPU]; - int mp_ncpus; /* # of CPUs, including BSP */ int mp_naps; /* # of Applications processors */ int mp_nbusses; /* # of busses */ @@ -210,6 +207,15 @@ int cpu_num_to_apic_id[NAPICID]; int io_num_to_apic_id[NAPICID]; int apic_id_to_logical[NAPICID]; +/* Boot of AP uses this PTD */ +u_int *bootPTD; + +/* Hotwire a 0->4MB V==P mapping */ +extern pt_entry_t KPTphys; + +/* virtual address of per-cpu common_tss */ +extern struct i386tss common_tss; + /* * look for MP compliant motherboard. */ @@ -283,11 +289,6 @@ found: /* please forgive the 'goto'! */ if (mptable_pass1()) panic("you must reconfigure your kernel"); -#if defined(LATE_START) - /* create pages for (address common) cpu APIC and each IO APIC */ - pmap_bootstrap_apics(); -#endif /* LATE_START */ - /* flag fact that we are running multiple processors */ mp_capable = 1; return 1; @@ -305,9 +306,6 @@ mp_start(void) mp_enable(boot_address); else panic("MP hardware not found!"); - - /* finish pmap initialization - turn off V==P mapping at zero */ - pmap_bootstrap2(); } @@ -321,23 +319,25 @@ mp_announce(void) printf("FreeBSD/SMP: Multiprocessor motherboard\n"); printf(" cpu0 (BSP): apic id: %d", CPU_TO_ID(0)); - printf(", version: 0x%08x\n", cpu_apic_versions[0]); + printf(", version: 0x%08x", cpu_apic_versions[0]); + printf(", at 0x%08x\n", cpu_apic_address); for (x = 1; x <= mp_naps; ++x) { printf(" cpu%d (AP): apic id: %d", x, CPU_TO_ID(x)); - printf(", version: 0x%08x\n", cpu_apic_versions[x]); + printf(", version: 0x%08x", cpu_apic_versions[x]); + printf(", at 0x%08x\n", cpu_apic_address); } #if defined(APIC_IO) for (x = 0; x < mp_napics; ++x) { printf(" io%d (APIC): apic id: %d", x, IO_TO_ID(x)); - printf(", version: 0x%08x\n", io_apic_versions[x]); + printf(", version: 0x%08x", io_apic_versions[x]); + printf(", at 0x%08x\n", io_apic_address[x]); } #else printf(" Warning: APIC I/O disabled\n"); #endif /* APIC_IO */ } - /* * AP cpu's call this to sync up protected mode. */ @@ -352,12 +352,18 @@ init_secondary(void) lidt(&r_idt); lldt(_default_ldt); - slot = NGDT + cpunumber(); + slot = NGDT + cpuid; gsel_tss = GSEL(slot, SEL_KPL); gdt[slot].sd.sd_type = SDT_SYS386TSS; + common_tss.tss_esp0 = 0; /* not used until after switch */ + common_tss.tss_ss0 = GSEL(GDATA_SEL, SEL_KPL); + common_tss.tss_ioopt = (sizeof common_tss) << 16; ltr(gsel_tss); load_cr0(0x8005003b); /* XXX! */ + + PTD[0] = 0; + invltlb(); } @@ -375,9 +381,9 @@ configure_local_apic(void) outb(0x23, byte); /* disconnect 8259s/NMI */ } /* mask the LVT1 */ - temp = lapic__lvt_lint0; + temp = lapic.lvt_lint0; temp |= APIC_LVT_M; - lapic__lvt_lint0 = temp; + lapic.lvt_lint0 = temp; } #endif /* APIC_IO */ @@ -398,13 +404,15 @@ mp_enable(u_int boot_addr) u_int ux; #endif /* APIC_IO */ - /* examine the MP table for needed info */ + /* Turn on 4MB of V == P addressing so we can get to MP table */ + *(int *)PTD = PG_V | PG_RW | ((u_long)KPTphys & PG_FRAME); + invltlb(); + + /* examine the MP table for needed info, uses physical addresses */ x = mptable_pass2(); -#if !defined(LATE_START) - /* create pages for (address common) cpu APIC and each IO APIC */ - pmap_bootstrap_apics(); -#endif /* LATE_START */ + *(int *)PTD = 0; + invltlb(); /* can't process default configs till the CPU APIC is pmapped */ if (x) @@ -832,7 +840,7 @@ fix_mp_table(void) for (x = 0; x < mp_nbusses; ++x) { if (bus_data[x].bus_type != PCI) continue; - if (bus_data[x].bus_id >= num_pci_bus ) + if (bus_data[x].bus_id >= num_pci_bus) panic("bad PCI bus numbering"); } } @@ -1258,7 +1266,7 @@ default_mp_table(int type) } #endif /* 0 */ - boot_cpu_id = (lapic__id & APIC_ID_MASK) >> 24; + boot_cpu_id = (lapic.id & APIC_ID_MASK) >> 24; ap_cpu_id = (boot_cpu_id == 0) ? 1 : 0; /* BSP */ @@ -1351,9 +1359,12 @@ default_mp_table(int type) static int start_all_aps(u_int boot_addr) { - int x; + int x, i; u_char mpbiosreason; u_long mpbioswarmvec; + pd_entry_t newptd; + pt_entry_t newpt; + int *newpp; /** * NOTE: this needs further thought: @@ -1362,7 +1373,7 @@ start_all_aps(u_int boot_addr) * * get the initial mp_lock with a count of 1 for the BSP */ - mp_lock = (lapic__id & APIC_ID_MASK) + 1; + mp_lock = (lapic.id & APIC_ID_MASK) + 1; /* initialize BSP's local APIC */ apic_initialize(1); @@ -1370,6 +1381,7 @@ start_all_aps(u_int boot_addr) /* install the AP 1st level boot code */ install_ap_tramp(boot_addr); + /* save the current value of the warm-start vector */ mpbioswarmvec = *((u_long *) WARMBOOT_OFF); outb(CMOS_REG, BIOS_RESET); @@ -1378,6 +1390,58 @@ start_all_aps(u_int boot_addr) /* start each AP */ for (x = 1; x <= mp_naps; ++x) { + /* HACK HACK HACK !!! */ + + /* alloc new page table directory */ + newptd = (pd_entry_t)(kmem_alloc(kernel_map, PAGE_SIZE)); + + /* clone currently active one (ie: IdlePTD) */ + bcopy(PTD, newptd, PAGE_SIZE); /* inc prv page pde */ + + /* set up 0 -> 4MB P==V mapping for AP boot */ + newptd[0] = PG_V | PG_RW | ((u_long)KPTphys & PG_FRAME); + + /* store PTD for this AP */ + bootPTD = (pd_entry_t)vtophys(newptd); + + /* alloc new page table page */ + newpt = (pt_entry_t)(kmem_alloc(kernel_map, PAGE_SIZE)); + + /* set the new PTD's private page to point there */ + newptd[MPPTDI] = PG_V | PG_RW | vtophys(newpt); + + /* install self referential entry */ + newptd[PTDPTDI] = PG_V | PG_RW | vtophys(newptd); + + /* get a new private data page */ + newpp = (int *)kmem_alloc(kernel_map, PAGE_SIZE); + + /* wire it into the private page table page */ + newpt[0] = PG_V | PG_RW | vtophys(newpp); + + /* wire the ptp into itself for access */ + newpt[1] = PG_V | PG_RW | vtophys(newpt); + + /* and the local apic */ + newpt[2] = SMP_prvpt[2]; + + /* and the IO apic mapping[s] */ + for (i = 16; i < 32; i++) + newpt[i] = SMP_prvpt[i]; + + /* prime data page for it to use */ + newpp[0] = x; /* cpuid */ + newpp[1] = 0; /* curproc */ + newpp[2] = 0; /* curpcb */ + newpp[3] = 0; /* npxproc */ + newpp[4] = 0; /* runtime.tv_sec */ + newpp[5] = 0; /* runtime.tv_usec */ + newpp[6] = x << 24; /* cpu_lockid */ + + /* XXX NOTE: ABANDON bootPTD for now!!!! */ + + /* END REVOLTING HACKERY */ + /* setup a vector to our boot code */ *((volatile u_short *) WARMBOOT_OFF) = WARMBOOT_TARGET; *((volatile u_short *) WARMBOOT_SEG) = (boot_addr >> 4); @@ -1401,7 +1465,7 @@ start_all_aps(u_int boot_addr) } /* fill in our (BSP) APIC version */ - cpu_apic_versions[0] = lapic__version; + cpu_apic_versions[0] = lapic.version; /* restore the warmstart vector */ *(u_long *) WARMBOOT_OFF = mpbioswarmvec; @@ -1503,24 +1567,24 @@ start_ap(int logical_cpu, u_int boot_addr) */ /* setup the address for the target AP */ - icr_hi = lapic__icr_hi & ~APIC_ID_MASK; + icr_hi = lapic.icr_hi & ~APIC_ID_MASK; icr_hi |= (physical_cpu << 24); - lapic__icr_hi = icr_hi; + lapic.icr_hi = icr_hi; /* do an INIT IPI: assert RESET */ - icr_lo = lapic__icr_lo & 0xfff00000; - lapic__icr_lo = icr_lo | 0x0000c500; + icr_lo = lapic.icr_lo & 0xfff00000; + lapic.icr_lo = icr_lo | 0x0000c500; /* wait for pending status end */ - while (lapic__icr_lo & APIC_DELSTAT_MASK) + while (lapic.icr_lo & APIC_DELSTAT_MASK) /* spin */ ; /* do an INIT IPI: deassert RESET */ - lapic__icr_lo = icr_lo | 0x00008500; + lapic.icr_lo = icr_lo | 0x00008500; /* wait for pending status end */ u_sleep(10000); /* wait ~10mS */ - while (lapic__icr_lo & APIC_DELSTAT_MASK) + while (lapic.icr_lo & APIC_DELSTAT_MASK) /* spin */ ; /* @@ -1533,8 +1597,8 @@ start_ap(int logical_cpu, u_int boot_addr) */ /* do a STARTUP IPI */ - lapic__icr_lo = icr_lo | 0x00000600 | vector; - while (lapic__icr_lo & APIC_DELSTAT_MASK) + lapic.icr_lo = icr_lo | 0x00000600 | vector; + while (lapic.icr_lo & APIC_DELSTAT_MASK) /* spin */ ; u_sleep(200); /* wait ~200uS */ @@ -1545,8 +1609,8 @@ start_ap(int logical_cpu, u_int boot_addr) * recognized after hardware RESET or INIT IPI. */ - lapic__icr_lo = icr_lo | 0x00000600 | vector; - while (lapic__icr_lo & APIC_DELSTAT_MASK) + lapic.icr_lo = icr_lo | 0x00000600 | vector; + while (lapic.icr_lo & APIC_DELSTAT_MASK) /* spin */ ; u_sleep(200); /* wait ~200uS */ diff --git a/sys/amd64/include/npx.h b/sys/amd64/include/npx.h index 33c6a23..719142d 100644 --- a/sys/amd64/include/npx.h +++ b/sys/amd64/include/npx.h @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * from: @(#)npx.h 5.3 (Berkeley) 1/18/91 - * $Id$ + * $Id: npx.h,v 1.12 1997/02/22 09:34:52 peter Exp $ */ /* @@ -140,6 +140,8 @@ struct save87 { struct proc; +extern struct proc *npxproc; + int npxdna __P((void)); void npxexit __P((struct proc *p)); void npxinit __P((int control)); diff --git a/sys/amd64/include/pcb.h b/sys/amd64/include/pcb.h index c93ed87..18a9af1 100644 --- a/sys/amd64/include/pcb.h +++ b/sys/amd64/include/pcb.h @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * from: @(#)pcb.h 5.10 (Berkeley) 5/12/91 - * $Id: pcb.h,v 1.21 1997/05/07 19:49:32 peter Exp $ + * $Id: pcb.h,v 1.22 1997/06/07 04:36:05 bde Exp $ */ #ifndef _I386_PCB_H_ @@ -45,9 +45,6 @@ */ #include <machine/tss.h> #include <machine/npx.h> -#if defined(KERNEL) && defined(SMP) -#include <machine/smp.h> /* cpunumber() */ -#endif struct pcb { int pcb_cr3; @@ -82,12 +79,7 @@ struct md_coredump { #ifdef KERNEL -#ifdef SMP -extern struct pcb *SMPcurpcb[]; /* our current running pcb */ -#define curpcb (SMPcurpcb[cpunumber()]) -#else /* !SMP */ extern struct pcb *curpcb; /* our current running pcb */ -#endif /* SMP */ void savectx __P((struct pcb*)); #endif diff --git a/sys/amd64/include/pmap.h b/sys/amd64/include/pmap.h index f0d4c01..f00d4f2 100644 --- a/sys/amd64/include/pmap.h +++ b/sys/amd64/include/pmap.h @@ -42,7 +42,7 @@ * * from: hp300: @(#)pmap.h 7.2 (Berkeley) 12/16/90 * from: @(#)pmap.h 7.4 (Berkeley) 5/12/91 - * $Id: pmap.h,v 1.49 1997/04/07 09:30:20 peter Exp $ + * $Id: pmap.h,v 1.50 1997/04/26 11:45:41 peter Exp $ */ #ifndef _MACHINE_PMAP_H_ @@ -91,11 +91,11 @@ #define NKPT 9 /* actual number of kernel page tables */ #endif #ifndef NKPDE -#if defined(SMP) && defined(SMP_PRIVPAGES) +#ifdef SMP #define NKPDE 62 /* addressable number of page tables/pde's */ -#else /* SMP && SMP_PRIVPAGES */ +#else #define NKPDE 63 /* addressable number of page tables/pde's */ -#endif /* SMP && SMP_PRIVPAGES */ +#endif /* SMP */ #endif /* @@ -107,12 +107,12 @@ * SMP_PRIVPAGES: The per-cpu address space is 0xff80000 -> 0xffbfffff */ #define APTDPTDI (NPDEPG-1) /* alt ptd entry that points to APTD */ -#if defined(SMP) && defined(SMP_PRIVPAGES) +#ifdef SMP #define MPPTDI (APTDPTDI-1) /* per cpu ptd entry */ #define KPTDI (MPPTDI-NKPDE) /* start of kernel virtual pde's */ -#else /* SMP && SMP_PRIVPAGES */ +#else #define KPTDI (APTDPTDI-NKPDE)/* start of kernel virtual pde's */ -#endif /* SMP && SMP_PRIVPAGES */ +#endif /* SMP */ #define PTDPTDI (KPTDI-1) /* ptd entry that points to ptd! */ #define UMAXPTDI (PTDPTDI-1) /* ptd entry for user space end */ #define UMAXPTEOFF (NPTEPG-UPAGES_HOLE) /* pte entry for user space end */ @@ -141,7 +141,7 @@ typedef unsigned int *pt_entry_t; extern pt_entry_t PTmap[], APTmap[], Upte; extern pd_entry_t PTD[], APTD[], PTDpde, APTDpde, Upde; -extern int IdlePTD; /* physical address of "Idle" state directory */ +extern pd_entry_t IdlePTD; /* physical address of "Idle" state directory */ #endif /* diff --git a/sys/amd64/include/smp.h b/sys/amd64/include/smp.h index ee96269..2943764 100644 --- a/sys/amd64/include/smp.h +++ b/sys/amd64/include/smp.h @@ -6,7 +6,7 @@ * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp * ---------------------------------------------------------------------------- * - * $Id: smp.h,v 1.9 1997/05/28 18:44:11 fsmp Exp $ + * $Id: smp.h,v 1.10 1997/05/29 05:57:43 fsmp Exp $ * */ @@ -56,6 +56,8 @@ extern u_int32_t io_apic_versions[]; extern int cpu_num_to_apic_id[]; extern int io_num_to_apic_id[]; extern int apic_id_to_logical[]; +extern u_int SMP_prvpt[]; +extern u_char SMP_ioapic[]; /* functions in mp_machdep.c */ u_int mp_bootaddress __P((u_int)); @@ -79,18 +81,12 @@ void init_secondary __P((void)); void smp_invltlb __P((void)); /* global data in mpapic.c */ -extern volatile u_int* apic_base; -#if 1 /** XXX APIC_STRUCT */ -extern volatile lapic_t* lapic; -#endif /** XXX APIC_STRUCT */ +extern volatile lapic_t lapic; #if defined(MULTIPLE_IOAPICS) #error MULTIPLE_IOAPICSXXX #else -extern volatile u_int* io_apic_base; -#if 1 /** XXX APIC_STRUCT */ -extern volatile ioapic_t* ioapic; -#endif /** XXX APIC_STRUCT */ +extern volatile ioapic_t *ioapic[]; #endif /* MULTIPLE_IOAPICS */ /* functions in mpapic.c */ @@ -114,32 +110,8 @@ void u_sleep __P((int)); extern int smp_active; extern int invltlb_ok; -/* in pmap.c FIXME: belongs in pmap.h??? */ -void pmap_bootstrap_apics __P((void)); -void pmap_bootstrap2 __P((void)); - -#if 0 -/* chicken and egg problem... */ -static __inline unsigned -cpunumber(void) -{ - return (unsigned)ID_TO_CPU((apic_base[APIC_ID] & APIC_ID_MASK) >> 24); -} -#else -/* - * we 'borrow' this info from apic.h - * this will go away soon... - */ -static __inline unsigned -cpunumber(void) -{ -#if 0 - return (unsigned)(apic_id_to_logical[(apic_base[8] & 0x0f000000) >> 24]); -#else - return (unsigned)(apic_id_to_logical[(lapic__id & 0x0f000000) >> 24]); -#endif -} -#endif /* 0 */ +extern volatile u_int cpuid; +extern volatile u_int cpu_lockid; #endif /* SMP || APIC_IO */ #endif /* KERNEL */ diff --git a/sys/amd64/isa/intr_machdep.c b/sys/amd64/isa/intr_machdep.c index 81557c3..d1caa64 100644 --- a/sys/amd64/isa/intr_machdep.c +++ b/sys/amd64/isa/intr_machdep.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * from: @(#)isa.c 7.2 (Berkeley) 5/13/91 - * $Id: intr_machdep.c,v 1.1 1997/06/02 08:19:04 dfr Exp $ + * $Id: intr_machdep.c,v 1.2 1997/06/02 15:28:10 kato Exp $ */ #include "opt_auto_eoi.h" @@ -268,7 +268,7 @@ isa_irq_pending(dvp) struct isa_device *dvp; { /* read APIC IRR containing the 16 ISA INTerrupts */ - return ((lapic__irr1 & 0x00ffffff) + return ((lapic.irr1 & 0x00ffffff) & (u_int32_t)dvp->id_irq) ? 1 : 0; } diff --git a/sys/amd64/isa/nmi.c b/sys/amd64/isa/nmi.c index 81557c3..d1caa64 100644 --- a/sys/amd64/isa/nmi.c +++ b/sys/amd64/isa/nmi.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * from: @(#)isa.c 7.2 (Berkeley) 5/13/91 - * $Id: intr_machdep.c,v 1.1 1997/06/02 08:19:04 dfr Exp $ + * $Id: intr_machdep.c,v 1.2 1997/06/02 15:28:10 kato Exp $ */ #include "opt_auto_eoi.h" @@ -268,7 +268,7 @@ isa_irq_pending(dvp) struct isa_device *dvp; { /* read APIC IRR containing the 16 ISA INTerrupts */ - return ((lapic__irr1 & 0x00ffffff) + return ((lapic.irr1 & 0x00ffffff) & (u_int32_t)dvp->id_irq) ? 1 : 0; } diff --git a/sys/amd64/isa/npx.c b/sys/amd64/isa/npx.c index aca74fa..14487c95 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.44 1997/05/31 09:27:31 peter Exp $ + * $Id: npx.c,v 1.45 1997/06/02 08:19:05 dfr Exp $ */ #include "npx.h" @@ -63,6 +63,7 @@ #include <machine/clock.h> #include <machine/specialreg.h> #if defined(APIC_IO) +#include <machine/smp.h> #include <machine/apic.h> #include <machine/mpapic.h> #endif /* APIC_IO */ @@ -140,10 +141,8 @@ 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 + +#ifndef SMP /* XXX per-cpu on smp */ struct proc *npxproc; #endif @@ -172,8 +171,8 @@ asm 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) + movl $lapic_eoi,%eax # EOI to local APIC + movl $0,(%eax) # movl $0, APIC_EOI(%eax) movb $0,%al outb %al,$0xf0 # clear BUSY# latch popl %eax diff --git a/sys/conf/NOTES b/sys/conf/NOTES index 16d2d79..3d62526 100644 --- a/sys/conf/NOTES +++ b/sys/conf/NOTES @@ -2,7 +2,7 @@ # LINT -- config file for checking all the sources, tries to pull in # as much of the source tree as it can. # -# $Id: LINT,v 1.344 1997/06/06 12:24:43 jkh Exp $ +# $Id: LINT,v 1.345 1997/06/17 05:58:15 kjc Exp $ # # NB: You probably don't want to try running a kernel built from this # file. Instead, you should start from GENERIC, and add options from @@ -71,9 +71,6 @@ config kernel root on wd0 dumps on wd0 # NAPIC sets the number of IO APICs on the motherboard, defaults to 1. # NINTR sets the total number of INTs provided by the motherboard. # -# SMP_AUTOSTART automates the startup of the additional CPUs. -# SMP_PRIVPAGES maintain 'per-CPU' private data, NOT implemented yet! -# # SMP_TIMER_NC is for motherboards that claim 8254 connectivity to the IO APIC, # when in fact it is NOT connected. # @@ -91,18 +88,12 @@ config kernel root on wd0 dumps on wd0 options SMP # Symmetric MultiProcessor Kernel options APIC_IO # Symmetric (APIC) I/O -# Useful: -options SMP_AUTOSTART # start the additional CPUs during boot - # Optional, these are the defaults: #options NCPU=2 # number of CPUs #options NBUS=4 # number of busses #options NAPIC=1 # number of IO APICs #options NINTR=24 # number of INTs -# Currently unusable: -#options SMP_PRIVPAGES # BROKEN: architecture problem - # # Rogue SMP hardware: # diff --git a/sys/conf/options.i386 b/sys/conf/options.i386 index 094c986..275753e 100644 --- a/sys/conf/options.i386 +++ b/sys/conf/options.i386 @@ -1,4 +1,4 @@ -# $Id: options.i386,v 1.46 1997/06/04 04:55:00 pst Exp $ +# $Id: options.i386,v 1.47 1997/06/04 16:25:07 pst Exp $ BOUNCEPAGES opt_bounce.h USER_LDT @@ -41,12 +41,6 @@ NAPIC opt_smp.h NINTR opt_smp.h SMP_TIMER_NC opt_smp.h -# These three are known to be broken, don't enable them. -SMP_PRIVPAGES opt_smp_privpages.h -SMP_AUTOSTART opt_smp_autostart.h - -SERIAL_DEBUG opt_serial.h - AHC_TAGENABLE opt_aic7xxx.h AHC_SCBPAGING_ENABLE opt_aic7xxx.h AHC_ALLOW_MEMIO opt_aic7xxx.h diff --git a/sys/i386/conf/LINT b/sys/i386/conf/LINT index 16d2d79..3d62526 100644 --- a/sys/i386/conf/LINT +++ b/sys/i386/conf/LINT @@ -2,7 +2,7 @@ # LINT -- config file for checking all the sources, tries to pull in # as much of the source tree as it can. # -# $Id: LINT,v 1.344 1997/06/06 12:24:43 jkh Exp $ +# $Id: LINT,v 1.345 1997/06/17 05:58:15 kjc Exp $ # # NB: You probably don't want to try running a kernel built from this # file. Instead, you should start from GENERIC, and add options from @@ -71,9 +71,6 @@ config kernel root on wd0 dumps on wd0 # NAPIC sets the number of IO APICs on the motherboard, defaults to 1. # NINTR sets the total number of INTs provided by the motherboard. # -# SMP_AUTOSTART automates the startup of the additional CPUs. -# SMP_PRIVPAGES maintain 'per-CPU' private data, NOT implemented yet! -# # SMP_TIMER_NC is for motherboards that claim 8254 connectivity to the IO APIC, # when in fact it is NOT connected. # @@ -91,18 +88,12 @@ config kernel root on wd0 dumps on wd0 options SMP # Symmetric MultiProcessor Kernel options APIC_IO # Symmetric (APIC) I/O -# Useful: -options SMP_AUTOSTART # start the additional CPUs during boot - # Optional, these are the defaults: #options NCPU=2 # number of CPUs #options NBUS=4 # number of busses #options NAPIC=1 # number of IO APICs #options NINTR=24 # number of INTs -# Currently unusable: -#options SMP_PRIVPAGES # BROKEN: architecture problem - # # Rogue SMP hardware: # diff --git a/sys/i386/conf/NOTES b/sys/i386/conf/NOTES index 16d2d79..3d62526 100644 --- a/sys/i386/conf/NOTES +++ b/sys/i386/conf/NOTES @@ -2,7 +2,7 @@ # LINT -- config file for checking all the sources, tries to pull in # as much of the source tree as it can. # -# $Id: LINT,v 1.344 1997/06/06 12:24:43 jkh Exp $ +# $Id: LINT,v 1.345 1997/06/17 05:58:15 kjc Exp $ # # NB: You probably don't want to try running a kernel built from this # file. Instead, you should start from GENERIC, and add options from @@ -71,9 +71,6 @@ config kernel root on wd0 dumps on wd0 # NAPIC sets the number of IO APICs on the motherboard, defaults to 1. # NINTR sets the total number of INTs provided by the motherboard. # -# SMP_AUTOSTART automates the startup of the additional CPUs. -# SMP_PRIVPAGES maintain 'per-CPU' private data, NOT implemented yet! -# # SMP_TIMER_NC is for motherboards that claim 8254 connectivity to the IO APIC, # when in fact it is NOT connected. # @@ -91,18 +88,12 @@ config kernel root on wd0 dumps on wd0 options SMP # Symmetric MultiProcessor Kernel options APIC_IO # Symmetric (APIC) I/O -# Useful: -options SMP_AUTOSTART # start the additional CPUs during boot - # Optional, these are the defaults: #options NCPU=2 # number of CPUs #options NBUS=4 # number of busses #options NAPIC=1 # number of IO APICs #options NINTR=24 # number of INTs -# Currently unusable: -#options SMP_PRIVPAGES # BROKEN: architecture problem - # # Rogue SMP hardware: # diff --git a/sys/i386/conf/SMP-GENERIC b/sys/i386/conf/SMP-GENERIC index 5102816..e47c165 100644 --- a/sys/i386/conf/SMP-GENERIC +++ b/sys/i386/conf/SMP-GENERIC @@ -11,7 +11,7 @@ # device lines is present in the ./LINT configuration file. If you are # in doubt as to the purpose or necessity of a line, check first in LINT. # -# $Id: SMP-GENERIC,v 1.2 1997/05/06 20:40:52 fsmp Exp $ +# $Id: SMP-GENERIC,v 1.3 1997/05/11 19:01:24 andreas Exp $ machine "i386" # SMP does NOT support 386/486 CPUs. @@ -27,9 +27,6 @@ maxusers 10 options SMP # Symmetric MultiProcessor Kernel options APIC_IO # Symmetric (APIC) I/O -# Useful and reported to work: -options SMP_AUTOSTART # start the additional CPUs during boot - # Optional, these are the defaults: #options NCPU=2 # number of CPUs #options NBUS=4 # number of busses diff --git a/sys/i386/conf/options.i386 b/sys/i386/conf/options.i386 index 094c986..275753e 100644 --- a/sys/i386/conf/options.i386 +++ b/sys/i386/conf/options.i386 @@ -1,4 +1,4 @@ -# $Id: options.i386,v 1.46 1997/06/04 04:55:00 pst Exp $ +# $Id: options.i386,v 1.47 1997/06/04 16:25:07 pst Exp $ BOUNCEPAGES opt_bounce.h USER_LDT @@ -41,12 +41,6 @@ NAPIC opt_smp.h NINTR opt_smp.h SMP_TIMER_NC opt_smp.h -# These three are known to be broken, don't enable them. -SMP_PRIVPAGES opt_smp_privpages.h -SMP_AUTOSTART opt_smp_autostart.h - -SERIAL_DEBUG opt_serial.h - AHC_TAGENABLE opt_aic7xxx.h AHC_SCBPAGING_ENABLE opt_aic7xxx.h AHC_ALLOW_MEMIO opt_aic7xxx.h diff --git a/sys/i386/i386/apic_vector.s b/sys/i386/i386/apic_vector.s index 0817521..fa7edb0 100644 --- a/sys/i386/i386/apic_vector.s +++ b/sys/i386/i386/apic_vector.s @@ -1,6 +1,6 @@ /* * from: vector.s, 386BSD 0.1 unknown origin - * $Id: apic_vector.s,v 1.1 1997/05/26 17:58:26 fsmp Exp $ + * $Id: apic_vector.s,v 1.2 1997/05/31 08:59:51 peter Exp $ */ @@ -11,19 +11,19 @@ #define REDTBL_IDX(irq_num) (0x10 + ((irq_num) * 2)) /* - * 'lazy masking' code submitted by: Bruce Evans <bde@zeta.org.au> + * 'lazy masking' code suggested by Bruce Evans <bde@zeta.org.au> */ #define MAYBE_MASK_IRQ(irq_num) \ testl $IRQ_BIT(irq_num),iactive ; /* lazy masking */ \ je 1f ; /* NOT currently active */ \ orl $IRQ_BIT(irq_num),_imen ; /* set the mask bit */ \ - movl _io_apic_base,%ecx ; /* io apic addr */ \ + movl _ioapic,%ecx ; /* ioapic[0]addr */ \ movl $REDTBL_IDX(irq_num),(%ecx) ; /* write the index */ \ movl IOAPIC_WINDOW(%ecx),%eax ; /* current value */ \ orl $IOART_INTMASK,%eax ; /* set the mask */ \ movl %eax,IOAPIC_WINDOW(%ecx) ; /* new value */ \ - movl _apic_base, %eax ; \ - movl $0, APIC_EOI(%eax) ; \ + movl $lapic_eoi, %eax ; \ + movl $0, (%eax) ; \ orl $IRQ_BIT(irq_num), _ipending ; \ REL_MPLOCK ; /* SMP release global lock */ \ popl %es ; \ @@ -43,7 +43,7 @@ testl $IRQ_BIT(irq_num),_imen ; \ je 2f ; \ andl $~IRQ_BIT(irq_num),_imen ; /* clear mask bit */ \ - movl _io_apic_base,%ecx ; /* io apic addr */ \ + movl _ioapic,%ecx ; /* ioapic[0]addr */ \ movl $REDTBL_IDX(irq_num),(%ecx) ; /* write the index */ \ movl IOAPIC_WINDOW(%ecx),%eax ; /* current value */ \ andl $~IOART_INTMASK,%eax ; /* clear the mask */ \ @@ -72,8 +72,8 @@ IDTVEC(vec_name) ; \ GET_MPLOCK ; /* SMP Spin lock */ \ pushl _intr_unit + (irq_num) * 4 ; \ call *_intr_handler + (irq_num) * 4 ; /* do the work ASAP */ \ - movl _apic_base, %eax ; \ - movl $0, APIC_EOI(%eax) ; \ + movl $lapic_eoi, %eax ; \ + movl $0, (%eax) ; \ addl $4,%esp ; \ incl _cnt+V_INTR ; /* book-keeping can wait */ \ movl _intr_countp + (irq_num) * 4,%eax ; \ @@ -132,8 +132,8 @@ IDTVEC(vec_name) ; \ movl %ax,%es ; \ GET_MPLOCK ; /* SMP Spin lock */ \ MAYBE_MASK_IRQ(irq_num) ; \ - movl _apic_base, %eax ; \ - movl $0, APIC_EOI(%eax) ; \ + movl $lapic_eoi, %eax ; \ + movl $0, (%eax) ; \ movl _cpl,%eax ; \ testl $IRQ_BIT(irq_num), %eax ; \ jne 3f ; \ @@ -172,10 +172,9 @@ _Xinvltlb: pushl %eax movl %cr3, %eax /* invalidate the TLB */ movl %eax, %cr3 + movl $lapic_eoi, %eax ss /* stack segment, avoid %ds load */ - movl _apic_base, %eax - ss - movl $0, APIC_EOI(%eax) /* End Of Interrupt to APIC */ + movl $0, (%eax) /* End Of Interrupt to APIC */ popl %eax iret diff --git a/sys/i386/i386/exception.s b/sys/i386/i386/exception.s index 054e086..22ddf7f 100644 --- a/sys/i386/i386/exception.s +++ b/sys/i386/i386/exception.s @@ -30,7 +30,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: exception.s,v 1.28 1997/05/29 05:11:09 peter Exp $ + * $Id: exception.s,v 1.29 1997/05/31 09:27:28 peter Exp $ */ #include "npx.h" /* NNPX */ @@ -44,7 +44,7 @@ #include <sys/cdefs.h> /* CPP macros */ #ifdef SMP -#include <machine/smpasm.h> /* this includes <machine/apic.h> */ +#include <machine/apic.h> /* for apic_vector.s */ #define GET_MPLOCK call _get_mplock #define REL_MPLOCK call _rel_mplock #define MP_INSTR_LOCK lock @@ -270,13 +270,7 @@ ENTRY(fork_trampoline) movl $SWI_AST_MASK,_cpl call _splz -#ifdef SMP - GETCPUID(%eax) - leal _SMPruntime(,%eax,8), %eax - pushl %eax -#else pushl $_runtime -#endif /* SMP */ call _microtime popl %eax diff --git a/sys/i386/i386/locore.s b/sys/i386/i386/locore.s index b35cac7..44ddcbb 100644 --- a/sys/i386/i386/locore.s +++ b/sys/i386/i386/locore.s @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * from: @(#)locore.s 7.3 (Berkeley) 5/13/91 - * $Id: locore.s,v 1.87 1997/05/15 19:12:56 tegge Exp $ + * $Id: locore.s,v 1.88 1997/05/29 05:11:09 peter Exp $ * * originally from: locore.s, by William F. Jolitz * @@ -47,8 +47,7 @@ #include "opt_cpu.h" #include "opt_ddb.h" #include "opt_userconfig.h" -#include "opt_smp_privpages.h" -#include "opt_serial.h" +#include "opt_smp.h" #include <sys/errno.h> #include <sys/syscall.h> @@ -60,9 +59,9 @@ #include <machine/pmap.h> #include <machine/specialreg.h> -#if defined(SMP) && defined(SMP_PRIVPAGES) +#ifdef SMP #include <machine/apic.h> -#endif /* SMP && PRIVPAGES */ +#endif /* SMP */ #include "assym.s" @@ -92,6 +91,31 @@ .set _APTD,_APTmap + (APTDPTDI * PAGE_SIZE) .set _APTDpde,_PTD + (APTDPTDI * PDESIZE) +#ifdef SMP + .globl _SMP_prvstart + .set _SMP_prvstart,(MPPTDI << PDRSHIFT) + + .globl _SMP_prvpage,_SMP_prvpt,_lapic,_SMP_ioapic + .set _SMP_prvpage,_SMP_prvstart + .set _SMP_prvpt,_SMP_prvstart + PAGE_SIZE + .set _lapic,_SMP_prvstart + (2 * PAGE_SIZE) + .set _SMP_ioapic,_SMP_prvstart + (16 * PAGE_SIZE) + + .globl _cpuid,_curproc,_curpcb,_npxproc,_runtime,_cpu_lockid + .globl _common_tss + .set _cpuid,_SMP_prvpage+0 + .set _curproc,_SMP_prvpage+4 + .set _curpcb,_SMP_prvpage+8 + .set _npxproc,_SMP_prvpage+12 + .set _runtime,_SMP_prvpage+16 /* 8 bytes struct timeval */ + .set _cpu_lockid,_SMP_prvpage+24 + .set _common_tss,_SMP_prvpage+28 /* 104 bytes long, next = 132 */ + +/* Fetch the .set's for the local apic */ +#include "i386/i386/mp_apicdefs.s" + +#endif + /* * Globals */ @@ -117,18 +141,21 @@ _bootinfo: .space BOOTINFO_SIZE /* bootinfo that we can handle */ _KERNend: .long 0 /* phys addr end of kernel (just after bss) */ physfree: .long 0 /* phys addr of next free page */ -#if defined(SMP) && defined(SMP_PRIVPAGES) +#ifdef SMP cpu0pp: .long 0 /* phys addr cpu0 private pg */ cpu0pt: .long 0 /* phys addr cpu0 private pt */ .globl _cpu0prvpage,_cpu0prvpt _cpu0prvpage: .long 0 /* relocated version */ _cpu0prvpt: .long 0 /* relocated version */ -#endif /* SMP && PRIVPAGES */ +#endif /* SMP */ .globl _IdlePTD _IdlePTD: .long 0 /* phys addr of kernel PTD */ +#ifdef SMP + .globl _KPTphys +#endif _KPTphys: .long 0 /* phys addr of kernel page tables */ .globl _proc0paddr @@ -769,7 +796,7 @@ over_symalloc: addl $KERNBASE, %esi movl %esi, R(_proc0paddr) -#if defined(SMP) && defined(SMP_PRIVPAGES) +#ifdef SMP /* Allocate cpu0's private data page */ ALLOCPAGES(1) movl %esi,R(cpu0pp) @@ -781,7 +808,7 @@ over_symalloc: movl %esi,R(cpu0pt) addl $KERNBASE, %esi movl %esi, R(_cpu0prvpt) /* relocated to KVM space */ -#endif /* SMP && SMP_PRIVPAGES */ +#endif /* SMP */ /* Map read-only from zero to the end of the kernel text section */ xorl %eax, %eax @@ -830,41 +857,35 @@ map_read_write: movl $ISA_HOLE_LENGTH>>PAGE_SHIFT, %ecx fillkptphys($PG_RW) -#if defined(SMP) && defined(SMP_PRIVPAGES) -/* Map cpu0's private page into global KVM */ +#ifdef SMP +/* Map cpu0's private page into global kmem (4K @ cpu0prvpage) */ movl R(cpu0pp), %eax movl $1, %ecx fillkptphys($PG_RW) -/* Map cpu0's private page table into global KVM */ +/* Map cpu0's private page table into global kmem FWIW */ movl R(cpu0pt), %eax movl $1, %ecx fillkptphys($PG_RW) -/* Map the private page into the private page table (4K @ 0xff80000) */ +/* Map the private page into the private page table into private space */ movl R(cpu0pp), %eax movl $0, %ebx /* pte offset = 0 */ movl $1, %ecx /* one private page coming right up */ fillkpt(R(cpu0pt), $PG_RW) -/* Map the default Local APIC address (4K @ 0xff801000) */ - movl $DEFAULT_APIC_BASE, %eax /* XXX just testing.. */ +/* Map the page table page into private space */ + movl R(cpu0pt), %eax movl $1, %ebx /* pte offset = 1 */ - movl $1, %ecx /* Bing! Local APIC appears */ - fillkpt(R(cpu0pt), $PG_RW|PG_N) - -/* Map the default IO APIC address (4K @ 0xff802000) */ - movl $DEFAULT_IO_APIC_BASE, %eax /* XXX just testing.. */ - movl $2, %ebx /* pte offset = 2 */ - movl $1, %ecx /* Bing! Local APIC appears */ - fillkpt(R(cpu0pt), $PG_RW|PG_N) + movl $1, %ecx /* one private pt coming right up */ + fillkpt(R(cpu0pt), $PG_RW) -/* ... and put the page table in the pde. */ +/* ... and put the page table table in the pde. */ movl R(cpu0pt), %eax movl $MPPTDI, %ebx movl $1, %ecx fillkpt(R(_IdlePTD), $PG_RW) -#endif /* SMP && SMP_PRIVPAGES */ +#endif /* SMP */ /* install a pde for temporary double map of bottom of VA */ movl R(_KPTphys), %eax diff --git a/sys/i386/i386/machdep.c b/sys/i386/i386/machdep.c index 19838a2..4456e42 100644 --- a/sys/i386/i386/machdep.c +++ b/sys/i386/i386/machdep.c @@ -35,7 +35,7 @@ * SUCH DAMAGE. * * from: @(#)machdep.c 7.4 (Berkeley) 6/3/91 - * $Id: machdep.c,v 1.249 1997/06/15 02:24:06 wollman Exp $ + * $Id: machdep.c,v 1.250 1997/06/22 15:47:07 peter Exp $ */ #include "apm.h" @@ -218,12 +218,6 @@ cpu_startup(dummy) * Good {morning,afternoon,evening,night}. */ printf(version); -#ifdef SMP -#if defined(LATE_START) - mp_start(); /* fire up the APs and APICs */ -#endif /* LATE_START */ - mp_announce(); -#endif /* SMP */ earlysetcpuclass(); startrtclock(); printcpuinfo(); @@ -402,6 +396,14 @@ again: printf("avail memory = %d (%dK bytes)\n", ptoa(cnt.v_free_count), ptoa(cnt.v_free_count) / 1024); +#ifdef SMP + /* + * OK, enough kmem_alloc/malloc state should be up, lets get on with it! + */ + mp_start(); /* fire up the APs and APICs */ + mp_announce(); +#endif /* SMP */ + /* * Set up buffers, so they can be used to read disk labels. */ @@ -787,8 +789,7 @@ struct region_descriptor r_gdt, r_idt; #endif #ifdef SMP -struct i386tss SMPcommon_tss[NCPU]; /* One tss per cpu */ -struct i386tss *SMPcommon_tss_ptr[NCPU]; /* for the benefit of asmp code */ +extern struct i386tss common_tss; /* One tss per cpu */ #else struct i386tss common_tss; #endif @@ -865,11 +866,7 @@ struct soft_segment_descriptor gdt_segs[ 0 /* limit granularity (byte/page units)*/ }, /* GPROC0_SEL 6 Proc 0 Tss Descriptor */ { -#ifdef SMP - (int) &SMPcommon_tss[0],/* segment base address */ -#else (int) &common_tss, /* segment base address */ -#endif sizeof(struct i386tss)-1,/* length - all address space */ SDT_SYS386TSS, /* segment type */ 0, /* segment descriptor priority level */ @@ -1055,12 +1052,11 @@ init386(first) #ifdef SMP /* - * Oh puke! + * Spin these up now. init_secondary() grabs them. We could use + * #for(x,y,z) / #endfor cpp directives if they existed. */ for (x = 0; x < NCPU; x++) { - SMPcommon_tss_ptr[x] = &SMPcommon_tss[x]; gdt_segs[NGDT + x] = gdt_segs[GPROC0_SEL]; - gdt_segs[NGDT + x].ssd_base = (int) SMPcommon_tss_ptr[x]; ssdtosd(&gdt_segs[NGDT + x], &gdt[NGDT + x].sd); } #endif @@ -1254,6 +1250,11 @@ init386(first) Maxmem = idp->id_msize / 4; #endif +#ifdef SMP + /* look for the MP hardware - needed for apic addresses */ + mp_probe(); +#endif + /* call pmap initialization to make new kernel address space */ pmap_bootstrap (first, 0); @@ -1383,40 +1384,18 @@ init386(first) avail_end + off, VM_PROT_ALL, TRUE); msgbufmapped = 1; -#ifdef SMP - /* look for the MP hardware */ - mp_probe(); - - /* make the initial tss so cpu can get interrupt stack on syscall! */ - for(x = 0; x < NCPU; x++) { - SMPcommon_tss[x].tss_esp0 = (int) proc0.p_addr + UPAGES*PAGE_SIZE; - SMPcommon_tss[x].tss_ss0 = GSEL(GDATA_SEL, SEL_KPL) ; - SMPcommon_tss[x].tss_ioopt = (sizeof SMPcommon_tss[x]) << 16; - } -#if 0 - /** XXX FIXME: - * We can't access the LOCAL APIC till mp_enable() runs. Since - * this is run by the BSP, cpunumber() should always equal 0 anyway. - */ - gsel_tss = GSEL(NGDT + cpunumber(), SEL_KPL); -#else - gsel_tss = GSEL(NGDT /** + 0 */, SEL_KPL); -#endif /** 0 */ - ltr(gsel_tss); -#else /* make an initial tss so cpu can get interrupt stack on syscall! */ common_tss.tss_esp0 = (int) proc0.p_addr + UPAGES*PAGE_SIZE; common_tss.tss_ss0 = GSEL(GDATA_SEL, SEL_KPL) ; common_tss.tss_ioopt = (sizeof common_tss) << 16; gsel_tss = GSEL(GPROC0_SEL, SEL_KPL); ltr(gsel_tss); -#endif /* SMP */ dblfault_tss.tss_esp = dblfault_tss.tss_esp0 = dblfault_tss.tss_esp1 = dblfault_tss.tss_esp2 = (int) &dblfault_stack[sizeof(dblfault_stack)]; dblfault_tss.tss_ss = dblfault_tss.tss_ss0 = dblfault_tss.tss_ss1 = dblfault_tss.tss_ss2 = GSEL(GDATA_SEL, SEL_KPL); - dblfault_tss.tss_cr3 = IdlePTD; + dblfault_tss.tss_cr3 = (int)IdlePTD; dblfault_tss.tss_eip = (int) dblfault_handler; dblfault_tss.tss_eflags = PSL_KERNEL; dblfault_tss.tss_ds = dblfault_tss.tss_es = dblfault_tss.tss_fs = @@ -1450,14 +1429,8 @@ init386(first) /* setup proc 0's pcb */ proc0.p_addr->u_pcb.pcb_flags = 0; - proc0.p_addr->u_pcb.pcb_cr3 = IdlePTD; + proc0.p_addr->u_pcb.pcb_cr3 = (int)IdlePTD; proc0.p_addr->u_pcb.pcb_mpnest = 1; - -#ifdef SMP -#if !defined(LATE_START) - mp_start(); /* fire up the APs and APICs */ -#endif /* LATE_START */ -#endif /* SMP */ } int diff --git a/sys/i386/i386/microtime.s b/sys/i386/i386/microtime.s index 4baee4b..b32f34e 100644 --- a/sys/i386/i386/microtime.s +++ b/sys/i386/i386/microtime.s @@ -32,14 +32,11 @@ * SUCH DAMAGE. * * from: Steve McCanne's microtime code - * $Id: microtime.s,v 1.22 1997/04/26 19:47:59 peter Exp $ + * $Id: microtime.s,v 1.23 1997/05/29 05:11:10 peter Exp $ */ #include "opt_cpu.h" -#ifdef APIC_IO -#include <machine/apic.h> -#endif /* APIC_IO */ #include <machine/asmacros.h> #include <i386/isa/icu.h> @@ -125,8 +122,7 @@ ENTRY(microtime) jbe 1f #if defined(APIC_IO) - movl _apic_base, %eax - movl APIC_IRR1(%eax), %eax /** XXX assumption: IRQ0-24 */ + movl lapic_irr1, %eax /** XXX assumption: IRQ0-24 */ testl %eax, _mask8254 /* is a hard timer interrupt pending? */ #else inb $IO_ICU1, %al /* read IRR in ICU */ diff --git a/sys/i386/i386/mp_apicdefs.s b/sys/i386/i386/mp_apicdefs.s new file mode 100644 index 0000000..3d7f5bc --- /dev/null +++ b/sys/i386/i386/mp_apicdefs.s @@ -0,0 +1,85 @@ +/*- + * Copyright (c) Peter Wemm <peter@FreeBSD.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id$ + */ + + .globl lapic_id,lapic_ver,lapic_tpr,lapic_apr,lapic_ppr,lapic_eoi + .globl lapic_ldr,lapic_dfr,lapic_svr,lapic_isr,lapic_isr0,lapic_isr1 + .globl lapic_isr2,lapic_isr3,lapic_isr4,lapic_isr5,lapic_isr6 + .globl lapic_isr7,lapic_tmr,lapic_tmr0,lapic_tmr1,lapic_tmr2 + .globl lapic_tmr3,lapic_tmr4,lapic_tmr5,lapic_tmr6,lapic_tmr7 + .globl lapic_irr,lapic_irr0,lapic_irr1,lapic_irr2,lapic_irr3 + .globl lapic_irr4,lapic_irr5,lapic_irr6,lapic_irr7,lapic_esr + .globl lapic_icr_lo,lapic_icr_hi,lapic_lvtt,lapic_pcint,lapic_lvt1 + .globl lapic_lvt2,lapic_lvt3,lapic_ticr,lapic_tccr,lapic_tdcr + + .set lapic_id, _lapic + 0x020 + .set lapic_ver, _lapic + 0x030 + .set lapic_tpr, _lapic + 0x080 + .set lapic_apr, _lapic + 0x090 + .set lapic_ppr, _lapic + 0x0a0 + .set lapic_eoi, _lapic + 0x0b0 + .set lapic_ldr, _lapic + 0x0d0 + .set lapic_dfr, _lapic + 0x0e0 + .set lapic_svr, _lapic + 0x0f0 + .set lapic_isr, _lapic + 0x100 + .set lapic_isr0, _lapic + 0x100 + .set lapic_isr1, _lapic + 0x110 + .set lapic_isr2, _lapic + 0x120 + .set lapic_isr3, _lapic + 0x130 + .set lapic_isr4, _lapic + 0x140 + .set lapic_isr5, _lapic + 0x150 + .set lapic_isr6, _lapic + 0x160 + .set lapic_isr7, _lapic + 0x170 + .set lapic_tmr, _lapic + 0x180 + .set lapic_tmr0, _lapic + 0x180 + .set lapic_tmr1, _lapic + 0x190 + .set lapic_tmr2, _lapic + 0x1a0 + .set lapic_tmr3, _lapic + 0x1b0 + .set lapic_tmr4, _lapic + 0x1c0 + .set lapic_tmr5, _lapic + 0x1d0 + .set lapic_tmr6, _lapic + 0x1e0 + .set lapic_tmr7, _lapic + 0x1f0 + .set lapic_irr, _lapic + 0x200 + .set lapic_irr0, _lapic + 0x200 + .set lapic_irr1, _lapic + 0x210 + .set lapic_irr2, _lapic + 0x220 + .set lapic_irr3, _lapic + 0x230 + .set lapic_irr4, _lapic + 0x240 + .set lapic_irr5, _lapic + 0x250 + .set lapic_irr6, _lapic + 0x260 + .set lapic_irr7, _lapic + 0x270 + .set lapic_esr, _lapic + 0x280 + .set lapic_icr_lo, _lapic + 0x300 + .set lapic_icr_hi, _lapic + 0x310 + .set lapic_lvtt, _lapic + 0x320 + .set lapic_pcint, _lapic + 0x340 + .set lapic_lvt1, _lapic + 0x350 + .set lapic_lvt2, _lapic + 0x360 + .set lapic_lvt3, _lapic + 0x370 + .set lapic_ticr, _lapic + 0x380 + .set lapic_tccr, _lapic + 0x390 + .set lapic_tdcr, _lapic + 0x3e0 diff --git a/sys/i386/i386/mp_machdep.c b/sys/i386/i386/mp_machdep.c index a27cf86..c817925 100644 --- a/sys/i386/i386/mp_machdep.c +++ b/sys/i386/i386/mp_machdep.c @@ -22,11 +22,10 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: mp_machdep.c,v 1.16 1997/05/29 05:58:41 fsmp Exp $ + * $Id: mp_machdep.c,v 1.17 1997/06/02 10:44:08 dfr Exp $ */ #include "opt_smp.h" -#include "opt_serial.h" #include <sys/param.h> /* for KERNBASE */ #include <sys/types.h> @@ -38,18 +37,21 @@ #include <vm/vm_param.h> /* for KERNBASE */ #include <vm/pmap.h> /* for KERNBASE */ #include <machine/pmap.h> /* for KERNBASE */ +#include <vm/vm_kern.h> +#include <vm/vm_extern.h> #include <machine/smp.h> #include <machine/apic.h> #include <machine/mpapic.h> #include <machine/cpufunc.h> #include <machine/segments.h> -#include <machine/smptests.h> /** TEST_DEFAULT_CONFIG, LATE_START */ +#include <machine/smptests.h> /** TEST_DEFAULT_CONFIG */ +#include <machine/tss.h> #include <i386/i386/cons.h> /* cngetc() */ #if defined(APIC_IO) -#include <i386/include/md_var.h> /* setidt() */ +#include <machine/md_var.h> /* setidt() */ #include <i386/isa/icu.h> /* Xinvltlb() */ #include <i386/isa/intr_machdep.h> /* Xinvltlb() */ #endif /* APIC_IO */ @@ -186,11 +188,6 @@ typedef struct BASETABLE_ENTRY { /** FIXME: what system files declare these??? */ extern struct region_descriptor r_gdt, r_idt; -/* global data */ -struct proc *SMPcurproc[NCPU]; -struct pcb *SMPcurpcb[NCPU]; -struct timeval SMPruntime[NCPU]; - int mp_ncpus; /* # of CPUs, including BSP */ int mp_naps; /* # of Applications processors */ int mp_nbusses; /* # of busses */ @@ -210,6 +207,15 @@ int cpu_num_to_apic_id[NAPICID]; int io_num_to_apic_id[NAPICID]; int apic_id_to_logical[NAPICID]; +/* Boot of AP uses this PTD */ +u_int *bootPTD; + +/* Hotwire a 0->4MB V==P mapping */ +extern pt_entry_t KPTphys; + +/* virtual address of per-cpu common_tss */ +extern struct i386tss common_tss; + /* * look for MP compliant motherboard. */ @@ -283,11 +289,6 @@ found: /* please forgive the 'goto'! */ if (mptable_pass1()) panic("you must reconfigure your kernel"); -#if defined(LATE_START) - /* create pages for (address common) cpu APIC and each IO APIC */ - pmap_bootstrap_apics(); -#endif /* LATE_START */ - /* flag fact that we are running multiple processors */ mp_capable = 1; return 1; @@ -305,9 +306,6 @@ mp_start(void) mp_enable(boot_address); else panic("MP hardware not found!"); - - /* finish pmap initialization - turn off V==P mapping at zero */ - pmap_bootstrap2(); } @@ -321,23 +319,25 @@ mp_announce(void) printf("FreeBSD/SMP: Multiprocessor motherboard\n"); printf(" cpu0 (BSP): apic id: %d", CPU_TO_ID(0)); - printf(", version: 0x%08x\n", cpu_apic_versions[0]); + printf(", version: 0x%08x", cpu_apic_versions[0]); + printf(", at 0x%08x\n", cpu_apic_address); for (x = 1; x <= mp_naps; ++x) { printf(" cpu%d (AP): apic id: %d", x, CPU_TO_ID(x)); - printf(", version: 0x%08x\n", cpu_apic_versions[x]); + printf(", version: 0x%08x", cpu_apic_versions[x]); + printf(", at 0x%08x\n", cpu_apic_address); } #if defined(APIC_IO) for (x = 0; x < mp_napics; ++x) { printf(" io%d (APIC): apic id: %d", x, IO_TO_ID(x)); - printf(", version: 0x%08x\n", io_apic_versions[x]); + printf(", version: 0x%08x", io_apic_versions[x]); + printf(", at 0x%08x\n", io_apic_address[x]); } #else printf(" Warning: APIC I/O disabled\n"); #endif /* APIC_IO */ } - /* * AP cpu's call this to sync up protected mode. */ @@ -352,12 +352,18 @@ init_secondary(void) lidt(&r_idt); lldt(_default_ldt); - slot = NGDT + cpunumber(); + slot = NGDT + cpuid; gsel_tss = GSEL(slot, SEL_KPL); gdt[slot].sd.sd_type = SDT_SYS386TSS; + common_tss.tss_esp0 = 0; /* not used until after switch */ + common_tss.tss_ss0 = GSEL(GDATA_SEL, SEL_KPL); + common_tss.tss_ioopt = (sizeof common_tss) << 16; ltr(gsel_tss); load_cr0(0x8005003b); /* XXX! */ + + PTD[0] = 0; + invltlb(); } @@ -375,9 +381,9 @@ configure_local_apic(void) outb(0x23, byte); /* disconnect 8259s/NMI */ } /* mask the LVT1 */ - temp = lapic__lvt_lint0; + temp = lapic.lvt_lint0; temp |= APIC_LVT_M; - lapic__lvt_lint0 = temp; + lapic.lvt_lint0 = temp; } #endif /* APIC_IO */ @@ -398,13 +404,15 @@ mp_enable(u_int boot_addr) u_int ux; #endif /* APIC_IO */ - /* examine the MP table for needed info */ + /* Turn on 4MB of V == P addressing so we can get to MP table */ + *(int *)PTD = PG_V | PG_RW | ((u_long)KPTphys & PG_FRAME); + invltlb(); + + /* examine the MP table for needed info, uses physical addresses */ x = mptable_pass2(); -#if !defined(LATE_START) - /* create pages for (address common) cpu APIC and each IO APIC */ - pmap_bootstrap_apics(); -#endif /* LATE_START */ + *(int *)PTD = 0; + invltlb(); /* can't process default configs till the CPU APIC is pmapped */ if (x) @@ -832,7 +840,7 @@ fix_mp_table(void) for (x = 0; x < mp_nbusses; ++x) { if (bus_data[x].bus_type != PCI) continue; - if (bus_data[x].bus_id >= num_pci_bus ) + if (bus_data[x].bus_id >= num_pci_bus) panic("bad PCI bus numbering"); } } @@ -1258,7 +1266,7 @@ default_mp_table(int type) } #endif /* 0 */ - boot_cpu_id = (lapic__id & APIC_ID_MASK) >> 24; + boot_cpu_id = (lapic.id & APIC_ID_MASK) >> 24; ap_cpu_id = (boot_cpu_id == 0) ? 1 : 0; /* BSP */ @@ -1351,9 +1359,12 @@ default_mp_table(int type) static int start_all_aps(u_int boot_addr) { - int x; + int x, i; u_char mpbiosreason; u_long mpbioswarmvec; + pd_entry_t newptd; + pt_entry_t newpt; + int *newpp; /** * NOTE: this needs further thought: @@ -1362,7 +1373,7 @@ start_all_aps(u_int boot_addr) * * get the initial mp_lock with a count of 1 for the BSP */ - mp_lock = (lapic__id & APIC_ID_MASK) + 1; + mp_lock = (lapic.id & APIC_ID_MASK) + 1; /* initialize BSP's local APIC */ apic_initialize(1); @@ -1370,6 +1381,7 @@ start_all_aps(u_int boot_addr) /* install the AP 1st level boot code */ install_ap_tramp(boot_addr); + /* save the current value of the warm-start vector */ mpbioswarmvec = *((u_long *) WARMBOOT_OFF); outb(CMOS_REG, BIOS_RESET); @@ -1378,6 +1390,58 @@ start_all_aps(u_int boot_addr) /* start each AP */ for (x = 1; x <= mp_naps; ++x) { + /* HACK HACK HACK !!! */ + + /* alloc new page table directory */ + newptd = (pd_entry_t)(kmem_alloc(kernel_map, PAGE_SIZE)); + + /* clone currently active one (ie: IdlePTD) */ + bcopy(PTD, newptd, PAGE_SIZE); /* inc prv page pde */ + + /* set up 0 -> 4MB P==V mapping for AP boot */ + newptd[0] = PG_V | PG_RW | ((u_long)KPTphys & PG_FRAME); + + /* store PTD for this AP */ + bootPTD = (pd_entry_t)vtophys(newptd); + + /* alloc new page table page */ + newpt = (pt_entry_t)(kmem_alloc(kernel_map, PAGE_SIZE)); + + /* set the new PTD's private page to point there */ + newptd[MPPTDI] = PG_V | PG_RW | vtophys(newpt); + + /* install self referential entry */ + newptd[PTDPTDI] = PG_V | PG_RW | vtophys(newptd); + + /* get a new private data page */ + newpp = (int *)kmem_alloc(kernel_map, PAGE_SIZE); + + /* wire it into the private page table page */ + newpt[0] = PG_V | PG_RW | vtophys(newpp); + + /* wire the ptp into itself for access */ + newpt[1] = PG_V | PG_RW | vtophys(newpt); + + /* and the local apic */ + newpt[2] = SMP_prvpt[2]; + + /* and the IO apic mapping[s] */ + for (i = 16; i < 32; i++) + newpt[i] = SMP_prvpt[i]; + + /* prime data page for it to use */ + newpp[0] = x; /* cpuid */ + newpp[1] = 0; /* curproc */ + newpp[2] = 0; /* curpcb */ + newpp[3] = 0; /* npxproc */ + newpp[4] = 0; /* runtime.tv_sec */ + newpp[5] = 0; /* runtime.tv_usec */ + newpp[6] = x << 24; /* cpu_lockid */ + + /* XXX NOTE: ABANDON bootPTD for now!!!! */ + + /* END REVOLTING HACKERY */ + /* setup a vector to our boot code */ *((volatile u_short *) WARMBOOT_OFF) = WARMBOOT_TARGET; *((volatile u_short *) WARMBOOT_SEG) = (boot_addr >> 4); @@ -1401,7 +1465,7 @@ start_all_aps(u_int boot_addr) } /* fill in our (BSP) APIC version */ - cpu_apic_versions[0] = lapic__version; + cpu_apic_versions[0] = lapic.version; /* restore the warmstart vector */ *(u_long *) WARMBOOT_OFF = mpbioswarmvec; @@ -1503,24 +1567,24 @@ start_ap(int logical_cpu, u_int boot_addr) */ /* setup the address for the target AP */ - icr_hi = lapic__icr_hi & ~APIC_ID_MASK; + icr_hi = lapic.icr_hi & ~APIC_ID_MASK; icr_hi |= (physical_cpu << 24); - lapic__icr_hi = icr_hi; + lapic.icr_hi = icr_hi; /* do an INIT IPI: assert RESET */ - icr_lo = lapic__icr_lo & 0xfff00000; - lapic__icr_lo = icr_lo | 0x0000c500; + icr_lo = lapic.icr_lo & 0xfff00000; + lapic.icr_lo = icr_lo | 0x0000c500; /* wait for pending status end */ - while (lapic__icr_lo & APIC_DELSTAT_MASK) + while (lapic.icr_lo & APIC_DELSTAT_MASK) /* spin */ ; /* do an INIT IPI: deassert RESET */ - lapic__icr_lo = icr_lo | 0x00008500; + lapic.icr_lo = icr_lo | 0x00008500; /* wait for pending status end */ u_sleep(10000); /* wait ~10mS */ - while (lapic__icr_lo & APIC_DELSTAT_MASK) + while (lapic.icr_lo & APIC_DELSTAT_MASK) /* spin */ ; /* @@ -1533,8 +1597,8 @@ start_ap(int logical_cpu, u_int boot_addr) */ /* do a STARTUP IPI */ - lapic__icr_lo = icr_lo | 0x00000600 | vector; - while (lapic__icr_lo & APIC_DELSTAT_MASK) + lapic.icr_lo = icr_lo | 0x00000600 | vector; + while (lapic.icr_lo & APIC_DELSTAT_MASK) /* spin */ ; u_sleep(200); /* wait ~200uS */ @@ -1545,8 +1609,8 @@ start_ap(int logical_cpu, u_int boot_addr) * recognized after hardware RESET or INIT IPI. */ - lapic__icr_lo = icr_lo | 0x00000600 | vector; - while (lapic__icr_lo & APIC_DELSTAT_MASK) + lapic.icr_lo = icr_lo | 0x00000600 | vector; + while (lapic.icr_lo & APIC_DELSTAT_MASK) /* spin */ ; u_sleep(200); /* wait ~200uS */ diff --git a/sys/i386/i386/mpapic.c b/sys/i386/i386/mpapic.c index 5d166fa..ec04109 100644 --- a/sys/i386/i386/mpapic.c +++ b/sys/i386/i386/mpapic.c @@ -22,9 +22,11 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: mpapic.c,v 1.5 1997/05/29 05:58:41 fsmp Exp $ + * $Id: mpapic.c,v 1.6 1997/05/31 03:29:57 fsmp Exp $ */ +#include "opt_smp.h" + #include <sys/types.h> #include <sys/sysproto.h> #include <sys/systm.h> @@ -35,7 +37,6 @@ #include <machine/cpufunc.h> #include <machine/segments.h> - /* EISA Edge/Level trigger control registers */ #define ELCR0 0x4d0 /* eisa irq 0-7 */ #define ELCR1 0x4d1 /* eisa irq 8-15 */ @@ -43,16 +44,9 @@ /* * pointers to pmapped apic hardware. */ -volatile u_int* apic_base; -#if 1 /** XXX APIC_STRUCT */ -volatile lapic_t* lapic; -#endif /** XXX APIC_STRUCT */ #if defined(APIC_IO) -volatile u_int* io_apic_base; -#if 1 /** XXX APIC_STRUCT */ -volatile ioapic_t* ioapic; -#endif /** XXX APIC_STRUCT */ +volatile ioapic_t *ioapic[NAPIC]; #endif /* APIC_IO */ /* @@ -65,19 +59,19 @@ apic_initialize(int is_bsp) if (is_bsp) { /* setup LVT1 as ExtINT */ - temp = lapic__lvt_lint0; + temp = lapic.lvt_lint0; temp &= 0xfffe58ff; temp |= 0x00000700; - lapic__lvt_lint0 = temp; + lapic.lvt_lint0 = temp; } /* setup LVT2 as NMI */ - temp = lapic__lvt_lint1; + temp = lapic.lvt_lint1; temp &= 0xfffe58ff; temp |= 0xffff0400; - lapic__lvt_lint1 = temp; + lapic.lvt_lint1 = temp; /* set the Task Priority Register as needed */ - temp = lapic__tpr; + temp = lapic.tpr; temp &= ~APIC_TPR_PRIO; /* clear priority field */ #if defined(TEST_LOPRIO) @@ -87,16 +81,16 @@ apic_initialize(int is_bsp) temp |= 0xff; /* disallow INT arbitration */ #endif /* TEST_LOPRIO */ - lapic__tpr = temp; + lapic.tpr = temp; /* enable the beast */ - temp = lapic__svr; + temp = lapic.svr; temp |= APIC_SVR_SWEN; /* software enable APIC */ temp &= ~APIC_SVR_FOCUS;/* enable 'focus processor' */ #if 0 temp |= 0x20; /** FIXME: 2f == strayIRQ15 */ #endif - lapic__svr = temp; + lapic.svr = temp; } @@ -581,7 +575,7 @@ apic_ipi(int dest_type, int vector, int delivery_mode) /* "lazy delivery", ie we only barf if they stack up on us... */ for (x = MAX_SPIN1; x; --x) { - if ((lapic__icr_lo & APIC_DELSTAT_MASK) == 0) + if ((lapic.icr_lo & APIC_DELSTAT_MASK) == 0) break; } if (x == 0) @@ -589,16 +583,16 @@ apic_ipi(int dest_type, int vector, int delivery_mode) #endif /* DETECT_DEADLOCK */ /* build IRC_LOW */ - icr_lo = (lapic__icr_lo & APIC_RESV2_MASK) + icr_lo = (lapic.icr_lo & APIC_RESV2_MASK) | dest_type | delivery_mode | vector; /* write APIC ICR */ - lapic__icr_lo = icr_lo; + lapic.icr_lo = icr_lo; /* wait for pending status end */ #if defined(DETECT_DEADLOCK) for (x = MAX_SPIN2; x; --x) { - if ((lapic__icr_lo & APIC_DELSTAT_MASK) == 0) + if ((lapic.icr_lo & APIC_DELSTAT_MASK) == 0) break; } if (x == 0) @@ -606,7 +600,7 @@ apic_ipi(int dest_type, int vector, int delivery_mode) #undef MAX_SPIN2 #undef MAX_SPIN1 #else - while (lapic__icr_lo & APIC_DELSTAT_MASK) + while (lapic.icr_lo & APIC_DELSTAT_MASK) /* spin */ ; #endif /* DETECT_DEADLOCK */ @@ -635,9 +629,9 @@ selected_apic_ipi(u_int target, int vector, int delivery_mode) for (status = 0, x = 0; x <= 14; ++x) if (target & (1 << x)) { /* write the destination field for the target AP */ - icr_hi = lapic__icr_hi & ~APIC_ID_MASK; + icr_hi = lapic.icr_hi & ~APIC_ID_MASK; icr_hi |= (CPU_TO_ID(x) << 24); - lapic__icr_hi = icr_hi; + lapic.icr_hi = icr_hi; /* send the IPI */ if (apic_ipi(APIC_DEST_DESTFLD, vector, delivery_mode) == -1) @@ -659,17 +653,17 @@ selected_proc_ipi(int target, int vector) u_long icr_hi; /* write the destination field for the target AP */ - icr_hi = (lapic__icr_hi & ~APIC_ID_MASK) | + icr_hi = (lapic.icr_hi & ~APIC_ID_MASK) | (cpu_num_to_apic_id[target] << 24); - lapic__icr_hi = icr_hi; + lapic.icr_hi = icr_hi; /* write command */ - icr_lo = (lapic__icr_lo & APIC_RESV2_MASK) | + icr_lo = (lapic.icr_lo & APIC_RESV2_MASK) | APIC_DEST_DESTFLD | APIC_DELMODE_FIXED | vector; - lapic__icr_lo = icr_lo; + lapic.icr_lo = icr_lo; /* wait for pending status end */ - while (lapic__icr_lo & APIC_DELSTAT_MASK) + while (lapic.icr_lo & APIC_DELSTAT_MASK) /* spin */ ; return 0; /** FIXME: return result */ @@ -738,18 +732,19 @@ set_apic_timer(int value) /* calculate divisor and count from value: * * timeBase == CPU bus clock divisor == [1,2,4,8,16,32,64,128] value == - * time in uS */ - lapic__dcr_timer = APIC_TDCR_1; + * time in uS + */ + lapic.dcr_timer = APIC_TDCR_1; ticks_per_microsec = bus_clock() / 1000000; /* configure timer as one-shot */ - lvtt = lapic__lvt_timer; + lvtt = lapic.lvt_timer; lvtt &= ~(APIC_LVTT_VECTOR | APIC_LVTT_DS | APIC_LVTT_M | APIC_LVTT_TM); lvtt |= APIC_LVTT_M; /* no INT, one-shot */ - lapic__lvt_timer = lvtt; + lapic.lvt_timer = lvtt; /* */ - lapic__icr_timer = value * ticks_per_microsec; + lapic.icr_timer = value * ticks_per_microsec; } @@ -764,7 +759,7 @@ read_apic_timer(void) * for now we just return the remaining count. */ #else - return lapic__ccr_timer; + return lapic.ccr_timer; #endif } diff --git a/sys/i386/i386/mpboot.s b/sys/i386/i386/mpboot.s index e43b250..f47f49f 100644 --- a/sys/i386/i386/mpboot.s +++ b/sys/i386/i386/mpboot.s @@ -31,7 +31,7 @@ * mpboot.s: FreeBSD machine support for the Intel MP Spec * multiprocessor systems. * - * $Id: mpboot.s,v 1.18 1997/04/25 03:11:27 fsmp Exp $ + * $Id: mpboot.s,v 1.1 1997/04/26 11:45:17 peter Exp $ */ @@ -76,7 +76,7 @@ NON_GPROF_ENTRY(MPentry) CHECKPOINT(0x36, 3) movl $mp_stk-KERNBASE,%esp /* mp boot stack end loc. */ /* Now enable paging mode */ - movl _IdlePTD-KERNBASE, %eax + movl _bootPTD-KERNBASE, %eax movl %eax,%cr3 movl %cr0,%eax orl $CR0_PE|CR0_PG,%eax /* enable paging */ @@ -96,13 +96,12 @@ mp_begin: /* now running relocated at KERNBASE */ CHECKPOINT(0x38, 5) /* disable the APIC, just to be SURE */ - movl _apic_base, %esi - movl APIC_SVR(%esi), %eax /* get spurious vector reg. */ + movl lapic_svr, %eax /* get spurious vector reg. */ andl $~APIC_SVR_SWEN, %eax /* clear software enable bit */ - movl %eax, APIC_SVR(%esi) + movl %eax, lapic_svr /* signal our startup to the BSP */ - movl APIC_VER(%esi), %eax /* our version reg contents */ + movl lapic_ver, %eax /* our version reg contents */ movl %eax, _cpu_apic_versions /* into [ 0 ] */ incl _mp_ncpus /* signal BSP */ diff --git a/sys/i386/i386/mplock.s b/sys/i386/i386/mplock.s index b2052f5..8402e26 100644 --- a/sys/i386/i386/mplock.s +++ b/sys/i386/i386/mplock.s @@ -6,7 +6,7 @@ * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp * ---------------------------------------------------------------------------- * - * $Id: mplock.s,v 1.2 1997/05/03 19:24:16 fsmp Exp $ + * $Id: mplock.s,v 1.3 1997/05/29 05:11:10 peter Exp $ * * Functions for locking between CPUs in a SMP system. * @@ -25,8 +25,8 @@ #include "assym.s" /* system definitions */ #include <machine/specialreg.h> /* x86 special registers */ #include <machine/asmacros.h> /* miscellaneous asm macros */ -#include <machine/smpasm.h> #include <machine/smptests.h> /** TEST_LOPRIO */ +#include <machine/apic.h> .text @@ -36,22 +36,11 @@ * Destroys %eax, %ecx and %edx. */ -/* XXX FIXME: remove this code entirely once it is proven unnecessary */ -#define BOTHER_TO_CHECK_NOT - NON_GPROF_ENTRY(MPgetlock) -#if defined(BOTHER_TO_CHECK) - movl _smp_active, %eax /* !MP ? -- skip it */ - cmpl $0, %eax - jne 1f - ret -#endif /* BOTHER_TO_CHECK */ 1: movl 4(%esp), %edx /* Get the address of the lock */ movl (%edx), %eax /* Try to see if we have it already */ andl $0x00ffffff, %eax /* - get count */ - movl _apic_base, %ecx /* - get cpu# */ - movl APIC_ID(%ecx), %ecx - andl $APIC_ID_MASK, %ecx + movl _cpu_lockid, %ecx /* - get pre-shifted logical cpu id */ orl %ecx, %eax /* - combine them */ movl %eax, %ecx incl %ecx /* - new count is one more */ @@ -60,19 +49,16 @@ NON_GPROF_ENTRY(MPgetlock) jne 2f /* - miss */ ret 2: movl $0xffffffff, %eax /* Assume it's free */ - movl _apic_base, %ecx /* - get cpu# */ - movl APIC_ID(%ecx), %ecx - andl $APIC_ID_MASK, %ecx + movl _cpu_lockid, %ecx /* - get pre-shifted logical cpu id */ incl %ecx /* - new count is one */ lock cmpxchg %ecx, (%edx) /* - try it atomically */ jne 3f /* ...do not collect $200 */ #if defined(TEST_LOPRIO) /* 1st acquire, claim LOW PRIO (ie, ALL INTerrupts) */ - movl _apic_base, %ecx /* base addr of LOCAL APIC */ - movl APIC_TPR(%ecx), %eax /* Task Priority Register */ + movl lapic_tpr, %eax /* Task Priority Register */ andl $0xffffff00, %eax /* clear task priority field */ - movl %eax, APIC_TPR(%ecx) /* set it */ + movl %eax, lapic_tpr /* set it */ #endif /** TEST_LOPRIO */ ret 3: cmpl $0xffffffff, (%edx) /* Wait for it to become free */ @@ -87,19 +73,10 @@ NON_GPROF_ENTRY(MPgetlock) */ NON_GPROF_ENTRY(MPtrylock) -#if defined(BOTHER_TO_CHECK) - movl _smp_active, %eax /* !MP ? -- skip it */ - cmpl $0, %eax - jne 1f - movl $1, %eax - ret -#endif /* BOTHER_TO_CHECK */ 1: movl 4(%esp), %edx /* Get the address of the lock */ movl (%edx), %eax /* Try to see if we have it already */ andl $0x00ffffff, %eax /* - get count */ - movl _apic_base, %ecx /* - get cpu# */ - movl APIC_ID(%ecx), %ecx - andl $APIC_ID_MASK, %ecx + movl _cpu_lockid, %ecx /* - get pre-shifted logical cpu id */ orl %ecx, %eax /* - combine them */ movl %eax, %ecx incl %ecx /* - new count is one more */ @@ -109,9 +86,7 @@ NON_GPROF_ENTRY(MPtrylock) movl $1, %eax ret 2: movl $0xffffffff, %eax /* Assume it's free */ - movl _apic_base, %ecx /* - get cpu# */ - movl APIC_ID(%ecx), %ecx - andl $APIC_ID_MASK, %ecx + movl _cpu_lockid, %ecx /* - get pre-shifted logical cpu id */ incl %ecx /* - new count is one */ lock cmpxchg %ecx, (%edx) /* - try it atomically */ @@ -128,12 +103,6 @@ NON_GPROF_ENTRY(MPtrylock) */ NON_GPROF_ENTRY(MPrellock) -#if defined(BOTHER_TO_CHECK) - movl _smp_active, %eax /* !MP ? -- skip it */ - cmpl $0, %eax - jne 1f - ret -#endif /* BOTHER_TO_CHECK */ 1: movl 4(%esp), %edx /* Get the address of the lock */ movl (%edx), %eax /* - get the value */ movl %eax,%ecx @@ -142,11 +111,10 @@ NON_GPROF_ENTRY(MPrellock) jnz 2f #if defined(TEST_LOPRIO) /* last release, give up LOW PRIO (ie, arbitrate INTerrupts) */ - movl _apic_base, %ecx /* base addr of LOCAL APIC */ - movl APIC_TPR(%ecx), %eax /* Task Priority Register */ + movl lapic_tpr, %eax /* Task Priority Register */ andl $0xffffff00, %eax /* clear task priority field */ orl $0x00000010, %eax /* set task priority to 'arbitrate' */ - movl %eax, APIC_TPR(%ecx) /* set it */ + movl %eax, lapic_tpr /* set it */ movl (%edx), %eax /* - get the value AGAIN */ #endif /** TEST_LOPRIO */ movl $0xffffffff, %ecx /* - In which case we release it */ diff --git a/sys/i386/i386/mptable.c b/sys/i386/i386/mptable.c index a27cf86..c817925 100644 --- a/sys/i386/i386/mptable.c +++ b/sys/i386/i386/mptable.c @@ -22,11 +22,10 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: mp_machdep.c,v 1.16 1997/05/29 05:58:41 fsmp Exp $ + * $Id: mp_machdep.c,v 1.17 1997/06/02 10:44:08 dfr Exp $ */ #include "opt_smp.h" -#include "opt_serial.h" #include <sys/param.h> /* for KERNBASE */ #include <sys/types.h> @@ -38,18 +37,21 @@ #include <vm/vm_param.h> /* for KERNBASE */ #include <vm/pmap.h> /* for KERNBASE */ #include <machine/pmap.h> /* for KERNBASE */ +#include <vm/vm_kern.h> +#include <vm/vm_extern.h> #include <machine/smp.h> #include <machine/apic.h> #include <machine/mpapic.h> #include <machine/cpufunc.h> #include <machine/segments.h> -#include <machine/smptests.h> /** TEST_DEFAULT_CONFIG, LATE_START */ +#include <machine/smptests.h> /** TEST_DEFAULT_CONFIG */ +#include <machine/tss.h> #include <i386/i386/cons.h> /* cngetc() */ #if defined(APIC_IO) -#include <i386/include/md_var.h> /* setidt() */ +#include <machine/md_var.h> /* setidt() */ #include <i386/isa/icu.h> /* Xinvltlb() */ #include <i386/isa/intr_machdep.h> /* Xinvltlb() */ #endif /* APIC_IO */ @@ -186,11 +188,6 @@ typedef struct BASETABLE_ENTRY { /** FIXME: what system files declare these??? */ extern struct region_descriptor r_gdt, r_idt; -/* global data */ -struct proc *SMPcurproc[NCPU]; -struct pcb *SMPcurpcb[NCPU]; -struct timeval SMPruntime[NCPU]; - int mp_ncpus; /* # of CPUs, including BSP */ int mp_naps; /* # of Applications processors */ int mp_nbusses; /* # of busses */ @@ -210,6 +207,15 @@ int cpu_num_to_apic_id[NAPICID]; int io_num_to_apic_id[NAPICID]; int apic_id_to_logical[NAPICID]; +/* Boot of AP uses this PTD */ +u_int *bootPTD; + +/* Hotwire a 0->4MB V==P mapping */ +extern pt_entry_t KPTphys; + +/* virtual address of per-cpu common_tss */ +extern struct i386tss common_tss; + /* * look for MP compliant motherboard. */ @@ -283,11 +289,6 @@ found: /* please forgive the 'goto'! */ if (mptable_pass1()) panic("you must reconfigure your kernel"); -#if defined(LATE_START) - /* create pages for (address common) cpu APIC and each IO APIC */ - pmap_bootstrap_apics(); -#endif /* LATE_START */ - /* flag fact that we are running multiple processors */ mp_capable = 1; return 1; @@ -305,9 +306,6 @@ mp_start(void) mp_enable(boot_address); else panic("MP hardware not found!"); - - /* finish pmap initialization - turn off V==P mapping at zero */ - pmap_bootstrap2(); } @@ -321,23 +319,25 @@ mp_announce(void) printf("FreeBSD/SMP: Multiprocessor motherboard\n"); printf(" cpu0 (BSP): apic id: %d", CPU_TO_ID(0)); - printf(", version: 0x%08x\n", cpu_apic_versions[0]); + printf(", version: 0x%08x", cpu_apic_versions[0]); + printf(", at 0x%08x\n", cpu_apic_address); for (x = 1; x <= mp_naps; ++x) { printf(" cpu%d (AP): apic id: %d", x, CPU_TO_ID(x)); - printf(", version: 0x%08x\n", cpu_apic_versions[x]); + printf(", version: 0x%08x", cpu_apic_versions[x]); + printf(", at 0x%08x\n", cpu_apic_address); } #if defined(APIC_IO) for (x = 0; x < mp_napics; ++x) { printf(" io%d (APIC): apic id: %d", x, IO_TO_ID(x)); - printf(", version: 0x%08x\n", io_apic_versions[x]); + printf(", version: 0x%08x", io_apic_versions[x]); + printf(", at 0x%08x\n", io_apic_address[x]); } #else printf(" Warning: APIC I/O disabled\n"); #endif /* APIC_IO */ } - /* * AP cpu's call this to sync up protected mode. */ @@ -352,12 +352,18 @@ init_secondary(void) lidt(&r_idt); lldt(_default_ldt); - slot = NGDT + cpunumber(); + slot = NGDT + cpuid; gsel_tss = GSEL(slot, SEL_KPL); gdt[slot].sd.sd_type = SDT_SYS386TSS; + common_tss.tss_esp0 = 0; /* not used until after switch */ + common_tss.tss_ss0 = GSEL(GDATA_SEL, SEL_KPL); + common_tss.tss_ioopt = (sizeof common_tss) << 16; ltr(gsel_tss); load_cr0(0x8005003b); /* XXX! */ + + PTD[0] = 0; + invltlb(); } @@ -375,9 +381,9 @@ configure_local_apic(void) outb(0x23, byte); /* disconnect 8259s/NMI */ } /* mask the LVT1 */ - temp = lapic__lvt_lint0; + temp = lapic.lvt_lint0; temp |= APIC_LVT_M; - lapic__lvt_lint0 = temp; + lapic.lvt_lint0 = temp; } #endif /* APIC_IO */ @@ -398,13 +404,15 @@ mp_enable(u_int boot_addr) u_int ux; #endif /* APIC_IO */ - /* examine the MP table for needed info */ + /* Turn on 4MB of V == P addressing so we can get to MP table */ + *(int *)PTD = PG_V | PG_RW | ((u_long)KPTphys & PG_FRAME); + invltlb(); + + /* examine the MP table for needed info, uses physical addresses */ x = mptable_pass2(); -#if !defined(LATE_START) - /* create pages for (address common) cpu APIC and each IO APIC */ - pmap_bootstrap_apics(); -#endif /* LATE_START */ + *(int *)PTD = 0; + invltlb(); /* can't process default configs till the CPU APIC is pmapped */ if (x) @@ -832,7 +840,7 @@ fix_mp_table(void) for (x = 0; x < mp_nbusses; ++x) { if (bus_data[x].bus_type != PCI) continue; - if (bus_data[x].bus_id >= num_pci_bus ) + if (bus_data[x].bus_id >= num_pci_bus) panic("bad PCI bus numbering"); } } @@ -1258,7 +1266,7 @@ default_mp_table(int type) } #endif /* 0 */ - boot_cpu_id = (lapic__id & APIC_ID_MASK) >> 24; + boot_cpu_id = (lapic.id & APIC_ID_MASK) >> 24; ap_cpu_id = (boot_cpu_id == 0) ? 1 : 0; /* BSP */ @@ -1351,9 +1359,12 @@ default_mp_table(int type) static int start_all_aps(u_int boot_addr) { - int x; + int x, i; u_char mpbiosreason; u_long mpbioswarmvec; + pd_entry_t newptd; + pt_entry_t newpt; + int *newpp; /** * NOTE: this needs further thought: @@ -1362,7 +1373,7 @@ start_all_aps(u_int boot_addr) * * get the initial mp_lock with a count of 1 for the BSP */ - mp_lock = (lapic__id & APIC_ID_MASK) + 1; + mp_lock = (lapic.id & APIC_ID_MASK) + 1; /* initialize BSP's local APIC */ apic_initialize(1); @@ -1370,6 +1381,7 @@ start_all_aps(u_int boot_addr) /* install the AP 1st level boot code */ install_ap_tramp(boot_addr); + /* save the current value of the warm-start vector */ mpbioswarmvec = *((u_long *) WARMBOOT_OFF); outb(CMOS_REG, BIOS_RESET); @@ -1378,6 +1390,58 @@ start_all_aps(u_int boot_addr) /* start each AP */ for (x = 1; x <= mp_naps; ++x) { + /* HACK HACK HACK !!! */ + + /* alloc new page table directory */ + newptd = (pd_entry_t)(kmem_alloc(kernel_map, PAGE_SIZE)); + + /* clone currently active one (ie: IdlePTD) */ + bcopy(PTD, newptd, PAGE_SIZE); /* inc prv page pde */ + + /* set up 0 -> 4MB P==V mapping for AP boot */ + newptd[0] = PG_V | PG_RW | ((u_long)KPTphys & PG_FRAME); + + /* store PTD for this AP */ + bootPTD = (pd_entry_t)vtophys(newptd); + + /* alloc new page table page */ + newpt = (pt_entry_t)(kmem_alloc(kernel_map, PAGE_SIZE)); + + /* set the new PTD's private page to point there */ + newptd[MPPTDI] = PG_V | PG_RW | vtophys(newpt); + + /* install self referential entry */ + newptd[PTDPTDI] = PG_V | PG_RW | vtophys(newptd); + + /* get a new private data page */ + newpp = (int *)kmem_alloc(kernel_map, PAGE_SIZE); + + /* wire it into the private page table page */ + newpt[0] = PG_V | PG_RW | vtophys(newpp); + + /* wire the ptp into itself for access */ + newpt[1] = PG_V | PG_RW | vtophys(newpt); + + /* and the local apic */ + newpt[2] = SMP_prvpt[2]; + + /* and the IO apic mapping[s] */ + for (i = 16; i < 32; i++) + newpt[i] = SMP_prvpt[i]; + + /* prime data page for it to use */ + newpp[0] = x; /* cpuid */ + newpp[1] = 0; /* curproc */ + newpp[2] = 0; /* curpcb */ + newpp[3] = 0; /* npxproc */ + newpp[4] = 0; /* runtime.tv_sec */ + newpp[5] = 0; /* runtime.tv_usec */ + newpp[6] = x << 24; /* cpu_lockid */ + + /* XXX NOTE: ABANDON bootPTD for now!!!! */ + + /* END REVOLTING HACKERY */ + /* setup a vector to our boot code */ *((volatile u_short *) WARMBOOT_OFF) = WARMBOOT_TARGET; *((volatile u_short *) WARMBOOT_SEG) = (boot_addr >> 4); @@ -1401,7 +1465,7 @@ start_all_aps(u_int boot_addr) } /* fill in our (BSP) APIC version */ - cpu_apic_versions[0] = lapic__version; + cpu_apic_versions[0] = lapic.version; /* restore the warmstart vector */ *(u_long *) WARMBOOT_OFF = mpbioswarmvec; @@ -1503,24 +1567,24 @@ start_ap(int logical_cpu, u_int boot_addr) */ /* setup the address for the target AP */ - icr_hi = lapic__icr_hi & ~APIC_ID_MASK; + icr_hi = lapic.icr_hi & ~APIC_ID_MASK; icr_hi |= (physical_cpu << 24); - lapic__icr_hi = icr_hi; + lapic.icr_hi = icr_hi; /* do an INIT IPI: assert RESET */ - icr_lo = lapic__icr_lo & 0xfff00000; - lapic__icr_lo = icr_lo | 0x0000c500; + icr_lo = lapic.icr_lo & 0xfff00000; + lapic.icr_lo = icr_lo | 0x0000c500; /* wait for pending status end */ - while (lapic__icr_lo & APIC_DELSTAT_MASK) + while (lapic.icr_lo & APIC_DELSTAT_MASK) /* spin */ ; /* do an INIT IPI: deassert RESET */ - lapic__icr_lo = icr_lo | 0x00008500; + lapic.icr_lo = icr_lo | 0x00008500; /* wait for pending status end */ u_sleep(10000); /* wait ~10mS */ - while (lapic__icr_lo & APIC_DELSTAT_MASK) + while (lapic.icr_lo & APIC_DELSTAT_MASK) /* spin */ ; /* @@ -1533,8 +1597,8 @@ start_ap(int logical_cpu, u_int boot_addr) */ /* do a STARTUP IPI */ - lapic__icr_lo = icr_lo | 0x00000600 | vector; - while (lapic__icr_lo & APIC_DELSTAT_MASK) + lapic.icr_lo = icr_lo | 0x00000600 | vector; + while (lapic.icr_lo & APIC_DELSTAT_MASK) /* spin */ ; u_sleep(200); /* wait ~200uS */ @@ -1545,8 +1609,8 @@ start_ap(int logical_cpu, u_int boot_addr) * recognized after hardware RESET or INIT IPI. */ - lapic__icr_lo = icr_lo | 0x00000600 | vector; - while (lapic__icr_lo & APIC_DELSTAT_MASK) + lapic.icr_lo = icr_lo | 0x00000600 | vector; + while (lapic.icr_lo & APIC_DELSTAT_MASK) /* spin */ ; u_sleep(200); /* wait ~200uS */ diff --git a/sys/i386/i386/pmap.c b/sys/i386/i386/pmap.c index 32b8b55..c95c509 100644 --- a/sys/i386/i386/pmap.c +++ b/sys/i386/i386/pmap.c @@ -39,7 +39,7 @@ * SUCH DAMAGE. * * from: @(#)pmap.c 7.7 (Berkeley) 5/12/91 - * $Id: pmap.c,v 1.143 1997/04/27 12:11:43 peter Exp $ + * $Id: pmap.c,v 1.145 1997/05/29 05:58:41 fsmp Exp $ */ /* @@ -187,14 +187,6 @@ static caddr_t CADDR2; static pt_entry_t *msgbufmap; struct msgbuf *msgbufp=0; -#if defined(SMP) || defined(APIC_IO) -static pt_entry_t *apic_map; -#endif /* SMP || APIC_IO */ - -#if defined(APIC_IO) -static pt_entry_t *io_apic_map; -#endif /* APIC_IO */ - pt_entry_t *PMAP1 = 0; unsigned *PADDR1 = 0; @@ -266,6 +258,7 @@ pmap_bootstrap(firstaddr, loadaddr) { vm_offset_t va; pt_entry_t *pte; + int i, j; avail_start = firstaddr; @@ -292,7 +285,7 @@ pmap_bootstrap(firstaddr, loadaddr) */ kernel_pmap = &kernel_pmap_store; - kernel_pmap->pm_pdir = (pd_entry_t *) (KERNBASE + IdlePTD); + kernel_pmap->pm_pdir = (pd_entry_t *) (KERNBASE + (u_int)IdlePTD); kernel_pmap->pm_count = 1; #if PMAP_PVLIST @@ -310,26 +303,6 @@ pmap_bootstrap(firstaddr, loadaddr) va = virtual_avail; pte = (pt_entry_t *) pmap_pte(kernel_pmap, va); -#if defined(SMP) || defined(APIC_IO) - /* - * apic_map is the pt for where the local (CPU) apic is mapped in. - */ - SYSMAP(unsigned int *, apic_map, apic_base, 1) -#if 1 /** XXX APIC_STRUCT */ - lapic = (lapic_t*)apic_base; -#endif /** XXX APIC_STRUCT */ -#endif /* SMP || APIC_IO */ - -#if defined(APIC_IO) - /* - * io_apic_map is the pt for where the I/O apic is mapped in. - */ - SYSMAP(unsigned int *, io_apic_map, io_apic_base, 1) -#if 1 /** XXX APIC_STRUCT */ - ioapic = (ioapic_t*)io_apic_base; -#endif /** XXX APIC_STRUCT */ -#endif /* APIC_IO */ - /* * CMAP1/CMAP2 are used for zeroing and copying pages. */ @@ -357,8 +330,37 @@ pmap_bootstrap(firstaddr, loadaddr) virtual_avail = va; *(int *) CMAP1 = *(int *) CMAP2 = 0; -#if !defined(SMP) *(int *) PTD = 0; + +#ifdef SMP + if (cpu_apic_address == 0) + panic("pmap_bootstrap: no local apic!"); + + /* 0 = private page */ + /* 1 = page table page */ + /* 2 = local apic */ + /* 16-31 = io apics */ + SMP_prvpt[2] = PG_V | PG_RW | ((u_long)cpu_apic_address & PG_FRAME); + + for (i = 0; i < mp_napics; i++) { + for (j = 0; j < 16; j++) { + /* same page frame as a previous IO apic? */ + if (((u_long)SMP_prvpt[j + 16] & PG_FRAME) == + ((u_long)io_apic_address[0] & PG_FRAME)) { + ioapic[i] = (ioapic_t *)&SMP_ioapic[j * PAGE_SIZE]; + break; + } + /* use this slot if available */ + if (((u_long)SMP_prvpt[j + 16] & PG_FRAME) == 0) { + SMP_prvpt[j + 16] = PG_V | PG_RW | + ((u_long)io_apic_address[i] & PG_FRAME); + ioapic[i] = (ioapic_t *)&SMP_ioapic[j * PAGE_SIZE]; + break; + } + } + if (j == 16) + panic("no space to map IO apic %d!", i); + } #endif invltlb(); @@ -371,39 +373,6 @@ pmap_bootstrap(firstaddr, loadaddr) pgeflag = 0; } -#if defined(SMP) || defined(APIC_IO) -void -pmap_bootstrap_apics() -{ - if (cpu_apic_address == 0) { - printf("pmap: BSP APIC address NOT found!\n"); - panic("pmap_bootstrap_apics: no apic"); - } - - *(int*)apic_map = PG_V | PG_RW | ((u_long)cpu_apic_address & PG_FRAME); - -#if defined(APIC_IO) -#if defined(MULTIPLE_IOAPICS) -#error MULTIPLE_IOAPICSXXX -#else - *(int*)io_apic_map = PG_V | PG_RW - | ((u_long)io_apic_address[0] & PG_FRAME); -#endif /* MULTIPLE_IOAPICS */ -#endif /* APIC_IO */ - - invltlb(); -} -#endif /* SMP || APIC_IO */ - -#ifdef SMP -void -pmap_bootstrap2() -{ - *(int *) PTD = 0; - invltlb(); -} -#endif - /* * Initialize the pmap module. * Called by vm_init, to initialize any structures that the pmap @@ -1062,6 +1031,7 @@ retry: bzero(pmap->pm_pdir, PAGE_SIZE); /* wire in kernel global address entries */ + /* XXX copies current process, does not fill in MPPTDI */ bcopy(PTD + KPTDI, pmap->pm_pdir + KPTDI, nkpt * PTESIZE); /* install self-referential address mapping entry */ @@ -1116,6 +1086,9 @@ pmap_release_free_page(pmap, p) */ if (p->pindex == PTDPTDI) { bzero(pde + KPTDI, nkpt * PTESIZE); +#ifdef SMP + pde[MPPTDI] = 0; +#endif pde[APTDPTDI] = 0; pmap_kremove((vm_offset_t) pmap->pm_pdir); } diff --git a/sys/i386/i386/support.s b/sys/i386/i386/support.s index b87370b..be18df8 100644 --- a/sys/i386/i386/support.s +++ b/sys/i386/i386/support.s @@ -30,7 +30,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: support.s,v 1.52 1997/04/26 11:45:21 peter Exp $ + * $Id: support.s,v 1.53 1997/05/29 05:11:10 peter Exp $ */ #include "npx.h" @@ -40,7 +40,6 @@ #include <machine/cputypes.h> #include <machine/pmap.h> #include <machine/specialreg.h> -#include <machine/smpasm.h> #include "assym.s" @@ -195,7 +194,7 @@ do0: ret #endif -#if defined(I586_CPU) && NNPX > 0 && !defined(SMP) +#if defined(I586_CPU) && NNPX > 0 ENTRY(i586_bzero) movl 4(%esp),%edx movl 8(%esp),%ecx @@ -438,7 +437,7 @@ ENTRY(generic_bcopy) cld ret -#if defined(I586_CPU) && NNPX > 0 && !defined(SMP) +#if defined(I586_CPU) && NNPX > 0 ENTRY(i586_bcopy) pushl %esi pushl %edi @@ -623,7 +622,7 @@ ENTRY(copyout) jmp *_copyout_vector ENTRY(generic_copyout) - GETCURPCB(%eax) + movl _curpcb,%eax movl $copyout_fault,PCB_ONFAULT(%eax) pushl %esi pushl %edi @@ -716,7 +715,7 @@ ENTRY(generic_copyout) 3: movl %ebx,%ecx -#if defined(I586_CPU) && NNPX > 0 && !defined(SMP) +#if defined(I586_CPU) && NNPX > 0 ALIGN_TEXT slow_copyout: #endif @@ -734,7 +733,7 @@ done_copyout: popl %edi popl %esi xorl %eax,%eax - GETCURPCB(%edx) + movl _curpcb,%edx movl %eax,PCB_ONFAULT(%edx) ret @@ -743,12 +742,12 @@ copyout_fault: popl %ebx popl %edi popl %esi - GETCURPCB(%edx) + movl _curpcb,%edx movl $0,PCB_ONFAULT(%edx) movl $EFAULT,%eax ret -#if defined(I586_CPU) && NNPX > 0 && !defined(SMP) +#if defined(I586_CPU) && NNPX > 0 ENTRY(i586_copyout) /* * Duplicated from generic_copyout. Could be done a bit better. @@ -808,7 +807,7 @@ ENTRY(copyin) jmp *_copyin_vector ENTRY(generic_copyin) - GETCURPCB(%eax) + movl _curpcb,%eax movl $copyin_fault,PCB_ONFAULT(%eax) pushl %esi pushl %edi @@ -825,7 +824,7 @@ ENTRY(generic_copyin) cmpl $VM_MAXUSER_ADDRESS,%edx ja copyin_fault -#if defined(I586_CPU) && NNPX > 0 && !defined(SMP) +#if defined(I586_CPU) && NNPX > 0 ALIGN_TEXT slow_copyin: #endif @@ -839,14 +838,14 @@ slow_copyin: rep movsb -#if defined(I586_CPU) && NNPX > 0 && !defined(SMP) +#if defined(I586_CPU) && NNPX > 0 ALIGN_TEXT done_copyin: #endif popl %edi popl %esi xorl %eax,%eax - GETCURPCB(%edx) + movl _curpcb,%edx movl %eax,PCB_ONFAULT(%edx) ret @@ -854,12 +853,12 @@ done_copyin: copyin_fault: popl %edi popl %esi - GETCURPCB(%edx) + movl _curpcb,%edx movl $0,PCB_ONFAULT(%edx) movl $EFAULT,%eax ret -#if defined(I586_CPU) && NNPX > 0 && !defined(SMP) +#if defined(I586_CPU) && NNPX > 0 ENTRY(i586_copyin) /* * Duplicated from generic_copyin. Could be done a bit better. @@ -894,7 +893,7 @@ ENTRY(i586_copyin) jmp done_copyin #endif /* I586_CPU && NNPX > 0 */ -#if defined(I586_CPU) && NNPX > 0 && !defined(SMP) +#if defined(I586_CPU) && NNPX > 0 /* fastmove(src, dst, len) src in %esi dst in %edi @@ -1086,7 +1085,7 @@ fastmove_tail_fault: * fu{byte,sword,word} : fetch a byte (sword, word) from user memory */ ENTRY(fuword) - GETCURPCB(%ecx) + movl _curpcb,%ecx movl $fusufault,PCB_ONFAULT(%ecx) movl 4(%esp),%edx /* from */ @@ -1109,7 +1108,7 @@ ENTRY(fuswintr) ret ENTRY(fusword) - GETCURPCB(%ecx) + movl _curpcb,%ecx movl $fusufault,PCB_ONFAULT(%ecx) movl 4(%esp),%edx @@ -1121,7 +1120,7 @@ ENTRY(fusword) ret ENTRY(fubyte) - GETCURPCB(%ecx) + movl _curpcb,%ecx movl $fusufault,PCB_ONFAULT(%ecx) movl 4(%esp),%edx @@ -1134,7 +1133,7 @@ ENTRY(fubyte) ALIGN_TEXT fusufault: - GETCURPCB(%ecx) + movl _curpcb,%ecx xorl %eax,%eax movl %eax,PCB_ONFAULT(%ecx) decl %eax @@ -1144,7 +1143,7 @@ fusufault: * su{byte,sword,word}: write a byte (word, longword) to user memory */ ENTRY(suword) - GETCURPCB(%ecx) + movl _curpcb,%ecx movl $fusufault,PCB_ONFAULT(%ecx) movl 4(%esp),%edx @@ -1188,12 +1187,12 @@ ENTRY(suword) movl 8(%esp),%eax movl %eax,(%edx) xorl %eax,%eax - GETCURPCB(%ecx) + movl _curpcb,%ecx movl %eax,PCB_ONFAULT(%ecx) ret ENTRY(susword) - GETCURPCB(%ecx) + movl _curpcb,%ecx movl $fusufault,PCB_ONFAULT(%ecx) movl 4(%esp),%edx @@ -1237,13 +1236,13 @@ ENTRY(susword) movw 8(%esp),%ax movw %ax,(%edx) xorl %eax,%eax - GETCURPCB(%ecx) /* restore trashed register */ + movl _curpcb,%ecx /* restore trashed register */ movl %eax,PCB_ONFAULT(%ecx) ret ALTENTRY(suibyte) ENTRY(subyte) - GETCURPCB(%ecx) + movl _curpcb,%ecx movl $fusufault,PCB_ONFAULT(%ecx) movl 4(%esp),%edx @@ -1286,7 +1285,7 @@ ENTRY(subyte) movb 8(%esp),%al movb %al,(%edx) xorl %eax,%eax - GETCURPCB(%ecx) /* restore trashed register */ + movl _curpcb,%ecx /* restore trashed register */ movl %eax,PCB_ONFAULT(%ecx) ret @@ -1300,7 +1299,7 @@ ENTRY(subyte) ENTRY(copyinstr) pushl %esi pushl %edi - GETCURPCB(%ecx) + movl _curpcb,%ecx movl $cpystrflt,PCB_ONFAULT(%ecx) movl 12(%esp),%esi /* %esi = from */ @@ -1348,7 +1347,7 @@ cpystrflt: cpystrflt_x: /* set *lencopied and return %eax */ - GETCURPCB(%ecx) + movl _curpcb,%ecx movl $0,PCB_ONFAULT(%ecx) movl 20(%esp),%ecx subl %edx,%ecx diff --git a/sys/i386/i386/swtch.s b/sys/i386/i386/swtch.s index 923d694..eacef02 100644 --- a/sys/i386/i386/swtch.s +++ b/sys/i386/i386/swtch.s @@ -33,22 +33,21 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: swtch.s,v 1.51 1997/05/31 09:27:29 peter Exp $ + * $Id: swtch.s,v 1.52 1997/06/07 04:36:10 bde Exp $ */ #include "npx.h" #include "opt_user_ldt.h" -#include "opt_smp_privpages.h" #include <sys/rtprio.h> #include <machine/asmacros.h> #include <machine/ipl.h> -#include <machine/smpasm.h> #include <machine/smptests.h> /** TEST_LOPRIO */ -#if defined(SMP) && defined(SMP_PRIVPAGES) +#if defined(SMP) #include <machine/pmap.h> +#include <machine/apic.h> #endif #include "assym.s" @@ -250,7 +249,7 @@ _idle: #ifdef SMP movl _smp_active, %eax cmpl $0, %eax - jnz badsw + jnz badsw3 #endif /* SMP */ xorl %ebp,%ebp movl $HIDENAME(tmpstk),%esp @@ -258,12 +257,7 @@ _idle: movl %ecx,%cr3 /* update common_tss.tss_esp0 pointer */ -#ifdef SMP - GETCPUID(%eax) - movl _SMPcommon_tss_ptr(,%eax,4), %eax -#else movl $_common_tss, %eax -#endif movl %esp, TSS_ESP0(%eax) #ifdef TSS_IS_CACHED /* example only */ @@ -315,7 +309,7 @@ ENTRY(default_halt) ENTRY(cpu_switch) /* switch to new process. first, save context as needed */ - GETCURPROC(%ecx) + movl _curproc,%ecx /* if no process to save, don't bother */ testl %ecx,%ecx @@ -342,16 +336,15 @@ ENTRY(cpu_switch) #ifdef SMP movl _mp_lock, %eax cmpl $0xffffffff, %eax /* is it free? */ - je badsw /* yes, bad medicine! */ + je badsw4 /* yes, bad medicine! */ andl $0x00ffffff, %eax /* clear CPU portion */ movl %eax,PCB_MPNEST(%ecx) /* store it */ #endif /* SMP */ #if NNPX > 0 /* have we used fp, and need a save? */ - GETCURPROC(%eax) - GETNPXPROC(%ebx) - cmp %eax,%ebx + movl _curproc,%eax + cmpl %eax,_npxproc jne 1f addl $PCB_SAVEFPU,%ecx /* h/w bugs make saving complicated */ pushl %ecx @@ -362,7 +355,7 @@ ENTRY(cpu_switch) movb $1,_intr_nesting_level /* charge Intr, not Sys/Idle */ - SETCURPROC($0, %edi) + movl $0,_curproc /* out of process */ /* save is done, now choose a new process or idle */ sw1: @@ -451,16 +444,16 @@ swtch_com: #ifdef DIAGNOSTIC cmpl %eax,P_WCHAN(%ecx) - jne badsw + jne badsw1 cmpb $SRUN,P_STAT(%ecx) - jne badsw + jne badsw2 #endif movl %eax,P_BACK(%ecx) /* isolate process to run */ movl P_ADDR(%ecx),%edx movl PCB_CR3(%edx),%ebx -#if defined(SMP) && defined(SMP_PRIVPAGES) +#if defined(SMP) /* Grab the private PT pointer from the outgoing process's PTD */ movl $_PTD,%esi movl 4*MPPTDI(%esi), %eax /* fetch cpu's prv pt */ @@ -469,7 +462,7 @@ swtch_com: /* switch address space */ movl %ebx,%cr3 -#if defined(SMP) && defined(SMP_PRIVPAGES) +#if defined(SMP) /* Copy the private PT to the new process's PTD */ /* XXX yuck, the _PTD changes when we switch, so we have to * reload %cr3 after changing the address space. @@ -477,7 +470,6 @@ swtch_com: * location of the per-process PTD in the PCB or something quick. * Dereferencing proc->vm_map->pmap->p_pdir[] is painful in asm. */ - movl $_PTD,%esi movl %eax, 4*MPPTDI(%esi) /* restore cpu's prv page */ /* XXX: we have just changed the page tables.. reload.. */ @@ -499,12 +491,7 @@ swtch_com: #endif /* update common_tss.tss_esp0 pointer */ -#ifdef SMP - GETCPUID(%eax) - movl _SMPcommon_tss_ptr(,%eax,4), %eax -#else movl $_common_tss, %eax -#endif movl %edx, %ebx /* pcb */ addl $(UPAGES * PAGE_SIZE), %ebx movl %ebx, TSS_ESP0(%eax) @@ -527,25 +514,22 @@ swtch_com: movl %eax,(%esp) #ifdef SMP - GETCPUID(%eax) + movl _cpuid,%eax movb %al, P_ONCPU(%ecx) #endif - SETCURPCB(%edx, %eax) - SETCURPROC(%ecx, %eax) + movl %edx,_curpcb + movl %ecx,_curproc /* into next process */ movb $0,_intr_nesting_level #ifdef SMP - movl _apic_base, %eax /* base addr of LOCAL APIC */ #if defined(TEST_LOPRIO) - pushl %edx - movl APIC_TPR(%eax), %edx /* get TPR register contents */ - andl $~0xff, %edx /* clear the prio field */ - movl %edx, APIC_TPR(%eax) /* now hold loprio for INTs */ - popl %edx + /* Set us to prefer to get irq's from the apic since we have the lock */ + movl lapic_tpr, %eax /* get TPR register contents */ + andl $0xffffff00, %eax /* clear the prio field */ + movl %eax, lapic_tpr /* now hold loprio for INTs */ #endif /* TEST_LOPRIO */ - movl APIC_ID(%eax), %eax /* APIC ID register */ - andl $APIC_ID_MASK, %eax /* extract ID portion */ - orl PCB_MPNEST(%edx), %eax /* add count from PROC */ + movl _cpu_lockid,%eax + orl PCB_MPNEST(%edx), %eax /* add next count from PROC */ movl %eax, _mp_lock /* load the mp_lock */ #endif /* SMP */ @@ -579,11 +563,33 @@ CROSSJUMPTARGET(idqr) CROSSJUMPTARGET(nortqr) CROSSJUMPTARGET(sw1a) -badsw: - pushl $sw0 +#ifdef DIAGNOSTIC +badsw1: + pushl $sw0_1 + call _panic + +sw0_1: .asciz "cpu_switch: has wchan" + +badsw2: + pushl $sw0_2 + call _panic + +sw0_2: .asciz "cpu_switch: not SRUN" +#endif + +#ifdef SMP +badsw3: + pushl $sw0_3 call _panic -sw0: .asciz "cpu_switch" +sw0_3: .asciz "cpu_switch: went idle with smp_active" + +badsw4: + pushl $sw0_4 + call _panic + +sw0_4: .asciz "cpu_switch: do not have lock" +#endif /* * savectx(pcb) @@ -618,7 +624,7 @@ ENTRY(savectx) * have to handle h/w bugs for reloading. We used to lose the * parent's npx state for forks by forgetting to reload. */ - GETNPXPROC(%eax) + movl _npxproc,%eax testl %eax,%eax je 1f diff --git a/sys/i386/i386/trap.c b/sys/i386/i386/trap.c index 89dd34f..8914a5b 100644 --- a/sys/i386/i386/trap.c +++ b/sys/i386/i386/trap.c @@ -35,7 +35,7 @@ * SUCH DAMAGE. * * from: @(#)trap.c 7.4 (Berkeley) 5/13/91 - * $Id: trap.c,v 1.98 1997/06/02 08:19:03 dfr Exp $ + * $Id: trap.c,v 1.99 1997/06/07 04:36:10 bde Exp $ */ /* @@ -87,11 +87,7 @@ #include "isa.h" #include "npx.h" -#ifdef SMP -extern struct i386tss *SMPcommon_tss_ptr[]; -#else extern struct i386tss common_tss; -#endif int (*pmath_emulate) __P((struct trapframe *)); @@ -704,7 +700,7 @@ trap_fatal(frame) type, trap_msg[type], ISPL(frame->tf_cs) == SEL_UPL ? "user" : "kernel"); #ifdef SMP - printf("cpunumber = %d\n", cpunumber()); + printf("cpuid = %d\n", cpuid); #endif if (type == T_PAGEFLT) { printf("fault virtual address = 0x%x\n", eva); @@ -790,19 +786,12 @@ trap_fatal(frame) void dblfault_handler() { -#ifdef SMP - int x = cpunumber(); -#endif - printf("\nFatal double fault:\n"); -#ifdef SMP - printf("eip = 0x%x\n", SMPcommon_tss_ptr[x]->tss_eip); - printf("esp = 0x%x\n", SMPcommon_tss_ptr[x]->tss_esp); - printf("ebp = 0x%x\n", SMPcommon_tss_ptr[x]->tss_ebp); -#else printf("eip = 0x%x\n", common_tss.tss_eip); printf("esp = 0x%x\n", common_tss.tss_esp); printf("ebp = 0x%x\n", common_tss.tss_ebp); +#ifdef SMP + printf("cpuid = %d\n", cpuid); #endif panic("double fault"); } diff --git a/sys/i386/i386/vm_machdep.c b/sys/i386/i386/vm_machdep.c index 6f1a4b6..5ad743d 100644 --- a/sys/i386/i386/vm_machdep.c +++ b/sys/i386/i386/vm_machdep.c @@ -38,7 +38,7 @@ * * from: @(#)vm_machdep.c 7.3 (Berkeley) 5/13/91 * Utah $Hdr: vm_machdep.c 1.16.1.1 89/06/23$ - * $Id: vm_machdep.c,v 1.79 1997/04/16 12:11:37 kato Exp $ + * $Id: vm_machdep.c,v 1.80 1997/05/07 20:19:18 peter Exp $ */ #include "npx.h" @@ -78,13 +78,6 @@ #include <i386/isa/isa.h> #endif -#ifdef SMP -extern struct proc *SMPnpxproc[]; -#define npxproc (SMPnpxproc[cpunumber()]) -#else -extern struct proc *npxproc; -#endif - #ifdef BOUNCE_BUFFERS static vm_offset_t vm_bounce_kva __P((int size, int waitok)); diff --git a/sys/i386/include/apic.h b/sys/i386/include/apic.h index 1d92faf..8e7f2a8 100644 --- a/sys/i386/include/apic.h +++ b/sys/i386/include/apic.h @@ -22,7 +22,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: apic.h,v 1.1 1997/05/28 19:43:45 smp Exp smp $ + * $Id: apic.h,v 1.3 1997/05/29 05:57:43 fsmp Exp $ */ #ifndef _MACHINE_APIC_H_ @@ -223,76 +223,6 @@ typedef struct IOAPIC ioapic_t; /* default physical locations of LOCAL (CPU) APICs */ #define DEFAULT_APIC_BASE 0xfee00000 -# if defined(LOCORE) - -#define APIC_ID 0x020 -#define APIC_VER 0x030 -#define APIC_TPR 0x080 -#define APIC_APR 0x090 -#define APIC_PPR 0x0a0 -#define APIC_EOI 0x0b0 -#define APIC_RR 0x0c0 -#define APIC_LDR 0x0d0 -#define APIC_DFR 0x0e0 -#define APIC_SVR 0x0f0 -#define APIC_ISR 0x100 -#define APIC_ISR0 0x100 -#define APIC_ISR1 0x110 -#define APIC_ISR2 0x120 -#define APIC_TMR 0x180 -#define APIC_IRR 0x200 -#define APIC_IRR0 0x200 -#define APIC_IRR1 0x210 -#define APIC_IRR2 0x220 -#define APIC_ESR 0x280 -#define APIC_ICR_LOW 0x300 -#define APIC_ICR_HI 0x310 -#define APIC_LVTT 0x320 -#define APIC_LVT1 0x350 -#define APIC_LVT2 0x360 -#define APIC_LVT3 0x370 -#define APIC_TICR 0x380 -#define APIC_TCCR 0x390 -#define APIC_TDCR 0x3e0 - -# else /* !LOCORE */ - -#if 0 /** XXX APIC_STRUCT */ -/* offsets in apic_base[] */ -#define APIC_ID (0x020/4) -#define APIC_VER (0x030/4) -#define APIC_TPR (0x080/4) -#define APIC_APR (0x090/4) -#define APIC_PPR (0x0a0/4) -#define APIC_EOI (0x0b0/4) -#define APIC_RR (0x0c0/4) -#define APIC_LDR (0x0d0/4) -#define APIC_DFR (0x0e0/4) -#define APIC_SVR (0x0f0/4) -#define APIC_ISR (0x100/4) -#define APIC_ISR0 (0x100/4) -#define APIC_ISR1 (0x110/4) -#define APIC_ISR2 (0x120/4) -#define APIC_TMR (0x180/4) -#define APIC_IRR (0x200/4) -#define APIC_IRR0 (0x200/4) -#define APIC_IRR1 (0x210/4) -#define APIC_IRR2 (0x220/4) -#define APIC_ESR (0x280/4) -#define APIC_ICR_LOW (0x300/4) -#define APIC_ICR_HI (0x310/4) -#define APIC_LVTT (0x320/4) -#define APIC_LVT1 (0x350/4) -#define APIC_LVT2 (0x360/4) -#define APIC_LVT3 (0x370/4) -#define APIC_TICR (0x380/4) -#define APIC_TCCR (0x390/4) -#define APIC_TDCR (0x3e0/4) -#endif /** XXX APIC_STRUCT */ - -# endif /* LOCORE */ - - /* fields in VER */ #define APIC_VER_VERSION 0x000000ff #define APIC_VER_MAXLVT 0x00ff0000 @@ -501,45 +431,4 @@ typedef struct IOAPIC ioapic_t; #define IOART_INTVEC 0x000000ff /* R/W: INTerrupt vector field */ -/** - * XXX FIXME: temproary defines till we get private pages... - */ -#if 1 /** XXX APIC_STRUCT */ - -/* XXX when automatically mapped to a virtual page */ -#define lapic__id lapic->id -#define lapic__version lapic->version -#define lapic__eoi lapic->eoi -#define lapic__irr1 lapic->irr1 -#define lapic__lvt_lint0 lapic->lvt_lint0 -#define lapic__lvt_lint1 lapic->lvt_lint1 -#define lapic__tpr lapic->tpr -#define lapic__svr lapic->svr -#define lapic__icr_lo lapic->icr_lo -#define lapic__icr_hi lapic->icr_hi -#define lapic__dcr_timer lapic->dcr_timer -#define lapic__lvt_timer lapic->lvt_timer -#define lapic__icr_timer lapic->icr_timer -#define lapic__ccr_timer lapic->ccr_timer - -#else - -/* XXX when mapped to a known virtual address */ -#define lapic__id lapic.id -#define lapic__version lapic.version -#define lapic__eoi lapic.eoi -#define lapic__irr1 lapic.irr1 -#define lapic__lvt_lint0 lapic.lvt_lint0 -#define lapic__lvt_lint1 lapic.lvt_lint1 -#define lapic__tpr lapic.tpr -#define lapic__svr lapic.svr -#define lapic__icr_lo lapic.icr_lo -#define lapic__icr_hi lapic.icr_hi -#define lapic__dcr_timer lapic.dcr_timer -#define lapic__lvt_timer lapic.lvt_timer -#define lapic__icr_timer lapic.icr_timer -#define lapic__ccr_timer lapic.ccr_timer - -#endif /** XXX APIC_STRUCT */ - #endif /* _MACHINE_APIC_H_ */ diff --git a/sys/i386/include/apicreg.h b/sys/i386/include/apicreg.h index 1d92faf..8e7f2a8 100644 --- a/sys/i386/include/apicreg.h +++ b/sys/i386/include/apicreg.h @@ -22,7 +22,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: apic.h,v 1.1 1997/05/28 19:43:45 smp Exp smp $ + * $Id: apic.h,v 1.3 1997/05/29 05:57:43 fsmp Exp $ */ #ifndef _MACHINE_APIC_H_ @@ -223,76 +223,6 @@ typedef struct IOAPIC ioapic_t; /* default physical locations of LOCAL (CPU) APICs */ #define DEFAULT_APIC_BASE 0xfee00000 -# if defined(LOCORE) - -#define APIC_ID 0x020 -#define APIC_VER 0x030 -#define APIC_TPR 0x080 -#define APIC_APR 0x090 -#define APIC_PPR 0x0a0 -#define APIC_EOI 0x0b0 -#define APIC_RR 0x0c0 -#define APIC_LDR 0x0d0 -#define APIC_DFR 0x0e0 -#define APIC_SVR 0x0f0 -#define APIC_ISR 0x100 -#define APIC_ISR0 0x100 -#define APIC_ISR1 0x110 -#define APIC_ISR2 0x120 -#define APIC_TMR 0x180 -#define APIC_IRR 0x200 -#define APIC_IRR0 0x200 -#define APIC_IRR1 0x210 -#define APIC_IRR2 0x220 -#define APIC_ESR 0x280 -#define APIC_ICR_LOW 0x300 -#define APIC_ICR_HI 0x310 -#define APIC_LVTT 0x320 -#define APIC_LVT1 0x350 -#define APIC_LVT2 0x360 -#define APIC_LVT3 0x370 -#define APIC_TICR 0x380 -#define APIC_TCCR 0x390 -#define APIC_TDCR 0x3e0 - -# else /* !LOCORE */ - -#if 0 /** XXX APIC_STRUCT */ -/* offsets in apic_base[] */ -#define APIC_ID (0x020/4) -#define APIC_VER (0x030/4) -#define APIC_TPR (0x080/4) -#define APIC_APR (0x090/4) -#define APIC_PPR (0x0a0/4) -#define APIC_EOI (0x0b0/4) -#define APIC_RR (0x0c0/4) -#define APIC_LDR (0x0d0/4) -#define APIC_DFR (0x0e0/4) -#define APIC_SVR (0x0f0/4) -#define APIC_ISR (0x100/4) -#define APIC_ISR0 (0x100/4) -#define APIC_ISR1 (0x110/4) -#define APIC_ISR2 (0x120/4) -#define APIC_TMR (0x180/4) -#define APIC_IRR (0x200/4) -#define APIC_IRR0 (0x200/4) -#define APIC_IRR1 (0x210/4) -#define APIC_IRR2 (0x220/4) -#define APIC_ESR (0x280/4) -#define APIC_ICR_LOW (0x300/4) -#define APIC_ICR_HI (0x310/4) -#define APIC_LVTT (0x320/4) -#define APIC_LVT1 (0x350/4) -#define APIC_LVT2 (0x360/4) -#define APIC_LVT3 (0x370/4) -#define APIC_TICR (0x380/4) -#define APIC_TCCR (0x390/4) -#define APIC_TDCR (0x3e0/4) -#endif /** XXX APIC_STRUCT */ - -# endif /* LOCORE */ - - /* fields in VER */ #define APIC_VER_VERSION 0x000000ff #define APIC_VER_MAXLVT 0x00ff0000 @@ -501,45 +431,4 @@ typedef struct IOAPIC ioapic_t; #define IOART_INTVEC 0x000000ff /* R/W: INTerrupt vector field */ -/** - * XXX FIXME: temproary defines till we get private pages... - */ -#if 1 /** XXX APIC_STRUCT */ - -/* XXX when automatically mapped to a virtual page */ -#define lapic__id lapic->id -#define lapic__version lapic->version -#define lapic__eoi lapic->eoi -#define lapic__irr1 lapic->irr1 -#define lapic__lvt_lint0 lapic->lvt_lint0 -#define lapic__lvt_lint1 lapic->lvt_lint1 -#define lapic__tpr lapic->tpr -#define lapic__svr lapic->svr -#define lapic__icr_lo lapic->icr_lo -#define lapic__icr_hi lapic->icr_hi -#define lapic__dcr_timer lapic->dcr_timer -#define lapic__lvt_timer lapic->lvt_timer -#define lapic__icr_timer lapic->icr_timer -#define lapic__ccr_timer lapic->ccr_timer - -#else - -/* XXX when mapped to a known virtual address */ -#define lapic__id lapic.id -#define lapic__version lapic.version -#define lapic__eoi lapic.eoi -#define lapic__irr1 lapic.irr1 -#define lapic__lvt_lint0 lapic.lvt_lint0 -#define lapic__lvt_lint1 lapic.lvt_lint1 -#define lapic__tpr lapic.tpr -#define lapic__svr lapic.svr -#define lapic__icr_lo lapic.icr_lo -#define lapic__icr_hi lapic.icr_hi -#define lapic__dcr_timer lapic.dcr_timer -#define lapic__lvt_timer lapic.lvt_timer -#define lapic__icr_timer lapic.icr_timer -#define lapic__ccr_timer lapic.ccr_timer - -#endif /** XXX APIC_STRUCT */ - #endif /* _MACHINE_APIC_H_ */ diff --git a/sys/i386/include/asnames.h b/sys/i386/include/asnames.h index 5599a12..0059932 100644 --- a/sys/i386/include/asnames.h +++ b/sys/i386/include/asnames.h @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: asnames.h,v 1.2 1997/05/21 22:56:59 jdp Exp $ + * $Id: asnames.h,v 1.3 1997/05/25 16:58:03 fsmp Exp $ */ #ifndef _MACHINE_ASNAMES_H_ @@ -64,11 +64,6 @@ #define _PTD PTD #define _PTDpde PTDpde #define _PTmap PTmap -#define _SMPcommon_tss_ptr SMPcommon_tss_ptr -#define _SMPcurpcb SMPcurpcb -#define _SMPcurproc SMPcurproc -#define _SMPnpxproc SMPnpxproc -#define _SMPruntime SMPruntime #define _Xalign Xalign #define _Xbnd Xbnd #define _Xbpt Xbpt @@ -172,6 +167,7 @@ #define _bootDataSeg bootDataSeg #define _bootMP bootMP #define _bootMP_size bootMP_size +#define _bootPTD bootPTD #define _bootdev bootdev #define _boothowto boothowto #define _bootinfo bootinfo @@ -183,6 +179,8 @@ #define _copyout_vector copyout_vector #define _cpl cpl #define _cpu cpu +#define _cpu0prvpage cpu0prvpage +#define _cpu0prvpt cpu0prvpt #define _cpu_apic_versions cpu_apic_versions #define _cpu_class cpu_class #define _cpu_feature cpu_feature @@ -224,7 +222,6 @@ #define _intr_unit intr_unit #define _intrcnt intrcnt #define _intrnames intrnames -#define _io_apic_base io_apic_base #define _ipending ipending #define _ivectors ivectors #define _kernelname kernelname diff --git a/sys/i386/include/mpapic.h b/sys/i386/include/mpapic.h index c64ca3e..3ea2f6d 100644 --- a/sys/i386/include/mpapic.h +++ b/sys/i386/include/mpapic.h @@ -22,7 +22,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: mpapic.h,v 1.6 1997/05/29 05:57:43 fsmp Exp $ + * $Id: mpapic.h,v 1.7 1997/05/31 03:29:06 fsmp Exp $ */ #ifndef _MACHINE_MPAPIC_H_ @@ -87,11 +87,10 @@ enum busTypes { * read 'reg' from 'apic' */ static __inline u_int32_t -/** XXX APIC_STRUCT */ io_apic_read(int apic, int reg) { - ioapic[apic].ioregsel = reg; - return ioapic[apic].iowin; + ioapic[apic]->ioregsel = reg; + return ioapic[apic]->iowin; } @@ -99,11 +98,10 @@ io_apic_read(int apic, int reg) * write 'value' to 'reg' of 'apic' */ static __inline void -/** XXX APIC_STRUCT */ io_apic_write(int apic, int reg, u_int32_t value) { - ioapic[apic].ioregsel = reg; - ioapic[apic].iowin = value; + ioapic[apic]->ioregsel = reg; + ioapic[apic]->iowin = value; } @@ -113,7 +111,7 @@ io_apic_write(int apic, int reg, u_int32_t value) static __inline void apic_eoi(void) { - lapic__eoi = 0; + lapic.eoi = 0; } diff --git a/sys/i386/include/mptable.h b/sys/i386/include/mptable.h index a27cf86..c817925 100644 --- a/sys/i386/include/mptable.h +++ b/sys/i386/include/mptable.h @@ -22,11 +22,10 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: mp_machdep.c,v 1.16 1997/05/29 05:58:41 fsmp Exp $ + * $Id: mp_machdep.c,v 1.17 1997/06/02 10:44:08 dfr Exp $ */ #include "opt_smp.h" -#include "opt_serial.h" #include <sys/param.h> /* for KERNBASE */ #include <sys/types.h> @@ -38,18 +37,21 @@ #include <vm/vm_param.h> /* for KERNBASE */ #include <vm/pmap.h> /* for KERNBASE */ #include <machine/pmap.h> /* for KERNBASE */ +#include <vm/vm_kern.h> +#include <vm/vm_extern.h> #include <machine/smp.h> #include <machine/apic.h> #include <machine/mpapic.h> #include <machine/cpufunc.h> #include <machine/segments.h> -#include <machine/smptests.h> /** TEST_DEFAULT_CONFIG, LATE_START */ +#include <machine/smptests.h> /** TEST_DEFAULT_CONFIG */ +#include <machine/tss.h> #include <i386/i386/cons.h> /* cngetc() */ #if defined(APIC_IO) -#include <i386/include/md_var.h> /* setidt() */ +#include <machine/md_var.h> /* setidt() */ #include <i386/isa/icu.h> /* Xinvltlb() */ #include <i386/isa/intr_machdep.h> /* Xinvltlb() */ #endif /* APIC_IO */ @@ -186,11 +188,6 @@ typedef struct BASETABLE_ENTRY { /** FIXME: what system files declare these??? */ extern struct region_descriptor r_gdt, r_idt; -/* global data */ -struct proc *SMPcurproc[NCPU]; -struct pcb *SMPcurpcb[NCPU]; -struct timeval SMPruntime[NCPU]; - int mp_ncpus; /* # of CPUs, including BSP */ int mp_naps; /* # of Applications processors */ int mp_nbusses; /* # of busses */ @@ -210,6 +207,15 @@ int cpu_num_to_apic_id[NAPICID]; int io_num_to_apic_id[NAPICID]; int apic_id_to_logical[NAPICID]; +/* Boot of AP uses this PTD */ +u_int *bootPTD; + +/* Hotwire a 0->4MB V==P mapping */ +extern pt_entry_t KPTphys; + +/* virtual address of per-cpu common_tss */ +extern struct i386tss common_tss; + /* * look for MP compliant motherboard. */ @@ -283,11 +289,6 @@ found: /* please forgive the 'goto'! */ if (mptable_pass1()) panic("you must reconfigure your kernel"); -#if defined(LATE_START) - /* create pages for (address common) cpu APIC and each IO APIC */ - pmap_bootstrap_apics(); -#endif /* LATE_START */ - /* flag fact that we are running multiple processors */ mp_capable = 1; return 1; @@ -305,9 +306,6 @@ mp_start(void) mp_enable(boot_address); else panic("MP hardware not found!"); - - /* finish pmap initialization - turn off V==P mapping at zero */ - pmap_bootstrap2(); } @@ -321,23 +319,25 @@ mp_announce(void) printf("FreeBSD/SMP: Multiprocessor motherboard\n"); printf(" cpu0 (BSP): apic id: %d", CPU_TO_ID(0)); - printf(", version: 0x%08x\n", cpu_apic_versions[0]); + printf(", version: 0x%08x", cpu_apic_versions[0]); + printf(", at 0x%08x\n", cpu_apic_address); for (x = 1; x <= mp_naps; ++x) { printf(" cpu%d (AP): apic id: %d", x, CPU_TO_ID(x)); - printf(", version: 0x%08x\n", cpu_apic_versions[x]); + printf(", version: 0x%08x", cpu_apic_versions[x]); + printf(", at 0x%08x\n", cpu_apic_address); } #if defined(APIC_IO) for (x = 0; x < mp_napics; ++x) { printf(" io%d (APIC): apic id: %d", x, IO_TO_ID(x)); - printf(", version: 0x%08x\n", io_apic_versions[x]); + printf(", version: 0x%08x", io_apic_versions[x]); + printf(", at 0x%08x\n", io_apic_address[x]); } #else printf(" Warning: APIC I/O disabled\n"); #endif /* APIC_IO */ } - /* * AP cpu's call this to sync up protected mode. */ @@ -352,12 +352,18 @@ init_secondary(void) lidt(&r_idt); lldt(_default_ldt); - slot = NGDT + cpunumber(); + slot = NGDT + cpuid; gsel_tss = GSEL(slot, SEL_KPL); gdt[slot].sd.sd_type = SDT_SYS386TSS; + common_tss.tss_esp0 = 0; /* not used until after switch */ + common_tss.tss_ss0 = GSEL(GDATA_SEL, SEL_KPL); + common_tss.tss_ioopt = (sizeof common_tss) << 16; ltr(gsel_tss); load_cr0(0x8005003b); /* XXX! */ + + PTD[0] = 0; + invltlb(); } @@ -375,9 +381,9 @@ configure_local_apic(void) outb(0x23, byte); /* disconnect 8259s/NMI */ } /* mask the LVT1 */ - temp = lapic__lvt_lint0; + temp = lapic.lvt_lint0; temp |= APIC_LVT_M; - lapic__lvt_lint0 = temp; + lapic.lvt_lint0 = temp; } #endif /* APIC_IO */ @@ -398,13 +404,15 @@ mp_enable(u_int boot_addr) u_int ux; #endif /* APIC_IO */ - /* examine the MP table for needed info */ + /* Turn on 4MB of V == P addressing so we can get to MP table */ + *(int *)PTD = PG_V | PG_RW | ((u_long)KPTphys & PG_FRAME); + invltlb(); + + /* examine the MP table for needed info, uses physical addresses */ x = mptable_pass2(); -#if !defined(LATE_START) - /* create pages for (address common) cpu APIC and each IO APIC */ - pmap_bootstrap_apics(); -#endif /* LATE_START */ + *(int *)PTD = 0; + invltlb(); /* can't process default configs till the CPU APIC is pmapped */ if (x) @@ -832,7 +840,7 @@ fix_mp_table(void) for (x = 0; x < mp_nbusses; ++x) { if (bus_data[x].bus_type != PCI) continue; - if (bus_data[x].bus_id >= num_pci_bus ) + if (bus_data[x].bus_id >= num_pci_bus) panic("bad PCI bus numbering"); } } @@ -1258,7 +1266,7 @@ default_mp_table(int type) } #endif /* 0 */ - boot_cpu_id = (lapic__id & APIC_ID_MASK) >> 24; + boot_cpu_id = (lapic.id & APIC_ID_MASK) >> 24; ap_cpu_id = (boot_cpu_id == 0) ? 1 : 0; /* BSP */ @@ -1351,9 +1359,12 @@ default_mp_table(int type) static int start_all_aps(u_int boot_addr) { - int x; + int x, i; u_char mpbiosreason; u_long mpbioswarmvec; + pd_entry_t newptd; + pt_entry_t newpt; + int *newpp; /** * NOTE: this needs further thought: @@ -1362,7 +1373,7 @@ start_all_aps(u_int boot_addr) * * get the initial mp_lock with a count of 1 for the BSP */ - mp_lock = (lapic__id & APIC_ID_MASK) + 1; + mp_lock = (lapic.id & APIC_ID_MASK) + 1; /* initialize BSP's local APIC */ apic_initialize(1); @@ -1370,6 +1381,7 @@ start_all_aps(u_int boot_addr) /* install the AP 1st level boot code */ install_ap_tramp(boot_addr); + /* save the current value of the warm-start vector */ mpbioswarmvec = *((u_long *) WARMBOOT_OFF); outb(CMOS_REG, BIOS_RESET); @@ -1378,6 +1390,58 @@ start_all_aps(u_int boot_addr) /* start each AP */ for (x = 1; x <= mp_naps; ++x) { + /* HACK HACK HACK !!! */ + + /* alloc new page table directory */ + newptd = (pd_entry_t)(kmem_alloc(kernel_map, PAGE_SIZE)); + + /* clone currently active one (ie: IdlePTD) */ + bcopy(PTD, newptd, PAGE_SIZE); /* inc prv page pde */ + + /* set up 0 -> 4MB P==V mapping for AP boot */ + newptd[0] = PG_V | PG_RW | ((u_long)KPTphys & PG_FRAME); + + /* store PTD for this AP */ + bootPTD = (pd_entry_t)vtophys(newptd); + + /* alloc new page table page */ + newpt = (pt_entry_t)(kmem_alloc(kernel_map, PAGE_SIZE)); + + /* set the new PTD's private page to point there */ + newptd[MPPTDI] = PG_V | PG_RW | vtophys(newpt); + + /* install self referential entry */ + newptd[PTDPTDI] = PG_V | PG_RW | vtophys(newptd); + + /* get a new private data page */ + newpp = (int *)kmem_alloc(kernel_map, PAGE_SIZE); + + /* wire it into the private page table page */ + newpt[0] = PG_V | PG_RW | vtophys(newpp); + + /* wire the ptp into itself for access */ + newpt[1] = PG_V | PG_RW | vtophys(newpt); + + /* and the local apic */ + newpt[2] = SMP_prvpt[2]; + + /* and the IO apic mapping[s] */ + for (i = 16; i < 32; i++) + newpt[i] = SMP_prvpt[i]; + + /* prime data page for it to use */ + newpp[0] = x; /* cpuid */ + newpp[1] = 0; /* curproc */ + newpp[2] = 0; /* curpcb */ + newpp[3] = 0; /* npxproc */ + newpp[4] = 0; /* runtime.tv_sec */ + newpp[5] = 0; /* runtime.tv_usec */ + newpp[6] = x << 24; /* cpu_lockid */ + + /* XXX NOTE: ABANDON bootPTD for now!!!! */ + + /* END REVOLTING HACKERY */ + /* setup a vector to our boot code */ *((volatile u_short *) WARMBOOT_OFF) = WARMBOOT_TARGET; *((volatile u_short *) WARMBOOT_SEG) = (boot_addr >> 4); @@ -1401,7 +1465,7 @@ start_all_aps(u_int boot_addr) } /* fill in our (BSP) APIC version */ - cpu_apic_versions[0] = lapic__version; + cpu_apic_versions[0] = lapic.version; /* restore the warmstart vector */ *(u_long *) WARMBOOT_OFF = mpbioswarmvec; @@ -1503,24 +1567,24 @@ start_ap(int logical_cpu, u_int boot_addr) */ /* setup the address for the target AP */ - icr_hi = lapic__icr_hi & ~APIC_ID_MASK; + icr_hi = lapic.icr_hi & ~APIC_ID_MASK; icr_hi |= (physical_cpu << 24); - lapic__icr_hi = icr_hi; + lapic.icr_hi = icr_hi; /* do an INIT IPI: assert RESET */ - icr_lo = lapic__icr_lo & 0xfff00000; - lapic__icr_lo = icr_lo | 0x0000c500; + icr_lo = lapic.icr_lo & 0xfff00000; + lapic.icr_lo = icr_lo | 0x0000c500; /* wait for pending status end */ - while (lapic__icr_lo & APIC_DELSTAT_MASK) + while (lapic.icr_lo & APIC_DELSTAT_MASK) /* spin */ ; /* do an INIT IPI: deassert RESET */ - lapic__icr_lo = icr_lo | 0x00008500; + lapic.icr_lo = icr_lo | 0x00008500; /* wait for pending status end */ u_sleep(10000); /* wait ~10mS */ - while (lapic__icr_lo & APIC_DELSTAT_MASK) + while (lapic.icr_lo & APIC_DELSTAT_MASK) /* spin */ ; /* @@ -1533,8 +1597,8 @@ start_ap(int logical_cpu, u_int boot_addr) */ /* do a STARTUP IPI */ - lapic__icr_lo = icr_lo | 0x00000600 | vector; - while (lapic__icr_lo & APIC_DELSTAT_MASK) + lapic.icr_lo = icr_lo | 0x00000600 | vector; + while (lapic.icr_lo & APIC_DELSTAT_MASK) /* spin */ ; u_sleep(200); /* wait ~200uS */ @@ -1545,8 +1609,8 @@ start_ap(int logical_cpu, u_int boot_addr) * recognized after hardware RESET or INIT IPI. */ - lapic__icr_lo = icr_lo | 0x00000600 | vector; - while (lapic__icr_lo & APIC_DELSTAT_MASK) + lapic.icr_lo = icr_lo | 0x00000600 | vector; + while (lapic.icr_lo & APIC_DELSTAT_MASK) /* spin */ ; u_sleep(200); /* wait ~200uS */ diff --git a/sys/i386/include/npx.h b/sys/i386/include/npx.h index 33c6a23..719142d 100644 --- a/sys/i386/include/npx.h +++ b/sys/i386/include/npx.h @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * from: @(#)npx.h 5.3 (Berkeley) 1/18/91 - * $Id$ + * $Id: npx.h,v 1.12 1997/02/22 09:34:52 peter Exp $ */ /* @@ -140,6 +140,8 @@ struct save87 { struct proc; +extern struct proc *npxproc; + int npxdna __P((void)); void npxexit __P((struct proc *p)); void npxinit __P((int control)); diff --git a/sys/i386/include/pcb.h b/sys/i386/include/pcb.h index c93ed87..18a9af1 100644 --- a/sys/i386/include/pcb.h +++ b/sys/i386/include/pcb.h @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * from: @(#)pcb.h 5.10 (Berkeley) 5/12/91 - * $Id: pcb.h,v 1.21 1997/05/07 19:49:32 peter Exp $ + * $Id: pcb.h,v 1.22 1997/06/07 04:36:05 bde Exp $ */ #ifndef _I386_PCB_H_ @@ -45,9 +45,6 @@ */ #include <machine/tss.h> #include <machine/npx.h> -#if defined(KERNEL) && defined(SMP) -#include <machine/smp.h> /* cpunumber() */ -#endif struct pcb { int pcb_cr3; @@ -82,12 +79,7 @@ struct md_coredump { #ifdef KERNEL -#ifdef SMP -extern struct pcb *SMPcurpcb[]; /* our current running pcb */ -#define curpcb (SMPcurpcb[cpunumber()]) -#else /* !SMP */ extern struct pcb *curpcb; /* our current running pcb */ -#endif /* SMP */ void savectx __P((struct pcb*)); #endif diff --git a/sys/i386/include/pmap.h b/sys/i386/include/pmap.h index f0d4c01..f00d4f2 100644 --- a/sys/i386/include/pmap.h +++ b/sys/i386/include/pmap.h @@ -42,7 +42,7 @@ * * from: hp300: @(#)pmap.h 7.2 (Berkeley) 12/16/90 * from: @(#)pmap.h 7.4 (Berkeley) 5/12/91 - * $Id: pmap.h,v 1.49 1997/04/07 09:30:20 peter Exp $ + * $Id: pmap.h,v 1.50 1997/04/26 11:45:41 peter Exp $ */ #ifndef _MACHINE_PMAP_H_ @@ -91,11 +91,11 @@ #define NKPT 9 /* actual number of kernel page tables */ #endif #ifndef NKPDE -#if defined(SMP) && defined(SMP_PRIVPAGES) +#ifdef SMP #define NKPDE 62 /* addressable number of page tables/pde's */ -#else /* SMP && SMP_PRIVPAGES */ +#else #define NKPDE 63 /* addressable number of page tables/pde's */ -#endif /* SMP && SMP_PRIVPAGES */ +#endif /* SMP */ #endif /* @@ -107,12 +107,12 @@ * SMP_PRIVPAGES: The per-cpu address space is 0xff80000 -> 0xffbfffff */ #define APTDPTDI (NPDEPG-1) /* alt ptd entry that points to APTD */ -#if defined(SMP) && defined(SMP_PRIVPAGES) +#ifdef SMP #define MPPTDI (APTDPTDI-1) /* per cpu ptd entry */ #define KPTDI (MPPTDI-NKPDE) /* start of kernel virtual pde's */ -#else /* SMP && SMP_PRIVPAGES */ +#else #define KPTDI (APTDPTDI-NKPDE)/* start of kernel virtual pde's */ -#endif /* SMP && SMP_PRIVPAGES */ +#endif /* SMP */ #define PTDPTDI (KPTDI-1) /* ptd entry that points to ptd! */ #define UMAXPTDI (PTDPTDI-1) /* ptd entry for user space end */ #define UMAXPTEOFF (NPTEPG-UPAGES_HOLE) /* pte entry for user space end */ @@ -141,7 +141,7 @@ typedef unsigned int *pt_entry_t; extern pt_entry_t PTmap[], APTmap[], Upte; extern pd_entry_t PTD[], APTD[], PTDpde, APTDpde, Upde; -extern int IdlePTD; /* physical address of "Idle" state directory */ +extern pd_entry_t IdlePTD; /* physical address of "Idle" state directory */ #endif /* diff --git a/sys/i386/include/smp.h b/sys/i386/include/smp.h index ee96269..2943764 100644 --- a/sys/i386/include/smp.h +++ b/sys/i386/include/smp.h @@ -6,7 +6,7 @@ * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp * ---------------------------------------------------------------------------- * - * $Id: smp.h,v 1.9 1997/05/28 18:44:11 fsmp Exp $ + * $Id: smp.h,v 1.10 1997/05/29 05:57:43 fsmp Exp $ * */ @@ -56,6 +56,8 @@ extern u_int32_t io_apic_versions[]; extern int cpu_num_to_apic_id[]; extern int io_num_to_apic_id[]; extern int apic_id_to_logical[]; +extern u_int SMP_prvpt[]; +extern u_char SMP_ioapic[]; /* functions in mp_machdep.c */ u_int mp_bootaddress __P((u_int)); @@ -79,18 +81,12 @@ void init_secondary __P((void)); void smp_invltlb __P((void)); /* global data in mpapic.c */ -extern volatile u_int* apic_base; -#if 1 /** XXX APIC_STRUCT */ -extern volatile lapic_t* lapic; -#endif /** XXX APIC_STRUCT */ +extern volatile lapic_t lapic; #if defined(MULTIPLE_IOAPICS) #error MULTIPLE_IOAPICSXXX #else -extern volatile u_int* io_apic_base; -#if 1 /** XXX APIC_STRUCT */ -extern volatile ioapic_t* ioapic; -#endif /** XXX APIC_STRUCT */ +extern volatile ioapic_t *ioapic[]; #endif /* MULTIPLE_IOAPICS */ /* functions in mpapic.c */ @@ -114,32 +110,8 @@ void u_sleep __P((int)); extern int smp_active; extern int invltlb_ok; -/* in pmap.c FIXME: belongs in pmap.h??? */ -void pmap_bootstrap_apics __P((void)); -void pmap_bootstrap2 __P((void)); - -#if 0 -/* chicken and egg problem... */ -static __inline unsigned -cpunumber(void) -{ - return (unsigned)ID_TO_CPU((apic_base[APIC_ID] & APIC_ID_MASK) >> 24); -} -#else -/* - * we 'borrow' this info from apic.h - * this will go away soon... - */ -static __inline unsigned -cpunumber(void) -{ -#if 0 - return (unsigned)(apic_id_to_logical[(apic_base[8] & 0x0f000000) >> 24]); -#else - return (unsigned)(apic_id_to_logical[(lapic__id & 0x0f000000) >> 24]); -#endif -} -#endif /* 0 */ +extern volatile u_int cpuid; +extern volatile u_int cpu_lockid; #endif /* SMP || APIC_IO */ #endif /* KERNEL */ diff --git a/sys/i386/include/smpasm.h b/sys/i386/include/smpasm.h deleted file mode 100644 index 6f15307..0000000 --- a/sys/i386/include/smpasm.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (c) 1996, by Peter Wemm - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. The name of the developer may NOT be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $Id: smpasm.h,v 1.8 1997/04/25 03:11:40 fsmp Exp $ - */ -#ifndef __MACHINE_SMPASM_H__ -#define __MACHINE_SMPASM_H__ 1 - - -#if defined(SMP) || defined(APIC_IO) - -#include <machine/apic.h> - -/* Macro to retrieve the current CPU id from hardware */ -#define GETCPUID(reg) \ - movl _apic_base, reg; \ - movl APIC_ID(reg), reg; \ - andl $APIC_ID_MASK, reg; \ - shrl $24, reg; \ - movl _apic_id_to_logical(,reg,4), reg - -#define SETCURPROC(val, reg) GETCPUID(reg); movl val, _SMPcurproc(,reg,4) -#define GETCURPROC(reg) GETCPUID(reg); movl _SMPcurproc(,reg,4), reg -#define SETCURPCB(val, reg) GETCPUID(reg); movl val, _SMPcurpcb(,reg,4) -#define GETCURPCB(reg) GETCPUID(reg); movl _SMPcurpcb(,reg,4), reg -#define SETNPXPROC(val, reg) GETCPUID(reg); movl val, _SMPnpxproc(,reg,4) -#define GETNPXPROC(reg) GETCPUID(reg); movl _SMPnpxproc(,reg,4), reg - -#else /* !SMP && !APIC_IO */ - -#define SETCURPROC(val, reg) movl val, _curproc -#define GETCURPROC(reg) movl _curproc, reg -#define SETCURPCB(val, reg) movl val, _curpcb -#define GETCURPCB(reg) movl _curpcb, reg -#define SETNPXPROC(val, reg) movl val, _npxproc -#define GETNPXPROC(reg) movl _npxproc, reg - -#endif /* SMP || APIC_IO */ - -#endif /* __MACHINE_SMPASM_H__ */ diff --git a/sys/i386/isa/apic_vector.s b/sys/i386/isa/apic_vector.s index 0817521..fa7edb0 100644 --- a/sys/i386/isa/apic_vector.s +++ b/sys/i386/isa/apic_vector.s @@ -1,6 +1,6 @@ /* * from: vector.s, 386BSD 0.1 unknown origin - * $Id: apic_vector.s,v 1.1 1997/05/26 17:58:26 fsmp Exp $ + * $Id: apic_vector.s,v 1.2 1997/05/31 08:59:51 peter Exp $ */ @@ -11,19 +11,19 @@ #define REDTBL_IDX(irq_num) (0x10 + ((irq_num) * 2)) /* - * 'lazy masking' code submitted by: Bruce Evans <bde@zeta.org.au> + * 'lazy masking' code suggested by Bruce Evans <bde@zeta.org.au> */ #define MAYBE_MASK_IRQ(irq_num) \ testl $IRQ_BIT(irq_num),iactive ; /* lazy masking */ \ je 1f ; /* NOT currently active */ \ orl $IRQ_BIT(irq_num),_imen ; /* set the mask bit */ \ - movl _io_apic_base,%ecx ; /* io apic addr */ \ + movl _ioapic,%ecx ; /* ioapic[0]addr */ \ movl $REDTBL_IDX(irq_num),(%ecx) ; /* write the index */ \ movl IOAPIC_WINDOW(%ecx),%eax ; /* current value */ \ orl $IOART_INTMASK,%eax ; /* set the mask */ \ movl %eax,IOAPIC_WINDOW(%ecx) ; /* new value */ \ - movl _apic_base, %eax ; \ - movl $0, APIC_EOI(%eax) ; \ + movl $lapic_eoi, %eax ; \ + movl $0, (%eax) ; \ orl $IRQ_BIT(irq_num), _ipending ; \ REL_MPLOCK ; /* SMP release global lock */ \ popl %es ; \ @@ -43,7 +43,7 @@ testl $IRQ_BIT(irq_num),_imen ; \ je 2f ; \ andl $~IRQ_BIT(irq_num),_imen ; /* clear mask bit */ \ - movl _io_apic_base,%ecx ; /* io apic addr */ \ + movl _ioapic,%ecx ; /* ioapic[0]addr */ \ movl $REDTBL_IDX(irq_num),(%ecx) ; /* write the index */ \ movl IOAPIC_WINDOW(%ecx),%eax ; /* current value */ \ andl $~IOART_INTMASK,%eax ; /* clear the mask */ \ @@ -72,8 +72,8 @@ IDTVEC(vec_name) ; \ GET_MPLOCK ; /* SMP Spin lock */ \ pushl _intr_unit + (irq_num) * 4 ; \ call *_intr_handler + (irq_num) * 4 ; /* do the work ASAP */ \ - movl _apic_base, %eax ; \ - movl $0, APIC_EOI(%eax) ; \ + movl $lapic_eoi, %eax ; \ + movl $0, (%eax) ; \ addl $4,%esp ; \ incl _cnt+V_INTR ; /* book-keeping can wait */ \ movl _intr_countp + (irq_num) * 4,%eax ; \ @@ -132,8 +132,8 @@ IDTVEC(vec_name) ; \ movl %ax,%es ; \ GET_MPLOCK ; /* SMP Spin lock */ \ MAYBE_MASK_IRQ(irq_num) ; \ - movl _apic_base, %eax ; \ - movl $0, APIC_EOI(%eax) ; \ + movl $lapic_eoi, %eax ; \ + movl $0, (%eax) ; \ movl _cpl,%eax ; \ testl $IRQ_BIT(irq_num), %eax ; \ jne 3f ; \ @@ -172,10 +172,9 @@ _Xinvltlb: pushl %eax movl %cr3, %eax /* invalidate the TLB */ movl %eax, %cr3 + movl $lapic_eoi, %eax ss /* stack segment, avoid %ds load */ - movl _apic_base, %eax - ss - movl $0, APIC_EOI(%eax) /* End Of Interrupt to APIC */ + movl $0, (%eax) /* End Of Interrupt to APIC */ popl %eax iret diff --git a/sys/i386/isa/intr_machdep.c b/sys/i386/isa/intr_machdep.c index 81557c3..d1caa64 100644 --- a/sys/i386/isa/intr_machdep.c +++ b/sys/i386/isa/intr_machdep.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * from: @(#)isa.c 7.2 (Berkeley) 5/13/91 - * $Id: intr_machdep.c,v 1.1 1997/06/02 08:19:04 dfr Exp $ + * $Id: intr_machdep.c,v 1.2 1997/06/02 15:28:10 kato Exp $ */ #include "opt_auto_eoi.h" @@ -268,7 +268,7 @@ isa_irq_pending(dvp) struct isa_device *dvp; { /* read APIC IRR containing the 16 ISA INTerrupts */ - return ((lapic__irr1 & 0x00ffffff) + return ((lapic.irr1 & 0x00ffffff) & (u_int32_t)dvp->id_irq) ? 1 : 0; } diff --git a/sys/i386/isa/nmi.c b/sys/i386/isa/nmi.c index 81557c3..d1caa64 100644 --- a/sys/i386/isa/nmi.c +++ b/sys/i386/isa/nmi.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * from: @(#)isa.c 7.2 (Berkeley) 5/13/91 - * $Id: intr_machdep.c,v 1.1 1997/06/02 08:19:04 dfr Exp $ + * $Id: intr_machdep.c,v 1.2 1997/06/02 15:28:10 kato Exp $ */ #include "opt_auto_eoi.h" @@ -268,7 +268,7 @@ isa_irq_pending(dvp) struct isa_device *dvp; { /* read APIC IRR containing the 16 ISA INTerrupts */ - return ((lapic__irr1 & 0x00ffffff) + return ((lapic.irr1 & 0x00ffffff) & (u_int32_t)dvp->id_irq) ? 1 : 0; } diff --git a/sys/i386/isa/npx.c b/sys/i386/isa/npx.c index aca74fa..14487c95 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.44 1997/05/31 09:27:31 peter Exp $ + * $Id: npx.c,v 1.45 1997/06/02 08:19:05 dfr Exp $ */ #include "npx.h" @@ -63,6 +63,7 @@ #include <machine/clock.h> #include <machine/specialreg.h> #if defined(APIC_IO) +#include <machine/smp.h> #include <machine/apic.h> #include <machine/mpapic.h> #endif /* APIC_IO */ @@ -140,10 +141,8 @@ 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 + +#ifndef SMP /* XXX per-cpu on smp */ struct proc *npxproc; #endif @@ -172,8 +171,8 @@ asm 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) + movl $lapic_eoi,%eax # EOI to local APIC + movl $0,(%eax) # movl $0, APIC_EOI(%eax) movb $0,%al outb %al,$0xf0 # clear BUSY# latch popl %eax diff --git a/sys/kern/init_main.c b/sys/kern/init_main.c index 949dad8..55d9256 100644 --- a/sys/kern/init_main.c +++ b/sys/kern/init_main.c @@ -39,7 +39,7 @@ * SUCH DAMAGE. * * @(#)init_main.c 8.9 (Berkeley) 1/21/94 - * $Id: init_main.c,v 1.63 1997/05/29 04:52:03 peter Exp $ + * $Id: init_main.c,v 1.64 1997/06/16 00:29:30 dyson Exp $ */ #include "opt_rlimit.h" @@ -104,11 +104,7 @@ struct timeval boottime; SYSCTL_STRUCT(_kern, KERN_BOOTTIME, boottime, CTLFLAG_RW, &boottime, timeval, ""); -/* - * for SMP, the runtime variable has to be per-cpu, so we use the - * extern declaration in sys/kernel.h - */ -#ifndef SMP +#ifndef SMP /* per-cpu on smp */ struct timeval runtime; #endif diff --git a/sys/kern/init_smp.c b/sys/kern/init_smp.c index 0751f15..b972872 100644 --- a/sys/kern/init_smp.c +++ b/sys/kern/init_smp.c @@ -22,11 +22,10 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: init_smp.c,v 1.5 1997/05/04 02:08:09 peter Exp $ + * $Id: init_smp.c,v 1.6 1997/05/06 07:10:06 fsmp Exp $ */ #include "opt_smp.h" -#include "opt_smp_autostart.h" #include <sys/param.h> #include <sys/filedesc.h> @@ -145,7 +144,7 @@ smp_kickoff(dummy) #define MSG_CPU_MADEIT \ printf("SMP: TADA! CPU #%d made it into the scheduler!.\n", \ - cpunumber()) + cpuid) #define MSG_NEXT_CPU \ printf("SMP: %d of %d CPU's online. Unlocking next CPU..\n", \ smp_cpus, mp_ncpus) @@ -171,11 +170,11 @@ secondary_main() * Record our ID so we know when we've released the mp_stk. * We must remain single threaded through this. */ - cpu_starting = cpunumber(); + cpu_starting = cpuid; smp_cpus++; printf("SMP: AP CPU #%d LAUNCHED!! Starting Scheduling...\n", - cpunumber()); + cpuid); curproc = NULL; /* ensure no context to save */ cpu_switch(curproc); /* start first process */ @@ -192,6 +191,7 @@ smp_idleloop(dummy) void *dummy; { int dcnt = 0; + int apic_id; /* * This code is executed only on startup of the idleprocs @@ -202,14 +202,14 @@ void *dummy; if ( ++idle_loops == mp_ncpus ) { printf("SMP: All idle procs online.\n"); -#if defined(SMP_AUTOSTART) +#ifndef NO_AUTOSTART printf("SMP: *** AUTO *** starting 1st AP!\n"); smp_cpus = 1; smp_active = mp_ncpus; /* XXX */ boot_unlock(); #else printf("You can now activate SMP processing, use: sysctl -w kern.smp_active=%d\n", mp_ncpus); -#endif /* SMP_AUTOSTART */ +#endif } spl0(); @@ -222,38 +222,44 @@ void *dummy; */ __asm __volatile("" : : : "memory"); -#if !defined(SMP_AUTOSTART) - /* - * Alternate code to enable a lockstep startup - * via sysctl instead of automatically. - */ +#ifdef NO_AUTOSTART if (smp_cpus == 0 && smp_active != 0) { get_mplock(); printf("SMP: Starting 1st AP!\n"); smp_cpus = 1; - smp_active = mp_ncpus; /* XXX */ + smp_active = mp_ncpus; /* XXX */ boot_unlock(); rel_mplock(); } -#endif /* !SMP_AUTOSTART */ +#endif /* * If smp_active is set to (say) 1, we want cpu id's * 1,2,etc to freeze here. */ - if (smp_active && smp_active <= cpunumber()) { + if (smp_active && smp_active <= cpuid) { get_mplock(); - printf("SMP: cpu#%d freezing\n", cpunumber()); + printf("SMP: cpu#%d freezing\n", cpuid); wakeup((caddr_t)&smp_active); rel_mplock(); - while (smp_active <= cpunumber()) { + while (smp_active <= cpuid) { __asm __volatile("" : : : "memory"); } get_mplock(); - printf("SMP: cpu#%d waking up!\n", cpunumber()); + printf("SMP: cpu#%d waking up!\n", cpuid); rel_mplock(); } + +/* XXX DEBUG */ + apic_id = (apic_id_to_logical[(lapic.id & 0x0f000000) >> 24]); + if (cpuid != apic_id) { + printf("SMP: cpuid = %d\n", cpuid); + printf("SMP: apic_id = %d\n", apic_id); + printf("PTD[MPPTDI] = %08x\n", PTD[MPPTDI]); + panic("cpuid mismatch! boom!!"); + } +/* XXX END DEBUG */ if (whichqs || whichrtqs || (!ignore_idleprocs && whichidqs)) { /* grab lock for kernel "entry" */ @@ -272,7 +278,7 @@ void *dummy; microtime(&runtime); if (cpu_starting != -1 && - cpu_starting == cpunumber()) { + cpu_starting == cpuid) { /* * TADA! we have arrived! unlock the * next cpu now that we have released @@ -309,7 +315,7 @@ void *dummy; if (idle_debug && (dcnt % idle_debug) == 0) { get_mplock(); printf("idleproc pid#%d on cpu#%d, lock %08x\n", - curproc->p_pid, cpunumber(), mp_lock); + curproc->p_pid, cpuid, mp_lock); rel_mplock(); } } diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c index 33e961f..cb50acb 100644 --- a/sys/kern/kern_fork.c +++ b/sys/kern/kern_fork.c @@ -36,7 +36,7 @@ * SUCH DAMAGE. * * @(#)kern_fork.c 8.6 (Berkeley) 4/8/94 - * $Id: kern_fork.c,v 1.42 1997/05/29 04:52:04 peter Exp $ + * $Id: kern_fork.c,v 1.43 1997/06/16 00:29:30 dyson Exp $ */ #include "opt_ktrace.h" @@ -142,6 +142,19 @@ fork1(p1, flags, retval) if ((flags & (RFFDG|RFCFDG)) == (RFFDG|RFCFDG)) return (EINVAL); +#ifdef SMP + /* + * FATAL now, we cannot have the same PTD on both cpus, the PTD + * needs to move out of PTmap and be per-process, even for shared + * page table processes. Unfortunately, this means either removing + * PTD[] as a fixed virtual address, or move it to the per-cpu map + * area for SMP mode. Both cases require seperate management of + * the per-process-even-if-PTmap-is-shared PTD. + */ + if (flags & RFMEM) + return (EOPNOTSUPP); +#endif + /* * Here we don't create a new process, but we divorce * certain parts of a process from itself. diff --git a/sys/kern/kern_shutdown.c b/sys/kern/kern_shutdown.c index c7cebca..1353dbf 100644 --- a/sys/kern/kern_shutdown.c +++ b/sys/kern/kern_shutdown.c @@ -36,7 +36,7 @@ * SUCH DAMAGE. * * @(#)kern_shutdown.c 8.3 (Berkeley) 1/21/94 - * $Id: kern_shutdown.c,v 1.15 1997/05/24 18:35:44 fsmp Exp $ + * $Id: kern_shutdown.c,v 1.16 1997/06/15 02:03:03 wollman Exp $ */ #include "opt_ddb.h" @@ -61,6 +61,9 @@ #include <machine/clock.h> #include <machine/cons.h> #include <machine/md_var.h> +#ifdef SMP +#include <machine/smp.h> /* smp_active, cpuid */ +#endif #include <sys/utsname.h> #include <sys/signalvar.h> @@ -175,8 +178,8 @@ boot(howto) spins = 100; - printf("boot() called on cpu#%d\n", cpunumber()); - while ((c = cpunumber()) != 0) { + printf("boot() called on cpu#%d\n", cpuid); + while ((c = cpuid) != 0) { if (spins-- < 1) { printf("timeout waiting for cpu #0!\n"); break; @@ -383,7 +386,7 @@ panic(const char *fmt, ...) va_end(ap); printf("\n"); #ifdef SMP - printf(" cpu#%d\n", cpunumber()); + printf(" cpuid %d\n", cpuid); #endif #if defined(DDB) diff --git a/sys/kern/kern_synch.c b/sys/kern/kern_synch.c index f684c05..b6d00a5 100644 --- a/sys/kern/kern_synch.c +++ b/sys/kern/kern_synch.c @@ -36,7 +36,7 @@ * SUCH DAMAGE. * * @(#)kern_synch.c 8.9 (Berkeley) 5/19/95 - * $Id: kern_synch.c,v 1.30 1997/02/27 18:03:48 bde Exp $ + * $Id: kern_synch.c,v 1.31 1997/04/26 11:46:15 peter Exp $ */ #include "opt_ktrace.h" @@ -216,15 +216,9 @@ schedcpu(arg) resetpriority(p); if (p->p_priority >= PUSER) { #define PPQ (128 / NQS) /* priorities per queue */ -#ifdef SMP - for (j = i = 0; i < NCPU; i++) { - if (p == SMPcurproc[i]) - j++; - } - if (!j && - -#else if ((p != curproc) && +#ifdef SMP + (u_char)p->p_oncpu == 0xff && /* idle */ #endif p->p_stat == SRUN && (p->p_flag & P_INMEM) && diff --git a/sys/kern/subr_smp.c b/sys/kern/subr_smp.c index a27cf86..c817925 100644 --- a/sys/kern/subr_smp.c +++ b/sys/kern/subr_smp.c @@ -22,11 +22,10 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: mp_machdep.c,v 1.16 1997/05/29 05:58:41 fsmp Exp $ + * $Id: mp_machdep.c,v 1.17 1997/06/02 10:44:08 dfr Exp $ */ #include "opt_smp.h" -#include "opt_serial.h" #include <sys/param.h> /* for KERNBASE */ #include <sys/types.h> @@ -38,18 +37,21 @@ #include <vm/vm_param.h> /* for KERNBASE */ #include <vm/pmap.h> /* for KERNBASE */ #include <machine/pmap.h> /* for KERNBASE */ +#include <vm/vm_kern.h> +#include <vm/vm_extern.h> #include <machine/smp.h> #include <machine/apic.h> #include <machine/mpapic.h> #include <machine/cpufunc.h> #include <machine/segments.h> -#include <machine/smptests.h> /** TEST_DEFAULT_CONFIG, LATE_START */ +#include <machine/smptests.h> /** TEST_DEFAULT_CONFIG */ +#include <machine/tss.h> #include <i386/i386/cons.h> /* cngetc() */ #if defined(APIC_IO) -#include <i386/include/md_var.h> /* setidt() */ +#include <machine/md_var.h> /* setidt() */ #include <i386/isa/icu.h> /* Xinvltlb() */ #include <i386/isa/intr_machdep.h> /* Xinvltlb() */ #endif /* APIC_IO */ @@ -186,11 +188,6 @@ typedef struct BASETABLE_ENTRY { /** FIXME: what system files declare these??? */ extern struct region_descriptor r_gdt, r_idt; -/* global data */ -struct proc *SMPcurproc[NCPU]; -struct pcb *SMPcurpcb[NCPU]; -struct timeval SMPruntime[NCPU]; - int mp_ncpus; /* # of CPUs, including BSP */ int mp_naps; /* # of Applications processors */ int mp_nbusses; /* # of busses */ @@ -210,6 +207,15 @@ int cpu_num_to_apic_id[NAPICID]; int io_num_to_apic_id[NAPICID]; int apic_id_to_logical[NAPICID]; +/* Boot of AP uses this PTD */ +u_int *bootPTD; + +/* Hotwire a 0->4MB V==P mapping */ +extern pt_entry_t KPTphys; + +/* virtual address of per-cpu common_tss */ +extern struct i386tss common_tss; + /* * look for MP compliant motherboard. */ @@ -283,11 +289,6 @@ found: /* please forgive the 'goto'! */ if (mptable_pass1()) panic("you must reconfigure your kernel"); -#if defined(LATE_START) - /* create pages for (address common) cpu APIC and each IO APIC */ - pmap_bootstrap_apics(); -#endif /* LATE_START */ - /* flag fact that we are running multiple processors */ mp_capable = 1; return 1; @@ -305,9 +306,6 @@ mp_start(void) mp_enable(boot_address); else panic("MP hardware not found!"); - - /* finish pmap initialization - turn off V==P mapping at zero */ - pmap_bootstrap2(); } @@ -321,23 +319,25 @@ mp_announce(void) printf("FreeBSD/SMP: Multiprocessor motherboard\n"); printf(" cpu0 (BSP): apic id: %d", CPU_TO_ID(0)); - printf(", version: 0x%08x\n", cpu_apic_versions[0]); + printf(", version: 0x%08x", cpu_apic_versions[0]); + printf(", at 0x%08x\n", cpu_apic_address); for (x = 1; x <= mp_naps; ++x) { printf(" cpu%d (AP): apic id: %d", x, CPU_TO_ID(x)); - printf(", version: 0x%08x\n", cpu_apic_versions[x]); + printf(", version: 0x%08x", cpu_apic_versions[x]); + printf(", at 0x%08x\n", cpu_apic_address); } #if defined(APIC_IO) for (x = 0; x < mp_napics; ++x) { printf(" io%d (APIC): apic id: %d", x, IO_TO_ID(x)); - printf(", version: 0x%08x\n", io_apic_versions[x]); + printf(", version: 0x%08x", io_apic_versions[x]); + printf(", at 0x%08x\n", io_apic_address[x]); } #else printf(" Warning: APIC I/O disabled\n"); #endif /* APIC_IO */ } - /* * AP cpu's call this to sync up protected mode. */ @@ -352,12 +352,18 @@ init_secondary(void) lidt(&r_idt); lldt(_default_ldt); - slot = NGDT + cpunumber(); + slot = NGDT + cpuid; gsel_tss = GSEL(slot, SEL_KPL); gdt[slot].sd.sd_type = SDT_SYS386TSS; + common_tss.tss_esp0 = 0; /* not used until after switch */ + common_tss.tss_ss0 = GSEL(GDATA_SEL, SEL_KPL); + common_tss.tss_ioopt = (sizeof common_tss) << 16; ltr(gsel_tss); load_cr0(0x8005003b); /* XXX! */ + + PTD[0] = 0; + invltlb(); } @@ -375,9 +381,9 @@ configure_local_apic(void) outb(0x23, byte); /* disconnect 8259s/NMI */ } /* mask the LVT1 */ - temp = lapic__lvt_lint0; + temp = lapic.lvt_lint0; temp |= APIC_LVT_M; - lapic__lvt_lint0 = temp; + lapic.lvt_lint0 = temp; } #endif /* APIC_IO */ @@ -398,13 +404,15 @@ mp_enable(u_int boot_addr) u_int ux; #endif /* APIC_IO */ - /* examine the MP table for needed info */ + /* Turn on 4MB of V == P addressing so we can get to MP table */ + *(int *)PTD = PG_V | PG_RW | ((u_long)KPTphys & PG_FRAME); + invltlb(); + + /* examine the MP table for needed info, uses physical addresses */ x = mptable_pass2(); -#if !defined(LATE_START) - /* create pages for (address common) cpu APIC and each IO APIC */ - pmap_bootstrap_apics(); -#endif /* LATE_START */ + *(int *)PTD = 0; + invltlb(); /* can't process default configs till the CPU APIC is pmapped */ if (x) @@ -832,7 +840,7 @@ fix_mp_table(void) for (x = 0; x < mp_nbusses; ++x) { if (bus_data[x].bus_type != PCI) continue; - if (bus_data[x].bus_id >= num_pci_bus ) + if (bus_data[x].bus_id >= num_pci_bus) panic("bad PCI bus numbering"); } } @@ -1258,7 +1266,7 @@ default_mp_table(int type) } #endif /* 0 */ - boot_cpu_id = (lapic__id & APIC_ID_MASK) >> 24; + boot_cpu_id = (lapic.id & APIC_ID_MASK) >> 24; ap_cpu_id = (boot_cpu_id == 0) ? 1 : 0; /* BSP */ @@ -1351,9 +1359,12 @@ default_mp_table(int type) static int start_all_aps(u_int boot_addr) { - int x; + int x, i; u_char mpbiosreason; u_long mpbioswarmvec; + pd_entry_t newptd; + pt_entry_t newpt; + int *newpp; /** * NOTE: this needs further thought: @@ -1362,7 +1373,7 @@ start_all_aps(u_int boot_addr) * * get the initial mp_lock with a count of 1 for the BSP */ - mp_lock = (lapic__id & APIC_ID_MASK) + 1; + mp_lock = (lapic.id & APIC_ID_MASK) + 1; /* initialize BSP's local APIC */ apic_initialize(1); @@ -1370,6 +1381,7 @@ start_all_aps(u_int boot_addr) /* install the AP 1st level boot code */ install_ap_tramp(boot_addr); + /* save the current value of the warm-start vector */ mpbioswarmvec = *((u_long *) WARMBOOT_OFF); outb(CMOS_REG, BIOS_RESET); @@ -1378,6 +1390,58 @@ start_all_aps(u_int boot_addr) /* start each AP */ for (x = 1; x <= mp_naps; ++x) { + /* HACK HACK HACK !!! */ + + /* alloc new page table directory */ + newptd = (pd_entry_t)(kmem_alloc(kernel_map, PAGE_SIZE)); + + /* clone currently active one (ie: IdlePTD) */ + bcopy(PTD, newptd, PAGE_SIZE); /* inc prv page pde */ + + /* set up 0 -> 4MB P==V mapping for AP boot */ + newptd[0] = PG_V | PG_RW | ((u_long)KPTphys & PG_FRAME); + + /* store PTD for this AP */ + bootPTD = (pd_entry_t)vtophys(newptd); + + /* alloc new page table page */ + newpt = (pt_entry_t)(kmem_alloc(kernel_map, PAGE_SIZE)); + + /* set the new PTD's private page to point there */ + newptd[MPPTDI] = PG_V | PG_RW | vtophys(newpt); + + /* install self referential entry */ + newptd[PTDPTDI] = PG_V | PG_RW | vtophys(newptd); + + /* get a new private data page */ + newpp = (int *)kmem_alloc(kernel_map, PAGE_SIZE); + + /* wire it into the private page table page */ + newpt[0] = PG_V | PG_RW | vtophys(newpp); + + /* wire the ptp into itself for access */ + newpt[1] = PG_V | PG_RW | vtophys(newpt); + + /* and the local apic */ + newpt[2] = SMP_prvpt[2]; + + /* and the IO apic mapping[s] */ + for (i = 16; i < 32; i++) + newpt[i] = SMP_prvpt[i]; + + /* prime data page for it to use */ + newpp[0] = x; /* cpuid */ + newpp[1] = 0; /* curproc */ + newpp[2] = 0; /* curpcb */ + newpp[3] = 0; /* npxproc */ + newpp[4] = 0; /* runtime.tv_sec */ + newpp[5] = 0; /* runtime.tv_usec */ + newpp[6] = x << 24; /* cpu_lockid */ + + /* XXX NOTE: ABANDON bootPTD for now!!!! */ + + /* END REVOLTING HACKERY */ + /* setup a vector to our boot code */ *((volatile u_short *) WARMBOOT_OFF) = WARMBOOT_TARGET; *((volatile u_short *) WARMBOOT_SEG) = (boot_addr >> 4); @@ -1401,7 +1465,7 @@ start_all_aps(u_int boot_addr) } /* fill in our (BSP) APIC version */ - cpu_apic_versions[0] = lapic__version; + cpu_apic_versions[0] = lapic.version; /* restore the warmstart vector */ *(u_long *) WARMBOOT_OFF = mpbioswarmvec; @@ -1503,24 +1567,24 @@ start_ap(int logical_cpu, u_int boot_addr) */ /* setup the address for the target AP */ - icr_hi = lapic__icr_hi & ~APIC_ID_MASK; + icr_hi = lapic.icr_hi & ~APIC_ID_MASK; icr_hi |= (physical_cpu << 24); - lapic__icr_hi = icr_hi; + lapic.icr_hi = icr_hi; /* do an INIT IPI: assert RESET */ - icr_lo = lapic__icr_lo & 0xfff00000; - lapic__icr_lo = icr_lo | 0x0000c500; + icr_lo = lapic.icr_lo & 0xfff00000; + lapic.icr_lo = icr_lo | 0x0000c500; /* wait for pending status end */ - while (lapic__icr_lo & APIC_DELSTAT_MASK) + while (lapic.icr_lo & APIC_DELSTAT_MASK) /* spin */ ; /* do an INIT IPI: deassert RESET */ - lapic__icr_lo = icr_lo | 0x00008500; + lapic.icr_lo = icr_lo | 0x00008500; /* wait for pending status end */ u_sleep(10000); /* wait ~10mS */ - while (lapic__icr_lo & APIC_DELSTAT_MASK) + while (lapic.icr_lo & APIC_DELSTAT_MASK) /* spin */ ; /* @@ -1533,8 +1597,8 @@ start_ap(int logical_cpu, u_int boot_addr) */ /* do a STARTUP IPI */ - lapic__icr_lo = icr_lo | 0x00000600 | vector; - while (lapic__icr_lo & APIC_DELSTAT_MASK) + lapic.icr_lo = icr_lo | 0x00000600 | vector; + while (lapic.icr_lo & APIC_DELSTAT_MASK) /* spin */ ; u_sleep(200); /* wait ~200uS */ @@ -1545,8 +1609,8 @@ start_ap(int logical_cpu, u_int boot_addr) * recognized after hardware RESET or INIT IPI. */ - lapic__icr_lo = icr_lo | 0x00000600 | vector; - while (lapic__icr_lo & APIC_DELSTAT_MASK) + lapic.icr_lo = icr_lo | 0x00000600 | vector; + while (lapic.icr_lo & APIC_DELSTAT_MASK) /* spin */ ; u_sleep(200); /* wait ~200uS */ diff --git a/sys/kern/subr_trap.c b/sys/kern/subr_trap.c index 89dd34f..8914a5b 100644 --- a/sys/kern/subr_trap.c +++ b/sys/kern/subr_trap.c @@ -35,7 +35,7 @@ * SUCH DAMAGE. * * from: @(#)trap.c 7.4 (Berkeley) 5/13/91 - * $Id: trap.c,v 1.98 1997/06/02 08:19:03 dfr Exp $ + * $Id: trap.c,v 1.99 1997/06/07 04:36:10 bde Exp $ */ /* @@ -87,11 +87,7 @@ #include "isa.h" #include "npx.h" -#ifdef SMP -extern struct i386tss *SMPcommon_tss_ptr[]; -#else extern struct i386tss common_tss; -#endif int (*pmath_emulate) __P((struct trapframe *)); @@ -704,7 +700,7 @@ trap_fatal(frame) type, trap_msg[type], ISPL(frame->tf_cs) == SEL_UPL ? "user" : "kernel"); #ifdef SMP - printf("cpunumber = %d\n", cpunumber()); + printf("cpuid = %d\n", cpuid); #endif if (type == T_PAGEFLT) { printf("fault virtual address = 0x%x\n", eva); @@ -790,19 +786,12 @@ trap_fatal(frame) void dblfault_handler() { -#ifdef SMP - int x = cpunumber(); -#endif - printf("\nFatal double fault:\n"); -#ifdef SMP - printf("eip = 0x%x\n", SMPcommon_tss_ptr[x]->tss_eip); - printf("esp = 0x%x\n", SMPcommon_tss_ptr[x]->tss_esp); - printf("ebp = 0x%x\n", SMPcommon_tss_ptr[x]->tss_ebp); -#else printf("eip = 0x%x\n", common_tss.tss_eip); printf("esp = 0x%x\n", common_tss.tss_esp); printf("ebp = 0x%x\n", common_tss.tss_ebp); +#ifdef SMP + printf("cpuid = %d\n", cpuid); #endif panic("double fault"); } diff --git a/sys/sys/kernel.h b/sys/sys/kernel.h index bc50603..1ca4485 100644 --- a/sys/sys/kernel.h +++ b/sys/sys/kernel.h @@ -39,7 +39,7 @@ * SUCH DAMAGE. * * @(#)kernel.h 8.3 (Berkeley) 1/21/94 - * $Id: kernel.h,v 1.30 1997/05/07 19:43:28 peter Exp $ + * $Id: kernel.h,v 1.31 1997/05/29 04:50:23 peter Exp $ */ #ifndef _SYS_KERNEL_H_ @@ -47,10 +47,6 @@ #ifdef KERNEL -#ifdef SMP -#include <machine/smp.h> -#endif - /* Global variables for the kernel. */ /* 1.1 */ @@ -64,12 +60,7 @@ extern char kernelname[MAXPATHLEN]; /* 1.2 */ extern volatile struct timeval mono_time; extern struct timeval boottime; -#ifdef SMP -extern struct timeval SMPruntime[]; -#define runtime (SMPruntime[cpunumber()]) -#else /* !SMP */ extern struct timeval runtime; -#endif /* SMP */ extern struct timeval time; /* nonvolatile at ipl >= splclock() */ extern struct timezone tz; /* XXX */ diff --git a/sys/sys/proc.h b/sys/sys/proc.h index 2c18e4e..684959b 100644 --- a/sys/sys/proc.h +++ b/sys/sys/proc.h @@ -36,16 +36,13 @@ * SUCH DAMAGE. * * @(#)proc.h 8.15 (Berkeley) 5/19/95 - * $Id: proc.h,v 1.39 1997/06/01 08:49:49 peter Exp $ + * $Id: proc.h,v 1.40 1997/06/16 00:29:25 dyson Exp $ */ #ifndef _SYS_PROC_H_ #define _SYS_PROC_H_ #include <machine/proc.h> /* Machine-dependent proc substruct. */ -#if defined(KERNEL) && defined(SMP) -#include <machine/smp.h> /* cpunumber() */ -#endif #include <sys/rtprio.h> /* For struct rtprio. */ #include <sys/select.h> /* For struct selinfo. */ #include <sys/time.h> /* For structs itimerval, timeval. */ @@ -273,13 +270,7 @@ extern u_long pidhash; extern LIST_HEAD(pgrphashhead, pgrp) *pgrphashtbl; extern u_long pgrphash; -#ifdef SMP -extern struct proc *SMPcurproc[]; /* Current running proc. */ -#define curproc (SMPcurproc[cpunumber()]) -#else /* !SMP */ extern struct proc *curproc; /* Current running proc. */ -#endif /* SMP */ - extern struct proc proc0; /* Process slot for swapper. */ extern int nprocs, maxproc; /* Current and max number of procs. */ extern int maxprocperuid; /* Max procs per uid. */ diff --git a/sys/sys/smp.h b/sys/sys/smp.h index ee96269..2943764 100644 --- a/sys/sys/smp.h +++ b/sys/sys/smp.h @@ -6,7 +6,7 @@ * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp * ---------------------------------------------------------------------------- * - * $Id: smp.h,v 1.9 1997/05/28 18:44:11 fsmp Exp $ + * $Id: smp.h,v 1.10 1997/05/29 05:57:43 fsmp Exp $ * */ @@ -56,6 +56,8 @@ extern u_int32_t io_apic_versions[]; extern int cpu_num_to_apic_id[]; extern int io_num_to_apic_id[]; extern int apic_id_to_logical[]; +extern u_int SMP_prvpt[]; +extern u_char SMP_ioapic[]; /* functions in mp_machdep.c */ u_int mp_bootaddress __P((u_int)); @@ -79,18 +81,12 @@ void init_secondary __P((void)); void smp_invltlb __P((void)); /* global data in mpapic.c */ -extern volatile u_int* apic_base; -#if 1 /** XXX APIC_STRUCT */ -extern volatile lapic_t* lapic; -#endif /** XXX APIC_STRUCT */ +extern volatile lapic_t lapic; #if defined(MULTIPLE_IOAPICS) #error MULTIPLE_IOAPICSXXX #else -extern volatile u_int* io_apic_base; -#if 1 /** XXX APIC_STRUCT */ -extern volatile ioapic_t* ioapic; -#endif /** XXX APIC_STRUCT */ +extern volatile ioapic_t *ioapic[]; #endif /* MULTIPLE_IOAPICS */ /* functions in mpapic.c */ @@ -114,32 +110,8 @@ void u_sleep __P((int)); extern int smp_active; extern int invltlb_ok; -/* in pmap.c FIXME: belongs in pmap.h??? */ -void pmap_bootstrap_apics __P((void)); -void pmap_bootstrap2 __P((void)); - -#if 0 -/* chicken and egg problem... */ -static __inline unsigned -cpunumber(void) -{ - return (unsigned)ID_TO_CPU((apic_base[APIC_ID] & APIC_ID_MASK) >> 24); -} -#else -/* - * we 'borrow' this info from apic.h - * this will go away soon... - */ -static __inline unsigned -cpunumber(void) -{ -#if 0 - return (unsigned)(apic_id_to_logical[(apic_base[8] & 0x0f000000) >> 24]); -#else - return (unsigned)(apic_id_to_logical[(lapic__id & 0x0f000000) >> 24]); -#endif -} -#endif /* 0 */ +extern volatile u_int cpuid; +extern volatile u_int cpu_lockid; #endif /* SMP || APIC_IO */ #endif /* KERNEL */ |