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 ******************************************************************************/ 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 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 ******************************************************************************/ 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 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