LOGIN   :::   RECOVER PASS   :::   GET ACCOUNT    
Browse
  • Projects
  • Code (CVS)
  • Forums
  • News
  • Articles
  • Polls
  •  
    OpenCores
  • FAQ
  • CVS HowTo
  • Mission
  • Media
  • Tools
  • Advertise
  • Mirrors
  • Logos
  • Contact us
  • Find Resources
  • Job Opportunity
  •  
    Tools
  • Search
      
  • Download Cores (CVSGet)
  •  
    More
  • Wishbone
  • Perlilog
  • EDA tools
  • OpenTech CD
  •  
    Navigation: All forums > Openrisc > Message List > Message Post

    Message

    Reply | Reply all
    Date Prev | Date Next | Thread Prev | Thread Next Date Index | Thread Index

    From: György 'nog' Jeney<nog@s...>
    Date: Sun Nov 28 15:50:00 CET 2004
    Subject: [openrisc] jp vpi interface
    Top
    > 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 <stdlib.h>
    #include <unistd.h>
    #include <stdarg.h>
    +#include <stdint.h>

    -/* Dirty way to include inb and outb from, but they say it is
    - a standard one. */
    -#include <asm/io.h>
    -#include <asm/system.h>
    +#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 <sys/stat.h>
    #include <sys/types.h>
    @@ -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 < 1000; i++) \
    - j = i; \
    - }
    -# define NUM_RETRIES (16) -# define JTAG_RETRY_WAIT() usleep (1000) -#endif - /* Selects crc trailer size in bits. Currently supported: 8 */ #define CRC_SIZE (8) @@ -133,7 +61,6 @@ #define ULONGEST unsigned long #endif -static int base = 0x378; /* FIXME: We should detect the address. */ int err = 0; int set_pc = 0; int set_step = 0; @@ -177,7 +104,7 @@ /* Generates new crc, sending in new bit input_bit */ static int -crc_calc (int crc, int input_bit) +crc_calc (int crc, uint8_t input_bit) { int c; int new_crc; @@ -203,109 +130,42 @@ #endif } -/* Send a byte to parallel port. */ - -inline static void -jp1_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 & 1)) - debug("[%x%c]", (value & TDI_BIT) != 0, (value & TMS_BIT)?'^':'_'); - flush_debug(); -} - -/* Receive a byte from parallel port. */ - -inline static unsigned char -jp1_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(" R%01X ", data); - 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 +static void jp1_write_JTAG (packet) - unsigned char packet; + uint8_t packet; { - unsigned char data = TRST_BIT; + uint8_t data = TRST_BIT; if (packet & 1) data |= TDI_BIT; if (packet & 2) data |= TMS_BIT; - jp1_out (data); - JTAG_WAIT(); + jp_out (data); + jp_wait(); crc_w = crc_calc (crc_w, packet&1); /* rise clock */ - jp1_out (data | TCLK_BIT); - JTAG_WAIT(); + jp_out (data | TCLK_BIT); + jp_wait(); } /* Reads TDI. */ -static inline int +static uint8_t jp1_read_JTAG () { - int data; - data = jp1_in (); + uint8_t data; + data = jp_in (); crc_r = crc_calc (crc_r, data); return data; } /* Writes bitstream. LS bit first. */ -static inline void +static void jp1_write_stream (stream, len, set_last_bit) ULONGEST stream; int len; @@ -326,7 +186,7 @@ /* Gets bitstream. LS bit first. */ -inline static ULONGEST +static ULONGEST jp1_read_stream (stream, len, set_last_bit) unsigned long stream; int len; @@ -355,7 +215,7 @@ /* Goes into SELECT_IR state. Should be called before every control write. */ -inline static void +static void jp1_prepare_control () { if (!select_dr) @@ -373,12 +233,12 @@ { int i; debug2 ("\nreset("); - jp1_out (0); + jp_out (0); JTAG_RETRY_WAIT(); /* In case we don't have TRST reset it manually */ for (i = 0; i < 8; i++) jp1_write_JTAG (TMS); - jp1_out (TRST_BIT); + jp_out (TRST_BIT); JTAG_RETRY_WAIT(); jp1_write_JTAG (0); debug2(")\n"); @@ -1081,50 +941,55 @@ int trace_fd = 0; char *s; + int c; + const char *args; + char *port; + char *cable; + srand(getpid()); - if (argc != 2) { + if ((argc < 3) || (argv[1][0] == '-') || (argv[2][0] == '-')) { printf("JTAG protocol via parallel port for linux.\n"); printf("Copyright (C) 2001 Marko Mlinar, markom@o...\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 <sys/stat.h> #include <sys/types.h> -/* Dirty way to include inb and outb from, but they say it is - a standard one. */ -#include <asm/io.h> -#include <asm/system.h> #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, MS 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) { len = -len; @@ -209,7 +139,7 @@ } /* Gets bitstream. LS bit first if len < 0, MS bit first 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 < 0) { @@ -259,11 +189,11 @@ static void jp2_reset_JTAG() { int i; debug2("\nreset("); - jp2_out(0); + jp_out(0); JTAG_RETRY_WAIT(); /* In case we don't have TRST reset it manually */ for(i = 0; i < 8; i++) jp2_write_JTAG(TMS); - jp2_out(TRST_BIT); + jp_out(TRST_BIT); JTAG_RETRY_WAIT(); jp2_write_JTAG(0); debug2(")\n"); @@ -1237,37 +1167,44 @@ char *s; int err = DBG_ERR_OK; + int c; + const char *args; + char *port; + char *cable; + srand(getpid()); - if(argc != 2) { + if ((argc < 3) || (argv[1][0] == '-') || (argv[2][0] == '-')) { printf("JTAG protocol via parallel port for linux.\n"); - printf("Copyright(C) 2001 Marko Mlinar, markom@o...\n\n"); - printf("Usage: %s JTAG port_number\n", argv[0]); + printf("Copyright (C) 2001 Marko Mlinar, markom@o...\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 < 1000; i++) \ - j = i; \ - } -# define JTAG_RETRY_WAIT() usleep (1000) -#endif - /* Selects crc trailer size in bits. Currently supported: 8 */ #define CRC_SIZE (8) --- /hd0/or1k/or1k/jtag/README 2004-04-20 08:46:02.000000000 +0200 +++ README 2004-11-27 18:11:10.000000000 +0100 @@ -8,18 +8,27 @@ Parallel Cable III. Gdb is capable of connecting, controlling and debugging the board -via JP1. Currently jp1 has a support only for Linux. +via JP1. Currently jp1 has support only for Linux. USAGE +jp1 [cable] [port] <cable options> + +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@o... + Copyright (C) 2004 Gy?rgy Jeney, nog@s... + 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 <stdio.h> +#include <stdint.h> +#include <string.h> +#include <sys/io.h> +#include <sys/types.h> +#include <unistd.h> +#include <errno.h> +#include <stdlib.h> + +#include <sys/socket.h> +#include <sys/un.h> + +#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[i].name; i++) { + if(!strcmp(cable, jtag_cables[i].name)) { + jtag_cable_in_use = &jtag_cables[i]; + 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[i].name; i++) { + if(i) + printf(", "); + printf(jtag_cables[i].name); + } + + printf("\n\nOptions availible for the cables:\n"); + for(i = 0; jtag_cables[i].name; i++) { + if(!jtag_cables[i].help) + continue; + printf(" %s:\n %s", jtag_cables[i].name, jtag_cables[i].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 < 1000; i++) + j = i; +} + +/*----------------------------------------------[ xpc3 specific functions ]---*/ +static void jp_xpc3_out(uint8_t value) +{ + uint8_t out = 0; + + /* First convert the bits in value byte to the ones that the cable wants */ + if(value & TCLK_BIT) + out |= 0x02; /* D1 pin 3 */ + if(value & TRST_BIT) + out |= 0x10; /* Not used */ + if(value & TDI_BIT) + out |= 0x01; /* D0 pin 2 */ + if(value & TMS_BIT) + out |= 0x04; /* D2 pin 4 */ + + jp_parallel_out(out); +} + +static uint8_t jp_xpc3_in() +{ + uint8_t in; + + in = jp_parallel_in(); + + if(in & 0x10) /* S6 pin 13 */ + return 1; + return 0; +} + +/*----------------------------------------------[ xess specific functions ]---*/ +static void jp_xess_out(uint8_t value) +{ + uint8_t out = 0; + + /* First convert the bits in value byte to the ones that the cable wants */ + if(value & TCLK_BIT) + out |= 0x04; /* D2 pin 4 */ + if(value & TRST_BIT) + out |= 0x08; /* D3 pin 5 */ + if(value & TDI_BIT) + out |= 0x10; /* D4 pin 6 */ + if(value & TMS_BIT) + out |= 0x20; /* D3 pin 5 */ + + jp_parallel_out(out); +} + +static uint8_t jp_xess_in() +{ + uint8_t in; + + in = jp_parallel_in(); + + if(in & 0x20) /* S5 pin 12*/ + return 1; + return 0; +} + +/*-------------------------------------------[ rtl_sim specific functions ]---*/ +static int jp_rtl_sim_init() +{ + FILE *fin = fopen (gdb_in, "wt+"); + if(!fin) { + fprintf(stderr, "Can not open %s\n", gdb_in); + return 0; + } + fclose(fin); + return 1; +} + +static void jp_rtl_sim_out(uint8_t value) +{ + FILE *fout; + int 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); + do { + fout = fopen(gdb_out, "rt"); + r = fscanf(fout,"%x", &num_read); + fclose(fout); + } while(!r || (num_read != (0x10 | value))); +} + +static uint8_t jp_rtl_sim_in() +{ + FILE *fin = 0; + char ch; + uint8_t data; + while(1) { + fin = fopen(gdb_in, "rt"); + if(!fin) + continue; + ch = fgetc(fin); + fclose(fin); + if((ch != '0') && (ch != '1')) + continue; + else + break; + } + data = ch == '1' ? 1 : 0; + return data; +} + +static void jp_rtl_sim_wait() +{ + usleep(1000); +} + +static int jp_rtl_sim_opt(int c, char *str) +{ + switch(c) { + case 'd': + if(!(gdb_in = malloc(strlen(str) + 12))) { /* 12 == strlen("gdb_in.dat") + 2 */ + fprintf(stderr, "Unable to allocate enough memory\n"); + return 0; + } + if(!(gdb_out = malloc(strlen(str) + 13))) { /* 13 == strlen("gdb_out.dat") + 2 */ + fprintf(stderr, "Unable to allocate enough memory\n"); + free(gdb_in); + return 0; + } + + sprintf(gdb_in, "%s/gdb_in.dat", str); + sprintf(gdb_out, "%s/gdb_out.dat", str); + break; + default: + fprintf(stderr, "Unknown parameter '%c'\n", c); + return 0; + } + return 1; +} + +/*-----------------------------------------------[ VPI specific functions ]---*/ +static int jp_vpi_init() +{ + struct sockaddr_un addr; + + if((vpi_comm = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) { + fprintf(stderr, "Unable to create socket (%s)\n", strerror(errno)); + return 0; + } + + addr.sun_family = AF_UNIX; + strcpy(addr.sun_path, sock_loc); + + if(connect(vpi_comm, (struct sockaddr *)&addr, sizeof(addr)) == -1) { + fprintf(stderr, "Unable to connect to %s (%s)\n", addr.sun_path, + strerror(errno)); + return 0; + } + return 1; +} + +static void jp_vpi_out(uint8_t value) +{ + uint8_t ack; + + /* Send the data to the socket */ + write(vpi_comm, &value, 1); + + do { + /* Ok, read the data */ + read(vpi_comm, &ack, 1); + } while(ack != (value | 0x10)); +} + +static uint8_t jp_vpi_in() +{ + uint8_t dat; + + /* ask vpi to send us the out-bit */ + dat = 0x80; + write(vpi_comm, &dat, 1); + + /* Wait and read the data */ + read(vpi_comm, &dat, 1); + + if(dat > 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 $< -jp1-xilinx: Makefile jp1.c +jp1: Makefile jp1.o jp-io.o jp.h rm -f $@ - $(CC) -o $@ $(CFLAGS) jp1.c -DXILINX_PARALLEL_CABLE_III + $(CC) -o $@ $(CFLAGS) jp1.o jp-io.o -jp1-xess: Makefile jp1.c +jp2: Makefile jp2.o gdb2.o jp2.h jp-io.o jp.h rm -f $@ - $(CC) -o $@ $(CFLAGS) jp1.c -DXESS_PARALLEL_CABLE + $(CC) -o $@ $(CFLAGS) jp2.o jp-io.o gdb2.o -jp2-rtl_sim: Makefile jp2.c gdb2.c - rm -f $@ - $(CC) -o $@ $(CFLAGS) jp2.c gdb2.c -DRTL_SIM +jp-io-vpi.vpi: jp-io-vpi.c + iverilog-vpi jp-io-vpi.c -jp2-xilinx: Makefile jp2.c gdb2.c - rm -f $@ - $(CC) -o $@ $(CFLAGS) jp2.c gdb2.c -DXILINX_PARALLEL_CABLE_III - -jp2-xess: Makefile jp2.c gdb2.c - rm -f $@ - $(CC) -o $@ $(CFLAGS) jp2.c gdb2.c -DXESS_PARALLEL_CABLE +vpi: jp-io-vpi.vpi Makefile install: all [ -d $(prefix)/bin ] || mkdir -p $(prefix)/bin @@ -40,4 +32,4 @@ done clean: Makefile - rm -f $(PROGRAMS) *.o *~ + rm -f $(PROGRAMS) jp-io-vpi.vpi *.o *~ --- /dev/null 2003-01-07 18:22:11.000000000 +0100 +++ jp-io-vpi.c 2004-11-28 15:46:22.000000000 +0100 @@ -0,0 +1,279 @@ +/* jp-io-vpi.c -- JTAG communications vpi plugin + Copyright (C) 2004 Gy?rgy Jeney, nog@s... + +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 <stdio.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <unistd.h> +#include <stdint.h> +#include <fcntl.h> +#include <sys/un.h> +#include <errno.h> + +#include <vpi_user.h> + +/* The vpi<->jp 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; +} + +/*---------------------------------------------------[ VPI<->jp 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)) < 0) { + fprintf(stderr, "Unable to create comm socket\n"); + return 0; + } + + if(bind(jp_comm_m, (struct sockaddr *)&addr, sizeof(addr)) == -1) { + fprintf(stderr, "Unable to bind to the unix socket %s\n", addr.sun_path); + return 0; + } + + if(listen(jp_comm_m, 1) == -1) { + fprintf(stderr, "Unable to listen on %s (%s)\n", addr.sun_path, + strerror(errno)); + return 0; + } + + ret = fcntl(jp_comm_m, F_GETFL); + ret |= O_NONBLOCK; + fcntl(jp_comm_m, F_SETFL, ret); + + jp_got_con = 0; + jp_waiting = 0; + printf("Just registered socket!!!\n"); + return 0; +} + +/* Checks to see if we got a connection */ +int jp_check_con() +{ + int ret; + + if((jp_comm = accept(jp_comm_m, NULL, NULL)) == -1) { + if(errno == EAGAIN) + return 0; + fprintf(stderr, "Unable to accept connection (%s)\n", strerror(errno)); + return 0; + } + + /* Set the comm socket to non-blocking */ + ret = fcntl(jp_comm, F_GETFL); + ret |= O_NONBLOCK; + fcntl(jp_comm, F_SETFL, ret); + + jp_got_con = 1; + return 1; +} + +/*------------------------------------------------------------[ VPI stuff ]---*/ +static void jtag_register() +{ + s_vpi_systf_data tf_data; + + tf_data.type = vpiSysTask; + tf_data.tfname = "$jp_in"; + tf_data.calltf = vpi_jp_in; + tf_data.compiletf = 0; + tf_data.sizetf = 0; + vpi_register_systf(&tf_data); + + tf_data.type = vpiSysTask; + tf_data.tfname = "$jp_out"; + tf_data.calltf = vpi_jp_out; + tf_data.compiletf = 0; + tf_data.sizetf = 0; + vpi_register_systf(&tf_data); + + tf_data.type = vpiSysTask; + tf_data.tfname = "$jp_init"; + tf_data.calltf = init_sock; + tf_data.compiletf = 0; + tf_data.sizetf = 0; + vpi_register_systf(&tf_data); + + tf_data.type = vpiSysTask; + tf_data.tfname = "$jp_wait_time"; + tf_data.calltf = jp_wait_time; + tf_data.compiletf = 0; + tf_data.sizetf = 0; + vpi_register_systf(&tf_data); +} + +void (*vlog_startup_routines[])() = { + jtag_register, + 0 +};

    ReferenceAuthor
    [openrisc] jp vpi interface=?unknown-8bit?Q?Gy=F6rgy?= 'nog' Jeney

     
    Copyright (c) 1999 OPENCORES.ORG. All rights reserved.