~ubuntu-branches/ubuntu/vivid/virtualbox-ose/vivid

« back to all changes in this revision

Viewing changes to src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxVgaMiniPortDxe/VBoxVgaMiniPortDxe.c

  • Committer: Bazaar Package Importer
  • Author(s): Felix Geyer
  • Date: 2010-03-11 17:16:37 UTC
  • mfrom: (0.3.4 upstream) (0.4.8 sid)
  • Revision ID: james.westby@ubuntu.com-20100311171637-43z64ia3ccpj8vqn
Tags: 3.1.4-dfsg-2ubuntu1
* Merge from Debian unstable (LP: #528561), remaining changes:
  - VirtualBox should go in Accessories, not in System tools (LP: #288590)
    - debian/virtualbox-ose-qt.files/virtualbox-ose.desktop
  - Add Apport hook
    - debian/virtualbox-ose.files/source_virtualbox-ose.py
    - debian/virtualbox-ose.install
  - Add Launchpad integration
    - debian/control
    - debian/lpi-bug.xpm
    - debian/patches/u02-lp-integration.dpatch
  - Replace *-source packages with transitional packages for *-dkms
* Fix crash in vboxvideo_drm with kernel 2.6.33 / backported drm code
  (LP: #535297)
* Add a list of linux-headers packages to the apport hook
* Update debian/patches/u02-lp-integration.dpatch with a
  DEP-3 compliant header
* Add ${misc:Depends} to virtualbox-ose-source and virtualbox-ose-guest-source
  Depends

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* $Id: VBoxVgaMiniPortDxe.c $ */
 
2
/** @file
 
3
 * VBoxVgaMiniPortDxe.c - VgaMiniPort Protocol Implementation.
 
4
 */
 
5
 
 
6
 
 
7
/*
 
8
 * Copyright (C) 2009-2010 Sun Microsystems, Inc.
 
9
 *
 
10
 * This file is part of VirtualBox Open Source Edition (OSE), as
 
11
 * available from http://www.virtualbox.org. This file is free software;
 
12
 * you can redistribute it and/or modify it under the terms of the GNU
 
13
 * General Public License (GPL) as published by the Free Software
 
14
 * Foundation, in version 2 as it comes in the "COPYING" file of the
 
15
 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
 
16
 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
 
17
 *
 
18
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
 
19
 * Clara, CA 95054 USA or visit http://www.sun.com if you need
 
20
 * additional information or have any questions.
 
21
 */
 
22
 
 
23
 
 
24
/*******************************************************************************
 
25
*   Header Files                                                               *
 
26
*******************************************************************************/
 
27
#include <Protocol/ComponentName.h>
 
28
#include <Protocol/ComponentName2.h>
 
29
#include <Protocol/DriverBinding.h>
 
30
#include <Protocol/PciIo.h>
 
31
#include <Protocol/VgaMiniPort.h>
 
32
#include <Library/BaseMemoryLib.h>
 
33
#include <Library/DebugLib.h>
 
34
#include <Library/UefiBootServicesTableLib.h>
 
35
#include <Library/UefiLib.h>
 
36
#include <IndustryStandard/Pci22.h>
 
37
 
 
38
#include "VBoxPkg.h"
 
39
#include "iprt/asm.h"
 
40
#include "VBoxVgaFonts.h"
 
41
 
 
42
 
 
43
/*******************************************************************************
 
44
*   Structures and Typedefs                                                    *
 
45
*******************************************************************************/
 
46
/**
 
47
 * Instance data for a VGA device this driver handles.
 
48
 */
 
49
typedef struct VBOXVGAMINIPORT
 
50
{
 
51
    /** The VGA Mini Port Protocol. */
 
52
    EFI_VGA_MINI_PORT_PROTOCOL  VgaMiniPort;
 
53
    /** Magic value, VBOX_VGA_MINI_PORT_MAGIC. */
 
54
    UINT32                      u32Magic;
 
55
    /** The controller handle of the device. */
 
56
    EFI_HANDLE                  hController;
 
57
    /** The PciIo protocol for the device. */
 
58
    EFI_PCI_IO_PROTOCOL        *pPciIo;
 
59
} VBOXVGAMINIPORT;
 
60
/** Pointer to a VBOXVGAMINIPORT structure. */
 
61
typedef VBOXVGAMINIPORT *PVBOXVGAMINIPORT;
 
62
 
 
63
/** VBOXVGAMINIPORT::u32Magic value (Isaac Asimov). */
 
64
#define VBOX_VGA_MINI_PORT_MAGIC        0x19200102
 
65
/** VBOXVGAMINIPORT::u32Magic dead value. */
 
66
#define VBOX_VGA_MINI_PORT_MAGIC_DEAD   0x19920406
 
67
 
 
68
 
 
69
/*******************************************************************************
 
70
*   Internal Functions                                                         *
 
71
*******************************************************************************/
 
72
static EFI_STATUS EFIAPI
 
73
VBoxVgaMiniPortDB_Supported(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE ControllerHandle,
 
74
                            IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL);
 
75
static EFI_STATUS EFIAPI
 
76
VBoxVgaMiniPortDB_Start(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE ControllerHandle,
 
77
                        IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL);
 
78
static EFI_STATUS EFIAPI
 
79
VBoxVgaMiniPortDB_Stop(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE ControllerHandle,
 
80
                       IN UINTN NumberOfChildren, IN EFI_HANDLE *ChildHandleBuffer OPTIONAL);
 
81
 
 
82
 
 
83
static EFI_STATUS EFIAPI
 
84
VBoxVgaMiniPortVMP_SetMode(IN EFI_VGA_MINI_PORT_PROTOCOL *This, IN UINTN ModeNumber);
 
85
 
 
86
 
 
87
static EFI_STATUS EFIAPI
 
88
VBoxVgaMiniPortCN_GetDriverName(IN EFI_COMPONENT_NAME_PROTOCOL *This,
 
89
                                IN CHAR8 *Language, OUT CHAR16 **DriverName);
 
90
static EFI_STATUS EFIAPI
 
91
VBoxVgaMiniPortCN_GetControllerName(IN EFI_COMPONENT_NAME_PROTOCOL *This,
 
92
                                    IN EFI_HANDLE ControllerHandle,
 
93
                                    IN EFI_HANDLE ChildHandle OPTIONAL,
 
94
                                    IN CHAR8 *Language,  OUT CHAR16 **ControllerName);
 
95
 
 
96
 
 
97
static EFI_STATUS EFIAPI
 
98
VBoxVgaMiniPortCN2_GetDriverName(IN EFI_COMPONENT_NAME2_PROTOCOL *This,
 
99
                                 IN CHAR8 *Language, OUT CHAR16 **DriverName);
 
100
static EFI_STATUS EFIAPI
 
101
VBoxVgaMiniPortCN2_GetControllerName(IN EFI_COMPONENT_NAME2_PROTOCOL *This,
 
102
                                     IN EFI_HANDLE ControllerHandle,
 
103
                                     IN EFI_HANDLE ChildHandle OPTIONAL,
 
104
                                     IN CHAR8 *Language,  OUT CHAR16 **ControllerName);
 
105
 
 
106
 
 
107
/*******************************************************************************
 
108
*   Global Variables                                                           *
 
109
*******************************************************************************/
 
110
/** EFI Driver Binding Protocol. */
 
111
static EFI_DRIVER_BINDING_PROTOCOL          g_VBoxVgaMiniPortDB =
 
112
{
 
113
    VBoxVgaMiniPortDB_Supported,
 
114
    VBoxVgaMiniPortDB_Start,
 
115
    VBoxVgaMiniPortDB_Stop,
 
116
    /* .Version             = */    1,  /* One higher than Pci/VgaMiniPortDxe. */
 
117
    /* .ImageHandle         = */ NULL,
 
118
    /* .DriverBindingHandle = */ NULL
 
119
};
 
120
 
 
121
/** EFI Component Name Protocol. */
 
122
static const EFI_COMPONENT_NAME_PROTOCOL    g_VBoxVgaMiniPortCN =
 
123
{
 
124
    VBoxVgaMiniPortCN_GetDriverName,
 
125
    VBoxVgaMiniPortCN_GetControllerName,
 
126
    "eng"
 
127
};
 
128
 
 
129
/** EFI Component Name 2 Protocol. */
 
130
static const EFI_COMPONENT_NAME2_PROTOCOL   g_VBoxVgaMiniPortCN2 =
 
131
{
 
132
    VBoxVgaMiniPortCN2_GetDriverName,
 
133
    VBoxVgaMiniPortCN2_GetControllerName,
 
134
    "en"
 
135
};
 
136
 
 
137
/** Driver name translation table. */
 
138
static CONST EFI_UNICODE_STRING_TABLE       g_aVBoxMiniPortDriverLangAndNames[] =
 
139
{
 
140
    {   "eng;en",   L"PCI VGA Mini Port Driver" },
 
141
    {   NULL,       NULL }
 
142
};
 
143
 
 
144
 
 
145
 
 
146
/**
 
147
 * VBoxVgaMiniPort entry point.
 
148
 *
 
149
 * @returns EFI status code.
 
150
 *
 
151
 * @param   ImageHandle     The image handle.
 
152
 * @param   SystemTable     The system table pointer.
 
153
 */
 
154
EFI_STATUS EFIAPI
 
155
DxeInitializeVBoxVgaMiniPort(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable)
 
156
{
 
157
    EFI_STATUS  rc;
 
158
    DEBUG((DEBUG_INFO, "DxeInitializeVBoxVgaMiniPort\n"));
 
159
 
 
160
    rc = EfiLibInstallDriverBindingComponentName2(ImageHandle, SystemTable,
 
161
                                                  &g_VBoxVgaMiniPortDB, ImageHandle,
 
162
                                                  &g_VBoxVgaMiniPortCN, &g_VBoxVgaMiniPortCN2);
 
163
    ASSERT_EFI_ERROR(rc);
 
164
    return rc;
 
165
}
 
166
 
 
167
/**
 
168
 * @copydoc EFI_DRIVER_BINDING_SUPPORTED
 
169
 */
 
170
static EFI_STATUS EFIAPI
 
171
VBoxVgaMiniPortDB_Supported(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE ControllerHandle,
 
172
                            IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL)
 
173
{
 
174
    EFI_STATUS              rcRet = EFI_UNSUPPORTED;
 
175
    EFI_PCI_IO_PROTOCOL    *pPciIo;
 
176
    EFI_STATUS              rc;
 
177
 
 
178
    DEBUG((DEBUG_INFO, "%a: Controller=%p\n", __FUNCTION__, ControllerHandle));
 
179
 
 
180
    /*
 
181
     * To perform the test we need to check some PCI configuration registers,
 
182
     * just read all the standard ones to make life simpler.
 
183
     */
 
184
    rc = gBS->OpenProtocol(ControllerHandle, &gEfiPciIoProtocolGuid, (VOID **)&pPciIo,
 
185
                           This->DriverBindingHandle, ControllerHandle, EFI_OPEN_PROTOCOL_BY_DRIVER);
 
186
    if (!EFI_ERROR(rc))
 
187
    {
 
188
        PCI_TYPE00  CfgRegs;
 
189
 
 
190
        rc = pPciIo->Pci.Read(pPciIo,
 
191
                              EfiPciIoWidthUint32,
 
192
                              0 /* Offset */,
 
193
                              sizeof(CfgRegs) / sizeof(UINT32) /* Count */ ,
 
194
                              &CfgRegs);
 
195
        if (!EFI_ERROR(rc))
 
196
        {
 
197
            /*
 
198
             * Perform the test.
 
199
             */
 
200
            if (IS_PCI_VGA(&CfgRegs))
 
201
            {
 
202
#if 0 /** @todo this doesn't quite work with our DevVGA since it doesn't flag I/O access. */
 
203
                if (    CfgRegs.Hdr.Command & (PCI_COMMAND_IOACCESS | PCI_COMMAND_MEMACCESS)
 
204
                    == (PCI_COMMAND_IOACCESS | PCI_COMMAND_MEMACCESS))
 
205
#else
 
206
                if (1)
 
207
#endif
 
208
                {
 
209
                    DEBUG((DEBUG_INFO, "%a: Found supported VGA device! (VendorId=%x DeviceId=%x)\n",
 
210
                           __FUNCTION__, CfgRegs.Hdr.VendorId, CfgRegs.Hdr.DeviceId));
 
211
                    rcRet = EFI_SUCCESS;
 
212
                }
 
213
                else
 
214
                    DEBUG((DEBUG_INFO, "%a: VGA device not enabled! (VendorId=%x DeviceId=%x)\n",
 
215
                           __FUNCTION__, CfgRegs.Hdr.VendorId, CfgRegs.Hdr.DeviceId));
 
216
            }
 
217
            else
 
218
                DEBUG((DEBUG_INFO, "%a: Not VGA (Class=%x,%x,%x VendorId=%x DeviceId=%x)\n",
 
219
                       __FUNCTION__, CfgRegs.Hdr.ClassCode[0], CfgRegs.Hdr.ClassCode[1],
 
220
                       CfgRegs.Hdr.ClassCode[2], CfgRegs.Hdr.VendorId, CfgRegs.Hdr.DeviceId));
 
221
        }
 
222
        else
 
223
            DEBUG((DEBUG_INFO, "%a: pPciIo->Pci.Read -> %r\n", __FUNCTION__, rc));
 
224
 
 
225
        gBS->CloseProtocol(ControllerHandle, &gEfiPciIoProtocolGuid, This->DriverBindingHandle, ControllerHandle);
 
226
    }
 
227
    else
 
228
        DEBUG((DEBUG_INFO, "%a: PciIoProtocol -> %r\n", __FUNCTION__, rc));
 
229
    return rcRet;
 
230
}
 
231
 
 
232
/**
 
233
 * @copydoc EFI_DRIVER_BINDING_START
 
234
 */
 
235
static EFI_STATUS EFIAPI
 
236
VBoxVgaMiniPortDB_Start(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE ControllerHandle,
 
237
                        IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL)
 
238
{
 
239
    EFI_STATUS              rc;
 
240
    EFI_PCI_IO_PROTOCOL    *pPciIo;
 
241
 
 
242
    DEBUG((DEBUG_INFO, "%a\n", __FUNCTION__));
 
243
 
 
244
    /*
 
245
     * We need the PCI I/O abstraction protocol.
 
246
     */
 
247
    rc = gBS->OpenProtocol(ControllerHandle, &gEfiPciIoProtocolGuid, (VOID **)&pPciIo,
 
248
                           This->DriverBindingHandle, ControllerHandle, EFI_OPEN_PROTOCOL_BY_DRIVER);
 
249
    if (!EFI_ERROR(rc))
 
250
    {
 
251
        /*
 
252
         * Allocate and initialize the instance data.
 
253
         */
 
254
        PVBOXVGAMINIPORT pThisDev;
 
255
        rc = gBS->AllocatePool(EfiBootServicesData, sizeof(*pThisDev), (VOID **)&pThisDev);
 
256
        if (!EFI_ERROR(rc))
 
257
        {
 
258
            pThisDev->VgaMiniPort.SetMode                   = VBoxVgaMiniPortVMP_SetMode;
 
259
            pThisDev->VgaMiniPort.VgaMemoryOffset           = 0x000b8000;
 
260
            pThisDev->VgaMiniPort.CrtcAddressRegisterOffset = 0x03d4;
 
261
            pThisDev->VgaMiniPort.CrtcDataRegisterOffset    = 0x03d5;
 
262
            pThisDev->VgaMiniPort.VgaMemoryBar              = EFI_PCI_IO_PASS_THROUGH_BAR;
 
263
            pThisDev->VgaMiniPort.CrtcAddressRegisterBar    = EFI_PCI_IO_PASS_THROUGH_BAR;
 
264
            pThisDev->VgaMiniPort.CrtcDataRegisterBar       = EFI_PCI_IO_PASS_THROUGH_BAR;
 
265
            pThisDev->VgaMiniPort.MaxMode                   = 2;
 
266
            pThisDev->u32Magic                              = VBOX_VGA_MINI_PORT_MAGIC;
 
267
            pThisDev->hController                           = ControllerHandle;
 
268
            pThisDev->pPciIo                                = pPciIo;
 
269
 
 
270
            /*
 
271
             * Register the VGA Mini Port Protocol.
 
272
             */
 
273
            rc = gBS->InstallMultipleProtocolInterfaces(&ControllerHandle,
 
274
                                                        &gEfiVgaMiniPortProtocolGuid, &pThisDev->VgaMiniPort,
 
275
                                                        NULL, NULL);
 
276
            if (!EFI_ERROR(rc))
 
277
            {
 
278
                DEBUG((DEBUG_INFO, "%a: Successfully started, pThisDev=%p ControllerHandle=%p\n",
 
279
                       __FUNCTION__, pThisDev, ControllerHandle));
 
280
                return EFI_SUCCESS;
 
281
            }
 
282
 
 
283
            DEBUG((DEBUG_INFO, "%a: InstallMultipleProtocolInterfaces -> %r\n", __FUNCTION__, rc));
 
284
            gBS->FreePool(pThisDev);
 
285
        }
 
286
        else
 
287
            DEBUG((DEBUG_INFO, "%a: AllocatePool -> %r\n", __FUNCTION__, rc));
 
288
 
 
289
        gBS->CloseProtocol(ControllerHandle, &gEfiPciIoProtocolGuid, This->DriverBindingHandle, ControllerHandle);
 
290
    }
 
291
    else
 
292
        DEBUG((DEBUG_INFO, "%a: PciIoProtocol -> %r\n", __FUNCTION__, rc));
 
293
    return rc;
 
294
}
 
295
 
 
296
/**
 
297
 * @copydoc EFI_DRIVER_BINDING_STOP
 
298
 */
 
299
static EFI_STATUS EFIAPI
 
300
VBoxVgaMiniPortDB_Stop(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE ControllerHandle,
 
301
                       IN UINTN NumberOfChildren, IN EFI_HANDLE *ChildHandleBuffer OPTIONAL)
 
302
{
 
303
    EFI_STATUS                  rc;
 
304
    PVBOXVGAMINIPORT            pThisDev;
 
305
 
 
306
    DEBUG((DEBUG_INFO, "%a: ControllerHandle=%p NumberOfChildren=%u\n", __FUNCTION__, ControllerHandle, NumberOfChildren));
 
307
 
 
308
    /*
 
309
     * Get the miniport driver instance associated with the controller.
 
310
     */
 
311
    rc = gBS->OpenProtocol(ControllerHandle, &gEfiVgaMiniPortProtocolGuid,
 
312
                           (VOID **)&pThisDev, This->DriverBindingHandle,
 
313
                           ControllerHandle, EFI_OPEN_PROTOCOL_GET_PROTOCOL);
 
314
    if (!EFI_ERROR(rc))
 
315
    {
 
316
        ASSERT(pThisDev->u32Magic == VBOX_VGA_MINI_PORT_MAGIC);
 
317
        ASSERT(pThisDev->hController == ControllerHandle);
 
318
        if (    pThisDev->u32Magic == VBOX_VGA_MINI_PORT_MAGIC
 
319
            &&  pThisDev->hController == ControllerHandle)
 
320
        {
 
321
            /*
 
322
             * Uninstall the VgaMiniPort interface.
 
323
             */
 
324
            rc = gBS->UninstallProtocolInterface(ControllerHandle,
 
325
                                                 &gEfiVgaMiniPortProtocolGuid,
 
326
                                                 &pThisDev->VgaMiniPort);
 
327
            if (!EFI_ERROR(rc))
 
328
            {
 
329
                /*
 
330
                 * Invalidate and release sources associated with the device instance.
 
331
                 */
 
332
                pThisDev->u32Magic = VBOX_VGA_MINI_PORT_MAGIC_DEAD;
 
333
                gBS->FreePool(pThisDev);
 
334
 
 
335
            }
 
336
            else
 
337
                DEBUG((DEBUG_INFO, "%a: UninstallProtocolInterface -> %r\n", __FUNCTION__, rc));
 
338
        }
 
339
        else
 
340
        {
 
341
            DEBUG((DEBUG_INFO, "%a: magic=%x/%x hController=%x/%x\n", __FUNCTION__,
 
342
                   pThisDev->u32Magic, VBOX_VGA_MINI_PORT_MAGIC,
 
343
                   pThisDev->hController, ControllerHandle));
 
344
            rc = EFI_DEVICE_ERROR;
 
345
        }
 
346
        gBS->CloseProtocol(ControllerHandle, &gEfiPciIoProtocolGuid,
 
347
                           This->DriverBindingHandle, ControllerHandle);
 
348
    }
 
349
    else
 
350
        DEBUG((DEBUG_INFO, "%a: VgaMiniPortProtocol -> %r\n", __FUNCTION__, rc));
 
351
    return rc;
 
352
}
 
353
 
 
354
 
 
355
 
 
356
 
 
357
 
 
358
/**
 
359
 * @copydoc EFI_VGA_MINI_PORT_SET_MODE
 
360
 */
 
361
static EFI_STATUS EFIAPI
 
362
VBoxVgaMiniPortVMP_SetMode(IN EFI_VGA_MINI_PORT_PROTOCOL *This, IN UINTN ModeNumber)
 
363
{
 
364
    PVBOXVGAMINIPORT    pThisDev = (PVBOXVGAMINIPORT)This;
 
365
    UINT8               r[64];
 
366
    int                 i;
 
367
 
 
368
    /*
 
369
     * Check input.
 
370
     */
 
371
    if (pThisDev->u32Magic != VBOX_VGA_MINI_PORT_MAGIC)
 
372
    {
 
373
        DEBUG((DEBUG_INFO, "%a: u32Magic=%x/%x\n", __FUNCTION__, pThisDev->u32Magic, VBOX_VGA_MINI_PORT_MAGIC));
 
374
        return EFI_DEVICE_ERROR;
 
375
    }
 
376
    if (ModeNumber >= This->MaxMode)
 
377
    {
 
378
        DEBUG((DEBUG_INFO, "%a: ModeNumber=%d >= MaxMode=%d\n", __FUNCTION__, ModeNumber, This->MaxMode));
 
379
        return EFI_UNSUPPORTED;
 
380
    }
 
381
    DEBUG((DEBUG_INFO, "%a: ModeNumber=%d\n", __FUNCTION__, ModeNumber));
 
382
 
 
383
    /* some initialization */
 
384
    ASMOutU8(0x3c2, 0xc3);
 
385
    ASMOutU8(0x3c4, 0x04);
 
386
    ASMOutU8(0x3c5, 0x02);
 
387
 
 
388
    /*
 
389
     * inb(r63, 0x3da);                     // reset attr F/F
 
390
     * outb(0x3c0, 0);                      // disable palette
 
391
     * outb(0x3d4, 0x11); outb(0x3d5, 0);   // unprotect crtc regs 0 - 7
 
392
     */
 
393
    r[63] = ASMInU8((UINTN)0x3da);
 
394
    ASMOutU8(0x3c0, 0);
 
395
    ASMOutU16(0x3d4, 0x0011);
 
396
 
 
397
#define BOUTB(count, aport, dport)  \
 
398
     do {                                \
 
399
         for (i = 0 ; i < count; ++i)    \
 
400
         {                               \
 
401
             ASMOutU8((aport), (UINT8)i);\
 
402
             ASMOutU8((dport), r[i]);    \
 
403
         }                               \
 
404
     } while (0)
 
405
 
 
406
    /*
 
407
     *  Reset and set sequencer registers
 
408
     *
 
409
     * r0 = 0x01;  r1 = 0x00;  r2 = 0x03;  r3 = 0x00;  r4 = 0x02;
 
410
     * boutb(5, 0x3c4, 0x3c5);
 
411
     */
 
412
     r[0] = 0x01;
 
413
     r[1] = 0x00;
 
414
     r[2] = 0x03;
 
415
     r[3] = 0x00;
 
416
     r[4] = 0x02;
 
417
     BOUTB(5, 0x3c4, 0x3c5);
 
418
 
 
419
     /*
 
420
      *  set misc out register
 
421
      *
 
422
      * outb(0x3c2, 0x67);
 
423
      *
 
424
      * r0 = 3
 
425
      * boutb(1, 0x3c4, 0x3c5);         // enable sequencer
 
426
      */
 
427
     r[0] = 3;
 
428
     BOUTB(1, 0x3c4, 0x3c5);
 
429
 
 
430
     /*  set all crtc registers */
 
431
     r[0] = 0x5f;  r[1] = 0x4f;  r[2] = 0x50;  r[3] = 0x82;
 
432
     r[4] = 0x55;  r[5] = 0x81;  r[6] = 0xbf;  r[7] = 0x1f;
 
433
     r[8] = 0x00;  r[9] = 0x4f;  r[10]= 0x0d;  r[11]= 0x0e;
 
434
     r[12]= 0x00;  r[13]= 0x00;  r[14]= 0x03;  r[15]= 0xc0;
 
435
     r[16]= 0x9c;  r[17]= 0x0e;  r[18]= 0x8f;  r[19]= 0x28;
 
436
     r[20]= 0x1f;  r[21]= 0x96;  r[22]= 0xb9;  r[23]= 0xa3;
 
437
     r[24]= 0xff;
 
438
     BOUTB(25, 0x3d4, 0x3d5);
 
439
 
 
440
     /*  set all graphics controller registers */
 
441
     r[0]= 0x00;  r[1]= 0x00;  r[2]= 0x00;  r[3]= 0x00;
 
442
     r[4]= 0x00;  r[5]= 0x10;  r[6]= 0x0e;  r[7]= 0x00;
 
443
     r[8]= 0xff;
 
444
     BOUTB(9, 0x3ce, 0x3cf);
 
445
 
 
446
     /*  set all attribute registers */
 
447
     r[63] = ASMInU8(0x3da);            // reset flip/flop
 
448
     r[0] = 0x00;  r[1] = 0x01;  r[2] = 0x02;  r[3] = 0x03;
 
449
     r[4] = 0x04;  r[5] = 0x05;  r[6] = 0x14;  r[7] = 0x07;
 
450
     r[8] = 0x38;  r[9] = 0x39;  r[10]= 0x3a;  r[11]= 0x3b;
 
451
     r[12]= 0x3c;  r[13]= 0x3d;  r[14]= 0x3e;  r[15]= 0x3f;
 
452
     r[16]= 0x0c;  r[17]= 0x00;  r[18]= 0x0f;  r[19]= 0x08;
 
453
     r[20]= 0x00;
 
454
     BOUTB(21, 0x3c0, 0x3c0);
 
455
     ASMOutU8(0x3c0, 0x20);             // re-enable palette
 
456
 
 
457
     /* set all VBox extended registers */
 
458
     r[0] = 1;
 
459
     BOUTB(1, 0x3c4, 0x3c5);            // disable sequencer
 
460
 
 
461
     ASMOutU16(0x1ce, 0x04); ASMOutU16(0x1cf, 0);  // ENABLE
 
462
 
 
463
     r[0] = 3;
 
464
     BOUTB(1, 0x3c4, 0x3c5);            // enable sequencer
 
465
 
 
466
     /* Load default values into the first 16 entries of the DAC */
 
467
     {
 
468
         static const UINT8 s_a3bVgaDac[64*3] =
 
469
         {
 
470
             0x00, 0x00, 0x00,
 
471
             0x00, 0x00, 0x2A,
 
472
             0x00, 0x2A, 0x00,
 
473
             0x00, 0x2A, 0x2A,
 
474
             0x2A, 0x00, 0x00,
 
475
             0x2A, 0x00, 0x2A,
 
476
             0x2A, 0x2A, 0x00,
 
477
             0x2A, 0x2A, 0x2A,
 
478
             0x00, 0x00, 0x15,
 
479
             0x00, 0x00, 0x3F,
 
480
             0x00, 0x2A, 0x15,
 
481
             0x00, 0x2A, 0x3F,
 
482
             0x2A, 0x00, 0x15,
 
483
             0x2A, 0x00, 0x3F,
 
484
             0x2A, 0x2A, 0x15,
 
485
             0x2A, 0x2A, 0x3F,
 
486
             0x00, 0x15, 0x00,
 
487
             0x00, 0x15, 0x2A,
 
488
             0x00, 0x3F, 0x00,
 
489
             0x00, 0x3F, 0x2A,
 
490
             0x2A, 0x15, 0x00,
 
491
             0x2A, 0x15, 0x2A,
 
492
             0x2A, 0x3F, 0x00,
 
493
             0x2A, 0x3F, 0x2A,
 
494
             0x00, 0x15, 0x15,
 
495
             0x00, 0x15, 0x3F,
 
496
             0x00, 0x3F, 0x15,
 
497
             0x00, 0x3F, 0x3F,
 
498
             0x2A, 0x15, 0x15,
 
499
             0x2A, 0x15, 0x3F,
 
500
             0x2A, 0x3F, 0x15,
 
501
             0x2A, 0x3F, 0x3F,
 
502
             0x15, 0x00, 0x00,
 
503
             0x15, 0x00, 0x2A,
 
504
             0x15, 0x2A, 0x00,
 
505
             0x15, 0x2A, 0x2A,
 
506
             0x3F, 0x00, 0x00,
 
507
             0x3F, 0x00, 0x2A,
 
508
             0x3F, 0x2A, 0x00,
 
509
             0x3F, 0x2A, 0x2A,
 
510
             0x15, 0x00, 0x15,
 
511
             0x15, 0x00, 0x3F,
 
512
             0x15, 0x2A, 0x15,
 
513
             0x15, 0x2A, 0x3F,
 
514
             0x3F, 0x00, 0x15,
 
515
             0x3F, 0x00, 0x3F,
 
516
             0x3F, 0x2A, 0x15,
 
517
             0x3F, 0x2A, 0x3F,
 
518
             0x15, 0x15, 0x00,
 
519
             0x15, 0x15, 0x2A,
 
520
             0x15, 0x3F, 0x00,
 
521
             0x15, 0x3F, 0x2A,
 
522
             0x3F, 0x15, 0x00,
 
523
             0x3F, 0x15, 0x2A,
 
524
             0x3F, 0x3F, 0x00,
 
525
             0x3F, 0x3F, 0x2A,
 
526
             0x15, 0x15, 0x15,
 
527
             0x15, 0x15, 0x3F,
 
528
             0x15, 0x3F, 0x15,
 
529
             0x15, 0x3F, 0x3F,
 
530
             0x3F, 0x15, 0x15,
 
531
             0x3F, 0x15, 0x3F,
 
532
             0x3F, 0x3F, 0x15,
 
533
             0x3F, 0x3F, 0x3F
 
534
          };
 
535
 
 
536
          for (i = 0; i < 64; ++i)
 
537
          {
 
538
              ASMOutU8(0x3c8, (UINT8)i);
 
539
              ASMOutU8(0x3c9, s_a3bVgaDac[i*3 + 0]);
 
540
              ASMOutU8(0x3c9, s_a3bVgaDac[i*3 + 1]);
 
541
              ASMOutU8(0x3c9, s_a3bVgaDac[i*3 + 2]);
 
542
          }
 
543
     }
 
544
 
 
545
     /* Load the appropriate font into the first map */
 
546
     {
 
547
        UINT8 const    *pabFont;
 
548
        unsigned        offBase = 0;
 
549
        UINT16          height;
 
550
 
 
551
        switch (ModeNumber) {
 
552
        case 0: // 80x25 mode, uses 8x16 font
 
553
            pabFont = g_abVgaFont_8x16;
 
554
            height  = 16;
 
555
            break;
 
556
        case 1: // 80x50 mode, uses 8x8 font
 
557
            pabFont = g_abVgaFont_8x8;
 
558
            height  = 8;
 
559
            break;
 
560
        default:
 
561
            ASSERT(0);  // Valid mode numbers checked above
 
562
            return EFI_UNSUPPORTED;
 
563
        }
 
564
        // Enable font map access
 
565
        {
 
566
            /* Write sequencer registers */
 
567
            ASMOutU16(0x3c4, 0x0100);
 
568
            ASMOutU16(0x3c4, 0x0402);
 
569
            ASMOutU16(0x3c4, 0x0704);
 
570
            ASMOutU16(0x3c4, 0x0300);
 
571
            /* Write graphics controller registers */
 
572
            ASMOutU16(0x3ce, 0x0204);
 
573
            ASMOutU16(0x3ce, 0x0005);
 
574
            ASMOutU16(0x3ce, 0x0406);
 
575
        }
 
576
 
 
577
        for (i = 0; i < 256; ++i)
 
578
        {
 
579
            int offChr = i * height;
 
580
            int offDst = offBase + i * 32;
 
581
            CopyMem((UINT8 *)0xA0000 + offDst, pabFont + offChr, height);
 
582
        }
 
583
 
 
584
        // Set the CRTC Maximum Scan Line register
 
585
        ASMOutU16(0x3d4, 0x4009 | ((height - 1) << 8));
 
586
 
 
587
        // Disable font map access again
 
588
        {
 
589
            /* Write sequencer registers */
 
590
            ASMOutU16(0x3c4, 0x0100);
 
591
            ASMOutU16(0x3c4, 0x0302);
 
592
            ASMOutU16(0x3c4, 0x0304);
 
593
            ASMOutU16(0x3c4, 0x0300);
 
594
            /* Write graphics controller registers */
 
595
            ASMOutU16(0x3ce, 0x0004);
 
596
            ASMOutU16(0x3ce, 0x1005);
 
597
            ASMOutU16(0x3ce, 0x0e06);
 
598
        }
 
599
    }
 
600
 
 
601
    return EFI_SUCCESS;
 
602
}
 
603
 
 
604
 
 
605
 
 
606
 
 
607
/** @copydoc EFI_COMPONENT_NAME_GET_DRIVER_NAME */
 
608
static EFI_STATUS EFIAPI
 
609
VBoxVgaMiniPortCN_GetDriverName(IN EFI_COMPONENT_NAME_PROTOCOL *This,
 
610
                                IN CHAR8 *Language, OUT CHAR16 **DriverName)
 
611
{
 
612
    return LookupUnicodeString2(Language,
 
613
                                This->SupportedLanguages,
 
614
                                &g_aVBoxMiniPortDriverLangAndNames[0],
 
615
                                DriverName,
 
616
                                TRUE);
 
617
}
 
618
 
 
619
/** @copydoc EFI_COMPONENT_NAME_GET_CONTROLLER_NAME */
 
620
static EFI_STATUS EFIAPI
 
621
VBoxVgaMiniPortCN_GetControllerName(IN EFI_COMPONENT_NAME_PROTOCOL *This,
 
622
                                    IN EFI_HANDLE ControllerHandle,
 
623
                                    IN EFI_HANDLE ChildHandle OPTIONAL,
 
624
                                    IN CHAR8 *Language, OUT CHAR16 **ControllerName)
 
625
{
 
626
    /** @todo try query the protocol from the controller and forward the query. */
 
627
    return EFI_UNSUPPORTED;
 
628
}
 
629
 
 
630
 
 
631
 
 
632
 
 
633
/** @copydoc EFI_COMPONENT_NAME2_GET_DRIVER_NAME */
 
634
static EFI_STATUS EFIAPI
 
635
VBoxVgaMiniPortCN2_GetDriverName(IN EFI_COMPONENT_NAME2_PROTOCOL *This,
 
636
                                 IN CHAR8 *Language, OUT CHAR16 **DriverName)
 
637
{
 
638
    return LookupUnicodeString2(Language,
 
639
                                This->SupportedLanguages,
 
640
                                &g_aVBoxMiniPortDriverLangAndNames[0],
 
641
                                DriverName,
 
642
                                FALSE);
 
643
}
 
644
 
 
645
/** @copydoc EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME */
 
646
static EFI_STATUS EFIAPI
 
647
VBoxVgaMiniPortCN2_GetControllerName(IN EFI_COMPONENT_NAME2_PROTOCOL *This,
 
648
                                     IN EFI_HANDLE ControllerHandle,
 
649
                                     IN EFI_HANDLE ChildHandle OPTIONAL,
 
650
                                     IN CHAR8 *Language, OUT CHAR16 **ControllerName)
 
651
{
 
652
    /** @todo try query the protocol from the controller and forward the query. */
 
653
    return EFI_UNSUPPORTED;
 
654
}
 
655