diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-06-11 10:33:36 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-06-11 10:33:36 -0700 |
commit | c29f5ec022451546be1e0b24c330a0368e63e4a7 (patch) | |
tree | af3c2fc0ba3236fd4c1c2d1a4303fb5a3dc396ab /drivers/edac/amd64_edac_dbg.c | |
parent | d3d07d941fd80c173b6d690ded00ee5fb8302e06 (diff) | |
parent | c476c23b45a41eb4e3ea63af786cc4d74762fe11 (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/bp/bp
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/bp/bp: (26 commits)
amd64_edac: add MAINTAINERS entry
EDAC: do not enable modules by default
amd64_edac: do not enable module by default
amd64_edac: add module registration routines
amd64_edac: add ECC reporting initializers
amd64_edac: add EDAC core-related initializers
amd64_edac: add error decoding logic
amd64_edac: add ECC chipkill syndrome mapping table
amd64_edac: add per-family descriptors
amd64_edac: add F10h-and-later methods-p3
amd64_edac: add F10h-and-later methods-p2
amd64_edac: add F10h-and-later methods-p1
amd64_edac: add k8-specific methods
amd64_edac: assign DRAM chip select base and mask in a family-specific way
amd64_edac: add helper to dump relevant registers
amd64_edac: add DRAM address type conversion facilities
amd64_edac: add functionality to compute the DRAM hole
amd64_edac: add sys addr to memory controller mapping helpers
amd64_edac: add memory scrubber interface
amd64_edac: add MCA error types
...
Diffstat (limited to 'drivers/edac/amd64_edac_dbg.c')
-rw-r--r-- | drivers/edac/amd64_edac_dbg.c | 255 |
1 files changed, 255 insertions, 0 deletions
diff --git a/drivers/edac/amd64_edac_dbg.c b/drivers/edac/amd64_edac_dbg.c new file mode 100644 index 00000000000..0a41b248a4a --- /dev/null +++ b/drivers/edac/amd64_edac_dbg.c @@ -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, + }, +}; |