Hi all,
I write a new device that is connect via socket to a host program that emulate a small memory.
I can correctly write in this "memory" but sometimes, when I want to read, the recv() socket function give me an error (-1 return).

Do you know if there is a socket problem with qemu? Because I tried to write a host program that make the same thing but I didn't get any errors.

I don't know if it is usefull but I attach my written module ( scmem.c).

Thanks,
Ale
#include "vl.h"
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <signal.h>
#include <netdb.h>
#include <string.h>
#include <fcntl.h>
#include <stdlib.h>

#define DATA 0xbfe00520
#define COMM 0xbfe00530
#define ADDR 0xbfe00510
#define CONTROL 0xbfe00500

//#define SCDEBUG

struct sockaddr_in myaddr_in;	// for local socket address
struct sockaddr_in peeraddr_in;	// for peer socket address
int theSocket;					// socket descriptor
struct hostent *hp;				// pointer to host info
struct servent *sp;				// pointer to service information

void scmem_restore();

typedef struct {
	unsigned int type;
	unsigned int address;
	unsigned int length;
	unsigned long long MemElem;
	unsigned long long MemElem1;
} sc_message_type_t;

sc_message_type_t msg;

struct scmemState {
    uint32_t data;
    uint32_t addr;
    uint32_t control;
    uint32_t comm;

    int irq;
    int irq_pending;
    CharDriverState *chr;
    int hw_driver;
};

//Data exchange
 uint32 cosim(int op, int addr, int data) {
  msg.type=op;
  #ifdef SCDEBUG
  printf("msg.type= %d\n",msg.type);
  #endif

  msg.address=addr;
  #ifdef SCDEBUG
  printf("msg.addr= %x\n",msg.address);
  #endif

  if (addr == CONTROL) {
    msg.length=1;
  } else { 
      if (addr == DATA && op == 0) {
        msg.length=0;
      } 
    else msg.length=sizeof(msg.address);
 }
  #ifdef SCDEBUG
  printf("msg.length= %x\n",msg.length);
  #endif

  msg.MemElem=data;
  usleep(250000);
  if(send(theSocket,&msg,sizeof(sc_message_type_t),MSG_OOB) == -1) perror("TcpWrite ERROR\n");
  usleep(250000);
  if(recv(theSocket,&msg,sizeof(sc_message_type_t),0) == -1) perror("TcpRead ERROR\n");
  usleep(250000);

  #ifdef SCDEBUG
  printf("msg.MemElem= %d\n",msg.MemElem);
  #endif

  return msg.MemElem;
}

/*
static void scmem_update_irq(scmemState *s)
{
    if (s->irq_pending)
        pic_set_irq(s->irq, 1);
    else
        pic_set_irq(s->irq, 0);
}
*/
static uint32_t scmem_ioport_read(void *opaque, uint32_t addr) {
	scmemState *s = opaque;
	uint32_t ret= 0xff;
	
	addr &= 7;
	switch(addr) {
	case 0:
		if(s->hw_driver) {

			s->data = cosim(0,DATA,0);
			#ifdef SCDEBUG
			printf("Reading at 0x738 (data reg) value= %d\n",s->data);
			#endif
		}
		ret = s->data;
		break;
	case 1:
		if(s->hw_driver) {

			s->addr = cosim(0,ADDR,0);
			#ifdef SCDEBUG			
			printf("Reading at 0x739 (addr reg) value= %d\n",s->addr);
			#endif
		}
		ret = s->addr;
		break;
	case 2:
		if(s->hw_driver) {

			s->control = cosim(0,CONTROL,0);
			#ifdef SCDEBUG	
			printf("Reading at 0x74a (control reg) value= %d\n",s->control);
			#endif
		}
		ret = s->control;
		break;
	case 3:
		if(s->hw_driver) {

			s->comm = cosim(0,COMM,0);
			#ifdef SCDEBUG	
			printf("Reading at 0x74b (comm reg) value= %d\n",s->comm);
			#endif
		}
		ret = s->comm;
		break;
	}
	
    return ret;
}

static void scmem_ioport_write(void *opaque, uint32_t addr, uint32_t val) {
	scmemState *s = opaque;
	addr &= 7;
	switch(addr) {
	case 0:
		if(s->hw_driver) {

			cosim(1,DATA,val);
			s->data = val;
			#ifdef SCDEBUG
			printf("Writing at 0x738 (data reg) value= %d\n",val);
			#endif
		}
		break;
	case 1:
		if(s->hw_driver) {
			cosim(1,ADDR,val);
			s->addr = val;
			#ifdef SCDEBUG	
			printf("Writing at 0x739 (addr reg) value= %d\n",val);
			#endif
		}
		break;
	case 2:
		if(s->hw_driver) {
			cosim(1,CONTROL,val);
			s->control = val;
			#ifdef SCDEBUG	
			printf("Writing at 0x74a (control reg) value= %d\n",val);
			#endif
		}
		break;
	case 3:
		if(s->hw_driver) {
			if (val == 0x0003) { //SC socket connection restore
				scmem_restore();
			} else {
				cosim(1,COMM,val);
				s->comm = val;
				#ifdef SCDEBUG	
				printf("Writing at 0x74b (comm reg) value= %d\n",val);
				#endif
			}
		}
		break;
	}
	
}

scmemState *scmem_init(int base, int irq, CharDriverState *chr){
	scmemState *s;

	s=qemu_mallocz(sizeof(scmemState));
	s->chr = chr;
	s->hw_driver = 1;
	s->irq = irq;
	s->data = 0;
	s->addr = 0; //correct?
	s->control = 0; //correct?
	
	//wrapper init
	memset ((char *)&peeraddr_in, 0, sizeof(struct sockaddr_in));
	hp=gethostbyname("127.0.0.1");
	peeraddr_in.sin_family = AF_INET;
	peeraddr_in.sin_addr.s_addr=((struct in_addr *)(hp->h_addr))->s_addr;
	peeraddr_in.sin_port=htons(4449);
	if((theSocket=socket(AF_INET,SOCK_STREAM,0))==-1) {
	  printf("Errore creazione socket\n");
	}
	if (connect(theSocket,(struct sockaddr *)&peeraddr_in,sizeof(struct sockaddr_in))==-1) {
		printf("Errore nella connessione del socket \n");
	} else {
	printf("Socket creato \n");
	}


	register_ioport_read(base, 8, 1, scmem_ioport_read, s);
	register_ioport_write(base, 8, 1, scmem_ioport_write, s);
    return s;
}



//SC socket connection restore WARNING: must reactivate sc program first!
void scmem_restore() {
	memset ((char *)&peeraddr_in, 0, sizeof(struct sockaddr_in));
	hp=gethostbyname("127.0.0.1");
	peeraddr_in.sin_family =AF_INET;
	peeraddr_in.sin_addr.s_addr=((struct in_addr *)(hp->h_addr))->s_addr;
	peeraddr_in.sin_port=htons(4449);
	theSocket=socket(AF_INET,SOCK_STREAM,0);
	if (connect(theSocket,(struct sockaddr *)&peeraddr_in,sizeof(struct sockaddr_in))==-1) {
		printf("Errore nella creazione del socket \n");;
	} else {
	printf("Socket creato \n");
	}
}
_______________________________________________
Qemu-devel mailing list
Qemu-devel@nongnu.org
http://lists.nongnu.org/mailman/listinfo/qemu-devel

Reply via email to