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

Subversion Repositories riscv_vhdl

[/] [riscv_vhdl/] [trunk/] [debugger/] [src/] [libdbg64g/] [services/] [exec/] [cmd/] [cmd_loadsrec.cpp] - Blame information for rev 5

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 5 sergeykhbr
/**
2
 * @file
3
 * @author     Sergey Khabarov - sergeykhbr@gmail.com
4
 * @brief      SREC-file loader command.
5
 */
6
 
7
#include "iservice.h"
8
#include "cmd_loadsrec.h"
9
#include <iostream>
10
 
11
namespace debugger {
12
 
13
//#define SHOW_USAGE_INFO
14
 
15
#ifdef SHOW_USAGE_INFO
16
#define ADDR_SPACE  (1 << 16)
17
char mark_[ADDR_SPACE] = {0};
18
 
19
void mark_addr(uint64_t addr, int len) {
20
    for (int i = 0; i < len; i++) {
21
        if ((addr + i) >= ADDR_SPACE) {
22
            continue;
23
        }
24
        mark_[addr + i] = 1;
25
    }
26
}
27
 
28
bool is_flash(unsigned addr) {
29
    if (addr >= 0x0450 && addr < 0x0500) {
30
        return true;
31
    }
32
    if (addr >= 0x0580 && addr < 0x0600) {
33
        return true;
34
    }
35
    if (addr >= 0x0E00 && addr < 0xfe00) {
36
        return true;
37
    }
38
    return false;
39
}
40
 
41
void print_flash_usage() {
42
    unsigned start_addr = 0;
43
    int cnt = 0;
44
    int total_cnt = 0;
45
 
46
    RISCV_printf(NULL, 0, "!!! Free Flash regions:", NULL);
47
    for (unsigned i = 0; i < ADDR_SPACE; i++) {
48
        if (!is_flash(i)) {
49
            if (cnt != 0) {
50
                RISCV_printf(NULL, 0, "    [%04x..%04x], length %d B",
51
                            start_addr, (start_addr + cnt - 1), cnt);
52
                total_cnt += cnt;
53
                cnt = 0;
54
            }
55
            continue;
56
        }
57
 
58
        if (mark_[i]) {
59
            if (cnt != 0) {
60
                RISCV_printf(NULL, 0, "    [%04x..%04x], length %d B",
61
                            start_addr, (start_addr + cnt - 1), cnt);
62
                total_cnt += cnt;
63
                cnt = 0;
64
            }
65
            continue;
66
        }
67
        if (cnt == 0) {
68
            start_addr = i;
69
        }
70
        cnt++;
71
    }
72
 
73
    RISCV_printf(NULL, 0, "    =========================", NULL);
74
    RISCV_printf(NULL, 0, "    Total: %d B", total_cnt);
75
}
76
#endif
77
 
78
CmdLoadSrec::CmdLoadSrec(ITap *tap, ISocInfo *info)
79
    : ICommand ("loadsrec", tap, info) {
80
 
81
    briefDescr_.make_string("Load SREC-file");
82
    detailedDescr_.make_string(
83
        "Description:\n"
84
        "    Load SREC-file to SOC target memory.\n"
85
        "Example:\n"
86
        "    loadsrec /home/hc08/image.s19\n");
87
}
88
 
89
bool CmdLoadSrec::isValid(AttributeType *args) {
90
    if ((*args)[0u].is_equal("loadsrec")
91
        && (args->size() == 2 || args->size() == 3)) {
92
        return CMD_VALID;
93
    }
94
    return CMD_INVALID;
95
}
96
 
97
void CmdLoadSrec::exec(AttributeType *args, AttributeType *res) {
98
    res->make_nil();
99
    if (!isValid(args)) {
100
        generateError(res, "Wrong argument list");
101
        return;
102
    }
103
 
104
    const char *filename = (*args)[1].to_string();
105
    FILE *fp = fopen(filename, "rb");
106
    if (!fp) {
107
        generateError(res, "File not found");
108
        return;
109
    }
110
    fseek(fp, 0, SEEK_END);
111
    int sz = ftell(fp);
112
    rewind(fp);
113
    uint8_t *image = new uint8_t[sz];
114
    fread(image, 1, sz, fp);
115
    fclose(fp);
116
 
117
    int off = check_header(image);
118
 
119
    DsuMapType *dsu = info_->getpDsu();
120
    uint64_t soft_reset = 1;
121
    uint64_t addr = reinterpret_cast<uint64_t>(&dsu->ulocal.v.soft_reset);
122
    tap_->write(addr, 8, reinterpret_cast<uint8_t *>(&soft_reset));
123
 
124
    uint64_t sec_addr;
125
    int sec_sz;
126
    uint8_t sec_data[1024];
127
    while ((off = readline(image, off, sec_addr, sec_sz, sec_data)) != 0) {
128
        tap_->write(sec_addr, sec_sz, sec_data);
129
#ifdef SHOW_USAGE_INFO
130
        mark_addr(sec_addr, sec_sz);
131
#endif
132
    }
133
 
134
//    soft_reset = 0;
135
//    tap_->write(addr, 8, reinterpret_cast<uint8_t *>(&soft_reset));
136
    delete [] image;
137
 
138
#ifdef SHOW_USAGE_INFO
139
    print_flash_usage();
140
#endif
141
}
142
 
143
uint8_t CmdLoadSrec::str2byte(uint8_t *pair) {
144
    uint8_t ret = 0;
145
    for (int i = 0; i < 2; i++) {
146
        ret <<= 4;
147
        if (pair[i] >= '0' && pair[i] <= '9') {
148
            ret |= pair[i] - '0';
149
        } else if (pair[i] >= 'A' && pair[i] <= 'F') {
150
            ret |= pair[i] - 'A' + 10;
151
        } else if (pair[i] >= 'a' && pair[i] <= 'f') {
152
            ret |= pair[i] - 'a' + 10;
153
        }
154
    }
155
    return ret;
156
}
157
 
158
bool CmdLoadSrec::check_crc(uint8_t *str, int sz) {
159
    uint8_t sum = 0;
160
    uint8_t *cur = str;
161
    for (int i = 0; i < sz; i++) {
162
        sum += str2byte(cur);
163
        cur += 2;
164
    }
165
    sum = ~sum;
166
    uint8_t ctrl = str2byte(cur);
167
    return ctrl == sum;
168
}
169
 
170
int CmdLoadSrec::check_header(uint8_t *img) {
171
    int off = 2;
172
    if (img[0] != 'S' || img[1] != '0') {
173
        return 0;
174
    }
175
    uint8_t sz = str2byte(&img[off]);
176
    if (!check_crc(&img[off], sz)) {
177
        return 0;
178
    }
179
 
180
    off += 2;
181
    uint16_t addr = str2byte(&img[off]);
182
    off += 2;
183
    addr = (addr << 8) + str2byte(&img[off]);
184
    off += 2;
185
    if (addr != 0) {
186
        return 0;
187
    }
188
    for (int i = 0; i < sz - 3; i++) {  // size (1) + addr (2) = 3
189
        header_data_[i] = static_cast<char>(str2byte(&img[off]));
190
        header_data_[i + 1] = 0;
191
        off += 2;
192
    }
193
    off += 2;  // skip checksum
194
    if (img[off] != '\r' || img[off + 1] != '\n') {
195
        return 0;
196
    }
197
    return off + 2;
198
}
199
 
200
int CmdLoadSrec::readline(uint8_t *img, int off,
201
                          uint64_t &addr, int &sz, uint8_t *out) {
202
    if (img[off++] != 'S') {
203
        return 0;
204
    }
205
    int bytes4addr = 0;
206
    switch (img[off++]) {    // 16-bits address only
207
    case '1':
208
        bytes4addr = 2; // 16-bits address
209
        break;
210
    case '2':
211
        bytes4addr = 3; // 24-bits address
212
        break;
213
    case '3':
214
        bytes4addr = 4; // 32-bits address
215
        break;
216
    default:
217
        return 0;
218
    }
219
    sz = str2byte(&img[off]);
220
    if (!check_crc(&img[off], sz)) {
221
        return 0;
222
    }
223
    sz -= 1;
224
    off += 2;
225
 
226
    addr = 0;
227
    for (int i = 0; i < bytes4addr; i++) {
228
        addr <<= 8;
229
        addr += str2byte(&img[off]);
230
        off += 2;
231
        sz--;
232
    }
233
#if 1
234
    // MCU specific endcoding:
235
    if (bytes4addr == 3) {
236
        uint64_t page = addr >> 16;
237
        addr = (0x4000 * page) + (addr & 0x3FFF);
238
    }
239
#endif
240
 
241
    for (int i = 0; i < sz; i++) {
242
        out[i] = static_cast<char>(str2byte(&img[off]));
243
        off += 2;
244
    }
245
    off += 2;  // skip checksum
246
    if (img[off] != '\r' || img[off + 1] != '\n') {
247
        return 0;
248
    }
249
    return off + 2;
250
}
251
 
252
}  // namespace debugger

powered by: WebSVN 2.1.0

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