Hi Simon, On Wed, Sep 25, 2019 at 10:59 PM Simon Glass <s...@chromium.org> wrote: > > With apollolake we need to support a normal cache, which almost never > changes and a much smaller 'variable' cache which changes every time. > > Update the code to add a cache type, use an array for the caches and use a > for loop to iterate over the caches. > > Signed-off-by: Simon Glass <s...@chromium.org> > --- > > arch/x86/cpu/broadwell/sdram.c | 8 ++- > arch/x86/cpu/ivybridge/sdram.c | 8 ++- > arch/x86/cpu/quark/dram.c | 8 ++- > arch/x86/include/asm/global_data.h | 21 +++++-- > arch/x86/include/asm/mrccache.h | 11 +++- > arch/x86/lib/fsp/fsp_common.c | 2 +- > arch/x86/lib/fsp1/fsp_dram.c | 8 ++- > arch/x86/lib/mrccache.c | 93 ++++++++++++++++++++---------- > 8 files changed, 109 insertions(+), 50 deletions(-) > > diff --git a/arch/x86/cpu/broadwell/sdram.c b/arch/x86/cpu/broadwell/sdram.c > index b31d78c092a..107c04691b0 100644 > --- a/arch/x86/cpu/broadwell/sdram.c > +++ b/arch/x86/cpu/broadwell/sdram.c > @@ -82,7 +82,7 @@ static int prepare_mrc_cache(struct pei_data *pei_data) > struct mrc_region entry; > int ret; > > - ret = mrccache_get_region(NULL, &entry); > + ret = mrccache_get_region(MRC_TYPE_NORMAL, NULL, &entry); > if (ret) > return ret; > mrc_cache = mrccache_find_current(&entry); > @@ -168,12 +168,14 @@ int dram_init(void) > pei_data->data_to_save); > /* S3 resume: don't save scrambler seed or MRC data */ > if (pei_data->boot_mode != SLEEP_STATE_S3) { > + struct mrc_output *mrc = &gd->arch.mrc[MRC_TYPE_NORMAL]; > + > /* > * This will be copied to SDRAM in reserve_arch(), then > written > * to SPI flash in mrccache_save() > */ > - gd->arch.mrc_output = (char *)pei_data->data_to_save; > - gd->arch.mrc_output_len = pei_data->data_to_save_size; > + mrc->buf = (char *)pei_data->data_to_save; > + mrc->len = pei_data->data_to_save_size; > } > gd->arch.pei_meminfo = pei_data->meminfo; > > diff --git a/arch/x86/cpu/ivybridge/sdram.c b/arch/x86/cpu/ivybridge/sdram.c > index 8a58d0383d5..8b03406666e 100644 > --- a/arch/x86/cpu/ivybridge/sdram.c > +++ b/arch/x86/cpu/ivybridge/sdram.c > @@ -115,7 +115,7 @@ static int prepare_mrc_cache(struct pei_data *pei_data) > ret = read_seed_from_cmos(pei_data); > if (ret) > return ret; > - ret = mrccache_get_region(NULL, &entry); > + ret = mrccache_get_region(MRC_TYPE_NORMAL, NULL, &entry); > if (ret) > return ret; > mrc_cache = mrccache_find_current(&entry); > @@ -537,12 +537,14 @@ int dram_init(void) > > /* S3 resume: don't save scrambler seed or MRC data */ > if (pei_data->boot_mode != PEI_BOOT_RESUME) { > + struct mrc_output *mrc = &gd->arch.mrc[MRC_TYPE_NORMAL]; > + > /* > * This will be copied to SDRAM in reserve_arch(), then > written > * to SPI flash in mrccache_save() > */ > - gd->arch.mrc_output = (char *)pei_data->mrc_output; > - gd->arch.mrc_output_len = pei_data->mrc_output_len; > + mrc->buf = (char *)pei_data->mrc_output; > + mrc->len = pei_data->mrc_output_len; > ret = write_seeds_to_cmos(pei_data); > if (ret) > debug("Failed to write seeds to CMOS: %d\n", ret); > diff --git a/arch/x86/cpu/quark/dram.c b/arch/x86/cpu/quark/dram.c > index 51f9659ab15..3994355112b 100644 > --- a/arch/x86/cpu/quark/dram.c > +++ b/arch/x86/cpu/quark/dram.c > @@ -22,7 +22,7 @@ static __maybe_unused int prepare_mrc_cache(struct > mrc_params *mrc_params) > struct mrc_region entry; > int ret; > > - ret = mrccache_get_region(NULL, &entry); > + ret = mrccache_get_region(MRC_TYPE_NORMAL, NULL, &entry); > if (ret) > return ret; > > @@ -152,9 +152,11 @@ int dram_init(void) > #ifdef CONFIG_ENABLE_MRC_CACHE > cache = malloc(sizeof(struct mrc_timings)); > if (cache) { > + struct mrc_output *mrc = &gd->arch.mrc[MRC_TYPE_NORMAL]; > + > memcpy(cache, &mrc_params.timings, sizeof(struct > mrc_timings)); > - gd->arch.mrc_output = cache; > - gd->arch.mrc_output_len = sizeof(struct mrc_timings); > + mrc->buf = cache; > + mrc->len = sizeof(struct mrc_timings); > } > #endif > > diff --git a/arch/x86/include/asm/global_data.h > b/arch/x86/include/asm/global_data.h > index c5faac5c901..2475b3427e1 100644 > --- a/arch/x86/include/asm/global_data.h > +++ b/arch/x86/include/asm/global_data.h > @@ -67,6 +67,21 @@ struct mtrr_request { > uint64_t size; > }; > > +/** > + * struct mrc_output - holds the MRC data > + * > + * @buf: MRC training data to save for the next boot. This is set to point to > + * the raw data after SDRAM init is complete. Then mrccache_setup() > + * turns it into a proper cache record with a checksum > + * @len: Length of @buf > + * @cache: Resulting cache record > + */ > +struct mrc_output { > + char *buf; > + uint len; > + struct mrc_data_container *cache; > +}; > + > /* Architecture-specific global data */ > struct arch_global_data { > u64 gdt[X86_GDT_NUM_ENTRIES] __aligned(16); > @@ -90,10 +105,8 @@ struct arch_global_data { > struct mtrr_request mtrr_req[MAX_MTRR_REQUESTS]; > int mtrr_req_count; > int has_mtrr; > - /* MRC training data to save for the next boot */ > - char *mrc_output; > - unsigned int mrc_output_len; > - struct mrc_data_container *mrc_cache; > + /* MRC training data */ > + struct mrc_output mrc[MRC_TYPE_COUNT]; > ulong table; /* Table pointer from previous loader > */ > int turbo_state; /* Current turbo state */ > struct irq_routing_table *pirq_routing_table; > diff --git a/arch/x86/include/asm/mrccache.h b/arch/x86/include/asm/mrccache.h > index abf58182237..b81e2b2fb6a 100644 > --- a/arch/x86/include/asm/mrccache.h > +++ b/arch/x86/include/asm/mrccache.h > @@ -27,6 +27,13 @@ struct mrc_region { > u32 length; > }; > > +/* Types of MRC data */ > +enum mrc_type_t { > + MRC_TYPE_NORMAL, > + > + MRC_TYPE_COUNT, > +}; > + > struct udevice; > > /** > @@ -84,6 +91,7 @@ int mrccache_reserve(void); > * triggers PCI bus enumeration during which insufficient memory issue > * might be exposed and it causes subsequent SPI flash probe fails). > * > + * @type: Type of MRC data to use > * @devp: Returns pointer to the SPI flash device > * @entry: Position and size of MRC cache in SPI flash > * @return 0 if success, -ENOENT if SPI flash node does not exist in the > @@ -91,7 +99,8 @@ int mrccache_reserve(void); > * tree, -EINVAL if MRC region properties format is incorrect, other error > * if SPI flash probe failed. > */ > -int mrccache_get_region(struct udevice **devp, struct mrc_region *entry); > +int mrccache_get_region(enum mrc_type_t type, struct udevice **devp, > + struct mrc_region *entry); > > /** > * mrccache_save() - save MRC data to the SPI flash > diff --git a/arch/x86/lib/fsp/fsp_common.c b/arch/x86/lib/fsp/fsp_common.c > index 40ba866d77c..c1c30ce0eb6 100644 > --- a/arch/x86/lib/fsp/fsp_common.c > +++ b/arch/x86/lib/fsp/fsp_common.c > @@ -63,7 +63,7 @@ void *fsp_prepare_mrc_cache(void) > struct mrc_region entry; > int ret; > > - ret = mrccache_get_region(NULL, &entry); > + ret = mrccache_get_region(MRC_TYPE_NORMAL, NULL, &entry); > if (ret) > return NULL; > > diff --git a/arch/x86/lib/fsp1/fsp_dram.c b/arch/x86/lib/fsp1/fsp_dram.c > index 6a3349b42af..5ef89744b94 100644 > --- a/arch/x86/lib/fsp1/fsp_dram.c > +++ b/arch/x86/lib/fsp1/fsp_dram.c > @@ -15,9 +15,11 @@ int dram_init(void) > if (ret) > return ret; > > - if (IS_ENABLED(CONFIG_ENABLE_MRC_CACHE)) > - gd->arch.mrc_output = fsp_get_nvs_data(gd->arch.hob_list, > - &gd->arch.mrc_output_len); > + if (IS_ENABLED(CONFIG_ENABLE_MRC_CACHE)) { > + struct mrc_output *mrc = &gd->arch.mrc[MRC_TYPE_NORMAL]; > + > + mrc->buf = fsp_get_nvs_data(gd->arch.hob_list, &mrc->len); > + } > > return 0; > } > diff --git a/arch/x86/lib/mrccache.c b/arch/x86/lib/mrccache.c > index 0208696c834..8de7dc48f44 100644 > --- a/arch/x86/lib/mrccache.c > +++ b/arch/x86/lib/mrccache.c > @@ -159,44 +159,51 @@ int mrccache_update(struct udevice *sf, struct > mrc_region *entry, > cur); > if (ret) { > debug("Failed to write to SPI flash\n"); > - return ret; > + return log_msg_ret("Cannot update mrccache", ret);
This line change should be in patch [84/126] "x86: Tidy up error handling in mrccache_save()" > } > > return 0; > } > > -static void mrccache_setup(void *data) > +static void mrccache_setup(struct mrc_output *mrc, void *data) > { > struct mrc_data_container *cache = data; > u16 checksum; > > cache->signature = MRC_DATA_SIGNATURE; > - cache->data_size = gd->arch.mrc_output_len; > - checksum = compute_ip_checksum(gd->arch.mrc_output, cache->data_size); > + cache->data_size = mrc->len; > + checksum = compute_ip_checksum(mrc->buf, cache->data_size); > debug("Saving %d bytes for MRC output data, checksum %04x\n", > cache->data_size, checksum); > cache->checksum = checksum; > cache->reserved = 0; > - memcpy(cache->data, gd->arch.mrc_output, cache->data_size); > + memcpy(cache->data, mrc->buf, cache->data_size); > > - gd->arch.mrc_cache = cache; > + mrc->cache = cache; > } > > int mrccache_reserve(void) > { > - if (!gd->arch.mrc_output_len) > - return 0; > + int i; > + > + for (i = 0; i < MRC_TYPE_COUNT; i++) { > + struct mrc_output *mrc = &gd->arch.mrc[i]; > > - /* adjust stack pointer to store pure cache data plus the header */ > - gd->start_addr_sp -= (gd->arch.mrc_output_len + MRC_DATA_HEADER_SIZE); > - mrccache_setup((void *)gd->start_addr_sp); > + if (!mrc->len) > + continue; > > - gd->start_addr_sp &= ~0xf; > + /* adjust stack pointer to store pure cache data plus header > */ > + gd->start_addr_sp -= (mrc->len + MRC_DATA_HEADER_SIZE); > + mrccache_setup(mrc, (void *)gd->start_addr_sp); > + > + gd->start_addr_sp &= ~0xf; > + } > > return 0; > } > > -int mrccache_get_region(struct udevice **devp, struct mrc_region *entry) > +int mrccache_get_region(enum mrc_type_t type, struct udevice **devp, > + struct mrc_region *entry) > { > struct udevice *dev; > ofnode mrc_node; > @@ -221,7 +228,8 @@ int mrccache_get_region(struct udevice **devp, struct > mrc_region *entry) > } > > /* Find the place where we put the MRC cache */ > - mrc_node = dev_read_subnode(dev, "rw-mrc-cache"); > + mrc_node = dev_read_subnode(dev, type == MRC_TYPE_NORMAL ? > + "rw-mrc-cache" : "rw-var-mrc-cache"); This change should either be put in next patch [86/126] "x86: Add mrccache support for a 'variable' cache", or squash the [86/126] patch into this patch. > if (!ofnode_valid(mrc_node)) > return log_msg_ret("Cannot find node", -EPERM); > > @@ -233,31 +241,33 @@ int mrccache_get_region(struct udevice **devp, struct > mrc_region *entry) > > if (devp) > *devp = dev; > - debug("MRC cache in '%s', offset %x, len %x, base %x\n", > - dev->name, entry->offset, entry->length, entry->base); > + debug("MRC cache type %d in '%s', offset %x, len %x, base %x\n", > + type, dev->name, entry->offset, entry->length, entry->base); > > return 0; > } > > -int mrccache_save(void) > +static int mrccache_save_type(enum mrc_type_t type) > { > struct mrc_data_container *cache; > + struct mrc_output *mrc; > struct mrc_region entry; > struct udevice *sf; > int ret; > > - if (!gd->arch.mrc_output_len) > + mrc = &gd->arch.mrc[type]; > + if (!mrc->len) > return 0; > - debug("Saving %#x bytes of MRC output data to SPI flash\n", > - gd->arch.mrc_output_len); > - > - ret = mrccache_get_region(&sf, &entry); > + log_debug("Saving %#x bytes of MRC output data type %d to SPI > flash\n", > + mrc->len, type); > + ret = mrccache_get_region(type, &sf, &entry); > if (ret) > return log_msg_ret("Cannot get region", ret); > ret = device_probe(sf); > if (ret) > return log_msg_ret("Cannot probe device", ret); > - cache = gd->arch.mrc_cache; > + cache = mrc->cache; > + > ret = mrccache_update(sf, &entry, cache); > if (!ret) > debug("Saved MRC data with checksum %04x\n", cache->checksum); > @@ -267,17 +277,36 @@ int mrccache_save(void) > return 0; > } > > +int mrccache_save(void) > +{ > + int i; > + > + for (i = 0; i < MRC_TYPE_COUNT; i++) { > + int ret; > + > + ret = mrccache_save_type(i); > + if (ret) > + return ret; > + } > + > + return 0; > +} > + > int mrccache_spl_save(void) > { > - void *data; > - int size; > - > - size = gd->arch.mrc_output_len + MRC_DATA_HEADER_SIZE; > - data = malloc(size); > - if (!data) > - return log_msg_ret("Allocate MRC cache block", -ENOMEM); > - mrccache_setup(data); > - gd->arch.mrc_output = data; > + int i; > + > + for (i = 0; i < MRC_TYPE_COUNT; i++) { > + struct mrc_output *mrc = &gd->arch.mrc[i]; > + void *data; > + int size; > + > + size = mrc->len + MRC_DATA_HEADER_SIZE; > + data = malloc(size); > + if (!data) > + return log_msg_ret("Allocate MRC cache block", > -ENOMEM); > + mrccache_setup(mrc, data); > + } > > return mrccache_save(); > } > -- Regards, Bin _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot