[coreboot-gerrit] Patch set updated for coreboot: 7c9e511 Remove unnecessary mappings in cbfs_media

Naman Govil (namangov@gmail.com) gerrit at coreboot.org
Mon Jun 30 19:40:37 CEST 2014


Naman Govil (namangov at gmail.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/6169

-gerrit

commit 7c9e511163197db9e57c874212a1c9574f2a1f47
Author: Naman Govil <namangov at gmail.com>
Date:   Mon Jun 30 22:57:11 2014 +0530

    Remove unnecessary mappings in cbfs_media
    
    Reducing the sram usage while booting by removing unwanted map()s by creating
    a structure to replace it with appropriate read()s
    
    Change-Id: If503368553308a2fdd3ecc1a312a11f14c7a707f
    Signed-off-by: Naman Govil <namangov at gmail.com>
---
 src/include/cbfs_core.h |  19 ++++-
 src/lib/cbfs.c          |  72 +++++++++++++------
 src/lib/cbfs_core.c     | 182 +++++++++++++++++++++++++++++++-----------------
 3 files changed, 188 insertions(+), 85 deletions(-)

diff --git a/src/include/cbfs_core.h b/src/include/cbfs_core.h
index a1d8127..6e0193a 100644
--- a/src/include/cbfs_core.h
+++ b/src/include/cbfs_core.h
@@ -4,6 +4,7 @@
  * Copyright (C) 2008 Jordan Crouse <jordan at cosmicpenguin.net>
  * Copyright (C) 2012 Google, Inc.
  * Copyright (C) 2013 The Chromium OS Authors. All rights reserved.
+ * Copyright (C) 2014 Naman Govil <namangov at gmail.com>
  *
  * This file is dual-licensed. You can choose between:
  *   - The GNU GPL, version 2, as published by the Free Software Foundation
@@ -189,6 +190,13 @@ struct cbfs_optionrom {
 #define CBFS_MEDIA_INVALID_MAP_ADDRESS	((void*)(0xffffffff))
 #define CBFS_DEFAULT_MEDIA		((void*)(0x0))
 
+struct cbfs_file_handler {
+	uint32_t found;
+	uint32_t data_offset;
+	uint32_t data_len;
+	struct cbfs_file file;
+};
+
 /* Media for CBFS to load files. */
 struct cbfs_media {
 
@@ -220,9 +228,6 @@ struct cbfs_media {
 /* returns pointer to a file entry inside CBFS or NULL */
 struct cbfs_file *cbfs_get_file(struct cbfs_media *media, const char *name);
 
-/* returns pointer to file content inside CBFS after if type is correct */
-void *cbfs_get_file_content(struct cbfs_media *media, const char *name,
-			    int type, size_t *sz);
 
 /* returns decompressed size on success, 0 on failure */
 int cbfs_decompress(int algo, void *src, void *dst, int len);
@@ -231,6 +236,14 @@ int cbfs_decompress(int algo, void *src, void *dst, int len);
  *  on failure */
 const struct cbfs_header *cbfs_get_header(struct cbfs_media *media);
 
+/*Returns success (0) on finding the file requested by verifying name/type; -1 if file not found
+ The absolute data_offset to the file is stored*/
+int cbfs_find_file(struct cbfs_media *media, struct cbfs_file_handler *f, const char *name, int type);
+
+
+/* returns pointer to file content inside CBFS after verifying if type is correct */
+void *cbfs_get_file_content(struct cbfs_media *media, const char *name, int type, size_t *sz);
+
 #endif /* __ROMCC__ */
 
 #endif
diff --git a/src/lib/cbfs.c b/src/lib/cbfs.c
index dc08937..d349383 100644
--- a/src/lib/cbfs.c
+++ b/src/lib/cbfs.c
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 2008, Jordan Crouse <jordan at cosmicpenguin.net>
  * Copyright (C) 2013 The Chromium OS Authors. All rights reserved.
- *
+ * Copyright (C) 2014, Naman Govil <namangov at gmail.com>
  * 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.
@@ -119,39 +119,71 @@ void *cbfs_load_optionrom(struct cbfs_media *media, uint16_t vendor,
 
 void * cbfs_load_stage(struct cbfs_media *media, const char *name)
 {
-	struct cbfs_stage *stage = (struct cbfs_stage *)
-		cbfs_get_file_content(media, name, CBFS_TYPE_STAGE, NULL);
+	struct cbfs_file_handler f;
+	struct cbfs_stage stage;
+	int c;
+	ssize_t value_read;
+	void * data;
+	ssize_t v_read;
+	struct cbfs_media default_media;
+
+	if (media == CBFS_DEFAULT_MEDIA) {
+			media = &default_media;
+			if (init_default_cbfs_media(media) != 0) {
+			ERROR("Failed to initialize default media.\n");
+			return NULL;
+		}
+	}
+
+	c = cbfs_find_file(media, &f, name, CBFS_TYPE_STAGE);
+	if (c == 0) {
+	value_read = media->read(media, &stage, f.data_offset, sizeof(stage));
 	/* this is a mess. There is no ntohll. */
 	/* for now, assume compatible byte order until we solve this. */
 	uint32_t entry;
 	uint32_t final_size;
 
-	if (stage == NULL)
+	DEBUG("Read Complete @offset = 0x%x and length = %d\n", f.data_offset, value_read);
+	if (value_read != sizeof(stage))
 		return (void *) -1;
 
 	LOG("loading stage %s @ 0x%x (%d bytes), entry @ 0x%llx\n",
 			name,
-			(uint32_t) stage->load, stage->memlen,
-			stage->entry);
-
-	final_size = cbfs_decompress(stage->compression,
-				     ((unsigned char *) stage) +
-				     sizeof(struct cbfs_stage),
-				     (void *) (uint32_t) stage->load,
-				     stage->len);
-	if (!final_size)
-		return (void *) -1;
+			(uint32_t) stage.load, stage.memlen,
+			stage.entry);
 
-	/* Stages rely the below clearing so that the bss is initialized. */
-	memset((void *)((uintptr_t)stage->load + final_size), 0,
-	       stage->memlen - final_size);
 
-	DEBUG("stage loaded.\n");
+	if(stage.compression == CBFS_COMPRESS_NONE) //i.e no compression
+	{
+		//No compression; hence we can directly read
+		DEBUG("Read Done\n");
+		v_read = media->read(media, (void *) (uintptr_t) stage.load, f.data_offset + sizeof(stage), f.data_len);
+		final_size = f.data_len;
+	}
+	else
+	{
+		data = media->map(media, f.data_offset + sizeof(stage), f.data_len);
+		DEBUG("Map Done\n");
+		final_size = cbfs_decompress(stage.compression, data,
+				     (void *) (uint32_t) stage.load,
+				     stage.len);
+
+		if (!final_size)
+			return (void *) -1;
+	}
 
-	entry = stage->entry;
-	// entry = ntohll(stage->entry);
+	/* Stages rely the below clearing so that the bss is initialized. */
+	memset((void *)((uintptr_t)stage.load + final_size), 0,
+	       stage.memlen - final_size);
 
+	DEBUG("stage loaded.\n");
+	entry = stage.entry;
 	return (void *) entry;
+
+	} else {
+		ERROR("Stage not loaded\n");
+		return (void *)-1;
+	}
 }
 
 /* Simple buffer */
diff --git a/src/lib/cbfs_core.c b/src/lib/cbfs_core.c
index 50c037e..10e23f1 100644
--- a/src/lib/cbfs_core.c
+++ b/src/lib/cbfs_core.c
@@ -3,6 +3,7 @@
  *
  * Copyright (C) 2011 secunet Security Networks AG
  * Copyright (C) 2013 The Chromium OS Authors. All rights reserved.
+ * Copyright (C) 2014 Naman Govil <namangov at gmail.com>
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -56,8 +57,10 @@
  *  on failure */
 const struct cbfs_header *cbfs_get_header(struct cbfs_media *media)
 {
-	const struct cbfs_header *header;
+	struct cbfs_header header;
+	const struct cbfs_header *h;
 	struct cbfs_media default_media;
+	ssize_t header_size;
 
 	if (media == CBFS_DEFAULT_MEDIA) {
 		media = &default_media;
@@ -70,133 +73,188 @@ const struct cbfs_header *cbfs_get_header(struct cbfs_media *media)
 	media->open(media);
 	DEBUG("CBFS_HEADER_ROM_ADDRESS: 0x%x/0x%x\n", CBFS_HEADER_ROM_ADDRESS,
 	      CONFIG_ROM_SIZE);
-	header = media->map(media, CBFS_HEADER_ROM_ADDRESS, sizeof(*header));
+	header_size = media->read(media, &header, CBFS_HEADER_ROM_ADDRESS, sizeof(header));
+	//size of mapping (now read) is 32 bytes
 	media->close(media);
 
-	if (header == CBFS_MEDIA_INVALID_MAP_ADDRESS) {
+	if (header_size == sizeof(header)) {
 		ERROR("Failed to load CBFS header from 0x%x\n",
 		      CBFS_HEADER_ROM_ADDRESS);
 		return CBFS_HEADER_INVALID_ADDRESS;
 	}
 
-	if (CBFS_HEADER_MAGIC != ntohl(header->magic)) {
+	if (CBFS_HEADER_MAGIC != ntohl(header.magic)) {
 		ERROR("Could not find valid CBFS master header at %x: "
 		      "%x vs %x.\n", CBFS_HEADER_ROM_ADDRESS, CBFS_HEADER_MAGIC,
-		      ntohl(header->magic));
-		if (header->magic == 0xffffffff) {
+		      ntohl(header.magic));
+		if (header.magic == 0xffffffff) {
 			ERROR("Maybe ROM is not mapped properly?\n");
 		}
 		return CBFS_HEADER_INVALID_ADDRESS;
 	}
-	return header;
+
+	h = &header;
+	return h;
 }
 
 /* public API starts here*/
-struct cbfs_file *cbfs_get_file(struct cbfs_media *media, const char *name)
+/* This functions finds the absolute data_offset of a file searched for by name/type
+   Returns 0 on success and -1 on failure
+ */
+int cbfs_find_file(struct cbfs_media *media, struct cbfs_file_handler *f, const char *name, int type)
 {
-	const char *file_name;
-	uint32_t offset, align, romsize, name_len;
-	const struct cbfs_header *header;
-	struct cbfs_file file, *file_ptr;
+	uint32_t offset, align, romsize,name_len;
 	struct cbfs_media default_media;
+	const struct cbfs_header *header;
+	ssize_t value_read;
+	const char *file_name;
 
 	if (media == CBFS_DEFAULT_MEDIA) {
 		media = &default_media;
 		if (init_default_cbfs_media(media) != 0) {
 			ERROR("Failed to initialize default media.\n");
-			return NULL;
+			return -1;
 		}
 	}
 
 	if (CBFS_HEADER_INVALID_ADDRESS == (header = cbfs_get_header(media)))
-		return NULL;
+		return -1; // error
 
 	// Logical offset (for source media) of first file.
+	// Now we know where the file lives
 	offset = ntohl(header->offset);
 	align = ntohl(header->align);
 	romsize = ntohl(header->romsize);
 
-	// TODO Add a "size" in CBFS header for a platform independent way to
-	// determine the end of CBFS data.
 #if defined(CONFIG_ARCH_X86) && CONFIG_ARCH_X86
 	romsize -= htonl(header->bootblocksize);
 #endif
+	int catch;
 	DEBUG("CBFS location: 0x%x~0x%x, align: %d\n", offset, romsize, align);
-
 	DEBUG("Looking for '%s' starting from 0x%x.\n", name, offset);
 	media->open(media);
-	while (offset < romsize &&
-	       media->read(media, &file, offset, sizeof(file)) == sizeof(file)) {
-		if (memcmp(CBFS_FILE_MAGIC, file.magic,
-			   sizeof(file.magic)) != 0) {
+	while (offset < romsize)
+	{
+		value_read = media->read(media, &f->file, offset, sizeof(f->file));
+		if(value_read != sizeof(f->file)){
+			return -1; //error: since read not successful
+			break;
+		}
+		//make all ntohl() at once place to avoid any gibberish later
+		f->file.len = ntohl(f->file.len);
+		f->file.offset = ntohl(f->file.offset);
+		f->file.type = ntohl(f->file.type);
+
+		if (memcmp(CBFS_FILE_MAGIC, f->file.magic,
+			   sizeof(f->file.magic)) != 0) {
 			uint32_t new_align = align;
 			if (offset % align)
 				new_align += align - (offset % align);
-			ERROR("ERROR: No file header found at 0x%x - "
-			      "try next aligned address: 0x%x.\n", offset,
-			      offset + new_align);
+			ERROR("ERROR: No file header found at 0x%x - try next aligned address: 0x%x.\n", offset,offset+new_align);
 			offset += new_align;
 			continue;
+			//continuing with new offset
 		}
-		name_len = ntohl(file.offset) - sizeof(file);
-		DEBUG(" - load entry 0x%x file name (%d bytes)...\n", offset,
-		      name_len);
-
-		// load file name (arbitrary length).
-		file_name = (const char *)media->map(
-				media, offset + sizeof(file), name_len);
-		if (file_name == CBFS_MEDIA_INVALID_MAP_ADDRESS) {
-			ERROR("ERROR: Failed to get filename: 0x%x.\n", offset);
-		} else if (strcmp(file_name, name) == 0) {
-			int file_offset = ntohl(file.offset),
-			    file_len = ntohl(file.len);
-			DEBUG("Found file (offset=0x%x, len=%d).\n",
-			    offset + file_offset, file_len);
-			media->unmap(media, file_name);
-			file_ptr = media->map(media, offset,
-					      file_offset + file_len);
-			media->close(media);
-			return file_ptr;
-		} else {
-			DEBUG(" (unmatched file @0x%x: %s)\n", offset,
-			      file_name);
-			media->unmap(media, file_name);
-		}
 
+		f->found = -1;
+		if(f->file.type == type){
+
+			name_len = f->file.offset - sizeof(f->file);
+			DEBUG(" - load entry 0x%x file name (%d bytes)...\n", offset,name_len);
+			// load file name (arbitrary length).
+			file_name = (const char *)media->map(media, offset + sizeof(f->file), name_len);
+			//this mapping done to verify name of file
+			if (file_name == CBFS_MEDIA_INVALID_MAP_ADDRESS) {
+				ERROR("ERROR: Failed to get filename: 0x%x.\n", offset);
+			} else if (strcmp(file_name, name) == 0) {
+					f->found = 0;
+					f->data_offset = offset + f->file.offset;
+					f->data_len = f->file.len;
+					media->unmap(media, file_name);
+					DEBUG("Found file:offset = 0x%x, len=%d\n", f->data_offset, f->data_len);
+					catch = f->found;
+					return catch;
+			} else {
+				DEBUG("unmatched file offset = 0x%x : %s\n", offset, file_name);
+				media->unmap(media,file_name);
+			}
+		}
 		// Move to next file.
-		offset += ntohl(file.len) + ntohl(file.offset);
+		offset += f->file.len + f->file.offset;
 		if (offset % align)
 			offset += align - (offset % align);
+		DEBUG("Going for next offset\n");
 	}
 	media->close(media);
-	LOG("WARNING: '%s' not found.\n", name);
-	return NULL;
+	LOG("Warning: '%s' not found\n",name);
+	return -1;
 }
 
-void *cbfs_get_file_content(struct cbfs_media *media, const char *name,
-			    int type, size_t *sz)
+
+/*Returns pointer to file content inside CBFS after verifying type
+ */
+void *cbfs_get_file_content(struct cbfs_media *media, const char *name, int type, size_t *sz)
 {
-	struct cbfs_file *file = cbfs_get_file(media, name);
+	struct cbfs_file_handler f;
+	int c;
+	struct cbfs_media default_media;
 
+	if (media == CBFS_DEFAULT_MEDIA) {
+		media = &default_media;
+		if (init_default_cbfs_media(media) != 0) {
+			ERROR("Failed to initialize default media.\n");
+			return NULL;
+		}
+	}
+	c = cbfs_find_file(media, &f, name, type);
+	if (c == 0){
+	DEBUG("Found file. Will be mapping it now!\n");
 	if (sz)
 		*sz = 0;
 
-	if (file == NULL) {
-		ERROR("Could not find file '%s'.\n", name);
+	if (f.file.type != type) {
+		ERROR("File '%s' is of type %x, but we requested %x.\n", name, f.file.type, type);
 		return NULL;
 	}
 
-	if (ntohl(file->type) != type) {
-		ERROR("File '%s' is of type %x, but we requested %x.\n", name,
-		      ntohl(file->type), type);
+	if (sz)
+		*sz = f.data_len;
+	return media->map(media, f.data_offset, f.data_len + f.file.offset);
+	}
+	else {
+		DEBUG("condition not successful\n");
+		ERROR("File Not Found\n");
 		return NULL;
 	}
+}
 
-	if (sz)
-		*sz = ntohl(file->len);
+/*void cbfs_get_data(struct cbfs_media *media, const char *name, int type)
+{
+	struct cbfs_file_handler f;
+	ssize_t value_read;
+	int c;
+	c = cbfs_find_file(media, &f, name, type);
+	if (c == 0){
+		DEBUG("File has been found and can be read\n");
+		uint32_t loop_offset = f.data_offset + f.file.offset;
+		uint32_t loop_align = f.align;
+
+		while (f.data_len > 0){
+
+			struct cbfs_file file;
+			value_read = media->read(media, &file, loop_offset , sizeof(file));
+			loop_offset += file.len + file.offset;
+			if (loop_offset % loop_align)
+				loop_offset += loop_align = (loop_offset % loop_align);
+			f.data_len -= sizeof(file);
+		}
+	}
+	else {
+		ERROR("File not found\n");
+	}
 
-	return (void *)CBFS_SUBHEADER(file);
 }
+*/
 
 int cbfs_decompress(int algo, void *src, void *dst, int len)
 {



More information about the coreboot-gerrit mailing list