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  2
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
68typedef struct {
69    const char*        name;
70    void*              opaque;
71    GoldfishPipeFuncs  funcs;
72} PipeService;
73
74typedef struct {
75    int          count;
76    PipeService  services[MAX_PIPE_SERVICES];
77} PipeServices;
78
79static PipeServices  _pipeServices[1];
80
81void
82goldfish_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
104static const PipeService*
105goldfish_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
127typedef struct PipeDevice  PipeDevice;
128
129typedef 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 */
143static void*  pipeConnector_new(Pipe*  pipe);
144
145static Pipe*
146pipe_new0(PipeDevice* dev)
147{
148    Pipe*  pipe;
149    ANEW0(pipe);
150    pipe->device = dev;
151    return pipe;
152}
153
154static Pipe*
155pipe_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
163static Pipe**
164pipe_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
178static Pipe**
179pipe_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
193static Pipe**
194pipe_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
208static void
209pipe_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
220static void
221pipe_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
251static Pipe*
252pipe_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
299static void
300pipe_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 */
322typedef struct {
323    Pipe*  pipe;
324    char   buffer[128];
325    int    buffpos;
326} PipeConnector;
327
328static const GoldfishPipeFuncs  pipeConnector_funcs;  // forward
329
330void*
331pipeConnector_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
341static void
342pipeConnector_close( void* opaque )
343{
344    PipeConnector*  pcon = opaque;
345    AFREE(pcon);
346}
347
348static int
349pipeConnector_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
433static int
434pipeConnector_recvBuffers( void* opaque, GoldfishPipeBuffer* buffers, int numBuffers )
435{
436    return PIPE_ERROR_IO;
437}
438
439static unsigned
440pipeConnector_poll( void* opaque )
441{
442    return PIPE_POLL_OUT;
443}
444
445static void
446pipeConnector_wakeOn( void* opaque, int flags )
447{
448    /* nothing, really should never happen */
449}
450
451static void
452pipeConnector_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
459static void*
460pipeConnector_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
477static 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
501typedef struct {
502    void* hwpipe;
503} ZeroPipe;
504
505static void*
506zeroPipe_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
516static void
517zeroPipe_close( void* opaque )
518{
519    ZeroPipe*  zpipe = opaque;
520
521    D("%s: hwpipe=%p", __FUNCTION__, zpipe->hwpipe);
522    AFREE(zpipe);
523}
524
525static int
526zeroPipe_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
537static int
538zeroPipe_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
550static unsigned
551zeroPipe_poll( void* opaque )
552{
553    return PIPE_POLL_IN | PIPE_POLL_OUT;
554}
555
556static void
557zeroPipe_wakeOn( void* opaque, int flags )
558{
559    /* nothing to do here */
560}
561
562static 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
588typedef 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
597static void
598pingPongPipe_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
607static void*
608pingPongPipe_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
618static void
619pingPongPipe_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
629static int
630pingPongPipe_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
693static int
694pingPongPipe_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
737static unsigned
738pingPongPipe_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
752static void
753pingPongPipe_wakeOn( void* opaque, int flags )
754{
755    PingPongPipe* pipe = opaque;
756    pipe->flags |= (unsigned)flags;
757}
758
759static 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
783typedef 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 */
793static void throttlePipe_timerFunc( void* opaque );
794
795static void*
796throttlePipe_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
809static void
810throttlePipe_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
819static void
820throttlePipe_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
842static void
843throttlePipe_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
871static int
872throttlePipe_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
890static int
891throttlePipe_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
908static unsigned
909throttlePipe_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
923static void
924throttlePipe_wakeOn( void* opaque, int flags )
925{
926    ThrottlePipe* pipe = opaque;
927    pingPongPipe_wakeOn(&pipe->pingpong, flags);
928}
929
930static 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
948struct 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    uint64_t  params_addr;
964};
965
966static void
967pipeDevice_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
1075static 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    case PIPE_REG_PARAMS_ADDR_HIGH:
1101        s->params_addr = (s->params_addr & ~(0xFFFFFFFFULL << 32) ) |
1102                          ((uint64_t)value << 32);
1103        break;
1104
1105    case PIPE_REG_PARAMS_ADDR_LOW:
1106        s->params_addr = (s->params_addr & ~(0xFFFFFFFFULL) ) | value;
1107        break;
1108
1109    case PIPE_REG_ACCESS_PARAMS:
1110    {
1111        struct access_params aps;
1112        uint32_t cmd;
1113
1114        /* Don't touch aps.result if anything wrong */
1115        if (s->params_addr == 0)
1116            break;
1117
1118        cpu_physical_memory_read(s->params_addr, (void*)&aps,
1119                        sizeof(struct access_params));
1120
1121        /* sync pipe device state from batch buffer */
1122        s->channel = aps.channel;
1123        s->size = aps.size;
1124        s->address = aps.address;
1125        cmd = aps.cmd;
1126        if ((cmd != PIPE_CMD_READ_BUFFER) && (cmd != PIPE_CMD_WRITE_BUFFER))
1127            break;
1128
1129        pipeDevice_doCommand(s, cmd);
1130        aps.result = s->status;
1131        cpu_physical_memory_write(s->params_addr, (void*)&aps,
1132                    sizeof(struct access_params));
1133    }
1134    break;
1135
1136    default:
1137        D("%s: offset=%d (0x%x) value=%d (0x%x)\n", __FUNCTION__, offset,
1138            offset, value, value);
1139        break;
1140    }
1141}
1142
1143/* I/O read */
1144static uint32_t pipe_dev_read(void *opaque, target_phys_addr_t offset)
1145{
1146    PipeDevice *dev = (PipeDevice *)opaque;
1147
1148    switch (offset) {
1149    case PIPE_REG_STATUS:
1150        DR("%s: REG_STATUS status=%d (0x%x)", __FUNCTION__, dev->status, dev->status);
1151        return dev->status;
1152
1153    case PIPE_REG_CHANNEL:
1154        if (dev->signaled_pipes != NULL) {
1155            Pipe* pipe = dev->signaled_pipes;
1156            DR("%s: channel=0x%x wanted=%d", __FUNCTION__,
1157               pipe->channel, pipe->wanted);
1158            dev->wakes = pipe->wanted;
1159            pipe->wanted = 0;
1160            dev->signaled_pipes = pipe->next_waked;
1161            pipe->next_waked = NULL;
1162            if (dev->signaled_pipes == NULL) {
1163                goldfish_device_set_irq(&dev->dev, 0, 0);
1164                DD("%s: lowering IRQ", __FUNCTION__);
1165            }
1166            return pipe->channel;
1167        }
1168        DR("%s: no signaled channels", __FUNCTION__);
1169        return 0;
1170
1171    case PIPE_REG_WAKES:
1172        DR("%s: wakes %d", __FUNCTION__, dev->wakes);
1173        return dev->wakes;
1174
1175    case PIPE_REG_PARAMS_ADDR_HIGH:
1176        return dev->params_addr >> 32;
1177
1178    case PIPE_REG_PARAMS_ADDR_LOW:
1179        return dev->params_addr & 0xFFFFFFFFUL;
1180
1181    default:
1182        D("%s: offset=%d (0x%x)\n", __FUNCTION__, offset, offset);
1183    }
1184    return 0;
1185}
1186
1187static CPUReadMemoryFunc *pipe_dev_readfn[] = {
1188   pipe_dev_read,
1189   pipe_dev_read,
1190   pipe_dev_read
1191};
1192
1193static CPUWriteMemoryFunc *pipe_dev_writefn[] = {
1194   pipe_dev_write,
1195   pipe_dev_write,
1196   pipe_dev_write
1197};
1198
1199static void
1200goldfish_pipe_save( QEMUFile* file, void* opaque )
1201{
1202    PipeDevice* dev = opaque;
1203    Pipe* pipe;
1204
1205    qemu_put_be32(file, dev->address);
1206    qemu_put_be32(file, dev->size);
1207    qemu_put_be32(file, dev->status);
1208    qemu_put_be32(file, dev->channel);
1209    qemu_put_be32(file, dev->wakes);
1210    qemu_put_be64(file, dev->params_addr);
1211
1212    /* Count the number of pipe connections */
1213    int count = 0;
1214    for ( pipe = dev->pipes; pipe; pipe = pipe->next )
1215        count++;
1216
1217    qemu_put_sbe32(file, count);
1218
1219    /* Now save each pipe one after the other */
1220    for ( pipe = dev->pipes; pipe; pipe = pipe->next ) {
1221        pipe_save(pipe, file);
1222    }
1223}
1224
1225static int
1226goldfish_pipe_load( QEMUFile* file, void* opaque, int version_id )
1227{
1228    PipeDevice* dev = opaque;
1229    Pipe*       pipe;
1230
1231    if (version_id != GOLDFISH_PIPE_SAVE_VERSION)
1232        return -EINVAL;
1233
1234    dev->address = qemu_get_be32(file);
1235    dev->size    = qemu_get_be32(file);
1236    dev->status  = qemu_get_be32(file);
1237    dev->channel = qemu_get_be32(file);
1238    dev->wakes   = qemu_get_be32(file);
1239    dev->params_addr   = qemu_get_be64(file);
1240
1241    /* Count the number of pipe connections */
1242    int count = qemu_get_sbe32(file);
1243
1244    /* Load all pipe connections */
1245    for ( ; count > 0; count-- ) {
1246        pipe = pipe_load(dev, file);
1247        if (pipe == NULL) {
1248            return -EIO;
1249        }
1250        pipe->next = dev->pipes;
1251        dev->pipes = pipe;
1252    }
1253
1254    /* Now we need to wake/close all relevant pipes */
1255    for ( pipe = dev->pipes; pipe; pipe = pipe->next ) {
1256        if (pipe->wanted != 0)
1257            goldfish_pipe_wake(pipe, pipe->wanted);
1258        if (pipe->closed != 0)
1259            goldfish_pipe_close(pipe);
1260    }
1261    return 0;
1262}
1263
1264/* initialize the trace device */
1265void pipe_dev_init()
1266{
1267    PipeDevice *s;
1268
1269    s = (PipeDevice *) qemu_mallocz(sizeof(*s));
1270
1271    s->dev.name = "qemu_pipe";
1272    s->dev.id = -1;
1273    s->dev.base = 0;       // will be allocated dynamically
1274    s->dev.size = 0x2000;
1275    s->dev.irq = 0;
1276    s->dev.irq_count = 1;
1277
1278    goldfish_device_add(&s->dev, pipe_dev_readfn, pipe_dev_writefn, s);
1279
1280    register_savevm( "goldfish_pipe", 0, GOLDFISH_PIPE_SAVE_VERSION,
1281                      goldfish_pipe_save, goldfish_pipe_load, s);
1282
1283#if DEBUG_ZERO_PIPE
1284    goldfish_pipe_add_type("zero", NULL, &zeroPipe_funcs);
1285#endif
1286#if DEBUG_PINGPONG_PIPE
1287    goldfish_pipe_add_type("pingpong", NULL, &pingPongPipe_funcs);
1288#endif
1289#if DEBUG_THROTTLE_PIPE
1290    goldfish_pipe_add_type("throttle", NULL, &throttlePipe_funcs);
1291#endif
1292}
1293
1294void
1295goldfish_pipe_wake( void* hwpipe, unsigned flags )
1296{
1297    Pipe*  pipe = hwpipe;
1298    Pipe** lookup;
1299    PipeDevice*  dev = pipe->device;
1300
1301    DD("%s: channel=0x%x flags=%d", __FUNCTION__, pipe->channel, flags);
1302
1303    /* If not already there, add to the list of signaled pipes */
1304    lookup = pipe_list_findp_waked(&dev->signaled_pipes, pipe);
1305    if (!*lookup) {
1306        pipe->next_waked = dev->signaled_pipes;
1307        dev->signaled_pipes = pipe;
1308    }
1309    pipe->wanted |= (unsigned)flags;
1310
1311    /* Raise IRQ to indicate there are items on our list ! */
1312    goldfish_device_set_irq(&dev->dev, 0, 1);
1313    DD("%s: raising IRQ", __FUNCTION__);
1314}
1315
1316void
1317goldfish_pipe_close( void* hwpipe )
1318{
1319    Pipe* pipe = hwpipe;
1320
1321    D("%s: channel=0x%x (closed=%d)", __FUNCTION__, pipe->channel, pipe->closed);
1322
1323    if (!pipe->closed) {
1324        pipe->closed = 1;
1325        goldfish_pipe_wake( hwpipe, PIPE_WAKE_CLOSED );
1326    }
1327}
1328