Commit | Line | Data |
---|---|---|
86530b38 AT |
1 | /* |
2 | * ========== Copyright Header Begin ========================================== | |
3 | * | |
4 | * OpenSPARC T2 Processor File: decode.c | |
5 | * Copyright (C) 1995-2007 Sun Microsystems, Inc. All Rights Reserved | |
6 | * 4150 Network Circle, Santa Clara, California 95054, U.S.A. | |
7 | * | |
8 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
9 | * | |
10 | * This program is free software; you can redistribute it and/or modify | |
11 | * it under the terms of the GNU General Public License as published by | |
12 | * the Free Software Foundation; version 2 of the License. | |
13 | * | |
14 | * This program is distributed in the hope that it will be useful, | |
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
17 | * GNU General Public License for more details. | |
18 | * | |
19 | * You should have received a copy of the GNU General Public License | |
20 | * along with this program; if not, write to the Free Software | |
21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
22 | * | |
23 | * For the avoidance of doubt, and except that if any non-GPL license | |
24 | * choice is available it will apply instead, Sun elects to use only | |
25 | * the General Public License version 2 (GPLv2) at this time for any | |
26 | * software where a choice of GPL license versions is made | |
27 | * available with the language indicating that GPLv2 or any later version | |
28 | * may be used, or where a choice of which version of the GPL is applied is | |
29 | * otherwise unspecified. | |
30 | * | |
31 | * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, | |
32 | * CA 95054 USA or visit www.sun.com if you need additional information or | |
33 | * have any questions. | |
34 | * | |
35 | * | |
36 | * ========== Copyright Header End ============================================ | |
37 | */ | |
38 | #include <stdlib.h> | |
39 | #include "vcsuser.h" | |
40 | ||
41 | #define BUFFER 1024 | |
42 | #define CHIPKILL 0x10000 | |
43 | ||
44 | #define DIMM_2G 0x3 | |
45 | #define DIMM_1G 0x2 | |
46 | #define DIMM_512 0x1 | |
47 | #define DIMM_256 0x0 | |
48 | ||
49 | #define DIMM_CONF_2 0x10 | |
50 | #define DIMM_CONF_4 0x20 | |
51 | #define DIMM_CONF_6 0x40 | |
52 | #define DIMM_CONF_8 0x80 | |
53 | ||
54 | #define DUAL_CHANNEL 0x100 | |
55 | #define SNG_CHANNEL 0x200 | |
56 | #define RANK_HIGH 0x400 | |
57 | #define RANK_LOW 0x800 | |
58 | ||
59 | #define STACK_DIMM 0x1000 | |
60 | #define RANK_DIMM 0x2000 | |
61 | ||
62 | #define PARTIAL_BANK_2BK 0x20000 | |
63 | #define PARTIAL_BANK_4BK 0x40000 | |
64 | ||
65 | #define HASH_PA 0x100000 | |
66 | ||
67 | ||
68 | int get_bank_set_mask(){ | |
69 | char *bank_set_mask_val = 0; | |
70 | unsigned int bank_set_mask = 0; | |
71 | bank_set_mask_val=mc_scan_plusargs("bank_set_mask="); | |
72 | if (!bank_set_mask_val){ | |
73 | bank_set_mask=0; | |
74 | } | |
75 | else | |
76 | bank_set_mask=strtoul(bank_set_mask_val, 0, 16); | |
77 | return(bank_set_mask); | |
78 | } | |
79 | ||
80 | long long pm_address_shift(long long addr, int shift) | |
81 | { | |
82 | long long shifted_addr; | |
83 | int bank_set_mask = get_bank_set_mask(); | |
84 | int pa6, pa7, pa8; | |
85 | ||
86 | if(shift > 0){ | |
87 | pa6 = (addr >> 6) & 0x1; | |
88 | if(shift == 1){ | |
89 | pa7 = (addr >> 7) & 0x1; | |
90 | pa8 = pa7; | |
91 | } | |
92 | else if(shift == 2){ | |
93 | pa7 = 0; | |
94 | pa8 = 0; | |
95 | } | |
96 | switch(bank_set_mask) { | |
97 | case 2: | |
98 | pa7 = 1; | |
99 | break; | |
100 | case 3: | |
101 | pa8 = 0; | |
102 | break; | |
103 | case 4: | |
104 | pa8 = 1; | |
105 | break; | |
106 | case 5: | |
107 | pa7 = 0; | |
108 | break; | |
109 | case 6: | |
110 | pa7 = !pa7; | |
111 | break; | |
112 | case 8: | |
113 | pa7 = 1; | |
114 | pa8 = 1; | |
115 | break; | |
116 | case 9: | |
117 | break; | |
118 | case 0xa: | |
119 | pa7 = 1; | |
120 | break; | |
121 | case 0xc: | |
122 | pa8 = 1; | |
123 | break; | |
124 | default: | |
125 | break; | |
126 | } | |
127 | shifted_addr = addr << shift; | |
128 | shifted_addr = shifted_addr >> 9; | |
129 | shifted_addr = (shifted_addr << 1) | pa8; | |
130 | shifted_addr = (shifted_addr << 1) | pa7; | |
131 | shifted_addr = (shifted_addr << 1) | pa6; | |
132 | shifted_addr = (shifted_addr << 6) | (addr & 0x3f); | |
133 | } | |
134 | else | |
135 | shifted_addr = addr; | |
136 | ||
137 | return(shifted_addr); | |
138 | } | |
139 | ||
140 | int pm_bank_s(long long addr, int shift) | |
141 | { | |
142 | int bank_s; | |
143 | addr = pm_address_shift(addr, shift); | |
144 | bank_s = (addr >> 7) & 0x3; | |
145 | return(bank_s); | |
146 | } | |
147 | ||
148 | long long fc_hash_pa(long long addr, int dimm_config) | |
149 | { | |
150 | long long hashed_pa = addr; | |
151 | long long pa_32_28 = 0; | |
152 | long long pa_17_13 = 0; | |
153 | long long pa_19_18 = 0; | |
154 | long long pa_12_11 = 0; | |
155 | long long hashed_pa_17_11 = 0; | |
156 | ||
157 | if(dimm_config & HASH_PA) | |
158 | { | |
159 | if(addr & 0x8000000000) // if PA[39] = 1, return addr | |
160 | return addr; | |
161 | ||
162 | pa_32_28 = ((addr & 0x1f0000000) >> 28); | |
163 | pa_17_13 = ((addr & 0x3e000) >> 13); | |
164 | pa_19_18 = ((addr & (0x3 << 18)) >> 18); | |
165 | pa_12_11 = ((addr & (0x3 << 11)) >> 11); | |
166 | //io_printf((char *)" pa_32_28 = %llx, pa_17_13 = %llx, pa_19_18 = %llx, pa_12_11 = %llx \n", pa_32_28, pa_17_13, pa_19_18, pa_12_11); | |
167 | hashed_pa_17_11 = (pa_32_28 ^ pa_17_13); | |
168 | hashed_pa_17_11 = (hashed_pa_17_11 << 2) | (pa_19_18 ^ pa_12_11); | |
169 | hashed_pa = (hashed_pa & 0xfffffc07ff) | (hashed_pa_17_11 << 11); | |
170 | //io_printf((char *)" ADDR = %llx, HASHED_PA = %llx\n",addr, hashed_pa); | |
171 | return hashed_pa; | |
172 | } | |
173 | else | |
174 | return addr; | |
175 | } | |
176 | ||
177 | long long address_decode(long long *addr, int dimm_config, int shift) | |
178 | { | |
179 | /* | |
180 | DUAL CHANNEL: | |
181 | dway = RAS[14:0], CAS[10:2], BA[2:0], CAS[1:0] | |
182 | [28:14] [13:5] [4:2] [1:0] | |
183 | SINGLE CHANNEL: | |
184 | dway = RAS[14:0], CAS[10:3], BA[2:0], CAS[2:0] | |
185 | [28:14] [13:6] [5:3] [2:0] | |
186 | */ | |
187 | ||
188 | long long dway = 0; | |
189 | int dimm_adjust = 0; | |
190 | int lsb_mask = 0; | |
191 | int msb_cas_bits_count = 0; | |
192 | int msb_cas = 0; | |
193 | int bank_addr = 0; | |
194 | long long dimm_addr = 0; | |
195 | int dimm_addr_bits = 0; | |
196 | ||
197 | long long saddr = *addr; | |
198 | //io_printf("-->before pm_address_shift, addr is %016llx\n",saddr); | |
199 | saddr = pm_address_shift(saddr, shift); | |
200 | //io_printf("-->after pm_address_shift, addr is %016llx\n",saddr); | |
201 | saddr = fc_hash_pa(saddr, dimm_config); | |
202 | //io_printf("-->after fc_hash_pa, addr is %016llx\n",saddr); | |
203 | ||
204 | //io_printf((char *)" entering address_decode. addr=%llx, dimm_config=%d\n",(saddr),dimm_config); | |
205 | if(dimm_config & DUAL_CHANNEL) | |
206 | { | |
207 | if(dimm_config & RANK_HIGH) // 2-ch Rank-high, Rank-dimm, Stack-dimm | |
208 | { | |
209 | if(dimm_config & DIMM_CONF_8) | |
210 | dimm_addr_bits = 3; | |
211 | else if(dimm_config & DIMM_CONF_6) | |
212 | dimm_addr_bits = 3; | |
213 | else if(dimm_config & DIMM_CONF_4) | |
214 | dimm_addr_bits = 2; | |
215 | else if(dimm_config & DIMM_CONF_2) | |
216 | dimm_addr_bits = 1; | |
217 | else dimm_addr_bits = 0; | |
218 | ||
219 | if (dimm_config & DIMM_1G) { // 1G | |
220 | if (dimm_config & DIMM_512) { // 2G | |
221 | dimm_addr = (((saddr) & ((0xffffffffff) >> (5 - dimm_addr_bits))) >> 35); | |
222 | dway = ((saddr) & ((0xffffffffff) >> 6)) >> 11; // RAS[14:0], CAS[10:3] | |
223 | dway = (dway << 1) | (((saddr) >> 34) & 1); // CAS[2] | |
224 | ||
225 | // last 5 bits are BA[2],BA[1],BA[0],PA[5],PA[4] | |
226 | // last 3 bits are common hence assigned in the end | |
227 | dway = (dway << 2) | (((saddr) >> 9) & 3); // BA[2:1] | |
228 | } | |
229 | else { // 1G | |
230 | dimm_addr = (((saddr) & ((0xffffffffff) >> (6 - dimm_addr_bits))) >> 34); | |
231 | dway = ((saddr) & ((0xffffffffff) >> 7)) >> 11; // RAS[13:0], CAS[10:3] | |
232 | dway = (dway << 1) | (((saddr) >> 33) & 1); // CAS[2] | |
233 | ||
234 | // last 5 bits are BA[2],BA[1],BA[0],PA[5],PA[4] | |
235 | // last 3 bits are common hence assigned in the end | |
236 | dway = (dway << 2) | (((saddr) >> 9) & 3); // BA[2:1] | |
237 | } | |
238 | } | |
239 | else { // 512 and 256 | |
240 | dimm_addr = (((saddr) & ((0xffffffffff) >> (8 - (dimm_config & 0xf) - dimm_addr_bits))) >> (32 + (dimm_config & 0xf))); | |
241 | dway = ((saddr) & ((0xffffffffff) >> (8 - (dimm_config & 0xf)))) >> 10; // RAS[13,12:0], CAS[10:2] | |
242 | ||
243 | // last 5 bits are 0,BA[1],BA[0],PA[5],PA[4] | |
244 | // last 3 bits are common hence assigned in the end | |
245 | dway = (dway << 1); | |
246 | dway = (dway << 1) | (((saddr) >> 9) & 1); // BA[1] | |
247 | } | |
248 | // restore bit 6 | |
249 | dway = (dway << 1) | (((saddr) >> 6) & 1); // BA[1] | |
250 | // Restore bit 4 & 5 | |
251 | dway = (dway << 2) | (((saddr) >> 4) & 3); // PA[5:4] | |
252 | //io_printf((char *)"dimm_addr = %x, dway = %llx\n",dimm_addr, dway); | |
253 | dway |= (dimm_addr << 29); | |
254 | } | |
255 | else if(dimm_config & RANK_LOW) // 2-ch rank-low | |
256 | { | |
257 | if(dimm_config & DIMM_CONF_8) | |
258 | dimm_addr_bits = 3; | |
259 | else if(dimm_config & DIMM_CONF_6) | |
260 | dimm_addr_bits = 3; | |
261 | else if(dimm_config & DIMM_CONF_4) | |
262 | dimm_addr_bits = 2; | |
263 | else if(dimm_config & DIMM_CONF_2) | |
264 | dimm_addr_bits = 1; | |
265 | else dimm_addr_bits = 0; | |
266 | ||
267 | if(dimm_config & RANK_DIMM) | |
268 | { | |
269 | if(dimm_config & DIMM_1G) { // 1G or 2G | |
270 | if(dimm_config & DIMM_512) // 2G | |
271 | dimm_adjust = 0; | |
272 | else | |
273 | dimm_adjust = 1; | |
274 | ||
275 | lsb_mask = 0; | |
276 | msb_cas_bits_count = 0; | |
277 | msb_cas = 0; | |
278 | bank_addr = 0; | |
279 | if(dimm_config & DIMM_CONF_8) { | |
280 | lsb_mask = 14; | |
281 | msb_cas_bits_count = 4; | |
282 | msb_cas = (((saddr) >> (34 - dimm_adjust)) & 0xf); // CAS[5:2] | |
283 | dimm_addr = (((saddr) >> 11) & 0x7); | |
284 | } | |
285 | else if(dimm_config & DIMM_CONF_4) { | |
286 | lsb_mask = 13; | |
287 | msb_cas_bits_count = 3; | |
288 | msb_cas = (((saddr) >> (34 - dimm_adjust)) & 0x7); // CAS[4:2] | |
289 | dimm_addr = (((saddr) >> 11) & 0x3); | |
290 | } | |
291 | else if(dimm_config & DIMM_CONF_2) { | |
292 | lsb_mask = 12; | |
293 | msb_cas_bits_count = 2; | |
294 | msb_cas = (((saddr) >> (34 - dimm_adjust)) & 0x3); // CAS[3:2] | |
295 | dimm_addr = (((saddr) >> 11) & 0x1); | |
296 | } | |
297 | else { | |
298 | lsb_mask = 11; | |
299 | msb_cas_bits_count = 1; | |
300 | msb_cas = (((saddr) >> (34 - dimm_adjust)) & 0x1); // CAS[2] | |
301 | dimm_addr = 0; | |
302 | } | |
303 | ||
304 | dway = ((saddr) & (0xffffffffff >> (6 + dimm_adjust))) >> lsb_mask; // RAS[14,13:0], CAS[10:6,5,4,3] | |
305 | dway = (dway << msb_cas_bits_count) | msb_cas; | |
306 | bank_addr = (((saddr) >> 9) & 0x3); // BA[2:1] | |
307 | dway = (dway << 2) | bank_addr; | |
308 | } // 1G or 2G | |
309 | else { // 512 or 256 | |
310 | if(dimm_config & DIMM_512) | |
311 | dimm_adjust = 0; | |
312 | else | |
313 | dimm_adjust = 1; | |
314 | ||
315 | lsb_mask = 0; | |
316 | msb_cas_bits_count = 0; | |
317 | msb_cas = 0; | |
318 | bank_addr = 0; | |
319 | if(dimm_config & DIMM_CONF_8) { | |
320 | lsb_mask = 13; | |
321 | msb_cas_bits_count = 3; | |
322 | msb_cas = (((saddr) >> (33 - dimm_adjust)) & 0x7); // CAS[4:2] | |
323 | dimm_addr = (((saddr) >> 10) & 0x7); | |
324 | } | |
325 | else if(dimm_config & DIMM_CONF_4) { | |
326 | lsb_mask = 12; | |
327 | msb_cas_bits_count = 2; | |
328 | msb_cas = (((saddr) >> (33 - dimm_adjust)) & 0x3); // CAS[3:2] | |
329 | dimm_addr = (((saddr) >> 10) & 0x3); | |
330 | } | |
331 | else if(dimm_config & DIMM_CONF_2) { | |
332 | lsb_mask = 11; | |
333 | msb_cas_bits_count = 1; | |
334 | msb_cas = (((saddr) >> (33 - dimm_adjust)) & 0x1); // CAS[2] | |
335 | dimm_addr = (((saddr) >> 10) & 0x1); | |
336 | } | |
337 | else { | |
338 | lsb_mask = 10; | |
339 | msb_cas_bits_count = 0; | |
340 | msb_cas = 0; | |
341 | dimm_addr = 0; | |
342 | } | |
343 | dway = ((saddr) & (0xffffffffff >> (7 + dimm_adjust))) >> lsb_mask; // RAS[13,12:0], CAS[10:5,4,3,2] | |
344 | dway = (dway << msb_cas_bits_count) | msb_cas; | |
345 | bank_addr = (((saddr) >> 9) & 0x1); // BA[1] | |
346 | dway = (dway << 1); // 0 for BA[2] | |
347 | dway = (dway << 1) | bank_addr; | |
348 | } // 512 or 256 | |
349 | ||
350 | ||
351 | // restore bit 6 | |
352 | dway = (dway << 1) | (((saddr) >> 6) & 1); // BA[0] | |
353 | // restore bit 5 & 4 | |
354 | dway = (dway << 2) | (((saddr) >> 4) & 0x3); // PA[5:4] | |
355 | dway |= (dimm_addr << 29); | |
356 | } // RANK_DIMM | |
357 | else if(dimm_config & STACK_DIMM) | |
358 | { | |
359 | if(dimm_config & DIMM_1G) { // 1G and 2G | |
360 | if(dimm_config & DIMM_512) | |
361 | dimm_adjust = 0; | |
362 | else | |
363 | dimm_adjust = 1; | |
364 | ||
365 | lsb_mask = 0; | |
366 | msb_cas_bits_count = 0; | |
367 | msb_cas = 0; | |
368 | bank_addr = 0; | |
369 | if(dimm_config & DIMM_CONF_8) { | |
370 | lsb_mask = 15; | |
371 | msb_cas_bits_count = 5; | |
372 | msb_cas = (((saddr) >> (34 - dimm_adjust)) & 0x1f); // CAS[6:2] | |
373 | dimm_addr = (((saddr) >> 11) & 0x7); | |
374 | } | |
375 | else if(dimm_config & DIMM_CONF_4) { | |
376 | lsb_mask = 14; | |
377 | msb_cas_bits_count = 4; | |
378 | msb_cas = (((saddr) >> (34 - dimm_adjust)) & 0xf); // CAS[5:2] | |
379 | dimm_addr = (((saddr) >> 11) & 0x3); | |
380 | } | |
381 | else if(dimm_config & DIMM_CONF_2) { | |
382 | lsb_mask = 13; | |
383 | msb_cas_bits_count = 3; | |
384 | msb_cas = (((saddr) >> (34 - dimm_adjust)) & 0x7); // CAS[4:2] | |
385 | dimm_addr = (((saddr) >> 11) & 0x1); | |
386 | } | |
387 | else { | |
388 | lsb_mask = 12; | |
389 | msb_cas_bits_count = 2; | |
390 | msb_cas = (((saddr) >> (34 - dimm_adjust)) & 0x3); // CAS[3:2] | |
391 | dimm_addr = 0; | |
392 | } | |
393 | ||
394 | dway = ((saddr) & (0xffffffffff >> (6 + dimm_adjust))) >> lsb_mask; // RAS[14,13:0], CAS[10:7,6,5,4] | |
395 | dway = (dway << msb_cas_bits_count) | msb_cas; | |
396 | bank_addr = (((saddr) >> 9) & 0x3); // BA[2:1] | |
397 | dway = (dway << 2) | bank_addr; | |
398 | } | |
399 | else { // 512 & 256 | |
400 | if(dimm_config & DIMM_512) | |
401 | dimm_adjust = 0; | |
402 | else | |
403 | dimm_adjust = 1; | |
404 | ||
405 | lsb_mask = 0; | |
406 | msb_cas_bits_count = 0; | |
407 | msb_cas = 0; | |
408 | bank_addr = 0; | |
409 | if(dimm_config & DIMM_CONF_8) { | |
410 | lsb_mask = 14; | |
411 | msb_cas_bits_count = 4; | |
412 | msb_cas = (((saddr) >> (33 - dimm_adjust)) & 0xf); // CAS[5:2] | |
413 | dimm_addr = (((saddr) >> 10) & 0x7); | |
414 | } | |
415 | else if(dimm_config & DIMM_CONF_4) { | |
416 | lsb_mask = 13; | |
417 | msb_cas_bits_count = 3; | |
418 | msb_cas = (((saddr) >> (33 - dimm_adjust)) & 0x7); // CAS[4:2] | |
419 | dimm_addr = (((saddr) >> 10) & 0x3); | |
420 | } | |
421 | else if(dimm_config & DIMM_CONF_2) { | |
422 | lsb_mask = 12; | |
423 | msb_cas_bits_count = 2; | |
424 | msb_cas = (((saddr) >> (33 - dimm_adjust)) & 0x3); // CAS[3:2] | |
425 | dimm_addr = (((saddr) >> 10) & 0x1); | |
426 | } | |
427 | else { | |
428 | lsb_mask = 11; | |
429 | msb_cas_bits_count = 1; | |
430 | msb_cas = (((saddr) >> (33 - dimm_adjust)) & 0x1); // CAS[2] | |
431 | dimm_addr = 0; | |
432 | } | |
433 | dway = ((saddr) & (0xffffffffff >> (7 + dimm_adjust))) >> lsb_mask; // RAS[13,12:0], CAS[10:6,5,4,3] | |
434 | dway = (dway << msb_cas_bits_count) | msb_cas; | |
435 | bank_addr = (((saddr) >> 9) & 0x1); // BA[1] | |
436 | dway = (dway << 1); // 0 for BA[2] | |
437 | dway = (dway << 1) | bank_addr; | |
438 | } // 512 & 256 | |
439 | ||
440 | // restore bit 6 | |
441 | dway = (dway << 1) | (((saddr) >> 6) & 1); // BA[0] | |
442 | // restore bit 5 & 4 | |
443 | dway = (dway << 2) | (((saddr) >> 4) & 0x3); // PA[5:4] | |
444 | dway |= (dimm_addr << 29); | |
445 | } // STACK_DIMM | |
446 | } // 2-ch rk-low | |
447 | } | |
448 | else // SNG_CHANNEL | |
449 | { | |
450 | if(dimm_config & RANK_HIGH) // 1-ch Rank-high, rank-dimm, stack-dimm | |
451 | { | |
452 | if(dimm_config & DIMM_CONF_8) | |
453 | dimm_addr_bits = 3; | |
454 | else if(dimm_config & DIMM_CONF_6) | |
455 | dimm_addr_bits = 3; | |
456 | else if(dimm_config & DIMM_CONF_4) | |
457 | dimm_addr_bits = 2; | |
458 | else if(dimm_config & DIMM_CONF_2) | |
459 | dimm_addr_bits = 1; | |
460 | else dimm_addr_bits = 0; | |
461 | ||
462 | if (dimm_config & DIMM_1G) { // 1G & 2G | |
463 | if (dimm_config & DIMM_512) | |
464 | dimm_adjust = 0; | |
465 | else | |
466 | dimm_adjust = 1; | |
467 | ||
468 | dimm_addr = (((saddr) & ((0xffffffffff) >> (6 + dimm_adjust - dimm_addr_bits))) >> (34 - dimm_adjust)); | |
469 | ||
470 | // RAS, CAS[10:4] | |
471 | dway = ((saddr) & ((0xffffffffff) >> (7 + dimm_adjust))) >> 11; | |
472 | // CAS[3] | |
473 | dway = (dway << 1) | (((saddr) >> (33 - dimm_adjust)) & 1); | |
474 | ||
475 | ||
476 | // last 6 bits are BA[2],BA[1],BA[0],CAS[2],CAS[1],CAS[0] | |
477 | dway = (dway << 2) | (((saddr) >> 9) & 3); // BA[2:1] | |
478 | dway = (dway << 1) | (((saddr) >> 6) & 1); // BA[0] | |
479 | dway = (dway << 2) | (((saddr) >> 4) & 0x3); // CAS[2], CAS[1] | |
480 | dway = (dway << 1); // CAS[0] | |
481 | } | |
482 | else { // 512 & 256 | |
483 | dimm_addr = (((saddr) & ((0xffffffffff) >> (9 - (dimm_config & 0xf) - dimm_addr_bits))) >> (31 + (dimm_config & 0xf))); | |
484 | // RAS, CAS[10:3] | |
485 | dway = ((saddr) & ((0xffffffffff) >> (9 - (dimm_config & 0xf)))) >> 10; | |
486 | ||
487 | ||
488 | // last 6 bits are BA[2],BA[1],BA[0],CAS[2],CAS[1],CAS[0] | |
489 | dway = (dway << 1); // BA[2] | |
490 | dway = (dway << 1) | (((saddr) >> 9) & 1); // BA[1] | |
491 | dway = (dway << 1) | (((saddr) >> 6) & 1); // BA[0] | |
492 | dway = (dway << 2) | (((saddr) >> 4) & 0x3); // CAS[2], CAS[1] | |
493 | dway = (dway << 1); // CAS[0] | |
494 | } | |
495 | //io_printf((char *)"dimm_addr = %x, dway = %llx\n",dimm_addr, dway); | |
496 | dway |= (dimm_addr << 29); | |
497 | } | |
498 | else if(dimm_config & RANK_LOW) // 1-ch rank-low | |
499 | { | |
500 | if(dimm_config & DIMM_CONF_8) | |
501 | dimm_addr_bits = 3; | |
502 | else if(dimm_config & DIMM_CONF_6) | |
503 | dimm_addr_bits = 3; | |
504 | else if(dimm_config & DIMM_CONF_4) | |
505 | dimm_addr_bits = 2; | |
506 | else if(dimm_config & DIMM_CONF_2) | |
507 | dimm_addr_bits = 1; | |
508 | else dimm_addr_bits = 0; | |
509 | ||
510 | ||
511 | if(dimm_config & RANK_DIMM) | |
512 | { | |
513 | if(dimm_config & DIMM_1G) { // 1G & 2G | |
514 | if(dimm_config & DIMM_512) | |
515 | dimm_adjust = 0; | |
516 | else | |
517 | dimm_adjust = 1; | |
518 | ||
519 | lsb_mask = 0; | |
520 | msb_cas_bits_count = 0; | |
521 | msb_cas = 0; | |
522 | bank_addr = 0; | |
523 | if(dimm_config & DIMM_CONF_8) { | |
524 | lsb_mask = 14; | |
525 | msb_cas_bits_count = 4; | |
526 | msb_cas = (((saddr) >> (33 - dimm_adjust)) & 0xf); | |
527 | dimm_addr = (((saddr) >> 11) & 0x7); | |
528 | } | |
529 | else if(dimm_config & DIMM_CONF_4) { | |
530 | lsb_mask = 13; | |
531 | msb_cas_bits_count = 3; | |
532 | msb_cas = (((saddr) >> (33 - dimm_adjust)) & 0x7); | |
533 | dimm_addr = (((saddr) >> 11) & 0x3); | |
534 | } | |
535 | else if(dimm_config & DIMM_CONF_2) { | |
536 | lsb_mask = 12; | |
537 | msb_cas_bits_count = 2; | |
538 | msb_cas = (((saddr) >> (33 - dimm_adjust)) & 0x3); | |
539 | dimm_addr = (((saddr) >> 11) & 0x1); | |
540 | } | |
541 | else { | |
542 | lsb_mask = 11; | |
543 | msb_cas_bits_count = 1; | |
544 | msb_cas = (((saddr) >> (33 - dimm_adjust)) & 0x1); | |
545 | dimm_addr = 0; | |
546 | } | |
547 | ||
548 | // RAS, CAS[10:7,6,5,4] | |
549 | dway = ((saddr) & (0xffffffffff >> (7 + dimm_adjust))) >> lsb_mask; | |
550 | dway = (dway << msb_cas_bits_count) | msb_cas; | |
551 | ||
552 | // BA[2:0] | |
553 | bank_addr = (((saddr) >> 9) & 0x3); | |
554 | bank_addr = (bank_addr << 1) | (((saddr) >> 6) & 1); | |
555 | dway = (dway << 3) | bank_addr; | |
556 | ||
557 | // CAS[2],CAS[1],CAS[0] | |
558 | dway = (dway << 2) | (((saddr) >> 4) & 0x3); // CAS[2], CAS[1] | |
559 | dway = (dway << 1); // CAS[0] | |
560 | } // 1G & 2G | |
561 | else { // 512 & 256 | |
562 | if(dimm_config & DIMM_512) | |
563 | dimm_adjust = 0; | |
564 | else | |
565 | dimm_adjust = 1; | |
566 | ||
567 | lsb_mask = 0; | |
568 | msb_cas_bits_count = 0; | |
569 | msb_cas = 0; | |
570 | bank_addr = 0; | |
571 | if(dimm_config & DIMM_CONF_8) { | |
572 | lsb_mask = 13; | |
573 | msb_cas_bits_count = 3; | |
574 | msb_cas = (((saddr) >> (32 - dimm_adjust)) & 0x7); | |
575 | dimm_addr = (((saddr) >> 10) & 0x7); | |
576 | } | |
577 | else if(dimm_config & DIMM_CONF_4) { | |
578 | lsb_mask = 12; | |
579 | msb_cas_bits_count = 2; | |
580 | msb_cas = (((saddr) >> (32 - dimm_adjust)) & 0x3); | |
581 | dimm_addr = (((saddr) >> 10) & 0x3); | |
582 | } | |
583 | else if(dimm_config & DIMM_CONF_2) { | |
584 | lsb_mask = 11; | |
585 | msb_cas_bits_count = 1; | |
586 | msb_cas = (((saddr) >> (32 - dimm_adjust)) & 0x1); | |
587 | dimm_addr = (((saddr) >> 10) & 0x1); | |
588 | } | |
589 | else { | |
590 | lsb_mask = 10; | |
591 | msb_cas_bits_count = 0; | |
592 | msb_cas = 0; | |
593 | dimm_addr = 0; | |
594 | } | |
595 | // RAS, CAS[10:6,5,4,3] | |
596 | dway = ((saddr) & (0xffffffffff >> (8 + dimm_adjust))) >> lsb_mask; | |
597 | dway = (dway << msb_cas_bits_count) | msb_cas; | |
598 | ||
599 | // BA | |
600 | bank_addr = (((saddr) >> 9) & 0x1); | |
601 | bank_addr = (bank_addr << 1) | (((saddr) >> 6) & 1); | |
602 | dway = (dway << 1); // BA[2] | |
603 | dway = (dway << 2) | (bank_addr & 0x3); | |
604 | ||
605 | // CAS[2],CAS[1],CAS[0] | |
606 | dway = (dway << 2) | (((saddr) >> 4) & 0x3); // CAS[2], CAS[1] | |
607 | dway = (dway << 1); // CAS[0] | |
608 | } | |
609 | dway |= (dimm_addr << 29); | |
610 | } | |
611 | else if(dimm_config & STACK_DIMM) | |
612 | { | |
613 | if(dimm_config & DIMM_1G) { // 1G and 2G | |
614 | if(dimm_config & DIMM_512) | |
615 | dimm_adjust = 0; | |
616 | else | |
617 | dimm_adjust = 1; | |
618 | ||
619 | lsb_mask = 0; | |
620 | msb_cas_bits_count = 0; | |
621 | msb_cas = 0; | |
622 | bank_addr = 0; | |
623 | if(dimm_config & DIMM_CONF_8) { | |
624 | lsb_mask = 15; | |
625 | msb_cas_bits_count = 5; | |
626 | msb_cas = (((saddr) >> (33 - dimm_adjust)) & 0x1f); | |
627 | dimm_addr = (((saddr) >> 11) & 0x7); | |
628 | } | |
629 | else if(dimm_config & DIMM_CONF_4) { | |
630 | lsb_mask = 14; | |
631 | msb_cas_bits_count = 4; | |
632 | msb_cas = (((saddr) >> (33 - dimm_adjust)) & 0xf); | |
633 | dimm_addr = (((saddr) >> 11) & 0x3); | |
634 | } | |
635 | else if(dimm_config & DIMM_CONF_2) { | |
636 | lsb_mask = 13; | |
637 | msb_cas_bits_count = 3; | |
638 | msb_cas = (((saddr) >> (33 - dimm_adjust)) & 0x7); | |
639 | dimm_addr = (((saddr) >> 11) & 0x1); | |
640 | } | |
641 | else { | |
642 | lsb_mask = 12; | |
643 | msb_cas_bits_count = 2; | |
644 | msb_cas = (((saddr) >> (33 - dimm_adjust)) & 0x3); | |
645 | dimm_addr = 0; | |
646 | } | |
647 | // RAS, CAS[10:8,7,6,5] | |
648 | dway = ((saddr) & (0xffffffffff >> (7 + dimm_adjust))) >> lsb_mask; | |
649 | dway = (dway << msb_cas_bits_count) | msb_cas; | |
650 | ||
651 | // BA | |
652 | bank_addr = (((saddr) >> 9) & 0x3); | |
653 | bank_addr = (bank_addr << 1) | (((saddr) >> 6) & 1); | |
654 | dway = (dway << 3) | bank_addr; | |
655 | ||
656 | // CAS[2],CAS[1],CAS[0] | |
657 | dway = (dway << 2) | (((saddr) >> 4) & 0x3); // CAS[2], CAS[1] | |
658 | dway = (dway << 1); // CAS[0] | |
659 | } | |
660 | else { // 512 & 256 | |
661 | if(dimm_config & DIMM_512) | |
662 | dimm_adjust = 0; | |
663 | else | |
664 | dimm_adjust = 1; | |
665 | ||
666 | lsb_mask = 0; | |
667 | msb_cas_bits_count = 0; | |
668 | msb_cas = 0; | |
669 | bank_addr = 0; | |
670 | if(dimm_config & DIMM_CONF_8) { | |
671 | lsb_mask = 14; | |
672 | msb_cas_bits_count = 4; | |
673 | msb_cas = (((saddr) >> (32 - dimm_adjust)) & 0xf); | |
674 | dimm_addr = (((saddr) >> 10) & 0x7); | |
675 | } | |
676 | else if(dimm_config & DIMM_CONF_4) { | |
677 | lsb_mask = 13; | |
678 | msb_cas_bits_count = 3; | |
679 | msb_cas = (((saddr) >> (32 - dimm_adjust)) & 0x7); | |
680 | dimm_addr = (((saddr) >> 10) & 0x3); | |
681 | } | |
682 | else if(dimm_config & DIMM_CONF_2) { | |
683 | lsb_mask = 12; | |
684 | msb_cas_bits_count = 2; | |
685 | msb_cas = (((saddr) >> (32 - dimm_adjust)) & 0x3); | |
686 | dimm_addr = (((saddr) >> 10) & 0x1); | |
687 | } | |
688 | else { | |
689 | lsb_mask = 11; | |
690 | msb_cas_bits_count = 1; | |
691 | msb_cas = (((saddr) >> (32 - dimm_adjust)) & 0x1); | |
692 | dimm_addr = 0; | |
693 | } | |
694 | // RAS, CAS[10:7,6,5,4] | |
695 | dway = ((saddr) & (0xffffffffff >> (8 + dimm_adjust))) >> lsb_mask; | |
696 | dway = (dway << msb_cas_bits_count) | msb_cas; | |
697 | ||
698 | // BA | |
699 | bank_addr = (((saddr) >> 9) & 0x1); | |
700 | bank_addr = (bank_addr << 1) | (((saddr) >> 6) & 1); | |
701 | dway = (dway << 1); // BA[2] | |
702 | dway = (dway << 2) | (bank_addr & 0x3); | |
703 | ||
704 | // CAS[2],CAS[1],CAS[0] | |
705 | dway = (dway << 2) | (((saddr) >> 4) & 0x3); // CAS[2], CAS[1] | |
706 | dway = (dway << 1); // CAS[0] | |
707 | } | |
708 | dway |= (dimm_addr << 29); | |
709 | } | |
710 | } | |
711 | ||
712 | } | |
713 | //io_printf((char *)" returning dway=%llx\n",dway); | |
714 | return dway; | |
715 | } | |
716 | ||
717 | long long decode_cs(long long *addr, int dimm_config, int shift) | |
718 | { | |
719 | long long cs = 0; | |
720 | int channel_adjust = 0, bit_adjust = 0; | |
721 | ||
722 | long long saddr = *addr; | |
723 | saddr = pm_address_shift(saddr, shift); | |
724 | saddr = fc_hash_pa(saddr, dimm_config); | |
725 | ||
726 | //io_printf((char *)" cs_decode, addr=%llx, dimm_config=%d\n",saddr,dimm_config); | |
727 | if(dimm_config & RANK_DIMM) | |
728 | { | |
729 | cs = 0; | |
730 | } | |
731 | else | |
732 | { | |
733 | if(dimm_config & RANK_HIGH) | |
734 | { | |
735 | if(dimm_config & DUAL_CHANNEL) | |
736 | channel_adjust = 0; | |
737 | else | |
738 | channel_adjust = 1; | |
739 | ||
740 | if(dimm_config & DIMM_1G) | |
741 | { | |
742 | if(dimm_config & DIMM_512) | |
743 | bit_adjust = 0; | |
744 | else | |
745 | bit_adjust = 1; | |
746 | } | |
747 | else if(dimm_config & DIMM_512) | |
748 | bit_adjust = 2; | |
749 | else | |
750 | bit_adjust = 3; | |
751 | ||
752 | if(dimm_config & DIMM_CONF_8) | |
753 | cs = ((saddr) >> (38 - channel_adjust - bit_adjust)) & 0x1; | |
754 | else if(dimm_config & DIMM_CONF_4) | |
755 | cs = ((saddr) >> (37 - channel_adjust - bit_adjust)) & 0x1; | |
756 | else if(dimm_config & DIMM_CONF_2) | |
757 | cs = ((saddr) >> (36 - channel_adjust - bit_adjust)) & 0x1; | |
758 | else | |
759 | cs = ((saddr) >> (35 - channel_adjust - bit_adjust)) & 0x1; | |
760 | } | |
761 | else | |
762 | { | |
763 | ||
764 | if(dimm_config & DIMM_1G) // 1G or 2G | |
765 | bit_adjust = 0; | |
766 | else // 512 or 256 | |
767 | bit_adjust = 1; | |
768 | ||
769 | if(dimm_config & DIMM_CONF_8) | |
770 | cs = ((saddr) >> (14 - bit_adjust)) & 0x1; | |
771 | else if(dimm_config & DIMM_CONF_6) | |
772 | cs = ((saddr) >> (12 - bit_adjust)) & 0x1; | |
773 | else if(dimm_config & DIMM_CONF_4) | |
774 | cs = ((saddr) >> (13 - bit_adjust)) & 0x1; | |
775 | else if(dimm_config & DIMM_CONF_2) | |
776 | cs = ((saddr) >> (12 - bit_adjust)) & 0x1; | |
777 | else | |
778 | cs = ((saddr) >> (11 - bit_adjust)) & 0x1; | |
779 | } | |
780 | } | |
781 | ||
782 | //io_printf((char *)" cs=%d\n",cs); | |
783 | return cs; | |
784 | } | |
785 | ||
786 | int check_if_valid_PA(long long addr, int dimm_config, int shift) | |
787 | { | |
788 | int dimm_adjust = 0; | |
789 | int rank_adjust = 0; | |
790 | int channel_adjust = 0; | |
791 | int side_adjust = 0; | |
792 | int size_adjust = 0; | |
793 | long long pa_mask_l = 0; | |
794 | ||
795 | if(dimm_config & DIMM_CONF_8) | |
796 | dimm_adjust = 0; | |
797 | else if(dimm_config & DIMM_CONF_4) | |
798 | dimm_adjust = 1; | |
799 | else if(dimm_config & DIMM_CONF_2) | |
800 | dimm_adjust = 2; | |
801 | else | |
802 | dimm_adjust = 3; | |
803 | ||
804 | ||
805 | //if(dimm_config & RANK_LOW) | |
806 | // rank_adjust = 1; | |
807 | //else | |
808 | rank_adjust = 0; | |
809 | ||
810 | if(dimm_config & STACK_DIMM) | |
811 | side_adjust = 0; | |
812 | else | |
813 | side_adjust = 1; | |
814 | ||
815 | if(dimm_config & SNG_CHANNEL) | |
816 | channel_adjust = 1; | |
817 | else | |
818 | channel_adjust = 0; | |
819 | ||
820 | if(dimm_config & DIMM_1G) | |
821 | if(dimm_config & DIMM_512) | |
822 | size_adjust = 0; | |
823 | else | |
824 | size_adjust = 1; | |
825 | else if(dimm_config & DIMM_512) | |
826 | size_adjust = 2; | |
827 | else | |
828 | size_adjust = 3; | |
829 | ||
830 | pa_mask_l = (0xffffffffff >> (1 + channel_adjust + side_adjust + size_adjust + rank_adjust + dimm_adjust)); | |
831 | ||
832 | if(shift > 0) | |
833 | addr = addr << shift; | |
834 | ||
835 | if(addr & (~pa_mask_l)) { | |
836 | io_printf((char *)"Warning: Out-of-bound address detected. Address is %llx\n",addr); | |
837 | return -1; | |
838 | } | |
839 | return 1; | |
840 | } |