* Use to update SPD cache. * *blk : the new SPD data will be stash into the cache. * * return CB_SUCCESS , update SPD cache successfully. * return CB_ERR , update SPD cache unsuccessfully and the cache is invalid */
| 36 | * return CB_ERR , update SPD cache unsuccessfully and the cache is invalid |
| 37 | */ |
| 38 | enum cb_err update_spd_cache(struct spd_block *blk) |
| 39 | { |
| 40 | struct region_device rdev; |
| 41 | uint16_t data_crc = 0; |
| 42 | int i, j; |
| 43 | |
| 44 | assert(blk->len <= SC_SPD_LEN); |
| 45 | |
| 46 | if (fmap_locate_area_as_rdev_rw(SPD_CACHE_FMAP_NAME, &rdev)) { |
| 47 | printk(BIOS_ERR, "SPD_CACHE: Cannot access %s region\n", SPD_CACHE_FMAP_NAME); |
| 48 | return CB_ERR; |
| 49 | } |
| 50 | |
| 51 | /* Erase whole area, it's for align with 4KiB which is the size of SPI rom sector. */ |
| 52 | if (rdev_eraseat(&rdev, 0, region_device_sz(&rdev)) < 0) { |
| 53 | printk(BIOS_ERR, "SPD_CACHE: Cannot erase %s region\n", SPD_CACHE_FMAP_NAME); |
| 54 | return CB_ERR; |
| 55 | } |
| 56 | |
| 57 | /* Write SPD data */ |
| 58 | for (i = 0; i < SC_SPD_NUMS; i++) { |
| 59 | if (blk->spd_array[i] == NULL) { |
| 60 | /* If DIMM is not present, we calculate the CRC with 0xff. */ |
| 61 | for (j = 0; j < SC_SPD_LEN; j++) |
| 62 | data_crc = crc16_byte(data_crc, 0xff); |
| 63 | } else { |
| 64 | if (rdev_writeat(&rdev, blk->spd_array[i], SC_SPD_OFFSET(i), blk->len) |
| 65 | < 0) { |
| 66 | printk(BIOS_ERR, "SPD_CACHE: Cannot write SPD data at %d\n", |
| 67 | SC_SPD_OFFSET(i)); |
| 68 | return CB_ERR; |
| 69 | } |
| 70 | |
| 71 | for (j = 0; j < blk->len; j++) |
| 72 | data_crc = crc16_byte(data_crc, blk->spd_array[i][j]); |
| 73 | |
| 74 | /* If the blk->len < SC_SPD_LEN, we calculate the CRC with 0xff. */ |
| 75 | if (blk->len < SC_SPD_LEN) |
| 76 | for (j = 0; j < (SC_SPD_LEN - (blk->len)); j++) |
| 77 | data_crc = crc16_byte(data_crc, 0xff); |
| 78 | } |
| 79 | } |
| 80 | |
| 81 | /* Write the crc16 */ |
| 82 | /* It must be the last step to ensure that the data is written correctly */ |
| 83 | if (rdev_writeat(&rdev, &data_crc, SC_CRC_OFFSET, SC_CRC_LEN) < 0) { |
| 84 | printk(BIOS_ERR, "SPD_CACHE: Cannot write crc at 0x%04x\n", SC_CRC_OFFSET); |
| 85 | return CB_ERR; |
| 86 | } |
| 87 | return CB_SUCCESS; |
| 88 | } |
| 89 | |
| 90 | /* |
| 91 | * Locate the RW_SPD_CACHE area in the fmap and read SPD_CACHE data. |
no test coverage detected