Exemple #1
0
void save_mrc_data(struct pei_data *pei_data)
{
	u16 c1, c2, checksum;

	/* Save the MRC S3 restore data to cbmem */
	store_current_mrc_cache(pei_data->mrc_output, pei_data->mrc_output_len);

	/* Save the MRC seed values to CMOS */
	cmos_write32(CMOS_OFFSET_MRC_SEED, pei_data->scrambler_seed);
	printk(BIOS_DEBUG, "Save scrambler seed    0x%08x to CMOS 0x%02x\n",
	       pei_data->scrambler_seed, CMOS_OFFSET_MRC_SEED);

	cmos_write32(CMOS_OFFSET_MRC_SEED_S3, pei_data->scrambler_seed_s3);
	printk(BIOS_DEBUG, "Save s3 scrambler seed 0x%08x to CMOS 0x%02x\n",
	       pei_data->scrambler_seed_s3, CMOS_OFFSET_MRC_SEED_S3);

	/* Save a simple checksum of the seed values */
	c1 = compute_ip_checksum((u8*)&pei_data->scrambler_seed,
				 sizeof(u32));
	c2 = compute_ip_checksum((u8*)&pei_data->scrambler_seed_s3,
				 sizeof(u32));
	checksum = add_ip_checksums(sizeof(u32), c1, c2);

	cmos_write(checksum & 0xff, CMOS_OFFSET_MRC_SEED_CHK);
	cmos_write((checksum >> 8) & 0xff, CMOS_OFFSET_MRC_SEED_CHK+1);
}
Exemple #2
0
static int write_seeds_to_cmos(struct pei_data *pei_data)
{
	u16 c1, c2, checksum;
	struct udevice *dev;
	int ret = 0;

	ret = uclass_get_device(UCLASS_RTC, 0, &dev);
	if (ret) {
		debug("Cannot find RTC: err=%d\n", ret);
		return -ENODEV;
	}

	/* Save the MRC seed values to CMOS */
	rtc_write32(dev, CMOS_OFFSET_MRC_SEED, pei_data->scrambler_seed);
	debug("Save scrambler seed    0x%08x to CMOS 0x%02x\n",
	      pei_data->scrambler_seed, CMOS_OFFSET_MRC_SEED);

	rtc_write32(dev, CMOS_OFFSET_MRC_SEED_S3, pei_data->scrambler_seed_s3);
	debug("Save s3 scrambler seed 0x%08x to CMOS 0x%02x\n",
	      pei_data->scrambler_seed_s3, CMOS_OFFSET_MRC_SEED_S3);

	/* Save a simple checksum of the seed values */
	c1 = compute_ip_checksum((u8 *)&pei_data->scrambler_seed,
				 sizeof(u32));
	c2 = compute_ip_checksum((u8 *)&pei_data->scrambler_seed_s3,
				 sizeof(u32));
	checksum = add_ip_checksums(sizeof(u32), c1, c2);

	rtc_write8(dev, CMOS_OFFSET_MRC_SEED_CHK, checksum & 0xff);
	rtc_write8(dev, CMOS_OFFSET_MRC_SEED_CHK + 1, (checksum >> 8) & 0xff);

	return 0;
}
Exemple #3
0
static int read_seed_from_cmos(struct pei_data *pei_data)
{
	u16 c1, c2, checksum, seed_checksum;
	struct udevice *dev;
	int ret = 0;

	ret = uclass_get_device(UCLASS_RTC, 0, &dev);
	if (ret) {
		debug("Cannot find RTC: err=%d\n", ret);
		return -ENODEV;
	}

	/*
	 * Read scrambler seeds from CMOS RAM. We don't want to store them in
	 * SPI flash since they change on every boot and that would wear down
	 * the flash too much. So we store these in CMOS and the large MRC
	 * data in SPI flash.
	 */
	ret = rtc_read32(dev, CMOS_OFFSET_MRC_SEED, &pei_data->scrambler_seed);
	if (!ret) {
		ret = rtc_read32(dev, CMOS_OFFSET_MRC_SEED_S3,
				 &pei_data->scrambler_seed_s3);
	}
	if (ret) {
		debug("Failed to read from RTC %s\n", dev->name);
		return ret;
	}

	debug("Read scrambler seed    0x%08x from CMOS 0x%02x\n",
	      pei_data->scrambler_seed, CMOS_OFFSET_MRC_SEED);
	debug("Read S3 scrambler seed 0x%08x from CMOS 0x%02x\n",
	      pei_data->scrambler_seed_s3, CMOS_OFFSET_MRC_SEED_S3);

	/* Compute seed checksum and compare */
	c1 = compute_ip_checksum((u8 *)&pei_data->scrambler_seed,
				 sizeof(u32));
	c2 = compute_ip_checksum((u8 *)&pei_data->scrambler_seed_s3,
				 sizeof(u32));
	checksum = add_ip_checksums(sizeof(u32), c1, c2);

	seed_checksum = rtc_read8(dev, CMOS_OFFSET_MRC_SEED_CHK);
	seed_checksum |= rtc_read8(dev, CMOS_OFFSET_MRC_SEED_CHK + 1) << 8;

	if (checksum != seed_checksum) {
		debug("%s: invalid seed checksum\n", __func__);
		pei_data->scrambler_seed = 0;
		pei_data->scrambler_seed_s3 = 0;
		return -EINVAL;
	}

	return 0;
}
Exemple #4
0
void save_mrc_data(struct pei_data *pei_data)
{
	u16 c1, c2, checksum;
	struct mrc_data_container *mrcdata;
	int output_len = ALIGN(pei_data->mrc_output_len, 16);

	/* Save the MRC S3 restore data to cbmem */
	mrcdata = cbmem_add
		(CBMEM_ID_MRCDATA,
		 output_len + sizeof(struct mrc_data_container));

	if (mrcdata != NULL) {
		printk(BIOS_DEBUG, "Relocate MRC DATA from %p to %p (%u bytes)\n",
			pei_data->mrc_output, mrcdata, output_len);

		mrcdata->mrc_signature = MRC_DATA_SIGNATURE;
		mrcdata->mrc_data_size = output_len;
		mrcdata->reserved = 0;
		memcpy(mrcdata->mrc_data, pei_data->mrc_output,
			pei_data->mrc_output_len);

		/* Zero the unused space in aligned buffer. */
		if (output_len > pei_data->mrc_output_len)
			memset(mrcdata->mrc_data+pei_data->mrc_output_len, 0,
			output_len - pei_data->mrc_output_len);

		mrcdata->mrc_checksum = compute_ip_checksum(mrcdata->mrc_data,
						mrcdata->mrc_data_size);
	}

	/* Save the MRC seed values to CMOS */
	cmos_write32(CMOS_OFFSET_MRC_SEED, pei_data->scrambler_seed);
	printk(BIOS_DEBUG, "Save scrambler seed    0x%08x to CMOS 0x%02x\n",
	       pei_data->scrambler_seed, CMOS_OFFSET_MRC_SEED);

	cmos_write32(CMOS_OFFSET_MRC_SEED_S3, pei_data->scrambler_seed_s3);
	printk(BIOS_DEBUG, "Save s3 scrambler seed 0x%08x to CMOS 0x%02x\n",
	       pei_data->scrambler_seed_s3, CMOS_OFFSET_MRC_SEED_S3);

	/* Save a simple checksum of the seed values */
	c1 = compute_ip_checksum((u8*)&pei_data->scrambler_seed,
				 sizeof(u32));
	c2 = compute_ip_checksum((u8*)&pei_data->scrambler_seed_s3,
				 sizeof(u32));
	checksum = add_ip_checksums(sizeof(u32), c1, c2);

	cmos_write(checksum & 0xff, CMOS_OFFSET_MRC_SEED_CHK);
	cmos_write((checksum >> 8) & 0xff, CMOS_OFFSET_MRC_SEED_CHK+1);
}
Exemple #5
0
static void prepare_mrc_cache(struct pei_data *pei_data)
{
	struct mrc_data_container *mrc_cache;
	u16 c1, c2, checksum, seed_checksum;

	// preset just in case there is an error
	pei_data->mrc_input = NULL;
	pei_data->mrc_input_len = 0;

	/* Read scrambler seeds from CMOS */
	pei_data->scrambler_seed = cmos_read32(CMOS_OFFSET_MRC_SEED);
	printk(BIOS_DEBUG, "Read scrambler seed    0x%08x from CMOS 0x%02x\n",
	       pei_data->scrambler_seed, CMOS_OFFSET_MRC_SEED);

	pei_data->scrambler_seed_s3 = cmos_read32(CMOS_OFFSET_MRC_SEED_S3);
	printk(BIOS_DEBUG, "Read S3 scrambler seed 0x%08x from CMOS 0x%02x\n",
	       pei_data->scrambler_seed_s3, CMOS_OFFSET_MRC_SEED_S3);

	/* Compute seed checksum and compare */
	c1 = compute_ip_checksum((u8*)&pei_data->scrambler_seed,
				 sizeof(u32));
	c2 = compute_ip_checksum((u8*)&pei_data->scrambler_seed_s3,
				 sizeof(u32));
	checksum = add_ip_checksums(sizeof(u32), c1, c2);

	seed_checksum = cmos_read(CMOS_OFFSET_MRC_SEED_CHK);
	seed_checksum |= cmos_read(CMOS_OFFSET_MRC_SEED_CHK+1) << 8;

	if (checksum != seed_checksum) {
		printk(BIOS_ERR, "%s: invalid seed checksum\n", __func__);
		pei_data->scrambler_seed = 0;
		pei_data->scrambler_seed_s3 = 0;
		return;
	}

	if ((mrc_cache = find_current_mrc_cache()) == NULL) {
		/* error message printed in find_current_mrc_cache */
		return;
	}

	pei_data->mrc_input = mrc_cache->mrc_data;
	pei_data->mrc_input_len = mrc_cache->mrc_data_size;

	printk(BIOS_DEBUG, "%s: at %p, size %x checksum %04x\n",
	       __func__, pei_data->mrc_input,
	       pei_data->mrc_input_len, mrc_cache->mrc_checksum);
}