• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Copyright (C) 2011 The Android Open Source Project
2 **
3 ** This software is licensed under the terms of the GNU General Public
4 ** License version 2, as published by the Free Software Foundation, and
5 ** may be copied, distributed, and modified under those terms.
6 **
7 ** This program is distributed in the hope that it will be useful,
8 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
9 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10 ** GNU General Public License for more details.
11 */
12 #include "android/utils/panic.h"
13 #include "android/utils/system.h"
14 #include "hw/goldfish_pipe.h"
15 #include "hw/goldfish_device.h"
16 #include "qemu-timer.h"
17 #ifdef CONFIG_KVM
18 #include "kvm.h"
19 #endif
20 
21 #define  DEBUG 0
22 
23 /* Set to 1 to debug i/o register reads/writes */
24 #define DEBUG_REGS  0
25 
26 #if DEBUG >= 1
27 #  define D(...)  fprintf(stderr, __VA_ARGS__), fprintf(stderr, "\n")
28 #else
29 #  define D(...)  (void)0
30 #endif
31 
32 #if DEBUG >= 2
33 #  define DD(...)  fprintf(stderr, __VA_ARGS__), fprintf(stderr, "\n")
34 #else
35 #  define DD(...)  (void)0
36 #endif
37 
38 #if DEBUG_REGS >= 1
39 #  define DR(...)   D(__VA_ARGS__)
40 #else
41 #  define DR(...)   (void)0
42 #endif
43 
44 #define E(...)  fprintf(stderr, "ERROR:" __VA_ARGS__), fprintf(stderr, "\n")
45 
46 /* Set to 1 to enable the 'zero' pipe type, useful for debugging */
47 #define DEBUG_ZERO_PIPE  1
48 
49 /* Set to 1 to enable the 'pingpong' pipe type, useful for debugging */
50 #define DEBUG_PINGPONG_PIPE 1
51 
52 /* Set to 1 to enable the 'throttle' pipe type, useful for debugging */
53 #define DEBUG_THROTTLE_PIPE 1
54 
55 /* Maximum length of pipe service name, in characters (excluding final 0) */
56 #define MAX_PIPE_SERVICE_NAME_SIZE  255
57 
58 #define GOLDFISH_PIPE_SAVE_VERSION  1
59 
60 /***********************************************************************
61  ***********************************************************************
62  *****
63  *****   P I P E   S E R V I C E   R E G I S T R A T I O N
64  *****
65  *****/
66 
67 #define MAX_PIPE_SERVICES  8
68 typedef struct {
69     const char*        name;
70     void*              opaque;
71     GoldfishPipeFuncs  funcs;
72 } PipeService;
73 
74 typedef struct {
75     int          count;
76     PipeService  services[MAX_PIPE_SERVICES];
77 } PipeServices;
78 
79 static PipeServices  _pipeServices[1];
80 
81 void
goldfish_pipe_add_type(const char * pipeName,void * pipeOpaque,const GoldfishPipeFuncs * pipeFuncs)82 goldfish_pipe_add_type(const char*               pipeName,
83                        void*                     pipeOpaque,
84                        const GoldfishPipeFuncs*  pipeFuncs )
85 {
86     PipeServices* list = _pipeServices;
87     int           count = list->count;
88 
89     if (count >= MAX_PIPE_SERVICES) {
90         APANIC("Too many goldfish pipe services (%d)", count);
91     }
92 
93     if (strlen(pipeName) > MAX_PIPE_SERVICE_NAME_SIZE) {
94         APANIC("Pipe service name too long: '%s'", pipeName);
95     }
96 
97     list->services[count].name   = pipeName;
98     list->services[count].opaque = pipeOpaque;
99     list->services[count].funcs  = pipeFuncs[0];
100 
101     list->count++;
102 }
103 
104 static const PipeService*
goldfish_pipe_find_type(const char * pipeName)105 goldfish_pipe_find_type(const char*  pipeName)
106 {
107     PipeServices* list = _pipeServices;
108     int           count = list->count;
109     int           nn;
110 
111     for (nn = 0; nn < count; nn++) {
112         if (!strcmp(list->services[nn].name, pipeName)) {
113             return &list->services[nn];
114         }
115     }
116     return NULL;
117 }
118 
119 
120 /***********************************************************************
121  ***********************************************************************
122  *****
123  *****    P I P E   C O N N E C T I O N S
124  *****
125  *****/
126 
127 typedef struct PipeDevice  PipeDevice;
128 
129 typedef struct Pipe {
130     struct Pipe*              next;
131     struct Pipe*              next_waked;
132     PipeDevice*                device;
133     uint32_t                   channel;
134     void*                      opaque;
135     const GoldfishPipeFuncs*   funcs;
136     const PipeService*         service;
137     char*                      args;
138     unsigned char              wanted;
139     char                       closed;
140 } Pipe;
141 
142 /* Forward */
143 static void*  pipeConnector_new(Pipe*  pipe);
144 
145 static Pipe*
pipe_new0(PipeDevice * dev)146 pipe_new0(PipeDevice* dev)
147 {
148     Pipe*  pipe;
149     ANEW0(pipe);
150     pipe->device = dev;
151     return pipe;
152 }
153 
154 static Pipe*
pipe_new(uint32_t channel,PipeDevice * dev)155 pipe_new(uint32_t channel, PipeDevice* dev)
156 {
157     Pipe*  pipe = pipe_new0(dev);
158     pipe->channel = channel;
159     pipe->opaque  = pipeConnector_new(pipe);
160     return pipe;
161 }
162 
163 static Pipe**
pipe_list_findp_channel(Pipe ** list,uint32_t channel)164 pipe_list_findp_channel( Pipe** list, uint32_t channel )
165 {
166     Pipe** pnode = list;
167     for (;;) {
168         Pipe* node = *pnode;
169         if (node == NULL || node->channel == channel) {
170             break;
171         }
172         pnode = &node->next;
173     }
174     return pnode;
175 }
176 
177 #if 0
178 static Pipe**
179 pipe_list_findp_opaque( Pipe** list, void* opaque )
180 {
181     Pipe** pnode = list;
182     for (;;) {
183         Pipe* node = *pnode;
184         if (node == NULL || node->opaque == opaque) {
185             break;
186         }
187         pnode = &node->next;
188     }
189     return pnode;
190 }
191 #endif
192 
193 static Pipe**
pipe_list_findp_waked(Pipe ** list,Pipe * pipe)194 pipe_list_findp_waked( Pipe** list, Pipe* pipe )
195 {
196     Pipe** pnode = list;
197     for (;;) {
198         Pipe* node = *pnode;
199         if (node == NULL || node == pipe) {
200             break;
201         }
202         pnode = &node->next_waked;
203     }
204     return pnode;
205 }
206 
207 
208 static void
pipe_list_remove_waked(Pipe ** list,Pipe * pipe)209 pipe_list_remove_waked( Pipe** list, Pipe*  pipe )
210 {
211     Pipe** lookup = pipe_list_findp_waked(list, pipe);
212     Pipe*  node   = *lookup;
213 
214     if (node != NULL) {
215         (*lookup) = node->next_waked;
216         node->next_waked = NULL;
217     }
218 }
219 
220 static void
pipe_save(Pipe * pipe,QEMUFile * file)221 pipe_save( Pipe* pipe, QEMUFile* file )
222 {
223     if (pipe->service == NULL) {
224         /* pipe->service == NULL means we're still using a PipeConnector */
225         /* Write a zero to indicate this condition */
226         qemu_put_byte(file, 0);
227     } else {
228         /* Otherwise, write a '1' then the service name */
229         qemu_put_byte(file, 1);
230         qemu_put_string(file, pipe->service->name);
231     }
232 
233     /* Now save other common data */
234     qemu_put_be32(file, (unsigned int)pipe->channel);
235     qemu_put_byte(file, (int)pipe->wanted);
236     qemu_put_byte(file, (int)pipe->closed);
237 
238     /* Write 1 + args, if any, or simply 0 otherwise */
239     if (pipe->args != NULL) {
240         qemu_put_byte(file, 1);
241         qemu_put_string(file, pipe->args);
242     } else {
243         qemu_put_byte(file, 0);
244     }
245 
246     if (pipe->funcs->save) {
247         pipe->funcs->save(pipe->opaque, file);
248     }
249 }
250 
251 static Pipe*
pipe_load(PipeDevice * dev,QEMUFile * file)252 pipe_load( PipeDevice* dev, QEMUFile* file )
253 {
254     Pipe*              pipe;
255     const PipeService* service = NULL;
256     int   state = qemu_get_byte(file);
257     uint32_t channel;
258 
259     if (state != 0) {
260         /* Pipe is associated with a service. */
261         char* name = qemu_get_string(file);
262         if (name == NULL)
263             return NULL;
264 
265         service = goldfish_pipe_find_type(name);
266         if (service == NULL) {
267             D("No QEMU pipe service named '%s'", name);
268             AFREE(name);
269             return NULL;
270         }
271     }
272 
273     channel = qemu_get_be32(file);
274     pipe = pipe_new(channel, dev);
275     pipe->wanted  = qemu_get_byte(file);
276     pipe->closed  = qemu_get_byte(file);
277     if (qemu_get_byte(file) != 0) {
278         pipe->args = qemu_get_string(file);
279     }
280 
281     pipe->service = service;
282     if (service != NULL) {
283         pipe->funcs = &service->funcs;
284     }
285 
286     if (pipe->funcs->load) {
287         pipe->opaque = pipe->funcs->load(pipe, service ? service->opaque : NULL, pipe->args, file);
288         if (pipe->opaque == NULL) {
289             AFREE(pipe);
290             return NULL;
291         }
292     } else {
293         /* Force-close the pipe on load */
294         pipe->closed = 1;
295     }
296     return pipe;
297 }
298 
299 static void
pipe_free(Pipe * pipe)300 pipe_free( Pipe* pipe )
301 {
302     /* Call close callback */
303     if (pipe->funcs->close) {
304         pipe->funcs->close(pipe->opaque);
305     }
306     /* Free stuff */
307     AFREE(pipe->args);
308     AFREE(pipe);
309 }
310 
311 /***********************************************************************
312  ***********************************************************************
313  *****
314  *****    P I P E   C O N N E C T O R S
315  *****
316  *****/
317 
318 /* These are used to handle the initial connection attempt, where the
319  * client is going to write the name of the pipe service it wants to
320  * connect to, followed by a terminating zero.
321  */
322 typedef struct {
323     Pipe*  pipe;
324     char   buffer[128];
325     int    buffpos;
326 } PipeConnector;
327 
328 static const GoldfishPipeFuncs  pipeConnector_funcs;  // forward
329 
330 void*
pipeConnector_new(Pipe * pipe)331 pipeConnector_new(Pipe*  pipe)
332 {
333     PipeConnector*  pcon;
334 
335     ANEW0(pcon);
336     pcon->pipe  = pipe;
337     pipe->funcs = &pipeConnector_funcs;
338     return pcon;
339 }
340 
341 static void
pipeConnector_close(void * opaque)342 pipeConnector_close( void* opaque )
343 {
344     PipeConnector*  pcon = opaque;
345     AFREE(pcon);
346 }
347 
348 static int
pipeConnector_sendBuffers(void * opaque,const GoldfishPipeBuffer * buffers,int numBuffers)349 pipeConnector_sendBuffers( void* opaque, const GoldfishPipeBuffer* buffers, int numBuffers )
350 {
351     PipeConnector* pcon = opaque;
352     const GoldfishPipeBuffer*  buffers_limit = buffers + numBuffers;
353     int ret = 0;
354 
355     DD("%s: channel=0x%x numBuffers=%d", __FUNCTION__,
356        pcon->pipe->channel,
357        numBuffers);
358 
359     while (buffers < buffers_limit) {
360         int  avail;
361 
362         DD("%s: buffer data (%3d bytes): '%.*s'", __FUNCTION__,
363            buffers[0].size, buffers[0].size, buffers[0].data);
364 
365         if (buffers[0].size == 0) {
366             buffers++;
367             continue;
368         }
369 
370         avail = sizeof(pcon->buffer) - pcon->buffpos;
371         if (avail > buffers[0].size)
372             avail = buffers[0].size;
373 
374         if (avail > 0) {
375             memcpy(pcon->buffer + pcon->buffpos, buffers[0].data, avail);
376             pcon->buffpos += avail;
377             ret += avail;
378         }
379         buffers++;
380     }
381 
382     /* Now check that our buffer contains a zero-terminated string */
383     if (memchr(pcon->buffer, '\0', pcon->buffpos) != NULL) {
384         /* Acceptable formats for the connection string are:
385          *
386          *   pipe:<name>
387          *   pipe:<name>:<arguments>
388          */
389         char* pipeName;
390         char* pipeArgs;
391 
392         D("%s: connector: '%s'", __FUNCTION__, pcon->buffer);
393 
394         if (memcmp(pcon->buffer, "pipe:", 5) != 0) {
395             /* Nope, we don't handle these for now. */
396             D("%s: Unknown pipe connection: '%s'", __FUNCTION__, pcon->buffer);
397             return PIPE_ERROR_INVAL;
398         }
399 
400         pipeName = pcon->buffer + 5;
401         pipeArgs = strchr(pipeName, ':');
402 
403         if (pipeArgs != NULL) {
404             *pipeArgs++ = '\0';
405             if (!*pipeArgs)
406                 pipeArgs = NULL;
407         }
408 
409         Pipe* pipe = pcon->pipe;
410         const PipeService* svc = goldfish_pipe_find_type(pipeName);
411         if (svc == NULL) {
412             D("%s: Unknown server!", __FUNCTION__);
413             return PIPE_ERROR_INVAL;
414         }
415 
416         void*  peer = svc->funcs.init(pipe, svc->opaque, pipeArgs);
417         if (peer == NULL) {
418             D("%s: Initialization failed!", __FUNCTION__);
419             return PIPE_ERROR_INVAL;
420         }
421 
422         /* Do the evil switch now */
423         pipe->opaque = peer;
424         pipe->service = svc;
425         pipe->funcs  = &svc->funcs;
426         pipe->args   = ASTRDUP(pipeArgs);
427         AFREE(pcon);
428     }
429 
430     return ret;
431 }
432 
433 static int
pipeConnector_recvBuffers(void * opaque,GoldfishPipeBuffer * buffers,int numBuffers)434 pipeConnector_recvBuffers( void* opaque, GoldfishPipeBuffer* buffers, int numBuffers )
435 {
436     return PIPE_ERROR_IO;
437 }
438 
439 static unsigned
pipeConnector_poll(void * opaque)440 pipeConnector_poll( void* opaque )
441 {
442     return PIPE_POLL_OUT;
443 }
444 
445 static void
pipeConnector_wakeOn(void * opaque,int flags)446 pipeConnector_wakeOn( void* opaque, int flags )
447 {
448     /* nothing, really should never happen */
449 }
450 
451 static void
pipeConnector_save(void * pipe,QEMUFile * file)452 pipeConnector_save( void* pipe, QEMUFile* file )
453 {
454     PipeConnector*  pcon = pipe;
455     qemu_put_sbe32(file, pcon->buffpos);
456     qemu_put_sbuffer(file, (const int8_t*)pcon->buffer, pcon->buffpos);
457 }
458 
459 static void*
pipeConnector_load(void * hwpipe,void * pipeOpaque,const char * args,QEMUFile * file)460 pipeConnector_load( void* hwpipe, void* pipeOpaque, const char* args, QEMUFile* file )
461 {
462     PipeConnector*  pcon;
463 
464     int len = qemu_get_sbe32(file);
465     if (len < 0 || len > sizeof(pcon->buffer)) {
466         return NULL;
467     }
468     pcon = pipeConnector_new(hwpipe);
469     pcon->buffpos = len;
470     if (qemu_get_buffer(file, (uint8_t*)pcon->buffer, pcon->buffpos) != pcon->buffpos) {
471         AFREE(pcon);
472         return NULL;
473     }
474     return pcon;
475 }
476 
477 static const GoldfishPipeFuncs  pipeConnector_funcs = {
478     NULL,  /* init */
479     pipeConnector_close,        /* should rarely happen */
480     pipeConnector_sendBuffers,  /* the interesting stuff */
481     pipeConnector_recvBuffers,  /* should not happen */
482     pipeConnector_poll,         /* should not happen */
483     pipeConnector_wakeOn,       /* should not happen */
484     pipeConnector_save,
485     pipeConnector_load,
486 };
487 
488 /***********************************************************************
489  ***********************************************************************
490  *****
491  *****    Z E R O   P I P E S
492  *****
493  *****/
494 
495 /* A simple pipe service that mimics /dev/zero, you can write anything to
496  * it, and you can always read any number of zeros from it. Useful for debugging
497  * the kernel driver.
498  */
499 #if DEBUG_ZERO_PIPE
500 
501 typedef struct {
502     void* hwpipe;
503 } ZeroPipe;
504 
505 static void*
zeroPipe_init(void * hwpipe,void * svcOpaque,const char * args)506 zeroPipe_init( void* hwpipe, void* svcOpaque, const char* args )
507 {
508     ZeroPipe*  zpipe;
509 
510     D("%s: hwpipe=%p", __FUNCTION__, hwpipe);
511     ANEW0(zpipe);
512     zpipe->hwpipe = hwpipe;
513     return zpipe;
514 }
515 
516 static void
zeroPipe_close(void * opaque)517 zeroPipe_close( void* opaque )
518 {
519     ZeroPipe*  zpipe = opaque;
520 
521     D("%s: hwpipe=%p", __FUNCTION__, zpipe->hwpipe);
522     AFREE(zpipe);
523 }
524 
525 static int
zeroPipe_sendBuffers(void * opaque,const GoldfishPipeBuffer * buffers,int numBuffers)526 zeroPipe_sendBuffers( void* opaque, const GoldfishPipeBuffer* buffers, int numBuffers )
527 {
528     int  ret = 0;
529     while (numBuffers > 0) {
530         ret += buffers[0].size;
531         buffers++;
532         numBuffers--;
533     }
534     return ret;
535 }
536 
537 static int
zeroPipe_recvBuffers(void * opaque,GoldfishPipeBuffer * buffers,int numBuffers)538 zeroPipe_recvBuffers( void* opaque, GoldfishPipeBuffer* buffers, int numBuffers )
539 {
540     int  ret = 0;
541     while (numBuffers > 0) {
542         ret += buffers[0].size;
543         memset(buffers[0].data, 0, buffers[0].size);
544         buffers++;
545         numBuffers--;
546     }
547     return ret;
548 }
549 
550 static unsigned
zeroPipe_poll(void * opaque)551 zeroPipe_poll( void* opaque )
552 {
553     return PIPE_POLL_IN | PIPE_POLL_OUT;
554 }
555 
556 static void
zeroPipe_wakeOn(void * opaque,int flags)557 zeroPipe_wakeOn( void* opaque, int flags )
558 {
559     /* nothing to do here */
560 }
561 
562 static const GoldfishPipeFuncs  zeroPipe_funcs = {
563     zeroPipe_init,
564     zeroPipe_close,
565     zeroPipe_sendBuffers,
566     zeroPipe_recvBuffers,
567     zeroPipe_poll,
568     zeroPipe_wakeOn,
569 };
570 
571 #endif /* DEBUG_ZERO */
572 
573 /***********************************************************************
574  ***********************************************************************
575  *****
576  *****    P I N G   P O N G   P I P E S
577  *****
578  *****/
579 
580 /* Similar debug service that sends back anything it receives */
581 /* All data is kept in a circular dynamic buffer */
582 
583 #if DEBUG_PINGPONG_PIPE
584 
585 /* Initial buffer size */
586 #define PINGPONG_SIZE  1024
587 
588 typedef struct {
589     void*     hwpipe;
590     uint8_t*  buffer;
591     size_t    size;
592     size_t    pos;
593     size_t    count;
594     unsigned  flags;
595 } PingPongPipe;
596 
597 static void
pingPongPipe_init0(PingPongPipe * pipe,void * hwpipe,void * svcOpaque)598 pingPongPipe_init0( PingPongPipe* pipe, void* hwpipe, void* svcOpaque )
599 {
600     pipe->hwpipe = hwpipe;
601     pipe->size = PINGPONG_SIZE;
602     pipe->buffer = malloc(pipe->size);
603     pipe->pos = 0;
604     pipe->count = 0;
605 }
606 
607 static void*
pingPongPipe_init(void * hwpipe,void * svcOpaque,const char * args)608 pingPongPipe_init( void* hwpipe, void* svcOpaque, const char* args )
609 {
610     PingPongPipe*  ppipe;
611 
612     D("%s: hwpipe=%p", __FUNCTION__, hwpipe);
613     ANEW0(ppipe);
614     pingPongPipe_init0(ppipe, hwpipe, svcOpaque);
615     return ppipe;
616 }
617 
618 static void
pingPongPipe_close(void * opaque)619 pingPongPipe_close( void* opaque )
620 {
621     PingPongPipe*  ppipe = opaque;
622 
623     D("%s: hwpipe=%p (pos=%d count=%d size=%d)", __FUNCTION__,
624       ppipe->hwpipe, ppipe->pos, ppipe->count, ppipe->size);
625     free(ppipe->buffer);
626     AFREE(ppipe);
627 }
628 
629 static int
pingPongPipe_sendBuffers(void * opaque,const GoldfishPipeBuffer * buffers,int numBuffers)630 pingPongPipe_sendBuffers( void* opaque, const GoldfishPipeBuffer* buffers, int numBuffers )
631 {
632     PingPongPipe*  pipe = opaque;
633     int  ret = 0;
634     int  count;
635     const GoldfishPipeBuffer* buff = buffers;
636     const GoldfishPipeBuffer* buffEnd = buff + numBuffers;
637 
638     count = 0;
639     for ( ; buff < buffEnd; buff++ )
640         count += buff->size;
641 
642     /* Do we need to grow the pingpong buffer? */
643     while (count > pipe->size - pipe->count) {
644         size_t    newsize = pipe->size*2;
645         uint8_t*  newbuff = realloc(pipe->buffer, newsize);
646         int       wpos    = pipe->pos + pipe->count;
647         if (newbuff == NULL) {
648             break;
649         }
650         if (wpos > pipe->size) {
651             wpos -= pipe->size;
652             memcpy(newbuff + pipe->size, newbuff, wpos);
653         }
654         pipe->buffer = newbuff;
655         pipe->size   = newsize;
656         D("pingpong buffer is now %d bytes", newsize);
657     }
658 
659     for ( buff = buffers; buff < buffEnd; buff++ ) {
660         int avail = pipe->size - pipe->count;
661         if (avail <= 0) {
662             if (ret == 0)
663                 ret = PIPE_ERROR_AGAIN;
664             break;
665         }
666         if (avail > buff->size) {
667             avail = buff->size;
668         }
669 
670         int wpos = pipe->pos + pipe->count;
671         if (wpos >= pipe->size) {
672             wpos -= pipe->size;
673         }
674         if (wpos + avail <= pipe->size) {
675             memcpy(pipe->buffer + wpos, buff->data, avail);
676         } else {
677             int  avail2 = pipe->size - wpos;
678             memcpy(pipe->buffer + wpos, buff->data, avail2);
679             memcpy(pipe->buffer, buff->data + avail2, avail - avail2);
680         }
681         pipe->count += avail;
682         ret += avail;
683     }
684 
685     /* Wake up any waiting readers if we wrote something */
686     if (pipe->count > 0 && (pipe->flags & PIPE_WAKE_READ)) {
687         goldfish_pipe_wake(pipe->hwpipe, PIPE_WAKE_READ);
688     }
689 
690     return ret;
691 }
692 
693 static int
pingPongPipe_recvBuffers(void * opaque,GoldfishPipeBuffer * buffers,int numBuffers)694 pingPongPipe_recvBuffers( void* opaque, GoldfishPipeBuffer* buffers, int numBuffers )
695 {
696     PingPongPipe*  pipe = opaque;
697     int  ret = 0;
698 
699     while (numBuffers > 0) {
700         int avail = pipe->count;
701         if (avail <= 0) {
702             if (ret == 0)
703                 ret = PIPE_ERROR_AGAIN;
704             break;
705         }
706         if (avail > buffers[0].size) {
707             avail = buffers[0].size;
708         }
709 
710         int rpos = pipe->pos;
711 
712         if (rpos + avail <= pipe->size) {
713             memcpy(buffers[0].data, pipe->buffer + rpos, avail);
714         } else {
715             int  avail2 = pipe->size - rpos;
716             memcpy(buffers[0].data, pipe->buffer + rpos, avail2);
717             memcpy(buffers[0].data + avail2, pipe->buffer, avail - avail2);
718         }
719         pipe->count -= avail;
720         pipe->pos   += avail;
721         if (pipe->pos >= pipe->size) {
722             pipe->pos -= pipe->size;
723         }
724         ret += avail;
725         numBuffers--;
726         buffers++;
727     }
728 
729     /* Wake up any waiting readers if we wrote something */
730     if (pipe->count < PINGPONG_SIZE && (pipe->flags & PIPE_WAKE_WRITE)) {
731         goldfish_pipe_wake(pipe->hwpipe, PIPE_WAKE_WRITE);
732     }
733 
734     return ret;
735 }
736 
737 static unsigned
pingPongPipe_poll(void * opaque)738 pingPongPipe_poll( void* opaque )
739 {
740     PingPongPipe*  pipe = opaque;
741     unsigned       ret = 0;
742 
743     if (pipe->count < pipe->size)
744         ret |= PIPE_POLL_OUT;
745 
746     if (pipe->count > 0)
747         ret |= PIPE_POLL_IN;
748 
749     return ret;
750 }
751 
752 static void
pingPongPipe_wakeOn(void * opaque,int flags)753 pingPongPipe_wakeOn( void* opaque, int flags )
754 {
755     PingPongPipe* pipe = opaque;
756     pipe->flags |= (unsigned)flags;
757 }
758 
759 static const GoldfishPipeFuncs  pingPongPipe_funcs = {
760     pingPongPipe_init,
761     pingPongPipe_close,
762     pingPongPipe_sendBuffers,
763     pingPongPipe_recvBuffers,
764     pingPongPipe_poll,
765     pingPongPipe_wakeOn,
766 };
767 
768 #endif /* DEBUG_PINGPONG_PIPE */
769 
770 /***********************************************************************
771  ***********************************************************************
772  *****
773  *****    T H R O T T L E   P I P E S
774  *****
775  *****/
776 
777 /* Similar to PingPongPipe, but will throttle the bandwidth to test
778  * blocking I/O.
779  */
780 
781 #ifdef DEBUG_THROTTLE_PIPE
782 
783 typedef struct {
784     PingPongPipe  pingpong;
785     double        sendRate;
786     int64_t       sendExpiration;
787     double        recvRate;
788     int64_t       recvExpiration;
789     QEMUTimer*    timer;
790 } ThrottlePipe;
791 
792 /* forward declaration */
793 static void throttlePipe_timerFunc( void* opaque );
794 
795 static void*
throttlePipe_init(void * hwpipe,void * svcOpaque,const char * args)796 throttlePipe_init( void* hwpipe, void* svcOpaque, const char* args )
797 {
798     ThrottlePipe* pipe;
799 
800     ANEW0(pipe);
801     pingPongPipe_init0(&pipe->pingpong, hwpipe, svcOpaque);
802     pipe->timer = qemu_new_timer_ns(vm_clock, throttlePipe_timerFunc, pipe);
803     /* For now, limit to 500 KB/s in both directions */
804     pipe->sendRate = 1e9 / (500*1024*8);
805     pipe->recvRate = pipe->sendRate;
806     return pipe;
807 }
808 
809 static void
throttlePipe_close(void * opaque)810 throttlePipe_close( void* opaque )
811 {
812     ThrottlePipe* pipe = opaque;
813 
814     qemu_del_timer(pipe->timer);
815     qemu_free_timer(pipe->timer);
816     pingPongPipe_close(&pipe->pingpong);
817 }
818 
819 static void
throttlePipe_rearm(ThrottlePipe * pipe)820 throttlePipe_rearm( ThrottlePipe* pipe )
821 {
822     int64_t  minExpiration = 0;
823 
824     DD("%s: sendExpiration=%lld recvExpiration=%lld\n", __FUNCTION__, pipe->sendExpiration, pipe->recvExpiration);
825 
826     if (pipe->sendExpiration) {
827         if (minExpiration == 0 || pipe->sendExpiration < minExpiration)
828             minExpiration = pipe->sendExpiration;
829     }
830 
831     if (pipe->recvExpiration) {
832         if (minExpiration == 0 || pipe->recvExpiration < minExpiration)
833             minExpiration = pipe->recvExpiration;
834     }
835 
836     if (minExpiration != 0) {
837         DD("%s: Arming for %lld\n", __FUNCTION__, minExpiration);
838         qemu_mod_timer(pipe->timer, minExpiration);
839     }
840 }
841 
842 static void
throttlePipe_timerFunc(void * opaque)843 throttlePipe_timerFunc( void* opaque )
844 {
845     ThrottlePipe* pipe = opaque;
846     int64_t  now = qemu_get_clock_ns(vm_clock);
847 
848     DD("%s: TICK! now=%lld sendExpiration=%lld recvExpiration=%lld\n",
849        __FUNCTION__, now, pipe->sendExpiration, pipe->recvExpiration);
850 
851     /* Timer has expired, signal wake up if needed */
852     int      flags = 0;
853 
854     if (pipe->sendExpiration && now > pipe->sendExpiration) {
855         flags |= PIPE_WAKE_WRITE;
856         pipe->sendExpiration = 0;
857     }
858     if (pipe->recvExpiration && now > pipe->recvExpiration) {
859         flags |= PIPE_WAKE_READ;
860         pipe->recvExpiration = 0;
861     }
862     flags &= pipe->pingpong.flags;
863     if (flags != 0) {
864         DD("%s: WAKE %d\n", __FUNCTION__, flags);
865         goldfish_pipe_wake(pipe->pingpong.hwpipe, flags);
866     }
867 
868     throttlePipe_rearm(pipe);
869 }
870 
871 static int
throttlePipe_sendBuffers(void * opaque,const GoldfishPipeBuffer * buffers,int numBuffers)872 throttlePipe_sendBuffers( void* opaque, const GoldfishPipeBuffer* buffers, int numBuffers )
873 {
874     ThrottlePipe*  pipe = opaque;
875     int            ret;
876 
877     if (pipe->sendExpiration > 0) {
878         return PIPE_ERROR_AGAIN;
879     }
880 
881     ret = pingPongPipe_sendBuffers(&pipe->pingpong, buffers, numBuffers);
882     if (ret > 0) {
883         /* Compute next send expiration time */
884         pipe->sendExpiration = qemu_get_clock_ns(vm_clock) + ret*pipe->sendRate;
885         throttlePipe_rearm(pipe);
886     }
887     return ret;
888 }
889 
890 static int
throttlePipe_recvBuffers(void * opaque,GoldfishPipeBuffer * buffers,int numBuffers)891 throttlePipe_recvBuffers( void* opaque, GoldfishPipeBuffer* buffers, int numBuffers )
892 {
893     ThrottlePipe* pipe = opaque;
894     int           ret;
895 
896     if (pipe->recvExpiration > 0) {
897         return PIPE_ERROR_AGAIN;
898     }
899 
900     ret = pingPongPipe_recvBuffers(&pipe->pingpong, buffers, numBuffers);
901     if (ret > 0) {
902         pipe->recvExpiration = qemu_get_clock_ns(vm_clock) + ret*pipe->recvRate;
903         throttlePipe_rearm(pipe);
904     }
905     return ret;
906 }
907 
908 static unsigned
throttlePipe_poll(void * opaque)909 throttlePipe_poll( void* opaque )
910 {
911     ThrottlePipe*  pipe = opaque;
912     unsigned       ret  = pingPongPipe_poll(&pipe->pingpong);
913 
914     if (pipe->sendExpiration > 0)
915         ret &= ~PIPE_POLL_OUT;
916 
917     if (pipe->recvExpiration > 0)
918         ret &= ~PIPE_POLL_IN;
919 
920     return ret;
921 }
922 
923 static void
throttlePipe_wakeOn(void * opaque,int flags)924 throttlePipe_wakeOn( void* opaque, int flags )
925 {
926     ThrottlePipe* pipe = opaque;
927     pingPongPipe_wakeOn(&pipe->pingpong, flags);
928 }
929 
930 static const GoldfishPipeFuncs  throttlePipe_funcs = {
931     throttlePipe_init,
932     throttlePipe_close,
933     throttlePipe_sendBuffers,
934     throttlePipe_recvBuffers,
935     throttlePipe_poll,
936     throttlePipe_wakeOn,
937 };
938 
939 #endif /* DEBUG_THROTTLE_PIPE */
940 
941 /***********************************************************************
942  ***********************************************************************
943  *****
944  *****    G O L D F I S H   P I P E   D E V I C E
945  *****
946  *****/
947 
948 struct PipeDevice {
949     struct goldfish_device dev;
950 
951     /* the list of all pipes */
952     Pipe*  pipes;
953 
954     /* the list of signalled pipes */
955     Pipe*  signaled_pipes;
956 
957     /* i/o registers */
958     uint32_t  address;
959     uint32_t  size;
960     uint32_t  status;
961     uint32_t  channel;
962     uint32_t  wakes;
963 };
964 
965 
966 static void
pipeDevice_doCommand(PipeDevice * dev,uint32_t command)967 pipeDevice_doCommand( PipeDevice* dev, uint32_t command )
968 {
969     Pipe** lookup = pipe_list_findp_channel(&dev->pipes, dev->channel);
970     Pipe*  pipe   = *lookup;
971     CPUState* env = cpu_single_env;
972 
973     /* Check that we're referring a known pipe channel */
974     if (command != PIPE_CMD_OPEN && pipe == NULL) {
975         dev->status = PIPE_ERROR_INVAL;
976         return;
977     }
978 
979     /* If the pipe is closed by the host, return an error */
980     if (pipe != NULL && pipe->closed && command != PIPE_CMD_CLOSE) {
981         dev->status = PIPE_ERROR_IO;
982         return;
983     }
984 
985     switch (command) {
986     case PIPE_CMD_OPEN:
987         DD("%s: CMD_OPEN channel=0x%x", __FUNCTION__, dev->channel);
988         if (pipe != NULL) {
989             dev->status = PIPE_ERROR_INVAL;
990             break;
991         }
992         pipe = pipe_new(dev->channel, dev);
993         pipe->next = dev->pipes;
994         dev->pipes = pipe;
995         dev->status = 0;
996         break;
997 
998     case PIPE_CMD_CLOSE:
999         DD("%s: CMD_CLOSE channel=0x%x", __FUNCTION__, dev->channel);
1000         /* Remove from device's lists */
1001         *lookup = pipe->next;
1002         pipe->next = NULL;
1003         pipe_list_remove_waked(&dev->signaled_pipes, pipe);
1004         pipe_free(pipe);
1005         break;
1006 
1007     case PIPE_CMD_POLL:
1008         dev->status = pipe->funcs->poll(pipe->opaque);
1009         DD("%s: CMD_POLL > status=%d", __FUNCTION__, dev->status);
1010         break;
1011 
1012     case PIPE_CMD_READ_BUFFER: {
1013         /* Translate virtual address into physical one, into emulator memory. */
1014         GoldfishPipeBuffer  buffer;
1015         uint32_t            address = dev->address;
1016         uint32_t            page    = address & TARGET_PAGE_MASK;
1017         target_phys_addr_t  phys;
1018 #ifdef CONFIG_KVM
1019         if(kvm_enabled()) {
1020             cpu_synchronize_state(env, 0);
1021         }
1022 #endif
1023         phys = cpu_get_phys_page_debug(env, page);
1024         buffer.data = qemu_get_ram_ptr(phys) + (address - page);
1025         buffer.size = dev->size;
1026         dev->status = pipe->funcs->recvBuffers(pipe->opaque, &buffer, 1);
1027         DD("%s: CMD_READ_BUFFER channel=0x%x address=0x%08x size=%d > status=%d",
1028            __FUNCTION__, dev->channel, dev->address, dev->size, dev->status);
1029         break;
1030     }
1031 
1032     case PIPE_CMD_WRITE_BUFFER: {
1033         /* Translate virtual address into physical one, into emulator memory. */
1034         GoldfishPipeBuffer  buffer;
1035         uint32_t            address = dev->address;
1036         uint32_t            page    = address & TARGET_PAGE_MASK;
1037         target_phys_addr_t  phys;
1038 #ifdef CONFIG_KVM
1039         if(kvm_enabled()) {
1040             cpu_synchronize_state(env, 0);
1041         }
1042 #endif
1043         phys = cpu_get_phys_page_debug(env, page);
1044         buffer.data = qemu_get_ram_ptr(phys) + (address - page);
1045         buffer.size = dev->size;
1046         dev->status = pipe->funcs->sendBuffers(pipe->opaque, &buffer, 1);
1047         DD("%s: CMD_WRITE_BUFFER channel=0x%x address=0x%08x size=%d > status=%d",
1048            __FUNCTION__, dev->channel, dev->address, dev->size, dev->status);
1049         break;
1050     }
1051 
1052     case PIPE_CMD_WAKE_ON_READ:
1053         DD("%s: CMD_WAKE_ON_READ channel=0x%x", __FUNCTION__, dev->channel);
1054         if ((pipe->wanted & PIPE_WAKE_READ) == 0) {
1055             pipe->wanted |= PIPE_WAKE_READ;
1056             pipe->funcs->wakeOn(pipe->opaque, pipe->wanted);
1057         }
1058         dev->status = 0;
1059         break;
1060 
1061     case PIPE_CMD_WAKE_ON_WRITE:
1062         DD("%s: CMD_WAKE_ON_WRITE channel=0x%x", __FUNCTION__, dev->channel);
1063         if ((pipe->wanted & PIPE_WAKE_WRITE) == 0) {
1064             pipe->wanted |= PIPE_WAKE_WRITE;
1065             pipe->funcs->wakeOn(pipe->opaque, pipe->wanted);
1066         }
1067         dev->status = 0;
1068         break;
1069 
1070     default:
1071         D("%s: command=%d (0x%x)\n", __FUNCTION__, command, command);
1072     }
1073 }
1074 
pipe_dev_write(void * opaque,target_phys_addr_t offset,uint32_t value)1075 static void pipe_dev_write(void *opaque, target_phys_addr_t offset, uint32_t value)
1076 {
1077     PipeDevice *s = (PipeDevice *)opaque;
1078 
1079     switch (offset) {
1080     case PIPE_REG_COMMAND:
1081         DR("%s: command=%d (0x%x)", __FUNCTION__, value, value);
1082         pipeDevice_doCommand(s, value);
1083         break;
1084 
1085     case PIPE_REG_SIZE:
1086         DR("%s: size=%d (0x%x)", __FUNCTION__, value, value);
1087         s->size = value;
1088         break;
1089 
1090     case PIPE_REG_ADDRESS:
1091         DR("%s: address=%d (0x%x)", __FUNCTION__, value, value);
1092         s->address = value;
1093         break;
1094 
1095     case PIPE_REG_CHANNEL:
1096         DR("%s: channel=%d (0x%x)", __FUNCTION__, value, value);
1097         s->channel = value;
1098         break;
1099 
1100     default:
1101         D("%s: offset=%d (0x%x) value=%d (0x%x)\n", __FUNCTION__, offset,
1102             offset, value, value);
1103         break;
1104     }
1105 }
1106 
1107 /* I/O read */
pipe_dev_read(void * opaque,target_phys_addr_t offset)1108 static uint32_t pipe_dev_read(void *opaque, target_phys_addr_t offset)
1109 {
1110     PipeDevice *dev = (PipeDevice *)opaque;
1111 
1112     switch (offset) {
1113     case PIPE_REG_STATUS:
1114         DR("%s: REG_STATUS status=%d (0x%x)", __FUNCTION__, dev->status, dev->status);
1115         return dev->status;
1116 
1117     case PIPE_REG_CHANNEL:
1118         if (dev->signaled_pipes != NULL) {
1119             Pipe* pipe = dev->signaled_pipes;
1120             DR("%s: channel=0x%x wanted=%d", __FUNCTION__,
1121                pipe->channel, pipe->wanted);
1122             dev->wakes = pipe->wanted;
1123             pipe->wanted = 0;
1124             dev->signaled_pipes = pipe->next_waked;
1125             pipe->next_waked = NULL;
1126             if (dev->signaled_pipes == NULL) {
1127                 goldfish_device_set_irq(&dev->dev, 0, 0);
1128                 DD("%s: lowering IRQ", __FUNCTION__);
1129             }
1130             return pipe->channel;
1131         }
1132         DR("%s: no signaled channels", __FUNCTION__);
1133         return 0;
1134 
1135     case PIPE_REG_WAKES:
1136         DR("%s: wakes %d", __FUNCTION__, dev->wakes);
1137         return dev->wakes;
1138 
1139     default:
1140         D("%s: offset=%d (0x%x)\n", __FUNCTION__, offset, offset);
1141     }
1142     return 0;
1143 }
1144 
1145 static CPUReadMemoryFunc *pipe_dev_readfn[] = {
1146    pipe_dev_read,
1147    pipe_dev_read,
1148    pipe_dev_read
1149 };
1150 
1151 static CPUWriteMemoryFunc *pipe_dev_writefn[] = {
1152    pipe_dev_write,
1153    pipe_dev_write,
1154    pipe_dev_write
1155 };
1156 
1157 static void
goldfish_pipe_save(QEMUFile * file,void * opaque)1158 goldfish_pipe_save( QEMUFile* file, void* opaque )
1159 {
1160     PipeDevice* dev = opaque;
1161     Pipe* pipe;
1162 
1163     qemu_put_be32(file, dev->address);
1164     qemu_put_be32(file, dev->size);
1165     qemu_put_be32(file, dev->status);
1166     qemu_put_be32(file, dev->channel);
1167     qemu_put_be32(file, dev->wakes);
1168 
1169     /* Count the number of pipe connections */
1170     int count = 0;
1171     for ( pipe = dev->pipes; pipe; pipe = pipe->next )
1172         count++;
1173 
1174     qemu_put_sbe32(file, count);
1175 
1176     /* Now save each pipe one after the other */
1177     for ( pipe = dev->pipes; pipe; pipe = pipe->next ) {
1178         pipe_save(pipe, file);
1179     }
1180 }
1181 
1182 static int
goldfish_pipe_load(QEMUFile * file,void * opaque,int version_id)1183 goldfish_pipe_load( QEMUFile* file, void* opaque, int version_id )
1184 {
1185     PipeDevice* dev = opaque;
1186     Pipe*       pipe;
1187 
1188     if (version_id != GOLDFISH_PIPE_SAVE_VERSION)
1189         return -EINVAL;
1190 
1191     dev->address = qemu_get_be32(file);
1192     dev->size    = qemu_get_be32(file);
1193     dev->status  = qemu_get_be32(file);
1194     dev->channel = qemu_get_be32(file);
1195     dev->wakes   = qemu_get_be32(file);
1196 
1197     /* Count the number of pipe connections */
1198     int count = qemu_get_sbe32(file);
1199 
1200     /* Load all pipe connections */
1201     for ( ; count > 0; count-- ) {
1202         pipe = pipe_load(dev, file);
1203         if (pipe == NULL) {
1204             return -EIO;
1205         }
1206         pipe->next = dev->pipes;
1207         dev->pipes = pipe;
1208     }
1209 
1210     /* Now we need to wake/close all relevant pipes */
1211     for ( pipe = dev->pipes; pipe; pipe = pipe->next ) {
1212         if (pipe->wanted != 0)
1213             goldfish_pipe_wake(pipe, pipe->wanted);
1214         if (pipe->closed != 0)
1215             goldfish_pipe_close(pipe);
1216     }
1217     return 0;
1218 }
1219 
1220 /* initialize the trace device */
pipe_dev_init()1221 void pipe_dev_init()
1222 {
1223     PipeDevice *s;
1224 
1225     s = (PipeDevice *) qemu_mallocz(sizeof(*s));
1226 
1227     s->dev.name = "qemu_pipe";
1228     s->dev.id = -1;
1229     s->dev.base = 0;       // will be allocated dynamically
1230     s->dev.size = 0x2000;
1231     s->dev.irq = 0;
1232     s->dev.irq_count = 1;
1233 
1234     goldfish_device_add(&s->dev, pipe_dev_readfn, pipe_dev_writefn, s);
1235 
1236     register_savevm( "goldfish_pipe", 0, GOLDFISH_PIPE_SAVE_VERSION,
1237                       goldfish_pipe_save, goldfish_pipe_load, s);
1238 
1239 #if DEBUG_ZERO_PIPE
1240     goldfish_pipe_add_type("zero", NULL, &zeroPipe_funcs);
1241 #endif
1242 #if DEBUG_PINGPONG_PIPE
1243     goldfish_pipe_add_type("pingpong", NULL, &pingPongPipe_funcs);
1244 #endif
1245 #if DEBUG_THROTTLE_PIPE
1246     goldfish_pipe_add_type("throttle", NULL, &throttlePipe_funcs);
1247 #endif
1248 }
1249 
1250 void
goldfish_pipe_wake(void * hwpipe,unsigned flags)1251 goldfish_pipe_wake( void* hwpipe, unsigned flags )
1252 {
1253     Pipe*  pipe = hwpipe;
1254     Pipe** lookup;
1255     PipeDevice*  dev = pipe->device;
1256 
1257     DD("%s: channel=0x%x flags=%d", __FUNCTION__, pipe->channel, flags);
1258 
1259     /* If not already there, add to the list of signaled pipes */
1260     lookup = pipe_list_findp_waked(&dev->signaled_pipes, pipe);
1261     if (!*lookup) {
1262         pipe->next_waked = dev->signaled_pipes;
1263         dev->signaled_pipes = pipe;
1264     }
1265     pipe->wanted |= (unsigned)flags;
1266 
1267     /* Raise IRQ to indicate there are items on our list ! */
1268     goldfish_device_set_irq(&dev->dev, 0, 1);
1269     DD("%s: raising IRQ", __FUNCTION__);
1270 }
1271 
1272 void
goldfish_pipe_close(void * hwpipe)1273 goldfish_pipe_close( void* hwpipe )
1274 {
1275     Pipe* pipe = hwpipe;
1276 
1277     D("%s: channel=0x%x (closed=%d)", __FUNCTION__, pipe->channel, pipe->closed);
1278 
1279     if (!pipe->closed) {
1280         pipe->closed = 1;
1281         goldfish_pipe_wake( hwpipe, PIPE_WAKE_CLOSED );
1282     }
1283 }
1284