static void pipeDevice_doCommand( PipeDevice* dev, uint32_t command ) { Pipe** lookup = pipe_list_findp_channel(&dev->pipes, dev->channel); Pipe* pipe = *lookup; CPUState* env = cpu_single_env; if (command != PIPE_CMD_OPEN && pipe == NULL) { dev->status = PIPE_ERROR_INVAL; return; } if (pipe != NULL && pipe->closed && command != PIPE_CMD_CLOSE) { dev->status = PIPE_ERROR_IO; return; } switch (command) { case PIPE_CMD_OPEN: DD("%s: CMD_OPEN channel=0x%x", __FUNCTION__, dev->channel); if (pipe != NULL) { dev->status = PIPE_ERROR_INVAL; break; } pipe = pipe_new(dev->channel, dev); pipe->next = dev->pipes; dev->pipes = pipe; dev->status = 0; break; case PIPE_CMD_CLOSE: DD("%s: CMD_CLOSE channel=0x%x", __FUNCTION__, dev->channel); *lookup = pipe->next; pipe->next = NULL; pipe_list_remove_waked(&dev->signaled_pipes, pipe); pipe_free(pipe); break; case PIPE_CMD_POLL: dev->status = pipe->funcs->poll(pipe->opaque); DD("%s: CMD_POLL > status=%d", __FUNCTION__, dev->status); break; case PIPE_CMD_READ_BUFFER: { GoldfishPipeBuffer buffer; uint32_t address = dev->address; uint32_t page = address & TARGET_PAGE_MASK; target_phys_addr_t phys; phys = safe_get_phys_page_debug(env, page); buffer.data = qemu_get_ram_ptr(phys) + (address - page); buffer.size = dev->size; dev->status = pipe->funcs->recvBuffers(pipe->opaque, &buffer, 1); DD("%s: CMD_READ_BUFFER channel=0x%x address=0x%08x size=%d > status=%d", __FUNCTION__, dev->channel, dev->address, dev->size, dev->status); break; } case PIPE_CMD_WRITE_BUFFER: { GoldfishPipeBuffer buffer; uint32_t address = dev->address; uint32_t page = address & TARGET_PAGE_MASK; target_phys_addr_t phys; phys = safe_get_phys_page_debug(env, page); buffer.data = qemu_get_ram_ptr(phys) + (address - page); buffer.size = dev->size; dev->status = pipe->funcs->sendBuffers(pipe->opaque, &buffer, 1); DD("%s: CMD_WRITE_BUFFER channel=0x%x address=0x%08x size=%d > status=%d", __FUNCTION__, dev->channel, dev->address, dev->size, dev->status); break; } case PIPE_CMD_WAKE_ON_READ: DD("%s: CMD_WAKE_ON_READ channel=0x%x", __FUNCTION__, dev->channel); if ((pipe->wanted & PIPE_WAKE_READ) == 0) { pipe->wanted |= PIPE_WAKE_READ; pipe->funcs->wakeOn(pipe->opaque, pipe->wanted); } dev->status = 0; break; case PIPE_CMD_WAKE_ON_WRITE: DD("%s: CMD_WAKE_ON_WRITE channel=0x%x", __FUNCTION__, dev->channel); if ((pipe->wanted & PIPE_WAKE_WRITE) == 0) { pipe->wanted |= PIPE_WAKE_WRITE; pipe->funcs->wakeOn(pipe->opaque, pipe->wanted); } dev->status = 0; break; default: D("%s: command=%d (0x%x)\n", __FUNCTION__, command, command); } }
static void pipeDevice_doCommand( PipeDevice* dev, uint32_t command ) { Pipe** lookup = pipe_list_findp_channel(&dev->pipes, dev->channel); Pipe* pipe = *lookup; CPUOldState* env = cpu_single_env; /* Check that we're referring a known pipe channel */ if (command != PIPE_CMD_OPEN && pipe == NULL) { dev->status = PIPE_ERROR_INVAL; return; } /* If the pipe is closed by the host, return an error */ if (pipe != NULL && pipe->closed && command != PIPE_CMD_CLOSE) { dev->status = PIPE_ERROR_IO; return; } switch (command) { case PIPE_CMD_OPEN: DD("%s: CMD_OPEN channel=0x%llx", __FUNCTION__, (unsigned long long)dev->channel); if (pipe != NULL) { dev->status = PIPE_ERROR_INVAL; break; } pipe = pipe_new(dev->channel, dev); pipe->next = dev->pipes; dev->pipes = pipe; dev->status = 0; break; case PIPE_CMD_CLOSE: DD("%s: CMD_CLOSE channel=0x%llx", __FUNCTION__, (unsigned long long)dev->channel); /* Remove from device's lists */ *lookup = pipe->next; pipe->next = NULL; pipe_list_remove_waked(&dev->signaled_pipes, pipe); pipe_free(pipe); break; case PIPE_CMD_POLL: dev->status = pipe->funcs->poll(pipe->opaque); DD("%s: CMD_POLL > status=%d", __FUNCTION__, dev->status); break; case PIPE_CMD_READ_BUFFER: { /* Translate virtual address into physical one, into emulator memory. */ GoldfishPipeBuffer buffer; target_ulong address = dev->address; target_ulong page = address & TARGET_PAGE_MASK; hwaddr phys; phys = safe_get_phys_page_debug(ENV_GET_CPU(env), page); #ifdef TARGET_X86_64 phys = phys & TARGET_PTE_MASK; #endif buffer.data = qemu_get_ram_ptr(phys) + (address - page); buffer.size = dev->size; dev->status = pipe->funcs->recvBuffers(pipe->opaque, &buffer, 1); extern int matchMeInPidTid(CPUArchState *); extern int getMeContextId(CPUArchState *); if(matchMeInPidTid(env)) { printf("%d %s: CMD_READ_BUFFER channel=0x%llx address=0x%16llx size=%d > status=%d", getMeContextId(env), __FUNCTION__, (unsigned long long)dev->channel, (unsigned long long)dev->address, dev->size, dev->status); } DD("%s: CMD_READ_BUFFER channel=0x%llx address=0x%16llx size=%d > status=%d", __FUNCTION__, (unsigned long long)dev->channel, (unsigned long long)dev->address, dev->size, dev->status); break; } case PIPE_CMD_WRITE_BUFFER: { /* Translate virtual address into physical one, into emulator memory. */ GoldfishPipeBuffer buffer; target_ulong address = dev->address; target_ulong page = address & TARGET_PAGE_MASK; hwaddr phys; phys = safe_get_phys_page_debug(ENV_GET_CPU(env), page); #ifdef TARGET_X86_64 phys = phys & TARGET_PTE_MASK; #endif buffer.data = qemu_get_ram_ptr(phys) + (address - page); buffer.size = dev->size; dev->status = pipe->funcs->sendBuffers(pipe->opaque, &buffer, 1); extern int matchMeInPidTid(CPUArchState *); extern int getMeContextId(CPUArchState *); if(matchMeInPidTid(env)) { printf("%d %s: CMD_WRITE_BUFFER channel=0x%llx address=0x%16llx size=%d > status=%d", getMeContextId(env), __FUNCTION__, (unsigned long long)dev->channel, (unsigned long long)dev->address, dev->size, dev->status); } DD("%s: CMD_WRITE_BUFFER channel=0x%llx address=0x%16llx size=%d > status=%d", __FUNCTION__, (unsigned long long)dev->channel, (unsigned long long)dev->address, dev->size, dev->status); break; } case PIPE_CMD_WAKE_ON_READ: DD("%s: CMD_WAKE_ON_READ channel=0x%llx", __FUNCTION__, (unsigned long long)dev->channel); if ((pipe->wanted & PIPE_WAKE_READ) == 0) { pipe->wanted |= PIPE_WAKE_READ; pipe->funcs->wakeOn(pipe->opaque, pipe->wanted); } dev->status = 0; break; case PIPE_CMD_WAKE_ON_WRITE: DD("%s: CMD_WAKE_ON_WRITE channel=0x%llx", __FUNCTION__, (unsigned long long)dev->channel); if ((pipe->wanted & PIPE_WAKE_WRITE) == 0) { pipe->wanted |= PIPE_WAKE_WRITE; pipe->funcs->wakeOn(pipe->opaque, pipe->wanted); } dev->status = 0; break; default: D("%s: command=%d (0x%x)\n", __FUNCTION__, command, command); } }