Imported Upstream version 1.15.1
[deb_xorg-server.git] / hw / xfree86 / os-support / shared / vidmem.c
CommitLineData
a09e091a
JB
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#ifdef HAVE_XORG_CONFIG_H
29#include <xorg-config.h>
30#endif
31
32#include <X11/X.h>
33#include "input.h"
34#include "scrnintstr.h"
35
36#include "xf86.h"
37#include "xf86Priv.h"
38#include "xf86_OSlib.h"
39#include "xf86OSpriv.h"
40
41/*
42 * This file contains the common part of the video memory mapping functions
43 */
44
45/*
46 * Get a piece of the ScrnInfoRec. At the moment, this is only used to hold
47 * the MTRR option information, but it is likely to be expanded if we do
48 * auto unmapping of memory at VT switch.
49 *
50 */
51
52typedef struct {
53 unsigned long size;
54 pointer virtBase;
55 pointer mtrrInfo;
56} MappingRec, *MappingPtr;
57
58typedef struct {
59 int numMappings;
60 MappingPtr *mappings;
61 Bool mtrrEnabled;
62 MessageType mtrrFrom;
63 Bool mtrrOptChecked;
64 ScrnInfoPtr pScrn;
65} VidMapRec, *VidMapPtr;
66
67static int vidMapIndex = -1;
68
69#define VIDMAPPTR(p) ((VidMapPtr)((p)->privates[vidMapIndex].ptr))
70
71static VidMemInfo vidMemInfo = { FALSE, };
72static VidMapRec vidMapRec = { 0, NULL, TRUE, X_DEFAULT, FALSE, NULL };
73
74static VidMapPtr
75getVidMapRec(int scrnIndex)
76{
77 VidMapPtr vp;
78 ScrnInfoPtr pScrn;
79
80 if ((scrnIndex < 0) || !(pScrn = xf86Screens[scrnIndex]))
81 return &vidMapRec;
82
83 if (vidMapIndex < 0)
84 vidMapIndex = xf86AllocateScrnInfoPrivateIndex();
85
86 if (VIDMAPPTR(pScrn) != NULL)
87 return VIDMAPPTR(pScrn);
88
89 vp = pScrn->privates[vidMapIndex].ptr = xnfcalloc(sizeof(VidMapRec), 1);
90 vp->mtrrEnabled = TRUE; /* default to enabled */
91 vp->mtrrFrom = X_DEFAULT;
92 vp->mtrrOptChecked = FALSE;
93 vp->pScrn = pScrn;
94 return vp;
95}
96
97static MappingPtr
98newMapping(VidMapPtr vp)
99{
100 vp->mappings = xnfrealloc(vp->mappings, sizeof(MappingPtr) *
101 (vp->numMappings + 1));
102 vp->mappings[vp->numMappings] = xnfcalloc(sizeof(MappingRec), 1);
103 return vp->mappings[vp->numMappings++];
104}
105
106static MappingPtr
107findMapping(VidMapPtr vp, pointer vbase, unsigned long size)
108{
109 int i;
110
111 for (i = 0; i < vp->numMappings; i++) {
112 if (vp->mappings[i]->virtBase == vbase && vp->mappings[i]->size == size)
113 return vp->mappings[i];
114 }
115 return NULL;
116}
117
118static void
119removeMapping(VidMapPtr vp, MappingPtr mp)
120{
121 int i, found = 0;
122
123 for (i = 0; i < vp->numMappings; i++) {
124 if (vp->mappings[i] == mp) {
125 found = 1;
126 free(vp->mappings[i]);
127 }
128 else if (found) {
129 vp->mappings[i - 1] = vp->mappings[i];
130 }
131 }
132 vp->numMappings--;
133 vp->mappings[vp->numMappings] = NULL;
134}
135
136enum { OPTION_MTRR };
137
138static const OptionInfoRec opts[] = {
139 {OPTION_MTRR, "mtrr", OPTV_BOOLEAN, {0}, FALSE},
140 {-1, NULL, OPTV_NONE, {0}, FALSE}
141};
142
143static void
144checkMtrrOption(VidMapPtr vp)
145{
146 if (!vp->mtrrOptChecked && vp->pScrn && vp->pScrn->options != NULL) {
147 OptionInfoPtr options;
148
149 options = xnfalloc(sizeof(opts));
150 (void) memcpy(options, opts, sizeof(opts));
151 xf86ProcessOptions(vp->pScrn->scrnIndex, vp->pScrn->options, options);
152 if (xf86GetOptValBool(options, OPTION_MTRR, &vp->mtrrEnabled))
153 vp->mtrrFrom = X_CONFIG;
154 free(options);
155 vp->mtrrOptChecked = TRUE;
156 }
157}
158
159void
160xf86InitVidMem(void)
161{
162 if (!vidMemInfo.initialised) {
163 memset(&vidMemInfo, 0, sizeof(VidMemInfo));
164 xf86OSInitVidMem(&vidMemInfo);
165 }
166}
167
168pointer
169xf86MapVidMem(int ScreenNum, int Flags, unsigned long Base, unsigned long Size)
170{
171 pointer vbase = NULL;
172 VidMapPtr vp;
173 MappingPtr mp;
174
175 if (((Flags & VIDMEM_FRAMEBUFFER) &&
176 (Flags & (VIDMEM_MMIO | VIDMEM_MMIO_32BIT))))
177 FatalError("Mapping memory with more than one type\n");
178
179 xf86InitVidMem();
180 if (!vidMemInfo.initialised || !vidMemInfo.mapMem)
181 return NULL;
182
183 vbase = vidMemInfo.mapMem(ScreenNum, Base, Size, Flags);
184
185 if (!vbase || vbase == (pointer) -1)
186 return NULL;
187
188 vp = getVidMapRec(ScreenNum);
189 mp = newMapping(vp);
190 mp->size = Size;
191 mp->virtBase = vbase;
192
193 /*
194 * Check the "mtrr" option even when MTRR isn't supported to avoid
195 * warnings about unrecognised options.
196 */
197 checkMtrrOption(vp);
198
199 if (vp->mtrrEnabled && vidMemInfo.setWC) {
200 if (Flags & (VIDMEM_MMIO | VIDMEM_MMIO_32BIT))
201 mp->mtrrInfo =
202 vidMemInfo.setWC(ScreenNum, Base, Size, FALSE, vp->mtrrFrom);
203 else if (Flags & VIDMEM_FRAMEBUFFER)
204 mp->mtrrInfo =
205 vidMemInfo.setWC(ScreenNum, Base, Size, TRUE, vp->mtrrFrom);
206 }
207 return vbase;
208}
209
210void
211xf86UnMapVidMem(int ScreenNum, pointer Base, unsigned long Size)
212{
213 VidMapPtr vp;
214 MappingPtr mp;
215
216 if (!vidMemInfo.initialised || !vidMemInfo.unmapMem) {
217 xf86DrvMsg(ScreenNum, X_WARNING,
218 "xf86UnMapVidMem() called before xf86MapVidMem()\n");
219 return;
220 }
221
222 vp = getVidMapRec(ScreenNum);
223 mp = findMapping(vp, Base, Size);
224 if (!mp) {
225 xf86DrvMsg(ScreenNum, X_WARNING,
226 "xf86UnMapVidMem: cannot find region for [%p,0x%lx]\n",
227 Base, Size);
228 return;
229 }
230 if (vp->mtrrEnabled && vidMemInfo.undoWC && mp)
231 vidMemInfo.undoWC(ScreenNum, mp->mtrrInfo);
232
233 vidMemInfo.unmapMem(ScreenNum, Base, Size);
234 removeMapping(vp, mp);
235}
236
237Bool
238xf86CheckMTRR(int ScreenNum)
239{
240 VidMapPtr vp = getVidMapRec(ScreenNum);
241
242 /*
243 * Check the "mtrr" option even when MTRR isn't supported to avoid
244 * warnings about unrecognised options.
245 */
246 checkMtrrOption(vp);
247
248 if (vp->mtrrEnabled && vidMemInfo.setWC)
249 return TRUE;
250
251 return FALSE;
252}
253
254Bool
255xf86LinearVidMem(void)
256{
257 xf86InitVidMem();
258 return vidMemInfo.linearSupported;
259}