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     0xa7f00000
11#define STACK_TOP       (VECTOR_BASE + (1 << 20) - 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
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
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    mrc p15, 0, r12, c1, c1, 0
63    /* set the NS bit */
64    orr r12, r12, #1
65    mcr p15, 0, r12, c1, c1, 0
66    pop {lr}
67    movs pc, lr
68
69/* for all other exceptions, just hang */
70smc_halt:
71    ldr pc, [pc, #-48]
72
73arm_monitor_vector_end:
74