1 /* $NetBSD: grf_compat.c,v 1.20 2007/03/05 21:11:04 he Exp $ */
4 * Copyright (C) 1999 Scott Reynolds
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission.
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 * macfb compatibility with legacy grf devices
34 #include <sys/cdefs.h>
35 __KERNEL_RCSID(0, "$NetBSD: grf_compat.c,v 1.20 2007/03/05 21:11:04 he Exp $");
37 #include <sys/param.h>
38 #include <sys/systm.h>
40 #include <sys/device.h>
41 #include <sys/errno.h>
42 #include <sys/ioctl.h>
43 #include <sys/malloc.h>
46 #include <sys/resourcevar.h>
47 #include <sys/vnode.h>
49 #include <machine/autoconf.h>
50 #include <machine/bus.h>
51 #include <machine/grfioctl.h>
53 #include <mac68k/nubus/nubus.h>
54 #include <mac68k/dev/grfvar.h>
55 #include <mac68k/dev/macfbvar.h>
57 #include <miscfs/specfs/specdev.h>
59 #include <uvm/uvm_extern.h>
60 #include <uvm/uvm_map.h>
62 dev_type_open(grfopen
);
63 dev_type_close(grfclose
);
64 dev_type_ioctl(grfioctl
);
65 dev_type_mmap(grfmmap
);
67 const struct cdevsw grf_cdevsw
= {
68 grfopen
, grfclose
, noread
, nowrite
, grfioctl
,
69 nostop
, notty
, nopoll
, grfmmap
, nokqfilter
,
72 void grf_scinit(struct grf_softc
*, const char *, int);
75 int grfmap(dev_t
, struct macfb_softc
*, void **, struct proc
*);
76 int grfunmap(dev_t
, struct macfb_softc
*, void *, struct proc
*);
78 /* Non-private for the benefit of libkvm. */
79 struct grf_softc
*grf_softc
;
83 * Initialize a softc to sane defaults.
86 grf_scinit(struct grf_softc
*sc
, const char *name
, int unit
)
88 memset(sc
, 0, sizeof(struct grf_softc
));
89 snprintf(sc
->sc_xname
, sizeof(sc
->sc_xname
), "%s%d", name
, unit
);
94 * (Re-)initialize the grf_softc block so that at least the requested
95 * number of elements has been allocated. If this results in more
96 * elements than we had prior to getting here, we initialize each of
97 * them to avoid problems down the road.
102 struct grf_softc
*sc
;
109 if (grf_softc
== NULL
)
110 sc
= (struct grf_softc
*)
111 malloc(numgrf
* sizeof(*sc
),
114 sc
= (struct grf_softc
*)
115 realloc(grf_softc
, numgrf
* sizeof(*sc
),
118 printf("WARNING: no memory for grf emulation\n");
119 if (grf_softc
!= NULL
)
120 free(grf_softc
, M_DEVBUF
);
125 /* Initialize per-softc structures. */
127 grf_scinit(&grf_softc
[i
], "grf", i
);
134 * Called by main() during pseudo-device attachment. If we had a
135 * way to configure additional grf devices later, this would actually
136 * allocate enough space for them. As it stands, it's nonsensical,
137 * so other than a basic sanity check we do nothing.
144 panic("grfattach: count <= 0");
149 #if 0 /* XXX someday, if we implement a way to attach after autoconfig */
155 * Called from macfb_attach() after setting up the frame buffer. Since
156 * there is a 1:1 correspondence between the macfb device and the grf
157 * device, the only bit of information we really need is the macfb_softc.
160 grf_attach(struct macfb_softc
*sc
, int unit
)
165 grf_softc
[unit
].mfb_sc
= sc
;
169 * Standard device ops
172 grfopen(dev_t dev
, int flag
, int mode
, struct lwp
*l
)
174 struct grf_softc
*sc
;
175 int unit
= GRFUNIT(dev
);
178 if (grf_softc
== NULL
|| unit
>= numgrf
)
181 sc
= &grf_softc
[unit
];
182 if (sc
->mfb_sc
== NULL
)
189 grfclose(dev_t dev
, int flag
, int mode
, struct lwp
*l
)
191 struct grf_softc
*sc
;
192 int unit
= GRFUNIT(dev
);
195 if (grf_softc
== NULL
|| unit
>= numgrf
)
198 sc
= &grf_softc
[unit
];
199 if (sc
->mfb_sc
!= NULL
)
200 macfb_clear(sc
->mfb_sc
->sc_dc
); /* clear the display */
208 grfioctl(dev_t dev
, u_long cmd
, void *data
, int flag
, struct lwp
*l
)
210 struct grf_softc
*sc
;
211 struct macfb_devconfig
*dc
;
212 #if defined(GRF_COMPAT) || (NGRF > 0)
214 #endif /* GRF_COMPAT || (NGRF > 0) */
216 int unit
= GRFUNIT(dev
);
219 if (grf_softc
== NULL
|| unit
>= numgrf
)
222 sc
= &grf_softc
[unit
];
223 if (sc
->mfb_sc
== NULL
)
226 dc
= sc
->mfb_sc
->sc_dc
;
229 #if defined(GRF_COMPAT) || (NGRF > 0)
231 gd
= (struct grfinfo
*)data
;
232 memset(gd
, 0, sizeof(struct grfinfo
));
233 gd
->gd_fbaddr
= (void *)dc
->dc_paddr
;
234 gd
->gd_fbsize
= dc
->dc_size
;
235 gd
->gd_colors
= (short)(1 << dc
->dc_depth
);
236 gd
->gd_planes
= (short)dc
->dc_depth
;
237 gd
->gd_fbwidth
= dc
->dc_wid
;
238 gd
->gd_fbheight
= dc
->dc_ht
;
239 gd
->gd_fbrowbytes
= dc
->dc_rowbytes
;
240 gd
->gd_dwidth
= dc
->dc_raster
.width
;
241 gd
->gd_dheight
= dc
->dc_raster
.height
;
244 #endif /* GRF_COMPAT || (NGRF > 0) */
252 #if defined(GRF_COMPAT) || (NGRF > 0)
254 rv
= grfmap(dev
, sc
->mfb_sc
, (void **)data
, l
->l_proc
);
258 rv
= grfunmap(dev
, sc
->mfb_sc
, *(void **)data
, l
->l_proc
);
260 #endif /* GRF_COMPAT || (NGRF > 0) */
263 gm
= (struct grfmode
*)data
;
264 memset(gm
, 0, sizeof(struct grfmode
));
265 gm
->fbbase
= (char *)dc
->dc_vaddr
;
266 gm
->fbsize
= dc
->dc_size
;
267 gm
->fboff
= dc
->dc_offset
;
268 gm
->rowbytes
= dc
->dc_rowbytes
;
269 gm
->width
= dc
->dc_wid
;
270 gm
->height
= dc
->dc_ht
;
271 gm
->psize
= dc
->dc_depth
;
275 case GRFIOCLISTMODES
:
278 /* NONE of these operations are (officially) supported. */
287 grfmmap(dev_t dev
, off_t off
, int prot
)
289 struct grf_softc
*sc
;
290 struct macfb_devconfig
*dc
;
291 int unit
= GRFUNIT(dev
);
293 if (grf_softc
== NULL
|| unit
>= numgrf
)
296 sc
= &grf_softc
[unit
];
297 if (sc
->mfb_sc
== NULL
)
300 dc
= sc
->mfb_sc
->sc_dc
;
302 if ((u_int
)off
< m68k_round_page(dc
->dc_offset
+ dc
->dc_size
))
303 return m68k_btop(dc
->dc_paddr
+ off
);
309 grfmap(dev_t dev
, struct macfb_softc
*sc
, void **addrp
, struct proc
*p
)
315 len
= m68k_round_page(sc
->sc_dc
->dc_offset
+ sc
->sc_dc
->dc_size
);
316 *addrp
= (void *)VM_DEFAULT_ADDRESS(p
->p_vmspace
->vm_daddr
, len
);
317 flags
= MAP_SHARED
| MAP_FIXED
;
319 vn
.v_type
= VCHR
; /* XXX */
320 vn
.v_rdev
= dev
; /* XXX */
322 error
= uvm_mmap(&p
->p_vmspace
->vm_map
, (vaddr_t
*)addrp
,
323 (vsize_t
)len
, VM_PROT_ALL
, VM_PROT_ALL
,
324 flags
, (void *)&vn
, 0, p
->p_rlimit
[RLIMIT_MEMLOCK
].rlim_cur
);
326 /* Offset into page: */
327 *addrp
= (char*)*addrp
+ sc
->sc_dc
->dc_offset
;
333 grfunmap(dev_t dev
, struct macfb_softc
*sc
, void *addr
, struct proc
*p
)
337 addr
= (char*)addr
- sc
->sc_dc
->dc_offset
;
342 size
= m68k_round_page(sc
->sc_dc
->dc_offset
+ sc
->sc_dc
->dc_size
);
343 uvm_unmap(&p
->p_vmspace
->vm_map
, (vaddr_t
)addr
, (vaddr_t
)addr
+ size
);