aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/init.c2
-rw-r--r--core/nvram-format.c9
-rw-r--r--core/nvram.c35
-rw-r--r--core/test/run-nvram-format.c10
-rw-r--r--hw/fsp/fsp-nvram.c28
-rw-r--r--include/fsp.h1
-rw-r--r--include/nvram.h2
7 files changed, 61 insertions, 26 deletions
diff --git a/core/init.c b/core/init.c
index 89a2758..f2747c6 100644
--- a/core/init.c
+++ b/core/init.c
@@ -497,7 +497,7 @@ void __noreturn load_and_boot_kernel(bool is_reboot)
/* We wait for the nvram read to complete here so we can
* grab stuff from there such as the kernel arguments
*/
- fsp_nvram_wait_open();
+ nvram_wait_for_load();
/* Wait for FW VPD data read to complete */
fsp_code_update_wait_vpd(true);
diff --git a/core/nvram-format.c b/core/nvram-format.c
index 923098a..3d030a3 100644
--- a/core/nvram-format.c
+++ b/core/nvram-format.c
@@ -216,6 +216,15 @@ const char *nvram_query(const char *key)
const char *part_end, *start;
int key_len = strlen(key);
+ if (!nvram_has_loaded()) {
+ prlog(PR_WARNING, "NVRAM: Query before is done loading\n");
+ prlog(PR_WARNING, "NVRAM: Waiting for load\n");
+ if (!nvram_wait_for_load()) {
+ prlog(PR_CRIT, "NVRAM: Failed to load\n");
+ return NULL;
+ }
+ }
+
/*
* The running OS can modify the NVRAM as it pleases so we need to be
* a little paranoid and check that it's ok before we try parse it.
diff --git a/core/nvram.c b/core/nvram.c
index 2140706..de6cbdd 100644
--- a/core/nvram.c
+++ b/core/nvram.c
@@ -122,6 +122,41 @@ void nvram_read_complete(bool success)
nvram_ready = true;
}
+bool nvram_wait_for_load(void)
+{
+ /* Short cut */
+ if (nvram_ready)
+ return true;
+
+ /* Tell the caller it will never happen */
+ if (!platform.nvram_info)
+ return false;
+
+ /*
+ * One of two things has happened here.
+ * 1. nvram_wait_for_load() was called before nvram_init()
+ * 2. The read of NVRAM failed.
+ * Either way, this is quite a bad event.
+ */
+ if (!nvram_image && !nvram_size) {
+ prlog(PR_CRIT, "NVRAM: Possible wait before nvram_init()!\n");
+ return false;
+ }
+
+ while (!nvram_ready) {
+ opal_run_pollers();
+ /* If the read fails, tell the caller */
+ if (!nvram_image && !nvram_size)
+ return false;
+ }
+ return true;
+}
+
+bool nvram_has_loaded(void)
+{
+ return nvram_ready;
+}
+
void nvram_init(void)
{
int rc;
diff --git a/core/test/run-nvram-format.c b/core/test/run-nvram-format.c
index 5bd8ea2..d86b1dc 100644
--- a/core/test/run-nvram-format.c
+++ b/core/test/run-nvram-format.c
@@ -18,11 +18,21 @@
#include "../nvram-format.c"
+bool nvram_wait_for_load(void)
+{
+ return true;
+}
+
bool nvram_validate(void)
{
return true;
}
+bool nvram_has_loaded(void)
+{
+ return true;
+}
+
static char *nvram_reset(void *nvram_image, int size)
{
struct chrp_nvram_hdr *h = nvram_image;
diff --git a/hw/fsp/fsp-nvram.c b/hw/fsp/fsp-nvram.c
index 1b4990f..eef535c 100644
--- a/hw/fsp/fsp-nvram.c
+++ b/hw/fsp/fsp-nvram.c
@@ -203,6 +203,10 @@ static void fsp_nvram_rd_complete(struct fsp_msg *msg)
*/
}
unlock(&fsp_nvram_lock);
+ nvram_read_complete(fsp_nvram_state == NVRAM_STATE_OPEN);
+ if (fsp_nvram_state != NVRAM_STATE_OPEN)
+ log_simple_error(&e_info(OPAL_RC_NVRAM_INIT),
+ "FSP: NVRAM not read, skipping init\n");
}
static void fsp_nvram_send_read(void)
@@ -428,27 +432,3 @@ int fsp_nvram_write(uint32_t offset, void *src, uint32_t size)
return 0;
}
-
-/* This is called right before starting the payload (Linux) to
- * ensure the initial open & read of nvram has happened before
- * we transfer control as the guest OS. This is necessary as
- * Linux will not handle a OPAL_BUSY return properly and treat
- * it as an error
- */
-void fsp_nvram_wait_open(void)
-{
- if (!fsp_present())
- return;
-
- while(fsp_nvram_state == NVRAM_STATE_OPENING)
- opal_run_pollers();
-
- if (!fsp_nvram_was_read) {
- log_simple_error(&e_info(OPAL_RC_NVRAM_INIT),
- "FSP: NVRAM not read, skipping init\n");
- nvram_read_complete(false);
- return;
- }
-
- nvram_read_complete(true);
-}
diff --git a/include/fsp.h b/include/fsp.h
index 36802a1..c34a518 100644
--- a/include/fsp.h
+++ b/include/fsp.h
@@ -776,7 +776,6 @@ extern void fsp_used_by_console(void);
extern int fsp_nvram_info(uint32_t *total_size);
extern int fsp_nvram_start_read(void *dst, uint32_t src, uint32_t len);
extern int fsp_nvram_write(uint32_t offset, void *src, uint32_t size);
-extern void fsp_nvram_wait_open(void);
/* RTC */
extern void fsp_rtc_init(void);
diff --git a/include/nvram.h b/include/nvram.h
index 288b536..012c107 100644
--- a/include/nvram.h
+++ b/include/nvram.h
@@ -21,6 +21,8 @@ int nvram_format(void *nvram_image, uint32_t nvram_size);
int nvram_check(void *nvram_image, uint32_t nvram_size);
void nvram_reinit(void);
bool nvram_validate(void);
+bool nvram_has_loaded(void);
+bool nvram_wait_for_load(void);
const char *nvram_query(const char *name);
bool nvram_query_eq(const char *key, const char *value);