xref: /NextBSD/sys/dev/drm2/radeon/radeon_ioc32.c (revision 287e3b14e9552995def1802ec9c5034f4adf28ec)
1 /**
2  * \file radeon_ioc32.c
3  *
4  * 32-bit ioctl compatibility routines for the Radeon DRM.
5  *
6  * \author Paul Mackerras <paulus@samba.org>
7  *
8  * Copyright (C) Paul Mackerras 2005
9  * All Rights Reserved.
10  *
11  * Permission is hereby granted, free of charge, to any person obtaining a
12  * copy of this software and associated documentation files (the "Software"),
13  * to deal in the Software without restriction, including without limitation
14  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
15  * and/or sell copies of the Software, and to permit persons to whom the
16  * Software is furnished to do so, subject to the following conditions:
17  *
18  * The above copyright notice and this permission notice (including the next
19  * paragraph) shall be included in all copies or substantial portions of the
20  * Software.
21  *
22  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
25  * THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
26  * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
28  * IN THE SOFTWARE.
29  */
30 
31 #include <sys/cdefs.h>
32 __FBSDID("$FreeBSD$");
33 
34 #include "opt_compat.h"
35 
36 #ifdef COMPAT_FREEBSD32
37 
38 #include <dev/drm2/drmP.h>
39 #include <dev/drm2/drm.h>
40 #include <dev/drm2/radeon/radeon_drm.h>
41 #include "radeon_drv.h"
42 
43 typedef struct drm_radeon_init32 {
44 	int func;
45 	u32 sarea_priv_offset;
46 	int is_pci;
47 	int cp_mode;
48 	int gart_size;
49 	int ring_size;
50 	int usec_timeout;
51 
52 	unsigned int fb_bpp;
53 	unsigned int front_offset, front_pitch;
54 	unsigned int back_offset, back_pitch;
55 	unsigned int depth_bpp;
56 	unsigned int depth_offset, depth_pitch;
57 
58 	u32 fb_offset;
59 	u32 mmio_offset;
60 	u32 ring_offset;
61 	u32 ring_rptr_offset;
62 	u32 buffers_offset;
63 	u32 gart_textures_offset;
64 } drm_radeon_init32_t;
65 
compat_radeon_cp_init(struct drm_device * dev,void * arg,struct drm_file * file_priv)66 static int compat_radeon_cp_init(struct drm_device *dev, void *arg,
67 				 struct drm_file *file_priv)
68 {
69 	drm_radeon_init32_t *init32;
70 	drm_radeon_init_t __user init;
71 
72 	init32 = arg;
73 
74 	init.func = init32->func;
75 	init.sarea_priv_offset = (unsigned long)init32->sarea_priv_offset;
76 	init.is_pci = init32->is_pci;
77 	init.cp_mode = init32->cp_mode;
78 	init.gart_size = init32->gart_size;
79 	init.ring_size = init32->ring_size;
80 	init.usec_timeout = init32->usec_timeout;
81 	init.fb_bpp = init32->fb_bpp;
82 	init.front_offset = init32->front_offset;
83 	init.front_pitch = init32->front_pitch;
84 	init.back_offset = init32->back_offset;
85 	init.back_pitch = init32->back_pitch;
86 	init.depth_bpp = init32->depth_bpp;
87 	init.depth_offset = init32->depth_offset;
88 	init.depth_pitch = init32->depth_pitch;
89 	init.fb_offset = (unsigned long)init32->fb_offset;
90 	init.mmio_offset = (unsigned long)init32->mmio_offset;
91 	init.ring_offset = (unsigned long)init32->ring_offset;
92 	init.ring_rptr_offset = (unsigned long)init32->ring_rptr_offset;
93 	init.buffers_offset = (unsigned long)init32->buffers_offset;
94 	init.gart_textures_offset = (unsigned long)init32->gart_textures_offset;
95 
96 	return radeon_cp_init(dev, &init, file_priv);
97 }
98 
99 typedef struct drm_radeon_clear32 {
100 	unsigned int flags;
101 	unsigned int clear_color;
102 	unsigned int clear_depth;
103 	unsigned int color_mask;
104 	unsigned int depth_mask;	/* misnamed field:  should be stencil */
105 	u32 depth_boxes;
106 } drm_radeon_clear32_t;
107 
compat_radeon_cp_clear(struct drm_device * dev,void * arg,struct drm_file * file_priv)108 static int compat_radeon_cp_clear(struct drm_device *dev, void *arg,
109 				  struct drm_file *file_priv)
110 {
111 	drm_radeon_clear32_t *clr32;
112 	drm_radeon_clear_t __user clr;
113 
114 	clr32 = arg;
115 
116 	clr.flags = clr32->flags;
117 	clr.clear_color = clr32->clear_color;
118 	clr.clear_depth = clr32->clear_depth;
119 	clr.color_mask = clr32->color_mask;
120 	clr.depth_mask = clr32->depth_mask;
121 	clr.depth_boxes = (drm_radeon_clear_rect_t *)(unsigned long)clr32->depth_boxes;
122 
123 	return radeon_ioctls[DRM_IOCTL_RADEON_CLEAR].func(dev, &clr, file_priv);
124 }
125 
126 typedef struct drm_radeon_stipple32 {
127 	u32 mask;
128 } drm_radeon_stipple32_t;
129 
compat_radeon_cp_stipple(struct drm_device * dev,void * arg,struct drm_file * file_priv)130 static int compat_radeon_cp_stipple(struct drm_device *dev, void *arg,
131 				    struct drm_file *file_priv)
132 {
133 	drm_radeon_stipple32_t __user *argp = (void __user *)arg;
134 	drm_radeon_stipple_t __user request;
135 
136 	request.mask = (unsigned int *)(unsigned long)argp->mask;
137 
138 	return radeon_ioctls[DRM_IOCTL_RADEON_STIPPLE].func(dev, &request, file_priv);
139 }
140 
141 typedef struct drm_radeon_tex_image32 {
142 	unsigned int x, y;	/* Blit coordinates */
143 	unsigned int width, height;
144 	u32 data;
145 } drm_radeon_tex_image32_t;
146 
147 typedef struct drm_radeon_texture32 {
148 	unsigned int offset;
149 	int pitch;
150 	int format;
151 	int width;		/* Texture image coordinates */
152 	int height;
153 	u32 image;
154 } drm_radeon_texture32_t;
155 
compat_radeon_cp_texture(struct drm_device * dev,void * arg,struct drm_file * file_priv)156 static int compat_radeon_cp_texture(struct drm_device *dev, void *arg,
157 				    struct drm_file *file_priv)
158 {
159 	drm_radeon_texture32_t *req32;
160 	drm_radeon_texture_t __user request;
161 	drm_radeon_tex_image32_t *img32;
162 	drm_radeon_tex_image_t __user image;
163 
164 	req32 = arg;
165 	if (req32->image == 0)
166 		return -EINVAL;
167 	img32 = (drm_radeon_tex_image32_t *)(unsigned long)req32->image;
168 
169 	request.offset = req32->offset;
170 	request.pitch = req32->pitch;
171 	request.format = req32->format;
172 	request.width = req32->width;
173 	request.height = req32->height;
174 	request.image = &image;
175 	image.x = img32->x;
176 	image.y = img32->y;
177 	image.width = img32->width;
178 	image.height = img32->height;
179 	image.data = (void *)(unsigned long)img32->data;
180 
181 	return radeon_ioctls[DRM_IOCTL_RADEON_TEXTURE].func(dev, &request, file_priv);
182 }
183 
184 typedef struct drm_radeon_vertex2_32 {
185 	int idx;		/* Index of vertex buffer */
186 	int discard;		/* Client finished with buffer? */
187 	int nr_states;
188 	u32 state;
189 	int nr_prims;
190 	u32 prim;
191 } drm_radeon_vertex2_32_t;
192 
compat_radeon_cp_vertex2(struct drm_device * dev,void * arg,struct drm_file * file_priv)193 static int compat_radeon_cp_vertex2(struct drm_device *dev, void *arg,
194 				    struct drm_file *file_priv)
195 {
196 	drm_radeon_vertex2_32_t *req32;
197 	drm_radeon_vertex2_t __user request;
198 
199 	req32 = arg;
200 
201 	request.idx = req32->idx;
202 	request.discard = req32->discard;
203 	request.nr_states = req32->nr_states;
204 	request.state = (drm_radeon_state_t *)(unsigned long)req32->state;
205 	request.nr_prims = req32->nr_prims;
206 	request.prim = (drm_radeon_prim_t *)(unsigned long)req32->prim;
207 
208 	return radeon_ioctls[DRM_IOCTL_RADEON_VERTEX2].func(dev, &request, file_priv);
209 }
210 
211 typedef struct drm_radeon_cmd_buffer32 {
212 	int bufsz;
213 	u32 buf;
214 	int nbox;
215 	u32 boxes;
216 } drm_radeon_cmd_buffer32_t;
217 
compat_radeon_cp_cmdbuf(struct drm_device * dev,void * arg,struct drm_file * file_priv)218 static int compat_radeon_cp_cmdbuf(struct drm_device *dev, void *arg,
219 				   struct drm_file *file_priv)
220 {
221 	drm_radeon_cmd_buffer32_t *req32;
222 	drm_radeon_cmd_buffer_t __user request;
223 
224 	req32 = arg;
225 
226 	request.bufsz = req32->bufsz;
227 	request.buf = (char *)(unsigned long)req32->buf;
228 	request.nbox = req32->nbox;
229 	request.boxes = (struct drm_clip_rect *)(unsigned long)req32->boxes;
230 
231 	return radeon_ioctls[DRM_IOCTL_RADEON_CMDBUF].func(dev, &request, file_priv);
232 }
233 
234 typedef struct drm_radeon_getparam32 {
235 	int param;
236 	u32 value;
237 } drm_radeon_getparam32_t;
238 
compat_radeon_cp_getparam(struct drm_device * dev,void * arg,struct drm_file * file_priv)239 static int compat_radeon_cp_getparam(struct drm_device *dev, void *arg,
240 				     struct drm_file *file_priv)
241 {
242 	drm_radeon_getparam32_t *req32;
243 	drm_radeon_getparam_t __user request;
244 
245 	req32 = arg;
246 
247 	request.param = req32->param;
248 	request.value = (void *)(unsigned long)req32->value;
249 
250 	return radeon_ioctls[DRM_IOCTL_RADEON_GETPARAM].func(dev, &request, file_priv);
251 }
252 
253 typedef struct drm_radeon_mem_alloc32 {
254 	int region;
255 	int alignment;
256 	int size;
257 	u32 region_offset;	/* offset from start of fb or GART */
258 } drm_radeon_mem_alloc32_t;
259 
compat_radeon_mem_alloc(struct drm_device * dev,void * arg,struct drm_file * file_priv)260 static int compat_radeon_mem_alloc(struct drm_device *dev, void *arg,
261 				   struct drm_file *file_priv)
262 {
263 	drm_radeon_mem_alloc32_t *req32;
264 	drm_radeon_mem_alloc_t __user request;
265 
266 	req32 = arg;
267 
268 	request.region = req32->region;
269 	request.alignment = req32->alignment;
270 	request.size = req32->size;
271 	request.region_offset = (int *)(unsigned long)req32->region_offset;
272 
273 	return radeon_mem_alloc(dev, &request, file_priv);
274 }
275 
276 typedef struct drm_radeon_irq_emit32 {
277 	u32 irq_seq;
278 } drm_radeon_irq_emit32_t;
279 
compat_radeon_irq_emit(struct drm_device * dev,void * arg,struct drm_file * file_priv)280 static int compat_radeon_irq_emit(struct drm_device *dev, void *arg,
281 				  struct drm_file *file_priv)
282 {
283 	drm_radeon_irq_emit32_t *req32;
284 	drm_radeon_irq_emit_t __user request;
285 
286 	req32 = arg;
287 
288 	request.irq_seq = (int *)(unsigned long)req32->irq_seq;
289 
290 	return radeon_irq_emit(dev, &request, file_priv);
291 }
292 
293 /* The two 64-bit arches where alignof(u64)==4 in 32-bit code */
294 #if defined (CONFIG_X86_64) || defined(CONFIG_IA64)
295 typedef struct drm_radeon_setparam32 {
296 	int param;
297 	u64 value;
298 } __attribute__((packed)) drm_radeon_setparam32_t;
299 
compat_radeon_cp_setparam(struct drm_device * dev,void * arg,struct drm_file * file_priv)300 static int compat_radeon_cp_setparam(struct drm_device *dev, void *arg,
301 				     struct drm_file *file_priv)
302 {
303 	drm_radeon_setparam32_t *req32;
304 	drm_radeon_setparam_t __user request;
305 
306 	req32 = arg;
307 
308 	request.param = req32->param;
309 	request.value = req32->value;
310 
311 	return radeon_ioctls[DRM_IOCTL_RADEON_SETPARAM].func(dev, &request, file_priv);
312 }
313 #else
314 #define compat_radeon_cp_setparam NULL
315 #endif /* X86_64 || IA64 */
316 
317 struct drm_ioctl_desc radeon_compat_ioctls[] = {
318 	DRM_IOCTL_DEF(DRM_RADEON_CP_INIT, compat_radeon_cp_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
319 	DRM_IOCTL_DEF(DRM_RADEON_CLEAR, compat_radeon_cp_clear, DRM_AUTH),
320 	DRM_IOCTL_DEF(DRM_RADEON_STIPPLE, compat_radeon_cp_stipple, DRM_AUTH),
321 	DRM_IOCTL_DEF(DRM_RADEON_TEXTURE, compat_radeon_cp_texture, DRM_AUTH),
322 	DRM_IOCTL_DEF(DRM_RADEON_VERTEX2, compat_radeon_cp_vertex2, DRM_AUTH),
323 	DRM_IOCTL_DEF(DRM_RADEON_CMDBUF, compat_radeon_cp_cmdbuf, DRM_AUTH),
324 	DRM_IOCTL_DEF(DRM_RADEON_GETPARAM, compat_radeon_cp_getparam, DRM_AUTH),
325 	DRM_IOCTL_DEF(DRM_RADEON_SETPARAM, compat_radeon_cp_setparam, DRM_AUTH),
326 	DRM_IOCTL_DEF(DRM_RADEON_ALLOC, compat_radeon_mem_alloc, DRM_AUTH),
327 	DRM_IOCTL_DEF(DRM_RADEON_IRQ_EMIT, compat_radeon_irq_emit, DRM_AUTH)
328 };
329 int radeon_num_compat_ioctls = ARRAY_SIZE(radeon_compat_ioctls);
330 
331 #endif
332