]> git.sur5r.net Git - u-boot/blob - board/MAI/bios_emulator/scitech/src/pm/tests/uswc.c
* Code cleanup:
[u-boot] / board / MAI / bios_emulator / scitech / src / pm / tests / uswc.c
1 /****************************************************************************
2 *
3 *                   SciTech OS Portability Manager Library
4 *
5 *  ========================================================================
6 *
7 *    The contents of this file are subject to the SciTech MGL Public
8 *    License Version 1.0 (the "License"); you may not use this file
9 *    except in compliance with the License. You may obtain a copy of
10 *    the License at http://www.scitechsoft.com/mgl-license.txt
11 *
12 *    Software distributed under the License is distributed on an
13 *    "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
14 *    implied. See the License for the specific language governing
15 *    rights and limitations under the License.
16 *
17 *    The Original Code is Copyright (C) 1991-1998 SciTech Software, Inc.
18 *
19 *    The Initial Developer of the Original Code is SciTech Software, Inc.
20 *    All Rights Reserved.
21 *
22 *  ========================================================================
23 *
24 * Language:     ANSI C
25 * Environment:  any
26 *
27 * Description:  Simple test program to test the write combine functions.
28 *
29 *               Note that this program should never be used in a production
30 *               environment, because write combining needs to be handled
31 *               with more intimate knowledge of the display hardware than
32 *               you can obtain by simply examining the PCI configuration
33 *               space.
34 *
35 ****************************************************************************/
36
37 #include "pmapi.h"
38 #include "pcilib.h"
39 #include <stdio.h>
40 #include <stdlib.h>
41 #include <string.h>
42 #include <stdarg.h>
43
44 /*------------------------- Global Variables ------------------------------*/
45
46 static int              NumPCI = -1;
47 static PCIDeviceInfo    *PCI;
48 static int              *BridgeIndex;
49 static int              *DeviceIndex;
50 static int              NumBridges;
51 static PCIDeviceInfo    *AGPBridge = NULL;
52 static int              NumDevices;
53
54 /*-------------------------- Implementation -------------------------------*/
55
56 /****************************************************************************
57 RETURNS:
58 Number of display devices found.
59
60 REMARKS:
61 This function enumerates the number of available display devices on the
62 PCI bus, and returns the number found.
63 ****************************************************************************/
64 static int PCI_enumerateDevices(void)
65 {
66     int             i,j;
67     PCIDeviceInfo   *info;
68
69     /* If this is the first time we have been called, enumerate all */
70     /* devices on the PCI bus. */
71     if (NumPCI == -1) {
72         if ((NumPCI = PCI_getNumDevices()) == 0)
73             return -1;
74         PCI = malloc(NumPCI * sizeof(PCI[0]));
75         BridgeIndex = malloc(NumPCI * sizeof(BridgeIndex[0]));
76         DeviceIndex = malloc(NumPCI * sizeof(DeviceIndex[0]));
77         if (!PCI || !BridgeIndex || !DeviceIndex)
78             return -1;
79         for (i = 0; i < NumPCI; i++)
80             PCI[i].dwSize = sizeof(PCI[i]);
81         if (PCI_enumerate(PCI) == 0)
82             return -1;
83
84         /* Build a list of all PCI bridge devices */
85         for (i = 0,NumBridges = 0,BridgeIndex[0] = -1; i < NumPCI; i++) {
86             if (PCI[i].BaseClass == PCI_BRIDGE_CLASS)
87                 BridgeIndex[NumBridges++] = i;
88             }
89
90         /* Now build a list of all display class devices */
91         for (i = 0,NumDevices = 1,DeviceIndex[0] = -1; i < NumPCI; i++) {
92             if (PCI_IS_DISPLAY_CLASS(&PCI[i])) {
93                 if ((PCI[i].Command & 0x3) == 0x3)
94                     DeviceIndex[0] = i;
95                 else
96                     DeviceIndex[NumDevices++] = i;
97                 if (PCI[i].slot.p.Bus != 0) {
98                     /* This device is on a different bus than the primary */
99                     /* PCI bus, so it is probably an AGP device. Find the */
100                     /* AGP bus device that controls that bus so we can */
101                     /* control it. */
102                     for (j = 0; j < NumBridges; j++) {
103                         info = (PCIDeviceInfo*)&PCI[BridgeIndex[j]];
104                         if (info->u.type1.SecondayBusNumber == PCI[i].slot.p.Bus) {
105                             AGPBridge = info;
106                             break;
107                             }
108                         }
109                     }
110                 }
111             }
112         }
113     return NumDevices;
114 }
115
116 /****************************************************************************
117 REMARKS:
118 Enumerates useful information about attached display devices.
119 ****************************************************************************/
120 static void ShowDisplayDevices(void)
121 {
122     int i,index;
123
124     printf("Displaying enumeration of %d PCI display devices\n", NumDevices);
125     printf("\n");
126     printf("DeviceID  SubSystem  Base10h  (length  )  Base14h  (length  )\n");
127     for (index = 0; index < NumDevices; index++) {
128         i = DeviceIndex[index];
129         printf("%04X:%04X %04X:%04X  %08lX (%6ld KB) %08lX (%6ld KB)\n",
130             PCI[i].VendorID,
131             PCI[i].DeviceID,
132             PCI[i].u.type0.SubSystemVendorID,
133             PCI[i].u.type0.SubSystemID,
134             PCI[i].u.type0.BaseAddress10,
135             PCI[i].u.type0.BaseAddress10Len / 1024,
136             PCI[i].u.type0.BaseAddress14,
137             PCI[i].u.type0.BaseAddress14Len / 1024);
138         }
139     printf("\n");
140 }
141
142 /****************************************************************************
143 REMARKS:
144 Dumps the value for a write combine region to the display.
145 ****************************************************************************/
146 static char *DecodeWCType(
147     uint type)
148 {
149     static char *names[] = {
150         "UNCACHABLE",
151         "WRCOMB",
152         "UNKNOWN",
153         "UNKNOWN",
154         "WRTHROUGH",
155         "WRPROT",
156         "WRBACK",
157         };
158     if (type <= PM_MTRR_MAX)
159         return names[type];
160     return "UNKNOWN";
161 }
162
163 /****************************************************************************
164 REMARKS:
165 Dumps the value for a write combine region to the display.
166 ****************************************************************************/
167 static void PMAPI EnumWriteCombine(
168     ulong base,
169     ulong length,
170     uint type)
171 {
172     printf("%08lX %-10ld %s\n", base, length / 1024, DecodeWCType(type));
173 }
174
175 /****************************************************************************
176 PARAMETERS:
177 err - Error to log
178
179 REMARKS:
180 Function to log an error message if the MTRR write combining attempt failed.
181 ****************************************************************************/
182 static void LogMTRRError(
183     int err)
184 {
185     if (err == PM_MTRR_ERR_OK)
186         return;
187     switch (err) {
188         case PM_MTRR_NOT_SUPPORTED:
189             printf("Failed: MTRR is not supported by host CPU\n");
190             break;
191         case PM_MTRR_ERR_PARAMS:
192             printf("Failed: Invalid parameters passed to PM_enableWriteCombined!\n");
193             break;
194         case PM_MTRR_ERR_NOT_4KB_ALIGNED:
195             printf("Failed: Address is not 4Kb aligned!\n");
196             break;
197         case PM_MTRR_ERR_BELOW_1MB:
198             printf("Failed: Addresses below 1Mb cannot be write combined!\n");
199             break;
200         case PM_MTRR_ERR_NOT_ALIGNED:
201             printf("Failed: Address is not correctly aligned for processor!\n");
202             break;
203         case PM_MTRR_ERR_OVERLAP:
204             printf("Failed: Address overlaps an existing region!\n");
205             break;
206         case PM_MTRR_ERR_TYPE_MISMATCH:
207             printf("Failed: Adress is contained with existing region, but type is different!\n");
208             break;
209         case PM_MTRR_ERR_NONE_FREE:
210             printf("Failed: Out of MTRR registers!\n");
211             break;
212         case PM_MTRR_ERR_NOWRCOMB:
213             printf("Failed: This processor does not support write combining!\n");
214             break;
215         case PM_MTRR_ERR_NO_OS_SUPPORT:
216             printf("Failed: MTRR is not supported by host OS\n");
217             break;
218         default:
219             printf("Failed: UNKNOWN ERROR!\n");
220             break;
221         }
222     exit(-1);
223 }
224
225 /****************************************************************************
226 REMARKS:
227 Shows all write combine regions.
228 ****************************************************************************/
229 static void ShowWriteCombine(void)
230 {
231     printf("Base     Length(KB) Type\n");
232     LogMTRRError(PM_enumWriteCombine(EnumWriteCombine));
233     printf("\n");
234 }
235
236 /****************************************************************************
237 REMARKS:
238 Dumps the value for a write combine region to the display.
239 ****************************************************************************/
240 static void EnableWriteCombine(void)
241 {
242     int i,index;
243
244     for (index = 0; index < NumDevices; index++) {
245         i = DeviceIndex[index];
246         if (PCI[i].u.type0.BaseAddress10 & 0x8) {
247             LogMTRRError(PM_enableWriteCombine(
248                 PCI[i].u.type0.BaseAddress10 & 0xFFFFFFF0,
249                 PCI[i].u.type0.BaseAddress10Len,
250                 PM_MTRR_WRCOMB));
251             }
252         if (PCI[i].u.type0.BaseAddress14 & 0x8) {
253             LogMTRRError(PM_enableWriteCombine(
254                 PCI[i].u.type0.BaseAddress14 & 0xFFFFFFF0,
255                 PCI[i].u.type0.BaseAddress14Len,
256                 PM_MTRR_WRCOMB));
257             }
258         }
259     printf("\n");
260     ShowDisplayDevices();
261     ShowWriteCombine();
262 }
263
264 /****************************************************************************
265 REMARKS:
266 Dumps the value for a write combine region to the display.
267 ****************************************************************************/
268 static void DisableWriteCombine(void)
269 {
270     int i,index;
271
272     for (index = 0; index < NumDevices; index++) {
273         i = DeviceIndex[index];
274         if (PCI[i].u.type0.BaseAddress10 & 0x8) {
275             LogMTRRError(PM_enableWriteCombine(
276                 PCI[i].u.type0.BaseAddress10 & 0xFFFFFFF0,
277                 PCI[i].u.type0.BaseAddress10Len,
278                 PM_MTRR_UNCACHABLE));
279             }
280         if (PCI[i].u.type0.BaseAddress14 & 0x8) {
281             LogMTRRError(PM_enableWriteCombine(
282                 PCI[i].u.type0.BaseAddress14 & 0xFFFFFFF0,
283                 PCI[i].u.type0.BaseAddress14Len,
284                 PM_MTRR_UNCACHABLE));
285             }
286         }
287     printf("\n");
288     ShowDisplayDevices();
289     ShowWriteCombine();
290 }
291
292 int main(int argc,char *argv[])
293 {
294     PM_init();
295     if (PCI_enumerateDevices() < 1) {
296         printf("No PCI display devices found!\n");
297         return -1;
298         }
299     if (argc < 2) {
300         printf("usage: uswc [-show -on -off]\n\n");
301         ShowDisplayDevices();
302         return -1;
303         }
304     if (stricmp(argv[1],"-show") == 0)
305         ShowWriteCombine();
306     else if (stricmp(argv[1],"-on") == 0)
307         EnableWriteCombine();
308     else if (stricmp(argv[1],"-off") == 0)
309         DisableWriteCombine();
310     return 0;
311 }