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