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.
6 Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>
7 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
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.
17 #include "CirrusLogic5430.h"
20 // UGA Draw Protocol Member Functions
24 CirrusLogic5430UgaDrawGetMode (
25 IN EFI_UGA_DRAW_PROTOCOL
*This
,
26 OUT UINT32
*HorizontalResolution
,
27 OUT UINT32
*VerticalResolution
,
28 OUT UINT32
*ColorDepth
,
29 OUT UINT32
*RefreshRate
32 CIRRUS_LOGIC_5430_PRIVATE_DATA
*Private
;
34 Private
= CIRRUS_LOGIC_5430_PRIVATE_DATA_FROM_UGA_DRAW_THIS (This
);
36 if (Private
->HardwareNeedsStarting
) {
37 return EFI_NOT_STARTED
;
40 if ((HorizontalResolution
== NULL
) ||
41 (VerticalResolution
== NULL
) ||
42 (ColorDepth
== NULL
) ||
43 (RefreshRate
== NULL
)) {
44 return EFI_INVALID_PARAMETER
;
47 *HorizontalResolution
= Private
->ModeData
[Private
->CurrentMode
].HorizontalResolution
;
48 *VerticalResolution
= Private
->ModeData
[Private
->CurrentMode
].VerticalResolution
;
49 *ColorDepth
= Private
->ModeData
[Private
->CurrentMode
].ColorDepth
;
50 *RefreshRate
= Private
->ModeData
[Private
->CurrentMode
].RefreshRate
;
57 CirrusLogic5430UgaDrawSetMode (
58 IN EFI_UGA_DRAW_PROTOCOL
*This
,
59 IN UINT32 HorizontalResolution
,
60 IN UINT32 VerticalResolution
,
65 CIRRUS_LOGIC_5430_PRIVATE_DATA
*Private
;
68 Private
= CIRRUS_LOGIC_5430_PRIVATE_DATA_FROM_UGA_DRAW_THIS (This
);
70 for (Index
= 0; Index
< Private
->MaxMode
; Index
++) {
72 if (HorizontalResolution
!= Private
->ModeData
[Index
].HorizontalResolution
) {
76 if (VerticalResolution
!= Private
->ModeData
[Index
].VerticalResolution
) {
80 if (ColorDepth
!= Private
->ModeData
[Index
].ColorDepth
) {
84 if (RefreshRate
!= Private
->ModeData
[Index
].RefreshRate
) {
88 if (Private
->LineBuffer
) {
89 gBS
->FreePool (Private
->LineBuffer
);
92 Private
->LineBuffer
= NULL
;
93 Private
->LineBuffer
= AllocatePool (HorizontalResolution
);
94 if (Private
->LineBuffer
== NULL
) {
95 return EFI_OUT_OF_RESOURCES
;
98 InitializeGraphicsMode (Private
, &CirrusLogic5430VideoModes
[Private
->ModeData
[Index
].ModeNumber
]);
100 Private
->CurrentMode
= Index
;
102 Private
->HardwareNeedsStarting
= FALSE
;
107 return EFI_NOT_FOUND
;
112 CirrusLogic5430UgaDrawBlt (
113 IN EFI_UGA_DRAW_PROTOCOL
*This
,
114 IN EFI_UGA_PIXEL
*BltBuffer
, OPTIONAL
115 IN EFI_UGA_BLT_OPERATION BltOperation
,
118 IN UINTN DestinationX
,
119 IN UINTN DestinationY
,
125 CIRRUS_LOGIC_5430_PRIVATE_DATA
*Private
;
137 Private
= CIRRUS_LOGIC_5430_PRIVATE_DATA_FROM_UGA_DRAW_THIS (This
);
139 if ((UINT32
)BltOperation
>= EfiUgaBltMax
) {
140 return EFI_INVALID_PARAMETER
;
143 if (Width
== 0 || Height
== 0) {
144 return EFI_INVALID_PARAMETER
;
148 // If Delta is zero, then the entire BltBuffer is being used, so Delta
149 // is the number of bytes in each row of BltBuffer. Since BltBuffer is Width pixels size,
150 // the number of bytes in each row can be computed.
153 Delta
= Width
* sizeof (EFI_UGA_PIXEL
);
157 // We need to fill the Virtual Screen buffer with the blt data.
158 // The virtual screen is upside down, as the first row is the bootom row of
163 // Make sure the SourceX, SourceY, DestinationX, DestinationY, Width, and Height parameters
164 // are valid for the operation and the current screen geometry.
166 if (BltOperation
== EfiUgaVideoToBltBuffer
) {
168 // Video to BltBuffer: Source is Video, destination is BltBuffer
170 if (SourceY
+ Height
> Private
->ModeData
[Private
->CurrentMode
].VerticalResolution
) {
171 return EFI_INVALID_PARAMETER
;
174 if (SourceX
+ Width
> Private
->ModeData
[Private
->CurrentMode
].HorizontalResolution
) {
175 return EFI_INVALID_PARAMETER
;
179 // BltBuffer to Video: Source is BltBuffer, destination is Video
181 if (DestinationY
+ Height
> Private
->ModeData
[Private
->CurrentMode
].VerticalResolution
) {
182 return EFI_INVALID_PARAMETER
;
185 if (DestinationX
+ Width
> Private
->ModeData
[Private
->CurrentMode
].HorizontalResolution
) {
186 return EFI_INVALID_PARAMETER
;
190 // We have to raise to TPL Notify, so we make an atomic write the frame buffer.
191 // We would not want a timer based event (Cursor, ...) to come in while we are
192 // doing this operation.
194 OriginalTPL
= gBS
->RaiseTPL (TPL_NOTIFY
);
196 switch (BltOperation
) {
197 case EfiUgaVideoToBltBuffer
:
199 // Video to BltBuffer: Source is Video, destination is BltBuffer
201 for (SrcY
= SourceY
, DstY
= DestinationY
; DstY
< (Height
+ DestinationY
); SrcY
++, DstY
++) {
203 Offset
= (SrcY
* Private
->ModeData
[Private
->CurrentMode
].HorizontalResolution
) + SourceX
;
204 if (((Offset
& 0x03) == 0) && ((Width
& 0x03) == 0)) {
205 Private
->PciIo
->Mem
.Read (
214 Private
->PciIo
->Mem
.Read (
224 for (X
= 0; X
< Width
; X
++) {
225 Blt
= (EFI_UGA_PIXEL
*) ((UINT8
*) BltBuffer
+ (DstY
* Delta
) + (DestinationX
+ X
) * sizeof (EFI_UGA_PIXEL
));
227 Blt
->Red
= (UINT8
) (Private
->LineBuffer
[X
] & 0xe0);
228 Blt
->Green
= (UINT8
) ((Private
->LineBuffer
[X
] & 0x1c) << 3);
229 Blt
->Blue
= (UINT8
) ((Private
->LineBuffer
[X
] & 0x03) << 6);
234 case EfiUgaVideoToVideo
:
236 // Perform hardware acceleration for Video to Video operations
238 ScreenWidth
= Private
->ModeData
[Private
->CurrentMode
].HorizontalResolution
;
239 SourceOffset
= (SourceY
* Private
->ModeData
[Private
->CurrentMode
].HorizontalResolution
) + (SourceX
);
240 Offset
= (DestinationY
* Private
->ModeData
[Private
->CurrentMode
].HorizontalResolution
) + (DestinationX
);
242 outw (Private
, GRAPH_ADDRESS_REGISTER
, 0x0000);
243 outw (Private
, GRAPH_ADDRESS_REGISTER
, 0x0010);
244 outw (Private
, GRAPH_ADDRESS_REGISTER
, 0x0012);
245 outw (Private
, GRAPH_ADDRESS_REGISTER
, 0x0014);
247 outw (Private
, GRAPH_ADDRESS_REGISTER
, 0x0001);
248 outw (Private
, GRAPH_ADDRESS_REGISTER
, 0x0011);
249 outw (Private
, GRAPH_ADDRESS_REGISTER
, 0x0013);
250 outw (Private
, GRAPH_ADDRESS_REGISTER
, 0x0015);
252 outw (Private
, GRAPH_ADDRESS_REGISTER
, (UINT16
) (((Width
<< 8) & 0xff00) | 0x20));
253 outw (Private
, GRAPH_ADDRESS_REGISTER
, (UINT16
) ((Width
& 0xff00) | 0x21));
254 outw (Private
, GRAPH_ADDRESS_REGISTER
, (UINT16
) (((Height
<< 8) & 0xff00) | 0x22));
255 outw (Private
, GRAPH_ADDRESS_REGISTER
, (UINT16
) ((Height
& 0xff00) | 0x23));
256 outw (Private
, GRAPH_ADDRESS_REGISTER
, (UINT16
) (((ScreenWidth
<< 8) & 0xff00) | 0x24));
257 outw (Private
, GRAPH_ADDRESS_REGISTER
, (UINT16
) ((ScreenWidth
& 0xff00) | 0x25));
258 outw (Private
, GRAPH_ADDRESS_REGISTER
, (UINT16
) (((ScreenWidth
<< 8) & 0xff00) | 0x26));
259 outw (Private
, GRAPH_ADDRESS_REGISTER
, (UINT16
) ((ScreenWidth
& 0xff00) | 0x27));
260 outw (Private
, GRAPH_ADDRESS_REGISTER
, (UINT16
) ((((Offset
) << 8) & 0xff00) | 0x28));
261 outw (Private
, GRAPH_ADDRESS_REGISTER
, (UINT16
) ((((Offset
) >> 0) & 0xff00) | 0x29));
262 outw (Private
, GRAPH_ADDRESS_REGISTER
, (UINT16
) ((((Offset
) >> 8) & 0xff00) | 0x2a));
263 outw (Private
, GRAPH_ADDRESS_REGISTER
, (UINT16
) ((((SourceOffset
) << 8) & 0xff00) | 0x2c));
264 outw (Private
, GRAPH_ADDRESS_REGISTER
, (UINT16
) ((((SourceOffset
) >> 0) & 0xff00) | 0x2d));
265 outw (Private
, GRAPH_ADDRESS_REGISTER
, (UINT16
) ((((SourceOffset
) >> 8) & 0xff00) | 0x2e));
266 outw (Private
, GRAPH_ADDRESS_REGISTER
, 0x002f);
267 outw (Private
, GRAPH_ADDRESS_REGISTER
, 0x0030);
268 outw (Private
, GRAPH_ADDRESS_REGISTER
, 0x0d32);
269 outw (Private
, GRAPH_ADDRESS_REGISTER
, 0x0033);
270 outw (Private
, GRAPH_ADDRESS_REGISTER
, 0x0034);
271 outw (Private
, GRAPH_ADDRESS_REGISTER
, 0x0035);
273 outw (Private
, GRAPH_ADDRESS_REGISTER
, 0x0231);
275 outb (Private
, GRAPH_ADDRESS_REGISTER
, 0x31);
276 while ((inb (Private
, GRAPH_DATA_REGISTER
) & 0x01) == 0x01)
280 case EfiUgaVideoFill
:
282 Pixel
= (UINT8
) ((Blt
->Red
& 0xe0) | ((Blt
->Green
>> 3) & 0x1c) | ((Blt
->Blue
>> 6) & 0x03));
283 WidePixel
= (Pixel
<< 8) | Pixel
;
284 WidePixel
= (WidePixel
<< 16) | WidePixel
;
286 if (DestinationX
== 0 && Width
== Private
->ModeData
[Private
->CurrentMode
].HorizontalResolution
) {
287 Offset
= DestinationY
* Private
->ModeData
[Private
->CurrentMode
].HorizontalResolution
;
288 if (((Offset
& 0x03) == 0) && (((Width
* Height
) & 0x03) == 0)) {
289 Private
->PciIo
->Mem
.Write (
291 EfiPciIoWidthFillUint32
,
294 (Width
* Height
) >> 2,
298 Private
->PciIo
->Mem
.Write (
300 EfiPciIoWidthFillUint8
,
308 for (SrcY
= SourceY
, DstY
= DestinationY
; SrcY
< (Height
+ SourceY
); SrcY
++, DstY
++) {
309 Offset
= (DstY
* Private
->ModeData
[Private
->CurrentMode
].HorizontalResolution
) + DestinationX
;
310 if (((Offset
& 0x03) == 0) && ((Width
& 0x03) == 0)) {
311 Private
->PciIo
->Mem
.Write (
313 EfiPciIoWidthFillUint32
,
320 Private
->PciIo
->Mem
.Write (
322 EfiPciIoWidthFillUint8
,
333 case EfiUgaBltBufferToVideo
:
334 for (SrcY
= SourceY
, DstY
= DestinationY
; SrcY
< (Height
+ SourceY
); SrcY
++, DstY
++) {
336 for (X
= 0; X
< Width
; X
++) {
337 Blt
= (EFI_UGA_PIXEL
*) ((UINT8
*) BltBuffer
+ (SrcY
* Delta
) + (SourceX
+ X
) * sizeof (EFI_UGA_PIXEL
));
338 Private
->LineBuffer
[X
] = (UINT8
) ((Blt
->Red
& 0xe0) | ((Blt
->Green
>> 3) & 0x1c) | ((Blt
->Blue
>> 6) & 0x03));
341 Offset
= (DstY
* Private
->ModeData
[Private
->CurrentMode
].HorizontalResolution
) + DestinationX
;
343 if (((Offset
& 0x03) == 0) && ((Width
& 0x03) == 0)) {
344 Private
->PciIo
->Mem
.Write (
353 Private
->PciIo
->Mem
.Write (
369 gBS
->RestoreTPL (OriginalTPL
);
375 // Construction and Destruction functions
378 CirrusLogic5430UgaDrawConstructor (
379 CIRRUS_LOGIC_5430_PRIVATE_DATA
*Private
382 EFI_UGA_DRAW_PROTOCOL
*UgaDraw
;
385 // Fill in Private->UgaDraw protocol
387 UgaDraw
= &Private
->UgaDraw
;
389 UgaDraw
->GetMode
= CirrusLogic5430UgaDrawGetMode
;
390 UgaDraw
->SetMode
= CirrusLogic5430UgaDrawSetMode
;
391 UgaDraw
->Blt
= CirrusLogic5430UgaDrawBlt
;
394 // Initialize the private data
396 Private
->CurrentMode
= 0;
397 Private
->HardwareNeedsStarting
= TRUE
;
398 Private
->LineBuffer
= NULL
;
401 // Initialize the hardware
405 Private
->ModeData
[Private
->CurrentMode
].HorizontalResolution
,
406 Private
->ModeData
[Private
->CurrentMode
].VerticalResolution
,
407 Private
->ModeData
[Private
->CurrentMode
].ColorDepth
,
408 Private
->ModeData
[Private
->CurrentMode
].RefreshRate
412 Private
->ModeData
[Private
->CurrentMode
].HorizontalResolution
,
413 Private
->ModeData
[Private
->CurrentMode
].VerticalResolution