4 * Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds 5 * Ported to MIPS by Ralf Baechle 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> 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> 26 externvoiddeskstation_tyne_dma_init(void); 27 externvoidsound_mem_init(void); 28 externvoiddie_if_kernel(char*,struct pt_regs
*,long); 29 externvoidshow_net_buffers(void); 31 externchar empty_zero_page
[PAGE_SIZE
]; 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 40 * BAD_PAGETABLE is the accompanying page-table: it is initialized 41 * to point to BAD_PAGE entries. 43 * ZERO_PAGE is a special page that is used for zero-initialized 46 pte_t
*__bad_pagetable(void) 48 externchar empty_bad_page_table
[PAGE_SIZE
]; 50 unsigned long dummy1
, dummy2
; 52 page
= ((unsigned long)empty_bad_page_table
) + (PT_OFFSET
- PAGE_OFFSET
); 55 * Use 64bit code even for Linux/MIPS 32bit on R4000 73 :"r"(pte_val(BAD_PAGE
)), 86 :"r"(pte_val(BAD_PAGE
)), 95 __zeropage(unsigned long page
) 97 unsigned long dummy1
, dummy2
; 101 * Use 64bit code even for Linux/MIPS 32bit on R4000 103 __asm__
__volatile__( 107 "1:\tsd\t$0,(%0)\n\t" 119 __asm__
__volatile__( 121 "1:\tsw\t$0,(%0)\n\t" 134 zeropage(unsigned long page
) 136 sys_cacheflush((void*)page
, PAGE_SIZE
, BCACHE
); 138 __zeropage(page
+ (PT_OFFSET
- PAGE_OFFSET
)); 141 pte_t
__bad_page(void) 143 externchar empty_bad_page
[PAGE_SIZE
]; 144 unsigned long page
= (unsigned long)empty_bad_page
; 147 returnpte_mkdirty(mk_pte(page
, PAGE_SHARED
)); 150 unsigned long__zero_page(void) 152 unsigned long page
= (unsigned long) empty_zero_page
; 159 * This is horribly inefficient ... 161 void__copy_page(unsigned long from
,unsigned long to
) 164 * Now copy page from uncached KSEG1 to KSEG0. The copy destination 165 * is in KSEG0 so that we keep stupid L2 caches happy. 167 if(from
== (unsigned long) empty_zero_page
) 170 * The page copied most is the COW empty_zero_page. Since we 171 * know it's contents we can avoid the writeback reading of 172 * the page. Speeds up the standard case a lot. 179 * Force writeback of old page to memory. We don't know the 180 * virtual address, so we have to flush the entire cache ... 182 sys_cacheflush(0, ~0, DCACHE
); 185 (void*) (from
+ (PT_OFFSET
- PAGE_OFFSET
)), PAGE_SIZE
); 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. 193 if(page_colour(from
) !=page_colour(to
)) 194 sys_cacheflush(0, ~0, DCACHE
); 195 sys_cacheflush(0, ~0, ICACHE
); 200 int i
, free
=0, total
=0, reserved
=0; 203 printk("Mem-info:\n"); 205 printk("Free swap: %6dkB\n", nr_swap_pages
<<(PAGE_SHIFT
-10)); 206 i
= (high_memory
- PAGE_OFFSET
) >> PAGE_SHIFT
; 209 if(mem_map
[i
].reserved
) 211 else if(!mem_map
[i
].count
) 214 shared
+= mem_map
[i
].count
-1; 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
); 226 externunsigned longfree_area_init(unsigned long,unsigned long); 228 unsigned longpaging_init(unsigned long start_mem
,unsigned long end_mem
) 230 pgd_init((unsigned long)swapper_pg_dir
- (PT_OFFSET
- PAGE_OFFSET
)); 231 returnfree_area_init(start_mem
, end_mem
); 234 voidmem_init(unsigned long start_mem
,unsigned long end_mem
) 241 #ifdef CONFIG_MIPS_JAZZ 242 start_mem
=vdma_init(start_mem
, end_mem
); 245 end_mem
&= PAGE_MASK
; 246 high_memory
= end_mem
; 248 /* mark usable pages in the mem_map[] */ 249 start_mem
=PAGE_ALIGN(start_mem
); 252 while(tmp
< high_memory
) { 253 mem_map
[MAP_NR(tmp
)].reserved
=0; 257 #ifdef CONFIG_DESKSTATION_TYNE 258 deskstation_tyne_dma_init(); 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
) 267 else if(tmp
< start_mem
) 271 mem_map
[MAP_NR(tmp
)].count
=1; 274 tmp
= nr_free_pages
<< PAGE_SHIFT
; 275 printk("Memory: %luk/%luk available (%dk kernel code, %dk data)\n", 277 (high_memory
- PAGE_OFFSET
) >>10, 278 codepages
<< (PAGE_SHIFT
-10), 279 datapages
<< (PAGE_SHIFT
-10)); 284 voidsi_meminfo(struct sysinfo
*val
) 288 i
= high_memory
>> PAGE_SHIFT
; 291 val
->freeram
= nr_free_pages
<< PAGE_SHIFT
; 292 val
->bufferram
= buffermem
; 294 if(mem_map
[i
].reserved
) 297 if(!mem_map
[i
].count
) 299 val
->sharedram
+= mem_map
[i
].count
-1; 301 val
->totalram
<<= PAGE_SHIFT
; 302 val
->sharedram
<<= PAGE_SHIFT
;