|
Message
From: György 'nog' Jeney<nog@s...>
Date: Sun Nov 28 15:50:00 CET 2004
Subject: [openrisc] jp vpi interface
> 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
+};
|
 |