diff options
Diffstat (limited to 'arch/arm/mm')
-rw-r--r-- | arch/arm/mm/init.c | 85 | ||||
-rw-r--r-- | arch/arm/mm/ioremap.c | 4 | ||||
-rw-r--r-- | arch/arm/mm/map.h | 1 | ||||
-rw-r--r-- | arch/arm/mm/mm-armo.c | 16 | ||||
-rw-r--r-- | arch/arm/mm/mm-armv.c | 96 | ||||
-rw-r--r-- | arch/arm/mm/proc-arm2,3.S | 6 | ||||
-rw-r--r-- | arch/arm/mm/proc-arm6,7.S | 8 | ||||
-rw-r--r-- | arch/arm/mm/proc-sa110.S | 4 | ||||
-rw-r--r-- | arch/arm/mm/small_page.c | 6 |
9 files changed, 138 insertions, 88 deletions
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c index 229b4dcd7..17972e427 100644 --- a/arch/arm/mm/init.c +++ b/arch/arm/mm/init.c @@ -25,7 +25,7 @@ #include <asm/system.h> #include <asm/segment.h> -#include <asm/pgtable.h> +#include <asm/pgalloc.h> #include <asm/dma.h> #include <asm/hardware.h> #include <asm/setup.h> @@ -168,6 +168,7 @@ void show_mem(void) void __init paging_init(void) { void *zero_page, *bad_page, *bad_table; + unsigned int zone_size[3]; #ifdef CONFIG_CPU_32 #define TABLE_OFFSET (PTRS_PER_PTE) @@ -189,7 +190,11 @@ void __init paging_init(void) pagetable_init(); flush_tlb_all(); - free_area_init(max_low_pfn); + /* + * Initialise the zones and mem_map + */ + zonesize_init(zone_size); + free_area_init(zone_size); /* * finish off the bad pages once @@ -235,22 +240,23 @@ static inline void free_unused_mem_map(void) */ void __init mem_init(void) { - int codepages = 0; - int reservedpages = 0; - int datapages = 0; - int initpages = 0, i, min_nr; + extern char __init_begin, __init_end, _text, _etext, _end; + unsigned int codepages, datapages, initpages; + int i; - max_mapnr = max_low_pfn; - high_memory = (void *)__va(max_low_pfn * PAGE_SIZE); + codepages = &_etext - &_text; + datapages = &_end - &_etext; + initpages = &__init_end - &__init_begin; + + max_mapnr = max_low_pfn; + high_memory = (void *)__va(PHYS_OFFSET + max_low_pfn * PAGE_SIZE); -#ifdef CONFIG_CPU_32 /* * We may have non-contiguous memory. Setup the PageSkip stuff, * and mark the areas of mem_map which can be freed */ if (meminfo.nr_banks != 1) create_memmap_holes(); -#endif /* this will put all unused low memory onto the freelists */ totalram_pages += free_all_bootmem(); @@ -259,42 +265,28 @@ void __init mem_init(void) * Since our memory may not be contiguous, calculate the * real number of pages we have in this system */ + printk("Memory:"); + num_physpages = 0; - for (i = 0; i < meminfo.nr_banks; i++) + for (i = 0; i < meminfo.nr_banks; i++) { num_physpages += meminfo.bank[i].size >> PAGE_SHIFT; + printk(" %ldMB", meminfo.bank[i].size >> 20); + } - printk ("Memory: %luk/%luM available (%dk code, %dk reserved, %dk data, %dk init)\n", - (unsigned long) nr_free_pages << (PAGE_SHIFT-10), - num_physpages >> (20 - PAGE_SHIFT), - codepages << (PAGE_SHIFT-10), - reservedpages << (PAGE_SHIFT-10), - datapages << (PAGE_SHIFT-10), - initpages << (PAGE_SHIFT-10)); + printk(" = %luMB total\n", num_physpages >> (20 - PAGE_SHIFT)); + printk("Memory: %luKB available (%dK code, %dK data, %dK init)\n", + (unsigned long) nr_free_pages() << (PAGE_SHIFT-10), + codepages >> 10, datapages >> 10, initpages >> 10); - /* - * Correct freepages watermarks - */ - i = nr_free_pages >> 7; - if (PAGE_SIZE < 32768) - min_nr = 10; - else - min_nr = 2; - if (i < min_nr) - i = min_nr; - if (i > 256) - i = 256; - freepages.min = i; - freepages.low = i * 2; - freepages.high = i * 3; - -#ifdef CONFIG_CPU_26 - if (max_mapnr <= 128) { + if (PAGE_SIZE >= 16384 && num_physpages <= 128) { extern int sysctl_overcommit_memory; - /* On a machine this small we won't get anywhere without - overcommit, so turn it on by default. */ + /* + * On a machine this small we won't get + * anywhere without overcommit, so turn + * it on by default. + */ sysctl_overcommit_memory = 1; } -#endif } static inline void free_area(unsigned long addr, unsigned long end, char *s) @@ -344,11 +336,24 @@ void free_initmem(void) printk("\n"); } +#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 + void si_meminfo(struct sysinfo *val) { val->totalram = totalram_pages; val->sharedram = 0; - val->freeram = nr_free_pages; + val->freeram = nr_free_pages(); val->bufferram = atomic_read(&buffermem_pages); val->totalhigh = 0; val->freehigh = 0; diff --git a/arch/arm/mm/ioremap.c b/arch/arm/mm/ioremap.c index 141644ae2..fb3007f8a 100644 --- a/arch/arm/mm/ioremap.c +++ b/arch/arm/mm/ioremap.c @@ -32,7 +32,7 @@ #include <linux/vmalloc.h> #include <asm/page.h> -#include <asm/pgtable.h> +#include <asm/pgalloc.h> #include <asm/io.h> static inline void remap_area_pte(pte_t * pte, unsigned long address, unsigned long size, @@ -136,7 +136,7 @@ void * __ioremap(unsigned long phys_addr, unsigned long size, unsigned long flag /* * Ok, go for it.. */ - area = get_vm_area(size); + area = get_vm_area(size, VM_IOREMAP); if (!area) return NULL; addr = area->addr; diff --git a/arch/arm/mm/map.h b/arch/arm/mm/map.h index 0a3ee8b4d..b596c6479 100644 --- a/arch/arm/mm/map.h +++ b/arch/arm/mm/map.h @@ -19,6 +19,7 @@ struct map_desc { extern struct map_desc io_desc[]; extern unsigned int io_desc_size; +extern void zonesize_init(unsigned int *); extern void create_memmap_holes(void); extern void pagetable_init(void); diff --git a/arch/arm/mm/mm-armo.c b/arch/arm/mm/mm-armo.c index 5ee95ea45..680a52948 100644 --- a/arch/arm/mm/mm-armo.c +++ b/arch/arm/mm/mm-armo.c @@ -11,6 +11,7 @@ #include <linux/bootmem.h> #include <asm/pgtable.h> +#include <asm/pgalloc.h> #include <asm/page.h> #include <asm/arch/memory.h> @@ -134,6 +135,20 @@ pte_t *get_pte_slow(pmd_t *pmd, unsigned long offset) } /* + * Calculate the size of the DMA, normal and highmem zones. + * On 26-bit ARMs, we don't have any real DMA or highmem, + * so we allocate the whole memory as being DMA-capable. + */ +void __init zonesize_init(unsigned int *zone_size) +{ + int i; + + zone_size[0] = max_low_pfn; + zone_size[1] = 0; + zone_size[2] = 0; +} + +/* * This contains the code to setup the memory map on an ARM2/ARM250/ARM3 * machine. This is both processor & architecture specific, and requires * some more work to get it to fit into our separate processor and @@ -147,7 +162,6 @@ void __init pagetable_init(void) page_nr = max_low_pfn; pte = alloc_bootmem_low_pages(PTRS_PER_PTE * sizeof(pte_t)); - memzero(pte, PTRS_PER_PTE * sizeof(pte_t)); pte[0] = mk_pte_phys(PAGE_OFFSET + 491520, PAGE_READONLY); set_pmd(pmd_offset(swapper_pg_dir, 0), mk_kernel_pmd(pte)); diff --git a/arch/arm/mm/mm-armv.c b/arch/arm/mm/mm-armv.c index 3df6c13b5..ee4750c62 100644 --- a/arch/arm/mm/mm-armv.c +++ b/arch/arm/mm/mm-armv.c @@ -11,6 +11,7 @@ #include <linux/bootmem.h> #include <asm/pgtable.h> +#include <asm/pgalloc.h> #include <asm/page.h> #include <asm/io.h> #include <asm/setup.h> @@ -24,6 +25,31 @@ extern void free_page_2k(unsigned long page); extern pte_t *get_bad_pte_table(void); /* + * These are useful for identifing cache coherency + * problems by allowing the cache or the cache and + * writebuffer to be turned off. (Note: the write + * buffer should not be on and the cache off). + */ +static int __init nocache_setup(char *__unused) +{ + cr_alignment &= ~4; + cr_no_alignment &= ~4; + set_cr(cr_alignment); + return 1; +} + +static int __init nowrite_setup(char *__unused) +{ + cr_alignment &= ~(8|4); + cr_no_alignment &= ~(8|4); + set_cr(cr_alignment); + return 1; +} + +__setup("nocache", nocache_setup); +__setup("nowb", nowrite_setup); + +/* * need to get a 16k page for level 1 */ pgd_t *get_pgd_slow(void) @@ -178,7 +204,6 @@ alloc_init_page(unsigned long virt, unsigned long phys, int domain, int prot) pte_t *ptep = alloc_bootmem_low_pages(2 * PTRS_PER_PTE * sizeof(pte_t)); - memzero(ptep, 2 * PTRS_PER_PTE * sizeof(pte_t)); ptep += PTRS_PER_PTE; set_pmd(pmdp, __mk_pmd(ptep, PMD_TYPE_TABLE | PMD_DOMAIN(domain))); @@ -266,6 +291,32 @@ static struct map_desc init_map[] __initdata = { #define NR_INIT_MAPS (sizeof(init_map) / sizeof(init_map[0])) +/* + * Calculate the size of the DMA, normal and highmem zones. + * On ARM, we don't have any problems with DMA, so all memory + * is allocated to the DMA zone. We also don't have any + * highmem either. + */ +void __init zonesize_init(unsigned int *zone_size) +{ + int i; + + zone_size[0] = 0; + zone_size[1] = 0; + zone_size[2] = 0; + + for (i = 0; i < meminfo.nr_banks; i++) { + if (meminfo.bank[i].size) { + unsigned int end; + + end = (meminfo.bank[i].start - PHYS_OFFSET + + meminfo.bank[i].size) >> PAGE_SHIFT; + if (end > zone_size[0]) + zone_size[0] = end; + } + } +} + void __init pagetable_init(void) { unsigned long address = 0; @@ -274,7 +325,7 @@ void __init pagetable_init(void) /* * Setup the above mappings */ - init_map[0].physical = PHYS_OFFSET; + init_map[0].physical = virt_to_phys(alloc_bootmem_low_pages(PAGE_SIZE)); init_map[5].physical = FLUSH_BASE_PHYS; init_map[5].virtual = FLUSH_BASE; #ifdef FLUSH_BASE_MINICACHE @@ -284,8 +335,9 @@ void __init pagetable_init(void) #endif for (i = 0; i < meminfo.nr_banks; i++) { - init_map[i+1].physical = PHYS_OFFSET + meminfo.bank[i].start; - init_map[i+1].virtual = PAGE_OFFSET + meminfo.bank[i].start; + init_map[i+1].physical = meminfo.bank[i].start; + init_map[i+1].virtual = meminfo.bank[i].start + + PAGE_OFFSET - PHYS_OFFSET; init_map[i+1].length = meminfo.bank[i].size; } @@ -327,13 +379,15 @@ void __init create_memmap_holes(void) { unsigned int start_pfn, end_pfn = -1; struct page *pg = NULL; - unsigned int sz, i; + unsigned int i; + +#define PFN(x) (((x) - PHYS_OFFSET) >> PAGE_SHIFT) for (i = 0; i < meminfo.nr_banks; i++) { if (meminfo.bank[i].size == 0) continue; - start_pfn = meminfo.bank[i].start >> PAGE_SHIFT; + start_pfn = PFN(meminfo.bank[i].start); /* * subtle here - if we have a full bank, then @@ -344,8 +398,8 @@ void __init create_memmap_holes(void) set_bit(PG_skip, &pg->flags); pg->next_hash = mem_map + start_pfn; - start_pfn = PAGE_ALIGN(__pa(pg + 1)); - end_pfn = __pa(pg->next_hash) & PAGE_MASK; + start_pfn = PFN(PAGE_ALIGN(__pa(pg + 1))); + end_pfn = PFN(__pa(pg->next_hash) & PAGE_MASK); if (end_pfn != start_pfn) free_bootmem(start_pfn, end_pfn - start_pfn); @@ -353,8 +407,7 @@ void __init create_memmap_holes(void) pg = NULL; } - end_pfn = (meminfo.bank[i].start + - meminfo.bank[i].size) >> PAGE_SHIFT; + end_pfn = PFN(meminfo.bank[i].start + meminfo.bank[i].size); if (end_pfn != meminfo.end >> PAGE_SHIFT) pg = mem_map + end_pfn; @@ -364,27 +417,4 @@ void __init create_memmap_holes(void) set_bit(PG_skip, &pg->flags); pg->next_hash = NULL; } - -#if 0 - /* - * setup address validity map - * - don't think this is used anymore? - */ - sz = meminfo.end >> (PAGE_SHIFT + 8); /* in MB */ - sz = (sz + 31) >> 3; - - valid_addr_bitmap = alloc_bootmem(sz); - memzero(valid_addr_bitmap, sz); - - for (i = 0; i < meminfo.nr_banks; i++) { - int idx, end; - - idx = meminfo.bank[i].start >> 20; - end = (meminfo.bank[i].start + - meminfo.bank[i].size) >> 20; - do - set_bit(idx, valid_addr_bitmap); - while (++idx < end); - } -#endif } diff --git a/arch/arm/mm/proc-arm2,3.S b/arch/arm/mm/proc-arm2,3.S index dcb5c10dc..36a9d8b28 100644 --- a/arch/arm/mm/proc-arm2,3.S +++ b/arch/arm/mm/proc-arm2,3.S @@ -270,9 +270,9 @@ _arm2_3_check_bugs: bics pc, lr, #0x04000000 @ Clear FIQ disable bit armvlsi_name: .asciz "ARM/VLSI" -_arm2_name: .asciz "arm2" -_arm250_name: .asciz "arm250" -_arm3_name: .asciz "arm3" +_arm2_name: .asciz "ARM 2" +_arm250_name: .asciz "ARM 250" +_arm3_name: .asciz "ARM 3" .section ".text.init", #alloc, #execinstr /* diff --git a/arch/arm/mm/proc-arm6,7.S b/arch/arm/mm/proc-arm6,7.S index b085c3c4e..d453269d2 100644 --- a/arch/arm/mm/proc-arm6,7.S +++ b/arch/arm/mm/proc-arm6,7.S @@ -413,12 +413,12 @@ ENTRY(cpu_arm7_reset) cpu_armvlsi_name: .asciz "ARM/VLSI" -cpu_arm6_name: .asciz "arm6" +cpu_arm6_name: .asciz "ARM 6" cpu_arm610_name: - .asciz "arm610" -cpu_arm7_name: .asciz "arm7" + .asciz "ARM 610" +cpu_arm7_name: .asciz "ARM 7" cpu_arm710_name: - .asciz "arm710" + .asciz "ARM 710" .align .section ".text.init", #alloc, #execinstr diff --git a/arch/arm/mm/proc-sa110.S b/arch/arm/mm/proc-sa110.S index 266d960b5..2d57b1030 100644 --- a/arch/arm/mm/proc-sa110.S +++ b/arch/arm/mm/proc-sa110.S @@ -456,9 +456,9 @@ ENTRY(cpu_sa1100_reset) cpu_manu_name: .asciz "Intel" ENTRY(cpu_sa110_name) - .asciz "sa110" + .asciz "StrongARM-110" ENTRY(cpu_sa1100_name) - .asciz "sa1100" + .asciz "StrongARM-1100" .align .section ".text.init", #alloc, #execinstr diff --git a/arch/arm/mm/small_page.c b/arch/arm/mm/small_page.c index ac303d45e..ee7f571a7 100644 --- a/arch/arm/mm/small_page.c +++ b/arch/arm/mm/small_page.c @@ -66,9 +66,9 @@ static struct order orders[] = { #endif }; -#define USED_MAP(pg) ((pg)->offset) -#define TEST_AND_CLEAR_USED(pg,off) (test_and_clear_bit(off, &(pg)->offset)) -#define SET_USED(pg,off) (set_bit(off, &(pg)->offset)) +#define USED_MAP(pg) ((pg)->index) +#define TEST_AND_CLEAR_USED(pg,off) (test_and_clear_bit(off, &USED_MAP(pg))) +#define SET_USED(pg,off) (set_bit(off, &USED_MAP(pg))) static void add_page_to_queue(struct page *page, struct page **p) { |