📄 jp-io.c
字号:
/* jp-io.c -- Low level JTAG communications Copyright (C) 2001 Marko Mlinar, markom@opencores.org Copyright (C) 2004 Gy鰎gy Jeney, nog@sdf.lonestar.org Code for TCP/IP copied from gdb, by Chris ZiomkowskiThis file is part of OpenRISC 1000 Architectural Simulator.This program is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe 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 ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with this program; if not, write to the Free SoftwareFoundation, 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;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -