2 * linux/arch/i386/mm/init.c
4 * Copyright (C) 1995 Linus Torvalds
7 #include <linux/config.h>
8 #include <linux/signal.h>
9 #include <linux/sched.h>
10 #include <linux/kernel.h>
11 #include <linux/errno.h>
12 #include <linux/string.h>
13 #include <linux/types.h>
14 #include <linux/ptrace.h>
15 #include <linux/mman.h>
17 #include <linux/swap.h>
18 #include <linux/smp.h>
19 #include <linux/init.h>
20 #ifdef CONFIG_BLK_DEV_INITRD
21 #include <linux/blk.h>
24 #include <asm/processor.h>
25 #include <asm/system.h>
26 #include <asm/uaccess.h>
27 #include <asm/pgtable.h>
29 #include <asm/fixmap.h>
31 extern void show_net_buffers(void);
32 extern unsigned long init_smp_mappings(unsigned long);
34 void __bad_pte_kernel(pmd_t
*pmd
)
36 printk("Bad pmd in pte_alloc: %08lx\n", pmd_val(*pmd
));
37 pmd_val(*pmd
) = _KERNPG_TABLE
+ __pa(BAD_PAGETABLE
);
40 void __bad_pte(pmd_t
*pmd
)
42 printk("Bad pmd in pte_alloc: %08lx\n", pmd_val(*pmd
));
43 pmd_val(*pmd
) = _PAGE_TABLE
+ __pa(BAD_PAGETABLE
);
46 pte_t
*get_pte_kernel_slow(pmd_t
*pmd
, unsigned long offset
)
50 pte
= (pte_t
*) __get_free_page(GFP_KERNEL
);
53 clear_page((unsigned long)pte
);
54 pmd_val(*pmd
) = _KERNPG_TABLE
+ __pa(pte
);
57 pmd_val(*pmd
) = _KERNPG_TABLE
+ __pa(BAD_PAGETABLE
);
60 free_page((unsigned long)pte
);
62 __bad_pte_kernel(pmd
);
65 return (pte_t
*) pmd_page(*pmd
) + offset
;
68 pte_t
*get_pte_slow(pmd_t
*pmd
, unsigned long offset
)
72 pte
= (unsigned long) __get_free_page(GFP_KERNEL
);
76 pmd_val(*pmd
) = _PAGE_TABLE
+ __pa(pte
);
77 return (pte_t
*)(pte
+ offset
);
79 pmd_val(*pmd
) = _PAGE_TABLE
+ __pa(BAD_PAGETABLE
);
87 return (pte_t
*) (pmd_page(*pmd
) + offset
);
90 int do_check_pgt_cache(int low
, int high
)
93 if(pgtable_cache_size
> high
) {
96 free_pgd_slow(get_pgd_fast()), freed
++;
98 free_pmd_slow(get_pmd_fast()), freed
++;
100 free_pte_slow(get_pte_fast()), freed
++;
101 } while(pgtable_cache_size
> low
);
107 * BAD_PAGE is the page that is used for page faults when linux
108 * is out-of-memory. Older versions of linux just did a
109 * do_exit(), but using this instead means there is less risk
110 * for a process dying in kernel mode, possibly leaving an inode
113 * BAD_PAGETABLE is the accompanying page-table: it is initialized
114 * to point to BAD_PAGE entries.
116 * ZERO_PAGE is a special page that is used for zero-initialized
119 pte_t
* __bad_pagetable(void)
121 extern char empty_bad_page_table
[PAGE_SIZE
];
124 __asm__
__volatile__("cld ; rep ; stosl"
125 : "=&D" (d0
), "=&c" (d1
)
126 : "a" (pte_val(BAD_PAGE
)),
127 "0" ((long) empty_bad_page_table
),
130 return (pte_t
*) empty_bad_page_table
;
133 pte_t
__bad_page(void)
135 extern char empty_bad_page
[PAGE_SIZE
];
138 __asm__
__volatile__("cld ; rep ; stosl"
139 : "=&D" (d0
), "=&c" (d1
)
141 "0" ((long) empty_bad_page
),
144 return pte_mkdirty(mk_pte((unsigned long) empty_bad_page
, PAGE_SHARED
));
149 int i
,free
= 0,total
= 0,reserved
= 0;
150 int shared
= 0, cached
= 0;
152 printk("Mem-info:\n");
154 printk("Free swap: %6dkB\n",nr_swap_pages
<<(PAGE_SHIFT
-10));
158 if (PageReserved(mem_map
+i
))
160 else if (PageSwapCache(mem_map
+i
))
162 else if (!page_count(mem_map
+i
))
165 shared
+= page_count(mem_map
+i
) - 1;
167 printk("%d pages of RAM\n",total
);
168 printk("%d reserved pages\n",reserved
);
169 printk("%d pages shared\n",shared
);
170 printk("%d pages swap cached\n",cached
);
171 printk("%ld pages in page table cache\n",pgtable_cache_size
);
177 extern unsigned long free_area_init(unsigned long, unsigned long);
179 /* References to section boundaries */
181 extern char _text
, _etext
, _edata
, __bss_start
, _end
;
182 extern char __init_begin
, __init_end
;
185 * allocate page table(s) for compile-time fixed mappings
187 static unsigned long __init
fixmap_init(unsigned long start_mem
)
191 unsigned long address
;
193 start_mem
= PAGE_ALIGN(start_mem
);
195 for (idx
=1; idx
<= __end_of_fixed_addresses
; idx
+= PTRS_PER_PTE
)
197 address
= __fix_to_virt(__end_of_fixed_addresses
-idx
);
198 pg_dir
= swapper_pg_dir
+ (address
>> PGDIR_SHIFT
);
199 memset((void *)start_mem
, 0, PAGE_SIZE
);
200 pgd_val(*pg_dir
) = _PAGE_TABLE
| __pa(start_mem
);
201 start_mem
+= PAGE_SIZE
;
207 static void set_pte_phys (unsigned long vaddr
, unsigned long phys
)
212 pte
= pte_offset(pmd_offset(pgd_offset_k(vaddr
), vaddr
), vaddr
);
214 if (boot_cpu_data
.x86_capability
& X86_FEATURE_PGE
)
215 pgprot_val(prot
) |= _PAGE_GLOBAL
;
216 set_pte(pte
, mk_pte_phys(phys
, prot
));
221 void set_fixmap (enum fixed_addresses idx
, unsigned long phys
)
223 unsigned long address
= __fix_to_virt(idx
);
225 if (idx
>= __end_of_fixed_addresses
) {
226 printk("Invalid set_fixmap\n");
229 set_pte_phys (address
,phys
);
233 * paging_init() sets up the page tables - note that the first 4MB are
234 * already mapped by head.S.
236 * This routines also unmaps the page at virtual kernel address 0, so
237 * that we can trap those pesky NULL-reference errors in the kernel.
239 __initfunc(unsigned long paging_init(unsigned long start_mem
, unsigned long end_mem
))
244 unsigned long address
;
247 * Physical page 0 is special; it's not touched by Linux since BIOS
248 * and SMM (for laptops with [34]86/SL chips) may need it. It is read
249 * and write protected to detect null pointer references in the
251 * It may also hold the MP configuration table when we are booting SMP.
253 start_mem
= PAGE_ALIGN(start_mem
);
254 address
= PAGE_OFFSET
;
255 pg_dir
= swapper_pg_dir
;
256 /* unmap the original low memory mappings */
257 pgd_val(pg_dir
[0]) = 0;
259 /* Map whole memory from PAGE_OFFSET */
260 pg_dir
+= USER_PGD_PTRS
;
261 while (address
< end_mem
) {
263 * If we're running on a Pentium CPU, we can use the 4MB
266 * The page tables we create span up to the next 4MB
267 * virtual memory boundary, but that's OK as we won't
268 * use that memory anyway.
270 if (boot_cpu_data
.x86_capability
& X86_FEATURE_PSE
) {
273 set_in_cr4(X86_CR4_PSE
);
274 boot_cpu_data
.wp_works_ok
= 1;
275 __pe
= _KERNPG_TABLE
+ _PAGE_4M
+ __pa(address
);
276 /* Make it "global" too if supported */
277 if (boot_cpu_data
.x86_capability
& X86_FEATURE_PGE
) {
278 set_in_cr4(X86_CR4_PGE
);
279 __pe
+= _PAGE_GLOBAL
;
281 pgd_val(*pg_dir
) = __pe
;
283 address
+= 4*1024*1024;
288 * We're on a [34]86, use normal page tables.
289 * pg_table is physical at this point
291 pg_table
= (pte_t
*) (PAGE_MASK
& pgd_val(*pg_dir
));
293 pg_table
= (pte_t
*) __pa(start_mem
);
294 start_mem
+= PAGE_SIZE
;
297 pgd_val(*pg_dir
) = _PAGE_TABLE
| (unsigned long) pg_table
;
300 /* now change pg_table to kernel virtual addresses */
301 pg_table
= (pte_t
*) __va(pg_table
);
302 for (tmp
= 0 ; tmp
< PTRS_PER_PTE
; tmp
++,pg_table
++) {
303 pte_t pte
= mk_pte(address
, PAGE_KERNEL
);
304 if (address
>= end_mem
)
306 set_pte(pg_table
, pte
);
307 address
+= PAGE_SIZE
;
310 start_mem
= fixmap_init(start_mem
);
312 start_mem
= init_smp_mappings(start_mem
);
316 return free_area_init(start_mem
, end_mem
);
320 * Test if the WP bit works in supervisor mode. It isn't supported on 386's
321 * and also on some strange 486's (NexGen etc.). All 586+'s are OK. The jumps
322 * before and after the test are here to work-around some nasty CPU bugs.
325 __initfunc(void test_wp_bit(void))
327 unsigned char tmp_reg
;
328 unsigned long old
= pg0
[0];
330 printk("Checking if this processor honours the WP bit even in supervisor mode... ");
331 pg0
[0] = pte_val(mk_pte(PAGE_OFFSET
, PAGE_READONLY
));
333 current
->mm
->mmap
->vm_start
+= PAGE_SIZE
;
334 __asm__
__volatile__(
339 :"=m" (*(char *) __va(0)),
345 current
->mm
->mmap
->vm_start
-= PAGE_SIZE
;
346 if (boot_cpu_data
.wp_works_ok
< 0) {
347 boot_cpu_data
.wp_works_ok
= 0;
349 #ifdef CONFIG_X86_WP_WORKS_OK
350 panic("This kernel doesn't support CPU's with broken WP. Recompile it for a 386!");
356 __initfunc(void mem_init(unsigned long start_mem
, unsigned long end_mem
))
358 unsigned long start_low_mem
= PAGE_SIZE
;
360 int reservedpages
= 0;
364 unsigned long endbase
;
366 end_mem
&= PAGE_MASK
;
367 high_memory
= (void *) end_mem
;
368 max_mapnr
= num_physpages
= MAP_NR(end_mem
);
370 /* clear the zero-page */
371 memset(empty_zero_page
, 0, PAGE_SIZE
);
373 /* mark usable pages in the mem_map[] */
374 start_low_mem
= PAGE_ALIGN(start_low_mem
)+PAGE_OFFSET
;
378 * But first pinch a few for the stack/trampoline stuff
379 * FIXME: Don't need the extra page at 4K, but need to fix
380 * trampoline before removing it. (see the GDT stuff)
383 start_low_mem
+= PAGE_SIZE
; /* 32bit startup code */
384 start_low_mem
= smp_alloc_memory(start_low_mem
); /* AP processor stacks */
386 start_mem
= PAGE_ALIGN(start_mem
);
389 * IBM messed up *AGAIN* in their thinkpad: 0xA0000 -> 0x9F000.
390 * They seem to have done something stupid with the floppy
391 * controller as well..
392 * The amount of available base memory is in WORD 40:13.
394 endbase
= PAGE_OFFSET
+ ((*(unsigned short *)__va(0x413) * 1024) & PAGE_MASK
);
395 while (start_low_mem
< endbase
) {
396 clear_bit(PG_reserved
, &mem_map
[MAP_NR(start_low_mem
)].flags
);
397 start_low_mem
+= PAGE_SIZE
;
400 while (start_mem
< end_mem
) {
401 clear_bit(PG_reserved
, &mem_map
[MAP_NR(start_mem
)].flags
);
402 start_mem
+= PAGE_SIZE
;
404 for (tmp
= PAGE_OFFSET
; tmp
< end_mem
; tmp
+= PAGE_SIZE
) {
405 if (tmp
>= MAX_DMA_ADDRESS
)
406 clear_bit(PG_DMA
, &mem_map
[MAP_NR(tmp
)].flags
);
407 if (PageReserved(mem_map
+MAP_NR(tmp
))) {
408 if (tmp
>= (unsigned long) &_text
&& tmp
< (unsigned long) &_edata
) {
409 if (tmp
< (unsigned long) &_etext
)
413 } else if (tmp
>= (unsigned long) &__init_begin
414 && tmp
< (unsigned long) &__init_end
)
416 else if (tmp
>= (unsigned long) &__bss_start
417 && tmp
< (unsigned long) start_mem
)
423 set_page_count(mem_map
+MAP_NR(tmp
), 1);
424 #ifdef CONFIG_BLK_DEV_INITRD
425 if (!initrd_start
|| (tmp
< initrd_start
|| tmp
>=
430 printk("Memory: %luk/%luk available (%dk kernel code, %dk reserved, %dk data, %dk init)\n",
431 (unsigned long) nr_free_pages
<< (PAGE_SHIFT
-10),
432 max_mapnr
<< (PAGE_SHIFT
-10),
433 codepages
<< (PAGE_SHIFT
-10),
434 reservedpages
<< (PAGE_SHIFT
-10),
435 datapages
<< (PAGE_SHIFT
-10),
436 initpages
<< (PAGE_SHIFT
-10));
438 if (boot_cpu_data
.wp_works_ok
< 0)
442 void free_initmem(void)
446 addr
= (unsigned long)(&__init_begin
);
447 for (; addr
< (unsigned long)(&__init_end
); addr
+= PAGE_SIZE
) {
448 mem_map
[MAP_NR(addr
)].flags
&= ~(1 << PG_reserved
);
449 set_page_count(mem_map
+MAP_NR(addr
), 1);
452 printk ("Freeing unused kernel memory: %dk freed\n", (&__init_end
- &__init_begin
) >> 10);
455 void si_meminfo(struct sysinfo
*val
)
462 val
->freeram
= nr_free_pages
<< PAGE_SHIFT
;
463 val
->bufferram
= atomic_read(&buffermem
);
465 if (PageReserved(mem_map
+i
))
468 if (!page_count(mem_map
+i
))
470 val
->sharedram
+= page_count(mem_map
+i
) - 1;
472 val
->totalram
<<= PAGE_SHIFT
;
473 val
->sharedram
<<= PAGE_SHIFT
;