OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [include/] [asm-arm/] [proc-armv/] [cache.h] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1276 phoenix
/*
2
 *  linux/include/asm-arm/proc-armv/cache.h
3
 *
4
 *  Copyright (C) 1999-2001 Russell King
5
 *
6
 * This program is free software; you can redistribute it and/or modify
7
 * it under the terms of the GNU General Public License version 2 as
8
 * published by the Free Software Foundation.
9
 */
10
#include <asm/mman.h>
11
 
12
/*
13
 * This flag is used to indicate that the page pointed to by a pte
14
 * is dirty and requires cleaning before returning it to the user.
15
 */
16
#define PG_dcache_dirty PG_arch_1
17
 
18
/*
19
 * Cache handling for 32-bit ARM processors.
20
 *
21
 * Note that on ARM, we have a more accurate specification than that
22
 * Linux's "flush".  We therefore do not use "flush" here, but instead
23
 * use:
24
 *
25
 * clean:      the act of pushing dirty cache entries out to memory.
26
 * invalidate: the act of discarding data held within the cache,
27
 *             whether it is dirty or not.
28
 */
29
 
30
/*
31
 * Generic I + D cache
32
 */
33
#define flush_cache_all()                                               \
34
        do {                                                            \
35
                cpu_cache_clean_invalidate_all();                       \
36
        } while (0)
37
 
38
/* This is always called for current->mm */
39
#define flush_cache_mm(_mm)                                             \
40
        do {                                                            \
41
                if ((_mm) == current->active_mm)                        \
42
                        cpu_cache_clean_invalidate_all();               \
43
        } while (0)
44
 
45
#define flush_cache_range(_mm,_start,_end)                              \
46
        do {                                                            \
47
                if ((_mm) == current->active_mm)                        \
48
                        cpu_cache_clean_invalidate_range((_start) & PAGE_MASK, \
49
                                                         PAGE_ALIGN(_end), 1); \
50
        } while (0)
51
 
52
#define flush_cache_page(_vma,_vmaddr)                                  \
53
        do {                                                            \
54
                if ((_vma)->vm_mm == current->active_mm) {              \
55
                        unsigned long _addr = (_vmaddr) & PAGE_MASK;    \
56
                        cpu_cache_clean_invalidate_range(_addr,         \
57
                                _addr + PAGE_SIZE,                      \
58
                                ((_vma)->vm_flags & VM_EXEC));          \
59
                } \
60
        } while (0)
61
 
62
/*
63
 * This flushes back any buffered write data.  We have to clean the entries
64
 * in the cache for this page.  This does not invalidate either I or D caches.
65
 *
66
 * Called from:
67
 * 1. mm/filemap.c:filemap_nopage
68
 * 2. mm/filemap.c:filemap_nopage
69
 *    [via do_no_page - ok]
70
 *
71
 * 3. mm/memory.c:break_cow
72
 *    [copy_cow_page doesn't do anything to the cache; insufficient cache
73
 *     handling.  Need to add flush_dcache_page() here]
74
 *
75
 * 4. mm/memory.c:do_swap_page
76
 *    [read_swap_cache_async doesn't do anything to the cache: insufficient
77
 *     cache handling.  Need to add flush_dcache_page() here]
78
 *
79
 * 5. mm/memory.c:do_anonymous_page
80
 *    [zero page, never written by kernel - ok]
81
 *
82
 * 6. mm/memory.c:do_no_page
83
 *    [we will be calling update_mmu_cache, which will catch on PG_dcache_dirty]
84
 *
85
 * 7. mm/shmem.c:shmem_nopage
86
 * 8. mm/shmem.c:shmem_nopage
87
 *    [via do_no_page - ok]
88
 *
89
 * 9. fs/exec.c:put_dirty_page
90
 *    [we call flush_dcache_page prior to this, which will flush out the
91
 *     kernel virtual addresses from the dcache - ok]
92
 */
93
static __inline__ void flush_page_to_ram(struct page *page)
94
{
95
        cpu_flush_ram_page(page_address(page));
96
}
97
 
98
/*
99
 * D cache only
100
 */
101
 
102
#define invalidate_dcache_range(_s,_e)  cpu_dcache_invalidate_range((_s),(_e))
103
#define clean_dcache_range(_s,_e)       cpu_dcache_clean_range((_s),(_e))
104
#define flush_dcache_range(_s,_e)       cpu_cache_clean_invalidate_range((_s),(_e),0)
105
 
106
/*
107
 * flush_dcache_page is used when the kernel has written to the page
108
 * cache page at virtual address page->virtual.
109
 *
110
 * If this page isn't mapped (ie, page->mapping = NULL), or it has
111
 * userspace mappings (page->mapping->i_mmap or page->mapping->i_mmap_shared)
112
 * then we _must_ always clean + invalidate the dcache entries associated
113
 * with the kernel mapping.
114
 *
115
 * Otherwise we can defer the operation, and clean the cache when we are
116
 * about to change to user space.  This is the same method as used on SPARC64.
117
 * See update_mmu_cache for the user space part.
118
 */
119
#define mapping_mapped(map)     ((map)->i_mmap || (map)->i_mmap_shared)
120
 
121
static inline void flush_dcache_page(struct page *page)
122
{
123
        if (page->mapping && !mapping_mapped(page->mapping))
124
                set_bit(PG_dcache_dirty, &page->flags);
125
        else {
126
                unsigned long virt = (unsigned long)page_address(page);
127
                cpu_cache_clean_invalidate_range(virt, virt + PAGE_SIZE, 0);
128
        }
129
}
130
 
131
#define flush_icache_user_range(vma,page,addr,len) \
132
        flush_dcache_page(page)
133
 
134
#define clean_dcache_entry(_s)          cpu_dcache_clean_entry((unsigned long)(_s))
135
 
136
/*
137
 * This function is misnamed IMHO.  There are three places where it
138
 * is called, each of which is preceded immediately by a call to
139
 * flush_page_to_ram:
140
 *
141
 *  1. kernel/ptrace.c:access_one_page
142
 *     called after we have written to the kernel view of a user page.
143
 *     The user page has been expundged from the cache by flush_cache_page.
144
 *     [we don't need to do anything here if we add a call to
145
 *      flush_dcache_page]
146
 *
147
 *  2. mm/memory.c:do_swap_page
148
 *     called after we have (possibly) written to the kernel view of a
149
 *     user page, which has previously been removed (ie, has been through
150
 *     the swap cache).
151
 *     [if the flush_page_to_ram() conditions are satisfied, then ok]
152
 *
153
 *  3. mm/memory.c:do_no_page
154
 *     [if the flush_page_to_ram() conditions are satisfied, then ok]
155
 *
156
 * Invalidating the icache at the kernels virtual page isn't really
157
 * going to do us much good, since we wouldn't have executed any
158
 * instructions there.
159
 */
160
#define flush_icache_page(vma,pg)       do { } while (0)
161
 
162
/*
163
 * I cache coherency stuff.
164
 *
165
 * This *is not* just icache.  It is to make data written to memory
166
 * consistent such that instructions fetched from the region are what
167
 * we expect.
168
 *
169
 * This generally means that we have to clean out the Dcache and write
170
 * buffers, and maybe flush the Icache in the specified range.
171
 */
172
#define flush_icache_range(_s,_e)                                       \
173
        do {                                                            \
174
                cpu_icache_invalidate_range((_s), (_e));                \
175
        } while (0)
176
 
177
/*
178
 * TLB flushing.
179
 *
180
 *  - flush_tlb_all()                   flushes all processes TLBs
181
 *  - flush_tlb_mm(mm)                  flushes the specified mm context TLB's
182
 *  - flush_tlb_page(vma, vmaddr)       flushes TLB for specified page
183
 *  - flush_tlb_range(mm, start, end)   flushes TLB for specified range of pages
184
 *
185
 * We drain the write buffer in here to ensure that the page tables in ram
186
 * are really up to date.  It is more efficient to do this here...
187
 */
188
 
189
/*
190
 * Notes:
191
 *  current->active_mm is the currently active memory description.
192
 *  current->mm == NULL iff we are lazy.
193
 */
194
#define flush_tlb_all()                                                 \
195
        do {                                                            \
196
                cpu_tlb_invalidate_all();                               \
197
        } while (0)
198
 
199
/*
200
 * Flush all user virtual address space translations described by `_mm'.
201
 *
202
 * Currently, this is always called for current->mm, which should be
203
 * the same as current->active_mm.  This is currently not be called for
204
 * the lazy TLB case.
205
 */
206
#define flush_tlb_mm(_mm)                                               \
207
        do {                                                            \
208
                if ((_mm) == current->active_mm)                        \
209
                        cpu_tlb_invalidate_all();                       \
210
        } while (0)
211
 
212
/*
213
 * Flush the specified range of user virtual address space translations.
214
 *
215
 * _mm may not be current->active_mm, but may not be NULL.
216
 */
217
#define flush_tlb_range(_mm,_start,_end)                                \
218
        do {                                                            \
219
                if ((_mm) == current->active_mm)                        \
220
                        cpu_tlb_invalidate_range((_start), (_end));     \
221
        } while (0)
222
 
223
/*
224
 * Flush the specified user virtual address space translation.
225
 */
226
#define flush_tlb_page(_vma,_page)                                      \
227
        do {                                                            \
228
                if ((_vma)->vm_mm == current->active_mm)                \
229
                        cpu_tlb_invalidate_page((_page),                \
230
                                 ((_vma)->vm_flags & VM_EXEC));         \
231
        } while (0)
232
 
233
/*
234
 * if PG_dcache_dirty is set for the page, we need to ensure that any
235
 * cache entries for the kernels virtual memory range are written
236
 * back to the page.
237
 */
238
extern void update_mmu_cache(struct vm_area_struct *vma, unsigned long addr, pte_t pte);
239
 
240
/*
241
 * Old ARM MEMC stuff.  This supports the reversed mapping handling that
242
 * we have on the older 26-bit machines.  We don't have a MEMC chip, so...
243
 */
244
#define memc_update_all()               do { } while (0)
245
#define memc_update_mm(mm)              do { } while (0)
246
#define memc_update_addr(mm,pte,log)    do { } while (0)
247
#define memc_clear(mm,physaddr)         do { } while (0)
248
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.