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