1/*
2 * Copyright (c) 2016, Freescale Semiconductor, Inc.
3 * Copyright 2016 - 2019 , NXP
4 * All rights reserved.
5 *
6 *
7 * SPDX-License-Identifier: Apache-2.0
8 */
9
10#include <zephyr/toolchain.h>
11#include <zephyr/linker/sections.h>
12#include <zephyr/arch/cpu.h>
13
14#if defined(CONFIG_SOC_RESET_HOOK) && defined(CONFIG_SOC_LPC54114_M4)
15
16    .syntax unified
17    .arch armv7-m
18    .text
19    .thumb
20
21rel_vals:
22    .long   0xE000ED00   /* cpu_id */
23    .long   0x40000800   /* cpu_ctrl */
24    .long   0x40000804   /* coproc_boot */
25    .long   0x40000808   /* coproc_stack */
26    .short  0x0FFF
27    .short  0x0C24
28
29GTEXT(soc_reset_hook)
30SECTION_FUNC(TEXT,soc_reset_hook)
31
32/* Both the M0+ and M4 core come via this shared startup code,
33 * but the M0+ and M4 core have different vector tables.
34 * Determine if the core executing this code is the master or
35 * the slave and handle each core state individually. */
36
37shared_boot_entry:
38    ldr     r6, =rel_vals
39
40    /* Flag for slave core (0) */
41    movs    r4, 0
42    movs    r5, 1
43    push {lr}
44    bl SystemInit
45    pop {lr}
46
47    /* Determine which core (M0+ or M4) this code is running on */
48    /* r2 = (((*cpu_id) >> 4) & 0xFFF); (M4 core == 0xC24) */
49get_current_core_id:
50    ldr     r0, [r6, #0]
51    ldr     r1, [r0]                        /* r1 = CPU ID status */
52    lsrs    r1, r1, #4                      /* Right justify 12 CPU ID bits */
53    ldrh    r2, [r6, #16]                   /* Mask for CPU ID bits */
54    ands    r2, r1, r2                      /* r2 = ARM COrtex CPU ID */
55    ldrh    r3, [r6, #18]                   /* Mask for CPU ID bits */
56    cmp     r3, r2                          /* Core ID matches M4 identifier */
57    bne     get_master_status
58    mov     r4, r5                          /* Set flag for master core (1) */
59
60    /* Determine if M4 core is the master or slave */
61    /* r3 = ((*cpu_ctrl) & 1); (0 == m0+, 1 == M4) */
62get_master_status:
63    ldr     r0, [r6, #4]
64    ldr     r3, [r0]                        /* r3 = SYSCON co-processor CPU control status */
65
66    ands    r3, r3, r5                      /* r3 = (Bit 0: 1 = M4 is master, 0 = M4 is slave) */
67
68    /* Select boot based on selected master core and core ID */
69
70select_boot:
71    eors    r3, r3, r4                      /* r4 = (Bit 0: 0 = master, 1 = slave) */
72
73    bne     slave_boot
74    b       normal_boot
75
76    /* Slave boot */
77slave_boot:
78    ldr     r0, [r6, #8]
79    ldr     r2, [r0]                        /* r1 = SYSCON co-processor boot address */
80
81    cmp     r2, #0                          /* Slave boot address = 0 (not set up)? */
82
83    beq     cpu_sleep
84    ldr     r0, [r6, #12]
85    ldr     r1, [r0]                        /* r5 = SYSCON co-processor stack address */
86
87    mov     sp, r1                          /* Update slave CPU stack pointer */
88
89    /* Be sure to update VTOR for the slave MCU to point to the */
90    /* slave vector table in boot memory */
91    bx      r2                              /* Jump to slave boot address */
92
93    /* Slave isn't yet setup for system boot from the master */
94    /* so sleep until the master sets it up and then reboots it */
95cpu_sleep:
96    mov     sp, r5                          /* Will force exception if something happens */
97cpu_sleep_wfi:
98    wfi                                     /* Sleep forever until master reboots */
99    b       cpu_sleep_wfi
100normal_boot:
101    bx      lr
102
103#endif
104