1eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten/** @file
2eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  Graphics Output Protocol functions for the QEMU video controller.
3eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten
4eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR>
5eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten
6eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  This program and the accompanying materials
7eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  are licensed and made available under the terms and conditions of the BSD License
8eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  which accompanies this distribution. The full text of the license may be found at
9eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  http://opensource.org/licenses/bsd-license.php
10eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten
11eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
13eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten
14eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten**/
15eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten
16eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten#include "Qemu.h"
17eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten#include <IndustryStandard/Acpi.h>
18eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten#include <Library/BltLib.h>
19eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten
20eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljustenSTATIC
21eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljustenVOID
22eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljustenQemuVideoCompleteModeInfo (
23eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  IN  QEMU_VIDEO_MODE_DATA           *ModeData,
24eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION  *Info
25eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  )
26eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten{
27eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  Info->Version = 0;
28eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  if (ModeData->ColorDepth == 8) {
29eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten    Info->PixelFormat = PixelBitMask;
30eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten    Info->PixelInformation.RedMask = PIXEL_RED_MASK;
31eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten    Info->PixelInformation.GreenMask = PIXEL_GREEN_MASK;
32eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten    Info->PixelInformation.BlueMask = PIXEL_BLUE_MASK;
33eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten    Info->PixelInformation.ReservedMask = 0;
34eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  } else if (ModeData->ColorDepth == 24) {
35eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten    Info->PixelFormat = PixelBitMask;
36eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten    Info->PixelInformation.RedMask = PIXEL24_RED_MASK;
37eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten    Info->PixelInformation.GreenMask = PIXEL24_GREEN_MASK;
38eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten    Info->PixelInformation.BlueMask = PIXEL24_BLUE_MASK;
39eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten    Info->PixelInformation.ReservedMask = 0;
40eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  } else if (ModeData->ColorDepth == 32) {
41eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten    DEBUG ((EFI_D_INFO, "PixelBlueGreenRedReserved8BitPerColor\n"));
42eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten    Info->PixelFormat = PixelBlueGreenRedReserved8BitPerColor;
43eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  }
44eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  Info->PixelsPerScanLine = Info->HorizontalResolution;
45eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten}
46eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten
47eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten
48eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljustenSTATIC
49eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljustenEFI_STATUS
50eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljustenQemuVideoCompleteModeData (
51eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  IN  QEMU_VIDEO_PRIVATE_DATA           *Private,
52eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  OUT EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE *Mode
53eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  )
54eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten{
55eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  EFI_GRAPHICS_OUTPUT_MODE_INFORMATION  *Info;
56eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR     *FrameBufDesc;
57eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  QEMU_VIDEO_MODE_DATA           *ModeData;
58eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten
59eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  ModeData = &Private->ModeData[Mode->Mode];
60eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  Info = Mode->Info;
61eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  QemuVideoCompleteModeInfo (ModeData, Info);
62eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten
63eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  Private->PciIo->GetBarAttributes (
64eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten                        Private->PciIo,
65eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten                        0,
66eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten                        NULL,
67eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten                        (VOID**) &FrameBufDesc
68eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten                        );
69eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten
70eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  Mode->FrameBufferBase = FrameBufDesc->AddrRangeMin;
71eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  Mode->FrameBufferSize = Info->HorizontalResolution * Info->VerticalResolution;
72eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  Mode->FrameBufferSize = Mode->FrameBufferSize * ((ModeData->ColorDepth + 7) / 8);
736394c35a7db3d7a7cc68f491179a45fe430a335aLaszlo Ersek  DEBUG ((EFI_D_INFO, "FrameBufferBase: 0x%Lx, FrameBufferSize: 0x%Lx\n",
746394c35a7db3d7a7cc68f491179a45fe430a335aLaszlo Ersek    Mode->FrameBufferBase, (UINT64)Mode->FrameBufferSize));
75eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten
765cdb96fa0d5f689cb4b3b17ddd2cec164842aebdLaszlo Ersek  FreePool (FrameBufDesc);
77eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  return EFI_SUCCESS;
78eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten}
79eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten
80eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten
81eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten//
82eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten// Graphics Output Protocol Member Functions
83eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten//
84eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljustenEFI_STATUS
85eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljustenEFIAPI
86eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljustenQemuVideoGraphicsOutputQueryMode (
87eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  IN  EFI_GRAPHICS_OUTPUT_PROTOCOL          *This,
88eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  IN  UINT32                                ModeNumber,
89eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  OUT UINTN                                 *SizeOfInfo,
90eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION  **Info
91eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  )
92eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten/*++
93eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten
94eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljustenRoutine Description:
95eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten
96eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  Graphics Output protocol interface to query video mode
97eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten
98eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  Arguments:
99eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten    This                  - Protocol instance pointer.
100eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten    ModeNumber            - The mode number to return information on.
101eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten    Info                  - Caller allocated buffer that returns information about ModeNumber.
102eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten    SizeOfInfo            - A pointer to the size, in bytes, of the Info buffer.
103eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten
104eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  Returns:
105eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten    EFI_SUCCESS           - Mode information returned.
106eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten    EFI_BUFFER_TOO_SMALL  - The Info buffer was too small.
107eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten    EFI_DEVICE_ERROR      - A hardware error occurred trying to retrieve the video mode.
108eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten    EFI_NOT_STARTED       - Video display is not initialized. Call SetMode ()
109eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten    EFI_INVALID_PARAMETER - One of the input args was NULL.
110eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten
111eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten--*/
112eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten{
113eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  QEMU_VIDEO_PRIVATE_DATA  *Private;
114eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  QEMU_VIDEO_MODE_DATA     *ModeData;
115eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten
116eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  Private = QEMU_VIDEO_PRIVATE_DATA_FROM_GRAPHICS_OUTPUT_THIS (This);
117eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten
118eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  if (Info == NULL || SizeOfInfo == NULL || ModeNumber >= This->Mode->MaxMode) {
119eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten    return EFI_INVALID_PARAMETER;
120eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  }
121eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten
122eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  *Info = AllocatePool (sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION));
123eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  if (*Info == NULL) {
124eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten    return EFI_OUT_OF_RESOURCES;
125eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  }
126eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten
127eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  *SizeOfInfo = sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION);
128eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten
129eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  ModeData = &Private->ModeData[ModeNumber];
130eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  (*Info)->HorizontalResolution = ModeData->HorizontalResolution;
131eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  (*Info)->VerticalResolution   = ModeData->VerticalResolution;
132eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  QemuVideoCompleteModeInfo (ModeData, *Info);
133eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten
134eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  return EFI_SUCCESS;
135eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten}
136eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten
137eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljustenEFI_STATUS
138eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljustenEFIAPI
139eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljustenQemuVideoGraphicsOutputSetMode (
140eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  IN  EFI_GRAPHICS_OUTPUT_PROTOCOL *This,
141eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  IN  UINT32                       ModeNumber
142eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  )
143eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten/*++
144eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten
145eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljustenRoutine Description:
146eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten
147eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  Graphics Output protocol interface to set video mode
148eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten
149eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  Arguments:
150eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten    This             - Protocol instance pointer.
151eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten    ModeNumber       - The mode number to be set.
152eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten
153eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  Returns:
154eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten    EFI_SUCCESS      - Graphics mode was changed.
155eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten    EFI_DEVICE_ERROR - The device had an error and could not complete the request.
156eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten    EFI_UNSUPPORTED  - ModeNumber is not supported by this device.
157eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten
158eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten--*/
159eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten{
160eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  QEMU_VIDEO_PRIVATE_DATA    *Private;
161eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  QEMU_VIDEO_MODE_DATA       *ModeData;
162eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten//  UINTN                             Count;
163eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten
164eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  Private = QEMU_VIDEO_PRIVATE_DATA_FROM_GRAPHICS_OUTPUT_THIS (This);
165eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten
166eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  if (ModeNumber >= This->Mode->MaxMode) {
167eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten    return EFI_UNSUPPORTED;
168eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  }
169eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten
170eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  ModeData = &Private->ModeData[ModeNumber];
171eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten
172eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  if (Private->LineBuffer) {
173eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten    gBS->FreePool (Private->LineBuffer);
174eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  }
175eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten
176eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  Private->LineBuffer = AllocatePool (4 * ModeData->HorizontalResolution);
177eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  if (Private->LineBuffer == NULL) {
178eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten    return EFI_OUT_OF_RESOURCES;
179eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  }
180eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten
181212aac55fd13e985cebf88042f40479c01ac2e44jljusten  switch (Private->Variant) {
182212aac55fd13e985cebf88042f40479c01ac2e44jljusten  case QEMU_VIDEO_CIRRUS_5430:
183212aac55fd13e985cebf88042f40479c01ac2e44jljusten  case QEMU_VIDEO_CIRRUS_5446:
184cd1526101469cb639c7166c0b750c5ebb810a446Laszlo Ersek    InitializeCirrusGraphicsMode (Private, &QemuVideoCirrusModes[ModeData->InternalModeIndex]);
185212aac55fd13e985cebf88042f40479c01ac2e44jljusten    break;
186cdb4f5dcb1d4778da71c82cc15cab6e3cf218417jljusten  case QEMU_VIDEO_BOCHS_MMIO:
18754f9b9accbcb6dc7f965342fc75b478464de21a3jljusten  case QEMU_VIDEO_BOCHS:
188cd1526101469cb639c7166c0b750c5ebb810a446Laszlo Ersek    InitializeBochsGraphicsMode (Private, &QemuVideoBochsModes[ModeData->InternalModeIndex]);
18954f9b9accbcb6dc7f965342fc75b478464de21a3jljusten    break;
190212aac55fd13e985cebf88042f40479c01ac2e44jljusten  default:
191212aac55fd13e985cebf88042f40479c01ac2e44jljusten    ASSERT (FALSE);
192212aac55fd13e985cebf88042f40479c01ac2e44jljusten    gBS->FreePool (Private->LineBuffer);
193212aac55fd13e985cebf88042f40479c01ac2e44jljusten    Private->LineBuffer = NULL;
194212aac55fd13e985cebf88042f40479c01ac2e44jljusten    return EFI_DEVICE_ERROR;
195212aac55fd13e985cebf88042f40479c01ac2e44jljusten  }
196eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten
197eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  This->Mode->Mode = ModeNumber;
198eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  This->Mode->Info->HorizontalResolution = ModeData->HorizontalResolution;
199eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  This->Mode->Info->VerticalResolution = ModeData->VerticalResolution;
200eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  This->Mode->SizeOfInfo = sizeof(EFI_GRAPHICS_OUTPUT_MODE_INFORMATION);
201eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten
202eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  QemuVideoCompleteModeData (Private, This->Mode);
203eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten
204eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  BltLibConfigure (
205eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten    (VOID*)(UINTN) This->Mode->FrameBufferBase,
206eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten    This->Mode->Info
207eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten    );
208eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten
209eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  return EFI_SUCCESS;
210eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten}
211eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten
212eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljustenEFI_STATUS
213eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljustenEFIAPI
214eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljustenQemuVideoGraphicsOutputBlt (
215eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  IN  EFI_GRAPHICS_OUTPUT_PROTOCOL          *This,
216eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  IN  EFI_GRAPHICS_OUTPUT_BLT_PIXEL         *BltBuffer, OPTIONAL
217eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  IN  EFI_GRAPHICS_OUTPUT_BLT_OPERATION     BltOperation,
218eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  IN  UINTN                                 SourceX,
219eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  IN  UINTN                                 SourceY,
220eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  IN  UINTN                                 DestinationX,
221eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  IN  UINTN                                 DestinationY,
222eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  IN  UINTN                                 Width,
223eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  IN  UINTN                                 Height,
224eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  IN  UINTN                                 Delta
225eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  )
226eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten/*++
227eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten
228eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljustenRoutine Description:
229eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten
230eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  Graphics Output protocol instance to block transfer for CirrusLogic device
231eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten
232eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljustenArguments:
233eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten
234eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  This          - Pointer to Graphics Output protocol instance
235eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  BltBuffer     - The data to transfer to screen
236eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  BltOperation  - The operation to perform
237eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  SourceX       - The X coordinate of the source for BltOperation
238eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  SourceY       - The Y coordinate of the source for BltOperation
239eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  DestinationX  - The X coordinate of the destination for BltOperation
240eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  DestinationY  - The Y coordinate of the destination for BltOperation
241eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  Width         - The width of a rectangle in the blt rectangle in pixels
242eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  Height        - The height of a rectangle in the blt rectangle in pixels
243eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  Delta         - Not used for EfiBltVideoFill and EfiBltVideoToVideo operation.
244eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten                  If a Delta of 0 is used, the entire BltBuffer will be operated on.
245eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten                  If a subrectangle of the BltBuffer is used, then Delta represents
246eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten                  the number of bytes in a row of the BltBuffer.
247eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten
248eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljustenReturns:
249eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten
250eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  EFI_INVALID_PARAMETER - Invalid parameter passed in
251eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  EFI_SUCCESS - Blt operation success
252eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten
253eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten--*/
254eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten{
255eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  EFI_STATUS                      Status;
256eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  EFI_TPL                         OriginalTPL;
257eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten
258eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  //
259eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  // We have to raise to TPL Notify, so we make an atomic write the frame buffer.
260eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  // We would not want a timer based event (Cursor, ...) to come in while we are
261eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  // doing this operation.
262eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  //
263eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  OriginalTPL = gBS->RaiseTPL (TPL_NOTIFY);
264eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten
265eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  switch (BltOperation) {
266eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  case EfiBltVideoToBltBuffer:
267eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  case EfiBltBufferToVideo:
268eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  case EfiBltVideoFill:
269eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  case EfiBltVideoToVideo:
270eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten    Status = BltLibGopBlt (
271eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten      BltBuffer,
272eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten      BltOperation,
273eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten      SourceX,
274eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten      SourceY,
275eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten      DestinationX,
276eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten      DestinationY,
277eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten      Width,
278eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten      Height,
279eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten      Delta
280eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten      );
281eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten    break;
282eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten
283eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  default:
284eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten    Status = EFI_INVALID_PARAMETER;
285eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten    ASSERT (FALSE);
286eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  }
287eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten
288eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  gBS->RestoreTPL (OriginalTPL);
289eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten
290eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  return Status;
291eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten}
292eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten
293eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljustenEFI_STATUS
294eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljustenQemuVideoGraphicsOutputConstructor (
295eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  QEMU_VIDEO_PRIVATE_DATA  *Private
296eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  )
297eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten{
298eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  EFI_STATUS                   Status;
299eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;
300eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten
301eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten
302eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  GraphicsOutput            = &Private->GraphicsOutput;
303eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  GraphicsOutput->QueryMode = QemuVideoGraphicsOutputQueryMode;
304eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  GraphicsOutput->SetMode   = QemuVideoGraphicsOutputSetMode;
305eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  GraphicsOutput->Blt       = QemuVideoGraphicsOutputBlt;
306eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten
307eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  //
308eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  // Initialize the private data
309eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  //
310eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  Status = gBS->AllocatePool (
311eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten                  EfiBootServicesData,
312eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten                  sizeof (EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE),
313eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten                  (VOID **) &Private->GraphicsOutput.Mode
314eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten                  );
315eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  if (EFI_ERROR (Status)) {
316eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten    return Status;
317eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  }
318d89186bc869bfedd9f83f8e52f995dfd04691521Laszlo Ersek
319eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  Status = gBS->AllocatePool (
320eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten                  EfiBootServicesData,
321eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten                  sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION),
322eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten                  (VOID **) &Private->GraphicsOutput.Mode->Info
323eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten                  );
324eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  if (EFI_ERROR (Status)) {
325d89186bc869bfedd9f83f8e52f995dfd04691521Laszlo Ersek    goto FreeMode;
326eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  }
327eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  Private->GraphicsOutput.Mode->MaxMode = (UINT32) Private->MaxMode;
328eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  Private->GraphicsOutput.Mode->Mode    = GRAPHICS_OUTPUT_INVALIDE_MODE_NUMBER;
329eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  Private->LineBuffer                   = NULL;
330eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten
331eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  //
332eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  // Initialize the hardware
333eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  //
334d89186bc869bfedd9f83f8e52f995dfd04691521Laszlo Ersek  Status = GraphicsOutput->SetMode (GraphicsOutput, 0);
335d89186bc869bfedd9f83f8e52f995dfd04691521Laszlo Ersek  if (EFI_ERROR (Status)) {
336d89186bc869bfedd9f83f8e52f995dfd04691521Laszlo Ersek    goto FreeInfo;
337d89186bc869bfedd9f83f8e52f995dfd04691521Laszlo Ersek  }
338d89186bc869bfedd9f83f8e52f995dfd04691521Laszlo Ersek
339eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  DrawLogo (
340eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten    Private,
341eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten    Private->ModeData[Private->GraphicsOutput.Mode->Mode].HorizontalResolution,
342eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten    Private->ModeData[Private->GraphicsOutput.Mode->Mode].VerticalResolution
343eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten    );
344eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten
345eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  return EFI_SUCCESS;
346d89186bc869bfedd9f83f8e52f995dfd04691521Laszlo Ersek
347d89186bc869bfedd9f83f8e52f995dfd04691521Laszlo ErsekFreeInfo:
348d89186bc869bfedd9f83f8e52f995dfd04691521Laszlo Ersek  FreePool (Private->GraphicsOutput.Mode->Info);
349d89186bc869bfedd9f83f8e52f995dfd04691521Laszlo Ersek
350d89186bc869bfedd9f83f8e52f995dfd04691521Laszlo ErsekFreeMode:
351d89186bc869bfedd9f83f8e52f995dfd04691521Laszlo Ersek  FreePool (Private->GraphicsOutput.Mode);
352d89186bc869bfedd9f83f8e52f995dfd04691521Laszlo Ersek  Private->GraphicsOutput.Mode = NULL;
353d89186bc869bfedd9f83f8e52f995dfd04691521Laszlo Ersek
354d89186bc869bfedd9f83f8e52f995dfd04691521Laszlo Ersek  return Status;
355eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten}
356eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten
357eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljustenEFI_STATUS
358eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljustenQemuVideoGraphicsOutputDestructor (
359eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  QEMU_VIDEO_PRIVATE_DATA  *Private
360eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  )
361eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten/*++
362eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten
363eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljustenRoutine Description:
364eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten
365eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljustenArguments:
366eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten
367eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljustenReturns:
368eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten
369eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  None
370eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten
371eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten--*/
372eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten{
373d89186bc869bfedd9f83f8e52f995dfd04691521Laszlo Ersek  if (Private->LineBuffer != NULL) {
374d89186bc869bfedd9f83f8e52f995dfd04691521Laszlo Ersek    FreePool (Private->LineBuffer);
375d89186bc869bfedd9f83f8e52f995dfd04691521Laszlo Ersek  }
376d89186bc869bfedd9f83f8e52f995dfd04691521Laszlo Ersek
377eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  if (Private->GraphicsOutput.Mode != NULL) {
378eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten    if (Private->GraphicsOutput.Mode->Info != NULL) {
379eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten      gBS->FreePool (Private->GraphicsOutput.Mode->Info);
380eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten    }
381eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten    gBS->FreePool (Private->GraphicsOutput.Mode);
382eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  }
383eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten
384eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten  return EFI_SUCCESS;
385eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten}
386eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten
387eaf4f336ea42dc32e1a5b31d6b7822c125a15d34jljusten
388