1/*
2 * Copyright 2014, General Dynamics C4 Systems
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 */
6
7#include <machine/assembler.h>
8
9.code 32
10.section .text, "ax"
11
12.global lockTLBEntry
13
14BEGIN_FUNC(lockTLBEntry)
15    /* Set the lockdown register's preserve bit. */
16    mrc p15, 0, r1, c10, c0, 0
17    orr r1, r1, #1
18    mcr p15, 0, r1, c10, c0, 0
19
20    /* Flush any existing entry in the TLB. Note that this assumes that
21     * there is no page boundary here (i.e., that the next two instruction
22     * accesses don't cause TLB misses unless they are in the page being
23     * locked); given that the kernel has a 16MB mapping for about 16k of
24     * code, this is a reasonably safe assumption.
25     */
26    mcr p15, 0, r0, c8, c7, 1
27    /* Now cause a TLB miss, to load the entry into the TLB locked region. */
28    ldr r2, [r0]
29
30    /* Clear the lockdown register's preserve bit. */
31    mrc p15, 0, r1, c10, c0, 0
32    bic r1, r1, #1
33    mcr p15, 0, r1, c10, c0, 0
34
35    bx lr
36END_FUNC(lockTLBEntry)
37