dbp_sim.c 3.87 KB

/*************************************************************************
 *
 *  File: dbp_sim.c
 *
 *  Simulator debug port
 */
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <unistd.h>
#include <ctype.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <errno.h>
#include <time.h>
#include <sys/wait.h>
#include "dbp_sim.h"

int recv_pkt_from_sock(int fd, char *buf, int len)
{
    int nleft, nread;

    memset(buf, 0, len);
    nleft = len;

    while (nleft > 0) {
        nread = recv(fd, buf, nleft, 0);

        if (nread < 0) {
            printf("\n Failed: cannot read from socket");
            return -1;
        }
        nleft -= nread;
        buf += nread;
    }

    return 0;
}

int send_pkt_to_sock(int fd, char *buf, int len)
{
    int nleft, nwritten;

    nleft = len;
    while (nleft > 0) {
        nwritten = send(fd, buf, nleft, 0);

        if (nwritten < 0) {
            printf("\n Failed: cannot write to socket");
            return -1;
        }
        nleft -= nwritten;
        buf += nwritten;
    }

    return 0;
}

int keep_alive_sock(int fd, int alive)
{
    IpcPkt req;

    memset(&req, 0, sizeof(req));
    if (alive)
        req.code = htonl(OPEN_ALIVE_SOCKET);
    else
        req.code = htonl(CLOSE_ALIVE_SOCKET);

    send_pkt_to_sock(fd, (char *) &req, sizeof(req));
    recv_pkt_from_sock(fd, (char *) &req, sizeof(req));

    return 0;
}

int open_simulator_sock()
{
    int fd;
    struct sockaddr_in addr;
    int addrlen = sizeof(addr);
    char *server, *sport;
    int port, i;

    server = getenv("IOSIM_SERVER");
    sport = getenv("IOSIM_PORT");
    if (server == NULL || sport == NULL) {
        printf("\n PLEASE specify IOSIM_SERVER and IOSIM_port");
        return -1;
    }

    fd = socket(AF_INET, SOCK_STREAM, 0);
    if (fd < 0) return -1;

    port = strtoul(sport, NULL, 0);
    memset(&addr, 0, sizeof(addr));
    addr.sin_family = AF_INET;
    addr.sin_addr.s_addr = htonl(INADDR_ANY);
    addr.sin_port = htons(port);

    for (i=0; i<3; i++) {
        if (connect(fd, (struct sockaddr *)&addr, addrlen) < 0) {
            if (errno == ECONNREFUSED) {
                sleep(3);
                continue;       /* Try again */
            }
            close(fd);
            return -1;
        } else break;
    }

    /* Keep socket alive */
    keep_alive_sock(fd, 1);

    return fd;
}

int sim_jtag_write(int fd, int data)
{
    IpcPkt req, rsp;

    memset(&req, 0, sizeof(IpcPkt));
    memset(&rsp, 0, sizeof(IpcPkt));

    req.length = htonl(sizeof(IpcPkt));
    req.code   = htonl(BD_JTAG_WRITE);
    req.data[0] = htonl(data);

    send_pkt_to_sock(fd, (char *) &req, sizeof(req));
    recv_pkt_from_sock(fd, (char *) &rsp, sizeof(rsp));
	
    if ((ntohl(rsp.code) & 0x1ff) != RSP_OK) {
        fprintf(stderr, "Fatal error: write to JTAG Backdoor wrong!\n");
        return -1;
    }

    return 0;
}

int sim_jtag_read(int fd)
{
    IpcPkt req, rsp;

    memset(&req, 0, sizeof(IpcPkt));
    memset(&rsp, 0, sizeof(IpcPkt));

    req.length = htonl(sizeof(IpcPkt));
    req.code   = htonl(BD_JTAG_READ);

    send_pkt_to_sock(fd, (char *) &req, sizeof(req));
    recv_pkt_from_sock(fd, (char *) &rsp, sizeof(rsp));

    if ((ntohl(rsp.code) & 0x1ff) != RSP_OK) {
        fprintf(stderr, "Fatal error: read from JTAG Backdoor wrong!\n");
        return -1;
    }

    return htonl(rsp.data[0]);
}

int sim_jtag_stall(int fd, int cycles)
{
    IpcPkt req, rsp;

    memset(&req, 0, sizeof(IpcPkt));
    memset(&rsp, 0, sizeof(IpcPkt));

    req.length = htonl(sizeof(IpcPkt));
    req.code   = htonl(REQ_STALL);
    req.data[0] = htonl(cycles);

    send_pkt_to_sock(fd, (char *) &req, sizeof(req));
    recv_pkt_from_sock(fd, (char *) &rsp, sizeof(rsp));

    if ((ntohl(rsp.code) & 0x1ff) != RSP_OK) {
        fprintf(stderr, "Fatal error: BCP STALL!\n");
        return -1;
    }
    return 0;
}