9os

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

commit 4ce9769862d0352900a9a0ec3e4e0b1611f512c7
parent dcb5fb757be749d2a067b98d7135184f8de05a7f
Author: Ambroise Vincent <ambroise.vincent@arm.com>
Date:   Wed,  8 May 2019 16:05:33 +0100

[dev] Parse FIP ToC with serialization tools

Change-Id: Ifc5a1d244afee51dff12aefc4392b074c953f72e
Signed-off-by: Ambroise Vincent <ambroise.vincent@arm.com>

Diffstat:
Mdrivers/devfip.c | 65++++++++++++++++++++++++++++++++++++++++++++++++++---------------
1 file changed, 50 insertions(+), 15 deletions(-)

diff --git a/drivers/devfip.c b/drivers/devfip.c @@ -1,4 +1,5 @@ #include <assert.h> +#include <deserialize.h> #include <errno.h> #include <limits.h> #include <stdlib.h> @@ -13,6 +14,8 @@ #define NR_FIPS 2 #define STOC_HEADER_NAME 4 /* strlen(TOC_HEADER_NAME); */ +#define STOC_HEADER 16 /* sizeof(fip_toc_header_t); */ +#define STOC_ENTRY 40 /* sizeof(fip_toc_entry_t); */ struct fipfile { Chan *c; @@ -20,25 +23,56 @@ struct fipfile { long size[NR_FILES]; }; +struct fipuuid { + char time_low[4]; + char time_mid[2]; + char time_hi_and_version[2]; + char clock_seq_hi_and_reserved; + char clock_seq_low; + char node[_UUID_NODE_LEN]; +}; + +struct fipntry { + struct fipuuid uuid; + long long offset_address; + long long size; + long long flags; +}; + static struct fipfile archives[NR_FIPS]; static int nfips; static int -getntry(Chan *c, struct fip_toc_entry *ntry) +getntry(Chan *c, struct fipntry *ntry) { - int n; + int i, n; + static unsigned char buf[STOC_ENTRY]; - // TODO: improve the way the entries are read in order to be more portable - n = devtab[c->type]->read(c, ntry, sizeof(*ntry)); + n = devtab[c->type]->read(c, buf, sizeof(buf)); if (n <= 0) return n; - if (n != sizeof(*ntry)) { + if (n != sizeof(buf)) { errno = EINVAL; return -1; } + n = 0; + for (i = 0; i < 4; i++) + CHAR(ntry->uuid.time_low[i], buf, n, sizeof(buf)); + for (i = 0; i < 2; i++) + CHAR(ntry->uuid.time_mid[i], buf, n, sizeof(buf)); + for (i = 0; i < 2; i++) + CHAR(ntry->uuid.time_hi_and_version[i], buf, n, sizeof(buf)); + CHAR(ntry->uuid.clock_seq_hi_and_reserved, buf, n, sizeof(buf)); + CHAR(ntry->uuid.clock_seq_low, buf, n, sizeof(buf)); + for (i = 0; i < _UUID_NODE_LEN; i++) + CHAR(ntry->uuid.node[i], buf, n, sizeof(buf)); + LLONG(ntry->offset_address, buf, n, sizeof(buf)); + LLONG(ntry->size, buf, n, sizeof(buf)); + LLONG(ntry->flags, buf, n, sizeof(buf)); + if (ntry->size > LONG_MAX || ntry->offset_address > LONG_MAX) { errno = EINVAL; return -1; @@ -51,7 +85,7 @@ getntry(Chan *c, struct fip_toc_entry *ntry) } static int -uuideq(const struct uuid *u1, const struct uuid *u2) +uuideq(const struct fipuuid *u1, const struct fipuuid *u2) { if (u1->clock_seq_hi_and_reserved != u2->clock_seq_hi_and_reserved) return 0; @@ -74,13 +108,13 @@ fipgen(Chan *c, const Dirtab *tab, int ntab, int n, Dir *dir) int i, r; long off; Chan nc; - struct fip_toc_entry ntry; + struct fipntry ntry; struct fipfile *fip; static char unk[NAMELEN]; struct uuidnames { const char name[NAMELEN]; - const struct uuid uuid; + const struct fipuuid uuid; }; // TODO: generate this array from a text file @@ -120,7 +154,7 @@ fipgen(Chan *c, const Dirtab *tab, int ntab, int n, Dir *dir) clone(archives[c->dev].c, &nc); fip = &archives[nc.dev]; - off = sizeof(struct fip_toc_header); + off = STOC_HEADER; for (i = 0; i <= n; i++) { if (fip->offset[i] == -1) return 0; @@ -203,10 +237,10 @@ static Chan * fipmount(Chan *c, char *spec) { int r, n, t; + long name; Chan *cspec; - char buf[STOC_HEADER_NAME]; - struct fip_toc_entry ntry; - struct fip_toc_header hdr; + unsigned char buf[STOC_HEADER_NAME]; + struct fipntry ntry; struct fipfile *fip; if (nfips == NR_FIPS) { @@ -222,17 +256,18 @@ fipmount(Chan *c, char *spec) return NULL; fip->c = cspec; - // TODO: improve the way the header is read in order to be more portable r = devtab[cspec->type]->read(cspec, buf, STOC_HEADER_NAME); if (r < 0) goto err; - if (r != STOC_HEADER_NAME || *((uint32_t *)buf) != TOC_HEADER_NAME) { + n = 0; + LONG(name, buf, n, sizeof(buf)); + if (r != STOC_HEADER_NAME || name != TOC_HEADER_NAME) { errno = EINVAL; goto err; } t = cspec->type; - if (devtab[t]->seek(cspec, sizeof(hdr), KSEEK_SET) < 0) + if (devtab[t]->seek(cspec, STOC_HEADER, KSEEK_SET) < 0) goto err; for (n = 0; n < NR_FILES; n++) { switch (getntry(cspec, &ntry)) {