blob: 7c902d2184ee48572d20badf67b4c083c4d5bdfd [file] [log] [blame]
/*
* Copyright (c) 2020 Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/****************************************************************************
* Includes
****************************************************************************/
#include "target.hpp"
#ifdef ETHOSU
#include <ethosu_driver.h>
#endif
#include "uart.h"
#include <stdio.h>
#include <stdlib.h>
#include <inttypes.h>
using namespace EthosU;
/****************************************************************************
* Defines
****************************************************************************/
#define ETHOSU_BASE_ADDRESS 0x48102000
#define ETHOSU_IRQ 56
/****************************************************************************
* Variables
****************************************************************************/
#if defined(ETHOSU_FAST_MEMORY_SIZE) && ETHOSU_FAST_MEMORY_SIZE > 0
__attribute__((aligned(16), section(".bss.ethosu_scratch"))) uint8_t ethosu_scratch[ETHOSU_FAST_MEMORY_SIZE];
#else
#define ethosu_scratch 0
#define ETHOSU_FAST_MEMORY_SIZE 0
#endif
/****************************************************************************
* Cache maintenance
****************************************************************************/
#if defined(CPU_CACHE_ENABLE) && defined(__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U)
extern "C" {
void ethosu_flush_dcache(uint32_t *p, size_t bytes) {
if (p)
SCB_CleanDCache_by_Addr(p, bytes);
else
SCB_CleanDCache();
}
void ethosu_invalidate_dcache(uint32_t *p, size_t bytes) {
if (p)
SCB_InvalidateDCache_by_Addr(p, bytes);
else
SCB_InvalidateDCache();
}
}
#endif
/****************************************************************************
* Init
****************************************************************************/
namespace {
extern "C" {
struct ExcContext {
uint32_t r0;
uint32_t r1;
uint32_t r2;
uint32_t r3;
uint32_t r12;
uint32_t lr;
uint32_t pc;
uint32_t xPsr;
};
void HardFault_Handler() {
int irq;
struct ExcContext *e;
uint32_t sp;
asm volatile("mrs %0, ipsr \n" // Read IPSR (Exceptio number)
"sub %0, #16 \n" // Get it into IRQn_Type range
"tst lr, #4 \n" // Select the stack which was in use
"ite eq \n"
"mrseq %1, msp \n"
"mrsne %1, psp \n"
"mov %2, sp \n"
: "=r"(irq), "=r"(e), "=r"(sp));
printf("Hard fault. irq=%d, pc=0x%08" PRIx32 ", lr=0x%08" PRIx32 ", xpsr=0x%08" PRIx32 ", sp=0x%08" PRIx32 "\n",
irq,
e->pc,
e->lr,
e->xPsr,
sp);
printf(
"%11s cfsr=0x%08" PRIx32 " bfar=0x%08" PRIx32 " mmfar=0x%08" PRIx32 "\n", "", SCB->CFSR, SCB->BFAR, SCB->MMFAR);
exit(1);
}
}
#ifdef ETHOSU
void ethosuIrqHandler() {
ethosu_irq_handler();
}
#endif
} // namespace
namespace EthosU {
void targetSetup() {
// Initialize UART driver
uart_init();
#ifdef ETHOSU
// Initialize Ethos-U NPU driver
if (ethosu_init_v3(reinterpret_cast<void *>(ETHOSU_BASE_ADDRESS), ethosu_scratch, ETHOSU_FAST_MEMORY_SIZE, 1, 1)) {
printf("Failed to initialize NPU.\n");
return;
}
/* Assumes SCB->VTOR point to RW memory */
NVIC_SetVector(static_cast<IRQn_Type>(ETHOSU_IRQ), (uint32_t)&ethosuIrqHandler);
NVIC_EnableIRQ(static_cast<IRQn_Type>(ETHOSU_IRQ));
#endif
}
} // namespace EthosU