123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828 |
- /*
- * Copyright (c) 2016 - 2017 Cadence Design Systems Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
- * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
- #include <stdint.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <xtensa/xtruntime.h>
- #include "xrp_api.h"
- #include "xrp_debug.h"
- #include "xrp_dsp_hw.h"
- #include "xrp_dsp_sync.h"
- #include "xrp_dsp_user.h"
- #include "xrp_ns.h"
- #include "xrp_types.h"
- #include "xrp_kernel_dsp_interface.h"
- extern char xrp_dsp_comm_base_magic[] __attribute__((weak));
- void *xrp_dsp_comm_base = &xrp_dsp_comm_base_magic;
- //void *xrp_dsp_comm_base = 0x98000000;
- static int manage_cache;
- int dsp_log_level = FW_DEBUG_LOG_MODE_ERR;
- #define MAX_STACK_BUFFERS 16
- #define MAX_TLV_LENGTH 0x10000
- /* DSP side XRP API implementation */
- struct xrp_refcounted {
- unsigned long count;
- };
- struct xrp_device {
- struct xrp_refcounted ref;
- void *dsp_cmd;
- };
- struct xrp_buffer {
- struct xrp_refcounted ref;
- void *ptr;
- size_t size;
- unsigned long map_count;
- enum xrp_access_flags allowed_access;
- enum xrp_access_flags map_flags;
- };
- struct xrp_buffer_group {
- struct xrp_refcounted ref;
- size_t n_buffers;
- struct xrp_buffer *buffer;
- };
- static struct xrp_cmd_ns_map ns_map;
- static size_t dsp_hw_queue_entry_size = XRP_DSP_CMD_STRIDE;
- static struct xrp_device dsp_device0;
- static int n_dsp_devices;
- static struct xrp_device **dsp_device;
- void xrp_device_enable_cache(struct xrp_device *device, int enable)
- {
- (void)device;
- manage_cache = enable;
- }
- static inline void dcache_region_invalidate(void *p, size_t sz)
- {
- if (manage_cache)
- xthal_dcache_region_invalidate(p, sz);
- }
- static inline void dcache_region_writeback(void *p, size_t sz)
- {
- if (manage_cache)
- xthal_dcache_region_writeback(p, sz);
- }
- static inline void set_status(enum xrp_status *status, enum xrp_status v)
- {
- if (status)
- *status = v;
- }
- static void retain_refcounted(struct xrp_refcounted *ref)
- {
- if (ref) {
- ++ref->count;
- }
- }
- static void release_refcounted(struct xrp_refcounted *ref)
- {
- if (ref) {
- --ref->count;
- }
- }
- struct xrp_device *xrp_open_device(int idx, enum xrp_status *status)
- {
- if (idx == 0) {
- dsp_device0.dsp_cmd = xrp_dsp_comm_base;
- set_status(status, XRP_STATUS_SUCCESS);
- return &dsp_device0;
- } else if (idx < n_dsp_devices) {
- xrp_retain_device(dsp_device[idx]);
- set_status(status, XRP_STATUS_SUCCESS);
- return dsp_device[idx];
- } else {
- set_status(status, XRP_STATUS_FAILURE);
- return NULL;
- }
- }
- void xrp_retain_device(struct xrp_device *device)
- {
- retain_refcounted(&device->ref);
- }
- void xrp_release_device(struct xrp_device *device)
- {
- release_refcounted(&device->ref);
- }
- struct xrp_buffer *xrp_create_buffer(struct xrp_device *device,
- size_t size, void *host_ptr,
- enum xrp_status *status)
- {
- (void)device;
- (void)size;
- (void)host_ptr;
- set_status(status, XRP_STATUS_FAILURE);
- return NULL;
- }
- void xrp_retain_buffer(struct xrp_buffer *buffer)
- {
- retain_refcounted(&buffer->ref);
- }
- void xrp_release_buffer(struct xrp_buffer *buffer)
- {
- release_refcounted(&buffer->ref);
- }
- void *xrp_map_buffer(struct xrp_buffer *buffer, size_t offset, size_t size,
- enum xrp_access_flags map_flags, enum xrp_status *status)
- {
- if (offset <= buffer->size &&
- size <= buffer->size - offset &&
- (buffer->allowed_access & map_flags) == map_flags) {
- retain_refcounted(&buffer->ref);
- ++buffer->map_count;
- buffer->map_flags |= map_flags;
- set_status(status, XRP_STATUS_SUCCESS);
- return buffer->ptr + offset;
- }
- set_status(status, XRP_STATUS_FAILURE);
- return NULL;
- }
- void xrp_unmap_buffer(struct xrp_buffer *buffer, void *p,
- enum xrp_status *status)
- {
- if (p >= buffer->ptr && (size_t)(p - buffer->ptr) <= buffer->size) {
- --buffer->map_count;
- release_refcounted(&buffer->ref);
- set_status(status, XRP_STATUS_SUCCESS);
- } else {
- set_status(status, XRP_STATUS_FAILURE);
- }
- }
- void xrp_buffer_get_info(struct xrp_buffer *buffer, enum xrp_buffer_info info,
- void *out, size_t out_sz, enum xrp_status *status)
- {
- enum xrp_status s = XRP_STATUS_FAILURE;
- size_t sz;
- void *ptr;
- switch (info) {
- case XRP_BUFFER_SIZE_SIZE_T:
- sz = sizeof(buffer->size);
- ptr = &buffer->size;
- break;
- case XRP_BUFFER_HOST_POINTER_PTR:
- sz = sizeof(void *);
- ptr = &buffer->ptr;
- break;
- default:
- goto out;
- }
- if (sz == out_sz) {
- memcpy(out, ptr, sz);
- s = XRP_STATUS_SUCCESS;
- }
- out:
- set_status(status, s);
- }
- struct xrp_buffer_group *xrp_create_buffer_group(enum xrp_status *status)
- {
- set_status(status, XRP_STATUS_FAILURE);
- return NULL;
- }
- void xrp_retain_buffer_group(struct xrp_buffer_group *group)
- {
- retain_refcounted(&group->ref);
- }
- void xrp_release_buffer_group(struct xrp_buffer_group *group)
- {
- release_refcounted(&group->ref);
- }
- size_t xrp_add_buffer_to_group(struct xrp_buffer_group *group,
- struct xrp_buffer *buffer,
- enum xrp_access_flags access_flags,
- enum xrp_status *status)
- {
- (void)group;
- (void)buffer;
- (void)access_flags;
- set_status(status, XRP_STATUS_FAILURE);
- return -1;
- }
- struct xrp_buffer *xrp_get_buffer_from_group(struct xrp_buffer_group *group,
- size_t idx,
- enum xrp_status *status)
- {
- if (idx < group->n_buffers) {
- set_status(status, XRP_STATUS_SUCCESS);
- xrp_retain_buffer(group->buffer + idx);
- return group->buffer + idx;
- }
- set_status(status, XRP_STATUS_FAILURE);
- return NULL;
- }
- void xrp_buffer_group_get_info(struct xrp_buffer_group *group,
- enum xrp_buffer_group_info info, size_t idx,
- void *out, size_t out_sz,
- enum xrp_status *status)
- {
- enum xrp_status s = XRP_STATUS_FAILURE;
- size_t sz;
- void *ptr;
- switch (info) {
- case XRP_BUFFER_GROUP_BUFFER_FLAGS_ENUM:
- if (idx >= group->n_buffers)
- goto out;
- sz = sizeof(group->buffer[idx].allowed_access);
- ptr = &group->buffer[idx].allowed_access;
- break;
- case XRP_BUFFER_GROUP_SIZE_SIZE_T:
- sz = sizeof(group->n_buffers);
- ptr = &group->n_buffers;
- break;
- default:
- goto out;
- }
- if (sz == out_sz) {
- memcpy(out, ptr, sz);
- s = XRP_STATUS_SUCCESS;
- }
- out:
- set_status(status, s);
- }
- /* DSP side request handling */
- static int update_hw_queues(uint32_t queue_priority[], int n)
- {
- if (xrp_user_create_queues) {
- struct xrp_device **new_device = malloc(n * sizeof(void *));
- struct xrp_device **old_device = dsp_device;
- int n_old = n_dsp_devices;
- int i;
- if (!new_device) {
- ps_debug("%s: device array allocation failed\n",
- __func__);
- return 0;
- }
- for (i = 1; i < n; ++i) {
- new_device[i] = calloc(1, sizeof(struct xrp_device));
- if (!new_device[i]) {
- ps_debug("%s: device allocation failed\n",
- __func__);
- while (--i)
- xrp_release_device(new_device[i]);
- free(new_device);
- return 0;
- }
- new_device[i]->dsp_cmd = xrp_dsp_comm_base +
- i * dsp_hw_queue_entry_size;
- xrp_retain_device(new_device[i]);
- }
- dsp_device = new_device;
- n_dsp_devices = n;
- for (i = 1; i < n_old; ++i)
- xrp_release_device(old_device[i]);
- free(old_device);
- return xrp_user_create_queues(n, queue_priority) ==
- XRP_STATUS_SUCCESS;
- } else {
- return 0;
- }
- }
- static int set_debug_profile_info(void* data)
- {
- struct xrp_dsp_debug_info *debug_info = data;
- if(xrp_hw_panic_init((void *)debug_info->panic_addr))
- {
- return -1;
- }
- dsp_log_level = debug_info->log_level;
- return 0;
- }
- static void process_sync_data(struct xrp_device *device,
- struct xrp_dsp_tlv *data)
- {
- (void)device;
- for (;; data = (void *)(data->value + ((data->length + 3) / 4))) {
- dcache_region_invalidate(data, sizeof(*data));
- if (data->length >= MAX_TLV_LENGTH) {
- ps_debug("%s: suspicious length, data = %p, length = %d\n",
- __func__, data, (unsigned)data->length);
- break;
- }
- dcache_region_invalidate(data->value, data->length);
- switch (data->type & XRP_DSP_SYNC_TYPE_MASK) {
- case XRP_DSP_SYNC_TYPE_LAST:
- return;
- case XRP_DSP_SYNC_TYPE_HW_SPEC_DATA:
- if (xrp_hw_set_sync_data)
- xrp_hw_set_sync_data(data->value);
- data->type |= XRP_DSP_SYNC_TYPE_ACCEPT;
- break;
- case XRP_DSP_SYNC_TYPE_HW_QUEUES:
- if (update_hw_queues(data->value,
- data->length / 4))
- data->type |= XRP_DSP_SYNC_TYPE_ACCEPT;
- break;
- case XRP_DSP_SYNC_TYPE_HW_DEBUG_INFO:
- if(!set_debug_profile_info(data->value))
- data->type |= XRP_DSP_SYNC_TYPE_ACCEPT;
- break;
- default:
- ps_debug("%s, unrecognized TLV: type = 0x%08x, length = %d\n",
- __func__, data->type, data->length);
- continue;
- }
- dcache_region_writeback(data, sizeof(data) + data->length);
- }
- }
- static void do_handshake(struct xrp_device *device)
- {
- struct xrp_dsp_sync_v2 *shared_sync = device->dsp_cmd;
- uint32_t v;
- while (xrp_l32ai(&shared_sync->sync) != XRP_DSP_SYNC_START) {
- dcache_region_invalidate(&shared_sync->sync,
- sizeof(shared_sync->sync));
- }
- xrp_s32ri(XRP_DSP_SYNC_DSP_READY_V2, &shared_sync->sync);
- dcache_region_writeback(&shared_sync->sync,
- sizeof(shared_sync->sync));
- for (;;) {
- dcache_region_invalidate(&shared_sync->sync,
- sizeof(shared_sync->sync));
- v = xrp_l32ai(&shared_sync->sync);
- if (v == XRP_DSP_SYNC_HOST_TO_DSP)
- break;
- if (v != XRP_DSP_SYNC_DSP_READY_V2)
- return;
- }
- process_sync_data(device, shared_sync->hw_sync_data);
- // xrp_s32ri(XRP_DSP_SYNC_DSP_TO_HOST, &shared_sync->sync);
- // dcache_region_writeback(&shared_sync->sync,
- // sizeof(shared_sync->sync));
- //
- // xrp_hw_wait_device_irq();
- //xrp_hw_send_host_irq();
- pr_debug("%s: done\n", __func__);
- }
- static inline int xrp_request_valid(struct xrp_dsp_cmd *dsp_cmd,
- uint32_t *pflags)
- {
- uint32_t flags = xrp_l32ai(&dsp_cmd->flags);
- *pflags = flags;
- return (flags & (XRP_DSP_CMD_FLAG_REQUEST_VALID |
- XRP_DSP_CMD_FLAG_RESPONSE_VALID)) ==
- XRP_DSP_CMD_FLAG_REQUEST_VALID;
- }
- static void complete_request(struct xrp_dsp_cmd *dsp_cmd, uint32_t flags)
- {
- flags |= XRP_DSP_CMD_FLAG_RESPONSE_VALID;
- dcache_region_writeback(dsp_cmd,
- sizeof(*dsp_cmd));
- xrp_s32ri(flags, &dsp_cmd->flags);
- xrp_s32ri(XRP_DSP_REPORT_TO_HOST_FLAG,&dsp_cmd->cmd_flag);
- dcache_region_writeback(&dsp_cmd->flags,
- sizeof(dsp_cmd->flags));
- xrp_hw_send_host_irq();
- }
- static enum xrp_access_flags dsp_buffer_allowed_access(__u32 flags)
- {
- return flags == XRP_DSP_BUFFER_FLAG_READ ?
- XRP_READ : XRP_READ_WRITE;
- }
- void xrp_run_command(const void *in_data, size_t in_data_size,
- void *out_data, size_t out_data_size,
- struct xrp_buffer_group *buffer_group,
- enum xrp_status *status) __attribute__((weak));
- void xrp_run_command(const void *in_data, size_t in_data_size,
- void *out_data, size_t out_data_size,
- struct xrp_buffer_group *buffer_group,
- enum xrp_status *status)
- {
- (void)in_data;
- (void)in_data_size;
- (void)out_data;
- (void)out_data_size;
- (void)buffer_group;
- *status = XRP_STATUS_FAILURE;
- }
- static inline enum xrp_status
- xrp_run_command_handler(void *handler_context,
- const void *in_data, size_t in_data_size,
- void *out_data, size_t out_data_size,
- struct xrp_buffer_group *buffer_group)
- {
- enum xrp_status status = XRP_STATUS_FAILURE;
- (void)handler_context;
- xrp_run_command(in_data, in_data_size,
- out_data, out_data_size,
- buffer_group, &status);
- return status;
- }
- static enum xrp_status process_command(struct xrp_device *device,
- uint32_t flags)
- {
- enum xrp_status status;
- struct xrp_dsp_cmd *dsp_cmd = device->dsp_cmd;
- size_t n_buffers = dsp_cmd->buffer_size / sizeof(struct xrp_dsp_buffer);
- struct xrp_dsp_buffer *dsp_buffer;
- struct xrp_buffer_group buffer_group;
- struct xrp_buffer sbuffer[n_buffers <= MAX_STACK_BUFFERS ? n_buffers : 1];
- struct xrp_buffer *buffer = sbuffer;
- xrp_command_handler *command_handler = xrp_run_command_handler;
- void *handler_context = NULL;
- size_t i;
- if (dsp_cmd->flags & XRP_DSP_CMD_FLAG_REQUEST_NSID) {
- struct xrp_cmd_ns *cmd_ns = xrp_find_cmd_ns(&ns_map,
- dsp_cmd->nsid);
- if (xrp_cmd_ns_match(dsp_cmd->nsid, cmd_ns)) {
- command_handler = cmd_ns->handler;
- handler_context = cmd_ns->handler_context;
- } else {
- flags |= XRP_DSP_CMD_FLAG_RESPONSE_DELIVERY_FAIL;
- status = XRP_STATUS_FAILURE;
- goto out;
- }
- }
- if (n_buffers > XRP_DSP_CMD_INLINE_BUFFER_COUNT) {
- dsp_buffer = (void *)dsp_cmd->buffer_addr;
- dcache_region_invalidate(dsp_buffer,
- n_buffers * sizeof(*dsp_buffer));
- } else {
- dsp_buffer = (void *)&dsp_cmd->buffer_data;
- }
- if (dsp_cmd->in_data_size > sizeof(dsp_cmd->in_data)) {
- dcache_region_invalidate((void *)dsp_cmd->in_data_addr,
- dsp_cmd->in_data_size);
- }
- if (n_buffers > MAX_STACK_BUFFERS) {
- buffer = malloc(n_buffers * sizeof(*buffer));
- if (!buffer) {
- status = XRP_STATUS_FAILURE;
- goto out;
- }
- }
- /* Create buffers from incoming buffer data, put them to group.
- * Passed flags add some restrictions to possible buffer mapping
- * modes:
- * R only allows R
- * W and RW allow R, W or RW
- * (actually W only allows W and RW, but that's hard to express and
- * is not particularly useful)
- */
- for (i = 0; i < n_buffers; ++i) {
- buffer[i] = (struct xrp_buffer){
- .allowed_access =
- dsp_buffer_allowed_access(dsp_buffer[i].flags),
- .ptr = (void *)dsp_buffer[i].addr,
- .size = dsp_buffer[i].size,
- };
- if (buffer[i].allowed_access & XRP_READ) {
- dcache_region_invalidate(buffer[i].ptr,
- buffer[i].size);
- }
- }
- buffer_group = (struct xrp_buffer_group){
- .n_buffers = n_buffers,
- .buffer = buffer,
- };
- status = command_handler(handler_context,
- dsp_cmd->in_data_size > sizeof(dsp_cmd->in_data) ?
- (void *)dsp_cmd->in_data_addr : dsp_cmd->in_data,
- dsp_cmd->in_data_size,
- dsp_cmd->out_data_size > sizeof(dsp_cmd->out_data) ?
- (void *)dsp_cmd->out_data_addr : dsp_cmd->out_data,
- dsp_cmd->out_data_size,
- &buffer_group);
- if (status != XRP_STATUS_SUCCESS)
- flags |= XRP_DSP_CMD_FLAG_RESPONSE_DELIVERY_FAIL;
- /*
- * update flags in the buffer data: what access actually took place,
- * to update caches on the host side.
- */
- for (i = 0; i < n_buffers; ++i) {
- __u32 flags = 0;
- if (buffer[i].map_flags & XRP_READ)
- flags |= XRP_DSP_BUFFER_FLAG_READ;
- if (buffer[i].map_flags & XRP_WRITE)
- flags |= XRP_DSP_BUFFER_FLAG_WRITE;
- // pr_debug("%s: dsp_buffer[%d].flags = %d\n", __func__, i, flags);
- dsp_buffer[i].flags = flags;
- if (buffer[i].ref.count) {
- ps_debug("%s: refcount leak on buffer %d\n",
- __func__, i);
- }
- if (buffer[i].map_count) {
- ps_debug("%s: map_count leak on buffer %d\n",
- __func__, i);
- }
- if (buffer[i].map_flags & XRP_WRITE) {
- dcache_region_writeback(buffer[i].ptr,
- buffer[i].size);
- }
- }
- if (buffer_group.ref.count) {
- ps_debug("%s: refcount leak on buffer group\n", __func__);
- }
- if (dsp_cmd->out_data_size > sizeof(dsp_cmd->out_data)) {
- dcache_region_writeback((void *)dsp_cmd->out_data_addr,
- dsp_cmd->out_data_size);
- }
- if (n_buffers > XRP_DSP_CMD_INLINE_BUFFER_COUNT) {
- dcache_region_writeback(dsp_buffer,
- n_buffers * sizeof(*dsp_buffer));
- }
- if (n_buffers > MAX_STACK_BUFFERS) {
- free(buffer);
- }
- out:
- complete_request(dsp_cmd, flags);
- return status;
- }
- void xrp_device_register_namespace(struct xrp_device *device,
- const void *nsid,
- xrp_command_handler *handler,
- void *handler_context,
- enum xrp_status *status)
- {
- (void)device;
- if (xrp_register_namespace(&ns_map,
- nsid, handler, handler_context))
- set_status(status, XRP_STATUS_SUCCESS);
- else
- set_status(status, XRP_STATUS_FAILURE);
- }
- void xrp_device_unregister_namespace(struct xrp_device *device,
- const void *nsid,
- enum xrp_status *status)
- {
- (void)device;
- if (xrp_unregister_namespace(&ns_map, nsid))
- set_status(status, XRP_STATUS_SUCCESS);
- else
- set_status(status, XRP_STATUS_FAILURE);
- }
- enum xrp_status xrp_device_poll(struct xrp_device *device)
- {
- uint32_t flags;
- dcache_region_invalidate(device->dsp_cmd,
- sizeof(struct xrp_dsp_cmd));
- if (xrp_request_valid(device->dsp_cmd, &flags))
- return XRP_STATUS_SUCCESS;
- else
- return XRP_STATUS_PENDING;
- }
- enum xrp_status xrp_device_dispatch(struct xrp_device *device)
- {
- uint32_t flags;
- enum xrp_status status;
- dcache_region_invalidate(device->dsp_cmd,
- sizeof(struct xrp_dsp_cmd));
- if (!xrp_request_valid(device->dsp_cmd, &flags))
- return XRP_STATUS_PENDING;
- if (flags == XRP_DSP_SYNC_START) {
- do_handshake(device);
- status = XRP_STATUS_SUCCESS;
- } else {
- status = process_command(device, flags);
- }
- return status;
- }
- enum xrp_status xrp_device_sync(struct xrp_device *device)
- {
- uint32_t flags;
- enum xrp_status status;
- dcache_region_invalidate(device->dsp_cmd,
- sizeof(struct xrp_dsp_cmd));
- if (!xrp_request_valid(device->dsp_cmd, &flags))
- return XRP_STATUS_PENDING;
- if (flags == XRP_DSP_SYNC_START) {
- do_handshake(device);
- return XRP_STATUS_SUCCESS;
- }
- return XRP_STATUS_FAILURE;
- }
- enum xrp_status xrp_device_init_done(struct xrp_device *device)
- {
- struct xrp_dsp_sync_v2 *shared_sync = device->dsp_cmd;
- xrp_s32ri(XRP_DSP_SYNC_DSP_TO_HOST, &shared_sync->sync);
- dcache_region_writeback(&shared_sync->sync,
- sizeof(shared_sync->sync));
- xrp_hw_wait_device_irq();
- return XRP_STATUS_SUCCESS;
- }
- enum xrp_status xrp_device_command_dispatch(struct xrp_device *device)
- {
- uint32_t flags;
- dcache_region_invalidate(device->dsp_cmd,
- sizeof(struct xrp_dsp_cmd));
- if (!xrp_request_valid(device->dsp_cmd, &flags))
- {
- return XRP_STATUS_FAILURE;
- }
- if(flags == XRP_DSP_SYNC_START)
- {
- return XRP_STATUS_FAILURE;
- }
- return process_command(device, flags);
- }
- enum xrp_status xrp_get_report_buffer(struct xrp_device *device,void** buffer,void*buffer_size)
- {
- enum xrp_status status;
- struct xrp_dsp_cmd* share_region=(struct xrp_dsp_cmd*)device->dsp_cmd;
- uint32_t report_status = xrp_l32ai(&share_region->report_status);
- if(report_status==XRP_DSP_REPORT_INVALID)
- {
- ps_wrn("Driver kernel report is not setup");
- return XRP_STATUS_PENDING;
- }
- // *buffer = share_region->report_paylad_size>XRP_DSP_CMD_INLINE_DATA_SIZE ?
- // share_region->report_addr: share_region->report_data;
- *buffer = (void*)share_region->report_addr;
- *(uint32_t *)buffer_size = share_region->report_paylad_size;
- return XRP_STATUS_SUCCESS;
- }
- enum xrp_status xrp_send_report(struct xrp_device *device,uint32_t id)
- {
- enum xrp_status status;
- struct xrp_dsp_cmd* share_region=(struct xrp_dsp_cmd*)device->dsp_cmd;
- uint32_t current_id = xrp_l32ai(&share_region->report_id);
- if(current_id!=0)
- {
- ps_err("previous report:%d still pending\n",current_id);
- return XRP_STATUS_PENDING;
- }
- xrp_s32ri(id,&share_region->report_id);
- xrp_hw_send_host_irq();
- // pr_debug("report send to Host\n");
- return XRP_STATUS_SUCCESS;
- }
- enum xrp_status xrp_get_report_status(struct xrp_device *device)
- {
- enum xrp_status status;
- struct xrp_dsp_cmd* share_region=(struct xrp_dsp_cmd*)device->dsp_cmd;
- uint32_t current_id = xrp_l32ai(&share_region->report_id);
- if(current_id!=0)
- {
- ps_wrn("previous report:%d still pending\n",current_id);
- return XRP_STATUS_PENDING;
- }
- return XRP_STATUS_SUCCESS;
- }
- static void exception(ExcFrame *ef)
- {
- unsigned long exccause, excvaddr, ps, epc1;
- exccause = ef->exccause & EXCCAUSE_FULLTYPE_MASK;
- excvaddr = ef->excvaddr;
- ps = ef->ps;
- epc1 = ef->pc;
- printf("%s: EXCCAUSE = %ld, EXCVADDR = 0x%08lx, PS = 0x%08lx, EPC1 = 0x%08lx\n",
- __func__, exccause, excvaddr, ps, epc1);
- hang();
- }
- static void register_exception_handlers(void)
- {
- static const int cause[] = {
- EXCCAUSE_INSTRUCTION,
- EXCCAUSE_ADDRESS,
- EXCCAUSE_HARDWARE,
- EXCCAUSE_MEMORY,
- };
- unsigned i;
- for (i = 0; i < sizeof(cause) / sizeof(cause[0]); ++i) {
- _xtos_set_exception_handler(cause[i], exception);
- }
- }
- void xrp_user_initialize(enum xrp_status *status)
- {
- ps_debug("%s\n", __func__);
- register_exception_handlers();
- // atexit(hang);
- if (status != NULL)
- *status = XRP_STATUS_SUCCESS;
- }
|