4 * Copyright (C) 2008 Jordan Crouse <jordan@cosmicpenguin.net>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA, 02110-1301 USA
23 struct romfs_file *rom_find(struct rom *rom, unsigned int offset)
25 while (offset < rom->fssize) {
26 struct romfs_file *c =
27 (struct romfs_file *)ROM_PTR(rom, offset);
29 if (!strcmp(c->magic, COMPONENT_MAGIC))
32 offset += ntohl(rom->header->align);
38 struct romfs_file *rom_find_first(struct rom *rom)
40 return rom_find(rom, ntohl(rom->header->offset));
43 struct romfs_file *rom_find_next(struct rom *rom, struct romfs_file *prev)
45 unsigned int offset = ROM_OFFSET(rom, prev);
47 return rom_find(rom, offset +
48 ALIGN(ntohl(prev->offset) + ntohl(prev->len),
49 ntohl(rom->header->align)));
52 struct romfs_file *rom_find_empty(struct rom *rom)
54 unsigned int offset = ntohl(rom->header->offset);
55 unsigned int ret = ntohl(rom->header->offset);
57 while (offset < rom->fssize) {
59 struct romfs_file *c =
60 (struct romfs_file *)ROM_PTR(rom, offset);
62 if (!strcmp(c->magic, COMPONENT_MAGIC)) {
63 offset += ALIGN(ntohl(c->offset) + ntohl(c->len),
64 ntohl(rom->header->align));
68 offset += ntohl(rom->header->align);
71 return (ret < rom->fssize) ?
72 (struct romfs_file *)ROM_PTR(rom, ret) : NULL;
75 struct romfs_file *rom_find_by_name(struct rom *rom, const char *name)
77 struct romfs_file *c = rom_find_first(rom);
80 if (!strcmp((char *)ROMFS_NAME(c), name))
83 c = rom_find_next(rom, c);
89 unsigned int rom_used_space(struct rom *rom)
91 struct romfs_file *c = rom_find_first(rom);
95 ret = ROM_OFFSET(rom, c) + ntohl(c->offset) + ntohl(c->len);
96 c = rom_find_next(rom, c);
102 int rom_remove(struct rom *rom, const char *name)
104 struct romfs_file *c = rom_find_by_name(rom, name);
105 struct romfs_file *n;
109 ERROR("Component %s does not exist\n", name);
113 /* Get the next component - and copy it into the current
116 n = rom_find_next(rom, c);
118 memcpy(c, n, rom->fssize - ROM_OFFSET(rom, n));
120 clear = ROM_OFFSET(rom, n) - ROM_OFFSET(rom, c);
122 /* Zero the new space */
123 memset(ROM_PTR(rom, rom->fssize - clear), 0, clear);
127 int rom_add(struct rom *rom, const char *name, void *buffer, int size, int type)
129 struct romfs_file *c = rom_find_empty(rom);
133 if (rom_find_by_name(rom, name)) {
134 ERROR("Component %s already exists in this rom\n", name);
139 ERROR("There is no more room in this ROM\n");
143 csize = sizeof(struct romfs_file) + ALIGN(strlen(name), 16) + size;
145 offset = ROM_OFFSET(rom, c);
147 if (offset + csize >= rom->fssize) {
148 ERROR("There is not enough room in this ROM for this\n");
149 ERROR("component. I need %d bytes, only have %d bytes avail\n",
150 csize, rom->fssize - offset);
155 strcpy(c->magic, COMPONENT_MAGIC);
157 csize = sizeof(struct romfs_file) + ALIGN(strlen(name) + 1, 16);
159 c->len = htonl(size);
160 c->offset = htonl(csize);
161 c->type = htonl(type);
163 memset(ROMFS_NAME(c), 0, ALIGN(strlen(name) + 1, 16));
164 strcpy((char *)ROMFS_NAME(c), name);
166 memcpy(((unsigned char *)c) + csize, buffer, size);