coreboot: infrastructure for different ramstage loaders
There are 2 methods currently available in coreboot to load ramstage from romstage: cbfs and vboot. The vboot path had to be explicitly enabled and code needed to be added to each chipset to support both. Additionally, many of the paths were duplicated between the two. An additional complication is the presence of having a relocatable ramstage which creates another path with duplication. To rectify this situation provide a common API through the use of a callback to load the ramstage. The rest of the existing logic to handle all the various cases is put in a common place. Change-Id: I5268ce70686cc0d121161a775c3a86ea38a4d8ae Signed-off-by: Aaron Durbin <adurbin@chromium.org> Reviewed-on: http://review.coreboot.org/5087 Tested-by: build bot (Jenkins) Reviewed-by: Paul Menzel <paulepanter@users.sourceforge.net> Reviewed-by: Patrick Georgi <patrick@georgi-clan.de>
This commit is contained in:
parent
e9aaa71fb1
commit
0f333071ef
|
@ -17,27 +17,10 @@
|
|||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include <console/console.h>
|
||||
#include <cbfs.h>
|
||||
#include <arch/stages.h>
|
||||
#include <timestamp.h>
|
||||
|
||||
static void cbfs_and_run_core(const char *filename)
|
||||
{
|
||||
u8 *dst;
|
||||
|
||||
timestamp_add_now(TS_START_COPYRAM);
|
||||
print_debug("Loading image.\n");
|
||||
dst = cbfs_load_stage(CBFS_DEFAULT_MEDIA, filename);
|
||||
if ((void *)dst == (void *) -1)
|
||||
die("FATAL: Essential component is missing.\n");
|
||||
|
||||
timestamp_add_now(TS_END_COPYRAM);
|
||||
print_debug("Jumping to image.\n");
|
||||
stage_exit(dst);
|
||||
}
|
||||
#include <ramstage_loader.h>
|
||||
|
||||
void asmlinkage copy_and_run(void)
|
||||
{
|
||||
cbfs_and_run_core(CONFIG_CBFS_PREFIX "/coreboot_ram");
|
||||
run_ramstage();
|
||||
}
|
||||
|
|
|
@ -309,8 +309,6 @@ void romstage_after_car(void)
|
|||
|
||||
prepare_for_resume(handoff);
|
||||
|
||||
vboot_verify_firmware(handoff);
|
||||
|
||||
/* Load the ramstage. */
|
||||
copy_and_run();
|
||||
}
|
||||
|
|
|
@ -83,6 +83,10 @@ void selfboot(void *entry);
|
|||
/* Defined in individual arch / board implementation. */
|
||||
int init_default_cbfs_media(struct cbfs_media *media);
|
||||
|
||||
#if defined(__PRE_RAM__)
|
||||
struct romstage_handoff;
|
||||
struct cbmem_entry;
|
||||
|
||||
#if CONFIG_RELOCATABLE_RAMSTAGE && defined(__PRE_RAM__)
|
||||
/* The cache_loaded_ramstage() and load_cached_ramstage() functions are defined
|
||||
* to be weak so that board and chipset code may override them. Their job is to
|
||||
|
@ -90,9 +94,6 @@ int init_default_cbfs_media(struct cbfs_media *media);
|
|||
* relocated ramstage is saved using the cbmem infrastructure. These
|
||||
* functions are only valid during romstage. */
|
||||
|
||||
struct romstage_handoff;
|
||||
struct cbmem_entry;
|
||||
|
||||
/* The implementer of cache_loaded_ramstage() may use the romstage_handoff
|
||||
* structure to store information, but note that the handoff variable can be
|
||||
* NULL. The ramstage cbmem_entry represents the region occupied by the loaded
|
||||
|
@ -105,7 +106,22 @@ cache_loaded_ramstage(struct romstage_handoff *handoff,
|
|||
void * __attribute__((weak))
|
||||
load_cached_ramstage(struct romstage_handoff *handoff,
|
||||
const struct cbmem_entry *ramstage);
|
||||
#else /* CONFIG_RELOCATABLE_RAMSTAGE */
|
||||
|
||||
static inline void cache_loaded_ramstage(struct romstage_handoff *handoff,
|
||||
const struct cbmem_entry *ramstage, void *entry_point)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void *
|
||||
load_cached_ramstage(struct romstage_handoff *handoff,
|
||||
const struct cbmem_entry *ramstage)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_RELOCATABLE_RAMSTAGE */
|
||||
#endif /* defined(__PRE_RAM__) */
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -66,6 +66,7 @@
|
|||
#define CBMEM_ID_HOB_POINTER 0x484f4221
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
struct cbmem_entry;
|
||||
|
@ -150,6 +151,10 @@ void cbmem_late_set_table(uint64_t base, uint64_t size);
|
|||
void get_cbmem_table(uint64_t *base, uint64_t *size);
|
||||
struct cbmem_entry *get_cbmem_toc(void);
|
||||
|
||||
static inline const struct cbmem_entry *cbmem_entry_find(uint32_t id)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
#endif /* CONFIG_DYNAMIC_CBMEM */
|
||||
|
||||
/* Common API between cbmem and dynamic cbmem. */
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* This file is part of the coreboot project.
|
||||
*
|
||||
* Copyright (C) 2014 Google Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; version 2 of the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
#ifndef RAMSTAGE_LOADER_H
|
||||
#define RAMSTAGE_LOADER_H
|
||||
|
||||
#include <stdint.h>
|
||||
struct cbmem_entry;
|
||||
|
||||
/* Run ramstage from romstage. */
|
||||
void run_ramstage(void);
|
||||
|
||||
struct ramstage_loader_ops {
|
||||
const char *name;
|
||||
void *(*load)(uint32_t cbmem_id, const char *name,
|
||||
const struct cbmem_entry **cbmem_entry);
|
||||
};
|
||||
|
||||
#endif /* RAMSTAGE_LOADER_H */
|
|
@ -41,6 +41,7 @@ struct romstage_handoff {
|
|||
};
|
||||
|
||||
#if defined(__PRE_RAM__)
|
||||
#if CONFIG_EARLY_CBMEM_INIT
|
||||
/* The romstage_handoff_find_or_add() function provides the necessary logic
|
||||
* for initializing the romstage_handoff structure in cbmem. Different components
|
||||
* of the romstage may be responsible for setting up different fields. Therefore
|
||||
|
@ -63,7 +64,14 @@ static inline struct romstage_handoff *romstage_handoff_find_or_add(void)
|
|||
|
||||
return handoff;
|
||||
}
|
||||
#endif
|
||||
#else /* CONFIG_EARLY_CBMEM_INIT */
|
||||
static inline struct romstage_handoff *romstage_handoff_find_or_add(void)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
#endif /* CONFIG_EARLY_CBMEM_INIT */
|
||||
|
||||
#endif /* defined(__PRE_RAM__) */
|
||||
|
||||
#endif /* ROMSTAGE_HANDOFF_H */
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
#
|
||||
subdirs-y += loaders
|
||||
|
||||
bootblock-y += cbfs.c
|
||||
ifneq ($(CONFIG_HAVE_ARCH_MEMSET),y)
|
||||
|
|
|
@ -123,58 +123,6 @@ void *cbfs_load_optionrom(struct cbfs_media *media, uint16_t vendor,
|
|||
return dest;
|
||||
}
|
||||
|
||||
#if CONFIG_RELOCATABLE_RAMSTAGE && defined(__PRE_RAM__)
|
||||
|
||||
#include <rmodule.h>
|
||||
#include <romstage_handoff.h>
|
||||
static void *load_stage_from_cbfs(struct cbfs_media *media, const char *name,
|
||||
struct romstage_handoff *handoff)
|
||||
{
|
||||
struct rmod_stage_load rmod_ram = {
|
||||
.cbmem_id = CBMEM_ID_RAMSTAGE,
|
||||
.name = name,
|
||||
};
|
||||
|
||||
if (rmodule_stage_load_from_cbfs(&rmod_ram)) {
|
||||
printk(BIOS_DEBUG, "Could not load ramstage.\n");
|
||||
return (void *) -1;
|
||||
}
|
||||
|
||||
cache_loaded_ramstage(handoff, rmod_ram.cbmem_entry, rmod_ram.entry);
|
||||
|
||||
return rmod_ram.entry;
|
||||
}
|
||||
|
||||
void * cbfs_load_stage(struct cbfs_media *media, const char *name)
|
||||
{
|
||||
struct romstage_handoff *handoff;
|
||||
const struct cbmem_entry *ramstage;
|
||||
void *entry;
|
||||
|
||||
handoff = romstage_handoff_find_or_add();
|
||||
|
||||
if (handoff == NULL) {
|
||||
LOG("Couldn't find or allocate romstage handoff.\n");
|
||||
return load_stage_from_cbfs(media, name, handoff);
|
||||
} else if (!handoff->s3_resume)
|
||||
return load_stage_from_cbfs(media, name, handoff);
|
||||
|
||||
ramstage = cbmem_entry_find(CBMEM_ID_RAMSTAGE);
|
||||
|
||||
if (ramstage == NULL)
|
||||
return load_stage_from_cbfs(media, name, handoff);
|
||||
|
||||
/* S3 resume path. Load a cached copy of the loaded ramstage. If
|
||||
* return value is NULL load from cbfs. */
|
||||
entry = load_cached_ramstage(handoff, ramstage);
|
||||
if (entry == NULL)
|
||||
return load_stage_from_cbfs(media, name, handoff);
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
void * cbfs_load_stage(struct cbfs_media *media, const char *name)
|
||||
{
|
||||
struct cbfs_stage *stage = (struct cbfs_stage *)
|
||||
|
@ -211,7 +159,6 @@ void * cbfs_load_stage(struct cbfs_media *media, const char *name)
|
|||
|
||||
return (void *) entry;
|
||||
}
|
||||
#endif /* CONFIG_RELOCATABLE_RAMSTAGE */
|
||||
|
||||
#if !CONFIG_ALT_CBFS_LOAD_PAYLOAD
|
||||
void *cbfs_load_payload(struct cbfs_media *media, const char *name)
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
#
|
||||
# This file is part of the coreboot project.
|
||||
#
|
||||
# Copyright (C) 2014 Google Inc.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; version 2 of the License.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
#
|
||||
|
||||
romstage-y += cbfs_ramstage_loader.c
|
||||
romstage-y += load_and_run_ramstage.c
|
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* This file is part of the coreboot project.
|
||||
*
|
||||
* Copyright (C) 2008-2009 coresystems GmbH
|
||||
* Copyright (C) 2014 Google Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; version 2 of the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
#include <console/console.h>
|
||||
#include <cbfs.h>
|
||||
#include <arch/stages.h>
|
||||
#include <ramstage_loader.h>
|
||||
#include <timestamp.h>
|
||||
|
||||
#if CONFIG_RELOCATABLE_RAMSTAGE
|
||||
#include <rmodule.h>
|
||||
|
||||
static void *cbfs_load_ramstage(uint32_t cbmem_id, const char *name,
|
||||
const struct cbmem_entry **cbmem_entry)
|
||||
{
|
||||
struct rmod_stage_load rmod_ram = {
|
||||
.cbmem_id = cbmem_id,
|
||||
.name = name,
|
||||
};
|
||||
|
||||
if (rmodule_stage_load_from_cbfs(&rmod_ram)) {
|
||||
printk(BIOS_DEBUG, "Could not load ramstage.\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
*cbmem_entry = rmod_ram.cbmem_entry;
|
||||
|
||||
return rmod_ram.entry;
|
||||
}
|
||||
|
||||
#else /* CONFIG_RELOCATABLE_RAMSTAGE */
|
||||
|
||||
static void *cbfs_load_ramstage(uint32_t cbmem_id, const char *name,
|
||||
const struct cbmem_entry **cbmem_entry)
|
||||
{
|
||||
void *entry;
|
||||
|
||||
entry = cbfs_load_stage(CBFS_DEFAULT_MEDIA, name);
|
||||
|
||||
if ((void *)entry == (void *) -1)
|
||||
entry = NULL;
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_RELOCATABLE_RAMSTAGE */
|
||||
|
||||
const struct ramstage_loader_ops cbfs_ramstage_loader = {
|
||||
.name = "CBFS",
|
||||
.load = cbfs_load_ramstage,
|
||||
};
|
|
@ -0,0 +1,100 @@
|
|||
/*
|
||||
* This file is part of the coreboot project.
|
||||
*
|
||||
* Copyright (C) 2014 Google Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; version 2 of the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <console/console.h>
|
||||
#include <arch/stages.h>
|
||||
#include <cbfs.h>
|
||||
#include <cbmem.h>
|
||||
#include <ramstage_loader.h>
|
||||
#include <romstage_handoff.h>
|
||||
#include <timestamp.h>
|
||||
|
||||
extern const struct ramstage_loader_ops cbfs_ramstage_loader;
|
||||
extern const struct ramstage_loader_ops vboot_ramstage_loader;
|
||||
|
||||
static const struct ramstage_loader_ops *loaders[] = {
|
||||
#if CONFIG_VBOOT_VERIFY_FIRMWARE
|
||||
&vboot_ramstage_loader,
|
||||
#endif
|
||||
&cbfs_ramstage_loader,
|
||||
};
|
||||
|
||||
static const char *ramstage_name = CONFIG_CBFS_PREFIX "/coreboot_ram";
|
||||
static const uint32_t ramstage_id = CBMEM_ID_RAMSTAGE;
|
||||
|
||||
static void
|
||||
load_ramstage(const struct ramstage_loader_ops *ops, struct romstage_handoff *handoff)
|
||||
{
|
||||
const struct cbmem_entry *cbmem_entry;
|
||||
void *entry_point;
|
||||
|
||||
timestamp_add_now(TS_START_COPYRAM);
|
||||
entry_point = ops->load(ramstage_id, ramstage_name, &cbmem_entry);
|
||||
|
||||
if (entry_point == NULL)
|
||||
return;
|
||||
|
||||
cache_loaded_ramstage(handoff, cbmem_entry, entry_point);
|
||||
|
||||
timestamp_add_now(TS_END_COPYRAM);
|
||||
|
||||
stage_exit(entry_point);
|
||||
}
|
||||
|
||||
static void run_ramstage_from_resume(struct romstage_handoff *handoff)
|
||||
{
|
||||
void *entry;
|
||||
const struct cbmem_entry *cbmem_entry;
|
||||
|
||||
if (handoff != NULL && handoff->s3_resume) {
|
||||
cbmem_entry = cbmem_entry_find(ramstage_id);
|
||||
|
||||
/* No place to load ramstage. */
|
||||
if (cbmem_entry == NULL)
|
||||
return;
|
||||
|
||||
/* Load the cached ramstage to runtime location. */
|
||||
entry = load_cached_ramstage(handoff, cbmem_entry);
|
||||
|
||||
if (entry != NULL) {
|
||||
print_debug("Jumping to image.\n");
|
||||
stage_exit(entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void run_ramstage(void)
|
||||
{
|
||||
struct romstage_handoff *handoff;
|
||||
const struct ramstage_loader_ops *ops;
|
||||
int i;
|
||||
|
||||
handoff = romstage_handoff_find_or_add();
|
||||
|
||||
run_ramstage_from_resume(handoff);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(loaders); i++) {
|
||||
ops = loaders[i];
|
||||
printk(BIOS_DEBUG, "Trying %s ramstage loader.\n", ops->name);
|
||||
load_ramstage(ops, handoff);
|
||||
}
|
||||
|
||||
die("Ramstage was not loaded!\n");
|
||||
}
|
|
@ -28,7 +28,6 @@
|
|||
#include <ramstage_cache.h>
|
||||
#include <romstage_handoff.h>
|
||||
#include <timestamp.h>
|
||||
#include <vendorcode/google/chromeos/chromeos.h>
|
||||
#include <baytrail/gpio.h>
|
||||
#include <baytrail/iomap.h>
|
||||
#include <baytrail/lpc.h>
|
||||
|
@ -172,9 +171,6 @@ void asmlinkage romstage_after_car(void)
|
|||
|
||||
timestamp_add_now(TS_END_ROMSTAGE);
|
||||
|
||||
/* Run vboot verification if configured. */
|
||||
vboot_verify_firmware(romstage_handoff_find_or_add());
|
||||
|
||||
/* Load the ramstage. */
|
||||
copy_and_run();
|
||||
while (1);
|
||||
|
|
|
@ -46,14 +46,10 @@ int recovery_mode_enabled(void);
|
|||
/* functions implemented in vboot.c */
|
||||
void init_chromeos(int bootmode);
|
||||
|
||||
struct romstage_handoff;
|
||||
#if CONFIG_VBOOT_VERIFY_FIRMWARE
|
||||
void vboot_verify_firmware(struct romstage_handoff *handoff);
|
||||
void *vboot_get_payload(size_t *len);
|
||||
/* Returns 0 on success < 0 on error. */
|
||||
int vboot_get_handoff_info(void **addr, uint32_t *size);
|
||||
#else
|
||||
static inline void vboot_verify_firmware(struct romstage_handoff *h) {}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include <console/vtxprintf.h>
|
||||
#include <pc80/tpm.h>
|
||||
#include <reset.h>
|
||||
#include <ramstage_loader.h>
|
||||
#include <romstage_handoff.h>
|
||||
#include <rmodule.h>
|
||||
#include <string.h>
|
||||
|
@ -141,57 +142,17 @@ static void vboot_invoke_wrapper(struct vboot_handoff *vboot_handoff)
|
|||
vboot_run_stub(&context);
|
||||
}
|
||||
|
||||
static void vboot_load_ramstage(struct vboot_handoff *vboot_handoff,
|
||||
struct romstage_handoff *handoff)
|
||||
static void *vboot_load_ramstage(uint32_t cbmem_id, const char *name,
|
||||
const struct cbmem_entry **cbmem_entry)
|
||||
{
|
||||
struct vboot_handoff *vboot_handoff;
|
||||
struct cbfs_stage *stage;
|
||||
const struct firmware_component *fwc;
|
||||
struct rmod_stage_load rmod_load = {
|
||||
.cbmem_id = CBMEM_ID_RAMSTAGE,
|
||||
.name = CONFIG_CBFS_PREFIX "/coreboot_ram",
|
||||
.cbmem_id = cbmem_id,
|
||||
.name = name,
|
||||
};
|
||||
|
||||
if (CONFIG_VBOOT_RAMSTAGE_INDEX >= MAX_PARSED_FW_COMPONENTS) {
|
||||
printk(BIOS_ERR, "Invalid ramstage index: %d\n",
|
||||
CONFIG_VBOOT_RAMSTAGE_INDEX);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Check for invalid address. */
|
||||
fwc = &vboot_handoff->components[CONFIG_VBOOT_RAMSTAGE_INDEX];
|
||||
if (fwc->address == 0) {
|
||||
printk(BIOS_DEBUG, "RW ramstage image address invalid.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
printk(BIOS_DEBUG, "RW ramstage image at 0x%08x, 0x%08x bytes.\n",
|
||||
fwc->address, fwc->size);
|
||||
|
||||
stage = (void *)fwc->address;
|
||||
|
||||
timestamp_add_now(TS_START_COPYRAM);
|
||||
|
||||
if (rmodule_stage_load(&rmod_load, stage)) {
|
||||
vboot_handoff->selected_firmware = VB_SELECT_FIRMWARE_READONLY;
|
||||
printk(BIOS_DEBUG, "Could not load ramstage region.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
cache_loaded_ramstage(handoff, rmod_load.cbmem_entry, rmod_load.entry);
|
||||
|
||||
timestamp_add_now(TS_END_COPYRAM);
|
||||
|
||||
stage_exit(rmod_load.entry);
|
||||
}
|
||||
|
||||
void vboot_verify_firmware(struct romstage_handoff *handoff)
|
||||
{
|
||||
struct vboot_handoff *vboot_handoff;
|
||||
|
||||
/* Don't go down verified boot path on S3 resume. */
|
||||
if (handoff != NULL && handoff->s3_resume)
|
||||
return;
|
||||
|
||||
timestamp_add_now(TS_START_VBOOT);
|
||||
|
||||
vboot_handoff = cbmem_add(CBMEM_ID_VBOOT_HANDOFF,
|
||||
|
@ -199,7 +160,7 @@ void vboot_verify_firmware(struct romstage_handoff *handoff)
|
|||
|
||||
if (vboot_handoff == NULL) {
|
||||
printk(BIOS_DEBUG, "Could not add vboot_handoff structure.\n");
|
||||
return;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memset(vboot_handoff, 0, sizeof(*vboot_handoff));
|
||||
|
@ -213,9 +174,39 @@ void vboot_verify_firmware(struct romstage_handoff *handoff)
|
|||
vboot_handoff->selected_firmware != VB_SELECT_FIRMWARE_B) {
|
||||
printk(BIOS_DEBUG, "No RW firmware selected: 0x%08x\n",
|
||||
vboot_handoff->selected_firmware);
|
||||
return;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Load ramstage from the vboot_handoff structure. */
|
||||
vboot_load_ramstage(vboot_handoff, handoff);
|
||||
if (CONFIG_VBOOT_RAMSTAGE_INDEX >= MAX_PARSED_FW_COMPONENTS) {
|
||||
printk(BIOS_ERR, "Invalid ramstage index: %d\n",
|
||||
CONFIG_VBOOT_RAMSTAGE_INDEX);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Check for invalid address. */
|
||||
fwc = &vboot_handoff->components[CONFIG_VBOOT_RAMSTAGE_INDEX];
|
||||
if (fwc->address == 0) {
|
||||
printk(BIOS_DEBUG, "RW ramstage image address invalid.\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
printk(BIOS_DEBUG, "RW ramstage image at 0x%08x, 0x%08x bytes.\n",
|
||||
fwc->address, fwc->size);
|
||||
|
||||
stage = (void *)fwc->address;
|
||||
|
||||
if (rmodule_stage_load(&rmod_load, stage)) {
|
||||
vboot_handoff->selected_firmware = VB_SELECT_FIRMWARE_READONLY;
|
||||
printk(BIOS_DEBUG, "Could not load ramstage region.\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
*cbmem_entry = rmod_load.cbmem_entry;
|
||||
|
||||
return rmod_load.entry;
|
||||
}
|
||||
|
||||
const struct ramstage_loader_ops vboot_ramstage_loader = {
|
||||
.name = "VBOOT",
|
||||
.load = vboot_load_ramstage,
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue