assets: abstract away the firmware assets used for booting
As there can be more than one source of firmware assets this patch generalizes the notion of locating a particular asset. struct asset is added along with some helper functions for working on assets as a first class citizen. Change-Id: I2ce575d1e5259aed4c34c3dcfd438abe9db1d7b9 Signed-off-by: Aaron Durbin <adurbin@chromium.org> Reviewed-on: http://review.coreboot.org/10264 Reviewed-by: Patrick Georgi <pgeorgi@google.com> Tested-by: build bot (Jenkins)
This commit is contained in:
parent
6a452eff90
commit
ac12c66cf9
|
@ -45,10 +45,7 @@ void __attribute__((weak)) *soc_get_bl31_plat_params(bl31_params_t *params)
|
||||||
|
|
||||||
void arm_tf_run_bl31(u64 payload_entry, u64 payload_arg0, u64 payload_spsr)
|
void arm_tf_run_bl31(u64 payload_entry, u64 payload_arg0, u64 payload_spsr)
|
||||||
{
|
{
|
||||||
struct prog bl31 = {
|
struct prog bl31 = PROG_INIT(ASSET_BL31, CONFIG_CBFS_PREFIX"/bl31");
|
||||||
.type = PROG_BL31,
|
|
||||||
.name = CONFIG_CBFS_PREFIX"/bl31",
|
|
||||||
};
|
|
||||||
void (*bl31_entry)(bl31_params_t *params, void *plat_params) = NULL;
|
void (*bl31_entry)(bl31_params_t *params, void *plat_params) = NULL;
|
||||||
|
|
||||||
if (prog_locate(&bl31))
|
if (prog_locate(&bl31))
|
||||||
|
|
|
@ -73,7 +73,7 @@ void arch_prog_run(struct prog *prog)
|
||||||
void (*doit)(void *);
|
void (*doit)(void *);
|
||||||
void *arg;
|
void *arg;
|
||||||
|
|
||||||
if (ENV_RAMSTAGE && prog->type == PROG_PAYLOAD) {
|
if (ENV_RAMSTAGE && prog_type(prog) == ASSET_PAYLOAD) {
|
||||||
run_payload(prog);
|
run_payload(prog);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -125,7 +125,7 @@ static void jmp_payload(void *entry, unsigned long buffer, unsigned long size)
|
||||||
|
|
||||||
static void try_payload(struct prog *prog)
|
static void try_payload(struct prog *prog)
|
||||||
{
|
{
|
||||||
if (prog->type == PROG_PAYLOAD) {
|
if (prog_type(prog) == ASSET_PAYLOAD) {
|
||||||
if (IS_ENABLED(CONFIG_RELOCATABLE_RAMSTAGE))
|
if (IS_ENABLED(CONFIG_RELOCATABLE_RAMSTAGE))
|
||||||
jmp_payload_no_bounce_buffer(prog_entry(prog));
|
jmp_payload_no_bounce_buffer(prog_entry(prog));
|
||||||
else
|
else
|
||||||
|
|
|
@ -0,0 +1,91 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the coreboot project.
|
||||||
|
*
|
||||||
|
* Copyright 2015 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.
|
||||||
|
*/
|
||||||
|
#ifndef ASSETS_H
|
||||||
|
#define ASSETS_H
|
||||||
|
|
||||||
|
#include <region.h>
|
||||||
|
|
||||||
|
/* An asset represents data used to boot the system. It can be found within
|
||||||
|
* CBFS or some other mechanism. While CBFS can be a source of an asset, note
|
||||||
|
* that using the asset API implies querying of other sources. */
|
||||||
|
|
||||||
|
enum asset_type {
|
||||||
|
ASSET_UNKNOWN,
|
||||||
|
ASSET_VERSTAGE,
|
||||||
|
ASSET_ROMSTAGE,
|
||||||
|
ASSET_RAMSTAGE,
|
||||||
|
ASSET_REFCODE,
|
||||||
|
ASSET_PAYLOAD,
|
||||||
|
ASSET_BL31,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct asset {
|
||||||
|
enum asset_type type;
|
||||||
|
const char *name;
|
||||||
|
struct region_device rdev;
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline const char *asset_name(const struct asset *asset)
|
||||||
|
{
|
||||||
|
return asset->name;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline enum asset_type asset_type(const struct asset *asset)
|
||||||
|
{
|
||||||
|
return asset->type;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct region_device *asset_rdev(struct asset *asset)
|
||||||
|
{
|
||||||
|
return &asset->rdev;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline size_t asset_size(const struct asset *asset)
|
||||||
|
{
|
||||||
|
return region_device_sz(&asset->rdev);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Returns NULL on error. */
|
||||||
|
static inline void *asset_mmap(const struct asset *asset)
|
||||||
|
{
|
||||||
|
return rdev_mmap_full(&asset->rdev);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define ASSET_INIT(type_, name_) \
|
||||||
|
{ \
|
||||||
|
.type = (type_), \
|
||||||
|
.name = (name_), \
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Locate the asset as described by the parameter. It will query all known
|
||||||
|
* asset providers. Returns 0 on success. < 0 on error. */
|
||||||
|
int asset_locate(struct asset *asset);
|
||||||
|
|
||||||
|
struct asset_provider {
|
||||||
|
const char *name;
|
||||||
|
/* Determines if the provider is the active one. If so returns 1 else 0
|
||||||
|
* or < 0 on error. */
|
||||||
|
int (*is_active)(struct asset *asset);
|
||||||
|
/* Returns < 0 on error or 0 on success. This function locates
|
||||||
|
* the rdev representing the file data associated with the passed in
|
||||||
|
* prog. */
|
||||||
|
int (*locate)(struct asset *asset);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* ASSETS_H */
|
|
@ -22,7 +22,7 @@
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <region.h>
|
#include <assets.h>
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
/* Last segment of program. Can be used to take different actions for
|
/* Last segment of program. Can be used to take different actions for
|
||||||
|
@ -34,40 +34,49 @@ enum {
|
||||||
* set on the last segment loaded. */
|
* set on the last segment loaded. */
|
||||||
void arch_segment_loaded(uintptr_t start, size_t size, int flags);
|
void arch_segment_loaded(uintptr_t start, size_t size, int flags);
|
||||||
|
|
||||||
enum prog_type {
|
|
||||||
PROG_VERSTAGE,
|
|
||||||
PROG_ROMSTAGE,
|
|
||||||
PROG_RAMSTAGE,
|
|
||||||
PROG_REFCODE,
|
|
||||||
PROG_PAYLOAD,
|
|
||||||
PROG_BL31,
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Representation of a program. */
|
/* Representation of a program. */
|
||||||
struct prog {
|
struct prog {
|
||||||
enum prog_type type;
|
/* The region_device within the asset is the source of program content
|
||||||
const char *name;
|
* to load. After loading program it represents the memory region of
|
||||||
/* Source of program content to load. After loading program it
|
* the stages and payload. For architectures that use a bounce buffer
|
||||||
* represents the memory region of the stages and payload. For
|
* then it would represent the bounce buffer. */
|
||||||
* architectures that use a bounce buffer then it would represent
|
struct asset asset;
|
||||||
* the bounce buffer. */
|
|
||||||
struct region_device rdev;
|
|
||||||
/* Entry to program with optional argument. It's up to the architecture
|
/* Entry to program with optional argument. It's up to the architecture
|
||||||
* to decide if argument is passed. */
|
* to decide if argument is passed. */
|
||||||
void (*entry)(void *);
|
void (*entry)(void *);
|
||||||
void *arg;
|
void *arg;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define PROG_INIT(type_, name_) \
|
||||||
|
{ \
|
||||||
|
.asset = ASSET_INIT(type_, name_), \
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline const char *prog_name(const struct prog *prog)
|
||||||
|
{
|
||||||
|
return asset_name(&prog->asset);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline enum asset_type prog_type(const struct prog *prog)
|
||||||
|
{
|
||||||
|
return asset_type(&prog->asset);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline struct region_device *prog_rdev(struct prog *prog)
|
||||||
|
{
|
||||||
|
return asset_rdev(&prog->asset);
|
||||||
|
}
|
||||||
|
|
||||||
/* Only valid for loaded programs. */
|
/* Only valid for loaded programs. */
|
||||||
static inline size_t prog_size(const struct prog *prog)
|
static inline size_t prog_size(const struct prog *prog)
|
||||||
{
|
{
|
||||||
return region_device_sz(&prog->rdev);
|
return asset_size(&prog->asset);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Only valid for loaded programs. */
|
/* Only valid for loaded programs. */
|
||||||
static inline void *prog_start(const struct prog *prog)
|
static inline void *prog_start(const struct prog *prog)
|
||||||
{
|
{
|
||||||
return rdev_mmap_full(&prog->rdev);
|
return asset_mmap(&prog->asset);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void *prog_entry(const struct prog *prog)
|
static inline void *prog_entry(const struct prog *prog)
|
||||||
|
@ -86,7 +95,7 @@ extern const struct mem_region_device addrspace_32bit;
|
||||||
static inline void prog_memory_init(struct prog *prog, uintptr_t ptr,
|
static inline void prog_memory_init(struct prog *prog, uintptr_t ptr,
|
||||||
size_t size)
|
size_t size)
|
||||||
{
|
{
|
||||||
rdev_chain(&prog->rdev, &addrspace_32bit.rdev, ptr, size);
|
rdev_chain(&prog->asset.rdev, &addrspace_32bit.rdev, ptr, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void prog_set_area(struct prog *prog, void *start, size_t size)
|
static inline void prog_set_area(struct prog *prog, void *start, size_t size)
|
||||||
|
@ -101,7 +110,11 @@ static inline void prog_set_entry(struct prog *prog, void *e, void *arg)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Locate the identified program to run. Return 0 on success. < 0 on error. */
|
/* Locate the identified program to run. Return 0 on success. < 0 on error. */
|
||||||
int prog_locate(struct prog *prog);
|
static inline int prog_locate(struct prog *prog)
|
||||||
|
{
|
||||||
|
return asset_locate(&prog->asset);
|
||||||
|
}
|
||||||
|
|
||||||
/* Run the program described by prog. */
|
/* Run the program described by prog. */
|
||||||
void prog_run(struct prog *prog);
|
void prog_run(struct prog *prog);
|
||||||
/* Per architecture implementation running a program. */
|
/* Per architecture implementation running a program. */
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#
|
#
|
||||||
subdirs-y += loaders
|
subdirs-y += loaders
|
||||||
|
|
||||||
|
bootblock-y += assets.c
|
||||||
bootblock-y += prog_loaders.c
|
bootblock-y += prog_loaders.c
|
||||||
bootblock-y += prog_ops.c
|
bootblock-y += prog_ops.c
|
||||||
bootblock-y += cbfs.c
|
bootblock-y += cbfs.c
|
||||||
|
@ -36,6 +37,7 @@ bootblock-y += region.c
|
||||||
bootblock-y += boot_device.c
|
bootblock-y += boot_device.c
|
||||||
bootblock-y += fmap.c
|
bootblock-y += fmap.c
|
||||||
|
|
||||||
|
verstage-y += assets.c
|
||||||
verstage-y += prog_loaders.c
|
verstage-y += prog_loaders.c
|
||||||
verstage-y += prog_ops.c
|
verstage-y += prog_ops.c
|
||||||
verstage-y += delay.c
|
verstage-y += delay.c
|
||||||
|
@ -60,6 +62,7 @@ verstage-$(CONFIG_GENERIC_UDELAY) += timer.c
|
||||||
verstage-$(CONFIG_GENERIC_GPIO_LIB) += gpio.c
|
verstage-$(CONFIG_GENERIC_GPIO_LIB) += gpio.c
|
||||||
verstage-y += mem_pool.c
|
verstage-y += mem_pool.c
|
||||||
|
|
||||||
|
romstage-y += assets.c
|
||||||
romstage-y += prog_loaders.c
|
romstage-y += prog_loaders.c
|
||||||
romstage-y += prog_ops.c
|
romstage-y += prog_ops.c
|
||||||
romstage-y += memchr.c
|
romstage-y += memchr.c
|
||||||
|
@ -92,6 +95,7 @@ endif
|
||||||
|
|
||||||
romstage-$(CONFIG_GENERIC_UDELAY) += timer.c
|
romstage-$(CONFIG_GENERIC_UDELAY) += timer.c
|
||||||
|
|
||||||
|
ramstage-y += assets.c
|
||||||
ramstage-y += prog_loaders.c
|
ramstage-y += prog_loaders.c
|
||||||
ramstage-y += prog_ops.c
|
ramstage-y += prog_ops.c
|
||||||
ramstage-y += hardwaremain.c
|
ramstage-y += hardwaremain.c
|
||||||
|
|
|
@ -0,0 +1,93 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the coreboot project.
|
||||||
|
*
|
||||||
|
* Copyright 2015 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <assets.h>
|
||||||
|
#include <boot_device.h>
|
||||||
|
#include <cbfs.h>
|
||||||
|
#include <console/console.h>
|
||||||
|
#include <rules.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#define DEFAULT_CBFS_PROVIDER_PRESENT \
|
||||||
|
(!ENV_VERSTAGE || (ENV_VERSTAGE && !CONFIG_RETURN_FROM_VERSTAGE))
|
||||||
|
|
||||||
|
#if DEFAULT_CBFS_PROVIDER_PRESENT
|
||||||
|
static int cbfs_boot_asset_locate(struct asset *asset)
|
||||||
|
{
|
||||||
|
return cbfs_boot_locate(&asset->rdev, asset->name, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct asset_provider cbfs_default_provider = {
|
||||||
|
.name = "CBFS",
|
||||||
|
.locate = cbfs_boot_asset_locate,
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern const struct asset_provider vboot_provider;
|
||||||
|
|
||||||
|
static const struct asset_provider *providers[] = {
|
||||||
|
#if CONFIG_VBOOT_VERIFY_FIRMWARE
|
||||||
|
&vboot_provider,
|
||||||
|
#endif
|
||||||
|
#if DEFAULT_CBFS_PROVIDER_PRESENT
|
||||||
|
&cbfs_default_provider,
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
int asset_locate(struct asset *asset)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
boot_device_init();
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_SIZE(providers); i++) {
|
||||||
|
/* Default provider state is active. */
|
||||||
|
int ret = 1;
|
||||||
|
const struct asset_provider *ops;
|
||||||
|
|
||||||
|
ops = providers[i];
|
||||||
|
|
||||||
|
if (ops->is_active != NULL)
|
||||||
|
ret = ops->is_active(asset);
|
||||||
|
|
||||||
|
if (ret == 0) {
|
||||||
|
printk(BIOS_DEBUG, "%s provider inactive.\n",
|
||||||
|
ops->name);
|
||||||
|
continue;
|
||||||
|
} else if (ret < 0) {
|
||||||
|
printk(BIOS_DEBUG, "%s provider failure.\n",
|
||||||
|
ops->name);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
printk(BIOS_DEBUG, "%s provider active.\n", ops->name);
|
||||||
|
|
||||||
|
if (ops->locate(asset))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
printk(BIOS_DEBUG, "'%s' located at offset: %zx size: %zx\n",
|
||||||
|
asset->name, region_device_offset(&asset->rdev),
|
||||||
|
region_device_sz(&asset->rdev));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
|
@ -188,12 +188,10 @@ void *cbfs_boot_map_optionrom(uint16_t vendor, uint16_t device)
|
||||||
|
|
||||||
void *cbfs_boot_load_stage_by_name(const char *name)
|
void *cbfs_boot_load_stage_by_name(const char *name)
|
||||||
{
|
{
|
||||||
struct prog stage = {
|
struct prog stage = PROG_INIT(ASSET_UNKNOWN, name);
|
||||||
.name = name,
|
|
||||||
};
|
|
||||||
uint32_t type = CBFS_TYPE_STAGE;
|
uint32_t type = CBFS_TYPE_STAGE;
|
||||||
|
|
||||||
if (cbfs_boot_locate(&stage.rdev, name, &type))
|
if (cbfs_boot_locate(&stage.asset.rdev, name, &type))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (cbfs_prog_stage_load(&stage))
|
if (cbfs_prog_stage_load(&stage))
|
||||||
|
@ -209,7 +207,7 @@ int cbfs_prog_stage_load(struct prog *pstage)
|
||||||
void *entry;
|
void *entry;
|
||||||
size_t fsize;
|
size_t fsize;
|
||||||
size_t foffset;
|
size_t foffset;
|
||||||
const struct region_device *fh = &pstage->rdev;
|
const struct region_device *fh = &pstage->asset.rdev;
|
||||||
|
|
||||||
if (rdev_readat(fh, &stage, 0, sizeof(stage)) != sizeof(stage))
|
if (rdev_readat(fh, &stage, 0, sizeof(stage)) != sizeof(stage))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -20,7 +20,6 @@
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <arch/stages.h>
|
#include <arch/stages.h>
|
||||||
#include <boot_device.h>
|
|
||||||
#include <cbfs.h>
|
#include <cbfs.h>
|
||||||
#include <cbmem.h>
|
#include <cbmem.h>
|
||||||
#include <console/console.h>
|
#include <console/console.h>
|
||||||
|
@ -38,83 +37,10 @@
|
||||||
/* Only can represent up to 1 byte less than size_t. */
|
/* Only can represent up to 1 byte less than size_t. */
|
||||||
const struct mem_region_device addrspace_32bit = MEM_REGION_DEV_INIT(0, ~0UL);
|
const struct mem_region_device addrspace_32bit = MEM_REGION_DEV_INIT(0, ~0UL);
|
||||||
|
|
||||||
#define DEFAULT_CBFS_LOADER_PRESENT \
|
|
||||||
(!ENV_VERSTAGE || (ENV_VERSTAGE && !CONFIG_RETURN_FROM_VERSTAGE))
|
|
||||||
|
|
||||||
#if DEFAULT_CBFS_LOADER_PRESENT
|
|
||||||
static int cbfs_boot_prog_locate(struct prog *prog)
|
|
||||||
{
|
|
||||||
return cbfs_boot_locate(&prog->rdev, prog->name, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct prog_loader_ops cbfs_default_loader = {
|
|
||||||
.locate = cbfs_boot_prog_locate,
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extern const struct prog_loader_ops vboot_loader;
|
|
||||||
|
|
||||||
static const struct prog_loader_ops *loaders[] = {
|
|
||||||
#if CONFIG_VBOOT_VERIFY_FIRMWARE
|
|
||||||
&vboot_loader,
|
|
||||||
#endif
|
|
||||||
#if DEFAULT_CBFS_LOADER_PRESENT
|
|
||||||
&cbfs_default_loader,
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
int prog_locate(struct prog *prog)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
boot_device_init();
|
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(loaders); i++) {
|
|
||||||
/* Default loader state is active. */
|
|
||||||
int ret = 1;
|
|
||||||
const struct prog_loader_ops *ops;
|
|
||||||
|
|
||||||
ops = loaders[i];
|
|
||||||
|
|
||||||
if (ops->is_loader_active != NULL)
|
|
||||||
ret = ops->is_loader_active(prog);
|
|
||||||
|
|
||||||
if (ret == 0) {
|
|
||||||
printk(BIOS_DEBUG, "%s loader inactive.\n",
|
|
||||||
ops->name);
|
|
||||||
continue;
|
|
||||||
} else if (ret < 0) {
|
|
||||||
printk(BIOS_DEBUG, "%s loader failure.\n",
|
|
||||||
ops->name);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
printk(BIOS_DEBUG, "%s loader active.\n", ops->name);
|
|
||||||
|
|
||||||
if (ops->locate(prog))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
printk(BIOS_DEBUG, "'%s' located at offset: %zx size: %zx\n",
|
|
||||||
prog->name, region_device_offset(&prog->rdev),
|
|
||||||
region_device_sz(&prog->rdev));
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void run_romstage(void)
|
void run_romstage(void)
|
||||||
{
|
{
|
||||||
struct prog romstage = {
|
struct prog romstage =
|
||||||
.name = CONFIG_CBFS_PREFIX "/romstage",
|
PROG_INIT(ASSET_ROMSTAGE, CONFIG_CBFS_PREFIX "/romstage");
|
||||||
.type = PROG_ROMSTAGE,
|
|
||||||
};
|
|
||||||
|
|
||||||
/* The only time the default CBFS loader isn't present is during
|
|
||||||
* VERSTAGE in which it returns back to the calling stage. */
|
|
||||||
if (!DEFAULT_CBFS_LOADER_PRESENT)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (prog_locate(&romstage))
|
if (prog_locate(&romstage))
|
||||||
goto fail;
|
goto fail;
|
||||||
|
@ -166,10 +92,8 @@ static int load_relocatable_ramstage(struct prog *ramstage)
|
||||||
|
|
||||||
void run_ramstage(void)
|
void run_ramstage(void)
|
||||||
{
|
{
|
||||||
struct prog ramstage = {
|
struct prog ramstage =
|
||||||
.name = CONFIG_CBFS_PREFIX "/ramstage",
|
PROG_INIT(ASSET_RAMSTAGE, CONFIG_CBFS_PREFIX "/ramstage");
|
||||||
.type = PROG_RAMSTAGE,
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Only x86 systems currently take the same firmware path on resume. */
|
/* Only x86 systems currently take the same firmware path on resume. */
|
||||||
if (IS_ENABLED(CONFIG_ARCH_X86) && IS_ENABLED(CONFIG_EARLY_CBMEM_INIT))
|
if (IS_ENABLED(CONFIG_ARCH_X86) && IS_ENABLED(CONFIG_EARLY_CBMEM_INIT))
|
||||||
|
@ -197,10 +121,8 @@ fail:
|
||||||
die("Ramstage was not loaded!\n");
|
die("Ramstage was not loaded!\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct prog global_payload = {
|
static struct prog global_payload =
|
||||||
.name = CONFIG_CBFS_PREFIX "/payload",
|
PROG_INIT(ASSET_PAYLOAD, CONFIG_CBFS_PREFIX "/payload");
|
||||||
.type = PROG_PAYLOAD,
|
|
||||||
};
|
|
||||||
|
|
||||||
void __attribute__((weak)) mirror_payload(struct prog *payload)
|
void __attribute__((weak)) mirror_payload(struct prog *payload)
|
||||||
{
|
{
|
||||||
|
|
|
@ -264,10 +264,10 @@ int rmodule_stage_load(struct rmod_stage_load *rsl)
|
||||||
void *rmod_loc;
|
void *rmod_loc;
|
||||||
struct region_device *fh;
|
struct region_device *fh;
|
||||||
|
|
||||||
if (rsl->prog == NULL || rsl->prog->name == NULL)
|
if (rsl->prog == NULL || prog_name(rsl->prog) == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
fh = &rsl->prog->rdev;
|
fh = prog_rdev(rsl->prog);
|
||||||
|
|
||||||
if (rdev_readat(fh, &stage, 0, sizeof(stage)) != sizeof(stage))
|
if (rdev_readat(fh, &stage, 0, sizeof(stage)) != sizeof(stage))
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -284,7 +284,7 @@ int rmodule_stage_load(struct rmod_stage_load *rsl)
|
||||||
rmod_loc = &stage_region[rmodule_offset];
|
rmod_loc = &stage_region[rmodule_offset];
|
||||||
|
|
||||||
printk(BIOS_INFO, "Decompressing stage %s @ 0x%p (%d bytes)\n",
|
printk(BIOS_INFO, "Decompressing stage %s @ 0x%p (%d bytes)\n",
|
||||||
rsl->prog->name, rmod_loc, stage.memlen);
|
prog_name(rsl->prog), rmod_loc, stage.memlen);
|
||||||
|
|
||||||
if (stage.compression == CBFS_COMPRESS_NONE) {
|
if (stage.compression == CBFS_COMPRESS_NONE) {
|
||||||
if (rdev_readat(fh, rmod_loc, sizeof(stage), stage.len) !=
|
if (rdev_readat(fh, rmod_loc, sizeof(stage), stage.len) !=
|
||||||
|
|
|
@ -454,7 +454,7 @@ void *selfload(struct prog *payload)
|
||||||
struct segment head;
|
struct segment head;
|
||||||
void *data;
|
void *data;
|
||||||
|
|
||||||
data = rdev_mmap_full(&payload->rdev);
|
data = rdev_mmap_full(prog_rdev(payload));
|
||||||
|
|
||||||
if (data == NULL)
|
if (data == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -469,7 +469,10 @@ void *selfload(struct prog *payload)
|
||||||
|
|
||||||
printk(BIOS_SPEW, "Loaded segments\n");
|
printk(BIOS_SPEW, "Loaded segments\n");
|
||||||
|
|
||||||
rdev_munmap(&payload->rdev, data);
|
rdev_munmap(prog_rdev(payload), data);
|
||||||
|
|
||||||
|
/* Update the payload's area with the bounce buffer information. */
|
||||||
|
prog_set_area(payload, (void *)(uintptr_t)bounce_buffer, bounce_size);
|
||||||
|
|
||||||
/* Update the payload's area with the bounce buffer information. */
|
/* Update the payload's area with the bounce buffer information. */
|
||||||
prog_set_area(payload, (void *)(uintptr_t)bounce_buffer, bounce_size);
|
prog_set_area(payload, (void *)(uintptr_t)bounce_buffer, bounce_size);
|
||||||
|
@ -477,6 +480,6 @@ void *selfload(struct prog *payload)
|
||||||
return (void *)entry;
|
return (void *)entry;
|
||||||
|
|
||||||
out:
|
out:
|
||||||
rdev_munmap(&payload->rdev, data);
|
rdev_munmap(prog_rdev(payload), data);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,10 +48,8 @@ static efi_wrapper_entry_t load_refcode_from_cache(void)
|
||||||
|
|
||||||
static efi_wrapper_entry_t load_reference_code(void)
|
static efi_wrapper_entry_t load_reference_code(void)
|
||||||
{
|
{
|
||||||
struct prog prog = {
|
struct prog prog =
|
||||||
.type = PROG_REFCODE,
|
PROG_INIT(ASSET_REFCODE, CONFIG_CBFS_PREFIX "/refcode");
|
||||||
.name = CONFIG_CBFS_PREFIX "/refcode",
|
|
||||||
};
|
|
||||||
struct rmod_stage_load refcode = {
|
struct rmod_stage_load refcode = {
|
||||||
.cbmem_id = CBMEM_ID_REFCODE,
|
.cbmem_id = CBMEM_ID_REFCODE,
|
||||||
.prog = &prog,
|
.prog = &prog,
|
||||||
|
|
|
@ -45,10 +45,8 @@ static pei_wrapper_entry_t load_refcode_from_cache(void)
|
||||||
|
|
||||||
static efi_wrapper_entry_t load_reference_code(void)
|
static efi_wrapper_entry_t load_reference_code(void)
|
||||||
{
|
{
|
||||||
struct prog prog = {
|
struct prog prog =
|
||||||
.type = PROG_REFCODE,
|
PROG_INIT(ASSET_REFCODE, CONFIG_CBFS_PREFIX "/refcode");
|
||||||
.name = CONFIG_CBFS_PREFIX "/refcode",
|
|
||||||
};
|
|
||||||
struct rmod_stage_load refcode = {
|
struct rmod_stage_load refcode = {
|
||||||
.cbmem_id = CBMEM_ID_REFCODE,
|
.cbmem_id = CBMEM_ID_REFCODE,
|
||||||
.prog = &prog,
|
.prog = &prog,
|
||||||
|
|
|
@ -17,10 +17,10 @@
|
||||||
* Foundation, Inc.
|
* Foundation, Inc.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <assets.h>
|
||||||
#include <cbfs.h>
|
#include <cbfs.h>
|
||||||
#include <cbmem.h>
|
#include <cbmem.h>
|
||||||
#include <console/console.h>
|
#include <console/console.h>
|
||||||
#include <program_loading.h>
|
|
||||||
#include <rmodule.h>
|
#include <rmodule.h>
|
||||||
#include <rules.h>
|
#include <rules.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
@ -79,7 +79,7 @@ static void init_vb2_working_data(void)
|
||||||
wd->buffer_size = work_size - wd->buffer_offset;
|
wd->buffer_size = work_size - wd->buffer_offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int vboot_loader_active(struct prog *prog)
|
static int vboot_active(struct asset *asset)
|
||||||
{
|
{
|
||||||
struct vb2_working_data *wd;
|
struct vb2_working_data *wd;
|
||||||
int run_verification;
|
int run_verification;
|
||||||
|
@ -90,15 +90,15 @@ static int vboot_loader_active(struct prog *prog)
|
||||||
init_vb2_working_data();
|
init_vb2_working_data();
|
||||||
verstage_main();
|
verstage_main();
|
||||||
} else if (verstage_should_load()) {
|
} else if (verstage_should_load()) {
|
||||||
struct prog verstage = {
|
struct prog verstage =
|
||||||
.type = PROG_VERSTAGE,
|
PROG_INIT(ASSET_VERSTAGE,
|
||||||
.name = CONFIG_CBFS_PREFIX "/verstage",
|
CONFIG_CBFS_PREFIX "/verstage");
|
||||||
};
|
|
||||||
|
|
||||||
printk(BIOS_DEBUG, "VBOOT: Loading verstage.\n");
|
printk(BIOS_DEBUG, "VBOOT: Loading verstage.\n");
|
||||||
|
|
||||||
/* load verstage from RO */
|
/* load verstage from RO */
|
||||||
if (cbfs_boot_locate(&verstage.rdev, verstage.name, NULL) ||
|
if (cbfs_boot_locate(prog_rdev(&verstage),
|
||||||
|
prog_name(&verstage), NULL) ||
|
||||||
cbfs_prog_stage_load(&verstage))
|
cbfs_prog_stage_load(&verstage))
|
||||||
die("failed to load verstage");
|
die("failed to load verstage");
|
||||||
|
|
||||||
|
@ -126,24 +126,24 @@ static int vboot_loader_active(struct prog *prog)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int vboot_locate_by_components(const struct region_device *fw_main,
|
static int vboot_locate_by_components(const struct region_device *fw_main,
|
||||||
struct prog *prog)
|
struct asset *asset)
|
||||||
{
|
{
|
||||||
struct vboot_components *fw_info;
|
struct vboot_components *fw_info;
|
||||||
size_t metadata_sz;
|
size_t metadata_sz;
|
||||||
size_t offset;
|
size_t offset;
|
||||||
size_t size;
|
size_t size;
|
||||||
struct region_device *fw = &prog->rdev;
|
struct region_device *fw = asset_rdev(asset);
|
||||||
int fw_index = 0;
|
int fw_index = 0;
|
||||||
|
|
||||||
if (prog->type == PROG_ROMSTAGE)
|
if (asset_type(asset) == ASSET_ROMSTAGE)
|
||||||
fw_index = CONFIG_VBOOT_ROMSTAGE_INDEX;
|
fw_index = CONFIG_VBOOT_ROMSTAGE_INDEX;
|
||||||
else if (prog->type == PROG_RAMSTAGE)
|
else if (asset_type(asset) == ASSET_RAMSTAGE)
|
||||||
fw_index = CONFIG_VBOOT_RAMSTAGE_INDEX;
|
fw_index = CONFIG_VBOOT_RAMSTAGE_INDEX;
|
||||||
else if (prog->type == PROG_PAYLOAD)
|
else if (asset_type(asset) == ASSET_PAYLOAD)
|
||||||
fw_index = CONFIG_VBOOT_BOOT_LOADER_INDEX;
|
fw_index = CONFIG_VBOOT_BOOT_LOADER_INDEX;
|
||||||
else if (prog->type == PROG_REFCODE)
|
else if (asset_type(asset) == ASSET_REFCODE)
|
||||||
fw_index = CONFIG_VBOOT_REFCODE_INDEX;
|
fw_index = CONFIG_VBOOT_REFCODE_INDEX;
|
||||||
else if (prog->type == PROG_BL31)
|
else if (asset_type(asset) == ASSET_BL31)
|
||||||
fw_index = CONFIG_VBOOT_BL31_INDEX;
|
fw_index = CONFIG_VBOOT_BL31_INDEX;
|
||||||
else
|
else
|
||||||
die("Invalid program type for vboot.");
|
die("Invalid program type for vboot.");
|
||||||
|
@ -177,7 +177,7 @@ static int vboot_locate_by_components(const struct region_device *fw_main,
|
||||||
}
|
}
|
||||||
|
|
||||||
static int vboot_locate_by_multi_cbfs(const struct region_device *fw_main,
|
static int vboot_locate_by_multi_cbfs(const struct region_device *fw_main,
|
||||||
struct prog *prog)
|
struct asset *asset)
|
||||||
{
|
{
|
||||||
struct cbfsd cbfs;
|
struct cbfsd cbfs;
|
||||||
struct region_device rdev;
|
struct region_device rdev;
|
||||||
|
@ -192,21 +192,21 @@ static int vboot_locate_by_multi_cbfs(const struct region_device *fw_main,
|
||||||
cbfs.rdev = &rdev;
|
cbfs.rdev = &rdev;
|
||||||
cbfs.align = props.align;
|
cbfs.align = props.align;
|
||||||
|
|
||||||
return cbfs_locate(&prog->rdev, &cbfs, prog->name, NULL);
|
return cbfs_locate(asset_rdev(asset), &cbfs, asset_name(asset), NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int vboot_prog_locate(const struct region_device *fw_main,
|
static int vboot_asset_locate(const struct region_device *fw_main,
|
||||||
struct prog *prog)
|
struct asset *asset)
|
||||||
{
|
{
|
||||||
if (IS_ENABLED(CONFIG_MULTIPLE_CBFS_INSTANCES))
|
if (IS_ENABLED(CONFIG_MULTIPLE_CBFS_INSTANCES))
|
||||||
return vboot_locate_by_multi_cbfs(fw_main, prog);
|
return vboot_locate_by_multi_cbfs(fw_main, asset);
|
||||||
else
|
else
|
||||||
return vboot_locate_by_components(fw_main, prog);
|
return vboot_locate_by_components(fw_main, asset);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This function is only called when vboot_loader_active() returns 1. That
|
/* This function is only called when vboot_active() returns 1. That
|
||||||
* means we are taking vboot paths. */
|
* means we are taking vboot paths. */
|
||||||
static int vboot_locate(struct prog *prog)
|
static int vboot_locate(struct asset *asset)
|
||||||
{
|
{
|
||||||
struct vb2_working_data *wd;
|
struct vb2_working_data *wd;
|
||||||
struct region_device fw_main;
|
struct region_device fw_main;
|
||||||
|
@ -221,11 +221,11 @@ static int vboot_locate(struct prog *prog)
|
||||||
if (vb2_get_selected_region(wd, &fw_main))
|
if (vb2_get_selected_region(wd, &fw_main))
|
||||||
die("failed to reference selected region\n");
|
die("failed to reference selected region\n");
|
||||||
|
|
||||||
return vboot_prog_locate(&fw_main, prog);
|
return vboot_asset_locate(&fw_main, asset);
|
||||||
}
|
}
|
||||||
|
|
||||||
const struct prog_loader_ops vboot_loader = {
|
const struct asset_provider vboot_provider = {
|
||||||
.name = "VBOOT",
|
.name = "VBOOT",
|
||||||
.is_loader_active = vboot_loader_active,
|
.is_active = vboot_active,
|
||||||
.locate = vboot_locate,
|
.locate = vboot_locate,
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue