diff options
author | Julius Werner <jwerner@chromium.org> | 2014-10-09 17:31:45 -0700 |
---|---|---|
committer | Patrick Georgi <pgeorgi@google.com> | 2015-04-08 08:48:06 +0200 |
commit | 108548a42aa3a255bd84247549cd1bf406a152f1 (patch) | |
tree | 6a000c46d9d11dc3a196603ddb2e2684d605731b /src/arch/arm/include | |
parent | 42e23a67ad2cd99fe7f9658b82d9dd2109643d68 (diff) |
armv7: Add fine-grained page table support
This patch adds an mmu_config_range_kb() function, which can set memory
types at the 4KB level by chaining a fine-grained page table to an
existing superpage entry. It is only intended for special cases where
this level of precision is really necessary and therefore comes with a
few practical limitations (the area for each invocation must be confined
within a single superpage, and you are not allowed to remap the same
region with mmu_config_range() again later). Since the fine-grained page
tables need some space, boards intending to use this feature must define
a TTB_SUBTABLES() region in their memlayout.ld.
BUG=chrome-os-partner:32848
TEST=Booted both Veyron_Pinky (normal) and Nyan_Blaze (LPAE), ensured
that they still work. Checksummed the page tables with and without this
patch, confirmed that they end up equal. Hacked in some subtable test
entries, hexdumped all tables and manually confirmed that they look as
expected.
Change-Id: I8c3eb7c2eb9c82e2abc5f2c0dda91f5b2eee7023
Signed-off-by: Patrick Georgi <pgeorgi@chromium.org>
Original-Commit-Id: 2f13e60cf5509b9a63fb7b8d84846daf889dc1b7
Original-Change-Id: Iedf7ca435ae337ead85115200d6987fb0d4828d7
Original-Signed-off-by: Julius Werner <jwerner@chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/223781
Reviewed-on: http://review.coreboot.org/9341
Tested-by: build bot (Jenkins)
Reviewed-by: Stefan Reinauer <stefan.reinauer@coreboot.org>
Diffstat (limited to 'src/arch/arm/include')
-rw-r--r-- | src/arch/arm/include/arch/memlayout.h | 5 | ||||
-rw-r--r-- | src/arch/arm/include/armv4/arch/cache.h | 19 | ||||
-rw-r--r-- | src/arch/arm/include/armv7/arch/cache.h | 11 |
3 files changed, 13 insertions, 22 deletions
diff --git a/src/arch/arm/include/arch/memlayout.h b/src/arch/arm/include/arch/memlayout.h index 9f5b383160..2c733946a2 100644 --- a/src/arch/arm/include/arch/memlayout.h +++ b/src/arch/arm/include/arch/memlayout.h @@ -27,6 +27,11 @@ _ = ASSERT(size >= 16K + IS_ENABLED(CONFIG_ARM_LPAE) * 32, \ "TTB must be 16K (+ 32 for LPAE)!"); +#define TTB_SUBTABLES(addr, size) \ + REGION(ttb_subtables, addr, size, IS_ENABLED(CONFIG_ARM_LPAE)*3K + 1K) \ + _ = ASSERT(size % (1K + 3K * IS_ENABLED(CONFIG_ARM_LPAE)) == 0, \ + "TTB subtable region must be evenly divisible by table size!"); + /* ARM stacks need 8-byte alignment and stay in one place through ramstage. */ #define STACK(addr, size) REGION(stack, addr, size, 8) diff --git a/src/arch/arm/include/armv4/arch/cache.h b/src/arch/arm/include/armv4/arch/cache.h index e41ff9a49f..65f59662a6 100644 --- a/src/arch/arm/include/armv4/arch/cache.h +++ b/src/arch/arm/include/armv4/arch/cache.h @@ -72,23 +72,4 @@ void cache_sync_instructions(void); /* tlb invalidate all */ void tlb_invalidate_all(void); -/* - * Generalized setup/init functions - */ - -/* mmu initialization (set page table address, set permissions, etc) */ -void mmu_init(void); - -enum dcache_policy { - DCACHE_OFF, - DCACHE_WRITEBACK, - DCACHE_WRITETHROUGH, -}; - -/* disable the mmu for a range. Primarily useful to lock out address 0. */ -void mmu_disable_range(unsigned long start_mb, unsigned long size_mb); -/* mmu range configuration (set dcache policy) */ -void mmu_config_range(unsigned long start_mb, unsigned long size_mb, - enum dcache_policy policy); - #endif /* ARM_CACHE_H */ diff --git a/src/arch/arm/include/armv7/arch/cache.h b/src/arch/arm/include/armv7/arch/cache.h index dde2c08c1d..f23dec1bbb 100644 --- a/src/arch/arm/include/armv7/arch/cache.h +++ b/src/arch/arm/include/armv7/arch/cache.h @@ -345,9 +345,14 @@ enum dcache_policy { }; /* disable the mmu for a range. Primarily useful to lock out address 0. */ -void mmu_disable_range(unsigned long start_mb, unsigned long size_mb); +void mmu_disable_range(u32 start_mb, u32 size_mb); /* mmu range configuration (set dcache policy) */ -void mmu_config_range(unsigned long start_mb, unsigned long size_mb, - enum dcache_policy policy); +void mmu_config_range(u32 start_mb, u32 size_mb, enum dcache_policy policy); + +/* Reconfigure memory mappings at the fine-grained (4K) page level. Must be + * called on a range contained within a single, already mapped block/superpage. + * Careful: Do NOT map over this address range with mmu_config_range() again + * later, or you will leak resources and may desync your TLB! */ +void mmu_config_range_kb(u32 start_kb, u32 size_kb, enum dcache_policy policy); #endif /* ARM_CACHE_H */ |