1/*
2 * Copyright (c) 2014-2015 Travis Geiselbrecht
3 *
4 * Use of this source code is governed by a MIT-style
5 * license that can be found in the LICENSE file or at
6 * https://opensource.org/licenses/MIT
7 */
8#include <lk/asm.h>
9#include <platform/zynq.h>
10
11/* code run at the very beginning of the system, attempting to trap the 2nd cpu */
12FUNCTION(platform_reset)
13    /* figure out our cpu number */
14    mrc     p15, 0, r12, c0, c0, 5 /* MPIDR */
15
16    /* mask off the bottom 8 bits to test cpu number */
17    ubfx    r12, r12, #0, #8
18
19    /* if we're the 0th cpu, continue to arm_reset */
20    teq     r12, #0
21    beq     arm_reset
22
23    /* bump the cpu counter */
24    adr     r12, __cpu_trapped
25    mov     r11, #1
26    str     r11, [r12]
27    dsb
28
29#if !WITH_SMP
300:
31    /* stay trapped here forever */
32    wfe
33    b       0b
34#else
35    /* pass on through the reset vector, where the arm arch code will trap the cpu */
36    b       arm_reset
37#endif
38
39DATA(__cpu_trapped)
40    .word     0
41
42#if 0
43/* disabled for now */
44
45/* this code attempts to remap sram to 0xfffc0000 - 0xffffffff and
46   branch the cpu into the equivalent spot. Assumes the cpu is running
47   at the initial 0 based mapping */
48
49/* a spot of the top bank of OCM memory for us to run our code from
50   needs to be below where the second cpu is running (0xffffe00-0xfffffff0) */
51#define TARGET_SPOT 0xfffff800
52
53/* first piece of code run out of the reset vector. use
54   to relocate sram to the final location at 0xfffc0000
55   and switch to there */
56FUNCTION(platform_reset)
57    /* relocate the below code to TARGET_SPOT */
58    ldr     r8, =TARGET_SPOT
59    adr     r9, .Lcore_reloc_start
60    adr     r10, .Lcore_reloc_end
61
620:
63    ldr     r12, [r9], #4
64    str     r12, [r8], #4
65    cmp     r9, r10
66    bne     0b
67
68    /* load constants we will need below */
69    ldr     r8, =SLCR_BASE
70    ldr     r9, =SCU_CONTROL_BASE
71
72    /* calculate the new return address this code will need to branch to */
73    adr     r12, .Ldone
74    add     r12, #0xfffc0000
75
76    ldr     r10, =TARGET_SPOT
77    bx      r10
78
79.Ldone:
80    b       arm_reset
81
82.Lcore_reloc_start:
83    # use SCLR to map the sram blocks to the top of their segment
84    movw    r10, #SLCR_UNLOCK_KEY
85    str     r10, [r8, #SLCR_UNLOCK]
86
87    ldr     r10, [r8, #OCM_CFG]
88    orr     r10, #0xf
89    str     r10, [r8, #OCM_CFG]
90
91    movw    r10, #SLCR_LOCK_KEY
92    str     r10, [r8, #SLCR_LOCK]
93
94    # tell the SCU to not filter first 1MB
95    mov     r10, #0
96    str     r10, [r9, #0x40] /* SCU filter start address */
97    dmb
98
99    bx      r12
100.Lcore_reloc_end:
101
102.ltorg
103#endif
104
105
106