2 * PROJECT: ReactOS Boot Loader
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: boot/freeldr/arch/arm/loader.c
5 * PURPOSE: ARM Kernel Loader
6 * PROGRAMMERS: ReactOS Portable Systems Group
9 /* INCLUDES *******************************************************************/
12 #include <internal/arm/ke.h>
13 #include <internal/arm/mm.h>
14 #include <internal/arm/intrin_i.h>
16 /* GLOBALS ********************************************************************/
18 ULONG PageDirectoryStart
, PageDirectoryEnd
;
19 LOADER_PARAMETER_BLOCK ArmLoaderBlock
;
20 LOADER_PARAMETER_EXTENSION ArmExtension
;
21 extern ARM_TRANSLATION_TABLE ArmTranslationTable
;
22 extern ROS_KERNEL_ENTRY_POINT KernelEntryPoint
;
24 /* FUNCTIONS ******************************************************************/
27 ArmSetupPageDirectory(VOID
)
29 ARM_TTB_REGISTER TtbRegister
;
30 ARM_DOMAIN_REGISTER DomainRegister
;
33 PARM_TRANSLATION_TABLE TranslationTable
;
36 // Allocate translation table buffer.
37 // During bootstrap, this will be a simple L1 (Master) Page Table with
38 // Section entries for KSEG0 and the first MB of RAM.
40 TranslationTable
= &ArmTranslationTable
;
41 if (!TranslationTable
) return;
46 TtbRegister
.AsUlong
= (ULONG
)TranslationTable
;
47 ASSERT(TtbRegister
.Reserved
== 0);
48 KeArmTranslationTableRegisterSet(TtbRegister
);
51 // Use Domain 0, enforce AP bits (client)
53 DomainRegister
.AsUlong
= 0;
54 DomainRegister
.Domain0
= ClientDomain
;
55 KeArmDomainRegisterSet(DomainRegister
);
58 // Set Fault PTEs everywhere
60 RtlZeroMemory(TranslationTable
, 4096 * sizeof(ARM_PTE
));
63 // Build the template PTE
65 Pte
.L1
.Section
.Type
= SectionPte
;
66 Pte
.L1
.Section
.Buffered
= FALSE
;
67 Pte
.L1
.Section
.Cached
= FALSE
;
68 Pte
.L1
.Section
.Reserved
= 1; // ARM926EJ-S manual recommends setting to 1
69 Pte
.L1
.Section
.Domain
= Domain0
;
70 Pte
.L1
.Section
.Access
= SupervisorAccess
;
71 Pte
.L1
.Section
.BaseAddress
= 0;
72 Pte
.L1
.Section
.Ignored
= Pte
.L1
.Section
.Ignored1
= 0;
75 // Map KSEG0 (0x80000000 - 0xA0000000) to 0x00000000 - 0x80000000
76 // In this way, the KERNEL_PHYS_ADDR (0x800000) becomes 0x80800000
77 // which is the entrypoint, just like on x86.
79 for (i
= (KSEG0_BASE
>> TTB_SHIFT
); i
< ((KSEG0_BASE
+ 0x20000000) >> TTB_SHIFT
); i
++)
82 // Write PTE and update the base address (next MB) for the next one
84 TranslationTable
->Pte
[i
] = Pte
;
85 Pte
.L1
.Section
.BaseAddress
++;
89 // Identity map the first MB of memory as well
91 Pte
.L1
.Section
.BaseAddress
= 0;
92 TranslationTable
->Pte
[0] = Pte
;
96 ArmSetupPagingAndJump(IN ULONG Magic
)
98 ARM_CONTROL_REGISTER ControlRegister
;
101 // Enable MMU, DCache and ICache
103 ControlRegister
= KeArmControlRegisterGet();
104 ControlRegister
.MmuEnabled
= TRUE
;
105 ControlRegister
.ICacheEnabled
= TRUE
;
106 ControlRegister
.DCacheEnabled
= TRUE
;
107 KeArmControlRegisterSet(ControlRegister
);
112 (*KernelEntryPoint
)(Magic
, (PVOID
)&ArmLoaderBlock
);
116 ArmPrepareForReactOS(IN BOOLEAN Setup
)
119 // Initialize the loader block
121 InitializeListHead(&ArmLoaderBlock
.BootDriverListHead
);
122 InitializeListHead(&ArmLoaderBlock
.LoadOrderListHead
);
123 InitializeListHead(&ArmLoaderBlock
.MemoryDescriptorListHead
);
126 // Setup the extension and setup block
128 ArmLoaderBlock
.Extension
= &ArmExtension
;
129 ArmLoaderBlock
.SetupLdrBlock
= NULL
;
132 // TODO: Setup memory descriptors
136 // TODO: Setup registry data
140 // TODO: Setup ARC Hardware tree data
144 // TODO: Setup NLS data
148 // TODO: Setup boot-driver data
152 // TODO: Setup extension parameters
156 // TODO: Setup ARM-specific block
161 FrLdrStartup(IN ULONG Magic
)
164 // Disable interrupts (aleady done)
168 // Set proper CPSR (already done)
172 // Initialize the page directory
174 ArmSetupPageDirectory();
177 // Initialize paging and load NTOSKRNL
179 ArmSetupPagingAndJump(Magic
);