Move PMU functions from pmu_ethosu.h to ethosu_pmu.c

This change is done as a prerequisite to be able to set
base address for NPU through ethosu_init(). So instead of using
a mamory mapped struct we use the same functions to read/write
PMU registers as the rest of the ethos-u driver.

Change-Id: Ie1f6e6af4627cbe9375e2b2d079ba8017b6294d3
diff --git a/include/pmu_ethosu.h b/include/pmu_ethosu.h
index 300a44a..64cd565 100644
--- a/include/pmu_ethosu.h
+++ b/include/pmu_ethosu.h
@@ -27,22 +27,6 @@
 
 #define ETHOSU_PMU_NCOUNTERS 4
 
-typedef volatile struct
-{
-    uint32_t PMCR;
-    uint32_t PMCNTENSET;
-    uint32_t PMCNTENCLR;
-    uint32_t PMOVSSET;
-    uint32_t PMOVSCLR;
-    uint32_t PMINTSET;
-    uint32_t PMINTCLR;
-    uint64_t PMCCNTR;
-    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
@@ -125,106 +109,55 @@
     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)
-#define ETHOSU_PMCCNTR_CFG_START_EVENT_MASK (0x3FF)
-#define ETHOSU_PMCCNTR_CFG_STOP_EVENT_MASK (0x3FF << 16)
 
 /* 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);
 
+/* Initialize the PMU driver */
+void ethosu_pmu_driver_init(void);
+
 // 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;
-}
+void ETHOSU_PMU_Enable(void);
 
 /**
   \brief   Disable the PMU
 */
-static inline void ETHOSU_PMU_Disable(void)
-{
-    ethosu_pmu_ctrl->PMCR &= ~ETHOSU_PMU_CTRL_ENABLE_Msk;
-}
+void ETHOSU_PMU_Disable(void);
 
 /**
   \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);
-}
+void ETHOSU_PMU_Set_EVTYPER(uint32_t num, enum ethosu_pmu_event_type 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]);
-}
+enum ethosu_pmu_event_type ETHOSU_PMU_Get_EVTYPER(uint32_t num);
 
 /**
   \brief  Reset cycle counter
 */
-static inline void ETHOSU_PMU_CYCCNT_Reset(void)
-{
-    ethosu_pmu_ctrl->PMCR |= ETHOSU_PMU_CTRL_CYCCNT_RESET_Msk;
-}
+void ETHOSU_PMU_CYCCNT_Reset(void);
 
 /**
   \brief  Reset all event counters
 */
-static inline void ETHOSU_PMU_EVCNTR_ALL_Reset(void)
-{
-    ethosu_pmu_ctrl->PMCR |= ETHOSU_PMU_CTRL_EVENTCNT_RESET_Msk;
-}
+void ETHOSU_PMU_EVCNTR_ALL_Reset(void);
 
 /**
   \brief  Enable counters
@@ -233,10 +166,7 @@
           - 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;
-}
+void ETHOSU_PMU_CNTR_Enable(uint32_t mask);
 
 /**
   \brief  Disable counters
@@ -245,10 +175,7 @@
           - 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;
-}
+void ETHOSU_PMU_CNTR_Disable(uint32_t mask);
 
 /**
   \brief  Determine counters activation
@@ -260,10 +187,7 @@
           - 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;
-}
+uint32_t ETHOSU_PMU_CNTR_Status();
 
 /**
   \brief  Read cycle counter (64 bit)
@@ -274,17 +198,7 @@
           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;
-}
+uint64_t ETHOSU_PMU_Get_CCNTR(void);
 
 /**
   \brief  Set cycle counter (64 bit)
@@ -293,32 +207,14 @@
           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);
-    }
-}
+void ETHOSU_PMU_Set_CCNTR(uint64_t val);
 
 /**
   \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];
-}
+uint32_t ETHOSU_PMU_Get_EVCNTR(uint32_t num);
 
 /**
   \brief   Set event counter value
@@ -326,20 +222,15 @@
   \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;
-}
+void ETHOSU_PMU_Set_EVCNTR(uint32_t num, uint32_t 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;
-}
+uint32_t ETHOSU_PMU_Get_CNTR_OVS(void);
 
 /**
   \brief   Clear counter overflow status
@@ -348,10 +239,7 @@
            - 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;
-}
+void ETHOSU_PMU_Set_CNTR_OVS(uint32_t mask);
 
 /**
   \brief   Enable counter overflow interrupt request
@@ -360,10 +248,7 @@
            - 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;
-}
+void ETHOSU_PMU_Set_CNTR_IRQ_Enable(uint32_t mask);
 
 /**
   \brief   Disable counter overflow interrupt request
@@ -372,10 +257,7 @@
            - 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;
-}
+void ETHOSU_PMU_Set_CNTR_IRQ_Disable(uint32_t mask);
 
 /**
   \brief   Get counters overflow interrupt request stiinings
@@ -385,10 +267,7 @@
            - 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;
-}
+uint32_t ETHOSU_PMU_Get_IRQ_Enable();
 
 /**
   \brief   Software increment event counter
@@ -397,37 +276,7 @@
            - 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);
-            }
-        }
-    }
-}
+void ETHOSU_PMU_CNTR_Increment(uint32_t mask);
 
 /**
   \brief   Set start event number for the cycle counter
@@ -436,11 +285,7 @@
   \note   Sets the event number that starts the cycle counter.
             - Event number in the range 0..1023
 */
-static inline void ETHOSU_PMU_PMCCNTR_CFG_Set_Start_Event(uint32_t start_event)
-{
-    uint32_t val                 = ethosu_pmu_ctrl->PMCCNTR_CFG & ~ETHOSU_PMCCNTR_CFG_START_EVENT_MASK;
-    ethosu_pmu_ctrl->PMCCNTR_CFG = val | (start_event & ETHOSU_PMCCNTR_CFG_START_EVENT_MASK);
-}
+void ETHOSU_PMU_PMCCNTR_CFG_Set_Start_Event(uint32_t start_event);
 
 /**
   \brief   Set stop event number for the cycle counter
@@ -449,11 +294,7 @@
   \note   Sets the event number that stops the cycle counter.
             - Event number in the range 0..1023
 */
-static inline void ETHOSU_PMU_PMCCNTR_CFG_Set_Stop_Event(uint32_t stop_event)
-{
-    uint32_t val                 = ethosu_pmu_ctrl->PMCCNTR_CFG & ~ETHOSU_PMCCNTR_CFG_STOP_EVENT_MASK;
-    ethosu_pmu_ctrl->PMCCNTR_CFG = val | ((stop_event << 16) & ETHOSU_PMCCNTR_CFG_STOP_EVENT_MASK);
-}
+void ETHOSU_PMU_PMCCNTR_CFG_Set_Stop_Event(uint32_t stop_event);
 
 #ifdef __cplusplus
 }
diff --git a/src/ethosu_common.h b/src/ethosu_common.h
index 58fa1c6..7c33470 100644
--- a/src/ethosu_common.h
+++ b/src/ethosu_common.h
@@ -48,6 +48,9 @@
 #define VER_STR(X) VNUM_STR(X)
 #define VNUM_STR(X) #X
 
+#define MASK_0_31_BITS (0xFFFFFFFF)
+#define MASK_32_47_BITS (0xFFFF00000000)
+
 static const __attribute__((section("npu_driver_version"))) char driver_version_str[] = VER_STR(
     ETHOSU_DRIVER_VERSION_MAJOR) "." VER_STR(ETHOSU_DRIVER_VERSION_MINOR) "." VER_STR(ETHOSU_DRIVER_VERSION_PATCH);
 
diff --git a/src/ethosu_device.c b/src/ethosu_device.c
index cc8ca12..a75a8f6 100644
--- a/src/ethosu_device.c
+++ b/src/ethosu_device.c
@@ -21,8 +21,6 @@
 #include <assert.h>
 #include <stdio.h>
 
-#define MASK_0_31_BITS 0xFFFFFFFF
-#define MASK_32_47_BITS 0xFFFF00000000
 #define BASEP_OFFSET 4
 #define REG_OFFSET 4
 #define BYTES_1KB 1024
diff --git a/src/ethosu_pmu.c b/src/ethosu_pmu.c
index 5e5490c..1d3b66c 100644
--- a/src/ethosu_pmu.c
+++ b/src/ethosu_pmu.c
@@ -34,24 +34,21 @@
 #define COMMA ,
 #define SEMICOLON ;
 
-#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 EVTYPE(A, name)                                                                                                \
     case PMU_EVENT_TYPE_##name:                                                                                        \
         return ETHOSU_PMU_##name
 
 #define EVID(A, name) (PMU_EVENT_TYPE_##name)
 
+#define ETHOSU_PMCCNTR_CFG_START_STOP_EVENT_MASK (0x3FF)
+
+#define NPU_REG_PMEVCNTR(x) (NPU_REG_PMEVCNTR0 + ((x) * sizeof(uint32_t)))
+#define NPU_REG_PMEVTYPER(x) (NPU_REG_PMEVTYPER0 + ((x) * sizeof(uint32_t)))
+
 /*****************************************************************************
  * Variables
  *****************************************************************************/
 
-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;
-
 static const enum pmu_event_type eventbyid[] = {EXPAND_PMU_EVENT_TYPE(EVID, COMMA)};
 
 /*****************************************************************************
@@ -81,22 +78,198 @@
 void ethosu_pmu_driver_init(void)
 {
 #ifdef PMU_AUTOINIT
-    *ethosu_pmu_ctrl = (PMU_Ethosu_ctrl_Type){.PMCR        = INIT_PMCR,
-                                              .PMCNTENSET  = INIT_PMCNTENSET,
-                                              .PMCNTENCLR  = INIT_PMCNTENCLR,
-                                              .PMOVSSET    = INIT_PMOVSSET,
-                                              .PMOVSCLR    = INIT_PMOVSCLR,
-                                              .PMINTSET    = INIT_PMINTSET,
-                                              .PMINTCLR    = INIT_PMINTCLR,
-                                              .PMCCNTR     = INIT_PMCCNTR,
-                                              .PMCCNTR_CFG = INIT_PMCCNTR_CFG};
+    write_reg(NPU_REG_PMCR, INIT_PMCR);
+    write_reg(NPU_REG_PMCNTENSET, INIT_PMCNTENSET);
+    write_reg(NPU_REG_PMCNTENCLR, INIT_PMCNTENCLR);
+    write_reg(NPU_REG_PMOVSSET, INIT_PMOVSSET);
+    write_reg(NPU_REG_PMOVSCLR, INIT_PMOVSCLR);
+    write_reg(NPU_REG_PMINTSET, INIT_PMINTSET);
+    write_reg(NPU_REG_PMINTCLR, INIT_PMINTCLR);
+    write_reg(NPU_REG_PMCCNTR_LO, INIT_PMCCNTR);
+    write_reg(NPU_REG_PMCCNTR_HI, INIT_PMCCNTR);
+    write_reg(NPU_REG_PMCCNTR_CFG, INIT_PMCCNTR_CFG);
 
     for (int i = 0; i < ETHOSU_PMU_NCOUNTERS; i++)
     {
-        *ethosu_pmu_cntr[i] = 0;
-        *ethosu_pmu_evnt[i] = 0;
+        write_reg(NPU_REG_PMEVCNTR(i), 0);
+        write_reg(NPU_REG_PMEVTYPER(i), 0);
     }
 #endif
 }
 
 void ethosu_pmu_driver_exit(void) {}
+
+void ETHOSU_PMU_Enable(void)
+{
+    struct pmcr_r pmcr;
+    pmcr.word   = read_reg(NPU_REG_PMCR);
+    pmcr.cnt_en = 1;
+    write_reg(NPU_REG_PMCR, pmcr.word);
+}
+
+void ETHOSU_PMU_Disable(void)
+{
+    struct pmcr_r pmcr;
+    pmcr.word   = read_reg(NPU_REG_PMCR);
+    pmcr.cnt_en = 0;
+    write_reg(NPU_REG_PMCR, pmcr.word);
+}
+
+void ETHOSU_PMU_Set_EVTYPER(uint32_t num, enum ethosu_pmu_event_type type)
+{
+    write_reg(NPU_REG_PMEVTYPER(num), pmu_event_value(type));
+}
+
+enum ethosu_pmu_event_type ETHOSU_PMU_Get_EVTYPER(uint32_t num)
+{
+    return pmu_event_type(read_reg(NPU_REG_PMEVTYPER(num)));
+}
+
+void ETHOSU_PMU_CYCCNT_Reset(void)
+{
+    struct pmcr_r pmcr;
+    pmcr.word          = read_reg(NPU_REG_PMCR);
+    pmcr.cycle_cnt_rst = 1;
+    write_reg(NPU_REG_PMCR, pmcr.word);
+}
+
+void ETHOSU_PMU_EVCNTR_ALL_Reset(void)
+{
+    struct pmcr_r pmcr;
+    pmcr.word          = read_reg(NPU_REG_PMCR);
+    pmcr.event_cnt_rst = 1;
+    write_reg(NPU_REG_PMCR, pmcr.word);
+}
+
+void ETHOSU_PMU_CNTR_Enable(uint32_t mask)
+{
+    write_reg(NPU_REG_PMCNTENSET, mask);
+}
+
+void ETHOSU_PMU_CNTR_Disable(uint32_t mask)
+{
+    write_reg(NPU_REG_PMCNTENCLR, mask);
+}
+
+uint32_t ETHOSU_PMU_CNTR_Status()
+{
+    return read_reg(NPU_REG_PMCNTENSET);
+}
+
+uint64_t ETHOSU_PMU_Get_CCNTR(void)
+{
+    uint64_t val1 = (((uint64_t)read_reg(NPU_REG_PMCCNTR_HI)) << 32) | read_reg(NPU_REG_PMCCNTR_LO);
+    uint64_t val2 = (((uint64_t)read_reg(NPU_REG_PMCCNTR_HI)) << 32) | read_reg(NPU_REG_PMCCNTR_LO);
+
+    if (val2 > val1)
+    {
+        return val2;
+    }
+    return val1;
+}
+
+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);
+    }
+
+    write_reg(NPU_REG_PMCCNTR_LO, (val & MASK_0_31_BITS));
+    write_reg(NPU_REG_PMCCNTR_HI, (val & MASK_32_47_BITS) >> 32);
+
+    if (mask & ETHOSU_PMU_CCNT_Msk)
+    {
+        ETHOSU_PMU_CNTR_Enable(ETHOSU_PMU_CCNT_Msk);
+    }
+}
+
+uint32_t ETHOSU_PMU_Get_EVCNTR(uint32_t num)
+{
+    return read_reg(NPU_REG_PMEVCNTR(num));
+}
+
+void ETHOSU_PMU_Set_EVCNTR(uint32_t num, uint32_t val)
+{
+    write_reg(NPU_REG_PMEVCNTR(num), val);
+}
+
+uint32_t ETHOSU_PMU_Get_CNTR_OVS(void)
+{
+    return read_reg(NPU_REG_PMOVSSET);
+}
+
+// TODO: check if this function name match with the description &
+// implementation.
+void ETHOSU_PMU_Set_CNTR_OVS(uint32_t mask)
+{
+    write_reg(NPU_REG_PMOVSCLR, mask);
+}
+
+void ETHOSU_PMU_Set_CNTR_IRQ_Enable(uint32_t mask)
+{
+    write_reg(NPU_REG_PMINTSET, mask);
+}
+
+void ETHOSU_PMU_Set_CNTR_IRQ_Disable(uint32_t mask)
+{
+    write_reg(NPU_REG_PMINTCLR, mask);
+}
+
+uint32_t ETHOSU_PMU_Get_IRQ_Enable()
+{
+    return read_reg(NPU_REG_PMINTSET);
+}
+
+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);
+            uint64_t val = ETHOSU_PMU_Get_CCNTR() + 1;
+            write_reg(NPU_REG_PMCCNTR_LO, (val & MASK_0_31_BITS));
+            write_reg(NPU_REG_PMCCNTR_HI, (val & MASK_32_47_BITS) >> 32);
+            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);
+            uint32_t val = read_reg(NPU_REG_PMEVCNTR(i));
+            write_reg(NPU_REG_PMEVCNTR(i), val + 1);
+            if (cntrs_active & cntr)
+            {
+                ETHOSU_PMU_CNTR_Enable(cntr);
+            }
+        }
+    }
+}
+
+void ETHOSU_PMU_PMCCNTR_CFG_Set_Start_Event(uint32_t start_event)
+{
+    struct pmccntr_cfg_r cfg;
+    cfg.word                = read_reg(NPU_REG_PMCCNTR_CFG);
+    cfg.CYCLE_CNT_CFG_START = start_event & ETHOSU_PMCCNTR_CFG_START_STOP_EVENT_MASK;
+    write_reg(NPU_REG_PMCCNTR_CFG, cfg.word);
+}
+
+void ETHOSU_PMU_PMCCNTR_CFG_Set_Stop_Event(uint32_t stop_event)
+{
+    struct pmccntr_cfg_r cfg;
+    cfg.word               = read_reg(NPU_REG_PMCCNTR_CFG);
+    cfg.CYCLE_CNT_CFG_STOP = stop_event & ETHOSU_PMCCNTR_CFG_START_STOP_EVENT_MASK;
+    write_reg(NPU_REG_PMCCNTR_CFG, cfg.word);
+}