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