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

Subversion Repositories riscv_vhdl

[/] [riscv_vhdl/] [trunk/] [debugger/] [src/] [libdbg64g/] [services/] [debug/] [edcl.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 2016 GNSS Sensor Ltd. All right reserved.
4
 * @author     Sergey Khabarov - sergeykhbr@gmail.com
5
 * @brief      Access to a hardware via Ethernet EDCL interface implementaion.
6
 */
7
 
8
#include "edcl_types.h"
9
#include "edcl.h"
10
 
11
namespace debugger {
12
 
13
/** Class registration in the Core */
14
REGISTER_CLASS(EdclService)
15
 
16
EdclService::EdclService(const char *name) : IService(name) {
17
    registerInterface(static_cast<ITap *>(this));
18
    registerAttribute("Transport", &transport_);
19
    registerAttribute("seq_cnt", &seq_cnt_);
20
    seq_cnt_.make_uint64(0);
21
    itransport_ = 0;
22
 
23
    dbgRdTRansactionCnt_ = 0;
24
}
25
 
26
void EdclService::postinitService() {
27
    IService *iserv =
28
        static_cast<IService *>(RISCV_get_service(transport_.to_string()));
29
    if (!iserv) {
30
        RISCV_error("Transport service '%'s not found",
31
                    transport_.to_string());
32
    }
33
    itransport_ = static_cast<ILink *>(iserv->getInterface(IFACE_LINK));
34
    if (!itransport_) {
35
        RISCV_error("UDP interface '%s' not found",
36
                     transport_.to_string());
37
    }
38
}
39
 
40
int EdclService::read(uint64_t addr, int bytes, uint8_t *obuf) {
41
    int txoff, rxoff;
42
    UdpEdclCommonType req = {0};
43
    UdpEdclCommonType rsp;
44
 
45
    if (!itransport_) {
46
        RISCV_error("UDP transport not defined, addr=%x", addr);
47
        return TAP_ERROR;
48
    }
49
 
50
    int rd_bytes = 0;
51
    while (rd_bytes < bytes && rd_bytes != TAP_ERROR) {
52
        req.control.request.seqidx =
53
                    static_cast<uint32_t>(seq_cnt_.to_uint64());
54
        req.control.request.write = 0;
55
        req.address = static_cast<uint32_t>(addr + rd_bytes);
56
        if ((bytes - rd_bytes) > EDCL_PAYLOAD_MAX_BYTES) {
57
            req.control.request.len =
58
                    static_cast<uint32_t>(EDCL_PAYLOAD_MAX_BYTES);
59
        } else {
60
            req.control.request.len = static_cast<uint32_t>(bytes - rd_bytes);
61
        }
62
 
63
        txoff = write16(tx_buf_, 0, req.offset);
64
        txoff = write32(tx_buf_, txoff, req.control.word);
65
        txoff = write32(tx_buf_, txoff, req.address);
66
 
67
        txoff = itransport_->sendData(tx_buf_, txoff);
68
        if (txoff == -1) {
69
            RISCV_error("Data sending error", NULL);
70
            rd_bytes = TAP_ERROR;
71
            break;
72
        }
73
 
74
        dbgRdTRansactionCnt_++;
75
        rxoff = itransport_->readData(rx_buf_, sizeof(rx_buf_));
76
        if (rxoff == -1) {
77
            RISCV_error("Data receiving error", NULL);
78
            rd_bytes = TAP_ERROR;
79
            break;
80
        }
81
        if (rxoff == 0) {
82
            RISCV_error("No response. Break read transaction[%d] at %08x",
83
                        dbgRdTRansactionCnt_, req.address);
84
            rd_bytes = TAP_ERROR;
85
            break;
86
        }
87
 
88
        rsp.control.word = read32(&rx_buf_[2]);
89
 
90
        const char *NAK[2] = {"ACK", "NAK"};
91
        RISCV_debug("EDCL read: %s[%d], len = %d",
92
                    NAK[rsp.control.response.nak],
93
                    rsp.control.response.seqidx,
94
                    rsp.control.response.len);
95
 
96
        // Retry with new sequence counter.
97
        if (rsp.control.response.nak) {
98
            RISCV_info("Sequence counter detected %d. Re-sending transaction.",
99
                         rsp.control.response.seqidx);
100
            seq_cnt_.make_uint64(rsp.control.response.seqidx);
101
            continue;
102
        }
103
 
104
        // Try to receive next packet:
105
        if (rsp.control.response.seqidx != seq_cnt_.to_uint32()) {
106
            RISCV_error("Wrong ID received %d != %d. Try again.",
107
                        seq_cnt_.to_uint32(), rsp.control.response.seqidx);
108
 
109
            rxoff = itransport_->readData(rx_buf_, sizeof(rx_buf_));
110
            if (rxoff <= 0) {
111
                rd_bytes = TAP_ERROR;
112
                break;
113
            }
114
            rsp.control.word = read32(&rx_buf_[2]);
115
            if (rsp.control.response.seqidx != seq_cnt_.to_uint32()) {
116
                rd_bytes = TAP_ERROR;
117
                break;
118
            }
119
        }
120
 
121
        memcpy(&obuf[rd_bytes], &rx_buf_[10], rsp.control.response.len);
122
        rd_bytes += rsp.control.response.len;
123
        seq_cnt_.make_uint64((seq_cnt_.to_uint64() + 1) & 0x3FFF);
124
    }
125
    return rd_bytes;
126
}
127
 
128
int EdclService::write(uint64_t addr, int bytes, uint8_t *ibuf) {
129
    int off;
130
    UdpEdclCommonType req = {0};
131
    UdpEdclCommonType rsp;
132
 
133
    if (!itransport_) {
134
        RISCV_error("UDP transport not defined, addr=%x", addr);
135
        return TAP_ERROR;
136
    }
137
 
138
    int wr_bytes = 0;
139
    while (wr_bytes < bytes && wr_bytes != -1) {
140
        req.control.request.seqidx =
141
                    static_cast<uint32_t>(seq_cnt_.to_uint64());
142
        req.control.request.write = 1;
143
        req.address = static_cast<uint32_t>(addr + wr_bytes);
144
        if ((bytes - wr_bytes) > EDCL_PAYLOAD_MAX_BYTES) {
145
            req.control.request.len =
146
                    static_cast<uint32_t>(EDCL_PAYLOAD_MAX_BYTES);
147
        } else {
148
            req.control.request.len = static_cast<uint32_t>(bytes - wr_bytes);
149
        }
150
 
151
        off = write16(tx_buf_, 0, req.offset);
152
        off = write32(tx_buf_, off, req.control.word);
153
        off = write32(tx_buf_, off, req.address);
154
        memcpy(&tx_buf_[off], &ibuf[wr_bytes], req.control.request.len);
155
 
156
 
157
        off = itransport_->sendData(tx_buf_, off + req.control.request.len);
158
        if (off == -1) {
159
            RISCV_error("Data sending error", NULL);
160
            wr_bytes = -1;
161
            break;
162
        }
163
 
164
        off = itransport_->readData(rx_buf_, sizeof(rx_buf_));
165
        if (off == -1) {
166
            RISCV_error("Data receiving error", NULL);
167
            wr_bytes = -1;
168
            break;
169
        }
170
        if (off == 0) {
171
            RISCV_error("No response. Break write transaction.", NULL);
172
            wr_bytes = -1;
173
            break;
174
        }
175
 
176
        rsp.control.word = read32(&rx_buf_[2]);
177
 
178
        // Warning:
179
        //   response length = 0;
180
        const char *NAK[2] = {"ACK", "NAK"};
181
        RISCV_debug("EDCL write: %s[%d], len = %d",
182
                    NAK[rsp.control.response.nak],
183
                    rsp.control.response.seqidx,
184
                    req.control.request.len);
185
 
186
        // Retry with new sequence counter.
187
        if (rsp.control.response.nak) {
188
            RISCV_info("Sequence counter detected %d. Re-sending transaction.",
189
                         rsp.control.response.seqidx);
190
            seq_cnt_.make_uint64(rsp.control.response.seqidx);
191
            continue;
192
        }
193
 
194
        wr_bytes += req.control.request.len;
195
        seq_cnt_.make_uint64(seq_cnt_.to_uint64() + 1);
196
    }
197
    return wr_bytes;
198
}
199
 
200
int EdclService::write16(uint8_t *buf, int off, uint16_t v) {
201
    buf[off++] = (uint8_t)((v >> 8) & 0xFF);
202
    buf[off++] = (uint8_t)(v & 0xFF);
203
    return off;
204
}
205
 
206
int EdclService::write32(uint8_t *buf, int off, uint32_t v) {
207
    buf[off++] = (uint8_t)((v >> 24) & 0xFF);
208
    buf[off++] = (uint8_t)((v >> 16) & 0xFF);
209
    buf[off++] = (uint8_t)((v >> 8) & 0xFF);
210
    buf[off++] = (uint8_t)(v & 0xFF);
211
    return off;
212
}
213
 
214
uint32_t EdclService::read32(uint8_t *buf) {
215
    return (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | (buf[3] << 0);
216
}
217
 
218
}  // namespace debugger

powered by: WebSVN 2.1.0

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