coreboot-kgpe-d16/util/cbfstool/common.h

178 lines
5.4 KiB
C
Raw Normal View History

/*
* Copyright (C) 2009 coresystems GmbH
* written by Patrick Georgi <patrick.georgi@coresystems.de>
* Copyright (C) 2012 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 __CBFSTOOL_COMMON_H
#define __CBFSTOOL_COMMON_H
#include <stdint.h>
#include <assert.h>
/* Endianess */
#include "swab.h"
#ifndef __APPLE__
#define ntohl(x) (is_big_endian() ? (x) : swab32(x))
#define htonl(x) (is_big_endian() ? (x) : swab32(x))
#endif
#define ntohll(x) (is_big_endian() ? (x) : swab64(x))
#define htonll(x) (is_big_endian() ? (x) : swab64(x))
int is_big_endian(void);
/* Message output */
extern int verbose;
#define ERROR(x...) { fprintf(stderr, "E: " x); }
#define WARN(x...) { fprintf(stderr, "W: " x); }
#define LOG(x...) { fprintf(stderr, x); }
#define INFO(x...) { if (verbose > 0) fprintf(stderr, "INFO: " x); }
#define DEBUG(x...) { if (verbose > 1) fprintf(stderr, "DEBUG: " x); }
/* Helpers */
#define ARRAY_SIZE(a) (int)(sizeof(a) / sizeof((a)[0]))
#define ALIGN(val, by) (((val) + (by)-1)&~((by)-1))
#define unused __attribute__((unused))
CBFS: Automate ROM image layout and remove hardcoded offsets Non-x86 boards currently need to hardcode the position of their CBFS master header in a Kconfig. This is very brittle because it is usually put in between the bootblock and the first CBFS entry, without any checks to guarantee that it won't overlap either of those. It is not fun to debug random failures that move and disappear with tiny alignment changes because someone decided to write "ORBC1112" over some part of your data section (in a way that is not visible in the symbolized .elf binaries, only in the final image). This patch seeks to prevent those issues and reduce the need for manual configuration by making the image layout a completely automated part of cbfstool. Since automated placement of the CBFS header means we can no longer hardcode its position into coreboot, this patch takes the existing x86 solution of placing a pointer to the header at the very end of the CBFS-managed section of the ROM and generalizes it to all architectures. This is now even possible with the read-only/read-write split in ChromeOS, since coreboot knows how large that section is from the CBFS_SIZE Kconfig (which is by default equal to ROM_SIZE, but can be changed on systems that place other data next to coreboot/CBFS in ROM). Also adds a feature to cbfstool that makes the -B (bootblock file name) argument on image creation optional, since we have recently found valid use cases for CBFS images that are not the first boot medium of the device (instead opened by an earlier bootloader that can already interpret CBFS) and therefore don't really need a bootblock. BRANCH=None BUG=None TEST=Built and booted on Veyron_Pinky, Nyan_Blaze and Falco. Change-Id: Ib715bb8db258e602991b34f994750a2d3e2d5adf Signed-off-by: Patrick Georgi <pgeorgi@chromium.org> Original-Commit-Id: e9879c0fbd57f105254c54bacb3e592acdcad35c Original-Change-Id: Ifcc755326832755cfbccd6f0a12104cba28a20af Original-Signed-off-by: Julius Werner <jwerner@chromium.org> Original-Reviewed-on: https://chromium-review.googlesource.com/229975 Reviewed-on: http://review.coreboot.org/9620 Tested-by: build bot (Jenkins) Reviewed-by: Stefan Reinauer <stefan.reinauer@coreboot.org>
2014-11-10 22:14:24 +01:00
static inline uint32_t align_up(uint32_t value, uint32_t align)
{
if (value % align)
value += align - (value % align);
return value;
}
/* Buffer and file I/O */
struct buffer {
char *name;
char *data;
size_t size;
};
static inline void *buffer_get(const struct buffer *b)
{
return b->data;
}
static inline size_t buffer_size(const struct buffer *b)
{
return b->size;
}
static inline void buffer_set_size(struct buffer *b, size_t size)
{
b->size = size;
}
/* Initialize a buffer with the given constraints. */
static inline void buffer_init(struct buffer *b, char *name, void *data,
size_t size)
{
b->name = name;
b->data = data;
b->size = size;
}
/* Splice a buffer into another buffer. If size is zero the entire buffer
* is spliced while if size is non-zero the buffer is spliced starting at
* offset for size bytes. Note that it's up to caller to bounds check.
*/
static inline void buffer_splice(struct buffer *dest, const struct buffer *src,
size_t offset, size_t size)
{
buffer_init(dest, src->name, src->data, src->size);
if (size != 0) {
dest->data += offset;
buffer_set_size(dest, size);
}
}
static inline void buffer_clone(struct buffer *dest, const struct buffer *src)
{
buffer_splice(dest, src, 0, 0);
}
static inline void buffer_seek(struct buffer *b, size_t size)
{
b->size -= size;
b->data += size;
}
/* Creates an empty memory buffer with given size.
* Returns 0 on success, otherwise non-zero. */
int buffer_create(struct buffer *buffer, size_t size, const char *name);
/* Loads a file into memory buffer. Returns 0 on success, otherwise non-zero. */
int buffer_from_file(struct buffer *buffer, const char *filename);
/* Writes memory buffer content into file.
* Returns 0 on success, otherwise non-zero. */
int buffer_write_file(struct buffer *buffer, const char *filename);
/* Destroys a memory buffer. */
void buffer_delete(struct buffer *buffer);
const char *arch_to_string(uint32_t a);
uint32_t string_to_arch(const char *arch_string);
typedef int (*comp_func_ptr) (char *, int, char *, int *);
typedef enum { CBFS_COMPRESS_NONE = 0, CBFS_COMPRESS_LZMA = 1 } comp_algo;
comp_func_ptr compression_function(comp_algo algo);
uint64_t intfiletype(const char *name);
/* cbfs-mkpayload.c */
int parse_elf_to_payload(const struct buffer *input,
struct buffer *output, uint32_t arch, comp_algo algo);
int parse_fv_to_payload(const struct buffer *input,
struct buffer *output, comp_algo algo);
int parse_bzImage_to_payload(const struct buffer *input,
struct buffer *output, const char *initrd,
char *cmdline, comp_algo algo);
int parse_flat_binary_to_payload(const struct buffer *input,
struct buffer *output,
uint32_t loadaddress,
uint32_t entrypoint,
comp_algo algo);
/* cbfs-mkstage.c */
int parse_elf_to_stage(const struct buffer *input, struct buffer *output,
uint32_t arch, comp_algo algo, uint32_t *location,
const char *ignore_section);
void print_supported_filetypes(void);
cbfs: fix issues with word size and endianness. Add XDR functions and use them to convert the ELF headers to native headers, using the Elf64 structs to ensure we accomodate all word sizes. Also, use these XDR functions for output. This may seem overly complex but it turned out to be much the easiest way to do this. Note that the basic elf parsing function in cbfs-mkstage.c now works over all ELF files, for all architectures, endian, and word size combinations. At the same time, the basic elf parsing in cbfs-mkstage.c is a loop that has no architecture-specific conditionals. Add -g to the LDFLAGS while we're here. It's on the CFLAGS so there is no harm done. This code has been tested on all chromebooks that use coreboot to date. I added most of the extra checks from ChromeOS and they triggered a lot of warnings, hence the other changes. I had to take -Wshadow back out due to the many errors it triggers in LZMA. BUG=None TEST=Build and boot for Peppy; works fine. Build and boot for nyan, works fine. Build for qemu targets and armv8 targets. BRANCH=None Change-Id: I5a4cee9854799189115ac701e22efc406a8d902f Signed-off-by: Ronald G. Minnich <rminnich@google.com> Reviewed-on: https://chromium-review.googlesource.com/178606 Reviewed-by: Ronald Minnich <rminnich@chromium.org> Commit-Queue: Ronald Minnich <rminnich@chromium.org> Tested-by: Ronald Minnich <rminnich@chromium.org> Reviewed-on: http://review.coreboot.org/4817 Reviewed-by: Alexandru Gagniuc <mr.nuke.me@gmail.com> Tested-by: build bot (Jenkins) Reviewed-by: Ronald G. Minnich <rminnich@gmail.com>
2013-12-03 20:13:35 +01:00
/* lzma/lzma.c */
int do_lzma_compress(char *in, int in_len, char *out, int *out_len);
int do_lzma_uncompress(char *dst, int dst_len, char *src, int src_len);
cbfs: fix issues with word size and endianness. Add XDR functions and use them to convert the ELF headers to native headers, using the Elf64 structs to ensure we accomodate all word sizes. Also, use these XDR functions for output. This may seem overly complex but it turned out to be much the easiest way to do this. Note that the basic elf parsing function in cbfs-mkstage.c now works over all ELF files, for all architectures, endian, and word size combinations. At the same time, the basic elf parsing in cbfs-mkstage.c is a loop that has no architecture-specific conditionals. Add -g to the LDFLAGS while we're here. It's on the CFLAGS so there is no harm done. This code has been tested on all chromebooks that use coreboot to date. I added most of the extra checks from ChromeOS and they triggered a lot of warnings, hence the other changes. I had to take -Wshadow back out due to the many errors it triggers in LZMA. BUG=None TEST=Build and boot for Peppy; works fine. Build and boot for nyan, works fine. Build for qemu targets and armv8 targets. BRANCH=None Change-Id: I5a4cee9854799189115ac701e22efc406a8d902f Signed-off-by: Ronald G. Minnich <rminnich@google.com> Reviewed-on: https://chromium-review.googlesource.com/178606 Reviewed-by: Ronald Minnich <rminnich@chromium.org> Commit-Queue: Ronald Minnich <rminnich@chromium.org> Tested-by: Ronald Minnich <rminnich@chromium.org> Reviewed-on: http://review.coreboot.org/4817 Reviewed-by: Alexandru Gagniuc <mr.nuke.me@gmail.com> Tested-by: build bot (Jenkins) Reviewed-by: Ronald G. Minnich <rminnich@gmail.com>
2013-12-03 20:13:35 +01:00
/* xdr.c */
struct xdr {
uint8_t (*get8)(struct buffer *input);
cbfs: fix issues with word size and endianness. Add XDR functions and use them to convert the ELF headers to native headers, using the Elf64 structs to ensure we accomodate all word sizes. Also, use these XDR functions for output. This may seem overly complex but it turned out to be much the easiest way to do this. Note that the basic elf parsing function in cbfs-mkstage.c now works over all ELF files, for all architectures, endian, and word size combinations. At the same time, the basic elf parsing in cbfs-mkstage.c is a loop that has no architecture-specific conditionals. Add -g to the LDFLAGS while we're here. It's on the CFLAGS so there is no harm done. This code has been tested on all chromebooks that use coreboot to date. I added most of the extra checks from ChromeOS and they triggered a lot of warnings, hence the other changes. I had to take -Wshadow back out due to the many errors it triggers in LZMA. BUG=None TEST=Build and boot for Peppy; works fine. Build and boot for nyan, works fine. Build for qemu targets and armv8 targets. BRANCH=None Change-Id: I5a4cee9854799189115ac701e22efc406a8d902f Signed-off-by: Ronald G. Minnich <rminnich@google.com> Reviewed-on: https://chromium-review.googlesource.com/178606 Reviewed-by: Ronald Minnich <rminnich@chromium.org> Commit-Queue: Ronald Minnich <rminnich@chromium.org> Tested-by: Ronald Minnich <rminnich@chromium.org> Reviewed-on: http://review.coreboot.org/4817 Reviewed-by: Alexandru Gagniuc <mr.nuke.me@gmail.com> Tested-by: build bot (Jenkins) Reviewed-by: Ronald G. Minnich <rminnich@gmail.com>
2013-12-03 20:13:35 +01:00
uint16_t (*get16)(struct buffer *input);
uint32_t (*get32)(struct buffer *input);
uint64_t (*get64)(struct buffer *input);
void (*put8)(struct buffer *input, uint8_t val);
cbfs: fix issues with word size and endianness. Add XDR functions and use them to convert the ELF headers to native headers, using the Elf64 structs to ensure we accomodate all word sizes. Also, use these XDR functions for output. This may seem overly complex but it turned out to be much the easiest way to do this. Note that the basic elf parsing function in cbfs-mkstage.c now works over all ELF files, for all architectures, endian, and word size combinations. At the same time, the basic elf parsing in cbfs-mkstage.c is a loop that has no architecture-specific conditionals. Add -g to the LDFLAGS while we're here. It's on the CFLAGS so there is no harm done. This code has been tested on all chromebooks that use coreboot to date. I added most of the extra checks from ChromeOS and they triggered a lot of warnings, hence the other changes. I had to take -Wshadow back out due to the many errors it triggers in LZMA. BUG=None TEST=Build and boot for Peppy; works fine. Build and boot for nyan, works fine. Build for qemu targets and armv8 targets. BRANCH=None Change-Id: I5a4cee9854799189115ac701e22efc406a8d902f Signed-off-by: Ronald G. Minnich <rminnich@google.com> Reviewed-on: https://chromium-review.googlesource.com/178606 Reviewed-by: Ronald Minnich <rminnich@chromium.org> Commit-Queue: Ronald Minnich <rminnich@chromium.org> Tested-by: Ronald Minnich <rminnich@chromium.org> Reviewed-on: http://review.coreboot.org/4817 Reviewed-by: Alexandru Gagniuc <mr.nuke.me@gmail.com> Tested-by: build bot (Jenkins) Reviewed-by: Ronald G. Minnich <rminnich@gmail.com>
2013-12-03 20:13:35 +01:00
void (*put16)(struct buffer *input, uint16_t val);
void (*put32)(struct buffer *input, uint32_t val);
void (*put64)(struct buffer *input, uint64_t val);
};
extern struct xdr xdr_le, xdr_be;
size_t bgets(struct buffer *input, void *output, size_t len);
size_t bputs(struct buffer *b, const void *data, size_t len);
#endif