Beispiel #1
0
/***********************************************************
 * Name: vc_dispmanx_resource_read_data
 *
 * Arguments:
 *       DISPMANX_RESOURCE_HANDLE_T res
 *       int src_pitch
 *       void * src_address
 *       const VC_RECT_T * rect
 *
 * Description: Copy the bitmap data to VideoCore memory
 *
 * Returns: 0 or failure
 *
 ***********************************************************/
VCHPRE_ int VCHPOST_
vc_dispmanx_resource_read_data(
   DISPMANX_RESOURCE_HANDLE_T handle,
   const VC_RECT_T* p_rect,
   void *   dst_address,
   uint32_t dst_pitch )
{
   uint8_t* host_start;
   int32_t  bulk_len;
   int32_t  success = 0;

   if ( p_rect == 0 || dst_address == 0 || dst_pitch == 0 )
   {
      return -1;
   }

   host_start = (uint8_t *)dst_address + (dst_pitch * p_rect->y);
   bulk_len   = (int32_t)dst_pitch * (p_rect->height-p_rect->y);

   // Now send the bulk transfer across
   // command parameters: resource handle, destination y, bulk length
   uint32_t param[] = { VC_HTOV32(handle), VC_HTOV32(p_rect->y), VC_HTOV32(bulk_len) };
   success = dispmanx_send_command( EDispmanBulkRead | DISPMANX_NO_REPLY_MASK, param, sizeof(param));
   if (success == 0)
   {
      lock_obtain();
      success = vchi_bulk_queue_receive(  dispmanx_client.client_handle[0],
                                          host_start,
                                          bulk_len,
                                          VCHI_FLAGS_BLOCK_UNTIL_OP_COMPLETE,
                                          0 );
      lock_release();
   }
   return (int) success;
}
/***********************************************************
 * Name: cecservice_wait_for_bulk_receive
 *
 * Arguments: response buffer, buffer length
 *
 * Description: blocked until bulk receive
 *
 * Returns error code of vchi
 *
 ***********************************************************/
static int32_t cecservice_wait_for_bulk_receive(void *buffer, uint32_t max_length) {
   vcos_assert(((uint32_t) buffer & 0xf) == 0); //should be 16 byte aligned
   return vchi_bulk_queue_receive( cecservice_client.client_handle[0],
                                   buffer,
                                   max_length,
                                   VCHI_FLAGS_BLOCK_UNTIL_OP_COMPLETE,
                                   NULL );
}
/******************************************************************************
NAME
   vchostreq_writemem

SYNOPSIS
   VC_RESP_CODE_T vchostreq_writemem( void* host_addr, void *vc_addr, int len, int channel )

FUNCTION
   Writes a block of data from Videocore into the host
   memory area specified by host_addr
   Obsolete now

RETURNS
   Success  : 0 - all the data was copied
   Fail     : 1 - error in input parameters or operation
******************************************************************************/
int vchostreq_writemem( void* host_addr, void *vc_addr, int len, int channel /* not used */ ) {
   uint32_t param[] = {(uint32_t) host_addr, len, (uint32_t) vc_addr};
   int success = hostreq_send_command(VC_HOSTREQ_WRITEMEM, param, sizeof(param));
   assert(success == 0);
   assert(0); // should not be calling this function
   success =  vchi_bulk_queue_receive(hostreq_client.client_handle[0],
                                      host_addr,
                                      len,
                                      VCHI_FLAGS_BLOCK_UNTIL_OP_COMPLETE,
                                      NULL);
   assert(success == 0);
   return (success == 0) ? 0 : 1;
}
// if handle==MEM_HANDLE_INVALID: data is a pointer, size is length
// if handle!=MEM_HANDLE_INVALID: data is int, offset from handle base, size is length
void vchiq_queue_bulk_receive(VCHIQ_STATE_T *state, int fourcc, VCHI_MEM_HANDLE_T handle, void *data, int size, void *userdata)
{
   VCHIQ_WRAPPER_T *st = wrapper_list;

   while(st != NULL && (st->state != state || st->fourcc != fourcc))
      st = st->next;

   vcos_demand(st != NULL);

   if(handle == MEM_HANDLE_INVALID)
      vchi_bulk_queue_receive(st->vchi_handle, data, size, VCHI_FLAGS_BLOCK_UNTIL_OP_COMPLETE, NULL);
   else
      vchi_bulk_queue_receive_reloc(st->vchi_handle, handle, (uint32_t) data, size, VCHI_FLAGS_BLOCK_UNTIL_OP_COMPLETE, NULL);

   st->callback(VCHIQ_BULK_RECEIVE_DONE, NULL, st->userdata, NULL);
}
Beispiel #5
0
int32_t vc_vchi_fb_read(VC_VCHI_FB_HANDLE_T handle, uint32_t res_handle,
			void *buf, int32_t size)
{
	int32_t ret, success = 0;
	FB_INSTANCE_T *instance = handle;
	uint32_t msg_len;
	VC_FB_MSG_HDR_T *msg_hdr;
	VC_FB_READ_T *fb_read;
	VC_FB_RESULT_T result;

	if (handle == NULL) {
		LOG_ERR("%s: invalid handle", __func__);

		ret = -1;
		goto out;
	}

	if (buf == NULL) {
		LOG_ERR("%s: invalid buffer pointer", __func__);

		ret = -1;
		goto out;
	}

	if (size <= 0) {
		LOG_ERR("%s: invalid buffer size %d", __func__, size);

		ret = -1;
		goto out;
	}

	mutex_lock(&instance->vchi_mutex);
	vchi_service_use(instance->vchi_handle[0]);

	LOG_INFO("%s: enter", __func__);

	msg_len = sizeof(*msg_hdr) + sizeof(*fb_read);
	memset(instance->msg_buf, 0, msg_len);

	msg_hdr = (VC_FB_MSG_HDR_T *) instance->msg_buf;
	msg_hdr->type = VC_FB_MSG_TYPE_READ;

	fb_read = (VC_FB_READ_T *) msg_hdr->body;
	fb_read->res_handle = res_handle;
	fb_read->size = size;

	/* Send the message to the videocore */
	success = vchi_msg_queue(instance->vchi_handle[0],
				 instance->msg_buf, msg_len,
				 VCHI_FLAGS_BLOCK_UNTIL_QUEUED, NULL);
	if (success != 0) {
		LOG_ERR("%s: failed to queue message (success=%d)",
			__func__, success);

		ret = -1;
		goto unlock;
	}
	LOG_INFO("%s: done sending msg", __func__);
	/* We are expecting a reply from the videocore */
	down(&instance->msg_avail);

	success = vchi_msg_dequeue(instance->vchi_handle[0],
				   &result, sizeof(result),
				   &msg_len, VCHI_FLAGS_NONE);

	LOG_INFO("%s: got reply message %x", __func__, result.success);

	if (success != 0) {
		LOG_ERR("%s: failed to dequeue message (success=%d)",
			__func__, success);

		ret = -1;
		goto unlock;
	} else if (msg_len != sizeof(result)) {
		LOG_ERR("%s: incorrect message length %u (expected=%u)",
			__func__, msg_len, sizeof(result));

		ret = -1;
		goto unlock;
	}

	LOG_INFO("%s: all good do bulk_receive %x", __func__, result.success);
	success = vchi_bulk_queue_receive(instance->vchi_handle[0],
					  buf,
					  size,
					  VCHI_FLAGS_BLOCK_UNTIL_OP_COMPLETE,
					  0);

	if (success != 0)
		LOG_ERR("%s: vchi_bulk_queue_receive failed", __func__);

unlock:

	vchi_service_release(instance->vchi_handle[0]);
	mutex_unlock(&instance->vchi_mutex);

	ret = success;
	LOG_INFO("%s: exit", __func__);
out:
	return ret;
}
Beispiel #6
0
// receive a buffer from VideoCore either from the message bytes
// or by a bulk transfer receieve
OMX_BUFFERHEADERTYPE *vc_ilcs_receive_buffer(void *call, int clen, OMX_COMPONENTTYPE **pComp)
{
   IL_PASS_BUFFER_EXECUTE_T *exe = call;
   OMX_BUFFERHEADERTYPE *pHeader = exe->bufferHeader.pInputPortPrivate;
   OMX_U8 *pBuffer = pHeader->pBuffer;
   OMX_PTR *pAppPrivate = pHeader->pAppPrivate;
   OMX_PTR *pPlatformPrivate = pHeader->pPlatformPrivate;
   OMX_PTR *pInputPortPrivate = pHeader->pInputPortPrivate;
   OMX_PTR *pOutputPortPrivate = pHeader->pOutputPortPrivate;

   vc_assert(pHeader);
   memcpy(pHeader, &exe->bufferHeader, sizeof(OMX_BUFFERHEADERTYPE));

   *pComp = exe->reference;

   pHeader->pBuffer = pBuffer;
   pHeader->pAppPrivate = pAppPrivate;
   pHeader->pPlatformPrivate = pPlatformPrivate;
   pHeader->pInputPortPrivate = pInputPortPrivate;
   pHeader->pOutputPortPrivate = pOutputPortPrivate;
   
   if(exe->method == IL_BUFFER_BULK)
   {
      vc_assert(VCHI_BULK_ALIGNED(pHeader->pBuffer));

      IL_BUFFER_BULK_T *fixup = (IL_BUFFER_BULK_T *) (exe+1);

      // bulk transfer from videocore to host
      uint8_t *start = pHeader->pBuffer + pHeader->nOffset;
      uint8_t *end   = start + pHeader->nFilledLen;
      int32_t bulk_len = pHeader->nFilledLen - fixup->headerlen - fixup->trailerlen;
      int32_t result;
      
      vc_assert(clen == sizeof(IL_PASS_BUFFER_EXECUTE_T) + sizeof(IL_BUFFER_BULK_T));

      result = vchi_bulk_queue_receive( vc_ilcsg.vchi_handle,
                                        start + fixup->headerlen,
                                        bulk_len,
                                        VCHI_FLAGS_BLOCK_UNTIL_QUEUED | VCHI_FLAGS_BLOCK_UNTIL_OP_COMPLETE,
                                        NULL );
      vc_assert(result == 0);
      
      if (fixup->headerlen)
         memcpy(start, fixup->header, fixup->headerlen);
      if (fixup->trailerlen)
         memcpy(end-fixup->trailerlen, fixup->trailer, fixup->trailerlen);
   }
   else if(exe->method == IL_BUFFER_INLINE)
   {
      IL_BUFFER_INLINE_T *buffer = (IL_BUFFER_INLINE_T *) (exe+1);

      vc_assert(clen == sizeof(IL_PASS_BUFFER_EXECUTE_T) + pHeader->nFilledLen);

      memcpy(pBuffer+pHeader->nOffset, buffer->buffer, pHeader->nFilledLen);
   }
   else if(exe->method == IL_BUFFER_NONE)
   {
      vc_assert(clen == sizeof(IL_PASS_BUFFER_EXECUTE_T));
   }
   else if(exe->method == IL_BUFFER_MAX)
   {
      vc_assert(0);
   }

   return pHeader;
}
//Request handler
static void hostreq_request_handler(int inum, HOSTREQ_SERVICE_T *state){
   assert(state->response_length);
   uint32_t *data = (uint32_t*)state->response_buffer;
   uint32_t command = *data;
   int32_t success = 0;
   data ++;
   state->response_length -= sizeof(uint32_t);

   switch(command) {
   case VC_HOSTREQ_TIME:
      {
         //VC asks for time
         //HOST specific implementation
         //We just return zero for time for now
         time_t dummytime = vchi_hostreq_time();
         int success = hostreq_send_command(VC_HOSTREQ_TIME, &dummytime, sizeof(dummytime));
         assert(success == 0);
      break;
      }
   case VC_HOSTREQ_NOTIFY:
      {
         //Host notify
         assert(state->response_length == 2*sizeof(uint32_t));
         VC_HRNOTIFY_T reason = (VC_HRNOTIFY_T) *data;
         data ++;
         uint32_t param = *data;
         if(hostreq_client.notify_callbacks[reason]) {
            (*hostreq_client.notify_callbacks[reason])(reason, param);
         }

         break;
      }
   case VC_HOSTREQ_READMEM:
      {
         //params are hostaddr, len, vc addr
         uint32_t *param = data;
         assert(param[0]);
         success = vchi_bulk_queue_transmit(hostreq_client.client_handle[0],
                                            (void *)param[0],
                                            param[1],
                                            VCHI_FLAGS_NONE,
                                            NULL);
         assert(success == 0);
         break;
      }
   case VC_HOSTREQ_WRITEMEM:
      {
         //params are hostaddr, len, vc addr
         uint32_t *param = data;
         assert(param[0]);
         success = vchi_bulk_queue_receive(hostreq_client.client_handle[0],
                                           (void *)param[0],
                                           param[1],
                                           VCHI_FLAGS_NONE,
                                           NULL);
         assert(success == 0);
         break;
      }

   default:
      assert(!"unhandled request");
   }
}