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 3

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

powered by: WebSVN 2.1.0

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