]> rtime.felk.cvut.cz Git - mf6xx.git/blob - src/qemu/hw/mf624.c
621e4bf4a0c51ff91a209d8a0a7992029f8f6d4f
[mf6xx.git] / src / qemu / hw / mf624.c
1 /* 
2  * Humusoft MF624 DAQ card implementation
3  * 
4  * Copyright (C) 2011 Rostislav Lisovy (lisovy@gmail.com)
5  * 
6  * Licensed under GPLv2 license
7  */
8 #include "hw.h"
9 #include "pci.h"
10 #include "../qemu-thread.c"
11 #include <string.h>
12 #include <unistd.h>
13 #include <sys/types.h> 
14 #include <sys/socket.h>
15 #include <netinet/in.h>
16 #include <sys/socket.h>
17
18 #define PCI_VENDOR_ID_HUMUSOFT          0x186c
19 #define PCI_DEVICE_ID_MF624             0x0624
20 #define PCI_CLASS_SIGNAL_PROCESSING_CONTROLLER  0x1180
21
22
23 #define BAR0_size                       32
24 #define BAR2_size                       128
25 #define BAR4_size                       128
26
27 /* BAR0 */
28 #define INTCSR_off                      0x4C
29 #define GPIOC_off                       0x54
30
31 /* BAR2 */ 
32 #define ADDATA_off                      0x00
33 #define ADCTRL_off                      0x00
34 #define ADDATA1_off                     0x02
35 #define ADDATA2_off                     0x04
36 #define ADDATA3_off                     0x06
37 #define ADDATA4_off                     0x08
38 #define ADDATA5_off                     0x0A
39 #define ADDATA6_off                     0x0C
40 #define ADDATA7_off                     0x0E
41 #define DOUT_off                        0x10
42 #define DIN_off                         0x10
43 #define ADSTART_off                     0x20
44 #define DA0_off                         0x20
45 #define DA1_off                         0x22
46 #define DA2_off                         0x24
47 #define DA3_off                         0x26
48 #define DA4_off                         0x28
49 #define DA5_off                         0x2A
50 #define DA6_off                         0x2C
51 #define DA7_off                         0x2E
52
53 #define GPIOC_EOLC_mask                 (1 << 17)
54 #define GPIOC_LDAC_mask                 (1 << 23)
55 #define GPIOC_DACEN_mask                (1 << 26)
56
57
58 typedef struct {
59         uint32_t INTCSR;
60         uint32_t GPIOC;
61 } BAR0_t;
62
63 typedef struct {
64         uint16_t ADDATA;
65         uint16_t ADCTRL;
66         uint16_t ADDATA1;
67         uint16_t ADDATA2;
68         uint16_t ADDATA3;
69         uint16_t ADDATA4;
70         uint16_t ADDATA5;
71         uint16_t ADDATA6;
72         uint16_t ADDATA7;
73         uint16_t DIN;
74         uint16_t DOUT;
75         uint16_t DA0;
76         uint16_t DA1;
77         uint16_t DA2;
78         uint16_t DA3;
79         uint16_t DA4;
80         uint16_t DA5;
81         uint16_t DA6;
82         uint16_t DA7;
83 } BAR2_t;
84
85 /* Not implemented */
86 typedef struct {
87 //      uint32_t CTR0STATUS;
88 //      uint32_t CTR0MODE;
89 //      uint32_t CTR0;
90 //      uint32_t CTR0A;
91 //      ...
92 } BAR4_t;
93
94 typedef struct {
95         PCIDevice dev;
96
97         int socket_srv;
98         int socket_tmp;
99         uint32_t port;
100         int addr;
101
102          /* The real voltage which is on inputs od A/D convertors.
103         Until new conversion is started, there is still old value in ADC registers*/    
104         unsigned int real_world_AD0; //Value in "ADC internal" format
105         unsigned int real_world_AD1;
106         unsigned int real_world_AD2;
107         unsigned int real_world_AD3;
108         unsigned int real_world_AD4;
109         unsigned int real_world_AD5;
110         unsigned int real_world_AD6;
111         unsigned int real_world_AD7;
112
113         // for cpu_register_physical_memory() function
114         unsigned int BAR0_mem_table_index;
115         unsigned int BAR2_mem_table_index;
116         unsigned int BAR4_mem_table_index;
117         
118         // Internal registers values
119         BAR0_t BAR0;
120         BAR2_t BAR2;
121         BAR4_t BAR4;
122
123         int ADDATA_FIFO[8]; //this array tells us which ADCs are being converted        
124         unsigned int ADDATA_FIFO_POSITION; //ADDATA is FIFO register; 
125                                 //We need to know, position in this FIFO =
126                                 //Which value will come next
127 } mf624_state_t;
128
129 int instance = 0; // Global variable shared between multiple mf624 devices
130
131
132 static int16_t volts_to_adinternal(double volt)
133 {
134         if (volt > 9.99) {
135                 volt = 9.99;
136         }
137         else if (volt < -10) {
138                 volt = -10;
139         }
140
141         return ((int16_t) ((volt*0x8000)/10))>>2;
142 }
143
144 static double dacinternal_to_volts(int16_t dacinternal)
145 {
146         return ((((double)dacinternal)/0x4000)*20.0 - 10.0);
147 }
148
149 //-----------------------------------------------------------------------------
150
151 /* Initialize register values due to MF624 manual */
152 static void mf624_init_registers(mf624_state_t* s)
153 {
154 #define INTCSR_default_value            0x000300
155 #define GPIOC_default_value             0x006C0 | (0x10 << 21) | (2 << 25)
156
157         //Initialize all registers to default values
158         s->BAR0.INTCSR = INTCSR_default_value;
159         s->BAR0.GPIOC = GPIOC_default_value; 
160         s->BAR2.ADDATA = 0x0;
161         s->BAR2.ADCTRL = 0x0;
162         s->BAR2.ADDATA1 = 0x0;
163         s->BAR2.ADDATA2 = 0x0;
164         s->BAR2.ADDATA3 = 0x0;
165         s->BAR2.ADDATA4 = 0x0;
166         s->BAR2.ADDATA5 = 0x0;
167         s->BAR2.ADDATA6 = 0x0;
168         s->BAR2.ADDATA7 = 0x0;
169
170         s->BAR2.DIN = 0xFF;
171         s->BAR2.DOUT = 0x00;
172         s->BAR2.DA0 = 0x3FFF;
173         s->BAR2.DA1 = 0x3FFF;
174         s->BAR2.DA2 = 0x3FFF;
175         s->BAR2.DA3 = 0x3FFF;
176         s->BAR2.DA4 = 0x3FFF;
177         s->BAR2.DA5 = 0x3FFF;
178         s->BAR2.DA6 = 0x3FFF;
179         s->BAR2.DA7 = 0x3FFF;
180
181         s->ADDATA_FIFO_POSITION = 0;
182 }
183
184 /* After some widget's value is changed, new value is send via socket to Qemu */
185 static void socket_write(mf624_state_t *s, const char* reg, double val)
186 {
187         int status;
188         char write_buffer[256];
189         snprintf(write_buffer, 255, "%s=%f\n", reg, val);
190
191         status = write(s->socket_tmp, write_buffer, strlen(write_buffer));
192         if (status < 0) {
193                 //perror("write()");
194                 printf("Error writing into socket. Is there no client connected?\n");
195         }
196 }
197
198 #define STRING_BUFF_SIZE        256
199 static void socket_read(mf624_state_t* dev)
200 {
201         // For parsing read instructions
202         char reg[STRING_BUFF_SIZE+1];
203         float val;
204         // For reading from socket
205         char read_buffer[STRING_BUFF_SIZE];
206         int received_length = 0;
207         int status;
208
209
210         while(1) {
211                 memset(read_buffer, '\0', STRING_BUFF_SIZE);
212                 received_length = read(dev->socket_tmp, read_buffer, STRING_BUFF_SIZE-1);
213                 if (received_length < 0) {
214                         perror("read()");
215                         return;
216                 }
217                 
218                 if (received_length == 0) {
219                         printf("Error while reading from socket. Client disconnected?\n");
220                         return;
221                 }
222
223                 // REG has "same size +1" as READ_BUFFER to avoid buffer overflow
224                 status = sscanf(read_buffer, "%[A-Z0-9]=%f", reg, &val);
225                 if (status == 2) {
226                         if(!strcmp(reg, "DIN")) {
227                                 dev->BAR2.DIN = val;
228                         }
229                         else if(!strcmp(reg, "ADC0")) {
230                                 dev->real_world_AD0 = volts_to_adinternal(val);
231                         }
232                         else if(!strcmp(reg, "ADC1")) {
233                                 dev->real_world_AD1 = volts_to_adinternal(val);
234                         }
235                         else if(!strcmp(reg, "ADC2")) {
236                                 dev->real_world_AD2 = volts_to_adinternal(val);
237                         }
238                         else if(!strcmp(reg, "ADC3")) {
239                                 dev->real_world_AD3 = volts_to_adinternal(val);
240                         }
241                         else if(!strcmp(reg, "ADC4")) {
242                                 dev->real_world_AD4 = volts_to_adinternal(val);
243                         }
244                         else if(!strcmp(reg, "ADC5")) {
245                                 dev->real_world_AD5 = volts_to_adinternal(val);
246                         }
247                         else if(!strcmp(reg, "ADC6")) {
248                                 dev->real_world_AD6 = volts_to_adinternal(val);
249                         }
250                         else if(!strcmp(reg, "ADC7")) {
251                                 dev->real_world_AD7 = volts_to_adinternal(val);
252                         }
253                         else {
254                                 printf("reg = %s; val = %f\n", reg, val);
255                         } 
256                 }
257         }
258 }
259
260
261 static void* init_socket(void* ptr)
262 {
263         struct sockaddr_in addr_client;
264         struct sockaddr_in addr_srv;
265         int port;
266         int yes = 1;
267         
268         mf624_state_t* dev = (mf624_state_t*) ptr;
269
270         dev->socket_tmp = -1;
271         port = dev->port;
272
273         dev->socket_srv = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
274         if (dev->socket_srv == -1) {
275                 perror("socket()");
276                 return NULL;
277         }
278         
279         if (setsockopt(dev->socket_srv, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) {
280                 perror("setsockopt()");
281                 return NULL;
282         }
283
284
285         socklen_t len = sizeof(addr_srv);
286         memset(&addr_srv, 0, len);
287         addr_srv.sin_family = AF_INET;
288         addr_srv.sin_addr.s_addr = htonl(INADDR_ANY);
289         addr_srv.sin_port = htons(port);
290         if(bind(dev->socket_srv, (struct sockaddr*) &addr_srv, len) == -1) {
291                 perror("bind()");
292                 return NULL;
293         }
294         
295         if (listen(dev->socket_srv, 5) == -1) {
296                 perror("listen()");
297                 return NULL;
298         }
299
300
301         while(1) {
302                 printf("Waiting on port %d for MF624 client to connect\n", dev->port);
303                 socklen_t len_client = sizeof(addr_client);
304                 dev->socket_tmp = accept(dev->socket_srv, (struct sockaddr*) &addr_client, &len_client);
305                 if (dev->socket_tmp == -1) {
306                         perror("accept()");
307                 }
308
309                 printf("Client connected\n");
310         
311                 socket_read(dev); // should run forever if everything is OK; 
312                                 // If error occurs (client disconnected), returns here
313                 
314                 close(dev->socket_tmp);
315         }
316
317         return NULL;
318 }
319
320 //-----------------------------------------------------------------------------
321
322 static void mf624_BAR0_write32(void *opaque, target_phys_addr_t addr, uint32_t value)
323 {
324         mf624_state_t *s = opaque;
325
326         switch (addr % BAR0_size) {
327                 case INTCSR_off:
328                         s->BAR0.INTCSR = (value & 0x7FF) | INTCSR_default_value; // Only first 11 bits are writable
329                         socket_write(s, "INTCSR", s->BAR0.INTCSR);
330                         break;
331                         
332                 case GPIOC_off:
333                         //Don't write anywhere else than into these two bits
334                         s->BAR0.GPIOC = (value & (GPIOC_LDAC_mask | GPIOC_DACEN_mask)) | GPIOC_default_value;
335                         socket_write(s, "GPIOC", s->BAR0.GPIOC);
336
337                         //Is DAC enabled & Output enabled?
338                         if (!(s->BAR0.GPIOC & GPIOC_LDAC_mask) &&
339                                 (s->BAR0.GPIOC & GPIOC_DACEN_mask)) {
340                                 socket_write(s, "DA0", dacinternal_to_volts(s->BAR2.DA0));
341                                 socket_write(s, "DA1", dacinternal_to_volts(s->BAR2.DA1));
342                                 socket_write(s, "DA2", dacinternal_to_volts(s->BAR2.DA2));
343                                 socket_write(s, "DA3", dacinternal_to_volts(s->BAR2.DA3));
344                                 socket_write(s, "DA4", dacinternal_to_volts(s->BAR2.DA4));
345                                 socket_write(s, "DA5", dacinternal_to_volts(s->BAR2.DA5));
346                                 socket_write(s, "DA6", dacinternal_to_volts(s->BAR2.DA6));
347                                 socket_write(s, "DA7", dacinternal_to_volts(s->BAR2.DA7));
348                         }
349                         
350                         //Is output forced to GND?
351                         if (!(s->BAR0.GPIOC & GPIOC_DACEN_mask))
352                         {
353                                 #define GND     0
354                                 socket_write(s, "DA0", dacinternal_to_volts(GND));
355                                 socket_write(s, "DA1", dacinternal_to_volts(GND));
356                                 socket_write(s, "DA2", dacinternal_to_volts(GND));
357                                 socket_write(s, "DA3", dacinternal_to_volts(GND));
358                                 socket_write(s, "DA4", dacinternal_to_volts(GND));
359                                 socket_write(s, "DA5", dacinternal_to_volts(GND));
360                                 socket_write(s, "DA6", dacinternal_to_volts(GND));
361                                 socket_write(s, "DA7", dacinternal_to_volts(GND));
362                         }
363                         break;
364                         
365                 default:
366                         printf("mf624_BAR0_write32(): addr = %d; value = %d\n", addr, value);
367                         break;
368         }
369 }
370
371
372 static uint32_t mf624_BAR0_read32(void *opaque, target_phys_addr_t addr)
373 {
374         mf624_state_t *s = opaque;
375
376         switch (addr % BAR0_size) {
377                 case INTCSR_off:
378                         return s->BAR0.INTCSR;
379
380                 case GPIOC_off:
381                         return s->BAR0.GPIOC;
382
383                 default:
384                         printf("mf624_BAR0_read32(): addr = %d\n", addr);
385                         return 0x0;
386         }
387 }
388
389
390 static uint32_t mf624_BAR2_read16(void *opaque, target_phys_addr_t addr)
391 {
392         int i;
393         int ADDATA_val = 0xFFFF;
394         mf624_state_t *s = opaque;
395
396         switch (addr % BAR2_size) {
397                 /* Reading from ADDATA FIFO register */
398                 case ADDATA_off:
399                 case ADDATA1_off: // Mirrored registers
400                 case ADDATA2_off:
401                 case ADDATA3_off:
402                 case ADDATA4_off:
403                 case ADDATA5_off:
404                 case ADDATA6_off:
405                 case ADDATA7_off:
406                         if (!(s->BAR0.GPIOC & GPIOC_EOLC_mask)) { //Has the conversion already ended?
407                                 #define ADC_CHANNELS    8
408                                 for(i = s->ADDATA_FIFO_POSITION; i < ADC_CHANNELS; i ++) {
409                                         if (s->BAR2.ADCTRL & (1 << i)) {
410                                                 s->ADDATA_FIFO_POSITION = i; // Move to next AD to be read
411                                         }
412                                 }
413                                 
414                                 switch (s->ADDATA_FIFO_POSITION)
415                                 {
416                                         case 0:
417                                                 ADDATA_val = s->BAR2.ADDATA;
418                                                 break;
419                                         case 1:
420                                                 ADDATA_val = s->BAR2.ADDATA1;
421                                                 break;
422                                         case 2:
423                                                 ADDATA_val = s->BAR2.ADDATA2;
424                                                 break;
425                                         case 3:
426                                                 ADDATA_val = s->BAR2.ADDATA3;
427                                                 break;
428                                         case 4:
429                                                 ADDATA_val = s->BAR2.ADDATA4;
430                                                 break;
431                                         case 5:
432                                                 ADDATA_val = s->BAR2.ADDATA5;
433                                                 break;
434                                         case 6:
435                                                 ADDATA_val = s->BAR2.ADDATA6;
436                                                 break;
437                                         case 7:
438                                                 ADDATA_val = s->BAR2.ADDATA7;
439                                                 break;
440                                         default: // restart counter
441                                                 s->ADDATA_FIFO_POSITION = 0;
442                                                 ADDATA_val = s->BAR2.ADDATA;
443                                                 break;
444                                 }
445                                 s->ADDATA_FIFO_POSITION ++;
446                                 return ADDATA_val;
447                         }
448                         return 0xFFFF; // Semirandom value
449
450                 /* Digital Input*/
451                 case DIN_off:
452                         return s->BAR2.DIN;
453
454                 /* A/D Conversion Start. Reading this register triggers A/D
455                 conversion for all channels selected in ADCTRL. */
456                 case ADSTART_off:
457                         s->BAR0.GPIOC |= GPIOC_EOLC_mask; // Conversion in progress
458                         s->ADDATA_FIFO_POSITION = 0;
459                         for (i = 0; i < 5000; i++) 
460                                 ; // Small delay simulating real conversion
461
462                         // Check before assignement, if particular ADC is enabled
463                         s->BAR2.ADDATA  = (s->BAR2.ADCTRL & (1 << 0)) ? s->real_world_AD0 : s->BAR2.ADDATA;
464                         s->BAR2.ADDATA1 = (s->BAR2.ADCTRL & (1 << 1)) ? s->real_world_AD1 : s->BAR2.ADDATA1;
465                         s->BAR2.ADDATA2 = (s->BAR2.ADCTRL & (1 << 2)) ? s->real_world_AD2 : s->BAR2.ADDATA2;
466                         s->BAR2.ADDATA3 = (s->BAR2.ADCTRL & (1 << 3)) ? s->real_world_AD3 : s->BAR2.ADDATA3;
467                         s->BAR2.ADDATA4 = (s->BAR2.ADCTRL & (1 << 4)) ? s->real_world_AD4 : s->BAR2.ADDATA4;
468                         s->BAR2.ADDATA5 = (s->BAR2.ADCTRL & (1 << 5)) ? s->real_world_AD5 : s->BAR2.ADDATA5;
469                         s->BAR2.ADDATA6 = (s->BAR2.ADCTRL & (1 << 6)) ? s->real_world_AD6 : s->BAR2.ADDATA6;
470                         s->BAR2.ADDATA7 = (s->BAR2.ADCTRL & (1 << 7)) ? s->real_world_AD7 : s->BAR2.ADDATA7;
471                         
472                         //All channels converted
473                         s->BAR0.GPIOC &= ~ GPIOC_EOLC_mask;
474                         
475                         return 0xFFFF; // Semirandom value
476
477                 default:
478                         printf("mf624_BAR2_read16(): addr = %d\n", addr);
479                         return 0x0;
480         }
481 }
482
483
484 static void mf624_BAR2_write16(void *opaque, target_phys_addr_t addr, uint32_t value)
485 {
486         mf624_state_t *s = opaque;
487
488         switch (addr % BAR2_size) {
489                 case ADCTRL_off:
490                         s->BAR2.ADCTRL = value;
491                         socket_write(s, "ADCTRL", s->BAR2.ADCTRL);
492                         break;
493
494                 case DOUT_off:
495                         s->BAR2.DOUT = value;
496                         socket_write(s, "DOUT", s->BAR2.DOUT);
497                         break;
498
499                 case DA0_off:
500                         s->BAR2.DA0 = value;
501                         //Is DAC enabled & Output enabled?
502                         if (!(s->BAR0.GPIOC & GPIOC_LDAC_mask) &&
503                                 (s->BAR0.GPIOC & GPIOC_DACEN_mask)) {
504                                 socket_write(s, "DA0", dacinternal_to_volts(s->BAR2.DA0));
505                         }
506                         break;
507
508                 case DA1_off:
509                         s->BAR2.DA1 = value;
510                         if (!(s->BAR0.GPIOC & GPIOC_LDAC_mask) && 
511                                 (s->BAR0.GPIOC & GPIOC_DACEN_mask)) {
512                                 socket_write(s, "DA1", dacinternal_to_volts(s->BAR2.DA1));
513                         }
514                         break;
515
516                 case DA2_off:
517                         s->BAR2.DA2 = value;
518                         if (!(s->BAR0.GPIOC & GPIOC_LDAC_mask) && 
519                                 (s->BAR0.GPIOC & GPIOC_DACEN_mask)) {
520                                 socket_write(s, "DA2", dacinternal_to_volts(s->BAR2.DA2));
521                         }
522                         break;
523
524                 case DA3_off:
525                         s->BAR2.DA3 = value;
526                         if (!(s->BAR0.GPIOC & GPIOC_LDAC_mask) && 
527                                 (s->BAR0.GPIOC & GPIOC_DACEN_mask)) {
528                                 socket_write(s, "DA3", dacinternal_to_volts(s->BAR2.DA3));
529                         }
530                         break;
531
532                 case DA4_off:
533                         s->BAR2.DA4 = value;
534                         if (!(s->BAR0.GPIOC & GPIOC_LDAC_mask) && 
535                                 (s->BAR0.GPIOC & GPIOC_DACEN_mask)) {
536                                 socket_write(s, "DA4", dacinternal_to_volts(s->BAR2.DA4));
537                         }
538                         break;
539
540                 case DA5_off:
541                         s->BAR2.DA5 = value;
542                         if (!(s->BAR0.GPIOC & GPIOC_LDAC_mask) && 
543                                 (s->BAR0.GPIOC & GPIOC_DACEN_mask)) {
544                                 socket_write(s, "DA5", dacinternal_to_volts(s->BAR2.DA5));
545                         }
546                         break;
547
548                 case DA6_off:
549                         s->BAR2.DA6 = value;
550                         if (!(s->BAR0.GPIOC & GPIOC_LDAC_mask) && 
551                                 (s->BAR0.GPIOC & GPIOC_DACEN_mask)) {
552                                 socket_write(s, "DA6", dacinternal_to_volts(s->BAR2.DA6));
553                         }
554                         break;
555
556                 case DA7_off:
557                         s->BAR2.DA7 = value;
558                         if (!(s->BAR0.GPIOC & GPIOC_LDAC_mask) && 
559                                 (s->BAR0.GPIOC & GPIOC_DACEN_mask)) {
560                                 socket_write(s, "DA7", dacinternal_to_volts(s->BAR2.DA7));
561                         }
562                         break;
563
564                 default:
565                         printf("mf624_BAR2_write16(): addr = %d; value = %d\n", addr, value);
566                         break;
567         }
568 }
569
570
571 static void mf624_BAR4_write32(void *opaque, target_phys_addr_t addr, uint32_t value)
572 {
573         printf("mf624_BAR4_write32(): addr = %d; value = %d\n", addr, value);
574 }
575
576 static uint32_t mf624_BAR4_read32(void *opaque, target_phys_addr_t addr)
577 {
578         printf("mf624_BAR4_read32(): addr = %d\n", addr);
579         return 0x0;
580 }
581
582
583 static CPUReadMemoryFunc * const mf624_BAR0_read[3] = {
584         NULL, /* read8 */
585         NULL, /* read16 */
586         mf624_BAR0_read32,
587 };
588  
589 static CPUWriteMemoryFunc * const mf624_BAR0_write[3] = {
590         NULL, /* write8 */
591         NULL, /* write16 */
592         mf624_BAR0_write32,
593 };
594
595 static CPUReadMemoryFunc * const mf624_BAR2_read[3] = {
596         NULL, /* read8 */
597         mf624_BAR2_read16,
598         NULL, /* read32 */
599 };
600  
601 static CPUWriteMemoryFunc * const mf624_BAR2_write[3] = {
602         NULL, /* write8 */
603         mf624_BAR2_write16,
604         NULL, /* write32 */
605 };
606
607 static CPUReadMemoryFunc * const mf624_BAR4_read[3] = {
608         NULL, /* read8 */
609         NULL, /* read16 */
610         mf624_BAR4_read32,
611 };
612  
613 static CPUWriteMemoryFunc * const mf624_BAR4_write[3] = {
614         NULL, /* write8 */
615         NULL, /* write16 */
616         mf624_BAR4_write32,
617 };
618 //-----------------------------------------------------------------------------
619         
620 static void mf624_map(PCIDevice *pci_dev, int region_num,
621                        pcibus_t addr, pcibus_t size, int type)
622 {
623         mf624_state_t *s = DO_UPCAST(mf624_state_t, dev, pci_dev);
624
625         switch (region_num) {
626                 case 0:
627                         //printf("reg%d, addr = %x\n", region_num, addr);
628                         cpu_register_physical_memory(addr + 0x0, BAR0_size, s->BAR0_mem_table_index);
629                         break;
630                 case 2:
631                         //printf("reg%d, addr = %x\n", region_num, addr);
632                         cpu_register_physical_memory(addr + 0x0, BAR2_size, s->BAR2_mem_table_index);
633                         break;
634                 case 4:
635                         //printf("reg%d, addr = %x\n", region_num, addr);
636                         cpu_register_physical_memory(addr + 0x0, BAR4_size, s->BAR4_mem_table_index);
637                         break;
638                 default:
639                         printf("FFFUUU\n");
640         }
641
642 }
643
644 #define DEFAULT_PORT                    55555
645 static int pci_mf624_init(PCIDevice *pci_dev)
646 {
647         mf624_state_t *s = DO_UPCAST(mf624_state_t, dev, pci_dev); //alocation of mf624_state_t
648         uint8_t *pci_conf;
649         QemuThread socket_thread;
650
651         printf("MF624 Loaded.\n");
652
653         if (s->port == DEFAULT_PORT) {
654                 s->port += instance; // Each instance of the same device should have another port number
655                 instance ++;
656         }
657
658         //Set all internal registers to default values
659         mf624_init_registers(s);
660
661         pci_conf = s->dev.config;
662         pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_HUMUSOFT);
663         pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_MF624);
664         pci_config_set_class(pci_conf, PCI_CLASS_SIGNAL_PROCESSING_CONTROLLER);
665         pci_conf[PCI_SUBSYSTEM_VENDOR_ID] = PCI_VENDOR_ID_HUMUSOFT & 0xff;
666         pci_conf[PCI_SUBSYSTEM_VENDOR_ID + 1] = PCI_VENDOR_ID_HUMUSOFT >> 8;
667         pci_conf[PCI_SUBSYSTEM_ID] = PCI_DEVICE_ID_MF624 & 0xff;
668         pci_conf[PCI_SUBSYSTEM_ID + 1] = PCI_DEVICE_ID_MF624 >> 8;
669
670         pci_conf[PCI_INTERRUPT_PIN] = 0x1; // interrupt pin 0
671
672
673         s->BAR0_mem_table_index = cpu_register_io_memory(mf624_BAR0_read,
674                                                  mf624_BAR0_write,
675                                                  s,
676                                                  DEVICE_NATIVE_ENDIAN);
677
678         s->BAR2_mem_table_index = cpu_register_io_memory(mf624_BAR2_read,
679                                                  mf624_BAR2_write,
680                                                  s,
681                                                  DEVICE_NATIVE_ENDIAN);
682
683         s->BAR4_mem_table_index = cpu_register_io_memory(mf624_BAR4_read,
684                                                  mf624_BAR4_write,
685                                                  s,
686                                                  DEVICE_NATIVE_ENDIAN);
687
688         //printf("BAR0: %d\n", s->BAR0_offset);
689         //printf("BAR2: %d\n", s->BAR2_offset);
690         //printf("BAR4: %d\n", s->BAR4_offset);
691
692         pci_register_bar(&s->dev, 0, BAR0_size, PCI_BASE_ADDRESS_SPACE_MEMORY, mf624_map);
693         pci_register_bar(&s->dev, 2, BAR2_size, PCI_BASE_ADDRESS_SPACE_MEMORY, mf624_map);
694         pci_register_bar(&s->dev, 4, BAR4_size, PCI_BASE_ADDRESS_SPACE_MEMORY, mf624_map);
695
696         //Create thread, which will be blocked on reading from socket (connected to "I/O GUI")
697         qemu_thread_create(&socket_thread, init_socket, (void*) s);
698         return 0;
699 }
700
701 static int pci_mf624_exit(PCIDevice *pci_dev)
702 {
703         mf624_state_t *s = DO_UPCAST(mf624_state_t, dev, pci_dev);
704         close(s->socket_srv);
705
706         return 0;
707 }
708
709
710 static PCIDeviceInfo mf624_info = {
711         .qdev.name  = "mf624",
712         .qdev.size  = sizeof(mf624_state_t),
713         .init       = pci_mf624_init,
714         .exit       = pci_mf624_exit,
715         .qdev.props = (Property[]) {
716                 DEFINE_PROP_UINT32("port", mf624_state_t, port, DEFAULT_PORT),
717                 DEFINE_PROP_END_OF_LIST(),
718         }
719 };
720
721 static void mf624_register_device(void)
722 {
723         pci_qdev_register(&mf624_info);
724 }
725
726 device_init(mf624_register_device)