patch-2.4.19 linux-2.4.19/arch/mips/mm/init.c
Next file: linux-2.4.19/arch/mips/mm/ioremap.c
Previous file: linux-2.4.19/arch/mips/mm/fault.c
Back to the patch index
Back to the overall index
- Lines: 265
- Date:
Fri Aug 2 17:39:43 2002
- Orig file:
linux-2.4.18/arch/mips/mm/init.c
- Orig date:
Wed Jul 4 11:50:39 2001
diff -urN linux-2.4.18/arch/mips/mm/init.c linux-2.4.19/arch/mips/mm/init.c
@@ -25,9 +25,7 @@
#include <linux/highmem.h>
#include <linux/swap.h>
#include <linux/swapctl.h>
-#ifdef CONFIG_BLK_DEV_INITRD
#include <linux/blk.h>
-#endif
#include <asm/bootinfo.h>
#include <asm/cachectl.h>
@@ -37,15 +35,13 @@
#include <asm/system.h>
#include <asm/pgtable.h>
#include <asm/pgalloc.h>
-#ifdef CONFIG_SGI_IP22
-#include <asm/sgialib.h>
-#endif
#include <asm/mmu_context.h>
#include <asm/tlb.h>
mmu_gather_t mmu_gathers[NR_CPUS];
-
+unsigned long highstart_pfn, highend_pfn;
static unsigned long totalram_pages;
+static unsigned long totalhigh_pages;
extern void prom_free_prom_memory(void);
@@ -98,19 +94,39 @@
{
int freed = 0;
- if(pgtable_cache_size > high) {
+ if (pgtable_cache_size > high) {
do {
- if(pgd_quicklist)
+ if (pgd_quicklist)
free_pgd_slow(get_pgd_fast()), freed++;
- if(pmd_quicklist)
+ if (pmd_quicklist)
free_pmd_slow(get_pmd_fast()), freed++;
- if(pte_quicklist)
+ if (pte_quicklist)
free_pte_slow(get_pte_fast()), freed++;
- } while(pgtable_cache_size > low);
+ } while (pgtable_cache_size > low);
}
return freed;
}
+#if CONFIG_HIGHMEM
+pte_t *kmap_pte;
+pgprot_t kmap_prot;
+
+#define kmap_get_fixmap_pte(vaddr) \
+ pte_offset(pmd_offset(pgd_offset_k(vaddr), (vaddr)), (vaddr))
+
+static void __init kmap_init(void)
+{
+ unsigned long kmap_vstart;
+
+ /* cache the first kmap pte */
+ kmap_vstart = __fix_to_virt(FIX_KMAP_BEGIN);
+ kmap_pte = kmap_get_fixmap_pte(kmap_vstart);
+
+ kmap_prot = PAGE_KERNEL;
+}
+
+#endif /* CONFIG_HIGHMEM */
+
void show_mem(void)
{
int i, free = 0, total = 0, reserved = 0;
@@ -145,19 +161,85 @@
extern char _ftext, _etext, _fdata, _edata;
extern char __init_begin, __init_end;
-void __init paging_init(void)
+static void __init fixrange_init (unsigned long start, unsigned long end,
+ pgd_t *pgd_base)
{
- unsigned long zones_size[MAX_NR_ZONES] = {0, 0, 0};
- unsigned long max_dma, low;
+ pgd_t *pgd;
+ pmd_t *pmd;
+ pte_t *pte;
+ int i, j;
+ unsigned long vaddr;
+
+ vaddr = start;
+ i = __pgd_offset(vaddr);
+ j = __pmd_offset(vaddr);
+ pgd = pgd_base + i;
+
+ for ( ; (i < PTRS_PER_PGD) && (vaddr != end); pgd++, i++) {
+ pmd = (pmd_t *)pgd;
+ for (; (j < PTRS_PER_PMD) && (vaddr != end); pmd++, j++) {
+ if (pmd_none(*pmd)) {
+ pte = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE);
+ set_pmd(pmd, __pmd(pte));
+ if (pte != pte_offset(pmd, 0))
+ BUG();
+ }
+ vaddr += PMD_SIZE;
+ }
+ j = 0;
+ }
+}
+
+void __init pagetable_init(void)
+{
+ unsigned long vaddr;
+ pgd_t *pgd, *pgd_base;
+ pmd_t *pmd;
+ pte_t *pte;
/* Initialize the entire pgd. */
pgd_init((unsigned long)swapper_pg_dir);
- pgd_init((unsigned long)swapper_pg_dir + PAGE_SIZE / 2);
+ pgd_init((unsigned long)swapper_pg_dir +
+ sizeof(pgd_t ) * USER_PTRS_PER_PGD);
+
+ pgd_base = swapper_pg_dir;
+
+#ifdef CONFIG_HIGHMEM
+ /*
+ * Fixed mappings:
+ */
+ vaddr = __fix_to_virt(__end_of_fixed_addresses - 1) & PMD_MASK;
+ fixrange_init(vaddr, 0, pgd_base);
+
+ /*
+ * Permanent kmaps:
+ */
+ vaddr = PKMAP_BASE;
+ fixrange_init(vaddr, vaddr + PAGE_SIZE*LAST_PKMAP, pgd_base);
+
+ pgd = swapper_pg_dir + __pgd_offset(vaddr);
+ pmd = pmd_offset(pgd, vaddr);
+ pte = pte_offset(pmd, vaddr);
+ pkmap_page_table = pte;
+#endif
+}
+
+void __init paging_init(void)
+{
+ unsigned long zones_size[MAX_NR_ZONES] = {0, 0, 0};
+ unsigned long max_dma, high, low;
+
+ pagetable_init();
+
+#ifdef CONFIG_HIGHMEM
+ kmap_init();
+#endif
max_dma = virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT;
low = max_low_pfn;
+ high = highend_pfn;
-#if defined(CONFIG_PCI) || defined(CONFIG_ISA)
+#ifdef CONFIG_ISA
if (low < max_dma)
zones_size[ZONE_DMA] = low;
else {
@@ -167,6 +249,9 @@
#else
zones_size[ZONE_DMA] = low;
#endif
+#ifdef CONFIG_HIGHMEM
+ zones_size[ZONE_HIGHMEM] = high - low;
+#endif
free_area_init(zones_size);
}
@@ -201,8 +286,19 @@
unsigned long codesize, reservedpages, datasize, initsize;
unsigned long tmp, ram;
- max_mapnr = num_physpages = max_low_pfn;
- high_memory = (void *) __va(max_mapnr << PAGE_SHIFT);
+#if defined(CONFIG_DISCONTIGMEM) && defined(CONFIG_HIGHMEM)
+#error "CONFIG_HIGHMEM and CONFIG_DISCONTIGMEM dont work together yet"
+#endif
+
+#ifdef CONFIG_HIGHMEM
+ highstart_pfn = (KSEG1 - KSEG0) >> PAGE_SHIFT;
+ highmem_start_page = mem_map + highstart_pfn;
+ max_mapnr = num_physpages = highend_pfn;
+ num_mappedpages = max_low_pfn;
+#else
+ max_mapnr = num_mappedpages = num_physpages = max_low_pfn;
+#endif
+ high_memory = (void *) __va(max_low_pfn * PAGE_SIZE);
totalram_pages += free_all_bootmem();
totalram_pages -= setup_zero_pages(); /* Setup zeroed pages. */
@@ -215,25 +311,43 @@
reservedpages++;
}
+#ifdef CONFIG_HIGHMEM
+ for (tmp = highstart_pfn; tmp < highend_pfn; tmp++) {
+ struct page *page = mem_map + tmp;
+
+ if (!page_is_ram(tmp)) {
+ SetPageReserved(page);
+ continue;
+ }
+ ClearPageReserved(page);
+ set_bit(PG_highmem, &page->flags);
+ atomic_set(&page->count, 1);
+ __free_page(page);
+ totalhigh_pages++;
+ }
+ totalram_pages += totalhigh_pages;
+#endif
+
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",
+ printk(KERN_INFO "Memory: %luk/%luk available (%ldk kernel code, "
+ "%ldk reserved, %ldk data, %ldk init, %ldk highmem)\n",
(unsigned long) nr_free_pages() << (PAGE_SHIFT-10),
ram << (PAGE_SHIFT-10),
codesize >> 10,
reservedpages << (PAGE_SHIFT-10),
datasize >> 10,
- initsize >> 10);
+ initsize >> 10,
+ (unsigned long) (totalhigh_pages << (PAGE_SHIFT-10)));
}
#ifdef CONFIG_BLK_DEV_INITRD
void free_initrd_mem(unsigned long start, unsigned long end)
{
if (start < end)
- printk("Freeing initrd memory: %ldk freed\n",
+ printk(KERN_INFO "Freeing initrd memory: %ldk freed\n",
(end - start) >> 10);
for (; start < end; start += PAGE_SIZE) {
@@ -262,17 +376,17 @@
totalram_pages++;
addr += PAGE_SIZE;
}
- printk("Freeing unused kernel memory: %dk freed\n",
+ printk(KERN_INFO "Freeing unused kernel memory: %dk freed\n",
(&__init_end - &__init_begin) >> 10);
}
void si_meminfo(struct sysinfo *val)
{
val->totalram = totalram_pages;
- val->sharedram = atomic_read(&shmem_nrpages);
+ val->sharedram = 0;
val->freeram = nr_free_pages();
val->bufferram = atomic_read(&buffermem_pages);
- val->totalhigh = 0;
+ val->totalhigh = totalhigh_pages;
val->freehigh = nr_free_highpages();
val->mem_unit = PAGE_SIZE;
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)