We now have the ARM defines/structures in stubs.c in FreeLDR in more appropriate...
[reactos.git] / reactos / boot / freeldr / freeldr / arch / arm / loader.c
1 /*
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
7 */
8
9 /* INCLUDES *******************************************************************/
10
11 #include <freeldr.h>
12 #include <internal/arm/ke.h>
13 #include <internal/arm/mm.h>
14 #include <internal/arm/intrin_i.h>
15
16 /* GLOBALS ********************************************************************/
17
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;
23
24 /* FUNCTIONS ******************************************************************/
25
26 VOID
27 ArmSetupPageDirectory(VOID)
28 {
29 ARM_TTB_REGISTER TtbRegister;
30 ARM_DOMAIN_REGISTER DomainRegister;
31 ARM_PTE Pte;
32 ULONG i;
33 PARM_TRANSLATION_TABLE TranslationTable;
34
35 //
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.
39 //
40 TranslationTable = &ArmTranslationTable;
41 if (!TranslationTable) return;
42
43 //
44 // Set it as the TTB
45 //
46 TtbRegister.AsUlong = (ULONG)TranslationTable;
47 ASSERT(TtbRegister.Reserved == 0);
48 KeArmTranslationTableRegisterSet(TtbRegister);
49
50 //
51 // Use Domain 0, enforce AP bits (client)
52 //
53 DomainRegister.AsUlong = 0;
54 DomainRegister.Domain0 = ClientDomain;
55 KeArmDomainRegisterSet(DomainRegister);
56
57 //
58 // Set Fault PTEs everywhere
59 //
60 RtlZeroMemory(TranslationTable, 4096 * sizeof(ARM_PTE));
61
62 //
63 // Build the template PTE
64 //
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;
73
74 //
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.
78 //
79 for (i = (KSEG0_BASE >> TTB_SHIFT); i < ((KSEG0_BASE + 0x20000000) >> TTB_SHIFT); i++)
80 {
81 //
82 // Write PTE and update the base address (next MB) for the next one
83 //
84 TranslationTable->Pte[i] = Pte;
85 Pte.L1.Section.BaseAddress++;
86 }
87
88 //
89 // Identity map the first MB of memory as well
90 //
91 Pte.L1.Section.BaseAddress = 0;
92 TranslationTable->Pte[0] = Pte;
93 }
94
95 VOID
96 ArmSetupPagingAndJump(IN ULONG Magic)
97 {
98 ARM_CONTROL_REGISTER ControlRegister;
99
100 //
101 // Enable MMU, DCache and ICache
102 //
103 ControlRegister = KeArmControlRegisterGet();
104 ControlRegister.MmuEnabled = TRUE;
105 ControlRegister.ICacheEnabled = TRUE;
106 ControlRegister.DCacheEnabled = TRUE;
107 KeArmControlRegisterSet(ControlRegister);
108
109 //
110 // Jump to Kernel
111 //
112 (*KernelEntryPoint)(Magic, (PVOID)&ArmLoaderBlock);
113 }
114
115 VOID
116 ArmPrepareForReactOS(IN BOOLEAN Setup)
117 {
118 //
119 // Initialize the loader block
120 //
121 InitializeListHead(&ArmLoaderBlock.BootDriverListHead);
122 InitializeListHead(&ArmLoaderBlock.LoadOrderListHead);
123 InitializeListHead(&ArmLoaderBlock.MemoryDescriptorListHead);
124
125 //
126 // Setup the extension and setup block
127 //
128 ArmLoaderBlock.Extension = &ArmExtension;
129 ArmLoaderBlock.SetupLdrBlock = NULL;
130
131 //
132 // TODO: Setup memory descriptors
133 //
134
135 //
136 // TODO: Setup registry data
137 //
138
139 //
140 // TODO: Setup ARC Hardware tree data
141 //
142
143 //
144 // TODO: Setup NLS data
145 //
146
147 //
148 // TODO: Setup boot-driver data
149 //
150
151 //
152 // TODO: Setup extension parameters
153 //
154
155 //
156 // TODO: Setup ARM-specific block
157 //
158 }
159
160 VOID
161 FrLdrStartup(IN ULONG Magic)
162 {
163 //
164 // Disable interrupts (aleady done)
165 //
166
167 //
168 // Set proper CPSR (already done)
169 //
170
171 //
172 // Initialize the page directory
173 //
174 ArmSetupPageDirectory();
175
176 //
177 // Initialize paging and load NTOSKRNL
178 //
179 ArmSetupPagingAndJump(Magic);
180 }