diff options
Diffstat (limited to 'ethosu_pmu')
-rw-r--r-- | ethosu_pmu/CMakeLists.txt | 39 | ||||
-rw-r--r-- | ethosu_pmu/common.h | 50 | ||||
-rw-r--r-- | ethosu_pmu/driver.c | 82 | ||||
-rw-r--r-- | ethosu_pmu/ethosu_pmu_config.h.in | 34 | ||||
-rw-r--r-- | ethosu_pmu/include/pmu_ethosu.h | 452 |
5 files changed, 657 insertions, 0 deletions
diff --git a/ethosu_pmu/CMakeLists.txt b/ethosu_pmu/CMakeLists.txt new file mode 100644 index 0000000..98c403e --- /dev/null +++ b/ethosu_pmu/CMakeLists.txt @@ -0,0 +1,39 @@ +# Copyright (c) 2019-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. +# + +# +# Global options +# + +set(NPU_PMCR "0x0" CACHE STRING "Register control b0 = CNT_EN = Enable counters (RW), b1 = EVENT_CNT_RST = Reset event counters (WO), b2 = CYCLE_CNT_RST = Reset cycle counter (WO), b[15:11] = Number of event counters (RO)") +set(NPU_PMCNTENSET "0x0" CACHE STRING "Bit k enables event counter k. k=31 enables the cycle counter. Read value is current status.") +set(NPU_PMCNTENCLR "0x0" CACHE STRING "Bit k disables event counter k. k=31 disables the cycle counter. Reda value is current status.") +set(NPU_PMOVSSET "0x0" CACHE STRING "Overflow detection set. Bit k is for counter k. k=31 is cycle counter.") +set(NPU_PMOVSCLR "0x0" CACHE STRING "Overflow detection clear. Bit k is for counter k. k=31 is cycle counter.") +set(NPU_PMINTSET "0x0" CACHE STRING "Interrupt set. Bit k is for counter k. k=31 is cycle counter.") +set(NPU_PMINTCLR "0x8003" CACHE STRING "Interrupt clear. Bit k is for counter k. k=31 is cycle counter.") +set(NPU_PMCCNTR "0x0" CACHE STRING "Cycle counter, 48 bits value") +set(NPU_PMCCNTR_CFG "0x0" CACHE STRING "b[9:0] Start Event – this event number starts the cycle counter b[25:16] Stop Event – this event number stops the cycle counter") + +# +# Build binaries +# + +add_library(ethosu_core_driver_pmu STATIC driver.c) +target_include_directories(ethosu_core_driver_pmu PUBLIC include PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) + +configure_file("${CMAKE_CURRENT_SOURCE_DIR}/ethosu_pmu_config.h.in" "${CMAKE_CURRENT_BINARY_DIR}/ethosu_pmu_config.h") diff --git a/ethosu_pmu/common.h b/ethosu_pmu/common.h new file mode 100644 index 0000000..f42a65e --- /dev/null +++ b/ethosu_pmu/common.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2019-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. + */ +#ifndef ethosu_pmu_common_h +#define ethosu_pmu_common_h + +#include <stdint.h> + +/* Separators for EXPAND_(name) macros */ +#define COMMA , +#define SEMICOLON ; +#define COLON : +#define NOTHING + +#if defined(CPU_CORTEX_M55) +#define NPU_BASE ((uint32_t)0x41700000) +#else +#define NPU_BASE ((uint32_t)0x41105000) +#endif + +#define ETHOSU_PMU_CTRL_BASE (NPU_BASE + ((uint32_t)0x180)) +#define ETHOSU_PMU_CNTR_BASE (NPU_BASE + ((uint32_t)0x300)) +#define ETHOSU_PMU_EVNT_BASE (NPU_BASE + ((uint32_t)0x380)) + +#define __init __attribute__((constructor)) +#define __exit __attribute__((destructor)) + +#ifdef NEVER +#define INIT __init void +#define EXIT __exit void +#else +#define INIT static __init void +#define EXIT static __init void +#endif + +#endif // mpu_pmu_common_h diff --git a/ethosu_pmu/driver.c b/ethosu_pmu/driver.c new file mode 100644 index 0000000..80cd79a --- /dev/null +++ b/ethosu_pmu/driver.c @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2019-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. + */ +#include "common.h" +#include "ethosu55_interface.h" +#include "ethosu_pmu_config.h" +#include <assert.h> +#include <ethosu_driver.h> +#include <pmu_ethosu.h> +#include <stdint.h> + +PMU_Ethosu_ctrl_Type *ethosu_pmu_ctrl = (PMU_Ethosu_ctrl_Type *)ETHOSU_PMU_CTRL_BASE; +PMU_Ethosu_cntr_Type *ethosu_pmu_cntr = (PMU_Ethosu_cntr_Type *)ETHOSU_PMU_CNTR_BASE; +PMU_Ethosu_evnt_Type *ethosu_pmu_evnt = (PMU_Ethosu_evnt_Type *)ETHOSU_PMU_EVNT_BASE; + +// Local functions & macros +#define PMUREG0(NAME) INIT_##NAME + +#define ETHOSU_PMU_INIT(N) \ + *ethosu_pmu_ctrl = (PMU_Ethosu_ctrl_Type){.PMCR = PMUREG##N(PMCR), \ + .PMCNTENSET = PMUREG##N(PMCNTENSET), \ + .PMCNTENCLR = PMUREG##N(PMCNTENCLR), \ + .PMOVSSET = PMUREG##N(PMOVSSET), \ + .PMOVSCLR = PMUREG##N(PMOVSCLR), \ + .PMINTSET = PMUREG##N(PMINTSET), \ + .PMINTCLR = PMUREG##N(PMINTCLR), \ + .PMCCNTR = PMUREG##N(PMCCNTR), \ + .PMCCNTR_CFG = PMUREG##N(PMCCNTR_CFG)}; + +// Public interfaces + +#define EVTYPE(A, name) \ + case PMU_EVENT_TYPE_##name: \ + return ETHOSU_PMU_##name +enum ethosu_pmu_event_type pmu_event_type(uint32_t id) +{ + switch (id) + { + EXPAND_PMU_EVENT_TYPE(EVTYPE, SEMICOLON); + } + return ETHOSU_PMU_SENTINEL; +} + +#define EVID(A, name) (PMU_EVENT_TYPE_##name) +static const enum pmu_event_type eventbyid[] = {EXPAND_PMU_EVENT_TYPE(EVID, COMMA)}; +uint32_t pmu_event_value(enum ethosu_pmu_event_type event) +{ + if (!(event < ETHOSU_PMU_SENTINEL) || (event < 0)) + { + return (uint32_t)(-1); + } + + return eventbyid[event]; +} + +// Driver Init/exit functions +INIT ethosu_pmu_driver_init(void) +{ + ETHOSU_PMU_INIT(0) + + for (int i = 0; i < ETHOSU_PMU_NCOUNTERS; i++) + { + *ethosu_pmu_cntr[i] = 0; + *ethosu_pmu_evnt[i] = 0; + } +} + +EXIT ethosu_pmu_driver_exit(void) {} diff --git a/ethosu_pmu/ethosu_pmu_config.h.in b/ethosu_pmu/ethosu_pmu_config.h.in new file mode 100644 index 0000000..05ca476 --- /dev/null +++ b/ethosu_pmu/ethosu_pmu_config.h.in @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2019-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. + */ + +/* ETHOSU_PMU config file */ +#ifndef ethosu_pmu_config_h +#define ethosu_pmu_config_h + +/* Initial values */ +#define INIT_PMCR (@NPU_PMCR@) +#define INIT_PMCNTENSET (@NPU_PMCNTENSET@) +#define INIT_PMCNTENCLR (@NPU_PMCNTENCLR@) +#define INIT_PMOVSSET (@NPU_PMOVSSET@) +#define INIT_PMOVSCLR (@NPU_PMOVSCLR@) +#define INIT_PMINTSET (@NPU_PMINTSET@) +#define INIT_PMINTCLR (@NPU_PMINTCLR@) +#define INIT_PMCCNTR (@NPU_PMCCNTR@) +#define INIT_PMCCNTR_CFG (@NPU_PMCCNTR_CFG@) + +#endif diff --git a/ethosu_pmu/include/pmu_ethosu.h b/ethosu_pmu/include/pmu_ethosu.h new file mode 100644 index 0000000..b8b1a23 --- /dev/null +++ b/ethosu_pmu/include/pmu_ethosu.h @@ -0,0 +1,452 @@ +/* + * Copyright (c) 2019-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. + */ + +#if defined(__ICCARM__) +#pragma system_include /* treat file as system include file for MISRA check */ +#elif defined(__clang__) +#pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef PMU_ETHOSU_H +#define PMU_ETHOSU_H + +#define ETHOSU_PMU_NCOUNTERS 4 + +#include <cmsis_compiler.h> + +#ifdef NOTNOW +#if defined(CPU_CORTEX_M55) +#include <core_cm55.h> +#elif defined(CPU_CORTEX_M33) +#include <core_cm33.h> +#else +#error npu-pmu not supported for CPU +#endif +#else +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + <strong>IO Type Qualifiers</strong> are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus +#define __I volatile /*!< Defines 'read only' permissions */ +#else +#define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/* following defines should be used for structure members */ +#define __IM volatile const /*! Defines 'read only' structure member permissions */ +#define __OM volatile /*! Defines 'write only' structure member permissions */ +#define __IOM volatile /*! Defines 'read / write' structure member permissions */ +#endif + +typedef struct +{ + __IOM uint32_t PMCR; + __IOM uint32_t PMCNTENSET; + __IOM uint32_t PMCNTENCLR; + __IOM uint32_t PMOVSSET; + __IOM uint32_t PMOVSCLR; + __IOM uint32_t PMINTSET; + __IOM uint32_t PMINTCLR; + __IOM uint64_t PMCCNTR; + __IOM uint32_t PMCCNTR_CFG; +} PMU_Ethosu_ctrl_Type; + +typedef uint32_t PMU_Ethosu_cntr_Type[ETHOSU_PMU_NCOUNTERS]; +typedef uint32_t PMU_Ethosu_evnt_Type[ETHOSU_PMU_NCOUNTERS]; + +/** \brief HW Supported ETHOSU PMU Events + * + * Note: These values are symbolic. Actual HW-values may change. I.e. always use API + * to set/get actual event-type value. + * */ +enum ethosu_pmu_event_type +{ + ETHOSU_PMU_CYCLE = 0, + ETHOSU_PMU_NPU_IDLE, + ETHOSU_PMU_MAC_ACTIVE, + ETHOSU_PMU_MAC_ACTIVE_8BIT, + ETHOSU_PMU_MAC_ACTIVE_16BIT, + ETHOSU_PMU_MAC_DPU_ACTIVE, + ETHOSU_PMU_MAC_STALLED_BY_WD_ACC, + ETHOSU_PMU_MAC_STALLED_BY_WD, + ETHOSU_PMU_MAC_STALLED_BY_ACC, + ETHOSU_PMU_MAC_STALLED_BY_IB, + ETHOSU_PMU_AO_ACTIVE, + ETHOSU_PMU_AO_ACTIVE_8BIT, + ETHOSU_PMU_AO_ACTIVE_16BIT, + ETHOSU_PMU_AO_STALLED_BY_OFMP_OB, + ETHOSU_PMU_AO_STALLED_BY_OFMP, + ETHOSU_PMU_AO_STALLED_BY_OB, + ETHOSU_PMU_AO_STALLED_BY_ACC_IB, + ETHOSU_PMU_AO_STALLED_BY_ACC, + ETHOSU_PMU_AO_STALLED_BY_IB, + ETHOSU_PMU_WD_ACTIVE, + ETHOSU_PMU_WD_STALLED, + ETHOSU_PMU_WD_STALLED_BY_WS, + ETHOSU_PMU_WD_STALLED_BY_WD_BUF, + ETHOSU_PMU_WD_PARSE_ACTIVE, + ETHOSU_PMU_WD_PARSE_STALLED, + ETHOSU_PMU_WD_PARSE_STALLED_IN, + ETHOSU_PMU_WD_PARSE_STALLED_OUT, + ETHOSU_PMU_AXI0_RD_TRANS_ACCEPTED, + ETHOSU_PMU_AXI0_RD_TRANS_COMPLETED, + ETHOSU_PMU_AXI0_RD_DATA_BEAT_RECEIVED, + ETHOSU_PMU_AXI0_RD_TRAN_REQ_STALLED, + ETHOSU_PMU_AXI0_WR_TRANS_ACCEPTED, + ETHOSU_PMU_AXI0_WR_TRANS_COMPLETED_M, + ETHOSU_PMU_AXI0_WR_TRANS_COMPLETED_S, + ETHOSU_PMU_AXI0_WR_DATA_BEAT_WRITTEN, + ETHOSU_PMU_AXI0_WR_TRAN_REQ_STALLED, + ETHOSU_PMU_AXI0_WR_DATA_BEAT_STALLED, + ETHOSU_PMU_AXI0_ENABLED_CYCLES, + ETHOSU_PMU_AXI0_RD_STALL_LIMIT, + ETHOSU_PMU_AXI0_WR_STALL_LIMIT, + ETHOSU_PMU_AXI1_RD_TRANS_ACCEPTED, + ETHOSU_PMU_AXI1_RD_TRANS_COMPLETED, + ETHOSU_PMU_AXI1_RD_DATA_BEAT_RECEIVED, + ETHOSU_PMU_AXI1_RD_TRAN_REQ_STALLED, + ETHOSU_PMU_AXI1_WR_TRANS_ACCEPTED, + ETHOSU_PMU_AXI1_WR_TRANS_COMPLETED_M, + ETHOSU_PMU_AXI1_WR_TRANS_COMPLETED_S, + ETHOSU_PMU_AXI1_WR_DATA_BEAT_WRITTEN, + ETHOSU_PMU_AXI1_WR_TRAN_REQ_STALLED, + ETHOSU_PMU_AXI1_WR_DATA_BEAT_STALLED, + ETHOSU_PMU_AXI1_ENABLED_CYCLES, + ETHOSU_PMU_AXI1_RD_STALL_LIMIT, + ETHOSU_PMU_AXI1_WR_STALL_LIMIT, + ETHOSU_PMU_AXI_LATENCY_ANY, + ETHOSU_PMU_AXI_LATENCY_32, + ETHOSU_PMU_AXI_LATENCY_64, + ETHOSU_PMU_AXI_LATENCY_128, + ETHOSU_PMU_AXI_LATENCY_256, + ETHOSU_PMU_AXI_LATENCY_512, + ETHOSU_PMU_AXI_LATENCY_1024, + + ETHOSU_PMU_SENTINEL // End-marker (not event) +}; + +extern PMU_Ethosu_ctrl_Type *ethosu_pmu_ctrl; +extern PMU_Ethosu_cntr_Type *ethosu_pmu_cntr; +extern PMU_Ethosu_evnt_Type *ethosu_pmu_evnt; + +#define ETHOSU_PMU_CTRL_ENABLE_Msk (0x0001) +#define ETHOSU_PMU_CTRL_EVENTCNT_RESET_Msk (0x0002) +#define ETHOSU_PMU_CTRL_CYCCNT_RESET_Msk (0x0004) +#define ETHOSU_PMU_CNT1_Msk (1UL << 0) +#define ETHOSU_PMU_CNT2_Msk (1UL << 1) +#define ETHOSU_PMU_CNT3_Msk (1UL << 2) +#define ETHOSU_PMU_CNT4_Msk (1UL << 3) +#define ETHOSU_PMU_CCNT_Msk (1UL << 31) + +/* Transpose functions between HW-event-type and event-id*/ +enum ethosu_pmu_event_type pmu_event_type(uint32_t); +uint32_t pmu_event_value(enum ethosu_pmu_event_type); + +// CMSIS ref API +/** \brief PMU Functions */ + +__STATIC_INLINE void ETHOSU_PMU_Enable(void); +__STATIC_INLINE void ETHOSU_PMU_Disable(void); + +__STATIC_INLINE void ETHOSU_PMU_Set_EVTYPER(uint32_t num, enum ethosu_pmu_event_type type); +__STATIC_INLINE enum ethosu_pmu_event_type ETHOSU_PMU_Get_EVTYPER(uint32_t num); + +__STATIC_INLINE void ETHOSU_PMU_CYCCNT_Reset(void); +__STATIC_INLINE void ETHOSU_PMU_EVCNTR_ALL_Reset(void); + +__STATIC_INLINE void ETHOSU_PMU_CNTR_Enable(uint32_t mask); +__STATIC_INLINE void ETHOSU_PMU_CNTR_Disable(uint32_t mask); +__STATIC_INLINE uint32_t ETHOSU_PMU_CNTR_Status(); + +__STATIC_INLINE uint64_t ETHOSU_PMU_Get_CCNTR(void); +__STATIC_INLINE void ETHOSU_PMU_Set_CCNTR(uint64_t val); +__STATIC_INLINE uint32_t ETHOSU_PMU_Get_EVCNTR(uint32_t num); +__STATIC_INLINE void ETHOSU_PMU_Set_EVCNTR(uint32_t num, uint32_t val); + +__STATIC_INLINE uint32_t ETHOSU_PMU_Get_CNTR_OVS(void); +__STATIC_INLINE void ETHOSU_PMU_Set_CNTR_OVS(uint32_t mask); + +__STATIC_INLINE void ETHOSU_PMU_Set_CNTR_IRQ_Enable(uint32_t mask); +__STATIC_INLINE void ETHOSU_PMU_Set_CNTR_IRQ_Disable(uint32_t mask); +__STATIC_INLINE uint32_t ETHOSU_PMU_Get_IRQ_Enable(); + +__STATIC_INLINE void ETHOSU_PMU_CNTR_Increment(uint32_t mask); + +/** + \brief Enable the PMU +*/ +__STATIC_INLINE void ETHOSU_PMU_Enable(void) +{ + ethosu_pmu_ctrl->PMCR |= ETHOSU_PMU_CTRL_ENABLE_Msk; +} + +/** + \brief Disable the PMU +*/ +__STATIC_INLINE void ETHOSU_PMU_Disable(void) +{ + ethosu_pmu_ctrl->PMCR &= ~ETHOSU_PMU_CTRL_ENABLE_Msk; +} + +/** + \brief Set event to count for PMU eventer counter + \param [in] num Event counter (0-ETHOSU_PMU_NCOUNTERS) to configure + \param [in] type Event to count +*/ +__STATIC_INLINE void ETHOSU_PMU_Set_EVTYPER(uint32_t num, enum ethosu_pmu_event_type type) +{ + (*ethosu_pmu_evnt)[num] = pmu_event_value(type); +} + +/** + \brief Get event to count for PMU eventer counter + \param [in] num Event counter (0-ETHOSU_PMU_NCOUNTERS) to configure + \return type Event to count +*/ +__STATIC_INLINE enum ethosu_pmu_event_type ETHOSU_PMU_Get_EVTYPER(uint32_t num) +{ + return pmu_event_type((*ethosu_pmu_evnt)[num]); +} + +/** + \brief Reset cycle counter +*/ +__STATIC_INLINE void ETHOSU_PMU_CYCCNT_Reset(void) +{ + ethosu_pmu_ctrl->PMCR |= ETHOSU_PMU_CTRL_CYCCNT_RESET_Msk; +} + +/** + \brief Reset all event counters +*/ +__STATIC_INLINE void ETHOSU_PMU_EVCNTR_ALL_Reset(void) +{ + ethosu_pmu_ctrl->PMCR |= ETHOSU_PMU_CTRL_EVENTCNT_RESET_Msk; +} + +/** + \brief Enable counters + \param [in] mask Counters to enable + \note Enables one or more of the following: + - event counters (bit 0-ETHOSU_PMU_NCOUNTERS) + - cycle counter (bit 31) +*/ +__STATIC_INLINE void ETHOSU_PMU_CNTR_Enable(uint32_t mask) +{ + ethosu_pmu_ctrl->PMCNTENSET = mask; +} + +/** + \brief Disable counters + \param [in] mask Counters to disable + \note Disables one or more of the following: + - event counters (bit 0-ETHOSU_PMU_NCOUNTERS) + - cycle counter (bit 31) +*/ +__STATIC_INLINE void ETHOSU_PMU_CNTR_Disable(uint32_t mask) +{ + ethosu_pmu_ctrl->PMCNTENCLR = mask; +} + +/** + \brief Determine counters activation + + \return Event count + \param [in] mask Counters to enable + \return a bitmask where bit-set means: + - event counters activated (bit 0-ETHOSU_PMU_NCOUNTERS) + - cycle counter activate (bit 31) + \note ETHOSU specific. Usage breaks CMSIS complience +*/ +__STATIC_INLINE uint32_t ETHOSU_PMU_CNTR_Status() +{ + return ethosu_pmu_ctrl->PMCNTENSET; +} + +/** + \brief Read cycle counter (64 bit) + \return Cycle count + \note Two HW 32-bit registers that can increment independently in-between reads. + To work-around raciness yet still avoid turning + off the event both are read as one value twice. If the latter read + is not greater than the former, it means overflow of LSW without + incrementing MSW has occurred, in which case the former value is used. +*/ +__STATIC_INLINE uint64_t ETHOSU_PMU_Get_CCNTR(void) +{ + uint64_t val1 = ethosu_pmu_ctrl->PMCCNTR; + uint64_t val2 = ethosu_pmu_ctrl->PMCCNTR; + + if (val2 > val1) + { + return val2; + } + return val1; +} + +/** + \brief Set cycle counter (64 bit) + \param [in] val Conter value + \note Two HW 32-bit registers that can increment independently in-between reads. + To work-around raciness, counter is temporary disabled if enabled. + \note ETHOSU specific. Usage breaks CMSIS complience +*/ +__STATIC_INLINE void ETHOSU_PMU_Set_CCNTR(uint64_t val) +{ + uint32_t mask = ETHOSU_PMU_CNTR_Status(); + + if (mask & ETHOSU_PMU_CCNT_Msk) + { + ETHOSU_PMU_CNTR_Disable(ETHOSU_PMU_CCNT_Msk); + } + + ethosu_pmu_ctrl->PMCCNTR = val; + + if (mask & ETHOSU_PMU_CCNT_Msk) + { + ETHOSU_PMU_CNTR_Enable(ETHOSU_PMU_CCNT_Msk); + } +} + +/** + \brief Read event counter + \param [in] num Event counter (0-ETHOSU_PMU_NCOUNTERS) + \return Event count +*/ +__STATIC_INLINE uint32_t ETHOSU_PMU_Get_EVCNTR(uint32_t num) +{ + return (*ethosu_pmu_cntr)[num]; +} + +/** + \brief Set event counter value + \param [in] num Event counter (0-ETHOSU_PMU_NCOUNTERS) + \param [in] val Conter value + \note ETHOSU specific. Usage breaks CMSIS complience +*/ +__STATIC_INLINE void ETHOSU_PMU_Set_EVCNTR(uint32_t num, uint32_t val) +{ + (*ethosu_pmu_cntr)[num] = val; +} +/** + \brief Read counter overflow status + \return Counter overflow status bits for the following: + - event counters (bit 0-ETHOSU_PMU_NCOUNTERS)) + - cycle counter (bit 31) +*/ +__STATIC_INLINE uint32_t ETHOSU_PMU_Get_CNTR_OVS(void) +{ + return ethosu_pmu_ctrl->PMOVSSET; +} + +/** + \brief Clear counter overflow status + \param [in] mask Counter overflow status bits to clear + \note Clears overflow status bits for one or more of the following: + - event counters (bit 0-ETHOSU_PMU_NCOUNTERS) + - cycle counter (bit 31) +*/ +__STATIC_INLINE void ETHOSU_PMU_Set_CNTR_OVS(uint32_t mask) +{ + ethosu_pmu_ctrl->PMOVSCLR = mask; +} + +/** + \brief Enable counter overflow interrupt request + \param [in] mask Counter overflow interrupt request bits to set + \note Sets overflow interrupt request bits for one or more of the following: + - event counters (bit 0-ETHOSU_PMU_NCOUNTERS) + - cycle counter (bit 31) +*/ +__STATIC_INLINE void ETHOSU_PMU_Set_CNTR_IRQ_Enable(uint32_t mask) +{ + ethosu_pmu_ctrl->PMINTSET = mask; +} + +/** + \brief Disable counter overflow interrupt request + \param [in] mask Counter overflow interrupt request bits to clear + \note Clears overflow interrupt request bits for one or more of the following: + - event counters (bit 0-ETHOSU_PMU_NCOUNTERS) + - cycle counter (bit 31) +*/ +__STATIC_INLINE void ETHOSU_PMU_Set_CNTR_IRQ_Disable(uint32_t mask) +{ + ethosu_pmu_ctrl->PMINTCLR = mask; +} + +/** + \brief Get counters overflow interrupt request stiinings + \return mask Counter overflow interrupt request bits + \note Sets overflow interrupt request bits for one or more of the following: + - event counters (bit 0-ETHOSU_PMU_NCOUNTERS) + - cycle counter (bit 31) + \note ETHOSU specific. Usage breaks CMSIS complience +*/ +__STATIC_INLINE uint32_t ETHOSU_PMU_Get_IRQ_Enable() +{ + return ethosu_pmu_ctrl->PMINTSET; +} + +/** + \brief Software increment event counter + \param [in] mask Counters to increment + - event counters (bit 0-ETHOSU_PMU_NCOUNTERS) + - cycle counter (bit 31) + \note Software increment bits for one or more event counters. +*/ +__STATIC_INLINE void ETHOSU_PMU_CNTR_Increment(uint32_t mask) +{ + uint32_t cntrs_active = ETHOSU_PMU_CNTR_Status(); + + if (mask & ETHOSU_PMU_CCNT_Msk) + { + if (mask & ETHOSU_PMU_CCNT_Msk) + { + ETHOSU_PMU_CNTR_Disable(ETHOSU_PMU_CCNT_Msk); + ethosu_pmu_ctrl->PMCCNTR = ETHOSU_PMU_Get_CCNTR() + 1; + if (cntrs_active & ETHOSU_PMU_CCNT_Msk) + { + ETHOSU_PMU_CNTR_Enable(ETHOSU_PMU_CCNT_Msk); + } + } + } + for (int i = 0; i < ETHOSU_PMU_NCOUNTERS; i++) + { + uint32_t cntr = (0x0001 << i); + + if (mask & cntr) + { + ETHOSU_PMU_CNTR_Disable(cntr); + (*ethosu_pmu_cntr)[i]++; + if (cntrs_active & cntr) + { + ETHOSU_PMU_CNTR_Enable(cntr); + } + } + } +} + +#endif /* PMU_ETHOSU_H */ |