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 ******************************************************************************/
rootgen(chan_t * channel,const dirtab_t * tab,int ntab,int n,dir_t * dir)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
rootwalk(chan_t * channel,const char * name)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 ******************************************************************************/
rootread(chan_t * channel,void * buf,int size)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
rootstat(chan_t * channel,const char * file,dir_t * dir)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