1 /* $NetBSD: darwin_ioframebuffer.c,v 1.42 2009/03/14 21:04:18 dsl Exp $ */
4 * Copyright (c) 2003 The NetBSD Foundation, Inc.
7 * This code is derived from software contributed to The NetBSD Foundation
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
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>
41 #include <sys/signal.h>
42 #include <sys/mount.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>
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>
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
},
99 "<integer size=\"32\" ID=\"0\">0x1000000</integer>"},
100 { "AAPL,boot-display", ""},
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
,
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
;
130 printf("darwin_ioframebuffer_connect_method_scalari_scalaro()\n");
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 */
144 shmemvers
= req
->req_in
[0]; /* 0x2 */
145 maxwidth
= req
->req_in
[1]; /* 0x20 */
146 maxheight
= req
->req_in
[2]; /* 0x20 */
148 printf("DARWIN_IOFBCREATESHAREDCURSOR: shmemvers = %d, "
149 "maxwidth = %d, maxheight = %d\n", shmemvers
,
150 maxwidth
, maxheight
);
152 if (darwin_ioframebuffer_shmem
== NULL
) {
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));
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;
183 case DARWIN_IOFBSETSTARTUPDISPLAYMODE
: {
184 darwin_iodisplaymodeid mode
;
185 darwin_ioindex depth
;
187 mode
= req
->req_in
[0];
188 depth
= req
->req_in
[1];
190 printf("DARWIN_IOFBSETSTARTUPDISPLAYMODE: mode = %d, "
191 "depth = %d\n", mode
, depth
);
193 /* Nothing for now */
197 case DARWIN_IOFBSETDISPLAYMODE
: {
198 darwin_iodisplaymodeid mode
;
199 darwin_ioindex depth
;
201 mode
= req
->req_in
[0];
202 depth
= req
->req_in
[1];
204 printf("DARWIN_IOFBSETDISPLAYMODE: mode = %d, "
205 "depth = %d\n", mode
, depth
);
207 /* Nothing for now */
211 case DARWIN_IOFBGETCURRENTDISPLAYMODE
: {
212 /* Get current display mode and depth. No input args */
215 printf("DARWIN_IOFBGETCURRENTDISPLAYMODE\n");
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) */
226 case DARWIN_IOFBSETCURSORVISIBLE
: {
227 mach_boolean_t visible
;
229 visible
= req
->req_in
[0];
231 printf("DARWIN_IOFBSETCURSORVISIBLE: visible = %d\n", visible
);
233 /* Nothing for now */
237 case DARWIN_IOFBGETATTRIBUTE
: {
238 /* Get attribute value */
241 name
= (char *)&req
->req_in
[0];
243 printf("DARWIN_IOFBGETATTRIBUTE: name = %s\n", name
);
246 /* We only heard about the mrdf attribute. What is it? */
247 if (memcmp(name
, "mrdf", 4) == 0) {
249 return mach_msg_error(args
, EINVAL
);
251 rep
->rep_outcount
= 1;
252 rep
->rep_out
[0] = 0; /* XXX */
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]);
259 return mach_msg_error(args
, EINVAL
);
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];
270 printf("DARWIN_IOFBGETVRAMMAPOFFSET: aperture = %d\n",
274 return mach_msg_error(args
, EINVAL
);
276 rep
->rep_outcount
= 1;
277 rep
->rep_out
[0] = (int)ded
->ded_vramoffset
;
283 printf("Unknown selector %d\n", req
->req_selector
);
285 return mach_msg_error(args
, EINVAL
);
289 *msglen
= sizeof(*rep
) - ((16 - rep
->rep_outcount
) * sizeof(int));
290 mach_set_header(rep
, req
, *msglen
);
291 mach_set_trailer(rep
, *msglen
);
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
;
305 printf("darwin_ioframebuffer_connect_method_scalari_structo()\n");
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 */
322 printf("DARWIN_IOFBGETPIXELINFORMATION: displaymode = %d, "
323 "depth = %d, aperture = %d\n", displaymode
, depth
,
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));
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;
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;
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;
387 printf("unknown depth %d\n", depth
);
391 /* Probably useless */
392 rep
->rep_out
[158] = 0x4;
393 rep
->rep_out
[162] = 0x3;
400 printf("Unknown selector %d\n", req
->req_selector
);
402 return mach_msg_error(args
, EINVAL
);
406 *msglen
= sizeof(*rep
) - (4096 - rep
->rep_outcount
);
407 mach_set_header(rep
, req
, *msglen
);
408 mach_set_trailer(rep
, *msglen
);
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
;
422 printf("darwin_ioframebuffer_connect_method_structi_structo()\n");
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];
436 printf("DARWIN_IOFBSETBOUNDS: bounds (%d, %d) - (%d, %d)\n",
437 bounds
->minx
, bounds
->miny
, bounds
->maxx
, bounds
->maxy
);
445 printf("Unknown selector %d\n", req
->req_selector
);
447 return mach_msg_error(args
, EINVAL
);
451 *msglen
= sizeof(*rep
) - (4096 - rep
->rep_outcount
);
452 mach_set_header(rep
, req
, *msglen
);
453 mach_set_trailer(rep
, *msglen
);
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
;
472 printf("darwin_ioframebuffer_connect_map_memory()\n");
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
);
492 printf("pvaddr = 0x%08lx\n", (long)pvaddr
);
496 case DARWIN_IOFRAMEBUFFER_VRAM_MEMORY
:
497 case DARWIN_IOFRAMEBUFFER_SYSTEM_APERTURE
: {
499 const struct cdevsw
*wsdisplay
;
502 struct wsdisplay_fbinfo fbi
;
503 struct darwin_emuldata
*ded
;
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) {
522 printf("*** Cannot get screen params ***\n");
524 return mach_msg_error(args
, error
);
527 printf("framebuffer: %d x %d x %d\n",
528 fbi
.width
, fbi
.height
, fbi
.depth
);
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) {
544 printf("*** Cannot get console state ***\n");
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) {
556 printf("*** Cannot switch to graphic mode ***\n");
558 return mach_msg_error(args
, ENODEV
);
561 if ((error
= cdevvp(device
, &vp
)) != 0) {
563 printf("*** cdevvp failed ***\n");
565 return mach_msg_error(args
, error
);
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) {
573 printf("*** uvm_mmap failed ***\n");
575 return mach_msg_error(args
, error
);
579 printf("mapped framebuffer at %p\n", (void *)pvaddr
);
586 printf("unimplemented memtype %d\n", req
->req_memtype
);
588 return mach_msg_error(args
, EINVAL
);
592 *msglen
= sizeof(*rep
);
593 mach_set_header(rep
, req
, *msglen
);
596 rep
->rep_addr
= pvaddr
;
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
;
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
);
618 darwin_ioframebuffer_shmeminit(vaddr_t kvaddr
)
620 struct darwin_ioframebuffer_shmem
*shmem
;
622 shmem
= (struct darwin_ioframebuffer_shmem
*)kvaddr
;
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
;
638 printf("darwin_ioframebuffer_connect_method_scalari_structi()\n");
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
: {
650 select
= req
->req_in
[0];
651 tablelen
= struct_len
/ sizeof(*data
);
653 printf("DARWIN_IOFBSETCOLORCONVERTTABLE: select = %d, "
654 "tablelen = %d\n", select
, tablelen
);
659 data
= (int *)struct_data
;
663 case DARWIN_IOFBSETGAMMATABLE
: {
669 entries
= req
->req_in
[0];
670 count
= req
->req_in
[1];
671 width
= req
->req_in
[2];
674 printf("DARWIN_IOFBSETGAMMATABLE: entries = %d, "
675 "count = %d, width = %d\n", entries
, count
, width
);
678 data
= &req
->req_in
[3];
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
;
688 struct darwin_iocolorentry
*clut
;
692 void *sg
= stackgap_init(p
, 0);
694 struct wsdisplay_cmap cmap
;
703 const struct cdevsw
*wsdisplay
;
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))
715 printf("DARWIN_IOFBSETCLUTWITHENTRIES: index = %d, "
716 "option = %d, clutlen = %d\n", index
, option
, clutlen
);
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.
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
);
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);
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
);
778 } while (clutlen
> 0);
786 printf("Unknown selector %d\n", req
->req_selector
);
788 return mach_msg_error(args
, EINVAL
);
792 *msglen
= sizeof(*rep
);
793 mach_set_header(rep
, req
, *msglen
);
797 mach_set_trailer(rep
, *msglen
);
803 /* Find a wsdisplay from unit and screen */
805 darwin_findscreen(dev_t
*dev
, int unit
, int screen
)
807 #if defined(NWSDISPLAY) && NWSDISPLAY > 0
809 struct wsdisplay_softc
*sc
;
812 /* Find a wsdisplay */
813 if ((dv
= device_find_by_driver_unit("wsdisplay", unit
)) == NULL
)
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
);
824 printf("ioframebuffer uses major = %d, minor = %d\n", major
, minor
);
825 #endif /* DEBUG_DARWIN */
827 #else /* defined(NWSDISPLAY) && NWSDISPLAY > 0 */
829 #endif /* defined(NWSDISPLAY) && NWSDISPLAY > 0 */