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 // ------------------------------------------------------------------------
39 INTERFACE [arm && armv5]:
45 Cp15_c1_write_buffer = 1 << 3,
46 Cp15_c1_prog32 = 1 << 4,
47 Cp15_c1_data32 = 1 << 5,
48 Cp15_c1_late_abort = 1 << 6,
49 Cp15_c1_big_endian = 1 << 7,
50 Cp15_c1_system_protect = 1 << 8,
51 Cp15_c1_rom_protect = 1 << 9,
56 Cp15_c1_generic = Cp15_c1_mmu
57 | (Config::Cp15_c1_use_alignment_check ? Cp15_c1_alignment_check : 0)
58 | Cp15_c1_write_buffer
63 | Cp15_c1_high_vector,
65 Cp15_c1_cache_bits = Cp15_c1_cache
67 | Cp15_c1_write_buffer,
72 INTERFACE [arm && armv6]:
82 Cp15_c1_nmfi = 1 << 27,
83 Cp15_c1_tex = 1 << 28,
84 Cp15_c1_force_ap = 1 << 29,
86 Cp15_c1_generic = Cp15_c1_mmu
87 | (Config::Cp15_c1_use_alignment_check ? Cp15_c1_alignment_check : 0)
88 | Cp15_c1_branch_predict
93 Cp15_c1_cache_bits = Cp15_c1_cache
100 INTERFACE [arm && armv7 && armca8]:
106 Cp15_c1_ee = 1 << 25,
107 Cp15_c1_nmfi = 1 << 27,
108 Cp15_c1_tre = 1 << 28,
109 Cp15_c1_afe = 1 << 29,
110 Cp15_c1_te = 1 << 30,
112 Cp15_c1_cache_bits = Cp15_c1_cache
113 | Cp15_c1_insn_cache,
115 Cp15_c1_generic = Cp15_c1_mmu
116 | (Config::Cp15_c1_use_alignment_check ? Cp15_c1_alignment_check : 0)
117 | Cp15_c1_branch_predict
118 | Cp15_c1_high_vector,
122 INTERFACE [arm && armv7 && armca9]:
128 Cp15_c1_sw = 1 << 10,
129 Cp15_c1_ha = 1 << 17,
130 Cp15_c1_ee = 1 << 25,
131 Cp15_c1_nmfi = 1 << 27,
132 Cp15_c1_tre = 1 << 28,
133 Cp15_c1_afe = 1 << 29,
134 Cp15_c1_te = 1 << 30,
136 Cp15_c1_cache_bits = Cp15_c1_cache
137 | Cp15_c1_insn_cache,
139 Cp15_c1_generic = Cp15_c1_mmu
140 | (Config::Cp15_c1_use_alignment_check ? Cp15_c1_alignment_check : 0)
141 | Cp15_c1_branch_predict
142 | Cp15_c1_high_vector
143 | (Config::Cp15_c1_use_a9_swp_enable ? Cp15_c1_sw : 0),
155 Cp15_c1_cache_enabled = Cp15_c1_generic | Cp15_c1_cache_bits,
156 Cp15_c1_cache_disabled = Cp15_c1_generic,
160 //---------------------------------------------------------------------------
161 IMPLEMENTATION [arm && (mpcore || armca9)]:
163 PUBLIC static inline void
164 Cpu::early_init_platform()
166 Io::write<Mword>(0xffffffff, Mem_layout::Mp_scu_map_base + 0xc);
167 Io::write<Mword>(1, Mem_layout::Mp_scu_map_base + 0);
169 Io::write<Mword>(Io::read<Mword>(Mem_layout::Gic_cpu_map_base + 0) | 1,
170 Mem_layout::Gic_cpu_map_base + 0);
171 Io::write<Mword>(Io::read<Mword>(Mem_layout::Gic_dist_map_base + 0) | 1,
172 Mem_layout::Gic_dist_map_base + 0);
174 Mem_unit::clean_dcache();
177 __asm__ __volatile__("mrc p15, 0, %0, c1, c0, 1 \n"
179 "mcr p15, 0, %0, c1, c0, 1 \n"
180 : : "r" (tmp), "i" (Smp_enable));
183 //---------------------------------------------------------------------------
184 IMPLEMENTATION [arm && !(mpcore || armca9)]:
186 PUBLIC static inline void Cpu::early_init_platform()
189 //---------------------------------------------------------------------------
190 IMPLEMENTATION [arm]:
197 #include "pagetable.h"
198 #include "kmem_space.h"
199 #include "mem_unit.h"
200 #include "processor.h"
201 #include "ram_quota.h"
203 Per_cpu<Cpu> DEFINE_PER_CPU_P(0) Cpu::cpus(true);
208 Cpu::stack_align(Mword stack)
209 { return stack & ~0x3; }
213 void Cpu::early_init()
215 // switch to supervisor mode and intialize the memory system
216 asm volatile ( " mov r2, r13 \n"
222 " mcr p15, 0, %0, c1, c0 \n"
224 : "r" (Config::cache_enabled
225 ? Cp15_c1_cache_enabled : Cp15_c1_cache_disabled),
229 early_init_platform();
231 Mem_unit::flush_cache();
239 Cpu::have_superpages()
244 Cpu::debugctl_enable()
249 Cpu::debugctl_disable()
252 PUBLIC static inline NEEDS["types.h"]
254 Cpu::get_scaler_tsc_to_ns()
257 PUBLIC static inline NEEDS["types.h"]
259 Cpu::get_scaler_tsc_to_us()
262 PUBLIC static inline NEEDS["types.h"]
264 Cpu::get_scaler_ns_to_tsc()
280 extern char ivt_start;
281 // map the interrupt vector table to 0xffff0000
282 Pte pte = Kmem_space::kdir()->walk((void*)Kmem_space::Ivt_base, 4096,
283 true, Ram_quota::root);
285 pte.set((unsigned long)&ivt_start, 4096,
286 Mem_page_attr(Page::KERN_RW | Page::CACHEABLE),
289 Mem_unit::tlb_flush();
299 Cpu::init(bool is_boot_cpu)
307 _phys_id = Proc::cpu_id();
312 //---------------------------------------------------------------------------
313 IMPLEMENTATION [arm && !tz]:
315 PRIVATE static inline
320 //---------------------------------------------------------------------------
321 INTERFACE [arm && tz]:
327 static char monitor_vector_base asm ("monitor_vector_base");
330 //---------------------------------------------------------------------------
331 IMPLEMENTATION [arm && tz]:
337 // set monitor vector base address
338 assert(!((Mword)&monitor_vector_base & 31));
339 tz_mvbar((Mword)&monitor_vector_base);
341 // enable nonsecure access to vfp coprocessor
342 asm volatile("mov r0, #0xc00;"
343 "mcr p15, 0, r0, c1, c1, 2;"
352 Cpu::tz_switch_to_ns(Mword *nonsecure_state)
354 volatile register Mword r0 asm("r0") = (Mword)nonsecure_state;
355 extern char go_nonsecure;
357 asm volatile("stmdb sp!, {fp} \n"
359 "mov r2, sp \n" // copy sp_svc to sp_mon
360 "cps #0x16 \n" // switch to monitor mode
362 "adr r3, 1f \n" // save return eip
363 "mrs r4, cpsr \n" // save return psr
364 "mov pc, r1 \n" // go nonsecure!
366 "mov r0, sp \n" // copy sp_mon to sp_svc
367 "cps #0x13 \n" // switch to svc mode
371 : : "r" (r0), "r" (&go_nonsecure)
372 : "r2", "r3", "r4", "r5", "r6", "r7",
373 "r8", "r9", "r10", "r12", "r14", "memory");
381 asm volatile ("mrc p15, 0, %0, c1, c1, 0" : "=r" (r));
387 Cpu::tz_scr(Mword val)
389 asm volatile ("mcr p15, 0, %0, c1, c1, 0" : : "r" (val));
397 asm volatile ("mrc p15, 0, %0, c12, c0, 1" : "=r" (r));
403 Cpu::tz_mvbar(Mword val)
405 asm volatile ("mcr p15, 0, %0, c12, c0, 1" : : "r" (val));
408 // ------------------------------------------------------------------------
409 IMPLEMENTATION [arm && tz && armca9]:
413 Cpu::enable_irq_ovrr()
415 // set IRQ/FIQ/Abort override bits
416 asm volatile("mov r0, #0x1c0 \n"
417 "mcr p15, 0, r0, c1, c1, 3 \n"
421 IMPLEMENTATION [!tz || !armca9]:
425 Cpu::enable_irq_ovrr()
428 // ------------------------------------------------------------------------
429 IMPLEMENTATION [!debug]:
431 PRIVATE static inline
436 // ------------------------------------------------------------------------
437 IMPLEMENTATION [debug]:
443 printf("Cache config: %s\n", Config::cache_enabled ? "ON" : "OFF");