Sync usage with man page.
[netbsd-mini2440.git] / sys / compat / darwin / darwin_ioframebuffer.c
blobb277de1ce5a825e8dc8c56a4b41e7985e5a899eb
1 /* $NetBSD: darwin_ioframebuffer.c,v 1.42 2009/03/14 21:04:18 dsl Exp $ */
3 /*-
4 * Copyright (c) 2003 The NetBSD Foundation, Inc.
5 * All rights reserved.
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Emmanuel Dreyfus.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
32 #include <sys/cdefs.h>
33 __KERNEL_RCSID(0, "$NetBSD: darwin_ioframebuffer.c,v 1.42 2009/03/14 21:04:18 dsl Exp $");
35 #include <sys/types.h>
36 #include <sys/param.h>
37 #include <sys/systm.h>
38 #include <sys/queue.h>
39 #include <sys/malloc.h>
40 #include <sys/conf.h>
41 #include <sys/signal.h>
42 #include <sys/mount.h>
43 #include <sys/proc.h>
44 #include <sys/mman.h>
45 #include <sys/vnode.h>
46 #include <sys/resourcevar.h>
47 #include <sys/device.h>
49 #include <uvm/uvm_extern.h>
50 #include <uvm/uvm_object.h>
51 #include <uvm/uvm_device.h>
52 #include <uvm/uvm_map.h>
53 #include <uvm/uvm.h>
55 #include <dev/wscons/wsconsio.h>
56 #include <dev/wscons/wsdisplayvar.h>
58 #include <compat/sys/signal.h>
60 #include <compat/common/compat_util.h>
62 #include <compat/mach/mach_types.h>
63 #include <compat/mach/mach_exec.h>
64 #include <compat/mach/mach_message.h>
65 #include <compat/mach/mach_port.h>
66 #include <compat/mach/mach_errno.h>
67 #include <compat/mach/mach_iokit.h>
69 #include <compat/darwin/darwin_exec.h>
70 #include <compat/darwin/darwin_iokit.h>
71 #include <compat/darwin/darwin_sysctl.h>
72 #include <compat/darwin/darwin_ioframebuffer.h>
74 #include "ioconf.h"
75 #include "wsdisplay.h"
77 /* Redefined from sys/dev/wscons/wsdisplay.c */
78 extern const struct cdevsw wsdisplay_cdevsw;
80 #define WSDISPLAYMINOR(unit, screen) (((unit) << 8) | (screen))
82 static int darwin_findscreen(dev_t *, int, int);
84 static struct uvm_object *darwin_ioframebuffer_shmem = NULL;
85 static void darwin_ioframebuffer_shmeminit(vaddr_t);
87 /* This is ugly, but we hope to see it going away quickly */
89 static char darwin_iofbconfig[] = "<dict ID=\"0\"><key>IOFBModes</key><array ID=\"1\"><dict ID=\"2\"><key>AID</key><integer size=\"32\" ID=\"3\">0xee</integer><key>DM</key><data ID=\"4\">AAACAAAAAYAAMgAAAAAAAgAQAAAAAAAAAAAAAAAAAAAAAAAA</data><key>ID</key><integer size=\"32\" ID=\"5\">0x3e</integer></dict><dict ID=\"6\"><key>AID</key><integer size=\"32\" ID=\"7\">0x82</integer><key>DM</key><data ID=\"8\">AAACAAAAAYAAPAAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAA</data><key>ID</key><integer size=\"32\" ID=\"9\">0x3</integer></dict><dict ID=\"10\"><key>AID</key><integer size=\"32\" ID=\"11\">0xe8</integer><key>DM</key><data ID=\"12\">AAACAAAAAYAAPAAAAAAAAgAQAAAAAAAAAAAAAAAAAAAAAAAA</data><key>ID</key><integer size=\"32\" ID=\"13\">0x37</integer></dict><dict ID=\"14\"><key>DM</key><data ID=\"15\">AAACAAAAAYAARgAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAA</data><key>ID</key><integer size=\"32\" ID=\"16\">0x5</integer></dict><dict ID=\"17\"><key>AID</key><reference IDREF=\"11\"/><key>DM</key><data ID=\"18\">AAACgAAAAeAAPAAAAAAAAgAQAAAAAAAAAAAAAAAAAAAAAAAA</data><key>ID</key><integer size=\"32\" ID=\"19\">0x38</integer></dict><dict ID=\"20\"><key>AID</key><reference IDREF=\"3\"/><key>DM</key><data ID=\"21\">AAACgAAAAeAAMgAAAAAAAgAQAAAAAAAAAAAAAAAAAAAAAAAA</data><key>ID</key><integer size=\"32\" ID=\"22\">0x3f</integer></dict><dict ID=\"23\"><key>AID</key><integer size=\"32\" ID=\"24\">0x96</integer><key>DM</key><data ID=\"25\">AAACgAAAAeAAPAAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAA</data><key>ID</key><integer size=\"32\" ID=\"26\">0x6</integer></dict><dict ID=\"27\"><key>AID</key><integer size=\"32\" ID=\"28\">0x8c</integer><key>DM</key><data ID=\"29\">AAACgAAAAeAAQwAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAA</data><key>ID</key><integer size=\"32\" ID=\"30\">0x7</integer></dict><dict ID=\"31\"><key>AID</key><integer size=\"32\" ID=\"32\">0x98</integer><key>DM</key><data ID=\"33\">AAACgAAAAeAASAAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAA</data><key>ID</key><integer size=\"32\" ID=\"34\">0x8</integer></dict><dict ID=\"35\"><key>AID</key><integer size=\"32\" ID=\"36\">0x9a</integer><key>DM</key><data ID=\"37\">AAACgAAAAeAASwAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAA</data><key>ID</key><integer size=\"32\" ID=\"38\">0x9</integer></dict><dict ID=\"39\"><key>AID</key><integer size=\"32\" ID=\"40\">0x9e</integer><key>DM</key><data ID=\"41\">AAACgAAAAeAAVQAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAA</data><key>ID</key><integer size=\"32\" ID=\"42\">0xa</integer></dict><dict ID=\"43\"><key>AID</key><integer size=\"32\" ID=\"44\">0xa0</integer><key>DM</key><data ID=\"45\">AAACgAAAA2YASwAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAA</data><key>ID</key><integer size=\"32\" ID=\"46\">0xe</integer></dict><dict ID=\"47\"><key>AID</key><reference IDREF=\"3\"/><key>DM</key><data ID=\"48\">AAAC0AAAAeAAMgAAAAAAAgAQAAAAAAAAAAAAAAAAAAAAAAAA</data><key>ID</key><integer size=\"32\" ID=\"49\">0x4b</integer></dict><dict ID=\"50\"><key>AID</key><reference IDREF=\"11\"/><key>DM</key><data ID=\"51\">AAAC0AAAAeAAPAAAAAAAAgAQAAAAAAAAAAAAAAAAAAAAAAAA</data><key>ID</key><integer size=\"32\" ID=\"52\">0x4d</integer></dict><dict ID=\"53\"><key>AID</key><reference IDREF=\"3\"/><key>DM</key><data ID=\"54\">AAAC0AAAAkAAMgAAAAAAAgAQAAAAAAAAAAAAAAAAAAAAAAAA</data><key>ID</key><integer size=\"32\" ID=\"55\">0x4c</integer></dict><dict ID=\"56\"><key>AID</key><reference IDREF=\"11\"/><key>DM</key><data ID=\"57\">AAAC0AAAAkAAPAAAAAAAAgAQAAAAAAAAAAAAAAAAAAAAAAAA</data><key>ID</key><integer size=\"32\" ID=\"58\">0x4e</integer></dict><dict ID=\"59\"><key>AID</key><reference IDREF=\"3\"/><key>DM</key><data ID=\"60\">AAADIAAAAlgAMgAAAAAAAgAQAAAAAAAAAAAAAAAAAAAAAAAA</data><key>ID</key><integer size=\"32\" ID=\"61\">0x40</integer></dict><dict ID=\"62\"><key>AID</key><integer size=\"32\" ID=\"63\">0xb4</integer><key>DM</key><data ID=\"64\">AAADIAAAAlgAOAAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAA</data><key>ID</key><integer size=\"32\" ID=\"65\">0xf</integer></dict><dict ID=\"66\"><key>AID</key><integer size=\"32\" ID=\"67\">0xb6</integer><key>DM</key><data ID=\"68\">AAADIAAAAlgAPAAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAA</data><key>ID</key><integer size=\"32\" ID=\"69\">0x10</integer></dict><dict ID=\"70\"><key>AID</key><reference IDREF=\"11\"/><key>DM</key><data ID=\"71\">AAADIAAAAlgAPAAAAAAAAgAQAAAAAAAAAAAAAAAAAAAAAAAA</data><key>ID</key><integer size=\"32\" ID=\"72\">0x39</integer></dict><dict ID=\"73\"><key>AID</key><integer size=\"32\" ID=\"74\">0x2a</integer><key>ID</key><integer size=\"32\" ID=\"75\">0x2d</integer><key>DF</key><integer size=\"32\" ID=\"76\">0x400</integer><key>DM</key><data ID=\"77\">AAADIAAAAlgAAAAAAAAAAgAABAAAAAAAAAAAAAAAAAAAAAAA</data></dict><dict ID=\"78\"><key>DF</key><integer size=\"32\" ID=\"79\">0x100</integer><key>DM</key><data ID=\"80\">AAADIAAAAlgAPAAAAAAAAgAAAQAAAAAAAAAAAAAAAAAAAAAA</data><key>ID</key><integer size=\"32\" ID=\"81\">0x32</integer></dict><dict ID=\"82\"><key>AID</key><integer size=\"32\" ID=\"83\">0xb8</integer><key>DM</key><data ID=\"84\">AAADIAAAAlgASAAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAA</data><key>ID</key><integer size=\"32\" ID=\"85\">0x11</integer></dict><dict ID=\"86\"><key>AID</key><integer size=\"32\" ID=\"87\">0xba</integer><key>DM</key><data ID=\"88\">AAADIAAAAlgASwAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAA</data><key>ID</key><integer size=\"32\" ID=\"89\">0x12</integer></dict><dict ID=\"90\"><key>AID</key><reference IDREF=\"74\"/><key>ID</key><integer size=\"32\" ID=\"91\">0x46</integer><key>DF</key><reference IDREF=\"76\"/><key>DM</key><reference IDREF=\"77\"/></dict><dict ID=\"92\"><key>AID</key><integer size=\"32\" ID=\"93\">0xbc</integer><key>DM</key><data ID=\"94\">AAADIAAAAlgAVQAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAA</data><key>ID</key><integer size=\"32\" ID=\"95\">0x13</integer></dict><dict ID=\"96\"><key>AID</key><reference IDREF=\"3\"/><key>DM</key><data ID=\"97\">AAADQAAAAnAAMgAAAAAAAgAQAAAAAAAAAAAAAAAAAAAAAAAA</data><key>ID</key><integer size=\"32\" ID=\"98\">0x41</integer></dict><dict ID=\"99\"><key>AID</key><reference IDREF=\"11\"/><key>DM</key><data ID=\"100\">AAADQAAAAnAAPAAAAAAAAgAQAAAAAAAAAAAAAAAAAAAAAAAA</data><key>ID</key><integer size=\"32\" ID=\"101\">0x3a</integer></dict><dict ID=\"102\"><key>AID</key><integer size=\"32\" ID=\"103\">0xaa</integer><key>DM</key><data ID=\"104\">AAADQAAAAnAASwAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAA</data><key>ID</key><integer size=\"32\" ID=\"105\">0x17</integer></dict><dict ID=\"106\"><key>DM</key><data ID=\"107\">AAADVAAAAoAAPAAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAA</data><key>ID</key><integer size=\"32\" ID=\"108\">0x18</integer></dict><dict ID=\"109\"><key>AID</key><integer size=\"32\" ID=\"110\">0xbe</integer><key>DM</key><data ID=\"111\">AAAEAAAAAwAAPAAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAA</data><key>ID</key><integer size=\"32\" ID=\"112\">0x19</integer></dict><dict ID=\"113\"><key>AID</key><reference IDREF=\"74\"/><key>ID</key><integer size=\"32\" ID=\"114\">0x2e</integer><key>DF</key><integer size=\"32\" ID=\"115\">0x407</integer><key>DM</key><data ID=\"116\">AAAEAAAAAwAAAAAAAAAAAgAABAcAAAAAAAAAAAAAAAAAAAAA</data></dict><dict ID=\"117\"><key>AID</key><reference IDREF=\"110\"/><key>ID</key><integer size=\"32\" ID=\"118\">0x33</integer><key>DF</key><reference IDREF=\"79\"/><key>DM</key><data ID=\"119\">AAAEAAAAAwAAPAAAAAAAAgAAAQAAAAAAAAAAAAAAAAAAAAAA</data></dict><dict ID=\"120\"><key>AID</key><integer size=\"32\" ID=\"121\">0xc8</integer><key>DM</key><data ID=\"122\">AAAEAAAAAwAARgAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAA</data><key>ID</key><integer size=\"32\" ID=\"123\">0x1a</integer></dict><dict ID=\"124\"><key>AID</key><integer size=\"32\" ID=\"125\">0xcc</integer><key>DM</key><data ID=\"126\">AAAEAAAAAwAASwAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAA</data><key>ID</key><integer size=\"32\" ID=\"127\">0x1b</integer></dict><dict ID=\"128\"><key>AID</key><integer size=\"32\" ID=\"129\">0xd2</integer><key>DM</key><reference IDREF=\"126\"/><key>ID</key><integer size=\"32\" ID=\"130\">0x1c</integer></dict><dict ID=\"131\"><key>AID</key><integer size=\"32\" ID=\"132\">0xd0</integer><key>DM</key><data ID=\"133\">AAAEAAAAAwAAVQAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAA</data><key>ID</key><integer size=\"32\" ID=\"134\">0x1d</integer></dict><dict ID=\"135\"><key>AID</key><integer size=\"32\" ID=\"136\">0xdc</integer><key>DM</key><data ID=\"137\">AAAEgAAAA2YASwAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAA</data><key>ID</key><integer size=\"32\" ID=\"138\">0x21</integer></dict><dict ID=\"139\"><key>AID</key><integer size=\"32\" ID=\"140\">0xfa</integer><key>DM</key><data ID=\"141\">AAAFAAAAA8AASwAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAA</data><key>ID</key><integer size=\"32\" ID=\"142\">0x22</integer></dict><dict ID=\"143\"><key>AID</key><integer size=\"32\" ID=\"144\">0x104</integer><key>DM</key><data ID=\"145\">AAAFAAAABAAAPAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAA</data><key>ID</key><integer size=\"32\" ID=\"146\">0x23</integer></dict><dict ID=\"147\"><key>AID</key><integer size=\"32\" ID=\"148\">0x106</integer><key>DM</key><data ID=\"149\">AAAFAAAABAAASwAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAA</data><key>ID</key><integer size=\"32\" ID=\"150\">0x24</integer></dict></array><key>IODisplayConnectFlags</key><integer size=\"32\" ID=\"151\">0x0</integer></dict>";
91 static char darwin_ioframebuffer_properties[] = "<dict ID=\"0\"><key>IOClass</key><string ID=\"1\">AppleBacklightDisplay</string><key>IOProbeScore</key><integer size=\"32\" ID=\"2\">0xbb8</integer><key>IOProviderClass</key><string ID=\"3\">IODisplayConnect</string><key>CFBundleIdentifier</key><string ID=\"4\">com.apple.iokit.IOGraphicsFamily</string><key>IOMatchCategory</key><string ID=\"5\">IODefaultMatchCategory</string><key>IODisplayConnectFlags</key><data ID=\"6\">AAAIxA==</data><key>AppleDisplayType</key><integer size=\"32\" ID=\"7\">0x2</integer><key>AppleSense</key><integer size=\"32\" ID=\"8\">0x400</integer><key>DisplayVendorID</key><integer size=\"32\" ID=\"9\">0x756e6b6e</integer><key>DisplayProductID</key><integer size=\"32\" ID=\"10\">0x20000</integer><key>IODisplayParameters</key><dict ID=\"11\"><key>brightness</key><dict ID=\"12\"><key>max</key><integer size=\"32\" ID=\"13\">0x73</integer><key>min</key><integer size=\"32\" ID=\"14\">0x3a</integer><key>value</key><integer size=\"32\" ID=\"15\">0x7f</integer></dict><key>commit</key><dict ID=\"16\"><key>reg</key><integer size=\"32\" ID=\"17\">0x0</integer></dict></dict><key>IODisplayGUID</key><integer size=\"64\" ID=\"18\">0x610000000000000</integer><key>Power Management protected data</key><string ID=\"19\">{ theNumberOfPowerStates = 4, version 1, power state 0 = { capabilityFlags 00000000, outputPowerCharacter 00000000, inputPowerRequirement 00000000, staticPower 0, unbudgetedPower 0, powerToAttain 0, timeToAttain 0, settleUpTime 0, timeToLower 0, settleDownTime 0, powerDomainBudget 0 }, power state 1 = { capabilityFlags 00000000, outputPowerCharacter 00000000, inputPowerRequirement 00000000, staticPower 0, unbudgetedPower 0, powerToAttain 0, timeToAttain 0, settleUpTime 0, timeToLower 0, settleDownTime 0, powerDomainBudget 0 }, power state 2 = { capabilityFlags 00008000, outputPowerCharacter 00000000, inputPowerRequirement 00000002, staticPower 0, unbudgetedPower 0, powerToAttain 0, timeToAttain 0, settleUpTime 0, timeToLower 0, settleDownTime 0, powerDomainBudget 0 }, power state 3 = { capabilityFlags 0000c000, outputPowerCharacter 00000000, inputPowerRequirement 00000002, staticPower 0, unbudgetedPower 0, powerToAttain 0, timeToAttain 0, settleUpTime 0, timeToLower 0, settleDownTime 0, powerDomainBudget 0 }, aggressiveness = 0, myCurrentState = 0, parentsCurrentPowerFlags = 00000002, maxCapability = 3 }</string><key>Power Management private data</key><string ID=\"20\">{ this object = 0114c800, interested driver = 0114c800, driverDesire = 0, deviceDesire = 0, ourDesiredPowerState = 0, previousReqest = 0 }</string></dict>";
93 struct mach_iokit_property darwin_ioframebuffer_properties_array[] = {
94 { "IOFBDependentID", NULL },
95 { "IOFBDependentIndex", NULL },
96 { "graphic-options", "<integer size=\"32\" ID=\"0\">0x0</integer>"},
97 { "IOFBConfig", darwin_iofbconfig },
98 { "IOFBMemorySize",
99 "<integer size=\"32\" ID=\"0\">0x1000000</integer>"},
100 { "AAPL,boot-display", ""},
101 { NULL, 0}
104 struct mach_iokit_devclass darwin_ioframebuffer_devclass = {
105 "<dict ID=\"0\"><key>IOProviderClass</key>"
106 "<string ID=\"1\">IOFramebuffer</string></dict>",
107 { &mach_ioroot_devclass, NULL },
108 darwin_ioframebuffer_properties,
109 darwin_ioframebuffer_properties_array,
110 darwin_ioframebuffer_connect_method_scalari_scalaro,
111 darwin_ioframebuffer_connect_method_scalari_structo,
112 darwin_ioframebuffer_connect_method_structi_structo,
113 darwin_ioframebuffer_connect_method_scalari_structi,
114 darwin_ioframebuffer_connect_map_memory,
115 "IOFramebuffer",
116 NULL,
120 darwin_ioframebuffer_connect_method_scalari_scalaro(struct mach_trap_args *args)
122 mach_io_connect_method_scalari_scalaro_request_t *req = args->smsg;
123 mach_io_connect_method_scalari_scalaro_reply_t *rep = args->rmsg;
124 size_t *msglen = args->rsize;
125 struct lwp *l = args->l;
126 int maxoutcount;
127 int error;
129 #ifdef DEBUG_DARWIN
130 printf("darwin_ioframebuffer_connect_method_scalari_scalaro()\n");
131 #endif
132 rep->rep_outcount = 0;
133 maxoutcount = req->req_in[req->req_incount];
135 switch (req->req_selector) {
136 case DARWIN_IOFBCREATESHAREDCURSOR: {
137 /* Create the shared memory containing cursor information */
138 int shmemvers;
139 int maxwidth;
140 int maxheight;
141 size_t memsize;
142 vaddr_t kvaddr;
144 shmemvers = req->req_in[0]; /* 0x2 */
145 maxwidth = req->req_in[1]; /* 0x20 */
146 maxheight = req->req_in[2]; /* 0x20 */
147 #ifdef DEBUG_DARWIN
148 printf("DARWIN_IOFBCREATESHAREDCURSOR: shmemvers = %d, "
149 "maxwidth = %d, maxheight = %d\n", shmemvers,
150 maxwidth, maxheight);
151 #endif
152 if (darwin_ioframebuffer_shmem == NULL) {
153 memsize =
154 round_page(sizeof(*darwin_ioframebuffer_shmem));
156 darwin_ioframebuffer_shmem = uao_create(memsize, 0);
158 error = uvm_map(kernel_map, &kvaddr, memsize,
159 darwin_ioframebuffer_shmem, 0, PAGE_SIZE,
160 UVM_MAPFLAG(UVM_PROT_RW, UVM_PROT_RW,
161 UVM_INH_SHARE, UVM_ADV_RANDOM, 0));
162 if (error != 0) {
163 uao_detach(darwin_ioframebuffer_shmem);
164 darwin_ioframebuffer_shmem = NULL;
165 return mach_msg_error(args, error);
168 if ((error = uvm_map_pageable(kernel_map, kvaddr,
169 kvaddr + memsize, FALSE, 0)) != 0) {
170 uao_detach(darwin_ioframebuffer_shmem);
171 darwin_ioframebuffer_shmem = NULL;
172 return mach_msg_error(args, error);
175 darwin_ioframebuffer_shmeminit(kvaddr);
178 /* No output, the zone is mapped during another call */
179 rep->rep_outcount = 0;
180 break;
183 case DARWIN_IOFBSETSTARTUPDISPLAYMODE: {
184 darwin_iodisplaymodeid mode;
185 darwin_ioindex depth;
187 mode = req->req_in[0];
188 depth = req->req_in[1];
189 #ifdef DEBUG_DARWIN
190 printf("DARWIN_IOFBSETSTARTUPDISPLAYMODE: mode = %d, "
191 "depth = %d\n", mode, depth);
192 #endif
193 /* Nothing for now */
194 break;
197 case DARWIN_IOFBSETDISPLAYMODE: {
198 darwin_iodisplaymodeid mode;
199 darwin_ioindex depth;
201 mode = req->req_in[0];
202 depth = req->req_in[1];
203 #ifdef DEBUG_DARWIN
204 printf("DARWIN_IOFBSETDISPLAYMODE: mode = %d, "
205 "depth = %d\n", mode, depth);
206 #endif
207 /* Nothing for now */
208 break;
211 case DARWIN_IOFBGETCURRENTDISPLAYMODE: {
212 /* Get current display mode and depth. No input args */
214 #ifdef DEBUG_DARWIN
215 printf("DARWIN_IOFBGETCURRENTDISPLAYMODE\n");
216 #endif
217 if (maxoutcount < 2)
218 return mach_msg_error(args, EINVAL);
220 rep->rep_outcount = 2;
221 rep->rep_out[0] = 0x2e; /* mode XXX */
222 rep->rep_out[1] = 0; /* depth (0=>8b 1=>15b 2=>24b) */
223 break;
226 case DARWIN_IOFBSETCURSORVISIBLE: {
227 mach_boolean_t visible;
229 visible = req->req_in[0];
230 #ifdef DEBUG_DARWIN
231 printf("DARWIN_IOFBSETCURSORVISIBLE: visible = %d\n", visible);
232 #endif
233 /* Nothing for now */
234 break;
237 case DARWIN_IOFBGETATTRIBUTE: {
238 /* Get attribute value */
239 char *name;
241 name = (char *)&req->req_in[0];
242 #ifdef DEBUG_DARWIN
243 printf("DARWIN_IOFBGETATTRIBUTE: name = %s\n", name);
244 #endif
246 /* We only heard about the mrdf attribute. What is it? */
247 if (memcmp(name, "mrdf", 4) == 0) {
248 if (maxoutcount < 1)
249 return mach_msg_error(args, EINVAL);
251 rep->rep_outcount = 1;
252 rep->rep_out[0] = 0; /* XXX */
253 } else {
254 #ifdef DEBUG_DARWIN
255 printf("Unknown attribute %c%c%c%c\n",
256 req->req_in[0], req->req_in[1],
257 req->req_in[2], req->req_in[3]);
258 #endif
259 return mach_msg_error(args, EINVAL);
261 break;
264 case DARWIN_IOFBGETVRAMMAPOFFSET: {
265 darwin_iopixelaperture aperture; /* 0 XXX Current aperture? */
266 struct darwin_emuldata *ded = l->l_proc->p_emuldata;
268 aperture = req->req_in[0];
269 #ifdef DEBUG_DARWIN
270 printf("DARWIN_IOFBGETVRAMMAPOFFSET: aperture = %d\n",
271 aperture);
272 #endif
273 if (maxoutcount < 1)
274 return mach_msg_error(args, EINVAL);
276 rep->rep_outcount = 1;
277 rep->rep_out[0] = (int)ded->ded_vramoffset;
278 break;
281 default:
282 #ifdef DEBUG_DARWIN
283 printf("Unknown selector %d\n", req->req_selector);
284 #endif
285 return mach_msg_error(args, EINVAL);
286 break;
289 *msglen = sizeof(*rep) - ((16 - rep->rep_outcount) * sizeof(int));
290 mach_set_header(rep, req, *msglen);
291 mach_set_trailer(rep, *msglen);
293 return 0;
297 darwin_ioframebuffer_connect_method_scalari_structo(struct mach_trap_args *args)
299 mach_io_connect_method_scalari_structo_request_t *req = args->smsg;
300 mach_io_connect_method_scalari_structo_reply_t *rep = args->rmsg;
301 size_t *msglen = args->rsize;
302 int maxoutcount;
304 #ifdef DEBUG_DARWIN
305 printf("darwin_ioframebuffer_connect_method_scalari_structo()\n");
306 #endif
307 rep->rep_outcount = 0;
308 maxoutcount = req->req_in[req->req_incount];
310 switch(req->req_selector) {
311 case DARWIN_IOFBGETPIXELINFORMATION: {
312 /* Get bit per pixel, etc... */
313 darwin_iodisplaymodeid displaymode;
314 darwin_ioindex depth;
315 darwin_iopixelaperture aperture;
316 darwin_iopixelinformation *pixelinfo;
318 displaymode = req->req_in[0]; /* 0x2e */
319 depth = req->req_in[1]; /* 0 or 1 */
320 aperture = req->req_in[2]; /* 0 */
321 #ifdef DEBUG_DARWIN
322 printf("DARWIN_IOFBGETPIXELINFORMATION: displaymode = %d, "
323 "depth = %d, aperture = %d\n", displaymode, depth,
324 aperture);
325 #endif
326 pixelinfo = (darwin_iopixelinformation *)&rep->rep_out[0];
328 if (maxoutcount < sizeof(*pixelinfo))
329 return mach_msg_error(args, EINVAL);
332 * darwin_iopixelinformation is shorter than the buffer
333 * usually supplied, but Darwin still returns the whole buffer
335 rep->rep_outcount = maxoutcount;
336 memset(pixelinfo, 0, maxoutcount * sizeof(int));
338 switch (depth) {
339 case 0: /* 8 bpp */
340 pixelinfo->bytesperrow = 0x400;
341 pixelinfo->bytesperplane = 0;
342 pixelinfo->bitsperpixel = 0x8;
343 pixelinfo->pixeltype = DARWIN_IOFB_CLUTPIXELS;
344 pixelinfo->componentcount = 1;
345 pixelinfo->bitspercomponent = 8;
346 pixelinfo->componentmasks[0] = 0x000000ff;
347 memcpy(&pixelinfo->pixelformat, "PPPPPPPP", 8);
348 pixelinfo->flags = 0;
349 pixelinfo->activewidth = 0;
350 pixelinfo->activeheight = 0;
351 break;
353 case 1: /* 15 bpp */
354 pixelinfo->bytesperrow = 0x800;
355 pixelinfo->bytesperplane = 0;
356 pixelinfo->bitsperpixel = 0x10;
357 pixelinfo->pixeltype = DARWIN_IOFB_RGBDIRECTPIXELS;
358 pixelinfo->componentcount = 3;
359 pixelinfo->bitspercomponent = 5;
360 pixelinfo->componentmasks[0] = 0x00007c00; /* Red */
361 pixelinfo->componentmasks[1] = 0x000003e0; /* Green */
362 pixelinfo->componentmasks[2] = 0x0000001f; /* Blue */
363 memcpy(&pixelinfo->pixelformat, "-RRRRRGGGGGBBBBB", 16);
364 pixelinfo->flags = 0;
365 pixelinfo->activewidth = 0;
366 pixelinfo->activeheight = 0;
367 break;
369 case 2: /* 24 bpp */
370 pixelinfo->bytesperrow = 0x1000;
371 pixelinfo->bytesperplane = 0;
372 pixelinfo->bitsperpixel = 0x20;
373 pixelinfo->pixeltype = DARWIN_IOFB_RGBDIRECTPIXELS;
374 pixelinfo->componentcount = 3;
375 pixelinfo->bitspercomponent = 8;
376 pixelinfo->componentmasks[0] = 0x00ff0000; /* Red */
377 pixelinfo->componentmasks[1] = 0x0000ff00; /* Green */
378 pixelinfo->componentmasks[2] = 0x000000ff; /* Blue */
379 memcpy(&pixelinfo->pixelformat,
380 "--------RRRRRRRRGGGGGGGGBBBBBBBB", 32);
381 pixelinfo->flags = 0;
382 pixelinfo->activewidth = 0;
383 pixelinfo->activeheight = 0;
384 break;
386 default:
387 printf("unknown depth %d\n", depth);
388 break;
391 /* Probably useless */
392 rep->rep_out[158] = 0x4;
393 rep->rep_out[162] = 0x3;
395 break;
398 default:
399 #ifdef DEBUG_DARWIN
400 printf("Unknown selector %d\n", req->req_selector);
401 #endif
402 return mach_msg_error(args, EINVAL);
403 break;
406 *msglen = sizeof(*rep) - (4096 - rep->rep_outcount);
407 mach_set_header(rep, req, *msglen);
408 mach_set_trailer(rep, *msglen);
410 return 0;
414 darwin_ioframebuffer_connect_method_structi_structo(struct mach_trap_args *args)
416 mach_io_connect_method_structi_structo_request_t *req = args->smsg;
417 mach_io_connect_method_structi_structo_reply_t *rep = args->rmsg;
418 size_t *msglen = args->rsize;
419 int maxoutcount;
421 #ifdef DEBUG_DARWIN
422 printf("darwin_ioframebuffer_connect_method_structi_structo()\n");
423 #endif
425 rep->rep_outcount = 0;
426 /* maxoutcount is word aligned */
427 maxoutcount = req->req_in[(req->req_incount & ~0x3UL) + 4];
429 switch(req->req_selector) {
430 case DARWIN_IOFBSETBOUNDS: {
431 darwin_iogbounds *bounds;
433 bounds = (darwin_iogbounds *)&req->req_in[0];
435 #ifdef DEBUG_DARWIN
436 printf("DARWIN_IOFBSETBOUNDS: bounds (%d, %d) - (%d, %d)\n",
437 bounds->minx, bounds->miny, bounds->maxx, bounds->maxy);
438 #endif
439 /* Nothing yet */
440 break;
443 default:
444 #ifdef DEBUG_DARWIN
445 printf("Unknown selector %d\n", req->req_selector);
446 #endif
447 return mach_msg_error(args, EINVAL);
448 break;
451 *msglen = sizeof(*rep) - (4096 - rep->rep_outcount);
452 mach_set_header(rep, req, *msglen);
453 mach_set_trailer(rep, *msglen);
455 return 0;
459 darwin_ioframebuffer_connect_map_memory(struct mach_trap_args *args)
461 mach_io_connect_map_memory_request_t *req = args->smsg;
462 mach_io_connect_map_memory_reply_t *rep = args->rmsg;
463 size_t *msglen = args->rsize;
464 struct lwp *l = args->l;
465 struct proc *p = args->l->l_proc;
466 int error = 0;
467 size_t memsize;
468 size_t len;
469 vaddr_t pvaddr;
471 #ifdef DEBUG_DARWIN
472 printf("darwin_ioframebuffer_connect_map_memory()\n");
473 #endif
474 switch (req->req_memtype) {
475 case DARWIN_IOFRAMEBUFFER_CURSOR_MEMORY:
476 if (darwin_ioframebuffer_shmem == NULL)
477 return mach_msg_error(args, error);
479 len = sizeof(struct darwin_ioframebuffer_shmem);
480 memsize = round_page(len);
482 uao_reference(darwin_ioframebuffer_shmem);
483 pvaddr = VM_DEFAULT_ADDRESS(p->p_vmspace->vm_daddr, memsize);
485 if ((error = uvm_map(&p->p_vmspace->vm_map, &pvaddr,
486 memsize, darwin_ioframebuffer_shmem, 0, PAGE_SIZE,
487 UVM_MAPFLAG(UVM_PROT_RW, UVM_PROT_RW,
488 UVM_INH_SHARE, UVM_ADV_RANDOM, 0))) != 0)
489 return mach_msg_error(args, error);
491 #ifdef DEBUG_DARWIN
492 printf("pvaddr = 0x%08lx\n", (long)pvaddr);
493 #endif
494 break;
496 case DARWIN_IOFRAMEBUFFER_VRAM_MEMORY:
497 case DARWIN_IOFRAMEBUFFER_SYSTEM_APERTURE: {
498 dev_t device;
499 const struct cdevsw *wsdisplay;
500 int unit;
501 int mode, screen;
502 struct wsdisplay_fbinfo fbi;
503 struct darwin_emuldata *ded;
504 struct vnode *vp;
507 * Use unit given by sysctl emul.darwin.ioframebuffer.unit
508 * and emul.darwin.ioframebuffer.screen
510 unit = darwin_ioframebuffer_unit;
511 screen = darwin_ioframebuffer_screen;
512 if ((error = darwin_findscreen(&device, unit, screen)) != 0)
513 return mach_msg_error(args, error);
515 if ((wsdisplay = cdevsw_lookup(device)) == NULL)
516 return mach_msg_error(args, ENXIO);
518 /* Find the framebuffer's size */
519 if ((error = (wsdisplay->d_ioctl)(device,
520 WSDISPLAYIO_GINFO, (void *)&fbi, 0, l)) != 0) {
521 #ifdef DEBUG_DARWIN
522 printf("*** Cannot get screen params ***\n");
523 #endif
524 return mach_msg_error(args, error);
526 #ifdef DEBUG_DARWIN
527 printf("framebuffer: %d x %d x %d\n",
528 fbi.width, fbi.height, fbi.depth);
529 #endif
530 len = round_page(fbi.height * fbi.width * fbi.depth / 8);
533 * The framebuffer cannot be mapped if the console is
534 * not in graphic mode. We will do the switch, but it
535 * screws the console. Therefore we attempt to restore
536 * its original state on process exit. ded->ded_wsdev
537 * is used to remember the console device. If it is not
538 * NODEV on process exit, we use it to restore text mode.
540 ded = (struct darwin_emuldata *)p->p_emuldata;
541 if ((error = (wsdisplay->d_ioctl)(device,
542 WSDISPLAYIO_GMODE, (void *)&mode, 0, l)) != 0) {
543 #ifdef DEBUG_DARWIN
544 printf("*** Cannot get console state ***\n");
545 #endif
546 return mach_msg_error(args, ENODEV);
548 if (mode == WSDISPLAYIO_MODE_EMUL)
549 ded->ded_wsdev = device;
551 /* Switch to graphic mode */
552 mode = WSDISPLAYIO_MODE_MAPPED;
553 if ((error = (wsdisplay->d_ioctl)(device,
554 WSDISPLAYIO_SMODE, (void *)&mode, 0, l)) != 0) {
555 #ifdef DEBUG_DARWIN
556 printf("*** Cannot switch to graphic mode ***\n");
557 #endif
558 return mach_msg_error(args, ENODEV);
561 if ((error = cdevvp(device, &vp)) != 0) {
562 #ifdef DEBUG_DARWIN
563 printf("*** cdevvp failed ***\n");
564 #endif
565 return mach_msg_error(args, error);
568 pvaddr = 0;
569 if ((error = uvm_mmap(&p->p_vmspace->vm_map, &pvaddr,
570 len, UVM_PROT_RW, UVM_PROT_RW, MAP_SHARED, vp, 0,
571 p->p_rlimit[RLIMIT_MEMLOCK].rlim_cur)) != 0) {
572 #ifdef DEBUG_DARWIN
573 printf("*** uvm_mmap failed ***\n");
574 #endif
575 return mach_msg_error(args, error);
578 #ifdef DEBUG_DARWIN
579 printf("mapped framebuffer at %p\n", (void *)pvaddr);
580 #endif
581 break;
584 default:
585 #ifdef DEBUG_DARWIN
586 printf("unimplemented memtype %d\n", req->req_memtype);
587 #endif
588 return mach_msg_error(args, EINVAL);
589 break;
592 *msglen = sizeof(*rep);
593 mach_set_header(rep, req, *msglen);
595 rep->rep_retval = 0;
596 rep->rep_addr = pvaddr;
597 rep->rep_len = len;
599 mach_set_trailer(rep, *msglen);
601 /* Track VRAM offset for connect_method IOFBGETVRAMMAPOFFSET */
602 if (req->req_memtype == DARWIN_IOFRAMEBUFFER_VRAM_MEMORY) {
603 struct darwin_emuldata *ded;
605 ded = p->p_emuldata;
607 * This seems to be the offset of the framebuffer
608 * within the VRAM. For now 0, as we are only
609 * able to map the framebuffer.
611 ded->ded_vramoffset = (void *)(pvaddr - pvaddr);
614 return 0;
617 void
618 darwin_ioframebuffer_shmeminit(vaddr_t kvaddr)
620 struct darwin_ioframebuffer_shmem *shmem;
622 shmem = (struct darwin_ioframebuffer_shmem *)kvaddr;
624 return;
628 darwin_ioframebuffer_connect_method_scalari_structi(struct mach_trap_args *args)
630 mach_io_connect_method_scalari_structi_request_t *req = args->smsg;
631 mach_io_connect_method_scalari_structi_reply_t *rep = args->rmsg;
632 size_t *msglen = args->rsize;
633 int scalar_len;
634 int struct_len;
635 char *struct_data;
637 #ifdef DEBUG_DARWIN
638 printf("darwin_ioframebuffer_connect_method_scalari_structi()\n");
639 #endif
640 scalar_len = req->req_incount;
641 struct_len = req->req_in[scalar_len];
642 struct_data = (char *)&req->req_in[scalar_len + 1];
644 switch (req->req_selector) {
645 case DARWIN_IOFBSETCOLORCONVERTTABLE: {
646 int select;
647 int *data;
648 size_t tablelen;
650 select = req->req_in[0];
651 tablelen = struct_len / sizeof(*data);
652 #ifdef DEBUG_DARWIN
653 printf("DARWIN_IOFBSETCOLORCONVERTTABLE: select = %d, "
654 "tablelen = %d\n", select, tablelen);
655 #endif
656 if (tablelen == 0)
657 break;
659 data = (int *)struct_data;
660 break;
663 case DARWIN_IOFBSETGAMMATABLE: {
664 int entries;
665 int count;
666 int width;
667 int *data;
669 entries = req->req_in[0];
670 count = req->req_in[1];
671 width = req->req_in[2];
673 #ifdef DEBUG_DARWIN
674 printf("DARWIN_IOFBSETGAMMATABLE: entries = %d, "
675 "count = %d, width = %d\n", entries, count, width);
676 #endif
678 data = &req->req_in[3];
679 break;
682 #if 0 /* comment out stackgap using code - needs to be done another way */
683 case DARWIN_IOFBSETCLUTWITHENTRIES: {
684 struct lwp *l = args->l;
685 struct proc *p = args->l->l_proc;
686 int index;
687 int option;
688 struct darwin_iocolorentry *clut;
689 size_t clutlen;
690 size_t tablen;
691 size_t kcolorsz;
692 void *sg = stackgap_init(p, 0);
693 int error;
694 struct wsdisplay_cmap cmap;
695 u_char *red;
696 u_char *green;
697 u_char *blue;
698 u_char kred[256];
699 u_char kgreen[256];
700 u_char kblue[256];
701 int unit, screen;
702 dev_t dev;
703 const struct cdevsw *wsdisplay;
704 int i;
706 index = req->req_in[0];
707 option = req->req_in[1];
708 clutlen = struct_len / sizeof(*clut);
709 clut = (struct darwin_iocolorentry *)struct_data;
711 if ((clutlen == 0) || (index >= 256))
712 break;
714 #ifdef DEBUG_DARWIN
715 printf("DARWIN_IOFBSETCLUTWITHENTRIES: index = %d, "
716 "option = %d, clutlen = %d\n", index, option, clutlen);
717 #endif
720 * Find wsdisplay. Use the screen given by sysctl
721 * emul.darwin.ioframebuffer.screen
723 unit = darwin_ioframebuffer_unit;
724 screen = darwin_ioframebuffer_screen;
725 if ((error = darwin_findscreen(&dev, unit, screen)) != 0)
726 return mach_msg_error(args, error);
728 if ((wsdisplay = cdevsw_lookup(dev)) == NULL)
729 return mach_msg_error(args, ENXIO);
732 * We only support 256 entries
734 if (index + clutlen > 256)
735 clutlen = 256 - index;
738 * Big tables will not fit in the stackgap.
739 * We have to split the data.
741 if (clutlen <= 128)
742 tablen = clutlen;
743 else
744 tablen = 128;
746 kcolorsz = sizeof(u_char) * tablen;
747 red = stackgap_alloc(p, &sg, kcolorsz);
748 green = stackgap_alloc(p, &sg, kcolorsz);
749 blue = stackgap_alloc(p, &sg, kcolorsz);
751 do {
752 for (i = 0; i < tablen; i++) {
753 kred[i] = (u_char)(clut->red >> 8);
754 kgreen[i] = (u_char)(clut->green >> 8);
755 kblue[i] = (u_char)(clut->blue >> 8);
756 clut++;
759 cmap.index = index;
760 cmap.count = tablen;
761 cmap.red = red;
762 cmap.green = green;
763 cmap.blue = blue;
765 if (((error = copyout(kred, red, kcolorsz)) != 0) ||
766 ((error = copyout(kgreen, green, kcolorsz)) != 0) ||
767 ((error = copyout(kblue, blue, kcolorsz)) != 0))
768 return mach_msg_error(args, error);
770 if ((error = (wsdisplay->d_ioctl)(dev,
771 WSDISPLAYIO_PUTCMAP, (void *)&cmap, 0, l)) != 0)
772 return mach_msg_error(args, error);
774 index += tablen;
775 clutlen -= tablen;
776 if (clutlen <= 128)
777 tablen = clutlen;
778 } while (clutlen > 0);
780 break;
782 #endif
784 default:
785 #ifdef DEBUG_DARWIN
786 printf("Unknown selector %d\n", req->req_selector);
787 #endif
788 return mach_msg_error(args, EINVAL);
789 break;
792 *msglen = sizeof(*rep);
793 mach_set_header(rep, req, *msglen);
795 rep->rep_retval = 0;
797 mach_set_trailer(rep, *msglen);
799 return 0;
803 /* Find a wsdisplay from unit and screen */
804 static int
805 darwin_findscreen(dev_t *dev, int unit, int screen)
807 #if defined(NWSDISPLAY) && NWSDISPLAY > 0
808 struct device *dv;
809 struct wsdisplay_softc *sc;
810 int major, minor;
812 /* Find a wsdisplay */
813 if ((dv = device_find_by_driver_unit("wsdisplay", unit)) == NULL)
814 return ENODEV;
816 sc = device_private(dv);
818 /* Derive the device number */
819 major = cdevsw_lookup_major(&wsdisplay_cdevsw);
820 minor = WSDISPLAYMINOR(device_unit(dv), screen);
821 *dev = makedev(major, minor);
823 #ifdef DEBUG_DARWIN
824 printf("ioframebuffer uses major = %d, minor = %d\n", major, minor);
825 #endif /* DEBUG_DARWIN */
826 return 0;
827 #else /* defined(NWSDISPLAY) && NWSDISPLAY > 0 */
828 return ENODEV;
829 #endif /* defined(NWSDISPLAY) && NWSDISPLAY > 0 */