1 // SPDX-License-Identifier: BSD-3-Clause
2 //
3 // Copyright(c) 2016 Intel Corporation. All rights reserved.
4 //
5 // Author: Liam Girdwood <liam.r.girdwood@linux.intel.com>
6
7 /**
8 * \file arch/xtensa/init.c
9 * \brief Xtensa initialization functions
10 * \authors Liam Girdwood <liam.r.girdwood@linux.intel.com>
11 */
12
13 #include "xtos-internal.h"
14 #include <sof/common.h>
15 #include <rtos/panic.h>
16 #include <sof/init.h>
17 #include <sof/lib/cpu.h>
18 #include <rtos/sof.h>
19 #include <rtos/spinlock.h>
20
21 #include <ipc/trace.h>
22
23 #include <xtensa/xtruntime-frames.h>
24 #include <xtos-structs.h>
25 #include <stddef.h>
26 #include <stdint.h>
27
28 /* UserFrame's size needs to be 16 bytes aligned */
29 STATIC_ASSERT((sizeof(UserFrame) % 16) == 0, invalid_UserFrame_alignment);
30
31 /* verify xtos_active_task offset */
32 STATIC_ASSERT(offsetof(struct thread_data, xtos_active_task) ==
33 XTOS_TASK_CONTEXT_OFFSET, invalid_xtos_active_task_offset);
34
35 #if CONFIG_DEBUG_LOCKS
36 /** \brief Debug lock. */
37 uint32_t lock_dbg_atomic;
38
39 /** \brief Debug locks per user. */
40 uint32_t lock_dbg_user[DBG_LOCK_USERS] = {0};
41 #endif
42 #if CONFIG_NO_SECONDARY_CORE_ROM
43 void *shared_vecbase_ptr __aligned(PLATFORM_DCACHE_ALIGN);
44 #endif
45 /** \brief Core context for primary core. */
46 static struct core_context primary_core_ctx;
47
48 /** \brief Core context pointers for all the cores. */
49 struct core_context *core_ctx_ptr[CONFIG_CORE_COUNT] = { 0 };
50
51 /** \brief Xtos core data for primary core. */
52 struct xtos_core_data primary_core_data;
53
54 /** \brief Xtos core data pointers for all the cores. */
55 struct xtos_core_data *core_data_ptr[CONFIG_CORE_COUNT] = { 0 };
56
57 /**
58 * \brief Initializes core specific data.
59 */
initialize_pointers_per_core(void)60 static void initialize_pointers_per_core(void)
61 {
62 int core = cpu_get_id();
63 struct xtos_core_data *core_data;
64 xtos_structures_pointers *p;
65
66 if (core == PLATFORM_PRIMARY_CORE_ID) {
67 primary_core_data.thread_data_ptr = &primary_core_ctx.td;
68 core_ctx_ptr[PLATFORM_PRIMARY_CORE_ID] = &primary_core_ctx;
69 core_data_ptr[PLATFORM_PRIMARY_CORE_ID] = &primary_core_data;
70 }
71
72 cpu_write_threadptr((int)core_ctx_ptr[core]);
73
74 core_data = core_data_ptr[core];
75
76 p = &core_data->thread_data_ptr->xtos_ptrs;
77 p->xtos_interrupt_ctx = &core_data->xtos_interrupt_ctx;
78 p->xtos_saved_sp = &core_data->xtos_saved_sp;
79 #if CONFIG_XT_INTERRUPT_LEVEL_1
80 p->xtos_stack_for_interrupt_1 = core_data->xtos_stack_for_interrupt_1;
81 #endif
82 #if CONFIG_XT_INTERRUPT_LEVEL_2
83 p->xtos_stack_for_interrupt_2 = core_data->xtos_stack_for_interrupt_2;
84 #endif
85 #if CONFIG_XT_INTERRUPT_LEVEL_3
86 p->xtos_stack_for_interrupt_3 = core_data->xtos_stack_for_interrupt_3;
87 #endif
88 #if CONFIG_XT_INTERRUPT_LEVEL_4
89 p->xtos_stack_for_interrupt_4 = core_data->xtos_stack_for_interrupt_4;
90 #endif
91 #if CONFIG_XT_INTERRUPT_LEVEL_5
92 p->xtos_stack_for_interrupt_5 = core_data->xtos_stack_for_interrupt_5;
93 #endif
94 #if CONFIG_MULTICORE
95 p->xtos_enabled = &core_data->xtos_int_data.xtos_enabled;
96 p->xtos_intstruct = &core_data->xtos_int_data;
97 p->xtos_interrupt_table =
98 &core_data->xtos_int_data.xtos_interrupt_table.array[0];
99 p->xtos_interrupt_mask_table =
100 &core_data->xtos_int_data.xtos_interrupt_mask_table[0];
101 #endif
102 }
103
104 /**
105 * \brief Called in the case of exception.
106 */
exception(void)107 static void exception(void)
108 {
109 uintptr_t epc1;
110
111 __asm__ __volatile__("rsr %0, EPC1" : "=a" (epc1) : : "memory");
112
113 /* now save panic dump */
114 /* TODO: we could invoke a GDB stub here */
115 panic_dump(SOF_IPC_PANIC_EXCEPTION, NULL, &epc1);
116 }
117
118 /**
119 * \brief Registers exception handlers.
120 */
register_exceptions(void)121 static void register_exceptions(void)
122 {
123
124 /* 0 - 9 */
125 _xtos_set_exception_handler(
126 EXCCAUSE_ILLEGAL, (void *)&exception);
127 _xtos_set_exception_handler(
128 EXCCAUSE_SYSCALL, (void *)&exception);
129 _xtos_set_exception_handler(
130 EXCCAUSE_INSTR_ERROR, (void *)&exception);
131 _xtos_set_exception_handler(
132 EXCCAUSE_LOAD_STORE_ERROR, (void *)&exception);
133 _xtos_set_exception_handler(
134 EXCCAUSE_ALLOCA, (void *)&exception);
135 _xtos_set_exception_handler(
136 EXCCAUSE_DIVIDE_BY_ZERO, (void *)&exception);
137 _xtos_set_exception_handler(
138 EXCCAUSE_SPECULATION, (void *)&exception);
139 _xtos_set_exception_handler(
140 EXCCAUSE_PRIVILEGED, (void *)&exception);
141 _xtos_set_exception_handler(
142 EXCCAUSE_UNALIGNED, (void *)&exception);
143
144 /* Reserved 10..11 */
145
146 _xtos_set_exception_handler(
147 EXCCAUSE_INSTR_DATA_ERROR, (void *)&exception);
148 _xtos_set_exception_handler(
149 EXCCAUSE_LOAD_STORE_DATA_ERROR, (void *)&exception);
150 _xtos_set_exception_handler(
151 EXCCAUSE_INSTR_ADDR_ERROR, (void *)&exception);
152 _xtos_set_exception_handler(
153 EXCCAUSE_LOAD_STORE_ADDR_ERROR, (void *)&exception);
154 _xtos_set_exception_handler(
155 EXCCAUSE_ITLB_MISS, (void *)&exception);
156 _xtos_set_exception_handler(
157 EXCCAUSE_ITLB_MULTIHIT, (void *)&exception);
158 _xtos_set_exception_handler(
159 EXCCAUSE_INSTR_RING, (void *)&exception);
160
161 /* Reserved 19 */
162
163 _xtos_set_exception_handler(
164 EXCCAUSE_INSTR_PROHIBITED, (void *)&exception);
165
166 /* Reserved 21..23 */
167 _xtos_set_exception_handler(
168 EXCCAUSE_DTLB_MISS, (void *)&exception);
169 _xtos_set_exception_handler(
170 EXCCAUSE_DTLB_MULTIHIT, (void *)&exception);
171 _xtos_set_exception_handler(
172 EXCCAUSE_LOAD_STORE_RING, (void *)&exception);
173
174 /* Reserved 27 */
175 _xtos_set_exception_handler(
176 EXCCAUSE_LOAD_PROHIBITED, (void *)&exception);
177 _xtos_set_exception_handler(
178 EXCCAUSE_STORE_PROHIBITED, (void *)&exception);
179
180 /* Reserved 30..31 */
181 _xtos_set_exception_handler(
182 EXCCAUSE_CP0_DISABLED, (void *)&exception);
183 _xtos_set_exception_handler(
184 EXCCAUSE_CP1_DISABLED, (void *)&exception);
185 _xtos_set_exception_handler(
186 EXCCAUSE_CP2_DISABLED, (void *)&exception);
187 _xtos_set_exception_handler(
188 EXCCAUSE_CP3_DISABLED, (void *)&exception);
189 _xtos_set_exception_handler(
190 EXCCAUSE_CP4_DISABLED, (void *)&exception);
191 _xtos_set_exception_handler(
192 EXCCAUSE_CP5_DISABLED, (void *)&exception);
193 _xtos_set_exception_handler(
194 EXCCAUSE_CP6_DISABLED, (void *)&exception);
195 _xtos_set_exception_handler(
196 EXCCAUSE_CP7_DISABLED, (void *)&exception);
197
198 /* Reserved 40..63 */
199 }
200
201 /**
202 * \brief Initializes architecture.
203 * \return Error status.
204 */
arch_init(void)205 int arch_init(void)
206 {
207 initialize_pointers_per_core();
208 register_exceptions();
209 return 0;
210 }
211