1/*
2 * Copyright (c) 2016 ETH Zurich.
3 * All rights reserved.
4 *
5 * This file is distributed under the terms in the attached LICENSE file.
6 * If you do not find this file, copies can be found by writing to:
7 * ETH Zurich D-INFK, Haldeneggsteig 4, CH-8092 Zurich. Attn: Systems Group.
8 */
9
10#ifndef __ASSEMBLER__
11#define __ASSEMBLER__
12#endif // __ASSEMBLER__
13
14#include <offsets.h>
15
16    .globl bsp_start
17
18    .arm
19    .section .text.bsp
20
21/*** Boot-core-only code. ***/
22
23/* This is the entry point for BSP kernel, which loads GOT base and kernel
24 * stack from their linked locations in the BSP image. */
25bsp_start:
26    // On entry:
27    //
28    // MMU, caches enabled.
29    // No TLB lockdown.
30    // CPU is in a system mode, interrupts and aborts disabled.
31    //
32
33    // Find the GOT, and place its address in the PIC register.  On the BSP,
34    // we're using the data segment provided by the bootloader, against which
35    // our text segment was relocated.  Thus it's safe to use code-relative
36    // addressing to find it here.  After this point, we'll never again use
37    // code-relative addressing outside the text segment, as other cores will
38    // have relocated data segments, but may share this text segment.
39
40    adr r4, stack_got_prel
41    ldr r5, [r4]
42    ldr r6, stack_got_offset
43    // We have:
44    //  - r4 = &stack_got_prel
45    //  - r5 = GOT(kernel_stack) - &stack_got_prel
46    //  - r6 = GOT(kernel_stack) - GOT_ORG
47
48    add r4, r5, r4 // r4 = GOT(kernel_stack)
49    sub r4, r4, r6 // r4 = GOT_ORG
50
51    // Set the PIC register.
52    mov PIC_REGISTER, r4
53
54    // Save the GOT base to the PL1 thread ID register, whence it will be
55    // reloaded on every kernel entry.
56    mcr p15, 0, PIC_REGISTER, c13, c0, 4
57
58    // Initialise SP to the BSP stack, via the GOT.
59    ldr sp, [PIC_REGISTER, r6]
60    add sp, sp, #KERNEL_STACK_SIZE
61
62    b arch_init
63
64/* These two relocations allow us to locate the GOT on the BSP core. */
65
66    .align 2
67    .type stack_got_offset, STT_OBJECT
68stack_got_offset:
69    // This is the address of the GOT entry for bsp_stack, relative to the
70    // base of the GOT.
71    .word kernel_stack(GOT)
72
73    .type stack_got_prel, STT_OBJECT
74stack_got_prel:
75    // This is the address of that same GOT entry, relative to (here + 8
76    // bytes) (PC bias).
77    .word kernel_stack(GOT_PREL)
78
79/* Any remaining constants go here. */
80.ltorg
81