hc
2023-10-25 6c2073b7aa40e29d0eca7d571dd7bc590c7ecaa7
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
143
144
145
/*
 * linux/arch/unicore32/mm/proc-macros.S
 *
 * Code specific to PKUnity SoC and UniCore ISA
 *
 * Copyright (C) 2001-2010 GUAN Xue-tao
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 *
 * 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