Commit edcc875f authored by Dan Aloni's avatar Dan Aloni Committed by Linus Torvalds

i385 mm cleanup:

  + cleanup init.c and split into pgtable.c
  + split declaration of _text, _etext outside into sections.h
parent b0ab8396
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
O_TARGET := mm.o O_TARGET := mm.o
obj-y := init.o fault.o ioremap.o extable.o pageattr.o obj-y := init.o pgtable.o fault.o ioremap.o extable.o pageattr.o
export-objs := pageattr.o export-objs := pageattr.o
include $(TOPDIR)/Rules.make include $(TOPDIR)/Rules.make
This diff is collapsed.
/*
* linux/arch/i386/mm/pgtable.c
*/
#include <linux/config.h>
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/mm.h>
#include <linux/swap.h>
#include <linux/smp.h>
#include <linux/highmem.h>
#include <linux/slab.h>
#include <asm/system.h>
#include <asm/pgtable.h>
#include <asm/pgalloc.h>
#include <asm/fixmap.h>
#include <asm/e820.h>
#include <asm/tlb.h>
#include <asm/tlbflush.h>
void show_mem(void)
{
int i, total = 0, reserved = 0;
int shared = 0, cached = 0;
int highmem = 0;
printk("Mem-info:\n");
show_free_areas();
printk("Free swap: %6dkB\n",nr_swap_pages<<(PAGE_SHIFT-10));
i = max_mapnr;
while (i-- > 0) {
total++;
if (PageHighMem(mem_map+i))
highmem++;
if (PageReserved(mem_map+i))
reserved++;
else if (PageSwapCache(mem_map+i))
cached++;
else if (page_count(mem_map+i))
shared += page_count(mem_map+i) - 1;
}
printk("%d pages of RAM\n", total);
printk("%d pages of HIGHMEM\n",highmem);
printk("%d reserved pages\n",reserved);
printk("%d pages shared\n",shared);
printk("%d pages swap cached\n",cached);
}
/*
* Associate a virtual page frame with a given physical page frame
* and protection flags for that frame.
*/
static void set_pte_phys (unsigned long vaddr, unsigned long phys, pgprot_t flags)
{
pgd_t *pgd;
pmd_t *pmd;
pte_t *pte;
pgd = swapper_pg_dir + __pgd_offset(vaddr);
if (pgd_none(*pgd)) {
BUG();
return;
}
pmd = pmd_offset(pgd, vaddr);
if (pmd_none(*pmd)) {
BUG();
return;
}
pte = pte_offset_kernel(pmd, vaddr);
/* <phys,flags> stored as-is, to permit clearing entries */
set_pte(pte, pfn_pte(phys >> PAGE_SHIFT, flags));
/*
* It's enough to flush this one mapping.
* (PGE mappings get flushed as well)
*/
__flush_tlb_one(vaddr);
}
void __set_fixmap (enum fixed_addresses idx, unsigned long phys, pgprot_t flags)
{
unsigned long address = __fix_to_virt(idx);
if (idx >= __end_of_fixed_addresses) {
BUG();
return;
}
set_pte_phys(address, phys, flags);
}
pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address)
{
int count = 0;
pte_t *pte;
do {
pte = (pte_t *) __get_free_page(GFP_KERNEL);
if (pte)
clear_page(pte);
else {
current->state = TASK_UNINTERRUPTIBLE;
schedule_timeout(HZ);
}
} while (!pte && (count++ < 10));
return pte;
}
struct page *pte_alloc_one(struct mm_struct *mm, unsigned long address)
{
int count = 0;
struct page *pte;
do {
#if CONFIG_HIGHPTE
pte = alloc_pages(GFP_KERNEL | __GFP_HIGHMEM, 0);
#else
pte = alloc_pages(GFP_KERNEL, 0);
#endif
if (pte)
clear_highpage(pte);
else {
current->state = TASK_UNINTERRUPTIBLE;
schedule_timeout(HZ);
}
} while (!pte && (count++ < 10));
return pte;
}
#if CONFIG_X86_PAE
pgd_t *pgd_alloc(struct mm_struct *mm)
{
int i;
pgd_t *pgd = kmem_cache_alloc(pae_pgd_cachep, GFP_KERNEL);
if (pgd) {
for (i = 0; i < USER_PTRS_PER_PGD; i++) {
unsigned long pmd = __get_free_page(GFP_KERNEL);
if (!pmd)
goto out_oom;
clear_page(pmd);
set_pgd(pgd + i, __pgd(1 + __pa(pmd)));
}
memcpy(pgd + USER_PTRS_PER_PGD,
swapper_pg_dir + USER_PTRS_PER_PGD,
(PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t));
}
return pgd;
out_oom:
for (i--; i >= 0; i--)
free_page((unsigned long)__va(pgd_val(pgd[i])-1));
kmem_cache_free(pae_pgd_cachep, pgd);
return NULL;
}
void pgd_free(pgd_t *pgd)
{
int i;
for (i = 0; i < USER_PTRS_PER_PGD; i++)
free_page((unsigned long)__va(pgd_val(pgd[i])-1));
kmem_cache_free(pae_pgd_cachep, pgd);
}
#else
pgd_t *pgd_alloc(struct mm_struct *mm)
{
pgd_t *pgd = (pgd_t *)__get_free_page(GFP_KERNEL);
if (pgd) {
memset(pgd, 0, USER_PTRS_PER_PGD * sizeof(pgd_t));
memcpy(pgd + USER_PTRS_PER_PGD,
swapper_pg_dir + USER_PTRS_PER_PGD,
(PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t));
}
return pgd;
}
void pgd_free(pgd_t *pgd)
{
free_page((unsigned long)pgd);
}
#endif /* CONFIG_X86_PAE */
#ifndef _ASM_GENERIC_SECTIONS_H_
#define _ASM_GENERIC_SECTIONS_H_
/* References to section boundaries */
extern char _text, _etext;
extern char _data, _edata;
extern char __bss_start;
extern char __init_begin, __init_end;
#endif /* _ASM_GENERIC_SECTIONS_H_ */
...@@ -106,4 +106,6 @@ static inline pmd_t pfn_pmd(unsigned long page_nr, pgprot_t pgprot) ...@@ -106,4 +106,6 @@ static inline pmd_t pfn_pmd(unsigned long page_nr, pgprot_t pgprot)
return __pmd(((unsigned long long)page_nr << PAGE_SHIFT) | pgprot_val(pgprot)); return __pmd(((unsigned long long)page_nr << PAGE_SHIFT) | pgprot_val(pgprot));
} }
extern struct kmem_cache_s *pae_pgd_cachep;
#endif /* _I386_PGTABLE_3LEVEL_H */ #endif /* _I386_PGTABLE_3LEVEL_H */
#ifndef _I386_SECTIONS_H
#define _I386_SECTIONS_H
/* nothing to see, move along */
#include <asm-generic/sections.h>
#endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment