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 SPDX-License-Identifier: BSD-2-Clause-Patent
11 #include "CirrusLogic5430.h"
14 // UGA Draw Protocol Member Functions
18 CirrusLogic5430UgaDrawGetMode (
19 IN EFI_UGA_DRAW_PROTOCOL
*This
,
20 OUT UINT32
*HorizontalResolution
,
21 OUT UINT32
*VerticalResolution
,
22 OUT UINT32
*ColorDepth
,
23 OUT UINT32
*RefreshRate
26 CIRRUS_LOGIC_5430_PRIVATE_DATA
*Private
;
28 Private
= CIRRUS_LOGIC_5430_PRIVATE_DATA_FROM_UGA_DRAW_THIS (This
);
30 if (Private
->HardwareNeedsStarting
) {
31 return EFI_NOT_STARTED
;
34 if ((HorizontalResolution
== NULL
) ||
35 (VerticalResolution
== NULL
) ||
36 (ColorDepth
== NULL
) ||
37 (RefreshRate
== NULL
)) {
38 return EFI_INVALID_PARAMETER
;
41 *HorizontalResolution
= Private
->ModeData
[Private
->CurrentMode
].HorizontalResolution
;
42 *VerticalResolution
= Private
->ModeData
[Private
->CurrentMode
].VerticalResolution
;
43 *ColorDepth
= Private
->ModeData
[Private
->CurrentMode
].ColorDepth
;
44 *RefreshRate
= Private
->ModeData
[Private
->CurrentMode
].RefreshRate
;
51 CirrusLogic5430UgaDrawSetMode (
52 IN EFI_UGA_DRAW_PROTOCOL
*This
,
53 IN UINT32 HorizontalResolution
,
54 IN UINT32 VerticalResolution
,
59 CIRRUS_LOGIC_5430_PRIVATE_DATA
*Private
;
62 Private
= CIRRUS_LOGIC_5430_PRIVATE_DATA_FROM_UGA_DRAW_THIS (This
);
64 for (Index
= 0; Index
< Private
->MaxMode
; Index
++) {
66 if (HorizontalResolution
!= Private
->ModeData
[Index
].HorizontalResolution
) {
70 if (VerticalResolution
!= Private
->ModeData
[Index
].VerticalResolution
) {
74 if (ColorDepth
!= Private
->ModeData
[Index
].ColorDepth
) {
78 if (RefreshRate
!= Private
->ModeData
[Index
].RefreshRate
) {
82 if (Private
->LineBuffer
) {
83 gBS
->FreePool (Private
->LineBuffer
);
86 Private
->LineBuffer
= NULL
;
87 Private
->LineBuffer
= AllocatePool (HorizontalResolution
);
88 if (Private
->LineBuffer
== NULL
) {
89 return EFI_OUT_OF_RESOURCES
;
92 InitializeGraphicsMode (Private
, &CirrusLogic5430VideoModes
[Private
->ModeData
[Index
].ModeNumber
]);
94 Private
->CurrentMode
= Index
;
96 Private
->HardwareNeedsStarting
= FALSE
;
101 return EFI_NOT_FOUND
;
106 CirrusLogic5430UgaDrawBlt (
107 IN EFI_UGA_DRAW_PROTOCOL
*This
,
108 IN EFI_UGA_PIXEL
*BltBuffer
, OPTIONAL
109 IN EFI_UGA_BLT_OPERATION BltOperation
,
112 IN UINTN DestinationX
,
113 IN UINTN DestinationY
,
119 CIRRUS_LOGIC_5430_PRIVATE_DATA
*Private
;
131 Private
= CIRRUS_LOGIC_5430_PRIVATE_DATA_FROM_UGA_DRAW_THIS (This
);
133 if ((UINT32
)BltOperation
>= EfiUgaBltMax
) {
134 return EFI_INVALID_PARAMETER
;
137 if (Width
== 0 || Height
== 0) {
138 return EFI_INVALID_PARAMETER
;
142 // If Delta is zero, then the entire BltBuffer is being used, so Delta
143 // is the number of bytes in each row of BltBuffer. Since BltBuffer is Width pixels size,
144 // the number of bytes in each row can be computed.
147 Delta
= Width
* sizeof (EFI_UGA_PIXEL
);
151 // We need to fill the Virtual Screen buffer with the blt data.
152 // The virtual screen is upside down, as the first row is the bootom row of
157 // Make sure the SourceX, SourceY, DestinationX, DestinationY, Width, and Height parameters
158 // are valid for the operation and the current screen geometry.
160 if (BltOperation
== EfiUgaVideoToBltBuffer
) {
162 // Video to BltBuffer: Source is Video, destination is BltBuffer
164 if (SourceY
+ Height
> Private
->ModeData
[Private
->CurrentMode
].VerticalResolution
) {
165 return EFI_INVALID_PARAMETER
;
168 if (SourceX
+ Width
> Private
->ModeData
[Private
->CurrentMode
].HorizontalResolution
) {
169 return EFI_INVALID_PARAMETER
;
173 // BltBuffer to Video: Source is BltBuffer, destination is Video
175 if (DestinationY
+ Height
> Private
->ModeData
[Private
->CurrentMode
].VerticalResolution
) {
176 return EFI_INVALID_PARAMETER
;
179 if (DestinationX
+ Width
> Private
->ModeData
[Private
->CurrentMode
].HorizontalResolution
) {
180 return EFI_INVALID_PARAMETER
;
184 // We have to raise to TPL Notify, so we make an atomic write the frame buffer.
185 // We would not want a timer based event (Cursor, ...) to come in while we are
186 // doing this operation.
188 OriginalTPL
= gBS
->RaiseTPL (TPL_NOTIFY
);
190 switch (BltOperation
) {
191 case EfiUgaVideoToBltBuffer
:
193 // Video to BltBuffer: Source is Video, destination is BltBuffer
195 for (SrcY
= SourceY
, DstY
= DestinationY
; DstY
< (Height
+ DestinationY
); SrcY
++, DstY
++) {
197 Offset
= (SrcY
* Private
->ModeData
[Private
->CurrentMode
].HorizontalResolution
) + SourceX
;
198 if (((Offset
& 0x03) == 0) && ((Width
& 0x03) == 0)) {
199 Private
->PciIo
->Mem
.Read (
208 Private
->PciIo
->Mem
.Read (
218 for (X
= 0; X
< Width
; X
++) {
219 Blt
= (EFI_UGA_PIXEL
*) ((UINT8
*) BltBuffer
+ (DstY
* Delta
) + (DestinationX
+ X
) * sizeof (EFI_UGA_PIXEL
));
221 Blt
->Red
= (UINT8
) (Private
->LineBuffer
[X
] & 0xe0);
222 Blt
->Green
= (UINT8
) ((Private
->LineBuffer
[X
] & 0x1c) << 3);
223 Blt
->Blue
= (UINT8
) ((Private
->LineBuffer
[X
] & 0x03) << 6);
228 case EfiUgaVideoToVideo
:
230 // Perform hardware acceleration for Video to Video operations
232 ScreenWidth
= Private
->ModeData
[Private
->CurrentMode
].HorizontalResolution
;
233 SourceOffset
= (SourceY
* Private
->ModeData
[Private
->CurrentMode
].HorizontalResolution
) + (SourceX
);
234 Offset
= (DestinationY
* Private
->ModeData
[Private
->CurrentMode
].HorizontalResolution
) + (DestinationX
);
236 outw (Private
, GRAPH_ADDRESS_REGISTER
, 0x0000);
237 outw (Private
, GRAPH_ADDRESS_REGISTER
, 0x0010);
238 outw (Private
, GRAPH_ADDRESS_REGISTER
, 0x0012);
239 outw (Private
, GRAPH_ADDRESS_REGISTER
, 0x0014);
241 outw (Private
, GRAPH_ADDRESS_REGISTER
, 0x0001);
242 outw (Private
, GRAPH_ADDRESS_REGISTER
, 0x0011);
243 outw (Private
, GRAPH_ADDRESS_REGISTER
, 0x0013);
244 outw (Private
, GRAPH_ADDRESS_REGISTER
, 0x0015);
246 outw (Private
, GRAPH_ADDRESS_REGISTER
, (UINT16
) (((Width
<< 8) & 0xff00) | 0x20));
247 outw (Private
, GRAPH_ADDRESS_REGISTER
, (UINT16
) ((Width
& 0xff00) | 0x21));
248 outw (Private
, GRAPH_ADDRESS_REGISTER
, (UINT16
) (((Height
<< 8) & 0xff00) | 0x22));
249 outw (Private
, GRAPH_ADDRESS_REGISTER
, (UINT16
) ((Height
& 0xff00) | 0x23));
250 outw (Private
, GRAPH_ADDRESS_REGISTER
, (UINT16
) (((ScreenWidth
<< 8) & 0xff00) | 0x24));
251 outw (Private
, GRAPH_ADDRESS_REGISTER
, (UINT16
) ((ScreenWidth
& 0xff00) | 0x25));
252 outw (Private
, GRAPH_ADDRESS_REGISTER
, (UINT16
) (((ScreenWidth
<< 8) & 0xff00) | 0x26));
253 outw (Private
, GRAPH_ADDRESS_REGISTER
, (UINT16
) ((ScreenWidth
& 0xff00) | 0x27));
254 outw (Private
, GRAPH_ADDRESS_REGISTER
, (UINT16
) ((((Offset
) << 8) & 0xff00) | 0x28));
255 outw (Private
, GRAPH_ADDRESS_REGISTER
, (UINT16
) ((((Offset
) >> 0) & 0xff00) | 0x29));
256 outw (Private
, GRAPH_ADDRESS_REGISTER
, (UINT16
) ((((Offset
) >> 8) & 0xff00) | 0x2a));
257 outw (Private
, GRAPH_ADDRESS_REGISTER
, (UINT16
) ((((SourceOffset
) << 8) & 0xff00) | 0x2c));
258 outw (Private
, GRAPH_ADDRESS_REGISTER
, (UINT16
) ((((SourceOffset
) >> 0) & 0xff00) | 0x2d));
259 outw (Private
, GRAPH_ADDRESS_REGISTER
, (UINT16
) ((((SourceOffset
) >> 8) & 0xff00) | 0x2e));
260 outw (Private
, GRAPH_ADDRESS_REGISTER
, 0x002f);
261 outw (Private
, GRAPH_ADDRESS_REGISTER
, 0x0030);
262 outw (Private
, GRAPH_ADDRESS_REGISTER
, 0x0d32);
263 outw (Private
, GRAPH_ADDRESS_REGISTER
, 0x0033);
264 outw (Private
, GRAPH_ADDRESS_REGISTER
, 0x0034);
265 outw (Private
, GRAPH_ADDRESS_REGISTER
, 0x0035);
267 outw (Private
, GRAPH_ADDRESS_REGISTER
, 0x0231);
269 outb (Private
, GRAPH_ADDRESS_REGISTER
, 0x31);
270 while ((inb (Private
, GRAPH_DATA_REGISTER
) & 0x01) == 0x01)
274 case EfiUgaVideoFill
:
276 Pixel
= (UINT8
) ((Blt
->Red
& 0xe0) | ((Blt
->Green
>> 3) & 0x1c) | ((Blt
->Blue
>> 6) & 0x03));
277 WidePixel
= (Pixel
<< 8) | Pixel
;
278 WidePixel
= (WidePixel
<< 16) | WidePixel
;
280 if (DestinationX
== 0 && Width
== Private
->ModeData
[Private
->CurrentMode
].HorizontalResolution
) {
281 Offset
= DestinationY
* Private
->ModeData
[Private
->CurrentMode
].HorizontalResolution
;
282 if (((Offset
& 0x03) == 0) && (((Width
* Height
) & 0x03) == 0)) {
283 Private
->PciIo
->Mem
.Write (
285 EfiPciIoWidthFillUint32
,
288 (Width
* Height
) >> 2,
292 Private
->PciIo
->Mem
.Write (
294 EfiPciIoWidthFillUint8
,
302 for (SrcY
= SourceY
, DstY
= DestinationY
; SrcY
< (Height
+ SourceY
); SrcY
++, DstY
++) {
303 Offset
= (DstY
* Private
->ModeData
[Private
->CurrentMode
].HorizontalResolution
) + DestinationX
;
304 if (((Offset
& 0x03) == 0) && ((Width
& 0x03) == 0)) {
305 Private
->PciIo
->Mem
.Write (
307 EfiPciIoWidthFillUint32
,
314 Private
->PciIo
->Mem
.Write (
316 EfiPciIoWidthFillUint8
,
327 case EfiUgaBltBufferToVideo
:
328 for (SrcY
= SourceY
, DstY
= DestinationY
; SrcY
< (Height
+ SourceY
); SrcY
++, DstY
++) {
330 for (X
= 0; X
< Width
; X
++) {
331 Blt
= (EFI_UGA_PIXEL
*) ((UINT8
*) BltBuffer
+ (SrcY
* Delta
) + (SourceX
+ X
) * sizeof (EFI_UGA_PIXEL
));
332 Private
->LineBuffer
[X
] = (UINT8
) ((Blt
->Red
& 0xe0) | ((Blt
->Green
>> 3) & 0x1c) | ((Blt
->Blue
>> 6) & 0x03));
335 Offset
= (DstY
* Private
->ModeData
[Private
->CurrentMode
].HorizontalResolution
) + DestinationX
;
337 if (((Offset
& 0x03) == 0) && ((Width
& 0x03) == 0)) {
338 Private
->PciIo
->Mem
.Write (
347 Private
->PciIo
->Mem
.Write (
363 gBS
->RestoreTPL (OriginalTPL
);
369 // Construction and Destruction functions
372 CirrusLogic5430UgaDrawConstructor (
373 CIRRUS_LOGIC_5430_PRIVATE_DATA
*Private
376 EFI_UGA_DRAW_PROTOCOL
*UgaDraw
;
379 // Fill in Private->UgaDraw protocol
381 UgaDraw
= &Private
->UgaDraw
;
383 UgaDraw
->GetMode
= CirrusLogic5430UgaDrawGetMode
;
384 UgaDraw
->SetMode
= CirrusLogic5430UgaDrawSetMode
;
385 UgaDraw
->Blt
= CirrusLogic5430UgaDrawBlt
;
388 // Initialize the private data
390 Private
->CurrentMode
= 0;
391 Private
->HardwareNeedsStarting
= TRUE
;
392 Private
->LineBuffer
= NULL
;
395 // Initialize the hardware
399 Private
->ModeData
[Private
->CurrentMode
].HorizontalResolution
,
400 Private
->ModeData
[Private
->CurrentMode
].VerticalResolution
,
401 Private
->ModeData
[Private
->CurrentMode
].ColorDepth
,
402 Private
->ModeData
[Private
->CurrentMode
].RefreshRate
406 Private
->ModeData
[Private
->CurrentMode
].HorizontalResolution
,
407 Private
->ModeData
[Private
->CurrentMode
].VerticalResolution