mirror of
https://review.coreboot.org/flashrom.git
synced 2025-04-27 07:02:34 +02:00
layout: Use linked list for struct romentry
This gets rid of the entry limit and hopefully makes future layout handling easier. We start by making `struct flashrom_layout` private to `layout.c`. Change-Id: I60a0aa1007ebcd5eb401db116f835d129b3e9732 Signed-off-by: Nico Huber <nico.h@gmx.de> Reviewed-on: https://review.coreboot.org/c/flashrom/+/33521 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Edward O'Callaghan <quasisec@chromium.org> Reviewed-by: Angel Pons <th3fanbus@gmail.com>
This commit is contained in:
parent
a1afc84156
commit
953c5ad440
106
layout.c
106
layout.c
@ -25,12 +25,17 @@
|
||||
#include "programmer.h"
|
||||
#include "layout.h"
|
||||
|
||||
static struct romentry entries[MAX_ROMLAYOUT];
|
||||
static struct flashrom_layout global_layout = { entries, MAX_ROMLAYOUT, 0 };
|
||||
struct flashrom_layout {
|
||||
struct romentry *head;
|
||||
};
|
||||
|
||||
static struct flashrom_layout *global_layout;
|
||||
|
||||
struct flashrom_layout *get_global_layout(void)
|
||||
{
|
||||
return &global_layout;
|
||||
if (!global_layout)
|
||||
flashrom_layout_new(&global_layout, 0);
|
||||
return global_layout;
|
||||
}
|
||||
|
||||
const struct flashrom_layout *get_default_layout(const struct flashrom_flashctx *const flashctx)
|
||||
@ -40,7 +45,7 @@ const struct flashrom_layout *get_default_layout(const struct flashrom_flashctx
|
||||
|
||||
const struct flashrom_layout *get_layout(const struct flashrom_flashctx *const flashctx)
|
||||
{
|
||||
if (flashctx->layout && flashctx->layout->num_entries)
|
||||
if (flashctx->layout)
|
||||
return flashctx->layout;
|
||||
else
|
||||
return get_default_layout(flashctx);
|
||||
@ -49,16 +54,7 @@ const struct flashrom_layout *get_layout(const struct flashrom_flashctx *const f
|
||||
static struct romentry *mutable_layout_next(
|
||||
const struct flashrom_layout *const layout, struct romentry *iterator)
|
||||
{
|
||||
const struct romentry *const end = layout->entries + layout->num_entries;
|
||||
|
||||
if (iterator)
|
||||
++iterator;
|
||||
else
|
||||
iterator = &layout->entries[0];
|
||||
|
||||
if (iterator < end)
|
||||
return iterator;
|
||||
return NULL;
|
||||
return iterator ? iterator->next : layout->head;
|
||||
}
|
||||
|
||||
static struct romentry *_layout_entry_by_name(
|
||||
@ -91,11 +87,6 @@ int read_romlayout(const char *name)
|
||||
while (!feof(romlayout)) {
|
||||
char *tstr1, *tstr2;
|
||||
|
||||
if (layout->num_entries >= layout->capacity) {
|
||||
msg_gerr("Maximum number of ROM images (%zu) in layout "
|
||||
"file reached.\n", layout->capacity);
|
||||
goto _close_ret;
|
||||
}
|
||||
if (2 != fscanf(romlayout, "%255s %255s\n", tempstr, tempname))
|
||||
continue;
|
||||
#if 0
|
||||
@ -186,7 +177,7 @@ static int include_region(struct flashrom_layout *const l, const char *name,
|
||||
/* returns -1 if an entry is not found, 0 if found. */
|
||||
static int find_romentry(struct flashrom_layout *const l, char *name, char *file)
|
||||
{
|
||||
if (l->num_entries == 0)
|
||||
if (!l->head)
|
||||
return -1;
|
||||
|
||||
msg_gspew("Looking for region \"%s\"... ", name);
|
||||
@ -222,7 +213,7 @@ int process_include_args(struct flashrom_layout *l, const struct layout_include_
|
||||
return 0;
|
||||
|
||||
/* User has specified an include argument, but no layout is loaded. */
|
||||
if (l->num_entries == 0) {
|
||||
if (!l->head) {
|
||||
msg_gerr("Region requested (with -i \"%s\"), "
|
||||
"but no layout data is available.\n",
|
||||
args->name);
|
||||
@ -287,7 +278,6 @@ int included_regions_overlap(const struct flashrom_layout *const l)
|
||||
void layout_cleanup(struct layout_include_args **args)
|
||||
{
|
||||
struct flashrom_layout *const layout = get_global_layout();
|
||||
unsigned int i;
|
||||
struct layout_include_args *tmp;
|
||||
|
||||
while (*args) {
|
||||
@ -298,12 +288,8 @@ void layout_cleanup(struct layout_include_args **args)
|
||||
*args = tmp;
|
||||
}
|
||||
|
||||
for (i = 0; i < layout->num_entries; i++) {
|
||||
free(layout->entries[i].name);
|
||||
free(layout->entries[i].file);
|
||||
layout->entries[i].included = false;
|
||||
}
|
||||
layout->num_entries = 0;
|
||||
global_layout = NULL;
|
||||
flashrom_layout_release(layout);
|
||||
}
|
||||
|
||||
/* Validate and - if needed - normalize layout entries. */
|
||||
@ -380,7 +366,7 @@ const struct romentry *layout_next_included(
|
||||
const struct romentry *layout_next(
|
||||
const struct flashrom_layout *const layout, const struct romentry *iterator)
|
||||
{
|
||||
return mutable_layout_next(layout, (struct romentry *)iterator);
|
||||
return iterator ? iterator->next : layout->head;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -399,17 +385,13 @@ const struct romentry *layout_next(
|
||||
*/
|
||||
int flashrom_layout_new(struct flashrom_layout **const layout, const unsigned int count)
|
||||
{
|
||||
*layout = malloc(sizeof(**layout) + count * sizeof(struct romentry));
|
||||
*layout = malloc(sizeof(**layout));
|
||||
if (!*layout) {
|
||||
msg_gerr("Error creating layout: %s\n", strerror(errno));
|
||||
return 1;
|
||||
}
|
||||
|
||||
const struct flashrom_layout tmp = {
|
||||
.entries = (void *)((char *)*layout + sizeof(**layout)),
|
||||
.capacity = count,
|
||||
.num_entries = 0,
|
||||
};
|
||||
const struct flashrom_layout tmp = { 0 };
|
||||
**layout = tmp;
|
||||
return 0;
|
||||
}
|
||||
@ -423,32 +405,36 @@ int flashrom_layout_new(struct flashrom_layout **const layout, const unsigned in
|
||||
* @param name Name of the region.
|
||||
*
|
||||
* @return 0 on success,
|
||||
* 1 if out of memory,
|
||||
* 2 if the layout is full already.
|
||||
* 1 if out of memory.
|
||||
*/
|
||||
int flashrom_layout_add_region(
|
||||
struct flashrom_layout *const layout,
|
||||
const size_t start, const size_t end, const char *const name)
|
||||
{
|
||||
if (layout->num_entries >= layout->capacity) {
|
||||
msg_gerr("Error adding layout entry: No space left\n");
|
||||
return 2;
|
||||
}
|
||||
struct romentry *const entry = malloc(sizeof(*entry));
|
||||
if (!entry)
|
||||
goto _err_ret;
|
||||
|
||||
struct romentry *const entry = &layout->entries[layout->num_entries];
|
||||
entry->start = start;
|
||||
entry->end = end;
|
||||
entry->included = false;
|
||||
entry->name = strdup(name);
|
||||
entry->file = NULL;
|
||||
if (!entry->name) {
|
||||
msg_gerr("Error adding layout entry: %s\n", strerror(errno));
|
||||
return 1;
|
||||
}
|
||||
const struct romentry tmp = {
|
||||
.next = layout->head,
|
||||
.start = start,
|
||||
.end = end,
|
||||
.included = false,
|
||||
.name = strdup(name),
|
||||
.file = NULL,
|
||||
};
|
||||
*entry = tmp;
|
||||
if (!entry->name)
|
||||
goto _err_ret;
|
||||
|
||||
msg_gdbg("Added layout entry %08zx - %08zx named %s\n", start, end, name);
|
||||
++layout->num_entries;
|
||||
layout->head = entry;
|
||||
return 0;
|
||||
|
||||
_err_ret:
|
||||
msg_gerr("Error adding layout entry: %s\n", strerror(errno));
|
||||
free(entry);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -472,14 +458,18 @@ int flashrom_layout_include_region(struct flashrom_layout *const layout, const c
|
||||
*/
|
||||
void flashrom_layout_release(struct flashrom_layout *const layout)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
if (!layout || layout == get_global_layout())
|
||||
if (layout == global_layout)
|
||||
return;
|
||||
|
||||
for (i = 0; i < layout->num_entries; ++i) {
|
||||
free(layout->entries[i].name);
|
||||
free(layout->entries[i].file);
|
||||
if (!layout)
|
||||
return;
|
||||
|
||||
while (layout->head) {
|
||||
struct romentry *const entry = layout->head;
|
||||
layout->head = entry->next;
|
||||
free(entry->file);
|
||||
free(entry->name);
|
||||
free(entry);
|
||||
}
|
||||
free(layout);
|
||||
}
|
||||
|
11
layout.h
11
layout.h
@ -36,6 +36,8 @@ typedef uint32_t chipsize_t; /* Able to store the number of bytes of any support
|
||||
#define MAX_ROMLAYOUT 128
|
||||
|
||||
struct romentry {
|
||||
struct romentry *next;
|
||||
|
||||
chipoff_t start;
|
||||
chipoff_t end;
|
||||
bool included;
|
||||
@ -43,14 +45,7 @@ struct romentry {
|
||||
char *file;
|
||||
};
|
||||
|
||||
struct flashrom_layout {
|
||||
/* entries store the entries specified in a layout file and associated run-time data */
|
||||
struct romentry *entries;
|
||||
/* the maximum number of entries */
|
||||
size_t capacity;
|
||||
/* the number of successfully parsed entries */
|
||||
size_t num_entries;
|
||||
};
|
||||
struct flashrom_layout;
|
||||
|
||||
struct layout_include_args {
|
||||
char *name;
|
||||
|
@ -505,11 +505,6 @@ static int flashrom_layout_parse_fmap(struct flashrom_layout **layout,
|
||||
if (!fmap || !l)
|
||||
return 1;
|
||||
|
||||
if (l->num_entries + fmap->nareas > l->capacity) {
|
||||
msg_gerr("Cannot add fmap entries to layout - Too many entries.\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
for (i = 0, area = fmap->areas; i < fmap->nareas; i++, area++) {
|
||||
snprintf(name, sizeof(name), "%s", area->name);
|
||||
if (flashrom_layout_add_region(l, area->offset, area->offset + area->size - 1, name))
|
||||
|
Loading…
x
Reference in New Issue
Block a user