Write initialization code in assembly -- we load the kernel stack from FreeLDR and jump to C code.

We now have a file for C-code initialization (no reason to use assembly).
We now have some basic TLB routines and intrinsics (not tested).
We also detect if we are running on V4 or V6, and set the TLB and ASID counts respectively.

svn path=/trunk/; revision=32323
This commit is contained in:
ReactOS Portable Systems Group 2008-02-12 16:22:01 +00:00
parent 22cecfcc97
commit e4d660e795
6 changed files with 201 additions and 2 deletions

View file

@ -29,6 +29,15 @@ KeArmIdCodeRegisterGet(VOID)
return Value;
}
FORCEINLINE
ARM_LOCKDOWN_REGISTER
KeArmLockdownRegisterGet(VOID)
{
ARM_LOCKDOWN_REGISTER Value;
__asm__ __volatile__ ("mrc p15, 0, %0, c10, c0, 0" : "=r"(Value.AsUlong) : : "cc");
return Value;
}
FORCEINLINE
ARM_CACHE_REGISTER
@ -61,4 +70,26 @@ KeArmDomainRegisterSet(IN ARM_DOMAIN_REGISTER DomainRegister)
__asm__ __volatile__ ("mcr p15, 0, %0, c3, c0, 0" : : "r"(DomainRegister.AsUlong) : "cc");
}
FORCEINLINE
VOID
KeArmLockdownRegisterSet(IN ARM_LOCKDOWN_REGISTER LockdownRegister)
{
__asm__ __volatile__ ("mcr p15, 0, %0, c10, c0, 0" : : "r"(LockdownRegister.AsUlong) : "cc");
}
FORCEINLINE
VOID
KeArmFlushTlb(VOID)
{
__asm__ __volatile__ ("mcr p15, 0, %0, c8, c7, 0" : : "r"(0) : "cc");
}
FORCEINLINE
VOID
KeArmInvalidateTlbEntry(IN PVOID Address)
{
__asm__ __volatile__ ("mcr p15, 0, %0, c8, c7, 1" : : "r"(Address) : "cc");
}
#endif

View file

@ -99,6 +99,18 @@ typedef union _ARM_CACHE_REGISTER
ULONG AsUlong;
} ARM_CACHE_REGISTER, *PARM_CACHE_REGISTER;
typedef union _ARM_LOCKDOWN_REGISTER
{
struct
{
ULONG Preserve:1;
ULONG Ignored:25;
ULONG Victim:3;
ULONG Reserved:3;
};
ULONG AsUlong;
} ARM_LOCKDOWN_REGISTER, *PARM_LOCKDOWN_REGISTER;
typedef enum _ARM_DOMAINS
{
Domain0,

View file

@ -1,9 +1,31 @@
//
// CPSR Values
//
.equ CPSR_IRQ_DISABLE, 0x80
.equ CPSR_FIQ_DISABLE, 0x40
.equ CPSR_THUMB_ENABLE, 0x20
//
// C1 Register Values
//
.equ C1_MMU_CONTROL, 0x01
.equ C1_ALIGNMENT_CONTROL, 0x02
.equ C1_DCACHE_CONTROL, 0x04
.equ C1_ICACHE_CONTROL, 0x1000
.equ C1_VECTOR_CONTROL, 0x2000
//
// Loader Parameter Block Offsets
//
.equ LpbKernelStack, 0x18
//
// PCR
//
.equ KiPcr, 0xFFFFF000
//
// Lockdown TLB entries
//
.equ PCR_ENTRY 0
.equ PDR_ENTRY 2

View file

@ -15,8 +15,13 @@
PROLOG_END KiSystemStartup
//
// Do stuff!
// Switch to boot kernel stack
//
b .
ldr sp, [a2, #LpbKernelStack]
//
// Go to C code
//
b KiInitializeSystem
ENTRY_END KiSystemStartup

View file

@ -0,0 +1,128 @@
/*
* PROJECT: ReactOS Kernel
* LICENSE: GPL - See COPYING in the top level directory
* FILE: ntoskrnl/ke/arm/kiinit.c
* PURPOSE: Implements the kernel entry point for ARM machines
* PROGRAMMERS: ReactOS Portable Systems Group
*/
/* INCLUDES *******************************************************************/
#include <ntoskrnl.h>
#define NDEBUG
#include <debug.h>
/* GLOBALS ********************************************************************/
BOOLEAN KeIsArmV6;
ULONG KeFixedTbEntries;
ULONG KeNumberProcessIds;
ULONG KeNumberTbEntries;
#define __ARMV6__ KeIsArmV6
/* FUNCTIONS ******************************************************************/
VOID
KiFlushSingleTb(IN BOOLEAN Invalid,
IN PVOID Virtual)
{
//
// Just invalidate it
//
KeArmInvalidateTlbEntry(Virtual);
}
VOID
KeFillFixedEntryTb(IN ARM_PTE Pte,
IN PVOID Virtual,
IN ULONG Index)
{
ARM_LOCKDOWN_REGISTER LockdownRegister;
ULONG OldVictimCount;
ULONG Temp;
UNREFERENCED_PARAMETER(Pte);
UNREFERENCED_PARAMETER(Index);
//
// On ARM, we can't set the index ourselves, so make sure that we are not
// locking down more than 8 entries.
//
KeFixedTbEntries++;
ASSERT(KeFixedTbEntries <= 8);
//
// Flush the address
//
KiFlushSingleTb(TRUE, Virtual);
//
// Read lockdown register and set the preserve bit
//
LockdownRegister = KeArmLockdownRegisterGet();
LockdownRegister.Preserve = TRUE;
OldVictimCount = LockdownRegister.Victim;
KeArmLockdownRegisterSet(LockdownRegister);
//
// Now force a miss
//
Temp = *(PULONG)Virtual;
//
// Read lockdown register and clear the preserve bit
//
LockdownRegister = KeArmLockdownRegisterGet();
LockdownRegister.Preserve = FALSE;
ASSERT(LockdownRegister.Victim == OldVictimCount + 1);
KeArmLockdownRegisterSet(LockdownRegister);
}
VOID
KeFlushTb(VOID)
{
//
// Flush the entire TLB
//
KeArmFlushTlb();
}
VOID
KiInitializeSystem(IN ULONG Magic,
IN PLOADER_PARAMETER_BLOCK LoaderBlock)
{
//
// Detect ARM version (Architecture 6 is the ARMv5TE-J, go figure!)
//
KeIsArmV6 = KeArmIdCodeRegisterGet().Architecture == 7;
//
// Set the number of TLB entries and ASIDs
//
KeNumberTbEntries = 64;
if (__ARMV6__)
{
//
// 256 ASIDs on v6/v7
//
KeNumberProcessIds = 256;
}
else
{
//
// The TLB is VIVT on v4/v5
//
KeNumberProcessIds = 0;
}
//
// Flush the TLB
//
KeFlushTb();
//
//
//
while (TRUE);
}

View file

@ -60,6 +60,7 @@
<if property="ARCH" value="arm">
<directory name="arm">
<file first="true">boot.s</file>
<file>kiinit.c</file>
<file>stubs_asm.s</file>
<file>stubs.c</file>
</directory>