1/* 2 * Copyright (c) 1993-2003 by The XFree86 Project, Inc. 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice shall be included in 12 * all copies or substantial portions of the Software. 13 * 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20 * OTHER DEALINGS IN THE SOFTWARE. 21 * 22 * Except as contained in this notice, the name of the copyright holder(s) 23 * and author(s) shall not be used in advertising or otherwise to promote 24 * the sale, use or other dealings in this Software without prior written 25 * authorization from the copyright holder(s) and author(s). 26 */ 27 28 29#ifdef HAVE_XORG_CONFIG_H 30#include <xorg-config.h> 31#endif 32 33#include <X11/X.h> 34#include "input.h" 35#include "scrnintstr.h" 36 37#include "xf86.h" 38#include "xf86Priv.h" 39#include "xf86_OSlib.h" 40#include "xf86OSpriv.h" 41 42/* 43 * This file contains the common part of the video memory mapping functions 44 */ 45 46/* 47 * Get a piece of the ScrnInfoRec. At the moment, this is only used to hold 48 * the MTRR option information, but it is likely to be expanded if we do 49 * auto unmapping of memory at VT switch. 50 * 51 */ 52 53typedef struct { 54 unsigned long physBase; 55 unsigned long size; 56 pointer virtBase; 57 pointer mtrrInfo; 58 int flags; 59} MappingRec, *MappingPtr; 60 61typedef struct { 62 int numMappings; 63 MappingPtr * mappings; 64 Bool mtrrEnabled; 65 MessageType mtrrFrom; 66 Bool mtrrOptChecked; 67 ScrnInfoPtr pScrn; 68} VidMapRec, *VidMapPtr; 69 70static int vidMapIndex = -1; 71 72#define VIDMAPPTR(p) ((VidMapPtr)((p)->privates[vidMapIndex].ptr)) 73 74static VidMemInfo vidMemInfo = {FALSE, }; 75static VidMapRec vidMapRec = {0, NULL, TRUE, X_DEFAULT, FALSE, NULL}; 76 77static VidMapPtr 78getVidMapRec(int scrnIndex) 79{ 80 VidMapPtr vp; 81 ScrnInfoPtr pScrn; 82 83 if ((scrnIndex < 0) || 84 !(pScrn = xf86Screens[scrnIndex])) 85 return &vidMapRec; 86 87 if (vidMapIndex < 0) 88 vidMapIndex = xf86AllocateScrnInfoPrivateIndex(); 89 90 if (VIDMAPPTR(pScrn) != NULL) 91 return VIDMAPPTR(pScrn); 92 93 vp = pScrn->privates[vidMapIndex].ptr = xnfcalloc(sizeof(VidMapRec), 1); 94 vp->mtrrEnabled = TRUE; /* default to enabled */ 95 vp->mtrrFrom = X_DEFAULT; 96 vp->mtrrOptChecked = FALSE; 97 vp->pScrn = pScrn; 98 return vp; 99} 100 101static MappingPtr 102newMapping(VidMapPtr vp) 103{ 104 vp->mappings = xnfrealloc(vp->mappings, sizeof(MappingPtr) * 105 (vp->numMappings + 1)); 106 vp->mappings[vp->numMappings] = xnfcalloc(sizeof(MappingRec), 1); 107 return vp->mappings[vp->numMappings++]; 108} 109 110static MappingPtr 111findMapping(VidMapPtr vp, pointer vbase, unsigned long size) 112{ 113 int i; 114 115 for (i = 0; i < vp->numMappings; i++) { 116 if (vp->mappings[i]->virtBase == vbase && 117 vp->mappings[i]->size == size) 118 return vp->mappings[i]; 119 } 120 return NULL; 121} 122 123static void 124removeMapping(VidMapPtr vp, MappingPtr mp) 125{ 126 int i, found = 0; 127 128 for (i = 0; i < vp->numMappings; i++) { 129 if (vp->mappings[i] == mp) { 130 found = 1; 131 free(vp->mappings[i]); 132 } else if (found) { 133 vp->mappings[i - 1] = vp->mappings[i]; 134 } 135 } 136 vp->numMappings--; 137 vp->mappings[vp->numMappings] = NULL; 138} 139 140enum { OPTION_MTRR }; 141static const OptionInfoRec opts[] = 142{ 143 { OPTION_MTRR, "mtrr", OPTV_BOOLEAN, {0}, FALSE }, 144 { -1, NULL, OPTV_NONE, {0}, FALSE } 145}; 146 147static void 148checkMtrrOption(VidMapPtr vp) 149{ 150 if (!vp->mtrrOptChecked && vp->pScrn && vp->pScrn->options != NULL) { 151 OptionInfoPtr options; 152 153 options = xnfalloc(sizeof(opts)); 154 (void)memcpy(options, opts, sizeof(opts)); 155 xf86ProcessOptions(vp->pScrn->scrnIndex, vp->pScrn->options, 156 options); 157 if (xf86GetOptValBool(options, OPTION_MTRR, &vp->mtrrEnabled)) 158 vp->mtrrFrom = X_CONFIG; 159 free(options); 160 vp->mtrrOptChecked = TRUE; 161 } 162} 163 164void 165xf86MakeNewMapping(int ScreenNum, int Flags, unsigned long Base, unsigned long Size, pointer Vbase) 166{ 167 VidMapPtr vp; 168 MappingPtr mp; 169 170 vp = getVidMapRec(ScreenNum); 171 mp = newMapping(vp); 172 mp->physBase = Base; 173 mp->size = Size; 174 mp->virtBase = Vbase; 175 mp->flags = Flags; 176} 177 178void 179xf86InitVidMem(void) 180{ 181 if (!vidMemInfo.initialised) { 182 memset(&vidMemInfo, 0, sizeof(VidMemInfo)); 183 xf86OSInitVidMem(&vidMemInfo); 184 } 185} 186 187pointer 188xf86MapVidMem(int ScreenNum, int Flags, unsigned long Base, unsigned long Size) 189{ 190 pointer vbase = NULL; 191 VidMapPtr vp; 192 MappingPtr mp; 193 194 if (((Flags & VIDMEM_FRAMEBUFFER) && 195 (Flags & (VIDMEM_MMIO | VIDMEM_MMIO_32BIT)))) 196 FatalError("Mapping memory with more than one type\n"); 197 198 xf86InitVidMem(); 199 if (!vidMemInfo.initialised || !vidMemInfo.mapMem) 200 return NULL; 201 202 vbase = vidMemInfo.mapMem(ScreenNum, Base, Size, Flags); 203 204 if (!vbase || vbase == (pointer)-1) 205 return NULL; 206 207 vp = getVidMapRec(ScreenNum); 208 mp = newMapping(vp); 209 mp->physBase = Base; 210 mp->size = Size; 211 mp->virtBase = vbase; 212 mp->flags = Flags; 213 214 /* 215 * Check the "mtrr" option even when MTRR isn't supported to avoid 216 * warnings about unrecognised options. 217 */ 218 checkMtrrOption(vp); 219 220 if (vp->mtrrEnabled && vidMemInfo.setWC) { 221 if (Flags & (VIDMEM_MMIO | VIDMEM_MMIO_32BIT)) 222 mp->mtrrInfo = 223 vidMemInfo.setWC(ScreenNum, Base, Size, FALSE, 224 vp->mtrrFrom); 225 else if (Flags & VIDMEM_FRAMEBUFFER) 226 mp->mtrrInfo = 227 vidMemInfo.setWC(ScreenNum, Base, Size, TRUE, 228 vp->mtrrFrom); 229 } 230 return vbase; 231} 232 233void 234xf86UnMapVidMem(int ScreenNum, pointer Base, unsigned long Size) 235{ 236 VidMapPtr vp; 237 MappingPtr mp; 238 239 if (!vidMemInfo.initialised || !vidMemInfo.unmapMem) { 240 xf86DrvMsg(ScreenNum, X_WARNING, 241 "xf86UnMapVidMem() called before xf86MapVidMem()\n"); 242 return; 243 } 244 245 vp = getVidMapRec(ScreenNum); 246 mp = findMapping(vp, Base, Size); 247 if (!mp) { 248 xf86DrvMsg(ScreenNum, X_WARNING, 249 "xf86UnMapVidMem: cannot find region for [%p,0x%lx]\n", 250 Base, Size); 251 return; 252 } 253 if (vp->mtrrEnabled && vidMemInfo.undoWC && mp) 254 vidMemInfo.undoWC(ScreenNum, mp->mtrrInfo); 255 256 vidMemInfo.unmapMem(ScreenNum, Base, Size); 257 removeMapping(vp, mp); 258} 259 260Bool 261xf86CheckMTRR(int ScreenNum) 262{ 263 VidMapPtr vp = getVidMapRec(ScreenNum); 264 265 /* 266 * Check the "mtrr" option even when MTRR isn't supported to avoid 267 * warnings about unrecognised options. 268 */ 269 checkMtrrOption(vp); 270 271 if (vp->mtrrEnabled && vidMemInfo.setWC) 272 return TRUE; 273 274 return FALSE; 275} 276 277Bool 278xf86LinearVidMem(void) 279{ 280 xf86InitVidMem(); 281 return vidMemInfo.linearSupported; 282} 283 284void 285xf86MapReadSideEffects(int ScreenNum, int Flags, pointer base, 286 unsigned long Size) 287{ 288 if (!(Flags & VIDMEM_READSIDEEFFECT)) 289 return; 290 291 if (!vidMemInfo.initialised || !vidMemInfo.readSideEffects) 292 return; 293 294 vidMemInfo.readSideEffects(ScreenNum, base, Size); 295} 296 297