spu: start offload code to TI C64x DSP
[pcsx_rearmed.git] / plugins / dfsound / spu_c64x.c
CommitLineData
5514a050 1/*
2 * SPU processing offload to TI C64x DSP using bsp's c64_tools
3 * (C) GraÅžvydas "notaz" Ignotas, 2015
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a copy of
6 * this software and associated documentation files (the "Software"), to deal in
7 * the Software without restriction, including without limitation the rights to
8 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
9 * of the Software, and to permit persons to whom the Software is furnished to do
10 * so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be included in all
13 * copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 * SOFTWARE.
22 */
23
24#include <dlfcn.h>
25#include <inc_libc64_mini.h>
26#include "spu_c64x.h"
27
28static dsp_mem_region_t region;
29
30static struct {
31 void *handle;
32 int (*dsp_open)(void);
33 dsp_mem_region_t (*dsp_shm_alloc)(dsp_cache_t _type, sU32 _numBytes);
34 int (*dsp_shm_free)(dsp_mem_region_t _mem);
35 void (*dsp_close)(void);
36 int (*dsp_component_load)(const char *_path, const char *_name, dsp_component_id_t *_id);
37 int (*dsp_cache_inv_virt)(void *_virtAddr, sU32 _size);
38 int (*dsp_rpc_send)(const dsp_msg_t *_msgTo);
39 int (*dsp_rpc_recv)(dsp_msg_t *_msgFrom);
40 void (*dsp_logbuf_print)(void);
41} f;
42
43static void thread_work_start(void)
44{
45 do_channel_work();
46}
47
48static void thread_work_wait_sync(void)
49{
50}
51
52static void init_spu_thread(void)
53{
54 struct region_mem *mem;
55 int ret;
56
57 if (f.handle == NULL) {
58 const char lib[] = "libc64.so.1";
59 int failed = 0;
60
61 f.handle = dlopen(lib, RTLD_NOW);
62 if (f.handle == NULL) {
63 fprintf(stderr, "can't load %s: %s\n", lib, dlerror());
64 return;
65 }
66 #define LDS(name) \
67 failed |= (f.name = dlsym(f.handle, #name)) == NULL
68 LDS(dsp_open);
69 LDS(dsp_close);
70 LDS(dsp_shm_alloc);
71 LDS(dsp_shm_free);
72 LDS(dsp_cache_inv_virt);
73 LDS(dsp_component_load);
74 LDS(dsp_rpc_send);
75 LDS(dsp_rpc_recv);
76 LDS(dsp_logbuf_print);
77 #undef LDS
78 if (failed) {
79 fprintf(stderr, "missing symbol(s) in %s\n", lib);
80 dlclose(f.handle);
81 f.handle = NULL;
82 return;
83 }
84 }
85
86 ret = f.dsp_open();
87 if (ret != 0) {
88 fprintf(stderr, "dsp_open failed: %d\n", ret);
89 return;
90 }
91
92 region = f.dsp_shm_alloc(DSP_CACHE_R, sizeof(*mem)); // writethrough
93 if (region.size < sizeof(*mem) || region.virt_addr == 0) {
94 fprintf(stderr, "dsp_shm_alloc failed\n");
95 goto fail_mem;
96 }
97 mem = (void *)region.virt_addr;
98
99 // override default allocations
100 free(spu.spuMemC);
101 spu.spuMemC = mem->spu_ram;
102 free(spu.sRVBStart);
103 spu.sRVBStart = mem->RVB;
104 free(SSumLR);
105 SSumLR = mem->SSumLR;
106 free(spu.s_chan);
107 spu.s_chan = mem->s_chan;
108 worker = &mem->worker;
109
110 printf("C64x DSP ready.\n");
111 return;
112
113fail_mem:
114 f.dsp_close();
115 worker = NULL;
116}
117
118static void exit_spu_thread(void)
119{
120 if (worker == NULL)
121 return;
122
123 if (worker->pending)
124 thread_work_wait_sync();
125 f.dsp_shm_free(region);
126 f.dsp_close();
127
128 spu.spuMemC = NULL;
129 spu.sRVBStart = NULL;
130 SSumLR = NULL;
131 spu.s_chan = NULL;
132 worker = NULL;
133}
134
135// vim:shiftwidth=1:expandtab