patch-2.4.6 linux/arch/arm/mm/mm-armv.c
Next file: linux/arch/arm/mm/mm-l7200.c
Previous file: linux/arch/arm/mm/fault-armv.c
Back to the patch index
Back to the overall index
- Lines: 163
- Date:
Wed Jun 27 14:12:04 2001
- Orig file:
v2.4.5/linux/arch/arm/mm/mm-armv.c
- Orig date:
Thu Apr 12 12:20:31 2001
diff -u --recursive --new-file v2.4.5/linux/arch/arm/mm/mm-armv.c linux/arch/arm/mm/mm-armv.c
@@ -79,37 +79,40 @@
memzero(new_pgd, FIRST_KERNEL_PGD_NR * sizeof(pgd_t));
- /*
- * This lock is here just to satisfy pmd_alloc and pte_lock
- */
- spin_lock(&mm->page_table_lock);
+ init_pgd = pgd_offset_k(0);
- /*
- * On ARM, first page must always be allocated since it contains
- * the machine vectors.
- */
- new_pmd = pmd_alloc(mm, new_pgd, 0);
- if (!new_pmd)
- goto no_pmd;
-
- new_pte = pte_alloc(mm, new_pmd, 0);
- if (!new_pte)
- goto no_pte;
+ if (vectors_base() == 0) {
+ init_pmd = pmd_offset(init_pgd, 0);
+ init_pte = pte_offset(init_pmd, 0);
+
+ /*
+ * This lock is here just to satisfy pmd_alloc and pte_lock
+ */
+ spin_lock(&mm->page_table_lock);
+
+ /*
+ * On ARM, first page must always be allocated since it
+ * contains the machine vectors.
+ */
+ new_pmd = pmd_alloc(mm, new_pgd, 0);
+ if (!new_pmd)
+ goto no_pmd;
+
+ new_pte = pte_alloc(mm, new_pmd, 0);
+ if (!new_pte)
+ goto no_pte;
- init_pgd = pgd_offset_k(0);
- init_pmd = pmd_offset(init_pgd, 0);
- init_pte = pte_offset(init_pmd, 0);
+ set_pte(new_pte, *init_pte);
- set_pte(new_pte, *init_pte);
+ spin_unlock(&mm->page_table_lock);
+ }
/*
* Copy over the kernel and IO PGD entries
*/
- memcpy(new_pgd + FIRST_KERNEL_PGD_NR, init_pgd + FIRST_KERNEL_PGD_NR,
+ memcpy(new_pgd + FIRST_KERNEL_PGD_NR, init_pgd + FIRST_KERNEL_PGD_NR,
(PTRS_PER_PGD - FIRST_KERNEL_PGD_NR) * sizeof(pgd_t));
- spin_unlock(&mm->page_table_lock);
-
/*
* FIXME: this should not be necessary
*/
@@ -134,25 +137,26 @@
void free_pgd_slow(pgd_t *pgd)
{
- if (pgd) { /* can pgd be NULL? */
- pmd_t *pmd;
- pte_t *pte;
-
- /* pgd is always present and good */
- pmd = (pmd_t *)pgd;
- if (pmd_none(*pmd))
- goto free;
- if (pmd_bad(*pmd)) {
- pmd_ERROR(*pmd);
- pmd_clear(pmd);
- goto free;
- }
+ pmd_t *pmd;
+ pte_t *pte;
- pte = pte_offset(pmd, 0);
+ if (!pgd)
+ return;
+
+ /* pgd is always present and good */
+ pmd = (pmd_t *)pgd;
+ if (pmd_none(*pmd))
+ goto free;
+ if (pmd_bad(*pmd)) {
+ pmd_ERROR(*pmd);
pmd_clear(pmd);
- pte_free(pte);
- pmd_free(pmd);
+ goto free;
}
+
+ pte = pte_offset(pmd, 0);
+ pmd_clear(pmd);
+ pte_free(pte);
+ pmd_free(pmd);
free:
free_pages((unsigned long) pgd, 2);
}
@@ -296,17 +300,6 @@
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 < mi->nr_banks; i++) {
if (mi->bank[i].size == 0)
continue;
@@ -350,16 +343,9 @@
#endif
/*
- * We may have a mapping in virtual address 0.
- * Clear it out.
- */
- clear_mapping(0);
-
- /*
* Go through the initial mappings, but clear out any
* pgdir entries that are not in the description.
*/
- i = 0;
q = init_maps;
do {
if (address < q->virtual || q == p) {
@@ -374,6 +360,21 @@
q ++;
}
} while (address != 0);
+
+ /*
+ * Create a mapping for the machine vectors at virtual address 0
+ * or 0xffff0000. We should always try the high mapping.
+ */
+ init_maps->physical = virt_to_phys(init_maps);
+ init_maps->virtual = vectors_base();
+ init_maps->length = PAGE_SIZE;
+ init_maps->domain = DOMAIN_USER;
+ init_maps->prot_read = 0;
+ init_maps->prot_write = 0;
+ init_maps->cacheable = 1;
+ init_maps->bufferable = 0;
+
+ create_mapping(init_maps);
flush_cache_all();
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)