1 /* SPDX-License-Identifier: GPL-2.0-only */
4 #include <console/console.h>
13 * +==========+ offset 0x00
14 * |DIMM 1 SPD| SPD data length is CONFIG_DIMM_SPD_SIZE.
15 * +----------+ offset CONFIG_DIMM_SPD_SIZE * 1
17 * +----------+ offset CONFIG_DIMM_SPD_SIZE * 2
19 * +----------+ offset CONFIG_DIMM_SPD_SIZE * (N -1)
20 * |DIMM N SPD| N = CONFIG_DIMM_MAX
21 * +----------+ offset CONFIG_DIMM_SPD_SIZE * CONFIG_DIMM_MAX
22 * | CRC 16 | Use to verify the data correctness.
25 * The size of the RW_SPD_CACHE needs to be aligned with 4KiB.
29 * Use to update SPD cache.
30 * *blk : the new SPD data will be stash into the cache.
32 * return CB_SUCCESS , update SPD cache successfully.
33 * return CB_ERR , update SPD cache unsuccessfully and the cache is invalid
35 enum cb_err
update_spd_cache(struct spd_block
*blk
)
37 struct region_device rdev
;
38 uint16_t data_crc
= 0;
41 assert(blk
->len
<= SC_SPD_LEN
);
43 if (fmap_locate_area_as_rdev_rw(SPD_CACHE_FMAP_NAME
, &rdev
)) {
44 printk(BIOS_ERR
, "SPD_CACHE: Cannot access %s region\n", SPD_CACHE_FMAP_NAME
);
48 /* Erase whole area, it's for align with 4KiB which is the size of SPI rom sector. */
49 if (rdev_eraseat(&rdev
, 0, region_device_sz(&rdev
)) < 0) {
50 printk(BIOS_ERR
, "SPD_CACHE: Cannot erase %s region\n", SPD_CACHE_FMAP_NAME
);
55 for (i
= 0; i
< SC_SPD_NUMS
; i
++) {
56 if (blk
->spd_array
[i
] == NULL
) {
57 /* If DIMM is not present, we calculate the CRC with 0xff. */
58 for (j
= 0; j
< SC_SPD_LEN
; j
++)
59 data_crc
= crc16_byte(data_crc
, 0xff);
61 if (rdev_writeat(&rdev
, blk
->spd_array
[i
], SC_SPD_OFFSET(i
), blk
->len
)
63 printk(BIOS_ERR
, "SPD_CACHE: Cannot write SPD data at %d\n",
68 for (j
= 0; j
< blk
->len
; j
++)
69 data_crc
= crc16_byte(data_crc
, blk
->spd_array
[i
][j
]);
71 /* If the blk->len < SC_SPD_LEN, we calculate the CRC with 0xff. */
72 if (blk
->len
< SC_SPD_LEN
)
73 for (j
= 0; j
< (SC_SPD_LEN
- (blk
->len
)); j
++)
74 data_crc
= crc16_byte(data_crc
, 0xff);
79 /* It must be the last step to ensure that the data is written correctly */
80 if (rdev_writeat(&rdev
, &data_crc
, SC_CRC_OFFSET
, SC_CRC_LEN
) < 0) {
81 printk(BIOS_ERR
, "SPD_CACHE: Cannot write crc at 0x%04x\n", SC_CRC_OFFSET
);
88 * Locate the RW_SPD_CACHE area in the fmap and read SPD_CACHE data.
89 * return CB_SUCCESS ,if the SPD_CACHE data is ready and the pointer return at *spd_cache.
90 * return CB_ERR ,if it cannot locate RW_SPD_CACHE area in the fmap or data cannot be read.
92 enum cb_err
load_spd_cache(uint8_t **spd_cache
, size_t *spd_cache_sz
)
94 struct region_device rdev
;
96 if (fmap_locate_area_as_rdev(SPD_CACHE_FMAP_NAME
, &rdev
) < 0) {
97 printk(BIOS_ERR
, "SPD_CACHE: Cannot find %s region\n", SPD_CACHE_FMAP_NAME
);
101 /* Assume boot device is memory mapped. */
102 assert(CONFIG(BOOT_DEVICE_MEMORY_MAPPED
));
103 *spd_cache
= rdev_mmap_full(&rdev
);
105 if (*spd_cache
== NULL
)
108 *spd_cache_sz
= region_device_sz(&rdev
);
110 /* SPD cache found */
111 printk(BIOS_INFO
, "SPD_CACHE: cache found, size 0x%zx\n", *spd_cache_sz
);
116 /* Use to verify the cache data is valid. */
117 bool spd_cache_is_valid(uint8_t *spd_cache
, size_t spd_cache_sz
)
119 uint16_t data_crc
= 0;
122 if (spd_cache_sz
< SC_SPD_TOTAL_LEN
+ SC_CRC_LEN
)
125 /* Check the spd_cache crc */
126 for (i
= 0; i
< SC_SPD_TOTAL_LEN
; i
++)
127 data_crc
= crc16_byte(data_crc
, *(spd_cache
+ i
));
129 return *(uint16_t *)(spd_cache
+ SC_CRC_OFFSET
) == data_crc
;
133 * Check if the DIMM is preset in cache.
134 * return true , DIMM is present.
135 * return false, DIMM is not present.
137 static bool get_cached_dimm_present(uint8_t *spd_cache
, uint8_t idx
)
139 if (*(uint16_t *)(spd_cache
+ SC_SPD_OFFSET(idx
)) == 0xffff)
146 * Use to check if the SODIMM is changed.
147 * spd_cache : it's a valid SPD cache.
148 * blk : it must include the smbus addresses of SODIMM.
150 bool check_if_dimm_changed(u8
*spd_cache
, struct spd_block
*blk
)
154 bool dimm_present_in_cache
;
155 bool dimm_changed
= false;
156 /* Check if the dimm is the same with last system boot. */
157 for (i
= 0; i
< SC_SPD_NUMS
&& !dimm_changed
; i
++) {
158 if (blk
->addr_map
[i
] == 0) {
159 printk(BIOS_NOTICE
, "SPD_CACHE: DIMM%d does not exist\n", i
);
162 /* Return true if any error happened here. */
163 if (get_spd_sn(blk
->addr_map
[i
], &sn
) == CB_ERR
)
165 dimm_present_in_cache
= get_cached_dimm_present(spd_cache
, i
);
166 /* Dimm is not present now. */
167 if (sn
== 0xffffffff) {
168 if (!dimm_present_in_cache
)
169 printk(BIOS_NOTICE
, "SPD_CACHE: DIMM%d is not present\n", i
);
171 printk(BIOS_NOTICE
, "SPD_CACHE: DIMM%d lost\n", i
);
174 } else { /* Dimm is present now. */
175 if (dimm_present_in_cache
) {
176 if (memcmp(&sn
, spd_cache
+ SC_SPD_OFFSET(i
) + DDR4_SPD_SN_OFF
,
178 printk(BIOS_NOTICE
, "SPD_CACHE: DIMM%d is the same\n",
181 printk(BIOS_NOTICE
, "SPD_CACHE: DIMM%d is new one\n",
186 printk(BIOS_NOTICE
, "SPD_CACHE: DIMM%d is new one\n", i
);
194 /* Use to fill the struct spd_block with cache data.*/
195 enum cb_err
spd_fill_from_cache(uint8_t *spd_cache
, struct spd_block
*blk
)
200 /* Find the first present SPD */
201 for (i
= 0; i
< SC_SPD_NUMS
; i
++)
202 if (get_cached_dimm_present(spd_cache
, i
))
205 if (i
== SC_SPD_NUMS
) {
206 printk(BIOS_ERR
, "SPD_CACHE: No DIMM is present.\n");
210 dram_type
= *(spd_cache
+ SC_SPD_OFFSET(i
) + SPD_DRAM_TYPE
);
212 if (dram_type
== SPD_DRAM_DDR4
)
213 blk
->len
= SPD_PAGE_LEN_DDR4
;
215 blk
->len
= SPD_PAGE_LEN
;
217 for (i
= 0; i
< SC_SPD_NUMS
; i
++)
218 if (get_cached_dimm_present(spd_cache
, i
))
219 blk
->spd_array
[i
] = spd_cache
+ SC_SPD_OFFSET(i
);
221 blk
->spd_array
[i
] = NULL
;