/* * Copyright (c) 2020-2021 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 #endif #include "mpu.hpp" #include #include "uart.h" #include #include #include #include using namespace EthosU; /**************************************************************************** * Defines ****************************************************************************/ #define ETHOSU_BASE_ADDRESS 0x48102000 #define ETHOSU_IRQ 56 #define ETHOSU0_TA0_BASE_ADDRESS 0x48103000 #define ETHOSU0_TA1_BASE_ADDRESS 0x48103200 /**************************************************************************** * 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 #ifdef ETHOSU struct ethosu_driver *ethosu0_driver = ðosu_drv; #endif static uintptr_t ethosu_ta_base_addrs[ETHOSU_NPU_COUNT][ETHOSU_NPU_TA_COUNT] = { {ETHOSU0_TA0_BASE_ADDRESS, ETHOSU0_TA1_BASE_ADDRESS}}; struct timing_adapter ethosu_ta[ETHOSU_NPU_COUNT][ETHOSU_NPU_TA_COUNT]; /**************************************************************************** * 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(ethosu0_driver); } #endif } // namespace namespace EthosU { void targetSetup() { // Initialize UART driver uart_init(); // Initialize timing adapter(s) for (int i = 0; i < ETHOSU_NPU_COUNT; i++) { for (int j = 0; j < ETHOSU_NPU_TA_COUNT; j++) { if (ta_init(ðosu_ta[i][j], ethosu_ta_base_addrs[i][j])) { printf("Failed to initialize timing-adapter %d for NPU %d\n", j, i); } } } #ifdef ETHOSU // Initialize Ethos-U NPU driver if (ethosu_init(ethosu0_driver, reinterpret_cast(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(ETHOSU_IRQ), (uint32_t)ðosuIrqHandler); NVIC_EnableIRQ(static_cast(ETHOSU_IRQ)); #endif // MPU setup const std::vector mpuConfig = { { // ITCM (NS) ARM_MPU_RBAR(0x00000000, // Base ARM_MPU_SH_NON, // Non-shareable 1, // Read-Only 1, // Non-Privileged 0), // eXecute Never disabled ARM_MPU_RLAR(0x0007ffff, // Limit Mpu::WTRA_index) // Attribute index - Write-Through, Read-allocate }, { // ITCM (S) ARM_MPU_RBAR(0x10000000, // Base ARM_MPU_SH_NON, // Non-shareable 1, // Read-Only 1, // Non-Privileged 0), // eXecute Never disabled ARM_MPU_RLAR(0x1007ffff, // Limit Mpu::WTRA_index) // Attribute index - Write-Through, Read-allocate }, { // FPGA DATA SRAM; BRAM (NS) ARM_MPU_RBAR(0x01000000, // Base ARM_MPU_SH_NON, // Non-shareable 0, // Read-Write 1, // Non-Privileged 0), // eXecute Never disabled ARM_MPU_RLAR(0x011fffff, // Limit Mpu::WBWARA_index) // Attribute index - Write-Back, Write-Allocate, Read-allocate }, { // FPGA DATA SRAM; BRAM (S) ARM_MPU_RBAR(0x11000000, // Base ARM_MPU_SH_NON, // Non-shareable 0, // Read-Write 1, // Non-Privileged 0), // eXecute Never disabled ARM_MPU_RLAR(0x111fffff, // Limit Mpu::WBWARA_index) // Attribute index - Write-Back, Write-Allocate, Read-allocate }, { // DTCM (NS) ARM_MPU_RBAR(0x20000000, // Base ARM_MPU_SH_NON, // Non-shareable 0, // Read-Write 1, // Non-Privileged 1), // eXecute Never enabled ARM_MPU_RLAR(0x2007ffff, // Limit Mpu::WBWARA_index) // Attribute index - Write-Back, Write-Allocate, Read-allocate }, { // DTCM (S) ARM_MPU_RBAR(0x30000000, // Base ARM_MPU_SH_NON, // Non-shareable 0, // Read-Write 1, // Non-Privileged 1), // eXecute Never enabled ARM_MPU_RLAR(0x3007ffff, // Limit Mpu::WBWARA_index) // Attribute index - Write-Back, Write-Allocate, Read-allocate }, { // SSE-300 internal SRAM (NS) ARM_MPU_RBAR(0x21000000, // Base ARM_MPU_SH_NON, // Non-shareable 0, // Read-Write 1, // Non-Privileged 1), // eXecute Never enabled ARM_MPU_RLAR(0x213fffff, // Limit Mpu::WBWARA_index) // Attribute index - Write-Back, Write-Allocate, Read-allocate }, { // SSE-300 internal SRAM (S) ARM_MPU_RBAR(0x31000000, // Base ARM_MPU_SH_NON, // Non-shareable 0, // Read-Write 1, // Non-Privileged 1), // eXecute Never enabled ARM_MPU_RLAR(0x313fffff, // Limit Mpu::WBWARA_index) // Attribute index - Write-Back, Write-Allocate, Read-allocate }, { // DDR (NS) ARM_MPU_RBAR(0x60000000, // Base ARM_MPU_SH_NON, // Non-shareable 0, // Read-Write 1, // Non-Privileged 1), // eXecute Never enabled ARM_MPU_RLAR(0x6fffffff, // Limit Mpu::WBWARA_index) // Attribute index - Write-Back, Write-Allocate, Read-allocate }, { // DDR (S) ARM_MPU_RBAR(0x70000000, // Base ARM_MPU_SH_NON, // Non-shareable 0, // Read-Write 1, // Non-Privileged 1), // eXecute Never enabled ARM_MPU_RLAR(0x7fffffff, // Limit Mpu::WBWARA_index) // Attribute index - Write-Back, Write-Allocate, Read-allocate }}; // Setup MPU configuration Mpu::loadAndEnableConfig(&mpuConfig[0], mpuConfig.size()); #if defined(CPU_CACHE_ENABLE) && defined(__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) SCB_EnableICache(); SCB_EnableDCache(); #endif } } // namespace EthosU