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

Subversion Repositories s80186

[/] [s80186/] [trunk/] [tests/] [jtag/] [JTAGCPU.cpp] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 jamieiles
// Copyright Jamie Iles, 2017
2
//
3
// This file is part of s80x86.
4
//
5
// s80x86 is free software: you can redistribute it and/or modify
6
// it under the terms of the GNU General Public License as published by
7
// the Free Software Foundation, either version 3 of the License, or
8
// (at your option) any later version.
9
//
10
// s80x86 is distributed in the hope that it will be useful,
11
// but WITHOUT ANY WARRANTY; without even the implied warranty of
12
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
// GNU General Public License for more details.
14
//
15
// You should have received a copy of the GNU General Public License
16
// along with s80x86.  If not, see <http://www.gnu.org/licenses/>.
17
 
18
#include <iostream>
19
#include <stdexcept>
20
#include <unistd.h>
21
 
22
#include <fstream>
23
#include "JTAGCPU.h"
24
 
25
extern "C" {
26
#include <jtag.h>
27
}
28
 
29
enum StatusControlBits {
30
    STATUS_CONTROL_RUN = (1 << 0),
31
    STATUS_CONTROL_RESET = (1 << 1),
32
    STATUS_CONTROL_WR_EN = (1 << 16),
33
};
34
 
35
union reg_converter {
36
    uint16_t v16;
37
    uint8_t v8[2];
38
};
39
 
40
using JTAGError = std::runtime_error;
41
 
42
JTAGCPU::JTAGCPU(const std::string &test_name) : test_name(test_name)
43
{
44
    if (jtag_open_virtual_device(0x00))
45
        throw JTAGError("Failed to open Virtual JTAG");
46
 
47
    write_scr(0);
48
    while (read_scr() & STATUS_CONTROL_RUN)
49
        continue;
50
}
51
 
52
JTAGCPU::~JTAGCPU()
53
{
54
    write_scr(STATUS_CONTROL_RUN);
55
    debug_run_proc(0, false);
56
    while (!(read_scr() & STATUS_CONTROL_RUN))
57
        continue;
58
}
59
 
60
void JTAGCPU::write_scr(uint16_t v)
61
{
62
    if (jtag_vir(1))
63
        throw JTAGError("Unable to write VIR");
64
    if (jtag_vdr(17, STATUS_CONTROL_WR_EN | v, NULL))
65
        throw JTAGError("Unable to write VIR");
66
}
67
 
68
uint16_t JTAGCPU::read_scr()
69
{
70
    uint32_t v;
71
 
72
    if (jtag_vir(1))
73
        throw JTAGError("Unable to write VIR");
74
    if (jtag_vdr(17, 0, &v))
75
        throw JTAGError("Unable to read VIR");
76
 
77
    return static_cast<uint16_t>(v);
78
}
79
 
80
uint16_t JTAGCPU::debug_read_data()
81
{
82
    uint32_t v;
83
 
84
    if (jtag_vir(2))
85
        throw JTAGError("Unable to write VIR");
86
 
87
    do {
88
        if (jtag_vdr(17, 0, &v))
89
            throw JTAGError("Unable to write VIR");
90
    } while (!(v & (1 << 16)));
91
 
92
    return static_cast<uint16_t>(v);
93
}
94
 
95
uint16_t JTAGCPU::debug_run_proc(unsigned addr, bool block)
96
{
97
    if (jtag_vir(3))
98
        throw JTAGError("Unable to write VIR");
99
    if (jtag_vdr(8, addr, NULL))
100
        throw JTAGError("Unable to write VIR");
101
 
102
    if (!block)
103
        return 0;
104
 
105
    while (read_scr() & STATUS_CONTROL_RUN)
106
        continue;
107
 
108
    return debug_read_data();
109
}
110
 
111
void JTAGCPU::debug_step()
112
{
113
    debug_run_proc(0x00);
114
}
115
 
116
void JTAGCPU::reset()
117
{
118
    write_scr(STATUS_CONTROL_RESET);
119
    write_scr(0);
120
    while (read_scr() & STATUS_CONTROL_RUN)
121
        continue;
122
 
123
    // All interrupts offset by 8 to not conflict with reserved vectors.
124
    write_io8(0xfff5, 8);
125
}
126
 
127
void JTAGCPU::write_reg(GPR regnum, uint16_t val)
128
{
129
    if (regnum == IP)
130
        write_ip(val);
131
    else if (regnum >= ES && regnum <= DS)
132
        write_sr(regnum, val);
133
    else
134
        write_gpr(regnum, val);
135
}
136
 
137
void JTAGCPU::write_sr(GPR regnum, uint16_t val)
138
{
139
    debug_write_data(val);
140
    debug_run_proc(0x13 + static_cast<int>(regnum));
141
}
142
 
143
void JTAGCPU::debug_write_data(uint16_t val)
144
{
145
    if (jtag_vir(2))
146
        throw JTAGError("Unable to write VIR");
147
    if (jtag_vdr(17, (1 << 16) | val, NULL))
148
        throw JTAGError("Unable to write VIR");
149
}
150
 
151
void JTAGCPU::write_ip(uint16_t val)
152
{
153
    debug_write_data(val);
154
    debug_run_proc(0x11);
155
}
156
 
157
void JTAGCPU::write_gpr(GPR regnum, uint16_t val)
158
{
159
    if (regnum < NUM_16BIT_REGS) {
160
        debug_write_data(val);
161
        debug_run_proc(0x13 + static_cast<int>(regnum));
162
    } else {
163
        auto regsel = (regnum - AL) & 0x3;
164
        reg_converter conv;
165
        conv.v16 = this->read_reg(static_cast<GPR>(regsel));
166
 
167
        conv.v8[regnum >= AH] = val;
168
 
169
        debug_write_data(conv.v16);
170
        debug_run_proc(0x13 + static_cast<int>(regsel));
171
    }
172
}
173
 
174
uint16_t JTAGCPU::read_reg(GPR regnum) const
175
{
176
    if (regnum == IP)
177
        return const_cast<JTAGCPU *>(this)->read_ip();
178
    else if (regnum >= ES && regnum <= DS)
179
        return const_cast<JTAGCPU *>(this)->read_sr(regnum);
180
    else
181
        return const_cast<JTAGCPU *>(this)->read_gpr(regnum);
182
}
183
 
184
uint16_t JTAGCPU::read_ip()
185
{
186
    return debug_run_proc(0x0f);
187
}
188
 
189
uint16_t JTAGCPU::read_gpr(GPR regnum)
190
{
191
    if (regnum < NUM_16BIT_REGS)
192
        return debug_run_proc(0x03 + static_cast<int>(regnum));
193
 
194
    auto regsel = static_cast<int>(regnum - AL) & 0x3;
195
    reg_converter conv;
196
 
197
    conv.v16 = debug_run_proc(0x03 + static_cast<int>(regsel));
198
 
199
    return conv.v8[regnum >= AH];
200
}
201
 
202
uint16_t JTAGCPU::read_sr(GPR regnum)
203
{
204
    return debug_run_proc(0x03 + static_cast<int>(regnum));
205
}
206
 
207
size_t JTAGCPU::step()
208
{
209
    ++num_cycles;
210
 
211
    this->debug_step();
212
 
213
    return 0;
214
}
215
 
216
void JTAGCPU::write_flags(uint16_t val)
217
{
218
    debug_write_data(val);
219
    debug_run_proc(0x12);
220
}
221
 
222
uint16_t JTAGCPU::read_flags() const
223
{
224
    return const_cast<JTAGCPU *>(this)->debug_run_proc(0x10);
225
}
226
 
227
bool JTAGCPU::has_trapped()
228
{
229
    auto int_cs = read_mem16(0, VEC_INT + 2);
230
    auto int_ip = read_mem16(0, VEC_INT + 0);
231
 
232
    return read_sr(CS) == int_cs && read_ip() == int_ip;
233
}
234
 
235
void JTAGCPU::write_mem8(uint16_t segment, uint16_t addr, uint8_t val)
236
{
237
    auto prev_ds = read_reg(DS);
238
 
239
    write_reg(DS, segment);
240
    write_mar(addr);
241
    write_mdr(val);
242
    debug_run_proc(0x23); // Write mem 8
243
    write_reg(DS, prev_ds);
244
}
245
 
246
void JTAGCPU::write_mem16(uint16_t segment, uint16_t addr, uint16_t val)
247
{
248
    auto prev_ds = read_reg(DS);
249
 
250
    write_reg(DS, segment);
251
    write_mar(addr);
252
    write_mdr(val);
253
    debug_run_proc(0x24); // Write mem 16
254
    write_reg(DS, prev_ds);
255
}
256
 
257
void JTAGCPU::write_vector8(uint16_t segment,
258
                            uint16_t addr,
259
                            const std::vector<uint8_t> &v)
260
{
261
    auto prev_ds = read_reg(DS);
262
 
263
    write_reg(DS, segment);
264
 
265
    write_mar(addr);
266
    for (auto &b : v) {
267
        write_mdr(b);
268
        debug_run_proc(0x23); // Write mem 8
269
    }
270
 
271
    write_reg(DS, prev_ds);
272
}
273
 
274
void JTAGCPU::write_vector16(uint16_t segment,
275
                             uint16_t addr,
276
                             const std::vector<uint16_t> &v)
277
{
278
    auto prev_ds = read_reg(DS);
279
 
280
    write_reg(DS, segment);
281
 
282
    write_mar(addr);
283
    for (auto &b : v) {
284
        write_mdr(b);
285
        debug_run_proc(0x24); // Write mem 16
286
    }
287
 
288
    write_reg(DS, prev_ds);
289
}
290
 
291
void JTAGCPU::write_mem32(uint16_t segment, uint16_t addr, uint32_t val)
292
{
293
    write_mem16(segment, addr, val & 0xffff);
294
    write_mem16(segment, addr + 2, val >> 16);
295
}
296
 
297
void JTAGCPU::write_mar(uint16_t v)
298
{
299
    debug_write_data(v);
300
    debug_run_proc(0x1f);
301
}
302
 
303
void JTAGCPU::write_mdr(uint16_t v)
304
{
305
    debug_write_data(v);
306
    debug_run_proc(0x20);
307
}
308
 
309
uint8_t JTAGCPU::read_mem8(uint16_t segment, uint16_t addr)
310
{
311
    auto prev_ds = read_reg(DS);
312
 
313
    write_reg(DS, segment);
314
    write_mar(addr);
315
    uint8_t val = debug_run_proc(0x21); // Read mem 8
316
 
317
    write_reg(DS, prev_ds);
318
 
319
    return val;
320
}
321
 
322
uint16_t JTAGCPU::read_mem16(uint16_t segment, uint16_t addr)
323
{
324
    auto prev_ds = read_reg(DS);
325
 
326
    write_reg(DS, segment);
327
    write_mar(addr);
328
    uint16_t val = debug_run_proc(0x22); // Read mem 16
329
 
330
    write_reg(DS, prev_ds);
331
 
332
    return val;
333
}
334
 
335
uint32_t JTAGCPU::read_mem32(uint16_t segment, uint16_t addr)
336
{
337
    return read_mem16(segment, addr) |
338
           (static_cast<uint32_t>(read_mem16(segment, addr + 2)) << 16);
339
}
340
 
341
void JTAGCPU::write_io8(uint32_t addr, uint8_t val)
342
{
343
    write_mar(addr);
344
    write_mdr(val);
345
    debug_run_proc(0x27); // Write io 8
346
}
347
 
348
void JTAGCPU::write_io16(uint32_t addr, uint16_t val)
349
{
350
    write_mar(addr);
351
    write_mdr(val);
352
    debug_run_proc(0x28); // Write io 16
353
}
354
 
355
uint8_t JTAGCPU::read_io8(uint32_t addr)
356
{
357
    write_mar(addr);
358
    return debug_run_proc(0x25); // Read io 8
359
}
360
 
361
uint16_t JTAGCPU::read_io16(uint32_t addr)
362
{
363
    write_mar(addr);
364
    return debug_run_proc(0x26); // Read io 16
365
}
366
 
367
uint32_t JTAGCPU::idcode()
368
{
369
    uint32_t idcode = 0;
370
    jtag_vir(0);
371
    jtag_vdr(32, 0, &idcode);
372
 
373
    return idcode;
374
}

powered by: WebSVN 2.1.0

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