Beispiel #1
0
Datei: smd.c Projekt: jaehyek/lk
int smd_get_channel_info(smd_channel_info_t *ch, uint32_t ch_type)
{
	int ret = 0;
	uint8_t *fifo_buf = NULL;
	uint32_t fifo_buf_size = 0;
	uint32_t size = 0;

	ret = smd_get_channel_entry(ch, ch_type);

	if (ret)
		return ret;

	ch->port_info = smem_get_alloc_entry(SMEM_SMD_BASE_ID + ch->alloc_entry.cid,
										 &size);

	fifo_buf = smem_get_alloc_entry(SMEM_SMD_FIFO_BASE_ID + ch->alloc_entry.cid,
									&fifo_buf_size);

	fifo_buf_size /= 2;
	ch->send_buf = fifo_buf;
	ch->recv_buf = fifo_buf + fifo_buf_size;
	ch->fifo_size = fifo_buf_size;

	return ret;
}
Beispiel #2
0
Datei: smd.c Projekt: jaehyek/lk
void smd_set_state(smd_channel_info_t *ch, uint32_t state, uint32_t flag)
{
	uint32_t current_state;
	uint32_t size = 0;

	if(!ch->port_info)
	{
		ch->port_info = smem_get_alloc_entry(SMEM_SMD_BASE_ID + ch->alloc_entry.cid,
							&size);
		ASSERT(ch->port_info);
	}

	current_state = ch->port_info->ch0.stream_state;

	switch(state)
	{
		case SMD_SS_CLOSED:
		if(current_state == SMD_SS_OPENED)
		{
			smd_write_state(ch, SMD_SS_CLOSING);
		}
		else
		{
			smd_write_state(ch, SMD_SS_CLOSED);
		}
		break;
		case SMD_SS_OPENING:
		if(current_state == SMD_SS_CLOSING || current_state == SMD_SS_CLOSED)
		{
			smd_write_state(ch, SMD_SS_OPENING);
			ch->port_info->ch1.read_index = 0;
			ch->port_info->ch0.write_index = 0;
			ch->port_info->ch0.mask_recv_intr = 0;
		}
		break;
		case SMD_SS_OPENED:
		if(current_state == SMD_SS_OPENING)
		{
			smd_write_state(ch, SMD_SS_OPENED);
		}
		break;
		case SMD_SS_CLOSING:
		if(current_state == SMD_SS_OPENED)
		{
			smd_write_state(ch, SMD_SS_CLOSING);
		}
		break;
		case SMD_SS_FLUSHING:
		case SMD_SS_RESET:
		case SMD_SS_RESET_OPENING:
		default:
		break;
	}

	ch->current_state = state;

	smd_state_update(ch, flag);
}
Beispiel #3
0
Datei: smd.c Projekt: jaehyek/lk
int smd_write(smd_channel_info_t *ch, void *data, uint32_t len, int ch_type)
{
	smd_pkt_hdr smd_hdr;
	uint32_t size = 0;

	memset(&smd_hdr, 0, sizeof(smd_pkt_hdr));

	if(len + sizeof(smd_hdr) > ch->fifo_size)
	{
		dprintf(CRITICAL,"%s: len is greater than fifo sz\n", __func__);
		return -1;
	}

	/* Read the indices from smem */
	ch->port_info = smem_get_alloc_entry(SMEM_SMD_BASE_ID + ch->alloc_entry.cid,
                                                        &size);
	if(!ch->port_info)
	{
		dprintf(CRITICAL,"%s: unable to find index in smem\n", __func__);
		ASSERT(0);
	}

	if(!is_channel_open(ch))
	{
		dprintf(CRITICAL,"%s: channel is not in OPEN state \n", __func__);
		return -1;
	}

	if(!ch->port_info->ch0.DTR_DSR)
	{
		dprintf(CRITICAL,"%s: DTR is off\n", __func__);
		return -1;
	}

	/* Clear the data_read flag */
	ch->port_info->ch1.data_read = 0;

	/*copy the local buf to smd buf */
	smd_hdr.pkt_size = len;

	memcpy_to_fifo(ch, (uint32_t *)&smd_hdr, sizeof(smd_hdr));

	memcpy_to_fifo(ch, data, len);

	dsb();

	/* Set the necessary flags */

	ch->port_info->ch0.data_written = 1;
	ch->port_info->ch0.mask_recv_intr = 0;

	dsb();

	smd_notify_rpm();

	return 0;
}
Beispiel #4
0
int smd_write(smd_channel_info_t *ch, void *data, uint32_t len, int ch_type)
{
	smd_pkt_hdr smd_hdr;
	uint32_t size = 0;

	memset(&smd_hdr, 0, sizeof(smd_pkt_hdr));

	if(len + sizeof(smd_hdr) > ch->fifo_size)
	{
		dprintf(CRITICAL,"%s: len is greater than fifo sz\n", __func__);
		return -1;
	}

	/* Read the indices from smem */
	ch->port_info = smem_get_alloc_entry(SMEM_SMD_BASE_ID + ch->alloc_entry.cid,
                                                        &size);

	if(!is_channel_open(ch))
	{
		dprintf(CRITICAL,"%s: channel is not in OPEN state \n", __func__);
		return -1;
	}

	if(!ch->port_info->ch0.DTR_DSR)
	{
		dprintf(CRITICAL,"%s: DTR is off\n", __func__);
		return -1;
	}

	/* Clear the data_read flag */
	ch->port_info->ch1.data_read = 0;

	/*copy the local buf to smd buf */
	smd_hdr.pkt_size = len;

	memcpy(ch->send_buf + ch->port_info->ch0.write_index, &smd_hdr, sizeof(smd_hdr));

	memcpy(ch->send_buf + ch->port_info->ch0.write_index + sizeof(smd_hdr), data, len);

	arch_invalidate_cache_range((addr_t)ch->send_buf+ch->port_info->ch0.write_index, sizeof(smd_hdr) + len);

	/* Update write index */
	ch->port_info->ch0.write_index += sizeof(smd_hdr) + len;

	dsb();

	/* Set the necessary flags */

	ch->port_info->ch0.data_written = 1;
	ch->port_info->ch0.mask_recv_intr = 0;

	dsb();

	smd_notify_rpm();

	return 0;
}
Beispiel #5
0
uint8_t* smd_read(smd_channel_info_t *ch, uint32_t *len, int ch_type)
{
	smd_pkt_hdr smd_hdr;
	uint32_t size = 0;

	/* Read the indices from smem */
	ch->port_info = smem_get_alloc_entry(SMEM_SMD_BASE_ID + ch->alloc_entry.cid,
										 &size);
	if(!ch->port_info->ch1.DTR_DSR)
	{
		dprintf(CRITICAL,"%s: DTR is off\n", __func__);
		return -1;
	}

	/* Wait until the data updated in the smd buffer is equal to smd packet header*/
	while ((ch->port_info->ch1.write_index - ch->port_info->ch1.read_index) < sizeof(smd_pkt_hdr))
	{
		/* Get the update info from memory */
		arch_invalidate_cache_range((addr_t) ch->port_info, size);

		if ((ch->port_info->ch1.read_index + sizeof(smd_pkt_hdr)) >= ch->fifo_size)
		{
			dprintf(CRITICAL, "At %d:%s:RX channel read index [%u] is greater than RX fifo size[%u]\n",
							   __LINE__,__func__, ch->port_info->ch1.read_index, ch->fifo_size);
			return -1;
		}
	}


	arch_invalidate_cache_range((addr_t)(ch->recv_buf + ch->port_info->ch1.read_index), sizeof(smd_hdr));

	/* Copy the smd buffer to local buf */
	memcpy(&smd_hdr, (void*)(ch->recv_buf + ch->port_info->ch1.read_index), sizeof(smd_hdr));

	*len = smd_hdr.pkt_size;

	/* Wait on the data being updated in SMEM before returing the response */
	while ((ch->port_info->ch1.write_index - ch->port_info->ch1.read_index) < smd_hdr.pkt_size)
	{
		/* Get the update info from memory */
		arch_invalidate_cache_range((addr_t) ch->port_info, size);

		if ((ch->port_info->ch1.read_index + sizeof(smd_hdr) + smd_hdr.pkt_size) >= ch->fifo_size)
		{
			dprintf(CRITICAL, "At %d:%s:RX channel read index [%u] is greater than RX fifo size[%u]\n",
							   __LINE__,__func__, ch->port_info->ch1.read_index, ch->fifo_size);
			return -1;
		}
	}

	/* We are good to return the response now */
	return (uint8_t*)(ch->recv_buf + ch->port_info->ch1.read_index + sizeof(smd_hdr));
}
Beispiel #6
0
Datei: smd.c Projekt: jaehyek/lk
void smd_read(smd_channel_info_t *ch, uint32_t *len, int ch_type, uint32_t *response)
{
	smd_pkt_hdr smd_hdr;
	uint32_t size = 0;

	/* Read the indices from smem */
	ch->port_info = smem_get_alloc_entry(SMEM_SMD_BASE_ID + ch->alloc_entry.cid,
										 &size);
	if(!ch->port_info)
	{
		dprintf(CRITICAL,"%s: unable to find index in smem\n", __func__);
		ASSERT(0);
	}

	if(!ch->port_info->ch1.DTR_DSR)
	{
		dprintf(CRITICAL,"%s: DTR is off\n", __func__);
		ASSERT(0);
	}

	/* Wait until the data updated in the smd buffer is equal to smd packet header*/
	while ((ch->port_info->ch1.write_index - ch->port_info->ch1.read_index) < sizeof(smd_pkt_hdr))
	{
		/* Get the update info from memory */
		arch_invalidate_cache_range((addr_t) ch->port_info, size);
	}

	/* Copy the smd buffer to local buf */
	memcpy_from_fifo(ch, (uint32_t *)&smd_hdr, sizeof(smd_hdr));

	arch_invalidate_cache_range((addr_t)&smd_hdr, sizeof(smd_hdr));

	*len = smd_hdr.pkt_size;

	/* Wait on the data being updated in SMEM before returing the response */
	while ((ch->port_info->ch1.write_index - ch->port_info->ch1.read_index) < smd_hdr.pkt_size)
	{
		/* Get the update info from memory */
		arch_invalidate_cache_range((addr_t) ch->port_info, size);
	}

	/* We are good to return the response now */
	memcpy_from_fifo(ch, response, smd_hdr.pkt_size);

	arch_invalidate_cache_range((addr_t)response, smd_hdr.pkt_size);

}