Updated MSA by putting Specification element at the end of the header section
[mirror_edk2.git] / EdkModulePkg / Bus / Pci / CirrusLogic / Dxe / CirrusLogic5430UgaDraw.c
CommitLineData
878ddf1f 1/*++\r
2\r
3Copyright (c) 2006, Intel Corporation \r
4All rights reserved. This program and the accompanying materials \r
5are licensed and made available under the terms and conditions of the BSD License \r
6which accompanies this distribution. The full text of the license may be found at \r
7http://opensource.org/licenses/bsd-license.php \r
8 \r
9THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
10WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
11\r
12Module Name:\r
13\r
14 CirrusLogic5430UgaDraw.c\r
15\r
16Abstract:\r
17\r
18 This file produces the graphics abstration of UGA Draw. It is called by \r
19 CirrusLogic5430.c file which deals with the EFI 1.1 driver model. \r
20 This file just does graphics.\r
21\r
22--*/\r
23\r
24#include "CirrusLogic5430.h"\r
25\r
26//\r
27// Video Mode structure\r
28//\r
29typedef struct {\r
30 UINT32 Width;\r
31 UINT32 Height;\r
32 UINT32 ColorDepth;\r
33 UINT32 RefreshRate;\r
34 UINT8 *CrtcSettings;\r
35 UINT16 *SeqSettings;\r
36 UINT8 MiscSetting;\r
37} CIRRUS_LOGIC_5430_VIDEO_MODES;\r
38\r
39//\r
40// Generic Attribute Controller Register Settings\r
41//\r
42static UINT8 AttributeController[21] = {\r
43 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, \r
44 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, \r
45 0x41, 0x00, 0x0F, 0x00, 0x00\r
46};\r
47\r
48//\r
49// Generic Graphics Controller Register Settings\r
50//\r
51static UINT8 GraphicsController[9] = {\r
52 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, 0xFF\r
53};\r
54\r
55//\r
56// 640 x 480 x 256 color @ 60 Hertz\r
57//\r
58static UINT8 Crtc_640_480_256_60[28] = {\r
59 0x5d, 0x4f, 0x50, 0x82, 0x53, 0x9f, 0x00, 0x3e,\r
60 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \r
61 0xe1, 0x83, 0xdf, 0x50, 0x00, 0xe7, 0x04, 0xe3,\r
62 0xff, 0x00, 0x00, 0x22\r
63};\r
64\r
65static UINT16 Seq_640_480_256_60[15] = {\r
66 0x0100, 0x0101, 0x0f02, 0x0003, 0x0e04, 0x1107, 0x0008, 0x4a0b, \r
67 0x5b0c, 0x450d, 0x7e0e, 0x2b1b, 0x2f1c, 0x301d, 0x331e\r
68};\r
69\r
70//\r
71// 800 x 600 x 256 color @ 60 Hertz\r
72//\r
73static UINT8 Crtc_800_600_256_60[28] = {\r
74 0x7F, 0x63, 0x64, 0x80, 0x6B, 0x1B, 0x72, 0xF0, \r
75 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \r
76 0x58, 0x8C, 0x57, 0x64, 0x00, 0x5F, 0x91, 0xE3,\r
77 0xFF, 0x00, 0x00, 0x22\r
78};\r
79\r
80static UINT16 Seq_800_600_256_60[15] = {\r
81 0x0100, 0x0101, 0x0f02, 0x0003, 0x0e04, 0x1107, 0x0008, 0x4a0b, \r
82 0x5b0c, 0x450d, 0x510e, 0x2b1b, 0x2f1c, 0x301d, 0x3a1e\r
83};\r
84\r
85//\r
86// 1024 x 768 x 256 color @ 60 Hertz\r
87//\r
88static UINT8 Crtc_1024_768_256_60[28] = {\r
89 0xA3, 0x7F, 0x80, 0x86, 0x85, 0x96, 0x24, 0xFD, \r
90 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \r
91 0x02, 0x88, 0xFF, 0x80, 0x00, 0x00, 0x24, 0xE3,\r
92 0xFF, 0x4A, 0x00, 0x22\r
93};\r
94\r
95static UINT16 Seq_1024_768_256_60[15] = {\r
96 0x0100, 0x0101, 0x0f02, 0x0003, 0x0e04, 0x1107, 0x0008, 0x4a0b, \r
97 0x5b0c, 0x450d, 0x760e, 0x2b1b, 0x2f1c, 0x301d, 0x341e\r
98};\r
99\r
100//\r
101// Table of supported video modes\r
102//\r
103static CIRRUS_LOGIC_5430_VIDEO_MODES CirrusLogic5430VideoModes[] = {\r
104 { 640, 480, 8, 60, Crtc_640_480_256_60, Seq_640_480_256_60, 0xe3 },\r
105 { 800, 600, 8, 60, Crtc_800_600_256_60, Seq_800_600_256_60, 0xef }, \r
106 { 1024, 768, 8, 60, Crtc_1024_768_256_60, Seq_1024_768_256_60, 0xef } \r
107};\r
108\r
109//\r
110// Local Function Prototypes\r
111//\r
112VOID\r
113InitializeGraphicsMode (\r
114 CIRRUS_LOGIC_5430_PRIVATE_DATA *Private,\r
115 CIRRUS_LOGIC_5430_VIDEO_MODES *ModeData\r
116 );\r
117\r
118VOID\r
119SetPaletteColor (\r
120 CIRRUS_LOGIC_5430_PRIVATE_DATA *Private,\r
121 UINTN Index,\r
122 UINT8 Red,\r
123 UINT8 Green,\r
124 UINT8 Blue\r
125 );\r
126\r
127VOID\r
128SetDefaultPalette (\r
129 CIRRUS_LOGIC_5430_PRIVATE_DATA *Private\r
130 );\r
131\r
132STATIC\r
133VOID\r
134ClearScreen (\r
135 CIRRUS_LOGIC_5430_PRIVATE_DATA *Private\r
136 );\r
137\r
138VOID\r
139DrawLogo (\r
140 CIRRUS_LOGIC_5430_PRIVATE_DATA *Private\r
141 );\r
142\r
143VOID\r
144outb (\r
145 CIRRUS_LOGIC_5430_PRIVATE_DATA *Private,\r
146 UINTN Address,\r
147 UINT8 Data\r
148 );\r
149\r
150VOID\r
151outw (\r
152 CIRRUS_LOGIC_5430_PRIVATE_DATA *Private,\r
153 UINTN Address,\r
154 UINT16 Data\r
155 );\r
156\r
157UINT8\r
158inb (\r
159 CIRRUS_LOGIC_5430_PRIVATE_DATA *Private,\r
160 UINTN Address\r
161 );\r
162\r
163UINT16\r
164inw (\r
165 CIRRUS_LOGIC_5430_PRIVATE_DATA *Private,\r
166 UINTN Address\r
167 );\r
168\r
169//\r
170// UGA Draw Protocol Member Functions\r
171//\r
172EFI_STATUS\r
173EFIAPI\r
174CirrusLogic5430UgaDrawGetMode (\r
175 IN EFI_UGA_DRAW_PROTOCOL *This,\r
176 OUT UINT32 *HorizontalResolution,\r
177 OUT UINT32 *VerticalResolution,\r
178 OUT UINT32 *ColorDepth,\r
179 OUT UINT32 *RefreshRate\r
180 )\r
181/*++\r
182\r
183Routine Description:\r
184\r
185 TODO: Add function description\r
186\r
187Arguments:\r
188\r
189 This - TODO: add argument description\r
190 HorizontalResolution - TODO: add argument description\r
191 VerticalResolution - TODO: add argument description\r
192 ColorDepth - TODO: add argument description\r
193 RefreshRate - TODO: add argument description\r
194\r
195Returns:\r
196\r
197 EFI_NOT_STARTED - TODO: Add description for return value\r
198 EFI_INVALID_PARAMETER - TODO: Add description for return value\r
199 EFI_SUCCESS - TODO: Add description for return value\r
200\r
201--*/\r
202{\r
203 CIRRUS_LOGIC_5430_PRIVATE_DATA *Private;\r
204\r
205 Private = CIRRUS_LOGIC_5430_PRIVATE_DATA_FROM_UGA_DRAW_THIS (This);\r
206\r
207 if (Private->HardwareNeedsStarting) {\r
208 return EFI_NOT_STARTED;\r
209 }\r
210\r
211 if ((HorizontalResolution == NULL) ||\r
212 (VerticalResolution == NULL) ||\r
213 (ColorDepth == NULL) ||\r
214 (RefreshRate == NULL)) {\r
215 return EFI_INVALID_PARAMETER;\r
216 }\r
217\r
218 *HorizontalResolution = Private->ModeData[Private->CurrentMode].HorizontalResolution;\r
219 *VerticalResolution = Private->ModeData[Private->CurrentMode].VerticalResolution;\r
220 *ColorDepth = Private->ModeData[Private->CurrentMode].ColorDepth;\r
221 *RefreshRate = Private->ModeData[Private->CurrentMode].RefreshRate;\r
222\r
223 return EFI_SUCCESS;\r
224}\r
225\r
226EFI_STATUS\r
227EFIAPI\r
228CirrusLogic5430UgaDrawSetMode (\r
229 IN EFI_UGA_DRAW_PROTOCOL *This,\r
230 IN UINT32 HorizontalResolution,\r
231 IN UINT32 VerticalResolution,\r
232 IN UINT32 ColorDepth,\r
233 IN UINT32 RefreshRate\r
234 )\r
235/*++\r
236\r
237Routine Description:\r
238\r
239 TODO: Add function description\r
240\r
241Arguments:\r
242\r
243 This - TODO: add argument description\r
244 HorizontalResolution - TODO: add argument description\r
245 VerticalResolution - TODO: add argument description\r
246 ColorDepth - TODO: add argument description\r
247 RefreshRate - TODO: add argument description\r
248\r
249Returns:\r
250\r
251 EFI_OUT_OF_RESOURCES - TODO: Add description for return value\r
252 EFI_SUCCESS - TODO: Add description for return value\r
253 EFI_NOT_FOUND - TODO: Add description for return value\r
254\r
255--*/\r
256{\r
257 CIRRUS_LOGIC_5430_PRIVATE_DATA *Private;\r
258 UINTN Index;\r
259\r
260 Private = CIRRUS_LOGIC_5430_PRIVATE_DATA_FROM_UGA_DRAW_THIS (This);\r
261\r
262 for (Index = 0; Index < Private->MaxMode; Index++) {\r
263\r
264 if (HorizontalResolution != Private->ModeData[Index].HorizontalResolution) {\r
265 continue;\r
266 }\r
267\r
268 if (VerticalResolution != Private->ModeData[Index].VerticalResolution) {\r
269 continue;\r
270 }\r
271\r
272 if (ColorDepth != Private->ModeData[Index].ColorDepth) {\r
273 continue;\r
274 }\r
275\r
276 if (RefreshRate != Private->ModeData[Index].RefreshRate) {\r
277 continue;\r
278 }\r
279\r
280 if (Private->LineBuffer) {\r
281 gBS->FreePool (Private->LineBuffer);\r
282 }\r
283\r
284 Private->LineBuffer = NULL;\r
285 Private->LineBuffer = AllocatePool (HorizontalResolution);\r
286 if (Private->LineBuffer == NULL) {\r
287 return EFI_OUT_OF_RESOURCES;\r
288 }\r
289\r
290 InitializeGraphicsMode (Private, &CirrusLogic5430VideoModes[Index]);\r
291\r
292 Private->CurrentMode = Index;\r
293\r
294 Private->HardwareNeedsStarting = FALSE;\r
295\r
296 return EFI_SUCCESS;\r
297 }\r
298\r
299 return EFI_NOT_FOUND;\r
300}\r
301\r
302EFI_STATUS\r
303EFIAPI\r
304CirrusLogic5430UgaDrawBlt (\r
305 IN EFI_UGA_DRAW_PROTOCOL *This,\r
306 IN EFI_UGA_PIXEL *BltBuffer, OPTIONAL\r
307 IN EFI_UGA_BLT_OPERATION BltOperation,\r
308 IN UINTN SourceX,\r
309 IN UINTN SourceY,\r
310 IN UINTN DestinationX,\r
311 IN UINTN DestinationY,\r
312 IN UINTN Width,\r
313 IN UINTN Height,\r
314 IN UINTN Delta\r
315 )\r
316/*++\r
317\r
318Routine Description:\r
319\r
320 TODO: Add function description\r
321\r
322Arguments:\r
323\r
324 This - TODO: add argument description\r
325 BltBuffer - TODO: add argument description\r
326 BltOperation - TODO: add argument description\r
327 SourceX - TODO: add argument description\r
328 SourceY - TODO: add argument description\r
329 DestinationX - TODO: add argument description\r
330 DestinationY - TODO: add argument description\r
331 Width - TODO: add argument description\r
332 Height - TODO: add argument description\r
333 Delta - TODO: add argument description\r
334\r
335Returns:\r
336\r
337 EFI_INVALID_PARAMETER - TODO: Add description for return value\r
338 EFI_INVALID_PARAMETER - TODO: Add description for return value\r
339 EFI_INVALID_PARAMETER - TODO: Add description for return value\r
340 EFI_INVALID_PARAMETER - TODO: Add description for return value\r
341 EFI_INVALID_PARAMETER - TODO: Add description for return value\r
342 EFI_INVALID_PARAMETER - TODO: Add description for return value\r
343 EFI_SUCCESS - TODO: Add description for return value\r
344\r
345--*/\r
346{\r
347 CIRRUS_LOGIC_5430_PRIVATE_DATA *Private;\r
348 EFI_TPL OriginalTPL;\r
349 UINTN DstY;\r
350 UINTN SrcY;\r
351 EFI_UGA_PIXEL *Blt;\r
352 UINTN X;\r
353 UINT8 Pixel;\r
354 UINT32 WidePixel;\r
355 UINTN ScreenWidth;\r
356 UINTN Offset;\r
357 UINTN SourceOffset;\r
358\r
359 Private = CIRRUS_LOGIC_5430_PRIVATE_DATA_FROM_UGA_DRAW_THIS (This);\r
360\r
361 if ((BltOperation < 0) || (BltOperation >= EfiUgaBltMax)) {\r
362 return EFI_INVALID_PARAMETER;\r
363 }\r
364\r
365 if (Width == 0 || Height == 0) {\r
366 return EFI_INVALID_PARAMETER;\r
367 }\r
368\r
369 //\r
370 // If Delta is zero, then the entire BltBuffer is being used, so Delta\r
371 // is the number of bytes in each row of BltBuffer. Since BltBuffer is Width pixels size,\r
372 // the number of bytes in each row can be computed.\r
373 //\r
374 if (Delta == 0) {\r
375 Delta = Width * sizeof (EFI_UGA_PIXEL);\r
376 }\r
377\r
378 //\r
379 // We need to fill the Virtual Screen buffer with the blt data.\r
380 // The virtual screen is upside down, as the first row is the bootom row of\r
381 // the image.\r
382 //\r
383\r
384 //\r
385 // Make sure the SourceX, SourceY, DestinationX, DestinationY, Width, and Height parameters\r
386 // are valid for the operation and the current screen geometry.\r
387 //\r
388 if (BltOperation == EfiUgaVideoToBltBuffer) {\r
389 //\r
390 // Video to BltBuffer: Source is Video, destination is BltBuffer\r
391 //\r
392 if (SourceY + Height > Private->ModeData[Private->CurrentMode].VerticalResolution) {\r
393 return EFI_INVALID_PARAMETER;\r
394 }\r
395\r
396 if (SourceX + Width > Private->ModeData[Private->CurrentMode].HorizontalResolution) {\r
397 return EFI_INVALID_PARAMETER;\r
398 }\r
399 } else {\r
400 //\r
401 // BltBuffer to Video: Source is BltBuffer, destination is Video\r
402 //\r
403 if (DestinationY + Height > Private->ModeData[Private->CurrentMode].VerticalResolution) {\r
404 return EFI_INVALID_PARAMETER;\r
405 }\r
406\r
407 if (DestinationX + Width > Private->ModeData[Private->CurrentMode].HorizontalResolution) {\r
408 return EFI_INVALID_PARAMETER;\r
409 }\r
410 }\r
411 //\r
412 // We have to raise to TPL Notify, so we make an atomic write the frame buffer.\r
413 // We would not want a timer based event (Cursor, ...) to come in while we are\r
414 // doing this operation.\r
415 //\r
416 OriginalTPL = gBS->RaiseTPL (EFI_TPL_NOTIFY);\r
417\r
418 switch (BltOperation) {\r
419 case EfiUgaVideoToBltBuffer:\r
420 //\r
421 // Video to BltBuffer: Source is Video, destination is BltBuffer\r
422 //\r
423 for (SrcY = SourceY, DstY = DestinationY; DstY < (Height + DestinationY); SrcY++, DstY++) {\r
424\r
425 Offset = (SrcY * Private->ModeData[Private->CurrentMode].HorizontalResolution) + SourceX;\r
426 if (((Offset & 0x03) == 0) && ((Width & 0x03) == 0)) {\r
427 Private->PciIo->Mem.Read (\r
428 Private->PciIo,\r
429 EfiPciIoWidthUint32,\r
430 0,\r
431 Offset,\r
432 Width >> 2,\r
433 Private->LineBuffer\r
434 );\r
435 } else {\r
436 Private->PciIo->Mem.Read (\r
437 Private->PciIo,\r
438 EfiPciIoWidthUint8,\r
439 0,\r
440 Offset,\r
441 Width,\r
442 Private->LineBuffer\r
443 );\r
444 }\r
445\r
446 for (X = 0; X < Width; X++) {\r
447 Blt = (EFI_UGA_PIXEL *) ((UINT8 *) BltBuffer + (DstY * Delta) + (DestinationX + X) * sizeof (EFI_UGA_PIXEL));\r
448\r
449 Blt->Red = (UINT8) (Private->LineBuffer[X] & 0xe0);\r
450 Blt->Green = (UINT8) ((Private->LineBuffer[X] & 0x1c) << 3);\r
451 Blt->Blue = (UINT8) ((Private->LineBuffer[X] & 0x03) << 6);\r
452 }\r
453 }\r
454 break;\r
455\r
456 case EfiUgaVideoToVideo:\r
457 //\r
458 // Perform hardware acceleration for Video to Video operations\r
459 //\r
460 ScreenWidth = Private->ModeData[Private->CurrentMode].HorizontalResolution;\r
461 SourceOffset = (SourceY * Private->ModeData[Private->CurrentMode].HorizontalResolution) + (SourceX);\r
462 Offset = (DestinationY * Private->ModeData[Private->CurrentMode].HorizontalResolution) + (DestinationX);\r
463\r
464 outw (Private, GRAPH_ADDRESS_REGISTER, 0x0000);\r
465 outw (Private, GRAPH_ADDRESS_REGISTER, 0x0010);\r
466 outw (Private, GRAPH_ADDRESS_REGISTER, 0x0012);\r
467 outw (Private, GRAPH_ADDRESS_REGISTER, 0x0014);\r
468\r
469 outw (Private, GRAPH_ADDRESS_REGISTER, 0x0001);\r
470 outw (Private, GRAPH_ADDRESS_REGISTER, 0x0011);\r
471 outw (Private, GRAPH_ADDRESS_REGISTER, 0x0013);\r
472 outw (Private, GRAPH_ADDRESS_REGISTER, 0x0015);\r
473\r
474 outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) (((Width << 8) & 0xff00) | 0x20));\r
475 outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((Width & 0xff00) | 0x21));\r
476 outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) (((Height << 8) & 0xff00) | 0x22));\r
477 outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((Height & 0xff00) | 0x23));\r
478 outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) (((ScreenWidth << 8) & 0xff00) | 0x24));\r
479 outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((ScreenWidth & 0xff00) | 0x25));\r
480 outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) (((ScreenWidth << 8) & 0xff00) | 0x26));\r
481 outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((ScreenWidth & 0xff00) | 0x27));\r
482 outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((((Offset) << 8) & 0xff00) | 0x28));\r
483 outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((((Offset) >> 0) & 0xff00) | 0x29));\r
484 outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((((Offset) >> 8) & 0xff00) | 0x2a));\r
485 outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((((SourceOffset) << 8) & 0xff00) | 0x2c));\r
486 outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((((SourceOffset) >> 0) & 0xff00) | 0x2d));\r
487 outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((((SourceOffset) >> 8) & 0xff00) | 0x2e));\r
488 outw (Private, GRAPH_ADDRESS_REGISTER, 0x002f);\r
489 outw (Private, GRAPH_ADDRESS_REGISTER, 0x0030);\r
490 outw (Private, GRAPH_ADDRESS_REGISTER, 0x0d32);\r
491 outw (Private, GRAPH_ADDRESS_REGISTER, 0x0033);\r
492 outw (Private, GRAPH_ADDRESS_REGISTER, 0x0034);\r
493 outw (Private, GRAPH_ADDRESS_REGISTER, 0x0035);\r
494\r
495 outw (Private, GRAPH_ADDRESS_REGISTER, 0x0231);\r
496\r
497 outb (Private, GRAPH_ADDRESS_REGISTER, 0x31);\r
498 while ((inb (Private, GRAPH_DATA_REGISTER) & 0x01) == 0x01)\r
499 ;\r
500 break;\r
501\r
502 case EfiUgaVideoFill:\r
503 Blt = BltBuffer;\r
504 Pixel = (UINT8) ((Blt->Red & 0xe0) | ((Blt->Green >> 3) & 0x1c) | ((Blt->Blue >> 6) & 0x03));\r
505 WidePixel = (Pixel << 8) | Pixel;\r
506 WidePixel = (WidePixel << 16) | WidePixel;\r
507\r
508 if (DestinationX == 0 && Width == Private->ModeData[Private->CurrentMode].HorizontalResolution) {\r
509 Offset = DestinationY * Private->ModeData[Private->CurrentMode].HorizontalResolution;\r
510 if (((Offset & 0x03) == 0) && (((Width * Height) & 0x03) == 0)) {\r
511 Private->PciIo->Mem.Write (\r
512 Private->PciIo,\r
513 EfiPciIoWidthFillUint32,\r
514 0,\r
515 Offset,\r
516 (Width * Height) >> 2,\r
517 &WidePixel\r
518 );\r
519 } else {\r
520 Private->PciIo->Mem.Write (\r
521 Private->PciIo,\r
522 EfiPciIoWidthFillUint8,\r
523 0,\r
524 Offset,\r
525 Width * Height,\r
526 &Pixel\r
527 );\r
528 }\r
529 } else {\r
530 for (SrcY = SourceY, DstY = DestinationY; SrcY < (Height + SourceY); SrcY++, DstY++) {\r
531 Offset = (DstY * Private->ModeData[Private->CurrentMode].HorizontalResolution) + DestinationX;\r
532 if (((Offset & 0x03) == 0) && ((Width & 0x03) == 0)) {\r
533 Private->PciIo->Mem.Write (\r
534 Private->PciIo,\r
535 EfiPciIoWidthFillUint32,\r
536 0,\r
537 Offset,\r
538 Width >> 2,\r
539 &WidePixel\r
540 );\r
541 } else {\r
542 Private->PciIo->Mem.Write (\r
543 Private->PciIo,\r
544 EfiPciIoWidthFillUint8,\r
545 0,\r
546 Offset,\r
547 Width,\r
548 &Pixel\r
549 );\r
550 }\r
551 }\r
552 }\r
553 break;\r
554\r
555 case EfiUgaBltBufferToVideo:\r
556 for (SrcY = SourceY, DstY = DestinationY; SrcY < (Height + SourceY); SrcY++, DstY++) {\r
557\r
558 for (X = 0; X < Width; X++) {\r
559 Blt = (EFI_UGA_PIXEL *) ((UINT8 *) BltBuffer + (SrcY * Delta) + (SourceX + X) * sizeof (EFI_UGA_PIXEL));\r
560 Private->LineBuffer[X] = (UINT8) ((Blt->Red & 0xe0) | ((Blt->Green >> 3) & 0x1c) | ((Blt->Blue >> 6) & 0x03));\r
561 }\r
562\r
563 Offset = (DstY * Private->ModeData[Private->CurrentMode].HorizontalResolution) + DestinationX;\r
564\r
565 if (((Offset & 0x03) == 0) && ((Width & 0x03) == 0)) {\r
566 Private->PciIo->Mem.Write (\r
567 Private->PciIo,\r
568 EfiPciIoWidthUint32,\r
569 0,\r
570 Offset,\r
571 Width >> 2,\r
572 Private->LineBuffer\r
573 );\r
574 } else {\r
575 Private->PciIo->Mem.Write (\r
576 Private->PciIo,\r
577 EfiPciIoWidthUint8,\r
578 0,\r
579 Offset,\r
580 Width,\r
581 Private->LineBuffer\r
582 );\r
583 }\r
584 }\r
585 break;\r
586\r
587 default:\r
588 break;\r
589 }\r
590\r
591 gBS->RestoreTPL (OriginalTPL);\r
592\r
593 return EFI_SUCCESS;\r
594}\r
595\r
596//\r
597// Construction and Destruction functions\r
598//\r
599\r
600EFI_STATUS\r
601CirrusLogic5430UgaDrawConstructor (\r
602 CIRRUS_LOGIC_5430_PRIVATE_DATA *Private\r
603 )\r
604/*++\r
605\r
606Routine Description:\r
607\r
608Arguments:\r
609\r
610Returns:\r
611\r
612 None\r
613\r
614--*/\r
615// TODO: Private - add argument and description to function comment\r
616// TODO: EFI_SUCCESS - add return value to function comment\r
617{\r
618 EFI_UGA_DRAW_PROTOCOL *UgaDraw;\r
619 UINTN Index;\r
620\r
621 //\r
622 // Fill in Private->UgaDraw protocol\r
623 //\r
624 UgaDraw = &Private->UgaDraw;\r
625\r
626 UgaDraw->GetMode = CirrusLogic5430UgaDrawGetMode;\r
627 UgaDraw->SetMode = CirrusLogic5430UgaDrawSetMode;\r
628 UgaDraw->Blt = CirrusLogic5430UgaDrawBlt;\r
629\r
630 //\r
631 // Initialize the private data\r
632 //\r
633 Private->MaxMode = CIRRUS_LOGIC_5430_UGA_DRAW_MODE_COUNT;\r
634 Private->CurrentMode = 0;\r
635 for (Index = 0; Index < Private->MaxMode; Index++) {\r
636 Private->ModeData[Index].HorizontalResolution = CirrusLogic5430VideoModes[Index].Width;\r
637 Private->ModeData[Index].VerticalResolution = CirrusLogic5430VideoModes[Index].Height;\r
638 Private->ModeData[Index].ColorDepth = 32;\r
639 Private->ModeData[Index].RefreshRate = CirrusLogic5430VideoModes[Index].RefreshRate;\r
640 }\r
641\r
642 Private->HardwareNeedsStarting = TRUE;\r
643 Private->LineBuffer = NULL;\r
644\r
645 //\r
646 // Initialize the hardware\r
647 //\r
648 UgaDraw->SetMode (\r
649 UgaDraw,\r
650 Private->ModeData[Private->CurrentMode].HorizontalResolution,\r
651 Private->ModeData[Private->CurrentMode].VerticalResolution,\r
652 Private->ModeData[Private->CurrentMode].ColorDepth,\r
653 Private->ModeData[Private->CurrentMode].RefreshRate\r
654 );\r
655 DrawLogo (Private);\r
656\r
657 return EFI_SUCCESS;\r
658}\r
659\r
660EFI_STATUS\r
661CirrusLogic5430UgaDrawDestructor (\r
662 CIRRUS_LOGIC_5430_PRIVATE_DATA *Private\r
663 )\r
664/*++\r
665\r
666Routine Description:\r
667\r
668Arguments:\r
669\r
670Returns:\r
671\r
672 None\r
673\r
674--*/\r
675// TODO: Private - add argument and description to function comment\r
676// TODO: EFI_SUCCESS - add return value to function comment\r
677{\r
678 return EFI_SUCCESS;\r
679}\r
680\r
681VOID\r
682outb (\r
683 CIRRUS_LOGIC_5430_PRIVATE_DATA *Private,\r
684 UINTN Address,\r
685 UINT8 Data\r
686 )\r
687/*++\r
688\r
689Routine Description:\r
690\r
691 TODO: Add function description\r
692\r
693Arguments:\r
694\r
695 Private - TODO: add argument description\r
696 Address - TODO: add argument description\r
697 Data - TODO: add argument description\r
698\r
699Returns:\r
700\r
701 TODO: add return values\r
702\r
703--*/\r
704{\r
705 Private->PciIo->Io.Write (\r
706 Private->PciIo,\r
707 EfiPciIoWidthUint8,\r
708 EFI_PCI_IO_PASS_THROUGH_BAR,\r
709 Address,\r
710 1,\r
711 &Data\r
712 );\r
713}\r
714\r
715VOID\r
716outw (\r
717 CIRRUS_LOGIC_5430_PRIVATE_DATA *Private,\r
718 UINTN Address,\r
719 UINT16 Data\r
720 )\r
721/*++\r
722\r
723Routine Description:\r
724\r
725 TODO: Add function description\r
726\r
727Arguments:\r
728\r
729 Private - TODO: add argument description\r
730 Address - TODO: add argument description\r
731 Data - TODO: add argument description\r
732\r
733Returns:\r
734\r
735 TODO: add return values\r
736\r
737--*/\r
738{\r
739 Private->PciIo->Io.Write (\r
740 Private->PciIo,\r
741 EfiPciIoWidthUint16,\r
742 EFI_PCI_IO_PASS_THROUGH_BAR,\r
743 Address,\r
744 1,\r
745 &Data\r
746 );\r
747}\r
748\r
749UINT8\r
750inb (\r
751 CIRRUS_LOGIC_5430_PRIVATE_DATA *Private,\r
752 UINTN Address\r
753 )\r
754/*++\r
755\r
756Routine Description:\r
757\r
758 TODO: Add function description\r
759\r
760Arguments:\r
761\r
762 Private - TODO: add argument description\r
763 Address - TODO: add argument description\r
764\r
765Returns:\r
766\r
767 TODO: add return values\r
768\r
769--*/\r
770{\r
771 UINT8 Data;\r
772\r
773 Private->PciIo->Io.Read (\r
774 Private->PciIo,\r
775 EfiPciIoWidthUint8,\r
776 EFI_PCI_IO_PASS_THROUGH_BAR,\r
777 Address,\r
778 1,\r
779 &Data\r
780 );\r
781 return Data;\r
782}\r
783\r
784UINT16\r
785inw (\r
786 CIRRUS_LOGIC_5430_PRIVATE_DATA *Private,\r
787 UINTN Address\r
788 )\r
789/*++\r
790\r
791Routine Description:\r
792\r
793 TODO: Add function description\r
794\r
795Arguments:\r
796\r
797 Private - TODO: add argument description\r
798 Address - TODO: add argument description\r
799\r
800Returns:\r
801\r
802 TODO: add return values\r
803\r
804--*/\r
805{\r
806 UINT16 Data;\r
807\r
808 Private->PciIo->Io.Read (\r
809 Private->PciIo,\r
810 EfiPciIoWidthUint16,\r
811 EFI_PCI_IO_PASS_THROUGH_BAR,\r
812 Address,\r
813 1,\r
814 &Data\r
815 );\r
816 return Data;\r
817}\r
818\r
819VOID\r
820SetPaletteColor (\r
821 CIRRUS_LOGIC_5430_PRIVATE_DATA *Private,\r
822 UINTN Index,\r
823 UINT8 Red,\r
824 UINT8 Green,\r
825 UINT8 Blue\r
826 )\r
827/*++\r
828\r
829Routine Description:\r
830\r
831 TODO: Add function description\r
832\r
833Arguments:\r
834\r
835 Private - TODO: add argument description\r
836 Index - TODO: add argument description\r
837 Red - TODO: add argument description\r
838 Green - TODO: add argument description\r
839 Blue - TODO: add argument description\r
840\r
841Returns:\r
842\r
843 TODO: add return values\r
844\r
845--*/\r
846{\r
847 outb (Private, PALETTE_INDEX_REGISTER, (UINT8) Index);\r
848 outb (Private, PALETTE_DATA_REGISTER, (UINT8) (Red >> 2));\r
849 outb (Private, PALETTE_DATA_REGISTER, (UINT8) (Green >> 2));\r
850 outb (Private, PALETTE_DATA_REGISTER, (UINT8) (Blue >> 2));\r
851}\r
852\r
853VOID\r
854SetDefaultPalette (\r
855 CIRRUS_LOGIC_5430_PRIVATE_DATA *Private\r
856 )\r
857/*++\r
858\r
859Routine Description:\r
860\r
861 TODO: Add function description\r
862\r
863Arguments:\r
864\r
865 Private - TODO: add argument description\r
866\r
867Returns:\r
868\r
869 TODO: add return values\r
870\r
871--*/\r
872{\r
873 UINTN Index;\r
874 UINTN RedIndex;\r
875 UINTN GreenIndex;\r
876 UINTN BlueIndex;\r
877\r
878 Index = 0;\r
879 for (RedIndex = 0; RedIndex < 8; RedIndex++) {\r
880 for (GreenIndex = 0; GreenIndex < 8; GreenIndex++) {\r
881 for (BlueIndex = 0; BlueIndex < 4; BlueIndex++) {\r
882 SetPaletteColor (Private, Index, (UINT8) (RedIndex << 5), (UINT8) (GreenIndex << 5), (UINT8) (BlueIndex << 6));\r
883 Index++;\r
884 }\r
885 }\r
886 }\r
887}\r
888\r
889STATIC\r
890VOID\r
891ClearScreen (\r
892 CIRRUS_LOGIC_5430_PRIVATE_DATA *Private\r
893 )\r
894/*++\r
895\r
896Routine Description:\r
897\r
898 TODO: Add function description\r
899\r
900Arguments:\r
901\r
902 Private - TODO: add argument description\r
903\r
904Returns:\r
905\r
906 TODO: add return values\r
907\r
908--*/\r
909{\r
910 UINT32 Color;\r
911\r
912 Color = 0;\r
913 Private->PciIo->Mem.Write (\r
914 Private->PciIo,\r
915 EfiPciIoWidthFillUint32,\r
916 0,\r
917 0,\r
918 0x100000 >> 2,\r
919 &Color\r
920 );\r
921}\r
922\r
923VOID\r
924DrawLogo (\r
925 CIRRUS_LOGIC_5430_PRIVATE_DATA *Private\r
926 )\r
927/*++\r
928\r
929Routine Description:\r
930\r
931 TODO: Add function description\r
932\r
933Arguments:\r
934\r
935 Private - TODO: add argument description\r
936\r
937Returns:\r
938\r
939 TODO: add return values\r
940\r
941--*/\r
942{\r
943 UINTN Offset;\r
944 UINTN X;\r
945 UINTN Y;\r
946 UINTN ScreenWidth;\r
947 UINTN ScreenHeight;\r
948 UINT8 Color;\r
949\r
950 ScreenWidth = Private->ModeData[Private->CurrentMode].HorizontalResolution;\r
951 ScreenHeight = Private->ModeData[Private->CurrentMode].VerticalResolution;\r
952\r
953 Offset = 0;\r
954 for (Y = 0; Y < ScreenHeight; Y++) {\r
955 for (X = 0; X < ScreenWidth; X++) {\r
956 Color = (UINT8) (256 * (X + Y) / (ScreenWidth + ScreenHeight));\r
957 Private->LineBuffer[X] = Color;\r
958 }\r
959\r
960 Private->PciIo->Mem.Write (\r
961 Private->PciIo,\r
962 EfiPciIoWidthUint32,\r
963 0,\r
964 Offset + (Y * ScreenWidth),\r
965 ScreenWidth >> 2,\r
966 Private->LineBuffer\r
967 );\r
968 }\r
969}\r
970\r
971VOID\r
972InitializeGraphicsMode (\r
973 CIRRUS_LOGIC_5430_PRIVATE_DATA *Private,\r
974 CIRRUS_LOGIC_5430_VIDEO_MODES *ModeData\r
975 )\r
976/*++\r
977\r
978Routine Description:\r
979\r
980 TODO: Add function description\r
981\r
982Arguments:\r
983\r
984 Private - TODO: add argument description\r
985 ModeData - TODO: add argument description\r
986\r
987Returns:\r
988\r
989 TODO: add return values\r
990\r
991--*/\r
992{\r
993 UINT8 Byte;\r
994 UINTN Index;\r
995\r
996 outw (Private, SEQ_ADDRESS_REGISTER, 0x1206);\r
997 outw (Private, SEQ_ADDRESS_REGISTER, 0x0012);\r
998\r
999 for (Index = 0; Index < 15; Index++) {\r
1000 outw (Private, SEQ_ADDRESS_REGISTER, ModeData->SeqSettings[Index]);\r
1001 }\r
1002\r
1003 outb (Private, SEQ_ADDRESS_REGISTER, 0x0f);\r
1004 Byte = (UINT8) ((inb (Private, SEQ_DATA_REGISTER) & 0xc7) ^ 0x30);\r
1005 outb (Private, SEQ_DATA_REGISTER, Byte);\r
1006\r
1007 outb (Private, MISC_OUTPUT_REGISTER, ModeData->MiscSetting);\r
1008 outw (Private, GRAPH_ADDRESS_REGISTER, 0x0506);\r
1009 outw (Private, SEQ_ADDRESS_REGISTER, 0x0300);\r
1010 outw (Private, CRTC_ADDRESS_REGISTER, 0x2011);\r
1011\r
1012 for (Index = 0; Index < 28; Index++) {\r
1013 outw (Private, CRTC_ADDRESS_REGISTER, (UINT16) ((ModeData->CrtcSettings[Index] << 8) | Index));\r
1014 }\r
1015\r
1016 for (Index = 0; Index < 9; Index++) {\r
1017 outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((GraphicsController[Index] << 8) | Index));\r
1018 }\r
1019\r
1020 inb (Private, INPUT_STATUS_1_REGISTER);\r
1021\r
1022 for (Index = 0; Index < 21; Index++) {\r
1023 outb (Private, ATT_ADDRESS_REGISTER, (UINT8) Index);\r
1024 outb (Private, ATT_ADDRESS_REGISTER, AttributeController[Index]);\r
1025 }\r
1026\r
1027 outb (Private, ATT_ADDRESS_REGISTER, 0x20);\r
1028\r
1029 outw (Private, GRAPH_ADDRESS_REGISTER, 0x0009);\r
1030 outw (Private, GRAPH_ADDRESS_REGISTER, 0x000a);\r
1031 outw (Private, GRAPH_ADDRESS_REGISTER, 0x000b);\r
1032 outb (Private, DAC_PIXEL_MASK_REGISTER, 0xff);\r
1033\r
1034 SetDefaultPalette (Private);\r
1035 ClearScreen (Private);\r
1036}\r