From e28048569a2051ec9728a5a6a80e6c91094516a4 Mon Sep 17 00:00:00 2001 From: ReactOS Portable Systems Group Date: Tue, 12 Feb 2008 18:34:33 +0000 Subject: [PATCH] Fixed some bugs in KeFillFixedEntryTb -- we actually needed to map the PTE into memory (then we can umap it). We were doing the initial PCR/PDR page allocation completely wrong since we're using 1MB section pages, not 4KB pages (this needs to be fixed later). Piggyhack arm_kprintf on top of DebugService which we now define. DPRINT1 and ASSERT now work! Send ARC paths and normalized command-line in the loader parameter block. Current state: FreeLoader v3.0 for ARM Bootargs: rdbase=0x2000000 rdsize=0x1400000 Detecting Hardware... Loading... Reading NTOSKRNL.EXE Reading BOOTVID.DLL Reading HAL.DLL Reading HAL.DLL Reading c_1252.nls Reading c_437.nls Reading l_intl.nls Reading scsiport.sys Reading atapi.sys Reading buslogic.sys Reading pci.sys Reading class2.sys Reading disk.sys Reading vfatfs.sys Reading ndis.sys Mapped serial port to 0xc00f1000 (ntoskrnl/ke/arm/kiinit.c:135) ----------------------------------------------------- (ntoskrnl/ke/arm/kiinit.c:136) ReactOS 0.4-SVN (Build 20080207-r32151) (ntoskrnl/ke/arm/kiinit.c:137) Command Line: DEBUG DEBUGPORT=COM1 BAUDRATE=115200 SOS (ntoskrnl/ke/arm/kiinit.c:138) ARC Paths: ramdisk(0) \ ramdisk(0) \ReactOS\ svn path=/trunk/; revision=32328 --- .../boot/freeldr/freeldr/arch/arm/loader.c | 69 +++++++++++++--- reactos/include/reactos/armddk.h | 3 +- .../ntoskrnl/include/internal/arm/intrin_i.h | 8 ++ reactos/ntoskrnl/include/internal/arm/ke.h | 4 +- reactos/ntoskrnl/ke/arm/kiinit.c | 78 +++++++++++++++++-- reactos/ntoskrnl/ke/arm/stubs_asm.s | 1 - 6 files changed, 143 insertions(+), 20 deletions(-) diff --git a/reactos/boot/freeldr/freeldr/arch/arm/loader.c b/reactos/boot/freeldr/freeldr/arch/arm/loader.c index 23809d39c16..ecbe87a7d8b 100644 --- a/reactos/boot/freeldr/freeldr/arch/arm/loader.c +++ b/reactos/boot/freeldr/freeldr/arch/arm/loader.c @@ -17,6 +17,11 @@ ULONG PageDirectoryStart, PageDirectoryEnd; LOADER_PARAMETER_BLOCK ArmLoaderBlock; +CHAR ArmCommandLine[256]; +CHAR ArmArcBootPath[64]; +CHAR ArmArcHalPath[64]; +CHAR ArmNtHalPath[64]; +CHAR ArmNtBootPath[64]; LOADER_PARAMETER_EXTENSION ArmExtension; extern ARM_TRANSLATION_TABLE ArmTranslationTable; extern ROS_KERNEL_ENTRY_POINT KernelEntryPoint; @@ -142,8 +147,13 @@ ArmSetupPagingAndJump(IN ULONG Magic) ControlRegister.ICacheEnabled = TRUE; ControlRegister.DCacheEnabled = TRUE; KeArmControlRegisterSet(ControlRegister); - - ArmBoardBlock->UartRegisterBase = UART_VIRTUAL | (ArmBoardBlock->UartRegisterBase & ((1<UartRegisterBase = UART_VIRTUAL | + (ArmBoardBlock->UartRegisterBase & + ((1 << TTB_SHIFT) - 1)); TuiPrintf("Mapped serial port to 0x%x\n", ArmBoardBlock->UartRegisterBase); // @@ -157,7 +167,8 @@ ArmPrepareForReactOS(IN BOOLEAN Setup) { ARM_CACHE_REGISTER CacheReg; PVOID Base; - + PCHAR BootPath, HalPath; + // // Initialize the loader block // @@ -196,10 +207,48 @@ ArmPrepareForReactOS(IN BOOLEAN Setup) // // - // Send the command line + // Make a copy of the command line // - ArmLoaderBlock.LoadOptions = reactos_kernel_cmdline; + ArmLoaderBlock.LoadOptions = ArmCommandLine; + strcpy(ArmCommandLine, reactos_kernel_cmdline); + // + // Find the first \, separating the ARC path from NT path + // + BootPath = strchr(ArmCommandLine, '\\'); + *BootPath = ANSI_NULL; + + // + // Set the ARC Boot Path + // + strncpy(ArmArcBootPath, ArmCommandLine, 63); + ArmLoaderBlock.ArcBootDeviceName = ArmArcBootPath; + + // + // The rest of the string is the NT path + // + HalPath = strchr(BootPath + 1, ' '); + *HalPath = ANSI_NULL; + ArmNtBootPath[0] = '\\'; + strncat(ArmNtBootPath, BootPath + 1, 63); + strcat(ArmNtBootPath,"\\"); + ArmLoaderBlock.NtBootPathName = ArmNtBootPath; + + // + // Set the HAL paths + // + strncpy(ArmArcHalPath, ArmArcBootPath, 63); + ArmLoaderBlock.ArcHalDeviceName = ArmArcHalPath; + strcpy(ArmNtHalPath, "\\"); + ArmLoaderBlock.NtHalPathName = ArmNtHalPath; + + /* Use this new command line */ + strncpy(ArmLoaderBlock.LoadOptions, HalPath + 2, 255); + + /* Parse it and change every slash to a space */ + BootPath = ArmLoaderBlock.LoadOptions; + do {if (*BootPath == '/') *BootPath = ' ';} while (*BootPath++); + // // Setup cache information // @@ -234,16 +283,17 @@ ArmPrepareForReactOS(IN BOOLEAN Setup) ArmLoaderBlock.u.Arm.PanicStack = KSEG0_BASE | (ULONG)Base; // - // Allocate the PCRs (1MB each for now!) + // Allocate the PCR page -- align it to 1MB (we only need 4KB) // Base = MmAllocateMemoryWithType(2 * 1024 * 1024, LoaderStartupPcrPage); + Base = (PVOID)ROUND_UP(Base, 1 * 1024 * 1024); ArmLoaderBlock.u.Arm.PcrPage = (ULONG)Base >> TTB_SHIFT; - ArmLoaderBlock.u.Arm.PcrPage2 = ArmLoaderBlock.u.Arm.PcrPage + 1; // - // Allocate PDR pages + // Allocate PDR pages -- align them to 1MB (we only need 3xKB) // - Base = MmAllocateMemoryWithType(3 * 1024 * 1024, LoaderStartupPdrPage); + Base = MmAllocateMemoryWithType(4 * 1024 * 1024, LoaderStartupPdrPage); + Base = (PVOID)ROUND_UP(Base, 1 * 1024 * 1024); ArmLoaderBlock.u.Arm.PdrPage = (ULONG)Base >> TTB_SHIFT; // @@ -274,6 +324,5 @@ FrLdrStartup(IN ULONG Magic) // // Initialize paging and load NTOSKRNL // - TuiPrintf("Kernel Command Line: %s\n", ArmLoaderBlock.LoadOptions); ArmSetupPagingAndJump(Magic); } diff --git a/reactos/include/reactos/armddk.h b/reactos/include/reactos/armddk.h index 8775eff5a5c..11449620999 100644 --- a/reactos/include/reactos/armddk.h +++ b/reactos/include/reactos/armddk.h @@ -46,7 +46,7 @@ typedef struct _KPCR { ULONG MinorVersion; ULONG MajorVersion; - PKINTERRUPT_ROUTINE InterruptRoutine[64]; + PKINTERRUPT_ROUTINE InterruptRoutine[16]; PVOID XcodeDispatch; ULONG FirstLevelDcacheSize; ULONG FirstLevelDcacheFillSize; @@ -71,6 +71,7 @@ typedef struct _KPCR PVOID DataBusError; PVOID InstructionBusError; ULONG CachePolicy; + ULONG AlignedCachePolicy; UCHAR IrqlMask[64]; UCHAR IrqlTable[64]; UCHAR CurrentIrql; diff --git a/reactos/ntoskrnl/include/internal/arm/intrin_i.h b/reactos/ntoskrnl/include/internal/arm/intrin_i.h index abeec315c5c..db3888bf3b5 100644 --- a/reactos/ntoskrnl/include/internal/arm/intrin_i.h +++ b/reactos/ntoskrnl/include/internal/arm/intrin_i.h @@ -38,6 +38,14 @@ KeArmLockdownRegisterGet(VOID) return Value; } +FORCEINLINE +ARM_TTB_REGISTER +KeArmTranslationTableRegisterGet(VOID) +{ + ARM_TTB_REGISTER Value; + __asm__ __volatile__ ("mrc p15, 0, %0, c2, c0, 0" : "=r"(Value.AsUlong) : : "cc"); + return Value; +} FORCEINLINE ARM_CACHE_REGISTER diff --git a/reactos/ntoskrnl/include/internal/arm/ke.h b/reactos/ntoskrnl/include/internal/arm/ke.h index e9d0864196d..019c2153aa7 100644 --- a/reactos/ntoskrnl/include/internal/arm/ke.h +++ b/reactos/ntoskrnl/include/internal/arm/ke.h @@ -9,8 +9,8 @@ // //Lockdown TLB entries // -#define PCR_ENTRY, 0 -#define PDR_ENTRY, 2 +#define PCR_ENTRY 0 +#define PDR_ENTRY 2 #define KeArchHaltProcessor() KeArmHaltProcessor() diff --git a/reactos/ntoskrnl/ke/arm/kiinit.c b/reactos/ntoskrnl/ke/arm/kiinit.c index 5c5babec4fc..bf43ddf3ad7 100644 --- a/reactos/ntoskrnl/ke/arm/kiinit.c +++ b/reactos/ntoskrnl/ke/arm/kiinit.c @@ -12,8 +12,6 @@ #define NDEBUG #include -void arm_kprintf(const char *fmt, ...); - /* GLOBALS ********************************************************************/ BOOLEAN KeIsArmV6; @@ -23,8 +21,26 @@ ULONG KeNumberTbEntries; #define __ARMV6__ KeIsArmV6 +// +// METAFIXME: We need to stop using 1MB Section Entry TTEs! +// + /* FUNCTIONS ******************************************************************/ +VOID +DebugService(IN ULONG ServiceType, + IN PCHAR Buffer, + IN ULONG Length, + IN ULONG Component, + IN ULONG Level) +{ + // + // ARM Bring-up Hack + // + void arm_kprintf(const char *fmt, ...); + arm_kprintf("%s", Buffer); +} + VOID KiFlushSingleTb(IN BOOLEAN Invalid, IN PVOID Virtual) @@ -42,14 +58,19 @@ KeFillFixedEntryTb(IN ARM_PTE Pte, { ARM_LOCKDOWN_REGISTER LockdownRegister; ULONG OldVictimCount; - ULONG Temp; - UNREFERENCED_PARAMETER(Pte); - UNREFERENCED_PARAMETER(Index); + volatile unsigned long Temp; + PARM_TRANSLATION_TABLE TranslationTable; + + // + // Hack for 1MB Section Entries + // + Virtual = (PVOID)((ULONG)Virtual & 0xFFF00000); // // On ARM, we can't set the index ourselves, so make sure that we are not // locking down more than 8 entries. // + UNREFERENCED_PARAMETER(Index); KeFixedTbEntries++; ASSERT(KeFixedTbEntries <= 8); @@ -66,6 +87,12 @@ KeFillFixedEntryTb(IN ARM_PTE Pte, OldVictimCount = LockdownRegister.Victim; KeArmLockdownRegisterSet(LockdownRegister); + // + // Map the PTE for this virtual address + // + TranslationTable = (PVOID)KeArmTranslationTableRegisterGet().AsUlong; + TranslationTable->Pte[(ULONG)Virtual >> TTB_SHIFT] = Pte; + // // Now force a miss // @@ -78,6 +105,11 @@ KeFillFixedEntryTb(IN ARM_PTE Pte, LockdownRegister.Preserve = FALSE; ASSERT(LockdownRegister.Victim == OldVictimCount + 1); KeArmLockdownRegisterSet(LockdownRegister); + + // + // Clear the PTE + // + TranslationTable->Pte[(ULONG)Virtual >> TTB_SHIFT].AsUlong = 0; } VOID @@ -93,7 +125,16 @@ VOID KiInitializeSystem(IN ULONG Magic, IN PLOADER_PARAMETER_BLOCK LoaderBlock) { - arm_kprintf("%s:%i\n", __func__, __LINE__); + ARM_PTE Pte; + PKPCR Pcr; + DPRINT1("-----------------------------------------------------\n"); + DPRINT1("ReactOS-ARM "KERNEL_VERSION_STR" (Build "KERNEL_VERSION_BUILD_STR")\n"); + DPRINT1("Command Line: %s\n", LoaderBlock->LoadOptions); + DPRINT1("ARC Paths: %s %s %s %s\n", LoaderBlock->ArcBootDeviceName, + LoaderBlock->NtHalPathName, + LoaderBlock->ArcHalDeviceName, + LoaderBlock->NtBootPathName); + // // Detect ARM version (Architecture 6 is the ARMv5TE-J, go figure!) // @@ -124,8 +165,33 @@ KiInitializeSystem(IN ULONG Magic, KeFlushTb(); // + // Build the KIPCR pte // + Pte.L1.Section.Type = SectionPte; + Pte.L1.Section.Buffered = FALSE; + Pte.L1.Section.Cached = FALSE; + Pte.L1.Section.Reserved = 1; // ARM926EJ-S manual recommends setting to 1 + Pte.L1.Section.Domain = Domain0; + Pte.L1.Section.Access = SupervisorAccess; + Pte.L1.Section.BaseAddress = LoaderBlock->u.Arm.PcrPage; + Pte.L1.Section.Ignored = Pte.L1.Section.Ignored1 = 0; + // + // Map it into kernel address space by locking it into the TLB + // + KeFillFixedEntryTb(Pte, (PVOID)KIPCR, PCR_ENTRY); + // + // Now map the PCR into user address space as well (read-only) + // + Pte.L1.Section.Access = SharedAccess; + KeFillFixedEntryTb(Pte, (PVOID)USPCR, PCR_ENTRY + 1); + + // + // Now we should be able to use the PCR... set the cache policies + // + Pcr = (PKPCR)KeGetPcr(); + Pcr->CachePolicy = 0; + Pcr->AlignedCachePolicy = 0; while (TRUE); } diff --git a/reactos/ntoskrnl/ke/arm/stubs_asm.s b/reactos/ntoskrnl/ke/arm/stubs_asm.s index 18725401e3f..94dc9aa0932 100644 --- a/reactos/ntoskrnl/ke/arm/stubs_asm.s +++ b/reactos/ntoskrnl/ke/arm/stubs_asm.s @@ -146,7 +146,6 @@ GENERATE_ARM_STUB RtlInitializeContext GENERATE_ARM_STUB RtlpGetExceptionAddress GENERATE_ARM_STUB RtlDispatchException GENERATE_ARM_STUB DebugService2 -GENERATE_ARM_STUB DebugService GENERATE_ARM_STUB KdPortPutByteEx GENERATE_ARM_STUB KdPortInitializeEx GENERATE_ARM_STUB KdpGdbStubInit