3 Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
4 Portions copyright (c) 2010, Apple, Inc. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
19 This file produces the graphics abstration of UGA. It is called by
20 UnixGopDriver.c file which deals with the EFI 1.1 driver model.
21 This file just does graphics.
27 EFI_UNIX_THUNK_PROTOCOL
*mUnix
;
28 EFI_EVENT mGopScreenExitBootServicesEvent
;
30 GOP_MODE_DATA mGopModeData
[] = {
41 IN GOP_PRIVATE_DATA
*Private
,
42 IN UINT32 HorizontalResolution
,
43 IN UINT32 VerticalResolution
,
56 // UGA Protocol Member Functions
62 IN EFI_GRAPHICS_OUTPUT_PROTOCOL
*This
,
64 OUT UINTN
*SizeOfInfo
,
65 OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
**Info
68 GOP_PRIVATE_DATA
*Private
;
70 Private
= GOP_PRIVATE_DATA_FROM_THIS (This
);
72 if (Info
== NULL
|| SizeOfInfo
== NULL
|| (UINTN
) ModeNumber
>= This
->Mode
->MaxMode
) {
73 return EFI_INVALID_PARAMETER
;
76 *Info
= AllocatePool (sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
));
78 return EFI_OUT_OF_RESOURCES
;
81 *SizeOfInfo
= sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
);
84 (*Info
)->HorizontalResolution
= Private
->ModeData
[ModeNumber
].HorizontalResolution
;
85 (*Info
)->VerticalResolution
= Private
->ModeData
[ModeNumber
].VerticalResolution
;
86 (*Info
)->PixelFormat
= PixelBltOnly
;
87 (*Info
)->PixelsPerScanLine
= (*Info
)->HorizontalResolution
;
97 IN EFI_GRAPHICS_OUTPUT_PROTOCOL
*This
,
102 GOP_PRIVATE_DATA
*Private
;
103 GOP_MODE_DATA
*ModeData
;
104 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Fill
;
106 Private
= GOP_PRIVATE_DATA_FROM_THIS (This
);
108 if (ModeNumber
>= This
->Mode
->MaxMode
) {
109 return EFI_UNSUPPORTED
;
112 ModeData
= &Private
->ModeData
[ModeNumber
];
113 This
->Mode
->Mode
= ModeNumber
;
114 Private
->GraphicsOutput
.Mode
->Info
->HorizontalResolution
= ModeData
->HorizontalResolution
;
115 Private
->GraphicsOutput
.Mode
->Info
->VerticalResolution
= ModeData
->VerticalResolution
;
116 Private
->GraphicsOutput
.Mode
->Info
->PixelsPerScanLine
= ModeData
->HorizontalResolution
;
118 if (Private
->HardwareNeedsStarting
) {
119 Status
= UnixGopStartWindow (
121 ModeData
->HorizontalResolution
,
122 ModeData
->VerticalResolution
,
123 ModeData
->ColorDepth
,
124 ModeData
->RefreshRate
126 if (EFI_ERROR (Status
)) {
127 return EFI_DEVICE_ERROR
;
130 Private
->HardwareNeedsStarting
= FALSE
;
134 Status
= Private
->UgaIo
->UgaSize(
136 ModeData
->HorizontalResolution
,
137 ModeData
->VerticalResolution
152 ModeData
->HorizontalResolution
,
153 ModeData
->VerticalResolution
,
154 ModeData
->HorizontalResolution
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
)
164 IN EFI_GRAPHICS_OUTPUT_PROTOCOL
*This
,
165 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*BltBuffer
, OPTIONAL
166 IN EFI_GRAPHICS_OUTPUT_BLT_OPERATION BltOperation
,
169 IN UINTN DestinationX
,
170 IN UINTN DestinationY
,
173 IN UINTN Delta OPTIONAL
176 GOP_PRIVATE_DATA
*Private
;
179 UGA_BLT_ARGS GopBltArgs
;
181 Private
= GOP_PRIVATE_DATA_FROM_THIS (This
);
183 if ((BltOperation
< 0) || (BltOperation
>= EfiGraphicsOutputBltOperationMax
)) {
184 return EFI_INVALID_PARAMETER
;
187 if (Width
== 0 || Height
== 0) {
188 return EFI_INVALID_PARAMETER
;
191 // If Delta is zero, then the entire BltBuffer is being used, so Delta
192 // is the number of bytes in each row of BltBuffer. Since BltBuffer is Width pixels size,
193 // the number of bytes in each row can be computed.
196 Delta
= Width
* sizeof (EFI_UGA_PIXEL
);
200 // We have to raise to TPL Notify, so we make an atomic write the frame buffer.
201 // We would not want a timer based event (Cursor, ...) to come in while we are
202 // doing this operation.
204 OriginalTPL
= gBS
->RaiseTPL (TPL_NOTIFY
);
207 // Pack UGA Draw protocol parameters to UGA_BLT_ARGS structure to adapt to
208 // GopBlt() API of Unix UGA IO protocol.
210 GopBltArgs
.DestinationX
= DestinationX
;
211 GopBltArgs
.DestinationY
= DestinationY
;
212 GopBltArgs
.Height
= Height
;
213 GopBltArgs
.Width
= Width
;
214 GopBltArgs
.SourceX
= SourceX
;
215 GopBltArgs
.SourceY
= SourceY
;
216 GopBltArgs
.Delta
= Delta
;
217 Status
= Private
->UgaIo
->UgaBlt (
219 (EFI_UGA_PIXEL
*)BltBuffer
,
220 (EFI_UGA_BLT_OPERATION
)BltOperation
,
224 gBS
->RestoreTPL (OriginalTPL
);
231 // Construction and Destruction functions
236 IN EFI_UNIX_IO_PROTOCOL
*UnixIo
249 // TODO: UnixIo - add argument and description to function comment
250 // TODO: EFI_UNSUPPORTED - add return value to function comment
251 // TODO: EFI_SUCCESS - add return value to function comment
254 // Check to see if the IO abstraction represents a device type we support.
256 // This would be replaced a check of PCI subsystem ID, etc.
258 if (!CompareGuid (UnixIo
->TypeGuid
, &gEfiUnixGopGuid
)) {
259 return EFI_UNSUPPORTED
;
268 GopPrivateInvokeRegisteredFunction (
270 IN EFI_KEY_DATA
*KeyData
276 IN GOP_PRIVATE_DATA
*Private
,
277 IN UINT32 HorizontalResolution
,
278 IN UINT32 VerticalResolution
,
279 IN UINT32 ColorDepth
,
280 IN UINT32 RefreshRate
285 mUnix
= Private
->UnixThunk
;
288 // Register to be notified on exit boot services so we can destroy the window.
290 Status
= gBS
->CreateEvent (
291 EVT_SIGNAL_EXIT_BOOT_SERVICES
,
295 &mGopScreenExitBootServicesEvent
298 Status
= Private
->UnixThunk
->UgaCreate (&Private
->UgaIo
, Private
->WindowName
);
299 if (!EFI_ERROR (Status
)) {
300 // Register callback to support RegisterKeyNotify()
301 Status
= Private
->UgaIo
->UgaRegisterKeyNotify (Private
->UgaIo
, GopPrivateInvokeRegisteredFunction
, Private
);
302 ASSERT_EFI_ERROR (Status
);
309 GOP_PRIVATE_DATA
*Private
312 Private
->ModeData
= mGopModeData
;
314 Private
->GraphicsOutput
.QueryMode
= UnixGopQuerytMode
;
315 Private
->GraphicsOutput
.SetMode
= UnixGopSetMode
;
316 Private
->GraphicsOutput
.Blt
= UnixGopBlt
;
319 // Allocate buffer for Graphics Output Protocol mode information
321 Private
->GraphicsOutput
.Mode
= AllocatePool (sizeof (EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE
));
322 if (Private
->GraphicsOutput
.Mode
== NULL
) {
323 return EFI_OUT_OF_RESOURCES
;
325 Private
->GraphicsOutput
.Mode
->Info
= AllocatePool (sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
));
326 if (Private
->GraphicsOutput
.Mode
->Info
== NULL
) {
327 return EFI_OUT_OF_RESOURCES
;
330 Private
->GraphicsOutput
.Mode
->MaxMode
= sizeof(mGopModeData
) / sizeof(GOP_MODE_DATA
);
332 // Till now, we have no idea about the window size.
334 Private
->GraphicsOutput
.Mode
->Mode
= GRAPHICS_OUTPUT_INVALIDE_MODE_NUMBER
;
335 Private
->GraphicsOutput
.Mode
->Info
->Version
= 0;
336 Private
->GraphicsOutput
.Mode
->Info
->HorizontalResolution
= 0;
337 Private
->GraphicsOutput
.Mode
->Info
->VerticalResolution
= 0;
338 Private
->GraphicsOutput
.Mode
->Info
->PixelFormat
= PixelBltOnly
;
339 Private
->GraphicsOutput
.Mode
->SizeOfInfo
= sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
);
340 Private
->GraphicsOutput
.Mode
->FrameBufferBase
= (EFI_PHYSICAL_ADDRESS
) (UINTN
) NULL
;
341 Private
->GraphicsOutput
.Mode
->FrameBufferSize
= 0;
343 Private
->HardwareNeedsStarting
= TRUE
;
344 Private
->UgaIo
= NULL
;
346 UnixGopInitializeSimpleTextInForWindow (Private
);
348 UnixGopInitializeSimplePointerForWindow (Private
);
357 GOP_PRIVATE_DATA
*Private
360 if (!Private
->HardwareNeedsStarting
) {
361 Private
->UgaIo
->UgaClose (Private
->UgaIo
);
362 Private
->UgaIo
= NULL
;
366 // Free graphics output protocol occupied resource
368 if (Private
->GraphicsOutput
.Mode
!= NULL
) {
369 if (Private
->GraphicsOutput
.Mode
->Info
!= NULL
) {
370 FreePool (Private
->GraphicsOutput
.Mode
->Info
);
372 FreePool (Private
->GraphicsOutput
.Mode
);
388 This is the UGA screen's callback notification function for exit-boot-services.
389 All we do here is call UnixGopDestructor().
394 Context - pointer to the Private structure.
403 Status
= UnixGopDestructor (Context
);