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 <sof/debug/panic.h>
16 #include <sof/init.h>
17 #include <sof/lib/cpu.h>
18 #include <sof/sof.h>
19 #include <sof/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