1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
|
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* linux/arch/unicore32/mm/proc-macros.S
*
* Code specific to PKUnity SoC and UniCore ISA
*
* Copyright (C) 2001-2010 GUAN Xue-tao
*
* We need constants.h for:
* VMA_VM_MM
* VMA_VM_FLAGS
* VM_EXEC
*/
#include <generated/asm-offsets.h>
#include <asm/thread_info.h>
#include <asm/memory.h>
/*
* the cache line sizes of the I and D cache are the same
*/
#define CACHE_LINESIZE 32
/*
* This is the maximum size of an area which will be invalidated
* using the single invalidate entry instructions. Anything larger
* than this, and we go for the whole cache.
*
* This value should be chosen such that we choose the cheapest
* alternative.
*/
#ifdef CONFIG_CPU_UCV2
#define MAX_AREA_SIZE 0x800 /* 64 cache line */
#endif
/*
* vma_vm_mm - get mm pointer from vma pointer (vma->vm_mm)
*/
.macro vma_vm_mm, rd, rn
ldw \rd, [\rn+], #VMA_VM_MM
.endm
/*
* vma_vm_flags - get vma->vm_flags
*/
.macro vma_vm_flags, rd, rn
ldw \rd, [\rn+], #VMA_VM_FLAGS
.endm
.macro tsk_mm, rd, rn
ldw \rd, [\rn+], #TI_TASK
ldw \rd, [\rd+], #TSK_ACTIVE_MM
.endm
/*
* act_mm - get current->active_mm
*/
.macro act_mm, rd
andn \rd, sp, #8128
andn \rd, \rd, #63
ldw \rd, [\rd+], #TI_TASK
ldw \rd, [\rd+], #TSK_ACTIVE_MM
.endm
/*
* mmid - get context id from mm pointer (mm->context.id)
*/
.macro mmid, rd, rn
ldw \rd, [\rn+], #MM_CONTEXT_ID
.endm
/*
* mask_asid - mask the ASID from the context ID
*/
.macro asid, rd, rn
and \rd, \rn, #255
.endm
.macro crval, clear, mmuset, ucset
.word \clear
.word \mmuset
.endm
#ifndef CONFIG_CPU_DCACHE_LINE_DISABLE
/*
* va2pa va, pa, tbl, msk, off, err
* This macro is used to translate virtual address to its physical address.
*
* va: virtual address
* pa: physical address, result is stored in this register
* tbl, msk, off: temp registers, will be destroyed
* err: jump to error label if the physical address not exist
* NOTE: all regs must be different
*/
.macro va2pa, va, pa, tbl, msk, off, err=990f
movc \pa, p0.c2, #0
mov \off, \va >> #22 @ off <- index of 1st page table
adr \tbl, 910f @ tbl <- table of 1st page table
900: @ ---- handle 1, 2 page table
add \pa, \pa, #PAGE_OFFSET @ pa <- virt addr of page table
ldw \pa, [\pa+], \off << #2 @ pa <- the content of pt
cand.a \pa, #4 @ test exist bit
beq \err @ if not exist
and \off, \pa, #3 @ off <- the last 2 bits
add \tbl, \tbl, \off << #3 @ cmove table pointer
ldw \msk, [\tbl+], #0 @ get the mask
ldw pc, [\tbl+], #4
930: @ ---- handle 2nd page table
and \pa, \pa, \msk @ pa <- phys addr of 2nd pt
mov \off, \va << #10
cntlo \tbl, \msk @ use tbl as temp reg
mov \off, \off >> \tbl
mov \off, \off >> #2 @ off <- index of 2nd pt
adr \tbl, 920f @ tbl <- table of 2nd pt
b 900b
910: @ 1st level page table
.word 0xfffff000, 930b @ second level page table
.word 0xfffffc00, 930b @ second level large page table
.word 0x00000000, \err @ invalid
.word 0xffc00000, 980f @ super page
920: @ 2nd level page table
.word 0xfffff000, 980f @ page
.word 0xffffc000, 980f @ middle page
.word 0xffff0000, 980f @ large page
.word 0x00000000, \err @ invalid
980:
andn \tbl, \va, \msk
and \pa, \pa, \msk
or \pa, \pa, \tbl
990:
.endm
#endif
.macro dcacheline_flush, addr, t1, t2
mov \t1, \addr << #20
ldw \t2, =_stext @ _stext must ALIGN(4096)
add \t2, \t2, \t1 >> #20
ldw \t1, [\t2+], #0x0000
ldw \t1, [\t2+], #0x1000
ldw \t1, [\t2+], #0x2000
ldw \t1, [\t2+], #0x3000
.endm
|