This is for dumping different registers and testing the address mapping logic using the ECC syndromes. Borislav: - split sysfs attrs per file - use more conform names for the sysfs attrs - fix function return value patterns - cleanup/fix comments - cleanup debug calls Reviewed-by: Mauro Carvalho Chehab <mchehab@redhat.com> Signed-off-by: Doug Thompson <dougthompson@xmission.com> Signed-off-by: Borislav Petkov <borislav.petkov@amd.com>tirimbino
parent
cfe40fdb4a
commit
fd3d6780f7
@ -0,0 +1,255 @@ |
||||
#include "amd64_edac.h" |
||||
|
||||
/*
|
||||
* accept a hex value and store it into the virtual error register file, field: |
||||
* nbeal and nbeah. Assume virtual error values have already been set for: NBSL, |
||||
* NBSH and NBCFG. Then proceed to map the error values to a MC, CSROW and |
||||
* CHANNEL |
||||
*/ |
||||
static ssize_t amd64_nbea_store(struct mem_ctl_info *mci, const char *data, |
||||
size_t count) |
||||
{ |
||||
struct amd64_pvt *pvt = mci->pvt_info; |
||||
unsigned long long value; |
||||
int ret = 0; |
||||
|
||||
ret = strict_strtoull(data, 16, &value); |
||||
if (ret != -EINVAL) { |
||||
debugf0("received NBEA= 0x%llx\n", value); |
||||
|
||||
/* place the value into the virtual error packet */ |
||||
pvt->ctl_error_info.nbeal = (u32) value; |
||||
value >>= 32; |
||||
pvt->ctl_error_info.nbeah = (u32) value; |
||||
|
||||
/* Process the Mapping request */ |
||||
/* TODO: Add race prevention */ |
||||
amd64_process_error_info(mci, &pvt->ctl_error_info, 1); |
||||
|
||||
return count; |
||||
} |
||||
return ret; |
||||
} |
||||
|
||||
/* display back what the last NBEA (MCA NB Address (MC4_ADDR)) was written */ |
||||
static ssize_t amd64_nbea_show(struct mem_ctl_info *mci, char *data) |
||||
{ |
||||
struct amd64_pvt *pvt = mci->pvt_info; |
||||
u64 value; |
||||
|
||||
value = pvt->ctl_error_info.nbeah; |
||||
value <<= 32; |
||||
value |= pvt->ctl_error_info.nbeal; |
||||
|
||||
return sprintf(data, "%llx\n", value); |
||||
} |
||||
|
||||
/* store the NBSL (MCA NB Status Low (MC4_STATUS)) value user desires */ |
||||
static ssize_t amd64_nbsl_store(struct mem_ctl_info *mci, const char *data, |
||||
size_t count) |
||||
{ |
||||
struct amd64_pvt *pvt = mci->pvt_info; |
||||
unsigned long value; |
||||
int ret = 0; |
||||
|
||||
ret = strict_strtoul(data, 16, &value); |
||||
if (ret != -EINVAL) { |
||||
debugf0("received NBSL= 0x%lx\n", value); |
||||
|
||||
pvt->ctl_error_info.nbsl = (u32) value; |
||||
|
||||
return count; |
||||
} |
||||
return ret; |
||||
} |
||||
|
||||
/* display back what the last NBSL value written */ |
||||
static ssize_t amd64_nbsl_show(struct mem_ctl_info *mci, char *data) |
||||
{ |
||||
struct amd64_pvt *pvt = mci->pvt_info; |
||||
u32 value; |
||||
|
||||
value = pvt->ctl_error_info.nbsl; |
||||
|
||||
return sprintf(data, "%x\n", value); |
||||
} |
||||
|
||||
/* store the NBSH (MCA NB Status High) value user desires */ |
||||
static ssize_t amd64_nbsh_store(struct mem_ctl_info *mci, const char *data, |
||||
size_t count) |
||||
{ |
||||
struct amd64_pvt *pvt = mci->pvt_info; |
||||
unsigned long value; |
||||
int ret = 0; |
||||
|
||||
ret = strict_strtoul(data, 16, &value); |
||||
if (ret != -EINVAL) { |
||||
debugf0("received NBSH= 0x%lx\n", value); |
||||
|
||||
pvt->ctl_error_info.nbsh = (u32) value; |
||||
|
||||
return count; |
||||
} |
||||
return ret; |
||||
} |
||||
|
||||
/* display back what the last NBSH value written */ |
||||
static ssize_t amd64_nbsh_show(struct mem_ctl_info *mci, char *data) |
||||
{ |
||||
struct amd64_pvt *pvt = mci->pvt_info; |
||||
u32 value; |
||||
|
||||
value = pvt->ctl_error_info.nbsh; |
||||
|
||||
return sprintf(data, "%x\n", value); |
||||
} |
||||
|
||||
/* accept and store the NBCFG (MCA NB Configuration) value user desires */ |
||||
static ssize_t amd64_nbcfg_store(struct mem_ctl_info *mci, |
||||
const char *data, size_t count) |
||||
{ |
||||
struct amd64_pvt *pvt = mci->pvt_info; |
||||
unsigned long value; |
||||
int ret = 0; |
||||
|
||||
ret = strict_strtoul(data, 16, &value); |
||||
if (ret != -EINVAL) { |
||||
debugf0("received NBCFG= 0x%lx\n", value); |
||||
|
||||
pvt->ctl_error_info.nbcfg = (u32) value; |
||||
|
||||
return count; |
||||
} |
||||
return ret; |
||||
} |
||||
|
||||
/* various show routines for the controls of a MCI */ |
||||
static ssize_t amd64_nbcfg_show(struct mem_ctl_info *mci, char *data) |
||||
{ |
||||
struct amd64_pvt *pvt = mci->pvt_info; |
||||
|
||||
return sprintf(data, "%x\n", pvt->ctl_error_info.nbcfg); |
||||
} |
||||
|
||||
|
||||
static ssize_t amd64_dhar_show(struct mem_ctl_info *mci, char *data) |
||||
{ |
||||
struct amd64_pvt *pvt = mci->pvt_info; |
||||
|
||||
return sprintf(data, "%x\n", pvt->dhar); |
||||
} |
||||
|
||||
|
||||
static ssize_t amd64_dbam_show(struct mem_ctl_info *mci, char *data) |
||||
{ |
||||
struct amd64_pvt *pvt = mci->pvt_info; |
||||
|
||||
return sprintf(data, "%x\n", pvt->dbam0); |
||||
} |
||||
|
||||
|
||||
static ssize_t amd64_topmem_show(struct mem_ctl_info *mci, char *data) |
||||
{ |
||||
struct amd64_pvt *pvt = mci->pvt_info; |
||||
|
||||
return sprintf(data, "%llx\n", pvt->top_mem); |
||||
} |
||||
|
||||
|
||||
static ssize_t amd64_topmem2_show(struct mem_ctl_info *mci, char *data) |
||||
{ |
||||
struct amd64_pvt *pvt = mci->pvt_info; |
||||
|
||||
return sprintf(data, "%llx\n", pvt->top_mem2); |
||||
} |
||||
|
||||
static ssize_t amd64_hole_show(struct mem_ctl_info *mci, char *data) |
||||
{ |
||||
u64 hole_base = 0; |
||||
u64 hole_offset = 0; |
||||
u64 hole_size = 0; |
||||
|
||||
amd64_get_dram_hole_info(mci, &hole_base, &hole_offset, &hole_size); |
||||
|
||||
return sprintf(data, "%llx %llx %llx\n", hole_base, hole_offset, |
||||
hole_size); |
||||
} |
||||
|
||||
/*
|
||||
* update NUM_DBG_ATTRS in case you add new members |
||||
*/ |
||||
struct mcidev_sysfs_attribute amd64_dbg_attrs[] = { |
||||
|
||||
{ |
||||
.attr = { |
||||
.name = "nbea_ctl", |
||||
.mode = (S_IRUGO | S_IWUSR) |
||||
}, |
||||
.show = amd64_nbea_show, |
||||
.store = amd64_nbea_store, |
||||
}, |
||||
{ |
||||
.attr = { |
||||
.name = "nbsl_ctl", |
||||
.mode = (S_IRUGO | S_IWUSR) |
||||
}, |
||||
.show = amd64_nbsl_show, |
||||
.store = amd64_nbsl_store, |
||||
}, |
||||
{ |
||||
.attr = { |
||||
.name = "nbsh_ctl", |
||||
.mode = (S_IRUGO | S_IWUSR) |
||||
}, |
||||
.show = amd64_nbsh_show, |
||||
.store = amd64_nbsh_store, |
||||
}, |
||||
{ |
||||
.attr = { |
||||
.name = "nbcfg_ctl", |
||||
.mode = (S_IRUGO | S_IWUSR) |
||||
}, |
||||
.show = amd64_nbcfg_show, |
||||
.store = amd64_nbcfg_store, |
||||
}, |
||||
{ |
||||
.attr = { |
||||
.name = "dhar", |
||||
.mode = (S_IRUGO) |
||||
}, |
||||
.show = amd64_dhar_show, |
||||
.store = NULL, |
||||
}, |
||||
{ |
||||
.attr = { |
||||
.name = "dbam", |
||||
.mode = (S_IRUGO) |
||||
}, |
||||
.show = amd64_dbam_show, |
||||
.store = NULL, |
||||
}, |
||||
{ |
||||
.attr = { |
||||
.name = "topmem", |
||||
.mode = (S_IRUGO) |
||||
}, |
||||
.show = amd64_topmem_show, |
||||
.store = NULL, |
||||
}, |
||||
{ |
||||
.attr = { |
||||
.name = "topmem2", |
||||
.mode = (S_IRUGO) |
||||
}, |
||||
.show = amd64_topmem2_show, |
||||
.store = NULL, |
||||
}, |
||||
{ |
||||
.attr = { |
||||
.name = "dram_hole", |
||||
.mode = (S_IRUGO) |
||||
}, |
||||
.show = amd64_hole_show, |
||||
.store = NULL, |
||||
}, |
||||
}; |
Loading…
Reference in new issue