Update handling of soft reset

Change-Id: Ia22b2934b4c85e3c480931c8b92608365351a877
diff --git a/include/ethosu_device.h b/include/ethosu_device.h
index dd34201..eff9054 100644
--- a/include/ethosu_device.h
+++ b/include/ethosu_device.h
@@ -55,7 +55,7 @@
 struct ethosu_device
 {
     volatile uint32_t *base_address;
-    uint32_t reset;
+    uint32_t proto;
     uint32_t pmcr;
     uint32_t pmccntr[2];
     uint32_t pmcnten;
diff --git a/src/ethosu_device.c b/src/ethosu_device.c
index adfdbb1..f8250bc 100644
--- a/src/ethosu_device.c
+++ b/src/ethosu_device.c
@@ -170,6 +170,7 @@
     cmd.clock_q_enable = oldcmd.clock_q_enable;
     cmd.power_q_enable = oldcmd.power_q_enable;
     ethosu_write_reg(dev, NPU_REG_CMD, cmd.word);
+    LOG_DEBUG("CMD=0x%08x\n", cmd.word);
 #else
     UNUSED(dev);
 #endif
@@ -187,23 +188,29 @@
     reset.pending_CPL = dev->privileged ? PRIVILEGE_LEVEL_PRIVILEGED : PRIVILEGE_LEVEL_USER;
     reset.pending_CSL = dev->secure ? SECURITY_LEVEL_SECURE : SECURITY_LEVEL_NON_SECURE;
 
-    prot.word = ethosu_read_reg(dev, NPU_REG_PROT);
-
-    if (prot.active_CPL < reset.pending_CPL && prot.active_CSL > reset.pending_CSL)
-    {
-        LOG_ERR("Failed to reset NPU\n");
-        // Register access not permitted
-        return ETHOSU_GENERIC_FAILURE;
-    }
-
     // Reset and set security level
+    LOG_INFO("Soft reset NPU\n");
     ethosu_write_reg(dev, NPU_REG_RESET, reset.word);
 
     // Wait for reset to complete
     return_code = ethosu_wait_for_reset(dev);
+    if (return_code != ETHOSU_SUCCESS)
+    {
+        LOG_ERR("Soft reset timed out\n");
+        return return_code;
+    }
+
+    // Verify that NPU has switched security state and privilege level
+    prot.word = ethosu_read_reg(dev, NPU_REG_PROT);
+    if (prot.active_CPL != reset.pending_CPL || prot.active_CSL != reset.pending_CSL)
+    {
+        LOG_ERR("Failed to switch security state and privilege level\n");
+        // Register access not permitted
+        return ETHOSU_GENERIC_FAILURE;
+    }
 
     // Save the prot register
-    dev->reset = ethosu_read_reg(dev, NPU_REG_PROT);
+    dev->proto = ethosu_read_reg(dev, NPU_REG_PROT);
 
     // Soft reset will clear the PMU configuration and counters. The shadow PMU counters
     // are cleared by saving the PMU counters to ram, which will read back zeros.
@@ -277,6 +284,7 @@
     }
 #if !defined(ARM_NPU_STUB)
     ethosu_write_reg(dev, NPU_REG_QCONFIG, memory_type);
+    LOG_DEBUG("QCONFIG=0x%08x\n", memory_type);
 #else
     // NPU stubbed
     UNUSED(dev);
@@ -324,6 +332,7 @@
     axi_limit0.max_outstanding_write_m1 = max_writes - 1;
 
     ethosu_write_reg(dev, NPU_REG_AXI_LIMIT0, axi_limit0.word);
+    LOG_DEBUG("AXI_LIMIT0=0x%08x\n", axi_limit0.word);
 #else
     // NPU stubbed
     UNUSED(dev);
@@ -351,6 +360,7 @@
     axi_limit1.max_outstanding_write_m1 = max_writes - 1;
 
     ethosu_write_reg(dev, NPU_REG_AXI_LIMIT1, axi_limit1.word);
+    LOG_DEBUG("AXI_LIMIT1=0x%08x\n", axi_limit1.word);
 #else
     // NPU stubbed
     UNUSED(dev);
@@ -378,6 +388,7 @@
     axi_limit2.max_outstanding_write_m1 = max_writes - 1;
 
     ethosu_write_reg(dev, NPU_REG_AXI_LIMIT2, axi_limit2.word);
+    LOG_DEBUG("AXI_LIMIT2=0x%08x\n", axi_limit2.word);
 #else
     // NPU stubbed
     UNUSED(dev);
@@ -405,6 +416,7 @@
     axi_limit3.max_outstanding_write_m1 = max_writes - 1;
 
     ethosu_write_reg(dev, NPU_REG_AXI_LIMIT3, axi_limit3.word);
+    LOG_DEBUG("AXI_LIMIT3=0x%08x\n", axi_limit3.word);
 #else
     // NPU stubbed
     UNUSED(dev);
@@ -479,6 +491,7 @@
     cmd.power_q_enable    = oldcmd.power_q_enable;
     cmd.clear_irq_history = irq_history_clear_mask;
     ethosu_write_reg(dev, NPU_REG_CMD, cmd.word);
+    LOG_DEBUG("CMD=0x%08x\n", cmd.word);
 #else
     UNUSED(dev);
     UNUSED(irq_history_clear_mask);
@@ -498,6 +511,7 @@
     cmd.clock_q_enable              = oldcmd.clock_q_enable;
     cmd.power_q_enable              = oldcmd.power_q_enable;
     ethosu_write_reg(dev, NPU_REG_CMD, cmd.word);
+    LOG_DEBUG("CMD=0x%08x\n", cmd.word);
 #else
     UNUSED(dev);
 #endif
@@ -537,6 +551,7 @@
     cmd.clock_q_enable = clock_q;
     cmd.power_q_enable = power_q;
     ethosu_write_reg(dev, NPU_REG_CMD, cmd.word);
+    LOG_DEBUG("CMD=0x%08x\n", cmd.word);
 #else
     UNUSED(dev);
     UNUSED(clock_q);
diff --git a/src/ethosu_driver.c b/src/ethosu_driver.c
index 3c9c55b..3b6ebcf 100644
--- a/src/ethosu_driver.c
+++ b/src/ethosu_driver.c
@@ -149,7 +149,7 @@
  ******************************************************************************/
 
 struct ethosu_driver ethosu_drv = {
-    .dev = {.base_address = NULL, .reset = 0, .pmccntr = {0}, .pmu_evcntr = {0, 0, 0, 0}, .pmu_evtypr = {0, 0, 0, 0}},
+    .dev = {.base_address = NULL, .proto = 0, .pmccntr = {0}, .pmu_evcntr = {0, 0, 0, 0}, .pmu_evtypr = {0, 0, 0, 0}},
     .abort_inference = false,
     .status_error    = false};
 
@@ -356,13 +356,15 @@
         *fast_memory = ethosu_drv.fast_memory;
     }
 
-    if (ethosu_drv.dev.reset != ethosu_read_reg(&ethosu_drv.dev, NPU_REG_PROT))
+    // Only soft reset if securty state or privilege level needs changing
+    if (ethosu_drv.dev.proto != ethosu_read_reg(&ethosu_drv.dev, NPU_REG_PROT))
     {
         if (ETHOSU_SUCCESS != ethosu_soft_reset(&ethosu_drv.dev))
         {
             return -1;
         }
     }
+
     ethosu_drv.status_error = false;
     ethosu_set_clock_and_power(&ethosu_drv.dev, ETHOSU_CLOCK_Q_ENABLE, ETHOSU_POWER_Q_DISABLE);
     ethosu_restore_pmu_config(&ethosu_drv.dev);
@@ -575,8 +577,10 @@
                                  const size_t *base_addr_size,
                                  const int num_base_addr)
 {
-    uint32_t qread     = 0;
-    uint32_t cms_bytes = cms_length * BYTES_IN_32_BITS;
+    uint32_t qread           = 0;
+    uint32_t cms_bytes       = cms_length * BYTES_IN_32_BITS;
+    ptrdiff_t cmd_stream_ptr = (ptrdiff_t)cmd_stream;
+
     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))
@@ -594,10 +598,12 @@
             base_addr_invalid = true;
         }
     }
+
     if (base_addr_invalid)
     {
         return -1;
     }
+
     npu_axi_init(drv);
 
     /* Flush the cache if available on our CPU.
@@ -608,7 +614,7 @@
 
     if (base_addr_size != NULL)
     {
-        ethosu_flush_dcache((uint32_t *)cmd_stream, cms_bytes);
+        ethosu_flush_dcache((uint32_t *)cmd_stream_ptr, cms_bytes);
         for (int i = 0; i < num_base_addr; i++)
         {
             ethosu_flush_dcache((uint32_t *)base_addr[i], base_addr_size[i]);