From 125429a1c089775b05d4d13739ee7fc72285079f Mon Sep 17 00:00:00 2001 From: Kristofer Jonsson Date: Thu, 20 Aug 2020 16:52:23 +0200 Subject: Base pointer offset and soft reset Allow user to define a base pointer offset, if the CPU and the NPU have address spaces offseted from each other. Soft reset NPU before every inference. Added log prints. Change-Id: I98a746d20dc780fefa23ad68816f5ba2ba2e6c6e --- src/ethosu_config.h | 8 ++++++++ src/ethosu_device.c | 34 +++++++++++++++++----------------- src/ethosu_driver.c | 14 +++++++++++++- 3 files changed, 38 insertions(+), 18 deletions(-) (limited to 'src') diff --git a/src/ethosu_config.h b/src/ethosu_config.h index 07eb824..91fe660 100644 --- a/src/ethosu_config.h +++ b/src/ethosu_config.h @@ -108,6 +108,14 @@ #define AXI_LIMIT3_MAX_OUTSTANDING_WRITES 16 #endif +/* + * Address offset between the CPU and the NPU. The offset is + * applied to the QBASE and BASEP registers. + */ +#ifndef BASE_POINTER_OFFSET +#define BASE_POINTER_OFFSET 0 +#endif + #ifdef PMU_AUTOINIT /* * Register control diff --git a/src/ethosu_device.c b/src/ethosu_device.c index 60fc243..404a0e7 100644 --- a/src/ethosu_device.c +++ b/src/ethosu_device.c @@ -17,6 +17,7 @@ */ #include "ethosu_device.h" #include "ethosu_common.h" +#include "ethosu_config.h" #include #include @@ -26,6 +27,9 @@ #define REG_OFFSET 4 #define BYTES_1KB 1024 +#define ADDRESS_BITS 48 +#define ADDRESS_MASK ((1ull << ADDRESS_BITS) - 1) + #if defined(ARM_NPU_STUB) static uint32_t stream_length = 0; #endif @@ -93,29 +97,24 @@ enum ethosu_error_codes ethosu_run_command_stream(struct ethosu_device *dev, enum ethosu_error_codes ret_code = ETHOSU_SUCCESS; #if !defined(ARM_NPU_STUB) - uint32_t qbase0; - uint32_t qbase1; - uint32_t qsize; - uint32_t *reg_basep; - int num_base_reg; - ASSERT(num_base_addr <= ETHOSU_DRIVER_BASEP_INDEXES); - qbase0 = ((uint64_t)cmd_stream_ptr) & MASK_0_31_BITS; - qbase1 = (((uint64_t)cmd_stream_ptr) & MASK_32_47_BITS) >> 32; - qsize = cms_length; - num_base_reg = num_base_addr * 2; - reg_basep = (uint32_t *)base_addr; + uint64_t qbase = (uint64_t)cmd_stream_ptr + BASE_POINTER_OFFSET; + ASSERT(qbase <= ADDRESS_MASK); + LOG_DEBUG("QBASE=0x%016llx, QSIZE=%u, base_pointer_offset=0x%08x\n", qbase, cms_length, BASE_POINTER_OFFSET); + ethosu_write_reg(dev, NPU_REG_QBASE0, qbase & 0xffffffff); + ethosu_write_reg(dev, NPU_REG_QBASE1, qbase >> 32); + ethosu_write_reg(dev, NPU_REG_QSIZE, cms_length); - for (int i = 0; i < num_base_reg; i++) + for (int i = 0; i < num_base_addr; i++) { - ethosu_write_reg(dev, NPU_REG_BASEP0 + (i * BASEP_OFFSET), reg_basep[i]); + uint64_t addr = base_addr[i] + BASE_POINTER_OFFSET; + ASSERT(addr <= ADDRESS_MASK); + LOG_DEBUG("BASEP%d=0x%016llx\n", i, addr); + ethosu_write_reg(dev, NPU_REG_BASEP0 + (2 * i) * BASEP_OFFSET, addr & 0xffffffff); + ethosu_write_reg(dev, NPU_REG_BASEP0 + (2 * i + 1) * BASEP_OFFSET, addr >> 32); } - ethosu_write_reg(dev, NPU_REG_QBASE0, qbase0); - ethosu_write_reg(dev, NPU_REG_QBASE1, qbase1); - ethosu_write_reg(dev, NPU_REG_QSIZE, qsize); - ret_code = ethosu_set_command_run(dev); #else // NPU stubbed @@ -282,6 +281,7 @@ enum ethosu_error_codes ethosu_set_regioncfg(struct ethosu_device *dev, regioncfg.word &= ~(0x3 << (2 * region)); regioncfg.word |= (memory_type & 0x3) << (2 * region); ethosu_write_reg(dev, NPU_REG_REGIONCFG, regioncfg.word); + LOG_DEBUG("REGIONCFG%u=0x%08x\n", region, regioncfg.word); #else // NPU stubbed UNUSED(dev); diff --git a/src/ethosu_driver.c b/src/ethosu_driver.c index 9d74980..f47d3f2 100644 --- a/src/ethosu_driver.c +++ b/src/ethosu_driver.c @@ -43,10 +43,20 @@ static volatile bool irq_triggered = false; void ethosu_irq_handler(void) { uint8_t irq_raised = 0; + + LOG_DEBUG("Interrupt. status=0x%08x, qread=%d\n", + ethosu_read_reg(ðosu_drv.dev, NPU_REG_STATUS), + ethosu_read_reg(ðosu_drv.dev, NPU_REG_QREAD)); + + // Verify that interrupt has been raised (void)ethosu_is_irq_raised(ðosu_drv.dev, &irq_raised); ASSERT(irq_raised == 1); irq_triggered = true; + + // Clear interrupt (void)ethosu_clear_irq_status(ðosu_drv.dev); + + // Verify that interrupt has been successfully cleard (void)ethosu_is_irq_raised(ðosu_drv.dev, &irq_raised); ASSERT(irq_raised == 0); } @@ -280,8 +290,10 @@ int ethosu_invoke(const void *custom_data_ptr, } int custom_data_32bit_size = (custom_data_size / BYTES_IN_32_BITS - CUSTOM_OPTION_LENGTH_32_BIT_WORD); + ethosu_soft_reset(ðosu_drv.dev); ethosu_set_clock_and_power(ðosu_drv.dev, ETHOSU_CLOCK_Q_ENABLE, ETHOSU_POWER_Q_DISABLE); ethosu_restore_pmu_config(ðosu_drv.dev); + while (data_ptr < (data_start_ptr + custom_data_32bit_size)) { int ret = 0; @@ -464,7 +476,7 @@ static int handle_command_stream(struct ethosu_driver *drv, { uint32_t qread = 0; uint32_t cms_bytes = cms_length * BYTES_IN_32_BITS; - LOG_INFO("handle_command_stream cms_length %d\n", cms_length); + LOG_INFO("handle_command_stream: cmd_stream=%p, cms_length %d\n", cmd_stream, cms_length); if (0 != ((ptrdiff_t)cmd_stream & MASK_16_BYTE_ALIGN)) { -- cgit v1.2.1