| 
									
										
										
										
											2009-04-27 19:50:23 +02:00
										 |  |  | #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 */ | 
					
						
							| 
									
										
										
										
											2009-07-24 13:51:42 +02:00
										 |  |  | 		amd_decode_nb_mce(pvt->mc_node_id, &pvt->ctl_error_info, 1); | 
					
						
							| 
									
										
										
										
											2009-04-27 19:50:23 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		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, | 
					
						
							|  |  |  | 	}, | 
					
						
							|  |  |  | }; |