blob: 9dd6c92ef4bf76c6f633273418103a1dbd737efc [file] [log] [blame]
Olivier Deprezcb4c5622019-09-19 17:46:46 +02001/*
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 ******************************************************************************/
17static 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
23static 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 ******************************************************************************/
30static 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
53static 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 ******************************************************************************/
61static 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
82static int rootstat(chan_t *channel, const char *file, dir_t *dir)
83{
84 return devstat(channel, file, dir, NULL, 0, rootgen);
85}
86
87const 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};