/**
 * find_next_mrc_cache() - get next cache entry
 *
 * @entry:	MRC cache flash area
 * @cache:	Entry to start from
 *
 * @return next cache entry if found, NULL if we got to the end
 */
static struct mrc_data_container *find_next_mrc_cache(struct mrc_region *entry,
		struct mrc_data_container *cache)
{
	ulong base_addr, end_addr;

	base_addr = entry->base + entry->offset;
	end_addr = base_addr + entry->length;

	cache = next_mrc_block(cache);
	if ((ulong)cache >= end_addr) {
		/* Crossed the boundary */
		cache = NULL;
		debug("%s: no available entries found\n", __func__);
	} else {
		debug("%s: picked next entry from cache block at %p\n",
		      __func__, cache);
	}

	return cache;
}
Beispiel #2
0
/* find the first empty block in the MRC cache area.
 * If there's none, return NULL.
 *
 * @mrc_cache_base - base address of the MRC cache area
 * @mrc_cache - current entry (for which we need to find next)
 * @region_size - total size of the MRC cache area
 */
static struct mrc_data_container *find_next_mrc_cache
(struct mrc_data_container *mrc_cache_base,
 struct mrc_data_container *mrc_cache,
 u32 region_size)
{
    u32 region_end = (u32) mrc_cache_base + region_size;

    mrc_cache = next_mrc_block(mrc_cache);
    if ((u32)mrc_cache >= region_end) {
        /* Crossed the boundary */
        mrc_cache = NULL;
        printk(BIOS_DEBUG, "%s: no available entries found\n",
               __func__);
    } else {
        printk(BIOS_DEBUG,
               "%s: picked next entry from cache block at %p\n",
               __func__, mrc_cache);
    }

    return mrc_cache;
}
Beispiel #3
0
/*
 * Find the largest index block in the MRC cache. Return NULL if none is
 * found.
 */
static struct mrc_data_container *find_current_mrc_cache_local
	(struct mrc_data_container *mrc_cache, u32 region_size)
{
	u32 region_end;
	u32 entry_id = 0;
	struct mrc_data_container *mrc_next = mrc_cache;

	region_end = (u32) mrc_cache + region_size;

	/* Search for the last filled entry in the region */
	while (is_mrc_cache(mrc_next)) {
		entry_id++;
		mrc_cache = mrc_next;
		mrc_next = next_mrc_block(mrc_next);
		if ((u32)mrc_next >= region_end) {
			/* Stay in the MRC data region */
			break;
		}
	}

	if (entry_id == 0) {
		printk(BIOS_ERR, "%s: No valid fast boot cache found.\n",
			__func__);
		return NULL;
	}

	/* Verify checksum */
	if (mrc_cache->mrc_checksum !=
	    compute_ip_checksum(mrc_cache->mrc_data,
				mrc_cache->mrc_data_size)) {
		printk(BIOS_ERR, "%s: fast boot cache checksum mismatch\n",
			__func__);
		return NULL;
	}

	printk(BIOS_DEBUG, "%s: picked entry %u from cache block\n", __func__,
	       entry_id - 1);

	return mrc_cache;
}
struct mrc_data_container *mrccache_find_current(struct mrc_region *entry)
{
	struct mrc_data_container *cache, *next;
	ulong base_addr, end_addr;
	uint id;

	base_addr = entry->base + entry->offset;
	end_addr = base_addr + entry->length;
	cache = NULL;

	/* Search for the last filled entry in the region */
	for (id = 0, next = (struct mrc_data_container *)base_addr;
	     is_mrc_cache(next);
	     id++) {
		cache = next;
		next = next_mrc_block(next);
		if ((ulong)next >= end_addr)
			break;
	}

	if (id-- == 0) {
		debug("%s: No valid MRC cache found.\n", __func__);
		return NULL;
	}

	/* Verify checksum */
	if (cache->checksum != compute_ip_checksum(cache->data,
						   cache->data_size)) {
		printf("%s: MRC cache checksum mismatch\n", __func__);
		return NULL;
	}

	debug("%s: picked entry %u from cache block\n", __func__, id);

	return cache;
}