1 /* $NetBSD: spdmemvar.h,v 1.6 2008/11/22 13:21:21 pgoyette Exp $ */
4 * Copyright (c) 2007 Paul Goyette
5 * Copyright (c) 2007 Tobias Nygren
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. The name of the author may not be used to endorse or promote products
17 * derived from this software without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
33 * This information is extracted from JEDEC standard SPD4_01 (www.jedec.org)
36 #if BYTE_ORDER == BIG_ENDIAN
37 #define SPD_BITFIELD(a, b, c, d) d; c; b; a
39 #define SPD_BITFIELD(a, b, c, d) a; b; c; d
42 struct spdmem_fpm
{ /* FPM and EDO DIMMS */
46 uint16_t fpm_datawidth
; /* endian-sensitive */
52 uint8_t fpm_refresh
:7, \
53 uint8_t fpm_selfrefresh
:1, , \
55 uint8_t fpm_dram_dramwidth
;
56 uint8_t fpm_dram_eccwidth
;
57 uint8_t fpm_unused2
[17];
59 uint8_t fpm_unused3
[30];
63 struct spdmem_sdram
{ /* PC66/PC100/PC133 SDRAM */
66 uint8_t sdr_rows2
:4, , \
70 uint8_t sdr_cols2
:4, , \
73 uint16_t sdr_datawidth
; /* endian-sensitive */
76 uint8_t sdr_cycle_tenths
:4, \
77 uint8_t sdr_cycle_whole
:4, , \
80 uint8_t sdr_tAC_tenths
:4, \
81 uint8_t sdr_tAC_whole
:4, , \
85 uint8_t sdr_refresh
:7, \
86 uint8_t sdr_selfrefresh
:1, , \
89 uint8_t sdr_dramwidth
:7, \
90 uint8_t sdr_dram_asym_bank2
:1, ,\
93 uint8_t sdr_eccwidth
:7, \
94 uint8_t sdr_ecc_asym_bank2
:1, , \
96 uint8_t sdr_min_clk_delay
;
98 uint8_t sdr_burstlengths
:4, \
99 uint8_t sdr_unused1
:4, , \
101 uint8_t sdr_banks_per_chip
;
105 uint8_t sdr_mod_attrs
;
106 uint8_t sdr_dev_attrs
;
107 uint8_t sdr_min_cc_1
;
108 uint8_t sdr_max_tAC_1
;
109 uint8_t sdr_min_cc_2
;
110 uint8_t sdr_max_tAC_2
;
115 uint8_t sdr_module_rank_density
;
117 #define sdr_superset sdr_tIS
121 uint8_t sdr_unused2
[5];
123 uint8_t sdr_unused3
[18];
125 uint8_t sdr_super_tech
;
134 uint16_t rom_datawidth
; /* endian-sensitive */
136 uint16_t rom_tAA
; /* endian-sensitive */
141 uint16_t rom_tCE
; /* endian-sensitive */
142 uint8_t rom_burstlength
;
143 uint8_t rom_unused2
[14];
144 uint8_t rom_superset
[31];
149 struct spdmem_ddr
{ /* Dual Data Rate SDRAM */
151 uint8_t ddr_rows
:4, \
152 uint8_t ddr_rows2
:4, , \
155 uint8_t ddr_cols
:4, \
156 uint8_t ddr_cols2
:4, , \
159 uint16_t ddr_datawidth
; /* endian-sensitive */
162 uint8_t ddr_cycle_tenths
:4, \
163 uint8_t ddr_cycle_whole
:4, , \
166 uint8_t ddr_tAC_hundredths
:4, \
167 uint8_t ddr_tAC_tenths
:4, , \
171 uint8_t ddr_refresh
:7, \
172 uint8_t ddr_selfrefresh
:1, , \
175 uint8_t ddr_dramwidth
:7, \
176 uint8_t ddr_dram_asym_bank2
:1, ,\
179 uint8_t ddr_eccwidth
:7, \
180 uint8_t ddr_ecc_asym_bank2
:1, , \
182 uint8_t ddr_min_clk_delay
;
184 uint8_t ddr_burstlengths
:4, \
185 uint8_t ddr_unused1
:4, , \
187 uint8_t ddr_banks_per_chip
;
191 uint8_t ddr_mod_attrs
;
192 uint8_t ddr_dev_attrs
;
193 uint8_t ddr_min_cc_05
;
194 uint8_t ddr_max_tAC_05
;
195 uint8_t ddr_min_cc_1
;
196 uint8_t ddr_max_tAC_1
;
201 uint8_t ddr_module_rank_density
;
203 #define ddr_superset ddr_tIS
207 uint8_t ddr_unused2
[5];
215 uint8_t ddr_unused4
[15];
219 struct spdmem_ddr2
{ /* Dual Data Rate 2 SDRAM */
221 uint8_t ddr2_rows
:5, \
222 uint8_t ddr2_unused1
:3, , \
225 uint8_t ddr2_cols
:4, \
226 uint8_t ddr2_unused2
:4, , \
229 uint8_t ddr2_ranks
:3,
230 uint8_t ddr2_cardoncard
:1, \
231 uint8_t ddr2_package
:1, \
232 uint8_t ddr2_height
:3 \
234 uint8_t ddr2_datawidth
;
235 uint8_t ddr2_unused3
;
236 uint8_t ddr2_voltage
;
238 uint8_t ddr2_cycle_frac
:4, \
239 uint8_t ddr2_cycle_whole
:4, , \
242 uint8_t ddr2_tAC_hundredths
:4, \
243 uint8_t ddr2_tAC_tenths
:4, , \
247 uint8_t ddr2_refresh
:7, \
248 uint8_t ddr2_selfrefresh
:1, , \
250 uint8_t ddr2_dramwidth
;
251 uint8_t ddr2_eccwidth
;
252 uint8_t ddr2_unused4
;
254 uint8_t ddr2_burstlengths
:4, \
255 uint8_t ddr2_unused5
:4, , \
257 uint8_t ddr2_banks_per_chip
;
259 uint8_t ddr2_mechanical
;
260 uint8_t ddr2_dimm_type
;
261 uint8_t ddr2_mod_attrs
;
262 uint8_t ddr2_dev_attrs
;
263 uint8_t ddr2_min_cc_1
;
264 uint8_t ddr2_max_tAC_1
;
265 uint8_t ddr2_min_cc_2
;
266 uint8_t ddr2_max_tAC_2
;
271 uint8_t ddr2_module_rank_density
;
280 uint8_t ddr2_extensions
;
286 uint8_t ddr2_pll_relock
;
287 uint8_t ddr2_Tcasemax
;
288 uint8_t ddr2_Psi_TA_DRAM
;
293 uint8_t ddr2_dt3Pfast
;
294 uint8_t ddr2_dt3Pslow
;
295 uint8_t ddr2_dt4R_4R4W_mode
;
298 uint8_t ddr2_Psi_TA_PLL
;
299 uint8_t ddr2_Psi_TA_Reg
;
300 uint8_t ddr2_dt_PLL_Active
;
301 uint8_t ddr2_dt_Reg_Active
;
306 struct spdmem_fbdimm
{ /* Fully-buffered DIMM */
308 uint8_t fbdimm_ps1_voltage
:4, \
309 uint8_t fbdimm_ps2_voltage
:4, , \
312 uint8_t fbdimm_banks
:2, \
313 uint8_t fbdimm_cols
:3, \
314 uint8_t fbdimm_rows
:3, \
317 uint8_t fbdimm_thick
:3, \
318 uint8_t fbdimm_height
:3, \
319 uint8_t fbdimm_unused1
:2, \
321 uint8_t fbdimm_mod_type
;
323 uint8_t fbdimm_dev_width
:3, \
324 uint8_t fbdimm_ranks
:3, \
325 uint8_t fbdimm_unused2
:2, \
328 uint8_t fbdimm_ftb_divisor
:4, \
329 uint8_t fbdimm_ftp_dividend
:4, ,\
331 uint8_t fbdimm_mtb_dividend
;
332 uint8_t fbdimm_mtb_divisor
;
333 uint8_t fbdimm_tCKmin
;
334 uint8_t fbdimm_tCKmax
;
336 uint8_t fbdimm_tAAmin
;
338 uint8_t fbdimm_tWR_min
:4, \
339 uint8_t fbdimm_WR_range
:4, , \
343 uint8_t fbdimm_tWL_min
:4, \
344 uint8_t fbdimm_tWL_range
:4, , \
347 uint8_t fbdimm_tAL_min
:4, \
348 uint8_t fbdimm_tAL_range
:4, , \
350 uint8_t fbdimm_tRCDmin
;
351 uint8_t fbdimm_tRRDmin
;
352 uint8_t fbdimm_tRPmin
;
354 uint8_t fbdimm_tRAS_msb
:4, \
355 uint8_t fbdimm_tRC_msb
:4, , \
357 uint8_t fbdimm_tRAS_lsb
;
358 uint8_t fbdimm_tRC_lsb
;
359 uint16_t fbdimm_tRFC
; /* endian-sensitive */
363 uint8_t fbdimm_burst_4
:1, \
364 uint8_t fbdimm_burst_8
:1, \
365 uint8_t fbdimm_unused3
:6, \
367 uint8_t fbdimm_terms
;
368 uint8_t fbdimm_drivers
;
369 uint8_t fbdimm_tREFI
;
370 uint8_t fbdimm_Tcasemax
;
371 uint8_t fbdimm_Psi_TA_SDRAM
;
373 uint8_t fbdimm_DT2N_DT2Q
;
376 uint8_t fbdimm_DT4R_DT4R4W
;
379 uint8_t fbdimm_unused4
[84];
383 struct spdmem_rambus
{ /* Direct Rambus DRAM */
385 uint8_t rdr_rows
:4, \
386 uint8_t rdr_cols
:4, , \
390 struct spdmem_ddr3
{ /* Dual Data Rate 3 SDRAM */
391 uint8_t ddr3_mod_type
;
393 /* chipsize is offset by 28: 0 = 256M, 1 = 512M, ... */ \
394 uint8_t ddr3_chipsize
:4, \
395 /* logbanks is offset by 3 */ \
396 uint8_t ddr3_logbanks
:3, \
397 uint8_t ddr3_unused1
:1, \
399 /* cols is offset by 9, rows offset by 12 */
401 uint8_t ddr3_cols
:3, \
402 uint8_t ddr3_rows
:5, , \
405 uint8_t ddr3_NOT15V
:1, \
406 uint8_t ddr3_135V
:1, \
407 uint8_t ddr3_12XV
:1, \
408 uint8_t ddr3_unused2
:5 \
410 /* chipwidth in bits offset by 2: 0 = X4, 1 = X8, 2 = X16 */
411 /* physbanks is offset by 1 */
413 uint8_t ddr3_chipwidth
:3, \
414 uint8_t ddr3_physbanks
:5, , \
416 /* datawidth in bits offset by 3: 1 = 16b, 2 = 32b, 3 = 64b */
418 uint8_t ddr3_datawidth
:3, \
419 uint8_t ddr3_hasECC
:2, \
420 uint8_t ddr3_unused2a
:3 , \
422 /* Fine time base, in pico-seconds */
424 uint8_t ddr3_ftb_divisor
:4, \
425 uint8_t ddr3_ftb_dividend
:4, , \
427 uint8_t ddr3_mtb_dividend
; /* 0x0108 = 0.1250ns */
428 uint8_t ddr3_mtb_divisor
; /* 0x010f = 0.0625ns */
429 uint8_t ddr3_tCKmin
; /* in terms of mtb */
430 uint8_t ddr3_unused3
;
431 uint16_t ddr3_CAS_sup
; /* Bit 0 ==> CAS 4 cycles */
432 uint8_t ddr3_tAAmin
; /* in terms of mtb */
434 uint8_t ddr3_tRCDmin
;
435 uint8_t ddr3_tRRDmin
;
438 uint8_t ddr3_tRAS_msb
:4, \
439 uint8_t ddr3_tRC_msb
:4, , \
441 uint8_t ddr3_tRAS_lsb
;
442 uint8_t ddr3_tRC_lsb
;
443 uint8_t ddr3_tRFCmin_lsb
;
444 uint8_t ddr3_tRFCmin_msb
;
445 uint8_t ddr3_tWTRmin
;
446 uint8_t ddr3_tRTPmin
;
448 uint8_t ddr3_tFAW_msb
:4, , , \
450 uint8_t ddr3_tFAW_lsb
;
451 uint8_t ddr3_output_drvrs
;
453 uint8_t ddr3_ext_temp_range
:1, \
454 uint8_t ddr3_ext_temp_2x_refresh
:1, \
455 uint8_t ddr3_asr_refresh
:1, \
456 /* Bit 4 indicates on-die thermal sensor */
457 /* Bit 7 indicates Partial-Array Self-Refresh (PASR) */
458 uint8_t ddr3_unused7
:5 \
461 uint8_t ddr3_therm_sensor_acc
:7,\
462 uint8_t ddr3_has_therm_sensor
:1, , \
465 uint8_t ddr3_non_std_devtype
:7, \
466 uint8_t ddr3_std_device
:1, , \
468 uint8_t ddr3_unused4
[26];
469 uint8_t ddr3_mod_height
;
470 uint8_t ddr3_mod_thickness
;
471 uint8_t ddr3_ref_card
;
472 uint8_t ddr3_mapping
;
473 uint8_t ddr3_unused5
[53];
474 uint8_t ddr3_mfgID_lsb
;
475 uint8_t ddr3_mfgID_msb
;
477 uint8_t ddr3_mfg_year
;
478 uint8_t ddr3_mfg_week
;
479 uint8_t ddr3_serial
[4];
488 struct spdmem_fbdimm u1_fbd
;
489 struct spdmem_fpm u1_fpm
;
490 struct spdmem_ddr u1_ddr
;
491 struct spdmem_ddr2 u1_ddr2
;
492 struct spdmem_sdram u1_sdr
;
493 struct spdmem_rambus u1_rdr
;
494 struct spdmem_rom u1_rom
;
495 struct spdmem_ddr3 u1_ddr3
;
497 uint8_t sm_extension
[128];
499 #define sm_fbd sm_u1.u1_fbd
500 #define sm_fpm sm_u1.u1_fpm
501 #define sm_ddr sm_u1.u1_ddr
502 #define sm_ddr2 sm_u1.u1_ddr2
503 #define sm_rdr sm_u1.u1_rdr
504 #define sm_rom sm_u1.u1_rom
505 #define sm_ddr3 sm_u1.u1_ddr3
506 #define sm_sdr sm_u1.u1_sdr
508 /* some fields are in the same place for all memory types */
510 #define sm_cksum sm_fpm.fpm_cksum
511 #define sm_config sm_fpm.fpm_config
512 #define sm_voltage sm_fpm.fpm_voltage
513 #define sm_refresh sm_fpm.fpm_refresh
514 #define sm_selfrefresh sm_fpm.fpm_selfrefresh
516 #define SPDMEM_TYPE_MAXLEN 16
517 struct spdmem_softc
{
520 struct spdmem sc_spd_data
;
521 char sc_type
[SPDMEM_TYPE_MAXLEN
];