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 53 typedef struct { 54 unsigned long physBase; 55 unsigned long size; 56 pointer virtBase; 57 pointer mtrrInfo; 58 int flags; 59 } MappingRec, *MappingPtr; 60 61 typedef struct { 62 int numMappings; 63 MappingPtr * mappings; 64 Bool mtrrEnabled; 65 MessageType mtrrFrom; 66 Bool mtrrOptChecked; 67 ScrnInfoPtr pScrn; 68 } VidMapRec, *VidMapPtr; 69 70 static int vidMapIndex = -1; 71 72 #define VIDMAPPTR(p) ((VidMapPtr)((p)->privates[vidMapIndex].ptr)) 73 74 static VidMemInfo vidMemInfo = {FALSE, }; 75 static VidMapRec vidMapRec = {0, NULL, TRUE, X_DEFAULT, FALSE, NULL}; 76 77 static VidMapPtr 78 getVidMapRec(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 101 static MappingPtr 102 newMapping(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 110 static MappingPtr 111 findMapping(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 123 static void 124 removeMapping(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 140 enum { OPTION_MTRR }; 141 static const OptionInfoRec opts[] = 142 { 143 { OPTION_MTRR, "mtrr", OPTV_BOOLEAN, {0}, FALSE }, 144 { -1, NULL, OPTV_NONE, {0}, FALSE } 145 }; 146 147 static void 148 checkMtrrOption(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 164 void 165 xf86MakeNewMapping(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 178 void 179 xf86InitVidMem(void) 180 { 181 if (!vidMemInfo.initialised) { 182 memset(&vidMemInfo, 0, sizeof(VidMemInfo)); 183 xf86OSInitVidMem(&vidMemInfo); 184 } 185 } 186 187 pointer 188 xf86MapVidMem(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 233 void 234 xf86UnMapVidMem(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 260 Bool 261 xf86CheckMTRR(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 277 Bool 278 xf86LinearVidMem(void) 279 { 280 xf86InitVidMem(); 281 return vidMemInfo.linearSupported; 282 } 283 284 void 285 xf86MapReadSideEffects(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