blob: ea2007747cd2523e7b34c464c395d237f3f1142b [file] [log] [blame]
Kristofer Jonsson93175812022-04-21 19:27:11 +02001/*
Jonny Svärd4db21c92023-05-15 11:44:05 +02002 * SPDX-FileCopyrightText: Copyright 2020-2023 Arm Limited and/or its affiliates <open-source-office@arm.com>
Kristofer Jonsson93175812022-04-21 19:27:11 +02003 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 * Licensed under the Apache License, Version 2.0 (the License); you may
7 * not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an AS IS BASIS, WITHOUT
14 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18
19/****************************************************************************
20 * Includes
21 ****************************************************************************/
22
23#include "target.hpp"
24
25#ifdef ETHOSU
26#include <ethosu_driver.h>
27#include <timing_adapter.h>
28#endif
29
30#include "mpu.hpp"
31#include "uart_stdout.h"
32
33#include <inttypes.h>
34#include <stdio.h>
35#include <stdlib.h>
36#include <vector>
37
38using namespace EthosU;
39
40/****************************************************************************
41 * Defines
42 ****************************************************************************/
43
44#define ETHOSU_BASE_ADDRESS 0x50004000
45#define ETHOSU_IRQ 16
Jonny Svärd4db21c92023-05-15 11:44:05 +020046#define ETHOSU_IRQ_PRIORITY 5
Kristofer Jonsson93175812022-04-21 19:27:11 +020047
48#define ETHOSU0_TA0_BASE_ADDRESS 0x58103000
49#define ETHOSU0_TA1_BASE_ADDRESS 0x58103200
50
51/****************************************************************************
52 * Variables
53 ****************************************************************************/
54
55#if defined(ETHOSU_FAST_MEMORY_SIZE) && ETHOSU_FAST_MEMORY_SIZE > 0
56__attribute__((aligned(16), section(".bss.ethosu_scratch"))) uint8_t ethosu_scratch[ETHOSU_FAST_MEMORY_SIZE];
57#else
58#define ethosu_scratch 0
59#define ETHOSU_FAST_MEMORY_SIZE 0
60#endif
61
62#ifdef ETHOSU
63struct ethosu_driver ethosu0_driver;
64#endif
65
66/****************************************************************************
67 * Timing Adapters
68 ****************************************************************************/
69
70#ifdef ETHOSU
71
72#ifndef ETHOSU_TA_MAXR_0
73#define ETHOSU_TA_MAXR_0 0
74#endif
75
76#ifndef ETHOSU_TA_MAXW_0
77#define ETHOSU_TA_MAXW_0 0
78#endif
79
80#ifndef ETHOSU_TA_MAXRW_0
81#define ETHOSU_TA_MAXRW_0 0
82#endif
83
84#ifndef ETHOSU_TA_RLATENCY_0
85#define ETHOSU_TA_RLATENCY_0 0
86#endif
87
88#ifndef ETHOSU_TA_WLATENCY_0
89#define ETHOSU_TA_WLATENCY_0 0
90#endif
91
92#ifndef ETHOSU_TA_PULSE_ON_0
93#define ETHOSU_TA_PULSE_ON_0 0
94#endif
95
96#ifndef ETHOSU_TA_PULSE_OFF_0
97#define ETHOSU_TA_PULSE_OFF_0 0
98#endif
99
100#ifndef ETHOSU_TA_BWCAP_0
101#define ETHOSU_TA_BWCAP_0 0
102#endif
103
104#ifndef ETHOSU_TA_PERFCTRL_0
105#define ETHOSU_TA_PERFCTRL_0 0
106#endif
107
108#ifndef ETHOSU_TA_PERFCNT_0
109#define ETHOSU_TA_PERFCNT_0 0
110#endif
111
112#ifndef ETHOSU_TA_MODE_0
113#define ETHOSU_TA_MODE_0 1
114#endif
115
116#ifndef ETHOSU_TA_HISTBIN_0
117#define ETHOSU_TA_HISTBIN_0 0
118#endif
119
120#ifndef ETHOSU_TA_HISTCNT_0
121#define ETHOSU_TA_HISTCNT_0 0
122#endif
123
124#ifndef ETHOSU_TA_MAXR_1
125#define ETHOSU_TA_MAXR_1 0
126#endif
127
128#ifndef ETHOSU_TA_MAXW_1
129#define ETHOSU_TA_MAXW_1 0
130#endif
131
132#ifndef ETHOSU_TA_MAXRW_1
133#define ETHOSU_TA_MAXRW_1 0
134#endif
135
136#ifndef ETHOSU_TA_RLATENCY_1
137#define ETHOSU_TA_RLATENCY_1 0
138#endif
139
140#ifndef ETHOSU_TA_WLATENCY_1
141#define ETHOSU_TA_WLATENCY_1 0
142#endif
143
144#ifndef ETHOSU_TA_PULSE_ON_1
145#define ETHOSU_TA_PULSE_ON_1 0
146#endif
147
148#ifndef ETHOSU_TA_PULSE_OFF_1
149#define ETHOSU_TA_PULSE_OFF_1 0
150#endif
151
152#ifndef ETHOSU_TA_BWCAP_1
153#define ETHOSU_TA_BWCAP_1 0
154#endif
155
156#ifndef ETHOSU_TA_PERFCTRL_1
157#define ETHOSU_TA_PERFCTRL_1 0
158#endif
159
160#ifndef ETHOSU_TA_PERFCNT_1
161#define ETHOSU_TA_PERFCNT_1 0
162#endif
163
164#ifndef ETHOSU_TA_MODE_1
165#define ETHOSU_TA_MODE_1 1
166#endif
167
168#ifndef ETHOSU_TA_HISTBIN_1
169#define ETHOSU_TA_HISTBIN_1 0
170#endif
171
172#ifndef ETHOSU_TA_HISTCNT_1
173#define ETHOSU_TA_HISTCNT_1 0
174#endif
175
Henrik Hoglindebe33a42022-06-17 11:32:17 +0200176#if defined(ETHOSU_TARGET_NPU_TA_COUNT) && ETHOSU_TARGET_NPU_TA_COUNT >= 2
Kristofer Jonsson93175812022-04-21 19:27:11 +0200177static uintptr_t ethosu_ta_base_addrs[ETHOSU_NPU_COUNT][ETHOSU_NPU_TA_COUNT] = {
178 {ETHOSU0_TA0_BASE_ADDRESS, ETHOSU0_TA1_BASE_ADDRESS}};
179struct timing_adapter ethosu_ta[ETHOSU_NPU_COUNT][ETHOSU_NPU_TA_COUNT];
180struct timing_adapter_settings ethosu_ta_settings[ETHOSU_NPU_TA_COUNT] = {{ETHOSU_TA_MAXR_0,
181 ETHOSU_TA_MAXW_0,
182 ETHOSU_TA_MAXRW_0,
183 ETHOSU_TA_RLATENCY_0,
184 ETHOSU_TA_WLATENCY_0,
185 ETHOSU_TA_PULSE_ON_0,
186 ETHOSU_TA_PULSE_OFF_0,
187 ETHOSU_TA_BWCAP_0,
188 ETHOSU_TA_PERFCTRL_0,
189 ETHOSU_TA_PERFCNT_0,
190 ETHOSU_TA_MODE_0,
191 0, // Read only register
192 ETHOSU_TA_HISTBIN_0,
193 ETHOSU_TA_HISTCNT_0},
194 {ETHOSU_TA_MAXR_1,
195 ETHOSU_TA_MAXW_1,
196 ETHOSU_TA_MAXRW_1,
197 ETHOSU_TA_RLATENCY_1,
198 ETHOSU_TA_WLATENCY_1,
199 ETHOSU_TA_PULSE_ON_1,
200 ETHOSU_TA_PULSE_OFF_1,
201 ETHOSU_TA_BWCAP_1,
202 ETHOSU_TA_PERFCTRL_1,
203 ETHOSU_TA_PERFCNT_1,
204 ETHOSU_TA_MODE_1,
205 0, // Read only register
206 ETHOSU_TA_HISTBIN_1,
207 ETHOSU_TA_HISTCNT_1}};
Henrik Hoglindebe33a42022-06-17 11:32:17 +0200208#endif
Kristofer Jonsson93175812022-04-21 19:27:11 +0200209
210#endif
211
212/****************************************************************************
213 * Cache maintenance
214 ****************************************************************************/
215
216#if defined(CPU_CACHE_ENABLE) && defined(__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U)
217extern "C" {
218void ethosu_flush_dcache(uint32_t *p, size_t bytes) {
219 if (p)
220 SCB_CleanDCache_by_Addr(p, bytes);
221 else
222 SCB_CleanDCache();
223}
224
225void ethosu_invalidate_dcache(uint32_t *p, size_t bytes) {
226 if (p)
227 SCB_InvalidateDCache_by_Addr(p, bytes);
228 else
229 SCB_InvalidateDCache();
230}
231}
232#endif
233
234/****************************************************************************
235 * Init
236 ****************************************************************************/
237
238namespace {
239
240extern "C" {
241struct ExcContext {
242 uint32_t r0;
243 uint32_t r1;
244 uint32_t r2;
245 uint32_t r3;
246 uint32_t r12;
247 uint32_t lr;
248 uint32_t pc;
249 uint32_t xPsr;
250};
251
252void HardFault_Handler() {
253 int irq;
254 struct ExcContext *e;
255 uint32_t sp;
256
Ledion Daja204210b2023-08-15 13:32:07 +0200257 asm volatile("mrs %0, ipsr \n" // Read IPSR (Exception number)
Kristofer Jonsson93175812022-04-21 19:27:11 +0200258 "sub %0, #16 \n" // Get it into IRQn_Type range
259 "tst lr, #4 \n" // Select the stack which was in use
260 "ite eq \n"
261 "mrseq %1, msp \n"
262 "mrsne %1, psp \n"
263 "mov %2, sp \n"
264 : "=r"(irq), "=r"(e), "=r"(sp));
265
266 printf("Hard fault. irq=%d, pc=0x%08" PRIx32 ", lr=0x%08" PRIx32 ", xpsr=0x%08" PRIx32 ", sp=0x%08" PRIx32 "\n",
267 irq,
268 e->pc,
269 e->lr,
270 e->xPsr,
271 sp);
272 printf(
273 "%11s cfsr=0x%08" PRIx32 " bfar=0x%08" PRIx32 " mmfar=0x%08" PRIx32 "\n", "", SCB->CFSR, SCB->BFAR, SCB->MMFAR);
274 exit(1);
275}
276}
277
278#ifdef ETHOSU
279void ethosuIrqHandler() {
280 ethosu_irq_handler(&ethosu0_driver);
281}
282#endif
283
284} // namespace
285
286namespace EthosU {
287
288void targetSetup() {
289 // Initialize UART driver
290 UartStdOutInit();
291
292#ifdef ETHOSU
293 // Initialize timing adapter(s)
294 for (int i = 0; i < ETHOSU_NPU_COUNT; i++) {
Henrik Hoglindebe33a42022-06-17 11:32:17 +0200295#if defined(ETHOSU_TARGET_NPU_TA_COUNT) && ETHOSU_TARGET_NPU_TA_COUNT >= 2
Kristofer Jonsson93175812022-04-21 19:27:11 +0200296 for (int j = 0; j < ETHOSU_NPU_TA_COUNT; j++) {
297 if (ta_init(&ethosu_ta[i][j], ethosu_ta_base_addrs[i][j])) {
298 printf("Failed to initialize timing-adapter %d for NPU %d\n", j, i);
299 } else {
300 // Set the updated configuration
301 ta_set_all(&ethosu_ta[i][j], &ethosu_ta_settings[j]);
302 }
303 }
Henrik Hoglindebe33a42022-06-17 11:32:17 +0200304#endif
Kristofer Jonsson93175812022-04-21 19:27:11 +0200305 }
306
307 // Initialize Ethos-U NPU driver
308 if (ethosu_init(&ethosu0_driver,
309 reinterpret_cast<void *>(ETHOSU_BASE_ADDRESS),
310 ethosu_scratch,
311 ETHOSU_FAST_MEMORY_SIZE,
312 1,
313 1)) {
314 printf("Failed to initialize NPU.\n");
315 return;
316 }
317
318 // Assumes SCB->VTOR point to RW memory
319 NVIC_SetVector(static_cast<IRQn_Type>(ETHOSU_IRQ), (uint32_t)&ethosuIrqHandler);
Jonny Svärd4db21c92023-05-15 11:44:05 +0200320 NVIC_SetPriority(static_cast<IRQn_Type>(ETHOSU_IRQ), ETHOSU_IRQ_PRIORITY);
Kristofer Jonsson93175812022-04-21 19:27:11 +0200321 NVIC_EnableIRQ(static_cast<IRQn_Type>(ETHOSU_IRQ));
322#endif
323
324 // MPU setup
325 const std::vector<ARM_MPU_Region_t> mpuConfig = {
326 {
327 // ITCM (NS)
328 ARM_MPU_RBAR(0x00000000, // Base
329 ARM_MPU_SH_NON, // Non-shareable
330 1, // Read-Only
331 1, // Non-Privileged
332 0), // eXecute Never disabled
333 ARM_MPU_RLAR(0x00007fff, // Limit
334 Mpu::WTRA_index) // Attribute index - Write-Through, Read-allocate
335 },
336 {
337 // ITCM (S)
338 ARM_MPU_RBAR(0x10000000, // Base
339 ARM_MPU_SH_NON, // Non-shareable
340 1, // Read-Only
341 1, // Non-Privileged
342 0), // eXecute Never disabled
343 ARM_MPU_RLAR(0x10007fff, // Limit
344 Mpu::WTRA_index) // Attribute index - Write-Through, Read-allocate
345 },
346 {
347 // DTCM (NS)
348 ARM_MPU_RBAR(0x20000000, // Base
349 ARM_MPU_SH_NON, // Non-shareable
350 0, // Read-Write
351 1, // Non-Privileged
352 1), // eXecute Never enabled
353 ARM_MPU_RLAR(0x20007fff, // Limit
354 Mpu::WBWARA_index) // Attribute index - Write-Back, Write-Allocate, Read-allocate
355 },
356 {
357 // DTCM (S)
358 ARM_MPU_RBAR(0x30000000, // Base
359 ARM_MPU_SH_NON, // Non-shareable
360 0, // Read-Write
361 1, // Non-Privileged
362 1), // eXecute Never enabled
363 ARM_MPU_RLAR(0x30007fff, // Limit
364 Mpu::WBWARA_index) // Attribute index - Write-Back, Write-Allocate, Read-allocate
365 },
366 {
367 // FPGA DATA SRAM; BRAM (NS)
368 ARM_MPU_RBAR(0x01000000, // Base
369 ARM_MPU_SH_NON, // Non-shareable
370 0, // Read-Write
371 1, // Non-Privileged
372 0), // eXecute Never disabled
373 ARM_MPU_RLAR(0x011fffff, // Limit
374 Mpu::WBWARA_index) // Attribute index - Write-Back, Write-Allocate, Read-allocate
375 },
376 {
377 // FPGA DATA SRAM; BRAM (S)
378 ARM_MPU_RBAR(0x11000000, // Base
379 ARM_MPU_SH_NON, // Non-shareable
380 0, // Read-Write
381 1, // Non-Privileged
382 0), // eXecute Never disabled
383 ARM_MPU_RLAR(0x111fffff, // Limit
384 Mpu::WBWARA_index) // Attribute index - Write-Back, Write-Allocate, Read-allocate
385 },
386 {
387 // SSE-300 internal SRAM (NS)
388 ARM_MPU_RBAR(0x21000000, // Base
389 ARM_MPU_SH_NON, // Non-shareable
390 0, // Read-Write
391 1, // Non-Privileged
392 0), // eXecute Never disabled
393 ARM_MPU_RLAR(0x213fffff, // Limit
Kristofer Jonsson01c32d42022-10-18 11:34:23 +0200394 Mpu::WTWARA_index) // Attribute index - Write-Through, Write-Allocate, Read-allocate
Kristofer Jonsson93175812022-04-21 19:27:11 +0200395 },
396 {
397 // SSE-300 internal SRAM (S)
398 ARM_MPU_RBAR(0x31000000, // Base
399 ARM_MPU_SH_NON, // Non-shareable
400 0, // Read-Write
401 1, // Non-Privileged
402 0), // eXecute Never disabled
403 ARM_MPU_RLAR(0x313fffff, // Limit
Kristofer Jonsson01c32d42022-10-18 11:34:23 +0200404 Mpu::WTWARA_index) // Attribute index - Write-Through, Write-Allocate, Read-allocate
Kristofer Jonsson93175812022-04-21 19:27:11 +0200405 },
406 {
407 // DDR (NS)
408 ARM_MPU_RBAR(0x60000000, // Base
409 ARM_MPU_SH_NON, // Non-shareable
410 0, // Read-Write
411 1, // Non-Privileged
412 1), // eXecute Never enabled
413 ARM_MPU_RLAR(0x6fffffff, // Limit
414 Mpu::WBWARA_index) // Attribute index - Write-Back, Write-Allocate, Read-allocate
415 },
416 {
417 // DDR (S)
418 ARM_MPU_RBAR(0x70000000, // Base
419 ARM_MPU_SH_NON, // Non-shareable
420 0, // Read-Write
421 1, // Non-Privileged
422 1), // eXecute Never enabled
423 ARM_MPU_RLAR(0x7fffffff, // Limit
424 Mpu::WBWARA_index) // Attribute index - Write-Back, Write-Allocate, Read-allocate
425 }};
426
427 // Setup MPU configuration
428 Mpu::loadAndEnableConfig(&mpuConfig[0], mpuConfig.size());
429
430#if defined(CPU_CACHE_ENABLE) && defined(__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U)
431 SCB_EnableICache();
432 SCB_EnableDCache();
433#endif
434}
435
436} // namespace EthosU