1 /* 2 * Copyright (c) 2019, Arm Limited. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #include <assert.h> 8 #include <common/debug.h> 9 #include <lib/debugfs.h> 10 11 #include "blobs.h" 12 #include "dev.h" 13 14 /******************************************************************************* 15 * This array contains the directories available from the root directory. 16 ******************************************************************************/ 17 static const dirtab_t dirtab[] = { 18 {"dev", CHDIR | DEV_ROOT_QDEV, 0, O_READ}, 19 {"blobs", CHDIR | DEV_ROOT_QBLOBS, 0, O_READ}, 20 {"fip", CHDIR | DEV_ROOT_QFIP, 0, O_READ} 21 }; 22 23 static const dirtab_t devfstab[] = { 24 }; 25 26 /******************************************************************************* 27 * This function exposes the elements of the root directory. 28 * It also exposes the content of the dev and blobs directories. 29 ******************************************************************************/ 30 static int rootgen(chan_t *channel, const dirtab_t *tab, int ntab, 31 int n, dir_t *dir) 32 { 33 switch (channel->qid & ~CHDIR) { 34 case DEV_ROOT_QROOT: 35 tab = dirtab; 36 ntab = NELEM(dirtab); 37 break; 38 case DEV_ROOT_QDEV: 39 tab = devfstab; 40 ntab = NELEM(devfstab); 41 break; 42 case DEV_ROOT_QBLOBS: 43 tab = blobtab; 44 ntab = NELEM(blobtab); 45 break; 46 default: 47 return 0; 48 } 49 50 return devgen(channel, tab, ntab, n, dir); 51 } 52 53 static int rootwalk(chan_t *channel, const char *name) 54 { 55 return devwalk(channel, name, NULL, 0, rootgen); 56 } 57 58 /******************************************************************************* 59 * This function copies at most n bytes from the element referred by c into buf. 60 ******************************************************************************/ 61 static int rootread(chan_t *channel, void *buf, int size) 62 { 63 const dirtab_t *dp; 64 dir_t *dir; 65 66 if ((channel->qid & CHDIR) != 0) { 67 if (size < sizeof(dir_t)) { 68 return -1; 69 } 70 71 dir = buf; 72 return dirread(channel, dir, NULL, 0, rootgen); 73 } 74 75 /* Only makes sense when using debug language */ 76 assert(channel->qid != DEV_ROOT_QBLOBCTL); 77 78 dp = &blobtab[channel->qid - DEV_ROOT_QBLOBCTL]; 79 return buf_to_channel(channel, buf, dp->data, size, dp->length); 80 } 81 82 static int rootstat(chan_t *channel, const char *file, dir_t *dir) 83 { 84 return devstat(channel, file, dir, NULL, 0, rootgen); 85 } 86 87 const dev_t rootdevtab = { 88 .id = '/', 89 .stat = rootstat, 90 .clone = devclone, 91 .attach = devattach, 92 .walk = rootwalk, 93 .read = rootread, 94 .write = deverrwrite, 95 .mount = deverrmount, 96 .seek = devseek 97 }; 98