Hello Nico Huber,
I'd like you to do a code review. Please visit
https://review.coreboot.org/19188
to review the following change.
Change subject: Give layouts their own type
......................................................................
Give layouts their own type
Introduce `struct fl_layout` and refactor layout.c a little, so we can
reuse the layout from there and have other sources of layouts beside it.
I didn't want to clutter up flash.h any more. So things went into a new
layout.h.
Change-Id: Ic728fc9f64958f62a2e2f321f4ec440e8658c808
Signed-off-by: Nico Huber <nico.huber(a)secunet.com>
---
M flash.h
M layout.c
A layout.h
3 files changed, 99 insertions(+), 50 deletions(-)
git pull ssh://review.coreboot.org:29418/flashrom refs/changes/88/19188/1
diff --git a/flash.h b/flash.h
index da049d1..bf381cf 100644
--- a/flash.h
+++ b/flash.h
@@ -37,6 +37,8 @@
#undef max
#endif
+#include "layout.h"
+
#define ERROR_PTR ((void*)-1)
/* Error codes */
@@ -46,14 +48,6 @@
/* TODO: check using code for correct usage of types */
typedef uintptr_t chipaddr;
#define PRIxPTR_WIDTH ((int)(sizeof(uintptr_t)*2))
-
-/* Types and macros regarding the maximum flash space size supported by generic code. */
-typedef uint32_t chipoff_t; /* Able to store any addressable offset within a supported flash memory. */
-typedef uint32_t chipsize_t; /* Able to store the number of bytes of any supported flash memory. */
-#define FL_MAX_CHIPOFF_BITS (24)
-#define FL_MAX_CHIPOFF ((chipoff_t)(1ULL<<FL_MAX_CHIPOFF_BITS)-1)
-#define PRIxCHIPOFF "06"PRIx32
-#define PRIuCHIPSIZE PRIu32
int register_shutdown(int (*function) (void *data), void *data);
int shutdown_free(void *data);
diff --git a/layout.c b/layout.c
index f71eeaa..9eadb22 100644
--- a/layout.c
+++ b/layout.c
@@ -25,24 +25,20 @@
#include <limits.h>
#include "flash.h"
#include "programmer.h"
+#include "layout.h"
-#define MAX_ROMLAYOUT 32
-
-typedef struct {
- chipoff_t start;
- chipoff_t end;
- unsigned int included;
- char name[256];
-} romentry_t;
-
-/* rom_entries store the entries specified in a layout file and associated run-time data */
-static romentry_t rom_entries[MAX_ROMLAYOUT];
-static int num_rom_entries = 0; /* the number of successfully parsed rom_entries */
+struct fl_romentry entries[MAX_ROMLAYOUT];
+static struct fl_layout layout = { entries, 0 };
/* include_args holds the arguments specified at the command line with -i. They must be processed at some point
- * so that desired regions are marked as "included" in the rom_entries list. */
+ * so that desired regions are marked as "included" in the layout. */
static char *include_args[MAX_ROMLAYOUT];
static int num_include_args = 0; /* the number of valid include_args. */
+
+const struct fl_layout *get_global_layout(void)
+{
+ return &layout;
+}
#ifndef __LIBPAYLOAD__
int read_romlayout(const char *name)
@@ -62,13 +58,13 @@
while (!feof(romlayout)) {
char *tstr1, *tstr2;
- if (num_rom_entries >= MAX_ROMLAYOUT) {
+ if (layout.num_entries >= MAX_ROMLAYOUT) {
msg_gerr("Maximum number of ROM images (%i) in layout "
"file reached.\n", MAX_ROMLAYOUT);
(void)fclose(romlayout);
return 1;
}
- if (2 != fscanf(romlayout, "%255s %255s\n", tempstr, rom_entries[num_rom_entries].name))
+ if (2 != fscanf(romlayout, "%255s %255s\n", tempstr, layout.entries[layout.num_entries].name))
continue;
#if 0
// fscanf does not like arbitrary comments like that :( later
@@ -83,16 +79,16 @@
(void)fclose(romlayout);
return 1;
}
- rom_entries[num_rom_entries].start = strtol(tstr1, (char **)NULL, 16);
- rom_entries[num_rom_entries].end = strtol(tstr2, (char **)NULL, 16);
- rom_entries[num_rom_entries].included = 0;
- num_rom_entries++;
+ layout.entries[layout.num_entries].start = strtol(tstr1, (char **)NULL, 16);
+ layout.entries[layout.num_entries].end = strtol(tstr2, (char **)NULL, 16);
+ layout.entries[layout.num_entries].included = 0;
+ layout.num_entries++;
}
- for (i = 0; i < num_rom_entries; i++) {
+ for (i = 0; i < layout.num_entries; i++) {
msg_gdbg("romlayout %08x - %08x named %s\n",
- rom_entries[i].start,
- rom_entries[i].end, rom_entries[i].name);
+ layout.entries[i].start,
+ layout.entries[i].end, layout.entries[i].name);
}
(void)fclose(romlayout);
@@ -140,13 +136,13 @@
{
int i;
- if (num_rom_entries == 0)
+ if (layout.num_entries == 0)
return -1;
msg_gspew("Looking for region \"%s\"... ", name);
- for (i = 0; i < num_rom_entries; i++) {
- if (!strcmp(rom_entries[i].name, name)) {
- rom_entries[i].included = 1;
+ for (i = 0; i < layout.num_entries; i++) {
+ if (!strcmp(layout.entries[i].name, name)) {
+ layout.entries[i].included = 1;
msg_gspew("found.\n");
return i;
}
@@ -167,7 +163,7 @@
return 0;
/* User has specified an area, but no layout file is loaded. */
- if (num_rom_entries == 0) {
+ if (layout.num_entries == 0) {
msg_gerr("Region requested (with -i \"%s\"), "
"but no layout data is available.\n",
include_args[0]);
@@ -200,22 +196,22 @@
}
num_include_args = 0;
- for (i = 0; i < num_rom_entries; i++) {
- rom_entries[i].included = 0;
+ for (i = 0; i < layout.num_entries; i++) {
+ layout.entries[i].included = 0;
}
- num_rom_entries = 0;
+ layout.num_entries = 0;
}
-romentry_t *get_next_included_romentry(unsigned int start)
+struct fl_romentry *get_next_included_romentry(unsigned int start)
{
int i;
unsigned int best_start = UINT_MAX;
- romentry_t *best_entry = NULL;
- romentry_t *cur;
+ struct fl_romentry *best_entry = NULL;
+ struct fl_romentry *cur;
/* First come, first serve for overlapping regions. */
- for (i = 0; i < num_rom_entries; i++) {
- cur = &rom_entries[i];
+ for (i = 0; i < layout.num_entries; i++) {
+ cur = &layout.entries[i];
if (!cur->included)
continue;
/* Already past the current entry? */
@@ -240,16 +236,16 @@
int ret = 0;
int i;
- for (i = 0; i < num_rom_entries; i++) {
- if (rom_entries[i].start >= total_size || rom_entries[i].end >= total_size) {
+ for (i = 0; i < layout.num_entries; i++) {
+ if (layout.entries[i].start >= total_size || layout.entries[i].end >= total_size) {
msg_gwarn("Warning: Address range of region \"%s\" exceeds the current chip's "
- "address space.\n", rom_entries[i].name);
- if (rom_entries[i].included)
+ "address space.\n", layout.entries[i].name);
+ if (layout.entries[i].included)
ret = 1;
}
- if (rom_entries[i].start > rom_entries[i].end) {
+ if (layout.entries[i].start > layout.entries[i].end) {
msg_gerr("Error: Size of the address range of region \"%s\" is not positive.\n",
- rom_entries[i].name);
+ layout.entries[i].name);
ret = 1;
}
}
@@ -281,7 +277,7 @@
int build_new_image(struct flashctx *flash, bool oldcontents_valid, uint8_t *oldcontents, uint8_t *newcontents)
{
unsigned int start = 0;
- romentry_t *entry;
+ struct fl_romentry *entry;
unsigned int size = flash->chip->total_size * 1024;
/* If no regions were specified for inclusion, assume
diff --git a/layout.h b/layout.h
new file mode 100644
index 0000000..3aebe8a
--- /dev/null
+++ b/layout.h
@@ -0,0 +1,59 @@
+/*
+ * This file is part of the flashrom project.
+ *
+ * Copyright (C) 2005-2008 coresystems GmbH
+ * (Written by Stefan Reinauer <stepan(a)coresystems.de> for coresystems GmbH)
+ * Copyright (C) 2011-2013 Stefan Tauner
+ * Copyright (C) 2016 secunet Security Networks AG
+ * (Written by Nico Huber <nico.huber(a)secunet.com> for secunet)
+ *
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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 __LAYOUT_H__
+#define __LAYOUT_H__ 1
+
+/* Types and macros regarding the maximum flash space size supported by generic code. */
+typedef uint32_t chipoff_t; /* Able to store any addressable offset within a supported flash memory. */
+typedef uint32_t chipsize_t; /* Able to store the number of bytes of any supported flash memory. */
+#define FL_MAX_CHIPOFF_BITS (24)
+#define FL_MAX_CHIPOFF ((chipoff_t)(1ULL<<FL_MAX_CHIPOFF_BITS)-1)
+#define PRIxCHIPOFF "06"PRIx32
+#define PRIuCHIPSIZE PRIu32
+
+#define MAX_ROMLAYOUT 32
+
+struct fl_romentry {
+ chipoff_t start;
+ chipoff_t end;
+ bool included;
+ char name[256];
+};
+
+struct fl_layout {
+ /* entries store the entries specified in a layout file and associated run-time data */
+ struct fl_romentry *entries;
+ /* the number of successfully parsed entries */
+ int num_entries;
+};
+
+struct fl_layout_single {
+ struct fl_layout base;
+ struct fl_romentry entry;
+};
+
+const struct fl_layout *get_global_layout(void);
+
+#endif /* !__LAYOUT_H__ */
--
To view, visit https://review.coreboot.org/19188
To unsubscribe, visit https://review.coreboot.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: Ic728fc9f64958f62a2e2f321f4ec440e8658c808
Gerrit-PatchSet: 1
Gerrit-Project: flashrom
Gerrit-Branch: staging
Gerrit-Owner: David Hendricks <david.hendricks(a)gmail.com>
Gerrit-Reviewer: Nico Huber <nico.h(a)gmx.de>
Hello Nico Huber,
I'd like you to do a code review. Please visit
https://review.coreboot.org/19189
to review the following change.
Change subject: Add functions to read/erase/write/verify by layout
......................................................................
Add functions to read/erase/write/verify by layout
Inspired by Lynxis' related work, this implements a foundation for
layout based flash access.
All operations iterate over the given layout regions. Erase and write
then walk, per region, over all erase blocks in an inner loop (which
might not be what we want, see note on optimization below). Special care
has been taken that flash content is merged properly, in case an erase
block is only partially covered by a layout region or even affects mul-
tiple regions.
A note on performance: In the case an erase block affects multiple
regions, it will probably be read, erased and written for each region.
Another approach would be to walk all erase blocks once and check for
each erase block which regions it touches (i.e. for each erase block,
merge data pontentially from the flash and all layout regions, then
flash the combined data). That might result in cleaner code. I haven't
tried it yet, though.
Change-Id: I060d9c42d71c83c3f95a6189cd22dad8b1504784
Signed-off-by: Nico Huber <nico.huber(a)secunet.com>
---
M flash.h
M flashrom.c
2 files changed, 327 insertions(+), 0 deletions(-)
git pull ssh://review.coreboot.org:29418/flashrom refs/changes/89/19189/1
diff --git a/flash.h b/flash.h
index bf381cf..be1134a 100644
--- a/flash.h
+++ b/flash.h
@@ -216,6 +216,7 @@
uintptr_t physical_registers;
chipaddr virtual_registers;
struct registered_master *mst;
+ const struct fl_layout *layout;
};
/* Timing used in probe routines. ZERO is -2 to differentiate between an unset
diff --git a/flashrom.c b/flashrom.c
index 1a43303..b6ba7e0 100644
--- a/flashrom.c
+++ b/flashrom.c
@@ -5,6 +5,8 @@
* Copyright (C) 2004 Tyan Corp <yhlu(a)tyan.com>
* Copyright (C) 2005-2008 coresystems GmbH
* Copyright (C) 2008,2009 Carl-Daniel Hailfinger
+ * Copyright (C) 2016 secunet Security Networks AG
+ * (Written by Nico Huber <nico.huber(a)secunet.com> for secunet)
*
* 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
@@ -1640,6 +1642,330 @@
return ret;
}
+/** @private */
+static const struct fl_layout *get_layout(const struct flashctx *const flashctx,
+ struct fl_layout_single *const fallback)
+{
+ if (flashctx->layout && flashctx->layout->num_entries)
+ return flashctx->layout;
+
+ fallback->base.entries = &fallback->entry;
+ fallback->base.num_entries = 1;
+ fallback->entry.start = 0;
+ fallback->entry.end = flashctx->chip->total_size * 1024 - 1;
+ fallback->entry.included = true;
+ strcpy(fallback->entry.name, "complete flash");
+ return &fallback->base;
+}
+
+/**
+ * @brief Reads the included layout regions into a buffer.
+ *
+ * If there is no layout set in the given flash context, the whole chip will
+ * be read.
+ *
+ * @param flashctx Flash context to be used.
+ * @param buffer Buffer of full chip size to read into.
+ * @return 0 on success,
+ * 1 if any read fails.
+ */
+static int read_by_layout(struct flashctx *const flashctx, void *const buffer)
+{
+ struct fl_layout_single fallback_layout;
+ const struct fl_layout *const layout = get_layout(flashctx, &fallback_layout);
+
+ size_t i;
+ for (i = 0; i < layout->num_entries; ++i) {
+ if (!layout->entries[i].included)
+ continue;
+
+ const chipoff_t region_start = layout->entries[i].start;
+ const chipsize_t region_len = layout->entries[i].end - layout->entries[i].start + 1;
+
+ if (flashctx->chip->read(flashctx, buffer + region_start, region_start, region_len))
+ return 1;
+ }
+ return 0;
+}
+
+typedef int (*erasefn_t)(struct flashctx *, unsigned int addr, unsigned int len);
+struct walk_info {
+ uint8_t *curcontents;
+ const uint8_t *newcontents;
+ unsigned int region_start;
+ unsigned int region_end;
+ unsigned int erase_start;
+ unsigned int erase_end;
+};
+typedef int (*per_blockfn_t)(struct flashctx *, const struct walk_info *, erasefn_t);
+
+/** @private */
+static int walk_eraseblocks(struct flashctx *const flashctx,
+ struct walk_info *const info,
+ const int erasefunction, per_blockfn_t per_blockfn)
+{
+ int ret;
+ int i, j;
+ bool first = true;
+ struct block_eraser *const eraser = &flashctx->chip->block_erasers[erasefunction];
+
+ info->erase_start = 0;
+ for (i = 0; i < NUM_ERASEREGIONS; i++) {
+ /* count==0 for all automatically initialized array
+ * members so the loop below won't be executed for them.
+ */
+ for (j = 0; j < eraser->eraseblocks[i].count; ++j, info->erase_start = info->erase_end + 1) {
+ info->erase_end = info->erase_start + eraser->eraseblocks[i].size - 1;
+
+ /* Skip any eraseblock that is completely outside the current region. */
+ if (info->erase_end < info->region_start || info->region_end < info->erase_start)
+ continue;
+
+ /* Print this for every block except the first one. */
+ if (first)
+ first = false;
+ else
+ msg_cdbg(", ");
+ msg_cdbg("0x%06x-0x%06x:", info->erase_start, info->erase_end);
+
+ ret = per_blockfn(flashctx, info, eraser->block_erase);
+ if (ret)
+ return ret;
+ }
+ }
+ msg_cdbg("\n");
+ return 0;
+}
+
+/** @private */
+static int walk_by_layout(struct flashctx *const flashctx, struct walk_info *const info,
+ per_blockfn_t per_blockfn)
+{
+ struct fl_layout_single fallback_layout;
+ const struct fl_layout *const layout = get_layout(flashctx, &fallback_layout);
+
+ all_skipped = true;
+ msg_cinfo("Erasing and writing flash chip... ");
+
+ size_t i;
+ for (i = 0; i < layout->num_entries; ++i) {
+ if (!layout->entries[i].included)
+ continue;
+
+ info->region_start = layout->entries[i].start;
+ info->region_end = layout->entries[i].end;
+
+ size_t j;
+ int ret = 1;
+ for (j = 0; j < NUM_ERASEFUNCTIONS; ++j) {
+ if (j != 0)
+ msg_cinfo("Looking for another erase function.\n");
+ msg_cdbg("Trying erase function %zi... ", j);
+ if (check_block_eraser(flashctx, j, 1))
+ continue;
+
+ ret = walk_eraseblocks(flashctx, info, j, per_blockfn);
+ if (ret != 1)
+ break;
+
+ if (info->curcontents) {
+ msg_cinfo("Reading current flash chip contents... ");
+ if (read_by_layout(flashctx, info->curcontents)) {
+ /* Now we are truly screwed. Read failed as well. */
+ msg_cerr("Can't read anymore! Aborting.\n");
+ /* We have no idea about the flash chip contents, so
+ * retrying with another erase function is pointless.
+ */
+ ret = 2;
+ break;
+ }
+ msg_cinfo("done. ");
+ }
+ }
+ if (ret == 1)
+ msg_cinfo("No usable erase functions left.\n");
+ if (ret) {
+ msg_cerr("FAILED!\n");
+ return 1;
+ }
+ }
+ if (all_skipped)
+ msg_cinfo("\nWarning: Chip content is identical to the requested image.\n");
+ msg_cinfo("Erase/write done.\n");
+ return 0;
+}
+
+/** @private */
+static int erase_block(struct flashctx *const flashctx, const struct walk_info *const info, erasefn_t erasefn)
+{
+ const unsigned int erase_len = info->erase_end + 1 - info->erase_start;
+
+ all_skipped = false;
+
+ msg_cdbg("E");
+ if (erasefn(flashctx, info->erase_start, erase_len))
+ return 1;
+ if (check_erased_range(flashctx, info->erase_start, erase_len)) {
+ msg_cerr("ERASE FAILED!\n");
+ return 1;
+ }
+ return 0;
+}
+
+/**
+ * @brief Erases the included layout regions.
+ *
+ * If there is no layout set in the given flash context, the whole chip will
+ * be erased.
+ *
+ * @param flashctx Flash context to be used.
+ * @param buffer Buffer of full chip size to read into.
+ * @return 0 on success,
+ * 1 if all available erase functions failed.
+ */
+static int erase_by_layout(struct flashctx *const flashctx)
+{
+ struct walk_info info = { 0 };
+ return walk_by_layout(flashctx, &info, erase_block);
+}
+
+/** @private */
+static int read_erase_write_block(struct flashctx *const flashctx,
+ const struct walk_info *const info, erasefn_t erasefn)
+{
+ const unsigned int erase_len = info->erase_end + 1 - info->erase_start;
+ const bool region_unaligned = info->region_start > info->erase_start ||
+ info->erase_end > info->region_end;
+ const uint8_t *newcontents = NULL;
+ int ret = 2;
+ /*
+ * Merge current flash contents into new buffer if the region is not erase-block
+ * aligned.
+ * Note: We can not use newcontents here as this erase block might overlap
+ * other regions as well. So we would invalidate data to be written there.
+ */
+ if (region_unaligned) {
+ msg_cdbg("R");
+ uint8_t *const newc = malloc(erase_len);
+ if (!newc) {
+ msg_cerr("Out of memory!\n");
+ return 1;
+ }
+ memcpy(newc, info->newcontents + info->erase_start, erase_len);
+ if (info->region_start > info->erase_start &&
+ flashctx->chip->read(flashctx, newc,
+ info->erase_start, info->region_start - info->erase_start)) {
+ msg_cerr("Can't read! Aborting.\n");
+ goto _free_ret;
+ }
+ if (info->erase_end > info->region_end &&
+ flashctx->chip->read(flashctx, newc - info->erase_start + info->region_end + 1,
+ info->region_end + 1, info->erase_end - info->region_end)) {
+ msg_cerr("Can't read! Aborting.\n");
+ goto _free_ret;
+ }
+ newcontents = newc;
+ } else {
+ newcontents = info->newcontents + info->erase_start;
+ }
+
+ ret = 1;
+ bool skipped = true;
+ uint8_t *const curcontents = info->curcontents + info->erase_start;
+ if (need_erase(curcontents, newcontents, erase_len, flashctx->chip->gran)) {
+ if (erase_block(flashctx, info, erasefn))
+ goto _free_ret;
+ /* Erase was successful. Adjust curcontents. */
+ memset(curcontents, 0xff, erase_len);
+ skipped = false;
+ }
+
+ unsigned int starthere = 0, lenhere = 0, writecount = 0;
+ /* get_next_write() sets starthere to a new value after the call. */
+ while ((lenhere = get_next_write(curcontents + starthere, newcontents + starthere,
+ erase_len - starthere, &starthere, flashctx->chip->gran))) {
+ if (!writecount++)
+ msg_cdbg("W");
+ /* Needs the partial write function signature. */
+ if (flashctx->chip->write(flashctx, newcontents + starthere,
+ info->erase_start + starthere, lenhere))
+ goto _free_ret;
+ starthere += lenhere;
+ skipped = false;
+ }
+ if (skipped)
+ msg_cdbg("S");
+ else
+ all_skipped = false;
+
+ /* Update curcontents, other regions with overlapping erase blocks
+ might rely on this. */
+ memcpy(curcontents, newcontents, erase_len);
+ ret = 0;
+
+_free_ret:
+ if (region_unaligned)
+ free((void *)newcontents);
+ return ret;
+}
+
+/**
+ * @brief Writes the included layout regions from a given image.
+ *
+ * If there is no layout set in the given flash context, the whole image
+ * will be written.
+ *
+ * @param flashctx Flash context to be used.
+ * @param curcontents A buffer of full chip size with current chip contents of included regions.
+ * @param newcontents The new image to be written.
+ * @return 0 on success,
+ * 1 if anything has gone wrong.
+ */
+static int write_by_layout(struct flashctx *const flashctx,
+ void *const curcontents, const void *const newcontents)
+{
+ struct walk_info info;
+ info.curcontents = curcontents;
+ info.newcontents = newcontents;
+ return walk_by_layout(flashctx, &info, read_erase_write_block);
+}
+
+/**
+ * @brief Compares the included layout regions with content from a buffer.
+ *
+ * If there is no layout set in the given flash context, the whole chip's
+ * contents will be compared.
+ *
+ * @param flashctx Flash context to be used.
+ * @param curcontents A buffer of full chip size to read current chip contents into.
+ * @param newcontents The new image to compare to.
+ * @return 0 on success,
+ * 1 if reading failed,
+ * 3 if the contents don't match.
+ */
+static int verify_by_layout(struct flashctx *const flashctx,
+ void *const curcontents, const void *const newcontents)
+{
+ struct fl_layout_single fallback_layout;
+ const struct fl_layout *const layout = get_layout(flashctx, &fallback_layout);
+
+ size_t i;
+ for (i = 0; i < layout->num_entries; ++i) {
+ if (!layout->entries[i].included)
+ continue;
+
+ const chipoff_t region_start = layout->entries[i].start;
+ const chipsize_t region_len = layout->entries[i].end - layout->entries[i].start + 1;
+
+ if (flashctx->chip->read(flashctx, curcontents + region_start, region_start, region_len))
+ return 1;
+ if (compare_range(newcontents + region_start, curcontents + region_start,
+ region_start, region_len))
+ return 3;
+ }
+ return 0;
+}
+
static void nonfatal_help_message(void)
{
msg_gerr("Good, writing to the flash chip apparently didn't do anything.\n");
--
To view, visit https://review.coreboot.org/19189
To unsubscribe, visit https://review.coreboot.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I060d9c42d71c83c3f95a6189cd22dad8b1504784
Gerrit-PatchSet: 1
Gerrit-Project: flashrom
Gerrit-Branch: staging
Gerrit-Owner: David Hendricks <david.hendricks(a)gmail.com>
Gerrit-Reviewer: Nico Huber <nico.h(a)gmx.de>
David Hendricks has uploaded a new patch set (#2). ( https://review.coreboot.org/19185 )
Change subject: This is a combination of 2 commits. The first commit's message is:
......................................................................
This is a combination of 2 commits.
The first commit's message is:
Convert flashrom to git
- Drop support for Subversion in the getrevision script and Makefile.
- Add .gitignore and .gitattributes file (the latter to limit exports).
- Restore modification dates of the exported files from the SCM.
- Stop exporting SCM log dumps to CHANGELOG. This makes no sense.
- Remove djgpp-dos target (it is not different to other x-compilations).
- Do not export the pre-"compiled" manpage. It can be generated like
anything else from the code dump when we export the respective variable.
The latter is added with this change.
- Add some initial client-side git hooks
* When committing check for obvious stuff you never want anyway:
- white space errors
- duplicate sign-offs
* When pushing to the upstream repository check mandatory rules:
- existing signoffs and acks in all new commits
- no deletions or creation of branches
- do not rewrite history of the precious branches, even if forced
- Change version string of flashrom as follows.
Previously, we included the last stable version according to a hard-
coded string in the Makefile and appended the subversion revision number.
With this patch the version string includes the last reachable git tag,
number of commits since said tag in the upstream branches (if any),
the name of said upstream branch, number of commits since that branch
(if any), and the shortened git hash.
In case there are uncommitted changes a "-dirty" indicator is also added.
The case of unknown versions is explicitly handled in getrevision instead
of simply appending "-unknown" to a hardcoded release number.
The version information is either taken from an existing git remote
pointing to an upstream repository (or a known mirror), or if that
is not available - with the user's consent - a shadow copy is fetched
from the upstream repo that is updated on every build (usually takes
less than a second).
In the following some examples of the version string changes are shown.
Basically we print the distance to the last known upstream tag, which
comprises any upstream commits since that tag as well as local commits on
top of that. Additionally we handle upstream's stable and staging branches
specially.
Old output:
flashrom v0.9.7-r1716 on Linux 3.8.0-6-generic (x86_64)
New output variants:
Build of the 0.9.99 release without any changes:
flashrom v0.9.99-e4f6643 on Linux 3.13.0-76-generic (x86_64)
5 commits since last tag in upstream's stable branch:
flashrom v0.9.99-5-stable-e4f6643-dirty on Linux 3.13.0-76-generic (x86_64)
3 commits since last tag in upstream's staging branch and
4 local commits on top of that:
flashrom v0.9.99-3-staging-4-e4f6643 on Linux 3.13.0-76-generic (x86_64)
3 commits since last tag in upstream's staging branch and
4 local commits on top of that, and some local uncommitted changes too:
flashrom v0.9.99-3-staging-4-e4f6643-dirty on Linux 3.13.0-76-generic (x86_64)
3 commits since the last tag in an unrelated upstream branch
(e.g., a stable release *branch* such as 0.9.99.x) or local branch:
flashrom v0.9.99-3-e4f6643 on Linux 3.13.0-76-generic (x86_64)
No tags reachable from current commit (generic git fallback):
flashrom d95935a version on Linux 3.13.0-76-generic (x86_64)
Not in a repository:
flashrom unknown version on Linux 3.13.0-76-generic (x86_64)
Signed-off-by: Stefan Tauner <stefan.tauner(a)alumni.tuwien.ac.at>
Acked-by: Stefan Tauner <stefan.tauner(a)alumni.tuwien.ac.at>
This is the 2nd commit message:
Use standard git commit-msg hook
This replaces commit-msg hook with the standard one so that
Change-Ids are generated.
We could merge the one which was being used which detects multiple
lines beginning with "Signed-off-by", however I wanted to check with
the author first due to licensing of the standard hook (Apache 2.0).
Change-Id: I8d3f54c3e87d3875b73a6f24c15d2ae43b84819f
Signed-off-by: David Hendricks <dhendricks(a)fb.com>
---
A .gitattributes
A .gitignore
M Makefile
M flashrom.c
M util/getrevision.sh
A util/git-hooks/applypatch-msg
A util/git-hooks/commit-msg
A util/git-hooks/install.sh
A util/git-hooks/pre-applypatch
A util/git-hooks/pre-commit
A util/git-hooks/pre-push
A util/git-hooks/wrapper.sh
12 files changed, 562 insertions(+), 124 deletions(-)
git pull ssh://review.coreboot.org:29418/flashrom refs/changes/85/19185/2
--
To view, visit https://review.coreboot.org/19185
To unsubscribe, visit https://review.coreboot.org/settings
Gerrit-MessageType: newpatchset
Gerrit-Change-Id: I8d3f54c3e87d3875b73a6f24c15d2ae43b84819f
Gerrit-PatchSet: 2
Gerrit-Project: flashrom
Gerrit-Branch: staging
Gerrit-Owner: David Hendricks <david.hendricks(a)gmail.com>