Linux-libre 5.3.12-gnu
[librecmc/linux-libre.git] / arch / unicore32 / mm / proc-ucv2.S
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 /*
3  * linux/arch/unicore32/mm/proc-ucv2.S
4  *
5  * Code specific to PKUnity SoC and UniCore ISA
6  *
7  * Copyright (C) 2001-2010 GUAN Xue-tao
8  */
9 #include <linux/init.h>
10 #include <linux/linkage.h>
11 #include <asm/assembler.h>
12 #include <asm/hwcap.h>
13 #include <asm/pgtable-hwdef.h>
14 #include <asm/pgtable.h>
15
16 #include "proc-macros.S"
17
18 ENTRY(cpu_proc_fin)
19         stm.w   (lr), [sp-]
20         mov     ip, #PSR_R_BIT | PSR_I_BIT | PRIV_MODE
21         mov.a   asr, ip
22         b.l     __cpuc_flush_kern_all
23         ldm.w   (pc), [sp]+
24
25 /*
26  *      cpu_reset(loc)
27  *
28  *      Perform a soft reset of the system.  Put the CPU into the
29  *      same state as it would be if it had been reset, and branch
30  *      to what would be the reset vector.
31  *
32  *      - loc   - location to jump to for soft reset
33  */
34         .align  5
35 ENTRY(cpu_reset)
36         mov     ip, #0
37         movc    p0.c5, ip, #28                  @ Cache invalidate all
38         nop8
39
40         movc    p0.c6, ip, #6                   @ TLB invalidate all
41         nop8
42
43         movc    ip, p0.c1, #0                   @ ctrl register
44         or      ip, ip, #0x2000                 @ vector base address
45         andn    ip, ip, #0x000f                 @ ............idam
46         movc    p0.c1, ip, #0                   @ disable caches and mmu
47         nop
48         mov     pc, r0                          @ jump to loc
49         nop8
50
51 /*
52  *      cpu_do_idle()
53  *
54  *      Idle the processor (eg, wait for interrupt).
55  *
56  *      IRQs are already disabled.
57  */
58 ENTRY(cpu_do_idle)
59         mov     r0, #0                          @ PCI address
60         .rept   8
61         ldw     r1, [r0]
62         .endr
63         mov     pc, lr
64
65 ENTRY(cpu_dcache_clean_area)
66 #ifndef CONFIG_CPU_DCACHE_LINE_DISABLE
67         csub.a  r1, #MAX_AREA_SIZE
68         bsg     101f
69         mov     r9, #PAGE_SZ
70         sub     r9, r9, #1                      @ PAGE_MASK
71 1:      va2pa   r0, r10, r11, r12, r13          @ r10 is PA
72         b       3f
73 2:      cand.a  r0, r9
74         beq     1b
75 3:      movc    p0.c5, r10, #11                 @ clean D entry
76         nop8
77         add     r0, r0, #CACHE_LINESIZE
78         add     r10, r10, #CACHE_LINESIZE
79         sub.a   r1, r1, #CACHE_LINESIZE
80         bua     2b
81         mov     pc, lr
82 #endif
83 101:    mov     ip, #0
84         movc    p0.c5, ip, #10                  @ Dcache clean all
85         nop8
86
87         mov     pc, lr
88
89 /*
90  *      cpu_do_switch_mm(pgd_phys)
91  *
92  *      Set the translation table base pointer to be pgd_phys
93  *
94  *      - pgd_phys - physical address of new pgd
95  *
96  *      It is assumed that:
97  *      - we are not using split page tables
98  */
99         .align  5
100 ENTRY(cpu_do_switch_mm)
101         movc    p0.c2, r0, #0                   @ update page table ptr
102         nop8
103
104         movc    p0.c6, ip, #6                   @ TLB invalidate all
105         nop8
106
107         mov     pc, lr
108
109 /*
110  *      cpu_set_pte(ptep, pte)
111  *
112  *      Set a level 2 translation table entry.
113  *
114  *      - ptep  - pointer to level 2 translation table entry
115  *      - pte   - PTE value to store
116  */
117         .align  5
118 ENTRY(cpu_set_pte)
119         stw     r1, [r0]
120 #ifndef CONFIG_CPU_DCACHE_LINE_DISABLE
121         sub     r2, r0, #PAGE_OFFSET
122         movc    p0.c5, r2, #11                          @ Dcache clean line
123         nop8
124 #else
125         mov     ip, #0
126         movc    p0.c5, ip, #10                          @ Dcache clean all
127         nop8
128         @dcacheline_flush       r0, r2, ip
129 #endif
130         mov     pc, lr
131