mirror of
https://review.coreboot.org/flashrom.git
synced 2025-04-27 23:22:37 +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 "programmer.h"
|
||||||
#include "layout.h"
|
#include "layout.h"
|
||||||
|
|
||||||
static struct romentry entries[MAX_ROMLAYOUT];
|
struct flashrom_layout {
|
||||||
static struct flashrom_layout global_layout = { entries, MAX_ROMLAYOUT, 0 };
|
struct romentry *head;
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct flashrom_layout *global_layout;
|
||||||
|
|
||||||
struct flashrom_layout *get_global_layout(void)
|
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)
|
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)
|
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;
|
return flashctx->layout;
|
||||||
else
|
else
|
||||||
return get_default_layout(flashctx);
|
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(
|
static struct romentry *mutable_layout_next(
|
||||||
const struct flashrom_layout *const layout, struct romentry *iterator)
|
const struct flashrom_layout *const layout, struct romentry *iterator)
|
||||||
{
|
{
|
||||||
const struct romentry *const end = layout->entries + layout->num_entries;
|
return iterator ? iterator->next : layout->head;
|
||||||
|
|
||||||
if (iterator)
|
|
||||||
++iterator;
|
|
||||||
else
|
|
||||||
iterator = &layout->entries[0];
|
|
||||||
|
|
||||||
if (iterator < end)
|
|
||||||
return iterator;
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct romentry *_layout_entry_by_name(
|
static struct romentry *_layout_entry_by_name(
|
||||||
@ -91,11 +87,6 @@ int read_romlayout(const char *name)
|
|||||||
while (!feof(romlayout)) {
|
while (!feof(romlayout)) {
|
||||||
char *tstr1, *tstr2;
|
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))
|
if (2 != fscanf(romlayout, "%255s %255s\n", tempstr, tempname))
|
||||||
continue;
|
continue;
|
||||||
#if 0
|
#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. */
|
/* returns -1 if an entry is not found, 0 if found. */
|
||||||
static int find_romentry(struct flashrom_layout *const l, char *name, char *file)
|
static int find_romentry(struct flashrom_layout *const l, char *name, char *file)
|
||||||
{
|
{
|
||||||
if (l->num_entries == 0)
|
if (!l->head)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
msg_gspew("Looking for region \"%s\"... ", name);
|
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;
|
return 0;
|
||||||
|
|
||||||
/* User has specified an include argument, but no layout is loaded. */
|
/* 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\"), "
|
msg_gerr("Region requested (with -i \"%s\"), "
|
||||||
"but no layout data is available.\n",
|
"but no layout data is available.\n",
|
||||||
args->name);
|
args->name);
|
||||||
@ -287,7 +278,6 @@ int included_regions_overlap(const struct flashrom_layout *const l)
|
|||||||
void layout_cleanup(struct layout_include_args **args)
|
void layout_cleanup(struct layout_include_args **args)
|
||||||
{
|
{
|
||||||
struct flashrom_layout *const layout = get_global_layout();
|
struct flashrom_layout *const layout = get_global_layout();
|
||||||
unsigned int i;
|
|
||||||
struct layout_include_args *tmp;
|
struct layout_include_args *tmp;
|
||||||
|
|
||||||
while (*args) {
|
while (*args) {
|
||||||
@ -298,12 +288,8 @@ void layout_cleanup(struct layout_include_args **args)
|
|||||||
*args = tmp;
|
*args = tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < layout->num_entries; i++) {
|
global_layout = NULL;
|
||||||
free(layout->entries[i].name);
|
flashrom_layout_release(layout);
|
||||||
free(layout->entries[i].file);
|
|
||||||
layout->entries[i].included = false;
|
|
||||||
}
|
|
||||||
layout->num_entries = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Validate and - if needed - normalize layout entries. */
|
/* Validate and - if needed - normalize layout entries. */
|
||||||
@ -380,7 +366,7 @@ const struct romentry *layout_next_included(
|
|||||||
const struct romentry *layout_next(
|
const struct romentry *layout_next(
|
||||||
const struct flashrom_layout *const layout, const struct romentry *iterator)
|
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)
|
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) {
|
if (!*layout) {
|
||||||
msg_gerr("Error creating layout: %s\n", strerror(errno));
|
msg_gerr("Error creating layout: %s\n", strerror(errno));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
const struct flashrom_layout tmp = {
|
const struct flashrom_layout tmp = { 0 };
|
||||||
.entries = (void *)((char *)*layout + sizeof(**layout)),
|
|
||||||
.capacity = count,
|
|
||||||
.num_entries = 0,
|
|
||||||
};
|
|
||||||
**layout = tmp;
|
**layout = tmp;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -423,32 +405,36 @@ int flashrom_layout_new(struct flashrom_layout **const layout, const unsigned in
|
|||||||
* @param name Name of the region.
|
* @param name Name of the region.
|
||||||
*
|
*
|
||||||
* @return 0 on success,
|
* @return 0 on success,
|
||||||
* 1 if out of memory,
|
* 1 if out of memory.
|
||||||
* 2 if the layout is full already.
|
|
||||||
*/
|
*/
|
||||||
int flashrom_layout_add_region(
|
int flashrom_layout_add_region(
|
||||||
struct flashrom_layout *const layout,
|
struct flashrom_layout *const layout,
|
||||||
const size_t start, const size_t end, const char *const name)
|
const size_t start, const size_t end, const char *const name)
|
||||||
{
|
{
|
||||||
if (layout->num_entries >= layout->capacity) {
|
struct romentry *const entry = malloc(sizeof(*entry));
|
||||||
msg_gerr("Error adding layout entry: No space left\n");
|
if (!entry)
|
||||||
return 2;
|
goto _err_ret;
|
||||||
}
|
|
||||||
|
|
||||||
struct romentry *const entry = &layout->entries[layout->num_entries];
|
const struct romentry tmp = {
|
||||||
entry->start = start;
|
.next = layout->head,
|
||||||
entry->end = end;
|
.start = start,
|
||||||
entry->included = false;
|
.end = end,
|
||||||
entry->name = strdup(name);
|
.included = false,
|
||||||
entry->file = NULL;
|
.name = strdup(name),
|
||||||
if (!entry->name) {
|
.file = NULL,
|
||||||
msg_gerr("Error adding layout entry: %s\n", strerror(errno));
|
};
|
||||||
return 1;
|
*entry = tmp;
|
||||||
}
|
if (!entry->name)
|
||||||
|
goto _err_ret;
|
||||||
|
|
||||||
msg_gdbg("Added layout entry %08zx - %08zx named %s\n", start, end, name);
|
msg_gdbg("Added layout entry %08zx - %08zx named %s\n", start, end, name);
|
||||||
++layout->num_entries;
|
layout->head = entry;
|
||||||
return 0;
|
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)
|
void flashrom_layout_release(struct flashrom_layout *const layout)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
if (layout == global_layout)
|
||||||
|
|
||||||
if (!layout || layout == get_global_layout())
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (i = 0; i < layout->num_entries; ++i) {
|
if (!layout)
|
||||||
free(layout->entries[i].name);
|
return;
|
||||||
free(layout->entries[i].file);
|
|
||||||
|
while (layout->head) {
|
||||||
|
struct romentry *const entry = layout->head;
|
||||||
|
layout->head = entry->next;
|
||||||
|
free(entry->file);
|
||||||
|
free(entry->name);
|
||||||
|
free(entry);
|
||||||
}
|
}
|
||||||
free(layout);
|
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
|
#define MAX_ROMLAYOUT 128
|
||||||
|
|
||||||
struct romentry {
|
struct romentry {
|
||||||
|
struct romentry *next;
|
||||||
|
|
||||||
chipoff_t start;
|
chipoff_t start;
|
||||||
chipoff_t end;
|
chipoff_t end;
|
||||||
bool included;
|
bool included;
|
||||||
@ -43,14 +45,7 @@ struct romentry {
|
|||||||
char *file;
|
char *file;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct flashrom_layout {
|
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 layout_include_args {
|
struct layout_include_args {
|
||||||
char *name;
|
char *name;
|
||||||
|
@ -505,11 +505,6 @@ static int flashrom_layout_parse_fmap(struct flashrom_layout **layout,
|
|||||||
if (!fmap || !l)
|
if (!fmap || !l)
|
||||||
return 1;
|
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++) {
|
for (i = 0, area = fmap->areas; i < fmap->nareas; i++, area++) {
|
||||||
snprintf(name, sizeof(name), "%s", area->name);
|
snprintf(name, sizeof(name), "%s", area->name);
|
||||||
if (flashrom_layout_add_region(l, area->offset, area->offset + area->size - 1, name))
|
if (flashrom_layout_add_region(l, area->offset, area->offset + area->size - 1, name))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user