/*+++

Copyright (c) 2006 - 2009, Intel Corporation                                                         
All rights reserved. This program and the accompanying materials                          
are licensed and made available under the terms and conditions of the BSD License         
which accompanies this distribution.  The full text of the license may be found at        
http://opensource.org/licenses/bsd-license.php                                            
                                                                                          
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             

Module Name:

  UnixBusDriver.c

Abstract:

This following section documents the envirnoment variables for the Win UNIX 
build.  These variables are used to define the (virtual) hardware 
configuration of the UNIX environment

A ! can be used to seperate multiple instances in a variable. Each 
instance represents a seperate hardware device. 

EFI_UNIX_PHYSICAL_DISKS - maps to drives on your system
EFI_UNIX_VIRTUAL_DISKS  - maps to a device emulated by a file
EFI_UNIX_FILE_SYSTEM    - mouts a directory as a file system
EFI_UNIX_CONSOLE        - make a logical comand line window (only one!)
EFI_UNIX_UGA            - Builds UGA Windows of Width and Height

 <F>ixed       - Fixed disk like a hard drive.
 <R>emovable   - Removable media like a floppy or CD-ROM.
 Read <O>nly   - Write protected device.
 Read <W>rite  - Read write device.
 <block count> - Decimal number of blocks a device supports.
 <block size>  - Decimal number of bytes per block.

 UNIX envirnonment variable contents. '<' and '>' are not part of the variable, 
 they are just used to make this help more readable. There should be no 
 spaces between the ';'. Extra spaces will break the variable. A '!' is  
 used to seperate multiple devices in a variable.

 EFI_UNIX_VIRTUAL_DISKS = 
   <F | R><O | W>;<block count>;<block size>[!...]

 EFI_UNIX_PHYSICAL_DISKS =
   <drive letter>:<F | R><O | W>;<block count>;<block size>[!...]

 Virtual Disks: These devices use a file to emulate a hard disk or removable
                media device. 
                
   Thus a 20 MB emulated hard drive would look like:
   EFI_UNIX_VIRTUAL_DISKS=FW;40960;512

   A 1.44MB emulated floppy with a block size of 1024 would look like:
   EFI_UNIX_VIRTUAL_DISKS=RW;1440;1024

 Physical Disks: These devices use UNIX to open a real device in your system

   Thus a 120 MB floppy would look like:
   EFI_UNIX_PHYSICAL_DISKS=B:RW;245760;512

   Thus a standard CD-ROM floppy would look like:
   EFI_UNIX_PHYSICAL_DISKS=Z:RO;307200;2048

 EFI_UNIX_FILE_SYSTEM = 
   <directory path>[!...]

   Mounting the two directories C:\FOO and C:\BAR would look like:
   EFI_UNIX_FILE_SYSTEM=c:\foo!c:\bar

 EFI_UNIX_CONSOLE = 
   <window title>

   Declaring a text console window with the title "My EFI Console" woild look like:
   EFI_UNIX_CONSOLE=My EFI Console

 EFI_UNIX_UGA = 
   <width> <height>[!...]

   Declaring a two UGA windows with resolutions of 800x600 and 1024x768 would look like:
   Example : EFI_UNIX_UGA=800 600!1024 768

 EFI_UNIX_PASS_THROUGH =
   <BaseAddress>;<Bus#>;<Device#>;<Function#>

   Declaring a base address of 0xE0000000 (used for PCI Express devices)
   and having NT32 talk to a device located at bus 0, device 1, function 0:
   Example : EFI_UNIX_PASS_THROUGH=E000000;0;1;0

---*/

#include "UnixBusDriver.h"

//
// Define GUID for the Unix Bus Driver
//
EFI_GUID gUnixBusDriverGuid = {
  0x419f582, 0x625, 0x4531, {0x8a, 0x33, 0x85, 0xa9, 0x96, 0x5c, 0x95, 0xbc}
};

//
// DriverBinding protocol global
//
EFI_DRIVER_BINDING_PROTOCOL           gUnixBusDriverBinding = {
  UnixBusDriverBindingSupported,
  UnixBusDriverBindingStart,
  UnixBusDriverBindingStop,
  0xa,
  NULL,
  NULL
};

#define UNIX_PCD_ARRAY_SIZE (sizeof(mPcdEnvironment)/sizeof(UNIX_PCD_ENTRY))

//
// Table to map UNIX Environment variable to the GUID that should be in
// device path.
//
UNIX_PCD_ENTRY  mPcdEnvironment[] = {
  {PcdToken(PcdUnixConsole),       &gEfiUnixConsoleGuid},
  {PcdToken(PcdUnixUga),           &gEfiUnixUgaGuid},
  {PcdToken(PcdUnixFileSystem),    &gEfiUnixFileSystemGuid},
  {PcdToken(PcdUnixSerialPort),    &gEfiUnixSerialPortGuid},
  {PcdToken(PcdUnixVirtualDisk),   &gEfiUnixVirtualDisksGuid},
  {PcdToken(PcdUnixPhysicalDisk),  &gEfiUnixPhysicalDisksGuid},
  {PcdToken(PcdUnixCpuModel),      &gEfiUnixCPUModelGuid},
  {PcdToken(PcdUnixCpuSpeed),      &gEfiUnixCPUSpeedGuid},
  {PcdToken(PcdUnixMemorySize),    &gEfiUnixMemoryGuid}
};

VOID *
AllocateMemory (
  IN  UINTN   Size
  )
{
  EFI_STATUS  Status;
  VOID        *Buffer;

  Status = gBS->AllocatePool (
                  EfiBootServicesData,
                  Size,
                  (VOID *)&Buffer
                  );
  if (EFI_ERROR (Status)) {
    ASSERT (FALSE);
    return NULL;
  }
  return Buffer;
}


EFI_STATUS
EFIAPI
UnixBusDriverBindingSupported (
  IN  EFI_DRIVER_BINDING_PROTOCOL  *This,
  IN  EFI_HANDLE                   ControllerHandle,
  IN  EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
  )
/*++

Routine Description:

Arguments:

Returns:

  None

--*/
// TODO:    This - add argument and description to function comment
// TODO:    ControllerHandle - add argument and description to function comment
// TODO:    RemainingDevicePath - add argument and description to function comment
// TODO:    EFI_UNSUPPORTED - add return value to function comment
// TODO:    EFI_UNSUPPORTED - add return value to function comment
// TODO:    EFI_SUCCESS - add return value to function comment
// TODO:    EFI_SUCCESS - add return value to function comment
{
  EFI_STATUS                Status;
  EFI_DEVICE_PATH_PROTOCOL  *ParentDevicePath;
  EFI_UNIX_THUNK_PROTOCOL *UnixThunk;
  UINTN                     Index;

  //
  // Check the contents of the first Device Path Node of RemainingDevicePath to make sure
  // it is a legal Device Path Node for this bus driver's children.
  //
  if (RemainingDevicePath != NULL) {
    //
    // Check if RemainingDevicePath is the End of Device Path Node, 
    // if yes, go on checking other conditions
    //
    if (!IsDevicePathEnd (RemainingDevicePath)) {
      //
      // If RemainingDevicePath isn't the End of Device Path Node,
      // check its validation
      //
      if (RemainingDevicePath->Type != HARDWARE_DEVICE_PATH ||
          RemainingDevicePath->SubType != HW_VENDOR_DP ||
          DevicePathNodeLength(RemainingDevicePath) != sizeof(UNIX_VENDOR_DEVICE_PATH_NODE)) {
        return EFI_UNSUPPORTED;
      }
  
      for (Index = 0; Index < UNIX_PCD_ARRAY_SIZE; Index++) {
        if (CompareGuid (&((VENDOR_DEVICE_PATH *) RemainingDevicePath)->Guid, mPcdEnvironment[Index].DevicePathGuid)) {
          break;
        }
      }
  
      if (Index >= UNIX_PCD_ARRAY_SIZE) {
        return EFI_UNSUPPORTED;
      }
    }
  }
  
  //
  // Open the IO Abstraction(s) needed to perform the supported test
  //
  Status = gBS->OpenProtocol (
                  ControllerHandle,
                  &gEfiUnixThunkProtocolGuid,
                  (VOID **)&UnixThunk,
                  This->DriverBindingHandle,
                  ControllerHandle,
                  EFI_OPEN_PROTOCOL_BY_DRIVER
                  );
  if (Status == EFI_ALREADY_STARTED) {
    return EFI_SUCCESS;
  }

  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Close the I/O Abstraction(s) used to perform the supported test
  //
  gBS->CloseProtocol (
        ControllerHandle,
        &gEfiUnixThunkProtocolGuid,
        This->DriverBindingHandle,
        ControllerHandle
        );

  //
  // Open the EFI Device Path protocol needed to perform the supported test
  //
  Status = gBS->OpenProtocol (
                  ControllerHandle,
                  &gEfiDevicePathProtocolGuid,
                  (VOID **)&ParentDevicePath,
                  This->DriverBindingHandle,
                  ControllerHandle,
                  EFI_OPEN_PROTOCOL_BY_DRIVER
                  );
  if (Status == EFI_ALREADY_STARTED) {
    return EFI_SUCCESS;
  }

  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Since we call through UnixThunk we need to make sure it's valid
  //
  Status = EFI_SUCCESS;
  if (UnixThunk->Signature != EFI_UNIX_THUNK_PROTOCOL_SIGNATURE) {
    Status = EFI_UNSUPPORTED;
  }

  //
  // Close protocol, don't use device path protocol in the Support() function
  //
  gBS->CloseProtocol (
        ControllerHandle,
        &gEfiDevicePathProtocolGuid,
        This->DriverBindingHandle,
        ControllerHandle
        );

  return Status;
}

EFI_STATUS
EFIAPI
UnixBusDriverBindingStart (
  IN  EFI_DRIVER_BINDING_PROTOCOL  *This,
  IN  EFI_HANDLE                   ControllerHandle,
  IN  EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
  )
/*++

Routine Description:

Arguments:

Returns:

  None

--*/
// TODO:    This - add argument and description to function comment
// TODO:    ControllerHandle - add argument and description to function comment
// TODO:    RemainingDevicePath - add argument and description to function comment
// TODO:    EFI_OUT_OF_RESOURCES - add return value to function comment
// TODO:    EFI_OUT_OF_RESOURCES - add return value to function comment
// TODO:    EFI_SUCCESS - add return value to function comment
{
  EFI_STATUS                      Status;
  EFI_STATUS                      InstallStatus;
  EFI_UNIX_THUNK_PROTOCOL         *UnixThunk;
  EFI_DEVICE_PATH_PROTOCOL        *ParentDevicePath;
  UNIX_BUS_DEVICE                 *UnixBusDevice;
  UNIX_IO_DEVICE                  *UnixDevice;
  UINTN                           Index;
  CHAR16                          *StartString;
  CHAR16                          *SubString;
  UINT16                          Count;
  UINTN                           StringSize;
  UINT16                          ComponentName[MAX_UNIX_ENVIRNMENT_VARIABLE_LENGTH];
  UNIX_VENDOR_DEVICE_PATH_NODE  *Node;
  BOOLEAN                         CreateDevice;
  CHAR16                          *TempStr;
  CHAR16                          *PcdTempStr;
  UINTN                           TempStrSize;

  Status = EFI_UNSUPPORTED;

  //
  // Grab the protocols we need
  //
  Status = gBS->OpenProtocol (
                  ControllerHandle,
                  &gEfiDevicePathProtocolGuid,
                  (VOID **)&ParentDevicePath,
                  This->DriverBindingHandle,
                  ControllerHandle,
                  EFI_OPEN_PROTOCOL_BY_DRIVER
                  );
  if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {
    return Status;
  }

  Status = gBS->OpenProtocol (
                  ControllerHandle,
                  &gEfiUnixThunkProtocolGuid,
                  (VOID **)&UnixThunk,
                  This->DriverBindingHandle,
                  ControllerHandle,
                  EFI_OPEN_PROTOCOL_BY_DRIVER
                  );
  if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {
    return Status;
  }

  if (Status != EFI_ALREADY_STARTED) {
    Status = gBS->AllocatePool (
                    EfiBootServicesData,
                    sizeof (UNIX_BUS_DEVICE),
                    (VOID *) &UnixBusDevice
                    );
    if (EFI_ERROR (Status)) {
      return Status;
    }

    UnixBusDevice->Signature           = UNIX_BUS_DEVICE_SIGNATURE;
    UnixBusDevice->ControllerNameTable = NULL;

    AddUnicodeString (
      "eng",
      gUnixBusDriverComponentName.SupportedLanguages,
      &UnixBusDevice->ControllerNameTable,
      L"Unix Bus Controller"
      );

    Status = gBS->InstallMultipleProtocolInterfaces (
                    &ControllerHandle,
                    &gUnixBusDriverGuid,
                    UnixBusDevice,
                    NULL
                    );
    if (EFI_ERROR (Status)) {
      FreeUnicodeStringTable (UnixBusDevice->ControllerNameTable);
      gBS->FreePool (UnixBusDevice);
      return Status;
    }
  }

  //
  // Loop on the Variable list. Parse each variable to produce a set of handles that
  // represent virtual hardware devices.
  //
  InstallStatus   = EFI_NOT_FOUND;
  for (Index = 0; Index < UNIX_PCD_ARRAY_SIZE; Index++) {
    PcdTempStr = (VOID *)LibPcdGetPtr (mPcdEnvironment[Index].Token);
    ASSERT (PcdTempStr != NULL);

    TempStrSize = StrLen (PcdTempStr);
    TempStr = AllocateMemory ((TempStrSize * sizeof (CHAR16)) + 1);
    StrCpy (TempStr, PcdTempStr);

    StartString = TempStr;

    //
    // Parse the envirnment variable into sub strings using '!' as a delimator.
    // Each substring needs it's own handle to be added to the system. This code
    // does not understand the sub string. Thats the device drivers job.
    //
    Count = 0;
    while (*StartString != '\0') {

      //
      // Find the end of the sub string
      //
      SubString = StartString;
      while (*SubString != '\0' && *SubString != '!') {
        SubString++;
      }

      if (*SubString == '!') {
        //
        // Replace token with '\0' to make sub strings. If this is the end
        //  of the string SubString will already point to NULL.
        //
        *SubString = '\0';
        SubString++;
      }

      CreateDevice = TRUE;
      if (RemainingDevicePath != NULL) {
        CreateDevice  = FALSE;
        //
        // Check if RemainingDevicePath is the End of Device Path Node, 
        // if yes, don't create any child device 
        //
        if (!IsDevicePathEnd (RemainingDevicePath)) {
          //
          // If RemainingDevicePath isn't the End of Device Path Node,
          // check its validation
          //
          Node          = (UNIX_VENDOR_DEVICE_PATH_NODE *) RemainingDevicePath;
          if (Node->VendorDevicePath.Header.Type == HARDWARE_DEVICE_PATH &&
              Node->VendorDevicePath.Header.SubType == HW_VENDOR_DP &&
              DevicePathNodeLength (&Node->VendorDevicePath.Header) == sizeof (UNIX_VENDOR_DEVICE_PATH_NODE)
              ) {
            if (CompareGuid (&Node->VendorDevicePath.Guid, mPcdEnvironment[Index].DevicePathGuid) &&
                Node->Instance == Count
                ) {
              CreateDevice = TRUE;
            }
          }
        }
      }

      if (CreateDevice) {
        //
        // Allocate instance structure, and fill in parent information.
        //
        UnixDevice = AllocateMemory (sizeof (UNIX_IO_DEVICE));
        if (UnixDevice == NULL) {
          return EFI_OUT_OF_RESOURCES;
        }

        UnixDevice->Handle             = NULL;
        UnixDevice->ControllerHandle   = ControllerHandle;
        UnixDevice->ParentDevicePath   = ParentDevicePath;

        UnixDevice->UnixIo.UnixThunk   = UnixThunk;

        //
        // Plus 2 to account for the NULL at the end of the Unicode string
        //
        StringSize = (UINTN) ((UINT8 *) SubString - (UINT8 *) StartString) + sizeof (CHAR16);
        UnixDevice->UnixIo.EnvString = AllocateMemory (StringSize);
        if (UnixDevice->UnixIo.EnvString != NULL) {
          CopyMem (UnixDevice->UnixIo.EnvString, StartString, StringSize);
        }

        UnixDevice->ControllerNameTable = NULL;

	//  FIXME: check size
        StrCpy(ComponentName, UnixDevice->UnixIo.EnvString);

        UnixDevice->DevicePath = UnixBusCreateDevicePath (
                                    ParentDevicePath,
                                    mPcdEnvironment[Index].DevicePathGuid,
                                    Count
                                    );
        if (UnixDevice->DevicePath == NULL) {
          gBS->FreePool (UnixDevice);
          return EFI_OUT_OF_RESOURCES;
        }

        AddUnicodeString (
          "eng",
          gUnixBusDriverComponentName.SupportedLanguages,
          &UnixDevice->ControllerNameTable,
          ComponentName
          );

        UnixDevice->UnixIo.TypeGuid       = mPcdEnvironment[Index].DevicePathGuid;
        UnixDevice->UnixIo.InstanceNumber = Count;

        UnixDevice->Signature              = UNIX_IO_DEVICE_SIGNATURE;

        Status = gBS->InstallMultipleProtocolInterfaces (
                        &UnixDevice->Handle,
                        &gEfiDevicePathProtocolGuid,
                        UnixDevice->DevicePath,
                        &gEfiUnixIoProtocolGuid,
                        &UnixDevice->UnixIo,
                        NULL
                        );
        if (EFI_ERROR (Status)) {
          FreeUnicodeStringTable (UnixDevice->ControllerNameTable);
          gBS->FreePool (UnixDevice);
        } else {
          //
          // Open For Child Device
          //
          Status = gBS->OpenProtocol (
                          ControllerHandle,
                          &gEfiUnixThunkProtocolGuid,
                          (VOID **)&UnixThunk,
                          This->DriverBindingHandle,
                          UnixDevice->Handle,
                          EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
                          );
          if (!EFI_ERROR (Status)) {
            InstallStatus = EFI_SUCCESS;
          }
        }
      }

      //
      // Parse Next sub string. This will point to '\0' if we are at the end.
      //
      Count++;
      StartString = SubString;
    }

    gBS->FreePool (TempStr);
  }

  return EFI_SUCCESS;
}


EFI_STATUS
EFIAPI
UnixBusDriverBindingStop (
  IN  EFI_DRIVER_BINDING_PROTOCOL  *This,
  IN  EFI_HANDLE                   ControllerHandle,
  IN  UINTN                        NumberOfChildren,
  IN  EFI_HANDLE                   *ChildHandleBuffer
  )
/*++

Routine Description:

Arguments:

Returns:

    None

--*/
// TODO:    This - add argument and description to function comment
// TODO:    ControllerHandle - add argument and description to function comment
// TODO:    NumberOfChildren - add argument and description to function comment
// TODO:    ChildHandleBuffer - add argument and description to function comment
// TODO:    EFI_SUCCESS - add return value to function comment
// TODO:    EFI_DEVICE_ERROR - add return value to function comment
// TODO:    EFI_SUCCESS - add return value to function comment
{
  EFI_STATUS                Status;
  UINTN                     Index;
  BOOLEAN                   AllChildrenStopped;
  EFI_UNIX_IO_PROTOCOL    *UnixIo;
  UNIX_BUS_DEVICE         *UnixBusDevice;
  UNIX_IO_DEVICE          *UnixDevice;
  EFI_UNIX_THUNK_PROTOCOL *UnixThunk;

  //
  // Complete all outstanding transactions to Controller.
  // Don't allow any new transaction to Controller to be started.
  //

  if (NumberOfChildren == 0) {
    //
    // Close the bus driver
    //
    Status = gBS->OpenProtocol (
                    ControllerHandle,
                    &gUnixBusDriverGuid,
                    (VOID **)&UnixBusDevice,
                    This->DriverBindingHandle,
                    ControllerHandle,
                    EFI_OPEN_PROTOCOL_GET_PROTOCOL
                    );
    if (EFI_ERROR (Status)) {
      return Status;
    }

    gBS->UninstallMultipleProtocolInterfaces (
          ControllerHandle,
          &gUnixBusDriverGuid,
          UnixBusDevice,
          NULL
          );

    FreeUnicodeStringTable (UnixBusDevice->ControllerNameTable);

    gBS->FreePool (UnixBusDevice);

    gBS->CloseProtocol (
          ControllerHandle,
          &gEfiUnixThunkProtocolGuid,
          This->DriverBindingHandle,
          ControllerHandle
          );

    gBS->CloseProtocol (
          ControllerHandle,
          &gEfiDevicePathProtocolGuid,
          This->DriverBindingHandle,
          ControllerHandle
          );
    return EFI_SUCCESS;
  }

  AllChildrenStopped = TRUE;

  for (Index = 0; Index < NumberOfChildren; Index++) {

    Status = gBS->OpenProtocol (
                    ChildHandleBuffer[Index],
                    &gEfiUnixIoProtocolGuid,
                    (VOID **)&UnixIo,
                    This->DriverBindingHandle,
                    ControllerHandle,
                    EFI_OPEN_PROTOCOL_GET_PROTOCOL
                    );
    if (!EFI_ERROR (Status)) {

      UnixDevice = UNIX_IO_DEVICE_FROM_THIS (UnixIo);

      Status = gBS->CloseProtocol (
                      ControllerHandle,
                      &gEfiUnixThunkProtocolGuid,
                      This->DriverBindingHandle,
                      UnixDevice->Handle
                      );

      Status = gBS->UninstallMultipleProtocolInterfaces (
                      UnixDevice->Handle,
                      &gEfiDevicePathProtocolGuid,
                      UnixDevice->DevicePath,
                      &gEfiUnixIoProtocolGuid,
                      &UnixDevice->UnixIo,
                      NULL
                      );

      if (EFI_ERROR (Status)) {
        gBS->OpenProtocol (
              ControllerHandle,
              &gEfiUnixThunkProtocolGuid,
              (VOID **) &UnixThunk,
              This->DriverBindingHandle,
              UnixDevice->Handle,
              EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
              );
      } else {
        //
        // Close the child handle
        //
        FreeUnicodeStringTable (UnixDevice->ControllerNameTable);
        gBS->FreePool (UnixDevice);
      }
    }

    if (EFI_ERROR (Status)) {
      AllChildrenStopped = FALSE;
    }
  }

  if (!AllChildrenStopped) {
    return EFI_DEVICE_ERROR;
  }

  return EFI_SUCCESS;
}

EFI_DEVICE_PATH_PROTOCOL *
UnixBusCreateDevicePath (
  IN  EFI_DEVICE_PATH_PROTOCOL  *RootDevicePath,
  IN  EFI_GUID                  *Guid,
  IN  UINT16                    InstanceNumber
  )
/*++

Routine Description:
  Create a device path node using Guid and InstanceNumber and append it to
  the passed in RootDevicePath

Arguments:
  RootDevicePath - Root of the device path to return.

  Guid           - GUID to use in vendor device path node.

  InstanceNumber - Instance number to use in the vendor device path. This
                    argument is needed to make sure each device path is unique.

Returns:

  EFI_DEVICE_PATH_PROTOCOL 

--*/
{
  UNIX_VENDOR_DEVICE_PATH_NODE  DevicePath;

  DevicePath.VendorDevicePath.Header.Type     = HARDWARE_DEVICE_PATH;
  DevicePath.VendorDevicePath.Header.SubType  = HW_VENDOR_DP;
  SetDevicePathNodeLength (&DevicePath.VendorDevicePath.Header, sizeof (UNIX_VENDOR_DEVICE_PATH_NODE));

  //
  // The GUID defines the Class
  //
  CopyMem (&DevicePath.VendorDevicePath.Guid, Guid, sizeof (EFI_GUID));

  //
  // Add an instance number so we can make sure there are no Device Path
  // duplication.
  //
  DevicePath.Instance = InstanceNumber;

  return AppendDevicePathNode (
          RootDevicePath,
          (EFI_DEVICE_PATH_PROTOCOL *) &DevicePath
          );
}
