[coreboot-gerrit] Patch set updated for coreboot: fe86a9a cbfs: move cbfs.c to cbfs_gpl.c

Aaron Durbin (adurbin@chromium.org) gerrit at coreboot.org
Wed Apr 15 00:27:17 CEST 2015


Aaron Durbin (adurbin at chromium.org) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/9127

-gerrit

commit fe86a9a9239478251cb6cd79f57668216550d25e
Author: Aaron Durbin <adurbin at chromium.org>
Date:   Thu Mar 26 21:17:17 2015 -0500

    cbfs: move cbfs.c to cbfs_gpl.c
    
    In order to prepare for a new cbfs API move cbfs.c to
    cbfs_gpl.c. That way replacement implementatoins can be
    dropped in with the intent of making code review easier.
    
    Change-Id: Ifb732261aabfe94545cdd5f673e9f1422ad46085
    Signed-off-by: Aaron Durbin <adurbin at chromium.org>
---
 src/include/cbfs.h              |  63 +-----------
 src/include/cbfs_declarations.h |  82 ++++++++++++++++
 src/lib/Makefile.inc            |  10 +-
 src/lib/cbfs.c                  | 209 ----------------------------------------
 src/lib/cbfs_gpl.c              | 209 ++++++++++++++++++++++++++++++++++++++++
 5 files changed, 299 insertions(+), 274 deletions(-)

diff --git a/src/include/cbfs.h b/src/include/cbfs.h
index 84fe251..315684e 100644
--- a/src/include/cbfs.h
+++ b/src/include/cbfs.h
@@ -1,14 +1,8 @@
 /*
  * This file is part of the coreboot project.
  *
- * Copyright (C) 2008 Jordan Crouse <jordan at cosmicpenguin.net>
- * Copyright (C) 2013-2015 Google, Inc.
+ * Copyright 2015 Google Inc.
  *
- * This file is dual-licensed. You can choose between:
- *   - The GNU GPL, version 2, as published by the Free Software Foundation
- *   - The revised BSD license (without advertising clause)
- *
- * ---------------------------------------------------------------------------
  * 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.
@@ -20,63 +14,12 @@
  *
  * 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
- * ---------------------------------------------------------------------------
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- *    derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ---------------------------------------------------------------------------
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
 #ifndef _CBFS_H_
 #define _CBFS_H_
 
-#include <cbfs_core.h>
-
-int init_backing_media(struct cbfs_media **media, struct cbfs_media *backing);
-void *cbfs_load_optionrom(struct cbfs_media *media, uint16_t vendor,
-			  uint16_t device, void * dest);
-void *cbfs_load_stage(struct cbfs_media *media, const char *name);
-void *cbfs_load_stage_by_offset(struct cbfs_media *media, ssize_t offset);
-/* Load a stage from a prog structure. Returns < 0 on error. 0 on success. */
-struct prog;
-int cbfs_load_prog_stage(struct cbfs_media *media, struct prog *prog);
-
-/* Simple buffer for streaming media. */
-struct cbfs_simple_buffer {
-	char *buffer;
-	size_t allocated;
-	size_t size;
-	size_t last_allocate;
-};
-
-void *cbfs_simple_buffer_map(struct cbfs_simple_buffer *buffer,
-			     struct cbfs_media *media,
-			     size_t offset, size_t count);
-
-void *cbfs_simple_buffer_unmap(struct cbfs_simple_buffer *buffer,
-			       const void *address);
-
-/* Defined in individual arch / board implementation. */
-int init_default_cbfs_media(struct cbfs_media *media);
+#include <cbfs_declarations.h>
 
 #endif
diff --git a/src/include/cbfs_declarations.h b/src/include/cbfs_declarations.h
new file mode 100644
index 0000000..2ac9c08
--- /dev/null
+++ b/src/include/cbfs_declarations.h
@@ -0,0 +1,82 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2008 Jordan Crouse <jordan at cosmicpenguin.net>
+ * Copyright (C) 2013-2015 Google, Inc.
+ *
+ * This file is dual-licensed. You can choose between:
+ *   - The GNU GPL, version 2, as published by the Free Software Foundation
+ *   - The revised BSD license (without advertising clause)
+ *
+ * ---------------------------------------------------------------------------
+ * 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
+ * ---------------------------------------------------------------------------
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ---------------------------------------------------------------------------
+ */
+
+#ifndef _CBFS_DECLARATIONS_H_
+#define _CBFS_DECLARATIONS_H_
+
+#include <cbfs_core.h>
+
+int init_backing_media(struct cbfs_media **media, struct cbfs_media *backing);
+void *cbfs_load_optionrom(struct cbfs_media *media, uint16_t vendor,
+			  uint16_t device, void * dest);
+void *cbfs_load_stage(struct cbfs_media *media, const char *name);
+void *cbfs_load_stage_by_offset(struct cbfs_media *media, ssize_t offset);
+/* Load a stage from a prog structure. Returns < 0 on error. 0 on success. */
+struct prog;
+int cbfs_load_prog_stage(struct cbfs_media *media, struct prog *prog);
+
+/* Simple buffer for streaming media. */
+struct cbfs_simple_buffer {
+	char *buffer;
+	size_t allocated;
+	size_t size;
+	size_t last_allocate;
+};
+
+void *cbfs_simple_buffer_map(struct cbfs_simple_buffer *buffer,
+			     struct cbfs_media *media,
+			     size_t offset, size_t count);
+
+void *cbfs_simple_buffer_unmap(struct cbfs_simple_buffer *buffer,
+			       const void *address);
+
+/* Defined in individual arch / board implementation. */
+int init_default_cbfs_media(struct cbfs_media *media);
+
+#endif
diff --git a/src/lib/Makefile.inc b/src/lib/Makefile.inc
index 134a5f3..0367d0f 100644
--- a/src/lib/Makefile.inc
+++ b/src/lib/Makefile.inc
@@ -19,7 +19,7 @@
 subdirs-y += loaders
 
 bootblock-y += prog_ops.c
-bootblock-y += cbfs.c cbfs_core.c
+bootblock-y += cbfs_gpl.c cbfs_core.c
 bootblock-$(CONFIG_COMMON_CBFS_SPI_WRAPPER) += cbfs_spi.c
 bootblock-$(CONFIG_GENERIC_GPIO_LIB) += gpio.c
 
@@ -33,7 +33,7 @@ bootblock-y += region.c
 
 verstage-y += prog_ops.c
 verstage-y += delay.c
-verstage-y += cbfs.c
+verstage-y += cbfs_gpl.c
 verstage-y += memcmp.c
 verstage-y += region.c
 verstage-$(CONFIG_CONSOLE_CBMEM) += cbmem_console.c
@@ -51,7 +51,7 @@ $(foreach arch,$(ARCH_SUPPORTED),\
 	    $(eval rmodules_$(arch)-y += rmodule.ld))
 
 romstage-$(CONFIG_I2C_TPM) += delay.c
-romstage-y += cbfs.c cbfs_core.c
+romstage-y += cbfs_gpl.c cbfs_core.c
 romstage-$(CONFIG_COMMON_CBFS_SPI_WRAPPER) += cbfs_spi.c
 romstage-$(CONFIG_COMPRESS_RAMSTAGE) += lzma.c lzmadecode.c
 romstage-$(CONFIG_PRIMITIVE_MEMTEST) += primitive_memtest.c
@@ -84,7 +84,7 @@ smm-$(CONFIG_SMM_TSEG) += malloc.c
 ramstage-y += delay.c
 ramstage-y += fallback_boot.c
 ramstage-y += compute_ip_checksum.c
-ramstage-y += cbfs.c cbfs_core.c
+ramstage-y += cbfs_gpl.c cbfs_core.c
 ramstage-$(CONFIG_COMMON_CBFS_SPI_WRAPPER) += cbfs_spi.c
 ramstage-y += lzma.c lzmadecode.c
 ramstage-y += stack.c
@@ -131,7 +131,7 @@ ramstage-y += mem_pool.c
 romstage-y += region.c
 ramstage-y += region.c
 
-smm-y += cbfs.c cbfs_core.c memcmp.c
+smm-y += cbfs_gpl.c cbfs_core.c memcmp.c
 smm-$(CONFIG_COMPILER_GCC) += gcc.c
 
 bootblock-y += version.c
diff --git a/src/lib/cbfs.c b/src/lib/cbfs.c
deleted file mode 100644
index 84638da..0000000
--- a/src/lib/cbfs.c
+++ /dev/null
@@ -1,209 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2008, Jordan Crouse <jordan at cosmicpenguin.net>
- * Copyright (C) 2013 The Chromium OS Authors. All rights reserved.
- *
- * 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 <program_loading.h>
-#include "cbfs_core.h"
-
-#ifndef __SMM__
-static inline int tohex4(unsigned int c)
-{
-	return (c <= 9) ? (c + '0') : (c - 10 + 'a');
-}
-
-static void tohex16(unsigned int val, char* dest)
-{
-	dest[0] = tohex4(val>>12);
-	dest[1] = tohex4((val>>8) & 0xf);
-	dest[2] = tohex4((val>>4) & 0xf);
-	dest[3] = tohex4(val & 0xf);
-}
-
-void *cbfs_load_optionrom(struct cbfs_media *media, uint16_t vendor,
-			  uint16_t device, void *dest)
-{
-	char name[17] = "pciXXXX,XXXX.rom";
-	struct cbfs_optionrom *orom;
-	uint8_t *src;
-
-	tohex16(vendor, name+3);
-	tohex16(device, name+8);
-
-	orom = (struct cbfs_optionrom *)
-	  cbfs_get_file_content(media, name, CBFS_TYPE_OPTIONROM, NULL);
-
-	if (orom == NULL)
-		return NULL;
-
-	/* They might have specified a dest address. If so, we can decompress.
-	 * If not, there's not much hope of decompressing or relocating the rom.
-	 * in the common case, the expansion rom is uncompressed, we
-	 * pass 0 in for the dest, and all we have to do is find the rom and
-	 * return a pointer to it.
-	 */
-
-	/* BUG: the cbfstool is (not yet) including a cbfs_optionrom header */
-	src = (uint8_t *)orom; // + sizeof(struct cbfs_optionrom);
-
-	if (! dest)
-		return src;
-
-	if (!cbfs_decompress(ntohl(orom->compression),
-			     src,
-			     dest,
-			     ntohl(orom->len)))
-		return NULL;
-
-	return dest;
-}
-
-static int cbfs_load_prog_stage_by_offset(struct cbfs_media *media,
-					struct prog *prog, ssize_t offset)
-{
-	struct cbfs_stage stage;
-	struct cbfs_media backing_store;
-
-	if (init_backing_media(&media, &backing_store))
-		return -1;
-
-	if (cbfs_read(media, &stage, offset, sizeof(stage)) != sizeof(stage)) {
-		ERROR("ERROR: failed to read stage header\n");
-		return -1;
-	}
-
-	LOG("loading stage @ 0x%llx (%d bytes), entry @ 0x%llx\n",
-	    stage.load, stage.memlen, stage.entry);
-
-	/* Stages rely the below clearing so that the bss is initialized. */
-	memset((void *)(uintptr_t)stage.load, 0, stage.memlen);
-
-	if (stage.compression == CBFS_COMPRESS_NONE) {
-		if (cbfs_read(media, (void *)(uintptr_t)stage.load,
-			      offset + sizeof(stage), stage.len) != stage.len) {
-			ERROR("ERROR: Reading stage failed.\n");
-			return -1;
-		}
-	} else {
-		void *data = media->map(media, offset + sizeof(stage),
-					stage.len);
-		if (data == CBFS_MEDIA_INVALID_MAP_ADDRESS) {
-			ERROR("ERROR: Mapping stage failed.\n");
-			return -1;
-		}
-		if (!cbfs_decompress(stage.compression, data,
-				    (void *)(uintptr_t)stage.load, stage.len))
-			return -1;
-		media->unmap(media, data);
-	}
-
-	arch_segment_loaded(stage.load, stage.memlen, SEG_FINAL);
-	DEBUG("stage loaded\n");
-
-	prog_set_area(prog, (void *)(uintptr_t)stage.load, stage.memlen);
-	prog_set_entry(prog, (void *)(uintptr_t)stage.entry, NULL);
-
-	return 0;
-}
-
-int cbfs_load_prog_stage(struct cbfs_media *media, struct prog *prog)
-{
-	struct cbfs_file file;
-	ssize_t offset;
-	struct cbfs_media backing_store;
-
-	if (init_backing_media(&media, &backing_store))
-		return -1;
-
-	offset = cbfs_locate_file(media, &file, prog->name);
-	if (offset < 0 || file.type != CBFS_TYPE_STAGE)
-		return -1;
-
-	if (cbfs_load_prog_stage_by_offset(media, prog, offset) < 0)
-		return -1;
-
-	return 0;
-}
-
-void *cbfs_load_stage_by_offset(struct cbfs_media *media, ssize_t offset)
-{
-	struct prog prog = {
-		.name = NULL,
-	};
-
-	if (cbfs_load_prog_stage_by_offset(media, &prog, offset) < 0)
-		return (void *)-1;
-
-	return prog_entry(&prog);
-}
-
-void *cbfs_load_stage(struct cbfs_media *media, const char *name)
-{
-	struct prog prog = {
-		.name = name,
-	};
-
-	if (cbfs_load_prog_stage(media, &prog) < 0)
-		return (void *)-1;
-
-	return prog_entry(&prog);
-}
-
-/* Simple buffer */
-
-void *cbfs_simple_buffer_map(struct cbfs_simple_buffer *buffer,
-			     struct cbfs_media *media,
-			     size_t offset, size_t count) {
-	void *address = buffer->buffer + buffer->allocated;
-	DEBUG("simple_buffer_map(offset=%zd, count=%zd): "
-	      "allocated=%zd, size=%zd, last_allocate=%zd\n",
-	    offset, count, buffer->allocated, buffer->size,
-	    buffer->last_allocate);
-	if (buffer->allocated + count > buffer->size) {
-		ERROR("simple_buffer: no room to map %zd bytes from %#zx\n",
-		      count, offset);
-		return CBFS_MEDIA_INVALID_MAP_ADDRESS;
-	}
-	if (media->read(media, address, offset, count) != count) {
-		ERROR("simple_buffer: fail to read %zd bytes from 0x%zx\n",
-		      count, offset);
-		return CBFS_MEDIA_INVALID_MAP_ADDRESS;
-	}
-	buffer->allocated += count;
-	buffer->last_allocate = count;
-	return address;
-}
-
-void *cbfs_simple_buffer_unmap(struct cbfs_simple_buffer *buffer,
-			       const void *address) {
-	// TODO Add simple buffer management so we can free more than last
-	// allocated one.
-	DEBUG("simple_buffer_unmap(address=0x%p): "
-	      "allocated=%zd, size=%zd, last_allocate=%zd\n",
-	    address, buffer->allocated, buffer->size,
-	    buffer->last_allocate);
-	if ((buffer->buffer + buffer->allocated - buffer->last_allocate) ==
-	    address) {
-		buffer->allocated -= buffer->last_allocate;
-		buffer->last_allocate = 0;
-	}
-	return NULL;
-}
-
-#endif
diff --git a/src/lib/cbfs_gpl.c b/src/lib/cbfs_gpl.c
new file mode 100644
index 0000000..84638da
--- /dev/null
+++ b/src/lib/cbfs_gpl.c
@@ -0,0 +1,209 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2008, Jordan Crouse <jordan at cosmicpenguin.net>
+ * Copyright (C) 2013 The Chromium OS Authors. All rights reserved.
+ *
+ * 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 <program_loading.h>
+#include "cbfs_core.h"
+
+#ifndef __SMM__
+static inline int tohex4(unsigned int c)
+{
+	return (c <= 9) ? (c + '0') : (c - 10 + 'a');
+}
+
+static void tohex16(unsigned int val, char* dest)
+{
+	dest[0] = tohex4(val>>12);
+	dest[1] = tohex4((val>>8) & 0xf);
+	dest[2] = tohex4((val>>4) & 0xf);
+	dest[3] = tohex4(val & 0xf);
+}
+
+void *cbfs_load_optionrom(struct cbfs_media *media, uint16_t vendor,
+			  uint16_t device, void *dest)
+{
+	char name[17] = "pciXXXX,XXXX.rom";
+	struct cbfs_optionrom *orom;
+	uint8_t *src;
+
+	tohex16(vendor, name+3);
+	tohex16(device, name+8);
+
+	orom = (struct cbfs_optionrom *)
+	  cbfs_get_file_content(media, name, CBFS_TYPE_OPTIONROM, NULL);
+
+	if (orom == NULL)
+		return NULL;
+
+	/* They might have specified a dest address. If so, we can decompress.
+	 * If not, there's not much hope of decompressing or relocating the rom.
+	 * in the common case, the expansion rom is uncompressed, we
+	 * pass 0 in for the dest, and all we have to do is find the rom and
+	 * return a pointer to it.
+	 */
+
+	/* BUG: the cbfstool is (not yet) including a cbfs_optionrom header */
+	src = (uint8_t *)orom; // + sizeof(struct cbfs_optionrom);
+
+	if (! dest)
+		return src;
+
+	if (!cbfs_decompress(ntohl(orom->compression),
+			     src,
+			     dest,
+			     ntohl(orom->len)))
+		return NULL;
+
+	return dest;
+}
+
+static int cbfs_load_prog_stage_by_offset(struct cbfs_media *media,
+					struct prog *prog, ssize_t offset)
+{
+	struct cbfs_stage stage;
+	struct cbfs_media backing_store;
+
+	if (init_backing_media(&media, &backing_store))
+		return -1;
+
+	if (cbfs_read(media, &stage, offset, sizeof(stage)) != sizeof(stage)) {
+		ERROR("ERROR: failed to read stage header\n");
+		return -1;
+	}
+
+	LOG("loading stage @ 0x%llx (%d bytes), entry @ 0x%llx\n",
+	    stage.load, stage.memlen, stage.entry);
+
+	/* Stages rely the below clearing so that the bss is initialized. */
+	memset((void *)(uintptr_t)stage.load, 0, stage.memlen);
+
+	if (stage.compression == CBFS_COMPRESS_NONE) {
+		if (cbfs_read(media, (void *)(uintptr_t)stage.load,
+			      offset + sizeof(stage), stage.len) != stage.len) {
+			ERROR("ERROR: Reading stage failed.\n");
+			return -1;
+		}
+	} else {
+		void *data = media->map(media, offset + sizeof(stage),
+					stage.len);
+		if (data == CBFS_MEDIA_INVALID_MAP_ADDRESS) {
+			ERROR("ERROR: Mapping stage failed.\n");
+			return -1;
+		}
+		if (!cbfs_decompress(stage.compression, data,
+				    (void *)(uintptr_t)stage.load, stage.len))
+			return -1;
+		media->unmap(media, data);
+	}
+
+	arch_segment_loaded(stage.load, stage.memlen, SEG_FINAL);
+	DEBUG("stage loaded\n");
+
+	prog_set_area(prog, (void *)(uintptr_t)stage.load, stage.memlen);
+	prog_set_entry(prog, (void *)(uintptr_t)stage.entry, NULL);
+
+	return 0;
+}
+
+int cbfs_load_prog_stage(struct cbfs_media *media, struct prog *prog)
+{
+	struct cbfs_file file;
+	ssize_t offset;
+	struct cbfs_media backing_store;
+
+	if (init_backing_media(&media, &backing_store))
+		return -1;
+
+	offset = cbfs_locate_file(media, &file, prog->name);
+	if (offset < 0 || file.type != CBFS_TYPE_STAGE)
+		return -1;
+
+	if (cbfs_load_prog_stage_by_offset(media, prog, offset) < 0)
+		return -1;
+
+	return 0;
+}
+
+void *cbfs_load_stage_by_offset(struct cbfs_media *media, ssize_t offset)
+{
+	struct prog prog = {
+		.name = NULL,
+	};
+
+	if (cbfs_load_prog_stage_by_offset(media, &prog, offset) < 0)
+		return (void *)-1;
+
+	return prog_entry(&prog);
+}
+
+void *cbfs_load_stage(struct cbfs_media *media, const char *name)
+{
+	struct prog prog = {
+		.name = name,
+	};
+
+	if (cbfs_load_prog_stage(media, &prog) < 0)
+		return (void *)-1;
+
+	return prog_entry(&prog);
+}
+
+/* Simple buffer */
+
+void *cbfs_simple_buffer_map(struct cbfs_simple_buffer *buffer,
+			     struct cbfs_media *media,
+			     size_t offset, size_t count) {
+	void *address = buffer->buffer + buffer->allocated;
+	DEBUG("simple_buffer_map(offset=%zd, count=%zd): "
+	      "allocated=%zd, size=%zd, last_allocate=%zd\n",
+	    offset, count, buffer->allocated, buffer->size,
+	    buffer->last_allocate);
+	if (buffer->allocated + count > buffer->size) {
+		ERROR("simple_buffer: no room to map %zd bytes from %#zx\n",
+		      count, offset);
+		return CBFS_MEDIA_INVALID_MAP_ADDRESS;
+	}
+	if (media->read(media, address, offset, count) != count) {
+		ERROR("simple_buffer: fail to read %zd bytes from 0x%zx\n",
+		      count, offset);
+		return CBFS_MEDIA_INVALID_MAP_ADDRESS;
+	}
+	buffer->allocated += count;
+	buffer->last_allocate = count;
+	return address;
+}
+
+void *cbfs_simple_buffer_unmap(struct cbfs_simple_buffer *buffer,
+			       const void *address) {
+	// TODO Add simple buffer management so we can free more than last
+	// allocated one.
+	DEBUG("simple_buffer_unmap(address=0x%p): "
+	      "allocated=%zd, size=%zd, last_allocate=%zd\n",
+	    address, buffer->allocated, buffer->size,
+	    buffer->last_allocate);
+	if ((buffer->buffer + buffer->allocated - buffer->last_allocate) ==
+	    address) {
+		buffer->allocated -= buffer->last_allocate;
+		buffer->last_allocate = 0;
+	}
+	return NULL;
+}
+
+#endif



More information about the coreboot-gerrit mailing list