Further SMP work (associate an idle thread with each processor)

svn path=/trunk/; revision=1808
This commit is contained in:
David Welch 2001-04-17 04:11:01 +00:00
parent 2cfadf3b41
commit f29036d97b
15 changed files with 235 additions and 94 deletions

View file

@ -176,17 +176,17 @@ KfLowerIrql (
CurrentIrql = KeGetCurrentKPCR()->Irql;
if (NewIrql > CurrentIrql)
{
DbgPrint ("(%s:%d) NewIrql %x CurrentIrql %x\n",
__FILE__, __LINE__, NewIrql, CurrentIrql);
KeDumpStackFrames (0, 32);
for(;;);
}
OldIrql = CurrentIrql;
if (NewIrql > CurrentIrql)
{
DbgPrint ("(%s:%d) NewIrql %x CurrentIrql %x\n",
__FILE__, __LINE__, NewIrql, CurrentIrql);
KeBugCheck(0);
for(;;);
}
OldIrql = CurrentIrql;
KeGetCurrentKPCR()->Irql = NewIrql;
HiSwitchIrql(OldIrql, Flags);
HiSwitchIrql(OldIrql, Flags);
}
@ -240,7 +240,7 @@ KfRaiseIrql (
)
{
KIRQL CurrentIrql;
KIRQL OldIrql;
KIRQL OldIrql;
ULONG Flags;
//DPRINT("KfRaiseIrql(NewIrql %d)\n", NewIrql);

View file

@ -148,7 +148,7 @@ VOID KeExpireTimers( PKDPC Apc,
VOID KeInitializeDispatcherHeader(DISPATCHER_HEADER* Header, ULONG Type,
ULONG Size, ULONG SignalState);
VOID KeDumpStackFrames(PVOID Stack, ULONG NrFrames);
VOID KeDumpStackFrames(PULONG Frame);
ULONG KeAllocateGdtSelector(ULONG Desc[2]);
VOID KeFreeGdtSelector(ULONG Entry);
BOOLEAN KiTestAlert(VOID);
@ -199,6 +199,12 @@ VOID
Ki386ApplicationProcessorInitializeTSS(VOID);
VOID
Ki386BootInitializeTSS(VOID);
VOID
KiGdtPrepareForApplicationProcessorInit(ULONG Id);
VOID
KePrepareForApplicationProcessorInit(ULONG id);
VOID
Ki386InitializeLdt(VOID);
#endif /* not __ASM__ */

View file

@ -462,4 +462,9 @@ MmGetSavedSwapEntryPage(PVOID PhysicalAddress);
#define STATUS_MM_RESTART_OPERATION (0xD0000001)
NTSTATUS
MmCreateVirtualMappingForKernel(PVOID Address,
ULONG flProtect,
ULONG PhysicalAddress);
#endif

View file

@ -555,6 +555,12 @@ PsBlockThread(PNTSTATUS Status, UCHAR Alertable, ULONG WaitMode,
BOOLEAN DispatcherLock, KIRQL WaitIrql);
VOID
PsUnblockThread(PETHREAD Thread, PNTSTATUS WaitStatus);
VOID
PsApplicationProcessorInit(VOID);
VOID
PsPrepareForApplicationProcessorInit(ULONG Id);
NTSTATUS
PsIdleThreadMain(PVOID Context);
#endif /* ASSEMBLER */

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: bug.c,v 1.17 2001/03/16 23:04:59 dwelch Exp $
/* $Id: bug.c,v 1.18 2001/04/17 04:11:00 dwelch Exp $
*
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/ke/bug.c
@ -105,7 +105,7 @@ KeBugCheckEx (ULONG BugCheckCode,
PsGetCurrentThread()->Cid.UniqueThread);
}
// PsDumpThreads();
KeDumpStackFrames(&((&BugCheckCode)[-1]),64);
KeDumpStackFrames((PULONG)__builtin_frame_address(0));
#if 1
for(;;)
@ -148,7 +148,7 @@ KeBugCheck (ULONG BugCheckCode)
PsGetCurrentThread()->Cid.UniqueThread);
}
// PsDumpThreads();
KeDumpStackFrames(&((&BugCheckCode)[-1]), 80);
KeDumpStackFrames((PULONG)__builtin_frame_address(0));
#if 1
for(;;)
{

View file

@ -71,8 +71,6 @@ extern VOID KiTrapUnknown(VOID);
extern ULONG init_stack;
extern ULONG init_stack_top;
static char KiNullLdt[8] = {0,};
static char *ExceptionTypeStrings[] =
{
"Divide Error",
@ -595,43 +593,22 @@ KiTrapHandler(PKTRAP_FRAME Tf, ULONG ExceptionNr)
}
VOID
KeDumpStackFrames(PVOID _Stack, ULONG NrFrames)
KeDumpStackFrames(PULONG Frame)
{
PULONG Stack = (PULONG)_Stack;
ULONG i;
ULONG StackLimit;
Stack = (PVOID)(((ULONG)Stack) & (~0x3));
DbgPrint("Stack: %x\n", Stack);
if (PsGetCurrentThread() != NULL)
{
DbgPrint("kernel stack base %x\n",
PsGetCurrentThread()->Tcb.StackLimit);
}
ULONG i;
if (PsGetCurrentThread() != NULL)
{
StackLimit = (ULONG)PsGetCurrentThread()->Tcb.StackBase;
}
else
{
StackLimit = (ULONG)&init_stack_top;
}
DbgPrint("Frames:\n");
for (i=0; i<NrFrames && ((ULONG)&Stack[i] < StackLimit); i++)
{
if (Stack[i] > KERNEL_BASE)
{
print_address((PVOID)Stack[i]);
DbgPrint(" ");
}
if (Stack[i] == 0xceafbeef)
{
DbgPrint("IRQ ");
}
}
DbgPrint("\n");
DbgPrint("Frames: ");
i = 1;
while (Frame != NULL)
{
print_address((PVOID)Frame[1]);
Frame = (PULONG)Frame[0];
i++;
}
if ((i % 8) != 0)
{
DbgPrint("\n");
}
}
static void set_system_call_gate(unsigned int sel, unsigned int func)
@ -658,29 +635,15 @@ set_task_gate(unsigned int sel, unsigned task_sel)
KiIdt[sel].b = 0x8500;
}
void KeInitExceptions(void)
VOID
KeInitExceptions(VOID)
/*
* FUNCTION: Initalize CPU exception handling
*/
{
int i;
ULONG base, length;
extern USHORT KiBootGdt[];
DPRINT("KeInitExceptions()\n",0);
/*
* Set up an a descriptor for the LDT
*/
memset(KiNullLdt, 0, sizeof(KiNullLdt));
base = (unsigned int)&KiNullLdt;
length = sizeof(KiNullLdt) - 1;
KiBootGdt[(LDT_SELECTOR / 2) + 0] = (length & 0xFFFF);
KiBootGdt[(LDT_SELECTOR / 2) + 1] = (base & 0xFFFF);
KiBootGdt[(LDT_SELECTOR / 2) + 2] = ((base & 0xFF0000) >> 16) | 0x8200;
KiBootGdt[(LDT_SELECTOR / 2) + 3] = ((length & 0xF0000) >> 16) |
((base & 0xFF000000) >> 16);
DPRINT("KeInitExceptions()\n");
/*
* Set up the other gates

View file

@ -64,6 +64,12 @@ static KSPIN_LOCK GdtLock;
/* FUNCTIONS *****************************************************************/
VOID
KiGdtPrepareForApplicationProcessorInit(ULONG Id)
{
KiGdtArray[Id] = ExAllocatePool(NonPagedPool, sizeof(USHORT) * 4 * 11);
}
VOID
KiInitializeGdt(PKPCR Pcr)
{
@ -85,9 +91,10 @@ KiInitializeGdt(PKPCR Pcr)
/*
* Allocate a GDT
*/
Gdt = ExAllocatePool(NonPagedPool, sizeof(USHORT) * 4 * 11);
Gdt = KiGdtArray[Pcr->ProcessorNumber];
if (Gdt == NULL)
{
DbgPrint("No GDT (%d)\n", Pcr->ProcessorNumber);
KeBugCheck(0);
}
@ -98,7 +105,6 @@ KiInitializeGdt(PKPCR Pcr)
* irrelevant.
*/
memcpy(Gdt, KiBootGdt, sizeof(USHORT) * 4 * 11);
KiGdtArray[Pcr->ProcessorNumber] = Gdt;
Pcr->GDT = Gdt;
/*
@ -143,6 +149,7 @@ KeSetBaseGdtSelector(ULONG Entry,
PVOID Base)
{
KIRQL oldIrql;
PUSHORT Gdt = KeGetCurrentKPCR()->GDT;
DPRINT("KeSetBaseGdtSelector(Entry %x, Base %x)\n",
Entry, Base);
@ -151,14 +158,14 @@ KeSetBaseGdtSelector(ULONG Entry,
Entry = (Entry & (~0x3)) / 2;
KiBootGdt[Entry + 1] = ((ULONG)Base) & 0xffff;
Gdt[Entry + 1] = ((ULONG)Base) & 0xffff;
KiBootGdt[Entry + 2] = KiBootGdt[Entry + 2] & ~(0xff);
KiBootGdt[Entry + 2] = KiBootGdt[Entry + 2] |
Gdt[Entry + 2] = Gdt[Entry + 2] & ~(0xff);
Gdt[Entry + 2] = Gdt[Entry + 2] |
((((ULONG)Base) & 0xff0000) >> 16);
KiBootGdt[Entry + 3] = KiBootGdt[Entry + 3] & ~(0xff00);
KiBootGdt[Entry + 3] = KiBootGdt[Entry + 3] |
Gdt[Entry + 3] = Gdt[Entry + 3] & ~(0xff00);
Gdt[Entry + 3] = Gdt[Entry + 3] |
((((ULONG)Base) & 0xff000000) >> 16);
DPRINT("%x %x %x %x\n",

View file

@ -40,11 +40,19 @@
ULONG KiPcrInitDone = 0;
static ULONG PcrsAllocated = 0;
static PVOID PcrPages[MAXIMUM_PROCESSORS];
/* FUNCTIONS *****************************************************************/
VOID
KeApplicationProcessorInit()
KePrepareForApplicationProcessorInit(ULONG Id)
{
PcrPages[Id] = MmAllocPage(0);
KiGdtPrepareForApplicationProcessorInit(Id);
}
VOID
KeApplicationProcessorInit(VOID)
{
PKPCR KPCR;
ULONG Offset;
@ -52,12 +60,11 @@ KeApplicationProcessorInit()
/*
* Create a PCR for this processor
*/
Offset = InterlockedIncrement(&PcrsAllocated);
Offset = InterlockedIncrement(&PcrsAllocated) - 1;
KPCR = (PKPCR)(KPCR_BASE + (Offset * PAGESIZE));
MmCreateVirtualMapping(NULL,
(PVOID)KPCR,
PAGE_READWRITE,
(ULONG)MmAllocPage(0));
MmCreateVirtualMappingForKernel((PVOID)KPCR,
PAGE_READWRITE,
(ULONG)PcrPages[Offset]);
memset(KPCR, 0, PAGESIZE);
KPCR->ProcessorNumber = Offset;
KPCR->Self = KPCR;
@ -67,11 +74,21 @@ KeApplicationProcessorInit()
* Initialize the GDT
*/
KiInitializeGdt(KPCR);
/*
* It is now safe to process interrupts
*/
KeLowerIrql(DISPATCH_LEVEL);
/*
* Initialize the TSS
*/
Ki386ApplicationProcessorInitializeTSS();
/*
* Initialize a default LDT
*/
Ki386InitializeLdt();
}
VOID
@ -103,6 +120,8 @@ KeInit1(VOID)
KPCR->ProcessorNumber = 0;
KiPcrInitDone = 1;
PcrsAllocated++;
Ki386InitializeLdt();
}
VOID

View file

@ -38,9 +38,9 @@
/* GLOBALS *******************************************************************/
/*
*
* Empty LDT shared by every process that doesn't have its own.
*/
//STATIC UCHAR KiNullLdt[8] = {0,};
STATIC UCHAR KiNullLdt[8];
/* FUNCTIONS *****************************************************************/
@ -52,3 +52,21 @@ NtSetLdtEntries (HANDLE Thread,
return(STATUS_NOT_IMPLEMENTED);
}
VOID
Ki386InitializeLdt(VOID)
{
PUSHORT Gdt = KeGetCurrentKPCR()->GDT;
unsigned int base, length;
/*
* Set up an a descriptor for the LDT
*/
base = (unsigned int)&KiNullLdt;
length = sizeof(KiNullLdt) - 1;
Gdt[(LDT_SELECTOR / 2) + 0] = (length & 0xFFFF);
Gdt[(LDT_SELECTOR / 2) + 1] = (base & 0xFFFF);
Gdt[(LDT_SELECTOR / 2) + 2] = ((base & 0xFF0000) >> 16) | 0x8200;
Gdt[(LDT_SELECTOR / 2) + 3] = ((length & 0xF0000) >> 16) |
((base & 0xFF000000) >> 16);
}

View file

@ -210,7 +210,7 @@ _multiboot_entry:
movl %eax, %es
movl %eax, %gs
movl %eax, %ss
movl $PCR_SELECTOR, %eax
movl $0, %eax
movl %eax, %fs
#ifdef MP
@ -253,6 +253,12 @@ _multiboot_entry:
#endif /* MP */
/*
* Load the PCR selector
*/
movl $PCR_SELECTOR, %eax
movl %eax, %fs
/*
* Load the initial kernel stack
*/

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: main.c,v 1.91 2001/04/16 23:29:54 dwelch Exp $
/* $Id: main.c,v 1.92 2001/04/17 04:11:00 dwelch Exp $
*
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/ke/main.c
@ -455,6 +455,8 @@ ExpInitializeExecutive(VOID)
while (!HalAllProcessorsStarted())
{
KePrepareForApplicationProcessorInit(KeNumberProcessors);
PsPrepareForApplicationProcessorInit(KeNumberProcessors);
HalInitializeProcessor(KeNumberProcessors);
KeNumberProcessors++;
}
@ -577,6 +579,10 @@ KiSystemStartup(BOOLEAN BootProcessor)
}
/* Do application processor initialization */
KeApplicationProcessorInit();
PsApplicationProcessorInit();
KeLowerIrql(PASSIVE_LEVEL);
PsIdleThreadMain(NULL);
KeBugCheck(0);
for(;;);
}

View file

@ -1,4 +1,4 @@
/* $Id: spinlock.c,v 1.6 2000/12/26 05:32:44 dwelch Exp $
/* $Id: spinlock.c,v 1.7 2001/04/17 04:11:01 dwelch Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -17,6 +17,7 @@
/* INCLUDES ****************************************************************/
#include <ddk/ntddk.h>
#include <internal/config.h>
#include <internal/debug.h>
@ -81,8 +82,12 @@ KeAcquireSpinLockAtDpcLevel (PKSPIN_LOCK SpinLock)
while ((i = InterlockedExchange(&SpinLock->Lock, 1)) == 1)
{
DbgPrint("Spinning on spinlock %x current value %x\n", SpinLock, i);
KeBugCheck(0);
#ifndef MP
DbgPrint("Spinning on spinlock %x current value %x\n", SpinLock, i);
KeBugCheck(0);
#else /* not MP */
/* Avoid reading the value again too fast */
#endif /* MP */
}
}

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: page.c,v 1.28 2001/04/16 23:29:55 dwelch Exp $
/* $Id: page.c,v 1.29 2001/04/17 04:11:01 dwelch Exp $
*
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/mm/i386/page.c
@ -583,6 +583,75 @@ BOOLEAN MmIsPagePresent(PEPROCESS Process, PVOID Address)
return((MmGetPageEntryForProcess1(Process, Address)) & PA_PRESENT);
}
NTSTATUS
MmCreateVirtualMappingForKernel(PVOID Address,
ULONG flProtect,
ULONG PhysicalAddress)
{
PEPROCESS CurrentProcess;
ULONG Attributes;
PULONG Pte;
NTSTATUS Status;
PEPROCESS Process = NULL;
if (Process != NULL)
{
CurrentProcess = PsGetCurrentProcess();
}
else
{
CurrentProcess = NULL;
}
if (Process == NULL && Address < (PVOID)KERNEL_BASE)
{
DPRINT1("No process\n");
KeBugCheck(0);
}
if (Process != NULL && Address >= (PVOID)KERNEL_BASE)
{
DPRINT1("Setting kernel address with process context\n");
KeBugCheck(0);
}
Attributes = ProtectToPTE(flProtect);
if (Process != NULL && Process != CurrentProcess)
{
KeAttachProcess(Process);
}
Status = MmGetPageEntry2(Address, &Pte);
if (!NT_SUCCESS(Status))
{
if (Process != NULL && Process != CurrentProcess)
{
KeDetachProcess();
}
return(Status);
}
if (PAGE_MASK((*Pte)) != 0)
{
}
*Pte = PhysicalAddress | Attributes;
if (Process != NULL &&
Process->AddressSpace.PageTableRefCountTable != NULL &&
ADDR_TO_PAGE_TABLE(Address) < 768 &&
Attributes & PA_PRESENT)
{
PUSHORT Ptrc;
Ptrc = Process->AddressSpace.PageTableRefCountTable;
Ptrc[ADDR_TO_PAGE_TABLE(Address)]++;
}
FLUSH_TLB;
if (Process != NULL && Process != CurrentProcess)
{
KeDetachProcess();
}
return(STATUS_SUCCESS);
}
NTSTATUS
MmCreateVirtualMappingUnsafe(PEPROCESS Process,
PVOID Address,

View file

@ -25,7 +25,8 @@ PETHREAD PiIdleThread;
/* FUNCTIONS *****************************************************************/
static NTSTATUS PsIdleThreadMain(PVOID Context)
NTSTATUS
PsIdleThreadMain(PVOID Context)
{
KIRQL oldlvl;

View file

@ -1,4 +1,4 @@
/* $Id: thread.c,v 1.75 2001/04/16 16:29:03 dwelch Exp $
/* $Id: thread.c,v 1.76 2001/04/17 04:11:01 dwelch Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -44,6 +44,7 @@ KSPIN_LOCK PiThreadListLock;
LIST_ENTRY PiThreadListHead;
static LIST_ENTRY PriorityListHead[MAXIMUM_PRIORITY];
static BOOLEAN DoneInitYet = FALSE;
static PETHREAD IdleThreads[MAXIMUM_PROCESSORS];
ULONG PiNrThreads = 0;
ULONG PiNrRunnableThreads = 0;
@ -107,8 +108,8 @@ VOID PsDumpThreads(VOID)
DbgPrint("current %x current->Tcb.State %d eip %x/%x ",
current, current->Tcb.State,
0, current->Tcb.LastEip);
KeDumpStackFrames((PVOID)current->Tcb.KernelStack,
16);
// KeDumpStackFrames((PVOID)current->Tcb.KernelStack,
// 16);
DbgPrint("PID %d ", current->ThreadsProcess->UniqueProcessId);
DbgPrint("\n");
@ -289,6 +290,34 @@ PsFreezeAllThreads(PEPROCESS Process)
KeReleaseSpinLock(&PiThreadListLock, oldIrql);
}
VOID
PsApplicationProcessorInit(VOID)
{
KeGetCurrentKPCR()->CurrentThread =
(PVOID)IdleThreads[KeGetCurrentProcessorNumber()];
}
VOID
PsPrepareForApplicationProcessorInit(ULONG Id)
{
PETHREAD IdleThread;
HANDLE IdleThreadHandle;
PsInitializeThread(NULL,
&IdleThread,
&IdleThreadHandle,
THREAD_ALL_ACCESS,
NULL,
TRUE);
IdleThread->Tcb.State = THREAD_STATE_RUNNING;
IdleThread->Tcb.FreezeCount = 0;
IdleThread->Tcb.UserAffinity = 1 << Id;
IdleThread->Tcb.Priority = LOW_PRIORITY;
IdleThreads[Id] = IdleThread;
NtClose(IdleThreadHandle);
}
VOID
PsInitThreadManagment(VOID)
/*
@ -304,6 +333,7 @@ PsInitThreadManagment(VOID)
{
InitializeListHead(&PriorityListHead[i]);
}
InitializeListHead(&PiThreadListHead);
PsThreadType = ExAllocatePool(NonPagedPool,sizeof(OBJECT_TYPE));