OpenCores
no use no use 1/1 no use no use
jp vpi interface
by Unknown on Nov 28, 2004
Not available!
Hi, I have been playing with orp in a rtl simulator (vvp), for a while and noticed that useing files for communicateing with the sim is painfully slow. So to fix the problem, I implemented a vpi interface for jp{1,2}. With this, communications between jp and the sim is imensly improved. As a side effect I cleaned up the communications part of jp{1,2}.c and made it more modular -- now we only have 1 binary for jp{1,2} respectively and it is possible to selected the cable to be used at runtime. I have also removed some inlines that make debugging impossible and don't add much to performance anyway. I haven't tested communications useing the xpc3 or xess cable since I don't have any of those, so if you have a board useing any of those cables, I would like to hear if my patch breaks anything for those. Find attached, the patch for jp{1,2} (jp.diff) and to dbg_comm.v to make use of the vpi interface (dbg_comm.diff) nog. -------------- next part -------------- --- /hd0/or1k/or1k/jtag/jp1.c 2004-11-03 18:36:24.000000000 +0100 +++ jp1.c 2004-11-27 09:53:43.000000000 +0100 @@ -27,21 +27,15 @@ #include #include #include +#include -/* Dirty way to include inb and outb from, but they say it is - a standard one. */ -#include -#include +#include "jp.h" #include "mc.h" - #define Boolean int #define false 0 #define true 1 -#define GDB_IN "../sim/rtl_sim/run/gdb_in.dat" -#define GDB_OUT "../sim/rtl_sim/run/gdb_out.dat" - /* Libraries for JTAG proxy server. */ #include #include @@ -57,72 +51,6 @@ #include "gdb.h" /* partially copied from gdb/config/or1k */ -#ifdef DEBUG -#define debug printf -#else -#define debug -#endif - -#ifdef DEBUG2 -#define debug2 printf -#else -#define debug2 -#endif - -#if (DEBUG) || (DEBUG2) -#define flush_debug() fflush(stdout) -#else -#define flush_debug() -#endif - -#define LPT_BASE (base) -#define LPT_READ (LPT_BASE+1) -#define LPT_WRITE LPT_BASE -#if RTL_SIM -#define TCLK_BIT (0x01) /* D0, pin #2 */ -#define TRST_BIT (0x02) /* D1, pin #3 */ -#define TDI_BIT (0x04) /* D2, pin #4 */ -#define TMS_BIT (0x08) /* D0, pin #5 */ -#define TDO_BIT (0x20) /* PE, pin #12 */ -#define TMS (0x02) -#define TDI (0x01) -#else -#ifdef XILINX_PARALLEL_CABLE_III -#define TCLK_BIT (0x02) /* D1 pin 3 */ -#define TRST_BIT (0x10) /* Not used */ -#define TDI_BIT (0x01) /* D0 pin 2 */ -#define TMS_BIT (0x04) /* D2 pin 4 */ -#define TDO_BIT (0x10) /* S6 pin 13*/ -#define TMS (0x02) -#define TDI (0x01) -#else -#ifdef XESS_PARALLEL_CABLE -#define TCLK_BIT (0x04) /* D2 pin 4 */ -#define TRST_BIT (0x08) /* D3 pin 5 */ -#define TDI_BIT (0x10) /* D4 pin 6 */ -#define TMS_BIT (0x20) /* D5 pin 7 */ -#define TDO_BIT (0x20) /* S5 pin 12*/ -#define TMS (0x02) -#define TDI (0x01) -#endif -#endif -#endif - -#ifdef RTL_SIM -# define JTAG_WAIT() usleep(1000) -# define NUM_RETRIES (16) -# define JTAG_RETRY_WAIT() usleep (1000) -#else -# define JTAG_WAIT() { \ - int i; \ - volatile int j; \ - for(i = 0; i markom@opencores.org\n\n"); - printf("Usage: %s JTAG port_number\n", argv[0]); + printf("Usage: %s [cable] [JTAG port_number]\n", argv[0]); + jp_print_cable_help(); return -1; } - -#ifndef RTL_SIM - if (ioperm(LPT_BASE, 3, 1)) { - fprintf(stderr, "Couldn't get the port at %x\n", LPT_BASE); - perror("Root privileges are required.\n"); + + cable = argv[1]; + port = argv[2]; + + if (!jp_select_cable(cable)) { + fprintf(stderr,"Error selecting cable %s\n", cable); return -1; } - printf("Connected to parallel port at %x\n", LPT_BASE); -#else - { - FILE *fin = fopen (GDB_IN, "wt+"); - if(fin == 0) { - fprintf(stderr, "Can not open %s\n", GDB_IN); - exit(1); - } - fclose(fin); - + + /* Get the cable-arguments */ + args = jp_get_cable_args(); + + /* Parse the cable arguments (if-any) */ + for(;;) { + c = getopt(argc, argv, args); + if(c == -1) + break; + if(c == '?') + return 1; + if(!jp_cable_opt(c, optarg)) + return 1; } -#endif -#ifndef RTL_SIM - /* Get rid of root privileges. */ - setreuid(getuid(), getuid()); -#endif - + if(!jp_init_cable()) + return 1; + /* Test the connection. */ if (jtag_init()) { - fprintf(stderr,"Connection with jtag via parallel port failed.\n"); + fprintf(stderr,"Connection with jtag via %s failed.\n", cable); exit(-1); } /* We have a connection. Establish server. */ - argv++; argc--; printf ("Dropping root privileges.\n"); - serverPort = strtol(*(argv),&s,10); + serverPort = strtol(port,&s,10); if(*s) return -1; - argv++; argc--; if(server_fd = GetServerSocket("or1ksim","tcp", serverPort)) { printf("JTAG Proxy server started on port %d\n", serverPort); --- /hd0/or1k/or1k/jtag/jp2.c 2004-04-15 09:24:21.000000000 +0200 +++ jp2.c 2004-11-27 18:04:39.000000000 +0100 @@ -31,13 +31,10 @@ #include #include -/* Dirty way to include inb and outb from, but they say it is - a standard one. */ -#include -#include #include "mc.h" #include "gdb.h" #include "jp2.h" +#include "jp.h" #define TC_RESET 0 #define TC_BRIGHT 1 @@ -62,8 +59,6 @@ #define SRAM_SIZE 0x04000000 // This is not ok - -static int base = 0x378; /* FIXME: We should detect the address. */ int err = 0; int set_pc = 0; int set_step = 0; @@ -97,97 +92,32 @@ return crc ^ (d ^ crc_32) & DBG_CRC_POLY; } -/* Send a byte to parallel port. */ -inline static void jp2_out(unsigned int value) { -#ifdef RTL_SIM - time_t time; - struct stat s; - char buf[1000]; - FILE *fout; - unsigned num_read; - int r; - fout = fopen(GDB_IN, "wt+"); - fprintf(fout, "F\n"); - fclose(fout); - fout = fopen(GDB_OUT, "wt+"); - fprintf(fout, "%02X\n", value); - fclose(fout); -error: - fout = fopen(GDB_OUT, "rt"); - r = fscanf(fout,"%x", &num_read); - fclose(fout); - if(r == 0 || num_read !=(0x10 | value)) goto error; -#else - outb(value, LPT_WRITE); -#endif /* RTL_SIM */ - if (!(value & TCLK_BIT)) { - if (value & TMS_BIT) debug("%c[%d;%dm", 0x1b, TC_BRIGHT, TC_WHITE + 30); - debug("%x",(value & TDI_BIT) != 0); - debug("%c[%d;%dm", 0x1b, TC_RESET, TC_WHITE + 30); - } - flush_debug(); -} - -/* Receive a byte from parallel port. */ -inline static unsigned char jp2_in() { - int data; -#ifndef RTL_SIM - data = inb(LPT_READ); -#ifdef TDO_INV - data =(data & TDO_BIT) != TDO_BIT; -#else - data =(data & TDO_BIT) == TDO_BIT; -#endif -#else - FILE *fin = 0; - char ch; - time_t time; - struct stat s; - while(1) { - fin = fopen(GDB_IN, "rt"); - if(fin == 0) continue; - ch = fgetc(fin); - if(ch != '0' && ch != '1') { - fclose(fin); - continue; - } else break; - } - fclose(fin); - data = ch == '1'; -#endif /* !RTL_SIM */ - debug("%c[%d;%dm", 0x1b, TC_BRIGHT, TC_GREEN + 30); - debug("%01X", data); - debug("%c[%d;%dm", 0x1b, TC_RESET, TC_WHITE + 30); - flush_debug(); - return data; -} - /* Writes TCLK=0, TRST=1, TMS=bit1, TDI=bit0 and TCLK=1, TRST=1, TMS=bit1, TDI=bit0 */ -static inline void jp2_write_JTAG(unsigned char packet) { - unsigned char data = TRST_BIT; +static void jp2_write_JTAG(uint8_t packet) { + uint8_t data = TRST_BIT; if(packet & 1) data |= TDI_BIT; if(packet & 2) data |= TMS_BIT; - jp2_out(data); - JTAG_WAIT(); + jp_out(data); + jp_wait(); crc_w = crc_calc(crc_w, packet&1); /* rise clock */ - jp2_out(data | TCLK_BIT); - JTAG_WAIT(); + jp_out(data | TCLK_BIT); + jp_wait(); } /* Reads TDI. */ -static inline int jp2_read_JTAG() { - int data; - data = jp2_in(); +static int jp2_read_JTAG() { + uint8_t data; + data = jp_in(); crc_r = crc_calc(crc_r, data); return data; } /* Writes bitstream. LS bit first if len 0. */ -static inline void jp2_write_stream(ULONGEST stream, int len, int set_last_bit) { +static void jp2_write_stream(ULONGEST stream, int len, int set_last_bit) { int i; if (len 0. */ -inline static ULONGEST jp2_read_stream(unsigned long stream, int len, int set_last_bit) { +static ULONGEST jp2_read_stream(unsigned long stream, int len, int set_last_bit) { int i; ULONGEST data = 0; if (len markom@opencores.org\n\n"); - printf("Usage: %s JTAG port_number\n", argv[0]); + printf("Copyright (C) 2001 Marko Mlinar, markom@opencores.org\n\n"); + printf("Usage: %s [cable] [JTAG port_number]\n", argv[0]); + jp_print_cable_help(); return -1; } - -#ifndef RTL_SIM - if(ioperm(LPT_BASE, 3, 1)) { - fprintf(stderr, "Couldn't get the port at %x\n", LPT_BASE); - perror("Root privileges are required.\n"); + + cable = argv[1]; + port = argv[2]; + + if (!jp_select_cable(cable)) { + fprintf(stderr,"Error selecting cable %s\n", cable); return -1; } - printf("Using parallel port at %x\n", LPT_BASE); -#else - { - FILE *fin = fopen(GDB_IN, "wt+"); - if(fin == 0) { - fprintf(stderr, "Can not open %s\n", GDB_IN); - exit(1); - } - fclose(fin); - + + /* Get the cable-arguments */ + args = jp_get_cable_args(); + + /* Parse the cable arguments (if-any) */ + for(;;) { + c = getopt(argc, argv, args); + if(c == -1) + break; + if(c == '?') + return 1; + if(!jp_cable_opt(c, optarg)) + return 1; } -#endif -#ifndef RTL_SIM - /* Get rid of root privileges. */ - setreuid(getuid(), getuid()); -#endif - + if(!jp_init_cable()) + return 1; + /* Initialize a new connection to the or1k board, and make sure we are really connected. */ current_chain = -1; @@ -1277,11 +1214,8 @@ dbg_test(); /* We have a connection. Establish server. */ - argv++; argc--; - printf("Dropping root privileges.\n"); - serverPort = strtol(*(argv),&s,10); + serverPort = strtol(port,&s,10); if(*s) return -1; - argv++; argc--; if(server_fd = GetServerSocket("or1ksim","tcp", serverPort)) { printf("JTAG Proxy server started on port %d\n", serverPort); --- /hd0/or1k/or1k/jtag/jp2.h 2004-04-14 15:03:24.000000000 +0200 +++ jp2.h 2004-11-27 17:53:12.000000000 +0100 @@ -1,80 +1,10 @@ #ifndef _JP2_H_ #define _JP2_H_ -//#define DEBUG 1 -//#define DEBUG2 1 - #define Boolean int #define false 0 #define true 1 -#define GDB_IN "../sim/rtl_sim/run/gdb_in.dat" -#define GDB_OUT "../sim/rtl_sim/run/gdb_out.dat" - -#ifdef DEBUG -#define debug printf -#else -#define debug -#endif - -#ifdef DEBUG2 -#define debug2 printf -#else -#define debug2 -#endif - -#if (DEBUG) || (DEBUG2) -#define flush_debug() fflush(stdout) -#else -#define flush_debug() -#endif - -#define LPT_BASE (base) -#define LPT_READ (LPT_BASE+1) -#define LPT_WRITE LPT_BASE -#if RTL_SIM -#define TCLK_BIT (0x01) /* D0, pin #2 */ -#define TRST_BIT (0x02) /* D1, pin #3 */ -#define TDI_BIT (0x04) /* D2, pin #4 */ -#define TMS_BIT (0x08) /* D0, pin #5 */ -#define TDO_BIT (0x20) /* PE, pin #12 */ -#define TMS (0x02) -#define TDI (0x01) -#else -#ifdef XILINX_PARALLEL_CABLE_III -#define TCLK_BIT (0x02) /* D1 pin 3 */ -#define TRST_BIT (0x10) /* Not used */ -#define TDI_BIT (0x01) /* D0 pin 2 */ -#define TMS_BIT (0x04) /* D2 pin 4 */ -#define TDO_BIT (0x10) /* S6 pin 13*/ -#define TMS (0x02) -#define TDI (0x01) -#else -#ifdef XESS_PARALLEL_CABLE -#define TCLK_BIT (0x04) /* D2 pin 4 */ -#define TRST_BIT (0x08) /* D3 pin 5 */ -#define TDI_BIT (0x10) /* D4 pin 6 */ -#define TMS_BIT (0x20) /* D5 pin 7 */ -#define TDO_BIT (0x20) /* S5 pin 12*/ -#define TMS (0x02) -#define TDI (0x01) -#endif -#endif -#endif - -#ifdef RTL_SIM -# define JTAG_WAIT() usleep(1000) -# define JTAG_RETRY_WAIT() usleep (1000) -#else -# define JTAG_WAIT() { \ - int i; \ - volatile int j; \ - for(i = 0; i + +The cable parameter selects the cable to use for communicateing with the board. +At the time of writting, cable may be one of xpc3, xess, rtl_sim or vpi. xpc3 +assumes a xillinx parallel cable 3, rtl_sim connects to a rtl simulator, +communicateing with it via files (slow), vpi connects to a rtl simulator via the +vpi (faster). The port parameter specified designates TCP/IP port address where +the server starts. Run jp1 without arguments for a list of cable specific +options. + First, start the jp1 program in root mode, e.g.: -./jp1 9999 +./jp1 xpc3 9999 -The parameter specified designates TCP/IP port address, -where the server starts. Then start gdb and connect to it, + Then start gdb and connect to it, using e.g.: $ or32-rtems-gdb test.or32 --- /dev/null 2003-01-07 18:22:11.000000000 +0100 +++ jp.h 2004-11-26 19:01:06.000000000 +0100 @@ -0,0 +1,41 @@ + +#define LPT_READ (base+1) +#define LPT_WRITE base + +#define TCLK_BIT (0x01) +#define TRST_BIT (0x02) +#define TDI_BIT (0x04) +#define TMS_BIT (0x08) +#define TDO_BIT (0x20) +#define TMS (0x02) +#define TDI (0x01) + +#ifdef DEBUG +#define debug printf +#else +#define debug +#endif + +#ifdef DEBUG2 +#define debug2 printf +#else +#define debug2 +#endif + +#if (DEBUG) || (DEBUG2) +#define flush_debug() fflush(stdout) +#else +#define flush_debug() +#endif + +void jp_out (uint8_t value); +uint8_t jp_in(); +int jp_select_cable(const char *cable); +void jp_wait(); +int jp_cable_opt(int c, char *str); +void jp_print_cable_help(); +const char *jp_get_cable_args(); +int jp_init_cable(); + +# define NUM_RETRIES (16) +# define JTAG_RETRY_WAIT() usleep (1000) --- /dev/null 2003-01-07 18:22:11.000000000 +0100 +++ jp-io.c 2004-11-27 18:04:21.000000000 +0100 @@ -0,0 +1,443 @@ +/* jp-io.c -- Low level JTAG communications + Copyright (C) 2001 Marko Mlinar, markom@opencores.org + Copyright (C) 2004 Gy?rgy Jeney, nog@sdf.lonestar.org + Code for TCP/IP copied from gdb, by Chris Ziomkowski + +This file is part of OpenRISC 1000 Architectural Simulator. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +/* This handles all the low-level io with the selected cable */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "jp.h" + +static int jp_parallel_init(); +static void jp_parallel_out(uint8_t value); +static uint8_t jp_parallel_in(); +static int jp_parallel_opt(int c, char *str); + +static void jp_phys_wait(); + +static int jp_rtl_sim_init(); +static void jp_rtl_sim_out(uint8_t value); +static uint8_t jp_rtl_sim_in(); +static void jp_rtl_sim_wait(); +static int jp_rtl_sim_opt(int c, char *str); + +static int jp_vpi_init(); +static void jp_vpi_out(uint8_t value); +static uint8_t jp_vpi_in(); +static void jp_vpi_wait(); +static int jp_vpi_opt(int c, char *str); + +static uint8_t jp_xpc3_in(); +static void jp_xpc3_out(uint8_t value); + +static uint8_t jp_xess_in(); +static void jp_xess_out(uint8_t value); + +static struct jtag_cable { + const char *name; + uint8_t (*in_func)(); + void (*out_func)(uint8_t); + int (*init_func)(); + void (*wait_func)(); + int (*opt_func)(int c, char *str); + const char *opts; + const char *help; +} jtag_cables[] = { + { "rtl_sim", jp_rtl_sim_in, jp_rtl_sim_out, jp_rtl_sim_init, jp_rtl_sim_wait, + jp_rtl_sim_opt, "d:", + "-d [directory] Directory in which gdb_in.dat/gdb_out.dat may be found\n" }, + { "vpi", jp_vpi_in, jp_vpi_out, jp_vpi_init, jp_vpi_wait, jp_vpi_opt, "s:", + "-s [socket] Location of socket that the vpi module created\n" }, + { "xpc3", jp_xpc3_in, jp_xpc3_out, jp_parallel_init, jp_phys_wait, + jp_parallel_opt, "p:", + "-p [port] Which port to use when communicateing with the parport hardware (eg. 0x378)\n" }, + { "xess", jp_xess_in, jp_xess_out, jp_parallel_init, jp_phys_wait, + jp_parallel_opt, "p:", + "-p [port] Which port to use when communicateing with the parport hardware (eg. 0x378)\n" }, + { NULL, NULL, NULL, NULL } }; + +static struct jtag_cable *jtag_cable_in_use = NULL; /* The current selected cable */ + +/* Only used for the parport */ +static int base = 0x378; + +/* Only used in the vpi */ +static int vpi_comm; +static char *sock_loc = "/tmp/jp-vpi"; + +/* Only used for the rtl_sim */ +static char *gdb_in = "gdb_in.dat"; +static char *gdb_out = "gdb_out.dat"; + +void jp_out (uint8_t value) +{ + /* finally call the cable-specific out-function */ + jtag_cable_in_use->out_func(value); + + if(!(value & 1)) + debug("[%x%c]", (value & TDI_BIT) != 0, (value & TMS_BIT) ? '^' : '_'); + flush_debug(); +} + +/* Receive a byte from the board. */ +uint8_t jp_in() +{ + int data; + + /* Get the data from the board */ + data = jtag_cable_in_use->in_func(); + + debug(" R%01X ", data); + flush_debug(); + return data; +} + +/* waits */ +void jp_wait() +{ + jtag_cable_in_use->wait_func(); +} + +/* Selects a cable for use, returns non-null on success */ +int jp_select_cable(const char *cable) +{ + int i; + + for(i = 0; jtag_cables.name; i++) { + if(!strcmp(cable, jtag_cables.name)) { + jtag_cable_in_use = &jtag_cables; + return 1; + } + } + + return 0; +} + +/* Calls the init-fucntion of the cable */ +int jp_init_cable() +{ + return jtag_cable_in_use->init_func(); +} + +/* Parses command-line options specific to the selected cable */ +int jp_cable_opt(int c, char *str) +{ + return jtag_cable_in_use->opt_func(c, str); +} + +const char *jp_get_cable_args() +{ + return jtag_cable_in_use->opts; +} + +/* Prints a (short) useage message for each availible cable */ +void jp_print_cable_help() +{ + int i; + printf("Availible cables: "); + + for(i = 0; jtag_cables.name; i++) { + if(i) + printf(", "); + printf(jtag_cables.name); + } + + printf("\n\nOptions availible for the cables:\n"); + for(i = 0; jtag_cables.name; i++) { + if(!jtag_cables.help) + continue; + printf(" %s:\n %s", jtag_cables.name, jtag_cables.help); + } +} + +/*-------------------------------------[ Parallel port specific functions ]---*/ +static int jp_parallel_init() +{ + if (ioperm(base, 3, 1)) { + fprintf(stderr, "Couldn't get the port at %x\n", base); + perror("Root privileges are required.\n"); + return 0; + } + printf("Connected to parallel port at %x\n", base); + printf("Dropping root privileges.\n"); + setreuid(getuid(), getuid()); + return 1; +} + +static void jp_parallel_out(uint8_t value) +{ + outb(value, LPT_WRITE); +} + +static uint8_t jp_parallel_in() +{ + return inb(LPT_READ); +} + +static int jp_parallel_opt(int c, char *str) +{ + switch(c) { + case 'p': + if(!sscanf(str, "%x", &base)) { + fprintf(stderr, "p parameter must have a hex number as parameter\n"); + return 0; + } + break; + default: + fprintf(stderr, "Unknown parameter '%c'\n", c); + return 0; + } + return 1; +} + +/*-----------------------------------------[ Physical board wait function ]---*/ +static void jp_phys_wait() +{ + /* FIXME: this needs some real TLC */ + int i; + volatile int j; + for(i = 0; i 1) + fprintf(stderr, "Unexpected value: %i\n", dat); + + return dat; +} + +static void jp_vpi_wait() +{ + uint8_t dat = 0x81; + + /* Get the sim to reply when the timeout has been reached */ + write(vpi_comm, &dat, 1); + + /* block, waiting for the data */ + read(vpi_comm, &dat, 1); +} + +static int jp_vpi_opt(int c, char *str) +{ + switch(c) { + case 's': + if(!(sock_loc = strdup(str))) { + fprintf(stderr, "Unable to allocate memory\n"); + return 0; + } + break; + default: + fprintf(stderr, "Unknown parameter '%c'\n", c); + return 0; + } + return 1; +} --- /dev/null 2003-01-07 18:22:11.000000000 +0100 +++ jp-io-vpi.c 2004-11-27 17:46:14.000000000 +0100 @@ -0,0 +1,259 @@ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +/* The vpijp connection is `mastered' by jp1. Therefore we just sit doing + * `nothing', waiting for jp1 to request or send us some data */ +static uint8_t vpi_out; /* data that the sim gives to us */ + +static int jp_comm_m; /* The listening socket */ +static int jp_comm; /* The socket for communitateing with jp1 */ + +static int jp_got_con; /* Have we got a connection ? */ + +static int count_comp; /* Has the predetermined cycle-count been reached ? */ +static int jp_waiting; /* Is jp-waiting for count_comp ? */ + +int jp_check_con(); + +/*---------------------------------------------[ VPI interface to the sim ]---*/ +/* Sends a byte from the sim */ +int vpi_jp_out(char *xx) +{ + vpiHandle sys = vpi_handle(vpiSysTfCall, 0); + vpiHandle argv = vpi_iterate(vpiArgument, sys); + s_vpi_value value; + + if(!argv) { + vpi_printf("$jp_out: missing destination argument\n"); + vpi_free_object(argv); + return 0; + } + vpiHandle dat_to = vpi_scan(argv); + if(vpi_get(vpiType, dat_to) != vpiNet) { + vpi_printf("$jp_out: Must have a net as argument!!\n"); + vpi_free_object(argv); + return 0; + } + + value.format = vpiVectorVal; + vpi_get_value(dat_to, &value); + + if((value.value.vector->bval & 1)) { + vpi_free_object(argv); + return 0; + } + vpi_out = value.value.vector->aval & 1; + + vpi_free_object(argv); + + return 0; +} + +/* Sends a byte to the sim */ +int vpi_jp_in(char *xx) +{ + int ret; + uint8_t dat; + s_vpi_vecval vec; + + s_vpi_value value; + vpiHandle sys = vpi_handle(vpiSysTfCall, 0); + vpiHandle argv; + vpiHandle dat_to; + + vpiHandle dat_to_index; + + if(!jp_got_con) { + if(!jp_check_con()) + return 0; + } + + ret = read(jp_comm, &dat, 1); + if(!ret) + return 0; + if((ret == -1) && (errno == EAGAIN)) + return 0; + + if(dat & 0x80) { + switch(dat & 0x7f) { + case 0: + /* jp1 wants the TDO */ + write(jp_comm, &vpi_out, 1); + return 0; + case 1: + /* jp wants a time-out */ + if(count_comp) + write(jp_comm, &dat, 1); /* The value is irrelevent */ + else + jp_waiting = 1; + return 0; + } + } + + argv = vpi_iterate(vpiArgument, sys); + + /* We got the data, acknowledge it and send it on to the sim */ + if(!argv) { + vpi_printf("$jp_in: missing destination argument\n"); + vpi_free_object(argv); + return 0; + } + dat_to = vpi_scan(argv); + if(vpi_get(vpiType, dat_to) != vpiMemory) { + vpi_printf("$jp_in: Must have a memory as argument!!\n"); + vpi_free_object(argv); + return 0; + } + + value.format = vpiVectorVal; + + vec.aval = (dat & 0xf) | 0x10; + vec.bval = 0; + value.value.vector = &vec; + dat_to_index = vpi_handle_by_index(dat_to, 0); + vpi_put_value(dat_to_index, &value, 0, vpiNoDelay); + + vpi_free_object(argv); + + dat |= 0x10; + write(jp_comm, &dat, 1); + + count_comp = 0; + + return 0; +} + +/* tells us that we reached a predetermined cycle count */ +int jp_wait_time(char *xx) +{ + uint8_t dat = 0; + if(jp_waiting) { + write(jp_comm, &dat, 1); + jp_waiting = 0; + } + count_comp = 1; + return 0; +} + +/*---------------------------------------------------[ VPIjp functions ]---*/ +int init_sock(char *xx) +{ + struct sockaddr_un addr; + int ret; + vpiHandle sys = vpi_handle(vpiSysTfCall, 0); + vpiHandle argv = vpi_iterate(vpiArgument, sys); + s_vpi_value value; + + if(!argv) { + vpi_printf("$jp_init: missing destination argument\n"); + return 0; + } + vpiHandle sock = vpi_scan(argv); +/* + if(vpi_get(vpiConstType, sock) != vpiStringConst) { + vpi_printf("$jp_init: Must have a string as argument!!\n"); + vpi_free_object(argv); + return 0; + } +*/ + + value.format = vpiStringVal; + vpi_get_value(sock, &value); + + addr.sun_family = AF_UNIX; + strcpy(addr.sun_path, value.value.str); + + if((jp_comm_m = socket(PF_UNIX, SOCK_STREAM, 0))
jp vpi interface
by Unknown on Nov 28, 2004
Not available!
Find attached, the patch for jp{1,2} (jp.diff) and to dbg_comm.v to make use of
the vpi interface (dbg_comm.diff)
Damn, I left of the copyright notice from jp-io-vpi.c, so here the fixed jp.diff. nog. -------------- next part -------------- --- /hd0/or1k/or1k/jtag/jp1.c 2004-11-03 18:36:24.000000000 +0100 +++ jp1.c 2004-11-27 09:53:43.000000000 +0100 @@ -27,21 +27,15 @@ #include #include #include +#include -/* Dirty way to include inb and outb from, but they say it is - a standard one. */ -#include -#include +#include "jp.h" #include "mc.h" - #define Boolean int #define false 0 #define true 1 -#define GDB_IN "../sim/rtl_sim/run/gdb_in.dat" -#define GDB_OUT "../sim/rtl_sim/run/gdb_out.dat" - /* Libraries for JTAG proxy server. */ #include #include @@ -57,72 +51,6 @@ #include "gdb.h" /* partially copied from gdb/config/or1k */ -#ifdef DEBUG -#define debug printf -#else -#define debug -#endif - -#ifdef DEBUG2 -#define debug2 printf -#else -#define debug2 -#endif - -#if (DEBUG) || (DEBUG2) -#define flush_debug() fflush(stdout) -#else -#define flush_debug() -#endif - -#define LPT_BASE (base) -#define LPT_READ (LPT_BASE+1) -#define LPT_WRITE LPT_BASE -#if RTL_SIM -#define TCLK_BIT (0x01) /* D0, pin #2 */ -#define TRST_BIT (0x02) /* D1, pin #3 */ -#define TDI_BIT (0x04) /* D2, pin #4 */ -#define TMS_BIT (0x08) /* D0, pin #5 */ -#define TDO_BIT (0x20) /* PE, pin #12 */ -#define TMS (0x02) -#define TDI (0x01) -#else -#ifdef XILINX_PARALLEL_CABLE_III -#define TCLK_BIT (0x02) /* D1 pin 3 */ -#define TRST_BIT (0x10) /* Not used */ -#define TDI_BIT (0x01) /* D0 pin 2 */ -#define TMS_BIT (0x04) /* D2 pin 4 */ -#define TDO_BIT (0x10) /* S6 pin 13*/ -#define TMS (0x02) -#define TDI (0x01) -#else -#ifdef XESS_PARALLEL_CABLE -#define TCLK_BIT (0x04) /* D2 pin 4 */ -#define TRST_BIT (0x08) /* D3 pin 5 */ -#define TDI_BIT (0x10) /* D4 pin 6 */ -#define TMS_BIT (0x20) /* D5 pin 7 */ -#define TDO_BIT (0x20) /* S5 pin 12*/ -#define TMS (0x02) -#define TDI (0x01) -#endif -#endif -#endif - -#ifdef RTL_SIM -# define JTAG_WAIT() usleep(1000) -# define NUM_RETRIES (16) -# define JTAG_RETRY_WAIT() usleep (1000) -#else -# define JTAG_WAIT() { \ - int i; \ - volatile int j; \ - for(i = 0; i markom@opencores.org\n\n"); - printf("Usage: %s JTAG port_number\n", argv[0]); + printf("Usage: %s [cable] [JTAG port_number]\n", argv[0]); + jp_print_cable_help(); return -1; } - -#ifndef RTL_SIM - if (ioperm(LPT_BASE, 3, 1)) { - fprintf(stderr, "Couldn't get the port at %x\n", LPT_BASE); - perror("Root privileges are required.\n"); + + cable = argv[1]; + port = argv[2]; + + if (!jp_select_cable(cable)) { + fprintf(stderr,"Error selecting cable %s\n", cable); return -1; } - printf("Connected to parallel port at %x\n", LPT_BASE); -#else - { - FILE *fin = fopen (GDB_IN, "wt+"); - if(fin == 0) { - fprintf(stderr, "Can not open %s\n", GDB_IN); - exit(1); - } - fclose(fin); - + + /* Get the cable-arguments */ + args = jp_get_cable_args(); + + /* Parse the cable arguments (if-any) */ + for(;;) { + c = getopt(argc, argv, args); + if(c == -1) + break; + if(c == '?') + return 1; + if(!jp_cable_opt(c, optarg)) + return 1; } -#endif -#ifndef RTL_SIM - /* Get rid of root privileges. */ - setreuid(getuid(), getuid()); -#endif - + if(!jp_init_cable()) + return 1; + /* Test the connection. */ if (jtag_init()) { - fprintf(stderr,"Connection with jtag via parallel port failed.\n"); + fprintf(stderr,"Connection with jtag via %s failed.\n", cable); exit(-1); } /* We have a connection. Establish server. */ - argv++; argc--; printf ("Dropping root privileges.\n"); - serverPort = strtol(*(argv),&s,10); + serverPort = strtol(port,&s,10); if(*s) return -1; - argv++; argc--; if(server_fd = GetServerSocket("or1ksim","tcp", serverPort)) { printf("JTAG Proxy server started on port %d\n", serverPort); --- /hd0/or1k/or1k/jtag/jp2.c 2004-04-15 09:24:21.000000000 +0200 +++ jp2.c 2004-11-27 18:04:39.000000000 +0100 @@ -31,13 +31,10 @@ #include #include -/* Dirty way to include inb and outb from, but they say it is - a standard one. */ -#include -#include #include "mc.h" #include "gdb.h" #include "jp2.h" +#include "jp.h" #define TC_RESET 0 #define TC_BRIGHT 1 @@ -62,8 +59,6 @@ #define SRAM_SIZE 0x04000000 // This is not ok - -static int base = 0x378; /* FIXME: We should detect the address. */ int err = 0; int set_pc = 0; int set_step = 0; @@ -97,97 +92,32 @@ return crc ^ (d ^ crc_32) & DBG_CRC_POLY; } -/* Send a byte to parallel port. */ -inline static void jp2_out(unsigned int value) { -#ifdef RTL_SIM - time_t time; - struct stat s; - char buf[1000]; - FILE *fout; - unsigned num_read; - int r; - fout = fopen(GDB_IN, "wt+"); - fprintf(fout, "F\n"); - fclose(fout); - fout = fopen(GDB_OUT, "wt+"); - fprintf(fout, "%02X\n", value); - fclose(fout); -error: - fout = fopen(GDB_OUT, "rt"); - r = fscanf(fout,"%x", &num_read); - fclose(fout); - if(r == 0 || num_read !=(0x10 | value)) goto error; -#else - outb(value, LPT_WRITE); -#endif /* RTL_SIM */ - if (!(value & TCLK_BIT)) { - if (value & TMS_BIT) debug("%c[%d;%dm", 0x1b, TC_BRIGHT, TC_WHITE + 30); - debug("%x",(value & TDI_BIT) != 0); - debug("%c[%d;%dm", 0x1b, TC_RESET, TC_WHITE + 30); - } - flush_debug(); -} - -/* Receive a byte from parallel port. */ -inline static unsigned char jp2_in() { - int data; -#ifndef RTL_SIM - data = inb(LPT_READ); -#ifdef TDO_INV - data =(data & TDO_BIT) != TDO_BIT; -#else - data =(data & TDO_BIT) == TDO_BIT; -#endif -#else - FILE *fin = 0; - char ch; - time_t time; - struct stat s; - while(1) { - fin = fopen(GDB_IN, "rt"); - if(fin == 0) continue; - ch = fgetc(fin); - if(ch != '0' && ch != '1') { - fclose(fin); - continue; - } else break; - } - fclose(fin); - data = ch == '1'; -#endif /* !RTL_SIM */ - debug("%c[%d;%dm", 0x1b, TC_BRIGHT, TC_GREEN + 30); - debug("%01X", data); - debug("%c[%d;%dm", 0x1b, TC_RESET, TC_WHITE + 30); - flush_debug(); - return data; -} - /* Writes TCLK=0, TRST=1, TMS=bit1, TDI=bit0 and TCLK=1, TRST=1, TMS=bit1, TDI=bit0 */ -static inline void jp2_write_JTAG(unsigned char packet) { - unsigned char data = TRST_BIT; +static void jp2_write_JTAG(uint8_t packet) { + uint8_t data = TRST_BIT; if(packet & 1) data |= TDI_BIT; if(packet & 2) data |= TMS_BIT; - jp2_out(data); - JTAG_WAIT(); + jp_out(data); + jp_wait(); crc_w = crc_calc(crc_w, packet&1); /* rise clock */ - jp2_out(data | TCLK_BIT); - JTAG_WAIT(); + jp_out(data | TCLK_BIT); + jp_wait(); } /* Reads TDI. */ -static inline int jp2_read_JTAG() { - int data; - data = jp2_in(); +static int jp2_read_JTAG() { + uint8_t data; + data = jp_in(); crc_r = crc_calc(crc_r, data); return data; } /* Writes bitstream. LS bit first if len 0. */ -static inline void jp2_write_stream(ULONGEST stream, int len, int set_last_bit) { +static void jp2_write_stream(ULONGEST stream, int len, int set_last_bit) { int i; if (len 0. */ -inline static ULONGEST jp2_read_stream(unsigned long stream, int len, int set_last_bit) { +static ULONGEST jp2_read_stream(unsigned long stream, int len, int set_last_bit) { int i; ULONGEST data = 0; if (len markom@opencores.org\n\n"); - printf("Usage: %s JTAG port_number\n", argv[0]); + printf("Copyright (C) 2001 Marko Mlinar, markom@opencores.org\n\n"); + printf("Usage: %s [cable] [JTAG port_number]\n", argv[0]); + jp_print_cable_help(); return -1; } - -#ifndef RTL_SIM - if(ioperm(LPT_BASE, 3, 1)) { - fprintf(stderr, "Couldn't get the port at %x\n", LPT_BASE); - perror("Root privileges are required.\n"); + + cable = argv[1]; + port = argv[2]; + + if (!jp_select_cable(cable)) { + fprintf(stderr,"Error selecting cable %s\n", cable); return -1; } - printf("Using parallel port at %x\n", LPT_BASE); -#else - { - FILE *fin = fopen(GDB_IN, "wt+"); - if(fin == 0) { - fprintf(stderr, "Can not open %s\n", GDB_IN); - exit(1); - } - fclose(fin); - + + /* Get the cable-arguments */ + args = jp_get_cable_args(); + + /* Parse the cable arguments (if-any) */ + for(;;) { + c = getopt(argc, argv, args); + if(c == -1) + break; + if(c == '?') + return 1; + if(!jp_cable_opt(c, optarg)) + return 1; } -#endif -#ifndef RTL_SIM - /* Get rid of root privileges. */ - setreuid(getuid(), getuid()); -#endif - + if(!jp_init_cable()) + return 1; + /* Initialize a new connection to the or1k board, and make sure we are really connected. */ current_chain = -1; @@ -1277,11 +1214,8 @@ dbg_test(); /* We have a connection. Establish server. */ - argv++; argc--; - printf("Dropping root privileges.\n"); - serverPort = strtol(*(argv),&s,10); + serverPort = strtol(port,&s,10); if(*s) return -1; - argv++; argc--; if(server_fd = GetServerSocket("or1ksim","tcp", serverPort)) { printf("JTAG Proxy server started on port %d\n", serverPort); --- /hd0/or1k/or1k/jtag/jp2.h 2004-04-14 15:03:24.000000000 +0200 +++ jp2.h 2004-11-27 17:53:12.000000000 +0100 @@ -1,80 +1,10 @@ #ifndef _JP2_H_ #define _JP2_H_ -//#define DEBUG 1 -//#define DEBUG2 1 - #define Boolean int #define false 0 #define true 1 -#define GDB_IN "../sim/rtl_sim/run/gdb_in.dat" -#define GDB_OUT "../sim/rtl_sim/run/gdb_out.dat" - -#ifdef DEBUG -#define debug printf -#else -#define debug -#endif - -#ifdef DEBUG2 -#define debug2 printf -#else -#define debug2 -#endif - -#if (DEBUG) || (DEBUG2) -#define flush_debug() fflush(stdout) -#else -#define flush_debug() -#endif - -#define LPT_BASE (base) -#define LPT_READ (LPT_BASE+1) -#define LPT_WRITE LPT_BASE -#if RTL_SIM -#define TCLK_BIT (0x01) /* D0, pin #2 */ -#define TRST_BIT (0x02) /* D1, pin #3 */ -#define TDI_BIT (0x04) /* D2, pin #4 */ -#define TMS_BIT (0x08) /* D0, pin #5 */ -#define TDO_BIT (0x20) /* PE, pin #12 */ -#define TMS (0x02) -#define TDI (0x01) -#else -#ifdef XILINX_PARALLEL_CABLE_III -#define TCLK_BIT (0x02) /* D1 pin 3 */ -#define TRST_BIT (0x10) /* Not used */ -#define TDI_BIT (0x01) /* D0 pin 2 */ -#define TMS_BIT (0x04) /* D2 pin 4 */ -#define TDO_BIT (0x10) /* S6 pin 13*/ -#define TMS (0x02) -#define TDI (0x01) -#else -#ifdef XESS_PARALLEL_CABLE -#define TCLK_BIT (0x04) /* D2 pin 4 */ -#define TRST_BIT (0x08) /* D3 pin 5 */ -#define TDI_BIT (0x10) /* D4 pin 6 */ -#define TMS_BIT (0x20) /* D5 pin 7 */ -#define TDO_BIT (0x20) /* S5 pin 12*/ -#define TMS (0x02) -#define TDI (0x01) -#endif -#endif -#endif - -#ifdef RTL_SIM -# define JTAG_WAIT() usleep(1000) -# define JTAG_RETRY_WAIT() usleep (1000) -#else -# define JTAG_WAIT() { \ - int i; \ - volatile int j; \ - for(i = 0; i + +The cable parameter selects the cable to use for communicateing with the board. +At the time of writting, cable may be one of xpc3, xess, rtl_sim or vpi. xpc3 +assumes a xillinx parallel cable 3, rtl_sim connects to a rtl simulator, +communicateing with it via files (slow), vpi connects to a rtl simulator via the +vpi (faster). The port parameter specified designates TCP/IP port address where +the server starts. Run jp1 without arguments for a list of cable specific +options. + First, start the jp1 program in root mode, e.g.: -./jp1 9999 +./jp1 xpc3 9999 -The parameter specified designates TCP/IP port address, -where the server starts. Then start gdb and connect to it, + Then start gdb and connect to it, using e.g.: $ or32-rtems-gdb test.or32 --- /dev/null 2003-01-07 18:22:11.000000000 +0100 +++ jp.h 2004-11-26 19:01:06.000000000 +0100 @@ -0,0 +1,41 @@ + +#define LPT_READ (base+1) +#define LPT_WRITE base + +#define TCLK_BIT (0x01) +#define TRST_BIT (0x02) +#define TDI_BIT (0x04) +#define TMS_BIT (0x08) +#define TDO_BIT (0x20) +#define TMS (0x02) +#define TDI (0x01) + +#ifdef DEBUG +#define debug printf +#else +#define debug +#endif + +#ifdef DEBUG2 +#define debug2 printf +#else +#define debug2 +#endif + +#if (DEBUG) || (DEBUG2) +#define flush_debug() fflush(stdout) +#else +#define flush_debug() +#endif + +void jp_out (uint8_t value); +uint8_t jp_in(); +int jp_select_cable(const char *cable); +void jp_wait(); +int jp_cable_opt(int c, char *str); +void jp_print_cable_help(); +const char *jp_get_cable_args(); +int jp_init_cable(); + +# define NUM_RETRIES (16) +# define JTAG_RETRY_WAIT() usleep (1000) --- /dev/null 2003-01-07 18:22:11.000000000 +0100 +++ jp-io.c 2004-11-27 18:04:21.000000000 +0100 @@ -0,0 +1,443 @@ +/* jp-io.c -- Low level JTAG communications + Copyright (C) 2001 Marko Mlinar, markom@opencores.org + Copyright (C) 2004 Gy?rgy Jeney, nog@sdf.lonestar.org + Code for TCP/IP copied from gdb, by Chris Ziomkowski + +This file is part of OpenRISC 1000 Architectural Simulator. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +/* This handles all the low-level io with the selected cable */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "jp.h" + +static int jp_parallel_init(); +static void jp_parallel_out(uint8_t value); +static uint8_t jp_parallel_in(); +static int jp_parallel_opt(int c, char *str); + +static void jp_phys_wait(); + +static int jp_rtl_sim_init(); +static void jp_rtl_sim_out(uint8_t value); +static uint8_t jp_rtl_sim_in(); +static void jp_rtl_sim_wait(); +static int jp_rtl_sim_opt(int c, char *str); + +static int jp_vpi_init(); +static void jp_vpi_out(uint8_t value); +static uint8_t jp_vpi_in(); +static void jp_vpi_wait(); +static int jp_vpi_opt(int c, char *str); + +static uint8_t jp_xpc3_in(); +static void jp_xpc3_out(uint8_t value); + +static uint8_t jp_xess_in(); +static void jp_xess_out(uint8_t value); + +static struct jtag_cable { + const char *name; + uint8_t (*in_func)(); + void (*out_func)(uint8_t); + int (*init_func)(); + void (*wait_func)(); + int (*opt_func)(int c, char *str); + const char *opts; + const char *help; +} jtag_cables[] = { + { "rtl_sim", jp_rtl_sim_in, jp_rtl_sim_out, jp_rtl_sim_init, jp_rtl_sim_wait, + jp_rtl_sim_opt, "d:", + "-d [directory] Directory in which gdb_in.dat/gdb_out.dat may be found\n" }, + { "vpi", jp_vpi_in, jp_vpi_out, jp_vpi_init, jp_vpi_wait, jp_vpi_opt, "s:", + "-s [socket] Location of socket that the vpi module created\n" }, + { "xpc3", jp_xpc3_in, jp_xpc3_out, jp_parallel_init, jp_phys_wait, + jp_parallel_opt, "p:", + "-p [port] Which port to use when communicateing with the parport hardware (eg. 0x378)\n" }, + { "xess", jp_xess_in, jp_xess_out, jp_parallel_init, jp_phys_wait, + jp_parallel_opt, "p:", + "-p [port] Which port to use when communicateing with the parport hardware (eg. 0x378)\n" }, + { NULL, NULL, NULL, NULL } }; + +static struct jtag_cable *jtag_cable_in_use = NULL; /* The current selected cable */ + +/* Only used for the parport */ +static int base = 0x378; + +/* Only used in the vpi */ +static int vpi_comm; +static char *sock_loc = "/tmp/jp-vpi"; + +/* Only used for the rtl_sim */ +static char *gdb_in = "gdb_in.dat"; +static char *gdb_out = "gdb_out.dat"; + +void jp_out (uint8_t value) +{ + /* finally call the cable-specific out-function */ + jtag_cable_in_use->out_func(value); + + if(!(value & 1)) + debug("[%x%c]", (value & TDI_BIT) != 0, (value & TMS_BIT) ? '^' : '_'); + flush_debug(); +} + +/* Receive a byte from the board. */ +uint8_t jp_in() +{ + int data; + + /* Get the data from the board */ + data = jtag_cable_in_use->in_func(); + + debug(" R%01X ", data); + flush_debug(); + return data; +} + +/* waits */ +void jp_wait() +{ + jtag_cable_in_use->wait_func(); +} + +/* Selects a cable for use, returns non-null on success */ +int jp_select_cable(const char *cable) +{ + int i; + + for(i = 0; jtag_cables.name; i++) { + if(!strcmp(cable, jtag_cables.name)) { + jtag_cable_in_use = &jtag_cables; + return 1; + } + } + + return 0; +} + +/* Calls the init-fucntion of the cable */ +int jp_init_cable() +{ + return jtag_cable_in_use->init_func(); +} + +/* Parses command-line options specific to the selected cable */ +int jp_cable_opt(int c, char *str) +{ + return jtag_cable_in_use->opt_func(c, str); +} + +const char *jp_get_cable_args() +{ + return jtag_cable_in_use->opts; +} + +/* Prints a (short) useage message for each availible cable */ +void jp_print_cable_help() +{ + int i; + printf("Availible cables: "); + + for(i = 0; jtag_cables.name; i++) { + if(i) + printf(", "); + printf(jtag_cables.name); + } + + printf("\n\nOptions availible for the cables:\n"); + for(i = 0; jtag_cables.name; i++) { + if(!jtag_cables.help) + continue; + printf(" %s:\n %s", jtag_cables.name, jtag_cables.help); + } +} + +/*-------------------------------------[ Parallel port specific functions ]---*/ +static int jp_parallel_init() +{ + if (ioperm(base, 3, 1)) { + fprintf(stderr, "Couldn't get the port at %x\n", base); + perror("Root privileges are required.\n"); + return 0; + } + printf("Connected to parallel port at %x\n", base); + printf("Dropping root privileges.\n"); + setreuid(getuid(), getuid()); + return 1; +} + +static void jp_parallel_out(uint8_t value) +{ + outb(value, LPT_WRITE); +} + +static uint8_t jp_parallel_in() +{ + return inb(LPT_READ); +} + +static int jp_parallel_opt(int c, char *str) +{ + switch(c) { + case 'p': + if(!sscanf(str, "%x", &base)) { + fprintf(stderr, "p parameter must have a hex number as parameter\n"); + return 0; + } + break; + default: + fprintf(stderr, "Unknown parameter '%c'\n", c); + return 0; + } + return 1; +} + +/*-----------------------------------------[ Physical board wait function ]---*/ +static void jp_phys_wait() +{ + /* FIXME: this needs some real TLC */ + int i; + volatile int j; + for(i = 0; i 1) + fprintf(stderr, "Unexpected value: %i\n", dat); + + return dat; +} + +static void jp_vpi_wait() +{ + uint8_t dat = 0x81; + + /* Get the sim to reply when the timeout has been reached */ + write(vpi_comm, &dat, 1); + + /* block, waiting for the data */ + read(vpi_comm, &dat, 1); +} + +static int jp_vpi_opt(int c, char *str) +{ + switch(c) { + case 's': + if(!(sock_loc = strdup(str))) { + fprintf(stderr, "Unable to allocate memory\n"); + return 0; + } + break; + default: + fprintf(stderr, "Unknown parameter '%c'\n", c); + return 0; + } + return 1; +} --- /hd0/or1k/or1k/jtag/Makefile 2004-05-05 20:15:37.000000000 +0200 +++ Makefile 2004-11-27 18:17:15.000000000 +0100 @@ -4,33 +4,25 @@ #CFLAGS = -g -O2 -DDEBUG2 -DDEBUG CC = gcc -PROGRAMS = jp1-xess jp1-xilinx jp1-rtl_sim jp2-xess jp2-xilinx jp2-rtl_sim +PROGRAMS = jp1 jp2 all: $(PROGRAMS) -jp1-rtl_sim: Makefile jp1.c - rm -f $@ - $(CC) -o $@ $(CFLAGS) jp1.c -DRTL_SIM +.c.o: + $(CC) $(CFLAGS) -c $nog@sdf.lonestar.org + +This file is part of OpenRISC 1000 Architectural Simulator. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +/* This plugs into an rtl simulator via vpi */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +/* The vpijp connection is `mastered' by jp1. Therefore we just sit doing + * `nothing', waiting for jp1 to request or send us some data */ +static uint8_t vpi_out; /* data that the sim gives to us */ + +static int jp_comm_m; /* The listening socket */ +static int jp_comm; /* The socket for communitateing with jp1 */ + +static int jp_got_con; /* Have we got a connection ? */ + +static int count_comp; /* Has the predetermined cycle-count been reached ? */ +static int jp_waiting; /* Is jp-waiting for count_comp ? */ + +int jp_check_con(); + +/*---------------------------------------------[ VPI interface to the sim ]---*/ +/* Sends a byte from the sim */ +int vpi_jp_out(char *xx) +{ + vpiHandle sys = vpi_handle(vpiSysTfCall, 0); + vpiHandle argv = vpi_iterate(vpiArgument, sys); + s_vpi_value value; + + if(!argv) { + vpi_printf("$jp_out: missing destination argument\n"); + vpi_free_object(argv); + return 0; + } + vpiHandle dat_to = vpi_scan(argv); + if(vpi_get(vpiType, dat_to) != vpiNet) { + vpi_printf("$jp_out: Must have a net as argument!!\n"); + vpi_free_object(argv); + return 0; + } + + value.format = vpiVectorVal; + vpi_get_value(dat_to, &value); + + if((value.value.vector->bval & 1)) { + vpi_free_object(argv); + return 0; + } + vpi_out = value.value.vector->aval & 1; + + vpi_free_object(argv); + + return 0; +} + +/* Sends a byte to the sim */ +int vpi_jp_in(char *xx) +{ + int ret; + uint8_t dat; + s_vpi_vecval vec; + + s_vpi_value value; + vpiHandle sys = vpi_handle(vpiSysTfCall, 0); + vpiHandle argv; + vpiHandle dat_to; + + vpiHandle dat_to_index; + + if(!jp_got_con) { + if(!jp_check_con()) + return 0; + } + + ret = read(jp_comm, &dat, 1); + if(!ret) + return 0; + if((ret == -1) && (errno == EAGAIN)) + return 0; + + if(dat & 0x80) { + switch(dat & 0x7f) { + case 0: + /* jp1 wants the TDO */ + write(jp_comm, &vpi_out, 1); + return 0; + case 1: + /* jp wants a time-out */ + if(count_comp) + write(jp_comm, &dat, 1); /* The value is irrelevent */ + else + jp_waiting = 1; + return 0; + } + } + + argv = vpi_iterate(vpiArgument, sys); + + /* We got the data, acknowledge it and send it on to the sim */ + if(!argv) { + vpi_printf("$jp_in: missing destination argument\n"); + vpi_free_object(argv); + return 0; + } + dat_to = vpi_scan(argv); + if(vpi_get(vpiType, dat_to) != vpiMemory) { + vpi_printf("$jp_in: Must have a memory as argument!!\n"); + vpi_free_object(argv); + return 0; + } + + value.format = vpiVectorVal; + + vec.aval = (dat & 0xf) | 0x10; + vec.bval = 0; + value.value.vector = &vec; + dat_to_index = vpi_handle_by_index(dat_to, 0); + vpi_put_value(dat_to_index, &value, 0, vpiNoDelay); + + vpi_free_object(argv); + + dat |= 0x10; + write(jp_comm, &dat, 1); + + count_comp = 0; + + return 0; +} + +/* tells us that we reached a predetermined cycle count */ +int jp_wait_time(char *xx) +{ + uint8_t dat = 0; + if(jp_waiting) { + write(jp_comm, &dat, 1); + jp_waiting = 0; + } + count_comp = 1; + return 0; +} + +/*---------------------------------------------------[ VPIjp functions ]---*/ +int init_sock(char *xx) +{ + struct sockaddr_un addr; + int ret; + vpiHandle sys = vpi_handle(vpiSysTfCall, 0); + vpiHandle argv = vpi_iterate(vpiArgument, sys); + s_vpi_value value; + + if(!argv) { + vpi_printf("$jp_init: missing destination argument\n"); + return 0; + } + vpiHandle sock = vpi_scan(argv); +/* + if(vpi_get(vpiConstType, sock) != vpiStringConst) { + vpi_printf("$jp_init: Must have a string as argument!!\n"); + vpi_free_object(argv); + return 0; + } +*/ + + value.format = vpiStringVal; + vpi_get_value(sock, &value); + + addr.sun_family = AF_UNIX; + strcpy(addr.sun_path, value.value.str); + + if((jp_comm_m = socket(PF_UNIX, SOCK_STREAM, 0))
jp vpi interface
by Unknown on Nov 30, 2004
Not available!
* György 'nog' Jeney (nog@sdf.lonestar.org) wrote:
Hi,

I have been playing with orp in a rtl simulator (vvp), for a while and noticed
that useing files for communicateing with the sim is painfully slow. So to fix
the problem, I implemented a vpi interface for jp{1,2}. With this, communications
between jp and the sim is imensly improved. As a side effect I cleaned up the
communications part of jp{1,2}.c and made it more modular -- now we only have 1
binary for jp{1,2} respectively and it is possible to selected the cable to be
used at runtime. I have also removed some inlines that make debugging
impossible and don't add much to performance anyway. I haven't tested
communications useing the xpc3 or xess cable since I don't have any of those, so
if you have a board useing any of those cables, I would like to hear if my patch
breaks anything for those.

Find attached, the patch for jp{1,2} (jp.diff) and to dbg_comm.v to make use of
the vpi interface (dbg_comm.diff)


looks great, this cleanup was long overdue. i'll take a closer look at it and
commit it to cvs.

best regards,
p.


no use no use 1/1 no use no use
© copyright 1999-2026 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.