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.

BUG=None
TEST=Built and booted on Snow. Verified that vboot screens were displayed
completely.
BRANCH=None

Change-Id: I9f3c3d3d1547b85d5b2d7035050a5107ead1f236
Signed-off-by: Gabe Black <gabeblack@google.com>
Reviewed-on: https://gerrit.chromium.org/gerrit/55638
Commit-Queue: Stefan Reinauer <reinauer@google.com>
Reviewed-by: Stefan Reinauer <reinauer@google.com>
Tested-by: Stefan Reinauer <reinauer@google.com>
This commit is contained in:
Gabe Black 2013-05-18 22:45:54 -07:00 committed by ChromeBot
commit 412df76d2f

View file

@ -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);
}
}