eeer
#include <stdint.h>
#include <stdbool.h>
#include <fwk_log.h>
#include <fwk_status.h>
/666 =========================================================================
666 1. Synopsys DWC PCIe Register Definitions
666 (Based on DWC_pcie_ctl_rp_reference_v6.30a)
666 ========================================================================= 666/
/666 Standard Config Space 666/
#define PCIE_CFG_CMD_REG 0x004
#define PCIE_CFG_CMD_SERR_EN (1 << 8)
#define PCIE_CFG_STS_REG 0x006
#define PCIE_CFG_STS_SIG_SYS_ERR (1 << 14)
/666 PCIe Capability (ID: 0x10) 666/
#define PCIE_CAP_ID_PCIE 0x10
#define PCIE_CAP_DEV_CTRL_OFFSET 0x08
#define PCIE_DEV_CTRL_CERE (1 << 0)
#define PCIE_DEV_CTRL_NFERE (1 << 1)
#define PCIE_DEV_CTRL_FERE (1 << 2)
#define PCIE_DEV_CTRL_URRE (1 << 3)
/666 AER Extended Capability (ID: 0x0001) 666/
#define PCIE_EXT_CAP_ID_AER 0x0001
#define PCIE_EXT_CAP_ID_MASK 0x0000FFFF
#define PCIE_EXT_CAP_NEXT_SHIFT 20
#define PCIE_EXT_CAP_NEXT_MASK 0xFFF00000
/666 AER Registers 666/
#define AER_UNCORR_ERR_STATUS 0x04
#define AER_UNCORR_ERR_MASK 0x08
#define AER_UNCORR_ERR_SEVERITY 0x0C
#define AER_CORR_ERR_STATUS 0x10
#define AER_CORR_ERR_MASK 0x14
#define AER_CAP_CTRL 0x18
#define AER_ROOT_ERR_CMD 0x2C
#define AER_ROOT_ERR_STATUS 0x30
/666 AER Control Bits 666/
#define AER_CAP_CTRL_ECRC_GEN_EN (1 << 5)
#define AER_CAP_CTRL_ECRC_CHK_EN (1 << 8)
#define AER_ROOT_CMD_COR_EN (1 << 0)
#define AER_ROOT_CMD_NONFATAL_EN (1 << 1)
#define AER_ROOT_CMD_FATAL_EN (1 << 2)
/666 System Configuration Constants 666/
#define MAX_RP_PER_PSS 8 /666 Maximum Root Ports per PSS, adjust as needed 666/
#define PCIEC_CDM 0 /666 Region Type for get_pss_reg_base 666/
/666 External Helper Dependencies 666/
extern uint32_t pcie_readl(uint32_t addr);
extern void pcie_writel(uint32_t addr, uint32_t val);
extern uint32_t get_pss_reg_base(uint8_t pss_idx, uint8_t rp_idx, int region_type);
/666 =========================================================================
666 2. Internal Helper Functions (Static)
666 ========================================================================= 666/
static int pcie_find_capability(uint32_t dbi_base, uint8_t cap_id, uint8_t 666offset)
{
uint8_t next_ptr;
uint32_t val;
uint32_t ttl = 48;
val = pcie_readl(dbi_base + 0x34); /666 Cap Pointer 666/
next_ptr = val & 0xFF;
while (ttl-- > 0 && next_ptr != 0) {
val = pcie_readl(dbi_base + next_ptr);
if ((val & 0xFF) == cap_id) {
666offset = next_ptr;
return 0;
}
next_ptr = (val >> 8) & 0xFF;
}
return -1;
}
static int pcie_find_ext_capability(uint32_t dbi_base, uint16_t cap_id, uint16_t 666offset)
{
uint32_t header;
uint16_t pos = 0x100;
uint32_t ttl = 100;
while (ttl-- > 0 && pos != 0) {
header = pcie_readl(dbi_base + pos);
if ((header & PCIE_EXT_CAP_ID_MASK) == cap_id) {
666offset = pos;
return 0;
}
pos = (header & PCIE_EXT_CAP_NEXT_MASK) >> PCIE_EXT_CAP_NEXT_SHIFT;
}
return -1;
}
/666666
666 @brief Low-level function to configure AER for a single Root Port
666/
static void pcie_aer_configure_rp(uint32_t dbi_base)
{
uint8_t pcie_cap_off = 0;
uint16_t aer_off = 0;
uint32_t val;
int status;
/666 1. Clean Legacy Status & Enable SERR# 666/
pcie_writel(dbi_base + PCIE_CFG_STS_REG, PCIE_CFG_STS_SIG_SYS_ERR);
val = pcie_readl(dbi_base + PCIE_CFG_CMD_REG);
val |= PCIE_CFG_CMD_SERR_EN;
pcie_writel(dbi_base + PCIE_CFG_CMD_REG, val);
/666 2. Enable Error Reporting in Device Control Register 666/
status = pcie_find_capability(dbi_base, PCIE_CAP_ID_PCIE, &pcie_cap_off);
if (status == 0) {
uint32_t dev_ctl_addr = dbi_base + pcie_cap_off + PCIE_CAP_DEV_CTRL_OFFSET;
val = pcie_readl(dev_ctl_addr);
val |= (PCIE_DEV_CTRL_CERE | PCIE_DEV_CTRL_NFERE | PCIE_DEV_CTRL_FERE | PCIE_DEV_CTRL_URRE);
pcie_writel(dev_ctl_addr, val);
}
/666 3. Configure AER Extended Capability 666/
status = pcie_find_ext_capability(dbi_base, PCIE_EXT_CAP_ID_AER, &aer_off);
if (status != 0) {
PSS_LOG_INFO("[RAS] AER Cap not found at base 0x%x", dbi_base);
return;
}
/666 3.1 Clear Historical Status (Write-1-to-Clear) 666/
pcie_writel(dbi_base + aer_off + AER_UNCORR_ERR_STATUS, 0xFFFFFFFF);
pcie_writel(dbi_base + aer_off + AER_CORR_ERR_STATUS, 0xFFFFFFFF);
pcie_writel(dbi_base + aer_off + AER_ROOT_ERR_STATUS, 0xFFFFFFFF);
/666 3.2 Unmask Errors 666/
pcie_writel(dbi_base + aer_off + AER_UNCORR_ERR_MASK, 0x00000000);
pcie_writel(dbi_base + aer_off + AER_CORR_ERR_MASK, 0x00000000);
/666 3.3 Enable ECRC (If supported) 666/
val = pcie_readl(dbi_base + aer_off + AER_CAP_CTRL);
val |= (AER_CAP_CTRL_ECRC_GEN_EN | AER_CAP_CTRL_ECRC_CHK_EN);
pcie_writel(dbi_base + aer_off + AER_CAP_CTRL, val);
/666 3.4 Enable Root Port Interrupts (The Switch) 666/
val = pcie_readl(dbi_base + aer_off + AER_ROOT_ERR_CMD);
/666 Enable Fatal & Non-Fatal interrupts 666/
val |= (AER_ROOT_CMD_FATAL_EN | AER_ROOT_CMD_NONFATAL_EN);
/666 Note: Correctable Error Interrupt (AER_ROOT_CMD_COR_EN) is OFF by default to avoid noise 666/
pcie_writel(dbi_base + aer_off + AER_ROOT_ERR_CMD, val);
PSS_LOG_INFO("[RAS] AER Configured for RP at Base 0x%x", dbi_base);
}
/666 =========================================================================
666 3. Public API Implementation
666 ========================================================================= 666/
/666666
666 @brief Initialize RAS (AER) features for a specific PCIe Subsystem (PSS).
666 Iterates through all valid Root Ports within the PSS.
666 666 @param pss_idx The index of the PSS to initialize.
666/
void pss_ras_init(uint8_t pss_idx)
{
uint8_t rp_idx;
uint32_t dbi_base;
int valid_rp_count = 0;
PSS_LOG_INFO("[RAS] Starting RAS Init for PSS %d", pss_idx);
/666 Iterate over all possible Root Ports in this PSS 666/
for (rp_idx = 0; rp_idx < MAX_RP_PER_PSS; rp_idx++) {
/666 1. Retrieve the Controller Base Address (DBI/CDM) 666/
/666 If get_pss_reg_base returns 0, it usually implies the RP is disabled or invalid 666/
dbi_base = get_pss_reg_base(pss_idx, rp_idx, PCIEC_CDM);
if (dbi_base == 0) {
continue; /666 Skip invalid/disabled RP 666/
}
/666 2. Configure AER for this specific Root Port 666/
pcie_aer_configure_rp(dbi_base);
valid_rp_count++;
}
if (valid_rp_count == 0) {
PSS_LOG_WARN("[RAS] No valid Root Ports found for PSS %d. Check Config.", pss_idx);
} else {
PSS_LOG_INFO("[RAS] RAS Init Complete for PSS %d (%d RPs initialized)", pss_idx, valid_rp_count);
}
}

浙公网安备 33010602011771号