Preliminary support for per-cpu data pages.
This eliminates a lot of #ifdef SMP type code. Things like _curproc reside in a data page that is unique on each cpu, eliminating the expensive macros like: #define curproc (SMPcurproc[cpunumber()]) There are some unresolved bootstrap and address space sharing issues at present, but Steve is waiting on this for other work. There is still some strictly temporary code present that isn't exactly pretty. This is part of a larger change that has run into some bumps, this part is standalone so it should be safe. The temporary code goes away when the full idle cpu support is finished. Reviewed by: fsmp, dyson
This commit is contained in:
parent
3b18caba29
commit
b3196e4b9f
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=26812
@ -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
|
||||
|
||||
|
@ -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: .asciz "cpu_switch"
|
||||
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_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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
movl $1, %ecx /* one private pt coming right up */
|
||||
fillkpt(R(cpu0pt), $PG_RW)
|
||||
|
||||
/* 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)
|
||||
|
||||
/* ... 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
|
||||
|
@ -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)
|
||||
movl $1, %ecx /* one private pt coming right up */
|
||||
fillkpt(R(cpu0pt), $PG_RW)
|
||||
|
||||
/* 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)
|
||||
|
||||
/* ... 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
|
||||
|
@ -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 @@ cpu_startup(dummy)
|
||||
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
|
||||
|
@ -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 @@ mp_probe(void)
|
||||
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 */
|
||||
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -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 @@ mp_probe(void)
|
||||
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 */
|
||||
|
||||
|
@ -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 @@ pmap_pinit(pmap)
|
||||
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);
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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: .asciz "cpu_switch"
|
||||
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_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
|
||||
|
||||
|
@ -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");
|
||||
}
|
||||
|
@ -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));
|
||||
|
@ -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_ */
|
||||
|
@ -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));
|
||||
|
@ -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 @@ mp_probe(void)
|
||||
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 */
|
||||
|
||||
|
@ -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));
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
/*
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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:
|
||||
#
|
||||
|
@ -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
|
||||
|
@ -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:
|
||||
#
|
||||
|
@ -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:
|
||||
#
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
movl $1, %ecx /* one private pt coming right up */
|
||||
fillkpt(R(cpu0pt), $PG_RW)
|
||||
|
||||
/* 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)
|
||||
|
||||
/* ... 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
|
||||
|
@ -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 @@ cpu_startup(dummy)
|
||||
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
|
||||
|
@ -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 */
|
||||
|
85
sys/i386/i386/mp_apicdefs.s
Normal file
85
sys/i386/i386/mp_apicdefs.s
Normal file
@ -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
|
@ -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 @@ mp_probe(void)
|
||||
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 */
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -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 */
|
||||
|
@ -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 @@ mp_probe(void)
|
||||
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 */
|
||||
|
||||
|
@ -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 @@ pmap_pinit(pmap)
|
||||
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);
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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: .asciz "cpu_switch"
|
||||
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_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
|
||||
|
||||
|
@ -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");
|
||||
}
|
||||
|
@ -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));
|
||||
|
@ -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_ */
|
||||
|
@ -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_ */
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -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 @@ mp_probe(void)
|
||||
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 */
|
||||
|
||||
|
@ -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));
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
/*
|
||||
|
@ -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 */
|
||||
|
@ -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__ */
|
@ -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
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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.
|
||||
|
@ -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)
|
||||
|
@ -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) &&
|
||||
|
@ -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 @@ mp_probe(void)
|
||||
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 */
|
||||
|
||||
|
@ -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");
|
||||
}
|
||||
|
@ -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 */
|
||||
|
@ -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. */
|
||||
|
@ -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 */
|
||||
|
Loading…
Reference in New Issue
Block a user