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; }
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); }
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; }
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; }
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)); }
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); }