| Doug Thompson | fd3d678 | 2009-04-27 19:50:23 +0200 | [diff] [blame] | 1 | #include "amd64_edac.h" | 
 | 2 |  | 
 | 3 | /* | 
 | 4 |  * accept a hex value and store it into the virtual error register file, field: | 
 | 5 |  * nbeal and nbeah. Assume virtual error values have already been set for: NBSL, | 
 | 6 |  * NBSH and NBCFG. Then proceed to map the error values to a MC, CSROW and | 
 | 7 |  * CHANNEL | 
 | 8 |  */ | 
 | 9 | static ssize_t amd64_nbea_store(struct mem_ctl_info *mci, const char *data, | 
 | 10 | 				size_t count) | 
 | 11 | { | 
 | 12 | 	struct amd64_pvt *pvt = mci->pvt_info; | 
 | 13 | 	unsigned long long value; | 
 | 14 | 	int ret = 0; | 
 | 15 |  | 
 | 16 | 	ret = strict_strtoull(data, 16, &value); | 
 | 17 | 	if (ret != -EINVAL) { | 
 | 18 | 		debugf0("received NBEA= 0x%llx\n", value); | 
 | 19 |  | 
 | 20 | 		/* place the value into the virtual error packet */ | 
 | 21 | 		pvt->ctl_error_info.nbeal = (u32) value; | 
 | 22 | 		value >>= 32; | 
 | 23 | 		pvt->ctl_error_info.nbeah = (u32) value; | 
 | 24 |  | 
 | 25 | 		/* Process the Mapping request */ | 
 | 26 | 		/* TODO: Add race prevention */ | 
| Borislav Petkov | 549d042 | 2009-07-24 13:51:42 +0200 | [diff] [blame] | 27 | 		amd_decode_nb_mce(pvt->mc_node_id, &pvt->ctl_error_info, 1); | 
| Doug Thompson | fd3d678 | 2009-04-27 19:50:23 +0200 | [diff] [blame] | 28 |  | 
 | 29 | 		return count; | 
 | 30 | 	} | 
 | 31 | 	return ret; | 
 | 32 | } | 
 | 33 |  | 
 | 34 | /* display back what the last NBEA (MCA NB Address (MC4_ADDR)) was written */ | 
 | 35 | static ssize_t amd64_nbea_show(struct mem_ctl_info *mci, char *data) | 
 | 36 | { | 
 | 37 | 	struct amd64_pvt *pvt = mci->pvt_info; | 
 | 38 | 	u64 value; | 
 | 39 |  | 
 | 40 | 	value = pvt->ctl_error_info.nbeah; | 
 | 41 | 	value <<= 32; | 
 | 42 | 	value |= pvt->ctl_error_info.nbeal; | 
 | 43 |  | 
 | 44 | 	return sprintf(data, "%llx\n", value); | 
 | 45 | } | 
 | 46 |  | 
 | 47 | /* store the NBSL (MCA NB Status Low (MC4_STATUS)) value user desires */ | 
 | 48 | static ssize_t amd64_nbsl_store(struct mem_ctl_info *mci, const char *data, | 
 | 49 | 				size_t count) | 
 | 50 | { | 
 | 51 | 	struct amd64_pvt *pvt = mci->pvt_info; | 
 | 52 | 	unsigned long value; | 
 | 53 | 	int ret = 0; | 
 | 54 |  | 
 | 55 | 	ret = strict_strtoul(data, 16, &value); | 
 | 56 | 	if (ret != -EINVAL) { | 
 | 57 | 		debugf0("received NBSL= 0x%lx\n", value); | 
 | 58 |  | 
 | 59 | 		pvt->ctl_error_info.nbsl = (u32) value; | 
 | 60 |  | 
 | 61 | 		return count; | 
 | 62 | 	} | 
 | 63 | 	return ret; | 
 | 64 | } | 
 | 65 |  | 
 | 66 | /* display back what the last NBSL value written */ | 
 | 67 | static ssize_t amd64_nbsl_show(struct mem_ctl_info *mci, char *data) | 
 | 68 | { | 
 | 69 | 	struct amd64_pvt *pvt = mci->pvt_info; | 
 | 70 | 	u32 value; | 
 | 71 |  | 
 | 72 | 	value = pvt->ctl_error_info.nbsl; | 
 | 73 |  | 
 | 74 | 	return sprintf(data, "%x\n", value); | 
 | 75 | } | 
 | 76 |  | 
 | 77 | /* store the NBSH (MCA NB Status High) value user desires */ | 
 | 78 | static ssize_t amd64_nbsh_store(struct mem_ctl_info *mci, const char *data, | 
 | 79 | 				size_t count) | 
 | 80 | { | 
 | 81 | 	struct amd64_pvt *pvt = mci->pvt_info; | 
 | 82 | 	unsigned long value; | 
 | 83 | 	int ret = 0; | 
 | 84 |  | 
 | 85 | 	ret = strict_strtoul(data, 16, &value); | 
 | 86 | 	if (ret != -EINVAL) { | 
 | 87 | 		debugf0("received NBSH= 0x%lx\n", value); | 
 | 88 |  | 
 | 89 | 		pvt->ctl_error_info.nbsh = (u32) value; | 
 | 90 |  | 
 | 91 | 		return count; | 
 | 92 | 	} | 
 | 93 | 	return ret; | 
 | 94 | } | 
 | 95 |  | 
 | 96 | /* display back what the last NBSH value written */ | 
 | 97 | static ssize_t amd64_nbsh_show(struct mem_ctl_info *mci, char *data) | 
 | 98 | { | 
 | 99 | 	struct amd64_pvt *pvt = mci->pvt_info; | 
 | 100 | 	u32 value; | 
 | 101 |  | 
 | 102 | 	value = pvt->ctl_error_info.nbsh; | 
 | 103 |  | 
 | 104 | 	return sprintf(data, "%x\n", value); | 
 | 105 | } | 
 | 106 |  | 
 | 107 | /* accept and store the NBCFG (MCA NB Configuration) value user desires */ | 
 | 108 | static ssize_t amd64_nbcfg_store(struct mem_ctl_info *mci, | 
 | 109 | 					const char *data, size_t count) | 
 | 110 | { | 
 | 111 | 	struct amd64_pvt *pvt = mci->pvt_info; | 
 | 112 | 	unsigned long value; | 
 | 113 | 	int ret = 0; | 
 | 114 |  | 
 | 115 | 	ret = strict_strtoul(data, 16, &value); | 
 | 116 | 	if (ret != -EINVAL) { | 
 | 117 | 		debugf0("received NBCFG= 0x%lx\n", value); | 
 | 118 |  | 
 | 119 | 		pvt->ctl_error_info.nbcfg = (u32) value; | 
 | 120 |  | 
 | 121 | 		return count; | 
 | 122 | 	} | 
 | 123 | 	return ret; | 
 | 124 | } | 
 | 125 |  | 
 | 126 | /* various show routines for the controls of a MCI */ | 
 | 127 | static ssize_t amd64_nbcfg_show(struct mem_ctl_info *mci, char *data) | 
 | 128 | { | 
 | 129 | 	struct amd64_pvt *pvt = mci->pvt_info; | 
 | 130 |  | 
 | 131 | 	return sprintf(data, "%x\n", pvt->ctl_error_info.nbcfg); | 
 | 132 | } | 
 | 133 |  | 
 | 134 |  | 
 | 135 | static ssize_t amd64_dhar_show(struct mem_ctl_info *mci, char *data) | 
 | 136 | { | 
 | 137 | 	struct amd64_pvt *pvt = mci->pvt_info; | 
 | 138 |  | 
 | 139 | 	return sprintf(data, "%x\n", pvt->dhar); | 
 | 140 | } | 
 | 141 |  | 
 | 142 |  | 
 | 143 | static ssize_t amd64_dbam_show(struct mem_ctl_info *mci, char *data) | 
 | 144 | { | 
 | 145 | 	struct amd64_pvt *pvt = mci->pvt_info; | 
 | 146 |  | 
 | 147 | 	return sprintf(data, "%x\n", pvt->dbam0); | 
 | 148 | } | 
 | 149 |  | 
 | 150 |  | 
 | 151 | static ssize_t amd64_topmem_show(struct mem_ctl_info *mci, char *data) | 
 | 152 | { | 
 | 153 | 	struct amd64_pvt *pvt = mci->pvt_info; | 
 | 154 |  | 
 | 155 | 	return sprintf(data, "%llx\n", pvt->top_mem); | 
 | 156 | } | 
 | 157 |  | 
 | 158 |  | 
 | 159 | static ssize_t amd64_topmem2_show(struct mem_ctl_info *mci, char *data) | 
 | 160 | { | 
 | 161 | 	struct amd64_pvt *pvt = mci->pvt_info; | 
 | 162 |  | 
 | 163 | 	return sprintf(data, "%llx\n", pvt->top_mem2); | 
 | 164 | } | 
 | 165 |  | 
 | 166 | static ssize_t amd64_hole_show(struct mem_ctl_info *mci, char *data) | 
 | 167 | { | 
 | 168 | 	u64 hole_base = 0; | 
 | 169 | 	u64 hole_offset = 0; | 
 | 170 | 	u64 hole_size = 0; | 
 | 171 |  | 
 | 172 | 	amd64_get_dram_hole_info(mci, &hole_base, &hole_offset, &hole_size); | 
 | 173 |  | 
 | 174 | 	return sprintf(data, "%llx %llx %llx\n", hole_base, hole_offset, | 
 | 175 | 						 hole_size); | 
 | 176 | } | 
 | 177 |  | 
 | 178 | /* | 
 | 179 |  * update NUM_DBG_ATTRS in case you add new members | 
 | 180 |  */ | 
 | 181 | struct mcidev_sysfs_attribute amd64_dbg_attrs[] = { | 
 | 182 |  | 
 | 183 | 	{ | 
 | 184 | 		.attr = { | 
 | 185 | 			.name = "nbea_ctl", | 
 | 186 | 			.mode = (S_IRUGO | S_IWUSR) | 
 | 187 | 		}, | 
 | 188 | 		.show = amd64_nbea_show, | 
 | 189 | 		.store = amd64_nbea_store, | 
 | 190 | 	}, | 
 | 191 | 	{ | 
 | 192 | 		.attr = { | 
 | 193 | 			.name = "nbsl_ctl", | 
 | 194 | 			.mode = (S_IRUGO | S_IWUSR) | 
 | 195 | 		}, | 
 | 196 | 		.show = amd64_nbsl_show, | 
 | 197 | 		.store = amd64_nbsl_store, | 
 | 198 | 	}, | 
 | 199 | 	{ | 
 | 200 | 		.attr = { | 
 | 201 | 			.name = "nbsh_ctl", | 
 | 202 | 			.mode = (S_IRUGO | S_IWUSR) | 
 | 203 | 		}, | 
 | 204 | 		.show = amd64_nbsh_show, | 
 | 205 | 		.store = amd64_nbsh_store, | 
 | 206 | 	}, | 
 | 207 | 	{ | 
 | 208 | 		.attr = { | 
 | 209 | 			.name = "nbcfg_ctl", | 
 | 210 | 			.mode = (S_IRUGO | S_IWUSR) | 
 | 211 | 		}, | 
 | 212 | 		.show = amd64_nbcfg_show, | 
 | 213 | 		.store = amd64_nbcfg_store, | 
 | 214 | 	}, | 
 | 215 | 	{ | 
 | 216 | 		.attr = { | 
 | 217 | 			.name = "dhar", | 
 | 218 | 			.mode = (S_IRUGO) | 
 | 219 | 		}, | 
 | 220 | 		.show = amd64_dhar_show, | 
 | 221 | 		.store = NULL, | 
 | 222 | 	}, | 
 | 223 | 	{ | 
 | 224 | 		.attr = { | 
 | 225 | 			.name = "dbam", | 
 | 226 | 			.mode = (S_IRUGO) | 
 | 227 | 		}, | 
 | 228 | 		.show = amd64_dbam_show, | 
 | 229 | 		.store = NULL, | 
 | 230 | 	}, | 
 | 231 | 	{ | 
 | 232 | 		.attr = { | 
 | 233 | 			.name = "topmem", | 
 | 234 | 			.mode = (S_IRUGO) | 
 | 235 | 		}, | 
 | 236 | 		.show = amd64_topmem_show, | 
 | 237 | 		.store = NULL, | 
 | 238 | 	}, | 
 | 239 | 	{ | 
 | 240 | 		.attr = { | 
 | 241 | 			.name = "topmem2", | 
 | 242 | 			.mode = (S_IRUGO) | 
 | 243 | 		}, | 
 | 244 | 		.show = amd64_topmem2_show, | 
 | 245 | 		.store = NULL, | 
 | 246 | 	}, | 
 | 247 | 	{ | 
 | 248 | 		.attr = { | 
 | 249 | 			.name = "dram_hole", | 
 | 250 | 			.mode = (S_IRUGO) | 
 | 251 | 		}, | 
 | 252 | 		.show = amd64_hole_show, | 
 | 253 | 		.store = NULL, | 
 | 254 | 	}, | 
 | 255 | }; |