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 | |
28 | static dsp_mem_region_t region; |
29 | |
30 | static 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 | |
43 | static void thread_work_start(void) |
44 | { |
45 | do_channel_work(); |
46 | } |
47 | |
48 | static void thread_work_wait_sync(void) |
49 | { |
50 | } |
51 | |
52 | static 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 | |
113 | fail_mem: |
114 | f.dsp_close(); |
115 | worker = NULL; |
116 | } |
117 | |
118 | static 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 |