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

Subversion Repositories riscv_vhdl

[/] [riscv_vhdl/] [trunk/] [debugger/] [src/] [libdbg64g/] [services/] [remote/] [tcpcmd.cpp] - Blame information for rev 5

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 5 sergeykhbr
/**
2
 * @file
3
 * @copyright  Copyright 2017 GNSS Sensor Ltd. All right reserved.
4
 * @author     Sergey Khabarov - sergeykhbr@gmail.com
5
 * @brief      TCP commands parser/processor.
6
 */
7
 
8
#include "tcpcmd.h"
9
 
10
namespace debugger {
11
 
12
TcpCommands::TcpCommands(IService *parent) : IHap(HAP_All) {
13
    parent_ = parent;
14
    rxcnt_ = 0;
15
 
16
    cpu_.make_string("core0");
17
    executor_.make_string("cmdexec0");
18
    source_.make_string("src0");
19
 
20
    iexec_ = static_cast<ICmdExecutor *>(
21
        RISCV_get_service_iface(executor_.to_string(), IFACE_CMD_EXECUTOR));
22
 
23
    iclk_ = static_cast<IClock *>(
24
        RISCV_get_service_iface(cpu_.to_string(), IFACE_CLOCK));
25
    IService *iservcpu = static_cast<IService *>(
26
                        RISCV_get_service(cpu_.to_string()));
27
    cpuLogLevel_ = static_cast<AttributeType *>(
28
                        iservcpu->getAttribute("LogLevel"));
29
 
30
    iriscv_ = static_cast<ICpuRiscV *>(
31
        RISCV_get_service_iface(cpu_.to_string(), IFACE_CPU_RISCV));
32
 
33
    isrc_ = static_cast<ISourceCode *>(
34
        RISCV_get_service_iface(source_.to_string(), IFACE_SOURCE_CODE));
35
 
36
    char tstr[128];
37
    RISCV_sprintf(tstr, sizeof(tstr), "%s_halt", parent_->getObjName());
38
    RISCV_event_create(&eventHalt_, tstr);
39
    RISCV_sprintf(tstr, sizeof(tstr), "%s_delay_ms", parent_->getObjName());
40
    RISCV_event_create(&eventDelayMs_, tstr);
41
    RISCV_sprintf(tstr, sizeof(tstr), "%s_pwr", parent_->getObjName());
42
    RISCV_event_create(&eventPowerChanged_, tstr);
43
 
44
    RISCV_register_hap(static_cast<IHap *>(this));
45
}
46
 
47
TcpCommands::~TcpCommands() {
48
    RISCV_event_close(&eventHalt_);
49
    RISCV_event_close(&eventDelayMs_);
50
    RISCV_event_close(&eventPowerChanged_);
51
}
52
 
53
void TcpCommands::hapTriggered(IFace *isrc, EHapType type,
54
                                const char *descr) {
55
    if (type == HAP_Halt) {
56
        RISCV_event_set(&eventHalt_);
57
    } else if (type == HAP_CpuTurnON || type == HAP_CpuTurnOFF) {
58
        RISCV_event_set(&eventPowerChanged_);
59
    }
60
}
61
 
62
void TcpCommands::stepCallback(uint64_t t) {
63
    RISCV_event_set(&eventDelayMs_);
64
}
65
 
66
void TcpCommands::updateData(const char *buf, int buflen) {
67
    for (int i = 0; i < buflen; i++) {
68
        rxbuf_[rxcnt_++] = buf[i];
69
        if (buf[i] == 0) {
70
            processCommand();
71
            rxcnt_ = 0;
72
        }
73
    }
74
}
75
 
76
void TcpCommands::processCommand() {
77
    AttributeType cmd;
78
    cmd.from_config(rxbuf_);
79
    if (!cmd.is_list() || cmd.size() < 3) {
80
        return;
81
    }
82
 
83
    uint64_t idx = cmd[0u].to_uint64();
84
    resp_.make_list(2);
85
    resp_[0u].make_uint64(idx);
86
    resp_[1].make_string("OK");
87
 
88
    AttributeType &requestType = cmd[1];
89
    AttributeType &requestAction = cmd[2];
90
    AttributeType *resp = &resp_[1];
91
 
92
    if (requestType.is_equal("Command")) {
93
        /** Redirect command to console directly */
94
        iexec_->exec(requestAction.to_string(), resp, false);
95
    } else if (requestType.is_equal("Breakpoint")) {
96
        /** Breakpoints action */
97
        if (requestAction[0u].is_equal("Add")) {
98
            br_add(requestAction[1], resp);
99
        } else if (requestAction[0u].is_equal("Remove")) {
100
            br_rm(requestAction[1], resp);
101
        } else {
102
            resp->make_string("Wrong breakpoint command");
103
        }
104
    } else if (requestType.is_equal("Control")) {
105
        /** Run Control action */
106
        if (requestAction[0u].is_equal("GoUntil")) {
107
            go_until(requestAction[1], resp);
108
        } else if (requestAction[0u].is_equal("GoMsec")) {
109
            go_msec(requestAction[1], resp);
110
        } else if (requestAction[0u].is_equal("Step")) {
111
            step(requestAction[1].to_int(), resp);
112
        } else if (requestAction[0u].is_equal("PowerOn")) {
113
            power_on(resp);
114
            RISCV_debug("[%" RV_PRI64 "d] Command Power-On", idx);
115
        } else if (requestAction[0u].is_equal("PowerOff")) {
116
            power_off(resp);
117
            RISCV_debug("[%" RV_PRI64 "d] Command Power-Off", idx);
118
        } else {
119
            resp->make_string("Wrong control command");
120
        }
121
    } else if (requestType.is_equal("Status")) {
122
        /** Pump status */
123
        if (requestAction.is_equal("IsON")) {
124
            resp->make_boolean(true);
125
        } else if (requestAction.is_equal("IsHalt")) {
126
            //resp->make_boolean(iriscv_->isHalt());
127
        } else if (requestAction.is_equal("Steps")) {
128
            resp->make_uint64(iclk_->getStepCounter());
129
        } else if (requestAction.is_equal("TimeSec")) {
130
            double t1 = iclk_->getStepCounter() / iclk_->getFreqHz();
131
            resp->make_floating(t1);
132
        } else {
133
            resp->make_string("Wrong status command");
134
        }
135
    } else if (requestType.is_equal("Symbol")) {
136
        /** Symbols table conversion */
137
        if (requestAction[0u].is_equal("ToAddr")) {
138
            symb2addr(requestAction[1].to_string(), resp);
139
        } else if (requestAction[0u].is_equal("FromAddr")) {
140
            // todo:
141
        } else {
142
            resp->make_string("Wrong symbol command");
143
        }
144
    } else if (requestType.is_equal("Attribute")) {
145
        IService *isrv = static_cast<IService *>(
146
                        RISCV_get_service(requestAction[0u].to_string()));
147
        if (isrv) {
148
            AttributeType *iatr = static_cast<AttributeType *>(
149
                        isrv->getAttribute(requestAction[1].to_string()));
150
            if (iatr) {
151
                resp->clone(iatr);
152
            } else {
153
                resp->make_string("Attribute not found");
154
            }
155
        } else {
156
            resp->make_string("Service not found");
157
        }
158
    } else {
159
        resp->make_list(2);
160
        (*resp)[0u].make_string("ERROR");
161
        (*resp)[1].make_string("Wrong command format");
162
    }
163
    resp_.to_config();
164
}
165
 
166
AttributeType *TcpCommands::response() {
167
    return &resp_;
168
}
169
 
170
void TcpCommands::br_add(const AttributeType &symb, AttributeType *res) {
171
    uint64_t addr;
172
    if (symb.is_string()) {
173
        AttributeType t1;
174
        symb2addr(symb.to_string(), &t1);
175
        if (t1.is_nil()) {
176
            res->make_string("br_add: Symbol not found");
177
            return;
178
        }
179
        addr = t1.to_uint64();
180
    } else if (symb.is_integer()) {
181
        addr = symb.to_uint64();
182
    } else {
183
        res->make_string("br_add: Wrong format");
184
        return;
185
    }
186
    char tstr[256];
187
    RISCV_sprintf(tstr, sizeof(tstr), "br add 0x%x", addr);
188
    iexec_->exec(tstr, res, false);
189
}
190
 
191
void TcpCommands::br_rm(const AttributeType &symb, AttributeType *res) {
192
    uint64_t addr;
193
    if (symb.is_string()) {
194
        AttributeType t1;
195
        symb2addr(symb.to_string(), &t1);
196
        if (t1.is_nil()) {
197
            res->make_string("br_rm: Symbol not found");
198
            return;
199
        }
200
        addr = t1.to_uint64();
201
    } else if (symb.is_integer()) {
202
        addr = symb.to_uint64();
203
    } else {
204
        res->make_string("br_rm: Wrong format");
205
        return;
206
    }
207
    char tstr[256];
208
    RISCV_sprintf(tstr, sizeof(tstr), "br rm 0x%x", addr);
209
    iexec_->exec(tstr, res, false);
210
}
211
 
212
void TcpCommands::step(int cnt, AttributeType *res) {
213
    char tstr[16];
214
    RISCV_sprintf(tstr, sizeof(tstr), "c %d", cnt);
215
 
216
    int log_level_old = cpuLogLevel_->to_int();
217
    cpuLogLevel_->make_int64(4);
218
 
219
    RISCV_event_clear(&eventHalt_);
220
    iexec_->exec(tstr, res, false);
221
    RISCV_event_wait(&eventHalt_);
222
    cpuLogLevel_->make_int64(log_level_old);
223
}
224
 
225
void TcpCommands::go_until(const AttributeType &symb, AttributeType *res) {
226
    uint64_t addr;
227
    if (symb.is_string()) {
228
        AttributeType t1;
229
        symb2addr(symb.to_string(), &t1);
230
        if (t1.is_nil()) {
231
            res->make_string("br_rm: Symbol not found");
232
            return;
233
        }
234
        addr = t1.to_uint64();
235
    } else if (symb.is_integer()) {
236
        addr = symb.to_uint64();
237
    } else {
238
        res->make_string("br_rm: Wrong format");
239
        return;
240
    }
241
    // Add breakpoint
242
    char tstr[256];
243
    RISCV_sprintf(tstr, sizeof(tstr), "br add 0x%x", addr);
244
    iexec_->exec(tstr, res, false);
245
 
246
    // Set CPU LogLevel=1 to hide all debugging messages
247
    int log_level_old = cpuLogLevel_->to_int();
248
    cpuLogLevel_->make_int64(1);
249
 
250
    // Run simulation
251
    RISCV_event_clear(&eventHalt_);
252
    RISCV_sprintf(tstr, sizeof(tstr), "c", 0);
253
    iexec_->exec(tstr, res, false);
254
    RISCV_event_wait(&eventHalt_);
255
    cpuLogLevel_->make_int64(log_level_old);
256
 
257
    // Remove breakpoint:
258
    RISCV_sprintf(tstr, sizeof(tstr), "br rm 0x%x", addr);
259
    iexec_->exec(tstr, res, false);
260
}
261
 
262
void TcpCommands::symb2addr(const char *symbol, AttributeType *res) {
263
    res->make_nil();
264
    if (!isrc_) {
265
        return;
266
    }
267
    // Letters capitalization:
268
    char capital[256];
269
    int i = 0;
270
    while (symbol[i]) {
271
        capital[i] = symbol[i];
272
        if (symbol[i] >= 'a' && symbol[i] <= 'z') {
273
            capital[i] += ('A' - 'a');
274
        }
275
        i++;
276
        capital[i] = '\0';
277
    }
278
    uint64_t addr;
279
    if (isrc_->symbol2Address(capital, &addr) == 0) {
280
        res->make_uint64(addr);
281
        return;
282
    }
283
}
284
 
285
void TcpCommands::power_on(AttributeType *res) {
286
}
287
 
288
void TcpCommands::power_off(AttributeType *res) {
289
}
290
 
291
void TcpCommands::go_msec(const AttributeType &msec, AttributeType *res) {
292
    RISCV_event_clear(&eventDelayMs_);
293
    RISCV_event_clear(&eventHalt_);
294
 
295
    uint64_t step = iclk_->getStepCounter();
296
    double delta = 0.001 * iclk_->getFreqHz() * msec.to_float();
297
    if (delta == 0) {
298
        delta = 1;
299
    }
300
    iclk_->registerStepCallback(static_cast<IClockListener *>(this),
301
                                step + static_cast<uint64_t>(delta));
302
 
303
    iexec_->exec("c", res, false);
304
    RISCV_event_wait(&eventDelayMs_);
305
    iexec_->exec("s", res, false);
306
    RISCV_event_wait(&eventHalt_);
307
}
308
 
309
 
310
}  // namespace debugger

powered by: WebSVN 2.1.0

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