From 001d046948c9f3eb94f41cd1378486b5e1650cfc Mon Sep 17 00:00:00 2001 From: Rostislav Lisovy Date: Mon, 4 Apr 2011 19:46:54 +0200 Subject: [PATCH] Creating socket works. Reading/writing from/to socket works. Reconnecting of client doesn't work. Parsing of input still missing. --- src/qemu/hw/mf624.c | 131 +++++++++++++++++++++++++++++++------------- 1 file changed, 92 insertions(+), 39 deletions(-) diff --git a/src/qemu/hw/mf624.c b/src/qemu/hw/mf624.c index a4208ea..ea64861 100755 --- a/src/qemu/hw/mf624.c +++ b/src/qemu/hw/mf624.c @@ -6,6 +6,7 @@ */ #include "hw.h" #include "pci.h" +#include "../qemu-thread.c" #include #include #include @@ -142,28 +143,46 @@ void mf624_init_registers(mf624_state_t* s) } -void socket_write(const char* reg, unsigned int val) +void socket_write(mf624_state_t *s, const char* reg, unsigned int val) { - printf("%s=%x\n", reg, val); - + int status; + char write_buffer[256]; + snprintf(write_buffer, 255, "%s=%x\n", reg, val); + + status = write(s->socket_tmp, write_buffer, strlen(write_buffer)); + if (status < 0) { + //perror("write()"); + printf("Error writing into socket. Is there no client connected?\n"); + } } -void init_socket(mf624_state_t* dev) +void* init_socket(void* ptr) { + // Hmm, I dunno. Socket stuff, I guess; struct sockaddr_in addr_srv; struct sockaddr_in addr_client; int port = 55555; int yes = 1; + // For reading from socket + char read_buffer[256]; + int received_length = 0; + // For parsing read instructions + int reg; + int val; + + mf624_state_t* dev = (mf624_state_t*) ptr; + // If no client connected, we will know about it + dev->socket_tmp = -1; dev->socket_srv = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); if (dev->socket_srv == -1) { perror("socket()"); - return; + goto exit; } if (setsockopt(dev->socket_srv, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) { perror("setsockopt()"); - return; + goto exit; } @@ -174,24 +193,50 @@ void init_socket(mf624_state_t* dev) addr_srv.sin_port = htons(port); if(bind(dev->socket_srv, (struct sockaddr*) &addr_srv, len) == -1) { perror("bind()"); - return; + goto exit; } if (listen(dev->socket_srv, 5) == -1) { perror("listen()"); - return; + goto exit; } + printf("Waiting on port %d for MF624 client to connect\n", port); + + + socklen_t len_client = sizeof(addr_client); + dev->socket_tmp = accept(dev->socket_srv, (struct sockaddr*) &addr_client, &len_client); + if (dev->socket_tmp == -1) { + perror("accept()"); + goto exit; + } + + + memset(read_buffer, '\0', 256); while(1) { - socklen_t len_client = sizeof(addr_client); - dev->socket_tmp = accept(dev->socket_srv, (struct sockaddr*) &addr_client, &len_client); - if (dev->socket_tmp == -1) { - perror("accept()"); - continue; + //FIXME what if the socket was closed from client? We get no error message + received_length = read(dev->socket_tmp, read_buffer, 255); + if (received_length < 0) { + perror("read()"); + goto exit_close; + } + + if (received_length == 0) { + printf("Error while reading from socket. Client disconnected?\n"); + //FIXME For client it is not possible to reconnect + goto exit_close; } - //open(dev, ); - //close(dev->socket_tmp); + //printf("rec: [%s]\n", read_buffer); + //FIXME possible buffer overflow! + sscanf(read_buffer, "%u=%u", ®, &val); + printf("reg = %d; val = %d\n", reg, val); } + + +exit_close: + close(dev->socket_tmp); +exit: + return NULL; } //----------------------------------------------------------------------------- @@ -203,38 +248,38 @@ void mf624_BAR0_write32(void *opaque, target_phys_addr_t addr, uint32_t value) switch (addr % BAR0_size) { case INTCSR_off: s->BAR0.INTCSR = (value & 0x7FF) | INTCSR_default_value; // Only first 11 bits are writable - socket_write("INTCSR", s->BAR0.INTCSR); + socket_write(s, "INTCSR", s->BAR0.INTCSR); break; case GPIOC_off: //Don't write anywhere else than into these two bits s->BAR0.GPIOC = (value & (GPIOC_LDAC_mask | GPIOC_DACEN_mask)) | GPIOC_default_value; - socket_write("GPIOC", s->BAR0.GPIOC); + socket_write(s, "GPIOC", s->BAR0.GPIOC); //Is DAC enabled & Output enabled? if (!(s->BAR0.GPIOC & GPIOC_LDAC_mask) && (s->BAR0.GPIOC & GPIOC_DACEN_mask)) { - socket_write("DA0", s->BAR2.DA0); - socket_write("DA1", s->BAR2.DA1); - socket_write("DA2", s->BAR2.DA2); - socket_write("DA3", s->BAR2.DA3); - socket_write("DA4", s->BAR2.DA4); - socket_write("DA5", s->BAR2.DA5); - socket_write("DA6", s->BAR2.DA6); - socket_write("DA7", s->BAR2.DA7); + socket_write(s, "DA0", s->BAR2.DA0); + socket_write(s, "DA1", s->BAR2.DA1); + socket_write(s, "DA2", s->BAR2.DA2); + socket_write(s, "DA3", s->BAR2.DA3); + socket_write(s, "DA4", s->BAR2.DA4); + socket_write(s, "DA5", s->BAR2.DA5); + socket_write(s, "DA6", s->BAR2.DA6); + socket_write(s, "DA7", s->BAR2.DA7); } //Is output forced to GND? if (!(s->BAR0.GPIOC & GPIOC_DACEN_mask)) { #define GND 0 - socket_write("DA0", GND); - socket_write("DA1", GND); - socket_write("DA2", GND); - socket_write("DA3", GND); - socket_write("DA4", GND); - socket_write("DA5", GND); - socket_write("DA6", GND); - socket_write("DA7", GND); + socket_write(s, "DA0", GND); + socket_write(s, "DA1", GND); + socket_write(s, "DA2", GND); + socket_write(s, "DA3", GND); + socket_write(s, "DA4", GND); + socket_write(s, "DA5", GND); + socket_write(s, "DA6", GND); + socket_write(s, "DA7", GND); } break; @@ -252,8 +297,10 @@ uint32_t mf624_BAR0_read32(void *opaque, target_phys_addr_t addr) switch (addr % BAR0_size) { case INTCSR_off: return s->BAR0.INTCSR; + case GPIOC_off: return s->BAR0.GPIOC; + default: printf("mf624_BAR0_read32(): addr = %d\n", addr); return 0x0; @@ -317,27 +364,31 @@ void mf624_BAR2_write16(void *opaque, target_phys_addr_t addr, uint32_t value) switch (addr % BAR2_size) { case ADCTRL_off: s->BAR2.ADCTRL = value; - socket_write("ADCTRL", s->BAR2.ADCTRL); + socket_write(s, "ADCTRL", s->BAR2.ADCTRL); break; + case DOUT_off: s->BAR2.DOUT = value; - socket_write("DOUT", s->BAR2.DOUT); + socket_write(s, "DOUT", s->BAR2.DOUT); break; + case DA0_off: s->BAR2.DA0 = value; //Is DAC enabled & Output enabled? if (!(s->BAR0.GPIOC & GPIOC_LDAC_mask) && (s->BAR0.GPIOC & GPIOC_DACEN_mask)) { - socket_write("DA0", s->BAR2.DA0); + socket_write(s, "DA0", s->BAR2.DA0); } break; + case DA1_off: s->BAR2.DA1 = value; if (!(s->BAR0.GPIOC & GPIOC_LDAC_mask) && (s->BAR0.GPIOC & GPIOC_DACEN_mask)) { - socket_write("DA1", s->BAR2.DA1); + socket_write(s, "DA1", s->BAR2.DA1); } break; + default: printf("mf624_BAR2_write16(): addr = %d; value = %d\n", addr, value); break; @@ -423,6 +474,8 @@ static int pci_mf624_init(PCIDevice *pci_dev) { mf624_state_t *s = DO_UPCAST(mf624_state_t, dev, pci_dev); //alocation of mf624_state_t uint8_t *pci_conf; + QemuThread socket_thread; + mf624_init_registers(s); @@ -462,7 +515,7 @@ static int pci_mf624_init(PCIDevice *pci_dev) pci_register_bar(&s->dev, 2, BAR2_size, PCI_BASE_ADDRESS_SPACE_MEMORY, mf624_map); pci_register_bar(&s->dev, 4, BAR4_size, PCI_BASE_ADDRESS_SPACE_MEMORY, mf624_map); - //init_socket(s); + qemu_thread_create(&socket_thread, init_socket, (void*) s); return 0; } @@ -487,7 +540,7 @@ static PCIDeviceInfo mf624_info = { static void mf624_register_device(void) { - printf("Lets give it a go\n"); + printf("MF624 Loaded.\n"); pci_qdev_register(&mf624_info); } -- 2.39.2