]> rtime.felk.cvut.cz Git - l4.git/blob - kernel/fiasco/src/kern/arm/bootstrap.cpp
update
[l4.git] / kernel / fiasco / src / kern / arm / bootstrap.cpp
1 INTERFACE [arm]:
2
3 #include <cstddef>
4 #include "types.h"
5 #include "mem_layout.h"
6
7 //---------------------------------------------------------------------------
8 IMPLEMENTATION [arm]:
9
10 #include "cpu.h"
11
12 //---------------------------------------------------------------------------
13 IMPLEMENTATION [arm && armv5]:
14
15 enum
16 {
17   Section_cachable = 0x40e,
18   Section_no_cache = 0x402,
19   Section_local    = 0,
20   Section_global   = 0,
21 };
22
23 void
24 set_asid()
25 {}
26
27 //---------------------------------------------------------------------------
28 IMPLEMENTATION [arm && armv6plus && (mpcore || armca9)]:
29
30 enum
31 {
32   Section_shared = 1UL << 16,
33 };
34
35 //---------------------------------------------------------------------------
36 IMPLEMENTATION [arm && armv6plus && !(mpcore || armca9)]:
37
38 enum
39 {
40   Section_shared = 0,
41 };
42
43
44 //---------------------------------------------------------------------------
45 IMPLEMENTATION [arm && (armv6 || armv7)]:
46
47 enum
48 {
49   Section_cachable = 0x5406 | Section_shared,
50   Section_no_cache = 0x0402 | Section_shared,
51   Section_local    = (1 << 17),
52   Section_global   = 0,
53 };
54
55 void
56 set_asid()
57 {
58   asm volatile ("MCR p15, 0, %0, c13, c0, 1" : : "r" (0)); // ASID 0
59 }
60
61 //---------------------------------------------------------------------------
62 IMPLEMENTATION [arm && arm1176_cache_alias_fix]:
63
64 static void
65 do_arm_1176_cache_alias_workaround()
66 {
67   Mword v;
68   asm volatile ("mrc p15, 0, %0, c0, c0, 1   \n" : "=r" (v));
69   if (v & ((1 << 23) | (1 << 11)))
70     { // P bits set
71       asm volatile ("mrc p15, 0, r0, c1, c0, 1   \n"
72                     "orr r0, r0, #(1 << 6)       \n"
73                     "mcr p15, 0, r0, c1, c0, 1   \n"
74                     : : : "r0");
75     }
76 }
77
78 //---------------------------------------------------------------------------
79 IMPLEMENTATION [arm && !arm1176_cache_alias_fix]:
80
81 static void do_arm_1176_cache_alias_workaround() {}
82
83 //---------------------------------------------------------------------------
84 IMPLEMENTATION [arm]:
85
86 #include "kmem_space.h"
87 #include "pagetable.h"
88
89 void
90 map_1mb(void *pd, Address va, Address pa, bool cache, bool local)
91 {
92   Unsigned32 *const p = (Unsigned32*)pd;
93   p[va >> 20] = (pa & 0xfff00000)
94                 | (cache ? Section_cachable : Section_no_cache)
95                 | (local ? Section_local : Section_global);
96 }
97
98 asm
99 (
100 ".section .text.init,#alloc,#execinstr \n"
101 ".global _start                        \n"
102 "_start:                               \n"
103 "     ldr sp, __init_data              \n"
104 "     bl        bootstrap_main         \n"
105
106 "__init_data:                          \n"
107 ".long _stack                          \n"
108 ".previous                             \n"
109 ".section .bss                         \n"
110 "       .space  2048                   \n"
111 "_stack:                               \n"
112 ".previous                             \n"
113 );
114
115
116 #include "mmu.h"
117
118 #include "globalconfig.h"
119
120 extern char bootstrap_bss_start[];
121 extern char bootstrap_bss_end[];
122 extern char __bss_start[];
123 extern char __bss_end[];
124
125 enum
126 {
127   Virt_ofs = Mem_layout::Sdram_phys_base - Mem_layout::Map_base,
128 };
129
130 extern "C" void bootstrap_main()
131 {
132   extern char kernel_page_directory[];
133   void *const page_dir = kernel_page_directory + Virt_ofs;
134
135   Address va, pa;
136   // map sdram linear from 0xf0000000
137   for (va = Mem_layout::Map_base, pa = Mem_layout::Sdram_phys_base;
138        va < Mem_layout::Map_base + (4 << 20); va += 0x100000, pa += 0x100000)
139     map_1mb(page_dir, va, pa, true, false);
140
141   // map sdram 1:1
142   for (va = Mem_layout::Sdram_phys_base;
143        va < Mem_layout::Sdram_phys_base + (4 << 20); va += 0x100000)
144     map_1mb(page_dir, va, va, true, true);
145
146   map_hw(page_dir);
147
148   unsigned domains      = 0x55555555; // client for all domains
149   unsigned control      = Config::cache_enabled
150                           ? Cpu::Cp15_c1_cache_enabled : Cpu::Cp15_c1_cache_disabled;
151
152   Mmu<Cache_flush_area, true>::flush_cache();
153
154   extern char _start_kernel[];
155
156   do_arm_1176_cache_alias_workaround();
157   set_asid();
158
159   asm volatile (
160       "mcr p15, 0, %[null], c8, c7, 0x00   \n" // TLB flush
161       "mcr p15, 0, %[doms], c3, c0    \n" // domains
162       "mcr p15, 0, %[pdir], c2, c0    \n" // pdbr
163       "mcr p15, 0, %[control], c1, c0 \n" // control
164
165       "mrc p15, 0, r0, c2, c0, 0      \n" // arbitrary read of cp15
166       "mov r0, r0                     \n" // wait for result
167       "sub pc, pc, #4                 \n"
168
169       "mov pc, %[start]               \n"
170       : :
171       [pdir]    "r"((Mword)page_dir | Page_table::Ttbr_bits),
172       [doms]    "r"(domains),
173       [control] "r"(control),
174       [start]   "r"(_start_kernel),
175       [null]    "r"(0)
176       : "r0"
177       );
178
179   while(1)
180     ;
181 }