Author: ros-arm-bringup
Date: Tue Feb 12 01:17:15 2008
New Revision: 32307
URL:
http://svn.reactos.org/svn/reactos?rev=32307&view=rev
Log:
We define a region in FreeLDR where we store the initial TTB. We have to align it at a
16KB boundary, and ld loves to crash with such big alignment, so wee manually define it to
load at 0x50000. Pray FreeLDR never gets that big (you'd think LD would warn if that
section is overwriting others).
Wrote a guideline for what ArmPrepareForReactOS should do and defined the initial ARM
loader block and extension.
Wrote the initial MMU code. It's totally busted but after 3 hours of debugging, it
doesn't abort anymore!
Cleanups TBD.
Modified:
trunk/reactos/boot/freeldr/freeldr/arch/arm/boot.s
trunk/reactos/boot/freeldr/freeldr/arch/arm/stubs.c
trunk/reactos/boot/freeldr/freeldr/freeldr.rbuild
Modified: trunk/reactos/boot/freeldr/freeldr/arch/arm/boot.s
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/arch/…
==============================================================================
--- trunk/reactos/boot/freeldr/freeldr/arch/arm/boot.s (original)
+++ trunk/reactos/boot/freeldr/freeldr/arch/arm/boot.s Tue Feb 12 01:17:15 2008
@@ -23,6 +23,7 @@
/* GLOBALS ********************************************************************/
.global _start
+.global ArmTranslationTable
.section startup
/* BOOT CODE ******************************************************************/
@@ -42,11 +43,12 @@
msr cpsr, r1
//
- // Turn off caches
+ // Turn off caches and the MMU
//
mrc p15, 0, r1, c1, c0, 0
bic r1, r1, #C1_DCACHE_CONTROL
bic r1, r1, #C1_ICACHE_CONTROL
+ bic r1, r1, #C1_MMU_CONTROL
mcr p15, 0, r1, c1, c0, 0
//
@@ -65,6 +67,8 @@
// r0 contains the ARM_BOARD_CONFIGURATION_DATA structure
//
bx lr
+
+/* BOOT STACK *****************************************************************/
L_BootStackEnd:
.long BootStackEnd
@@ -77,3 +81,9 @@
.space 0x4000
BootStackEnd:
.long 0
+
+/* INITIAL PAGE TABLE *********************************************************/
+
+.section pagedata
+ArmTranslationTable:
+ .space 0x4000
Modified: trunk/reactos/boot/freeldr/freeldr/arch/arm/stubs.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/arch/…
==============================================================================
--- trunk/reactos/boot/freeldr/freeldr/arch/arm/stubs.c (original)
+++ trunk/reactos/boot/freeldr/freeldr/arch/arm/stubs.c Tue Feb 12 01:17:15 2008
@@ -12,7 +12,185 @@
/* GLOBALS ********************************************************************/
+typedef union _ARM_PTE
+{
+ union
+ {
+ struct
+ {
+ ULONG Type:2;
+ ULONG Unused:30;
+ } Fault;
+ struct
+ {
+ ULONG Type:2;
+ ULONG Reserved:3;
+ ULONG Domain:4;
+ ULONG Ignored:1;
+ ULONG BaseAddress:22;
+ } Coarse;
+ struct
+ {
+ ULONG Type:2;
+ ULONG Buffered:1;
+ ULONG Cached:1;
+ ULONG Reserved:1;
+ ULONG Domain:4;
+ ULONG Ignored:1;
+ ULONG Access:2;
+ ULONG Ignored1:8;
+ ULONG BaseAddress:12;
+ } Section;
+ struct
+ {
+ ULONG Type:2;
+ ULONG Reserved:3;
+ ULONG Domain:4;
+ ULONG Ignored:3;
+ ULONG BaseAddress:20;
+ } Fine;
+ } L1;
+ union
+ {
+ struct
+ {
+ ULONG Type:2;
+ ULONG Unused:30;
+ } Fault;
+ struct
+ {
+ ULONG Type:2;
+ ULONG Buffered:1;
+ ULONG Cached:1;
+ ULONG Access0:2;
+ ULONG Access1:2;
+ ULONG Access2:2;
+ ULONG Access3:2;
+ ULONG Ignored:4;
+ ULONG BaseAddress:16;
+ } Large;
+ struct
+ {
+ ULONG Type:2;
+ ULONG Buffered:1;
+ ULONG Cached:1;
+ ULONG Access0:2;
+ ULONG Access1:2;
+ ULONG Access2:2;
+ ULONG Access3:2;
+ ULONG BaseAddress:20;
+ } Small;
+ struct
+ {
+ ULONG Type:2;
+ ULONG Buffered:1;
+ ULONG Cached:1;
+ ULONG Access0:2;
+ ULONG Ignored:4;
+ ULONG BaseAddress:22;
+ } Tiny;
+ } L2;
+ ULONG AsUlong;
+} ARM_PTE, *PARM_PTE;
+
+typedef struct _ARM_TRANSLATION_TABLE
+{
+ ARM_PTE Pte[4096];
+} ARM_TRANSLATION_TABLE, *PARM_TRANSLATION_TABLE;
+
+typedef union _ARM_TTB_REGISTER
+{
+ struct
+ {
+ ULONG Reserved:14;
+ ULONG BaseAddress:18;
+ };
+ ULONG AsUlong;
+} ARM_TTB_REGISTER;
+
+typedef enum _ARM_L1_PTE_TYPE
+{
+ FaultPte,
+ CoarsePte,
+ SectionPte,
+ FinePte
+} ARM_L1_PTE_TYPE;
+
+typedef enum _ARM_PTE_ACCESS
+{
+ FaultAccess,
+ SupervisorAccess,
+ SharedAccess,
+ UserAccess
+} ARM_PTE_ACCESS;
+
+typedef enum _ARM_DOMAIN
+{
+ FaultDomain,
+ ClientDomain,
+ InvalidDomain,
+ ManagerDomain
+} ARM_DOMAIN;
+
+typedef union _ARM_DOMAIN_REGISTER
+{
+ struct
+ {
+ ULONG Domain0:2;
+ ULONG Domain1:2;
+ ULONG Domain2:2;
+ ULONG Domain3:2;
+ ULONG Domain4:2;
+ ULONG Domain5:2;
+ ULONG Domain6:2;
+ ULONG Domain7:2;
+ ULONG Domain8:2;
+ ULONG Domain9:2;
+ ULONG Domain10:2;
+ ULONG Domain11:2;
+ ULONG Domain12:2;
+ ULONG Domain13:2;
+ ULONG Domain14:2;
+ ULONG Domain15:2;
+ };
+ ULONG AsUlong;
+} ARM_DOMAIN_REGISTER;
+
+typedef union _ARM_CONTROL_REGISTER
+{
+ struct
+ {
+ ULONG MmuEnabled:1;
+ ULONG AlignmentFaultsEnabled:1;
+ ULONG DCacheEnabled:1;
+ ULONG Sbo:3;
+ ULONG BigEndianEnabled:1;
+ ULONG System:1;
+ ULONG Rom:1;
+ ULONG Sbz:2;
+ ULONG ICacheEnabled:1;
+ ULONG HighVectors:1;
+ ULONG RoundRobinReplacementEnabled:1;
+ ULONG Armv4Compat:1;
+ ULONG Sbo1:1;
+ ULONG Sbz1:1;
+ ULONG Sbo2:1;
+ ULONG Reserved:14;
+ };
+ ULONG AsUlong;
+} ARM_CONTROL_REGISTER, *PARM_CONTROL_REGISTER;
+
+typedef enum _ARM_DOMAINS
+{
+ Domain0
+} ARM_DOMAINS;
+
+#define TTB_SHIFT 20
+
ULONG PageDirectoryStart, PageDirectoryEnd;
+LOADER_PARAMETER_BLOCK ArmLoaderBlock;
+LOADER_PARAMETER_EXTENSION ArmExtension;
+extern ARM_TRANSLATION_TABLE ArmTranslationTable;
/* FUNCTIONS ******************************************************************/
@@ -41,10 +219,183 @@
return FALSE;
}
+ARM_CONTROL_REGISTER
+FORCEINLINE
+ArmControlRegisterGet(VOID)
+{
+ ARM_CONTROL_REGISTER Value;
+ __asm__ __volatile__ ("mrc p15, 0, %0, c1, c0, 0" :
"=r"(Value.AsUlong) : : "cc");
+ return Value;
+}
+
+VOID
+FORCEINLINE
+ArmControlRegisterSet(IN ARM_CONTROL_REGISTER ControlRegister)
+{
+ __asm__ __volatile__ ("mcr p15, 0, %0, c1, c0, 0; b ." : :
"r"(ControlRegister.AsUlong) : "cc");
+}
+
+VOID
+FORCEINLINE
+ArmMmuTtbSet(IN ARM_TTB_REGISTER Ttb)
+{
+ __asm__ __volatile__ ("mcr p15, 0, %0, c2, c0, 0" : :
"r"(Ttb.AsUlong) : "cc");
+}
+
+VOID
+FORCEINLINE
+ArmMmuDomainRegisterSet(IN ARM_DOMAIN_REGISTER DomainRegister)
+{
+ __asm__ __volatile__ ("mcr p15, 0, %0, c3, c0, 0" : :
"r"(DomainRegister.AsUlong) : "cc");
+}
+
+VOID
+ArmSetupPageDirectory(VOID)
+{
+ ARM_TTB_REGISTER TtbRegister;
+ ARM_DOMAIN_REGISTER DomainRegister;
+ ARM_PTE Pte;
+ ULONG i;
+ PARM_TRANSLATION_TABLE TranslationTable;
+
+ //
+ // Allocate translation table buffer.
+ // During bootstrap, this will be a simple L1 (Master) Page Table with
+ // Section entries for KSEG0 and the first MB of RAM.
+ //
+ TranslationTable = &ArmTranslationTable;
+ if (!TranslationTable) return;
+
+ //
+ // Set it as the TTB
+ //
+ TtbRegister.AsUlong = (ULONG)TranslationTable;
+ ASSERT(TtbRegister.Reserved == 0);
+ TuiPrintf("CP15 C2: %x\n", TtbRegister);
+ ArmMmuTtbSet(TtbRegister);
+
+ //
+ // Use Domain 0, enforce AP bits (client)
+ //
+ DomainRegister.AsUlong = 0;
+ DomainRegister.Domain0 = ClientDomain;
+ TuiPrintf("CP15 C3: %x\n", DomainRegister);
+ ArmMmuDomainRegisterSet(DomainRegister);
+
+ //
+ // Set Fault PTEs everywhere
+ //
+ RtlZeroMemory(TranslationTable, 4096 * sizeof(ARM_PTE));
+
+ //
+ // Build the template 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 = KSEG0_BASE >> TTB_SHIFT;
+ Pte.L1.Section.Ignored = Pte.L1.Section.Ignored1 = 0;
+ TuiPrintf("Template PTE: %x\n", Pte.AsUlong);
+ TuiPrintf("Base: %x %x\n", KSEG0_BASE, Pte.L1.Section.BaseAddress);
+
+ //
+ // Map KSEG0 (0x80000000 - 0xA0000000)
+ //
+ TuiPrintf("First PTE Index: %x\n", KSEG0_BASE >> TTB_SHIFT);
+ TuiPrintf("Last PTE Index: %x\n", ((KSEG0_BASE + 0x20000000) >>
TTB_SHIFT));
+ for (i = (KSEG0_BASE >> TTB_SHIFT); i < ((KSEG0_BASE + 0x20000000) >>
TTB_SHIFT); i++)
+ {
+ //
+ // Update the PTE base address (next MB)
+ //
+ Pte.L1.Section.BaseAddress++;
+ TranslationTable->Pte[i] = Pte;
+ }
+
+ //
+ // Identity map the first MB of memory
+ //
+ TuiPrintf("Last KSEG0 PTE: %x %x\n", i, Pte.AsUlong);
+ Pte.L1.Section.BaseAddress = 0;
+ TranslationTable->Pte[0] = Pte;
+}
+
+VOID
+ArmSetupPagingAndJump(IN ULONG Magic)
+{
+ ARM_CONTROL_REGISTER ControlRegister;
+
+ //
+ // This is it! Once we enable the MMU we're in a totally different universe.
+ // Cross our fingers: We mapped the bottom 1MB of memory, so FreeLDR and
+ // boot-data is still there. We also mapped the kernel, and made our
+ // allocations | KSEG0_BASE. If any of this isn't true, we're dead.
+ //
+ TuiPrintf("Crossing the Rubicon!\n");
+
+ //
+ // Enable MMU, DCache and ICache
+ //
+ ControlRegister = ArmControlRegisterGet();
+ TuiPrintf("CP15 C1: %x\n", ControlRegister);
+ ControlRegister.MmuEnabled = TRUE;
+ ControlRegister.ICacheEnabled = TRUE;
+ ControlRegister.DCacheEnabled = TRUE;
+ TuiPrintf("CP15 C1: %x\n", ControlRegister);
+ ArmControlRegisterSet(ControlRegister);
+
+ //
+ // Are we still alive?
+ //
+ while (TRUE);
+}
+
VOID
ArmPrepareForReactOS(IN BOOLEAN Setup)
-{
- while (TRUE);
+{
+ //
+ // Initialize the loader block
+ //
+ InitializeListHead(&ArmLoaderBlock.BootDriverListHead);
+ InitializeListHead(&ArmLoaderBlock.LoadOrderListHead);
+ InitializeListHead(&ArmLoaderBlock.MemoryDescriptorListHead);
+
+ //
+ // Setup the extension and setup block
+ //
+ ArmLoaderBlock.Extension = &ArmExtension;
+ ArmLoaderBlock.SetupLdrBlock = NULL;
+
+ //
+ // TODO: Setup memory descriptors
+ //
+
+ //
+ // TODO: Setup registry data
+ //
+
+ //
+ // TODO: Setup ARC Hardware tree data
+ //
+
+ //
+ // TODO: Setup NLS data
+ //
+
+ //
+ // TODO: Setup boot-driver data
+ //
+
+ //
+ // TODO: Setup extension parameters
+ //
+
+ //
+ // TODO: Setup ARM-specific block
+ //
}
PCONFIGURATION_COMPONENT_DATA
@@ -167,5 +518,21 @@
VOID
FrLdrStartup(IN ULONG Magic)
{
- while (TRUE);
-}
+ //
+ // Disable interrupts (aleady done)
+ //
+
+ //
+ // Set proper CPSR (already done)
+ //
+
+ //
+ // Initialize the page directory
+ //
+ ArmSetupPageDirectory();
+
+ //
+ // Initialize paging and load NTOSKRNL
+ //
+ ArmSetupPagingAndJump(Magic);
+}
Modified: trunk/reactos/boot/freeldr/freeldr/freeldr.rbuild
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/freel…
==============================================================================
--- trunk/reactos/boot/freeldr/freeldr/freeldr.rbuild (original)
+++ trunk/reactos/boot/freeldr/freeldr/freeldr.rbuild Tue Feb 12 01:17:15 2008
@@ -31,6 +31,7 @@
<library>libcntpr</library>
<linkerflag>-lgcc</linkerflag>
<linkerflag>-static</linkerflag>
+ <linkerflag>-Wl,--section-start,pagedata=0x50000</linkerflag>
</module>
</if>
<if property="ARCH" value="powerpc">