1/*
2 * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230)
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 */
6
7#include <autoconf.h>
8#include <elfloader/gen_config.h>
9
10#define VECTOR_BASE     0x10000000
11#define STACK_TOP       (VECTOR_BASE + (1 << 12) - 0x10)
12
13/* vector table for monitor mode
14 * 0x00: not used
15 * 0x04: not used
16 * 0x08: secure monitor call
17 * 0x0c: prefetch abort
18 * 0x10: data abort
19 * 0x14: not used
20 * 0x18: IRQ interrupt
21 * 0x1c: FIQ interrupt
22 */
23.arch_extension sec
24.global arm_monitor_vector
25.global arm_monitor_vector_end
26.global smc_handler
27.global smc_halt
28
29/* pc contains the current instruction + 8 bytes
30 * use pc-relative addressing so we can copy the
31 * table. only the offset 0x08 is set up to call
32 * smc_handler, other offsets halt the system.
33 */
34.align 12
35arm_monitor_vector:
36    ldr pc, [pc, #28]
37    ldr pc, [pc, #24]
38    ldr pc, [pc, #16]
39    ldr pc, [pc, #16]
40    ldr pc, [pc, #12]
41    ldr pc, [pc, #8]
42    ldr pc, [pc, #4]
43    ldr pc, [pc, #0]
44
45smc_handler_addr:
46.word   VECTOR_BASE + (smc_handler - arm_monitor_vector)
47smc_halt_addr:
48.word   VECTOR_BASE + (smc_halt - arm_monitor_vector)
49smc_stack:
50.word   STACK_TOP
51
52/* r0: the start physical address for the code that the
53 * caller wants to execute in monitor mode. I know, a huge
54 * security hole. WARNING: the code to be executed should
55 * not reference memory locations !!!
56 */
57smc_handler:
58    /* always have a valid stack */
59    ldr sp, [pc, #-12]
60    push {lr}
61    blx r0
62    isb
63    mrc p15, 0, r12, c1, c1, 0
64    /* set the NS bit */
65    orr r12, r12, #1
66    mcr p15, 0, r12, c1, c1, 0
67    pop {lr}
68    isb
69    movs pc, lr
70
71/* for all other exceptions, just hang */
72smc_halt:
73    ldr pc, [pc, #-48]
74
75arm_monitor_vector_end:
76