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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [orpsocv2/] [bench/] [verilog/] [vpi/] [c/] [rsp-rtl_sim.c] - Blame information for rev 46

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

Line No. Rev Author Line
1 40 julius
/*$$HEADER*/
2
/******************************************************************************/
3
/*                                                                            */
4
/*                    H E A D E R   I N F O R M A T I O N                     */
5
/*                                                                            */
6
/******************************************************************************/
7
 
8
// Project Name                   : ORPSoCv2
9
// File Name                      : rsp-rtl_sim.c
10
// Prepared By                    : jb, jb@orsoc.se
11
// Project Start                  : 2009-05-01
12
 
13
/*$$COPYRIGHT NOTICE*/
14
/******************************************************************************/
15
/*                                                                            */
16
/*                      C O P Y R I G H T   N O T I C E                       */
17
/*                                                                            */
18
/******************************************************************************/
19
/*
20
  This library is free software; you can redistribute it and/or
21
  modify it under the terms of the GNU Lesser General Public
22
  License as published by the Free Software Foundation;
23
  version 2.1 of the License, a copy of which is available from
24
  http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt.
25
 
26
  This library is distributed in the hope that it will be useful,
27
  but WITHOUT ANY WARRANTY; without even the implied warranty of
28
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
29
  Lesser General Public License for more details.
30
 
31
  You should have received a copy of the GNU Lesser General Public
32
  License along with this library; if not, write to the Free Software
33
  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
34
*/
35
 
36
 
37
/* Establishes GDB proxy server and communicates via pipes
38
   to some functions running under the VPI in an RTL sim */
39
 
40
#include <stdio.h>
41
#include <sys/stat.h>
42
#include <sys/types.h>
43
#include <assert.h>
44
 
45
#include <ctype.h>
46
#include <stdint.h>
47
#include <string.h>
48
#include <stdlib.h>
49
#include <unistd.h>
50
#include <stdarg.h>
51
#include <fcntl.h>
52
#include <errno.h>
53
#include <signal.h>
54
 
55
#include "gdb.h"
56
#include "rsp-rtl_sim.h"
57
#include "rsp-vpi.h"
58
 
59
static int err = 0;
60
 
61
/* Currently selected scan chain - just to prevent unnecessary
62
   transfers. */
63
static int current_chain = -1;
64
 
65
/* The chain that should be currently selected. */
66
static int dbg_chain = -1;
67
 
68
/* Crc of current read or written data.  */
69
static int crc_r, crc_w = 0;
70
 
71
/* Generates new crc, sending in new bit input_bit */
72
static uint32_t crc_calc(uint32_t crc, int input_bit) {
73
  uint32_t d = (input_bit&1) ? 0xfffffff : 0x0000000;
74
  uint32_t crc_32 = ((crc >> 31)&1) ? 0xfffffff : 0x0000000;
75
  crc <<= 1;
76
  return crc ^ (d ^ crc_32) & DBG_CRC_POLY;
77
}
78
 
79
/* VPI communication prototyopes */
80
static void get_response_from_vpi();
81
static void get_data_from_vpi();
82
static void get_block_data_from_vpi(int len, uint32_t *data);
83
static void send_data_to_vpi(uint32_t data);
84
static void send_block_data_to_vpi(int len, uint32_t *data);
85
static void send_address_to_vpi(uint32_t address);
86
static void send_command_to_vpi(char CMD);
87
 
88
void send_command_to_vpi(char CMD)
89
{
90
  // first thing we do  is send a command
91
  // and wait for an ack
92
  int n;
93
  char cmd_resp;
94
 
95 46 julius
  if (DBG_CALLS)printf("send_command_to_vpi: cmd 0x%x \n", CMD);
96 40 julius
 
97
  //n = write(rsp_to_vpi_pipe[1],&CMD, 1); // send the command to the sim
98
  n = write(command_pipe[1],&CMD, 1); // send the command to the sim
99
 
100
  if (n < 0)   error("ERROR writing to VPI FIFO");
101
 
102
  n = read(vpi_to_rsp_pipe[0],&cmd_resp,1); // block and wait for the ack
103
 
104
  if (cmd_resp != CMD) error("Response from RTL sim incorrect"); //check it acked with cmd
105
 
106
  return;
107
}
108
 
109
void send_address_to_vpi(uint32_t address)
110
{
111
  // Now send address
112
  int n;
113
 
114
  char* send_buf;
115
 
116 46 julius
  if (DBG_CALLS)printf("send_address_to_vpi: address 0x%.8x\n",address);
117
 
118 40 julius
  send_buf = (char *) &address;
119
 
120
  n = write(rsp_to_vpi_pipe[1],send_buf, 4); // send the address to the sim
121
 
122
  if (n < 0)   error("ERROR writing to VPI socket");
123
 
124
  return;
125
}
126
 
127
void send_data_to_vpi(uint32_t data)
128
{
129
  // Now send data
130
  int n;
131
 
132
  char* send_buf;
133
 
134 46 julius
  if (DBG_CALLS)printf("send_data_to_vpi: data 0x%.8x\n",data);
135
 
136 40 julius
  send_buf = (char *) &data;
137
 
138
  n = write(rsp_to_vpi_pipe[1],send_buf, 4); // Write the data to the socket
139
 
140
  if (n < 0)   error("ERROR writing to VPI socket");
141
 
142
  return;
143
 
144
}
145
 
146
void send_block_data_to_vpi(int len, uint32_t *data)
147
{
148
  // Now send data
149
  int n, i;
150
 
151
  char* send_buf;
152 46 julius
 
153
  if (DBG_CALLS)printf("send_block_data_to_vpi: len %d\n",len);
154 40 julius
 
155
  send_buf = (char *) data;
156
 
157
  n = write(rsp_to_vpi_pipe[1],send_buf, len); // Write the data to the fifo
158
 
159
  if (n < 0)   error("ERROR writing to VPI socket");
160
 
161
  return;
162
 
163
}
164
 
165
void get_data_from_vpi(uint32_t* data)
166
{
167
 
168
  int n;
169
 
170
  uint32_t inc_data;
171
 
172
  char* recv_buf;
173
 
174
  recv_buf = (char*) &inc_data;
175
 
176
  n = read(vpi_to_rsp_pipe[0],recv_buf,4); // block and wait for the data
177
 
178
  if (DBG_VPI) printf("rsp-rtl_sim: get_data_from_vpi: 0x%.8x\n",inc_data);
179
 
180
  *data = inc_data;
181
 
182
  return;
183
 
184
}
185
 
186
void get_block_data_from_vpi(int len, uint32_t* data)
187
{
188
  int n, i, status;
189
 
190
  uint32_t inc_data;
191
 
192
  char* recv_buf;
193
 
194
  uint32_t* data_ptr;
195
 
196
  recv_buf = (char *) data;
197
 
198
  n=0;
199
 
200 46 julius
  if (DBG_CALLS)printf("rsp_rtl_sim: get_block_data_from_vpi len %d\n",len);
201
 
202 40 julius
  while (n < len)
203
    {
204
 
205
      status = read(vpi_to_rsp_pipe[0], recv_buf, len - n); // block and wait for the data
206
 
207
      if (status > 0) n += status; // we read "status" number of bytes
208
 
209
    }
210 46 julius
 
211
 
212 40 julius
  if (DBG_VPI){
213 46 julius
    printf("rsp-rtl_sim: get_block_data_from_vpi: %d bytes: ",len);
214
    for (i = 0;i < (len); i++)
215 40 julius
      {
216 46 julius
        if ((i%12) == 0) printf("\n\t");
217
        printf("%.2x",recv_buf[i]);
218
        if ((i%3) == 0) printf(" ");
219
 
220 40 julius
      }
221
    printf("\n");
222
  }
223
 
224
  return;
225
 
226
}
227
 
228
void get_response_from_vpi()
229
{
230
  // Basically just wait for the response from VPI
231
  // by blocking wait on recv
232
 
233
  int n = 0;
234
  char tmp;
235
 
236 46 julius
  if (DBG_CALLS)printf("get_response_from_vpi\n");
237
 
238 40 julius
  n = read(vpi_to_rsp_pipe[0],&tmp,1); // block and wait
239
 
240
  return;
241
}
242
 
243
static void jp2_reset_JTAG() {
244
  int i;
245
 
246
  debug2("\nreset(");
247
 
248
  send_command_to_vpi(CMD_RESET);
249
 
250
  get_response_from_vpi();
251
 
252
  debug2(")\n");
253
 
254
}
255
 
256
/* Resets JTAG, and sets DEBUG scan chain */
257
 int dbg_reset() {
258
 
259
   int err;
260
   uint32_t id;
261
 
262
   jp2_reset_JTAG();
263
 
264
  /* set idcode jtag chain */
265
  send_command_to_vpi(CMD_JTAG_SET_IR);
266
 
267
  send_data_to_vpi(JI_IDCODE);
268
 
269
  get_response_from_vpi();
270
 
271
  /* now read out the jtag id */
272
  send_command_to_vpi(CMD_READ_JTAG_ID);
273
 
274
  //id = get_data_from_vpi();  
275
  get_data_from_vpi((uint32_t *)&id);
276
 
277
  get_response_from_vpi();
278
 
279
  printf("JTAG ID = %08x\n", id);
280
 
281
  /* now set the chain to debug */
282
  send_command_to_vpi(CMD_JTAG_SET_IR);
283
 
284
  send_data_to_vpi(JI_DEBUG);
285
 
286
  get_response_from_vpi();
287
 
288
  current_chain = -1;
289
  return DBG_ERR_OK;
290
}
291
 
292
/* counts retries and returns zero if we should abort */
293
/* TODO: dinamically adjust timings for jp2 */
294
static int retry_no = 0;
295
int retry_do() {
296
  int i, err;
297
  printf("RETRY\n");
298
  //exit(2);
299
  if (retry_no >= NUM_SOFT_RETRIES) {
300
    if ((err = dbg_reset())) return err;
301
  }
302
  if (retry_no >= NUM_SOFT_RETRIES + NUM_HARD_RETRIES) {
303
    retry_no = 0;
304
    return 0;
305
  }
306
  retry_no++;
307
  return 1;
308
}
309
 
310
/* resets retry counter */
311
void retry_ok() {
312
  retry_no = 0;
313
}
314
 
315
/* Sets scan chain.  */
316
int dbg_set_chain(int chain) {
317
 
318
  debug("\n");
319
  debug2("dbg_set_chain %d\n", chain);
320
 
321
  if (current_chain == chain)
322
    return DBG_ERR_OK;
323 46 julius
 
324
  if (DBG_CALLS)printf("dbg_set_chain chain %d \n", chain);
325 40 julius
 
326
  dbg_chain = chain;
327
 
328
  send_command_to_vpi(CMD_SET_DEBUG_CHAIN);
329
 
330
  send_data_to_vpi(chain);
331
 
332
  get_response_from_vpi();
333
 
334
  current_chain = chain;
335
 
336
  return DBG_ERR_OK;
337
}
338
 
339
/* writes a ctrl reg */
340
int dbg_ctrl(int reset, int stall)
341
{
342
 
343
  debug("\n");
344
  debug2("ctrl\n");
345 46 julius
 
346
  if (DBG_CALLS)printf("dbg_ctrl: reset %d stall %d \n", reset, stall);
347 40 julius
 
348
  dbg_set_chain(dbg_chain);
349
 
350
  send_command_to_vpi(CMD_CPU_CTRL_WR);
351
 
352
  //send_data_to_vpi(((reset & 0x1) | ((stall&0x1)<<1)));
353
  send_data_to_vpi(((stall & 0x1) | ((reset&0x1)<<1)));
354
 
355
  get_response_from_vpi();
356
 
357
  return DBG_ERR_OK;
358
}
359
 
360
/* reads control register */
361
int dbg_ctrl_read(int *reset, int *stall)
362
{
363
 
364
  uint32_t resp;
365
 
366
  dbg_set_chain(dbg_chain);
367
 
368
  debug("\n");
369
  debug2("ctrl\n");
370 46 julius
 
371
  if (DBG_CALLS)printf("dbg_ctrl_read\n");
372 40 julius
 
373
  dbg_set_chain(dbg_chain);
374
 
375
  send_command_to_vpi(CMD_CPU_CTRL_RD);
376
 
377
  get_data_from_vpi((uint32_t *)&resp);
378
 
379
  if (DBG_VPI) printf("rsp-rtl_sim: dbg_ctrl_read: 0x%.8x\n",resp);
380
 
381
  get_response_from_vpi();
382
 
383
  *reset = (int)(resp & 0x00000001);
384
 
385
  *stall = (int)((resp >> 1) & 0x00000001);
386
 
387
  return DBG_ERR_OK;
388
}
389
 
390
/* read a word from wishbone */
391
int dbg_wb_read32(uint32_t adr, uint32_t *data)
392
{
393 46 julius
  if (DBG_CALLS)printf("dbg_wb_read32: adr 0x%.8x \n",adr);
394 40 julius
 
395
  dbg_set_chain(DC_WISHBONE);
396
 
397
  send_command_to_vpi(CMD_WB_RD32);
398
 
399
  send_address_to_vpi(adr);
400
 
401
  get_data_from_vpi(data);
402
 
403
  get_response_from_vpi();
404
 
405
  return 0;
406
}
407
 
408
/* write a word to wishbone */
409
int dbg_wb_write32(uint32_t adr, uint32_t data)
410
{
411 46 julius
 
412
  if (DBG_CALLS)printf("dbg_wb_write32: adr 0x%.8x data 0x%.8x\n",adr, data);
413
 
414
  dbg_set_chain(DC_WISHBONE);
415
 
416
  send_command_to_vpi(CMD_WB_WR);
417
 
418
  send_address_to_vpi(adr);
419 40 julius
 
420 46 julius
  send_data_to_vpi(sizeof(data));
421
 
422
  send_data_to_vpi(data);
423
 
424
  get_response_from_vpi();
425
 
426
  return 0;
427
}
428
 
429
/* write a hword to wishbone */
430
int dbg_wb_write16(uint32_t adr, uint16_t data)
431
{
432
 
433
  if (DBG_CALLS)printf("dbg_wb_write16: adr 0x%.8x data 0x%.4x\n",adr, data);
434
 
435 40 julius
  dbg_set_chain(DC_WISHBONE);
436
 
437 46 julius
  send_command_to_vpi(CMD_WB_WR);
438 40 julius
 
439
  send_address_to_vpi(adr);
440
 
441 46 julius
  send_data_to_vpi(sizeof(data));
442
 
443 40 julius
  send_data_to_vpi(data);
444
 
445
  get_response_from_vpi();
446
 
447
  return 0;
448
}
449
 
450 46 julius
/* write a word to wishbone */
451
int dbg_wb_write8(uint32_t adr, uint8_t data)
452
{
453
 
454
  if (DBG_CALLS)printf("dbg_wb_write8: adr 0x%.8x data 0x%.2x\n",adr, data);
455
 
456
  dbg_set_chain(DC_WISHBONE);
457
 
458
  send_command_to_vpi(CMD_WB_WR);
459
 
460
  send_address_to_vpi(adr);
461
 
462
  send_data_to_vpi(sizeof(data));
463
 
464
  send_data_to_vpi(data);
465
 
466
  get_response_from_vpi();
467
 
468
  return 0;
469
}
470
 
471
 
472 40 julius
/* read a block from wishbone */
473
int dbg_wb_read_block32(uint32_t adr, uint32_t *data, int len)
474
{
475
 
476
  // len is in B Y T E S ! !
477
 
478 46 julius
  if (DBG_VPI) printf("xbrsp-rtl_sim: block read len: %d from addr: 0x%.8x\n",len, adr);
479 40 julius
 
480
  dbg_set_chain(DC_WISHBONE);
481
 
482
  send_command_to_vpi(CMD_WB_BLOCK_RD32);
483
 
484
  send_data_to_vpi(adr);
485
 
486
  send_data_to_vpi(len);
487
 
488
  get_block_data_from_vpi(len, data);
489
 
490
  get_response_from_vpi();
491
 
492
  return DBG_ERR_OK;
493
}
494
 
495
/* write a block to wishbone */
496
int dbg_wb_write_block32(uint32_t adr, uint32_t *data, int len)
497
{
498 46 julius
 
499
  if (DBG_CALLS)printf("dbg_wb_block32: adr 0x%.8x len %d bytes\n",adr, len);
500 40 julius
 
501
  dbg_set_chain(DC_WISHBONE);
502
 
503
  send_command_to_vpi(CMD_WB_BLOCK_WR32);
504
 
505
  send_data_to_vpi(adr);
506
 
507
  send_data_to_vpi(len);
508
 
509
  send_block_data_to_vpi(len, data);
510
 
511
  get_response_from_vpi();
512
 
513
  return DBG_ERR_OK;
514
}
515
 
516
/* read a register from cpu */
517
int dbg_cpu0_read(uint32_t adr, uint32_t *data)
518
{
519 46 julius
 
520
  if (DBG_CALLS)printf("dbg_cpu0_read: adr 0x%.8x\n",adr);
521 40 julius
 
522
  dbg_set_chain(DC_CPU0);
523
 
524
  send_command_to_vpi(CMD_CPU_RD_REG);
525
 
526
  send_address_to_vpi(adr);
527
 
528
  get_data_from_vpi(data);
529
 
530
  get_response_from_vpi();
531
 
532
  return 0;
533
 
534
}
535
 
536
/* write a cpu register */
537
int dbg_cpu0_write(uint32_t adr, uint32_t data)
538
{
539
 
540 46 julius
  if (DBG_CALLS)printf("dbg_cpu0_write: adr 0x%.8x\n",adr);
541 40 julius
 
542
  dbg_set_chain(DC_CPU0);
543
 
544
  send_command_to_vpi(CMD_CPU_WR_REG);
545
 
546
  send_address_to_vpi(adr);
547
 
548
  send_data_to_vpi(data);
549
 
550
  get_response_from_vpi();
551
 
552
  return 0;
553
}
554
 
555
/* read a register from cpu */
556
int dbg_cpu1_read(uint32_t adr, uint32_t *data) {
557
  /*
558
  int err;
559
  if ((err = dbg_set_chain(DC_CPU1))) return err;
560
  if ((err = dbg_command(0x6, adr, 4))) return err;
561
  if ((err = dbg_go((unsigned char*)data, 4, 1))) return err;
562
  *data = ntohl(*data);
563
  */
564
  return DBG_ERR_OK;
565
}
566
 
567
/* write a cpu register */
568
int dbg_cpu1_write(uint32_t adr, uint32_t data) {
569
  /*
570
  int err;
571
  data = ntohl(data);
572
  if ((err = dbg_set_chain(DC_CPU1))) return err;
573
  if ((err = dbg_command(0x2, adr, 4))) return err;
574
  if ((err = dbg_go((unsigned char*)&data, 4, 0))) return err;
575
  */
576
  return DBG_ERR_OK;
577
}
578
 
579
/* read a register from cpu module */
580
int dbg_cpu1_read_ctrl(uint32_t adr, unsigned char *data) {
581
  /*
582
    int err;
583
    int r, s;
584
    if ((err = dbg_set_chain(DC_CPU1))) return err;
585
    if ((err = dbg_ctrl_read(&r, &s))) return err;
586
    *data = (r << 1) | s;
587
    */
588
  return DBG_ERR_OK;
589
}
590
 
591
/* write a cpu module register */
592
int dbg_cpu0_write_ctrl(uint32_t adr, unsigned char data) {
593
  int err;
594
  if ((err = dbg_set_chain(DC_CPU0))) return err;
595
  if ((err = dbg_ctrl(data & 2, data &1))) return err;
596
  return DBG_ERR_OK;
597
}
598
 
599
/* read a register from cpu module */
600
int dbg_cpu0_read_ctrl(uint32_t adr, unsigned char *data) {
601
  int err;
602
  int r, s;
603
  if ((err = dbg_set_chain(DC_CPU0))) return err;
604
  if ((err = dbg_ctrl_read(&r, &s))) return err;
605
  *data = (r << 1) | s;
606
  return DBG_ERR_OK;
607
}
608
 
609
void dbg_test() {
610
  int i;
611
  uint32_t npc, ppc, r1, insn, result;
612
  unsigned char stalled;
613
  //    uint32_t stalled;
614
  unsigned char read_byte;
615
 
616
  printf("  Stall or1k\n");
617
  dbg_cpu0_write_ctrl(0, 0x01);      // stall or1k
618
 
619
  dbg_cpu0_read_ctrl(0, &stalled);
620
  if (!(stalled & 0x1)) {
621
    printf("\tor1k stall failed. read: 0x%x\n", stalled);   // check stall or1k
622
    //exit(1);
623
  }
624
 
625
  debug2("  Reading npc\n");
626
  dbg_cpu0_read((0 << 11) + 16, &npc);
627
  debug2("  Reading ppc\n");
628
  dbg_cpu0_read((0 << 11) + 18, &ppc);
629
  debug2("  Reading r1\n");
630
  dbg_cpu0_read(0x401, &r1);
631
  printf("  Read      npc = %.8x ppc = %.8x r1 = %.8x\n", npc, ppc, r1);
632
 
633
}
634
 
635
// Catch the term/int signals, close gdb then close ourselves
636
void catch_sigint(int sig_num)
637
{
638
  gdb_close();
639
  exit(0);
640
}
641
 
642
void dbg_client_detached(void)
643
{
644
  // Send this message back to the sim
645
  send_command_to_vpi(CMD_GDB_DETACH);
646
}
647
 
648
 
649
// This function is called after the fork in the VPI function.
650
 
651
void run_rsp_server(int portNum)
652
{
653
  // Send commands to init and reset debug interface
654
  dbg_reset();
655
  // Stall and read NPC, PPC etc
656
  dbg_test();
657
 
658
  set_rsp_server_port(portNum);
659
 
660
  // Install SIGINT/SIGTERM handlers, to close down gracefully
661
  signal(SIGINT, catch_sigint);
662
  signal(SIGTERM, catch_sigint);
663
 
664
  if (DBG_ON) printf("rsp-rtl_sim: starting handle_rsp()\n");
665
  // Now, start the RSP server. This should not return
666
  handle_rsp ();
667
 
668
  // Exit gracefully if it returns (shouldn't though)
669
  exit(0);
670
 
671
}
672
 
673
 

powered by: WebSVN 2.1.0

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