Aaron Durbin (adurbin(a)google.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/5299
-gerrit
commit 27deff64db1f803bee4f069539329924f132c987
Author: Aaron Durbin <adurbin(a)chromium.org>
Date: Mon Feb 24 22:11:45 2014 -0600
selfboot: store bounce buffer in struct payload
In order to break the dependency on selfboot for jumping to
payload the bounce buffer location needs to be communicated.
Therefore, add the bounce buffer to struct payload.
Change-Id: I9d9396e5c5bfba7a63940227ee0bdce6cba39578
Signed-off-by: Aaron Durbin <adurbin(a)chromium.org>
---
src/include/payload_loader.h | 6 ++++--
src/lib/selfboot.c | 26 +++++++++++++++-----------
2 files changed, 19 insertions(+), 13 deletions(-)
diff --git a/src/include/payload_loader.h b/src/include/payload_loader.h
index 1dc06c7..0c526c2 100644
--- a/src/include/payload_loader.h
+++ b/src/include/payload_loader.h
@@ -22,14 +22,16 @@
#include <stdint.h>
#include <stddef.h>
-struct payload_backing_store {
+struct buffer_area {
void *data;
size_t size;
};
struct payload {
const char *name;
- struct payload_backing_store backing_store;
+ struct buffer_area backing_store;
+ /* Used when payload wants memory coreboot ramstage is running at. */
+ struct buffer_area bounce;
void *entry;
};
diff --git a/src/lib/selfboot.c b/src/lib/selfboot.c
index bd1206f..ba07480 100644
--- a/src/lib/selfboot.c
+++ b/src/lib/selfboot.c
@@ -74,22 +74,22 @@ struct segment {
static unsigned long bounce_size, bounce_buffer;
-#if CONFIG_RELOCATABLE_RAMSTAGE
-static void get_bounce_buffer(struct lb_memory *mem, unsigned long req_size)
-{
- /* When the ramstage is relocatable there is no need for a bounce
- * buffer. All payloads should not overlap the ramstage.
- */
- bounce_buffer = ~0UL;
- bounce_size = 0;
-}
-#else
static void get_bounce_buffer(struct lb_memory *mem, unsigned long req_size)
{
unsigned long lb_size;
unsigned long mem_entries;
unsigned long buffer;
int i;
+
+ /* When the ramstage is relocatable there is no need for a bounce
+ * buffer. All payloads should not overlap the ramstage.
+ */
+ if (IS_ENABLED(CONFIG_RELOCATABLE_RAMSTAGE)) {
+ bounce_buffer = ~0UL;
+ bounce_size = 0;
+ return;
+ }
+
lb_size = lb_end - lb_start;
/* Plus coreboot size so I have somewhere
* to place a copy to return to.
@@ -120,7 +120,6 @@ static void get_bounce_buffer(struct lb_memory *mem, unsigned long req_size)
bounce_buffer = buffer;
bounce_size = req_size;
}
-#endif /* CONFIG_RELOCATABLE_RAMSTAGE */
static int valid_area(struct lb_memory *mem, unsigned long buffer,
unsigned long start, unsigned long len)
@@ -417,6 +416,11 @@ static int load_self_segments(
printk(BIOS_ERR, "Could not find a bounce buffer...\n");
return 0;
}
+
+ /* Update the payload's bounce buffer data used when loading. */
+ payload->bounce.data = (void *)(uintptr_t)bounce_buffer;
+ payload->bounce.size = bounce_size;
+
for(ptr = head->next; ptr != head; ptr = ptr->next) {
/* Verify the memory addresses in the segment are valid */
if (!valid_area(mem, bounce_buffer, ptr->s_dstaddr, ptr->s_memsz))
Aaron Durbin (adurbin(a)google.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/5297
-gerrit
commit c1e7d8920d04001191192af6cc15c2e36c81d7d3
Author: Aaron Durbin <adurbin(a)chromium.org>
Date: Mon Feb 24 21:24:28 2014 -0600
coreboot: move common code to payload_run() from selfboot()
The selfboot() routine was perfoming most of the common teardown
and stack checking infrastructure. Move that code into
payload_run() to prepare removal of the selfboot() function.
Change-Id: I29f2a5cfcc692f7a0fe2656cb1cda18158c49c6e
Signed-off-by: Aaron Durbin <adurbin(a)chromium.org>
---
src/lib/loaders/load_and_run_payload.c | 16 ++++++++++++++++
src/lib/selfboot.c | 19 -------------------
2 files changed, 16 insertions(+), 19 deletions(-)
diff --git a/src/lib/loaders/load_and_run_payload.c b/src/lib/loaders/load_and_run_payload.c
index dba5898..8be4e3c 100644
--- a/src/lib/loaders/load_and_run_payload.c
+++ b/src/lib/loaders/load_and_run_payload.c
@@ -21,7 +21,10 @@
#include <stdlib.h>
#include <console/console.h>
#include <boot/coreboot_tables.h>
+#include <fallback.h>
+#include <lib.h>
#include <payload_loader.h>
+#include <timestamp.h>
extern const struct payload_loader_ops vboot_payload_loader;
extern const struct payload_loader_ops cbfs_payload_loader;
@@ -77,5 +80,18 @@ void payload_run(const struct payload *payload)
if (payload == NULL)
return;
+ /* Reset to booting from this image as late as possible */
+ boot_successful();
+
+ printk(BIOS_DEBUG, "Jumping to boot code at %p\n", payload->entry);
+ post_code(POST_ENTER_ELF_BOOT);
+
+ timestamp_add_now(TS_SELFBOOT_JUMP);
+
+ /* Before we go off to run the payload, see if
+ * we stayed within our bounds.
+ */
+ checkstack(_estack, 0);
+
selfboot(payload->entry);
}
diff --git a/src/lib/selfboot.c b/src/lib/selfboot.c
index c0986d1..6f200fa 100644
--- a/src/lib/selfboot.c
+++ b/src/lib/selfboot.c
@@ -22,16 +22,12 @@
#include <arch/stages.h>
#include <console/console.h>
#include <cpu/cpu.h>
-#include <fallback.h>
#include <boot/coreboot_tables.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <cbfs.h>
#include <lib.h>
-#if CONFIG_COLLECT_TIMESTAMPS
-#include <timestamp.h>
-#endif
#include <payload_loader.h>
/* Maximum physical address we can use for the coreboot bounce buffer. */
@@ -527,21 +523,6 @@ out:
void selfboot(void *entry)
{
- /* Reset to booting from this image as late as possible */
- boot_successful();
-
- printk(BIOS_DEBUG, "Jumping to boot code at %p\n", entry);
- post_code(POST_ENTER_ELF_BOOT);
-
-#if CONFIG_COLLECT_TIMESTAMPS
- timestamp_add_now(TS_SELFBOOT_JUMP);
-#endif
-
- /* Before we go off to run the payload, see if
- * we stayed within our bounds.
- */
- checkstack(_estack, 0);
-
/* Jump to kernel */
jmp_to_elf_entry(entry, bounce_buffer, bounce_size);
}
Aaron Durbin (adurbin(a)google.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/5296
-gerrit
commit 2464f16875c60a408e0052a11707fccabe45b074
Author: Aaron Durbin <adurbin(a)chromium.org>
Date: Mon Feb 24 14:56:34 2014 -0600
coreboot: infrastructure for loading payloads
A payload can be loaded either from a vboot region or from cbfs.
Provide a common place for choosing where the payload is loaded
from. Additionally, place the logic in the 'loaders' directory
similarly to the ramstage loader infrastructure.
Change-Id: I6b0034ea5ebd04a3d058151819ac77a126a6bfe2
Signed-off-by: Aaron Durbin <adurbin(a)chromium.org>
---
src/include/cbfs.h | 6 ---
src/include/payload_loader.h | 61 +++++++++++++++++++++++
src/lib/cbfs.c | 19 --------
src/lib/hardwaremain.c | 22 ++++-----
src/lib/loaders/Makefile.inc | 2 +
src/lib/loaders/cbfs_payload_loader.c | 45 +++++++++++++++++
src/lib/loaders/load_and_run_payload.c | 81 +++++++++++++++++++++++++++++++
src/lib/selfboot.c | 1 +
src/vendorcode/google/chromeos/chromeos.c | 25 +++++++++-
src/vendorcode/google/chromeos/chromeos.h | 1 -
10 files changed, 223 insertions(+), 40 deletions(-)
diff --git a/src/include/cbfs.h b/src/include/cbfs.h
index 9ce862b..ebdbf43 100644
--- a/src/include/cbfs.h
+++ b/src/include/cbfs.h
@@ -54,7 +54,6 @@
void *cbfs_load_optionrom(struct cbfs_media *media, uint16_t vendor,
uint16_t device, void * dest);
-void *cbfs_load_payload(struct cbfs_media *media, const char *name);
void *cbfs_load_stage(struct cbfs_media *media, const char *name);
/* Simple buffer for streaming media. */
@@ -75,11 +74,6 @@ void *cbfs_simple_buffer_unmap(struct cbfs_simple_buffer *buffer,
// Utility functions
int run_address(void *f);
-/* Defined in src/lib/selfboot.c */
-struct lb_memory;
-void *selfload(struct lb_memory *mem, struct cbfs_payload *payload);
-void selfboot(void *entry);
-
/* Defined in individual arch / board implementation. */
int init_default_cbfs_media(struct cbfs_media *media);
diff --git a/src/include/payload_loader.h b/src/include/payload_loader.h
new file mode 100644
index 0000000..27b62d3
--- /dev/null
+++ b/src/include/payload_loader.h
@@ -0,0 +1,61 @@
+/*
+ * 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 PAYLOAD_LOADER_H
+#define PAYLOAD_LOADER_H
+
+#include <stdint.h>
+#include <stddef.h>
+
+struct payload_backing_store {
+ void *data;
+ size_t size;
+};
+
+struct payload {
+ const char *name;
+ struct payload_backing_store backing_store;
+ void *entry;
+};
+
+/*
+ * Load payload into memory and return pointer to payload structure. Returns
+ * NULL on error.
+ */
+struct payload *payload_load(void);
+
+/* Run the loaded payload. */
+void payload_run(const struct payload *payload);
+
+/* Payload loading operations. */
+struct payload_loader_ops {
+ const char *name;
+ /*
+ * Fill in payload_backing_store structure. Return 0 on success, < 0
+ * if failure.
+ */
+ int (*locate)(struct payload *payload);
+};
+
+/* Defined in src/lib/selfboot.c */
+struct lb_memory;
+struct cbfs_payload;
+void *selfload(struct lb_memory *mem, struct cbfs_payload *payload);
+void selfboot(void *entry);
+
+#endif /* PAYLOAD_LOADER_H */
diff --git a/src/lib/cbfs.c b/src/lib/cbfs.c
index 99eeac8..dc08937 100644
--- a/src/lib/cbfs.c
+++ b/src/lib/cbfs.c
@@ -65,12 +65,6 @@
#include "cbfs_core.c"
-#if CONFIG_VBOOT_VERIFY_FIRMWARE
-#include <vendorcode/google/chromeos/chromeos.h>
-#else
-static inline void *vboot_get_payload(int *len) { return NULL; }
-#endif
-
#ifndef __SMM__
static inline int tohex4(unsigned int c)
{
@@ -160,19 +154,6 @@ void * cbfs_load_stage(struct cbfs_media *media, const char *name)
return (void *) entry;
}
-void *cbfs_load_payload(struct cbfs_media *media, const char *name)
-{
- struct cbfs_payload *payload;
-
- payload = vboot_get_payload(NULL);
- if (payload != NULL)
- return payload;
-
- payload = (struct cbfs_payload *)cbfs_get_file_content(
- media, name, CBFS_TYPE_PAYLOAD, NULL);
- return payload;
-}
-
/* Simple buffer */
void *cbfs_simple_buffer_map(struct cbfs_simple_buffer *buffer,
diff --git a/src/lib/hardwaremain.c b/src/lib/hardwaremain.c
index fed153b..d90e0f6 100644
--- a/src/lib/hardwaremain.c
+++ b/src/lib/hardwaremain.c
@@ -32,7 +32,7 @@
#include <stdlib.h>
#include <reset.h>
#include <boot/tables.h>
-#include <cbfs.h>
+#include <payload_loader.h>
#include <lib.h>
#if CONFIG_HAVE_ACPI_RESUME
#include <arch/acpi.h>
@@ -226,30 +226,26 @@ static boot_state_t bs_write_tables(void *arg)
static boot_state_t bs_payload_load(void *arg)
{
- void *payload;
- void *entry;
+ struct payload *payload;
timestamp_add_now(TS_LOAD_PAYLOAD);
- payload = cbfs_load_payload(CBFS_DEFAULT_MEDIA,
- CONFIG_CBFS_PREFIX "/payload");
- if (! payload)
- die("Could not find a payload\n");
-
- entry = selfload(get_lb_mem(), payload);
+ payload = payload_load();
- if (! entry)
+ if (! payload)
die("Could not load payload\n");
/* Pass the payload to the next state. */
- boot_states[BS_PAYLOAD_BOOT].arg = entry;
+ boot_states[BS_PAYLOAD_BOOT].arg = payload;
return BS_PAYLOAD_BOOT;
}
-static boot_state_t bs_payload_boot(void *entry)
+static boot_state_t bs_payload_boot(void *arg)
{
- selfboot(entry);
+ struct payload *payload = arg;
+
+ payload_run(payload);
printk(BIOS_EMERG, "Boot failed");
/* Returning from this state will fail because the following signals
diff --git a/src/lib/loaders/Makefile.inc b/src/lib/loaders/Makefile.inc
index eceaa00..356e47e 100644
--- a/src/lib/loaders/Makefile.inc
+++ b/src/lib/loaders/Makefile.inc
@@ -19,3 +19,5 @@
romstage-y += cbfs_ramstage_loader.c
romstage-y += load_and_run_ramstage.c
+ramstage-y += cbfs_payload_loader.c
+ramstage-y += load_and_run_payload.c
diff --git a/src/lib/loaders/cbfs_payload_loader.c b/src/lib/loaders/cbfs_payload_loader.c
new file mode 100644
index 0000000..c115572
--- /dev/null
+++ b/src/lib/loaders/cbfs_payload_loader.c
@@ -0,0 +1,45 @@
+/*
+ * 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 <cbfs.h>
+#include <payload_loader.h>
+
+static int cbfs_locate_payload(struct payload *payload)
+{
+ void *buffer;
+ size_t size;
+ const int type = CBFS_TYPE_PAYLOAD;
+
+ buffer = cbfs_get_file_content(CBFS_DEFAULT_MEDIA, payload->name,
+ type, &size);
+
+ if (buffer == NULL)
+ return -1;
+
+ payload->backing_store.data = buffer;
+ payload->backing_store.size = size;
+
+ return 0;
+}
+
+const struct payload_loader_ops cbfs_payload_loader = {
+ .name = "CBFS",
+ .locate = cbfs_locate_payload,
+};
+
diff --git a/src/lib/loaders/load_and_run_payload.c b/src/lib/loaders/load_and_run_payload.c
new file mode 100644
index 0000000..dba5898
--- /dev/null
+++ b/src/lib/loaders/load_and_run_payload.c
@@ -0,0 +1,81 @@
+/*
+ * 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 <stdint.h>
+#include <stdlib.h>
+#include <console/console.h>
+#include <boot/coreboot_tables.h>
+#include <payload_loader.h>
+
+extern const struct payload_loader_ops vboot_payload_loader;
+extern const struct payload_loader_ops cbfs_payload_loader;
+
+static const struct payload_loader_ops *payload_ops[] = {
+#if CONFIG_VBOOT_VERIFY_FIRMWARE
+ &vboot_payload_loader,
+#endif
+ &cbfs_payload_loader,
+};
+
+static struct payload global_payload = {
+ .name = CONFIG_CBFS_PREFIX "/payload",
+};
+
+struct payload *payload_load(void)
+{
+ int i;
+ void *entry;
+ struct lb_mem *mem;
+ const struct payload_loader_ops *ops;
+ struct payload *payload = &global_payload;
+
+ for (i = 0; i < ARRAY_SIZE(payload_ops); i++) {
+ ops = payload_ops[i];
+ if (ops->locate(payload) < 0) {
+ printk(BIOS_DEBUG, "%s: could not locate payload.\n",
+ ops->name);
+ continue;
+ }
+ printk(BIOS_DEBUG, "%s: located payload @ %p, %zu bytes.\n",
+ ops->name, payload->backing_store.data,
+ payload->backing_store.size);
+ break;
+ }
+
+ if (i == ARRAY_SIZE(payload_ops))
+ return NULL;
+
+ mem = get_lb_mem();
+ entry = selfload(mem, payload->backing_store.data);
+
+ if (entry == NULL)
+ return NULL;
+
+ payload->entry = entry;
+
+ return payload;
+}
+
+void payload_run(const struct payload *payload)
+{
+ if (payload == NULL)
+ return;
+
+ selfboot(payload->entry);
+}
diff --git a/src/lib/selfboot.c b/src/lib/selfboot.c
index 222eae2..c0986d1 100644
--- a/src/lib/selfboot.c
+++ b/src/lib/selfboot.c
@@ -32,6 +32,7 @@
#if CONFIG_COLLECT_TIMESTAMPS
#include <timestamp.h>
#endif
+#include <payload_loader.h>
/* Maximum physical address we can use for the coreboot bounce buffer. */
#ifndef MAX_ADDR
diff --git a/src/vendorcode/google/chromeos/chromeos.c b/src/vendorcode/google/chromeos/chromeos.c
index 54fe8db..e917ba1 100644
--- a/src/vendorcode/google/chromeos/chromeos.c
+++ b/src/vendorcode/google/chromeos/chromeos.c
@@ -82,7 +82,9 @@ int recovery_mode_enabled(void)
}
#if CONFIG_VBOOT_VERIFY_FIRMWARE
-void *vboot_get_payload(size_t *len)
+#include <payload_loader.h>
+
+static void *vboot_get_payload(size_t *len)
{
struct vboot_handoff *vboot_handoff;
struct firmware_component *fwc;
@@ -109,6 +111,27 @@ void *vboot_get_payload(size_t *len)
return (void *)fwc->address;
}
+static int vboot_locate_payload(struct payload *payload)
+{
+ void *buffer;
+ size_t size;
+
+ buffer = vboot_get_payload(&size);
+
+ if (buffer == NULL)
+ return -1;
+
+ payload->backing_store.data = buffer;
+ payload->backing_store.size = size;
+
+ return 0;
+}
+
+const struct payload_loader_ops vboot_payload_loader = {
+ .name = "VBOOT",
+ .locate = vboot_locate_payload,
+};
+
int vboot_get_handoff_info(void **addr, uint32_t *size)
{
struct vboot_handoff *vboot_handoff;
diff --git a/src/vendorcode/google/chromeos/chromeos.h b/src/vendorcode/google/chromeos/chromeos.h
index 0359c91..7fe8f06 100644
--- a/src/vendorcode/google/chromeos/chromeos.h
+++ b/src/vendorcode/google/chromeos/chromeos.h
@@ -47,7 +47,6 @@ int recovery_mode_enabled(void);
void init_chromeos(int bootmode);
#if CONFIG_VBOOT_VERIFY_FIRMWARE
-void *vboot_get_payload(size_t *len);
/* Returns 0 on success < 0 on error. */
int vboot_get_handoff_info(void **addr, uint32_t *size);
#endif