Added Intel MultiProcessor Specification support

svn path=/trunk/; revision=1789
This commit is contained in:
Casper Hornstrup 2001-04-13 16:12:26 +00:00
parent 33408fe398
commit 94309de6e4
26 changed files with 4234 additions and 276 deletions

View file

@ -1,4 +1,4 @@
# $Id: Makefile,v 1.33 2001/04/11 22:13:21 dwelch Exp $ # $Id: Makefile,v 1.34 2001/04/13 16:12:24 chorns Exp $
# #
# ReactOS Operating System # ReactOS Operating System
# #
@ -11,6 +11,7 @@ PATH_TO_TOP := ..
# #
# Include details of the kernel configuration # Include details of the kernel configuration
# #
include config include config
# #
@ -56,12 +57,6 @@ all: $(EXE_PREFIX)depends$(EXE_POSTFIX) \
$(EXE_PREFIX)depends$(EXE_POSTFIX): depends.c $(EXE_PREFIX)depends$(EXE_POSTFIX): depends.c
$(HOST_CC) -o depends$(EXE_POSTFIX) depends.c $(HOST_CC) -o depends$(EXE_POSTFIX) depends.c
#
# Hardware Abstraction Layer (Hal)
# Defines $(OBJECTS_HAL)
#
include hal/x86/sources
# #
# Architecture specific Makefile # Architecture specific Makefile
# Defines $(OBJECTS_ARCH) # Defines $(OBJECTS_ARCH)
@ -110,7 +105,6 @@ OBJECTS_RTL = \
rtl/memcmp.o rtl/memcmp.o
# Kernel (Ke) # Kernel (Ke)
# Note: head.o MUST be the first file!!!
OBJECTS_KE = \ OBJECTS_KE = \
ke/apc.o \ ke/apc.o \
ke/bug.o \ ke/bug.o \
@ -451,7 +445,7 @@ $(OBJECTS_PATH)/kd.o: $(OBJECTS_KD)
$(TARGETNAME).coff: $(TARGETNAME).rc ../include/reactos/resource.h $(TARGETNAME).coff: $(TARGETNAME).rc ../include/reactos/resource.h
# Note: ke.o MUST be the first file!!! # Note: arch.o MUST be the first file!!!
OBJECTS := \ OBJECTS := \
$(OBJECTS_PATH)/arch.o \ $(OBJECTS_PATH)/arch.o \
$(OBJECTS_PATH)/ke.o \ $(OBJECTS_PATH)/ke.o \
@ -601,6 +595,9 @@ ke/main.o: ke/main.c ../include/reactos/buildno.h
mkconfig$(EXE_SUFFIX): mkconfig.c mkconfig$(EXE_SUFFIX): mkconfig.c
$(HOST_CC) -g -o mkconfig$(EXE_SUFFIX) mkconfig.c $(HOST_CC) -g -o mkconfig$(EXE_SUFFIX) mkconfig.c
config:
$(EXE_PREFIX)mkconfig$(EXE_SUFFIX) include/internal/config.h $(CONFIG)
include/internal/config.h: config mkconfig$(EXE_SUFFIX) include/internal/config.h: config mkconfig$(EXE_SUFFIX)
$(EXE_PREFIX)mkconfig$(EXE_SUFFIX) include/internal/config.h$(CONFIG) $(EXE_PREFIX)mkconfig$(EXE_SUFFIX) include/internal/config.h$(CONFIG)
@ -617,6 +614,7 @@ endif
.%.d: %.S .%.d: %.S
$(CC) $(CFLAGS) -M $< | $(EXE_PREFIX)depends$(EXE_POSTFIX) $(@D) $@ $(CC) $(CFLAGS) -M $< | $(EXE_PREFIX)depends$(EXE_POSTFIX) $(@D) $@
.%.d: %.asm
$(NASM_CMD) $< | $(EXE_PREFIX)depends$(EXE_POSTFIX) $(@D) $@
# EOF # EOF

View file

@ -1,3 +1,10 @@
#
# Hardware Abstraction Layer (Hal) for x86 systems
#
# Defines $(OBJECTS_HAL)
include hal/x86/sources
OBJECTS_BOOT := ke/i386/multiboot.o OBJECTS_BOOT := ke/i386/multiboot.o
OBJECTS_KE_I386 := \ OBJECTS_KE_I386 := \
@ -13,7 +20,7 @@ OBJECTS_KE_I386 := \
ke/i386/v86m.o \ ke/i386/v86m.o \
ke/i386/v86m_sup.o \ ke/i386/v86m_sup.o \
ke/i386/bios.o \ ke/i386/bios.o \
ke/i386/i386-mcount.o \ ke/i386/i386-mcount.o \
ke/i386/gdt.o \ ke/i386/gdt.o \
ke/i386/idt.o \ ke/i386/idt.o \
ke/i386/ldt.o \ ke/i386/ldt.o \

View file

@ -1,9 +1,9 @@
/* $Id: halinit.c,v 1.17 2001/03/16 18:11:21 dwelch Exp $ /* $Id: halinit.c,v 1.18 2001/04/13 16:12:25 chorns Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
* FILE: ntoskrnl/hal/x86/halinit.c * FILE: ntoskrnl/hal/x86/halinit.c
* PURPOSE: Initalize the uniprocessor, x86 hal * PURPOSE: Initalize the x86 hal
* PROGRAMMER: David Welch (welch@cwcom.net) * PROGRAMMER: David Welch (welch@cwcom.net)
* UPDATE HISTORY: * UPDATE HISTORY:
* 11/06/98: Created * 11/06/98: Created
@ -12,27 +12,45 @@
/* INCLUDES *****************************************************************/ /* INCLUDES *****************************************************************/
#include <ddk/ntddk.h> #include <ddk/ntddk.h>
#include <internal/config.h>
#include <internal/hal/hal.h> #include <internal/hal/hal.h>
#include <internal/ntoskrnl.h> #include <internal/ntoskrnl.h>
#ifdef MP
#include <internal/hal/mps.h>
#endif /* MP */
#define NDEBUG #define NDEBUG
#include <internal/debug.h> #include <internal/debug.h>
/* FUNCTIONS ***************************************************************/ /* FUNCTIONS ***************************************************************/
BOOLEAN STDCALL BOOLEAN STDCALL
HalInitSystem (ULONG BootPhase, HalInitSystem (ULONG BootPhase,
PLOADER_PARAMETER_BLOCK LoaderBlock) PLOADER_PARAMETER_BLOCK LoaderBlock)
{ {
if (BootPhase == 0) if (BootPhase == 0)
{ {
HalInitializeDisplay (LoaderBlock); HalInitializeDisplay (LoaderBlock);
HalpInitPICs ();
#ifdef MP
HalpInitMPS();
#else
HalpInitPICs();
/* Setup busy waiting */
HalpCalibrateStallExecution();
#endif /* MP */
} }
else else
{ {
HalpInitBusHandlers (); HalpInitBusHandlers ();
} }
return TRUE; return TRUE;

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,76 @@
/* $Id: mps.S,v 1.1 2001/04/13 16:12:25 chorns Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/hal/x86/mps.S
* PURPOSE: Intel MultiProcessor specification support
* PROGRAMMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
* UPDATE HISTORY:
* Created 12/04/2001
*/
/* INCLUDES ******************************************************************/
#include <internal/i386/segment.h>
/* FUNCTIONS *****************************************************************/
#define BEFORE \
pusha; \
pushl %ds; \
pushl %es; \
pushl %fs; \
pushl %gs; \
movl $(KERNEL_DS), %eax; \
movl %eax, %ds; \
movl %eax, %es; \
movl %eax, %gs; \
movl $(PCR_SELECTOR), %eax; \
movl %eax, %fs;
#define AFTER \
popl %gs; \
popl %fs; \
popl %es; \
popl %ds; \
popa;
.globl _MpsTimerInterrupt
_MpsTimerInterrupt:
/* Save registers */
BEFORE
/* Call the C handler */
call _MpsTimerHandler
/* Return to the caller */
AFTER
iret
.globl _MpsErrorInterrupt
_MpsErrorInterrupt:
/* Save registers */
BEFORE
/* Call the C handler */
call _MpsErrorHandler
/* Return to the caller */
AFTER
iret
.globl _MpsSpuriousInterrupt
_MpsSpuriousInterrupt:
/* Save registers */
BEFORE
/* Call the C handler */
call _MpsSpuriousHandler
/* Return to the caller */
AFTER
iret
/* EOF */

View file

@ -0,0 +1,106 @@
;
; COPYRIGHT: See COPYING in the top level directory
; PROJECT: ReactOS kernel
; FILE: ntoskrnl/hal/x86/mpsboot.c
; PURPOSE: Bootstrap code for application processors
; PROGRAMMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
; UPDATE HISTORY:
; Created 12/04/2001
;
;
; Memory map at this stage is:
; 0x2000 Location of our stack
; 0x3000 Startup code for the APs (this code)
;
;
; Base address of common area for BSP and APs
;
LOAD_BASE equ 00200000h
;
; Magic value to be put in EAX when multiboot.S is called as part of the
; application processor initialization process
;
AP_MAGIC equ 12481020h
;
; Segment selectors
;
%define KERNEL_CS (0x8)
%define KERNEL_DS (0x10)
section .text
global _APstart
global _APend
; 16 bit code
BITS 16
_APstart:
cli ; Just in case
xor ax, ax
mov ds, ax
mov ss, ax
mov eax, 3000h + APgdt - _APstart
lgdt [eax]
mov eax, cr0
or eax, 00010001h ; Turn on protected mode and write protection
mov cr0, eax
db 0eah
dw 3000h + flush - _APstart, KERNEL_CS
; 32 bit code
BITS 32
flush:
mov ax, KERNEL_DS
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ss, ax
; Setup a stack for the AP
mov eax, 2000h
mov eax, [eax]
mov esp, eax
; Jump to start of the kernel with AP magic in eax
mov eax, AP_MAGIC
jmp dword KERNEL_CS:(LOAD_BASE + 0x1000)
; Never get here
; Temporary GDT descriptor for the APs
APgdt:
; Limit
dw (3*8)-1
; Base
dd 3000h + gdt - _APstart
gdt:
dw 0x0 ; Null descriptor
dw 0x0
dw 0x0
dw 0x0
dw 0xffff ; Kernel code descriptor
dw 0x0000
dw 0x9a00
dw 0x00cf
dw 0xffff ; Kernel data descriptor
dw 0x0000
dw 0x9200
dw 0x00cf
_APend:

View file

@ -0,0 +1,426 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/hal/x86/mpsirql.c
* PURPOSE: Implements IRQLs for multiprocessor systems
* PROGRAMMERS: David Welch (welch@cwcom.net)
* Casper S. Hornstrup (chorns@users.sourceforge.net)
* UPDATE HISTORY:
* 12/04/2001 CSH Created
*/
/* INCLUDES *****************************************************************/
#include <ddk/ntddk.h>
#include <internal/bitops.h>
#include <internal/ke.h>
#include <internal/ps.h>
#include <internal/hal/mps.h>
#define NDEBUG
#include <internal/debug.h>
/* GLOBALS ******************************************************************/
extern ULONG DpcQueueSize;
static VOID KeSetCurrentIrql(KIRQL newlvl);
/* FUNCTIONS ****************************************************************/
#define IRQL2TPR(irql) (APIC_TPR_MIN + ((irql - DISPATCH_LEVEL - 1) << 4))
static VOID HiSetCurrentPriority(
ULONG Priority)
{
// DPRINT(" P(0x%X) \n", Priority);
APICWrite(APIC_TPR, Priority & APIC_TPR_PRI);
}
static VOID HiSwitchIrql(KIRQL OldIrql, ULONG Flags)
/*
* FUNCTION: Switches to the current irql
* NOTE: Must be called with interrupt disabled
*/
{
PKTHREAD CurrentThread;
KIRQL CurrentIrql;
CurrentIrql = KeGetCurrentKPCR()->Irql;
if (CurrentIrql == HIGH_LEVEL)
{
/* Block all interrupts */
HiSetCurrentPriority(APIC_TPR_MAX);
return;
}
if (CurrentIrql == IPI_LEVEL)
{
HiSetCurrentPriority(APIC_TPR_MAX - 16);
popfl(Flags);
return;
}
if (CurrentIrql == CLOCK2_LEVEL)
{
HiSetCurrentPriority(APIC_TPR_MAX - 32);
popfl(Flags);
return;
}
if (CurrentIrql > DISPATCH_LEVEL)
{
HiSetCurrentPriority(IRQL2TPR(CurrentIrql));
popfl(Flags);
return;
}
/* Pass all interrupts */
HiSetCurrentPriority(0);
if (CurrentIrql == DISPATCH_LEVEL)
{
popfl(Flags);
return;
}
if (CurrentIrql == APC_LEVEL)
{
if (DpcQueueSize > 0 )
{
KeSetCurrentIrql(DISPATCH_LEVEL);
__asm__("sti\n\t");
KiDispatchInterrupt();
__asm__("cli\n\t");
KeSetCurrentIrql(PASSIVE_LEVEL);
}
popfl(Flags);
return;
}
CurrentThread = KeGetCurrentThread();
if (CurrentIrql == PASSIVE_LEVEL &&
CurrentThread != NULL &&
CurrentThread->ApcState.KernelApcPending)
{
KeSetCurrentIrql(APC_LEVEL);
__asm__("sti\n\t");
KiDeliverApc(0, 0, 0);
__asm__("cli\n\t");
KeSetCurrentIrql(PASSIVE_LEVEL);
popfl(Flags);
}
else
{
popfl(Flags);
}
}
KIRQL STDCALL KeGetCurrentIrql (VOID)
/*
* PURPOSE: Returns the current irq level
* RETURNS: The current irq level
*/
{
return(KeGetCurrentKPCR()->Irql);
}
static VOID KeSetCurrentIrql(KIRQL newlvl)
/*
* PURPOSE: Sets the current irq level without taking any action
*/
{
// DPRINT("KeSetCurrentIrql(newlvl %x)\n",newlvl);
KeGetCurrentKPCR()->Irql = newlvl;
}
/**********************************************************************
* NAME EXPORTED
* KfLowerIrql
*
* DESCRIPTION
* Restores the irq level on the current processor
*
* ARGUMENTS
* NewIrql = Irql to lower to
*
* RETURN VALUE
* None
*
* NOTES
* Uses fastcall convention
*/
VOID FASTCALL
KfLowerIrql (
KIRQL NewIrql
)
{
KIRQL CurrentIrql;
KIRQL OldIrql;
ULONG Flags;
//DPRINT("KfLowerIrql(NewIrql %d)\n", NewIrql);
//DbgPrint("KfLowerIrql(NewIrql %d)\n", NewIrql);
//KeBugCheck(0);
pushfl(Flags);
__asm__ ("\n\tcli\n\t");
CurrentIrql = KeGetCurrentKPCR()->Irql;
if (NewIrql > CurrentIrql)
{
DbgPrint ("(%s:%d) NewIrql %x CurrentIrql %x\n",
__FILE__, __LINE__, NewIrql, CurrentIrql);
KeDumpStackFrames (0, 32);
for(;;);
}
OldIrql = CurrentIrql;
KeGetCurrentKPCR()->Irql = NewIrql;
HiSwitchIrql(OldIrql, Flags);
}
/**********************************************************************
* NAME EXPORTED
* KeLowerIrql
*
* DESCRIPTION
* Restores the irq level on the current processor
*
* ARGUMENTS
* NewIrql = Irql to lower to
*
* RETURN VALUE
* None
*
* NOTES
*/
VOID
STDCALL
KeLowerIrql (
KIRQL NewIrql
)
{
KfLowerIrql (NewIrql);
}
/**********************************************************************
* NAME EXPORTED
* KfRaiseIrql
*
* DESCRIPTION
* Raises the hardware priority (irql)
*
* ARGUMENTS
* NewIrql = Irql to raise to
*
* RETURN VALUE
* previous irq level
*
* NOTES
* Uses fastcall convention
*/
KIRQL
FASTCALL
KfRaiseIrql (
KIRQL NewIrql
)
{
KIRQL CurrentIrql;
KIRQL OldIrql;
ULONG Flags;
//DPRINT("KfRaiseIrql(NewIrql %d)\n", NewIrql);
//DbgPrint("KfRaiseIrql(NewIrql %d)\n", NewIrql);
//KeBugCheck(0);
pushfl(Flags);
__asm__ ("\n\tcli\n\t");
CurrentIrql = KeGetCurrentKPCR()->Irql;
if (NewIrql < CurrentIrql)
{
DbgPrint ("%s:%d CurrentIrql %x NewIrql %x\n",
__FILE__,__LINE__,CurrentIrql,NewIrql);
KeBugCheck (0);
for(;;);
}
OldIrql = CurrentIrql;
KeGetCurrentKPCR()->Irql = NewIrql;
//DPRINT("NewIrql %x OldIrql %x\n", NewIrql, OldIrql);
HiSwitchIrql(OldIrql, Flags);
return OldIrql;
}
/**********************************************************************
* NAME EXPORTED
* KeRaiseIrql
*
* DESCRIPTION
* Raises the hardware priority (irql)
*
* ARGUMENTS
* NewIrql = Irql to raise to
* OldIrql (OUT) = Caller supplied storage for the previous irql
*
* RETURN VALUE
* None
*
* NOTES
* Calls KfRaiseIrql
*/
VOID
STDCALL
KeRaiseIrql (
KIRQL NewIrql,
PKIRQL OldIrql
)
{
*OldIrql = KfRaiseIrql (NewIrql);
}
/**********************************************************************
* NAME EXPORTED
* KeRaiseIrqlToDpcLevel
*
* DESCRIPTION
* Raises the hardware priority (irql) to DISPATCH level
*
* ARGUMENTS
* None
*
* RETURN VALUE
* Previous irq level
*
* NOTES
* Calls KfRaiseIrql
*/
KIRQL
STDCALL
KeRaiseIrqlToDpcLevel (VOID)
{
return KfRaiseIrql (DISPATCH_LEVEL);
}
/**********************************************************************
* NAME EXPORTED
* KeRaiseIrqlToSynchLevel
*
* DESCRIPTION
* Raises the hardware priority (irql) to CLOCK2 level
*
* ARGUMENTS
* None
*
* RETURN VALUE
* Previous irq level
*
* NOTES
* Calls KfRaiseIrql
*/
KIRQL
STDCALL
KeRaiseIrqlToSynchLevel (VOID)
{
return KfRaiseIrql (CLOCK2_LEVEL);
}
BOOLEAN STDCALL HalBeginSystemInterrupt (ULONG Vector,
KIRQL Irql,
PKIRQL OldIrql)
{
DPRINT("Vector (0x%X) Irql (0x%X)\n",
Vector, Irql);
if (Vector < FIRST_DEVICE_VECTOR ||
Vector > FIRST_DEVICE_VECTOR + NUMBER_DEVICE_VECTORS) {
DPRINT("Not a device interrupt\n");
return FALSE;
}
/*
* Acknowledge the interrupt
*/
APICSendEOI();
*OldIrql = KeGetCurrentIrql();
KeSetCurrentIrql(Irql);
return TRUE;
}
VOID STDCALL HalEndSystemInterrupt (KIRQL Irql,
ULONG Unknown2)
{
KeSetCurrentIrql(Irql);
}
BOOLEAN STDCALL HalDisableSystemInterrupt (ULONG Vector,
ULONG Unknown2)
{
ULONG irq;
DPRINT("Vector (0x%X)\n", Vector);
if (Vector < FIRST_DEVICE_VECTOR ||
Vector > FIRST_DEVICE_VECTOR + NUMBER_DEVICE_VECTORS) {
DPRINT("Not a device interrupt\n");
return FALSE;
}
irq = VECTOR2IRQ(Vector);
IOAPICMaskIrq(0, irq);
return TRUE;
}
BOOLEAN STDCALL HalEnableSystemInterrupt (ULONG Vector,
ULONG Unknown2,
ULONG Unknown3)
{
ULONG irq;
DPRINT("Vector (0x%X)\n", Vector);
if (Vector < FIRST_DEVICE_VECTOR ||
Vector > FIRST_DEVICE_VECTOR + NUMBER_DEVICE_VECTORS) {
DPRINT("Not a device interrupt\n");
return FALSE;
}
irq = VECTOR2IRQ(Vector);
IOAPICUnmaskIrq(0, irq);
return TRUE;
}
/* EOF */

View file

@ -1,4 +1,4 @@
OBJECTS_HAL = \ OBJECTS_HAL_COMMON = \
hal/x86/adapter.o \ hal/x86/adapter.o \
hal/x86/beep.o \ hal/x86/beep.o \
hal/x86/bios32.o \ hal/x86/bios32.o \
@ -9,7 +9,6 @@ OBJECTS_HAL = \
hal/x86/fmutex.o \ hal/x86/fmutex.o \
hal/x86/halinit.o \ hal/x86/halinit.o \
hal/x86/isa.o \ hal/x86/isa.o \
hal/x86/irql.o \
hal/x86/kdbg.o \ hal/x86/kdbg.o \
hal/x86/mbr.o \ hal/x86/mbr.o \
hal/x86/misc.o \ hal/x86/misc.o \
@ -24,3 +23,17 @@ OBJECTS_HAL = \
hal/x86/sysinfo.o \ hal/x86/sysinfo.o \
hal/x86/time.o \ hal/x86/time.o \
hal/x86/udelay.o hal/x86/udelay.o
OBJECTS_HAL_UP = \
hal/x86/irql.o
OBJECTS_HAL_MP = \
hal/x86/mps.o \
hal/x86/mpsboot.o \
hal/x86/mpsirql.o
ifeq ($(MP), 1)
OBJECTS_HAL = $(OBJECTS_HAL_COMMON) $(OBJECTS_HAL_MP)
else
OBJECTS_HAL = $(OBJECTS_HAL_COMMON) $(OBJECTS_HAL_UP)
endif

View file

@ -10,6 +10,7 @@
#include <ddk/ntddk.h> #include <ddk/ntddk.h>
#include <string.h> #include <string.h>
#include <internal/hal/mps.h>
#define NDEBUG #define NDEBUG
#include <internal/debug.h> #include <internal/debug.h>
@ -38,13 +39,15 @@ static BYTE
HalQueryCMOS (BYTE Reg) HalQueryCMOS (BYTE Reg)
{ {
BYTE Val; BYTE Val;
ULONG Flags;
Reg |= 0x80; Reg |= 0x80;
pushfl(Flags);
__asm__("cli\n"); // AP unsure as to whether to do this here __asm__("cli\n"); // AP unsure as to whether to do this here
WRITE_PORT_UCHAR((PUCHAR)0x70, Reg); WRITE_PORT_UCHAR((PUCHAR)0x70, Reg);
Val = READ_PORT_UCHAR((PUCHAR)0x71); Val = READ_PORT_UCHAR((PUCHAR)0x71);
WRITE_PORT_UCHAR((PUCHAR)0x70, 0); WRITE_PORT_UCHAR((PUCHAR)0x70, 0);
__asm__("sti\n"); // AP unsure about this too.. popfl(Flags);
return(Val); return(Val);
} }
@ -53,12 +56,15 @@ HalQueryCMOS (BYTE Reg)
static VOID static VOID
HalSetCMOS (BYTE Reg, BYTE Val) HalSetCMOS (BYTE Reg, BYTE Val)
{ {
ULONG Flags;
Reg |= 0x80; Reg |= 0x80;
pushfl(Flags);
__asm__("cli\n"); // AP unsure as to whether to do this here __asm__("cli\n"); // AP unsure as to whether to do this here
WRITE_PORT_UCHAR((PUCHAR)0x70, Reg); WRITE_PORT_UCHAR((PUCHAR)0x70, Reg);
WRITE_PORT_UCHAR((PUCHAR)0x71, Val); WRITE_PORT_UCHAR((PUCHAR)0x71, Val);
WRITE_PORT_UCHAR((PUCHAR)0x70, 0); WRITE_PORT_UCHAR((PUCHAR)0x70, 0);
__asm__("sti\n"); // AP unsure about this too.. popfl(Flags);
} }

View file

@ -20,7 +20,7 @@
* MA 02139, USA. * MA 02139, USA.
* *
*/ */
/* $Id: udelay.c,v 1.7 2001/03/16 18:11:21 dwelch Exp $ /* $Id: udelay.c,v 1.8 2001/04/13 16:12:25 chorns Exp $
* *
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
* FILE: ntoskrnl/hal/x86/udelay.c * FILE: ntoskrnl/hal/x86/udelay.c
@ -34,7 +34,7 @@
#include <ddk/ntddk.h> #include <ddk/ntddk.h>
#define NDEBUG //#define NDEBUG
#include <internal/debug.h> #include <internal/debug.h>
/* GLOBALS ******************************************************************/ /* GLOBALS ******************************************************************/
@ -77,6 +77,8 @@ static unsigned int delay_count = 1;
#define TMR_CH1 0x4 /* Channel 1 bit */ #define TMR_CH1 0x4 /* Channel 1 bit */
#define TMR_CH0 0x2 /* Channel 0 bit */ #define TMR_CH0 0x2 /* Channel 0 bit */
static BOOLEAN UdelayCalibrated = FALSE;
/* FUNCTIONS **************************************************************/ /* FUNCTIONS **************************************************************/
void init_pit(float h, unsigned char channel) void init_pit(float h, unsigned char channel)
@ -98,7 +100,7 @@ void init_pit(float h, unsigned char channel)
VOID STDCALL VOID STDCALL
__KeStallExecutionProcessor(ULONG Loops) __KeStallExecutionProcessor(ULONG Loops)
{ {
unsigned int i; register unsigned int i;
for (i=0; i<Loops;i++); for (i=0; i<Loops;i++);
} }
@ -108,35 +110,74 @@ VOID STDCALL KeStallExecutionProcessor(ULONG Microseconds)
} }
#define HZ (100) #define HZ (100)
#define CLOCK_TICK_RATE (1193180) #define CLOCK_TICK_RATE (1193182)
#define LATCH ((CLOCK_TICK_RATE + HZ/2) / HZ) #define LATCH (CLOCK_TICK_RATE / HZ)
static ULONG Read8254Timer(VOID)
{
ULONG Count;
WRITE_PORT_UCHAR((PUCHAR)0x43, 0x00);
Count = READ_PORT_UCHAR((PUCHAR)0x40);
Count |= READ_PORT_UCHAR((PUCHAR)0x40) << 8;
return Count;
}
static VOID WaitFor8254Wraparound(VOID)
{
ULONG CurCount, PrevCount = ~0;
LONG Delta;
CurCount = Read8254Timer();
do {
PrevCount = CurCount;
CurCount = Read8254Timer();
Delta = CurCount - PrevCount;
/*
* This limit for delta seems arbitrary, but it isn't, it's
* slightly above the level of error a buggy Mercury/Neptune
* chipset timer can cause.
*/
} while (Delta < 300);
}
VOID HalpCalibrateStallExecution(VOID) VOID HalpCalibrateStallExecution(VOID)
{ {
unsigned int prevtick; ULONG i;
unsigned int i; ULONG calib_bit;
unsigned int calib_bit; ULONG CurCount;
extern volatile ULONG KiRawTicks;
if (UdelayCalibrated)
return;
UdelayCalibrated = TRUE;
DbgPrint("Calibrating delay loop... ["); DbgPrint("Calibrating delay loop... [");
/* Initialise timer interrupt with MILLISECOND ms interval */ /* Initialise timer interrupt with MILLISECOND ms interval */
//init_pit(FREQ, 0);
WRITE_PORT_UCHAR((PUCHAR)0x43, 0x34); /* binary, mode 2, LSB/MSB, ch 0 */ WRITE_PORT_UCHAR((PUCHAR)0x43, 0x34); /* binary, mode 2, LSB/MSB, ch 0 */
WRITE_PORT_UCHAR((PUCHAR)0x40, LATCH & 0xff); /* LSB */ WRITE_PORT_UCHAR((PUCHAR)0x40, LATCH & 0xff); /* LSB */
WRITE_PORT_UCHAR((PUCHAR)0x40, LATCH >> 8); /* MSB */ WRITE_PORT_UCHAR((PUCHAR)0x40, LATCH >> 8); /* MSB */
/* Stage 1: Coarse calibration */ /* Stage 1: Coarse calibration */
WaitFor8254Wraparound();
delay_count = 1;
do { do {
delay_count <<= 1; /* Next delay count to try */ delay_count <<= 1; /* Next delay count to try */
prevtick=KiRawTicks; /* Wait for the start of the next */ WaitFor8254Wraparound();
while(prevtick==KiRawTicks); /* timer tick */
prevtick=KiRawTicks; /* Start measurement now */ __KeStallExecutionProcessor(delay_count); /* Do the delay */
__KeStallExecutionProcessor(delay_count); /* Do the delay */
} while(prevtick == KiRawTicks); /* Until delay is just too big */ CurCount = Read8254Timer();
} while (CurCount > LATCH / 2);
delay_count >>= 1; /* Get bottom value for delay */ delay_count >>= 1; /* Get bottom value for delay */
@ -146,36 +187,30 @@ VOID HalpCalibrateStallExecution(VOID)
calib_bit = delay_count; /* Which bit are we going to test */ calib_bit = delay_count; /* Which bit are we going to test */
for(i=0;i<PRECISION;i++) { for(i=0;i<PRECISION;i++) {
calib_bit >>= 1; /* Next bit to calibrate */ calib_bit >>= 1; /* Next bit to calibrate */
if(!calib_bit) break; /* If we have done all bits, stop */ if(!calib_bit) break; /* If we have done all bits, stop */
delay_count |= calib_bit; /* Set the bit in delay_count */ delay_count |= calib_bit; /* Set the bit in delay_count */
prevtick=KiRawTicks; /* Wait for the start of the next */ WaitFor8254Wraparound();
while(prevtick==KiRawTicks); /* timer tick */
prevtick=KiRawTicks; /* Start measurement now */ __KeStallExecutionProcessor(delay_count); /* Do the delay */
__KeStallExecutionProcessor(delay_count); /* Do the delay */
if(prevtick != KiRawTicks) /* If a tick has passed, turn the */ CurCount = Read8254Timer();
delay_count &= ~calib_bit; /* calibrated bit back off */ if (CurCount <= LATCH / 2) /* If a tick has passed, turn the */
delay_count &= ~calib_bit; /* calibrated bit back off */
} }
/* We're finished: Do the finishing touches */ /* We're finished: Do the finishing touches */
delay_count /= MILLISEC; /* Calculate delay_count for 1ms */ delay_count /= (MILLISEC / 2); /* Calculate delay_count for 1ms */
DbgPrint("]\n"); DbgPrint("]\n");
DbgPrint("delay_count: %d\n", delay_count); DbgPrint("delay_count: %d\n", delay_count);
DbgPrint("CPU speed: %d\n", delay_count/500); DbgPrint("CPU speed: %d\n", delay_count/250);
#if 0 #if 0
DbgPrint("About to start delay loop test\n"); DbgPrint("About to start delay loop test\n");
for (i = 0; i < (10*1000*20); i++)
{
KeStallExecutionProcessor(50);
}
DbgPrint("Waiting for five minutes..."); DbgPrint("Waiting for five minutes...");
KeStallExecutionProcessor(5*60*1000*1000);
for (i = 0; i < (5*60*1000*20); i++) for (i = 0; i < (5*60*1000*20); i++)
{ {
KeStallExecutionProcessor(50); KeStallExecutionProcessor(50);

View file

@ -0,0 +1,432 @@
#ifndef __INCLUDE_HAL_MPS
#define __INCLUDE_HAL_MPS
#define APIC_DEFAULT_BASE 0xFEE00000 /* Default Local APIC Base Register Address */
#define IOAPIC_DEFAULT_BASE 0xFEC00000 /* Default I/O APIC Base Register Address */
/* APIC Register Address Map */
#define APIC_ID 0x0020 /* Local APIC ID Register (R/W) */
#define APIC_VER 0x0030 /* Local APIC Version Register (R) */
#define APIC_TPR 0x0080 /* Task Priority Register (R/W) */
#define APIC_APR 0x0090 /* Arbitration Priority Register (R) */
#define APIC_PPR 0x00A0 /* Processor Priority Register (R) */
#define APIC_EOI 0x00B0 /* EOI Register (W) */
#define APIC_LDR 0x00D0 /* Logical Destination Register (R/W) */
#define APIC_DFR 0x00E0 /* Destination Format Register (0-27 R, 28-31 R/W) */
#define APIC_SIVR 0x00F0 /* Spurious Interrupt Vector Register (0-3 R, 4-9 R/W) */
#define APIC_ISR 0x0100 /* Interrupt Service Register 0-255 (R) */
#define APIC_TMR 0x0180 /* Trigger Mode Register 0-255 (R) */
#define APIC_IRR 0x0200 /* Interrupt Request Register 0-255 (r) */
#define APIC_ESR 0x0280 /* Error Status Register (R) */
#define APIC_ICR0 0x0300 /* Interrupt Command Register 0-31 (R/W) */
#define APIC_ICR1 0x0310 /* Interrupt Command Register 32-63 (R/W) */
#define APIC_LVTT 0x0320 /* Local Vector Table (Timer) (R/W) */
#define APIC_LVTPC 0x0340 /* Performance Counter LVT (R/W) */
#define APIC_LINT0 0x0350 /* Local Vector Table (LINT0) (R/W) */
#define APIC_LINT1 0x0360 /* Local Vector Table (LINT1) (R/W) */
#define APIC_LVT3 0x0370 /* Local Vector Table (Error) (R/W) */
#define APIC_ICRT 0x0380 /* Initial Count Register for Timer (R/W) */
#define APIC_CCRT 0x0390 /* Current Count Register for Timer (R) */
#define APIC_TDCR 0x03E0 /* Timer Divide Configuration Register (R/W) */
#define APIC_ID_MASK (0xF << 24)
#define GET_APIC_ID(x) (((x) & APIC_ID_MASK) >> 24)
#define APIC_VER_MASK 0xFF00FF
#define GET_APIC_VERSION(x)((x) & 0xFF)
#define GET_APIC_MAXLVT(x) (((x) >> 16) & 0xFF)
#define APIC_TPR_PRI 0xFF
#define APIC_TPR_INT 0xF0
#define APIC_TPR_SUB 0xF
#define APIC_TPR_MAX 0xFF /* Maximum priority */
#define APIC_TPR_MIN 0x20 /* Minimum priority */
#define APIC_LDR_MASK (0xFF << 24)
#define APIC_SIVR_ENABLE (0x1 << 8)
#define APIC_SIVR_FOCUS (0x1 << 9)
#define APIC_ESR_MASK (0xFE << 0) /* Error Mask */
#define APIC_ICR0_VECTOR (0xFF << 0) /* Vector */
#define APIC_ICR0_DM (0x7 << 8) /* Delivery Mode */
#define APIC_ICR0_DESTM (0x1 << 11) /* Destination Mode */
#define APIC_ICR0_DS (0x1 << 12) /* Delivery Status */
#define APIC_ICR0_LEVEL (0x1 << 14) /* Level */
#define APIC_ICR0_TM (0x1 << 15) /* Trigger Mode */
#define APIC_ICR0_DESTS (0x3 << 18) /* Destination Shorthand */
/* Delivery Modes */
#define APIC_DM_FIXED (0x0 << 8)
#define APIC_DM_LOWEST (0x1 << 8)
#define APIC_DM_SMI (0x2 << 8)
#define APIC_DM_REMRD (0x3 << 8)
#define APIC_DM_NMI (0x4 << 8)
#define APIC_DM_INIT (0x5 << 8)
#define APIC_DM_STARTUP (0x6 << 8)
#define APIC_DM_EXTINT (0x7 << 8)
#define GET_APIC_DELIVERY_MODE(x) (((x) >> 8) & 0x7)
#define SET_APIC_DELIVERY_MODE(x,y) (((x) & ~0x700) | ((y) << 8))
/* Destination Shorthand values */
#define APIC_ICR0_DESTS_FIELD (0x0 << 0)
#define APIC_ICR0_DESTS_SELF (0x1 << 18)
#define APIC_ICR0_DESTS_ALL (0x2 << 18)
#define APIC_ICR0_DESTS_ALL_BUT_SELF (0x3 << 18)
#define APIC_ICR0_LEVEL_DEASSERT (0x0 << 14) /* Deassert level */
#define APIC_ICR0_LEVEL_ASSERT (0x1 << 14) /* Assert level */
#define GET_APIC_DEST_FIELD(x) (((x) >> 24) & 0xFF)
#define SET_APIC_DEST_FIELD(x) (((x) & 0xFF) << 24)
#define GET_APIC_TIMER_BASE(x) (((x) >> 18) & 0x3)
#define SET_APIC_TIMER_BASE(x) ((x) << 18)
#define APIC_TIMER_BASE_CLKIN 0x0
#define APIC_TIMER_BASE_TMBASE 0x1
#define APIC_TIMER_BASE_DIV 0x2
#define APIC_LVT_VECTOR (0xFF << 0) /* Vector */
#define APIC_LVT_DS (0x1 << 12) /* Delivery Status */
#define APIC_LVT_REMOTE_IRR (0x1 << 14) /* Remote IRR */
#define APIC_LVT_LEVEL_TRIGGER (0x1 << 15) /* Lvel Triggered */
#define APIC_LVT_MASKED (0x1 << 16) /* Mask */
#define APIC_LVT_PERIODIC (0x1 << 17) /* Timer Mode */
#define APIC_LVT3_DM (0x7 << 8)
#define APIC_LVT3_IIPP (0x1 << 13)
#define APIC_LVT3_TM (0x1 << 15)
#define APIC_LVT3_MASKED (0x1 << 16)
#define APIC_LVT3_OS (0x1 << 17)
#define APIC_TDCR_TMBASE (0x1 << 2)
#define APIC_TDCR_MASK 0x0F
#define APIC_TDCR_2 0x00
#define APIC_TDCR_4 0x01
#define APIC_TDCR_8 0x02
#define APIC_TDCR_16 0x03
#define APIC_TDCR_32 0x08
#define APIC_TDCR_64 0x09
#define APIC_TDCR_128 0x0A
#define APIC_TDCR_1 0x0B
#define APIC_TARGET_SELF 0x100
#define APIC_TARGET_ALL 0x200
#define APIC_TARGET_ALL_BUT_SELF 0x300
#define IPI_CACHE_FLUSH 0x40
#define IPI_INV_TLB 0x41
#define IPI_INV_PTE 0x42
#define IPI_INV_RESCHED 0x43
#define IPI_STOP 0x44
#define APIC_INTEGRATED(version) (version & 0xF0)
/* I/O APIC Register Address Map */
#define IOAPIC_IOREGSEL 0x0000 /* I/O Register Select (index) (R/W) */
#define IOAPIC_IOWIN 0x0010 /* I/O window (data) (R/W) */
#define IOAPIC_ID 0x0000 /* IO APIC ID (R/W) */
#define IOAPIC_VER 0x0001 /* IO APIC Version (R) */
#define IOAPIC_ARB 0x0002 /* IO APIC Arbitration ID (R) */
#define IOAPIC_REDTBL 0x0010 /* Redirection Table (0-23 64-bit registers) (R/W) */
#define IOAPIC_ID_MASK (0xF << 24)
#define GET_IOAPIC_ID(x) (((x) & IOAPIC_ID_MASK) >> 24)
#define SET_IOAPIC_ID(x) ((x) << 24)
#define IOAPIC_VER_MASK (0xFF)
#define GET_IOAPIC_VERSION(x) (((x) & IOAPIC_VER_MASK))
#define IOAPIC_MRE_MASK (0xFF << 16) /* Maximum Redirection Entry */
#define GET_IOAPIC_MRE(x) (((x) & IOAPIC_MRE_MASK) >> 16)
#define IOAPIC_ARB_MASK (0xF << 24)
#define GET_IOAPIC_ARB(x) (((x) & IOAPIC_ARB_MASK) >> 24)
#define IOAPIC_TBL_DELMOD (0x7 << 10) /* Delivery Mode (see APIC_DM_*) */
#define IOAPIC_TBL_DM (0x1 << 11) /* Destination Mode */
#define IOAPIC_TBL_DS (0x1 << 12) /* Delivery Status */
#define IOAPIC_TBL_INTPOL (0x1 << 13) /* Interrupt Input Pin Polarity */
#define IOAPIC_TBL_RIRR (0x1 << 14) /* Remote IRR */
#define IOAPIC_TBL_TM (0x1 << 15) /* Trigger Mode */
#define IOAPIC_TBL_IM (0x1 << 16) /* Interrupt Mask */
#define IOAPIC_TBL_DF0 (0xF << 56) /* Destination Field (physical mode) */
#define IOAPIC_TBL_DF1 (0xFF<< 56) /* Destination Field (logical mode) */
#define IOAPIC_TBL_VECTOR (0xFF << 0) /* Vector (10h - FEh) */
typedef struct _IOAPIC_ROUTE_ENTRY {
ULONG vector : 8,
delivery_mode : 3, /* 000: FIXED
* 001: lowest priority
* 111: ExtINT
*/
dest_mode : 1, /* 0: physical, 1: logical */
delivery_status : 1,
polarity : 1,
irr : 1,
trigger : 1, /* 0: edge, 1: level */
mask : 1, /* 0: enabled, 1: disabled */
__reserved_2 : 15;
union { struct { ULONG
__reserved_1 : 24,
physical_dest : 4,
__reserved_2 : 4;
} physical;
struct { ULONG
__reserved_1 : 24,
logical_dest : 8;
} logical;
} dest;
} __attribute__ ((packed)) IOAPIC_ROUTE_ENTRY, *PIOAPIC_ROUTE_ENTRY;
typedef struct _IOAPIC_INFO
{
ULONG ApicId; /* APIC ID */
ULONG ApicVersion; /* APIC version */
ULONG ApicAddress; /* APIC address */
ULONG EntryCount; /* Number of redirection entries */
} IOAPIC_INFO, *PIOAPIC_INFO;
/*
* Local APIC timer IRQ vector is on a different priority level,
* to work around the 'lost local interrupt if more than 2 IRQ
* sources per level' errata.
*/
#define LOCAL_TIMER_VECTOR 0xEF
#define CALL_FUNCTION_VECTOR 0xFB
#define RESCHEDULE_VECTOR 0xFC
#define INVALIDATE_TLB_VECTOR 0xFD
#define ERROR_VECTOR 0xFE
#define SPURIOUS_VECTOR 0xFF /* Must be 0xXF */
/*
* First APIC vector available to drivers: (vectors 0x30-0xEE)
* we start at 0x31 to spread out vectors evenly between priority
* levels.
*/
#define FIRST_DEVICE_VECTOR 0x31
#define FIRST_SYSTEM_VECTOR 0xEF
#define NUMBER_DEVICE_VECTORS (FIRST_SYSTEM_VECTOR - FIRST_DEVICE_VECTOR)
/* MP Floating Pointer Structure */
#define MPF_SIGNATURE (('_' << 24) | ('P' << 16) | ('M' << 8) | '_')
typedef struct __attribute__((packed)) _MP_FLOATING_POINTER
{
ULONG Signature[4]; /* _MP_ */
ULONG Address; /* Physical Address Pointer (0 means no configuration table exist) */
UCHAR Length; /* Structure length in 16-byte paragraphs */
UCHAR Specification; /* Specification revision */
UCHAR Checksum; /* Checksum */
UCHAR Feature1; /* MP System Configuration Type */
UCHAR Feature2; /* Bit 7 set for IMCR|PIC */
UCHAR Feature3; /* Unused (0) */
UCHAR Feature4; /* Unused (0) */
UCHAR Feature5; /* Unused (0) */
} MP_FLOATING_POINTER, *PMP_FLOATING_POINTER;
#define FEATURE2_IMCRP 0x80
/* MP Configuration Table Header */
#define MPC_SIGNATURE (('P' << 24) | ('M' << 16) | ('C' << 8) | 'P')
typedef struct __attribute__((packed)) _MP_CONFIGURATION_TABLE
{
ULONG Signature[4]; /* PCMP */
USHORT Length; /* Size of configuration table */
CHAR Specification; /* Specification Revision */
CHAR Checksum; /* Checksum */
CHAR Oem[8]; /* OEM ID */
CHAR ProductId[12]; /* Product ID */
ULONG OemTable; /* 0 if not present */
USHORT OemTableSize; /* 0 if not present */
USHORT EntryCount; /* Number of entries */
ULONG LocalAPICAddress; /* Local APIC address */
USHORT ExtTableLength; /* Extended Table Length */
UCHAR ExtTableChecksum; /* Extended Table Checksum */
UCHAR Reserved; /* Reserved */
} MP_CONFIGURATION_TABLE, *PMP_CONFIGURATION_TABLE;
/* MP Configuration Table Entries */
#define MPCTE_PROCESSOR 0 /* One entry per processor */
#define MPCTE_BUS 1 /* One entry per bus */
#define MPCTE_IOAPIC 2 /* One entry per I/O APIC */
#define MPCTE_INTSRC 3 /* One entry per bus interrupt source */
#define MPCTE_LINTSRC 4 /* One entry per system interrupt source */
typedef struct __attribute__((packed)) _MP_CONFIGURATION_PROCESSOR
{
UCHAR Type; /* 0 */
UCHAR ApicId; /* Local APIC ID for the processor */
UCHAR ApicVersion; /* Local APIC version */
UCHAR CpuFlags; /* CPU flags */
ULONG CpuSignature; /* CPU signature */
ULONG FeatureFlags; /* CPUID feature value */
ULONG Reserved[2]; /* Reserved (0) */
} MP_CONFIGURATION_PROCESSOR, *PMP_CONFIGURATION_PROCESSOR;
#define CPU_FLAG_ENABLED 1 /* Processor is available */
#define CPU_FLAG_BSP 2 /* Processor is the bootstrap processor */
#define CPU_STEPPING_MASK 0x0F
#define CPU_MODEL_MASK 0xF0
#define CPU_FAMILY_MASK 0xF00
typedef struct __attribute__((packed)) _MP_CONFIGURATION_BUS
{
UCHAR Type; /* 1 */
UCHAR BusId; /* Bus ID */
UCHAR BusType[6]; /* Bus type */
} MP_CONFIGURATION_BUS, *PMP_CONFIGURATION_BUS;
#define MAX_BUS 32
#define MP_BUS_ISA 1
#define MP_BUS_EISA 2
#define MP_BUS_PCI 3
#define MP_BUS_MCA 4
#define BUSTYPE_EISA "EISA"
#define BUSTYPE_ISA "ISA"
#define BUSTYPE_INTERN "INTERN" /* Internal BUS */
#define BUSTYPE_MCA "MCA"
#define BUSTYPE_VL "VL" /* Local bus */
#define BUSTYPE_PCI "PCI"
#define BUSTYPE_PCMCIA "PCMCIA"
#define BUSTYPE_CBUS "CBUS"
#define BUSTYPE_CBUSII "CBUSII"
#define BUSTYPE_FUTURE "FUTURE"
#define BUSTYPE_MBI "MBI"
#define BUSTYPE_MBII "MBII"
#define BUSTYPE_MPI "MPI"
#define BUSTYPE_MPSA "MPSA"
#define BUSTYPE_NUBUS "NUBUS"
#define BUSTYPE_TC "TC"
#define BUSTYPE_VME "VME"
#define BUSTYPE_XPRESS "XPRESS"
typedef struct __attribute__((packed)) _MP_CONFIGURATION_IOAPIC
{
UCHAR Type; /* 2 */
UCHAR ApicId; /* I/O APIC ID */
UCHAR ApicVersion; /* I/O APIC version */
UCHAR ApicFlags; /* I/O APIC flags */
ULONG ApicAddress; /* I/O APIC base address */
} MP_CONFIGURATION_IOAPIC, *PMP_CONFIGURATION_IOAPIC;
#define MAX_IOAPIC 2
#define MP_IOAPIC_USABLE 0x01
typedef struct __attribute__((packed)) _MP_CONFIGURATION_INTSRC
{
UCHAR Type; /* 3 */
UCHAR IrqType; /* Interrupt type */
USHORT IrqFlag; /* Interrupt flags */
UCHAR SrcBusId; /* Source bus ID */
UCHAR SrcBusIrq; /* Source bus interrupt */
UCHAR DstApicId; /* Destination APIC ID */
UCHAR DstApicInt; /* Destination interrupt */
} MP_CONFIGURATION_INTSRC, *PMP_CONFIGURATION_INTSRC;
#define MAX_IRQ_SOURCE 128
#define INT_VECTORED 0
#define INT_NMI 1
#define INT_SMI 2
#define INT_EXTINT 3
#define IRQDIR_DEFAULT 0
#define IRQDIR_HIGH 1
#define IRQDIR_LOW 3
typedef struct __attribute__((packed)) _MP_CONFIGURATION_INTLOCAL
{
UCHAR Type; /* 4 */
UCHAR IrqType; /* Interrupt type */
USHORT IrqFlag; /* Interrupt flags */
UCHAR SrcBusId; /* Source bus ID */
UCHAR SrcBusIrq; /* Source bus interrupt */
UCHAR DstApicId; /* Destination local APIC ID */
UCHAR DstApicLInt; /* Destination local APIC interrupt */
} MP_CONFIGURATION_INTLOCAL, *PMP_CONFIGURATION_INTLOCAL;
#define MP_APIC_ALL 0xFF
static inline VOID ReadPentiumClock(PULARGE_INTEGER Count)
{
register ULONG nLow;
register ULONG nHigh;
__asm__ __volatile__ ("rdtsc" : "=a" (nLow), "=d" (nHigh));
Count->u.LowPart = nLow;
Count->u.HighPart = nHigh;
}
#define MAX_CPU 32
typedef struct _CPU_INFO
{
UCHAR Flags; /* CPU flags */
UCHAR APICId; /* Local APIC ID */
UCHAR APICVersion; /* Local APIC version */
UCHAR MaxLVT; /* Number of LVT registers */
ULONG BusSpeed; /* BUS speed */
ULONG CoreSpeed; /* Core speed */
UCHAR Padding[16-12]; /* Padding to 16-byte */
} CPU_INFO, *PCPU_INFO;
/* CPU flags */
#define CPU_USABLE 0x01 /* 1 if the CPU is usable (ie. can be used) */
#define CPU_ENABLED 0x02 /* 1 if the CPU is enabled */
#define CPU_BSP 0x04 /* 1 if the CPU is the bootstrap processor */
typedef enum {
amPIC = 0, /* IMCR and PIC compatibility mode */
amVWIRE /* Virtual Wire compatibility mode */
} APIC_MODE;
#define pushfl(x) __asm__ __volatile__("pushfl ; popl %0":"=g" (x): /* no input */)
#define popfl(x) __asm__ __volatile__("pushl %0 ; popfl": /* no output */ :"g" (x):"memory")
#define PIC_IRQS 16
/* Prototypes */
VOID HalpInitMPS(VOID);
volatile ULONG IOAPICRead(ULONG Apic, ULONG Offset);
VOID IOAPICWrite(ULONG Apic, ULONG Offset, ULONG Value);
VOID IOAPICMaskIrq(ULONG Apic, ULONG Irq);
VOID IOAPICUnmaskIrq(ULONG Apic, ULONG Irq);
volatile inline ULONG APICRead(ULONG Offset);
inline VOID APICWrite(ULONG Offset, ULONG Value);
inline VOID APICSendEOI(VOID);
inline ULONG ThisCPU(VOID);
VOID APICSendIPI(ULONG Target,
ULONG DeliveryMode,
ULONG IntNum,
ULONG Level);
/* For debugging */
VOID IOAPICDump(VOID);
VOID APICDump(VOID);
#endif /* __INCLUDE_HAL_MPS */

View file

@ -172,6 +172,7 @@ VOID KeInitDispatcher(VOID);
VOID KeInitializeDispatcher(VOID); VOID KeInitializeDispatcher(VOID);
VOID KeInitializeTimerImpl(VOID); VOID KeInitializeTimerImpl(VOID);
VOID KeInitializeBugCheck(VOID); VOID KeInitializeBugCheck(VOID);
VOID Phase1Initialization(PVOID Context);
VOID KeInit1(VOID); VOID KeInit1(VOID);
VOID KeInit2(VOID); VOID KeInit2(VOID);

View file

@ -27,11 +27,11 @@
/* /*
* Defines a descriptor as it appears in the processor tables * Defines a descriptor as it appears in the processor tables
*/ */
typedef struct typedef struct _DESCRIPTOR
{ {
unsigned int a; ULONG a;
unsigned int b; ULONG b;
} IDT_DESCRIPTOR, GDT_DESCRIPTOR; } __attribute__ ((packed)) IDT_DESCRIPTOR, GDT_DESCRIPTOR;
extern IDT_DESCRIPTOR KiIdt[256]; extern IDT_DESCRIPTOR KiIdt[256];
//extern GDT_DESCRIPTOR KiGdt[256]; //extern GDT_DESCRIPTOR KiGdt[256];

View file

@ -40,9 +40,10 @@
#define KPROCESS_PAGE_TABLE_DIRECTORY 0x10 #define KPROCESS_PAGE_TABLE_DIRECTORY 0x10
#define KPCR_BASE 0xFFDFF000 #define KPCR_BASE 0xFF000000
#define KPCR_EXCEPTION_LIST 0x0 #define KPCR_EXCEPTION_LIST 0x0
#define KPCR_SELF 0x18
#define KPCR_CURRENT_THREAD 0x124 #define KPCR_CURRENT_THREAD 0x124
#ifndef __ASM__ #ifndef __ASM__
@ -52,6 +53,10 @@
struct _KTHREAD; struct _KTHREAD;
struct _KTRAPFRAME; struct _KTRAPFRAME;
/* FIXME: This does not work if we have more than 24 IRQs (ie. more than one I/O APIC) */
#define VECTOR2IRQ(vector) (((vector) - 0x31) / 8)
#define VECTOR2IRQL(vector) (4 + VECTOR2IRQ(vector))
/* /*
* Processor Control Region * Processor Control Region
*/ */
@ -64,11 +69,29 @@ typedef struct _KPCR
PVOID Reserved1; /* 10 */ PVOID Reserved1; /* 10 */
PVOID ArbitraryUserPointer; /* 14 */ PVOID ArbitraryUserPointer; /* 14 */
struct _KPCR* Self; /* 18 */ struct _KPCR* Self; /* 18 */
UCHAR Reserved2[0x108]; /* 1C */ UCHAR ProcessorNumber; /* 1C */
KIRQL Irql; /* 1D */
UCHAR Reserved2[0x2]; /* 1E */
PUSHORT IDT; /* 20 */
PUSHORT GDT; /* 24 */
UCHAR Reserved3[0xFC]; /* 28 */
struct _KTHREAD* CurrentThread; /* 124 */ struct _KTHREAD* CurrentThread; /* 124 */
} KPCR, *PKPCR; } __attribute__((packed)) KPCR, *PKPCR;
#define CURRENT_KPCR ((PKPCR)KPCR_BASE) static inline PKPCR KeGetCurrentKPCR(VOID)
{
ULONG value;
__asm__ __volatile__ ("movl %%fs:0x18, %0\n\t"
: "=r" (value)
: /* no inputs */
);
return((PKPCR)value);
}
#define CURRENT_KPCR KeGetCurrentKPCR()
#define KeGetCurrentProcessorNumber (KeGetCurrentKPCR()->ProcessorNumber)
extern HANDLE SystemProcessHandle; extern HANDLE SystemProcessHandle;

View file

@ -1,4 +1,4 @@
/* $Id: cntrller.c,v 1.6 2001/03/26 05:03:54 phreak Exp $ /* $Id: cntrller.c,v 1.7 2001/04/13 16:12:25 chorns Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel

View file

@ -42,7 +42,7 @@ USHORT KiGdt[11 * 4] =
0x0, 0x0, 0xfa00, 0xcc, /* User CS */ 0x0, 0x0, 0xfa00, 0xcc, /* User CS */
0x0, 0x0, 0xf200, 0xcc, /* User DS */ 0x0, 0x0, 0xf200, 0xcc, /* User DS */
0x0, 0x0, 0x0, 0x0, /* TSS */ 0x0, 0x0, 0x0, 0x0, /* TSS */
0x1000, 0xf000, 0x92df, 0xff00, /* PCR */ 0x1000, 0x0000, 0x9200, 0xff00, /* PCR */
0x1000, 0x0, 0xf200, 0x0, /* TEB */ 0x1000, 0x0, 0xf200, 0x0, /* TEB */
0x0, 0x0, 0x0, 0x0, /* Reserved */ 0x0, 0x0, 0x0, 0x0, /* Reserved */
0x0, 0x0, 0x0, 0x0, /* LDT */ 0x0, 0x0, 0x0, 0x0, /* LDT */

View file

@ -1,4 +1,4 @@
/* $Id: irq.c,v 1.8 2001/03/16 16:05:34 dwelch Exp $ /* $Id: irq.c,v 1.9 2001/04/13 16:12:26 chorns Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -19,17 +19,114 @@
/* INCLUDES ****************************************************************/ /* INCLUDES ****************************************************************/
#include <ddk/ntddk.h> #include <ddk/ntddk.h>
#include <internal/config.h>
#include <internal/ke.h> #include <internal/ke.h>
#include <internal/ps.h> #include <internal/ps.h>
#include <internal/i386/segment.h> #include <internal/i386/segment.h>
#include <internal/pool.h> #include <internal/pool.h>
#ifdef MP
#include <internal/hal/mps.h>
#endif /* MP */
#define NDEBUG #define NDEBUG
#include <internal/debug.h> #include <internal/debug.h>
/* GLOBALS *****************************************************************/ /* GLOBALS *****************************************************************/
#ifdef MP
#define IRQ_BASE FIRST_DEVICE_VECTOR
#define NR_IRQS 0x100 - 0x30
#define __STR(x) #x
#define STR(x) __STR(x)
#define INT_NAME(intnum) _KiUnexpectedInterrupt##intnum
#define INT_NAME2(intnum) KiUnexpectedInterrupt##intnum
#define BUILD_COMMON_INTERRUPT_HANDLER() \
__asm__( \
"_KiCommonInterrupt:\n\t" \
"cld\n\t" \
"pushl %ds\n\t" \
"pushl %es\n\t" \
"pushl %fs\n\t" \
"pushl %gs\n\t" \
"movl $0xceafbeef,%eax\n\t" \
"pushl %eax\n\t" \
"movl $" STR(KERNEL_DS) ",%eax\n\t" \
"movl %eax,%ds\n\t" \
"movl %eax,%es\n\t" \
"movl $" STR(PCR_SELECTOR) ",%eax\n\t" \
"movl %eax,%fs\n\t" \
"pushl %esp\n\t" \
"pushl %ebx\n\t" \
"call _KiInterruptDispatch\n\t" \
"popl %eax\n\t" \
"popl %eax\n\t" \
"popl %eax\n\t" \
"popl %gs\n\t" \
"popl %fs\n\t" \
"popl %es\n\t" \
"popl %ds\n\t" \
"popa\n\t" \
"iret\n\t");
#define BUILD_INTERRUPT_HANDLER(intnum) \
VOID INT_NAME2(intnum)(VOID); \
__asm__( \
STR(INT_NAME(intnum)) ":\n\t" \
"pusha\n\t" \
"movl $0x" STR(intnum) ",%ebx\n\t" \
"jmp _KiCommonInterrupt");
/* Interrupt handlers and declarations */
#define B(x,y) \
BUILD_INTERRUPT_HANDLER(x##y)
#define B16(x) \
B(x,0) B(x,1) B(x,2) B(x,3) \
B(x,4) B(x,5) B(x,6) B(x,7) \
B(x,8) B(x,9) B(x,A) B(x,B) \
B(x,C) B(x,D) B(x,E) B(x,F)
BUILD_COMMON_INTERRUPT_HANDLER()
B16(3) B16(4) B16(5) B16(6)
B16(7) B16(8) B16(9) B16(A)
B16(B) B16(C) B16(D) B16(E)
B16(F)
#undef B;
#undef B16;
/* Interrupt handler list */
#define L(x,y) \
(ULONG)&##INT_NAME2(x##y)
#define L16(x) \
L(x,0), L(x,1), L(x,2), L(x,3), \
L(x,4), L(x,5), L(x,6), L(x,7), \
L(x,8), L(x,9), L(x,A), L(x,B), \
L(x,C), L(x,D), L(x,E), L(x,F)
static ULONG irq_handler[NR_IRQS] = {
L16(3), L16(4), L16(5), L16(6),
L16(7), L16(8), L16(9), L16(A),
L16(B), L16(C), L16(D), L16(E),
L16(F)
};
#undef L;
#undef L16;
#else /* MP */
#define NR_IRQS (16) #define NR_IRQS (16)
#define IRQ_BASE (0x40) #define IRQ_BASE (0x40)
@ -70,6 +167,8 @@ static unsigned int irq_handler[NR_IRQS]=
(int)&irq_handler_15, (int)&irq_handler_15,
}; };
#endif /* MP */
/* /*
* PURPOSE: Object describing each isr * PURPOSE: Object describing each isr
* NOTE: The data in this table is only modified at passsive level but can * NOTE: The data in this table is only modified at passsive level but can
@ -92,7 +191,20 @@ VOID KeInitInterrupts (VOID)
{ {
int i; int i;
DPRINT("KeInitInterrupts ()\n",0); #ifdef MP
/*
* Setup the IDT entries to point to the interrupt handlers
*/
for (i=0;i<NR_IRQS;i++)
{
KiIdt[0x30+i].a=(irq_handler[i]&0xffff)+(KERNEL_CS<<16);
KiIdt[0x30+i].b=(irq_handler[i]&0xffff0000)+PRESENT+
I486_INTERRUPT_GATE;
InitializeListHead(&isr_table[i]);
}
#else
/* /*
* Setup the IDT entries to point to the interrupt handlers * Setup the IDT entries to point to the interrupt handlers
@ -104,6 +216,9 @@ VOID KeInitInterrupts (VOID)
I486_INTERRUPT_GATE; I486_INTERRUPT_GATE;
InitializeListHead(&isr_table[i]); InitializeListHead(&isr_table[i]);
} }
#endif
} }
typedef struct _KIRQ_TRAPFRAME typedef struct _KIRQ_TRAPFRAME
@ -125,6 +240,95 @@ typedef struct _KIRQ_TRAPFRAME
ULONG Eflags; ULONG Eflags;
} KIRQ_TRAPFRAME, *PKIRQ_TRAPFRAME; } KIRQ_TRAPFRAME, *PKIRQ_TRAPFRAME;
#ifdef MP
VOID
KiInterruptDispatch (ULONG Vector, PKIRQ_TRAPFRAME Trapframe)
/*
* FUNCTION: Calls the irq specific handler for an irq
* ARGUMENTS:
* Vector = Interrupt vector
* Trapframe = CPU context
*/
{
KIRQL old_level;
PKINTERRUPT isr;
PLIST_ENTRY current;
ULONG irq;
DPRINT("I(%d) ", Vector);
/*
* Notify the rest of the kernel of the raised irq level
*/
HalBeginSystemInterrupt (Vector,
VECTOR2IRQL(Vector),
&old_level);
irq = VECTOR2IRQ(Vector);
/*
* Enable interrupts
* NOTE: Only higher priority interrupts will get through
*/
__asm__("sti\n\t");
DPRINT("KiInterruptDispatch(Vector %d)\n", Vector);
/*
* Iterate the list until one of the isr tells us its device interrupted
*/
current = isr_table[irq].Flink;
isr = CONTAINING_RECORD(current,KINTERRUPT,Entry);
//DPRINT("current %x isr %x\n",current,isr);
while (current!=(&isr_table[irq]) &&
!isr->ServiceRoutine(isr,isr->ServiceContext))
{
current = current->Flink;
isr = CONTAINING_RECORD(current,KINTERRUPT,Entry);
//DPRINT("current %x isr %x\n",current,isr);
}
/*
* Disable interrupts
*/
__asm__("cli\n\t");
/*
* Unmask the related irq
*/
HalEnableSystemInterrupt (Vector, 0, 0);
/*
* If the processor level will drop below dispatch level on return then
* issue a DPC queue drain interrupt
*/
if (old_level < DISPATCH_LEVEL)
{
HalEndSystemInterrupt (DISPATCH_LEVEL, 0);
__asm__("sti\n\t");
if (KeGetCurrentThread() != NULL)
{
KeGetCurrentThread()->LastEip = Trapframe->Eip;
}
KiDispatchInterrupt();
if (KeGetCurrentThread() != NULL &&
KeGetCurrentThread()->Alerted[1] != 0 &&
Trapframe->Cs != KERNEL_CS)
{
HalEndSystemInterrupt (APC_LEVEL, 0);
KiDeliverNormalApc();
}
}
HalEndSystemInterrupt (old_level, 0);
}
#else /* MP */
VOID VOID
KiInterruptDispatch (ULONG irq, PKIRQ_TRAPFRAME Trapframe) KiInterruptDispatch (ULONG irq, PKIRQ_TRAPFRAME Trapframe)
/* /*
@ -137,8 +341,6 @@ KiInterruptDispatch (ULONG irq, PKIRQ_TRAPFRAME Trapframe)
PKINTERRUPT isr; PKINTERRUPT isr;
PLIST_ENTRY current; PLIST_ENTRY current;
// DbgPrint("{");
/* /*
* Notify the rest of the kernel of the raised irq level * Notify the rest of the kernel of the raised irq level
*/ */
@ -214,6 +416,7 @@ KiInterruptDispatch (ULONG irq, PKIRQ_TRAPFRAME Trapframe)
HalEndSystemInterrupt (old_level, 0); HalEndSystemInterrupt (old_level, 0);
} }
#endif /* MP */
static VOID static VOID
KeDumpIrqList(VOID) KeDumpIrqList(VOID)

View file

@ -45,42 +45,31 @@ ULONG KiPcrInitDone = 0;
VOID VOID
KeInit1(VOID) KeInit1(VOID)
{ {
PKPCR KPCR;
extern USHORT KiGdt[];
KiCheckFPU(); KiCheckFPU();
KeInitExceptions (); KeInitExceptions ();
KeInitInterrupts (); KeInitInterrupts ();
/* Initialize the initial PCR region. We can't allocate a page
with MmAllocPage() here because MmInit1() has not yet been
called, so we use a predefined page in low memory */
KPCR = (PKPCR)KPCR_BASE;
memset(KPCR, 0, PAGESIZE);
KPCR->Self = (PKPCR)KPCR_BASE;
KPCR->Irql = HIGH_LEVEL;
KPCR->GDT = (PUSHORT)&KiGdt;
KPCR->IDT = (PUSHORT)&KiIdt;
KiPcrInitDone = 1;
} }
VOID VOID
KeInit2(VOID) KeInit2(VOID)
{ {
PVOID PcrPage;
KeInitDpc(); KeInitDpc();
KeInitializeBugCheck(); KeInitializeBugCheck();
KeInitializeDispatcher(); KeInitializeDispatcher();
KeInitializeTimerImpl(); KeInitializeTimerImpl();
/*
* Initialize the PCR region.
* FIXME: This should be per-processor.
*/
PcrPage = MmAllocPage(0);
if (PcrPage == NULL)
{
DPRINT1("No memory for PCR page\n");
KeBugCheck(0);
}
MmCreateVirtualMapping(NULL,
(PVOID)KPCR_BASE,
PAGE_READWRITE,
(ULONG)PcrPage);
memset((PVOID)KPCR_BASE, 0, 4096);
KiPcrInitDone = 1;
} }

View file

@ -1,3 +1,4 @@
#include <internal/config.h>
#include <internal/ntoskrnl.h> #include <internal/ntoskrnl.h>
#include <internal/i386/segment.h> #include <internal/i386/segment.h>
@ -9,6 +10,11 @@
#define V2P(x) (x - 0xc0000000 + 0x200000) #define V2P(x) (x - 0xc0000000 + 0x200000)
#ifdef MP
#define AP_MAGIC (0x12481020)
#endif /* MP */
.globl _NtProcessStartup .globl _NtProcessStartup
.globl _start .globl _start
@ -19,12 +25,15 @@
.globl _unmap_me .globl _unmap_me
.globl _unmap_me2 .globl _unmap_me2
.globl _unmap_me3 .globl _unmap_me3
.globl _unmap_me4
/* /*
* This is called by the realmode loader, with protected mode * This is called by the realmode loader, with protected mode
* enabled, paging disabled and the segment registers pointing * enabled, paging disabled and the segment registers pointing
* a 4Gb, 32-bit segment starting at zero. * a 4Gb, 32-bit segment starting at zero.
* *
* EAX = Multiboot magic or application processor magic
*
* EBX = Points to a structure in lowmem with data from the * EBX = Points to a structure in lowmem with data from the
* loader * loader
*/ */
@ -65,6 +74,18 @@ _multiboot_entry:
*/ */
cld cld
#ifdef MP
/*
* Save the multiboot or application processor magic
*/
movl %eax, %edx
cmpl $AP_MAGIC, %edx
je .m1
#endif /* MP */
/* /*
* Zero the BSS * Zero the BSS
*/ */
@ -87,6 +108,10 @@ _multiboot_entry:
movl $(V2P(kernel_pagetable) + 0x7), 0xC00(%esi) movl $(V2P(kernel_pagetable) + 0x7), 0xC00(%esi)
movl $(V2P(lowmem_pagetable) + 0x7), 0xD00(%esi) movl $(V2P(lowmem_pagetable) + 0x7), 0xD00(%esi)
movl $(V2P(startup_pagedirectory) + 0x7), 0xF00(%esi) movl $(V2P(startup_pagedirectory) + 0x7), 0xF00(%esi)
#ifdef MP
movl $(V2P(apic_pagetable) + 0x7), 0xFEC(%esi)
#endif /* MP */
movl $(V2P(kpcr_pagetable) + 0x7), 0xFF0(%esi)
/* /*
* Initialize the page table that maps low memory * Initialize the page table that maps low memory
@ -114,6 +139,39 @@ _multiboot_entry:
cmpl $2048, %edi cmpl $2048, %edi
jl .l4 jl .l4
#ifdef MP
/*
* Initialize the page table that maps the APIC register address space
*/
/* FIXME: APIC register address space can be non-standard so do the mapping later */
movl $V2P(apic_pagetable), %esi
movl $0, %edi
movl $0xFEC0001B, %eax
movl %eax, (%esi, %edi)
movl $0x800, %edi
movl $0xFEE0001B, %eax
movl %eax, (%esi, %edi)
#endif /* MP */
/*
* Initialize the page table that maps the initial KPCR (at FF000000)
*/
movl $V2P(kpcr_pagetable), %esi
movl $0, %edi
movl $0x1007, %eax
movl %eax, (%esi, %edi)
#ifdef MP
.m1:
#endif /* MP */
/* /*
* Set up the PDBR * Set up the PDBR
*/ */
@ -138,6 +196,9 @@ _multiboot_entry:
* Load the GDTR and IDTR with new tables located above * Load the GDTR and IDTR with new tables located above
* 0xc0000000 * 0xc0000000
*/ */
/* FIXME: Application processors should have their own GDT/IDT */
lgdt _KiGdtDescriptor lgdt _KiGdtDescriptor
lidt _KiIdtDescriptor lidt _KiIdtDescriptor
@ -147,9 +208,37 @@ _multiboot_entry:
movl $KERNEL_DS, %eax movl $KERNEL_DS, %eax
movl %eax, %ds movl %eax, %ds
movl %eax, %es movl %eax, %es
movl %eax, %fs
movl %eax, %gs movl %eax, %gs
movl %eax, %ss movl %eax, %ss
movl $PCR_SELECTOR, %eax
movl %eax, %fs
#ifdef MP
cmpl $AP_MAGIC, %edx
jne .m2
/*
* This is an application processor executing
*/
/*
* Initialize EFLAGS
*/
pushl $0
popfl
/*
* Call the application processor initialization code
*/
pushl $0
pushl $KERNEL_CS
pushl $_KiSystemStartup
lret
.m2:
#endif /* MP */
/* /*
* Load the initial ring0 stack * Load the initial ring0 stack
@ -186,6 +275,14 @@ lowmem_pagetable:
kernel_pagetable: kernel_pagetable:
.fill 4096, 1, 0 .fill 4096, 1, 0
#ifdef MP
apic_pagetable:
.fill 4096, 1, 0
#endif /* MP */
kpcr_pagetable:
.fill 4096, 1, 0
_unmap_me: _unmap_me:
.fill 4096, 1, 0 .fill 4096, 1, 0
@ -202,5 +299,3 @@ _trap_stack_top:
_unmap_me3: _unmap_me3:
.fill 4096, 1, 0 .fill 4096, 1, 0

View file

@ -71,10 +71,16 @@ _Ki386ContextSwitch:
addl $8, %esp addl $8, %esp
popl %ebx popl %ebx
/*
* Load the PCR selector
*/
movl $PCR_SELECTOR, %eax
movl %eax, %fs
/* /*
* Set the current thread information in the PCR * Set the current thread information in the PCR
*/ */
movl %ebx, (KPCR_BASE + KPCR_CURRENT_THREAD) movl %ebx, %fs:KPCR_CURRENT_THREAD
/* /*
* FIXME: Save debugging state. * FIXME: Save debugging state.
@ -105,12 +111,6 @@ _Ki386ContextSwitch:
movl KPROCESS_PAGE_TABLE_DIRECTORY(%ebx), %eax movl KPROCESS_PAGE_TABLE_DIRECTORY(%ebx), %eax
movl %eax, %cr3 movl %eax, %cr3
/*
* Load the PCR selector
*/
movl $PCR_SELECTOR, %eax
movl %eax, %fs
/* /*
* FIXME: Restore floating point state * FIXME: Restore floating point state
*/ */

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
/* $Id: main.c,v 1.86 2001/04/10 17:48:17 dwelch Exp $ /* $Id: main.c,v 1.87 2001/04/13 16:12:25 chorns Exp $
* *
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
* FILE: ntoskrnl/ke/main.c * FILE: ntoskrnl/ke/main.c
@ -29,6 +29,7 @@
/* INCLUDES *****************************************************************/ /* INCLUDES *****************************************************************/
#include <ddk/ntddk.h> #include <ddk/ntddk.h>
#include <internal/config.h>
#include <internal/ntoskrnl.h> #include <internal/ntoskrnl.h>
#include <reactos/resource.h> #include <reactos/resource.h>
#include <internal/mm.h> #include <internal/mm.h>
@ -52,11 +53,15 @@
ULONG EXPORTED NtBuildNumber = KERNEL_VERSION_BUILD; ULONG EXPORTED NtBuildNumber = KERNEL_VERSION_BUILD;
ULONG EXPORTED NtGlobalFlag = 0; ULONG EXPORTED NtGlobalFlag = 0;
CHAR EXPORTED KeNumberProcessors = 1; CHAR EXPORTED KeNumberProcessors;
LOADER_PARAMETER_BLOCK EXPORTED KeLoaderBlock; LOADER_PARAMETER_BLOCK EXPORTED KeLoaderBlock;
static LOADER_MODULE KeLoaderModules[64]; static LOADER_MODULE KeLoaderModules[64];
static UCHAR KeLoaderModuleStrings[64][256]; static UCHAR KeLoaderModuleStrings[64][256];
static UCHAR KeLoaderCommandLine[256]; static UCHAR KeLoaderCommandLine[256];
static ULONG FirstKrnlPhysAddr;
static ULONG LastKrnlPhysAddr;
static ULONG LastKernelAddress;
volatile BOOLEAN Initialized = FALSE;
/* FUNCTIONS ****************************************************************/ /* FUNCTIONS ****************************************************************/
@ -378,123 +383,193 @@ InitSystemSharedUserPage (PCSZ ParameterLine)
KeBugCheck (0x0); KeBugCheck (0x0);
} }
} }
#if 0
VOID
TestV86Mode(VOID)
{
ULONG i;
extern UCHAR OrigIVT[1024];
KV86M_REGISTERS regs;
NTSTATUS Status;
struct vesa_info* vi;
for (i = 0; i < (640 / 4); i++)
{
MmCreateVirtualMapping(NULL,
(PVOID)(i * 4096),
PAGE_EXECUTE_READWRITE,
(ULONG)MmAllocPage(0));
}
for (; i < (1024 / 4); i++)
{
MmCreateVirtualMapping(NULL,
(PVOID)(i * 4096),
PAGE_EXECUTE_READ,
i * 4096);
}
vi = (struct vesa_info*)0x20000;
vi->Signature[0] = 'V';
vi->Signature[1] = 'B';
vi->Signature[2] = 'E';
vi->Signature[3] = '2';
memset(&regs, 0, sizeof(regs));
regs.Eax = 0x4F00;
regs.Es = 0x2000;
regs.Edi = 0x0;
memcpy((PVOID)0x0, OrigIVT, 1024);
Status = Ke386CallBios(0x10, &regs);
DbgPrint("Finished (Status %x, CS:EIP %x:%x)\n", Status, regs.Cs,
regs.Eip);
DbgPrint("Eax %x\n", regs.Eax);
DbgPrint("Signature %.4s\n", vi->Signature);
DbgPrint("TotalVideoMemory %dKB\n", vi->TotalVideoMemory * 64);
}
#endif
VOID VOID
_main (ULONG MultiBootMagic, PLOADER_PARAMETER_BLOCK _LoaderBlock) ExpInitializeExecutive(VOID)
/*
* FUNCTION: Called by the boot loader to start the kernel
* ARGUMENTS:
* LoaderBlock = Pointer to boot parameters initialized by the boot
* loader
* NOTE: The boot parameters are stored in low memory which will become
* invalid after the memory managment is initialized so we make a local copy.
*/
{ {
ULONG i;
ULONG last_kernel_address;
ULONG start;
PCHAR name;
extern ULONG _bss_end__;
/*
* Copy the parameters to a local buffer because lowmem will go away
*/
memcpy (&KeLoaderBlock, _LoaderBlock, sizeof(LOADER_PARAMETER_BLOCK));
memcpy (&KeLoaderModules[1], (PVOID)KeLoaderBlock.ModsAddr,
sizeof(LOADER_MODULE) * KeLoaderBlock.ModsCount);
KeLoaderBlock.ModsCount++;
KeLoaderBlock.ModsAddr = (ULONG)&KeLoaderModules;
/*
* FIXME: Preliminary hack!!!! Add boot device to beginning of command line.
* This should be done by the boot loader.
*/
strcpy (KeLoaderCommandLine,
"multi(0)disk(0)rdisk(0)partition(1)\\reactos ");
strcat (KeLoaderCommandLine, (PUCHAR)KeLoaderBlock.CommandLine);
KeLoaderBlock.CommandLine = (ULONG)KeLoaderCommandLine;
strcpy(KeLoaderModuleStrings[0], "ntoskrnl.exe");
KeLoaderModules[0].String = (ULONG)KeLoaderModuleStrings[0];
KeLoaderModules[0].ModStart = 0xC0000000;
KeLoaderModules[0].ModEnd = PAGE_ROUND_UP((ULONG)&_bss_end__);
for (i = 1; i < KeLoaderBlock.ModsCount; i++)
{
strcpy(KeLoaderModuleStrings[i], (PUCHAR)KeLoaderModules[i].String);
KeLoaderModules[i].ModStart -= 0x200000;
KeLoaderModules[i].ModStart += 0xc0000000;
KeLoaderModules[i].ModEnd -= 0x200000;
KeLoaderModules[i].ModEnd += 0xc0000000;
KeLoaderModules[i].String = (ULONG)KeLoaderModuleStrings[i];
}
/* /*
* Initialization phase 0 * Initialization phase 0
*/ */
HalInitSystem (0, (PLOADER_PARAMETER_BLOCK)&KeLoaderBlock); HalInitSystem (0, (PLOADER_PARAMETER_BLOCK)&KeLoaderBlock);
KeInit1();
LdrInit1(); /* Execute executive initialization code on bootstrap processor only */
KeLowerIrql(DISPATCH_LEVEL); if (!Initialized)
{
Initialized = TRUE;
DPRINT("Phase 0 initialization started...\n");
/*
* Fail at runtime if someone has changed various structures without
* updating the offsets used for the assembler code.
*/
assert(FIELD_OFFSET(KTHREAD, InitialStack) == KTHREAD_INITIAL_STACK);
assert(FIELD_OFFSET(KTHREAD, Teb) == KTHREAD_TEB);
assert(FIELD_OFFSET(KTHREAD, KernelStack) == KTHREAD_KERNEL_STACK);
assert(FIELD_OFFSET(KTHREAD, PreviousMode) == KTHREAD_PREVIOUS_MODE);
assert(FIELD_OFFSET(KTHREAD, TrapFrame) == KTHREAD_TRAP_FRAME);
assert(FIELD_OFFSET(ETHREAD, ThreadsProcess) == ETHREAD_THREADS_PROCESS);
assert(FIELD_OFFSET(KPROCESS, PageTableDirectory) ==
KPROCESS_PAGE_TABLE_DIRECTORY);
assert(FIELD_OFFSET(KTRAP_FRAME, Reserved9) == KTRAP_FRAME_RESERVED9);
assert(FIELD_OFFSET(KV86M_TRAP_FRAME, regs) == TF_REGS);
assert(FIELD_OFFSET(KV86M_TRAP_FRAME, orig_ebp) == TF_ORIG_EBP);
assert(FIELD_OFFSET(KPCR, ExceptionList) == KPCR_EXCEPTION_LIST);
assert(FIELD_OFFSET(KPCR, Self) == KPCR_SELF);
assert(FIELD_OFFSET(KPCR, CurrentThread) == KPCR_CURRENT_THREAD);
LdrInit1();
KeLowerIrql(DISPATCH_LEVEL);
NtEarlyInitVdm();
MmInit1(FirstKrnlPhysAddr, LastKrnlPhysAddr, LastKernelAddress);
/*
* Initialize the kernel debugger
*/
KdInitSystem (0, (PLOADER_PARAMETER_BLOCK)&KeLoaderBlock);
if (KdPollBreakIn ())
{
DbgBreakPointWithStatus (DBG_STATUS_CONTROL_C);
}
MmInit2();
KeInit2();
{
char tmpbuf[80];
sprintf(tmpbuf,"System with %d/%d MB memory\n",
(unsigned int)(KeLoaderBlock.MemLower)/1024,
(unsigned int)(KeLoaderBlock.MemHigher)/1024);
HalDisplayString(tmpbuf);
}
KeLowerIrql(PASSIVE_LEVEL);
ObInit();
PiInitProcessManager();
/*
* Allow interrupts
*/
__asm__ ("sti\n\t");
#ifdef MP
Phase1Initialization(NULL);
#endif
}
}
VOID
KiSystemStartup(VOID)
{
ExpInitializeExecutive();
for (;;)
{
NtYieldExecution();
}
}
/* Initialization phase 1 */
VOID Phase1Initialization(PVOID Context)
{
ULONG i;
ULONG start;
PCHAR name;
CHAR str[50];
DPRINT("Initialization phase 1 started...\n");
/* /*
* Display version number and copyright/warranty message * Display version number and copyright/warranty message
*/ */
HalDisplayString("Starting ReactOS "KERNEL_VERSION_STR" (Build " HalDisplayString("Starting ReactOS "KERNEL_VERSION_STR" (Build "
KERNEL_VERSION_BUILD_STR")\n"); KERNEL_VERSION_BUILD_STR")\n");
HalDisplayString(RES_STR_LEGAL_COPYRIGHT); HalDisplayString(RES_STR_LEGAL_COPYRIGHT);
HalDisplayString("\n\nReactOS is free software, covered by the GNU General " HalDisplayString("\n\nReactOS is free software, covered by the GNU General "
"Public License, and you\n"); "Public License, and you\n");
HalDisplayString("are welcome to change it and/or distribute copies of it " HalDisplayString("are welcome to change it and/or distribute copies of it "
"under certain\n"); "under certain\n");
HalDisplayString("conditions. There is absolutely no warranty for ReactOS.\n"); HalDisplayString("conditions. There is absolutely no warranty for ReactOS.\n");
/* /* Initialize all processors */
* Fail at runtime if someone has changed various structures without KeNumberProcessors = 0;
* updating the offsets used for the assembler code
*/
assert(FIELD_OFFSET(KTHREAD, InitialStack) == KTHREAD_INITIAL_STACK);
assert(FIELD_OFFSET(KTHREAD, Teb) == KTHREAD_TEB);
assert(FIELD_OFFSET(KTHREAD, KernelStack) == KTHREAD_KERNEL_STACK);
assert(FIELD_OFFSET(KTHREAD, PreviousMode) == KTHREAD_PREVIOUS_MODE);
assert(FIELD_OFFSET(KTHREAD, TrapFrame) == KTHREAD_TRAP_FRAME);
assert(FIELD_OFFSET(ETHREAD, ThreadsProcess) == ETHREAD_THREADS_PROCESS);
assert(FIELD_OFFSET(KPROCESS, PageTableDirectory) ==
KPROCESS_PAGE_TABLE_DIRECTORY);
assert(FIELD_OFFSET(KTRAP_FRAME, Reserved9) == KTRAP_FRAME_RESERVED9);
assert(FIELD_OFFSET(KV86M_TRAP_FRAME, regs) == TF_REGS);
assert(FIELD_OFFSET(KV86M_TRAP_FRAME, orig_ebp) == TF_ORIG_EBP);
last_kernel_address = KeLoaderModules[KeLoaderBlock.ModsCount - 1].ModEnd; while (!HalAllProcessorsStarted())
{
HalInitializeProcessor(
KeNumberProcessors);
KeNumberProcessors++;
}
NtEarlyInitVdm(); if (KeNumberProcessors > 1)
MmInit1(KeLoaderModules[0].ModStart - 0xc0000000 + 0x200000, {
last_kernel_address - 0xc0000000 + 0x200000, sprintf(str, "Found %d system processors.\n",
last_kernel_address); KeNumberProcessors);
}
else
{
strcpy(str, "Found 1 system processor.\n");
}
HalDisplayString(str);
/* #ifdef MP
* Initialize the kernel debugger
*/
KdInitSystem (0, (PLOADER_PARAMETER_BLOCK)&KeLoaderBlock);
if (KdPollBreakIn ())
{
DbgBreakPointWithStatus (DBG_STATUS_CONTROL_C);
}
/* DbgPrint("BSP halted\n");
* Initialization phase 1 for (;;);
* Initalize various critical subsystems
*/ #endif /* MP */
/*
* Initialize various critical subsystems
*/
HalInitSystem (1, (PLOADER_PARAMETER_BLOCK)&KeLoaderBlock); HalInitSystem (1, (PLOADER_PARAMETER_BLOCK)&KeLoaderBlock);
MmInit2();
KeInit2();
/*
* Allow interrupts
*/
KeLowerIrql(PASSIVE_LEVEL);
ObInit();
PiInitProcessManager();
ExInit(); ExInit();
IoInit(); IoInit();
LdrInitModuleManagement(); LdrInitModuleManagement();
@ -542,10 +617,34 @@ _main (ULONG MultiBootMagic, PLOADER_PARAMETER_BLOCK _LoaderBlock)
DPRINT1("process module '%s' at %08lx\n", name, start); DPRINT1("process module '%s' at %08lx\n", name, start);
LdrProcessDriver((PVOID)start, name); LdrProcessDriver((PVOID)start, name);
} }
}
DPRINT("About to try MmAllocateContiguousAlignedMemory\n");
do
{
extern PVOID STDCALL
MmAllocateContiguousAlignedMemory(IN ULONG NumberOfBytes,
IN PHYSICAL_ADDRESS HighestAcceptableAddress,
IN ULONG Alignment);
PVOID v;
PHYSICAL_ADDRESS p;
p.QuadPart = 16*1024*1024;
v = MmAllocateContiguousAlignedMemory(12*1024, p,
64*1024);
if (v != NULL)
{
DPRINT("Worked\n");
}
else
{
DPRINT("Failed\n");
}
} }
while (0);
/* Create the SystemRoot symbolic link */ /* Create the SystemRoot symbolic link */
DbgPrint("CommandLine: %s\n", (PUCHAR)KeLoaderBlock.CommandLine); DbgPrint("CommandLine: %s\n", (PUCHAR)KeLoaderBlock.CommandLine);
CreateSystemRootLink ((PUCHAR)KeLoaderBlock.CommandLine); CreateSystemRootLink ((PUCHAR)KeLoaderBlock.CommandLine);
#ifdef DBGPRINT_FILE_LOG #ifdef DBGPRINT_FILE_LOG
@ -554,6 +653,7 @@ _main (ULONG MultiBootMagic, PLOADER_PARAMETER_BLOCK _LoaderBlock)
DebugLogInit2(); DebugLogInit2();
#endif /* DBGPRINT_FILE_LOG */ #endif /* DBGPRINT_FILE_LOG */
CmInitializeRegistry2(); CmInitializeRegistry2();
/* /*
@ -580,9 +680,76 @@ _main (ULONG MultiBootMagic, PLOADER_PARAMETER_BLOCK _LoaderBlock)
*/ */
LdrLoadInitialProcess(); LdrLoadInitialProcess();
DbgPrint("Finished main()\n"); DbgPrint("Finished kernel initialization.\n");
/* FIXME: Call zero page thread function */
PsTerminateSystemThread(STATUS_SUCCESS); PsTerminateSystemThread(STATUS_SUCCESS);
} }
VOID
_main (ULONG MultiBootMagic, PLOADER_PARAMETER_BLOCK _LoaderBlock)
/*
* FUNCTION: Called by the boot loader to start the kernel
* ARGUMENTS:
* LoaderBlock = Pointer to boot parameters initialized by the boot
* loader
* NOTE: The boot parameters are stored in low memory which will become
* invalid after the memory managment is initialized so we make a local copy.
*/
{
ULONG i;
ULONG last_kernel_address;
extern ULONG _bss_end__;
/*
* Copy the parameters to a local buffer because lowmem will go away
*/
memcpy (&KeLoaderBlock, _LoaderBlock, sizeof(LOADER_PARAMETER_BLOCK));
memcpy (&KeLoaderModules[1], (PVOID)KeLoaderBlock.ModsAddr,
sizeof(LOADER_MODULE) * KeLoaderBlock.ModsCount);
KeLoaderBlock.ModsCount++;
KeLoaderBlock.ModsAddr = (ULONG)&KeLoaderModules;
/*
* FIXME: Preliminary hack!!!! Add boot device to beginning of command line.
* This should be done by the boot loader.
*/
strcpy (KeLoaderCommandLine,
"multi(0)disk(0)rdisk(0)partition(1)\\reactos /DEBUGPORT=SCREEN");
strcat (KeLoaderCommandLine, (PUCHAR)KeLoaderBlock.CommandLine);
KeLoaderBlock.CommandLine = (ULONG)KeLoaderCommandLine;
strcpy(KeLoaderModuleStrings[0], "ntoskrnl.exe");
KeLoaderModules[0].String = (ULONG)KeLoaderModuleStrings[0];
KeLoaderModules[0].ModStart = 0xC0000000;
KeLoaderModules[0].ModEnd = PAGE_ROUND_UP((ULONG)&_bss_end__);
for (i = 1; i < KeLoaderBlock.ModsCount; i++)
{
strcpy(KeLoaderModuleStrings[i], (PUCHAR)KeLoaderModules[i].String);
KeLoaderModules[i].ModStart -= 0x200000;
KeLoaderModules[i].ModStart += 0xc0000000;
KeLoaderModules[i].ModEnd -= 0x200000;
KeLoaderModules[i].ModEnd += 0xc0000000;
KeLoaderModules[i].String = (ULONG)KeLoaderModuleStrings[i];
}
last_kernel_address = KeLoaderModules[KeLoaderBlock.ModsCount - 1].ModEnd;
FirstKrnlPhysAddr = KeLoaderModules[0].ModStart - 0xc0000000 + 0x200000;
LastKrnlPhysAddr = last_kernel_address - 0xc0000000 + 0x200000;
LastKernelAddress = last_kernel_address;
KeInit1();
#if 0
/*
* Allow interrupts
*/
__asm__ ("sti\n\t");
#endif
KiSystemStartup();
}
/* EOF */ /* EOF */

View file

@ -1,4 +1,4 @@
/* $Id: timer.c,v 1.43 2001/03/18 19:35:13 dwelch Exp $ /* $Id: timer.c,v 1.44 2001/04/13 16:12:25 chorns Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -125,7 +125,7 @@ NTSTATUS STDCALL NtDelayExecution(IN ULONG Alertable,
Alertable, Internal, Timeout); Alertable, Internal, Timeout);
DPRINT("Execution delay is %d/%d\n", DPRINT("Execution delay is %d/%d\n",
Timeout.u.Highpart, Timeout.u.LowPart); Timeout.u.HighPart, Timeout.u.LowPart);
Status = KeDelayExecutionThread(UserMode, Alertable, &Timeout); Status = KeDelayExecutionThread(UserMode, Alertable, &Timeout);
return(Status); return(Status);
} }
@ -462,17 +462,12 @@ KeInitializeTimerImpl(VOID)
{ {
TIME_FIELDS TimeFields; TIME_FIELDS TimeFields;
LARGE_INTEGER SystemBootTime; LARGE_INTEGER SystemBootTime;
extern VOID HalpCalibrateStallExecution (VOID);
DPRINT("KeInitializeTimerImpl()\n"); DPRINT("KeInitializeTimerImpl()\n");
HalpCalibrateStallExecution ();
InitializeListHead(&TimerListHead); InitializeListHead(&TimerListHead);
KeInitializeSpinLock(&TimerListLock); KeInitializeSpinLock(&TimerListLock);
KeInitializeDpc(&ExpireTimerDpc, KeExpireTimers, 0); KeInitializeDpc(&ExpireTimerDpc, KeExpireTimers, 0);
TimerInitDone = TRUE; TimerInitDone = TRUE;
/* /*
* Calculate the starting time for the system clock * Calculate the starting time for the system clock
*/ */

View file

@ -193,7 +193,15 @@ PVOID MmInitializePageList(PVOID FirstPhysKernelAddress,
InsertTailList(&BiosPageListHead, InsertTailList(&BiosPageListHead,
&MmPageArray[0].ListEntry); &MmPageArray[0].ListEntry);
i = 1; /*
* Page one is reserved for the initial KPCR
*/
MmPageArray[1].Flags = MM_PHYSICAL_PAGE_BIOS;
MmPageArray[1].ReferenceCount = 0;
InsertTailList(&BiosPageListHead,
&MmPageArray[1].ListEntry);
i = 2;
if ((ULONG)FirstPhysKernelAddress < 0xa0000) if ((ULONG)FirstPhysKernelAddress < 0xa0000)
{ {
MmStats.NrFreePages += (((ULONG)FirstPhysKernelAddress/PAGESIZE) - 1); MmStats.NrFreePages += (((ULONG)FirstPhysKernelAddress/PAGESIZE) - 1);

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
/* $Id: page.c,v 1.25 2001/03/26 20:46:53 dwelch Exp $ /* $Id: page.c,v 1.26 2001/04/13 16:12:26 chorns Exp $
* *
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
* FILE: ntoskrnl/mm/i386/page.c * FILE: ntoskrnl/mm/i386/page.c
@ -589,11 +589,20 @@ MmCreateVirtualMappingUnsafe(PEPROCESS Process,
ULONG flProtect, ULONG flProtect,
ULONG PhysicalAddress) ULONG PhysicalAddress)
{ {
PEPROCESS CurrentProcess = PsGetCurrentProcess(); PEPROCESS CurrentProcess;
ULONG Attributes = 0; ULONG Attributes;
PULONG Pte; PULONG Pte;
NTSTATUS Status; NTSTATUS Status;
if (Process != NULL)
{
CurrentProcess = PsGetCurrentProcess();
}
else
{
CurrentProcess = NULL;
}
if (Process == NULL && Address < (PVOID)KERNEL_BASE) if (Process == NULL && Address < (PVOID)KERNEL_BASE)
{ {
DPRINT1("No process\n"); DPRINT1("No process\n");
@ -652,11 +661,12 @@ MmCreateVirtualMapping(PEPROCESS Process,
ULONG flProtect, ULONG flProtect,
ULONG PhysicalAddress) ULONG PhysicalAddress)
{ {
if (!MmIsUsablePage((PVOID)PhysicalAddress)) if (!MmIsUsablePage((PVOID)PhysicalAddress))
{ {
DPRINT1("Page not usable\n"); DPRINT1("Page at address %x not usable\n", PhysicalAddress);
KeBugCheck(0); KeBugCheck(0);
} }
return(MmCreateVirtualMappingUnsafe(Process, return(MmCreateVirtualMappingUnsafe(Process,
Address, Address,
flProtect, flProtect,
@ -693,8 +703,10 @@ MmSetPageProtect(PEPROCESS Process, PVOID Address, ULONG flProtect)
PULONG PageEntry; PULONG PageEntry;
PEPROCESS CurrentProcess = PsGetCurrentProcess(); PEPROCESS CurrentProcess = PsGetCurrentProcess();
Attributes = ProtectToPTE(flProtect); DPRINT("MmSetPageProtect(Process %x Address %x flProtect %x)\n",
Process, Address, flProtect);
Attributes = ProtectToPTE(flProtect);
if (Process != CurrentProcess) if (Process != CurrentProcess)
{ {
KeAttachProcess(Process); KeAttachProcess(Process);

View file

@ -1,4 +1,4 @@
/* $Id: mminit.c,v 1.17 2001/03/28 14:24:05 dwelch Exp $ /* $Id: mminit.c,v 1.18 2001/04/13 16:12:26 chorns Exp $
* *
* COPYRIGHT: See COPYING in the top directory * COPYRIGHT: See COPYING in the top directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -12,6 +12,7 @@
/* INCLUDES *****************************************************************/ /* INCLUDES *****************************************************************/
#include <ddk/ntddk.h> #include <ddk/ntddk.h>
#include <internal/config.h>
#include <internal/i386/segment.h> #include <internal/i386/segment.h>
#include <internal/mm.h> #include <internal/mm.h>
#include <internal/ntoskrnl.h> #include <internal/ntoskrnl.h>
@ -31,7 +32,7 @@
#define EXTENDED_MEMORY_SIZE (3*1024*1024) #define EXTENDED_MEMORY_SIZE (3*1024*1024)
/* /*
* Compiler defined symbol s * Compiler defined symbols
*/ */
extern unsigned int _text_start__; extern unsigned int _text_start__;
extern unsigned int _text_end__; extern unsigned int _text_end__;
@ -79,7 +80,7 @@ VOID MmInitVirtualMemory(ULONG LastKernelAddress,
ULONG ParamLength = KernelLength; ULONG ParamLength = KernelLength;
NTSTATUS Status; NTSTATUS Status;
DPRINT("MmInitVirtualMemory(%x)\n",bp); DPRINT("MmInitVirtualMemory(%x, %x)\n",LastKernelAddress, KernelLength);
LastKernelAddress = PAGE_ROUND_UP(LastKernelAddress); LastKernelAddress = PAGE_ROUND_UP(LastKernelAddress);
@ -102,7 +103,6 @@ VOID MmInitVirtualMemory(ULONG LastKernelAddress,
0, 0,
&kernel_text_desc, &kernel_text_desc,
FALSE); FALSE);
Length = PAGE_ROUND_UP(((ULONG)&_bss_end__)) - Length = PAGE_ROUND_UP(((ULONG)&_bss_end__)) -
PAGE_ROUND_UP(((ULONG)&_text_end__)); PAGE_ROUND_UP(((ULONG)&_text_end__));
ParamLength = ParamLength - Length; ParamLength = ParamLength - Length;
@ -151,6 +151,7 @@ VOID MmInitVirtualMemory(ULONG LastKernelAddress,
0, 0,
&kernel_shared_data_desc, &kernel_shared_data_desc,
FALSE); FALSE);
MmSharedDataPagePhysicalAddress = MmAllocPage(0); MmSharedDataPagePhysicalAddress = MmAllocPage(0);
Status = MmCreateVirtualMapping(NULL, Status = MmCreateVirtualMapping(NULL,
(PVOID)KERNEL_SHARED_DATA_BASE, (PVOID)KERNEL_SHARED_DATA_BASE,
@ -176,10 +177,14 @@ VOID MmInit1(ULONG FirstKrnlPhysAddr,
{ {
ULONG i; ULONG i;
ULONG kernel_len; ULONG kernel_len;
#ifndef MP
extern unsigned int unmap_me, unmap_me2, unmap_me3; extern unsigned int unmap_me, unmap_me2, unmap_me3;
#endif
DPRINT("MmInit1(bp %x, LastKernelAddress %x)\n", bp, DPRINT("MmInit1(FirstKrnlPhysAddr, %x, LastKrnlPhysAddr %x, LastKernelAddress %x)\n",
LastKernelAddress); FirstKrnlPhysAddr,
LastKrnlPhysAddr,
LastKernelAddress);
/* /*
* FIXME: Set this based on the system command line * FIXME: Set this based on the system command line
@ -209,8 +214,10 @@ VOID MmInit1(ULONG FirstKrnlPhysAddr,
/* /*
* Unmap low memory * Unmap low memory
*/ */
#ifndef MP
/* FIXME: This is broken in SMP mode */
MmDeletePageTable(NULL, 0); MmDeletePageTable(NULL, 0);
#endif
/* /*
* Free all pages not used for kernel memory * Free all pages not used for kernel memory
* (we assume the kernel occupies a continuous range of physical * (we assume the kernel occupies a continuous range of physical
@ -247,30 +254,31 @@ VOID MmInit1(ULONG FirstKrnlPhysAddr,
* segment * segment
*/ */
CHECKPOINT; CHECKPOINT;
DPRINT("stext %x etext %x\n",(int)&stext,(int)&etext); DPRINT("_text_start__ %x _text_end__ %x\n",(int)&_text_start__,(int)&_text_end__);
for (i=PAGE_ROUND_UP(((int)&_text_start__)); for (i=PAGE_ROUND_UP(((int)&_text_start__));
i<PAGE_ROUND_DOWN(((int)&_text_end__));i=i+PAGESIZE) i<PAGE_ROUND_DOWN(((int)&_text_end__));i=i+PAGESIZE)
{ {
MmSetPageProtect(NULL, MmSetPageProtect(NULL,
(PVOID)i, (PVOID)i,
PAGE_EXECUTE_READ); PAGE_EXECUTE_READ);
} }
DPRINT("Invalidating between %x and %x\n", DPRINT("Invalidating between %x and %x\n",
LastKernelAddress, LastKernelAddress,
KERNEL_BASE + PAGE_TABLE_SIZE); KERNEL_BASE + PAGE_TABLE_SIZE);
for (i=(LastKernelAddress); for (i=(LastKernelAddress);
i<(KERNEL_BASE + PAGE_TABLE_SIZE); i<(KERNEL_BASE + PAGE_TABLE_SIZE);
i=i+PAGESIZE) i=i+PAGESIZE)
{ {
MmDeleteVirtualMapping(NULL, (PVOID)(i), FALSE, NULL, NULL); MmDeleteVirtualMapping(NULL, (PVOID)(i), FALSE, NULL, NULL);
} }
DPRINT("Almost done MmInit()\n"); DPRINT("Almost done MmInit()\n");
#ifndef MP
/* FIXME: This is broken in SMP mode */
MmDeleteVirtualMapping(NULL, (PVOID)&unmap_me, FALSE, NULL, NULL); MmDeleteVirtualMapping(NULL, (PVOID)&unmap_me, FALSE, NULL, NULL);
MmDeleteVirtualMapping(NULL, (PVOID)&unmap_me2, FALSE, NULL, NULL); MmDeleteVirtualMapping(NULL, (PVOID)&unmap_me2, FALSE, NULL, NULL);
MmDeleteVirtualMapping(NULL, (PVOID)&unmap_me3, FALSE, NULL, NULL); MmDeleteVirtualMapping(NULL, (PVOID)&unmap_me3, FALSE, NULL, NULL);
#endif
/* /*
* Intialize memory areas * Intialize memory areas
*/ */

View file

@ -1,4 +1,4 @@
/* $Id: psmgr.c,v 1.7 2000/06/03 21:36:32 ekohl Exp $ /* $Id: psmgr.c,v 1.8 2001/04/13 16:12:26 chorns Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -10,6 +10,7 @@
/* INCLUDES **************************************************************/ /* INCLUDES **************************************************************/
#include <ddk/ntddk.h> #include <ddk/ntddk.h>
#include <internal/ke.h>
#include <internal/ps.h> #include <internal/ps.h>
#include <reactos/version.h> #include <reactos/version.h>
@ -26,10 +27,32 @@ VOID PiShutdownProcessManager(VOID)
VOID PiInitProcessManager(VOID) VOID PiInitProcessManager(VOID)
{ {
#ifndef MP
HANDLE Phase1InitializationHandle;
NTSTATUS Status;
#endif
PsInitProcessManagment(); PsInitProcessManagment();
PsInitThreadManagment(); PsInitThreadManagment();
PsInitIdleThread(); PsInitIdleThread();
PiInitApcManagement(); PiInitApcManagement();
#ifndef MP
/* Create thread for Phase1Initialization */
Status = PsCreateSystemThread(
&Phase1InitializationHandle, /* Thread handle */
0, /* Desired access */
NULL, /* Object attributes */
NULL, /* Process handle */
NULL, /* Client id */
(PKSTART_ROUTINE)Phase1Initialization, /* Start routine */
NULL); /* Start context */
if (!NT_SUCCESS(Status)) {
DPRINT1("Could not create system thread (Status 0x%X)\n", Status);
KeBugCheck(0);
}
ZwClose(Phase1InitializationHandle);
#endif
} }