v2/documentation: romfs -> cbfs rename
[coreboot.git] / util / romtool / fs.c
1 /*
2  * romtool
3  *
4  * Copyright (C) 2008 Jordan Crouse <jordan@cosmicpenguin.net>
5  *
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.
9  *
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.
14  *
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
18  */
19
20 #include <string.h>
21 #include "romtool.h"
22
23 struct romfs_file *rom_find(struct rom *rom, unsigned int offset)
24 {
25         while (offset < rom->fssize) {
26                 struct romfs_file *c =
27                     (struct romfs_file *)ROM_PTR(rom, offset);
28
29                 if (!strcmp(c->magic, COMPONENT_MAGIC))
30                         return c;
31
32                 offset += ntohl(rom->header->align);
33         }
34
35         return NULL;
36 }
37
38 struct romfs_file *rom_find_first(struct rom *rom)
39 {
40         return rom_find(rom, ntohl(rom->header->offset));
41 }
42
43 struct romfs_file *rom_find_next(struct rom *rom, struct romfs_file *prev)
44 {
45         unsigned int offset = ROM_OFFSET(rom, prev);
46
47         return rom_find(rom, offset +
48                         ALIGN(ntohl(prev->offset) + ntohl(prev->len),
49                               ntohl(rom->header->align)));
50 }
51
52 struct romfs_file *rom_find_empty(struct rom *rom)
53 {
54         unsigned int offset = ntohl(rom->header->offset);
55         unsigned int ret = ntohl(rom->header->offset);
56
57         while (offset < rom->fssize) {
58
59                 struct romfs_file *c =
60                     (struct romfs_file *)ROM_PTR(rom, offset);
61
62                 if (!strcmp(c->magic, COMPONENT_MAGIC)) {
63                         offset += ALIGN(ntohl(c->offset) + ntohl(c->len),
64                                         ntohl(rom->header->align));
65
66                         ret = offset;
67                 } else
68                         offset += ntohl(rom->header->align);
69         }
70
71         return (ret < rom->fssize) ?
72             (struct romfs_file *)ROM_PTR(rom, ret) : NULL;
73 }
74
75 struct romfs_file *rom_find_by_name(struct rom *rom, const char *name)
76 {
77         struct romfs_file *c = rom_find_first(rom);
78
79         while (c) {
80                 if (!strcmp((char *)ROMFS_NAME(c), name))
81                         return c;
82
83                 c = rom_find_next(rom, c);
84         }
85
86         return NULL;
87 }
88
89 unsigned int rom_used_space(struct rom *rom)
90 {
91         struct romfs_file *c = rom_find_first(rom);
92         unsigned int ret = 0;
93
94         while (c) {
95                 ret = ROM_OFFSET(rom, c) + ntohl(c->offset) + ntohl(c->len);
96                 c = rom_find_next(rom, c);
97         }
98
99         return ret;
100 }
101
102 int rom_remove(struct rom *rom, const char *name)
103 {
104         struct romfs_file *c = rom_find_by_name(rom, name);
105         struct romfs_file *n;
106         int clear;
107
108         if (c == NULL) {
109                 ERROR("Component %s does not exist\n", name);
110                 return -1;
111         }
112
113         /* Get the next component - and copy it into the current
114            space */
115
116         n = rom_find_next(rom, c);
117
118         memcpy(c, n, rom->fssize - ROM_OFFSET(rom, n));
119
120         clear = ROM_OFFSET(rom, n) - ROM_OFFSET(rom, c);
121
122         /* Zero the new space */
123         memset(ROM_PTR(rom, rom->fssize - clear), 0, clear);
124         return 0;
125 }
126
127 int rom_add(struct rom *rom, const char *name, void *buffer, int size, int type)
128 {
129         struct romfs_file *c = rom_find_empty(rom);
130         unsigned int offset;
131         unsigned int csize;
132
133         if (rom_find_by_name(rom, name)) {
134                 ERROR("Component %s already exists in this rom\n", name);
135                 return -1;
136         }
137
138         if (c == NULL) {
139                 ERROR("There is no more room in this ROM\n");
140                 return -1;
141         }
142
143         csize = sizeof(struct romfs_file) + ALIGN(strlen(name), 16) + size;
144
145         offset = ROM_OFFSET(rom, c);
146
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);
151
152                 return -1;
153         }
154
155         strcpy(c->magic, COMPONENT_MAGIC);
156
157         csize = sizeof(struct romfs_file) + ALIGN(strlen(name) + 1, 16);
158
159         c->len = htonl(size);
160         c->offset = htonl(csize);
161         c->type = htonl(type);
162
163         memset(ROMFS_NAME(c), 0, ALIGN(strlen(name) + 1, 16));
164         strcpy((char *)ROMFS_NAME(c), name);
165
166         memcpy(((unsigned char *)c) + csize, buffer, size);
167         return 0;
168 }