3 Copyright (c) 2006 - 2007, Intel Corporation
4 All rights reserved. This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
18 This following section documents the envirnoment variables for the Win NT
19 build. These variables are used to define the (virtual) hardware
20 configuration of the NT environment
22 A ! can be used to seperate multiple instances in a variable. Each
23 instance represents a seperate hardware device.
25 EFI_WIN_NT_PHYSICAL_DISKS - maps to drives on your system
26 EFI_WIN_NT_VIRTUAL_DISKS - maps to a device emulated by a file
27 EFI_WIN_NT_FILE_SYSTEM - mouts a directory as a file system
28 EFI_WIN_NT_CONSOLE - make a logical comand line window (only one!)
29 EFI_WIN_NT_UGA - Builds UGA Windows of Width and Height
30 EFI_WIN_NT_SERIAL_PORT - maps physical serial ports
32 <F>ixed - Fixed disk like a hard drive.
33 <R>emovable - Removable media like a floppy or CD-ROM.
34 Read <O>nly - Write protected device.
35 Read <W>rite - Read write device.
36 <block count> - Decimal number of blocks a device supports.
37 <block size> - Decimal number of bytes per block.
39 NT envirnonment variable contents. '<' and '>' are not part of the variable,
40 they are just used to make this help more readable. There should be no
41 spaces between the ';'. Extra spaces will break the variable. A '!' is
42 used to seperate multiple devices in a variable.
44 EFI_WIN_NT_VIRTUAL_DISKS =
45 <F | R><O | W>;<block count>;<block size>[!...]
47 EFI_WIN_NT_PHYSICAL_DISKS =
48 <drive letter>:<F | R><O | W>;<block count>;<block size>[!...]
50 Virtual Disks: These devices use a file to emulate a hard disk or removable
53 Thus a 20 MB emulated hard drive would look like:
54 EFI_WIN_NT_VIRTUAL_DISKS=FW;40960;512
56 A 1.44MB emulated floppy with a block size of 1024 would look like:
57 EFI_WIN_NT_VIRTUAL_DISKS=RW;1440;1024
59 Physical Disks: These devices use NT to open a real device in your system
61 Thus a 120 MB floppy would look like:
62 EFI_WIN_NT_PHYSICAL_DISKS=B:RW;245760;512
64 Thus a standard CD-ROM floppy would look like:
65 EFI_WIN_NT_PHYSICAL_DISKS=Z:RO;307200;2048
67 EFI_WIN_NT_FILE_SYSTEM =
68 <directory path>[!...]
70 Mounting the two directories C:\FOO and C:\BAR would look like:
71 EFI_WIN_NT_FILE_SYSTEM=c:\foo!c:\bar
76 Declaring a text console window with the title "My EFI Console" woild look like:
77 EFI_WIN_NT_CONSOLE=My EFI Console
80 <width> <height>[!...]
82 Declaring a two UGA windows with resolutions of 800x600 and 1024x768 would look like:
83 Example : EFI_WIN_NT_UGA=800 600!1024 768
85 EFI_WIN_NT_SERIAL_PORT =
88 Declaring two serial ports on COM1 and COM2 would look like:
89 Example : EFI_WIN_NT_SERIAL_PORT=COM1!COM2
91 EFI_WIN_NT_PASS_THROUGH =
92 <BaseAddress>;<Bus#>;<Device#>;<Function#>
94 Declaring a base address of 0xE0000000 (used for PCI Express devices)
95 and having NT32 talk to a device located at bus 0, device 1, function 0:
96 Example : EFI_WIN_NT_PASS_THROUGH=E000000;0;1;0
100 #include "WinNtBusDriver.h"
102 extern EFI_GUID gWinNtBusDriverGuid
;
104 // DriverBinding protocol global
106 EFI_DRIVER_BINDING_PROTOCOL gWinNtBusDriverBinding
= {
107 WinNtBusDriverBindingSupported
,
108 WinNtBusDriverBindingStart
,
109 WinNtBusDriverBindingStop
,
115 #define NT_PCD_ARRAY_SIZE (sizeof(mPcdEnvironment)/sizeof(NT_PCD_ENTRY))
118 // Table to map NT Environment variable to the GUID that should be in
121 static NT_PCD_ENTRY mPcdEnvironment
[] = {
122 PcdToken(PcdWinNtConsole
), &gEfiWinNtConsoleGuid
,
123 PcdToken(PcdWinNtUga
), &gEfiWinNtUgaGuid
,
124 PcdToken(PcdWinNtGop
), &gEfiWinNtGopGuid
,
125 PcdToken(PcdWinNtSerialPort
), &gEfiWinNtSerialPortGuid
,
126 PcdToken(PcdWinNtFileSystem
), &gEfiWinNtFileSystemGuid
,
127 PcdToken(PcdWinNtVirtualDisk
), &gEfiWinNtVirtualDisksGuid
,
128 PcdToken(PcdWinNtPhysicalDisk
), &gEfiWinNtPhysicalDisksGuid
,
129 PcdToken(PcdWinNtCpuModel
), &gEfiWinNtCPUModelGuid
,
130 PcdToken(PcdWinNtCpuSpeed
), &gEfiWinNtCPUSpeedGuid
,
131 PcdToken(PcdWinNtMemorySize
), &gEfiWinNtMemoryGuid
141 Buffer
= AllocatePool (Size
);
142 ASSERT (Buffer
!= NULL
);
150 WinNtBusDriverBindingSupported (
151 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
152 IN EFI_HANDLE ControllerHandle
,
153 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
166 // TODO: This - add argument and description to function comment
167 // TODO: ControllerHandle - add argument and description to function comment
168 // TODO: RemainingDevicePath - add argument and description to function comment
169 // TODO: EFI_UNSUPPORTED - add return value to function comment
170 // TODO: EFI_UNSUPPORTED - add return value to function comment
171 // TODO: EFI_SUCCESS - add return value to function comment
172 // TODO: EFI_SUCCESS - add return value to function comment
175 EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
;
176 EFI_WIN_NT_THUNK_PROTOCOL
*WinNtThunk
;
180 // Check the contents of the first Device Path Node of RemainingDevicePath to make sure
181 // it is a legal Device Path Node for this bus driver's children.
183 if (RemainingDevicePath
!= NULL
) {
184 if (RemainingDevicePath
->Type
!= HARDWARE_DEVICE_PATH
||
185 RemainingDevicePath
->SubType
!= HW_VENDOR_DP
||
186 DevicePathNodeLength(RemainingDevicePath
) != sizeof(WIN_NT_VENDOR_DEVICE_PATH_NODE
)) {
187 return EFI_UNSUPPORTED
;
190 for (Index
= 0; Index
< NT_PCD_ARRAY_SIZE
; Index
++) {
191 if (CompareGuid (&((VENDOR_DEVICE_PATH
*) RemainingDevicePath
)->Guid
, mPcdEnvironment
[Index
].DevicePathGuid
)) {
196 if (Index
>= NT_PCD_ARRAY_SIZE
) {
197 return EFI_UNSUPPORTED
;
202 // Open the IO Abstraction(s) needed to perform the supported test
204 Status
= gBS
->OpenProtocol (
206 &gEfiDevicePathProtocolGuid
,
208 This
->DriverBindingHandle
,
210 EFI_OPEN_PROTOCOL_BY_DRIVER
212 if (Status
== EFI_ALREADY_STARTED
) {
216 if (EFI_ERROR (Status
)) {
222 &gEfiDevicePathProtocolGuid
,
223 This
->DriverBindingHandle
,
227 Status
= gBS
->OpenProtocol (
229 &gEfiWinNtThunkProtocolGuid
,
231 This
->DriverBindingHandle
,
233 EFI_OPEN_PROTOCOL_BY_DRIVER
235 if (Status
== EFI_ALREADY_STARTED
) {
239 if (EFI_ERROR (Status
)) {
244 // Since we call through WinNtThunk we need to make sure it's valid
246 Status
= EFI_SUCCESS
;
247 if (WinNtThunk
->Signature
!= EFI_WIN_NT_THUNK_PROTOCOL_SIGNATURE
) {
248 Status
= EFI_UNSUPPORTED
;
252 // Close the I/O Abstraction(s) used to perform the supported test
256 &gEfiWinNtThunkProtocolGuid
,
257 This
->DriverBindingHandle
,
266 WinNtBusDriverBindingStart (
267 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
268 IN EFI_HANDLE ControllerHandle
,
269 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
282 // TODO: This - add argument and description to function comment
283 // TODO: ControllerHandle - add argument and description to function comment
284 // TODO: RemainingDevicePath - add argument and description to function comment
285 // TODO: EFI_OUT_OF_RESOURCES - add return value to function comment
286 // TODO: EFI_OUT_OF_RESOURCES - add return value to function comment
287 // TODO: EFI_SUCCESS - add return value to function comment
290 EFI_STATUS InstallStatus
;
291 EFI_WIN_NT_THUNK_PROTOCOL
*WinNtThunk
;
292 EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
;
293 WIN_NT_BUS_DEVICE
*WinNtBusDevice
;
294 WIN_NT_IO_DEVICE
*WinNtDevice
;
300 UINT16 ComponentName
[MAX_NT_ENVIRNMENT_VARIABLE_LENGTH
];
301 WIN_NT_VENDOR_DEVICE_PATH_NODE
*Node
;
302 BOOLEAN CreateDevice
;
307 Status
= EFI_UNSUPPORTED
;
310 // Grab the protocols we need
312 Status
= gBS
->OpenProtocol (
314 &gEfiDevicePathProtocolGuid
,
316 This
->DriverBindingHandle
,
318 EFI_OPEN_PROTOCOL_BY_DRIVER
320 if (EFI_ERROR (Status
) && Status
!= EFI_ALREADY_STARTED
) {
324 Status
= gBS
->OpenProtocol (
326 &gEfiWinNtThunkProtocolGuid
,
328 This
->DriverBindingHandle
,
330 EFI_OPEN_PROTOCOL_BY_DRIVER
332 if (EFI_ERROR (Status
) && Status
!= EFI_ALREADY_STARTED
) {
336 if (Status
!= EFI_ALREADY_STARTED
) {
337 WinNtBusDevice
= AllocatePool (sizeof (WIN_NT_BUS_DEVICE
));
338 if (WinNtBusDevice
== NULL
) {
339 return EFI_OUT_OF_RESOURCES
;
342 WinNtBusDevice
->Signature
= WIN_NT_BUS_DEVICE_SIGNATURE
;
343 WinNtBusDevice
->ControllerNameTable
= NULL
;
347 gWinNtBusDriverComponentName
.SupportedLanguages
,
348 &WinNtBusDevice
->ControllerNameTable
,
349 L
"Windows Bus Controller"
352 Status
= gBS
->InstallMultipleProtocolInterfaces (
354 &gWinNtBusDriverGuid
,
358 if (EFI_ERROR (Status
)) {
359 FreeUnicodeStringTable (WinNtBusDevice
->ControllerNameTable
);
360 FreePool (WinNtBusDevice
);
366 // Loop on the Variable list. Parse each variable to produce a set of handles that
367 // represent virtual hardware devices.
369 InstallStatus
= EFI_NOT_FOUND
;
370 for (Index
= 0; Index
< NT_PCD_ARRAY_SIZE
; Index
++) {
371 PcdTempStr
= (VOID
*)LibPcdGetPtr (mPcdEnvironment
[Index
].Token
);
372 ASSERT (PcdTempStr
!= NULL
);
374 TempStrSize
= StrLen (PcdTempStr
);
375 TempStr
= AllocateMemory ((TempStrSize
* sizeof (CHAR16
)) + 1);
376 StrCpy (TempStr
, PcdTempStr
);
378 StartString
= TempStr
;
381 // Parse the envirnment variable into sub strings using '!' as a delimator.
382 // Each substring needs it's own handle to be added to the system. This code
383 // does not understand the sub string. Thats the device drivers job.
386 while (*StartString
!= '\0') {
389 // Find the end of the sub string
391 SubString
= StartString
;
392 while (*SubString
!= '\0' && *SubString
!= '!') {
396 if (*SubString
== '!') {
398 // Replace token with '\0' to make sub strings. If this is the end
399 // of the string SubString will already point to NULL.
406 if (RemainingDevicePath
!= NULL
) {
407 CreateDevice
= FALSE
;
408 Node
= (WIN_NT_VENDOR_DEVICE_PATH_NODE
*) RemainingDevicePath
;
409 if (Node
->VendorDevicePath
.Header
.Type
== HARDWARE_DEVICE_PATH
&&
410 Node
->VendorDevicePath
.Header
.SubType
== HW_VENDOR_DP
&&
411 DevicePathNodeLength (&Node
->VendorDevicePath
.Header
) == sizeof (WIN_NT_VENDOR_DEVICE_PATH_NODE
)
413 if (CompareGuid (&Node
->VendorDevicePath
.Guid
, mPcdEnvironment
[Index
].DevicePathGuid
) &&
414 Node
->Instance
== Count
424 // Allocate instance structure, and fill in parent information.
426 WinNtDevice
= AllocateMemory (sizeof (WIN_NT_IO_DEVICE
));
427 if (WinNtDevice
== NULL
) {
428 return EFI_OUT_OF_RESOURCES
;
431 WinNtDevice
->Handle
= NULL
;
432 WinNtDevice
->ControllerHandle
= ControllerHandle
;
433 WinNtDevice
->ParentDevicePath
= ParentDevicePath
;
435 WinNtDevice
->WinNtIo
.WinNtThunk
= WinNtThunk
;
438 // Plus 2 to account for the NULL at the end of the Unicode string
440 StringSize
= (UINTN
) ((UINT8
*) SubString
- (UINT8
*) StartString
) + sizeof (CHAR16
);
441 WinNtDevice
->WinNtIo
.EnvString
= AllocateMemory (StringSize
);
442 if (WinNtDevice
->WinNtIo
.EnvString
!= NULL
) {
443 CopyMem (WinNtDevice
->WinNtIo
.EnvString
, StartString
, StringSize
);
446 WinNtDevice
->ControllerNameTable
= NULL
;
448 WinNtThunk
->SPrintf (ComponentName
, sizeof (ComponentName
), L
"%s", WinNtDevice
->WinNtIo
.EnvString
);
450 WinNtDevice
->DevicePath
= WinNtBusCreateDevicePath (
452 mPcdEnvironment
[Index
].DevicePathGuid
,
455 if (WinNtDevice
->DevicePath
== NULL
) {
456 FreePool (WinNtDevice
);
457 return EFI_OUT_OF_RESOURCES
;
462 gWinNtBusDriverComponentName
.SupportedLanguages
,
463 &WinNtDevice
->ControllerNameTable
,
467 WinNtDevice
->WinNtIo
.TypeGuid
= mPcdEnvironment
[Index
].DevicePathGuid
;
468 WinNtDevice
->WinNtIo
.InstanceNumber
= Count
;
470 WinNtDevice
->Signature
= WIN_NT_IO_DEVICE_SIGNATURE
;
472 Status
= gBS
->InstallMultipleProtocolInterfaces (
473 &WinNtDevice
->Handle
,
474 &gEfiDevicePathProtocolGuid
,
475 WinNtDevice
->DevicePath
,
476 &gEfiWinNtIoProtocolGuid
,
477 &WinNtDevice
->WinNtIo
,
480 if (EFI_ERROR (Status
)) {
481 FreeUnicodeStringTable (WinNtDevice
->ControllerNameTable
);
482 FreePool (WinNtDevice
);
485 // Open For Child Device
487 Status
= gBS
->OpenProtocol (
489 &gEfiWinNtThunkProtocolGuid
,
491 This
->DriverBindingHandle
,
493 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
495 if (!EFI_ERROR (Status
)) {
496 InstallStatus
= EFI_SUCCESS
;
502 // Parse Next sub string. This will point to '\0' if we are at the end.
505 StartString
= SubString
;
517 WinNtBusDriverBindingStop (
518 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
519 IN EFI_HANDLE ControllerHandle
,
520 IN UINTN NumberOfChildren
,
521 IN EFI_HANDLE
*ChildHandleBuffer
534 // TODO: This - add argument and description to function comment
535 // TODO: ControllerHandle - add argument and description to function comment
536 // TODO: NumberOfChildren - add argument and description to function comment
537 // TODO: ChildHandleBuffer - add argument and description to function comment
538 // TODO: EFI_SUCCESS - add return value to function comment
539 // TODO: EFI_DEVICE_ERROR - add return value to function comment
540 // TODO: EFI_SUCCESS - add return value to function comment
544 BOOLEAN AllChildrenStopped
;
545 EFI_WIN_NT_IO_PROTOCOL
*WinNtIo
;
546 WIN_NT_BUS_DEVICE
*WinNtBusDevice
;
547 WIN_NT_IO_DEVICE
*WinNtDevice
;
548 EFI_WIN_NT_THUNK_PROTOCOL
*WinNtThunk
;
551 // Complete all outstanding transactions to Controller.
552 // Don't allow any new transaction to Controller to be started.
555 if (NumberOfChildren
== 0) {
557 // Close the bus driver
559 Status
= gBS
->OpenProtocol (
561 &gWinNtBusDriverGuid
,
563 This
->DriverBindingHandle
,
565 EFI_OPEN_PROTOCOL_GET_PROTOCOL
567 if (EFI_ERROR (Status
)) {
571 gBS
->UninstallMultipleProtocolInterfaces (
573 &gWinNtBusDriverGuid
,
578 FreeUnicodeStringTable (WinNtBusDevice
->ControllerNameTable
);
580 FreePool (WinNtBusDevice
);
584 &gEfiWinNtThunkProtocolGuid
,
585 This
->DriverBindingHandle
,
591 &gEfiDevicePathProtocolGuid
,
592 This
->DriverBindingHandle
,
598 AllChildrenStopped
= TRUE
;
600 for (Index
= 0; Index
< NumberOfChildren
; Index
++) {
602 Status
= gBS
->OpenProtocol (
603 ChildHandleBuffer
[Index
],
604 &gEfiWinNtIoProtocolGuid
,
606 This
->DriverBindingHandle
,
608 EFI_OPEN_PROTOCOL_GET_PROTOCOL
610 if (!EFI_ERROR (Status
)) {
612 WinNtDevice
= WIN_NT_IO_DEVICE_FROM_THIS (WinNtIo
);
614 Status
= gBS
->CloseProtocol (
616 &gEfiWinNtThunkProtocolGuid
,
617 This
->DriverBindingHandle
,
621 Status
= gBS
->UninstallMultipleProtocolInterfaces (
623 &gEfiDevicePathProtocolGuid
,
624 WinNtDevice
->DevicePath
,
625 &gEfiWinNtIoProtocolGuid
,
626 &WinNtDevice
->WinNtIo
,
630 if (EFI_ERROR (Status
)) {
633 &gEfiWinNtThunkProtocolGuid
,
634 (VOID
**) &WinNtThunk
,
635 This
->DriverBindingHandle
,
637 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
641 // Close the child handle
643 FreeUnicodeStringTable (WinNtDevice
->ControllerNameTable
);
644 FreePool (WinNtDevice
);
648 if (EFI_ERROR (Status
)) {
649 AllChildrenStopped
= FALSE
;
653 if (!AllChildrenStopped
) {
654 return EFI_DEVICE_ERROR
;
660 EFI_DEVICE_PATH_PROTOCOL
*
661 WinNtBusCreateDevicePath (
662 IN EFI_DEVICE_PATH_PROTOCOL
*RootDevicePath
,
664 IN UINT16 InstanceNumber
669 Create a device path node using Guid and InstanceNumber and append it to
670 the passed in RootDevicePath
673 RootDevicePath - Root of the device path to return.
675 Guid - GUID to use in vendor device path node.
677 InstanceNumber - Instance number to use in the vendor device path. This
678 argument is needed to make sure each device path is unique.
682 EFI_DEVICE_PATH_PROTOCOL
686 WIN_NT_VENDOR_DEVICE_PATH_NODE DevicePath
;
688 DevicePath
.VendorDevicePath
.Header
.Type
= HARDWARE_DEVICE_PATH
;
689 DevicePath
.VendorDevicePath
.Header
.SubType
= HW_VENDOR_DP
;
690 SetDevicePathNodeLength (&DevicePath
.VendorDevicePath
.Header
, sizeof (WIN_NT_VENDOR_DEVICE_PATH_NODE
));
693 // The GUID defines the Class
695 CopyMem (&DevicePath
.VendorDevicePath
.Guid
, Guid
, sizeof (EFI_GUID
));
698 // Add an instance number so we can make sure there are no Device Path
701 DevicePath
.Instance
= InstanceNumber
;
703 return AppendDevicePathNode (
705 (EFI_DEVICE_PATH_PROTOCOL
*) &DevicePath