/*
 * Copyright (c) 2019-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 "ethosu_driver.h"
#include "ethosu_common.h"
#include "ethosu_config.h"
#include "ethosu_device.h"

#include <assert.h>
#include <cmsis_compiler.h>
#include <inttypes.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>

/******************************************************************************
 * Defines
 ******************************************************************************/

#define MACS_PER_CYCLE_LOG2_MASK 0x000F
#define SHRAM_SIZE_MASK 0xFF00
#define SHRAM_SIZE_RIGHT_SHIFT 8
#define BYTES_IN_32_BITS 4
#define CUSTOM_OPTION_LENGTH_32_BIT_WORD 1
#define DRIVER_ACTION_LENGTH_32_BIT_WORD 1
#define OPTIMIZER_CONFIG_LENGTH_32_BIT_WORD 2
#define ETHOSU_FOURCC ('1' << 24 | 'P' << 16 | 'O' << 8 | 'C') // "Custom Operator Payload 1"
#define APB_START_ADDR_MASK 0x0FFF
#define APB_NUM_REG_BIT_SHIFT 12
#define BYTES_1KB 1024
#define PRODUCT_MAJOR_ETHOSU55 (4)
#define MASK_16_BYTE_ALIGN (0xF)
#define FAST_MEMORY_BASE_ADDR_INDEX 2

/******************************************************************************
 * Types
 ******************************************************************************/

// Driver actions
enum DRIVER_ACTION_e
{
    RESERVED         = 0,
    OPTIMIZER_CONFIG = 1,
    COMMAND_STREAM   = 2,
    READ_APB_REG     = 3,
    DUMP_SHRAM       = 4,
    NOP              = 5,
};

// Custom data struct
struct custom_data_s
{
    union
    {
        // Driver action data
        struct
        {
            // Driver action command (valid values in DRIVER_ACTION_e)
            uint8_t driver_action_command;

            // reserved
            uint8_t reserved;

            // Driver action data
            union
            {
                // DA_CMD_OPT_CFG
                struct
                {
                    uint16_t rel_nbr : 4;
                    uint16_t patch_nbr : 4;
                    uint16_t opt_cfg_reserved : 8;
                };

                // DA_CMD_CMSTRM
                struct
                {
                    uint16_t length;
                };

                // DA_CMD_READAPB
                struct
                {
                    uint16_t start_address : 12;
                    uint16_t nbr_reg_minus1 : 4;
                };

                uint16_t driver_action_data;
            };
        };

        uint32_t word;
    };
};

// optimizer config struct
struct opt_cfg_s
{
    struct custom_data_s da_data;
    union
    {
        struct
        {
            uint32_t macs_per_cc : 4;
            uint32_t cmd_stream_version : 4;
            uint32_t shram_size : 8;
            uint32_t reserved0 : 11;
            uint32_t custom_dma : 1;
            uint32_t product : 4;
        };
        uint32_t npu_cfg;
    };
    union
    {
        struct
        {
            uint32_t version_status : 4;
            uint32_t version_minor : 4;
            uint32_t version_major : 4;
            uint32_t product_major : 4;
            uint32_t arch_patch_rev : 4;
            uint32_t arch_minor_rev : 8;
            uint32_t arch_major_rev : 4;
        };
        uint32_t ethosu_id;
    };
};

/******************************************************************************
 * Functions
 ******************************************************************************/

struct ethosu_driver ethosu_drv = {
    .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,
    .dev_power_always_on = false};

// Registered drivers linked list HEAD
static struct ethosu_driver *registered_drivers = NULL;

/*
 * Following section handles the minimal sempahore and mutex implementation in case of baremetal applications.
 * Weak symbols will be overwritten by RTOS definitions and implement true thread-safety. (Done in application layer)
 */

// Baremetal sempahore implementation
struct ethosu_semaphore_t
{
    int count;
};

// Minimal needed declaration to allow baremetal functionality.
static void *ethosu_mutex;
static void *ethosu_semaphore;

void *__attribute__((weak)) ethosu_mutex_create(void) {}

void __attribute__((weak)) ethosu_mutex_lock(void *mutex) {}

void __attribute__((weak)) ethosu_mutex_unlock(void *mutex) {}

// Baremetal implementation of creating a semaphore
void *__attribute__((weak)) ethosu_semaphore_create(void)
{
    struct ethosu_semaphore_t *sem = malloc(sizeof(*sem));
    sem->count                     = 1;
    return sem;
}

// Baremetal simulation of waiting/sleeping for and then taking a semaphore using intrisics
void __attribute__((weak)) ethosu_semaphore_take(void *sem)
{
    struct ethosu_semaphore_t *s = sem;
    while (s->count <= 0)
    {
        __WFE();
    }
    s->count--;
}

// Baremetal simulation of giving a semaphore and waking up processes using intrinsics
void __attribute__((weak)) ethosu_semaphore_give(void *sem)
{
    struct ethosu_semaphore_t *s = sem;
    s->count++;
    __SEV();
}
// <--- End of semaphore and mutex implementations

static int ethosu_soft_reset_and_restore(struct ethosu_driver *drv);

void __attribute__((weak)) ethosu_irq_handler_v2(struct ethosu_driver *drv)
{
    uint8_t irq_raised = 0;

    LOG_DEBUG("Interrupt. status=0x%08x, qread=%d\n",
              ethosu_read_reg(&drv->dev, NPU_REG_STATUS),
              ethosu_read_reg(&drv->dev, NPU_REG_QREAD));

    // Verify that interrupt has been raised
    (void)ethosu_is_irq_raised(&drv->dev, &irq_raised);
    ASSERT(irq_raised == 1);
    drv->irq_triggered = true;

    // Clear interrupt
    (void)ethosu_clear_irq_status(&drv->dev);

    // Verify that interrupt has been successfully cleared
    (void)ethosu_is_irq_raised(&drv->dev, &irq_raised);
    ASSERT(irq_raised == 0);

    if (ethosu_status_has_error(&drv->dev))
    {
        ethosu_soft_reset_and_restore(drv);
        drv->status_error = true;
    }

    ethosu_semaphore_give(drv->semaphore);
}

static inline void wait_for_irq(struct ethosu_driver *drv)
{
    while (1)
    {
        if (drv->irq_triggered || drv->abort_inference)
        {
            drv->irq_triggered = false;
            break;
        }

        ethosu_semaphore_take(drv->semaphore);
    }
}

static int handle_optimizer_config(struct ethosu_driver *drv, struct opt_cfg_s *opt_cfg_p);
static int handle_command_stream(struct ethosu_driver *drv,
                                 const uint8_t *cmd_stream,
                                 const int cms_length,
                                 const uint64_t *base_addr,
                                 const size_t *base_addr_size,
                                 const int num_base_addr);
static int read_apb_reg(struct ethosu_driver *drv, uint16_t);
static int dump_shram(struct ethosu_driver *drv);
static void dump_npu_register(struct ethosu_driver *drv, int npu_reg, int npu_reg_end);
static void dump_command_stream(const uint32_t *cmd_stream, const int cms_length, int qread);
static void npu_axi_init(struct ethosu_driver *drv);
static struct ethosu_driver *ethosu_find_and_reserve_driver(void);

int ethosu_init_v4(struct ethosu_driver *drv,
                   const void *base_address,
                   const void *fast_memory,
                   const size_t fast_memory_size,
                   uint32_t secure_enable,
                   uint32_t privilege_enable)
{
    int return_code = 0;

    LOG_INFO("%s. base_address=%p, fast_memory=%p, fast_memory_size=%zu, secure=%" PRIu32 ", privileged=%" PRIu32 "\n",
             __FUNCTION__,
             base_address,
             fast_memory,
             fast_memory_size,
             secure_enable,
             privilege_enable);

    if (!ethosu_mutex)
    {
        ethosu_mutex = ethosu_mutex_create();
    }

    if (!ethosu_semaphore)
    {
        ethosu_semaphore = ethosu_semaphore_create();
    }

    ethosu_register_driver(drv);

    drv->fast_memory      = (uint32_t)fast_memory;
    drv->fast_memory_size = fast_memory_size;
    drv->irq_triggered    = false;
    drv->semaphore        = ethosu_semaphore_create();

    if (ETHOSU_SUCCESS != ethosu_dev_init(&drv->dev, base_address, secure_enable, privilege_enable))
    {
        LOG_ERR("Failed in ethosu_dev_init");
        return -1;
    }

    if (ETHOSU_SUCCESS !=
        set_clock_and_power_request(drv, ETHOSU_INFERENCE_REQUEST, ETHOSU_CLOCK_Q_DISABLE, ETHOSU_POWER_Q_DISABLE))
    {
        LOG_ERR("Failed to disable clock-q & power-q for Ethos-U\n");
        return -1;
    }

    if (ETHOSU_SUCCESS != ethosu_soft_reset(&drv->dev))
    {
        return -1;
    }

    if (ETHOSU_SUCCESS != ethosu_wait_for_reset(&drv->dev))
    {
        LOG_ERR("Failed reset of Ethos-U\n");
        return -1;
    }

    drv->status_error = false;

    return return_code;
}

int ethosu_get_version_v2(struct ethosu_driver *drv, struct ethosu_version *version)
{
    int return_code = 0;

    if (NULL != version)
    {
        struct ethosu_id id;
        struct ethosu_config cfg;
        (void)ethosu_get_id(&drv->dev, &id);
        (void)ethosu_get_config(&drv->dev, &cfg);

        version->id.version_status      = id.version_status;
        version->id.version_minor       = id.version_minor;
        version->id.version_major       = id.version_major;
        version->id.product_major       = id.product_major;
        version->id.arch_patch_rev      = id.arch_patch_rev;
        version->id.arch_minor_rev      = id.arch_minor_rev;
        version->id.arch_major_rev      = id.arch_major_rev;
        version->id.driver_patch_rev    = ETHOSU_DRIVER_VERSION_PATCH;
        version->id.driver_minor_rev    = ETHOSU_DRIVER_VERSION_MINOR;
        version->id.driver_major_rev    = ETHOSU_DRIVER_VERSION_MAJOR;
        version->cfg.macs_per_cc        = cfg.macs_per_cc;
        version->cfg.cmd_stream_version = cfg.cmd_stream_version;
        version->cfg.shram_size         = cfg.shram_size;
        version->cfg.custom_dma         = cfg.custom_dma;
    }
    else
    {
        return_code = -1;
    }

    return return_code;
}

int ethosu_invoke_v3(struct ethosu_driver *drv,
                     const void *custom_data_ptr,
                     const int custom_data_size,
                     const uint64_t *base_addr,
                     const size_t *base_addr_size,
                     const int num_base_addr)
{
    const struct custom_data_s *data_ptr = custom_data_ptr;
    const struct custom_data_s *data_end = custom_data_ptr + custom_data_size;
    int return_code                      = 0;

    LOG_INFO("%s\n", __FUNCTION__);

    // First word in custom_data_ptr should contain "Custom Operator Payload 1"
    if (data_ptr->word != ETHOSU_FOURCC)
    {
        LOG_ERR("Custom Operator Payload: %" PRIu32 " is not correct, expected %x\n", data_ptr->word, ETHOSU_FOURCC);
        return -1;
    }

    // Custom data length must be a multiple of 32 bits
    if ((custom_data_size % BYTES_IN_32_BITS) != 0)
    {
        LOG_ERR("ethosu_invoke ERROR custom_data_size=0x%x not a multiple of 4\n", custom_data_size);
        return -1;
    }

    ++data_ptr;

    // Adjust base address to fast memory area
    if (drv->fast_memory != 0 && num_base_addr >= FAST_MEMORY_BASE_ADDR_INDEX)
    {
        uint64_t *fast_memory = (uint64_t *)&base_addr[FAST_MEMORY_BASE_ADDR_INDEX];

        if (base_addr_size != NULL && base_addr_size[FAST_MEMORY_BASE_ADDR_INDEX] > drv->fast_memory_size)
        {
            LOG_ERR("Fast memory area too small. fast_memory_size=%u, base_addr_size=%u\n",
                    drv->fast_memory_size,
                    base_addr_size[FAST_MEMORY_BASE_ADDR_INDEX]);
            return -1;
        }

        *fast_memory = drv->fast_memory;
    }

    if (!drv->dev_power_always_on)
    {
        // Only soft reset if securty state or privilege level needs changing
        if (drv->dev.proto != ethosu_read_reg(&drv->dev, NPU_REG_PROT))
        {
            if (ETHOSU_SUCCESS != ethosu_soft_reset(&drv->dev))
            {
                return -1;
            }
        }

        drv->status_error = false;
        set_clock_and_power_request(drv, ETHOSU_INFERENCE_REQUEST, ETHOSU_CLOCK_Q_ENABLE, ETHOSU_POWER_Q_DISABLE);
        ethosu_restore_pmu_config(&drv->dev);
        npu_axi_init(drv);
    }

    drv->status_error = false;

    while (data_ptr < data_end)
    {
        int ret = 0;
        switch (data_ptr->driver_action_command)
        {
        case OPTIMIZER_CONFIG:
            LOG_INFO("ethosu_invoke OPTIMIZER_CONFIG\n");
            struct opt_cfg_s *opt_cfg_p = (struct opt_cfg_s *)data_ptr;

            ret = handle_optimizer_config(drv, opt_cfg_p);
            data_ptr += DRIVER_ACTION_LENGTH_32_BIT_WORD + OPTIMIZER_CONFIG_LENGTH_32_BIT_WORD;
            break;
        case COMMAND_STREAM:
            LOG_INFO("ethosu_invoke COMMAND_STREAM\n");
            void *command_stream = (uint8_t *)(data_ptr) + sizeof(struct custom_data_s);
            int cms_length       = (data_ptr->reserved << 16) | data_ptr->length;

            drv->abort_inference = false;
            // It is safe to clear this flag without atomic, because npu is not running.
            drv->irq_triggered = false;

            ret = handle_command_stream(drv, command_stream, cms_length, base_addr, base_addr_size, num_base_addr);

            if (return_code == -1 && drv->abort_inference)
            {
                uint32_t qread = 0;
                ethosu_get_qread(&drv->dev, &qread);
                LOG_ERR("NPU timeout\n");
                dump_command_stream(command_stream, cms_length, qread);
                dump_npu_register(drv, 0x200, 0x2BF);
                dump_npu_register(drv, 0x800, 0xB3F);
                dump_shram(drv);
            }

            data_ptr += DRIVER_ACTION_LENGTH_32_BIT_WORD + cms_length;
            break;
        case READ_APB_REG:
            LOG_INFO("ethosu_invoke READ_APB_REG\n");
            ret = read_apb_reg(drv, data_ptr->driver_action_data);
            data_ptr += DRIVER_ACTION_LENGTH_32_BIT_WORD;
            break;
        case DUMP_SHRAM:
            LOG_INFO("ethosu_invoke DUMP_SHRAM\n");
            ret = dump_shram(drv);
            data_ptr += DRIVER_ACTION_LENGTH_32_BIT_WORD;
            break;
        case NOP:
            LOG_INFO("ethosu_invoke NOP\n");
            data_ptr += DRIVER_ACTION_LENGTH_32_BIT_WORD;
            break;
        default:
            LOG_ERR("ethosu_invoke UNSUPPORTED driver_action_command %d \n", data_ptr->driver_action_command);
            ret = -1;
            break;
        }
        if (ret != 0)
        {
            return_code = -1;
            break;
        }
    }

    if (!drv->status_error && !drv->dev_power_always_on)
    {
        ethosu_save_pmu_counters(&drv->dev);
        set_clock_and_power_request(drv, ETHOSU_INFERENCE_REQUEST, ETHOSU_CLOCK_Q_ENABLE, ETHOSU_POWER_Q_ENABLE);
    }

    return return_code;
}

void ethosu_abort_v2(struct ethosu_driver *drv)
{
    drv->abort_inference = true;
}

void ethosu_set_power_mode_v2(struct ethosu_driver *drv, bool always_on)
{
    drv->dev_power_always_on = always_on;

    if (always_on)
    {
        npu_axi_init(drv);
    }
}

int ethosu_register_driver(struct ethosu_driver *drv)
{
    // Safeguard check for if driver is already registered
    struct ethosu_driver *cur = registered_drivers;
    while (cur != NULL)
    {
        if (cur == drv)
        {
            LOG_ERR("%s: NPU driver at address %p is already registered.\n", __FUNCTION__, drv);
            return -1;
        }
        cur = cur->next;
    }

    drv->next = registered_drivers;
    // Designate new registered driver HEAD
    registered_drivers = drv;

    LOG_INFO("%s: New NPU driver at address %p is registered.\n", __FUNCTION__, drv);
    return 0;
}

int ethosu_deregister_driver(struct ethosu_driver *drv)
{
    struct ethosu_driver *cur   = registered_drivers;
    struct ethosu_driver **prev = &registered_drivers;

    while (cur != NULL)
    {
        if (cur == drv)
        {
            *prev = cur->next;
            LOG_INFO("%s: NPU driver at address %p is deregistered.\n", __FUNCTION__, drv);
            return 0;
        }

        prev = &cur->next;
        cur  = cur->next;
    }

    LOG_ERR("%s: NPU driver at address %p does not match a registered driver and therefore may not be deregistered.\n",
            __FUNCTION__,
            drv);

    return -1;
}

struct ethosu_driver *ethosu_reserve_driver(void)
{
    struct ethosu_driver *drv = NULL;

    do
    {
        ethosu_mutex_lock(ethosu_mutex);
        drv = ethosu_find_and_reserve_driver();
        ethosu_mutex_unlock(ethosu_mutex);

        if (drv != NULL)
        {
            break;
        }

        LOG_INFO("%s - Waiting for driver \n", __FUNCTION__);
        ethosu_semaphore_take(ethosu_semaphore);

    } while (1);

    return drv;
}

static struct ethosu_driver *ethosu_find_and_reserve_driver(void)
{
    struct ethosu_driver *drv = registered_drivers;

    while (drv != NULL)
    {
        if (!drv->reserved)
        {
            drv->reserved = true;
            LOG_INFO("%s - Driver %p reserved.\n", __FUNCTION__, drv);
            return drv;
        }
        drv = drv->next;
    }

    LOG_INFO("%s: No available drivers.\n", __FUNCTION__, drv);

    return NULL;
}

void ethosu_release_driver(struct ethosu_driver *drv)
{
    ethosu_mutex_lock(ethosu_mutex);
    if (drv != NULL && drv->reserved)
    {
        drv->reserved = false;
        LOG_INFO("%s - Driver %p released\n", __FUNCTION__, drv);
        ethosu_semaphore_give(ethosu_semaphore);
    }
    ethosu_mutex_unlock(ethosu_mutex);
}

static int ethosu_soft_reset_and_restore(struct ethosu_driver *drv)
{

    if (ETHOSU_SUCCESS != ethosu_soft_reset(&drv->dev))
    {
        return -1;
    }

    set_clock_and_power_request(drv, ETHOSU_INFERENCE_REQUEST, ETHOSU_CLOCK_Q_ENABLE, ETHOSU_POWER_Q_DISABLE);

    npu_axi_init(drv);
    ethosu_restore_pmu_config(&drv->dev);

    return 0;
}

enum ethosu_error_codes set_clock_and_power_request(struct ethosu_driver *drv,
                                                    enum ethosu_request_clients client,
                                                    enum ethosu_clock_q_request clock_request,
                                                    enum ethosu_power_q_request power_request)
{
    // Set clock request bit for client
    if (clock_request == ETHOSU_CLOCK_Q_DISABLE)
    {
        drv->clock_request |= (1 << client);
    }
    else
    {
        drv->clock_request &= ~(1 << client);
    }
    // Get current clock request (ENABLE if both PMU and INFERENCE asks for clock request, else DISABLE)
    clock_request = drv->clock_request == 0 ? ETHOSU_CLOCK_Q_ENABLE : ETHOSU_CLOCK_Q_DISABLE;

    // Set power request bit for client
    if (power_request == ETHOSU_CLOCK_Q_DISABLE)
    {
        drv->power_request |= (1 << client);
    }
    else
    {
        drv->power_request &= ~(1 << client);
    }
    // Get current power request (ENABLE if both PMU and INFERENCE asks for power request, else DISABLE)
    power_request = drv->power_request == 0 ? ETHOSU_POWER_Q_ENABLE : ETHOSU_POWER_Q_DISABLE;
    // Set clock and power
    enum ethosu_error_codes ret = ethosu_set_clock_and_power(&drv->dev, clock_request, power_request);

    return ret;
}

static int handle_optimizer_config(struct ethosu_driver *drv, struct opt_cfg_s *opt_cfg_p)
{
    struct ethosu_config cfg;
    struct ethosu_id id;
    int return_code = 0;

    LOG_INFO("handle_optimizer_config:\n");
    LOG_INFO("Optimizer release nbr: %d patch: %d\n", opt_cfg_p->da_data.rel_nbr, opt_cfg_p->da_data.patch_nbr);
    LOG_INFO("Optimizer config cmd_stream_version: %d macs_per_cc: %d shram_size: %d custom_dma: %d\n",
             opt_cfg_p->cmd_stream_version,
             opt_cfg_p->macs_per_cc,
             opt_cfg_p->shram_size,
             opt_cfg_p->custom_dma);
    LOG_INFO("Optimizer config Ethos-U version: %d.%d.%d\n",
             opt_cfg_p->arch_major_rev,
             opt_cfg_p->arch_minor_rev,
             opt_cfg_p->arch_patch_rev);

    (void)ethosu_get_config(&drv->dev, &cfg);
    (void)ethosu_get_id(&drv->dev, &id);
    LOG_INFO("Ethos-U config cmd_stream_version: %" PRIu32 " macs_per_cc: %" PRIu32 " shram_size: %" PRIu32
             " custom_dma: %" PRIu32 "\n",
             cfg.cmd_stream_version,
             cfg.macs_per_cc,
             cfg.shram_size,
             cfg.custom_dma);
    LOG_INFO("Ethos-U version: %" PRIu32 ".%" PRIu32 ".%" PRIu32 "\n",
             id.arch_major_rev,
             id.arch_minor_rev,
             id.arch_patch_rev);

    if ((cfg.macs_per_cc != opt_cfg_p->macs_per_cc) || (cfg.shram_size != opt_cfg_p->shram_size) ||
        (cfg.cmd_stream_version != opt_cfg_p->cmd_stream_version) || (!cfg.custom_dma && opt_cfg_p->custom_dma))
    {
        if (cfg.macs_per_cc != opt_cfg_p->macs_per_cc)
        {
            LOG_ERR("NPU config mismatch: npu.macs_per_cc=%" PRIu32 " optimizer.macs_per_cc=%d\n",
                    cfg.macs_per_cc,
                    opt_cfg_p->macs_per_cc);
        }
        if (cfg.shram_size != opt_cfg_p->shram_size)
        {
            LOG_ERR("NPU config mismatch: npu.shram_size=%" PRIu32 " optimizer.shram_size=%d\n",
                    cfg.shram_size,
                    opt_cfg_p->shram_size);
        }
        if (cfg.cmd_stream_version != opt_cfg_p->cmd_stream_version)
        {
            LOG_ERR("NPU config mismatch: npu.cmd_stream_version=%" PRIu32 " optimizer.cmd_stream_version=%d\n",
                    cfg.cmd_stream_version,
                    opt_cfg_p->cmd_stream_version);
        }
        if (!cfg.custom_dma && opt_cfg_p->custom_dma)
        {
            LOG_ERR("NPU config mismatch: npu.custom_dma=%" PRIu32 " optimize.custom_dma=%d\n",
                    cfg.custom_dma,
                    opt_cfg_p->custom_dma);
        }
        return_code = -1;
    }

    if ((id.arch_major_rev != opt_cfg_p->arch_major_rev) || (id.arch_minor_rev < opt_cfg_p->arch_minor_rev))
    {
        LOG_ERR("NPU arch mismatch: npu.arch=%" PRIu32 ".%" PRIu32 ".%" PRIu32 " optimizer.arch=%d.%d.%d\n",
                id.arch_major_rev,
                id.arch_minor_rev,
                id.arch_patch_rev,
                opt_cfg_p->arch_major_rev,
                opt_cfg_p->arch_minor_rev,
                opt_cfg_p->arch_patch_rev);
        return_code = -1;
    }

#if !defined(LOG_ENABLED)
    UNUSED(opt_cfg_p);
#endif
    return return_code;
}

static void npu_axi_init(struct ethosu_driver *drv)
{
    ethosu_set_qconfig(&drv->dev, NPU_QCONFIG);

    ethosu_set_regioncfg(&drv->dev, 0, NPU_REGIONCFG_0);
    ethosu_set_regioncfg(&drv->dev, 1, NPU_REGIONCFG_1);
    ethosu_set_regioncfg(&drv->dev, 2, NPU_REGIONCFG_2);
    ethosu_set_regioncfg(&drv->dev, 3, NPU_REGIONCFG_3);
    ethosu_set_regioncfg(&drv->dev, 4, NPU_REGIONCFG_4);
    ethosu_set_regioncfg(&drv->dev, 5, NPU_REGIONCFG_5);
    ethosu_set_regioncfg(&drv->dev, 6, NPU_REGIONCFG_6);
    ethosu_set_regioncfg(&drv->dev, 7, NPU_REGIONCFG_7);

    (void)ethosu_set_axi_limit0(&drv->dev,
                                AXI_LIMIT0_MAX_BEATS_BYTES,
                                AXI_LIMIT0_MEM_TYPE,
                                AXI_LIMIT0_MAX_OUTSTANDING_READS,
                                AXI_LIMIT0_MAX_OUTSTANDING_WRITES);
    (void)ethosu_set_axi_limit1(&drv->dev,
                                AXI_LIMIT1_MAX_BEATS_BYTES,
                                AXI_LIMIT1_MEM_TYPE,
                                AXI_LIMIT1_MAX_OUTSTANDING_READS,
                                AXI_LIMIT1_MAX_OUTSTANDING_WRITES);
    (void)ethosu_set_axi_limit2(&drv->dev,
                                AXI_LIMIT2_MAX_BEATS_BYTES,
                                AXI_LIMIT2_MEM_TYPE,
                                AXI_LIMIT2_MAX_OUTSTANDING_READS,
                                AXI_LIMIT2_MAX_OUTSTANDING_WRITES);
    (void)ethosu_set_axi_limit3(&drv->dev,
                                AXI_LIMIT3_MAX_BEATS_BYTES,
                                AXI_LIMIT3_MEM_TYPE,
                                AXI_LIMIT3_MAX_OUTSTANDING_READS,
                                AXI_LIMIT3_MAX_OUTSTANDING_WRITES);
}

/* Default implementation to flush the data cache. Override if available on the targeted device.
 * Passing NULL as p argument expects the whole cache to be flushed.
 */
void __attribute__((weak)) ethosu_flush_dcache(uint32_t *p, size_t bytes)
{
    (void)p;
    (void)bytes;
}

/* Default implementation to invalidate the data cache. Override if available on the targeted device.
 * Passing NULL as p argument expects the whole cache to be flushed.
 */
void __attribute__((weak)) ethosu_invalidate_dcache(uint32_t *p, size_t bytes)
{
    (void)p;
    (void)bytes;
}

static int handle_command_stream(struct ethosu_driver *drv,
                                 const uint8_t *cmd_stream,
                                 const int cms_length,
                                 const uint64_t *base_addr,
                                 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;
    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))
    {
        LOG_ERR("Error: Command stream addr %p not aligned to 16 bytes\n", cmd_stream);
        return -1;
    }

    bool base_addr_invalid = false;
    for (int i = 0; i < num_base_addr; i++)
    {
        if (0 != (base_addr[i] & MASK_16_BYTE_ALIGN))
        {
            LOG_ERR("Error: Base addr %d: 0x%llx not aligned to 16 bytes\n", i, base_addr[i]);
            base_addr_invalid = true;
        }
    }

    if (base_addr_invalid)
    {
        return -1;
    }

    /* Flush the cache if available on our CPU.
     * The upcasting to uin32_t* is ok since the pointer never is dereferenced.
     * The base_addr_size is null if invoking from prior to invoke_V2, in that case
     * the whole cache is being flushed.
     */

    if (base_addr_size != NULL)
    {
        ethosu_flush_dcache((uint32_t *)cmd_stream_ptr, cms_bytes);
        for (int i = 0; i < num_base_addr; i++)
        {
            ethosu_flush_dcache((uint32_t *)(uintptr_t)base_addr[i], base_addr_size[i]);
        }
    }
    else
    {
        ethosu_flush_dcache(NULL, 0);
    }

    if (ETHOSU_SUCCESS != ethosu_run_command_stream(&drv->dev, cmd_stream, cms_bytes, base_addr, num_base_addr))
    {
        return -1;
    }

    wait_for_irq(drv);

    if (drv->status_error)
    {
        return -1;
    }

    if (base_addr_size != NULL)
    {
        for (int i = 0; i < num_base_addr; i++)
        {
            ethosu_invalidate_dcache((uint32_t *)(uintptr_t)base_addr[i], base_addr_size[i]);
        }
    }
    else
    {
        ethosu_invalidate_dcache(NULL, 0);
    }

    (void)ethosu_get_qread(&drv->dev, &qread);
    if (qread != cms_bytes)
    {
        LOG_WARN(
            "Failure: IRQ received but qread (%" PRIu32 ") not at end of stream (%" PRIu32 ").\n", qread, cms_bytes);
        return -1;
    }

    return 0;
}

static int read_apb_reg(struct ethosu_driver *drv, uint16_t da_data)
{
    uint32_t *reg_p;
    uint32_t start_address = (uint32_t)(da_data & APB_START_ADDR_MASK);
    uint16_t num_reg       = (da_data >> APB_NUM_REG_BIT_SHIFT) + 1;

    reg_p = (uint32_t *)malloc(num_reg * sizeof(uint32_t));
    if (reg_p == NULL)
    {
        LOG_INFO("read_apb_reg, Error! memory not allocated.");
        return -1;
    }

    if (ETHOSU_SUCCESS == ethosu_read_apb_reg(&drv->dev, start_address, num_reg, reg_p))
    {
        for (int i = 0; i < num_reg; i++)
        {
            LOG_INFO(
                "NPU_REG ADDR 0x%04" PRIu32 " = 0x%08" PRIu32 "\n", (start_address + (i * BYTES_IN_32_BITS)), reg_p[i]);
        }
    }
    else
    {
        free(reg_p);
        return -1;
    }

    free(reg_p);
    return 0;
}

static int dump_shram(struct ethosu_driver *drv)
{
    struct ethosu_config cfg;
    uint32_t *shram_p;
    (void)ethosu_get_config(&drv->dev, &cfg);

    LOG_INFO("dump_shram size = %" PRIu32 " KB\n", cfg.shram_size);

    shram_p = (uint32_t *)malloc(BYTES_1KB);
    if (shram_p == NULL)
    {
        LOG_ERR("read_shram, Error! memory not allocated.");
        return -1;
    }

    for (uint32_t i = 0; i < cfg.shram_size; i++)
    {
        ethosu_get_shram_data(&drv->dev, i, (uint32_t *)shram_p);
        // Output 1KB of SHRAM
        LOG_INFO("***SHRAM SECTION %" PRIu32 "***\n", i);
        for (int j = 0; j < (BYTES_1KB / BYTES_IN_32_BITS); j++)
        {
            LOG_INFO("[0x%04" PRIx32 "] %" PRIx32 "\n", (i * 1024 + j * 4), shram_p[j]);
        }
    }
    free(shram_p);

    return 0;
}

typedef struct
{
    int number;
    const char *name;
} name_lookup_t;

static const name_lookup_t npu_reg_name_tbl[] = {
    {0x200, "KERNEL_X"},
    {0x204, "KERNEL_Y"},
    {0x208, "KERNEL_W_M1"},
    {0x20C, "KERNEL_H_M1"},
    {0x210, "OFM_CBLK_WIDTH_M1"},
    {0x214, "OFM_CBLK_HEIGHT_M1"},
    {0x218, "OFM_CBLK_DEPTH_M1"},
    {0x21c, "IFM_CBLK_DEPTH_M1"},
    {0x220, "OFM_X"},
    {0x224, "OFM_Y"},
    {0x228, "OFM_Z"},
    {0x22C, "IFM_Z"},
    {0x230, "PAD_TOP"},
    {0x234, "PAD_LEFT"},
    {0x238, "IFM_CBLK_WIDTH"},
    {0x23C, "IFM_CBLK_HEIGHT"},
    {0x240, "DMA_IFM_SRC"},
    {0x244, "DMA_IFM_SRC_HI"},
    {0x248, "DMA_IFM_DST"},
    {0x24c, "DMA_OFM_SRC"},
    {0x250, "DMA_OFM_DST"},
    {0x254, "DMA_OFM_DST_HI"},
    {0x258, "DMA_WEIGHT_SRC"},
    {0x25c, "DMA_WEIGHT_SRC_HI"},
    {0x260, "DMA_CMD_SRC"},
    {0x264, "DMA_CMD_SRC_HI"},
    {0x268, "DMA_CMD_SIZE"},
    {0x26c, "DMA_M2M_SRC"},
    {0x270, "DMA_M2M_SRC_HI"},
    {0x274, "DMA_M2M_DST"},
    {0x278, "DMA_M2M_DST_HI"},
    {0x27c, "CURRENT_QREAD"},
    {0x280, "DMA_SCALE_SRC"},
    {0x284, "DMA_SCALE_SRC_HI"},
    {0x2BC, "CURRENT_CMD"},
    {0x800, "IFM_PAD_TOP"},
    {0x804, "IFM_PAD_LEFT"},
    {0x808, "IFM_PAD_RIGHT"},
    {0x80C, "IFM_PAD_BOTTOM"},
    {0x810, "IFM_DEPTH_M1"},
    {0x814, "IFM_PRECISION"},
    {0x81C, "IFM_UPSCALE"},
    {0x824, "IFM_ZERO_POINT"},
    {0x828, "IFM_WIDTH0_M1"},
    {0x82C, "IFM_HEIGHT0_M1"},
    {0x830, "IFM_HEIGHT1_M1"},
    {0x834, "IFM_IB_END"},
    {0x83C, "IFM_REGION"},
    {0x844, "OFM_WIDTH_M1"},
    {0x848, "OFM_HEIGHT_M1"},
    {0x84C, "OFM_DEPTH_M1"},
    {0x850, "OFM_PRECISION"},
    {0x854, "OFM_BLK_WIDTH_M1"},
    {0x858, "OFM_BLK_HEIGHT_M1"},
    {0x85C, "OFM_BLK_DEPTH_M1"},
    {0x860, "OFM_ZERO_POINT"},
    {0x868, "OFM_WIDTH0_M1"},
    {0x86C, "OFM_HEIGHT0_M1"},
    {0x870, "OFM_HEIGHT1_M1"},
    {0x87C, "OFM_REGION"},
    {0x880, "KERNEL_WIDTH_M1"},
    {0x884, "KERNEL_HEIGHT_M1"},
    {0x888, "KERNEL_STRIDE"},
    {0x88C, "PARALLEL_MODE"},
    {0x890, "ACC_FORMAT"},
    {0x894, "ACTIVATION"},
    {0x898, "ACTIVATION_MIN"},
    {0x89C, "ACTIVATION_MAX"},
    {0x8A0, "WEIGHT_REGION"},
    {0x8A4, "SCALE_REGION"},
    {0x8B4, "AB_START"},
    {0x8BC, "BLOCKDEP"},
    {0x8C0, "DMA0_SRC_REGION"},
    {0x8C4, "DMA0_DST_REGION"},
    {0x8C8, "DMA0_SIZE0"},
    {0x8CC, "DMA0_SIZE1"},
    {0x900, "IFM2_BROADCAST"},
    {0x904, "IFM2_SCALAR"},
    {0x924, "IFM2_ZERO_POINT"},
    {0x928, "IFM2_WIDTH0_M1"},
    {0x92C, "IFM2_HEIGHT0_M1"},
    {0x930, "IFM2_HEIGHT1_M1"},
    {0x934, "IFM2_IB_START"},
    {0x93C, "IFM2_REGION"},
    {0xA00, "IFM_BASE0"},
    {0xA04, "IFM_BASE0_HI"},
    {0xA08, "IFM_BASE1"},
    {0xA0C, "IFM_BASE1_HI"},
    {0xA10, "IFM_BASE2"},
    {0xA14, "IFM_BASE2_HI"},
    {0xA18, "IFM_BASE3"},
    {0xA1C, "IFM_BASE3_HI"},
    {0xA20, "IFM_STRIDE_X"},
    {0xA24, "IFM_STRIDE_X_HI"},
    {0xA28, "IFM_STRIDE_Y"},
    {0xA2C, "IFM_STRIDE_Y_HI"},
    {0xA30, "IFM_STRIDE_C"},
    {0xA34, "IFM_STRIDE_C_HI"},
    {0xA40, "OFM_BASE0"},
    {0xA44, "OFM_BASE0_HI"},
    {0xA48, "OFM_BASE1"},
    {0xA4C, "OFM_BASE1_HI"},
    {0xA50, "OFM_BASE2"},
    {0xA54, "OFM_BASE2_HI"},
    {0xA58, "OFM_BASE3"},
    {0xA5C, "OFM_BASE3_HI"},
    {0xA60, "OFM_STRIDE_X"},
    {0xA64, "OFM_STRIDE_X_HI"},
    {0xA68, "OFM_STRIDE_Y"},
    {0xA6C, "OFM_STRIDE_Y_HI"},
    {0xA70, "OFM_STRIDE_C"},
    {0xA74, "OFM_STRIDE_C_HI"},
    {0xA80, "WEIGHT_BASE"},
    {0xA84, "WEIGHT_BASE_HI"},
    {0xA88, "WEIGHT_LENGTH"},
    {0xA8C, "WEIGHT_LENGTH_HI"},
    {0xA90, "SCALE_BASE"},
    {0xA94, "SCALE_BASE_HI"},
    {0xA98, "SCALE_LENGTH"},
    {0xAA0, "OFM_SCALE"},
    {0xAA4, "OFM_SCALE_SHIFT"},
    {0xAA8, "OPA_SCALE "},
    {0xAB0, "OPB_SCALE"},
    {0xAC0, "DMA0_SRC"},
    {0xAC4, "DMA0_SRC_HI"},
    {0xAC8, "DMA0_DST"},
    {0xACC, "DMA0_DST_HI"},
    {0xAD0, "DMA0_LEN"},
    {0xAD4, "DMA0_LEN_HI"},
    {0xAD8, "DMA0_SKIP0"},
    {0xADC, "DMA0_SKIP0_HI"},
    {0xAE0, "DMA0_SKIP1"},
    {0xAE4, "DMA0_SKIP1_HI"},
    {0xB00, "IFM2_BASE0"},
    {0xB04, "IFM2_BASE0_HI"},
    {0xB08, "IFM2_BASE1"},
    {0xB0C, "IFM2_BASE1_HI"},
    {0xB10, "IFM2_BASE2"},
    {0xB14, "IFM2_BASE2_HI"},
    {0xB18, "IFM2_BASE3"},
    {0xB1C, "IFM2_BASE3_HI"},
    {0xB20, "IFM2_STRIDE_X"},
    {0xB24, "IFM2_STRIDE_X_HI"},
    {0xB28, "IFM2_STRIDE_Y"},
    {0xB2C, "IFM2_STRIDE_Y_HI"},
    {0xB30, "IFM2_STRIDE_C"},
    {0xB34, "IFM2_STRIDE_C_HI"},
    {0xB40, "WEIGHT1_BASE"},
    {0xB44, "WEIGHT1_BASE_HI"},
    {0xB48, "WEIGHT1_LENGTH"},
    {0xB4C, "WEIGHT1_LENGTH_HI"},
    {0xB50, "SCALE1_BASE"},
    {0xB54, "SCALE1_BASE_HI"},
    {0xB58, "SCALE1_LENGTH"},
};

static const char *lookup_name(const name_lookup_t *lookup_table, int lookup_table_count, int find)
{
    int n;
    for (n = 0; n < lookup_table_count; n++)
    {
        if (lookup_table[n].number == find)
        {
            return lookup_table[n].name;
        }
    }
    // Not found
    return 0;
}

static void dump_npu_register(struct ethosu_driver *drv, int npu_reg, int npu_reg_end)
{
    unsigned int reg_val;
    const char *reg_name;
    int npu_reg_name_tbl_count = sizeof(npu_reg_name_tbl) / sizeof(npu_reg_name_tbl[0]);

    LOG_INFO("dump_register %X - %X\n", npu_reg, npu_reg_end);
    for (; npu_reg <= npu_reg_end; npu_reg += sizeof(int))
    {
        reg_val  = ethosu_read_reg(&drv->dev, npu_reg);
        reg_name = lookup_name(npu_reg_name_tbl, npu_reg_name_tbl_count, npu_reg);
        LOG_INFO("[0x%.4X] 0x%.8X\t%s\n", npu_reg, reg_val, (reg_name) ? reg_name : "");
    }
}

static const name_lookup_t cmd0_name_tbl[] = {
    {0x000, "NPU_OP_STOP"},
    {0x001, "NPU_OP_IRQ"},
    {0x002, "NPU_OP_CONV"},
    {0x003, "NPU_OP_DEPTHWISE"},
    {0x004, "NPU_OP_VECTOR_PROD"},
    {0x005, "NPU_OP_POOL"},
    {0x006, "NPU_OP_ELEMENTWISE"},
    {0x010, "NPU_OP_DMA_START"},
    {0x011, "NPU_OP_DMA_WAIT"},
    {0x012, "NPU_OP_KERNEL_WAIT"},
    {0x100, "NPU_SET_IFM_PAD_TOP"},
    {0x101, "NPU_SET_IFM_PAD_LEFT"},
    {0x102, "NPU_SET_IFM_PAD_RIGHT"},
    {0x103, "NPU_SET_IFM_PAD_BOTTOM"},
    {0x104, "NPU_SET_IFM_DEPTH_M1"},
    {0x105, "NPU_SET_IFM_PRECISION"},
    {0x107, "NPU_SET_IFM_UPSCALE"},
    {0x109, "NPU_SET_IFM_ZERO_POINT"},
    {0x10A, "NPU_SET_IFM_WIDTH0_M1"},
    {0x10B, "NPU_SET_IFM_HEIGHT0_M1"},
    {0x10C, "NPU_SET_IFM_HEIGHT1_M1"},
    {0x10D, "NPU_SET_IFM_IB_END"},
    {0x10F, "NPU_SET_IFM_REGION"},
    {0x110, "NPU_SET_OFM_BATCH_SIZE_M1"},
    {0x111, "NPU_SET_OFM_WIDTH_M1"},
    {0x112, "NPU_SET_OFM_HEIGHT_M1"},
    {0x113, "NPU_SET_OFM_DEPTH_M1"},
    {0x114, "NPU_SET_OFM_PRECISION"},
    {0x115, "NPU_SET_OFM_BLK_WIDTH_M1"},
    {0x116, "NPU_SET_OFM_BLK_HEIGHT_M1"},
    {0x117, "NPU_SET_OFM_BLK_DEPTH_M1"},
    {0x118, "NPU_SET_OFM_ZERO_POINT"},
    {0x11A, "NPU_SET_OFM_WIDTH0_M1"},
    {0x11B, "NPU_SET_OFM_HEIGHT0_M1"},
    {0x11C, "NPU_SET_OFM_HEIGHT1_M1"},
    {0x11F, "NPU_SET_OFM_REGION"},
    {0x120, "NPU_SET_KERNEL_WIDTH_M1"},
    {0x121, "NPU_SET_KERNEL_HEIGHT_M1"},
    {0x122, "NPU_SET_KERNEL_STRIDE"},
    {0x124, "NPU_SET_ACC_FORMAT"},
    {0x125, "NPU_SET_ACTIVATION"},
    {0x126, "NPU_SET_ACTIVATION_MIN"},
    {0x127, "NPU_SET_ACTIVATION_MAX"},
    {0x128, "NPU_SET_WEIGHT_REGION"},
    {0x129, "NPU_SET_SCALE_REGION"},
    {0x12D, "NPU_SET_AB_START"},
    {0x12F, "NPU_SET_BLOCKDEP"},
    {0x130, "NPU_SET_DMA0_SRC_REGION"},
    {0x131, "NPU_SET_DMA0_DST_REGION"},
    {0x180, "NPU_SET_IFM2_BROADCAST"},
    {0x181, "NPU_SET_IFM2_SCALAR"},
    {0x185, "NPU_SET_IFM2_PRECISION"},
    {0x189, "NPU_SET_IFM2_ZERO_POINT"},
    {0x18A, "NPU_SET_IFM2_WIDTH0_M1"},
    {0x18B, "NPU_SET_IFM2_HEIGHT0_M1"},
    {0x18C, "NPU_SET_IFM2_HEIGHT1_M1"},
    {0x18D, "NPU_SET_IFM2_IB_START"},
    {0x18F, "NPU_SET_IFM2_REGION"},
};

static const name_lookup_t cmd1_name_tbl[] = {
    {0x000, "NPU_SET_IFM_BASE0"},     {0x001, "NPU_SET_IFM_BASE1"},     {0x002, "NPU_SET_IFM_BASE2"},
    {0x003, "NPU_SET_IFM_BASE3"},     {0x004, "NPU_SET_IFM_STRIDE_X"},  {0x005, "NPU_SET_IFM_STRIDE_Y"},
    {0x006, "NPU_SET_IFM_STRIDE_C"},  {0x007, "NPU_SET_IFM_STRIDE_N"},  {0x010, "NPU_SET_OFM_BASE0"},
    {0x011, "NPU_SET_OFM_BASE1"},     {0x012, "NPU_SET_OFM_BASE2"},     {0x013, "NPU_SET_OFM_BASE3"},
    {0x014, "NPU_SET_OFM_STRIDE_X"},  {0x015, "NPU_SET_OFM_STRIDE_Y"},  {0x016, "NPU_SET_OFM_STRIDE_C"},
    {0x017, "NPU_SET_OFM_STRIDE_N"},  {0x020, "NPU_SET_WEIGHT_BASE"},   {0x021, "NPU_SET_WEIGHT_LENGTH"},
    {0x022, "NPU_SET_SCALE_BASE"},    {0x023, "NPU_SET_SCALE_LENGTH"},  {0x024, "NPU_SET_OFM_SCALE"},
    {0x025, "NPU_SET_OPA_SCALE"},     {0x026, "NPU_SET_OPB_SCALE"},     {0x030, "NPU_SET_DMA0_SRC"},
    {0x031, "NPU_SET_DMA0_DST"},      {0x032, "NPU_SET_DMA0_LEN"},      {0x080, "NPU_SET_IFM2_BASE0"},
    {0x081, "NPU_SET_IFM2_BASE1"},    {0x082, "NPU_SET_IFM2_BASE2"},    {0x083, "NPU_SET_IFM2_BASE3"},
    {0x084, "NPU_SET_IFM2_STRIDE_X"}, {0x085, "NPU_SET_IFM2_STRIDE_Y"}, {0x086, "NPU_SET_IFM2_STRIDE_C"},
};

static void dump_command_stream(const uint32_t *cmd_stream, const int cms_length, int qread)
{
    int n;
    int offset;
    uint32_t cmd_val;
    const uint8_t *cmd_ptr;
    const char *cmd_name;
    int cmd0_name_tbl_count = sizeof(cmd0_name_tbl) / sizeof(cmd0_name_tbl[0]);
    int cmd1_name_tbl_count = sizeof(cmd1_name_tbl) / sizeof(cmd1_name_tbl[0]);

    LOG_INFO("dump_command_stream cmd_stream = 0x%8p cms_length = %d\n", cmd_stream, cms_length);
    for (n = 0; n < cms_length; n++)
    {
        // Offset
        offset = n * sizeof(int);
        LOG_INFO("[%.4d] ", offset);
        // Command
        cmd_ptr = (const uint8_t *)&cmd_stream[n];
        LOG_INFO("0x%.2X 0x%.2X 0x%.2X 0x%.2X ", cmd_ptr[0], cmd_ptr[1], cmd_ptr[2], cmd_ptr[3]);
        // Command name and payload
        if (cmd_stream[n] & 0x4000)
        {
            cmd_name = lookup_name(cmd1_name_tbl, cmd1_name_tbl_count, cmd_stream[n] & 0x3FF);
            n++;
            cmd_val = cmd_stream[n];
            cmd_ptr = (const uint8_t *)&cmd_stream[n];
            LOG_INFO("0x%.2X 0x%.2X 0x%.2X 0x%.2X ", cmd_ptr[0], cmd_ptr[1], cmd_ptr[2], cmd_ptr[3]);
        }
        else
        {
            cmd_val  = cmd_stream[n] >> 16;
            cmd_name = lookup_name(cmd0_name_tbl, cmd0_name_tbl_count, cmd_stream[n] & 0x3FF);
        }
        if (cmd_name)
        {
            LOG_INFO("\t%s 0x%.8" PRIX32, cmd_name, cmd_val);
        }
        if (offset == qread)
        {
            LOG_INFO(" <<== QREAD\n");
        }
        else
        {
            LOG_INFO("\n");
        }
    }
}
