/** * 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; }
/* 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; }
/* * 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; }