URL
https://opencores.org/ocsvn/or1k_old/or1k_old/trunk
Subversion Repositories or1k_old
Compare Revisions
- This comparison shows the changes necessary to convert path
/
- from Rev 1379 to Rev 1380
- ↔ Reverse comparison
Rev 1379 → Rev 1380
/trunk/jtag/gdb2.c
19,6 → 19,7
#include <errno.h> |
|
#include "gdb.h" /* partially copied from gdb/config/or1k */ |
#include "jp.h" /* just for debug() */ |
#include "jp2.h" |
|
|
26,7 → 27,7
int gdb_chain = -1; |
|
int gdb_read_reg(unsigned long adr, unsigned long *data) { |
printf("rr %d\n", gdb_chain); |
debug("rr %d\n", gdb_chain); |
switch (gdb_chain) { |
case SC_RISC_DEBUG: return dbg_cpu0_read(adr, data) ? ERR_CRC : ERR_NONE; |
case SC_REGISTER: return dbg_cpu0_read_ctrl(adr, (unsigned char*)data) ? ERR_CRC : ERR_NONE; |
37,7 → 38,7
} |
|
int gdb_write_reg(unsigned long adr, unsigned long data) { |
printf("wr %d\n", gdb_chain); |
debug("wr %d\n", gdb_chain); |
switch (gdb_chain) { /* remap registers, to be compatible with jp1 */ |
case SC_RISC_DEBUG: if (adr == JTAG_RISCOP) adr = 0x00; |
return dbg_cpu0_write(adr, data) ? ERR_CRC : ERR_NONE; |
49,7 → 50,7
} |
|
int gdb_read_block(unsigned long adr, unsigned long *data, int len) { |
printf("rb %d\n", gdb_chain); |
debug("rb %d\n", gdb_chain); |
switch (gdb_chain) { |
case SC_WISHBONE: return dbg_wb_read_block32(adr, data, len) ? ERR_CRC : ERR_NONE; |
default: return JTAG_PROXY_INVALID_CHAIN; |
57,7 → 58,7
} |
|
int gdb_write_block(unsigned long adr, unsigned long *data, int len) { |
printf("wb %d\n", gdb_chain); |
debug("wb %d\n", gdb_chain); |
switch (gdb_chain) { |
case SC_WISHBONE: return dbg_wb_write_block32(adr, data, len) ? ERR_CRC : ERR_NONE; |
default: return JTAG_PROXY_INVALID_CHAIN; |
65,7 → 66,7
} |
|
int gdb_set_chain(int chain) { |
printf("set_chain %d\n", chain); |
debug("set_chain %d\n", chain); |
switch (chain) { |
case SC_RISC_DEBUG: |
case SC_REGISTER: |
/trunk/jtag/jp-io.c
0,0 → 1,443
/* jp-io.c -- Low level JTAG communications |
Copyright (C) 2001 Marko Mlinar, markom@opencores.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 <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; |
} |
/trunk/jtag/jp.h
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) |
/trunk/jtag/jp2.h
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) |
|
/trunk/jtag/jp1.c
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,102 → 130,35
#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; |
} |
305,7 → 165,7
|
/* 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@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); |
/trunk/jtag/jp-io-vpi.c
0,0 → 1,279
/* jp-io-vpi.c -- JTAG communications vpi plugin |
|
|
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 |
}; |
/trunk/jtag/jp2.c
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@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); |
/trunk/jtag/Makefile
4,34 → 4,26
#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 |
vpi: jp-io-vpi.vpi Makefile |
|
jp2-xess: Makefile jp2.c gdb2.c |
rm -f $@ |
$(CC) -o $@ $(CFLAGS) jp2.c gdb2.c -DXESS_PARALLEL_CABLE |
|
install: all |
[ -d $(prefix)/bin ] || mkdir -p $(prefix)/bin |
for p in $(PROGRAMS) ; do \ |
40,4 → 32,4
done |
|
clean: Makefile |
rm -f $(PROGRAMS) *.o *~ |
rm -f $(PROGRAMS) jp-io-vpi.vpi *.o *~ |
/trunk/jtag/README
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 |