提交 53494dcc 编写于 作者: F fengsheng 提交者: Xie XiuQi

sysctl: Miscarriage of Justice sas ras to usb ras.

driver inclusion
category: feature
bugzilla: NA
CVE: NA

1 fix bug:Miscarriage of
Justice sas ras to usb ras.
2 read reg 0x20107E238 to judge cs or es.
Signed-off-by: Nfengsheng <fengsheng5@huawei.com>
Reviewed-by: linsiwei <linsiwei@huawei.com>a
Reviewed-by: NYang Yingliang <yangyingliang@huawei.com>
Signed-off-by: NYang Yingliang <yangyingliang@huawei.com>
上级 24c1d66a
...@@ -50,6 +50,10 @@ ...@@ -50,6 +50,10 @@
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#define DEBUG #define DEBUG
#define SYSCTL_DRIVER_VERSION "1.7.8.0"
/* debug?a1? */
unsigned int g_sysctrl_debug;
/* sysctrl reg base address */ /* sysctrl reg base address */
struct his_hllc_priv { struct his_hllc_priv {
void __iomem *hllc_base[CHIP_ID_NUM_MAX][HLLC_NUM_MAX]; void __iomem *hllc_base[CHIP_ID_NUM_MAX][HLLC_NUM_MAX];
...@@ -62,7 +66,7 @@ struct his_hllc_priv { ...@@ -62,7 +66,7 @@ struct his_hllc_priv {
struct his_hllc_priv hip_hllc_priv; struct his_hllc_priv hip_hllc_priv;
static void his_sysctrl_reg_rd(void __iomem *addr, u32 reg, unsigned int *val) static void his_sysctrl_reg_rd(const void __iomem *addr, u32 reg, unsigned int *val)
{ {
*val = readl(addr + reg); *val = readl(addr + reg);
} }
...@@ -72,6 +76,16 @@ static void his_sysctrl_reg_wr(void __iomem *addr, u32 reg, unsigned int val) ...@@ -72,6 +76,16 @@ static void his_sysctrl_reg_wr(void __iomem *addr, u32 reg, unsigned int val)
writel(val, addr + reg); writel(val, addr + reg);
} }
int hisi_sysctl_print_debug(u32 print_debug_en)
{
if (print_debug_en)
g_sysctrl_debug = 0x1;
else
g_sysctrl_debug = 0x0;
return 0;
}
int his_hllc_init(void) int his_hllc_init(void)
{ {
u32 hllc_num; u32 hllc_num;
...@@ -81,46 +95,52 @@ int his_hllc_init(void) ...@@ -81,46 +95,52 @@ int his_hllc_init(void)
u32 chip_ver; u32 chip_ver;
u64 chip_module_base; u64 chip_module_base;
void __iomem *chip_ver_addr; void __iomem *chip_ver_addr;
void __iomem *chip_ver_base;
chip_ver_base = ioremap(0xd7d00000, (u64)0x10000); pr_info("[INFO] %s start.\n", __func__);
chip_ver_addr = chip_ver_base + 0x8;
chip_ver_addr = ioremap(0x20107E238, (u64)4);
if (!chip_ver_addr) {
pr_err("[ERROR] %s chip_ver_base is error.\n", __func__);
return ERR_FAILED;
}
chip_ver = readl(chip_ver_addr); chip_ver = readl(chip_ver_addr);
if ((chip_ver & CHIP_VERSION_MASK) == CHIP_VERSION_ES) { chip_ver = chip_ver>>28;
if (chip_ver == CHIP_VERSION_ES) {
pr_info("[sysctl hllc] chip is es\n");
chip_module_base = HLLC_CHIP_MODULE_ES; chip_module_base = HLLC_CHIP_MODULE_ES;
} else if ((chip_ver & CHIP_VERSION_MASK) == CHIP_VERSION_CS) {
chip_module_base = HLLC_CHIP_MODULE_CS;
} else { } else {
pr_err("%s: chip_ver[%u] is ERR.\n", __func__, chip_ver); chip_module_base = HLLC_CHIP_MODULE_CS;
if (chip_ver_base) pr_info("[sysctl hllc] chip is cs\n");
iounmap((void *)chip_ver_base);
return ERR_FAILED;
} }
pr_info("[sysctl hllc] chip ver=%x\n", chip_ver);
for (chip_id = 0; chip_id < CHIP_ID_NUM_MAX; chip_id++) { for (chip_id = 0; chip_id < CHIP_ID_NUM_MAX; chip_id++) {
for (hllc_num = 0; hllc_num < HLLC_NUM_MAX; hllc_num++) { for (hllc_num = 0; hllc_num < HLLC_NUM_MAX; hllc_num++) {
addr = (u64)chip_id * chip_module_base + HLLC0_REG_BASE + (u64)hllc_num * 0x10000; addr = (u64)chip_id * chip_module_base + HLLC0_REG_BASE + (u64)hllc_num * 0x10000;
hip_hllc_priv.hllc_base[chip_id][hllc_num] = ioremap(addr, (u64)0x10000); hip_hllc_priv.hllc_base[chip_id][hllc_num] = ioremap(addr, (u64)0x10000);
debug_sysctrl_print("hllc_base:%p\n", debug_sysctrl_print("[DBG] hllc_base: %p.\n",
hip_hllc_priv.hllc_base[chip_id][hllc_num]); hip_hllc_priv.hllc_base[chip_id][hllc_num]);
addr = (u64)chip_id * chip_module_base + PCS0_REG_BASE + (u64)hllc_num * 0x10000; addr = (u64)chip_id * chip_module_base + PCS0_REG_BASE + (u64)hllc_num * 0x10000;
hip_hllc_priv.pcs_base[chip_id][hllc_num] = ioremap(addr, (u64)0x10000); hip_hllc_priv.pcs_base[chip_id][hllc_num] = ioremap(addr, (u64)0x10000);
debug_sysctrl_print("hllc_base:%p\n", debug_sysctrl_print("[DBG] pcs_base: %p.\n",
hip_hllc_priv.hllc_base[chip_id][hllc_num]); hip_hllc_priv.pcs_base[chip_id][hllc_num]);
} }
addr = (u64)chip_id * chip_module_base + PA_REG_BASE; addr = (u64)chip_id * chip_module_base + PA_REG_BASE;
hip_hllc_priv.pa_base[chip_id] = ioremap(addr, (u64)0x10000); hip_hllc_priv.pa_base[chip_id] = ioremap(addr, (u64)0x10000);
debug_sysctrl_print("[DBG] pa_base: %p.\n",
hip_hllc_priv.pa_base[chip_id]);
addr = (u64)chip_id * chip_module_base + PM_REG_BASE; addr = (u64)chip_id * chip_module_base + PM_REG_BASE;
hip_hllc_priv.pm_base[chip_id] = ioremap(addr, (u64)0x10000); hip_hllc_priv.pm_base[chip_id] = ioremap(addr, (u64)0x10000);
debug_sysctrl_print("pa_base:%p\n", debug_sysctrl_print("[DBG] pm_base: %p.\n",
hip_hllc_priv.pa_base[chip_id]); hip_hllc_priv.pm_base[chip_id]);
for (ddrc_num = 0; ddrc_num < DDRC_CH_NUM_MAX; ddrc_num++) { for (ddrc_num = 0; ddrc_num < DDRC_CH_NUM_MAX; ddrc_num++) {
addr = (u64)chip_id * chip_module_base + DDRC0_TB_REG_BASE + (u64)ddrc_num * 0x10000; addr = (u64)chip_id * chip_module_base + DDRC0_TB_REG_BASE + (u64)ddrc_num * 0x10000;
...@@ -128,15 +148,15 @@ int his_hllc_init(void) ...@@ -128,15 +148,15 @@ int his_hllc_init(void)
addr = (u64)chip_id * chip_module_base + DDRC0_TA_REG_BASE + (u64)ddrc_num * 0x10000; addr = (u64)chip_id * chip_module_base + DDRC0_TA_REG_BASE + (u64)ddrc_num * 0x10000;
hip_hllc_priv.ddrc_ta_base[chip_id][ddrc_num] = ioremap(addr, (u64)0x10000); hip_hllc_priv.ddrc_ta_base[chip_id][ddrc_num] = ioremap(addr, (u64)0x10000);
debug_sysctrl_print("ddrc_tb_base:%p\n", debug_sysctrl_print("[DBG] ddrc_tb_base: %p.\n",
hip_hllc_priv.ddrc_tb_base[chip_id][ddrc_num]); hip_hllc_priv.ddrc_tb_base[chip_id][ddrc_num]);
debug_sysctrl_print("ddrc_ta_base:%p\n", debug_sysctrl_print("[DBG] ddrc_ta_base: %p.\n",
hip_hllc_priv.ddrc_ta_base[chip_id][ddrc_num]); hip_hllc_priv.ddrc_ta_base[chip_id][ddrc_num]);
} }
} }
iounmap((void *)chip_ver_base); iounmap((void *)chip_ver_addr);
return ERR_OK; return ERR_OK;
} }
...@@ -926,9 +946,8 @@ int sysctl_pmbus_write(u8 chip_id, u8 addr, u32 slave_addr, u32 data_len, u32 bu ...@@ -926,9 +946,8 @@ int sysctl_pmbus_write(u8 chip_id, u8 addr, u32 slave_addr, u32 data_len, u32 bu
static void __iomem *base; static void __iomem *base;
if (CHIP_ID_NUM_MAX <= chip_id if (CHIP_ID_NUM_MAX <= chip_id
|| 0x4 < data_len || 0x4 < data_len) {
|| 0x0 == data_len) { pr_err("[sysctl pmbus]write chip_id range[0x0-0x3] or data_len range[0x0-0x4] is err!\n");
pr_err("[sysctl pmbus]write chip_id range[0x0-0x3] or data_len range[0x1-0x4] is err!\n");
return ERR_PARAM; return ERR_PARAM;
} }
...@@ -937,15 +956,16 @@ int sysctl_pmbus_write(u8 chip_id, u8 addr, u32 slave_addr, u32 data_len, u32 bu ...@@ -937,15 +956,16 @@ int sysctl_pmbus_write(u8 chip_id, u8 addr, u32 slave_addr, u32 data_len, u32 bu
his_sysctrl_reg_wr(base, I2C_INTR_RAW_OFFSET, 0x3ffff); his_sysctrl_reg_wr(base, I2C_INTR_RAW_OFFSET, 0x3ffff);
his_sysctrl_reg_wr(base, 0x0810, (2 << 8) | slave_addr); his_sysctrl_reg_wr(base, 0x0810, (2 << 8) | slave_addr);
if (data_len != 0) {
his_sysctrl_reg_wr(base, 0x0810, addr); his_sysctrl_reg_wr(base, 0x0810, addr);
for (i = 0; i < data_len - 1; i++) { for (i = 0; i < data_len - 1; i++)
his_sysctrl_reg_wr(base, I2C_DATA_CMD_OFFSET, 0xff & (buf >> (i*8))); his_sysctrl_reg_wr(base, I2C_DATA_CMD_OFFSET, 0xff & (buf >> (i*8)));
}
i++;
his_sysctrl_reg_wr(base, I2C_DATA_CMD_OFFSET, (4 << 8) | (0xff & (buf >> (i*8)))); his_sysctrl_reg_wr(base, I2C_DATA_CMD_OFFSET, (4 << 8) | (0xff & (buf >> (i*8))));
} else {
his_sysctrl_reg_wr(base, 0x0810, (4 << 8) | addr);
}
/*poll untill send done*/ /*poll untill send done*/
for (;;) { for (;;) {
...@@ -1234,7 +1254,7 @@ int hip_sysctrl_probe(void) ...@@ -1234,7 +1254,7 @@ int hip_sysctrl_probe(void)
ret = his_hllc_init(); ret = his_hllc_init();
if (ret != ERR_OK) { if (ret != ERR_OK) {
pr_err("sysctrl init fail, ret:[0x%x]\n", ret); pr_err("[ERROR] his_hllc_init fail, ret:[0x%x].\n", ret);
return ret; return ret;
} }
...@@ -1248,7 +1268,7 @@ int hip_sysctrl_remove(void) ...@@ -1248,7 +1268,7 @@ int hip_sysctrl_remove(void)
ret = his_hllc_deinit(); ret = his_hllc_deinit();
if (ret != ERR_OK) { if (ret != ERR_OK) {
pr_err("sysctrl deinit fail, ret:[0x%x]\n", ret); pr_err("[ERROR] his hllc deinit fail, ret:[0x%x].\n", ret);
return ret; return ret;
} }
...@@ -1263,7 +1283,7 @@ static int __init his_sysctrl_init(void) ...@@ -1263,7 +1283,7 @@ static int __init his_sysctrl_init(void)
(void)hip_sysctl_local_ras_init(); (void)hip_sysctl_local_ras_init();
pr_info("insmod sysctrl success\n"); pr_info("[INFO] insmod sysctrl success.\n");
return ret; return ret;
} }
...@@ -1274,7 +1294,7 @@ static void __exit his_sysctrl_exit(void) ...@@ -1274,7 +1294,7 @@ static void __exit his_sysctrl_exit(void)
(void)hip_sysctl_local_ras_exit(); (void)hip_sysctl_local_ras_exit();
pr_info("rmmod sysctrl success\n"); pr_info("[INFO] rmmod sysctrl success.\n");
return; return;
} }
...@@ -1292,11 +1312,15 @@ EXPORT_SYMBOL(hip_sysctrl_remove); ...@@ -1292,11 +1312,15 @@ EXPORT_SYMBOL(hip_sysctrl_remove);
EXPORT_SYMBOL(sysctl_cpu_voltage_read); EXPORT_SYMBOL(sysctl_cpu_voltage_read);
EXPORT_SYMBOL(hi_vrd_info_get); EXPORT_SYMBOL(hi_vrd_info_get);
EXPORT_SYMBOL(sysctl_cpu_voltage_adjust); EXPORT_SYMBOL(sysctl_cpu_voltage_adjust);
EXPORT_SYMBOL(sysctl_pmbus_write);
EXPORT_SYMBOL(sysctl_pmbus_read);
EXPORT_SYMBOL(InitPmbus);
EXPORT_SYMBOL(DeInitPmbus);
module_init(his_sysctrl_init); module_init(his_sysctrl_init);
module_exit(his_sysctrl_exit); module_exit(his_sysctrl_exit);
MODULE_DESCRIPTION("sysctrl for hisillicon platform"); MODULE_DESCRIPTION("sysctrl for hisillicon platform");
MODULE_VERSION("1.02"); MODULE_VERSION(SYSCTL_DRIVER_VERSION);
MODULE_LICENSE("GPL v2"); MODULE_LICENSE("GPL v2");
MODULE_ALIAS("platform:hip-sysctl"); MODULE_ALIAS("platform:hip-sysctl");
...@@ -76,9 +76,7 @@ ...@@ -76,9 +76,7 @@
#define HLLC_INTLV_MODE_3P1 0x5 #define HLLC_INTLV_MODE_3P1 0x5
#define HLLC_INTLV_MODE_3P2 0x6 #define HLLC_INTLV_MODE_3P2 0x6
#define CHIP_VERSION_MASK (0xff) #define CHIP_VERSION_ES (0x1)
#define CHIP_VERSION_ES (0x20)
#define CHIP_VERSION_CS (0x21)
#define HLLC_CHIP_MODULE_ES (0x400000000000) #define HLLC_CHIP_MODULE_ES (0x400000000000)
#define HLLC_CHIP_MODULE_CS (0x200000000000) #define HLLC_CHIP_MODULE_CS (0x200000000000)
#define HLLC_NUM_MAX (0x3) #define HLLC_NUM_MAX (0x3)
...@@ -152,13 +150,13 @@ ...@@ -152,13 +150,13 @@
#define STATUS_RPT_OFFSET 0x0AA4 #define STATUS_RPT_OFFSET 0x0AA4
#define STATUS_ERR_RPT_OFFSET 0x0AA8 #define STATUS_ERR_RPT_OFFSET 0x0AA8
#define SYSCTL_DEBUG_LEVEL 0 extern unsigned int g_sysctrl_debug;
#if (SYSCTL_DEBUG_LEVEL == 0) #define debug_sysctrl_print(fmt...) \
#define debug_sysctrl_print(fmt...) do { \
#else if (g_sysctrl_debug) \
#define debug_sysctrl_print(fmt...) printk(fmt) printk(fmt); \
#endif } while (0)
typedef struct { typedef struct {
unsigned char hllc_enable; unsigned char hllc_enable;
......
...@@ -41,7 +41,7 @@ ...@@ -41,7 +41,7 @@
static LIST_HEAD(hisi_ghes_list); static LIST_HEAD(hisi_ghes_list);
static DEFINE_MUTEX(hisi_ghes_mutex); static DEFINE_MUTEX(hisi_ghes_mutex);
#define GHES_ESTATUS_MAX_SIZE 65536 #define HISI_GHES_ESTATUS_MAX_SIZE 65536
/* Platform Memory */ /* Platform Memory */
#define CPER_SEC_PLATFORM_sysctl_LOCAL_RAS \ #define CPER_SEC_PLATFORM_sysctl_LOCAL_RAS \
...@@ -69,37 +69,39 @@ static int sysctl_lpc_init(void) ...@@ -69,37 +69,39 @@ static int sysctl_lpc_init(void)
u32 chip_ver; u32 chip_ver;
u64 chip_module_base; u64 chip_module_base;
void __iomem *chip_ver_addr; void __iomem *chip_ver_addr;
void __iomem *chip_ver_base;
chip_ver_base = ioremap(0xd7d00000, (u64)0x10000); pr_info("[INFO] %s start.\n", __func__);
if (!chip_ver_base) {
pr_err("%s: chip_ver_base is error.\n", __func__); chip_ver_addr = ioremap(0x20107E238, (u64)4);
if (!chip_ver_addr) {
pr_err("[ERROR] %s chip_ver_base is error.\n", __func__);
return ERR_FAILED; return ERR_FAILED;
} }
chip_ver_addr = chip_ver_base + 0x8;
chip_ver = readl(chip_ver_addr); chip_ver = readl(chip_ver_addr);
if ((chip_ver & CHIP_VERSION_MASK) == CHIP_VERSION_ES) { chip_ver = chip_ver>>28;
if (chip_ver == CHIP_VERSION_ES) {
pr_info("[sysctl lpc] chip is es\n");
chip_module_base = HLLC_CHIP_MODULE_ES; chip_module_base = HLLC_CHIP_MODULE_ES;
} else if ((chip_ver & CHIP_VERSION_MASK) == CHIP_VERSION_CS) {
chip_module_base = HLLC_CHIP_MODULE_CS;
} else { } else {
pr_err("%s: chip_ver[%u] is ERR.\n", __func__, chip_ver); chip_module_base = HLLC_CHIP_MODULE_CS;
iounmap((void *)chip_ver_base); pr_info("[sysctl lpc] chip is cs\n");
return ERR_FAILED;
} }
pr_info("[sysctl lpc] chip ver=%x\n", chip_ver);
for (chip_id = 0; chip_id < CHIP_ID_NUM_MAX; chip_id++) { for (chip_id = 0; chip_id < CHIP_ID_NUM_MAX; chip_id++) {
addr = (u64)chip_id * chip_module_base + SUBCTRL_REG_BASE; addr = (u64)chip_id * chip_module_base + SUBCTRL_REG_BASE;
sysctl_subctrl_lpc_priv[chip_id] = ioremap(addr, (u64)0x10000); sysctl_subctrl_lpc_priv[chip_id] = ioremap(addr, (u64)0x10000);
debug_sysctrl_print("subctl lpc_reset addr:%p\n", sysctl_subctrl_lpc_priv[chip_id]); debug_sysctrl_print("[DBG] subctl lpc reset addr of chip[%d]: %p.\n",
chip_id, sysctl_subctrl_lpc_priv[chip_id]);
lpc_addr = (u64)chip_id * chip_module_base + LPC_REG_BASE; lpc_addr = (u64)chip_id * chip_module_base + LPC_REG_BASE;
sysctl_lpc_priv[chip_id] = ioremap(lpc_addr, (u64)0x10000); sysctl_lpc_priv[chip_id] = ioremap(lpc_addr, (u64)0x10000);
debug_sysctrl_print("lpc mem access ctrl addr:%p\n", sysctl_lpc_priv[chip_id]); debug_sysctrl_print("[DBG] lpc mem access ctrl addr of chip[%d]: %p.\n",
chip_id, sysctl_lpc_priv[chip_id]);
} }
iounmap((void *)chip_ver_base); iounmap((void *)chip_ver_addr);
return ERR_OK; return ERR_OK;
} }
...@@ -143,6 +145,9 @@ static int sysctl_lpc_mem_access_open(u8 chip_id) ...@@ -143,6 +145,9 @@ static int sysctl_lpc_mem_access_open(u8 chip_id)
{ {
void __iomem *addr; void __iomem *addr;
if (!sysctl_lpc_priv[chip_id])
return ERR_PARAM;
addr = sysctl_lpc_priv[chip_id] + LPC_MEM_ACCESS_OFFSET; addr = sysctl_lpc_priv[chip_id] + LPC_MEM_ACCESS_OFFSET;
writel(0x0, addr); writel(0x0, addr);
...@@ -167,40 +172,55 @@ static int sysctl_correlation_reg_report(const struct sysctl_local_ras_cper *ras ...@@ -167,40 +172,55 @@ static int sysctl_correlation_reg_report(const struct sysctl_local_ras_cper *ras
{ {
switch (ras_cper->module_id) { switch (ras_cper->module_id) {
case MODULE_LPC_ERR: case MODULE_LPC_ERR:
pr_err("SYSCTL RAS lpc correlation_reg info"); pr_info("[INFO] SYSCTL RAS lpc correlation_reg info:\n");
break; break;
case MODULE_USB_ERR:
case MODULE_USB2_ERR: if (ras_cper->sub_mod_id == MODULE_USB0_ERR) {
pr_err("SYSCTL RAS usb2 correlation_reg info"); pr_info("[INFO] SYSCTL RAS usb0 correlation_reg info:\n");
} else if (ras_cper->sub_mod_id == MODULE_USB1_ERR) {
pr_info("[INFO] SYSCTL RAS usb1 correlation_reg info:\n");
} else if (ras_cper->sub_mod_id == MODULE_USB2_ERR) {
pr_info("[INFO] SYSCTL RAS usb2 correlation_reg info:\n");
} else {
pr_err("[ERROR] SYSCTL RAS usb sub_module_id[0x%x] is error.\n",
ras_cper->sub_mod_id);
return -1;
}
break; break;
case MODULE_SAS_ERR:
case MODULE_USB3_ERR: if (ras_cper->sub_mod_id == MODULE_SAS0_ERR) {
pr_err("SYSCTL RAS usb3 correlation_reg info"); pr_info("[INFO] SYSCTL RAS sas0 correlation_reg info:\n");
} else if (ras_cper->sub_mod_id == MODULE_SAS1_ERR) {
pr_info("[INFO] SYSCTL RAS sas1 correlation_reg info:\n");
} else {
pr_err("[ERROR] SYSCTL RAS sas sub_module_id[0x%x] is error.\n",
ras_cper->sub_mod_id);
return -1;
}
break; break;
default: default:
pr_err("SYSCTL RAS module_id[0x%x] correlation_reg info", pr_err("[ERROR] SYSCTL RAS module_id[0x%x] is error.\n",
ras_cper->module_id); ras_cper->module_id);
return -1; return -1;
} }
pr_err("SYSCTL RAS socket_id %x", pr_info("[INFO] SYSCTL RAS socket_id: %x.\n",
ras_cper->socket_id); ras_cper->socket_id);
pr_err("SYSCTL RAS nimbus_id %x", pr_info("[INFO] SYSCTL RAS nimbus_id: %x.\n",
ras_cper->nimbus_id); ras_cper->nimbus_id);
pr_err("SYSCTL RAS err_misc0 %x", pr_info("[INFO] SYSCTL RAS err_misc0: %x.\n",
ras_cper->err_misc0); ras_cper->err_misc0);
pr_err("SYSCTL RAS err_misc1 %x", pr_info("[INFO] SYSCTL RAS err_misc1: %x.\n",
ras_cper->err_misc1); ras_cper->err_misc1);
pr_err("SYSCTL RAS err_misc2 %x", pr_info("[INFO] SYSCTL RAS err_misc2: %x.\n",
ras_cper->err_misc2); ras_cper->err_misc2);
pr_err("SYSCTL RAS err_misc3 %x", pr_info("[INFO] SYSCTL RAS err_misc3: %x.\n",
ras_cper->err_misc3); ras_cper->err_misc3);
pr_err("SYSCTL RAS err_misc4 %x", pr_info("[INFO] SYSCTL RAS err_misc4: %x.\n",
ras_cper->err_misc4); ras_cper->err_misc4);
pr_err("SYSCTL RAS err_addrl %x", pr_info("[INFO] SYSCTL RAS err_addrl: %x.\n",
ras_cper->err_addrl); ras_cper->err_addrl);
pr_err("SYSCTL RAS err_addrh %x", pr_info("[INFO] SYSCTL RAS err_addrh: %x.\n",
ras_cper->err_addrh); ras_cper->err_addrh);
return 0; return 0;
...@@ -215,33 +235,51 @@ static int sysctl_do_recovery(const struct sysctl_local_ras_cper *ras_cper) ...@@ -215,33 +235,51 @@ static int sysctl_do_recovery(const struct sysctl_local_ras_cper *ras_cper)
sysctl_lpc_irq_cnt++; sysctl_lpc_irq_cnt++;
sysctl_lpc_reset(ras_cper->socket_id); sysctl_lpc_reset(ras_cper->socket_id);
pr_err("SYSCTL RAS lpc of chip[%d] reset", ras_cper->socket_id); pr_info("[INFO] SYSCTL RAS lpc of chip[%d] reset.\n", ras_cper->socket_id);
pr_err("SYSCTL RAS sysctl_lpc_irq_cnt[%d]", sysctl_lpc_irq_cnt); pr_info("[INFO] SYSCTL RAS sysctl_lpc_irq_cnt[%d].\n", sysctl_lpc_irq_cnt);
udelay((unsigned long)20); udelay((unsigned long)20);
if (sysctl_lpc_irq_cnt <= LPC_IRQ_CNT_MAX) { if (sysctl_lpc_irq_cnt <= LPC_IRQ_CNT_MAX) {
sysctl_lpc_unreset(ras_cper->socket_id); sysctl_lpc_unreset(ras_cper->socket_id);
pr_err("SYSCTL RAS lpc of chip[%d] unreset", pr_info("[INFO] SYSCTL RAS lpc of chip[%d] unreset.\n",
ras_cper->socket_id); ras_cper->socket_id);
sysctl_lpc_mem_access_open(ras_cper->socket_id); sysctl_lpc_mem_access_open(ras_cper->socket_id);
pr_err("SYSCTL RAS lpc of chip[%d] mem access open", pr_info("[INFO] SYSCTL RAS lpc of chip[%d] mem access open.\n",
ras_cper->socket_id); ras_cper->socket_id);
} else { } else {
pr_err("SYSCTL RAS lpc of chip[%d] unreset 3 times, which won't unreset", pr_err("[ERROR] SYSCTL RAS lpc of chip[%d] unreset %d times, won't unreset.\n",
ras_cper->socket_id); ras_cper->socket_id, LPC_IRQ_CNT_MAX);
} }
break; break;
case MODULE_USB2_ERR: case MODULE_USB_ERR:
pr_err("SYSCTL RAS usb2 err %d", ret); if (ras_cper->sub_mod_id == MODULE_USB0_ERR) {
pr_info("[INFO] SYSCTL RAS usb0 error.\n");
} else if (ras_cper->sub_mod_id == MODULE_USB1_ERR) {
pr_info("[INFO] SYSCTL RAS usb1 error.\n");
} else if (ras_cper->sub_mod_id == MODULE_USB2_ERR) {
pr_info("[INFO] SYSCTL RAS usb2 error.\n");
} else {
pr_err("[ERROR] SYSCTL RAS usb sub_module_id[0x%x] is error.\n",
ras_cper->sub_mod_id);
return ret;
}
break; break;
case MODULE_USB3_ERR: case MODULE_SAS_ERR:
pr_err("SYSCTL RAS usb3 err %d", ret); if (ras_cper->sub_mod_id == MODULE_SAS0_ERR) {
pr_info("[INFO] SYSCTL RAS sas0 error.\n");
} else if (ras_cper->sub_mod_id == MODULE_SAS1_ERR) {
pr_info("[INFO] SYSCTL RAS sas1 error.\n");
} else {
pr_err("[ERROR] SYSCTL RAS sas sub_module_id[0x%x] is error.\n",
ras_cper->sub_mod_id);
return ret;
}
break; break;
default: default:
pr_err("SYSCTL RAS err module_id[0x%x] not process in sysctl\n", pr_err("[ERROR] SYSCTL RAS module_id[0x%x] is error, has not match process in sysctl.\n",
ras_cper->module_id); ras_cper->module_id);
return 0; return ret;
} }
(void)sysctl_correlation_reg_report(ras_cper); (void)sysctl_correlation_reg_report(ras_cper);
...@@ -259,248 +297,250 @@ static int sysctl_hest_hisi_parse_ghes_count(struct acpi_hest_header *hest_hdr, ...@@ -259,248 +297,250 @@ static int sysctl_hest_hisi_parse_ghes_count(struct acpi_hest_header *hest_hdr,
return 0; return 0;
} }
static struct ghes *sysctl_ghes_new(struct acpi_hest_generic *generic) static struct ghes *sysctl_ghes_new(struct acpi_hest_generic *sysctl_generic)
{ {
struct ghes *ghes; struct ghes *sysctl_ghes;
size_t error_block_length; size_t err_block_length = 0;
int rc = 0; int ret = 0;
ghes = kzalloc(sizeof(*ghes), GFP_KERNEL); sysctl_ghes = kzalloc(sizeof(*sysctl_ghes), GFP_KERNEL);
if (!ghes) if (!sysctl_ghes)
return ERR_PTR((long)-ENOMEM); return ERR_PTR((long)-ENOMEM);
ghes->generic = generic; sysctl_ghes->generic = sysctl_generic;
if (is_hest_type_generic_v2(ghes)) { if (is_hest_type_generic_v2(sysctl_ghes)) {
rc = map_gen_v2(ghes); ret = map_gen_v2(sysctl_ghes);
if (rc) if (ret)
goto err_free; goto err_free;
} }
rc = apei_map_generic_address(&generic->error_status_address); ret = apei_map_generic_address(&sysctl_generic->error_status_address);
if (rc) if (ret)
goto err_unmap_read_ack_addr; goto err_unmap_read_ack_addr;
error_block_length = generic->error_block_length; err_block_length = sysctl_generic->error_block_length;
if (error_block_length > GHES_ESTATUS_MAX_SIZE) { if (err_block_length > HISI_GHES_ESTATUS_MAX_SIZE) {
pr_err("SYSCTL RAS Error status block length is too long: %u for " pr_err("SYSCTL RAS Error status block length is too long: %u for "
"generic hardware error source: %d.\n", "generic hardware error source: %d.\n",
(u32)error_block_length, generic->header.source_id); (u32)err_block_length, sysctl_generic->header.source_id);
error_block_length = GHES_ESTATUS_MAX_SIZE; err_block_length = HISI_GHES_ESTATUS_MAX_SIZE;
} }
ghes->estatus = (struct acpi_hest_generic_status *)kmalloc(error_block_length, GFP_KERNEL); sysctl_ghes->estatus = (struct acpi_hest_generic_status *)kmalloc(err_block_length, GFP_KERNEL);
if (!ghes->estatus) { if (!sysctl_ghes->estatus) {
rc = -ENOMEM; ret = -ENOMEM;
goto err_unmap_status_addr; goto err_unmap_status_addr;
} }
return ghes; return sysctl_ghes;
err_unmap_status_addr: err_unmap_status_addr:
apei_unmap_generic_address(&generic->error_status_address); apei_unmap_generic_address(&sysctl_generic->error_status_address);
err_unmap_read_ack_addr: err_unmap_read_ack_addr:
if (is_hest_type_generic_v2(ghes)) if (is_hest_type_generic_v2(sysctl_ghes))
unmap_gen_v2(ghes); unmap_gen_v2(sysctl_ghes);
err_free: err_free:
kfree(ghes); kfree(sysctl_ghes);
return ERR_PTR((long)rc); return ERR_PTR((long)ret);
} }
static int sysctl_hest_hisi_parse_ghes(struct acpi_hest_header *hest_hdr, void *data) static int sysctl_hest_hisi_parse_ghes(struct acpi_hest_header *hest_hdr, void *data)
{ {
struct acpi_hest_generic *generic; struct acpi_hest_generic *sysctl_generic;
struct ghes *ghes; struct ghes *sysctl_ghes;
(void)data; (void)data;
generic = container_of(hest_hdr, struct acpi_hest_generic, header); sysctl_generic = container_of(hest_hdr, struct acpi_hest_generic, header);
if (!generic->enabled) if (!sysctl_generic->enabled)
return 0; return 0;
debug_sysctrl_print("SYSCTL RAS HISILICON Error : ghes source id = %x\n", debug_sysctrl_print("[DBG] SYSCTL RAS ghes source id: %x.\n",
hest_hdr->source_id); hest_hdr->source_id);
debug_sysctrl_print("SYSCTL RAS HISILICON Error : ghes error_block_length = %x\n", debug_sysctrl_print("[DBG] SYSCTL RAS ghes error_block_length: %x.\n",
generic->error_block_length); sysctl_generic->error_block_length);
debug_sysctrl_print("SYSCTL RAS HISILICON Error : ghes notify type = %x\n", debug_sysctrl_print("[DBG] SYSCTL RAS ghes notify type: %x.\n",
generic->notify.type); sysctl_generic->notify.type);
ghes = sysctl_ghes_new(generic); sysctl_ghes = sysctl_ghes_new(sysctl_generic);
if (!ghes) if (!sysctl_ghes) {
pr_err("[ERROR] SYSCTL RAS sysctl_ghes is null.\n");
return -ENOMEM; return -ENOMEM;
}
mutex_lock(&hisi_ghes_mutex); mutex_lock(&hisi_ghes_mutex);
list_add_rcu(&ghes->list, &hisi_ghes_list); list_add_rcu(&sysctl_ghes->list, &hisi_ghes_list);
mutex_unlock(&hisi_ghes_mutex); mutex_unlock(&hisi_ghes_mutex);
return 0; return 0;
} }
static int sysctl_ghes_read_estatus(struct ghes *ghes, int silent) static int sysctl_ghes_read_estatus(struct ghes *sysctl_ghes, int silent)
{ {
struct acpi_hest_generic *g = ghes->generic; struct acpi_hest_generic *g = sysctl_ghes->generic;
phys_addr_t buf_paddr; phys_addr_t buf_paddr;
u32 error_block_length; u32 err_block_length = 0;
u32 len; u32 len;
int rc = 0; int ret = 0;
rc = apei_read(&buf_paddr, &g->error_status_address); ret = apei_read(&buf_paddr, &g->error_status_address);
if (rc) { if (ret) {
if (!silent && printk_ratelimit()) { if (!silent && printk_ratelimit()) {
pr_err("SYSCTL RAS Failed to read error status block address for hardware error source: %d.\n", pr_err("[ERROR] SYSCTL RAS apei_read fail, source_id: %d.\n",
g->header.source_id); g->header.source_id);
} }
pr_err("SYSCTL RAS apei_read rc: %d.\n", rc); pr_err("[ERROR] SYSCTL RAS apei_read fail, ret: %d.\n", ret);
return -EIO; return -EIO;
} }
if (!buf_paddr) { if (!buf_paddr) {
pr_err("SYSCTL RAS buf_paddr is null.\n"); pr_err("[ERROR] SYSCTL RAS buf_paddr is null.\n");
return -ENOENT; return -ENOENT;
} }
error_block_length = g->error_block_length; err_block_length = g->error_block_length;
if (error_block_length > GHES_ESTATUS_MAX_SIZE) { if (err_block_length > HISI_GHES_ESTATUS_MAX_SIZE) {
pr_err("SYSCTL RAS error_block_length: %u, source_id: %d.\n", pr_info("[INFO] SYSCTL RAS error_block_length: %u, source_id: %d.\n",
error_block_length, g->header.source_id); err_block_length, g->header.source_id);
error_block_length = GHES_ESTATUS_MAX_SIZE; err_block_length = HISI_GHES_ESTATUS_MAX_SIZE;
} }
ghes->estatus = ioremap_wc(buf_paddr, error_block_length); sysctl_ghes->estatus = ioremap_wc(buf_paddr, err_block_length);
if (!ghes->estatus) { if (!sysctl_ghes->estatus) {
pr_err("SYSCTL RAS ghes->estatus is null.\n"); pr_err("[ERROR] SYSCTL RAS sysctl_ghes->estatus is null.\n");
goto err_release_estatus; goto error_release_estatus;
} }
if (!ghes->estatus->block_status) { if (!sysctl_ghes->estatus->block_status) {
pr_err("SYSCTL RAS ghes->estatus->block_status is 0.\n"); pr_err("[ERROR] SYSCTL RAS sysctl_ghes->estatus->block_status is 0.\n");
iounmap(ghes->estatus); iounmap(sysctl_ghes->estatus);
return -ENOENT; return -ENOENT;
} }
ghes->buffer_paddr = buf_paddr; sysctl_ghes->buffer_paddr = buf_paddr;
ghes->flags |= GHES_TO_CLEAR; sysctl_ghes->flags |= GHES_TO_CLEAR;
rc = -EIO; ret = -EIO;
len = cper_estatus_len(ghes->estatus); len = cper_estatus_len(sysctl_ghes->estatus);
if (len < sizeof(*ghes->estatus)) { if (len < sizeof(*sysctl_ghes->estatus)) {
pr_err("SYSCTL RAS len[%d] less than sizeof(*ghes->estatus)[%ld].\n", pr_err("[ERROR] SYSCTL RAS len[%d] less than sizeof(*ghes->estatus)[%ld].\n",
len, sizeof(*ghes->estatus)); len, sizeof(*sysctl_ghes->estatus));
goto err_read_block; goto error_read_block;
} }
if (len > ghes->generic->error_block_length) { if (len > sysctl_ghes->generic->error_block_length) {
pr_err("SYSCTL RAS len[%d] more than error_block_length[%d].\n", pr_err("[ERROR] SYSCTL RAS len[%d] more than error_block_length[%d].\n",
len, ghes->generic->error_block_length); len, sysctl_ghes->generic->error_block_length);
goto err_read_block; goto error_read_block;
} }
if (cper_estatus_check_header(ghes->estatus)) { if (cper_estatus_check_header(sysctl_ghes->estatus)) {
pr_err("SYSCTL RAS cper_estatus_check_header fail.\n"); pr_err("[ERROR] SYSCTL RAS cper_estatus_check_header fail.\n");
goto err_read_block; goto error_read_block;
} }
pr_err("SYSCTL RAS HISILICON Error : ghes source id is %d\n", pr_info("[INFO] SYSCTL RAS HISILICON Error : ghes source id is %d.\n",
g->header.source_id); g->header.source_id);
pr_err("SYSCTL RAS HISILICON Error : error status addr is 0x%llx\n", pr_info("[INFO] SYSCTL RAS HISILICON Error : error status addr is 0x%llx.\n",
buf_paddr); buf_paddr);
pr_err("SYSCTL RAS HISILICON Error : data_length = %d.\n", pr_info("[INFO] SYSCTL RAS HISILICON Error : data_length is %d.\n",
ghes->estatus->data_length); sysctl_ghes->estatus->data_length);
pr_err("SYSCTL RAS HISILICON Error : severity = %d.\n", pr_info("[INFO] SYSCTL RAS HISILICON Error : severity is %d.\n",
ghes->estatus->error_severity); sysctl_ghes->estatus->error_severity);
if (cper_estatus_check(ghes->estatus)) { if (cper_estatus_check(sysctl_ghes->estatus)) {
pr_err("SYSCTL RAS cper_estatus_check fail.\n"); pr_err("[ERROR] SYSCTL RAS cper_estatus_check fail.\n");
goto err_read_block; goto error_read_block;
} }
rc = 0; ret = 0;
return rc; return ret;
err_read_block: error_read_block:
pr_err("SYSCTL RAS ghes error status block read error\n"); pr_err("[ERROR] SYSCTL RAS info of ghes error status block is error.\n");
iounmap(ghes->estatus); iounmap(sysctl_ghes->estatus);
pr_err("SYSCTL RAS Failed to read error status block!\n"); pr_err("[ERROR] SYSCTL RAS read error status block fail.\n");
err_release_estatus: error_release_estatus:
pr_err("error ioremap, release memory\n"); pr_err("[ERROR] ioremap_wc fail, release_estatus.\n");
return rc; return ret;
} }
void sysctl_ghes_clear_estatus(struct ghes *ghes) void sysctl_ghes_clear_estatus(struct ghes *sysctl_ghes)
{ {
ghes->estatus->block_status = 0; sysctl_ghes->estatus->block_status = 0;
if (!(ghes->flags & GHES_TO_CLEAR)) if (!(sysctl_ghes->flags & GHES_TO_CLEAR))
return; return;
ghes->flags &= ~GHES_TO_CLEAR; sysctl_ghes->flags &= ~GHES_TO_CLEAR;
} }
static void sysctl_ghes_do_proc(struct ghes *ghes, static void sysctl_ghes_do_proc(struct ghes *sysctl_ghes,
struct acpi_hest_generic_status *estatus) struct acpi_hest_generic_status *sysct_estatus)
{ {
struct acpi_hest_generic_data *gdata = NULL; struct acpi_hest_generic_data *gdata = NULL;
guid_t *sec_type; guid_t *sec_type;
struct sysctl_local_ras_cper *ras_cper; struct sysctl_local_ras_cper *ras_cper;
struct cper_sec_proc_arm *arm_ras_cper; struct cper_sec_proc_arm *arm_ras_cper;
(void)ghes; (void)sysctl_ghes;
apei_estatus_for_each_section(estatus, gdata) { apei_estatus_for_each_section(sysct_estatus, gdata) {
sec_type = (guid_t *)gdata->section_type; sec_type = (guid_t *)gdata->section_type;
if (guid_equal(sec_type, &CPER_SEC_PLATFORM_sysctl_LOCAL_RAS)) { if (guid_equal(sec_type, &CPER_SEC_PLATFORM_sysctl_LOCAL_RAS)) {
ras_cper = acpi_hest_get_payload(gdata); ras_cper = acpi_hest_get_payload(gdata);
(void)sysctl_do_recovery(ras_cper); (void)sysctl_do_recovery(ras_cper);
} else if (guid_equal(sec_type, &CPER_SEC_PROC_ARM)) { } else if (guid_equal(sec_type, &CPER_SEC_PROC_ARM)) {
arm_ras_cper = acpi_hest_get_payload(gdata); arm_ras_cper = acpi_hest_get_payload(gdata);
if (arm_ras_cper->err_info_num != 1) { if (arm_ras_cper->err_info_num != 1) {
pr_err("SYSCTL RAS ERR: err_info_num[0x%x] is err.\n", pr_err("[ERROR] SYSCTL RAS err_info_num[0x%x] is error.\n",
arm_ras_cper->err_info_num); arm_ras_cper->err_info_num);
return; return;
} }
} }
cper_estatus_print("SYSCTL RAS HISILICON Error : ", cper_estatus_print("[INFO] SYSCTL RAS HISILICON Error : ",
ghes->estatus); sysctl_ghes->estatus);
} }
return; return;
} }
static int sysctl_ghes_proc(struct ghes *ghes) static int sysctl_ghes_proc(struct ghes *sysctl_ghes)
{ {
int rc = 0; int ret = 0;
rc = sysctl_ghes_read_estatus(ghes, 0); ret = sysctl_ghes_read_estatus(sysctl_ghes, 0);
if (rc) if (ret)
return rc; return ret;
sysctl_ghes_do_proc(ghes, ghes->estatus); sysctl_ghes_do_proc(sysctl_ghes, sysctl_ghes->estatus);
if (ghes->estatus) if (sysctl_ghes->estatus)
iounmap(ghes->estatus); iounmap(sysctl_ghes->estatus);
return rc; return ret;
} }
static int sysctl_hisi_error_handler(struct work_struct *work) static int sysctl_hisi_error_handler(struct work_struct *work)
{ {
int ret = 0; int ret = 0;
struct ghes *ghes; struct ghes *sysctl_ghes;
(void)work; (void)work;
pr_err("SYSCTL RAS HISILICON Error : handler start.\n"); pr_info("[INFO] SYSCTL RAS %s start.\n", __func__);
rcu_read_lock(); rcu_read_lock();
list_for_each_entry_rcu(ghes, &hisi_ghes_list, list) { list_for_each_entry_rcu(sysctl_ghes, &hisi_ghes_list, list) {
if (!sysctl_ghes_proc(ghes)) if (!sysctl_ghes_proc(sysctl_ghes))
ret = NOTIFY_OK; ret = NOTIFY_OK;
} }
rcu_read_unlock(); rcu_read_unlock();
pr_err("SYSCTL RAS ghes_proc %d", ret); pr_info("[INFO] SYSCTL RAS sysctl_ghes_proc ret: %d.\n", ret);
pr_err("SYSCTL RAS HISILICON Error : handler end.\n"); pr_info("[INFO] SYSCTL RAS %s end.\n", __func__);
return ret; return ret;
...@@ -509,30 +549,29 @@ static int sysctl_hisi_error_handler(struct work_struct *work) ...@@ -509,30 +549,29 @@ static int sysctl_hisi_error_handler(struct work_struct *work)
/*acpi hisi hest init*/ /*acpi hisi hest init*/
static void sysctl_acpi_hisi_hest_init(void) static void sysctl_acpi_hisi_hest_init(void)
{ {
int rc; int ret;
unsigned int ghes_count = 0; unsigned int ghes_count = 0;
debug_sysctrl_print("SYSCTL RAS sysctl_acpi_hisi_hest_init start\n"); debug_sysctrl_print("[DBG] SYSCTL RAS %s start.\n", __func__);
if (hest_disable) { if (hest_disable) {
pr_err("SYSCTL RAS Table parsing disabled.\n"); pr_err("[ERROR] SYSCTL RAS Table parsing disabled.\n");
return; return;
} }
rc = apei_hest_parse(sysctl_hest_hisi_parse_ghes_count, &ghes_count); ret = apei_hest_parse(sysctl_hest_hisi_parse_ghes_count, &ghes_count);
if (rc) { if (ret) {
pr_err("SYSCTL RAS hest_hisi_parse_ghes_count faile.\n"); pr_err("[ERROR] SYSCTL RAS hest_hisi_parse_ghes_count fail.\n");
return; return;
} }
debug_sysctrl_print("[DBG] SYSCTL RAS Get ghes count: %d.\n", ghes_count);
debug_sysctrl_print("SYSCTL RAS Get ghes count = %d\n", ghes_count); ret = apei_hest_parse(sysctl_hest_hisi_parse_ghes, &ghes_count);
if (ret) {
rc = apei_hest_parse(sysctl_hest_hisi_parse_ghes, &ghes_count); pr_err("[ERROR] SYSCTL RAS hest_hisi_parse_ghes fail.\n");
if (rc) {
pr_err("SYSCTL RAS hest_hisi_parse_ghes faile.\n");
return; return;
} }
debug_sysctrl_print("SYSCTL RAS sysctl_acpi_hisi_hest_init end\n"); debug_sysctrl_print("[DBG] SYSCTL RAS sysctl_acpi_hisi_hest_init end.\n");
return; return;
} }
...@@ -575,5 +614,5 @@ void hip_sysctl_local_ras_exit(void) ...@@ -575,5 +614,5 @@ void hip_sysctl_local_ras_exit(void)
unregister_acpi_hed_notifier(&sysctl_ghes_hisi_notifier_hed); unregister_acpi_hed_notifier(&sysctl_ghes_hisi_notifier_hed);
pr_err(KERN_INFO "Goodbye test.\n"); pr_info("[INFO] hip sysctl local ras exit.\n");
} }
...@@ -21,8 +21,19 @@ ...@@ -21,8 +21,19 @@
enum sysctl_bios_err { enum sysctl_bios_err {
MODULE_LPC_ERR = 9, MODULE_LPC_ERR = 9,
MODULE_USB2_ERR = 14, MODULE_SAS_ERR = 15,
MODULE_USB3_ERR = 15, MODULE_USB_ERR = 17,
};
enum sysctl_sub_usb_err {
MODULE_USB0_ERR = 0,
MODULE_USB1_ERR,
MODULE_USB2_ERR,
};
enum sysctl_sub_sas_err {
MODULE_SAS0_ERR = 0,
MODULE_SAS1_ERR,
}; };
struct sysctl_validation_bits { struct sysctl_validation_bits {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册