/* jp-io.c -- Low level JTAG communications
|
/* jp-io.c -- Low level JTAG communications
|
Copyright (C) 2001 Marko Mlinar, markom@opencores.org
|
Copyright (C) 2001 Marko Mlinar, markom@opencores.org
|
Copyright (C) 2004 György Jeney, nog@sdf.lonestar.org
|
Copyright (C) 2004 György Jeney, nog@sdf.lonestar.org
|
Code for TCP/IP copied from gdb, by Chris Ziomkowski
|
Code for TCP/IP copied from gdb, by Chris Ziomkowski
|
|
|
This file is part of OpenRISC 1000 Architectural Simulator.
|
This file is part of OpenRISC 1000 Architectural Simulator.
|
|
|
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
the Free Software Foundation; either version 2 of the License, or
|
the Free Software Foundation; either version 2 of the License, or
|
(at your option) any later version.
|
(at your option) any later version.
|
|
|
This program is distributed in the hope that it will be useful,
|
This program is distributed in the hope that it will be useful,
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
GNU General Public License for more details.
|
GNU General Public License for more details.
|
|
|
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
along with this program; if not, write to the Free Software
|
along with this program; if not, write to the Free Software
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
|
|
/* This handles all the low-level io with the selected cable */
|
/* This handles all the low-level io with the selected cable */
|
|
|
#include <stdio.h>
|
#include <stdio.h>
|
#include <stdint.h>
|
#include <stdint.h>
|
#include <string.h>
|
#include <string.h>
|
#include <sys/io.h>
|
#include <sys/io.h>
|
#include <sys/types.h>
|
#include <sys/types.h>
|
#include <unistd.h>
|
#include <unistd.h>
|
#include <errno.h>
|
#include <errno.h>
|
#include <stdlib.h>
|
#include <stdlib.h>
|
|
|
#include <sys/socket.h>
|
#include <sys/socket.h>
|
#include <sys/un.h>
|
#include <sys/un.h>
|
|
|
#include "jp.h"
|
#include "jp.h"
|
|
|
static int jp_parallel_init();
|
static int jp_parallel_init();
|
static void jp_parallel_out(uint8_t value);
|
static void jp_parallel_out(uint8_t value);
|
static uint8_t jp_parallel_in();
|
static uint8_t jp_parallel_in();
|
static int jp_parallel_opt(int c, char *str);
|
static int jp_parallel_opt(int c, char *str);
|
|
|
static void jp_phys_wait();
|
static void jp_phys_wait();
|
|
|
static int jp_rtl_sim_init();
|
static int jp_rtl_sim_init();
|
static void jp_rtl_sim_out(uint8_t value);
|
static void jp_rtl_sim_out(uint8_t value);
|
static uint8_t jp_rtl_sim_in();
|
static uint8_t jp_rtl_sim_in();
|
static void jp_rtl_sim_wait();
|
static void jp_rtl_sim_wait();
|
static int jp_rtl_sim_opt(int c, char *str);
|
static int jp_rtl_sim_opt(int c, char *str);
|
|
|
static int jp_vpi_init();
|
static int jp_vpi_init();
|
static void jp_vpi_out(uint8_t value);
|
static void jp_vpi_out(uint8_t value);
|
static uint8_t jp_vpi_in();
|
static uint8_t jp_vpi_in();
|
static void jp_vpi_wait();
|
static void jp_vpi_wait();
|
static int jp_vpi_opt(int c, char *str);
|
static int jp_vpi_opt(int c, char *str);
|
|
|
static uint8_t jp_xpc3_in();
|
static uint8_t jp_xpc3_in();
|
static void jp_xpc3_out(uint8_t value);
|
static void jp_xpc3_out(uint8_t value);
|
|
|
static uint8_t jp_xess_in();
|
static uint8_t jp_xess_in();
|
static void jp_xess_out(uint8_t value);
|
static void jp_xess_out(uint8_t value);
|
|
|
static struct jtag_cable {
|
static struct jtag_cable {
|
const char *name;
|
const char *name;
|
uint8_t (*in_func)();
|
uint8_t (*in_func)();
|
void (*out_func)(uint8_t);
|
void (*out_func)(uint8_t);
|
int (*init_func)();
|
int (*init_func)();
|
void (*wait_func)();
|
void (*wait_func)();
|
int (*opt_func)(int c, char *str);
|
int (*opt_func)(int c, char *str);
|
const char *opts;
|
const char *opts;
|
const char *help;
|
const char *help;
|
} jtag_cables[] = {
|
} jtag_cables[] = {
|
{ "rtl_sim", jp_rtl_sim_in, jp_rtl_sim_out, jp_rtl_sim_init, jp_rtl_sim_wait,
|
{ "rtl_sim", jp_rtl_sim_in, jp_rtl_sim_out, jp_rtl_sim_init, jp_rtl_sim_wait,
|
jp_rtl_sim_opt, "d:",
|
jp_rtl_sim_opt, "d:",
|
"-d [directory] Directory in which gdb_in.dat/gdb_out.dat may be found\n" },
|
"-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:",
|
{ "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" },
|
"-s [socket] Location of socket that the vpi module created\n" },
|
{ "xpc3", jp_xpc3_in, jp_xpc3_out, jp_parallel_init, jp_phys_wait,
|
{ "xpc3", jp_xpc3_in, jp_xpc3_out, jp_parallel_init, jp_phys_wait,
|
jp_parallel_opt, "p:",
|
jp_parallel_opt, "p:",
|
"-p [port] Which port to use when communicateing with the parport hardware (eg. 0x378)\n" },
|
"-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,
|
{ "xess", jp_xess_in, jp_xess_out, jp_parallel_init, jp_phys_wait,
|
jp_parallel_opt, "p:",
|
jp_parallel_opt, "p:",
|
"-p [port] Which port to use when communicateing with the parport hardware (eg. 0x378)\n" },
|
"-p [port] Which port to use when communicateing with the parport hardware (eg. 0x378)\n" },
|
{ NULL, NULL, NULL, NULL } };
|
{ NULL, NULL, NULL, NULL } };
|
|
|
static struct jtag_cable *jtag_cable_in_use = NULL; /* The current selected cable */
|
static struct jtag_cable *jtag_cable_in_use = NULL; /* The current selected cable */
|
|
|
/* Only used for the parport */
|
/* Only used for the parport */
|
static int base = 0x378;
|
static int base = 0x378;
|
|
|
/* Only used in the vpi */
|
/* Only used in the vpi */
|
static int vpi_comm;
|
static int vpi_comm;
|
static char *sock_loc = "/tmp/jp-vpi";
|
static char *sock_loc = "/tmp/jp-vpi";
|
|
|
/* Only used for the rtl_sim */
|
/* Only used for the rtl_sim */
|
static char *gdb_in = "gdb_in.dat";
|
static char *gdb_in = "gdb_in.dat";
|
static char *gdb_out = "gdb_out.dat";
|
static char *gdb_out = "gdb_out.dat";
|
|
|
void jp_out (uint8_t value)
|
void jp_out (uint8_t value)
|
{
|
{
|
/* finally call the cable-specific out-function */
|
/* finally call the cable-specific out-function */
|
jtag_cable_in_use->out_func(value);
|
jtag_cable_in_use->out_func(value);
|
|
|
if(!(value & 1))
|
if(!(value & 1))
|
debug("[%x%c]", (value & TDI_BIT) != 0, (value & TMS_BIT) ? '^' : '_');
|
debug("[%x%c]", (value & TDI_BIT) != 0, (value & TMS_BIT) ? '^' : '_');
|
flush_debug();
|
flush_debug();
|
}
|
}
|
|
|
/* Receive a byte from the board. */
|
/* Receive a byte from the board. */
|
uint8_t jp_in()
|
uint8_t jp_in()
|
{
|
{
|
int data;
|
int data;
|
|
|
/* Get the data from the board */
|
/* Get the data from the board */
|
data = jtag_cable_in_use->in_func();
|
data = jtag_cable_in_use->in_func();
|
|
|
debug(" R%01X ", data);
|
debug(" R%01X ", data);
|
flush_debug();
|
flush_debug();
|
return data;
|
return data;
|
}
|
}
|
|
|
/* waits */
|
/* waits */
|
void jp_wait()
|
void jp_wait()
|
{
|
{
|
jtag_cable_in_use->wait_func();
|
jtag_cable_in_use->wait_func();
|
}
|
}
|
|
|
/* Selects a cable for use, returns non-null on success */
|
/* Selects a cable for use, returns non-null on success */
|
int jp_select_cable(const char *cable)
|
int jp_select_cable(const char *cable)
|
{
|
{
|
int i;
|
int i;
|
|
|
for(i = 0; jtag_cables[i].name; i++) {
|
for(i = 0; jtag_cables[i].name; i++) {
|
if(!strcmp(cable, jtag_cables[i].name)) {
|
if(!strcmp(cable, jtag_cables[i].name)) {
|
jtag_cable_in_use = &jtag_cables[i];
|
jtag_cable_in_use = &jtag_cables[i];
|
return 1;
|
return 1;
|
}
|
}
|
}
|
}
|
|
|
return 0;
|
return 0;
|
}
|
}
|
|
|
/* Calls the init-fucntion of the cable */
|
/* Calls the init-fucntion of the cable */
|
int jp_init_cable()
|
int jp_init_cable()
|
{
|
{
|
return jtag_cable_in_use->init_func();
|
return jtag_cable_in_use->init_func();
|
}
|
}
|
|
|
/* Parses command-line options specific to the selected cable */
|
/* Parses command-line options specific to the selected cable */
|
int jp_cable_opt(int c, char *str)
|
int jp_cable_opt(int c, char *str)
|
{
|
{
|
return jtag_cable_in_use->opt_func(c, str);
|
return jtag_cable_in_use->opt_func(c, str);
|
}
|
}
|
|
|
const char *jp_get_cable_args()
|
const char *jp_get_cable_args()
|
{
|
{
|
return jtag_cable_in_use->opts;
|
return jtag_cable_in_use->opts;
|
}
|
}
|
|
|
/* Prints a (short) useage message for each availible cable */
|
/* Prints a (short) useage message for each availible cable */
|
void jp_print_cable_help()
|
void jp_print_cable_help()
|
{
|
{
|
int i;
|
int i;
|
printf("Availible cables: ");
|
printf("Availible cables: ");
|
|
|
for(i = 0; jtag_cables[i].name; i++) {
|
for(i = 0; jtag_cables[i].name; i++) {
|
if(i)
|
if(i)
|
printf(", ");
|
printf(", ");
|
printf(jtag_cables[i].name);
|
printf(jtag_cables[i].name);
|
}
|
}
|
|
|
printf("\n\nOptions availible for the cables:\n");
|
printf("\n\nOptions availible for the cables:\n");
|
for(i = 0; jtag_cables[i].name; i++) {
|
for(i = 0; jtag_cables[i].name; i++) {
|
if(!jtag_cables[i].help)
|
if(!jtag_cables[i].help)
|
continue;
|
continue;
|
printf(" %s:\n %s", jtag_cables[i].name, jtag_cables[i].help);
|
printf(" %s:\n %s", jtag_cables[i].name, jtag_cables[i].help);
|
}
|
}
|
}
|
}
|
|
|
/*-------------------------------------[ Parallel port specific functions ]---*/
|
/*-------------------------------------[ Parallel port specific functions ]---*/
|
static int jp_parallel_init()
|
static int jp_parallel_init()
|
{
|
{
|
if (ioperm(base, 3, 1)) {
|
if (ioperm(base, 3, 1)) {
|
fprintf(stderr, "Couldn't get the port at %x\n", base);
|
fprintf(stderr, "Couldn't get the port at %x\n", base);
|
perror("Root privileges are required.\n");
|
perror("Root privileges are required.\n");
|
return 0;
|
return 0;
|
}
|
}
|
printf("Connected to parallel port at %x\n", base);
|
printf("Connected to parallel port at %x\n", base);
|
printf("Dropping root privileges.\n");
|
printf("Dropping root privileges.\n");
|
setreuid(getuid(), getuid());
|
setreuid(getuid(), getuid());
|
return 1;
|
return 1;
|
}
|
}
|
|
|
static void jp_parallel_out(uint8_t value)
|
static void jp_parallel_out(uint8_t value)
|
{
|
{
|
outb(value, LPT_WRITE);
|
outb(value, LPT_WRITE);
|
}
|
}
|
|
|
static uint8_t jp_parallel_in()
|
static uint8_t jp_parallel_in()
|
{
|
{
|
return inb(LPT_READ);
|
return inb(LPT_READ);
|
}
|
}
|
|
|
static int jp_parallel_opt(int c, char *str)
|
static int jp_parallel_opt(int c, char *str)
|
{
|
{
|
switch(c) {
|
switch(c) {
|
case 'p':
|
case 'p':
|
if(!sscanf(str, "%x", &base)) {
|
if(!sscanf(str, "%x", &base)) {
|
fprintf(stderr, "p parameter must have a hex number as parameter\n");
|
fprintf(stderr, "p parameter must have a hex number as parameter\n");
|
return 0;
|
return 0;
|
}
|
}
|
break;
|
break;
|
default:
|
default:
|
fprintf(stderr, "Unknown parameter '%c'\n", c);
|
fprintf(stderr, "Unknown parameter '%c'\n", c);
|
return 0;
|
return 0;
|
}
|
}
|
return 1;
|
return 1;
|
}
|
}
|
|
|
/*-----------------------------------------[ Physical board wait function ]---*/
|
/*-----------------------------------------[ Physical board wait function ]---*/
|
static void jp_phys_wait()
|
static void jp_phys_wait()
|
{
|
{
|
/* FIXME: this needs some real TLC */
|
/* FIXME: this needs some real TLC */
|
int i;
|
int i;
|
volatile int j;
|
volatile int j;
|
for(i = 0; i < 1000; i++)
|
for(i = 0; i < 1000; i++)
|
j = i;
|
j = i;
|
}
|
}
|
|
|
/*----------------------------------------------[ xpc3 specific functions ]---*/
|
/*----------------------------------------------[ xpc3 specific functions ]---*/
|
static void jp_xpc3_out(uint8_t value)
|
static void jp_xpc3_out(uint8_t value)
|
{
|
{
|
uint8_t out = 0;
|
uint8_t out = 0;
|
|
|
/* First convert the bits in value byte to the ones that the cable wants */
|
/* First convert the bits in value byte to the ones that the cable wants */
|
if(value & TCLK_BIT)
|
if(value & TCLK_BIT)
|
out |= 0x02; /* D1 pin 3 */
|
out |= 0x02; /* D1 pin 3 */
|
if(value & TRST_BIT)
|
if(value & TRST_BIT)
|
out |= 0x10; /* Not used */
|
out |= 0x10; /* Not used */
|
if(value & TDI_BIT)
|
if(value & TDI_BIT)
|
out |= 0x01; /* D0 pin 2 */
|
out |= 0x01; /* D0 pin 2 */
|
if(value & TMS_BIT)
|
if(value & TMS_BIT)
|
out |= 0x04; /* D2 pin 4 */
|
out |= 0x04; /* D2 pin 4 */
|
|
|
jp_parallel_out(out);
|
jp_parallel_out(out);
|
}
|
}
|
|
|
static uint8_t jp_xpc3_in()
|
static uint8_t jp_xpc3_in()
|
{
|
{
|
uint8_t in;
|
uint8_t in;
|
|
|
in = jp_parallel_in();
|
in = jp_parallel_in();
|
|
|
if(in & 0x10) /* S6 pin 13 */
|
if(in & 0x10) /* S6 pin 13 */
|
return 1;
|
return 1;
|
return 0;
|
return 0;
|
}
|
}
|
|
|
/*----------------------------------------------[ xess specific functions ]---*/
|
/*----------------------------------------------[ xess specific functions ]---*/
|
static void jp_xess_out(uint8_t value)
|
static void jp_xess_out(uint8_t value)
|
{
|
{
|
uint8_t out = 0;
|
uint8_t out = 0;
|
|
|
/* First convert the bits in value byte to the ones that the cable wants */
|
/* First convert the bits in value byte to the ones that the cable wants */
|
if(value & TCLK_BIT)
|
if(value & TCLK_BIT)
|
out |= 0x04; /* D2 pin 4 */
|
out |= 0x04; /* D2 pin 4 */
|
if(value & TRST_BIT)
|
if(value & TRST_BIT)
|
out |= 0x08; /* D3 pin 5 */
|
out |= 0x08; /* D3 pin 5 */
|
if(value & TDI_BIT)
|
if(value & TDI_BIT)
|
out |= 0x10; /* D4 pin 6 */
|
out |= 0x10; /* D4 pin 6 */
|
if(value & TMS_BIT)
|
if(value & TMS_BIT)
|
out |= 0x20; /* D3 pin 5 */
|
out |= 0x20; /* D3 pin 5 */
|
|
|
jp_parallel_out(out);
|
jp_parallel_out(out);
|
}
|
}
|
|
|
static uint8_t jp_xess_in()
|
static uint8_t jp_xess_in()
|
{
|
{
|
uint8_t in;
|
uint8_t in;
|
|
|
in = jp_parallel_in();
|
in = jp_parallel_in();
|
|
|
if(in & 0x20) /* S5 pin 12*/
|
if(in & 0x20) /* S5 pin 12*/
|
return 1;
|
return 1;
|
return 0;
|
return 0;
|
}
|
}
|
|
|
/*-------------------------------------------[ rtl_sim specific functions ]---*/
|
/*-------------------------------------------[ rtl_sim specific functions ]---*/
|
static int jp_rtl_sim_init()
|
static int jp_rtl_sim_init()
|
{
|
{
|
FILE *fin = fopen (gdb_in, "wt+");
|
FILE *fin = fopen (gdb_in, "wt+");
|
if(!fin) {
|
if(!fin) {
|
fprintf(stderr, "Can not open %s\n", gdb_in);
|
fprintf(stderr, "Can not open %s\n", gdb_in);
|
return 0;
|
return 0;
|
}
|
}
|
fclose(fin);
|
fclose(fin);
|
return 1;
|
return 1;
|
}
|
}
|
|
|
static void jp_rtl_sim_out(uint8_t value)
|
static void jp_rtl_sim_out(uint8_t value)
|
{
|
{
|
FILE *fout;
|
FILE *fout;
|
int num_read;
|
int num_read;
|
int r;
|
int r;
|
fout = fopen(gdb_in, "wt+");
|
fout = fopen(gdb_in, "wt+");
|
fprintf(fout, "F\n");
|
fprintf(fout, "F\n");
|
fclose(fout);
|
fclose(fout);
|
fout = fopen(gdb_out, "wt+");
|
fout = fopen(gdb_out, "wt+");
|
fprintf(fout, "%02X\n", value);
|
fprintf(fout, "%02X\n", value);
|
fclose(fout);
|
fclose(fout);
|
do {
|
do {
|
fout = fopen(gdb_out, "rt");
|
fout = fopen(gdb_out, "rt");
|
r = fscanf(fout,"%x", &num_read);
|
r = fscanf(fout,"%x", &num_read);
|
fclose(fout);
|
fclose(fout);
|
} while(!r || (num_read != (0x10 | value)));
|
} while(!r || (num_read != (0x10 | value)));
|
}
|
}
|
|
|
static uint8_t jp_rtl_sim_in()
|
static uint8_t jp_rtl_sim_in()
|
{
|
{
|
FILE *fin = 0;
|
FILE *fin = 0;
|
char ch;
|
char ch;
|
uint8_t data;
|
uint8_t data;
|
while(1) {
|
while(1) {
|
fin = fopen(gdb_in, "rt");
|
fin = fopen(gdb_in, "rt");
|
if(!fin)
|
if(!fin)
|
continue;
|
continue;
|
ch = fgetc(fin);
|
ch = fgetc(fin);
|
fclose(fin);
|
fclose(fin);
|
if((ch != '0') && (ch != '1'))
|
if((ch != '0') && (ch != '1'))
|
continue;
|
continue;
|
else
|
else
|
break;
|
break;
|
}
|
}
|
data = ch == '1' ? 1 : 0;
|
data = ch == '1' ? 1 : 0;
|
return data;
|
return data;
|
}
|
}
|
|
|
static void jp_rtl_sim_wait()
|
static void jp_rtl_sim_wait()
|
{
|
{
|
usleep(1000);
|
usleep(1000);
|
}
|
}
|
|
|
static int jp_rtl_sim_opt(int c, char *str)
|
static int jp_rtl_sim_opt(int c, char *str)
|
{
|
{
|
switch(c) {
|
switch(c) {
|
case 'd':
|
case 'd':
|
if(!(gdb_in = malloc(strlen(str) + 12))) { /* 12 == strlen("gdb_in.dat") + 2 */
|
if(!(gdb_in = malloc(strlen(str) + 12))) { /* 12 == strlen("gdb_in.dat") + 2 */
|
fprintf(stderr, "Unable to allocate enough memory\n");
|
fprintf(stderr, "Unable to allocate enough memory\n");
|
return 0;
|
return 0;
|
}
|
}
|
if(!(gdb_out = malloc(strlen(str) + 13))) { /* 13 == strlen("gdb_out.dat") + 2 */
|
if(!(gdb_out = malloc(strlen(str) + 13))) { /* 13 == strlen("gdb_out.dat") + 2 */
|
fprintf(stderr, "Unable to allocate enough memory\n");
|
fprintf(stderr, "Unable to allocate enough memory\n");
|
free(gdb_in);
|
free(gdb_in);
|
return 0;
|
return 0;
|
}
|
}
|
|
|
sprintf(gdb_in, "%s/gdb_in.dat", str);
|
sprintf(gdb_in, "%s/gdb_in.dat", str);
|
sprintf(gdb_out, "%s/gdb_out.dat", str);
|
sprintf(gdb_out, "%s/gdb_out.dat", str);
|
break;
|
break;
|
default:
|
default:
|
fprintf(stderr, "Unknown parameter '%c'\n", c);
|
fprintf(stderr, "Unknown parameter '%c'\n", c);
|
return 0;
|
return 0;
|
}
|
}
|
return 1;
|
return 1;
|
}
|
}
|
|
|
/*-----------------------------------------------[ VPI specific functions ]---*/
|
/*-----------------------------------------------[ VPI specific functions ]---*/
|
static int jp_vpi_init()
|
static int jp_vpi_init()
|
{
|
{
|
struct sockaddr_un addr;
|
struct sockaddr_un addr;
|
|
|
if((vpi_comm = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) {
|
if((vpi_comm = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) {
|
fprintf(stderr, "Unable to create socket (%s)\n", strerror(errno));
|
fprintf(stderr, "Unable to create socket (%s)\n", strerror(errno));
|
return 0;
|
return 0;
|
}
|
}
|
|
|
addr.sun_family = AF_UNIX;
|
addr.sun_family = AF_UNIX;
|
strcpy(addr.sun_path, sock_loc);
|
strcpy(addr.sun_path, sock_loc);
|
|
|
if(connect(vpi_comm, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
|
if(connect(vpi_comm, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
|
fprintf(stderr, "Unable to connect to %s (%s)\n", addr.sun_path,
|
fprintf(stderr, "Unable to connect to %s (%s)\n", addr.sun_path,
|
strerror(errno));
|
strerror(errno));
|
return 0;
|
return 0;
|
}
|
}
|
return 1;
|
return 1;
|
}
|
}
|
|
|
static void jp_vpi_out(uint8_t value)
|
static void jp_vpi_out(uint8_t value)
|
{
|
{
|
uint8_t ack;
|
uint8_t ack;
|
|
|
/* Send the data to the socket */
|
/* Send the data to the socket */
|
write(vpi_comm, &value, 1);
|
write(vpi_comm, &value, 1);
|
|
|
do {
|
do {
|
/* Ok, read the data */
|
/* Ok, read the data */
|
read(vpi_comm, &ack, 1);
|
read(vpi_comm, &ack, 1);
|
} while(ack != (value | 0x10));
|
} while(ack != (value | 0x10));
|
}
|
}
|
|
|
static uint8_t jp_vpi_in()
|
static uint8_t jp_vpi_in()
|
{
|
{
|
uint8_t dat;
|
uint8_t dat;
|
|
|
/* ask vpi to send us the out-bit */
|
/* ask vpi to send us the out-bit */
|
dat = 0x80;
|
dat = 0x80;
|
write(vpi_comm, &dat, 1);
|
write(vpi_comm, &dat, 1);
|
|
|
/* Wait and read the data */
|
/* Wait and read the data */
|
read(vpi_comm, &dat, 1);
|
read(vpi_comm, &dat, 1);
|
|
|
if(dat > 1)
|
if(dat > 1)
|
fprintf(stderr, "Unexpected value: %i\n", dat);
|
fprintf(stderr, "Unexpected value: %i\n", dat);
|
|
|
return dat;
|
return dat;
|
}
|
}
|
|
|
static void jp_vpi_wait()
|
static void jp_vpi_wait()
|
{
|
{
|
uint8_t dat = 0x81;
|
uint8_t dat = 0x81;
|
|
|
/* Get the sim to reply when the timeout has been reached */
|
/* Get the sim to reply when the timeout has been reached */
|
write(vpi_comm, &dat, 1);
|
write(vpi_comm, &dat, 1);
|
|
|
/* block, waiting for the data */
|
/* block, waiting for the data */
|
read(vpi_comm, &dat, 1);
|
read(vpi_comm, &dat, 1);
|
}
|
}
|
|
|
static int jp_vpi_opt(int c, char *str)
|
static int jp_vpi_opt(int c, char *str)
|
{
|
{
|
switch(c) {
|
switch(c) {
|
case 's':
|
case 's':
|
if(!(sock_loc = strdup(str))) {
|
if(!(sock_loc = strdup(str))) {
|
fprintf(stderr, "Unable to allocate memory\n");
|
fprintf(stderr, "Unable to allocate memory\n");
|
return 0;
|
return 0;
|
}
|
}
|
break;
|
break;
|
default:
|
default:
|
fprintf(stderr, "Unknown parameter '%c'\n", c);
|
fprintf(stderr, "Unknown parameter '%c'\n", c);
|
return 0;
|
return 0;
|
}
|
}
|
return 1;
|
return 1;
|
}
|
}
|
|
|