summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGabe Black <gabeblack@google.com>2013-05-18 22:45:54 -0700
committerStefan Reinauer <stefan.reinauer@coreboot.org>2013-07-10 21:06:34 +0200
commit800790d4e1e4817a140c706a32b5448cbd9d0c45 (patch)
tree44b639d8f3f91eb3f62f0ebb06728bcf5628974e
parent1e797bdb79b9b3d05640abfee93acf1359cda4db (diff)
ARM: Fix up page table/cachability management.
When modifying the page tables, use writel to ensure the writes happen, flush the page tables themselves to ensure they're visible to the MMU if it doesn't look at the caches, and invalidate the right TLB entries. The first two changes are probably safer but may not be strictly necessary. The third change is necessary because we were invalidating the TLB using i which was in megabytes but using an instruction that expects an address in bytes. One symptom of this problem was that the framebuffer, which was supposed to be marked uncacheable, was only being partially updated since some of the updates were still in the cache. With this change the graphics show up correctly. Change-Id: I5475df29690371459b0d37a304eebc62f81dd76b Signed-off-by: Gabe Black <gabeblack@chromium.org> Reviewed-on: http://review.coreboot.org/3653 Tested-by: build bot (Jenkins) Reviewed-by: Stefan Reinauer <stefan.reinauer@coreboot.org>
-rw-r--r--src/arch/armv7/lib/mmu.c19
1 files changed, 14 insertions, 5 deletions
diff --git a/src/arch/armv7/lib/mmu.c b/src/arch/armv7/lib/mmu.c
index 594bba5f29..7d6d46a8a1 100644
--- a/src/arch/armv7/lib/mmu.c
+++ b/src/arch/armv7/lib/mmu.c
@@ -34,6 +34,7 @@
#include <console/console.h>
#include <arch/cache.h>
+#include <arch/io.h>
#define L1_TLB_ENTRIES 4096 /* 1 entry for each 1MB address space */
@@ -44,11 +45,14 @@ void mmu_disable_range(unsigned long start_mb, unsigned long size_mb)
unsigned int i;
uint32_t *ttb_entry = (uint32_t *)ttb_addr;
printk(BIOS_DEBUG, "Disabling: 0x%08lx:0x%08lx\n",
- start_mb << 20, ((start_mb + size_mb) << 20) - 1);
+ start_mb*MiB, start_mb*MiB + size_mb*MiB - 1);
+
+ for (i = start_mb; i < start_mb + size_mb; i++)
+ writel(0, &ttb_entry[i]);
for (i = start_mb; i < start_mb + size_mb; i++) {
- ttb_entry[i] = 0;
- tlbimvaa(i);
+ dccmvac((uintptr_t)&ttb_entry[i]);
+ tlbimvaa(i*MiB);
}
}
@@ -99,9 +103,14 @@ void mmu_config_range(unsigned long start_mb, unsigned long size_mb,
printk(BIOS_DEBUG, "Setting dcache policy: 0x%08lx:0x%08lx [%s]\n",
start_mb << 20, ((start_mb + size_mb) << 20) - 1, str);
+ /* Write out page table entries. */
+ for (i = start_mb; i < start_mb + size_mb; i++)
+ writel((i << 20) | attr, &ttb_entry[i]);
+
+ /* Flush the page table entries, and old translations from the TLB. */
for (i = start_mb; i < start_mb + size_mb; i++) {
- ttb_entry[i] = (i << 20) | attr;
- tlbimvaa(start_mb);
+ dccmvac((uintptr_t)&ttb_entry[i]);
+ tlbimvaa(i*MiB);
}
}