aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mm/mm-armv.c
diff options
context:
space:
mode:
authorRussell King <rmk@dyn-67.arm.linux.org.uk>2005-10-28 09:48:37 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2005-10-28 09:48:37 -0400
commit90072059d2963dec237ae0cf49831ef77ddb5739 (patch)
tree5ec0cc3e9759599957ea98eb9f5c372ffabca00f /arch/arm/mm/mm-armv.c
parentf339ab3d6c59f8f898c165384aa2b6a0ae5d4c1c (diff)
[ARM] Re-jig bootmem initialisation
Make ARM independent of the way bootmem operates internally. We now map each node as we initialise it, and place the bootmem bitmap inside each node, rather than all in the first node. Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/mm/mm-armv.c')
-rw-r--r--arch/arm/mm/mm-armv.c110
1 files changed, 3 insertions, 107 deletions
diff --git a/arch/arm/mm/mm-armv.c b/arch/arm/mm/mm-armv.c
index d125a3dc061c..c626361c0f5e 100644
--- a/arch/arm/mm/mm-armv.c
+++ b/arch/arm/mm/mm-armv.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * linux/arch/arm/mm/mm-armv.c 2 * linux/arch/arm/mm/mm-armv.c
3 * 3 *
4 * Copyright (C) 1998-2002 Russell King 4 * Copyright (C) 1998-2005 Russell King
5 * 5 *
6 * This program is free software; you can redistribute it and/or modify 6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as 7 * it under the terms of the GNU General Public License version 2 as
@@ -305,16 +305,6 @@ alloc_init_page(unsigned long virt, unsigned long phys, unsigned int prot_l1, pg
305 set_pte(ptep, pfn_pte(phys >> PAGE_SHIFT, prot)); 305 set_pte(ptep, pfn_pte(phys >> PAGE_SHIFT, prot));
306} 306}
307 307
308/*
309 * Clear any PGD mapping. On a two-level page table system,
310 * the clearance is done by the middle-level functions (pmd)
311 * rather than the top-level (pgd) functions.
312 */
313static inline void clear_mapping(unsigned long virt)
314{
315 pmd_clear(pmd_off_k(virt));
316}
317
318struct mem_types { 308struct mem_types {
319 unsigned int prot_pte; 309 unsigned int prot_pte;
320 unsigned int prot_l1; 310 unsigned int prot_l1;
@@ -373,7 +363,7 @@ static struct mem_types mem_types[] __initdata = {
373/* 363/*
374 * Adjust the PMD section entries according to the CPU in use. 364 * Adjust the PMD section entries according to the CPU in use.
375 */ 365 */
376static void __init build_mem_type_table(void) 366void __init build_mem_type_table(void)
377{ 367{
378 struct cachepolicy *cp; 368 struct cachepolicy *cp;
379 unsigned int cr = get_cr(); 369 unsigned int cr = get_cr();
@@ -483,7 +473,7 @@ static void __init build_mem_type_table(void)
483 * offsets, and we take full advantage of sections and 473 * offsets, and we take full advantage of sections and
484 * supersections. 474 * supersections.
485 */ 475 */
486static void __init create_mapping(struct map_desc *md) 476void __init create_mapping(struct map_desc *md)
487{ 477{
488 unsigned long virt, length; 478 unsigned long virt, length;
489 int prot_sect, prot_l1, domain; 479 int prot_sect, prot_l1, domain;
@@ -601,100 +591,6 @@ void setup_mm_for_reboot(char mode)
601 } 591 }
602} 592}
603 593
604extern void _stext, _etext;
605
606/*
607 * Setup initial mappings. We use the page we allocated for zero page to hold
608 * the mappings, which will get overwritten by the vectors in traps_init().
609 * The mappings must be in virtual address order.
610 */
611void __init memtable_init(struct meminfo *mi)
612{
613 struct map_desc *init_maps, *p, *q;
614 unsigned long address = 0;
615 int i;
616
617 build_mem_type_table();
618
619 init_maps = p = alloc_bootmem_low_pages(PAGE_SIZE);
620
621#ifdef CONFIG_XIP_KERNEL
622 p->physical = CONFIG_XIP_PHYS_ADDR & PMD_MASK;
623 p->virtual = (unsigned long)&_stext & PMD_MASK;
624 p->length = ((unsigned long)&_etext - p->virtual + ~PMD_MASK) & PMD_MASK;
625 p->type = MT_ROM;
626 p ++;
627#endif
628
629 for (i = 0; i < mi->nr_banks; i++) {
630 if (mi->bank[i].size == 0)
631 continue;
632
633 p->physical = mi->bank[i].start;
634 p->virtual = __phys_to_virt(p->physical);
635 p->length = mi->bank[i].size;
636 p->type = MT_MEMORY;
637 p ++;
638 }
639
640#ifdef FLUSH_BASE
641 p->physical = FLUSH_BASE_PHYS;
642 p->virtual = FLUSH_BASE;
643 p->length = PGDIR_SIZE;
644 p->type = MT_CACHECLEAN;
645 p ++;
646#endif
647
648#ifdef FLUSH_BASE_MINICACHE
649 p->physical = FLUSH_BASE_PHYS + PGDIR_SIZE;
650 p->virtual = FLUSH_BASE_MINICACHE;
651 p->length = PGDIR_SIZE;
652 p->type = MT_MINICLEAN;
653 p ++;
654#endif
655
656 /*
657 * Go through the initial mappings, but clear out any
658 * pgdir entries that are not in the description.
659 */
660 q = init_maps;
661 do {
662 if (address < q->virtual || q == p) {
663 clear_mapping(address);
664 address += PGDIR_SIZE;
665 } else {
666 create_mapping(q);
667
668 address = q->virtual + q->length;
669 address = (address + PGDIR_SIZE - 1) & PGDIR_MASK;
670
671 q ++;
672 }
673 } while (address != 0);
674
675 /*
676 * Create a mapping for the machine vectors at the high-vectors
677 * location (0xffff0000). If we aren't using high-vectors, also
678 * create a mapping at the low-vectors virtual address.
679 */
680 init_maps->physical = virt_to_phys(init_maps);
681 init_maps->virtual = 0xffff0000;
682 init_maps->length = PAGE_SIZE;
683 init_maps->type = MT_HIGH_VECTORS;
684 create_mapping(init_maps);
685
686 if (!vectors_high()) {
687 init_maps->virtual = 0;
688 init_maps->type = MT_LOW_VECTORS;
689 create_mapping(init_maps);
690 }
691
692 flush_cache_all();
693 local_flush_tlb_all();
694
695 top_pmd = pmd_off_k(0xffff0000);
696}
697
698/* 594/*
699 * Create the architecture specific mappings 595 * Create the architecture specific mappings
700 */ 596 */