From patchwork Mon Nov 25 04:09:44 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 1200188 X-Patchwork-Delegate: bmeng.cn@gmail.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.denx.de (client-ip=81.169.180.215; helo=lists.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=chromium.org Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=chromium.org header.i=@chromium.org header.b="fW7gPINu"; dkim-atps=neutral Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 47LvkR6Sr2z9sPK for ; Mon, 25 Nov 2019 15:51:11 +1100 (AEDT) Received: by lists.denx.de (Postfix, from userid 105) id C6CAAC21E30; Mon, 25 Nov 2019 04:25:01 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=RCVD_IN_MSPIKE_H2, T_DKIM_INVALID autolearn=unavailable autolearn_force=no version=3.4.0 Received: from lists.denx.de (localhost [IPv6:::1]) by lists.denx.de (Postfix) with ESMTP id CB6B7C21E08; Mon, 25 Nov 2019 04:12:22 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id C1891C21EBE; Mon, 25 Nov 2019 04:11:50 +0000 (UTC) Received: from mail-il1-f196.google.com (mail-il1-f196.google.com [209.85.166.196]) by lists.denx.de (Postfix) with ESMTPS id 112EBC21DFB for ; Mon, 25 Nov 2019 04:11:39 +0000 (UTC) Received: by mail-il1-f196.google.com with SMTP id q1so12873906ile.13 for ; Sun, 24 Nov 2019 20:11:39 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=C0YgzHjQAW8cSFFiZN1S7RvgELRiDedL5Nk6qO6p6yI=; b=fW7gPINuT/BSyMIZ5IQss01sHXgIa6QX8wd7hsHn2IucfiG8s46J01owkZzkLC2tYo TdEMbrM/efqZauibePvkdU9egWug4Sg3qim3AAWq2gtVI9lCJ4Cga1na0ZnYW4IAk7g4 nT+JJvbxSFxUG9yQBbHC1YGPLjvyQEAcLn3tA= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=C0YgzHjQAW8cSFFiZN1S7RvgELRiDedL5Nk6qO6p6yI=; b=I3ELHB3xwSE0BqPpni9qG97UiE6zmcOs+TPJA6XKWAqKEQGKmXLhWWTrKoxd3IDKBj gJyKqGlBhL/9Gsxx3YpvKouDiTnusZeJJmrcnxC/mmV4t+AtsxDFVGKKrqCNo7TIlJO1 F2Gc9vReukEpV5d78KAxIYMwjZhkZmpVSrBmEH0m9eEWTpm1UqnyoqSlZ4TYxhWWdl7s 5pTSROPH3YC6tL8OIr5jZSuSv8s9nxnyan0swyXKJpwbYBi9XI9jz4CN05gp1I9KQT7F EaStr52uEyGW9kJIXl2TuZNrdKztx6AikxEsfbONhMrpVPct9SbFt6DpM779wEkHdOoy 5W2g== X-Gm-Message-State: APjAAAVKW8taRNE0yfCbyzjhU5djAm4B4ZIl3vPoqfywDj0z2MAMgWQ4 J9IAm9eA6Tj/8Dq0Y4nwnouftVJa9ik= X-Google-Smtp-Source: APXvYqyUAS83Bi0dkzLqZKV5witgXMs+cGFCFr2ieGP3NlLjVeJVx5OBnQJb2auOPdhDXgi5xzYFOQ== X-Received: by 2002:a92:8388:: with SMTP id p8mr31753523ilk.49.1574655097620; Sun, 24 Nov 2019 20:11:37 -0800 (PST) Received: from kiwi.bld.corp.google.com ([2620:15c:183:0:8223:87c:a681:66aa]) by smtp.gmail.com with ESMTPSA id k199sm1827978ilk.20.2019.11.24.20.11.37 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 24 Nov 2019 20:11:37 -0800 (PST) From: Simon Glass To: U-Boot Mailing List Date: Sun, 24 Nov 2019 21:09:44 -0700 Message-Id: <20191124211020.v5.34.Ie8badf1328570408b3352525d35cd0f804073e17@changeid> X-Mailer: git-send-email 2.24.0.432.g9d3f5f5b63-goog In-Reply-To: <20191125041051.117416-1-sjg@chromium.org> References: <20191125041051.117416-1-sjg@chromium.org> MIME-Version: 1.0 Subject: [U-Boot] [PATCH v5 034/101] x86: Update mrccache to support multiple caches X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.18 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" With Apollo Lake 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 Reviewed-by: Bin Meng --- Changes in v5: None Changes in v4: - apollolake -> Apollo Lake Changes in v3: - Move line related to variable-cache into the next patch Changes in v2: None 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 | 88 ++++++++++++++++++++---------- 8 files changed, 106 insertions(+), 48 deletions(-) diff --git a/arch/x86/cpu/broadwell/sdram.c b/arch/x86/cpu/broadwell/sdram.c index b31d78c092..107c04691b 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 8a58d0383d..8b03406666 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 51f9659ab1..3994355112 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 3212b006eb..190b604e0f 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); @@ -91,10 +106,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 abf5818223..b81e2b2fb6 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 40ba866d77..c1c30ce0eb 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 6a3349b42a..5ef89744b9 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 712bacd5d2..1278737ce4 100644 --- a/arch/x86/lib/mrccache.c +++ b/arch/x86/lib/mrccache.c @@ -174,38 +174,45 @@ int mrccache_update(struct udevice *sf, struct mrc_region *entry, 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; @@ -246,31 +253,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); @@ -280,17 +289,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(); }