/* SPDX-License-Identifier: MIT */ /* * Copyright 2025 Advanced Micro Devices, Inc. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * */ #ifndef __RAS_UMC_H__ #define __RAS_UMC_H__ #include "ras.h" #include "eeprom.h" #include "cmd.h" #define UMC_VRAM_TYPE_UNKNOWN 0 #define UMC_VRAM_TYPE_GDDR1 1 #define UMC_VRAM_TYPE_DDR2 2 #define UMC_VRAM_TYPE_GDDR3 3 #define UMC_VRAM_TYPE_GDDR4 4 #define UMC_VRAM_TYPE_GDDR5 5 #define UMC_VRAM_TYPE_HBM 6 #define UMC_VRAM_TYPE_DDR3 7 #define UMC_VRAM_TYPE_DDR4 8 #define UMC_VRAM_TYPE_GDDR6 9 #define UMC_VRAM_TYPE_DDR5 10 #define UMC_VRAM_TYPE_LPDDR4 11 #define UMC_VRAM_TYPE_LPDDR5 12 #define UMC_VRAM_TYPE_HBM3E 13 #define UMC_ECC_NEW_DETECTED_TAG 0x1 #define UMC_INV_MEM_PFN (0xFFFFFFFFFFFFFFFF) /* invalid node instance value */ #define UMC_INV_AID_NODE 0xffff /* * a flag to indicate v2 format channel index stored in eeprom * * v1: store channel index within a umc instance in eeprom * range in UMC v12: 0 ~ 7 * v2: store global channel index in eeprom * range in UMC v12: 0 ~ 127 * * NOTE: it's better to store it in eeprom_table_record.mem_channel, * but there is only 8 bits in mem_channel, and the channel number may * increase in the future, we decide to save it in * eeprom_table_record.retired_page. retired_page is useless in v2, * we depend on eeprom_table_record.address instead of retired_page in v2. * Only 48 bits are saved on eeprom, use bit 47 here. * * UMC_CHANNEL_IDX_V2 is replaced by nps value in cur_nps_retired_row_pfn * in eeprom v3 format, so they have no conflict. */ #define UMC_CHANNEL_IDX_V2 BIT_ULL(47) /* three column bits and one row bit in MCA address flip * in bad page retirement */ #define UMC_PA_FLIP_BITS_NUM 4 /* bits [63:58] of pa carry the nps mode for RAS_TA_PA_TO_MCA, * RAS TA will use it to get the nps related to pa */ #define UMC_PA_NPS_SHIFT 58 enum umc_memory_partition_mode { UMC_MEMORY_PARTITION_MODE_NONE = 0, UMC_MEMORY_PARTITION_MODE_NPS1 = 1, UMC_MEMORY_PARTITION_MODE_NPS2 = 2, UMC_MEMORY_PARTITION_MODE_NPS3 = 3, UMC_MEMORY_PARTITION_MODE_NPS4 = 4, UMC_MEMORY_PARTITION_MODE_NPS6 = 6, UMC_MEMORY_PARTITION_MODE_NPS8 = 8, UMC_MEMORY_PARTITION_MODE_UNKNOWN }; struct ras_core_context; struct ras_bank_ecc; struct umc_flip_bits { uint32_t flip_bits_in_pa[UMC_PA_FLIP_BITS_NUM]; uint32_t flip_row_bit; uint32_t r13_in_pa; uint32_t bit_num; }; struct umc_mca_addr { uint64_t err_addr; uint32_t ch_inst; uint32_t umc_inst; uint32_t node_inst; uint32_t socket_id; }; struct umc_phy_addr { uint64_t pa; uint32_t bank; uint32_t channel_idx; }; struct umc_bank_addr { uint32_t stack_id; /* SID */ uint32_t bank_group; uint32_t bank; uint32_t row; uint32_t column; uint32_t channel; uint32_t subchannel; /* Also called Pseudochannel (PC) */ }; struct ras_umc_ip_func { int (*bank_to_eeprom_record)(struct ras_core_context *ras_core, struct ras_bank_ecc *bank, struct eeprom_umc_record *record); int (*eeprom_record_to_nps_pages)(struct ras_core_context *ras_core, struct eeprom_umc_record *record, uint32_t nps, uint64_t *pfns, uint32_t num); int (*bank_to_soc_pa)(struct ras_core_context *ras_core, struct umc_bank_addr bank_addr, uint64_t *soc_pa); int (*soc_pa_to_bank)(struct ras_core_context *ras_core, uint64_t soc_pa, struct umc_bank_addr *bank_addr); void (*mca_ipid_parse)(struct ras_core_context *ras_core, uint64_t ipid, uint32_t *did, uint32_t *ch, uint32_t *umc_inst, uint32_t *sid); int (*ma2pa)(struct ras_core_context *ras_core, struct umc_mca_addr *addr_in, struct umc_phy_addr *addr_out, uint32_t nps); uint64_t (*nps_pa_to_row_pa)(struct ras_core_context *ras_core, uint64_t pa, enum umc_memory_partition_mode nps, bool zero_pfn_ok); uint32_t (*get_die_id)(uint64_t mca_addr, uint64_t pa); }; struct eeprom_store_record { /* point to data records array */ struct eeprom_umc_record *bps; /* the count of entries */ int count; /* the space can place new entries */ int space_left; /* logical bad page number */ int bad_page_num; /* the bad page number is ras_num_recs or * ras_num_recs * retire_unit */ int bad_page_num_old; }; struct ras_umc_err_data { struct eeprom_store_record rom_data; struct eeprom_store_record ram_data; enum umc_memory_partition_mode umc_nps_mode; uint64_t last_retired_pfn; }; struct ras_umc { u32 umc_ip_version; u32 umc_vram_type; u32 num_umc; const struct ras_umc_ip_func *ip_func; struct radix_tree_root root; struct mutex tree_lock; struct mutex umc_lock; struct mutex bank_log_lock; struct mutex pending_ecc_lock; struct ras_umc_err_data umc_err_data; struct list_head pending_ecc_list; /* number of entries currently queued on pending_ecc_list */ u32 pending_ecc_count; /* number of entries dropped because pending_ecc_list was full */ u32 pending_ecc_dropped; }; /* * Upper bound on entries that can be queued on pending_ecc_list while a * GPU reset is in progress. Beyond this, new ECC events are dropped to * prevent unbounded kernel memory growth in case of an ECC storm or * malicious/repeated UMC error injection. */ #define RAS_UMC_PENDING_ECC_MAX 8192 int ras_umc_sw_init(struct ras_core_context *ras); int ras_umc_sw_fini(struct ras_core_context *ras); int ras_umc_hw_init(struct ras_core_context *ras); int ras_umc_hw_fini(struct ras_core_context *ras); int ras_umc_psp_ma2pa(struct ras_core_context *ras_core, struct umc_mca_addr *in, struct umc_phy_addr *out, uint32_t nps); int ras_umc_handle_bad_pages(struct ras_core_context *ras_core, void *data); int ras_umc_log_bad_bank(struct ras_core_context *ras, struct ras_bank_ecc *bank); int ras_umc_log_bad_bank_pending(struct ras_core_context *ras_core, struct ras_bank_ecc *bank); int ras_umc_log_pending_bad_bank(struct ras_core_context *ras_core); int ras_umc_clear_logged_ecc(struct ras_core_context *ras_core); int ras_umc_load_bad_pages(struct ras_core_context *ras_core); int ras_umc_get_saved_eeprom_count(struct ras_core_context *ras_core); int ras_umc_clean_badpage_data(struct ras_core_context *ras_core); int ras_umc_fill_eeprom_record(struct ras_core_context *ras_core, uint64_t err_addr, uint32_t umc_inst, struct umc_phy_addr *cur_nps_addr, enum umc_memory_partition_mode cur_nps, struct eeprom_umc_record *record); int ras_umc_get_badpage_count(struct ras_core_context *ras_core); int ras_umc_get_badpage_record(struct ras_core_context *ras_core, uint32_t index, void *record); bool ras_umc_check_retired_addr(struct ras_core_context *ras_core, uint64_t addr); int ras_umc_translate_soc_pa_and_bank(struct ras_core_context *ras_core, uint64_t *soc_pa, struct umc_bank_addr *bank_addr, bool bank_to_pa); int ras_umc_convert_record_to_nps_pages(struct ras_core_context *ras_core, struct eeprom_umc_record *record, uint32_t nps, uint64_t *page_pfn, uint32_t max_pages); uint32_t ras_umc_bit_wise_xor(uint32_t val); int ras_umc_ma2pa(struct ras_core_context *ras_core, struct umc_mca_addr *addr_in, struct umc_phy_addr *addr_out, uint32_t nps); #endif