[coreboot] r3288 - in trunk/payloads/libpayload: include include/arch libc

svn at coreboot.org svn at coreboot.org
Wed May 7 22:34:03 CEST 2008


Author: jcrouse
Date: 2008-05-07 22:34:02 +0200 (Wed, 07 May 2008)
New Revision: 3288

Added:
   trunk/payloads/libpayload/include/arch/endian.h
   trunk/payloads/libpayload/include/lar.h
   trunk/payloads/libpayload/libc/lar.c
Modified:
   trunk/payloads/libpayload/include/libpayload.h
   trunk/payloads/libpayload/libc/Makefile.inc
Log:
libpayload: Add LAR walking support

Add suport for walking LARs.  These try to emulate the f*
functions from POSIX, though they are obviously different
in their behavior.

Signed-off-by: Jordan Crouse <jordan.crouse at amd.com>
Acked-by: Myles Watson <mylesgw at gmail.com>


Added: trunk/payloads/libpayload/include/arch/endian.h
===================================================================
--- trunk/payloads/libpayload/include/arch/endian.h	                        (rev 0)
+++ trunk/payloads/libpayload/include/arch/endian.h	2008-05-07 20:34:02 UTC (rev 3288)
@@ -0,0 +1,46 @@
+/*
+ * This file is part of the libpayload project.
+ *
+ * Copyright (C) 2008 Advanced Micro Devices, Inc.
+ *
+ * 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 _ARCH_ENDIAN_H
+#define _ARCH_ENDIAN_H
+
+static u32 ntohl(u32 in)
+{
+	return ((in & 0xFF) << 24) | ((in & 0xFF00) << 8) |
+		((in & 0xFF0000) >> 8) | ((in & 0xFF000000) >> 24);
+}
+
+static u64 ntohll(u64 in)
+{
+	u32 h = in >> 32;
+	u32 l = in & 0xFFFFFFFF;
+
+	return (((u64) ntohl(l) << 32) | ((u64) ntohl(h)));
+}
+#endif

Added: trunk/payloads/libpayload/include/lar.h
===================================================================
--- trunk/payloads/libpayload/include/lar.h	                        (rev 0)
+++ trunk/payloads/libpayload/include/lar.h	2008-05-07 20:34:02 UTC (rev 3288)
@@ -0,0 +1,94 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2006 coresystems GmbH
+ * (Written by Stefan Reinauer <stepan at coresystems.de> for coresystems GmbH)
+ *
+ * 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 LAR_H
+#define LAR_H
+
+#include <arch/types.h>
+
+#define LAR_MAGIC "LARCHIVE"
+#define LAR_MAX_PATHLEN 1024
+
+struct lar_header {
+	char magic[8];
+	u32 len;
+	u32 reallen;
+	u32 checksum;
+	u32 compchecksum;
+	u32 offset;
+	/* Compression:
+	 * 0 = no compression
+	 * 1 = lzma
+	 * 2 = nrv2b
+	 * 3 = zeroes
+	 */
+	u32 compression;
+	u64 entry;
+	u64 loadaddress;
+};
+
+enum compalgo {
+	ALGO_NONE = 0,
+	ALGO_LZMA = 1,
+	ALGO_NRV2B = 2,
+	ALGO_ZEROES = 3,
+	/* invalid should always be the last entry. */
+	ALGO_INVALID
+};
+
+struct mem_file {
+	void *start;
+	int len;
+	u32 reallen;
+	u32 compression;
+	void *entry;
+	void *loadaddress;
+};
+
+#endif /* LAR_H */

Modified: trunk/payloads/libpayload/include/libpayload.h
===================================================================
--- trunk/payloads/libpayload/include/libpayload.h	2008-05-07 19:21:18 UTC (rev 3287)
+++ trunk/payloads/libpayload/include/libpayload.h	2008-05-07 20:34:02 UTC (rev 3288)
@@ -36,6 +36,7 @@
 #include <arch/io.h>
 #include <sysinfo.h>
 #include <stdarg.h>
+#include <lar.h>
 
 #define MIN(a,b) ((a) < (b) ? (a) : (b))
 #define MAX(a,b) ((a) > (b) ? (a) : (b))
@@ -207,6 +208,55 @@
 
 int gettimeofday(struct timeval *tv, void *tz);
 
+/* libc/lar.c */
+
+struct LAR {
+	void * start;
+	int cindex;
+	int count;
+	int alloc;
+	int eof;
+	void **headers;
+};
+
+struct larent {
+	u8 name[LAR_MAX_PATHLEN];
+};
+
+struct larstat {
+	u32 len;
+	u32 reallen;
+	u32 checksum;
+	u32 compchecksum;
+	u32 offset;
+	u32 compression;
+	u64 entry;
+	u64 loadaddress;
+};
+
+struct LFILE {
+	struct LAR *lar;
+	struct lar_header *header;
+	u32 size;
+	void *start;
+	u32 offset;
+};
+
+struct LAR *openlar(void *addr);
+int closelar(struct LAR *lar);
+struct larent *readlar(struct LAR *lar);
+void rewindlar(struct LAR *lar);
+int larstat(struct LAR *lar, const char *path, struct larstat *buf);
+struct LFILE * lfopen(struct LAR *lar, const char *filename);
+int lfread(void *ptr, size_t size, size_t nmemb, struct LFILE *stream);
+
+#define SEEK_SET 0
+#define SEEK_CUR 1
+#define SEEK_END 2
+
+int lfseek(struct LFILE *stream, long offset, int whence);
+int lfclose(struct LFILE *file);
+
 /* i386/coreboot.c */
 int get_coreboot_info(struct sysinfo_t *info);
 

Modified: trunk/payloads/libpayload/libc/Makefile.inc
===================================================================
--- trunk/payloads/libpayload/libc/Makefile.inc	2008-05-07 19:21:18 UTC (rev 3287)
+++ trunk/payloads/libpayload/libc/Makefile.inc	2008-05-07 20:34:02 UTC (rev 3288)
@@ -29,4 +29,4 @@
 
 TARGETS-y += libc/malloc.o libc/printf.o libc/console.o libc/string.o
 TARGETS-y += libc/memory.o libc/ctype.o libc/ipchecksum.o libc/lib.o
-TARGETS-y += libc/rand.o libc/time.o
+TARGETS-y += libc/rand.o libc/time.o libc/lar.o

Added: trunk/payloads/libpayload/libc/lar.c
===================================================================
--- trunk/payloads/libpayload/libc/lar.c	                        (rev 0)
+++ trunk/payloads/libpayload/libc/lar.c	2008-05-07 20:34:02 UTC (rev 3288)
@@ -0,0 +1,301 @@
+/*
+ * This file is part of the libpayload project.
+ *
+ * Copyright (C) 2008 Advanced Micro Devices, Inc.
+ *
+ * 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.
+ */
+
+#include <libpayload.h>
+#include <arch/endian.h>
+
+#define ROM_RESET_VECTOR 0xFFFFFFF0
+
+static void * next_header(void * cur)
+{
+	struct lar_header *header = (struct lar_header *) cur;
+	int offset = ((ntohl(header->offset) + ntohl(header->len)) + 15) &
+		0xFFFFFFF0;
+
+	return (void *) (cur + offset);
+}
+
+static struct lar_header *lar_get_header(struct LAR *lar, int index)
+{
+	int i;
+
+	if (index < lar->count)
+		return (struct lar_header *) lar->headers[index];
+
+	if (lar->eof && index >= lar->eof)
+		return NULL;
+
+	for(i = lar->count; i <= index; i++) {
+		void *next = (i == 0) ?
+			lar->start : next_header(lar->headers[i - 1]);
+
+		if (strncmp((const char *) next, LAR_MAGIC, 8)) {
+			lar->eof = lar->count;
+			return NULL;
+		}
+
+		if (lar->count == lar->alloc) {
+			void *tmp = realloc(lar->headers,
+					    (lar->alloc + 16) * sizeof(void *));
+
+			if (tmp == NULL)
+				return NULL;
+
+			lar->headers = tmp;
+			lar->alloc += 16;
+		}
+
+		lar->headers[lar->count++] = next;
+	}
+
+	return (struct lar_header *) lar->headers[index];
+}
+
+
+/**
+ * Open a LAR stream
+ *
+ * @param addr The address in memory where the LAR is located.
+ * Use NULL to specify the boot LAR
+ * @return a pointer to the LAR stream
+ */
+
+struct LAR *openlar(void *addr)
+{
+	struct LAR *lar;
+
+	/* If the address is null, then figure out the start of the
+	   boot LAR */
+
+	if (addr == NULL) {
+		u32 size = *((u32 *) (ROM_RESET_VECTOR + 4));
+		addr = (void *) ((ROM_RESET_VECTOR  + 16) - size);
+	}
+
+	/* Check the magic to make sure this is a LAR */
+	if (strncmp((const char *) addr, LAR_MAGIC, strlen(LAR_MAGIC)))
+		return NULL;
+
+	lar = calloc(sizeof(struct LAR), 1);
+
+	if (!lar)
+		return NULL;
+
+	lar->start = addr;
+
+	/* Preallocate 16 slots in the cache - this saves wear and
+	 * tear on the heap */
+
+	lar->headers = malloc(16 * sizeof(void *));
+	lar->alloc = 16;
+	lar->count = lar->eof = 0;
+	lar->cindex = 0;
+
+	return lar;
+}
+
+/**
+ * Close a LAR stream
+ *
+ * @param lar A pointer to the LAR stream
+ * @return Return 0 on success, -1 on error
+ */
+
+int closelar(struct LAR *lar)
+{
+	if (!lar)
+		return 0;
+
+	if (lar->headers)
+		free(lar->headers);
+
+	free(lar);
+
+	return 0;
+}
+
+/**
+ * Read an entry from the LAR
+ *
+ * @param lar A pointer to the LAR stream
+ * @return A pointer to a larent structure
+           representing the next file in the LAR
+ */
+
+struct larent *readlar(struct LAR *lar)
+{
+	static struct larent _larent;
+	struct lar_header *header;
+	int nlen;
+
+	if (!lar)
+		return NULL;
+
+	header = lar_get_header(lar, lar->cindex);
+
+	if (header == NULL)
+		return NULL;
+
+	nlen = ntohl(header->offset) - sizeof(*header);
+
+	if (nlen > LAR_MAX_PATHLEN - 1)
+		nlen = LAR_MAX_PATHLEN - 1;
+
+	memcpy((void *) _larent.name, ((char *) header + sizeof(*header)),
+		nlen);
+
+	_larent.name[nlen] = 0;
+
+	lar->cindex++;
+
+	return (struct larent *) &_larent;
+}
+
+void rewindlar(struct LAR *lar)
+{
+	if (lar != NULL)
+		lar->cindex = 0;
+}
+
+static struct lar_header *get_header_by_name(struct LAR *lar, const char *name)
+{
+	struct lar_header *header;
+	int i;
+
+	for(i = 0; ; i++) {
+		header = lar_get_header(lar, i);
+
+		if (header == NULL)
+			return NULL;
+
+		if (!strcmp(name, ((char *) header + sizeof(*header))))
+			return header;
+	}
+}
+
+int larstat(struct LAR *lar, const char *path, struct larstat *buf)
+{
+	struct lar_header *header = get_header_by_name(lar, path);
+
+	if (header == NULL || buf == NULL)
+		return -1;
+
+	buf->len = ntohl(header->len);
+	buf->reallen = ntohl(header->reallen);
+	buf->checksum = ntohl(header->checksum);
+	buf->compchecksum = ntohl(header->compchecksum);
+	buf->compression = ntohl(header->compression);
+	buf->entry = ntohll(header->entry);
+	buf->loadaddress = ntohll(header->loadaddress);
+	buf->offset = ((u32) header - (u32) lar->start) + ntohl(header->offset);
+
+	return 0;
+}
+
+struct LFILE * lfopen(struct LAR *lar, const char *filename)
+{
+	struct LFILE *file;
+	struct lar_header *header = get_header_by_name(lar, filename);
+
+	if (header == NULL)
+		return NULL;
+
+	/* FIXME: What other validations do we want to do on the file here? */
+
+	file = malloc(sizeof(struct LFILE));
+
+	if (file == NULL)
+		return NULL;
+
+	file->lar = lar;
+	file->header = header;
+	file->size = ntohl(header->len);
+	file->start = ((u8 *) header + ntohl(header->offset));
+	file->offset = 0;
+
+	return file;
+}
+
+void *lfmap(struct LFILE *file, int offset)
+{
+	if (file == NULL)
+		return (void *) -1;
+
+	if (offset > file->size)
+		return (void *) -1;
+
+	return (void *) (file->start + offset);
+};
+
+int lfread(void *ptr, size_t size, size_t nmemb, struct LFILE *stream)
+{
+	size_t tsize, actual;
+	size_t remain = stream->size - stream->offset;
+
+	if (!stream || !remain)
+		return 0;
+
+	tsize = (size * nmemb);
+	actual = (tsize > remain) ? remain : tsize;
+
+	memcpy(ptr, (void *) (stream->start + stream->offset), actual);
+	stream->offset += actual;
+
+	return actual;
+}
+
+int lfseek(struct LFILE *file, long offset, int whence)
+{
+	int o = file->offset;
+
+	switch(whence) {
+	case SEEK_SET:
+		o = offset;
+		break;
+	case SEEK_CUR:
+		o += offset;
+		break;
+
+	case SEEK_END:
+		return -1;
+	}
+
+	if (o < 0 || o > file->size)
+		return -1;
+
+	file->offset = o;
+	return file->offset;
+}
+
+int lfclose(struct LFILE *file)
+{
+	if (file)
+		free(file);
+	return 0;
+}





More information about the coreboot mailing list