rk3288: Add early SRAM mapping

Solving the DACR bug will mean that XN bits suddenly become enforced on
non-LPAE systems, and we will no longer be able to execute out of a
region mapped DCACHE_OFF. When we enable the MMU in romstage we are
still executing out of SRAM, so we would instantly kill ourselves.

Solve this issue by enabling the MMU earlier (in the bootblock) and
mapping the SRAM regions as DCACHE_WRITETHROUGH. They should really be
DCACHE_WRITEBACK, but it looks like there might be hardware limitations
in the Cortex-A12 cache architecture that prevent us from doing so.
Write-through mappings are equivalent to normal non-cacheable on the A12
anyway, and by using this attribute we don't need to introduce a new
DCACHE_OFF_BUT_WITHOUT_XN_BIT type in our API. (Also, using normal
non-cacheable might still have a slight speed advantage over strongly
ordered since it should fetch whole cache lines at once if the processor
finds enough accesses it can combine.)

CQ-DEPEND=CL:223783
BUG=chrome-os-partner:32118
TEST=None (depends on follow-up CL)

Change-Id: I53e827d95acc2db909f1251de78d65e295eceaa7
Signed-off-by: Julius Werner <jwerner@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/223782
Reviewed-by: Aaron Durbin <adurbin@chromium.org>
This commit is contained in:
Julius Werner 2014-10-15 18:50:45 -07:00 committed by chrome-internal-fetch
commit e7b079f4b6
3 changed files with 17 additions and 15 deletions

View file

@ -64,10 +64,6 @@ void main(void)
uint64_t base_time = timestamp_get();
start_romstage_time = timestamp_get();
#endif
/* used for MMU and CBMEM setup, in MB */
u32 dram_start_mb = (uintptr_t)_dram/MiB;
u32 dram_size_mb = CONFIG_DRAM_SIZE_MB;
u32 dram_end_mb = dram_start_mb + dram_size_mb;
console_init();
@ -80,18 +76,12 @@ void main(void)
#if CONFIG_COLLECT_TIMESTAMPS
after_dram_time = timestamp_get();
#endif
mmu_init();
/* Device memory below DRAM is uncached. */
mmu_config_range(0, dram_start_mb, DCACHE_OFF);
/* DRAM is cached. */
mmu_config_range(dram_start_mb, dram_size_mb, DCACHE_WRITEBACK);
/* A window for DMA is uncached. */
/* Now that DRAM is up, add mappings for it and DMA coherency buffer. */
mmu_config_range((uintptr_t)_dram/MiB,
CONFIG_DRAM_SIZE_MB, DCACHE_WRITEBACK);
mmu_config_range((uintptr_t)_dma_coherent/MiB,
_dma_coherent_size/MiB, DCACHE_OFF);
/* The space above DRAM is uncached. */
if (dram_end_mb < 4096)
mmu_config_range(dram_end_mb, 4096 - dram_end_mb, DCACHE_OFF);
dcache_mmu_enable();
cbmem_initialize_empty();
#if CONFIG_COLLECT_TIMESTAMPS

View file

@ -17,10 +17,12 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <arch/cache.h>
#include <arch/io.h>
#include <bootblock_common.h>
#include <console/console.h>
#include <soc/rockchip/rk3288/grf.h>
#include <symbols.h>
#include "addressmap.h"
#include "timer.h"
#include "clock.h"
@ -41,4 +43,13 @@ void bootblock_cpu_init(void)
}
rkclk_init();
mmu_init();
/* Start with a clean slate. */
mmu_config_range(0, 4096, DCACHE_OFF);
/* SRAM is tightly wedged between registers, need to use subtables. Map
* write-through as equivalent for non-cacheable without XN on A17. */
mmu_config_range_kb((uintptr_t)_sram/KiB,
_sram_size/KiB, DCACHE_WRITETHROUGH);
dcache_mmu_enable();
}

View file

@ -34,7 +34,8 @@ SECTIONS
SRAM_START(0xFF700000)
TTB(0xFF700000, 16K)
BOOTBLOCK(0xFF704004, 16K - 4)
BOOTBLOCK(0xFF704004, 15K - 4)
TTB_SUBTABLES(0xFF707c00, 1K)
VBOOT2_WORK(0xFF708000, 16K)
OVERLAP_VERSTAGE_ROMSTAGE(0xFF70C000, 40K)
PRERAM_CBFS_CACHE(0xFF716000, 4K)