patch-2.3.40 linux/arch/arm/mm/mm-armv.c

Next file: linux/arch/arm/mm/mm-sa1100.c
Previous file: linux/arch/arm/mm/mm-armo.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.3.39/linux/arch/arm/mm/mm-armv.c linux/arch/arm/mm/mm-armv.c
@@ -46,6 +46,15 @@
 	return 1;
 }
 
+static int __init noalign_setup(char *__unused)
+{
+	cr_alignment &= ~2;
+	cr_no_alignment &= ~2;
+	set_cr(cr_alignment);
+	return 1;
+}
+
+__setup("noalign", noalign_setup);
 __setup("nocache", nocache_setup);
 __setup("nowb", nowrite_setup);
 
@@ -218,7 +227,7 @@
  * the clearance is done by the middle-level functions (pmd)
  * rather than the top-level (pgd) functions.
  */
-static inline void free_init_section(unsigned long virt)
+static inline void clear_mapping(unsigned long virt)
 {
 	pmd_clear(pmd_offset(pgd_offset_k(virt), virt));
 }
@@ -273,73 +282,76 @@
 	}
 }
 
-/*
- * Initial boot-time mapping.  This covers just the zero page, kernel and
- * the flush area.  NB: it must be sorted by virtual address, and no
- * virtual address overlaps.
- *  init_map[2..4] are for architectures with banked memory.
- */
-static struct map_desc init_map[] __initdata = {
-	{ 0, 0, PAGE_SIZE,  DOMAIN_USER,   0, 0, 1, 0 }, /* zero page     */
-	{ 0, 0, 0,          DOMAIN_KERNEL, 0, 1, 1, 1 }, /* kernel memory */
-	{ 0, 0, 0,          DOMAIN_KERNEL, 0, 1, 1, 1 }, /* (4 banks)	  */
-	{ 0, 0, 0,          DOMAIN_KERNEL, 0, 1, 1, 1 },
-	{ 0, 0, 0,          DOMAIN_KERNEL, 0, 1, 1, 1 },
-	{ 0, 0, PGDIR_SIZE, DOMAIN_KERNEL, 1, 0, 1, 1 }, /* cache flush 1 */
-	{ 0, 0, 0,          DOMAIN_KERNEL, 1, 0, 1, 0 }  /* cache flush 2 */
-};
-
-#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)
+void __init pagetable_init(void)
 {
+	struct map_desc *init_maps, *p;
+	unsigned long address = 0;
 	int i;
 
-	zone_size[0] = 0;
-	zone_size[1] = 0;
-	zone_size[2] = 0;
+	/*
+	 * Setup initial mappings.  We use the page we allocated
+	 * for zero page to hold the mappings, which will get
+	 * overwritten by the vectors in traps_init().  The
+	 * mappings must be in virtual address order.
+	 */
+	init_maps = p = alloc_bootmem_low_pages(PAGE_SIZE);
+
+	p->physical   = virt_to_phys(init_maps);
+	p->virtual    = 0;
+	p->length     = PAGE_SIZE;
+	p->domain     = DOMAIN_USER;
+	p->prot_read  = 0;
+	p->prot_write = 0;
+	p->cacheable  = 1;
+	p->bufferable = 0;
+
+	p ++;
 
 	for (i = 0; i < meminfo.nr_banks; i++) {
-		if (meminfo.bank[i].size) {
-			unsigned int end;
+		if (meminfo.bank[i].size == 0)
+			continue;
 
-			end = (meminfo.bank[i].start - PHYS_OFFSET +
-				meminfo.bank[i].size) >> PAGE_SHIFT;
-			if (end > zone_size[0])
-				zone_size[0] = end;
-		}
-	}
-}
+		p->physical   = meminfo.bank[i].start;
+		p->virtual    = __phys_to_virt(p->physical);
+		p->length     = meminfo.bank[i].size;
+		p->domain     = DOMAIN_KERNEL;
+		p->prot_read  = 0;
+		p->prot_write = 1;
+		p->cacheable  = 1;
+		p->bufferable = 1;
+
+		p ++;
+	}
+
+	p->physical   = FLUSH_BASE_PHYS;
+	p->virtual    = FLUSH_BASE;
+	p->length     = PGDIR_SIZE;
+	p->domain     = DOMAIN_KERNEL;
+	p->prot_read  = 1;
+	p->prot_write = 0;
+	p->cacheable  = 1;
+	p->bufferable = 1;
 
-void __init pagetable_init(void)
-{
-	unsigned long address = 0;
-	int i;
+	p ++;
 
-	/*
-	 * Setup the above mappings
-	 */
-	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
-	init_map[6].physical = FLUSH_BASE_PHYS + PGDIR_SIZE;
-	init_map[6].virtual  = FLUSH_BASE_MINICACHE;
-	init_map[6].length   = PGDIR_SIZE;
+	p->physical   = FLUSH_BASE_PHYS + PGDIR_SIZE;
+	p->virtual    = FLUSH_BASE_MINICACHE;
+	p->length     = PGDIR_SIZE;
+	p->domain     = DOMAIN_KERNEL;
+	p->prot_read  = 1;
+	p->prot_write = 0;
+	p->cacheable  = 1;
+	p->bufferable = 0;
+
+	p ++;
 #endif
 
-	for (i = 0; i < meminfo.nr_banks; i++) {
-		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;
-	}
+	/*
+	 * We may have a mapping in virtual address 0.
+	 * Clear it out.
+	 */
+	clear_mapping(0);
 
 	/*
 	 * Go through the initial mappings, but clear out any
@@ -347,18 +359,16 @@
 	 */
 	i = 0;
 	do {
-		if (address < init_map[i].virtual || i == NR_INIT_MAPS) {
-			free_init_section(address);
+		if (address < init_maps->virtual || init_maps == p) {
+			clear_mapping(address);
 			address += PGDIR_SIZE;
 		} else {
-			create_mapping(init_map + i);
+			create_mapping(init_maps);
 
-			address = init_map[i].virtual + init_map[i].length;
+			address = init_maps->virtual + init_maps->length;
 			address = (address + PGDIR_SIZE - 1) & PGDIR_MASK;
 
-			do {
-				i += 1;
-			} while (init_map[i].length == 0 && i < NR_INIT_MAPS);
+			init_maps ++;
 		}
 	} while (address != 0);
 
@@ -382,6 +392,7 @@
 	unsigned int i;
 
 #define PFN(x)	(((x) - PHYS_OFFSET) >> PAGE_SHIFT)
+#define free_bootmem(s,sz)  free_bootmem(((s)<<PAGE_SHIFT)+PHYS_OFFSET, (sz)<<PAGE_SHIFT)
 
 	for (i = 0; i < meminfo.nr_banks; i++) {
 		if (meminfo.bank[i].size == 0)
@@ -409,7 +420,7 @@
 
 		end_pfn = PFN(meminfo.bank[i].start + meminfo.bank[i].size);
 
-		if (end_pfn != meminfo.end >> PAGE_SHIFT)
+		if (end_pfn != PFN(meminfo.end))
 			pg = mem_map + end_pfn;
 	}
 

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)