Refactor out shim code
[chai.git] / shim.c
1 /* Raw shim communication appears here.
2  * If/when the shim is replaced by something less hacky,
3  * only this file will change.
4  */
5
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <sys/ioctl.h>
9 #include <sys/mman.h>
10 #include <fcntl.h>
11 #include <string.h>
12 #include <errno.h>
13 #include <unistd.h>
14
15 #include "shim.h"
16
17 #define m_ioctl(fd, data, no) \
18         data.header.id = no; \
19         if(ioctl(fd, _IOC(_IOC_READ, 0, 0, sizeof(data)), &data)) { \
20                 printf("Bad ioctl %d (%s)\n", no, strerror(errno)); \
21                 exit(1); \
22         }
23
24 int open_kernel_module()
25 {
26         int fd = open("/dev/mali0", O_RDWR);
27
28         if(fd == -1) {
29                 printf("Failed to open /dev/mali0\n");
30                 return 1;
31         }
32
33         /* Declare the ABI version (handshake 1/3) */
34
35         struct uku_version_check_args check = {
36                 .major = BASE_UK_VERSION_MAJOR,
37                 .minor = BASE_UK_VERSION_MINOR
38         };
39
40         m_ioctl(fd, check, UKP_FUNC_ID_CHECK_VERSION);
41
42         /* Declare special flags (handshake 2/3) */
43
44         struct kbase_uk_set_flags flags = {
45                 .create_flags = BASE_CONTEXT_CREATE_FLAG_NONE
46         };
47
48         m_ioctl(fd, flags, KBASE_FUNC_SET_FLAGS);
49
50         /* Map the Memmap Tracking Handle (handshake 3/3) */
51
52         uint8_t *mtp = mmap(NULL, PAGE_SIZE, PROT_READ, MAP_SHARED, fd,
53                                 BASE_MEM_MAP_TRACKING_HANDLE);
54
55         if(mtp == MAP_FAILED) {
56                 printf("MP map failed (%s)\n", strerror(errno));
57                 return -1;
58         }
59
60         return fd;
61 }
62
63 uint64_t alloc_gpu_pages(int fd, int pages, int e_flags)
64 {
65         struct kbase_uk_mem_alloc alloc = {
66                 .va_pages = pages,
67                 .commit_pages = pages,
68                 .extent = 0,
69                 .flags = BASE_MEM_PROT_CPU_RD | BASE_MEM_PROT_CPU_WR 
70                        | e_flags
71         };
72
73         m_ioctl(fd, alloc, KBASE_FUNC_MEM_ALLOC);
74
75         return alloc.gpu_va;
76 }
77
78 void free_gpu(int fd, uint64_t addr)
79 {
80         struct kbase_uk_mem_free gfree = { .gpu_addr = addr };
81         m_ioctl(fd, gfree, KBASE_FUNC_MEM_FREE);
82 }
83
84 void sync_gpu(int fd, uint8_t* cpu, uint64_t gpu, int pages)
85 {
86         struct basep_syncset base_sset = {
87                 .mem_handle = { .basep = { .handle = gpu } },
88                 .user_addr = (u32) cpu,
89                 .size = pages << PAGE_SHIFT,
90                 .type = BASE_SYNCSET_OP_MSYNC
91         };
92
93         struct kbase_uk_sync_now sync = {
94                 .sset = { .basep_sset = base_sset}
95         };
96
97         m_ioctl(fd, sync, KBASE_FUNC_SYNC);
98 }
99
100 void submit_job(int fd, struct base_jd_atom_v2 *atoms, size_t count)
101 {
102         struct kbase_uk_job_submit submit = {
103                 .addr = { .value = atoms },
104                 .nr_atoms = count,
105                 .stride = sizeof(struct base_jd_atom_v2)
106         };
107         
108         m_ioctl(fd, submit, KBASE_FUNC_JOB_SUBMIT);
109 }
110
111 /* Not strictly an ioctl but still shim related */
112
113 uint8_t* mmap_gpu(int fd, uint64_t addr, int page_count)
114 {
115         uint8_t* buffer = mmap(NULL, page_count << PAGE_SHIFT,
116                                 PROT_READ | PROT_WRITE, MAP_SHARED,
117                                 fd, addr);
118
119         if(buffer == MAP_FAILED) {
120                 printf("Buffer map failed (%s)\n", strerror(errno));
121                 exit(1);
122         }
123
124         return buffer;
125 }