patch-2.3.48 linux/arch/mips/mm/init.c
Next file: linux/arch/mips/mm/loadmmu.c
Previous file: linux/arch/mips/mm/fault.c
Back to the patch index
Back to the overall index
- Lines: 413
- Date:
Thu Feb 24 22:52:30 2000
- Orig file:
v2.3.47/linux/arch/mips/mm/init.c
- Orig date:
Thu Feb 10 17:11:04 2000
diff -u --recursive --new-file v2.3.47/linux/arch/mips/mm/init.c linux/arch/mips/mm/init.c
@@ -1,10 +1,11 @@
-/* $Id: init.c,v 1.13 1999/05/01 22:40:40 ralf Exp $
+/* $Id: init.c,v 1.27 2000/02/23 01:33:56 ralf Exp $
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
- * Copyright (C) 1994 - 1998 by Ralf Baechle
+ * Copyright (C) 1994 - 2000 by Ralf Baechle
+ * Copyright (C) 2000 Silicon Graphics, Inc.
*/
#include <linux/config.h>
#include <linux/init.h>
@@ -18,6 +19,8 @@
#include <linux/ptrace.h>
#include <linux/mman.h>
#include <linux/mm.h>
+#include <linux/bootmem.h>
+#include <linux/highmem.h>
#include <linux/swap.h>
#include <linux/swapctl.h>
#ifdef CONFIG_BLK_DEV_INITRD
@@ -30,21 +33,28 @@
#include <asm/jazzdma.h>
#include <asm/system.h>
#include <asm/pgtable.h>
-#ifdef CONFIG_SGI
+#include <asm/pgalloc.h>
+#ifdef CONFIG_SGI_IP22
#include <asm/sgialib.h>
#endif
#include <asm/mmu_context.h>
+static unsigned long totalram_pages = 0;
+
+extern void prom_fixup_mem_map(unsigned long start, unsigned long end);
+extern void prom_free_prom_memory(void);
+
+
void __bad_pte_kernel(pmd_t *pmd)
{
printk("Bad pmd in pte_alloc_kernel: %08lx\n", pmd_val(*pmd));
- pmd_val(*pmd) = BAD_PAGETABLE;
+ pmd_set(pmd, BAD_PAGETABLE);
}
void __bad_pte(pmd_t *pmd)
{
printk("Bad pmd in pte_alloc: %08lx\n", pmd_val(*pmd));
- pmd_val(*pmd) = BAD_PAGETABLE;
+ pmd_set(pmd, BAD_PAGETABLE);
}
pte_t *get_pte_kernel_slow(pmd_t *pmd, unsigned long offset)
@@ -54,11 +64,11 @@
page = (pte_t *) __get_free_page(GFP_USER);
if (pmd_none(*pmd)) {
if (page) {
- clear_page((unsigned long)page);
+ clear_page(page);
pmd_val(*pmd) = (unsigned long)page;
return page + offset;
}
- pmd_val(*pmd) = BAD_PAGETABLE;
+ pmd_set(pmd, BAD_PAGETABLE);
return NULL;
}
free_page((unsigned long)page);
@@ -76,11 +86,11 @@
page = (pte_t *) __get_free_page(GFP_KERNEL);
if (pmd_none(*pmd)) {
if (page) {
- clear_page((unsigned long)page);
+ clear_page(page);
pmd_val(*pmd) = (unsigned long)page;
return page + offset;
}
- pmd_val(*pmd) = BAD_PAGETABLE;
+ pmd_set(pmd, BAD_PAGETABLE);
return NULL;
}
free_page((unsigned long)page);
@@ -128,9 +138,9 @@
panic("Oh boy, that early out of memory?");
pg = MAP_NR(empty_zero_page);
- while(pg < MAP_NR(empty_zero_page) + (1 << order)) {
+ while (pg < MAP_NR(empty_zero_page) + (1 << order)) {
set_bit(PG_reserved, &mem_map[pg].flags);
- atomic_set(&mem_map[pg].count, 0);
+ set_page_count(mem_map + pg, 0);
pg++;
}
@@ -138,7 +148,7 @@
zero_page_mask = (size - 1) & PAGE_MASK;
memset((void *)empty_zero_page, 0, size);
- return size;
+ return 1UL << order;
}
int do_check_pgt_cache(int low, int high)
@@ -174,43 +184,9 @@
pte_t * __bad_pagetable(void)
{
extern char empty_bad_page_table[PAGE_SIZE];
- unsigned long page;
- unsigned long dummy1, dummy2;
-#if (_MIPS_ISA == _MIPS_ISA_MIPS3) || (_MIPS_ISA == _MIPS_ISA_MIPS4)
- unsigned long dummy3;
-#endif
+ unsigned long page, dummy1, dummy2;
page = (unsigned long) empty_bad_page_table;
- /*
- * As long as we only save the low 32 bit of the 64 bit wide
- * R4000 registers on interrupt we cannot use 64 bit memory accesses
- * to the main memory.
- */
-#if (_MIPS_ISA == _MIPS_ISA_MIPS3) || (_MIPS_ISA == _MIPS_ISA_MIPS4)
- /*
- * Use 64bit code even for Linux/MIPS 32bit on R4000
- */
- __asm__ __volatile__(
- ".set\tnoreorder\n"
- ".set\tnoat\n\t"
- ".set\tmips3\n\t"
- "dsll32\t$1,%2,0\n\t"
- "dsrl32\t%2,$1,0\n\t"
- "or\t%2,$1\n"
- "1:\tsd\t%2,(%0)\n\t"
- "subu\t%1,1\n\t"
- "bnez\t%1,1b\n\t"
- "addiu\t%0,8\n\t"
- ".set\tmips0\n\t"
- ".set\tat\n"
- ".set\treorder"
- :"=r" (dummy1),
- "=r" (dummy2),
- "=r" (dummy3)
- :"0" (page),
- "1" (PAGE_SIZE/8),
- "2" (pte_val(BAD_PAGE)));
-#else /* (_MIPS_ISA == _MIPS_ISA_MIPS1) || (_MIPS_ISA == _MIPS_ISA_MIPS2) */
__asm__ __volatile__(
".set\tnoreorder\n"
"1:\tsw\t%2,(%0)\n\t"
@@ -218,12 +194,9 @@
"bnez\t%1,1b\n\t"
"addiu\t%0,4\n\t"
".set\treorder"
- :"=r" (dummy1),
- "=r" (dummy2)
- :"r" (pte_val(BAD_PAGE)),
- "0" (page),
- "1" (PAGE_SIZE/4));
-#endif
+ :"=r" (dummy1), "=r" (dummy2)
+ :"r" (pte_val(BAD_PAGE)), "0" (page), "1" (PAGE_SIZE/4)
+ :"$1");
return (pte_t *)page;
}
@@ -231,10 +204,10 @@
pte_t __bad_page(void)
{
extern char empty_bad_page[PAGE_SIZE];
- unsigned long page = (unsigned long)empty_bad_page;
+ unsigned long page = (unsigned long) empty_bad_page;
- clear_page(page);
- return pte_mkdirty(mk_pte(page, PAGE_SHARED));
+ clear_page((void *)page);
+ return pte_mkdirty(mk_pte_phys(__pa(page), PAGE_SHARED));
}
void show_mem(void)
@@ -252,10 +225,10 @@
reserved++;
else if (PageSwapCache(mem_map+i))
cached++;
- else if (!atomic_read(&mem_map[i].count))
+ else if (!page_count(mem_map + i))
free++;
else
- shared += atomic_read(&mem_map[i].count) - 1;
+ shared += page_count(mem_map + i) - 1;
}
printk("%d pages of RAM\n", total);
printk("%d reserved pages\n", reserved);
@@ -266,79 +239,83 @@
show_buffers();
}
-extern unsigned long free_area_init(unsigned long, unsigned long);
+/* References to section boundaries */
-unsigned long __init paging_init(unsigned long start_mem, unsigned long end_mem)
+extern char _ftext, _etext, _fdata, _edata;
+extern char __init_begin, __init_end;
+
+void __init paging_init(void)
{
+ unsigned long zones_size[MAX_NR_ZONES] = {0, 0, 0};
+ unsigned long max_dma, low;
+
/* Initialize the entire pgd. */
pgd_init((unsigned long)swapper_pg_dir);
pgd_init((unsigned long)swapper_pg_dir + PAGE_SIZE / 2);
- return free_area_init(start_mem, end_mem);
+
+ max_dma = virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT;
+ low = max_low_pfn;
+
+ if (low < max_dma)
+ zones_size[ZONE_DMA] = low;
+ else {
+ zones_size[ZONE_DMA] = max_dma;
+ zones_size[ZONE_NORMAL] = low - max_dma;
+ }
+
+ free_area_init(zones_size);
}
-void __init mem_init(unsigned long start_mem, unsigned long end_mem)
+extern int page_is_ram(unsigned long pagenr);
+
+void __init mem_init(void)
{
- int codepages = 0;
- int datapages = 0;
- unsigned long tmp;
- extern int _etext, _ftext;
+ unsigned long codesize, reservedpages, datasize, initsize;
+ unsigned long tmp, ram;
-#ifdef CONFIG_MIPS_JAZZ
- if (mips_machgroup == MACH_GROUP_JAZZ)
- start_mem = vdma_init(start_mem, end_mem);
-#endif
+ max_mapnr = num_physpages = max_low_pfn;
+ high_memory = (void *) __va(max_mapnr << PAGE_SHIFT);
- end_mem &= PAGE_MASK;
- max_mapnr = MAP_NR(end_mem);
- high_memory = (void *)end_mem;
- num_physpages = 0;
-
- /* mark usable pages in the mem_map[] */
- start_mem = PAGE_ALIGN(start_mem);
-
- for(tmp = MAP_NR(start_mem);tmp < max_mapnr;tmp++)
- clear_bit(PG_reserved, &mem_map[tmp].flags);
-
- prom_fixup_mem_map(start_mem, (unsigned long)high_memory);
-
- for (tmp = PAGE_OFFSET; tmp < end_mem; tmp += PAGE_SIZE) {
- /*
- * This is only for PC-style DMA. The onboard DMA
- * of Jazz and Tyne machines is completely different and
- * not handled via a flag in mem_map_t.
- */
- if (tmp >= MAX_DMA_ADDRESS)
- clear_bit(PG_DMA, &mem_map[MAP_NR(tmp)].flags);
- if (PageReserved(mem_map+MAP_NR(tmp))) {
- if ((tmp < (unsigned long) &_etext) &&
- (tmp >= (unsigned long) &_ftext))
- codepages++;
- else if ((tmp < start_mem) &&
- (tmp > (unsigned long) &_etext))
- datapages++;
- continue;
+ totalram_pages += free_all_bootmem();
+ totalram_pages -= setup_zero_pages(); /* Setup zeroed pages. */
+
+ reservedpages = ram = 0;
+ for (tmp = 0; tmp < max_low_pfn; tmp++)
+ if (page_is_ram(tmp)) {
+ ram++;
+ if (PageReserved(mem_map+tmp))
+ reservedpages++;
}
- num_physpages++;
- atomic_set(&mem_map[MAP_NR(tmp)].count, 1);
-#ifdef CONFIG_BLK_DEV_INITRD
- if (!initrd_start || (tmp < initrd_start || tmp >=
- initrd_end))
-#endif
- free_page(tmp);
- }
- tmp = nr_free_pages << PAGE_SHIFT;
- /* Setup zeroed pages. */
- tmp -= setup_zero_pages();
+ codesize = (unsigned long) &_etext - (unsigned long) &_ftext;
+ datasize = (unsigned long) &_edata - (unsigned long) &_fdata;
+ initsize = (unsigned long) &__init_end - (unsigned long) &__init_begin;
+
+ printk("Memory: %luk/%luk available (%ldk kernel code, %ldk reserved, "
+ "%ldk data, %ldk init)\n",
+ (unsigned long) nr_free_pages() << (PAGE_SHIFT-10),
+ ram << (PAGE_SHIFT-10),
+ codesize >> 10,
+ reservedpages << (PAGE_SHIFT-10),
+ datasize >> 10,
+ initsize >> 10);
+}
- printk("Memory: %luk/%luk available (%dk kernel code, %dk data)\n",
- tmp >> 10,
- max_mapnr << (PAGE_SHIFT-10),
- codepages << (PAGE_SHIFT-10),
- datapages << (PAGE_SHIFT-10));
+#ifdef CONFIG_BLK_DEV_INITRD
+void free_initrd_mem(unsigned long start, unsigned long end)
+{
+ for (; start < end; start += PAGE_SIZE) {
+ ClearPageReserved(mem_map + MAP_NR(start));
+ set_page_count(mem_map+MAP_NR(start), 1);
+ free_page(start);
+ totalram_pages++;
+ }
+ printk ("Freeing initrd memory: %ldk freed\n", (end - start) >> 10);
}
+#endif
extern char __init_begin, __init_end;
+extern void prom_free_prom_memory(void);
void free_initmem(void)
{
@@ -346,11 +323,13 @@
prom_free_prom_memory ();
- addr = (unsigned long)(&__init_begin);
- for (; addr < (unsigned long)(&__init_end); addr += PAGE_SIZE) {
- mem_map[MAP_NR(addr)].flags &= ~(1 << PG_reserved);
- atomic_set(&mem_map[MAP_NR(addr)].count, 1);
+ addr = (unsigned long) &__init_begin;
+ while (addr < (unsigned long) &__init_end) {
+ ClearPageReserved(mem_map + MAP_NR(addr));
+ set_page_count(mem_map + MAP_NR(addr), 1);
free_page(addr);
+ totalram_pages++;
+ addr += PAGE_SIZE;
}
printk("Freeing unused kernel memory: %dk freed\n",
(&__init_end - &__init_begin) >> 10);
@@ -358,54 +337,13 @@
void si_meminfo(struct sysinfo *val)
{
- int i;
-
- i = MAP_NR(high_memory);
- val->totalram = 0;
+ val->totalram = totalram_pages;
val->sharedram = 0;
- val->freeram = nr_free_pages << PAGE_SHIFT;
- val->bufferram = atomic_read(&buffermem);
- while (i-- > 0) {
- if (PageReserved(mem_map+i))
- continue;
- val->totalram++;
- if (!atomic_read(&mem_map[i].count))
- continue;
- val->sharedram += atomic_read(&mem_map[i].count) - 1;
- }
- val->totalram <<= PAGE_SHIFT;
- val->sharedram <<= PAGE_SHIFT;
- return;
-}
-
-/* Fixup an immediate instruction */
-static void __init __i_insn_fixup(unsigned int **start, unsigned int **stop,
- unsigned int i_const)
-{
- unsigned int **p, *ip;
-
- for (p = start;p < stop; p++) {
- ip = *p;
- *ip = (*ip & 0xffff0000) | i_const;
- }
-}
-
-#define i_insn_fixup(section, const) \
-do { \
- extern unsigned int *__start_ ## section; \
- extern unsigned int *__stop_ ## section; \
- __i_insn_fixup(&__start_ ## section, &__stop_ ## section, const); \
-} while(0)
+ val->freeram = nr_free_pages();
+ val->bufferram = atomic_read(&buffermem_pages);
+ val->totalhigh = 0;
+ val->freehigh = nr_free_highpages();
+ val->mem_unit = PAGE_SIZE;
-/* Caller is assumed to flush the caches before the first context switch. */
-void __init __asid_setup(unsigned int inc, unsigned int mask,
- unsigned int version_mask,
- unsigned int first_version)
-{
- i_insn_fixup(__asid_inc, inc);
- i_insn_fixup(__asid_mask, mask);
- i_insn_fixup(__asid_version_mask, version_mask);
- i_insn_fixup(__asid_first_version, first_version);
-
- asid_cache = first_version;
+ return;
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)