summaryrefslogtreecommitdiffstats
path: root/arch/arm/mm
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mm')
-rw-r--r--arch/arm/mm/init.c85
-rw-r--r--arch/arm/mm/ioremap.c4
-rw-r--r--arch/arm/mm/map.h1
-rw-r--r--arch/arm/mm/mm-armo.c16
-rw-r--r--arch/arm/mm/mm-armv.c96
-rw-r--r--arch/arm/mm/proc-arm2,3.S6
-rw-r--r--arch/arm/mm/proc-arm6,7.S8
-rw-r--r--arch/arm/mm/proc-sa110.S4
-rw-r--r--arch/arm/mm/small_page.c6
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)
{