VirtualBox

source: vbox/trunk/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxIdeControllerDxe/IdeController.c@ 33212

Last change on this file since 33212 was 33212, checked in by vboxsync, 14 years ago

EFI: fixed file attributes

  • Property svn:eol-style set to native
File size: 14.5 KB
Line 
1/* $Id$ */
2/** @file
3 * IdeController.c
4 */
5
6/*
7 * Copyright (C) 2009-2010 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18/** @file
19 This driver module produces IDE_CONTROLLER_INIT protocol and will be used by
20 IDE Bus driver to support platform dependent timing information. This driver
21 is responsible for early initialization of IDE controller.
22
23 Copyright (c) 2008 - 2009 Intel Corporation. <BR>
24 All rights reserved. This program and the accompanying materials
25 are licensed and made available under the terms and conditions of the BSD License
26 which accompanies this distribution. The full text of the license may be found at
27 http://opensource.org/licenses/bsd-license.php
28
29 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
30 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
31
32**/
33
34#include "IdeController.h"
35
36//
37// EFI_DRIVER_BINDING_PROTOCOL instance
38//
39EFI_DRIVER_BINDING_PROTOCOL gIdeControllerDriverBinding = {
40 IdeControllerSupported,
41 IdeControllerStart,
42 IdeControllerStop,
43 0xa,
44 NULL,
45 NULL
46};
47
48//
49// EFI_IDE_CONTROLLER_PROVATE_DATA Template
50//
51EFI_IDE_CONTROLLER_INIT_PROTOCOL gEfiIdeControllerInit = {
52 IdeInitGetChannelInfo,
53 IdeInitNotifyPhase,
54 IdeInitSubmitData,
55 IdeInitDisqualifyMode,
56 IdeInitCalculateMode,
57 IdeInitSetTiming,
58 ICH_IDE_ENUMER_ALL,
59 ICH_IDE_MAX_CHANNEL
60};
61
62//
63// EFI_ATA_COLLECTIVE_MODE Template
64//
65EFI_ATA_COLLECTIVE_MODE gEfiAtaCollectiveModeTemplate = {
66 {
67 TRUE, // PioMode.Valid
68 0 // PioMode.Mode
69 },
70 {
71 TRUE, // SingleWordDmaMode.Valid
72 0
73 },
74 {
75 FALSE, // MultiWordDmaMode.Valid
76 0
77 },
78 {
79 TRUE, // UdmaMode.Valid
80 0 // UdmaMode.Mode
81 }
82};
83
84static BOOLEAN gfIdeAhciEmulation = FALSE;
85
86EFI_STATUS
87EFIAPI
88InitializeIdeControllerDriver (
89 IN EFI_HANDLE ImageHandle,
90 IN EFI_SYSTEM_TABLE *SystemTable
91 )
92/*++
93 Routine Description:
94
95 Chipset Ide Driver EntryPoint function. It follows the standard EFI driver
96 model. It's called by StartImage() of DXE Core
97
98 Argments:
99
100 ImageHnadle -- While the driver image loaded be the ImageLoader(),
101 an image handle is assigned to this driver binary,
102 all activities of the driver is tied to this ImageHandle
103 *SystemTable -- A pointer to the system table, for all BS(Boo Services) and
104 RT(Runtime Services)
105
106 Retruns:
107
108 Always call EfiLibInstallDriverBindingProtocol( ) and retrun the result
109
110--*/
111{
112 EFI_STATUS Status;
113
114 //
115 // Install driver model protocol(s).
116 //
117 Status = EfiLibInstallDriverBindingComponentName2 (
118 ImageHandle,
119 SystemTable,
120 &gIdeControllerDriverBinding,
121 ImageHandle,
122 &gIdeControllerComponentName,
123 &gIdeControllerComponentName2
124 );
125 ASSERT_EFI_ERROR (Status);
126
127 return Status;
128}
129
130EFI_STATUS
131EFIAPI
132IdeControllerSupported (
133 IN EFI_DRIVER_BINDING_PROTOCOL *This,
134 IN EFI_HANDLE Controller,
135 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
136 )
137/*++
138
139 Routine Description:
140
141 Register Driver Binding protocol for this driver.
142
143 Arguments:
144
145 This -- a pointer points to the Binding Protocol instance
146 Controller -- The handle of controller to be tested.
147 *RemainingDevicePath -- A pointer to the device path. Ignored by device
148 driver but used by bus driver
149
150 Returns:
151
152 EFI_SUCCESS -- Driver loaded.
153 other -- Driver not loaded.
154--*/
155{
156 EFI_STATUS Status;
157 EFI_PCI_IO_PROTOCOL *PciIo;
158 UINT8 PciClass;
159 UINT8 PciSubClass;
160
161 //
162 // Attempt to Open PCI I/O Protocol
163 //
164 Status = gBS->OpenProtocol (
165 Controller,
166 &gEfiPciIoProtocolGuid,
167 (VOID **) &PciIo,
168 This->DriverBindingHandle,
169 Controller,
170 EFI_OPEN_PROTOCOL_BY_DRIVER
171 );
172 if (EFI_ERROR (Status)) {
173 return Status;
174 }
175
176 //
177 // Now further check the PCI header: Base class (offset 0x0B) and
178 // Sub Class (offset 0x0A). This controller should be an Ide controller
179 //
180 Status = PciIo->Pci.Read (
181 PciIo,
182 EfiPciIoWidthUint8,
183 PCI_CLASSCODE_OFFSET + 2,
184 1,
185 &PciClass
186 );
187 if (EFI_ERROR (Status)) {
188 goto Done;
189 }
190
191 Status = PciIo->Pci.Read (
192 PciIo,
193 EfiPciIoWidthUint8,
194 PCI_CLASSCODE_OFFSET + 1,
195 1,
196 &PciSubClass
197 );
198 if (EFI_ERROR (Status)) {
199 goto Done;
200 }
201
202 //
203 // Examine Ide PCI Configuration table fields
204 //
205 if ((PciClass != PCI_CLASS_MASS_STORAGE) || ((PciSubClass != PCI_CLASS_MASS_STORAGE_IDE) && (PciSubClass != 0x06 /*SATA*/))) {
206 Status = EFI_UNSUPPORTED;
207 }
208 if (PciSubClass == 0x6)
209 gfIdeAhciEmulation = TRUE;
210
211Done:
212 gBS->CloseProtocol (
213 Controller,
214 &gEfiPciIoProtocolGuid,
215 This->DriverBindingHandle,
216 Controller
217 );
218
219 return Status;
220}
221
222EFI_STATUS
223EFIAPI
224IdeControllerStart (
225 IN EFI_DRIVER_BINDING_PROTOCOL *This,
226 IN EFI_HANDLE Controller,
227 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
228 )
229/*++
230
231 Routine Description:
232
233 This routine is called right after the .Supported() called and return
234 EFI_SUCCESS. Notes: The supported protocols are checked but the Protocols
235 are closed.
236
237 Arguments:
238
239 This -- a pointer points to the Binding Protocol instance
240 Controller -- The handle of controller to be tested. Parameter
241 passed by the caller
242 *RemainingDevicePath -- A pointer to the device path. Should be ignored by
243 device driver
244--*/
245{
246 EFI_STATUS Status;
247 EFI_PCI_IO_PROTOCOL *PciIo;
248
249 //
250 // Now test and open the EfiPciIoProtocol
251 //
252 Status = gBS->OpenProtocol (
253 Controller,
254 &gEfiPciIoProtocolGuid,
255 (VOID **) &PciIo,
256 This->DriverBindingHandle,
257 Controller,
258 EFI_OPEN_PROTOCOL_BY_DRIVER
259 );
260 //
261 // Status == EFI_SUCCESS - A normal execution flow, SUCCESS and the program proceeds.
262 // Status == ALREADY_STARTED - A non-zero Status code returned. It indicates
263 // that the protocol has been opened and should be treated as a
264 // normal condition and the program proceeds. The Protocol will not
265 // opened 'again' by this call.
266 // Status != ALREADY_STARTED - Error status, terminate program execution
267 //
268 if (EFI_ERROR (Status)) {
269 return Status;
270 }
271
272 //
273 // Install IDE_CONTROLLER_INIT protocol
274 //
275 return gBS->InstallMultipleProtocolInterfaces (
276 &Controller,
277 &gEfiIdeControllerInitProtocolGuid, &gEfiIdeControllerInit,
278 NULL
279 );
280}
281
282EFI_STATUS
283EFIAPI
284IdeControllerStop (
285 IN EFI_DRIVER_BINDING_PROTOCOL *This,
286 IN EFI_HANDLE Controller,
287 IN UINTN NumberOfChildren,
288 IN EFI_HANDLE *ChildHandleBuffer
289 )
290/*++
291
292 Routine Description:
293 Stop this driver on Controller Handle.
294
295 Arguments:
296 This - Protocol instance pointer.
297 Controller - Handle of device to stop driver on
298 NumberOfChildren - Not used
299 ChildHandleBuffer - Not used
300
301 Returns:
302 EFI_SUCCESS - This driver is removed DeviceHandle
303 other - This driver was not removed from this device
304
305--*/
306{
307 EFI_STATUS Status;
308 EFI_IDE_CONTROLLER_INIT_PROTOCOL *IdeControllerInit;
309
310 //
311 // Open the produced protocol
312 //
313 Status = gBS->OpenProtocol (
314 Controller,
315 &gEfiIdeControllerInitProtocolGuid,
316 (VOID **) &IdeControllerInit,
317 This->DriverBindingHandle,
318 Controller,
319 EFI_OPEN_PROTOCOL_GET_PROTOCOL
320 );
321 if (EFI_ERROR (Status)) {
322 return EFI_UNSUPPORTED;
323 }
324
325 //
326 // Make sure the protocol was produced by this driver
327 //
328 if (IdeControllerInit != &gEfiIdeControllerInit) {
329 return EFI_UNSUPPORTED;
330 }
331
332 //
333 // Uninstall the IDE Controller Init Protocol
334 //
335 Status = gBS->UninstallMultipleProtocolInterfaces (
336 Controller,
337 &gEfiIdeControllerInitProtocolGuid, &gEfiIdeControllerInit,
338 NULL
339 );
340 if (EFI_ERROR (Status)) {
341 return Status;
342 }
343
344 //
345 // Close protocols opened by Ide controller driver
346 //
347 return gBS->CloseProtocol (
348 Controller,
349 &gEfiPciIoProtocolGuid,
350 This->DriverBindingHandle,
351 Controller
352 );
353}
354
355//
356// Interface functions of IDE_CONTROLLER_INIT protocol
357//
358EFI_STATUS
359EFIAPI
360IdeInitGetChannelInfo (
361 IN EFI_IDE_CONTROLLER_INIT_PROTOCOL *This,
362 IN UINT8 Channel,
363 OUT BOOLEAN *Enabled,
364 OUT UINT8 *MaxDevices
365 )
366/*++
367Routine Description:
368
369 This function can be used to obtain information about a specified channel.
370 It's usually used by IDE Bus driver during enumeration process.
371
372Arguments:
373
374 This -- the EFI_IDE_CONTROLLER_INIT_PROTOCOL instance.
375 Channel -- Channel number (0 based, either 0 or 1)
376 Enabled -- TRUE if the channel is enabled. If the channel is disabled,
377 then it will no be enumerated.
378 MaxDevices -- The Max number of IDE devices that the bus driver can expect
379 on this channel. For ATA/ATAPI, this number is either 1 or 2.
380
381Returns:
382 EFI_STATUS
383
384--*/
385{
386 //
387 // Channel number (0 based, either 0 or 1)
388 //
389 if (Channel < ICH_IDE_MAX_CHANNEL) {
390 *Enabled = TRUE;
391 *MaxDevices = ICH_IDE_MAX_DEVICES;
392 return EFI_SUCCESS;
393 }
394
395 *Enabled = FALSE;
396 return EFI_INVALID_PARAMETER;
397}
398
399
400EFI_STATUS
401EFIAPI
402IdeInitNotifyPhase (
403 IN EFI_IDE_CONTROLLER_INIT_PROTOCOL *This,
404 IN EFI_IDE_CONTROLLER_ENUM_PHASE Phase,
405 IN UINT8 Channel
406 )
407/*++
408
409Routine Description:
410
411 This function is called by IdeBus driver before executing certain actions.
412 This allows IDE Controller Init to prepare for each action.
413
414Arguments:
415
416 This -- the EFI_IDE_CONTROLLER_INIT_PROTOCOL instance.
417 Phase -- phase indicator defined by IDE_CONTROLLER_INIT protocol
418 Channel -- Channel number (0 based, either 0 or 1)
419
420Returns:
421
422--*/
423{
424 return EFI_SUCCESS;
425}
426
427EFI_STATUS
428EFIAPI
429IdeInitSubmitData (
430 IN EFI_IDE_CONTROLLER_INIT_PROTOCOL *This,
431 IN UINT8 Channel,
432 IN UINT8 Device,
433 IN EFI_IDENTIFY_DATA *IdentifyData
434 )
435/*++
436
437Routine Description:
438
439 This function is called by IdeBus driver to submit EFI_IDENTIFY_DATA data structure
440 obtained from IDE deivce. This structure is used to set IDE timing
441
442Arguments:
443
444 This -- the EFI_IDE_CONTROLLER_INIT_PROTOCOL instance.
445 Channel -- IDE channel number (0 based, either 0 or 1)
446 Device -- IDE device number
447 IdentifyData -- A pointer to EFI_IDENTIFY_DATA data structure
448
449Returns:
450
451--*/
452{
453 return EFI_SUCCESS;
454}
455
456EFI_STATUS
457EFIAPI
458IdeInitDisqualifyMode (
459 IN EFI_IDE_CONTROLLER_INIT_PROTOCOL *This,
460 IN UINT8 Channel,
461 IN UINT8 Device,
462 IN EFI_ATA_COLLECTIVE_MODE *BadModes
463 )
464/*++
465
466Routine Description:
467
468 This function is called by IdeBus driver to disqualify unsupported operation
469 mode on specfic IDE device
470
471Arguments:
472
473 This -- the EFI_IDE_CONTROLLER_INIT_PROTOCOL instance.
474 Channel -- IDE channel number (0 based, either 0 or 1)
475 Device -- IDE device number
476 BadModes -- Operation mode indicator
477
478Returns:
479
480--*/
481{
482 return EFI_SUCCESS;
483}
484
485EFI_STATUS
486EFIAPI
487IdeInitCalculateMode (
488 IN EFI_IDE_CONTROLLER_INIT_PROTOCOL *This,
489 IN UINT8 Channel,
490 IN UINT8 Device,
491 OUT EFI_ATA_COLLECTIVE_MODE **SupportedModes
492 )
493/*++
494
495Routine Description:
496
497 This function is called by IdeBus driver to calculate the best operation mode
498 supported by specific IDE device
499
500Arguments:
501
502 This -- the EFI_IDE_CONTROLLER_INIT_PROTOCOL instance.
503 Channel -- IDE channel number (0 based, either 0 or 1)
504 Device -- IDE device number
505 SupportedModes -- Modes collection supported by IDE device
506
507Returns:
508
509--*/
510{
511 if (Channel >= ICH_IDE_MAX_CHANNEL || Device >= ICH_IDE_MAX_DEVICES) {
512 return EFI_INVALID_PARAMETER;
513 }
514
515 *SupportedModes = AllocateCopyPool (sizeof (EFI_ATA_COLLECTIVE_MODE), &gEfiAtaCollectiveModeTemplate);
516 if (*SupportedModes == NULL) {
517 return EFI_OUT_OF_RESOURCES;
518 }
519 EFI_ATA_COLLECTIVE_MODE *pSupportedModes = (*SupportedModes);
520 pSupportedModes->PioMode.Mode = 3; /* AtaPioMode4 see VBoxIdeBusDxe/IdeData.h */
521 if (gfIdeAhciEmulation)
522 {
523 pSupportedModes->UdmaMode.Valid = FALSE;
524 pSupportedModes->MultiWordDmaMode.Valid = FALSE;
525 }
526
527 return EFI_SUCCESS;
528}
529
530
531EFI_STATUS
532EFIAPI
533IdeInitSetTiming (
534 IN EFI_IDE_CONTROLLER_INIT_PROTOCOL *This,
535 IN UINT8 Channel,
536 IN UINT8 Device,
537 IN EFI_ATA_COLLECTIVE_MODE *Modes
538 )
539/*++
540
541Routine Description:
542
543 This function is called by IdeBus driver to set appropriate timing on IDE
544 controller according supported operation mode
545
546Arguments:
547
548 This -- the EFI_IDE_CONTROLLER_INIT_PROTOCOL instance.
549 Channel -- IDE channel number (0 based, either 0 or 1)
550 Device -- IDE device number
551
552Returns:
553
554--*/
555{
556 return EFI_SUCCESS;
557}
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette