Hung-Te Lin (hun...@chromium.org) just uploaded a new patch set to gerrit, 
which you can find at http://review.coreboot.org/2206

-gerrit

commit b121861b6b238f0c3b8a7aeeda33ab718333566a
Author: Hung-Te Lin <hun...@chromium.org>
Date:   Tue Jan 29 02:15:49 2013 +0800

    cbfstool: Use cbfs_image API for "print" command.
    
    First attempt to process CBFS ROM image by cbfs_image API.
    To verify, run "cbfstool coreboot.rom print -v" and compare with old 
cbfstool.
    
    Change-Id: I3a5a9ef176596d825e6cdba28a8ad732f69f5600
    Signed-off-by: Hung-Te Lin <hun...@chromium.org>
---
 util/cbfstool/cbfs.h       |   1 +
 util/cbfstool/cbfs_image.c | 209 +++++++++++++++++++++++++++++++++++++++++++++
 util/cbfstool/cbfs_image.h |  17 ++++
 util/cbfstool/cbfstool.c   |  13 ++-
 4 files changed, 232 insertions(+), 8 deletions(-)

diff --git a/util/cbfstool/cbfs.h b/util/cbfstool/cbfs.h
index 4a3ff94..35d0670 100644
--- a/util/cbfstool/cbfs.h
+++ b/util/cbfstool/cbfs.h
@@ -108,6 +108,7 @@ struct cbfs_payload {
 #define CBFS_COMPONENT_NULL 0xFFFFFFFF
 
 int cbfs_file_header(unsigned long physaddr);
+#define CBFS_NAME(_c) (((char *) (_c)) + sizeof(struct cbfs_file))
 #define CBFS_SUBHEADER(_p) ( (void *) ((((uint8_t *) (_p)) + 
ntohl((_p)->offset))) )
 
 struct cbfs_file *cbfs_create_empty_file(uint32_t physaddr, uint32_t size);
diff --git a/util/cbfstool/cbfs_image.c b/util/cbfstool/cbfs_image.c
index 569d108..d16ca0f 100644
--- a/util/cbfstool/cbfs_image.c
+++ b/util/cbfstool/cbfs_image.c
@@ -17,6 +17,7 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA, 02110-1301 USA
  */
 
+#include <inttypes.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -37,6 +38,65 @@ static uint32_t align_up(uint32_t value, uint32_t align) {
        return value;
 }
 
+/* Type and format */
+
+struct typedesc_t {
+       uint32_t type;
+       const char *name;
+};
+
+static struct typedesc_t types_cbfs_entry[] = {
+       {CBFS_COMPONENT_STAGE, "stage"},
+       {CBFS_COMPONENT_PAYLOAD, "payload"},
+       {CBFS_COMPONENT_OPTIONROM, "optionrom"},
+       {CBFS_COMPONENT_BOOTSPLASH, "bootsplash"},
+       {CBFS_COMPONENT_RAW, "raw"},
+       {CBFS_COMPONENT_VSA, "vsa"},
+       {CBFS_COMPONENT_MBI, "mbi"},
+       {CBFS_COMPONENT_MICROCODE, "microcode"},
+       {CBFS_COMPONENT_CMOS_DEFAULT, "cmos_default"},
+       {CBFS_COMPONENT_CMOS_LAYOUT, "cmos_layout"},
+       {CBFS_COMPONENT_DELETED, "deleted"},
+       {CBFS_COMPONENT_NULL, "null"},
+       {0, NULL},
+};
+
+static struct typedesc_t types_cbfs_compression[] = {
+       {CBFS_COMPRESS_NONE, "none"},
+       {CBFS_COMPRESS_LZMA, "LZMA"},
+       {0, NULL},
+};
+
+uint32_t lookup_type_by_name(struct typedesc_t *desc, const char *name,
+                            uint32_t default_value) {
+       int i;
+       for (i = 0; desc[i].name; i++)
+               if (strcmp(desc[i].name, name) == 0)
+                       return desc[i].type;
+       return default_value;
+}
+
+const char *lookup_name_by_type(struct typedesc_t *desc, uint32_t type,
+                               const char *default_value) {
+       int i;
+       for (i = 0; desc[i].name; i++)
+               if (desc[i].type == type)
+                       return desc[i].name;
+       return default_value;
+}
+
+uint32_t get_cbfs_entry_type(const char *name, uint32_t default_value) {
+       return lookup_type_by_name(types_cbfs_entry, name, default_value);
+}
+
+const char *get_cbfs_entry_type_name(uint32_t type) {
+       return lookup_name_by_type(types_cbfs_entry, type, "(unknown)");
+}
+
+uint32_t get_cbfs_compression(const char *name, uint32_t unknown) {
+       return lookup_type_by_name(types_cbfs_compression, name, unknown);
+}
+
 int cbfs_image_from_file(struct cbfs_image *image, const char *filename) {
        if (buffer_from_file(&image->buffer, filename) != 0)
                return -1;
@@ -64,6 +124,155 @@ int cbfs_image_delete(struct cbfs_image *image) {
        return 0;
 }
 
+int cbfs_print_header_info(struct cbfs_image *image) {
+       assert(image && image->header);
+       printf("%s: %zd kB, bootblocksize %d, romsize %d, offset 0x%x\n"
+              "alignment: %d bytes\n\n",
+              simple_basename(image->buffer.name),
+              image->buffer.size / 1024,
+              ntohl(image->header->bootblocksize),
+              ntohl(image->header->romsize),
+              ntohl(image->header->offset),
+              ntohl(image->header->align));
+       return 0;
+}
+
+static int cbfs_print_stage_info(struct cbfs_stage *stage, FILE* fp) {
+       fprintf(fp,
+               "    %s compression, entry: 0x%" PRIx64 ", load: 0x%" PRIx64 ", 
"
+               "length: %d/%d\n",
+               lookup_name_by_type(types_cbfs_compression,
+                                   stage->compression, "(unknown)"),
+               stage->entry,
+               stage->load,
+               stage->len,
+               stage->memlen);
+       return 0;
+}
+
+static int cbfs_print_payload_segment_info(struct cbfs_payload_segment 
*payload,
+                                          FILE *fp)
+{
+       switch(payload->type) {
+               case PAYLOAD_SEGMENT_CODE:
+               case PAYLOAD_SEGMENT_DATA:
+                       fprintf(fp, "    %s (%s compression, offset: 0x%x, "
+                               "load: 0x%" PRIx64 ", length: %d/%d)\n",
+                               (payload->type == PAYLOAD_SEGMENT_CODE ?
+                                "code " : "data"),
+                               lookup_name_by_type(types_cbfs_compression,
+                                                   ntohl(payload->compression),
+                                                   "(unknown)"),
+                               ntohl(payload->offset),
+                               ntohll(payload->load_addr),
+                               ntohl(payload->len), ntohl(payload->mem_len));
+                       break;
+
+               case PAYLOAD_SEGMENT_ENTRY:
+                       fprintf(fp, "    entry (0x%" PRIx64 ")\n",
+                               ntohll(payload->load_addr));
+                       break;
+
+               case PAYLOAD_SEGMENT_BSS:
+                       fprintf(fp, "    BSS (address 0x%016" PRIx64 ", "
+                               "length 0x%x)\n",
+                               ntohll(payload->load_addr),
+                               ntohl(payload->len));
+                       break;
+
+               case PAYLOAD_SEGMENT_PARAMS:
+                       fprintf(fp, "    parameters\n");
+                       break;
+
+               default:
+                       fprintf(fp, "   0x%x (%s compression, offset: 0x%x, "
+                               "load: 0x%" PRIx64 ", length: %d/%d\n",
+                               payload->type,
+                               lookup_name_by_type(types_cbfs_compression,
+                                                   payload->compression,
+                                                   "(unknown)"),
+                               ntohl(payload->offset),
+                               ntohll(payload->load_addr),
+                               ntohl(payload->len),
+                               ntohl(payload->mem_len));
+                       break;
+       }
+       return 0;
+}
+
+int cbfs_print_entry_info(struct cbfs_image *image, struct cbfs_file *entry,
+                         void *arg) {
+       const char *name = CBFS_NAME(entry);
+       struct cbfs_payload_segment *payload;
+       FILE *fp = (FILE *)arg;
+
+       if (!cbfs_is_valid_entry(entry)) {
+               ERROR("cbfs_print_entry_info: Invalid entry at 0x%x\n",
+                     cbfs_get_entry_addr(image, entry));
+               return -1;
+       }
+       if (!fp)
+               fp = stdout;
+
+       fprintf(fp, "%-30s 0x%-8x %-12s %d\n",
+               *name ? name : "(empty)",
+               cbfs_get_entry_addr(image, entry),
+               get_cbfs_entry_type_name(ntohl(entry->type)),
+               ntohl(entry->len));
+
+       if (!verbose)
+               return 0;
+
+       DEBUG(" cbfs_file=0x%x, offset=0x%x, content_address=0x%x+0x%x\n",
+             cbfs_get_entry_addr(image, entry), ntohl(entry->offset),
+             cbfs_get_entry_addr(image, entry) + ntohl(entry->offset),
+             ntohl(entry->len));
+
+       /* note the components of the subheader may be in host order ... */
+       switch (ntohl(entry->type)) {
+               case CBFS_COMPONENT_STAGE:
+                       cbfs_print_stage_info((struct cbfs_stage *)
+                                             CBFS_SUBHEADER(entry), fp);
+                       break;
+
+               case CBFS_COMPONENT_PAYLOAD:
+                       payload  = (struct cbfs_payload_segment *)
+                                       CBFS_SUBHEADER(entry);
+                       while (payload) {
+                               cbfs_print_payload_segment_info(payload, fp);
+                               if (payload->type == PAYLOAD_SEGMENT_ENTRY)
+                                       break;
+                               else
+                                       payload ++;
+                       }
+                       break;
+               default:
+                       break;
+       }
+       return 0;
+}
+
+int cbfs_print_directory(struct cbfs_image *image) {
+       cbfs_print_header_info(image);
+       printf("%-30s %-10s %-12s Size\n", "Name", "Offset", "Type");
+       cbfs_walk(image, cbfs_print_entry_info, NULL);
+       return 0;
+}
+
+int cbfs_walk(struct cbfs_image *image, cbfs_entry_callback callback,
+             void *arg) {
+       int count = 0;
+       struct cbfs_file *entry;
+       for (entry = cbfs_find_first_entry(image);
+            entry && cbfs_is_valid_entry(entry);
+            entry = cbfs_find_next_entry(image, entry)) {
+               count ++;
+               if (callback(image, entry, arg) != 0)
+                       break;
+       }
+       return count;
+}
+
 struct cbfs_header *cbfs_find_header(char *data, size_t size) {
        size_t offset;
        int found = 0;
diff --git a/util/cbfstool/cbfs_image.h b/util/cbfstool/cbfs_image.h
index 617a716..ed8be5a 100644
--- a/util/cbfstool/cbfs_image.h
+++ b/util/cbfstool/cbfs_image.h
@@ -38,6 +38,17 @@ int cbfs_image_write_file(struct cbfs_image *image, const 
char *filename);
 /* Releases the CBFS image. Returns 0 on success, otherwise non-zero. */
 int cbfs_image_delete(struct cbfs_image *image);
 
+/* Callback function used by cbfs_walk.
+ * Returns 0 on success, or non-zero to stop further iteration. */
+typedef int (*cbfs_entry_callback)(struct cbfs_image *image,
+                                  struct cbfs_file *file,
+                                  void *arg);
+
+/* Iterates through all entries in CBFS image, and invoke with callback.
+ * Stops if callback returns non-zero values.
+ * Returns number of entries invoked. */
+int cbfs_walk(struct cbfs_image *image, cbfs_entry_callback callback, void 
*arg);
+
 /* Primitive CBFS utilities */
 
 /* Returns a pointer to the only valid CBFS header in give buffer, otherwise
@@ -62,4 +73,10 @@ uint32_t cbfs_get_entry_addr(struct cbfs_image *image, 
struct cbfs_file *entry);
 /* Returns 1 if entry has valid data (by checking magic number), otherwise 0. 
*/
 int cbfs_is_valid_entry(struct cbfs_file *entry);
 
+/* Print CBFS component information. */
+int cbfs_print_directory(struct cbfs_image *image);
+int cbfs_print_header_info(struct cbfs_image *image);
+int cbfs_print_entry_info(struct cbfs_image *image, struct cbfs_file *entry,
+                         void *arg);
+
 #endif
diff --git a/util/cbfstool/cbfstool.c b/util/cbfstool/cbfstool.c
index edab7e3..5e4f8f1 100644
--- a/util/cbfstool/cbfstool.c
+++ b/util/cbfstool/cbfstool.c
@@ -27,6 +27,7 @@
 #include <getopt.h>
 #include "common.h"
 #include "cbfs.h"
+#include "cbfs_image.h"
 
 struct command {
        const char *name;
@@ -388,18 +389,14 @@ static int cbfs_locate_stage(void)
 
 static int cbfs_print(void)
 {
-       void *rom;
-
-       rom = loadrom(param.cbfs_name);
-       if (rom == NULL) {
+       struct cbfs_image image;
+       if (cbfs_image_from_file(&image, param.cbfs_name) != 0) {
                ERROR("Could not load ROM image '%s'.\n",
                        param.cbfs_name);
                return 1;
        }
-
-       print_cbfs_directory(param.cbfs_name);
-
-       free(rom);
+       cbfs_print_directory(&image);
+       cbfs_image_delete(&image);
        return 0;
 }
 

-- 
coreboot mailing list: coreboot@coreboot.org
http://www.coreboot.org/mailman/listinfo/coreboot

Reply via email to