Aaron Durbin (adurbin@google.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/9127
-gerrit
commit 6976544cdc7a20f7d73de329785020a65484c65f Author: Aaron Durbin adurbin@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@chromium.org --- src/include/cbfs.h | 63 +----------- src/include/cbfs_declarations.h | 82 ++++++++++++++++ src/lib/Makefile.inc | 10 +- src/lib/cbfs.c | 206 ---------------------------------------- src/lib/cbfs_gpl.c | 206 ++++++++++++++++++++++++++++++++++++++++ 5 files changed, 296 insertions(+), 271 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@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@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 1c38118..284f0ce 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_CONSOLE_CBMEM) += cbmem_console.c @@ -28,7 +28,7 @@ bootblock-y += memcmp.c
verstage-y += prog_ops.c verstage-y += delay.c -verstage-y += cbfs.c +verstage-y += cbfs_gpl.c verstage-y += memcmp.c verstage-$(CONFIG_CONSOLE_CBMEM) += cbmem_console.c verstage-$(CONFIG_COMMON_CBFS_SPI_WRAPPER) += cbfs_spi.c @@ -42,7 +42,7 @@ $(foreach arch,$(ARCH_SUPPORTED),\ $(eval rmodules_$(arch)-y += memcmp.c))
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 @@ -72,7 +72,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 @@ -113,7 +113,7 @@ romstage-$(CONFIG_RELOCATABLE_RAMSTAGE) += cbmem_stage_cache.c endif
-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 0fddb53..0000000 --- a/src/lib/cbfs.c +++ /dev/null @@ -1,206 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2008, Jordan Crouse jordan@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) - 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..0fddb53 --- /dev/null +++ b/src/lib/cbfs_gpl.c @@ -0,0 +1,206 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2008, Jordan Crouse jordan@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) + 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