| /* |
| * Copyright (c) 2020 Intel Corporation |
| * |
| * SPDX-License-Identifier: Apache-2.0 |
| */ |
| |
| /** |
| * @file |
| * @brief EDAC API header file |
| */ |
| |
| #ifndef ZEPHYR_INCLUDE_DRIVERS_EDAC_H_ |
| #define ZEPHYR_INCLUDE_DRIVERS_EDAC_H_ |
| |
| #include <sys/types.h> |
| |
| typedef int (*edac_api_inject_set_param1_f)(const struct device *dev, |
| uint64_t addr); |
| typedef uint64_t (*edac_api_inject_get_param1_f)(const struct device *dev); |
| |
| typedef int (*edac_api_inject_set_param2_f)(const struct device *dev, |
| uint64_t mask); |
| typedef uint64_t (*edac_api_inject_get_param2_f)(const struct device *dev); |
| |
| typedef int (*edac_api_inject_set_error_type_f)(const struct device *dev, |
| uint32_t error_type); |
| typedef uint32_t (*edac_api_inject_get_error_type_f)(const struct device *dev); |
| |
| typedef int (*edac_api_inject_error_trigger_f)(const struct device *dev); |
| |
| typedef uint64_t (*edac_api_ecc_error_log_get_f)(const struct device *dev); |
| typedef void (*edac_api_ecc_error_log_clear_f)(const struct device *dev); |
| |
| typedef uint64_t (*edac_api_parity_error_log_get_f)(const struct device *dev); |
| typedef void (*edac_api_parity_error_log_clear_f)(const struct device *dev); |
| |
| typedef unsigned int (*edac_api_errors_cor_get_f)(const struct device *dev); |
| typedef unsigned int (*edac_api_errors_uc_get_f)(const struct device *dev); |
| |
| typedef void (*edac_notify_callback_f)(const struct device *dev, |
| void *data); |
| typedef int (*edac_api_notify_cb_set_f)(const struct device *dev, |
| edac_notify_callback_f cb); |
| |
| /** |
| * @defgroup edac Zephyr API |
| * @{ |
| */ |
| |
| /** @brief Correctable error type */ |
| #define EDAC_ERROR_TYPE_DRAM_COR BIT(0) |
| /** @brief Uncorrectable error type */ |
| #define EDAC_ERROR_TYPE_DRAM_UC BIT(1) |
| |
| /** |
| * @brief EDAC driver API |
| * |
| * This is the mandatory API any EDAC driver needs to expose. |
| */ |
| __subsystem struct edac_driver_api { |
| #if defined(CONFIG_EDAC_ERROR_INJECT) |
| /* Error Injection API is disabled by default */ |
| edac_api_inject_set_param1_f inject_set_param1; |
| edac_api_inject_get_param1_f inject_get_param1; |
| edac_api_inject_set_param2_f inject_set_param2; |
| edac_api_inject_get_param2_f inject_get_param2; |
| edac_api_inject_get_error_type_f inject_get_error_type; |
| edac_api_inject_set_error_type_f inject_set_error_type; |
| edac_api_inject_error_trigger_f inject_error_trigger; |
| #endif /* CONFIG_EDAC_ERROR_INJECT */ |
| |
| /* Error Logging API */ |
| edac_api_ecc_error_log_get_f ecc_error_log_get; |
| edac_api_ecc_error_log_clear_f ecc_error_log_clear; |
| edac_api_parity_error_log_get_f parity_error_log_get; |
| edac_api_parity_error_log_clear_f parity_error_log_clear; |
| |
| /* Error stats API */ |
| edac_api_errors_cor_get_f errors_cor_get; |
| edac_api_errors_uc_get_f errors_uc_get; |
| |
| /* Notification callback API */ |
| edac_api_notify_cb_set_f notify_cb_set; |
| }; |
| |
| #if defined(CONFIG_EDAC_ERROR_INJECT) |
| |
| /** |
| * @brief Set injection parameter param1 |
| * |
| * This parameter is used to set first error injection parameter value. |
| * |
| * @param dev Pointer to the device structure |
| * @param addr Injection address base |
| * @return 0 on success, error code otherwise |
| */ |
| static inline int edac_inject_set_param1(const struct device *dev, |
| uint64_t addr) |
| { |
| const struct edac_driver_api *api = |
| (const struct edac_driver_api *)dev->api; |
| |
| return api->inject_set_param1(dev, addr); |
| } |
| |
| /** |
| * @brief Get injection parameter param1 |
| * |
| * Get first error injection parameter value. |
| * |
| * @param dev Pointer to the device structure |
| * @return Injection parameter param1 |
| */ |
| static inline uint64_t edac_inject_get_param1(const struct device *dev) |
| { |
| const struct edac_driver_api *api = |
| (const struct edac_driver_api *)dev->api; |
| |
| return api->inject_get_param1(dev); |
| |
| } |
| |
| /** |
| * @brief Set injection parameter param2 |
| * |
| * This parameter is used to set second error injection parameter value. |
| * |
| * @param dev Pointer to the device structure |
| * @param addr Injection address mask |
| * @return 0 on success, error code otherwise |
| */ |
| static inline int edac_inject_set_param2(const struct device *dev, |
| uint64_t mask) |
| { |
| const struct edac_driver_api *api = |
| (const struct edac_driver_api *)dev->api; |
| |
| return api->inject_set_param2(dev, mask); |
| } |
| |
| /** |
| * @brief Get injection parameter param2 |
| * |
| * @param dev Pointer to the device structure |
| * @return Injection parameter param2 |
| */ |
| static inline uint64_t edac_inject_get_param2(const struct device *dev) |
| { |
| const struct edac_driver_api *api = |
| (const struct edac_driver_api *)dev->api; |
| |
| return api->inject_get_param2(dev); |
| |
| } |
| |
| /** |
| * @brief Set error type value |
| * |
| * Set the value of error type to be injected |
| * |
| * @param dev Pointer to the device structure |
| * @param error_type Error type value |
| * @return 0 on success, error code otherwise |
| */ |
| static inline int edac_inject_set_error_type(const struct device *dev, |
| uint32_t error_type) |
| { |
| const struct edac_driver_api *api = |
| (const struct edac_driver_api *)dev->api; |
| |
| return api->inject_set_error_type(dev, error_type); |
| } |
| |
| /** |
| * @brief Get error type value |
| * |
| * Get the value of error type to be injected |
| * |
| * @param dev Pointer to the device structure |
| * @return error_type Error type value |
| */ |
| static inline uint32_t edac_inject_get_error_type(const struct device *dev) |
| { |
| const struct edac_driver_api *api = |
| (const struct edac_driver_api *)dev->api; |
| |
| return api->inject_get_error_type(dev); |
| } |
| |
| /** |
| * @brief Set injection control |
| * |
| * Set injection control register to the value provided. |
| * |
| * @param dev Pointer to the device structure |
| * @param addr Injection control value |
| * @return 0 on success, error code otherwise |
| */ |
| static inline int edac_inject_error_trigger(const struct device *dev) |
| { |
| const struct edac_driver_api *api = |
| (const struct edac_driver_api *)dev->api; |
| |
| return api->inject_error_trigger(dev); |
| } |
| |
| #endif /* CONFIG_EDAC_ERROR_INJECT */ |
| |
| /** |
| * @brief Get ECC Error Log |
| * |
| * Read value of ECC Error Log |
| * |
| * @param dev Pointer to the device structure |
| * @return ECC Error Log value |
| */ |
| static inline uint64_t edac_ecc_error_log_get(const struct device *dev) |
| { |
| const struct edac_driver_api *api = |
| (const struct edac_driver_api *)dev->api; |
| |
| return api->ecc_error_log_get(dev); |
| } |
| |
| /** |
| * @brief Clear ECC Error Log |
| * |
| * Clear value of ECC Error Log |
| * |
| * @param dev Pointer to the device structure |
| */ |
| static inline void edac_ecc_error_log_clear(const struct device *dev) |
| { |
| const struct edac_driver_api *api = |
| (const struct edac_driver_api *)dev->api; |
| |
| api->ecc_error_log_clear(dev); |
| } |
| |
| /** |
| * @brief Get Parity Error Log |
| * |
| * Read value of Parity Error Log |
| * |
| * @param dev Pointer to the device structure |
| * @return Parity Error Log value |
| */ |
| static inline uint64_t edac_parity_error_log_get(const struct device *dev) |
| { |
| const struct edac_driver_api *api = |
| (const struct edac_driver_api *)dev->api; |
| |
| return api->parity_error_log_get(dev); |
| } |
| |
| /** |
| * @brief Clear Parity Error Log |
| * |
| * Clear value of Parity Error Log |
| * |
| * @param dev Pointer to the device structure |
| */ |
| static inline void edac_parity_error_log_clear(const struct device *dev) |
| { |
| const struct edac_driver_api *api = |
| (const struct edac_driver_api *)dev->api; |
| |
| api->parity_error_log_clear(dev); |
| } |
| |
| /** |
| * @brief Get number of correctable errors |
| * |
| * @param dev Pointer to the device structure |
| * @return Number of correctable errors |
| */ |
| static inline unsigned int edac_errors_cor_get(const struct device *dev) |
| { |
| const struct edac_driver_api *api = |
| (const struct edac_driver_api *)dev->api; |
| |
| return api->errors_cor_get(dev); |
| } |
| |
| /** |
| * @brief Get number of uncorrectable errors |
| * |
| * @param dev Pointer to the device structure |
| * @return Number of uncorrectable errors |
| */ |
| static inline unsigned int edac_errors_uc_get(const struct device *dev) |
| { |
| const struct edac_driver_api *api = |
| (const struct edac_driver_api *)dev->api; |
| |
| return api->errors_uc_get(dev); |
| } |
| |
| /** |
| * Register callback function for memory error exception |
| * |
| * This callback runs in interrupt context |
| * |
| * @param dev EDAC driver device to install callback |
| * @param cb Callback function pointer |
| * @return 0 Success, nonzero if an error occurred |
| */ |
| static inline int edac_notify_callback_set(const struct device *dev, |
| edac_notify_callback_f cb) |
| { |
| const struct edac_driver_api *api = dev->api; |
| |
| return api->notify_cb_set(dev, cb); |
| } |
| |
| /** |
| * @} |
| */ |
| |
| #endif /* ZEPHYR_INCLUDE_DRIVERS_EDAC_H_ */ |