/* $NetBSD: darwin_ioframebuffer.c,v 1.8 2003/05/14 18:28:05 manu Exp $ */ /*- * Copyright (c) 2003 The NetBSD Foundation, Inc. * All rights reserved. * * This code is derived from software contributed to The NetBSD Foundation * by Emmanuel Dreyfus. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the NetBSD * Foundation, Inc. and its contributors. * 4. Neither the name of The NetBSD Foundation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #include __KERNEL_RCSID(0, "$NetBSD: darwin_ioframebuffer.c,v 1.8 2003/05/14 18:28:05 manu Exp $"); #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include static struct uvm_object *darwin_ioframebuffer_shmem = NULL; static void darwin_ioframebuffer_shmeminit(vaddr_t); /* This is ugly, but we hope to see it going away quickly */ static char darwin_iofbconfig[] = "IOFBModesAID0xeeDMAAACAAAAAYAAMgAAAAAAAgAQAAAAAAAAAAAAAAAAAAAAAAAAID0x3eAID0x82DMAAACAAAAAYAAPAAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAID0x3AID0xe8DMAAACAAAAAYAAPAAAAAAAAgAQAAAAAAAAAAAAAAAAAAAAAAAAID0x37DMAAACAAAAAYAARgAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAID0x5AIDDMAAACgAAAAeAAPAAAAAAAAgAQAAAAAAAAAAAAAAAAAAAAAAAAID0x38AIDDMAAACgAAAAeAAMgAAAAAAAgAQAAAAAAAAAAAAAAAAAAAAAAAAID0x3fAID0x96DMAAACgAAAAeAAPAAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAID0x6AID0x8cDMAAACgAAAAeAAQwAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAID0x7AID0x98DMAAACgAAAAeAASAAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAID0x8AID0x9aDMAAACgAAAAeAASwAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAID0x9AID0x9eDMAAACgAAAAeAAVQAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAID0xaAID0xa0DMAAACgAAAA2YASwAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAID0xeAIDDMAAAC0AAAAeAAMgAAAAAAAgAQAAAAAAAAAAAAAAAAAAAAAAAAID0x4bAIDDMAAAC0AAAAeAAPAAAAAAAAgAQAAAAAAAAAAAAAAAAAAAAAAAAID0x4dAIDDMAAAC0AAAAkAAMgAAAAAAAgAQAAAAAAAAAAAAAAAAAAAAAAAAID0x4cAIDDMAAAC0AAAAkAAPAAAAAAAAgAQAAAAAAAAAAAAAAAAAAAAAAAAID0x4eAIDDMAAADIAAAAlgAMgAAAAAAAgAQAAAAAAAAAAAAAAAAAAAAAAAAID0x40AID0xb4DMAAADIAAAAlgAOAAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAID0xfAID0xb6DMAAADIAAAAlgAPAAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAID0x10AIDDMAAADIAAAAlgAPAAAAAAAAgAQAAAAAAAAAAAAAAAAAAAAAAAAID0x39AID0x2aID0x2dDF0x400DMAAADIAAAAlgAAAAAAAAAAgAABAAAAAAAAAAAAAAAAAAAAAAADF0x100DMAAADIAAAAlgAPAAAAAAAAgAAAQAAAAAAAAAAAAAAAAAAAAAAID0x32AID0xb8DMAAADIAAAAlgASAAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAID0x11AID0xbaDMAAADIAAAAlgASwAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAID0x12AIDID0x46DFDMAID0xbcDMAAADIAAAAlgAVQAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAID0x13AIDDMAAADQAAAAnAAMgAAAAAAAgAQAAAAAAAAAAAAAAAAAAAAAAAAID0x41AIDDMAAADQAAAAnAAPAAAAAAAAgAQAAAAAAAAAAAAAAAAAAAAAAAAID0x3aAID0xaaDMAAADQAAAAnAASwAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAID0x17DMAAADVAAAAoAAPAAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAID0x18AID0xbeDMAAAEAAAAAwAAPAAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAID0x19AIDID0x2eDF0x407DMAAAEAAAAAwAAAAAAAAAAAgAABAcAAAAAAAAAAAAAAAAAAAAAAIDID0x33DFDMAAAEAAAAAwAAPAAAAAAAAgAAAQAAAAAAAAAAAAAAAAAAAAAAAID0xc8DMAAAEAAAAAwAARgAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAID0x1aAID0xccDMAAAEAAAAAwAASwAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAID0x1bAID0xd2DMID0x1cAID0xd0DMAAAEAAAAAwAAVQAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAID0x1dAID0xdcDMAAAEgAAAA2YASwAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAID0x21AID0xfaDMAAAFAAAAA8AASwAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAID0x22AID0x104DMAAAFAAAABAAAPAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAID0x23AID0x106DMAAAFAAAABAAASwAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAID0x24IODisplayConnectFlags0x0"; static char darwin_ioframebuffer_properties[] = "IOClassAppleBacklightDisplayIOProbeScore0xbb8IOProviderClassIODisplayConnectCFBundleIdentifiercom.apple.iokit.IOGraphicsFamilyIOMatchCategoryIODefaultMatchCategoryIODisplayConnectFlagsAAAIxA==AppleDisplayType0x2AppleSense0x400DisplayVendorID0x756e6b6eDisplayProductID0x20000IODisplayParametersbrightnessmax0x73min0x3avalue0x7fcommitreg0x0IODisplayGUID0x610000000000000Power Management protected data{ 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 }Power Management private data{ this object = 0114c800, interested driver = 0114c800, driverDesire = 0, deviceDesire = 0, ourDesiredPowerState = 0, previousReqest = 0 }"; struct mach_iokit_property darwin_ioframebuffer_properties_array[] = { { "IOFBDependentID", NULL }, { "IOFBDependentIndex", NULL }, { "graphic-options", "0x0"}, { "IOFBConfig", darwin_iofbconfig }, { "IOFBMemorySize", "0x1000000"}, { NULL, 0} }; struct mach_iokit_devclass darwin_ioframebuffer_devclass = { "IOProviderClass" "IOFramebuffer", darwin_ioframebuffer_properties, darwin_ioframebuffer_properties_array, darwin_ioframebuffer_connect_method_scalari_scalaro, darwin_ioframebuffer_connect_method_scalari_structo, darwin_ioframebuffer_connect_method_structi_structo, darwin_ioframebuffer_connect_map_memory, "IOFramebuffer", }; int darwin_ioframebuffer_connect_method_scalari_scalaro(args) struct mach_trap_args *args; { mach_io_connect_method_scalari_scalaro_request_t *req = args->smsg; mach_io_connect_method_scalari_scalaro_reply_t *rep = args->rmsg; size_t *msglen = args->rsize; #ifdef DEBUG_DARWIN printf("darwin_ioframebuffer_connect_method_scalari_scalaro()\n"); printf("select = %d, incount = %d, in0 = %d, in1 = %d, in2 = %d\n", req->req_selector, req->req_incount, req->req_in[0], req->req_in[1], req->req_in[2]); printf("outcount = %d\n", req->req_in[req->req_incount]); #endif rep->rep_msgh.msgh_bits = MACH_MSGH_REPLY_LOCAL_BITS(MACH_MSG_TYPE_MOVE_SEND_ONCE); rep->rep_msgh.msgh_size = sizeof(*rep) - sizeof(rep->rep_trailer); rep->rep_msgh.msgh_local_port = req->req_msgh.msgh_local_port; rep->rep_msgh.msgh_id = req->req_msgh.msgh_id + 100; rep->rep_outcount = 0; /* * XXX this is ugly, but we don't really know what we are doing here. */ if (req->req_in[0] == 0x00000003) { #ifdef DEBUG_MACH printf("flavor 1\n"); #endif rep->rep_outcount = 1; rep->rep_outcount = 0; } /* Called from main() */ if ((req->req_selector == 0) && (req->req_in[0] == 0x2) && (req->req_in[1] == 0x20) && (req->req_in[2] == 0x20) && (req->req_in[req->req_incount] >= 0)) { #ifdef DEBUG_MACH printf("flavor 2\n"); #endif rep->rep_outcount = 0; } /* called from IOFramebufferServerOpen() */ if ((req->req_selector == 0x2) && (req->req_in[req->req_incount] >= 2)) { #ifdef DEBUG_MACH printf("flavor 3\n"); #endif rep->rep_outcount = 2; rep->rep_out[0] = 0x2e; rep->rep_out[1] = 2; } /* IOFBRebuild gives this */ if ((req->req_selector == 0x12) && (req->req_in[0] == 0x6d726466) && (req->req_in[req->req_incount] >= 1)) { #ifdef DEBUG_MACH printf("flavor 4\n"); #endif rep->rep_outcount = 1; rep->rep_out[0] = 0; } /* IOFBGetFramebufferInformationForAperture() gives this */ if ((req->req_selector == 0x8) && (req->req_in[0] == 0x0) && (req->req_in[req->req_incount] >= 1)) { #ifdef DEBUG_MACH printf("flavor 5\n"); #endif rep->rep_outcount = 1; rep->rep_out[0] = 0x00801000; } rep->rep_out[rep->rep_outcount + 1] = 8; /* XXX Trailer */ *msglen = sizeof(*rep) - ((16 - rep->rep_outcount) * sizeof(int)); rep->rep_msgh.msgh_size = *msglen - sizeof(rep->rep_trailer); return 0; } int darwin_ioframebuffer_connect_method_scalari_structo(args) struct mach_trap_args *args; { mach_io_connect_method_scalari_structo_request_t *req = args->smsg; mach_io_connect_method_scalari_structo_reply_t *rep = args->rmsg; size_t *msglen = args->rsize; #ifdef DEBUG_DARWIN printf("darwin_ioframebuffer_connect_method_scalari_structo()\n"); printf("select = %d, incount = %d, in0 = %d, in1 = %d, in2 = %d\n", req->req_selector, req->req_incount, req->req_in[0], req->req_in[1], req->req_in[2]); printf("outcount = %d\n", req->req_in[req->req_incount]); #endif rep->rep_msgh.msgh_bits = MACH_MSGH_REPLY_LOCAL_BITS(MACH_MSG_TYPE_MOVE_SEND_ONCE); rep->rep_msgh.msgh_size = sizeof(*rep) - sizeof(rep->rep_trailer); rep->rep_msgh.msgh_local_port = req->req_msgh.msgh_local_port; rep->rep_msgh.msgh_id = req->req_msgh.msgh_id + 100; rep->rep_outcount = 0; /* * XXX this is ugly, but we don't really know what we are doing here. */ /* IOFBGetPixelInformation gives this */ if ((req->req_selector == 1) && (req->req_incount == 3) && (req->req_in[0] == 0x2e) && (req->req_in[1] == 0x0) && (req->req_in[2] == 0x0) && (req->req_in[req->req_incount] >= 0xac)) { /* req_outcount */ #ifdef DEBUG_MACH printf("flavor 1\n"); #endif rep->rep_outcount = req->req_in[req->req_incount]; memset(&rep->rep_out[0], 0, rep->rep_outcount * sizeof(int)); rep->rep_out[2] = 0x4; rep->rep_out[11] = 0x8; rep->rep_out[19] = 0x1; rep->rep_out[23] = 0x8; rep->rep_out[27] = 0xff; rep->rep_out[88] = 0x50; rep->rep_out[89] = 0x50; rep->rep_out[90] = 0x50; rep->rep_out[91] = 0x50; rep->rep_out[92] = 0x50; rep->rep_out[93] = 0x50; rep->rep_out[94] = 0x50; rep->rep_out[95] = 0x50; rep->rep_out[158] = 0x4; rep->rep_out[162] = 0x3; } /* IOFBGetPixelInformation gives this too */ if ((req->req_selector == 1) && (req->req_incount == 3) && (req->req_in[0] == 0x2e) && (req->req_in[1] == 0x1) && (req->req_in[2] == 0x0) && (req->req_in[req->req_incount] >= 0xac)) { /* req_outcount */ #ifdef DEBUG_MACH printf("flavor 1\n"); #endif rep->rep_outcount = req->req_in[req->req_incount]; memset(&rep->rep_out[0], 0, rep->rep_outcount * sizeof(int)); rep->rep_out[2] = 0x8; rep->rep_out[11] = 0x10; rep->rep_out[15] = 0x2; rep->rep_out[19] = 0x3; rep->rep_out[23] = 0x5; rep->rep_out[26] = 0x7c; rep->rep_out[30] = 0x3; rep->rep_out[31] = 0xe0; rep->rep_out[35] = 0x1f; rep->rep_out[88] = 0x2d; rep->rep_out[89] = 0x52; rep->rep_out[90] = 0x52; rep->rep_out[91] = 0x52; rep->rep_out[92] = 0x52; rep->rep_out[93] = 0x52; rep->rep_out[94] = 0x47; rep->rep_out[95] = 0x47; rep->rep_out[96] = 0x47; rep->rep_out[97] = 0x47; rep->rep_out[98] = 0x47; rep->rep_out[99] = 0x42; rep->rep_out[99] = 0x42; rep->rep_out[100] = 0x42; rep->rep_out[101] = 0x42; rep->rep_out[102] = 0x42; rep->rep_out[103] = 0x42; rep->rep_out[158] = 0x4; rep->rep_out[162] = 0x3; } /* IOFBGetPixelInformation gives this too */ if ((req->req_selector == 1) && (req->req_incount == 3) && (req->req_in[0] == 0x2e) && (req->req_in[1] == 0x2) && (req->req_in[2] == 0x0) && (req->req_in[req->req_incount] >= 0xac)) { /* req_outcount */ #ifdef DEBUG_MACH printf("flavor 3\n"); #endif rep->rep_outcount = req->req_in[req->req_incount]; memset(&rep->rep_out[0], 0, rep->rep_outcount * sizeof(int)); rep->rep_out[2] = 0x10; rep->rep_out[11] = 0x20; rep->rep_out[15] = 0x2; rep->rep_out[19] = 0x3; rep->rep_out[23] = 0x8; rep->rep_out[25] = 0xff; rep->rep_out[30] = 0xff; rep->rep_out[35] = 0x1f; rep->rep_out[88] = 0x2d; rep->rep_out[89] = 0x2d; rep->rep_out[90] = 0x2d; rep->rep_out[91] = 0x2d; rep->rep_out[92] = 0x2d; rep->rep_out[93] = 0x2d; rep->rep_out[94] = 0x2d; rep->rep_out[95] = 0x2d; rep->rep_out[96] = 0x52; rep->rep_out[97] = 0x52; rep->rep_out[98] = 0x52; rep->rep_out[99] = 0x52; rep->rep_out[100] = 0x52; rep->rep_out[101] = 0x52; rep->rep_out[102] = 0x52; rep->rep_out[103] = 0x52; rep->rep_out[104] = 0x47; rep->rep_out[105] = 0x47; rep->rep_out[106] = 0x47; rep->rep_out[107] = 0x47; rep->rep_out[108] = 0x47; rep->rep_out[109] = 0x47; rep->rep_out[110] = 0x47; rep->rep_out[111] = 0x47; rep->rep_out[112] = 0x42; rep->rep_out[113] = 0x42; rep->rep_out[114] = 0x42; rep->rep_out[115] = 0x42; rep->rep_out[116] = 0x42; rep->rep_out[117] = 0x42; rep->rep_out[118] = 0x42; rep->rep_out[119] = 0x42; rep->rep_out[158] = 0x4; rep->rep_out[162] = 0x3; } rep->rep_out[rep->rep_outcount + 7] = 8; /* XXX Trailer */ *msglen = sizeof(*rep) - (4096 - rep->rep_outcount); rep->rep_msgh.msgh_size = *msglen - sizeof(rep->rep_trailer); return 0; } int darwin_ioframebuffer_connect_method_structi_structo(args) struct mach_trap_args *args; { mach_io_connect_method_structi_structo_request_t *req = args->smsg; mach_io_connect_method_structi_structo_reply_t *rep = args->rmsg; size_t *msglen = args->rsize; #ifdef DEBUG_DARWIN printf("darwin_ioframebuffer_connect_method_structi_structo()\n"); #endif rep->rep_msgh.msgh_bits = MACH_MSGH_REPLY_LOCAL_BITS(MACH_MSG_TYPE_MOVE_SEND_ONCE); rep->rep_msgh.msgh_size = sizeof(*rep) - sizeof(rep->rep_trailer); rep->rep_msgh.msgh_local_port = req->req_msgh.msgh_local_port; rep->rep_msgh.msgh_id = req->req_msgh.msgh_id + 100; rep->rep_outcount = 1; rep->rep_out[0] = 1; rep->rep_out[rep->rep_outcount + 1] = 8; /* XXX Trailer */ *msglen = sizeof(*rep) - (4096 - rep->rep_outcount); rep->rep_msgh.msgh_size = *msglen - sizeof(rep->rep_trailer); return 0; } int darwin_ioframebuffer_connect_map_memory(args) struct mach_trap_args *args; { mach_io_connect_map_memory_request_t *req = args->smsg; mach_io_connect_map_memory_reply_t *rep = args->rmsg; size_t *msglen = args->rsize; struct proc *p = args->l->l_proc; int error; size_t memsize; size_t len; vaddr_t pvaddr; vaddr_t kvaddr; #ifdef DEBUG_DARWIN printf("darwin_ioframebuffer_connect_map_memory()\n"); #endif switch (req->req_memtype) { case DARWIN_IOFRAMEBUFFER_CURSOR_MEMORY: len = sizeof(struct darwin_ioframebuffer_shmem); memsize = round_page(len); if (darwin_ioframebuffer_shmem == NULL) { darwin_ioframebuffer_shmem = uao_create(memsize, 0); error = uvm_map(kernel_map, &kvaddr, memsize, darwin_ioframebuffer_shmem, 0, PAGE_SIZE, UVM_MAPFLAG(UVM_PROT_RW, UVM_PROT_RW, UVM_INH_SHARE, UVM_ADV_RANDOM, 0)); if (error != 0) { uao_detach(darwin_ioframebuffer_shmem); darwin_ioframebuffer_shmem = NULL; return mach_msg_error(args, error); } if ((error = uvm_map_pageable(kernel_map, kvaddr, kvaddr + memsize, FALSE, 0)) != 0) { uao_detach(darwin_ioframebuffer_shmem); darwin_ioframebuffer_shmem = NULL; return mach_msg_error(args, error); } darwin_ioframebuffer_shmeminit(kvaddr); } uao_reference(darwin_ioframebuffer_shmem); pvaddr = VM_DEFAULT_ADDRESS(p->p_vmspace->vm_daddr, memsize); if ((error = uvm_map(&p->p_vmspace->vm_map, &pvaddr, memsize, darwin_ioframebuffer_shmem, 0, PAGE_SIZE, UVM_MAPFLAG(UVM_PROT_RW, UVM_PROT_RW, UVM_INH_SHARE, UVM_ADV_RANDOM, 0))) != 0) return mach_msg_error(args, error); #ifdef DEBUG_DARWIN printf("pvaddr = 0x%08lx\n", (long)pvaddr); #endif break; case DARWIN_IOFRAMEBUFFER_SYSTEM_APERTURE: case DARWIN_IOFRAMEBUFFER_VRAM_MEMORY: default: #ifdef DEBUG_DARWIN printf("unimplemented memtype %d\n", req->req_memtype); #endif return mach_msg_error(args, EINVAL); break; } rep->rep_msgh.msgh_bits = MACH_MSGH_REPLY_LOCAL_BITS(MACH_MSG_TYPE_MOVE_SEND_ONCE); rep->rep_msgh.msgh_size = sizeof(*rep) - sizeof(rep->rep_trailer); rep->rep_msgh.msgh_local_port = req->req_msgh.msgh_local_port; rep->rep_msgh.msgh_id = req->req_msgh.msgh_id + 100; rep->rep_retval = 0; rep->rep_addr = pvaddr; rep->rep_len = len; rep->rep_trailer.msgh_trailer_size = 8; *msglen = sizeof(*rep); return 0; } void darwin_ioframebuffer_shmeminit(kvaddr) vaddr_t kvaddr; { struct darwin_ioframebuffer_shmem *shmem; shmem = (struct darwin_ioframebuffer_shmem *)kvaddr; return; }