1254885Sdumbbell/**
2254885Sdumbbell * \file radeon_ioc32.c
3254885Sdumbbell *
4254885Sdumbbell * 32-bit ioctl compatibility routines for the Radeon DRM.
5254885Sdumbbell *
6254885Sdumbbell * \author Paul Mackerras <paulus@samba.org>
7254885Sdumbbell *
8254885Sdumbbell * Copyright (C) Paul Mackerras 2005
9254885Sdumbbell * All Rights Reserved.
10254885Sdumbbell *
11254885Sdumbbell * Permission is hereby granted, free of charge, to any person obtaining a
12254885Sdumbbell * copy of this software and associated documentation files (the "Software"),
13254885Sdumbbell * to deal in the Software without restriction, including without limitation
14254885Sdumbbell * the rights to use, copy, modify, merge, publish, distribute, sublicense,
15254885Sdumbbell * and/or sell copies of the Software, and to permit persons to whom the
16254885Sdumbbell * Software is furnished to do so, subject to the following conditions:
17254885Sdumbbell *
18254885Sdumbbell * The above copyright notice and this permission notice (including the next
19254885Sdumbbell * paragraph) shall be included in all copies or substantial portions of the
20254885Sdumbbell * Software.
21254885Sdumbbell *
22254885Sdumbbell * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23254885Sdumbbell * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24254885Sdumbbell * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
25254885Sdumbbell * THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
26254885Sdumbbell * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27254885Sdumbbell * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
28254885Sdumbbell * IN THE SOFTWARE.
29254885Sdumbbell */
30254885Sdumbbell
31254885Sdumbbell#include <sys/cdefs.h>
32254885Sdumbbell__FBSDID("$FreeBSD$");
33254885Sdumbbell
34267430Sdumbbell#include "opt_compat.h"
35254885Sdumbbell
36267430Sdumbbell#ifdef COMPAT_FREEBSD32
37267430Sdumbbell
38267430Sdumbbell#include <dev/drm2/drmP.h>
39267430Sdumbbell#include <dev/drm2/drm.h>
40267430Sdumbbell#include <dev/drm2/radeon/radeon_drm.h>
41254885Sdumbbell#include "radeon_drv.h"
42254885Sdumbbell
43254885Sdumbbelltypedef struct drm_radeon_init32 {
44254885Sdumbbell	int func;
45254885Sdumbbell	u32 sarea_priv_offset;
46254885Sdumbbell	int is_pci;
47254885Sdumbbell	int cp_mode;
48254885Sdumbbell	int gart_size;
49254885Sdumbbell	int ring_size;
50254885Sdumbbell	int usec_timeout;
51254885Sdumbbell
52254885Sdumbbell	unsigned int fb_bpp;
53254885Sdumbbell	unsigned int front_offset, front_pitch;
54254885Sdumbbell	unsigned int back_offset, back_pitch;
55254885Sdumbbell	unsigned int depth_bpp;
56254885Sdumbbell	unsigned int depth_offset, depth_pitch;
57254885Sdumbbell
58254885Sdumbbell	u32 fb_offset;
59254885Sdumbbell	u32 mmio_offset;
60254885Sdumbbell	u32 ring_offset;
61254885Sdumbbell	u32 ring_rptr_offset;
62254885Sdumbbell	u32 buffers_offset;
63254885Sdumbbell	u32 gart_textures_offset;
64254885Sdumbbell} drm_radeon_init32_t;
65254885Sdumbbell
66267430Sdumbbellstatic int compat_radeon_cp_init(struct drm_device *dev, void *arg,
67267430Sdumbbell				 struct drm_file *file_priv)
68254885Sdumbbell{
69267430Sdumbbell	drm_radeon_init32_t *init32;
70267430Sdumbbell	drm_radeon_init_t __user init;
71254885Sdumbbell
72267430Sdumbbell	init32 = arg;
73254885Sdumbbell
74267430Sdumbbell	init.func = init32->func;
75267430Sdumbbell	init.sarea_priv_offset = (unsigned long)init32->sarea_priv_offset;
76267430Sdumbbell	init.is_pci = init32->is_pci;
77267430Sdumbbell	init.cp_mode = init32->cp_mode;
78267430Sdumbbell	init.gart_size = init32->gart_size;
79267430Sdumbbell	init.ring_size = init32->ring_size;
80267430Sdumbbell	init.usec_timeout = init32->usec_timeout;
81267430Sdumbbell	init.fb_bpp = init32->fb_bpp;
82267430Sdumbbell	init.front_offset = init32->front_offset;
83267430Sdumbbell	init.front_pitch = init32->front_pitch;
84267430Sdumbbell	init.back_offset = init32->back_offset;
85267430Sdumbbell	init.back_pitch = init32->back_pitch;
86267430Sdumbbell	init.depth_bpp = init32->depth_bpp;
87267430Sdumbbell	init.depth_offset = init32->depth_offset;
88267430Sdumbbell	init.depth_pitch = init32->depth_pitch;
89267430Sdumbbell	init.fb_offset = (unsigned long)init32->fb_offset;
90267430Sdumbbell	init.mmio_offset = (unsigned long)init32->mmio_offset;
91267430Sdumbbell	init.ring_offset = (unsigned long)init32->ring_offset;
92267430Sdumbbell	init.ring_rptr_offset = (unsigned long)init32->ring_rptr_offset;
93267430Sdumbbell	init.buffers_offset = (unsigned long)init32->buffers_offset;
94267430Sdumbbell	init.gart_textures_offset = (unsigned long)init32->gart_textures_offset;
95254885Sdumbbell
96267430Sdumbbell	return radeon_cp_init(dev, &init, file_priv);
97254885Sdumbbell}
98254885Sdumbbell
99254885Sdumbbelltypedef struct drm_radeon_clear32 {
100254885Sdumbbell	unsigned int flags;
101254885Sdumbbell	unsigned int clear_color;
102254885Sdumbbell	unsigned int clear_depth;
103254885Sdumbbell	unsigned int color_mask;
104254885Sdumbbell	unsigned int depth_mask;	/* misnamed field:  should be stencil */
105254885Sdumbbell	u32 depth_boxes;
106254885Sdumbbell} drm_radeon_clear32_t;
107254885Sdumbbell
108267430Sdumbbellstatic int compat_radeon_cp_clear(struct drm_device *dev, void *arg,
109267430Sdumbbell				  struct drm_file *file_priv)
110254885Sdumbbell{
111267430Sdumbbell	drm_radeon_clear32_t *clr32;
112267430Sdumbbell	drm_radeon_clear_t __user clr;
113254885Sdumbbell
114267430Sdumbbell	clr32 = arg;
115254885Sdumbbell
116267430Sdumbbell	clr.flags = clr32->flags;
117267430Sdumbbell	clr.clear_color = clr32->clear_color;
118267430Sdumbbell	clr.clear_depth = clr32->clear_depth;
119267430Sdumbbell	clr.color_mask = clr32->color_mask;
120267430Sdumbbell	clr.depth_mask = clr32->depth_mask;
121267430Sdumbbell	clr.depth_boxes = (drm_radeon_clear_rect_t *)(unsigned long)clr32->depth_boxes;
122254885Sdumbbell
123267430Sdumbbell	return radeon_ioctls[DRM_IOCTL_RADEON_CLEAR].func(dev, &clr, file_priv);
124254885Sdumbbell}
125254885Sdumbbell
126254885Sdumbbelltypedef struct drm_radeon_stipple32 {
127254885Sdumbbell	u32 mask;
128254885Sdumbbell} drm_radeon_stipple32_t;
129254885Sdumbbell
130267430Sdumbbellstatic int compat_radeon_cp_stipple(struct drm_device *dev, void *arg,
131267430Sdumbbell				    struct drm_file *file_priv)
132254885Sdumbbell{
133254885Sdumbbell	drm_radeon_stipple32_t __user *argp = (void __user *)arg;
134267430Sdumbbell	drm_radeon_stipple_t __user request;
135254885Sdumbbell
136267430Sdumbbell	request.mask = (unsigned int *)(unsigned long)argp->mask;
137254885Sdumbbell
138267430Sdumbbell	return radeon_ioctls[DRM_IOCTL_RADEON_STIPPLE].func(dev, &request, file_priv);
139254885Sdumbbell}
140254885Sdumbbell
141254885Sdumbbelltypedef struct drm_radeon_tex_image32 {
142254885Sdumbbell	unsigned int x, y;	/* Blit coordinates */
143254885Sdumbbell	unsigned int width, height;
144254885Sdumbbell	u32 data;
145254885Sdumbbell} drm_radeon_tex_image32_t;
146254885Sdumbbell
147254885Sdumbbelltypedef struct drm_radeon_texture32 {
148254885Sdumbbell	unsigned int offset;
149254885Sdumbbell	int pitch;
150254885Sdumbbell	int format;
151254885Sdumbbell	int width;		/* Texture image coordinates */
152254885Sdumbbell	int height;
153254885Sdumbbell	u32 image;
154254885Sdumbbell} drm_radeon_texture32_t;
155254885Sdumbbell
156267430Sdumbbellstatic int compat_radeon_cp_texture(struct drm_device *dev, void *arg,
157267430Sdumbbell				    struct drm_file *file_priv)
158254885Sdumbbell{
159267430Sdumbbell	drm_radeon_texture32_t *req32;
160267430Sdumbbell	drm_radeon_texture_t __user request;
161267430Sdumbbell	drm_radeon_tex_image32_t *img32;
162267430Sdumbbell	drm_radeon_tex_image_t __user image;
163254885Sdumbbell
164267430Sdumbbell	req32 = arg;
165267430Sdumbbell	if (req32->image == 0)
166254885Sdumbbell		return -EINVAL;
167267430Sdumbbell	img32 = (drm_radeon_tex_image32_t *)(unsigned long)req32->image;
168254885Sdumbbell
169267430Sdumbbell	request.offset = req32->offset;
170267430Sdumbbell	request.pitch = req32->pitch;
171267430Sdumbbell	request.format = req32->format;
172267430Sdumbbell	request.width = req32->width;
173267430Sdumbbell	request.height = req32->height;
174267430Sdumbbell	request.image = &image;
175267430Sdumbbell	image.x = img32->x;
176267430Sdumbbell	image.y = img32->y;
177267430Sdumbbell	image.width = img32->width;
178267430Sdumbbell	image.height = img32->height;
179267430Sdumbbell	image.data = (void *)(unsigned long)img32->data;
180254885Sdumbbell
181267430Sdumbbell	return radeon_ioctls[DRM_IOCTL_RADEON_TEXTURE].func(dev, &request, file_priv);
182254885Sdumbbell}
183254885Sdumbbell
184254885Sdumbbelltypedef struct drm_radeon_vertex2_32 {
185254885Sdumbbell	int idx;		/* Index of vertex buffer */
186254885Sdumbbell	int discard;		/* Client finished with buffer? */
187254885Sdumbbell	int nr_states;
188254885Sdumbbell	u32 state;
189254885Sdumbbell	int nr_prims;
190254885Sdumbbell	u32 prim;
191254885Sdumbbell} drm_radeon_vertex2_32_t;
192254885Sdumbbell
193267430Sdumbbellstatic int compat_radeon_cp_vertex2(struct drm_device *dev, void *arg,
194267430Sdumbbell				    struct drm_file *file_priv)
195254885Sdumbbell{
196267430Sdumbbell	drm_radeon_vertex2_32_t *req32;
197267430Sdumbbell	drm_radeon_vertex2_t __user request;
198254885Sdumbbell
199267430Sdumbbell	req32 = arg;
200254885Sdumbbell
201267430Sdumbbell	request.idx = req32->idx;
202267430Sdumbbell	request.discard = req32->discard;
203267430Sdumbbell	request.nr_states = req32->nr_states;
204267430Sdumbbell	request.state = (drm_radeon_state_t *)(unsigned long)req32->state;
205267430Sdumbbell	request.nr_prims = req32->nr_prims;
206267430Sdumbbell	request.prim = (drm_radeon_prim_t *)(unsigned long)req32->prim;
207254885Sdumbbell
208267430Sdumbbell	return radeon_ioctls[DRM_IOCTL_RADEON_VERTEX2].func(dev, &request, file_priv);
209254885Sdumbbell}
210254885Sdumbbell
211254885Sdumbbelltypedef struct drm_radeon_cmd_buffer32 {
212254885Sdumbbell	int bufsz;
213254885Sdumbbell	u32 buf;
214254885Sdumbbell	int nbox;
215254885Sdumbbell	u32 boxes;
216254885Sdumbbell} drm_radeon_cmd_buffer32_t;
217254885Sdumbbell
218267430Sdumbbellstatic int compat_radeon_cp_cmdbuf(struct drm_device *dev, void *arg,
219267430Sdumbbell				   struct drm_file *file_priv)
220254885Sdumbbell{
221267430Sdumbbell	drm_radeon_cmd_buffer32_t *req32;
222267430Sdumbbell	drm_radeon_cmd_buffer_t __user request;
223254885Sdumbbell
224267430Sdumbbell	req32 = arg;
225254885Sdumbbell
226267430Sdumbbell	request.bufsz = req32->bufsz;
227267430Sdumbbell	request.buf = (char *)(unsigned long)req32->buf;
228267430Sdumbbell	request.nbox = req32->nbox;
229267430Sdumbbell	request.boxes = (struct drm_clip_rect *)(unsigned long)req32->boxes;
230254885Sdumbbell
231267430Sdumbbell	return radeon_ioctls[DRM_IOCTL_RADEON_CMDBUF].func(dev, &request, file_priv);
232254885Sdumbbell}
233254885Sdumbbell
234254885Sdumbbelltypedef struct drm_radeon_getparam32 {
235254885Sdumbbell	int param;
236254885Sdumbbell	u32 value;
237254885Sdumbbell} drm_radeon_getparam32_t;
238254885Sdumbbell
239267430Sdumbbellstatic int compat_radeon_cp_getparam(struct drm_device *dev, void *arg,
240267430Sdumbbell				     struct drm_file *file_priv)
241254885Sdumbbell{
242267430Sdumbbell	drm_radeon_getparam32_t *req32;
243267430Sdumbbell	drm_radeon_getparam_t __user request;
244254885Sdumbbell
245267430Sdumbbell	req32 = arg;
246254885Sdumbbell
247267430Sdumbbell	request.param = req32->param;
248267430Sdumbbell	request.value = (void *)(unsigned long)req32->value;
249254885Sdumbbell
250267430Sdumbbell	return radeon_ioctls[DRM_IOCTL_RADEON_GETPARAM].func(dev, &request, file_priv);
251254885Sdumbbell}
252254885Sdumbbell
253254885Sdumbbelltypedef struct drm_radeon_mem_alloc32 {
254254885Sdumbbell	int region;
255254885Sdumbbell	int alignment;
256254885Sdumbbell	int size;
257254885Sdumbbell	u32 region_offset;	/* offset from start of fb or GART */
258254885Sdumbbell} drm_radeon_mem_alloc32_t;
259254885Sdumbbell
260267430Sdumbbellstatic int compat_radeon_mem_alloc(struct drm_device *dev, void *arg,
261267430Sdumbbell				   struct drm_file *file_priv)
262254885Sdumbbell{
263267430Sdumbbell	drm_radeon_mem_alloc32_t *req32;
264267430Sdumbbell	drm_radeon_mem_alloc_t __user request;
265254885Sdumbbell
266267430Sdumbbell	req32 = arg;
267254885Sdumbbell
268267430Sdumbbell	request.region = req32->region;
269267430Sdumbbell	request.alignment = req32->alignment;
270267430Sdumbbell	request.size = req32->size;
271267430Sdumbbell	request.region_offset = (int *)(unsigned long)req32->region_offset;
272254885Sdumbbell
273267430Sdumbbell	return radeon_mem_alloc(dev, &request, file_priv);
274254885Sdumbbell}
275254885Sdumbbell
276254885Sdumbbelltypedef struct drm_radeon_irq_emit32 {
277254885Sdumbbell	u32 irq_seq;
278254885Sdumbbell} drm_radeon_irq_emit32_t;
279254885Sdumbbell
280267430Sdumbbellstatic int compat_radeon_irq_emit(struct drm_device *dev, void *arg,
281267430Sdumbbell				  struct drm_file *file_priv)
282254885Sdumbbell{
283267430Sdumbbell	drm_radeon_irq_emit32_t *req32;
284267430Sdumbbell	drm_radeon_irq_emit_t __user request;
285254885Sdumbbell
286267430Sdumbbell	req32 = arg;
287254885Sdumbbell
288267430Sdumbbell	request.irq_seq = (int *)(unsigned long)req32->irq_seq;
289254885Sdumbbell
290267430Sdumbbell	return radeon_irq_emit(dev, &request, file_priv);
291254885Sdumbbell}
292254885Sdumbbell
293254885Sdumbbell/* The two 64-bit arches where alignof(u64)==4 in 32-bit code */
294254885Sdumbbelltypedef struct drm_radeon_setparam32 {
295254885Sdumbbell	int param;
296254885Sdumbbell	u64 value;
297254885Sdumbbell} __attribute__((packed)) drm_radeon_setparam32_t;
298254885Sdumbbell
299267430Sdumbbellstatic int compat_radeon_cp_setparam(struct drm_device *dev, void *arg,
300267430Sdumbbell				     struct drm_file *file_priv)
301254885Sdumbbell{
302267430Sdumbbell	drm_radeon_setparam32_t *req32;
303267430Sdumbbell	drm_radeon_setparam_t __user request;
304254885Sdumbbell
305267430Sdumbbell	req32 = arg;
306254885Sdumbbell
307267430Sdumbbell	request.param = req32->param;
308267430Sdumbbell	request.value = req32->value;
309254885Sdumbbell
310267430Sdumbbell	return radeon_ioctls[DRM_IOCTL_RADEON_SETPARAM].func(dev, &request, file_priv);
311254885Sdumbbell}
312254885Sdumbbell
313267430Sdumbbellstruct drm_ioctl_desc radeon_compat_ioctls[] = {
314267430Sdumbbell	DRM_IOCTL_DEF(DRM_RADEON_CP_INIT, compat_radeon_cp_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
315267430Sdumbbell	DRM_IOCTL_DEF(DRM_RADEON_CLEAR, compat_radeon_cp_clear, DRM_AUTH),
316267430Sdumbbell	DRM_IOCTL_DEF(DRM_RADEON_STIPPLE, compat_radeon_cp_stipple, DRM_AUTH),
317267430Sdumbbell	DRM_IOCTL_DEF(DRM_RADEON_TEXTURE, compat_radeon_cp_texture, DRM_AUTH),
318267430Sdumbbell	DRM_IOCTL_DEF(DRM_RADEON_VERTEX2, compat_radeon_cp_vertex2, DRM_AUTH),
319267430Sdumbbell	DRM_IOCTL_DEF(DRM_RADEON_CMDBUF, compat_radeon_cp_cmdbuf, DRM_AUTH),
320267430Sdumbbell	DRM_IOCTL_DEF(DRM_RADEON_GETPARAM, compat_radeon_cp_getparam, DRM_AUTH),
321267430Sdumbbell	DRM_IOCTL_DEF(DRM_RADEON_SETPARAM, compat_radeon_cp_setparam, DRM_AUTH),
322267430Sdumbbell	DRM_IOCTL_DEF(DRM_RADEON_ALLOC, compat_radeon_mem_alloc, DRM_AUTH),
323267430Sdumbbell	DRM_IOCTL_DEF(DRM_RADEON_IRQ_EMIT, compat_radeon_irq_emit, DRM_AUTH)
324254885Sdumbbell};
325267430Sdumbbellint radeon_num_compat_ioctls = DRM_ARRAY_SIZE(radeon_compat_ioctls);
326254885Sdumbbell
327267430Sdumbbell#endif
328