From 4dc73dcea25d951971ae306481d1f201c8d6ebdd Mon Sep 17 00:00:00 2001 From: Kristofer Jonsson Date: Fri, 16 Oct 2020 12:33:47 +0200 Subject: PMU counter shadow Storing PMU counters in shadow variables, in case the PMU was powered off or soft reset. Change-Id: I64ccf3fb6195f9be2d8315891ec612bb75404885 --- include/ethosu_device.h | 21 +++- include/ethosu_driver.h | 6 ++ include/pmu_ethosu.h | 254 ++++++++++++++++++++++++------------------------ 3 files changed, 153 insertions(+), 128 deletions(-) (limited to 'include') diff --git a/include/ethosu_device.h b/include/ethosu_device.h index 5edba94..91aa877 100644 --- a/include/ethosu_device.h +++ b/include/ethosu_device.h @@ -54,15 +54,15 @@ enum ethosu_error_codes struct ethosu_device { - uintptr_t base_address; + volatile uint32_t *base_address; uint32_t reset; uint32_t pmcr; - uint64_t pmccntr; + uint32_t pmccntr[2]; uint32_t pmcnten; uint32_t pmint; uint32_t pmccntr_cfg; uint32_t pmu_evcntr[ETHOSU_PMU_NCOUNTERS]; - enum ethosu_pmu_event_type pmu_evtypr[ETHOSU_PMU_NCOUNTERS]; + uint32_t pmu_evtypr[ETHOSU_PMU_NCOUNTERS]; }; struct ethosu_id @@ -377,6 +377,13 @@ uint32_t ethosu_read_reg(struct ethosu_device *dev, uint32_t address); */ void ethosu_write_reg(struct ethosu_device *dev, uint32_t address, uint32_t value); +/** + * Write register with shadow variable. + * \param[in] address Address to read. + * \param[in] value Value to be written. + */ +void ethosu_write_reg_shadow(struct ethosu_device *dev, uint32_t address, uint32_t value, uint32_t *shadow); + /** * Save the PMU configuration to ethosu_device struct. * \param[in] dev Ethos-U device where the PMU configuration is @@ -393,6 +400,14 @@ enum ethosu_error_codes ethosu_save_pmu_config(struct ethosu_device *dev); */ enum ethosu_error_codes ethosu_restore_pmu_config(struct ethosu_device *dev); +/** + * Save PMU counters to shadow variables in memory. + * \param[in] dev Ethos-U device where the PMU configuration is + * stored. + * \return \ref ethosu_error_codes + */ +enum ethosu_error_codes ethosu_save_pmu_counters(struct ethosu_device *dev); + /** * Check if the STATUS register has any error bits set or not. * \param[in] dev Ethos-U device to check. diff --git a/include/ethosu_driver.h b/include/ethosu_driver.h index 2594fbe..433ad06 100644 --- a/include/ethosu_driver.h +++ b/include/ethosu_driver.h @@ -76,6 +76,12 @@ struct ethosu_version struct ethosu_version_config cfg; }; +/****************************************************************************** + * Variables + ******************************************************************************/ + +extern struct ethosu_driver ethosu_drv; + /****************************************************************************** * Prototypes ******************************************************************************/ diff --git a/include/pmu_ethosu.h b/include/pmu_ethosu.h index 7eb5c09..78d46ee 100644 --- a/include/pmu_ethosu.h +++ b/include/pmu_ethosu.h @@ -19,14 +19,32 @@ #ifndef PMU_ETHOSU_H #define PMU_ETHOSU_H +/***************************************************************************** + * Includes + *****************************************************************************/ + #include #ifdef __cplusplus extern "C" { #endif +/***************************************************************************** + * Defines + *****************************************************************************/ + #define ETHOSU_PMU_NCOUNTERS 4 +#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) + +/***************************************************************************** + * Types + *****************************************************************************/ + /** \brief HW Supported ETHOSU PMU Events * * Note: These values are symbolic. Actual HW-values may change. I.e. always use API @@ -112,193 +130,179 @@ enum ethosu_pmu_event_type ETHOSU_PMU_SENTINEL // End-marker (not event) }; -#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); - -/* Initialize the PMU driver */ -void ethosu_pmu_driver_init(void); - -void ethosu_pmu_driver_exit(void); - -// CMSIS ref API -/** \brief PMU Functions */ +/***************************************************************************** + * Functions + *****************************************************************************/ /** - \brief Enable the PMU -*/ + * \brief Enable the PMU + */ void ETHOSU_PMU_Enable(void); /** - \brief Disable the PMU -*/ + * \brief Disable the PMU + */ 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 -*/ + * \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 + */ 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 -*/ + * \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 + */ enum ethosu_pmu_event_type ETHOSU_PMU_Get_EVTYPER(uint32_t num); /** - \brief Reset cycle counter -*/ + * \brief Reset cycle counter + */ void ETHOSU_PMU_CYCCNT_Reset(void); /** - \brief Reset all event counters -*/ + * \brief Reset all event counters + */ void ETHOSU_PMU_EVCNTR_ALL_Reset(void); /** - \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) -*/ + * \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) + */ void ETHOSU_PMU_CNTR_Enable(uint32_t 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) -*/ + * \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) + */ void ETHOSU_PMU_CNTR_Disable(uint32_t 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 -*/ + * \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 + */ uint32_t ETHOSU_PMU_CNTR_Status(void); /** - \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. -*/ + * \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. + */ uint64_t ETHOSU_PMU_Get_CCNTR(void); /** - \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 -*/ + * \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 + */ void ETHOSU_PMU_Set_CCNTR(uint64_t val); /** - \brief Read event counter - \param [in] num Event counter (0-ETHOSU_PMU_NCOUNTERS) - \return Event count -*/ + * \brief Read event counter + * \param [in] num Event counter (0-ETHOSU_PMU_NCOUNTERS) + * \return Event count + */ uint32_t ETHOSU_PMU_Get_EVCNTR(uint32_t 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 -*/ + * \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 + */ 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) -*/ + * \brief Read counter overflow status + * \return Counter overflow status bits for the following: + * - event counters (bit 0-ETHOSU_PMU_NCOUNTERS)) + * - cycle counter (bit 31) + */ uint32_t ETHOSU_PMU_Get_CNTR_OVS(void); /** - \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) -*/ + * \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) + */ void ETHOSU_PMU_Set_CNTR_OVS(uint32_t 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) -*/ + * \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) + */ void ETHOSU_PMU_Set_CNTR_IRQ_Enable(uint32_t 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) -*/ + * \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) + */ void ETHOSU_PMU_Set_CNTR_IRQ_Disable(uint32_t 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 compliance -*/ + * \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 compliance + */ uint32_t ETHOSU_PMU_Get_IRQ_Enable(void); /** - \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. -*/ + * \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. + */ void ETHOSU_PMU_CNTR_Increment(uint32_t mask); /** - \brief Set start event number for the cycle counter - \param [in] start_event Event number - - Start event (bits [9:0]) - \note Sets the event number that starts the cycle counter. - - Event number in the range 0..1023 -*/ + * \brief Set start event number for the cycle counter + * \param [in] start_event Event number + * - Start event (bits [9:0]) + * \note Sets the event number that starts the cycle counter. + * - Event number in the range 0..1023 + */ void ETHOSU_PMU_PMCCNTR_CFG_Set_Start_Event(uint32_t start_event); /** - \brief Set stop event number for the cycle counter - \param [in] stop_event Event number - - Stop event (bits [25:16]) - \note Sets the event number that stops the cycle counter. - - Event number in the range 0..1023 -*/ + * \brief Set stop event number for the cycle counter + * \param [in] stop_event Event number + * - Stop event (bits [25:16]) + * \note Sets the event number that stops the cycle counter. + * - Event number in the range 0..1023 + */ void ETHOSU_PMU_PMCCNTR_CFG_Set_Stop_Event(uint32_t stop_event); #ifdef __cplusplus -- cgit v1.2.1