- Convert all Loader Block structures to virtual addresses (By adding KSEG0_BASE) since the kernel eventually unmaps the page table responsible for the physical->virtual identity mapping, but we'll still need to access the loader block.

- Implement proper trap prolog/epilog code -- currently used and tested in the data abort handler. Currently hacked away some KTRAP_FRAME stuff on ARM.
- The data abort handler has a very rudimentary check to detect page faults and will call MmAccessFaults, this means we now support paged pool!
- We now succesfully go past MmInitSystem and go all the way until ObInitSystem (still in Phase 0).


svn path=/trunk/; revision=32659
This commit is contained in:
ReactOS Portable Systems Group
2008-03-11 16:13:43 +00:00
parent f5402d88df
commit a31f9d1367
6 changed files with 220 additions and 34 deletions
+83 -8
View File
@@ -30,6 +30,7 @@ CHAR ArmArcBootPath[64];
CHAR ArmArcHalPath[64];
CHAR ArmNtHalPath[64];
CHAR ArmNtBootPath[64];
WCHAR ArmModuleName[64];
PNLS_DATA_BLOCK ArmNlsDataBlock;
PLOADER_PARAMETER_EXTENSION ArmExtension;
BIOS_MEMORY_DESCRIPTOR ArmBoardMemoryDescriptors[16] = {{0}};
@@ -1042,7 +1043,7 @@ ArmSetupPagingAndJump(IN ULONG Magic)
//
// Jump to Kernel
//
(*KernelEntryPoint)(Magic, (PVOID)ArmLoaderBlock);
(*KernelEntryPoint)(Magic, (PVOID)((ULONG_PTR)ArmLoaderBlock | KSEG0_BASE));
}
VOID
@@ -1054,6 +1055,7 @@ ArmPrepareForReactOS(IN BOOLEAN Setup)
NTSTATUS Status;
ULONG Dummy, i;
PLDR_DATA_TABLE_ENTRY LdrEntry;
PLIST_ENTRY NextEntry, OldEntry;
//
// Allocate the ARM Shared Heap
@@ -1080,7 +1082,7 @@ ArmPrepareForReactOS(IN BOOLEAN Setup)
//
// Setup the extension and setup block
//
ArmLoaderBlock->Extension = ArmExtension;
ArmLoaderBlock->Extension = (PVOID)((ULONG_PTR)ArmExtension | KSEG0_BASE);
ArmLoaderBlock->SetupLdrBlock = NULL;
//
@@ -1223,6 +1225,7 @@ ArmPrepareForReactOS(IN BOOLEAN Setup)
//
// Setup loader entry for the kernel
//
wcscpy(ArmModuleName, L"ntoskrnl.exe");
LdrEntry = ArmAllocateFromSharedHeap(sizeof(LDR_DATA_TABLE_ENTRY));
RtlZeroMemory(LdrEntry, sizeof(LDR_DATA_TABLE_ENTRY));
LdrEntry->DllBase = (PVOID)KernelBase;
@@ -1230,6 +1233,10 @@ ArmPrepareForReactOS(IN BOOLEAN Setup)
LdrEntry->EntryPoint = KernelEntryPoint;
LdrEntry->LoadCount = 1;
LdrEntry->Flags = LDRP_IMAGE_DLL | LDRP_ENTRY_PROCESSED;
RtlInitUnicodeString(&LdrEntry->FullDllName, ArmModuleName);
RtlInitUnicodeString(&LdrEntry->BaseDllName, ArmModuleName);
LdrEntry->FullDllName.Buffer = (PVOID)((ULONG_PTR)LdrEntry->FullDllName.Buffer | KSEG0_BASE);
LdrEntry->BaseDllName.Buffer = (PVOID)((ULONG_PTR)LdrEntry->BaseDllName.Buffer | KSEG0_BASE);
InsertTailList(&ArmLoaderBlock->LoadOrderListHead, &LdrEntry->InLoadOrderLinks);
//
@@ -1253,6 +1260,36 @@ ArmPrepareForReactOS(IN BOOLEAN Setup)
if (Status != STATUS_SUCCESS) return;
}
//
// Loop driver list
//
NextEntry = ArmLoaderBlock->LoadOrderListHead.Flink;
while (NextEntry != &ArmLoaderBlock->LoadOrderListHead)
{
//
// Remember the physical entry
//
OldEntry = NextEntry->Flink;
//
// Edit the data
//
NextEntry->Flink = (PVOID)((ULONG_PTR)NextEntry->Flink | KSEG0_BASE);
NextEntry->Blink = (PVOID)((ULONG_PTR)NextEntry->Blink | KSEG0_BASE);
//
// Keep looping
//
NextEntry = OldEntry;
}
//
// Now edit the root itself
//
NextEntry->Flink = (PVOID)((ULONG_PTR)NextEntry->Flink | KSEG0_BASE);
NextEntry->Blink = (PVOID)((ULONG_PTR)NextEntry->Blink | KSEG0_BASE);
//
// Setup extension parameters
//
@@ -1276,7 +1313,7 @@ ArmPrepareForReactOS(IN BOOLEAN Setup)
// Set the ARC Boot Path
//
strncpy(ArmArcBootPath, ArmCommandLine, 63);
ArmLoaderBlock->ArcBootDeviceName = ArmArcBootPath;
ArmLoaderBlock->ArcBootDeviceName = (PVOID)((ULONG_PTR)ArmArcBootPath | KSEG0_BASE);
//
// The rest of the string is the NT path
@@ -1286,23 +1323,32 @@ ArmPrepareForReactOS(IN BOOLEAN Setup)
ArmNtBootPath[0] = '\\';
strncat(ArmNtBootPath, BootPath + 1, 63);
strcat(ArmNtBootPath,"\\");
ArmLoaderBlock->NtBootPathName = ArmNtBootPath;
ArmLoaderBlock->NtBootPathName = (PVOID)((ULONG_PTR)ArmNtBootPath | KSEG0_BASE);
//
// Set the HAL paths
//
strncpy(ArmArcHalPath, ArmArcBootPath, 63);
ArmLoaderBlock->ArcHalDeviceName = ArmArcHalPath;
ArmLoaderBlock->ArcHalDeviceName = (PVOID)((ULONG_PTR)ArmArcHalPath | KSEG0_BASE);
strcpy(ArmNtHalPath, "\\");
ArmLoaderBlock->NtHalPathName = ArmNtHalPath;
ArmLoaderBlock->NtHalPathName = (PVOID)((ULONG_PTR)ArmNtHalPath | KSEG0_BASE);
/* Use this new command line */
//
// Use this new command line
//
strncpy(ArmLoaderBlock->LoadOptions, HalPath + 2, 255);
/* Parse it and change every slash to a space */
//
// Parse it and change every slash to a space
//
BootPath = ArmLoaderBlock->LoadOptions;
do {if (*BootPath == '/') *BootPath = ' ';} while (*BootPath++);
//
// Fixup command-line pointer
//
ArmLoaderBlock->LoadOptions = (PVOID)((ULONG_PTR)ArmLoaderBlock->LoadOptions | KSEG0_BASE);
//
// Setup cache information
//
@@ -1412,6 +1458,35 @@ ArmPrepareForReactOS(IN BOOLEAN Setup)
ArmLoaderBlock->Prcb = KSEG0_BASE | (ULONG)Base;
ArmLoaderBlock->Process = ArmLoaderBlock->Prcb + sizeof(KPRCB);
ArmLoaderBlock->Thread = ArmLoaderBlock->Process + sizeof(EPROCESS);
//
// Loop memory list
//
NextEntry = ArmLoaderBlock->MemoryDescriptorListHead.Flink;
while (NextEntry != &ArmLoaderBlock->MemoryDescriptorListHead)
{
//
// Remember the physical entry
//
OldEntry = NextEntry->Flink;
//
// Edit the data
//
NextEntry->Flink = (PVOID)((ULONG_PTR)NextEntry->Flink | KSEG0_BASE);
NextEntry->Blink = (PVOID)((ULONG_PTR)NextEntry->Blink | KSEG0_BASE);
//
// Keep looping
//
NextEntry = OldEntry;
}
//
// Now edit the root itself
//
NextEntry->Flink = (PVOID)((ULONG_PTR)NextEntry->Flink | KSEG0_BASE);
NextEntry->Blink = (PVOID)((ULONG_PTR)NextEntry->Blink | KSEG0_BASE);
}
VOID
+11 -10
View File
@@ -59,6 +59,7 @@ Author:
//
typedef struct _KTRAP_FRAME
{
ULONG Spsr;
ULONG R0;
ULONG R1;
ULONG R2;
@@ -72,17 +73,17 @@ typedef struct _KTRAP_FRAME
ULONG R10;
ULONG R11;
ULONG R12;
ULONG Sp;
ULONG Lr;
ULONG UserSp;
ULONG UserLr;
ULONG SvcSp;
ULONG SvcLr;
ULONG Pc;
ULONG Psr;
UCHAR ExceptionRecord[(sizeof(EXCEPTION_RECORD) + 7) & (~7)];
UCHAR OldIrql;
UCHAR PreviousMode;
ULONG Fpscr;
ULONG FpExc;
ULONG S[33];
ULONG FpExtra[8];
// UCHAR OldIrql;
// UCHAR PreviousMode;
// ULONG Fpscr;
// ULONG FpExc;
// ULONG S[33];
// ULONG FpExtra[8];
} KTRAP_FRAME, *PKTRAP_FRAME;
#ifndef NTOS_MODE_USER
@@ -29,6 +29,24 @@ KeArmIdCodeRegisterGet(VOID)
return Value;
}
FORCEINLINE
ULONG
KeArmFaultStatusRegisterGet(VOID)
{
ULONG Value;
__asm__ __volatile__ ("mrc p15, 0, %0, c5, c0, 0" : "=r"(Value) : : "cc");
return Value;
}
FORCEINLINE
ULONG
KeArmFaultAddressRegisterGet(VOID)
{
ULONG Value;
__asm__ __volatile__ ("mrc p15, 0, %0, c6, c0, 0" : "=r"(Value) : : "cc");
return Value;
}
FORCEINLINE
ARM_LOCKDOWN_REGISTER
KeArmLockdownRegisterGet(VOID)
@@ -9,6 +9,7 @@
.equ CPSR_SVC_MODE, 0x13
.equ CPSR_ABORT_MODE, 0x17
.equ CPSR_UND_MODE, 0x1B
.equ CPSR_MODES, 0x1F
/*
+90 -15
View File
@@ -62,32 +62,107 @@
NESTED_ENTRY KiDataAbortException
PROLOG_END KiDataAbortException
//
// Save space for trap frame
//
sub sp, #TrapFrameLength
//
// Build the register part of the trap frame
//
stm sp, {r0-r15}
//
// TOOD: We'll worry about the rest later...
// Fixup lr
//
sub lr, lr, #8
//
// Save the bottom 4 registers
//
stmdb sp, {r0-r3}
//
// Save the abort lr, sp, spsr, cpsr
//
mov r0, lr
mov r1, sp
mrs r2, cpsr
mrs r3, spsr
//
// Switch to SVC mode
//
bic r2, r2, #CPSR_MODES
orr r2, r2, #CPSR_SVC_MODE
msr cpsr_c, r2
//
// Save the SVC sp before we modify it
//
mov r2, sp
//
// Save the abort lr
//
str r0, [sp, #-4]!
//
// Save the SVC lr and sp
//
str lr, [sp, #-4]!
str r2, [sp, #-4]!
//
// Restore the saved SPSR
//
msr spsr_all, r3
//
// Restore our 4 registers
//
ldmdb r1, {r0-r3}
//
// Make space for the trap frame
//
sub sp, sp, #(4*15) // TrapFrameLength
//
// Save user-mode registers
//
stmia sp, {r0-r12}
add r0, sp, #(4*13)
stmia r0, {r13-r14}^
//
// Save SPSR
//
mrs r0, spsr_all
str r0, [sp, #-4]!
//
// Call the C handler
//
mov a1, sp
b KiDataAbortHandler
adr lr, AbortExit
mov r0, sp
ldr pc, =KiDataAbortHandler
AbortExit:
//
// Restore state
// Get the SPSR and restore it
//
b .
ldr r0, [sp], #4
msr spsr_all, r0
//
// Restore the registers
//
ldmia sp, {r0-r14}^
mov r0, r0
//
// Advance in the trap frame
//
add sp, sp, #(4*15)
//
// Restore program execution state
//
ldmia sp, {sp, lr, pc}^
b .
ENTRY_END KiDataAbortException
NESTED_ENTRY KiInterruptException
+17 -1
View File
@@ -19,7 +19,23 @@
NTSTATUS
KiDataAbortHandler(IN PKTRAP_FRAME TrapFrame)
{
DPRINT1("Data Abort (%p) @ %p\n", TrapFrame, TrapFrame->Lr - 8);
NTSTATUS Status;
PVOID Address = (PVOID)KeArmFaultAddressRegisterGet();
DPRINT1("Data Abort (%x) @ %p %p\n", Address, TrapFrame->SvcLr, TrapFrame->Pc);
DPRINT1("Abort Reason: %d\n", KeArmFaultStatusRegisterGet());
//
// Check if this is a page fault
//
if (KeArmFaultStatusRegisterGet() == 21)
{
Status = MmAccessFault(FALSE,
Address,
KernelMode,
TrapFrame);
DPRINT1("Status: %x\n", Status);
if (Status == STATUS_SUCCESS) return Status;
}
while (TRUE);
return STATUS_SUCCESS;