X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=arch%2Fsh%2Fmm%2Finit.c;h=e342565f75fbc464684faf8e54f28e05134475ea;hb=987b0145d94eecf292d8b301228356f44611ab7c;hp=95b5368c06700615a85bfc93b252ef936a28b5f9;hpb=daddc0d38b3571bed170afa273a49a0eba090c1e;p=linux-2.6.git diff --git a/arch/sh/mm/init.c b/arch/sh/mm/init.c index 95b5368c0..e342565f7 100644 --- a/arch/sh/mm/init.c +++ b/arch/sh/mm/init.c @@ -3,7 +3,7 @@ * linux/arch/sh/mm/init.c * * Copyright (C) 1999 Niibe Yutaka - * Copyright (C) 2002 Paul Mundt + * Copyright (C) 2002, 2004 Paul Mundt * * Based on linux/arch/i386/mm/init.c: * Copyright (C) 1995 Linus Torvalds @@ -51,11 +51,6 @@ unsigned long mmu_context_cache = NO_CONTEXT; #define MAX_LOW_PFN (NODE_DATA(0)->bdata->node_low_pfn) #endif -#ifdef CONFIG_DISCONTIGMEM -pg_data_t discontig_page_data[MAX_NUMNODES]; -bootmem_data_t discontig_node_bdata[MAX_NUMNODES]; -#endif - void (*copy_page)(void *from, void *to); void (*clear_page)(void *to); @@ -66,7 +61,7 @@ void show_mem(void) printk("Mem-info:\n"); show_free_areas(); - printk("Free swap: %6dkB\n",nr_swap_pages<<(PAGE_SHIFT-10)); + printk("Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10)); i = max_mapnr; while (i-- > 0) { total++; @@ -83,6 +78,66 @@ void show_mem(void) printk("%d pages swap cached\n",cached); } +static void set_pte_phys(unsigned long addr, unsigned long phys, pgprot_t prot) +{ + pgd_t *pgd; + pmd_t *pmd; + pte_t *pte; + + pgd = swapper_pg_dir + pgd_index(addr); + if (pgd_none(*pgd)) { + pgd_ERROR(*pgd); + return; + } + + pmd = pmd_offset(pgd, addr); + if (pmd_none(*pmd)) { + pte = (pte_t *)get_zeroed_page(GFP_ATOMIC); + set_pmd(pmd, __pmd(__pa(pte) | _KERNPG_TABLE | _PAGE_USER)); + if (pte != pte_offset_kernel(pmd, 0)) { + pmd_ERROR(*pmd); + return; + } + } + + pte = pte_offset_kernel(pmd, addr); + if (!pte_none(*pte)) { + pte_ERROR(*pte); + return; + } + + set_pte(pte, pfn_pte(phys >> PAGE_SHIFT, prot)); + + __flush_tlb_page(get_asid(), addr); +} + +/* + * As a performance optimization, other platforms preserve the fixmap mapping + * across a context switch, we don't presently do this, but this could be done + * in a similar fashion as to the wired TLB interface that sh64 uses (by way + * of the memorry mapped UTLB configuration) -- this unfortunately forces us to + * give up a TLB entry for each mapping we want to preserve. While this may be + * viable for a small number of fixmaps, it's not particularly useful for + * everything and needs to be carefully evaluated. (ie, we may want this for + * the vsyscall page). + * + * XXX: Perhaps add a _PAGE_WIRED flag or something similar that we can pass + * in at __set_fixmap() time to determine the appropriate behavior to follow. + * + * -- PFM. + */ +void __set_fixmap(enum fixed_addresses idx, unsigned long phys, pgprot_t prot) +{ + unsigned long address = __fix_to_virt(idx); + + if (idx >= __end_of_fixed_addresses) { + BUG(); + return; + } + + set_pte_phys(address, phys, prot); +} + /* References to section boundaries */ extern char _text, _etext, _edata, __bss_start, _end; @@ -154,19 +209,8 @@ void __init paging_init(void) */ disable_mmu(); #endif - - free_area_init_node(0, NODE_DATA(0), 0, zones_size, __MEMORY_START >> PAGE_SHIFT, 0); - /* XXX: MRB-remove - this doesn't seem sane, should this be done somewhere else ?*/ - mem_map = NODE_DATA(0)->node_mem_map; - -#ifdef CONFIG_DISCONTIGMEM - /* - * And for discontig, do some more fixups on the zone sizes.. - */ - zones_size[ZONE_DMA] = __MEMORY_SIZE_2ND >> PAGE_SHIFT; - zones_size[ZONE_NORMAL] = 0; - free_area_init_node(1, NODE_DATA(1), 0, zones_size, __MEMORY_START_2ND >> PAGE_SHIFT, 0); -#endif + NODE_DATA(0)->node_mem_map = NULL; + free_area_init_node(0, NODE_DATA(0), zones_size, __MEMORY_START >> PAGE_SHIFT, 0); } void __init mem_init(void) @@ -190,7 +234,7 @@ void __init mem_init(void) memset(empty_zero_page, 0, PAGE_SIZE); __flush_wback_region(empty_zero_page, PAGE_SIZE); - /* + /* * Setup wrappers for copy/clear_page(), these will get overridden * later in the boot process if a better method is available. */ @@ -199,9 +243,6 @@ void __init mem_init(void) /* this will put all low memory onto the freelists */ totalram_pages += free_all_bootmem_node(NODE_DATA(0)); -#ifdef CONFIG_DISCONTIGMEM - totalram_pages += free_all_bootmem_node(NODE_DATA(1)); -#endif reservedpages = 0; for (tmp = 0; tmp < num_physpages; tmp++) /* @@ -228,7 +269,7 @@ void __init mem_init(void) void free_initmem(void) { unsigned long addr; - + addr = (unsigned long)(&__init_begin); for (; addr < (unsigned long)(&__init_end); addr += PAGE_SIZE) { ClearPageReserved(virt_to_page(addr));