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