diff options
-rw-r--r-- | core/init.c | 2 | ||||
-rw-r--r-- | core/nvram-format.c | 9 | ||||
-rw-r--r-- | core/nvram.c | 35 | ||||
-rw-r--r-- | core/test/run-nvram-format.c | 10 | ||||
-rw-r--r-- | hw/fsp/fsp-nvram.c | 28 | ||||
-rw-r--r-- | include/fsp.h | 1 | ||||
-rw-r--r-- | include/nvram.h | 2 |
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); |