[coreboot-gerrit] New patch to review for coreboot: commonlib: add endian related accessor functions
Aaron Durbin (adurbin@chromium.org)
gerrit at coreboot.org
Thu Sep 17 16:55:16 CET 2015
Aaron Durbin (adurbin at chromium.org) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/11677
-gerrit
commit fdfb2b0b39caae446424ea63a00036f85a832eb6
Author: Aaron Durbin <adurbin at chromium.org>
Date: Thu Sep 17 11:24:08 2015 -0500
commonlib: add endian related accessor functions
This commit adds read/write functions for both big and
little endian interpretations. Additionally there are
variants that allow an offse to be provided into the
source buffer.
Along with this commit is a change to the cbfs locating
code to use the new API.
BUG=None
TEST=Wrote test harness for functions. Also booted ARM QEMU
through end of payload.
Change-Id: If44c4d489f0dab86a73b73580c039e364c7e517d
Signed-off-by: Aaron Durbin <adurbin at chromium.org>
---
src/arch/x86/include/arch/cbfs.h | 4 +-
src/commonlib/include/commonlib/cbfs_serialized.h | 2 +-
src/commonlib/include/commonlib/endian.h | 261 ++++++++++++++++++++++
src/cpu/intel/microcode/microcode.c | 2 +-
src/lib/cbfs.c | 38 +++-
5 files changed, 296 insertions(+), 11 deletions(-)
diff --git a/src/arch/x86/include/arch/cbfs.h b/src/arch/x86/include/arch/cbfs.h
index 195c06f..ff45edb 100644
--- a/src/arch/x86/include/arch/cbfs.h
+++ b/src/arch/x86/include/arch/cbfs.h
@@ -25,7 +25,7 @@
#define CBFS_SUBHEADER(_p) ( (void *) ((((uint8_t *) (_p)) + ntohl((_p)->offset))) )
-static struct cbfs_file *walkcbfs_head(char *target)
+static struct cbfs_file_serialized *walkcbfs_head(char *target)
{
void *entry;
asm volatile (
@@ -37,7 +37,7 @@ static struct cbfs_file *walkcbfs_head(char *target)
static void *walkcbfs(char *target)
{
- struct cbfs_file *head = walkcbfs_head(target);
+ struct cbfs_file_serialized *head = walkcbfs_head(target);
if ((u32)head != 0)
return CBFS_SUBHEADER(head);
diff --git a/src/commonlib/include/commonlib/cbfs_serialized.h b/src/commonlib/include/commonlib/cbfs_serialized.h
index f672095..c655fc1 100644
--- a/src/commonlib/include/commonlib/cbfs_serialized.h
+++ b/src/commonlib/include/commonlib/cbfs_serialized.h
@@ -128,7 +128,7 @@ struct cbfs_header {
#define CBFS_FILE_MAGIC "LARCHIVE"
-struct cbfs_file {
+struct cbfs_file_serialized {
char magic[8];
uint32_t len;
uint32_t type;
diff --git a/src/commonlib/include/commonlib/endian.h b/src/commonlib/include/commonlib/endian.h
new file mode 100644
index 0000000..bcd3b39
--- /dev/null
+++ b/src/commonlib/include/commonlib/endian.h
@@ -0,0 +1,261 @@
+/*
+ * 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 _COMMONLIB_ENDIAN_H_
+#define _COMMONLIB_ENDIAN_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+/* Endian agnostic functions working on single byte. */
+
+static inline uint8_t read_ble8(const void *src)
+{
+ const uint8_t *s = src;
+ return *s;
+}
+
+static inline uint8_t read_at_ble8(const void *src, size_t offset)
+{
+ const uint8_t *s = src;
+ s += offset;
+ return read_ble8(s);
+}
+
+static inline void write_ble8(void *dest, uint8_t val)
+{
+ *(uint8_t *)dest = val;
+}
+
+static inline void write_at_ble8(void *dest, uint8_t val, size_t offset)
+{
+ uint8_t *d = dest;
+ d += offset;
+ write_ble8(d, val);
+}
+
+/* Big Endian functions. */
+
+static inline uint8_t read_be8(const void *src)
+{
+ return read_ble8(src);
+}
+
+static inline uint8_t read_at_be8(const void *src, size_t offset)
+{
+ return read_at_ble8(src, offset);
+}
+
+static inline void write_be8(void *dest, uint8_t val)
+{
+ write_ble8(dest, val);
+}
+
+static inline void write_at_be8(void *dest, uint8_t val, size_t offset)
+{
+ write_at_ble8(dest, val, offset);
+}
+
+static inline uint16_t read_be16(const void *src)
+{
+ const uint8_t *s = src;
+ return (((uint16_t)s[0]) << 8) | (((uint16_t)s[1]) << 0);
+}
+
+static inline uint16_t read_at_be16(const void *src, size_t offset)
+{
+ const uint8_t *s = src;
+ s += offset;
+ return read_be16(s);
+}
+
+static inline void write_be16(void *dest, uint16_t val)
+{
+ write_be8(dest, val >> 8);
+ write_at_be8(dest, val >> 0, sizeof(uint8_t));
+}
+
+static inline void write_at_be16(void *dest, uint16_t val, size_t offset)
+{
+ uint8_t *d = dest;
+ d += offset;
+ write_be16(d, val);
+}
+
+static inline uint32_t read_be32(const void *src)
+{
+ const uint8_t *s = src;
+ return (((uint32_t)s[0]) << 24) | (((uint32_t)s[1]) << 16) |
+ (((uint32_t)s[2]) << 8) | (((uint32_t)s[3]) << 0);
+}
+
+static inline uint32_t read_at_be32(const void *src, size_t offset)
+{
+ const uint8_t *s = src;
+ s += offset;
+ return read_be32(s);
+}
+
+static inline void write_be32(void *dest, uint32_t val)
+{
+ write_be16(dest, val >> 16);
+ write_at_be16(dest, val >> 0, sizeof(uint16_t));
+}
+
+static inline void write_at_be32(void *dest, uint32_t val, size_t offset)
+{
+ uint8_t *d = dest;
+ d += offset;
+ write_be32(d, val);
+}
+
+static inline uint64_t read_be64(const void *src)
+{
+ uint64_t val;
+ val = read_be32(src);
+ val <<= 32;
+ val |= read_at_be32(src, sizeof(uint32_t));
+ return val;
+}
+
+static inline uint64_t read_at_be64(const void *src, size_t offset)
+{
+ const uint8_t *s = src;
+ s += offset;
+ return read_be64(s);
+}
+
+static inline void write_be64(void *dest, uint64_t val)
+{
+ write_be32(dest, val >> 32);
+ write_at_be32(dest, val >> 0, sizeof(uint32_t));
+}
+
+static inline void write_at_be64(void *dest, uint64_t val, size_t offset)
+{
+ uint8_t *d = dest;
+ d += offset;
+ write_be64(d, val);
+}
+
+/* Little Endian functions. */
+
+static inline uint8_t read_le8(const void *src)
+{
+ return read_ble8(src);
+}
+
+static inline uint8_t read_at_le8(const void *src, size_t offset)
+{
+ return read_at_ble8(src, offset);
+}
+
+static inline void write_le8(void *dest, uint8_t val)
+{
+ write_ble8(dest, val);
+}
+
+static inline void write_at_le8(void *dest, uint8_t val, size_t offset)
+{
+ write_at_ble8(dest, val, offset);
+}
+
+static inline uint16_t read_le16(const void *src)
+{
+ const uint8_t *s = src;
+ return (((uint16_t)s[1]) << 8) | (((uint16_t)s[0]) << 0);
+}
+
+static inline uint16_t read_at_le16(const void *src, size_t offset)
+{
+ const uint8_t *s = src;
+ s += offset;
+ return read_le16(s);
+}
+
+static inline void write_le16(void *dest, uint16_t val)
+{
+ write_le8(dest, val >> 0);
+ write_at_le8(dest, val >> 8, sizeof(uint8_t));
+}
+
+static inline void write_at_le16(void *dest, uint16_t val, size_t offset)
+{
+ uint8_t *d = dest;
+ d += offset;
+ write_le16(d, val);
+}
+
+static inline uint32_t read_le32(const void *src)
+{
+ const uint8_t *s = src;
+ return (((uint32_t)s[3]) << 24) | (((uint32_t)s[2]) << 16) |
+ (((uint32_t)s[1]) << 8) | (((uint32_t)s[0]) << 0);
+}
+
+static inline uint32_t read_at_le32(const void *src, size_t offset)
+{
+ const uint8_t *s = src;
+ s += offset;
+ return read_le32(s);
+}
+
+static inline void write_le32(void *dest, uint32_t val)
+{
+ write_le16(dest, val >> 0);
+ write_at_le16(dest, val >> 16, sizeof(uint16_t));
+}
+
+static inline void write_at_le32(void *dest, uint32_t val, size_t offset)
+{
+ uint8_t *d = dest;
+ d += offset;
+ write_le32(d, val);
+}
+
+static inline uint64_t read_le64(const void *src)
+{
+ uint64_t val;
+ val = read_at_le32(src, sizeof(uint32_t));
+ val <<= 32;
+ val |= read_le32(src);
+ return val;
+}
+
+static inline uint64_t read_at_le64(const void *src, size_t offset)
+{
+ const uint8_t *s = src;
+ s += offset;
+ return read_le64(s);
+}
+
+static inline void write_le64(void *dest, uint64_t val)
+{
+ write_le32(dest, val >> 0);
+ write_at_le32(dest, val >> 32, sizeof(uint32_t));
+}
+
+static inline void write_at_le64(void *dest, uint64_t val, size_t offset)
+{
+ uint8_t *d = dest;
+ d += offset;
+ write_le64(d, val);
+}
+
+#endif
diff --git a/src/cpu/intel/microcode/microcode.c b/src/cpu/intel/microcode/microcode.c
index 8791a2e..1cee30f 100644
--- a/src/cpu/intel/microcode/microcode.c
+++ b/src/cpu/intel/microcode/microcode.c
@@ -126,7 +126,7 @@ const void *intel_microcode_find(void)
msr_t msr;
#ifdef __PRE_RAM__
- struct cbfs_file *microcode_file;
+ struct cbfs_file_serialized *microcode_file;
microcode_file = walkcbfs_head((char *) MICROCODE_CBFS_FILE);
if (!microcode_file)
diff --git a/src/lib/cbfs.c b/src/lib/cbfs.c
index abc4077..c4eff5b 100644
--- a/src/lib/cbfs.c
+++ b/src/lib/cbfs.c
@@ -23,7 +23,7 @@
#include <stdlib.h>
#include <boot_device.h>
#include <cbfs.h>
-#include <endian.h>
+#include <commonlib/endian.h>
#include <lib.h>
#include <symbols.h>
@@ -35,6 +35,30 @@
#define DEBUG(x...)
#endif
+struct cbfs_file {
+ char magic[8];
+ uint32_t len;
+ uint32_t type;
+ uint32_t checksum;
+ uint32_t offset;
+};
+
+static void cbfs_file_deserialize(struct cbfs_file *f, void *from)
+{
+ size_t off;
+
+ off = 0;
+ memcpy(&f->magic, from, sizeof(f->magic));
+ off += sizeof(f->magic);
+ f->len = read_at_be32(from, off);
+ off += sizeof(f->len);
+ f->type = read_at_be32(from, off);
+ off += sizeof(f->type);
+ f->checksum = read_at_be32(from, off);
+ off += sizeof(f->checksum);
+ f->offset = read_at_be32(from, off);
+}
+
int cbfs_boot_locate(struct region_device *fh, const char *name, uint32_t *type)
{
struct cbfsd cbfs;
@@ -91,16 +115,20 @@ int cbfs_locate(struct region_device *fh, const struct cbfsd *cbfs,
/* Try to scan the entire cbfs region looking for file name. */
while (1) {
struct cbfs_file file;
- const size_t fsz = sizeof(file);
+ const size_t fsz = sizeof(struct cbfs_file_serialized);
char *fname;
int name_match;
size_t datasz;
+ void *mapping;
DEBUG("Checking offset %zx\n", offset);
+ mapping = rdev_mmap(rd, offset, fsz);
/* Can't read file. Nothing else to do but bail out. */
- if (rdev_readat(rd, &file, offset, fsz) != fsz)
+ if (mapping == NULL)
break;
+ cbfs_file_deserialize(&file, mapping);
+ rdev_munmap(rd, mapping);
if (memcmp(file.magic, CBFS_FILE_MAGIC, sizeof(file.magic))) {
offset++;
@@ -108,10 +136,6 @@ int cbfs_locate(struct region_device *fh, const struct cbfsd *cbfs,
continue;
}
- file.len = ntohl(file.len);
- file.type = ntohl(file.type);
- file.offset = ntohl(file.offset);
-
/* See if names match. */
fname = rdev_mmap(rd, offset + fsz, file.offset - fsz);
More information about the coreboot-gerrit
mailing list