Skip to content

Commit 55ce50d

Browse files
ArcaneNibblelaurensvalk
authored andcommitted
pbio/platform/ev3/platform.c: Use lockdown TLB
This makes sure that we can never take a TLB miss penalty when accessing MMIO or local RAM. These "lockdown" TLB entries are not used by general-purpose operating systems like Linux, and they are entirely separate from the "normal" TLB entries.
1 parent 9caac6c commit 55ce50d

File tree

1 file changed

+30
-0
lines changed

1 file changed

+30
-0
lines changed

lib/pbio/platform/ev3/platform.c

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -652,6 +652,21 @@ static void Edma3CCErrHandlerIsr(void) {
652652
static uint32_t l1_page_table[MMU_L1_ENTS] __attribute__((aligned(MMU_L1_ALIGN)));
653653
#define SYSTEM_RAM_SZ_MB 64
654654

655+
static void mmu_tlb_lock(uint32_t addr) {
656+
uint32_t tmp;
657+
__asm__ volatile (
658+
"mrc p15, 0, %0, c10, c0, 0\n" // read lockdown register
659+
"orr %0, #1\n" // set P bit
660+
"mcr p15, 0, %0, c10, c0, 0\n" // write lockdown register
661+
"ldr %0, [%1]\n" // force a TLB load
662+
"mrc p15, 0, %0, c10, c0, 0\n" // read lockdown register
663+
"bic %0, #1\n" // clear P bit
664+
"mcr p15, 0, %0, c10, c0, 0\n" // write lockdown register
665+
: "=&r" (tmp)
666+
: "r" (addr)
667+
);
668+
}
669+
655670
static void mmu_init(void) {
656671
// Invalidate TLB
657672
CP15InvTLB();
@@ -701,6 +716,21 @@ static void mmu_init(void) {
701716
// Enable I-cache, D-cache, alignment faults, and MMU
702717
c15_control |= (1 << 12) | (1 << 2) | (1 << 1) | (1 << 0);
703718
CP15ControlSet(c15_control);
719+
720+
// Set victim field in TLB lockdown register to 0
721+
__asm__ volatile (
722+
"movs r0, #0\n"
723+
"mcr p15, 0, r0, c10, c0, 0"
724+
::: "r0"
725+
);
726+
// Lock all the TLB entries other than main DDR RAM
727+
// This helps improve real-time performance as we will never TLB miss on them
728+
mmu_tlb_lock(0x01C00000);
729+
mmu_tlb_lock(0x01D00000);
730+
mmu_tlb_lock(0x01E00000);
731+
mmu_tlb_lock(0x01F00000);
732+
mmu_tlb_lock(0x80000000);
733+
mmu_tlb_lock(0xFFF00000);
704734
}
705735

706736
enum {

0 commit comments

Comments
 (0)