2 * This file is part of the coreboot project.
4 * Copyright (C) 2012 Google Inc.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
18 #include <bootstate.h>
19 #include <console/console.h>
22 #include <ip_checksum.h>
23 #include <device/device.h>
27 #include <spi-generic.h>
28 #include <spi_flash.h>
30 /* convert a pointer to flash area into the offset inside the flash */
31 static inline u32
to_flash_offset(struct spi_flash
*flash
, void *p
) {
32 return ((u32
)p
+ flash
->size
);
35 static struct mrc_data_container
*next_mrc_block(
36 struct mrc_data_container
*mrc_cache
)
38 /* MRC data blocks are aligned within the region */
39 u32 mrc_size
= sizeof(*mrc_cache
) + mrc_cache
->mrc_data_size
;
40 if (mrc_size
& (MRC_DATA_ALIGN
- 1UL)) {
41 mrc_size
&= ~(MRC_DATA_ALIGN
- 1UL);
42 mrc_size
+= MRC_DATA_ALIGN
;
45 u8
*region_ptr
= (u8
*)mrc_cache
;
46 region_ptr
+= mrc_size
;
47 return (struct mrc_data_container
*)region_ptr
;
50 static int is_mrc_cache(struct mrc_data_container
*mrc_cache
)
52 return (!!mrc_cache
) && (mrc_cache
->mrc_signature
== MRC_DATA_SIGNATURE
);
55 /* Right now, the offsets for the MRC cache area are hard-coded in the
56 * northbridge Kconfig if CONFIG_CHROMEOS is not set. In order to make
57 * this more flexible, there are two of options:
58 * - Have each mainboard Kconfig supply a hard-coded offset
61 static u32
get_mrc_cache_region(struct mrc_data_container
**mrc_region_ptr
)
63 size_t region_size
= 0;
64 *mrc_region_ptr
= NULL
;
66 if (IS_ENABLED(CONFIG_CHROMEOS
)) {
67 struct region_device rdev
;
69 if (fmap_locate_area_as_rdev("RW_MRC_CACHE", &rdev
) == 0) {
70 region_size
= region_device_sz(&rdev
);
71 *mrc_region_ptr
= rdev_mmap_full(&rdev
);
74 *mrc_region_ptr
= cbfs_boot_map_with_leak("mrc.cache",
82 * Find the largest index block in the MRC cache. Return NULL if non is
85 static struct mrc_data_container
*find_current_mrc_cache_local
86 (struct mrc_data_container
*mrc_cache
, u32 region_size
)
90 struct mrc_data_container
*mrc_next
= mrc_cache
;
92 region_end
= (u32
) mrc_cache
+ region_size
;
94 /* Search for the last filled entry in the region */
95 while (is_mrc_cache(mrc_next
)) {
98 mrc_next
= next_mrc_block(mrc_next
);
99 if ((u32
)mrc_next
>= region_end
) {
100 /* Stay in the MRC data region */
106 printk(BIOS_ERR
, "%s: No valid MRC cache found.\n", __func__
);
110 /* Verify checksum */
111 if (mrc_cache
->mrc_checksum
!=
112 compute_ip_checksum(mrc_cache
->mrc_data
,
113 mrc_cache
->mrc_data_size
)) {
114 printk(BIOS_ERR
, "%s: MRC cache checksum mismatch\n", __func__
);
118 printk(BIOS_DEBUG
, "%s: picked entry %u from cache block\n", __func__
,
124 /* SPI code needs malloc/free.
125 * Also unknown if writing flash from XIP-flash code is a good idea
128 /* find the first empty block in the MRC cache area.
129 * If there's none, return NULL.
131 * @mrc_cache_base - base address of the MRC cache area
132 * @mrc_cache - current entry (for which we need to find next)
133 * @region_size - total size of the MRC cache area
135 static struct mrc_data_container
*find_next_mrc_cache
136 (struct mrc_data_container
*mrc_cache_base
,
137 struct mrc_data_container
*mrc_cache
,
140 u32 region_end
= (u32
) mrc_cache_base
+ region_size
;
142 mrc_cache
= next_mrc_block(mrc_cache
);
143 if ((u32
)mrc_cache
>= region_end
) {
144 /* Crossed the boundary */
146 printk(BIOS_DEBUG
, "%s: no available entries found\n",
150 "%s: picked next entry from cache block at %p\n",
151 __func__
, mrc_cache
);
157 static void update_mrc_cache(void *unused
)
159 printk(BIOS_DEBUG
, "Updating MRC cache data.\n");
160 struct mrc_data_container
*current
= cbmem_find(CBMEM_ID_MRCDATA
);
161 struct mrc_data_container
*cache
, *cache_base
;
165 printk(BIOS_ERR
, "No MRC cache in cbmem. Can't update flash.\n");
168 if (current
->mrc_data_size
== -1) {
169 printk(BIOS_ERR
, "MRC cache data in cbmem invalid.\n");
173 cache_size
= get_mrc_cache_region(&cache_base
);
174 if (cache_base
== NULL
) {
175 printk(BIOS_ERR
, "%s: could not find MRC cache area\n",
183 // 0. compare MRC data to last mrc-cache block (exit if same)
184 cache
= find_current_mrc_cache_local(cache_base
, cache_size
);
186 if (cache
&& (cache
->mrc_data_size
== current
->mrc_data_size
) &&
187 (memcmp(cache
, current
, cache
->mrc_data_size
) == 0)) {
189 "MRC data in flash is up to date. No update.\n");
193 // 1. use spi_flash_probe() to find the flash, then
195 struct spi_flash
*flash
= spi_flash_probe(0, 0);
197 printk(BIOS_DEBUG
, "Could not find SPI device\n");
201 // 2. look up the first unused block
203 cache
= find_next_mrc_cache(cache_base
, cache
, cache_size
);
206 * 3. if no such place exists, erase entire mrc-cache range & use
207 * block 0. First time around the erase is not needed, but this is a
208 * small overhead for simpler code.
212 "Need to erase the MRC cache region of %d bytes at %p\n",
213 cache_size
, cache_base
);
215 flash
->erase(flash
, to_flash_offset(flash
, cache_base
), cache_size
);
217 /* we will start at the beginning again */
220 // 4. write mrc data with flash->write()
221 printk(BIOS_DEBUG
, "Finally: write MRC cache update to flash at %p\n",
223 flash
->write(flash
, to_flash_offset(flash
, cache
),
224 current
->mrc_data_size
+ sizeof(*current
), current
);
227 BOOT_STATE_INIT_ENTRY(BS_WRITE_TABLES
, BS_ON_ENTRY
, update_mrc_cache
, NULL
);
229 struct mrc_data_container
*find_current_mrc_cache(void)
231 struct mrc_data_container
*cache_base
;
234 cache_size
= get_mrc_cache_region(&cache_base
);
235 if (cache_base
== NULL
) {
236 printk(BIOS_ERR
, "%s: could not find MRC cache area\n",
244 // 0. compare MRC data to last mrc-cache block (exit if same)
245 return find_current_mrc_cache_local(cache_base
, cache_size
);