• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /netgear-R7000-V1.0.7.12_1.2.5/components/opensource/linux/linux-2.6.36/drivers/edac/
1#include "amd64_edac.h"
2
3static ssize_t amd64_inject_section_show(struct mem_ctl_info *mci, char *buf)
4{
5	struct amd64_pvt *pvt = mci->pvt_info;
6	return sprintf(buf, "0x%x\n", pvt->injection.section);
7}
8
9/*
10 * store error injection section value which refers to one of 4 16-byte sections
11 * within a 64-byte cacheline
12 *
13 * range: 0..3
14 */
15static ssize_t amd64_inject_section_store(struct mem_ctl_info *mci,
16					  const char *data, size_t count)
17{
18	struct amd64_pvt *pvt = mci->pvt_info;
19	unsigned long value;
20	int ret = 0;
21
22	ret = strict_strtoul(data, 10, &value);
23	if (ret != -EINVAL) {
24
25		if (value > 3) {
26			amd64_printk(KERN_WARNING,
27				     "%s: invalid section 0x%lx\n",
28				     __func__, value);
29			return -EINVAL;
30		}
31
32		pvt->injection.section = (u32) value;
33		return count;
34	}
35	return ret;
36}
37
38static ssize_t amd64_inject_word_show(struct mem_ctl_info *mci, char *buf)
39{
40	struct amd64_pvt *pvt = mci->pvt_info;
41	return sprintf(buf, "0x%x\n", pvt->injection.word);
42}
43
44/*
45 * store error injection word value which refers to one of 9 16-bit word of the
46 * 16-byte (128-bit + ECC bits) section
47 *
48 * range: 0..8
49 */
50static ssize_t amd64_inject_word_store(struct mem_ctl_info *mci,
51					const char *data, size_t count)
52{
53	struct amd64_pvt *pvt = mci->pvt_info;
54	unsigned long value;
55	int ret = 0;
56
57	ret = strict_strtoul(data, 10, &value);
58	if (ret != -EINVAL) {
59
60		if (value > 8) {
61			amd64_printk(KERN_WARNING,
62				     "%s: invalid word 0x%lx\n",
63				     __func__, value);
64			return -EINVAL;
65		}
66
67		pvt->injection.word = (u32) value;
68		return count;
69	}
70	return ret;
71}
72
73static ssize_t amd64_inject_ecc_vector_show(struct mem_ctl_info *mci, char *buf)
74{
75	struct amd64_pvt *pvt = mci->pvt_info;
76	return sprintf(buf, "0x%x\n", pvt->injection.bit_map);
77}
78
79/*
80 * store 16 bit error injection vector which enables injecting errors to the
81 * corresponding bit within the error injection word above. When used during a
82 * DRAM ECC read, it holds the contents of the of the DRAM ECC bits.
83 */
84static ssize_t amd64_inject_ecc_vector_store(struct mem_ctl_info *mci,
85					     const char *data, size_t count)
86{
87	struct amd64_pvt *pvt = mci->pvt_info;
88	unsigned long value;
89	int ret = 0;
90
91	ret = strict_strtoul(data, 16, &value);
92	if (ret != -EINVAL) {
93
94		if (value & 0xFFFF0000) {
95			amd64_printk(KERN_WARNING,
96				     "%s: invalid EccVector: 0x%lx\n",
97				     __func__, value);
98			return -EINVAL;
99		}
100
101		pvt->injection.bit_map = (u32) value;
102		return count;
103	}
104	return ret;
105}
106
107/*
108 * Do a DRAM ECC read. Assemble staged values in the pvt area, format into
109 * fields needed by the injection registers and read the NB Array Data Port.
110 */
111static ssize_t amd64_inject_read_store(struct mem_ctl_info *mci,
112					const char *data, size_t count)
113{
114	struct amd64_pvt *pvt = mci->pvt_info;
115	unsigned long value;
116	u32 section, word_bits;
117	int ret = 0;
118
119	ret = strict_strtoul(data, 10, &value);
120	if (ret != -EINVAL) {
121
122		/* Form value to choose 16-byte section of cacheline */
123		section = F10_NB_ARRAY_DRAM_ECC |
124				SET_NB_ARRAY_ADDRESS(pvt->injection.section);
125		pci_write_config_dword(pvt->misc_f3_ctl,
126					F10_NB_ARRAY_ADDR, section);
127
128		word_bits = SET_NB_DRAM_INJECTION_READ(pvt->injection.word,
129						pvt->injection.bit_map);
130
131		/* Issue 'word' and 'bit' along with the READ request */
132		pci_write_config_dword(pvt->misc_f3_ctl,
133					F10_NB_ARRAY_DATA, word_bits);
134
135		debugf0("section=0x%x word_bits=0x%x\n", section, word_bits);
136
137		return count;
138	}
139	return ret;
140}
141
142/*
143 * Do a DRAM ECC write. Assemble staged values in the pvt area and format into
144 * fields needed by the injection registers.
145 */
146static ssize_t amd64_inject_write_store(struct mem_ctl_info *mci,
147					const char *data, size_t count)
148{
149	struct amd64_pvt *pvt = mci->pvt_info;
150	unsigned long value;
151	u32 section, word_bits;
152	int ret = 0;
153
154	ret = strict_strtoul(data, 10, &value);
155	if (ret != -EINVAL) {
156
157		/* Form value to choose 16-byte section of cacheline */
158		section = F10_NB_ARRAY_DRAM_ECC |
159				SET_NB_ARRAY_ADDRESS(pvt->injection.section);
160		pci_write_config_dword(pvt->misc_f3_ctl,
161					F10_NB_ARRAY_ADDR, section);
162
163		word_bits = SET_NB_DRAM_INJECTION_WRITE(pvt->injection.word,
164						pvt->injection.bit_map);
165
166		/* Issue 'word' and 'bit' along with the READ request */
167		pci_write_config_dword(pvt->misc_f3_ctl,
168					F10_NB_ARRAY_DATA, word_bits);
169
170		debugf0("section=0x%x word_bits=0x%x\n", section, word_bits);
171
172		return count;
173	}
174	return ret;
175}
176
177/*
178 * update NUM_INJ_ATTRS in case you add new members
179 */
180struct mcidev_sysfs_attribute amd64_inj_attrs[] = {
181
182	{
183		.attr = {
184			.name = "inject_section",
185			.mode = (S_IRUGO | S_IWUSR)
186		},
187		.show = amd64_inject_section_show,
188		.store = amd64_inject_section_store,
189	},
190	{
191		.attr = {
192			.name = "inject_word",
193			.mode = (S_IRUGO | S_IWUSR)
194		},
195		.show = amd64_inject_word_show,
196		.store = amd64_inject_word_store,
197	},
198	{
199		.attr = {
200			.name = "inject_ecc_vector",
201			.mode = (S_IRUGO | S_IWUSR)
202		},
203		.show = amd64_inject_ecc_vector_show,
204		.store = amd64_inject_ecc_vector_store,
205	},
206	{
207		.attr = {
208			.name = "inject_write",
209			.mode = (S_IRUGO | S_IWUSR)
210		},
211		.show = NULL,
212		.store = amd64_inject_write_store,
213	},
214	{
215		.attr = {
216			.name = "inject_read",
217			.mode = (S_IRUGO | S_IWUSR)
218		},
219		.show = NULL,
220		.store = amd64_inject_read_store,
221	},
222};
223