1#ifndef __ASM_ARM_SYSTEM_H
2#define __ASM_ARM_SYSTEM_H
3
4#include <linux/compiler.h>
5#include <asm/barriers.h>
6
7#ifdef CONFIG_ARM64
8
9
10
11
12#define CR_M (1 << 0)
13#define CR_A (1 << 1)
14#define CR_C (1 << 2)
15#define CR_SA (1 << 3)
16#define CR_I (1 << 12)
17#define CR_WXN (1 << 19)
18#define CR_EE (1 << 25)
19
20#define ES_TO_AARCH64 1
21#define ES_TO_AARCH32 0
22
23
24
25
26#define SCR_EL3_RW_AARCH64 (1 << 10)
27#define SCR_EL3_RW_AARCH32 (0 << 10)
28#define SCR_EL3_HCE_EN (1 << 8)
29#define SCR_EL3_SMD_DIS (1 << 7)
30#define SCR_EL3_RES1 (3 << 4)
31#define SCR_EL3_EA_EN (1 << 3)
32#define SCR_EL3_NS_EN (1 << 0)
33
34
35
36
37#define SPSR_EL_END_LE (0 << 9)
38#define SPSR_EL_DEBUG_MASK (1 << 9)
39#define SPSR_EL_ASYN_MASK (1 << 8)
40#define SPSR_EL_SERR_MASK (1 << 8)
41#define SPSR_EL_IRQ_MASK (1 << 7)
42#define SPSR_EL_FIQ_MASK (1 << 6)
43#define SPSR_EL_T_A32 (0 << 5)
44#define SPSR_EL_M_AARCH64 (0 << 4)
45#define SPSR_EL_M_AARCH32 (1 << 4)
46#define SPSR_EL_M_SVC (0x3)
47#define SPSR_EL_M_HYP (0xa)
48#define SPSR_EL_M_EL1H (5)
49#define SPSR_EL_M_EL2H (9)
50
51
52
53
54#define CPTR_EL2_RES1 (3 << 12 | 0x3ff)
55
56
57
58
59#define SCTLR_EL2_RES1 (3 << 28 | 3 << 22 | 1 << 18 | 1 << 16 |\
60 1 << 11 | 3 << 4)
61#define SCTLR_EL2_EE_LE (0 << 25)
62#define SCTLR_EL2_WXN_DIS (0 << 19)
63#define SCTLR_EL2_ICACHE_DIS (0 << 12)
64#define SCTLR_EL2_SA_DIS (0 << 3)
65#define SCTLR_EL2_DCACHE_DIS (0 << 2)
66#define SCTLR_EL2_ALIGN_DIS (0 << 1)
67#define SCTLR_EL2_MMU_DIS (0)
68
69
70
71
72#define CNTHCTL_EL2_EL1PCEN_EN (1 << 1)
73#define CNTHCTL_EL2_EL1PCTEN_EN (1 << 0)
74
75
76
77
78#define HCR_EL2_RW_AARCH64 (1 << 31)
79#define HCR_EL2_RW_AARCH32 (0 << 31)
80#define HCR_EL2_HCD_DIS (1 << 29)
81
82
83
84
85#define CPACR_EL1_FPEN_EN (3 << 20)
86
87
88
89
90#define SCTLR_EL1_RES1 (3 << 28 | 3 << 22 | 1 << 20 |\
91 1 << 11)
92#define SCTLR_EL1_UCI_DIS (0 << 26)
93#define SCTLR_EL1_EE_LE (0 << 25)
94#define SCTLR_EL1_WXN_DIS (0 << 19)
95#define SCTLR_EL1_NTWE_DIS (0 << 18)
96#define SCTLR_EL1_NTWI_DIS (0 << 16)
97#define SCTLR_EL1_UCT_DIS (0 << 15)
98#define SCTLR_EL1_DZE_DIS (0 << 14)
99#define SCTLR_EL1_ICACHE_DIS (0 << 12)
100#define SCTLR_EL1_UMA_DIS (0 << 9)
101#define SCTLR_EL1_SED_EN (0 << 8)
102#define SCTLR_EL1_ITD_EN (0 << 7)
103#define SCTLR_EL1_CP15BEN_DIS (0 << 5)
104#define SCTLR_EL1_SA0_DIS (0 << 4)
105#define SCTLR_EL1_SA_DIS (0 << 3)
106#define SCTLR_EL1_DCACHE_DIS (0 << 2)
107#define SCTLR_EL1_ALIGN_DIS (0 << 1)
108#define SCTLR_EL1_MMU_DIS (0)
109
110#ifndef __ASSEMBLY__
111
112struct pt_regs;
113
114u64 get_page_table_size(void);
115#define PGTABLE_SIZE get_page_table_size()
116
117
118#define MMU_SECTION_SHIFT 21
119#define MMU_SECTION_SIZE (1 << MMU_SECTION_SHIFT)
120
121
122enum dcache_option {
123 DCACHE_OFF = 0 << 2,
124 DCACHE_WRITETHROUGH = 3 << 2,
125 DCACHE_WRITEBACK = 4 << 2,
126 DCACHE_WRITEALLOC = 4 << 2,
127};
128
129#define wfi() \
130 ({asm volatile( \
131 "wfi" : : : "memory"); \
132 })
133
134static inline unsigned int current_el(void)
135{
136 unsigned long el;
137
138 asm volatile("mrs %0, CurrentEL" : "=r" (el) : : "cc");
139 return 3 & (el >> 2);
140}
141
142static inline unsigned int get_sctlr(void)
143{
144 unsigned int el;
145 unsigned long val;
146
147 el = current_el();
148 if (el == 1)
149 asm volatile("mrs %0, sctlr_el1" : "=r" (val) : : "cc");
150 else if (el == 2)
151 asm volatile("mrs %0, sctlr_el2" : "=r" (val) : : "cc");
152 else
153 asm volatile("mrs %0, sctlr_el3" : "=r" (val) : : "cc");
154
155 return val;
156}
157
158static inline void set_sctlr(unsigned long val)
159{
160 unsigned int el;
161
162 el = current_el();
163 if (el == 1)
164 asm volatile("msr sctlr_el1, %0" : : "r" (val) : "cc");
165 else if (el == 2)
166 asm volatile("msr sctlr_el2, %0" : : "r" (val) : "cc");
167 else
168 asm volatile("msr sctlr_el3, %0" : : "r" (val) : "cc");
169
170 asm volatile("isb");
171}
172
173static inline unsigned long read_mpidr(void)
174{
175 unsigned long val;
176
177 asm volatile("mrs %0, mpidr_el1" : "=r" (val));
178
179 return val;
180}
181
182#define BSP_COREID 0
183
184void __asm_flush_dcache_all(void);
185void __asm_invalidate_dcache_all(void);
186void __asm_flush_dcache_range(u64 start, u64 end);
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201void __asm_invalidate_dcache_range(u64 start, u64 end);
202void __asm_invalidate_tlb_all(void);
203void __asm_invalidate_icache_all(void);
204int __asm_invalidate_l3_dcache(void);
205int __asm_flush_l3_dcache(void);
206int __asm_invalidate_l3_icache(void);
207void __asm_switch_ttbr(u64 new_ttbr);
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222void __noreturn armv8_switch_to_el2(u64 args, u64 mach_nr, u64 fdt_addr,
223 u64 arg4, u64 entry_point, u64 es_flag);
224
225
226
227
228
229
230
231
232
233
234
235
236
237void armv8_switch_to_el1(u64 args, u64 mach_nr, u64 fdt_addr,
238 u64 arg4, u64 entry_point, u64 es_flag);
239void armv8_el2_to_aarch32(u64 args, u64 mach_nr, u64 fdt_addr,
240 u64 arg4, u64 entry_point);
241void gic_init(void);
242void gic_send_sgi(unsigned long sgino);
243void wait_for_wakeup(void);
244void protect_secure_region(void);
245void smp_kick_all_cpus(void);
246
247void flush_l3_cache(void);
248void mmu_change_region_attr(phys_addr_t start, size_t size, u64 attrs);
249
250
251
252
253
254
255
256
257
258void smc_call(struct pt_regs *args);
259
260void __noreturn psci_system_reset(void);
261void __noreturn psci_system_reset2(u32 reset_level, u32 cookie);
262void __noreturn psci_system_off(void);
263
264#ifdef CONFIG_ARMV8_PSCI
265extern char __secure_start[];
266extern char __secure_end[];
267extern char __secure_stack_start[];
268extern char __secure_stack_end[];
269
270void armv8_setup_psci(void);
271void psci_setup_vectors(void);
272void psci_arch_init(void);
273#endif
274
275#endif
276
277#else
278
279#ifdef __KERNEL__
280
281#define CPU_ARCH_UNKNOWN 0
282#define CPU_ARCH_ARMv3 1
283#define CPU_ARCH_ARMv4 2
284#define CPU_ARCH_ARMv4T 3
285#define CPU_ARCH_ARMv5 4
286#define CPU_ARCH_ARMv5T 5
287#define CPU_ARCH_ARMv5TE 6
288#define CPU_ARCH_ARMv5TEJ 7
289#define CPU_ARCH_ARMv6 8
290#define CPU_ARCH_ARMv7 9
291
292
293
294
295#define CR_M (1 << 0)
296#define CR_A (1 << 1)
297#define CR_C (1 << 2)
298#define CR_W (1 << 3)
299#define CR_P (1 << 4)
300#define CR_D (1 << 5)
301#define CR_L (1 << 6)
302#define CR_B (1 << 7)
303#define CR_S (1 << 8)
304#define CR_R (1 << 9)
305#define CR_F (1 << 10)
306#define CR_Z (1 << 11)
307#define CR_I (1 << 12)
308#define CR_V (1 << 13)
309#define CR_RR (1 << 14)
310#define CR_L4 (1 << 15)
311#define CR_DT (1 << 16)
312#define CR_IT (1 << 18)
313#define CR_ST (1 << 19)
314#define CR_FI (1 << 21)
315#define CR_U (1 << 22)
316#define CR_XP (1 << 23)
317#define CR_VE (1 << 24)
318#define CR_EE (1 << 25)
319#define CR_TRE (1 << 28)
320#define CR_AFE (1 << 29)
321#define CR_TE (1 << 30)
322
323#if defined(CONFIG_ARMV7_LPAE) && !defined(PGTABLE_SIZE)
324#define PGTABLE_SIZE (4096 * 5)
325#elif !defined(PGTABLE_SIZE)
326#define PGTABLE_SIZE (4096 * 4)
327#endif
328
329
330
331
332
333
334
335
336
337#define __asmeq(x, y) ".ifnc " x "," y " ; .err ; .endif\n\t"
338
339#ifndef __ASSEMBLY__
340
341#ifdef CONFIG_ARMV7_LPAE
342void switch_to_hypervisor_ret(void);
343#endif
344
345#define nop() __asm__ __volatile__("mov\tr0,r0\t@ nop\n\t");
346
347#ifdef __ARM_ARCH_7A__
348#define wfi() __asm__ __volatile__ ("wfi" : : : "memory")
349#else
350#define wfi()
351#endif
352
353static inline unsigned long get_cpsr(void)
354{
355 unsigned long cpsr;
356
357 asm volatile("mrs %0, cpsr" : "=r"(cpsr): );
358 return cpsr;
359}
360
361static inline int is_hyp(void)
362{
363#ifdef CONFIG_ARMV7_LPAE
364
365 return ((get_cpsr() & 0x1f) == 0x1a);
366#else
367
368 return 0;
369#endif
370}
371
372static inline unsigned int get_cr(void)
373{
374 unsigned int val;
375
376 if (is_hyp())
377 asm volatile("mrc p15, 4, %0, c1, c0, 0 @ get CR" : "=r" (val)
378 :
379 : "cc");
380 else
381 asm volatile("mrc p15, 0, %0, c1, c0, 0 @ get CR" : "=r" (val)
382 :
383 : "cc");
384 return val;
385}
386
387static inline void set_cr(unsigned int val)
388{
389 if (is_hyp())
390 asm volatile("mcr p15, 4, %0, c1, c0, 0 @ set CR" :
391 : "r" (val)
392 : "cc");
393 else
394 asm volatile("mcr p15, 0, %0, c1, c0, 0 @ set CR" :
395 : "r" (val)
396 : "cc");
397 isb();
398}
399
400static inline unsigned int get_dacr(void)
401{
402 unsigned int val;
403 asm("mrc p15, 0, %0, c3, c0, 0 @ get DACR" : "=r" (val) : : "cc");
404 return val;
405}
406
407static inline void set_dacr(unsigned int val)
408{
409 asm volatile("mcr p15, 0, %0, c3, c0, 0 @ set DACR"
410 : : "r" (val) : "cc");
411 isb();
412}
413
414#ifdef CONFIG_ARMV7_LPAE
415
416#define TTB_SECT_XN_MASK (1ULL << 54)
417#define TTB_SECT_NG_MASK (1 << 11)
418#define TTB_SECT_AF (1 << 10)
419#define TTB_SECT_SH_MASK (3 << 8)
420#define TTB_SECT_NS_MASK (1 << 5)
421#define TTB_SECT_AP (1 << 6)
422
423#define TTB_SECT_MAIR(x) ((x & 0x7) << 2)
424#define TTB_SECT (1 << 0)
425#define TTB_PAGETABLE (3 << 0)
426
427
428#define TTBCR_EAE (1 << 31)
429#define TTBCR_T0SZ(x) ((x) << 0)
430#define TTBCR_T1SZ(x) ((x) << 16)
431#define TTBCR_USING_TTBR0 (TTBCR_T0SZ(0) | TTBCR_T1SZ(0))
432#define TTBCR_IRGN0_NC (0 << 8)
433#define TTBCR_IRGN0_WBWA (1 << 8)
434#define TTBCR_IRGN0_WT (2 << 8)
435#define TTBCR_IRGN0_WBNWA (3 << 8)
436#define TTBCR_IRGN0_MASK (3 << 8)
437#define TTBCR_ORGN0_NC (0 << 10)
438#define TTBCR_ORGN0_WBWA (1 << 10)
439#define TTBCR_ORGN0_WT (2 << 10)
440#define TTBCR_ORGN0_WBNWA (3 << 10)
441#define TTBCR_ORGN0_MASK (3 << 10)
442#define TTBCR_SHARED_NON (0 << 12)
443#define TTBCR_SHARED_OUTER (2 << 12)
444#define TTBCR_SHARED_INNER (3 << 12)
445#define TTBCR_EPD0 (0 << 7)
446
447
448
449
450
451
452
453
454
455
456#define MEMORY_ATTRIBUTES ((0x00 << (0 * 8)) | (0xaa << (1 * 8)) | \
457 (0xee << (2 * 8)) | (0xff << (3 * 8)))
458
459
460enum dcache_option {
461 DCACHE_OFF = TTB_SECT | TTB_SECT_MAIR(0) | TTB_SECT_XN_MASK,
462 DCACHE_WRITETHROUGH = TTB_SECT | TTB_SECT_MAIR(1),
463 DCACHE_WRITEBACK = TTB_SECT | TTB_SECT_MAIR(2),
464 DCACHE_WRITEALLOC = TTB_SECT | TTB_SECT_MAIR(3),
465};
466#elif defined(CONFIG_CPU_V7A)
467
468#define TTB_SECT_NS_MASK (1 << 19)
469#define TTB_SECT_NG_MASK (1 << 17)
470#define TTB_SECT_S_MASK (1 << 16)
471
472#define TTB_SECT_AP (3 << 10)
473#define TTB_SECT_TEX(x) ((x & 0x7) << 12)
474#define TTB_SECT_DOMAIN(x) ((x & 0xf) << 5)
475#define TTB_SECT_XN_MASK (1 << 4)
476#define TTB_SECT_C_MASK (1 << 3)
477#define TTB_SECT_B_MASK (1 << 2)
478#define TTB_SECT (2 << 0)
479
480
481
482
483
484
485
486
487
488
489
490enum dcache_option {
491 DCACHE_OFF = TTB_SECT_DOMAIN(0) | TTB_SECT_XN_MASK | TTB_SECT,
492 DCACHE_WRITETHROUGH = DCACHE_OFF | TTB_SECT_C_MASK,
493 DCACHE_WRITEBACK = DCACHE_WRITETHROUGH | TTB_SECT_B_MASK,
494 DCACHE_WRITEALLOC = DCACHE_WRITEBACK | TTB_SECT_TEX(1),
495};
496#else
497#define TTB_SECT_AP (3 << 10)
498
499enum dcache_option {
500 DCACHE_OFF = 0x12,
501 DCACHE_WRITETHROUGH = 0x1a,
502 DCACHE_WRITEBACK = 0x1e,
503 DCACHE_WRITEALLOC = 0x16,
504};
505#endif
506
507#if defined(CONFIG_SYS_ARM_CACHE_WRITETHROUGH)
508#define DCACHE_DEFAULT_OPTION DCACHE_WRITETHROUGH
509#elif defined(CONFIG_SYS_ARM_CACHE_WRITEALLOC)
510#define DCACHE_DEFAULT_OPTION DCACHE_WRITEALLOC
511#elif defined(CONFIG_SYS_ARM_CACHE_WRITEBACK)
512#define DCACHE_DEFAULT_OPTION DCACHE_WRITEBACK
513#endif
514
515
516enum {
517#ifdef CONFIG_ARMV7_LPAE
518 MMU_SECTION_SHIFT = 21,
519#else
520 MMU_SECTION_SHIFT = 20,
521#endif
522 MMU_SECTION_SIZE = 1 << MMU_SECTION_SHIFT,
523};
524
525#ifdef CONFIG_CPU_V7A
526
527#define TTBR0_BASE_ADDR_MASK 0xFFFFC000
528#define TTBR0_RGN_NC (0 << 3)
529#define TTBR0_RGN_WBWA (1 << 3)
530#define TTBR0_RGN_WT (2 << 3)
531#define TTBR0_RGN_WB (3 << 3)
532
533#define TTBR0_IRGN_NC (0 << 0 | 0 << 6)
534#define TTBR0_IRGN_WBWA (0 << 0 | 1 << 6)
535#define TTBR0_IRGN_WT (1 << 0 | 0 << 6)
536#define TTBR0_IRGN_WB (1 << 0 | 1 << 6)
537#endif
538
539
540
541
542
543
544
545
546
547void mmu_page_table_flush(unsigned long start, unsigned long stop);
548
549#ifdef CONFIG_ARMV7_PSCI
550void psci_arch_cpu_entry(void);
551void psci_arch_init(void);
552u32 psci_version(void);
553s32 psci_features(u32 function_id, u32 psci_fid);
554s32 psci_cpu_off(void);
555s32 psci_cpu_on(u32 function_id, u32 target_cpu, u32 pc,
556 u32 context_id);
557s32 psci_affinity_info(u32 function_id, u32 target_affinity,
558 u32 lowest_affinity_level);
559u32 psci_migrate_info_type(void);
560void psci_system_off(void);
561void psci_system_reset(void);
562s32 psci_features(u32 function_id, u32 psci_fid);
563#endif
564
565#endif
566
567#define arch_align_stack(x) (x)
568
569#endif
570
571#endif
572
573#ifndef __ASSEMBLY__
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603void save_boot_params_ret(void);
604
605
606
607
608
609
610
611
612
613
614
615void mmu_set_region_dcache_behaviour_phys(phys_addr_t virt, phys_addr_t phys,
616 size_t size, enum dcache_option option);
617
618
619
620
621
622
623
624
625
626
627void mmu_set_region_dcache_behaviour(phys_addr_t start, size_t size,
628 enum dcache_option option);
629
630#ifdef CONFIG_SYS_NONCACHED_MEMORY
631
632
633
634
635
636
637
638
639
640
641int noncached_init(void);
642
643phys_addr_t noncached_alloc(size_t size, size_t align);
644#endif
645
646#endif
647
648#endif
649