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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [or_debug_proxy/] [src/] [vpi_functions.c] - Blame information for rev 178

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

Line No. Rev Author Line
1 39 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                   : OpenRISC Debug Proxy
9
// File Name                      : vpi_functions.c
10
// Prepared By                    : jb
11
// Project Start                  : 2008-10-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
/*$$DESCRIPTION*/
37
/******************************************************************************/
38
/*                                                                            */
39
/*                           D E S C R I P T I O N                            */
40
/*                                                                            */
41
/******************************************************************************/
42
//
43
// Implements communications with a Verilog RTL simulation via functions running
44
// in the simulator, attached via VPI.
45
//
46
 
47
 
48
/*$$CHANGE HISTORY*/
49
/******************************************************************************/
50
/*                                                                            */
51
/*                         C H A N G E  H I S T O R Y                         */
52
/*                                                                            */
53
/******************************************************************************/
54
 
55
// Date         Version Description
56
//------------------------------------------------------------------------
57
// 081101               First revision                                  jb
58
 
59
#include <assert.h>
60
#include <stdio.h>
61
#include <ctype.h>
62
#include <string.h>
63
#include <stdlib.h>
64
#include <unistd.h>
65
#include <stdarg.h>
66
#include <sys/stat.h>
67
#include <sys/types.h>
68
 
69
#include <sys/socket.h>
70
#include <netinet/in.h>
71
#include <fcntl.h>
72
#include <errno.h>
73
#include <netdb.h> 
74
 
75
#include "gdb.h"
76
 
77
#include "or_debug_proxy.h"
78
 
79
#include "vpi_functions.h"
80
 
81
// Definition of MSG_WAITALL -- appears to be missing from Cygwin's sys/socket.h
82
#ifdef CYGWIN_COMPILE
83
#define MSG_WAITALL 0
84
#endif
85
 
86
// socket stuff for connection to the VPI interface
87
int vpiPort = VPI_PORT;
88
int vpi_fd; // should be the descriptor for our connection to the VPI server
89
 
90
#ifdef RTL_SIM
91
#define DBG_VPI 1
92
#else
93
#define DBG_VPI 0
94
#endif
95
 
96
//Protocol ensuring synchronisation with the jp-rtl_sim program
97
 
98
// 1. jp-rtl_sim will first write a command byte
99
// 2. jp-rtl_sim will then send the address if it's a read or write
100
//    or the data to write if it's a dbg_cpu_wr_ctrl (stall & reset bits)
101
// 3. will then send data if we're writing and we sent address in 2
102
// 4. wait for response from vpi functions
103
 
104
// commands:
105
// 4'h1 jtag set instruction register (input: instruction value)
106
// 4'h2 set debug chain (dbg_set_command here) (input: chain value)
107
// 4'h3 cpu_ctrl_wr (input: ctrl value (2 bits))
108
// 4'h4 cpu_ctrl_rd (output: ctrl value (2bits))
109
// 4'h5 cpu wr reg (inputs: address, data)
110
// 4'h6 cpu rd reg (input: address; output: data)
111
// 4'h7 wb wr 32 (inputs: address, data)
112
// 4'h8 wb rd 32 (input: address; output: data)
113
// 4'h9 wb wr block 32 (inputs: address, length, data)
114
// 4'ha wb rd block 32 (inputs: address, length; output: data)
115
// 4'hb reset
116
// 4'hc read jtag id (output: data)
117
 
118
#define CMD_JTAG_SET_IR 0x1
119
#define CMD_SET_DEBUG_CHAIN 0x2
120
#define CMD_CPU_CTRL_WR 0x3
121
#define CMD_CPU_CTRL_RD 0x4
122
#define CMD_CPU_WR_REG 0x5
123
#define CMD_CPU_RD_REG 0x6
124
#define CMD_WB_WR32 0x7
125
#define CMD_WB_RD32 0x8
126
#define CMD_WB_BLOCK_WR32 0x9
127
#define CMD_WB_BLOCK_RD32 0xa
128
#define CMD_RESET 0xb
129
#define CMD_READ_JTAG_ID 0xc
130
 
131
 
132
void send_command_to_vpi(char CMD)
133
{
134
  // first thing we do  is send a command
135
  // and wait for an ack
136
  uint32_t n;
137
  char cmd_resp;
138
 
139
  n = write(vpi_fd,&CMD, 1); // send the command to the sim
140
 
141
  if (n < 0)   perror("ERROR writing to VPI socket");
142
 
143
  n = recv(vpi_fd,&cmd_resp,1, MSG_WAITALL); // block and wait for the ack
144
 
145
  if (n < 0)   perror("ERROR Reading from VPI socket");
146
 
147
  if (cmd_resp != CMD) perror("Response from RTL sim incorrect"); //check it acked with cmd
148
 
149
  return;
150
}
151
 
152
void send_address_to_vpi(uint32_t address)
153
{
154
  // Now send address
155
  uint32_t n;
156
 
157
  char* send_buf;
158
 
159
  address = htonl(address);
160
 
161
  send_buf = (char *) &address;
162
 
163
  n = write(vpi_fd,send_buf, 4); // send the address to the sim
164
 
165
  if (n < 0)   perror("ERROR writing to VPI socket");
166
 
167
  return;
168
}
169
 
170
void send_data_to_vpi(uint32_t data)
171
{
172
  // Now send data
173
  uint32_t n;
174
 
175
  data = htonl(data);
176
 
177
  char* send_buf;
178
 
179
  send_buf = (char *) &data;
180
 
181
  n = write(vpi_fd,send_buf, 4); // Write the data to the socket
182
 
183
  if (n < 0)   perror("ERROR writing to VPI socket");
184
 
185
  return;
186
 
187
}
188
 
189
void send_block_data_to_vpi(uint32_t len, uint32_t *data)
190
{
191
  // Now send data
192
  uint32_t n, i;
193
 
194
  for (i = 0; i < (len/4); i++)
195
    data[i] = htonl(data[i]);
196
 
197
  char* send_buf;
198
 
199
  send_buf = (char *) data;
200
 
201
  n = write(vpi_fd,send_buf, len); // Write the data to the socket
202
 
203
  if (n < 0)   perror("ERROR writing to VPI socket");
204
 
205
  return;
206
 
207
}
208
 
209
void get_data_from_vpi(uint32_t* data)
210
{
211
 
212
  uint32_t n;
213
 
214
  uint32_t inc_data;
215
 
216
  char* recv_buf;
217
 
218
  recv_buf = (char*) &inc_data;
219
 
220
  n = recv(vpi_fd,recv_buf,4, MSG_WAITALL); // block and wait for the data
221
 
222
  if (n < 0)   perror("ERROR Reading from VPI socket");
223
 
224
  inc_data = ntohl(inc_data);
225
 
226
  if (DBG_VPI) printf("get_data_from_vpi: 0x%.8x\n",inc_data);
227
 
228
  *data = inc_data;
229
 
230
  return;
231
 
232
}
233
 
234
void get_block_data_from_vpi(uint32_t len, uint32_t* data)
235
{
236
  uint32_t n, i;
237
 
238
  char* recv_buf;
239
 
240
  recv_buf = (char *) data;
241
 
242
  n = recv(vpi_fd, recv_buf, len, MSG_WAITALL); // block and wait for the data
243
 
244
  if (n < 0)   perror("ERROR Reading from VPI socket");
245
 
246
  // re-order host compliant style the recieved words
247
  if (DBG_VPI) printf("get_block_data_from_vpi: %d bytes",len);
248
  for (i = 0;i < (len/4); i++)
249
    {
250
      data[i] = ntohl(data[i]);
251
 
252
      if (DBG_VPI) printf("0x%.8x ",data[i]);
253
    }
254
  if (DBG_VPI) printf("\n");
255
 
256
  return;
257
 
258
}
259
 
260
void get_response_from_vpi()
261
{
262
  // Basically just wait for the response from VPI
263
  // by blocking wait on recv
264
 
265
  uint32_t n;
266
  char tmp;
267
 
268
  n = recv(vpi_fd,&tmp,1, MSG_WAITALL); // block and wait
269
 
270
  if (n < 0)   perror("ERROR Reading from VPI socket");
271
 
272
  return;
273
}
274
 
275
/* Resets JTAG
276
   Writes TRST=0
277
   and    TRST=1 */
278
static void jp2_reset_JTAG() {
279
 
280
  debug2("\nreset(");
281
 
282
  send_command_to_vpi(CMD_RESET);
283
 
284
  get_response_from_vpi();
285
 
286
  debug2(")\n");
287
 
288
}
289
 
290
 
291
int vpi_connect() {
292
    int sockfd;
293
    struct sockaddr_in serv_addr;
294
    struct hostent *server;
295
    socklen_t flags;
296
    char sTemp[256];
297
 
298
    debug2("Started vpi_connect()\n");
299
 
300
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
301
    //sockfd = socket(PF_INET, SOCK_STREAM, 0);
302
 
303
    if (sockfd < 0) {
304
      perror("ERROR opening socket");
305
      goto socket_setup_exit;
306
    }
307
 
308
    server = gethostbyname("localhost");
309
 
310
    if (server == NULL) {
311
        fprintf(stderr,"ERROR, no such host\n");
312
        goto socket_setup_exit;
313
    }
314
 
315
    /*
316
    if(fcntl(sockfd, F_GETFL, &flags) < 0) {
317
      sprintf(sTemp, "Unable to get flags for socket %d", sockfd);
318
      perror(sTemp);
319
      close(sockfd);
320
      goto socket_setup_exit;
321
    }
322
 
323
    // Set the nonblocking flag
324
    if(fcntl(sockfd, F_SETFL, flags | O_NONBLOCK) < 0) {
325
      sprintf(sTemp, "Unable to set flags for socket %d to value 0x%08x",
326
              sockfd, flags | O_NONBLOCK);
327
      perror(sTemp);
328
      close(sockfd);
329
      goto socket_setup_exit;
330
    }
331
    */
332
 
333
    bzero((char *) &serv_addr, sizeof(serv_addr));
334
 
335
    serv_addr.sin_family = AF_INET;
336
 
337
    bcopy(server->h_addr,(char *)&serv_addr.sin_addr.s_addr,server->h_length);
338
 
339
    serv_addr.sin_port = htons(vpiPort);
340
 
341
    printf("Initialising connection with simulation\n");
342
 
343
    if (connect(sockfd,(struct sockaddr *)&serv_addr,sizeof(serv_addr)) < 0)
344
      {
345
        perror("Error connecting");
346
        goto socket_setup_exit;
347
      }
348
 
349
    return sockfd;
350
 
351
 socket_setup_exit:
352
    if (vpi_fd) close(vpi_fd);
353
    exit(1);
354
 
355
}
356
 
357
/* Resets JTAG, and sets DEBUG scan chain */
358
 int vpi_dbg_reset() {
359
 
360
   uint32_t id;
361
 
362
   jp2_reset_JTAG();
363
 
364
  /* set idcode jtag chain */
365
  send_command_to_vpi(CMD_JTAG_SET_IR);
366
 
367
  send_data_to_vpi(JI_IDCODE);
368
 
369
  get_response_from_vpi();
370
 
371
  /* now read out the jtag id */
372
  send_command_to_vpi(CMD_READ_JTAG_ID);
373
 
374
  //id = get_data_from_vpi();  
375
  get_data_from_vpi((uint32_t *)&id);
376
 
377
  get_response_from_vpi();
378
 
379
  printf("JTAG ID = %08x\n", (unsigned int) id);
380
 
381
  /* now set the chain to debug */
382
  send_command_to_vpi(CMD_JTAG_SET_IR);
383
 
384
  send_data_to_vpi(JI_DEBUG);
385
 
386
  get_response_from_vpi();
387
 
388
  current_chain = -1;
389
  return DBG_ERR_OK;
390
}
391
 
392
void vpi_dbg_test() {
393
 
394
  uint32_t npc, ppc, r1;
395
  unsigned char stalled;
396
 
397
  printf("  Stall or1k\n");
398
  dbg_cpu0_write_ctrl(0, 0x01);      // stall or1k
399
 
400
  dbg_cpu0_read_ctrl(0, &stalled);
401
  if (!(stalled & 0x1)) {
402
    printf("  or1k stall failed. Exiting\n");   // check stall or1k
403
    if (vpi_fd) close(vpi_fd);
404
    exit(1);
405
  }
406
 
407
  debug2("  Reading npc\n");
408
  dbg_cpu0_read((0 << 11) + 16, &npc);
409
  debug2("  Reading ppc\n");
410
  dbg_cpu0_read((0 << 11) + 18, &ppc);
411
  debug2("  Reading r1\n");
412
  dbg_cpu0_read(0x401, &r1);
413
  printf("  Read      npc = %.8x ppc = %.8x r1 = %.8x\n", npc, ppc, r1);
414
 
415
}
416
 
417
/* Sets scan chain.  */
418
int vpi_dbg_set_chain(uint32_t chain) {
419
  //uint32_t status, crc_generated, crc_read;
420
 
421
  if (current_chain == chain)
422
    return DBG_ERR_OK;
423
 
424
  dbg_chain = chain;
425
 
426
  send_command_to_vpi(CMD_SET_DEBUG_CHAIN);
427
 
428
  send_data_to_vpi(chain);
429
 
430
  get_response_from_vpi();
431
 
432
  current_chain = chain;
433
 
434
  return DBG_ERR_OK;
435
}
436
 
437
/* writes a ctrl reg */
438
int vpi_dbg_ctrl(uint32_t reset, uint32_t stall)
439
{
440
 
441
  debug("\n");
442
  debug2("ctrl\n");
443
 
444
  vpi_dbg_set_chain(dbg_chain);
445
 
446
  send_command_to_vpi(CMD_CPU_CTRL_WR);
447
 
448
  //send_data_to_vpi(((reset & 0x1) | ((stall&0x1)<<1)));
449
  send_data_to_vpi(((stall & 0x1) | ((reset&0x1)<<1)));
450
 
451
  get_response_from_vpi();
452
 
453
  return DBG_ERR_OK;
454
}
455
 
456
/* reads control register */
457
int vpi_dbg_ctrl_read(uint32_t *reset, uint32_t *stall)
458
{
459
 
460
  uint32_t resp;
461
 
462
  vpi_dbg_set_chain(dbg_chain);
463
 
464
  debug("\n");
465
  debug2("ctrl\n");
466
 
467
  vpi_dbg_set_chain(dbg_chain);
468
 
469
  send_command_to_vpi(CMD_CPU_CTRL_RD);
470
 
471
  get_data_from_vpi((uint32_t *)&resp);
472
 
473
  if (DBG_VPI) printf(" dbg_ctrl_read: 0x%.8x\n",resp);
474
 
475
  get_response_from_vpi();
476
 
477
  *reset = (resp & 0x00000001);
478
 
479
  *stall = ((resp >> 1) & 0x00000001);
480
 
481
  return DBG_ERR_OK;
482
}
483
 
484
/* read a word from wishbone */
485
int vpi_dbg_wb_read32(uint32_t adr, uint32_t *data)
486
{
487
  //uint32_t resp;
488
 
489
  vpi_dbg_set_chain(DC_WISHBONE);
490
 
491
  send_command_to_vpi(CMD_WB_RD32);
492
 
493
  send_address_to_vpi(adr);
494
 
495
  get_data_from_vpi(data);
496
 
497
  get_response_from_vpi();
498
 
499
  return 0;
500
}
501
 
502
/* write a word to wishbone */
503
int vpi_dbg_wb_write32(uint32_t adr, uint32_t data)
504
{
505
 
506
  vpi_dbg_set_chain(DC_WISHBONE);
507
 
508
  send_command_to_vpi(CMD_WB_WR32);
509
 
510
  send_address_to_vpi(adr);
511
 
512
  send_data_to_vpi(data);
513
 
514
  get_response_from_vpi();
515
 
516
  return 0;
517
}
518
 
519
/* read a block from wishbone */
520
int vpi_dbg_wb_read_block32(uint32_t adr, uint32_t *data, uint32_t len)
521
{
522
 
523
  // len is in B Y T E S ! !
524
 
525
  if (DBG_VPI) printf("block read len: %d from addr: 0x%.8x\n",len, adr);
526
 
527
  vpi_dbg_set_chain(DC_WISHBONE);
528
 
529
  send_command_to_vpi(CMD_WB_BLOCK_RD32);
530
 
531
  send_data_to_vpi(adr);
532
 
533
  send_data_to_vpi(len);
534
 
535
  get_block_data_from_vpi(len, data);
536
 
537
  get_response_from_vpi();
538
 
539
  return DBG_ERR_OK;
540
}
541
 
542
/* write a block to wishbone */
543
int vpi_dbg_wb_write_block32(uint32_t adr, uint32_t *data, uint32_t len)
544
{
545
 
546
  vpi_dbg_set_chain(DC_WISHBONE);
547
 
548
  send_command_to_vpi(CMD_WB_BLOCK_WR32);
549
 
550
  send_data_to_vpi(adr);
551
 
552
  send_data_to_vpi(len);
553
 
554
  send_block_data_to_vpi(len, data);
555
 
556
  get_response_from_vpi();
557
 
558
  return DBG_ERR_OK;
559
}
560
 
561
/* read a register from cpu */
562
int vpi_dbg_cpu0_read(uint32_t adr, uint32_t *data)
563
{
564
 
565
  vpi_dbg_set_chain(DC_CPU0);
566
 
567
  send_command_to_vpi(CMD_CPU_RD_REG);
568
 
569
  send_address_to_vpi(adr);
570
 
571
  get_data_from_vpi(data);
572
 
573
  get_response_from_vpi();
574
 
575
  return 0;
576
 
577
}
578
 
579
/* write a cpu register */
580
int vpi_dbg_cpu0_write(uint32_t adr, uint32_t data)
581
{
582
 
583
  vpi_dbg_set_chain(DC_CPU0);
584
 
585
  send_command_to_vpi(CMD_CPU_WR_REG);
586
 
587
  send_address_to_vpi(adr);
588
 
589
  send_data_to_vpi(data);
590
 
591
  get_response_from_vpi();
592
 
593
  return 0;
594
}
595
 
596
 
597
/* write a cpu module register */
598
int vpi_dbg_cpu0_write_ctrl(uint32_t adr, unsigned char data) {
599
  uint32_t err;
600
  if ((err = vpi_dbg_set_chain(DC_CPU0))) return err;
601
  if ((err = vpi_dbg_ctrl(data & 2, data &1))) return err;
602
  return DBG_ERR_OK;
603
}
604
 
605
/* read a register from cpu module */
606
int vpi_dbg_cpu0_read_ctrl(uint32_t adr, unsigned char *data) {
607
  uint32_t err;
608
  uint32_t r, s;
609
  if ((err = vpi_dbg_set_chain(DC_CPU0))) return err;
610
  if ((err = vpi_dbg_ctrl_read(&r, &s))) return err;
611
  *data = (r << 1) | s;
612
  return DBG_ERR_OK;
613
}

powered by: WebSVN 2.1.0

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