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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [orpsocv2/] [bench/] [sysc/] [src/] [DebugUnitSC.cpp] - Blame information for rev 508

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 63 julius
// ----------------------------------------------------------------------------
2
 
3
// SystemC OpenRISC 1000 Debug Unit: implementation
4
 
5
// Copyright (C) 2008  Embecosm Limited <info@embecosm.com>
6
// Copyright (C) 2009  ORSoC
7
 
8
// Contributor Jeremy Bennett <jeremy.bennett@embecosm.com>
9
// Contributor Julius Baxter <julius@orsoc.se>
10
 
11
// This file is part of the GDB interface to the cycle accurate model of the
12
// OpenRISC 1000 based system-on-chip, ORPSoC, built using Verilator.
13
 
14
// This program is free software: you can redistribute it and/or modify it
15
// under the terms of the GNU Lesser General Public License as published by
16
// the Free Software Foundation, either version 3 of the License, or (at your
17
// option) any later version.
18
 
19
// This program is distributed in the hope that it will be useful, but WITHOUT
20
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
22
// License for more details.
23
 
24
// You should have received a copy of the GNU Lesser General Public License
25
// along with this program.  If not, see <http://www.gnu.org/licenses/>.
26
 
27
// ----------------------------------------------------------------------------
28
 
29
// $Id$
30
 
31
#include <iostream>
32
#include <iomanip>
33
 
34
#include "DebugUnitSC.h"
35
#include "Utils.h"
36
 
37
using sc_core::sc_event;
38
using sc_core::sc_fifo;
39
using sc_core::sc_module_name;
40
 
41
//-----------------------------------------------------------------------------
42
//! Constructor for the Debug Unit
43
 
44
//! This module is entirely subservient to the GDB server. It has no SystemC
45
//! processes of its own. It provides services via calls to its API.
46
 
47
//! The current scan chain is marked as undefined, and the current JTAG scan
48
//! chain is maked as undefined.
49
 
50
//! Caches for SPR and memory access are initialized.
51
 
52
//! This makes use of the Embecosm cycle accurate SystemC JTAG interface.
53
 
54
//! @see Embecosm Application Note 5 "Using JTAG with SystemC: Implementation
55
//!      of a Cycle Accurate Interface"
56
//!      (http://www.embecosm.com/download/ean5.html)
57
 
58
//! @param[in] name             Name of this module, passed to the parent
59
//!                             constructor. 
60
//! @param[in] _tapActionQueue  Pointer to fifo of actions to be performed by
61
//!                             the JTAG interface
62
//-----------------------------------------------------------------------------
63 462 julius
DebugUnitSC::DebugUnitSC(sc_module_name name, sc_fifo < TapAction * >*_tapActionQueue):
64
sc_module(name),
65
tapActionQueue(_tapActionQueue),
66
stallState(UNKNOWN), currentScanChain(OR1K_SC_UNDEF)
67 63 julius
{
68
#ifdef NOCACHE
69 462 julius
        npcCacheIsValid = false;        // Always cache NPC
70 63 julius
#else
71 462 julius
        sprCache = new SprCache();
72
        memCache = new MemCache();
73 63 julius
#endif
74
 
75 462 julius
}                               // DebugUnitSC ()
76 63 julius
 
77
//-----------------------------------------------------------------------------
78
//! Destructor
79
 
80
//! Free up data structures
81
//-----------------------------------------------------------------------------
82 462 julius
DebugUnitSC::~DebugUnitSC()
83 63 julius
{
84
#ifndef NOCACHE
85 462 julius
        delete memCache;
86
        delete sprCache;
87 63 julius
#endif
88
 
89 462 julius
}                               // ~DebugUnitSC
90 63 julius
 
91
//-----------------------------------------------------------------------------
92
//! Reset the Debug Unit
93
 
94
//! This is just a reset of the JTAG. It is quite possible to reset the debug
95
//! unit without resetting the whole target.
96
 
97
//! @note Must be called from a SystemC thread, because of the use of wait()
98
//-----------------------------------------------------------------------------
99
void
100 462 julius
 DebugUnitSC::resetDebugUnit()
101 63 julius
{
102 462 julius
        sc_event *done = new sc_event();
103
        TapActionReset *resetAction;
104 63 julius
 
105 462 julius
        // Create and queue the reset action and wait for it to complete
106
        resetAction = new TapActionReset(done);
107
        tapActionQueue->write(resetAction);
108
        wait(*done);
109 63 julius
 
110 462 julius
        delete resetAction;
111
        delete done;
112 63 julius
 
113 462 julius
}                               // resetDebugUnit ()
114 63 julius
 
115
//-----------------------------------------------------------------------------
116
//! Reset the processor
117
 
118
//! Read the RISCOP register, OR in the reset bit and write it back.
119
 
120
//! After reset, the processor is known to be unstalled.
121
//-----------------------------------------------------------------------------
122 462 julius
void DebugUnitSC::reset()
123 63 julius
{
124 462 julius
        writeRiscop(readRiscop() | RISCOP_RESET);
125
        stallState = UNKNOWN;
126 63 julius
 
127 462 julius
}                               // reset ()
128 63 julius
 
129
//-----------------------------------------------------------------------------
130
//! Stall the processor
131
 
132
//! Read the RISCOP register, OR in the stall bit and write it back.
133
//-----------------------------------------------------------------------------
134 462 julius
void DebugUnitSC::stall()
135 63 julius
{
136 462 julius
        writeRiscop( /*readRiscop () | */ RISCOP_STALL);
137
        stallState = STALLED;
138 63 julius
 
139 462 julius
}                               // stall ()
140 63 julius
 
141
//-----------------------------------------------------------------------------
142
//! Unstall the processor
143
 
144
//! Read the RISCOP register, AND out the stall bit and write it back. After
145
//! this the NPC cache will be invalid.
146
 
147
//! @note Don't be tempted to read back for confirmation. Single stepping
148
//!       will already have stalled the processor again!
149
//-----------------------------------------------------------------------------
150 462 julius
void DebugUnitSC::unstall()
151 63 julius
{
152 462 julius
        writeRiscop( /*readRiscop () & ~RISCOP_STALL */ 0);
153
        stallState = UNKNOWN;
154 63 julius
 
155
#ifdef NOCACHE
156 462 julius
        npcCacheIsValid = false;        // Always cache NPC
157 63 julius
#else
158 462 julius
        // Clear the caches
159
        sprCache->clear();
160
        memCache->clear();
161 63 julius
#endif
162
 
163 462 julius
}                               // unstall ()
164 63 julius
 
165
//-----------------------------------------------------------------------------
166
//! Report if the processor is stalled.
167
 
168
//! A stalled processor cannot spontaneously "unstall", so if the stallState
169
//! flag is STALLED, that value is returned. Otherwise the target is
170
//! interrogated to determine the status.
171
 
172
//! @return  TRUE if the processor is known to be stalled
173
//-----------------------------------------------------------------------------
174 462 julius
bool DebugUnitSC::isStalled()
175 63 julius
{
176 462 julius
        if (STALLED == stallState) {
177
                return true;
178
        }
179 63 julius
 
180 462 julius
        uint32_t riscop = readRiscop();
181
        /* For some reason the reset bit is skipped over somewhere, so we should
182
           just get riscop = 1 if it's stalled */
183 63 julius
 
184 462 julius
        //stallState = (RISCOP_STALL == (riscop & RISCOP_STALL)) ? STALLED : UNKNOWN;
185
        stallState = riscop ? STALLED : UNKNOWN;
186 63 julius
 
187 462 julius
        return STALLED == stallState;
188 63 julius
 
189 462 julius
}                               // isStalled ()
190 63 julius
 
191
//-----------------------------------------------------------------------------
192
//! Read the value of an OpenRISC 1000 Special Purpose Register
193
 
194
//! First see if we have the value in the cache, and if so return
195
//! it. Otherwise, select the RISC_DEBUG scan chain and read from JTAG,
196
//! storing the result in the cache.
197
 
198
//! @param[in]  sprNum  The SPR to read
199
 
200
//! @return  The value of the SPR
201
//-----------------------------------------------------------------------------
202 462 julius
uint32_t DebugUnitSC::readSpr(uint16_t sprNum)
203 63 julius
{
204 462 julius
        uint32_t cachedValue;
205 63 julius
 
206
#ifdef NOCACHE
207 462 julius
        // Always check NPC cache
208
        if ((STALLED == stallState) && (sprNum == SPR_NPC) && npcCacheIsValid) {
209
                return npcCachedValue;
210
        }
211 63 julius
#else
212 462 julius
        // Use any cached value if we are stalled.
213
        if ((STALLED == stallState) && sprCache->read(sprNum, cachedValue)) {
214
                return cachedValue;     // Already there, no more to do
215
        }
216 63 julius
#endif
217
 
218 462 julius
        // Read the value
219
        selectDebugModule(OR1K_SC_CPU0);
220
        cachedValue = readJtagReg(sprNum);
221 63 julius
 
222
#ifdef NOCACHE
223 462 julius
        // Always update the NPC cache
224
        if ((STALLED == stallState) && (sprNum == SPR_NPC)) {
225
                npcCachedValue = cachedValue;
226
                npcCacheIsValid = true;
227
        }
228 63 julius
#else
229 462 julius
        // Update the cache if we are stalled
230
        if (STALLED == stallState) {
231
                sprCache->write(sprNum, cachedValue, sprNum == SPR_NPC);
232
        }
233 63 julius
#endif
234
 
235 462 julius
        return cachedValue;
236 63 julius
 
237 462 julius
}                               // readSpr ()
238 63 julius
 
239
//-----------------------------------------------------------------------------
240
//! Write the value of an OpenRISC 1000 Special Purpose Register
241
 
242
//! First look to see if we are stalled and the value is cached. If the value
243
//! has not changed, then we need to no more. Otherwise cache the value prior
244
//! to writing it.
245
 
246
//! Select the RISC_DEBUG scan chain and write to JTAG
247
 
248
//! @param[in] sprNum  The SPR to write
249
//! @param[in] value   The value to write
250
//-----------------------------------------------------------------------------
251 462 julius
void DebugUnitSC::writeSpr(uint16_t sprNum, uint32_t value)
252 63 julius
{
253
#ifdef NOCACHE
254 462 julius
        // Always cache the NPC
255
        if ((STALLED == stallState) && (SPR_NPC == sprNum)) {
256
                // Have we already cached this NPC value?
257
                if (npcCacheIsValid && (value == npcCachedValue)) {
258
                        return;
259
                } else {
260
                        npcCachedValue = value;
261
                        npcCacheIsValid = true;
262
                }
263 63 julius
        }
264
#else
265 462 julius
        if (STALLED == stallState) {
266
                // Have we already cached this value?
267
                uint32_t cachedValue;
268
                if (sprCache->read(sprNum, cachedValue) &&
269
                    (value == cachedValue)) {
270
                        return; // Already there, no more to do
271
                } else {
272
                        sprCache->write(sprNum, value, sprNum == SPR_NPC);
273
                }
274 63 julius
        }
275
#endif
276
 
277 462 julius
        // Write the SPR
278
        selectDebugModule(OR1K_SC_CPU0);
279
        writeJtagReg(sprNum, value);
280 63 julius
 
281 462 julius
}                               // writeSpr ()
282 63 julius
 
283
//-----------------------------------------------------------------------------
284
//! AND the contents of an SPR with a value
285
 
286
//! A convenience combination of read and write
287
 
288
//! @param[in] sprNum  The SPR to write
289
//! @param[in] value   The value to AND into the register
290
//-----------------------------------------------------------------------------
291 462 julius
void DebugUnitSC::andSpr(uint16_t sprNum, uint32_t value)
292 63 julius
{
293 462 julius
        writeSpr(sprNum, readSpr(sprNum) & value);
294 63 julius
 
295 462 julius
}                               // andSpr ()
296 63 julius
 
297
//-----------------------------------------------------------------------------
298
//! OR the contents of an SPR with a value
299
 
300
//! A convenience combination of read and write
301
 
302
//! @param[in] sprNum  The SPR to write
303
//! @param[in] value   The value to OR into the register
304
//-----------------------------------------------------------------------------
305 462 julius
void DebugUnitSC::orSpr(uint16_t sprNum, uint32_t value)
306 63 julius
{
307 462 julius
        writeSpr(sprNum, readSpr(sprNum) | value);
308 63 julius
 
309 462 julius
}                               // orSpr ()
310 63 julius
 
311
//-----------------------------------------------------------------------------
312
//! Read a 32-bit word from the OpenRISC 1000 memory
313
 
314
//! Select the WISHBONE scan chain, then write the register. The data is in
315
//! model endianness and passed on without modification.
316
 
317
//! @todo Provide code to check if the read was from a valid address.
318
 
319
//! @param[in] addr  The address to read from
320
 
321
//! @return  The 32-bit value read
322
//-----------------------------------------------------------------------------
323 462 julius
uint32_t DebugUnitSC::readMem32(uint32_t addr)
324 63 julius
{
325 462 julius
        uint32_t cachedValue;
326 63 julius
 
327
#ifndef NOCACHE
328 462 julius
        // Use any cached value if we are stalled.
329
        if ((STALLED == stallState) && memCache->read(addr, cachedValue)) {
330
                return cachedValue;     // Already there, no more to do
331
        }
332 63 julius
#endif
333
 
334 462 julius
        // Read the value
335
        selectDebugModule(OR1K_SC_WISHBONE);
336
        cachedValue = readJtagReg(addr);
337 63 julius
 
338
#ifndef NOCACHE
339 462 julius
        // Update the cache if we are stalled
340
        if (STALLED == stallState) {
341
                memCache->write(addr, cachedValue);
342
        }
343 63 julius
#endif
344
 
345 462 julius
        return cachedValue;
346 63 julius
 
347 462 julius
}                               // readMem32 ()
348 63 julius
 
349
//-----------------------------------------------------------------------------
350
//! Write a 32-bit word to the OpenRISC 1000 memory
351
 
352
//! Select the WISHBONE scan chain, then write the register. The data is in
353
//! model endianness and passed on without modification.
354
 
355
//! @todo Provide code to check if the write was to a valid address.
356
 
357
//! @param[in] addr   The address to write to
358
//! @param[in] value  The 32-bit value to write
359
 
360
//! @return  True if the write was successful. For now all writes are
361
//           successful.
362
//-----------------------------------------------------------------------------
363 462 julius
bool DebugUnitSC::writeMem32(uint32_t addr, uint32_t value)
364 63 julius
{
365
#ifndef NOCACHE
366 462 julius
        if (STALLED == stallState) {
367
                // Have we already cached this value?
368
                uint32_t cachedValue;
369
                if (memCache->read(addr, cachedValue) && (value == cachedValue)) {
370
                        return true;    // Already there, no more to do
371
                } else {
372
                        memCache->write(addr, value);   // Write for the future
373
                }
374 63 julius
        }
375
#endif
376
 
377 462 julius
        // Write the memory
378
        selectDebugModule(OR1K_SC_WISHBONE);
379
        writeJtagReg(addr, value);
380 63 julius
 
381 462 julius
        return true;
382 63 julius
 
383 462 julius
}                               // writeMem32 ()
384 63 julius
 
385
//-----------------------------------------------------------------------------
386
//! Read a byte from the OpenRISC 1000 main memory
387
 
388
//! All we can get are 32-bits words, so we have to unpick the value.
389
 
390
//! The underlying 32-bit routines take target endian arguments and return
391
//! target endian results. We need to convert to host endianness to access the
392
//! relevant byte.
393
 
394
//! @todo Provide code to check if the read was from a valid address.
395
 
396
//! @note Read bytes from memory mapped devices at your peril!
397
 
398
//! @param[in] addr  The address to read from
399
//! @return  The byte read
400
//-----------------------------------------------------------------------------
401 462 julius
uint8_t DebugUnitSC::readMem8(uint32_t addr)
402 63 julius
{
403 462 julius
        uint32_t word = Utils::ttohl(readMem32(addr & 0xfffffffc));
404
        uint8_t *bytes = (uint8_t *) (&word);
405
        int offset = addr & 0x3;
406 63 julius
 
407 462 julius
        return bytes[offset];
408 63 julius
 
409 462 julius
}                               // readMem8 ()
410 63 julius
 
411
//-----------------------------------------------------------------------------
412
//! Write a byte to the OpenRISC 1000 main memory
413
 
414
//! All we can get are 32-bits words, so we have to read the current value and
415
//! construct the new value to write back.
416
 
417
//! The underlying 32-bit routines take target endian arguments and return
418
//! target endian results. We need to convert to host endianness to alter the
419
//! relevant byte.
420
 
421
//! @note Write bytes to memory mapped devices at your peril!
422
 
423
//! @todo Provide code to check if the write was to a valid address.
424
 
425
//! @param[in] addr   The address to write to
426
//! @param[in] value  The byte to write
427
 
428
//! @return  True if the write was successful. For now all writes are
429
//           successful.
430
//-----------------------------------------------------------------------------
431 462 julius
bool DebugUnitSC::writeMem8(uint32_t addr, uint8_t value)
432 63 julius
{
433 462 julius
        uint32_t currWord = Utils::ttohl(readMem32(addr & 0xfffffffc));
434
        uint8_t *currBytes = (uint8_t *) (&currWord);
435
        int offset = addr & 0x3;
436 63 julius
 
437 462 julius
        currBytes[offset] = value;
438 63 julius
 
439 462 julius
        return writeMem32(addr & 0xfffffffc, Utils::htotl(currWord));
440 63 julius
 
441 462 julius
}                               // writeMem8 ()
442 63 julius
 
443
//-----------------------------------------------------------------------------
444
//! Get the debug interface CPU0 control register value
445
 
446
//! @return  The value in the RISCOP register
447
//-----------------------------------------------------------------------------
448 462 julius
uint32_t DebugUnitSC::readRiscop()
449 63 julius
{
450 462 julius
        selectDebugModule(OR1K_SC_CPU0);
451 63 julius
 
452 462 julius
        int drLen;              // Size of the data register
453 63 julius
 
454 462 julius
        uint32_t calc_recv_crc = 0, recv_crc, status_ret;
455 63 julius
 
456 462 julius
        drLen = 1 + 4 + 32 + 52 + 4 + 32;
457 63 julius
 
458 462 julius
        // Initialize the register fields
459
        uint64_t *dRegIn = new uint64_t[(drLen + 63) / 64];
460
        uint64_t *dRegOut = new uint64_t[(drLen + 63) / 64];
461
 
462
        // Write the READ command
463
        clearBits(dRegIn, drLen);
464
 
465
        packBits(dRegIn, 0, 1, 0);
466
        packBits(dRegIn, 0 + 1, 4, BITREV(0x3, 4));      // We're reading CPU0 control reg
467
        uint32_t crc32_send = crc32(dRegIn, 0 + 1 + 4, 0);
468
        packBits(dRegIn, 0 + 1 + 4, 32, BITREV(crc32_send, 32));
469
 
470
        // Allocate a SystemC completion event
471
        sc_event *done = new sc_event();
472
 
473
        // Loop until status is OK and CRCs match.
474
        do {
475
                TapActionDRScan *dRScan =
476
                    new TapActionDRScan(done, dRegIn, drLen);
477
                tapActionQueue->write(dRScan);
478
                wait(*done);
479
                dRScan->getDRegOut(dRegOut);
480
                delete dRScan;
481
                status_ret = unpackBits(dRegOut, 1 + 4 + 32 + 52, 4);
482
                calc_recv_crc = crc32(dRegOut, 52 + 4, 1 + 4 + 32);
483
                recv_crc =
484
                    BITREV(unpackBits(dRegOut, 1 + 4 + 32 + 52 + 4, 32), 32);
485
        }
486
        while ((0 != status_ret) || (calc_recv_crc != recv_crc));
487
 
488
        // All done
489
        uint32_t res = BITREV(unpackBits(dRegOut, (1 + 4 + 32), 2), 2);
490
 
491
        delete[]dRegIn;
492
        delete[]dRegOut;
493
        delete done;
494
        return res;
495
}                               // readRiscop ()
496
 
497 63 julius
//-----------------------------------------------------------------------------
498
//! Set the RISCOP control register
499
 
500
//! Convenience function. Select the REGISTER scan chain, write the new value.
501
 
502
//! @param[in] value  The value to write into the RISCOP register
503
//-----------------------------------------------------------------------------
504 462 julius
void DebugUnitSC::writeRiscop(uint32_t value)
505 63 julius
{
506 462 julius
        selectDebugModule(OR1K_SC_CPU0);
507 63 julius
 
508 462 julius
        int drLen;              // Size of the data register
509 63 julius
 
510 462 julius
        uint32_t calc_recv_crc = 0, recv_crc, status_ret;
511 63 julius
 
512 462 julius
        drLen = 1 + 4 + 32 + 52 + 4 + 32;
513 63 julius
 
514 462 julius
        // Initialize the register fields
515
        uint64_t *dRegIn = new uint64_t[(drLen + 63) / 64];
516
        uint64_t *dRegOut = new uint64_t[(drLen + 63) / 64];
517
 
518
        // Write the READ command
519
        clearBits(dRegIn, drLen);
520
 
521
        packBits(dRegIn, 0, 1, 0);
522
        packBits(dRegIn, 0 + 1, 4, BITREV(0x4, 4));      // We're writing CPU0 control reg
523
        packBits(dRegIn, 5, 1, value & RISCOP_RESET);   // First bit is reset
524
        packBits(dRegIn, 6, 1, (value & RISCOP_STALL) >> 1);    // Next bit is stall
525
        /* Next 50 bits should be zero */
526
        uint32_t crc32_send = crc32(dRegIn, 1 + 4 + 52, 0);
527
        packBits(dRegIn, 1 + 4 + 52, 32, BITREV(crc32_send, 32));
528
 
529
        // Allocate a SystemC completion event
530
        sc_event *done = new sc_event();
531
 
532
        // Loop until status is OK and CRCs match.
533
        do {
534
                TapActionDRScan *dRScan =
535
                    new TapActionDRScan(done, dRegIn, drLen);
536
                tapActionQueue->write(dRScan);
537
                wait(*done);
538
                dRScan->getDRegOut(dRegOut);
539
                delete dRScan;
540
                status_ret = unpackBits(dRegOut, 1 + 4 + 32 + 52, 4);
541
                calc_recv_crc = crc32(dRegOut, 4, 1 + 4 + 52 + 32);
542
                recv_crc =
543
                    BITREV(unpackBits(dRegOut, 1 + 4 + 52 + 32 + 4, 32), 32);
544
        }
545
        while ((0 != status_ret) || (calc_recv_crc != recv_crc));
546
 
547
        delete[]dRegIn;
548
        delete[]dRegOut;
549
        delete done;
550
 
551
}                               // writeRiscop ()
552
 
553 63 julius
//-----------------------------------------------------------------------------
554
//! Select a module attached to the debug module
555
 
556
//! @note Must be called from a SystemC thread, because of the use of wait()
557
 
558
//! @param[in] chain  The desired module
559
//-----------------------------------------------------------------------------
560 462 julius
void DebugUnitSC::selectDebugModule(int module)
561 63 julius
{
562
 
563 462 julius
        if (module == currentScanChain) {
564
                return;
565
        } else {
566
                currentScanChain = module;
567
        }
568 63 julius
 
569 462 julius
        sc_event *done = new sc_event();
570
        TapActionIRScan *iRScan;
571
        TapActionDRScan *dRScan;
572 63 julius
 
573 462 julius
        // Create and queue the IR-Scan action for DEBUG (no CRC)
574
        iRScan = new TapActionIRScan(done, DEBUG_IR, JTAG_IR_LEN);
575
        tapActionQueue->write(iRScan);
576
        wait(*done);
577 63 julius
 
578 462 julius
        delete iRScan;
579 63 julius
 
580 462 julius
        // Initialize the register fields
581
        uint64_t *dRegIn = new uint64_t[(DUSEL_DR_LEN + 63) / 64];
582
        uint64_t *dRegOut = new uint64_t[(DUSEL_DR_LEN + 63) / 64];
583 63 julius
 
584 462 julius
        clearBits(dRegIn, DUSEL_DR_LEN);
585
        packBits(dRegIn, DUSEL_SEL_OFF, DUSEL_SEL_LEN, 0x1);
586
        packBits(dRegIn, DUSEL_OPCODE_OFF, DUSEL_OPCODE_LEN,
587
                 bit_reverse_data(module, 4));
588
        uint32_t crc32_send = crc32(dRegIn, DUSEL_CRC_OFF, 0);
589
        packBits(dRegIn, DUSEL_CRC_OFF, DUSEL_CRC_LEN,
590
                 bit_reverse_data(crc32_send, 32));
591
        uint32_t calc_recv_crc = 0, recv_crc, status_ret;
592
        // Loop until status is OK and CRCs match.
593
        do {
594
                TapActionDRScan *dRScan =
595
                    new TapActionDRScan(done, dRegIn, DUSEL_DR_LEN);
596
                tapActionQueue->write(dRScan);
597
                wait(*done);
598
                dRScan->getDRegOut(dRegOut);
599
                delete dRScan;
600
                status_ret =
601
                    unpackBits(dRegOut, DUSEL_RESP_STATUS_OFF,
602
                               DUSEL_RESP_STATUS_LEN);
603
                calc_recv_crc =
604
                    crc32(dRegOut, DUSEL_RESP_STATUS_LEN,
605
                          DUSEL_RESP_STATUS_OFF);
606
                recv_crc =
607
                    bit_reverse_data(unpackBits
608
                                     (dRegOut, DUSEL_RESP_CRC_OFF,
609
                                      DUSEL_RESP_CRC_LEN), 32);
610
        }
611
        while ((0 != status_ret) || (calc_recv_crc != recv_crc));
612 63 julius
 
613 462 julius
        delete[]dRegIn;
614
        delete[]dRegOut;
615
        delete done;
616 63 julius
 
617 462 julius
}                               // selectDebugModule()
618 63 julius
 
619
//-----------------------------------------------------------------------------
620
//! Read a 32-bit value via the debug interface
621
 
622
//! @note Must be called from a SystemC thread, because of the use of wait()
623
 
624
//! @param[in] addr  The address of the register
625
 
626
//! @return  The register value read
627
//-----------------------------------------------------------------------------
628 462 julius
uint32_t DebugUnitSC::readJtagReg(uint32_t addr)
629 63 julius
{
630 462 julius
        int drLen;              // Size of the data register
631 63 julius
 
632 462 julius
        uint32_t calc_recv_crc = 0, recv_crc, status_ret;
633 63 julius
 
634 462 julius
        drLen = 125;            // Size of write command command (bigger than data read)
635
 
636
        // Initialize the register fields
637
        uint64_t *dRegIn = new uint64_t[(drLen + 63) / 64];
638
        uint64_t *dRegOut = new uint64_t[(drLen + 63) / 64];
639
 
640
        // Write the READ command
641
        clearBits(dRegIn, drLen);
642
 
643
        packBits(dRegIn, 0, 1, 0);
644
        packBits(dRegIn, 0 + 1, 4, BITREV(0x2, 4));      // We're writing a command
645
        packBits(dRegIn, 1 + 4, 4, BITREV(0x6, 4));     // Access type, 0x6 = 32-bit READ
646
        packBits(dRegIn, 1 + 4 + 4, 32, BITREV(addr, 32));      // Address
647
        packBits(dRegIn, 1 + 4 + 4 + 32, 16, BITREV(0x3, 16));  // Length (always 32-bit,n=(32/8)-1=3)
648
        uint32_t crc32_send = crc32(dRegIn, 1 + 4 + 4 + 32 + 16, 0);
649
        packBits(dRegIn, 1 + 4 + 4 + 32 + 16, 32, BITREV(crc32_send, 32));
650
 
651
        // Allocate a SystemC completion event
652
        sc_event *done = new sc_event();
653
 
654
        // Loop until status is OK and CRCs match.
655
        do {
656
                TapActionDRScan *dRScan =
657
                    new TapActionDRScan(done, dRegIn, 125);
658
                tapActionQueue->write(dRScan);
659
                wait(*done);
660
                dRScan->getDRegOut(dRegOut);
661
                delete dRScan;
662
                status_ret = unpackBits(dRegOut, 1 + 4 + 4 + 32 + 16 + 32, 4);
663
                calc_recv_crc = crc32(dRegOut, 4, 1 + 4 + 4 + 32 + 16 + 32);
664
                recv_crc =
665
                    BITREV(unpackBits
666
                           (dRegOut, 1 + 4 + 4 + 32 + 16 + 32 + 4, 32), 32);
667 63 julius
        }
668 462 julius
        while ((0 != status_ret) || (calc_recv_crc != recv_crc));
669 63 julius
 
670 462 julius
        clearBits(dRegIn, drLen);
671
        packBits(dRegIn, 0, 1, 0);
672
        packBits(dRegIn, 0 + 1, 4, 0x0); // We're GO'ing command
673
        crc32_send = crc32(dRegIn, 1 + 4, 0);
674
        packBits(dRegIn, 1 + 4, 32, BITREV(crc32_send, 32));    // CRC
675 63 julius
 
676 462 julius
        uint32_t result;
677
        // Loop until status is OK and CRCs match.
678
        do {
679
                TapActionDRScan *dRScan = new TapActionDRScan(done, dRegIn,
680
                                                              (1 + 4 + 32 + 36 +
681
                                                               ((3 + 1) * 8)));
682
                tapActionQueue->write(dRScan);
683
                wait(*done);
684
                dRScan->getDRegOut(dRegOut);
685
                delete dRScan;
686
                status_ret =
687
                    BITREV(unpackBits(dRegOut, 1 + 4 + 32 + ((3 + 1) * 8), 4),
688
                           4);
689
                if (status_ret) {
690
                        printf("readJtagReg(): Addr: 0x%.8x Status err: 0x%x\n",
691
                               addr, status_ret);
692
                        result = 0;
693
                        break;
694
                }
695
                calc_recv_crc = crc32(dRegOut, ((3 + 1) * 8) + 4, 1 + 4 + 32);
696
                recv_crc =
697
                    BITREV(unpackBits
698
                           (dRegOut, 1 + 4 + 32 + ((3 + 1) * 8) + 4, 32), 32);
699
                result =
700
                    BITREV(unpackBits(dRegOut, (1 + 4 + 32), ((3 + 1) * 8)),
701
                           32);
702 63 julius
 
703 462 julius
        }
704
        while ((0 != status_ret) || (calc_recv_crc != recv_crc));
705 63 julius
 
706 462 julius
        // All done
707
 
708
        delete[]dRegIn;
709
        delete[]dRegOut;
710
        delete done;
711
        return result;
712
 
713
}                               // readJtagReg ()
714
 
715 63 julius
//-----------------------------------------------------------------------------
716
//! Write a 32-bit value via the debug interface
717
 
718
//! @note Must be called from a SystemC thread, because of the use of wait()
719
 
720
//! @param[in] addr  The address of the register
721
//! @param[in] data  The register data to write
722
//-----------------------------------------------------------------------------
723 462 julius
void DebugUnitSC::writeJtagReg(uint32_t addr, uint32_t data)
724 63 julius
{
725 462 julius
        int drLen;              // Size of the data register
726 63 julius
 
727 462 julius
        uint32_t calc_recv_crc = 0, recv_crc, status_ret;
728 63 julius
 
729 462 julius
        drLen = 125;            // Size of write command command (bigger than data read)
730 63 julius
 
731 462 julius
        // Initialize the register fields
732
        uint64_t *dRegIn = new uint64_t[(drLen + 63) / 64];
733
        uint64_t *dRegOut = new uint64_t[(drLen + 63) / 64];
734 63 julius
 
735 462 julius
        // Write the READ command
736
        clearBits(dRegIn, drLen);
737
 
738
        packBits(dRegIn, 0, 1, 0);
739
        packBits(dRegIn, 0 + 1, 4, BITREV(0x2, 4));      // We're writing a command
740
        packBits(dRegIn, 1 + 4, 4, BITREV(0x2, 4));     // Access type, 0x2 = 32-bit WRITE
741
        packBits(dRegIn, 1 + 4 + 4, 32, BITREV(addr, 32));      // Address
742
        packBits(dRegIn, 1 + 4 + 4 + 32, 16, BITREV(0x3, 16));  // Length (always 32-bit,n=(32/8)-1=3)
743
        uint32_t crc32_send = crc32(dRegIn, 1 + 4 + 4 + 32 + 16, 0);
744
        packBits(dRegIn, 1 + 4 + 4 + 32 + 16, 32, BITREV(crc32_send, 32));
745
 
746
        // Allocate a SystemC completion event
747
        sc_event *done = new sc_event();
748
 
749
        // Loop until status is OK and CRCs match.
750
        do {
751
                TapActionDRScan *dRScan =
752
                    new TapActionDRScan(done, dRegIn, 125);
753
                tapActionQueue->write(dRScan);
754
                wait(*done);
755
                dRScan->getDRegOut(dRegOut);
756
                delete dRScan;
757
                status_ret = unpackBits(dRegOut, 1 + 4 + 4 + 32 + 16 + 32, 4);
758
                calc_recv_crc = crc32(dRegOut, 4, 1 + 4 + 4 + 32 + 16 + 32);
759
                recv_crc =
760
                    BITREV(unpackBits
761
                           (dRegOut, 1 + 4 + 4 + 32 + 16 + 32 + 4, 32), 32);
762
        }
763
        while ((0 != status_ret) || (calc_recv_crc != recv_crc));
764
 
765
        clearBits(dRegIn, drLen);
766
        packBits(dRegIn, 0, 1, 0);
767
        packBits(dRegIn, 0 + 1, 4, 0x0); // We're GO'ing command
768
        packBits(dRegIn, 0 + 1 + 4, 32, BITREV(data, 32));       // Add in data
769
        crc32_send = crc32(dRegIn, 1 + 4 + 32, 0);
770
        packBits(dRegIn, 1 + 4 + 32, 32, BITREV(crc32_send, 32));       // CRC
771
 
772
        // Loop until status is OK and CRCs match.
773
        do {
774
                TapActionDRScan *dRScan = new TapActionDRScan(done, dRegIn,
775
                                                              (1 + 4 +
776
                                                               ((3 + 1) * 8) +
777
                                                               32 + 36));
778
                tapActionQueue->write(dRScan);
779
                wait(*done);
780
                dRScan->getDRegOut(dRegOut);
781
                delete dRScan;
782
                status_ret = unpackBits(dRegOut, 1 + 4 + 32 + 32, 4);
783
                calc_recv_crc = crc32(dRegOut, 4, 1 + 4 + 32 + 32);
784
                recv_crc =
785
                    BITREV(unpackBits(dRegOut, 1 + 4 + 32 + 32 + 4, 32), 32);
786
        }
787
        while ((0 != status_ret) || (calc_recv_crc != recv_crc));
788
 
789
        delete[]dRegIn;
790
        delete[]dRegOut;
791
        delete done;
792
 
793
}                               // writeJtagReg ()
794
 
795 63 julius
//-----------------------------------------------------------------------------
796
//! Clear the bits in a data register
797
 
798
//! We always clear whole 64-bit words, not just the minimum number of
799
//! bytes. It saves all sorts of confusion when debugging code.
800
 
801
//! @note It is the caller's responsibility to make sure the date register
802
//!       array is large enough.
803
 
804
//! @param[in,out] regArray  The data register to clear
805
//! @param[in]     regBits  Size of the data register (in bits)
806
//-----------------------------------------------------------------------------
807 462 julius
void DebugUnitSC::clearBits(uint64_t regArray[], int regBits)
808 63 julius
{
809 462 julius
        memset((char *)regArray, 0, ((regBits + 63) / 64) * 8);
810 63 julius
 
811 462 julius
}                               // clearBits ()
812 63 julius
 
813
//-----------------------------------------------------------------------------
814
//! Set a bit field in a data register
815
 
816
//! The field is cleared, the supplied value masked and then ored into the
817
//! vector.
818
 
819
//! @note It is the caller's responsibility to make sure the date register
820
//!       array is large enough.
821
 
822
//! @param[in,out] regArray     The data register
823
//! @param[in]     fieldOffset  Start of the field (in bits)
824
//! @param[in]     fieldBits    Size of the field (in bits)
825
//! @param[in]     fieldVal     Value to set in the field
826
//-----------------------------------------------------------------------------
827 462 julius
void DebugUnitSC::packBits(uint64_t regArray[],
828
                           int fieldOffset, int fieldBits, uint64_t fieldVal)
829 63 julius
{
830 462 julius
        fieldVal &= (1ULL << fieldBits) - 1ULL; // Mask the supplied value
831 63 julius
 
832 462 julius
        int startWord = fieldOffset / 64;
833
        int endWord = (fieldOffset + fieldBits - 1) / 64;
834 63 julius
 
835 462 julius
        fieldOffset = fieldOffset % 64; // Now refers to target word
836 63 julius
 
837 462 julius
        // Deal with the startWord. Get enough bits for the mask and put them in the
838
        // right place
839
        uint64_t startMask = ((1ULL << fieldBits) - 1ULL) << fieldOffset;
840 63 julius
 
841 462 julius
        regArray[startWord] &= ~startMask;
842
        regArray[startWord] |= fieldVal << fieldOffset;
843 63 julius
 
844 462 julius
        // If we were all in one word, we can give up now.
845
        if (startWord == endWord) {
846
                return;
847
        }
848
        // Deal with the endWord. Get enough bits for the mask. No need to shift
849
        // these up - they're always at the bottom of the word
850
        int bitsToDo = (fieldOffset + fieldBits) % 64;
851
        uint64_t endMask = (1ULL << bitsToDo) - 1ULL;
852 63 julius
 
853 462 julius
        regArray[endWord] &= ~endMask;
854
        regArray[endWord] |= fieldVal >> (fieldBits - bitsToDo);
855 63 julius
 
856 462 julius
}                               // packBits ()
857 63 julius
 
858
//-----------------------------------------------------------------------------
859
//! Extract a bit field from a data register
860
 
861
//! The field is cleared, the supplied value masked and then ored into the
862
//! vector.
863
 
864
//! @note It is the caller's responsibility to make sure the date register
865
//!       array is large enough.
866
 
867
//! @param[in,out] regArray     The data register
868
//! @param[in]     fieldOffset  Start of the field (in bits)
869
//! @param[in]     fieldBits    Size of the field (in bits)
870
 
871
//! @return  The value in the field
872
//-----------------------------------------------------------------------------
873
uint64_t
874 462 julius
    DebugUnitSC::unpackBits(uint64_t regArray[], int fieldOffset, int fieldBits)
875 63 julius
{
876 462 julius
        int startWord = fieldOffset / 64;
877
        int endWord = (fieldOffset + fieldBits - 1) / 64;
878 63 julius
 
879 462 julius
        fieldOffset = fieldOffset % 64; // Now refers to target word
880 63 julius
 
881 462 julius
        // Deal with the startWord. Get enough bits for the mask and put them in the
882
        // right place
883
        uint64_t startMask = ((1ULL << fieldBits) - 1ULL) << fieldOffset;
884
        uint64_t res = (regArray[startWord] & startMask) >> fieldOffset;
885 63 julius
 
886 462 julius
        // If we were all in one word, we can give up now.
887
        if (startWord == endWord) {
888
                res &= (1ULL << fieldBits) - 1ULL;      // Mask off any unwanted bits
889
                return res;
890
        }
891
        // Deal with the endWord. Get enough bits for the mask. No need to shift
892
        // these up - they're always at the bottom of the word
893
        int bitsToDo = (fieldOffset + fieldBits) % 64;
894
        uint64_t endMask = (1ULL << bitsToDo) - 1ULL;
895 63 julius
 
896 462 julius
        res = res | ((regArray[endWord] & endMask) << (fieldBits - bitsToDo));
897
        res &= (1ULL << fieldBits) - 1ULL;      // Mask off any unwanted bits
898
        return res;
899 63 julius
 
900 462 julius
}                               // unpackBits ()
901 63 julius
 
902
//-----------------------------------------------------------------------------
903
//! Compute CRC-8-ATM
904
 
905
//! The data is in an array of uint64_t, for which we use the first size bits
906
//! to compute the CRC.
907
 
908
//! @Note I am using the same algorithm as the ORPSoC debug unit, but I
909
//!       believe its function is broken! I don't believe the data bit should
910
//!       feature in the computation of bits 2 & 1 of the new CRC.
911
 
912
//! @Note I've realized that this is an algorithm for LSB first, so maybe it
913
//!       is correct!
914
 
915
//! @param dataArray  The array of data whose CRC is desired
916
//! @param size       The number of bits in the data
917
//-----------------------------------------------------------------------------
918 462 julius
uint8_t DebugUnitSC::crc8(uint64_t dataArray[], int size)
919 63 julius
{
920 462 julius
        uint8_t crc = 0;
921 63 julius
 
922 462 julius
        for (int i = 0; i < size; i++) {
923
                uint8_t d = (dataArray[i / 64] >> (i % 64)) & 1;
924
                uint8_t oldCrc7 = (crc >> 7) & 1;
925
                uint8_t oldCrc1 = (crc >> 1) & 1;
926
                uint8_t oldCrc0 = (crc >> 0) & 1;
927
                uint8_t newCrc2 = d ^ oldCrc1 ^ oldCrc7;        // Why d?
928
                uint8_t newCrc1 = d ^ oldCrc0 ^ oldCrc7;        // Why d?
929
                uint8_t newCrc0 = d ^ oldCrc7;
930 63 julius
 
931 462 julius
                crc =
932
                    ((crc << 1) & 0xf8) | (newCrc2 << 2) | (newCrc1 << 1) |
933
                    newCrc0;
934
        }
935 63 julius
 
936 462 julius
        return crc;
937 63 julius
 
938 462 julius
}                               // crc8 ()
939 63 julius
 
940
/* Crc of current read or written data.  */
941
uint32_t crc_r, crc_w = 0;
942
 
943
/* Generates new crc, sending in new bit input_bit */
944 462 julius
uint32_t DebugUnitSC::crc32(uint64_t dataArray[], int size, int offset)
945 63 julius
{
946 462 julius
        uint32_t crc = 0xffffffff;
947
        for (int i = offset; i < size + offset; i++) {
948
                uint32_t d =
949
                    ((dataArray[i / 64] >> (i % 64)) & 1) ? 0xfffffff :
950
                    0x0000000;
951
                uint32_t crc_32 = ((crc >> 31) & 1) ? 0xfffffff : 0x0000000;
952
                crc <<= 1;
953
                crc = crc ^ ((d ^ crc_32) & DBG_CRC32_POLY);
954
        }
955 63 julius
 
956 462 julius
        return crc;
957 63 julius
}
958
 
959 462 julius
uint32_t DebugUnitSC::bit_reverse_swar_2(uint32_t x)
960 63 julius
{
961 462 julius
        return (((x & 0xaaaaaaaa) >> 1) | ((x & 0x55555555) << 1));
962 63 julius
}
963 462 julius
 
964
uint32_t DebugUnitSC::bit_reverse_swar_4(uint32_t x)
965 63 julius
{
966 462 julius
        x = (((x & 0xaaaaaaaa) >> 1) | ((x & 0x55555555) << 1));
967
        x = (((x & 0xcccccccc) >> 2) | ((x & 0x33333333) << 2));
968
        return x;
969 63 julius
}
970 462 julius
 
971
uint32_t DebugUnitSC::bit_reverse_swar_8(uint32_t x)
972 63 julius
{
973 462 julius
        x = (((x & 0xaaaaaaaa) >> 1) | ((x & 0x55555555) << 1));
974
        x = (((x & 0xcccccccc) >> 2) | ((x & 0x33333333) << 2));
975
        x = (((x & 0xf0f0f0f0) >> 4) | ((x & 0x0f0f0f0f) << 4));
976
        return x;
977 63 julius
}
978 462 julius
 
979
uint32_t DebugUnitSC::bit_reverse_swar_16(uint32_t x)
980 63 julius
{
981 462 julius
        x = (((x & 0xaaaaaaaa) >> 1) | ((x & 0x55555555) << 1));
982
        x = (((x & 0xcccccccc) >> 2) | ((x & 0x33333333) << 2));
983
        x = (((x & 0xf0f0f0f0) >> 4) | ((x & 0x0f0f0f0f) << 4));
984
        x = (((x & 0xff00ff00) >> 8) | ((x & 0x00ff00ff) << 8));
985
        return x;
986 63 julius
}
987 462 julius
 
988
uint32_t DebugUnitSC::bit_reverse_swar_32(uint32_t x)
989 63 julius
{
990 462 julius
        x = (((x & 0xaaaaaaaa) >> 1) | ((x & 0x55555555) << 1));
991
        x = (((x & 0xcccccccc) >> 2) | ((x & 0x33333333) << 2));
992
        x = (((x & 0xf0f0f0f0) >> 4) | ((x & 0x0f0f0f0f) << 4));
993
        x = (((x & 0xff00ff00) >> 8) | ((x & 0x00ff00ff) << 8));
994
        x = (((x & 0xffff0000) >> 16) | ((x & 0x0000ffff) << 16));      // We could be on 64-bit arch!
995
        return x;
996 63 julius
}
997 462 julius
 
998
uint32_t DebugUnitSC::bit_reverse_data(uint32_t data, int length)
999
{
1000
        if (length == 2)
1001
                return bit_reverse_swar_2(data);
1002
        if (length == 4)
1003
                return bit_reverse_swar_4(data);
1004
        if (length == 8)
1005
                return bit_reverse_swar_8(data);
1006
        if (length == 16)
1007
                return bit_reverse_swar_16(data);
1008
        if (length == 32)
1009
                return bit_reverse_swar_32(data);
1010
        // Long and laborious way - hopefully never gets called anymore!
1011
        uint32_t reverse = 0;
1012
        for (int i = 0; i < length; i++)
1013
                reverse |= (((data >> i) & 1) << (length - 1 - i));
1014
        return reverse;
1015 63 julius
}

powered by: WebSVN 2.1.0

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