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
18ENTRY(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
35ENTRY(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 */
58ENTRY(cpu_do_idle)
59	mov	r0, #0				@ PCI address
60	.rept	8
61	ldw	r1, [r0]
62	.endr
63	mov	pc, lr
64
65ENTRY(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
711:	va2pa	r0, r10, r11, r12, r13		@ r10 is PA
72	b	3f
732:	cand.a	r0, r9
74	beq	1b
753:	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
83101:	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
100ENTRY(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
118ENTRY(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
132