4 #include "mem_layout.h"
7 #include "per_cpu_data.h"
14 void init(bool is_boot_cpu = false);
16 static void early_init();
18 static Per_cpu<Cpu> cpus;
19 static Cpu *boot_cpu() { return _boot_cpu; }
23 Cp15_c1_alignment_check = 1 << 1,
24 Cp15_c1_cache = 1 << 2,
25 Cp15_c1_branch_predict = 1 << 11,
26 Cp15_c1_insn_cache = 1 << 12,
27 Cp15_c1_high_vector = 1 << 13,
30 Cpu(unsigned id) { set_id(id); }
33 static Cpu *_boot_cpu;
38 INTERFACE [arm && armv5]:
44 Cp15_c1_write_buffer = 1 << 3,
45 Cp15_c1_prog32 = 1 << 4,
46 Cp15_c1_data32 = 1 << 5,
47 Cp15_c1_late_abort = 1 << 6,
48 Cp15_c1_big_endian = 1 << 7,
49 Cp15_c1_system_protect = 1 << 8,
50 Cp15_c1_rom_protect = 1 << 9,
55 Cp15_c1_generic = Cp15_c1_mmu
56 | (Config::Cp15_c1_use_alignment_check ? Cp15_c1_alignment_check : 0)
57 | Cp15_c1_write_buffer
62 | Cp15_c1_high_vector,
64 Cp15_c1_cache_bits = Cp15_c1_cache
66 | Cp15_c1_write_buffer,
71 INTERFACE [arm && armv6]:
81 Cp15_c1_nmfi = 1 << 27,
82 Cp15_c1_tex = 1 << 28,
83 Cp15_c1_force_ap = 1 << 29,
85 Cp15_c1_generic = Cp15_c1_mmu
86 | (Config::Cp15_c1_use_alignment_check ? Cp15_c1_alignment_check : 0)
87 | Cp15_c1_branch_predict
92 Cp15_c1_cache_bits = Cp15_c1_cache
99 INTERFACE [arm && armv7 && armca8]:
105 Cp15_c1_ee = 1 << 25,
106 Cp15_c1_nmfi = 1 << 27,
107 Cp15_c1_tre = 1 << 28,
108 Cp15_c1_afe = 1 << 29,
109 Cp15_c1_te = 1 << 30,
111 Cp15_c1_cache_bits = Cp15_c1_cache
112 | Cp15_c1_insn_cache,
114 Cp15_c1_generic = Cp15_c1_mmu
115 | (Config::Cp15_c1_use_alignment_check ? Cp15_c1_alignment_check : 0)
116 | Cp15_c1_branch_predict
117 | Cp15_c1_high_vector,
121 INTERFACE [arm && armv7 && armca9]:
127 Cp15_c1_sw = 1 << 10,
128 Cp15_c1_ha = 1 << 17,
129 Cp15_c1_ee = 1 << 25,
130 Cp15_c1_nmfi = 1 << 27,
131 Cp15_c1_tre = 1 << 28,
132 Cp15_c1_afe = 1 << 29,
133 Cp15_c1_te = 1 << 30,
135 Cp15_c1_cache_bits = Cp15_c1_cache
136 | Cp15_c1_insn_cache,
138 Cp15_c1_generic = Cp15_c1_mmu
139 | (Config::Cp15_c1_use_alignment_check ? Cp15_c1_alignment_check : 0)
140 //| Cp15_c1_branch_predict
141 | Cp15_c1_high_vector
142 | (Config::Cp15_c1_use_a9_swp_enable ? Cp15_c1_sw : 0),
154 Cp15_c1_cache_enabled = Cp15_c1_generic | Cp15_c1_cache_bits,
155 Cp15_c1_cache_disabled = Cp15_c1_generic,
159 //---------------------------------------------------------------------------
160 IMPLEMENTATION [arm && (mpcore || armca9)]:
162 PUBLIC static inline void
163 Cpu::early_init_platform()
165 Io::write<Mword>(0xffffffff, Mem_layout::Mp_scu_map_base + 0xc);
166 Io::write<Mword>(1, Mem_layout::Mp_scu_map_base + 0);
168 Io::write<Mword>(Io::read<Mword>(Mem_layout::Gic_cpu_map_base + 0) | 1,
169 Mem_layout::Gic_cpu_map_base + 0);
170 Io::write<Mword>(Io::read<Mword>(Mem_layout::Gic_dist_map_base + 0) | 1,
171 Mem_layout::Gic_dist_map_base + 0);
173 Mem_unit::clean_dcache();
176 __asm__ __volatile__("mrc p15, 0, %0, c1, c0, 1 \n"
178 "mcr p15, 0, %0, c1, c0, 1 \n"
179 : : "r" (tmp), "i" (Smp_enable));
182 //---------------------------------------------------------------------------
183 IMPLEMENTATION [arm && !(mpcore || armca9)]:
185 PUBLIC static inline void Cpu::early_init_platform()
188 //---------------------------------------------------------------------------
189 IMPLEMENTATION [arm]:
196 #include "pagetable.h"
197 #include "kmem_space.h"
198 #include "mem_unit.h"
199 #include "processor.h"
200 #include "ram_quota.h"
202 Per_cpu<Cpu> DEFINE_PER_CPU_P(0) Cpu::cpus(true);
207 Cpu::stack_align(Mword stack)
208 { return stack & ~0x3; }
212 void Cpu::early_init()
214 // switch to supervisor mode and intialize the memory system
215 asm volatile ( " mov r2, r13 \n"
221 " mcr p15, 0, %0, c1, c0 \n"
223 : "r" (Config::cache_enabled
224 ? Cp15_c1_cache_enabled : Cp15_c1_cache_disabled),
228 early_init_platform();
230 Mem_unit::flush_cache();
238 Cpu::have_superpages()
243 Cpu::debugctl_enable()
248 Cpu::debugctl_disable()
251 PUBLIC static inline NEEDS["types.h"]
253 Cpu::get_scaler_tsc_to_ns()
256 PUBLIC static inline NEEDS["types.h"]
258 Cpu::get_scaler_tsc_to_us()
261 PUBLIC static inline NEEDS["types.h"]
263 Cpu::get_scaler_ns_to_tsc()
279 extern char ivt_start;
280 // map the interrupt vector table to 0xffff0000
281 Pte pte = Kmem_space::kdir()->walk((void*)Kmem_space::Ivt_base, 4096,
282 true, Ram_quota::root);
284 pte.set((unsigned long)&ivt_start, 4096,
285 Mem_page_attr(Page::KERN_RW | Page::CACHEABLE),
288 Mem_unit::tlb_flush();
298 Cpu::init(bool is_boot_cpu)
306 _phys_id = Proc::cpu_id();
311 //---------------------------------------------------------------------------
312 IMPLEMENTATION [arm && !tz]:
314 PRIVATE static inline
319 //---------------------------------------------------------------------------
320 INTERFACE [arm && tz]:
326 static char monitor_vector_base asm ("monitor_vector_base");
329 //---------------------------------------------------------------------------
330 IMPLEMENTATION [arm && tz]:
336 // set monitor vector base address
337 assert(!((Mword)&monitor_vector_base & 31));
338 tz_mvbar((Mword)&monitor_vector_base);
340 // enable nonsecure access to vfp coprocessor
341 asm volatile("mov r0, #0xc00;"
342 "mcr p15, 0, r0, c1, c1, 2;"
351 Cpu::tz_switch_to_ns(Mword *nonsecure_state)
353 volatile register Mword r0 asm("r0") = (Mword)nonsecure_state;
354 extern char go_nonsecure;
356 asm volatile( "stmdb sp!, {fp} \n"
358 "mov r2, sp \n" // copy sp_svc to sp_mon
359 "cps #0x16 \n" // switch to monitor mode
361 "adr r3, 1f \n" // save return eip
362 "mrs r4, cpsr \n" // save return psr
363 "mov pc, r1 \n" // go nonsecure!
365 "mov r0, sp \n" // copy sp_mon to sp_svc
366 "cps #0x13 \n" // switch to svc mode
370 : : "r" (r0), "r" (&go_nonsecure)
371 : "r2", "r3", "r4", "r5", "r6", "r7",
372 "r8", "r9", "r10", "r12", "r14", "memory");
380 asm volatile ("mrc p15, 0, %0, c1, c1, 0" : "=r" (r));
386 Cpu::tz_scr(Mword val)
388 asm volatile ("mcr p15, 0, %0, c1, c1, 0" : : "r" (val));
396 asm volatile ("mrc p15, 0, %0, c12, c0, 1" : "=r" (r));
402 Cpu::tz_mvbar(Mword val)
404 asm volatile ("mcr p15, 0, %0, c12, c0, 1" : : "r" (val));
407 // ------------------------------------------------------------------------
408 IMPLEMENTATION [arm && tz && armca9]:
412 Cpu::enable_irq_ovrr()
414 // set IRQ/FIQ/Abort override bits
415 asm volatile("mov r0, #0x1c0; \n"
416 "mcr p15, 0, r0, c1, c1, 3; \n"
420 IMPLEMENTATION [!tz || !armca9]:
424 Cpu::enable_irq_ovrr()
427 // ------------------------------------------------------------------------
428 IMPLEMENTATION [!debug]:
430 PRIVATE static inline
435 // ------------------------------------------------------------------------
436 IMPLEMENTATION [debug]:
442 printf("Cache config: %s\n", Config::cache_enabled ? "ON" : "OFF");