9os

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

commit d94a222d93f9786881c8b7e6e86f0ff3963b992e
parent eff6c097f55b7122e50ef1870f803511c509df16
Author: Ambroise Vincent <ambroise.vincent@arm.com>
Date:   Thu, 18 Apr 2019 16:23:14 +0100

[dev] Add FIP filesystem

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

Diffstat:
Mdrivers/dev.h | 3++-
Mdrivers/devar.c | 6+++---
Adrivers/devfip.c | 242+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mdrivers/devroot.c | 2++
Adrivers/fip.h | 92+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Adrivers/uuid.h | 62++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mtarget/native/rcode | 3+++
Mtarget/native/rom.c | 3+++
8 files changed, 409 insertions(+), 4 deletions(-)

diff --git a/drivers/dev.h b/drivers/dev.h @@ -1,9 +1,10 @@ #include <stddef.h> -#define NR_CHANS 15 +#define NR_CHANS 20 #define NR_UARTS 2 #define NR_CONSS 1 #define NR_BINDS 4 +#define NR_FILES 20 #define NODEV 255 #define CHDIR (1 << 15) diff --git a/drivers/devar.c b/drivers/devar.c @@ -9,7 +9,6 @@ #include "dev.h" #define NR_ARS 2 -#define NR_FILES 10 #define ARMAG "!<arch>\n" /* ar "magic number" */ #define SARMAG 8 /* strlen(ARMAG); */ @@ -57,7 +56,7 @@ gethdr(Chan *c, struct ar_hdr *hdr) hdr->ar_name[i] = '\0'; } - return 1; + return 1; } static int @@ -124,7 +123,8 @@ arread(Chan *c, void *buf, int n) return -1; n = devtab[cs.type]->read(&cs, buf, n); - c->offset += n; + if (n > 0) + c->offset += n; return n; } diff --git a/drivers/devfip.c b/drivers/devfip.c @@ -0,0 +1,242 @@ +#include <assert.h> +#include <errno.h> +#include <limits.h> +#include <stdlib.h> +#include <string.h> + +#include <rcode/rcode.h> +#include <rcode/9p.h> + +#include "dev.h" +#include "fip.h" + +#define NR_FIPS 2 + +#define STOC_HEADER_NAME 4 /* strlen(TOC_HEADER_NAME); */ + +struct fipfile { + Chan *c; + long offset[NR_FILES]; + long size[NR_FILES]; +}; + +static struct fipfile archives[NR_FIPS]; +static int nfips; + +static int +getntry(Chan *c, struct fip_toc_entry *ntry) +{ + int n; + + // TODO: improve the way the entries are read in order to be more portable + n = devtab[c->type]->read(c, ntry, sizeof(*ntry)); + if (n <= 0) + return n; + + if (n != sizeof(*ntry)) { + errno = EINVAL; + return -1; + } + + if (ntry->size > LONG_MAX || ntry->offset_address > LONG_MAX) { + errno = EINVAL; + return -1; + } + + if (ntry->size == 0) + return 0; + + return 1; +} + +static int +uuideq(const struct uuid *u1, const struct uuid *u2) +{ + if (u1->clock_seq_hi_and_reserved != u2->clock_seq_hi_and_reserved) + return 0; + if (u1->clock_seq_low != u2->clock_seq_low) + return 0; + if (memcmp(u1->node, u2->node, sizeof(u1->node))) + return 0; + if (memcmp(u1->time_hi_and_version, u2->time_hi_and_version, sizeof(u1->time_hi_and_version))) + return 0; + if (memcmp(u1->time_low, u2->time_low, sizeof(u1->time_low))) + return 0; + if (memcmp(u1->time_mid, u2->time_mid, sizeof(u1->time_mid))) + return 0; + return 1; +} + +static int +fipgen(Chan *c, const Dirtab *tab, int ntab, int n, Dir *dir) +{ + int i, r; + static char unk[NAMELEN]; + Chan nc; + struct fip_toc_entry ntry; + struct fipfile *fip; + + struct uuidnames { + const char name[NAMELEN]; + const struct uuid uuid; + }; + + // TODO: generate this array from a text file + static const struct uuidnames uuidnames[] = { + {"scp-bl2u.bin", UUID_TRUSTED_UPDATE_FIRMWARE_SCP_BL2U}, + {"bl2u.bin", UUID_TRUSTED_UPDATE_FIRMWARE_BL2U}, + {"ns-bl2u.bin", UUID_TRUSTED_UPDATE_FIRMWARE_NS_BL2U}, + {"fwu.crt", UUID_TRUSTED_FWU_CERT}, + {"bl2.bin", UUID_TRUSTED_BOOT_FIRMWARE_BL2}, + {"scp-bl2.bin", UUID_SCP_FIRMWARE_SCP_BL2}, + {"bl31.bin", UUID_EL3_RUNTIME_FIRMWARE_BL31}, + {"bl32.bin", UUID_SECURE_PAYLOAD_BL32}, + {"bl32-xtr1.bin", UUID_SECURE_PAYLOAD_BL32_EXTRA1}, + {"bl32-xtr2.bin", UUID_SECURE_PAYLOAD_BL32_EXTRA2}, + {"bl33.bin", UUID_NON_TRUSTED_FIRMWARE_BL33}, + {"rot-k.crt", UUID_ROT_KEY_CERT}, + {"trstd-k.crt", UUID_TRUSTED_KEY_CERT}, + {"nt-k.crt", UUID_NON_TRUSTED_WORLD_KEY_CERT}, + {"scp-fw-k.crt", UUID_SCP_FW_KEY_CERT}, + {"soc-fw-k.crt", UUID_SOC_FW_KEY_CERT}, + {"tos-fw-k.crt", UUID_TRUSTED_OS_FW_KEY_CERT}, + {"nt-fw-k.crt", UUID_NON_TRUSTED_FW_KEY_CERT}, + {"tb-fw.crt", UUID_TRUSTED_BOOT_FW_CERT}, + {"scp-fw-c.crt", UUID_SCP_FW_CONTENT_CERT}, + {"soc-fw-c.crt", UUID_SOC_FW_CONTENT_CERT}, + {"tos-fw-c.crt", UUID_TRUSTED_OS_FW_CONTENT_CERT}, + {"nt-fw-c.crt", UUID_NON_TRUSTED_FW_CONTENT_CERT}, + {"hw.cfg", UUID_HW_CONFIG}, + {"tb-fw.cfg", UUID_TB_FW_CONFIG}, + {"soc-fw.cfg", UUID_SOC_FW_CONFIG}, + {"tos-fw.cfg", UUID_TOS_FW_CONFIG}, + {"nt-fw.cfg", UUID_NT_FW_CONFIG} + }; + + if (c->dev >= nfips) + panic("fipgen"); + clone(archives[c->dev].c, &nc); + fip = &archives[nc.dev]; + + for (i = 0; i <= n; i++) { + if (fip->offset[i] == -1) + return 0; + if (devseek(&nc, sizeof(struct fip_toc_header) + i * sizeof(ntry), RSEEK_SET) < 0) + return -1; + if ((r = getntry(&nc, &ntry)) <= 0) + return r; + } + + for (i = 0; i < NELEM(uuidnames); i++) { + if (uuideq(&uuidnames[i].uuid, &ntry.uuid)) + break; + } + + if (i < NELEM(uuidnames)) { + mkentry(c, dir, uuidnames[i].name, ntry.size, n, O_READ); + } else { + // TODO: set name depending on uuid node value + mkentry(c, dir, unk, ntry.size, n, O_READ); + } + + return 1; +} + +static int +fipwalk(Chan *c, const char *name) +{ + return devwalk(c, name, NULL, 0, fipgen); +} + +static int +fipread(Chan *c, void *buf, int n) +{ + long off; + Chan cs; + struct fipfile *fip; + + if (c->qid == CHDIR) + return dirread(c, buf, n, NULL, 0, fipgen); + + if (c->dev >= nfips || (c->qid & CHDIR)) + panic("fipread1"); + fip = &archives[c->dev]; + + if (c->qid >= NR_FILES || fip->offset[c->qid] < 0) + panic("fipread2"); + clone(fip->c, &cs); + + if (c->offset >= fip->size[c->qid]) + return 0; + + off = fip->offset[c->qid] + c->offset; + if (devseek(&cs, off, RSEEK_SET) < 0) + return -1; + + n = devtab[cs.type]->read(&cs, buf, n); + if (n > 0) + c->offset += n; + + return n; +} + +static Chan * +fipmount(Chan *c, char *spec) +{ + int r, n; + Chan *cspec; + char buf[STOC_HEADER_NAME]; + struct fip_toc_entry ntry; + struct fip_toc_header hdr; + struct fipfile *fip; + + if (nfips == NR_FIPS) { + errno = ENOMEM; + return NULL; + } + fip = &archives[nfips]; + + for (n = 0; n < NR_FILES; n++) + fip->offset[n] = -1; + + if ((cspec = namec(spec, O_READ)) < 0) + 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) { + errno = EINVAL; + goto err; + } + + if (devseek(cspec, sizeof(hdr), RSEEK_SET) < 0) + goto err; + for (n = 0; n < NR_FILES; n++) { + switch (getntry(cspec, &ntry)) { + case 0: + return devattach('F', nfips++); + case -1: + goto err; + default: + fip->offset[n] = ntry.offset_address; + fip->size[n] = ntry.size; + break; + } + } + errno = ENOMEM; + +err: + chanclose(cspec); + return NULL; +} + +const Dev fipdevtab = { + .id = 'F', + .walk = fipwalk, + .read = fipread, + .write = devwrite, + .mount = fipmount, +}; diff --git a/drivers/devroot.c b/drivers/devroot.c @@ -14,6 +14,7 @@ enum Orootqid { Qdevcons, Qrealm, Qarfs, + Qfip, Qblobs, Qblobctl, }; @@ -27,6 +28,7 @@ static const Dirtab dirtab[] = { {"realm", CHDIR | Qrealm, 0, O_READ}, {"blobs", CHDIR | Qblobs, 0, O_READ}, {"arfs", CHDIR | Qarfs, 0, O_READ}, + {"fip", CHDIR | Qfip, 0, O_READ}, }; static const Dirtab devfstab[] = { diff --git a/drivers/fip.h b/drivers/fip.h @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef FIRMWARE_IMAGE_PACKAGE_H +#define FIRMWARE_IMAGE_PACKAGE_H + +#include <stdint.h> + +#include "uuid.h" + +/* This is used as a signature to validate the blob header */ +#define TOC_HEADER_NAME 0xAA640001 + + +/* ToC Entry UUIDs */ +#define UUID_TRUSTED_UPDATE_FIRMWARE_SCP_BL2U \ + {{0x65, 0x92, 0x27, 0x03}, {0x2f, 0x74}, {0xe6, 0x44}, 0x8d, 0xff, {0x57, 0x9a, 0xc1, 0xff, 0x06, 0x10} } +#define UUID_TRUSTED_UPDATE_FIRMWARE_BL2U \ + {{0x60, 0xb3, 0xeb, 0x37}, {0xc1, 0xe5}, {0xea, 0x41}, 0x9d, 0xf3, {0x19, 0xed, 0xa1, 0x1f, 0x68, 0x01} } +#define UUID_TRUSTED_UPDATE_FIRMWARE_NS_BL2U \ + {{0x4f, 0x51, 0x1d, 0x11}, {0x2b, 0xe5}, {0x4e, 0x49}, 0xb4, 0xc5, {0x83, 0xc2, 0xf7, 0x15, 0x84, 0x0a} } +#define UUID_TRUSTED_FWU_CERT \ + {{0x71, 0x40, 0x8a, 0xb2}, {0x18, 0xd6}, {0x87, 0x4c}, 0x8b, 0x2e, {0xc6, 0xdc, 0xcd, 0x50, 0xf0, 0x96} } +#define UUID_TRUSTED_BOOT_FIRMWARE_BL2 \ + {{0x5f, 0xf9, 0xec, 0x0b}, {0x4d, 0x22}, {0x3e, 0x4d}, 0xa5, 0x44, {0xc3, 0x9d, 0x81, 0xc7, 0x3f, 0x0a} } +#define UUID_SCP_FIRMWARE_SCP_BL2 \ + {{0x97, 0x66, 0xfd, 0x3d}, {0x89, 0xbe}, {0xe8, 0x49}, 0xae, 0x5d, {0x78, 0xa1, 0x40, 0x60, 0x82, 0x13} } +#define UUID_EL3_RUNTIME_FIRMWARE_BL31 \ + {{0x47, 0xd4, 0x08, 0x6d}, {0x4c, 0xfe}, {0x98, 0x46}, 0x9b, 0x95, {0x29, 0x50, 0xcb, 0xbd, 0x5a, 0x00} } +#define UUID_SECURE_PAYLOAD_BL32 \ + {{0x05, 0xd0, 0xe1, 0x89}, {0x53, 0xdc}, {0x13, 0x47}, 0x8d, 0x2b, {0x50, 0x0a, 0x4b, 0x7a, 0x3e, 0x38} } +#define UUID_SECURE_PAYLOAD_BL32_EXTRA1 \ + {{0x0b, 0x70, 0xc2, 0x9b}, {0x2a, 0x5a}, {0x78, 0x40}, 0x9f, 0x65, {0x0a, 0x56, 0x82, 0x73, 0x82, 0x88} } +#define UUID_SECURE_PAYLOAD_BL32_EXTRA2 \ + {{0x8e, 0xa8, 0x7b, 0xb1}, {0xcf, 0xa2}, {0x3f, 0x4d}, 0x85, 0xfd, {0xe7, 0xbb, 0xa5, 0x02, 0x20, 0xd9} } +#define UUID_NON_TRUSTED_FIRMWARE_BL33 \ + {{0xd6, 0xd0, 0xee, 0xa7}, {0xfc, 0xea}, {0xd5, 0x4b}, 0x97, 0x82, {0x99, 0x34, 0xf2, 0x34, 0xb6, 0xe4} } +/* Key certificates */ +#define UUID_ROT_KEY_CERT \ + {{0x86, 0x2d, 0x1d, 0x72}, {0xf8, 0x60}, {0xe4, 0x11}, 0x92, 0x0b, {0x8b, 0xe7, 0x62, 0x16, 0x0f, 0x24} } +#define UUID_TRUSTED_KEY_CERT \ + {{0x82, 0x7e, 0xe8, 0x90}, {0xf8, 0x60}, {0xe4, 0x11}, 0xa1, 0xb4, {0x77, 0x7a, 0x21, 0xb4, 0xf9, 0x4c} } +#define UUID_NON_TRUSTED_WORLD_KEY_CERT \ + {{0x1c, 0x67, 0x87, 0x3d}, {0x5f, 0x63}, {0xe4, 0x11}, 0x97, 0x8d, {0x27, 0xc0, 0xc7, 0x14, 0x8a, 0xbd} } +#define UUID_SCP_FW_KEY_CERT \ + {{0x02, 0x42, 0x21, 0xa1}, {0xf8, 0x60}, {0xe4, 0x11}, 0x8d, 0x9b, {0xf3, 0x3c, 0x0e, 0x15, 0xa0, 0x14} } +#define UUID_SOC_FW_KEY_CERT \ + {{0x8a, 0xb8, 0xbe, 0xcc}, {0xf9, 0x60}, {0xe4, 0x11}, 0x9a, 0xd0, {0xeb, 0x48, 0x22, 0xd8, 0xdc, 0xf8} } +#define UUID_TRUSTED_OS_FW_KEY_CERT \ + {{0x94, 0x77, 0xd6, 0x03}, {0xfb, 0x60}, {0xe4, 0x11}, 0x85, 0xdd, {0xb7, 0x10, 0x5b, 0x8c, 0xee, 0x04} } +#define UUID_NON_TRUSTED_FW_KEY_CERT \ + {{0x8a, 0xd5, 0x83, 0x2a}, {0xfb, 0x60}, {0xe4, 0x11}, 0x8a, 0xaf, {0xdf, 0x30, 0xbb, 0xc4, 0x98, 0x59} } +/* Content certificates */ +#define UUID_TRUSTED_BOOT_FW_CERT \ + {{0xd6, 0xe2, 0x69, 0xea}, {0x5d, 0x63}, {0xe4, 0x11}, 0x8d, 0x8c, {0x9f, 0xba, 0xbe, 0x99, 0x56, 0xa5} } +#define UUID_SCP_FW_CONTENT_CERT \ + {{0x44, 0xbe, 0x6f, 0x04}, {0x5e, 0x63}, {0xe4, 0x11}, 0xb2, 0x8b, {0x73, 0xd8, 0xea, 0xae, 0x96, 0x56} } +#define UUID_SOC_FW_CONTENT_CERT \ + {{0xe2, 0xb2, 0x0c, 0x20}, {0x5e, 0x63}, {0xe4, 0x11}, 0x9c, 0xe8, {0xab, 0xcc, 0xf9, 0x2b, 0xb6, 0x66} } +#define UUID_TRUSTED_OS_FW_CONTENT_CERT \ + {{0xa4, 0x9f, 0x44, 0x11}, {0x5e, 0x63}, {0xe4, 0x11}, 0x87, 0x28, {0x3f, 0x05, 0x72, 0x2a, 0xf3, 0x3d} } +#define UUID_NON_TRUSTED_FW_CONTENT_CERT \ + {{0x8e, 0xc4, 0xc1, 0xf3}, {0x5d, 0x63}, {0xe4, 0x11}, 0xa7, 0xa9, {0x87, 0xee, 0x40, 0xb2, 0x3f, 0xa7} } +/* Dynamic configs */ +#define UUID_HW_CONFIG \ + {{0x08, 0xb8, 0xf1, 0xd9}, {0xc9, 0xcf}, {0x93, 0x49}, 0xa9, 0x62, {0x6f, 0xbc, 0x6b, 0x72, 0x65, 0xcc} } +#define UUID_TB_FW_CONFIG \ + {{0x6c, 0x04, 0x58, 0xff}, {0xaf, 0x6b}, {0x7d, 0x4f}, 0x82, 0xed, {0xaa, 0x27, 0xbc, 0x69, 0xbf, 0xd2} } +#define UUID_SOC_FW_CONFIG \ + {{0x99, 0x79, 0x81, 0x4b}, {0x03, 0x76}, {0xfb, 0x46}, 0x8c, 0x8e, {0x8d, 0x26, 0x7f, 0x78, 0x59, 0xe0} } +#define UUID_TOS_FW_CONFIG \ + {{0x26, 0x25, 0x7c, 0x1a}, {0xdb, 0xc6}, {0x7f, 0x47}, 0x8d, 0x96, {0xc4, 0xc4, 0xb0, 0x24, 0x80, 0x21} } +#define UUID_NT_FW_CONFIG \ + {{0x28, 0xda, 0x98, 0x15}, {0x93, 0xe8}, {0x7e, 0x44}, 0xac, 0x66, {0x1a, 0xaf, 0x80, 0x15, 0x50, 0xf9} } + +typedef struct fip_toc_header { + uint32_t name; + uint32_t serial_number; + uint64_t flags; +} fip_toc_header_t; + +typedef struct fip_toc_entry { + uuid_t uuid; + uint64_t offset_address; + uint64_t size; + uint64_t flags; +} fip_toc_entry_t; + +#endif /* FIRMWARE_IMAGE_PACKAGE_H */ diff --git a/drivers/uuid.h b/drivers/uuid.h @@ -0,0 +1,62 @@ +/*- + * Copyright (c) 2002 Marcel Moolenaar + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $FreeBSD$ + */ + +/* + * Portions copyright (c) 2014, ARM Limited and Contributors. + * All rights reserved. + */ + +#ifndef UUID_H +#define UUID_H + +/* Length of a node address (an IEEE 802 address). */ +#define _UUID_NODE_LEN 6 + +/* Length of UUID string including dashes. */ +#define _UUID_STR_LEN 36 + +/* + * See also: + * http://www.opengroup.org/dce/info/draft-leach-uuids-guids-01.txt + * http://www.opengroup.org/onlinepubs/009629399/apdxa.htm + * + * A DCE 1.1 compatible source representation of UUIDs. + */ +struct uuid { + uint8_t time_low[4]; + uint8_t time_mid[2]; + uint8_t time_hi_and_version[2]; + uint8_t clock_seq_hi_and_reserved; + uint8_t clock_seq_low; + uint8_t node[_UUID_NODE_LEN]; +}; + +/* XXX namespace pollution? */ +typedef struct uuid uuid_t; + +#endif /* UUID_H */ diff --git a/target/native/rcode b/target/native/rcode @@ -4,4 +4,7 @@ dev pl011 base=0x1C090000,clk=24000000,rate=115200 pl011 base=0x1c0c0000,clk=24000000,rate=115200 cons + fip +blob + fip.bin 0x1000,0x100000 end diff --git a/target/native/rom.c b/target/native/rom.c @@ -131,6 +131,9 @@ namespace(void) // Link required after bind conslink((Attr []) {{"in", "/dev/uart0/raw"},{"out", "/dev/uart0/raw"},{0}}); + if (mount("#F", "/fip", "/blobs/fip.bin") < 0) + goto error; + return; error: