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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [uclinux/] [uClinux-2.0.x/] [arch/] [mips/] [mm/] [init.c] - Blame information for rev 199

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 199 simons
/*
2
 *  arch/mips/mm/init.c
3
 *
4
 *  Copyright (C) 1991, 1992, 1993, 1994  Linus Torvalds
5
 *  Ported to MIPS by Ralf Baechle
6
 */
7
#include <linux/config.h>
8
#include <linux/signal.h>
9
#include <linux/sched.h>
10
#include <linux/head.h>
11
#include <linux/kernel.h>
12
#include <linux/errno.h>
13
#include <linux/string.h>
14
#include <linux/types.h>
15
#include <linux/ptrace.h>
16
#include <linux/mman.h>
17
#include <linux/mm.h>
18
 
19
#include <asm/cachectl.h>
20
#include <asm/jazzdma.h>
21
#include <asm/vector.h>
22
#include <asm/system.h>
23
#include <asm/segment.h>
24
#include <asm/pgtable.h>
25
 
26
extern void deskstation_tyne_dma_init(void);
27
extern void sound_mem_init(void);
28
extern void die_if_kernel(char *,struct pt_regs *,long);
29
extern void show_net_buffers(void);
30
 
31
extern char empty_zero_page[PAGE_SIZE];
32
 
33
/*
34
 * BAD_PAGE is the page that is used for page faults when linux
35
 * is out-of-memory. Older versions of linux just did a
36
 * do_exit(), but using this instead means there is less risk
37
 * for a process dying in kernel mode, possibly leaving a inode
38
 * unused etc..
39
 *
40
 * BAD_PAGETABLE is the accompanying page-table: it is initialized
41
 * to point to BAD_PAGE entries.
42
 *
43
 * ZERO_PAGE is a special page that is used for zero-initialized
44
 * data and COW.
45
 */
46
pte_t * __bad_pagetable(void)
47
{
48
        extern char empty_bad_page_table[PAGE_SIZE];
49
        unsigned long page;
50
        unsigned long dummy1, dummy2;
51
 
52
        page = ((unsigned long)empty_bad_page_table) + (PT_OFFSET - PAGE_OFFSET);
53
#if __mips__ >= 3
54
        /*
55
         * Use 64bit code even for Linux/MIPS 32bit on R4000
56
         */
57
        __asm__ __volatile__(
58
                ".set\tnoreorder\n"
59
                ".set\tnoat\n\t"
60
                ".set\tmips3\n\t"
61
                "dsll32\t$1,%2,0\n\t"
62
                "dsrl32\t%2,$1,0\n\t"
63
                "or\t%2,$1\n"
64
                "1:\tsd\t%2,(%0)\n\t"
65
                "subu\t%1,1\n\t"
66
                "bnez\t%1,1b\n\t"
67
                "addiu\t%0,8\n\t"
68
                ".set\tmips0\n\t"
69
                ".set\tat\n"
70
                ".set\treorder"
71
                :"=r" (dummy1),
72
                 "=r" (dummy2)
73
                :"r" (pte_val(BAD_PAGE)),
74
                 "0" (page),
75
                 "1" (PAGE_SIZE/8));
76
#else
77
        __asm__ __volatile__(
78
                ".set\tnoreorder\n"
79
                "1:\tsw\t%2,(%0)\n\t"
80
                "subu\t%1,1\n\t"
81
                "bnez\t%1,1b\n\t"
82
                "addiu\t%0,4\n\t"
83
                ".set\treorder"
84
                :"=r" (dummy1),
85
                 "=r" (dummy2)
86
                :"r" (pte_val(BAD_PAGE)),
87
                 "0" (page),
88
                 "1" (PAGE_SIZE/4));
89
#endif
90
 
91
        return (pte_t *)page;
92
}
93
 
94
static inline void
95
__zeropage(unsigned long page)
96
{
97
        unsigned long dummy1, dummy2;
98
 
99
#ifdef __R4000__
100
        /*
101
         * Use 64bit code even for Linux/MIPS 32bit on R4000
102
         */
103
        __asm__ __volatile__(
104
                ".set\tnoreorder\n"
105
                ".set\tnoat\n\t"
106
                ".set\tmips3\n"
107
                "1:\tsd\t$0,(%0)\n\t"
108
                "subu\t%1,1\n\t"
109
                "bnez\t%1,1b\n\t"
110
                "addiu\t%0,8\n\t"
111
                ".set\tmips0\n\t"
112
                ".set\tat\n"
113
                ".set\treorder"
114
                :"=r" (dummy1),
115
                 "=r" (dummy2)
116
                :"0" (page),
117
                 "1" (PAGE_SIZE/8));
118
#else
119
        __asm__ __volatile__(
120
                ".set\tnoreorder\n"
121
                "1:\tsw\t$0,(%0)\n\t"
122
                "subu\t%1,1\n\t"
123
                "bnez\t%1,1b\n\t"
124
                "addiu\t%0,4\n\t"
125
                ".set\treorder"
126
                :"=r" (dummy1),
127
                 "=r" (dummy2)
128
                :"0" (page),
129
                 "1" (PAGE_SIZE/4));
130
#endif
131
}
132
 
133
static inline void
134
zeropage(unsigned long page)
135
{
136
        sys_cacheflush((void *)page, PAGE_SIZE, BCACHE);
137
        sync_mem();
138
        __zeropage(page + (PT_OFFSET - PAGE_OFFSET));
139
}
140
 
141
pte_t __bad_page(void)
142
{
143
        extern char empty_bad_page[PAGE_SIZE];
144
        unsigned long page = (unsigned long)empty_bad_page;
145
 
146
        zeropage(page);
147
        return pte_mkdirty(mk_pte(page, PAGE_SHARED));
148
}
149
 
150
unsigned long __zero_page(void)
151
{
152
        unsigned long page = (unsigned long) empty_zero_page;
153
 
154
        zeropage(page);
155
        return page;
156
}
157
 
158
/*
159
 * This is horribly inefficient ...
160
 */
161
void __copy_page(unsigned long from, unsigned long to)
162
{
163
        /*
164
         * Now copy page from uncached KSEG1 to KSEG0.  The copy destination
165
         * is in KSEG0 so that we keep stupid L2 caches happy.
166
         */
167
        if(from == (unsigned long) empty_zero_page)
168
        {
169
                /*
170
                 * The page copied most is the COW empty_zero_page.  Since we
171
                 * know its contents we can avoid the writeback reading of
172
                 * the page.  Speeds up the standard case a lot.
173
                 */
174
                __zeropage(to);
175
        }
176
        else
177
        {
178
                /*
179
                 * Force writeback of old page to memory.  We don't know the
180
                 * virtual address, so we have to flush the entire cache ...
181
                 */
182
                sys_cacheflush(0, ~0, DCACHE);
183
                sync_mem();
184
                memcpy((void *) to,
185
                       (void *) (from + (PT_OFFSET - PAGE_OFFSET)), PAGE_SIZE);
186
        }
187
        /*
188
         * Now writeback the page again if colour has changed.
189
         * Actually this does a Hit_Writeback, but due to an artifact in
190
         * the R4xx0 implementation this should be slightly faster.
191
         * Then sweep chipset controlled secondary caches and the ICACHE.
192
         */
193
        if (page_colour(from) != page_colour(to))
194
                sys_cacheflush(0, ~0, DCACHE);
195
        sys_cacheflush(0, ~0, ICACHE);
196
}
197
 
198
void show_mem(void)
199
{
200
        int i, free = 0, total = 0, reserved = 0;
201
        int shared = 0;
202
 
203
        printk("Mem-info:\n");
204
        show_free_areas();
205
        printk("Free swap:       %6dkB\n", nr_swap_pages<<(PAGE_SHIFT-10));
206
        i = (high_memory - PAGE_OFFSET) >> PAGE_SHIFT;
207
        while (i-- > 0) {
208
                total++;
209
                if (mem_map[i].reserved)
210
                        reserved++;
211
                else if (!mem_map[i].count)
212
                        free++;
213
                else
214
                        shared += mem_map[i].count-1;
215
        }
216
        printk("%d pages of RAM\n", total);
217
        printk("%d free pages\n", free);
218
        printk("%d reserved pages\n", reserved);
219
        printk("%d pages shared\n", shared);
220
        show_buffers();
221
#ifdef CONFIG_NET
222
        show_net_buffers();
223
#endif
224
}
225
 
226
extern unsigned long free_area_init(unsigned long, unsigned long);
227
 
228
unsigned long paging_init(unsigned long start_mem, unsigned long end_mem)
229
{
230
        pgd_init((unsigned long)swapper_pg_dir - (PT_OFFSET - PAGE_OFFSET));
231
        return free_area_init(start_mem, end_mem);
232
}
233
 
234
void mem_init(unsigned long start_mem, unsigned long end_mem)
235
{
236
        int codepages = 0;
237
        int datapages = 0;
238
        unsigned long tmp;
239
        extern int _etext;
240
 
241
#ifdef CONFIG_MIPS_JAZZ
242
        start_mem = vdma_init(start_mem, end_mem);
243
#endif
244
 
245
        end_mem &= PAGE_MASK;
246
        high_memory = end_mem;
247
 
248
        /* mark usable pages in the mem_map[] */
249
        start_mem = PAGE_ALIGN(start_mem);
250
 
251
        tmp = start_mem;
252
        while (tmp < high_memory) {
253
                mem_map[MAP_NR(tmp)].reserved = 0;
254
                tmp += PAGE_SIZE;
255
        }
256
 
257
#ifdef CONFIG_DESKSTATION_TYNE
258
        deskstation_tyne_dma_init();
259
#endif
260
#ifdef CONFIG_SOUND
261
        sound_mem_init();
262
#endif
263
        for (tmp = PAGE_OFFSET ; tmp < high_memory ; tmp += PAGE_SIZE) {
264
                if (mem_map[MAP_NR(tmp)].reserved) {
265
                        if (tmp < (unsigned long) &_etext)
266
                                codepages++;
267
                        else if (tmp < start_mem)
268
                                datapages++;
269
                        continue;
270
                }
271
                mem_map[MAP_NR(tmp)].count = 1;
272
                free_page(tmp);
273
        }
274
        tmp = nr_free_pages << PAGE_SHIFT;
275
        printk("Memory: %luk/%luk available (%dk kernel code, %dk data)\n",
276
                tmp >> 10,
277
                (high_memory - PAGE_OFFSET) >> 10,
278
                codepages << (PAGE_SHIFT-10),
279
                datapages << (PAGE_SHIFT-10));
280
 
281
        return;
282
}
283
 
284
void si_meminfo(struct sysinfo *val)
285
{
286
        int i;
287
 
288
        i = high_memory >> PAGE_SHIFT;
289
        val->totalram = 0;
290
        val->sharedram = 0;
291
        val->freeram = nr_free_pages << PAGE_SHIFT;
292
        val->bufferram = buffermem;
293
        while (i-- > 0)  {
294
                if (mem_map[i].reserved)
295
                        continue;
296
                val->totalram++;
297
                if (!mem_map[i].count)
298
                        continue;
299
                val->sharedram += mem_map[i].count-1;
300
        }
301
        val->totalram <<= PAGE_SHIFT;
302
        val->sharedram <<= PAGE_SHIFT;
303
        return;
304
}

powered by: WebSVN 2.1.0

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