OpenCores
URL https://opencores.org/ocsvn/riscv_vhdl/riscv_vhdl/trunk

Subversion Repositories riscv_vhdl

[/] [riscv_vhdl/] [trunk/] [debugger/] [src/] [libdbg64g/] [services/] [exec/] [cmdexec.cpp] - Blame information for rev 4

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 3 sergeykhbr
/**
2
 * @file
3
 * @copyright  Copyright 2016 GNSS Sensor Ltd. All right reserved.
4
 * @author     Sergey Khabarov - sergeykhbr@gmail.com
5
 * @brief      Command Executor implementation.
6
 */
7
 
8
#include <string.h>
9
#include "cmdexec.h"
10
#include "cmd/cmd_regs.h"
11
#include "cmd/cmd_reg.h"
12
#include "cmd/cmd_loadelf.h"
13 4 sergeykhbr
#include "cmd/cmd_loadsrec.h"
14 3 sergeykhbr
#include "cmd/cmd_log.h"
15
#include "cmd/cmd_isrunning.h"
16
#include "cmd/cmd_read.h"
17
#include "cmd/cmd_write.h"
18
#include "cmd/cmd_run.h"
19
#include "cmd/cmd_halt.h"
20
#include "cmd/cmd_csr.h"
21
#include "cmd/cmd_exit.h"
22
#include "cmd/cmd_memdump.h"
23
#include "cmd/cmd_br.h"
24
#include "cmd/cmd_cpi.h"
25
#include "cmd/cmd_status.h"
26
#include "cmd/cmd_reset.h"
27
#include "cmd/cmd_disas.h"
28
#include "cmd/cmd_busutil.h"
29
#include "cmd/cmd_symb.h"
30
#include "cmd/cmd_stack.h"
31 4 sergeykhbr
#include "cmd/cmd_loadbin.h"
32 3 sergeykhbr
 
33
namespace debugger {
34
 
35
/** Class registration in the Core */
36
REGISTER_CLASS(CmdExecutor)
37
 
38
CmdExecutor::CmdExecutor(const char *name)
39
    : IService(name) {
40
    registerInterface(static_cast<ICmdExecutor *>(this));
41
    registerAttribute("Tap", &tap_);
42
    registerAttribute("SocInfo", &socInfo_);
43
 
44
    //console_.make_list(0);
45
    tap_.make_string("");
46
    socInfo_.make_string("");
47
    cmds_.make_list(0);
48
 
49
    RISCV_mutex_init(&mutexExec_);
50
 
51
    tmpbuf_ = new uint8_t[tmpbuf_size_ = 4096];
52
    outbuf_ = new char[outbuf_size_ = 4096];
53
}
54
 
55
CmdExecutor::~CmdExecutor() {
56
    RISCV_mutex_destroy(&mutexExec_);
57
    delete [] tmpbuf_;
58
    delete [] outbuf_;
59
    for (unsigned i = 0; i < cmds_.size(); i++) {
60
        delete cmds_[i].to_iface();
61
    }
62
}
63
 
64
void CmdExecutor::postinitService() {
65
    itap_ = static_cast<ITap *>
66
            (RISCV_get_service_iface(tap_.to_string(), IFACE_TAP));
67
    info_ = static_cast<ISocInfo *>
68
            (RISCV_get_service_iface(socInfo_.to_string(),
69
                                    IFACE_SOC_INFO));
70
 
71
    // Core commands registration:
72
    registerCommand(new CmdBr(itap_, info_));
73
    registerCommand(new CmdBusUtil(itap_, info_));
74
    registerCommand(new CmdCpi(itap_, info_));
75
    registerCommand(new CmdCsr(itap_, info_));
76
    registerCommand(new CmdDisas(itap_, info_));
77
    registerCommand(new CmdExit(itap_, info_));
78
    registerCommand(new CmdHalt(itap_, info_));
79
    registerCommand(new CmdIsRunning(itap_, info_));
80 4 sergeykhbr
    registerCommand(new CmdLoadBin(itap_, info_));
81 3 sergeykhbr
    registerCommand(new CmdLoadElf(itap_, info_));
82 4 sergeykhbr
    registerCommand(new CmdLoadSrec(itap_, info_));
83 3 sergeykhbr
    registerCommand(new CmdLog(itap_, info_));
84
    registerCommand(new CmdMemDump(itap_, info_));
85
    registerCommand(new CmdRead(itap_, info_));
86
    registerCommand(new CmdRun(itap_, info_));
87
    registerCommand(new CmdReg(itap_, info_));
88
    registerCommand(new CmdRegs(itap_, info_));
89
    registerCommand(new CmdReset(itap_, info_));
90
    registerCommand(new CmdStack(itap_, info_));
91
    registerCommand(new CmdStatus(itap_, info_));
92
    registerCommand(new CmdSymb(itap_, info_));
93
    registerCommand(new CmdWrite(itap_, info_));
94
}
95
 
96
void CmdExecutor::registerCommand(ICommand *icmd) {
97
    AttributeType t1(icmd);
98
    cmds_.add_to_list(&t1);
99
}
100
 
101
void CmdExecutor::unregisterCommand(ICommand *icmd) {
102
    for (unsigned i = 0; i < cmds_.size(); i++) {
103
        if (cmds_[i].to_iface() == icmd) {
104
            cmds_.remove_from_list(i);
105
            break;
106
        }
107
    }
108
}
109
 
110
void CmdExecutor::exec(const char *line, AttributeType *res, bool silent) {
111
    RISCV_mutex_lock(&mutexExec_);
112
    res->make_nil();
113
 
114
    AttributeType cmd;
115
    if (line[0] == '[' || line[0] == '}') {
116
        cmd.from_config(line);
117
    } else {
118
        cmd.make_string(line);
119
    }
120
 
121
    AttributeType listArgs(Attr_List), *cmd_parsed;
122
    if (cmd.is_string()) {
123
        splitLine(const_cast<char *>(cmd.to_string()), &listArgs);
124
        cmd_parsed = &listArgs;
125
    } else {
126
        cmd_parsed = &cmd;
127
    }
128
    processSimple(cmd_parsed, res);
129
 
130
    RISCV_mutex_unlock(&mutexExec_);
131
 
132
    /** Do not output any information into console in silent mode: */
133
    if (silent) {
134
        return;
135
    }
136
    //RISCV_printf0("%s", outbuf_);
137
}
138
 
139
void CmdExecutor::commands(const char *substr, AttributeType *res) {
140
    if (!res->is_list()) {
141
        res->make_list(0);
142
    }
143
    AttributeType item;
144
    item.make_list(3);
145
    for (unsigned i = 0; i < cmds_.size(); i++) {
146
        ICommand *icmd = static_cast<ICommand *>(cmds_[i].to_iface());
147
        if (strstr(icmd->cmdName(), substr)) {
148
            item[0u].make_string(icmd->cmdName());
149
            item[1].make_string(icmd->briefDescr());
150
            item[2].make_string(icmd->detailedDescr());
151
            res->add_to_list(&item);
152
        }
153
    }
154
}
155
 
156
void CmdExecutor::processSimple(AttributeType *cmd, AttributeType *res) {
157
    outbuf_[outbuf_cnt_ = 0] = '\0';
158
    if (cmd->size() == 0) {
159
        return;
160
    }
161
 
162
    ICommand *icmd;
163
    if (!(*cmd)[0u].is_string()) {
164
        RISCV_error("Wrong command format", NULL);
165
        return;
166
    }
167
 
168
    if ((*cmd)[0u].is_equal("help")) {
169
        if (cmd->size() == 1) {
170
            RISCV_printf0("** List of supported commands: **", NULL);
171
            for (unsigned i = 0; i < cmds_.size(); i++) {
172
                icmd = static_cast<ICommand *>(cmds_[i].to_iface());
173
                RISCV_printf0("%13s   - %s",
174
                        icmd->cmdName(), icmd->briefDescr());
175
            }
176
        } else {
177
            const char *helpcmd = (*cmd)[1].to_string();
178
            icmd = getICommand(helpcmd);
179
            if (icmd) {
180
                RISCV_printf0("\n%s", icmd->detailedDescr());
181
            } else {
182 4 sergeykhbr
                RISCV_error("Command \\'%s\\' not found", helpcmd);
183 3 sergeykhbr
            }
184
        }
185
        return;
186
    }
187
 
188
    AttributeType u;
189
    icmd = getICommand(cmd);
190
    if (!icmd) {
191 4 sergeykhbr
         RISCV_error("Command \\'%s\\' not found. "
192
                    "Use \\'help\\' to list commands", (*cmd)[0u].to_string());
193 3 sergeykhbr
        return;
194
    }
195
    icmd->exec(cmd, res);
196
 
197
    if (cmdIsError(res)) {
198 4 sergeykhbr
        RISCV_error("Command \\'%s\\' error: \\'%s\\'",
199 3 sergeykhbr
            (*res)[1].to_string(), (*res)[2].to_string());
200
    }
201
}
202
 
203
bool CmdExecutor::cmdIsError(AttributeType *res) {
204
    if (!res->is_list() || res->size() != 3) {
205
        return false;
206
    }
207
    if (!(*res)[0u].is_string()) {
208
        return false;
209
    }
210
    return (*res)[0u].is_equal("ERROR");
211
}
212
 
213
ICommand *CmdExecutor::getICommand(AttributeType *args) {
214
    ICommand *ret = 0;
215
    for (unsigned i = 0; i < cmds_.size(); i++) {
216
        ret = static_cast<ICommand *>(cmds_[i].to_iface());
217
        if (ret && (ret->isValid(args) == CMD_VALID)) {
218
            return ret;
219
        }
220
    }
221
    return 0;
222
}
223
 
224
ICommand *CmdExecutor::getICommand(const char *name) {
225
    ICommand *ret = 0;
226
    for (unsigned i = 0; i < cmds_.size(); i++) {
227
        ret = static_cast<ICommand *>(cmds_[i].to_iface());
228
        if (ret && strcmp(ret->cmdName(), name) == 0) {
229
            return ret;
230
        }
231
    }
232
    return 0;
233
}
234
 
235
void CmdExecutor::splitLine(char *str, AttributeType *listArgs) {
236
    char *end = str;
237
    bool last = false;
238
    bool inside_string = false;
239
    char string_marker;
240
    while (*str) {
241
        if (*end == '\0') {
242
            last = true;
243
        } else if (*end == ' ' && !inside_string) {
244
            *end = '\0';
245
            while (*(end + 1) == ' ') {
246
                *(++end) = '\0';
247
            }
248
        } else  if (!inside_string && (*end == '"' || *end == '\'')) {
249
            inside_string = true;
250
            string_marker = *end;
251
        } else if (inside_string && string_marker == *end) {
252
            inside_string = false;
253
        }
254
 
255
        if (*end == '\0') {
256
            AttributeType item;
257
            if ((str[0] >= '0' && str[0] <= '9')
258
             || (str[0] == '[') || (str[0] == '"') || (str[0] == '\'')
259
             || (str[0] == '{') || (str[0] == '(')) {
260
                item.from_config(str);
261
            } else {
262
                item.make_string(str);
263
            }
264
            listArgs->add_to_list(&item);
265
            if (!last) {
266
                splitLine(end + 1, listArgs);
267
            }
268
            break;
269
        }
270
        ++end;
271
    }
272
}
273
 
274
int CmdExecutor::outf(const char *fmt, ...) {
275
    if (outbuf_cnt_ > (outbuf_size_ - 128)) {
276
        char *t = new char [2*outbuf_size_];
277
        memcpy(t, outbuf_, outbuf_size_);
278
        delete [] outbuf_;
279
        outbuf_size_ *= 2;
280
        outbuf_ = t;
281
    }
282
    va_list arg;
283
    va_start(arg, fmt);
284
    outbuf_cnt_ += vsprintf(&outbuf_[outbuf_cnt_], fmt, arg);
285
    va_end(arg);
286
    return outbuf_cnt_;
287
}
288
 
289
}  // namespace debugger

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.